diff options
author | Jordi Vilalta Prat | 2008-12-19 16:21:27 +0000 |
---|---|---|
committer | Jordi Vilalta Prat | 2008-12-19 16:21:27 +0000 |
commit | c4f33dfb866e71ff34331fe696076c0ffc2f60eb (patch) | |
tree | e16e8280a0ff31c133bdbe41eb5f461420fc41d9 /sound/softsynth | |
parent | 519815cb51aad20198ea8eeb771c1dc6cedc959f (diff) | |
download | scummvm-rg350-c4f33dfb866e71ff34331fe696076c0ffc2f60eb.tar.gz scummvm-rg350-c4f33dfb866e71ff34331fe696076c0ffc2f60eb.tar.bz2 scummvm-rg350-c4f33dfb866e71ff34331fe696076c0ffc2f60eb.zip |
Custom percussion instruments for the AdLib MIDI driver (Slightly modified patch #2357165)
svn-id: r35439
Diffstat (limited to 'sound/softsynth')
-rw-r--r-- | sound/softsynth/adlib.cpp | 66 |
1 files changed, 60 insertions, 6 deletions
diff --git a/sound/softsynth/adlib.cpp b/sound/softsynth/adlib.cpp index 86ee466065..af6c9d488c 100644 --- a/sound/softsynth/adlib.cpp +++ b/sound/softsynth/adlib.cpp @@ -143,13 +143,14 @@ protected: void init(MidiDriver_ADLIB *owner, byte channel); public: + ~AdlibPercussionChannel(); + void noteOff(byte note); void noteOn(byte note, byte velocity); void programChange(byte program) { } void pitchBend(int16 bend) { } // Control Change messages - void controlChange(byte control, byte value) { } void modulationWheel(byte value) { } void pitchBendFactor(byte value) { } void detune(byte value) { } @@ -157,7 +158,11 @@ public: void sustain(bool value) { } // SysEx messages - void sysEx_customInstrument(uint32 type, const byte *instr) { } + void sysEx_customInstrument(uint32 type, const byte *instr); + +private: + byte _notes[256]; + AdlibInstrument *_customInstruments[256]; }; struct Struct10 { @@ -775,10 +780,20 @@ void AdlibPart::sysEx_customInstrument(uint32 type, const byte *instr) { // MidiChannel method implementations for percussion +AdlibPercussionChannel::~AdlibPercussionChannel() { + for (int i = 0; i < ARRAYSIZE(_customInstruments); ++i) { + delete _customInstruments[i]; + } +} + void AdlibPercussionChannel::init(MidiDriver_ADLIB *owner, byte channel) { AdlibPart::init(owner, channel); _pri_eff = 0; _vol_eff = 127; + + // Initialize the custom instruments data + memset(_notes, 0, sizeof(_notes)); + memset(_customInstruments, 0, sizeof(_customInstruments)); } void AdlibPercussionChannel::noteOff(byte note) { @@ -797,12 +812,51 @@ void AdlibPercussionChannel::noteOff(byte note) { } void AdlibPercussionChannel::noteOn(byte note, byte velocity) { - byte key = gm_percussion_lookup[note]; - if (key == 0xFF) { - debug(2, "No FM map for GM percussion key %d", (int) note); + AdlibInstrument *inst = NULL; + + // The custom instruments have priority over the default mapping + inst = _customInstruments[note]; + if (inst) + note = _notes[note]; + + if (!inst) { + // Use the default GM to FM mapping as a fallback as a fallback + byte key = gm_percussion_lookup[note]; + if (key != 0xFF) + inst = (AdlibInstrument *)&gm_percussion_to_fm[key]; + } + + if (!inst) { + debug(2, "No instrument FM definition for GM percussion key %d", (int)note); return; } - _owner->part_key_on(this, (AdlibInstrument *) &gm_percussion_to_fm[key], note, velocity); + + _owner->part_key_on(this, inst, note, velocity); +} + +void AdlibPercussionChannel::sysEx_customInstrument(uint32 type, const byte *instr) { + if (type == 'ADLP') { + byte note = instr[0]; + _notes[note] = instr[1]; + + // Allocate memory for the new instruments + if (!_customInstruments[note]) { + _customInstruments[note] = new AdlibInstrument; + } + + // Save the new instrument data + _customInstruments[note]->mod_characteristic = instr[2]; + _customInstruments[note]->mod_scalingOutputLevel = instr[3]; + _customInstruments[note]->mod_attackDecay = instr[4]; + _customInstruments[note]->mod_sustainRelease = instr[5]; + _customInstruments[note]->mod_waveformSelect = instr[6]; + _customInstruments[note]->car_characteristic = instr[7]; + _customInstruments[note]->car_scalingOutputLevel = instr[8]; + _customInstruments[note]->car_attackDecay = instr[9]; + _customInstruments[note]->car_sustainRelease = instr[10]; + _customInstruments[note]->car_waveformSelect = instr[11]; + _customInstruments[note]->feedback = instr[12]; + } } // MidiDriver method implementations |