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
[email protected]
http://lists.nongnu.org/mailman/listinfo/fluid-dev