aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/tsage/sound.cpp53
-rw-r--r--engines/tsage/sound.h5
2 files changed, 37 insertions, 21 deletions
diff --git a/engines/tsage/sound.cpp b/engines/tsage/sound.cpp
index e26b3d1544..f5c59a709c 100644
--- a/engines/tsage/sound.cpp
+++ b/engines/tsage/sound.cpp
@@ -66,7 +66,7 @@ SoundManager::~SoundManager() {
}
_sfTerminate();
- g_system->getTimerManager()->removeTimerProc(_sfUpdateCallback);
+// g_system->getTimerManager()->removeTimerProc(_sfUpdateCallback);
}
_soundManager = NULL;
@@ -78,9 +78,12 @@ void SoundManager::postInit() {
_saver->addLoadNotifier(&SoundManager::loadNotifier);
_saver->addListener(this);
- // Install a timer for handling sound manager updates at 60Hz
- g_system->getTimerManager()->installTimerProc(_sfUpdateCallback, 1000000 / GAME_FRAME_RATE, NULL);
+// I originally separated the sound manager update method into a separate thread, since
+// it handles updates for both music and Fx. However, since Adlib updates also get done in a
+// thread, and doesn't get too far ahead, I've left it to the AdlibSoundDriver class to
+// call the update method, rather than having it be called separately
+// g_system->getTimerManager()->installTimerProc(_sfUpdateCallback, 1000000 / SOUND_FREQUENCY, NULL);
__sndmgrReady = true;
}
}
@@ -2488,7 +2491,12 @@ AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() {
_opl = OPL::Config::create();
assert(_opl);
_opl->init(_sampleRate);
-
+
+ _samplesTillCallback = 0;
+ _samplesTillCallbackRemainder = 0;
+ _samplesPerCallback = getRate() / CALLBACKS_PER_SECOND;
+ _samplesPerCallbackRemainder = getRate() % CALLBACKS_PER_SECOND;
+
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
Common::set_to(_channelVoiced, _channelVoiced + ADLIB_CHANNEL_COUNT, false);
@@ -2750,26 +2758,29 @@ void AdlibSoundDriver::setFrequency(int channel) {
}
int AdlibSoundDriver::readBuffer(int16 *buffer, const int numSamples) {
- update(buffer, numSamples);
- return numSamples;
-}
-
-void AdlibSoundDriver::update(int16 *buf, int len) {
- static int samplesLeft = 0;
- while (len != 0) {
- int count = samplesLeft;
- if (count > len) {
- count = len;
- }
- samplesLeft -= count;
- len -= count;
- _opl->readBuffer(buf, count);
- if (samplesLeft == 0) {
+ int32 samplesLeft = numSamples;
+ memset(buffer, 0, sizeof(int16) * numSamples);
+ while (samplesLeft) {
+ if (!_samplesTillCallback) {
+ SoundManager::_sfUpdateCallback(NULL);
flush();
- samplesLeft = _sampleRate / 50;
+
+ _samplesTillCallback = _samplesPerCallback;
+ _samplesTillCallbackRemainder += _samplesPerCallbackRemainder;
+ if (_samplesTillCallbackRemainder >= CALLBACKS_PER_SECOND) {
+ _samplesTillCallback++;
+ _samplesTillCallbackRemainder -= CALLBACKS_PER_SECOND;
+ }
}
- buf += count;
+
+ int32 render = MIN(samplesLeft, _samplesTillCallback);
+ samplesLeft -= render;
+ _samplesTillCallback -= render;
+
+ _opl->readBuffer(buffer, render);
+ buffer += render;
}
+ return numSamples;
}
/*--------------------------------------------------------------------------*/
diff --git a/engines/tsage/sound.h b/engines/tsage/sound.h
index 6a47a1aaf5..f954a65610 100644
--- a/engines/tsage/sound.h
+++ b/engines/tsage/sound.h
@@ -41,6 +41,7 @@ class Sound;
#define ROLAND_DRIVER_NUM 2
#define ADLIB_DRIVER_NUM 3
#define SBLASTER_DRIVER_NUM 4
+#define CALLBACKS_PER_SECOND 60
struct trackInfoStruct {
int _numTracks;
@@ -411,6 +412,10 @@ private:
const byte *_patchData;
int _masterVolume;
Common::Queue<RegisterValue> _queue;
+ int _samplesTillCallback;
+ int _samplesTillCallbackRemainder;
+ int _samplesPerCallback;
+ int _samplesPerCallbackRemainder;
bool _channelVoiced[ADLIB_CHANNEL_COUNT];
int _channelVolume[ADLIB_CHANNEL_COUNT];