aboutsummaryrefslogtreecommitdiff
path: root/engines/titanic/sound
diff options
context:
space:
mode:
authorPaul Gilbert2017-02-09 21:18:13 -0500
committerPaul Gilbert2017-02-09 21:18:13 -0500
commit6618af29fa64857227af18bf4bfc8020106920ba (patch)
tree2f6ce60b69459d7c418641bc188cb6dcbc818319 /engines/titanic/sound
parentc2b3abd676a194138849252a3e37d6cb977a343c (diff)
downloadscummvm-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.cpp6
-rw-r--r--engines/titanic/sound/wave_file.cpp74
-rw-r--r--engines/titanic/sound/wave_file.h28
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