aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/sound/drivers/fmtowns.cpp2
-rw-r--r--engines/sci/sound/drivers/pc9801.cpp31
-rw-r--r--engines/scumm/imuse/drivers/fmtowns.cpp2
-rw-r--r--engines/scumm/players/player_towns.cpp2
4 files changed, 23 insertions, 14 deletions
diff --git a/engines/sci/sound/drivers/fmtowns.cpp b/engines/sci/sound/drivers/fmtowns.cpp
index 7475b01a6f..4dd74bc42d 100644
--- a/engines/sci/sound/drivers/fmtowns.cpp
+++ b/engines/sci/sound/drivers/fmtowns.cpp
@@ -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);
+ _intf = new TownsAudioInterface(mixer, this, true);
_out = new TownsChannel*[6];
for (int i = 0; i < 6; i++)
_out[i] = new TownsChannel(this, i);
diff --git a/engines/sci/sound/drivers/pc9801.cpp b/engines/sci/sound/drivers/pc9801.cpp
index a4b634f1dd..13cb9d0371 100644
--- a/engines/sci/sound/drivers/pc9801.cpp
+++ b/engines/sci/sound/drivers/pc9801.cpp
@@ -328,6 +328,7 @@ private:
const uint16 _baseTempo;
PC98AudioCore *_pc98a;
+ Audio::Mixer *_mixer;
const SciVersion _version;
};
@@ -1317,27 +1318,28 @@ void MidiPart_PC9801::assignFreeChannels() {
MidiPart_PC9801 **MidiDriver_PC9801::_parts = 0;
MidiDriver_PC9801::MidiDriver_PC9801(Audio::Mixer *mixer, SciVersion version)
- : _version(version), _pc98a(0), _chan(0), _numChan(6), _internalVersion(0xFF), _ssgPatchOffset(0xFF), _patchSize(0),
+ : _mixer(mixer), _version(version), _pc98a(0), _chan(0), _numChan(6), _internalVersion(0xFF), _ssgPatchOffset(0xFF), _patchSize(0),
_timerProc(0), _timerProcPara(0), _baseTempo(10080), _ready(false), _isOpen(false), _masterVolume(0x0f) ,_soundOn(true), _playID(0),
_polyphony(9), _channelMask1(0x10), _channelMask2(0x02) {
- _pc98a =
-#ifdef SCI_PC98_AUDIO_EXTENDED
- new PC98AudioCore(mixer, this, kType86);
-#else
- new PC98AudioCore(mixer, this, kType26);
-#endif
}
MidiDriver_PC9801::~MidiDriver_PC9801() {
- _ready = false;
close();
- delete _pc98a;
}
int MidiDriver_PC9801::open() {
if (_isOpen)
return MERR_ALREADY_OPEN;
+ if (!_pc98a) {
+ _pc98a =
+#ifdef SCI_PC98_AUDIO_EXTENDED
+ new PC98AudioCore(_mixer, this, kType86);
+#else
+ new PC98AudioCore(_mixer, this, kType26);
+#endif
+ }
+
if (!_ready) {
if (!_pc98a->init())
return MERR_CANNOT_CONNECT;
@@ -1413,7 +1415,8 @@ void MidiDriver_PC9801::close() {
bool ready = _ready;
_isOpen = _ready = false;
- PC98AudioCore::MutexLock lock = _pc98a->stackLockMutex();
+ delete _pc98a;
+ _pc98a = 0;
if (_parts) {
for (int i = 0; i < 16; ++i) {
@@ -1624,8 +1627,14 @@ bool MidiDriver_PC9801::loadInstruments(const SciSpan<const uint8> &data) {
}
void MidiDriver_PC9801::updateParser() {
- if (_timerProc)
+ if (_timerProc) {
+ // The mutex lock has to be lifted, before entering the SCI engine space. The engine has its owns mutex and the different threads
+ // will often cause an immediate lockup (each thread caught in the mutex lock of the other). I consider this safe for all realistic
+ // scenarios, since a reentry of the space guarded by the PC98 audio mutex is not possible without triggering another mutex lock.
+ // I have also rearranged the driver deconstruction appropriately.
+ PC98AudioCore::MutexLock tempUnlock = _pc98a->stackUnlockMutex();
_timerProc(_timerProcPara);
+ }
}
void MidiDriver_PC9801::updateChannels() {
diff --git a/engines/scumm/imuse/drivers/fmtowns.cpp b/engines/scumm/imuse/drivers/fmtowns.cpp
index cf15fcdb25..a85b4597e4 100644
--- a/engines/scumm/imuse/drivers/fmtowns.cpp
+++ b/engines/scumm/imuse/drivers/fmtowns.cpp
@@ -827,7 +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) {
- _intf = new TownsAudioInterface(mixer, this);
+ _intf = new TownsAudioInterface(mixer, this, true);
_channels = new TownsMidiInputChannel*[32];
for (int i = 0; i < 32; i++)
diff --git a/engines/scumm/players/player_towns.cpp b/engines/scumm/players/player_towns.cpp
index c5f6b21841..a2b3fdb0ff 100644
--- a/engines/scumm/players/player_towns.cpp
+++ b/engines/scumm/players/player_towns.cpp
@@ -586,7 +586,7 @@ void Player_Towns_v1::playCdaTrack(int sound, const uint8 *data, bool skipTrackV
Player_Towns_v2::Player_Towns_v2(ScummEngine *vm, Audio::Mixer *mixer, IMuse *imuse, bool disposeIMuse) : Player_Towns(vm, true), _imuse(imuse), _imuseDispose(disposeIMuse), _sblData(0) {
_soundOverride = new SoundOvrParameters[_numSoundMax];
memset(_soundOverride, 0, _numSoundMax * sizeof(SoundOvrParameters));
- _intf = new TownsAudioInterface(mixer, 0);
+ _intf = new TownsAudioInterface(mixer, 0, true);
}
Player_Towns_v2::~Player_Towns_v2() {