From 0bb4d9f2c18328a60fdd1336da717e1778900116 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 11 Oct 2017 17:09:27 -0700 Subject: [PATCH] Manually track the source decoder sample pos Rather than a virtual method for each decoder to report the current sample position, the stream class tracks the number of samples read and each seek. --- examples/alure-dumb.cpp | 9 +------ include/AL/alure2.h | 5 ---- src/decoders/flac.cpp | 16 ++---------- src/decoders/mpg123.cpp | 7 ------ src/decoders/opusfile.cpp | 7 ------ src/decoders/sndfile.cpp | 7 ------ src/decoders/vorbisfile.cpp | 7 ------ src/decoders/wave.cpp | 7 ------ src/source.cpp | 61 +++++++++++++++++++++++---------------------- 9 files changed, 34 insertions(+), 92 deletions(-) diff --git a/examples/alure-dumb.cpp b/examples/alure-dumb.cpp index fe86c15..86d1b2f 100644 --- a/examples/alure-dumb.cpp +++ b/examples/alure-dumb.cpp @@ -87,14 +87,13 @@ class DumbDecoder : public alure::Decoder { ALuint mFrequency; alure::Vector mSampleBuf; - uint64_t mStreamPos; public: DumbDecoder(alure::UniquePtr file, alure::UniquePtr dfs, DUMBFILE *dfile, DUH *duh, DUH_SIGRENDERER *renderer, alure::SampleType stype, ALuint srate) : mFile(std::move(file)), mDfs(std::move(dfs)), mDumbfile(dfile), mDuh(duh) - , mRenderer(renderer), mSampleType(stype), mFrequency(srate), mStreamPos(0) + , mRenderer(renderer), mSampleType(stype), mFrequency(srate) { } ~DumbDecoder() override final { @@ -129,11 +128,6 @@ public: return 0; } - uint64_t getPosition() const override final - { - return mStreamPos; - } - bool seek(uint64_t) override final { // Cannot seek @@ -173,7 +167,6 @@ public: out[i] = smp; } } - mStreamPos += ret; return ret; } diff --git a/include/AL/alure2.h b/include/AL/alure2.h index 8343f37..05fcd25 100644 --- a/include/AL/alure2.h +++ b/include/AL/alure2.h @@ -1242,11 +1242,6 @@ public: */ virtual uint64_t getLength() const = 0; /** - * Retrieves the current sample frame position (i.e. the number of sample - * frames from the beginning). - */ - virtual uint64_t getPosition() const = 0; - /** * Seek to pos, specified in sample frames. Returns true if the seek was * successful. */ diff --git a/src/decoders/flac.cpp b/src/decoders/flac.cpp index 0947bb7..6d56ef3 100644 --- a/src/decoders/flac.cpp +++ b/src/decoders/flac.cpp @@ -19,7 +19,6 @@ class FlacDecoder : public Decoder { SampleType mSampleType; ALuint mFrequency; ALuint mFrameSize; - uint64_t mSamplePos; Vector mData; @@ -193,7 +192,7 @@ class FlacDecoder : public Decoder { public: FlacDecoder() : mFlacFile(nullptr), mChannelConfig(ChannelConfig::Mono), mSampleType(SampleType::Int16) - , mFrequency(0), mFrameSize(0), mSamplePos(0), mOutBytes(nullptr), mOutMax(0), mOutLen(0) + , mFrequency(0), mFrameSize(0), mOutBytes(nullptr), mOutMax(0), mOutLen(0) { } ~FlacDecoder() override final; @@ -204,7 +203,6 @@ public: SampleType getSampleType() const override final; uint64_t getLength() const override final; - uint64_t getPosition() const override final; bool seek(uint64_t pos) override final; std::pair getLoopPoints() const override final; @@ -273,16 +271,10 @@ uint64_t FlacDecoder::getLength() const return FLAC__stream_decoder_get_total_samples(mFlacFile); } -uint64_t FlacDecoder::getPosition() const -{ - return mSamplePos; -} - bool FlacDecoder::seek(uint64_t pos) { if(!FLAC__stream_decoder_seek_absolute(mFlacFile, pos)) return false; - mSamplePos = pos; return true; } @@ -311,11 +303,7 @@ ALuint FlacDecoder::read(ALvoid *ptr, ALuint count) FLAC__stream_decoder_get_state(mFlacFile) == FLAC__STREAM_DECODER_END_OF_STREAM) break; } - ALuint ret = mOutLen / mFrameSize; - - mSamplePos += ret; - - return ret; + return mOutLen / mFrameSize; } diff --git a/src/decoders/mpg123.cpp b/src/decoders/mpg123.cpp index 0772b5f..87e9105 100644 --- a/src/decoders/mpg123.cpp +++ b/src/decoders/mpg123.cpp @@ -47,7 +47,6 @@ public: SampleType getSampleType() const override final; uint64_t getLength() const override final; - uint64_t getPosition() const override final; bool seek(uint64_t pos) override final; std::pair getLoopPoints() const override final; @@ -89,12 +88,6 @@ uint64_t Mpg123Decoder::getLength() const return (ALuint)std::max(len, 0); } -uint64_t Mpg123Decoder::getPosition() const -{ - off_t pos = mpg123_tell(mMpg123); - return (ALuint)std::max(pos, 0); -} - bool Mpg123Decoder::seek(uint64_t pos) { off_t newpos = mpg123_seek(mMpg123, pos, SEEK_SET); diff --git a/src/decoders/opusfile.cpp b/src/decoders/opusfile.cpp index 4afede2..3037ae8 100644 --- a/src/decoders/opusfile.cpp +++ b/src/decoders/opusfile.cpp @@ -148,7 +148,6 @@ public: SampleType getSampleType() const override final; uint64_t getLength() const override final; - uint64_t getPosition() const override final; bool seek(uint64_t pos) override final; std::pair getLoopPoints() const override final; @@ -185,12 +184,6 @@ uint64_t OpusFileDecoder::getLength() const return std::max(len, 0); } -uint64_t OpusFileDecoder::getPosition() const -{ - ogg_int64_t pos = op_pcm_tell(mOggFile); - return std::max(pos, 0); -} - bool OpusFileDecoder::seek(uint64_t pos) { return op_pcm_seek(mOggFile, pos) == 0; diff --git a/src/decoders/sndfile.cpp b/src/decoders/sndfile.cpp index a94ec55..8eca4f2 100644 --- a/src/decoders/sndfile.cpp +++ b/src/decoders/sndfile.cpp @@ -78,7 +78,6 @@ public: SampleType getSampleType() const override final; uint64_t getLength() const override final; - uint64_t getPosition() const override final; bool seek(uint64_t pos) override final; std::pair getLoopPoints() const override final; @@ -114,12 +113,6 @@ uint64_t SndFileDecoder::getLength() const return std::max(mSndInfo.frames, 0); } -uint64_t SndFileDecoder::getPosition() const -{ - sf_count_t pos = sf_seek(mSndFile, 0, SEEK_CUR); - return std::max(pos, 0); -} - bool SndFileDecoder::seek(uint64_t pos) { sf_count_t newpos = sf_seek(mSndFile, pos, SEEK_SET); diff --git a/src/decoders/vorbisfile.cpp b/src/decoders/vorbisfile.cpp index 00fbb9c..c151273 100644 --- a/src/decoders/vorbisfile.cpp +++ b/src/decoders/vorbisfile.cpp @@ -70,7 +70,6 @@ public: SampleType getSampleType() const override final; uint64_t getLength() const override final; - uint64_t getPosition() const override final; bool seek(uint64_t pos) override final; std::pair getLoopPoints() const override final; @@ -106,12 +105,6 @@ uint64_t VorbisFileDecoder::getLength() const return std::max(len, 0); } -uint64_t VorbisFileDecoder::getPosition() const -{ - ogg_int64_t pos = ov_pcm_tell(mOggFile.get()); - return std::max(pos, 0); -} - bool VorbisFileDecoder::seek(uint64_t pos) { return ov_pcm_seek(mOggFile.get(), pos) == 0; diff --git a/src/decoders/wave.cpp b/src/decoders/wave.cpp index db3584c..e2e4c6c 100644 --- a/src/decoders/wave.cpp +++ b/src/decoders/wave.cpp @@ -83,7 +83,6 @@ public: SampleType getSampleType() const override final; uint64_t getLength() const override final; - uint64_t getPosition() const override final; bool seek(uint64_t pos) override final; std::pair getLoopPoints() const override final; @@ -117,12 +116,6 @@ uint64_t WaveDecoder::getLength() const return (mEnd - mStart) / mFrameSize; } -uint64_t WaveDecoder::getPosition() const -{ - mFile->clear(); - return (std::max(mFile->tellg(), mStart) - mStart) / mFrameSize; -} - bool WaveDecoder::seek(uint64_t pos) { std::streamsize offset = pos*mFrameSize + mStart; diff --git a/src/source.cpp b/src/source.cpp index b81c970..e4300da 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -37,6 +37,7 @@ class ALBufferStream { Vector mBufferIds; ALuint mCurrentIdx; + uint64_t mSamplePos; std::pair mLoopPts; std::atomic mHasLooped; std::atomic mDone; @@ -45,7 +46,8 @@ public: ALBufferStream(SharedPtr decoder, ALuint updatelen, ALuint numupdates) : mDecoder(decoder), mUpdateLen(updatelen), mNumUpdates(numupdates), mFormat(AL_NONE), mFrequency(0), mFrameSize(0), mSilence(0), - mCurrentIdx(0), mLoopPts{0,0}, mHasLooped(false), mDone(false) + mCurrentIdx(0), mSamplePos(0), mLoopPts{0,0}, mHasLooped(false), + mDone(false) { } ~ALBufferStream() { @@ -57,7 +59,7 @@ public: } uint64_t getLength() const { return mDecoder->getLength(); } - uint64_t getPosition() const { return mDecoder->getPosition(); } + uint64_t getPosition() const { return mSamplePos; } ALuint getNumUpdates() const { return mNumUpdates; } ALuint getUpdateLength() const { return mUpdateLen; } @@ -68,7 +70,8 @@ public: { if(!mDecoder->seek(pos)) return false; - mHasLooped.store(false, std::memory_order_release); + mSamplePos = pos; + mHasLooped.store(false, std::memory_order_relaxed); mDone.store(false, std::memory_order_release); return true; } @@ -116,42 +119,40 @@ public: return false; ALuint frames; - if(!loop) - frames = mDecoder->read(&mData[0], mUpdateLen); + ALuint len = mUpdateLen; + if(loop && mSamplePos <= mLoopPts.second) + len = std::min(len, mLoopPts.second - mSamplePos); else - { - ALuint len = mUpdateLen; - uint64_t pos = mDecoder->getPosition(); - if(pos <= mLoopPts.second) - len = std::min(len, mLoopPts.second - pos); - else - loop = false; + loop = false; - frames = mDecoder->read(&mData[0], len); - if(frames < mUpdateLen && loop && pos+frames > 0) + frames = mDecoder->read(mData.data(), len); + mSamplePos += frames; + if(frames < mUpdateLen && loop && mSamplePos > 0) + { + if(mSamplePos < mLoopPts.second) { - if(pos+frames < mLoopPts.second) - { - mLoopPts.second = pos+frames; - mLoopPts.first = std::min(mLoopPts.first, mLoopPts.second-1); - } - - do { - if(!mDecoder->seek(mLoopPts.first)) - break; - mHasLooped.store(true, std::memory_order_release); - - len = std::min(mUpdateLen-frames, mLoopPts.second-mLoopPts.first); - ALuint got = mDecoder->read(&mData[frames*mFrameSize], len); - if(got == 0) break; - frames += got; - } while(frames < mUpdateLen); + mLoopPts.second = mSamplePos; + mLoopPts.first = std::min(mLoopPts.first, mLoopPts.second-1); } + + do { + if(!mDecoder->seek(mLoopPts.first)) + break; + mSamplePos = mLoopPts.first; + mHasLooped.store(true, std::memory_order_release); + + len = std::min(mUpdateLen-frames, mLoopPts.second-mLoopPts.first); + ALuint got = mDecoder->read(&mData[frames*mFrameSize], len); + if(got == 0) break; + mSamplePos += got; + frames += got; + } while(frames < mUpdateLen); } if(frames < mUpdateLen) { mDone.store(true, std::memory_order_release); if(frames == 0) return false; + mSamplePos += mUpdateLen - frames; std::fill(mData.begin() + frames*mFrameSize, mData.end(), mSilence); } -- 2.11.4.GIT