mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-12-02 17:12:15 +00:00
Handle GM/GM2 mode on, GS reset, and XG reset, and reset the
synthesizer upon setting the mode.
This commit is contained in:
parent
4231645fb8
commit
7068c13f71
2 changed files with 117 additions and 2 deletions
|
@ -178,6 +178,7 @@ enum midi_meta_event
|
|||
enum midi_sysex_manuf
|
||||
{
|
||||
MIDI_SYSEX_MANUF_ROLAND = 0x41, /**< Roland manufacturer ID */
|
||||
MIDI_SYSEX_MANUF_YAMAHA = 0x43,
|
||||
MIDI_SYSEX_UNIV_NON_REALTIME = 0x7E, /**< Universal non realtime message */
|
||||
MIDI_SYSEX_UNIV_REALTIME = 0x7F /**< Universal realtime message */
|
||||
};
|
||||
|
@ -188,6 +189,7 @@ enum midi_sysex_manuf
|
|||
#define MIDI_SYSEX_MIDI_TUNING_ID 0x08 /**< Sysex sub-ID #1 for MIDI tuning messages */
|
||||
#define MIDI_SYSEX_GM_ID 0x09 /**< Sysex sub-ID #1 for General MIDI messages */
|
||||
#define MIDI_SYSEX_GS_ID 0x42 /**< Model ID (GS) serving as sub-ID #1 for GS messages*/
|
||||
#define MIDI_SYSEX_XG_ID 0x4C /**< Model ID (XG) serving as sub-ID #1 for XG messages*/
|
||||
|
||||
/**
|
||||
* SYSEX tuning message IDs.
|
||||
|
@ -209,6 +211,7 @@ enum midi_sysex_tuning_msg_id
|
|||
/* General MIDI sub-ID #2 */
|
||||
#define MIDI_SYSEX_GM_ON 0x01 /**< Enable GM mode */
|
||||
#define MIDI_SYSEX_GM_OFF 0x02 /**< Disable GM mode */
|
||||
#define MIDI_SYSEX_GM2_ON 0x03 /**< Enable GM2 mode */
|
||||
#define MIDI_SYSEX_GS_DT1 0x12 /**< GS DT1 command */
|
||||
|
||||
enum fluid_driver_status
|
||||
|
|
|
@ -70,6 +70,10 @@ static int fluid_synth_sysex_gs_dt1(fluid_synth_t *synth, const char *data,
|
|||
int len, char *response,
|
||||
int *response_len, int avail_response,
|
||||
int *handled, int dryrun);
|
||||
static int fluid_synth_sysex_xg(fluid_synth_t *synth, const char *data,
|
||||
int len, char *response,
|
||||
int *response_len, int avail_response,
|
||||
int *handled, int dryrun);
|
||||
int fluid_synth_all_notes_off_LOCAL(fluid_synth_t *synth, int chan);
|
||||
static int fluid_synth_all_sounds_off_LOCAL(fluid_synth_t *synth, int chan);
|
||||
static int fluid_synth_system_reset_LOCAL(fluid_synth_t *synth);
|
||||
|
@ -2012,9 +2016,29 @@ fluid_synth_sysex(fluid_synth_t *synth, const char *data, int len,
|
|||
FLUID_API_RETURN(result);
|
||||
}
|
||||
|
||||
/* GM or GM2 system on */
|
||||
if(data[0] == MIDI_SYSEX_UNIV_NON_REALTIME
|
||||
&& (data[1] == synth->device_id || data[1] == MIDI_SYSEX_DEVICE_ID_ALL)
|
||||
&& data[2] == MIDI_SYSEX_GM_ID)
|
||||
{
|
||||
if(handled)
|
||||
{
|
||||
*handled = TRUE;
|
||||
}
|
||||
if(!dryrun && (data[3] == MIDI_SYSEX_GM_ON
|
||||
|| data[3] == MIDI_SYSEX_GM2_ON))
|
||||
{
|
||||
int result;
|
||||
synth->bank_select = FLUID_BANK_STYLE_GM;
|
||||
fluid_synth_api_enter(synth);
|
||||
result = fluid_synth_system_reset_LOCAL(synth);
|
||||
FLUID_API_RETURN(result);
|
||||
}
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
/* GS DT1 message */
|
||||
if((synth->bank_select == FLUID_BANK_STYLE_GS)
|
||||
&& data[0] == MIDI_SYSEX_MANUF_ROLAND
|
||||
if(data[0] == MIDI_SYSEX_MANUF_ROLAND
|
||||
&& (data[1] == synth->device_id || data[1] == MIDI_SYSEX_DEVICE_ID_ALL)
|
||||
&& data[2] == MIDI_SYSEX_GS_ID
|
||||
&& data[3] == MIDI_SYSEX_GS_DT1)
|
||||
|
@ -2027,6 +2051,19 @@ fluid_synth_sysex(fluid_synth_t *synth, const char *data, int len,
|
|||
FLUID_API_RETURN(result);
|
||||
}
|
||||
|
||||
/* XG message */
|
||||
if(data[0] == MIDI_SYSEX_MANUF_YAMAHA
|
||||
&& (data[1] == synth->device_id || data[1] == MIDI_SYSEX_DEVICE_ID_ALL)
|
||||
&& data[2] == MIDI_SYSEX_XG_ID)
|
||||
{
|
||||
int result;
|
||||
fluid_synth_api_enter(synth);
|
||||
result = fluid_synth_sysex_xg(synth, data, len, response,
|
||||
response_len, avail_response,
|
||||
handled, dryrun);
|
||||
FLUID_API_RETURN(result);
|
||||
}
|
||||
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
|
@ -2348,6 +2385,36 @@ fluid_synth_sysex_gs_dt1(fluid_synth_t *synth, const char *data, int len,
|
|||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
if (addr == 0x40007F) // Mode set
|
||||
{
|
||||
if (len_data > 1 || (data[7] != 0 && data[7] != 0x7f))
|
||||
{
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
if (handled)
|
||||
{
|
||||
*handled = TRUE;
|
||||
}
|
||||
if (!dryrun)
|
||||
{
|
||||
if (data[7] == 0)
|
||||
{
|
||||
synth->bank_select = FLUID_BANK_STYLE_GS;
|
||||
}
|
||||
else
|
||||
{
|
||||
synth->bank_select = FLUID_BANK_STYLE_GM;
|
||||
}
|
||||
return fluid_synth_system_reset_LOCAL(synth);
|
||||
}
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
if (synth->bank_select != FLUID_BANK_STYLE_GS)
|
||||
{
|
||||
return FLUID_OK; // Silently ignore all other messages
|
||||
}
|
||||
|
||||
if ((addr & 0xFFF0FF) == 0x401015) // Use for rhythm part
|
||||
{
|
||||
if (len_data > 1 || data[7] > 0x02)
|
||||
|
@ -2377,6 +2444,51 @@ fluid_synth_sysex_gs_dt1(fluid_synth_t *synth, const char *data, int len,
|
|||
return FLUID_OK;
|
||||
}
|
||||
|
||||
/* Handler for XG messages */
|
||||
static int
|
||||
fluid_synth_sysex_xg(fluid_synth_t *synth, const char *data, int len,
|
||||
char *response, int *response_len, int avail_response,
|
||||
int *handled, int dryrun)
|
||||
{
|
||||
int addr;
|
||||
int len_data;
|
||||
|
||||
if(len < 7) // at least one byte of data should be transmitted
|
||||
{
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
len_data = len - 6;
|
||||
addr = (data[3] << 16) | (data[4] << 8) | data[5];
|
||||
|
||||
if (addr == 0x00007E // Reset
|
||||
|| addr == 0x00007F) // Reset to factory
|
||||
{
|
||||
if (len_data > 1 || data[6] != 0)
|
||||
{
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
if (handled)
|
||||
{
|
||||
*handled = TRUE;
|
||||
}
|
||||
if (!dryrun)
|
||||
{
|
||||
synth->bank_select = FLUID_BANK_STYLE_XG;
|
||||
return fluid_synth_system_reset_LOCAL(synth);
|
||||
}
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
/* No other messages handled yet
|
||||
if (synth->bank_select != FLUID_BANK_STYLE_XG)
|
||||
{
|
||||
return FLUID_OK; // Silently ignore all other messages
|
||||
}*/
|
||||
|
||||
//silently ignore
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn off all voices that are playing on the given MIDI channel, by putting them into release phase.
|
||||
* @param synth FluidSynth instance
|
||||
|
|
Loading…
Reference in a new issue