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

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Thu Jan 7 15:22:24 CET 2010


Revision: 47111
          http://scummvm.svn.sourceforge.net/scummvm/?rev=47111&view=rev
Author:   lordhoto
Date:     2010-01-07 14:22:24 +0000 (Thu, 07 Jan 2010)

Log Message:
-----------
- Strip custom looping code out of FLAC, Vorbis and MP3 streams
- Adapt the legacy make*Stream factories to use the new AudioStream subclasses
- Change return value of make*Stream back to AudioStream *

Modified Paths:
--------------
    scummvm/trunk/engines/tucker/resource.cpp
    scummvm/trunk/sound/flac.cpp
    scummvm/trunk/sound/flac.h
    scummvm/trunk/sound/mp3.cpp
    scummvm/trunk/sound/mp3.h
    scummvm/trunk/sound/vorbis.cpp
    scummvm/trunk/sound/vorbis.h

Modified: scummvm/trunk/engines/tucker/resource.cpp
===================================================================
--- scummvm/trunk/engines/tucker/resource.cpp	2010-01-07 14:21:13 UTC (rev 47110)
+++ scummvm/trunk/engines/tucker/resource.cpp	2010-01-07 14:22:24 UTC (rev 47111)
@@ -43,7 +43,7 @@
 
 struct CompressedSoundFile {
 	const char *filename;
-	Audio::SeekableAudioStream *(*makeStream)(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 startTime, uint32 duration, uint numLoops);
+	Audio::AudioStream *(*makeStream)(Common::SeekableReadStream *stream, bool disposeAfterUse, uint32 startTime, uint32 duration, uint numLoops);
 };
 
 static const CompressedSoundFile compressedSoundFilesTable[] = {

Modified: scummvm/trunk/sound/flac.cpp
===================================================================
--- scummvm/trunk/sound/flac.cpp	2010-01-07 14:21:13 UTC (rev 47110)
+++ scummvm/trunk/sound/flac.cpp	2010-01-07 14:22:24 UTC (rev 47111)
@@ -92,18 +92,12 @@
 	/** Header of the stream */
 	FLAC__StreamMetadata_StreamInfo _streaminfo;
 
-	/** index of the first sample to be played */
-	FLAC__uint64 _firstSample;
-
 	/** index + 1(!) of the last sample to be played */
 	FLAC__uint64 _lastSample;
 
 	/** total play time */
-	int32 _totalPlayTime;
+	Timestamp _length;
 
-	uint _numLoops;			///< Number of loops to play
-	uint _numPlayedLoops;	///< Number of loops which have been played
-
 	/** true if the last sample was decoded from the FLAC-API - there might still be data in the buffer */
 	bool _lastSampleWritten;
 
@@ -130,7 +124,7 @@
 
 
 public:
-	FlacInputStream(Common::SeekableReadStream *inStream, bool dispose, uint startTime = 0, uint endTime = 0, uint numLoops = 1);
+	FlacInputStream(Common::SeekableReadStream *inStream, bool dispose);
 	virtual ~FlacInputStream();
 
 	int readBuffer(int16 *buffer, const int numSamples);
@@ -144,17 +138,9 @@
 	}
 
 	bool seek(const Timestamp &where);
-	// TODO: We can definitly increase the precision here, since FLAC allows us to catch the sample count
-	Timestamp getLength() const { return Timestamp(_totalPlayTime, getRate()); }
+	Timestamp getLength() const { return _length; }
 
 	bool isStreamDecoderReady() const { return getStreamDecoderState() == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ; }
-
-	void setNumLoops(uint numLoops = 1) {
-		_numLoops = numLoops;
-		_numPlayedLoops = 0;
-	}
-	uint getNumPlayedLoops() { return _numPlayedLoops; }
-
 protected:
 	uint getChannels() const { return MIN<uint>(_streaminfo.channels, MAX_OUTPUT_CHANNELS); }
 
@@ -193,7 +179,7 @@
 	static void convertBuffersMono8Bit(SampleType* bufDestination, const FLAC__int32 *inChannels[], uint numSamples, const uint numChannels, const uint8 numBits);
 };
 
-FlacInputStream::FlacInputStream(Common::SeekableReadStream *inStream, bool dispose, uint startTime, uint endTime, uint numLoops)
+FlacInputStream::FlacInputStream(Common::SeekableReadStream *inStream, bool dispose)
 #ifdef LEGACY_FLAC
 			:	_decoder(::FLAC__seekable_stream_decoder_new()),
 #else
@@ -201,9 +187,7 @@
 #endif
 		_inStream(inStream),
 		_disposeAfterUse(dispose),
-		_numLoops(numLoops),
-		_numPlayedLoops(0),
-		_firstSample(0), _lastSample(0),
+		_length(0, 1000), _lastSample(0),
 		_outBuffer(NULL), _requestedSamples(0), _lastSampleWritten(false),
 		_methodConvertBuffers(&FlacInputStream::convertBuffersGeneric)
 {
@@ -244,34 +228,9 @@
 #endif
 	if (success) {
 		if (processUntilEndOfMetadata() && _streaminfo.channels > 0) {
-			// Compute the start/end sample (we use floating point arithmetics here to
-			// avoid overflows).
-			_firstSample = (FLAC__uint64)(startTime * (_streaminfo.sample_rate / 1000.0));
-			_lastSample = !endTime ? _streaminfo.total_samples + 1 : (FLAC__uint64)(endTime * (_streaminfo.sample_rate / 1000.0));
-
-			if (_firstSample == 0 || seekAbsolute(_firstSample)) {
-				int32 samples = -1;
-
-				if (!_lastSample) {
-					if (_streaminfo.total_samples)
-						samples = _streaminfo.total_samples - _firstSample;
-				} else {
-					samples = _lastSample - _firstSample - 1;
-				}
-
-				if (samples != -1 && samples >= 0 && numLoops) {
-					const int32 rate = _streaminfo.sample_rate;
-
-					int32 seconds = samples / rate;
-					int32 milliseconds = (1000 * (samples % rate)) / rate;
-
-					_totalPlayTime = (seconds * 1000 + milliseconds);
-				} else {
-					_totalPlayTime = 0;
-				}
-
-				return; // no error occured
-			}
+			_lastSample = _streaminfo.total_samples + 1;
+			_length = Timestamp(0, _lastSample - 1, getRate());
+			return; // no error occured
 		}
 	}
 
@@ -381,16 +340,8 @@
 		processSingleBlock();
 		state = getStreamDecoderState();
 
-		if (state == FLAC__STREAM_DECODER_END_OF_STREAM) {
+		if (state == FLAC__STREAM_DECODER_END_OF_STREAM)
 			_lastSampleWritten = true;
-			++_numPlayedLoops;
-		}
-
-		// If we reached the end of the stream, and looping is enabled: Try to rewind
-		if (_lastSampleWritten && (!_numLoops || _numPlayedLoops < _numLoops)) {
-			seekAbsolute(_firstSample);
-			state = getStreamDecoderState();
-		}
 	}
 
 	// Error handling
@@ -774,27 +725,36 @@
 #pragma mark -
 
 
-SeekableAudioStream *makeFlacStream(
+AudioStream *makeFlacStream(
 	Common::SeekableReadStream *stream,
 	bool disposeAfterUse,
 	uint32 startTime,
 	uint32 duration,
 	uint numLoops) {
 
-	uint32 endTime = duration ? (startTime + duration) : 0;
+	SeekableAudioStream *input = new FlacInputStream(stream, disposeAfterUse);
+	assert(input);
 
-	FlacInputStream *input = new FlacInputStream(stream, disposeAfterUse, startTime, endTime, numLoops);
-	if (!input->isStreamDecoderReady()) {
-		delete input;
-		return 0;
+	if (startTime || duration) {
+		Timestamp start(startTime, 1000), end(startTime + duration, 1000);
+
+		if (!duration)
+			end = input->getLength();
+
+		input = new SubSeekableAudioStream(input, start, end);
+		assert(input);
 	}
-	return input;
+
+	if (numLoops)
+		return new LoopingAudioStream(input, numLoops);
+	else
+		return input;
 }
 
 SeekableAudioStream *makeFlacStream(
 	Common::SeekableReadStream *stream,
 	bool disposeAfterUse) {
-	return makeFlacStream(stream, disposeAfterUse, 0, 0, 1);
+	return new FlacInputStream(stream, disposeAfterUse);
 }
 
 } // End of namespace Audio

Modified: scummvm/trunk/sound/flac.h
===================================================================
--- scummvm/trunk/sound/flac.h	2010-01-07 14:21:13 UTC (rev 47110)
+++ scummvm/trunk/sound/flac.h	2010-01-07 14:22:24 UTC (rev 47111)
@@ -51,6 +51,7 @@
 
 namespace Audio {
 
+class AudioStream;
 class SeekableAudioStream;
 
 /**
@@ -69,7 +70,7 @@
  * @param numLoops			how often the data shall be looped (0 = infinite)
  * @return	a new AudioStream, or NULL, if an error occured
  */
-SeekableAudioStream *makeFlacStream(
+AudioStream *makeFlacStream(
 	Common::SeekableReadStream *stream,
 	bool disposeAfterUse,
 	uint32 startTime,

Modified: scummvm/trunk/sound/mp3.cpp
===================================================================
--- scummvm/trunk/sound/mp3.cpp	2010-01-07 14:21:13 UTC (rev 47110)
+++ scummvm/trunk/sound/mp3.cpp	2010-01-07 14:22:24 UTC (rev 47111)
@@ -59,16 +59,9 @@
 	uint _posInFrame;
 	State _state;
 
-	const mad_timer_t _startTime;
-	const mad_timer_t _endTime;
+	Timestamp _length;
 	mad_timer_t _totalTime;
 
-	int32 _totalPlayTime; // Length of one loop iteration
-	uint32 _length;       // Total length of the MP3 stream
-
-	uint _numLoops;			///< Number of loops to play
-	uint _numPlayedLoops;	///< Number of loops which have been played
-
 	mad_stream _stream;
 	mad_frame _frame;
 	mad_synth _synth;
@@ -82,10 +75,7 @@
 
 public:
 	MP3InputStream(Common::SeekableReadStream *inStream,
-	               bool dispose,
-	               mad_timer_t start = mad_timer_zero,
-	               mad_timer_t end = mad_timer_zero,
-	               uint numLoops = 1);
+	               bool dispose);
 	~MP3InputStream();
 
 	int readBuffer(int16 *buffer, const int numSamples);
@@ -95,15 +85,7 @@
 	int getRate() const			{ return _frame.header.samplerate; }
 
 	bool seek(const Timestamp &where);
-	// TODO: Maybe we can have a more precise implementation of this
-	Timestamp getLength() const { return Timestamp(_totalPlayTime, getRate()); }
-
-	void setNumLoops(uint numLoops) {
-		_numLoops = numLoops;
-		_numPlayedLoops = 0;
-	}
-	uint getNumPlayedLoops() { return _numPlayedLoops; }
-
+	Timestamp getLength() const { return _length; }
 protected:
 	void decodeMP3Data();
 	void readMP3Data();
@@ -113,19 +95,14 @@
 	void deinitStream();
 };
 
-MP3InputStream::MP3InputStream(Common::SeekableReadStream *inStream, bool dispose, mad_timer_t start, mad_timer_t end, uint numLoops) :
+MP3InputStream::MP3InputStream(Common::SeekableReadStream *inStream, bool dispose) :
 	_inStream(inStream),
 	_disposeAfterUse(dispose),
-	_numLoops(numLoops),
 	_posInFrame(0),
 	_state(MP3_STATE_INIT),
-	_startTime(start),
-	_endTime(end),
+	_length(0, 1000),
 	_totalTime(mad_timer_zero) {
 
-	// Make sure that either start < end, or end is zero (indicating "play until end")
-	assert(mad_timer_compare(_startTime, _endTime) < 0 || mad_timer_sign(_endTime) == 0);
-
 	// The MAD_BUFFER_GUARD must always contain zeros (the reason
 	// for this is that the Layer III Huffman decoder of libMAD
 	// may read a few bytes beyond the end of the input buffer).
@@ -137,33 +114,13 @@
 	while (_state != MP3_STATE_EOS)
 		readHeader();
 
-	_length = mad_timer_count(_totalTime, MAD_UNITS_MILLISECONDS);
+	_length = Timestamp(mad_timer_count(_totalTime, MAD_UNITS_MILLISECONDS), getRate());
 
 	deinitStream();
 
 	// Reinit stream
 	_state = MP3_STATE_INIT;
 
-	// Calculate play time
-	mad_timer_t length;
-
-	mad_timer_set(&length, 0, 0, 1000);
-	mad_timer_add(&length, start);
-	mad_timer_negate(&length);
-
-	if (mad_timer_sign(end) != 0) {
-		mad_timer_add(&length, end);
-	} else {
-		mad_timer_set(&_totalTime, _length / 1000, _length % 1000, 1000);
-		mad_timer_add(&length, _totalTime);
-		_totalTime = mad_timer_zero;
-	}
-
-	_totalPlayTime = mad_timer_count(length, MAD_UNITS_MILLISECONDS);
-
-	if (mad_timer_sign(length) < 0)
-		_totalPlayTime = 0;
-
 	// Decode the first chunk of data. This is necessary so that _frame
 	// is setup and isStereo() and getRate() return correct results.
 	decodeMP3Data();
@@ -189,18 +146,9 @@
 			readMP3Data();
 
 		while (_state == MP3_STATE_READY) {
+			// TODO: Do we need to use readHeader, when we do not do any seeking here?
 			readHeader();
 
-			// If we have not yet reached the start point, skip to the next frame
-			if (mad_timer_compare(_totalTime, _startTime) < 0)
-				continue;
-
-			// If an end time is specified and we are past it, stop
-			if (mad_timer_sign(_endTime) > 0 && mad_timer_compare(_totalTime, _endTime) >= 0) {
-				_state = MP3_STATE_EOS;
-				break;
-			}
-
 			// Decode the next frame
 			if (mad_frame_decode(&_frame, &_stream) == -1) {
 				if (_stream.error == MAD_ERROR_BUFLEN) {
@@ -222,18 +170,6 @@
 			_posInFrame = 0;
 			break;
 		}
-
-		if (_state == MP3_STATE_EOS) {
-			++_numPlayedLoops;
-			// If looping is on and there are loops left, rewind to the start
-			if (!_numLoops || _numPlayedLoops < _numLoops) {
-				deinitStream();
-
-				// Reset the decoder state to indicate we should start over
-				_state = MP3_STATE_INIT;
-			}
-		}
-
 	} while (_state != MP3_STATE_EOS && _stream.error == MAD_ERROR_BUFLEN);
 
 	if (_stream.error != MAD_ERROR_NONE)
@@ -271,15 +207,15 @@
 }
 
 bool MP3InputStream::seek(const Timestamp &where) {
-	const uint32 time = where.msecs();
-
-	if (time == _length) {
+	if (where == _length) {
 		_state = MP3_STATE_EOS;
 		return true;
-	} else if (time > _length) {
+	} else if (where > _length) {
 		return false;
 	}
 
+	const uint32 time = where.msecs();
+
 	mad_timer_t destination;
 	mad_timer_set(&destination, time / 1000, time % 1000, 1000);
 
@@ -402,33 +338,36 @@
 #pragma mark --- MP3 factory functions ---
 #pragma mark -
 
-SeekableAudioStream *makeMP3Stream(
+AudioStream *makeMP3Stream(
 	Common::SeekableReadStream *stream,
 	bool disposeAfterUse,
 	uint32 startTime,
 	uint32 duration,
 	uint numLoops) {
 
-	mad_timer_t start;
-	mad_timer_t end;
+	SeekableAudioStream *mp3 = new MP3InputStream(stream, disposeAfterUse);
+	assert(mp3);
 
-	// Both startTime and duration are given in milliseconds.
-	// Calculate the appropriate mad_timer_t values from them.
-	mad_timer_set(&start, startTime / 1000, startTime % 1000, 1000);
-	if (duration == 0) {
-		end = mad_timer_zero;
-	} else {
-		int endTime = startTime + duration;
-		mad_timer_set(&end, endTime / 1000, endTime % 1000, 1000);
+	if (startTime || duration) {
+		Timestamp start(startTime, 1000), end(startTime + duration, 1000);
+
+		if (!duration)
+			end = mp3->getLength();
+
+		mp3 = new SubSeekableAudioStream(mp3, start, end);
+		assert(mp3);
 	}
 
-	return new MP3InputStream(stream, disposeAfterUse, start, end, numLoops);
+	if (numLoops)
+		return new LoopingAudioStream(mp3, numLoops);
+	else
+		return mp3;
 }
 
 SeekableAudioStream *makeMP3Stream(
 	Common::SeekableReadStream *stream,
 	bool disposeAfterUse) {
-	return makeMP3Stream(stream, disposeAfterUse, 0, 0, 1);
+	return new MP3InputStream(stream, disposeAfterUse);
 }
 
 } // End of namespace Audio

Modified: scummvm/trunk/sound/mp3.h
===================================================================
--- scummvm/trunk/sound/mp3.h	2010-01-07 14:21:13 UTC (rev 47110)
+++ scummvm/trunk/sound/mp3.h	2010-01-07 14:22:24 UTC (rev 47111)
@@ -51,6 +51,7 @@
 
 namespace Audio {
 
+class AudioStream;
 class SeekableAudioStream;
 
 /**
@@ -69,7 +70,7 @@
  * @param numLoops			how often the data shall be looped (0 = infinite)
  * @return	a new SeekableAudioStream, or NULL, if an error occured
  */
-SeekableAudioStream *makeMP3Stream(
+AudioStream *makeMP3Stream(
 	Common::SeekableReadStream *stream,
 	bool disposeAfterUse,
 	uint32 startTime,

Modified: scummvm/trunk/sound/vorbis.cpp
===================================================================
--- scummvm/trunk/sound/vorbis.cpp	2010-01-07 14:21:13 UTC (rev 47110)
+++ scummvm/trunk/sound/vorbis.cpp	2010-01-07 14:22:24 UTC (rev 47111)
@@ -93,17 +93,8 @@
 	bool _isStereo;
 	int _rate;
 
-	uint _numLoops;			///< Number of loops to play
-	uint _numPlayedLoops;	///< Number of loops which have been played
+	Timestamp _length;
 
-#ifdef USE_TREMOR
-	ogg_int64_t _startTime;
-	ogg_int64_t _endTime;
-#else
-	double _startTime;
-	double _endTime;
-#endif
-
 	OggVorbis_File _ovFile;
 
 	int16 _buffer[4096];
@@ -112,7 +103,7 @@
 
 public:
 	// startTime / duration are in milliseconds
-	VorbisInputStream(Common::SeekableReadStream *inStream, bool dispose, uint startTime = 0, uint endTime = 0, uint numLoops = 1);
+	VorbisInputStream(Common::SeekableReadStream *inStream, bool dispose);
 	~VorbisInputStream();
 
 	int readBuffer(int16 *buffer, const int numSamples);
@@ -121,30 +112,16 @@
 	bool isStereo() const		{ return _isStereo; }
 	int getRate() const			{ return _rate; }
 
-	void setNumLoops(uint numLoops) {
-		_numLoops = numLoops;
-		_numPlayedLoops = 0;
-	}
-	uint getNumPlayedLoops() { return _numPlayedLoops; }
-
 	bool seek(const Timestamp &where);
-	// TODO: Maybe we can have a more precise implementation of this
-	Timestamp getLength() const {
-#ifdef USE_TREMOR
-		return Timestamp(_endTime, getRate());
-#else
-		return Timestamp((uint32)(_endTime * 1000.0), getRate());
-#endif
-	}
-
+	Timestamp getLength() const { return _length; }
 protected:
 	bool refill();
 };
 
-VorbisInputStream::VorbisInputStream(Common::SeekableReadStream *inStream, bool dispose, uint startTime, uint endTime, uint numLoops) :
+VorbisInputStream::VorbisInputStream(Common::SeekableReadStream *inStream, bool dispose) :
 	_inStream(inStream),
 	_disposeAfterUse(dispose),
-	_numLoops(numLoops),
+	_length(0, 1000),
 	_bufferEnd(_buffer + ARRAYSIZE(_buffer)) {
 
 	int res = ov_open_callbacks(inStream, &_ovFile, NULL, 0, g_stream_wrap);
@@ -155,41 +132,11 @@
 	}
 
 #ifdef USE_TREMOR
-	/* TODO: Symbian may have to use scumm_fixdfdi here? To quote:
-	 "SumthinWicked says: fixing "relocation truncated to fit: ARM_26 __fixdfdi" during linking on GCC, see portdefs.h"
-	*/
-
-	// In Tremor, the ov_time_seek() and ov_time_seek_page() calls take seeking
-	// positions in milliseconds as 64 bit integers, rather than in seconds as
-	// doubles as in Vorbisfile.
-	ogg_int64_t totalTime;
-	_startTime = startTime;
-	_endTime = endTime;
+	_length = Timestamp(ov_time_total(&_ovFile, -1), getRate());
 #else
-	double totalTime;
-	_startTime = startTime / 1000.0;
-	_endTime = endTime / 1000.0;
+	_length = Timestamp(ov_time_total(&_ovFile, -1) * 1000.0, getRate());
 #endif
 
-	// If endTime was 0, or is past the end of the file, set it to the maximal time possible
-	totalTime = ov_time_total(&_ovFile, -1);
-	if (_endTime == 0 || _endTime > totalTime)
-		_endTime = totalTime;
-
-	// If the specified time range is empty, abort early.
-	if (_startTime >= _endTime) {
-		_pos = _bufferEnd;
-		return;
-	}
-
-	// Seek to the start position
-	res = ov_time_seek(&_ovFile, _startTime);
-	if (res < 0) {
-		warning("Error seeking in Vorbis stream (%d)", res);
-		_pos = _bufferEnd;
-		return;
-	}
-
 	// Read in initial data
 	if (!refill())
 		return;
@@ -206,7 +153,7 @@
 }
 
 int VorbisInputStream::readBuffer(int16 *buffer, const int numSamples) {
-	int res, samples = 0;
+	int samples = 0;
 	while (samples < numSamples && _pos < _bufferEnd) {
 		const int len = MIN(numSamples - samples, (int)(_bufferEnd - _pos));
 		memcpy(buffer, _pos, len * 2);
@@ -216,24 +163,6 @@
 		if (_pos >= _bufferEnd) {
 			if (!refill())
 				break;
-
-			// If we are still out of data, and also past the end of specified
-			// time range, check whether looping is enabled...
-			if (_pos >= _bufferEnd && ov_time_tell(&_ovFile) >= _endTime) {
-				++_numPlayedLoops;
-				// If looping is on and there are loops left, rewind to the start
-				if (!_numLoops || _numPlayedLoops < _numLoops) {
-					res = ov_time_seek(&_ovFile, _startTime);
-					if (res < 0) {
-						warning("Error seeking in Vorbis stream (%d)", res);
-						_pos = _bufferEnd;
-						break;
-					}
-
-					if (!refill())
-						break;
-				}
-			}
 		}
 	}
 	return samples;
@@ -252,26 +181,12 @@
 
 bool VorbisInputStream::refill() {
 	// Read the samples
-	int res;
 	uint len_left = sizeof(_buffer);
 	char *read_pos = (char *)_buffer;
 
 	while (len_left > 0) {
-		if (ov_time_tell(&_ovFile) >= _endTime) {
-			// If looping is on and there are loops left, rewind to the start
-			if (_numLoops == 1)
-				break;	// Last loop, abort
-			if (_numLoops != 0)
-				_numLoops--;
-			res = ov_time_seek(&_ovFile, _startTime);
-			if (res < 0) {
-				warning("Error seeking in Vorbis stream (%d)", res);
-				_pos = _bufferEnd;
-				return false;
-			}
-		}
-
 		long result;
+
 #ifdef USE_TREMOR
 		// Tremor ov_read() always returns data as signed 16 bit interleaved PCM
 		// in host byte order. As such, it does not take arguments to request
@@ -297,9 +212,10 @@
 			// Possibly recoverable, just warn about it
 			warning("Corrupted data in Vorbis file");
 		} else if (result == 0) {
-			warning("End of file while reading from Vorbis file");
-			_pos = _bufferEnd;
-			return false;
+			//warning("End of file while reading from Vorbis file");
+			//_pos = _bufferEnd;
+			//return false;
+			break;
 		} else if (result < 0) {
 			warning("Error reading from Vorbis stream (%d)", int(result));
 			_pos = _bufferEnd;
@@ -324,29 +240,36 @@
 #pragma mark -
 
 
-SeekableAudioStream *makeVorbisStream(
+AudioStream *makeVorbisStream(
 	Common::SeekableReadStream *stream,
 	bool disposeAfterUse,
 	uint32 startTime,
 	uint32 duration,
 	uint numLoops) {
 
-	uint32 endTime = duration ? (startTime + duration) : 0;
+	SeekableAudioStream *input = new VorbisInputStream(stream, disposeAfterUse);
+	assert(input);
 
-	VorbisInputStream *input = new VorbisInputStream(stream, disposeAfterUse, startTime, endTime, numLoops);
+	if (startTime || duration) {
+		Timestamp start(startTime, 1000), end(startTime + duration, 1000);
 
-	if (input->endOfData()) {
-		delete input;
-		return 0;
+		if (!duration)
+			end = input->getLength();
+
+		input = new SubSeekableAudioStream(input, start, end);
+		assert(input);
 	}
 
-	return input;
+	if (numLoops)
+		return new LoopingAudioStream(input, numLoops);
+	else
+		return input;
 }
 
 SeekableAudioStream *makeVorbisStream(
 	Common::SeekableReadStream *stream,
 	bool disposeAfterUse) {
-	return makeVorbisStream(stream, disposeAfterUse, 0, 0, 1);
+	return new VorbisInputStream(stream, disposeAfterUse);
 }
 
 } // End of namespace Audio

Modified: scummvm/trunk/sound/vorbis.h
===================================================================
--- scummvm/trunk/sound/vorbis.h	2010-01-07 14:21:13 UTC (rev 47110)
+++ scummvm/trunk/sound/vorbis.h	2010-01-07 14:22:24 UTC (rev 47111)
@@ -51,6 +51,7 @@
 
 namespace Audio {
 
+class AudioStream;
 class SeekableAudioStream;
 
 /**
@@ -69,7 +70,7 @@
  * @param numLoops			how often the data shall be looped (0 = infinite)
  * @return	a new SeekableAudioStream, or NULL, if an error occured
  */
-SeekableAudioStream *makeVorbisStream(
+AudioStream *makeVorbisStream(
 	Common::SeekableReadStream *stream,
 	bool disposeAfterUse,
 	uint32 startTime,


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