示例#1
0
 public static int ogg_stream_packetout(ogg_stream_state os, ogg_packet op)
 {
     if (ogg_stream_check(os) != 0)
     {
         return(0);
     }
     return(_packetout(os, op, 1));
 }
示例#2
0
        static ushort[] convbuffer = new ushort[4096]; /* take 8k out of the data segment, not the stack */
        //static long convsize = 4096;

        public static void Main(string[] args)
        {
            /* sync and verify incoming physical bitstream */
            var oy = new ogg_sync_state();

            /* take physical pages, weld into a logical stream of packets */
            var os = new ogg_stream_state();

            /* one Ogg bitstream page. Vorbis packets are inside */
            var og = new ogg_page();

            /* one raw packet of data for decode */
            var op = new ogg_packet();

            /* struct that stores all the static vorbis bitstream settings */
            var vi = new vorbis_info();

            /* struct that stores all the bitstream user comments */
            var vc = new vorbis_comment();

            /* central working state for the packet->PCM decoder */
            var vd = new vorbis_dsp_state();

            /* local working space for packet->PCM decode */
            var vb = new vorbis_block();

            var stdin  = Console.OpenStandardInput();
            var stdout = Console.OpenStandardOutput();
            var stderr = Console.OpenStandardError();

            /********** Decode setup ************/

            ogg_sync_init(oy); /* Now we can read pages */

            while (true)
            { /* we repeat if the bitstream is chained */
              /* grab some data at the head of the stream. We want the first page
               * (which is guaranteed to be small and only contain the Vorbis
               * stream initial header) We need the first page to get the stream
               * serialno. */

                /* submit a 4k block to libvorbis' Ogg layer */
                var buffer = ogg_sync_buffer(oy, 4096);
                int bytes  = fread(buffer, 1, 4096, stdin);
                ogg_sync_wrote(oy, bytes);

                /* Get the first page. */
                if (ogg_sync_pageout(oy, og) != 1)
                {
                    /* have we simply run out of data?  If so, we're done. */
                    if (bytes < 4096)
                    {
                        break;
                    }

                    /* error case.  Must not be Vorbis data */
                    fprintf(stderr, "Input does not appear to be an Ogg bitstream.\n");
                    exit(1);
                }

                /* get the serial number and set up the rest of decode. */
                /* serialno first; use it to set up a logical stream */
                ogg_stream_init(os, ogg_page_serialno(og));

                /* extract the initial header from the first page and verify that the
                 * ogg bitstream is in fact vorbis data */

                /* i handle the initial header first instead of just having the code
                 * read all three vorbis headers at once because reading the initial
                 * header is an easy way to identify a vorbis bitstream and it's
                 * useful to see that functionality seperated out. */

                vorbis_info_init(vi);
                vorbis_comment_init(vc);

                if (ogg_stream_pagein(os, og) < 0)
                {
                    /* error; stream version mismatch perhaps */
                    fprintf(stderr, "error reading first page of ogg bitstream data.\n");
                    exit(1);
                }

                if (ogg_stream_packetout(os, op) != 1)
                {
                    /* no page? must not be vorbis */
                    fprintf(stderr, "error reading initial header packet.\n");
                    exit(1);
                }

                if (vorbis_synthesis_headerin(vi, vc, op) < 0)
                {
                    /* error case; not a vorbis header */
                    fprintf(stderr, "this ogg bitstream does not contain vorbis audio data.\n");
                    exit(1);
                }

                ////                /* At this point, we're sure we're Vorbis. We've set up the logical
                ////                   (Ogg) bitstream decoder. Get the comment and codebook headers and
                ////                   set up the Vorbis decoder */

                ////                /* The next two packets in order are the comment and codebook headers.
                ////                   They're likely large and may span multiple pages. Thus we read
                ////                   and submit data until we get our two packets, watching that no
                ////                   pages are missing. If a page is missing, error out; losing a
                ////                   header page is the only place where missing data is fatal. */

                ////                i = 0;
                ////                while (i < 2)
                ////                {
                ////                    while (i < 2)
                ////                    {
                ////                        int result = ogg_sync_pageout(oggSyncState, oggPage);
                ////                        if (result == 0) break; /* Need more data */
                ////                                                /* Don't complain about missing or corrupt data yet. We'll
                ////                                                   catch it at the packet output phase */
                ////                        if (result == 1)
                ////                        {
                ////                            ogg_stream_pagein(oggStreamState, oggPage); /* we can ignore any errors here
                ////                                         as they'll also become apparent
                ////                                         at packetout */
                ////                            while (i < 2)
                ////                            {
                ////                                result = ogg_stream_packetout(oggStreamState, oggPacket);
                ////                                if (result == 0) break;
                ////                                if (result < 0)
                ////                                {
                ////                                    /* Uh oh; data at some point was corrupted or missing!
                ////                                       We can't tolerate that in a header.  Die. */
                ////                                    fprintf(stderr, "Corrupt secondary header.  Exiting.\n");
                ////                                    exit(1);
                ////                                }
                ////                                result = vorbis_synthesis_headerin(vorbisInfo, vorbisComment, oggPacket);
                ////                                if (result < 0)
                ////                                {
                ////                                    fprintf(stderr, "Corrupt secondary header.  Exiting.\n");
                ////                                    exit(1);
                ////                                }
                ////                                i++;
                ////                            }
                ////                        }
                ////                    }
                ////                    /* no harm in not checking before adding more */
                ////                    buffer = ogg_sync_buffer(oggSyncState, 4096);
                ////                    bytes = fread(buffer, 1, 4096, stdin);
                ////                    if (bytes == 0 && i < 2)
                ////                    {
                ////                        fprintf(stderr, "End of file before finding all Vorbis headers!\n");
                ////                        exit(1);
                ////                    }
                ////                    ogg_sync_wrote(oggSyncState, bytes);
                ////                }

                ////                /* Throw the comments plus a few lines about the bitstream we're
                ////                   decoding */
                ////                {
                ////                    char** ptr = vorbisComment.user_comments;
                ////                    while (*ptr)
                ////                    {
                ////                        fprintf(stderr, "%s\n", *ptr);
                ////                        ++ptr;
                ////                    }
                ////                    fprintf(stderr, "\nBitstream is %d channel, %ldHz\n", vorbisInfo.channels, vorbisInfo.rate);
                ////                    fprintf(stderr, "Encoded by: %s\n\n", vorbisComment.vendor);
                ////                }

                ////                convsize = 4096 / vorbisInfo.channels;

                ////                /* OK, got and parsed all three headers. Initialize the Vorbis
                ////                   packet->PCM decoder. */
                ////                if (vorbis_synthesis_init(vorbisDspState, vorbisInfo) == 0)
                ////                { /* central decode state */
                ////                    vorbis_block_init(vorbisDspState, vorbisBlock);          /* local state for most of the decode
                ////                                              so multiple block decodes can
                ////                                              proceed in parallel. We could init
                ////                                              multiple vorbis_block structures
                ////                                              for vd here */

                ////                    /* The rest is just a straight decode loop until end of stream */
                ////                    while (eos == 0)
                ////                    {
                ////                        while (eos == 0)
                ////                        {
                ////                            int result = ogg_sync_pageout(oggSyncState, oggPage);
                ////                            if (result == 0) break; /* need more data */
                ////                            if (result < 0)
                ////                            { /* missing or corrupt data at this page position */
                ////                                fprintf(stderr, "Corrupt or missing data in bitstream; "



                ////                                        "continuing...\n");
                ////                            }
                ////                            else
                ////                            {
                ////                                ogg_stream_pagein(oggStreamState, oggPage); /* can safely ignore errors at
                ////                                           this point */
                ////                                while (1)
                ////                                {
                ////                                    result = ogg_stream_packetout(&oggStreamState, &oggPacket);

                ////                                    if (result == 0) break; /* need more data */
                ////                                    if (result < 0)
                ////                                    { /* missing or corrupt data at this page position */
                ////                                      /* no reason to complain; already complained above */
                ////                                    }
                ////                                    else
                ////                                    {
                ////                                        /* we have a packet.  Decode it */
                ////                                        float** pcm;
                ////                                        int samples;

                ////                                        if (vorbis_synthesis(&vorbisBlock, &oggPacket) == 0) /* test for success! */
                ////                                            vorbis_synthesis_blockin(&vorbisDspState, &vorbisBlock);
                ////                                        /*

                ////                                        **pcm is a multichannel float vector.  In stereo, for
                ////                                        example, pcm[0] is left, and pcm[1] is right.  samples is
                ////                                        the size of each channel.  Convert the float values
                ////                                        (-1.<=range<=1.) to whatever PCM format and write it out */

                ////                                        while ((samples = vorbis_synthesis_pcmout(&vorbisDspState, &pcm)) > 0)
                ////                                        {
                ////                                            int j;
                ////                                            int clipflag = 0;
                ////                                            int bout = (samples < convsize ? samples : convsize);

                ////                                            /* convert floats to 16 bit signed ints (host order) and
                ////                                               interleave */
                ////                                            for (i = 0; i < vorbisInfo.channels; i++)
                ////                                            {
                ////                                                ogg_int16_t* ptr = convbuffer + i;
                ////                                                float* mono = pcm[i];
                ////                                                for (j = 0; j < bout; j++)
                ////                                                {
                ////#if 1
                ////                      int val=floor(mono[j]*32767.f+.5f);
                ////#else /* optional dither */
                ////                                                    int val = mono[j] * 32767.f + drand48() - 0.5f;
                ////#endif
                ////                                                    /* might as well guard against clipping */
                ////                                                    if (val > 32767)
                ////                                                    {
                ////                                                        val = 32767;
                ////                                                        clipflag = 1;
                ////                                                    }
                ////                                                    if (val < -32768)
                ////                                                    {
                ////                                                        val = -32768;
                ////                                                        clipflag = 1;
                ////                                                    }
                ////                                                    *ptr = val;
                ////                                                    ptr += vorbisInfo.channels;
                ////                                                }
                ////                                            }

                ////                                            if (clipflag)
                ////                                                fprintf(stderr, "Clipping in frame %ld\n", (long)(vorbisDspState.sequence));


                ////                                            fwrite(convbuffer, 2 * vorbisInfo.channels, bout, stdout);

                ////                                            vorbis_synthesis_read(vorbisDspState, bout); /* tell libvorbis how
                ////                                                      many samples we
                ////                                                      actually consumed */
                ////                                        }
                ////                                    }
                ////                                }
                ////                                if (ogg_page_eos(oggPage) != 0) eos = 1;
                ////                            }
                ////                        }
                ////                        if (eos == 0)
                ////                        {
                ////                            buffer = ogg_sync_buffer(oggSyncState, 4096);
                ////                            bytes = fread(buffer, 1, 4096, stdin);
                ////                            ogg_sync_wrote(oggSyncState, bytes);
                ////                            if (bytes == 0) eos = 1;
                ////                        }
                ////                    }

                ////                    /* ogg_page and ogg_packet structs always point to storage in
                ////                       libvorbis.  They're never freed or manipulated directly */

                ////                    vorbis_block_clear(vorbisBlock);
                ////                    vorbis_dsp_clear(vorbisDspState);
                ////                }
                ////                else
                ////                {
                ////                    fprintf(stderr, "Error: Corrupt header during playback initialization.\n");
                ////                }

                ////                /* clean up this logical bitstream; before exit we see if we're
                ////                   followed by another [chained] */

                ////                ogg_stream_clear(oggStreamState);
                ////                vorbis_comment_clear(vorbisComment);
                ////                vorbis_info_clear(vorbisInfo);  /* must be called last */
            }

            /* OK, clean up the framer */
            ogg_sync_clear(oy);

            fprintf(stderr, "Done.\n");
        }
示例#3
0
        public static int _packetout(ogg_stream_state os, ogg_packet op, int adv)
        {
            /* The last part of decode. We have the stream broken into packet
             * segments.  Now we need to group them into packets (or return the
             * out of sync markers) */

            long ptr = os.lacing_returned;

            if (os.lacing_packet <= ptr)
            {
                return(0);
            }

            if ((os.lacing_vals[ptr] & 0x400) != 0)
            {
                /* we need to tell the codec there's a gap; it might need to
                 * handle previous packet dependencies. */
                os.lacing_returned++;
                os.packetno++;
                return(-1);
            }

            if (op == null && adv == 0)
            {
                return(1);                          /* just using peek as an inexpensive way
                                                     * to ask if there's a whole packet
                                                     * waiting */
            }
            /* Gather the whole packet. We'll have no holes or a partial packet */
            {
                int  size  = os.lacing_vals[ptr] & 0xff;
                long bytes = size;
                int  eos   = os.lacing_vals[ptr] & 0x200; /* last packet of the stream? */
                int  bos   = os.lacing_vals[ptr] & 0x100; /* first packet of the stream? */

                while (size == 255)
                {
                    int val = os.lacing_vals[++ptr];
                    size = val & 0xff;
                    if ((val & 0x200) != 0)
                    {
                        eos = 0x200;
                    }
                    bytes += size;
                }

                if (op != null)
                {
                    op.e_o_s      = eos;
                    op.b_o_s      = bos;
                    op.packet     = os.body_data + os.body_returned;
                    op.packetno   = os.packetno;
                    op.granulepos = os.granule_vals[ptr];
                    op.bytes      = bytes;
                }

                if (adv != 0)
                {
                    os.body_returned  += bytes;
                    os.lacing_returned = ptr + 1;
                    os.packetno++;
                }
            }
            return(1);
        }
示例#4
0
        /* The Vorbis header is in three packets; the initial small packet in
         * the first page that identifies basic parameters, a second packet
         * with bitstream comments and a third packet that holds the
         * codebook. */

        public static int vorbis_synthesis_headerin(vorbis_info vi, vorbis_comment vc, ogg_packet op)
        {
            oggpack_buffer opb = new oggpack_buffer();

            if (op != null)
            {
                oggpack_readinit(opb, op.packet, op.bytes);

                /* Which of the three types of header is this? */
                /* Also verify header-ness, vorbis */
                {
                    var  buffer   = new ArrayPointer();
                    long packtype = oggpack_read(opb, 8);
                    //memset(buffer, 0, 6);
                    _v_readstring(opb, buffer, 6);
                    if (memcmp(buffer, "vorbis", 6) != 0)
                    {
                        /* not a vorbis header */
                        return(OV_ENOTVORBIS);
                    }
                    switch (packtype)
                    {
                    case 0x01:     /* least significant *bit* is read first */
                        if (op.b_o_s == 0)
                        {
                            /* Not the initial packet */
                            return(OV_EBADHEADER);
                        }
                        if (vi.rate != 0)
                        {
                            /* previously initialized info header */
                            return(OV_EBADHEADER);
                        }

                        return(_vorbis_unpack_info(vi, opb));

                    case 0x03:     /* least significant *bit* is read first */
                        if (vi.rate == 0)
                        {
                            /* um... we didn't get the initial header */
                            return(OV_EBADHEADER);
                        }
                        if (vc.vendor != null)
                        {
                            /* previously initialized comment header */
                            return(OV_EBADHEADER);
                        }

                        return(_vorbis_unpack_comment(vc, opb));

                    case 0x05:     /* least significant *bit* is read first */
                        if (vi.rate == 0 || vc.vendor == null)
                        {
                            /* um... we didn;t get the initial header or comments yet */
                            return(OV_EBADHEADER);
                        }
                        if (vi.codec_setup == null)
                        {
                            /* improperly initialized vorbis_info */
                            return(OV_EFAULT);
                        }
                        if (((codec_setup_info)vi.codec_setup).books > 0)
                        {
                            /* previously initialized setup header */
                            return(OV_EBADHEADER);
                        }

                        return(_vorbis_unpack_books(vi, opb));

                    default:
                        /* Not a valid vorbis header type */
                        return(OV_EBADHEADER);
                        //break;
                    }
                }
            }
            return(OV_EBADHEADER);
        }