Пример #1
0
static int
cda_init (DB_fileinfo_t *_info, DB_playItem_t *it)
{
    deadbeef->pl_lock();
    const char *uri = deadbeef->pl_find_meta(it, ":URI");
    const char *nr = uri ? strchr(uri, '#') : NULL;
    if (!nr || nr == uri) {
        deadbeef->pl_unlock();
        trace ("cdda: bad name: %s\n", uri);
        return -1;
    }

    trace ("cdda: init %s\n", uri);
    const int track_nr = atoi(nr+1);
    const size_t device_length = nr - uri;
    char device[device_length+1];
    strncpy(device, uri, device_length);
    device[device_length] = '\0';
    deadbeef->pl_unlock();

    cdda_info_t *info = (cdda_info_t *)_info;
    info->cdio = cdio_open(device, DRIVER_UNKNOWN);
    if  (!info->cdio) {
        trace ("cdda: Could not open CD device\n");
        return -1;
    }

    const int need_bitrate = info->hints & DDB_DECODER_HINT_NEED_BITRATE;
    const int drive_speed = deadbeef->conf_get_int("cdda.drive_speed", 2);
    cdio_set_speed(info->cdio, need_bitrate && drive_speed < 5 ? 1<<drive_speed : -1);

    cddb_disc_t *disc = create_disc(info->cdio);
    if (!disc) {
        return -1;
    }

    const unsigned long discid = cddb_disc_get_discid(disc);
    cddb_disc_destroy(disc);

    deadbeef->pl_lock();
    const char *discid_hex = deadbeef->pl_find_meta(it, CDDB_DISCID_TAG);
    const unsigned long trk_discid = discid_hex ? strtoul(discid_hex, NULL, 16) : 0;
    deadbeef->pl_unlock();
    if (trk_discid != discid) {
        trace ("cdda: the track belongs to another disc (%x vs %x), skipped\n", trk_discid, discid);
        return -1;
    }

    if (cdio_get_track_format(info->cdio, track_nr) != TRACK_FORMAT_AUDIO) {
        trace ("cdda: Not an audio track (%d)\n", track_nr);
        return -1;
    }

    info->first_sector = cdio_get_track_lsn(info->cdio, track_nr);
    info->current_sector = info->first_sector;
    info->last_sector = info->first_sector + cdio_get_track_sec_count(info->cdio, track_nr) - 1;
    trace("cdio nchannels (should always be 2 for an audio track): %d\n", cdio_get_track_channels (info->cdio, track_nr));
    if (info->first_sector == CDIO_INVALID_LSN || info->last_sector <= info->first_sector) {
        trace ("cdda: invalid track\n");
        return -1;
    }

#if USE_PARANOIA
    if (cdio_get_driver_id(info->cdio) != DRIVER_NRG) {
        info->cdrom = cdda_identify(device, CDDA_MESSAGE_FORGETIT, NULL);
        if (info->cdrom) {
            cdda_open(info->cdrom);
            info->paranoia = paranoia_init(info->cdrom);
        }
        if (!info->paranoia) {
            trace ("cdda: cannot re-open %s for paranoia\n", device);
            return -1;
        }
        const int no_paranoia = need_bitrate || !deadbeef->conf_get_int("cdda.paranoia", 0);
        if (no_paranoia) {
            paranoia_cachemodel_size(info->paranoia, 100);
        }
        paranoia_modeset(info->paranoia, no_paranoia ? PARANOIA_MODE_DISABLE : PARANOIA_MODE_FULL^PARANOIA_MODE_NEVERSKIP);
        paranoia_seek(info->paranoia, info->first_sector, SEEK_SET);
    }
#endif
    return 0;
}
Пример #2
0
int
main(int argc, char *argv[])
{
  uint8_t buffer[CDIO_CD_FRAMESIZE_RAW] = { 0, };
  unsigned int blocklen=CDIO_CD_FRAMESIZE_RAW;
  CdIo *p_cdio=NULL;
  int output_fd=-1;
  FILE *output_stream;
  
  init();

  /* Parse our arguments; every option seen by `parse_opt' will
     be reflected in `arguments'. */
  parse_options(argc, argv);
     
  print_version(program_name, VERSION, opts.no_header, opts.version_only);

  p_cdio = open_input(source_name, opts.source_image, opts.access_mode);

  if (opts.output_file!=NULL) {
    
    /* If hexdump not explicitly set, then don't produce hexdump 
       when writing to a file.
     */
    if (opts.hexdump == 2) opts.hexdump = 0;

    output_fd = open(opts.output_file, O_WRONLY|O_CREAT|O_TRUNC, 0644);
    if (-1 == output_fd) {
      err_exit("Error opening output file %s: %s\n",
	       opts.output_file, strerror(errno));

    }
  } else 
    /* If we are writing to stdout, then the default is to produce 
       a hexdump.
     */
    if (opts.hexdump == 2) opts.hexdump = 1;


  for ( ; opts.start_lsn <= opts.end_lsn; opts.start_lsn++ ) {
    switch (opts.read_mode) {
    case READ_AUDIO:
    case READ_M1F1:
    case READ_M1F2:
    case READ_M2F1:
    case READ_M2F2:
      if (DRIVER_OP_SUCCESS != 
	  cdio_read_sector(p_cdio, &buffer, 
			   opts.start_lsn, 
			   (cdio_read_mode_t) opts.read_mode)) {
	report( stderr, "error reading block %u\n", 
		(unsigned int) opts.start_lsn );
	blocklen = 0;
      } else {
	switch (opts.read_mode) {
	case READ_M1F1:
	  blocklen=CDIO_CD_FRAMESIZE;
	  break;
	case READ_M1F2:
	  blocklen=M2RAW_SECTOR_SIZE;
	case READ_M2F1:
	  blocklen=CDIO_CD_FRAMESIZE;
	case READ_M2F2:
	  blocklen=M2F2_SECTOR_SIZE;
	default: ;
	}
      }
      break;

    case READ_ANY:
      {
	driver_id_t driver_id = cdio_get_driver_id(p_cdio);
	if (cdio_is_device(source_name, driver_id)) {
	  if (DRIVER_OP_SUCCESS != 
	      mmc_read_sectors(p_cdio, &buffer, 
			       opts.start_lsn, CDIO_MMC_READ_TYPE_ANY, 1)) {
	    report( stderr, "error reading block %u\n", 
		    (unsigned int) opts.start_lsn );
	    blocklen = 0;
	  }
	} else {
	  err_exit(
		   "%s: mode 'any' must be used with a real CD-ROM, not an image file.\n", program_name);
	}
      }
      break;

      case READ_MODE_UNINIT: 
      err_exit("%s: Reading mode not set\n", program_name);
      break;
    }

    if (!opts.output_file) {
      output_stream = stdout;
    } else {
      output_stream = fdopen(output_fd, "w");
    }
    
    if (opts.hexdump)
      hexdump(output_stream, buffer, blocklen, opts.just_hex);
    else if (opts.output_file)
      write(output_fd, buffer, blocklen);
    else {
      unsigned int i;
      for (i=0; i<blocklen; i++) printf("%c", buffer[i]);
    }
    
  }

  if (opts.output_file) close(output_fd);

  myexit(p_cdio, EXIT_SUCCESS);
  /* Not reached:*/
  return(EXIT_SUCCESS);

}