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(FIELD, 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(FIELD, 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(FIELD, 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 CDDA Meta Information about the CD.
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 )
224 cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
226 if ( ! p_cdda ) return;
228 p_cdda->psz_mcn = cdio_get_mcn(p_cdda->p_cdio);
231 if ( p_cdda->b_cddb_enabled )
233 GetCDDBInfo(p_access, p_cdda);
234 if ( p_cdda->cddb.disc )
236 p_cdda->p_meta = vlc_meta_New();
239 add_cddb_meta(title, VLC_META_TITLE);
240 add_cddb_meta(artist, VLC_META_ARTIST);
241 input_Control( p_cdda->p_input, INPUT_SET_NAME,
242 p_cdda->cddb.disc->artist );
246 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
250 if( t->title != NULL )
252 add_meta_val( NULL, VLC_META_TITLE, t->title );
254 if( t->artist != NULL )
256 add_meta_val( NULL, VLC_META_ARTIST, t->artist );
260 add_cddb_meta(genre, VLC_META_GENRE);
261 add_cddb_meta_fmt(year, "%d", VLC_META_DATE );
265 #endif /*HAVE_LIBCDDB*/
268 track_t i = p_cdda->i_tracks;
269 const int i_first_track = p_cdda->i_first_track;
270 char psz_buffer[MSTRTIME_MAX_SIZE];
272 (p_cdda->lsn[i_first_track+i] - p_cdda->lsn[i_first_track])
273 / CDIO_CD_FRAMES_PER_SEC;
275 dbg_print( INPUT_DBG_META, "Duration %ld", (long int) i_duration );
276 input_Control( p_cdda->p_input, INPUT_ADD_INFO,
277 _("Disc"), _("Duration"), "%s",
278 secstotimestr( psz_buffer, i_duration ) );
281 if (p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
283 add_cddb_disc_info_str("Artist (CDDB)", artist);
284 add_cddb_disc_info_str("Genre (CDDB)", genre);
285 add_cddb_disc_info_str("Extended Data (CDDB)", ext_data);
286 add_cddb_disc_info_val("Year (CDDB)", "%d", year);
287 add_cddb_disc_info_val("Disc ID (CDDB)", "%x", discid);
288 add_cddb_disc_info_str("Title (CDDB)", title);
289 add_info_str("Disc", "Category (CDDB)",
290 CDDB_CATEGORY[p_cdda->cddb.disc->category]);
293 #endif /*HAVE_LIBCDDB*/
295 p_cdda->p_cdtext[0] = cdio_get_cdtext(p_cdda->p_cdio, 0);
296 if (p_cdda->p_cdtext[0])
298 add_cdtext_disc_info_str("Arranger (CD-Text)", CDTEXT_ARRANGER);
299 add_cdtext_disc_info_str("Composer (CD-Text)", CDTEXT_COMPOSER);
300 add_cdtext_disc_info_str("Disc ID (CD-Text)", CDTEXT_DISCID);
301 add_cdtext_disc_info_str("Genre (CD-Text)", CDTEXT_GENRE);
302 add_cdtext_disc_info_str("Message (CD-Text)", CDTEXT_MESSAGE);
303 add_cdtext_disc_info_str("Performer (CD-Text)", CDTEXT_PERFORMER);
304 add_cdtext_disc_info_str("Songwriter (CD-Text)", CDTEXT_SONGWRITER);
305 add_cdtext_disc_info_str("Title (CD-Text)", CDTEXT_TITLE);
310 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
312 char psz_track[TITLE_MAX];
313 const track_t i_track = i_first_track + i;
314 mtime_t i_duration = (p_cdda->lsn[i_track+1] -
315 p_cdda->lsn[i_track])
316 / CDIO_CD_FRAMES_PER_SEC;
317 snprintf(psz_track, TITLE_MAX, "%s %02d", _("Track"), i_track);
318 input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
320 secstotimestr( psz_buffer, i_duration ) );
322 p_cdda->p_cdtext[i_track] =
323 cdio_get_cdtext(p_cdda->p_cdio, i_track);
325 if (p_cdda->p_cdtext[i_track])
327 add_cdtext_info_str( psz_track, "Arranger (CD-Text)",
328 i_track, CDTEXT_ARRANGER);
329 add_cdtext_info_str( psz_track, "Composer (CD-Text)",
330 i_track, CDTEXT_COMPOSER);
331 add_cdtext_info_str( psz_track, "Disc ID (CD-Text)",
332 i_track, CDTEXT_DISCID);
333 add_cdtext_info_str( psz_track, "Genre (CD-Text)",
334 i_track, CDTEXT_GENRE);
335 add_cdtext_info_str( psz_track, "Message (CD-Text)",
336 i_track, CDTEXT_MESSAGE);
337 add_cdtext_info_str( psz_track, "Performer (CD-Text)",
338 i_track, CDTEXT_PERFORMER);
339 add_cdtext_info_str( psz_track, "Songwriter (CD-Text)",
340 i_track, CDTEXT_SONGWRITER);
341 add_cdtext_info_str( psz_track, "Title (CD-Text)",
342 i_track, CDTEXT_TITLE);
346 if (p_cdda->b_cddb_enabled)
348 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i);
351 add_info_str(psz_track, "Artist (CDDB)", t->artist);
352 add_info_str(psz_track, "Title (CDDB)", t->title);
353 add_info_str(psz_track, "Extended Data (CDDB)",
357 #endif /*HAVE_LIBCDDB*/
363 #define add_format_str_info(val) \
365 const char *str = val; \
370 strncat(tp, str, TEMP_STR_LEN-(tp-temp_str)); \
373 saw_control_prefix = false; \
377 #define add_format_num_info(val, fmt) \
381 sprintf(num_str, fmt, val); \
382 len=strlen(num_str); \
384 strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); \
387 saw_control_prefix = false; \
391 Take a format string and expand escape sequences, that is sequences that
392 begin with %, with information from the current CD.
393 The expanded string is returned. Here is a list of escape sequences:
395 %a : The album artist **
396 %A : The album information **
401 %m : The CD-DA Media Catalog Number (MCN)
402 %n : The number of tracks on the CD
403 %p : The artist/performer/composer in the track **
404 %T : The track number **
405 %s : Number of seconds in this track
407 %Y : The year 19xx or 20xx **
411 CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
412 const char format_str[], const char *mrl, track_t i_track)
414 #define TEMP_STR_SIZE 256
415 #define TEMP_STR_LEN (TEMP_STR_SIZE-1)
416 static char temp_str[TEMP_STR_SIZE];
418 char * tp = temp_str;
419 vlc_bool_t saw_control_prefix = false;
420 size_t format_len = strlen(format_str);
422 memset(temp_str, 0, TEMP_STR_SIZE);
424 for (i=0; i<format_len; i++)
427 if (!saw_control_prefix && format_str[i] != '%')
429 *tp++ = format_str[i];
430 saw_control_prefix = false;
434 switch(format_str[i])
437 if (saw_control_prefix)
441 saw_control_prefix = !saw_control_prefix;
445 if (!p_cdda->b_cddb_enabled) goto not_special;
446 if (p_cdda->cddb.disc)
447 add_format_str_info(p_cdda->cddb.disc->artist);
450 if (!p_cdda->b_cddb_enabled) goto not_special;
451 if (p_cdda->cddb.disc)
452 add_format_str_info(p_cdda->cddb.disc->title);
455 if (!p_cdda->b_cddb_enabled) goto not_special;
456 if (p_cdda->cddb.disc)
458 CDDB_CATEGORY[p_cdda->cddb.disc->category]);
461 if (!p_cdda->b_cddb_enabled) goto not_special;
462 if (p_cdda->cddb.disc)
463 add_format_str_info(p_cdda->cddb.disc->genre);
466 if (!p_cdda->b_cddb_enabled) goto not_special;
467 if (p_cdda->cddb.disc)
468 add_format_num_info(p_cdda->cddb.disc->discid, "%x");
471 if (!p_cdda->b_cddb_enabled) goto not_special;
472 if (p_cdda->cddb.disc)
473 add_format_num_info(p_cdda->cddb.disc->year, "%5d");
476 if (p_cdda && p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
478 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
480 if (t != NULL && t->title != NULL)
481 add_format_str_info(t->title);
483 else goto not_special;
486 if (p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
488 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
490 if (t != NULL && t->artist != NULL)
491 add_format_str_info(t->artist);
492 } else goto not_special;
495 if (p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
497 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
499 if (t != NULL && t->ext_data != NULL)
500 add_format_str_info(t->ext_data);
501 } else goto not_special;
504 if (p_cdda->b_cddb_enabled)
506 char psz_buffer[MSTRTIME_MAX_SIZE];
507 mtime_t i_duration = (p_cdda->lsn[i_track+1] -
508 p_cdda->lsn[i_track])
509 / CDIO_CD_FRAMES_PER_SEC;
510 add_format_str_info(secstotimestr( psz_buffer,
512 } else goto not_special;
514 #endif /*HAVE_LIBCDDB*/
517 add_format_str_info(mrl);
521 add_format_str_info(p_cdda->psz_mcn);
525 add_format_num_info(p_cdda->i_tracks, "%d");
529 add_format_num_info(i_track, "%02d");
536 *tp++ = format_str[i];
537 saw_control_prefix = false;
540 return strdup(temp_str);
543 /* Adds a string-valued entry to the playlist information under "Track"
544 if the string is not null or the null string.
546 #define add_playlist_track_info_str(TITLE, FIELD) \
547 if (FIELD && strlen(FIELD)) \
549 playlist_ItemAddInfo( p_item, _("Track"), _(TITLE), \
554 CDDACreatePlaylistItem( const access_t *p_access, cdda_data_t *p_cdda,
555 playlist_t *p_playlist, playlist_item_t *p_item,
556 track_t i_track, char *psz_mrl, int psz_mrl_max,
557 const char *psz_source )
559 mtime_t i_duration = (p_cdda->lsn[i_track+1] - p_cdda->lsn[i_track])
560 * (1000000 / CDIO_CD_FRAMES_PER_SEC) ;
562 char *config_varname = MODULE_STRING "-title-format";
564 playlist_item_t *p_child = NULL;
572 if (p_cdda->b_cddb_enabled)
574 config_varname = MODULE_STRING "-cddb-title-format";
576 #endif /*HAVE_LIBCDDB*/
579 psz_title = CDDAFormatStr( p_access, p_cdda,
580 config_GetPsz( p_access, config_varname ),
583 snprintf(psz_mrl, psz_mrl_max, "%s%s@T%u",
584 CDDA_MRL_PREFIX, psz_source, i_track);
586 dbg_print( INPUT_DBG_META, "mrl: %s, title: %s, duration, %ld",
587 psz_mrl, psz_title, (long int) i_duration / 1000000 );
589 p_child = playlist_ItemNew( p_playlist, psz_mrl, psz_title );
590 p_child->input.b_fixed_name = VLC_TRUE;
592 if( !p_child ) return NULL;
594 playlist_NodeAddItem( p_playlist, p_child,
595 p_item->pp_parents[0]->i_view,
596 p_item, PLAYLIST_APPEND, PLAYLIST_END );
597 playlist_CopyParents( p_item, p_child );
602 int CDDAAddMetaToItem( access_t *p_access, cdda_data_t *p_cdda,
603 playlist_item_t *p_item, const char *psz_source,
604 int i_track, vlc_bool_t b_single )
606 vlc_mutex_lock( &p_item->input.lock );
608 add_playlist_track_info_str("Source", psz_source);
609 playlist_ItemAddInfo( p_item, _("Track"), _("Track Number"),
612 if (p_cdda->p_cdtext[0])
614 const cdtext_t *p = p_cdda->p_cdtext[0];
615 add_playlist_track_info_str("Disc Arranger (CD-Text)",
616 p->field[CDTEXT_ARRANGER]);
617 add_playlist_track_info_str("Disc Composer (CD-Text)",
618 p->field[CDTEXT_COMPOSER]);
619 add_playlist_track_info_str("Disc ID (CD-Text)",
620 p->field[CDTEXT_DISCID]);
621 add_playlist_track_info_str("Disc Genre (CD-Text)",
622 p->field[CDTEXT_GENRE]);
623 add_playlist_track_info_str("Disc Message (CD-Text)",
624 p->field[CDTEXT_MESSAGE]);
625 add_playlist_track_info_str("Disc Performer (CD-Text)",
626 p->field[CDTEXT_PERFORMER]);
627 add_playlist_track_info_str("Disc Songwriter (CD-Text)",
628 p->field[CDTEXT_SONGWRITER]);
629 add_playlist_track_info_str("Disc Title (CD-Text)",
630 p->field[CDTEXT_TITLE]);
633 if (p_cdda->p_cdtext[i_track])
635 const cdtext_t *p = p_cdda->p_cdtext[i_track];
636 add_playlist_track_info_str("Arranger (CD-Text)",
637 p->field[CDTEXT_ARRANGER]);
638 add_playlist_track_info_str("Composer (CD-Text)",
639 p->field[CDTEXT_COMPOSER]);
640 add_playlist_track_info_str("Genre (CD-Text)",
641 p->field[CDTEXT_GENRE]);
642 add_playlist_track_info_str("Message (CD-Text)",
643 p->field[CDTEXT_MESSAGE]);
644 add_playlist_track_info_str("Performer (CD-Text)",
645 p->field[CDTEXT_PERFORMER]);
646 add_playlist_track_info_str("Songwriter (CD-Text)",
647 p->field[CDTEXT_SONGWRITER]);
648 add_playlist_track_info_str("Title (CD-Text)",
649 p->field[CDTEXT_TITLE]);
653 if (p_cdda->b_cddb_enabled)
655 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
656 i_track-p_cdda->i_first_track);
658 add_playlist_track_info_str("Disc Album (CDDB)",
659 p_cdda->cddb.disc->title);
660 add_playlist_track_info_str("Disc Artist(s) (CDDB)",
661 p_cdda->cddb.disc->artist);
662 add_playlist_track_info_str("Disc Category (CDDB)",
663 CDDB_CATEGORY[p_cdda->cddb.disc->category]);
664 add_playlist_track_info_str("Disc Genre (CDDB)",
665 p_cdda->cddb.disc->genre);
667 if ( p_cdda->cddb.disc->discid )
669 playlist_ItemAddInfo( p_item, _("Track"), _("Disc ID (CDDB)"),
670 "%x", p_cdda->cddb.disc->discid );
672 if (p_cdda->cddb.disc->year != 0)
674 playlist_ItemAddInfo( p_item, _("Track"), _("Year (CDDB)"),
675 "%5d", p_cdda->cddb.disc->year );
681 add_playlist_track_info_str("Track Artist (CDDB)",
684 add_playlist_track_info_str("Track Title (CDDB)",
688 #endif /*HAVE_LIBCDDB*/
690 vlc_mutex_unlock( &p_item->input.lock );
696 CDDAFixupPlaylist( access_t *p_access, cdda_data_t *p_cdda,
697 const char *psz_source, vlc_bool_t b_single_track )
700 playlist_t * p_playlist;
702 unsigned int psz_mrl_max = strlen(CDDA_MRL_PREFIX) + strlen(psz_source) +
703 strlen("@T") + strlen("100") + 1;
704 const track_t i_first_track = p_cdda->i_first_track;
705 playlist_item_t *p_item;
706 vlc_bool_t b_play = VLC_FALSE;
709 p_cdda->b_cddb_enabled =
710 config_GetInt( p_access, MODULE_STRING "-cddb-enabled" );
711 if( b_single_track && !p_cdda->b_cddb_enabled )
718 psz_mrl = malloc( psz_mrl_max );
720 if( psz_mrl == NULL )
722 msg_Warn( p_access, "out of memory" );
726 p_playlist = (playlist_t *) vlc_object_find( p_access, VLC_OBJECT_PLAYLIST,
730 msg_Warn( p_access, "can't find playlist" );
737 CDDAMetaInfo( p_access, p_cdda->i_track );
741 CDDAMetaInfo( p_access, -1 );
744 p_item = playlist_ItemGetByInput( p_playlist,
745 ((input_thread_t *)p_access->p_parent)->input.p_item );
747 if( p_item == p_playlist->status.p_item && !b_single_track )
758 /*May fill out more information when the playlist user interface becomes
761 track_t i_track = p_cdda->i_track;
763 input_title_t *t = p_cdda->p_title[0] = //i_track-i_first_track] =
764 vlc_input_title_New();
766 asprintf( &t->psz_name, _("Track %i"), i_track );
767 t->i_size = p_access->info.i_size =
768 ( p_cdda->lsn[i_track+1] - p_cdda->lsn[i_track] ) *
769 (int64_t) CDIO_CD_FRAMESIZE_RAW;
771 t->i_length = I64C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
774 CDDAAddMetaToItem( p_access, p_cdda, p_item, psz_source, i_track,
777 p_cdda->i_titles = 1;
781 playlist_ItemToNode( p_playlist, p_item );
782 for( i = 0 ; i < p_cdda->i_tracks ; i++ )
784 playlist_item_t *p_child;
785 const track_t i_track = i_first_track + i;
786 input_title_t *t = p_cdda->p_title[i] = vlc_input_title_New();
788 asprintf( &t->psz_name, _("Track %i"), i_track );
789 t->i_size = ( p_cdda->lsn[i_track+1] - p_cdda->lsn[i_track] ) *
790 (int64_t) CDIO_CD_FRAMESIZE_RAW;
792 t->i_length = I64C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
794 p_child = CDDACreatePlaylistItem( p_access, p_cdda, p_playlist,
797 psz_mrl_max, psz_source );
798 CDDAAddMetaToItem( p_access, p_cdda, p_child, psz_source,
801 p_cdda->i_titles = p_cdda->i_tracks; /* should be +1 */
802 p_access->info.i_size =
803 (p_cdda->lsn[i_first_track + p_cdda->i_tracks]
804 - p_cdda->lsn[i_first_track]) * (int64_t) CDIO_CD_FRAMESIZE_RAW;
809 playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
810 p_playlist->status.i_view,
811 p_playlist->status.p_item, NULL );
814 vlc_object_release( p_playlist );