예제 #1
0
        private static short[] GetFinalBuffer(int[] Buffer)
        {
            short[] Output = new short[Buffer.Length];

            for (int Offset = 0; Offset < Buffer.Length; Offset++)
            {
                Output[Offset] = DspUtils.Saturate(Buffer[Offset]);
            }

            return(Output);
        }
예제 #2
0
        private unsafe static short[] GetFinalBuffer(int[] buffer)
        {
            short[] output = new short[buffer.Length];

            int offset = 0;

            // Perform Saturation using SSE2 if supported
            if (Sse2.IsSupported)
            {
                fixed(int *inptr = buffer)
                fixed(short *outptr = output)
                {
                    for (; offset + 32 <= buffer.Length; offset += 32)
                    {
                        // Unroll the loop a little to ensure the CPU pipeline
                        // is always full.
                        Vector128 <int> block1A = Sse2.LoadVector128(inptr + offset + 0);
                        Vector128 <int> block1B = Sse2.LoadVector128(inptr + offset + 4);

                        Vector128 <int> block2A = Sse2.LoadVector128(inptr + offset + 8);
                        Vector128 <int> block2B = Sse2.LoadVector128(inptr + offset + 12);

                        Vector128 <int> block3A = Sse2.LoadVector128(inptr + offset + 16);
                        Vector128 <int> block3B = Sse2.LoadVector128(inptr + offset + 20);

                        Vector128 <int> block4A = Sse2.LoadVector128(inptr + offset + 24);
                        Vector128 <int> block4B = Sse2.LoadVector128(inptr + offset + 28);

                        Vector128 <short> output1 = Sse2.PackSignedSaturate(block1A, block1B);
                        Vector128 <short> output2 = Sse2.PackSignedSaturate(block2A, block2B);
                        Vector128 <short> output3 = Sse2.PackSignedSaturate(block3A, block3B);
                        Vector128 <short> output4 = Sse2.PackSignedSaturate(block4A, block4B);

                        Sse2.Store(outptr + offset + 0, output1);
                        Sse2.Store(outptr + offset + 8, output2);
                        Sse2.Store(outptr + offset + 16, output3);
                        Sse2.Store(outptr + offset + 24, output4);
                    }
                }
            }

            // Process left overs
            for (; offset < buffer.Length; offset++)
            {
                output[offset] = DspUtils.Saturate(buffer[offset]);
            }

            return(output);
        }
예제 #3
0
        public static int[] Decode(byte[] Buffer, AdpcmDecoderContext Context)
        {
            int Samples = GetSamplesCountFromSize(Buffer.Length);

            int[] Pcm = new int[Samples * 2];

            short History0 = Context.History0;
            short History1 = Context.History1;

            int InputOffset  = 0;
            int OutputOffset = 0;

            while (InputOffset < Buffer.Length)
            {
                byte Header = Buffer[InputOffset++];

                int Scale = 0x800 << (Header & 0xf);

                int CoeffIndex = (Header >> 4) & 7;

                short Coeff0 = Context.Coefficients[CoeffIndex * 2 + 0];
                short Coeff1 = Context.Coefficients[CoeffIndex * 2 + 1];

                int FrameSamples = SamplesPerFrame;

                if (FrameSamples > Samples)
                {
                    FrameSamples = Samples;
                }

                int Value = 0;

                for (int SampleIndex = 0; SampleIndex < FrameSamples; SampleIndex++)
                {
                    int Sample;

                    if ((SampleIndex & 1) == 0)
                    {
                        Value = Buffer[InputOffset++];

                        Sample = (Value << 24) >> 28;
                    }
                    else
                    {
                        Sample = (Value << 28) >> 28;
                    }

                    int Prediction = Coeff0 * History0 + Coeff1 * History1;

                    Sample = (Sample * Scale + Prediction + 0x400) >> 11;

                    short SaturatedSample = DspUtils.Saturate(Sample);

                    History1 = History0;
                    History0 = SaturatedSample;

                    Pcm[OutputOffset++] = SaturatedSample;
                    Pcm[OutputOffset++] = SaturatedSample;
                }

                Samples -= FrameSamples;
            }

            Context.History0 = History0;
            Context.History1 = History1;

            return(Pcm);
        }