bool CdParanoia::init() { free(); #ifdef CDIOPARANOIA_FOUND drive = cdda_identify(dev.toLatin1().data(), 0, 0); #else drive = cdda_identify(dev.toLatin1().data(), 0, 0); #endif if (!drive) { return false; } #ifdef CDIOPARANOIA_FOUND cdio_cddap_open(drive); paranoia = cdio_paranoia_init(drive); #else cdda_open(drive); paranoia = paranoia_init(drive); #endif if (paranoia == 0) { free(); return false; } return true; }
bool CDDAParanoia::_paranoia_init() { mutex.lock(); _paranoia_free(); paranoia_drive = cdda_identify(_device.toAscii().data(), 0, 0); if (paranoia_drive == 0) { mutex.unlock(); kDebug() << "Failed to find device."; return FALSE; } //cdda_cdda_verbose_set(_drive, 1, 1); cdda_open(paranoia_drive); paranoia = paranoia_init(paranoia_drive); if (paranoia == 0) { _paranoia_free(); mutex.unlock(); kDebug() << "Failed to init device."; return FALSE; } mutex.unlock(); return TRUE; }
/* * Class: org_tritonus_lowlevel_cdda_cdparanoia_Cdparanoia * Method: open * Signature: (Ljava/lang/String;)I */ JNIEXPORT jint JNICALL Java_org_tritonus_lowlevel_cdda_cdparanoia_Cdparanoia_open (JNIEnv *env, jobject obj, jstring strDevice) { int nReturn; const char* cd_dev; cdrom_drive* cdrom = NULL; handle_t* pHandle; int nParanoiaMode; if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_cdda_cdparanoia_Cdparanoia_open(): begin\n"); } cd_dev = (*env)->GetStringUTFChars(env, strDevice, NULL); if (cd_dev == NULL) { if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_cdda_cdparanoia_Cdparanoia_open(): GetStringUTFChars() failed.\n"); } return -1; } if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_cdda_cdparanoia_Cdparanoia_open(): device name: %s\n", cd_dev); } cdrom = cdda_identify(cd_dev, 0, NULL); if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_cdda_cdparanoia_Cdparanoia_open(): device name: %s\n", cd_dev); } (*env)->ReleaseStringUTFChars(env, strDevice, cd_dev); if (cdrom == NULL) { if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_cdda_cdparanoia_Cdparanoia_open(): cdda_identify() failed.\n"); } return -1; } nReturn = cdda_open(cdrom); if (nReturn < 0) { if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_cdda_cdparanoia_Cdparanoia_open(): cdda_open() failed.\n"); } return -1; } if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_cdda_cdparanoia_Cdparanoia_open(): drive endianess: %d\n", cdrom->bigendianp); } pHandle = (handle_t*) malloc(sizeof(handle_t)); if (pHandle == NULL) { if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_cdda_cdparanoia_Cdparanoia_open(): malloc() failed.\n"); } cdda_close(cdrom); return -1; } pHandle->drive = cdrom; pHandle->paranoia = paranoia_init(pHandle->drive); if (pHandle->paranoia == NULL) { if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_cdda_cdparanoia_Cdparanoia_open(): paranoia_init() failed.\n"); } cdda_close(pHandle->drive); free(pHandle); return -1; } nParanoiaMode = getParanoiaMode(); if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_cdda_cdparanoia_Cdparanoia_open(): paranoia mode: %d\n", nParanoiaMode); } paranoia_modeset(pHandle->paranoia, nParanoiaMode); setHandle(env, obj, pHandle); if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_cdda_cdparanoia_Cdparanoia_open(): end\n"); } return 0; }
bool CdParanoia::init() { free(); drive = cdda_identify(dev.toLatin1().data(), 0, 0); if (!drive) { return false; } cdda_open(drive); paranoia = paranoia_init(drive); if (paranoia == 0) { free(); return false; } return true; }
int main(int argc, char *argv[]) { ZInfo4(DBG_MISC, "Start CDDetection\n"); static cdrom_drive *d = NULL; if (signal(SIGINT | SIGKILL | SIGTERM | SIGSTOP | SIGHUP, catchKill) == SIG_ERR) { ZWarning(DBG_INIT, "Unable to set SIGINT to catchKill function"); } //lock the cdrom i_cdHandler = zrip_lock_cdrom( ZLOCK_CDROM_FILE); //search for CDROM d = cdda_find_a_cdrom(0, NULL); if(!d){ ZError(DBG_INIT, "Can not find cdrom drive.\n"); return(-1); } ZInfo4(DBG_MISC, "Waiting for CD insert\n"); while(1) { if(cdda_open(d) == 0){ // found a cd had been inserted ZInfo4(DBG_MISC, "CD Inserted\n"); SendZMXEvent(ZAPP_ZQ_SOCKET, ZMX_EVT_WAKEUP_CDINSERT, strlen(ZMX_EVT_WAKEUP_CDINSERT)); break; } } if(d) cdda_close(d); //release cdrom lock zrip_unlock_cdrom(i_cdHandler); i_cdHandler = -1; ZInfo4(DBG_MISC, "Exit CDDetectThread!\n"); return 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; }
/* this function gets called by the gui to update mplayer */ static void guiSetEvent(int event) { if(guiInfo.mpcontext) mixer = mpctx_get_mixer(guiInfo.mpcontext); switch(event) { case evPlay: case evPlaySwitchToPause: case evPauseSwitchToPlay: uiPlay(); break; case evPause: uiPause(); break; #ifdef CONFIG_DVDREAD case evPlayDVD: { static char dvdname[MAX_PATH]; guiInfo.Track = 1; guiInfo.Chapter = 1; guiInfo.Angle = 1; guiInfo.NewPlay = GUI_FILE_SAME; #ifdef __WINE__ // dvd_device is in the Windows style (D:\), which needs to be // converted for MPlayer, so that it will find the device in the // Linux filesystem. dvd_device = unix_device(dvd_device); #endif uiSetFileName(NULL, dvd_device, STREAMTYPE_DVD); dvdname[0] = 0; strcat(dvdname, "DVD Movie"); GetVolumeInformation(dvd_device, dvdname, MAX_PATH, NULL, NULL, NULL, NULL, 0); capitalize(dvdname); mp_msg(MSGT_GPLAYER, MSGL_V, "Opening DVD %s -> %s\n", dvd_device, dvdname); mygui->playlist->clear_playlist(mygui->playlist); mygui->playlist->add_track(mygui->playlist, filename, NULL, dvdname, 0); uiPlay(); break; } #endif #ifdef CONFIG_CDDA case evPlayCD: { int i; char track[10]; char trackname[10]; #ifdef CONFIG_LIBCDIO cdrom_drive_t *cd; #else cdrom_drive *cd; #endif int i_tracks; #ifdef __WINE__ // cdrom_device is in the Windows style (D:\), which needs to be // converted for MPlayer, so that it will find the device in the // Linux filesystem. cdrom_device = unix_device(cdrom_device); #endif cd = cdda_identify(cdrom_device, 0, NULL); if (cd) { if (cdda_open(cd) != 0) { cdda_close(cd); cd = NULL; } } if(!cd) { printf("Couldn't find a driver.\n"); break; } i_tracks = cdda_tracks(cd); mygui->playlist->clear_playlist(mygui->playlist); for(i=0;i<i_tracks;i++) { sprintf(track, "cdda://%d", i+1); sprintf(trackname, "Track %d", i+1); mygui->playlist->add_track(mygui->playlist, track, NULL, trackname, 0); } cdda_close(cd); mygui->startplay(mygui); break; } #endif case evFullScreen: mp_input_queue_cmd(mp_input_parse_cmd("vo_fullscreen")); break; case evExit: { /* We are asking mplayer to exit, later it will ask us after uninit is made this should be the only safe way to quit */ mygui->activewidget = NULL; mp_input_queue_cmd(mp_input_parse_cmd("quit")); break; } case evStop: if(guiInfo.Playing) gui(GUI_SET_STATE, (void *) GUI_STOP); break; case evSetMoviePosition: { rel_seek_secs = guiInfo.Position / 100.0f; abs_seek_pos = 3; break; } case evForward10sec: { rel_seek_secs = 10.0f; abs_seek_pos = 0; break; } case evBackward10sec: { rel_seek_secs = -10.0f; abs_seek_pos = 0; break; } case evSetBalance: case evSetVolume: { float l,r; if (guiInfo.Playing == GUI_STOP) break; if (guiInfo.Balance == 50.0f) mixer_setvolume(mixer, guiInfo.Volume, guiInfo.Volume); l = guiInfo.Volume * ((100.0f - guiInfo.Balance) / 50.0f); r = guiInfo.Volume * ((guiInfo.Balance) / 50.0f); if (l > guiInfo.Volume) l=guiInfo.Volume; if (r > guiInfo.Volume) r=guiInfo.Volume; mixer_setvolume(mixer, l, r); /* Check for balance support on mixer - there is a better way ?? */ if (r != l) { mixer_getvolume(mixer, &l, &r); if (r == l) { mp_msg(MSGT_GPLAYER, MSGL_V, "[GUI] Mixer doesn't support balanced audio\n"); mixer_setvolume(mixer, guiInfo.Volume, guiInfo.Volume); guiInfo.Balance = 50.0f; } } break; } case evMute: { mp_cmd_t * cmd = calloc(1, sizeof(*cmd)); cmd->id=MP_CMD_MUTE; cmd->name=strdup("mute"); mp_input_queue_cmd(cmd); break; } case evLoadPlay: { switch(guiInfo.StreamType) { case STREAMTYPE_DVD: { guiInfo.NewPlay = GUI_FILE_SAME; gui(GUI_SET_STATE, (void *) GUI_PLAY); break; } default: { guiInfo.NewPlay = GUI_FILE_NEW; update_playlistwindow(); uiGotoTheNext = guiInfo.Playing? 0 : 1; gui(GUI_SET_STATE, (void *) GUI_STOP); gui(GUI_SET_STATE, (void *) GUI_PLAY); break; } } break; } case evNext: uiNext(); break; case evPrev: uiPrev(); break; } }
static gboolean gst_cd_paranoia_src_open (GstAudioCdSrc * audiocdsrc, const gchar * device) { GstCdParanoiaSrc *src = GST_CD_PARANOIA_SRC (audiocdsrc); gint i, cache_size; GST_DEBUG_OBJECT (src, "trying to open device %s (generic-device=%s) ...", device, GST_STR_NULL (src->generic_device)); /* find the device */ if (src->generic_device != NULL) { src->d = cdda_identify_scsi (src->generic_device, device, FALSE, NULL); } else { if (device != NULL) { src->d = cdda_identify (device, FALSE, NULL); } else { src->d = cdda_identify ("/dev/cdrom", FALSE, NULL); } } /* fail if the device couldn't be found */ if (src->d == NULL) goto no_device; /* set verbosity mode */ cdda_verbose_set (src->d, CDDA_MESSAGE_FORGETIT, CDDA_MESSAGE_FORGETIT); /* open the disc */ if (cdda_open (src->d)) goto open_failed; GST_INFO_OBJECT (src, "set read speed to %d", src->read_speed); cdda_speed_set (src->d, src->read_speed); for (i = 1; i < src->d->tracks + 1; i++) { GstAudioCdSrcTrack track = { 0, }; track.num = i; track.is_audio = IS_AUDIO (src->d, i - 1); track.start = cdda_track_firstsector (src->d, i); track.end = cdda_track_lastsector (src->d, i); track.tags = NULL; gst_audio_cd_src_add_track (GST_AUDIO_CD_SRC (src), &track); } /* create the paranoia struct and set it up */ src->p = paranoia_init (src->d); if (src->p == NULL) goto init_failed; paranoia_modeset (src->p, src->paranoia_mode); GST_INFO_OBJECT (src, "set paranoia mode to 0x%02x", src->paranoia_mode); if (src->search_overlap != -1) { paranoia_overlapset (src->p, src->search_overlap); GST_INFO_OBJECT (src, "search overlap set to %u", src->search_overlap); } cache_size = src->cache_size; if (cache_size == -1) { /* if paranoia mode is low (the default), assume we're doing playback */ if (src->paranoia_mode <= PARANOIA_MODE_FRAGMENT) cache_size = 150; else cache_size = paranoia_cachemodel_size (src->p, -1); } paranoia_cachemodel_size (src->p, cache_size); GST_INFO_OBJECT (src, "set cachemodel size to %u", cache_size); src->next_sector = -1; return TRUE; /* ERRORS */ no_device: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (_("Could not open CD device for reading.")), ("cdda_identify failed")); return FALSE; } open_failed: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (_("Could not open CD device for reading.")), ("cdda_open failed")); cdda_close (src->d); src->d = NULL; return FALSE; } init_failed: { GST_ELEMENT_ERROR (src, LIBRARY, INIT, ("failed to initialize paranoia"), ("failed to initialize paranoia")); return FALSE; } }
static int open_cdda(stream_t *st, int m) { cdda_priv *priv = st->priv; cdda_priv *p = priv; int mode = p->paranoia_mode; int offset = p->toc_offset; cdrom_drive_t *cdd = NULL; int last_track; if (m != STREAM_READ) { return STREAM_UNSUPPORTED; } if (!p->device) { if (cdrom_device) p->device = talloc_strdup(NULL, cdrom_device); else p->device = talloc_strdup(NULL, DEFAULT_CDROM_DEVICE); } #if defined(__NetBSD__) cdd = cdda_identify_scsi(p->device, p->device, 0, NULL); #else cdd = cdda_identify(p->device, 0, NULL); #endif if (!cdd) { MP_ERR(st, "Can't open CDDA device.\n"); return STREAM_ERROR; } cdda_verbose_set(cdd, CDDA_MESSAGE_FORGETIT, CDDA_MESSAGE_FORGETIT); if (p->sector_size) cdd->nsectors = p->sector_size; if (cdda_open(cdd) != 0) { MP_ERR(st, "Can't open disc.\n"); cdda_close(cdd); return STREAM_ERROR; } priv = malloc(sizeof(cdda_priv)); memset(priv, 0, sizeof(cdda_priv)); priv->cd = cdd; if (p->toc_bias) offset -= cdda_track_firstsector(cdd, 1); if (offset) { for (int n = 0; n < cdd->tracks + 1; n++) cdd->disc_toc[n].dwStartSector += offset; } if (p->speed > 0) cdda_speed_set(cdd, p->speed); last_track = cdda_tracks(cdd); if (p->span[0] > last_track) p->span[0] = last_track; if (p->span[1] < p->span[0]) p->span[1] = p->span[0]; if (p->span[1] > last_track) p->span[1] = last_track; if (p->span[0]) priv->start_sector = cdda_track_firstsector(cdd, p->span[0]); else priv->start_sector = cdda_disc_firstsector(cdd); if (p->span[1]) priv->end_sector = cdda_track_lastsector(cdd, p->span[1]); else priv->end_sector = cdda_disc_lastsector(cdd); priv->cdp = paranoia_init(cdd); if (priv->cdp == NULL) { cdda_close(cdd); free(priv); return STREAM_ERROR; } if (mode == 0) mode = PARANOIA_MODE_DISABLE; else if (mode == 1) mode = PARANOIA_MODE_OVERLAP; else mode = PARANOIA_MODE_FULL; if (p->no_skip) mode |= PARANOIA_MODE_NEVERSKIP; else mode &= ~PARANOIA_MODE_NEVERSKIP; if (p->search_overlap > 0) mode |= PARANOIA_MODE_OVERLAP; else if (p->search_overlap == 0) mode &= ~PARANOIA_MODE_OVERLAP; paranoia_modeset(priv->cdp, mode); if (p->search_overlap > 0) paranoia_overlapset(priv->cdp, p->search_overlap); paranoia_seek(priv->cdp, priv->start_sector, SEEK_SET); priv->sector = priv->start_sector; st->priv = priv; st->start_pos = priv->start_sector * CDIO_CD_FRAMESIZE_RAW; st->end_pos = (priv->end_sector + 1) * CDIO_CD_FRAMESIZE_RAW; st->sector_size = CDIO_CD_FRAMESIZE_RAW; st->fill_buffer = fill_buffer; st->seek = seek; st->control = control; st->close = close_cdda; st->demuxer = "rawaudio"; print_cdtext(st, 0); return STREAM_OK; }
int main(int argc,char *argv[]){ int toc_bias=0; int toc_offset=0; int sample_offset=0; int force_cdrom_endian=-1; int force_cdrom_sectors=-1; int force_cdrom_overlap=-1; char *force_cdrom_device=NULL; char *force_generic_device=NULL; char *force_cooked_device=NULL; int force_cdrom_speed=0; int max_retries=20; char *span=NULL; int output_type=1; /* 0=raw, 1=wav, 2=aifc */ int output_endian=0; /* -1=host, 0=little, 1=big */ int query_only=0; int batch=0,i; int run_cache_test=0; char *logfile_name=NULL; char *reportfile_name=NULL; int logfile_open=0; int reportfile_open=0; /* full paranoia, but allow skipping */ int paranoia_mode=PARANOIA_MODE_FULL^PARANOIA_MODE_NEVERSKIP; char *info_file=NULL; int out; int search=0; int c,long_option_index; atexit(cleanup); while((c=getopt_long(argc,argv,optstring,options,&long_option_index))!=EOF){ switch(c){ case 'B': batch=1; break; case 'c': force_cdrom_endian=0; break; case 'C': force_cdrom_endian=1; break; case 'n': force_cdrom_sectors=atoi(optarg); break; case 'o': force_cdrom_overlap=atoi(optarg); break; case 'd': if(force_cdrom_device)free(force_cdrom_device); force_cdrom_device=copystring(optarg); break; case 'g': if(force_cooked_device){ report("-g option incompatable with -k\n"); exit(1); } force_cooked_device=NULL; if(force_generic_device)free(force_generic_device); force_generic_device=copystring(optarg); break; case 'k': if(force_generic_device || force_cdrom_device){ report("-k option incompatable with -d and -g\n"); exit(1); } if(force_cooked_device)free(force_cooked_device); force_cooked_device=copystring(optarg); break; case 'S': force_cdrom_speed=atoi(optarg); break; case 'p': output_type=0; output_endian=-1; break; case 'r': output_type=0; output_endian=0; break; case 'R': output_type=0; output_endian=1; break; case 'w': output_type=1; output_endian=0; break; case 'a': output_type=2; output_endian=1; break; case 'f': output_type=3; output_endian=1; break; case 'v': verbose=CDDA_MESSAGE_PRINTIT; quiet=0; break; case 's': search=1; break; case 'q': verbose=CDDA_MESSAGE_FORGETIT; quiet=1; break; case 'e': callscript=1; fprintf(stderr,"Sending all callbacks to stderr for wrapper script\n"); break; case 'V': fprintf(stderr,VERSION); fprintf(stderr,"\n"); exit(0); break; case 'Q': query_only=1; break; case 'h': usage(stdout); exit(0); case 'Z': paranoia_mode=PARANOIA_MODE_DISABLE; break; case 'A': run_cache_test=1; query_only=1; reportfile_open=1; verbose=CDDA_MESSAGE_PRINTIT; break; case 'z': if (optarg) { max_retries = atoi (optarg); paranoia_mode&=~PARANOIA_MODE_NEVERSKIP; } else { paranoia_mode|=PARANOIA_MODE_NEVERSKIP; } break; case 'Y': paranoia_mode|=PARANOIA_MODE_OVERLAP; /* cdda2wav style overlap check only */ paranoia_mode&=~PARANOIA_MODE_VERIFY; break; case 'X': /*paranoia_mode&=~(PARANOIA_MODE_SCRATCH|PARANOIA_MODE_REPAIR);*/ abort_on_skip=1; break; case 'W': paranoia_mode&=~PARANOIA_MODE_REPAIR; break; case 'F': paranoia_mode&=~(PARANOIA_MODE_FRAGMENT); break; case 'i': if(info_file)free(info_file); info_file=copystring(info_file); break; case 'T': toc_bias=-1; break; case 't': toc_offset=atoi(optarg); break; case 'l': if(logfile_name)free(logfile_name); logfile_name=NULL; if(optarg) logfile_name=strdup(optarg); logfile_open=1; break; case 'L': if(reportfile_name)free(reportfile_name); reportfile_name=NULL; if(optarg) reportfile_name=strdup(optarg); reportfile_open=1; break; case 'O': sample_offset=atoi(optarg); break; default: usage(stderr); exit(1); } } if(logfile_open){ if(logfile_name==NULL) logfile_name=strdup("cdparanoia.log"); if(!strcmp(logfile_name,"-")){ logfile=stdout; logfile_open=0; }else{ logfile=fopen(logfile_name,"w"); if(logfile==NULL){ report("Cannot open log summary file %s: %s",logfile_name, strerror(errno)); exit(1); } } } if(reportfile_open){ if(reportfile_name==NULL) reportfile_name=strdup("cdparanoia.log"); if(!strcmp(reportfile_name,"-")){ reportfile=stdout; reportfile_open=0; }else{ if(logfile_name && !strcmp(reportfile_name,logfile_name)){ reportfile=logfile; reportfile_open=0; }else{ reportfile=fopen(reportfile_name,"w"); if(reportfile==NULL){ report("Cannot open debug log file %s: %s",reportfile_name, strerror(errno)); exit(1); } } } } if(logfile){ /* log command line and version */ int i; for (i = 0; i < argc; i++) fprintf(logfile,"%s ",argv[i]); fprintf(logfile,"\n"); if(reportfile!=logfile){ fprintf(logfile,VERSION); fprintf(logfile,"\n"); fprintf(logfile,"Using cdda library version: %s\n",cdda_version()); fprintf(logfile,"Using paranoia library version: %s\n",paranoia_version()); } fflush(logfile); } if(reportfile && reportfile!=logfile){ /* log command line */ int i; for (i = 0; i < argc; i++) fprintf(reportfile,"%s ",argv[i]); fprintf(reportfile,"\n"); fflush(reportfile); } if(optind>=argc && !query_only){ if(batch) span=NULL; else{ /* D'oh. No span. Fetch me a brain, Igor. */ usage(stderr); exit(1); } }else span=copystring(argv[optind]); report(VERSION); if(verbose){ report("Using cdda library version: %s",cdda_version()); report("Using paranoia library version: %s",paranoia_version()); } /* Query the cdrom/disc; we may need to override some settings */ if(force_cooked_device){ d=cdda_identify_cooked(force_cooked_device,verbose,NULL); }else if(force_generic_device) d=cdda_identify_scsi(force_generic_device,force_cdrom_device,verbose,NULL); else if(force_cdrom_device) d=cdda_identify(force_cdrom_device,verbose,NULL); else if(search) d=cdda_find_a_cdrom(verbose,NULL); else{ /* does the /dev/cdrom link exist? */ struct stat s; if(lstat("/dev/cdrom",&s)){ /* no link. Search anyway */ d=cdda_find_a_cdrom(verbose,NULL); }else{ d=cdda_identify("/dev/cdrom",verbose,NULL); if(d==NULL && !verbose){ verbose=1; report("\n/dev/cdrom exists but isn't accessible. By default,\n" "cdparanoia stops searching for an accessible drive here.\n" "Consider using -sv to force a more complete autosense\n" "of the machine.\n\nMore information about /dev/cdrom:"); d=cdda_identify("/dev/cdrom",CDDA_MESSAGE_PRINTIT,NULL); report("\n"); exit(1); }else report(" "); } } if(!d){ if(!verbose) report("\nUnable to open cdrom drive; -v will give more information."); exit(1); } if(verbose) cdda_verbose_set(d,CDDA_MESSAGE_PRINTIT,CDDA_MESSAGE_PRINTIT); else cdda_verbose_set(d,CDDA_MESSAGE_PRINTIT,CDDA_MESSAGE_FORGETIT); /* possibly force hand on endianness of drive, sector request size */ if(force_cdrom_endian!=-1){ d->bigendianp=force_cdrom_endian; switch(force_cdrom_endian){ case 0: report("Forcing CDROM sense to little-endian; ignoring preset and autosense"); break; case 1: report("Forcing CDROM sense to big-endian; ignoring preset and autosense"); break; } } if(force_cdrom_sectors!=-1){ if(force_cdrom_sectors<0 || force_cdrom_sectors>100){ report("Default sector read size must be 1<= n <= 100\n"); cdda_close(d); d=NULL; exit(1); } report("Forcing default to read %d sectors; " "ignoring preset and autosense",force_cdrom_sectors); d->nsectors=force_cdrom_sectors; d->bigbuff=force_cdrom_sectors*CD_FRAMESIZE_RAW; } if(force_cdrom_overlap!=-1){ if(force_cdrom_overlap<0 || force_cdrom_overlap>75){ report("Search overlap sectors must be 0<= n <=75\n"); cdda_close(d); d=NULL; exit(1); } report("Forcing search overlap to %d sectors; " "ignoring autosense",force_cdrom_overlap); } switch(cdda_open(d)){ case -2:case -3:case -4:case -5: report("\nUnable to open disc. Is there an audio CD in the drive?"); exit(1); case -6: report("\ncdparanoia could not find a way to read audio from this drive."); exit(1); case 0: break; default: report("\nUnable to open disc."); exit(1); } if(force_cdrom_speed==0)force_cdrom_speed=-1; if(force_cdrom_speed!=-1){ report("\nAttempting to set speed to %dx... ",force_cdrom_speed); }else{ if(verbose) report("\nAttempting to set cdrom to full speed... "); } if(cdda_speed_set(d,force_cdrom_speed)){ if(verbose || force_cdrom_speed!=-1) report("\tCDROM speed set FAILED. Continuing anyway..."); }else{ if(verbose) report("\tdrive returned OK."); } if(run_cache_test){ int warn=analyze_cache(d, stderr, reportfile, force_cdrom_speed); if(warn==0){ reportC("\nDrive tests OK with Paranoia.\n\n"); return 0; } if(warn==1) reportC("\nWARNING! PARANOIA MAY NOT BE TRUSTWORTHY WITH THIS DRIVE!\n" "\nThe Paranoia library may not model this CDROM drive's cache" "\ncorrectly according to this analysis run. Analysis is not" "\nalways accurate (it can be fooled by machine load or random" "\nkernel latencies), but if a failed result happens more often" "\nthan one time in twenty on an unloaded machine, please mail" "\nthe %s file produced by this failed analysis to" "\[email protected] to assist developers in extending" "\nParanoia to handle this CDROM properly.\n\n",reportfile_name); return 1; } /* Dump the TOC */ if(query_only || verbose)display_toc(d); if(query_only)exit(0); /* bias the disc. A hack. Of course. */ /* we may need to read before or past user area; this is never default, and we do it because the [allegedly informed] user told us to */ if(sample_offset){ toc_offset+=sample_offset/588; sample_offset%=588; if(sample_offset<0){ sample_offset+=588; toc_offset--; } } if(toc_bias){ toc_offset=-cdda_track_firstsector(d,1); } for(i=0;i<d->tracks+1;i++) d->disc_toc[i].dwStartSector+=toc_offset; if(d->nsectors==1){ report("WARNING: The autosensed/selected sectors per read value is\n" " one sector, making it very unlikely Paranoia can \n" " work.\n\n" " Attempting to continue...\n\n"); } /* parse the span, set up begin and end sectors */ { long first_sector; long last_sector; long batch_first; long batch_last; int batch_track; if(span){ /* look for the hyphen */ char *span2=strchr(span,'-'); if(strrchr(span,'-')!=span2){ report("Error parsing span argument"); cdda_close(d); d=NULL; exit(1); } if(span2!=NULL){ *span2='\0'; span2++; } first_sector=parse_offset(d,span,-1); if(first_sector==-1) last_sector=parse_offset(d,span2,cdda_disc_firstsector(d)); else last_sector=parse_offset(d,span2,first_sector); if(first_sector==-1){ if(last_sector==-1){ report("Error parsing span argument"); cdda_close(d); d=NULL; exit(1); }else{ first_sector=cdda_disc_firstsector(d); } }else{ if(last_sector==-1){ if(span2){ /* There was a hyphen */ last_sector=cdda_disc_lastsector(d); }else{ last_sector= cdda_track_lastsector(d,cdda_sector_gettrack(d,first_sector)); } } } }else{ first_sector=cdda_disc_firstsector(d); last_sector=cdda_disc_lastsector(d); } { int track1=cdda_sector_gettrack(d,first_sector); int track2=cdda_sector_gettrack(d,last_sector); long off1=first_sector-cdda_track_firstsector(d,track1); long off2=last_sector-cdda_track_firstsector(d,track2); int i; for(i=track1;i<=track2;i++) if(!cdda_track_audiop(d,i)){ report("Selected span contains non audio tracks. Aborting.\n\n"); exit(1); } report("Ripping from sector %7ld (track %2d [%d:%02d.%02d])\n" "\t to sector %7ld (track %2d [%d:%02d.%02d])\n",first_sector, track1,(int)(off1/(60*75)),(int)((off1/75)%60),(int)(off1%75), last_sector, track2,(int)(off2/(60*75)),(int)((off2/75)%60),(int)(off2%75)); } { long cursor; int16_t offset_buffer[1176]; int offset_buffer_used=0; int offset_skip=sample_offset*4; p=paranoia_init(d); paranoia_modeset(p,paranoia_mode); if(force_cdrom_overlap!=-1)paranoia_overlapset(p,force_cdrom_overlap); if(verbose) cdda_verbose_set(d,CDDA_MESSAGE_LOGIT,CDDA_MESSAGE_LOGIT); else cdda_verbose_set(d,CDDA_MESSAGE_FORGETIT,CDDA_MESSAGE_FORGETIT); paranoia_seek(p,cursor=first_sector,SEEK_SET); /* this is probably a good idea in general */ seteuid(getuid()); setegid(getgid()); /* we'll need to be able to read one sector past user data if we have a sample offset in order to pick up the last bytes. We need to set the disc length forward here so that the libs are willing to read past, assuming that works on the hardware, of course */ if(sample_offset) d->disc_toc[d->tracks].dwStartSector++; while(cursor<=last_sector){ char outfile_name[256]; if(batch){ batch_first=cursor; batch_last= cdda_track_lastsector(d,batch_track= cdda_sector_gettrack(d,cursor)); if(batch_last>last_sector)batch_last=last_sector; }else{ batch_first=first_sector; batch_last=last_sector; batch_track=-1; } callbegin=batch_first; callend=batch_last; /* argv[optind] is the span, argv[optind+1] (if exists) is outfile */ if(optind+1<argc){ if(!strcmp(argv[optind+1],"-")){ out=dup(fileno(stdout)); if(batch)report("Are you sure you wanted 'batch' " "(-B) output with stdout?"); report("outputting to stdout\n"); if(logfile){ fprintf(logfile,"outputting to stdout\n"); fflush(logfile); } outfile_name[0]='\0'; }else{ char path[256]; char *post=strrchr(argv[optind+1],'/'); int pos=(post?post-argv[optind+1]+1:0); char *file=argv[optind+1]+pos; path[0]='\0'; if(pos) strncat(path,argv[optind+1],pos>256?256:pos); if(batch) snprintf(outfile_name,246,"%strack%02d.%s",path,batch_track,file); else snprintf(outfile_name,246,"%s%s",path,file); if(file[0]=='\0'){ switch(output_type){ case 0: /* raw */ strcat(outfile_name,"cdda.raw"); break; case 1: strcat(outfile_name,"cdda.wav"); break; case 2: strcat(outfile_name,"cdda.aifc"); break; case 3: strcat(outfile_name,"cdda.aiff"); break; } } out=open(outfile_name,O_RDWR|O_CREAT|O_TRUNC,0666); if(out==-1){ report("Cannot open specified output file %s: %s",outfile_name, strerror(errno)); cdda_close(d); d=NULL; exit(1); } report("outputting to %s\n",outfile_name); if(logfile){ fprintf(logfile,"outputting to %s\n",outfile_name); fflush(logfile); } } }else{ /* default */ if(batch) sprintf(outfile_name,"track%02d.",batch_track); else outfile_name[0]='\0'; switch(output_type){ case 0: /* raw */ strcat(outfile_name,"cdda.raw"); break; case 1: strcat(outfile_name,"cdda.wav"); break; case 2: strcat(outfile_name,"cdda.aifc"); break; case 3: strcat(outfile_name,"cdda.aiff"); break; } out=open(outfile_name,O_RDWR|O_CREAT|O_TRUNC,0666); if(out==-1){ report("Cannot open default output file %s: %s",outfile_name, strerror(errno)); cdda_close(d); d=NULL; exit(1); } report("outputting to %s\n",outfile_name); if(logfile){ fprintf(logfile,"outputting to %s\n",outfile_name); fflush(logfile); } } switch(output_type){ case 0: /* raw */ break; case 1: /* wav */ WriteWav(out,(batch_last-batch_first+1)*CD_FRAMESIZE_RAW); break; case 2: /* aifc */ WriteAifc(out,(batch_last-batch_first+1)*CD_FRAMESIZE_RAW); break; case 3: /* aiff */ WriteAiff(out,(batch_last-batch_first+1)*CD_FRAMESIZE_RAW); break; } /* Off we go! */ if(offset_buffer_used){ /* partial sector from previous batch read */ cursor++; if(buffering_write(out, ((char *)offset_buffer)+offset_buffer_used, CD_FRAMESIZE_RAW-offset_buffer_used)){ report("Error writing output: %s",strerror(errno)); exit(1); } } skipped_flag=0; while(cursor<=batch_last){ /* read a sector */ int16_t *readbuf=paranoia_read_limited(p,callback,max_retries); char *err=cdda_errors(d); char *mes=cdda_messages(d); if(mes || err) fprintf(stderr,"\r " " \r%s%s\n", mes?mes:"",err?err:""); if(err)free(err); if(mes)free(mes); if(readbuf==NULL){ if(errno==EBADF || errno==ENOMEDIUM){ report("\nparanoia_read: CDROM drive unavailable, bailing.\n"); exit(1); } skipped_flag=1; report("\nparanoia_read: Unrecoverable error, bailing.\n"); break; } if(skipped_flag && abort_on_skip){ cursor=batch_last+1; break; } skipped_flag=0; cursor++; if(output_endian!=bigendianp()){ int i; for(i=0;i<CD_FRAMESIZE_RAW/2;i++)readbuf[i]=swap16(readbuf[i]); } callback(cursor*(CD_FRAMEWORDS)-1,-2); if(buffering_write(out,((char *)readbuf)+offset_skip, CD_FRAMESIZE_RAW-offset_skip)){ report("Error writing output: %s",strerror(errno)); exit(1); } offset_skip=0; if(output_endian!=bigendianp()){ int i; for(i=0;i<CD_FRAMESIZE_RAW/2;i++)readbuf[i]=swap16(readbuf[i]); } /* One last bit of silliness to deal with sample offsets */ if(sample_offset && cursor>batch_last){ int i; /* read a sector and output the partial offset. Save the rest for the next batch iteration */ readbuf=paranoia_read_limited(p,callback,max_retries); err=cdda_errors(d);mes=cdda_messages(d); if(mes || err) fprintf(stderr,"\r " " \r%s%s\n", mes?mes:"",err?err:""); if(err)free(err);if(mes)free(mes); if(readbuf==NULL){ skipped_flag=1; report("\nparanoia_read: Unrecoverable error reading through " "sample_offset shift\n\tat end of track, bailing.\n"); break; } if(skipped_flag && abort_on_skip)break; skipped_flag=0; /* do not move the cursor */ if(output_endian!=bigendianp()) for(i=0;i<CD_FRAMESIZE_RAW/2;i++) offset_buffer[i]=swap16(readbuf[i]); else memcpy(offset_buffer,readbuf,CD_FRAMESIZE_RAW); offset_buffer_used=sample_offset*4; callback(cursor*(CD_FRAMEWORDS),-2); if(buffering_write(out,(char *)offset_buffer, offset_buffer_used)){ report("Error writing output: %s",strerror(errno)); exit(1); } } } callback(cursor*(CD_FRAMESIZE_RAW/2)-1,-1); buffering_close(out); if(skipped_flag){ /* remove the file */ report("\nRemoving aborted file: %s",outfile_name); unlink(outfile_name); /* make the cursor correct if we have another track */ if(batch_track!=-1){ batch_track++; cursor=cdda_track_firstsector(d,batch_track); paranoia_seek(p,cursor,SEEK_SET); offset_skip=sample_offset*4; offset_buffer_used=0; } } report("\n"); } paranoia_free(p); p=NULL; } } report("Done.\n\n"); cdda_close(d); d=NULL; if(logfile_open) fclose(logfile); if(reportfile_open) fclose(reportfile); return 0; }
/* mutex must be locked */ static void scan_cd (void) { AUDDBG ("Scanning CD drive.\n"); g_return_if_fail (pcdrom_drive != NULL); g_return_if_fail (trackinfo == NULL); gint trackno; /* general track initialization */ /* skip endianness detection (because it only affects cdda_read, and we use * cdio_read_audio_sectors instead) */ pcdrom_drive->bigendianp = 0; /* finish initialization of drive/disc (performs disc TOC sanitization) */ if (cdda_open (pcdrom_drive) != 0) { cdaudio_error ("Failed to finish initializing opened CD drive."); goto ERR; } if (cdda_speed_set (pcdrom_drive, cdng_cfg.disc_speed) != DRIVER_OP_SUCCESS) warn ("Cannot set drive speed.\n"); firsttrackno = cdio_get_first_track_num (pcdrom_drive->p_cdio); lasttrackno = cdio_get_last_track_num (pcdrom_drive->p_cdio); if (firsttrackno == CDIO_INVALID_TRACK || lasttrackno == CDIO_INVALID_TRACK) { cdaudio_error ("Failed to retrieve first/last track number."); goto ERR; } AUDDBG ("first track is %d and last track is %d\n", firsttrackno, lasttrackno); trackinfo = (trackinfo_t *) g_new (trackinfo_t, (lasttrackno + 1)); cdaudio_set_fullinfo (&trackinfo[0], cdda_track_firstsector (pcdrom_drive, 0), cdda_track_lastsector (pcdrom_drive, lasttrackno), "", "", ""); n_audio_tracks = 0; for (trackno = firsttrackno; trackno <= lasttrackno; trackno++) { cdaudio_set_fullinfo (&trackinfo[trackno], cdda_track_firstsector (pcdrom_drive, trackno), cdda_track_lastsector (pcdrom_drive, trackno), "", "", ""); if (trackinfo[trackno].startlsn == CDIO_INVALID_LSN || trackinfo[trackno].endlsn == CDIO_INVALID_LSN) { cdaudio_error ("Cannot read start/end LSN for track %d.", trackno); goto ERR; } /* count how many tracks are audio tracks */ if (cdda_track_audiop (pcdrom_drive, trackno)) n_audio_tracks++; } /* get trackinfo[0] cdtext information (the disc) */ if (cdng_cfg.use_cdtext) { AUDDBG ("getting cd-text information for disc\n"); cdtext_t *pcdtext = cdio_get_cdtext (pcdrom_drive->p_cdio, 0); if (pcdtext == NULL || pcdtext->field[CDTEXT_TITLE] == NULL) { AUDDBG ("no cd-text available for disc\n"); } else { cdaudio_set_strinfo (&trackinfo[0], pcdtext->field[CDTEXT_PERFORMER] ? pcdtext-> field[CDTEXT_PERFORMER] : "", pcdtext->field[CDTEXT_TITLE] ? pcdtext-> field[CDTEXT_TITLE] : "", pcdtext->field[CDTEXT_GENRE] ? pcdtext-> field[CDTEXT_GENRE] : ""); } } /* get track information from cdtext */ gboolean cdtext_was_available = FALSE; for (trackno = firsttrackno; trackno <= lasttrackno; trackno++) { cdtext_t *pcdtext = NULL; if (cdng_cfg.use_cdtext) { AUDDBG ("getting cd-text information for track %d\n", trackno); pcdtext = cdio_get_cdtext (pcdrom_drive->p_cdio, trackno); if (pcdtext == NULL || pcdtext->field[CDTEXT_PERFORMER] == NULL) { AUDDBG ("no cd-text available for track %d\n", trackno); pcdtext = NULL; } } if (pcdtext != NULL) { cdaudio_set_strinfo (&trackinfo[trackno], pcdtext->field[CDTEXT_PERFORMER] ? pcdtext-> field[CDTEXT_PERFORMER] : "", pcdtext->field[CDTEXT_TITLE] ? pcdtext-> field[CDTEXT_TITLE] : "", pcdtext->field[CDTEXT_GENRE] ? pcdtext-> field[CDTEXT_GENRE] : ""); cdtext_was_available = TRUE; } else { cdaudio_set_strinfo (&trackinfo[trackno], "", "", ""); snprintf (trackinfo[trackno].name, DEF_STRING_LEN, "Track %d", trackno); } } if (!cdtext_was_available) { /* initialize de cddb subsystem */ cddb_conn_t *pcddb_conn = NULL; cddb_disc_t *pcddb_disc = NULL; cddb_track_t *pcddb_track = NULL; lba_t lba; /* Logical Block Address */ if (cdng_cfg.use_cddb) { pcddb_conn = cddb_new (); if (pcddb_conn == NULL) cdaudio_error ("Failed to create the cddb connection."); else { AUDDBG ("getting CDDB info\n"); cddb_cache_enable (pcddb_conn); // cddb_cache_set_dir(pcddb_conn, "~/.cddbslave"); if (cdng_cfg.use_proxy) { cddb_http_proxy_enable (pcddb_conn); cddb_set_http_proxy_server_name (pcddb_conn, cdng_cfg.proxy_host); cddb_set_http_proxy_server_port (pcddb_conn, cdng_cfg.proxy_port); cddb_set_http_proxy_username (pcddb_conn, cdng_cfg.proxy_username); cddb_set_http_proxy_password (pcddb_conn, cdng_cfg.proxy_password); cddb_set_server_name (pcddb_conn, cdng_cfg.cddb_server); cddb_set_server_port (pcddb_conn, cdng_cfg.cddb_port); } else if (cdng_cfg.cddb_http) { cddb_http_enable (pcddb_conn); cddb_set_server_name (pcddb_conn, cdng_cfg.cddb_server); cddb_set_server_port (pcddb_conn, cdng_cfg.cddb_port); cddb_set_http_path_query (pcddb_conn, cdng_cfg.cddb_path); } else { cddb_set_server_name (pcddb_conn, cdng_cfg.cddb_server); cddb_set_server_port (pcddb_conn, cdng_cfg.cddb_port); } pcddb_disc = cddb_disc_new (); lba = cdio_get_track_lba (pcdrom_drive->p_cdio, CDIO_CDROM_LEADOUT_TRACK); cddb_disc_set_length (pcddb_disc, FRAMES_TO_SECONDS (lba)); for (trackno = firsttrackno; trackno <= lasttrackno; trackno++) { pcddb_track = cddb_track_new (); cddb_track_set_frame_offset (pcddb_track, cdio_get_track_lba ( pcdrom_drive->p_cdio, trackno)); cddb_disc_add_track (pcddb_disc, pcddb_track); } cddb_disc_calc_discid (pcddb_disc); #if DEBUG guint discid = cddb_disc_get_discid (pcddb_disc); AUDDBG ("CDDB disc id = %x\n", discid); #endif gint matches; if ((matches = cddb_query (pcddb_conn, pcddb_disc)) == -1) { if (cddb_errno (pcddb_conn) == CDDB_ERR_OK) cdaudio_error ("Failed to query the CDDB server"); else cdaudio_error ("Failed to query the CDDB server: %s", cddb_error_str (cddb_errno (pcddb_conn))); cddb_disc_destroy (pcddb_disc); pcddb_disc = NULL; } else { if (matches == 0) { AUDDBG ("no cddb info available for this disc\n"); cddb_disc_destroy (pcddb_disc); pcddb_disc = NULL; } else { AUDDBG ("CDDB disc category = \"%s\"\n", cddb_disc_get_category_str (pcddb_disc)); cddb_read (pcddb_conn, pcddb_disc); if (cddb_errno (pcddb_conn) != CDDB_ERR_OK) { cdaudio_error ("failed to read the cddb info: %s", cddb_error_str (cddb_errno (pcddb_conn))); cddb_disc_destroy (pcddb_disc); pcddb_disc = NULL; } else { cdaudio_set_strinfo (&trackinfo[0], cddb_disc_get_artist (pcddb_disc), cddb_disc_get_title (pcddb_disc), cddb_disc_get_genre (pcddb_disc)); gint trackno; for (trackno = firsttrackno; trackno <= lasttrackno; trackno++) { cddb_track_t *pcddb_track = cddb_disc_get_track (pcddb_disc, trackno - 1); cdaudio_set_strinfo (&trackinfo[trackno], cddb_track_get_artist (pcddb_track), cddb_track_get_title (pcddb_track), cddb_disc_get_genre (pcddb_disc)); } } } } } } if (pcddb_disc != NULL) cddb_disc_destroy (pcddb_disc); if (pcddb_conn != NULL) cddb_destroy (pcddb_conn); } return; ERR: g_free (trackinfo); trackinfo = NULL; }
void *pyrip_thread (void *arg) { printf ("in thread first\n"); thread_arg_s *thread_arg = (thread_arg_s *)arg; char **filenames_c = thread_arg->filenames_c; text_tag_s **text_tags = thread_arg->text_tags; rip_opts_s *rip_opts = thread_arg->rip_opts; int size = thread_arg->size; char *device = thread_arg->device; cdrom_drive *drive; int i; /* child thread*/ printf ("in thread\n"); printf ("thread_arg: %s\n", thread_arg->device); printf ("device: %s\n", device); if (strcmp (device, "auto") == 0) { drive = cdda_find_a_cdrom (0, NULL); } else { drive = cdda_identify (device, 0, NULL); } if (drive == NULL) { log_msg ("Couldn't get a CD drive", FL, FN, LN); exit (1); } cdda_open (drive); if (filenames_c == NULL) { log_msg ("Error allocating filenames_c", FL, FN, LN); } for (i = 0; i < size; i++) { print_text_tag (text_tags[i]); } rip (drive, text_tags, filenames_c); for (i = 0; i < size; i++) { //free_text_tag (text_tags[i]); printf ("freeing filename\n"); free (filenames_c[i]); } //free (text_tags); printf ("freeing filenames\n"); free (filenames_c); printf ("freeing device\n"); free (device); printf ("freeing rip opts\n"); free_rip_opts (rip_opts); printf ("freeing thread arg\n"); free (thread_arg); //Py_DECREF (tags); //cdda_close (drive); printf ("done freeing, detaching\n"); pthread_detach (pthread_self ()); printf ("done\n"); return NULL; }
static int open_cdda(stream_t *st,int m, void* opts, int* file_format) { struct cdda_params* p = (struct cdda_params*)opts; int mode = p->paranoia_mode; int offset = p->toc_offset; #ifndef HAVE_LIBCDIO cdrom_drive* cdd = NULL; #else cdrom_drive_t* cdd = NULL; #endif cdda_priv* priv; cd_info_t *cd_info,*cddb_info = NULL; unsigned int audiolen=0; int last_track; int i; char *xmcd_file = NULL; if(m != STREAM_READ) { m_struct_free(&stream_opts,opts); return STREAM_UNSUPORTED; } if(!p->device) { if (cdrom_device) p->device = strdup(cdrom_device); else p->device = strdup(DEFAULT_CDROM_DEVICE); } #ifdef HAVE_CDDB // cdd_identify returns -1 if it cannot read the TOC, // in which case there is no point in calling cddb_resolve if(cdd_identify(p->device) >= 0 && strncmp(st->url,"cddb",4) == 0) { i = cddb_resolve(p->device, &xmcd_file); if(i == 0) { cddb_info = cddb_parse_xmcd(xmcd_file); free(xmcd_file); } } #endif #ifndef HAVE_LIBCDIO if(p->generic_dev) cdd = cdda_identify_scsi(p->generic_dev,p->device,0,NULL); else #endif #if defined(__NetBSD__) cdd = cdda_identify_scsi(p->device,p->device,0,NULL); #else cdd = cdda_identify(p->device,0,NULL); #endif if(!cdd) { mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_MPDEMUX_CDDA_CantOpenCDDADevice); m_struct_free(&stream_opts,opts); free(cddb_info); return STREAM_ERROR; } cdda_verbose_set(cdd, CDDA_MESSAGE_FORGETIT, CDDA_MESSAGE_FORGETIT); if(p->sector_size) { cdd->nsectors = p->sector_size; #ifndef HAVE_LIBCDIO cdd->bigbuff = p->sector_size * CD_FRAMESIZE_RAW; #endif } if(cdda_open(cdd) != 0) { mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_MPDEMUX_CDDA_CantOpenDisc); cdda_close(cdd); m_struct_free(&stream_opts,opts); free(cddb_info); return STREAM_ERROR; } cd_info = cd_info_new(); mp_msg(MSGT_OPEN,MSGL_INFO,MSGTR_MPDEMUX_CDDA_AudioCDFoundWithNTracks,cdda_tracks(cdd)); for(i=0;i<cdd->tracks;i++) { char track_name[80]; long sec=cdda_track_firstsector(cdd,i+1); long off=cdda_track_lastsector(cdd,i+1)-sec+1; sprintf(track_name, "Track %d", i+1); cd_info_add_track(cd_info, track_name, i+1, (unsigned int)(off/(60*75)), (unsigned int)((off/75)%60), (unsigned int)(off%75), sec, off ); audiolen += off; } cd_info->min = (unsigned int)(audiolen/(60*75)); cd_info->sec = (unsigned int)((audiolen/75)%60); cd_info->msec = (unsigned int)(audiolen%75); priv = malloc(sizeof(cdda_priv)); memset(priv, 0, sizeof(cdda_priv)); priv->cd = cdd; priv->cd_info = cd_info; if(p->toc_bias) offset -= cdda_track_firstsector(cdd,1); if(offset) { int i; for(i = 0 ; i < cdd->tracks + 1 ; i++) cdd->disc_toc[i].dwStartSector += offset; } if(p->speed) cdda_speed_set(cdd,p->speed); last_track = cdda_tracks(cdd); if (p->span.start > last_track) p->span.start = last_track; if (p->span.end < p->span.start) p->span.end = p->span.start; if (p->span.end > last_track) p->span.end = last_track; if(p->span.start) priv->start_sector = cdda_track_firstsector(cdd,p->span.start); else priv->start_sector = cdda_disc_firstsector(cdd); if(p->span.end) { priv->end_sector = cdda_track_lastsector(cdd,p->span.end); } else priv->end_sector = cdda_disc_lastsector(cdd); priv->cdp = paranoia_init(cdd); if(priv->cdp == NULL) { cdda_close(cdd); free(priv); cd_info_free(cd_info); m_struct_free(&stream_opts,opts); free(cddb_info); return STREAM_ERROR; } if(mode == 0) mode = PARANOIA_MODE_DISABLE; else if(mode == 1) mode = PARANOIA_MODE_OVERLAP; else mode = PARANOIA_MODE_FULL; if(p->no_skip) mode |= PARANOIA_MODE_NEVERSKIP; #ifndef HAVE_LIBCDIO paranoia_modeset(cdd, mode); if(p->search_overlap >= 0) paranoia_overlapset(cdd,p->search_overlap); #else paranoia_modeset(priv->cdp, mode); if(p->search_overlap >= 0) paranoia_overlapset(priv->cdp,p->search_overlap); #endif paranoia_seek(priv->cdp,priv->start_sector,SEEK_SET); priv->sector = priv->start_sector; #ifdef HAVE_CDDB if(cddb_info) { cd_info_free(cd_info); priv->cd_info = cddb_info; cd_info_debug( cddb_info ); } #endif st->priv = priv; st->start_pos = priv->start_sector*CD_FRAMESIZE_RAW; st->end_pos = priv->end_sector*CD_FRAMESIZE_RAW; st->type = STREAMTYPE_CDDA; st->sector_size = CD_FRAMESIZE_RAW; st->fill_buffer = fill_buffer; st->seek = seek; st->close = close_cdda; *file_format = DEMUXER_TYPE_RAWAUDIO; m_struct_free(&stream_opts,opts); return STREAM_OK; }
int main(int argc,char *argv[]) { int toc_bias = 0; int force_cdrom_endian = -1; int output_type = 1; /* 0=raw, 1=wav, 2=aifc */ int output_endian = 0; /* -1=host, 0=little, 1=big */ int query_only = 0; int batch = 0; int run_cache_test = 0; long int force_cdrom_overlap = -1; long int force_cdrom_sectors = -1; long int force_cdrom_speed = 0; long int force_overread = 0; long int sample_offset = 0; long int test_flags = 0; long int toc_offset = 0; long int max_retries = 20; char *logfile_name=NULL; char *reportfile_name=NULL; /* full paranoia, but allow skipping */ int paranoia_mode=PARANOIA_MODE_FULL^PARANOIA_MODE_NEVERSKIP; int out; int c,long_option_index; atexit(cleanup); while((c=getopt_long(argc,argv,optstring,options,&long_option_index))!=EOF){ switch(c){ case 'a': output_type=2; output_endian=1; break; case 'B': batch=1; break; case 'c': force_cdrom_endian=0; break; case 'C': force_cdrom_endian=1; break; case 'e': callscript=1; fprintf(stderr, "Sending all callback output to stderr for wrapper script\n"); break; case 'f': output_type=3; output_endian=1; break; case 'F': paranoia_mode&=~(PARANOIA_MODE_FRAGMENT); break; case 'g': case 'k': case 'd': if (force_cdrom_device) { fprintf(stderr, "Multiple cdrom devices given. Previous device %s ignored\n", force_cdrom_device); free(force_cdrom_device); } force_cdrom_device=strdup(optarg); break; case 'h': usage(stdout); exit(0); case 'l': if(logfile_name)free(logfile_name); logfile_name=NULL; if(optarg) logfile_name=strdup(optarg); logfile_open=1; break; case 'L': if(reportfile_name)free(reportfile_name); reportfile_name=NULL; if(optarg) reportfile_name=strdup(optarg); reportfile_open=1; break; case 'm': { long int mmc_timeout_sec; if (get_int_arg(c, &mmc_timeout_sec)) { mmc_timeout_ms = 1000*mmc_timeout_sec; } } break; case 'n': get_int_arg(c, &force_cdrom_sectors); break; case 'o': get_int_arg(c, &force_cdrom_overlap); break; case 'O': get_int_arg(c, &sample_offset); break; case 'p': output_type=0; output_endian=-1; break; case 'r': output_type=0; output_endian=0; break; case 'q': verbose=CDDA_MESSAGE_FORGETIT; quiet=1; break; case 'Q': query_only=1; break; case 'R': output_type=0; output_endian=1; break; case 'S': get_int_arg(c, &force_cdrom_speed); break; case 't': get_int_arg(c, &toc_offset); break; case 'T': toc_bias=-1; break; case 'v': verbose=CDDA_MESSAGE_PRINTIT; quiet=0; break; case 'V': fprintf(stderr,PARANOIA_VERSION); fprintf(stderr,"\n"); exit(0); break; case 'w': output_type=1; output_endian=0; break; case 'W': paranoia_mode&=~PARANOIA_MODE_REPAIR; break; case 'x': get_int_arg(c, &test_flags); break; case 'X': /*paranoia_mode&=~(PARANOIA_MODE_SCRATCH|PARANOIA_MODE_REPAIR);*/ abort_on_skip=1; break; case 'Y': paranoia_mode|=PARANOIA_MODE_OVERLAP; /* cdda2wav style overlap check only */ paranoia_mode&=~PARANOIA_MODE_VERIFY; break; case 'Z': paranoia_mode=PARANOIA_MODE_DISABLE; break; case 'A': run_cache_test=1; query_only=1; reportfile_open=1; verbose=CDDA_MESSAGE_PRINTIT; break; case 'z': if (optarg) { get_int_arg(c, &max_retries); paranoia_mode&=~PARANOIA_MODE_NEVERSKIP; } else { paranoia_mode|=PARANOIA_MODE_NEVERSKIP; } break; case 'E': force_overread=1; break; default: usage(stderr); exit(1); } } if(logfile_open){ if(logfile_name==NULL) logfile_name=strdup("cdparanoia.log"); if(!strcmp(logfile_name,"-")){ logfile=stdout; logfile_open=0; }else{ logfile=fopen(logfile_name,"w"); if(logfile==NULL){ report("Cannot open log summary file %s: %s",logfile_name, strerror(errno)); exit(1); } } } if(reportfile_open){ if(reportfile_name==NULL) reportfile_name=strdup("cdparanoia.log"); if(!strcmp(reportfile_name,"-")){ reportfile=stdout; reportfile_open=0; }else{ if(logfile_name && !strcmp(reportfile_name,logfile_name)){ reportfile=logfile; reportfile_open=0; }else{ reportfile=fopen(reportfile_name,"w"); if(reportfile==NULL){ report("Cannot open debug log file %s: %s",reportfile_name, strerror(errno)); exit(1); } } } } if(logfile){ /* log command line and version */ int i; for (i = 0; i < argc; i++) fprintf(logfile,"%s ",argv[i]); fprintf(logfile,"\n"); if(reportfile!=logfile){ fprintf(logfile,VERSION); fprintf(logfile,"\n"); fprintf(logfile,"Using cdda library version: %s\n",cdda_version()); fprintf(logfile,"Using paranoia library version: %s\n",paranoia_version()); } fflush(logfile); } if(reportfile && reportfile!=logfile){ /* log command line */ int i; for (i = 0; i < argc; i++) fprintf(reportfile,"%s ",argv[i]); fprintf(reportfile,"\n"); fflush(reportfile); } if(optind>=argc && !query_only){ if(batch) span=NULL; else{ /* D'oh. No span. Fetch me a brain, Igor. */ usage(stderr); exit(1); } }else if (argv[optind]) span=strdup(argv[optind]); report(PARANOIA_VERSION); if(verbose){ report("Using cdda library version: %s",cdda_version()); report("Using paranoia library version: %s",paranoia_version()); } /* Query the cdrom/disc; we may need to override some settings */ if(force_cdrom_device) d=cdda_identify(force_cdrom_device,verbose,NULL); else { driver_id_t driver_id; char **ppsz_cd_drives = cdio_get_devices_with_cap_ret(NULL, CDIO_FS_AUDIO, false, &driver_id); if (ppsz_cd_drives && *ppsz_cd_drives) { d=cdda_identify(*ppsz_cd_drives,verbose, NULL); } else { report("\nUnable find or access a CD-ROM drive with an audio CD" " in it."); report("\nYou might try specifying the drive, especially if it has" " mixed-mode (and non-audio) format tracks"); exit(1); } cdio_free_device_list(ppsz_cd_drives); } if(!d){ if(!verbose) report("\nUnable to open cdrom drive; -v might give more information."); exit(1); } if(verbose) cdda_verbose_set(d,CDDA_MESSAGE_PRINTIT,CDDA_MESSAGE_PRINTIT); else cdda_verbose_set(d,CDDA_MESSAGE_PRINTIT,CDDA_MESSAGE_FORGETIT); /* possibly force hand on endianness of drive, sector request size */ if(force_cdrom_endian!=-1){ d->bigendianp=force_cdrom_endian; switch(force_cdrom_endian){ case 0: report("Forcing CDROM sense to little-endian; ignoring preset and autosense"); break; case 1: report("Forcing CDROM sense to big-endian; ignoring preset and autosense"); break; } } if (force_cdrom_sectors!=-1) { if(force_cdrom_sectors<0 || force_cdrom_sectors>100){ report("Default sector read size must be 1<= n <= 100\n"); cdda_close(d); d=NULL; exit(1); } report("Forcing default to read %ld sectors; " "ignoring preset and autosense",force_cdrom_sectors); d->nsectors=force_cdrom_sectors; } if (force_cdrom_overlap!=-1) { if (force_cdrom_overlap<0 || force_cdrom_overlap>CDIO_CD_FRAMES_PER_SEC) { report("Search overlap sectors must be 0<= n <=75\n"); cdda_close(d); d=NULL; if(logfile && logfile != stdout) fclose(logfile); exit(1); } report("Forcing search overlap to %ld sectors; " "ignoring autosense",force_cdrom_overlap); } switch( cdda_open(d) ) { case -2:case -3:case -4:case -5: report("\nUnable to open disc. Is there an audio CD in the drive?"); exit(1); case -6: report("\nCdparanoia could not find a way to read audio from this drive."); exit(1); case 0: break; default: report("\nUnable to open disc."); exit(1); } d->i_test_flags = test_flags; if (force_cdrom_speed == 0) force_cdrom_speed = -1; if (force_cdrom_speed != -1) { report("\nAttempting to set speed to %ldx... ", force_cdrom_speed); } else { if (verbose) report("\nAttempting to set cdrom to full speed... "); } if (cdda_speed_set(d, force_cdrom_speed)) { if (verbose || force_cdrom_speed != -1) report("\tCDROM speed set FAILED. Continuing anyway..."); } else { if (verbose) report("\tdrive returned OK."); } if(run_cache_test){ int warn=analyze_cache(d, stderr, reportfile, force_cdrom_speed); if(warn==0){ reportC("\nDrive tests OK with Paranoia.\n\n"); return 0; } if(warn==1) reportC("\nWARNING! PARANOIA MAY NOT BE TRUSTWORTHY WITH THIS DRIVE!\n" "\nThe Paranoia library may not model this CDROM drive's cache" "\ncorrectly according to this analysis run. Analysis is not" "\nalways accurate (it can be fooled by machine load or random" "\nkernel latencies), but if a failed result happens more often" "\nthan one time in twenty on an unloaded machine, please mail" "\nthe %s file produced by this failed analysis to" "\[email protected] to assist developers in extending" "\nParanoia to handle this CDROM properly.\n\n",reportfile_name); return 1; } /* Dump the TOC */ if (query_only || verbose ) display_toc(d); if (query_only) exit(0); /* bias the disc. A hack. Of course. this is never the default. */ /* Some CD-ROM/CD-R drives will add an offset to the position on reading audio data. This is usually around 500-700 audio samples (ca. 1/75 second) on reading. So when this program queries a specific sector, it might not receive exactly that sector, but shifted by some amount. Note that if ripping includes the end of the CD, this will this cause this program to attempt to read partial sectors before or past the known user data area of the disc, probably causing read errors on most drives and possibly even hard lockups on some buggy hardware. [Note to libcdio driver hackers: make sure all CD-drivers don't try to read outside of the stated disc boundaries.] */ if(sample_offset){ toc_offset+=sample_offset/588; sample_offset%=588; if(sample_offset<0){ sample_offset+=588; toc_offset--; } } if (toc_bias) { toc_offset = -cdda_track_firstsector(d,1); } { int i; for( i=0; i < d->tracks+1; i++ ) d->disc_toc[i].dwStartSector+=toc_offset; } if (d->nsectors==1) { report("WARNING: The autosensed/selected sectors per read value is\n" " one sector, making it very unlikely Paranoia can \n" " work.\n\n" " Attempting to continue...\n\n"); } /* parse the span, set up begin and end sectors */ { long i_first_lsn; long i_last_lsn; long batch_first; long batch_last; int batch_track; if (span) { /* look for the hyphen */ char *span2=strchr(span,'-'); if(strrchr(span,'-')!=span2){ report("Error parsing span argument"); exit(1); } if (span2!=NULL) { *span2='\0'; span2++; } i_first_lsn=parse_offset(d, span, -1); if(i_first_lsn==-1) i_last_lsn=parse_offset(d, span2, cdda_disc_firstsector(d)); else i_last_lsn=parse_offset(d, span2, i_first_lsn); if (i_first_lsn == -1) { if (i_last_lsn == -1) { report("Error parsing span argument"); exit(1); } else { i_first_lsn=cdda_disc_firstsector(d); } } else { if (i_last_lsn==-1) { if (span2) { /* There was a hyphen */ i_last_lsn=cdda_disc_lastsector(d); } else { i_last_lsn= cdda_track_lastsector(d,cdda_sector_gettrack(d, i_first_lsn)); } } } } else { i_first_lsn = cdda_disc_firstsector(d); i_last_lsn = cdda_disc_lastsector(d); } { int track1 = cdda_sector_gettrack(d, i_first_lsn); int track2 = cdda_sector_gettrack(d, i_last_lsn); long off1 = i_first_lsn - cdda_track_firstsector(d, track1); long off2 = i_last_lsn - cdda_track_firstsector(d, track2); int i; for( i=track1; i<=track2; i++ ) { if(i != 0 && !cdda_track_audiop(d,i)){ report("Selected span contains non audio track at track %02d. Aborting.\n\n", i); exit(1); if (i == 0) i = cdio_get_first_track_num(d->p_cdio) - 1; } } report("Ripping from sector %7ld (track %2d [%d:%02d.%02d])\n" "\t to sector %7ld (track %2d [%d:%02d.%02d])\n", i_first_lsn, track1, (int) (off1/(CDIO_CD_FRAMES_PER_MIN)), (int) ((off1/CDIO_CD_FRAMES_PER_SEC) % CDIO_CD_SECS_PER_MIN), (int)(off1 % CDIO_CD_FRAMES_PER_SEC), i_last_lsn, track2, (int) (off2/(CDIO_CD_FRAMES_PER_MIN)), (int) ((off2/CDIO_CD_FRAMES_PER_SEC) % CDIO_CD_SECS_PER_MIN), (int)(off2 % CDIO_CD_FRAMES_PER_SEC)); } if (toc_offset && !force_overread) { d->disc_toc[d->tracks].dwStartSector -= toc_offset; if (i_last_lsn > cdda_track_lastsector(d, d->tracks)) i_last_lsn -= toc_offset; } { long cursor; int16_t offset_buffer[1176]; int offset_buffer_used=0; int offset_skip=sample_offset*4; off_t sectorlen; #if defined(HAVE_GETUID) && (defined(HAVE_SETEUID) || defined(HAVE_SETEGID)) int dummy __attribute__((unused)); #endif p=paranoia_init(d); paranoia_modeset(p,paranoia_mode); if(force_cdrom_overlap!=-1)paranoia_overlapset(p,force_cdrom_overlap); if(verbose) { cdda_verbose_set(d,CDDA_MESSAGE_LOGIT,CDDA_MESSAGE_LOGIT); cdio_loglevel_default = CDIO_LOG_INFO; } else cdda_verbose_set(d,CDDA_MESSAGE_FORGETIT,CDDA_MESSAGE_FORGETIT); paranoia_seek(p,cursor=i_first_lsn,SEEK_SET); /* this is probably a good idea in general */ #if defined(HAVE_GETUID) && defined(HAVE_SETEUID) dummy = seteuid(getuid()); #endif #if defined(HAVE_GETGID) && defined(HAVE_SETEGID) dummy = setegid(getgid()); #endif /* we'll need to be able to read one sector past user data if we have a sample offset in order to pick up the last bytes. We need to set the disc length forward here so that the libs are willing to read past, assuming that works on the hardware, of course */ if(sample_offset && force_overread) d->disc_toc[d->tracks].dwStartSector++; while(cursor<=i_last_lsn){ char outfile_name[PATH_MAX]; if ( batch ){ batch_first = cursor; batch_track = cdda_sector_gettrack(d,cursor); batch_last = cdda_track_lastsector(d, batch_track); if (batch_last>i_last_lsn) batch_last=i_last_lsn; } else { batch_first = i_first_lsn; batch_last = i_last_lsn; batch_track = -1; } callbegin=batch_first; callend=batch_last; /* argv[optind] is the span, argv[optind+1] (if exists) is outfile */ if (optind+1<argc) { if (!strcmp(argv[optind+1],"-") ){ out = dup(fileno(stdout)); if(out==-1){ report("Cannot dupplicate stdout: %s", strerror(errno)); exit(1); } if(batch) report("Are you sure you wanted 'batch' " "(-B) output with stdout?"); report("outputting to stdout\n"); if(logfile){ fprintf(logfile,"outputting to stdout\n"); fflush(logfile); } outfile_name[0]='\0'; } else { char dirname[PATH_MAX]; char *basename=split_base_dir(argv[optind+1], dirname, PATH_MAX); if (NULL == basename) { report("Output filename too long"); exit(1); } if(batch) { if (strlen(argv[optind+1]) - 10 > PATH_MAX) { report("Output filename too long"); exit(1); } snprintf(outfile_name, PATH_MAX, " %strack%02d.%s", dirname, batch_track, basename); } else snprintf(outfile_name, PATH_MAX, "%s%s", dirname, basename); if(basename[0]=='\0'){ switch (output_type) { case 0: /* raw */ strncat(outfile_name, "cdda.raw", sizeof("cdda.raw")); break; case 1: strncat(outfile_name, "cdda.wav", sizeof("cdda.wav")); break; case 2: strncat(outfile_name, "cdda.aifc", sizeof("cdda.aifc")); break; case 3: strncat(outfile_name, "cdda.aiff", sizeof("cdda.aiff")); break; } } out=open(outfile_name,O_RDWR|O_CREAT|O_TRUNC|O_BINARY,0666); if(out==-1){ report("Cannot open specified output file %s: %s", outfile_name, strerror(errno)); exit(1); } report("outputting to %s\n", outfile_name); if(logfile){ fprintf(logfile,"outputting to %s\n",outfile_name); fflush(logfile); } } } else { /* default */ if (batch) sprintf(outfile_name,"track%02d.", batch_track); else outfile_name[0]='\0'; switch(output_type){ case 0: /* raw */ strncat(outfile_name, "cdda.raw", sizeof("cdda.raw")); break; case 1: strncat(outfile_name, "cdda.wav", sizeof("cdda.wav")); break; case 2: strncat(outfile_name, "cdda.aifc", sizeof("cdda.aifc")); break; case 3: strncat(outfile_name, "cdda.aiff", sizeof("cdda.aiff")); break; } out = open(outfile_name, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666); if(out==-1){ report("Cannot open default output file %s: %s", outfile_name, strerror(errno)); exit(1); } report("outputting to %s\n", outfile_name); if(logfile){ fprintf(logfile,"outputting to %s\n",outfile_name); fflush(logfile); } } sectorlen = batch_last - batch_first + 1; if (cdda_sector_gettrack(d, cursor) == d->tracks && toc_offset > 0 && !force_overread){ sectorlen += toc_offset; } switch(output_type) { case 0: /* raw */ break; case 1: /* wav */ WriteWav(out, sectorlen * CD_FRAMESIZE_RAW); break; case 2: /* aifc */ WriteAifc(out, sectorlen * CD_FRAMESIZE_RAW); break; case 3: /* aiff */ WriteAiff(out, sectorlen * CD_FRAMESIZE_RAW); break; } /* Off we go! */ if(offset_buffer_used){ /* partial sector from previous batch read */ cursor++; if (buffering_write(out, ((char *)offset_buffer)+offset_buffer_used, CDIO_CD_FRAMESIZE_RAW-offset_buffer_used)){ report("Error writing output: %s", strerror(errno)); exit(1); } } skipped_flag=0; while(cursor<=batch_last){ /* read a sector */ int16_t *readbuf=paranoia_read_limited(p, callback, max_retries); char *err=cdda_errors(d); char *mes=cdda_messages(d); if(mes || err) fprintf(stderr,"\r " " \r%s%s\n", mes?mes:"",err?err:""); if (err) free(err); if (mes) free(mes); if( readbuf==NULL) { if(errno==EBADF || errno==ENOMEDIUM){ report("\nparanoia_read: CDROM drive unavailable, bailing.\n"); exit(1); } skipped_flag=1; report("\nparanoia_read: Unrecoverable error, bailing.\n"); break; } if(skipped_flag && abort_on_skip){ cursor=batch_last+1; break; } skipped_flag=0; cursor++; if (output_endian!=bigendianp()) { int i; for (i=0; i<CDIO_CD_FRAMESIZE_RAW/2; i++) readbuf[i]=UINT16_SWAP_LE_BE_C(readbuf[i]); } callback(cursor*(CD_FRAMEWORDS)-1, PARANOIA_CB_WROTE); if (buffering_write(out,((char *)readbuf)+offset_skip, CDIO_CD_FRAMESIZE_RAW-offset_skip)){ report("Error writing output: %s", strerror(errno)); exit(1); } offset_skip=0; if (output_endian != bigendianp()){ int i; for (i=0; i<CDIO_CD_FRAMESIZE_RAW/2; i++) readbuf[i] = UINT16_SWAP_LE_BE_C(readbuf[i]); } /* One last bit of silliness to deal with sample offsets */ if(sample_offset && cursor>batch_last){ if (cdda_sector_gettrack(d, batch_last) < d->tracks || force_overread) { int i; /* Need to flush the buffer when overreading into the leadout */ if (cdda_sector_gettrack(d, batch_last) == d->tracks) paranoia_seek(p, cursor, SEEK_SET); /* read a sector and output the partial offset. Save the rest for the next batch iteration */ readbuf=paranoia_read_limited(p,callback,max_retries); err=cdda_errors(d);mes=cdda_messages(d); if(mes || err) fprintf(stderr,"\r " " \r%s%s\n", mes?mes:"",err?err:""); if(err)free(err);if(mes)free(mes); if(readbuf==NULL){ skipped_flag=1; report("\nparanoia_read: Unrecoverable error reading through " "sample_offset shift\n\tat end of track, bailing.\n"); break; } if (skipped_flag && abort_on_skip) break; skipped_flag=0; /* do not move the cursor */ if(output_endian!=bigendianp()) for(i=0;i<CD_FRAMESIZE_RAW/2;i++) offset_buffer[i]=UINT16_SWAP_LE_BE_C(readbuf[i]); else memcpy(offset_buffer,readbuf,CD_FRAMESIZE_RAW); offset_buffer_used=sample_offset*4; callback(cursor* (CD_FRAMEWORDS), PARANOIA_CB_WROTE); } else { memset(offset_buffer, 0, sizeof(offset_buffer)); offset_buffer_used = sample_offset * 4; } if(buffering_write(out,(char *)offset_buffer, offset_buffer_used)){ report("Error writing output: %s", strerror(errno)); exit(1); } } } /* Write sectors of silent audio to compensate for missing samples that would be in the leadout */ if (cdda_sector_gettrack(d, batch_last) == d->tracks && toc_offset > 0 && !force_overread) { char *silence; size_t missing_sector_bytes = CD_FRAMESIZE_RAW * toc_offset; silence = calloc(toc_offset, CD_FRAMESIZE_RAW); if (!silence || buffering_write(out, silence, missing_sector_bytes)) { report("Error writing output: %s", strerror(errno)); exit(1); } free(silence); } callback(cursor* (CDIO_CD_FRAMESIZE_RAW/2)-1, PARANOIA_CB_FINISHED); buffering_close(out); if(skipped_flag){ /* remove the file */ report("\nRemoving aborted file: %s", outfile_name); unlink(outfile_name); /* make the cursor correct if we have another track */ if(batch_track!=-1){ batch_track++; cursor=cdda_track_firstsector(d,batch_track); paranoia_seek(p,cursor, SEEK_SET); offset_skip=sample_offset*4; offset_buffer_used=0; } } report("\n"); } paranoia_free(p); p=NULL; } } report("Done.\n\n"); return 0; }
static gboolean gst_cd_paranoia_src_open (GstCddaBaseSrc * cddabasesrc, const gchar * device) { GstCdParanoiaSrc *src = GST_CD_PARANOIA_SRC (cddabasesrc); gint i; GST_DEBUG_OBJECT (src, "trying to open device %s (generic-device=%s) ...", device, GST_STR_NULL (src->generic_device)); /* find the device */ if (src->generic_device != NULL) { src->d = cdda_identify_scsi (src->generic_device, device, FALSE, NULL); } else { if (device != NULL) { src->d = cdda_identify (device, FALSE, NULL); } else { src->d = cdda_identify ("/dev/cdrom", FALSE, NULL); } } /* fail if the device couldn't be found */ if (src->d == NULL) goto no_device; /* set verbosity mode */ cdda_verbose_set (src->d, CDDA_MESSAGE_FORGETIT, CDDA_MESSAGE_FORGETIT); /* open the disc */ if (cdda_open (src->d)) goto open_failed; if (src->read_speed != -1) { cdda_speed_set (src->d, src->read_speed); } for (i = 1; i < src->d->tracks + 1; i++) { GstCddaBaseSrcTrack track = { 0, }; track.num = i; track.is_audio = IS_AUDIO (src->d, i - 1); track.start = cdda_track_firstsector (src->d, i); track.end = cdda_track_lastsector (src->d, i); track.tags = NULL; gst_cdda_base_src_add_track (GST_CDDA_BASE_SRC (src), &track); } /* create the paranoia struct and set it up */ src->p = paranoia_init (src->d); if (src->p == NULL) goto init_failed; paranoia_modeset (src->p, src->paranoia_mode); if (src->search_overlap != -1) paranoia_overlapset (src->p, src->search_overlap); src->next_sector = -1; return TRUE; /* ERRORS */ no_device: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (_("Could not open CD device for reading.")), ("cdda_identify failed")); return FALSE; } open_failed: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (_("Could not open CD device for reading.")), ("cdda_open failed")); cdda_close (src->d); src->d = NULL; return FALSE; } init_failed: { GST_ELEMENT_ERROR (src, LIBRARY, INIT, ("failed to initialize paranoia"), ("failed to initialize paranoia")); return FALSE; } }
unsigned LocalAudioCD::Create(const std::string& device, AudioCDPtr *pcd) { *pcd = AudioCDPtr(NULL); TRACE << "Calling identify\n"; cdrom_drive *cdt = cdda_identify(device.c_str(), CDDA_MESSAGE_FORGETIT, NULL); if (!cdt) { TRACE << "Can't identify CD drive\n"; return EINVAL; } TRACE << "Identified\n"; int rc = cdda_open(cdt); if (rc<0) { TRACE << "Can't open CD drive\n"; return (unsigned)errno; } TRACE << "Opened\n"; unsigned int total = (unsigned int)cdda_tracks(cdt); TRACE << "Got tracks\n"; if (total == (track_t)-1) { cdda_close(cdt); TRACE << "No audio tracks\n"; return ENOENT; } toc_t toc; unsigned total_sectors = 0; for (track_t i=1; i<=total; ++i) // Peculiar 1-based numbering { if (cdda_track_audiop(cdt, i)) { TocEntry te; te.first_sector = (int)cdda_track_firstsector(cdt, i); te.last_sector = (int)cdda_track_lastsector(cdt, i); TRACE << "Track " << i << " " << te.first_sector << ".." << te.last_sector << "\n"; toc.push_back(te); total_sectors += (unsigned)(te.last_sector - te.first_sector + 1); } else { // TRACE << "Track " << i+1 << " not audio\n"; } } if (toc.empty()) { cdda_close(cdt); TRACE << "No audio tracks\n"; return ENOENT; } TRACE << "Opened with " << toc.size() << " tracks\n"; LocalAudioCD *cd = new LocalAudioCD(); cd->m_toc = toc; cd->m_cdt = cdt; cd->m_total_sectors = total_sectors; *pcd = AudioCDPtr(cd); return 0; }