//################################################################################################################################## /// <summary> /// NOTE!!!! The decibel array has been normalised in 0 - 1. /// </summary> protected static Tuple <double[, ], double[]> MakeCepstrogram(SonogramConfig config, double[,] matrix, double[] decibels, int sampleRate) { double[,] m = matrix; int nyquist = sampleRate / 2; double epsilon = config.epsilon; bool includeDelta = config.mfccConfig.IncludeDelta; bool includeDoubleDelta = config.mfccConfig.IncludeDoubleDelta; //Log.WriteIfVerbose(" MakeCepstrogram(matrix, decibels, includeDelta=" + includeDelta + ", includeDoubleDelta=" + includeDoubleDelta + ")"); //(i) APPLY FILTER BANK int bandCount = config.mfccConfig.FilterbankCount; bool doMelScale = config.mfccConfig.DoMelScale; int ccCount = config.mfccConfig.CcCount; int fftBinCount = config.FreqBinCount; //number of Hz bands = 2^N +1. Subtract DC bin int minHz = config.MinFreqBand ?? 0; int maxHz = config.MaxFreqBand ?? nyquist; Log.WriteIfVerbose("ApplyFilterBank(): Dim prior to filter bank =" + matrix.GetLength(1)); //error check that filterBankCount < FFTbins if (bandCount > fftBinCount) { throw new Exception( "## FATAL ERROR in BaseSonogram.MakeCepstrogram():- Can't calculate cepstral coeff. FilterbankCount > FFTbins. (" + bandCount + " > " + fftBinCount + ")\n\n"); } //this is the filter count for full bandwidth 0-Nyquist. This number is trimmed proportionately to fit the required bandwidth. if (doMelScale) { m = MFCCStuff.MelFilterBank(m, bandCount, nyquist, minHz, maxHz); // using the Greg integral } else { m = MFCCStuff.LinearFilterBank(m, bandCount, nyquist, minHz, maxHz); } Log.WriteIfVerbose("\tDim after filter bank=" + m.GetLength(1) + " (Max filter bank=" + bandCount + ")"); //(ii) CONVERT AMPLITUDES TO DECIBELS m = MFCCStuff.DecibelSpectra(m, config.WindowPower, sampleRate, epsilon); //from spectrogram //(iii) NOISE REDUCTION var tuple1 = SNR.NoiseReduce(m, config.NoiseReductionType, config.NoiseReductionParameter); m = tuple1.Item1; //(iv) calculate cepstral coefficients m = MFCCStuff.Cepstra(m, ccCount); //(v) NormaliseMatrixValues m = DataTools.normalise(m); //(vi) Calculate the full range of MFCC coefficients ie including decibel and deltas, etc m = MFCCStuff.AcousticVectors(m, decibels, includeDelta, includeDoubleDelta); var tuple2 = Tuple.Create(m, tuple1.Item2); return(tuple2); // return matrix and full bandwidth modal noise profile }