static cddb_disc_t * create_disc(CdIo_t *cdio) { cddb_disc_t *disc = cddb_disc_new(); if (disc) { const lba_t leadout_lba = cdio_get_track_lba(cdio, CDIO_CDROM_LEADOUT_TRACK); cddb_disc_set_length(disc, leadout_lba / CDIO_CD_FRAMES_PER_SEC); const track_t first_track = cdio_get_first_track_num(cdio); const track_t num_tracks = cdio_get_num_tracks(cdio); if (leadout_lba == CDIO_INVALID_LBA || first_track == CDIO_INVALID_TRACK || num_tracks == CDIO_INVALID_TRACK) { trace("cda: create_disc failed, invalid CD disc format\n"); cddb_disc_destroy(disc); return NULL; } const track_t last_track = first_track + num_tracks; for (track_t i = first_track; i < last_track; i++) { cddb_track_t *track = cddb_track_new(); if (!track) { cddb_disc_destroy(disc); return NULL; } const lba_t offset = cdio_get_track_lba(cdio, i); cddb_track_set_frame_offset(track, offset); cddb_disc_add_track(disc, track); } cddb_disc_calc_discid(disc); } return disc; }
static int cda_init (DB_fileinfo_t *_info, DB_playItem_t *it) { cdda_info_t *info = (cdda_info_t *)_info; trace ("cdda: init %s\n", deadbeef->pl_find_meta (it, ":URI")); size_t l = strlen (deadbeef->pl_find_meta (it, ":URI")); char location[l+1]; memcpy (location, deadbeef->pl_find_meta (it, ":URI"), l+1); char *nr = strchr (location, '#'); if (nr) { *nr = 0; nr++; } else { trace ("cdda: bad name: %s\n", deadbeef->pl_find_meta (it, ":URI")); return -1; } int track_nr = atoi (nr); char *fname = (*location) ? location : NULL; //NULL if empty string; means pysical CD drive info->cdio = cdio_open (fname, DRIVER_UNKNOWN); if (!info->cdio) { trace ("cdda: Could not open CD\n"); return -1; } track_t first_track = cdio_get_first_track_num (info->cdio); if (first_track == 0xff) { trace ("cdda: no medium found\n"); return -1; } track_t tracks = cdio_get_num_tracks (info->cdio); track_t i; cddb_track_t *track; cddb_disc_t *disc = cddb_disc_new(); cddb_disc_set_length (disc, cdio_get_track_lba (info->cdio, CDIO_CDROM_LEADOUT_TRACK) / CDIO_CD_FRAMES_PER_SEC); for (i = 0; i < tracks; i++) { lsn_t offset = cdio_get_track_lba (info->cdio, i+first_track); track = cddb_track_new(); cddb_track_set_frame_offset (track, offset); cddb_disc_add_track (disc, track); } cddb_disc_calc_discid (disc); int discid = cddb_disc_get_discid (disc); int trk_discid = deadbeef->pl_find_meta_int (it, ":CDIO_DISCID", 0); if (trk_discid != discid) { cddb_disc_destroy (disc); trace ("cdda: the track belongs to another disc, skipped\n"); return -1; } cddb_disc_destroy (disc); if (TRACK_FORMAT_AUDIO != cdio_get_track_format (info->cdio, track_nr)) { trace ("cdda: Not an audio track (%d)\n", track_nr); return -1; } int channels = cdio_get_track_channels (info->cdio, track_nr); trace ("cdio nchannels: %d\n", channels); _info->plugin = &plugin; _info->fmt.bps = 16; _info->fmt.channels = 2; _info->fmt.samplerate = 44100; _info->fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT; _info->readpos = 0; info->first_sector = cdio_get_track_lsn (info->cdio, track_nr); info->sector_count = cdio_get_track_sec_count (info->cdio, track_nr); info->current_sector = info->first_sector; info->tail_len = 0; info->current_sample = 0; return 0; }
static DB_playItem_t * cda_insert (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname) { trace ("CDA insert: %s\n", fname); CdIo_t* cdio = NULL; int track_nr; DB_playItem_t *res; const char* shortname = strrchr (fname, '/'); if (shortname) { shortname++; } else { shortname = fname; } const char *ext = strrchr (shortname, '.') + 1; int is_image = ext && (0 == strcmp (ext, "nrg")); if (is_image && !deadbeef->conf_get_int ("cdda.enable_nrg", 0)) { return NULL; } if (0 == strcmp (ext, "cda")) { cdio = cdio_open (NULL, DRIVER_UNKNOWN); } else if (is_image) { cdio = cdio_open (fname, DRIVER_NRG); } if (!cdio) { trace ("not an audio disc/image, or file not found (%s)\n", fname); return NULL; } // calculate discid track_t first_track = cdio_get_first_track_num (cdio); if (first_track == 0xff) { trace ("cdda: no medium found\n"); cdio_destroy (cdio); return NULL; } track_t tracks = cdio_get_num_tracks (cdio); track_t i; cddb_track_t *track; cddb_disc_t *disc = cddb_disc_new(); cddb_disc_set_length (disc, cdio_get_track_lba (cdio, CDIO_CDROM_LEADOUT_TRACK) / CDIO_CD_FRAMES_PER_SEC); for (i = 0; i < tracks; i++) { lsn_t offset = cdio_get_track_lba (cdio, i+first_track); track = cddb_track_new(); cddb_track_set_frame_offset (track, offset); cddb_disc_add_track (disc, track); } cddb_disc_calc_discid (disc); int discid = cddb_disc_get_discid (disc); if (0 == strcasecmp (shortname, "all.cda") || is_image) { track_t i; res = after; struct cddb_thread_params *p = malloc (sizeof (struct cddb_thread_params)); memset (p, 0, sizeof (struct cddb_thread_params)); p->cdio = cdio; int enable_cddb = deadbeef->conf_get_int ("cdda.freedb.enable", DEFAULT_USE_CDDB); for (i = 0; i < tracks; i++) { trace ("inserting track %d\n", i); res = insert_single_track (cdio, plt, res, is_image ? fname : NULL, i+first_track, discid); if (res) { p->items[i] = res; } } int got_cdtext = read_disc_cdtext (p); int prefer_cdtext = deadbeef->conf_get_int ("cdda.prefer_cdtext", DEFAULT_PREFER_CDTEXT); if ((!got_cdtext || !prefer_cdtext) && enable_cddb) { trace ("cdda: querying freedb...\n"); intptr_t tid = deadbeef->thread_start (cddb_thread, p); //will destroy cdio deadbeef->thread_detach (tid); } else cleanup_thread_params (p); } else { track_nr = atoi (shortname); res = insert_single_track (cdio, plt, after, NULL, track_nr, discid); if (res) { read_track_cdtext (cdio, track_nr, res); deadbeef->pl_item_unref (res); } cdio_destroy (cdio); } cddb_disc_destroy (disc); return res; }
bool AudioCDDemux::freedb_query( cddb_disc_t *&cddb_disc ) { #ifdef Q_OS_WIN bool hasHomeEnv = getenv( "HOME" ); if ( !hasHomeEnv ) putenv( "HOME=" + QDir::homePath().toLocal8Bit() ); #endif cddb_conn_t *cddb = cddb_new(); #ifdef Q_OS_WIN if ( !hasHomeEnv ) putenv( "HOME=" ); #endif cddb_disc = cddb_disc_new(); #ifdef Q_OS_WIN const QString cddbDir = QMPlay2Core.getSettingsDir() + "CDDB"; if ( QDir( cddbDir ).exists() || QDir( QMPlay2Core.getSettingsDir() ).mkdir( "CDDB" ) ) cddb_cache_set_dir( cddb, cddbDir.toLocal8Bit() ); #endif cddb_disc_set_length( cddb_disc, FRAMES_TO_SECONDS( cdio_get_track_lba( cdio, CDIO_CDROM_LEADOUT_TRACK ) ) ); for ( int trackno = 1 ; trackno <= numTracks ; ++trackno ) { cddb_track_t *pcddb_track = cddb_track_new(); cddb_track_set_frame_offset( pcddb_track, cdio_get_track_lba( cdio, trackno ) ); cddb_disc_add_track( cddb_disc, pcddb_track ); } bool useNetwork = false; cddb_disc_calc_discid( cddb_disc ); if ( cddb_disc_get_discid( cddb_disc ) == discID ) cddb_cache_only( cddb ); else { discID = cddb_disc_get_discid( cddb_disc ); cddb_set_timeout( cddb, 3 ); cddb_http_enable( cddb ); cddb_set_server_port( cddb, 80 ); Settings sets( "QMPlay2" ); if ( sets.getBool( "Proxy/Use" ) ) { cddb_http_proxy_enable( cddb ); cddb_set_http_proxy_server_name( cddb, sets.getString( "Proxy/Host" ).toLocal8Bit() ); cddb_set_http_proxy_server_port( cddb, sets.getUInt( "Proxy/Port" ) ); if ( sets.getBool( "Proxy/Login" ) ) { cddb_set_http_proxy_username( cddb, sets.getString( "Proxy/User" ).toLocal8Bit() ); cddb_set_http_proxy_password( cddb, QString( QByteArray::fromBase64( sets.getByteArray( "Proxy/Password" ) ) ).toLocal8Bit() ); } } useNetwork = true; } for ( int i = 0 ; i <= useNetwork ; ++i ) { if ( cddb_query( cddb, cddb_disc ) > 0 ) { do if ( cddb_disc_get_discid( cddb_disc ) == discID ) { cddb_read( cddb, cddb_disc ); cddb_destroy( cddb ); return true; } while ( cddb_query_next( cddb, cddb_disc ) ); } if ( useNetwork && !i ) cddb_set_server_name( cddb, "freedb.musicbrainz.org" ); } cddb_disc_destroy( cddb_disc ); cddb_destroy( cddb ); cddb_disc = NULL; return false; }
static cddb_disc_t *GetCDDBInfo( access_t *p_access, int i_titles, int *p_sectors ) { if( var_InheritInteger( p_access, "album-art" ) == ALBUM_ART_WHEN_ASKED ) return NULL; /* */ cddb_conn_t *p_cddb = cddb_new(); if( !p_cddb ) { msg_Warn( p_access, "unable to use CDDB" ); return NULL; } /* */ cddb_http_enable( p_cddb ); char *psz_tmp = var_InheritString( p_access, "cddb-server" ); if( psz_tmp ) { cddb_set_server_name( p_cddb, psz_tmp ); free( psz_tmp ); } cddb_set_server_port( p_cddb, var_InheritInteger( p_access, "cddb-port" ) ); cddb_set_email_address( p_cddb, "*****@*****.**" ); cddb_set_http_path_query( p_cddb, "/~cddb/cddb.cgi" ); cddb_set_http_path_submit( p_cddb, "/~cddb/submit.cgi" ); char *psz_cachedir; char *psz_temp = config_GetUserDir( VLC_CACHE_DIR ); if( asprintf( &psz_cachedir, "%s" DIR_SEP "cddb", psz_temp ) > 0 ) { cddb_cache_enable( p_cddb ); cddb_cache_set_dir( p_cddb, psz_cachedir ); free( psz_cachedir ); } free( psz_temp ); cddb_set_timeout( p_cddb, 10 ); /* */ cddb_disc_t *p_disc = cddb_disc_new(); if( !p_disc ) { msg_Err( p_access, "unable to create CDDB disc structure." ); goto error; } int64_t i_length = 0; for( int i = 0; i < i_titles; i++ ) { cddb_track_t *t = cddb_track_new(); cddb_track_set_frame_offset( t, p_sectors[i] ); cddb_disc_add_track( p_disc, t ); const int64_t i_size = ( p_sectors[i+1] - p_sectors[i] ) * (int64_t)CDDA_DATA_SIZE; i_length += INT64_C(1000000) * i_size / 44100 / 4 ; } cddb_disc_set_length( p_disc, (int)(i_length/1000000) ); if( !cddb_disc_calc_discid( p_disc ) ) { msg_Err( p_access, "CDDB disc ID calculation failed" ); goto error; } const int i_matches = cddb_query( p_cddb, p_disc ); if( i_matches < 0 ) { msg_Warn( p_access, "CDDB error: %s", cddb_error_str((cddb_error_t)errno) ); // sunqueen modify goto error; } else if( i_matches == 0 ) { msg_Dbg( p_access, "Couldn't find any matches in CDDB." ); goto error; } else if( i_matches > 1 ) msg_Warn( p_access, "found %d matches in CDDB. Using first one.", i_matches ); cddb_read( p_cddb, p_disc ); cddb_destroy( p_cddb); return p_disc; error: if( p_disc ) cddb_disc_destroy( p_disc ); cddb_destroy( p_cddb ); return NULL; }
// Copied from asunder v2.2 - GPL v2 void CddbInterface::readDisc() { if (disc) { return; } int fd=open(dev.toLocal8Bit(), O_RDONLY | O_NONBLOCK); if (fd < 0) { emit error(i18n("Failed to open CD device")); return; } QByteArray unknown=i18n("Unknown").toUtf8(); #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) struct ioc_toc_header th; struct ioc_read_toc_single_entry te; struct ioc_read_subchannel cdsc; struct cd_sub_channel_info data; bzero(&cdsc,sizeof(cdsc)); cdsc.data = &data; cdsc.data_len = sizeof(data); cdsc.data_format = CD_CURRENT_POSITION; cdsc.address_format = CD_MSF_FORMAT; if (ioctl(fd, CDIOCREADSUBCHANNEL, (char *)&cdsc) >= 0 && 0==ioctl(fd, CDIOREADTOCHEADER, &th)) { disc = cddb_disc_new(); if (disc) { te.address_format = CD_LBA_FORMAT; for (int i=th.starting_track; i<=th.ending_track; i++) { te.track = i; if (0==ioctl(fd, CDIOREADTOCENTRY, &te)) { cddb_track_t *track = cddb_track_new(); if (track) { cddb_track_set_frame_offset(track, te.entry.addr.lba + SECONDS_TO_FRAMES(2)); cddb_track_set_title(track, te.entry.control&0x04 ? dataTrack().toUtf8().constData() : i18n("Track %1", i).toUtf8().constData()); cddb_track_set_artist(track, unknown.constData()); cddb_disc_add_track(disc, track); } } } te.track = 0xAA; if (0==ioctl(fd, CDIOREADTOCENTRY, &te)) { cddb_disc_set_length(disc, (ntohl(te.entry.addr.lba)+SECONDS_TO_FRAMES(2))/SECONDS_TO_FRAMES(1)); } } } #elif defined(__linux__) struct cdrom_tochdr th; struct cdrom_tocentry te; int status = ioctl(fd, CDROM_DISC_STATUS, CDSL_CURRENT); if ((CDS_AUDIO==status || CDS_MIXED==status) && 0==ioctl(fd, CDROMREADTOCHDR, &th)) { disc = cddb_disc_new(); if (disc) { te.cdte_format = CDROM_LBA; for (int i=th.cdth_trk0; i<=th.cdth_trk1; i++) { te.cdte_track = i; if (0==ioctl(fd, CDROMREADTOCENTRY, &te)) { cddb_track_t *track = cddb_track_new(); if (track) { cddb_track_set_frame_offset(track, te.cdte_addr.lba + SECONDS_TO_FRAMES(2)); cddb_track_set_title(track, te.cdte_ctrl&CDROM_DATA_TRACK ? dataTrack().toUtf8().constData() : i18n("Track %1", i).toUtf8().constData()); cddb_track_set_artist(track, unknown.constData()); cddb_disc_add_track(disc, track); } } } te.cdte_track = CDROM_LEADOUT; if (0==ioctl(fd, CDROMREADTOCENTRY, &te)) { cddb_disc_set_length(disc, (te.cdte_addr.lba+SECONDS_TO_FRAMES(2))/SECONDS_TO_FRAMES(1)); } } } #endif cddb_disc_set_artist(disc, unknown.constData()); cddb_disc_set_title(disc, unknown.constData()); cddb_disc_set_genre(disc, unknown.constData()); cddb_disc_calc_discid(disc); close(fd); initial=toAlbum(disc); initial.isDefault=true; emit initialDetails(initial); }
/* 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; }
static void print_cddb_info(CdIo_t *p_cdio, track_t i_tracks, track_t i_first_track) { int i, matches; cddb_conn_t *conn = cddb_new(); cddb_disc_t *disc = NULL; if (!conn) { report(stderr, "%s: unable to initialize libcddb\n", program_name); goto cddb_destroy; } if (NULL == opts.cddb_email) cddb_set_email_address(conn, "me@home"); else cddb_set_email_address(conn, opts.cddb_email); if (NULL == opts.cddb_server) cddb_set_server_name(conn, "freedb.freedb.org"); else cddb_set_server_name(conn, opts.cddb_server); if (opts.cddb_timeout >= 0) cddb_set_timeout(conn, opts.cddb_timeout); cddb_set_server_port(conn, opts.cddb_port); if (opts.cddb_http) cddb_http_enable(conn); else cddb_http_disable(conn); if (NULL != opts.cddb_cachedir) cddb_cache_set_dir(conn, opts.cddb_cachedir); if (opts.cddb_disable_cache) cddb_cache_disable(conn); disc = cddb_disc_new(); if (!disc) { report(stderr, "%s: unable to create CDDB disc structure", program_name); goto cddb_destroy; } for(i = 0; i < i_tracks; i++) { cddb_track_t *t = cddb_track_new(); t->frame_offset = cdio_get_track_lba(p_cdio, i+i_first_track); cddb_disc_add_track(disc, t); } disc->length = cdio_get_track_lba(p_cdio, CDIO_CDROM_LEADOUT_TRACK) / CDIO_CD_FRAMES_PER_SEC; if (!cddb_disc_calc_discid(disc)) { report(stderr, "%s: libcddb calc discid failed.\n", program_name); goto cddb_destroy; } matches = cddb_query(conn, disc); if (-1 == matches) { sprintf(temp_msg, "%s: %s\n", program_name, cddb_error_str(cddb_errno(conn))); report(stdout, temp_msg); } else { sprintf(temp_msg, "%s: Found %d matches in CDDB\n", program_name, matches); report(stdout, temp_msg); for (i=1; i<=matches; i++) { cddb_read(conn, disc); cddb_disc_print(disc); cddb_query_next(conn, disc); } } cddb_disc_destroy(disc); cddb_destroy: cddb_destroy(conn); }
void do_query(cddb_conn_t *conn, cddb_disc_t *disc, int quiet) { int matches, i; /* This command also requires the disc ID to be initalized correctly. So we first calculate this disc ID before executing the query command. */ cddb_disc_calc_discid(disc); /* Try querying the database for information about the provided disc. This function will return the number of matches that were found. A return value of 0 means that no matches were found. The data of the first match (when found) will be filled in into the disc structure passed to it. The information will be retrieved from the server or read from the cache depending on the connection settings. */ matches = cddb_query(conn, disc); /* If an error occured then the return value will be -1 and the internal libcddb error number will be set. */ if (matches == -1) { /* Print an explanatory message on stderr. Other routines are available for retrieving the message without printing it or printing it on a stream other than stderr. */ if (!quiet) { cddb_error_print(cddb_errno(conn)); } /* Return to calling fucntion. */ return; } printf("Number of matches: %d\n", matches); /* A CDDB query command will not return all the disc information. It will return a subset that can afterwards be used to do a CDDB read. This enables you to first show a pop-up listing the found matches before doing further reads for the full data. The data that is returned for each match is: the disc CDDB category, the disc ID as known by the server, the disc title and the artist's name. */ /* Let's loop over the matches. */ i = 0; while (i < matches) { /* Increment the match counter. */ i++; /* Print out the information for the current match. */ printf("Match %d\n", i); /* Retrieve and print the category and disc ID. */ printf(" category: %s (%d)\t%08x\n", cddb_disc_get_category_str(disc), cddb_disc_get_category(disc), cddb_disc_get_discid(disc)); /* Retrieve and print the disc title and artist name. */ printf(" '%s' by %s\n", cddb_disc_get_title(disc), cddb_disc_get_artist(disc)); /* Get the next match, if there is one left. */ if (i < matches) { /* If there are multiple matches, then you can use the following function to retrieve the matches beyond the first. This function will overwrite any data that might be present in the disc structure passed to it. So if you still need that disc for anything else, then first create a new disc and use that to call this function. If there are no more matches left, false (i.e. 0) will be returned. */ if (!cddb_query_next(conn, disc)) { error_exit(cddb_errno(conn), "query index out of bounds"); } } } }