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 #define CDDA_MRL_PREFIX "cddax://"
45 #define free_and_dup(var, val) \
47 if (val) var=strdup(val);
50 static void GetCDDBInfo( access_t *p_access, cdda_data_t *p_cdda )
53 cddb_conn_t *conn = cddb_new();
54 const CdIo *p_cdio = p_cdda->p_cdio;
56 dbg_print( (INPUT_DBG_CALL), "" );
59 cddb_log_set_handler (uninit_log_handler);
64 msg_Warn( p_access, "Unable to initialize libcddb" );
68 cddb_set_email_address( conn,
69 config_GetPsz( p_access,
70 MODULE_STRING "-cddb-email") );
71 cddb_set_server_name( conn,
72 config_GetPsz( p_access,
73 MODULE_STRING "-cddb-server") );
74 cddb_set_server_port(conn,
75 config_GetInt( p_access,
76 MODULE_STRING "-cddb-port") );
78 /* Set the location of the local CDDB cache directory.
79 The default location of this directory is */
81 if (!config_GetInt( p_access, MODULE_STRING "-cddb-enable-cache" ))
82 cddb_cache_disable(conn);
84 cddb_cache_set_dir(conn,
85 config_GetPsz( p_access,
86 MODULE_STRING "-cddb-cachedir") );
88 cddb_set_timeout(conn,
89 config_GetInt( p_access, MODULE_STRING "-cddb-timeout") );
92 if (config_GetInt( p_access, MODULE_STRING "-cddb-httpd" ) )
94 cddb_http_enable(conn);
98 cddb_http_disable(conn);
101 p_cdda->cddb.disc = cddb_disc_new();
103 if (!p_cdda->cddb.disc)
105 msg_Err( p_access, "Unable to create CDDB disc structure." );
109 for(i = 0; i < p_cdda->i_tracks; i++)
111 track_t i_track = p_cdda->i_first_track + i;
112 cddb_track_t *t = cddb_track_new();
113 t->frame_offset = cdio_get_track_lba(p_cdio, i_track);
114 cddb_disc_add_track(p_cdda->cddb.disc, t);
117 p_cdda->cddb.disc->length =
118 cdio_get_track_lba(p_cdio, CDIO_CDROM_LEADOUT_TRACK)
119 / CDIO_CD_FRAMES_PER_SEC;
121 if (!cddb_disc_calc_discid(p_cdda->cddb.disc))
123 msg_Err( p_access, "CDDB disc ID calculation failed" );
127 i_matches = cddb_query(conn, p_cdda->cddb.disc);
132 msg_Warn( p_access, "Found %d matches in CDDB. Using first one.",
134 cddb_read(conn, p_cdda->cddb.disc);
136 if (p_cdda->i_debug & INPUT_DBG_CDDB)
137 cddb_disc_print(p_cdda->cddb.disc);
142 msg_Warn( p_access, "CDDB error: %s", cddb_error_str(errno));
150 #endif /*HAVE_LIBCDDB*/
152 #define add_meta_val(VLC_META, VAL) \
153 if ( p_cdda->p_meta && VAL) { \
154 vlc_meta_Add( p_cdda->p_meta, VLC_META, VAL ); \
155 dbg_print( INPUT_DBG_META, "field %s: %s\n", VLC_META, VAL ); \
158 #define add_cddb_meta(FIELD, VLC_META) \
159 add_meta_val(VLC_META, p_cdda->cddb.disc->FIELD);
161 #define add_cddb_meta_fmt(FIELD, FORMAT_SPEC, VLC_META) \
164 snprintf( psz_buf, sizeof(psz_buf)-1, FORMAT_SPEC, \
165 p_cdda->cddb.disc->FIELD ); \
166 psz_buf[sizeof(psz_buf)-1] = '\0'; \
167 add_meta_val(VLC_META, psz_buf); \
170 /* Adds a string-valued entry to the stream and media information if
171 the string is not null or the null string.
173 #define add_info_str(CATEGORY, TITLE, FIELD) \
174 if (FIELD && strlen(FIELD)) { \
175 input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY, \
176 _(TITLE), "%s", FIELD ); \
179 /* Adds a numeric-valued entry to the stream and media information
180 if the number is not zero. */
181 #define add_info_val(CATEGORY, TITLE, FMT, FIELD) \
183 input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY, \
184 _(TITLE), FMT, FIELD ); \
187 /* Adds a CDDB string-valued entry to the stream and media information
188 under category "Disc" if the string is not null or the null string.
190 #define add_cddb_disc_info_str(TITLE, FIELD) \
191 add_info_str("Disc", TITLE, p_cdda->cddb.disc->FIELD)
193 /* Adds a CDDB numeric-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_val(TITLE, FMT, FIELD) \
197 add_info_val("Disc", TITLE, FMT, p_cdda->cddb.disc->FIELD)
199 /* Adds a CD-Text 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_cdtext_info_str(CATEGORY, TITLE, INDEX, FIELD) \
203 add_info_str(CATEGORY, TITLE, p_cdda->p_cdtext[INDEX]->field[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_disc_info_str(TITLE, FIELD) \
209 add_cdtext_info_str("Disc", TITLE, 0, FIELD)
213 Gets and saves Meta Information about the CD-DA.
215 In the Control routine, we handle Meta Information requests and
216 basically copy what we've saved here.
218 Meta information is also used elsewhere such as in "stream and
219 media info" or in playlist info. The intialization of CD-Text or CDDB
222 void CDDAMetaInfo( access_t *p_access, int i_track, /*const*/ char *psz_mrl )
224 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
225 char *psz_meta_title = psz_mrl;
226 char *psz_meta_artist = NULL;
228 if ( ! p_cdda ) return;
230 p_cdda->psz_mcn = cdio_get_mcn(p_cdda->p_cdio);
231 p_cdda->p_meta = vlc_meta_New();
234 if ( p_cdda->b_cddb_enabled )
236 GetCDDBInfo(p_access, p_cdda);
237 if ( p_cdda->cddb.disc )
241 psz_meta_title = p_cdda->cddb.disc->title;
242 psz_meta_artist = p_cdda->cddb.disc->artist;
244 input_Control( p_cdda->p_input, INPUT_SET_NAME,
245 p_cdda->cddb.disc->artist );
249 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
253 if( t->title != NULL )
255 add_meta_val( VLC_META_TITLE, t->title );
257 if( t->artist != NULL )
259 add_meta_val( VLC_META_ARTIST, t->artist );
263 add_cddb_meta(genre, VLC_META_GENRE);
264 add_cddb_meta_fmt(year, "%d", VLC_META_DATE );
269 #endif /*HAVE_LIBCDDB*/
273 track_t i = p_cdda->i_tracks;
274 const int i_first_track = p_cdda->i_first_track;
275 char psz_buffer[MSTRTIME_MAX_SIZE];
277 (p_cdda->lsn[i_first_track+i] - p_cdda->lsn[i_first_track])
278 / CDIO_CD_FRAMES_PER_SEC;
280 dbg_print( INPUT_DBG_META, "Duration %ld, tracks %d",
281 (long int) i_duration, p_cdda->i_tracks );
282 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
283 _("Disc"), _("Duration"), "%s",
284 secstotimestr( psz_buffer, i_duration ) );
286 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
287 _("Disc"), _("Tracks"), "%d", p_cdda->i_tracks );
290 if (p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
292 add_cddb_disc_info_str("Artist (CDDB)", artist);
293 add_cddb_disc_info_str("Genre (CDDB)", genre);
294 add_cddb_disc_info_str("Extended Data (CDDB)", ext_data);
295 add_cddb_disc_info_val("Year (CDDB)", "%d", year);
296 add_cddb_disc_info_val("Disc ID (CDDB)", "%x", discid);
297 add_cddb_disc_info_str("Title (CDDB)", title);
298 add_info_str("Disc", "Category (CDDB)",
299 CDDB_CATEGORY[p_cdda->cddb.disc->category]);
302 #endif /*HAVE_LIBCDDB*/
304 p_cdda->p_cdtext[0] = cdio_get_cdtext(p_cdda->p_cdio, 0);
305 if (p_cdda->p_cdtext[0])
309 add_cdtext_disc_info_str("Arranger (CD-Text)", CDTEXT_ARRANGER);
310 add_cdtext_disc_info_str("Composer (CD-Text)", CDTEXT_COMPOSER);
311 add_cdtext_disc_info_str("Disc ID (CD-Text)", CDTEXT_DISCID);
312 add_cdtext_disc_info_str("Genre (CD-Text)", CDTEXT_GENRE);
313 add_cdtext_disc_info_str("Message (CD-Text)", CDTEXT_MESSAGE);
314 add_cdtext_disc_info_str("Performer (CD-Text)", CDTEXT_PERFORMER);
315 add_cdtext_disc_info_str("Songwriter (CD-Text)", CDTEXT_SONGWRITER);
316 add_cdtext_disc_info_str("Title (CD-Text)", CDTEXT_TITLE);
318 psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
319 if (psz_field && strlen(psz_field)) {
320 psz_meta_title = psz_field;
322 psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
323 if (psz_field && strlen(psz_field)) {
324 psz_meta_artist = psz_field;
329 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
331 char psz_track[TITLE_MAX];
332 const track_t i_track = i_first_track + i;
333 mtime_t i_duration = (p_cdda->lsn[i_track+1] -
334 p_cdda->lsn[i_track])
335 / CDIO_CD_FRAMES_PER_SEC;
336 snprintf(psz_track, TITLE_MAX, "%s %02d", _("Track"), i_track);
338 input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
340 secstotimestr( psz_buffer, i_duration ) );
342 p_cdda->p_cdtext[i_track] =
343 cdio_get_cdtext(p_cdda->p_cdio, i_track);
345 if (p_cdda->p_cdtext[i_track])
347 add_cdtext_info_str( psz_track, "Arranger (CD-Text)",
348 i_track, CDTEXT_ARRANGER);
349 add_cdtext_info_str( psz_track, "Composer (CD-Text)",
350 i_track, CDTEXT_COMPOSER);
351 add_cdtext_info_str( psz_track, "Disc ID (CD-Text)",
352 i_track, CDTEXT_DISCID);
353 add_cdtext_info_str( psz_track, "Genre (CD-Text)",
354 i_track, CDTEXT_GENRE);
355 add_cdtext_info_str( psz_track, "Message (CD-Text)",
356 i_track, CDTEXT_MESSAGE);
357 add_cdtext_info_str( psz_track, "Performer (CD-Text)",
358 i_track, CDTEXT_PERFORMER);
359 add_cdtext_info_str( psz_track, "Songwriter (CD-Text)",
360 i_track, CDTEXT_SONGWRITER);
361 add_cdtext_info_str( psz_track, "Title (CD-Text)",
362 i_track, CDTEXT_TITLE);
366 if (p_cdda->b_cddb_enabled)
368 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i);
371 add_info_str(psz_track, "Artist (CDDB)", t->artist);
372 add_info_str(psz_track, "Title (CDDB)", t->title);
373 add_info_str(psz_track, "Extended Data (CDDB)",
377 #endif /*HAVE_LIBCDDB*/
380 /* Above we should have set psz_meta_title and psz_meta_artist
381 to CDDB or CD-Text values or the default value depending on
382 availablity and user preferences. So now add it to VLC's meta.
384 add_meta_val( VLC_META_TITLE, psz_meta_title );
386 add_meta_val( VLC_META_ARTIST, psz_meta_artist );
390 #define add_format_str_info(val) \
392 const char *str = val; \
397 strncat(tp, str, TEMP_STR_LEN-(tp-temp_str)); \
400 saw_control_prefix = false; \
404 #define add_format_num_info(val, fmt) \
408 sprintf(num_str, fmt, val); \
409 len=strlen(num_str); \
411 strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); \
414 saw_control_prefix = false; \
419 cdda_data_t *p_cdda, char *psz_cdtext)
421 /* We either don't have CD-Text info, or we do but we prefer to get CDDB
422 which means CDDB has been enabled and we were able to retrieve the info.*/
424 return !psz_cdtext ||
425 (!p_cdda->b_cdtext_prefer && p_cdda->b_cddb_enabled && p_cdda->cddb.disc);
433 Take a format string and expand escape sequences, that is sequences that
434 begin with %, with information from the current CD.
435 The expanded string is returned. Here is a list of escape sequences:
437 %a : The album artist **
438 %A : The album information **
443 %m : The CD-DA Media Catalog Number (MCN)
444 %n : The number of tracks on the CD
445 %p : The artist/performer/composer in the track **
446 %T : The track number **
447 %s : Number of seconds in this track
448 %t : The track name or MRL if no name **
449 %Y : The year 19xx or 20xx **
453 CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
454 const char format_str[], const char *psz_mrl, track_t i_track)
456 #define TEMP_STR_SIZE 256
457 #define TEMP_STR_LEN (TEMP_STR_SIZE-1)
458 static char temp_str[TEMP_STR_SIZE];
460 char * tp = temp_str;
461 vlc_bool_t saw_control_prefix = false;
462 size_t format_len = strlen(format_str);
464 memset(temp_str, 0, TEMP_STR_SIZE);
466 for (i=0; i<format_len; i++)
470 if (!saw_control_prefix && format_str[i] != '%')
472 *tp++ = format_str[i];
473 saw_control_prefix = false;
477 switch(format_str[i])
480 if (saw_control_prefix)
484 saw_control_prefix = !saw_control_prefix;
488 if (p_cdda->p_cdtext[0]
489 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
490 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
491 if (want_cddb_info(p_cdda, psz))
492 psz = p_cdda->cddb.disc->artist;
495 if (p_cdda->p_cdtext[0]
496 && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
497 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
498 if (want_cddb_info(p_cdda, psz))
499 psz = p_cdda->cddb.disc->title;
502 if (!p_cdda->b_cddb_enabled) goto not_special;
503 if (p_cdda->cddb.disc)
505 CDDB_CATEGORY[p_cdda->cddb.disc->category]);
508 if (p_cdda->p_cdtext[0]
509 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
510 psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
511 if (want_cddb_info(p_cdda, psz))
512 psz = p_cdda->cddb.disc->genre;
515 if (p_cdda->p_cdtext[0]
516 && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
517 psz = p_cdda->p_cdtext[0]->field[CDTEXT_DISCID];
518 if (want_cddb_info(p_cdda, psz)) {
519 add_format_num_info(p_cdda->cddb.disc->discid, "%x");
521 add_format_str_info(psz);
524 if (!p_cdda->b_cddb_enabled) goto not_special;
525 if (p_cdda->cddb.disc)
526 add_format_num_info(p_cdda->cddb.disc->year, "%5d");
529 if (p_cdda && p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
531 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
533 if (t != NULL && t->title != NULL) {
534 add_format_str_info(t->title);
536 add_format_str_info(psz_mrl);
539 if (p_cdda->p_cdtext[i_track]
540 && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE]) {
541 add_format_str_info(p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE]);
544 add_format_str_info(psz_mrl);
548 if (p_cdda->p_cdtext[i_track]
549 && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
550 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
551 if (want_cddb_info(p_cdda, psz))
553 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
555 if (t != NULL && t->artist != NULL)
560 if (p_cdda->p_cdtext[i_track]
561 && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
562 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
563 if (want_cddb_info(p_cdda, psz))
565 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
567 if (t != NULL && t->ext_data != NULL)
573 if (p_cdda->b_cddb_enabled)
575 char psz_buffer[MSTRTIME_MAX_SIZE];
576 mtime_t i_duration = (p_cdda->lsn[i_track+1] -
577 p_cdda->lsn[i_track])
578 / CDIO_CD_FRAMES_PER_SEC;
579 add_format_str_info(secstotimestr( psz_buffer,
581 } else goto not_special;
585 if (p_cdda->p_cdtext[0]
586 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
587 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
590 if (p_cdda->p_cdtext[0]
591 && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
592 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
595 if (p_cdda->p_cdtext[0]
596 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
597 psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
600 if (p_cdda->p_cdtext[0]
601 && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
602 add_format_str_info(p_cdda->p_cdtext[0]->field[CDTEXT_DISCID]);
605 if (p_cdda->p_cdtext[i_track]
606 && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
607 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
610 if (p_cdda->p_cdtext[i_track]
611 && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE])
612 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE];
617 if (p_cdda->p_cdtext[i_track]
618 && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
619 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
622 #endif /*HAVE_LIBCDDB*/
625 add_format_str_info(psz_mrl);
629 add_format_str_info(p_cdda->psz_mcn);
633 add_format_num_info(p_cdda->i_tracks, "%d");
637 add_format_num_info(i_track, "%02d");
641 add_format_str_info(psz);
648 *tp++ = format_str[i];
649 saw_control_prefix = false;
652 return strdup(temp_str);
655 /* Adds a string-valued entry to the playlist information under "Track"
656 if the string is not null or the null string.
658 #define add_playlist_track_info_str(TITLE, FIELD) \
659 if (FIELD && strlen(FIELD)) \
661 playlist_ItemAddInfo( p_item, _("Track"), _(TITLE), \
666 CDDACreatePlaylistItem( const access_t *p_access, cdda_data_t *p_cdda,
667 playlist_t *p_playlist, playlist_item_t *p_item,
668 track_t i_track, char *psz_mrl, int psz_mrl_max,
669 const char *psz_source )
671 mtime_t i_duration = (p_cdda->lsn[i_track+1] - p_cdda->lsn[i_track])
672 * (1000000 / CDIO_CD_FRAMES_PER_SEC) ;
674 char *config_varname = MODULE_STRING "-title-format";
676 playlist_item_t *p_child = NULL;
684 if (p_cdda->b_cddb_enabled)
686 config_varname = MODULE_STRING "-cddb-title-format";
688 #endif /*HAVE_LIBCDDB*/
691 snprintf(psz_mrl, psz_mrl_max, "%s%s@T%u",
692 CDDA_MRL_PREFIX, psz_source, i_track);
694 psz_title = CDDAFormatStr( p_access, p_cdda,
695 config_GetPsz( p_access, config_varname ),
698 dbg_print( INPUT_DBG_META, "mrl: %s, title: %s, duration, %ld",
699 psz_mrl, psz_title, (long int) i_duration / 1000000 );
701 p_child = playlist_ItemNew( p_playlist, psz_mrl, psz_title );
702 p_child->input.b_fixed_name = VLC_TRUE;
703 p_child->input.i_duration = i_duration;
705 if( !p_child ) return NULL;
707 playlist_NodeAddItem( p_playlist, p_child,
708 p_item->pp_parents[0]->i_view,
709 p_item, PLAYLIST_APPEND, PLAYLIST_END );
710 playlist_CopyParents( p_item, p_child );
715 int CDDAAddMetaToItem( access_t *p_access, cdda_data_t *p_cdda,
716 playlist_item_t *p_item, const char *psz_source,
717 int i_track, vlc_bool_t b_single )
719 vlc_mutex_lock( &p_item->input.lock );
721 add_playlist_track_info_str("Source", psz_source);
722 playlist_ItemAddInfo( p_item, _("Track"), _("Track Number"),
725 if (p_cdda->p_cdtext[0])
727 const cdtext_t *p = p_cdda->p_cdtext[0];
728 add_playlist_track_info_str("Disc Arranger (CD-Text)",
729 p->field[CDTEXT_ARRANGER]);
730 add_playlist_track_info_str("Disc Composer (CD-Text)",
731 p->field[CDTEXT_COMPOSER]);
732 add_playlist_track_info_str("Disc ID (CD-Text)",
733 p->field[CDTEXT_DISCID]);
734 add_playlist_track_info_str("Disc Genre (CD-Text)",
735 p->field[CDTEXT_GENRE]);
736 add_playlist_track_info_str("Disc Message (CD-Text)",
737 p->field[CDTEXT_MESSAGE]);
738 add_playlist_track_info_str("Disc Performer (CD-Text)",
739 p->field[CDTEXT_PERFORMER]);
740 add_playlist_track_info_str("Disc Songwriter (CD-Text)",
741 p->field[CDTEXT_SONGWRITER]);
742 add_playlist_track_info_str("Disc Title (CD-Text)",
743 p->field[CDTEXT_TITLE]);
746 if (p_cdda->p_cdtext[i_track])
748 const cdtext_t *p = p_cdda->p_cdtext[i_track];
749 add_playlist_track_info_str("Arranger (CD-Text)",
750 p->field[CDTEXT_ARRANGER]);
751 add_playlist_track_info_str("Composer (CD-Text)",
752 p->field[CDTEXT_COMPOSER]);
753 add_playlist_track_info_str("Genre (CD-Text)",
754 p->field[CDTEXT_GENRE]);
755 add_playlist_track_info_str("Message (CD-Text)",
756 p->field[CDTEXT_MESSAGE]);
757 add_playlist_track_info_str("Performer (CD-Text)",
758 p->field[CDTEXT_PERFORMER]);
759 add_playlist_track_info_str("Songwriter (CD-Text)",
760 p->field[CDTEXT_SONGWRITER]);
761 add_playlist_track_info_str("Title (CD-Text)",
762 p->field[CDTEXT_TITLE]);
766 if (p_cdda->b_cddb_enabled)
768 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
769 i_track-p_cdda->i_first_track);
771 add_playlist_track_info_str("Disc Album (CDDB)",
772 p_cdda->cddb.disc->title);
773 add_playlist_track_info_str("Disc Artist(s) (CDDB)",
774 p_cdda->cddb.disc->artist);
775 add_playlist_track_info_str("Disc Category (CDDB)",
776 CDDB_CATEGORY[p_cdda->cddb.disc->category]);
777 add_playlist_track_info_str("Disc Genre (CDDB)",
778 p_cdda->cddb.disc->genre);
780 if ( p_cdda->cddb.disc->discid )
782 playlist_ItemAddInfo( p_item, _("Track"), _("Disc ID (CDDB)"),
783 "%x", p_cdda->cddb.disc->discid );
785 if (p_cdda->cddb.disc->year != 0)
787 playlist_ItemAddInfo( p_item, _("Track"), _("Year (CDDB)"),
788 "%5d", p_cdda->cddb.disc->year );
794 add_playlist_track_info_str("Track Artist (CDDB)",
797 add_playlist_track_info_str("Track Title (CDDB)",
801 #endif /*HAVE_LIBCDDB*/
803 vlc_mutex_unlock( &p_item->input.lock );
809 CDDAFixupPlaylist( access_t *p_access, cdda_data_t *p_cdda,
810 const char *psz_source, vlc_bool_t b_single_track )
813 playlist_t * p_playlist;
814 char * psz_mrl = NULL;
815 unsigned int psz_mrl_max = strlen(CDDA_MRL_PREFIX) + strlen(psz_source) +
816 strlen("@T") + strlen("100") + 1;
817 const track_t i_first_track = p_cdda->i_first_track;
818 playlist_item_t *p_item;
819 vlc_bool_t b_play = VLC_FALSE;
822 p_cdda->b_cddb_enabled =
823 config_GetInt( p_access, MODULE_STRING "-cddb-enabled" );
824 if( b_single_track && !p_cdda->b_cddb_enabled )
831 psz_mrl = malloc( psz_mrl_max );
833 if( psz_mrl == NULL )
835 msg_Warn( p_access, "out of memory" );
839 p_playlist = (playlist_t *) vlc_object_find( p_access, VLC_OBJECT_PLAYLIST,
843 msg_Warn( p_access, "can't find playlist" );
850 snprintf(psz_mrl, psz_mrl_max, "%s%s@T%u", CDDA_MRL_PREFIX,
851 psz_source, p_cdda->i_track);
852 CDDAMetaInfo( p_access, p_cdda->i_track, psz_mrl );
856 snprintf(psz_mrl, psz_mrl_max, "%s%s", CDDA_MRL_PREFIX, psz_source);
857 CDDAMetaInfo( p_access, -1, psz_mrl );
860 p_item = playlist_ItemGetByInput( p_playlist,
861 ((input_thread_t *)p_access->p_parent)->input.p_item );
863 if( p_item == p_playlist->status.p_item && !b_single_track )
874 /*May fill out more information when the playlist user interface becomes
877 track_t i_track = p_cdda->i_track;
879 input_title_t *t = p_cdda->p_title[0] = //i_track-i_first_track] =
880 vlc_input_title_New();
882 asprintf( &t->psz_name, _("Track %i"), i_track );
883 t->i_size = p_access->info.i_size =
884 ( p_cdda->lsn[i_track+1] - p_cdda->lsn[i_track] ) *
885 (int64_t) CDIO_CD_FRAMESIZE_RAW;
887 t->i_length = I64C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
890 CDDAAddMetaToItem( p_access, p_cdda, p_item, psz_source, i_track,
893 p_cdda->i_titles = 1;
894 p_access->info.i_size =
895 (p_cdda->lsn[p_cdda->i_track]
896 - p_cdda->lsn[i_first_track+1]) * (int64_t) CDIO_CD_FRAMESIZE_RAW;
897 p_item->input.i_duration =
898 (p_cdda->lsn[p_cdda->i_track]
899 - p_cdda->lsn[i_first_track+1]) / CDIO_CD_FRAMES_PER_SEC;
903 playlist_ItemToNode( p_playlist, p_item );
904 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
906 playlist_item_t *p_child;
907 const track_t i_track = i_first_track + i;
908 input_title_t *t = p_cdda->p_title[i] = vlc_input_title_New();
910 asprintf( &t->psz_name, _("Track %i"), i_track );
911 t->i_size = ( p_cdda->lsn[i_track+1] - p_cdda->lsn[i_track] ) *
912 (int64_t) CDIO_CD_FRAMESIZE_RAW;
914 t->i_length = I64C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
916 p_child = CDDACreatePlaylistItem( p_access, p_cdda, p_playlist,
919 psz_mrl_max, psz_source );
920 CDDAAddMetaToItem( p_access, p_cdda, p_child, psz_source,
923 p_cdda->i_titles = p_cdda->i_tracks; /* should be +1 */
924 p_access->info.i_size =
925 (p_cdda->lsn[i_first_track + p_cdda->i_tracks]
926 - p_cdda->lsn[i_first_track]) * (int64_t) CDIO_CD_FRAMESIZE_RAW;
927 p_item->input.i_duration =
928 (p_cdda->lsn[i_first_track + p_cdda->i_tracks]
929 - p_cdda->lsn[i_first_track]) / CDIO_CD_FRAMES_PER_SEC;
934 playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
935 p_playlist->status.i_view,
936 p_playlist->status.p_item, NULL );
939 vlc_object_release( p_playlist );