namespace NSpeex { using System; internal class Filters { private int last_pitch; private float[] last_pitch_gain; private float smooth_gain; private float[] xx; public Filters() { float num; this.last_pitch_gain = new float[3]; this.xx = new float[0x400]; this.last_pitch = 0; this.last_pitch_gain[2] = num = 0f; this.last_pitch_gain[0] = this.last_pitch_gain[1] = num; this.smooth_gain = 1f; } public static void Bw_lpc(float gamma, float[] lpc_in, float[] lpc_out, int order) { float num = 1f; for (int i = 0; i < (order + 1); i++) { lpc_out[i] = num * lpc_in[i]; num *= gamma; } } public void Comb_filter(float[] exc, int esi, float[] new_exc, int nsi, int nsf, int pitch, float[] pitch_gain, float comb_gain) { int num; float num3 = 0f; float num4 = 0f; float num8 = 0f; for (num = esi; num < (esi + nsf); num++) { num3 += exc[num] * exc[num]; } num8 = 0.5f * Math.Abs((float)(((((pitch_gain[0] + pitch_gain[1]) + pitch_gain[2]) + this.last_pitch_gain[0]) + this.last_pitch_gain[1]) + this.last_pitch_gain[2])); if (num8 > 1.3f) { comb_gain *= 1.3f / num8; } if (num8 < 0.5f) { comb_gain *= 2f * num8; } float num6 = 1f / ((float)nsf); float num7 = 0f; num = 0; for (int i = esi; num < nsf; i++) { num7 += num6; new_exc[nsi + num] = (exc[i] + ((comb_gain * num7) * (((pitch_gain[0] * exc[(i - pitch) + 1]) + (pitch_gain[1] * exc[i - pitch])) + (pitch_gain[2] * exc[(i - pitch) - 1])))) + ((comb_gain * (1f - num7)) * (((this.last_pitch_gain[0] * exc[(i - this.last_pitch) + 1]) + (this.last_pitch_gain[1] * exc[i - this.last_pitch])) + (this.last_pitch_gain[2] * exc[(i - this.last_pitch) - 1]))); num++; } this.last_pitch_gain[0] = pitch_gain[0]; this.last_pitch_gain[1] = pitch_gain[1]; this.last_pitch_gain[2] = pitch_gain[2]; this.last_pitch = pitch; for (num = nsi; num < (nsi + nsf); num++) { num4 += new_exc[num] * new_exc[num]; } float num5 = (float)Math.Sqrt((double)(num3 / (0.1f + num4))); if (num5 < 0.5f) { num5 = 0.5f; } if (num5 > 1f) { num5 = 1f; } for (num = nsi; num < (nsi + nsf); num++) { this.smooth_gain = (0.96f * this.smooth_gain) + (0.04f * num5); new_exc[num] *= this.smooth_gain; } } public static void Filter_mem2(float[] x, int xs, float[] num, float[] den, int N, int ord, float[] mem, int ms) { for (int i = 0; i < N; i++) { float num4 = x[xs + i]; x[xs + i] = (num[0] * num4) + mem[ms]; float num5 = x[xs + i]; for (int j = 0; j < (ord - 1); j++) { mem[ms + j] = (mem[(ms + j) + 1] + (num[j + 1] * num4)) - (den[j + 1] * num5); } mem[(ms + ord) - 1] = (num[ord] * num4) - (den[ord] * num5); } } public static void Filter_mem2(float[] x, int xs, float[] num, float[] den, float[] y, int ys, int N, int ord, float[] mem, int ms) { for (int i = 0; i < N; i++) { float num4 = x[xs + i]; y[ys + i] = (num[0] * num4) + mem[0]; float num5 = y[ys + i]; for (int j = 0; j < (ord - 1); j++) { mem[ms + j] = (mem[(ms + j) + 1] + (num[j + 1] * num4)) - (den[j + 1] * num5); } mem[(ms + ord) - 1] = (num[ord] * num4) - (den[ord] * num5); } } public void Fir_mem_up(float[] x, float[] a, float[] y, int N, int M, float[] mem) { int num; for (num = 0; num < (N / 2); num++) { this.xx[2 * num] = x[((N / 2) - 1) - num]; } for (num = 0; num < (M - 1); num += 2) { this.xx[N + num] = mem[num + 1]; } for (num = 0; num < N; num += 4) { float num4; float num5; float num6; float num3 = num4 = num5 = num6 = 0f; float num7 = this.xx[(N - 4) - num]; for (int i = 0; i < M; i += 4) { float num9 = a[i]; float num10 = a[i + 1]; float num8 = this.xx[((N - 2) + i) - num]; num3 += num9 * num8; num4 += num10 * num8; num5 += num9 * num7; num6 += num10 * num7; num9 = a[i + 2]; num10 = a[i + 3]; num7 = this.xx[(N + i) - num]; num3 += num9 * num7; num4 += num10 * num7; num5 += num9 * num8; num6 += num10 * num8; } y[num] = num3; y[num + 1] = num4; y[num + 2] = num5; y[num + 3] = num6; } for (num = 0; num < (M - 1); num += 2) { mem[num + 1] = this.xx[num]; } } public static void Fir_mem2(float[] x, int xs, float[] num, float[] y, int ys, int N, int ord, float[] mem) { for (int i = 0; i < N; i++) { float num4 = x[xs + i]; y[ys + i] = (num[0] * num4) + mem[0]; for (int j = 0; j < (ord - 1); j++) { mem[j] = mem[j + 1] + (num[j + 1] * num4); } mem[ord - 1] = num[ord] * num4; } } public static void Iir_mem2(float[] x, int xs, float[] den, float[] y, int ys, int N, int ord, float[] mem) { for (int i = 0; i < N; i++) { y[ys + i] = x[xs + i] + mem[0]; for (int j = 0; j < (ord - 1); j++) { mem[j] = mem[j + 1] - (den[j + 1] * y[ys + i]); } mem[ord - 1] = -den[ord] * y[ys + i]; } } public static void Qmf_decomp(float[] xx_0, float[] aa, float[] y1, float[] y2, int N, int M, float[] mem) { int num; float[] numArray = new float[M]; float[] numArray2 = new float[(N + M) - 1]; int num5 = M - 1; int num4 = M >> 1; for (num = 0; num < M; num++) { numArray[(M - num) - 1] = aa[num]; } for (num = 0; num < (M - 1); num++) { numArray2[num] = mem[(M - num) - 2]; } for (num = 0; num < N; num++) { numArray2[(num + M) - 1] = xx_0[num]; } num = 0; for (int i = 0; num < N; i++) { y1[i] = 0f; y2[i] = 0f; for (int j = 0; j < num4; j++) { y1[i] += numArray[j] * (numArray2[num + j] + numArray2[(num5 + num) - j]); y2[i] -= numArray[j] * (numArray2[num + j] - numArray2[(num5 + num) - j]); j++; y1[i] += numArray[j] * (numArray2[num + j] + numArray2[(num5 + num) - j]); y2[i] += numArray[j] * (numArray2[num + j] - numArray2[(num5 + num) - j]); } num += 2; } for (num = 0; num < (M - 1); num++) { mem[num] = xx_0[(N - num) - 1]; } } public static void Residue_percep_zero(float[] xx_0, int xxs, float[] ak, float[] awk1, float[] awk2, float[] y, int N, int ord) { float[] mem = new float[ord]; Filter_mem2(xx_0, xxs, ak, awk1, y, 0, N, ord, mem, 0); for (int i = 0; i < ord; i++) { mem[i] = 0f; } Fir_mem2(y, 0, awk2, y, 0, N, ord, mem); } public static void Syn_percep_zero(float[] xx_0, int xxs, float[] ak, float[] awk1, float[] awk2, float[] y, int N, int ord) { float[] mem = new float[ord]; Filter_mem2(xx_0, xxs, awk1, ak, y, 0, N, ord, mem, 0); for (int i = 0; i < ord; i++) { mem[i] = 0f; } Iir_mem2(y, 0, awk2, y, 0, N, ord, mem); } } }