diff options
author | Paul Gilbert | 2017-02-09 21:18:13 -0500 |
---|---|---|
committer | Paul Gilbert | 2017-02-09 21:18:13 -0500 |
commit | 6618af29fa64857227af18bf4bfc8020106920ba (patch) | |
tree | 2f6ce60b69459d7c418641bc188cb6dcbc818319 /engines/titanic/sound | |
parent | c2b3abd676a194138849252a3e37d6cb977a343c (diff) | |
download | scummvm-rg350-6618af29fa64857227af18bf4bfc8020106920ba.tar.gz scummvm-rg350-6618af29fa64857227af18bf4bfc8020106920ba.tar.bz2 scummvm-rg350-6618af29fa64857227af18bf4bfc8020106920ba.zip |
TITANIC: Refactor CWaveFile audio stream generation
Wave files need to handle both stand-alone playback via an audio stream,
as well as reading the raw data when merging instrument fragments in
the music room.
Diffstat (limited to 'engines/titanic/sound')
-rw-r--r-- | engines/titanic/sound/qmixer.cpp | 6 | ||||
-rw-r--r-- | engines/titanic/sound/wave_file.cpp | 74 | ||||
-rw-r--r-- | engines/titanic/sound/wave_file.h | 28 |
3 files changed, 72 insertions, 36 deletions
diff --git a/engines/titanic/sound/qmixer.cpp b/engines/titanic/sound/qmixer.cpp index 1854260f54..9ff6834efc 100644 --- a/engines/titanic/sound/qmixer.cpp +++ b/engines/titanic/sound/qmixer.cpp @@ -204,9 +204,9 @@ void QMixer::qsWaveMixPump() { if (sound._started && !_mixer->isSoundHandleActive(sound._soundHandle)) { if (sound._loops == -1 || sound._loops-- > 0) { // Need to loop the sound again - sound._waveFile->_audioStream->rewind(); + sound._waveFile->audioStream()->rewind(); _mixer->playStream(sound._waveFile->_soundType, - &sound._soundHandle, sound._waveFile->_audioStream, + &sound._soundHandle, sound._waveFile->audioStream(), -1, channel.getRawVolume(), 0, DisposeAfterUse::NO); } else { // Sound is finished @@ -230,7 +230,7 @@ void QMixer::qsWaveMixPump() { // Calculate an effective volume based on distance of source _mixer->playStream(sound._waveFile->_soundType, - &sound._soundHandle, sound._waveFile->_audioStream, + &sound._soundHandle, sound._waveFile->audioStream(), -1, channel.getRawVolume(), 0, DisposeAfterUse::NO); sound._started = true; } diff --git a/engines/titanic/sound/wave_file.cpp b/engines/titanic/sound/wave_file.cpp index 04800b6157..bc29ed037c 100644 --- a/engines/titanic/sound/wave_file.cpp +++ b/engines/titanic/sound/wave_file.cpp @@ -28,14 +28,14 @@ namespace Titanic { -#define WAV_DATA_OFFSET 0x46 - CWaveFile::CWaveFile() : _soundManager(nullptr), _audioStream(nullptr), - _rawData(nullptr), _soundType(Audio::Mixer::kPlainSoundType) { + _waveData(nullptr), _waveSize(0), _dataSize(0), + _soundType(Audio::Mixer::kPlainSoundType) { setup(); } CWaveFile::CWaveFile(QSoundManager *owner) : _soundManager(owner), _audioStream(nullptr), + _waveData(nullptr), _waveSize(0), _dataSize(0), _soundType(Audio::Mixer::kPlainSoundType) { setup(); } @@ -58,6 +58,8 @@ CWaveFile::~CWaveFile() { if (_disposeAudioBuffer == DisposeAfterUse::YES && _audioBuffer) delete _audioBuffer; + + delete[] _waveData; } uint CWaveFile::getDurationTicks() const { @@ -68,8 +70,7 @@ uint CWaveFile::getDurationTicks() const { // a desired size. Since I have no idea how the system API // method works, for now I'm using a simple ratio of a // sample output to input value - uint dataSize = _dataSize - WAV_DATA_OFFSET; - double newSize = (double)dataSize * (1475712.0 / 199836.0); + double newSize = (double)_dataSize * (1475712.0 / 199836.0); return (uint)(newSize * 1000.0 / _audioStream->getRate()); } @@ -81,17 +82,12 @@ bool CWaveFile::loadSound(const CString &name) { return false; Common::SeekableReadStream *stream = file.readStream(); - uint dataSize = stream->size(); - _dataSize = dataSize - 44; - - _rawData = new byte[dataSize]; - stream->read(_rawData, dataSize); - - _audioStream = Audio::makeWAVStream( - new Common::MemoryReadStream(_rawData, dataSize, DisposeAfterUse::YES), - DisposeAfterUse::YES); - _soundType = Audio::Mixer::kSFXSoundType; + uint size = stream->size(); + byte *data = new byte[size]; + stream->read(data, size); + load(data, size); + _soundType = Audio::Mixer::kSFXSoundType; return true; } @@ -102,12 +98,9 @@ bool CWaveFile::loadSpeech(CDialogueFile *dialogueFile, int speechIndex) { byte *data = (byte *)malloc(res->_size); dialogueFile->read(res, data, res->_size); + load(data, res->_size); - _dataSize = res->_size; - _audioStream = Audio::makeWAVStream(new Common::MemoryReadStream(data, _dataSize, DisposeAfterUse::YES), - DisposeAfterUse::YES); _soundType = Audio::Mixer::kSpeechSoundType; - return true; } @@ -119,10 +112,13 @@ bool CWaveFile::loadMusic(const CString &name) { return false; Common::SeekableReadStream *stream = file.readStream(); - _dataSize = stream->size(); - _audioStream = Audio::makeWAVStream(stream->readStream(_dataSize), DisposeAfterUse::YES); - _soundType = Audio::Mixer::kMusicSoundType; + uint size = stream->size(); + byte *data = new byte[size]; + stream->read(data, size); + delete stream; + load(data, size); + _soundType = Audio::Mixer::kMusicSoundType; return true; } @@ -135,18 +131,44 @@ bool CWaveFile::loadMusic(CAudioBuffer *buffer, DisposeAfterUse::Flag disposeAft return true; } -uint CWaveFile::getFrequency() const { - return _audioStream->getRate(); +void CWaveFile::load(byte *data, uint size) { + _waveData = data; + _waveSize = size; + + // Parse the wave header + Common::MemoryReadStream wavStream(data, size, DisposeAfterUse::NO); + int rate; + byte flags; + Audio::loadWAVFromStream(wavStream, _dataSize, rate, flags); +} + +Audio::SeekableAudioStream *CWaveFile::audioStream() { + if (!_audioStream) { + // No stream yet, so create one and give it control of the raw wave data + assert(_waveData); + _audioStream = Audio::makeWAVStream( + new Common::MemoryReadStream(_waveData, _waveSize, DisposeAfterUse::YES), + DisposeAfterUse::YES); + _waveData = nullptr; + } + + return _audioStream; +} + + +uint CWaveFile::getFrequency() { + return audioStream()->getRate(); } void CWaveFile::reset() { - _audioStream->rewind(); + audioStream()->rewind(); } const byte *CWaveFile::lock() { switch (_loadMode) { case LOADMODE_SCUMMVM: - return _rawData + WAV_DATA_OFFSET; + assert(_waveData); + return _waveData; default: return nullptr; diff --git a/engines/titanic/sound/wave_file.h b/engines/titanic/sound/wave_file.h index 019ee9413e..4158d64683 100644 --- a/engines/titanic/sound/wave_file.h +++ b/engines/titanic/sound/wave_file.h @@ -37,21 +37,28 @@ class QSoundManager; class CWaveFile { private: + byte *_waveData; + int _waveSize; + int _dataSize; + QSoundManager *_soundManager; + Audio::SeekableAudioStream *_audioStream; + Audio::SoundHandle _soundHandle; +private: /** * Handles setup of fields shared by the constructors */ void setup(); + + /** + * Gets passed the raw data for the wave file + */ + void load(byte *data, uint size); public: - QSoundManager *_soundManager; - byte *_rawData; - Audio::SeekableAudioStream *_audioStream; - Audio::SoundHandle _soundHandle; Audio::Mixer::SoundType _soundType; LoadMode _loadMode; int _field4; int _field14; - uint _dataSize; CAudioBuffer *_audioBuffer; DisposeAfterUse::Flag _disposeAudioBuffer; int _channel; @@ -73,6 +80,11 @@ public: uint size() const { return _dataSize; } /** + * Returns a ScummVM Audio Stream for playback purposes + */ + Audio::SeekableAudioStream *audioStream(); + + /** * Tries to load the specified wave file sound */ bool loadSound(const CString &name); @@ -95,12 +107,14 @@ public: /** * Returns true if the wave file has data loaded */ - bool isLoaded() const { return _audioStream != nullptr; } + bool isLoaded() const { + return _audioStream != nullptr || _waveData != nullptr; + } /** * Return the frequency of the loaded wave file */ - uint getFrequency() const; + uint getFrequency(); /** * Resets the music stream |