diff options
author | Jamieson Christian | 2002-11-26 16:54:58 +0000 |
---|---|---|
committer | Jamieson Christian | 2002-11-26 16:54:58 +0000 |
commit | 973164a74177f5f3fe3b15567f7a0ac329abdc52 (patch) | |
tree | 8244e071531983592feaf41ad128322f97ccf50a /scumm | |
parent | 4544d24fe2995426bb8687799f84fe673cca6f06 (diff) | |
download | scummvm-rg350-973164a74177f5f3fe3b15567f7a0ac329abdc52.tar.gz scummvm-rg350-973164a74177f5f3fe3b15567f7a0ac329abdc52.tar.bz2 scummvm-rg350-973164a74177f5f3fe3b15567f7a0ac329abdc52.zip |
Restructured MIDI channel allocation architecture.
Adlib no longer suffers from 16-channel MIDI restrictions.
Fixes a regression in the MI2 intro music under Adlib.
svn-id: r5721
Diffstat (limited to 'scumm')
-rw-r--r-- | scumm/imuse.cpp | 219 |
1 files changed, 128 insertions, 91 deletions
diff --git a/scumm/imuse.cpp b/scumm/imuse.cpp index 09b069bd7d..1c529fc57a 100644 --- a/scumm/imuse.cpp +++ b/scumm/imuse.cpp @@ -112,8 +112,8 @@ public: class IMuseDriver; struct Part; -struct MidiChannelAdl; -struct MidiChannelGM; +// struct MidiChannelAdl; +// struct MidiChannelGM; struct Instrument; @@ -262,7 +262,7 @@ struct IsNoteCmdData { }; - +/* struct MidiChannel { Part *_part; MidiChannel() : _part(0) {} @@ -273,10 +273,10 @@ struct MidiChannel { struct MidiChannelGM : MidiChannel { byte _chan; - uint16 _actives[8]; - MidiChannelGM() : _chan(0) { memset(_actives, 0, 16); } +// uint16 _actives[8]; +// MidiChannelGM() : _chan(0) { memset(_actives, 0, 16); } }; - +*/ struct Part { int _slot; @@ -302,6 +302,9 @@ struct Part { byte _percussion; byte _bank; + // Used to be in MidiDriverGM. + uint16 _actives[8]; + void key_on(byte note, byte velocity); void key_off(byte note); void set_param(byte param, int value); @@ -577,7 +580,7 @@ struct MidiChannelAdl : MidiChannel { MidiChannelAdl() : _next(0), _prev(0) {} }; - +/* class IMuseAdlib : public IMuseDriver { private: FM_OPL *_opl; @@ -661,7 +664,7 @@ public: return 1; } }; - +*/ /* IMuseGM classes */ @@ -669,7 +672,7 @@ class IMuseGM : public IMuseDriver { IMuseInternal *_se; OSystem *_system; MidiDriver *_md; - MidiChannelGM _midi_channels[16]; +// MidiChannelGM _midi_channels[16]; Instrument _part_instr[32]; // Adlib custom instruments Instrument _glob_instr[32]; // Adlib custom instruments @@ -1937,7 +1940,8 @@ int IMuseInternal::initialize(OSystem *syst, MidiDriver *midi, SoundMixer *mixer IMuseDriver *driv; if (midi == NULL) { - driv = new IMuseAdlib(mixer); +// driv = new IMuseAdlib(mixer); + driv = NULL; } else { driv = new IMuseGM(midi); } @@ -3559,6 +3563,7 @@ void Part::init(IMuseDriver * driver) _next = NULL; _prev = NULL; _mc = NULL; + memset(_actives, 0, sizeof (_actives)); } void Part::setup(Player *player) @@ -3663,7 +3668,7 @@ void Part::set_instrument(uint b) //***** ADLIB PART OF IMUSE STARTS HERE ****** //******************************************** - +/* static byte lookup_table[64][32]; const byte volume_table[] = { 0, 4, 7, 11, @@ -3814,21 +3819,21 @@ static const byte channel_mappings_2[9] = { }; static const AdlibSetParams adlib_setparam_table[] = { - {0x40, 0, 63, 63}, /* level */ - {0xE0, 2, 0, 0}, /* unused */ - {0x40, 6, 192, 0}, /* level key scaling */ - {0x20, 0, 15, 0}, /* modulator frequency multiple */ - {0x60, 4, 240, 15}, /* attack rate */ - {0x60, 0, 15, 15}, /* decay rate */ - {0x80, 4, 240, 15}, /* sustain level */ - {0x80, 0, 15, 15}, /* release rate */ - {0xE0, 0, 3, 0}, /* waveform select */ - {0x20, 7, 128, 0}, /* amp mod */ - {0x20, 6, 64, 0}, /* vib */ - {0x20, 5, 32, 0}, /* eg typ */ - {0x20, 4, 16, 0}, /* ksr */ - {0xC0, 0, 1, 0}, /* decay alg */ - {0xC0, 1, 14, 0} /* feedback */ + {0x40, 0, 63, 63}, // level + {0xE0, 2, 0, 0}, // unused + {0x40, 6, 192, 0}, // level key scaling + {0x20, 0, 15, 0}, // modulator frequency multiple + {0x60, 4, 240, 15}, // attack rate + {0x60, 0, 15, 15}, // decay rate + {0x80, 4, 240, 15}, // sustain level + {0x80, 0, 15, 15}, // release rate + {0xE0, 0, 3, 0}, // waveform select + {0x20, 7, 128, 0}, // amp mod + {0x20, 6, 64, 0}, // vib + {0x20, 5, 32, 0}, // eg typ + {0x20, 4, 16, 0}, // ksr + {0xC0, 0, 1, 0}, // decay alg + {0xC0, 1, 14, 0} // feedback }; void IMuseAdlib::adlib_set_param(int channel, byte param, int value) @@ -4762,7 +4767,7 @@ int IMuseAdlib::part_update_active(Part *part, uint16 *active) } return count; } - +*/ //******************************************** //** GENERAL MIDI PART OF IMUSE STARTS HERE ** //******************************************** @@ -4889,27 +4894,40 @@ void IMuseGM::midiSilence(byte chan) void IMuseGM::part_key_on(Part *part, byte note, byte velocity) { - MidiChannelGM *mc = part->_mc->gm(); + MidiChannel/*GM*/ *mc = part->_mc;//->gm(); + part->_actives[note >> 4] |= (1 << (note & 0xF)); if (mc) { - mc->_actives[note >> 4] |= (1 << (note & 0xF)); - midiNoteOn(mc->_chan, note, velocity); +// mc->_actives[note >> 4] |= (1 << (note & 0xF)); +// midiNoteOn(mc->_chan, note, velocity); + mc->noteOn (note, velocity); } else if (part->_percussion) { - midiVolume(PERCUSSION_CHANNEL, part->_vol_eff); - midiProgram(PERCUSSION_CHANNEL, part->_bank, part->_player->_mt32emulate); - midiNoteOn(PERCUSSION_CHANNEL, note, velocity); +// midiVolume(PERCUSSION_CHANNEL, part->_vol_eff); +// midiProgram(PERCUSSION_CHANNEL, part->_bank, part->_player->_mt32emulate); +// midiNoteOn(PERCUSSION_CHANNEL, note, velocity); + mc = _md->getPercussionChannel(); + if (!mc) + return; + mc->volume (part->_vol_eff); + mc->programChange (part->_bank /*, part->_player->_mt32emulate*/); + mc->noteOn (note, velocity); } } void IMuseGM::part_key_off(Part *part, byte note) { - MidiChannelGM *mc = part->_mc->gm(); + MidiChannel/*GM*/ *mc = part->_mc;//->gm(); + part->_actives[note >> 4] &= ~(1 << (note & 0xF)); if (mc) { - mc->_actives[note >> 4] &= ~(1 << (note & 0xF)); - midiNoteOff(mc->_chan, note); +// mc->_actives[note >> 4] &= ~(1 << (note & 0xF)); +// midiNoteOff(mc->_chan, note); + mc->noteOff (note); } else if (part->_percussion) { - midiNoteOff(PERCUSSION_CHANNEL, note); +// midiNoteOff(PERCUSSION_CHANNEL, note); + mc = _md->getPercussionChannel(); + if (mc) + mc->noteOff (note); } } @@ -4984,22 +5002,22 @@ int IMuseGM::midi_driver_thread(void *param) void IMuseGM::init(IMuseInternal *eng, OSystem *syst) { int i; - MidiChannelGM *mc; +// MidiChannel/*GM*/ *mc; _system = syst; - /* open midi driver */ + // Open MIDI driver int result = _md->open(MidiDriver::MO_SIMPLE); if (result) error("IMuseGM::error = %s", MidiDriver::get_error_name(result)); - /* Install the on_timer thread */ + // Connect to the driver's timer _se = eng; // syst->create_thread(midi_driver_thread, this); _md->setTimerCallback (NULL, &IMuseGM::timer_callback); - for (i = 0, mc = _midi_channels; i != ARRAYSIZE(_midi_channels); i++, mc++) { - mc->_chan = i; + for (i = 0; i != ARRAYSIZE(_midi_program_last); i++) { +// mc->_chan = i; _midi_program_last [i] = 255; } } @@ -5018,7 +5036,8 @@ void IMuseGM::update_pris() Part *part, *hipart; int i; byte hipri, lopri; - MidiChannelGM *mc, *lomc; +// MidiChannel/*GM*/ *mc, *lomc; + Part *lopart; while (true) { hipri = 0; @@ -5033,30 +5052,26 @@ void IMuseGM::update_pris() if (!hipart) return; - lopri = 255; - lomc = NULL; - for (i = ARRAYSIZE(_midi_channels), mc = _midi_channels;; mc++) { - if (mc->_chan != 9) { - if (!mc->_part) { - lomc = mc; - break; - } - if (mc->_part->_pri_eff <= lopri) { - lopri = mc->_part->_pri_eff; - lomc = mc; - } - } + if ((hipart->_mc = _md->allocateChannel()) != NULL) { + hipart->changed (pcAll); + return; + } - if (!--i) { - if (lopri >= hipri) - return; - lomc->_part->off(); - break; + lopri = 255; + lopart = NULL; + for (i = 32, part = _se->parts_ptr(); i; i--, part++) { + if (part->_mc && part->_pri_eff <= lopri) { + lopri = part->_pri_eff; + lopart = part; } } - hipart->_mc = lomc; - lomc->_part = hipart; + if (lopart == NULL || lopri >= hipri) + return; + lopart->off(); + + if ((hipart->_mc = _md->allocateChannel()) == NULL) + return; hipart->changed(pcAll); } } @@ -5069,7 +5084,8 @@ int IMuseGM::part_update_active(Part *part, uint16 *active) bits = 1 << part->_chan; - act = part->_mc->gm()->_actives; +// act = part->_mc->gm()->_actives; + act = part->_actives; for (i = 8; i; i--) { mask = *act++; @@ -5102,83 +5118,104 @@ void IMuseGM::set_instrument(uint slot, byte *data) void IMuseGM::part_changed(Part *part, uint16 what) { - MidiChannelGM *mc; + MidiChannel/*GM*/ *mc; - /* Mark for re-schedule if program changed when in pre-state */ + // Mark for re-schedule if program changed when in pre-state if (what & pcProgram && !part->_percussion && !part->_mc) { update_pris(); } - if (!(mc = part->_mc->gm())) + if (!(mc = part->_mc/*->gm()*/)) return; - if (part->_player == NULL) { /* No player, so dump phantom channel */ + if (part->_player == NULL) { // No player, so dump phantom channel + part->_mc->release(); part->_mc = NULL; - mc->_part = NULL; - memset(mc->_actives, 0, sizeof(mc->_actives)); +// mc->_part = NULL; +// memset(mc->_actives, 0, sizeof(mc->_actives)); + memset(part->_actives, 0, sizeof(part->_actives)); return; } if (what & pcPitchBendFactor) - midiPitchBendFactor (mc->_chan, part->_pitchbend_factor); +// midiPitchBendFactor (mc->_chan, part->_pitchbend_factor); + mc->pitchBendFactor (part->_pitchbend_factor); if (what & pcMod) - midiPitchBend(mc->_chan, - clamp(part->_pitchbend + - (part->_detune_eff * 64 / 12) + - (part->_transpose_eff * 8192 / 12), -8192, 8191)); +// midiPitchBend(mc->_chan, +// clamp(part->_pitchbend + +// (part->_detune_eff * 64 / 12) + +// (part->_transpose_eff * 8192 / 12), -8192, 8191)); + mc->pitchBend (clamp(part->_pitchbend + + (part->_detune_eff * 64 / 12) + + (part->_transpose_eff * 8192 / 12), -8192, 8191)); if (what & pcVolume) - midiVolume(mc->_chan, part->_vol_eff); +// midiVolume(mc->_chan, part->_vol_eff); + mc->volume (part->_vol_eff); if (what & pcPedal) - midiPedal(mc->_chan, part->_pedal); +// midiPedal(mc->_chan, part->_pedal); + mc->sustain (part->_pedal); if (what & pcModwheel) - midiModWheel(mc->_chan, part->_modwheel); +// midiModWheel(mc->_chan, part->_modwheel); + mc->modulationWheel (part->_modwheel); if (what & pcPan) - midiPan(mc->_chan, part->_pan_eff); +// midiPan(mc->_chan, part->_pan_eff); + mc->panPosition (part->_pan_eff); if (what & pcEffectLevel) - midiEffectLevel(mc->_chan, part->_effect_level); +// midiEffectLevel(mc->_chan, part->_effect_level); + mc->effectLevel (part->_effect_level); if (what & pcProgram) { if (part->_player->_isGM) { if (part->_program < 128) { _midi_program_last [part->_chan] = part->_program; if (part->_bank) { - midiControl0(mc->_chan, part->_bank); - midiProgram(mc->_chan, part->_program, part->_player->_mt32emulate); - midiControl0(mc->_chan, 0); +// midiControl0(mc->_chan, part->_bank); +// midiProgram(mc->_chan, part->_program, part->_player->_mt32emulate); +// midiControl0(mc->_chan, 0); + mc->controlChange (0, part->_bank); + mc->programChange (part->_program /*, part->_player->_mt32emulate*/); + mc->controlChange (0, 0); } else { - midiProgram(mc->_chan, part->_program, part->_player->_mt32emulate); +// midiProgram(mc->_chan, part->_program, part->_player->_mt32emulate); + mc->programChange (part->_program /*, part->_player->_mt32emulate*/); } } } else { if (part->_program < 32) { memcpy (&_part_instr [part->_slot], &_glob_instr[part->_program], sizeof (Instrument)); } - _md->sysEx_customInstrument (mc->_chan, 'ADL ', (byte *) (&_part_instr [part->_slot])); +// _md->sysEx_customInstrument (mc->_chan, 'ADL ', (byte *) (&_part_instr [part->_slot])); + mc->sysEx_customInstrument ('ADL ', (byte *) (&_part_instr [part->_slot])); } } if (what & pcChorus) - midiChorus(mc->_chan, part->_effect_level); +// midiChorus(mc->_chan, part->_effect_level); + mc->chorusLevel (part->_effect_level); if (what & pcPriority) - _md->send ((part->_pri_eff << 16) | (18 << 8) | 0xB0 | mc->_chan); +// _md->send ((part->_pri_eff << 16) | (18 << 8) | 0xB0 | mc->_chan); + mc->priority (part->_pri_eff); } void IMuseGM::part_off(Part *part) { - MidiChannelGM *mc = part->_mc->gm(); + MidiChannel/*GM*/ *mc = part->_mc/*->gm()*/; if (mc) { + mc->allNotesOff(); + mc->release(); part->_mc = NULL; - mc->_part = NULL; - memset(mc->_actives, 0, sizeof(mc->_actives)); - midiSilence(mc->_chan); +// mc->_part = NULL; +// memset(mc->_actives, 0, sizeof(mc->_actives)); + memset(part->_actives, 0, sizeof(part->_actives)); +// midiSilence(mc->_chan); } } |