diff options
Diffstat (limited to 'audio')
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_audio.cpp | 3 | ||||
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_midi.cpp | 101 |
2 files changed, 85 insertions, 19 deletions
diff --git a/audio/softsynth/fmtowns_pc98/towns_audio.cpp b/audio/softsynth/fmtowns_pc98/towns_audio.cpp index 065532f526..33606128bf 100644 --- a/audio/softsynth/fmtowns_pc98/towns_audio.cpp +++ b/audio/softsynth/fmtowns_pc98/towns_audio.cpp @@ -467,6 +467,7 @@ int TownsAudioInterfaceIntern::processCommand(int command, va_list &args) { if (command < 0 || command > 81) return 4; + Common::StackLock lock(_mutex); return (this->*_intfOpcodes[command])(args); } @@ -918,7 +919,7 @@ int TownsAudioInterfaceIntern::intf_setOutputVolume(va_list &args) { left = (left & 0x7e) >> 1; right = (right & 0x7e) >> 1; - if (chan) + if (chan == 12) _outputVolumeFlags |= flags[chanType]; else _outputVolumeFlags &= ~flags[chanType]; diff --git a/audio/softsynth/fmtowns_pc98/towns_midi.cpp b/audio/softsynth/fmtowns_pc98/towns_midi.cpp index 0c04044a76..7072149d2d 100644 --- a/audio/softsynth/fmtowns_pc98/towns_midi.cpp +++ b/audio/softsynth/fmtowns_pc98/towns_midi.cpp @@ -53,9 +53,9 @@ private: struct StateA { uint8 numLoop; int32 fld_1; - uint32 fld_5; + int32 duration; int32 fld_9; - int32 effectState; + int16 effectState; uint8 fld_11; uint8 ar1[4]; uint8 ar2[4]; @@ -63,7 +63,7 @@ private: uint8 modWheelState; uint8 fld_1c; uint32 fld_1d; - uint32 fld_21; + int32 fld_21; uint32 fld_25; int8 dir; uint32 fld_2a; @@ -71,14 +71,14 @@ private: } *_stateA; struct StateB { - uint32 fld_0; + int8 inc; uint8 type; uint8 useModWheel; uint8 fld_6; StateA *a; } *_stateB; - uint32 getEffectState(uint8 type); + uint16 getEffectState(uint8 type); void initEffect(StateA *a, const uint8 *effectData); void updateEffectOuter3(StateA *a, StateB *b); int updateEffectOuter(StateA *a, StateB *b); @@ -292,19 +292,19 @@ void TownsMidiOutputChannel::setupProgram(const uint8 *data, uint8 vol1, uint8 v void TownsMidiOutputChannel::setupEffects(int index, uint8 c, const uint8 *effectData) { uint16 maxVal[] = { 0x2FF, 0x1F, 0x07, 0x3F, 0x0F, 0x0F, 0x0F, 0x03, 0x3F, 0x0F, 0x0F, 0x0F, 0x03, 0x3E, 0x1F }; - uint8 para1[] = { 0x1D, 0x1C, 0x1B, 0x00, 0x03, 0x04, 0x07, 0x08, 0x0D, 0x10, 0x11, 0x14, 0x15, 0x1e, 0x1f, 0x00 }; + uint8 effectType[] = { 0x1D, 0x1C, 0x1B, 0x00, 0x03, 0x04, 0x07, 0x08, 0x0D, 0x10, 0x11, 0x14, 0x15, 0x1e, 0x1f, 0x00 }; StateA *a = &_stateA[index]; StateB *b = &_stateB[index]; - b->fld_0 = 0; + b->inc = 0; b->useModWheel = c & 0x40; a->fld_11 = c & 0x20; b->fld_6 = c & 0x10; - b->type = para1[c & 0x0f]; + b->type = effectType[c & 0x0f]; a->fld_9 = maxVal[c & 0x0f]; - a->modWheelSensitivity = 0x1f; - a->modWheelState = b->useModWheel ? _midi->_modWheel >> 2 : 0x1f; + a->modWheelSensitivity = 31; + a->modWheelState = b->useModWheel ? _midi->_modWheel >> 2 : 31; switch (b->type) { case 0: @@ -314,7 +314,7 @@ void TownsMidiOutputChannel::setupEffects(int index, uint8 c, const uint8 *effec a->effectState = _modulatorTl; break; case 30: - a->effectState = 0x1f; + a->effectState = 31; b->a->modWheelState = 0; break; case 31: @@ -392,7 +392,7 @@ int TownsMidiOutputChannel::checkPriority(int pri) { return kHighPriority; } -uint32 TownsMidiOutputChannel::getEffectState(uint8 type) { +uint16 TownsMidiOutputChannel::getEffectState(uint8 type) { uint8 chan = (type < 13) ? _chanMap2[_chan] : ((type < 26) ? _chanMap[_chan] : _chan); if (type == 28) @@ -415,8 +415,8 @@ uint32 TownsMidiOutputChannel::getEffectState(uint8 type) { void TownsMidiOutputChannel::initEffect(StateA *a, const uint8 *effectData) { a->numLoop = 1; a->fld_1 = 0; - a->fld_1c = 0x1f; - a->fld_5 = effectData[0]; + a->fld_1c = 31; + a->duration = effectData[0] * 63; a->ar1[0] = effectData[1]; a->ar1[1] = effectData[3]; a->ar1[2] = effectData[5]; @@ -429,15 +429,80 @@ void TownsMidiOutputChannel::initEffect(StateA *a, const uint8 *effectData) { } void TownsMidiOutputChannel::updateEffectOuter3(StateA *a, StateB *b) { + uint8 f = updateEffectOuter(a, b); + + if (f & 1) { + switch (b->type) { + case 0: + _carrierTl = (a->effectState & 0xff) + b->inc; /*???*/ + break; + case 13: + _modulatorTl = (a->effectState & 0xff) + b->inc; /*???*/ + break; + case 30: + b->a->modWheelState = b->inc; + break; + case 31: + b->a->modWheelSensitivity = b->inc; + break; + default: + break; + } + } + if (f & 2) { + if (b->fld_6) + keyOn(); + } } int TownsMidiOutputChannel::updateEffectOuter(StateA *a, StateB *b) { - return 0; + if (a->duration) { + a->duration -= 17; + if (a->duration <= 0) { + a->numLoop = 0; + return 0; + } + } + + int32 t = a->fld_1 + a->fld_25; + + a->fld_2e += a->fld_2a; + if (a->fld_2e >= a->fld_1d) { + a->fld_2e -= a->fld_1d; + t += a->dir; + } + + int retFlags = 0; + + if (t != a->fld_1 || a->modWheelState != a->fld_1c) { + a->fld_1 = t; + a->fld_1c = a->modWheelState; + t = lookupVolume(t, a->modWheelState); + if (t != b->inc) + b->inc = t; + retFlags |= 1; + } + + if (--a->fld_21 != 0) + return retFlags; + + if (++a->numLoop > 4) { + if (a->fld_11 == 0) { + a->numLoop = 0; + return retFlags; + } + a->numLoop = 1; + retFlags |= 2; + } + + updateEffect(a); + + return retFlags; } void TownsMidiOutputChannel::updateEffect(StateA *a) { - uint8 c = --a->numLoop; + uint8 c = a->numLoop - 1; uint16 v = a->ar1[c]; int e = _effectData[_driver->_chanOutputLevel[((v & 0x7f) << 5) + a->modWheelSensitivity]]; @@ -461,7 +526,7 @@ void TownsMidiOutputChannel::updateEffect(StateA *a) { e = a->fld_9 - a->effectState; } else { if (e + a->effectState + 1 <= 0) - e = -e; + e = -a->effectState; } d = e - a->fld_1; @@ -646,7 +711,7 @@ void TownsMidiInputChannel::noteOn(byte note, byte velocity) { oc->_fld_c = _instrument[10] & 1; oc->_note = note; oc->_sustainNoteOff = 0; - oc->_duration = _instrument[29] * 72; + oc->_duration = _instrument[29] * 63; oc->_modulatorTl = (_instrument[1] & 0x3f) + _driver->_chanOutputLevel[((velocity >> 1) << 5) + (_instrument[4] >> 2)]; if (oc->_modulatorTl > 63) |