コード例 #1
0
ファイル: MfccMirage.cs プロジェクト: remy22/FindSimilar
        private int numberWaveletTransforms = 2; // number of wavelet transform iterations, 3?

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Create a Mfcc object
        /// This method is not optimized in the sense that the Mel Filter Bands
        /// and the DCT is created here (and not read in)
        /// </summary>
        /// <param name="winsize">window size</param>
        /// <param name="srate">sample rate</param>
        /// <param name="numberFilters">number of filters (MEL COEFFICIENTS). E.g. 36 (SPHINX-III uses 40)</param>
        /// <param name="numberCoefficients">number of MFCC COEFFICIENTS. E.g. 20</param>
        public MfccMirage(int winsize, int srate, int numberFilters, int numberCoefficients)
        {
            this.numberCoefficients = numberCoefficients;

            double[] mel = new double[srate/2 - 19];
            double[] freq = new double[srate/2 - 19];
            int startFreq = 20;

            // Mel Scale from StartFreq to SamplingRate/2, step every 1Hz
            for (int f = startFreq; f <= srate/2; f++) {
                mel[f-startFreq] = LinearToMel(f);
                freq[f-startFreq] = f;
            }

            // Prepare filters
            double[] freqs = new double[numberFilters + 2];
            melScaleFreqsIndex = new int[numberFilters + 2];

            for (int f = 0; f < freqs.Length; f++) {
                double melIndex = 1.0 + ((mel[mel.Length - 1] - 1.0) /
                                         (freqs.Length - 1.0) * f);
                double min = Math.Abs(mel[0] - melIndex);
                freqs[f] = freq[0];

                for (int j = 1; j < mel.Length; j++) {
                    double cur = Math.Abs(mel[j] - melIndex);
                    if (cur < min) {
                        min = cur;
                        freqs[f] = freq[j];
                    }
                }

                melScaleFreqsIndex[f] = MathUtils.FreqToIndex(freqs[f], srate, winsize);
            }

            // triangle heights
            melScaleTriangleHeights = new double[numberFilters];
            for (int j = 0; j < melScaleTriangleHeights.Length; j++) {
                melScaleTriangleHeights[j] = 2.0/(freqs[j+2] - freqs[j]);
            }

            double[] fftFreq = new double[winsize/2 + 1];
            for (int j = 0; j < fftFreq.Length; j++) {
                fftFreq[j] = ((srate/2)/(fftFreq.Length -1.0)) * j;
            }

            // Compute the MFCC filter Weights
            filterWeights = new Matrix(numberFilters, winsize/2);
            for (int j = 0; j < numberFilters; j++) {
                for (int k = 0; k < fftFreq.Length; k++) {
                    if ((fftFreq[k] > freqs[j]) && (fftFreq[k] <= freqs[j+1])) {

                        filterWeights.MatrixData[j][k] = (float)(melScaleTriangleHeights[j] *
                                                                 ((fftFreq[k]-freqs[j])/(freqs[j+1]-freqs[j])));
                    }
                    if ((fftFreq[k] > freqs[j+1]) &&
                        (fftFreq[k] < freqs[j+2])) {

                        filterWeights.MatrixData[j][k] += (float)(melScaleTriangleHeights[j] *
                                                                  ((freqs[j+2]-fftFreq[k])/(freqs[j+2]-freqs[j+1])));
                    }
                }
            }
            #if DEBUG
            if (Mirage.Analyzer.DEBUG_INFO_VERBOSE) {
                if (Mirage.Analyzer.DEBUG_OUTPUT_TEXT) filterWeights.WriteAscii("melfilters-mirage-orig.ascii");
                //filterWeights.DrawMatrixGraph("melfilters-mirage-orig.png");
            }
            #endif

            // Compute the DCT
            // This whole section is copied from GetDCTMatrix() from CoMirva package
            dct = new DctComirva(numberCoefficients, numberFilters).DCTMatrix;

            #if DEBUG
            if (Mirage.Analyzer.DEBUG_INFO_VERBOSE) {
                if (Mirage.Analyzer.DEBUG_OUTPUT_TEXT) dct.WriteAscii("dct-mirage-orig.ascii");
                //dct.DrawMatrixGraph("dct-mirage-orig.png");
            }
            #endif
        }