]> git.tdb.fi Git - libs/al.git/commitdiff
Implement seeking in sound decoders
authorMikko Rasa <tdb@tdb.fi>
Sun, 24 Jun 2018 14:46:39 +0000 (17:46 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 24 Jun 2018 14:46:39 +0000 (17:46 +0300)
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.

source/mp3decoder.cpp
source/mp3decoder.h
source/oggdecoder.cpp
source/oggdecoder.h
source/sounddecoder.h

index ec08be7f9a5969bfe2ee67ad81f4a1eb5adf6bbd..34604e320339dc5bdb0dcae98125e78d160ceee1 100644 (file)
@@ -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)
index c026081126b3f76c259d9dea70e70948bd54b0dc..201d68f26e789f174041b08b3e0c97e2c8d0f1e2 100644 (file)
@@ -35,7 +35,7 @@ public:
 
        static bool detect(const std::string &);
 
-       virtual void rewind();
+       virtual void seek(unsigned);
        virtual unsigned read(char *, unsigned);
 
 private:
index 78a2b5ac158d20a857db455f7ee7e1e969b12922..cd2def8ca78d1d86488d2ceb2d15a25ce9a916e7 100644 (file)
@@ -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)
index aab8f5c8da6b06c7b66049e90d1687e2fe4ee4bc..3bf33b8bec32b8440ce0feef9df96afd9039d129 100644 (file)
@@ -31,7 +31,7 @@ public:
 
        static bool detect(const std::string &);
 
-       virtual void rewind();
+       virtual void seek(unsigned);
        virtual unsigned read(char *, unsigned);
 };
 
index ee5b07d5f33abea2410dc95076f026c0586a1ffc..37fddac2ee34c8881163c30a875d451c7429d473 100644 (file)
@@ -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; }