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

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Sun Jan 10 16:20:14 CET 2010


Revision: 47226
          http://scummvm.svn.sourceforge.net/scummvm/?rev=47226&view=rev
Author:   lordhoto
Date:     2010-01-10 15:20:14 +0000 (Sun, 10 Jan 2010)

Log Message:
-----------
- Add a SubLoopingAudioStream, which loops a nested part of a stream and thus features the same looping capabilites as LinearMemoryStream and LinearDiskStream.
- Remove custom looping code from LinearMemoryStream and LinearDiskStream.
- Adapt various client code to the changes.

Modified Paths:
--------------
    scummvm/trunk/engines/kyra/sound.cpp
    scummvm/trunk/engines/saga/music.cpp
    scummvm/trunk/engines/sci/sound/audio.cpp
    scummvm/trunk/engines/sci/sound/music.cpp
    scummvm/trunk/engines/tucker/sequences.cpp
    scummvm/trunk/sound/aiff.cpp
    scummvm/trunk/sound/audiostream.cpp
    scummvm/trunk/sound/audiostream.h
    scummvm/trunk/sound/voc.cpp
    scummvm/trunk/sound/voc.h
    scummvm/trunk/sound/wave.cpp

Modified: scummvm/trunk/engines/kyra/sound.cpp
===================================================================
--- scummvm/trunk/engines/kyra/sound.cpp	2010-01-10 13:22:45 UTC (rev 47225)
+++ scummvm/trunk/engines/kyra/sound.cpp	2010-01-10 15:20:14 UTC (rev 47226)
@@ -244,9 +244,9 @@
 Audio::SeekableAudioStream *makeVOCStream(Common::SeekableReadStream *stream, bool disposeAfterUse) {
 
 #ifdef STREAM_AUDIO_FROM_DISK
-	Audio::SeekableAudioStream *as = Audio::makeVOCStream(*stream, Audio::Mixer::FLAG_UNSIGNED, 0, 0, disposeAfterUse);
+	Audio::SeekableAudioStream *as = Audio::makeVOCStream(*stream, Audio::Mixer::FLAG_UNSIGNED, disposeAfterUse);
 #else
-	Audio::SeekableAudioStream *as = Audio::makeVOCStream(*stream, Audio::Mixer::FLAG_UNSIGNED);
+	Audio::SeekableAudioStream *as = Audio::makeVOCStream(*stream, Audio::Mixer::FLAG_UNSIGNED, false);
 
 	if (disposeAfterUse)
 		delete stream;

Modified: scummvm/trunk/engines/saga/music.cpp
===================================================================
--- scummvm/trunk/engines/saga/music.cpp	2010-01-10 13:22:45 UTC (rev 47225)
+++ scummvm/trunk/engines/saga/music.cpp	2010-01-10 15:20:14 UTC (rev 47226)
@@ -292,7 +292,7 @@
 				loopStart = 0;
 				// Fix ITE sunstatm/sunspot score
 				if (resourceId == MUSIC_SUNSPOT)
-					loopStart = 4 * 18727;
+					loopStart = 18727;
 
 				// Digital music
 				ResourceData *resData = _digitalMusicContext->getResourceData(resourceId - 9);
@@ -311,7 +311,7 @@
 					Audio::LinearDiskStreamAudioBlock audioBlocks[1];
 					audioBlocks[0].pos = 0;
 					audioBlocks[0].len = resData->size / 2;	// 16-bit sound
-					audioStream = Audio::makeLinearDiskStream(musicStream, audioBlocks, 1, 11025, musicFlags, false, loopStart, 0);
+					audioStream = Audio::makeLinearDiskStream(musicStream, audioBlocks, 1, 11025, musicFlags, false);
 				} else {
 					// Read compressed header to determine compression type
 					musicFile->seek((uint32)resData->offset, SEEK_SET);
@@ -337,8 +337,16 @@
 
 	if (audioStream) {
 		debug(2, "Playing digitized music");
-		_mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle,
-		                        Audio::makeLoopingAudioStream(audioStream, (flags == MUSIC_LOOP ? 0 : 1)));
+		if (loopStart) {
+			_mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle,
+			                        new Audio::SubLoopingAudioStream(audioStream,
+			                        (flags == MUSIC_LOOP ? 0 : 1),
+			                        Audio::Timestamp(0, loopStart, audioStream->getRate()),
+			                        audioStream->getLength()));
+		} else {
+			_mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle,
+			                        Audio::makeLoopingAudioStream(audioStream, (flags == MUSIC_LOOP ? 0 : 1)));
+		}
 		_digitalMusic = true;
 		return;
 	}

Modified: scummvm/trunk/engines/sci/sound/audio.cpp
===================================================================
--- scummvm/trunk/engines/sci/sound/audio.cpp	2010-01-10 13:22:45 UTC (rev 47225)
+++ scummvm/trunk/engines/sci/sound/audio.cpp	2010-01-10 15:20:14 UTC (rev 47226)
@@ -243,10 +243,9 @@
 		}
 	}
 
-	if (data) {
-		audioStream = Audio::makeLinearInputStream(data, size, _audioRate, 
-										flags | Audio::Mixer::FLAG_AUTOFREE, 0, 0);
-	}
+	if (data)
+		audioStream = Audio::makeLinearInputStream(data, size, _audioRate, flags | Audio::Mixer::FLAG_AUTOFREE);
+
 	if (audioStream) {
 		*sampleLen = (flags & Audio::Mixer::FLAG_16BITS ? size >> 1 : size) * 60 / _audioRate;
 		return audioStream;

Modified: scummvm/trunk/engines/sci/sound/music.cpp
===================================================================
--- scummvm/trunk/engines/sci/sound/music.cpp	2010-01-10 13:22:45 UTC (rev 47225)
+++ scummvm/trunk/engines/sci/sound/music.cpp	2010-01-10 15:20:14 UTC (rev 47226)
@@ -303,8 +303,7 @@
 		if (track->digitalChannelNr != -1) {
 			byte *channelData = track->channels[track->digitalChannelNr].data;
 			delete pSnd->pStreamAud;
-			pSnd->pStreamAud = Audio::makeLinearInputStream(channelData, track->digitalSampleSize, track->digitalSampleRate,
-					Audio::Mixer::FLAG_UNSIGNED, 0, 0);
+			pSnd->pStreamAud = Audio::makeLinearInputStream(channelData, track->digitalSampleSize, track->digitalSampleRate, Audio::Mixer::FLAG_UNSIGNED);
 			delete pSnd->pLoopStream;
 			pSnd->pLoopStream = 0;
 			pSnd->soundType = Audio::Mixer::kSFXSoundType;

Modified: scummvm/trunk/engines/tucker/sequences.cpp
===================================================================
--- scummvm/trunk/engines/tucker/sequences.cpp	2010-01-10 13:22:45 UTC (rev 47225)
+++ scummvm/trunk/engines/tucker/sequences.cpp	2010-01-10 15:20:14 UTC (rev 47226)
@@ -598,7 +598,7 @@
 				uint8 *sampleData = (uint8 *)malloc(size);
 				if (sampleData) {
 					f.read(sampleData, size);
-					stream = Audio::makeLinearInputStream(sampleData, size, rate, flags, 0, 0);
+					stream = Audio::makeLinearInputStream(sampleData, size, rate, flags);
 				}
 			}
 			break;

Modified: scummvm/trunk/sound/aiff.cpp
===================================================================
--- scummvm/trunk/sound/aiff.cpp	2010-01-10 13:22:45 UTC (rev 47225)
+++ scummvm/trunk/sound/aiff.cpp	2010-01-10 15:20:14 UTC (rev 47226)
@@ -174,7 +174,7 @@
 	// Since we allocated our own buffer for the data, we must set the autofree flag.
 	flags |= Audio::Mixer::FLAG_AUTOFREE;
 
-	return makeLinearInputStream(data, size, rate, flags, 0, 0);
+	return makeLinearInputStream(data, size, rate, flags);
 }
 
 } // End of namespace Audio

Modified: scummvm/trunk/sound/audiostream.cpp
===================================================================
--- scummvm/trunk/sound/audiostream.cpp	2010-01-10 13:22:45 UTC (rev 47225)
+++ scummvm/trunk/sound/audiostream.cpp	2010-01-10 15:20:14 UTC (rev 47226)
@@ -162,6 +162,59 @@
 }
 
 #pragma mark -
+#pragma mark --- SubLoopingAudioStream ---
+#pragma mark -
+
+SubLoopingAudioStream::SubLoopingAudioStream(SeekableAudioStream *stream,
+	                                         uint loops,
+	                                         const Timestamp loopStart,
+	                                         const Timestamp loopEnd,
+	                                         bool disposeAfterUse)
+    : _parent(stream), _disposeAfterUse(disposeAfterUse), _loops(loops),
+      _pos(0, getRate() * (isStereo() ? 2 : 1)),
+      _loopStart(loopStart.convertToFramerate(getRate() * (isStereo() ? 2 : 1))),
+      _loopEnd(loopEnd.convertToFramerate(getRate() * (isStereo() ? 2 : 1))),
+      _done(false) {
+	if (!_parent->rewind())
+		_done = true;
+}
+
+SubLoopingAudioStream::~SubLoopingAudioStream() {
+	if (_disposeAfterUse)
+		delete _parent;
+}
+
+int SubLoopingAudioStream::readBuffer(int16 *buffer, const int numSamples) {
+	int framesLeft = MIN(_loopEnd.frameDiff(_pos), numSamples);
+	int framesRead = _parent->readBuffer(buffer, framesLeft);
+	_pos = _pos.addFrames(framesRead);
+
+	if (framesLeft < numSamples || framesRead < framesLeft) {
+		if (_loops != 0) {
+			--_loops;
+			if (!_loops) {
+				_done = true;
+				return framesRead;
+			}
+		}
+
+		if (!_parent->seek(_loopStart)) {
+			_done = true;
+			return framesRead;
+		}
+
+		_pos = _loopStart;
+		framesLeft = numSamples - framesLeft;
+		framesRead += _parent->readBuffer(buffer + framesRead, framesLeft);
+
+		if (_parent->endOfStream())
+			_done = true;
+	}
+
+	return framesRead;
+}
+
+#pragma mark -
 #pragma mark --- SubSeekableAudioStream ---
 #pragma mark -
 
@@ -226,36 +279,23 @@
 protected:
 	const byte *_ptr;
 	const byte *_end;
-	const byte *_loopPtr;
-	const byte *_loopEnd;
 	const int _rate;
 	const byte *_origPtr;
 	const bool _disposeAfterUse;
 	const Timestamp _playtime;
 
-	uint _numLoops;			///< Number of loops to play
-	uint _numPlayedLoops;	///< Number of loops which have been played
-
 public:
-	LinearMemoryStream(int rate, const byte *ptr, uint len, uint loopOffset, uint loopLen, bool autoFreeMemory)
-	    : _ptr(ptr), _end(ptr+len), _loopPtr(0), _loopEnd(0), _rate(rate), _disposeAfterUse(autoFreeMemory),
+	LinearMemoryStream(int rate, const byte *ptr, uint len, bool autoFreeMemory)
+	    : _ptr(ptr), _end(ptr+len), _rate(rate), _origPtr(ptr),
+	      _disposeAfterUse(autoFreeMemory),
 	      _playtime(0, len / (is16Bit ? 2 : 1) / (stereo ? 2 : 1), rate) {
+	}
 
-		if (loopLen) {
-			_numLoops = 0;
-			_loopPtr = _ptr + loopOffset;
-			_loopEnd = _loopPtr + loopLen;
-		} else {
-			_numLoops = 1;
-		}
-		_numPlayedLoops = 0;
-
-		_origPtr = ptr;
-	}
 	virtual ~LinearMemoryStream() {
 		if (_disposeAfterUse)
 			free(const_cast<byte *>(_origPtr));
 	}
+
 	int readBuffer(int16 *buffer, const int numSamples);
 
 	bool isStereo() const			{ return stereo; }
@@ -276,14 +316,6 @@
 			*buffer++ = READ_ENDIAN_SAMPLE(is16Bit, isUnsigned, _ptr, isLE);
 			_ptr += (is16Bit ? 2 : 1);
 		} while (--len);
-		// Loop, if looping was specified
-		// TODO: Handle non-infinite loops
-		if (_loopPtr && _ptr >= _end) {
-			_ptr = _loopPtr;
-			_end = _loopEnd;
-
-			_numPlayedLoops++;
-		}
 	}
 	return numSamples-samples;
 }
@@ -339,17 +371,10 @@
 	LinearDiskStreamAudioBlock *_audioBlock;	///< Audio block list
 	int _audioBlockCount;		///< Number of blocks in _audioBlock
 	int _currentBlock;		///< Current audio block number
-
-	int _beginLoop;			///< Loop start parameter
-	int _endLoop;			///< Loop end parameter, currently not implemented
-	bool _loop;				///< Determines if the stream should be looped when it finishes
-	uint _numLoops;			///< Number of loops to play
-	uint _numPlayedLoops;	///< Number of loops which have been played
-
 public:
-	LinearDiskStream(int rate, uint beginLoop, uint endLoop, bool disposeStream, Common::SeekableReadStream *stream, LinearDiskStreamAudioBlock *block, uint numBlocks, bool loop)
-		: _rate(rate), _playtime(0, rate), _stream(stream), _beginLoop(beginLoop), _endLoop(endLoop), _disposeAfterUse(disposeStream),
-		  _audioBlockCount(numBlocks), _loop(loop), _numLoops(loop ? 0 : 1), _numPlayedLoops(0) {
+	LinearDiskStream(int rate, bool disposeStream, Common::SeekableReadStream *stream, LinearDiskStreamAudioBlock *block, uint numBlocks)
+		: _rate(rate), _playtime(0, rate), _stream(stream), _disposeAfterUse(disposeStream),
+		  _audioBlockCount(numBlocks) {
 
 		assert(numBlocks > 0);
 
@@ -442,22 +467,12 @@
 			_bufferLeft = readAmount;
 			_diskLeft -= readAmount;
 			_ptr = (byte *)_buffer;
-			_filePos += readAmount * (is16Bit? 2: 1);
+			_filePos += readAmount * (is16Bit ? 2 : 1);
 
 			// Set this flag now we've used the file, it restores it's
 			// original position.
 			restoreFilePosition = true;
 		}
-
-		// Looping
-		if (_diskLeft == 0 && _loop) {
-			// Reset the stream
-			_currentBlock = 0;
-			_filePos = _audioBlock[_currentBlock].pos + _beginLoop;
-			_diskLeft = _audioBlock[_currentBlock].len;
-
-			_numPlayedLoops++;
-		}
 	}
 
 	// In case calling code relies on the position of this stream staying 
@@ -496,7 +511,7 @@
 	} else {
 		const uint32 offset = seekSample - curSample;
 
-		_filePos = _audioBlock[_currentBlock].pos + offset * (is16Bit? 2: 1);
+		_filePos = _audioBlock[_currentBlock].pos + offset * (is16Bit ? 2 : 1);
 		_diskLeft = _audioBlock[_currentBlock].len - offset;
 
 		return true;
@@ -519,36 +534,24 @@
 #define MAKE_LINEAR(STEREO, UNSIGNED) \
 		if (is16Bit) { \
 			if (isLE) \
-				return new LinearMemoryStream<STEREO, true, UNSIGNED, true>(rate, ptr, len, loopOffset, loopLen, autoFree); \
+				return new LinearMemoryStream<STEREO, true, UNSIGNED, true>(rate, ptr, len, autoFree); \
 			else  \
-				return new LinearMemoryStream<STEREO, true, UNSIGNED, false>(rate, ptr, len, loopOffset, loopLen, autoFree); \
+				return new LinearMemoryStream<STEREO, true, UNSIGNED, false>(rate, ptr, len, autoFree); \
 		} else \
-			return new LinearMemoryStream<STEREO, false, UNSIGNED, false>(rate, ptr, len, loopOffset, loopLen, autoFree)
+			return new LinearMemoryStream<STEREO, false, UNSIGNED, false>(rate, ptr, len, autoFree)
 
-SeekableAudioStream *makeLinearInputStream(const byte *ptr, uint32 len, int rate, byte flags, uint loopStart, uint loopEnd) {
+SeekableAudioStream *makeLinearInputStream(const byte *ptr, uint32 len, int rate, byte flags) {
 	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 & Mixer::FLAG_LOOP) {
-		if (loopEnd == 0)
-			loopEnd = len;
-		assert(loopStart <= loopEnd);
-		assert(loopEnd <= len);
-
-		loopOffset = loopStart;
-		loopLen = loopEnd - loopStart;
-	}
-
 	// Verify the buffer sizes are sane
 	if (is16Bit && isStereo) {
-		assert((len & 3) == 0 && (loopLen & 3) == 0);
+		assert((len & 3) == 0);
 	} else if (is16Bit || isStereo) {
-		assert((len & 1) == 0 && (loopLen & 1) == 0);
+		assert((len & 1) == 0);
 	}
 
 	if (isStereo) {
@@ -567,25 +570,55 @@
 }
 
 
+AudioStream *makeLinearInputStream(const byte *ptr, uint32 len, int rate,
+                                   byte flags, uint loopStart, uint loopEnd) {
+	SeekableAudioStream *stream = makeLinearInputStream(ptr, len, rate, flags);
 
+	const bool isStereo   = (flags & Mixer::FLAG_STEREO) != 0;
+	const bool is16Bit    = (flags & Mixer::FLAG_16BITS) != 0;
+	const bool isLooping  = (flags & Mixer::FLAG_LOOP) != 0;
 
+	if (isLooping) {
+		uint loopOffset = 0, loopLen = 0;
+		if (loopEnd == 0)
+			loopEnd = len;
+		assert(loopStart <= loopEnd);
+		assert(loopEnd <= len);
 
+		loopOffset = loopStart;
+		loopLen = loopEnd - loopStart;
+
+		// Verify the buffer sizes are sane
+		if (is16Bit && isStereo)
+			assert((loopLen & 3) == 0 && (loopStart & 3) == 0 && (loopEnd & 3) == 0);
+		else if (is16Bit || isStereo)
+			assert((loopLen & 1) == 0 && (loopStart & 1) == 0 && (loopEnd & 3) == 0);
+
+		const uint32 extRate = stream->getRate() * (is16Bit ? 2 : 1) * (isStereo ? 2 : 1);
+
+		return new SubLoopingAudioStream(stream, 0, Timestamp(0, loopStart, extRate), Timestamp(0, loopEnd, extRate));
+	} else {
+		return stream;
+	}
+}
+
+
+
 #define MAKE_LINEAR_DISK(STEREO, UNSIGNED) \
 		if (is16Bit) { \
 			if (isLE) \
-				return new LinearDiskStream<STEREO, true, UNSIGNED, true>(rate, loopStart, loopEnd, takeOwnership, stream, block, numBlocks, loop); \
+				return new LinearDiskStream<STEREO, true, UNSIGNED, true>(rate, takeOwnership, stream, block, numBlocks); \
 			else  \
-				return new LinearDiskStream<STEREO, true, UNSIGNED, false>(rate, loopStart, loopEnd, takeOwnership, stream, block, numBlocks, loop); \
+				return new LinearDiskStream<STEREO, true, UNSIGNED, false>(rate, takeOwnership, stream, block, numBlocks); \
 		} else \
-			return new LinearDiskStream<STEREO, false, UNSIGNED, false>(rate, loopStart, loopEnd, takeOwnership, stream, block, numBlocks, loop)
+			return new LinearDiskStream<STEREO, false, UNSIGNED, false>(rate, takeOwnership, stream, block, numBlocks)
 
 
-SeekableAudioStream *makeLinearDiskStream(Common::SeekableReadStream *stream, LinearDiskStreamAudioBlock *block, int numBlocks, int rate, byte flags, bool takeOwnership, uint loopStart, uint loopEnd) {
+SeekableAudioStream *makeLinearDiskStream(Common::SeekableReadStream *stream, LinearDiskStreamAudioBlock *block, int numBlocks, int rate, byte flags, bool takeOwnership) {
 	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) {
@@ -602,8 +635,40 @@
 	}
 }
 
+AudioStream *makeLinearDiskStream(Common::SeekableReadStream *stream, LinearDiskStreamAudioBlock *block,
+		int numBlocks, int rate, byte flags, bool disposeStream, uint loopStart, uint loopEnd) {
+	SeekableAudioStream *s = makeLinearDiskStream(stream, block, numBlocks, rate, flags, disposeStream);
 
+	const bool isStereo   = (flags & Mixer::FLAG_STEREO) != 0;
+	const bool is16Bit    = (flags & Mixer::FLAG_16BITS) != 0;
+	const bool isLooping  = (flags & Mixer::FLAG_LOOP) != 0;
 
+	if (isLooping) {
+		uint loopOffset = 0, loopLen = 0;
+		const uint len = s->getLength().totalNumberOfFrames() / (is16Bit ? 2 : 1) / (isStereo ? 2 : 1);
+
+		if (loopEnd == 0)
+			loopEnd = len;
+		assert(loopStart <= loopEnd);
+		assert(loopEnd <= len);
+
+		loopOffset = loopStart;
+		loopLen = loopEnd - loopStart;
+
+		// Verify the buffer sizes are sane
+		if (is16Bit && isStereo)
+			assert((loopLen & 3) == 0 && (loopStart & 3) == 0 && (loopEnd & 3) == 0);
+		else if (is16Bit || isStereo)
+			assert((loopLen & 1) == 0 && (loopStart & 1) == 0 && (loopEnd & 3) == 0);
+
+		const uint32 extRate = s->getRate() * (is16Bit ? 2 : 1) * (isStereo ? 2 : 1);
+
+		return new SubLoopingAudioStream(s, 0, Timestamp(0, loopStart, extRate), Timestamp(0, loopEnd, extRate));
+	} else {
+		return s;
+	}
+}
+
 #pragma mark -
 #pragma mark --- Queueing audio stream ---
 #pragma mark -

Modified: scummvm/trunk/sound/audiostream.h
===================================================================
--- scummvm/trunk/sound/audiostream.h	2010-01-10 13:22:45 UTC (rev 47225)
+++ scummvm/trunk/sound/audiostream.h	2010-01-10 15:20:14 UTC (rev 47226)
@@ -216,6 +216,42 @@
 AudioStream *makeLoopingAudioStream(SeekableAudioStream *stream, Timestamp start, Timestamp end, uint loops);
 
 /**
+ * A looping audio stream, which features looping of a nested part of the
+ * stream.
+ *
+ * NOTE:
+ * Currently this implementation stops after the nested loop finished
+ * playback.
+ *
+ * IMPORTANT:
+ * This might be merged with SubSeekableAudioStream for playback purposes.
+ * (After extending it to accept a start time).
+ */
+class SubLoopingAudioStream : public AudioStream {
+public:
+	SubLoopingAudioStream(SeekableAudioStream *stream, uint loops,
+	                      const Timestamp loopStart,
+	                      const Timestamp loopEnd,
+	                      bool disposeAfterUse = true);
+	~SubLoopingAudioStream();
+
+	int readBuffer(int16 *buffer, const int numSamples);
+	bool endOfData() const { return _done; }
+
+	bool isStereo() const { return _parent->isStereo(); }
+	int getRate() const { return _parent->getRate(); }
+private:
+	SeekableAudioStream *_parent;
+	bool _disposeAfterUse;
+
+	uint _loops;
+	Timestamp _pos;
+	Timestamp _loopStart, _loopEnd;
+
+	bool _done;
+};
+
+/**
  * A SubSeekableAudioStream provides access to a SeekableAudioStream
  * just in the range [start, end).
  * The same caveats apply to SubSeekableAudioStream as do to SeekableAudioStream.
@@ -259,6 +295,8 @@
 	Timestamp _pos, _length;
 };
 
+SeekableAudioStream *makeLinearInputStream(const byte *ptr, uint32 len, int rate, byte flags);
+
 /**
  * Factory function for a raw linear AudioStream, which will simply treat all
  * data in the buffer described by ptr and len as raw sample data in the
@@ -267,8 +305,8 @@
  * signed native endian). Optionally supports (infinite) looping of a portion
  * of the data.
  */
-SeekableAudioStream *makeLinearInputStream(const byte *ptr, uint32 len, int rate,
-		byte flags, uint loopStart, uint loopEnd);
+AudioStream *makeLinearInputStream(const byte *ptr, uint32 len, int rate,
+                                   byte flags, uint loopStart, uint loopEnd);
 
 
 /**
@@ -279,6 +317,8 @@
 	int32 len;		///< Length of the block (in samples)
 };
 
+SeekableAudioStream *makeLinearDiskStream(Common::SeekableReadStream *stream, LinearDiskStreamAudioBlock *block,
+		int numBlocks, int rate, byte flags, bool disposeStream);
 
 /**
  * Factory function for a Linear Disk Stream.  This can stream linear (PCM)
@@ -286,7 +326,7 @@
  * LinearDiskStreamAudioBlock which defines the start position and length of
  * each block of uncompressed audio in the stream.
  */
-SeekableAudioStream *makeLinearDiskStream(Common::SeekableReadStream *stream, LinearDiskStreamAudioBlock *block,
+AudioStream *makeLinearDiskStream(Common::SeekableReadStream *stream, LinearDiskStreamAudioBlock *block,
 		int numBlocks, int rate, byte flags, bool disposeStream, uint loopStart, uint loopEnd);
 
 class QueuingAudioStream : public Audio::AudioStream {

Modified: scummvm/trunk/sound/voc.cpp
===================================================================
--- scummvm/trunk/sound/voc.cpp	2010-01-10 13:22:45 UTC (rev 47225)
+++ scummvm/trunk/sound/voc.cpp	2010-01-10 15:20:14 UTC (rev 47226)
@@ -298,7 +298,7 @@
 	return currentBlock;
 }
 
-SeekableAudioStream *makeVOCDiskStream(Common::SeekableReadStream &stream, byte flags, bool takeOwnership) {
+AudioStream *makeVOCDiskStream(Common::SeekableReadStream &stream, byte flags, bool takeOwnership) {
 	const int MAX_AUDIO_BLOCKS = 256;
 
 	LinearDiskStreamAudioBlock *block = new LinearDiskStreamAudioBlock[MAX_AUDIO_BLOCKS];
@@ -317,11 +317,31 @@
 
 	return audioStream;
 }
-	
+
+SeekableAudioStream *makeVOCDiskStreamNoLoop(Common::SeekableReadStream &stream, byte flags, bool takeOwnership) {
+	const int MAX_AUDIO_BLOCKS = 256;
+
+	LinearDiskStreamAudioBlock *block = new LinearDiskStreamAudioBlock[MAX_AUDIO_BLOCKS];
+	int rate, loops, begin_loop, end_loop;
+
+	int numBlocks = parseVOCFormat(stream, block, rate, loops, begin_loop, end_loop);
+
+	SeekableAudioStream *audioStream = 0;
+
+	// Create an audiostream from the data. Note the numBlocks may be 0,
+	// e.g. when invalid data is encountered. See bug #2890038.
+	if (numBlocks)
+		audioStream = makeLinearDiskStream(&stream, block, numBlocks, rate, flags, takeOwnership);
+
+	delete[] block;
+
+	return audioStream;
+}
+
 #endif
 
 
-SeekableAudioStream *makeVOCStream(Common::SeekableReadStream &stream, byte flags, uint loopStart, uint loopEnd, bool takeOwnershipOfStream) {
+AudioStream *makeVOCStream(Common::SeekableReadStream &stream, byte flags, uint loopStart, uint loopEnd, bool takeOwnershipOfStream) {
 #ifdef STREAM_AUDIO_FROM_DISK
 	return makeVOCDiskStream(stream, flags, takeOwnershipOfStream);
 #else
@@ -336,5 +356,19 @@
 #endif
 }
 
+SeekableAudioStream *makeVOCStream(Common::SeekableReadStream &stream, byte flags, bool takeOwnershipOfStream) {
+#ifdef STREAM_AUDIO_FROM_DISK
+	return makeVOCDiskStreamNoLoop(stream, flags, takeOwnershipOfStream);
+#else
+	int size, rate;
 
+	byte *data = loadVOCFromStream(stream, size, rate);
+
+	if (!data)
+		return 0;
+
+	return makeLinearInputStream(data, size, rate, flags | Audio::Mixer::FLAG_AUTOFREE);
+#endif
+}
+
 } // End of namespace Audio

Modified: scummvm/trunk/sound/voc.h
===================================================================
--- scummvm/trunk/sound/voc.h	2010-01-10 13:22:45 UTC (rev 47225)
+++ scummvm/trunk/sound/voc.h	2010-01-10 15:20:14 UTC (rev 47226)
@@ -93,8 +93,13 @@
  *
  * This function uses loadVOCFromStream() internally.
  */
-SeekableAudioStream *makeVOCStream(Common::SeekableReadStream &stream, byte flags = 0, uint loopStart = 0, uint loopEnd = 0, bool takeOwnershipOfStream = false);
+AudioStream *makeVOCStream(Common::SeekableReadStream &stream, byte flags = 0, uint loopStart = 0, uint loopEnd = 0, bool takeOwnershipOfStream = false);
 
+/**
+ * This does not use any of the looping features from VOC files!
+ */
+SeekableAudioStream *makeVOCStream(Common::SeekableReadStream &stream, byte flags, bool takeOwnershipOfStream);
+
 } // End of namespace Audio
 
 #endif

Modified: scummvm/trunk/sound/wave.cpp
===================================================================
--- scummvm/trunk/sound/wave.cpp	2010-01-10 13:22:45 UTC (rev 47225)
+++ scummvm/trunk/sound/wave.cpp	2010-01-10 15:20:14 UTC (rev 47226)
@@ -190,7 +190,7 @@
 	// Since we allocated our own buffer for the data, we must set the autofree flag.
 	flags |= Audio::Mixer::FLAG_AUTOFREE;
 
-	return makeLinearInputStream(data, size, rate, flags, 0, 0);
+	return makeLinearInputStream(data, size, rate, flags);
 }
 
 } // End of namespace Audio


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