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

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Thu Feb 22 15:30:14 CET 2007


Revision: 25789
          http://scummvm.svn.sourceforge.net/scummvm/?rev=25789&view=rev
Author:   fingolfin
Date:     2007-02-22 06:30:12 -0800 (Thu, 22 Feb 2007)

Log Message:
-----------
Added looping support and an enhanced factory function to the Vorbis code

Modified Paths:
--------------
    scummvm/trunk/sound/mp3.cpp
    scummvm/trunk/sound/vorbis.cpp
    scummvm/trunk/sound/vorbis.h

Modified: scummvm/trunk/sound/mp3.cpp
===================================================================
--- scummvm/trunk/sound/mp3.cpp	2007-02-22 14:07:12 UTC (rev 25788)
+++ scummvm/trunk/sound/mp3.cpp	2007-02-22 14:30:12 UTC (rev 25789)
@@ -208,10 +208,11 @@
 			break;
 		}
 	
-		if (_eos) {
-			// If looping is enabled, rewind to the start
-			if (_numLoops == 0 || --_numLoops > 0)
-				rewind();
+		if (_eos && _numLoops != 1) {
+			// If looping is on and there are loops left, rewind to the start
+			if (_numLoops != 0)
+				_numLoops--;
+			rewind();
 		}
 
 	} while (_stream.error == MAD_ERROR_BUFLEN);

Modified: scummvm/trunk/sound/vorbis.cpp
===================================================================
--- scummvm/trunk/sound/vorbis.cpp	2007-02-22 14:07:12 UTC (rev 25788)
+++ scummvm/trunk/sound/vorbis.cpp	2007-02-22 14:30:12 UTC (rev 25789)
@@ -86,17 +86,12 @@
 
 class VorbisInputStream : public AudioStream {
 protected:
-	OggVorbis_File _ovFile;
-
 	Common::SeekableReadStream *_inStream;
 	bool _disposeAfterUse;
 
-	int16 _buffer[4096];
-	const int16 *_bufferEnd;
-	const int16 *_pos;
-	
 	bool _isStereo;
 	int _rate;
+	uint _numLoops;
 	
 #ifdef USE_TREMOR
 	ogg_int64_t _startTime;
@@ -106,25 +101,31 @@
 	double _endTime;
 #endif
 
-	void refill();
-	inline bool eosIntern() const;
+	OggVorbis_File _ovFile;
+
+	int16 _buffer[4096];
+	const int16 *_bufferEnd;
+	const int16 *_pos;
+	
 public:
 	// startTime / duration are in milliseconds
-	VorbisInputStream(Common::SeekableReadStream *inStream, bool dispose, uint startTime = 0, uint endTime = 0);
+	VorbisInputStream(Common::SeekableReadStream *inStream, bool dispose, uint startTime = 0, uint endTime = 0, uint numLoops = 1);
 	~VorbisInputStream();
 
 	int readBuffer(int16 *buffer, const int numSamples);
 
-	bool endOfData() const		{ return eosIntern(); }
+	bool endOfData() const		{ return _pos >= _bufferEnd; }
 	bool isStereo() const		{ return _isStereo; }
-
 	int getRate() const			{ return _rate; }
 
+protected:
+	void refill();
 };
 
-VorbisInputStream::VorbisInputStream(Common::SeekableReadStream *inStream, bool dispose, uint startTime, uint endTime) :
+VorbisInputStream::VorbisInputStream(Common::SeekableReadStream *inStream, bool dispose, uint startTime, uint endTime, uint numLoops) :
 	_inStream(inStream),
 	_disposeAfterUse(dispose),
+	_numLoops(numLoops),
 	_bufferEnd(_buffer + ARRAYSIZE(_buffer)) {
 
 	bool err = (ov_open_callbacks(inStream, &_ovFile, NULL, 0, g_stream_wrap) < 0);
@@ -176,13 +177,9 @@
 		delete _inStream;
 }
 
-inline bool VorbisInputStream::eosIntern() const {
-	return _pos >= _bufferEnd;
-}
-
 int VorbisInputStream::readBuffer(int16 *buffer, const int numSamples) {
 	int samples = 0;
-	while (samples < numSamples && !eosIntern()) {
+	while (samples < numSamples && _pos < _bufferEnd) {
 		const int len = MIN(numSamples - samples, (int)(_bufferEnd - _pos));
 		memcpy(buffer, _pos, len * 2);
 		buffer += len;
@@ -190,6 +187,17 @@
 		samples += len;
 		if (_pos >= _bufferEnd) {
 			refill();
+			// 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) {
+				if (_numLoops != 1) {
+					// If looping is on and there are loops left, rewind to the start
+					if (_numLoops != 0)
+						_numLoops--;
+					ov_time_seek(&_ovFile, _startTime);
+					refill();
+				}
+			}
 		}
 	}
 	return samples;
@@ -200,7 +208,16 @@
 	uint len_left = sizeof(_buffer);
 	char *read_pos = (char *)_buffer;
 
-	while (len_left > 0 && ov_time_tell(&_ovFile) < _endTime) {
+	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--;
+			ov_time_seek(&_ovFile, _startTime);
+		}
+
 		long result;
 #ifdef USE_TREMOR
 		// Tremor ov_read() always returns data as signed 16 bit interleaved PCM
@@ -260,7 +277,20 @@
 	return new VorbisInputStream(stream, true);
 }
 
+AudioStream *makeVorbisStream(
+	Common::SeekableReadStream *stream,
+	bool disposeAfterUse,
+	uint32 startTime,
+	uint32 duration,
+	uint numLoops) {
 
+	uint32 endTime = duration ? (startTime + duration) : 0;
+
+	return new VorbisInputStream(stream, disposeAfterUse, startTime, endTime, numLoops);
+}
+
+
+
 #pragma mark -
 #pragma mark --- Ogg Vorbis Audio CD emulation ---
 #pragma mark -

Modified: scummvm/trunk/sound/vorbis.h
===================================================================
--- scummvm/trunk/sound/vorbis.h	2007-02-22 14:07:12 UTC (rev 25788)
+++ scummvm/trunk/sound/vorbis.h	2007-02-22 14:30:12 UTC (rev 25789)
@@ -30,6 +30,7 @@
 
 namespace Common {
 	class File;
+	class SeekableReadStream;
 }
 
 namespace Audio {
@@ -40,13 +41,34 @@
 DigitalTrackInfo *getVorbisTrack(int track);
 
 /**
- * Create a new AudioStream from the Vorbis data in the given
+ * Create a new AudioStream from the Ogg Vorbis data in the given
  * file. If you only want to play part of that file, then seek
  * to the start position in file before passing it to this
  * factory function, and specify the appropriate size.
  */
 AudioStream *makeVorbisStream(Common::File *file, uint32 size);
 
+
+/**
+ * Create a new AudioStream from the Ogg Vorbis data in the given stream.
+ * Allows for looping (which is why we require a SeekableReadStream),
+ * and specifying only a portion of the data to be played, based 
+ * on time offsets.
+ *
+ * @param stream			the SeekableReadStream from which to read the MP3 data
+ * @param disposeAfterUse	whether to delete the stream after use
+ * @param startTime			the (optional) time offset in milliseconds from which to start playback 
+ * @param duration			the (optional) time in milliseconds specifying how long to play
+ * @param numLoops			how often the data shall be looped (0 = infinite)
+ * @return	a new AudioStream, or NULL, if an error occured
+ */
+AudioStream *makeVorbisStream(
+	Common::SeekableReadStream *stream,
+	bool disposeAfterUse,
+	uint32 startTime = 0,
+	uint32 duration = 0,
+	uint numLoops = 1);
+
 } // End of namespace Audio
 
 #endif // #ifdef USE_VORBIS


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