csvorbis.VorbisFile.process_packet C# (CSharp) Method

process_packet() private method

private process_packet ( int readp ) : int
readp int
return int
        int process_packet(int readp)
        {
            Page og=new Page();

            // handle one packet.  Try to fetch it from current stream state
            // extract packets from page
            while(true)
            {
                // process a packet if we can.  If the machine isn't loaded,
                // neither is a page
                if(decode_ready)
                {
                    Packet op=new Packet();
                    int result=os.packetout(op);
                    long granulepos;
                    // if(result==-1)return(-1); // hole in the data. For now, swallow
                    // and go. We'll need to add a real
                    // error code in a bit.
                    if(result>0)
                    {
                        // got a packet.  process it
                        granulepos=op.granulepos;
                        if(vb.synthesis(op)==0)
                        { // lazy check for lazy
                            // header handling.  The
                            // header packets aren't
                            // audio, so if/when we
                            // submit them,
                            // vorbis_synthesis will
                            // reject them
                            // suck in the synthesis data and track bitrate
                        {
                            int oldsamples=vd.synthesis_pcmout(null, null);
                            vd.synthesis_blockin(vb);
                            samptrack+=vd.synthesis_pcmout(null, null)-oldsamples;
                            bittrack+=op.bytes*8;
                        }

                            // update the pcm offset.
                            if(granulepos!=-1 && op.e_o_s==0)
                            {
                                int link=(skable?current_link:0);
                                int samples;
                                // this packet has a pcm_offset on it (the last packet
                                // completed on a page carries the offset) After processing
                                // (above), we know the pcm position of the *last* sample
                                // ready to be returned. Find the offset of the *first*
                                //
                                // As an aside, this trick is inaccurate if we begin
                                // reading anew right at the last page; the end-of-stream
                                // granulepos declares the last frame in the stream, and the
                                // last packet of the last page may be a partial frame.
                                // So, we need a previous granulepos from an in-sequence page
                                // to have a reference point.  Thus the !op.e_o_s clause above

                                samples=vd.synthesis_pcmout(null, null);
                                granulepos-=samples;
                                for(int i=0;i<link;i++)
                                {
                                    granulepos+=pcmlengths[i];
                                }
                                pcm_offset=granulepos;
                            }
                            return(1);
                        }
                    }
                }

                if(readp==0)return(0);
                if(get_next_page(og,-1)<0)return(0); // eof. leave unitialized

                // bitrate tracking; add the header's bytes here, the body bytes
                // are done by packet above
                bittrack+=og.header_len*8;

                // has our decoding just traversed a bitstream boundary?
                if(decode_ready)
                {
                    if(current_serialno!=og.serialno())
                    {
                        decode_clear();
                    }
                }

                // Do we need to load a new machine before submitting the page?
                // This is different in the seekable and non-seekable cases.
                //
                // In the seekable case, we already have all the header
                // information loaded and cached; we just initialize the machine
                // with it and continue on our merry way.
                //
                // In the non-seekable (streaming) case, we'll only be at a
                // boundary if we just left the previous logical bitstream and
                // we're now nominally at the header of the next bitstream

                if(!decode_ready)
                {
                    int i;
                    if(skable)
                    {
                        current_serialno=og.serialno();

                        // match the serialno to bitstream section.  We use this rather than
                        // offset positions to avoid problems near logical bitstream
                        // boundaries
                        for(i=0;i<links;i++)
                        {
                            if(serialnos[i]==current_serialno)break;
                        }
                        if(i==links)return(-1); // sign of a bogus stream.  error out,
                        // leave machine uninitialized
                        current_link=i;

                        os.init(current_serialno);
                        os.reset();

                    }
                    else
                    {
                        // we're streaming
                        // fetch the three header packets, build the info struct
                        int[] foo = new int[1];
                        int ret=fetch_headers(vi[0], vc[0], foo, og);
                        current_serialno=foo[0];
                        if(ret!=0)return ret;
                        current_link++;
                        i=0;
                    }
                    make_decode_ready();
                }
                os.pagein(og);
            }
        }