@@ -1969,20 +1969,28 @@ fluid_synth_handle_device_id(void *data, const char *name, int value)
19691969 * @param len Length of data in buffer
19701970 * @param response Buffer to store response to or NULL to ignore
19711971 * @param response_len IN/OUT parameter, in: size of response buffer, out:
1972- * amount of data written to response buffer (if FLUID_FAILED is returned and
1972+ * amount of data written to response buffer (if # FLUID_FAILED is returned and
19731973 * this value is non-zero, it indicates the response buffer is too small)
19741974 * @param handled Optional location to store boolean value if message was
19751975 * recognized and handled or not (set to TRUE if it was handled)
19761976 * @param dryrun TRUE to just do a dry run but not actually execute the SYSEX
19771977 * command (useful for checking if a SYSEX message would be handled)
19781978 * @return #FLUID_OK on success, #FLUID_FAILED otherwise
19791979 * @since 1.1.0
1980- */
1981- /* SYSEX format (0xF0 and 0xF7 not passed to this function):
1982- * Non-realtime: 0xF0 0x7E <DeviceId> [BODY] 0xF7
1983- * Realtime: 0xF0 0x7F <DeviceId> [BODY] 0xF7
1984- * Tuning messages: 0xF0 0x7E/0x7F <DeviceId> 0x08 <sub ID2> [BODY] <ChkSum> 0xF7
1985- * GS DT1 messages: 0xF0 0x41 <DeviceId> 0x42 0x12 [ADDRESS (3 bytes)] [DATA] <ChkSum> 0xF7
1980+ * @note When Fluidsynth receives an XG System Mode ON message, it compares the @p synth 's deviceID
1981+ * directly with the deviceID of the SysEx message. This is contrary to the XG spec (page 42), which
1982+ * requires to only compare the lower nibble. However, following the XG spec seems to break drum channels
1983+ * for a lot of MIDI files out there and therefore we've decided for this customization. If you rely on
1984+ * XG System Mode ON messages, make sure to set the setting \ref settings_synth_device-id to match the
1985+ * deviceID provided in the SysEx message (in most cases, this will be <code>deviceID=16</code>).
1986+ *
1987+ * @code
1988+ * SYSEX format (0xF0 and 0xF7 bytes shall not be passed to this function):
1989+ * Non-realtime: 0xF0 0x7E <DeviceId> [BODY] 0xF7
1990+ * Realtime: 0xF0 0x7F <DeviceId> [BODY] 0xF7
1991+ * Tuning messages: 0xF0 0x7E/0x7F <DeviceId> 0x08 <sub ID2> [BODY] <ChkSum> 0xF7
1992+ * GS DT1 messages: 0xF0 0x41 <DeviceId> 0x42 0x12 [ADDRESS (3 bytes)] [DATA] <ChkSum> 0xF7
1993+ * @endcode
19861994 */
19871995int
19881996fluid_synth_sysex (fluid_synth_t * synth , const char * data , int len ,
@@ -2061,9 +2069,8 @@ fluid_synth_sysex(fluid_synth_t *synth, const char *data, int len,
20612069 }
20622070
20632071 /* XG message */
2064- /* note the comparison of device_id, see XG spec 1.23A page 42 "XG System On" */
20652072 if (data [0 ] == MIDI_SYSEX_MANUF_YAMAHA
2066- && (data [1 ] == (( synth -> device_id & 0x0F ) | 0x10 ) || data [1 ] == MIDI_SYSEX_DEVICE_ID_ALL )
2073+ && (data [1 ] == synth -> device_id || data [1 ] == MIDI_SYSEX_DEVICE_ID_ALL )
20672074 && data [2 ] == MIDI_SYSEX_XG_ID )
20682075 {
20692076 int result ;
0 commit comments