1 /*****************************************************************************
2 * info.c : CD digital audio input information routines
3 *****************************************************************************
4 * Copyright (C) 2004 VideoLAN
5 * $Id: info.c 8845 2004-09-29 09:00:41Z rocky $
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., 59 Temple Place - Suite 330, Boston, MA 02111, 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 *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 t->frame_offset = cdio_get_track_lba(p_cdio, i_track);
120 cddb_disc_add_track(p_cdda->cddb.disc, t);
123 p_cdda->cddb.disc->length =
124 cdio_get_track_lba(p_cdio, CDIO_CDROM_LEADOUT_TRACK)
125 / CDIO_CD_FRAMES_PER_SEC;
127 if (!cddb_disc_calc_discid(p_cdda->cddb.disc))
129 msg_Err( p_access, "CDDB disc ID calculation failed" );
133 i_matches = cddb_query(conn, p_cdda->cddb.disc);
138 msg_Warn( p_access, "Found %d matches in CDDB. Using first one.",
140 cddb_read(conn, p_cdda->cddb.disc);
142 if (p_cdda->i_debug & INPUT_DBG_CDDB)
143 cddb_disc_print(p_cdda->cddb.disc);
148 msg_Warn( p_access, "CDDB error: %s", cddb_error_str(errno));
156 #endif /*HAVE_LIBCDDB*/
158 #define add_meta_val(VLC_META, VAL) \
159 if ( p_cdda->p_meta && VAL) { \
160 vlc_meta_Add( p_cdda->p_meta, VLC_META, VAL ); \
161 dbg_print( INPUT_DBG_META, "field %s: %s\n", VLC_META, VAL ); \
164 #define add_cddb_meta(FIELD, VLC_META) \
165 add_meta_val(VLC_META, p_cdda->cddb.disc->FIELD);
167 #define add_cddb_meta_fmt(FIELD, FORMAT_SPEC, VLC_META) \
170 snprintf( psz_buf, sizeof(psz_buf)-1, FORMAT_SPEC, \
171 p_cdda->cddb.disc->FIELD ); \
172 psz_buf[sizeof(psz_buf)-1] = '\0'; \
173 add_meta_val(VLC_META, psz_buf); \
176 /* Adds a string-valued entry to the stream and media information if
177 the string is not null or the null string.
179 #define add_info_str(CATEGORY, TITLE, FIELD) \
180 if (FIELD && strlen(FIELD)) { \
181 input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY, \
182 _(TITLE), "%s", FIELD ); \
185 /* Adds a numeric-valued entry to the stream and media information
186 if the number is not zero. */
187 #define add_info_val(CATEGORY, TITLE, FMT, FIELD) \
189 input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY, \
190 _(TITLE), FMT, FIELD ); \
193 /* Adds a CDDB string-valued entry to the stream and media information
194 under category "Disc" if the string is not null or the null string.
196 #define add_cddb_disc_info_str(TITLE, FIELD) \
197 add_info_str("Disc", TITLE, p_cdda->cddb.disc->FIELD)
199 /* Adds a CDDB numeric-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_val(TITLE, FMT, FIELD) \
203 add_info_val("Disc", TITLE, FMT, p_cdda->cddb.disc->FIELD)
205 /* Adds a CD-Text string-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_cdtext_info_str(CATEGORY, TITLE, INDEX, FIELD) \
209 add_info_str(CATEGORY, TITLE, p_cdda->p_cdtext[INDEX]->field[FIELD])
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_disc_info_str(TITLE, FIELD) \
215 add_cdtext_info_str("Disc", TITLE, 0, FIELD)
219 Saves Meta Information about the CD-DA.
221 Meta information used in "stream and media info" or in playlist
222 info. The intialization of CD-Text or CDDB is done here though.
223 Therefore, this should be called before CDDAMetaInfo is called.
227 CDDAMetaInfoInit( access_t *p_access )
229 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
231 if ( ! p_cdda ) return;
233 p_cdda->psz_mcn = cdio_get_mcn(p_cdda->p_cdio);
234 p_cdda->p_meta = vlc_meta_New();
237 if ( p_cdda->b_cddb_enabled )
239 GetCDDBInfo(p_access, p_cdda);
242 #endif /*HAVE_LIBCDDB*/
248 for( i_track = 0 ; i_track < p_cdda->i_tracks ; i_track++ )
250 p_cdda->p_cdtext[i_track] =
251 cdio_get_cdtext(p_cdda->p_cdio, i_track);
257 In the Control routine, we handle Meta Information requests and
258 basically copy what was saved in CDDAMetaInfoInit.
260 If i_track is CDIO_INVALID_TRACK we are probably asking about the entire
264 CDDAMetaInfo( access_t *p_access, track_t i_track )
266 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
267 char *psz_meta_title = CDDAFormatMRL( p_access, i_track );
268 char *psz_meta_artist = NULL;
270 if ( ! p_cdda ) return;
274 /* Set up for Meta and name for CDDB access. */
275 if ( p_cdda->b_cddb_enabled && p_cdda->cddb.disc )
277 if( CDIO_INVALID_TRACK == i_track )
280 psz_meta_title = p_cdda->cddb.disc->title;
281 psz_meta_artist = p_cdda->cddb.disc->artist;
282 if ( p_cdda->cddb.disc->genre && strlen(p_cdda->cddb.disc->genre) )
283 add_cddb_meta(genre, VLC_META_GENRE);
284 if ( 0 != p_cdda->cddb.disc->year )
285 add_cddb_meta_fmt(year, "%d", VLC_META_DATE );
289 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i_track-1);
292 if( t->title != NULL )
294 add_meta_val( VLC_META_TITLE, t->title );
296 if( t->artist != NULL )
298 add_meta_val( VLC_META_ARTIST, t->artist );
304 #endif /*HAVE_LIBCDDB*/
308 track_t i = p_cdda->i_tracks;
309 const int i_first_track = p_cdda->i_first_track;
310 char psz_buffer[MSTRTIME_MAX_SIZE];
311 unsigned int i_track_frames =
312 cdio_get_track_lba(p_cdda->p_cdio, CDIO_CDROM_LEADOUT_TRACK);
314 mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
316 dbg_print( INPUT_DBG_META, "Duration %ld, tracks %d",
317 (long int) i_duration, p_cdda->i_tracks );
318 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
319 _("Disc"), _("Duration"), "%s",
320 secstotimestr( psz_buffer, i_duration ) );
322 if (p_cdda->psz_mcn) {
323 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
324 _("Disc"), _("Media Catalog Number (MCN)"), "%s",
327 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
328 _("Disc"), _("Tracks"), "%d", p_cdda->i_tracks );
333 if (p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
335 add_cddb_disc_info_str("Artist (CDDB)", artist);
336 if ( CDDB_CAT_INVALID != p_cdda->cddb.disc->category )
337 add_info_str("Disc", "Category (CDDB)",
338 CDDB_CATEGORY[p_cdda->cddb.disc->category]);
339 add_cddb_disc_info_val("Disc ID (CDDB)", "%x", discid);
340 add_cddb_disc_info_str("Extended Data (CDDB)", ext_data);
341 add_cddb_disc_info_str("Genre (CDDB)", genre);
342 add_cddb_disc_info_str("Title (CDDB)", title);
343 if ( 0 != p_cdda->cddb.disc->year )
344 add_cddb_disc_info_val("Year (CDDB)", "%d", year);
347 #endif /*HAVE_LIBCDDB*/
349 if (p_cdda->p_cdtext[0])
353 add_cdtext_disc_info_str("Arranger (CD-Text)", CDTEXT_ARRANGER);
354 add_cdtext_disc_info_str("Composer (CD-Text)", CDTEXT_COMPOSER);
355 add_cdtext_disc_info_str("Disc ID (CD-Text)", CDTEXT_DISCID);
356 add_cdtext_disc_info_str("Genre (CD-Text)", CDTEXT_GENRE);
357 add_cdtext_disc_info_str("Message (CD-Text)", CDTEXT_MESSAGE);
358 add_cdtext_disc_info_str("Performer (CD-Text)", CDTEXT_PERFORMER);
359 add_cdtext_disc_info_str("Songwriter (CD-Text)", CDTEXT_SONGWRITER);
360 add_cdtext_disc_info_str("Title (CD-Text)", CDTEXT_TITLE);
362 psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
363 if (psz_field && strlen(psz_field)) {
364 psz_meta_title = psz_field;
366 psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
367 if (psz_field && strlen(psz_field)) {
368 psz_meta_artist = psz_field;
373 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
375 char psz_track[TITLE_MAX];
376 const track_t i_track = i_first_track + i;
377 unsigned int i_track_frames =
378 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
379 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
381 mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
382 char *psz_mrl = CDDAFormatMRL( p_access, i_track );
384 snprintf(psz_track, TITLE_MAX, "%s %02d", _("Track"), i_track);
386 input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
388 secstotimestr( psz_buffer, i_duration ) );
390 input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
391 _("MRL"), "%s", psz_mrl );
394 if (p_cdda->p_cdtext[i_track])
396 add_cdtext_info_str( psz_track, "Arranger (CD-Text)",
397 i_track, CDTEXT_ARRANGER);
398 add_cdtext_info_str( psz_track, "Composer (CD-Text)",
399 i_track, CDTEXT_COMPOSER);
400 add_cdtext_info_str( psz_track, "Disc ID (CD-Text)",
401 i_track, CDTEXT_DISCID);
402 add_cdtext_info_str( psz_track, "Genre (CD-Text)",
403 i_track, CDTEXT_GENRE);
404 add_cdtext_info_str( psz_track, "Message (CD-Text)",
405 i_track, CDTEXT_MESSAGE);
406 add_cdtext_info_str( psz_track, "Performer (CD-Text)",
407 i_track, CDTEXT_PERFORMER);
408 add_cdtext_info_str( psz_track, "Songwriter (CD-Text)",
409 i_track, CDTEXT_SONGWRITER);
410 add_cdtext_info_str( psz_track, "Title (CD-Text)",
411 i_track, CDTEXT_TITLE);
415 if (p_cdda->b_cddb_enabled)
417 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i);
420 add_info_str(psz_track, "Artist (CDDB)", t->artist);
421 add_info_str(psz_track, "Title (CDDB)", t->title);
422 add_info_str(psz_track, "Extended Data (CDDB)",
426 #endif /*HAVE_LIBCDDB*/
429 /* Above we should have set psz_meta_title and psz_meta_artist
430 to CDDB or CD-Text values or the default value depending on
431 availablity and user preferences.
433 So now add the title and artist to VLC's meta, and the
434 name as shown in the status bar and playlist entry.
436 add_meta_val( VLC_META_TITLE, psz_meta_title );
438 add_meta_val( VLC_META_ARTIST, psz_meta_artist );
440 if ( CDIO_INVALID_TRACK != i_track )
442 char *psz_name = CDDAFormatTitle( p_access, i_track ) ;
443 input_Control( p_cdda->p_input, INPUT_SET_NAME, psz_name );
449 #define add_format_str_info(val) \
451 const char *str = val; \
456 strncat(tp, str, TEMP_STR_LEN-(tp-temp_str)); \
459 saw_control_prefix = false; \
463 #define add_format_num_info(val, fmt) \
467 sprintf(num_str, fmt, val); \
468 len=strlen(num_str); \
470 strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); \
473 saw_control_prefix = false; \
478 cdda_data_t *p_cdda, char *psz_cdtext)
480 /* We either don't have CD-Text info, or we do but we prefer to get CDDB
481 which means CDDB has been enabled and we were able to retrieve the info.*/
483 return !psz_cdtext ||
484 (!p_cdda->b_cdtext_prefer && p_cdda->b_cddb_enabled && p_cdda->cddb.disc);
492 Take a format string and expand escape sequences, that is sequences that
493 begin with %, with information from the current CD.
494 The expanded string is returned. Here is a list of escape sequences:
496 %a : The album artist **
497 %A : The album information **
499 %e : The extended track data
503 %m : The CD-DA Media Catalog Number (MCN)
504 %n : The number of tracks on the CD
505 %p : The artist/performer/composer in the track **
506 %T : The track number **
507 %s : Number of seconds in this track, or seconds in CD if invalid track
508 %S : Number of seconds on the CD
509 %t : The track name or MRL if no name
510 %Y : The year 19xx or 20xx **
514 CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
515 const char format_str[], const char *psz_mrl, track_t i_track)
517 #define TEMP_STR_SIZE 256
518 #define TEMP_STR_LEN (TEMP_STR_SIZE-1)
519 static char temp_str[TEMP_STR_SIZE];
521 char * tp = temp_str;
522 vlc_bool_t saw_control_prefix = false;
523 size_t format_len = strlen(format_str);
525 memset(temp_str, 0, TEMP_STR_SIZE);
527 for (i=0; i<format_len; i++)
531 if (!saw_control_prefix && format_str[i] != '%')
533 *tp++ = format_str[i];
534 saw_control_prefix = false;
538 switch(format_str[i])
541 if (saw_control_prefix)
545 saw_control_prefix = !saw_control_prefix;
549 if (p_cdda->p_cdtext[0]
550 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
551 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
552 if (want_cddb_info(p_cdda, psz))
553 psz = p_cdda->cddb.disc->artist;
556 if (p_cdda->p_cdtext[0]
557 && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
558 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
559 if (want_cddb_info(p_cdda, psz))
560 psz = p_cdda->cddb.disc->title;
563 if (!p_cdda->b_cddb_enabled) goto not_special;
564 if (p_cdda->cddb.disc)
566 CDDB_CATEGORY[p_cdda->cddb.disc->category]);
569 if (p_cdda->p_cdtext[0]
570 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
571 psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
572 if (want_cddb_info(p_cdda, psz))
573 psz = p_cdda->cddb.disc->genre;
576 if (p_cdda->p_cdtext[0]
577 && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
578 psz = p_cdda->p_cdtext[0]->field[CDTEXT_DISCID];
579 if (want_cddb_info(p_cdda, psz)) {
580 add_format_num_info(p_cdda->cddb.disc->discid, "%x");
582 add_format_str_info(psz);
585 if (!p_cdda->b_cddb_enabled) goto not_special;
586 if (p_cdda->cddb.disc)
587 add_format_num_info(p_cdda->cddb.disc->year, "%5d");
590 if ( CDIO_INVALID_TRACK == i_track ) break;
591 if (p_cdda && p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
593 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
595 if (t != NULL && t->title != NULL) {
596 add_format_str_info(t->title);
598 add_format_str_info(psz_mrl);
601 if (p_cdda->p_cdtext[i_track]
602 && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE]) {
603 add_format_str_info(p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE]);
606 add_format_str_info(psz_mrl);
610 if ( CDIO_INVALID_TRACK == i_track ) break;
611 if (p_cdda->p_cdtext[i_track]
612 && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
613 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
614 if (want_cddb_info(p_cdda, psz))
616 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
618 if (t != NULL && t->artist != NULL)
623 if ( CDIO_INVALID_TRACK == i_track ) break;
624 if (p_cdda->p_cdtext[i_track]
625 && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
626 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
627 if (want_cddb_info(p_cdda, psz))
629 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
631 if (t != NULL && t->ext_data != NULL)
638 if (p_cdda->p_cdtext[0]
639 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
640 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
643 if (p_cdda->p_cdtext[0]
644 && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
645 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
648 if (p_cdda->p_cdtext[0]
649 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
650 psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
653 if (p_cdda->p_cdtext[0]
654 && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
655 add_format_str_info(p_cdda->p_cdtext[0]->field[CDTEXT_DISCID]);
658 if ( CDIO_INVALID_TRACK == i_track ) break;
659 if (p_cdda->p_cdtext[i_track]
660 && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
661 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
664 if ( CDIO_INVALID_TRACK == i_track ) break;
665 if (p_cdda->p_cdtext[i_track]
666 && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE])
667 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE];
672 if ( CDIO_INVALID_TRACK == i_track ) break;
673 if (p_cdda->p_cdtext[i_track]
674 && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
675 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
678 #endif /*HAVE_LIBCDDB*/
681 if ( CDIO_INVALID_TRACK != i_track )
683 char psz_buffer[MSTRTIME_MAX_SIZE];
684 unsigned int i_track_frames =
685 cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
687 i_track_frames / CDIO_CD_FRAMES_PER_SEC;
688 add_format_str_info( secstotimestr( psz_buffer,
693 /* Fall through to disc duration if CDIO_INVALID_TRACK */
696 char psz_buffer[MSTRTIME_MAX_SIZE];
697 unsigned int i_track_frames =
698 cdio_get_track_lba(p_cdda->p_cdio,
699 CDIO_CDROM_LEADOUT_TRACK);
701 i_track_frames / CDIO_CD_FRAMES_PER_SEC;
702 add_format_str_info( secstotimestr( psz_buffer,
708 add_format_str_info(psz_mrl);
712 add_format_str_info(p_cdda->psz_mcn);
716 add_format_num_info(p_cdda->i_tracks, "%d");
720 add_format_num_info(i_track, "%02d");
724 add_format_str_info(psz);
731 *tp++ = format_str[i];
732 saw_control_prefix = false;
735 return strdup(temp_str);
738 /* Return a MRL for the given track. The caller must free the
741 CDDAFormatMRL( const access_t *p_access, track_t i_track )
743 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
744 const unsigned int psz_mrl_max = strlen(CDDA_MRL_PREFIX)
745 + strlen(p_cdda->psz_source) +
746 + strlen("@T") + strlen("100") + 1;
747 char *psz_mrl = malloc( psz_mrl_max );
749 if (CDIO_INVALID_TRACK == i_track)
750 snprintf(psz_mrl, psz_mrl_max, "%s%s",
751 CDDA_MRL_PREFIX, p_cdda->psz_source);
753 snprintf(psz_mrl, psz_mrl_max, "%s%s@T%u",
754 CDDA_MRL_PREFIX, p_cdda->psz_source, i_track);
759 /* Return a title string as specified by the titel format string for the
760 given track. The caller must free the allocated string. */
762 CDDAFormatTitle( const access_t *p_access, track_t i_track )
765 char *config_varname = MODULE_STRING "-title-format";
766 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
767 char *psz_mrl = CDDAFormatMRL( p_access, i_track );
773 if (p_cdda->b_cddb_enabled)
775 config_varname = MODULE_STRING "-cddb-title-format";
777 #endif /*HAVE_LIBCDDB*/
779 CDDAFormatStr( p_access, p_cdda,
780 config_GetPsz( p_access, config_varname ),
788 /* Adds a string-valued entry to the playlist information under "Track"
789 if the string is not null or the null string.
791 #define add_playlist_track_info_str(TITLE, FIELD) \
792 if (FIELD && strlen(FIELD)) \
794 playlist_ItemAddInfo( p_item, _("Track"), _(TITLE), \
798 static playlist_item_t *
799 CDDACreatePlaylistItem( const access_t *p_access, cdda_data_t *p_cdda,
800 playlist_t *p_playlist, playlist_item_t *p_item,
803 unsigned int i_track_frames =
804 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
805 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
806 mtime_t i_mduration =
807 i_track_frames * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) ;
808 char *psz_title = NULL;
809 char *psz_mrl = NULL;
811 playlist_item_t *p_child = NULL;
813 if( !p_item ) return NULL;
815 psz_title = CDDAFormatTitle( p_access, i_track ) ;
816 psz_mrl = CDDAFormatMRL( p_access, i_track ) ;
818 dbg_print( INPUT_DBG_META, "mrl: %s, title: %s, duration, %ld",
819 psz_mrl, psz_title, (long int) i_mduration / 1000000 );
821 p_child = playlist_ItemNew( p_playlist, psz_mrl, psz_title );
822 p_child->input.i_duration = i_mduration;
826 if( !p_child ) return NULL;
828 playlist_NodeAddItem( p_playlist, p_child,
829 p_item->pp_parents[0]->i_view,
830 p_item, PLAYLIST_APPEND, PLAYLIST_END );
831 playlist_CopyParents( p_item, p_child );
836 int CDDAAddMetaToItem( access_t *p_access, cdda_data_t *p_cdda,
837 playlist_item_t *p_item, int i_track,
838 vlc_bool_t b_single )
840 vlc_mutex_lock( &p_item->input.lock );
842 add_playlist_track_info_str("Source", p_cdda->psz_source);
843 playlist_ItemAddInfo( p_item, _("Track"), _("Track Number"),
846 if (p_cdda->p_cdtext[i_track])
848 const cdtext_t *p = p_cdda->p_cdtext[i_track];
849 add_playlist_track_info_str("Arranger (CD-Text)",
850 p->field[CDTEXT_ARRANGER]);
851 add_playlist_track_info_str("Composer (CD-Text)",
852 p->field[CDTEXT_COMPOSER]);
853 add_playlist_track_info_str("Genre (CD-Text)",
854 p->field[CDTEXT_GENRE]);
855 add_playlist_track_info_str("Message (CD-Text)",
856 p->field[CDTEXT_MESSAGE]);
857 add_playlist_track_info_str("Performer (CD-Text)",
858 p->field[CDTEXT_PERFORMER]);
859 add_playlist_track_info_str("Songwriter (CD-Text)",
860 p->field[CDTEXT_SONGWRITER]);
861 add_playlist_track_info_str("Title (CD-Text)",
862 p->field[CDTEXT_TITLE]);
866 if (p_cdda->b_cddb_enabled)
868 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
869 i_track-p_cdda->i_first_track);
874 add_playlist_track_info_str("Artist (CDDB)",
877 add_playlist_track_info_str("Title (CDDB)",
880 add_playlist_track_info_str("Extended information (CDDB)",
884 #endif /*HAVE_LIBCDDB*/
886 vlc_mutex_unlock( &p_item->input.lock );
892 CDDAFixupPlaylist( access_t *p_access, cdda_data_t *p_cdda,
893 vlc_bool_t b_single_track )
896 playlist_t * p_playlist = NULL;
897 const track_t i_first_track = p_cdda->i_first_track;
898 playlist_item_t *p_item = NULL;
899 vlc_bool_t b_play = VLC_FALSE;
903 p_cdda->b_cddb_enabled =
904 config_GetInt( p_access, MODULE_STRING "-cddb-enabled" );
905 if( b_single_track && !p_cdda->b_cddb_enabled )
912 if (! p_cdda->b_nav_mode ) {
913 p_playlist = (playlist_t *) vlc_object_find( p_access,
918 msg_Warn( p_access, "can't find playlist" );
923 if( b_single_track || p_cdda->b_nav_mode ) {
924 i_track = p_cdda->i_track;
928 i_track = CDIO_INVALID_TRACK;
930 CDDAMetaInfoInit( p_access );
931 CDDAMetaInfo( p_access, p_cdda->i_track );
934 p_item = playlist_LockItemGetByInput( p_playlist,
935 ((input_thread_t *)p_access->p_parent)->input.p_item );
937 if( p_item == p_playlist->status.p_item && !b_single_track )
949 /*May fill out more information when the playlist user interface becomes
952 track_t i_track = p_cdda->i_track;
953 unsigned int i_track_frames =
954 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
955 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
957 input_title_t *t = p_cdda->p_title[0] = //i_track-i_first_track] =
958 vlc_input_title_New();
960 asprintf( &t->psz_name, _("Track %i"), i_track );
961 t->i_size = p_access->info.i_size =
962 i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
964 t->i_length = I64C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
968 CDDAAddMetaToItem( p_access, p_cdda, p_item, i_track, VLC_FALSE );
970 p_cdda->i_titles = 1;
971 p_access->info.i_size =
972 i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
973 p_access->info.i_update |= INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE;
974 p_item->input.psz_uri = CDDAFormatMRL(p_access, i_track);
975 p_item->input.i_duration = i_track_frames
976 * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC);
983 if ( ! p_cdda->b_nav_mode )
984 playlist_ItemToNode( p_playlist, p_item );
986 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
988 playlist_item_t *p_child;
989 const track_t i_track = i_first_track + i;
990 unsigned int i_track_frames =
991 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
992 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
994 t = p_cdda->p_title[i] = vlc_input_title_New();
996 asprintf( &t->psz_name, _("Track %i"), i_track );
997 t->i_size = i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
999 t->i_length = I64C(1000000) * t->i_size
1000 / CDDA_FREQUENCY_SAMPLE / 4;
1002 if ( ! p_cdda->b_nav_mode ) {
1003 p_child = CDDACreatePlaylistItem( p_access, p_cdda, p_playlist,
1006 CDDAAddMetaToItem( p_access, p_cdda, p_child, i_track,
1011 p_cdda->i_titles = p_cdda->i_tracks;
1012 p_access->info.i_size =
1013 cdio_get_track_lba(p_cdda->p_cdio, CDIO_CDROM_LEADOUT_TRACK)
1014 * (int64_t) CDIO_CD_FRAMESIZE_RAW;
1015 p_access->info.i_update |= INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE;
1017 p_item->input.i_duration =
1018 p_access->info.i_size * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) ;
1019 p_item->input.psz_uri = CDDAFormatMRL(p_access,
1027 playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
1028 p_playlist->status.i_view,
1029 p_playlist->status.p_item, NULL );
1030 vlc_object_release( p_playlist );