diff options
-rw-r--r-- | backends/midi/ym2612.cpp | 141 | ||||
-rw-r--r-- | scumm/midiparser_eup.cpp | 26 |
2 files changed, 68 insertions, 99 deletions
diff --git a/backends/midi/ym2612.cpp b/backends/midi/ym2612.cpp index fcdfa26f25..69bfef8cc9 100644 --- a/backends/midi/ym2612.cpp +++ b/backends/midi/ym2612.cpp @@ -97,9 +97,7 @@ public: class Voice2612 { public: - MidiChannel_YM2612 *_owner; - Voice2612 *prev, *next; - bool _in_use; + Voice2612 *next; uint16 _rate; protected: @@ -129,18 +127,17 @@ public: class MidiChannel_YM2612 : public MidiChannel { protected: - MidiDriver_YM2612 *_owner; uint16 _rate; - byte _instrument[48]; Voice2612 *_voices; + Voice2612 *_next_voice; public: - void removeVoice (Voice2612 *voice); + void removeAllVoices(); void nextTick(int *outbuf, int buflen); void rate(uint16 r); public: - MidiChannel_YM2612 (MidiDriver_YM2612 *owner); + MidiChannel_YM2612(); virtual ~MidiChannel_YM2612(); // MidiChannel interface @@ -160,7 +157,6 @@ public: class MidiDriver_YM2612 : public MidiDriver { protected: MidiChannel_YM2612 *_channel[16]; - Voice2612 *_voices[32]; int _next_voice; int _volume; @@ -183,9 +179,6 @@ protected: static void premix_proc(void *param, int16 *buf, uint len); public: - Voice2612 *allocateVoice(); - -public: MidiDriver_YM2612(SoundMixer *mixer); virtual ~MidiDriver_YM2612(); @@ -318,7 +311,7 @@ void Operator2612::frequency(int freq) { r = _specifiedReleaseRate; if (r != 0) { - r = r * 2 + 1; // このタイミングで良いのかわからん + r = r * 2 + 1; // (Translated) I cannot know whether the timing is a good choice or not r = r * 2 + (keyscaleTable[freq/262205] >> (3-_keyScale)); // KS による補正はあるらしい。赤p.206 では記述されてないけど。 if (r >= 64) @@ -435,9 +428,7 @@ void Operator2612::nextTick(const int *phasebuf, int *outbuf, int buflen) { //////////////////////////////////////// Voice2612::Voice2612() { - _owner = 0; - prev = next = 0; - _in_use = false; + next = 0; _control7 = 127; _note = 40; _frequency = 440; @@ -513,16 +504,8 @@ void Voice2612::setInstrument(byte const *instrument) { } void Voice2612::nextTick(int *outbuf, int buflen) { - if (!_in_use || _velocity == 0) + if (_velocity == 0) return; - if (!_opr[0]->inUse() && !_opr[1]->inUse() && - !_opr[2]->inUse() && !_opr[3]->inUse()) - { - _in_use = false; - if (_owner) - _owner->removeVoice (this); - return; - } if (_buflen < buflen) { free(_buffer); @@ -593,7 +576,6 @@ void Voice2612::noteOn(int n, int onVelo) { _note = n; velocity(onVelo); recalculateFrequency(); - _in_use = true; int i; for (i = 0; i < ARRAYSIZE(_opr); i++) _opr[i]->keyOn(); @@ -645,64 +627,71 @@ void Voice2612::recalculateFrequency() { // //////////////////////////////////////// -MidiChannel_YM2612::MidiChannel_YM2612 (MidiDriver_YM2612 *owner) { -// _voice = new Voice2612(); - _owner = owner; +MidiChannel_YM2612::MidiChannel_YM2612() { _voices = 0; + _next_voice = 0; } MidiChannel_YM2612::~MidiChannel_YM2612() { -// delete _voice; + removeAllVoices(); } -void MidiChannel_YM2612::noteOn(byte note, byte onVelo) { - Voice2612 *voice = _owner->allocateVoice(); - if (!voice) +void MidiChannel_YM2612::removeAllVoices() { + if (!_voices) return; - voice->_owner = this; - voice->_rate = _rate; - voice->next = _voices; - voice->prev = 0; - if (_voices) - _voices->prev = voice; - _voices = voice; - voice->setInstrument (_instrument); - voice->noteOn(note, onVelo); + Voice2612 *last, *voice = _voices; + for (; voice; voice = last) { + last = voice->next; + delete voice; + } + _voices = _next_voice = 0; } -void MidiChannel_YM2612::noteOff(byte note) { - Voice2612 *voice = _voices; - for (; voice; voice = voice->next) { - if (voice->noteOff(note)) - removeVoice(voice); - } +void MidiChannel_YM2612::noteOn(byte note, byte onVelo) { + if (!_voices) + return; + _next_voice = _next_voice ? _next_voice : _voices; + _next_voice->noteOn(note, onVelo); + _next_voice = _next_voice->next; } -void MidiChannel_YM2612::removeVoice(Voice2612 *voice) { - // We ASSUME that the voice belongs to us. - voice->_owner = 0; - if (voice->next) - voice->next->prev = voice->prev; - if (voice->prev) - voice->prev->next = voice->next; - else - _voices = voice->next; +void MidiChannel_YM2612::noteOff(byte note) { + if (!_voices) + return; + if (_next_voice == _voices) + _next_voice = 0; + Voice2612 *voice = _next_voice; + do { + if (!voice) + voice = _voices; + if (voice->noteOff(note)) { + _next_voice = voice; + break; + } + voice = voice->next; + } while (voice != _next_voice); } void MidiChannel_YM2612::controlChange(byte control, byte value) { - // いいのかこれで? - Voice2612 *voice = _voices; - for (; voice; voice = voice->next) - voice->setControlParameter(control, value); + // いいのかこれで? + if (control == 121) { + // Reset controller + removeAllVoices(); + } else { + Voice2612 *voice = _voices; + for (; voice; voice = voice->next) + voice->setControlParameter(control, value); + } } void MidiChannel_YM2612::sysEx_customInstrument(uint32 type, byte *fmInst) { if (type != 'EUP ') return; - memcpy (_instrument, fmInst, 48); - Voice2612 *voice = _voices; - for (; voice; voice = voice->next) - voice->setInstrument(fmInst); + Voice2612 *voice = new Voice2612; + voice->next = _voices; + _voices = voice; + voice->_rate = _rate; + voice->setInstrument(fmInst); } void MidiChannel_YM2612::pitchBend(int16 value) { @@ -744,10 +733,8 @@ _mixer(mixer) createLookupTables(); _volume = 256; int i; - for (i = 0; i < ARRAYSIZE(_voices); i++) - _voices[i] = new Voice2612; for (i = 0; i < ARRAYSIZE(_channel); i++) - _channel[i] = new MidiChannel_YM2612 (this); + _channel[i] = new MidiChannel_YM2612; rate(_mixer->getOutputRate()); } @@ -755,8 +742,6 @@ MidiDriver_YM2612::~MidiDriver_YM2612() { int i; for (i = 0; i < ARRAYSIZE(_channel); i++) delete _channel[i]; - for (i = 0; i < ARRAYSIZE(_voices); i++) - delete _voices[i]; delete sintbl; delete powtbl; delete frequencyTable; @@ -865,8 +850,8 @@ void MidiDriver_YM2612::nextTick(int16 *buf1, int buflen) { int *buf0 = (int *)buf1; int i; - for (i = 0; i < ARRAYSIZE(_voices); i++) - _voices[i]->nextTick(buf0, buflen); + for (i = 0; i < ARRAYSIZE(_channel); i++) + _channel[i]->nextTick(buf0, buflen); for (i = 0; i < buflen; ++i) buf1[i*2+1] = buf1[i*2] = ((buf0[i] * volume()) >> 10) & 0xffff; @@ -951,20 +936,6 @@ void MidiDriver_YM2612::createLookupTables() { } } -Voice2612 *MidiDriver_YM2612::allocateVoice() { - _next_voice %= ARRAYSIZE(_voices); - int oldStart = _next_voice; - do { - if (!_voices[_next_voice++]->_in_use) - return _voices[_next_voice-1]; - _next_voice %= ARRAYSIZE(_voices); - } while (_next_voice != oldStart); - Voice2612 *voice = _voices[_next_voice++]; - if (voice->_owner) - voice->_owner->removeVoice (voice); - return voice; -} - //////////////////////////////////////// // // MidiDriver_YM2612 factory diff --git a/scumm/midiparser_eup.cpp b/scumm/midiparser_eup.cpp index eeca9fbb6d..c8c6f95fdc 100644 --- a/scumm/midiparser_eup.cpp +++ b/scumm/midiparser_eup.cpp @@ -33,7 +33,7 @@ namespace Scumm { class MidiParser_EUP : public MidiParser { protected: byte _instruments[6][50]; // Two extra bytes for SysEx ID and channel # - byte _channel_instr[16]; + byte *_instr_to_channel; struct { byte *enable; int8 *channel; @@ -71,20 +71,21 @@ void MidiParser_EUP::parseNextEvent (EventInfo &info) { // program changes to get a reasonable "one-size- // fits-all" sound until we actually support the // FM synthesis capabilities of FM Towns. - for (; _presend < 32; ++_presend) { - if (_channel_instr[_presend >> 1] == 0xFF) continue; + for (; _presend < 12; ++_presend) { + if (_instr_to_channel[_presend>>1] >= 16) + continue; info.start = pos; info.delta = 0; if (_presend & 1) { - info.event = 0xB0; - info.basic.param1 = 7; - info.basic.param2 = 127; - } else { - byte *data = &_instruments[_channel_instr[_presend >> 1]][0]; - data[1] = _presend >> 1; + byte *data = &_instruments[_presend>>1][0]; + data[1] = _instr_to_channel[_presend>>1]; info.event = 0xF0; info.ext.data = data; info.length = 48; + } else { + info.event = 0xB0 | (_presend >> 1); + info.basic.param1 = 121; + info.basic.param2 = 0; } ++_presend; return; @@ -186,11 +187,8 @@ bool MidiParser_EUP::loadMusic (byte *data, uint32 size) { pos += 32; pos += 8; // Unknown bytes - for (i = 0; i < 16; ++i) - _channel_instr[i] = 0xFF; - for (i = 0; i < 6; ++i) - _channel_instr[pos[i]] = i; - pos += 6; // Instrument-to-channel mapping (not supported yet) + _instr_to_channel = pos; // Instrument-to-channel mapping + pos += 6; pos += 4; // Skip the music size for now. pos++; // Unknown byte byte tempo = *pos++; |