info.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:33k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * info.c : CD digital audio input information routines
  3.  *****************************************************************************
  4.  * Copyright (C) 2004, 2005 the VideoLAN team
  5.  * $Id: b0de8285b6caadf5ab00dc43080eb408c684dd46 $
  6.  *
  7.  * Authors: Rocky Bernstein <rocky@panix.com>
  8.  *
  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.
  13.  *
  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.
  18.  *
  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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #include "callback.h"      /* FIXME - reorganize callback.h, cdda.h better */
  27. #include "cdda.h"          /* private structures. Also #includes vlc things */
  28. #warning playlist code must not be used here.
  29. #include <vlc_playlist.h>  /* Has to come *after* cdda.h */
  30. #include <cdio/cdio.h>
  31. #include <cdio/cdtext.h>
  32. #include <cdio/logging.h>
  33. #include <cdio/cd_types.h>
  34. #include "info.h"
  35. #include <errno.h>
  36. #include <assert.h>
  37. static char *CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
  38.                 const char format_str[], const char *psz_mrl,
  39.                 track_t i_track);
  40. static char *CDDAFormatMRL( const access_t *p_access, track_t i_track );
  41. #ifdef HAVE_LIBCDDB
  42. #define free_and_dup(var, val) 
  43.   if (var) free(var);          
  44.   if (val) var=strdup(val);
  45. /* Saves CDDB information about CD-DA via libcddb. */
  46. static void
  47. GetCDDBInfo( access_t *p_access, cdda_data_t *p_cdda )
  48. {
  49.     int i, i_matches;
  50.     cddb_conn_t  *conn = cddb_new();
  51.     const CdIo_t *p_cdio = p_cdda->p_cdio;
  52.     dbg_print( (INPUT_DBG_CALL), "" );
  53. #ifdef FIXME_NOW
  54.     cddb_log_set_handler (uninit_log_handler);
  55. #endif
  56.     if (!conn)
  57.     {
  58.         msg_Warn( p_access, "Unable to initialize libcddb" );
  59.         goto cddb_destroy;
  60.     }
  61.     char* psz_email = config_GetPsz( p_access, MODULE_STRING "-cddb-email");
  62.     char* psz_srv_name = config_GetPsz( p_access, MODULE_STRING "-cddb-server");
  63.     cddb_set_email_address( conn, psz_email );
  64.     cddb_set_server_name( conn, psz_srv_name );
  65.     cddb_set_server_port(conn,
  66.                          config_GetInt( p_access,
  67.                                         MODULE_STRING "-cddb-port") );
  68.     free( psz_email );
  69.     free( psz_srv_name );
  70.   /* Set the location of the local CDDB cache directory.
  71.      The default location of this directory is */
  72.     if (!config_GetInt( p_access, MODULE_STRING "-cddb-enable-cache" ))
  73.         cddb_cache_disable(conn);
  74.     char* psz_cache = config_GetPsz( p_access, MODULE_STRING "-cddb-cachedir");
  75.     cddb_cache_set_dir(conn, psz_cache );
  76.     free( psz_cache );
  77.     cddb_set_timeout(conn,
  78.                    config_GetInt( p_access, MODULE_STRING "-cddb-timeout") );
  79.     if (config_GetInt( p_access, MODULE_STRING "-cddb-httpd" ) )
  80.     {
  81.         cddb_http_enable(conn);
  82.     }
  83.     else
  84.     {
  85.         cddb_http_disable(conn);
  86.     }
  87.     p_cdda->cddb.disc = cddb_disc_new();
  88.     if (!p_cdda->cddb.disc)
  89.     {
  90.         msg_Err( p_access, "Unable to create CDDB disc structure." );
  91.         goto cddb_end;
  92.     }
  93.     for(i = 0; i < p_cdda->i_tracks; i++)
  94.     {
  95.         track_t i_track =  p_cdda->i_first_track + i;
  96.         cddb_track_t *t = cddb_track_new();
  97.     cddb_track_set_frame_offset(t,
  98.                     cdio_get_track_lba(p_cdio, i_track));
  99.         cddb_disc_add_track(p_cdda->cddb.disc, t);
  100.     }
  101.     cddb_disc_set_length(p_cdda->cddb.disc,
  102.              cdio_get_track_lba(p_cdio, CDIO_CDROM_LEADOUT_TRACK)
  103.              / CDIO_CD_FRAMES_PER_SEC);
  104.     if (!cddb_disc_calc_discid(p_cdda->cddb.disc))
  105.     {
  106.         msg_Err( p_access, "CDDB disc ID calculation failed" );
  107.         goto cddb_destroy;
  108.     }
  109.     i_matches = cddb_query(conn, p_cdda->cddb.disc);
  110.     if (i_matches > 0)
  111.     {
  112.         if (i_matches > 1)
  113.              msg_Warn( p_access, "Found %d matches in CDDB. Using first one.",
  114.                                  i_matches);
  115.         cddb_read(conn, p_cdda->cddb.disc);
  116.         if (p_cdda->i_debug & INPUT_DBG_CDDB)
  117.             cddb_disc_print(p_cdda->cddb.disc);
  118.     }
  119.     else
  120.     {
  121.         msg_Warn( p_access, "CDDB error: %s", cddb_error_str(errno));
  122.     }
  123. cddb_destroy:
  124.     cddb_destroy(conn);
  125. cddb_end: ;
  126. }
  127. #endif /*HAVE_LIBCDDB*/
  128. #define add_meta_val(VLC_META, VAL)                           
  129.   if ( p_cdda->p_meta && VAL) {                               
  130.     /*vlc_meta_Add( p_cdda->p_meta, VLC_META, VAL );*/        
  131.     dbg_print( INPUT_DBG_META, "field %s: %sn",              
  132.             input_MetaTypeToLocalizedString(VLC_META), VAL ); 
  133.   }                                                           
  134. #define add_cddb_meta(FIELD, VLC_META)                            
  135.   add_meta_val(VLC_META, cddb_disc_get_##FIELD(p_cdda->cddb.disc));
  136. #define add_cddb_meta_fmt(FIELD, FORMAT_SPEC, VLC_META)                 
  137.   {                                                                     
  138.     char psz_buf[100];                                                  
  139.     snprintf( psz_buf, sizeof(psz_buf)-1, FORMAT_SPEC,                  
  140.               cddb_disc_get_##FIELD(p_cdda->cddb.disc));                               
  141.     psz_buf[sizeof(psz_buf)-1] = '';                                  
  142.     add_meta_val(VLC_META, psz_buf);                    
  143.   }
  144. /* Adds a string-valued entry to the stream and media information if
  145.    the string is not null or the null string.
  146.  */
  147. #define add_info_str(CATEGORY, TITLE, FIELD)                      
  148.   if (FIELD && strlen(FIELD)) {                                   
  149.     input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY,     
  150.                    _(TITLE), "%s", FIELD );                       
  151.   }
  152. /* Adds a numeric-valued entry to the stream and media information
  153.    if the number is not zero. */
  154. #define add_info_val(CATEGORY, TITLE, FMT, FIELD)                 
  155.   if (FIELD) {                                                    
  156.     input_Control( p_cdda->p_input, INPUT_ADD_INFO, CATEGORY,     
  157.                    _(TITLE), FMT, FIELD );                        
  158.   }
  159. /* Adds a CDDB string-valued entry to the stream and media information
  160.    under category "Disc" if the string is not null or the null string.
  161.  */
  162. #define add_cddb_disc_info_str(TITLE, FIELD)                    
  163.   add_info_str("Disc", TITLE, cddb_disc_get_##FIELD(p_cdda->cddb.disc))
  164. /* Adds a CDDB numeric-valued entry to the stream and media information
  165.    under category "Disc" if the string is not null or the null string.
  166.  */
  167. #define add_cddb_disc_info_val(TITLE, FMT, FIELD)               
  168.   add_info_val("Disc", TITLE, FMT, cddb_disc_get_##FIELD(p_cdda->cddb.disc))
  169. /* Adds a CD-Text string-valued entry to the stream and media information
  170.    under category "Disc" if the string is not null or the null string.
  171.  */
  172. #define add_cdtext_info_str(CATEGORY, TITLE, INDEX, FIELD)              
  173.     add_info_str(CATEGORY, TITLE, p_cdda->p_cdtext[INDEX]->field[FIELD])
  174. /* Adds a CD-Text string-valued entry to the stream and media information
  175.    under category "Disc" if the string is not null or the null string.
  176.  */
  177. #define add_cdtext_disc_info_str(TITLE, FIELD) 
  178.   add_cdtext_info_str("Disc", TITLE, 0, FIELD)
  179. /*
  180.   Saves Meta Information about the CD-DA.
  181.   Meta information used in "stream and media info" or in playlist
  182.   info. The intialization of CD-Text or CDDB is done here though.
  183.   Therefore, this should be called before CDDAMetaInfo is called.
  184.  */
  185. static void
  186. CDDAMetaInfoInit( access_t *p_access )
  187. {
  188.     cdda_data_t *p_cdda   = (cdda_data_t *) p_access->p_sys;
  189.     if ( ! p_cdda ) return;
  190.     dbg_print( (INPUT_DBG_CALL), "p_cdda->i_tracks %d",
  191.            p_cdda->i_tracks );
  192.     p_cdda->psz_mcn = cdio_get_mcn(p_cdda->p_cdio);
  193. #if 0
  194.     p_cdda->p_meta = vlc_meta_New();
  195. #endif
  196. #ifdef HAVE_LIBCDDB
  197.     if ( p_cdda->b_cddb_enabled )
  198.     {
  199.         GetCDDBInfo(p_access, p_cdda);
  200.     }
  201. #endif /*HAVE_LIBCDDB*/
  202.  
  203. #define TITLE_MAX 30
  204.     {
  205.         track_t i_track;
  206.         for( i_track = 0 ; i_track < p_cdda->i_tracks ; i_track++ )
  207.         {
  208.             p_cdda->p_cdtext[i_track] =
  209.             cdio_get_cdtext(p_cdda->p_cdio, i_track);
  210.         }
  211.     }
  212. }
  213. /*
  214.  In the Control routine, we handle Meta Information requests and
  215.  basically copy what was saved in CDDAMetaInfoInit.
  216.  If i_track is CDIO_INVALID_TRACK we are probably asking about the entire
  217.  CD.
  218.  */
  219. void
  220. CDDAMetaInfo( access_t *p_access, track_t i_track )
  221. {
  222.     cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
  223.     char *psz_meta_title = CDDAFormatMRL( p_access, i_track );
  224.     char *psz_meta_artist = NULL;
  225.     if ( ! p_cdda ) return;
  226.     dbg_print( (INPUT_DBG_CALL), "i_track %d", i_track );
  227. #ifdef HAVE_LIBCDDB
  228.     /* Set up for Meta and name for CDDB access. */
  229.     if ( p_cdda->b_cddb_enabled &&  p_cdda->cddb.disc )
  230.     {
  231.         if( CDIO_INVALID_TRACK == i_track )
  232.         {
  233.             psz_meta_title  = (char *)cddb_disc_get_title(p_cdda->cddb.disc);
  234.             psz_meta_artist = (char *)cddb_disc_get_artist(p_cdda->cddb.disc);
  235.             if ( cddb_disc_get_genre(p_cdda->cddb.disc) &&
  236.                 strlen(cddb_disc_get_genre(p_cdda->cddb.disc)) )
  237.                 add_cddb_meta(genre, vlc_meta_Genre);
  238.             if ( 0 != cddb_disc_get_year(p_cdda->cddb.disc))
  239.                 add_cddb_meta_fmt(year, "%d", vlc_meta_Date );
  240.         }
  241.         else
  242.         {
  243.             cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i_track-1);
  244.             if (t != NULL )
  245.             {
  246.                 if( cddb_track_get_title(t) != NULL && ! p_cdda->b_nav_mode )
  247.                 {
  248.                     add_meta_val( vlc_meta_Title, cddb_track_get_title(t) );
  249.                 }
  250.                 if( cddb_track_get_artist(t) != NULL )
  251.                 {
  252.                     add_meta_val( vlc_meta_Artist, cddb_track_get_artist(t) );
  253.                 }
  254.             }
  255.         }
  256.     }
  257. #endif /*HAVE_LIBCDDB*/
  258. #define TITLE_MAX 30
  259.     {
  260.         track_t i = p_cdda->i_tracks;
  261.         const int i_first_track = p_cdda->i_first_track;
  262.         char psz_buffer[MSTRTIME_MAX_SIZE];
  263.         unsigned int i_track_frames =
  264.         cdio_get_track_lba(p_cdda->p_cdio, CDIO_CDROM_LEADOUT_TRACK);
  265.         mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
  266.         dbg_print( INPUT_DBG_META, "Duration %ld, tracks %d",
  267.            (long int) i_duration, p_cdda->i_tracks );
  268.         input_Control( p_cdda->p_input, INPUT_ADD_INFO,
  269.                        _("Disc"), _("Duration"), "%s",
  270.                        secstotimestr( psz_buffer, i_duration ) );
  271.         if (p_cdda->psz_mcn)
  272.         {
  273.             input_Control( p_cdda->p_input, INPUT_ADD_INFO,
  274.                 _("Disc"), _("Media Catalog Number (MCN)"), "%s",
  275.                 p_cdda->psz_mcn );
  276.             input_Control( p_cdda->p_input, INPUT_ADD_INFO,
  277.                 _("Disc"), _("Tracks"), "%d", p_cdda->i_tracks );
  278.         }
  279. #ifdef HAVE_LIBCDDB
  280.         if (p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
  281.         {
  282.             add_cddb_disc_info_str("Artist (CDDB)", artist);
  283.             if ( CDDB_CAT_INVALID != cddb_disc_get_category(p_cdda->cddb.disc) )
  284.                 add_info_str("Disc", "Category (CDDB)",
  285.                         CDDB_CATEGORY[cddb_disc_get_category(p_cdda->cddb.disc)]);
  286.             add_cddb_disc_info_val("Disc ID (CDDB)", "%x", discid);
  287.             add_cddb_disc_info_str("Extended Data (CDDB)", ext_data);
  288.             add_cddb_disc_info_str("Genre (CDDB)",  genre);
  289.             add_cddb_disc_info_str("Title (CDDB)",  title);
  290.             if ( 0 != cddb_disc_get_year(p_cdda->cddb.disc) )
  291.                 add_cddb_disc_info_val("Year (CDDB)", "%d", year);
  292.         }
  293. #endif /*HAVE_LIBCDDB*/
  294.         if (p_cdda->p_cdtext[0])
  295.         {
  296.             char *psz_field;
  297.             add_cdtext_disc_info_str("Arranger (CD-Text)",    CDTEXT_ARRANGER);
  298.             add_cdtext_disc_info_str("Composer (CD-Text)",    CDTEXT_COMPOSER);
  299.             add_cdtext_disc_info_str("Disc ID (CD-Text)",     CDTEXT_DISCID);
  300.             add_cdtext_disc_info_str("Genre (CD-Text)",       CDTEXT_GENRE);
  301.             add_cdtext_disc_info_str("Message (CD-Text)",     CDTEXT_MESSAGE);
  302.             add_cdtext_disc_info_str("Performer (CD-Text)",   CDTEXT_PERFORMER);
  303.             add_cdtext_disc_info_str("Songwriter (CD-Text)",  CDTEXT_SONGWRITER);
  304.             add_cdtext_disc_info_str("Title (CD-Text)",       CDTEXT_TITLE);
  305.             psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
  306.             if (psz_field && strlen(psz_field))
  307.                 psz_meta_title = psz_field;
  308.             psz_field = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
  309.             if (psz_field && strlen(psz_field))
  310.                 psz_meta_artist = psz_field;
  311.         }
  312.         for( i = 0 ; i < p_cdda->i_tracks ; i++ )
  313.         {
  314.             char psz_track[TITLE_MAX];
  315.             const track_t i_track = i_first_track + i;
  316.             unsigned int i_track_frames =
  317.             cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
  318.             cdio_get_track_lsn(p_cdda->p_cdio, i_track);
  319.             mtime_t i_duration = i_track_frames / CDIO_CD_FRAMES_PER_SEC;
  320.             char *psz_mrl = CDDAFormatMRL( p_access, i_track );
  321.             snprintf(psz_track, TITLE_MAX, "%s %02d", _("Track"), i_track);
  322.             input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
  323.                 _("Duration"), "%s",
  324.                 secstotimestr( psz_buffer, i_duration ) );
  325.             input_Control( p_cdda->p_input, INPUT_ADD_INFO, psz_track,
  326.                 _("MRL"), "%s", psz_mrl );
  327.             free(psz_mrl);
  328.             if (p_cdda->p_cdtext[i_track])
  329.             {
  330.                 add_cdtext_info_str( psz_track, "Arranger (CD-Text)",
  331.                         i_track, CDTEXT_ARRANGER);
  332.                 add_cdtext_info_str( psz_track, "Composer (CD-Text)",
  333.                         i_track, CDTEXT_COMPOSER);
  334.                 add_cdtext_info_str( psz_track, "Disc ID (CD-Text)",
  335.                         i_track, CDTEXT_DISCID);
  336.                 add_cdtext_info_str( psz_track, "Genre (CD-Text)",
  337.                         i_track, CDTEXT_GENRE);
  338.                 add_cdtext_info_str( psz_track, "Message (CD-Text)",
  339.                         i_track, CDTEXT_MESSAGE);
  340.                 add_cdtext_info_str( psz_track, "Performer (CD-Text)",
  341.                         i_track, CDTEXT_PERFORMER);
  342.                 add_cdtext_info_str( psz_track, "Songwriter (CD-Text)",
  343.                         i_track, CDTEXT_SONGWRITER);
  344.                 add_cdtext_info_str( psz_track, "Title (CD-Text)",
  345.                         i_track, CDTEXT_TITLE);
  346.             }
  347. #ifdef HAVE_LIBCDDB
  348.             if (p_cdda->b_cddb_enabled)
  349.             {
  350.                 cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc, i);
  351.                 if (t != NULL)
  352.                 {
  353.                     add_info_str(psz_track, "Artist (CDDB)",
  354.                             cddb_track_get_artist(t));
  355.                     add_info_str(psz_track, "Title (CDDB)",
  356.                             cddb_track_get_title(t));
  357.                     add_info_str(psz_track, "Extended Data (CDDB)",
  358.                             cddb_track_get_ext_data(t));
  359.                 }
  360.             }
  361. #endif /*HAVE_LIBCDDB*/
  362.         }
  363.     /* Above we should have set psz_meta_title and psz_meta_artist
  364.        to CDDB or CD-Text values or the default value depending on
  365.        availablity and user preferences.
  366.        So now add the title and artist to VLC's meta, and the name
  367.        as shown in the status bar and playlist entry.
  368.        For playlist mode, the meta title is what's seen at the
  369.        bottom and in the playlist. For nav-mode playing, it is
  370.        done by input_control. I don't understand why they do
  371.        different things. In either case, we may have customized to
  372.        put in the track name.
  373.      */
  374.         if ( CDIO_INVALID_TRACK != i_track )
  375.         {
  376.             char *psz_name = CDDAFormatTitle( p_access, i_track ) ;
  377.             if ( !p_cdda->b_nav_mode ) {
  378.                 add_meta_val( vlc_meta_Title, psz_name );
  379.             } else
  380.             {
  381.                 input_Control( p_cdda->p_input, INPUT_SET_NAME, psz_name );
  382.                 free(psz_name);
  383.             }
  384.             if (psz_meta_artist)
  385.             add_meta_val( vlc_meta_Artist, psz_meta_artist );
  386.         }
  387.     }
  388. }
  389. #define add_format_str_info(val)                         
  390.   {                                                      
  391.     const char *str = val;                               
  392.     unsigned int len;                                    
  393.     if (val != NULL) {                                   
  394.       len=strlen(str);                                   
  395.       if (len != 0) {                                    
  396.         strncat(tp, str, TEMP_STR_LEN-(tp-temp_str));    
  397.         tp += len;                                       
  398.       }                                                  
  399.       saw_control_prefix = false;                        
  400.     }                                                    
  401.   }
  402. #define add_format_num_info(val, fmt)                    
  403.   {                                                      
  404.     char num_str[10];                                    
  405.     unsigned int len;                                    
  406.     sprintf(num_str, fmt, val);                          
  407.     len=strlen(num_str);                                 
  408.     if (len != 0) {                                      
  409.       strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str));  
  410.       tp += len;                                         
  411.     }                                                    
  412.     saw_control_prefix = false;                          
  413.   }
  414. static inline bool
  415. want_cddb_info(
  416. cdda_data_t *p_cdda, char *psz_cdtext)
  417. {
  418.   /* We either don't have CD-Text info, or we do but we prefer to get CDDB
  419.      which means CDDB has been enabled and we were able to retrieve the info.*/
  420. #ifdef HAVE_LIBCDDB
  421.     return !psz_cdtext ||
  422.         (!p_cdda->b_cdtext_prefer && p_cdda->b_cddb_enabled && p_cdda->cddb.disc);
  423. #else
  424.     return false;
  425. #endif
  426. }
  427. /*!
  428.    Take a format string and expand escape sequences, that is sequences that
  429.    begin with %, with information from the current CD.
  430.    The expanded string is returned. Here is a list of escape sequences:
  431.    %a : The album artist **
  432.    %A : The album information **
  433.    %C : Category **
  434.    %e : The extended track data
  435.    %I : CDDB disk ID **
  436.    %G : Genre **
  437.    %M : The current MRL
  438.    %m : The CD-DA Media Catalog Number (MCN)
  439.    %n : The number of tracks on the CD
  440.    %p : The artist/performer/composer in the track **
  441.    %T : The track number **
  442.    %s : Number of seconds in this track, or seconds in CD if invalid track
  443.    %S : Number of seconds on the CD
  444.    %t : The track name or MRL if no name
  445.    %Y : The year 19xx or 20xx **
  446.    %% : a %
  447. */
  448. char *
  449. CDDAFormatStr( const access_t *p_access, cdda_data_t *p_cdda,
  450.                const char format_str[], const char *psz_mrl, track_t i_track)
  451. {
  452. #define TEMP_STR_SIZE 256
  453. #define TEMP_STR_LEN (TEMP_STR_SIZE-1)
  454.     static char temp_str[TEMP_STR_SIZE];
  455.     size_t i;
  456.     char * tp = temp_str;
  457.     bool saw_control_prefix = false;
  458.     size_t format_len = strlen(format_str);
  459.     memset(temp_str, 0, TEMP_STR_SIZE);
  460.     for (i=0; i<format_len; i++)
  461.     {
  462.         char *psz = NULL;
  463.         if (!saw_control_prefix && format_str[i] != '%')
  464.         {
  465.             *tp++ = format_str[i];
  466.             saw_control_prefix = false;
  467.             continue;
  468.         }
  469.         switch(format_str[i])
  470.         {
  471.             case '%':
  472.               if (saw_control_prefix)
  473.               {
  474.                   *tp++ = '%';
  475.               }
  476.               saw_control_prefix = !saw_control_prefix;
  477.               break;
  478. #ifdef HAVE_LIBCDDB
  479.             case 'a':
  480.                 if (p_cdda->p_cdtext[0]
  481.                     && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
  482.                     psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
  483.                 if (want_cddb_info(p_cdda, psz))
  484.                     psz = (char *)cddb_disc_get_artist(p_cdda->cddb.disc);
  485.                 goto format_str;
  486.             case 'A':
  487.                 if (p_cdda->p_cdtext[0]
  488.                     && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
  489.                     psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
  490.                 if (want_cddb_info(p_cdda, psz))
  491.                     psz =  (char *)cddb_disc_get_title(p_cdda->cddb.disc);
  492.                 goto format_str;
  493.             case 'C':
  494.                 if (!p_cdda->b_cddb_enabled) goto not_special;
  495.                 if (p_cdda->cddb.disc)
  496.                     add_format_str_info(CDDB_CATEGORY[cddb_disc_get_category(p_cdda->cddb.disc)]);
  497.                 break;
  498.             case 'G':
  499.                 if (p_cdda->p_cdtext[0]
  500.                     && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
  501.                     psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
  502.                 if (want_cddb_info(p_cdda, psz))
  503.                     psz = (char *)cddb_disc_get_genre(p_cdda->cddb.disc);
  504.                 goto format_str;
  505.             case 'I':
  506.                 if (p_cdda->p_cdtext[0]
  507.                     && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
  508.                     psz = p_cdda->p_cdtext[0]->field[CDTEXT_DISCID];
  509.                 if (want_cddb_info(p_cdda, psz)) {
  510.                     add_format_num_info(cddb_disc_get_discid(p_cdda->cddb.disc), "%x");
  511.                 } else if (psz)
  512.                     add_format_str_info(psz);
  513.                 break;
  514.             case 'Y':
  515.                 if (!p_cdda->b_cddb_enabled) goto not_special;
  516.                 if (p_cdda->cddb.disc)
  517.                     add_format_num_info(cddb_disc_get_year(p_cdda->cddb.disc),
  518.                     "%5d");
  519.                 break;
  520.             case 't':
  521.                 if ( CDIO_INVALID_TRACK == i_track ) break;
  522.                 if (p_cdda && p_cdda->b_cddb_enabled && p_cdda->cddb.disc)
  523.                 {
  524.                     cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
  525.                                                         i_track-1);
  526.                     if (t != NULL && cddb_track_get_title(t) != NULL) {
  527.                       add_format_str_info(cddb_track_get_title(t));
  528.                     } else {
  529.                       add_format_str_info(psz_mrl);
  530.                     }
  531.                 }
  532.                 else
  533.                 {
  534.                     if (p_cdda->p_cdtext[i_track]
  535.                         && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE])
  536.                     {
  537.                         add_format_str_info(p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE]);
  538.                     }
  539.                     else
  540.                         add_format_str_info(psz_mrl);
  541.                 }
  542.                 break;
  543.             case 'p':
  544.                 if ( CDIO_INVALID_TRACK == i_track ) break;
  545.                 if (p_cdda->p_cdtext[i_track]
  546.                     && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
  547.                     psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
  548.                 if (want_cddb_info(p_cdda, psz))
  549.                 {
  550.                     cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
  551.                                 i_track-1);
  552.                     if (t != NULL && cddb_track_get_artist(t) != NULL)
  553.                     psz = (char *)cddb_track_get_artist(t);
  554.                 }
  555.                 goto format_str;
  556.             case 'e':
  557.                     if ( CDIO_INVALID_TRACK == i_track ) break;
  558.                     if (p_cdda->p_cdtext[i_track]
  559.                         && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
  560.                     psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
  561.                     if (want_cddb_info(p_cdda, psz))
  562.                     {
  563.                         cddb_track_t *t=cddb_disc_get_track(p_cdda->cddb.disc,
  564.                                                             i_track-1);
  565.                         if (t != NULL && cddb_track_get_ext_data(t) != NULL)
  566.                             psz = (char *)cddb_track_get_ext_data(t);
  567.                     }
  568.                     goto format_str;
  569.                 break;
  570. #else
  571.             case 'a':
  572.                 if (p_cdda->p_cdtext[0]
  573.                 && p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER])
  574.                 psz = p_cdda->p_cdtext[0]->field[CDTEXT_PERFORMER];
  575.                     goto format_str;
  576.             case 'A':
  577.                 if (p_cdda->p_cdtext[0]
  578.                     && p_cdda->p_cdtext[0]->field[CDTEXT_TITLE])
  579.                 psz = p_cdda->p_cdtext[0]->field[CDTEXT_TITLE];
  580.                 goto format_str;
  581.             case 'G':
  582.                 if (p_cdda->p_cdtext[0]
  583.                 && p_cdda->p_cdtext[0]->field[CDTEXT_GENRE])
  584.                     psz = p_cdda->p_cdtext[0]->field[CDTEXT_GENRE];
  585.                 goto format_str;
  586.             case 'I':
  587.                 if (p_cdda->p_cdtext[0]
  588.                     && p_cdda->p_cdtext[0]->field[CDTEXT_DISCID])
  589.                     add_format_str_info(p_cdda->p_cdtext[0]->field[CDTEXT_DISCID]);
  590.                 break;
  591.             case 'p':
  592.                 if ( CDIO_INVALID_TRACK == i_track ) break;
  593.                 if (p_cdda->p_cdtext[i_track]
  594.                     && p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER])
  595.                 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_PERFORMER];
  596.                 goto format_str;
  597.             case 't':
  598.                 if ( CDIO_INVALID_TRACK == i_track ) break;
  599.                 if (p_cdda->p_cdtext[i_track]
  600.                     && p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE])
  601.                     psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_TITLE];
  602.                 else
  603.                     psz = psz_mrl;
  604.                 goto format_str;
  605.             case 'e':
  606.                 if ( CDIO_INVALID_TRACK == i_track ) break;
  607.                 if (p_cdda->p_cdtext[i_track]
  608.                     && p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE])
  609.                 psz = p_cdda->p_cdtext[i_track]->field[CDTEXT_MESSAGE];
  610.                 goto format_str;
  611.                 break;
  612. #endif /*HAVE_LIBCDDB*/
  613.             case 's':
  614.                 if ( CDIO_INVALID_TRACK != i_track )
  615.                 {
  616.                     char psz_buffer[MSTRTIME_MAX_SIZE];
  617.                     unsigned int i_track_frames =
  618.                     cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
  619.                     mtime_t i_duration =
  620.                         i_track_frames / CDIO_CD_FRAMES_PER_SEC;
  621.                     add_format_str_info( secstotimestr( psz_buffer,
  622.                             i_duration ) );
  623.                     break;
  624.                 }
  625.             /* Fall through to disc duration if CDIO_INVALID_TRACK  */
  626.             case 'S':
  627.                 {
  628.                     char psz_buffer[MSTRTIME_MAX_SIZE];
  629.                     unsigned int i_track_frames =
  630.                     cdio_get_track_lba(p_cdda->p_cdio,
  631.                         CDIO_CDROM_LEADOUT_TRACK);
  632.                     mtime_t i_duration =
  633.                     i_track_frames / CDIO_CD_FRAMES_PER_SEC;
  634.                     add_format_str_info( secstotimestr( psz_buffer,
  635.                             i_duration ) );
  636.                     break;
  637.                 }
  638.             case 'M':
  639.                 add_format_str_info(psz_mrl);
  640.                 break;
  641.             case 'm':
  642.                 add_format_str_info(p_cdda->psz_mcn);
  643.                 break;
  644.             case 'n':
  645.                 add_format_num_info(p_cdda->i_tracks, "%d");
  646.                 break;
  647.             case 'T':
  648.                 add_format_num_info(i_track, "%02d");
  649.                 break;
  650.             format_str:
  651.                 if (psz)
  652.                     add_format_str_info(psz);
  653.                 break;
  654. #ifdef HAVE_LIBCDDB
  655.             not_special:
  656. #endif
  657.             default:
  658.                 *tp++ = '%';
  659.                 *tp++ = format_str[i];
  660.                 saw_control_prefix = false;
  661.         }
  662.     }
  663.     return strdup(temp_str);
  664. }
  665. /* Return a MRL for the given track. The caller must free the
  666.    allocated string. */
  667. static char *
  668. CDDAFormatMRL( const access_t *p_access, track_t i_track )
  669. {
  670.     cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
  671.     const unsigned int psz_mrl_max = strlen(CDDA_MRL_PREFIX)
  672.       + strlen(p_cdda->psz_source) +
  673.       + strlen("@T") + strlen("100") + 1;
  674.     char *psz_mrl = calloc( 1, psz_mrl_max );
  675.     if (CDIO_INVALID_TRACK == i_track)
  676.       snprintf(psz_mrl, psz_mrl_max, "%s%s",
  677.            CDDA_MRL_PREFIX, p_cdda->psz_source);
  678.     else
  679.       snprintf(psz_mrl, psz_mrl_max, "%s%s@T%u",
  680.            CDDA_MRL_PREFIX, p_cdda->psz_source, i_track);
  681.     return psz_mrl;
  682. }
  683. /* Return a title string as specified by the titel format string for the
  684.    given track. The caller must free the allocated string. */
  685. char *
  686. CDDAFormatTitle( const access_t *p_access, track_t i_track )
  687. {
  688.     const char *config_varname = MODULE_STRING "-title-format";
  689.     cdda_data_t *p_cdda = (cdda_data_t *) p_access->p_sys;
  690.     char *psz_mrl = CDDAFormatMRL( p_access, i_track );
  691.     if( psz_mrl )
  692.     {
  693.         char *psz_name;
  694. #ifdef HAVE_LIBCDDB
  695.         if (p_cdda->b_cddb_enabled)
  696.         {
  697.             config_varname = MODULE_STRING "-cddb-title-format";
  698.         }
  699. #endif /*HAVE_LIBCDDB*/
  700.         char* psz_config_varname = config_GetPsz( p_access, config_varname );
  701.         psz_name = CDDAFormatStr( p_access, p_cdda, psz_config_varname,
  702.                                   psz_mrl, i_track );
  703.         free( psz_config_varname );
  704.         free( psz_mrl );
  705.         return psz_name;
  706.     }
  707.     return NULL;
  708. }
  709. /*
  710.    Fixes up playlist.
  711. */
  712. int
  713. CDDAFixupPlaylist( access_t *p_access, cdda_data_t *p_cdda,
  714.                    bool b_single_track )
  715. {
  716.     int i;
  717.     const track_t i_first_track = p_cdda->i_first_track;
  718.     track_t    i_track;
  719. #ifdef HAVE_LIBCDDB
  720.     p_cdda->b_cddb_enabled =
  721.         config_GetInt( p_access, MODULE_STRING "-cddb-enabled" );
  722.     if( b_single_track && !p_cdda->b_cddb_enabled )
  723.         return VLC_SUCCESS;
  724. #else
  725.     if( b_single_track )
  726.         return VLC_SUCCESS;
  727. #endif
  728.     if( b_single_track || p_cdda->b_nav_mode ) {
  729.         i_track = p_cdda->i_track;
  730.     }
  731.     else
  732.     {
  733.         i_track = CDIO_INVALID_TRACK;
  734.     }
  735.     CDDAMetaInfoInit( p_access );
  736.     CDDAMetaInfo( p_access, p_cdda->i_track );
  737.     if( b_single_track && !p_cdda->b_nav_mode )
  738.     {
  739.         /*May fill out more information when the playlist user interface becomes
  740.            more mature.
  741.          */
  742.         track_t i_track = p_cdda->i_track;
  743.         unsigned int i_track_frames =
  744.         cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
  745.         input_title_t *t = p_cdda->p_title[0] = //i_track-i_first_track] =
  746.         vlc_input_title_New();
  747.         if( asprintf( &t->psz_name, _("Track %i"), i_track ) == -1 )
  748.             t->psz_name = NULL;
  749.         t->i_size = i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
  750.         t->i_length = INT64_C(1000000) * t->i_size / CDDA_FREQUENCY_SAMPLE / 4;
  751.         p_cdda->i_titles = 1;
  752.         p_access->info.i_update = INPUT_UPDATE_TITLE;
  753.     }
  754.     else
  755.     {
  756.         input_thread_t *p_input = (input_thread_t*)vlc_object_find( p_access, VLC_OBJECT_INPUT, FIND_PARENT );
  757.         if( !p_input )
  758.             return VLC_EGENERIC;
  759.         input_item_t *p_current = input_GetItem( p_input );
  760.         assert( p_current );
  761.         for( i = 0 ; i < p_cdda->i_tracks ; i++ )
  762.         {
  763.             const track_t i_track = i_first_track + i;
  764.             unsigned int i_track_frames =
  765.                 cdio_get_track_sec_count(p_cdda->p_cdio, i_track);
  766.             input_title_t *t;
  767.             t = p_cdda->p_title[i] = vlc_input_title_New();
  768.             if( asprintf( &t->psz_name, _("Track %i"), i_track ) == -1 )
  769.                 t->psz_name = NULL;
  770.             t->i_size = i_track_frames * (int64_t) CDIO_CD_FRAMESIZE_RAW;
  771.             t->i_length = INT64_C(1000000) * t->i_size
  772.                 / CDDA_FREQUENCY_SAMPLE / 4;
  773.             if( !p_cdda->b_nav_mode )
  774.             {
  775.                 input_item_t *p_child;
  776.                 char *psz_mrl = CDDAFormatMRL( p_access, i_track  );
  777.                 char *psz_title = CDDAFormatTitle( p_access, i_track );
  778.                 unsigned int i_track_frames =
  779.                     cdio_get_track_lsn(p_cdda->p_cdio, i_track+1) -
  780.                     cdio_get_track_lsn(p_cdda->p_cdio, i_track);
  781.                 mtime_t i_mduration = i_track_frames * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) ;
  782.                 p_child = input_item_NewWithType( VLC_OBJECT( p_access ),
  783.                                                   psz_mrl, psz_title, 0, NULL, 0, i_mduration,
  784.                                                   ITEM_TYPE_DISC );
  785.                 if( p_child )
  786.                 {
  787.                     input_item_CopyOptions( p_current, p_child );
  788.                     input_item_AddSubItem( p_current, p_child );
  789.                     vlc_gc_decref( p_child );
  790.                 }
  791.                 free( psz_mrl );
  792.                 free( psz_title );
  793.             }
  794.         }
  795.         p_cdda->i_titles = p_cdda->i_tracks;
  796.         p_access->info.i_update |= INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE;
  797.         if( p_current )
  798.         {
  799.             input_item_SetDuration( p_current,
  800.                                     (mtime_t) p_access->info.i_size * (CLOCK_FREQ / CDIO_CD_FRAMES_PER_SEC) );
  801.             input_item_SetURI( p_current, CDDAFormatMRL( p_access, p_cdda->i_track ) );
  802.         }
  803.         vlc_object_release( p_input );
  804.     }
  805.     return VLC_SUCCESS;
  806. }
  807. /*
  808.  * Local variables:
  809.  *  mode: C
  810.  *  style: gnu
  811.  * End:
  812.  */