MelFilter MFCC_to_MelFilter (MFCC me, long first, long last) { try { long nf = my maximumNumberOfCoefficients + 1; autoNUMmatrix<double> cosinesTable (NUMcosinesTable (nf), 1, 1); autoNUMvector<double> x (1, nf); autoNUMvector<double> y (1, nf); if (first >= last) { first = 0; last = nf - 1; } if (first < 0 || last > nf - 1) { Melder_throw ("MFCC_to_MelFilter: coefficients must be in interval [0,", my maximumNumberOfCoefficients, "]."); } double df = (my fmax - my fmin) / (nf + 1); autoMelFilter thee = MelFilter_create (my xmin, my xmax, my nx, my dx, my x1, my fmin, my fmax, nf, df, df); for (long frame = 1; frame <= my nx; frame++) { CC_Frame cf = (CC_Frame) & my frame[frame]; long iend = MIN (last, cf -> numberOfCoefficients); x[1] = first == 0 ? cf -> c0 : 0; for (long i = 1; i <= my maximumNumberOfCoefficients; i++) { x[i + 1] = i < first || i > iend ? 0 : cf -> c[i]; } NUMinverseCosineTransform (x.peek(), y.peek(), nf, cosinesTable.peek()); for (long i = 1; i <= nf; i++) { thy z[i][frame] = y[i]; } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, ": no MelFilter created."); } }
// Preconditions: Domains and number of frames conform // 0 <= first <= last <= my ny-1 void CC_into_BandFilterSpectrogram (CC me, BandFilterSpectrogram thee, long first, long last, bool use_c0) { long nf = my maximumNumberOfCoefficients + 1; autoNUMmatrix<double> cosinesTable (NUMcosinesTable (nf), 1, 1); autoNUMvector<double> x (1, nf); autoNUMvector<double> y (1, nf); for (long frame = 1; frame <= my nx; frame++) { CC_Frame ccframe = (CC_Frame) & my frame[frame]; long iend = last < ccframe -> numberOfCoefficients ? last : ccframe -> numberOfCoefficients; x[1] = use_c0 ? ccframe -> c0 : 0; for (long i = 1; i <= my maximumNumberOfCoefficients; i++) { x[i + 1] = i < first || i > iend ? 0 : ccframe -> c[i]; } NUMinverseCosineTransform (x.peek(), y.peek(), nf, cosinesTable.peek()); for (long i = 1; i <= nf; i++) { thy z[i][frame] = BandFilterSpectrogram_DBREF * pow (10, y[i] / BandFilterSpectrogram_DBFAC); } } }
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"); } }