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>
44 static char *CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
45 const char format_str[], const char *psz_mrl,
48 static char *CDDAFormatMRL( const access_t *p_access, track_t i_track );
52 #define free_and_dup(var, val) \
54 if (val) var=strdup(val);
57 /* Saves CDDB information about CD-DA via libcddb. */
59 GetCDDBInfo( access_t *p_access, cdda_data_t *p_cdda )
62 cddb_conn_t *conn = cddb_new();
63 const CdIo_t *p_cdio = p_cdda->p_cdio;
65 dbg_print( (INPUT_DBG_CALL), "" );
68 cddb_log_set_handler (uninit_log_handler);
73 msg_Warn( p_access, "Unable to initialize libcddb" );
77 char* psz_email = config_GetPsz( p_access, MODULE_STRING "-cddb-email");
78 char* psz_srv_name = config_GetPsz( p_access, MODULE_STRING "-cddb-server");
79 cddb_set_email_address( conn, psz_email );
80 cddb_set_server_name( conn, psz_srv_name );
81 cddb_set_server_port(conn,
82 config_GetInt( p_access,
83 MODULE_STRING "-cddb-port") );
87 /* Set the location of the local CDDB cache directory.
88 The default location of this directory is */
90 if (!config_GetInt( p_access, MODULE_STRING "-cddb-enable-cache" ))
91 cddb_cache_disable(conn);
93 char* psz_cache = config_GetPsz( p_access, MODULE_STRING "-cddb-cachedir");
94 cddb_cache_set_dir(conn, psz_cache );
97 cddb_set_timeout(conn,
98 config_GetInt( p_access, MODULE_STRING "-cddb-timeout") );
101 if (config_GetInt( p_access, MODULE_STRING "-cddb-httpd" ) )
103 cddb_http_enable(conn);
107 cddb_http_disable(conn);
110 p_cdda->cddb.disc = cddb_disc_new();
112 if (!p_cdda->cddb.disc)
114 msg_Err( p_access, "Unable to create CDDB disc structure." );
118 for(i = 0; i < p_cdda->i_tracks; i++)
120 track_t i_track = p_cdda->i_first_track + i;
121 cddb_track_t *t = cddb_track_new();
122 cddb_track_set_frame_offset(t,
123 cdio_get_track_lba(p_cdio, i_track));
124 cddb_disc_add_track(p_cdda->cddb.disc, t);
127 cddb_disc_set_length(p_cdda->cddb.disc,
128 cdio_get_track_lba(p_cdio, CDIO_CDROM_LEADOUT_TRACK)
129 / CDIO_CD_FRAMES_PER_SEC);
131 if (!cddb_disc_calc_discid(p_cdda->cddb.disc))
133 msg_Err( p_access, "CDDB disc ID calculation failed" );
137 i_matches = cddb_query(conn, p_cdda->cddb.disc);
142 msg_Warn( p_access, "Found %d matches in CDDB. Using first one.",
144 cddb_read(conn, p_cdda->cddb.disc);
146 if (p_cdda->i_debug & INPUT_DBG_CDDB)
147 cddb_disc_print(p_cdda->cddb.disc);
152 msg_Warn( p_access, "CDDB error: %s", cddb_error_str(errno));
160 #endif /*HAVE_LIBCDDB*/
162 #define add_meta_val(VLC_META, VAL) \
163 if ( p_cdda->p_meta && VAL) { \
164 /*vlc_meta_Add( p_cdda->p_meta, VLC_META, VAL );*/ \
165 dbg_print( INPUT_DBG_META, "field %s: %s\n", \
166 input_MetaTypeToLocalizedString(VLC_META), VAL ); \
169 #define add_cddb_meta(FIELD, VLC_META) \
170 add_meta_val(VLC_META, cddb_disc_get_##FIELD(p_cdda->cddb.disc));
172 #define add_cddb_meta_fmt(FIELD, FORMAT_SPEC, VLC_META) \
175 snprintf( psz_buf, sizeof(psz_buf)-1, FORMAT_SPEC, \
176 cddb_disc_get_##FIELD(p_cdda->cddb.disc)); \
177 psz_buf[sizeof(psz_buf)-1] = '\0'; \
178 add_meta_val(VLC_META, psz_buf); \
181 /* Adds a string-valued entry to the stream and media information if
182 the string is not null or the null string.
184 #define add_info_str(CATEGORY, TITLE, FIELD) \
185 if (FIELD && strlen(FIELD)) { \
186 input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY, \
187 _(TITLE), "%s", FIELD ); \
190 /* Adds a numeric-valued entry to the stream and media information
191 if the number is not zero. */
192 #define add_info_val(CATEGORY, TITLE, FMT, FIELD) \
194 input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY, \
195 _(TITLE), FMT, FIELD ); \
198 /* Adds a CDDB string-valued entry to the stream and media information
199 under category "Disc" if the string is not null or the null string.
201 #define add_cddb_disc_info_str(TITLE, FIELD) \
202 add_info_str("Disc", TITLE, cddb_disc_get_##FIELD(p_cdda->cddb.disc))
204 /* Adds a CDDB numeric-valued entry to the stream and media information
205 under category "Disc" if the string is not null or the null string.
207 #define add_cddb_disc_info_val(TITLE, FMT, FIELD) \
208 add_info_val("Disc", TITLE, FMT, cddb_disc_get_##FIELD(p_cdda->cddb.disc))
210 /* Adds a CD-Text string-valued entry to the stream and media information
211 under category "Disc" if the string is not null or the null string.
213 #define add_cdtext_info_str(CATEGORY, TITLE, INDEX, FIELD) \
214 add_info_str(CATEGORY, TITLE, p_cdda->p_cdtext[INDEX]->field[FIELD])
216 /* Adds a CD-Text string-valued entry to the stream and media information
217 under category "Disc" if the string is not null or the null string.
219 #define add_cdtext_disc_info_str(TITLE, FIELD) \
220 add_cdtext_info_str("Disc", TITLE, 0, FIELD)
224 Saves Meta Information about the CD-DA.
226 Meta information used in "stream and media info" or in playlist
227 info. The intialization of CD-Text or CDDB is done here though.
228 Therefore, this should be called before CDDAMetaInfo is called.
232 CDDAMetaInfoInit( access_t *p_access )
234 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
236 if ( ! p_cdda ) return;
238 dbg_print( (INPUT_DBG_CALL), "p_cdda->i_tracks %d",
241 p_cdda->psz_mcn = cdio_get_mcn(p_cdda->p_cdio);
243 p_cdda->p_meta = vlc_meta_New();
247 if ( p_cdda->b_cddb_enabled )
249 GetCDDBInfo(p_access, p_cdda);
252 #endif /*HAVE_LIBCDDB*/
258 for( i_track = 0 ; i_track < p_cdda->i_tracks ; i_track++ )
260 p_cdda->p_cdtext[i_track] =
261 cdio_get_cdtext(p_cdda->p_cdio, i_track);
267 In the Control routine, we handle Meta Information requests and
268 basically copy what was saved in CDDAMetaInfoInit.
270 If i_track is CDIO_INVALID_TRACK we are probably asking about the entire
274 CDDAMetaInfo( access_t *p_access, track_t i_track )
276 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
277 char *psz_meta_title = CDDAFormatMRL( p_access, i_track );
278 char *psz_meta_artist = NULL;
280 if ( ! p_cdda ) return;
282 dbg_print( (INPUT_DBG_CALL), "i_track %d", i_track );
286 /* Set up for Meta and name for CDDB access. */
287 if ( p_cdda->b_cddb_enabled && p_cdda->cddb.disc )
289 if( CDIO_INVALID_TRACK == i_track )
292 psz_meta_title = (char *)cddb_disc_get_title(p_cdda->cddb.disc);
293 psz_meta_artist = (char *)cddb_disc_get_artist(p_cdda->cddb.disc);
294 if ( cddb_disc_get_genre(p_cdda->cddb.disc) &&
295 strlen(cddb_disc_get_genre(p_cdda->cddb.disc)) )
296 add_cddb_meta(genre, vlc_meta_Genre);
297 if ( 0 != cddb_disc_get_year(p_cdda->cddb.disc))
298 add_cddb_meta_fmt(year, "%d", vlc_meta_Date );
302 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i_track-1);
305 if( cddb_track_get_title(t) != NULL && ! p_cdda->b_nav_mode )
307 add_meta_val( vlc_meta_Title, cddb_track_get_title(t) );
309 if( cddb_track_get_artist(t) != NULL )
311 add_meta_val( vlc_meta_Artist, cddb_track_get_artist(t) );
316 #endif /*HAVE_LIBCDDB*/
320 track_t i = p_cdda->i_tracks;
321 const int i_first_track = p_cdda->i_first_track;
322 char psz_buffer[MSTRTIME_MAX_SIZE];
323 unsigned int i_track_frames =
324 cdio_get_track_lba(p_cdda->p_cdio, CDIO_CDROM_LEADOUT_TRACK);
326 mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
328 dbg_print( INPUT_DBG_META, "Duration %ld, tracks %d",
329 (long int) i_duration, p_cdda->i_tracks );
330 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
331 _("Disc"), _("Duration"), "%s",
332 secstotimestr( psz_buffer, i_duration ) );
336 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
337 _("Disc"), _("Media Catalog Number (MCN)"), "%s",
339 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
340 _("Disc"), _("Tracks"), "%d", p_cdda->i_tracks );
344 if (p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
346 add_cddb_disc_info_str("Artist (CDDB)", artist);
347 if ( CDDB_CAT_INVALID != cddb_disc_get_category(p_cdda->cddb.disc) )
348 add_info_str("Disc", "Category (CDDB)",
349 CDDB_CATEGORY[cddb_disc_get_category(p_cdda->cddb.disc)]);
350 add_cddb_disc_info_val("Disc ID (CDDB)", "%x", discid);
351 add_cddb_disc_info_str("Extended Data (CDDB)", ext_data);
352 add_cddb_disc_info_str("Genre (CDDB)", genre);
353 add_cddb_disc_info_str("Title (CDDB)", title);
354 if ( 0 != cddb_disc_get_year(p_cdda->cddb.disc) )
355 add_cddb_disc_info_val("Year (CDDB)", "%d", year);
358 #endif /*HAVE_LIBCDDB*/
360 if (p_cdda->p_cdtext[0])
364 add_cdtext_disc_info_str("Arranger (CD-Text)", CDTEXT_ARRANGER);
365 add_cdtext_disc_info_str("Composer (CD-Text)", CDTEXT_COMPOSER);
366 add_cdtext_disc_info_str("Disc ID (CD-Text)", CDTEXT_DISCID);
367 add_cdtext_disc_info_str("Genre (CD-Text)", CDTEXT_GENRE);
368 add_cdtext_disc_info_str("Message (CD-Text)", CDTEXT_MESSAGE);
369 add_cdtext_disc_info_str("Performer (CD-Text)", CDTEXT_PERFORMER);
370 add_cdtext_disc_info_str("Songwriter (CD-Text)", CDTEXT_SONGWRITER);
371 add_cdtext_disc_info_str("Title (CD-Text)", CDTEXT_TITLE);
373 psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
374 if (psz_field && strlen(psz_field))
375 psz_meta_title = psz_field;
377 psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
378 if (psz_field && strlen(psz_field))
379 psz_meta_artist = psz_field;
382 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
384 char psz_track[TITLE_MAX];
385 const track_t i_track = i_first_track + i;
386 unsigned int i_track_frames =
387 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
388 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
390 mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
391 char *psz_mrl = CDDAFormatMRL( p_access, i_track );
393 snprintf(psz_track, TITLE_MAX, "%s %02d", _("Track"), i_track);
395 input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
397 secstotimestr( psz_buffer, i_duration ) );
399 input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
400 _("MRL"), "%s", psz_mrl );
403 if (p_cdda->p_cdtext[i_track])
405 add_cdtext_info_str( psz_track, "Arranger (CD-Text)",
406 i_track, CDTEXT_ARRANGER);
407 add_cdtext_info_str( psz_track, "Composer (CD-Text)",
408 i_track, CDTEXT_COMPOSER);
409 add_cdtext_info_str( psz_track, "Disc ID (CD-Text)",
410 i_track, CDTEXT_DISCID);
411 add_cdtext_info_str( psz_track, "Genre (CD-Text)",
412 i_track, CDTEXT_GENRE);
413 add_cdtext_info_str( psz_track, "Message (CD-Text)",
414 i_track, CDTEXT_MESSAGE);
415 add_cdtext_info_str( psz_track, "Performer (CD-Text)",
416 i_track, CDTEXT_PERFORMER);
417 add_cdtext_info_str( psz_track, "Songwriter (CD-Text)",
418 i_track, CDTEXT_SONGWRITER);
419 add_cdtext_info_str( psz_track, "Title (CD-Text)",
420 i_track, CDTEXT_TITLE);
424 if (p_cdda->b_cddb_enabled)
426 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i);
429 add_info_str(psz_track, "Artist (CDDB)",
430 cddb_track_get_artist(t));
431 add_info_str(psz_track, "Title (CDDB)",
432 cddb_track_get_title(t));
433 add_info_str(psz_track, "Extended Data (CDDB)",
434 cddb_track_get_ext_data(t));
437 #endif /*HAVE_LIBCDDB*/
440 /* Above we should have set psz_meta_title and psz_meta_artist
441 to CDDB or CD-Text values or the default value depending on
442 availablity and user preferences.
444 So now add the title and artist to VLC's meta, and the name
445 as shown in the status bar and playlist entry.
447 For playlist mode, the meta title is what's seen at the
448 bottom and in the playlist. For nav-mode playing, it is
449 done by input_control. I don't understand why they do
450 different things. In either case, we may have customized to
451 put in the track name.
453 if ( CDIO_INVALID_TRACK != i_track )
455 char *psz_name = CDDAFormatTitle( p_access, i_track ) ;
456 if ( !p_cdda->b_nav_mode ) {
457 add_meta_val( vlc_meta_Title, psz_name );
460 input_Control( p_cdda->p_input, INPUT_SET_NAME, psz_name );
464 add_meta_val( vlc_meta_Artist, psz_meta_artist );
469 #define add_format_str_info(val) \
471 const char *str = val; \
476 strncat(tp, str, TEMP_STR_LEN-(tp-temp_str)); \
479 saw_control_prefix = false; \
483 #define add_format_num_info(val, fmt) \
487 sprintf(num_str, fmt, val); \
488 len=strlen(num_str); \
490 strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); \
493 saw_control_prefix = false; \
498 cdda_data_t *p_cdda, char *psz_cdtext)
500 /* We either don't have CD-Text info, or we do but we prefer to get CDDB
501 which means CDDB has been enabled and we were able to retrieve the info.*/
503 return !psz_cdtext ||
504 (!p_cdda->b_cdtext_prefer && p_cdda->b_cddb_enabled && p_cdda->cddb.disc);
512 Take a format string and expand escape sequences, that is sequences that
513 begin with %, with information from the current CD.
514 The expanded string is returned. Here is a list of escape sequences:
516 %a : The album artist **
517 %A : The album information **
519 %e : The extended track data
523 %m : The CD-DA Media Catalog Number (MCN)
524 %n : The number of tracks on the CD
525 %p : The artist/performer/composer in the track **
526 %T : The track number **
527 %s : Number of seconds in this track, or seconds in CD if invalid track
528 %S : Number of seconds on the CD
529 %t : The track name or MRL if no name
530 %Y : The year 19xx or 20xx **
534 CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
535 const char format_str[], const char *psz_mrl, track_t i_track)
537 #define TEMP_STR_SIZE 256
538 #define TEMP_STR_LEN (TEMP_STR_SIZE-1)
539 static char temp_str[TEMP_STR_SIZE];
541 char * tp = temp_str;
542 bool saw_control_prefix = false;
543 size_t format_len = strlen(format_str);
545 memset(temp_str, 0, TEMP_STR_SIZE);
547 for (i=0; i<format_len; i++)
551 if (!saw_control_prefix && format_str[i] != '%')
553 *tp++ = format_str[i];
554 saw_control_prefix = false;
558 switch(format_str[i])
561 if (saw_control_prefix)
565 saw_control_prefix = !saw_control_prefix;
569 if (p_cdda->p_cdtext[0]
570 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
571 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
572 if (want_cddb_info(p_cdda, psz))
573 psz = (char *)cddb_disc_get_artist(p_cdda->cddb.disc);
576 if (p_cdda->p_cdtext[0]
577 && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
578 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
579 if (want_cddb_info(p_cdda, psz))
580 psz = (char *)cddb_disc_get_title(p_cdda->cddb.disc);
583 if (!p_cdda->b_cddb_enabled) goto not_special;
584 if (p_cdda->cddb.disc)
585 add_format_str_info(CDDB_CATEGORY[cddb_disc_get_category(p_cdda->cddb.disc)]);
588 if (p_cdda->p_cdtext[0]
589 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
590 psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
591 if (want_cddb_info(p_cdda, psz))
592 psz = (char *)cddb_disc_get_genre(p_cdda->cddb.disc);
595 if (p_cdda->p_cdtext[0]
596 && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
597 psz = p_cdda->p_cdtext[0]->field[CDTEXT_DISCID];
598 if (want_cddb_info(p_cdda, psz)) {
599 add_format_num_info(cddb_disc_get_discid(p_cdda->cddb.disc), "%x");
601 add_format_str_info(psz);
604 if (!p_cdda->b_cddb_enabled) goto not_special;
605 if (p_cdda->cddb.disc)
606 add_format_num_info(cddb_disc_get_year(p_cdda->cddb.disc),
610 if ( CDIO_INVALID_TRACK == i_track ) break;
611 if (p_cdda && p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
613 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
615 if (t != NULL && cddb_track_get_title(t) != NULL) {
616 add_format_str_info(cddb_track_get_title(t));
618 add_format_str_info(psz_mrl);
623 if (p_cdda->p_cdtext[i_track]
624 && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE])
626 add_format_str_info(p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE]);
629 add_format_str_info(psz_mrl);
633 if ( CDIO_INVALID_TRACK == i_track ) break;
634 if (p_cdda->p_cdtext[i_track]
635 && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
636 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
637 if (want_cddb_info(p_cdda, psz))
639 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
641 if (t != NULL && cddb_track_get_artist(t) != NULL)
642 psz = (char *)cddb_track_get_artist(t);
646 if ( CDIO_INVALID_TRACK == i_track ) break;
647 if (p_cdda->p_cdtext[i_track]
648 && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
649 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
650 if (want_cddb_info(p_cdda, psz))
652 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
654 if (t != NULL && cddb_track_get_ext_data(t) != NULL)
655 psz = (char *)cddb_track_get_ext_data(t);
661 if (p_cdda->p_cdtext[0]
662 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
663 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
666 if (p_cdda->p_cdtext[0]
667 && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
668 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
671 if (p_cdda->p_cdtext[0]
672 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
673 psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
676 if (p_cdda->p_cdtext[0]
677 && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
678 add_format_str_info(p_cdda->p_cdtext[0]->field[CDTEXT_DISCID]);
681 if ( CDIO_INVALID_TRACK == i_track ) break;
682 if (p_cdda->p_cdtext[i_track]
683 && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
684 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
687 if ( CDIO_INVALID_TRACK == i_track ) break;
688 if (p_cdda->p_cdtext[i_track]
689 && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE])
690 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE];
695 if ( CDIO_INVALID_TRACK == i_track ) break;
696 if (p_cdda->p_cdtext[i_track]
697 && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
698 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
701 #endif /*HAVE_LIBCDDB*/
704 if ( CDIO_INVALID_TRACK != i_track )
706 char psz_buffer[MSTRTIME_MAX_SIZE];
707 unsigned int i_track_frames =
708 cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
710 i_track_frames / CDIO_CD_FRAMES_PER_SEC;
711 add_format_str_info( secstotimestr( psz_buffer,
716 /* Fall through to disc duration if CDIO_INVALID_TRACK */
719 char psz_buffer[MSTRTIME_MAX_SIZE];
720 unsigned int i_track_frames =
721 cdio_get_track_lba(p_cdda->p_cdio,
722 CDIO_CDROM_LEADOUT_TRACK);
724 i_track_frames / CDIO_CD_FRAMES_PER_SEC;
725 add_format_str_info( secstotimestr( psz_buffer,
731 add_format_str_info(psz_mrl);
735 add_format_str_info(p_cdda->psz_mcn);
739 add_format_num_info(p_cdda->i_tracks, "%d");
743 add_format_num_info(i_track, "%02d");
747 add_format_str_info(psz);
754 *tp++ = format_str[i];
755 saw_control_prefix = false;
758 return strdup(temp_str);
761 /* Return a MRL for the given track. The caller must free the
764 CDDAFormatMRL( const access_t *p_access, track_t i_track )
766 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
767 const unsigned int psz_mrl_max = strlen(CDDA_MRL_PREFIX)
768 + strlen(p_cdda->psz_source) +
769 + strlen("@T") + strlen("100") + 1;
770 char *psz_mrl = calloc( 1, psz_mrl_max );
772 if (CDIO_INVALID_TRACK == i_track)
773 snprintf(psz_mrl, psz_mrl_max, "%s%s",
774 CDDA_MRL_PREFIX, p_cdda->psz_source);
776 snprintf(psz_mrl, psz_mrl_max, "%s%s@T%u",
777 CDDA_MRL_PREFIX, p_cdda->psz_source, i_track);
782 /* Return a title string as specified by the titel format string for the
783 given track. The caller must free the allocated string. */
785 CDDAFormatTitle( const access_t *p_access, track_t i_track )
788 const char *config_varname = MODULE_STRING "-title-format";
789 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
790 char *psz_mrl = CDDAFormatMRL( p_access, i_track );
796 if (p_cdda->b_cddb_enabled)
798 config_varname = MODULE_STRING "-cddb-title-format";
800 #endif /*HAVE_LIBCDDB*/
801 char* psz_config_varname = config_GetPsz( p_access, config_varname );
802 psz_name = CDDAFormatStr( p_access, p_cdda, psz_config_varname,
804 free( psz_config_varname );
815 CDDAFixupPlaylist( access_t *p_access, cdda_data_t *p_cdda,
816 bool b_single_track )
819 const track_t i_first_track = p_cdda->i_first_track;
823 p_cdda->b_cddb_enabled =
824 config_GetInt( p_access, MODULE_STRING "-cddb-enabled" );
825 if( b_single_track && !p_cdda->b_cddb_enabled )
832 if( b_single_track || p_cdda->b_nav_mode ) {
833 i_track = p_cdda->i_track;
837 i_track = CDIO_INVALID_TRACK;
839 CDDAMetaInfoInit( p_access );
840 CDDAMetaInfo( p_access, p_cdda->i_track );
842 if( b_single_track && !p_cdda->b_nav_mode )
844 /*May fill out more information when the playlist user interface becomes
847 track_t i_track = p_cdda->i_track;
848 unsigned int i_track_frames =
849 cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
851 input_title_t *t = p_cdda->p_title[0] = //i_track-i_first_track] =
852 vlc_input_title_New();
854 if( asprintf( &t->psz_name, _("Track %i"), i_track ) == -1 )
856 t->i_size = i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
857 t->i_length = INT64_C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
859 p_cdda->i_titles = 1;
860 p_access->info.i_update = INPUT_UPDATE_TITLE;
864 input_thread_t *p_input = (input_thread_t*)vlc_object_find( p_access, VLC_OBJECT_INPUT, FIND_PARENT );
868 input_item_t *p_current = input_GetItem( p_input );
871 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
873 playlist_item_t *p_child;
874 const track_t i_track = i_first_track + i;
875 unsigned int i_track_frames =
876 cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
879 t = p_cdda->p_title[i] = vlc_input_title_New();
881 if( asprintf( &t->psz_name, _("Track %i"), i_track ) == -1 )
883 t->i_size = i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
885 t->i_length = INT64_C(1000000) * t->i_size
886 / CDDA_FREQUENCY_SAMPLE / 4;
888 if( !p_cdda->b_nav_mode )
890 input_item_t *p_child;
891 char *psz_mrl = CDDAFormatMRL( p_access, i_track );
892 char *psz_title = CDDAFormatTitle( p_access, i_track );
893 unsigned int i_track_frames =
894 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
895 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
896 mtime_t i_mduration = i_track_frames * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) ;
898 p_child = input_item_NewWithType( VLC_OBJECT( p_access ),
899 psz_mrl, psz_title, 0, NULL, 0, i_mduration,
903 input_item_CopyOptions( p_current, p_child );
905 input_item_AddSubItem( p_current, p_child );
907 vlc_gc_decref( p_child );
914 p_cdda->i_titles = p_cdda->i_tracks;
915 p_access->info.i_update |= INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE;
918 input_item_SetDuration( p_current,
919 (mtime_t) p_access->info.i_size * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) );
920 input_item_SetURI( p_current, CDDAFormatMRL( p_access, p_cdda->i_track ) );
923 vlc_object_release( p_input );