Пример #1
0
        /* simplistic, wasteful way of doing this (unique lookup for each mode/submapping); there should be a central repository for
         * identical lookups.  That will require minor work, so I'm putting it off as low priority.
         *
         * Why a lookup for each backend in a given mode?  Because the blocksize is set by the mode, and low backend lookups may require
         * parameters from other areas of the mode/mapping */

        static void mapping0_free_info(ref vorbis_info_mapping i)
        {
            vorbis_info_mapping0 info = i as vorbis_info_mapping0;

            if (info != null)
            {
                info = null;
            }
        }
Пример #2
0
        static void mapping0_pack(ref vorbis_info vi, vorbis_info_mapping vm, ref Ogg.oggpack_buffer opb)
        {
            int i;
            vorbis_info_mapping0 info = vm as vorbis_info_mapping0;

            /* another 'we meant to do it this way' hack...  up to beta 4, we packed 4 binary zeros here to signify one submapping in use.  We
             * now redefine that to mean four bitflags that indicate use of deeper features; bit0:submappings, bit1:coupling,
             * bit2,3: reserved. This is backward compatable with all actual uses of the beta code. */

            if (info.submaps > 1)
            {
                Ogg.oggpack_write(ref opb, 1, 1);
                Ogg.oggpack_write(ref opb, (uint)(info.submaps - 1), 4);
            }
            else
            {
                Ogg.oggpack_write(ref opb, 0, 1);
            }

            if (info.coupling_steps > 0)
            {
                Ogg.oggpack_write(ref opb, 1, 1);
                Ogg.oggpack_write(ref opb, (uint)(info.coupling_steps - 1), 8);

                for (i = 0; i < info.coupling_steps; i++)
                {
                    Ogg.oggpack_write(ref opb, (uint)info.coupling_mag[i], ilog((uint)vi.channels));
                    Ogg.oggpack_write(ref opb, (uint)info.coupling_ang[i], ilog((uint)vi.channels));
                }
            }
            else
            {
                Ogg.oggpack_write(ref opb, 0, 1);
            }

            Ogg.oggpack_write(ref opb, 0, 2); /* 2,3:reserved */

            /* we don't write the channel submappings if we only have one... */
            if (info.submaps > 1)
            {
                for (i = 0; i < vi.channels; i++)
                {
                    Ogg.oggpack_write(ref opb, (uint)info.chmuxlist[i], 4);
                }
            }

            for (i = 0; i < info.submaps; i++)
            {
                Ogg.oggpack_write(ref opb, 0, 8); /* time submap unused */
                Ogg.oggpack_write(ref opb, (uint)info.floorsubmap[i], 8);
                Ogg.oggpack_write(ref opb, (uint)info.residuesubmap[i], 8);
            }
        }
Пример #3
0
        static int mapping0_inverse(ref vorbis_block vb, vorbis_info_mapping l)
        {
            vorbis_dsp_state     vd   = vb.vd;
            vorbis_info          vi   = vd.vi;
            codec_setup_info     ci   = vi.codec_setup as codec_setup_info;
            private_state        b    = vd.backend_state as private_state;
            vorbis_info_mapping0 info = l as vorbis_info_mapping0;

            int i, j;
            int n = vb.pcmend = ci.blocksizes[vb.W];

            float **pcmbundle  = stackalloc float *[vi.channels];
            int *   zerobundle = stackalloc int[vi.channels];

            int *  nonzero   = stackalloc int[vi.channels];
            void **floormemo = stackalloc void *[vi.channels];

            /* recover the spectral envelope; store it in the PCM vector for now */
            for (i = 0; i < vi.channels; i++)
            {
                int submap = info.chmuxlist[i];

                floormemo[i] = _floor_P[ci.floor_type[info.floorsubmap[submap]]].inverse1(ref vb, b.flr[info.floorsubmap[submap]]);

                if (floormemo[i] != null)
                {
                    nonzero[i] = 1;
                }
                else
                {
                    nonzero[i] = 0;
                }

                ZeroMemory(vb.pcm[i], sizeof(float) * n / 2);
            }

            /* channel coupling can 'dirty' the nonzero listing */
            for (i = 0; i < info.coupling_steps; i++)
            {
                if (nonzero[info.coupling_mag[i]] != 0 || nonzero[info.coupling_ang[i]] != 0)
                {
                    nonzero[info.coupling_mag[i]] = 1;
                    nonzero[info.coupling_ang[i]] = 1;
                }
            }

            /* recover the residue into our working vectors */
            for (i = 0; i < info.submaps; i++)
            {
                int ch_in_bundle = 0;

                for (j = 0; j < vi.channels; j++)
                {
                    if (info.chmuxlist[j] == i)
                    {
                        if (nonzero[j] != 0)
                        {
                            zerobundle[ch_in_bundle] = 1;
                        }
                        else
                        {
                            zerobundle[ch_in_bundle] = 0;
                        }

                        pcmbundle[ch_in_bundle++] = vb.pcm[j];
                    }
                }

                _residue_P[ci.residue_type[info.residuesubmap[i]]].inverse(ref vb, b.residue[info.residuesubmap[i]], pcmbundle, zerobundle, ch_in_bundle);
            }

            /* channel coupling */
            for (i = info.coupling_steps - 1; i >= 0; i--)
            {
                float *pcmM = vb.pcm[info.coupling_mag[i]];
                float *pcmA = vb.pcm[info.coupling_ang[i]];

                for (j = 0; j < n / 2; j++)
                {
                    float mag = pcmM[j];
                    float ang = pcmA[j];

                    if (mag > 0)
                    {
                        if (ang > 0)
                        {
                            pcmM[j] = mag;
                            pcmA[j] = mag - ang;
                        }
                        else
                        {
                            pcmA[j] = mag;
                            pcmM[j] = mag + ang;
                        }
                    }
                    else
                    {
                        if (ang > 0)
                        {
                            pcmM[j] = mag;
                            pcmA[j] = mag + ang;
                        }
                        else
                        {
                            pcmA[j] = mag;
                            pcmM[j] = mag - ang;
                        }
                    }
                }
            }

            /* compute and apply spectral envelope */
            for (i = 0; i < vi.channels; i++)
            {
                float *pcm    = vb.pcm[i];
                int    submap = info.chmuxlist[i];

                _floor_P[ci.floor_type[info.floorsubmap[submap]]].inverse2(ref vb, b.flr[info.floorsubmap[submap]], floormemo[i], pcm);
            }

            /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
            /* only MDCT right now.... */
            for (i = 0; i < vi.channels; i++)
            {
                float *pcm = vb.pcm[i];
                mdct_backward(b.transform[vb.W][0] as mdct_lookup, pcm, pcm);
            }

            /* all done! */
            return(0);
        }