1 /*****************************************************************************
2 * info.c : CD digital audio input information routines
3 *****************************************************************************
4 * Copyright (C) 2004 VideoLAN
5 * $Id: info.c 8845 2004-09-29 09:00:41Z rocky $
7 * Authors: Rocky Bernstein <rocky@panix.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include "callback.h" /* FIXME - reorganize callback.h, cdda.h better */
28 #include "cdda.h" /* private structures. Also #includes vlc things */
29 #include <vlc_playlist.h> /* Has to come *after* cdda.h */
31 #include <cdio/cdio.h>
32 #include <cdio/cdtext.h>
33 #include <cdio/logging.h>
34 #include <cdio/cd_types.h>
43 #define free_and_dup(var, val) \
45 if (val) var=strdup(val);
48 /* Saves CDDB information about CD-DA via libcddb. */
50 GetCDDBInfo( access_t *p_access, cdda_data_t *p_cdda )
53 cddb_conn_t *conn = cddb_new();
54 const CdIo *p_cdio = p_cdda->p_cdio;
56 dbg_print( (INPUT_DBG_CALL), "" );
59 cddb_log_set_handler (uninit_log_handler);
64 msg_Warn( p_access, "Unable to initialize libcddb" );
68 cddb_set_email_address( conn,
69 config_GetPsz( p_access,
70 MODULE_STRING "-cddb-email") );
71 cddb_set_server_name( conn,
72 config_GetPsz( p_access,
73 MODULE_STRING "-cddb-server") );
74 cddb_set_server_port(conn,
75 config_GetInt( p_access,
76 MODULE_STRING "-cddb-port") );
78 /* Set the location of the local CDDB cache directory.
79 The default location of this directory is */
81 if (!config_GetInt( p_access, MODULE_STRING "-cddb-enable-cache" ))
82 cddb_cache_disable(conn);
84 cddb_cache_set_dir(conn,
85 config_GetPsz( p_access,
86 MODULE_STRING "-cddb-cachedir") );
88 cddb_set_timeout(conn,
89 config_GetInt( p_access, MODULE_STRING "-cddb-timeout") );
92 if (config_GetInt( p_access, MODULE_STRING "-cddb-httpd" ) )
94 cddb_http_enable(conn);
98 cddb_http_disable(conn);
101 p_cdda->cddb.disc = cddb_disc_new();
103 if (!p_cdda->cddb.disc)
105 msg_Err( p_access, "Unable to create CDDB disc structure." );
109 for(i = 0; i < p_cdda->i_tracks; i++)
111 track_t i_track = p_cdda->i_first_track + i;
112 cddb_track_t *t = cddb_track_new();
113 t->frame_offset = cdio_get_track_lba(p_cdio, i_track);
114 cddb_disc_add_track(p_cdda->cddb.disc, t);
117 p_cdda->cddb.disc->length =
118 cdio_get_track_lba(p_cdio, CDIO_CDROM_LEADOUT_TRACK)
119 / CDIO_CD_FRAMES_PER_SEC;
121 if (!cddb_disc_calc_discid(p_cdda->cddb.disc))
123 msg_Err( p_access, "CDDB disc ID calculation failed" );
127 i_matches = cddb_query(conn, p_cdda->cddb.disc);
132 msg_Warn( p_access, "Found %d matches in CDDB. Using first one.",
134 cddb_read(conn, p_cdda->cddb.disc);
136 if (p_cdda->i_debug & INPUT_DBG_CDDB)
137 cddb_disc_print(p_cdda->cddb.disc);
142 msg_Warn( p_access, "CDDB error: %s", cddb_error_str(errno));
150 #endif /*HAVE_LIBCDDB*/
152 #define add_meta_val(VLC_META, VAL) \
153 if ( p_cdda->p_meta && VAL) { \
154 vlc_meta_Add( p_cdda->p_meta, VLC_META, VAL ); \
155 dbg_print( INPUT_DBG_META, "field %s: %s\n", VLC_META, VAL ); \
158 #define add_cddb_meta(FIELD, VLC_META) \
159 add_meta_val(VLC_META, p_cdda->cddb.disc->FIELD);
161 #define add_cddb_meta_fmt(FIELD, FORMAT_SPEC, VLC_META) \
164 snprintf( psz_buf, sizeof(psz_buf)-1, FORMAT_SPEC, \
165 p_cdda->cddb.disc->FIELD ); \
166 psz_buf[sizeof(psz_buf)-1] = '\0'; \
167 add_meta_val(VLC_META, psz_buf); \
170 /* Adds a string-valued entry to the stream and media information if
171 the string is not null or the null string.
173 #define add_info_str(CATEGORY, TITLE, FIELD) \
174 if (FIELD && strlen(FIELD)) { \
175 input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY, \
176 _(TITLE), "%s", FIELD ); \
179 /* Adds a numeric-valued entry to the stream and media information
180 if the number is not zero. */
181 #define add_info_val(CATEGORY, TITLE, FMT, FIELD) \
183 input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY, \
184 _(TITLE), FMT, FIELD ); \
187 /* Adds a CDDB string-valued entry to the stream and media information
188 under category "Disc" if the string is not null or the null string.
190 #define add_cddb_disc_info_str(TITLE, FIELD) \
191 add_info_str("Disc", TITLE, p_cdda->cddb.disc->FIELD)
193 /* Adds a CDDB numeric-valued entry to the stream and media information
194 under category "Disc" if the string is not null or the null string.
196 #define add_cddb_disc_info_val(TITLE, FMT, FIELD) \
197 add_info_val("Disc", TITLE, FMT, p_cdda->cddb.disc->FIELD)
199 /* Adds a CD-Text string-valued entry to the stream and media information
200 under category "Disc" if the string is not null or the null string.
202 #define add_cdtext_info_str(CATEGORY, TITLE, INDEX, FIELD) \
203 add_info_str(CATEGORY, TITLE, p_cdda->p_cdtext[INDEX]->field[FIELD])
205 /* Adds a CD-Text string-valued entry to the stream and media information
206 under category "Disc" if the string is not null or the null string.
208 #define add_cdtext_disc_info_str(TITLE, FIELD) \
209 add_cdtext_info_str("Disc", TITLE, 0, FIELD)
213 Saves Meta Information about the CD-DA.
215 Saves information that CDDAMetaInfo uses. Should be called before
216 CDDAMetaInfo is called.
219 CDDAMetaInfoInit( access_t *p_access, int i_track )
221 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
223 if ( ! p_cdda ) return;
225 p_cdda->psz_mcn = cdio_get_mcn(p_cdda->p_cdio);
226 p_cdda->p_meta = vlc_meta_New();
229 if ( p_cdda->b_cddb_enabled )
231 GetCDDBInfo(p_access, p_cdda);
234 #endif /*HAVE_LIBCDDB*/
239 p_cdda->p_cdtext[0] = cdio_get_cdtext(p_cdda->p_cdio, 0);
241 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
243 p_cdda->p_cdtext[i_track] =
244 cdio_get_cdtext(p_cdda->p_cdio, i_track);
250 Gets and saves Meta Information about the CD-DA.
252 In the Control routine, we handle Meta Information requests and
253 basically copy what we've saved here.
255 Meta information is also used elsewhere such as in "stream and
256 media info" or in playlist info. The intialization of CD-Text or CDDB
260 CDDAMetaInfo( access_t *p_access, int i_track, /*const*/ char *psz_mrl )
262 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
263 char *psz_meta_title = psz_mrl;
264 char *psz_meta_artist = NULL;
266 if ( ! p_cdda ) return;
269 if ( p_cdda->b_cddb_enabled && p_cdda->cddb.disc )
273 psz_meta_title = p_cdda->cddb.disc->title;
274 psz_meta_artist = p_cdda->cddb.disc->artist;
276 input_Control( p_cdda->p_input, INPUT_SET_NAME,
277 p_cdda->cddb.disc->artist );
281 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
285 if( t->title != NULL )
287 add_meta_val( VLC_META_TITLE, t->title );
289 if( t->artist != NULL )
291 add_meta_val( VLC_META_ARTIST, t->artist );
295 add_cddb_meta(genre, VLC_META_GENRE);
296 add_cddb_meta_fmt(year, "%d", VLC_META_DATE );
299 #endif /*HAVE_LIBCDDB*/
303 track_t i = p_cdda->i_tracks;
304 const int i_first_track = p_cdda->i_first_track;
305 char psz_buffer[MSTRTIME_MAX_SIZE];
306 unsigned int i_track_frames =
307 cdio_get_track_lba(p_cdda->p_cdio, CDIO_CDROM_LEADOUT_TRACK);
309 mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
311 dbg_print( INPUT_DBG_META, "Duration %ld, tracks %d",
312 (long int) i_duration, p_cdda->i_tracks );
313 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
314 _("Disc"), _("Duration"), "%s",
315 secstotimestr( psz_buffer, i_duration ) );
317 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
318 _("Disc"), _("Tracks"), "%d", p_cdda->i_tracks );
321 if (p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
323 add_cddb_disc_info_str("Artist (CDDB)", artist);
324 add_cddb_disc_info_str("Genre (CDDB)", genre);
325 add_cddb_disc_info_str("Extended Data (CDDB)", ext_data);
326 add_cddb_disc_info_val("Year (CDDB)", "%d", year);
327 add_cddb_disc_info_val("Disc ID (CDDB)", "%x", discid);
328 add_cddb_disc_info_str("Title (CDDB)", title);
329 add_info_str("Disc", "Category (CDDB)",
330 CDDB_CATEGORY[p_cdda->cddb.disc->category]);
333 #endif /*HAVE_LIBCDDB*/
335 if (p_cdda->p_cdtext[0])
339 add_cdtext_disc_info_str("Arranger (CD-Text)", CDTEXT_ARRANGER);
340 add_cdtext_disc_info_str("Composer (CD-Text)", CDTEXT_COMPOSER);
341 add_cdtext_disc_info_str("Disc ID (CD-Text)", CDTEXT_DISCID);
342 add_cdtext_disc_info_str("Genre (CD-Text)", CDTEXT_GENRE);
343 add_cdtext_disc_info_str("Message (CD-Text)", CDTEXT_MESSAGE);
344 add_cdtext_disc_info_str("Performer (CD-Text)", CDTEXT_PERFORMER);
345 add_cdtext_disc_info_str("Songwriter (CD-Text)", CDTEXT_SONGWRITER);
346 add_cdtext_disc_info_str("Title (CD-Text)", CDTEXT_TITLE);
348 psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
349 if (psz_field && strlen(psz_field)) {
350 psz_meta_title = psz_field;
352 psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
353 if (psz_field && strlen(psz_field)) {
354 psz_meta_artist = psz_field;
359 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
361 char psz_track[TITLE_MAX];
362 const track_t i_track = i_first_track + i;
363 unsigned int i_track_frames =
364 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
365 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
367 mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
368 snprintf(psz_track, TITLE_MAX, "%s %02d", _("Track"), i_track);
370 input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
372 secstotimestr( psz_buffer, i_duration ) );
374 if (p_cdda->p_cdtext[i_track])
376 add_cdtext_info_str( psz_track, "Arranger (CD-Text)",
377 i_track, CDTEXT_ARRANGER);
378 add_cdtext_info_str( psz_track, "Composer (CD-Text)",
379 i_track, CDTEXT_COMPOSER);
380 add_cdtext_info_str( psz_track, "Disc ID (CD-Text)",
381 i_track, CDTEXT_DISCID);
382 add_cdtext_info_str( psz_track, "Genre (CD-Text)",
383 i_track, CDTEXT_GENRE);
384 add_cdtext_info_str( psz_track, "Message (CD-Text)",
385 i_track, CDTEXT_MESSAGE);
386 add_cdtext_info_str( psz_track, "Performer (CD-Text)",
387 i_track, CDTEXT_PERFORMER);
388 add_cdtext_info_str( psz_track, "Songwriter (CD-Text)",
389 i_track, CDTEXT_SONGWRITER);
390 add_cdtext_info_str( psz_track, "Title (CD-Text)",
391 i_track, CDTEXT_TITLE);
395 if (p_cdda->b_cddb_enabled)
397 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i);
400 add_info_str(psz_track, "Artist (CDDB)", t->artist);
401 add_info_str(psz_track, "Title (CDDB)", t->title);
402 add_info_str(psz_track, "Extended Data (CDDB)",
406 #endif /*HAVE_LIBCDDB*/
409 /* Above we should have set psz_meta_title and psz_meta_artist
410 to CDDB or CD-Text values or the default value depending on
411 availablity and user preferences. So now add it to VLC's meta.
413 add_meta_val( VLC_META_TITLE, psz_meta_title );
415 add_meta_val( VLC_META_ARTIST, psz_meta_artist );
419 #define add_format_str_info(val) \
421 const char *str = val; \
426 strncat(tp, str, TEMP_STR_LEN-(tp-temp_str)); \
429 saw_control_prefix = false; \
433 #define add_format_num_info(val, fmt) \
437 sprintf(num_str, fmt, val); \
438 len=strlen(num_str); \
440 strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); \
443 saw_control_prefix = false; \
448 cdda_data_t *p_cdda, char *psz_cdtext)
450 /* We either don't have CD-Text info, or we do but we prefer to get CDDB
451 which means CDDB has been enabled and we were able to retrieve the info.*/
453 return !psz_cdtext ||
454 (!p_cdda->b_cdtext_prefer && p_cdda->b_cddb_enabled && p_cdda->cddb.disc);
462 Take a format string and expand escape sequences, that is sequences that
463 begin with %, with information from the current CD.
464 The expanded string is returned. Here is a list of escape sequences:
466 %a : The album artist **
467 %A : The album information **
472 %m : The CD-DA Media Catalog Number (MCN)
473 %n : The number of tracks on the CD
474 %p : The artist/performer/composer in the track **
475 %T : The track number **
476 %s : Number of seconds in this track
477 %t : The track name or MRL if no name **
478 %Y : The year 19xx or 20xx **
482 CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
483 const char format_str[], const char *psz_mrl, track_t i_track)
485 #define TEMP_STR_SIZE 256
486 #define TEMP_STR_LEN (TEMP_STR_SIZE-1)
487 static char temp_str[TEMP_STR_SIZE];
489 char * tp = temp_str;
490 vlc_bool_t saw_control_prefix = false;
491 size_t format_len = strlen(format_str);
493 memset(temp_str, 0, TEMP_STR_SIZE);
495 for (i=0; i<format_len; i++)
499 if (!saw_control_prefix && format_str[i] != '%')
501 *tp++ = format_str[i];
502 saw_control_prefix = false;
506 switch(format_str[i])
509 if (saw_control_prefix)
513 saw_control_prefix = !saw_control_prefix;
517 if (p_cdda->p_cdtext[0]
518 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
519 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
520 if (want_cddb_info(p_cdda, psz))
521 psz = p_cdda->cddb.disc->artist;
524 if (p_cdda->p_cdtext[0]
525 && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
526 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
527 if (want_cddb_info(p_cdda, psz))
528 psz = p_cdda->cddb.disc->title;
531 if (!p_cdda->b_cddb_enabled) goto not_special;
532 if (p_cdda->cddb.disc)
534 CDDB_CATEGORY[p_cdda->cddb.disc->category]);
537 if (p_cdda->p_cdtext[0]
538 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
539 psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
540 if (want_cddb_info(p_cdda, psz))
541 psz = p_cdda->cddb.disc->genre;
544 if (p_cdda->p_cdtext[0]
545 && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
546 psz = p_cdda->p_cdtext[0]->field[CDTEXT_DISCID];
547 if (want_cddb_info(p_cdda, psz)) {
548 add_format_num_info(p_cdda->cddb.disc->discid, "%x");
550 add_format_str_info(psz);
553 if (!p_cdda->b_cddb_enabled) goto not_special;
554 if (p_cdda->cddb.disc)
555 add_format_num_info(p_cdda->cddb.disc->year, "%5d");
558 if (p_cdda && p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
560 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
562 if (t != NULL && t->title != NULL) {
563 add_format_str_info(t->title);
565 add_format_str_info(psz_mrl);
568 if (p_cdda->p_cdtext[i_track]
569 && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE]) {
570 add_format_str_info(p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE]);
573 add_format_str_info(psz_mrl);
577 if (p_cdda->p_cdtext[i_track]
578 && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
579 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
580 if (want_cddb_info(p_cdda, psz))
582 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
584 if (t != NULL && t->artist != NULL)
589 if (p_cdda->p_cdtext[i_track]
590 && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
591 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
592 if (want_cddb_info(p_cdda, psz))
594 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
596 if (t != NULL && t->ext_data != NULL)
602 if (p_cdda->b_cddb_enabled)
604 char psz_buffer[MSTRTIME_MAX_SIZE];
605 unsigned int i_track_frames =
606 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
607 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
609 i_track_frames / CDIO_CD_FRAMES_PER_SEC;
610 add_format_str_info( secstotimestr( psz_buffer,
612 } else goto not_special;
616 if (p_cdda->p_cdtext[0]
617 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
618 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
621 if (p_cdda->p_cdtext[0]
622 && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
623 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
626 if (p_cdda->p_cdtext[0]
627 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
628 psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
631 if (p_cdda->p_cdtext[0]
632 && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
633 add_format_str_info(p_cdda->p_cdtext[0]->field[CDTEXT_DISCID]);
636 if (p_cdda->p_cdtext[i_track]
637 && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
638 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
641 if (p_cdda->p_cdtext[i_track]
642 && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE])
643 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE];
648 if (p_cdda->p_cdtext[i_track]
649 && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
650 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
653 #endif /*HAVE_LIBCDDB*/
656 add_format_str_info(psz_mrl);
660 add_format_str_info(p_cdda->psz_mcn);
664 add_format_num_info(p_cdda->i_tracks, "%d");
668 add_format_num_info(i_track, "%02d");
672 add_format_str_info(psz);
679 *tp++ = format_str[i];
680 saw_control_prefix = false;
683 return strdup(temp_str);
686 /* Adds a string-valued entry to the playlist information under "Track"
687 if the string is not null or the null string.
689 #define add_playlist_track_info_str(TITLE, FIELD) \
690 if (FIELD && strlen(FIELD)) \
692 playlist_ItemAddInfo( p_item, _("Track"), _(TITLE), \
697 CDDACreatePlaylistItem( const access_t *p_access, cdda_data_t *p_cdda,
698 playlist_t *p_playlist, playlist_item_t *p_item,
699 track_t i_track, char *psz_mrl, int psz_mrl_max )
701 unsigned int i_track_frames =
702 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
703 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
704 mtime_t i_mduration =
705 i_track_frames * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) ;
707 char *config_varname = MODULE_STRING "-title-format";
709 playlist_item_t *p_child = NULL;
717 if (p_cdda->b_cddb_enabled)
719 config_varname = MODULE_STRING "-cddb-title-format";
721 #endif /*HAVE_LIBCDDB*/
724 snprintf(psz_mrl, psz_mrl_max, "%s%s@T%u",
725 CDDA_MRL_PREFIX, p_cdda->psz_source, i_track);
727 psz_title = CDDAFormatStr( p_access, p_cdda,
728 config_GetPsz( p_access, config_varname ),
731 dbg_print( INPUT_DBG_META, "mrl: %s, title: %s, duration, %ld",
732 psz_mrl, psz_title, (long int) i_mduration / 1000000 );
734 p_child = playlist_ItemNew( p_playlist, psz_mrl, psz_title );
735 p_child->input.b_fixed_name = VLC_TRUE;
736 p_child->input.i_duration = i_mduration;
738 if( !p_child ) return NULL;
740 playlist_NodeAddItem( p_playlist, p_child,
741 p_item->pp_parents[0]->i_view,
742 p_item, PLAYLIST_APPEND, PLAYLIST_END );
743 playlist_CopyParents( p_item, p_child );
748 int CDDAAddMetaToItem( access_t *p_access, cdda_data_t *p_cdda,
749 playlist_item_t *p_item, int i_track,
750 vlc_bool_t b_single )
752 vlc_mutex_lock( &p_item->input.lock );
754 add_playlist_track_info_str("Source", p_cdda->psz_source);
755 playlist_ItemAddInfo( p_item, _("Track"), _("Track Number"),
758 if (p_cdda->p_cdtext[0])
760 const cdtext_t *p = p_cdda->p_cdtext[0];
761 add_playlist_track_info_str("Disc Arranger (CD-Text)",
762 p->field[CDTEXT_ARRANGER]);
763 add_playlist_track_info_str("Disc Composer (CD-Text)",
764 p->field[CDTEXT_COMPOSER]);
765 add_playlist_track_info_str("Disc ID (CD-Text)",
766 p->field[CDTEXT_DISCID]);
767 add_playlist_track_info_str("Disc Genre (CD-Text)",
768 p->field[CDTEXT_GENRE]);
769 add_playlist_track_info_str("Disc Message (CD-Text)",
770 p->field[CDTEXT_MESSAGE]);
771 add_playlist_track_info_str("Disc Performer (CD-Text)",
772 p->field[CDTEXT_PERFORMER]);
773 add_playlist_track_info_str("Disc Songwriter (CD-Text)",
774 p->field[CDTEXT_SONGWRITER]);
775 add_playlist_track_info_str("Disc Title (CD-Text)",
776 p->field[CDTEXT_TITLE]);
779 if (p_cdda->p_cdtext[i_track])
781 const cdtext_t *p = p_cdda->p_cdtext[i_track];
782 add_playlist_track_info_str("Arranger (CD-Text)",
783 p->field[CDTEXT_ARRANGER]);
784 add_playlist_track_info_str("Composer (CD-Text)",
785 p->field[CDTEXT_COMPOSER]);
786 add_playlist_track_info_str("Genre (CD-Text)",
787 p->field[CDTEXT_GENRE]);
788 add_playlist_track_info_str("Message (CD-Text)",
789 p->field[CDTEXT_MESSAGE]);
790 add_playlist_track_info_str("Performer (CD-Text)",
791 p->field[CDTEXT_PERFORMER]);
792 add_playlist_track_info_str("Songwriter (CD-Text)",
793 p->field[CDTEXT_SONGWRITER]);
794 add_playlist_track_info_str("Title (CD-Text)",
795 p->field[CDTEXT_TITLE]);
799 if (p_cdda->b_cddb_enabled)
801 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
802 i_track-p_cdda->i_first_track);
804 add_playlist_track_info_str("Disc Album (CDDB)",
805 p_cdda->cddb.disc->title);
806 add_playlist_track_info_str("Disc Artist(s) (CDDB)",
807 p_cdda->cddb.disc->artist);
808 add_playlist_track_info_str("Disc Category (CDDB)",
809 CDDB_CATEGORY[p_cdda->cddb.disc->category]);
810 add_playlist_track_info_str("Disc Genre (CDDB)",
811 p_cdda->cddb.disc->genre);
813 if ( p_cdda->cddb.disc->discid )
815 playlist_ItemAddInfo( p_item, _("Track"), _("Disc ID (CDDB)"),
816 "%x", p_cdda->cddb.disc->discid );
818 if (p_cdda->cddb.disc->year != 0)
820 playlist_ItemAddInfo( p_item, _("Track"), _("Year (CDDB)"),
821 "%5d", p_cdda->cddb.disc->year );
827 add_playlist_track_info_str("Track Artist (CDDB)",
830 add_playlist_track_info_str("Track Title (CDDB)",
834 #endif /*HAVE_LIBCDDB*/
836 vlc_mutex_unlock( &p_item->input.lock );
842 CDDAFixupPlaylist( access_t *p_access, cdda_data_t *p_cdda,
843 vlc_bool_t b_single_track )
846 playlist_t * p_playlist;
847 char * psz_mrl = NULL;
848 unsigned int psz_mrl_max = strlen(CDDA_MRL_PREFIX)
849 + strlen(p_cdda->psz_source) +
850 + strlen("@T") + strlen("100") + 1;
851 const track_t i_first_track = p_cdda->i_first_track;
852 playlist_item_t *p_item;
853 vlc_bool_t b_play = VLC_FALSE;
856 p_cdda->b_cddb_enabled =
857 config_GetInt( p_access, MODULE_STRING "-cddb-enabled" );
858 if( b_single_track && !p_cdda->b_cddb_enabled )
865 psz_mrl = malloc( psz_mrl_max );
867 if( psz_mrl == NULL )
869 msg_Warn( p_access, "out of memory" );
873 p_playlist = (playlist_t *) vlc_object_find( p_access, VLC_OBJECT_PLAYLIST,
877 msg_Warn( p_access, "can't find playlist" );
884 snprintf(psz_mrl, psz_mrl_max, "%s%s@T%u", CDDA_MRL_PREFIX,
885 p_cdda->psz_source, p_cdda->i_track);
886 CDDAMetaInfoInit( p_access, p_cdda->i_track );
887 CDDAMetaInfo( p_access, p_cdda->i_track, psz_mrl );
891 snprintf(psz_mrl, psz_mrl_max, "%s%s", CDDA_MRL_PREFIX,
893 CDDAMetaInfoInit( p_access, -1 );
894 CDDAMetaInfo( p_access, -1, psz_mrl );
897 p_item = playlist_ItemGetByInput( p_playlist,
898 ((input_thread_t *)p_access->p_parent)->input.p_item );
900 if( p_item == p_playlist->status.p_item && !b_single_track )
911 /*May fill out more information when the playlist user interface becomes
914 track_t i_track = p_cdda->i_track;
915 unsigned int i_track_frames =
916 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
917 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
919 input_title_t *t = p_cdda->p_title[0] = //i_track-i_first_track] =
920 vlc_input_title_New();
922 asprintf( &t->psz_name, _("Track %i"), i_track );
923 t->i_size = p_access->info.i_size =
924 i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
926 t->i_length = I64C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
929 CDDAAddMetaToItem( p_access, p_cdda, p_item, i_track, VLC_FALSE );
931 p_cdda->i_titles = 1;
932 p_access->info.i_size =
933 i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
934 p_access->info.i_update |= INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE;
935 p_item->input.i_duration = i_track_frames
936 * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC);
940 playlist_ItemToNode( p_playlist, p_item );
941 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
943 playlist_item_t *p_child;
944 const track_t i_track = i_first_track + i;
945 unsigned int i_track_frames =
946 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
947 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
949 input_title_t *t = p_cdda->p_title[i] = vlc_input_title_New();
951 asprintf( &t->psz_name, _("Track %i"), i_track );
952 t->i_size = i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
954 t->i_length = I64C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
956 p_child = CDDACreatePlaylistItem( p_access, p_cdda, p_playlist,
960 CDDAAddMetaToItem( p_access, p_cdda, p_child, i_track, VLC_TRUE );
962 p_cdda->i_titles = p_cdda->i_tracks; /* should be +1 */
963 p_access->info.i_size =
964 cdio_get_track_lba(p_cdda->p_cdio, CDIO_CDROM_LEADOUT_TRACK)
965 * (int64_t) CDIO_CD_FRAMESIZE_RAW;
966 p_access->info.i_update |= INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE;
967 p_item->input.i_duration =
968 p_access->info.i_size * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) ;
973 playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
974 p_playlist->status.i_view,
975 p_playlist->status.p_item, NULL );
978 vlc_object_release( p_playlist );