mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-12-11 21:31:18 +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
|
enum midi_sysex_manuf
|
||||||
{
|
{
|
||||||
MIDI_SYSEX_MANUF_ROLAND = 0x41, /**< Roland manufacturer ID */
|
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_NON_REALTIME = 0x7E, /**< Universal non realtime message */
|
||||||
MIDI_SYSEX_UNIV_REALTIME = 0x7F /**< Universal 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_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_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_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.
|
* SYSEX tuning message IDs.
|
||||||
|
@ -209,6 +211,7 @@ enum midi_sysex_tuning_msg_id
|
||||||
/* General MIDI sub-ID #2 */
|
/* General MIDI sub-ID #2 */
|
||||||
#define MIDI_SYSEX_GM_ON 0x01 /**< Enable GM mode */
|
#define MIDI_SYSEX_GM_ON 0x01 /**< Enable GM mode */
|
||||||
#define MIDI_SYSEX_GM_OFF 0x02 /**< Disable 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 */
|
#define MIDI_SYSEX_GS_DT1 0x12 /**< GS DT1 command */
|
||||||
|
|
||||||
enum fluid_driver_status
|
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 len, char *response,
|
||||||
int *response_len, int avail_response,
|
int *response_len, int avail_response,
|
||||||
int *handled, int dryrun);
|
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);
|
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_all_sounds_off_LOCAL(fluid_synth_t *synth, int chan);
|
||||||
static int fluid_synth_system_reset_LOCAL(fluid_synth_t *synth);
|
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);
|
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 */
|
/* GS DT1 message */
|
||||||
if((synth->bank_select == FLUID_BANK_STYLE_GS)
|
if(data[0] == MIDI_SYSEX_MANUF_ROLAND
|
||||||
&& data[0] == MIDI_SYSEX_MANUF_ROLAND
|
|
||||||
&& (data[1] == synth->device_id || data[1] == MIDI_SYSEX_DEVICE_ID_ALL)
|
&& (data[1] == synth->device_id || data[1] == MIDI_SYSEX_DEVICE_ID_ALL)
|
||||||
&& data[2] == MIDI_SYSEX_GS_ID
|
&& data[2] == MIDI_SYSEX_GS_ID
|
||||||
&& data[3] == MIDI_SYSEX_GS_DT1)
|
&& 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);
|
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;
|
return FLUID_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2348,6 +2385,36 @@ fluid_synth_sysex_gs_dt1(fluid_synth_t *synth, const char *data, int len,
|
||||||
return FLUID_FAILED;
|
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 ((addr & 0xFFF0FF) == 0x401015) // Use for rhythm part
|
||||||
{
|
{
|
||||||
if (len_data > 1 || data[7] > 0x02)
|
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;
|
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.
|
* Turn off all voices that are playing on the given MIDI channel, by putting them into release phase.
|
||||||
* @param synth FluidSynth instance
|
* @param synth FluidSynth instance
|
||||||
|
|
Loading…
Reference in a new issue