static int Sound_into_MelFilter_frame (Sound me, MelFilter thee, long frame) { autoMatrix pv = Sound_to_spectralpower (me); double z1 = pv -> x1; double dz = pv -> dx; long nf = pv -> nx; double df = thy dy; for (long i = 1; i <= thy ny; i++) { double p = 0; double fc_mel = thy y1 + (i - 1) * df; double fc_hz = MELTOHZ (fc_mel); double fl_hz = MELTOHZ (fc_mel - df); double fh_hz = MELTOHZ (fc_mel + df); double *pow = pv -> z[1]; for (long j = 1; j <= nf; j++) { // Filter with a triangular filter the power (=amplitude-squared) double f = z1 + (j - 1) * dz; double a = NUMtriangularfilter_amplitude (fl_hz, fc_hz, fh_hz, f); p += a * pow[j] ; } thy z[i][frame] = p; } return 1; }
void MelFilter_drawFilterFunctions (MelFilter me, Graphics g, int toFreqScale, int fromFilter, int toFilter, double zmin, double zmax, int dbScale, double ymin, double ymax, int garnish) { if (! checkLimits (me, FilterBank_MEL, toFreqScale, & fromFilter, & toFilter, & zmin, & zmax, dbScale, & ymin, & ymax)) { return; } long n = 1000; autoNUMvector<double> a (1, n); Graphics_setInner (g); Graphics_setWindow (g, zmin, zmax, ymin, ymax); for (long j = fromFilter; j <= toFilter; j++) { double df = (zmax - zmin) / (n - 1); double fc_mel = my y1 + (j - 1) * my dy; double fc_hz = MELTOHZ (fc_mel); double fl_hz = MELTOHZ (fc_mel - my dy); double fh_hz = MELTOHZ (fc_mel + my dy); long ibegin, iend; for (long i = 1; i <= n; i++) { // Filterfunction: triangular on a linear frequency scale AND a linear amplitude scale. double f = zmin + (i - 1) * df; double z = scaleFrequency (f, toFreqScale, FilterBank_HERTZ); if (z == NUMundefined) { a[i] = NUMundefined; } else { a[i] = NUMtriangularfilter_amplitude (fl_hz, fc_hz, fh_hz, z); if (dbScale) { a[i] = to_dB (a[i], 10, ymin); } } } setDrawingLimits (a.peek(), n, ymin, ymax, &ibegin, &iend); if (ibegin <= iend) { double fmin = zmin + (ibegin - 1) * df; double fmax = zmax - (n - iend) * df; Graphics_function (g, a.peek(), ibegin, iend, fmin, fmax); } } Graphics_unsetInner (g); if (garnish) { double distance = dbScale ? 10 : 1; char32 const *ytext = dbScale ? U"Amplitude (dB)" : U"Amplitude"; Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, 1, 1, 0); Graphics_marksLeftEvery (g, 1, distance, 1, 1, 0); Graphics_textLeft (g, 1, ytext); Graphics_textBottom (g, 1, GetFreqScaleText (toFreqScale)); } }
static void Sound_into_MelSpectrogram_frame (Sound me, MelSpectrogram thee, long frame) { autoSpectrum him = Sound_to_Spectrum_power (me); for (long ifilter = 1; ifilter <= thy ny; ifilter ++) { double power = 0; double fc_mel = thy y1 + (ifilter - 1) * thy dy; double fc_hz = thy v_frequencyToHertz (fc_mel); double fl_hz = thy v_frequencyToHertz (fc_mel - thy dy); double fh_hz = thy v_frequencyToHertz (fc_mel + thy dy); long ifrom, ito; Sampled_getWindowSamples (him.get(), fl_hz, fh_hz, &ifrom, &ito); for (long i = ifrom; i <= ito; i++) { // Bin with a triangular filter the power (=amplitude-squared) double f = his x1 + (i - 1) * his dx; double a = NUMtriangularfilter_amplitude (fl_hz, fc_hz, fh_hz, f); power += a * his z[1][i]; } thy z[ifilter][frame] = power; } }
void MelSpectrogram_drawTriangularFilterFunctions (MelSpectrogram me, Graphics g, bool xIsHertz, int fromFilter, int toFilter, double zmin, double zmax, bool yscale_dB, double ymin, double ymax, int garnish) { double xmin = zmin, xmax = zmax; if (zmin >= zmax) { zmin = my ymin; zmax = my ymax; // mel xmin = xIsHertz ? my v_frequencyToHertz (zmin) : zmin; xmax = xIsHertz ? my v_frequencyToHertz (zmax) : zmax; } if (xIsHertz) { zmin = my v_hertzToFrequency (xmin); zmax = my v_hertzToFrequency (xmax); } if (ymin >= ymax) { ymin = yscale_dB ? -60 : 0; ymax = yscale_dB ? 0 : 1; } fromFilter = fromFilter <= 0 ? 1 : fromFilter; toFilter = toFilter <= 0 || toFilter > my ny ? my ny : toFilter; if (fromFilter > toFilter) { fromFilter = 1; toFilter = my ny; } long n = xIsHertz ? 1000 : 500; autoNUMvector<double> xz (1, n), xhz (1,n), y (1, n); Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); double dz = (zmax - zmin) / (n - 1); for (long iz = 1; iz <= n; iz++) { double f = zmin + (iz - 1) * dz; xz[iz] = f; xhz[iz] = my v_frequencyToHertz (f); // just in case we need the linear scale } for (long ifilter = fromFilter; ifilter <= toFilter; ifilter++) { double zc = Matrix_rowToY (me, ifilter), zl = zc - my dy, zh = zc + my dy; double xo1, yo1, xo2, yo2; if (yscale_dB) { for (long iz = 1; iz <= n; iz++) { double z = xz[iz]; double amp = NUMtriangularfilter_amplitude (zl, zc, zh, z); y[iz] = yscale_dB ? (amp > 0 ? 20 * log10 (amp) : ymin - 10) : amp; } double x1 = xIsHertz ? xhz[1] : xz[1], y1 = y[1]; if (NUMdefined (y1)) { for (long iz = 1; iz <= n; iz++) { double x2 = xIsHertz ? xhz[iz] : xz[iz], y2 = y[iz]; if (NUMdefined (y2)) { if (NUMclipLineWithinRectangle (x1, y1, x2, y2, xmin, ymin, xmax, ymax, &xo1, &yo1, &xo2, &yo2)) { Graphics_line (g, xo1, yo1, xo2, yo2); } } x1 = x2; y1 = y2; } } } else { double x1 = xIsHertz ? my v_frequencyToHertz (zl) : zl; double x2 = xIsHertz ? my v_frequencyToHertz (zc) : zc; if (NUMclipLineWithinRectangle (x1, 0, x2, 1, xmin, ymin, xmax, ymax, &xo1, &yo1, &xo2, &yo2)) { Graphics_line (g, xo1, yo1, xo2, yo2); } double x3 = xIsHertz ? my v_frequencyToHertz (zh) : zh; if (NUMclipLineWithinRectangle (x2, 1, x3, 0, xmin, ymin, xmax, ymax, &xo1, &yo1, &xo2, &yo2)) { Graphics_line (g, xo1, yo1, xo2, yo2); } } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, 1, 1, 0); Graphics_marksLeftEvery (g, 1, yscale_dB ? 10 : 0.5, 1, 1, 0); Graphics_textLeft (g, 1, yscale_dB ? U"Amplitude (dB)" : U"Amplitude"); Graphics_textBottom (g, 1, Melder_cat (U"Frequency (", ( xIsHertz ? U"Hz" : my v_getFrequencyUnit () ), U")")); } }