jpemartins / speex.js

Speex codec in Javascript. Mirror from https://code.ua.pt/projects/speex-js
215 stars 64 forks source link

Correctly update granule_pos in Ogg header #13

Open jpemartins opened 10 years ago

jpemartins commented 10 years ago

VLC ignores speex.js-generated ogg files, because granule_pos is not correctly updated.

This field in the Ogg header describes the number of samples that the encoded audio has. libogg checks whether granule_pos is correctly inserted in all frames. If that's not the case, it will ignore all ogg pages inside that ogg packet.

dbieber commented 10 years ago

Before I try to fix this, I want to make sure I understand what granule_pos is supposed to be.

One source https://xiph.org/ogg/doc/ogg-multiplex.html doesn't mention Speex by name at all. And http://www.speex.org/docs/manual/speex-manual/node8.html says "granulepos is the number of the last sample encoded in that packet" and "The header packet has packetno=0 and granulepos=0."

In ogg.js I see where the granulepos fits into the header, but not where the packetno belongs.

Also important is that sample numbers refer to PCM samples, not Speex samples (http://www.ucc.gu.uwa.edu.au/~dagobah/speexcat/speexcat.c)

dbieber commented 10 years ago

I've had limited success (see here: https://github.com/dbieber/speex.js/blob/granulepos/src/ogg.js), but I am still working on figuring out the proper way of doing things.

It mostly works for both example wav files (assuming the frame size is set properly), but the end of wb_male_speex_21.wav gets cut off a little.

jpemartins commented 10 years ago

Really Cool!

Btw, for WB the frame size is 320, and NB is 160 samples. It looks like there is a frame missing (in granule pos) if it's the end that that gets cut a little.