[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