예제 #1
0
        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;
        }
예제 #2
0
 public void Convert(Wave wave)
 {
     AdjustSize(wave);
     WhisperFilter(wave);
 }