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,
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 *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 cddb_set_email_address( conn,
73 config_GetPsz( p_access,
74 MODULE_STRING "-cddb-email") );
75 cddb_set_server_name( conn,
76 config_GetPsz( p_access,
77 MODULE_STRING "-cddb-server") );
78 cddb_set_server_port(conn,
79 config_GetInt( p_access,
80 MODULE_STRING "-cddb-port") );
82 /* Set the location of the local CDDB cache directory.
83 The default location of this directory is */
85 if (!config_GetInt( p_access, MODULE_STRING "-cddb-enable-cache" ))
86 cddb_cache_disable(conn);
88 cddb_cache_set_dir(conn,
89 config_GetPsz( p_access,
90 MODULE_STRING "-cddb-cachedir") );
92 cddb_set_timeout(conn,
93 config_GetInt( p_access, MODULE_STRING "-cddb-timeout") );
96 if (config_GetInt( p_access, MODULE_STRING "-cddb-httpd" ) )
98 cddb_http_enable(conn);
102 cddb_http_disable(conn);
105 p_cdda->cddb.disc = cddb_disc_new();
107 if (!p_cdda->cddb.disc)
109 msg_Err( p_access, "Unable to create CDDB disc structure." );
113 for(i = 0; i < p_cdda->i_tracks; i++)
115 track_t i_track = p_cdda->i_first_track + i;
116 cddb_track_t *t = cddb_track_new();
117 t->frame_offset = cdio_get_track_lba(p_cdio, i_track);
118 cddb_disc_add_track(p_cdda->cddb.disc, t);
121 p_cdda->cddb.disc->length =
122 cdio_get_track_lba(p_cdio, CDIO_CDROM_LEADOUT_TRACK)
123 / CDIO_CD_FRAMES_PER_SEC;
125 if (!cddb_disc_calc_discid(p_cdda->cddb.disc))
127 msg_Err( p_access, "CDDB disc ID calculation failed" );
131 i_matches = cddb_query(conn, p_cdda->cddb.disc);
136 msg_Warn( p_access, "Found %d matches in CDDB. Using first one.",
138 cddb_read(conn, p_cdda->cddb.disc);
140 if (p_cdda->i_debug & INPUT_DBG_CDDB)
141 cddb_disc_print(p_cdda->cddb.disc);
146 msg_Warn( p_access, "CDDB error: %s", cddb_error_str(errno));
154 #endif /*HAVE_LIBCDDB*/
156 #define add_meta_val(VLC_META, VAL) \
157 if ( p_cdda->p_meta && VAL) { \
158 vlc_meta_Add( p_cdda->p_meta, VLC_META, VAL ); \
159 dbg_print( INPUT_DBG_META, "field %s: %s\n", VLC_META, VAL ); \
162 #define add_cddb_meta(FIELD, VLC_META) \
163 add_meta_val(VLC_META, p_cdda->cddb.disc->FIELD);
165 #define add_cddb_meta_fmt(FIELD, FORMAT_SPEC, VLC_META) \
168 snprintf( psz_buf, sizeof(psz_buf)-1, FORMAT_SPEC, \
169 p_cdda->cddb.disc->FIELD ); \
170 psz_buf[sizeof(psz_buf)-1] = '\0'; \
171 add_meta_val(VLC_META, psz_buf); \
174 /* Adds a string-valued entry to the stream and media information if
175 the string is not null or the null string.
177 #define add_info_str(CATEGORY, TITLE, FIELD) \
178 if (FIELD && strlen(FIELD)) { \
179 input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY, \
180 _(TITLE), "%s", FIELD ); \
183 /* Adds a numeric-valued entry to the stream and media information
184 if the number is not zero. */
185 #define add_info_val(CATEGORY, TITLE, FMT, FIELD) \
187 input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY, \
188 _(TITLE), FMT, FIELD ); \
191 /* Adds a CDDB string-valued entry to the stream and media information
192 under category "Disc" if the string is not null or the null string.
194 #define add_cddb_disc_info_str(TITLE, FIELD) \
195 add_info_str("Disc", TITLE, p_cdda->cddb.disc->FIELD)
197 /* Adds a CDDB numeric-valued entry to the stream and media information
198 under category "Disc" if the string is not null or the null string.
200 #define add_cddb_disc_info_val(TITLE, FMT, FIELD) \
201 add_info_val("Disc", TITLE, FMT, p_cdda->cddb.disc->FIELD)
203 /* Adds a CD-Text string-valued entry to the stream and media information
204 under category "Disc" if the string is not null or the null string.
206 #define add_cdtext_info_str(CATEGORY, TITLE, INDEX, FIELD) \
207 add_info_str(CATEGORY, TITLE, p_cdda->p_cdtext[INDEX]->field[FIELD])
209 /* Adds a CD-Text string-valued entry to the stream and media information
210 under category "Disc" if the string is not null or the null string.
212 #define add_cdtext_disc_info_str(TITLE, FIELD) \
213 add_cdtext_info_str("Disc", TITLE, 0, FIELD)
217 Saves Meta Information about the CD-DA.
219 Meta information used in "stream and media info" or in playlist
220 info. The intialization of CD-Text or CDDB is done here though.
221 Therefore, this should be called before CDDAMetaInfo is called.
225 CDDAMetaInfoInit( access_t *p_access )
227 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
229 if ( ! p_cdda ) return;
231 p_cdda->psz_mcn = cdio_get_mcn(p_cdda->p_cdio);
232 p_cdda->p_meta = vlc_meta_New();
235 if ( p_cdda->b_cddb_enabled )
237 GetCDDBInfo(p_access, p_cdda);
240 #endif /*HAVE_LIBCDDB*/
246 for( i_track = 0 ; i_track < p_cdda->i_tracks ; i_track++ )
248 p_cdda->p_cdtext[i_track] =
249 cdio_get_cdtext(p_cdda->p_cdio, i_track);
255 In the Control routine, we handle Meta Information requests and
256 basically copy what was saved in CDDAMetaInfoInit.
258 If i_track is CDIO_INVALID_TRACK we are probably asking about the entire
262 CDDAMetaInfo( access_t *p_access, track_t i_track, /*const*/ char *psz_mrl )
264 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
265 char *psz_meta_title = psz_mrl;
266 char *psz_meta_artist = NULL;
267 char *psz_name = NULL;
268 char *config_varname = MODULE_STRING "-title-format";
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 (p_cdda->b_cddb_enabled)
279 config_varname = MODULE_STRING "-cddb-title-format";
282 if( CDIO_INVALID_TRACK == i_track )
285 psz_meta_title = p_cdda->cddb.disc->title;
286 psz_meta_artist = p_cdda->cddb.disc->artist;
287 if ( p_cdda->cddb.disc->genre && strlen(p_cdda->cddb.disc->genre) )
288 add_cddb_meta(genre, VLC_META_GENRE);
289 if ( 0 != p_cdda->cddb.disc->year )
290 add_cddb_meta_fmt(year, "%d", VLC_META_DATE );
294 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i_track-1);
297 if( t->title != NULL )
299 add_meta_val( VLC_META_TITLE, t->title );
301 if( t->artist != NULL )
303 add_meta_val( VLC_META_ARTIST, t->artist );
309 #endif /*HAVE_LIBCDDB*/
313 track_t i = p_cdda->i_tracks;
314 const int i_first_track = p_cdda->i_first_track;
315 char psz_buffer[MSTRTIME_MAX_SIZE];
316 unsigned int i_track_frames =
317 cdio_get_track_lba(p_cdda->p_cdio, CDIO_CDROM_LEADOUT_TRACK);
319 mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
321 dbg_print( INPUT_DBG_META, "Duration %ld, tracks %d",
322 (long int) i_duration, p_cdda->i_tracks );
323 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
324 _("Disc"), _("Duration"), "%s",
325 secstotimestr( psz_buffer, i_duration ) );
327 if (p_cdda->psz_mcn) {
328 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
329 _("Disc"), _("Media Catalog Number (MCN)"), "%s",
332 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
333 _("Disc"), _("Tracks"), "%d", p_cdda->i_tracks );
338 if (p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
340 add_cddb_disc_info_str("Artist (CDDB)", artist);
341 if ( CDDB_CAT_INVALID != p_cdda->cddb.disc->category )
342 add_info_str("Disc", "Category (CDDB)",
343 CDDB_CATEGORY[p_cdda->cddb.disc->category]);
344 add_cddb_disc_info_val("Disc ID (CDDB)", "%x", discid);
345 add_cddb_disc_info_str("Extended Data (CDDB)", ext_data);
346 add_cddb_disc_info_str("Genre (CDDB)", genre);
347 add_cddb_disc_info_str("Title (CDDB)", title);
348 if ( 0 != p_cdda->cddb.disc->year )
349 add_cddb_disc_info_val("Year (CDDB)", "%d", year);
352 #endif /*HAVE_LIBCDDB*/
354 if (p_cdda->p_cdtext[0])
358 add_cdtext_disc_info_str("Arranger (CD-Text)", CDTEXT_ARRANGER);
359 add_cdtext_disc_info_str("Composer (CD-Text)", CDTEXT_COMPOSER);
360 add_cdtext_disc_info_str("Disc ID (CD-Text)", CDTEXT_DISCID);
361 add_cdtext_disc_info_str("Genre (CD-Text)", CDTEXT_GENRE);
362 add_cdtext_disc_info_str("Message (CD-Text)", CDTEXT_MESSAGE);
363 add_cdtext_disc_info_str("Performer (CD-Text)", CDTEXT_PERFORMER);
364 add_cdtext_disc_info_str("Songwriter (CD-Text)", CDTEXT_SONGWRITER);
365 add_cdtext_disc_info_str("Title (CD-Text)", CDTEXT_TITLE);
367 psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
368 if (psz_field && strlen(psz_field)) {
369 psz_meta_title = psz_field;
371 psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
372 if (psz_field && strlen(psz_field)) {
373 psz_meta_artist = psz_field;
378 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
380 char psz_track[TITLE_MAX];
381 const track_t i_track = i_first_track + i;
382 unsigned int i_track_frames =
383 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
384 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
386 mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
389 snprintf(psz_track, TITLE_MAX, "%s %02d", _("Track"), i_track);
391 input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
393 secstotimestr( psz_buffer, i_duration ) );
395 asprintf(&psz_mrl, "%s%s@T%u",
396 CDDA_MRL_PREFIX, p_cdda->psz_source, i_track);
398 input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
399 _("MRL"), "%s", psz_mrl );
402 if (p_cdda->p_cdtext[i_track])
404 add_cdtext_info_str( psz_track, "Arranger (CD-Text)",
405 i_track, CDTEXT_ARRANGER);
406 add_cdtext_info_str( psz_track, "Composer (CD-Text)",
407 i_track, CDTEXT_COMPOSER);
408 add_cdtext_info_str( psz_track, "Disc ID (CD-Text)",
409 i_track, CDTEXT_DISCID);
410 add_cdtext_info_str( psz_track, "Genre (CD-Text)",
411 i_track, CDTEXT_GENRE);
412 add_cdtext_info_str( psz_track, "Message (CD-Text)",
413 i_track, CDTEXT_MESSAGE);
414 add_cdtext_info_str( psz_track, "Performer (CD-Text)",
415 i_track, CDTEXT_PERFORMER);
416 add_cdtext_info_str( psz_track, "Songwriter (CD-Text)",
417 i_track, CDTEXT_SONGWRITER);
418 add_cdtext_info_str( psz_track, "Title (CD-Text)",
419 i_track, CDTEXT_TITLE);
423 if (p_cdda->b_cddb_enabled)
425 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i);
428 add_info_str(psz_track, "Artist (CDDB)", t->artist);
429 add_info_str(psz_track, "Title (CDDB)", t->title);
430 add_info_str(psz_track, "Extended Data (CDDB)",
434 #endif /*HAVE_LIBCDDB*/
437 /* Above we should have set psz_meta_title and psz_meta_artist
438 to CDDB or CD-Text values or the default value depending on
439 availablity and user preferences.
441 We also set above config_varname to the format used
443 So now add the title and artist to VLC's meta, and the
444 name as shown in the status bar and playlist entry.
446 add_meta_val( VLC_META_TITLE, psz_meta_title );
448 add_meta_val( VLC_META_ARTIST, psz_meta_artist );
450 if ( CDIO_INVALID_TRACK != i_track )
453 CDDAFormatStr( p_access, p_cdda,
454 config_GetPsz( p_access, config_varname ),
457 input_Control( p_cdda->p_input, INPUT_SET_NAME, psz_name );
462 #define add_format_str_info(val) \
464 const char *str = val; \
469 strncat(tp, str, TEMP_STR_LEN-(tp-temp_str)); \
472 saw_control_prefix = false; \
476 #define add_format_num_info(val, fmt) \
480 sprintf(num_str, fmt, val); \
481 len=strlen(num_str); \
483 strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); \
486 saw_control_prefix = false; \
491 cdda_data_t *p_cdda, char *psz_cdtext)
493 /* We either don't have CD-Text info, or we do but we prefer to get CDDB
494 which means CDDB has been enabled and we were able to retrieve the info.*/
496 return !psz_cdtext ||
497 (!p_cdda->b_cdtext_prefer && p_cdda->b_cddb_enabled && p_cdda->cddb.disc);
505 Take a format string and expand escape sequences, that is sequences that
506 begin with %, with information from the current CD.
507 The expanded string is returned. Here is a list of escape sequences:
509 %a : The album artist **
510 %A : The album information **
515 %m : The CD-DA Media Catalog Number (MCN)
516 %n : The number of tracks on the CD
517 %p : The artist/performer/composer in the track **
518 %T : The track number **
519 %s : Number of seconds in this track, or seconds in CD if invalid track
520 %S : Number of seconds on the CD
521 %t : The track name or MRL if no name
522 %Y : The year 19xx or 20xx **
526 CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
527 const char format_str[], const char *psz_mrl, track_t i_track)
529 #define TEMP_STR_SIZE 256
530 #define TEMP_STR_LEN (TEMP_STR_SIZE-1)
531 static char temp_str[TEMP_STR_SIZE];
533 char * tp = temp_str;
534 vlc_bool_t saw_control_prefix = false;
535 size_t format_len = strlen(format_str);
537 memset(temp_str, 0, TEMP_STR_SIZE);
539 for (i=0; i<format_len; i++)
543 if (!saw_control_prefix && format_str[i] != '%')
545 *tp++ = format_str[i];
546 saw_control_prefix = false;
550 switch(format_str[i])
553 if (saw_control_prefix)
557 saw_control_prefix = !saw_control_prefix;
561 if (p_cdda->p_cdtext[0]
562 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
563 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
564 if (want_cddb_info(p_cdda, psz))
565 psz = p_cdda->cddb.disc->artist;
568 if (p_cdda->p_cdtext[0]
569 && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
570 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
571 if (want_cddb_info(p_cdda, psz))
572 psz = p_cdda->cddb.disc->title;
575 if (!p_cdda->b_cddb_enabled) goto not_special;
576 if (p_cdda->cddb.disc)
578 CDDB_CATEGORY[p_cdda->cddb.disc->category]);
581 if (p_cdda->p_cdtext[0]
582 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
583 psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
584 if (want_cddb_info(p_cdda, psz))
585 psz = p_cdda->cddb.disc->genre;
588 if (p_cdda->p_cdtext[0]
589 && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
590 psz = p_cdda->p_cdtext[0]->field[CDTEXT_DISCID];
591 if (want_cddb_info(p_cdda, psz)) {
592 add_format_num_info(p_cdda->cddb.disc->discid, "%x");
594 add_format_str_info(psz);
597 if (!p_cdda->b_cddb_enabled) goto not_special;
598 if (p_cdda->cddb.disc)
599 add_format_num_info(p_cdda->cddb.disc->year, "%5d");
602 if ( CDIO_INVALID_TRACK == i_track ) break;
603 if (p_cdda && p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
605 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
607 if (t != NULL && t->title != NULL) {
608 add_format_str_info(t->title);
610 add_format_str_info(psz_mrl);
613 if (p_cdda->p_cdtext[i_track]
614 && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE]) {
615 add_format_str_info(p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE]);
618 add_format_str_info(psz_mrl);
622 if ( CDIO_INVALID_TRACK == i_track ) break;
623 if (p_cdda->p_cdtext[i_track]
624 && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
625 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
626 if (want_cddb_info(p_cdda, psz))
628 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
630 if (t != NULL && t->artist != NULL)
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_MESSAGE])
638 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
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 && t->ext_data != NULL)
650 if (p_cdda->p_cdtext[0]
651 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
652 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
655 if (p_cdda->p_cdtext[0]
656 && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
657 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
660 if (p_cdda->p_cdtext[0]
661 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
662 psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
665 if (p_cdda->p_cdtext[0]
666 && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
667 add_format_str_info(p_cdda->p_cdtext[0]->field[CDTEXT_DISCID]);
670 if ( CDIO_INVALID_TRACK == i_track ) break;
671 if (p_cdda->p_cdtext[i_track]
672 && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
673 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
676 if ( CDIO_INVALID_TRACK == i_track ) break;
677 if (p_cdda->p_cdtext[i_track]
678 && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE])
679 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE];
684 if ( CDIO_INVALID_TRACK == i_track ) break;
685 if (p_cdda->p_cdtext[i_track]
686 && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
687 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
690 #endif /*HAVE_LIBCDDB*/
693 if ( CDIO_INVALID_TRACK != i_track )
695 char psz_buffer[MSTRTIME_MAX_SIZE];
696 unsigned int i_track_frames =
697 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
698 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
700 i_track_frames / CDIO_CD_FRAMES_PER_SEC;
701 add_format_str_info( secstotimestr( psz_buffer,
706 /* Fall through to disc duration if CDIO_INVALID_TRACK */
709 char psz_buffer[MSTRTIME_MAX_SIZE];
710 unsigned int i_track_frames =
711 cdio_get_track_lba(p_cdda->p_cdio,
712 CDIO_CDROM_LEADOUT_TRACK);
714 i_track_frames / CDIO_CD_FRAMES_PER_SEC;
715 add_format_str_info( secstotimestr( psz_buffer,
721 add_format_str_info(psz_mrl);
725 add_format_str_info(p_cdda->psz_mcn);
729 add_format_num_info(p_cdda->i_tracks, "%d");
733 add_format_num_info(i_track, "%02d");
737 add_format_str_info(psz);
744 *tp++ = format_str[i];
745 saw_control_prefix = false;
748 return strdup(temp_str);
751 /* Adds a string-valued entry to the playlist information under "Track"
752 if the string is not null or the null string.
754 #define add_playlist_track_info_str(TITLE, FIELD) \
755 if (FIELD && strlen(FIELD)) \
757 playlist_ItemAddInfo( p_item, _("Track"), _(TITLE), \
762 CDDACreatePlaylistItem( const access_t *p_access, cdda_data_t *p_cdda,
763 playlist_t *p_playlist, playlist_item_t *p_item,
764 track_t i_track, char *psz_mrl, int psz_mrl_max )
766 unsigned int i_track_frames =
767 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
768 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
769 mtime_t i_mduration =
770 i_track_frames * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) ;
772 char *config_varname = MODULE_STRING "-title-format";
774 playlist_item_t *p_child = NULL;
782 if (p_cdda->b_cddb_enabled)
784 config_varname = MODULE_STRING "-cddb-title-format";
786 #endif /*HAVE_LIBCDDB*/
789 snprintf(psz_mrl, psz_mrl_max, "%s%s@T%u",
790 CDDA_MRL_PREFIX, p_cdda->psz_source, i_track);
792 psz_title = CDDAFormatStr( p_access, p_cdda,
793 config_GetPsz( p_access, config_varname ),
796 dbg_print( INPUT_DBG_META, "mrl: %s, title: %s, duration, %ld",
797 psz_mrl, psz_title, (long int) i_mduration / 1000000 );
799 p_child = playlist_ItemNew( p_playlist, psz_mrl, psz_title );
800 p_child->input.i_duration = i_mduration;
802 if( !p_child ) return NULL;
804 playlist_NodeAddItem( p_playlist, p_child,
805 p_item->pp_parents[0]->i_view,
806 p_item, PLAYLIST_APPEND, PLAYLIST_END );
807 playlist_CopyParents( p_item, p_child );
812 int CDDAAddMetaToItem( access_t *p_access, cdda_data_t *p_cdda,
813 playlist_item_t *p_item, int i_track,
814 vlc_bool_t b_single )
816 vlc_mutex_lock( &p_item->input.lock );
818 add_playlist_track_info_str("Source", p_cdda->psz_source);
819 playlist_ItemAddInfo( p_item, _("Track"), _("Track Number"),
822 if (p_cdda->p_cdtext[i_track])
824 const cdtext_t *p = p_cdda->p_cdtext[i_track];
825 add_playlist_track_info_str("Arranger (CD-Text)",
826 p->field[CDTEXT_ARRANGER]);
827 add_playlist_track_info_str("Composer (CD-Text)",
828 p->field[CDTEXT_COMPOSER]);
829 add_playlist_track_info_str("Genre (CD-Text)",
830 p->field[CDTEXT_GENRE]);
831 add_playlist_track_info_str("Message (CD-Text)",
832 p->field[CDTEXT_MESSAGE]);
833 add_playlist_track_info_str("Performer (CD-Text)",
834 p->field[CDTEXT_PERFORMER]);
835 add_playlist_track_info_str("Songwriter (CD-Text)",
836 p->field[CDTEXT_SONGWRITER]);
837 add_playlist_track_info_str("Title (CD-Text)",
838 p->field[CDTEXT_TITLE]);
842 if (p_cdda->b_cddb_enabled)
844 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
845 i_track-p_cdda->i_first_track);
850 add_playlist_track_info_str("Artist (CDDB)",
853 add_playlist_track_info_str("Title (CDDB)",
856 add_playlist_track_info_str("Extended information (CDDB)",
860 #endif /*HAVE_LIBCDDB*/
862 vlc_mutex_unlock( &p_item->input.lock );
868 CDDAFixupPlaylist( access_t *p_access, cdda_data_t *p_cdda,
869 vlc_bool_t b_single_track )
872 playlist_t * p_playlist;
873 char * psz_mrl = NULL;
874 unsigned int psz_mrl_max = strlen(CDDA_MRL_PREFIX)
875 + strlen(p_cdda->psz_source) +
876 + strlen("@T") + strlen("100") + 1;
877 const track_t i_first_track = p_cdda->i_first_track;
878 playlist_item_t *p_item;
879 vlc_bool_t b_play = VLC_FALSE;
882 p_cdda->b_cddb_enabled =
883 config_GetInt( p_access, MODULE_STRING "-cddb-enabled" );
884 if( b_single_track && !p_cdda->b_cddb_enabled )
891 psz_mrl = malloc( psz_mrl_max );
893 if( psz_mrl == NULL )
895 msg_Warn( p_access, "out of memory" );
899 p_playlist = (playlist_t *) vlc_object_find( p_access, VLC_OBJECT_PLAYLIST,
903 msg_Warn( p_access, "can't find playlist" );
910 snprintf(psz_mrl, psz_mrl_max, "%s%s@T%u", CDDA_MRL_PREFIX,
911 p_cdda->psz_source, p_cdda->i_track);
912 CDDAMetaInfoInit( p_access );
913 CDDAMetaInfo( p_access, p_cdda->i_track, psz_mrl );
917 snprintf(psz_mrl, psz_mrl_max, "%s%s", CDDA_MRL_PREFIX,
919 CDDAMetaInfoInit( p_access );
920 CDDAMetaInfo( p_access, CDIO_INVALID_TRACK, psz_mrl );
923 p_item = playlist_ItemGetByInput( p_playlist,
924 ((input_thread_t *)p_access->p_parent)->input.p_item );
926 if( p_item == p_playlist->status.p_item && !b_single_track )
937 /*May fill out more information when the playlist user interface becomes
940 track_t i_track = p_cdda->i_track;
941 unsigned int i_track_frames =
942 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
943 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
945 input_title_t *t = p_cdda->p_title[0] = //i_track-i_first_track] =
946 vlc_input_title_New();
948 asprintf( &t->psz_name, _("Track %i"), i_track );
949 t->i_size = p_access->info.i_size =
950 i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
952 t->i_length = I64C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
955 CDDAAddMetaToItem( p_access, p_cdda, p_item, i_track, VLC_FALSE );
957 p_cdda->i_titles = 1;
958 p_access->info.i_size =
959 i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
960 p_access->info.i_update |= INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE;
961 p_item->input.psz_uri = strdup(psz_mrl);
962 p_item->input.i_duration = i_track_frames
963 * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC);
968 playlist_ItemToNode( p_playlist, p_item );
969 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
971 playlist_item_t *p_child;
972 const track_t i_track = i_first_track + i;
973 unsigned int i_track_frames =
974 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
975 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
977 t = p_cdda->p_title[i] = vlc_input_title_New();
979 asprintf( &t->psz_name, _("Track %i"), i_track );
980 t->i_size = i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
982 t->i_length = I64C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
984 p_child = CDDACreatePlaylistItem( p_access, p_cdda, p_playlist,
988 CDDAAddMetaToItem( p_access, p_cdda, p_child, i_track, VLC_TRUE );
991 p_cdda->i_titles = p_cdda->i_tracks;
992 p_access->info.i_size =
993 cdio_get_track_lba(p_cdda->p_cdio, CDIO_CDROM_LEADOUT_TRACK)
994 * (int64_t) CDIO_CD_FRAMESIZE_RAW;
995 p_access->info.i_update |= INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE;
996 p_item->input.i_duration =
997 p_access->info.i_size * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) ;
998 p_item->input.psz_uri = strdup(psz_mrl);
1003 playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
1004 p_playlist->status.i_view,
1005 p_playlist->status.p_item, NULL );
1008 vlc_object_release( p_playlist );