From bf4562ba4f8befe9f985c464e9a5094e3e6f255d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 12 Aug 2016 07:46:35 -0400 Subject: TITANIC: Further fleshing out sound manager, fixing sound looping --- engines/titanic/sound/proximity.cpp | 2 +- engines/titanic/sound/proximity.h | 2 +- engines/titanic/sound/qmixer.cpp | 23 ++++++++++++++++++----- engines/titanic/sound/qmixer.h | 7 ++++--- engines/titanic/sound/sound.cpp | 22 ++++++++++++++++------ engines/titanic/sound/sound.h | 15 +++++++++------ engines/titanic/sound/sound_manager.cpp | 4 ++-- engines/titanic/sound/sound_manager.h | 2 +- engines/titanic/sound/wave_file.h | 2 +- 9 files changed, 53 insertions(+), 26 deletions(-) (limited to 'engines/titanic/sound') diff --git a/engines/titanic/sound/proximity.cpp b/engines/titanic/sound/proximity.cpp index b4cd16077c..7f4e6784f2 100644 --- a/engines/titanic/sound/proximity.cpp +++ b/engines/titanic/sound/proximity.cpp @@ -30,7 +30,7 @@ CProximity::CProximity() : _field4(0), _channelVolume(100), _fieldC(0), _repeated(false), _channel(10), _positioningMode(POSMODE_NONE), _azimuth(0.0), _range(0.5), _elevation(0), _posX(0.0), _posY(0.0), _posZ(0.0), _hasVelocity(false), _velocityX(0), _velocityY(0), _velocityZ(0), - _field54(0), _field58(0), _field5C(0), _field60(0), _endTalkerFn(nullptr), + _field54(0), _field58(0), _field5C(0), _freeSoundFlag(false), _endTalkerFn(nullptr), _talker(nullptr), _field6C(0) { } diff --git a/engines/titanic/sound/proximity.h b/engines/titanic/sound/proximity.h index 933598900d..b728f22c26 100644 --- a/engines/titanic/sound/proximity.h +++ b/engines/titanic/sound/proximity.h @@ -58,7 +58,7 @@ public: int _field54; int _field58; int _field5C; - int _field60; + bool _freeSoundFlag; CEndTalkerFn _endTalkerFn; TTtalker *_talker; int _field6C; diff --git a/engines/titanic/sound/qmixer.cpp b/engines/titanic/sound/qmixer.cpp index 32554a5659..145d142b2d 100644 --- a/engines/titanic/sound/qmixer.cpp +++ b/engines/titanic/sound/qmixer.cpp @@ -118,7 +118,7 @@ int QMixer::qsWaveMixPlayEx(int iChannel, uint flags, CWaveFile *waveFile, int l } // Add the sound to the channel - channel._sounds.push_back(SoundEntry(waveFile, params.callback, params.dwUser)); + channel._sounds.push_back(SoundEntry(waveFile, params.callback, loops, params.dwUser)); qsWaveMixPump(); return 0; @@ -138,9 +138,21 @@ void QMixer::qsWaveMixPump() { if (!channel._sounds.empty()) { SoundEntry &sound = channel._sounds.front(); if (sound._started && !_mixer->isSoundHandleActive(sound._soundHandle)) { - if (sound._callback) - sound._callback(iChannel, sound._waveFile, sound._userData); - channel._sounds.erase(channel._sounds.begin()); + if (sound._loops == -1 || sound._loops-- > 0) { + // Need to loop the sound again + sound._waveFile->_stream->rewind(); + _mixer->playStream(sound._waveFile->_soundType, + &sound._soundHandle, sound._waveFile->_stream, + -1, 0xff, 0, DisposeAfterUse::NO); + } else { + // Sound is finished + if (sound._callback) + // Call the callback to signal end + sound._callback(iChannel, sound._waveFile, sound._userData); + + // Remove sound record from channel + channel._sounds.erase(channel._sounds.begin()); + } } } @@ -150,7 +162,8 @@ void QMixer::qsWaveMixPump() { SoundEntry &sound = channel._sounds.front(); if (!sound._started) { _mixer->playStream(sound._waveFile->_soundType, - &sound._soundHandle, sound._waveFile->_stream); + &sound._soundHandle, sound._waveFile->_stream, + -1, 0xff, 0, DisposeAfterUse::NO); sound._started = true; } } diff --git a/engines/titanic/sound/qmixer.h b/engines/titanic/sound/qmixer.h index edb20b795c..4ba76a8969 100644 --- a/engines/titanic/sound/qmixer.h +++ b/engines/titanic/sound/qmixer.h @@ -177,12 +177,13 @@ class QMixer { CWaveFile *_waveFile; Audio::SoundHandle _soundHandle; LPQMIXDONECALLBACK _callback; + int _loops; void *_userData; SoundEntry() : _started(false), _waveFile(nullptr), _callback(nullptr), - _userData(nullptr) {} + _loops(0), _userData(nullptr) {} - SoundEntry(CWaveFile *waveFile, LPQMIXDONECALLBACK callback, void *userData) : - _started(false), _waveFile(waveFile), _callback(callback), _userData(userData) {} + SoundEntry(CWaveFile *waveFile, LPQMIXDONECALLBACK callback, int loops, void *userData) : + _started(false), _waveFile(waveFile), _callback(callback), _loops(loops), _userData(userData) {} }; struct ChannelEntry { Common::List _sounds; diff --git a/engines/titanic/sound/sound.cpp b/engines/titanic/sound/sound.cpp index d14c628a78..7e791c2ba5 100644 --- a/engines/titanic/sound/sound.cpp +++ b/engines/titanic/sound/sound.cpp @@ -68,8 +68,18 @@ void CSound::setVolume(uint handle, uint volume, uint seconds) { _soundManager.setVolume(handle, volume, seconds); } -void CSound::fn4(CWaveFile *waveFile, int val) { - // TODO +void CSound::activateSound(CWaveFile *waveFile, bool freeFlag) { + for (CSoundItemList::iterator i = _sounds.begin(); i != _sounds.end(); ++i) { + CSoundItem *sound = *i; + if (sound->_waveFile == waveFile) { + sound->_active = true; + sound->_freeFlag = freeFlag; + + if (!freeFlag && waveFile->size() > 51200) + sound->_freeFlag = true; + break; + } + } } void CSound::stopChannel(int channel) { @@ -79,7 +89,7 @@ void CSound::stopChannel(int channel) { void CSound::checkSounds() { for (CSoundItemList::iterator i = _sounds.begin(); i != _sounds.end(); ++i) { CSoundItem *soundItem = *i; - if (soundItem->_field24 && soundItem->_field28) { + if (soundItem->_active && soundItem->_freeFlag) { if (_soundManager.isActive(soundItem->_waveFile)) { _sounds.remove(soundItem); delete soundItem; @@ -92,7 +102,7 @@ void CSound::removeOldest() { for (CSoundItemList::iterator i = _sounds.reverse_begin(); i != _sounds.end(); --i) { CSoundItem *soundItem = *i; - if (soundItem->_field28 && !_soundManager.isActive(soundItem->_waveFile)) { + if (soundItem->_active && !_soundManager.isActive(soundItem->_waveFile)) { _sounds.remove(soundItem); delete soundItem; break; @@ -145,7 +155,7 @@ int CSound::playSound(const CString &name, CProximity &prox) { return -1; prox._field6C = waveFile->fn1(); - fn4(waveFile, prox._field60); + activateSound(waveFile, prox._freeSoundFlag); return _soundManager.playSound(*waveFile, prox); } @@ -192,7 +202,7 @@ int CSound::playSpeech(CDialogueFile *dialogueFile, int speechId, CProximity &pr return -1; prox._field6C = waveFile->fn1(); - fn4(waveFile, prox._field60); + activateSound(waveFile, prox._freeSoundFlag); return _soundManager.playSound(*waveFile, prox); } diff --git a/engines/titanic/sound/sound.h b/engines/titanic/sound/sound.h index b6c77e76b2..de95f9edf1 100644 --- a/engines/titanic/sound/sound.h +++ b/engines/titanic/sound/sound.h @@ -41,15 +41,15 @@ public: CWaveFile *_waveFile; File *_dialogueFileHandle; int _speechId; - int _field24; - int _field28; + bool _freeFlag; + bool _active; public: CSoundItem() : ListItem(), _waveFile(nullptr), _dialogueFileHandle(nullptr), - _speechId(0), _field24(0), _field28(0) {} + _speechId(0), _freeFlag(false), _active(false) {} CSoundItem(const CString &name) : ListItem(), _name(name), _waveFile(nullptr), - _dialogueFileHandle(nullptr), _speechId(0), _field24(0), _field28(0) {} + _dialogueFileHandle(nullptr), _speechId(0), _freeFlag(false), _active(false) {} CSoundItem(File *dialogueFile, int speechId) : ListItem(), _waveFile(nullptr), - _dialogueFileHandle(dialogueFile), _speechId(speechId), _field24(0), _field28(0) {} + _dialogueFileHandle(dialogueFile), _speechId(speechId), _freeFlag(false), _active(false) {} }; class CSoundItemList : public List { @@ -123,7 +123,10 @@ public: */ void setVolume(uint handle, uint volume, uint seconds); - void fn4(CWaveFile *waveFile, int val); + /** + * Flags a sound about to be played as activated + */ + void activateSound(CWaveFile *waveFile, bool freeFlag); /** * Stops any sounds attached to a given channel diff --git a/engines/titanic/sound/sound_manager.cpp b/engines/titanic/sound/sound_manager.cpp index 18ad9703ea..84d38ed2ab 100644 --- a/engines/titanic/sound/sound_manager.cpp +++ b/engines/titanic/sound/sound_manager.cpp @@ -32,7 +32,7 @@ CSoundManager::CSoundManager() : _musicPercent(75.0), _speechPercent(75.0), _masterPercent(75.0), _parrotPercent(75.0), _handleCtr(1) { } -uint CSoundManager::getModeVolume(int mode) { +double CSoundManager::getModeVolume(int mode) { switch (mode) { case -1: return _masterPercent; @@ -414,7 +414,7 @@ int QSoundManager::playWave(CWaveFile *waveFile, int iChannel, uint flags, CProx return slot._handle; } else { _sounds.flushChannel(waveFile, iChannel); - if (prox._field60) + if (prox._freeSoundFlag) delete waveFile; return 0; } diff --git a/engines/titanic/sound/sound_manager.h b/engines/titanic/sound/sound_manager.h index d1afdb4ad4..3dfba92e9c 100644 --- a/engines/titanic/sound/sound_manager.h +++ b/engines/titanic/sound/sound_manager.h @@ -214,7 +214,7 @@ public: /** * Gets the volume for a given mode? value */ - uint getModeVolume(int mode); + double getModeVolume(int mode); }; class QSoundManagerSound : public ListItem { diff --git a/engines/titanic/sound/wave_file.h b/engines/titanic/sound/wave_file.h index 8c86c509bc..aede0c9328 100644 --- a/engines/titanic/sound/wave_file.h +++ b/engines/titanic/sound/wave_file.h @@ -37,7 +37,7 @@ private: uint _size; public: QSoundManager *_owner; - Audio::AudioStream *_stream; + Audio::SeekableAudioStream *_stream; Audio::SoundHandle _soundHandle; Audio::Mixer::SoundType _soundType; public: -- cgit v1.2.3