diff options
-rw-r--r-- | engines/tsage/events.cpp | 6 | ||||
-rw-r--r-- | engines/tsage/sound.cpp | 51 | ||||
-rw-r--r-- | engines/tsage/sound.h | 22 |
3 files changed, 72 insertions, 7 deletions
diff --git a/engines/tsage/events.cpp b/engines/tsage/events.cpp index 94c074a50b..a24f65421b 100644 --- a/engines/tsage/events.cpp +++ b/engines/tsage/events.cpp @@ -48,9 +48,8 @@ bool EventsClass::pollEvent() { _priorFrameTime = milli; ++_frameNumber; - // Update screen and allow the sound manager to process pending sounds + // Update screen g_system->updateScreen(); - SoundManager::_sfSoundServer(); } if (!g_system->getEventManager()->pollEvent(_event)) return false; @@ -299,9 +298,6 @@ void EventsClass::delay(int numFrames) { ++_frameNumber; _priorFrameTime = g_system->getMillis(); - - // Allow pending sounds to be processed - SoundManager::_sfSoundServer(); } g_system->updateScreen(); diff --git a/engines/tsage/sound.cpp b/engines/tsage/sound.cpp index 0c0d93be03..24c64bda3c 100644 --- a/engines/tsage/sound.cpp +++ b/engines/tsage/sound.cpp @@ -51,6 +51,8 @@ SoundManager::SoundManager() { _needToRethink = false; _soTimeIndexFlag = false; + _updateTicksCounter = 0; + _eventsDelay = GAME_FRAME_TIME; } SoundManager::~SoundManager() { @@ -114,6 +116,14 @@ void SoundManager::syncSounds() { this->setMasterVol(musicVolume / 2); } +void SoundManager::update() { + ++_updateTicksCounter; + if (_updateTicksCounter > _eventsDelay) { + _sfSoundServer(); + _updateTicksCounter = 0; + } +} + Common::List<SoundDriverEntry> &SoundManager::buildDriverList(bool detectFlag) { assert(__sndmgrReady); _availableDrivers.clear(); @@ -482,6 +492,10 @@ void SoundManager::_sfUpdateVoiceStructs2() { } } +void SoundManager::_sfUpdateCallback(void *ref) { + ((SoundManager *)ref)->update(); +} + /*--------------------------------------------------------------------------*/ void SoundManager::saveNotifier(bool postFlag) { @@ -1293,7 +1307,8 @@ void SoundManager::_sfExtractGroupMask() { bool SoundManager::_sfInstallDriver(SoundDriver *driver) { if (!driver->open()) return false; - + + driver->setUpdateCallback(_sfUpdateCallback, (void *)&sfManager()); sfManager()._installedDrivers.push_back(driver); driver->_groupOffset = driver->getGroupData(); driver->_groupMask = READ_LE_UINT32(driver->_groupOffset); @@ -2376,6 +2391,8 @@ const int v440D4[48] = { }; AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() { + _upCb = NULL; + _upRef = NULL; _minVersion = 0x102; _maxVersion = 0x10A; _masterVolume = 0; @@ -2388,6 +2405,7 @@ AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() { _mixer = _vm->_mixer; _sampleRate = _mixer->getOutputRate(); _opl = makeAdLibOPL(_sampleRate); + _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); Common::set_to(_channelVoiced, _channelVoiced + ADLIB_CHANNEL_COUNT, false); memset(_channelVolume, 0, ADLIB_CHANNEL_COUNT * sizeof(int)); @@ -2404,6 +2422,7 @@ AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() { AdlibSoundDriver::~AdlibSoundDriver() { DEALLOCATE(_patchData); + _mixer->stopHandle(_soundHandle); OPLDestroy(_opl); } @@ -2640,4 +2659,34 @@ void AdlibSoundDriver::setFrequency(int channel) { ((dataWord >> 8) & 3) | (var2 << 2)); } +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; + YM3812UpdateOne(_opl, buf, count); + if (samplesLeft == 0) { + if (_upCb) { + (*_upCb)(_upRef); + } + samplesLeft = _sampleRate / 50; + } + buf += count; + } +} + +void AdlibSoundDriver::setUpdateCallback(UpdateCallback upCb, void *ref) { + _upCb = upCb; + _upRef = ref; +} + } // End of namespace tSage diff --git a/engines/tsage/sound.h b/engines/tsage/sound.h index 4cda2cd1d9..ed93d33443 100644 --- a/engines/tsage/sound.h +++ b/engines/tsage/sound.h @@ -72,6 +72,10 @@ public: uint32 _groupMask; const GroupData *_groupOffset; int _driverResID; + + typedef void (*UpdateCallback)(void *); + UpdateCallback _upCb; + void *_upRef; public: SoundDriver(); virtual ~SoundDriver() {}; @@ -101,6 +105,8 @@ public: virtual void proc38(int channel, int cmd, int value) {} // Method #19 virtual void setPitch(int channel, int pitchBlend) {} // Method #20 virtual void proc42(int channel, int v0, int v1) {} // Method #21 + + virtual void setUpdateCallback(UpdateCallback upCb, void *ref) {} }; struct VoiceStructEntryType0 { @@ -171,6 +177,8 @@ public: Common::List<Sound *> _soundList; Common::List<SoundDriverEntry> _availableDrivers; bool _needToRethink; + int _updateTicksCounter; + int _eventsDelay; // Misc flags bool _soTimeIndexFlag; public: @@ -181,6 +189,7 @@ public: virtual void listenerSynchronize(Serializer &s); virtual void postInit(); void syncSounds(); + void update(); static void saveNotifier(bool postFlag); void saveNotifierProc(bool postFlag); @@ -243,6 +252,7 @@ public: static void _sfProcessFading(); static void _sfUpdateVoiceStructs(); static void _sfUpdateVoiceStructs2(); + static void _sfUpdateCallback(void *ref); }; class Sound: public EventHandler { @@ -387,11 +397,12 @@ public: #define ADLIB_CHANNEL_COUNT 9 -class AdlibSoundDriver: public SoundDriver { +class AdlibSoundDriver: public SoundDriver, Audio::AudioStream { private: GroupData _groupData; Audio::Mixer *_mixer; FM_OPL *_opl; + Audio::SoundHandle _soundHandle; int _sampleRate; byte _portContents[256]; const byte *_patchData; @@ -428,6 +439,15 @@ public: virtual void updateVoice(int channel); virtual void proc38(int channel, int cmd, int value); virtual void setPitch(int channel, int pitchBlend); + virtual void setUpdateCallback(UpdateCallback upCb, void *ref); + + // AudioStream interface + virtual int readBuffer(int16 *buffer, const int numSamples); + virtual bool isStereo() const { return false; } + virtual bool endOfData() const { return false; } + virtual int getRate() const { return _sampleRate; } + + void update(int16 *buf, int len); }; } // End of namespace tSage |