1 /*****************************************************************************
2 * info.c : CD digital audio input information routines
3 *****************************************************************************
4 * Copyright (C) 2004, 2005 the VideoLAN team
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, 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>
41 static char *CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
42 const char format_str[], const char *psz_mrl,
45 static char *CDDAFormatMRL( const access_t *p_access, track_t i_track );
49 #define free_and_dup(var, val) \
51 if (val) var=strdup(val);
54 /* Saves CDDB information about CD-DA via libcddb. */
56 GetCDDBInfo( access_t *p_access, cdda_data_t *p_cdda )
59 cddb_conn_t *conn = cddb_new();
60 const CdIo_t *p_cdio = p_cdda->p_cdio;
62 dbg_print( (INPUT_DBG_CALL), "" );
65 cddb_log_set_handler (uninit_log_handler);
70 msg_Warn( p_access, "Unable to initialize libcddb" );
74 cddb_set_email_address( conn,
75 config_GetPsz( p_access,
76 MODULE_STRING "-cddb-email") );
77 cddb_set_server_name( conn,
78 config_GetPsz( p_access,
79 MODULE_STRING "-cddb-server") );
80 cddb_set_server_port(conn,
81 config_GetInt( p_access,
82 MODULE_STRING "-cddb-port") );
84 /* Set the location of the local CDDB cache directory.
85 The default location of this directory is */
87 if (!config_GetInt( p_access, MODULE_STRING "-cddb-enable-cache" ))
88 cddb_cache_disable(conn);
90 cddb_cache_set_dir(conn,
91 config_GetPsz( p_access,
92 MODULE_STRING "-cddb-cachedir") );
94 cddb_set_timeout(conn,
95 config_GetInt( p_access, MODULE_STRING "-cddb-timeout") );
98 if (config_GetInt( p_access, MODULE_STRING "-cddb-httpd" ) )
100 cddb_http_enable(conn);
104 cddb_http_disable(conn);
107 p_cdda->cddb.disc = cddb_disc_new();
109 if (!p_cdda->cddb.disc)
111 msg_Err( p_access, "Unable to create CDDB disc structure." );
115 for(i = 0; i < p_cdda->i_tracks; i++)
117 track_t i_track = p_cdda->i_first_track + i;
118 cddb_track_t *t = cddb_track_new();
119 cddb_track_set_frame_offset(t,
120 cdio_get_track_lba(p_cdio, i_track));
121 cddb_disc_add_track(p_cdda->cddb.disc, t);
124 cddb_disc_set_length(p_cdda->cddb.disc,
125 cdio_get_track_lba(p_cdio, CDIO_CDROM_LEADOUT_TRACK)
126 / CDIO_CD_FRAMES_PER_SEC);
128 if (!cddb_disc_calc_discid(p_cdda->cddb.disc))
130 msg_Err( p_access, "CDDB disc ID calculation failed" );
134 i_matches = cddb_query(conn, p_cdda->cddb.disc);
139 msg_Warn( p_access, "Found %d matches in CDDB. Using first one.",
141 cddb_read(conn, p_cdda->cddb.disc);
143 if (p_cdda->i_debug & INPUT_DBG_CDDB)
144 cddb_disc_print(p_cdda->cddb.disc);
149 msg_Warn( p_access, "CDDB error: %s", cddb_error_str(errno));
157 #endif /*HAVE_LIBCDDB*/
159 #define add_meta_val(VLC_META, VAL) \
160 if ( p_cdda->p_meta && VAL) { \
161 vlc_meta_Add( p_cdda->p_meta, VLC_META, VAL ); \
162 dbg_print( INPUT_DBG_META, "field %s: %s\n", VLC_META, VAL ); \
165 #define add_cddb_meta(FIELD, VLC_META) \
166 add_meta_val(VLC_META, cddb_disc_get_##FIELD(p_cdda->cddb.disc));
168 #define add_cddb_meta_fmt(FIELD, FORMAT_SPEC, VLC_META) \
171 snprintf( psz_buf, sizeof(psz_buf)-1, FORMAT_SPEC, \
172 cddb_disc_get_##FIELD(p_cdda->cddb.disc)); \
173 psz_buf[sizeof(psz_buf)-1] = '\0'; \
174 add_meta_val(VLC_META, psz_buf); \
177 /* Adds a string-valued entry to the stream and media information if
178 the string is not null or the null string.
180 #define add_info_str(CATEGORY, TITLE, FIELD) \
181 if (FIELD && strlen(FIELD)) { \
182 input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY, \
183 _(TITLE), "%s", FIELD ); \
186 /* Adds a numeric-valued entry to the stream and media information
187 if the number is not zero. */
188 #define add_info_val(CATEGORY, TITLE, FMT, FIELD) \
190 input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY, \
191 _(TITLE), FMT, FIELD ); \
194 /* Adds a CDDB string-valued entry to the stream and media information
195 under category "Disc" if the string is not null or the null string.
197 #define add_cddb_disc_info_str(TITLE, FIELD) \
198 add_info_str("Disc", TITLE, cddb_disc_get_##FIELD(p_cdda->cddb.disc))
200 /* Adds a CDDB numeric-valued entry to the stream and media information
201 under category "Disc" if the string is not null or the null string.
203 #define add_cddb_disc_info_val(TITLE, FMT, FIELD) \
204 add_info_val("Disc", TITLE, FMT, cddb_disc_get_##FIELD(p_cdda->cddb.disc))
206 /* Adds a CD-Text string-valued entry to the stream and media information
207 under category "Disc" if the string is not null or the null string.
209 #define add_cdtext_info_str(CATEGORY, TITLE, INDEX, FIELD) \
210 add_info_str(CATEGORY, TITLE, p_cdda->p_cdtext[INDEX]->field[FIELD])
212 /* Adds a CD-Text string-valued entry to the stream and media information
213 under category "Disc" if the string is not null or the null string.
215 #define add_cdtext_disc_info_str(TITLE, FIELD) \
216 add_cdtext_info_str("Disc", TITLE, 0, FIELD)
220 Saves Meta Information about the CD-DA.
222 Meta information used in "stream and media info" or in playlist
223 info. The intialization of CD-Text or CDDB is done here though.
224 Therefore, this should be called before CDDAMetaInfo is called.
228 CDDAMetaInfoInit( access_t *p_access )
230 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
232 if ( ! p_cdda ) return;
234 dbg_print( (INPUT_DBG_CALL), "p_cdda->i_tracks %d",
237 p_cdda->psz_mcn = cdio_get_mcn(p_cdda->p_cdio);
238 p_cdda->p_meta = vlc_meta_New();
241 if ( p_cdda->b_cddb_enabled )
243 GetCDDBInfo(p_access, p_cdda);
246 #endif /*HAVE_LIBCDDB*/
252 for( i_track = 0 ; i_track < p_cdda->i_tracks ; i_track++ )
254 p_cdda->p_cdtext[i_track] =
255 cdio_get_cdtext(p_cdda->p_cdio, i_track);
261 In the Control routine, we handle Meta Information requests and
262 basically copy what was saved in CDDAMetaInfoInit.
264 If i_track is CDIO_INVALID_TRACK we are probably asking about the entire
268 CDDAMetaInfo( access_t *p_access, track_t i_track )
270 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
271 char *psz_meta_title = CDDAFormatMRL( p_access, i_track );
272 char *psz_meta_artist = NULL;
274 if ( ! p_cdda ) return;
276 dbg_print( (INPUT_DBG_CALL), "i_track %d", i_track );
280 /* Set up for Meta and name for CDDB access. */
281 if ( p_cdda->b_cddb_enabled && p_cdda->cddb.disc )
283 if( CDIO_INVALID_TRACK == i_track )
286 psz_meta_title = (char *)cddb_disc_get_title(p_cdda->cddb.disc);
287 psz_meta_artist = (char *)cddb_disc_get_artist(p_cdda->cddb.disc);
288 if ( cddb_disc_get_genre(p_cdda->cddb.disc) &&
289 strlen(cddb_disc_get_genre(p_cdda->cddb.disc)) )
290 add_cddb_meta(genre, VLC_META_GENRE);
291 if ( 0 != cddb_disc_get_year(p_cdda->cddb.disc))
292 add_cddb_meta_fmt(year, "%d", VLC_META_DATE );
296 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i_track-1);
299 if( cddb_track_get_title(t) != NULL && ! p_cdda->b_nav_mode )
301 add_meta_val( VLC_META_TITLE, cddb_track_get_title(t) );
303 if( cddb_track_get_artist(t) != NULL )
305 add_meta_val( VLC_META_ARTIST, cddb_track_get_artist(t) );
311 #endif /*HAVE_LIBCDDB*/
315 track_t i = p_cdda->i_tracks;
316 const int i_first_track = p_cdda->i_first_track;
317 char psz_buffer[MSTRTIME_MAX_SIZE];
318 unsigned int i_track_frames =
319 cdio_get_track_lba(p_cdda->p_cdio, CDIO_CDROM_LEADOUT_TRACK);
321 mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
323 dbg_print( INPUT_DBG_META, "Duration %ld, tracks %d",
324 (long int) i_duration, p_cdda->i_tracks );
325 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
326 _("Disc"), _("Duration"), "%s",
327 secstotimestr( psz_buffer, i_duration ) );
329 if (p_cdda->psz_mcn) {
330 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
331 _("Disc"), _("Media Catalog Number (MCN)"), "%s",
334 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
335 _("Disc"), _("Tracks"), "%d", p_cdda->i_tracks );
340 if (p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
342 add_cddb_disc_info_str("Artist (CDDB)", artist);
343 if ( CDDB_CAT_INVALID != cddb_disc_get_category(p_cdda->cddb.disc) )
344 add_info_str("Disc", "Category (CDDB)",
345 CDDB_CATEGORY[cddb_disc_get_category(p_cdda->cddb.disc)]);
346 add_cddb_disc_info_val("Disc ID (CDDB)", "%x", discid);
347 add_cddb_disc_info_str("Extended Data (CDDB)", ext_data);
348 add_cddb_disc_info_str("Genre (CDDB)", genre);
349 add_cddb_disc_info_str("Title (CDDB)", title);
350 if ( 0 != cddb_disc_get_year(p_cdda->cddb.disc) )
351 add_cddb_disc_info_val("Year (CDDB)", "%d", year);
354 #endif /*HAVE_LIBCDDB*/
356 if (p_cdda->p_cdtext[0])
360 add_cdtext_disc_info_str("Arranger (CD-Text)", CDTEXT_ARRANGER);
361 add_cdtext_disc_info_str("Composer (CD-Text)", CDTEXT_COMPOSER);
362 add_cdtext_disc_info_str("Disc ID (CD-Text)", CDTEXT_DISCID);
363 add_cdtext_disc_info_str("Genre (CD-Text)", CDTEXT_GENRE);
364 add_cdtext_disc_info_str("Message (CD-Text)", CDTEXT_MESSAGE);
365 add_cdtext_disc_info_str("Performer (CD-Text)", CDTEXT_PERFORMER);
366 add_cdtext_disc_info_str("Songwriter (CD-Text)", CDTEXT_SONGWRITER);
367 add_cdtext_disc_info_str("Title (CD-Text)", CDTEXT_TITLE);
369 psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
370 if (psz_field && strlen(psz_field)) {
371 psz_meta_title = psz_field;
373 psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
374 if (psz_field && strlen(psz_field)) {
375 psz_meta_artist = psz_field;
380 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
382 char psz_track[TITLE_MAX];
383 const track_t i_track = i_first_track + i;
384 unsigned int i_track_frames =
385 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
386 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
388 mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
389 char *psz_mrl = CDDAFormatMRL( p_access, i_track );
391 snprintf(psz_track, TITLE_MAX, "%s %02d", _("Track"), i_track);
393 input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
395 secstotimestr( psz_buffer, i_duration ) );
397 input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
398 _("MRL"), "%s", psz_mrl );
401 if (p_cdda->p_cdtext[i_track])
403 add_cdtext_info_str( psz_track, "Arranger (CD-Text)",
404 i_track, CDTEXT_ARRANGER);
405 add_cdtext_info_str( psz_track, "Composer (CD-Text)",
406 i_track, CDTEXT_COMPOSER);
407 add_cdtext_info_str( psz_track, "Disc ID (CD-Text)",
408 i_track, CDTEXT_DISCID);
409 add_cdtext_info_str( psz_track, "Genre (CD-Text)",
410 i_track, CDTEXT_GENRE);
411 add_cdtext_info_str( psz_track, "Message (CD-Text)",
412 i_track, CDTEXT_MESSAGE);
413 add_cdtext_info_str( psz_track, "Performer (CD-Text)",
414 i_track, CDTEXT_PERFORMER);
415 add_cdtext_info_str( psz_track, "Songwriter (CD-Text)",
416 i_track, CDTEXT_SONGWRITER);
417 add_cdtext_info_str( psz_track, "Title (CD-Text)",
418 i_track, CDTEXT_TITLE);
422 if (p_cdda->b_cddb_enabled)
424 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i);
427 add_info_str(psz_track, "Artist (CDDB)",
428 cddb_track_get_artist(t));
429 add_info_str(psz_track, "Title (CDDB)",
430 cddb_track_get_title(t));
431 add_info_str(psz_track, "Extended Data (CDDB)",
432 cddb_track_get_ext_data(t));
435 #endif /*HAVE_LIBCDDB*/
438 /* Above we should have set psz_meta_title and psz_meta_artist
439 to CDDB or CD-Text values or the default value depending on
440 availablity and user preferences.
442 So now add the title and artist to VLC's meta, and the name
443 as shown in the status bar and playlist entry.
445 For playlist mode, the meta title is what's seen at the
446 bottom and in the playlist. For nav-mode playing, it is
447 done by input_control. I don't understand why they do
448 different things. In either case, we may have customized to
449 put in the track name.
451 if ( CDIO_INVALID_TRACK != i_track )
453 char *psz_name = CDDAFormatTitle( p_access, i_track ) ;
454 if ( !p_cdda->b_nav_mode ) {
455 add_meta_val( VLC_META_TITLE, psz_name );
458 input_Control( p_cdda->p_input, INPUT_SET_NAME, psz_name );
462 add_meta_val( VLC_META_ARTIST, psz_meta_artist );
468 #define add_format_str_info(val) \
470 const char *str = val; \
475 strncat(tp, str, TEMP_STR_LEN-(tp-temp_str)); \
478 saw_control_prefix = false; \
482 #define add_format_num_info(val, fmt) \
486 sprintf(num_str, fmt, val); \
487 len=strlen(num_str); \
489 strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); \
492 saw_control_prefix = false; \
497 cdda_data_t *p_cdda, char *psz_cdtext)
499 /* We either don't have CD-Text info, or we do but we prefer to get CDDB
500 which means CDDB has been enabled and we were able to retrieve the info.*/
502 return !psz_cdtext ||
503 (!p_cdda->b_cdtext_prefer && p_cdda->b_cddb_enabled && p_cdda->cddb.disc);
511 Take a format string and expand escape sequences, that is sequences that
512 begin with %, with information from the current CD.
513 The expanded string is returned. Here is a list of escape sequences:
515 %a : The album artist **
516 %A : The album information **
518 %e : The extended track data
522 %m : The CD-DA Media Catalog Number (MCN)
523 %n : The number of tracks on the CD
524 %p : The artist/performer/composer in the track **
525 %T : The track number **
526 %s : Number of seconds in this track, or seconds in CD if invalid track
527 %S : Number of seconds on the CD
528 %t : The track name or MRL if no name
529 %Y : The year 19xx or 20xx **
533 CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
534 const char format_str[], const char *psz_mrl, track_t i_track)
536 #define TEMP_STR_SIZE 256
537 #define TEMP_STR_LEN (TEMP_STR_SIZE-1)
538 static char temp_str[TEMP_STR_SIZE];
540 char * tp = temp_str;
541 vlc_bool_t saw_control_prefix = false;
542 size_t format_len = strlen(format_str);
544 memset(temp_str, 0, TEMP_STR_SIZE);
546 for (i=0; i<format_len; i++)
550 if (!saw_control_prefix && format_str[i] != '%')
552 *tp++ = format_str[i];
553 saw_control_prefix = false;
557 switch(format_str[i])
560 if (saw_control_prefix)
564 saw_control_prefix = !saw_control_prefix;
568 if (p_cdda->p_cdtext[0]
569 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
570 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
571 if (want_cddb_info(p_cdda, psz))
572 psz = (char *)cddb_disc_get_artist(p_cdda->cddb.disc);
575 if (p_cdda->p_cdtext[0]
576 && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
577 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
578 if (want_cddb_info(p_cdda, psz))
579 psz = (char *)cddb_disc_get_title(p_cdda->cddb.disc);
582 if (!p_cdda->b_cddb_enabled) goto not_special;
583 if (p_cdda->cddb.disc)
584 add_format_str_info(CDDB_CATEGORY[cddb_disc_get_category(p_cdda->cddb.disc)]);
587 if (p_cdda->p_cdtext[0]
588 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
589 psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
590 if (want_cddb_info(p_cdda, psz))
591 psz = (char *)cddb_disc_get_genre(p_cdda->cddb.disc);
594 if (p_cdda->p_cdtext[0]
595 && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
596 psz = p_cdda->p_cdtext[0]->field[CDTEXT_DISCID];
597 if (want_cddb_info(p_cdda, psz)) {
598 add_format_num_info(cddb_disc_get_discid(p_cdda->cddb.disc), "%x");
600 add_format_str_info(psz);
603 if (!p_cdda->b_cddb_enabled) goto not_special;
604 if (p_cdda->cddb.disc)
605 add_format_num_info(cddb_disc_get_year(p_cdda->cddb.disc),
609 if ( CDIO_INVALID_TRACK == i_track ) break;
610 if (p_cdda && p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
612 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
614 if (t != NULL && cddb_track_get_title(t) != NULL) {
615 add_format_str_info(cddb_track_get_title(t));
617 add_format_str_info(psz_mrl);
620 if (p_cdda->p_cdtext[i_track]
621 && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE]) {
622 add_format_str_info(p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE]);
625 add_format_str_info(psz_mrl);
629 if ( CDIO_INVALID_TRACK == i_track ) break;
630 if (p_cdda->p_cdtext[i_track]
631 && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
632 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
633 if (want_cddb_info(p_cdda, psz))
635 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
637 if (t != NULL && cddb_track_get_artist(t) != NULL)
638 psz = (char *)cddb_track_get_artist(t);
642 if ( CDIO_INVALID_TRACK == i_track ) break;
643 if (p_cdda->p_cdtext[i_track]
644 && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
645 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
646 if (want_cddb_info(p_cdda, psz))
648 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
650 if (t != NULL && cddb_track_get_ext_data(t) != NULL)
651 psz = (char *)cddb_track_get_ext_data(t);
657 if (p_cdda->p_cdtext[0]
658 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
659 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
662 if (p_cdda->p_cdtext[0]
663 && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
664 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
667 if (p_cdda->p_cdtext[0]
668 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
669 psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
672 if (p_cdda->p_cdtext[0]
673 && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
674 add_format_str_info(p_cdda->p_cdtext[0]->field[CDTEXT_DISCID]);
677 if ( CDIO_INVALID_TRACK == i_track ) break;
678 if (p_cdda->p_cdtext[i_track]
679 && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
680 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
683 if ( CDIO_INVALID_TRACK == i_track ) break;
684 if (p_cdda->p_cdtext[i_track]
685 && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE])
686 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE];
691 if ( CDIO_INVALID_TRACK == i_track ) break;
692 if (p_cdda->p_cdtext[i_track]
693 && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
694 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
697 #endif /*HAVE_LIBCDDB*/
700 if ( CDIO_INVALID_TRACK != i_track )
702 char psz_buffer[MSTRTIME_MAX_SIZE];
703 unsigned int i_track_frames =
704 cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
706 i_track_frames / CDIO_CD_FRAMES_PER_SEC;
707 add_format_str_info( secstotimestr( psz_buffer,
712 /* Fall through to disc duration if CDIO_INVALID_TRACK */
715 char psz_buffer[MSTRTIME_MAX_SIZE];
716 unsigned int i_track_frames =
717 cdio_get_track_lba(p_cdda->p_cdio,
718 CDIO_CDROM_LEADOUT_TRACK);
720 i_track_frames / CDIO_CD_FRAMES_PER_SEC;
721 add_format_str_info( secstotimestr( psz_buffer,
727 add_format_str_info(psz_mrl);
731 add_format_str_info(p_cdda->psz_mcn);
735 add_format_num_info(p_cdda->i_tracks, "%d");
739 add_format_num_info(i_track, "%02d");
743 add_format_str_info(psz);
750 *tp++ = format_str[i];
751 saw_control_prefix = false;
754 return strdup(temp_str);
757 /* Return a MRL for the given track. The caller must free the
760 CDDAFormatMRL( const access_t *p_access, track_t i_track )
762 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
763 const unsigned int psz_mrl_max = strlen(CDDA_MRL_PREFIX)
764 + strlen(p_cdda->psz_source) +
765 + strlen("@T") + strlen("100") + 1;
766 char *psz_mrl = calloc( 1, psz_mrl_max );
768 if (CDIO_INVALID_TRACK == i_track)
769 snprintf(psz_mrl, psz_mrl_max, "%s%s",
770 CDDA_MRL_PREFIX, p_cdda->psz_source);
772 snprintf(psz_mrl, psz_mrl_max, "%s%s@T%u",
773 CDDA_MRL_PREFIX, p_cdda->psz_source, i_track);
778 /* Return a title string as specified by the titel format string for the
779 given track. The caller must free the allocated string. */
781 CDDAFormatTitle( const access_t *p_access, track_t i_track )
784 char *config_varname = MODULE_STRING "-title-format";
785 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
786 char *psz_mrl = CDDAFormatMRL( p_access, i_track );
792 if (p_cdda->b_cddb_enabled)
794 config_varname = MODULE_STRING "-cddb-title-format";
796 #endif /*HAVE_LIBCDDB*/
798 CDDAFormatStr( p_access, p_cdda,
799 config_GetPsz( p_access, config_varname ),
807 /* Adds a string-valued entry to the playlist information under "Track"
808 if the string is not null or the null string.
810 #define add_playlist_track_info_str(TITLE, FIELD) \
811 if (FIELD && strlen(FIELD)) \
813 vlc_input_item_AddInfo( &p_item->input, _("Track"), _(TITLE), \
817 static playlist_item_t *
818 CDDACreatePlaylistItem( const access_t *p_access, cdda_data_t *p_cdda,
819 playlist_t *p_playlist, playlist_item_t *p_item,
822 unsigned int i_track_frames =
823 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
824 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
825 mtime_t i_mduration =
826 i_track_frames * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) ;
827 char *psz_title = NULL;
828 char *psz_mrl = NULL;
830 playlist_item_t *p_child = NULL;
832 if( !p_item ) return NULL;
834 psz_title = CDDAFormatTitle( p_access, i_track ) ;
835 psz_mrl = CDDAFormatMRL( p_access, i_track ) ;
837 dbg_print( INPUT_DBG_META, "mrl: %s, title: %s, duration, %ld",
838 psz_mrl, psz_title, (long int) i_mduration / 1000000 );
840 p_child = playlist_ItemNew( p_playlist, psz_mrl, psz_title );
841 p_child->input.i_duration = i_mduration;
845 if( !p_child ) return NULL;
847 playlist_NodeAddItem( p_playlist, p_child,
848 p_item->pp_parents[0]->i_view,
849 p_item, PLAYLIST_APPEND, PLAYLIST_END );
850 playlist_CopyParents( p_item, p_child );
855 int CDDAAddMetaToItem( access_t *p_access, cdda_data_t *p_cdda,
856 playlist_item_t *p_item, int i_track,
857 vlc_bool_t b_single )
859 add_playlist_track_info_str("Source", p_cdda->psz_source);
860 vlc_input_item_AddInfo( &p_item->input, _("Track"), _("Track Number"),
863 if (p_cdda->p_cdtext[i_track])
865 const cdtext_t *p = p_cdda->p_cdtext[i_track];
866 add_playlist_track_info_str("Arranger (CD-Text)",
867 p->field[CDTEXT_ARRANGER]);
868 add_playlist_track_info_str("Composer (CD-Text)",
869 p->field[CDTEXT_COMPOSER]);
870 add_playlist_track_info_str("Genre (CD-Text)",
871 p->field[CDTEXT_GENRE]);
872 add_playlist_track_info_str("Message (CD-Text)",
873 p->field[CDTEXT_MESSAGE]);
874 add_playlist_track_info_str("Performer (CD-Text)",
875 p->field[CDTEXT_PERFORMER]);
876 add_playlist_track_info_str("Songwriter (CD-Text)",
877 p->field[CDTEXT_SONGWRITER]);
878 add_playlist_track_info_str("Title (CD-Text)",
879 p->field[CDTEXT_TITLE]);
883 if (p_cdda->b_cddb_enabled)
885 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
886 i_track-p_cdda->i_first_track);
890 if (cddb_track_get_artist(t))
891 add_playlist_track_info_str("Artist (CDDB)",
892 cddb_track_get_artist(t));
893 if (cddb_track_get_title(t))
894 add_playlist_track_info_str("Title (CDDB)",
895 cddb_track_get_title(t));
896 if (cddb_track_get_ext_data(t))
897 add_playlist_track_info_str("Extended information (CDDB)",
898 cddb_track_get_ext_data(t));
901 #endif /*HAVE_LIBCDDB*/
910 CDDAFixupPlaylist( access_t *p_access, cdda_data_t *p_cdda,
911 vlc_bool_t b_single_track )
914 playlist_t * p_playlist = NULL;
915 const track_t i_first_track = p_cdda->i_first_track;
916 playlist_item_t *p_item = NULL;
917 vlc_bool_t b_play = VLC_FALSE;
921 p_cdda->b_cddb_enabled =
922 config_GetInt( p_access, MODULE_STRING "-cddb-enabled" );
923 if( b_single_track && !p_cdda->b_cddb_enabled )
930 if (! p_cdda->b_nav_mode ) {
931 p_playlist = (playlist_t *) vlc_object_find( p_access,
936 msg_Warn( p_access, "can't find playlist" );
941 if( b_single_track || p_cdda->b_nav_mode ) {
942 i_track = p_cdda->i_track;
946 i_track = CDIO_INVALID_TRACK;
948 CDDAMetaInfoInit( p_access );
949 CDDAMetaInfo( p_access, p_cdda->i_track );
953 p_item = playlist_LockItemGetByInput( p_playlist,
954 ((input_thread_t *)p_access->p_parent)->input.p_item );
956 if( p_item == p_playlist->status.p_item && !b_single_track )
966 if( b_single_track && !p_cdda->b_nav_mode )
968 /*May fill out more information when the playlist user interface becomes
971 track_t i_track = p_cdda->i_track;
972 unsigned int i_track_frames =
973 cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
975 input_title_t *t = p_cdda->p_title[0] = //i_track-i_first_track] =
976 vlc_input_title_New();
978 asprintf( &t->psz_name, _("Track %i"), i_track );
979 t->i_size = i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
981 t->i_length = I64C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
986 CDDAAddMetaToItem( p_access, p_cdda, p_item, i_track, VLC_FALSE );
987 p_item->input.i_duration = i_track_frames
988 * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC);
989 p_item->input.psz_uri = CDDAFormatMRL(p_access, i_track);
992 p_cdda->i_titles = 1;
993 p_access->info.i_update = INPUT_UPDATE_TITLE;
999 if ( !p_cdda->b_nav_mode )
1000 playlist_ItemToNode( p_playlist, p_item );
1002 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
1004 playlist_item_t *p_child;
1005 const track_t i_track = i_first_track + i;
1006 unsigned int i_track_frames =
1007 cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
1009 t = p_cdda->p_title[i] = vlc_input_title_New();
1011 asprintf( &t->psz_name, _("Track %i"), i_track );
1012 t->i_size = i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
1014 t->i_length = I64C(1000000) * t->i_size
1015 / CDDA_FREQUENCY_SAMPLE / 4;
1017 if ( ! p_cdda->b_nav_mode ) {
1018 p_child = CDDACreatePlaylistItem( p_access, p_cdda, p_playlist,
1021 CDDAAddMetaToItem( p_access, p_cdda, p_child, i_track,
1026 p_cdda->i_titles = p_cdda->i_tracks;
1027 p_access->info.i_update |= INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE;
1029 p_item->input.i_duration =
1030 p_access->info.i_size * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) ;
1031 p_item->input.psz_uri = CDDAFormatMRL(p_access,
1039 playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
1040 p_playlist->status.i_view,
1041 p_playlist->status.p_item, NULL );
1044 if (p_playlist) vlc_object_release( p_playlist );