aboutsummaryrefslogtreecommitdiff
path: root/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp')
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp66
1 files changed, 25 insertions, 41 deletions
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);
}