namespace NSpeex { using System; internal class Ltp3Tap : Ltp { private float[][] e; private float[] gain = new float[3]; private int gain_bits; private int[] gain_cdbk; private int pitch_bits; public Ltp3Tap(int[] gain_cdbk_0, int gain_bits_1, int pitch_bits_2) { this.gain_cdbk = gain_cdbk_0; this.gain_bits = gain_bits_1; this.pitch_bits = pitch_bits_2; this.e = this.CreateJaggedArray(3, 0x80); } private T[][] CreateJaggedArray(int dim1, int dim2) { T[][] localArray = new T[dim1][]; for (int i = 0; i < dim1; i++) { localArray[i] = new T[dim2]; Array.Clear(localArray[i], 0, dim2); } return localArray; } private float Pitch_gain_search_3tap(float[] target, float[] ak, float[] awk1, float[] awk2, float[] exc, int es, int pitch, int p, int nsf, Bits bits, float[] exc2, int e2s, float[] r, int[] cdbk_index) { int num; int num2; float[] numArray2 = new float[3]; float[][] numArray3 = this.CreateJaggedArray(3, 3); int num3 = ((int)1) << this.gain_bits; float[][] numArray = this.CreateJaggedArray(3, nsf); this.e = this.CreateJaggedArray(3, nsf); for (num = 2; num >= 0; num--) { int num6 = (pitch + 1) - num; num2 = 0; while (num2 < nsf) { if ((num2 - num6) < 0) { this.e[num][num2] = exc2[(e2s + num2) - num6]; } else if (((num2 - num6) - pitch) < 0) { this.e[num][num2] = exc2[((e2s + num2) - num6) - pitch]; } else { this.e[num][num2] = 0f; } num2++; } if (num == 2) { Filters.Syn_percep_zero(this.e[num], 0, ak, awk1, awk2, numArray[num], nsf, p); } else { num2 = 0; while (num2 < (nsf - 1)) { numArray[num][num2 + 1] = numArray[num + 1][num2]; num2++; } numArray[num][0] = 0f; num2 = 0; while (num2 < nsf) { numArray[num][num2] += this.e[num][0] * r[num2]; num2++; } } } for (num = 0; num < 3; num++) { numArray2[num] = Ltp.Inner_prod(numArray[num], 0, target, 0, nsf); } for (num = 0; num < 3; num++) { for (num2 = 0; num2 <= num; num2++) { numArray3[num][num2] = numArray3[num2][num] = Ltp.Inner_prod(numArray[num], 0, numArray[num2], 0, nsf); } } float[] numArray4 = new float[9]; int index = 0; int num8 = 0; float num9 = 0f; numArray4[0] = numArray2[2]; numArray4[1] = numArray2[1]; numArray4[2] = numArray2[0]; numArray4[3] = numArray3[1][2]; numArray4[4] = numArray3[0][1]; numArray4[5] = numArray3[0][2]; numArray4[6] = numArray3[2][2]; numArray4[7] = numArray3[1][1]; numArray4[8] = numArray3[0][0]; for (num = 0; num < num3; num++) { float num10 = 0f; index = 3 * num; float num11 = (0.015625f * this.gain_cdbk[index]) + 0.5f; float num12 = (0.015625f * this.gain_cdbk[index + 1]) + 0.5f; float num13 = (0.015625f * this.gain_cdbk[index + 2]) + 0.5f; num10 += numArray4[0] * num11; num10 += numArray4[1] * num12; num10 += numArray4[2] * num13; num10 -= (numArray4[3] * num11) * num12; num10 -= (numArray4[4] * num13) * num12; num10 -= (numArray4[5] * num13) * num11; num10 -= ((0.5f * numArray4[6]) * num11) * num11; num10 -= ((0.5f * numArray4[7]) * num12) * num12; num10 -= ((0.5f * numArray4[8]) * num13) * num13; if ((num10 > num9) || (num == 0)) { num9 = num10; num8 = num; } } this.gain[0] = (0.015625f * this.gain_cdbk[num8 * 3]) + 0.5f; this.gain[1] = (0.015625f * this.gain_cdbk[(num8 * 3) + 1]) + 0.5f; this.gain[2] = (0.015625f * this.gain_cdbk[(num8 * 3) + 2]) + 0.5f; cdbk_index[0] = num8; for (num = 0; num < nsf; num++) { exc[es + num] = ((this.gain[0] * this.e[2][num]) + (this.gain[1] * this.e[1][num])) + (this.gain[2] * this.e[0][num]); } float num4 = 0f; float num5 = 0f; for (num = 0; num < nsf; num++) { num4 += target[num] * target[num]; } for (num = 0; num < nsf; num++) { num5 += (((target[num] - (this.gain[2] * numArray[0][num])) - (this.gain[1] * numArray[1][num])) - (this.gain[0] * numArray[2][num])) * (((target[num] - (this.gain[2] * numArray[0][num])) - (this.gain[1] * numArray[1][num])) - (this.gain[0] * numArray[2][num])); } return num5; } public sealed override int Quant(float[] target, float[] sw, int sws, float[] ak, float[] awk1, float[] awk2, float[] exc, int es, int start, int end, float pitch_coef, int p, int nsf, Bits bits, float[] exc2, int e2s, float[] r, int complexity) { int num; int[] numArray = new int[1]; int pitch = 0; int data = 0; int num5 = 0; float num7 = -1f; int n = complexity; if (n > 10) { n = 10; } int[] numArray3 = new int[n]; float[] gain = new float[n]; if ((n == 0) || (end < start)) { bits.Pack(0, this.pitch_bits); bits.Pack(0, this.gain_bits); for (num = 0; num < nsf; num++) { exc[es + num] = 0f; } return start; } float[] numArray2 = new float[nsf]; if (n > ((end - start) + 1)) { n = (end - start) + 1; } Ltp.Open_loop_nbest_pitch(sw, sws, start, end, nsf, numArray3, gain, n); for (num = 0; num < n; num++) { pitch = numArray3[num]; int index = 0; while (index < nsf) { exc[es + index] = 0f; index++; } float num6 = this.Pitch_gain_search_3tap(target, ak, awk1, awk2, exc, es, pitch, p, nsf, bits, exc2, e2s, r, numArray); if ((num6 < num7) || (num7 < 0f)) { for (index = 0; index < nsf; index++) { numArray2[index] = exc[es + index]; } num7 = num6; num5 = pitch; data = numArray[0]; } } bits.Pack(num5 - start, this.pitch_bits); bits.Pack(data, this.gain_bits); for (num = 0; num < nsf; num++) { exc[es + num] = numArray2[num]; } return pitch; } public sealed override int Unquant(float[] exc, int es, int start, float pitch_coef, int nsf, float[] gain_val, Bits bits, int count_lost, int subframe_offset, float last_pitch_gain) { int num; int num2 = bits.Unpack(this.pitch_bits) + start; int num3 = bits.Unpack(this.gain_bits); this.gain[0] = (0.015625f * this.gain_cdbk[num3 * 3]) + 0.5f; this.gain[1] = (0.015625f * this.gain_cdbk[(num3 * 3) + 1]) + 0.5f; this.gain[2] = (0.015625f * this.gain_cdbk[(num3 * 3) + 2]) + 0.5f; if ((count_lost != 0) && (num2 > subframe_offset)) { float num4 = Math.Abs(this.gain[1]); float num5 = (count_lost < 4) ? last_pitch_gain : (0.4f * last_pitch_gain); if (num5 > 0.95f) { num5 = 0.95f; } if (this.gain[0] > 0f) { num4 += this.gain[0]; } else { num4 -= 0.5f * this.gain[0]; } if (this.gain[2] > 0f) { num4 += this.gain[2]; } else { num4 -= 0.5f * this.gain[0]; } if (num4 > num5) { float num6 = num5 / num4; for (num = 0; num < 3; num++) { this.gain[num] *= num6; } } } gain_val[0] = this.gain[0]; gain_val[1] = this.gain[1]; gain_val[2] = this.gain[2]; for (num = 0; num < 3; num++) { int num10 = (num2 + 1) - num; int num8 = nsf; if (num8 > num10) { num8 = num10; } int num9 = nsf; if (num9 > (num10 + num2)) { num9 = num10 + num2; } int index = 0; while (index < num8) { this.e[num][index] = exc[(es + index) - num10]; index++; } index = num8; while (index < num9) { this.e[num][index] = exc[((es + index) - num10) - num2]; index++; } for (index = num9; index < nsf; index++) { this.e[num][index] = 0f; } } for (num = 0; num < nsf; num++) { exc[es + num] = ((this.gain[0] * this.e[2][num]) + (this.gain[1] * this.e[1][num])) + (this.gain[2] * this.e[0][num]); } return num2; } } }