4

I'm working with JNI and Android NDK bindings to wrap around the Tremor version of Vorbis. So far i've succeeded in streaming sound from file to speakers.

However, i'd also like to be able to 'cache' small sounds in byte arrays, so there's no redundant decompression when i use these sounds often.

My problem is that i don't know how large the array needs to be to hold all the PCM data in the vorbis file.

I have tried these following methods, none of which work 100% of the time.

pcmDuration = ov_pcm_total(vorbisFile, -1);
pcmDuration *= 2;              // 16bit channels
pcmDuration *= vorbisInfo->channels;   // number of channels.

The above works perfectly for some files, and nails exactly the size required. However, for others it doesn't. It dramatically underestimates (usually by about 1-2kb) the size required, obviously leading to out of bounds exceptions.

The below was a recommended solution, but has the exact same problem. It yields the same results as above.

for(int i = 0; i < ov_streams(vorbisFile); i++)
    size += ov_pcm_total(vorbisFile, i);

What method should i use to find out the actual byte size required to hold an Ogg Vorbis file?

EDIT;

I know i could just do ov_reads over the entire length of the file, and take the sum of those reads as the decompressed size. However i'd prefer not to double-decompress, since i'm working in Android and it's got limited CPU power in the first place, and that's a pretty ugly solution. This isn't a response to any answer, i just know i could do it but would prefer not to.

Charles
  • 50,943
  • 13
  • 104
  • 142
Knetic
  • 2,099
  • 1
  • 20
  • 34

2 Answers2

0

I know this is four years late, but I never found a real answer to this question. The solution I went with long ago was to use linked lists of fixed-size byte arrays, each representing one chunk of decompressed data. Each ov_read would store the data into a new chunk, and chunks would link together one-to-the-next until the entire file was decoded. Subsequent playback would just grab data from each chunk sequentially and replay it.

This obviously fell apart when decompressing large files, and leads to a lot of memory management for decompressed chunks (unloading a single file means de-linking all chunks completely so that they can be garbage collected).

Knetic
  • 2,099
  • 1
  • 20
  • 34
0

I just had this same exact issue streaming ogg using the Vorbisfile API with XAudio2.

The fix that worked for me was to call ov_raw_seek (after both ov_open_callbacks and ov_info calls, but before ov_pcm_total and ov_read) to seek back to the start of the file. Apparently, this "fixes" the internal state around the pcm positions/offset vars.

After that, all ogg files I test with play correctly.

This gave me the clue: https://github.com/xiph/vorbis/issues/60

Gordon Glas
  • 1,659
  • 2
  • 15
  • 23