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."); } }
MelFilter MFCC_to_MelFilter2 (MFCC me, long first_cc, long last_cc, double f1_mel, double df_mel) { try { int use_c0 = 0; long nf = ((my fmax - my fmin) / df_mel + 0.5); double fmin = MAX (f1_mel - df_mel, 0), fmax = f1_mel + (nf + 1) * df_mel; if (nf < 1) { Melder_throw ("MFCC_to_MelFilter: the position of the first filter, the distance between the filters, " "and, the maximum do not result in a positive number of filters."); } // Default values if (first_cc == 0) { first_cc = 1; use_c0 = 1; } if (last_cc == 0) { last_cc = my maximumNumberOfCoefficients; } // Be strict if (last_cc < first_cc || first_cc < 1 || last_cc > my maximumNumberOfCoefficients) { Melder_throw ("MFCC_to_MelFilter: coefficients must be in interval [1,", my maximumNumberOfCoefficients, "]."); } autoNUMmatrix<double> dct (NUMcosinesTable (first_cc, last_cc, nf), first_cc, 1); // TODO ?? //if ((dct = NUMcosinesTable (first_cc, last_cc, nf)) == NULL) return NULL; autoMelFilter thee = MelFilter_create (my xmin, my xmax, my nx, my dx, my x1, fmin, fmax, nf, df_mel, f1_mel); for (long frame = 1; frame <= my nx; frame++) { CC_Frame cf = (CC_Frame) & my frame[frame]; long ie = MIN (last_cc, cf -> numberOfCoefficients); for (long j = 1; j <= nf; j++) { double t = 0; for (long i = first_cc; i <= ie; i++) { t += cf -> c[i] * dct[i][j]; } // The inverse CT has a factor 1/N t /= nf; if (use_c0) { t += cf -> c0; } thy z[j][frame] = t; } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, ": no MelFilter created."); } }
MelFilter Matrix_to_MelFilter (I) { iam (Matrix); try { autoMelFilter thee = MelFilter_create (my xmin, my xmax, my nx, my dx, my x1, my ymin, my ymax, my ny, my dy, my y1); NUMmatrix_copyElements (my z, thy z, 1, my ny, 1, my nx); return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to MelFilter."); } }
MelFilter Sound_to_MelFilter (Sound me, double analysisWidth, double dt, double f1_mel, double fmax_mel, double df_mel) { try { double t1, samplingFrequency = 1 / my dx, nyquist = 0.5 * samplingFrequency; double windowDuration = 2 * analysisWidth; /* gaussian window */ double fmin_mel = 0; double fbottom = HZTOMEL (100.0), fceiling = HZTOMEL (nyquist); long nt, frameErrorCount = 0; // Check defaults. if (fmax_mel <= 0 || fmax_mel > fceiling) { fmax_mel = fceiling; } if (fmax_mel <= f1_mel) { f1_mel = fbottom; fmax_mel = fceiling; } if (f1_mel <= 0) { f1_mel = fbottom; } if (df_mel <= 0) { df_mel = 100.0; } // Determine the number of filters. long nf = floor ( (fmax_mel - f1_mel) / df_mel + 0.5); fmax_mel = f1_mel + nf * df_mel; Sampled_shortTermAnalysis (me, windowDuration, dt, &nt, &t1); autoSound sframe = Sound_createSimple (1, windowDuration, samplingFrequency); autoSound window = Sound_createGaussian (windowDuration, samplingFrequency); autoMelFilter thee = MelFilter_create (my xmin, my xmax, nt, dt, t1, fmin_mel, fmax_mel, nf, df_mel, f1_mel); autoMelderProgress progress (L"MelFilters analysis"); for (long i = 1; i <= nt; i++) { double t = Sampled_indexToX (thee.peek(), i); Sound_into_Sound (me, sframe.peek(), t - windowDuration / 2); Sounds_multiply (sframe.peek(), window.peek()); if (! Sound_into_MelFilter_frame (sframe.peek(), thee.peek(), i)) { frameErrorCount++; } if ( (i % 10) == 1) { Melder_progress ( (double) i / nt, L"Frame ", Melder_integer (i), L" out of ", Melder_integer (nt), L"."); } } if (frameErrorCount) Melder_warning (L"Analysis results of ", Melder_integer (frameErrorCount), L" frame(s) out of ", Melder_integer (nt), L" will be suspect."); // Window correction. double ref = FilterBank_DBREF * gaussian_window_squared_correction (window -> nx); NUMdmatrix_to_dBs (thy z, 1, thy ny, 1, thy nx, ref, FilterBank_DBFAC, FilterBank_DBFLOOR); return thee.transfer(); } catch (MelderError) { Melder_throw (me, ": no MelFilter created."); } }