mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-24 05:01:43 +00:00
Fix invalid sample position on Timestamp to sample conversion for Stereo streams.
svn-id: r47591
This commit is contained in:
parent
9f2a619c06
commit
812603e29e
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user