MFCC MelFilter_to_MFCC (MelFilter me, long numberOfCoefficients) { try { autoNUMmatrix<double> cosinesTable (NUMcosinesTable (my ny), 1, 1); autoNUMvector<double> x (1, my ny); autoNUMvector<double> y (1, my ny); double fmax_mel = my y1 + (my ny - 1) * my dy; numberOfCoefficients = numberOfCoefficients > my ny - 1 ? my ny - 1 : numberOfCoefficients; Melder_assert (numberOfCoefficients > 0); // 20130220 new interpretation of maximumNumberOfCoefficients necessary for inverse transform autoMFCC thee = MFCC_create (my xmin, my xmax, my nx, my dx, my x1, my ny - 1, my ymin, my ymax); for (long frame = 1; frame <= my nx; frame++) { CC_Frame cf = (CC_Frame) & thy frame[frame]; for (long i = 1; i <= my ny; i++) { x[i] = my z[i][frame]; } NUMcosineTransform (x.peek(), y.peek(), my ny, cosinesTable.peek()); CC_Frame_init (cf, numberOfCoefficients); for (long i = 1; i <= numberOfCoefficients; i++) { cf -> c[i] = y[i + 1]; } cf -> c0 = y[1]; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, ": no MFCC created."); } }
/* Precondition: 1. CC object has been created but individual frames not yet initialized * 2. Domains and number of frames conform * Steps: * 1. transform power-spectra to dB-spectra * 2. cosine transform of dB-spectrum */ void BandFilterSpectrogram_into_CC (BandFilterSpectrogram me, CC thee, long numberOfCoefficients) { autoNUMmatrix<double> cosinesTable (NUMcosinesTable (my ny), 1, 1); autoNUMvector<double> x (1, my ny); autoNUMvector<double> y (1, my ny); numberOfCoefficients = numberOfCoefficients > my ny - 1 ? my ny - 1 : numberOfCoefficients; Melder_assert (numberOfCoefficients > 0); // 20130220 new interpretation of maximumNumberOfCoefficients necessary for inverse transform for (long frame = 1; frame <= my nx; frame++) { CC_Frame ccframe = (CC_Frame) & thy frame[frame]; for (long i = 1; i <= my ny; i++) { x[i] = my v_getValueAtSample (frame, i, 1); // z[i][frame]; } NUMcosineTransform (x.peek(), y.peek(), my ny, cosinesTable.peek()); CC_Frame_init (ccframe, numberOfCoefficients); for (long i = 1; i <= numberOfCoefficients; i++) { ccframe -> c[i] = y[i + 1]; } ccframe -> c0 = y[1]; } }
double testCosineTransform (long n) { try { autoNUMvector<double> x (1, n); autoNUMvector<double> y (1, n); autoNUMvector<double> x2 (1, n); autoNUMmatrix<double> cosinesTable (NUMcosinesTable (n), 1, 1); for (long i = 1 ; i <= n; i++) { x[i] = NUMrandomUniform (0, 70); } NUMcosineTransform (x.peek(), y.peek(), n, cosinesTable.peek()); NUMinverseCosineTransform (y.peek(), x2.peek(), n, cosinesTable.peek()); double delta = 0; for (long i =1 ; i <= n; i++) { double dif = x[i] - x2[i]; delta += dif * dif; } delta = sqrt (delta); return delta; } catch (MelderError) { Melder_throw ("Test cosine transform error"); } }