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); }
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); }
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); }