コード例 #1
0
ファイル: framing.cs プロジェクト: ETdoFresh/OggVorbis
        /* Helpers for ogg_stream_encode; this keeps the structure and
         * what's happening fairly clear */

        public static int _os_body_expand(ogg_stream_state os, long needed)
        {
            if (os.body_storage - needed <= os.body_fill)
            {
                long body_storage;
                //object ret;
                if (os.body_storage > long.MaxValue - needed)
                {
                    ogg_stream_clear(os);
                    return(-1);
                }
                body_storage = os.body_storage + needed;
                // Uses an expanding array, hence reallocation should not be necessary
                //if (body_storage < long.MaxValue - 1024) body_storage += 1024;
                //ret = _ogg_realloc(os.body_data, body_storage /* * sizeof(*os.body_data)*/);
                //if (ret == null)
                //{
                //    ogg_stream_clear(os);
                //    return -1;
                //}
                os.body_storage = body_storage;
                //os.body_data = ret;
            }
            return(0);
        }
コード例 #2
0
ファイル: framing.cs プロジェクト: ETdoFresh/OggVorbis
 public static int _os_lacing_expand(ogg_stream_state os, long needed)
 {
     if (os.lacing_storage - needed <= os.lacing_fill)
     {
         long   lacing_storage;
         object ret;
         if (os.lacing_storage > long.MaxValue - needed)
         {
             ogg_stream_clear(os);
             return(-1);
         }
         lacing_storage = os.lacing_storage + needed;
         if (lacing_storage < long.MaxValue - 32)
         {
             lacing_storage += 32;
         }
         ret = _ogg_realloc(os.lacing_vals, lacing_storage /* * sizeof(*os.lacing_vals)*/);
         if (ret == null)
         {
             ogg_stream_clear(os);
             return(-1);
         }
         os.lacing_vals = (int[])ret;
         ret            = _ogg_realloc(os.granule_vals, lacing_storage /* * sizeof(*os.granule_vals)*/);
         if (ret == null)
         {
             ogg_stream_clear(os);
             return(-1);
         }
         os.granule_vals   = (long[])ret;
         os.lacing_storage = lacing_storage;
     }
     return(0);
 }
コード例 #3
0
ファイル: framing.cs プロジェクト: ETdoFresh/OggVorbis
 /* _clear does not free os, only the non-flat storage within */
 public static int ogg_stream_clear(ogg_stream_state os)
 {
     os.body_data    = null;
     os.lacing_vals  = null;
     os.granule_vals = null;
     return(0);
 }
コード例 #4
0
ファイル: framing.cs プロジェクト: ETdoFresh/OggVorbis
 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));
 }
コード例 #5
0
ファイル: framing.cs プロジェクト: ETdoFresh/OggVorbis
 /* async/delayed error detection for the ogg_stream_state */
 public static int ogg_stream_check(ogg_stream_state os)
 {
     if (os == null || os.body_data == null)
     {
         return(-1);
     }
     return(0);
 }
コード例 #6
0
ファイル: framing.cs プロジェクト: ETdoFresh/OggVorbis
        /* init the encode/decode logical stream state */

        public static int ogg_stream_init(ogg_stream_state os, int serialno)
        {
            os.body_storage   = 16 * 1024;
            os.lacing_storage = 1024;

            os.stream       = new MemoryStream();
            os.body_data    = new ArrayPointer(os.stream); // _ogg_malloc(os.body_storage * sizeof(*os.body_data));
            os.lacing_vals  = new int[os.lacing_storage];  // _ogg_malloc(os.lacing_storage * sizeof(*os.lacing_vals));
            os.granule_vals = new long[os.lacing_storage]; // _ogg_malloc(os.lacing_storage * sizeof(*os.granule_vals));

            if (os.body_data == null || os.lacing_vals == null || os.granule_vals == null)
            {
                ogg_stream_clear(os);
                return(-1);
            }

            os.serialno = serialno;

            return(0);
        }
コード例 #7
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");
        }
コード例 #8
0
ファイル: framing.cs プロジェクト: ETdoFresh/OggVorbis
        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);
        }
コード例 #9
0
ファイル: framing.cs プロジェクト: ETdoFresh/OggVorbis
        /* add the incoming page to the stream state; we decompose the page
         * into packet segments here as well. */

        public static int ogg_stream_pagein(ogg_stream_state os, ogg_page og)
        {
            ArrayPointer header   = og.header;
            ArrayPointer body     = og.body;
            long         bodysize = og.body_len;
            int          segptr   = 0;

            int  version    = ogg_page_version(og);
            int  continued  = ogg_page_continued(og);
            int  bos        = ogg_page_bos(og);
            int  eos        = ogg_page_eos(og);
            long granulepos = ogg_page_granulepos(og);
            int  serialno   = ogg_page_serialno(og);
            long pageno     = ogg_page_pageno(og);
            int  segments   = header[26];

            if (ogg_stream_check(os) != 0)
            {
                return(-1);
            }

            /* clean up 'returned data' */
            {
                long lr = os.lacing_returned;
                long br = os.body_returned;

                /* body data */
                if (br != 0)
                {
                    os.body_fill -= br;
                    if (os.body_fill != 0)
                    {
                        memmove(os.body_data, os.body_data + br, os.body_fill);
                    }
                    os.body_returned = 0;
                }

                if (lr != 0)
                {
                    /* segment table */
                    if ((os.lacing_fill - lr) != 0)
                    {
                        memmove(os.lacing_vals, /*os.lacing_vals +*/ lr,
                                (os.lacing_fill - lr) /* * sizeof(*os.lacing_vals)*/);
                        memmove(os.granule_vals, /*os.granule_vals +*/ lr,
                                (os.lacing_fill - lr) /* * sizeof(*os.granule_vals)*/);
                    }
                    os.lacing_fill    -= lr;
                    os.lacing_packet  -= lr;
                    os.lacing_returned = 0;
                }
            }

            /* check the serial number */
            if (serialno != os.serialno)
            {
                return(-1);
            }
            if (version > 0)
            {
                return(-1);
            }

            if (_os_lacing_expand(os, segments + 1) != 0)
            {
                return(-1);
            }

            /* are we in sequence? */
            if (pageno != os.pageno)
            {
                long i;

                /* unroll previous partial packet (if any) */
                for (i = os.lacing_packet; i < os.lacing_fill; i++)
                {
                    os.body_fill -= os.lacing_vals[i] & 0xff;
                }
                os.lacing_fill = os.lacing_packet;

                /* make a note of dropped data in segment table */
                if (os.pageno != -1)
                {
                    os.lacing_vals[os.lacing_fill++] = 0x400;
                    os.lacing_packet++;
                }
            }

            /* are we a 'continued packet' page?  If so, we may need to skip
             * some segments */
            if (continued != 0)
            {
                if (os.lacing_fill < 1 ||
                    (os.lacing_vals[os.lacing_fill - 1] & 0xff) < 255 ||
                    os.lacing_vals[os.lacing_fill - 1] == 0x400)
                {
                    bos = 0;
                    for (; segptr < segments; segptr++)
                    {
                        int val = header[27 + segptr];
                        body     += val;
                        bodysize -= val;
                        if (val < 255)
                        {
                            segptr++;
                            break;
                        }
                    }
                }
            }

            if (bodysize != 0)
            {
                if (_os_body_expand(os, bodysize) != 0)
                {
                    return(-1);
                }
                memcpy(os.body_data + os.body_fill, body, bodysize);
                os.body_fill += bodysize;
            }

            {
                long saved = -1;
                while (segptr < segments)
                {
                    int val = header[27 + segptr];
                    os.lacing_vals[os.lacing_fill]  = val;
                    os.granule_vals[os.lacing_fill] = -1;

                    if (bos != 0)
                    {
                        os.lacing_vals[os.lacing_fill] |= 0x100;
                        bos = 0;
                    }

                    if (val < 255)
                    {
                        saved = os.lacing_fill;
                    }

                    os.lacing_fill++;
                    segptr++;

                    if (val < 255)
                    {
                        os.lacing_packet = os.lacing_fill;
                    }
                }

                /* set the granulepos on the last granuleval of the last full packet */
                if (saved != -1)
                {
                    os.granule_vals[saved] = granulepos;
                }
            }

            if (eos != 0)
            {
                os.e_o_s = 1;
                if (os.lacing_fill > 0)
                {
                    os.lacing_vals[os.lacing_fill - 1] |= 0x200;
                }
            }

            os.pageno = pageno + 1;

            return(0);
        }