diff options
author | athrxx | 2011-05-23 16:37:58 +0200 |
---|---|---|
committer | unknown | 2011-05-29 01:04:01 +0200 |
commit | c60807cbb9dec063c0b00f8d6ffdb19e83db48f3 (patch) | |
tree | 8a590760f7a5047f9a7ae739699d7a53bffe0e27 /audio | |
parent | 3d42141e9dda203a5dae7bb91384405be5abc243 (diff) | |
download | scummvm-rg350-c60807cbb9dec063c0b00f8d6ffdb19e83db48f3.tar.gz scummvm-rg350-c60807cbb9dec063c0b00f8d6ffdb19e83db48f3.tar.bz2 scummvm-rg350-c60807cbb9dec063c0b00f8d6ffdb19e83db48f3.zip |
FM-TOWNS AUDIO: Unlock internal mutex before calling imuse timer proc.
Diffstat (limited to 'audio')
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_audio.cpp | 33 | ||||
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_audio.h | 9 | ||||
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_midi.cpp | 4 | ||||
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp | 29 | ||||
-rw-r--r-- | audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h | 6 |
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(); |