aboutsummaryrefslogtreecommitdiff
path: root/audio
diff options
context:
space:
mode:
Diffstat (limited to 'audio')
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_audio.cpp33
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_audio.h9
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_midi.cpp4
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp29
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h6
5 files changed, 36 insertions, 45 deletions
diff --git a/audio/softsynth/fmtowns_pc98/towns_audio.cpp b/audio/softsynth/fmtowns_pc98/towns_audio.cpp
index 5161871601..42a8252d53 100644
--- a/audio/softsynth/fmtowns_pc98/towns_audio.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_audio.cpp
@@ -103,12 +103,12 @@ private:
class TownsAudioInterfaceInternal : public TownsPC98_FmSynth {
public:
- TownsAudioInterfaceInternal(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver);
+ TownsAudioInterfaceInternal(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling = false);
~TownsAudioInterfaceInternal();
- static TownsAudioInterfaceInternal *addNewRef(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver);
+ static TownsAudioInterfaceInternal *addNewRef(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling = false);
static void releaseRef();
- bool checkPluginDriver(TownsAudioInterfacePluginDriver *driver);
+ bool checkPluginDriver(TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling = false);
bool init();
@@ -252,7 +252,8 @@ private:
static const uint16 _pcmPhase2[];
};
-TownsAudioInterfaceInternal::TownsAudioInterfaceInternal(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver) : TownsPC98_FmSynth(mixer, kTypeTowns),
+TownsAudioInterfaceInternal::TownsAudioInterfaceInternal(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling) :
+ TownsPC98_FmSynth(mixer, kTypeTowns, externalMutexHandling),
_fmInstruments(0), _pcmInstruments(0), _pcmChan(0), _waveTables(0), _waveTablesTotalDataSize(0),
_baserate(55125.0f / (float)mixer->getOutputRate()), _tickLength(0), _timer(0), _drv(driver),
_pcmSfxChanMask(0), _musicVolume(Audio::Mixer::kMaxMixerVolume), _sfxVolume(Audio::Mixer::kMaxMixerVolume),
@@ -395,13 +396,13 @@ TownsAudioInterfaceInternal::~TownsAudioInterfaceInternal() {
delete[] _pcmChan;
}
-TownsAudioInterfaceInternal *TownsAudioInterfaceInternal::addNewRef(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver) {
+TownsAudioInterfaceInternal *TownsAudioInterfaceInternal::addNewRef(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling) {
_refCount++;
if (_refCount == 1 && _refInstance == 0)
- _refInstance = new TownsAudioInterfaceInternal(mixer, driver);
+ _refInstance = new TownsAudioInterfaceInternal(mixer, driver, externalMutexHandling);
else if (_refCount < 2 || _refInstance == 0)
error("TownsAudioInterfaceInternal::addNewRef(): Internal reference management failure");
- else if (!_refInstance->checkPluginDriver(driver))
+ else if (!_refInstance->checkPluginDriver(driver, externalMutexHandling))
error("TownsAudioInterfaceInternal::addNewRef(): Plugin driver conflict");
return _refInstance;
@@ -419,7 +420,7 @@ void TownsAudioInterfaceInternal::releaseRef() {
}
}
-bool TownsAudioInterfaceInternal::checkPluginDriver(TownsAudioInterfacePluginDriver *driver) {
+bool TownsAudioInterfaceInternal::checkPluginDriver(TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling) {
if (_refCount <= 1)
return true;
@@ -428,6 +429,7 @@ bool TownsAudioInterfaceInternal::checkPluginDriver(TownsAudioInterfacePluginDri
return false;
} else {
_drv = driver;
+ _externalMutex = externalMutexHandling;
}
return true;
@@ -1669,7 +1671,6 @@ void TownsAudioInterfaceInternal::updateOutputVolumeInternal() {
int volume = (int)(((float)(maxVol * 255) / 63.0f));
int balance = maxVol ? (int)( ( ((int)_outputLevel[13] * (_outputMute[13] ^ 1) - _outputLevel[12] * (_outputMute[12] ^ 1)) * 127) / (float)maxVol) : 0;
- Common::StackLock lock(_mutex);
g_system->getAudioCDManager()->setVolume(volume);
g_system->getAudioCDManager()->setBalance(balance);
@@ -1854,8 +1855,8 @@ void TownsAudio_WaveTable::clear() {
data = 0;
}
-TownsAudioInterface::TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver) {
- _intf = TownsAudioInterfaceInternal::addNewRef(mixer, driver);
+TownsAudioInterface::TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling) {
+ _intf = TownsAudioInterfaceInternal::addNewRef(mixer, driver, externalMutexHandling);
}
TownsAudioInterface::~TownsAudioInterface() {
@@ -1887,12 +1888,4 @@ void TownsAudioInterface::setSoundEffectVolume(int volume) {
void TownsAudioInterface::setSoundEffectChanMask(int mask) {
_intf->setSoundEffectChanMask(mask);
-}
-
-void TownsAudioInterface::lockInternal() {
- _intf->mutexLock();
-}
-
-void TownsAudioInterface::unlockInternal() {
- _intf->mutexUnlock();
-}
+} \ No newline at end of file
diff --git a/audio/softsynth/fmtowns_pc98/towns_audio.h b/audio/softsynth/fmtowns_pc98/towns_audio.h
index b00243f610..4af888f009 100644
--- a/audio/softsynth/fmtowns_pc98/towns_audio.h
+++ b/audio/softsynth/fmtowns_pc98/towns_audio.h
@@ -35,7 +35,7 @@ public:
class TownsAudioInterface {
public:
- TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver);
+ TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver, bool externalMutexHandling = false);
~TownsAudioInterface();
bool init();
@@ -48,13 +48,6 @@ public:
// The first 6 bits are the 6 fm channels. The next 8 bits are pcm channels.
void setSoundEffectChanMask(int mask);
- // These methods should not be needed in standard situations, since the mutex
- // is handled internally. However, they may be required to avoid lockup situations
- // if the code using this class has a mutex of its own (example for a lockup
- // situation: imuse.cpp, line 78).
- void lockInternal();
- void unlockInternal();
-
private:
TownsAudioInterfaceInternal *_intf;
};
diff --git a/audio/softsynth/fmtowns_pc98/towns_midi.cpp b/audio/softsynth/fmtowns_pc98/towns_midi.cpp
index 00f0d43b98..4617b0555c 100644
--- a/audio/softsynth/fmtowns_pc98/towns_midi.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_midi.cpp
@@ -834,7 +834,9 @@ const uint8 TownsMidiInputChannel::_programAdjustLevel[] = {
MidiDriver_TOWNS::MidiDriver_TOWNS(Audio::Mixer *mixer) : _timerProc(0), _timerProcPara(0), _channels(0), _out(0),
_chanState(0), _operatorLevelTable(0), _tickCounter1(0), _tickCounter2(0), _rand(1), _allocCurPos(0), _isOpen(false) {
- _intf = new TownsAudioInterface(mixer, this);
+ // We set exteral mutex handling to true, since this driver is only suitable for use with the SCUMM engine
+ // which has its own mutex. This causes lockups which cannot always be avoided.
+ _intf = new TownsAudioInterface(mixer, this, true);
_channels = new TownsMidiInputChannel*[32];
for (int i = 0; i < 32; i++)
diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
index 4336de9bdb..f4dd3cf6cc 100644
--- a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
+++ b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
@@ -851,7 +851,7 @@ void TownsPC98_FmSynthPercussionSource::advanceInput(RhtChannel *ins) {
}
#endif // DISABLE_PC98_RHYTHM_CHANNEL
-TownsPC98_FmSynth::TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type) :
+TownsPC98_FmSynth::TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type, bool externalMutexHandling) :
_mixer(mixer),
_chanInternal(0), _ssg(0),
#ifndef DISABLE_PC98_RHYTHM_CHANNEL
@@ -861,7 +861,8 @@ 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), _externalMutex(externalMutexHandling), _ready(false) {
memset(&_timers[0], 0, sizeof(ChipTimer));
memset(&_timers[1], 0, sizeof(ChipTimer));
@@ -1147,7 +1148,7 @@ int TownsPC98_FmSynth::readBuffer(int16 *buffer, const int numSamples) {
bool locked = false;
if (_ready) {
- mutexLock();
+ _mutex.lock();
locked = true;
}
@@ -1157,7 +1158,19 @@ int TownsPC98_FmSynth::readBuffer(int16 *buffer, const int numSamples) {
for (int i = 0; i < 2; i++) {
if (_timers[i].enabled && _timers[i].cb) {
if (!_timers[i].smpTillCb) {
+
+ if (locked && _externalMutex) {
+ _mutex.unlock();
+ locked = false;
+ }
+
(this->*_timers[i].cb)();
+
+ if (_ready && !locked && _externalMutex) {
+ _mutex.lock();
+ locked = true;
+ }
+
_timers[i].smpTillCb = _timers[i].smpPerCb;
_timers[i].smpTillCbRem += _timers[i].smpPerCbRem;
@@ -1201,7 +1214,7 @@ int TownsPC98_FmSynth::readBuffer(int16 *buffer, const int numSamples) {
}
if (locked)
- mutexUnlock();
+ _mutex.unlock();
delete[] tmpStart;
@@ -1220,14 +1233,6 @@ int TownsPC98_FmSynth::getRate() const {
return _mixer->getOutputRate();
}
-void TownsPC98_FmSynth::mutexLock() {
- _mutex.lock();
-}
-
-void TownsPC98_FmSynth::mutexUnlock() {
- _mutex.unlock();
-}
-
void TownsPC98_FmSynth::deinit() {
_ready = false;
_mixer->stopHandle(_soundHandle);
diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h
index 6ea9815a72..50a05f92a9 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);
+ TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type, bool externalMutexHandling = false);
virtual ~TownsPC98_FmSynth();
virtual bool init();
@@ -73,9 +73,6 @@ public:
bool endOfData() const;
int getRate() const;
- void mutexLock();
- void mutexUnlock();
-
protected:
void deinit();
@@ -104,6 +101,7 @@ protected:
const bool _hasPercussion;
Common::Mutex _mutex;
+ bool _externalMutex;
private:
void generateTables();