Beispiel #1
0
static bool print_cdtext(stream_t *s, int track)
{
    cdda_priv* p = (cdda_priv*)s->priv;
#ifdef OLD_API
    cdtext_t *text = cdio_get_cdtext(p->cd->p_cdio, track);
#else
    cdtext_t *text = cdio_get_cdtext(p->cd->p_cdio);
#endif
    int header = 0;
    if (text) {
        for (int i = 0; i < sizeof(cdtext_name) / sizeof(cdtext_name[0]); i++) {
            const char *name = cdtext_name[i];
#ifdef OLD_API
            const char *value = cdtext_get_const(i, text);
#else
            const char *value = cdtext_get_const(text, i, track);
#endif
            if (name && value) {
                if (!header)
                    MP_INFO(s, "CD-Text (%s):\n", track ? "track" : "CD");
                header = 1;
                MP_INFO(s, "  %s: '%s'\n", name, value);
            }
        }
        return true;
    }
    return false;
}
Beispiel #2
0
void AudioCDDemux::readCDText( track_t trackNo )
{
#if LIBCDIO_VERSION_NUM >= 84
	if ( cdtext_t *cdtext = cdio_get_cdtext( cdio ) )
	{
		if ( trackNo == 0 )
		{
			cdTitle  = cdtext_get_const( cdtext, CDTEXT_FIELD_TITLE, 0 );
			cdArtist = cdtext_get_const( cdtext, CDTEXT_FIELD_PERFORMER, 0 );
		}
		else
		{
			Title  = cdtext_get_const( cdtext, CDTEXT_FIELD_TITLE, trackNo );
			Artist = cdtext_get_const( cdtext, CDTEXT_FIELD_PERFORMER, trackNo );
			Genre  = cdtext_get_const( cdtext, CDTEXT_FIELD_GENRE, trackNo );
		}
	}
#else
	if ( cdtext_t *cdtext = cdio_get_cdtext( cdio, trackNo ) )
	{
		if ( trackNo == 0 )
		{
			cdTitle  = cdtext_get_const( CDTEXT_TITLE, cdtext );
			cdArtist = cdtext_get_const( CDTEXT_PERFORMER, cdtext );
		}
		else
		{
			Title  = cdtext_get_const( CDTEXT_TITLE, cdtext );
			Artist = cdtext_get_const( CDTEXT_PERFORMER, cdtext );
			Genre  = cdtext_get_const( CDTEXT_GENRE, cdtext );
		}
	}
#endif
}
Beispiel #3
0
static void 
print_cdtext_track_info(cdtext_t *p_cdtext, track_t i_track, const char *psz_msg) {

  if (NULL != p_cdtext) {
    cdtext_field_t i;
    
    printf("%s\n", psz_msg);
    
    for (i=0; i < MAX_CDTEXT_FIELDS; i++) {
      if (cdtext_get_const(p_cdtext, i, i_track)) {
        printf("\t%s: %s\n", cdtext_field2str(i), cdtext_get_const(p_cdtext, i, i_track));
      }
    }
  }
}
Beispiel #4
0
/*!
  Returns a copy of the return value of cdtext_get_const or NULL.

  Must be freed using cdio_free() when done.
  @see cdtext_get_const
*/
char *
cdtext_get(const cdtext_t *p_cdtext, cdtext_field_t field, track_t track)
{
  const char *ret = cdtext_get_const(p_cdtext, field, track);
  if (NULL == ret)
    return NULL;
  else
    return strdup(ret);
}
void
gst_cdio_add_cdtext_field (GstObject * src, cdtext_t * cdtext, track_t track,
    cdtext_field_t field, const gchar * gst_tag, GstTagList ** p_tags)
{
  const gchar *vars[] = { "GST_CDTEXT_TAG_ENCODING", "GST_TAG_ENCODING", NULL };
  const gchar *txt;
  gchar *txt_utf8;

#if LIBCDIO_VERSION_NUM > 83
  txt = cdtext_get_const (cdtext, field, track);
#else
  txt = cdtext_get_const (field, cdtext);
#endif
  if (txt == NULL || *txt == '\0') {
    GST_DEBUG_OBJECT (src, "empty CD-TEXT field %u (%s)", field, gst_tag);
    return;
  }

  /* The character encoding is not specified, and there is no provision
   * for indicating in the CD-Text data which encoding is in use.. */
  txt_utf8 = gst_tag_freeform_string_to_utf8 (txt, -1, vars);

  if (txt_utf8 == NULL) {
    GST_WARNING_OBJECT (src, "CD-TEXT %s could not be converted to UTF-8, "
        "try setting the GST_CDTEXT_TAG_ENCODING or GST_TAG_ENCODING "
        "environment variable", gst_tag);
    return;
  }

  /* FIXME: beautify strings (they might be all uppercase for example)? */

  if (*p_tags == NULL)
    *p_tags = gst_tag_list_new_empty ();

  gst_tag_list_add (*p_tags, GST_TAG_MERGE_REPLACE, gst_tag, txt_utf8, NULL);

  GST_DEBUG_OBJECT (src, "CD-TEXT: %s = %s", gst_tag, txt_utf8);
  g_free (txt_utf8);
}
Beispiel #6
0
std::string CdTextImpl::upc_ean() const
{
   const char* value = cdtext_get_const(_cdtext, CDTEXT_FIELD_UPC_EAN, _track);
   return value != NULL ? value : "";
}
Beispiel #7
0
std::string CdTextImpl::title() const
{
   const char* value = cdtext_get_const(_cdtext, CDTEXT_FIELD_TITLE, _track);
   return value != NULL ? value : "";
}
Beispiel #8
0
std::string CdTextImpl::song_writer() const
{
   const char* value = cdtext_get_const(_cdtext, CDTEXT_FIELD_SONGWRITER, _track);
   return value != NULL ? value : "";
}
Beispiel #9
0
std::string CdTextImpl::isrc() const
{
   const char* value = cdtext_get_const(_cdtext, CDTEXT_FIELD_ISRC, _track);
   return value != NULL ? value : "";
}
Beispiel #10
0
std::string CdTextImpl::message() const
{
   const char* value = cdtext_get_const(_cdtext, CDTEXT_FIELD_MESSAGE, _track);
   return value != NULL ? value : "";
}
Beispiel #11
0
std::string CdTextImpl::disc_id() const
{
   const char* value = cdtext_get_const(_cdtext, CDTEXT_FIELD_DISCID, _track);
   return value != NULL ? value : "";
}
Beispiel #12
0
std::string CdTextImpl::composer() const
{
   const char* value = cdtext_get_const(_cdtext, CDTEXT_FIELD_COMPOSER, _track);
   return value != NULL ? value : "";
}
Beispiel #13
0
std::string CdTextImpl::arranger() const
{
   const char* value = cdtext_get_const(_cdtext, CDTEXT_FIELD_ARRANGER, _track);
   return value != NULL ? value : "";
}
Beispiel #14
0
//virtual
Metadata *CdDecoder::getMetadata()
{
    QString artist, album, compilation_artist, title, genre;
    int year = 0;
    unsigned long length = 0;
    track_t tracknum = 0;

    if (-1 == m_settracknum)
        tracknum = getFilename().toUInt();
    else
    {
        tracknum = m_settracknum;
        setFilename(QString("%1" CDEXT).arg(tracknum));
    }

    QMutexLocker lock(&getCdioMutex());

    StCdioDevice cdio(m_devicename);
    if (!cdio)
        return NULL;

    const track_t lastTrack = cdio_get_last_track_num(cdio);
    if (CDIO_INVALID_TRACK == lastTrack)
        return NULL;

    if (TRACK_FORMAT_AUDIO != cdio_get_track_format(cdio, tracknum))
        return NULL;

    // Assume disc changed if max LSN different
    bool isDiscChanged = false;
    static lsn_t s_totalSectors;
    lsn_t totalSectors = cdio_get_track_lsn(cdio, CDIO_CDROM_LEADOUT_TRACK);
    if (s_totalSectors != totalSectors)
    {
        s_totalSectors = totalSectors;
        isDiscChanged = true;
    }

    // NB cdio_get_track_last_lsn is unreliable for the last audio track
    // of discs with data tracks beyond
    lsn_t end = cdio_get_track_last_lsn(cdio, tracknum);
    if (isDiscChanged)
    {
        const track_t audioTracks = getNumCDAudioTracks();
        s_lastAudioLsn = cdio_get_track_last_lsn(cdio, audioTracks);

        if (audioTracks < lastTrack)
        {
            cdrom_drive_t *dev = cdio_cddap_identify_cdio(cdio, 0, NULL);
            if (NULL != dev)
            {
                if (DRIVER_OP_SUCCESS == cdio_cddap_open(dev))
                {
                    // NB this can be S L O W  but is reliable
                    lsn_t end2 = cdio_cddap_track_lastsector(dev,
                        getNumCDAudioTracks());
                    if (CDIO_INVALID_LSN != end2)
                        s_lastAudioLsn = end2;
                }
                cdio_cddap_close_no_free_cdio(dev);
            }
        }
    }

    if (s_lastAudioLsn && s_lastAudioLsn < end)
        end = s_lastAudioLsn;

    const lsn_t start = cdio_get_track_lsn(cdio, tracknum);
    if (CDIO_INVALID_LSN != start && CDIO_INVALID_LSN != end)
    {
        length = ((end - start + 1) * 1000 + CDIO_CD_FRAMES_PER_SEC/2) /
            CDIO_CD_FRAMES_PER_SEC;
    }

    bool isCompilation = false;

#define CDTEXT 0 // Disabled - cd-text access on discs without it is S L O W
#if CDTEXT
    static int s_iCdtext;
    if (isDiscChanged)
        s_iCdtext = -1;

    if (s_iCdtext)
    {
        // cdio_get_cdtext can't take >5 seconds on some CD's without cdtext
        if (s_iCdtext < 0)
            LOG(VB_MEDIA, LOG_INFO,
                QString("Getting cdtext for track %1...").arg(tracknum));
        cdtext_t * cdtext = cdio_get_cdtext(m_cdio, tracknum);
        if (NULL != cdtext)
        {
            genre = cdtext_get_const(CDTEXT_GENRE, cdtext);
            artist = cdtext_get_const(CDTEXT_PERFORMER, cdtext);
            title = cdtext_get_const(CDTEXT_TITLE, cdtext);
            const char* isrc = cdtext_get_const(CDTEXT_ISRC, cdtext);
            /* ISRC codes are 12 characters long, in the form CCXXXYYNNNNN
             * CC = country code
             * XXX = registrant e.g. BMG
             * CC = year withou century
             * NNNNN = unique ID
             */
            if (isrc && strlen(isrc) >= 7)
            {
                year = (isrc[5] - '0') * 10 + (isrc[6] - '0');
                year += (year <= 30) ? 2000 : 1900;
            }

            cdtext_destroy(cdtext);

            if (!title.isNull())
            {
                if (s_iCdtext < 0)
                    LOG(VB_MEDIA, LOG_INFO, "Found cdtext track title");
                s_iCdtext = 1;

                // Get disc info
                cdtext = cdio_get_cdtext(cdio, 0);
                if (NULL != cdtext)
                {
                    compilation_artist = cdtext_get_const(
                        CDTEXT_PERFORMER, cdtext);
                    if (!compilation_artist.isEmpty() &&
                            artist != compilation_artist)
                        isCompilation = true;

                    album = cdtext_get_const(CDTEXT_TITLE, cdtext);

                    if (genre.isNull())
                        genre = cdtext_get_const(CDTEXT_GENRE, cdtext);

                    cdtext_destroy(cdtext);
                }
            }
            else
            {
                if (s_iCdtext < 0)
                    LOG(VB_MEDIA, LOG_INFO, "No cdtext title for track");
                s_iCdtext = 0;
            }
        }
        else
        {
            if (s_iCdtext < 0)
                LOG(VB_MEDIA, LOG_INFO, "No cdtext");
            s_iCdtext = 0;
        }
    }

    if (title.isEmpty() || artist.isEmpty() || album.isEmpty())
#endif // CDTEXT
    {
        // CDDB lookup
        Cddb::Toc toc;
        Cddb::Matches r;
        if (Cddb::Query(r, GetToc(cdio, toc)))
        {
            Cddb::Matches::match_t::const_iterator select = r.matches.begin();

            if (r.matches.size() > 1)
            {
                // TODO prompt user to select one
                // In the meantime, select the first non-generic genre
                for (Cddb::Matches::match_t::const_iterator it = select;
                    it != r.matches.end(); ++it)
                {
                    QString g = it->genre.toLower();
                    if (g != "misc" && g != "data")
                    {
                        select = it;
                        break;
                    }
                }
            }

            Cddb::Album info;
            if (Cddb::Read(info, select->genre, select->discID))
            {
                isCompilation = info.isCompilation;
                if (info.genre.toLower() != "misc")
                    genre = info.genre;
                album = info.title;
                compilation_artist = info.artist;
                year = info.year;
                if (info.tracks.size() >= tracknum)
                {
                    const Cddb::Track& track = info.tracks[tracknum - 1];
                    title = track.title;
                    artist = track.artist;
                }

                // Create a temporary local alias for future lookups
                if (r.discID != info.discID)
                    Cddb::Alias(info, r.discID);
            }
        }
    }

    if (compilation_artist.toLower().left(7) == "various")
        compilation_artist = QObject::tr("Various Artists");

    if (artist.isEmpty())
    {
        artist = compilation_artist;
        compilation_artist.clear();
    }

    if (title.isEmpty())
        title = QObject::tr("Track %1").arg(tracknum);

    Metadata *m = new Metadata(getFilename(), artist, compilation_artist,
        album, title, genre, year, tracknum, length);
    if (m)
        m->setCompilation(isCompilation);

    return m;
}
Beispiel #15
0
static void
read_track_cdtext (CdIo_t *cdio, int track_nr, DB_playItem_t *item)
{
#if CDIO_API_VERSION >= 6
    cdtext_t *cdtext = cdio_get_cdtext (cdio);
#else
    cdtext_t *cdtext = cdio_get_cdtext (cdio, 0);
#endif
    if (!cdtext) {
        trace ("No cdtext\n");
        return;
    }
    const char *artist = NULL;
    const char *album = NULL;
    int field_type;
    for (field_type = 0; field_type < MAX_CDTEXT_FIELDS; field_type++) {
#if CDIO_API_VERSION >= 6
        const char *text = cdtext_get_const (cdtext, field_type, track_nr);
#else
        const char *text = cdtext_get_const (field_type, cdtext);
#endif
        if (text) {
            switch (field_type) {
#if CDIO_API_VERSION >= 6
                case CDTEXT_FIELD_TITLE: album = text; break;
                case CDTEXT_FIELD_PERFORMER: artist = text; break;
#else
                case CDTEXT_TITLE: album = text; break;
                case CDTEXT_PERFORMER: artist = text; break;
#endif
            }
        }
    }

    trace ("artist: %s; album: %s\n", artist, album);
    replace_meta(item, "artist", artist);
    replace_meta(item, "album", album);

#if CDIO_API_VERSION >= 6
    cdtext = cdio_get_cdtext (cdio);
#else
    cdtext = cdio_get_cdtext (cdio, track_nr);
#endif
    if (!cdtext) {
        return;
    }

    for (field_type = 0; field_type < MAX_CDTEXT_FIELDS; field_type++) {
#if CDIO_API_VERSION >= 6
        const char *text = cdtext_get_const (cdtext, field_type, track_nr);
#else
        const char *text = cdtext_get_const (field_type, cdtext);
#endif
        if (!text) {
            continue;
        }

        const char *field = NULL;
        switch (field_type) {
#if CDIO_API_VERSION >= 6
            case CDTEXT_FIELD_TITLE:      field = "title";    break;
            case CDTEXT_FIELD_PERFORMER:  field = "artist";   break;
            case CDTEXT_FIELD_COMPOSER:   field = "composer"; break;
            case CDTEXT_FIELD_GENRE:      field = "genre";    break;
            case CDTEXT_FIELD_SONGWRITER: field = "songwriter";   break;
            case CDTEXT_FIELD_MESSAGE:    field = "comment";  break;
#else
            case CDTEXT_TITLE:      field = "title";    break;
            case CDTEXT_PERFORMER:  field = "artist";   break;
            case CDTEXT_COMPOSER:   field = "composer"; break;
            case CDTEXT_GENRE:      field = "genre";    break;
            case CDTEXT_SONGWRITER: field = "songwriter";   break;
            case CDTEXT_MESSAGE:    field = "comment";  break;
#endif
            default: field = NULL;
        }
        if (field) {
            trace("%s: %s\n", field, text);
            replace_meta(item, field, text);
        }
    }
}
Beispiel #16
0
static void
read_track_cdtext (CdIo_t *cdio, int track_nr, DB_playItem_t *item)
{
    cdtext_t *cdtext = cdio_get_cdtext (cdio, 0);
    if (!cdtext)
    {
        trace ("No cdtext\n");
        return;
    }
    const char *artist = NULL;
    const char *album = NULL;
    int field_type;
    for (field_type = 0; field_type < MAX_CDTEXT_FIELDS; field_type++)
    {
        const char *text = cdtext_get_const (field_type, cdtext);
        const char *field = NULL;
        if (text)
        {
            switch (field_type)
            {
                case CDTEXT_TITLE: album = text; break;
                case CDTEXT_PERFORMER: artist = text; break;
            }
        }
    }

    trace ("artist: %s; album: %s\n", artist, album);
    if (artist) {
        deadbeef->pl_replace_meta (item, "artist", artist);
    }
    if (album) {
        deadbeef->pl_replace_meta (item, "album", album);
    }

    cdtext = cdio_get_cdtext (cdio, track_nr);
    if (!cdtext)
        return;

    for (field_type = 0; field_type < MAX_CDTEXT_FIELDS; field_type++)
    {
        const char *text = cdtext_get_const (field_type, cdtext);
        const char *field = NULL;
        if (!text)
            continue;
        switch (field_type)
        {
            case CDTEXT_TITLE:      field = "title";    break;
            case CDTEXT_PERFORMER:  field = "artist";   break;
            case CDTEXT_COMPOSER:   field = "composer"; break;
            case CDTEXT_GENRE:      field = "genre";    break;
            case CDTEXT_SONGWRITER: field = "songwriter";   break;
            case CDTEXT_MESSAGE:    field = "comment";  break;
            default: field = NULL;
        }
        if (field && text)
        {
            trace ("%s: %s\n", field, text);
            deadbeef->pl_replace_meta (item, field, text);
        }
    }
}
Beispiel #17
0
std::string CdTextImpl::performer() const
{
   const char* value = cdtext_get_const(_cdtext, CDTEXT_FIELD_PERFORMER, _track);
   return value != NULL ? value : "";
}