spessasynth_core documentation
    Preparing search index...

    MIDI Implementation

    This page describes what messages SpessaSynthProcessor can receive. The supported standards are:

    • MIDI 1.0 Protocol
    • General MIDI Level 1
    • General MIDI Level 2
    • Roland GS
    • Yamaha XG

    Below is the list of supported MIDI messages.

    Message Supported? Notes
    Note On ✔️ More info
    Note Off ✔️ Does not support note off velocity (Per SF2 specification) More info
    Poly Pressure ✔️ Recognized, but no default behavior (Per SF2 specification). It has to be defined with modulators or System Exclusives.
    Controller Change ✔️ More info
    Program Change ✔️ More info: MIDIPatch
    Channel Pressure ✔️ 50 cents of vibrato (Per SF2 specification)
    Pitch Wheel ✔️ Controlled by Pitch Wheel Range. More info.
    System Exclusive ✔️ More info
    Time Code ❌ Not Applicable
    Song Position ❌ Not Applicable
    Song Select ❌ Not Applicable
    Tune Request ❌ Not Applicable
    MIDI Clock ❌ Not Applicable
    MIDI Start ❌ Not Applicable
    MIDI Continue ❌ Not Applicable
    MIDI Stop ❌ Not Applicable
    Active Sense ❌ Not Applicable
    System Reset ✔️ This message can only be received via live MIDI input, as 0xFF in MIDI files means a meta message.

    As of 4.1.0 SpessaSynth supports per-note Pitch Wheel as a part of the MIDI 2.0 specification. Per-note mode is activated through the API and deactivated on channel or system reset.

    Below is the list of controllers supported by default.

    Legend for the "Type" column:

    • SF2 - Support for this controller is provided by an SF2 default modulator, can be disabled via DMOD.
    • Extended - Support for this controller is provided by a non-SF2 default modulator, can be disabled via DMOD.
    • Engine - Support for this controller is provided with a custom behavior, cannot be disabled via DMOD.
    CC# Controller Name Type Behavior
    0 Bank Select Engine Changes the bank number that is used in Program Change. More info: MIDIPatch
    1 Modulation Wheel SF2 Controls the vibrato for the given patch.
    5 Portamento Time Engine Controls the portamento time. More info
    6 Data Entry MSB Engine Sets the selected RPN or NRPN to the given value. Upper 7 bits. More info
    7 Main Volume SF2 Changes the channel's volume.
    10 Pan SF2 Controls the channel's stereo pan.
    11 Expression SF2 Changes the channel's volume, similarly to Main Volume, but independent of it.
    32 Bank Select LSB Engine Changes the bank number that is used in Program Change. More info: MIDIPatch
    33 - 63 excluding 38 Controller LSB values Engine Extends the precision of the corresponding controllers from 7-bit to 14-bit.
    38 Data Entry LSB Engine Sets the selected RPN or NRPN to the given value. Lower 7 bits. More info
    64 Sustain Pedal Engine Holds the Note Off messages until the pedal is off, then stops them all at once.
    65 Portamento On/Off Engine Controls if the portamento is enabled or not. More info
    67 Soft Pedal Extended Lowers the low-pass filter cutoff frequency.
    71 Filter Resonance Extended Controls the filter resonance of the given patch.
    72 Release Time Extended Controls the release time for the given patch.
    73 Attack Time Extended Controls the attack time for the given patch.
    74 Brightness Extended Controls the brightness (lowpass frequency) of the given patch.
    75 Decay time Extended Controls the decay time for the given patch.
    84 Portamento Control Engine Controls the portamento target key. Forces portamento once, even if portamento is off. The value persists across channel reset. More info
    91 Reverb Depth SF2 Controls the reverb effect send for the given channel. More info
    93 Chorus Depth SF2 Controls the chorus effect for the given channel. More info
    94 Variation Depth Engine In GS mode, it controls the delay effect for the given channel.1
    98 Non-Registered Parameter Number LSB Engine Selects the LSB of the Non-Registered Parameter Number. More info
    99 Non-Registered Parameter Number MSB Engine Selects the MSB of the Non-Registered Parameter Number. More info
    100 Registered Parameter Number LSB Engine Selects the LSB of the Registered Parameter Number. More info
    101 Registered Parameter Number MSB Engine Selects the MSB of the Registered Parameter Number. More info
    120 All Sound Off Engine Immediately terminates all active voices, disregarding their release time.
    121 Reset All Controllers Engine Resets controllers to their default values according to the RP-15 recommended practice.
    123 All Notes Off Engine Stops all notes, respecting their release time.
    124 or 125 Omni mode On/Off Engine Stops all notes, respecting their release time.
    126 or 127 Poly/Mono Mode On/Off Engine Setting the corresponding controller to any value switches the Poly mode on or off, immediately terminating all active voices on the channel. More info

    Below are all the controller values which are not zero when the controllers are reset.

    CC Number Name Reset Value
    0 Bank Select 121 when the synthesizer is in GM2 mode.
    7 Main Volume 100
    8 Balance 64
    10 Pan 64
    11 Expression 127
    71 Timbre Harmonic Content 64
    72 Release Time 64
    73 Attack Time 64
    74 Brightness 64
    75 Decay Time 64
    76 Vibrato Rate 64
    77 Vibrato Depth 64
    78 Vibrato Delay 64
    81 General Purpose Controller 6 64
    83 General Purpose Controller 8 64
    98 Non-Registered Parameter Number LSB 127 (NULL)
    99 Non-Registered Parameter Number MSB 127 (NULL)
    100 Registered Parameter Number LSB 127 (NULL)
    101 Registered Parameter Number MSB 127 (NULL)

    Below is the list of currently implemented Registered Parameters.

    RPN MSB RPN LSB Name Explanation Default
    0 0 Pitch Wheel Range Sets the Channel MIDI Parameter pitchWheelRange 2 semitones
    0 1 Channel Fine Tuning Sets the Channel MIDI Parameter fineTune 0 cents
    0 2 Channel Coarse Tuning Sets the Channel MIDI Parameter keyShift 0 keys
    0 5 Channel Modulation Depth Sets the Channel MIDI Parameter modulationDepth Default SF2 depth (50 cents)
    127 127 Reset parameters Resets the selected RPN/NRPN to NULL (unspecified state). All data entries in this state are recognized as ignored. N.A.

    Below is the list of currently implemented Non-Registered Parameters.

    rr: Drum MIDI note number (0 - 127)

    NRPN MSB NRPN LSB Name Explanation Default
    0x01 0x08 Vibrato Rate Alias to MIDI CC#76. (Vibrato Rate) Also see custom vibrato. 64
    0x01 0x09 Vibrato Depth Alias to MIDI CC#77. (Vibrato Depth) Also see custom vibrato. 64
    0x01 0x0A Vibrato Delay Alias to MIDI CC#78. (Vibrato Delay) Also see custom vibrato. 64
    0x01 0x20 TVF Filter Cutoff Alias to MIDI CC#74. (Brightness) 64
    0x01 0x21 TVF Filter Resonance Alias to MIDI CC#71. (Filter resonance) 64
    0x01 0x63 EG Attack Time Alias to MIDI CC#73. (Attack Time) 64
    0x01 0x64 EG Decay Time Alias to MIDI CC#75. (Decay Time) 64
    0x01 0x66 EG Release Time Alias to MIDI CC#72. (Release Time) 64
    0x18 rr Drum Pitch Controls the pitch of the drum instrument. More info 0
    0x19 rr Drum Pitch Fine Controls the pitch of the drum instrument in cents (XG only) 0
    0x1A rr Drum Level Controls how loud the drum instrument is. 120 (normal)
    0x1C rr Drum Pan Controls the absolute pan position of the drum instrument. 0 is random. 64 leaves the channel pan unchanged (additive of channel) 64 (no override)
    0x1D rr Drum Reverb Controls the reverb level of the drum instrument. (multiplicative of channel) 0 for kick drums, otherwise 127.
    0x1E rr Drum Chorus Controls the chorus level of the drum instrument. (multiplicative of channel) 0, or on XG reset: 0 for kick drums, otherwise 127.
    0x1F rr Drum Variation Controls the variation level of the drum instrument.2 (multiplicative of channel) 0 (none), or on XG reset: 0 for kick drums, otherwise 127.

    The NRPN vibrato messages have special behavior. On synth start and reset it is disabled. Any value other than 64 received for any of the states activates it with the default settings:

    • depth = 50 cents
    • rate = 8 Hz
    • delay = 0.6s

    After which any changes received through the NRPN (including the one that triggered it) are processed.

    Calculation for the specific NRPN parameters are as follows (value is the data entry MSB value from 0 to 127):

    • Rate: Hz = (value / 64) * 8
    • Depth: cents = value / 2
    • Delay: seconds = value / 64 / 3

    This behavior has existed since the beginning of this program as a way to enhance Touhou Project MIDI files, the original target of SpessaSynth.

    It is disabled for any channel that has CC#1 (Mod Wheel) set to anything other than 0. This can be useful as setting CC#1 to something like 1 (which is usually imperceptible), will disable the extra vibrato for this channel when it is globally enabled.

    As of 3.26.15, SpessaSynth supports the standard SF2 NRPN implementation, as defined in Section 9.6 of the SoundFont2.04 specification.

    As of 3.26.11, SpessaSynth supports emulation of the AWE32 NRPN generator modification. The implementation is similar to FluidSynth's emulation, as it has been tested and found relatively accurate to the sound cards. Here are some useful resources about this:

    There are a few differences from FluidSynth's implementation:

    • LSB 16 overrides the fineTune generator instead of emitting a pitch-wheel event.
    • Effect generators get overridden directly rather than passing through the modulator.
    • Filter cutoff and Q have been tuned slightly differently.

    See MIDIPatch for more information.

    General MIDI (Level 1).

    Currently equivalent to GS.

    Roland GS, default.

    Bank MSB processed directly, LSB is ignored, unless a direct match is found. System Exclusive messages can be used to turn a channel into a drum channel.

    General MIDI Level 2.

    Bank LSB and MSB are processed. Default bank MSB is 121 instead of 0. Bank MSB 120 (GM2 drums) or 127 (XG drums) turns a channel into a drum channel (126 SFX drums only match by direct preset match). Drums will be selected according to the XG Validity Test

    Yamaha XG.

    Bank LSB and MSB are processed. Bank MSB 120 or 127 turns a channel into a drum channel (126 SFX drums only match by direct preset match). Drums will be selected according to the XG Validity Test

    Each sound bank is validated for XG compatibility. That is, contains only allowed program numbers in the XG standard for the drum presets. This is done because some sound bank set the bank MSB of 127 for Roland MT presets.

    If a sound bank fails to meet that check, the synthesizer prefers any available XG drums first, then any drum preset, falling back to the first preset if no drums exist. In practice this means the GM/GS drum presets will be used instead when they exist.

    Below is the list of currently implemented System Exclusive messages.

    Jump to the links:

    SpessaSynth has good support for the GS standard, including effects. Below are the supported Roland GS messages.

    All messages with address of 0x10 xx xx are recognized. A displayMessage event will be emitted with the System Exclusive data.

    These are global parameters, affecting the entire synthesizer.

    Name Description
    SYSTEM MODE SET (SC-88+ Reset) Resets the synthesizer and sets the Global MIDI Parameter system to gs. Value 01 (Double Module Mode) also makes the synthesizer ensure that it has at least 32 channels.

    These are global parameters, affecting the entire synthesizer.

    Name Description
    MASTER TUNE Sets the Global MIDI Parameter fineTune.
    MASTER VOLUME Sets the Global MIDI Parameter volume.
    MASTER KEY-SHIFT Sets the Global MIDI Parameter keyShift.
    MASTER PAN Sets the Global MIDI Parameter pan.
    MODE SET GS Reset. Resets the synthesizer and sets the Global MIDI Parameter system to gs.
    PATCH NAME Treated as recognized, decoded name is logged to console if verbose output is enabled. A displayMessage will be emitted with the System Exclusive data.
    Name Description
    REVERB MACRO Sets all Reverb Processor parameters to a predefined value. All GS macros are supported. Refer to SC-8850 Owner's Manual, page 81.
    REVERB CHARACTER Sets the Reverb Processor property character.
    REVERB PRE-LPF Sets the Reverb Processor property preLowpass.
    REVERB LEVEL Sets the Reverb Processor property level.
    REVERB TIME Sets the Reverb Processor property time.
    REVERB DELAY FEEDBACK Sets the Reverb Processor property delayFeedback.
    REVERB PREDELAY TIME Sets the Reverb Processor property preDelayTime.
    Name Description
    CHORUS MACRO Sets all Chorus Processor parameters to a predefined value. All GS macros are supported. Refer to SC-8850 Owner's Manual, page 83.
    CHORUS PRE-LPF Sets the Chorus Processor property preLowpass.
    CHORUS LEVEL Sets the Chorus Processor property level.
    CHORUS FEEDBACK Sets the Chorus Processor property feedback.
    CHORUS DELAY Sets the Chorus Processor property delay.
    CHORUS RATE Sets the Chorus Processor property rate.
    CHORUS DEPTH Sets the Chorus Processor property depth.
    CHORUS SEND LEVEL TO REVERB Sets the Chorus Processor property sendLevelToReverb.
    CHORUS SEND LEVEL TO DELAY Sets the Chorus Processor property sendLevelToDelay.
    Name Description
    DELAY MACRO Sets all Delay Processor parameters to a predefined value. All GS macros are supported. Refer to SC-8850 Owner's Manual, page 85.
    DELAY PRE-LPF Sets the Delay Processor property preLowpass.
    DELAY TIME CENTER Sets the Delay Processor property timeCenter.
    DELAY TIME RATIO LEFT Sets the Delay Processor property timeRatioLeft.
    DELAY TIME RATIO RIGHT Sets the Delay Processor property timeRatioRight.
    DELAY LEVEL CENTER Sets the Delay Processor property levelCenter.
    DELAY LEVEL LEFT Sets the Delay Processor property levelLeft.
    DELAY LEVEL RIGHT Sets the Delay Processor property levelRight.
    DELAY LEVEL Sets the Delay Processor property level.
    DELAY FEEDBACK Sets the Delay Processor property feedback.
    DELAY SEND LEVEL TO REVERB Sets the Delay Processor property sendLevelToReverb.
    Name Description
    EFX TYPE Sets the type of the insertion effect. See supported insertion effects.
    EFX PARAMETER 1-20 Sets the parameters of the insertion effect.
    EFX SEND LEVEL TO REVERB Sets the amount of signal sent from the insertion effect to the reverb effect.
    EFX SEND LEVEL TO CHORUS Sets the amount of signal sent from the insertion effect to the chorus effect.
    EFX SEND LEVEL TO DELAY Sets the amount of signal sent from the insertion effect to the delay effect.

    Part (channel) parameters set a specific parameter for a specific channel.

    Name Description
    TONE NUMBER Bank MSB and Program Change in one message.
    Rx. CHANNEL Sets the Channel MIDI Parameter rxChannel.
    MONO/POLY MODE Sets the Channel MIDI Parameter polyMode. See poly/mono implementation.
    ASSIGN MODE Sets the Channel MIDI Parameter assignMode.
    USE FOR RHYTHM PART Sets the Channel MIDI Parameter drumMap and turns any channel into a drum channel if the value is not 0.3
    PITCH KEY SHIFT Sets the Channel MIDI Parameter keyShift.
    PART LEVEL Aliased to MIDI CC#7 (Main Volume).
    VELOCITY SENSE DEPTH Sets the Channel MIDI Parameter velocitySenseDepth.
    VELOCITY SENSE OFFSET Sets the Channel MIDI Parameter velocitySenseOffset.
    PART PANPOT Aliased to MIDI CC#10 (Pan), except value 0 enables random pan for every new voice on that channel.
    CC1 CONTROLLER NUMBER Sets the Channel MIDI Parameter cc1.
    CC2 CONTROLLER NUMBER Sets the Channel MIDI Parameter cc2.
    CHORUS SEND LEVEL Aliased to MIDI CC#93 (Chorus Depth).
    REVERB SEND LEVEL Aliased to MIDI CC#91 (Reverb Depth).
    PITCH FINE TUNE Sets the Channel MIDI Parameter fineTune.
    DELAY SEND LEVEL Aliased to MIDI CC#94 (Variation Depth).
    TONE MODIFY1 (Vibrato rate) Aliased to MIDI CC#76 (Vibrato Rate).
    TONE MODIFY2 (Vibrato depth) Aliased to MIDI CC#77 (Vibrato Depth).
    TONE MODIFY3 (TVF Cutoff Freq) Aliased to MIDI CC#74 (Brightness).
    TONE MODIFY4 (TVF Resonance) Aliased to MIDI CC#71 (Filter Resonance).
    TONE MODIFY5 (TVF&TVA Env.attack) Aliased to MIDI CC#73 (Attack Time).
    TONE MODIFY6 (TVF&TVA Env.decay) Aliased to MIDI CC#75 (Decay Time).
    TONE MODIFY7 (TVA Env.release) Aliased to MIDI CC#72 (Release Time).
    TONE MODIFY8 (Vibrato delay) Aliased to MIDI CC#78 (Vibrato Delay).
    SCALE TUNING Treated like MTS octave tuning, tunes an octave in cents. Tuning is repeated for all octaves.
    * CONTROL See Patch Part Parameters (Controllers) for more details.
    TONE MAP NUMBER Aliased to MIDI CC#32 (Bank Select LSB).
    TONE MAP-0 NUMBER Aliased to MIDI CC#32 (Bank Select LSB).
    PART EFX ASSIGN Sets the Channel MIDI Parameter efxAssign.

    All of them are supported! At least, in theory. These define how a controller affects the sound. See page 198 of the SC-88Pro Manual. This is implemented using a dynamic modulator system and additional generators to cover the linear time and hertz range.

    There are two special cases that are directly aliased to Channel MIDI Parameters:

    The following messages tune individual drum instruments. A drum instrument is defined as a single MIDI key in the drum preset. These search for a matching drum channel with the correct drumMap Channel MIDI Parameter.

    Name Description
    DRUM MAP NAME Treated as recognized, decoded name is logged to console if verbose output is enabled. A displayMessage event will be emitted with the System Exclusive data.
    PLAY NOTE NUMBER Relative pitch tuning of the instrument. More info
    LEVEL The drum's loudness. Normalized against 120 as gain = (data / 120) ^ 2.
    ASSIGN GROUP NUMBER This overrides the exclusiveClass generator, defining custom exclusive notes.
    PANPOT Pan position of the instrument, except value 0 enables random panning for every note. Value 64 leaves the channel pan unchanged (additive of channel).
    REVERB SEND LEVEL Reverb send level of the instrument. (multiplicative of channel)
    CHORUS SEND LEVEL Chorus send level of the instrument. (multiplicative of channel)
    Rx. NOTE OFF Enabling this (as it is disabled by default) forces the drum instrument to immediately terminate when it receives a Note Off.
    Rx. NOTE ON Disabling this prevents the drum instrument from receiving Note On events.
    DELAY SEND LEVEL Delay send level of the instrument. (multiplicative of channel)

    The following messages create a custom drum set, by setting which key from which drum set is bound to a specific key in the user drum set. Then the parameters above may also be applied to the key. Instruments are available on programs 64 and 65 in GS mode.

    Name Description Parameter Name
    USER DRUM MAP NAME Exactly the same behavior as DRUM MAP NAME. N.A.
    PLAY NOTE NUMBER Relative pitch tuning of the instrument. More info pitchCoarse
    LEVEL The drum's loudness. Normalized against 120 as gain = (data / 120) ^ 2. level
    ASSIGN GROUP NUMBER This overrides the exclusiveClass generator, defining custom exclusive notes. assignGroup
    PANPOT Pan position of the instrument, except value 0 enables random panning for every note. Value 64 leaves the channel pan unchanged (additive of channel). pan
    REVERB SEND LEVEL Reverb send level of the instrument. (multiplicative of channel) reverbSend
    CHORUS SEND LEVEL Chorus send level of the instrument. (multiplicative of channel) chorusSend
    Rx. NOTE OFF Enabling this (as it is disabled by default) forces the drum instrument to immediately terminate when it receives a Note Off. rxNoteOff
    Rx. NOTE ON Disabling this prevents the drum instrument from receiving Note On events. rxNoteOn
    DELAY SEND LEVEL Delay send level of the instrument. (multiplicative of channel) variationSend
    SOURCE DRUM SET# (MAP) Bank LSB number of the source drum set for this key. (GS map) sourceDrumSet
    (PG#: Program number) The program number of the source drum set for this key. program
    SOURCE NOTE NUMBER The MIDI note number of the source drum set for this key. sourceNoteNumber

    Bulk dump messages set many parameters in one message.

    SpessaSynth currently recognizes the bulk dump messages for User Drum Set only.

    SpessaSynth has great support for the XG standard, including effect routing. Below are the supported Yamaha XG System Exclusive messages.

    These are global parameters, affecting the entire synthesizer.

    Name Description
    MASTER TUNE Sets the Global MIDI Parameter fineTune.
    MASTER VOLUME Sets the Global MIDI Parameter volume.
    MASTER ATTENUATOR Sets the Global MIDI Parameter volume with an inverted value.
    MASTER TRANSPOSE Sets the Global MIDI Parameter keyShift
    XG SYSTEM ON Resets the synthesizer and sets the Global MIDI Parameter system to xg.
    ALL PARAMETER RESET Resets the synthesizer and sets the Global MIDI Parameter system to xg.

    All reverb, chorus, and variation parameter addresses are recognized. Selecting an unimplemented reverb or chorus type silences the block (NO EFFECT), while an unimplemented variation type falls back to the "THRU" processor. See currently implemented XG effects.

    Variation can act like a system effect (reverb, chorus), being global with sends for each channel, or like an insertion effect, routing all audio of a single channel through it.

    Name Description
    REVERB TYPE Sets the reverb block type. Unknown types are silent (NO EFFECT).
    REVERB PARAMETER 1-16 Type-specific reverb parameters.
    REVERB RETURN Output level of the reverb block. 0 is silence, 64 is normal, 127 is double volume.
    REVERB PAN Stereo panning of the reverb block. 1 is hard left, 64 is center, 127 is hard right.
    CHORUS TYPE Sets the chorus block type. Unknown types are silent (NO EFFECT).
    CHORUS PARAMETER 1-16 Type-specific chorus parameters.
    CHORUS RETURN Output level of the chorus block. 0 is silence, 64 is normal, 127 is double volume.
    CHORUS PAN Stereo panning of the chorus block. 1 is hard left, 64 is center, 127 is hard right.
    SEND CHORUS TO REVERB Amount of chorus output sent to the reverb block. Heard even at chorus return 0.
    VARIATION TYPE Sets the variation block type. Unknown types pass dry (THRU).
    VARIATION PARAMETER 1-10 Type-specific variation parameters, two-byte.
    VARIATION PARAMETER 11-16 Type-specific variation parameters, single-byte.
    VARIATION RETURN Output level of the variation block. 0 is silence, 64 is normal, 127 is double volume. Ignored in insertion mode.
    VARIATION PAN Stereo panning of the variation block. 1 is hard left, 64 is center, 127 is hard right. Ignored in insertion mode.
    SEND VARIATION TO REVERB Amount of variation output sent to the reverb block.
    SEND VARIATION TO CHORUS Amount of variation output sent to the chorus block.
    VARIATION CONNECTION 0: INSERTION routes a single part through the block (like EFFECT 2), 1: SYSTEM feeds it via sends like reverb and chorus.
    VARIATION PART The part (channel) routed through the block in insertion mode. 127 (OFF) disables the block. Ignored in system mode.

    The MW/BEND/CAT/AC1/AC2 VARIATION CONTROL DEPTHs are not recognized.

    Currently, there are four insertion blocks (n is the insertion effect number), each routing a single part straight through the effect.

    Unknown types use THRU.

    Name Description
    INSERTION EFFECT TYPE Sets the insertion block type.
    INSERTION EFFECT PARAMETER 1-16 Type-specific parameters. Parameters 1-10 use the single-byte form, or the two-byte form when the value needs the upper 7 bits.
    INSERTION EFFECT PART The part (channel) routed through the block. 127 (OFF) disables the block.

    The MW/BEND/CAT/AC1/AC2 INSERTION CONTROL DEPTHs are not recognized.

    Part (channel) parameters set a specific parameter for a specific channel.

    Name Description
    BANK SELECT MSB Aliased to MIDI CC#0 (Bank Select).
    BANK SELECT LSB Aliased to MIDI CC#32 (Bank Select LSB).
    PROGRAM CHANGE Same as a MIDI Program Change on that part's channel.
    RECEIVE CHANNEL NUMBER Sets the Channel MIDI Parameter rxChannel.
    POLY/MONO MODE Sets the Channel MIDI Parameter polyMode. See poly/mono implementation.
    SAME NOTE NUMBER KEY ON ASSIGN Sets the Channel MIDI Parameter assignMode.
    PART MODE Sets the Channel MIDI Parameter drumMap and turns any channel into a drum channel if the value is not 0.4
    NOTE SHIFT Sets the Channel MIDI Parameter keyShift.
    VOLUME Aliased to MIDI CC#7 (Main Volume).
    VELOCITY SENSE DEPTH Sets the Channel MIDI Parameter velocitySenseDepth.
    VELOCITY SENSE OFFSET Sets the Channel MIDI Parameter velocitySenseOffset.
    PAN Aliased to MIDI CC#10 (Pan), except value 0 enables random pan for every new voice on that channel.
    DRY LEVEL Sets the Channel MIDI Parameter dryLevel.
    CHORUS Aliased to MIDI CC#93 (Chorus Depth).
    REVERB Aliased to MIDI CC#91 (Reverb Depth).
    VIBRATO RATE Aliased to MIDI CC#76 (Vibrato Rate).
    VIBRATO DEPTH Aliased to MIDI CC#77 (Vibrato Depth).
    VIBRATO DELAY Aliased to MIDI CC#78 (Vibrato Delay).
    FILTER CUTOFF Aliased to MIDI CC#74 (Brightness).
    FILTER RESONANCE Aliased to MIDI CC#71 (Filter Resonance).
    EG ATTACK TIME Aliased to MIDI CC#73 (Attack Time).
    EG DECAY TIME Aliased to MIDI CC#75 (Decay Time).
    EG RELEASE TIME Aliased to MIDI CC#72 (Release Time).
    AC1 CONTROLLER NUMBER Sets the Channel MIDI Parameter cc1.
    AC2 CONTROLLER NUMBER Sets the Channel MIDI Parameter cc2.
    PORTAMENTO SWITCH Aliased to MIDI CC#65 (Portamento On/Off), as a switch. ON is 127, OFF is 0.
    PORTAMENTO TIME Aliased to MIDI CC#5 (Portamento Time).

    All of them are supported! At least, in theory (excluding HPF which is marked as (NOT USED)) These define how a controller affects the sound. Examples:

    • MW PITCH CONTROL
    • MW FILTER CONTROL
    • PAT AMPLITUDE CONTROL
    • AC2 LFO AMOD DEPTH

    See pages 42 and 43 of the XG specification. This is implemented using a dynamic modulator system and additional generators to cover the linear amplitude range.

    There are two special cases that are directly aliased to Channel MIDI Parameters:

    The following messages tune individual drum instruments. A drum instrument is defined as a single MIDI key in the drum preset.

    Edits are applied to every drum channel: for each note/key, all drum channels get the same stored parameters, as there isn't a MAP system, like in GS.

    Name Description
    PITCH COARSE Relative pitch tuning of the instrument. More info
    PITCH FINE Cent tuning for the drum instrument.
    LEVEL Normalizes loudness as gain = (data / 120) ^ 2.
    ALTERNATE GROUP Overrides the exclusiveClass generator for that drum instrument.
    PAN Pan position of the instrument, except value 0 enables random panning for every note. Value 64 leaves the channel pan unchanged (additive of channel).
    REVERB SEND Reverb send level of the instrument. (multiplicative of channel)
    CHORUS SEND Chorus send level of the instrument. (multiplicative of channel)
    VARIATION SEND Variation send level of the instrument. (multiplicative of channel)
    Rcv NOTE OFF Enabling this (as it is disabled by default) forces the drum instrument to immediately terminate when it receives a Note Off.
    Rcv NOTE ON Disabling this prevents the drum instrument from receiving Note On events.
    Name Description
    Display Letter The text that XG MIDIs display on the device. A displayMessage event will be emitted with the System Exclusive data.
    Display Bitmap Dot matrix display data for the XG devices. A displayMessage event will be emitted with the System Exclusive data.

    SpessaSynth has good support for the Universal MIDI System Exclusives, including General MIDI 2 and Device Control messages. Below are the supported Universal System Exclusive messages.

    Name Description
    Master Volume Sets the Global MIDI Parameter volume.
    Master Balance Sets the Global MIDI Parameter pan.
    Master Fine-Tuning Sets the Global MIDI Parameter fineTune.
    Master Coarse Tuning Sets the Global MIDI Parameter keyShift.
    Name Description
    Reverb Type Sets all Reverb Processor parameters to a predefined value. All GS macros are supported. Refer to SC-8850 Owner's Manual, page 81.
    Reverb Time Sets the Reverb Processor property time.
    Chorus Type Sets all Chorus Processor parameters to a predefined value. All GS macros are supported. Refer to SC-8850 Owner's Manual, page 83.
    Mod Rate Sets the Chorus Processor property rate.
    Mod Depth Sets the Chorus Processor property depth.
    Feedback Sets the Chorus Processor property feedback.
    Send to Reverb Sets the Chorus Processor property sendLevelToReverb.
    Name Description
    GM System Off Resets the synthesizer and sets the Global MIDI Parameter system to gs.
    GM1 System On Resets the synthesizer and sets the Global MIDI Parameter system to gm.
    GM2 System On Resets the synthesizer and sets the Global MIDI Parameter system to gm2.

    Below are the supported messages for the MTS. Both non-realtime and realtime are treated as realtime.

    Name Description
    Bulk Tuning Dump Tuning dump for all 128 notes.
    Scale Octave Tuning (1 byte) Tunes an octave in cents. Tuning is repeated for all octaves.
    Scale Octave Tuning (2 bytes) Tunes an octave in cents. Tuning is repeated for all octaves.
    Single Note Tuning Change Tunes a single note.5

    As of 4.3.6 SpessaSynth supports overlapping MIDI notes (for example two consecutive Note On messages and two Note Off messages after), matching the behavior of Sound Canvases and XG synthesizers. Although overlapping notes are not technically permitted by the MIDI standard, some files use them anyway.

    The implementation is FIFO - First In, First Out. The first voice that started playing on the note will be stopped upon receiving the Note Off. This behavior is tracked independently per channel.

    The following example describes the behavior:

    1. Program Change to 80 - Square Wave.
    2. Note On 60, Square Wave starts playing.
    3. Program Change to 81 - Saw Wave.
    4. Note On 60, Saw Wave starts playing on top of Square Wave.
    5. Note Off 60, Square Wave stops playing, only Saw Wave sounds.
    6. Note Off 60, Saw Wave stops playing.

    SpessaSynth's poly/mono mode implementation works like the GS implementation. This is regardless of the current MIDI system.

    Poly Mode is regular playback, multiple notes are allowed on the channel. It is the default mode on all channels.

    Mono Mode allows only a single note on the channel. A Note On for a different pitch will immediately terminate the previously tracked mono note. Releasing a note while another one is held will retrigger the highest currently held note, with the velocity of the last Note On.

    SpessaSynth attempts to recreate the old Sound Canvas/Yamaha XG portamento behavior.

    That is:

    • Portamento Time is only 7-bit. (only CC#5 is processed)
    • Setting Portamento Control (CC#84) overrides the current from key and forces portamento on the next Note On that can apply portamento, regardless of CC#65 (Portamento On/Off) being enabled.
    • If Portamento is on (CC#65 >= 64), the note glides from the previous note.
    • For XG, the initial key to glide from is 60, for other systems there's no initial glide.
    • Portamento is applied only when the channel is not a drum channel, the previous note is valid (>= 0), differs from the new note, and the portamento time is non-zero.
    • Portamento Time depends on the distance of the keys. The rate is constant so the time scales linearly with distance. The final calculation is portamentoSeconds = portamentoTimeToSeconds(cc5, keyDistance).
    • The rate comes from a table measured on the original Sound Canvas firmware, with one rate for every CC#5 value. All systems use it. For example, gliding over 40 semitones takes 0.54 s at CC#5 = 32, 2.16 s at 64, 8.64 s at 96 and 40 s at 120.
    • The details of the portamentoTimeToSeconds function can be found here.

    Relative pitch tuning of the drum instrument has special handling. Precision depends on the mode:

    For XG: The drum tuning resolution is 100 cents, i.e. a semitone.

    For GS: It depends on the bank LSB number (MSB and drum map are ignored for this detection):

    • Bank LSB value of 1 indicates an SC-55 preset, the resolution is 100 cents, i.e. a semitone
    • Any other value is treated as SC-88 or higher, where the resolution (for whatever reason) is 50 cents.

    SpessaSynth's GS effects are modeled after the Sound Canvas line. There are currently 3 system effect processors and the insertion processors, below are their built-in, default implementations.

    Note that all three can be replaced with custom effect processors. The XG effect blocks can likewise be replaced, see XG effects.

    Characters 0-5 use the Dattorro reverb model, based on this processor. Each of the characters has parameters tuned to match the SC-55 effects more closely. The built-in pre-lowpass filter is used for the pre-LPF param.

    Character 6 uses a single delay line while character 7 uses a ping-pong delay. A simple 1st order lowpass filter is used for the pre-LPF param.

    Implemented using 2 delay lines modulated by triangle LFOs. A simple 1st order lowpass filter is used for the pre-LPF param.

    Implemented using a single shared circular buffer with three read indexes (center, left, right), with the central tap having feedback and feeding into the stereo taps. Input is fed to all three taps.

    SpessaSynth has an architecture in place to support SC-88Pro+ insertion effects.

    • Stereo-EQ
    • Phaser
    • Auto Pan
    • Auto Wah (needs improvements)
    • Tremolo
    • PH + Auto Wah

    SpessaSynth's XG effect routing is fully in place: system sends, post-insertion channel processing, variation system/insertion dual mode and four EFFECT 2 blocks.

    Each effect can have a type which has its own DSP processor.

    Applies to: Reverb, Chorus, Variation in System mode.

    These effects behave similarly to their GS counterparts, respecting channel send values and having them routed globally.

    Applies to: Insertion (EFFECT2), Variation in Insertion mode.

    These effects behave similarly to GS insertion, but they only apply to one part (channel). Multiple insertions may be applied to a part, chaining the effects.

    Variation is a unique effect which can function both as a System Effect and as an Insertion Effect. The behavior depends on "VARIATION CONNECTION" which defaults to "INSERTION" and can be changed to "SYSTEM".

    • NO EFFECT - silence in the reverb, chorus and variation blocks.
    • THRU - passes dry. Also used as the fallback: unknown variation types and unknown EFFECT 2 types pass dry, while unknown reverb and chorus types are silent (NO EFFECT).
    • Reverb block: HALL 1/2, HALL M/L, ROOM 1/2/3, ROOM S/M/L, STAGE 1/2, PLATE, GM PLATE, WHITE ROOM, TUNNEL and BASEMENT. Other LSB values use the type with LSB 00. All reverb parameters are recognized and clamped to their XG ranges.
    • Chorus block: CHORUS 1-4, GM CHORUS 1-4, FB CHORUS, CELESTE 1-4, FLANGER 1-3 and GM FLANGER. Other LSB values use the type with LSB 00. All chorus parameters except Dry/Wet are recognized and clamped to their XG ranges. The input mode of the flangers is fixed per type.
    • Variation block and EFFECT 2 (insertion) blocks: HALL 1/2, ROOM 1/2/3, STAGE 1/2, PLATE, CHORUS 1-4, CELESTE 1-4 and FLANGER 1-3 (same type numbers as above, other LSB values use the type with LSB 00), DELAY L,C,R, DELAY L,R, ECHO, CROSS DELAY, KARAOKE 1-3, SYMPHONIC, ROTARY SPEAKER, TREMOLO, AUTO PAN, PHASER 1, DISTORTION, OVER DRIVE, AMP SIMULATOR, 3-BAND EQ, 2-BAND EQ and AUTO WAH. In the insertion mode, Dry/Wet (parameter 10) is used. In the system mode the output is fully wet.
    • Variation block only: EARLY REF 1/2, GATE REVERB, REVERSE GATE and PHASER 2 (EFFECT 2 uses PHASER 1 for it).

    1. In XG mode it controls the variation send level instead (only when variation connection is set to "system").

      ↩
    2. This controls the delay level in GS/GM mode. In XG mode, it controls the variation send level (only when variation connection is set to "system").

      ↩
    3. Unlike with Sound Canvases, there's no limit to drum channels the synthesizer can have. The Drum Map number is stored in Channel MIDI Parameter drumMap. Switching resets the bank to 0 and the program to 0 and changing the drum map number re-selects the kit the same way.

      ↩
    4. In XG, the conventional drum channel (9 within each 16-channel group) cannot be switched back to melodic mode. Switching to drums re-initializes the kit, resetting the program to 0, while switching back to melodic keeps the program.

      ↩
    5. Note that this can theoretically be used as per-note Pitch Wheel.

      ↩