* Replaced the A8SVXDecoder class with a function to return an AudioStream in trunk/sound/.

* Refactored sound code in Parallaction to use the new Audio::make8SVXStream.

svn-id: r41460
This commit is contained in:
Nicola Mettifogo 2009-06-12 07:18:01 +00:00
parent 5915e60452
commit df1534ffd0
5 changed files with 115 additions and 120 deletions

View file

@ -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");
}
void A8SVXDecoder::decode() {
Common::IFFChunk *chunk;
while ((chunk = nextChunk()) != 0) {
switch (chunk->id) {
bool callback(Common::IFFChunk &chunk) {
switch (chunk.id) {
case ID_VHDR:
readVHDR(*chunk);
_header.load(chunk);
break;
case ID_BODY:
readBODY(*chunk);
_dataSize = chunk.size;
_data = (int8*)malloc(_dataSize);
assert(_data);
loadData(&chunk);
return true;
}
return false;
}
void loadData(Common::ReadStream *stream) {
switch (_header.compression) {
case 0:
stream->read(_data, _dataSize);
break;
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);
}
}

View file

@ -32,6 +32,7 @@
#define SOUND_IFF_H
#include "common/iff_container.h"
#include "sound/audiostream.h"
namespace Audio {
@ -47,34 +48,12 @@ struct Voice8Header {
Voice8Header() {
memset(this, 0, sizeof(Voice8Header));
}
void load(Common::ReadStream &stream);
};
AudioStream *make8SVXStream(Common::ReadStream &stream, bool loop);
/*
A8SVX decoder reads 8SVX subtype of IFF files.
TODO: make a factory function for this kind of stream?
*/
class A8SVXDecoder : public Common::IFFParser {
protected:
Voice8Header &_header;
int8* &_data;
uint32 &_dataSize;
protected:
void readVHDR(Common::IFFChunk &chunk);
void readBODY(Common::IFFChunk &chunk);
public:
A8SVXDecoder(Common::ReadStream &input, Voice8Header &header, int8 *&data, uint32 &dataSize);
void decode();
};
/*
TODO: Implement a parser for AIFF subtype.
*/
}