Skip to content

Commit e1fba96

Browse files
authored
Fix drum kits not being selected after SysEx GS Rythm Part (#1663)
1 parent a00c3af commit e1fba96

File tree

3 files changed

+43
-18
lines changed

3 files changed

+43
-18
lines changed

src/synth/fluid_synth.c

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2237,10 +2237,6 @@ fluid_synth_sysex(fluid_synth_t *synth, const char *data, int len,
22372237
result = fluid_synth_sysex_gs_dt1(synth, data, len, response,
22382238
response_len, avail_response,
22392239
handled, dryrun);
2240-
if(synth->verbose)
2241-
{
2242-
FLUID_LOG(FLUID_INFO, "Processing SysEX GS DT1 message, bank selection mode might have been changed.");
2243-
}
22442240
FLUID_API_RETURN(result);
22452241
}
22462242

@@ -2568,7 +2564,7 @@ fluid_synth_sysex_gs_dt1(fluid_synth_t *synth, const char *data, int len,
25682564

25692565
if(len < 9) // at least one byte of data should be transmitted
25702566
{
2571-
FLUID_LOG(FLUID_INFO, "SysEx DT1: message too short, dropping it.");
2567+
FLUID_LOG(FLUID_INFO, "SysEx GS DT1: message too short, dropping it.");
25722568
return FLUID_FAILED;
25732569
}
25742570
len_data = len - 8;
@@ -2582,24 +2578,26 @@ fluid_synth_sysex_gs_dt1(fluid_synth_t *synth, const char *data, int len,
25822578
// An intermediate checksum of 0x80 must be treated as zero! #1578
25832579
if ((checksum & 0x7F) != data[len - 1])
25842580
{
2585-
FLUID_LOG(FLUID_INFO, "SysEx DT1: dropping message on addr 0x%x due to incorrect checksum 0x%x. Correct checksum: 0x%x", addr, (int)data[len - 1], checksum);
2581+
FLUID_LOG(FLUID_INFO, "SysEx GS DT1: dropping message on addr 0x%x due to incorrect checksum 0x%x. Correct checksum: 0x%x", addr, (int)data[len - 1], checksum);
25862582
return FLUID_FAILED;
25872583
}
25882584

25892585
if (addr == 0x40007F) // Mode set
25902586
{
25912587
if (len_data > 1 || (data[7] != 0 && data[7] != 0x7f))
25922588
{
2593-
FLUID_LOG(FLUID_INFO, "SysEx DT1: dropping invalid mode set message");
2589+
FLUID_LOG(FLUID_INFO, "SysEx GS DT1: dropping invalid mode set message");
25942590
return FLUID_FAILED;
25952591
}
25962592
if (handled)
25972593
{
25982594
*handled = TRUE;
25992595
}
2596+
2597+
i = data[7];
26002598
if (!dryrun)
26012599
{
2602-
if (data[7] == 0)
2600+
if (i == 0)
26032601
{
26042602
synth->bank_select = FLUID_BANK_STYLE_GS;
26052603
}
@@ -2609,6 +2607,12 @@ fluid_synth_sysex_gs_dt1(fluid_synth_t *synth, const char *data, int len,
26092607
}
26102608
return fluid_synth_system_reset_LOCAL(synth);
26112609
}
2610+
if(synth->verbose)
2611+
{
2612+
FLUID_LOG(FLUID_INFO, "%sSysEX GS DT1: bank selection mode is now %s",
2613+
dryrun ? "[DRYRUN] " : "",
2614+
i == 0 ? "GS" : "GM");
2615+
}
26122616
return FLUID_OK;
26132617
}
26142618

@@ -2621,7 +2625,7 @@ fluid_synth_sysex_gs_dt1(fluid_synth_t *synth, const char *data, int len,
26212625
{
26222626
if (len_data > 1 || data[7] > 0x02)
26232627
{
2624-
FLUID_LOG(FLUID_INFO, "SysEx DT1: dropping invalid rhythm part message");
2628+
FLUID_LOG(FLUID_INFO, "SysEx GS DT1: dropping invalid rhythm part message");
26252629
return FLUID_FAILED;
26262630
}
26272631
if (handled)
@@ -2630,15 +2634,25 @@ fluid_synth_sysex_gs_dt1(fluid_synth_t *synth, const char *data, int len,
26302634
}
26312635
if (!dryrun)
26322636
{
2633-
int chan = (addr >> 8) & 0x0F;
2637+
int chan = (addr >> 8) & 0x0F, type;
26342638
//See the Patch Part parameters section in SC-88Pro/8850 owner's manual
26352639
chan = chan >= 0x0a ? chan : (chan == 0 ? 9 : chan - 1);
2636-
synth->channel[chan]->channel_type =
2637-
data[7] == 0x00 ? CHANNEL_TYPE_MELODIC : CHANNEL_TYPE_DRUM;
2638-
2639-
FLUID_LOG(FLUID_DBG, "SysEx DT1: setting MIDI channel %d to type %d", chan, (int)synth->channel[chan]->channel_type);
2640-
//Roland synths seem to "remember" the last instrument a channel
2641-
//used in the selected mode. This behavior is not replicated here.
2640+
type = data[7] == 0x00 ? CHANNEL_TYPE_MELODIC : CHANNEL_TYPE_DRUM;
2641+
synth->channel[chan]->channel_type = type;
2642+
2643+
FLUID_LOG(FLUID_DBG, "SysEx GS DT1: setting MIDI channel %d to type %d", chan, (int)synth->channel[chan]->channel_type);
2644+
// Roland synths seem to "remember" the last instrument a channel
2645+
// used in the selected mode. This behavior is not replicated here.
2646+
// Issue 1579: The preset selected for the channel needs to be forcibly changed. Therefore it is not sufficient
2647+
// to send a prog change, as the old bank is still active in the channel.
2648+
// MSGS selects the standard drum kit right after this message (which is equivalent to sending a prog change 0).
2649+
// However, this behavior is insonsistent with the note on site 60:
2650+
// "To select a drum set after setting the part mode, transmit a program change [...]"
2651+
fluid_synth_cc_LOCAL(synth, chan, ALL_CTRL_OFF);
2652+
fluid_channel_set_sfont_bank_prog(synth->channel[chan],
2653+
-1,
2654+
type == CHANNEL_TYPE_DRUM ? DRUM_INST_BANK : 0,
2655+
-1);
26422656
fluid_synth_program_change(synth, chan, 0);
26432657
}
26442658
return FLUID_OK;

test/CMakeLists.txt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ set(DYNSAM_RENDER_DIR "${CMAKE_CURRENT_BINARY_DIR}/manual/dynamic-sample-loading
7474
set(BANKSELECT_RENDER_DIR "${CMAKE_CURRENT_BINARY_DIR}/manual/midi-bank-select")
7575
set(STACKEDSF_RENDER_DIR "${CMAKE_CURRENT_BINARY_DIR}/manual/stacked_sf2")
7676
set(SFE_RENDER_DIR "${CMAKE_CURRENT_BINARY_DIR}/manual/sfe")
77+
set(SYSEX_GS_DT1 "${CMAKE_CURRENT_BINARY_DIR}/manual/sysex/gs_dt1")
7778

7879
if(LIBSNDFILE_SUPPORT)
7980
set(FEXT "wav")
@@ -85,7 +86,7 @@ endif()
8586
add_custom_target(check_manual)
8687

8788
add_custom_target(create_iir_dir
88-
COMMAND ${CMAKE_COMMAND} -E make_directory ${IIR_FILTER_RENDER_DIR} ${AWE32_NRPN_RENDER_DIR} ${SFSPEC_RENDER_DIR} ${PORTAMENTO_RENDER_DIR} ${REVERB_RENDER_DIR} ${EXCL_RENDER_DIR} ${DSPINTERP_RENDER_DIR} ${DYNSAM_RENDER_DIR} ${STACKEDSF_RENDER_DIR} ${GUGDEMO_RENDER_DIR} ${BANKSELECT_RENDER_DIR} ${SFE_RENDER_DIR}
89+
COMMAND ${CMAKE_COMMAND} -E make_directory ${IIR_FILTER_RENDER_DIR} ${AWE32_NRPN_RENDER_DIR} ${SFSPEC_RENDER_DIR} ${PORTAMENTO_RENDER_DIR} ${REVERB_RENDER_DIR} ${EXCL_RENDER_DIR} ${DSPINTERP_RENDER_DIR} ${DYNSAM_RENDER_DIR} ${STACKEDSF_RENDER_DIR} ${GUGDEMO_RENDER_DIR} ${BANKSELECT_RENDER_DIR} ${SFE_RENDER_DIR} ${SYSEX_GS_DT1}
8990
VERBATIM)
9091

9192
add_custom_target(render1415
@@ -328,6 +329,16 @@ add_custom_target(renderDMOD
328329
VERBATIM
329330
)
330331

332+
add_custom_target(renderGSDT1
333+
COMMAND fluidsynth -R 0 -C 0 -g 0.6 -F "${SYSEX_GS_DT1}/wikipedia_MIDI_sample_gstest.${FEXT}" ${GENERAL_USER_GS2} "wikipedia_MIDI_sample_gstest.mid"
334+
COMMAND fluidsynth -R 0 -C 0 -g 0.6 -F "${SYSEX_GS_DT1}/D_DM2TTL - GS Drums.${FEXT}" ${GENERAL_USER_GS2} "D_DM2TTL - GS Drums.mid"
335+
COMMAND fluidsynth -R 0 -C 0 -g 0.6 -F "${SYSEX_GS_DT1}/GS Drums Bank Select and Program Change interaction on MSGS.${FEXT}" ${GENERAL_USER_GS2} "GS Drums Bank Select and Program Change interaction on MSGS.mid"
336+
COMMENT "Rendering Test MIDIs for SysEx GS DT1"
337+
DEPENDS fluidsynth create_iir_dir
338+
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/manual/sysex/gs_dt1"
339+
VERBATIM
340+
)
341+
331342
if ( LIBINSTPATCH_SUPPORT )
332343
add_custom_target(renderStreetwise
333344
COMMAND fluidsynth -R 0 -C 0 -g 0.6 -F "${STACKEDSF_RENDER_DIR}/Streetwise.${FEXT}" "Streetwise.mid" ${GENERAL_USER_GS2} "Streetwise.dls"

0 commit comments

Comments
 (0)