aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schickel2011-12-11 04:54:18 +0100
committerJohannes Schickel2011-12-11 05:04:08 +0100
commit6ba090b45aee2b39851c97ea3424a85f27d84138 (patch)
tree766ec294c4c0dbe46f98eece7a1422169a53c8d4
parent42fd6975447b99f4a66ec411a62def2b3b49c5d6 (diff)
downloadscummvm-rg350-6ba090b45aee2b39851c97ea3424a85f27d84138.tar.gz
scummvm-rg350-6ba090b45aee2b39851c97ea3424a85f27d84138.tar.bz2
scummvm-rg350-6ba090b45aee2b39851c97ea3424a85f27d84138.zip
CINE: Make PC sound code thread safe, since the MIDI output might run the callback in an extra thread.
-rw-r--r--engines/cine/sound.cpp26
1 files changed, 24 insertions, 2 deletions
diff --git a/engines/cine/sound.cpp b/engines/cine/sound.cpp
index c909474093..1fb18a9885 100644
--- a/engines/cine/sound.cpp
+++ b/engines/cine/sound.cpp
@@ -26,6 +26,7 @@
#include "common/system.h"
#include "common/textconsole.h"
#include "common/timer.h"
+#include "common/mutex.h"
#include "cine/cine.h"
#include "cine/sound.h"
@@ -200,6 +201,7 @@ public:
private:
MidiDriver *_output;
UpdateCallback _callback;
+ Common::Mutex _mutex;
void writeInstrument(int offset, const byte *data, int size);
void selectInstrument(int channel, int unk, int instrument, int volume);
@@ -241,6 +243,7 @@ private:
byte *_sfxData;
byte *_instrumentsData[NUM_INSTRUMENTS];
PCSoundDriver *_driver;
+ Common::Mutex _mutex;
};
@@ -595,7 +598,7 @@ void AdLibSoundDriverADL::playSample(const byte *data, int size, int channel, in
}
MidiSoundDriverH32::MidiSoundDriverH32(MidiDriver *output)
- : _output(output), _callback(0) {
+ : _output(output), _callback(0), _mutex() {
}
MidiSoundDriverH32::~MidiSoundDriverH32() {
@@ -607,6 +610,8 @@ MidiSoundDriverH32::~MidiSoundDriverH32() {
}
void MidiSoundDriverH32::setUpdateCallback(UpdateCallback upCb, void *ref) {
+ Common::StackLock lock(_mutex);
+
Common::TimerManager *timer = g_system->getTimerManager();
assert(timer);
@@ -619,6 +624,8 @@ void MidiSoundDriverH32::setUpdateCallback(UpdateCallback upCb, void *ref) {
}
void MidiSoundDriverH32::setupChannel(int channel, const byte *data, int instrument, int volume) {
+ Common::StackLock lock(_mutex);
+
if (volume < 0 || volume > 100)
volume = 0;
@@ -631,6 +638,8 @@ void MidiSoundDriverH32::setupChannel(int channel, const byte *data, int instrum
}
void MidiSoundDriverH32::setChannelFrequency(int channel, int frequency) {
+ Common::StackLock lock(_mutex);
+
int note, oct;
findNote(frequency, &note, &oct);
note %= 12;
@@ -640,10 +649,14 @@ void MidiSoundDriverH32::setChannelFrequency(int channel, int frequency) {
}
void MidiSoundDriverH32::stopChannel(int channel) {
+ Common::StackLock lock(_mutex);
+
_output->send(0xB1 + channel, 0x7B, 0x00);
}
void MidiSoundDriverH32::playSample(const byte *data, int size, int channel, int volume) {
+ Common::StackLock lock(_mutex);
+
stopChannel(channel);
volume = volume * 8 / 5;
@@ -659,6 +672,8 @@ void MidiSoundDriverH32::playSample(const byte *data, int size, int channel, int
}
void MidiSoundDriverH32::notifyInstrumentLoad(const byte *data, int size, int channel) {
+ Common::StackLock lock(_mutex);
+
if (data[0] < 0x80 || data[0] > 0xC0)
return;
@@ -722,7 +737,7 @@ void MidiSoundDriverH32::selectInstrument(int channel, int unk, int instrument,
}
PCSoundFxPlayer::PCSoundFxPlayer(PCSoundDriver *driver)
- : _playing(false), _driver(driver) {
+ : _playing(false), _driver(driver), _mutex() {
memset(_instrumentsData, 0, sizeof(_instrumentsData));
_sfxData = NULL;
_fadeOutCounter = 0;
@@ -730,12 +745,15 @@ PCSoundFxPlayer::PCSoundFxPlayer(PCSoundDriver *driver)
}
PCSoundFxPlayer::~PCSoundFxPlayer() {
+ Common::StackLock lock(_mutex);
+
_driver->setUpdateCallback(NULL, NULL);
stop();
}
bool PCSoundFxPlayer::load(const char *song) {
debug(9, "PCSoundFxPlayer::load('%s')", song);
+ Common::StackLock lock(_mutex);
/* stop (w/ fade out) the previous song */
while (_fadeOutCounter != 0 && _fadeOutCounter < 100) {
@@ -779,6 +797,7 @@ bool PCSoundFxPlayer::load(const char *song) {
void PCSoundFxPlayer::play() {
debug(9, "PCSoundFxPlayer::play()");
+ Common::StackLock lock(_mutex);
if (_sfxData) {
for (int i = 0; i < NUM_CHANNELS; ++i) {
_instrumentsChannelTable[i] = -1;
@@ -793,6 +812,7 @@ void PCSoundFxPlayer::play() {
}
void PCSoundFxPlayer::stop() {
+ Common::StackLock lock(_mutex);
if (_playing || _fadeOutCounter != 0) {
_fadeOutCounter = 0;
_playing = false;
@@ -805,6 +825,7 @@ void PCSoundFxPlayer::stop() {
}
void PCSoundFxPlayer::fadeOut() {
+ Common::StackLock lock(_mutex);
if (_playing) {
_fadeOutCounter = 1;
_playing = false;
@@ -816,6 +837,7 @@ void PCSoundFxPlayer::updateCallback(void *ref) {
}
void PCSoundFxPlayer::update() {
+ Common::StackLock lock(_mutex);
if (_playing || (_fadeOutCounter != 0 && _fadeOutCounter < 100)) {
++_updateTicksCounter;
if (_updateTicksCounter > _eventsDelay) {