7
\$\begingroup\$

I'm successfully streaming ogg vorbis data to openAL with the Java library JOrbis, but now I want to loop over a part of this stream, e.g from 30" to 1'30".

I thought that at the end of the loop, I could redecode from the beginning of the file, skip the unwanted part, and then keep streaming until the end of the loop, and restart again. But I'm not really convinced by this method, as for example, if I want to loop over 4' and 4'30", I'll need to decode each loop 4 minutes of ogg data for nothing.

Another way would be to put all the loop in memory, but it won't be streaming anymore and I want to avoid this.

So is there a way to reach a point in an ogg vorbis stream without decoding the previous data every time ? Does ogg contains a kind of index that can be used, or is it possible to make one by decoding the whole file once before ?

Thanks

(ps: I could't give this question the right tags as I haven't yet 150 rep)

\$\endgroup\$

2 Answers 2

5
\$\begingroup\$

Backtracking and seeking in Vorbis files is notoriously tricky. Restarting from the beginning may be your best option, especially if you are using someone else's API.

Another option would be to cut up the file into two, one of which is the full track and then a second 30 second track which you (hopefully) can transition to without a gap.

A third option, if your API provides the information, would be to build a custom lookup table of granulepos -> file offsets, and binary search through that, then read linearly from there. The table size can be adjusted based on memory requirements, unlike the disk file. Although, there are some tricky issues with that...

Sean Barrett wrote an Ogg Vorbis decoder for RAD and explained in some detail why the format is no good for seeking. It mirrors my experience working with Ogg Vorbis, and I didn't even have to touch the Vorbis part for my work.

\$\endgroup\$
2
  • \$\begingroup\$ Thanks for the links, it's very useful! I'll try to build a lookup table like you said. JOrbis is a "low-level" library, so it provides the granulepos. As I don't need a sample-precision, I think going 1 page before and then drop the useless data, it will avoid decoding to much. \$\endgroup\$
    – Mr_Qqn
    Commented Sep 8, 2010 at 18:47
  • \$\begingroup\$ You may not need sample precision, but a good-sounding audio loop will need more than the 1/4 second precision page-level seeking alone provides. Good luck. \$\endgroup\$
    – user744
    Commented Sep 8, 2010 at 19:48
0
\$\begingroup\$

Yes, you can seek into an ogg, assuming the off file you are reading is seekable (which most file are). As I am not familiar with JOrbis, I will present native C/C++ solution (using vorbisFile.h - i.e. libvorbis), hopefully you will find some counterpart in your library.

Use ov_pcm_seek to seek into your desired position, then you can continue reading normally using ov_read

\$\endgroup\$
8
  • \$\begingroup\$ Are you sure? Could you, please, quote the source. \$\endgroup\$
    – Suma
    Commented Sep 8, 2010 at 14:50
  • \$\begingroup\$ Still, as this is the only low-level API available, it is very unlikely high level APIs would be able to provide you more. The low-level API is complete in the sense it can handle all features present in the default OGG file. You might be able to insert some custom meta data containing your own index, but I guess this is obvious and not what you ask for. \$\endgroup\$
    – Suma
    Commented Sep 8, 2010 at 14:52
  • 1
    \$\begingroup\$ Scratch that. I was wrong. ov_pcm_seek is a linear search; ov_pcm_seek_page is a binary search. However, it still effectively decodes the file up to that point, which is what the asker wishes to avoid. \$\endgroup\$
    – user744
    Commented Sep 8, 2010 at 15:41
  • 1
    \$\begingroup\$ Source is at svn.xiph.org/trunk/vorbis/lib/vorbisfile.c, for those interested in playing along at home. I think Sean's analysis is a lot more fun however, and more relevant to this since JOrbis is not libvorbis-derived. \$\endgroup\$
    – user744
    Commented Sep 8, 2010 at 15:43
  • \$\begingroup\$ JOrbis doesn't provide this function, mainly it convert binary data to pages, pages to frames and frames to PCM, and don't have a lot of utility functions. So I'll have to seek in the file by myself. \$\endgroup\$
    – Mr_Qqn
    Commented Sep 8, 2010 at 18:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .