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", \
163 input_MetaTypeToLocalizedString(VLC_META), VAL ); \
166 #define add_cddb_meta(FIELD, VLC_META) \
167 add_meta_val(VLC_META, cddb_disc_get_##FIELD(p_cdda->cddb.disc));
169 #define add_cddb_meta_fmt(FIELD, FORMAT_SPEC, VLC_META) \
172 snprintf( psz_buf, sizeof(psz_buf)-1, FORMAT_SPEC, \
173 cddb_disc_get_##FIELD(p_cdda->cddb.disc)); \
174 psz_buf[sizeof(psz_buf)-1] = '\0'; \
175 add_meta_val(VLC_META, psz_buf); \
178 /* Adds a string-valued entry to the stream and media information if
179 the string is not null or the null string.
181 #define add_info_str(CATEGORY, TITLE, FIELD) \
182 if (FIELD && strlen(FIELD)) { \
183 input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY, \
184 _(TITLE), "%s", FIELD ); \
187 /* Adds a numeric-valued entry to the stream and media information
188 if the number is not zero. */
189 #define add_info_val(CATEGORY, TITLE, FMT, FIELD) \
191 input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY, \
192 _(TITLE), FMT, FIELD ); \
195 /* Adds a CDDB string-valued entry to the stream and media information
196 under category "Disc" if the string is not null or the null string.
198 #define add_cddb_disc_info_str(TITLE, FIELD) \
199 add_info_str("Disc", TITLE, cddb_disc_get_##FIELD(p_cdda->cddb.disc))
201 /* Adds a CDDB numeric-valued entry to the stream and media information
202 under category "Disc" if the string is not null or the null string.
204 #define add_cddb_disc_info_val(TITLE, FMT, FIELD) \
205 add_info_val("Disc", TITLE, FMT, cddb_disc_get_##FIELD(p_cdda->cddb.disc))
207 /* Adds a CD-Text string-valued entry to the stream and media information
208 under category "Disc" if the string is not null or the null string.
210 #define add_cdtext_info_str(CATEGORY, TITLE, INDEX, FIELD) \
211 add_info_str(CATEGORY, TITLE, p_cdda->p_cdtext[INDEX]->field[FIELD])
213 /* Adds a CD-Text string-valued entry to the stream and media information
214 under category "Disc" if the string is not null or the null string.
216 #define add_cdtext_disc_info_str(TITLE, FIELD) \
217 add_cdtext_info_str("Disc", TITLE, 0, FIELD)
221 Saves Meta Information about the CD-DA.
223 Meta information used in "stream and media info" or in playlist
224 info. The intialization of CD-Text or CDDB is done here though.
225 Therefore, this should be called before CDDAMetaInfo is called.
229 CDDAMetaInfoInit( access_t *p_access )
231 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
233 if ( ! p_cdda ) return;
235 dbg_print( (INPUT_DBG_CALL), "p_cdda->i_tracks %d",
238 p_cdda->psz_mcn = cdio_get_mcn(p_cdda->p_cdio);
240 p_cdda->p_meta = vlc_meta_New();
244 if ( p_cdda->b_cddb_enabled )
246 GetCDDBInfo(p_access, p_cdda);
249 #endif /*HAVE_LIBCDDB*/
255 for( i_track = 0 ; i_track < p_cdda->i_tracks ; i_track++ )
257 p_cdda->p_cdtext[i_track] =
258 cdio_get_cdtext(p_cdda->p_cdio, i_track);
264 In the Control routine, we handle Meta Information requests and
265 basically copy what was saved in CDDAMetaInfoInit.
267 If i_track is CDIO_INVALID_TRACK we are probably asking about the entire
271 CDDAMetaInfo( access_t *p_access, track_t i_track )
273 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
274 char *psz_meta_title = CDDAFormatMRL( p_access, i_track );
275 char *psz_meta_artist = NULL;
277 if ( ! p_cdda ) return;
279 dbg_print( (INPUT_DBG_CALL), "i_track %d", i_track );
283 /* Set up for Meta and name for CDDB access. */
284 if ( p_cdda->b_cddb_enabled && p_cdda->cddb.disc )
286 if( CDIO_INVALID_TRACK == i_track )
289 psz_meta_title = (char *)cddb_disc_get_title(p_cdda->cddb.disc);
290 psz_meta_artist = (char *)cddb_disc_get_artist(p_cdda->cddb.disc);
291 if ( cddb_disc_get_genre(p_cdda->cddb.disc) &&
292 strlen(cddb_disc_get_genre(p_cdda->cddb.disc)) )
293 add_cddb_meta(genre, vlc_meta_Genre);
294 if ( 0 != cddb_disc_get_year(p_cdda->cddb.disc))
295 add_cddb_meta_fmt(year, "%d", vlc_meta_Date );
299 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i_track-1);
302 if( cddb_track_get_title(t) != NULL && ! p_cdda->b_nav_mode )
304 add_meta_val( vlc_meta_Title, cddb_track_get_title(t) );
306 if( cddb_track_get_artist(t) != NULL )
308 add_meta_val( vlc_meta_Artist, cddb_track_get_artist(t) );
313 #endif /*HAVE_LIBCDDB*/
317 track_t i = p_cdda->i_tracks;
318 const int i_first_track = p_cdda->i_first_track;
319 char psz_buffer[MSTRTIME_MAX_SIZE];
320 unsigned int i_track_frames =
321 cdio_get_track_lba(p_cdda->p_cdio, CDIO_CDROM_LEADOUT_TRACK);
323 mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
325 dbg_print( INPUT_DBG_META, "Duration %ld, tracks %d",
326 (long int) i_duration, p_cdda->i_tracks );
327 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
328 _("Disc"), _("Duration"), "%s",
329 secstotimestr( psz_buffer, i_duration ) );
333 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
334 _("Disc"), _("Media Catalog Number (MCN)"), "%s",
336 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
337 _("Disc"), _("Tracks"), "%d", p_cdda->i_tracks );
341 if (p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
343 add_cddb_disc_info_str("Artist (CDDB)", artist);
344 if ( CDDB_CAT_INVALID != cddb_disc_get_category(p_cdda->cddb.disc) )
345 add_info_str("Disc", "Category (CDDB)",
346 CDDB_CATEGORY[cddb_disc_get_category(p_cdda->cddb.disc)]);
347 add_cddb_disc_info_val("Disc ID (CDDB)", "%x", discid);
348 add_cddb_disc_info_str("Extended Data (CDDB)", ext_data);
349 add_cddb_disc_info_str("Genre (CDDB)", genre);
350 add_cddb_disc_info_str("Title (CDDB)", title);
351 if ( 0 != cddb_disc_get_year(p_cdda->cddb.disc) )
352 add_cddb_disc_info_val("Year (CDDB)", "%d", year);
355 #endif /*HAVE_LIBCDDB*/
357 if (p_cdda->p_cdtext[0])
361 add_cdtext_disc_info_str("Arranger (CD-Text)", CDTEXT_ARRANGER);
362 add_cdtext_disc_info_str("Composer (CD-Text)", CDTEXT_COMPOSER);
363 add_cdtext_disc_info_str("Disc ID (CD-Text)", CDTEXT_DISCID);
364 add_cdtext_disc_info_str("Genre (CD-Text)", CDTEXT_GENRE);
365 add_cdtext_disc_info_str("Message (CD-Text)", CDTEXT_MESSAGE);
366 add_cdtext_disc_info_str("Performer (CD-Text)", CDTEXT_PERFORMER);
367 add_cdtext_disc_info_str("Songwriter (CD-Text)", CDTEXT_SONGWRITER);
368 add_cdtext_disc_info_str("Title (CD-Text)", CDTEXT_TITLE);
370 psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
371 if (psz_field && strlen(psz_field))
372 psz_meta_title = psz_field;
374 psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
375 if (psz_field && strlen(psz_field))
376 psz_meta_artist = psz_field;
379 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
381 char psz_track[TITLE_MAX];
382 const track_t i_track = i_first_track + i;
383 unsigned int i_track_frames =
384 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
385 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
387 mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
388 char *psz_mrl = CDDAFormatMRL( p_access, i_track );
390 snprintf(psz_track, TITLE_MAX, "%s %02d", _("Track"), i_track);
392 input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
394 secstotimestr( psz_buffer, i_duration ) );
396 input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
397 _("MRL"), "%s", psz_mrl );
400 if (p_cdda->p_cdtext[i_track])
402 add_cdtext_info_str( psz_track, "Arranger (CD-Text)",
403 i_track, CDTEXT_ARRANGER);
404 add_cdtext_info_str( psz_track, "Composer (CD-Text)",
405 i_track, CDTEXT_COMPOSER);
406 add_cdtext_info_str( psz_track, "Disc ID (CD-Text)",
407 i_track, CDTEXT_DISCID);
408 add_cdtext_info_str( psz_track, "Genre (CD-Text)",
409 i_track, CDTEXT_GENRE);
410 add_cdtext_info_str( psz_track, "Message (CD-Text)",
411 i_track, CDTEXT_MESSAGE);
412 add_cdtext_info_str( psz_track, "Performer (CD-Text)",
413 i_track, CDTEXT_PERFORMER);
414 add_cdtext_info_str( psz_track, "Songwriter (CD-Text)",
415 i_track, CDTEXT_SONGWRITER);
416 add_cdtext_info_str( psz_track, "Title (CD-Text)",
417 i_track, CDTEXT_TITLE);
421 if (p_cdda->b_cddb_enabled)
423 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i);
426 add_info_str(psz_track, "Artist (CDDB)",
427 cddb_track_get_artist(t));
428 add_info_str(psz_track, "Title (CDDB)",
429 cddb_track_get_title(t));
430 add_info_str(psz_track, "Extended Data (CDDB)",
431 cddb_track_get_ext_data(t));
434 #endif /*HAVE_LIBCDDB*/
437 /* Above we should have set psz_meta_title and psz_meta_artist
438 to CDDB or CD-Text values or the default value depending on
439 availablity and user preferences.
441 So now add the title and artist to VLC's meta, and the name
442 as shown in the status bar and playlist entry.
444 For playlist mode, the meta title is what's seen at the
445 bottom and in the playlist. For nav-mode playing, it is
446 done by input_control. I don't understand why they do
447 different things. In either case, we may have customized to
448 put in the track name.
450 if ( CDIO_INVALID_TRACK != i_track )
452 char *psz_name = CDDAFormatTitle( p_access, i_track ) ;
453 if ( !p_cdda->b_nav_mode ) {
454 add_meta_val( vlc_meta_Title, psz_name );
457 input_Control( p_cdda->p_input, INPUT_SET_NAME, psz_name );
461 add_meta_val( vlc_meta_Artist, psz_meta_artist );
466 #define add_format_str_info(val) \
468 const char *str = val; \
473 strncat(tp, str, TEMP_STR_LEN-(tp-temp_str)); \
476 saw_control_prefix = false; \
480 #define add_format_num_info(val, fmt) \
484 sprintf(num_str, fmt, val); \
485 len=strlen(num_str); \
487 strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); \
490 saw_control_prefix = false; \
495 cdda_data_t *p_cdda, char *psz_cdtext)
497 /* We either don't have CD-Text info, or we do but we prefer to get CDDB
498 which means CDDB has been enabled and we were able to retrieve the info.*/
500 return !psz_cdtext ||
501 (!p_cdda->b_cdtext_prefer && p_cdda->b_cddb_enabled && p_cdda->cddb.disc);
509 Take a format string and expand escape sequences, that is sequences that
510 begin with %, with information from the current CD.
511 The expanded string is returned. Here is a list of escape sequences:
513 %a : The album artist **
514 %A : The album information **
516 %e : The extended track data
520 %m : The CD-DA Media Catalog Number (MCN)
521 %n : The number of tracks on the CD
522 %p : The artist/performer/composer in the track **
523 %T : The track number **
524 %s : Number of seconds in this track, or seconds in CD if invalid track
525 %S : Number of seconds on the CD
526 %t : The track name or MRL if no name
527 %Y : The year 19xx or 20xx **
531 CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
532 const char format_str[], const char *psz_mrl, track_t i_track)
534 #define TEMP_STR_SIZE 256
535 #define TEMP_STR_LEN (TEMP_STR_SIZE-1)
536 static char temp_str[TEMP_STR_SIZE];
538 char * tp = temp_str;
539 bool saw_control_prefix = false;
540 size_t format_len = strlen(format_str);
542 memset(temp_str, 0, TEMP_STR_SIZE);
544 for (i=0; i<format_len; i++)
548 if (!saw_control_prefix && format_str[i] != '%')
550 *tp++ = format_str[i];
551 saw_control_prefix = false;
555 switch(format_str[i])
558 if (saw_control_prefix)
562 saw_control_prefix = !saw_control_prefix;
566 if (p_cdda->p_cdtext[0]
567 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
568 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
569 if (want_cddb_info(p_cdda, psz))
570 psz = (char *)cddb_disc_get_artist(p_cdda->cddb.disc);
573 if (p_cdda->p_cdtext[0]
574 && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
575 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
576 if (want_cddb_info(p_cdda, psz))
577 psz = (char *)cddb_disc_get_title(p_cdda->cddb.disc);
580 if (!p_cdda->b_cddb_enabled) goto not_special;
581 if (p_cdda->cddb.disc)
582 add_format_str_info(CDDB_CATEGORY[cddb_disc_get_category(p_cdda->cddb.disc)]);
585 if (p_cdda->p_cdtext[0]
586 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
587 psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
588 if (want_cddb_info(p_cdda, psz))
589 psz = (char *)cddb_disc_get_genre(p_cdda->cddb.disc);
592 if (p_cdda->p_cdtext[0]
593 && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
594 psz = p_cdda->p_cdtext[0]->field[CDTEXT_DISCID];
595 if (want_cddb_info(p_cdda, psz)) {
596 add_format_num_info(cddb_disc_get_discid(p_cdda->cddb.disc), "%x");
598 add_format_str_info(psz);
601 if (!p_cdda->b_cddb_enabled) goto not_special;
602 if (p_cdda->cddb.disc)
603 add_format_num_info(cddb_disc_get_year(p_cdda->cddb.disc),
607 if ( CDIO_INVALID_TRACK == i_track ) break;
608 if (p_cdda && p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
610 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
612 if (t != NULL && cddb_track_get_title(t) != NULL) {
613 add_format_str_info(cddb_track_get_title(t));
615 add_format_str_info(psz_mrl);
620 if (p_cdda->p_cdtext[i_track]
621 && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE])
623 add_format_str_info(p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE]);
626 add_format_str_info(psz_mrl);
630 if ( CDIO_INVALID_TRACK == i_track ) break;
631 if (p_cdda->p_cdtext[i_track]
632 && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
633 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
634 if (want_cddb_info(p_cdda, psz))
636 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
638 if (t != NULL && cddb_track_get_artist(t) != NULL)
639 psz = (char *)cddb_track_get_artist(t);
643 if ( CDIO_INVALID_TRACK == i_track ) break;
644 if (p_cdda->p_cdtext[i_track]
645 && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
646 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
647 if (want_cddb_info(p_cdda, psz))
649 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
651 if (t != NULL && cddb_track_get_ext_data(t) != NULL)
652 psz = (char *)cddb_track_get_ext_data(t);
658 if (p_cdda->p_cdtext[0]
659 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
660 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
663 if (p_cdda->p_cdtext[0]
664 && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
665 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
668 if (p_cdda->p_cdtext[0]
669 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
670 psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
673 if (p_cdda->p_cdtext[0]
674 && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
675 add_format_str_info(p_cdda->p_cdtext[0]->field[CDTEXT_DISCID]);
678 if ( CDIO_INVALID_TRACK == i_track ) break;
679 if (p_cdda->p_cdtext[i_track]
680 && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
681 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
684 if ( CDIO_INVALID_TRACK == i_track ) break;
685 if (p_cdda->p_cdtext[i_track]
686 && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE])
687 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE];
692 if ( CDIO_INVALID_TRACK == i_track ) break;
693 if (p_cdda->p_cdtext[i_track]
694 && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
695 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
698 #endif /*HAVE_LIBCDDB*/
701 if ( CDIO_INVALID_TRACK != i_track )
703 char psz_buffer[MSTRTIME_MAX_SIZE];
704 unsigned int i_track_frames =
705 cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
707 i_track_frames / CDIO_CD_FRAMES_PER_SEC;
708 add_format_str_info( secstotimestr( psz_buffer,
713 /* Fall through to disc duration if CDIO_INVALID_TRACK */
716 char psz_buffer[MSTRTIME_MAX_SIZE];
717 unsigned int i_track_frames =
718 cdio_get_track_lba(p_cdda->p_cdio,
719 CDIO_CDROM_LEADOUT_TRACK);
721 i_track_frames / CDIO_CD_FRAMES_PER_SEC;
722 add_format_str_info( secstotimestr( psz_buffer,
728 add_format_str_info(psz_mrl);
732 add_format_str_info(p_cdda->psz_mcn);
736 add_format_num_info(p_cdda->i_tracks, "%d");
740 add_format_num_info(i_track, "%02d");
744 add_format_str_info(psz);
751 *tp++ = format_str[i];
752 saw_control_prefix = false;
755 return strdup(temp_str);
758 /* Return a MRL for the given track. The caller must free the
761 CDDAFormatMRL( const access_t *p_access, track_t i_track )
763 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
764 const unsigned int psz_mrl_max = strlen(CDDA_MRL_PREFIX)
765 + strlen(p_cdda->psz_source) +
766 + strlen("@T") + strlen("100") + 1;
767 char *psz_mrl = calloc( 1, psz_mrl_max );
769 if (CDIO_INVALID_TRACK == i_track)
770 snprintf(psz_mrl, psz_mrl_max, "%s%s",
771 CDDA_MRL_PREFIX, p_cdda->psz_source);
773 snprintf(psz_mrl, psz_mrl_max, "%s%s@T%u",
774 CDDA_MRL_PREFIX, p_cdda->psz_source, i_track);
779 /* Return a title string as specified by the titel format string for the
780 given track. The caller must free the allocated string. */
782 CDDAFormatTitle( const access_t *p_access, track_t i_track )
785 const char *config_varname = MODULE_STRING "-title-format";
786 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
787 char *psz_mrl = CDDAFormatMRL( p_access, i_track );
793 if (p_cdda->b_cddb_enabled)
795 config_varname = MODULE_STRING "-cddb-title-format";
797 #endif /*HAVE_LIBCDDB*/
799 CDDAFormatStr( p_access, p_cdda,
800 config_GetPsz( p_access, config_varname ),
808 static playlist_item_t *
809 CDDACreatePlaylistItem( const access_t *p_access, cdda_data_t *p_cdda,
810 playlist_t *p_playlist, playlist_item_t *p_item,
813 unsigned int i_track_frames =
814 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
815 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
816 mtime_t i_mduration = i_track_frames * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) ;
817 char *psz_title = NULL;
818 char *psz_mrl = NULL;
820 playlist_item_t *p_child = NULL;
822 if( !p_item ) return NULL;
824 psz_title = CDDAFormatTitle( p_access, i_track ) ;
825 psz_mrl = CDDAFormatMRL( p_access, i_track ) ;
827 dbg_print( INPUT_DBG_META, "mrl: %s, title: %s, duration, %ld",
828 psz_mrl, psz_title, (long int) i_mduration / 1000000 );
830 p_child = playlist_ItemNew( p_playlist, psz_mrl, psz_title );
831 input_item_SetDuration( input_GetItem( p_child->p_input ),
832 (mtime_t) i_mduration );
836 if( !p_child ) return NULL;
844 CDDAFixupPlaylist( access_t *p_access, cdda_data_t *p_cdda,
845 bool b_single_track )
848 playlist_t * p_playlist = NULL;
849 const track_t i_first_track = p_cdda->i_first_track;
850 playlist_item_t *p_item = NULL;
855 p_cdda->b_cddb_enabled =
856 config_GetInt( p_access, MODULE_STRING "-cddb-enabled" );
857 if( b_single_track && !p_cdda->b_cddb_enabled )
864 if (! p_cdda->b_nav_mode ) {
865 p_playlist = pl_Yield( p_access );
868 if( b_single_track || p_cdda->b_nav_mode ) {
869 i_track = p_cdda->i_track;
873 i_track = CDIO_INVALID_TRACK;
875 CDDAMetaInfoInit( p_access );
876 CDDAMetaInfo( p_access, p_cdda->i_track );
880 input_thread_t *p_input = (input_thread_t*)vlc_object_find( p_access, VLC_OBJECT_INPUT, FIND_PARENT );
883 p_item = playlist_ItemGetByInput( p_playlist, input_GetItem(p_input), false );
885 if( p_item == p_playlist->status.p_item && !b_single_track )
889 vlc_object_release( p_input );
893 if( b_single_track && !p_cdda->b_nav_mode )
895 /*May fill out more information when the playlist user interface becomes
898 track_t i_track = p_cdda->i_track;
899 unsigned int i_track_frames =
900 cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
902 input_title_t *t = p_cdda->p_title[0] = //i_track-i_first_track] =
903 vlc_input_title_New();
905 asprintf( &t->psz_name, _("Track %i"), i_track );
906 t->i_size = i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
907 t->i_length = INT64_C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
911 input_item_SetDuration( p_item->p_input, (mtime_t) i_track_frames
912 * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) );
913 input_item_SetURI( p_item->p_input,
914 CDDAFormatMRL( p_access, i_track ) );
917 p_cdda->i_titles = 1;
918 p_access->info.i_update = INPUT_UPDATE_TITLE;
924 if( !p_cdda->b_nav_mode )
925 playlist_ItemToNode( p_playlist, p_item, false );
927 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
929 playlist_item_t *p_child;
930 const track_t i_track = i_first_track + i;
931 unsigned int i_track_frames =
932 cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
934 t = p_cdda->p_title[i] = vlc_input_title_New();
936 asprintf( &t->psz_name, _("Track %i"), i_track );
937 t->i_size = i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
939 t->i_length = INT64_C(1000000) * t->i_size
940 / CDDA_FREQUENCY_SAMPLE / 4;
942 if ( ! p_cdda->b_nav_mode )
944 p_child = CDDACreatePlaylistItem( p_access, p_cdda, p_playlist,
949 p_cdda->i_titles = p_cdda->i_tracks;
950 p_access->info.i_update |= INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE;
953 input_item_SetDuration( p_item->p_input, (mtime_t) p_access->info.i_size
954 * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) );
955 input_item_SetURI( p_item->p_input,
956 CDDAFormatMRL( p_access, p_cdda->i_track ) );
962 playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, true,
963 p_playlist->status.p_item, NULL );
966 if (p_playlist) vlc_object_release( p_playlist );