aboutsummaryrefslogtreecommitdiff
path: root/audio/softsynth
diff options
context:
space:
mode:
authorathrxx2019-08-03 22:23:24 +0200
committerathrxx2019-08-07 16:43:06 +0200
commit0e73472207b18e406f51e8bca9c3450dd908ec38 (patch)
tree676ca6131e65f5ec48668c4d01f63701ce7be0dc /audio/softsynth
parent8b197e4ec70a52f91c0774be98acf5b373542bde (diff)
downloadscummvm-rg350-0e73472207b18e406f51e8bca9c3450dd908ec38.tar.gz
scummvm-rg350-0e73472207b18e406f51e8bca9c3450dd908ec38.tar.bz2
scummvm-rg350-0e73472207b18e406f51e8bca9c3450dd908ec38.zip
AUDIO: (FM-Towns/PC98) - cleanup mutex handling
Diffstat (limited to 'audio/softsynth')
-rw-r--r--audio/softsynth/fmtowns_pc98/pc98_audio.cpp36
-rw-r--r--audio/softsynth/fmtowns_pc98/pc98_audio.h2
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_audio.cpp51
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_audio.h2
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp66
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h3
6 files changed, 77 insertions, 83 deletions
diff --git a/audio/softsynth/fmtowns_pc98/pc98_audio.cpp b/audio/softsynth/fmtowns_pc98/pc98_audio.cpp
index 3ad100911a..c8d58f6923 100644
--- a/audio/softsynth/fmtowns_pc98/pc98_audio.cpp
+++ b/audio/softsynth/fmtowns_pc98/pc98_audio.cpp
@@ -26,11 +26,11 @@
class PC98AudioCoreInternal : public TownsPC98_FmSynth {
private:
- PC98AudioCoreInternal(Audio::Mixer *mixer, PC98AudioCore *owner, PC98AudioPluginDriver *driver, PC98AudioPluginDriver::EmuType type, bool externalMutexHandling = false);
+ PC98AudioCoreInternal(Audio::Mixer *mixer, PC98AudioCore *owner, PC98AudioPluginDriver *driver, PC98AudioPluginDriver::EmuType type);
public:
~PC98AudioCoreInternal();
- static PC98AudioCoreInternal *addNewRef(Audio::Mixer *mixer, PC98AudioCore *owner, PC98AudioPluginDriver *driver, PC98AudioPluginDriver::EmuType type, bool externalMutexHandling = false);
+ static PC98AudioCoreInternal *addNewRef(Audio::Mixer *mixer, PC98AudioCore *owner, PC98AudioPluginDriver *driver, PC98AudioPluginDriver::EmuType type);
static void releaseRef(PC98AudioCore *owner);
bool init();
@@ -69,8 +69,8 @@ private:
static int _refCount;
};
-PC98AudioCoreInternal::PC98AudioCoreInternal(Audio::Mixer *mixer, PC98AudioCore *owner, PC98AudioPluginDriver *driver, PC98AudioPluginDriver::EmuType type, bool externalMutexHandling) :
- TownsPC98_FmSynth(mixer, (TownsPC98_FmSynth::EmuType)type, externalMutexHandling),
+PC98AudioCoreInternal::PC98AudioCoreInternal(Audio::Mixer *mixer, PC98AudioCore *owner, PC98AudioPluginDriver *driver, PC98AudioPluginDriver::EmuType type) :
+ TownsPC98_FmSynth(mixer, (TownsPC98_FmSynth::EmuType)type),
_drv(driver), _drvOwner(owner),
_musicVolume(Audio::Mixer::kMaxMixerVolume), _sfxVolume(Audio::Mixer::kMaxMixerVolume),
_port1(type == PC98AudioPluginDriver::kTypeTowns ? 0x4D8 : 0x188), _port2(type == PC98AudioPluginDriver::kTypeTowns ? 0x4DA : 0x18A),
@@ -80,22 +80,22 @@ PC98AudioCoreInternal::PC98AudioCoreInternal(Audio::Mixer *mixer, PC98AudioCore
}
PC98AudioCoreInternal::~PC98AudioCoreInternal() {
+ Common::StackLock lock(_mutex);
_ready = false;
deinit();
- Common::StackLock lock(_mutex);
/*
*/
}
-PC98AudioCoreInternal *PC98AudioCoreInternal::addNewRef(Audio::Mixer *mixer, PC98AudioCore *owner, PC98AudioPluginDriver *driver, PC98AudioPluginDriver::EmuType type, bool externalMutexHandling) {
+PC98AudioCoreInternal *PC98AudioCoreInternal::addNewRef(Audio::Mixer *mixer, PC98AudioCore *owner, PC98AudioPluginDriver *driver, PC98AudioPluginDriver::EmuType type) {
_refCount++;
if (_refCount == 1 && _refInstance == 0)
- _refInstance = new PC98AudioCoreInternal(mixer, owner, driver, type, externalMutexHandling);
+ _refInstance = new PC98AudioCoreInternal(mixer, owner, driver, type);
else if (_refCount < 2 || _refInstance == 0)
error("PC98AudioCoreInternal::addNewRef(): Internal reference management failure");
- else if (!_refInstance->assignPluginDriver(owner, driver, externalMutexHandling))
+ else if (!_refInstance->assignPluginDriver(owner, driver))
error("PC98AudioCoreInternal::addNewRef(): Plugin driver conflict");
return _refInstance;
@@ -139,6 +139,7 @@ bool PC98AudioCoreInternal::init() {
}
void PC98AudioCoreInternal::writePort(uint16 port, uint8 value) {
+ Common::StackLock lock(_mutex);
if (port == _port1)
_address[0] = value;
else if (port == _port2 && _address[0] < 0xc0) {
@@ -153,6 +154,7 @@ void PC98AudioCoreInternal::writePort(uint16 port, uint8 value) {
}
uint8 PC98AudioCoreInternal::readPort(uint16 port) {
+ Common::StackLock lock(_mutex);
uint8 val = 0;
if (port == _port2 && _address[0] < 0xc0) {
val = readReg(0, _address[0]);
@@ -165,20 +167,24 @@ uint8 PC98AudioCoreInternal::readPort(uint16 port) {
}
void PC98AudioCoreInternal::setMusicVolume(int volume) {
+ Common::StackLock lock(_mutex);
_musicVolume = CLIP<uint16>(volume, 0, Audio::Mixer::kMaxMixerVolume);
setVolumeIntern(_musicVolume, _sfxVolume);
}
void PC98AudioCoreInternal::setSoundEffectVolume(int volume) {
+ Common::StackLock lock(_mutex);
_sfxVolume = CLIP<uint16>(volume, 0, Audio::Mixer::kMaxMixerVolume);
setVolumeIntern(_musicVolume, _sfxVolume);
}
void PC98AudioCoreInternal::setSoundEffectChanMask(int mask) {
+ Common::StackLock lock(_mutex);
setVolumeChannelMasks(~mask, mask);
}
void PC98AudioCoreInternal::ssgSetVolume(int volume) {
+ Common::StackLock lock(_mutex);
setLevelSSG(volume);
}
@@ -187,6 +193,7 @@ Common::Mutex &PC98AudioCoreInternal::mutex() {
}
bool PC98AudioCoreInternal::assignPluginDriver(PC98AudioCore *owner, PC98AudioPluginDriver *driver, bool externalMutexHandling) {
+ Common::StackLock lock(_mutex);
if (_refCount <= 1)
return true;
@@ -194,28 +201,27 @@ bool PC98AudioCoreInternal::assignPluginDriver(PC98AudioCore *owner, PC98AudioPl
if (driver && driver != _drv)
return false;
} else {
- Common::StackLock lock(_mutex);
_drv = driver;
_drvOwner = owner;
- _externalMutex = externalMutexHandling;
}
return true;
}
void PC98AudioCoreInternal::removePluginDriver(PC98AudioCore *owner) {
- if (_drvOwner == owner) {
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(_mutex);
+ if (_drvOwner == owner)
_drv = 0;
- }
}
void PC98AudioCoreInternal::timerCallbackA() {
+ Common::StackLock lock(_mutex);
if (_drv && _ready)
_drv->timerCallbackA();
}
void PC98AudioCoreInternal::timerCallbackB() {
+ Common::StackLock lock(_mutex);
if (_drv && _ready)
_drv->timerCallbackB();
}
@@ -224,8 +230,8 @@ PC98AudioCoreInternal *PC98AudioCoreInternal::_refInstance = 0;
int PC98AudioCoreInternal::_refCount = 0;
-PC98AudioCore::PC98AudioCore(Audio::Mixer *mixer, PC98AudioPluginDriver *driver, PC98AudioPluginDriver::EmuType type, bool externalMutexHandling) {
- _internal = PC98AudioCoreInternal::addNewRef(mixer, this, driver, type, externalMutexHandling);
+PC98AudioCore::PC98AudioCore(Audio::Mixer *mixer, PC98AudioPluginDriver *driver, PC98AudioPluginDriver::EmuType type) {
+ _internal = PC98AudioCoreInternal::addNewRef(mixer, this, driver, type);
}
PC98AudioCore::~PC98AudioCore() {
diff --git a/audio/softsynth/fmtowns_pc98/pc98_audio.h b/audio/softsynth/fmtowns_pc98/pc98_audio.h
index b6269f0f67..2bfae78cd4 100644
--- a/audio/softsynth/fmtowns_pc98/pc98_audio.h
+++ b/audio/softsynth/fmtowns_pc98/pc98_audio.h
@@ -45,7 +45,7 @@ public:
class PC98AudioCore {
public:
- PC98AudioCore(Audio::Mixer *mixer, PC98AudioPluginDriver *driver, PC98AudioPluginDriver::EmuType type, bool externalMutexHandling = false);
+ PC98AudioCore(Audio::Mixer *mixer, PC98AudioPluginDriver *driver, PC98AudioPluginDriver::EmuType type);
~PC98AudioCore();
bool init();
diff --git a/audio/softsynth/fmtowns_pc98/towns_audio.cpp b/audio/softsynth/fmtowns_pc98/towns_audio.cpp
index 1a12fa9443..1464dd73b7 100644
--- a/audio/softsynth/fmtowns_pc98/towns_audio.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_audio.cpp
@@ -135,11 +135,11 @@ private:
class TownsAudioInterfaceInternal : public TownsPC98_FmSynth {
private:
- TownsAudioInterfaceInternal(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling = false);
+ TownsAudioInterfaceInternal(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver);
public:
~TownsAudioInterfaceInternal();
- static TownsAudioInterfaceInternal *addNewRef(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling = false);
+ static TownsAudioInterfaceInternal *addNewRef(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver);
static void releaseRef(TownsAudioInterface *owner);
bool init();
@@ -154,7 +154,7 @@ public:
void setSoundEffectChanMask(int mask);
private:
- bool assignPluginDriver(TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling = false);
+ bool assignPluginDriver(TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver);
void removePluginDriver(TownsAudioInterface *owner);
void nextTickEx(int32 *buffer, uint32 bufferSize);
@@ -275,8 +275,8 @@ private:
static const uint8 _fmDefaultInstrument[];
};
-TownsAudioInterfaceInternal::TownsAudioInterfaceInternal(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling) :
- TownsPC98_FmSynth(mixer, kTypeTowns, externalMutexHandling),
+TownsAudioInterfaceInternal::TownsAudioInterfaceInternal(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver) :
+ TownsPC98_FmSynth(mixer, kTypeTowns),
_fmInstruments(0), _pcmInstruments(0), _pcmChan(0), _waveTables(0), _waveTablesTotalDataSize(0),
_baserate(55125.0f / (float)mixer->getOutputRate()), _tickLength(0), _timer(0), _drv(driver), _drvOwner(owner),
_pcmSfxChanMask(0), _musicVolume(Audio::Mixer::kMaxMixerVolume), _sfxVolume(Audio::Mixer::kMaxMixerVolume),
@@ -404,11 +404,10 @@ TownsAudioInterfaceInternal::TownsAudioInterfaceInternal(Audio::Mixer *mixer, To
}
TownsAudioInterfaceInternal::~TownsAudioInterfaceInternal() {
+ Common::StackLock lock(_mutex);
_ready = false;
deinit();
- Common::StackLock lock(_mutex);
-
delete[] _fmSaveReg[0];
delete[] _fmSaveReg[1];
delete[] _fmInstruments;
@@ -417,13 +416,13 @@ TownsAudioInterfaceInternal::~TownsAudioInterfaceInternal() {
delete[] _pcmChan;
}
-TownsAudioInterfaceInternal *TownsAudioInterfaceInternal::addNewRef(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling) {
+TownsAudioInterfaceInternal *TownsAudioInterfaceInternal::addNewRef(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver) {
_refCount++;
if (_refCount == 1 && _refInstance == 0)
- _refInstance = new TownsAudioInterfaceInternal(mixer, owner, driver, externalMutexHandling);
+ _refInstance = new TownsAudioInterfaceInternal(mixer, owner, driver);
else if (_refCount < 2 || _refInstance == 0)
error("TownsAudioInterfaceInternal::addNewRef(): Internal reference management failure");
- else if (!_refInstance->assignPluginDriver(owner, driver, externalMutexHandling))
+ else if (!_refInstance->assignPluginDriver(owner, driver))
error("TownsAudioInterfaceInternal::addNewRef(): Plugin driver conflict");
return _refInstance;
@@ -448,9 +447,6 @@ bool TownsAudioInterfaceInternal::init() {
if (_ready)
return true;
- if (!TownsPC98_FmSynth::init())
- return false;
-
_fmSaveReg[0] = new uint8[256];
_fmSaveReg[1] = new uint8[256];
_fmInstruments = new uint8[128 * 48];
@@ -460,6 +456,10 @@ bool TownsAudioInterfaceInternal::init() {
_timer = 0;
+ if (!TownsPC98_FmSynth::init())
+ return false;
+
+
setVolumeChannelMasks(-1, 0);
_ready = true;
@@ -469,6 +469,7 @@ bool TownsAudioInterfaceInternal::init() {
}
int TownsAudioInterfaceInternal::callback(int command, ...) {
+ Common::StackLock lock(_mutex);
if (!_ready)
return 1;
@@ -482,35 +483,39 @@ int TownsAudioInterfaceInternal::callback(int command, ...) {
}
int TownsAudioInterfaceInternal::processCommand(int command, va_list &args) {
+ Common::StackLock lock(_mutex);
if (!_ready)
return 1;
if (command < 0 || command > 81)
return 4;
-
- Common::StackLock lock(_mutex);
+
int res = (this->*_intfOpcodes[command])(args);
return res;
}
void TownsAudioInterfaceInternal::setMusicVolume(int volume) {
+ Common::StackLock lock(_mutex);
_musicVolume = CLIP<uint16>(volume, 0, Audio::Mixer::kMaxMixerVolume);
setVolumeIntern(_musicVolume, _sfxVolume);
}
void TownsAudioInterfaceInternal::setSoundEffectVolume(int volume) {
+ Common::StackLock lock(_mutex);
_sfxVolume = CLIP<uint16>(volume, 0, Audio::Mixer::kMaxMixerVolume);
setVolumeIntern(_musicVolume, _sfxVolume);
}
void TownsAudioInterfaceInternal::setSoundEffectChanMask(int mask) {
+ Common::StackLock lock(_mutex);
_pcmSfxChanMask = mask >> 6;
mask &= 0x3f;
setVolumeChannelMasks(~mask, mask);
}
-bool TownsAudioInterfaceInternal::assignPluginDriver(TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling) {
+bool TownsAudioInterfaceInternal::assignPluginDriver(TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver) {
+ Common::StackLock lock(_mutex);
if (_refCount <= 1)
return true;
@@ -518,23 +523,21 @@ bool TownsAudioInterfaceInternal::assignPluginDriver(TownsAudioInterface *owner,
if (driver && driver != _drv)
return false;
} else {
- Common::StackLock lock(_mutex);
_drv = driver;
_drvOwner = owner;
- _externalMutex = externalMutexHandling;
}
return true;
}
void TownsAudioInterfaceInternal::removePluginDriver(TownsAudioInterface *owner) {
- if (_drvOwner == owner) {
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(_mutex);
+ if (_drvOwner == owner)
_drv = 0;
- }
}
void TownsAudioInterfaceInternal::nextTickEx(int32 *buffer, uint32 bufferSize) {
+ Common::StackLock lock(_mutex);
if (!_ready)
return;
@@ -579,11 +582,13 @@ void TownsAudioInterfaceInternal::nextTickEx(int32 *buffer, uint32 bufferSize) {
}
void TownsAudioInterfaceInternal::timerCallbackA() {
+ Common::StackLock lock(_mutex);
if (_drv && _ready)
_drv->timerCallback(0);
}
void TownsAudioInterfaceInternal::timerCallbackB() {
+ Common::StackLock lock(_mutex);
if (_ready) {
if (_drv)
_drv->timerCallback(1);
@@ -1936,8 +1941,8 @@ void TownsAudio_WaveTable::clear() {
data = 0;
}
-TownsAudioInterface::TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling) {
- _intf = TownsAudioInterfaceInternal::addNewRef(mixer, this, driver, externalMutexHandling);
+TownsAudioInterface::TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver) {
+ _intf = TownsAudioInterfaceInternal::addNewRef(mixer, this, driver);
}
TownsAudioInterface::~TownsAudioInterface() {
diff --git a/audio/softsynth/fmtowns_pc98/towns_audio.h b/audio/softsynth/fmtowns_pc98/towns_audio.h
index ba13bd10f6..815875c1ac 100644
--- a/audio/softsynth/fmtowns_pc98/towns_audio.h
+++ b/audio/softsynth/fmtowns_pc98/towns_audio.h
@@ -37,7 +37,7 @@ public:
class TownsAudioInterface {
public:
- TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling = false);
+ TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver);
~TownsAudioInterface();
enum ErrorCode {
diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
index 03b4502cda..178d33ef72 100644
--- a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
@@ -27,9 +27,8 @@
class TownsPC98_FmSynthOperator {
public:
- TownsPC98_FmSynthOperator(const uint32 timerbase, const uint32 rtt, const uint8 *rateTable,
- const uint8 *shiftTable, const uint8 *attackDecayTable, const uint32 *frqTable,
- const uint32 *sineTable, const int32 *tlevelOut, const int32 *detuneTable);
+ TownsPC98_FmSynthOperator(const uint32 timerbase, const uint32 rtt, const uint8 *rateTable, const uint8 *shiftTable,
+ const uint8 *attackDecayTable, const uint32 *frqTable, const uint32 *sineTable, const int32 *tlevelOut, const int32 *detuneTable);
~TownsPC98_FmSynthOperator() {}
void keyOn();
@@ -101,17 +100,15 @@ protected:
} fs_a, fs_d, fs_s, fs_r;
};
-TownsPC98_FmSynthOperator::TownsPC98_FmSynthOperator(const uint32 timerbase, const uint32 rtt,
- const uint8 *rateTable, const uint8 *shiftTable, const uint8 *attackDecayTable,
- const uint32 *frqTable, const uint32 *sineTable, const int32 *tlevelOut, const int32 *detuneTable) :
- _rtt(rtt), _rateTbl(rateTable), _rshiftTbl(shiftTable), _adTbl(attackDecayTable), _fTbl(frqTable),
- _sinTbl(sineTable), _tLvlTbl(tlevelOut), _detnTbl(detuneTable), _tickLength(timerbase * 2),
- _specifiedAttackRate(0), _specifiedDecayRate(0), _specifiedReleaseRate(0), _envelopeShapeSpecs(0), _specifiedSustainRate(0),
- _sustainLevel(0), _phase(0), _shapeState(0), _shapeScale(0), _state(kEnvReady), _holdKey(false), _timer(0), _keyScale1(0),
- _keyScale2(0), _freqTemp(0), _currentLevel(1023), _ampMod(false), _tickCount(0), _phaseIncrement(0) {
+TownsPC98_FmSynthOperator::TownsPC98_FmSynthOperator(const uint32 timerbase, const uint32 rtt, const uint8 *rateTable, const uint8 *shiftTable,
+ const uint8 *attackDecayTable, const uint32 *frqTable, const uint32 *sineTable, const int32 *tlevelOut, const int32 *detuneTable) :
+ _rtt(rtt), _rateTbl(rateTable), _rshiftTbl(shiftTable), _adTbl(attackDecayTable), _fTbl(frqTable), _sinTbl(sineTable),
+ _tLvlTbl(tlevelOut), _detnTbl(detuneTable), _tickLength(timerbase * 2), _specifiedAttackRate(0), _specifiedDecayRate(0),
+ _specifiedReleaseRate(0), _envelopeShapeSpecs(0), _specifiedSustainRate(0), _sustainLevel(0), _phase(0), _shapeState(0),
+ _shapeScale(0), _state(kEnvReady), _holdKey(false), _timer(0), _keyScale1(0), _keyScale2(0), _freqTemp(0),
+ _currentLevel(1023), _ampMod(false), _tickCount(0), _phaseIncrement(0) {
fs_a.rate = fs_a.shift = fs_d.rate = fs_d.shift = fs_s.rate = fs_s.shift = fs_r.rate = fs_r.shift = 0;
-
reset();
}
@@ -199,6 +196,7 @@ void TownsPC98_FmSynthOperator::generateOutput(int32 phasebuf, int32 *feed, int3
switch (_state) {
case kEnvReady:
return;
+
case kEnvAttacking:
targetLevel = 0;
nextState = _sustainLevel ? kEnvDecaying : kEnvSustaining;
@@ -211,18 +209,21 @@ void TownsPC98_FmSynthOperator::generateOutput(int32 phasebuf, int32 *feed, int3
continue;
}
break;
+
case kEnvDecaying:
targetTime = (1 << fs_d.shift) - 1;
nextState = kEnvSustaining;
targetLevel = _sustainLevel;
levelIncrement = _adTbl[fs_d.rate + ((_tickCount >> fs_d.shift) & 7)] << _shapeScale;
break;
+
case kEnvSustaining:
targetTime = (1 << fs_s.shift) - 1;
nextState = kEnvSustaining;
targetLevel = _shapeScale ? 832 : 1023;
levelIncrement = _adTbl[fs_s.rate + ((_tickCount >> fs_s.shift) & 7)] << _shapeScale;
break;
+
case kEnvReleasing:
targetTime = (1 << fs_r.shift) - 1;
nextState = kEnvReady;
@@ -238,8 +239,10 @@ void TownsPC98_FmSynthOperator::generateOutput(int32 phasebuf, int32 *feed, int3
if ((_state == kEnvAttacking && _currentLevel <= targetLevel) || (_state != kEnvAttacking && _currentLevel >= targetLevel)) {
if (_state != kEnvDecaying)
_currentLevel = targetLevel;
+
if (_state == kEnvSustaining && _shapeScale) {
_currentLevel += 191;
+
if (_shapeState & 1) {
if (!(_shapeState & 0x10))
_shapeState |= 0x40;
@@ -934,7 +937,7 @@ void TownsPC98_FmSynthPercussionSource::advanceInput(RhtChannel *ins) {
}
#endif // DISABLE_PC98_RHYTHM_CHANNEL
-TownsPC98_FmSynth::TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type, bool externalMutexHandling) :
+TownsPC98_FmSynth::TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type) :
_mixer(mixer),
_chanInternal(0), _ssg(0),
#ifndef DISABLE_PC98_RHYTHM_CHANNEL
@@ -944,7 +947,7 @@ TownsPC98_FmSynth::TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type, bool ext
_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), _externalMutex(externalMutexHandling), _ready(false) {
+ _volMaskA(0), _volMaskB(0), _volumeA(255), _volumeB(255), _ready(false) {
memset(&_timers[0], 0, sizeof(ChipTimer));
memset(&_timers[1], 0, sizeof(ChipTimer));
@@ -957,11 +960,10 @@ TownsPC98_FmSynth::TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type, bool ext
}
TownsPC98_FmSynth::~TownsPC98_FmSynth() {
+ Common::StackLock lock(_mutex);
if (_ready)
deinit();
- Common::StackLock lock(_mutex);
-
delete _ssg;
#ifndef DISABLE_PC98_RHYTHM_CHANNEL
delete _prc;
@@ -1006,8 +1008,7 @@ bool TownsPC98_FmSynth::init() {
_timers[0].cb = &TownsPC98_FmSynth::timerCallbackA;
_timers[1].cb = &TownsPC98_FmSynth::timerCallbackB;
- _mixer->playStream(Audio::Mixer::kPlainSoundType,
- &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
_ready = true;
@@ -1015,10 +1016,10 @@ bool TownsPC98_FmSynth::init() {
}
void TownsPC98_FmSynth::reset() {
+ Common::StackLock lock(_mutex);
if (!_ready)
return;
- Common::StackLock lock(_mutex);
for (int i = 0; i < _numChan; i++) {
for (int ii = 0; ii < 4; ii++)
_chanInternal[i].opr[ii]->reset();
@@ -1043,6 +1044,7 @@ void TownsPC98_FmSynth::reset() {
}
void TownsPC98_FmSynth::writeReg(uint8 part, uint8 regAddress, uint8 value) {
+ Common::StackLock lock(_mutex);
if (!_ready)
return;
@@ -1051,8 +1053,6 @@ void TownsPC98_FmSynth::writeReg(uint8 part, uint8 regAddress, uint8 value) {
return;
}
- Common::StackLock lock(_mutex);
-
static const uint8 oprOrdr[] = { 0, 2, 1, 3 };
_registers[regAddress][part] = value;
@@ -1253,6 +1253,7 @@ void TownsPC98_FmSynth::writeReg(uint8 part, uint8 regAddress, uint8 value) {
}
uint8 TownsPC98_FmSynth::readReg(uint8 part, uint8 regAddress) {
+ Common::StackLock lock(_mutex);
if (!_ready || part > 1)
return 0;
@@ -1270,18 +1271,13 @@ uint8 TownsPC98_FmSynth::readReg(uint8 part, uint8 regAddress) {
}
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;
- bool locked = false;
- if (_ready) {
- _mutex.lock();
- locked = true;
- }
-
while (_ready && samplesLeft) {
int32 render = samplesLeft;
@@ -1289,18 +1285,8 @@ int TownsPC98_FmSynth::readBuffer(int16 *buffer, const int numSamples) {
if (_timers[i].enabled && _timers[i].cb) {
if (!_timers[i].smpTillCb) {
- if (locked && _externalMutex) {
- _mutex.unlock();
- locked = false;
- }
-
(this->*_timers[i].cb)();
- if (!locked && _externalMutex) {
- _mutex.lock();
- locked = true;
- }
-
_timers[i].smpTillCb = _timers[i].smpPerCb;
_timers[i].smpTillCbRem += _timers[i].smpPerCbRem;
@@ -1343,9 +1329,6 @@ int TownsPC98_FmSynth::readBuffer(int16 *buffer, const int numSamples) {
tmp += (render << 1);
}
- if (locked)
- _mutex.unlock();
-
delete[] tmpStart;
return numSamples;
@@ -1364,9 +1347,9 @@ int TownsPC98_FmSynth::getRate() const {
}
void TownsPC98_FmSynth::deinit() {
+ Common::StackLock lock(_mutex);
_ready = false;
_mixer->stopHandle(_soundHandle);
- Common::StackLock lock(_mutex);
_timers[0].cb = _timers[1].cb = &TownsPC98_FmSynth::idleTimerCallback;
}
@@ -1395,6 +1378,7 @@ void TownsPC98_FmSynth::setVolumeChannelMasks(int channelMaskA, int channelMaskB
}
void TownsPC98_FmSynth::setLevelSSG(int vol) {
+ Common::StackLock lock(_mutex);
if (_ssg)
_ssg->setOutputLevel(vol);
}
diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h
index 0c4a77875f..730dbecb16 100644
--- a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h
+++ b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h
@@ -59,7 +59,7 @@ public:
kType86
};
- TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type, bool externalMutexHandling = false);
+ TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type);
virtual ~TownsPC98_FmSynth();
virtual bool init();
@@ -99,7 +99,6 @@ protected:
const bool _hasPercussion;
Common::Mutex _mutex;
- bool _externalMutex;
private:
void generateTables();