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."); } }
MFCC MelFilter_to_MFCC (MelFilter me, long numberOfCoefficients) { try { long nf = my ny; double fmax_mel = my y1 + (nf - 1) * my dy; Melder_assert (numberOfCoefficients > 0); autoNUMmatrix<double> dct (NUMcosinesTable (1, numberOfCoefficients, nf), 1, 1); autoMFCC thee = MFCC_create (my xmin, my xmax, my nx, my dx, my x1, numberOfCoefficients, my y1, fmax_mel); for (long frame = 1; frame <= my nx; frame++) { CC_Frame cf = (CC_Frame) & thy frame[frame]; CC_Frame_init (cf, numberOfCoefficients); for (long i = 1; i <= numberOfCoefficients; i++) { double p = 0; for (long j = 1; j <= nf; j++) { p += my z[j][frame] * dct[i][j]; } cf -> c[i] = p; } // c0 equals the average of the filterbank outputs. double p = 0; for (long j = 1; j <= nf; j++) { p += my z[j][frame]; } cf -> c0 = p / nf; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, ": no MFCC created."); } }
LFCC LPC_to_LFCC (LPC me, long numberOfCoefficients) { try { if (numberOfCoefficients < 1) { numberOfCoefficients = my maxnCoefficients; } autoLFCC thee = LFCC_create (my xmin, my xmax, my nx, my dx, my x1, numberOfCoefficients, 0, 0.5 / my samplingPeriod); for (long i = 1; i <= my nx; i++) { CC_Frame_init (& thy frame[i], numberOfCoefficients); LPC_Frame_into_CC_Frame (& my d_frames[i], & thy frame[i]); } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": no LFCC 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]; } }