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 */
30 #warning playlist code must not be used here.
31 #include <vlc_playlist.h> /* Has to come *after* cdda.h */
33 #include <cdio/cdio.h>
34 #include <cdio/cdtext.h>
35 #include <cdio/logging.h>
36 #include <cdio/cd_types.h>
42 static char *CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
43 const char format_str[], const char *psz_mrl,
46 static char *CDDAFormatMRL( const access_t *p_access, track_t i_track );
50 #define free_and_dup(var, val) \
52 if (val) var=strdup(val);
55 /* Saves CDDB information about CD-DA via libcddb. */
57 GetCDDBInfo( access_t *p_access, cdda_data_t *p_cdda )
60 cddb_conn_t *conn = cddb_new();
61 const CdIo_t *p_cdio = p_cdda->p_cdio;
63 dbg_print( (INPUT_DBG_CALL), "" );
66 cddb_log_set_handler (uninit_log_handler);
71 msg_Warn( p_access, "Unable to initialize libcddb" );
75 char* psz_email = config_GetPsz( p_access, MODULE_STRING "-cddb-email");
76 char* psz_srv_name = config_GetPsz( p_access, MODULE_STRING "-cddb-server");
77 cddb_set_email_address( conn, psz_email );
78 cddb_set_server_name( conn, psz_srv_name );
79 cddb_set_server_port(conn,
80 config_GetInt( p_access,
81 MODULE_STRING "-cddb-port") );
85 /* Set the location of the local CDDB cache directory.
86 The default location of this directory is */
88 if (!config_GetInt( p_access, MODULE_STRING "-cddb-enable-cache" ))
89 cddb_cache_disable(conn);
91 char* psz_cache = config_GetPsz( p_access, MODULE_STRING "-cddb-cachedir");
92 cddb_cache_set_dir(conn, psz_cache );
95 cddb_set_timeout(conn,
96 config_GetInt( p_access, MODULE_STRING "-cddb-timeout") );
99 if (config_GetInt( p_access, MODULE_STRING "-cddb-httpd" ) )
101 cddb_http_enable(conn);
105 cddb_http_disable(conn);
108 p_cdda->cddb.disc = cddb_disc_new();
110 if (!p_cdda->cddb.disc)
112 msg_Err( p_access, "Unable to create CDDB disc structure." );
116 for(i = 0; i < p_cdda->i_tracks; i++)
118 track_t i_track = p_cdda->i_first_track + i;
119 cddb_track_t *t = cddb_track_new();
120 cddb_track_set_frame_offset(t,
121 cdio_get_track_lba(p_cdio, i_track));
122 cddb_disc_add_track(p_cdda->cddb.disc, t);
125 cddb_disc_set_length(p_cdda->cddb.disc,
126 cdio_get_track_lba(p_cdio, CDIO_CDROM_LEADOUT_TRACK)
127 / CDIO_CD_FRAMES_PER_SEC);
129 if (!cddb_disc_calc_discid(p_cdda->cddb.disc))
131 msg_Err( p_access, "CDDB disc ID calculation failed" );
135 i_matches = cddb_query(conn, p_cdda->cddb.disc);
140 msg_Warn( p_access, "Found %d matches in CDDB. Using first one.",
142 cddb_read(conn, p_cdda->cddb.disc);
144 if (p_cdda->i_debug & INPUT_DBG_CDDB)
145 cddb_disc_print(p_cdda->cddb.disc);
150 msg_Warn( p_access, "CDDB error: %s", cddb_error_str(errno));
158 #endif /*HAVE_LIBCDDB*/
160 #define add_meta_val(VLC_META, VAL) \
161 if ( p_cdda->p_meta && VAL) { \
162 /*vlc_meta_Add( p_cdda->p_meta, VLC_META, VAL );*/ \
163 dbg_print( INPUT_DBG_META, "field %s: %s\n", \
164 input_MetaTypeToLocalizedString(VLC_META), VAL ); \
167 #define add_cddb_meta(FIELD, VLC_META) \
168 add_meta_val(VLC_META, cddb_disc_get_##FIELD(p_cdda->cddb.disc));
170 #define add_cddb_meta_fmt(FIELD, FORMAT_SPEC, VLC_META) \
173 snprintf( psz_buf, sizeof(psz_buf)-1, FORMAT_SPEC, \
174 cddb_disc_get_##FIELD(p_cdda->cddb.disc)); \
175 psz_buf[sizeof(psz_buf)-1] = '\0'; \
176 add_meta_val(VLC_META, psz_buf); \
179 /* Adds a string-valued entry to the stream and media information if
180 the string is not null or the null string.
182 #define add_info_str(CATEGORY, TITLE, FIELD) \
183 if (FIELD && strlen(FIELD)) { \
184 input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY, \
185 _(TITLE), "%s", FIELD ); \
188 /* Adds a numeric-valued entry to the stream and media information
189 if the number is not zero. */
190 #define add_info_val(CATEGORY, TITLE, FMT, FIELD) \
192 input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY, \
193 _(TITLE), FMT, FIELD ); \
196 /* Adds a CDDB string-valued entry to the stream and media information
197 under category "Disc" if the string is not null or the null string.
199 #define add_cddb_disc_info_str(TITLE, FIELD) \
200 add_info_str("Disc", TITLE, cddb_disc_get_##FIELD(p_cdda->cddb.disc))
202 /* Adds a CDDB numeric-valued entry to the stream and media information
203 under category "Disc" if the string is not null or the null string.
205 #define add_cddb_disc_info_val(TITLE, FMT, FIELD) \
206 add_info_val("Disc", TITLE, FMT, cddb_disc_get_##FIELD(p_cdda->cddb.disc))
208 /* Adds a CD-Text string-valued entry to the stream and media information
209 under category "Disc" if the string is not null or the null string.
211 #define add_cdtext_info_str(CATEGORY, TITLE, INDEX, FIELD) \
212 add_info_str(CATEGORY, TITLE, p_cdda->p_cdtext[INDEX]->field[FIELD])
214 /* Adds a CD-Text string-valued entry to the stream and media information
215 under category "Disc" if the string is not null or the null string.
217 #define add_cdtext_disc_info_str(TITLE, FIELD) \
218 add_cdtext_info_str("Disc", TITLE, 0, FIELD)
222 Saves Meta Information about the CD-DA.
224 Meta information used in "stream and media info" or in playlist
225 info. The intialization of CD-Text or CDDB is done here though.
226 Therefore, this should be called before CDDAMetaInfo is called.
230 CDDAMetaInfoInit( access_t *p_access )
232 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
234 if ( ! p_cdda ) return;
236 dbg_print( (INPUT_DBG_CALL), "p_cdda->i_tracks %d",
239 p_cdda->psz_mcn = cdio_get_mcn(p_cdda->p_cdio);
241 p_cdda->p_meta = vlc_meta_New();
245 if ( p_cdda->b_cddb_enabled )
247 GetCDDBInfo(p_access, p_cdda);
250 #endif /*HAVE_LIBCDDB*/
256 for( i_track = 0 ; i_track < p_cdda->i_tracks ; i_track++ )
258 p_cdda->p_cdtext[i_track] =
259 cdio_get_cdtext(p_cdda->p_cdio, i_track);
265 In the Control routine, we handle Meta Information requests and
266 basically copy what was saved in CDDAMetaInfoInit.
268 If i_track is CDIO_INVALID_TRACK we are probably asking about the entire
272 CDDAMetaInfo( access_t *p_access, track_t i_track )
274 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
275 char *psz_meta_title = CDDAFormatMRL( p_access, i_track );
276 char *psz_meta_artist = NULL;
278 if ( ! p_cdda ) return;
280 dbg_print( (INPUT_DBG_CALL), "i_track %d", i_track );
284 /* Set up for Meta and name for CDDB access. */
285 if ( p_cdda->b_cddb_enabled && p_cdda->cddb.disc )
287 if( CDIO_INVALID_TRACK == i_track )
290 psz_meta_title = (char *)cddb_disc_get_title(p_cdda->cddb.disc);
291 psz_meta_artist = (char *)cddb_disc_get_artist(p_cdda->cddb.disc);
292 if ( cddb_disc_get_genre(p_cdda->cddb.disc) &&
293 strlen(cddb_disc_get_genre(p_cdda->cddb.disc)) )
294 add_cddb_meta(genre, vlc_meta_Genre);
295 if ( 0 != cddb_disc_get_year(p_cdda->cddb.disc))
296 add_cddb_meta_fmt(year, "%d", vlc_meta_Date );
300 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i_track-1);
303 if( cddb_track_get_title(t) != NULL && ! p_cdda->b_nav_mode )
305 add_meta_val( vlc_meta_Title, cddb_track_get_title(t) );
307 if( cddb_track_get_artist(t) != NULL )
309 add_meta_val( vlc_meta_Artist, cddb_track_get_artist(t) );
314 #endif /*HAVE_LIBCDDB*/
318 track_t i = p_cdda->i_tracks;
319 const int i_first_track = p_cdda->i_first_track;
320 char psz_buffer[MSTRTIME_MAX_SIZE];
321 unsigned int i_track_frames =
322 cdio_get_track_lba(p_cdda->p_cdio, CDIO_CDROM_LEADOUT_TRACK);
324 mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
326 dbg_print( INPUT_DBG_META, "Duration %ld, tracks %d",
327 (long int) i_duration, p_cdda->i_tracks );
328 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
329 _("Disc"), _("Duration"), "%s",
330 secstotimestr( psz_buffer, i_duration ) );
334 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
335 _("Disc"), _("Media Catalog Number (MCN)"), "%s",
337 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
338 _("Disc"), _("Tracks"), "%d", p_cdda->i_tracks );
342 if (p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
344 add_cddb_disc_info_str("Artist (CDDB)", artist);
345 if ( CDDB_CAT_INVALID != cddb_disc_get_category(p_cdda->cddb.disc) )
346 add_info_str("Disc", "Category (CDDB)",
347 CDDB_CATEGORY[cddb_disc_get_category(p_cdda->cddb.disc)]);
348 add_cddb_disc_info_val("Disc ID (CDDB)", "%x", discid);
349 add_cddb_disc_info_str("Extended Data (CDDB)", ext_data);
350 add_cddb_disc_info_str("Genre (CDDB)", genre);
351 add_cddb_disc_info_str("Title (CDDB)", title);
352 if ( 0 != cddb_disc_get_year(p_cdda->cddb.disc) )
353 add_cddb_disc_info_val("Year (CDDB)", "%d", year);
356 #endif /*HAVE_LIBCDDB*/
358 if (p_cdda->p_cdtext[0])
362 add_cdtext_disc_info_str("Arranger (CD-Text)", CDTEXT_ARRANGER);
363 add_cdtext_disc_info_str("Composer (CD-Text)", CDTEXT_COMPOSER);
364 add_cdtext_disc_info_str("Disc ID (CD-Text)", CDTEXT_DISCID);
365 add_cdtext_disc_info_str("Genre (CD-Text)", CDTEXT_GENRE);
366 add_cdtext_disc_info_str("Message (CD-Text)", CDTEXT_MESSAGE);
367 add_cdtext_disc_info_str("Performer (CD-Text)", CDTEXT_PERFORMER);
368 add_cdtext_disc_info_str("Songwriter (CD-Text)", CDTEXT_SONGWRITER);
369 add_cdtext_disc_info_str("Title (CD-Text)", CDTEXT_TITLE);
371 psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
372 if (psz_field && strlen(psz_field))
373 psz_meta_title = psz_field;
375 psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
376 if (psz_field && strlen(psz_field))
377 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 );
467 #define add_format_str_info(val) \
469 const char *str = val; \
474 strncat(tp, str, TEMP_STR_LEN-(tp-temp_str)); \
477 saw_control_prefix = false; \
481 #define add_format_num_info(val, fmt) \
485 sprintf(num_str, fmt, val); \
486 len=strlen(num_str); \
488 strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); \
491 saw_control_prefix = false; \
496 cdda_data_t *p_cdda, char *psz_cdtext)
498 /* We either don't have CD-Text info, or we do but we prefer to get CDDB
499 which means CDDB has been enabled and we were able to retrieve the info.*/
501 return !psz_cdtext ||
502 (!p_cdda->b_cdtext_prefer && p_cdda->b_cddb_enabled && p_cdda->cddb.disc);
510 Take a format string and expand escape sequences, that is sequences that
511 begin with %, with information from the current CD.
512 The expanded string is returned. Here is a list of escape sequences:
514 %a : The album artist **
515 %A : The album information **
517 %e : The extended track data
521 %m : The CD-DA Media Catalog Number (MCN)
522 %n : The number of tracks on the CD
523 %p : The artist/performer/composer in the track **
524 %T : The track number **
525 %s : Number of seconds in this track, or seconds in CD if invalid track
526 %S : Number of seconds on the CD
527 %t : The track name or MRL if no name
528 %Y : The year 19xx or 20xx **
532 CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
533 const char format_str[], const char *psz_mrl, track_t i_track)
535 #define TEMP_STR_SIZE 256
536 #define TEMP_STR_LEN (TEMP_STR_SIZE-1)
537 static char temp_str[TEMP_STR_SIZE];
539 char * tp = temp_str;
540 bool saw_control_prefix = false;
541 size_t format_len = strlen(format_str);
543 memset(temp_str, 0, TEMP_STR_SIZE);
545 for (i=0; i<format_len; i++)
549 if (!saw_control_prefix && format_str[i] != '%')
551 *tp++ = format_str[i];
552 saw_control_prefix = false;
556 switch(format_str[i])
559 if (saw_control_prefix)
563 saw_control_prefix = !saw_control_prefix;
567 if (p_cdda->p_cdtext[0]
568 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
569 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
570 if (want_cddb_info(p_cdda, psz))
571 psz = (char *)cddb_disc_get_artist(p_cdda->cddb.disc);
574 if (p_cdda->p_cdtext[0]
575 && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
576 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
577 if (want_cddb_info(p_cdda, psz))
578 psz = (char *)cddb_disc_get_title(p_cdda->cddb.disc);
581 if (!p_cdda->b_cddb_enabled) goto not_special;
582 if (p_cdda->cddb.disc)
583 add_format_str_info(CDDB_CATEGORY[cddb_disc_get_category(p_cdda->cddb.disc)]);
586 if (p_cdda->p_cdtext[0]
587 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
588 psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
589 if (want_cddb_info(p_cdda, psz))
590 psz = (char *)cddb_disc_get_genre(p_cdda->cddb.disc);
593 if (p_cdda->p_cdtext[0]
594 && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
595 psz = p_cdda->p_cdtext[0]->field[CDTEXT_DISCID];
596 if (want_cddb_info(p_cdda, psz)) {
597 add_format_num_info(cddb_disc_get_discid(p_cdda->cddb.disc), "%x");
599 add_format_str_info(psz);
602 if (!p_cdda->b_cddb_enabled) goto not_special;
603 if (p_cdda->cddb.disc)
604 add_format_num_info(cddb_disc_get_year(p_cdda->cddb.disc),
608 if ( CDIO_INVALID_TRACK == i_track ) break;
609 if (p_cdda && p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
611 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
613 if (t != NULL && cddb_track_get_title(t) != NULL) {
614 add_format_str_info(cddb_track_get_title(t));
616 add_format_str_info(psz_mrl);
621 if (p_cdda->p_cdtext[i_track]
622 && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE])
624 add_format_str_info(p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE]);
627 add_format_str_info(psz_mrl);
631 if ( CDIO_INVALID_TRACK == i_track ) break;
632 if (p_cdda->p_cdtext[i_track]
633 && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
634 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
635 if (want_cddb_info(p_cdda, psz))
637 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
639 if (t != NULL && cddb_track_get_artist(t) != NULL)
640 psz = (char *)cddb_track_get_artist(t);
644 if ( CDIO_INVALID_TRACK == i_track ) break;
645 if (p_cdda->p_cdtext[i_track]
646 && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
647 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
648 if (want_cddb_info(p_cdda, psz))
650 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
652 if (t != NULL && cddb_track_get_ext_data(t) != NULL)
653 psz = (char *)cddb_track_get_ext_data(t);
659 if (p_cdda->p_cdtext[0]
660 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
661 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
664 if (p_cdda->p_cdtext[0]
665 && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
666 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
669 if (p_cdda->p_cdtext[0]
670 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
671 psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
674 if (p_cdda->p_cdtext[0]
675 && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
676 add_format_str_info(p_cdda->p_cdtext[0]->field[CDTEXT_DISCID]);
679 if ( CDIO_INVALID_TRACK == i_track ) break;
680 if (p_cdda->p_cdtext[i_track]
681 && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
682 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
685 if ( CDIO_INVALID_TRACK == i_track ) break;
686 if (p_cdda->p_cdtext[i_track]
687 && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE])
688 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE];
693 if ( CDIO_INVALID_TRACK == i_track ) break;
694 if (p_cdda->p_cdtext[i_track]
695 && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
696 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
699 #endif /*HAVE_LIBCDDB*/
702 if ( CDIO_INVALID_TRACK != i_track )
704 char psz_buffer[MSTRTIME_MAX_SIZE];
705 unsigned int i_track_frames =
706 cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
708 i_track_frames / CDIO_CD_FRAMES_PER_SEC;
709 add_format_str_info( secstotimestr( psz_buffer,
714 /* Fall through to disc duration if CDIO_INVALID_TRACK */
717 char psz_buffer[MSTRTIME_MAX_SIZE];
718 unsigned int i_track_frames =
719 cdio_get_track_lba(p_cdda->p_cdio,
720 CDIO_CDROM_LEADOUT_TRACK);
722 i_track_frames / CDIO_CD_FRAMES_PER_SEC;
723 add_format_str_info( secstotimestr( psz_buffer,
729 add_format_str_info(psz_mrl);
733 add_format_str_info(p_cdda->psz_mcn);
737 add_format_num_info(p_cdda->i_tracks, "%d");
741 add_format_num_info(i_track, "%02d");
745 add_format_str_info(psz);
752 *tp++ = format_str[i];
753 saw_control_prefix = false;
756 return strdup(temp_str);
759 /* Return a MRL for the given track. The caller must free the
762 CDDAFormatMRL( const access_t *p_access, track_t i_track )
764 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
765 const unsigned int psz_mrl_max = strlen(CDDA_MRL_PREFIX)
766 + strlen(p_cdda->psz_source) +
767 + strlen("@T") + strlen("100") + 1;
768 char *psz_mrl = calloc( 1, psz_mrl_max );
770 if (CDIO_INVALID_TRACK == i_track)
771 snprintf(psz_mrl, psz_mrl_max, "%s%s",
772 CDDA_MRL_PREFIX, p_cdda->psz_source);
774 snprintf(psz_mrl, psz_mrl_max, "%s%s@T%u",
775 CDDA_MRL_PREFIX, p_cdda->psz_source, i_track);
780 /* Return a title string as specified by the titel format string for the
781 given track. The caller must free the allocated string. */
783 CDDAFormatTitle( const access_t *p_access, track_t i_track )
786 const char *config_varname = MODULE_STRING "-title-format";
787 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
788 char *psz_mrl = CDDAFormatMRL( p_access, i_track );
794 if (p_cdda->b_cddb_enabled)
796 config_varname = MODULE_STRING "-cddb-title-format";
798 #endif /*HAVE_LIBCDDB*/
799 char* psz_config_varname = config_GetPsz( p_access, config_varname );
800 psz_name = CDDAFormatStr( p_access, p_cdda, psz_config_varname,
802 free( psz_config_varname );
813 CDDAFixupPlaylist( access_t *p_access, cdda_data_t *p_cdda,
814 bool b_single_track )
817 const track_t i_first_track = p_cdda->i_first_track;
821 p_cdda->b_cddb_enabled =
822 config_GetInt( p_access, MODULE_STRING "-cddb-enabled" );
823 if( b_single_track && !p_cdda->b_cddb_enabled )
830 if( b_single_track || p_cdda->b_nav_mode ) {
831 i_track = p_cdda->i_track;
835 i_track = CDIO_INVALID_TRACK;
837 CDDAMetaInfoInit( p_access );
838 CDDAMetaInfo( p_access, p_cdda->i_track );
840 if( b_single_track && !p_cdda->b_nav_mode )
842 /*May fill out more information when the playlist user interface becomes
845 track_t i_track = p_cdda->i_track;
846 unsigned int i_track_frames =
847 cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
849 input_title_t *t = p_cdda->p_title[0] = //i_track-i_first_track] =
850 vlc_input_title_New();
852 if( asprintf( &t->psz_name, _("Track %i"), i_track ) == -1 )
854 t->i_size = i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
855 t->i_length = INT64_C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
857 p_cdda->i_titles = 1;
858 p_access->info.i_update = INPUT_UPDATE_TITLE;
862 input_thread_t *p_input = (input_thread_t*)vlc_object_find( p_access, VLC_OBJECT_INPUT, FIND_PARENT );
866 input_item_t *p_current = input_GetItem( p_input );
869 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
871 const track_t i_track = i_first_track + i;
872 unsigned int i_track_frames =
873 cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
876 t = p_cdda->p_title[i] = vlc_input_title_New();
878 if( asprintf( &t->psz_name, _("Track %i"), i_track ) == -1 )
880 t->i_size = i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
882 t->i_length = INT64_C(1000000) * t->i_size
883 / CDDA_FREQUENCY_SAMPLE / 4;
885 if( !p_cdda->b_nav_mode )
887 input_item_t *p_child;
888 char *psz_mrl = CDDAFormatMRL( p_access, i_track );
889 char *psz_title = CDDAFormatTitle( p_access, i_track );
890 unsigned int i_track_frames =
891 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
892 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
893 mtime_t i_mduration = i_track_frames * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) ;
895 p_child = input_item_NewWithType( VLC_OBJECT( p_access ),
896 psz_mrl, psz_title, 0, NULL, 0, i_mduration,
900 input_item_CopyOptions( p_current, p_child );
902 input_item_AddSubItem( p_current, p_child );
904 vlc_gc_decref( p_child );
911 p_cdda->i_titles = p_cdda->i_tracks;
912 p_access->info.i_update |= INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE;
915 input_item_SetDuration( p_current,
916 (mtime_t) p_access->info.i_size * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) );
917 input_item_SetURI( p_current, CDDAFormatMRL( p_access, p_cdda->i_track ) );
920 vlc_object_release( p_input );