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.b_fixed_name = VLC_TRUE;
801 p_child->input.i_duration = i_mduration;
803 if( !p_child ) return NULL;
805 playlist_NodeAddItem( p_playlist, p_child,
806 p_item->pp_parents[0]->i_view,
807 p_item, PLAYLIST_APPEND, PLAYLIST_END );
808 playlist_CopyParents( p_item, p_child );
813 int CDDAAddMetaToItem( access_t *p_access, cdda_data_t *p_cdda,
814 playlist_item_t *p_item, int i_track,
815 vlc_bool_t b_single )
817 vlc_mutex_lock( &p_item->input.lock );
819 add_playlist_track_info_str("Source", p_cdda->psz_source);
820 playlist_ItemAddInfo( p_item, _("Track"), _("Track Number"),
823 if (p_cdda->p_cdtext[i_track])
825 const cdtext_t *p = p_cdda->p_cdtext[i_track];
826 add_playlist_track_info_str("Arranger (CD-Text)",
827 p->field[CDTEXT_ARRANGER]);
828 add_playlist_track_info_str("Composer (CD-Text)",
829 p->field[CDTEXT_COMPOSER]);
830 add_playlist_track_info_str("Genre (CD-Text)",
831 p->field[CDTEXT_GENRE]);
832 add_playlist_track_info_str("Message (CD-Text)",
833 p->field[CDTEXT_MESSAGE]);
834 add_playlist_track_info_str("Performer (CD-Text)",
835 p->field[CDTEXT_PERFORMER]);
836 add_playlist_track_info_str("Songwriter (CD-Text)",
837 p->field[CDTEXT_SONGWRITER]);
838 add_playlist_track_info_str("Title (CD-Text)",
839 p->field[CDTEXT_TITLE]);
843 if (p_cdda->b_cddb_enabled)
845 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
846 i_track-p_cdda->i_first_track);
851 add_playlist_track_info_str("Artist (CDDB)",
854 add_playlist_track_info_str("Title (CDDB)",
857 add_playlist_track_info_str("Extended information (CDDB)",
861 #endif /*HAVE_LIBCDDB*/
863 vlc_mutex_unlock( &p_item->input.lock );
869 CDDAFixupPlaylist( access_t *p_access, cdda_data_t *p_cdda,
870 vlc_bool_t b_single_track )
873 playlist_t * p_playlist;
874 char * psz_mrl = NULL;
875 unsigned int psz_mrl_max = strlen(CDDA_MRL_PREFIX)
876 + strlen(p_cdda->psz_source) +
877 + strlen("@T") + strlen("100") + 1;
878 const track_t i_first_track = p_cdda->i_first_track;
879 playlist_item_t *p_item;
880 vlc_bool_t b_play = VLC_FALSE;
883 p_cdda->b_cddb_enabled =
884 config_GetInt( p_access, MODULE_STRING "-cddb-enabled" );
885 if( b_single_track && !p_cdda->b_cddb_enabled )
892 psz_mrl = malloc( psz_mrl_max );
894 if( psz_mrl == NULL )
896 msg_Warn( p_access, "out of memory" );
900 p_playlist = (playlist_t *) vlc_object_find( p_access, VLC_OBJECT_PLAYLIST,
904 msg_Warn( p_access, "can't find playlist" );
911 snprintf(psz_mrl, psz_mrl_max, "%s%s@T%u", CDDA_MRL_PREFIX,
912 p_cdda->psz_source, p_cdda->i_track);
913 CDDAMetaInfoInit( p_access );
914 CDDAMetaInfo( p_access, p_cdda->i_track, psz_mrl );
918 snprintf(psz_mrl, psz_mrl_max, "%s%s", CDDA_MRL_PREFIX,
920 CDDAMetaInfoInit( p_access );
921 CDDAMetaInfo( p_access, CDIO_INVALID_TRACK, psz_mrl );
924 p_item = playlist_ItemGetByInput( p_playlist,
925 ((input_thread_t *)p_access->p_parent)->input.p_item );
927 if( p_item == p_playlist->status.p_item && !b_single_track )
938 /*May fill out more information when the playlist user interface becomes
941 track_t i_track = p_cdda->i_track;
942 unsigned int i_track_frames =
943 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
944 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
946 input_title_t *t = p_cdda->p_title[0] = //i_track-i_first_track] =
947 vlc_input_title_New();
949 asprintf( &t->psz_name, _("Track %i"), i_track );
950 t->i_size = p_access->info.i_size =
951 i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
953 t->i_length = I64C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
956 CDDAAddMetaToItem( p_access, p_cdda, p_item, i_track, VLC_FALSE );
958 p_cdda->i_titles = 1;
959 p_access->info.i_size =
960 i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
961 p_access->info.i_update |= INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE;
962 p_item->input.i_duration = i_track_frames
963 * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC);
967 playlist_ItemToNode( p_playlist, p_item );
968 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
970 playlist_item_t *p_child;
971 const track_t i_track = i_first_track + i;
972 unsigned int i_track_frames =
973 cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
974 cdio_get_track_lsn(p_cdda->p_cdio, i_track);
976 input_title_t *t = p_cdda->p_title[i] = vlc_input_title_New();
978 asprintf( &t->psz_name, _("Track %i"), i_track );
979 t->i_size = i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
981 t->i_length = I64C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
983 p_child = CDDACreatePlaylistItem( p_access, p_cdda, p_playlist,
987 CDDAAddMetaToItem( p_access, p_cdda, p_child, i_track, VLC_TRUE );
989 p_cdda->i_titles = p_cdda->i_tracks; /* should be +1 */
990 p_access->info.i_size =
991 cdio_get_track_lba(p_cdda->p_cdio, CDIO_CDROM_LEADOUT_TRACK)
992 * (int64_t) CDIO_CD_FRAMESIZE_RAW;
993 p_access->info.i_update |= INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE;
994 p_item->input.i_duration =
995 p_access->info.i_size * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) ;
1000 playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
1001 p_playlist->status.i_view,
1002 p_playlist->status.p_item, NULL );
1005 vlc_object_release( p_playlist );