Attached is a patch for 4 SysEx messages.  This allow Fluidsynth to 
automatically switch between GM, GS, XG mode on the fly, without having to 
restart, that is.  Often a "reset" sysex is sent at beginning of a midi file, 
but not always.

Sys-Ex "reset" messages:

   myweb.tiscali.co.uk/mikesmusic/my_technical_articles2.html#sysex
   
   1. GM Reset (understood by every GM-compatible instrument)
   Sys-Ex String: F0 7E 7F 09 01 F7

   2. Roland GS Reset (Understood by all Roland GS instruments)
   Sys-Ex String: F0 41 10 42 12 40 00 7F 00 41 F7

   3. Yamaha XG reset (Understood by all Yamaha XG instruments)
   Sys-Ex String: F0 43 10 4C 00 00 7E 00 F7

About master volume:

   home.roadrunner.com/~jgglatt/tech/midispec/mastrvol.htm

   Master Volume SysEx:   0xF0 0x7F 0x7F 0x04 0x01 0xLL 0xMM 0xF7

where (0xLL=LSB, 0xMM=MSB), where 7F 7F is maximum volume.

My patch ignores LSB (LSB=0), simply takes the MSB (7-bit, max value 127) 
devide by 12.70 to get the range of [0.0 - 10.0].

-----

In adding SysEx handler for master volume adjustment ("gain" in Fluidsynth), I 
found a few inconsitencies regarding "gain":

       -g, --gain
              Set the master gain [0 < gain < 10, default = 0.2]

which sets fluidsynth settings of:

       synth.gain FLOAT [min=0.000, max=10.000, def=0.200] REALTIME
              Master synthesizer gain.

While the fluidsynth command shell and manual page have:

       gain value
              Set the master gain (0 < gain < 5)

but the shell-command handler fluid_handle_gain() doesn't try to scale it in 
anyway to 10.0.  Any reason for that?  Or, it's just an oversight (in previous 
changes).

In this patch, I go ahead and change all references regarding maximum "gain" 
from 5 to 10.  Let me know if those need to be left alone.

Jimmy




      
diff -pur fluidsynth.svnRev405.20110207/doc/fluidsynth.1 fluidsynth.svnRev405.20110207.jnSysex/doc/fluidsynth.1
--- fluidsynth.svnRev405.20110207/doc/fluidsynth.1	2011-02-07 20:29:49.000000000 -0500
+++ fluidsynth.svnRev405.20110207.jnSysex/doc/fluidsynth.1	2011-02-09 15:51:53.000000000 -0500
@@ -415,7 +415,7 @@ Print out the presets of all channels.
 .B AUDIO SYNTHESIS
 .TP
 .B gain value
-Set the master gain (0 < gain < 5)
+Set the master gain (0 < gain < 10)
 .TP
 .B interp num
 Choose interpolation method for all channels
diff -pur fluidsynth.svnRev405.20110207/src/bindings/fluid_cmd.c fluidsynth.svnRev405.20110207.jnSysex/src/bindings/fluid_cmd.c
--- fluidsynth.svnRev405.20110207/src/bindings/fluid_cmd.c	2011-02-07 20:29:47.000000000 -0500
+++ fluidsynth.svnRev405.20110207.jnSysex/src/bindings/fluid_cmd.c	2011-02-09 15:51:53.000000000 -0500
@@ -119,7 +119,7 @@ fluid_cmd_t fluid_commands[] = {
   { "chorus", "chorus", (fluid_cmd_func_t) fluid_handle_chorus, NULL,
     "chorus [0|1|on|off]        Turn the chorus on or off" },
   { "gain", "general", (fluid_cmd_func_t) fluid_handle_gain, NULL,
-    "gain value                 Set the master gain (0 < gain < 5)" },
+    "gain value                 Set the master gain (0 < gain < 10)" },
   { "voice_count", "general", (fluid_cmd_func_t) fluid_handle_voice_count, NULL,
     "voice_count                Get number of active synthesis voices" },
   { "tuning", "tuning", (fluid_cmd_func_t) fluid_handle_tuning, NULL,
@@ -981,8 +981,8 @@ fluid_handle_gain(fluid_synth_t* synth,
 
   gain = atof(av[0]);
 
-  if ((gain < 0.0f) || (gain > 5.0f)) {
-    fluid_ostream_printf(out, "gain: value should be between '0' and '5'.\n");
+  if ((gain < 0.0f) || (gain > 10.0f)) {
+    fluid_ostream_printf(out, "gain: value should be between '0' and '10'.\n");
     return -1;
   };
 
diff -pur fluidsynth.svnRev405.20110207/src/synth/fluid_synth.c fluidsynth.svnRev405.20110207.jnSysex/src/synth/fluid_synth.c
--- fluidsynth.svnRev405.20110207/src/synth/fluid_synth.c	2011-02-07 20:29:48.000000000 -0500
+++ fluidsynth.svnRev405.20110207.jnSysex/src/synth/fluid_synth.c	2011-02-10 09:24:19.000000000 -0500
@@ -1221,18 +1221,88 @@ fluid_synth_sysex(fluid_synth_t *synth,
 
   if (len < 4) return FLUID_OK;
 
-  /* MIDI tuning SYSEX message? */
+  /* GM Reset:        F0 7E 7F 09 01 F7 */
+  if ((0x7E == data[0]) && (0x7F == data[1]) && (0x09 == data[2]) && (0x01 == data[3]))
+  {
+      if (synth->verbose)
+          FLUID_LOG(FLUID_INFO, "FLUID_BANK_STYLE_GM");
+
+      if (handled) *handled = TRUE;
+      if (!dryrun)
+      {
+          fluid_synth_setstr(synth, "synth.midi-bank-select", "gm");
+          synth->bank_select = FLUID_BANK_STYLE_GM;
+          fluid_synth_system_reset(synth);
+      }
+      return FLUID_OK;
+  }
+  /* GS Reset:        F0 41 10 42 12 40 00 7F 00 41 F7 */
+  else if ((0x41 == data[0]) && (0x10 == data[1]) && (0x42 == data[2]) &&
+      (0x12 == data[3]) && (0x40 == data[4]) && (0x00 == data[5]) &&
+      (0x7F == data[6]) && (0x00 == data[7]) && (0x41 == data[8]))
+  {
+      if (synth->verbose)
+          FLUID_LOG(FLUID_INFO, "FLUID_BANK_STYLE_GS");
+
+      if (handled) *handled = TRUE;
+      if (!dryrun)
+      {
+          fluid_synth_setstr(synth, "synth.midi-bank-select", "gs");
+          synth->bank_select = FLUID_BANK_STYLE_GS;
+          fluid_synth_system_reset(synth);
+      }
+      return FLUID_OK;
+  }
+  /* XG reset:        F0 43 10 4C 00 00 7E 00 F7 */
+  else if ((0x43 == data[0]) && (0x10 == data[1]) && (0x4C == data[2]) &&
+      (0x00 == data[3]) && (0x00 == data[4]) && (0x7E == data[5]) && (0x00 == data[6]))
+  {
+      if (synth->verbose)
+          FLUID_LOG(FLUID_INFO, "FLUID_BANK_STYLE_XG");
+
+      if (handled) *handled = TRUE;
+      if (!dryrun)
+      {
+          fluid_synth_setstr(synth, "synth.midi-bank-select", "xg");
+          synth->bank_select = FLUID_BANK_STYLE_XG;
+          fluid_synth_system_reset(synth);
+      }
+      return FLUID_OK;
+  }
+
   if ((data[0] == MIDI_SYSEX_UNIV_NON_REALTIME || data[0] == MIDI_SYSEX_UNIV_REALTIME)
-      && (data[1] == synth->device_id || data[1] == MIDI_SYSEX_DEVICE_ID_ALL)
-      && data[2] == MIDI_SYSEX_MIDI_TUNING_ID)
+           && (data[1] == synth->device_id || data[1] == MIDI_SYSEX_DEVICE_ID_ALL))
   {
-    int result;
-    fluid_synth_api_enter(synth);
-    result = fluid_synth_sysex_midi_tuning (synth, data, len, response, 
-						response_len, avail_response, 
-						handled, dryrun);
+      /* Master Volume:   0xF0 0x7F 0x7F 0x04 0x01 0xLL 0xMM 0xF7 */
+      if (data[2] == 0x04 && data[3] == 0x01)
+      {
+          fluid_return_val_if_fail (5 < len, FLUID_FAILED);
+          /* Ignores LSB (0xLL, data[4]), use MSB (0xMM, data[5]).
+          * Convert (int)[0-127] to volume range (float)[0.0-10.0] */
+          float gain = (data[5] & 0x7F) / 12.70;
+
+          if (synth->verbose)
+              FLUID_LOG(FLUID_INFO, "MasterVolume Sysex -- msb: %d , gain: %f ", data[5], gain);
+          if (handled) *handled = TRUE;
+          if (!dryrun) 
+          {
+              fluid_synth_setnum(synth, "synth.gain", gain);
+              fluid_synth_set_gain(synth, gain);
+          }
+          return FLUID_OK;
+      }
+
+	  /* MIDI tuning SYSEX message? */
+	  if (data[2] == MIDI_SYSEX_MIDI_TUNING_ID)
+	  {
+		  int result;
+		  fluid_synth_api_enter(synth);
+		  result = fluid_synth_sysex_midi_tuning (synth, data, len, response, 
+					response_len, avail_response, 
+					handled, dryrun);
 
-    FLUID_API_RETURN(result);
+		  FLUID_API_RETURN(result);
+	  }
   }
   return FLUID_OK;
 }
@@ -2124,7 +2194,7 @@ fluid_synth_update_presets(fluid_synth_t
   }
 }
 
-/* Handler for synth.gain setting. */
+/* Handler for synth.sample-rate setting. */
 static int
 fluid_synth_update_sample_rate(fluid_synth_t* synth, char* name, double value)
 {
_______________________________________________
fluid-dev mailing list
fluid-dev@nongnu.org
http://lists.nongnu.org/mailman/listinfo/fluid-dev

Reply via email to