private void WhisperFilter(Wave wave) { Func <int, int, double> windowFunction = Hamming; int length = wave.Data.Length; double[] x = new double[frame]; double[] y = new double[frame]; double[] E = new double[frame]; //残差信号 double[] a = new double[Order + 1]; //LPC係数 double[] v = wave.Data; double[] v1 = new double[v.Length]; double[] v2 = new double[v.Length]; for (int i = 0; i < length / frame * 2 - 1; i++) { double max = 0.0; for (int j = 0; j < frame; j++) { x[j] = v[j + i * frame / 2] * windowFunction(j, frame); } //LPC係数の導出 LevinsonDurbin(x, frame, a, Order); //残差信号(声帯音源)の導出 for (int j = 0; j < frame; j++) { double e = 0.0; for (int n = 0; n < Order + 1; n++) { if (j >= n) { e += a[n] * x[j - n]; } } E[j] = e; max += e * e; } //声帯振動 for (int j = 0; j < frame; j++) { v2[j + i * frame / 2] += E[j] * 10.0; } //ホワイトノイズの生成 for (int j = 0; j < frame; j++) { y[j] = GenerateWhiteNoise(); } for (int j = 1; j < frame; j++) { E[j] = ((1.0 - Rate) * E[j - 1] + E[j]) / (2.0 - Rate); } //残差信号とノイズの二乗平均レベルをそろえる max = Math.Sqrt(3.0 * max / frame); for (int j = 0; j < frame; j++) { y[j] = Rate * E[j] + (1.0 - Rate) * max * y[j]; } //for (int j=1; j<order+1; j++) a[j] *= pow(alpha, (double)j); //音声合成フィルタ for (int j = 0; j < frame; j++) { for (int n = 1; n < Order + 1; n++) { if (j >= n) { y[j] -= a[n] * y[j - n]; } } } for (int j = 0; j < frame; j++) { v1[j + i * frame / 2] += y[j]; } } //デエンファシス for (int i = 1; i < length; i++) { v1[i] = Lpf * v1[i - 1] + v1[i]; } for (int i = 1; i < length; i++) { v2[i] = 0.97 * v2[i - 1] + v2[i]; } wave.Data = v1; wave.EData = v2; }
public void Convert(Wave wave) { AdjustSize(wave); WhisperFilter(wave); }