cd_info_t *cddb_parse_xmcd(char *xmcd_file) { cd_info_t *cd_info = NULL; int length, pos = 0; char *ptr, *ptr2; unsigned int audiolen; if (xmcd_file == NULL) return NULL; cd_info = cd_info_new(); if (cd_info == NULL) { return NULL; } length = strlen(xmcd_file); ptr = xmcd_file; while (ptr != NULL && pos < length) { // Read a line ptr2 = ptr; while(ptr2[0] != '\0' && ptr2[0] != '\r' && ptr2[0] != '\n') ptr2++; if (ptr2[0] == '\0') { break; } ptr2[0] = '\0'; // Ignore comments if (ptr[0] != '#') { // Search for the album title if (xmcd_parse_dtitle(cd_info, ptr)) ; // Search for the genre else if (xmcd_parse_dgenre(cd_info, ptr)) ; // Search for a track title else if (xmcd_parse_ttitle(cd_info, ptr)) audiolen++; // <-- audiolen++ to shut up gcc warning } if (ptr2[1] == '\n') ptr2++; pos = (ptr2 + 1) - ptr; ptr = ptr2 + 1; } audiolen = cdtoc[cd_info->nb_tracks].frame-cdtoc[0].frame; cd_info->min = (unsigned int) (audiolen / (60 * 75)); cd_info->sec = (unsigned int) ((audiolen / 75) % 60); cd_info->msec = (unsigned int) (audiolen % 75); return cd_info; }
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; }