[Vorbis] encoder_example.c Questions

Michael Smith msmith at xiph.org
Tue Sep 27 02:30:18 PDT 2005


On 9/26/05, Daniel Mikusa <dan at trz.cc> wrote:
>  I've been trying to piece my way through the encoder_example.c program to
> better understand how to encode files as ogg/vorbis.  I'm stuck on two
> sections of the code.
>
>  This is the first
>
>        /* uninterleave samples */
>        for(i=0;i<bytes/4;i++){
>          buffer[0][i]=((readbuffer[i*4+1]<<8)|
>
> (0x00ff&(int)readbuffer[i*4]))/32768.f;
>          buffer[1][i]=((readbuffer[i*4+3]<<8)|
>
> (0x00ff&(int)readbuffer[i*4+2]))/32768.f;
>        }

The encoder example assumes that the audio is stored as (interleaved)
stereo, 16-bit signed little-endian samples (this is the most common
format in WAV files, for example).

The vorbis encoder library takes floating point samples in two
seperate vectors (i.e. not interleaved).

So this chunk of code is converting from 16-bit little-endian integer
samples to floats (ranging from -1 to 1), then putting them into the
buffers for the encoder.

>
>
>  This is the second.
>
>      /* vorbis does some data preanalysis, then divvies up blocks for
>         more involved (potentially parallel) processing.  Get a single
>         block for encoding now */
>      while(vorbis_analysis_blockout(&vd,&vb)==1){

At this point, we've already submitted raw (unencoded) data to the
library. This call tells it to produce a 'block' to actually encode
(this requires doing quite a bit of analysis to decide what size of
block to use).

The while loop makes us continue doing this until there's no longer
enough data in the internal buffers (at which point we need to submit
more data).


>
>        /* analysis, assume we want to use bitrate management */
>        vorbis_analysis(&vb,NULL);
>        vorbis_bitrate_addblock(&vb);

This does the main analysis/encoding step.

>
>        while(vorbis_bitrate_flushpacket(&vd,&op)){

Then this actually produces a packet that we can write to our output
file, based on the analysis that has been done. Again, we keep doing
this until the encoder library has no further packets to produce.

>
>          /* weld the packet into the bitstream */
>          ogg_stream_packetin(&os,&op);

At this point, we're no longer doing vorbis-specific things, we're
just doing the work to write our packets into an ogg bitstream. This
call gives the packet to libogg.

>
>          /* write out pages (if any) */
>          while(!eos){
>            int result=ogg_stream_pageout(&os,&og);
>            if(result==0)break;
>            fwrite(og.header,1,og.header_len,stdout);
>            fwrite(og.body,1,og.body_len,stdout);

And then we loop writing out ogg pages (if any) until we hit EOS or
don't have any pages to write (in fact, most of the time we won't have
any pages at all to write out here - there are multiple packets per
page normally.


Mike


More information about the Vorbis mailing list