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

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Fri Jan 8 23:04:30 CET 2010


Revision: 47177
          http://scummvm.svn.sourceforge.net/scummvm/?rev=47177&view=rev
Author:   fingolfin
Date:     2010-01-08 22:04:30 +0000 (Fri, 08 Jan 2010)

Log Message:
-----------
Move Mohawk's QueuedAudioStream to sound/ (with some tweaks)

Modified Paths:
--------------
    scummvm/trunk/engines/mohawk/video/qt_player.cpp
    scummvm/trunk/engines/mohawk/video/qt_player.h
    scummvm/trunk/sound/audiostream.cpp
    scummvm/trunk/sound/audiostream.h

Modified: scummvm/trunk/engines/mohawk/video/qt_player.cpp
===================================================================
--- scummvm/trunk/engines/mohawk/video/qt_player.cpp	2010-01-08 21:47:28 UTC (rev 47176)
+++ scummvm/trunk/engines/mohawk/video/qt_player.cpp	2010-01-08 22:04:30 UTC (rev 47177)
@@ -51,47 +51,6 @@
 namespace Mohawk {
 
 ////////////////////////////////////////////
-// QueuedAudioStream 
-////////////////////////////////////////////
-
-QueuedAudioStream::QueuedAudioStream(int rate, int channels, bool autofree) {
-	_rate = rate;
-	_channels = channels;
-	_autofree = autofree;
-	_finished = false;
-}
-
-QueuedAudioStream::~QueuedAudioStream() {
-	if (_autofree)
-		while (!_queue.empty())
-			delete _queue.pop();
-	_queue.clear();
-}
-
-void QueuedAudioStream::queueAudioStream(Audio::AudioStream *audStream) {
-	if (audStream->getRate() != getRate() && audStream->isStereo() && isStereo())
-		error("QueuedAudioStream::queueAudioStream: audStream has mismatched parameters");
-		
-	_queue.push(audStream);
-}
-
-int QueuedAudioStream::readBuffer(int16 *buffer, const int numSamples) {
-	int samplesDecoded = 0;
-
-	while (samplesDecoded < numSamples && !_queue.empty()) {
-		samplesDecoded += _queue.front()->readBuffer(buffer + samplesDecoded, numSamples - samplesDecoded);
-
-		if (_queue.front()->endOfData()) {
-			Audio::AudioStream *temp = _queue.pop();
-			if (_autofree)
-				delete temp;
-		}
-	}
-
-	return samplesDecoded;
-}
-
-////////////////////////////////////////////
 // QTPlayer 
 ////////////////////////////////////////////
 
@@ -189,7 +148,7 @@
 	stopAudio();
 	if (_audioStreamIndex >= 0) {
 		_curAudioChunk = 0;
-		_audStream = new QueuedAudioStream(_streams[_audioStreamIndex]->sample_rate, _streams[_audioStreamIndex]->channels);
+		_audStream = Audio::makeQueuedAudioStream(_streams[_audioStreamIndex]->sample_rate, _streams[_audioStreamIndex]->channels == 2);
 	}
 	startAudio();
 }
@@ -345,7 +304,7 @@
 	}
 	
 	if (_audioStreamIndex >= 0 && checkAudioCodecSupport(_streams[_audioStreamIndex]->codec_tag)) {
-		_audStream = new QueuedAudioStream(_streams[_audioStreamIndex]->sample_rate, _streams[_audioStreamIndex]->channels);
+		_audStream = Audio::makeQueuedAudioStream(_streams[_audioStreamIndex]->sample_rate, _streams[_audioStreamIndex]->channels == 2);
 		_curAudioChunk = 0;
 	
 		// Make sure the bits per sample transfers to the sample size
@@ -1229,7 +1188,7 @@
 		return;
 
 	// Keep two streams in buffer so that when the first ends, it goes right into the next
-	for (; _audStream->streamsInQueue() < 2 && _curAudioChunk < _streams[_audioStreamIndex]->chunk_count; _curAudioChunk++) {
+	for (; _audStream->numQueuedStreams() < 2 && _curAudioChunk < _streams[_audioStreamIndex]->chunk_count; _curAudioChunk++) {
 		Common::MemoryWriteStreamDynamic *wStream = new Common::MemoryWriteStreamDynamic();
 		
 		_fd->seek(_streams[_audioStreamIndex]->chunk_offsets[_curAudioChunk]);

Modified: scummvm/trunk/engines/mohawk/video/qt_player.h
===================================================================
--- scummvm/trunk/engines/mohawk/video/qt_player.h	2010-01-08 21:47:28 UTC (rev 47176)
+++ scummvm/trunk/engines/mohawk/video/qt_player.h	2010-01-08 22:04:30 UTC (rev 47177)
@@ -46,31 +46,6 @@
 
 namespace Mohawk {
 
-class QueuedAudioStream : public Audio::AudioStream {
-public:
-	QueuedAudioStream(int rate, int channels, bool autofree = true);
-	~QueuedAudioStream();
-
-	int readBuffer(int16 *buffer, const int numSamples);
-	bool isStereo() const { return _channels == 2; }
-	int getRate() const { return _rate; }
-	bool endOfData() const { return _queue.empty(); }
-	bool endOfStream() const { return _finished; }
-
-	void queueAudioStream(Audio::AudioStream *audStream);
-	void finish() { _finished = true; }
-
-	uint32 streamsInQueue() { return _queue.size(); }
-
-private:
-	bool _autofree;
-	bool _finished;
-	int _rate;
-	int _channels;
-
-	Common::Queue<Audio::AudioStream*> _queue;
-};
-
 enum ScaleMode {
 	kScaleNormal = 1,
 	kScaleHalf = 2,
@@ -271,7 +246,7 @@
 	void resetInternal();
 	uint32 getFrameDuration();
 
-	QueuedAudioStream *_audStream;
+	Audio::QueuedAudioStream *_audStream;
 	int8 _videoStreamIndex;
 	int8 _audioStreamIndex;
 	uint _curAudioChunk;

Modified: scummvm/trunk/sound/audiostream.cpp
===================================================================
--- scummvm/trunk/sound/audiostream.cpp	2010-01-08 21:47:28 UTC (rev 47176)
+++ scummvm/trunk/sound/audiostream.cpp	2010-01-08 22:04:30 UTC (rev 47177)
@@ -27,6 +27,7 @@
 #include "common/endian.h"
 #include "common/file.h"
 #include "common/list.h"
+#include "common/queue.h"
 #include "common/util.h"
 
 #include "sound/audiostream.h"
@@ -523,15 +524,15 @@
 			return new LinearMemoryStream<STEREO, false, UNSIGNED, false>(rate, ptr, len, loopOffset, loopLen, autoFree)
 
 SeekableAudioStream *makeLinearInputStream(const byte *ptr, uint32 len, int rate, byte flags, uint loopStart, uint loopEnd) {
-	const bool isStereo   = (flags & Audio::Mixer::FLAG_STEREO) != 0;
-	const bool is16Bit    = (flags & Audio::Mixer::FLAG_16BITS) != 0;
-	const bool isUnsigned = (flags & Audio::Mixer::FLAG_UNSIGNED) != 0;
-	const bool isLE       = (flags & Audio::Mixer::FLAG_LITTLE_ENDIAN) != 0;
-	const bool autoFree   = (flags & Audio::Mixer::FLAG_AUTOFREE) != 0;
+	const bool isStereo   = (flags & Mixer::FLAG_STEREO) != 0;
+	const bool is16Bit    = (flags & Mixer::FLAG_16BITS) != 0;
+	const bool isUnsigned = (flags & Mixer::FLAG_UNSIGNED) != 0;
+	const bool isLE       = (flags & Mixer::FLAG_LITTLE_ENDIAN) != 0;
+	const bool autoFree   = (flags & Mixer::FLAG_AUTOFREE) != 0;
 
 
 	uint loopOffset = 0, loopLen = 0;
-	if (flags & Audio::Mixer::FLAG_LOOP) {
+	if (flags & Mixer::FLAG_LOOP) {
 		if (loopEnd == 0)
 			loopEnd = len;
 		assert(loopStart <= loopEnd);
@@ -578,11 +579,11 @@
 
 
 SeekableAudioStream *makeLinearDiskStream(Common::SeekableReadStream *stream, LinearDiskStreamAudioBlock *block, int numBlocks, int rate, byte flags, bool takeOwnership, uint loopStart, uint loopEnd) {
-	const bool isStereo   = (flags & Audio::Mixer::FLAG_STEREO) != 0;
-	const bool is16Bit    = (flags & Audio::Mixer::FLAG_16BITS) != 0;
-	const bool isUnsigned = (flags & Audio::Mixer::FLAG_UNSIGNED) != 0;
-	const bool isLE       = (flags & Audio::Mixer::FLAG_LITTLE_ENDIAN) != 0;
-	const bool loop       = (flags & Audio::Mixer::FLAG_LOOP) != 0;
+	const bool isStereo   = (flags & Mixer::FLAG_STEREO) != 0;
+	const bool is16Bit    = (flags & Mixer::FLAG_16BITS) != 0;
+	const bool isUnsigned = (flags & Mixer::FLAG_UNSIGNED) != 0;
+	const bool isLE       = (flags & Mixer::FLAG_LITTLE_ENDIAN) != 0;
+	const bool loop       = (flags & Mixer::FLAG_LOOP) != 0;
 
 	if (isStereo) {
 		if (isUnsigned) {
@@ -600,8 +601,6 @@
 }
 
 
-
-
 #pragma mark -
 #pragma mark --- Appendable audio stream ---
 #pragma mark -
@@ -617,16 +616,18 @@
 class BaseAppendableMemoryStream : public AppendableAudioStream {
 protected:
 
-	// A mutex to avoid access problems (causing e.g. corruption of
-	// the linked list) in thread aware environments.
+	/**
+	 * A mutex to avoid access problems (causing e.g. corruption of
+	 * the linked list) in thread aware environments.
+	 */
 	Common::Mutex _mutex;
 
 	// List of all queued buffers
 	Common::List<Buffer> _bufferQueue;
 
-	// Position in the front buffer, if any
 	bool _finalized;
 	const int _rate;
+	// Position in the front buffer, if any
 	byte *_pos;
 
 	inline bool eosIntern() const { return _bufferQueue.empty(); };
@@ -739,10 +740,10 @@
 			return new AppendableMemoryStream<STEREO, false, UNSIGNED, false>(rate)
 
 AppendableAudioStream *makeAppendableAudioStream(int rate, byte _flags) {
-	const bool isStereo = (_flags & Audio::Mixer::FLAG_STEREO) != 0;
-	const bool is16Bit = (_flags & Audio::Mixer::FLAG_16BITS) != 0;
-	const bool isUnsigned = (_flags & Audio::Mixer::FLAG_UNSIGNED) != 0;
-	const bool isLE       = (_flags & Audio::Mixer::FLAG_LITTLE_ENDIAN) != 0;
+	const bool isStereo = (_flags & Mixer::FLAG_STEREO) != 0;
+	const bool is16Bit = (_flags & Mixer::FLAG_16BITS) != 0;
+	const bool isUnsigned = (_flags & Mixer::FLAG_UNSIGNED) != 0;
+	const bool isLE       = (_flags & Mixer::FLAG_LITTLE_ENDIAN) != 0;
 
 	if (isStereo) {
 		if (isUnsigned) {
@@ -760,4 +761,122 @@
 }
 
 
+
+
+
+#pragma mark -
+#pragma mark --- Appendable audio stream ---
+#pragma mark -
+
+
+class QueuedAudioStreamImpl : public QueuedAudioStream {
+private:
+	/**
+	 * We queue a number of (pointers to) audio stream objects.
+	 * In addition, we need to remember for each stream whether
+	 * to dispose it after all data has been read from it.
+	 * Hence, we don't store pointers to stream objects directly,
+	 * but rather StreamHolder structs.
+	 */
+	struct StreamHolder {
+		AudioStream *_stream;
+		bool _disposeAfterUse;
+		StreamHolder(AudioStream *stream, bool disposeAfterUse)
+			: _stream(stream),
+			  _disposeAfterUse(disposeAfterUse) {}
+	};
+
+	/**
+	 * The sampling rate of this audio stream.
+	 */
+	const int _rate;
+
+	/**
+	 * Whether this audio stream is mono (=false) or stereo (=true).
+	 */
+	const int _stereo;
+
+	/**
+	 * This flag is set by the finish() method only. See there for more details.
+	 */
+	bool _finished;
+
+	/**
+	 * A mutex to avoid access problems (causing e.g. corruption of
+	 * the linked list) in thread aware environments.
+	 */
+	Common::Mutex _mutex;
+
+	/**
+	 * The queue of audio streams.
+	 */
+	Common::Queue<StreamHolder> _queue;
+
+public:
+	QueuedAudioStreamImpl(int rate, bool stereo)
+		: _rate(rate), _stereo(stereo), _finished(false) {}
+	~QueuedAudioStreamImpl();
+
+	// Implement the AudioStream API
+	virtual int readBuffer(int16 *buffer, const int numSamples);
+	virtual bool isStereo() const { return _stereo; }
+	virtual int getRate() const { return _rate; }
+	virtual bool endOfData() const {
+		//Common::StackLock lock(_mutex);
+		return _queue.empty();
+	}
+	virtual bool endOfStream() const { return _finished; }
+
+	// Implement the QueuedAudioStream API
+	virtual void queueAudioStream(AudioStream *stream, bool disposeAfterUse);
+	virtual void finish() { _finished = true; }
+
+	uint32 numQueuedStreams() const {
+		//Common::StackLock lock(_mutex);
+		return _queue.size();
+	}
+};
+
+QueuedAudioStreamImpl::~QueuedAudioStreamImpl() {
+	while (!_queue.empty()) {
+		StreamHolder tmp = _queue.pop();
+		if (tmp._disposeAfterUse)
+			delete tmp._stream;
+	}
+}
+
+void QueuedAudioStreamImpl::queueAudioStream(AudioStream *stream, bool disposeAfterUse) {
+	if ((stream->getRate() != getRate()) || (stream->isStereo() != isStereo()))
+		error("QueuedAudioStreamImpl::queueAudioStream: stream has mismatched parameters");
+
+	Common::StackLock lock(_mutex);
+	_queue.push(StreamHolder(stream, disposeAfterUse));
+}
+
+int QueuedAudioStreamImpl::readBuffer(int16 *buffer, const int numSamples) {
+	Common::StackLock lock(_mutex);
+	int samplesDecoded = 0;
+
+	while (samplesDecoded < numSamples && !_queue.empty()) {
+		AudioStream *stream = _queue.front()._stream;
+		samplesDecoded += stream->readBuffer(buffer + samplesDecoded, numSamples - samplesDecoded);
+
+		if (stream->endOfData()	) {
+			StreamHolder tmp = _queue.pop();
+			if (tmp._disposeAfterUse)
+				delete stream;
+		}
+	}
+
+	return samplesDecoded;
+}
+
+
+
+QueuedAudioStream *makeQueuedAudioStream(int rate, bool stereo) {
+	return new QueuedAudioStreamImpl(rate, stereo);
+}
+
+
+
 } // End of namespace Audio

Modified: scummvm/trunk/sound/audiostream.h
===================================================================
--- scummvm/trunk/sound/audiostream.h	2010-01-08 21:47:28 UTC (rev 47176)
+++ scummvm/trunk/sound/audiostream.h	2010-01-08 22:04:30 UTC (rev 47177)
@@ -319,7 +319,52 @@
  */
 AppendableAudioStream *makeAppendableAudioStream(int rate, byte flags);
 
+
+class QueuedAudioStream : public Audio::AudioStream {
+public:
+
+	/**
+	 * Queue an audio stream for playback. This stream will
+	 * play all queued streams, in the order they were queued.
+	 * If the disposeAfterUse is true, then the stream is
+	 * deleted after all data contained in it has been played.
+	 */
+	virtual void queueAudioStream(Audio::AudioStream *audStream,
+						bool disposeAfterUse = true) = 0;
+
+	/**
+	 * Queue a block of raw audio data for playback. This stream
+	 * will play all queued buffers, in the order they were
+	 * queued. After all data contained in them has been played,
+	 * the buffer will be delete[]'d (so make sure to allocate them
+	 * with new[], not with malloc).
+	 */
+	void queueBuffer(byte *data, uint32 size, byte flags) {
+		AudioStream *stream = makeLinearInputStream(data, size, getRate(), flags, 0, 0);
+		queueAudioStream(stream, true);
+	}
+
+	/**
+	 * Mark the stream as finished, that is, signal that no further data
+	 * will be appended to it. Only after this has been done can this
+	 * stream ever 'end'.
+	 */
+	virtual void finish() = 0;
+
+	/**
+	 * Return the number of streams still queued for playback (including
+	 * the currently playing stream).
+	 */
+	virtual uint32 numQueuedStreams() const = 0;
+};
+
 /**
+ * Factory function for an QueuedAudioStream.
+ */
+QueuedAudioStream *makeQueuedAudioStream(int rate, bool stereo);
+
+
+/**
  * Calculates the sample, which the timestamp describes in a
  * AudioStream with the given framerate.
  *


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