Пример #1
0
        //--------------------------------------------------------------------------
        //constant Q transform
        static Complex[,] constantQ_transform(double[] wavdata)
        {
            double[] new_wavdata;
            Complex[,] kernel;
            Complex[,] output;
            int wav_length = wavdata.Length;
            int T_step;
            int F_step;
            int fft_step;
            int fft_start_point;
            int hop;

            double[] freqs = get_freqs(fmin, get_freq_num(fmin, fmax, fratio), fratio);
            kernel = calcKernel_matrix(freqs);

            hop         = (int)(Math.Round(0.01 * fs)); //100 frames per 1 sec
            T_step      = wav_length / hop;
            F_step      = freqs.Length;
            fft_step    = (int)(Math.Pow(2, Math.Ceiling((Math.Log(fs * Q / freqs[0], 2))))); //greater than Max of N[k]
            new_wavdata = new double[wav_length + fft_step];
            output      = new Complex[F_step, T_step];

            for (int i = 0; i < wav_length; i++)
            {
                new_wavdata[i + fft_step / 2] = wavdata[i];
            }

            for (int t = 0; t < T_step; t++)
            {
                fft_start_point = hop * t;
                Complex[] partial_data = new Complex[fft_step];
                for (int i = 0; i < fft_step; i++)
                {
                    partial_data[i] = new Complex(new_wavdata[fft_start_point + i], 0);
                }

                Complex[] fft = Nm.FastFourierTransform(partial_data, true);
                Complex[] cq  = new Complex[F_step];
                for (int i = 0; i < F_step; i++)
                {
                    for (int j = 0; j < fft.Length; j++)         //fft.Length = fft_step
                    {
                        cq[i] += fft[j] * kernel[i, j];
                    }
                }

                for (int f = 0; f < F_step; f++)
                {
                    output[f, t] = cq[f];
                }
            }
            return(output);
        }
Пример #2
0
        //--------------------------------------------------------------------------
        //Kernel行列の計算
        static Complex[,] calcKernel_matrix(double[] freqs)
        {
            //窓幅N[k]の最大値
            int fftlen = (int)(Math.Pow(2, Math.Ceiling((Math.Log(fs * Q / freqs[0], 2)))));

            Complex[,] kernel = new Complex[freqs.Length, fftlen];
            Complex[] tmp_kernel = new Complex[fftlen];

            for (int k = 0; k < freqs.Length; k++)
            {
                double   freq      = freqs[k];
                int      N_k       = (int)((double)(fs * Q) / freq); //窓幅
                int      start_win = (fftlen - N_k) / 2;             //FFT窓の中心を解析部分に合わせる
                double[] hamming   = new double[N_k];
                for (int i = 0; i < N_k; i++)
                {
                    hamming[i] = 1;
                }
                Nm.Windowing(hamming, Nm.DataWindowType.Hamming);
                for (int i = start_win; i < start_win + N_k; i++)
                {
                    tmp_kernel[i] = hamming[i - start_win] / N_k * Complex.Exp(2 * Math.PI * Complex.ImaginaryOne * Q * (i - start_win) / N_k);
                }
                tmp_kernel = Nm.FastFourierTransform(tmp_kernel, false); //sw==falseでfftlenで割る
                double[] d = new double[tmp_kernel.Length];
                for (int i = 0; i < tmp_kernel.Length; i++)
                {
                    d[i] = tmp_kernel[i].Magnitude;
                }
                double max = d.Max();
                for (int i = 0; i < fftlen; i++)
                {
                    //if (tmp_kernel[i].Magnitude <= 0.0054)
                    //    kernel[k, i] = Complex.Zero;
                    //else
                    kernel[k, i] = Complex.Conjugate(tmp_kernel[i]);
                }
            }

            return(kernel);
        }