aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schickel2012-09-11 22:21:43 +0200
committerJohannes Schickel2012-09-11 22:28:40 +0200
commitc31d1971b52ab2f4fe8ad3a04d879679620e66f1 (patch)
treef2ee39a5ccc8fc21cced35af9e0fc91f7744a9ed
parentf8e93ea9f79d6d59fbcf97b219251e6c0fbeb9c7 (diff)
downloadscummvm-rg350-c31d1971b52ab2f4fe8ad3a04d879679620e66f1.tar.gz
scummvm-rg350-c31d1971b52ab2f4fe8ad3a04d879679620e66f1.tar.bz2
scummvm-rg350-c31d1971b52ab2f4fe8ad3a04d879679620e66f1.zip
CINE: Implement music fade out for Amiga/AtariST music.
-rw-r--r--engines/cine/sound.cpp71
-rw-r--r--engines/cine/sound.h7
2 files changed, 69 insertions, 9 deletions
diff --git a/engines/cine/sound.cpp b/engines/cine/sound.cpp
index ead17b1c2f..10404ae56b 100644
--- a/engines/cine/sound.cpp
+++ b/engines/cine/sound.cpp
@@ -998,21 +998,27 @@ void PCSound::stopSound(int channel) {
}
PaulaSound::PaulaSound(Audio::Mixer *mixer, CineEngine *vm)
- : Sound(mixer, vm), _sfxTimer(0) {
+ : Sound(mixer, vm), _sfxTimer(0), _musicTimer(0), _musicFadeTimer(0) {
_moduleStream = 0;
// The original is using the following timer frequency:
// 0.709379Mhz / 8000 = 88.672375Hz
// 1000000 / 88.672375Hz = 11277.46944863us
g_system->getTimerManager()->installTimerProc(&PaulaSound::sfxTimerProc, 11277, this, "PaulaSound::sfxTimerProc");
+ // The original is using the following timer frequency:
+ // 0.709379Mhz / 14565 = 48.704359Hz
+ // 1000000 / 48.704359Hz = 20532.04313806us
+ g_system->getTimerManager()->installTimerProc(&PaulaSound::musicTimerProc, 20532, this, "PaulaSound::musicTimerProc");
}
PaulaSound::~PaulaSound() {
- Common::StackLock lock(_mutex);
-
+ Common::StackLock sfxLock(_sfxMutex);
g_system->getTimerManager()->removeTimerProc(&PaulaSound::sfxTimerProc);
for (int i = 0; i < NUM_CHANNELS; ++i) {
stopSound(i);
}
+
+ Common::StackLock musicLock(_musicMutex);
+ g_system->getTimerManager()->removeTimerProc(&PaulaSound::musicTimerProc);
stopMusic();
}
@@ -1022,6 +1028,25 @@ void PaulaSound::loadMusic(const char *name) {
stopSound(i);
}
+ // Fade music out when there is music playing.
+ _musicMutex.lock();
+ if (_mixer->isSoundHandleActive(_moduleHandle)) {
+ // Only start fade out when it is not in progress.
+ if (!_musicFadeTimer) {
+ _musicFadeTimer = 1;
+ }
+
+ _musicMutex.unlock();
+ while (_musicFadeTimer != 64) {
+ g_system->delayMillis(50);
+ }
+ } else {
+ _musicMutex.unlock();
+ }
+
+ Common::StackLock lock(_musicMutex);
+ assert(!_mixer->isSoundHandleActive(_moduleHandle));
+
if (_vm->getGameType() == GType_FW) {
// look for separate files
Common::File f;
@@ -1042,26 +1067,32 @@ void PaulaSound::loadMusic(const char *name) {
void PaulaSound::playMusic() {
debugC(5, kCineDebugSound, "PaulaSound::playMusic()");
+ Common::StackLock lock(_musicMutex);
+
_mixer->stopHandle(_moduleHandle);
if (_moduleStream) {
+ _musicFadeTimer = 0;
_mixer->playStream(Audio::Mixer::kMusicSoundType, &_moduleHandle, _moduleStream);
}
}
void PaulaSound::stopMusic() {
debugC(5, kCineDebugSound, "PaulaSound::stopMusic()");
+ Common::StackLock lock(_musicMutex);
+
_mixer->stopHandle(_moduleHandle);
}
void PaulaSound::fadeOutMusic() {
debugC(5, kCineDebugSound, "PaulaSound::fadeOutMusic()");
- // TODO
- stopMusic();
+ Common::StackLock lock(_musicMutex);
+
+ _musicFadeTimer = 1;
}
void PaulaSound::playSound(int channel, int frequency, const uint8 *data, int size, int volumeStep, int stepCount, int volume, int repeat) {
debugC(5, kCineDebugSound, "PaulaSound::playSound() channel %d size %d", channel, size);
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(_sfxMutex);
assert(frequency > 0);
stopSound(channel);
@@ -1090,7 +1121,7 @@ void PaulaSound::playSound(int channel, int frequency, const uint8 *data, int si
void PaulaSound::stopSound(int channel) {
debugC(5, kCineDebugSound, "PaulaSound::stopSound() channel %d", channel);
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(_sfxMutex);
_mixer->stopHandle(_channelsTable[channel].handle);
}
@@ -1101,7 +1132,7 @@ void PaulaSound::sfxTimerProc(void *param) {
}
void PaulaSound::sfxTimerCallback() {
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(_sfxMutex);
if (_sfxTimer < 6) {
++_sfxTimer;
@@ -1133,6 +1164,30 @@ void PaulaSound::sfxTimerCallback() {
}
}
+void PaulaSound::musicTimerProc(void *param) {
+ PaulaSound *sound = (PaulaSound *)param;
+ sound->musicTimerCallback();
+}
+
+void PaulaSound::musicTimerCallback() {
+ Common::StackLock lock(_musicMutex);
+
+ ++_musicTimer;
+ if (_musicTimer == 6) {
+ _musicTimer = 0;
+ if (_musicFadeTimer) {
+ ++_musicFadeTimer;
+ if (_musicFadeTimer == 64) {
+ stopMusic();
+ } else {
+ if (_mixer->isSoundHandleActive(_moduleHandle)) {
+ _mixer->setChannelVolume(_moduleHandle, (64 - _musicFadeTimer) * Audio::Mixer::kMaxChannelVolume / 64);
+ }
+ }
+ }
+ }
+}
+
const int PaulaSound::_channelBalance[NUM_CHANNELS] = {
// L/R/R/L This is according to the Hardware Reference Manual.
// TODO: It seems the order is swapped for some Amiga models:
diff --git a/engines/cine/sound.h b/engines/cine/sound.h
index fe1c5a9130..fdb183ad34 100644
--- a/engines/cine/sound.h
+++ b/engines/cine/sound.h
@@ -98,7 +98,6 @@ public:
};
protected:
- Common::Mutex _mutex;
struct SfxChannel {
Audio::SoundHandle handle;
@@ -115,10 +114,16 @@ protected:
};
SfxChannel _channelsTable[NUM_CHANNELS];
static const int _channelBalance[NUM_CHANNELS];
+ Common::Mutex _sfxMutex;
int _sfxTimer;
static void sfxTimerProc(void *param);
void sfxTimerCallback();
+ Common::Mutex _musicMutex;
+ int _musicTimer;
+ int _musicFadeTimer;
+ static void musicTimerProc(void *param);
+ void musicTimerCallback();
Audio::SoundHandle _moduleHandle;
Audio::AudioStream *_moduleStream;
};