diff options
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_audio.cpp | 13 | ||||
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_midi.cpp | 32 | ||||
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp | 10 | ||||
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp | 30 | ||||
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h | 8 |
5 files changed, 59 insertions, 34 deletions
diff --git a/audio/softsynth/fmtowns_pc98/towns_audio.cpp b/audio/softsynth/fmtowns_pc98/towns_audio.cpp index 33606128bf..51c2000514 100644 --- a/audio/softsynth/fmtowns_pc98/towns_audio.cpp +++ b/audio/softsynth/fmtowns_pc98/towns_audio.cpp @@ -411,13 +411,13 @@ bool TownsAudioInterfaceIntern::checkPluginDriver(TownsAudioInterfacePluginDrive if (_refCount <= 1) return true; - Common::StackLock lock(_mutex); - if (_drv) { if (driver && driver != _drv) return false; } else { + lock(); _drv = driver; + unlock(); } return true; @@ -467,8 +467,11 @@ int TownsAudioInterfaceIntern::processCommand(int command, va_list &args) { if (command < 0 || command > 81) return 4; - Common::StackLock lock(_mutex); - return (this->*_intfOpcodes[command])(args); + lock(); + int res = (this->*_intfOpcodes[command])(args); + unlock(); + + return res; } void TownsAudioInterfaceIntern::setMusicVolume(int volume) { @@ -539,13 +542,11 @@ void TownsAudioInterfaceIntern::nextTickEx(int32 *buffer, uint32 bufferSize) { } void TownsAudioInterfaceIntern::timerCallbackA() { - Common::StackLock lock(_mutex); if (_drv && _ready) _drv->timerCallback(0); } void TownsAudioInterfaceIntern::timerCallbackB() { - Common::StackLock lock(_mutex); if (_ready) { if (_drv) _drv->timerCallback(1); diff --git a/audio/softsynth/fmtowns_pc98/towns_midi.cpp b/audio/softsynth/fmtowns_pc98/towns_midi.cpp index 7072149d2d..ff14bb158a 100644 --- a/audio/softsynth/fmtowns_pc98/towns_midi.cpp +++ b/audio/softsynth/fmtowns_pc98/towns_midi.cpp @@ -52,7 +52,7 @@ public: private: struct StateA { uint8 numLoop; - int32 fld_1; + uint32 fld_1; int32 duration; int32 fld_9; int16 effectState; @@ -60,10 +60,10 @@ private: uint8 ar1[4]; uint8 ar2[4]; int8 modWheelSensitivity; - uint8 modWheelState; + int8 modWheelState; uint8 fld_1c; uint32 fld_1d; - int32 fld_21; + uint32 fld_21; uint32 fld_25; int8 dir; uint32 fld_2a; @@ -71,14 +71,14 @@ private: } *_stateA; struct StateB { - int8 inc; + int16 inc; uint8 type; uint8 useModWheel; uint8 fld_6; StateA *a; } *_stateB; - uint16 getEffectState(uint8 type); + int16 getEffectState(uint8 type); void initEffect(StateA *a, const uint8 *effectData); void updateEffectOuter3(StateA *a, StateB *b); int updateEffectOuter(StateA *a, StateB *b); @@ -159,7 +159,7 @@ private: int8 _transpose; uint8 _fld_1f; int8 _detune; - uint8 _modWheel; + int8 _modWheel; uint8 _sustain; uint8 _pitchBendFactor; int16 _pitchBend; @@ -392,7 +392,7 @@ int TownsMidiOutputChannel::checkPriority(int pri) { return kHighPriority; } -uint16 TownsMidiOutputChannel::getEffectState(uint8 type) { +int16 TownsMidiOutputChannel::getEffectState(uint8 type) { uint8 chan = (type < 13) ? _chanMap2[_chan] : ((type < 26) ? _chanMap[_chan] : _chan); if (type == 28) @@ -404,7 +404,7 @@ uint16 TownsMidiOutputChannel::getEffectState(uint8 type) { else if (type > 12) type -= 13; - uint32 res = 0; + int32 res = 0; uint8 cs = (_driver->_chanState[chan].get(_effectDefs[type * 4] >> 5) & _effectDefs[type * 4 + 2]) >> _effectDefs[type * 4 + 1]; if (_effectDefs[type * 4 + 3]) res = _effectDefs[type * 4 + 3] - cs; @@ -422,7 +422,7 @@ void TownsMidiOutputChannel::initEffect(StateA *a, const uint8 *effectData) { a->ar1[2] = effectData[5]; a->ar1[3] = effectData[6]; a->ar2[0] = effectData[2]; - a->ar2[1] = effectData[3]; + a->ar2[1] = effectData[4]; a->ar2[2] = 0; a->ar2[3] = effectData[7]; updateEffect(a); @@ -434,10 +434,10 @@ void TownsMidiOutputChannel::updateEffectOuter3(StateA *a, StateB *b) { if (f & 1) { switch (b->type) { case 0: - _carrierTl = (a->effectState & 0xff) + b->inc; /*???*/ + _carrierTl = a->effectState + b->inc; /*???*/ break; case 13: - _modulatorTl = (a->effectState & 0xff) + b->inc; /*???*/ + _modulatorTl = a->effectState + b->inc; /*???*/ break; case 30: b->a->modWheelState = b->inc; @@ -504,7 +504,7 @@ int TownsMidiOutputChannel::updateEffectOuter(StateA *a, StateB *b) { void TownsMidiOutputChannel::updateEffect(StateA *a) { uint8 c = a->numLoop - 1; uint16 v = a->ar1[c]; - int e = _effectData[_driver->_chanOutputLevel[((v & 0x7f) << 5) + a->modWheelSensitivity]]; + int32 e = _effectData[_driver->_chanOutputLevel[((v & 0x7f) << 5) + a->modWheelSensitivity]]; if (v & 0x80) e = _driver->randomValue(e); @@ -545,7 +545,7 @@ int TownsMidiOutputChannel::lookupVolume(int a, int b) { if (b == 31) return a; - if (a > 63) + if (a > 63 || a < -63) return ((a + 1) * b) >> 5; if (b < 0) { @@ -760,6 +760,10 @@ void TownsMidiInputChannel::controlChange(byte control, byte value) { case 64: controlSustain(value); break; + case 123: + while (_outChan) + _outChan->disconnect(); + break; default: break; } @@ -793,7 +797,7 @@ void TownsMidiInputChannel::controlVolume(byte value) { uint16 v2 = value; if (_chanIndex != 16) { _ctrlVolume = value; - v2 = value; + v2 = _player->getEffectiveVolume(); } _tl = (v1 * v2) >> 7;*/ diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp b/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp index 289cc95863..e35da91cbb 100644 --- a/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp +++ b/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp @@ -1145,7 +1145,7 @@ void TownsPC98_AudioDriver::loadMusicData(uint8 *data, bool loadPaused) { reset(); - Common::StackLock lock(_mutex); + lock(); uint8 *src_a = _trackPtr = _musicBuffer = data; for (uint8 i = 0; i < 3; i++) { @@ -1176,6 +1176,7 @@ void TownsPC98_AudioDriver::loadMusicData(uint8 *data, bool loadPaused) { _finishedChannelsFlag = _finishedSSGFlag = _finishedRhythmFlag = 0; _musicPlaying = (loadPaused ? false : true); + unlock(); } void TownsPC98_AudioDriver::loadSoundEffectData(uint8 *data, uint8 trackNum) { @@ -1194,16 +1195,17 @@ void TownsPC98_AudioDriver::loadSoundEffectData(uint8 *data, uint8 trackNum) { return; } - Common::StackLock lock(_mutex); + lock(); _sfxData = _sfxBuffer = data; _sfxOffsets[0] = READ_LE_UINT16(&_sfxData[(trackNum << 2)]); _sfxOffsets[1] = READ_LE_UINT16(&_sfxData[(trackNum << 2) + 2]); _sfxPlaying = true; _finishedSfxFlag = 0; + unlock(); } void TownsPC98_AudioDriver::reset() { - Common::StackLock lock(_mutex); + lock(); _musicPlaying = false; _sfxPlaying = false; @@ -1230,13 +1232,13 @@ void TownsPC98_AudioDriver::reset() { if (_rhythmChannel) _rhythmChannel->reset(); #endif + unlock(); } void TownsPC98_AudioDriver::fadeStep() { if (!_musicPlaying) return; - Common::StackLock lock(_mutex); for (int j = 0; j < _numChan; j++) { if (_updateChannelsFlag & _channels[j]->_idFlag) _channels[j]->fadeStep(); diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp index 57ab8d9e1f..9412538685 100644 --- a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp +++ b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp @@ -837,8 +837,7 @@ TownsPC98_FmSynth::TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type) : _hasPercussion(type == kType86 ? true : false), _oprRates(0), _oprRateshift(0), _oprAttackDecay(0), _oprFrq(0), _oprSinTbl(0), _oprLevelOut(0), _oprDetune(0), _rtt(type == kTypeTowns ? 0x514767 : 0x5B8D80), _baserate(55125.0f / (float)mixer->getOutputRate()), - _volMaskA(0), _volMaskB(0), _volumeA(255), _volumeB(255), - _regProtectionFlag(false), _ready(false) { + _volMaskA(0), _volMaskB(0), _volumeA(255), _volumeB(255), _regProtectionFlag(false), _externLock(0), _ready(false) { memset(&_timers[0], 0, sizeof(ChipTimer)); memset(&_timers[1], 0, sizeof(ChipTimer)); @@ -931,9 +930,9 @@ void TownsPC98_FmSynth::writeReg(uint8 part, uint8 regAddress, uint8 value) { if (_regProtectionFlag || !_ready) return; - static const uint8 oprOrdr[] = { 0, 2, 1, 3 }; + lock(); - Common::StackLock lock(_mutex); + static const uint8 oprOrdr[] = { 0, 2, 1, 3 }; uint8 h = regAddress & 0xf0; uint8 l = (regAddress & 0x0f); @@ -1081,6 +1080,7 @@ void TownsPC98_FmSynth::writeReg(uint8 part, uint8 regAddress, uint8 value) { if (l == 0) { c->frqTemp = (c->frqTemp & 0xff00) | value; c->updateEnvelopeParameters = true; + c->fmIndex = (c->frqTemp >> 4 & 0x7f); for (int i = 0; i < 4; i++) co[i]->frequency(c->frqTemp); } else if (l == 4) { @@ -1112,18 +1112,17 @@ void TownsPC98_FmSynth::writeReg(uint8 part, uint8 regAddress, uint8 value) { default: warning("TownsPC98_FmSynth: UNKNOWN ADDRESS %d", regAddress); } + unlock(); } int TownsPC98_FmSynth::readBuffer(int16 *buffer, const int numSamples) { - Common::StackLock lock(_mutex); - memset(buffer, 0, sizeof(int16) * numSamples); int32 *tmp = new int32[numSamples]; int32 *tmpStart = tmp; memset(tmp, 0, sizeof(int32) * numSamples); int32 samplesLeft = numSamples >> 1; - while (_ready && samplesLeft) { + while (_ready && !_externLock && samplesLeft) { int32 render = samplesLeft; for (int i = 0; i < 2; i++) { @@ -1173,6 +1172,7 @@ int TownsPC98_FmSynth::readBuffer(int16 *buffer, const int numSamples) { } delete[] tmpStart; + return numSamples; } @@ -1187,7 +1187,7 @@ uint8 TownsPC98_FmSynth::readSSGStatus() { } void TownsPC98_FmSynth::setVolumeIntern(int volA, int volB) { - Common::StackLock lock(_mutex); + lock(); _volumeA = CLIP<uint16>(volA, 0, Audio::Mixer::kMaxMixerVolume); _volumeB = CLIP<uint16>(volB, 0, Audio::Mixer::kMaxMixerVolume); if (_ssg) @@ -1196,10 +1196,11 @@ void TownsPC98_FmSynth::setVolumeIntern(int volA, int volB) { if (_prc) _prc->setVolumeIntern(_volumeA, _volumeB); #endif + unlock(); } void TownsPC98_FmSynth::setVolumeChannelMasks(int channelMaskA, int channelMaskB) { - Common::StackLock lock(_mutex); + lock(); _volMaskA = channelMaskA; _volMaskB = channelMaskB; if (_ssg) @@ -1208,6 +1209,17 @@ void TownsPC98_FmSynth::setVolumeChannelMasks(int channelMaskA, int channelMaskB if (_prc) _prc->setVolumeChannelMasks(_volMaskA >> (_numChan + _numSSG), _volMaskB >> (_numChan + _numSSG)); #endif + unlock(); +} + +void TownsPC98_FmSynth::lock() { + _mutex.lock(); + _externLock++; +} + +void TownsPC98_FmSynth::unlock() { + _mutex.unlock(); + _externLock--; } void TownsPC98_FmSynth::generateTables() { diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h index 5edd1a3ab8..f1494b6ba7 100644 --- a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h +++ b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h @@ -102,11 +102,13 @@ protected: void setVolumeIntern(int volA, int volB); void setVolumeChannelMasks(int channelMaskA, int channelMaskB); + void lock(); + void unlock(); + const int _numChan; const int _numSSG; const bool _hasPercussion; - Common::Mutex _mutex; private: void generateTables(); void nextTick(int32 *buffer, uint32 bufferSize); @@ -124,6 +126,7 @@ private: } uint16 frqTemp; + uint8 fmIndex; bool enableLeft; bool enableRight; bool updateEnvelopeParameters; @@ -179,6 +182,9 @@ private: Audio::Mixer *_mixer; Audio::SoundHandle _soundHandle; + int _externLock; + Common::Mutex _mutex; + #ifndef DISABLE_PC98_RHYTHM_CHANNEL static const uint8 _percussionData[]; #endif |