Esempio n. 1
0
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;
}
Esempio n. 2
0
cddb_disc_t*
resolve_disc (CdIo_t *cdio)
{
    track_t first_track = cdio_get_first_track_num (cdio);
    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_conn_t *conn = NULL;

    conn = cddb_new();

    deadbeef->conf_lock ();
    cddb_set_server_name (conn, deadbeef->conf_get_str_fast ("cdda.freedb.host", DEFAULT_SERVER));
    cddb_set_server_port (conn, deadbeef->conf_get_int ("cdda.freedb.port", DEFAULT_PORT));

    if (!deadbeef->conf_get_int ("cdda.protocol", DEFAULT_PROTOCOL))
    {
        cddb_http_enable (conn);
        if (deadbeef->conf_get_int ("network.proxy", 0))
        {
            cddb_set_server_port(conn, deadbeef->conf_get_int ("network.proxy.port", 8080));
            cddb_set_server_name(conn, deadbeef->conf_get_str_fast ("network.proxy.address", ""));
        }
    }
    deadbeef->conf_unlock ();

    int matches = cddb_query (conn, disc);
    if (matches == -1)
    {
        cddb_disc_destroy (disc);
        cddb_destroy (conn);
        return NULL;
    }
    cddb_read (conn, disc);
    cddb_destroy (conn);
    return disc;
}
Esempio n. 3
0
File: cddb.c Progetto: bricka/giles
/**
 * Given a CDIO device, calculates the necessary information about the device
 * and contacts a CDDB server to get disk information.
 *
 * @param p_cdio a CDIO device
 * @param disk the disk structure to store the information in
 *
 * @return an error status about whether information was obtained
 */
enum giles_cddb_err get_cddb_info_for_device(const CdIo_t *p_cdio, cddb_disc_t *disc) {
    lsn_t last_lsn;
    msf_t last_msf;
    unsigned disc_len_in_s, i, matches;
    track_t num_tracks;
    cddb_track_t *track;
    cddb_conn_t *conn;

    num_tracks = cdio_get_num_tracks(p_cdio);

    DPRINTF ("Disc contains %d tracks\n", num_tracks);

    for (i = 1; i <= num_tracks; i++) {
        track = cddb_track_new();
        
        cddb_track_set_frame_offset(track, cdio_get_track_lba(p_cdio, i));
        DPRINTF ("Offset for track %d is %d\n", i, cdio_get_track_lba(p_cdio, i));
        cddb_disc_add_track(disc, track);
    }

    last_lsn = cdio_get_disc_last_lsn(p_cdio);
    cdio_lsn_to_msf(last_lsn, &last_msf);
    disc_len_in_s = cdio_audio_get_msf_seconds(&last_msf);

    cddb_disc_set_length(disc, disc_len_in_s);

    conn = cddb_new();

    if (conn == NULL) {
        cddb_error_print(cddb_errno(conn));
        return giles_cddb_err_no_conn;
    }

    matches = cddb_query(conn, disc);

    if (matches == -1) {
        return giles_cddb_err_no_conn;
    } else if (matches == 0) {
        return giles_cddb_err_no_match;
    }

    cddb_read(conn, disc);

    cddb_destroy(conn);

    return giles_cddb_err_none;
}
Esempio n. 4
0
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;
}
Esempio n. 5
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;
}
Esempio n. 6
0
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;
}
Esempio n. 8
0
// 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);
}
Esempio n. 9
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;
}