static int CDDAReader_read_image(cdio_CDDAReader *self, unsigned sectors_to_read, int *samples) { const unsigned samples_per_sector = (44100 / 75) * 2; const unsigned initial_sectors_to_read = sectors_to_read; while (sectors_to_read && (self->_.image.current_sector <= self->_.image.final_sector)) { uint8_t sector[CDIO_CD_FRAMESIZE_RAW]; const int result = cdio_read_audio_sector( self->_.image.image, sector, self->_.image.current_sector); if (result == DRIVER_OP_SUCCESS) { pcm_to_int_converter(16, 0, 1)(samples_per_sector, sector, samples); samples += samples_per_sector; self->_.image.current_sector++; sectors_to_read--; } else { return -1; } } return initial_sectors_to_read - sectors_to_read; }
static PyObject* CDImage_read_sector(cdio_CDImage* self) { uint8_t* data; PyObject* to_return; data = malloc(CDIO_CD_FRAMESIZE_RAW); switch (cdio_read_audio_sector(self->image, data, self->current_sector)) { case DRIVER_OP_SUCCESS: to_return = PyObject_CallMethod(self->pcm_module, "FrameList", "s#iiii", (char *)data, (int)(CDIO_CD_FRAMESIZE_RAW), 2, 16, 0, 1); free(data); self->current_sector += 1; return to_return; default: free(data); PyErr_SetString(PyExc_IOError, "error reading sectors"); return NULL; } }
static PyObject* CDImage_read_sector(cdio_CDImage* self) { uint8_t* data; PyObject* to_return; int result; data = malloc(CDIO_CD_FRAMESIZE_RAW); Py_BEGIN_ALLOW_THREADS result = cdio_read_audio_sector(self->image, data, self->current_sector); Py_END_ALLOW_THREADS if (result == DRIVER_OP_SUCCESS) { to_return = PyObject_CallMethod(self->pcm_module, "FrameList", "s#iiii", (char *)data, (int)(CDIO_CD_FRAMESIZE_RAW), 2, 16, 0, 1); free(data); self->current_sector += 1; return to_return; } else { free(data); PyErr_SetString(PyExc_IOError, "error reading sectors"); return NULL; } }
void RipCD::ThreadClickedRipButton() { temporary_directory_ = Utilities::MakeTempDir() + "/"; finished_success_ = 0; finished_failed_ = 0; ui_->progress_bar->setMaximum(NumTracksToRip() * 2 * 100); // Set up progress bar emit(SignalUpdateProgress()); for (int i = 1; i <= i_tracks_; i++) { if (!checkboxes_.value(i - 1)->isChecked()) { continue; } tracks_to_rip_.append(i); QString filename = temporary_directory_ + ParseFileFormatString(ui_->format_filename->text(), i) + ".wav"; QFile* destination_file = new QFile(filename); destination_file->open(QIODevice::WriteOnly); lsn_t i_first_lsn = cdio_get_track_lsn(cdio_, i); lsn_t i_last_lsn = cdio_get_track_last_lsn(cdio_, i); WriteWAVHeader(destination_file, (i_last_lsn - i_first_lsn + 1) * CDIO_CD_FRAMESIZE_RAW); QByteArray buffered_input_bytes(CDIO_CD_FRAMESIZE_RAW, '\0'); for (lsn_t i_cursor = i_first_lsn; i_cursor <= i_last_lsn; i_cursor++) { if (cdio_read_audio_sector(cdio_, buffered_input_bytes.data(), i_cursor) == DRIVER_OP_SUCCESS) { destination_file->write(buffered_input_bytes.data(), buffered_input_bytes.size()); } else { qLog(Error) << "CD read error"; break; } } finished_success_++; emit(SignalUpdateProgress()); TranscoderPreset preset = ui_->format->itemData(ui_->format->currentIndex()) .value<TranscoderPreset>(); QString outfilename = GetOutputFileName(filename, preset); transcoder_->AddJob(filename, preset, outfilename); } emit(RippingComplete()); }
static int cda_seek_sample (DB_fileinfo_t *_info, int sample) { cdda_info_t *info = (cdda_info_t *)_info; int sector = sample / (SECTORSIZE / SAMPLESIZE) + info->first_sector; int offset = (sample % (SECTORSIZE / SAMPLESIZE)) * SAMPLESIZE; //in bytes char buf [SECTORSIZE]; driver_return_code_t ret = cdio_read_audio_sector (info->cdio, buf, sector); if (ret != DRIVER_OP_SUCCESS) return -1; memcpy (info->tail, buf + offset, SECTORSIZE - offset); info->current_sector = sector; info->current_sample = sample; _info->readpos = (float)info->current_sample / _info->fmt.samplerate; return 0; }
static const char * read_sector(cdda_info_t *info) { #if USE_PARANOIA if (info->paranoia) { const int16_t *p_readbuf = paranoia_read(info->paranoia, NULL); if (p_readbuf) { return (char *)p_readbuf; } } else #endif if (!cdio_read_audio_sector(info->cdio, info->buffer, info->current_sector)) { return info->buffer; } return NULL; }
bool AudioCDDemux::read( Packet &decoded, int &idx ) { if ( aborted || numSectors <= sector || isData ) return false; short cd_samples[ CD_BLOCKSIZE ]; if ( cdio_read_audio_sector( cdio, cd_samples, startSector + sector ) == DRIVER_OP_SUCCESS ) { decoded.resize( CD_BLOCKSIZE * sizeof( float ) ); float *decoded_data = ( float * )decoded.data(); for ( int i = 0 ; i < CD_BLOCKSIZE ; ++i ) decoded_data[ i ] = cd_samples[ i ] / 32768.0f; idx = 0; decoded.ts = sector * duration; decoded.duration = duration; ++sector; return true; } return false; }
int main(int argc, const char *argv[]) { cdrom_drive_t *d = NULL; /* Place to store handle given by cd-parapnioa. */ driver_id_t driver_id; char **ppsz_cd_drives; /* List of all drives with a loaded CDDA in it. */ int i_rc=0; /* See if we can find a device with a loaded CD-DA in it. If successful drive_id will be set. */ ppsz_cd_drives = cdio_get_devices_with_cap_ret(NULL, CDIO_FS_AUDIO, false, &driver_id); if (ppsz_cd_drives && *ppsz_cd_drives) { /* Found such a CD-ROM with a CD-DA loaded. Use the first drive in the list. */ d=cdda_identify(*ppsz_cd_drives, 1, NULL); } else { printf("Unable find or access a CD-ROM drive with an audio CD in it.\n"); exit(SKIP_TEST_RC); } /** We had a bug in is_device when driver_id == DRIVER_UNKNOWN or DRIVER_DEVICE. Let's make sure we've fixed that problem. **/ if (!cdio_is_device(*ppsz_cd_drives, DRIVER_UNKNOWN) || !cdio_is_device(*ppsz_cd_drives, DRIVER_DEVICE)) exit(99); /* Don't need a list of CD's with CD-DA's any more. */ cdio_free_device_list(ppsz_cd_drives); /* We'll set for verbose paranoia messages. */ cdda_verbose_set(d, CDDA_MESSAGE_PRINTIT, CDDA_MESSAGE_PRINTIT); if ( 0 != cdio_cddap_open(d) ) { printf("Unable to open disc.\n"); exit(SKIP_TEST_RC); } /* Okay now set up to read up to the first 300 frames of the first audio track of the Audio CD. */ { cdrom_paranoia_t *p = paranoia_init(d); lsn_t i_first_lsn = cdda_disc_firstsector(d); if ( -1 == i_first_lsn ) { printf("Trouble getting starting LSN\n"); } else { lsn_t i_lsn; /* Current LSN to read */ lsn_t i_last_lsn = cdda_disc_lastsector(d); unsigned int i_sectors = i_last_lsn - i_first_lsn + 1; unsigned int j; unsigned int i_good = 0; unsigned int i_bad = 0; /* Set reading mode for full paranoia, but allow skipping sectors. */ paranoia_modeset(p, PARANOIA_MODE_FULL^PARANOIA_MODE_NEVERSKIP); for ( j=0; j<10; j++ ) { /* Pick a place to start reading. */ i_lsn = i_first_lsn + (rand() % i_sectors); paranoia_seek(p, i_lsn, SEEK_SET); printf("Testing %d sectors starting at %ld\n", MAX_SECTORS, (long int) i_lsn); for ( i = 0; i < MAX_SECTORS && i_lsn <= i_last_lsn; i++, i_lsn++ ) { /* read a sector */ int16_t *p_readbuf = paranoia_read(p, callback); char *psz_err=cdio_cddap_errors(d); char *psz_mes=cdio_cddap_messages(d); memcpy(audio_buf[i], p_readbuf, CDIO_CD_FRAMESIZE_RAW); if (psz_mes || psz_err) printf("%s%s\n", psz_mes ? psz_mes: "", psz_err ? psz_err: ""); if (psz_err) free(psz_err); if (psz_mes) free(psz_mes); if( !p_readbuf ) { printf("paranoia read error. Stopping.\n"); goto out; } } /* Compare with the sectors from paranoia. */ i_lsn -= MAX_SECTORS; for ( i = 0; i < MAX_SECTORS; i++, i_lsn++ ) { uint8_t readbuf[CDIO_CD_FRAMESIZE_RAW] = {0,}; if ( PARANOIA_CB_READ == audio_status[i] || PARANOIA_CB_VERIFY == audio_status[i] ) { /* We read the block via paranoia without an error. */ if ( 0 == cdio_read_audio_sector(d->p_cdio, readbuf, i_lsn) ) { if ( BIGENDIAN != d->bigendianp ) { /* We will compare in the slow, pedantic way*/ int j; for (j=0; j < CDIO_CD_FRAMESIZE_RAW ; j +=2) { if (audio_buf[i][j] != readbuf[j+1] && audio_buf[i][j+1] != readbuf[j] ) { printf("LSN %ld doesn't match\n", (long int) i_lsn); i_bad++; } else { i_good++; } } } else { if ( 0 != memcmp(audio_buf[i], readbuf, CDIO_CD_FRAMESIZE_RAW) ) { printf("LSN %ld doesn't match\n", (long int) i_lsn); i_bad++; } else { i_good++; } } } } else { printf("Skipping LSN %ld because of status: %s\n", (long int) i_lsn, paranoia_cb_mode2str[audio_status[i]]); } } } printf("%u sectors compared okay %u sectors were different\n", i_good, i_bad); if (i_bad > i_good) i_rc = 1; } out: paranoia_free(p); } cdio_cddap_close(d); exit(i_rc); }
void AudioCD::_fillBuffer(short* buffer, int i) { cdio_read_audio_sector(m_cdio, buffer, i); }
int cdrfile_read_audio_sector(CDRFile *p_cdrfile, void *buf, uint8 *SubPWBuf, lsn_t lsn) { if(SubPWBuf) { memset(SubPWBuf, 0, 96); MakeSubQ(p_cdrfile, lsn, SubPWBuf); } if(p_cdrfile->p_cdio) { if(cdio_read_audio_sector(p_cdrfile->p_cdio, buf, lsn) < 0) { memset(buf, 0, 2352); return(0); } Endian_A16_LE_to_NE(buf, 588 * 2); return(1); } else { track_t track; for(track = p_cdrfile->FirstTrack; track < (p_cdrfile->FirstTrack + p_cdrfile->NumTracks); track++) { if(lsn >= (p_cdrfile->Tracks[track].LSN - p_cdrfile->Tracks[track].pregap) && lsn < (p_cdrfile->Tracks[track].LSN + p_cdrfile->Tracks[track].sectors)) { if(lsn < p_cdrfile->Tracks[track].LSN) { //puts("Pregap read"); memset(buf, 0, 2352); } else { if(p_cdrfile->Tracks[track].sf) { long SeekPos = (p_cdrfile->Tracks[track].FileOffset / 4) + (lsn - p_cdrfile->Tracks[track].LSN) * 588; //printf("%d, %d\n", lsn, p_cdrfile->Tracks[track].LSN); if(p_cdrfile->Tracks[track].LastSamplePos != SeekPos) { //printf("Seek: %d %d\n", SeekPos, p_cdrfile->Tracks[track].LastSamplePos); sf_seek(p_cdrfile->Tracks[track].sf, SeekPos, SEEK_SET); p_cdrfile->Tracks[track].LastSamplePos = SeekPos; } sf_count_t readcount = sf_read_short(p_cdrfile->Tracks[track].sf, (short*)buf, 588 * 2); p_cdrfile->Tracks[track].LastSamplePos += readcount / 2; } else if(p_cdrfile->Tracks[track].ovfile)// vorbis { int cursection = 0; if(p_cdrfile->Tracks[track].LastSamplePos != 588 * (lsn - p_cdrfile->Tracks[track].LSN)) { ov_pcm_seek((OggVorbis_File *)p_cdrfile->Tracks[track].ovfile, (lsn - p_cdrfile->Tracks[track].LSN) * 588); p_cdrfile->Tracks[track].LastSamplePos = 588 * (lsn - p_cdrfile->Tracks[track].LSN); } long toread = 2352; while(toread > 0) { long didread = ov_read((OggVorbis_File *)p_cdrfile->Tracks[track].ovfile, (char*)buf, toread, &cursection); if(didread == 0) { memset(buf, 0, toread); toread = 0; break; } buf = (uint8 *)buf + didread; toread -= didread; p_cdrfile->Tracks[track].LastSamplePos += didread / 4; } } // end if vorbis else if(p_cdrfile->Tracks[track].MPCReaderFile) // MPC { //printf("%d %d\n", (lsn - p_cdrfile->Tracks[track].LSN), p_cdrfile->Tracks[track].LastSamplePos); if(p_cdrfile->Tracks[track].LastSamplePos != 1176 * (lsn - p_cdrfile->Tracks[track].LSN)) { mpc_decoder_seek_sample(p_cdrfile->Tracks[track].MPCDecoder, 588 * (lsn - p_cdrfile->Tracks[track].LSN)); p_cdrfile->Tracks[track].LastSamplePos = 1176 * (lsn - p_cdrfile->Tracks[track].LSN); } //MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH]; // MPC_SAMPLE_FORMAT MPCBuffer[MPC_DECODER_BUFFER_LENGTH]; // uint32 MPCBufferIn; int16 *cowbuf = (int16 *)buf; int32 toread = 1176; while(toread) { int32 tmplen; if(!p_cdrfile->Tracks[track].MPCBufferIn) { int status = mpc_decoder_decode(p_cdrfile->Tracks[track].MPCDecoder, p_cdrfile->Tracks[track].MPCBuffer, 0, 0); if(status < 0) { printf("Bah\n"); break; } p_cdrfile->Tracks[track].MPCBufferIn = status * 2; p_cdrfile->Tracks[track].MPCBufferOffs = 0; } tmplen = p_cdrfile->Tracks[track].MPCBufferIn; if(tmplen >= toread) tmplen = toread; for(int x = 0; x < tmplen; x++) { int32 samp = p_cdrfile->Tracks[track].MPCBuffer[p_cdrfile->Tracks[track].MPCBufferOffs + x] >> 14; //if(samp < - 32768 || samp > 32767) // This happens with some MPCs of ripped games I've tested, and it's not just 1 or 2 over, and I don't know why! // printf("MPC Sample out of range: %d\n", samp); *cowbuf = (int16)samp; cowbuf++; } p_cdrfile->Tracks[track].MPCBufferOffs += tmplen; toread -= tmplen; p_cdrfile->Tracks[track].LastSamplePos += tmplen; p_cdrfile->Tracks[track].MPCBufferIn -= tmplen; } } else // Binary, woo. { long SeekPos = p_cdrfile->Tracks[track].FileOffset + 2352 * (lsn - p_cdrfile->Tracks[track].LSN); //(lsn - p_cdrfile->Tracks[track].index - p_cdrfile->Tracks[track].pregap); if(p_cdrfile->Tracks[track].SubchannelMode) SeekPos += 96 * (lsn - p_cdrfile->Tracks[track].LSN); if(!fseek(p_cdrfile->Tracks[track].fp, SeekPos, SEEK_SET)) { size_t didread = fread(buf, 1, 2352, p_cdrfile->Tracks[track].fp); if(didread != 2352) { if(didread < 0) didread = 0; memset((uint8*)buf + didread, 0, 2352 - didread); } if(SubPWBuf && p_cdrfile->Tracks[track].SubchannelMode) { fread(SubPWBuf, 1, 96, p_cdrfile->Tracks[track].fp); } if(p_cdrfile->Tracks[track].RawAudioMSBFirst) Endian_A16_BE_to_NE(buf, 588 * 2); else Endian_A16_LE_to_NE(buf, 588 * 2); } else memset(buf, 0, 2352); } } // end if audible part of audio track read. break; } // End if LSN is in range } // end track search loop if(track == (p_cdrfile->FirstTrack + p_cdrfile->NumTracks)) { memset(buf, 0, 2352); return(0); } return(1); }
// private virtual void CdDecoder::run() { RunProlog(); if (!m_inited) { RunEpilog(); return; } m_stat = DecoderEvent::Decoding; // NB block scope required to prevent re-entrancy { DecoderEvent e(m_stat); dispatch(e); } // account for possible frame expansion in aobase (upmix, float conv) const std::size_t thresh = m_bks * 6; while (!m_finish && !m_user_stop) { if (m_seekTime >= +0.) { m_curpos = m_start + static_cast< lsn_t >( (m_seekTime * kSamplesPerSec) / CD_FRAMESAMPLES); if (m_paranoia) { QMutexLocker lock(&getCdioMutex()); cdio_paranoia_seek(m_paranoia, m_curpos, SEEK_SET); } m_output_at = 0; m_seekTime = -1.; } if (m_output_at < m_bks) { while (m_output_at < m_decodeBytes && !m_finish && !m_user_stop && m_seekTime <= +0.) { if (m_curpos < m_end) { QMutexLocker lock(&getCdioMutex()); if (m_paranoia) { int16_t *cdbuffer = cdio_paranoia_read_limited( m_paranoia, 0, 10); if (cdbuffer) memcpy(&m_output_buf[m_output_at], cdbuffer, CDIO_CD_FRAMESIZE_RAW); } else { driver_return_code_t c = cdio_read_audio_sector( m_cdio, &m_output_buf[m_output_at], m_curpos); if (DRIVER_OP_SUCCESS != c) { LOG(VB_MEDIA, LOG_DEBUG, QString("cdio_read_audio_sector(%1) error %2"). arg(m_curpos).arg(c)); memset( &m_output_buf[m_output_at], 0, CDIO_CD_FRAMESIZE_RAW); } } m_output_at += CDIO_CD_FRAMESIZE_RAW; ++(m_curpos); } else { m_finish = true; } } } if (!output()) continue; // Wait until we need to decode or supply more samples uint fill = 0, total = 0; while (!m_finish && !m_user_stop && m_seekTime <= +0.) { output()->GetBufferStatus(fill, total); // Make sure we have decoded samples ready and that the // audiobuffer is reasonably populated if (fill < (thresh << 6)) break; else { // Wait for half of the buffer to drain ::usleep(output()->GetAudioBufferedTime()<<9); } } // write a block if there's sufficient space for it if (!m_user_stop && m_output_at >= m_bks && fill <= total - thresh) { writeBlock(); } } if (m_user_stop) m_inited = false; else if (output()) { // Drain our buffer while (m_output_at >= m_bks) writeBlock(); // Drain ao buffer output()->Drain(); } if (m_finish) m_stat = DecoderEvent::Finished; else if (m_user_stop) m_stat = DecoderEvent::Stopped; else m_stat = DecoderEvent::Error; // NB block scope required to step onto next track { DecoderEvent e(m_stat); dispatch(e); } deinit(); RunEpilog(); }