CUETools.Codecs.FLAKE.FlakeWriter.encode_residual_lpc_sub C# (CSharp) Method

encode_residual_lpc_sub() private method

private encode_residual_lpc_sub ( FlacFrame frame, float lpcs, int iWindow, int order, int ch ) : void
frame FlacFrame
lpcs float
iWindow int
order int
ch int
return void
		unsafe void encode_residual_lpc_sub(FlacFrame frame, float* lpcs, int iWindow, int order, int ch)
		{
			// select LPC precision based on block size
			uint lpc_precision;
			if (frame.blocksize <= 192) lpc_precision = 7U;
			else if (frame.blocksize <= 384) lpc_precision = 8U;
			else if (frame.blocksize <= 576) lpc_precision = 9U;
			else if (frame.blocksize <= 1152) lpc_precision = 10U;
			else if (frame.blocksize <= 2304) lpc_precision = 11U;
			else if (frame.blocksize <= 4608) lpc_precision = 12U;
			else if (frame.blocksize <= 8192) lpc_precision = 13U;
			else if (frame.blocksize <= 16384) lpc_precision = 14U;
			else lpc_precision = 15;

			for (int i_precision = eparams.lpc_min_precision_search; i_precision <= eparams.lpc_max_precision_search && lpc_precision + i_precision < 16; i_precision++)
				// check if we already calculated with this order, window and precision
				if ((frame.subframes[ch].lpc_ctx[iWindow].done_lpcs[i_precision] & (1U << (order - 1))) == 0)
				{
					frame.subframes[ch].lpc_ctx[iWindow].done_lpcs[i_precision] |= (1U << (order - 1));

					uint cbits = lpc_precision + (uint)i_precision;

					frame.current.type = SubframeType.LPC;
					frame.current.order = order;
					frame.current.window = iWindow;

					fixed (int* coefs = frame.current.coefs)
					{
						lpc.quantize_lpc_coefs(lpcs + (frame.current.order - 1) * lpc.MAX_LPC_ORDER,
							frame.current.order, cbits, coefs, out frame.current.shift, 15, 0);

						if (frame.current.shift < 0 || frame.current.shift > 15)
							throw new Exception("negative shift");

						ulong csum = 0;
						for (int i = frame.current.order; i > 0; i--)
							csum += (ulong)Math.Abs(coefs[i - 1]);

						if ((csum << frame.subframes[ch].obits) >= 1UL << 32)
							lpc.encode_residual_long(frame.current.residual, frame.subframes[ch].samples, frame.blocksize, frame.current.order, coefs, frame.current.shift);
						else
							lpc.encode_residual(frame.current.residual, frame.subframes[ch].samples, frame.blocksize, frame.current.order, coefs, frame.current.shift);

					}
					int pmax = get_max_p_order(eparams.max_partition_order, frame.blocksize, frame.current.order);
					int pmin = Math.Min(eparams.min_partition_order, pmax);
					uint best_size = calc_rice_params(frame.current.rc, pmin, pmax, frame.current.residual, (uint)frame.blocksize, (uint)frame.current.order, PCM.BitsPerSample);
					// not working
					//for (int o = 1; o <= frame.current.order; o++)
					//{
					//    if (frame.current.coefs[o - 1] > -(1 << frame.current.shift))
					//    {
					//        for (int i = o; i < frame.blocksize; i++)
					//            frame.current.residual[i] += frame.subframes[ch].samples[i - o] >> frame.current.shift;
					//        frame.current.coefs[o - 1]--;
					//        uint new_size = calc_rice_params(ref frame.current.rc, pmin, pmax, frame.current.residual, (uint)frame.blocksize, (uint)frame.current.order);
					//        if (new_size > best_size)
					//        {
					//            for (int i = o; i < frame.blocksize; i++)
					//                frame.current.residual[i] -= frame.subframes[ch].samples[i - o] >> frame.current.shift;
					//            frame.current.coefs[o - 1]++;
					//        }
					//    }
					//}
					frame.current.size = (uint)(frame.current.order * frame.subframes[ch].obits + 4 + 5 + frame.current.order * (int)cbits + 6 + (int)best_size);
					frame.ChooseBestSubframe(ch);
				}
		}