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 #include <cdio/cdio.h>
31 #include <cdio/cdtext.h>
32 #include <cdio/logging.h>
33 #include <cdio/cd_types.h>
39 static char *CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
40 const char format_str[], const char *psz_mrl,
43 static char *CDDAFormatMRL( const access_t *p_access, track_t i_track );
47 #define free_and_dup(var, val) \
49 if (val) var = strdup( val );
52 /* Saves CDDB information about CD-DA via libcddb. */
54 GetCDDBInfo( access_t *p_access, cdda_data_t *p_cdda )
57 cddb_conn_t *conn = cddb_new();
58 const CdIo_t *p_cdio = p_cdda->p_cdio;
60 dbg_print( (INPUT_DBG_CALL), "" );
63 cddb_log_set_handler (uninit_log_handler);
68 msg_Warn( p_access, "Unable to initialize libcddb" );
72 char* psz_email = var_InheritString( p_access, MODULE_STRING "-cddb-email");
75 cddb_set_email_address( conn, psz_email );
79 char* psz_srv_name = var_InheritString( p_access, MODULE_STRING "-cddb-server");
82 cddb_set_server_name( conn, psz_srv_name );
85 cddb_set_server_port(conn,
86 var_InheritInteger( p_access,
87 MODULE_STRING "-cddb-port") );
89 /* Set the location of the local CDDB cache directory.
90 The default location of this directory is */
92 if (!var_InheritInteger( p_access, MODULE_STRING "-cddb-enable-cache" ))
93 cddb_cache_disable(conn);
95 char* psz_cache = var_InheritString( p_access, MODULE_STRING "-cddb-cachedir");
98 cddb_cache_set_dir(conn, psz_cache );
102 cddb_set_timeout(conn,
103 var_InheritInteger( p_access, MODULE_STRING "-cddb-timeout") );
106 if (var_InheritInteger( p_access, MODULE_STRING "-cddb-httpd" ) )
107 cddb_http_enable(conn);
109 cddb_http_disable(conn);
111 p_cdda->cddb.disc = cddb_disc_new();
113 if (!p_cdda->cddb.disc)
115 msg_Err( p_access, "Unable to create CDDB disc structure." );
119 for(i = 0; i < p_cdda->i_tracks; i++)
121 track_t i_track = p_cdda->i_first_track + i;
122 cddb_track_t *t = cddb_track_new();
123 cddb_track_set_frame_offset(t,
124 cdio_get_track_lba(p_cdio, i_track));
125 cddb_disc_add_track(p_cdda->cddb.disc, t);
128 cddb_disc_set_length(p_cdda->cddb.disc,
129 cdio_get_track_lba(p_cdio, CDIO_CDROM_LEADOUT_TRACK)
130 / CDIO_CD_FRAMES_PER_SEC);
132 if (!cddb_disc_calc_discid(p_cdda->cddb.disc))
134 msg_Err( p_access, "CDDB disc ID calculation failed" );
138 i_matches = cddb_query(conn, p_cdda->cddb.disc);
143 msg_Warn( p_access, "Found %d matches in CDDB. Using first one.",
145 cddb_read(conn, p_cdda->cddb.disc);
147 if (p_cdda->i_debug & INPUT_DBG_CDDB)
148 cddb_disc_print(p_cdda->cddb.disc);
153 msg_Warn( p_access, "CDDB error: %s", cddb_error_str(errno));
161 #endif /*HAVE_LIBCDDB*/
163 static inline void add_meta_val(access_t *p_access, vlc_meta_type_t meta, const char * val)
165 cdda_data_t *p_cdda = (cdda_data_t *)p_access->p_sys;
166 if (p_cdda->p_meta && val)
167 dbg_print( INPUT_DBG_META, "field %s: %s\n", input_MetaTypeToLocalizedString(meta), val);
170 #define add_cddb_meta(FIELD, VLC_META) \
171 add_meta_val(p_access, VLC_META, cddb_disc_get_##FIELD(p_cdda->cddb.disc));
173 #define add_cddb_meta_fmt(FIELD, FORMAT_SPEC, VLC_META) \
176 snprintf( psz_buf, sizeof(psz_buf)-1, FORMAT_SPEC, \
177 cddb_disc_get_##FIELD(p_cdda->cddb.disc)); \
178 psz_buf[sizeof(psz_buf)-1] = '\0'; \
179 add_meta_val(p_access, VLC_META, psz_buf); \
182 /* Adds a string-valued entry to the stream and media information if
183 the string is not null or the null string.
185 #define add_info_str(CATEGORY, TITLE, FIELD) \
186 if (FIELD && strlen(FIELD)) { \
187 input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY, \
188 _(TITLE), "%s", FIELD ); \
191 /* Adds a numeric-valued entry to the stream and media information
192 if the number is not zero. */
193 #define add_info_val(CATEGORY, TITLE, FMT, FIELD) \
195 input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY, \
196 _(TITLE), FMT, FIELD ); \
199 /* Adds a CDDB string-valued entry to the stream and media information
200 under category "Disc" if the string is not null or the null string.
202 #define add_cddb_disc_info_str(TITLE, FIELD) \
203 add_info_str("Disc", TITLE, cddb_disc_get_##FIELD(p_cdda->cddb.disc))
205 /* Adds a CDDB numeric-valued entry to the stream and media information
206 under category "Disc" if the string is not null or the null string.
208 #define add_cddb_disc_info_val(TITLE, FMT, FIELD) \
209 add_info_val("Disc", TITLE, FMT, cddb_disc_get_##FIELD(p_cdda->cddb.disc))
211 /* Adds a CD-Text string-valued entry to the stream and media information
212 under category "Disc" if the string is not null or the null string.
214 #define add_cdtext_info_str(CATEGORY, TITLE, INDEX, FIELD) \
215 add_info_str(CATEGORY, TITLE, p_cdda->p_cdtext[INDEX]->field[FIELD])
217 /* Adds a CD-Text string-valued entry to the stream and media information
218 under category "Disc" if the string is not null or the null string.
220 #define add_cdtext_disc_info_str(TITLE, FIELD) \
221 add_cdtext_info_str("Disc", TITLE, 0, FIELD)
225 Saves Meta Information about the CD-DA.
227 Meta information used in "stream and media info" or in playlist
228 info. The intialization of CD-Text or CDDB is done here though.
229 Therefore, this should be called before CDDAMetaInfo is called.
233 CDDAMetaInfoInit( access_t *p_access )
235 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
237 if ( ! p_cdda ) return;
239 dbg_print( (INPUT_DBG_CALL), "p_cdda->i_tracks %d",
242 p_cdda->psz_mcn = cdio_get_mcn(p_cdda->p_cdio);
244 p_cdda->p_meta = vlc_meta_New();
248 if ( p_cdda->b_cddb_enabled )
250 GetCDDBInfo(p_access, p_cdda);
253 #endif /*HAVE_LIBCDDB*/
259 for( i_track = 0 ; i_track < p_cdda->i_tracks ; i_track++ )
261 p_cdda->p_cdtext[i_track] =
262 cdio_get_cdtext(p_cdda->p_cdio, i_track);
268 In the Control routine, we handle Meta Information requests and
269 basically copy what was saved in CDDAMetaInfoInit.
271 If i_track is CDIO_INVALID_TRACK we are probably asking about the entire
275 CDDAMetaInfo( access_t *p_access, track_t i_track )
277 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
278 char *psz_meta_title = CDDAFormatMRL( p_access, i_track );
279 char *psz_meta_artist = NULL;
281 if ( ! p_cdda ) return;
283 dbg_print( (INPUT_DBG_CALL), "i_track %d", i_track );
287 /* Set up for Meta and name for CDDB access. */
288 if ( p_cdda->b_cddb_enabled && p_cdda->cddb.disc )
290 if( CDIO_INVALID_TRACK == i_track )
293 psz_meta_title = (char *)cddb_disc_get_title(p_cdda->cddb.disc);
294 psz_meta_artist = (char *)cddb_disc_get_artist(p_cdda->cddb.disc);
295 if ( cddb_disc_get_genre(p_cdda->cddb.disc) &&
296 strlen(cddb_disc_get_genre(p_cdda->cddb.disc)) )
297 add_cddb_meta(genre, vlc_meta_Genre);
298 if ( 0 != cddb_disc_get_year(p_cdda->cddb.disc))
299 add_cddb_meta_fmt(year, "%d", vlc_meta_Date );
303 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i_track-1);
306 if( cddb_track_get_title(t) != NULL && ! p_cdda->b_nav_mode )
308 add_meta_val( p_access, vlc_meta_Title, cddb_track_get_title(t) );
310 if( cddb_track_get_artist(t) != NULL )
312 add_meta_val( p_access, vlc_meta_Artist, cddb_track_get_artist(t) );
317 #endif /*HAVE_LIBCDDB*/
321 track_t i = p_cdda->i_tracks;
322 const int i_first_track = p_cdda->i_first_track;
323 char psz_buffer[MSTRTIME_MAX_SIZE];
324 unsigned int i_track_frames =
325 cdio_get_track_lba(p_cdda->p_cdio, CDIO_CDROM_LEADOUT_TRACK);
327 mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
329 dbg_print( INPUT_DBG_META, "Duration %ld, tracks %d",
330 (long int) i_duration, p_cdda->i_tracks );
331 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
332 _("Disc"), _("Duration"), "%s",
333 secstotimestr( psz_buffer, i_duration ) );
337 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
338 _("Disc"), _("Media Catalog Number (MCN)"), "%s",
340 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
341 _("Disc"), _("Tracks"), "%d", p_cdda->i_tracks );
345 if (p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
347 add_cddb_disc_info_str("Artist (CDDB)", artist);
348 if ( CDDB_CAT_INVALID != cddb_disc_get_category(p_cdda->cddb.disc) )
349 add_info_str("Disc", "Category (CDDB)",
350 CDDB_CATEGORY[cddb_disc_get_category(p_cdda->cddb.disc)]);
351 add_cddb_disc_info_val("Disc ID (CDDB)", "%x", discid);
352 add_cddb_disc_info_str("Extended Data (CDDB)", ext_data);
353 add_cddb_disc_info_str("Genre (CDDB)", genre);
354 add_cddb_disc_info_str("Title (CDDB)", title);
355 if ( 0 != cddb_disc_get_year(p_cdda->cddb.disc) )
356 add_cddb_disc_info_val("Year (CDDB)", "%d", year);
359 #endif /*HAVE_LIBCDDB*/
361 if (p_cdda->p_cdtext[0])
365 add_cdtext_disc_info_str("Arranger (CD-Text)", CDTEXT_ARRANGER);
366 add_cdtext_disc_info_str("Composer (CD-Text)", CDTEXT_COMPOSER);
367 add_cdtext_disc_info_str("Disc ID (CD-Text)", CDTEXT_DISCID);
368 add_cdtext_disc_info_str("Genre (CD-Text)", CDTEXT_GENRE);
369 add_cdtext_disc_info_str("Message (CD-Text)", CDTEXT_MESSAGE);
370 add_cdtext_disc_info_str("Performer (CD-Text)", CDTEXT_PERFORMER);
371 add_cdtext_disc_info_str("Songwriter (CD-Text)", CDTEXT_SONGWRITER);
372 add_cdtext_disc_info_str("Title (CD-Text)", CDTEXT_TITLE);
374 psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
375 if (psz_field && strlen(psz_field))
376 psz_meta_title = psz_field;
378 psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
379 if (psz_field && strlen(psz_field))
380 psz_meta_artist = psz_field;
383 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
385 char psz_track[TITLE_MAX];
386 const track_t i_track = i_first_track + i;
387 unsigned int i_track_frames =
388 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
389 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
391 mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
392 char *psz_mrl = CDDAFormatMRL( p_access, i_track );
394 snprintf(psz_track, TITLE_MAX, "%s %02d", _("Track"), i_track);
396 input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
398 secstotimestr( psz_buffer, i_duration ) );
400 input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
401 _("MRL"), "%s", psz_mrl );
404 if (p_cdda->p_cdtext[i_track])
406 add_cdtext_info_str( psz_track, "Arranger (CD-Text)",
407 i_track, CDTEXT_ARRANGER);
408 add_cdtext_info_str( psz_track, "Composer (CD-Text)",
409 i_track, CDTEXT_COMPOSER);
410 add_cdtext_info_str( psz_track, "Disc ID (CD-Text)",
411 i_track, CDTEXT_DISCID);
412 add_cdtext_info_str( psz_track, "Genre (CD-Text)",
413 i_track, CDTEXT_GENRE);
414 add_cdtext_info_str( psz_track, "Message (CD-Text)",
415 i_track, CDTEXT_MESSAGE);
416 add_cdtext_info_str( psz_track, "Performer (CD-Text)",
417 i_track, CDTEXT_PERFORMER);
418 add_cdtext_info_str( psz_track, "Songwriter (CD-Text)",
419 i_track, CDTEXT_SONGWRITER);
420 add_cdtext_info_str( psz_track, "Title (CD-Text)",
421 i_track, CDTEXT_TITLE);
425 if (p_cdda->b_cddb_enabled)
427 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i);
430 add_info_str(psz_track, "Artist (CDDB)",
431 cddb_track_get_artist(t));
432 add_info_str(psz_track, "Title (CDDB)",
433 cddb_track_get_title(t));
434 add_info_str(psz_track, "Extended Data (CDDB)",
435 cddb_track_get_ext_data(t));
438 #endif /*HAVE_LIBCDDB*/
441 /* Above we should have set psz_meta_title and psz_meta_artist
442 to CDDB or CD-Text values or the default value depending on
443 availablity and user preferences.
445 So now add the title and artist to VLC's meta, and the name
446 as shown in the status bar and playlist entry.
448 For playlist mode, the meta title is what's seen at the
449 bottom and in the playlist. For nav-mode playing, it is
450 done by input_control. I don't understand why they do
451 different things. In either case, we may have customized to
452 put in the track name.
454 if ( CDIO_INVALID_TRACK != i_track )
456 char *psz_name = CDDAFormatTitle( p_access, i_track ) ;
457 if ( !p_cdda->b_nav_mode ) {
458 add_meta_val( p_access, vlc_meta_Title, psz_name );
461 input_Control( p_cdda->p_input, INPUT_SET_NAME, psz_name );
465 add_meta_val( p_access, vlc_meta_Artist, psz_meta_artist );
470 #define add_format_str_info(val) \
472 const char *str = val; \
477 strncat(tp, str, TEMP_STR_LEN-(tp-temp_str)); \
480 saw_control_prefix = false; \
484 #define add_format_num_info(val, fmt) \
488 sprintf(num_str, fmt, val); \
489 len=strlen(num_str); \
491 strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); \
494 saw_control_prefix = false; \
499 cdda_data_t *p_cdda, char *psz_cdtext)
501 /* We either don't have CD-Text info, or we do but we prefer to get CDDB
502 which means CDDB has been enabled and we were able to retrieve the info.*/
504 return !psz_cdtext ||
505 (!p_cdda->b_cdtext_prefer && p_cdda->b_cddb_enabled && p_cdda->cddb.disc);
513 Take a format string and expand escape sequences, that is sequences that
514 begin with %, with information from the current CD.
515 The expanded string is returned. Here is a list of escape sequences:
517 %a : The album artist **
518 %A : The album information **
520 %e : The extended track data
524 %m : The CD-DA Media Catalog Number (MCN)
525 %n : The number of tracks on the CD
526 %p : The artist/performer/composer in the track **
527 %T : The track number **
528 %s : Number of seconds in this track, or seconds in CD if invalid track
529 %S : Number of seconds on the CD
530 %t : The track name or MRL if no name
531 %Y : The year 19xx or 20xx **
535 CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
536 const char format_str[], const char *psz_mrl, track_t i_track)
538 VLC_UNUSED(p_access);
539 #define TEMP_STR_SIZE 256
540 #define TEMP_STR_LEN (TEMP_STR_SIZE-1)
541 static char temp_str[TEMP_STR_SIZE];
543 char * tp = temp_str;
544 bool saw_control_prefix = false;
545 size_t format_len = strlen(format_str);
547 memset(temp_str, 0, TEMP_STR_SIZE);
549 for (i=0; i<format_len; i++)
553 if (!saw_control_prefix && format_str[i] != '%')
555 *tp++ = format_str[i];
556 saw_control_prefix = false;
560 switch(format_str[i])
563 if (saw_control_prefix)
567 saw_control_prefix = !saw_control_prefix;
571 if (p_cdda->p_cdtext[0]
572 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
573 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
574 if (want_cddb_info(p_cdda, psz))
575 psz = (char *)cddb_disc_get_artist(p_cdda->cddb.disc);
578 if (p_cdda->p_cdtext[0]
579 && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
580 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
581 if (want_cddb_info(p_cdda, psz))
582 psz = (char *)cddb_disc_get_title(p_cdda->cddb.disc);
585 if (!p_cdda->b_cddb_enabled) goto not_special;
586 if (p_cdda->cddb.disc)
587 add_format_str_info(CDDB_CATEGORY[cddb_disc_get_category(p_cdda->cddb.disc)]);
590 if (p_cdda->p_cdtext[0]
591 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
592 psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
593 if (want_cddb_info(p_cdda, psz))
594 psz = (char *)cddb_disc_get_genre(p_cdda->cddb.disc);
597 if (p_cdda->p_cdtext[0]
598 && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
599 psz = p_cdda->p_cdtext[0]->field[CDTEXT_DISCID];
600 if (want_cddb_info(p_cdda, psz)) {
601 add_format_num_info(cddb_disc_get_discid(p_cdda->cddb.disc), "%x");
603 add_format_str_info(psz);
606 if (!p_cdda->b_cddb_enabled) goto not_special;
607 if (p_cdda->cddb.disc)
608 add_format_num_info(cddb_disc_get_year(p_cdda->cddb.disc),
612 if ( CDIO_INVALID_TRACK == i_track ) break;
613 if (p_cdda && p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
615 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
617 if (t != NULL && cddb_track_get_title(t) != NULL) {
618 add_format_str_info(cddb_track_get_title(t));
620 add_format_str_info(psz_mrl);
625 if (p_cdda->p_cdtext[i_track]
626 && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE])
628 add_format_str_info(p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE]);
631 add_format_str_info(psz_mrl);
635 if ( CDIO_INVALID_TRACK == i_track ) break;
636 if (p_cdda->p_cdtext[i_track]
637 && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
638 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
639 if (want_cddb_info(p_cdda, psz))
641 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
643 if (t != NULL && cddb_track_get_artist(t) != NULL)
644 psz = (char *)cddb_track_get_artist(t);
648 if ( CDIO_INVALID_TRACK == i_track ) break;
649 if (p_cdda->p_cdtext[i_track]
650 && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
651 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
652 if (want_cddb_info(p_cdda, psz))
654 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
656 if (t != NULL && cddb_track_get_ext_data(t) != NULL)
657 psz = (char *)cddb_track_get_ext_data(t);
663 if (p_cdda->p_cdtext[0]
664 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
665 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
668 if (p_cdda->p_cdtext[0]
669 && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
670 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
673 if (p_cdda->p_cdtext[0]
674 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
675 psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
678 if (p_cdda->p_cdtext[0]
679 && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
680 add_format_str_info(p_cdda->p_cdtext[0]->field[CDTEXT_DISCID]);
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_PERFORMER])
686 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
689 if ( CDIO_INVALID_TRACK == i_track ) break;
690 if (p_cdda->p_cdtext[i_track]
691 && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE])
692 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE];
697 if ( CDIO_INVALID_TRACK == i_track ) break;
698 if (p_cdda->p_cdtext[i_track]
699 && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
700 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
703 #endif /*HAVE_LIBCDDB*/
706 if ( CDIO_INVALID_TRACK != i_track )
708 char psz_buffer[MSTRTIME_MAX_SIZE];
709 unsigned int i_track_frames =
710 cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
712 i_track_frames / CDIO_CD_FRAMES_PER_SEC;
713 add_format_str_info( secstotimestr( psz_buffer,
718 /* Fall through to disc duration if CDIO_INVALID_TRACK */
721 char psz_buffer[MSTRTIME_MAX_SIZE];
722 unsigned int i_track_frames =
723 cdio_get_track_lba(p_cdda->p_cdio,
724 CDIO_CDROM_LEADOUT_TRACK);
726 i_track_frames / CDIO_CD_FRAMES_PER_SEC;
727 add_format_str_info( secstotimestr( psz_buffer,
733 add_format_str_info(psz_mrl);
737 add_format_str_info(p_cdda->psz_mcn);
741 add_format_num_info(p_cdda->i_tracks, "%d");
745 add_format_num_info(i_track, "%02d");
749 add_format_str_info(psz);
756 *tp++ = format_str[i];
757 saw_control_prefix = false;
760 return strdup(temp_str);
763 /* Return a MRL for the given track. The caller must free the
766 CDDAFormatMRL( const access_t *p_access, track_t i_track )
768 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
769 const unsigned int psz_mrl_max = strlen(CDDA_MRL_PREFIX)
770 + strlen(p_cdda->psz_source) +
771 + strlen("@T") + strlen("100") + 1;
772 char *psz_mrl = calloc( 1, psz_mrl_max );
774 if (CDIO_INVALID_TRACK == i_track)
775 snprintf(psz_mrl, psz_mrl_max, "%s%s",
776 CDDA_MRL_PREFIX, p_cdda->psz_source);
778 snprintf(psz_mrl, psz_mrl_max, "%s%s@T%u",
779 CDDA_MRL_PREFIX, p_cdda->psz_source, i_track);
784 /* Return a title string as specified by the titel format string for the
785 given track. The caller must free the allocated string. */
787 CDDAFormatTitle( const access_t *p_access, track_t i_track )
790 const char *config_varname = MODULE_STRING "-title-format";
791 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
792 char *psz_mrl = CDDAFormatMRL( p_access, i_track );
798 if (p_cdda->b_cddb_enabled)
800 config_varname = MODULE_STRING "-cddb-title-format";
802 #endif /*HAVE_LIBCDDB*/
803 char* psz_config_varname = var_InheritString( p_access, config_varname );
804 if( psz_config_varname )
806 psz_name = CDDAFormatStr( p_access, p_cdda, psz_config_varname,
808 free( psz_config_varname );
820 CDDAFixupPlaylist( access_t *p_access, cdda_data_t *p_cdda,
821 bool b_single_track )
824 const track_t i_first_track = p_cdda->i_first_track;
828 p_cdda->b_cddb_enabled =
829 var_InheritInteger( p_access, MODULE_STRING "-cddb-enabled" );
830 if( b_single_track && !p_cdda->b_cddb_enabled )
837 if( b_single_track || p_cdda->b_nav_mode ) {
838 i_track = p_cdda->i_track;
842 i_track = CDIO_INVALID_TRACK;
844 CDDAMetaInfoInit( p_access );
845 CDDAMetaInfo( p_access, p_cdda->i_track );
847 if( b_single_track && !p_cdda->b_nav_mode )
849 /*May fill out more information when the playlist user interface becomes
852 track_t i_track = p_cdda->i_track;
853 unsigned int i_track_frames =
854 cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
856 input_title_t *t = p_cdda->p_title[0] = //i_track-i_first_track] =
857 vlc_input_title_New();
859 if( asprintf( &t->psz_name, _("Track %i"), i_track ) == -1 )
861 t->i_size = i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
862 t->i_length = INT64_C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
864 p_cdda->i_titles = 1;
865 p_access->info.i_update = INPUT_UPDATE_TITLE;
869 input_thread_t *p_input = access_GetParentInput( p_access );
873 input_item_t *p_current = input_GetItem( p_input );
876 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
878 const track_t i_track = i_first_track + i;
879 unsigned int i_track_frames =
880 cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
883 t = p_cdda->p_title[i] = vlc_input_title_New();
885 if( asprintf( &t->psz_name, _("Track %i"), i_track ) == -1 )
887 t->i_size = i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
889 t->i_length = INT64_C(1000000) * t->i_size
890 / CDDA_FREQUENCY_SAMPLE / 4;
892 if( !p_cdda->b_nav_mode )
894 input_item_t *p_child;
895 char *psz_mrl = CDDAFormatMRL( p_access, i_track );
896 char *psz_title = CDDAFormatTitle( p_access, i_track );
897 unsigned int i_track_frames =
898 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
899 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
900 mtime_t i_mduration = i_track_frames * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) ;
902 p_child = input_item_NewWithType( VLC_OBJECT( p_access ),
903 psz_mrl, psz_title, 0, NULL, 0, i_mduration,
907 input_item_CopyOptions( p_current, p_child );
909 input_item_AddSubItem( p_current, p_child );
911 vlc_gc_decref( p_child );
918 p_cdda->i_titles = p_cdda->i_tracks;
919 p_access->info.i_update |= INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE;
922 input_item_SetDuration( p_current,
923 (mtime_t) p_access->info.i_size * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) );
924 input_item_SetURI( p_current, CDDAFormatMRL( p_access, p_cdda->i_track ) );
927 vlc_object_release( p_input );