From: Mikko Rasa Date: Sun, 24 Jun 2018 14:46:39 +0000 (+0300) Subject: Implement seeking in sound decoders X-Git-Url: http://git.tdb.fi/?p=libs%2Fal.git;a=commitdiff_plain;h=d365c5394308740f478fbdfbb23e2c5d972f19f0 Implement seeking in sound decoders This also fixes a bug in Mp3Decoder where the input buffer was not cleared on rewind so playback didn't immediately restart from the beginning. --- diff --git a/source/mp3decoder.cpp b/source/mp3decoder.cpp index ec08be7..34604e3 100644 --- a/source/mp3decoder.cpp +++ b/source/mp3decoder.cpp @@ -87,9 +87,32 @@ bool Mp3Decoder::detect(const string &sig) return !sig.compare(0, sizeof(id3_sig), id3_sig); } -void Mp3Decoder::rewind() +void Mp3Decoder::seek(unsigned pos) { + unsigned unit = get_unit_size(format); + pos /= unit; + in.seek(0, IO::S_BEG); + mad_stream_buffer(&priv->stream, 0, 0); + fill_input(); + if(!pos) + { + priv->synth.pcm.length = 0; + return; + } + + while(decode(false)) + { + unsigned frame_len = 32*MAD_NSBSAMPLES(&priv->frame.header); + if(frame_len>pos) + { + decode(true); + read_pos = pos; + break; + } + + pos -= frame_len; + } } unsigned Mp3Decoder::read(char *buf, unsigned len) diff --git a/source/mp3decoder.h b/source/mp3decoder.h index c026081..201d68f 100644 --- a/source/mp3decoder.h +++ b/source/mp3decoder.h @@ -35,7 +35,7 @@ public: static bool detect(const std::string &); - virtual void rewind(); + virtual void seek(unsigned); virtual unsigned read(char *, unsigned); private: diff --git a/source/oggdecoder.cpp b/source/oggdecoder.cpp index 78a2b5a..cd2def8 100644 --- a/source/oggdecoder.cpp +++ b/source/oggdecoder.cpp @@ -109,9 +109,10 @@ bool OggDecoder::detect(const std::string &sig) return !sig.compare(0, sizeof(ogg_sig), ogg_sig); } -void OggDecoder::rewind() +void OggDecoder::seek(unsigned pos) { - ov_pcm_seek(&priv->ovfile, 0); + pos /= get_unit_size(format); + ov_pcm_seek(&priv->ovfile, pos); } unsigned OggDecoder::read(char *buf, unsigned len) diff --git a/source/oggdecoder.h b/source/oggdecoder.h index aab8f5c..3bf33b8 100644 --- a/source/oggdecoder.h +++ b/source/oggdecoder.h @@ -31,7 +31,7 @@ public: static bool detect(const std::string &); - virtual void rewind(); + virtual void seek(unsigned); virtual unsigned read(char *, unsigned); }; diff --git a/source/sounddecoder.h b/source/sounddecoder.h index ee5b07d..37fddac 100644 --- a/source/sounddecoder.h +++ b/source/sounddecoder.h @@ -37,7 +37,8 @@ public: static SoundDecoder *open_file(const std::string &); static SoundDecoder *open_io(IO::Seekable &); - virtual void rewind() = 0; + virtual void rewind() { seek(0); } + virtual void seek(unsigned) = 0; virtual unsigned read(char *, unsigned) = 0; bool eof() const { return eof_flag; }