mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
AUDIO: (FM-Towns/PC98) - cleanup mutex handling
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
namespace Kyra {
|
||||
|
||||
SoundTowns_Darkmoon::SoundTowns_Darkmoon(KyraEngine_v1 *vm, Audio::Mixer *mixer) : Sound(vm, mixer) {
|
||||
_intf = new TownsAudioInterface(mixer, this, false);
|
||||
_intf = new TownsAudioInterface(mixer, this);
|
||||
_pcmData = 0;
|
||||
_pcmVol = 0;
|
||||
_timer = 0;
|
||||
|
||||
@@ -405,7 +405,7 @@ int TownsMidiPart::allocateChannel() {
|
||||
}
|
||||
|
||||
MidiDriver_FMTowns::MidiDriver_FMTowns(Audio::Mixer *mixer, SciVersion version) : _version(version), _timerProc(0), _timerProcPara(0), _baseTempo(10080), _ready(false), _isOpen(false), _masterVolume(0x0f), _soundOn(true) {
|
||||
_intf = new TownsAudioInterface(mixer, this, true);
|
||||
_intf = new TownsAudioInterface(mixer, this);
|
||||
_out = new TownsChannel*[6];
|
||||
for (int i = 0; i < 6; i++)
|
||||
_out[i] = new TownsChannel(this, i);
|
||||
|
||||
@@ -1322,9 +1322,9 @@ MidiDriver_PC9801::MidiDriver_PC9801(Audio::Mixer *mixer, SciVersion version)
|
||||
_polyphony(9), _channelMask1(0x10), _channelMask2(0x02) {
|
||||
_pc98a =
|
||||
#ifdef SCI_PC98_AUDIO_EXTENDED
|
||||
new PC98AudioCore(mixer, this, kType86, true);
|
||||
new PC98AudioCore(mixer, this, kType86);
|
||||
#else
|
||||
new PC98AudioCore(mixer, this, kType26, true);
|
||||
new PC98AudioCore(mixer, this, kType26);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -827,8 +827,7 @@ const uint8 TownsMidiInputChannel::_programAdjustLevel[] = {
|
||||
|
||||
MidiDriver_TOWNS::MidiDriver_TOWNS(Audio::Mixer *mixer) : _timerProc(0), _timerProcPara(0), _channels(0), _out(0),
|
||||
_baseTempo(10080), _chanState(0), _operatorLevelTable(0), _tickCounter(0), _rand(1), _allocCurPos(0), _isOpen(false) {
|
||||
// We set exteral mutex handling to true to avoid lockups in SCUMM which has its own mutex.
|
||||
_intf = new TownsAudioInterface(mixer, this, true);
|
||||
_intf = new TownsAudioInterface(mixer, this);
|
||||
|
||||
_channels = new TownsMidiInputChannel*[32];
|
||||
for (int i = 0; i < 32; i++)
|
||||
|
||||
Reference in New Issue
Block a user