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;
}
Exemplo n.º 2
0
/*!

 */
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;
}
Exemplo n.º 3
0
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
}
Exemplo n.º 4
0
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", &sectors_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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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);
    }
}
Exemplo n.º 7
0
// 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();
}