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;
}
Example #2
0
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;
    }
}
Example #4
0
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());
}
Example #5
0
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;
}
Example #6
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;
}
Example #7
0
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;
}
Example #8
0
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);
}
Example #9
0
void AudioCD::_fillBuffer(short* buffer, int i)
{
   cdio_read_audio_sector(m_cdio, buffer, i);  
}
Example #10
0
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);
 }
Example #11
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();
}