static int CDDAReader_read_device(cdio_CDDAReader *self, unsigned sectors_to_read, int *samples) { const unsigned initial_sectors_to_read = sectors_to_read; if (self->is_logging) { log_state = &(self->log); } while (sectors_to_read && (self->_.drive.current_sector <= self->_.drive.final_sector)) { int16_t *raw_sector = cdio_paranoia_read_limited( self->_.drive.paranoia, self->is_logging ? cddareader_callback : NULL, 10); unsigned i; for (i = 0; i < ((44100 / 75) * 2); i++) { *samples = raw_sector[i]; samples += 1; } self->_.drive.current_sector++; sectors_to_read--; } if (self->is_logging) { log_state = NULL; } return initial_sectors_to_read - sectors_to_read; }
/*! */ long ParanoiaReaderImpl::read(uint8_t* buffer, uint32_t begin_sector, uint32_t sectors) { if (not _audio_cd->is_open()) { THROW_EXCEPTION(CddaException, "AudioCd is closed"); } cdio_paranoia_modeset(_cdrom_paranoia, PARANOIA_MODE_FULL ^ PARANOIA_MODE_NEVERSKIP); cdio_paranoia_seek(_cdrom_paranoia, begin_sector, SEEK_SET); int16_t* read_buffer = cdio_paranoia_read_limited(_cdrom_paranoia, NULL, _max_retries); //! \todo Use another system to free returned messages char* err = cdio_cddap_errors(_audio_cd->cdrom()); //char* mes = cdio_cddap_messages(_audio_cd->cdrom()); if (err) { std::string tmp = err; delete [] err; THROW_EXCEPTION(CddaException, tmp); } buffer = reinterpret_cast<uint8_t*>(read_buffer); return sectors; }
qint16 * CdParanoia::read() { #ifdef CDIOPARANOIA_FOUND return paranoia ? cdio_paranoia_read_limited(paranoia, 0, maxRetries) : 0; #else return paranoia ? paranoia_read_limited(paranoia, 0, maxRetries) : 0; #endif }
static PyObject* CDDA_read_sectors(cdio_CDDAObject* self, PyObject *args) { int16_t *raw_sector; int i; int current_sectors_position = 0; int sectors_read; int sectors_to_read; pcm_FrameList *sectors; PyThreadState *thread_state = NULL; if (!PyArg_ParseTuple(args, "i", §ors_to_read)) return NULL; sectors = (pcm_FrameList*)PyObject_CallMethod(self->pcm_module, "__blank__", NULL); if (sectors == NULL) return NULL; if (read_callback == NULL) { thread_state = PyEval_SaveThread(); } sectors->frames = sectors_to_read * (44100 / 75); sectors->channels = 2; sectors->bits_per_sample = 16; sectors->samples_length = (sectors->frames * sectors->channels); sectors->samples = realloc(sectors->samples, sectors->samples_length * sizeof(int)); for (sectors_read = 0; sectors_read < sectors_to_read; sectors_read++) { raw_sector = cdio_paranoia_read_limited(self->paranoia, &read_sector_callback, 10); for (i = 0; i < (SECTOR_LENGTH / 2); i++) { sectors->samples[current_sectors_position++] = raw_sector[i]; } } if (read_callback == NULL) { PyEval_RestoreThread(thread_state); } return (PyObject*)sectors; }
static PyObject* CDDA_read_sector(cdio_CDDAObject* self) { int16_t *raw_sector; int i; int current_sector_position = 0; pcm_FrameList *sector; PyThreadState *thread_state = NULL; sector = (pcm_FrameList*)PyObject_CallMethod(self->pcm_module, "__blank__", NULL); if (sector == NULL) return NULL; if (read_callback == NULL) { thread_state = PyEval_SaveThread(); } sector->frames = 44100 / 75; sector->channels = 2; sector->bits_per_sample = 16; sector->samples_length = (sector->frames * sector->channels); sector->samples = realloc(sector->samples, sector->samples_length * sizeof(int)); raw_sector = cdio_paranoia_read_limited(self->paranoia, &read_sector_callback, 10); for (i = 0; i < (SECTOR_LENGTH / 2); i++) { sector->samples[current_sector_position++] = raw_sector[i]; } if (read_callback == NULL) { PyEval_RestoreThread(thread_state); } return (PyObject*)sector; }
void cued_rip_to_file(rip_context_t *rip) { SF_INFO sfinfo; PIT(SNDFILE, sfObj); PIT(int16_t, pbuf); lsn_t currSector, offsetSectors; int wordsToWrite, wordsWritten, i; int offsetWords = rip->offsetWords; track_t track = rip->currentTrack; memset(&sfinfo, 0x00, sizeof(sfinfo)); sfinfo.samplerate = 44100; sfinfo.channels = rip->channels; sfinfo.format = SF_FORMAT_PCM_16 | rip->soundFileFormat; offsetSectors = offsetWords / CD_FRAMEWORDS; rip->firstSector += offsetSectors; rip->lastSector += offsetSectors; offsetWords %= CD_FRAMEWORDS; if (offsetWords < 0) { rip->firstSector -= 1; } else if (offsetWords > 0) { rip->lastSector += 1; } // else offsetWords is zero b/c the offset fell on a sector boundary currSector = rip->firstSector; #ifdef CUED_HAVE_PARANOIA if (ripUseParanoia) { lsn_t seekSector, prc; if (currSector < 0 && !ripReadPregap) { seekSector = 0; } else { seekSector = currSector; } // TODO: paranoia has a problem with reading leadout if (seekSector < rip->endOfDiscSector) { prc = cdio_paranoia_seek(rip->paranoiaRipObj, seekSector, SEEK_SET); cdio2_paranoia_msg(rip->paranoiaCtlObj, "paranoia seek"); if (-1 == prc) { cdio_error("paranoia returned \"%d\" during seek to \"%d\"; skipping track %02d", prc, seekSector, track); return; } } } #endif // CUED_HAVE_PARANOIA if (ripExtract) { // does not return on error (void) format_get_file_path(rip->cdObj, rip->cddbObj, rip->fileNamePattern, cued_fmt_to_ext(rip->soundFileFormat), track, rip->fileNameBuffer, rip->bufferSize ); sfObj = sf_open(rip->fileNameBuffer, SFM_WRITE, &sfinfo); if (!sfObj) { cdio_error("sf_open(\"%s\") returned \"%s\"; skipping extraction of track %02d", rip->fileNameBuffer, sf_strerror(sfObj), track); return; } } for (; currSector <= rip->lastSector; ++currSector) { if ((currSector < 0 && !ripReadPregap) || (currSector >= rip->endOfDiscSector && !ripReadLeadout)) { // N.B. assume that if mmcBuf is not NULL, it is >= sizeof(audio_buffer_t) if (!rip->mmcBuf) { // use twice the audio_buffer_t size for reading 1 sector; // this should accomodate any extra headers/sub-channel data // requested later in the normal read path // rip->mmcBuf = (uint8_t *) malloc(2 * sizeof(audio_buffer_t)); if (rip->mmcBuf) { rip->allocatedSectors = 1; } else { cdio2_abort("out of memory allocating overread sector"); } } memset(rip->mmcBuf, 0x00, sizeof(audio_buffer_t)); pbuf = (int16_t *) rip->mmcBuf; } else { // TODO: need to update track indices on skip of sector (continue) if (ripUseParanoia) { #ifdef CUED_HAVE_PARANOIA pbuf = cdio_paranoia_read_limited(rip->paranoiaRipObj, cdio2_paranoia_callback, rip->retries); cdio2_paranoia_msg(rip->paranoiaCtlObj, "read of audio sector"); if (!pbuf) { cdio_error("paranoia did not return data; skipping extraction of audio sector %d in track %02d", currSector, track); continue; } #endif // CUED_HAVE_PARANOIA } else { if (DRIVER_OP_SUCCESS == cued_read_audio(rip, currSector, 1, NULL, rip->retries)) { pbuf = (int16_t *) rip->mmcBuf; } else { continue; } } } wordsToWrite = CD_FRAMEWORDS; // N.B. firstSector == lastSector is not possible if offsetWords is non-zero // if (rip->firstSector == currSector) { if (offsetWords < 0) { pbuf += CD_FRAMEWORDS + offsetWords; wordsToWrite = -offsetWords; } else if (offsetWords > 0) { pbuf += offsetWords; wordsToWrite -= offsetWords; } } else if (rip->lastSector == currSector) { if (offsetWords < 0) { wordsToWrite += offsetWords; } else if (offsetWords > 0) { wordsToWrite = offsetWords; } } if (ripExtract) { wordsWritten = sf_write_short(sfObj, pbuf, wordsToWrite); if (wordsWritten != wordsToWrite) { // probably out of disk space, which is bad, because most things rely on it cdio2_abort("failed to write to file \"%s\" due to \"%s\"", rip->fileNameBuffer, sf_strerror(sfObj)); } } if (!track && !ripNoisyPregap) { for (i = 0; i < wordsToWrite; ++i) { if (pbuf[i]) { SETF(RIP_F_NOISY_PREGAP, rip->flags); break; } } } } if (!track && !ripNoisyPregap) { SETF(RIP_F_SILENT_PREGAP, rip->flags); } if (ripExtract) { sf_close(sfObj); } }
// 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(); }