From e8ad0f3b234c6d06576e802b478c59bad00898c0 Mon Sep 17 00:00:00 2001 From: Einar Johan Trøan Sømåen Date: Tue, 17 Jul 2012 18:42:30 +0200 Subject: WINTERMUTE: Revamp the sound-system, adding WAV-support and following the ScummVM-volume settings. --- engines/wintermute/Ad/AdObject.cpp | 2 +- engines/wintermute/Base/BFrame.cpp | 4 +- engines/wintermute/Base/BGame.cpp | 40 ++++---- engines/wintermute/Base/BObject.cpp | 10 +- engines/wintermute/Base/BRegistry.cpp | 44 ++++++++- engines/wintermute/Base/BSound.cpp | 17 +++- engines/wintermute/Base/BSound.h | 9 +- engines/wintermute/Base/BSoundBuffer.cpp | 86 +++++++++-------- engines/wintermute/Base/BSoundBuffer.h | 16 ++-- engines/wintermute/Base/BSoundMgr.cpp | 135 +++++++++------------------ engines/wintermute/Base/BSoundMgr.h | 16 ++-- engines/wintermute/dctypes.h | 6 -- engines/wintermute/video/VidTheoraPlayer.cpp | 2 +- 13 files changed, 200 insertions(+), 187 deletions(-) (limited to 'engines/wintermute') diff --git a/engines/wintermute/Ad/AdObject.cpp b/engines/wintermute/Ad/AdObject.cpp index 4dd6f4ce4b..2f536cd74a 100644 --- a/engines/wintermute/Ad/AdObject.cpp +++ b/engines/wintermute/Ad/AdObject.cpp @@ -862,7 +862,7 @@ void CAdObject::talk(const char *text, const char *sound, uint32 duration, const // load sound and set duration appropriately if (sound) { CBSound *snd = new CBSound(Game); - if (snd && DID_SUCCEED(snd->setSound(sound, SOUND_SPEECH, true))) { + if (snd && DID_SUCCEED(snd->setSound(sound, Audio::Mixer::kSpeechSoundType, true))) { _sentence->setSound(snd); if (_sentence->_duration <= 0) { uint32 Length = snd->getLength(); diff --git a/engines/wintermute/Base/BFrame.cpp b/engines/wintermute/Base/BFrame.cpp index a0d7d5a1e0..b57d2e41f3 100644 --- a/engines/wintermute/Base/BFrame.cpp +++ b/engines/wintermute/Base/BFrame.cpp @@ -251,7 +251,7 @@ ERRORCODE CBFrame::loadBuffer(byte *buffer, int lifeTime, bool keepLoaded) { _sound = NULL; } _sound = new CBSound(Game); - if (!_sound || DID_FAIL(_sound->setSound(params, SOUND_SFX, false))) { + if (!_sound || DID_FAIL(_sound->setSound(params, Audio::Mixer::kSFXSoundType, false))) { if (Game->_soundMgr->_soundAvailable) Game->LOG(0, "Error loading sound '%s'.", params); delete _sound; _sound = NULL; @@ -423,7 +423,7 @@ ERRORCODE CBFrame::scCallMethod(CScScript *script, CScStack *stack, CScStack *th if (!val->isNULL()) { _sound = new CBSound(Game); - if (!_sound || DID_FAIL(_sound->setSound(val->getString(), SOUND_SFX, false))) { + if (!_sound || DID_FAIL(_sound->setSound(val->getString(), Audio::Mixer::kSFXSoundType, false))) { stack->pushBool(false); delete _sound; _sound = NULL; diff --git a/engines/wintermute/Base/BGame.cpp b/engines/wintermute/Base/BGame.cpp index cd7dc07925..3a3aad50e6 100644 --- a/engines/wintermute/Base/BGame.cpp +++ b/engines/wintermute/Base/BGame.cpp @@ -1279,7 +1279,7 @@ ERRORCODE CBGame::scCallMethod(CScScript *script, CScStack *stack, CScStack *thi int volume = stack->pop()->getInt(); if (channel < 0 || channel >= NUM_MUSIC_CHANNELS || !_music[channel]) stack->pushBool(false); else { - if (DID_FAIL(_music[channel]->setVolume(volume))) stack->pushBool(false); + if (DID_FAIL(_music[channel]->setVolumePercent(volume))) stack->pushBool(false); else stack->pushBool(true); } return STATUS_OK; @@ -1297,7 +1297,7 @@ ERRORCODE CBGame::scCallMethod(CScScript *script, CScStack *stack, CScStack *thi } if (channel < 0 || channel >= NUM_MUSIC_CHANNELS || !_music[channel]) stack->pushInt(0); - else stack->pushInt(_music[channel]->getVolume()); + else stack->pushInt(_music[channel]->getVolumePercent()); return STATUS_OK; } @@ -1340,7 +1340,7 @@ ERRORCODE CBGame::scCallMethod(CScScript *script, CScStack *stack, CScStack *thi const char *filename = stack->pop()->getString(); CBSound *sound = new CBSound(Game); - if (sound && DID_SUCCEED(sound->setSound(filename, SOUND_MUSIC, true))) { + if (sound && DID_SUCCEED(sound->setSound(filename, Audio::Mixer::kMusicSoundType, true))) { length = sound->getLength(); delete sound; sound = NULL; @@ -1603,7 +1603,7 @@ ERRORCODE CBGame::scCallMethod(CScScript *script, CScStack *stack, CScStack *thi ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetGlobalSFXVolume") == 0) { stack->correctParams(1); - Game->_soundMgr->setVolumePercent(SOUND_SFX, (byte)stack->pop()->getInt()); + Game->_soundMgr->setVolumePercent(Audio::Mixer::kSFXSoundType, (byte)stack->pop()->getInt()); stack->pushNULL(); return STATUS_OK; } @@ -1613,7 +1613,7 @@ ERRORCODE CBGame::scCallMethod(CScScript *script, CScStack *stack, CScStack *thi ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetGlobalSpeechVolume") == 0) { stack->correctParams(1); - Game->_soundMgr->setVolumePercent(SOUND_SPEECH, (byte)stack->pop()->getInt()); + Game->_soundMgr->setVolumePercent(Audio::Mixer::kSpeechSoundType, (byte)stack->pop()->getInt()); stack->pushNULL(); return STATUS_OK; } @@ -1623,7 +1623,7 @@ ERRORCODE CBGame::scCallMethod(CScScript *script, CScStack *stack, CScStack *thi ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SetGlobalMusicVolume") == 0) { stack->correctParams(1); - Game->_soundMgr->setVolumePercent(SOUND_MUSIC, (byte)stack->pop()->getInt()); + Game->_soundMgr->setVolumePercent(Audio::Mixer::kMusicSoundType, (byte)stack->pop()->getInt()); stack->pushNULL(); return STATUS_OK; } @@ -1643,7 +1643,7 @@ ERRORCODE CBGame::scCallMethod(CScScript *script, CScStack *stack, CScStack *thi ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetGlobalSFXVolume") == 0) { stack->correctParams(0); - stack->pushInt(_soundMgr->getVolumePercent(SOUND_SFX)); + stack->pushInt(_soundMgr->getVolumePercent(Audio::Mixer::kSFXSoundType)); return STATUS_OK; } @@ -1652,7 +1652,7 @@ ERRORCODE CBGame::scCallMethod(CScScript *script, CScStack *stack, CScStack *thi ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetGlobalSpeechVolume") == 0) { stack->correctParams(0); - stack->pushInt(_soundMgr->getVolumePercent(SOUND_SPEECH)); + stack->pushInt(_soundMgr->getVolumePercent(Audio::Mixer::kSpeechSoundType)); return STATUS_OK; } @@ -1661,7 +1661,7 @@ ERRORCODE CBGame::scCallMethod(CScScript *script, CScStack *stack, CScStack *thi ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "GetGlobalMusicVolume") == 0) { stack->correctParams(0); - stack->pushInt(_soundMgr->getVolumePercent(SOUND_MUSIC)); + stack->pushInt(_soundMgr->getVolumePercent(Audio::Mixer::kMusicSoundType)); return STATUS_OK; } @@ -2302,7 +2302,7 @@ CScValue *CBGame::scGetProperty(const char *name) { ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SFXVolume") == 0) { Game->LOG(0, "**Warning** The SFXVolume attribute is obsolete"); - _scValue->setInt(_soundMgr->getVolumePercent(SOUND_SFX)); + _scValue->setInt(_soundMgr->getVolumePercent(Audio::Mixer::kSFXSoundType)); return _scValue; } @@ -2311,7 +2311,7 @@ CScValue *CBGame::scGetProperty(const char *name) { ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SpeechVolume") == 0) { Game->LOG(0, "**Warning** The SpeechVolume attribute is obsolete"); - _scValue->setInt(_soundMgr->getVolumePercent(SOUND_SPEECH)); + _scValue->setInt(_soundMgr->getVolumePercent(Audio::Mixer::kSpeechSoundType)); return _scValue; } @@ -2320,7 +2320,7 @@ CScValue *CBGame::scGetProperty(const char *name) { ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "MusicVolume") == 0) { Game->LOG(0, "**Warning** The MusicVolume attribute is obsolete"); - _scValue->setInt(_soundMgr->getVolumePercent(SOUND_MUSIC)); + _scValue->setInt(_soundMgr->getVolumePercent(Audio::Mixer::kMusicSoundType)); return _scValue; } @@ -2626,7 +2626,7 @@ ERRORCODE CBGame::scSetProperty(const char *name, CScValue *value) { ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SFXVolume") == 0) { Game->LOG(0, "**Warning** The SFXVolume attribute is obsolete"); - Game->_soundMgr->setVolumePercent(SOUND_SFX, (byte)value->getInt()); + Game->_soundMgr->setVolumePercent(Audio::Mixer::kSFXSoundType, (byte)value->getInt()); return STATUS_OK; } @@ -2635,7 +2635,7 @@ ERRORCODE CBGame::scSetProperty(const char *name, CScValue *value) { ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "SpeechVolume") == 0) { Game->LOG(0, "**Warning** The SpeechVolume attribute is obsolete"); - Game->_soundMgr->setVolumePercent(SOUND_SPEECH, (byte)value->getInt()); + Game->_soundMgr->setVolumePercent(Audio::Mixer::kSpeechSoundType, (byte)value->getInt()); return STATUS_OK; } @@ -2644,7 +2644,7 @@ ERRORCODE CBGame::scSetProperty(const char *name, CScValue *value) { ////////////////////////////////////////////////////////////////////////// else if (strcmp(name, "MusicVolume") == 0) { Game->LOG(0, "**Warning** The MusicVolume attribute is obsolete"); - Game->_soundMgr->setVolumePercent(SOUND_MUSIC, (byte)value->getInt()); + Game->_soundMgr->setVolumePercent(Audio::Mixer::kMusicSoundType, (byte)value->getInt()); return STATUS_OK; } @@ -3386,7 +3386,7 @@ ERRORCODE CBGame::playMusic(int channel, const char *filename, bool looping, uin _music[channel] = NULL; _music[channel] = new CBSound(Game); - if (_music[channel] && DID_SUCCEED(_music[channel]->setSound(filename, SOUND_MUSIC, true))) { + if (_music[channel] && DID_SUCCEED(_music[channel]->setSound(filename, Audio::Mixer::kMusicSoundType, true))) { if (_musicStartTime[channel]) { _music[channel]->setPositionTime(_musicStartTime[channel]); _musicStartTime[channel] = 0; @@ -4083,11 +4083,11 @@ ERRORCODE CBGame::updateMusicCrossfade() { if (currentTime >= _musicCrossfadeLength) { _musicCrossfadeRunning = false; //_music[_musicCrossfadeChannel2]->setVolume(GlobMusicVol); - _music[_musicCrossfadeChannel2]->setVolume(100); + _music[_musicCrossfadeChannel2]->setVolumePercent(100); _music[_musicCrossfadeChannel1]->stop(); //_music[_musicCrossfadeChannel1]->setVolume(GlobMusicVol); - _music[_musicCrossfadeChannel1]->setVolume(100); + _music[_musicCrossfadeChannel1]->setVolumePercent(100); if (_musicCrossfadeSwap) { @@ -4104,8 +4104,8 @@ ERRORCODE CBGame::updateMusicCrossfade() { } else { //_music[_musicCrossfadeChannel1]->setVolume(GlobMusicVol - (float)CurrentTime / (float)_musicCrossfadeLength * GlobMusicVol); //_music[_musicCrossfadeChannel2]->setVolume((float)CurrentTime / (float)_musicCrossfadeLength * GlobMusicVol); - _music[_musicCrossfadeChannel1]->setVolume((int)(100.0f - (float)currentTime / (float)_musicCrossfadeLength * 100.0f)); - _music[_musicCrossfadeChannel2]->setVolume((int)((float)currentTime / (float)_musicCrossfadeLength * 100.0f)); + _music[_musicCrossfadeChannel1]->setVolumePercent((int)(100.0f - (float)currentTime / (float)_musicCrossfadeLength * 100.0f)); + _music[_musicCrossfadeChannel2]->setVolumePercent((int)((float)currentTime / (float)_musicCrossfadeLength * 100.0f)); //Game->QuickMessageForm("%d %d", _music[_musicCrossfadeChannel1]->GetVolume(), _music[_musicCrossfadeChannel2]->GetVolume()); } diff --git a/engines/wintermute/Base/BObject.cpp b/engines/wintermute/Base/BObject.cpp index abced32767..60a9fe7f32 100644 --- a/engines/wintermute/Base/BObject.cpp +++ b/engines/wintermute/Base/BObject.cpp @@ -423,7 +423,7 @@ ERRORCODE CBObject::scCallMethod(CScScript *script, CScStack *stack, CScStack *t stack->correctParams(0); if (!_sFX) stack->pushInt(_sFXVolume); - else stack->pushInt(_sFX->getVolume()); + else stack->pushInt(_sFX->getVolumePercent()); return STATUS_OK; } @@ -982,7 +982,7 @@ ERRORCODE CBObject::playSFX(const char *filename, bool looping, bool playNow, co // just play loaded sound if (filename == NULL && _sFX) { if (Game->_editorMode || _sFXStart) { - _sFX->setVolume(_sFXVolume); + _sFX->setVolumePercent(_sFXVolume); _sFX->setPositionTime(_sFXStart); if (!Game->_editorMode) _sFXStart = 0; } @@ -999,8 +999,8 @@ ERRORCODE CBObject::playSFX(const char *filename, bool looping, bool playNow, co delete _sFX; _sFX = new CBSound(Game); - if (_sFX && DID_SUCCEED(_sFX->setSound(filename, SOUND_SFX, true))) { - _sFX->setVolume(_sFXVolume); + if (_sFX && DID_SUCCEED(_sFX->setSound(filename, Audio::Mixer::kSFXSoundType, true))) { + _sFX->setVolumePercent(_sFXVolume); if (_sFXStart) { _sFX->setPositionTime(_sFXStart); _sFXStart = 0; @@ -1057,7 +1057,7 @@ ERRORCODE CBObject::setSFXTime(uint32 time) { ////////////////////////////////////////////////////////////////////////// ERRORCODE CBObject::setSFXVolume(int volume) { _sFXVolume = volume; - if (_sFX) return _sFX->setVolume(volume); + if (_sFX) return _sFX->setVolumePercent(volume); else return STATUS_OK; } diff --git a/engines/wintermute/Base/BRegistry.cpp b/engines/wintermute/Base/BRegistry.cpp index 6d73ac73ac..b8520b07fd 100644 --- a/engines/wintermute/Base/BRegistry.cpp +++ b/engines/wintermute/Base/BRegistry.cpp @@ -32,7 +32,7 @@ #include "engines/wintermute/utils/PathUtil.h" #include "engines/wintermute/utils/StringUtil.h" #include "engines/wintermute/utils/utils.h" - +#include "common/config-manager.h" #include "common/file.h" namespace WinterMute { @@ -77,6 +77,33 @@ bool CBRegistry::writeString(const AnsiString &subKey, const AnsiString &key, co ////////////////////////////////////////////////////////////////////////// int CBRegistry::readInt(const AnsiString &subKey, const AnsiString &key, int init) { + if (subKey == "Audio") { + if (key == "MasterVolume") { + if (ConfMan.hasKey("master_volume")) { + return ConfMan.getInt("master_volume"); + } else { + return init; + } + } else if (key == "SFXVolume") { + if (ConfMan.hasKey("sfx_volume")) { + error("This key shouldn't be read by the scripts"); + } else { + return init; + } + } else if (key == "SpeechVolume") { + if (ConfMan.hasKey("speech_volume")) { + error("This key shouldn't be read by the scripts"); + } else { + return init; + } + } else if (key == "MusicVolume") { + if (ConfMan.hasKey("music_volume")) { + error("This key shouldn't be read by the scripts"); + } else { + return init; + } + } + } AnsiString val = readString(subKey, key, ""); if (val.empty()) return init; else return atoi(val.c_str()); @@ -85,6 +112,21 @@ int CBRegistry::readInt(const AnsiString &subKey, const AnsiString &key, int ini ////////////////////////////////////////////////////////////////////////// bool CBRegistry::writeInt(const AnsiString &subKey, const AnsiString &key, int value) { + if (subKey == "Audio") { + if (key == "MasterVolume") { + ConfMan.setInt("master_volume", value); + return true; + } else if (key == "SFXVolume") { + error("This key shouldn't be read by the scripts"); + return true; + } else if (key == "SpeechVolume") { + error("This key shouldn't be read by the scripts"); + return true; + } else if (key == "MusicVolume") { + error("This key shouldn't be read by the scripts"); + return true; + } + } writeString(subKey, key, StringUtil::toString(value)); return true; } diff --git a/engines/wintermute/Base/BSound.cpp b/engines/wintermute/Base/BSound.cpp index b4536e7f9e..c5fdb11ade 100644 --- a/engines/wintermute/Base/BSound.cpp +++ b/engines/wintermute/Base/BSound.cpp @@ -29,6 +29,7 @@ #include "engines/wintermute/Base/BSound.h" #include "engines/wintermute/Base/BGame.h" #include "engines/wintermute/Base/BSoundMgr.h" +#include "engines/wintermute/Base/BSoundBuffer.h" namespace WinterMute { @@ -39,7 +40,7 @@ CBSound::CBSound(CBGame *inGame): CBBase(inGame) { _sound = NULL; _soundFilename = NULL; - _soundType = SOUND_SFX; + _soundType = Audio::Mixer::kSFXSoundType; _soundStreamed = false; _soundLooping = false; _soundPlaying = false; @@ -65,7 +66,7 @@ CBSound::~CBSound() { ////////////////////////////////////////////////////////////////////////// -ERRORCODE CBSound::setSound(const char *filename, TSoundType type, bool streamed) { +ERRORCODE CBSound::setSound(const char *filename, Audio::Mixer::SoundType type, bool streamed) { if (_sound) { Game->_soundMgr->removeSound(_sound); _sound = NULL; @@ -212,6 +213,12 @@ uint32 CBSound::getPositionTime() { else return _sound->getPosition(); } +////////////////////////////////////////////////////////////////////////// +ERRORCODE CBSound::setVolumePercent(int percent) { + if (!_sound) + return STATUS_FAILED; + else return _sound->setPrivateVolume(percent * 255 / 100); +} ////////////////////////////////////////////////////////////////////////// ERRORCODE CBSound::setVolume(int volume) { @@ -227,6 +234,12 @@ ERRORCODE CBSound::setPrivateVolume(int volume) { else return _sound->_privateVolume = volume; } +////////////////////////////////////////////////////////////////////////// +int CBSound::getVolumePercent() { + if (!_sound) + return 0; + else return _sound->_privateVolume * 100 / 255; +} ////////////////////////////////////////////////////////////////////////// int CBSound::getVolume() { diff --git a/engines/wintermute/Base/BSound.h b/engines/wintermute/Base/BSound.h index dd08e32b54..3dc9dadf68 100644 --- a/engines/wintermute/Base/BSound.h +++ b/engines/wintermute/Base/BSound.h @@ -31,16 +31,19 @@ #include "engines/wintermute/Base/BBase.h" #include "engines/wintermute/dctypes.h" // Added by ClassView -#include "engines/wintermute/Base/BSoundBuffer.h" #include "engines/wintermute/persistent.h" +#include "audio/mixer.h" namespace WinterMute { +class CBSoundBuffer; class CBSound : public CBBase { public: ERRORCODE setPan(float pan); int _soundPrivateVolume; int getVolume(); + int getVolumePercent(); + ERRORCODE setVolumePercent(int percent); ERRORCODE setVolume(int volume); ERRORCODE setPrivateVolume(int volume); ERRORCODE setLoopStart(uint32 pos); @@ -61,10 +64,10 @@ public: ERRORCODE play(bool looping = false); uint32 getLength(); bool _soundStreamed; - TSoundType _soundType; + Audio::Mixer::SoundType _soundType; char *_soundFilename; ERRORCODE setSoundSimple(); - ERRORCODE setSound(const char *filename, TSoundType type = SOUND_SFX, bool streamed = false); + ERRORCODE setSound(const char *filename, Audio::Mixer::SoundType type = Audio::Mixer::kSFXSoundType, bool streamed = false); CBSound(CBGame *inGame); virtual ~CBSound(); diff --git a/engines/wintermute/Base/BSoundBuffer.cpp b/engines/wintermute/Base/BSoundBuffer.cpp index 1bdb0f3adc..2448451784 100644 --- a/engines/wintermute/Base/BSoundBuffer.cpp +++ b/engines/wintermute/Base/BSoundBuffer.cpp @@ -37,7 +37,9 @@ #include "audio/mixer.h" #include "audio/decoders/vorbis.h" #include "audio/decoders/wave.h" +#include "audio/decoders/raw.h" #include "common/system.h" +#include "common/substream.h" namespace WinterMute { @@ -50,18 +52,19 @@ namespace WinterMute { ////////////////////////////////////////////////////////////////////////// CBSoundBuffer::CBSoundBuffer(CBGame *inGame): CBBase(inGame) { _stream = NULL; - _handle = new Audio::SoundHandle; + _handle = NULL; // _sync = NULL; _streamed = false; _filename = NULL; _file = NULL; - _privateVolume = 100; + _privateVolume = 255; + _volume = 255; _looping = false; _loopStart = 0; - _type = SOUND_SFX; + _type = Audio::Mixer::kSFXSoundType; _freezePaused = false; } @@ -72,14 +75,12 @@ CBSoundBuffer::~CBSoundBuffer() { stop(); if (_handle) { + g_system->getMixer()->stopHandle(*_handle); delete _handle; _handle = NULL; } - - if (_file) { - Game->_fileManager->closeFile(_file); - _file = NULL; - } + delete _stream; + _stream = NULL; delete[] _filename; _filename = NULL; @@ -101,8 +102,6 @@ ERRORCODE CBSoundBuffer::loadFromFile(const char *filename, bool forceReload) { _stream = NULL; } #endif - // If we already had a file, delete it. - delete _file; // Load a file, but avoid having the File-manager handle the disposal of it. _file = Game->_fileManager->openFile(filename, true, false); @@ -114,8 +113,19 @@ ERRORCODE CBSoundBuffer::loadFromFile(const char *filename, bool forceReload) { if (strFilename.hasSuffix(".ogg")) { _stream = Audio::makeVorbisStream(_file, DisposeAfterUse::YES); } else if (strFilename.hasSuffix(".wav")) { - warning("BSoundBuffer::LoadFromFile - WAVE not supported yet for %s", filename); - //_stream = Audio::makeWAVStream(_file, DisposeAfterUse::NO); + int waveSize, waveRate; + byte waveFlags; + uint16 waveType; + + if (Audio::loadWAVFromStream(*_file, waveSize, waveRate, waveFlags, &waveType)) { + if (waveType == 1) { + // We need to wrap the file in a substream to make sure the size is right. + _file = new Common::SeekableSubReadStream(_file, 0, waveSize); + _stream = Audio::makeRawStream(_file, waveRate, waveFlags, DisposeAfterUse::YES); + } else { + warning("BSoundBuffer::LoadFromFile - WAVE not supported yet for %s with type %d", filename, waveType); + } + } } else { warning("BSoundBuffer::LoadFromFile - Unknown filetype for %s", filename); } @@ -190,22 +200,31 @@ ERRORCODE CBSoundBuffer::play(bool looping, uint32 startSample) { if (startSample != 0) { warning("BSoundBuffer::Play - Should start playback at %d, but currently we don't", startSample); } + if (_handle) { + g_system->getMixer()->stopHandle(*_handle); + delete _handle; + _handle = NULL; + } if (_stream) { + _stream->seek(startSample); + _handle = new Audio::SoundHandle; if (looping) { - Audio::AudioStream *loopStream = new Audio::LoopingAudioStream(_stream, 0, DisposeAfterUse::YES); - g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, _handle, loopStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::YES); + Audio::AudioStream *loopStream = new Audio::LoopingAudioStream(_stream, 0, DisposeAfterUse::NO); + g_system->getMixer()->playStream(_type, _handle, loopStream, -1, _volume, 0, DisposeAfterUse::YES); } else { - g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, _handle, _stream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::YES); + g_system->getMixer()->playStream(_type, _handle, _stream, -1, _volume, 0, DisposeAfterUse::NO); } - } + } + return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// void CBSoundBuffer::setLooping(bool looping) { - warning("BSoundBuffer::SetLooping(%d) - not implemented yet", looping); -#if 0 + warning("BSoundBuffer::SetLooping(%d) - won't change a playing sound", looping); _looping = looping; +#if 0 + if (_stream) { BASS_ChannelFlags(_stream, looping ? BASS_SAMPLE_LOOP : 0, BASS_SAMPLE_LOOP); @@ -251,15 +270,20 @@ uint32 CBSoundBuffer::getLength() { ////////////////////////////////////////////////////////////////////////// -void CBSoundBuffer::setType(TSoundType type) { +void CBSoundBuffer::setType(Audio::Mixer::SoundType type) { _type = type; } +////////////////////////////////////////////////////////////////////////// +void CBSoundBuffer::updateVolume() { + setVolume(_privateVolume); +} ////////////////////////////////////////////////////////////////////////// ERRORCODE CBSoundBuffer::setVolume(int volume) { + _volume = volume * Game->_soundMgr->getMasterVolume() / 255; if (_stream && _handle) { - byte vol = (byte)(volume / 100.f * Audio::Mixer::kMaxChannelVolume); + byte vol = (byte)(_volume); g_system->getMixer()->setChannelVolume(*_handle, vol); } return STATUS_OK; @@ -268,22 +292,8 @@ ERRORCODE CBSoundBuffer::setVolume(int volume) { ////////////////////////////////////////////////////////////////////////// ERRORCODE CBSoundBuffer::setPrivateVolume(int volume) { -#if 0 - _privateVolume = Volume; - - switch (_type) { - case SOUND_SFX: - volume = Game->_soundMgr->_volumeSFX; - break; - case SOUND_SPEECH: - volume = Game->_soundMgr->_volumeSpeech; - break; - case SOUND_MUSIC: - volume = Game->_soundMgr->_volumeMusic; - break; - } -#endif - return setVolume(volume); + _privateVolume = volume; + return setVolume(_privateVolume); } @@ -348,7 +358,7 @@ void CBSoundBuffer::LoopSyncProc(HSYNC handle, uint32 channel, uint32 data, void #endif ////////////////////////////////////////////////////////////////////////// ERRORCODE CBSoundBuffer::setPan(float pan) { - if (_stream) { + if (_handle) { g_system->getMixer()->setChannelBalance(*_handle, (int8)(pan * 127)); } return STATUS_OK; @@ -357,7 +367,6 @@ ERRORCODE CBSoundBuffer::setPan(float pan) { ////////////////////////////////////////////////////////////////////////// ERRORCODE CBSoundBuffer::applyFX(TSFXType type, float param1, float param2, float param3, float param4) { warning("CBSoundBuffer::ApplyFX - not implemented yet"); -#if 0 switch (type) { case SFX_ECHO: break; @@ -368,7 +377,6 @@ ERRORCODE CBSoundBuffer::applyFX(TSFXType type, float param1, float param2, floa default: break; } -#endif return STATUS_OK; } diff --git a/engines/wintermute/Base/BSoundBuffer.h b/engines/wintermute/Base/BSoundBuffer.h index 22c4fd63da..f65ea1d40f 100644 --- a/engines/wintermute/Base/BSoundBuffer.h +++ b/engines/wintermute/Base/BSoundBuffer.h @@ -31,6 +31,7 @@ #include "engines/wintermute/Base/BBase.h" +#include "audio/mixer.h" #include "common/stream.h" namespace Audio { @@ -68,8 +69,9 @@ public: ERRORCODE setPan(float pan); ERRORCODE setPrivateVolume(int colume); ERRORCODE setVolume(int colume); + void updateVolume(); - void setType(TSoundType Type); + void setType(Audio::Mixer::SoundType Type); ERRORCODE loadFromFile(const char *filename, bool forceReload = false); void setStreaming(bool streamed, uint32 numBlocks = 0, uint32 blockSize = 0); @@ -82,19 +84,15 @@ public: bool _freezePaused; uint32 _loopStart; - TSoundType _type; + Audio::Mixer::SoundType _type; bool _looping; Common::SeekableReadStream *_file; char *_filename; bool _streamed; - int _privateVolume; - - /*static void CALLBACK LoopSyncProc(HSYNC handle, uint32 channel, uint32 data, void *user); - static void CALLBACK FileCloseProc(void *user); - static QWORD CALLBACK FileLenProc(void *user); - static uint32 CALLBACK FileReadProc(void *buffer, uint32 length, void *user); - static BOOL CALLBACK FileSeekProc(QWORD offset, void *user);*/ + int _privateVolume; +private: + int _volume; }; } // end of namespace WinterMute diff --git a/engines/wintermute/Base/BSoundMgr.cpp b/engines/wintermute/Base/BSoundMgr.cpp index b8393bc0f2..6346971c54 100644 --- a/engines/wintermute/Base/BSoundMgr.cpp +++ b/engines/wintermute/Base/BSoundMgr.cpp @@ -34,6 +34,9 @@ #include "engines/wintermute/Base/BGame.h" #include "engines/wintermute/Base/BFileManager.h" #include "engines/wintermute/Base/BSoundBuffer.h" +#include "engines/wintermute/wintermute.h" +#include "common/config-manager.h" +#include "audio/mixer.h" namespace WinterMute { @@ -46,8 +49,7 @@ namespace WinterMute { ////////////////////////////////////////////////////////////////////////// CBSoundMgr::CBSoundMgr(CBGame *inGame): CBBase(inGame) { _soundAvailable = false; - - _volumeSFX = _volumeSpeech = _volumeMusic = _volumeMaster = 100; + _volumeMaster = 255; } @@ -73,43 +75,18 @@ ERRORCODE CBSoundMgr::cleanup() { void CBSoundMgr::saveSettings() { if (_soundAvailable) { Game->_registry->writeInt("Audio", "MasterVolume", _volumeMaster); - - Game->_registry->writeInt("Audio", "SFXVolume", _volumeSFX); - Game->_registry->writeInt("Audio", "SpeechVolume", _volumeSpeech); - Game->_registry->writeInt("Audio", "MusicVolume", _volumeMusic); } } ////////////////////////////////////////////////////////////////////////// ERRORCODE CBSoundMgr::initialize() { _soundAvailable = false; -#if 0 - -#ifdef __IPHONEOS__ -#define BASS_CONFIG_IOS_MIXAUDIO 34 - BASS_SetConfig(BASS_CONFIG_IOS_MIXAUDIO, 0); -#endif - - - if (HIWORD(BASS_GetVersion()) != BASSVERSION) { - Game->LOG(0, "An incorrect version of BASS was loaded"); + + if (!g_system->getMixer()->isReady()) { return STATUS_FAILED; } - - if (!BASS_Init(-1, 44100, 0, 0, NULL)) { - Game->LOG(0, "Can't initialize sound device"); - return STATUS_FAILED; - } -#endif - - _volumeMaster = Game->_registry->readInt("Audio", "MasterVolume", 100); - - _volumeSFX = Game->_registry->readInt("Audio", "SFXVolume", 100); - _volumeSpeech = Game->_registry->readInt("Audio", "SpeechVolume", 100); - _volumeMusic = Game->_registry->readInt("Audio", "MusicVolume", 100); - + _volumeMaster = Game->_registry->readInt("Audio", "MasterVolume", 255); _soundAvailable = true; - setMasterVolumePercent(_volumeMaster); return STATUS_OK; } @@ -128,7 +105,7 @@ ERRORCODE CBSoundMgr::initLoop() { ////////////////////////////////////////////////////////////////////////// -CBSoundBuffer *CBSoundMgr::addSound(const char *filename, TSoundType type, bool streamed) { +CBSoundBuffer *CBSoundMgr::addSound(const char *filename, Audio::Mixer::SoundType type, bool streamed) { if (!_soundAvailable) return NULL; @@ -160,18 +137,8 @@ CBSoundBuffer *CBSoundMgr::addSound(const char *filename, TSoundType type, bool return NULL; } - // set volume appropriately - switch (type) { - case SOUND_SFX: - sound->setVolume(_volumeSFX); - break; - case SOUND_SPEECH: - sound->setVolume(_volumeSpeech); - break; - case SOUND_MUSIC: - sound->setVolume(_volumeMusic); - break; - } + // Make sure the master-volume is applied to the sound. + sound->updateVolume(); // register sound _sounds.add(sound); @@ -182,22 +149,12 @@ CBSoundBuffer *CBSoundMgr::addSound(const char *filename, TSoundType type, bool } ////////////////////////////////////////////////////////////////////////// -ERRORCODE CBSoundMgr::addSound(CBSoundBuffer *sound, TSoundType type) { +ERRORCODE CBSoundMgr::addSound(CBSoundBuffer *sound, Audio::Mixer::SoundType type) { if (!sound) return STATUS_FAILED; - // set volume appropriately - switch (type) { - case SOUND_SFX: - sound->setVolume(_volumeSFX); - break; - case SOUND_SPEECH: - sound->setVolume(_volumeSpeech); - break; - case SOUND_MUSIC: - sound->setVolume(_volumeMusic); - break; - } + // Make sure the master-volume is applied to the sound. + sound->updateVolume(); // register sound _sounds.add(sound); @@ -220,83 +177,81 @@ ERRORCODE CBSoundMgr::removeSound(CBSoundBuffer *sound) { ////////////////////////////////////////////////////////////////////////// -ERRORCODE CBSoundMgr::setVolume(TSoundType type, int volume) { +ERRORCODE CBSoundMgr::setVolume(Audio::Mixer::SoundType type, int volume) { if (!_soundAvailable) return STATUS_OK; switch (type) { - case SOUND_SFX: - _volumeSFX = volume; + case Audio::Mixer::kSFXSoundType: + ConfMan.setInt("sfx_volume", volume); break; - case SOUND_SPEECH: - _volumeSpeech = volume; + case Audio::Mixer::kSpeechSoundType: + ConfMan.setInt("speech_volume", volume); break; - case SOUND_MUSIC: - _volumeMusic = volume; + case Audio::Mixer::kMusicSoundType: + ConfMan.setInt("music_volume", volume); break; } - - for (int i = 0; i < _sounds.getSize(); i++) { - if (_sounds[i]->_type == type) _sounds[i]->setVolume(volume); - } + g_wintermute->syncSoundSettings(); return STATUS_OK; } ////////////////////////////////////////////////////////////////////////// -ERRORCODE CBSoundMgr::setVolumePercent(TSoundType type, byte percent) { - return setVolume(type, percent); +ERRORCODE CBSoundMgr::setVolumePercent(Audio::Mixer::SoundType type, byte percent) { + return setVolume(type, percent * 255 / 100); } ////////////////////////////////////////////////////////////////////////// -byte CBSoundMgr::getVolumePercent(TSoundType type) { +byte CBSoundMgr::getVolumePercent(Audio::Mixer::SoundType type) { int volume = 0; + switch (type) { - case SOUND_SFX: - volume = _volumeSFX; - break; - case SOUND_SPEECH: - volume = _volumeSpeech; - break; - case SOUND_MUSIC: - volume = _volumeMusic; + case Audio::Mixer::kSFXSoundType: + case Audio::Mixer::kSpeechSoundType: + case Audio::Mixer::kMusicSoundType: + volume = g_system->getMixer()->getVolumeForSoundType(type); break; default: error("Sound-type not set"); break; } - return (byte)volume; + return (byte)(volume * 100 / 255); } +////////////////////////////////////////////////////////////////////////// +ERRORCODE CBSoundMgr::setMasterVolume(byte value) { + _volumeMaster = value; + for (int i = 0; i < _sounds.getSize(); i++) { + _sounds[i]->updateVolume(); + } +} + ////////////////////////////////////////////////////////////////////////// ERRORCODE CBSoundMgr::setMasterVolumePercent(byte percent) { - _volumeMaster = percent; -#if 0 - BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, (uint32)(10000.0f / 100.0f * (float)Percent)); -#endif - return STATUS_OK; + setMasterVolume(percent * 255 / 100); } ////////////////////////////////////////////////////////////////////////// byte CBSoundMgr::getMasterVolumePercent() { -#if 0 - uint32 val = BASS_GetConfig(BASS_CONFIG_GVOL_STREAM); - return (float)val / 10000.0f * 100.0f; -#endif - return 0; + return getMasterVolume() * 100 / 255; } +////////////////////////////////////////////////////////////////////////// +byte CBSoundMgr::getMasterVolume() { + return _volumeMaster; +} ////////////////////////////////////////////////////////////////////////// ERRORCODE CBSoundMgr::pauseAll(bool includingMusic) { for (int i = 0; i < _sounds.getSize(); i++) { - if (_sounds[i]->isPlaying() && (_sounds[i]->_type != SOUND_MUSIC || includingMusic)) { + if (_sounds[i]->isPlaying() && (_sounds[i]->_type != Audio::Mixer::kMusicSoundType || includingMusic)) { _sounds[i]->pause(); _sounds[i]->_freezePaused = true; } diff --git a/engines/wintermute/Base/BSoundMgr.h b/engines/wintermute/Base/BSoundMgr.h index 9e8106e973..1ae7b7709a 100644 --- a/engines/wintermute/Base/BSoundMgr.h +++ b/engines/wintermute/Base/BSoundMgr.h @@ -31,6 +31,7 @@ #include "engines/wintermute/coll_templ.h" #include "engines/wintermute/Base/BBase.h" +#include "audio/mixer.h" namespace WinterMute { class CBSoundBuffer; @@ -42,18 +43,17 @@ public: ERRORCODE cleanup(); //DECLARE_PERSISTENT(CBSoundMgr, CBBase); byte getMasterVolumePercent(); + byte getMasterVolume(); + ERRORCODE setMasterVolume(byte percent); ERRORCODE setMasterVolumePercent(byte percent); - byte getVolumePercent(TSoundType type); - ERRORCODE setVolumePercent(TSoundType type, byte percent); - ERRORCODE setVolume(TSoundType type, int volume); + byte getVolumePercent(Audio::Mixer::SoundType type); + ERRORCODE setVolumePercent(Audio::Mixer::SoundType type, byte percent); + ERRORCODE setVolume(Audio::Mixer::SoundType type, int volume); uint32 _volumeOriginal; int _volumeMaster; - int _volumeMusic; - int _volumeSpeech; - int _volumeSFX; ERRORCODE removeSound(CBSoundBuffer *sound); - CBSoundBuffer *addSound(const char *filename, TSoundType type = SOUND_SFX, bool streamed = false); - ERRORCODE addSound(CBSoundBuffer *sound, TSoundType type = SOUND_SFX); + CBSoundBuffer *addSound(const char *filename, Audio::Mixer::SoundType type = Audio::Mixer::kSFXSoundType, bool streamed = false); + ERRORCODE addSound(CBSoundBuffer *sound, Audio::Mixer::SoundType type = Audio::Mixer::kSFXSoundType); ERRORCODE initLoop(); ERRORCODE initialize(); bool _soundAvailable; diff --git a/engines/wintermute/dctypes.h b/engines/wintermute/dctypes.h index 988f865f21..1dde068013 100644 --- a/engines/wintermute/dctypes.h +++ b/engines/wintermute/dctypes.h @@ -140,12 +140,6 @@ enum TSeek { SEEK_TO_END = SEEK_END }; -enum TSoundType { - SOUND_SFX, - SOUND_MUSIC, - SOUND_SPEECH -}; - enum TVideoMode { VIDEO_WINDOW, VIDEO_FULLSCREEN, diff --git a/engines/wintermute/video/VidTheoraPlayer.cpp b/engines/wintermute/video/VidTheoraPlayer.cpp index 99acdc24e4..0250aac5b2 100644 --- a/engines/wintermute/video/VidTheoraPlayer.cpp +++ b/engines/wintermute/video/VidTheoraPlayer.cpp @@ -351,7 +351,7 @@ ERRORCODE CVidTheoraPlayer::play(TVideoPlayback type, int x, int y, bool freezeG if (forceZoom < 0.0f) forceZoom = 100.0f; if (volume < 0) - _volume = Game->_soundMgr->getVolumePercent(SOUND_SFX); + _volume = Game->_soundMgr->getVolumePercent(Audio::Mixer::kSFXSoundType); else _volume = volume; _freezeGame = freezeGame; -- cgit v1.2.3