int main() { int n, ip[NMAXSQRT + 2]; double a[NMAX + 1], w[NMAX * 5 / 4], t[NMAX / 2 + 1], err; printf("data length n=? (must be 2^m)\n"); scanf("%d", &n); ip[0] = 0; /* check of CDFT */ putdata(0, n - 1, a); cdft(n, 1, a, ip, w); cdft(n, -1, a, ip, w); err = errorcheck(0, n - 1, 2.0 / n, a); printf("cdft err= %g \n", err); /* check of RDFT */ putdata(0, n - 1, a); rdft(n, 1, a, ip, w); rdft(n, -1, a, ip, w); err = errorcheck(0, n - 1, 2.0 / n, a); printf("rdft err= %g \n", err); /* check of DDCT */ putdata(0, n - 1, a); ddct(n, 1, a, ip, w); ddct(n, -1, a, ip, w); a[0] *= 0.5; err = errorcheck(0, n - 1, 2.0 / n, a); printf("ddct err= %g \n", err); /* check of DDST */ putdata(0, n - 1, a); ddst(n, 1, a, ip, w); ddst(n, -1, a, ip, w); a[0] *= 0.5; err = errorcheck(0, n - 1, 2.0 / n, a); printf("ddst err= %g \n", err); /* check of DFCT */ putdata(0, n, a); a[0] *= 0.5; a[n] *= 0.5; dfct(n, a, t, ip, w); a[0] *= 0.5; a[n] *= 0.5; dfct(n, a, t, ip, w); err = errorcheck(0, n, 2.0 / n, a); printf("dfct err= %g \n", err); /* check of DFST */ putdata(1, n - 1, a); dfst(n, a, t, ip, w); dfst(n, a, t, ip, w); err = errorcheck(1, n - 1, 2.0 / n, a); printf("dfst err= %g \n", err); return 0; }
void dfct(int n, double *a) { void ddct(int n, int isgn, double *a); void bitrv1(int n, double *a); int j, k, m, mh; double xr, xi, yr, yi, an; m = n >> 1; for (j = 0; j < m; j++) { k = n - j; xr = a[j] + a[k]; a[j] -= a[k]; a[k] = xr; } an = a[n]; while (m >= 2) { ddct(m, 1, a); bitrv1(m, a); mh = m >> 1; xi = a[m]; a[m] = a[0]; a[0] = an - xi; an += xi; for (j = 1; j < mh; j++) { k = m - j; xr = a[m + k]; xi = a[m + j]; yr = a[j]; yi = a[k]; a[m + j] = yr; a[m + k] = yi; a[j] = xr - xi; a[k] = xr + xi; } xr = a[mh]; a[mh] = a[m + mh]; a[m + mh] = xr; m = mh; } xi = a[1]; a[1] = a[0]; a[0] = an + xi; a[n] = an - xi; bitrv1(n, a); }
void chebexp(double (*f)(T), T a, T b, T eps, BasicArray<T> &c, T &err) { int lenc = c.n() ; int j, k, l, n; T esf, ba, cos2, sin2, wi, ss, x, y, t, h, eref, erefh, errh; esf = 10; ba = T(0.5) * (b - a); c[0] = T(0.5) * (*f)(a); c[2] = T(0.5) * (*f)(b); c[1] = (*f)(a + ba); c[lenc - 1] = c[0] - c[2]; c[lenc] = c[0] + c[2] + c[1]; c[lenc - 2] = c[0] + c[2] - c[1]; cos2 = 0; sin2 = 1; wi = -1; h = 1; l = 1; n = 2; eref = erefh = T() ; do { ss = 2 * sin2; cos2 = sqrt(2 + cos2); sin2 /= 2 + cos2; x = ba * sin2; y = 0; for (j = 0; j <= l - 1; j++) { x += y; y += ss * (ba - x); c[j] = (*f)(a + x); c[n - 1 - j] = (*f)(b - x); } wi /= cos2; ddct(n, T(0.5) * cos2, wi, c); l = n; n *= 2; for (j = l - 1; j >= 0; j--) { k = lenc - j; t = c[k] - c[j]; c[k] += c[j]; c[lenc - n + j] = t; } if (n == 4) { eref = T(0.25) * (fabs(c[lenc]) + fabs(c[lenc - 1]) + fabs(c[lenc - 2]) + fabs(c[lenc - 3]) + fabs(c[lenc - 4])); erefh = eref * sqrt(eps); eref *= eps; err = erefh; } h *= T(0.5); errh = esf * err; err = h * (T(0.5) * fabs(c[lenc - n]) + fabs(c[lenc - n + 1])); } while ((err > eref || errh > erefh) && 2 * n + 4 <= lenc); c[lenc - n] *= T(0.5); c[lenc] *= T(0.5); for (j = lenc - n; j <= lenc; j++) { c[j] *= h; } if (err > eref || errh > erefh) { err = -(err); } else { do { n -= 2; err += fabs(c[lenc - n]) + fabs(c[lenc - n + 1]); } while (err < eref && n > 2); n += 2; err = eref; } if (ba != 0) { c[3] = 1 / ba; } else { c[3] = 0; } c[2] = T(0.5) * (b + a); c[1] = n + T(0.5); c[0] = lenc + T(0.5); }
void whs_extractor_process (WhsExtractor *self, const gfloat *in, WhsFeatureVector *ret) { gdouble tmp; // Calculate MFCC // http://de.wikipedia.org/wiki/MFCC // Copy to our temporary array and apply hamming window gdouble *freqdata = self->priv->fft.freqdata; for (gint i = 0; i < self->frame_length; i++) { freqdata[i] = in[i] * self->priv->cos[i]; } // Take FFT rdft (self->frame_length, 1, freqdata, self->priv->fft.ip, self->priv->fft.w); // Store magnitude spectrum in freqdata[0...n/2] for (guint i = 0; i < self->frame_length; i += 2) { gdouble cur; if (i == 0) { freqdata[0] = freqdata[0] * freqdata[0]; freqdata[1] = freqdata[1] * freqdata[1]; } else { cur = freqdata[i / 2 + 1] = freqdata[i] * freqdata[i] + freqdata[i+1] * freqdata[i+1]; } } // Move freqdata[1] to the end, it's for the nyquist frequency! tmp = freqdata[1]; g_memmove (&freqdata[1], &freqdata[2], sizeof (gdouble) * (self->frame_length / 2 - 1)); freqdata[self->frame_length / 2] = tmp; // Take logarithms for (gint i = 0; i < self->frame_length / 2 + 1; i++) { if (freqdata[i] != 0.0) freqdata[i] = CLAMP (log10 (sqrt (freqdata[i]/(self->frame_length*self->frame_length))), -500.0, G_MAXDOUBLE); else freqdata[i] = -500.0; } // Convert to mel spectrum gdouble bins[32]; #if 0 { gint bin = 0; gint step = mel (self->sample_rate / 2) / 32; // 32 bins for (bin = 0; bin < 32; bin++) { gint i; bins[bin] = 0.0; // Fill bin from 'start' to 'stop' with triangular weighting gdouble start = (bin > 0) ? bin * step - 0.5 * step : 0; gdouble stop = (bin < 31) ? (bin + 1) * step + 0.5 * step : (bin + 1) * step; for (i = 0; i < self->frame_length / 2 + 1; i++) { gdouble f = (((gfloat) i) / ((gfloat) (self->frame_length))) * self->sample_rate; bins[bin] += triangle (start, stop, mel (f)) * freqdata[i]; } } } #else { #if 1 gint i, j = 0, bin = 0; gint start_m = (self->min_freq > 0) ? mel (CLAMP (self->min_freq - (self->sample_rate / self->frame_length), 0, self->sample_rate / 2)) : 0; gint stop_m = (self->max_freq > 0) ? mel (CLAMP (self->max_freq + (self->sample_rate / self->frame_length), 0, self->sample_rate / 2)) : mel (self->sample_rate / 2); gint step = (stop_m - start_m) / 32; // 32 bins #else gint i, j = 0, bin = 0; gint start_m = 0; gint step = mel (self->sample_rate / 2) / 32; // 32 bins #endif for (bin = i = 0; bin < 32; bin++, i += j) { bins[bin] = 0.0; // Fill bin for (j = 0; (i + j) <= self->frame_length / 2 && mel (((i + j) * (self->sample_rate / 2)) / (self->frame_length / 2)) <= start_m + step * (bin + 1); j++) { bins[bin] += freqdata[i+j]; } // Normalize bin if (j != 0) bins[bin] /= j; } } #endif // Calculate DCT ddct (32, -1, bins, self->priv->dct.ip, self->priv->dct.w); for (gint i = 0; i < 32; i++) ret->mfcc[i] = bins[i]; }