private unsafe List <FlacSubFrameData> AllocOuputMemory() { if (_destBuffer == null || _destBuffer.Length < (Header.Channels * Header.BlockSize)) { _destBuffer = new int[Header.Channels * Header.BlockSize]; } if (_residualBuffer == null || _residualBuffer.Length < (Header.Channels * Header.BlockSize)) { _residualBuffer = new int[Header.Channels * Header.BlockSize]; } List <FlacSubFrameData> output = new List <FlacSubFrameData>(); for (int c = 0; c < Header.Channels; c++) { fixed(int *ptrDestBuffer = _destBuffer, ptrResidualBuffer = _residualBuffer) { FreeBuffers(); _handle1 = GCHandle.Alloc(_destBuffer, GCHandleType.Pinned); _handle2 = GCHandle.Alloc(_residualBuffer, GCHandleType.Pinned); FlacSubFrameData data = new FlacSubFrameData { DestBuffer = (ptrDestBuffer + c * Header.BlockSize), ResidualBuffer = (ptrResidualBuffer + c * Header.BlockSize) }; output.Add(data); } } return(output); }
public unsafe FlacSubFrameLPC(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bps, int order) : base(header) { //warmup _warmup = new int[FlacConstant.MaxLpcOrder]; for (int i = 0; i < order; i++) { _warmup[i] = data.ResidualBuffer[i] = reader.ReadBitsSigned(bps); } //header int u32 = (int)reader.ReadBits(FlacConstant.SubframeLpcQlpCoeffPrecisionLen); if (u32 == (1 << FlacConstant.SubframeLpcQlpCoeffPrecisionLen) - 1) { Debug.WriteLine("Invalid FlacLPC qlp coeff precision."); return; //return false; } _qlpCoeffPrecision = u32 + 1; int level = reader.ReadBitsSigned(FlacConstant.SubframeLpcQlpShiftLen); if (level < 0) throw new Exception("negative shift"); _lpcShiftNeeded = level; _qlpCoeffs = new int[FlacConstant.MaxLpcOrder]; //qlp coeffs for (int i = 0; i < order; i++) { _qlpCoeffs[i] = reader.ReadBitsSigned(_qlpCoeffPrecision); } Residual = new FlacResidual(reader, header, data, order); for (int i = 0; i < order; i++) { data.DestBuffer[i] = data.ResidualBuffer[i]; } int i1 = order; int result = 0; while ((i1 >>= 1) != 0) { result++; } if (bps + _qlpCoeffPrecision + result <= 32) { if (bps <= 16 && _qlpCoeffPrecision <= 16) RestoreLPCSignal(data.ResidualBuffer + order, data.DestBuffer + order, header.BlockSize - order, order); //Restore(data.residualBuffer + order, data.destBuffer, Header.BlockSize - order, order, order); else RestoreLPCSignal(data.ResidualBuffer + order, data.DestBuffer + order, header.BlockSize - order, order); } else { RestoreLPCSignalWide(data.ResidualBuffer + order, data.DestBuffer + order, header.BlockSize - order, order);//RestoreWide(data.residualBuffer + order, data.destBuffer, Header.BlockSize - order, order, order); } }
public unsafe FlacSubFrameFixed(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bps, int order) : base(header) { for (int i = 0; i < order; i++) { data.ResidualBuffer[i] = data.DestBuffer[i] = reader.ReadBitsSigned(bps); } Residual = new FlacResidual(reader, header, data, order); //necessary for decoding RestoreSignal(data, header.BlockSize - order, order); }
public unsafe bool ProcessResidual(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int order) { data.Content.UpdateSize(PartitionOrder); int porder = PartitionOrder; FlacEntropyCoding codingMethod = CodingMethod; int psize = header.BlockSize >> porder; int resCnt = psize - order; int ricelength = 4 + (int)codingMethod; //4bit = RICE I | 5bit = RICE II //residual int j = order; int* r = data.ResidualBuffer + j; int partitioncount = 1 << porder; for (int p = 0; p < partitioncount; p++) { if (p == 1) resCnt = psize; int n = Math.Min(resCnt, header.BlockSize - j); int k = Content.Parameters[p] = (int)reader.ReadBits(ricelength); if (k == (1 << ricelength) - 1) { k = (int)reader.ReadBits(5); for (int i = n; i > 0; i--) { *(r) = reader.ReadBitsSigned((int)k); } } else { ReadFlacRiceBlock(reader, n, (int)k, r); r += n; } j += n; } return true; }
public unsafe bool ProcessResidual(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int order) { data.Content.UpdateSize(PartitionOrder); int porder = PartitionOrder; FlacEntropyCoding codingMethod = CodingMethod; int psize = header.BlockSize >> porder; int resCnt = psize - order; int ricelength = 4 + (int)codingMethod; //4bit = RICE I | 5bit = RICE II //residual int j = order; int *r = data.ResidualBuffer + j; int partitioncount = 1 << porder; for (int p = 0; p < partitioncount; p++) { if (p == 1) { resCnt = psize; } int n = Math.Min(resCnt, header.BlockSize - j); int k = Content.Parameters[p] = (int)reader.ReadBits(ricelength); if (k == (1 << ricelength) - 1) { k = (int)reader.ReadBits(5); for (int i = n; i > 0; i--) { *(r) = reader.ReadBitsSigned((int)k); } } else { ReadFlacRiceBlock(reader, n, (int)k, r); r += n; } j += n; } return(true); }
//http://www.hpl.hp.com/techreports/1999/HPL-1999-144.pdf private unsafe bool RestoreSignal(FlacSubFrameData subframeData, int length, int predictorOrder) { int *residual = subframeData.ResidualBuffer + predictorOrder; int *data = subframeData.DestBuffer + predictorOrder; int t0, t1, t2; //temp switch (predictorOrder) { case 0: for (int i = 0; i < length; i++) { *(data++) = *(residual++); } break; case 1: t1 = data[-1]; for (int i = 0; i < length; i++) { t1 += *(residual++); *(data++) = t1; } break; case 2: t2 = data[-2]; t1 = data[-1]; for (int i = 0; i < length; i++) { *(data++) = t0 = ((t1 << 1) + *(residual++)) - t2; t2 = t1; t1 = t0; } break; case 3: for (int i = 0; i < length; i++) { *(data) = *(residual) + (((data[-1] - data[-2]) << 1) + (data[-1] - data[-2])) + data[-3]; data++; residual++; } break; case 4: for (int i = 0; i < length; i++) { *(data) = *(residual) + ((data[-1] + data[-3]) << 2) - ((data[-2] << 2) + (data[-2] << 1)) - data[-4]; data++; residual++; } break; default: Debug.WriteLine("Invalid FlacFixedSubFrame predictororder."); return(false); } return(true); }
public unsafe FlacSubFrameLPC(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bps, int order) : base(header) { //warmup _warmup = new int[FlacConstant.MaxLpcOrder]; for (int i = 0; i < order; i++) { _warmup[i] = data.ResidualBuffer[i] = reader.ReadBitsSigned(bps); } //header int u32 = (int)reader.ReadBits(FlacConstant.SubframeLpcQlpCoeffPrecisionLen); if (u32 == (1 << FlacConstant.SubframeLpcQlpCoeffPrecisionLen) - 1) { Debug.WriteLine("Invalid FlacLPC qlp coeff precision."); return; //return false; } _qlpCoeffPrecision = u32 + 1; int level = reader.ReadBitsSigned(FlacConstant.SubframeLpcQlpShiftLen); if (level < 0) { throw new Exception("negative shift"); } _lpcShiftNeeded = level; _qlpCoeffs = new int[FlacConstant.MaxLpcOrder]; //qlp coeffs for (int i = 0; i < order; i++) { _qlpCoeffs[i] = reader.ReadBitsSigned(_qlpCoeffPrecision); } Residual = new FlacResidual(reader, header, data, order); for (int i = 0; i < order; i++) { data.DestBuffer[i] = data.ResidualBuffer[i]; } int i1 = order; int result = 0; while ((i1 >>= 1) != 0) { result++; } if (bps + _qlpCoeffPrecision + result <= 32) { if (bps <= 16 && _qlpCoeffPrecision <= 16) { RestoreLPCSignal(data.ResidualBuffer + order, data.DestBuffer + order, header.BlockSize - order, order); //Restore(data.residualBuffer + order, data.destBuffer, Header.BlockSize - order, order, order); } else { RestoreLPCSignal(data.ResidualBuffer + order, data.DestBuffer + order, header.BlockSize - order, order); } } else { RestoreLPCSignalWide(data.ResidualBuffer + order, data.DestBuffer + order, header.BlockSize - order, order);//RestoreWide(data.residualBuffer + order, data.destBuffer, Header.BlockSize - order, order, order); } }
private unsafe List<FlacSubFrameData> AllocOuputMemory() { if (_destBuffer == null || _destBuffer.Length < (Header.Channels * Header.BlockSize)) _destBuffer = new int[Header.Channels * Header.BlockSize]; if (_residualBuffer == null || _residualBuffer.Length < (Header.Channels * Header.BlockSize)) _residualBuffer = new int[Header.Channels * Header.BlockSize]; List<FlacSubFrameData> output = new List<FlacSubFrameData>(); for (int c = 0; c < Header.Channels; c++) { fixed (int* ptrDestBuffer = _destBuffer, ptrResidualBuffer = _residualBuffer) { _handle1 = GCHandle.Alloc(_destBuffer, GCHandleType.Pinned); _handle2 = GCHandle.Alloc(_residualBuffer, GCHandleType.Pinned); FlacSubFrameData data = new FlacSubFrameData { DestBuffer = (ptrDestBuffer + c * Header.BlockSize), ResidualBuffer = (ptrResidualBuffer + c * Header.BlockSize) }; output.Add(data); } } return output; }
public unsafe static FlacSubFrameBase GetSubFrame(FlacBitReader reader, FlacSubFrameData data, FlacFrameHeader header, int bps) { int wastedBits = 0, order = 0; uint x = reader.ReadBits(8); bool hasWastedBits = (x & 1) != 0; x &= 0xFE; //1111 1110 if (hasWastedBits) { int u = (int)reader.ReadUnary(); wastedBits = u + 1; bps -= wastedBits; } if ((x & 0x80) != 0) { Debug.WriteLine("Flacdecoder lost sync while reading FlacSubFrameHeader. [x & 0x80]."); return null; } FlacSubFrameBase subFrame; if ((x > 2 && x < 16) || (x > 24 && x < 64)) { Debug.WriteLine("Invalid FlacSubFrameHeader. [" + x.ToString("x") + "]"); return null; } if (x == 0) { subFrame = new FlacSubFrameConstant(reader, header, data, bps); } else if (x == 2) { //verbatim subFrame = new FlacSubFrameVerbatim(reader, header, data, bps); } else if (x >= 16 && x <= 24) { //fixed order = (int)((x >> 1) & 7); subFrame = new FlacSubFrameFixed(reader, header, data, bps, order); } else if (x >= 64) { //lpc order = (int)(((x >> 1) & 31) + 1); subFrame = new FlacSubFrameLPC(reader, header, data, bps, order); } else { Debug.WriteLine("Invalid Flac-SubframeType: x = " + x + "."); return null; } if (hasWastedBits) { int* ptrDest = data.DestBuffer; for (int i = 0; i < header.BlockSize; i++) { *(ptrDest++) <<= wastedBits; } } //System.Diagnostics.Debug.WriteLine(subFrame.GetType().Name); //check null removed subFrame.WastedBits = wastedBits; return subFrame; }
//http://www.hpl.hp.com/techreports/1999/HPL-1999-144.pdf private unsafe bool RestoreSignal(FlacSubFrameData subframeData, int length, int predictorOrder) { int* residual = subframeData.ResidualBuffer + predictorOrder; int* data = subframeData.DestBuffer + predictorOrder; int t0, t1, t2; //temp switch (predictorOrder) { case 0: for (int i = 0; i < length; i++) { *(data++) = *(residual++); } break; case 1: t1 = data[-1]; for (int i = 0; i < length; i++) { t1 += *(residual++); *(data++) = t1; } break; case 2: t2 = data[-2]; t1 = data[-1]; for (int i = 0; i < length; i++) { *(data++) = t0 = ((t1 << 1) + *(residual++)) - t2; t2 = t1; t1 = t0; } break; case 3: for (int i = 0; i < length; i++) { *(data) = *(residual) + (((data[-1] - data[-2]) << 1) + (data[-1] - data[-2])) + data[-3]; data++; residual++; } break; case 4: for (int i = 0; i < length; i++) { *(data) = *(residual) + ((data[-1] + data[-3]) << 2) - ((data[-2] << 2) + (data[-2] << 1)) - data[-4]; data++; residual++; } break; default: Debug.WriteLine("Invalid FlacFixedSubFrame predictororder."); return false; } return true; }
public unsafe static FlacSubFrameBase GetSubFrame(FlacBitReader reader, FlacSubFrameData data, FlacFrameHeader header, int bps) { int wastedBits = 0, order = 0; uint x = reader.ReadBits(8); bool hasWastedBits = (x & 1) != 0; x &= 0xFE; //1111 1110 if (hasWastedBits) { int u = (int)reader.ReadUnary(); wastedBits = u + 1; bps -= wastedBits; } if ((x & 0x80) != 0) { Debug.WriteLine("Flacdecoder lost sync while reading FlacSubFrameHeader. [x & 0x80]."); return(null); } FlacSubFrameBase subFrame; if ((x > 2 && x < 16) || (x > 24 && x < 64)) { Debug.WriteLine("Invalid FlacSubFrameHeader. [" + x.ToString("x") + "]"); return(null); } if (x == 0) { subFrame = new FlacSubFrameConstant(reader, header, data, bps); } else if (x == 2) { //verbatim subFrame = new FlacSubFrameVerbatim(reader, header, data, bps); } else if (x >= 16 && x <= 24) { //fixed order = (int)((x >> 1) & 7); subFrame = new FlacSubFrameFixed(reader, header, data, bps, order); } else if (x >= 64) { //lpc order = (int)(((x >> 1) & 31) + 1); subFrame = new FlacSubFrameLPC(reader, header, data, bps, order); } else { Debug.WriteLine("Invalid Flac-SubframeType: x = " + x + "."); return(null); } if (hasWastedBits) { int *ptrDest = data.DestBuffer; for (int i = 0; i < header.BlockSize; i++) { *(ptrDest++) <<= wastedBits; } } //System.Diagnostics.Debug.WriteLine(subFrame.GetType().Name); //check null removed subFrame.WastedBits = wastedBits; return(subFrame); }