Ticket #8940: adlib-percussion.patch

File adlib-percussion.patch, 2.8 KB (added by jvprat, 16 years ago)
  • sound/softsynth/adlib.cpp

     
    143143        void init(MidiDriver_ADLIB *owner, byte channel);
    144144
    145145public:
     146        ~AdlibPercussionChannel();
     147
    146148        void noteOff(byte note);
    147149        void noteOn(byte note, byte velocity);
    148150        void programChange(byte program) { }
    149151        void pitchBend(int16 bend) { }
    150152
    151153        // Control Change messages
    152         void controlChange(byte control, byte value) { }
    153154        void modulationWheel(byte value) { }
    154155        void pitchBendFactor(byte value) { }
    155156        void detune(byte value) { }
     
    157158        void sustain(bool value) { }
    158159
    159160        // SysEx messages
    160         void sysEx_customInstrument(uint32 type, const byte *instr) { }
     161        void sysEx_customInstrument(uint32 type, const byte *instr);
     162
     163private:
     164        byte _notes[256];
     165        AdlibInstrument *_customInstruments[256];
    161166};
    162167
    163168struct Struct10 {
     
    775780
    776781// MidiChannel method implementations for percussion
    777782
     783AdlibPercussionChannel::~AdlibPercussionChannel() {
     784        for (int i = 0; i < ARRAYSIZE(_customInstruments); ++i) {
     785                delete _customInstruments[i];
     786        }
     787}
     788
    778789void AdlibPercussionChannel::init(MidiDriver_ADLIB *owner, byte channel) {
    779790        AdlibPart::init(owner, channel);
    780791        _pri_eff = 0;
    781792        _vol_eff = 127;
     793
     794        // Initialize the custom instruments data
     795        memset(_notes, 0, sizeof(_notes));
     796        memset(_customInstruments, 0, sizeof(_customInstruments));
    782797}
    783798
    784799void AdlibPercussionChannel::noteOff(byte note) {
     
    797812}
    798813
    799814void AdlibPercussionChannel::noteOn(byte note, byte velocity) {
    800         byte key = gm_percussion_lookup[note];
    801         if (key == 0xFF) {
    802                 debug(2, "No FM map for GM percussion key %d", (int) note);
     815        AdlibInstrument *inst = NULL;
     816
     817        // The custom instruments have priority over the default mapping
     818        inst = _customInstruments[note];
     819        if (inst)
     820                note = _notes[note];
     821
     822        if (!inst) {
     823                // Use the default GM to FM mapping as a fallback as a fallback
     824                byte key = gm_percussion_lookup[note];
     825                if (key != 0xFF)
     826                        inst = (AdlibInstrument *)&gm_percussion_to_fm[key];
     827        }
     828
     829        if (!inst) {
     830                debug(2, "No instrument FM definition for GM percussion key %d", (int)note);
    803831                return;
    804832        }
    805         _owner->part_key_on(this, (AdlibInstrument *) &gm_percussion_to_fm[key], note, velocity);
     833
     834        _owner->part_key_on(this, inst, note, velocity);
    806835}
    807836
     837void AdlibPercussionChannel::sysEx_customInstrument(uint32 type, const byte *instr) {
     838        if (type == 'ADLP') {
     839                byte note = *instr;
     840                _notes[note] = *(instr + 1);
     841
     842                // Allocate memory for the new instruments
     843                if (!_customInstruments[note]) {
     844                        _customInstruments[note] = new AdlibInstrument;
     845                }
     846
     847                // Save the new instrument data
     848                memcpy(_customInstruments[note], instr + 2, sizeof(AdlibInstrument));
     849        }
     850}
     851
    808852// MidiDriver method implementations
    809853
    810854MidiDriver_ADLIB::MidiDriver_ADLIB(Audio::Mixer *mixer)