[Speex-dev] Speex seek with high precision

Conrad Parker conrad at metadecks.org
Wed May 13 15:31:10 PDT 2009


2009/5/14 Arnau Alemany <arnau.alemany at gmail.com>:
> Hello everybody,
> I'm new to this mailing list so I'm sorry if it's the wrong place to post
> this.
>
> I'm developing a Speex player and I need to seek with a precision of
> milliseconds. I used liboggz that supposedly does just that, but it never
> seeks exactly where it should. For example if I use oggz_seek_units(oggz,
> 18450, SEEK_SET) result it's 16386 and there is a delay between the playback
> and the moment where it should start. Only when I seek to position 0 I get
> the desired result.

ok, first up I'll mention that I'm rewriting the seeking part of
liboggz atm, so this is good feedback :-)

> I've also used ogg_page_granulepos for seeking but it seems more difficult
> to use. I use something like this:
>
>     do
>     {
>         while (ogg_sync_pageout(&oy, &og) != 1)
>         {
>             data = ogg_sync_buffer(&oy, 512);
>             readbytes = fread(data, 1, 512, spxfile);
>             ogg_sync_wrote(&oy, readbytes);
>         }
>         //printf("ogg_page_granulepos: %lld\n", ogg_page_granulepos(&og));
>     }
>     while (ogg_page_granulepos(&og) < time * freq); // time in seconds,
> freq: 16000
>
> But this way I can't get enough precision neither.

Seeking on Ogg pages will only give you page accuracy, and each page
can contain multiple packets. eg. a narrowband encode:

conrad at chichai:~/share/speech$ speexenc male.wav male.spx
Encoding 8000 Hz audio using narrowband mode (mono)
conrad at chichai:~/share/speech$ oggz info male.spx
Content-Duration: 00:00:06.000

Speex: serialno 1523256763
        303 packets in 5 pages, 60.6 packets/page, 3.653% Ogg overhead
        Audio-Samplerate: 8000 Hz
        Audio-Channels: 1

Actually the first two pages each contain one header packet, so
there's 301 data packets in the last 3 pages, ie. about 100 packets
per page. So if each packet is 320 samples for speex (at 1 speex frame
per packet) then the duration of a page is about 2 seconds: that's
about the granularity you can expect for Ogg Speex pages.

> Could anyone give me some idea of what could I do to get a high precision
> when seeking?

Once you've found the closest page, you need to iterate through the
packets until you find the one containing the time you want. Speex
packets can contain up to 10 speex frames, so packet granularity is
3200 samples in the worst case.

If you're happy with packet precision then you're done; otherwise you
need to start decoding and just throw away the samples before the time
you want.

Keep in mind that for decode accuracy you should start decoding from
about 3 frames prior to the target: throw that decoded data away, but
the subsequent data from the time you actually want will be closer to
what was recorded.

Conrad.


More information about the Speex-dev mailing list