diff options
author | athrxx | 2011-05-14 15:25:39 +0200 |
---|---|---|
committer | Willem Jan Palenstijn | 2011-05-17 20:36:32 +0200 |
commit | b3476fc8016e3a62812eb9c7b5602e1f05f529cb (patch) | |
tree | 92f56280720e2e97285ba990ff2ddb93651e478e /audio/softsynth | |
parent | 15610b56db9f655ad0c8df0ffe730d123f048bac (diff) | |
download | scummvm-rg350-b3476fc8016e3a62812eb9c7b5602e1f05f529cb.tar.gz scummvm-rg350-b3476fc8016e3a62812eb9c7b5602e1f05f529cb.tar.bz2 scummvm-rg350-b3476fc8016e3a62812eb9c7b5602e1f05f529cb.zip |
FM-TOWNS AUDIO: Some fixes and renaming
- renamed some stuff in the new midi driver code
- fixed minor bug in midi driver code
- fixed minor bug in euphony driver code
- add some functionality to towns audio interface
Diffstat (limited to 'audio/softsynth')
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_audio.cpp | 65 | ||||
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_euphony.cpp | 2 | ||||
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_midi.cpp | 253 | ||||
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_midi.h | 2 | ||||
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h | 2 |
5 files changed, 185 insertions, 139 deletions
diff --git a/audio/softsynth/fmtowns_pc98/towns_audio.cpp b/audio/softsynth/fmtowns_pc98/towns_audio.cpp index 6679e65cd2..f2d249b32a 100644 --- a/audio/softsynth/fmtowns_pc98/towns_audio.cpp +++ b/audio/softsynth/fmtowns_pc98/towns_audio.cpp @@ -163,9 +163,10 @@ private: int intf_fmReset(va_list &args); int intf_setOutputVolume(va_list &args); int intf_resetOutputVolume(va_list &args); + int intf_getOutputVolume(va_list &args); int intf_setOutputMute(va_list &args); int intf_cdaToggle(va_list &args); - int intf_getOutputVolume(va_list &args); + int intf_getOutputVolume2(va_list &args); int intf_getOutputMute(va_list &args); int intf_pcmUpdateEnvelopeGenerator(va_list &args); @@ -224,7 +225,7 @@ private: void updateOutputVolume(); uint8 _outputVolumeFlags; uint8 _outputLevel[16]; - uint8 _outputMuteFlags; + uint8 _outputMute[16]; const float _baserate; uint32 _timerBase; @@ -253,7 +254,7 @@ TownsAudioInterfaceIntern::TownsAudioInterfaceIntern(Audio::Mixer *mixer, TownsA _fmInstruments(0), _pcmInstruments(0), _pcmChan(0), _waveTables(0), _waveTablesTotalDataSize(0), _baserate(55125.0f / (float)mixer->getOutputRate()), _tickLength(0), _timer(0), _drv(driver), _pcmSfxChanMask(0), _musicVolume(Audio::Mixer::kMaxMixerVolume), _sfxVolume(Audio::Mixer::kMaxMixerVolume), - _outputVolumeFlags(0), _outputMuteFlags(0), _pcmChanOut(0), _pcmChanReserved(0), _pcmChanKeyPressed(0), + _outputVolumeFlags(0), _pcmChanOut(0), _pcmChanReserved(0), _pcmChanKeyPressed(0), _pcmChanEffectPlaying(0), _pcmChanKeyPlaying(0), _ready(false) { #define INTCB(x) &TownsAudioInterfaceIntern::intf_##x @@ -345,13 +346,13 @@ TownsAudioInterfaceIntern::TownsAudioInterfaceIntern(Audio::Mixer *mixer, TownsA INTCB(setOutputVolume), // 68 INTCB(resetOutputVolume), - INTCB(notImpl), + INTCB(getOutputVolume), INTCB(setOutputMute), INTCB(notImpl), // 72 INTCB(notImpl), INTCB(cdaToggle), - INTCB(getOutputVolume), + INTCB(getOutputVolume2), INTCB(getOutputMute), // 76 INTCB(notImpl), @@ -368,6 +369,7 @@ TownsAudioInterfaceIntern::TownsAudioInterfaceIntern(Audio::Mixer *mixer, TownsA memset(_fmSaveReg, 0, sizeof(_fmSaveReg)); memset(_outputLevel, 0, sizeof(_outputLevel)); + memset(_outputMute, 0, sizeof(_outputMute)); _timerBase = (uint32)(_baserate * 1000000.0f); _tickLength = 2 * _timerBase; @@ -929,11 +931,13 @@ int TownsAudioInterfaceIntern::intf_setOutputVolume(va_list &args) { if (chanType > 1) { _outputLevel[chan + chanType] = left; + _outputMute[chan + chanType] = 0; } else { if (chanType == 0) chan -= 8; _outputLevel[chan] = left; _outputLevel[chan + 1] = right; + _outputMute[chan] = _outputMute[chan + 1] = 0; } updateOutputVolume(); @@ -943,15 +947,56 @@ int TownsAudioInterfaceIntern::intf_setOutputVolume(va_list &args) { int TownsAudioInterfaceIntern::intf_resetOutputVolume(va_list &args) { memset(_outputLevel, 0, sizeof(_outputLevel)); - _outputMuteFlags = 0; _outputVolumeFlags = 0; updateOutputVolume(); return 0; } +int TownsAudioInterfaceIntern::intf_getOutputVolume(va_list &args) { + int chanType = va_arg(args, int); + int *left = va_arg(args, int*); + int *right = va_arg(args, int*); + + uint8 chan = (chanType & 0x40) ? 8 : 12; + chanType &= 3; + + if (chanType > 1) { + *left = _outputLevel[chan + chanType] & 0x3f; + } else { + if (chanType == 0) + chan -= 8; + *left = _outputLevel[chan] & 0x3f; + *right = _outputLevel[chan + 1] & 0x3f; + } + + return 0; +} + int TownsAudioInterfaceIntern::intf_setOutputMute(va_list &args) { int flags = va_arg(args, int); - _outputMuteFlags = flags & 3; + _outputVolumeFlags = flags; + uint8 mute = flags & 3; + uint8 f = flags & 0xff; + + memset(_outputMute, 1, 8); + if (mute & 2) + memset(_outputMute + 12, 1, 4); + if (mute & 1) + memset(_outputMute + 8, 1, 4); + + _outputMute[(f < 0x80) ? 11 : 15] = 0; + f += f; + _outputMute[(f < 0x80) ? 10 : 14] = 0; + f += f; + _outputMute[(f < 0x80) ? 8 : 12] = 0; + f += f; + _outputMute[(f < 0x80) ? 9 : 13] = 0; + f += f; + _outputMute[(f < 0x80) ? 0 : 4] = 0; + f += f; + _outputMute[(f < 0x80) ? 1 : 5] = 0; + f += f; + updateOutputVolume(); return 0; } @@ -962,7 +1007,7 @@ int TownsAudioInterfaceIntern::intf_cdaToggle(va_list &args) { return 0; } -int TownsAudioInterfaceIntern::intf_getOutputVolume (va_list &args) { +int TownsAudioInterfaceIntern::intf_getOutputVolume2(va_list &args) { return 0; } @@ -1602,10 +1647,10 @@ void TownsAudioInterfaceIntern::updateOutputVolume() { // balance values for our -128 to 127 volume range // CD-AUDIO - uint32 maxVol = MAX(_outputLevel[12], _outputLevel[13]); + uint32 maxVol = MAX(_outputLevel[12] * (_outputMute[12] ^ 1), _outputLevel[13] * (_outputMute[13] ^ 1)); int volume = (int)(((float)(maxVol * 255) / 63.0f)); - int balance = maxVol ? (int)( ( ((int)_outputLevel[13] - _outputLevel[12]) * 127) / (float)maxVol) : 0; + int balance = maxVol ? (int)( ( ((int)_outputLevel[13] * (_outputMute[13] ^ 1) - _outputLevel[12] * (_outputMute[12] ^ 1)) * 127) / (float)maxVol) : 0; g_system->getAudioCDManager()->setVolume(volume); g_system->getAudioCDManager()->setBalance(balance); diff --git a/audio/softsynth/fmtowns_pc98/towns_euphony.cpp b/audio/softsynth/fmtowns_pc98/towns_euphony.cpp index f161228876..f7aa33f44d 100644 --- a/audio/softsynth/fmtowns_pc98/towns_euphony.cpp +++ b/audio/softsynth/fmtowns_pc98/towns_euphony.cpp @@ -81,7 +81,7 @@ void TownsEuphonyDriver::reset() { _intf->callback(0); _intf->callback(74); - _intf->callback(70); + _intf->callback(70, 0); _intf->callback(75, 3); setTimerA(true, 1); diff --git a/audio/softsynth/fmtowns_pc98/towns_midi.cpp b/audio/softsynth/fmtowns_pc98/towns_midi.cpp index 6843a35ce3..6b31ea1aba 100644 --- a/audio/softsynth/fmtowns_pc98/towns_midi.cpp +++ b/audio/softsynth/fmtowns_pc98/towns_midi.cpp @@ -23,9 +23,12 @@ */ #include "audio/softsynth/fmtowns_pc98/towns_midi.h" +#include "audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h" #include "common/textconsole.h" #include "common/system.h" +enum EnvelopeState; + class TownsMidiOutputChannel { friend class TownsMidiInputChannel; public: @@ -51,40 +54,40 @@ public: int checkPriority(int pri); private: - struct EffectState { - uint8 envState; - int32 envStepLen; - int32 duration; - int32 envTargetLevel; + struct EffectEnvelope { + uint8 state; int32 currentLevel; + int32 duration; + int32 maxLevel; + int32 startLevel; uint8 loop; - uint8 envStepping[4]; - uint8 envMod[4]; + uint8 stateTargetLevels[4]; + uint8 stateModWheelLevels[4]; int8 modWheelSensitivity; int8 modWheelState; int8 modWheelLast; - uint16 envStateNumSteps; - uint32 envStateStepCounter; - int32 envChangePerStep; + uint16 numSteps; + uint32 stepCounter; + int32 incrPerStep; int8 dir; - uint32 envChangePerStepRem; - uint32 envChangeCountRem; - } *_effectStates; + uint32 incrPerStepRem; + uint32 incrCountRem; + } *_effectEnvelopes; struct EffectDef { int32 phase; uint8 type; uint8 useModWheel; uint8 loopRefresh; - EffectState *s; + EffectEnvelope *s; } *_effectDefs; - int16 getEffectLevel(uint8 type); - void initEffect(EffectState *s, const uint8 *effectData); - void updateEffectGenerator(EffectState *s, EffectDef *d); - int updateEffectEnvelope(EffectState *s, EffectDef *d); - void updateEffect(EffectState *s); - int calcModWheelLevel(int lvl, int mod); + void startEffect(EffectEnvelope *s, const uint8 *effectData); + void updateEffectGenerator(EffectEnvelope *s, EffectDef *d); + int advanceEffectEnvelope(EffectEnvelope *s, EffectDef *d); + void initNextEnvelopeState(EffectEnvelope *s); + int16 getEffectStartLevel(uint8 type); + int getEffectModLevel(int lvl, int mod); void keyOn(); void keyOff(); @@ -216,17 +219,17 @@ uint8 TownsMidiChanState::get(uint8 type) { TownsMidiOutputChannel::TownsMidiOutputChannel(MidiDriver_TOWNS *driver, int chanIndex) : _driver(driver), _chan(chanIndex), _in(0), _prev(0), _next(0), _adjustModTl(0), _operator2Tl(0), _note(0), _operator1Tl(0), _sustainNoteOff(0), _duration(0), _freq(0), _freqAdjust(0) { - _effectStates = new EffectState[2]; + _effectEnvelopes = new EffectEnvelope[2]; _effectDefs = new EffectDef[2]; - memset(_effectStates, 0, 2 * sizeof(EffectState)); + memset(_effectEnvelopes, 0, 2 * sizeof(EffectEnvelope)); memset(_effectDefs, 0, 2 * sizeof(EffectDef)); - _effectDefs[0].s = &_effectStates[1]; - _effectDefs[1].s = &_effectStates[0]; + _effectDefs[0].s = &_effectEnvelopes[1]; + _effectDefs[1].s = &_effectEnvelopes[0]; } TownsMidiOutputChannel::~TownsMidiOutputChannel() { - delete[] _effectStates; + delete[] _effectEnvelopes; delete[] _effectDefs; } @@ -295,10 +298,10 @@ void TownsMidiOutputChannel::setupProgram(const uint8 *data, uint8 mLevelPara, u } void TownsMidiOutputChannel::setupEffects(int index, uint8 flags, const uint8 *effectData) { - uint16 effectTargetLevel[] = { 0x2FF, 0x1F, 0x07, 0x3F, 0x0F, 0x0F, 0x0F, 0x03, 0x3F, 0x0F, 0x0F, 0x0F, 0x03, 0x3E, 0x1F }; + uint16 effectMaxLevel[] = { 0x2FF, 0x1F, 0x07, 0x3F, 0x0F, 0x0F, 0x0F, 0x03, 0x3F, 0x0F, 0x0F, 0x0F, 0x03, 0x3E, 0x1F }; uint8 effectType[] = { 0x1D, 0x1C, 0x1B, 0x00, 0x03, 0x04, 0x07, 0x08, 0x0D, 0x10, 0x11, 0x14, 0x15, 0x1e, 0x1f, 0x00 }; - EffectState *s = &_effectStates[index]; + EffectEnvelope *s = &_effectEnvelopes[index]; EffectDef *d = &_effectDefs[index]; d->phase = 0; @@ -306,39 +309,39 @@ void TownsMidiOutputChannel::setupEffects(int index, uint8 flags, const uint8 *e s->loop = flags & 0x20; d->loopRefresh = flags & 0x10; d->type = effectType[flags & 0x0f]; - s->envTargetLevel = effectTargetLevel[flags & 0x0f]; + s->maxLevel = effectMaxLevel[flags & 0x0f]; s->modWheelSensitivity = 31; s->modWheelState = d->useModWheel ? _in->_modWheel >> 2 : 31; switch (d->type) { case 0: - s->currentLevel = _operator2Tl; + s->startLevel = _operator2Tl; break; case 13: - s->currentLevel = _operator1Tl; + s->startLevel = _operator1Tl; break; case 30: - s->currentLevel = 31; + s->startLevel = 31; d->s->modWheelState = 0; break; case 31: - s->currentLevel = 0; + s->startLevel = 0; d->s->modWheelSensitivity = 0; break; default: - s->currentLevel = getEffectLevel(d->type); + s->startLevel = getEffectStartLevel(d->type); break; } - initEffect(s, effectData); + startEffect(s, effectData); } void TownsMidiOutputChannel::setModWheel(uint8 value) { - if (_effectStates[0].envState && _effectDefs[0].type) - _effectStates[0].modWheelState = value >> 2; + if (_effectEnvelopes[0].state != kEnvReady && _effectDefs[0].type) + _effectEnvelopes[0].modWheelState = value >> 2; - if (_effectStates[1].envState && _effectDefs[1].type) - _effectStates[1].modWheelState = value >> 2; + if (_effectEnvelopes[1].state != kEnvReady && _effectDefs[1].type) + _effectEnvelopes[1].modWheelState = value >> 2; } void TownsMidiOutputChannel::connect(TownsMidiInputChannel *chan) { @@ -381,8 +384,8 @@ bool TownsMidiOutputChannel::update() { } for (int i = 0; i < 2; i++) { - if (_effectStates[i].envState) - updateEffectGenerator(&_effectStates[i], &_effectDefs[i]); + if (_effectEnvelopes[i].state != kEnvReady) + updateEffectGenerator(&_effectEnvelopes[i], &_effectDefs[i]); } return false; @@ -398,52 +401,32 @@ int TownsMidiOutputChannel::checkPriority(int pri) { return kHighPriority; } -int16 TownsMidiOutputChannel::getEffectLevel(uint8 type) { - uint8 chan = (type < 13) ? _chanMap2[_chan] : ((type < 26) ? _chanMap[_chan] : _chan); - - if (type == 28) - return 15; - else if (type == 29) - return 383; - else if (type > 29) - return 0; - else if (type > 12) - type -= 13; - - int32 res = 0; - uint8 cs = (_driver->_chanState[chan].get(_effectDefaults[type * 4] >> 5) & _effectDefaults[type * 4 + 2]) >> _effectDefaults[type * 4 + 1]; - if (_effectDefaults[type * 4 + 3]) - res = _effectDefaults[type * 4 + 3] - cs; - - return res; -} - -void TownsMidiOutputChannel::initEffect(EffectState *s, const uint8 *effectData) { - s->envState = 1; - s->envStepLen = 0; +void TownsMidiOutputChannel::startEffect(EffectEnvelope *s, const uint8 *effectData) { + s->state = kEnvAttacking; + s->currentLevel = 0; s->modWheelLast = 31; s->duration = effectData[0] * 63; - s->envStepping[0] = effectData[1]; - s->envStepping[1] = effectData[3]; - s->envStepping[2] = effectData[5]; - s->envStepping[3] = effectData[6]; - s->envMod[0] = effectData[2]; - s->envMod[1] = effectData[4]; - s->envMod[2] = 0; - s->envMod[3] = effectData[7]; - updateEffect(s); + s->stateTargetLevels[0] = effectData[1]; + s->stateTargetLevels[1] = effectData[3]; + s->stateTargetLevels[2] = effectData[5]; + s->stateTargetLevels[3] = effectData[6]; + s->stateModWheelLevels[0] = effectData[2]; + s->stateModWheelLevels[1] = effectData[4]; + s->stateModWheelLevels[2] = 0; + s->stateModWheelLevels[3] = effectData[7]; + initNextEnvelopeState(s); } -void TownsMidiOutputChannel::updateEffectGenerator(EffectState *s, EffectDef *d) { - uint8 f = updateEffectEnvelope(s, d); +void TownsMidiOutputChannel::updateEffectGenerator(EffectEnvelope *s, EffectDef *d) { + uint8 f = advanceEffectEnvelope(s, d); if (f & 1) { switch (d->type) { case 0: - _operator2Tl = s->currentLevel + d->phase; + _operator2Tl = s->startLevel + d->phase; break; case 13: - _operator1Tl = s->currentLevel + d->phase; + _operator1Tl = s->startLevel + d->phase; break; case 30: d->s->modWheelState = d->phase; @@ -462,55 +445,54 @@ void TownsMidiOutputChannel::updateEffectGenerator(EffectState *s, EffectDef *d) } } -int TownsMidiOutputChannel::updateEffectEnvelope(EffectState *s, EffectDef *d) { +int TownsMidiOutputChannel::advanceEffectEnvelope(EffectEnvelope *s, EffectDef *d) { if (s->duration) { s->duration -= 17; if (s->duration <= 0) { - s->envState = 0; + s->state = kEnvReady; return 0; } } - int32 t = s->envStepLen + s->envChangePerStep; + int32 t = s->currentLevel + s->incrPerStep; - s->envChangeCountRem += s->envChangePerStepRem; - if (s->envChangeCountRem >= s->envStateNumSteps) { - s->envChangeCountRem -= s->envStateNumSteps; + s->incrCountRem += s->incrPerStepRem; + if (s->incrCountRem >= s->numSteps) { + s->incrCountRem -= s->numSteps; t += s->dir; } int retFlags = 0; - if (t != s->envStepLen || (s->modWheelState != s->modWheelLast)) { - s->envStepLen = t; + if (t != s->currentLevel || (s->modWheelState != s->modWheelLast)) { + s->currentLevel = t; s->modWheelLast = s->modWheelState; - t = calcModWheelLevel(t, s->modWheelState); + t = getEffectModLevel(t, s->modWheelState); if (t != d->phase) d->phase = t; retFlags |= 1; } - if (--s->envStateStepCounter) + if (--s->stepCounter) return retFlags; - if (++s->envState > 4) { + if (++s->state > kEnvReleasing) { if (!s->loop) { - s->envState = 0; + s->state = kEnvReady; return retFlags; } - s->envState = 1; + s->state = kEnvAttacking; retFlags |= 2; } - updateEffect(s); + initNextEnvelopeState(s); return retFlags; } -void TownsMidiOutputChannel::updateEffect(EffectState *s) { - uint8 st= s->envState - 1; - uint8 v = s->envStepping[st]; - int32 e = _effectEnvStepTable[_driver->_chanEffectLevelModifier[((v & 0x7f) << 5) + s->modWheelSensitivity]]; +void TownsMidiOutputChannel::initNextEnvelopeState(EffectEnvelope *s) { + uint8 v = s->stateTargetLevels[s->state - 1]; + int32 e = _effectEnvStepTable[_driver->_operatorLevelTable[((v & 0x7f) << 5) + s->modWheelSensitivity]]; if (v & 0x80) e = _driver->randomValue(e); @@ -518,34 +500,54 @@ void TownsMidiOutputChannel::updateEffect(EffectState *s) { if (!e) e = 1; - s->envStateNumSteps = s->envStateStepCounter = e; + s->numSteps = s->stepCounter = e; int32 d = 0; - if (st != 2) { - v = s->envMod[st]; - e = calcModWheelLevel(s->envTargetLevel, (v & 0x7f) - 31); + if (s->state != kEnvSustaining) { + v = s->stateModWheelLevels[s->state - 1]; + e = getEffectModLevel(s->maxLevel, (v & 0x7f) - 31); if (v & 0x80) e = _driver->randomValue(e); - if (e + s->currentLevel > s->envTargetLevel) { - e = s->envTargetLevel - s->currentLevel; + if (e + s->startLevel > s->maxLevel) { + e = s->maxLevel - s->startLevel; } else { - if (e + s->currentLevel + 1 <= 0) - e = -s->currentLevel; + if (e + s->startLevel < 0) + e = -s->startLevel; } - d = e - s->envStepLen; + d = e - s->currentLevel; } - s->envChangePerStep = d / s->envStateNumSteps; + s->incrPerStep = d / s->numSteps; s->dir = (d < 0) ? -1 : 1; d *= s->dir; - s->envChangePerStepRem = d % s->envStateNumSteps; - s->envChangeCountRem = 0; + s->incrPerStepRem = d % s->numSteps; + s->incrCountRem = 0; +} + +int16 TownsMidiOutputChannel::getEffectStartLevel(uint8 type) { + uint8 chan = (type < 13) ? _chanMap2[_chan] : ((type < 26) ? _chanMap[_chan] : _chan); + + if (type == 28) + return 15; + else if (type == 29) + return 383; + else if (type > 29) + return 0; + else if (type > 12) + type -= 13; + + const uint8 *def = &_effectDefaults[type << 2]; + uint8 res = (_driver->_chanState[chan].get(def[0] >> 5) & def[2]) >> def[1]; + if (def[3]) + res = def[3] - res; + + return res; } -int TownsMidiOutputChannel::calcModWheelLevel(int lvl, int mod) { +int TownsMidiOutputChannel::getEffectModLevel(int lvl, int mod) { if (mod == 0) return 0; @@ -556,15 +558,15 @@ int TownsMidiOutputChannel::calcModWheelLevel(int lvl, int mod) { return ((lvl + 1) * mod) >> 5; if (mod < 0) { - if (mod < 0) - return _driver->_chanEffectLevelModifier[((-lvl) << 5) - mod]; + if (lvl < 0) + return _driver->_operatorLevelTable[((-lvl) << 5) - mod]; else - return -_driver->_chanEffectLevelModifier[(lvl << 5) - mod]; + return -_driver->_operatorLevelTable[(lvl << 5) - mod]; } else { - if (mod < 0) - return -_driver->_chanEffectLevelModifier[((-lvl) << 5) + mod]; + if (lvl < 0) + return -_driver->_operatorLevelTable[((-lvl) << 5) + mod]; else - return _driver->_chanEffectLevelModifier[((-lvl) << 5) + mod]; + return _driver->_operatorLevelTable[((-lvl) << 5) + mod]; } return 0; @@ -714,26 +716,26 @@ void TownsMidiInputChannel::noteOn(byte note, byte velocity) { oc->_sustainNoteOff = 0; oc->_duration = _instrument[29] * 63; - oc->_operator1Tl = (_instrument[1] & 0x3f) + _driver->_chanEffectLevelModifier[((velocity >> 1) << 5) + (_instrument[4] >> 2)]; + oc->_operator1Tl = (_instrument[1] & 0x3f) + _driver->_operatorLevelTable[((velocity >> 1) << 5) + (_instrument[4] >> 2)]; if (oc->_operator1Tl > 63) oc->_operator1Tl = 63; - oc->_operator2Tl = (_instrument[6] & 0x3f) + _driver->_chanEffectLevelModifier[((velocity >> 1) << 5) + (_instrument[9] >> 2)]; + oc->_operator2Tl = (_instrument[6] & 0x3f) + _driver->_operatorLevelTable[((velocity >> 1) << 5) + (_instrument[9] >> 2)]; if (oc->_operator2Tl > 63) oc->_operator2Tl = 63; - oc->setupProgram(_instrument, oc->_adjustModTl == 1 ? _programAdjustLevel[_driver->_chanEffectLevelModifier[(_tl >> 2) + (oc->_operator1Tl << 5)]] : oc->_operator1Tl, _programAdjustLevel[_driver->_chanEffectLevelModifier[(_tl >> 2) + (oc->_operator2Tl << 5)]]); + oc->setupProgram(_instrument, oc->_adjustModTl == 1 ? _programAdjustLevel[_driver->_operatorLevelTable[(_tl >> 2) + (oc->_operator1Tl << 5)]] : oc->_operator1Tl, _programAdjustLevel[_driver->_operatorLevelTable[(_tl >> 2) + (oc->_operator2Tl << 5)]]); oc->noteOn(note + _transpose, _freqLSB); if (_instrument[11] & 0x80) oc->setupEffects(0, _instrument[11], &_instrument[12]); else - oc->_effectStates[0].envState = 0; + oc->_effectEnvelopes[0].state = kEnvReady; if (_instrument[20] & 0x80) oc->setupEffects(1, _instrument[20], &_instrument[21]); else - oc->_effectStates[1].envState = 0; + oc->_effectEnvelopes[1].state = kEnvReady; } void TownsMidiInputChannel::programChange(byte program) { @@ -852,7 +854,7 @@ int MidiDriver_TOWNS::open() { _channels = new TownsMidiInputChannel*[32]; for (int i = 0; i < 32; i++) - _channels[i] = new TownsMidiInputChannel(this, i); + _channels[i] = new TownsMidiInputChannel(this, i > 8 ? (i + 1) : i); _out = new TownsMidiOutputChannel*[6]; for (int i = 0; i < 6; i++) @@ -860,13 +862,13 @@ int MidiDriver_TOWNS::open() { _chanState = new TownsMidiChanState[32]; - _chanEffectLevelModifier = new uint8[2048]; + _operatorLevelTable = new uint8[2048]; for (int i = 0; i < 64; i++) { for (int ii = 0; ii < 32; ii++) - _chanEffectLevelModifier[(i << 5) + ii] = ((i * (ii + 1)) >> 5) & 0xff; + _operatorLevelTable[(i << 5) + ii] = ((i * (ii + 1)) >> 5) & 0xff; } for (int i = 0; i < 64; i++) - _chanEffectLevelModifier[i << 5] = 0; + _operatorLevelTable[i << 5] = 0; _intf->callback(0); @@ -911,8 +913,8 @@ void MidiDriver_TOWNS::close() { delete[] _chanState; _chanState = 0; - delete[] _chanEffectLevelModifier; - _chanEffectLevelModifier = 0; + delete[] _operatorLevelTable; + _operatorLevelTable = 0; } void MidiDriver_TOWNS::send(uint32 b) { @@ -1009,8 +1011,7 @@ void MidiDriver_TOWNS::updateOutputChannels() { while (_tickCounter2 >= 16667) { _tickCounter2 -= 16667; for (int i = 0; i < 6; i++) { - TownsMidiOutputChannel *oc = _out[i]; - if (oc->update()) + if (_out[i]->update()) return; } } diff --git a/audio/softsynth/fmtowns_pc98/towns_midi.h b/audio/softsynth/fmtowns_pc98/towns_midi.h index 52298d77ce..2b6e1dff4e 100644 --- a/audio/softsynth/fmtowns_pc98/towns_midi.h +++ b/audio/softsynth/fmtowns_pc98/towns_midi.h @@ -78,7 +78,7 @@ private: bool _open; - uint8 *_chanEffectLevelModifier; + uint8 *_operatorLevelTable; }; #endif diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h index cbf856c78c..f7bcc90585 100644 --- a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h +++ b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h @@ -44,7 +44,7 @@ class TownsPC98_FmSynthPercussionSource; #endif enum EnvelopeState { - kEnvReady, + kEnvReady = 0, kEnvAttacking, kEnvDecaying, kEnvSustaining, |