aboutsummaryrefslogtreecommitdiff
path: root/sound/iff.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sound/iff.cpp')
-rw-r--r--sound/iff.cpp95
1 files changed, 60 insertions, 35 deletions
diff --git a/sound/iff.cpp b/sound/iff.cpp
index de380276bb..bf3318d80e 100644
--- a/sound/iff.cpp
+++ b/sound/iff.cpp
@@ -26,58 +26,83 @@
#include "sound/iff.h"
#include "sound/audiostream.h"
#include "sound/mixer.h"
+#include "common/func.h"
namespace Audio {
-
-void A8SVXDecoder::readVHDR(Common::IFFChunk &chunk) {
- _header.oneShotHiSamples = chunk.readUint32BE();
- _header.repeatHiSamples = chunk.readUint32BE();
- _header.samplesPerHiCycle = chunk.readUint32BE();
- _header.samplesPerSec = chunk.readUint16BE();
- _header.octaves = chunk.readByte();
- _header.compression = chunk.readByte();
- _header.volume = chunk.readUint32BE();
+void Voice8Header::load(Common::ReadStream &stream) {
+ stream.read(this, sizeof(Voice8Header));
+ oneShotHiSamples = FROM_BE_32(oneShotHiSamples);
+ repeatHiSamples = FROM_BE_32(repeatHiSamples);
+ samplesPerHiCycle = FROM_BE_32(samplesPerHiCycle);
+ samplesPerSec = FROM_BE_16(samplesPerSec);
+ volume = FROM_BE_32(volume);
}
-void A8SVXDecoder::readBODY(Common::IFFChunk &chunk) {
-
- switch (_header.compression) {
- case 0:
- _dataSize = chunk.size;
- _data = (int8*)malloc(_dataSize);
- chunk.read(_data, _dataSize);
- break;
- case 1:
- warning("compressed IFF audio is not supported");
- break;
- }
-}
+struct A8SVXLoader {
+ Voice8Header _header;
+ int8 *_data;
+ uint32 _dataSize;
+ void load(Common::ReadStream &input) {
+ Common::IFFParser parser(input);
+ Common::IFFChunk *chunk;
+ while (chunk = parser.nextChunk()) {
+ callback(*chunk);
+ }
+ }
-A8SVXDecoder::A8SVXDecoder(Common::ReadStream &input, Voice8Header &header, int8 *&data, uint32 &dataSize) :
- IFFParser(input), _header(header), _data(data), _dataSize(dataSize) {
- if (_typeId != ID_8SVX)
- error("unknown audio format");
-}
+ bool callback(Common::IFFChunk &chunk) {
+ switch (chunk.id) {
+ case ID_VHDR:
+ _header.load(chunk);
+ break;
-void A8SVXDecoder::decode() {
+ case ID_BODY:
+ _dataSize = chunk.size;
+ _data = (int8*)malloc(_dataSize);
+ assert(_data);
+ loadData(&chunk);
+ return true;
+ }
- Common::IFFChunk *chunk;
+ return false;
+ }
- while ((chunk = nextChunk()) != 0) {
- switch (chunk->id) {
- case ID_VHDR:
- readVHDR(*chunk);
+ void loadData(Common::ReadStream *stream) {
+ switch (_header.compression) {
+ case 0:
+ stream->read(_data, _dataSize);
break;
- case ID_BODY:
- readBODY(*chunk);
+ case 1:
+ // implement other formats here
+ error("compressed IFF audio is not supported");
break;
}
+
+ }
+};
+
+
+AudioStream *make8SVXStream(Common::ReadStream &input, bool loop) {
+ A8SVXLoader loader;
+ loader.load(input);
+
+ uint32 loopStart = 0, loopEnd = 0, flags = 0;
+ if (loop) {
+ // the standard way to loop 8SVX audio implies use of the oneShotHiSamples and
+ // repeatHiSamples fields
+ loopStart = 0;
+ loopEnd = loader._header.oneShotHiSamples + loader._header.repeatHiSamples;
+ flags |= Audio::Mixer::FLAG_LOOP;
}
+
+ flags |= Audio::Mixer::FLAG_AUTOFREE;
+
+ return Audio::makeLinearInputStream((byte *)loader._data, loader._dataSize, loader._header.samplesPerSec, flags, loopStart, loopEnd);
}
}