changeset 805:b8b9d7f5d371 trunk

[svn] update amidi-plug towards 0.2; bug fixes and a new option (midi length pre-calculation)
author giacomo
date Tue, 07 Mar 2006 11:47:20 -0800
parents 79c651988a44
children d51a251b542c
files Plugins/Input/amidi-plug/amidi-plug.c Plugins/Input/amidi-plug/amidi-plug.h Plugins/Input/amidi-plug/i_common.h Plugins/Input/amidi-plug/i_configure.c Plugins/Input/amidi-plug/i_configure.h Plugins/Input/amidi-plug/i_fileinfo.c Plugins/Input/amidi-plug/i_midi.c Plugins/Input/amidi-plug/i_midi.h Plugins/Input/amidi-plug/i_seq.c
diffstat 9 files changed, 163 insertions(+), 98 deletions(-) [+]
line wrap: on
line diff
--- a/Plugins/Input/amidi-plug/amidi-plug.c	Sun Mar 05 13:42:27 2006 -0800
+++ b/Plugins/Input/amidi-plug/amidi-plug.c	Tue Mar 07 11:47:20 2006 -0800
@@ -289,7 +289,23 @@
      but the file must be entirely parsed to calculate it; this could lead
      to performance loss, for now it's safer to calculate the length only
      right before playing the file */
-  *length = -1;
+
+  if ( amidiplug_cfg.length_precalc_enable )
+  {
+    /* let's calculate the midi length, using this nice helper function that
+       will return 0 if a problem occurs and the length can't be calculated */
+    midifile_t mf;
+
+    if ( i_midi_parse_from_filename( filename , &mf ) )
+      *length = (gint)(mf.length / 1000);
+    else
+      *length = -1;
+
+    i_midi_free( &mf );
+  }
+  else  
+    *length = -1;
+
   return;
 }
 
--- a/Plugins/Input/amidi-plug/amidi-plug.h	Sun Mar 05 13:42:27 2006 -0800
+++ b/Plugins/Input/amidi-plug/amidi-plug.h	Tue Mar 07 11:47:20 2006 -0800
@@ -66,7 +66,8 @@
   NULL,		/* seq_writable_ports */
   0,		/* mixer_card_id */
   NULL,		/* mixer_control_name */
-  0		/* mixer_control_id */
+  0,		/* mixer_control_id */
+  0		/* length_precalc_enable */
 };
 
 void * amidiplug_play_loop( void * );
--- a/Plugins/Input/amidi-plug/i_common.h	Sun Mar 05 13:42:27 2006 -0800
+++ b/Plugins/Input/amidi-plug/i_common.h	Tue Mar 07 11:47:20 2006 -0800
@@ -44,7 +44,7 @@
 #endif /* DEBUG */
 
 
-#define AMIDIPLUG_VERSION "0.1a"
+#define AMIDIPLUG_VERSION "0.1+"
 #define PLAYER_NAME "Audacious"
 #define G_PATH_GET_BASENAME(x) g_path_get_basename(x)
 #define G_STRING_PRINTF(...) g_string_printf(__VA_ARGS__)
--- a/Plugins/Input/amidi-plug/i_configure.c	Sun Mar 05 13:42:27 2006 -0800
+++ b/Plugins/Input/amidi-plug/i_configure.c	Tue Mar 07 11:47:20 2006 -0800
@@ -34,6 +34,7 @@
   GtkWidget *configwin_vbox;
   GtkWidget *port_lv, *port_lv_sw, *port_frame;
   GtkWidget *mixer_card_cmb_evbox, *mixer_card_cmb, *mixer_vbox, *mixer_frame;
+  GtkWidget *advanced_precalc_checkbt, *advanced_vbox, *advanced_frame;
   GtkWidget *hseparator, *hbuttonbox, *button_ok, *button_cancel;
   GtkListStore *port_liststore, *mixer_card_liststore;
   GtkTreeIter iter;
@@ -133,7 +134,7 @@
   gtk_container_add( GTK_CONTAINER(port_lv_sw) , port_lv );
   gtk_container_set_border_width( GTK_CONTAINER(port_lv_sw) , 5 );
   gtk_container_add( GTK_CONTAINER(port_frame) , port_lv_sw );
-  gtk_box_pack_start( GTK_BOX(configwin_vbox) , port_frame , TRUE , TRUE , 0 );
+  gtk_box_pack_start( GTK_BOX(configwin_vbox) , port_frame , TRUE , TRUE , 2 );
 
   /**********************/
   /*** MIXER SETTINGS ***/
@@ -185,7 +186,23 @@
 
   mixer_frame = gtk_frame_new( "Mixer settings" );
   gtk_container_add( GTK_CONTAINER(mixer_frame) , mixer_vbox );
-  gtk_box_pack_start( GTK_BOX(configwin_vbox) , mixer_frame , TRUE , TRUE , 0 );
+  gtk_box_pack_start( GTK_BOX(configwin_vbox) , mixer_frame , TRUE , TRUE , 2 );
+
+  /*************************/
+  /*** ADVANCED SETTINGS ***/
+  advanced_vbox = gtk_vbox_new( FALSE , 0 );
+  gtk_container_set_border_width( GTK_CONTAINER(advanced_vbox) , 5 );
+  
+  advanced_precalc_checkbt = gtk_check_button_new_with_label( "pre-calculate length of MIDI files in playlist" );
+  amidiplug_gui_prefs.precalc_checkbt = advanced_precalc_checkbt;
+  if ( amidiplug_cfg.length_precalc_enable )
+    gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(advanced_precalc_checkbt) , TRUE );
+  gtk_box_pack_start( GTK_BOX(advanced_vbox) , advanced_precalc_checkbt , TRUE , TRUE , 0 );
+
+  advanced_frame = gtk_frame_new( "Advanced settings" );
+  gtk_container_add( GTK_CONTAINER(advanced_frame) , advanced_vbox );
+  gtk_box_pack_start( GTK_BOX(configwin_vbox) , advanced_frame , TRUE , TRUE , 2 );
+
 
   /* horizontal separator and buttons */
   hseparator = gtk_hseparator_new();
@@ -322,6 +339,13 @@
   /* update amidiplug_cfg.mixer_card_id and amidiplug_cfg.mixer_control_name
      using the selected values from the card-mixer combo list */
   i_configure_upd_mixercardlist();
+  
+  /* update amidiplug_cfg.length_precalc_enable using
+     the check control in the advanced settings frame */
+  if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(amidiplug_gui_prefs.precalc_checkbt) ) )
+    amidiplug_cfg.length_precalc_enable = 1;
+  else
+    amidiplug_cfg.length_precalc_enable = 0;
 
   /* save settings */
   i_configure_cfg_save();
@@ -375,6 +399,7 @@
     amidiplug_cfg.mixer_card_id = 0;
     amidiplug_cfg.mixer_control_name = g_strdup( "Synth" );
     amidiplug_cfg.mixer_control_id = 0;
+    amidiplug_cfg.length_precalc_enable = 0;
   }
   else
   {
@@ -390,6 +415,9 @@
     if ( !xmms_cfg_read_int( cfgfile , "amidi-plug" , "mixer_control_id" , &amidiplug_cfg.mixer_control_id ) )
       amidiplug_cfg.mixer_control_id = 0; /* default value */
 
+    if ( !xmms_cfg_read_int( cfgfile , "amidi-plug" , "length_precalc_enable" , &amidiplug_cfg.length_precalc_enable ) )
+      amidiplug_cfg.length_precalc_enable = 0; /* default value */
+
     xmms_cfg_free(cfgfile);
   }
 }
@@ -407,6 +435,7 @@
   xmms_cfg_write_int( cfgfile , "amidi-plug" , "mixer_card_id" , amidiplug_cfg.mixer_card_id );
   xmms_cfg_write_string( cfgfile , "amidi-plug" , "mixer_control_name" , amidiplug_cfg.mixer_control_name );
   xmms_cfg_write_int( cfgfile , "amidi-plug" , "mixer_control_id" , amidiplug_cfg.mixer_control_id );
+  xmms_cfg_write_int( cfgfile , "amidi-plug" , "length_precalc_enable" , amidiplug_cfg.length_precalc_enable );
 
   xmms_cfg_write_default_file(cfgfile);
   xmms_cfg_free(cfgfile);
--- a/Plugins/Input/amidi-plug/i_configure.h	Sun Mar 05 13:42:27 2006 -0800
+++ b/Plugins/Input/amidi-plug/i_configure.h	Tue Mar 07 11:47:20 2006 -0800
@@ -51,6 +51,7 @@
   gint mixer_card_id;
   gchar * mixer_control_name;
   gint mixer_control_id;
+  gint length_precalc_enable;
 }
 amidiplug_cfg_t;
 
@@ -61,11 +62,12 @@
   GtkWidget * config_win;
   GtkWidget * port_treeview;
   GtkWidget * mixercard_combo;
+  GtkWidget * precalc_checkbt;
   GtkTooltips * config_tips;
 }
 amidiplug_gui_prefs_t;
 
-static amidiplug_gui_prefs_t amidiplug_gui_prefs = { NULL , NULL , NULL , NULL };
+static amidiplug_gui_prefs_t amidiplug_gui_prefs = { NULL , NULL , NULL , NULL , NULL };
 
 void i_configure_gui( GSList * , GSList * );
 void i_configure_ev_destroy( void );
--- a/Plugins/Input/amidi-plug/i_fileinfo.c	Sun Mar 05 13:42:27 2006 -0800
+++ b/Plugins/Input/amidi-plug/i_fileinfo.c	Tue Mar 07 11:47:20 2006 -0800
@@ -28,67 +28,10 @@
 static amidiplug_gui_fileinfo_t amidiplug_gui_fileinfo = { NULL };
 
 
-gint i_fileinfo_midiparse( gchar * filename , midifile_t * mf )
+void i_fileinfo_ev_destroy( GtkWidget * win , gpointer mf )
 {
-  i_midi_init( mf );
-  DEBUGMSG( "FILEINFO requested, opening file: %s\n" , filename );
-  mf->file_pointer = fopen( filename , "rb" );
-  if (!mf->file_pointer)
-  {
-    g_warning( "Cannot open %s\n" , filename );
-    return 0;
-  }
-  mf->file_name = filename;
-
-  switch( i_midi_file_read_id( mf ) )
-  {
-    case MAKE_ID('R', 'I', 'F', 'F'):
-    {
-      DEBUGMSG( "FILEINFO requested, RIFF chunk found, processing...\n" );
-      /* read riff chunk */
-      if ( !i_midi_file_parse_riff( mf ) )
-        WARNANDBREAK( "%s: invalid file format (riff parser)\n" , filename );
-
-      /* if that was read correctly, go ahead and read smf data */
-    }
-
-    case MAKE_ID('M', 'T', 'h', 'd'):
-    {
-      DEBUGMSG( "FILEINFO requested, MThd chunk found, processing...\n" );
-      /* we don't care about port count here, pass 1 */
-      if ( !i_midi_file_parse_smf( mf , 1 ) )
-        WARNANDBREAK( "%s: invalid file format (smf parser)\n" , filename );
-
-      if ( mf->time_division < 1 )
-        WARNANDBREAK( "%s: invalid time division (%i)\n" , filename , mf->time_division );
-
-      /* fill mf->ppq and mf->tempo using time_division */
-      if ( !i_midi_setget_tempo( mf ) )
-        WARNANDBREAK( "%s: invalid values while setting ppq and tempo\n" , filename );
-
-      /* fill mf->length, keeping in count tempo-changes */
-      i_midi_setget_length( mf );
-
-      /* ok, mf has been filled with information; successfully return */
-      fclose( mf->file_pointer );
-      return 1;
-    }
-
-    default:
-    {
-      g_warning( "%s is not a Standard MIDI File\n" , filename );
-      break;
-    }
-  }
-
-  /* something failed */
-  fclose( mf->file_pointer );
-  return 0;
-}
-
-
-void i_fileinfo_ev_destroy( void )
-{
+  i_midi_free( (midifile_t *)mf );
+  g_free( mf );
   amidiplug_gui_fileinfo.fileinfo_win = NULL;
 }
 
@@ -130,17 +73,17 @@
   GString *value_gstring;
   gchar *title , *filename_utf8;
   gint bpm = 0, wavg_bpm = 0;
-  midifile_t mf;
+  midifile_t * mf = g_malloc(sizeof(midifile_t));
 
   if ( amidiplug_gui_fileinfo.fileinfo_win )
     return;
 
   /****************** midifile parser ******************/
-  if ( !i_fileinfo_midiparse( filename , &mf ) )
+  if ( !i_midi_parse_from_filename( filename , mf ) )
     return;
   /* midifile is filled with information at this point,
      bpm information is needed too */
-  i_midi_get_bpm( &mf , &bpm , &wavg_bpm );
+  i_midi_get_bpm( mf , &bpm , &wavg_bpm );
   /*****************************************************/
 
   amidiplug_gui_fileinfo.fileinfo_win = gtk_window_new( GTK_WINDOW_TOPLEVEL );
@@ -148,7 +91,7 @@
   gtk_window_set_resizable( GTK_WINDOW(amidiplug_gui_fileinfo.fileinfo_win) , FALSE );
   gtk_window_set_position( GTK_WINDOW(amidiplug_gui_fileinfo.fileinfo_win) , GTK_WIN_POS_CENTER );
   g_signal_connect( G_OBJECT(amidiplug_gui_fileinfo.fileinfo_win) ,
-                    "destroy" , G_CALLBACK(i_fileinfo_ev_destroy) , NULL );
+                    "destroy" , G_CALLBACK(i_fileinfo_ev_destroy) , mf );
   gtk_container_set_border_width( GTK_CONTAINER(amidiplug_gui_fileinfo.fileinfo_win), 10 );
 
   fileinfowin_vbox = gtk_vbox_new( FALSE , 10 );
@@ -191,13 +134,13 @@
   value_gstring = g_string_new( "" );
 
   /* midi format */
-  G_STRING_PRINTF( value_gstring , "type %i" , mf.format );
+  G_STRING_PRINTF( value_gstring , "type %i" , mf->format );
   i_fileinfo_table_add_entry( _("Format:") , value_gstring->str , info_table , 0 , pangoattrlist );
   /* midi length */
-  G_STRING_PRINTF( value_gstring , "%i" , (gint)(mf.length / 1000) );
+  G_STRING_PRINTF( value_gstring , "%i" , (gint)(mf->length / 1000) );
   i_fileinfo_table_add_entry( _("Length (msec):") , value_gstring->str , info_table , 1 , pangoattrlist );
   /* midi num of tracks */
-  G_STRING_PRINTF( value_gstring , "%i" , mf.num_tracks );
+  G_STRING_PRINTF( value_gstring , "%i" , mf->num_tracks );
   i_fileinfo_table_add_entry( _("Num of Tracks:") , value_gstring->str , info_table , 2 , pangoattrlist );
   /* midi bpm */
   if ( bpm > 0 )
@@ -212,7 +155,7 @@
     G_STRING_PRINTF( value_gstring , "%i" , wavg_bpm ); /* variable bpm, display wavg_bpm */
   i_fileinfo_table_add_entry( _("BPM (wavg):") , value_gstring->str , info_table , 4 , pangoattrlist );
   /* midi time division */
-  G_STRING_PRINTF( value_gstring , "%i" , mf.time_division );
+  G_STRING_PRINTF( value_gstring , "%i" , mf->time_division );
   i_fileinfo_table_add_entry( _("Time Div:") , value_gstring->str , info_table , 5 , pangoattrlist );
 
   g_string_free( value_gstring , TRUE );
--- a/Plugins/Input/amidi-plug/i_midi.c	Sun Mar 05 13:42:27 2006 -0800
+++ b/Plugins/Input/amidi-plug/i_midi.c	Tue Mar 07 11:47:20 2006 -0800
@@ -669,3 +669,63 @@
 
   return;
 }
+
+
+/* helper function that parses a midi file; returns 1 on success, 0 otherwise */
+gint i_midi_parse_from_filename( gchar * filename , midifile_t * mf )
+{
+  i_midi_init( mf );
+  DEBUGMSG( "PARSE_FROM_FILENAME requested, opening file: %s\n" , filename );
+  mf->file_pointer = fopen( filename , "rb" );
+  if (!mf->file_pointer)
+  {
+    g_warning( "Cannot open %s\n" , filename );
+    return 0;
+  }
+  mf->file_name = filename;
+
+  switch( i_midi_file_read_id( mf ) )
+  {
+    case MAKE_ID('R', 'I', 'F', 'F'):
+    {
+      DEBUGMSG( "PARSE_FROM_FILENAME requested, RIFF chunk found, processing...\n" );
+      /* read riff chunk */
+      if ( !i_midi_file_parse_riff( mf ) )
+        WARNANDBREAK( "%s: invalid file format (riff parser)\n" , filename );
+
+      /* if that was read correctly, go ahead and read smf data */
+    }
+
+    case MAKE_ID('M', 'T', 'h', 'd'):
+    {
+      DEBUGMSG( "PARSE_FROM_FILENAME requested, MThd chunk found, processing...\n" );
+      /* we don't care about port count here, pass 1 */
+      if ( !i_midi_file_parse_smf( mf , 1 ) )
+        WARNANDBREAK( "%s: invalid file format (smf parser)\n" , filename );
+
+      if ( mf->time_division < 1 )
+        WARNANDBREAK( "%s: invalid time division (%i)\n" , filename , mf->time_division );
+
+      /* fill mf->ppq and mf->tempo using time_division */
+      if ( !i_midi_setget_tempo( mf ) )
+        WARNANDBREAK( "%s: invalid values while setting ppq and tempo\n" , filename );
+
+      /* fill mf->length, keeping in count tempo-changes */
+      i_midi_setget_length( mf );
+
+      /* ok, mf has been filled with information; successfully return */
+      fclose( mf->file_pointer );
+      return 1;
+    }
+
+    default:
+    {
+      g_warning( "%s is not a Standard MIDI File\n" , filename );
+      break;
+    }
+  }
+
+  /* something failed */
+  fclose( mf->file_pointer );
+  return 0;
+}
--- a/Plugins/Input/amidi-plug/i_midi.h	Sun Mar 05 13:42:27 2006 -0800
+++ b/Plugins/Input/amidi-plug/i_midi.h	Tue Mar 07 11:47:20 2006 -0800
@@ -103,5 +103,7 @@
 gint i_midi_setget_tempo( midifile_t * );
 void i_midi_setget_length( midifile_t * );
 void i_midi_get_bpm( midifile_t * , gint * , gint * );
+/* helper function */
+gint i_midi_parse_from_filename( gchar * , midifile_t * );
 
 #endif /* !_I_MIDI_H */
--- a/Plugins/Input/amidi-plug/i_seq.c	Sun Mar 05 13:42:27 2006 -0800
+++ b/Plugins/Input/amidi-plug/i_seq.c	Tue Mar 07 11:47:20 2006 -0800
@@ -384,23 +384,38 @@
 }
 
 
-gint i_seq_mixer_get_volume( gint * left_volume , gint * right_volume ,
-                            gchar * mixer_card , gchar * mixer_control_name , gint mixer_control_id )
+gint i_seq_mixer_find_selem( snd_mixer_t * mixer_h , gchar * mixer_card ,
+                             gchar * mixer_control_name , gint mixer_control_id ,
+                             snd_mixer_elem_t ** mixer_elem )
 {
-  snd_mixer_t * mixer_h;
-  snd_mixer_selem_id_t * mixer_selem_id;
-  snd_mixer_elem_t * mixer_elem;
+  snd_mixer_selem_id_t * mixer_selem_id = NULL;
 
   snd_mixer_selem_id_alloca( &mixer_selem_id );
   snd_mixer_selem_id_set_index( mixer_selem_id , mixer_control_id );
   snd_mixer_selem_id_set_name( mixer_selem_id , mixer_control_name );
 
-  snd_mixer_open( &mixer_h , 0 );
   snd_mixer_attach( mixer_h , mixer_card );
   snd_mixer_selem_register( mixer_h , NULL , NULL);
   snd_mixer_load( mixer_h );
 
-  mixer_elem = snd_mixer_find_selem( mixer_h , mixer_selem_id );
+  /* assign the mixer element (can be NULL if there is no such element) */
+  *mixer_elem = snd_mixer_find_selem( mixer_h , mixer_selem_id );
+
+  /* always return 1 here */
+  return 1;
+}
+
+
+gint i_seq_mixer_get_volume( gint * left_volume , gint * right_volume ,
+                            gchar * mixer_card , gchar * mixer_control_name , gint mixer_control_id )
+{
+  snd_mixer_t * mixer_h = NULL;
+  snd_mixer_elem_t * mixer_elem = NULL;
+
+  if ( snd_mixer_open( &mixer_h , 0 ) > -1 )
+    i_seq_mixer_find_selem( mixer_h , mixer_card , mixer_control_name , mixer_control_id , &mixer_elem );
+  else
+    mixer_h = NULL;
 
   if ( ( mixer_elem ) && ( snd_mixer_selem_has_playback_volume( mixer_elem ) ) )
   {
@@ -416,19 +431,21 @@
         snd_mixer_selem_get_playback_volume( mixer_elem , SND_MIXER_SCHN_FRONT_LEFT , &lc );
         /* convert the range to 0-100 (for the unlucky case that pv_range is not 0-100 already) */
         *left_volume = (gint)(((lc - pv_min) * pv_range) / 100);
-        DEBUGMSG( "GET VOLUME requested, get left channel (%i)\n" , left_volume );
+        DEBUGMSG( "GET VOLUME requested, get left channel (%i)\n" , *left_volume );
       }
       if ( snd_mixer_selem_has_playback_channel( mixer_elem , SND_MIXER_SCHN_FRONT_RIGHT ) )
       {
         snd_mixer_selem_get_playback_volume( mixer_elem , SND_MIXER_SCHN_FRONT_RIGHT , &rc );
         /* convert the range to 0-100 (for the unlucky case that pv_range is not 0-100 already) */
         *right_volume = (gint)(((rc - pv_min) * pv_range) / 100);
-        DEBUGMSG( "GET VOLUME requested, get right channel (%i)\n" , right_volume );
+        DEBUGMSG( "GET VOLUME requested, get right channel (%i)\n" , *right_volume );
       }
     }
   }
 
-  snd_mixer_close( mixer_h );
+  if ( mixer_h )
+    snd_mixer_close( mixer_h );
+
   /* for now, always return 1 here */
   return 1;
 }
@@ -437,20 +454,13 @@
 gint i_seq_mixer_set_volume( gint left_volume , gint right_volume ,
                             gchar * mixer_card , gchar * mixer_control_name , gint mixer_control_id )
 {
-  snd_mixer_t * mixer_h;
-  snd_mixer_selem_id_t * mixer_selem_id;
-  snd_mixer_elem_t * mixer_elem;
+  snd_mixer_t * mixer_h = NULL;
+  snd_mixer_elem_t * mixer_elem = NULL;
 
-  snd_mixer_selem_id_alloca( &mixer_selem_id );
-  snd_mixer_selem_id_set_index( mixer_selem_id , mixer_control_id );
-  snd_mixer_selem_id_set_name( mixer_selem_id , mixer_control_name );
-
-  snd_mixer_open( &mixer_h , 0 );
-  snd_mixer_attach( mixer_h , mixer_card );
-  snd_mixer_selem_register( mixer_h , NULL , NULL);
-  snd_mixer_load( mixer_h );
-
-  mixer_elem = snd_mixer_find_selem( mixer_h , mixer_selem_id );
+  if ( snd_mixer_open( &mixer_h , 0 ) > -1 )
+    i_seq_mixer_find_selem( mixer_h , mixer_card , mixer_control_name , mixer_control_id , &mixer_elem );
+  else
+    mixer_h = NULL;
 
   if ( ( mixer_elem ) && ( snd_mixer_selem_has_playback_volume( mixer_elem ) ) )
   {
@@ -475,7 +485,9 @@
     }
   }
 
-  snd_mixer_close( mixer_h );
+  if ( mixer_h )
+    snd_mixer_close( mixer_h );
+
   /* for now, always return 1 here */
   return 1;
 }