[Scummvm-cvs-logs] SF.net SVN: scummvm:[41460] scummvm/trunk

peres001 at users.sourceforge.net peres001 at users.sourceforge.net
Fri Jun 12 09:18:01 CEST 2009


Revision: 41460
          http://scummvm.svn.sourceforge.net/scummvm/?rev=41460&view=rev
Author:   peres001
Date:     2009-06-12 07:18:01 +0000 (Fri, 12 Jun 2009)

Log Message:
-----------
* 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.

Modified Paths:
--------------
    scummvm/trunk/engines/parallaction/sound.h
    scummvm/trunk/engines/parallaction/sound_br.cpp
    scummvm/trunk/engines/parallaction/sound_ns.cpp
    scummvm/trunk/sound/iff.cpp
    scummvm/trunk/sound/iff.h

Modified: scummvm/trunk/engines/parallaction/sound.h
===================================================================
--- scummvm/trunk/engines/parallaction/sound.h	2009-06-12 06:20:11 UTC (rev 41459)
+++ scummvm/trunk/engines/parallaction/sound.h	2009-06-12 07:18:01 UTC (rev 41460)
@@ -154,10 +154,9 @@
 		uint32				dataSize;
 		bool				dispose;
 		Audio::SoundHandle	handle;
-		uint32				flags;
 	} _channels[NUM_SFX_CHANNELS];
 
-	void loadChannelData(const char *filename, Channel *ch);
+	Audio::AudioStream *loadChannelData(const char *filename, Channel *ch, bool looping);
 
 public:
 	AmigaSoundMan_ns(Parallaction_ns *vm);
@@ -202,11 +201,8 @@
 		uint32				dataSize;
 		bool				dispose;
 		Audio::SoundHandle	handle;
-		uint32				flags;
 	} _channels[NUM_SFX_CHANNELS];
 
-	virtual void loadChannelData(const char *filename, Channel *ch) = 0;
-
 public:
 	SoundMan_br(Parallaction_br *vm);
 	~SoundMan_br();
@@ -228,7 +224,7 @@
 
 	MidiPlayer_MSC	*_midiPlayer;
 
-	void loadChannelData(const char *filename, Channel *ch);
+	Audio::AudioStream *loadChannelData(const char *filename, Channel *ch, bool looping);
 
 public:
 	DosSoundMan_br(Parallaction_br *vm, MidiDriver *midiDriver);
@@ -246,7 +242,7 @@
 	Audio::AudioStream *_musicStream;
 	Audio::SoundHandle	_musicHandle;
 
-	void loadChannelData(const char *filename, Channel *ch);
+	Audio::AudioStream *loadChannelData(const char *filename, Channel *ch, bool looping);
 
 public:
 	AmigaSoundMan_br(Parallaction_br *vm);

Modified: scummvm/trunk/engines/parallaction/sound_br.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/sound_br.cpp	2009-06-12 06:20:11 UTC (rev 41459)
+++ scummvm/trunk/engines/parallaction/sound_br.cpp	2009-06-12 07:18:01 UTC (rev 41460)
@@ -401,7 +401,7 @@
 	delete _midiPlayer;
 }
 
-void DosSoundMan_br::loadChannelData(const char *filename, Channel *ch) {
+Audio::AudioStream *DosSoundMan_br::loadChannelData(const char *filename, Channel *ch, bool looping) {
 	Common::SeekableReadStream *stream = _vm->_disk->loadSound(filename);
 
 	ch->dataSize = stream->size();
@@ -414,6 +414,15 @@
 
 	// TODO: Confirm sound rate
 	ch->header.samplesPerSec = 11025;
+
+	uint32 loopStart = 0, loopEnd = 0, flags = Audio::Mixer::FLAG_UNSIGNED;
+	if (looping) {
+		loopEnd = ch->dataSize;
+		flags |= Audio::Mixer::FLAG_LOOP;
+	}
+
+	// Create the input stream
+	return Audio::makeLinearInputStream((byte *)ch->data, ch->dataSize, ch->header.samplesPerSec, flags, loopStart, loopEnd);
 }
 
 void DosSoundMan_br::playSfx(const char *filename, uint channel, bool looping, int volume) {
@@ -426,16 +435,8 @@
 	debugC(1, kDebugAudio, "DosSoundMan_br::playSfx(%s, %u, %i, %i)", filename, channel, looping, volume);
 
 	Channel *ch = &_channels[channel];
-	loadChannelData(filename, ch);
-
-	uint32 loopStart = 0, loopEnd = 0, flags = Audio::Mixer::FLAG_UNSIGNED;
-	if (looping) {
-		loopEnd = ch->dataSize;
-		flags |= Audio::Mixer::FLAG_LOOP;
-	}
-
-	_mixer->playRaw(Audio::Mixer::kSFXSoundType, &ch->handle, ch->data, ch->dataSize,
-		ch->header.samplesPerSec, flags, -1, volume, 0, loopStart, loopEnd);
+	Audio::AudioStream *input = loadChannelData(filename, ch, looping);
+	_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &ch->handle, input, -1, volume);
 }
 
 void DosSoundMan_br::playMusic() {
@@ -468,8 +469,10 @@
 	stopMusic();
 }
 
-void AmigaSoundMan_br::loadChannelData(const char *filename, Channel *ch) {
+Audio::AudioStream *AmigaSoundMan_br::loadChannelData(const char *filename, Channel *ch, bool looping) {
 	Common::SeekableReadStream *stream = _vm->_disk->loadSound(filename);
+	Audio::AudioStream *input = 0;
+
 	if (_vm->getFeatures() & GF_DEMO) {
 		ch->dataSize = stream->size();
 		ch->data = (int8*)malloc(ch->dataSize);
@@ -478,12 +481,20 @@
 
 		// TODO: Confirm sound rate
 		ch->header.samplesPerSec = 11025;
+
+		uint32 loopStart = 0, loopEnd = 0, flags = 0;
+		if (looping) {
+			loopEnd = ch->header.oneShotHiSamples + ch->header.repeatHiSamples;
+			flags = Audio::Mixer::FLAG_LOOP;
+		}
+
+		input = Audio::makeLinearInputStream((byte *)ch->data, ch->dataSize, ch->header.samplesPerSec, flags, loopStart, loopEnd);
 	} else {
-		Audio::A8SVXDecoder decoder(*stream, ch->header, ch->data, ch->dataSize);
-		decoder.decode();
+		input = Audio::make8SVXStream(*stream, looping);
+		delete stream;
 	}
-	ch->dispose = true;
-	delete stream;
+
+	return input;
 }
 
 void AmigaSoundMan_br::playSfx(const char *filename, uint channel, bool looping, int volume) {
@@ -501,24 +512,13 @@
 	debugC(1, kDebugAudio, "AmigaSoundMan_ns::playSfx(%s, %i)", filename, channel);
 
 	Channel *ch = &_channels[channel];
-	loadChannelData(filename, ch);
+	Audio::AudioStream *input = loadChannelData(filename, ch, looping);
 
-	uint32 loopStart = 0, loopEnd = 0, flags = 0;
-	if (looping) {
-		// the standard way to loop 8SVX audio implies use of the oneShotHiSamples and
-		// repeatHiSamples fields, but Nippon Safes handles loops according to flags
-		// set in its location scripts and always operates on the whole data.
-		loopStart = 0;
-		loopEnd = ch->header.oneShotHiSamples + ch->header.repeatHiSamples;
-		flags = Audio::Mixer::FLAG_LOOP;
-	}
-
 	if (volume == -1) {
 		volume = ch->header.volume;
 	}
 
-	_mixer->playRaw(Audio::Mixer::kSFXSoundType, &ch->handle, ch->data, ch->dataSize,
-		ch->header.samplesPerSec, flags, -1, volume, 0, loopStart, loopEnd);
+	_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &ch->handle, input, -1, volume);
 }
 
 void AmigaSoundMan_br::playMusic() {

Modified: scummvm/trunk/engines/parallaction/sound_ns.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/sound_ns.cpp	2009-06-12 06:20:11 UTC (rev 41459)
+++ scummvm/trunk/engines/parallaction/sound_ns.cpp	2009-06-12 07:18:01 UTC (rev 41460)
@@ -360,8 +360,9 @@
 	0, 20, 40, 60, 80, 60, 40, 20, 0, -20, -40, -60, -80, -60, -40, -20
 };
 
+Audio::AudioStream *AmigaSoundMan_ns::loadChannelData(const char *filename, Channel *ch, bool looping) {
+	Audio::AudioStream *input = 0;
 
-void AmigaSoundMan_ns::loadChannelData(const char *filename, Channel *ch) {
 	if (!scumm_stricmp("beep", filename)) {
 		ch->header.oneShotHiSamples = 0;
 		ch->header.repeatHiSamples = 0;
@@ -376,14 +377,22 @@
 		}
 		ch->dataSize = AMIGABEEP_SIZE * NUM_REPEATS;
 		ch->dispose = true;
-		return;
+
+		uint32 loopStart = 0, loopEnd = 0, flags = 0;
+		if (looping) {
+			loopEnd = ch->header.oneShotHiSamples + ch->header.repeatHiSamples;
+			flags = Audio::Mixer::FLAG_LOOP;
+		}
+
+		input = Audio::makeLinearInputStream((byte *)ch->data, ch->dataSize, ch->header.samplesPerSec, flags, loopStart, loopEnd);
+	} else {
+		Common::SeekableReadStream *stream = _vm->_disk->loadSound(filename);
+		input = Audio::make8SVXStream(*stream, looping);
+		ch->dispose = true;
+		delete stream;
 	}
 
-	Common::SeekableReadStream *stream = _vm->_disk->loadSound(filename);
-	Audio::A8SVXDecoder decoder(*stream, ch->header, ch->data, ch->dataSize);
-	decoder.decode();
-	ch->dispose = true;
-	delete stream;
+	return input;
 }
 
 void AmigaSoundMan_ns::playSfx(const char *filename, uint channel, bool looping, int volume) {
@@ -397,27 +406,13 @@
 	debugC(1, kDebugAudio, "AmigaSoundMan_ns::playSfx(%s, %i)", filename, channel);
 
 	Channel *ch = &_channels[channel];
-	loadChannelData(filename, ch);
+	Audio::AudioStream *input = loadChannelData(filename, ch, looping);
 
-	uint32 loopStart, loopEnd, flags;
-	if (looping) {
-		// the standard way to loop 8SVX audio implies use of the oneShotHiSamples and
-		// repeatHiSamples fields, but Nippon Safes handles loops according to flags
-		// set in its location scripts and always operates on the whole data.
-		loopStart = 0;
-		loopEnd = ch->header.oneShotHiSamples + ch->header.repeatHiSamples;
-		flags = Audio::Mixer::FLAG_LOOP;
-	} else {
-		loopStart = loopEnd = 0;
-		flags = 0;
-	}
-
 	if (volume == -1) {
 		volume = ch->header.volume;
 	}
 
-	_mixer->playRaw(Audio::Mixer::kSFXSoundType, &ch->handle, ch->data, ch->dataSize,
-		ch->header.samplesPerSec, flags, -1, volume, 0, loopStart, loopEnd);
+	_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &ch->handle, input, -1, volume);
 }
 
 void AmigaSoundMan_ns::stopSfx(uint channel) {

Modified: scummvm/trunk/sound/iff.cpp
===================================================================
--- scummvm/trunk/sound/iff.cpp	2009-06-12 06:20:11 UTC (rev 41459)
+++ scummvm/trunk/sound/iff.cpp	2009-06-12 07:18:01 UTC (rev 41460)
@@ -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);
+		}
 	}
 
-}
+	bool callback(Common::IFFChunk &chunk) {
+		switch (chunk.id) {
+		case ID_VHDR:
+			_header.load(chunk);
+			break;
 
+		case ID_BODY:
+			_dataSize = chunk.size;
+			_data = (int8*)malloc(_dataSize);
+			assert(_data);
+			loadData(&chunk);
+			return true;
+		}
 
-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");
-}
+		return false;
+	}
 
-void A8SVXDecoder::decode() {
-
-	Common::IFFChunk *chunk;
-
-	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);
 }
 
 }

Modified: scummvm/trunk/sound/iff.h
===================================================================
--- scummvm/trunk/sound/iff.h	2009-06-12 06:20:11 UTC (rev 41459)
+++ scummvm/trunk/sound/iff.h	2009-06-12 07:18:01 UTC (rev 41460)
@@ -32,6 +32,7 @@
 #define SOUND_IFF_H
 
 #include "common/iff_container.h"
+#include "sound/audiostream.h"
 
 namespace Audio {
 
@@ -47,34 +48,12 @@
 	Voice8Header() {
 		memset(this, 0, sizeof(Voice8Header));
 	}
-};
 
-
-/*
-	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();
+	void load(Common::ReadStream &stream);
 };
 
+AudioStream *make8SVXStream(Common::ReadStream &stream, bool loop);
 
-/*
-	TODO: Implement a parser for AIFF subtype.
- */
 
 }
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list