aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schickel2010-01-27 08:08:33 +0000
committerJohannes Schickel2010-01-27 08:08:33 +0000
commit812603e29eef2bd0c224a9b3b4c2bf29b2d3b653 (patch)
tree63cb6f484d6ebaad723b589b2d99300bc452ed6b
parent9f2a619c06851429e261264c7f4b18a75cd4d7fd (diff)
downloadscummvm-rg350-812603e29eef2bd0c224a9b3b4c2bf29b2d3b653.tar.gz
scummvm-rg350-812603e29eef2bd0c224a9b3b4c2bf29b2d3b653.tar.bz2
scummvm-rg350-812603e29eef2bd0c224a9b3b4c2bf29b2d3b653.zip
Fix invalid sample position on Timestamp to sample conversion for Stereo streams.
svn-id: r47591
-rw-r--r--engines/kyra/sound_digital.cpp2
-rw-r--r--sound/audiostream.cpp21
-rw-r--r--sound/audiostream.h19
-rw-r--r--sound/decoders/flac.cpp2
-rw-r--r--sound/decoders/raw.cpp11
-rw-r--r--sound/decoders/vorbis.cpp2
6 files changed, 30 insertions, 27 deletions
diff --git a/engines/kyra/sound_digital.cpp b/engines/kyra/sound_digital.cpp
index 393a2f3eda..7a04fc0691 100644
--- a/engines/kyra/sound_digital.cpp
+++ b/engines/kyra/sound_digital.cpp
@@ -356,7 +356,7 @@ int AUDStream::readChunk(int16 *buffer, const int maxSamples) {
}
bool AUDStream::seek(const Audio::Timestamp &where) {
- const uint32 seekSample = Audio::calculateSampleOffset(where, getRate());
+ const uint32 seekSample = Audio::convertTimeToStreamPos(where, getRate(), isStereo()).totalNumberOfFrames();
_stream->seek(_streamStart);
_processedSize = 0;
diff --git a/sound/audiostream.cpp b/sound/audiostream.cpp
index e781149a55..08ea636a1d 100644
--- a/sound/audiostream.cpp
+++ b/sound/audiostream.cpp
@@ -164,8 +164,8 @@ SubLoopingAudioStream::SubLoopingAudioStream(SeekableAudioStream *stream,
DisposeAfterUse::Flag 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))),
+ _loopStart(convertTimeToStreamPos(loopStart, getRate(), isStereo())),
+ _loopEnd(convertTimeToStreamPos(loopEnd, getRate(), isStereo())),
_done(false) {
if (!_parent->rewind())
_done = true;
@@ -212,9 +212,9 @@ int SubLoopingAudioStream::readBuffer(int16 *buffer, const int numSamples) {
SubSeekableAudioStream::SubSeekableAudioStream(SeekableAudioStream *parent, const Timestamp start, const Timestamp end, DisposeAfterUse::Flag disposeAfterUse)
: _parent(parent), _disposeAfterUse(disposeAfterUse),
- _start(start.convertToFramerate(getRate())),
+ _start(convertTimeToStreamPos(start, getRate(), isStereo())),
_pos(0, getRate() * (isStereo() ? 2 : 1)),
- _length((end - start).convertToFramerate(getRate() * (isStereo() ? 2 : 1))) {
+ _length(convertTimeToStreamPos(end - start, getRate(), isStereo())) {
assert(_length.totalNumberOfFrames() % (isStereo() ? 2 : 1) == 0);
_parent->seek(_start);
@@ -233,7 +233,7 @@ int SubSeekableAudioStream::readBuffer(int16 *buffer, const int numSamples) {
}
bool SubSeekableAudioStream::seek(const Timestamp &where) {
- _pos = where.convertToFramerate(getRate());
+ _pos = convertTimeToStreamPos(where, getRate(), isStereo());
if (_pos > _length) {
_pos = _length;
return false;
@@ -364,4 +364,15 @@ QueuingAudioStream *makeQueuingAudioStream(int rate, bool stereo) {
return new QueuingAudioStreamImpl(rate, stereo);
}
+Timestamp convertTimeToStreamPos(const Timestamp &where, int rate, bool isStereo) {
+ Timestamp result(where.convertToFramerate(rate * (isStereo ? 2 : 1)));
+
+ // When the Stream is a stereo stream, we have to assure
+ // that the sample position is an even number.
+ if (isStereo && (result.totalNumberOfFrames() & 1))
+ return result.addFrames(-1); // We cut off one sample here.
+ else
+ return result;
+}
+
} // End of namespace Audio
diff --git a/sound/audiostream.h b/sound/audiostream.h
index bb0edaa100..764662e378 100644
--- a/sound/audiostream.h
+++ b/sound/audiostream.h
@@ -162,9 +162,9 @@ public:
* Tries to load a file by trying all available formats.
* In case of an error, the file handle will be closed, but deleting
* it is still the responsibility of the caller.
- * @param basename a filename without an extension
- * @return an SeekableAudioStream ready to use in case of success;
- * NULL in case of an error (e.g. invalid/nonexisting file)
+ * @param basename a filename without an extension
+ * @return an SeekableAudioStream ready to use in case of success;
+ * NULL in case of an error (e.g. invalid/nonexisting file)
*/
static SeekableAudioStream *openStreamFile(const Common::String &basename);
@@ -337,16 +337,15 @@ public:
*/
QueuingAudioStream *makeQueuingAudioStream(int rate, bool stereo);
-
/**
- * Calculates the sample, which the timestamp describes in a
- * AudioStream with the given framerate.
+ * Converts a point in time to a precise sample offset
+ * with the given parameters.
*
- * @param where point in time
- * @param rate rate of the AudioStream
- * @return sample index
+ * @param where Point in time.
+ * @param rate Rate of the stream.
+ * @param isStereo Is the stream a stereo stream?
*/
-uint32 calculateSampleOffset(const Timestamp &where, int rate);
+Timestamp convertTimeToStreamPos(const Timestamp &where, int rate, bool isStereo);
} // End of namespace Audio
diff --git a/sound/decoders/flac.cpp b/sound/decoders/flac.cpp
index 29302827da..6fa7302a9a 100644
--- a/sound/decoders/flac.cpp
+++ b/sound/decoders/flac.cpp
@@ -294,7 +294,7 @@ bool FlacInputStream::seekAbsolute(FLAC__uint64 sample) {
bool FlacInputStream::seek(const Timestamp &where) {
_sampleCache.bufFill = 0;
_sampleCache.bufReadPos = NULL;
- return seekAbsolute((FLAC__uint64)calculateSampleOffset(where, _streaminfo.sample_rate));
+ return seekAbsolute((FLAC__uint64)convertTimeToStreamPos(where, getRate(), isStereo()).totalNumberOfFrames());
}
int FlacInputStream::readBuffer(int16 *buffer, const int numSamples) {
diff --git a/sound/decoders/raw.cpp b/sound/decoders/raw.cpp
index 6747111a1a..ecdde10250 100644
--- a/sound/decoders/raw.cpp
+++ b/sound/decoders/raw.cpp
@@ -41,13 +41,6 @@ namespace Audio {
((is16Bit ? (isLE ? READ_LE_UINT16(ptr) : READ_BE_UINT16(ptr)) : (*ptr << 8)) ^ (isUnsigned ? 0x8000 : 0))
-// TODO: Get rid of this
-uint32 calculateSampleOffset(const Timestamp &where, int rate) {
- return where.convertToFramerate(rate).totalNumberOfFrames();
-}
-
-
-
#pragma mark -
#pragma mark --- RawMemoryStream ---
#pragma mark -
@@ -110,7 +103,7 @@ int RawMemoryStream<stereo, is16Bit, isUnsigned, isLE>::readBuffer(int16 *buffer
template<bool stereo, bool is16Bit, bool isUnsigned, bool isLE>
bool RawMemoryStream<stereo, is16Bit, isUnsigned, isLE>::seek(const Timestamp &where) {
- const uint8 *ptr = _origPtr + calculateSampleOffset(where, getRate()) * (is16Bit ? 2 : 1) * (stereo ? 2 : 1);
+ const uint8 *ptr = _origPtr + convertTimeToStreamPos(where, getRate(), isStereo()).totalNumberOfFrames() * (is16Bit ? 2 : 1);
if (ptr > _end) {
_ptr = _end;
return false;
@@ -275,7 +268,7 @@ int RawDiskStream<stereo, is16Bit, isUnsigned, isLE>::readBuffer(int16 *buffer,
template<bool stereo, bool is16Bit, bool isUnsigned, bool isLE>
bool RawDiskStream<stereo, is16Bit, isUnsigned, isLE>::seek(const Timestamp &where) {
- const uint32 seekSample = calculateSampleOffset(where, getRate()) * (stereo ? 2 : 1);
+ const uint32 seekSample = convertTimeToStreamPos(where, getRate(), isStereo()).totalNumberOfFrames();
uint32 curSample = 0;
// Search for the disk block in which the specific sample is placed
diff --git a/sound/decoders/vorbis.cpp b/sound/decoders/vorbis.cpp
index 46a94a6214..f5ebc112c3 100644
--- a/sound/decoders/vorbis.cpp
+++ b/sound/decoders/vorbis.cpp
@@ -169,7 +169,7 @@ int VorbisInputStream::readBuffer(int16 *buffer, const int numSamples) {
}
bool VorbisInputStream::seek(const Timestamp &where) {
- int res = ov_pcm_seek(&_ovFile, calculateSampleOffset(where, getRate()));
+ int res = ov_pcm_seek(&_ovFile, convertTimeToStreamPos(where, getRate(), isStereo()).totalNumberOfFrames());
if (res) {
warning("Error seeking in Vorbis stream (%d)", res);
_pos = _bufferEnd;