summaryrefslogtreecommitdiff
path: root/sms
diff options
context:
space:
mode:
Diffstat (limited to 'sms')
-rw-r--r--sms/OOURA.c638
-rw-r--r--sms/OOURA.h23
-rw-r--r--sms/SFMT.c621
-rw-r--r--sms/SFMT.h157
-rw-r--r--sms/SFMT/SFMT-params.h97
-rw-r--r--sms/SFMT/SFMT-params11213.h46
-rw-r--r--sms/SFMT/SFMT-params1279.h46
-rw-r--r--sms/SFMT/SFMT-params132049.h46
-rw-r--r--sms/SFMT/SFMT-params19937.h46
-rw-r--r--sms/SFMT/SFMT-params216091.h46
-rw-r--r--sms/SFMT/SFMT-params2281.h46
-rw-r--r--sms/SFMT/SFMT-params4253.h46
-rw-r--r--sms/SFMT/SFMT-params44497.h46
-rw-r--r--sms/SFMT/SFMT-params607.h46
-rw-r--r--sms/SFMT/SFMT-params86243.h46
-rw-r--r--sms/analysis.c563
-rw-r--r--sms/cepstrum.c259
-rw-r--r--sms/fileIO.c559
-rw-r--r--sms/filters.c190
-rw-r--r--sms/fixTracks.c259
-rw-r--r--sms/harmDetection.c390
-rw-r--r--sms/modify.c215
-rw-r--r--sms/peakContinuation.c481
-rw-r--r--sms/peakDetection.c202
-rw-r--r--sms/residual.c76
-rw-r--r--sms/sineSynth.c190
-rw-r--r--sms/sms.c1132
-rw-r--r--sms/sms.h723
-rw-r--r--sms/sms.i540
-rw-r--r--sms/soundIO.c54
-rw-r--r--sms/spectralApprox.c152
-rw-r--r--sms/spectrum.c264
-rw-r--r--sms/stocAnalysis.c55
-rw-r--r--sms/synthesis.c260
-rw-r--r--sms/tables.c162
-rw-r--r--sms/transforms.c57
-rw-r--r--sms/windows.c280
37 files changed, 0 insertions, 9059 deletions
diff --git a/sms/OOURA.c b/sms/OOURA.c
deleted file mode 100644
index d88d20d..0000000
--- a/sms/OOURA.c
+++ /dev/null
@@ -1,638 +0,0 @@
-/* -_-_-_-_-_-_-_-_-_-_-_-_-_-_- Ooura Real DFT -_-_-_-_-_-_-_-_-_-_-_-_-_-_ */
-/* Copyright notice:
- This code comes from the "General Purpose FFT Package" that I obtained at
- the following website http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html
- It is exactly copied from the file fft4g.c, but I have changed the doubles to sfloats.
- Here is the copyright notice included in the package:
-
- Copyright(C) 1996-2001 Takuya OOURA
- email: ooura@mmm.t.u-tokyo.ac.jp
- download: http://momonga.t.u-tokyo.ac.jp/~ooura/fft.html
- You may use, copy, modify this code for any purpose and
- without fee. You may distribute this ORIGINAL package.
-
- The following is documentation of the algorithm included with the source code:
-
- -------- Real DFT / Inverse of Real DFT --------
- [definition]
- <case1> RDFT
- R[k] = sum_j=0^n-1 a[j]*cos(2*pi*j*k/n), 0<=k<=n/2
- I[k] = sum_j=0^n-1 a[j]*sin(2*pi*j*k/n), 0<k<n/2
- <case2> IRDFT (excluding scale)
- a[k] = (R[0] + R[n/2]*cos(pi*k))/2 +
- sum_j=1^n/2-1 R[j]*cos(2*pi*j*k/n) +
- sum_j=1^n/2-1 I[j]*sin(2*pi*j*k/n), 0<=k<n
- [usage]
- <case1>
- ip[0] = 0; // first time only
- rdft(n, 1, a, ip, w);
- <case2>
- ip[0] = 0; // first time only
- rdft(n, -1, a, ip, w);
- [parameters]
- n :data length (int)
- n >= 2, n = power of 2
- a[0...n-1] :input/output data (sfloat *)
- <case1>
- output data
- a[2*k] = R[k], 0<=k<n/2
- a[2*k+1] = I[k], 0<k<n/2
- a[1] = R[n/2]
- <case2>
- input data
- a[2*j] = R[j], 0<=j<n/2
- a[2*j+1] = I[j], 0<j<n/2
- a[1] = R[n/2]
- ip[0...*] :work area for bit reversal (int *)
- length of ip >= 2+sqrt(n/2)
- strictly,
- length of ip >=
- 2+(1<<(int)(log(n/2+0.5)/log(2))/2).
- ip[0],ip[1] are pointers of the cos/sin table.
- w[0...n/2-1] :cos/sin table (sfloat *)
- w[],ip[] are initialized if ip[0] == 0.
- [remark]
- Inverse of
- rdft(n, 1, a, ip, w);
- is
- rdft(n, -1, a, ip, w);
- for (j = 0; j <= n - 1; j++) {
- a[j] *= 2.0 / n;
- }
- .
-*/
-
-#include "OOURA.h"
-#include "math.h" /*! \todo (optimize) replace math.h trig functions (table lookup?) */
-
-/* ! \brief OOURA Real / Inverse DFT algoriithm
- *
- * The source code contains documentation from
- * the original author.
- */
-void rdft(int n, int isgn, sfloat *a, int *ip, sfloat *w)
-{
- int nw, nc;
- sfloat xi;
-
- nw = ip[0];
- if (n > (nw << 2)) {
- nw = n >> 2;
- makewt(nw, ip, w);
- }
- nc = ip[1];
- if (n > (nc << 2)) {
- nc = n >> 2;
- makect(nc, ip, w + nw);
- }
- if (isgn >= 0) {
- if (n > 4) {
- bitrv2(n, ip + 2, a);
- cftfsub(n, a, w);
- rftfsub(n, a, nc, w + nw);
- } else if (n == 4) {
- cftfsub(n, a, w);
- }
- xi = a[0] - a[1];
- a[0] += a[1];
- a[1] = xi;
- } else {
- a[1] = 0.5 * (a[0] - a[1]);
- a[0] -= a[1];
- if (n > 4) {
- rftbsub(n, a, nc, w + nw);
- bitrv2(n, ip + 2, a);
- cftbsub(n, a, w);
- } else if (n == 4) {
- cftfsub(n, a, w);
- }
- }
-}
-
-
-void makewt(int nw, int *ip, sfloat *w)
-{
- int j, nwh;
- sfloat delta, x, y;
-
- ip[0] = nw;
- ip[1] = 1;
- if (nw > 2) {
- nwh = nw >> 1;
- delta = atan(1.0) / nwh;
- w[0] = 1;
- w[1] = 0;
- w[nwh] = cos(delta * nwh);
- w[nwh + 1] = w[nwh];
- if (nwh > 2) {
- for (j = 2; j < nwh; j += 2) {
- x = cos(delta * j);
- y = sin(delta * j);
- w[j] = x;
- w[j + 1] = y;
- w[nw - j] = y;
- w[nw - j + 1] = x;
- }
- bitrv2(nw, ip + 2, w);
- }
- }
-}
-
-void makect(int nc, int *ip, sfloat *c)
-{
- int j, nch;
- sfloat delta;
-
- ip[1] = nc;
- if (nc > 1) {
- nch = nc >> 1;
- delta = atan(1.0) / nch;
- c[0] = cos(delta * nch);
- c[nch] = 0.5 * c[0];
- for (j = 1; j < nch; j++) {
- c[j] = 0.5 * cos(delta * j);
- c[nc - j] = 0.5 * sin(delta * j);
- }
- }
-}
-
-void bitrv2(int n, int *ip, sfloat *a)
-{
- int j, j1, k, k1, l, m, m2;
- sfloat xr, xi, yr, yi;
-
- ip[0] = 0;
- l = n;
- m = 1;
- while ((m << 3) < l) {
- l >>= 1;
- for (j = 0; j < m; j++) {
- ip[m + j] = ip[j] + l;
- }
- m <<= 1;
- }
- m2 = 2 * m;
- if ((m << 3) == l) {
- for (k = 0; k < m; k++) {
- for (j = 0; j < k; j++) {
- j1 = 2 * j + ip[k];
- k1 = 2 * k + ip[j];
- xr = a[j1];
- xi = a[j1 + 1];
- yr = a[k1];
- yi = a[k1 + 1];
- a[j1] = yr;
- a[j1 + 1] = yi;
- a[k1] = xr;
- a[k1 + 1] = xi;
- j1 += m2;
- k1 += 2 * m2;
- xr = a[j1];
- xi = a[j1 + 1];
- yr = a[k1];
- yi = a[k1 + 1];
- a[j1] = yr;
- a[j1 + 1] = yi;
- a[k1] = xr;
- a[k1 + 1] = xi;
- j1 += m2;
- k1 -= m2;
- xr = a[j1];
- xi = a[j1 + 1];
- yr = a[k1];
- yi = a[k1 + 1];
- a[j1] = yr;
- a[j1 + 1] = yi;
- a[k1] = xr;
- a[k1 + 1] = xi;
- j1 += m2;
- k1 += 2 * m2;
- xr = a[j1];
- xi = a[j1 + 1];
- yr = a[k1];
- yi = a[k1 + 1];
- a[j1] = yr;
- a[j1 + 1] = yi;
- a[k1] = xr;
- a[k1 + 1] = xi;
- }
- j1 = 2 * k + m2 + ip[k];
- k1 = j1 + m2;
- xr = a[j1];
- xi = a[j1 + 1];
- yr = a[k1];
- yi = a[k1 + 1];
- a[j1] = yr;
- a[j1 + 1] = yi;
- a[k1] = xr;
- a[k1 + 1] = xi;
- }
- } else {
- for (k = 1; k < m; k++) {
- for (j = 0; j < k; j++) {
- j1 = 2 * j + ip[k];
- k1 = 2 * k + ip[j];
- xr = a[j1];
- xi = a[j1 + 1];
- yr = a[k1];
- yi = a[k1 + 1];
- a[j1] = yr;
- a[j1 + 1] = yi;
- a[k1] = xr;
- a[k1 + 1] = xi;
- j1 += m2;
- k1 += m2;
- xr = a[j1];
- xi = a[j1 + 1];
- yr = a[k1];
- yi = a[k1 + 1];
- a[j1] = yr;
- a[j1 + 1] = yi;
- a[k1] = xr;
- a[k1 + 1] = xi;
- }
- }
- }
-}
-
-void cftfsub(int n, sfloat *a, sfloat *w)
-{
- int j, j1, j2, j3, l;
- sfloat x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
-
- l = 2;
- if (n > 8) {
- cft1st(n, a, w);
- l = 8;
- while ((l << 2) < n) {
- cftmdl(n, l, a, w);
- l <<= 2;
- }
- }
- if ((l << 2) == n) {
- for (j = 0; j < l; j += 2) {
- j1 = j + l;
- j2 = j1 + l;
- j3 = j2 + l;
- x0r = a[j] + a[j1];
- x0i = a[j + 1] + a[j1 + 1];
- x1r = a[j] - a[j1];
- x1i = a[j + 1] - a[j1 + 1];
- x2r = a[j2] + a[j3];
- x2i = a[j2 + 1] + a[j3 + 1];
- x3r = a[j2] - a[j3];
- x3i = a[j2 + 1] - a[j3 + 1];
- a[j] = x0r + x2r;
- a[j + 1] = x0i + x2i;
- a[j2] = x0r - x2r;
- a[j2 + 1] = x0i - x2i;
- a[j1] = x1r - x3i;
- a[j1 + 1] = x1i + x3r;
- a[j3] = x1r + x3i;
- a[j3 + 1] = x1i - x3r;
- }
- } else {
- for (j = 0; j < l; j += 2) {
- j1 = j + l;
- x0r = a[j] - a[j1];
- x0i = a[j + 1] - a[j1 + 1];
- a[j] += a[j1];
- a[j + 1] += a[j1 + 1];
- a[j1] = x0r;
- a[j1 + 1] = x0i;
- }
- }
-}
-
-
-void cftbsub(int n, sfloat *a, sfloat *w)
-{
- int j, j1, j2, j3, l;
- sfloat x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
-
- l = 2;
- if (n > 8) {
- cft1st(n, a, w);
- l = 8;
- while ((l << 2) < n) {
- cftmdl(n, l, a, w);
- l <<= 2;
- }
- }
- if ((l << 2) == n) {
- for (j = 0; j < l; j += 2) {
- j1 = j + l;
- j2 = j1 + l;
- j3 = j2 + l;
- x0r = a[j] + a[j1];
- x0i = -a[j + 1] - a[j1 + 1];
- x1r = a[j] - a[j1];
- x1i = -a[j + 1] + a[j1 + 1];
- x2r = a[j2] + a[j3];
- x2i = a[j2 + 1] + a[j3 + 1];
- x3r = a[j2] - a[j3];
- x3i = a[j2 + 1] - a[j3 + 1];
- a[j] = x0r + x2r;
- a[j + 1] = x0i - x2i;
- a[j2] = x0r - x2r;
- a[j2 + 1] = x0i + x2i;
- a[j1] = x1r - x3i;
- a[j1 + 1] = x1i - x3r;
- a[j3] = x1r + x3i;
- a[j3 + 1] = x1i + x3r;
- }
- } else {
- for (j = 0; j < l; j += 2) {
- j1 = j + l;
- x0r = a[j] - a[j1];
- x0i = -a[j + 1] + a[j1 + 1];
- a[j] += a[j1];
- a[j + 1] = -a[j + 1] - a[j1 + 1];
- a[j1] = x0r;
- a[j1 + 1] = x0i;
- }
- }
-}
-
-
-void cft1st(int n, sfloat *a, sfloat *w)
-{
- int j, k1, k2;
- sfloat wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;
- sfloat x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
-
- x0r = a[0] + a[2];
- x0i = a[1] + a[3];
- x1r = a[0] - a[2];
- x1i = a[1] - a[3];
- x2r = a[4] + a[6];
- x2i = a[5] + a[7];
- x3r = a[4] - a[6];
- x3i = a[5] - a[7];
- a[0] = x0r + x2r;
- a[1] = x0i + x2i;
- a[4] = x0r - x2r;
- a[5] = x0i - x2i;
- a[2] = x1r - x3i;
- a[3] = x1i + x3r;
- a[6] = x1r + x3i;
- a[7] = x1i - x3r;
- wk1r = w[2];
- x0r = a[8] + a[10];
- x0i = a[9] + a[11];
- x1r = a[8] - a[10];
- x1i = a[9] - a[11];
- x2r = a[12] + a[14];
- x2i = a[13] + a[15];
- x3r = a[12] - a[14];
- x3i = a[13] - a[15];
- a[8] = x0r + x2r;
- a[9] = x0i + x2i;
- a[12] = x2i - x0i;
- a[13] = x0r - x2r;
- x0r = x1r - x3i;
- x0i = x1i + x3r;
- a[10] = wk1r * (x0r - x0i);
- a[11] = wk1r * (x0r + x0i);
- x0r = x3i + x1r;
- x0i = x3r - x1i;
- a[14] = wk1r * (x0i - x0r);
- a[15] = wk1r * (x0i + x0r);
- k1 = 0;
- for (j = 16; j < n; j += 16) {
- k1 += 2;
- k2 = 2 * k1;
- wk2r = w[k1];
- wk2i = w[k1 + 1];
- wk1r = w[k2];
- wk1i = w[k2 + 1];
- wk3r = wk1r - 2 * wk2i * wk1i;
- wk3i = 2 * wk2i * wk1r - wk1i;
- x0r = a[j] + a[j + 2];
- x0i = a[j + 1] + a[j + 3];
- x1r = a[j] - a[j + 2];
- x1i = a[j + 1] - a[j + 3];
- x2r = a[j + 4] + a[j + 6];
- x2i = a[j + 5] + a[j + 7];
- x3r = a[j + 4] - a[j + 6];
- x3i = a[j + 5] - a[j + 7];
- a[j] = x0r + x2r;
- a[j + 1] = x0i + x2i;
- x0r -= x2r;
- x0i -= x2i;
- a[j + 4] = wk2r * x0r - wk2i * x0i;
- a[j + 5] = wk2r * x0i + wk2i * x0r;
- x0r = x1r - x3i;
- x0i = x1i + x3r;
- a[j + 2] = wk1r * x0r - wk1i * x0i;
- a[j + 3] = wk1r * x0i + wk1i * x0r;
- x0r = x1r + x3i;
- x0i = x1i - x3r;
- a[j + 6] = wk3r * x0r - wk3i * x0i;
- a[j + 7] = wk3r * x0i + wk3i * x0r;
- wk1r = w[k2 + 2];
- wk1i = w[k2 + 3];
- wk3r = wk1r - 2 * wk2r * wk1i;
- wk3i = 2 * wk2r * wk1r - wk1i;
- x0r = a[j + 8] + a[j + 10];
- x0i = a[j + 9] + a[j + 11];
- x1r = a[j + 8] - a[j + 10];
- x1i = a[j + 9] - a[j + 11];
- x2r = a[j + 12] + a[j + 14];
- x2i = a[j + 13] + a[j + 15];
- x3r = a[j + 12] - a[j + 14];
- x3i = a[j + 13] - a[j + 15];
- a[j + 8] = x0r + x2r;
- a[j + 9] = x0i + x2i;
- x0r -= x2r;
- x0i -= x2i;
- a[j + 12] = -wk2i * x0r - wk2r * x0i;
- a[j + 13] = -wk2i * x0i + wk2r * x0r;
- x0r = x1r - x3i;
- x0i = x1i + x3r;
- a[j + 10] = wk1r * x0r - wk1i * x0i;
- a[j + 11] = wk1r * x0i + wk1i * x0r;
- x0r = x1r + x3i;
- x0i = x1i - x3r;
- a[j + 14] = wk3r * x0r - wk3i * x0i;
- a[j + 15] = wk3r * x0i + wk3i * x0r;
- }
-}
-
-
-void cftmdl(int n, int l, sfloat *a, sfloat *w)
-{
- int j, j1, j2, j3, k, k1, k2, m, m2;
- sfloat wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;
- sfloat x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
-
- m = l << 2;
- for (j = 0; j < l; j += 2) {
- j1 = j + l;
- j2 = j1 + l;
- j3 = j2 + l;
- x0r = a[j] + a[j1];
- x0i = a[j + 1] + a[j1 + 1];
- x1r = a[j] - a[j1];
- x1i = a[j + 1] - a[j1 + 1];
- x2r = a[j2] + a[j3];
- x2i = a[j2 + 1] + a[j3 + 1];
- x3r = a[j2] - a[j3];
- x3i = a[j2 + 1] - a[j3 + 1];
- a[j] = x0r + x2r;
- a[j + 1] = x0i + x2i;
- a[j2] = x0r - x2r;
- a[j2 + 1] = x0i - x2i;
- a[j1] = x1r - x3i;
- a[j1 + 1] = x1i + x3r;
- a[j3] = x1r + x3i;
- a[j3 + 1] = x1i - x3r;
- }
- wk1r = w[2];
- for (j = m; j < l + m; j += 2) {
- j1 = j + l;
- j2 = j1 + l;
- j3 = j2 + l;
- x0r = a[j] + a[j1];
- x0i = a[j + 1] + a[j1 + 1];
- x1r = a[j] - a[j1];
- x1i = a[j + 1] - a[j1 + 1];
- x2r = a[j2] + a[j3];
- x2i = a[j2 + 1] + a[j3 + 1];
- x3r = a[j2] - a[j3];
- x3i = a[j2 + 1] - a[j3 + 1];
- a[j] = x0r + x2r;
- a[j + 1] = x0i + x2i;
- a[j2] = x2i - x0i;
- a[j2 + 1] = x0r - x2r;
- x0r = x1r - x3i;
- x0i = x1i + x3r;
- a[j1] = wk1r * (x0r - x0i);
- a[j1 + 1] = wk1r * (x0r + x0i);
- x0r = x3i + x1r;
- x0i = x3r - x1i;
- a[j3] = wk1r * (x0i - x0r);
- a[j3 + 1] = wk1r * (x0i + x0r);
- }
- k1 = 0;
- m2 = 2 * m;
- for (k = m2; k < n; k += m2) {
- k1 += 2;
- k2 = 2 * k1;
- wk2r = w[k1];
- wk2i = w[k1 + 1];
- wk1r = w[k2];
- wk1i = w[k2 + 1];
- wk3r = wk1r - 2 * wk2i * wk1i;
- wk3i = 2 * wk2i * wk1r - wk1i;
- for (j = k; j < l + k; j += 2) {
- j1 = j + l;
- j2 = j1 + l;
- j3 = j2 + l;
- x0r = a[j] + a[j1];
- x0i = a[j + 1] + a[j1 + 1];
- x1r = a[j] - a[j1];
- x1i = a[j + 1] - a[j1 + 1];
- x2r = a[j2] + a[j3];
- x2i = a[j2 + 1] + a[j3 + 1];
- x3r = a[j2] - a[j3];
- x3i = a[j2 + 1] - a[j3 + 1];
- a[j] = x0r + x2r;
- a[j + 1] = x0i + x2i;
- x0r -= x2r;
- x0i -= x2i;
- a[j2] = wk2r * x0r - wk2i * x0i;
- a[j2 + 1] = wk2r * x0i + wk2i * x0r;
- x0r = x1r - x3i;
- x0i = x1i + x3r;
- a[j1] = wk1r * x0r - wk1i * x0i;
- a[j1 + 1] = wk1r * x0i + wk1i * x0r;
- x0r = x1r + x3i;
- x0i = x1i - x3r;
- a[j3] = wk3r * x0r - wk3i * x0i;
- a[j3 + 1] = wk3r * x0i + wk3i * x0r;
- }
- wk1r = w[k2 + 2];
- wk1i = w[k2 + 3];
- wk3r = wk1r - 2 * wk2r * wk1i;
- wk3i = 2 * wk2r * wk1r - wk1i;
- for (j = k + m; j < l + (k + m); j += 2) {
- j1 = j + l;
- j2 = j1 + l;
- j3 = j2 + l;
- x0r = a[j] + a[j1];
- x0i = a[j + 1] + a[j1 + 1];
- x1r = a[j] - a[j1];
- x1i = a[j + 1] - a[j1 + 1];
- x2r = a[j2] + a[j3];
- x2i = a[j2 + 1] + a[j3 + 1];
- x3r = a[j2] - a[j3];
- x3i = a[j2 + 1] - a[j3 + 1];
- a[j] = x0r + x2r;
- a[j + 1] = x0i + x2i;
- x0r -= x2r;
- x0i -= x2i;
- a[j2] = -wk2i * x0r - wk2r * x0i;
- a[j2 + 1] = -wk2i * x0i + wk2r * x0r;
- x0r = x1r - x3i;
- x0i = x1i + x3r;
- a[j1] = wk1r * x0r - wk1i * x0i;
- a[j1 + 1] = wk1r * x0i + wk1i * x0r;
- x0r = x1r + x3i;
- x0i = x1i - x3r;
- a[j3] = wk3r * x0r - wk3i * x0i;
- a[j3 + 1] = wk3r * x0i + wk3i * x0r;
- }
- }
-}
-
-
-void rftfsub(int n, sfloat *a, int nc, sfloat *c)
-{
- int j, k, kk, ks, m;
- sfloat wkr, wki, xr, xi, yr, yi;
-
- m = n >> 1;
- ks = 2 * nc / m;
- kk = 0;
- for (j = 2; j < m; j += 2) {
- k = n - j;
- kk += ks;
- wkr = 0.5 - c[nc - kk];
- wki = c[kk];
- xr = a[j] - a[k];
- xi = a[j + 1] + a[k + 1];
- yr = wkr * xr - wki * xi;
- yi = wkr * xi + wki * xr;
- a[j] -= yr;
- a[j + 1] -= yi;
- a[k] += yr;
- a[k + 1] -= yi;
- }
-}
-
-void rftbsub(int n, sfloat *a, int nc, sfloat *c)
-{
- int j, k, kk, ks, m;
- sfloat wkr, wki, xr, xi, yr, yi;
-
- a[1] = -a[1];
- m = n >> 1;
- ks = 2 * nc / m;
- kk = 0;
- for (j = 2; j < m; j += 2) {
- k = n - j;
- kk += ks;
- wkr = 0.5 - c[nc - kk];
- wki = c[kk];
- xr = a[j] - a[k];
- xi = a[j + 1] + a[k + 1];
- yr = wkr * xr + wki * xi;
- yi = wkr * xi - wki * xr;
- a[j] -= yr;
- a[j + 1] = yi - a[j + 1];
- a[k] += yr;
- a[k + 1] = yi - a[k + 1];
- }
- a[m + 1] = -a[m + 1];
-}
diff --git a/sms/OOURA.h b/sms/OOURA.h
deleted file mode 100644
index d7c60ad..0000000
--- a/sms/OOURA.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef _OOURA_H
-#define _OOURA_H
-
-#define sfloat double
-/*#define sfloat float*/
-
-#define NMAX 8192
-#define NMAXSQRT 64
-
-void rdft(int n, int isgn, sfloat *a, int *ip, sfloat *w);
-
-void makewt(int nw, int *ip, sfloat *w);
-void makect(int nc, int *ip, sfloat *c);
-void bitrv2(int n, int *ip, sfloat *a);
-void cftfsub(int n, sfloat *a, sfloat *w);
-void cftbsub(int n, sfloat *a, sfloat *w);
-void rftfsub(int n, sfloat *a, int nc, sfloat *c);
-void rftbsub(int n, sfloat *a, int nc, sfloat *c);
-
-void cft1st(int n, sfloat *a, sfloat *w);
-void cftmdl(int n, int l, sfloat *a, sfloat *w);
-
-#endif /* _OURA_H */
diff --git a/sms/SFMT.c b/sms/SFMT.c
deleted file mode 100644
index 7b84db7..0000000
--- a/sms/SFMT.c
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * @file SFMT.c
- * @brief SIMD oriented Fast Mersenne Twister(SFMT)
- *
- * @author Mutsuo Saito (Hiroshima University)
- * @author Makoto Matsumoto (Hiroshima University)
- *
- * Copyright (C) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
- * University. All rights reserved.
- *
- * The new BSD License is applied to this software, see LICENSE.txt
- */
-
-#include <string.h>
-#include <assert.h>
-#include "SFMT.h"
-#include "SFMT/SFMT-params.h"
-
-#if defined(__BIG_ENDIAN__) && !defined(__amd64) && !defined(BIG_ENDIAN64)
-#define BIG_ENDIAN64 1
-#endif
-#if defined(HAVE_ALTIVEC) && !defined(BIG_ENDIAN64)
-#define BIG_ENDIAN64 1
-#endif
-#if defined(ONLY64) && !defined(BIG_ENDIAN64)
- #if defined(__GNUC__)
- #error "-DONLY64 must be specified with -DBIG_ENDIAN64"
- #endif
-#undef ONLY64
-#endif
-/*------------------------------------------------------
- 128-bit SIMD data type for Altivec, SSE2 or standard C
- ------------------------------------------------------*/
-#if defined(HAVE_ALTIVEC)
- #if !defined(__APPLE__)
- #include <altivec.h>
- #endif
-/** 128-bit data structure */
-union W128_T {
- vector unsigned int s;
- uint32_t u[4];
-};
-/** 128-bit data type */
-typedef union W128_T w128_t;
-
-#elif defined(HAVE_SSE2)
- #include <emmintrin.h>
-
-/** 128-bit data structure */
-union W128_T {
- __m128i si;
- uint32_t u[4];
-};
-/** 128-bit data type */
-typedef union W128_T w128_t;
-
-#else
-
-/** 128-bit data structure */
-struct W128_T {
- uint32_t u[4];
-};
-/** 128-bit data type */
-typedef struct W128_T w128_t;
-
-#endif
-
-/*--------------------------------------
- FILE GLOBAL VARIABLES
- internal state, index counter and flag
- --------------------------------------*/
-/** the 128-bit internal state array */
-static w128_t sfmt[N];
-/** the 32bit integer pointer to the 128-bit internal state array */
-static uint32_t *psfmt32 = &sfmt[0].u[0];
-#if !defined(BIG_ENDIAN64) || defined(ONLY64)
-/** the 64bit integer pointer to the 128-bit internal state array */
-static uint64_t *psfmt64 = (uint64_t *)&sfmt[0].u[0];
-#endif
-/** index counter to the 32-bit internal state array */
-static int idx;
-/** a flag: it is 0 if and only if the internal state is not yet
- * initialized. */
-static int initialized = 0;
-/** a parity check vector which certificate the period of 2^{MEXP} */
-static uint32_t parity[4] = {PARITY1, PARITY2, PARITY3, PARITY4};
-
-/*----------------
- STATIC FUNCTIONS
- ----------------*/
-inline static int idxof(int i);
-inline static void rshift128(w128_t *out, w128_t const *in, int shift);
-inline static void lshift128(w128_t *out, w128_t const *in, int shift);
-inline static void gen_rand_all(void);
-inline static void gen_rand_array(w128_t *array, int size);
-inline static uint32_t func1(uint32_t x);
-inline static uint32_t func2(uint32_t x);
-static void period_certification(void);
-#if defined(BIG_ENDIAN64) && !defined(ONLY64)
-inline static void swap(w128_t *array, int size);
-#endif
-
-#if defined(HAVE_ALTIVEC)
- #include "SFMT-alti.h"
-#elif defined(HAVE_SSE2)
- #include "SFMT-sse2.h"
-#endif
-
-/**
- * This function simulate a 64-bit index of LITTLE ENDIAN
- * in BIG ENDIAN machine.
- */
-#ifdef ONLY64
-inline static int idxof(int i) {
- return i ^ 1;
-}
-#else
-inline static int idxof(int i) {
- return i;
-}
-#endif
-/**
- * This function simulates SIMD 128-bit right shift by the standard C.
- * The 128-bit integer given in in is shifted by (shift * 8) bits.
- * This function simulates the LITTLE ENDIAN SIMD.
- * @param out the output of this function
- * @param in the 128-bit data to be shifted
- * @param shift the shift value
- */
-#ifdef ONLY64
-inline static void rshift128(w128_t *out, w128_t const *in, int shift) {
- uint64_t th, tl, oh, ol;
-
- th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);
- tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);
-
- oh = th >> (shift * 8);
- ol = tl >> (shift * 8);
- ol |= th << (64 - shift * 8);
- out->u[0] = (uint32_t)(ol >> 32);
- out->u[1] = (uint32_t)ol;
- out->u[2] = (uint32_t)(oh >> 32);
- out->u[3] = (uint32_t)oh;
-}
-#else
-inline static void rshift128(w128_t *out, w128_t const *in, int shift) {
- uint64_t th, tl, oh, ol;
-
- th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);
- tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);
-
- oh = th >> (shift * 8);
- ol = tl >> (shift * 8);
- ol |= th << (64 - shift * 8);
- out->u[1] = (uint32_t)(ol >> 32);
- out->u[0] = (uint32_t)ol;
- out->u[3] = (uint32_t)(oh >> 32);
- out->u[2] = (uint32_t)oh;
-}
-#endif
-/**
- * This function simulates SIMD 128-bit left shift by the standard C.
- * The 128-bit integer given in in is shifted by (shift * 8) bits.
- * This function simulates the LITTLE ENDIAN SIMD.
- * @param out the output of this function
- * @param in the 128-bit data to be shifted
- * @param shift the shift value
- */
-#ifdef ONLY64
-inline static void lshift128(w128_t *out, w128_t const *in, int shift) {
- uint64_t th, tl, oh, ol;
-
- th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);
- tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);
-
- oh = th << (shift * 8);
- ol = tl << (shift * 8);
- oh |= tl >> (64 - shift * 8);
- out->u[0] = (uint32_t)(ol >> 32);
- out->u[1] = (uint32_t)ol;
- out->u[2] = (uint32_t)(oh >> 32);
- out->u[3] = (uint32_t)oh;
-}
-#else
-inline static void lshift128(w128_t *out, w128_t const *in, int shift) {
- uint64_t th, tl, oh, ol;
-
- th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);
- tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);
-
- oh = th << (shift * 8);
- ol = tl << (shift * 8);
- oh |= tl >> (64 - shift * 8);
- out->u[1] = (uint32_t)(ol >> 32);
- out->u[0] = (uint32_t)ol;
- out->u[3] = (uint32_t)(oh >> 32);
- out->u[2] = (uint32_t)oh;
-}
-#endif
-
-/**
- * This function represents the recursion formula.
- * @param r output
- * @param a a 128-bit part of the internal state array
- * @param b a 128-bit part of the internal state array
- * @param c a 128-bit part of the internal state array
- * @param d a 128-bit part of the internal state array
- */
-#if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))
-#ifdef ONLY64
-inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,
- w128_t *d) {
- w128_t x;
- w128_t y;
-
- lshift128(&x, a, SL2);
- rshift128(&y, c, SR2);
- r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SR1) & MSK2) ^ y.u[0]
- ^ (d->u[0] << SL1);
- r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SR1) & MSK1) ^ y.u[1]
- ^ (d->u[1] << SL1);
- r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SR1) & MSK4) ^ y.u[2]
- ^ (d->u[2] << SL1);
- r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SR1) & MSK3) ^ y.u[3]
- ^ (d->u[3] << SL1);
-}
-#else
-inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,
- w128_t *d) {
- w128_t x;
- w128_t y;
-
- lshift128(&x, a, SL2);
- rshift128(&y, c, SR2);
- r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SR1) & MSK1) ^ y.u[0]
- ^ (d->u[0] << SL1);
- r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SR1) & MSK2) ^ y.u[1]
- ^ (d->u[1] << SL1);
- r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SR1) & MSK3) ^ y.u[2]
- ^ (d->u[2] << SL1);
- r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SR1) & MSK4) ^ y.u[3]
- ^ (d->u[3] << SL1);
-}
-#endif
-#endif
-
-#if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))
-/**
- * This function fills the internal state array with pseudorandom
- * integers.
- */
-inline static void gen_rand_all(void) {
- int i;
- w128_t *r1, *r2;
-
- r1 = &sfmt[N - 2];
- r2 = &sfmt[N - 1];
- for (i = 0; i < N - POS1; i++) {
- do_recursion(&sfmt[i], &sfmt[i], &sfmt[i + POS1], r1, r2);
- r1 = r2;
- r2 = &sfmt[i];
- }
- for (; i < N; i++) {
- do_recursion(&sfmt[i], &sfmt[i], &sfmt[i + POS1 - N], r1, r2);
- r1 = r2;
- r2 = &sfmt[i];
- }
-}
-
-/**
- * This function fills the user-specified array with pseudorandom
- * integers.
- *
- * @param array an 128-bit array to be filled by pseudorandom numbers.
- * @param size number of 128-bit pseudorandom numbers to be generated.
- */
-inline static void gen_rand_array(w128_t *array, int size) {
- int i, j;
- w128_t *r1, *r2;
-
- r1 = &sfmt[N - 2];
- r2 = &sfmt[N - 1];
- for (i = 0; i < N - POS1; i++) {
- do_recursion(&array[i], &sfmt[i], &sfmt[i + POS1], r1, r2);
- r1 = r2;
- r2 = &array[i];
- }
- for (; i < N; i++) {
- do_recursion(&array[i], &sfmt[i], &array[i + POS1 - N], r1, r2);
- r1 = r2;
- r2 = &array[i];
- }
- for (; i < size - N; i++) {
- do_recursion(&array[i], &array[i - N], &array[i + POS1 - N], r1, r2);
- r1 = r2;
- r2 = &array[i];
- }
- for (j = 0; j < 2 * N - size; j++) {
- sfmt[j] = array[j + size - N];
- }
- for (; i < size; i++, j++) {
- do_recursion(&array[i], &array[i - N], &array[i + POS1 - N], r1, r2);
- r1 = r2;
- r2 = &array[i];
- sfmt[j] = array[i];
- }
-}
-#endif
-
-#if defined(BIG_ENDIAN64) && !defined(ONLY64) && !defined(HAVE_ALTIVEC)
-inline static void swap(w128_t *array, int size) {
- int i;
- uint32_t x, y;
-
- for (i = 0; i < size; i++) {
- x = array[i].u[0];
- y = array[i].u[2];
- array[i].u[0] = array[i].u[1];
- array[i].u[2] = array[i].u[3];
- array[i].u[1] = x;
- array[i].u[3] = y;
- }
-}
-#endif
-/**
- * This function represents a function used in the initialization
- * by init_by_array
- * @param x 32-bit integer
- * @return 32-bit integer
- */
-static uint32_t func1(uint32_t x) {
- return (x ^ (x >> 27)) * (uint32_t)1664525UL;
-}
-
-/**
- * This function represents a function used in the initialization
- * by init_by_array
- * @param x 32-bit integer
- * @return 32-bit integer
- */
-static uint32_t func2(uint32_t x) {
- return (x ^ (x >> 27)) * (uint32_t)1566083941UL;
-}
-
-/**
- * This function certificate the period of 2^{MEXP}
- */
-static void period_certification(void) {
- int inner = 0;
- int i, j;
- uint32_t work;
-
- for (i = 0; i < 4; i++)
- inner ^= psfmt32[idxof(i)] & parity[i];
- for (i = 16; i > 0; i >>= 1)
- inner ^= inner >> i;
- inner &= 1;
- /* check OK */
- if (inner == 1) {
- return;
- }
- /* check NG, and modification */
- for (i = 0; i < 4; i++) {
- work = 1;
- for (j = 0; j < 32; j++) {
- if ((work & parity[i]) != 0) {
- psfmt32[idxof(i)] ^= work;
- return;
- }
- work = work << 1;
- }
- }
-}
-
-/*----------------
- PUBLIC FUNCTIONS
- ----------------*/
-/**
- * This function returns the identification string.
- * The string shows the word size, the Mersenne exponent,
- * and all parameters of this generator.
- */
-const char *get_idstring(void) {
- return IDSTR;
-}
-
-/**
- * This function returns the minimum size of array used for \b
- * fill_array32() function.
- * @return minimum size of array used for fill_array32() function.
- */
-int get_min_array_size32(void) {
- return N32;
-}
-
-/**
- * This function returns the minimum size of array used for \b
- * fill_array64() function.
- * @return minimum size of array used for fill_array64() function.
- */
-int get_min_array_size64(void) {
- return N64;
-}
-
-#ifndef ONLY64
-/**
- * This function generates and returns 32-bit pseudorandom number.
- * init_gen_rand or init_by_array must be called before this function.
- * @return 32-bit pseudorandom number
- */
-uint32_t gen_rand32(void) {
- uint32_t r;
-
- assert(initialized);
- if (idx >= N32) {
- gen_rand_all();
- idx = 0;
- }
- r = psfmt32[idx++];
- return r;
-}
-#endif
-/**
- * This function generates and returns 64-bit pseudorandom number.
- * init_gen_rand or init_by_array must be called before this function.
- * The function gen_rand64 should not be called after gen_rand32,
- * unless an initialization is again executed.
- * @return 64-bit pseudorandom number
- */
-uint64_t gen_rand64(void) {
-#if defined(BIG_ENDIAN64) && !defined(ONLY64)
- uint32_t r1, r2;
-#else
- uint64_t r;
-#endif
-
- assert(initialized);
- assert(idx % 2 == 0);
-
- if (idx >= N32) {
- gen_rand_all();
- idx = 0;
- }
-#if defined(BIG_ENDIAN64) && !defined(ONLY64)
- r1 = psfmt32[idx];
- r2 = psfmt32[idx + 1];
- idx += 2;
- return ((uint64_t)r2 << 32) | r1;
-#else
- r = psfmt64[idx / 2];
- idx += 2;
- return r;
-#endif
-}
-
-#ifndef ONLY64
-/**
- * This function generates pseudorandom 32-bit integers in the
- * specified array[] by one call. The number of pseudorandom integers
- * is specified by the argument size, which must be at least 624 and a
- * multiple of four. The generation by this function is much faster
- * than the following gen_rand function.
- *
- * For initialization, init_gen_rand or init_by_array must be called
- * before the first call of this function. This function can not be
- * used after calling gen_rand function, without initialization.
- *
- * @param array an array where pseudorandom 32-bit integers are filled
- * by this function. The pointer to the array must be \b "aligned"
- * (namely, must be a multiple of 16) in the SIMD version, since it
- * refers to the address of a 128-bit integer. In the standard C
- * version, the pointer is arbitrary.
- *
- * @param size the number of 32-bit pseudorandom integers to be
- * generated. size must be a multiple of 4, and greater than or equal
- * to (MEXP / 128 + 1) * 4.
- *
- * @note \b memalign or \b posix_memalign is available to get aligned
- * memory. Mac OSX doesn't have these functions, but \b malloc of OSX
- * returns the pointer to the aligned memory block.
- */
-void fill_array32(uint32_t *array, int size) {
- assert(initialized);
- assert(idx == N32);
- assert(size % 4 == 0);
- assert(size >= N32);
-
- gen_rand_array((w128_t *)array, size / 4);
- idx = N32;
-}
-#endif
-
-/**
- * This function generates pseudorandom 64-bit integers in the
- * specified array[] by one call. The number of pseudorandom integers
- * is specified by the argument size, which must be at least 312 and a
- * multiple of two. The generation by this function is much faster
- * than the following gen_rand function.
- *
- * For initialization, init_gen_rand or init_by_array must be called
- * before the first call of this function. This function can not be
- * used after calling gen_rand function, without initialization.
- *
- * @param array an array where pseudorandom 64-bit integers are filled
- * by this function. The pointer to the array must be "aligned"
- * (namely, must be a multiple of 16) in the SIMD version, since it
- * refers to the address of a 128-bit integer. In the standard C
- * version, the pointer is arbitrary.
- *
- * @param size the number of 64-bit pseudorandom integers to be
- * generated. size must be a multiple of 2, and greater than or equal
- * to (MEXP / 128 + 1) * 2
- *
- * @note \b memalign or \b posix_memalign is available to get aligned
- * memory. Mac OSX doesn't have these functions, but \b malloc of OSX
- * returns the pointer to the aligned memory block.
- */
-void fill_array64(uint64_t *array, int size) {
- assert(initialized);
- assert(idx == N32);
- assert(size % 2 == 0);
- assert(size >= N64);
-
- gen_rand_array((w128_t *)array, size / 2);
- idx = N32;
-
-#if defined(BIG_ENDIAN64) && !defined(ONLY64)
- swap((w128_t *)array, size /2);
-#endif
-}
-
-/**
- * This function initializes the internal state array with a 32-bit
- * integer seed.
- *
- * @param seed a 32-bit integer used as the seed.
- */
-void init_gen_rand(uint32_t seed) {
- int i;
-
- psfmt32[idxof(0)] = seed;
- for (i = 1; i < N32; i++) {
- psfmt32[idxof(i)] = 1812433253UL * (psfmt32[idxof(i - 1)]
- ^ (psfmt32[idxof(i - 1)] >> 30))
- + i;
- }
- idx = N32;
- period_certification();
- initialized = 1;
-}
-
-/**
- * This function initializes the internal state array,
- * with an array of 32-bit integers used as the seeds
- * @param init_key the array of 32-bit integers, used as a seed.
- * @param key_length the length of init_key.
- */
-void init_by_array(uint32_t *init_key, int key_length) {
- int i, j, count;
- uint32_t r;
- int lag;
- int mid;
- int size = N * 4;
-
- if (size >= 623) {
- lag = 11;
- } else if (size >= 68) {
- lag = 7;
- } else if (size >= 39) {
- lag = 5;
- } else {
- lag = 3;
- }
- mid = (size - lag) / 2;
-
- memset(sfmt, 0x8b, sizeof(sfmt));
- if (key_length + 1 > N32) {
- count = key_length + 1;
- } else {
- count = N32;
- }
- r = func1(psfmt32[idxof(0)] ^ psfmt32[idxof(mid)]
- ^ psfmt32[idxof(N32 - 1)]);
- psfmt32[idxof(mid)] += r;
- r += key_length;
- psfmt32[idxof(mid + lag)] += r;
- psfmt32[idxof(0)] = r;
-
- count--;
- for (i = 1, j = 0; (j < count) && (j < key_length); j++) {
- r = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % N32)]
- ^ psfmt32[idxof((i + N32 - 1) % N32)]);
- psfmt32[idxof((i + mid) % N32)] += r;
- r += init_key[j] + i;
- psfmt32[idxof((i + mid + lag) % N32)] += r;
- psfmt32[idxof(i)] = r;
- i = (i + 1) % N32;
- }
- for (; j < count; j++) {
- r = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % N32)]
- ^ psfmt32[idxof((i + N32 - 1) % N32)]);
- psfmt32[idxof((i + mid) % N32)] += r;
- r += i;
- psfmt32[idxof((i + mid + lag) % N32)] += r;
- psfmt32[idxof(i)] = r;
- i = (i + 1) % N32;
- }
- for (j = 0; j < N32; j++) {
- r = func2(psfmt32[idxof(i)] + psfmt32[idxof((i + mid) % N32)]
- + psfmt32[idxof((i + N32 - 1) % N32)]);
- psfmt32[idxof((i + mid) % N32)] ^= r;
- r -= i;
- psfmt32[idxof((i + mid + lag) % N32)] ^= r;
- psfmt32[idxof(i)] = r;
- i = (i + 1) % N32;
- }
-
- idx = N32;
- period_certification();
- initialized = 1;
-}
diff --git a/sms/SFMT.h b/sms/SFMT.h
deleted file mode 100644
index 7c8b35e..0000000
--- a/sms/SFMT.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/**
- * @file SFMT.h
- *
- * @brief SIMD oriented Fast Mersenne Twister(SFMT) pseudorandom
- * number generator
- *
- * @author Mutsuo Saito (Hiroshima University)
- * @author Makoto Matsumoto (Hiroshima University)
- *
- * Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
- * University. All rights reserved.
- *
- * The new BSD License is applied to this software.
- * see LICENSE.txt
- *
- * @note We assume that your system has inttypes.h. If your system
- * doesn't have inttypes.h, you have to typedef uint32_t and uint64_t,
- * and you have to define PRIu64 and PRIx64 in this file as follows:
- * @verbatim
- typedef unsigned int uint32_t
- typedef unsigned long long uint64_t
- #define PRIu64 "llu"
- #define PRIx64 "llx"
-@endverbatim
- * uint32_t must be exactly 32-bit unsigned integer type (no more, no
- * less), and uint64_t must be exactly 64-bit unsigned integer type.
- * PRIu64 and PRIx64 are used for printf function to print 64-bit
- * unsigned int and 64-bit unsigned int in hexadecimal format.
- */
-
-#ifndef SFMT_H
-#define SFMT_H
-
-#include <stdio.h>
-
-#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
- #include <inttypes.h>
-#elif defined(_MSC_VER) || defined(__BORLANDC__)
- typedef unsigned int uint32_t;
- typedef unsigned __int64 uint64_t;
- #define inline __inline
-#else
- #include <inttypes.h>
- #if defined(__GNUC__)
- #define inline __inline__
- #endif
-#endif
-
-#ifndef PRIu64
- #if defined(_MSC_VER) || defined(__BORLANDC__)
- #define PRIu64 "I64u"
- #define PRIx64 "I64x"
- #else
- #define PRIu64 "llu"
- #define PRIx64 "llx"
- #endif
-#endif
-
-#if defined(__GNUC__)
-#define ALWAYSINLINE __attribute__((always_inline))
-#else
-#define ALWAYSINLINE
-#endif
-
-#if defined(_MSC_VER)
- #if _MSC_VER >= 1200
- #define PRE_ALWAYS __forceinline
- #else
- #define PRE_ALWAYS inline
- #endif
-#else
- #define PRE_ALWAYS inline
-#endif
-
-uint32_t gen_rand32(void);
-uint64_t gen_rand64(void);
-void fill_array32(uint32_t *array, int size);
-void fill_array64(uint64_t *array, int size);
-void init_gen_rand(uint32_t seed);
-void init_by_array(uint32_t *init_key, int key_length);
-const char *get_idstring(void);
-int get_min_array_size32(void);
-int get_min_array_size64(void);
-
-/* These real versions are due to Isaku Wada */
-/** generates a random number on [0,1]-real-interval */
-inline static double to_real1(uint32_t v)
-{
- return v * (1.0/4294967295.0);
- /* divided by 2^32-1 */
-}
-
-/** generates a random number on [0,1]-real-interval */
-inline static double genrand_real1(void)
-{
- return to_real1(gen_rand32());
-}
-
-/** generates a random number on [0,1)-real-interval */
-inline static double to_real2(uint32_t v)
-{
- return v * (1.0/4294967296.0);
- /* divided by 2^32 */
-}
-
-/** generates a random number on [0,1)-real-interval */
-inline static double genrand_real2(void)
-{
- return to_real2(gen_rand32());
-}
-
-/** generates a random number on (0,1)-real-interval */
-inline static double to_real3(uint32_t v)
-{
- return (((double)v) + 0.5)*(1.0/4294967296.0);
- /* divided by 2^32 */
-}
-
-/** generates a random number on (0,1)-real-interval */
-inline static double genrand_real3(void)
-{
- return to_real3(gen_rand32());
-}
-/** These real versions are due to Isaku Wada */
-
-/** generates a random number on [0,1) with 53-bit resolution*/
-inline static double to_res53(uint64_t v)
-{
- return v * (1.0/18446744073709551616.0L);
-}
-
-/** generates a random number on [0,1) with 53-bit resolution from two
- * 32 bit integers */
-inline static double to_res53_mix(uint32_t x, uint32_t y)
-{
- return to_res53(x | ((uint64_t)y << 32));
-}
-
-/** generates a random number on [0,1) with 53-bit resolution
- */
-inline static double genrand_res53(void)
-{
- return to_res53(gen_rand64());
-}
-
-/** generates a random number on [0,1) with 53-bit resolution
- using 32bit integer.
- */
-inline static double genrand_res53_mix(void)
-{
- uint32_t x, y;
-
- x = gen_rand32();
- y = gen_rand32();
- return to_res53_mix(x, y);
-}
-#endif
diff --git a/sms/SFMT/SFMT-params.h b/sms/SFMT/SFMT-params.h
deleted file mode 100644
index 661bbf2..0000000
--- a/sms/SFMT/SFMT-params.h
+++ /dev/null
@@ -1,97 +0,0 @@
-#ifndef SFMT_PARAMS_H
-#define SFMT_PARAMS_H
-
-#if !defined(MEXP)
-#ifdef __GNUC__
- #warning "MEXP is not defined. I assume MEXP is 19937."
-#endif
- #define MEXP 19937
-#endif
-/*-----------------
- BASIC DEFINITIONS
- -----------------*/
-/** Mersenne Exponent. The period of the sequence
- * is a multiple of 2^MEXP-1.
- * #define MEXP 19937 */
-/** SFMT generator has an internal state array of 128-bit integers,
- * and N is its size. */
-#define N (MEXP / 128 + 1)
-/** N32 is the size of internal state array when regarded as an array
- * of 32-bit integers.*/
-#define N32 (N * 4)
-/** N64 is the size of internal state array when regarded as an array
- * of 64-bit integers.*/
-#define N64 (N * 2)
-
-/*----------------------
- the parameters of SFMT
- following definitions are in paramsXXXX.h file.
- ----------------------*/
-/** the pick up position of the array.
-#define POS1 122
-*/
-
-/** the parameter of shift left as four 32-bit registers.
-#define SL1 18
- */
-
-/** the parameter of shift left as one 128-bit register.
- * The 128-bit integer is shifted by (SL2 * 8) bits.
-#define SL2 1
-*/
-
-/** the parameter of shift right as four 32-bit registers.
-#define SR1 11
-*/
-
-/** the parameter of shift right as one 128-bit register.
- * The 128-bit integer is shifted by (SL2 * 8) bits.
-#define SR2 1
-*/
-
-/** A bitmask, used in the recursion. These parameters are introduced
- * to break symmetry of SIMD.
-#define MSK1 0xdfffffefU
-#define MSK2 0xddfecb7fU
-#define MSK3 0xbffaffffU
-#define MSK4 0xbffffff6U
-*/
-
-/** These definitions are part of a 128-bit period certification vector.
-#define PARITY1 0x00000001U
-#define PARITY2 0x00000000U
-#define PARITY3 0x00000000U
-#define PARITY4 0xc98e126aU
-*/
-
-#if MEXP == 607
- #include "SFMT-params607.h"
-#elif MEXP == 1279
- #include "SFMT-params1279.h"
-#elif MEXP == 2281
- #include "SFMT-params2281.h"
-#elif MEXP == 4253
- #include "SFMT-params4253.h"
-#elif MEXP == 11213
- #include "SFMT-params11213.h"
-#elif MEXP == 19937
- #include "SFMT-params19937.h"
-#elif MEXP == 44497
- #include "SFMT-params44497.h"
-#elif MEXP == 86243
- #include "SFMT-params86243.h"
-#elif MEXP == 132049
- #include "SFMT-params132049.h"
-#elif MEXP == 216091
- #include "SFMT-params216091.h"
-#else
-#ifdef __GNUC__
- #error "MEXP is not valid."
- #undef MEXP
-#else
- #undef MEXP
-#endif
-
-#endif
-
-#endif /* SFMT_PARAMS_H */
diff --git a/sms/SFMT/SFMT-params11213.h b/sms/SFMT/SFMT-params11213.h
deleted file mode 100644
index 244d313..0000000
--- a/sms/SFMT/SFMT-params11213.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef SFMT_PARAMS11213_H
-#define SFMT_PARAMS11213_H
-
-#define POS1 68
-#define SL1 14
-#define SL2 3
-#define SR1 7
-#define SR2 3
-#define MSK1 0xeffff7fbU
-#define MSK2 0xffffffefU
-#define MSK3 0xdfdfbfffU
-#define MSK4 0x7fffdbfdU
-#define PARITY1 0x00000001U
-#define PARITY2 0x00000000U
-#define PARITY3 0xe8148000U
-#define PARITY4 0xd0c7afa3U
-
-
-/* PARAMETERS FOR ALTIVEC */
-#if defined(__APPLE__) /* For OSX */
- #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
- #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
- #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
- #define ALTI_MSK64 \
- (vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
- #define ALTI_SL2_PERM \
- (vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
- #define ALTI_SL2_PERM64 \
- (vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
- #define ALTI_SR2_PERM \
- (vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)
- #define ALTI_SR2_PERM64 \
- (vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)
-#else /* For OTHER OSs(Linux?) */
- #define ALTI_SL1 {SL1, SL1, SL1, SL1}
- #define ALTI_SR1 {SR1, SR1, SR1, SR1}
- #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
- #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
- #define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
- #define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
- #define ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}
- #define ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}
-#endif /* For OSX */
-#define IDSTR "SFMT-11213:68-14-3-7-3:effff7fb-ffffffef-dfdfbfff-7fffdbfd"
-
-#endif /* SFMT_PARAMS11213_H */
diff --git a/sms/SFMT/SFMT-params1279.h b/sms/SFMT/SFMT-params1279.h
deleted file mode 100644
index df538df..0000000
--- a/sms/SFMT/SFMT-params1279.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef SFMT_PARAMS1279_H
-#define SFMT_PARAMS1279_H
-
-#define POS1 7
-#define SL1 14
-#define SL2 3
-#define SR1 5
-#define SR2 1
-#define MSK1 0xf7fefffdU
-#define MSK2 0x7fefcfffU
-#define MSK3 0xaff3ef3fU
-#define MSK4 0xb5ffff7fU
-#define PARITY1 0x00000001U
-#define PARITY2 0x00000000U
-#define PARITY3 0x00000000U
-#define PARITY4 0x20000000U
-
-
-/* PARAMETERS FOR ALTIVEC */
-#if defined(__APPLE__) /* For OSX */
- #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
- #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
- #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
- #define ALTI_MSK64 \
- (vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
- #define ALTI_SL2_PERM \
- (vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
- #define ALTI_SL2_PERM64 \
- (vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
- #define ALTI_SR2_PERM \
- (vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
- #define ALTI_SR2_PERM64 \
- (vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
-#else /* For OTHER OSs(Linux?) */
- #define ALTI_SL1 {SL1, SL1, SL1, SL1}
- #define ALTI_SR1 {SR1, SR1, SR1, SR1}
- #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
- #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
- #define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
- #define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
- #define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
- #define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
-#endif /* For OSX */
-#define IDSTR "SFMT-1279:7-14-3-5-1:f7fefffd-7fefcfff-aff3ef3f-b5ffff7f"
-
-#endif /* SFMT_PARAMS1279_H */
diff --git a/sms/SFMT/SFMT-params132049.h b/sms/SFMT/SFMT-params132049.h
deleted file mode 100644
index 94e297e..0000000
--- a/sms/SFMT/SFMT-params132049.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef SFMT_PARAMS132049_H
-#define SFMT_PARAMS132049_H
-
-#define POS1 110
-#define SL1 19
-#define SL2 1
-#define SR1 21
-#define SR2 1
-#define MSK1 0xffffbb5fU
-#define MSK2 0xfb6ebf95U
-#define MSK3 0xfffefffaU
-#define MSK4 0xcff77fffU
-#define PARITY1 0x00000001U
-#define PARITY2 0x00000000U
-#define PARITY3 0xcb520000U
-#define PARITY4 0xc7e91c7dU
-
-
-/* PARAMETERS FOR ALTIVEC */
-#if defined(__APPLE__) /* For OSX */
- #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
- #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
- #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
- #define ALTI_MSK64 \
- (vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
- #define ALTI_SL2_PERM \
- (vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
- #define ALTI_SL2_PERM64 \
- (vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
- #define ALTI_SR2_PERM \
- (vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
- #define ALTI_SR2_PERM64 \
- (vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
-#else /* For OTHER OSs(Linux?) */
- #define ALTI_SL1 {SL1, SL1, SL1, SL1}
- #define ALTI_SR1 {SR1, SR1, SR1, SR1}
- #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
- #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
- #define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
- #define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
- #define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
- #define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
-#endif /* For OSX */
-#define IDSTR "SFMT-132049:110-19-1-21-1:ffffbb5f-fb6ebf95-fffefffa-cff77fff"
-
-#endif /* SFMT_PARAMS132049_H */
diff --git a/sms/SFMT/SFMT-params19937.h b/sms/SFMT/SFMT-params19937.h
deleted file mode 100644
index 04708cd..0000000
--- a/sms/SFMT/SFMT-params19937.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef SFMT_PARAMS19937_H
-#define SFMT_PARAMS19937_H
-
-#define POS1 122
-#define SL1 18
-#define SL2 1
-#define SR1 11
-#define SR2 1
-#define MSK1 0xdfffffefU
-#define MSK2 0xddfecb7fU
-#define MSK3 0xbffaffffU
-#define MSK4 0xbffffff6U
-#define PARITY1 0x00000001U
-#define PARITY2 0x00000000U
-#define PARITY3 0x00000000U
-#define PARITY4 0x13c9e684U
-
-
-/* PARAMETERS FOR ALTIVEC */
-#if defined(__APPLE__) /* For OSX */
- #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
- #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
- #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
- #define ALTI_MSK64 \
- (vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
- #define ALTI_SL2_PERM \
- (vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
- #define ALTI_SL2_PERM64 \
- (vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
- #define ALTI_SR2_PERM \
- (vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
- #define ALTI_SR2_PERM64 \
- (vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
-#else /* For OTHER OSs(Linux?) */
- #define ALTI_SL1 {SL1, SL1, SL1, SL1}
- #define ALTI_SR1 {SR1, SR1, SR1, SR1}
- #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
- #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
- #define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
- #define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
- #define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
- #define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
-#endif /* For OSX */
-#define IDSTR "SFMT-19937:122-18-1-11-1:dfffffef-ddfecb7f-bffaffff-bffffff6"
-
-#endif /* SFMT_PARAMS19937_H */
diff --git a/sms/SFMT/SFMT-params216091.h b/sms/SFMT/SFMT-params216091.h
deleted file mode 100644
index 46c7303..0000000
--- a/sms/SFMT/SFMT-params216091.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef SFMT_PARAMS216091_H
-#define SFMT_PARAMS216091_H
-
-#define POS1 627
-#define SL1 11
-#define SL2 3
-#define SR1 10
-#define SR2 1
-#define MSK1 0xbff7bff7U
-#define MSK2 0xbfffffffU
-#define MSK3 0xbffffa7fU
-#define MSK4 0xffddfbfbU
-#define PARITY1 0xf8000001U
-#define PARITY2 0x89e80709U
-#define PARITY3 0x3bd2b64bU
-#define PARITY4 0x0c64b1e4U
-
-
-/* PARAMETERS FOR ALTIVEC */
-#if defined(__APPLE__) /* For OSX */
- #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
- #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
- #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
- #define ALTI_MSK64 \
- (vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
- #define ALTI_SL2_PERM \
- (vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
- #define ALTI_SL2_PERM64 \
- (vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
- #define ALTI_SR2_PERM \
- (vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
- #define ALTI_SR2_PERM64 \
- (vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
-#else /* For OTHER OSs(Linux?) */
- #define ALTI_SL1 {SL1, SL1, SL1, SL1}
- #define ALTI_SR1 {SR1, SR1, SR1, SR1}
- #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
- #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
- #define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
- #define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
- #define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
- #define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
-#endif /* For OSX */
-#define IDSTR "SFMT-216091:627-11-3-10-1:bff7bff7-bfffffff-bffffa7f-ffddfbfb"
-
-#endif /* SFMT_PARAMS216091_H */
diff --git a/sms/SFMT/SFMT-params2281.h b/sms/SFMT/SFMT-params2281.h
deleted file mode 100644
index ee2ebdf..0000000
--- a/sms/SFMT/SFMT-params2281.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef SFMT_PARAMS2281_H
-#define SFMT_PARAMS2281_H
-
-#define POS1 12
-#define SL1 19
-#define SL2 1
-#define SR1 5
-#define SR2 1
-#define MSK1 0xbff7ffbfU
-#define MSK2 0xfdfffffeU
-#define MSK3 0xf7ffef7fU
-#define MSK4 0xf2f7cbbfU
-#define PARITY1 0x00000001U
-#define PARITY2 0x00000000U
-#define PARITY3 0x00000000U
-#define PARITY4 0x41dfa600U
-
-
-/* PARAMETERS FOR ALTIVEC */
-#if defined(__APPLE__) /* For OSX */
- #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
- #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
- #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
- #define ALTI_MSK64 \
- (vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
- #define ALTI_SL2_PERM \
- (vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
- #define ALTI_SL2_PERM64 \
- (vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
- #define ALTI_SR2_PERM \
- (vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
- #define ALTI_SR2_PERM64 \
- (vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
-#else /* For OTHER OSs(Linux?) */
- #define ALTI_SL1 {SL1, SL1, SL1, SL1}
- #define ALTI_SR1 {SR1, SR1, SR1, SR1}
- #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
- #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
- #define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
- #define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
- #define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
- #define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
-#endif /* For OSX */
-#define IDSTR "SFMT-2281:12-19-1-5-1:bff7ffbf-fdfffffe-f7ffef7f-f2f7cbbf"
-
-#endif /* SFMT_PARAMS2281_H */
diff --git a/sms/SFMT/SFMT-params4253.h b/sms/SFMT/SFMT-params4253.h
deleted file mode 100644
index f391a70..0000000
--- a/sms/SFMT/SFMT-params4253.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef SFMT_PARAMS4253_H
-#define SFMT_PARAMS4253_H
-
-#define POS1 17
-#define SL1 20
-#define SL2 1
-#define SR1 7
-#define SR2 1
-#define MSK1 0x9f7bffffU
-#define MSK2 0x9fffff5fU
-#define MSK3 0x3efffffbU
-#define MSK4 0xfffff7bbU
-#define PARITY1 0xa8000001U
-#define PARITY2 0xaf5390a3U
-#define PARITY3 0xb740b3f8U
-#define PARITY4 0x6c11486dU
-
-
-/* PARAMETERS FOR ALTIVEC */
-#if defined(__APPLE__) /* For OSX */
- #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
- #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
- #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
- #define ALTI_MSK64 \
- (vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
- #define ALTI_SL2_PERM \
- (vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
- #define ALTI_SL2_PERM64 \
- (vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
- #define ALTI_SR2_PERM \
- (vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
- #define ALTI_SR2_PERM64 \
- (vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
-#else /* For OTHER OSs(Linux?) */
- #define ALTI_SL1 {SL1, SL1, SL1, SL1}
- #define ALTI_SR1 {SR1, SR1, SR1, SR1}
- #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
- #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
- #define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
- #define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
- #define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
- #define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
-#endif /* For OSX */
-#define IDSTR "SFMT-4253:17-20-1-7-1:9f7bffff-9fffff5f-3efffffb-fffff7bb"
-
-#endif /* SFMT_PARAMS4253_H */
diff --git a/sms/SFMT/SFMT-params44497.h b/sms/SFMT/SFMT-params44497.h
deleted file mode 100644
index ddef00d..0000000
--- a/sms/SFMT/SFMT-params44497.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef SFMT_PARAMS44497_H
-#define SFMT_PARAMS44497_H
-
-#define POS1 330
-#define SL1 5
-#define SL2 3
-#define SR1 9
-#define SR2 3
-#define MSK1 0xeffffffbU
-#define MSK2 0xdfbebfffU
-#define MSK3 0xbfbf7befU
-#define MSK4 0x9ffd7bffU
-#define PARITY1 0x00000001U
-#define PARITY2 0x00000000U
-#define PARITY3 0xa3ac4000U
-#define PARITY4 0xecc1327aU
-
-
-/* PARAMETERS FOR ALTIVEC */
-#if defined(__APPLE__) /* For OSX */
- #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
- #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
- #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
- #define ALTI_MSK64 \
- (vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
- #define ALTI_SL2_PERM \
- (vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
- #define ALTI_SL2_PERM64 \
- (vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
- #define ALTI_SR2_PERM \
- (vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)
- #define ALTI_SR2_PERM64 \
- (vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)
-#else /* For OTHER OSs(Linux?) */
- #define ALTI_SL1 {SL1, SL1, SL1, SL1}
- #define ALTI_SR1 {SR1, SR1, SR1, SR1}
- #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
- #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
- #define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
- #define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
- #define ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}
- #define ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}
-#endif /* For OSX */
-#define IDSTR "SFMT-44497:330-5-3-9-3:effffffb-dfbebfff-bfbf7bef-9ffd7bff"
-
-#endif /* SFMT_PARAMS44497_H */
diff --git a/sms/SFMT/SFMT-params607.h b/sms/SFMT/SFMT-params607.h
deleted file mode 100644
index fc2be6d..0000000
--- a/sms/SFMT/SFMT-params607.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef SFMT_PARAMS607_H
-#define SFMT_PARAMS607_H
-
-#define POS1 2
-#define SL1 15
-#define SL2 3
-#define SR1 13
-#define SR2 3
-#define MSK1 0xfdff37ffU
-#define MSK2 0xef7f3f7dU
-#define MSK3 0xff777b7dU
-#define MSK4 0x7ff7fb2fU
-#define PARITY1 0x00000001U
-#define PARITY2 0x00000000U
-#define PARITY3 0x00000000U
-#define PARITY4 0x5986f054U
-
-
-/* PARAMETERS FOR ALTIVEC */
-#if defined(__APPLE__) /* For OSX */
- #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
- #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
- #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
- #define ALTI_MSK64 \
- (vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
- #define ALTI_SL2_PERM \
- (vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
- #define ALTI_SL2_PERM64 \
- (vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
- #define ALTI_SR2_PERM \
- (vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)
- #define ALTI_SR2_PERM64 \
- (vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)
-#else /* For OTHER OSs(Linux?) */
- #define ALTI_SL1 {SL1, SL1, SL1, SL1}
- #define ALTI_SR1 {SR1, SR1, SR1, SR1}
- #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
- #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
- #define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
- #define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
- #define ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}
- #define ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}
-#endif /* For OSX */
-#define IDSTR "SFMT-607:2-15-3-13-3:fdff37ff-ef7f3f7d-ff777b7d-7ff7fb2f"
-
-#endif /* SFMT_PARAMS607_H */
diff --git a/sms/SFMT/SFMT-params86243.h b/sms/SFMT/SFMT-params86243.h
deleted file mode 100644
index 3b52b76..0000000
--- a/sms/SFMT/SFMT-params86243.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef SFMT_PARAMS86243_H
-#define SFMT_PARAMS86243_H
-
-#define POS1 366
-#define SL1 6
-#define SL2 7
-#define SR1 19
-#define SR2 1
-#define MSK1 0xfdbffbffU
-#define MSK2 0xbff7ff3fU
-#define MSK3 0xfd77efffU
-#define MSK4 0xbf9ff3ffU
-#define PARITY1 0x00000001U
-#define PARITY2 0x00000000U
-#define PARITY3 0x00000000U
-#define PARITY4 0xe9528d85U
-
-
-/* PARAMETERS FOR ALTIVEC */
-#if defined(__APPLE__) /* For OSX */
- #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
- #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
- #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
- #define ALTI_MSK64 \
- (vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
- #define ALTI_SL2_PERM \
- (vector unsigned char)(25,25,25,25,3,25,25,25,7,0,1,2,11,4,5,6)
- #define ALTI_SL2_PERM64 \
- (vector unsigned char)(7,25,25,25,25,25,25,25,15,0,1,2,3,4,5,6)
- #define ALTI_SR2_PERM \
- (vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
- #define ALTI_SR2_PERM64 \
- (vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
-#else /* For OTHER OSs(Linux?) */
- #define ALTI_SL1 {SL1, SL1, SL1, SL1}
- #define ALTI_SR1 {SR1, SR1, SR1, SR1}
- #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
- #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
- #define ALTI_SL2_PERM {25,25,25,25,3,25,25,25,7,0,1,2,11,4,5,6}
- #define ALTI_SL2_PERM64 {7,25,25,25,25,25,25,25,15,0,1,2,3,4,5,6}
- #define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
- #define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
-#endif /* For OSX */
-#define IDSTR "SFMT-86243:366-6-7-19-1:fdbffbff-bff7ff3f-fd77efff-bf9ff3ff"
-
-#endif /* SFMT_PARAMS86243_H */
diff --git a/sms/analysis.c b/sms/analysis.c
deleted file mode 100644
index 89d4b4a..0000000
--- a/sms/analysis.c
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG)
- * UNIVERSITAT POMPEU FABRA
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*! \file analysis.c
- * \brief main sms analysis routines
- *
- * the analysis routine here calls all necessary functions to perform the complete
- * SMS analysis, once the desired analysis parameters are set in SMS_AnalParams.
- */
-
-#include "sms.h"
-
-/*! \brief maximum size for magnitude spectrum */
-#define SMS_MAX_SPEC 8192
-
-/*! \brief compute spectrum, find peaks, and fundamental of one frame
- *
- * This is the main core of analysis calls
- *
- * \param iCurrentFrame frame number to be computed
- * \param pAnalParams structure of analysis parameters
- * \param fRefFundamental reference fundamental
- */
-void sms_analyzeFrame(int iCurrentFrame, SMS_AnalParams *pAnalParams, sfloat fRefFundamental)
-{
- int i, iFrame;
- SMS_AnalFrame *pCurrentFrame = pAnalParams->ppFrames[iCurrentFrame];
- int iSoundLoc = pCurrentFrame->iFrameSample -((pCurrentFrame->iFrameSize + 1) >> 1) + 1;
- sfloat *pFData = &(pAnalParams->soundBuffer.pFBuffer[iSoundLoc - pAnalParams->soundBuffer.iMarker]);
-
- /* TODO: this doesn't have to be done every time */
- int sizeWindow = pCurrentFrame->iFrameSize;
- int sizeMag = sms_power2(sizeWindow);
- sms_getWindow(sizeWindow, pAnalParams->spectrumWindow, pAnalParams->iWindowType);
- sms_scaleWindow(sizeWindow, pAnalParams->spectrumWindow);
-
- /* compute the magnitude and (zero-windowed) phase spectra */
- sms_spectrum(sizeWindow, pFData, pAnalParams->spectrumWindow, sizeMag,
- pAnalParams->magSpectrum, pAnalParams->phaseSpectrum,
- pAnalParams->fftBuffer);
-
- /* convert magnitude spectra to dB */
- sms_arrayMagToDB(sizeMag, pAnalParams->magSpectrum);
-
- /* find the prominent peaks */
- pCurrentFrame->nPeaks = sms_detectPeaks(sizeMag,
- pAnalParams->magSpectrum,
- pAnalParams->phaseSpectrum,
- pCurrentFrame->pSpectralPeaks,
- pAnalParams);
-
- /* find a reference harmonic */
- if(pCurrentFrame->nPeaks > 0 &&
- (pAnalParams->iFormat == SMS_FORMAT_H || pAnalParams->iFormat == SMS_FORMAT_HP))
- pCurrentFrame->fFundamental = sms_harmDetection(pAnalParams->maxPeaks, pCurrentFrame->pSpectralPeaks,
- fRefFundamental, pAnalParams->iRefHarmonic,
- pAnalParams->fLowestFundamental, pAnalParams->fHighestFundamental,
- pAnalParams->iSoundType, pAnalParams->fMinRefHarmMag,
- pAnalParams->fRefHarmMagDiffFromMax);
-}
-
-/*! \brief re-analyze the previous frames if necessary
- *
- * \todo explain when this is necessary
- *
- * \param iCurrentFrame current frame number
- * \param pAnalParams structure with analysis parameters
- * \return 1 if frames are good, -1 if analysis is necessary
- * \todo is the return value info correct? Why isn't it used in sms_analyze?
- */
-static int ReAnalyzeFrame(int iCurrentFrame, SMS_AnalParams *pAnalParams)
-{
- sfloat fFund, fLastFund, fDev;
- int iNewFrameSize, i;
- sfloat fAvgDeviation = sms_fundDeviation(pAnalParams, iCurrentFrame);
- int iFirstFrame = iCurrentFrame - pAnalParams->minGoodFrames;
-
- /*! \todo make this a < 0 check, but first make sure sms_fundDeviation does not
- return values below zero */
- if(fAvgDeviation == -1)
- return -1;
-
- /* if the last SMS_MIN_GOOD_FRAMES are stable look before them */
- /* and recompute the frames that are not stable */
- if (fAvgDeviation <= pAnalParams->maxDeviation)
- {
- for(i = 0; i < pAnalParams->analDelay; i++)
- {
- if(pAnalParams->ppFrames[iFirstFrame - i]->iFrameNum <= 0 ||
- pAnalParams->ppFrames[iFirstFrame - i]->iStatus == SMS_FRAME_RECOMPUTED)
- return -1;
- fFund = pAnalParams->ppFrames[iFirstFrame - i]->fFundamental;
- fLastFund = pAnalParams->ppFrames[iFirstFrame - i + 1]->fFundamental;
- fDev = fabs (fFund - fLastFund) / fLastFund;
- iNewFrameSize = ((pAnalParams->iSamplingRate / fLastFund) *
- pAnalParams->fSizeWindow/2) * 2 + 1;
-
- if(fFund <= 0 || fDev > .2 ||
- fabs((double)(pAnalParams->ppFrames[iFirstFrame - i]->iFrameSize -
- iNewFrameSize)) / iNewFrameSize >= .2)
- {
- pAnalParams->ppFrames[iFirstFrame - i]->iFrameSize = iNewFrameSize;
- pAnalParams->ppFrames[iFirstFrame - i]->iStatus = SMS_FRAME_READY;
-
- /* recompute frame */
- sms_analyzeFrame(iFirstFrame - i, pAnalParams, fLastFund);
- pAnalParams->ppFrames[iFirstFrame - i]->iStatus = SMS_FRAME_RECOMPUTED;
-
- if(fabs(pAnalParams->ppFrames[iFirstFrame - i]->fFundamental - fLastFund) /
- fLastFund >= .2)
- return -1;
- }
- }
- }
- return 1;
-}
-
-int sms_findPeaks(int sizeWaveform, sfloat *pWaveform, SMS_AnalParams *pAnalParams, SMS_SpectralPeaks *pSpectralPeaks)
-{
- int iCurrentFrame = pAnalParams->iMaxDelayFrames - 1; /* frame # of current frame */
- sfloat fRefFundamental = 0; /* reference fundamental for current frame */
- int i, iError, iExtraSamples; /* samples used for next analysis frame */
- SMS_AnalFrame *pTmpAnalFrame;
-
- /* set initial analysis-window size */
- if(pAnalParams->windowSize == 0)
- pAnalParams->windowSize = pAnalParams->iDefaultSizeWindow;
-
- /* fill sound buffer and perform pre-emphasis */
- if(sizeWaveform > 0)
- sms_fillSoundBuffer(sizeWaveform, pWaveform, pAnalParams);
-
- /* move analysis data one frame back */
- pTmpAnalFrame = pAnalParams->ppFrames[0];
- for(i = 1; i < pAnalParams->iMaxDelayFrames; i++)
- pAnalParams->ppFrames[i-1] = pAnalParams->ppFrames[i];
- pAnalParams->ppFrames[pAnalParams->iMaxDelayFrames-1] = pTmpAnalFrame;
-
- /* initialize the current frame */
- sms_initFrame(iCurrentFrame, pAnalParams, pAnalParams->windowSize);
-
- if(pAnalParams->ppFrames[iCurrentFrame]->iStatus == SMS_FRAME_READY)
- {
- sfloat fAvgDev = sms_fundDeviation(pAnalParams, iCurrentFrame - 1);
-
- /* if single note use the default fundamental as reference */
- if(pAnalParams->iSoundType == SMS_SOUND_TYPE_NOTE)
- fRefFundamental = pAnalParams->fDefaultFundamental;
- /* if sound is stable use the last fundamental as a reference */
- else if(fAvgDev != -1 && fAvgDev <= pAnalParams->maxDeviation)
- fRefFundamental = pAnalParams->ppFrames[iCurrentFrame - 1]->fFundamental;
- else
- fRefFundamental = 0;
-
- /* compute spectrum, find peaks, and find fundamental of frame */
- sms_analyzeFrame(iCurrentFrame, pAnalParams, fRefFundamental);
-
- /* set the size of the next analysis window */
- if(pAnalParams->ppFrames[iCurrentFrame]->fFundamental > 0 &&
- pAnalParams->iSoundType != SMS_SOUND_TYPE_NOTE)
- pAnalParams->windowSize = sms_sizeNextWindow(iCurrentFrame, pAnalParams);
-
- /* figure out how much needs to be read next time
- * how many processed - sample no. of end of next frame
- * = no. samples that we haven't processed yet from whenever, if sizeNextRead was 0
- */
- iExtraSamples = (pAnalParams->soundBuffer.iMarker + pAnalParams->soundBuffer.sizeBuffer) -
- (pAnalParams->ppFrames[iCurrentFrame]->iFrameSample + pAnalParams->sizeHop);
-
- pAnalParams->sizeNextRead = MAX(0, (pAnalParams->windowSize+1)/2 - iExtraSamples);
- ReAnalyzeFrame(iCurrentFrame, pAnalParams);
-
- /* save peaks */
- pSpectralPeaks->nPeaksFound = pAnalParams->ppFrames[iCurrentFrame]->nPeaks;
- pSpectralPeaks->nPeaks = pAnalParams->maxPeaks;
-
- for(i = 0; i < pSpectralPeaks->nPeaks; i++)
- {
- if(i < pSpectralPeaks->nPeaksFound)
- {
- pSpectralPeaks->pSpectralPeaks[i].fMag =
- sms_dBToMag(pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks[i].fMag);
- pSpectralPeaks->pSpectralPeaks[i].fFreq =
- pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks[i].fFreq;
- pSpectralPeaks->pSpectralPeaks[i].fPhase =
- pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks[i].fPhase;
- }
- else
- {
- pSpectralPeaks->pSpectralPeaks[i].fMag = 0.0;
- pSpectralPeaks->pSpectralPeaks[i].fFreq = 0.0;
- pSpectralPeaks->pSpectralPeaks[i].fPhase = 0.0;
- }
- }
- return pSpectralPeaks->nPeaks;
- }
- else
- {
- return 0;
- }
-}
-
-void sms_setPeaks(SMS_AnalParams *pAnalParams, int numamps, sfloat* amps,
- int numfreqs, sfloat* freqs, int numphases, sfloat* phases)
-{
- int i;
- SMS_AnalFrame *tempFrame;
- int currentFrame = pAnalParams->iMaxDelayFrames - 1; /* frame # of current frame */
-
- /* move analysis data one frame back */
- tempFrame = pAnalParams->ppFrames[0];
- for(i = 1; i < pAnalParams->iMaxDelayFrames; i++)
- pAnalParams->ppFrames[i-1] = pAnalParams->ppFrames[i];
- pAnalParams->ppFrames[pAnalParams->iMaxDelayFrames-1] = tempFrame;
-
- /* initialize the current frame */
- SMS_AnalFrame *frame = pAnalParams->ppFrames[currentFrame];
- sms_initFrame(currentFrame, pAnalParams, 0);
- if(sms_errorCheck())
- {
- printf("Error in init frame: %s \n", sms_errorString());
- return;
- }
-
- for(i = 0; i < numamps; i++)
- {
- /* copy current peaks data */
- frame->pSpectralPeaks[i].fMag = sms_magToDB(amps[i]);
- frame->pSpectralPeaks[i].fFreq = freqs[i];
- frame->pSpectralPeaks[i].fPhase = phases[i];
- }
- frame->nPeaks = numamps;
- frame->iStatus = SMS_FRAME_READY;
-
- /* harmonic detection */
- if(frame->nPeaks > 0 &&
- (pAnalParams->iFormat == SMS_FORMAT_H || pAnalParams->iFormat == SMS_FORMAT_HP))
- {
- /* get a reference fundamental */
- sfloat refFundamental = 0;
- sfloat avgDeviation = sms_fundDeviation(pAnalParams, currentFrame-1);
- if(pAnalParams->iSoundType == SMS_SOUND_TYPE_NOTE)
- refFundamental = pAnalParams->fDefaultFundamental;
- /* if sound is stable use the last fundamental as a reference */
- else if(avgDeviation != -1 && avgDeviation <= pAnalParams->maxDeviation)
- refFundamental = pAnalParams->ppFrames[currentFrame-1]->fFundamental;
- else
- refFundamental = 0;
-
- frame->fFundamental = sms_harmDetection(frame->nPeaks, frame->pSpectralPeaks,
- refFundamental, pAnalParams->iRefHarmonic,
- pAnalParams->fLowestFundamental, pAnalParams->fHighestFundamental,
- pAnalParams->iSoundType, pAnalParams->fMinRefHarmMag,
- pAnalParams->fRefHarmMagDiffFromMax);
- }
-}
-
-int sms_findPartials(SMS_Data *pSmsData, SMS_AnalParams *pAnalParams)
-{
- int currentFrame = pAnalParams->iMaxDelayFrames - 1;
-
- /* set the frame delay, checking that it does not exceed the given maximum
- *
- * TODO: check for good values of pAnalParams->minGoodFrames and
- * pAnalParams->analDelay here too? Or figure out why sms_crashes if
- * pAnalParamx->iMaxDelayFrames is changed without changing the other
- * two variables.
- */
- int delayFrames = pAnalParams->minGoodFrames + pAnalParams->analDelay;
- if(delayFrames > (pAnalParams->iMaxDelayFrames - 1))
- delayFrames = pAnalParams->iMaxDelayFrames - 1;
-
- /* clear SMS output */
- sms_clearFrame(pSmsData);
-
- /* incorporate the peaks into the corresponding tracks */
- if(pAnalParams->ppFrames[currentFrame-delayFrames]->fFundamental > 0 ||
- ((pAnalParams->iFormat == SMS_FORMAT_IH || pAnalParams->iFormat == SMS_FORMAT_IHP) &&
- pAnalParams->ppFrames[currentFrame-delayFrames]->nPeaks > 0))
- {
- sms_peakContinuation(currentFrame-delayFrames, pAnalParams);
- }
-
- /* fill gaps and delete short tracks */
- if(pAnalParams->iCleanTracks > 0)
- {
- sms_cleanTracks(currentFrame-delayFrames, pAnalParams);
- }
-
- /* output data */
- int length = sizeof(sfloat) * pSmsData->nTracks;
- memcpy((char *) pSmsData->pFSinFreq, (char *)
- pAnalParams->ppFrames[0]->deterministic.pFSinFreq, length);
- memcpy((char *) pSmsData->pFSinAmp, (char *)
- pAnalParams->ppFrames[0]->deterministic.pFSinAmp, length);
-
- /* convert mags back to linear */
- sms_arrayDBToMag(pSmsData->nTracks, pSmsData->pFSinAmp);
-
- if(pAnalParams->iFormat == SMS_FORMAT_HP ||
- pAnalParams->iFormat == SMS_FORMAT_IHP)
- memcpy((char *) pSmsData->pFSinPha, (char *)
- pAnalParams->ppFrames[0]->deterministic.pFSinPha, length);
-
- return 1;
-}
-
-int sms_findResidual(int sizeSynthesis, sfloat* pSynthesis,
- int sizeOriginal, sfloat* pOriginal,
- SMS_ResidualParams *residualParams)
-{
- if(residualParams->hopSize < sizeOriginal)
- {
- sms_error("Residual signal length is smaller than the original signal length");
- return -1;
- }
-
- sms_residual(residualParams->hopSize, pSynthesis, pOriginal, residualParams);
- sms_filterHighPass(residualParams->hopSize,
- residualParams->residual,
- residualParams->samplingRate);
- return 0;
-}
-
-int sms_analyze(int sizeWaveform, sfloat *pWaveform, SMS_Data *pSmsData, SMS_AnalParams *pAnalParams)
-{
- int iCurrentFrame = pAnalParams->iMaxDelayFrames - 1; /* frame # of current frame */
- int i, iError, iExtraSamples; /* samples used for next analysis frame */
- sfloat fRefFundamental = 0; /* reference fundamental for current frame */
- SMS_AnalFrame *pTmpAnalFrame;
-
- /* set the frame delay, checking that it does not exceed the given maximum
- *
- * TODO: check for good values of pAnalParams->minGoodFrames and
- * pAnalParams->analDelay here too? Or figure out why sms_crashes if
- * pAnalParamx->iMaxDelayFrames is changed without changing the other
- * two variables.
- */
- int delayFrames = pAnalParams->minGoodFrames + pAnalParams->analDelay;
- if(delayFrames > (pAnalParams->iMaxDelayFrames - 1))
- delayFrames = pAnalParams->iMaxDelayFrames - 1;
-
- /* clear SMS output */
- sms_clearFrame(pSmsData);
-
- /* set initial analysis-window size */
- if(pAnalParams->windowSize == 0)
- pAnalParams->windowSize = pAnalParams->iDefaultSizeWindow;
-
- /* fill the input sound buffer and perform pre-emphasis */
- if(sizeWaveform > 0)
- sms_fillSoundBuffer(sizeWaveform, pWaveform, pAnalParams);
-
- /* move analysis data one frame back */
- pTmpAnalFrame = pAnalParams->ppFrames[0];
- for(i = 1; i < pAnalParams->iMaxDelayFrames; i++)
- pAnalParams->ppFrames[i-1] = pAnalParams->ppFrames[i];
- pAnalParams->ppFrames[pAnalParams->iMaxDelayFrames-1] = pTmpAnalFrame;
-
- /* initialize the current frame */
- sms_initFrame(iCurrentFrame, pAnalParams, pAnalParams->windowSize);
- if(sms_errorCheck())
- {
- printf("error in init frame: %s \n", sms_errorString());
- return -1;
- }
-
- /* if right data in the sound buffer do analysis */
- if(pAnalParams->ppFrames[iCurrentFrame]->iStatus == SMS_FRAME_READY)
- {
- sfloat fAvgDev = sms_fundDeviation(pAnalParams, iCurrentFrame - 1);
-
- /* if single note use the default fundamental as reference */
- if(pAnalParams->iSoundType == SMS_SOUND_TYPE_NOTE)
- fRefFundamental = pAnalParams->fDefaultFundamental;
- /* if sound is stable use the last fundamental as a reference */
- else if(fAvgDev != -1 && fAvgDev <= pAnalParams->maxDeviation)
- fRefFundamental = pAnalParams->ppFrames[iCurrentFrame - 1]->fFundamental;
- else
- fRefFundamental = 0;
-
- /* compute spectrum, find peaks, and find fundamental of frame */
- sms_analyzeFrame(iCurrentFrame, pAnalParams, fRefFundamental);
-
- /* set the size of the next analysis window */
- if(pAnalParams->ppFrames[iCurrentFrame]->fFundamental > 0 &&
- pAnalParams->iSoundType != SMS_SOUND_TYPE_NOTE)
- pAnalParams->windowSize = sms_sizeNextWindow (iCurrentFrame, pAnalParams);
-
- /* figure out how much needs to be read next time */
- iExtraSamples =
- (pAnalParams->soundBuffer.iMarker + pAnalParams->soundBuffer.sizeBuffer) -
- (pAnalParams->ppFrames[iCurrentFrame]->iFrameSample + pAnalParams->sizeHop);
-
- pAnalParams->sizeNextRead = MAX(0, (pAnalParams->windowSize+1)/2 - iExtraSamples);
-
- /* check again the previous frames and recompute if necessary */
- ReAnalyzeFrame(iCurrentFrame, pAnalParams);
- }
-
- /* incorporate the peaks into the corresponding tracks */
- /* This is done after a pAnalParams->iMaxDelayFrames delay */
- if(pAnalParams->ppFrames[iCurrentFrame - delayFrames]->fFundamental > 0 ||
- ((pAnalParams->iFormat == SMS_FORMAT_IH || pAnalParams->iFormat == SMS_FORMAT_IHP) &&
- pAnalParams->ppFrames[iCurrentFrame - delayFrames]->nPeaks > 0))
- sms_peakContinuation(iCurrentFrame - delayFrames, pAnalParams);
-
- /* fill gaps and delete short tracks */
- if(pAnalParams->iCleanTracks > 0 &&
- pAnalParams->ppFrames[iCurrentFrame - delayFrames]->iStatus != SMS_FRAME_EMPTY)
- sms_cleanTracks(iCurrentFrame - delayFrames, pAnalParams);
-
- /* do stochastic analysis */
- if(pAnalParams->iStochasticType != SMS_STOC_NONE)
- {
- /* synthesize deterministic signal */
- if(pAnalParams->ppFrames[1]->iStatus != SMS_FRAME_EMPTY &&
- pAnalParams->ppFrames[1]->iStatus != SMS_FRAME_END)
- {
- /* shift synthesis buffer */
- memcpy(pAnalParams->synthBuffer.pFBuffer,
- pAnalParams->synthBuffer.pFBuffer+pAnalParams->sizeHop,
- sizeof(sfloat) * pAnalParams->sizeHop);
- memset(pAnalParams->synthBuffer.pFBuffer+pAnalParams->sizeHop,
- 0, sizeof(sfloat) * pAnalParams->sizeHop);
-
- /* get deterministic signal with phase */
- sms_sineSynthFrame(&pAnalParams->ppFrames[1]->deterministic,
- pAnalParams->synthBuffer.pFBuffer+pAnalParams->sizeHop,
- pAnalParams->sizeHop, &pAnalParams->prevFrame,
- pAnalParams->iSamplingRate);
- }
-
- /* perform stochastic analysis after 1 frame of the */
- /* deterministic synthesis because it needs two frames */
- if(pAnalParams->ppFrames[0]->iStatus != SMS_FRAME_EMPTY &&
- pAnalParams->ppFrames[0]->iStatus != SMS_FRAME_END)
- {
- int iSoundLoc = pAnalParams->ppFrames[0]->iFrameSample - pAnalParams->sizeHop;
- sfloat *pOriginal = &(pAnalParams->soundBuffer.pFBuffer[iSoundLoc -
- pAnalParams->soundBuffer.iMarker]);
-
- int sizeData = MIN(pAnalParams->soundBuffer.sizeBuffer -
- (iSoundLoc - pAnalParams->soundBuffer.iMarker),
- pAnalParams->residualParams.residualSize);
- if(sizeData > pAnalParams->residualParams.residualSize)
- {
- sms_error("Residual size larger than expected.");
- return -1;
- }
- else if(sizeData < pAnalParams->residualParams.residualSize)
- {
- /* should only happen if we're at the end of a sound, unless hop size changes */
- /* TODO: should the window type be set to pAnalParams->iWindowType? */
- sms_getWindow(sizeData, pAnalParams->residualParams.fftWindow, SMS_WIN_HAMMING);
- sms_scaleWindow(sizeData, pAnalParams->residualParams.fftWindow);
- }
-
- /* obtain residual sound from original and synthesized sounds. accumulate the residual percentage.*/
- pAnalParams->fResidualAccumPerc += sms_residual(sizeData,
- pAnalParams->synthBuffer.pFBuffer,
- pOriginal,
- &pAnalParams->residualParams);
-
- if(pAnalParams->iStochasticType == SMS_STOC_APPROX)
- {
- /* filter residual with a high pass filter (it solves some problems) */
- sms_filterHighPass(sizeData, pAnalParams->residualParams.residual, pAnalParams->iSamplingRate);
-
- /* approximate residual */
- sms_stocAnalysis(sizeData, pAnalParams->residualParams.residual, pAnalParams->residualParams.fftWindow,
- pSmsData, pAnalParams);
- }
- else if(pAnalParams->iStochasticType == SMS_STOC_IFFT)
- {
- int sizeMag = sms_power2(sizeData >> 1);
- sms_spectrum(sizeData, pAnalParams->residualParams.residual, pAnalParams->residualParams.fftWindow,
- sizeMag, pSmsData->pFStocCoeff, pSmsData->pResPhase,
- pAnalParams->fftBuffer);
- }
-
- /* get sharper transitions in deterministic representation */
- sms_scaleDet(pAnalParams->synthBuffer.pFBuffer, pOriginal,
- pAnalParams->ppFrames[0]->deterministic.pFSinAmp,
- pAnalParams, pSmsData->nTracks);
-
- pAnalParams->ppFrames[0]->iStatus = SMS_FRAME_DONE;
- }
- }
- else if(pAnalParams->ppFrames[0]->iStatus != SMS_FRAME_EMPTY &&
- pAnalParams->ppFrames[0]->iStatus != SMS_FRAME_END)
- pAnalParams->ppFrames[0]->iStatus = SMS_FRAME_DONE;
-
- /* get the result */
- if(pAnalParams->ppFrames[0]->iStatus == SMS_FRAME_EMPTY)
- {
- /* no partials yet, so output the current peaks for testing */
- int numPeaks = pAnalParams->ppFrames[iCurrentFrame]->nPeaks;
- int numTracks = pSmsData->nTracks;
- numTracks = MIN(numPeaks, numTracks);
- for(i = 0; i < numTracks; i++)
- {
- pSmsData->pFSinFreq[i] = pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks[i].fFreq;
- pSmsData->pFSinAmp[i] = sms_dBToMag(pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks[i].fMag);
- if(pAnalParams->iFormat == SMS_FORMAT_HP || pAnalParams->iFormat == SMS_FORMAT_IHP)
- {
- pSmsData->pFSinPha[i] = pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks[i].fPhase;
- }
- }
- pSmsData->nTracks = numTracks;
- return 0;
- }
- /* return analysis data */
- else if(pAnalParams->ppFrames[0]->iStatus == SMS_FRAME_DONE)
- {
- /* put data into output */
- int length = sizeof(sfloat) * pSmsData->nTracks;
- memcpy((char *) pSmsData->pFSinFreq, (char *)
- pAnalParams->ppFrames[0]->deterministic.pFSinFreq, length);
- memcpy((char *) pSmsData->pFSinAmp, (char *)
- pAnalParams->ppFrames[0]->deterministic.pFSinAmp, length);
-
- /* convert mags back to linear */
- sms_arrayDBToMag(pSmsData->nTracks, pSmsData->pFSinAmp);
- if(pAnalParams->iFormat == SMS_FORMAT_HP || pAnalParams->iFormat == SMS_FORMAT_IHP)
- memcpy((char *) pSmsData->pFSinPha, (char *)
- pAnalParams->ppFrames[0]->deterministic.pFSinPha, length);
-
- /* do post-processing (for now, spectral envelope calculation and storage) */
- if(pAnalParams->specEnvParams.iType != SMS_ENV_NONE)
- {
- sms_spectralEnvelope(pSmsData, &pAnalParams->specEnvParams);
- }
- return 1;
- }
- /* done, end of sound */
- else if(pAnalParams->ppFrames[0]->iStatus == SMS_FRAME_END)
- return -1;
- else
- {
- sms_error("sms_analyze error: wrong status of frame.");
- return -1;
- }
- return 1;
-}
diff --git a/sms/cepstrum.c b/sms/cepstrum.c
deleted file mode 100644
index 8a56787..0000000
--- a/sms/cepstrum.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG)
- * UNIVERSITAT POMPEU FABRA
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-/*! \file cepstrum.c
- * \brief routines for different Fast Fourier Transform Algorithms
- *
- */
-
-#include "sms.h"
-#include <gsl/gsl_matrix.h>
-#include <gsl/gsl_linalg.h>
-#include <gsl/gsl_blas.h>
-
-#define COEF ( 8 * powf(PI, 2))
-#define CHOLESKY 1
-
-typedef struct
-{
- int nPoints;
- int nCoeff;
- gsl_matrix *pM;
- gsl_matrix *pMt;
- gsl_matrix *pR;
- gsl_matrix *pMtMR;
- gsl_vector *pXk;
- gsl_vector *pMtXk;
- gsl_vector *pC;
- gsl_permutation *pPerm;
-} CepstrumMatrices;
-
-void FreeDCepstrum(CepstrumMatrices *m)
-{
- gsl_matrix_free(m->pM);
- gsl_matrix_free(m->pMt);
- gsl_matrix_free(m->pR);
- gsl_matrix_free(m->pMtMR);
- gsl_vector_free(m->pXk);
- gsl_vector_free(m->pMtXk);
- gsl_vector_free(m->pC);
- gsl_permutation_free (m->pPerm);
-
-}
-
-void AllocateDCepstrum(int nPoints, int nCoeff, CepstrumMatrices *m)
-{
- if(m->nPoints != 0 || m->nCoeff != 0)
- FreeDCepstrum(m);
- m->nPoints = nPoints;
- m->nCoeff = nCoeff;
- m->pM = gsl_matrix_alloc(nPoints, nCoeff);
- m->pMt = gsl_matrix_alloc(nCoeff, nPoints);
- m->pR = gsl_matrix_calloc(nCoeff, nCoeff);
- m->pMtMR = gsl_matrix_alloc(nCoeff, nCoeff);
- m->pXk = gsl_vector_alloc(nPoints);
- m->pMtXk = gsl_vector_alloc(nCoeff);
- m->pC = gsl_vector_alloc(nCoeff);
- m->pPerm = gsl_permutation_alloc (nCoeff);
-}
-
-/*! \brief Discrete Cepstrum Transform
- *
- * method for computing cepstrum aenalysis from a discrete
- * set of partial peaks (frequency and amplitude)
- *
- * This implementation is owed to the help of Jordi Janer (thanks!) from the MTG,
- * along with the following paper:
- * "Regularization Techniques for Discrete Cepstrum Estimation"
- * Olivier Cappe and Eric Moulines, IEEE Signal Processing Letters, Vol. 3
- * No.4, April 1996
- *
- * \todo add anchor point add at frequency = 0 with the same magnitude as the first
- * peak in pMag. This does not change the size of the cepstrum, only helps to smoothen it
- * at the very beginning.
- *
- * \param sizeCepstrum order+1 of the discrete cepstrum
- * \param pCepstrum pointer to output array of cepstrum coefficients
- * \param sizeFreq number of partials peaks (the size of pFreq should be the same as pMag
- * \param pFreq pointer to partial peak frequencies (hertz)
- * \param pMag pointer to partial peak magnitudes (linear)
- * \param fLambda regularization factor
- * \param iMaxFreq maximum frequency of cepstrum
- */
-void sms_dCepstrum( int sizeCepstrum, sfloat *pCepstrum, int sizeFreq, sfloat *pFreq, sfloat *pMag,
- sfloat fLambda, int iMaxFreq)
-{
- int i, k;
- sfloat factor;
- sfloat fNorm = PI / (sfloat)iMaxFreq; /* value to normalize frequencies to 0:0.5 */
- //static sizeCepstrumStatic
- static CepstrumMatrices m;
- //printf("nPoints: %d, nCoeff: %d \n", m.nPoints, m.nCoeff);
- if(m.nPoints != sizeCepstrum || m.nCoeff != sizeFreq)
- AllocateDCepstrum(sizeFreq, sizeCepstrum, &m);
- int s; /* signum: "(-1)^n, where n is the number of interchanges in the permutation." */
- /* compute matrix M (eq. 4)*/
- for (i=0; i<sizeFreq; i++)
- {
- gsl_matrix_set (m.pM, i, 0, 1.); // first colum is all 1
- for (k=1; k <sizeCepstrum; k++)
- gsl_matrix_set (m.pM, i, k , 2.*sms_sine(PI_2 + fNorm * k * pFreq[i]) );
- }
-
- /* compute transpose of M */
- gsl_matrix_transpose_memcpy (m.pMt, m.pM);
-
- /* compute R diagonal matrix (for eq. 7)*/
- factor = COEF * (fLambda / (1.-fLambda)); /* \todo why is this divided like this again? */
- for (k=0; k<sizeCepstrum; k++)
- gsl_matrix_set(m.pR, k, k, factor * powf((sfloat) k,2.));
-
- /* MtM = Mt * M, later will add R */
- gsl_blas_dgemm (CblasNoTrans, CblasNoTrans, 1., m.pMt, m.pM, 0.0, m.pMtMR);
- /* add R to make MtMR */
- gsl_matrix_add (m.pMtMR, m.pR);
-
- /* set pMag in X and multiply with Mt to get pMtXk */
- for(k = 0; k <sizeFreq; k++)
- gsl_vector_set(m.pXk, k, log(pMag[k]));
- gsl_blas_dgemv (CblasNoTrans, 1., m.pMt, m.pXk, 0., m.pMtXk);
-
- /* solve x (the cepstrum) in Ax = b, where A=MtMR and b=pMtXk */
-
- /* ==== the Cholesky Decomposition way ==== */
- /* MtM is 'symmetric and positive definite?' */
- //gsl_linalg_cholesky_decomp (m.pMtMR);
- //gsl_linalg_cholesky_solve (m.pMtMR, m.pMtXk, m.pC);
-
- /* ==== the LU decomposition way ==== */
- gsl_linalg_LU_decomp (m.pMtMR, m.pPerm, &s);
- gsl_linalg_LU_solve (m.pMtMR, m.pPerm, m.pMtXk, m.pC);
-
-
- /* copy pC to pCepstrum */
- for(i = 0; i < sizeCepstrum; i++)
- pCepstrum[i] = gsl_vector_get (m.pC, i);
-}
-
-/*! \brief Spectrum Envelope from Cepstrum
- *
- * from a set of cepstrum coefficients, compute the spectrum envelope
- *
- * \param sizeCepstrum order + 1 of the cepstrum
- * \param pCepstrum pointer to array of cepstrum coefficients
- * \param sizeEnv size of spectrum envelope (max frequency in bins) \todo does this have to be a pow2
- * \param pEnv pointer to output spectrum envelope (real part only)
- */
-void sms_dCepstrumEnvelope(int sizeCepstrum, sfloat *pCepstrum, int sizeEnv, sfloat *pEnv)
-{
-
- static sfloat *pFftBuffer;
- static int sizeFftArray = 0;
- int sizeFft = sizeEnv << 1;
- int i;
- if(sizeFftArray != sizeFft)
- {
- if(sizeFftArray != 0) free(pFftBuffer);
- sizeFftArray = sms_power2(sizeFft);
- if(sizeFftArray != sizeFft)
- {
- sms_error("bad fft size, incremented to power of 2");
- }
- if ((pFftBuffer = (sfloat *) malloc(sizeFftArray * sizeof(sfloat))) == NULL)
- {
- sms_error("could not allocate memory for fft array");
- return;
- }
- }
- memset(pFftBuffer, 0, sizeFftArray * sizeof(sfloat));
-
- pFftBuffer[0] = pCepstrum[0] * 0.5;
- for (i = 1; i < sizeCepstrum-1; i++)
- pFftBuffer[i] = pCepstrum[i];
-
-
- sms_fft(sizeFftArray, pFftBuffer);
-
- for (i = 0; i < sizeEnv; i++)
- pEnv[i] = powf(EXP, 2. * pFftBuffer[i*2]);
-}
-
-/*! \brief main function for computing spectral envelope from sinusoidal peaks
- *
- * Magnitudes should already be in linear for this function.
- * If pSmsData->iEnvelope == SMS_ENV_CEP, will return cepstrum coefficeints
- * If pSmsData->iEnvelope == SMS_ENV_FBINS, will return linear magnitude spectrum
- *
- * \param pSmsData pointer to SMS_Data structure with all the arrays necessary
- * \param pSpecEnvParams pointer to a structure of parameters for spectral enveloping
- */
-void sms_spectralEnvelope( SMS_Data *pSmsData, SMS_SEnvParams *pSpecEnvParams)
-{
- int i, k;
- int sizeCepstrum = pSpecEnvParams->iOrder+1;
- //int nPeaks = 0;
- static sfloat pFreqBuff[1000], pMagBuff[1000];
-
- /* \todo see if this memset is even necessary, once working */
- //memset(pSmsData->pSpecEnv, 0, pSpecEnvParams->nCoeff * sizeof(sfloat));
-
- /* try to store cepstrum coefficients in pSmsData->nEnvCoeff always.
- if cepstrum is what is wanted, memset the rest. otherwise, hand this array 2x to dCepstrumEnvelope */
- if(pSpecEnvParams->iOrder + 1> pSmsData->nEnvCoeff)
- {
- sms_error("cepstrum order is larger than the size of the spectral envelope");
- return;
- }
-
- /* find out how many tracks were actually found... many are zero
- \todo is this necessary? */
- for(i = 0, k=0; i < pSmsData->nTracks; i++)
- {
- if(pSmsData->pFSinFreq[i] > 0.00001)
- {
- if(pSpecEnvParams->iAnchor != 0)
- {
- if(k == 0) /* add anchor at beginning */
-
- {
- pFreqBuff[k] = 0.0;
- pMagBuff[k] = pSmsData->pFSinAmp[i];
- k++;
- }
- }
- pFreqBuff[k] = pSmsData->pFSinFreq[i];
- pMagBuff[k] = pSmsData->pFSinAmp[i];
- k++;
- }
- }
- /* \todo see if adding an anchor at the max freq helps */
-
-
- if(k < 1) // how few can this be? try out a few in python
- return;
- sms_dCepstrum(sizeCepstrum, pSmsData->pSpecEnv, k, pFreqBuff, pMagBuff,
- pSpecEnvParams->fLambda, pSpecEnvParams->iMaxFreq);
-
- if(pSpecEnvParams->iType == SMS_ENV_FBINS)
- {
- sms_dCepstrumEnvelope(sizeCepstrum, pSmsData->pSpecEnv,
- pSpecEnvParams->nCoeff, pSmsData->pSpecEnv);
- }
-}
diff --git a/sms/fileIO.c b/sms/fileIO.c
deleted file mode 100644
index e870c5a..0000000
--- a/sms/fileIO.c
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG)
- * UNIVERSITAT POMPEU FABRA
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-/*! \file fileIO.c
- * \brief SMS file input and output
- */
-
-#include "sms.h"
-
-/*! \brief file identification constant
- *
- * constant number that is first within SMS_Header, in order to correctly
- * identify an SMS file when read.
- */
-#define SMS_MAGIC 767
-
-static char pChTextString[1000]; /*!< string to store analysis parameters in sms header */
-
-/*! \brief initialize the header structure of an SMS file
- *
- * \param pSmsHeader header for SMS file
- */
-void sms_initHeader(SMS_Header *pSmsHeader)
-{
- pSmsHeader->iSmsMagic = SMS_MAGIC;
- pSmsHeader->iHeadBSize = sizeof(SMS_Header);
- pSmsHeader->nFrames = 0;
- pSmsHeader->iFrameBSize = 0;
- pSmsHeader->iFormat = SMS_FORMAT_H;
- pSmsHeader->iFrameRate = 0;
- pSmsHeader->iStochasticType = SMS_STOC_APPROX;
- pSmsHeader->nTracks = 0;
- pSmsHeader->nStochasticCoeff = 0;
- pSmsHeader->nEnvCoeff = 0;
- pSmsHeader->iMaxFreq = 0;
- pSmsHeader->fResidualPerc = 0;
-}
-
-/*! \brief fill an SMS header with necessary information for storage
- *
- * copies parameters from SMS_AnalParams, along with other values
- * so an SMS file can be stored and correctly synthesized at a later
- * time. This is somewhat of a convenience function.
- *
- * sms_initAnal() should be done first to properly set everything.
- *
- * \param pSmsHeader header for SMS file (to be stored)
- * \param pAnalParams structure of analysis parameters
- * \param pProgramString pointer to a string containing the name of the program that made the analysis data
- */
-void sms_fillHeader(SMS_Header *pSmsHeader, SMS_AnalParams *pAnalParams, char *pProgramString)
-{
- sms_initHeader(pSmsHeader);
- pSmsHeader->nFrames = pAnalParams->nFrames;
- pSmsHeader->iFormat = pAnalParams->iFormat;
- pSmsHeader->iFrameRate = pAnalParams->iFrameRate;
- pSmsHeader->iStochasticType = pAnalParams->iStochasticType;
- pSmsHeader->nTracks = pAnalParams->nTracks;
- pSmsHeader->iSamplingRate = pAnalParams->iSamplingRate;
- if(pAnalParams->iStochasticType == SMS_STOC_NONE)
- pSmsHeader->nStochasticCoeff = 0;
- else
- pSmsHeader->nStochasticCoeff = pAnalParams->nStochasticCoeff;
- pSmsHeader->iEnvType = pAnalParams->specEnvParams.iType;
- pSmsHeader->nEnvCoeff = pAnalParams->specEnvParams.nCoeff;
- pSmsHeader->iMaxFreq = (int)pAnalParams->fHighestFreq;
- pSmsHeader->iFrameBSize = sms_frameSizeB(pSmsHeader);
-}
-
-/*! \brief write SMS header to file
- *
- * \param pChFileName file name for SMS file
- * \param pSmsHeader header for SMS file
- * \param ppSmsFile (double pointer to) file to be created
- * \return error code \see SMS_WRERR in SMS_ERRORS
- */
-int sms_writeHeader(char *pChFileName, SMS_Header *pSmsHeader, FILE **ppSmsFile)
-{
- int iVariableSize = 0;
-
- if(pSmsHeader->iSmsMagic != SMS_MAGIC)
- {
- sms_error("not an SMS file");
- return -1;
- }
- if((*ppSmsFile = fopen (pChFileName, "w+")) == NULL)
- {
- sms_error("cannot open file for writing");
- return -1;
- }
-
- pSmsHeader->iHeadBSize = sizeof(SMS_Header);
-
- /* write header */
- if(fwrite((void *)pSmsHeader, (size_t)1, (size_t)sizeof(SMS_Header),
- *ppSmsFile) < (size_t)sizeof(SMS_Header))
- {
- sms_error("cannot write output file");
- return(-1);
- }
- return 0;
-}
-
-/*! \brief rewrite SMS header and close file
- *
- * \param pSmsFile pointer to SMS file
- * \param pSmsHeader pointer to header for SMS file
- * \return error code \see SMS_WRERR in SMS_ERRORS
- */
-int sms_writeFile(FILE *pSmsFile, SMS_Header *pSmsHeader)
-{
- int iVariableSize;
- rewind(pSmsFile);
-
- pSmsHeader->iHeadBSize = sizeof(SMS_Header);
-
- /* write header */
- if(fwrite((void *)pSmsHeader, (size_t)1, (size_t)sizeof(SMS_Header),
- pSmsFile) < (size_t)sizeof(SMS_Header))
- {
- sms_error("cannot write output file (header)");
- return -1;
- }
-
- fclose(pSmsFile);
- return 0;
-}
-
-/*! \brief write SMS frame
- *
- * \param pSmsFile pointer to SMS file
- * \param pSmsHeader pointer to SMS header
- * \param pSmsFrame pointer to SMS data frame
- * \return 0 on success, -1 on failure
- */
-int sms_writeFrame(FILE *pSmsFile, SMS_Header *pSmsHeader, SMS_Data *pSmsFrame)
-{
- if (fwrite((void *)pSmsFrame->pSmsData, 1, pSmsHeader->iFrameBSize,
- pSmsFile) < (unsigned int) pSmsHeader->iFrameBSize)
- {
- sms_error("cannot write frame to output file");
- return -1;
- }
- return 0;
-}
-
-/*! \brief get the size in bytes of the frame in a SMS file
- *
- * \param pSmsHeader pointer to SMS header
- * \return the size in bytes of the frame
- */
-int sms_frameSizeB(SMS_Header *pSmsHeader)
-{
- int iSize, nDet;
-
- if(pSmsHeader->iFormat == SMS_FORMAT_H ||
- pSmsHeader->iFormat == SMS_FORMAT_IH)
- nDet = 2;/* freq, mag */
- else
- nDet = 3; /* freq, mag, phase */
-
- iSize = sizeof (sfloat) * (nDet * pSmsHeader->nTracks);
-
- if(pSmsHeader->iStochasticType == SMS_STOC_APPROX)
- { /* stocCoeff + 1 (gain) */
- iSize += sizeof(sfloat) * (pSmsHeader->nStochasticCoeff + 1);
- }
- else if(pSmsHeader->iStochasticType == SMS_STOC_IFFT)
- {
- /* sizeFFT*2 + 1 (gain) */
- iSize += sizeof(sfloat) * (pSmsHeader->nStochasticCoeff * 2 + 1);
- }
- iSize += sizeof(sfloat) * pSmsHeader->nEnvCoeff;
- return iSize;
-}
-
-/*! \brief function to read SMS header
- *
- * \param pChFileName file name for SMS file
- * \param ppSmsHeader (double pointer to) SMS header
- * \param ppSmsFile (double pointer to) inputfile
- * \return error code \see SMS_ERRORS
- */
-int sms_getHeader(char *pChFileName, SMS_Header **ppSmsHeader, FILE **ppSmsFile)
-{
- int iHeadBSize, iFrameBSize, nFrames;
- int iMagicNumber;
-
- /* open file for reading */
- if((*ppSmsFile = fopen (pChFileName, "r")) == NULL)
- {
- sms_error("could not open SMS header");
- return -1;
- }
- /* read magic number */
- if(fread((void *) &iMagicNumber, (size_t) sizeof(int), (size_t)1,
- *ppSmsFile) < (size_t)1)
- {
- sms_error("could not read SMS header");
- return -1;
- }
-
- if(iMagicNumber != SMS_MAGIC)
- {
- sms_error("not an SMS file");
- return -1;
- }
-
- /* read size of of header */
- if(fread((void *) &iHeadBSize, (size_t) sizeof(int), (size_t)1,
- *ppSmsFile) < (size_t)1)
- {
- sms_error("could not read SMS header (iHeadBSize)");
- return -1;
- }
-
- if(iHeadBSize <= 0)
- {
- sms_error("bad SMS header size");
- return -1;
- }
-
- /* read number of data Frames */
- if(fread((void *) &nFrames, (size_t) sizeof(int), (size_t)1,
- *ppSmsFile) < (size_t)1)
- {
- sms_error("could not read SMS number of frames");
- return -1;
- }
-
- if(nFrames <= 0)
- {
- sms_error("number of frames <= 0");
- return -1;
- }
-
- /* read size of data Frames */
- if(fread((void *) &iFrameBSize, (size_t) sizeof(int), (size_t)1,
- *ppSmsFile) < (size_t)1)
- {
- sms_error("could not read size of SMS data");
- return -1;
- }
-
- if(iFrameBSize <= 0)
- {
- sms_error("size bytes of frames <= 0");
- return -1;
- }
-
- /* allocate memory for header */
- if(((*ppSmsHeader) = (SMS_Header *)malloc (iHeadBSize)) == NULL)
- {
- sms_error("cannot allocate memory for header");
- return -1;
- }
-
- /* read header */
- rewind(*ppSmsFile);
- if(fread ((void *) (*ppSmsHeader), 1, iHeadBSize, *ppSmsFile) < (unsigned int) iHeadBSize)
- {
- sms_error("cannot read header of SMS file");
- return -1;
- }
-
- return 0;
-}
-
-/*! \brief read an SMS data frame
- *
- * \param pSmsFile pointer to SMS file
- * \param pSmsHeader pointer to SMS header
- * \param iFrame frame number
- * \param pSmsFrame pointer to SMS frame
- * \return 0 on sucess, -1 on error
- */
-int sms_getFrame(FILE *pSmsFile, SMS_Header *pSmsHeader, int iFrame, SMS_Data *pSmsFrame)
-{
- if(fseek(pSmsFile, pSmsHeader->iHeadBSize + iFrame *
- pSmsHeader->iFrameBSize, SEEK_SET) < 0)
- {
- sms_error("cannot seek to the SMS frame");
- return -1;
- }
- if((pSmsHeader->iFrameBSize =
- fread((void *)pSmsFrame->pSmsData, (size_t)1,
- (size_t)pSmsHeader->iFrameBSize, pSmsFile))
- != pSmsHeader->iFrameBSize)
- {
- sms_error("cannot read SMS frame");
- return -1;
- }
- return 0;
-}
-
-/*! \brief allocate memory for a frame of SMS data
- *
- * \param pSmsFrame pointer to a frame of SMS data
- * \param nTracks number of sinusoidal tracks in frame
- * \param nStochCoeff number of stochastic coefficients in frame
- * \param iPhase whether phase information is in the frame
- * \param stochType stochastic resynthesis type
- * \param nStochCoeff number of envelope coefficients in frame
- * \param nEnvCoeff number of envelope coefficients in frame
- * \return 0 on success, -1 on error
- */
-int sms_allocFrame(SMS_Data *pSmsFrame, int nTracks, int nStochCoeff, int iPhase,
- int stochType, int nEnvCoeff)
-{
- sfloat *dataPos; /* a marker to locate specific data witin smsData */
-
- /* calculate size of frame */
- int sizeData = sizeof(sfloat); /* nSamples */
- /* frequencies and magnitudes */
- sizeData += 2 * nTracks * sizeof(sfloat);
- /* phases */
- if(iPhase > 0)
- sizeData += nTracks * sizeof(sfloat);
- /* stochastic coefficients */
- if(stochType == SMS_STOC_APPROX)
- sizeData += (nStochCoeff + 1) * sizeof(sfloat);
- else if(stochType == SMS_STOC_IFFT)
- sizeData += ((2*nStochCoeff) + 1) * sizeof(sfloat);
- /* spectral envelope */
- sizeData += nEnvCoeff * sizeof(sfloat); /* add in number of envelope coefficients (cep or fbins) if any */
-
- /* allocate memory for data */
- pSmsFrame->pSmsData = (sfloat *)malloc(sizeData);
- if(pSmsFrame->pSmsData == NULL)
- {
- sms_error("cannot allocate memory for SMS frame data");
- return -1;
- }
- memset(pSmsFrame->pSmsData, 0, sizeData);
-
- /* set the variables in the structure */
- /* \todo why not set these in init functions, then allocate with them?? */
- pSmsFrame->sizeData = sizeData;
- pSmsFrame->nTracks = nTracks;
- pSmsFrame->nCoeff = nStochCoeff;
- pSmsFrame->nEnvCoeff = nEnvCoeff;
-
- /* set pointers to data types within smsData array */
- pSmsFrame->pFSinFreq = pSmsFrame->pSmsData;
- dataPos = (sfloat *)(pSmsFrame->pFSinFreq + nTracks);
-
- pSmsFrame->pFSinAmp = dataPos;
- dataPos = (sfloat *)(pSmsFrame->pFSinAmp + nTracks);
-
- if(iPhase > 0)
- {
- pSmsFrame->pFSinPha = dataPos;
- dataPos = (sfloat *)(pSmsFrame->pFSinPha + nTracks);
- }
- else
- pSmsFrame->pFSinPha = NULL;
-
- if(stochType == SMS_STOC_APPROX)
- {
- pSmsFrame->pFStocCoeff = dataPos;
- dataPos = (sfloat *)(pSmsFrame->pFStocCoeff + nStochCoeff);
-
- pSmsFrame->pFStocGain = dataPos;
- dataPos = (sfloat *)(pSmsFrame->pFStocGain + 1);
- }
- else if(stochType == SMS_STOC_IFFT)
- {
- pSmsFrame->pFStocCoeff = dataPos;
- dataPos = (sfloat *)(pSmsFrame->pFStocCoeff + nStochCoeff);
- pSmsFrame->pResPhase = dataPos;
- dataPos = (sfloat *)(pSmsFrame->pResPhase + nStochCoeff);
- pSmsFrame->pFStocGain = dataPos;
- dataPos = (sfloat *)(pSmsFrame->pFStocGain + 1);
- }
- else
- {
- pSmsFrame->pFStocCoeff = NULL;
- pSmsFrame->pResPhase = NULL;
- pSmsFrame->pFStocGain = NULL;
- }
-
- if(nEnvCoeff > 0)
- pSmsFrame->pSpecEnv = dataPos;
- else
- pSmsFrame->pSpecEnv = NULL;
-
- return 0;
-}
-
-/*! \brief function to allocate an SMS data frame using an SMS_Header
- *
- * this one is used when you have only read the header, such as after
- * opening a file.
- *
- * \param pSmsHeader pointer to SMS header
- * \param pSmsFrame pointer to SMS frame
- * \return 0 on success, -1 on error
- */
-int sms_allocFrameH(SMS_Header *pSmsHeader, SMS_Data *pSmsFrame)
-{
- int iPhase = (pSmsHeader->iFormat == SMS_FORMAT_HP ||
- pSmsHeader->iFormat == SMS_FORMAT_IHP) ? 1 : 0;
- return sms_allocFrame(pSmsFrame, pSmsHeader->nTracks,
- pSmsHeader->nStochasticCoeff, iPhase,
- pSmsHeader->iStochasticType,
- pSmsHeader->nEnvCoeff);
-}
-
-/*! \brief free the SMS data structure
- *
- * \param pSmsFrame pointer to frame of SMS data
- */
-void sms_freeFrame(SMS_Data *pSmsFrame)
-{
- if(!pSmsFrame)
- return;
-
- if(pSmsFrame->pSmsData)
- free(pSmsFrame->pSmsData);
-
- pSmsFrame->nTracks = 0;
- pSmsFrame->nCoeff = 0;
- pSmsFrame->sizeData = 0;
- pSmsFrame->pFSinFreq = NULL;
- pSmsFrame->pFSinAmp = NULL;
- pSmsFrame->pFStocCoeff = NULL;
- pSmsFrame->pResPhase = NULL;
- pSmsFrame->pFStocGain = NULL;
-}
-
-/*! \brief clear the SMS data structure
- *
- * \param pSmsFrame pointer to frame of SMS data
- */
-void sms_clearFrame(SMS_Data *pSmsFrame)
-{
- memset(pSmsFrame->pSmsData, 0, pSmsFrame->sizeData);
-}
-
-/*! \brief copy a frame of SMS_Data
- *
- * \param pCopySmsData copy of frame
- * \param pOriginalSmsData original frame
- *
- */
-void sms_copyFrame(SMS_Data *pCopySmsData, SMS_Data *pOriginalSmsData)
-{
- /* if the two frames are the same size just copy data */
- if(pCopySmsData->sizeData == pOriginalSmsData->sizeData &&
- pCopySmsData->nTracks == pOriginalSmsData->nTracks)
- {
- memcpy((char *)pCopySmsData->pSmsData,
- (char *)pOriginalSmsData->pSmsData,
- pCopySmsData->sizeData);
- }
- /* if frames is different size copy the smallest */
- else
- {
- int nTracks = MIN(pCopySmsData->nTracks, pOriginalSmsData->nTracks);
- int nCoeff = MIN(pCopySmsData->nCoeff, pOriginalSmsData->nCoeff);
-
- pCopySmsData->nTracks = nTracks;
- pCopySmsData->nCoeff = nCoeff;
- memcpy((char *)pCopySmsData->pFSinFreq,
- (char *)pOriginalSmsData->pFSinFreq,
- sizeof(sfloat) * nTracks);
- memcpy((char *)pCopySmsData->pFSinAmp,
- (char *)pOriginalSmsData->pFSinAmp,
- sizeof(sfloat) * nTracks);
- if(pOriginalSmsData->pFSinPha != NULL &&
- pCopySmsData->pFSinPha != NULL)
- memcpy((char *)pCopySmsData->pFSinPha,
- (char *)pOriginalSmsData->pFSinPha,
- sizeof(sfloat) * nTracks);
- if(pOriginalSmsData->pFStocCoeff != NULL &&
- pCopySmsData->pFStocCoeff != NULL)
- {
- if(pOriginalSmsData->pResPhase != NULL &&
- pCopySmsData->pResPhase != NULL)
- memcpy((char *)pCopySmsData->pResPhase,
- (char *)pOriginalSmsData->pResPhase,
- sizeof(sfloat) * nCoeff);
- }
- if(pOriginalSmsData->pFStocGain != NULL &&
- pCopySmsData->pFStocGain != NULL)
- memcpy((char *)pCopySmsData->pFStocGain,
- (char *)pOriginalSmsData->pFStocGain,
- sizeof(sfloat));
- }
-}
-
-/*! \brief function to interpolate two SMS frames
- *
- * this assumes that the two frames are of the same size
- *
- * \param pSmsFrame1 sms frame 1
- * \param pSmsFrame2 sms frame 2
- * \param pSmsFrameOut sms output frame
- * \param fInterpFactor interpolation factor
- */
-void sms_interpolateFrames(SMS_Data *pSmsFrame1, SMS_Data *pSmsFrame2,
- SMS_Data *pSmsFrameOut, sfloat fInterpFactor)
-{
- int i;
- sfloat fFreq1, fFreq2;
-
- /* interpolate the deterministic part */
- for(i = 0; i < pSmsFrame1->nTracks; i++)
- {
- fFreq1 = pSmsFrame1->pFSinFreq[i];
- fFreq2 = pSmsFrame2->pFSinFreq[i];
- if(fFreq1 == 0)
- fFreq1 = fFreq2;
- if(fFreq2 == 0)
- fFreq2 = fFreq1;
- pSmsFrameOut->pFSinFreq[i] = fFreq1 + fInterpFactor * (fFreq2 - fFreq1);
- pSmsFrameOut->pFSinAmp[i] =
- pSmsFrame1->pFSinAmp[i] + fInterpFactor *
- (pSmsFrame2->pFSinAmp[i] - pSmsFrame1->pFSinAmp[i]);
- }
-
- /* interpolate the stochastic part. The pointer is non-null when the frame contains
- stochastic coefficients */
- if(pSmsFrameOut->pFStocGain)
- {
- *(pSmsFrameOut->pFStocGain) =
- *(pSmsFrame1->pFStocGain) + fInterpFactor *
- (*(pSmsFrame2->pFStocGain) - *(pSmsFrame1->pFStocGain));
- }
- /*! \todo how to interpolate residual phase spectrum */
- for(i = 0; i < pSmsFrame1->nCoeff; i++)
- pSmsFrameOut->pFStocCoeff[i] =
- pSmsFrame1->pFStocCoeff[i] + fInterpFactor *
- (pSmsFrame2->pFStocCoeff[i] - pSmsFrame1->pFStocCoeff[i]);
-
- /* DO NEXT: interpolate spec env here if fbins */
- for(i = 0; i < pSmsFrame1->nEnvCoeff; i++)
- pSmsFrameOut->pSpecEnv[i] =
- pSmsFrame1->pSpecEnv[i] + fInterpFactor *
- (pSmsFrame2->pSpecEnv[i] - pSmsFrame1->pSpecEnv[i]);
-}
-
diff --git a/sms/filters.c b/sms/filters.c
deleted file mode 100644
index 7f31317..0000000
--- a/sms/filters.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG)
- * UNIVERSITAT POMPEU FABRA
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-/*! \file filters.c
- * \brief various filters
- */
-
-#include "sms.h"
-
-/*! \brief coefficient for pre_emphasis filter */
-#define SMS_EMPH_COEF .9
-
-/* pre-emphasis filter function, it returns the filtered value
- *
- * sfloat fInput; sound sample
- */
-sfloat sms_preEmphasis(sfloat fInput, SMS_AnalParams *pAnalParams)
-{
- if(pAnalParams->preEmphasis)
- {
- sfloat fOutput = fInput - SMS_EMPH_COEF * pAnalParams->preEmphasisLastValue;
- pAnalParams->preEmphasisLastValue = fOutput;
- return fOutput;
- }
- return fInput;
-}
-
-/* de-emphasis filter function, it returns the filtered value
- *
- * sfloat fInput; sound input
- */
-sfloat sms_deEmphasis(sfloat fInput, SMS_SynthParams *pSynthParams)
-{
- if(pSynthParams->deEmphasis)
- {
- sfloat fOutput = fInput + SMS_EMPH_COEF * pSynthParams->deEmphasisLastValue;
- pSynthParams->deEmphasisLastValue = fInput;
- return fOutput;
- }
- return fInput;
-}
-
-/*! \brief function to implement a zero-pole filter
- *
- * \todo will forgetting to reset pD to zero at the beginning of a new analysis
- * (when there are multiple analyses within the life of one program)
- * cause problems?
- *
- * \param pFa pointer to numerator coefficients
- * \param pFb pointer to denominator coefficients
- * \param nCoeff number of coefficients
- * \param fInput input sample
- * \return value is the filtered sample
- */
-static sfloat ZeroPoleFilter(sfloat *pFa, sfloat *pFb, int nCoeff, sfloat fInput )
-{
- double fOut = 0;
- int iSection;
- static sfloat pD[5] = {0, 0, 0, 0, 0};
-
- pD[0] = fInput;
- for (iSection = nCoeff-1; iSection > 0; iSection--)
- {
- fOut = fOut + pFa[iSection] * pD[iSection];
- pD[0] = pD[0] - pFb[iSection] * pD[iSection];
- pD[iSection] = pD [iSection-1];
- }
- fOut = fOut + pFa[0] * pD[0];
- return (sfloat) fOut;
-}
-
-/*! \brief function to filter a waveform with a high-pass filter
- *
- * cutoff =1500 Hz
- *
- * \todo this filter only works on sample rates up to 48k?
- *
- * \param sizeResidual size of signal
- * \param pResidual pointer to residual signal
- * \param iSamplingRate sampling rate of signal
- */
-void sms_filterHighPass(int sizeResidual, sfloat *pResidual, int iSamplingRate)
-{
- /* cutoff 800Hz */
- static sfloat pFCoeff32k[10] = {0.814255, -3.25702, 4.88553, -3.25702,
- 0.814255, 1, -3.58973, 4.85128, -2.92405, 0.66301};
- static sfloat pFCoeff36k[10] = {0.833098, -3.33239, 4.99859, -3.33239,
- 0.833098, 1, -3.63528, 4.97089, -3.02934,0.694052};
- static sfloat pFCoeff40k[10] = {0.848475, -3.3939, 5.09085, -3.3939,
- 0.848475, 1, -3.67173, 5.068, -3.11597, 0.71991};
- static sfloat pFCoeff441k[10] = {0.861554, -3.44622, 5.16932, -3.44622,
- 0.861554, 1, -3.70223, 5.15023, -3.19013, 0.742275};
- static sfloat pFCoeff48k[10] = {0.872061, -3.48824, 5.23236, -3.48824,
- 0.872061, 1, -3.72641, 5.21605, -3.25002, 0.76049};
- sfloat *pFCoeff, fSample = 0;
- int i;
-
- if(iSamplingRate <= 32000)
- pFCoeff = pFCoeff32k;
- else if(iSamplingRate <= 36000)
- pFCoeff = pFCoeff36k;
- else if(iSamplingRate <= 40000)
- pFCoeff = pFCoeff40k;
- else if(iSamplingRate <= 44100)
- pFCoeff = pFCoeff441k;
- else
- pFCoeff = pFCoeff48k;
-
- for(i = 0; i < sizeResidual; i++)
- {
- /* try to avoid underflow when there is nothing to filter */
- if(i > 0 && fSample == 0 && pResidual[i] == 0)
- return;
-
- fSample = pResidual[i];
- pResidual[i] = ZeroPoleFilter (&pFCoeff[0], &pFCoeff[5], 5, fSample);
- }
-}
-
-/*! \brief a spectral filter
- *
- * filter each point of the current array by the surounding
- * points using a triangular window
- *
- * \param pFArray two dimensional input array
- * \param size1 vertical size of pFArray
- * \param size2 horizontal size of pFArray
- * \param pFOutArray output array of size size1
- */
-void sms_filterArray(sfloat *pFArray, int size1, int size2, sfloat *pFOutArray)
-{
- int i, j, iPoint, iFrame, size2_2 = size2-2, size2_1 = size2-1;
- sfloat *pFCurrentArray = pFArray + (size2_1) * size1;
- sfloat fVal, fWeighting, fTotalWeighting, fTmpVal;
-
- /* find the filtered envelope */
- for(i = 0; i < size1; i++)
- {
- fVal = pFCurrentArray[i];
- fTotalWeighting = 1;
- /* filter by the surrounding points */
- for(j = 1; j < (size2_2); j++)
- {
- fWeighting = (sfloat) size2 / (1+ j);
- /* filter on the vertical dimension */
- /* consider the lower points */
- iPoint = i - (size2_1) + j;
- if(iPoint >= 0)
- {
- fVal += pFCurrentArray[iPoint] * fWeighting;
- fTotalWeighting += fWeighting;
- }
- /* consider the higher points */
- iPoint = i + (size2_1) - j;
- if(iPoint < size1)
- {
- fVal += pFCurrentArray[iPoint] * fWeighting;
- fTotalWeighting += fWeighting;
- }
- /*filter on the horizontal dimension */
- /* consider the previous points */
- iFrame = j;
- fTmpVal = pFArray[iFrame*size1 + i];
- if(fTmpVal)
- {
- fVal += fTmpVal * fWeighting;
- fTotalWeighting += fWeighting;
- }
- }
- /* scale value by weighting */
- pFOutArray[i] = fVal / fTotalWeighting;
- }
-}
diff --git a/sms/fixTracks.c b/sms/fixTracks.c
deleted file mode 100644
index 109d854..0000000
--- a/sms/fixTracks.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG)
- * UNIVERSITAT POMPEU FABRA
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-/*! \file fixTracks.c
- * \brief functions for making smoothly evolving tracks (partial frequencies)
- *
- * Tries to fix gaps and short tracks
- */
-
-#include "sms.h"
-
-/*! \brief fill a gap in a given track
- *
- * \param iCurrentFrame currrent frame number
- * \param iTrack track to be filled
- * \param pIState pointer to the state of tracks
- * \param pAnalParams pointer to analysis parameters
- */
-static void FillGap(int iCurrentFrame, int iTrack, int *pIState,
- SMS_AnalParams *pAnalParams)
-{
- int iFrame, iLastFrame = - (pIState[iTrack] - 1);
- sfloat fConstant = TWO_PI / pAnalParams->iSamplingRate;
- sfloat fFirstMag, fFirstFreq, fLastMag, fLastFreq, fIncrMag, fIncrFreq,
- fMag, fTmpPha, fFreq;
-
- if(iCurrentFrame - iLastFrame < 0)
- return;
-
- /* if firstMag is 0 it means that there is no Gap, just the begining of a track */
- if(pAnalParams->ppFrames[iCurrentFrame -
- iLastFrame]->deterministic.pFSinAmp[iTrack] == 0)
- {
- pIState[iTrack] = 1;
- return;
- }
-
- fFirstMag =
- pAnalParams->ppFrames[iCurrentFrame - iLastFrame]->deterministic.pFSinAmp[iTrack];
- fFirstFreq =
- pAnalParams->ppFrames[iCurrentFrame - iLastFrame]->deterministic.pFSinFreq[iTrack];
- fLastMag = pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinAmp[iTrack];
- fLastFreq = pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinFreq[iTrack];
- fIncrMag = (fLastMag - fFirstMag) / iLastFrame;
- fIncrFreq = (fLastFreq - fFirstFreq) / iLastFrame;
-
- /* if inharmonic format and the two extremes are very different */
- /* do not interpolate, it means that they are different tracks */
- if((pAnalParams->iFormat == SMS_FORMAT_IH ||
- pAnalParams->iFormat == SMS_FORMAT_IHP) &&
- (MIN (fFirstFreq, fLastFreq) * .5 * pAnalParams->fFreqDeviation <
- fabs(fLastFreq - fFirstFreq)))
- {
- pIState[iTrack] = 1;
- return;
- }
-
- fMag = fFirstMag;
- fFreq = fFirstFreq;
- /* fill the gap by interpolating values */
- /* if the gap is too long it should consider the lower partials */
- for(iFrame = iCurrentFrame - iLastFrame + 1; iFrame < iCurrentFrame; iFrame++)
- {
- /* interpolate magnitude */
- fMag += fIncrMag;
- pAnalParams->ppFrames[iFrame]->deterministic.pFSinAmp[iTrack] = fMag;
- /* interpolate frequency */
- fFreq += fIncrFreq;
- pAnalParams->ppFrames[iFrame]->deterministic.pFSinFreq[iTrack] = fFreq;
- /*interpolate phase (this may not be the right way) */
- fTmpPha =
- pAnalParams->ppFrames[iFrame-1]->deterministic.pFSinPha[iTrack] -
- (pAnalParams->ppFrames[iFrame-1]->deterministic.pFSinFreq[iTrack] *
- fConstant) * pAnalParams->sizeHop;
- pAnalParams->ppFrames[iFrame]->deterministic.pFSinPha[iTrack] =
- fTmpPha - floor(fTmpPha/ TWO_PI) * TWO_PI;
- }
-
- if(pAnalParams->iDebugMode == SMS_DBG_CLEAN_TRAJ ||
- pAnalParams->iDebugMode == SMS_DBG_ALL)
- {
- fprintf (stdout, "fillGap: track %d, frames %d to %d filled\n",
- iTrack, pAnalParams->ppFrames[iCurrentFrame-iLastFrame + 1]->iFrameNum,
- pAnalParams->ppFrames[iCurrentFrame-1]->iFrameNum);
- fprintf (stdout, "firstFreq %f lastFreq %f, firstMag %f lastMag %f\n",
- fFirstFreq, fLastFreq, fFirstMag, fLastMag);
-
- }
-
- /* reset status */
- pIState[iTrack] = pAnalParams->iMinTrackLength;
-}
-
-
-/*! \brief delete a short track
- *
- * this function is not exported to sms.h
- *
- * \param iCurrentFrame current frame
- * \param iTrack track to be deleted
- * \param pIState pointer to the state of tracks
- * \param pAnalParams pointer to analysis parameters
- */
-static void DeleteShortTrack(int iCurrentFrame, int iTrack, int *pIState,
- SMS_AnalParams *pAnalParams)
-{
- int iFrame, frame;
-
- for(iFrame = 1; iFrame <= pIState[iTrack]; iFrame++)
- {
- frame = iCurrentFrame - iFrame;
-
- if(frame <= 0)
- return;
-
- pAnalParams->ppFrames[frame]->deterministic.pFSinAmp[iTrack] = 0;
- pAnalParams->ppFrames[frame]->deterministic.pFSinFreq[iTrack] = 0;
- pAnalParams->ppFrames[frame]->deterministic.pFSinPha[iTrack] = 0;
- }
-
- if(pAnalParams->iDebugMode == SMS_DBG_CLEAN_TRAJ ||
- pAnalParams->iDebugMode == SMS_DBG_ALL)
- fprintf(stdout, "deleteShortTrack: track %d, frames %d to %d deleted\n",
- iTrack, pAnalParams->ppFrames[iCurrentFrame - pIState[iTrack]]->iFrameNum,
- pAnalParams->ppFrames[iCurrentFrame-1]->iFrameNum);
-
- /* reset state */
- pIState[iTrack] = -pAnalParams->iMaxSleepingTime;
-}
-
-/*! \brief fill gaps and delete short tracks
- *
- * \param iCurrentFrame current frame number
- * \param pAnalParams pointer to analysis parameters
- */
-void sms_cleanTracks(int iCurrentFrame, SMS_AnalParams *pAnalParams)
-{
- int iTrack, iLength, iFrame;
-
- /* if fundamental and first partial are short, delete everything */
- if((pAnalParams->iFormat == SMS_FORMAT_H || pAnalParams->iFormat == SMS_FORMAT_HP) &&
- pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinAmp[0] == 0 &&
- pAnalParams->guideStates[0] > 0 &&
- pAnalParams->guideStates[0] < pAnalParams->iMinTrackLength &&
- pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinAmp[1] == 0 &&
- pAnalParams->guideStates[1] > 0 &&
- pAnalParams->guideStates[1] < pAnalParams->iMinTrackLength)
- {
- iLength = pAnalParams->guideStates[0];
- for(iTrack = 0; iTrack < pAnalParams->nGuides; iTrack++)
- {
- for(iFrame = 1; iFrame <= iLength; iFrame++)
- {
- if((iCurrentFrame - iFrame) >= 0)
- {
- pAnalParams->ppFrames[iCurrentFrame -
- iFrame]->deterministic.pFSinAmp[iTrack] = 0;
- pAnalParams->ppFrames[iCurrentFrame -
- iFrame]->deterministic.pFSinFreq[iTrack] = 0;
- pAnalParams->ppFrames[iCurrentFrame -
- iFrame]->deterministic.pFSinPha[iTrack] = 0;
- }
- }
- pAnalParams->guideStates[iTrack] = -pAnalParams->iMaxSleepingTime;
- }
- if(pAnalParams->iDebugMode == SMS_DBG_CLEAN_TRAJ ||
- pAnalParams->iDebugMode == SMS_DBG_ALL)
- {
- fprintf(stdout, "cleanTrack: frame %d to frame %d deleted\n",
- pAnalParams->ppFrames[iCurrentFrame-iLength]->iFrameNum,
- pAnalParams->ppFrames[iCurrentFrame-1]->iFrameNum);
- }
-
- return;
- }
-
- /* check every partial individually */
- for(iTrack = 0; iTrack < pAnalParams->nGuides; iTrack++)
- {
- /* track after gap */
- if(pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinAmp[iTrack] != 0)
- {
- if(pAnalParams->guideStates[iTrack] < 0 &&
- pAnalParams->guideStates[iTrack] > -pAnalParams->iMaxSleepingTime)
- FillGap (iCurrentFrame, iTrack, pAnalParams->guideStates, pAnalParams);
- else
- pAnalParams->guideStates[iTrack] =
- (pAnalParams->guideStates[iTrack]<0) ? 1 : pAnalParams->guideStates[iTrack]+1;
- }
- /* gap after track */
- else
- {
- if(pAnalParams->guideStates[iTrack] > 0 &&
- pAnalParams->guideStates[iTrack] < pAnalParams->iMinTrackLength)
- DeleteShortTrack (iCurrentFrame, iTrack, pAnalParams->guideStates, pAnalParams);
- else
- pAnalParams->guideStates[iTrack] =
- (pAnalParams->guideStates[iTrack]>0) ? -1 : pAnalParams->guideStates[iTrack]-1;
- }
- }
- return;
-}
-
-/*! \brief scale deterministic magnitude if synthesis is larger than original
- *
- * \param pFSynthBuffer synthesis buffer
- * \param pFOriginalBuffer original sound
- * \param pFSinAmp magnitudes to be scaled
- * \param pAnalParams pointer to analysis parameters
- * \param nTrack number of tracks
- */
-void sms_scaleDet(sfloat *pFSynthBuffer, sfloat *pFOriginalBuffer,
- sfloat *pFSinAmp, SMS_AnalParams *pAnalParams, int nTrack)
-{
- sfloat fOriginalMag = 0, fSynthesisMag = 0;
- sfloat fCosScaleFactor;
- int iTrack, i;
-
- /* get sound energy */
- for(i = 0; i < pAnalParams->sizeHop; i++)
- {
- fOriginalMag += fabs(pFOriginalBuffer[i]);
- fSynthesisMag += fabs(pFSynthBuffer[i]);
- }
-
- /* if total energy of deterministic sound is larger than original,
- scale deterministic representation */
- if(fSynthesisMag > (1.5 * fOriginalMag))
- {
- fCosScaleFactor = fOriginalMag / fSynthesisMag;
-
- if(pAnalParams->iDebugMode == SMS_DBG_CLEAN_TRAJ ||
- pAnalParams->iDebugMode == SMS_DBG_ALL)
- fprintf(stdout, "Frame %d: magnitude scaled by %f\n",
- pAnalParams->ppFrames[0]->iFrameNum, fCosScaleFactor);
-
- for(iTrack = 0; iTrack < nTrack; iTrack++)
- if(pFSinAmp[iTrack] > 0)
- pFSinAmp[iTrack] = sms_magToDB(sms_dBToMag(pFSinAmp[iTrack]) * fCosScaleFactor);
- }
-}
-
diff --git a/sms/harmDetection.c b/sms/harmDetection.c
deleted file mode 100644
index bf99729..0000000
--- a/sms/harmDetection.c
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG)
- * UNIVERSITAT POMPEU FABRA
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-/*! \file harmDetection.c
- * \brief Detection of a given harmonic
- */
-
-#include "sms.h"
-
-#define N_FUND_HARM 6 /*!< number of harmonics to use for fundamental detection */
-#define N_HARM_PEAKS 4 /*!< number of peaks to check as possible ref harmonics */
-#define FREQ_DEV_THRES .07 /*!< threshold for deviation from perfect harmonics */
-#define MAG_PERC_THRES .6 /*!< threshold for magnitude of harmonics
- with respect to the total magnitude */
-#define HARM_RATIO_THRES .8 /*!< threshold for percentage of harmonics found */
-
-/*! \brief get closest peak to a given harmonic of the possible fundamental
- *
- * \param iPeakCandidate peak number of possible fundamental
- * \param nHarm number of harmonic
- * \param pSpectralPeaks pointer to all the peaks
- * \param pICurrentPeak pointer to the last peak taken
- * \param iRefHarmonic reference harmonic number
- * \return the number of the closest peak or -1 if not found
- */
-static int GetClosestPeak(int iPeakCandidate, int nHarm, SMS_Peak *pSpectralPeaks,
- int *pICurrentPeak, int iRefHarmonic, int maxPeaks)
-{
- int iBestPeak = *pICurrentPeak + 1;
- int iNextPeak = iBestPeak + 1;
-
- if((iBestPeak >= maxPeaks) || (iNextPeak >= maxPeaks))
- return -1;
-
- sfloat fBestPeakFreq = pSpectralPeaks[iBestPeak].fFreq,
- fHarmFreq = (1 + nHarm) * pSpectralPeaks[iPeakCandidate].fFreq / iRefHarmonic,
- fMinDistance = fabs(fHarmFreq - fBestPeakFreq),
- fMaxPeakDev = .5 * fHarmFreq / (nHarm + 1),
- fDistance = 0.0;
-
- fDistance = fabs(fHarmFreq - pSpectralPeaks[iNextPeak].fFreq);
- while((fDistance < fMinDistance) && (iNextPeak < maxPeaks - 1))
- {
- iBestPeak = iNextPeak;
- fMinDistance = fDistance;
- iNextPeak++;
- fDistance = fabs(fHarmFreq - pSpectralPeaks[iNextPeak].fFreq);
- }
-
- /* make sure the chosen peak is good */
- fBestPeakFreq = pSpectralPeaks[iBestPeak].fFreq;
-
- /* if best peak is not in the range */
- if(fabs(fBestPeakFreq - fHarmFreq) > fMaxPeakDev)
- return -1;
-
- *pICurrentPeak = iBestPeak;
- return iBestPeak;
-}
-
-/*! \brief checks if peak is substantial
- *
- * check if peak is larger enough to be considered a fundamental
- * without any further testing or too small to be considered
- *
-
- * \param fRefHarmMag magnitude of possible fundamental
- * \param pSpectralPeaks all the peaks
- * \param nCand number of existing candidates
- * \param fRefHarmMagDiffFromMax value to judge the peak based on the difference of its magnitude compared to the reference
- * \return 1 if big peak, -1 if too small , otherwise return 0
- */
-static int ComparePeak(sfloat fRefHarmMag, SMS_Peak *pSpectralPeaks, int nCand,
- sfloat fRefHarmMagDiffFromMax, int maxPeaks)
-{
- int iPeak;
- sfloat fMag = 0;
-
- /* if peak is very large take it as possible fundamental */
- if(nCand == 0 && fRefHarmMag > 80.)
- return 1;
-
- /* compare the peak with the first N_FUND_HARM peaks */
- /* if too small forget it */
- for(iPeak = 0; (iPeak < N_FUND_HARM) && (iPeak < maxPeaks); iPeak++)
- {
- if(pSpectralPeaks[iPeak].fMag > 0 &&
- fRefHarmMag - pSpectralPeaks[iPeak].fMag < - fRefHarmMagDiffFromMax)
- return -1;
- }
-
- /* if it is much bigger than rest take it */
- for(iPeak = 0; (iPeak < N_FUND_HARM) && (iPeak < maxPeaks); iPeak++)
- {
- fMag = pSpectralPeaks[iPeak].fMag;
- if(fMag <= 0 ||
- ((fMag != fRefHarmMag) && (nCand > 0) && (fRefHarmMag - fMag < 30.0)) ||
- ((nCand == 0) && (fRefHarmMag - fMag < 15.0)))
- return 0;
- }
- return 1;
-}
-
-
-/*! \brief check if the current peak is a harmonic of one of the candidates
- *
- * \param fFundFreq frequency of peak to be tested
- * \param pCHarmonic all candidates accepted
- * \param nCand location of las candidate
- * \return 1 if it is a harmonic, 0 if it is not
- */
-static int CheckIfHarmonic(sfloat fFundFreq, SMS_HarmCandidate *pCHarmonic, int nCand)
-{
- int iPeak;
-
- /* go through all the candidates checking if they are fundamentals
- * of the peak to be considered */
- for(iPeak = 0; iPeak < nCand; iPeak++)
- {
- if(fabs(floor((double)(fFundFreq / pCHarmonic[iPeak].fFreq) + .5) -
- (fFundFreq / pCHarmonic[iPeak].fFreq)) <= .1)
- return 1;
- }
- return 0;
-}
-
-
-/*! \brief consider a peak as a possible candidate and give it a weight value,
- *
- * \param iPeak iPeak number to be considered
- * \param pSpectralPeaks all the peaks
- * \param pCHarmonic all the candidates
- * \param nCand candidate number that is to be filled
- * \param pPeakParams analysis parameters
- * \param fRefFundamental previous fundamental
- * \return -1 if not good enough for a candidate, return 0 if reached
- * the top frequency boundary, return -2 if stop checking because it
- * found a really good one, return 1 if the peak is a good candidate
- */
-
-static int GoodCandidate(int iPeak, int maxPeaks, SMS_Peak *pSpectralPeaks,
- SMS_HarmCandidate *pCHarmonic, int nCand, int soundType, sfloat fRefFundamental,
- sfloat minRefHarmMag, sfloat refHarmMagDiffFromMax, sfloat refHarmonic)
-{
- sfloat fHarmFreq = 0.0,
- fRefHarmFreq = 0.0,
- fRefHarmMag = 0.0,
- fTotalMag = 0.0,
- fTotalDev = 0.0,
- fTotalMaxMag = 0.0,
- fAvgMag = 0.0,
- fAvgDev = 0.0,
- fHarmRatio = 0.0;
- int iHarm = 0,
- iChosenPeak = 0,
- iPeakComp = 0,
- iCurrentPeak = 0,
- nGoodHarm = 0,
- i = 0;
-
- fRefHarmFreq = fHarmFreq = pSpectralPeaks[iPeak].fFreq;
-
- fTotalDev = 0;
- fRefHarmMag = pSpectralPeaks[iPeak].fMag;
- fTotalMag = fRefHarmMag;
-
- /* check if magnitude is big enough */
- /*! \bug sfloat comparison to 0 */
- if(((fRefFundamental > 0) && (fRefHarmMag < minRefHarmMag - 10)) ||
- ((fRefFundamental <= 0) && (fRefHarmMag < minRefHarmMag)))
- return -1;
-
- /* check that it is not a harmonic of a previous candidate */
- if(nCand > 0 &&
- CheckIfHarmonic(fRefHarmFreq / refHarmonic, pCHarmonic, nCand))
- return -1;
-
- /* check if it is very big or very small */
- iPeakComp = ComparePeak(fRefHarmMag, pSpectralPeaks, nCand, refHarmMagDiffFromMax, maxPeaks);
-
- /* too small */
- if(iPeakComp == -1)
- return -1;
- /* very big */
- else if(iPeakComp == 1)
- {
- pCHarmonic[nCand].fFreq = fRefHarmFreq;
- pCHarmonic[nCand].fMag = fRefHarmMag;
- pCHarmonic[nCand].fMagPerc = 1;
- pCHarmonic[nCand].fFreqDev = 0;
- pCHarmonic[nCand].fHarmRatio = 1;
- return -2;
- }
-
- /* get a weight on the peak by comparing its harmonic series */
- /* with the existing peaks */
- if(soundType != SMS_SOUND_TYPE_NOTE)
- {
- fHarmFreq = fRefHarmFreq;
- iCurrentPeak = iPeak;
- nGoodHarm = 0;
- for(iHarm = refHarmonic; (iHarm < N_FUND_HARM) && (iHarm < maxPeaks); iHarm++)
- {
- fHarmFreq += fRefHarmFreq / refHarmonic;
- iChosenPeak = GetClosestPeak(iPeak, iHarm, pSpectralPeaks,
- &iCurrentPeak, refHarmonic,
- maxPeaks);
- if(iChosenPeak > 0)
- {
- fTotalDev += fabs(fHarmFreq - pSpectralPeaks[iChosenPeak].fFreq) /
- fHarmFreq;
- fTotalMag += pSpectralPeaks[iChosenPeak].fMag;
- nGoodHarm++;
- }
- }
-
- for(i = 0; i <= iCurrentPeak; i++)
- fTotalMaxMag += pSpectralPeaks[i].fMag;
-
- fAvgDev = fTotalDev / (iHarm + 1);
- fAvgMag = fTotalMag / fTotalMaxMag;
- fHarmRatio = (sfloat)nGoodHarm / (N_FUND_HARM - 1);
-
- if(fRefFundamental > 0)
- {
- if(fAvgDev > FREQ_DEV_THRES || fAvgMag < MAG_PERC_THRES - .1 ||
- fHarmRatio < HARM_RATIO_THRES - .1)
- return -1;
- }
- else
- {
- if(fAvgDev > FREQ_DEV_THRES || fAvgMag < MAG_PERC_THRES ||
- fHarmRatio < HARM_RATIO_THRES)
- return -1;
- }
- }
-
- pCHarmonic[nCand].fFreq = fRefHarmFreq;
- pCHarmonic[nCand].fMag = fRefHarmMag;
- pCHarmonic[nCand].fMagPerc = fAvgMag;
- pCHarmonic[nCand].fFreqDev = fAvgDev;
- pCHarmonic[nCand].fHarmRatio = fHarmRatio;
-
- return 1;
-}
-
-/*! \brief choose the best fundamental out of all the candidates
- *
- * \param pCHarmonic array of candidates
- * \param iRefHarmonic reference harmonic number
- * \param nGoodPeaks number of candiates
- * \param fPrevFund reference fundamental
- * \return the integer number of the best candidate
- */
-static int GetBestCandidate(SMS_HarmCandidate *pCHarmonic,
- int iRefHarmonic, int nGoodPeaks, sfloat fPrevFund)
-{
- int iBestCandidate = 0, iPeak;
- sfloat fBestFreq, fHarmFreq, fDev;
-
- /* if a fundamental existed in previous frame take the closest candidate */
- if(fPrevFund > 0)
- {
- for(iPeak = 1; iPeak < nGoodPeaks; iPeak++)
- {
- if(fabs(fPrevFund - pCHarmonic[iPeak].fFreq / iRefHarmonic) <
- fabs(fPrevFund - pCHarmonic[iBestCandidate].fFreq / iRefHarmonic))
- iBestCandidate = iPeak;
- }
- }
- else
- {
- /* try to find the best candidate */
- for(iPeak = 1; iPeak < nGoodPeaks; iPeak++)
- {
- fBestFreq = pCHarmonic[iBestCandidate].fFreq / iRefHarmonic;
- fHarmFreq = fBestFreq * floor(.5 +
- (pCHarmonic[iPeak].fFreq / iRefHarmonic) /
- fBestFreq);
- fDev = fabs(fHarmFreq - (pCHarmonic[iPeak].fFreq / iRefHarmonic)) / fHarmFreq;
-
- /* if candidate is far from harmonic from best candidate and
- * bigger, take it */
- if(fDev > .2 &&
- pCHarmonic[iPeak].fMag > pCHarmonic[iBestCandidate].fMag)
- iBestCandidate = iPeak;
- /* if frequency deviation is much smaller, take it */
- else if(pCHarmonic[iPeak].fFreqDev < .2 * pCHarmonic[iBestCandidate].fFreqDev)
- iBestCandidate = iPeak;
- /* if freq. deviation is smaller and bigger amplitude, take it */
- else if(pCHarmonic[iPeak].fFreqDev < pCHarmonic[iBestCandidate].fFreqDev &&
- pCHarmonic[iPeak].fMagPerc > pCHarmonic[iBestCandidate].fMagPerc &&
- pCHarmonic[iPeak].fMag > pCHarmonic[iBestCandidate].fMag)
- iBestCandidate = iPeak;
- }
- }
- return iBestCandidate;
-}
-
-/*! \brief main harmonic detection function
- *
- * find a given harmonic peak from a set of spectral peaks,
- * put the frequency of the fundamental in the current frame
- *
- * \param pFrame pointer to current frame
- * \param fRefFundamental frequency of previous frame
- * \param pPeakParams pointer to analysis parameters
- * \todo is it possible to use pSpectralPeaks instead of SMS_AnalFrame?
- * \todo move pCHarmonic array to SMS_AnalFrame structure
- - this will allow for analysis of effectiveness from outside this file
- * This really should only be for sms_analyzeFrame
- */
-sfloat sms_harmDetection(int numPeaks, SMS_Peak* spectralPeaks, sfloat refFundamental,
- sfloat refHarmonic, sfloat lowestFreq, sfloat highestFreq,
- int soundType, sfloat minRefHarmMag, sfloat refHarmMagDiffFromMax)
-{
- int iPeak = -1, nGoodPeaks = 0, iCandidate, iBestCandidate;
- sfloat peakFreq=0;
- SMS_HarmCandidate pCHarmonic[N_HARM_PEAKS];
-
- /* find all possible candidates to use as harmonic reference */
- lowestFreq = lowestFreq * refHarmonic;
- highestFreq = highestFreq * refHarmonic;
-
- while((peakFreq < highestFreq) && (iPeak < numPeaks - 1))
- {
- iPeak++;
- peakFreq = spectralPeaks[iPeak].fFreq;
- if(peakFreq > highestFreq)
- break;
-
- /* no more peaks */
- if(spectralPeaks[iPeak].fMag <= 0) /*!< \bug sfloat comparison to zero */
- break;
-
- /* peak too low */
- if(peakFreq < lowestFreq)
- continue;
-
- /* if previous fundamental look only around it */
- if(refFundamental > 0 &&
- fabs(peakFreq - (refHarmonic * refFundamental)) / refFundamental > .5)
- continue;
-
- iCandidate = GoodCandidate(iPeak, numPeaks, spectralPeaks, pCHarmonic,
- nGoodPeaks, soundType, refFundamental,
- minRefHarmMag, refHarmMagDiffFromMax, refHarmonic);
-
- /* good candiate found */
- if(iCandidate == 1)
- nGoodPeaks++;
-
- /* a perfect candiate found */
- else if(iCandidate == -2)
- {
- nGoodPeaks++;
- break;
- }
- }
-
- /* if no candidate for fundamental, continue */
- if(nGoodPeaks == 0)
- return -1;
- /* if only 1 candidate for fundamental take it */
- else if(nGoodPeaks == 1)
- return pCHarmonic[0].fFreq / refHarmonic;
- /* if more than one candidate choose the best one */
- else
- {
- iBestCandidate = GetBestCandidate(pCHarmonic, refHarmonic, nGoodPeaks, refFundamental);
- return pCHarmonic[iBestCandidate].fFreq / refHarmonic;
- }
-}
diff --git a/sms/modify.c b/sms/modify.c
deleted file mode 100644
index 1afdf82..0000000
--- a/sms/modify.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (c) 2009 John Glover, National University of Ireland, Maynooth
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*! \file modify.c
- * \brief modify sms data
- */
-
-#include "sms.h"
-
-/*! \brief initialize a modifications structure based on an SMS_Header
- *
- * \param params pointer to parameter structure
- * \param header pointer to sms header
- */
-void sms_initModify(SMS_Header *header, SMS_ModifyParams *params)
-{
- static int sizeEnvArray = 0;
- params->maxFreq = header->iMaxFreq;
- params->sizeSinEnv = header->nEnvCoeff;
-
- if(sizeEnvArray < params->sizeSinEnv)
- {
- if(sizeEnvArray != 0) free(params->sinEnv);
- if ((params->sinEnv = (sfloat *) malloc(params->sizeSinEnv * sizeof(sfloat))) == NULL)
- {
- sms_error("could not allocate memory for envelope array");
- return;
- }
- sizeEnvArray = params->sizeSinEnv;
- }
- params->ready = 1;
-}
-
-/*! \brief initialize modification parameters
- *
- * \todo call this from sms_initSynth()? some other mod params are updated there
- *
- * \param params pointer to parameters structure
- */
-void sms_initModifyParams(SMS_ModifyParams *params)
-{
- params->ready = 0;
- params->doResGain = 0;
- params->resGain = 1.;
- params->doTranspose = 0;
- params->transpose = 0;
- params->doSinEnv = 0;
- params->sinEnvInterp = 0.;
- params->sizeSinEnv = 0;
- params->doResEnv = 0;
- params->resEnvInterp = 0.;
- params->sizeResEnv = 0;
-}
-
-/*! \brief free memory allocated during initialization
- *
- * \param params pointer to parameter structure
- */
-void sms_freeModify(SMS_ModifyParams *params)
-{
-}
-
-/*! \brief linear interpolation between 2 spectral envelopes.
- *
- * The values in env2 are overwritten by the new interpolated envelope values.
- */
-void sms_interpEnvelopes(int sizeEnv, sfloat *env1, sfloat *env2, sfloat interpFactor)
-{
- if(sizeEnv <= 0)
- {
- return;
- }
-
- int i;
- sfloat amp1, amp2;
-
- for(i = 0; i < sizeEnv; i++)
- {
- amp1 = env1[i];
- amp2 = env2[i];
- if(amp1 <= 0) amp1 = amp2;
- if(amp2 <= 0) amp2 = amp1;
- env2[i] = amp1 + (interpFactor * (amp2 - amp1));
- }
-}
-
-/*! \brief apply the spectral envelope of 1 sound to another
- *
- * Changes the amplitude of spectral peaks in a target sound (pFreqs, pMags) to match those
- * in the envelope (pCepEnvFreqs, pCepEnvMags) of another, up to a maximum frequency of maxFreq.
- */
-void sms_applyEnvelope(int numPeaks, sfloat *pFreqs, sfloat *pMags, int sizeEnv, sfloat *pEnvMags, int maxFreq)
-{
- if(sizeEnv <= 0 || maxFreq <= 0)
- {
- return;
- }
-
- int i, envPos;
- sfloat frac, binSize = (sfloat)maxFreq / (sfloat)sizeEnv;
-
- for(i = 0; i < numPeaks; i++)
- {
- /* convert peak freqs into bin positions for quicker envelope lookup */
- /* \todo try to remove so many pFreq lookups and get rid of divide */
- pFreqs[i] /= binSize;
-
- /* if current peak is within envelope range, set its mag to the envelope mag */
- if(pFreqs[i] < (sizeEnv-1) && pFreqs[i] > 0)
- {
- envPos = (int)pFreqs[i];
- frac = pFreqs[i] - envPos;
- if(envPos < sizeEnv - 1)
- {
- pMags[i] = ((1.0 - frac) * pEnvMags[envPos]) + (frac * pEnvMags[envPos+1]);
- }
- else
- {
- pMags[i] = pEnvMags[sizeEnv-1];
- }
- }
- else
- {
- pMags[i] = 0;
- }
-
- /* convert back to frequency values */
- pFreqs[i] *= binSize;
- }
-
-}
-
-/*! \brief scale the residual gain factor
- *
- * \param frame pointer to sms data
- * \param gain factor to scale the residual
- */
-void sms_resGain(SMS_Data *frame, sfloat gain)
-{
- int i;
- for( i = 0; i < frame->nCoeff; i++)
- frame->pFStocCoeff[i] *= gain;
-}
-
-
-/*! \brief basic transposition
- * Multiply the frequencies of the deterministic component by a constant
- */
-void sms_transpose(SMS_Data *frame, sfloat transpositionFactor)
-{
- int i;
- for(i = 0; i < frame->nTracks; i++)
- {
- frame->pFSinFreq[i] *= sms_scalarTempered(transpositionFactor);
- }
-}
-
-
-/*! \brief transposition maintaining spectral envelope
- *
- * Multiply the frequencies of the deterministic component by a constant, then change
- * their amplitudes so that the original spectral envelope is maintained
- */
-void sms_transposeKeepEnv(SMS_Data *frame, sfloat transpositionFactor, int maxFreq)
-{
- sms_transpose(frame, transpositionFactor);
- sms_applyEnvelope(frame->nTracks, frame->pFSinFreq, frame->pFSinAmp, frame->nEnvCoeff, frame->pSpecEnv, maxFreq);
-}
-
-/*! \brief modify a frame (SMS_Data object)
- *
- * Performs a modification on a SMS_Data object. The type of modification and any additional
- * parameters are specified in the given SMS_ModifyParams structure.
- */
-void sms_modify(SMS_Data *frame, SMS_ModifyParams *params)
-{
- if(params->doResGain)
- sms_resGain(frame, params->resGain);
-
- if(params->doTranspose)
- sms_transpose(frame, params->transpose);
-
- if(params->doSinEnv)
- {
- if(params->sinEnvInterp < .00001) /* maintain original */
- sms_applyEnvelope(frame->nTracks, frame->pFSinFreq, frame->pFSinAmp,
- frame->nEnvCoeff, frame->pSpecEnv, params->maxFreq);
- else
- {
- if(params->sinEnvInterp > .00001 && params->sinEnvInterp < .99999)
- sms_interpEnvelopes(params->sizeSinEnv, frame->pSpecEnv, params->sinEnv, params->sinEnvInterp);
-
- sms_applyEnvelope(frame->nTracks, frame->pFSinFreq, frame->pFSinAmp,
- params->sizeSinEnv, params->sinEnv, params->maxFreq);
-
- }
- }
-}
-
diff --git a/sms/peakContinuation.c b/sms/peakContinuation.c
deleted file mode 100644
index b61d14e..0000000
--- a/sms/peakContinuation.c
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG)
- * UNIVERSITAT POMPEU FABRA
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-/*! \file peakContinuation.c
- * \brief peak continuation algorithm and functions
- */
-
-#include "sms.h"
-
-/*! guide states */
-#define GUIDE_BEG -2
-#define GUIDE_DEAD -1
-#define GUIDE_ACTIVE 0
-
-/*!< maximum number of peak continuation candidates */
-#define MAX_CONT_CANDIDATES 5
-
-/*! \brief function to get the next closest peak from a guide
- *
- * \param fGuideFreq guide's frequency
- * \param pFFreqDistance distance of last best peak from guide
- * \param pSpectralPeaks array of peaks
- * \param pAnalParams analysis parameters
- * \param fFreqDev maximum deviation from guide
- * \return peak number or -1 if nothing is good
- */
-static int GetNextClosestPeak(sfloat fGuideFreq, sfloat *pFFreqDistance,
- SMS_Peak *pSpectralPeaks, SMS_AnalParams *pAnalParams,
- sfloat fFreqDev)
-{
- int iInitialPeak = SMS_MAX_NPEAKS * fGuideFreq / (pAnalParams->iSamplingRate * .5);
- int iLowPeak, iHighPeak, iChosenPeak = -1;
- sfloat fLowDistance, fHighDistance, fFreq;
-
- if(iInitialPeak >= pAnalParams->maxPeaks)
- iInitialPeak = 0;
- else if(pSpectralPeaks[iInitialPeak].fFreq <= 0)
- iInitialPeak = 0;
-
- /* find a low peak to start */
- fLowDistance = fGuideFreq - pSpectralPeaks[iInitialPeak].fFreq;
- if(floor(fLowDistance) < floor(*pFFreqDistance))
- {
- while(floor(fLowDistance) <= floor(*pFFreqDistance) &&
- iInitialPeak > 0)
- {
- iInitialPeak--;
- fLowDistance = fGuideFreq - pSpectralPeaks[iInitialPeak].fFreq;
- }
- }
- else
- {
- while(floor(fLowDistance) >= floor(*pFFreqDistance) &&
- iInitialPeak < (pAnalParams->maxPeaks-1))
- {
- iInitialPeak++;
- if((fFreq = pSpectralPeaks[iInitialPeak].fFreq) == 0)
- return -1;
- fLowDistance = fGuideFreq - fFreq;
- }
- if(iInitialPeak > 0)
- iInitialPeak--;
- fLowDistance = fGuideFreq - pSpectralPeaks[iInitialPeak].fFreq;
- }
-
- if(floor(fLowDistance) <= floor(*pFFreqDistance) ||
- fLowDistance > fFreqDev)
- iLowPeak = -1;
- else
- iLowPeak = iInitialPeak;
-
- /* find a high peak to finish */
- iHighPeak = iInitialPeak;
- fHighDistance = fGuideFreq - pSpectralPeaks[iHighPeak].fFreq;
- while(floor(fHighDistance) >= floor(-*pFFreqDistance) &&
- iHighPeak < (pAnalParams->maxPeaks - 1))
- {
- iHighPeak++;
- if((fFreq = pSpectralPeaks[iHighPeak].fFreq) == 0)
- {
- iHighPeak = -1;
- break;
- }
- fHighDistance = fGuideFreq - fFreq;
- }
- if(fHighDistance > 0 || fabs(fHighDistance) > fFreqDev ||
- floor(fabs(fHighDistance)) <= floor(*pFFreqDistance))
- iHighPeak = -1;
-
- /* chose between the two extrema */
- if(iHighPeak >= 0 && iLowPeak >= 0)
- {
- if(fabs(fHighDistance) > fLowDistance)
- iChosenPeak = iLowPeak;
- else
- iChosenPeak = iHighPeak;
- }
- else if(iHighPeak < 0 && iLowPeak >= 0)
- iChosenPeak = iLowPeak;
- else if(iHighPeak >= 0 && iLowPeak < 0)
- iChosenPeak = iHighPeak;
- else
- return -1;
-
- *pFFreqDistance = fabs(fGuideFreq - pSpectralPeaks[iChosenPeak].fFreq);
- return iChosenPeak;
-}
-
-/*! \brief choose the best candidate out of all
- *
- * \param pCandidate pointer to all the continuation candidates
- * \param nCandidates number of candidates
- * \param fFreqDev maximum frequency deviation allowed
- * \return the peak number of the best candidate
- */
-static int ChooseBestCand(SMS_ContCandidate *pCandidate, int nCandidates, sfloat fFreqDev)
-{
- int i, iHighestCand, iClosestCand, iBestCand = 0;
- sfloat fMaxMag, fClosestFreq;
-
- /* intial guess */
- iClosestCand = 0;
- fClosestFreq = pCandidate[iClosestCand].fFreqDev;
- iHighestCand = 0;
- fMaxMag = pCandidate[iHighestCand].fMagDev;
-
- /* get the best candidate */
- for (i = 1; i < nCandidates; i++)
- {
- /* look for the one with highest magnitude */
- if (pCandidate[i].fMagDev > fMaxMag)
- {
- fMaxMag = pCandidate[i].fMagDev;
- iHighestCand = i;
- }
- /* look for the closest one to the guide */
- if (pCandidate[i].fFreqDev < fClosestFreq)
- {
- fClosestFreq = pCandidate[i].fFreqDev;
- iClosestCand = i;
- }
- }
- iBestCand = iHighestCand;
-
- /* reconcile the two results */
- if(iBestCand != iClosestCand &&
- fabs(pCandidate[iHighestCand].fFreqDev - fClosestFreq) > fFreqDev / 2)
- iBestCand = iClosestCand;
-
- return pCandidate[iBestCand].iPeak;
-}
-
-/*! \brief check for one guide that has choosen iBestPeak
- *
- * \param iBestPeak choosen peak for a guide
- * \param pGuides array of guides
- * \param nGuides total number of guides
- * \return number of guide that chose the peak, or -1 if none
- */
-static int CheckForConflict(int iBestPeak, SMS_Guide *pGuides, int nGuides)
-{
- int iGuide;
-
- for (iGuide = 0; iGuide < nGuides; iGuide++)
- if (pGuides[iGuide].iPeakChosen == iBestPeak)
- return iGuide;
-
- return -1;
-}
-
-/*! \brief chose the best of the two guides for the conflicting peak
- *
- * \param iConflictingGuide conflicting guide number
- * \param iGuide guide number
- * \param pGuides array of guides
- * \param pSpectralPeaks array of peaks
- * \return number of guide
- */
-static int BestGuide(int iConflictingGuide, int iGuide, SMS_Guide *pGuides,
- SMS_Peak *pSpectralPeaks)
-{
- int iConflictingPeak = pGuides[iConflictingGuide].iPeakChosen;
- sfloat fGuideDistance = fabs(pSpectralPeaks[iConflictingPeak].fFreq -
- pGuides[iGuide].fFreq);
- sfloat fConfGuideDistance = fabs(pSpectralPeaks[iConflictingPeak].fFreq -
- pGuides[iConflictingGuide].fFreq);
-
- if(fGuideDistance > fConfGuideDistance)
- return iConflictingGuide;
- else
- return iGuide;
-}
-
-/*! \brief function to find the best continuation peak for a given guide
- * \param pGuides guide attributes
- * \param iGuide number of guide
- * \param pSpectralPeaks peak values at the current frame
- * \param pAnalParams analysis parameters
- * \param fFreqDev frequency deviation allowed
- * \return the peak number
- */
-int GetBestPeak(SMS_Guide *pGuides, int iGuide, SMS_Peak *pSpectralPeaks,
- SMS_AnalParams *pAnalParams, sfloat fFreqDev)
-{
- int iCand = 0, iPeak, iBestPeak, iConflictingGuide, iWinnerGuide;
- sfloat fGuideFreq = pGuides[iGuide].fFreq,
- fGuideMag = pGuides[iGuide].fMag,
- fMagDistance = 0;
- sfloat fFreqDistance = -1;
- SMS_ContCandidate pCandidate[MAX_CONT_CANDIDATES];
-
- /* find all possible candidates */
- while (iCand < MAX_CONT_CANDIDATES)
- {
- /* find the next best peak */
- if((iPeak = GetNextClosestPeak(fGuideFreq, &fFreqDistance,
- pSpectralPeaks, pAnalParams, fFreqDev)) < 0)
- break;
-
- /* if the peak's magnitude is not too small accept it as */
- /* possible candidate */
- if ((fMagDistance = pSpectralPeaks[iPeak].fMag - fGuideMag) > -20.0)
- {
- pCandidate[iCand].fFreqDev = fabs(fFreqDistance);
- pCandidate[iCand].fMagDev = fMagDistance;
- pCandidate[iCand].iPeak = iPeak;
-
- if(pAnalParams->iDebugMode == SMS_DBG_PEAK_CONT ||
- pAnalParams->iDebugMode == SMS_DBG_ALL)
- fprintf(stdout, "candidate %d: freq %f mag %f\n",
- iCand, pSpectralPeaks[iPeak].fFreq,
- pSpectralPeaks[iPeak].fMag);
- iCand++;
- }
- }
- /* get best candidate */
- if(iCand < 1)
- return 0;
- else if (iCand == 1)
- iBestPeak = pCandidate[0].iPeak;
- else
- iBestPeak = ChooseBestCand (pCandidate, iCand,
- pAnalParams->fFreqDeviation);
-
- if(pAnalParams->iDebugMode == SMS_DBG_PEAK_CONT ||
- pAnalParams->iDebugMode == SMS_DBG_ALL)
- fprintf (stdout, "BestCandidate: freq %f\n",
- pSpectralPeaks[iBestPeak].fFreq);
-
- /* if peak taken by another guide resolve conflict */
- if ((iConflictingGuide = CheckForConflict (iBestPeak, pGuides,
- pAnalParams->nGuides)) >= 0)
- {
- iWinnerGuide = BestGuide (iConflictingGuide, iGuide, pGuides,
- pSpectralPeaks);
- if(pAnalParams->iDebugMode == SMS_DBG_PEAK_CONT ||
- pAnalParams->iDebugMode == SMS_DBG_ALL)
- fprintf (stdout,
- "Conflict: guide: %d (%f), and guide: %d (%f). best: %d\n",
- iGuide, pGuides[iGuide].fFreq,
- iConflictingGuide, pGuides[iConflictingGuide].fFreq,
- iWinnerGuide);
-
- if (iGuide == iWinnerGuide)
- {
- pGuides[iGuide].iPeakChosen = iBestPeak;
- pGuides[iConflictingGuide].iPeakChosen = -1;
- }
- }
- else
- pGuides[iGuide].iPeakChosen = iBestPeak;
-
- return iBestPeak;
-}
-
-/*! \brief function to get the next maximum (magnitude) peak
- * \param pSpectralPeaks array of peaks
- * \param pFCurrentMax last peak maximum
- * \return the number of the maximum peak
- */
-static int GetNextMax(SMS_Peak *pSpectralPeaks, SMS_AnalParams *pAnalParams,
- sfloat *pFCurrentMax)
-{
- sfloat fPeakMag;
- sfloat fMaxMag = 0.;
- int iPeak, iMaxPeak = -1;
-
- for (iPeak = 0; iPeak < pAnalParams->maxPeaks; iPeak++)
- {
- fPeakMag = pSpectralPeaks[iPeak].fMag;
-
- if (fPeakMag == 0)
- break;
-
- if (fPeakMag > fMaxMag && fPeakMag < *pFCurrentMax)
- {
- iMaxPeak = iPeak;
- fMaxMag = fPeakMag;
- }
- }
- *pFCurrentMax = fMaxMag;
- return (iMaxPeak);
-}
-
-/*! \brief function to get a good starting peak for a track
- *
- * \param iGuide current guide
- * \param pGuides array of guides
- * \param nGuides total number of guides
- * \param pSpectralPeaks array of peaks
- * \param pFCurrentMax current peak maximum
- * \return \todo should this return something?
- */
-static int GetStartingPeak(int iGuide, SMS_Guide *pGuides, int nGuides,
- SMS_Peak *pSpectralPeaks, SMS_AnalParams *pAnalParams,
- sfloat *pFCurrentMax)
-{
- int iPeak = -1;
- short peakNotFound = 1;
-
- while (peakNotFound == 1 && *pFCurrentMax > 0)
- {
- /* \todo I don't think this ever returns -1, but check */
- if ((iPeak = GetNextMax(pSpectralPeaks, pAnalParams, pFCurrentMax)) < 0)
- return (-1);
-
- if (CheckForConflict (iPeak, pGuides, nGuides) < 0)
- {
- pGuides[iGuide].iPeakChosen = iPeak;
- pGuides[iGuide].iStatus = GUIDE_BEG;
- pGuides[iGuide].fFreq = pSpectralPeaks[iPeak].fFreq;
- peakNotFound = 0;
- }
- }
- return (1);
-}
-
-/*! \brief function to advance the guides through the next frame
- *
- * the output is the frequency, magnitude, and phase tracks
- *
- * \param iFrame current frame number
- * \param pAnalParams analysis parameters
- * \return error code \see SMS_ERRORS
- */
-int sms_peakContinuation(int iFrame, SMS_AnalParams *pAnalParams)
-{
- int iGuide, iCurrentPeak = -1, iGoodPeak = -1;
- sfloat fFund = pAnalParams->ppFrames[iFrame]->fFundamental,
- fFreqDev = fFund * pAnalParams->fFreqDeviation, fCurrentMax = 1000;
-
- /* update guides with fundamental contribution */
- if(fFund > 0 && (pAnalParams->iFormat == SMS_FORMAT_H ||
- pAnalParams->iFormat == SMS_FORMAT_HP))
- for(iGuide = 0; iGuide < pAnalParams->nGuides; iGuide++)
- pAnalParams->guides[iGuide].fFreq =
- (1 - pAnalParams->fFundContToGuide) * pAnalParams->guides[iGuide].fFreq +
- pAnalParams->fFundContToGuide * fFund * (iGuide + 1);
-
- if(pAnalParams->iDebugMode == SMS_DBG_PEAK_CONT ||
- pAnalParams->iDebugMode == SMS_DBG_ALL)
- fprintf(stdout, "Frame %d Peak Continuation: \n",
- pAnalParams->ppFrames[iFrame]->iFrameNum);
-
- /* continue all guides */
- for(iGuide = 0; iGuide < pAnalParams->nGuides; iGuide++)
- {
- sfloat fPreviousFreq = pAnalParams->ppFrames[iFrame-1]->deterministic.pFSinFreq[iGuide];
-
- /* get the guide value by upgrading the previous guide */
- if(fPreviousFreq > 0)
- pAnalParams->guides[iGuide].fFreq =
- (1 - pAnalParams->fPeakContToGuide) * pAnalParams->guides[iGuide].fFreq +
- pAnalParams->fPeakContToGuide * fPreviousFreq;
-
- if(pAnalParams->iDebugMode == SMS_DBG_PEAK_CONT ||
- pAnalParams->iDebugMode == SMS_DBG_ALL)
- fprintf(stdout, "Guide %d: freq %f, mag %f\n",
- iGuide, pAnalParams->guides[iGuide].fFreq, pAnalParams->guides[iGuide].fMag);
-
- if(pAnalParams->guides[iGuide].fFreq <= 0.0 ||
- pAnalParams->guides[iGuide].fFreq > pAnalParams->fHighestFreq)
- {
- pAnalParams->guides[iGuide].iStatus = GUIDE_DEAD;
- pAnalParams->guides[iGuide].fFreq = 0;
- continue;
- }
-
- pAnalParams->guides[iGuide].iPeakChosen = -1;
-
- if(pAnalParams->iFormat == SMS_FORMAT_IH ||
- pAnalParams->iFormat == SMS_FORMAT_IHP)
- fFreqDev = pAnalParams->guides[iGuide].fFreq * pAnalParams->fFreqDeviation;
-
- /* get the best peak for the guide */
- iGoodPeak =
- GetBestPeak(pAnalParams->guides, iGuide, pAnalParams->ppFrames[iFrame]->pSpectralPeaks,
- pAnalParams, fFreqDev);
- }
-
- /* try to find good peaks for the GUIDE_DEAD guides */
- if(pAnalParams->iFormat == SMS_FORMAT_IH ||
- pAnalParams->iFormat == SMS_FORMAT_IHP)
- for(iGuide = 0; iGuide < pAnalParams->nGuides; iGuide++)
- {
- if(pAnalParams->guides[iGuide].iStatus != GUIDE_DEAD)
- continue;
-
- if(GetStartingPeak(iGuide, pAnalParams->guides, pAnalParams->nGuides,
- pAnalParams->ppFrames[iFrame]->pSpectralPeaks,
- pAnalParams, &fCurrentMax) == -1)
- break;
- }
-
- /* save all the continuation values,
- * assume output tracks are already clear */
- for(iGuide = 0; iGuide < pAnalParams->nGuides; iGuide++)
- {
- if(pAnalParams->guides[iGuide].iStatus == GUIDE_DEAD)
- continue;
-
- if(pAnalParams->iFormat == SMS_FORMAT_IH ||
- pAnalParams->iFormat == SMS_FORMAT_IHP)
- {
- if(pAnalParams->guides[iGuide].iStatus > 0 &&
- pAnalParams->guides[iGuide].iPeakChosen == -1)
- {
- if(pAnalParams->guides[iGuide].iStatus++ > pAnalParams->iMaxSleepingTime)
- {
- pAnalParams->guides[iGuide].iStatus = GUIDE_DEAD;
- pAnalParams->guides[iGuide].fFreq = 0;
- pAnalParams->guides[iGuide].fMag = 0;
- pAnalParams->guides[iGuide].iPeakChosen = -1;
- }
- else
- pAnalParams->guides[iGuide].iStatus++;
- continue;
- }
-
- if(pAnalParams->guides[iGuide].iStatus == GUIDE_ACTIVE &&
- pAnalParams->guides[iGuide].iPeakChosen == -1)
- {
- pAnalParams->guides[iGuide].iStatus = 1;
- continue;
- }
- }
-
- /* if good continuation peak found, save it */
- if((iCurrentPeak = pAnalParams->guides[iGuide].iPeakChosen) >= 0)
- {
- pAnalParams->ppFrames[iFrame]->deterministic.pFSinFreq[iGuide] =
- pAnalParams->ppFrames[iFrame]->pSpectralPeaks[iCurrentPeak].fFreq;
- pAnalParams->ppFrames[iFrame]->deterministic.pFSinAmp[iGuide] =
- pAnalParams->ppFrames[iFrame]->pSpectralPeaks[iCurrentPeak].fMag;
- pAnalParams->ppFrames[iFrame]->deterministic.pFSinPha[iGuide] =
- pAnalParams->ppFrames[iFrame]->pSpectralPeaks[iCurrentPeak].fPhase;
-
- pAnalParams->guides[iGuide].iStatus = GUIDE_ACTIVE;
- pAnalParams->guides[iGuide].iPeakChosen = -1;
- }
- }
- return SMS_OK;
-}
-
diff --git a/sms/peakDetection.c b/sms/peakDetection.c
deleted file mode 100644
index 4015c27..0000000
--- a/sms/peakDetection.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG)
- * UNIVERSITAT POMPEU FABRA
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-/*! \file peakDetection.c
- * \brief peak detection algorithm and functions
- */
-
-#include "sms.h"
-
-/*! \brief function used for the parabolic interpolation of the spectral peaks
- *
- * it performs the interpolation in a log scale and
- * stores the location in pFDiffFromMax and
- *
- * \param fMaxVal value of max bin
- * \param fLeftBinVal value for left bin
- * \param fRightBinVal value for right bin
- * \param pFDiffFromMax location of the tip as the difference from the top bin
- * \return the peak height
- */
-static sfloat PeakInterpolation(sfloat fMaxVal, sfloat fLeftBinVal,
- sfloat fRightBinVal, sfloat *pFDiffFromMax)
-{
- /* get the location of the tip of the parabola */
- *pFDiffFromMax = (.5 * (fLeftBinVal - fRightBinVal) /
- (fLeftBinVal - (2*fMaxVal) + fRightBinVal));
- /* return the value at the tip */
- return fMaxVal - (.25 * (fLeftBinVal - fRightBinVal) * *pFDiffFromMax);
-}
-
-/*! \brief detect the next local maximum in the spectrum
- *
- * stores the value in pFMaxVal
- *
- * \todo export this to sms.h and wrap in pysms
- *
- * \param pFMagSpectrum magnitude spectrum
- * \param iHighBinBound highest bin to search
- * \param pICurrentLoc current bin location
- * \param pFMaxVal value of the maximum found
- * \param fMinPeakMag minimum magnitude to accept a peak
- * \return the bin location of the maximum
- */
-static int FindNextMax(sfloat *pFMagSpectrum, int iHighBinBound,
- int *pICurrentLoc, sfloat *pFMaxVal, sfloat fMinPeakMag)
-{
- int iCurrentBin = *pICurrentLoc;
- sfloat fPrevVal = pFMagSpectrum[iCurrentBin - 1];
- sfloat fCurrentVal = pFMagSpectrum[iCurrentBin];
- sfloat fNextVal = (iCurrentBin >= iHighBinBound) ? 0 : pFMagSpectrum[iCurrentBin + 1];
-
- /* try to find a local maximum */
- while(iCurrentBin <= iHighBinBound)
- {
- if(fCurrentVal > fMinPeakMag &&
- fCurrentVal >= fPrevVal &&
- fCurrentVal >= fNextVal)
- break;
- iCurrentBin++;
- fPrevVal = fCurrentVal;
- fCurrentVal = fNextVal;
- fNextVal = pFMagSpectrum[1+iCurrentBin];
- }
-
- /* save the current location, value of maximum and return */
- /* location of max */
- *pICurrentLoc = iCurrentBin + 1;
- *pFMaxVal = fCurrentVal;
- return iCurrentBin;
-}
-
-/*! \brief function to detect the next spectral peak
- *
- * \param pFMagSpectrum magnitude spectrum
- * \param iHighestBin highest bin to search
- * \param pICurrentLoc current bin location
- * \param pFPeakMag magnitude value of peak
- * \param pFPeakLoc location of peak
- * \param fMinPeakMag minimum magnitude to accept a peak
- * \return 1 if found, 0 if not
- */
-static int FindNextPeak(sfloat *pFMagSpectrum, int iHighestBin,
- int *pICurrentLoc, sfloat *pFPeakMag,
- sfloat *pFPeakLoc, sfloat fMinPeakMag)
-{
- int iPeakBin = 0; /* location of the local peak */
- sfloat fPeakMag = 0; /* value of local peak */
-
- /* keep trying to find a good peak while inside the freq range */
- while((iPeakBin = FindNextMax(pFMagSpectrum, iHighestBin,
- pICurrentLoc, &fPeakMag, fMinPeakMag))
- <= iHighestBin)
- {
- /* get the neighboring samples */
- sfloat fDiffFromMax = 0;
- sfloat fLeftBinVal = pFMagSpectrum[iPeakBin - 1];
- sfloat fRightBinVal = pFMagSpectrum[iPeakBin + 1];
- if(fLeftBinVal <= 0 || fRightBinVal <= 0) //ahah! there you are!
- continue;
- /* interpolate the spectral samples to obtain
- a more accurate magnitude and freq */
- *pFPeakMag = PeakInterpolation(fPeakMag, fLeftBinVal,
- fRightBinVal, &fDiffFromMax);
- *pFPeakLoc = iPeakBin + fDiffFromMax;
- return 1;
- }
- /* if it does not find a peak return 0 */
- return 0;
-}
-
-/*! \brief get the corresponding phase value for a given peak
- *
- * performs linear interpolation for a more accurate phase
-
- * \param pPhaseSpectrum phase spectrum
- * \param fPeakLoc location of peak
- * \return the phase value
- */
-static sfloat GetPhaseVal(sfloat *pPhaseSpectrum, sfloat fPeakLoc)
-{
- int bin = (int)fPeakLoc;
- sfloat fFraction = fPeakLoc - bin,
- fLeftPha = pPhaseSpectrum[bin],
- fRightPha = pPhaseSpectrum[bin+1];
-
- /* check for phase wrapping */
- if(fLeftPha - fRightPha > 1.5 * PI)
- fRightPha += TWO_PI;
- else if(fRightPha - fLeftPha > 1.5 * PI)
- fLeftPha += TWO_PI;
-
- /* return interpolated phase */
- return fLeftPha + fFraction * (fRightPha - fLeftPha);
-}
-
-/*! \brief find the prominent spectral peaks
- *
- * uses a dB spectrum
- *
- * \param sizeSpec size of magnitude spectrum
- * \param pMag pointer to power spectrum
- * \param pPhase pointer to phase spectrum
- * \param pSpectralPeaks pointer to array of peaks
- * \param pAnalParams peak detection parameters
- * \return the number of peaks found
- */
-int sms_detectPeaks(int sizeSpec, sfloat *pMag, sfloat *pPhase,
- SMS_Peak *pSpectralPeaks, SMS_AnalParams *pAnalParams)
-{
- int sizeFft = sizeSpec << 1;
- sfloat fInvSizeFft = 1.0 / sizeFft;
- int iFirstBin = MAX(1, sizeFft * pAnalParams->fLowestFreq / pAnalParams->iSamplingRate);
- int iHighestBin = MIN(sizeSpec-1,
- sizeFft * pAnalParams->fHighestFreq / pAnalParams->iSamplingRate);
- int iPeak = 0;
-
- /* clear peak structure */
- for(iPeak = 0; iPeak < pAnalParams->maxPeaks; iPeak++)
- {
- pSpectralPeaks[iPeak].fFreq = 0.0;
- pSpectralPeaks[iPeak].fMag = 0.0;
- pSpectralPeaks[iPeak].fPhase = 0.0;
- }
-
- /* set starting search values */
- int iCurrentLoc = iFirstBin;
- sfloat fPeakMag = 0.0; /* magnitude of peak */
- sfloat fPeakLoc = 0.0; /* location of peak */
-
- /* find peaks */
- iPeak = 0;
- while((iPeak < pAnalParams->maxPeaks) &&
- (FindNextPeak(pMag, iHighestBin, &iCurrentLoc, &fPeakMag,
- &fPeakLoc, pAnalParams->fMinPeakMag) == 1))
- {
- /* store peak values */
- pSpectralPeaks[iPeak].fFreq = pAnalParams->iSamplingRate * fPeakLoc * fInvSizeFft;
- pSpectralPeaks[iPeak].fMag = fPeakMag;
- pSpectralPeaks[iPeak].fPhase = GetPhaseVal(pPhase, fPeakLoc);
- iPeak++;
- }
-
- /* return the number of peaks found */
- return iPeak;
-}
diff --git a/sms/residual.c b/sms/residual.c
deleted file mode 100644
index 0c720f0..0000000
--- a/sms/residual.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG)
- * UNIVERSITAT POMPEU FABRA
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-/*! \file residual.c
- * \brief main sms_residual() function
- */
-
-#include "sms.h"
-
-/*! \brief get the residual waveform
- *
- * \param sizeWindow size of buffers
- * \param pSynthesis pointer to deterministic component
- * \param pOriginal pointer to original waveform
- * \param pResidual pointer to output residual waveform
- * \param pWindow pointer to windowing array
- * \return residual percentage (0 if residual was not large enough)
- */
-int sms_residual(int sizeWindow, sfloat *pSynthesis, sfloat *pOriginal,
- SMS_ResidualParams* residualParams)
-{
- sfloat fScale = 1.;
- sfloat fCurrentResidualMag = 0.;
- sfloat fCurrentOriginalMag = 0.;
- int i;
-
- /* get residual */
- for(i = 0; i < sizeWindow; i++)
- residualParams->residual[i] = pOriginal[i] - pSynthesis[i];
-
- /* get energy of residual */
- for(i = 0; i < sizeWindow; i++)
- fCurrentResidualMag += (residualParams->residual[i] * residualParams->residual[i]);
-
- /* if residual is big enough compute coefficients */
- if(fCurrentResidualMag)
- {
- /* get energy of original */
- for(i = 0; i < sizeWindow; i++)
- fCurrentOriginalMag += (pOriginal[i] * pOriginal[i]);
-
- residualParams->originalMag =
- .5 * (fCurrentOriginalMag/sizeWindow + residualParams->originalMag);
- residualParams->residualMag =
- .5 * (fCurrentResidualMag/sizeWindow + residualParams->residualMag);
-
- /* scale residual if need to be */
- if(residualParams->residualMag > residualParams->originalMag)
- {
- fScale = residualParams->originalMag / residualParams->residualMag;
- for(i = 0; i < sizeWindow; i++)
- residualParams->residual[i] *= fScale;
- }
-
- return fCurrentResidualMag / fCurrentOriginalMag;
- }
- return 0;
-}
-
diff --git a/sms/sineSynth.c b/sms/sineSynth.c
deleted file mode 100644
index 9882062..0000000
--- a/sms/sineSynth.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG)
- * UNIVERSITAT POMPEU FABRA
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-/*! \file sineSynth.c
- * \brief functions for synthesizing evolving sinusoids
- */
-
-#include "sms.h"
-
-/*! \brief generate a sinusoid given two peaks, current and last
- *
- * it interpolation between phase values and magnitudes
- *
- * \param fFreq current frequency
- * \param fMag current magnitude
- * \param fPhase current phase
- * \param pLastFrame stucture with values from last frame
- * \param pFWaveform pointer to output waveform
- * \param sizeBuffer size of the synthesis buffer
- * \param iTrack current track
- */
-static void SinePhaSynth(sfloat fFreq, sfloat fMag, sfloat fPhase,
- SMS_Data *pLastFrame, sfloat *pFWaveform,
- int sizeBuffer, int iTrack)
-{
- sfloat fMagIncr, fInstMag, fInstPhase, fTmp;
- int iM, i;
- sfloat fAlpha, fBeta, fTmp1, fTmp2;
-
- /* if no mag in last frame copy freq from current and make phase */
- if(pLastFrame->pFSinAmp[iTrack] <= 0)
- {
- pLastFrame->pFSinFreq[iTrack] = fFreq;
- fTmp = fPhase - (fFreq * sizeBuffer);
- pLastFrame->pFSinPha[iTrack] = fTmp - floor(fTmp / TWO_PI) * TWO_PI;
- }
- /* and the other way */
- else if(fMag <= 0)
- {
- fFreq = pLastFrame->pFSinFreq[iTrack];
- fTmp = pLastFrame->pFSinPha[iTrack] +
- (pLastFrame->pFSinFreq[iTrack] * sizeBuffer);
- fPhase = fTmp - floor(fTmp / TWO_PI) * TWO_PI;
- }
-
- /* caculate the instantaneous amplitude */
- fMagIncr = (fMag - pLastFrame->pFSinAmp[iTrack]) / sizeBuffer;
- fInstMag = pLastFrame->pFSinAmp[iTrack];
-
- /* create instantaneous phase from freq. and phase values */
- fTmp1 = fFreq - pLastFrame->pFSinFreq[iTrack];
- fTmp2 = ((pLastFrame->pFSinPha[iTrack] +
- pLastFrame->pFSinFreq[iTrack] * sizeBuffer - fPhase) +
- fTmp1 * sizeBuffer / 2.0) / TWO_PI;
- iM = (int)(fTmp2 + .5);
- fTmp2 = fPhase - pLastFrame->pFSinPha[iTrack] -
- pLastFrame->pFSinFreq[iTrack] * sizeBuffer + TWO_PI * iM;
- fAlpha = (3.0 / (sfloat)(sizeBuffer * sizeBuffer)) *
- fTmp2 - fTmp1 / sizeBuffer;
- fBeta = (-2.0 / ((sfloat) (sizeBuffer * sizeBuffer * sizeBuffer))) *
- fTmp2 + fTmp1 / ((sfloat) (sizeBuffer * sizeBuffer));
-
- for(i=0; i<sizeBuffer; i++)
- {
- fInstMag += fMagIncr;
- fInstPhase = pLastFrame->pFSinPha[iTrack] +
- pLastFrame->pFSinFreq[iTrack] * i +
- fAlpha * i * i + fBeta * i * i * i;
-
- /*pFWaveform[i] += sms_dBToMag(fInstMag) * sms_sine(fInstPhase + PI_2);*/
- pFWaveform[i] += sms_dBToMag(fInstMag) * sinf(fInstPhase + PI_2);
- }
-
- /* save current values into buffer */
- pLastFrame->pFSinFreq[iTrack] = fFreq;
- pLastFrame->pFSinAmp[iTrack] = fMag;
- pLastFrame->pFSinPha[iTrack] = fPhase;
-}
-
-/*! \brief generate a sinusoid given two frames, current and last
- *
- * \param fFreq current frequency
- * \param fMag current magnitude
- * \param pLastFrame stucture with values from last frame
- * \param pFBuffer pointer to output waveform
- * \param sizeBuffer size of the synthesis buffer
- * \param iTrack current track
- */
-static void SineSynth(sfloat fFreq, sfloat fMag, SMS_Data *pLastFrame,
- sfloat *pFBuffer, int sizeBuffer, int iTrack)
-{
- sfloat fMagIncr, fInstMag, fFreqIncr, fInstPhase, fInstFreq;
- int i;
-
- /* if no mag in last frame copy freq from current */
- if(pLastFrame->pFSinAmp[iTrack] <= 0)
- {
- pLastFrame->pFSinFreq[iTrack] = fFreq;
- pLastFrame->pFSinPha[iTrack] = TWO_PI * sms_random();
- }
- /* and the other way */
- else if(fMag <= 0)
- fFreq = pLastFrame->pFSinFreq[iTrack];
-
- /* calculate the instantaneous amplitude */
- fMagIncr = (fMag - pLastFrame->pFSinAmp[iTrack]) / sizeBuffer;
- fInstMag = pLastFrame->pFSinAmp[iTrack];
- /* calculate instantaneous frequency */
- fFreqIncr = (fFreq - pLastFrame->pFSinFreq[iTrack]) / sizeBuffer;
- fInstFreq = pLastFrame->pFSinFreq[iTrack];
- fInstPhase = pLastFrame->pFSinPha[iTrack];
-
- /* generate all the samples */
- for(i = 0; i < sizeBuffer; i++)
- {
- fInstMag += fMagIncr;
- fInstFreq += fFreqIncr;
- fInstPhase += fInstFreq;
- pFBuffer[i] += sms_dBToMag(fInstMag) * sms_sine(fInstPhase);
- }
-
- /* save current values into last values */
- pLastFrame->pFSinFreq[iTrack] = fFreq;
- pLastFrame->pFSinAmp[iTrack] = fMag;
- pLastFrame->pFSinPha[iTrack] = fInstPhase - floor(fInstPhase / TWO_PI) * TWO_PI;
-}
-
-/*! \brief generate all the sinusoids for a given frame
- *
- * \param pSmsData SMS data for current frame
- * \param pFBuffer pointer to output waveform
- * \param sizeBuffer size of the synthesis buffer
- * \param pLastFrame SMS data from last frame
- * \param iSamplingRate sampling rate to synthesize for
- */
-void sms_sineSynthFrame(SMS_Data *pSmsData, sfloat *pFBuffer,
- int sizeBuffer, SMS_Data *pLastFrame,
- int iSamplingRate)
-{
- sfloat fMag, fFreq;
- int i;
- int nTracks = pSmsData->nTracks;
- int iHalfSamplingRate = iSamplingRate >> 1;
-
- /* go through all the tracks */
- for(i = 0; i < nTracks; i++)
- {
- fMag = pSmsData->pFSinAmp[i];
- fFreq = pSmsData->pFSinFreq[i];
-
- /* make that sure transposed frequencies don't alias */
- if(fFreq > iHalfSamplingRate || fFreq < 0)
- fMag = 0;
-
- /* generate sines if there are magnitude values */
- if((fMag > 0) || (pLastFrame->pFSinAmp[i] > 0))
- {
- /* frequency from Hz to radians */
- fFreq = (fFreq == 0) ? 0 : TWO_PI * fFreq / iSamplingRate;
-
- /* \todo make seperate function for SineSynth /wo phase */
- if(pSmsData->pFSinPha == NULL)
- {
- SineSynth(fFreq, fMag, pLastFrame, pFBuffer, sizeBuffer, i);
- }
- else
- {
- SinePhaSynth(fFreq, fMag, pSmsData->pFSinPha[i], pLastFrame,
- pFBuffer, sizeBuffer, i);
- }
- }
- }
-}
diff --git a/sms/sms.c b/sms/sms.c
deleted file mode 100644
index 8501d4d..0000000
--- a/sms/sms.c
+++ /dev/null
@@ -1,1132 +0,0 @@
-/*
- * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG)
- * UNIVERSITAT POMPEU FABRA
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-/*! \file sms.c
- * \brief initialization, free, and debug functions
- */
-
-#include "sms.h"
-#include "SFMT.h" /*!< mersenne twister random number genorator */
-
-char *pChDebugFile = "debug.txt"; /*!< debug text file */
-FILE *pDebug; /*!< pointer to debug file */
-
-static char error_message[256];
-static int error_status = 0;
-static sfloat mag_thresh = .00001; /*!< magnitude threshold for db conversion (-100db)*/
-static sfloat inv_mag_thresh = 100000.; /*!< inv(.00001) */
-static int initIsDone = 0; /* \todo is this variable necessary? */
-
-#define SIZE_TABLES 4096
-#define HALF_MAX 1073741823.5 /*!< half the max of a 32-bit word */
-#define INV_HALF_MAX (1.0 / HALF_MAX)
-#define TWENTY_OVER_LOG10 (20. / LOG10)
-
-/*! \brief initialize global data
- *
- * Currently, just generating the sine and sinc tables.
- * This is necessary before both analysis and synthesis.
- *
- * If using the Mersenne Twister algorithm for random number
- * generation, initialize (seed) it.
- *
- * \return error code \see SMS_MALLOC or SMS_OK in SMS_ERRORS
- */
-int sms_init(void)
-{
- if (!initIsDone)
- {
- initIsDone = 1;
- if(sms_prepSine(SIZE_TABLES))
- {
- sms_error("cannot allocate memory for sine table");
- return -1;
- }
- if(sms_prepSinc(SIZE_TABLES))
- {
- sms_error("cannot allocate memory for sinc table");
- return -1;
- }
-
-#ifdef MERSENNE_TWISTER
- init_gen_rand(1234);
-#endif
- }
-
- return 0;
-}
-
-/*! \brief free global data
- *
- * deallocates memory allocated to global arrays (windows and tables)
- */
-void sms_free()
-{
- initIsDone = 0;
- sms_clearSine();
- sms_clearSinc();
-}
-
-/*! \brief give default values to an SMS_AnalParams struct
- *
- * This will initialize an SMS_AnalParams with values that work
- * for common analyses. It is useful to start with and then
- * adjust the parameters manually to fit a particular sound
- *
- * Certain things are hard coded in here that will have to
- * be updated later (i.e. samplerate), so it is best to call this
- * function first, then fill whatever parameters need to be
- * adjusted.
- *
- * \param pAnalParams pointer to analysis data structure
- */
-void sms_initAnalParams(SMS_AnalParams *pAnalParams)
-{
- int i;
- pAnalParams->iDebugMode = 0;
- pAnalParams->iFormat = SMS_FORMAT_H;
- pAnalParams->iSoundType = SMS_SOUND_TYPE_MELODY;
- pAnalParams->iStochasticType =SMS_STOC_APPROX;
- pAnalParams->iFrameRate = 300;
- pAnalParams->nStochasticCoeff = 128;
- pAnalParams->fLowestFundamental = 50;
- pAnalParams->fHighestFundamental = 1000;
- pAnalParams->fDefaultFundamental = 100;
- pAnalParams->fPeakContToGuide = .4;
- pAnalParams->fFundContToGuide = .5;
- pAnalParams->fFreqDeviation = .45;
- pAnalParams->iSamplingRate = 44100; /* should be set to the real samplingrate with sms_initAnalysis */
- pAnalParams->iDefaultSizeWindow = 1001;
- pAnalParams->windowSize = 0;
- pAnalParams->sizeHop = 110;
- pAnalParams->fSizeWindow = 3.5;
- pAnalParams->nTracks = 60;
- pAnalParams->maxPeaks = 60;
- pAnalParams->nGuides = 100;
- pAnalParams->iCleanTracks = 1;
- pAnalParams->fMinRefHarmMag = 30;
- pAnalParams->fRefHarmMagDiffFromMax = 30;
- pAnalParams->iRefHarmonic = 1;
- pAnalParams->iMinTrackLength = 40; /*!< depends on iFrameRate normally */
- pAnalParams->iMaxSleepingTime = 40; /*!< depends on iFrameRate normally */
- pAnalParams->fLowestFreq = 50.0;
- pAnalParams->fHighestFreq = 12000.;
- pAnalParams->fMinPeakMag = 0.;
- pAnalParams->iAnalysisDirection = SMS_DIR_FWD;
- pAnalParams->iWindowType = SMS_WIN_BH_70;
- pAnalParams->iSizeSound = 0; /*!< no sound yet */
- pAnalParams->nFrames = 0; /*!< no frames yet */
- pAnalParams->minGoodFrames = 3;
- pAnalParams->maxDeviation = 0.01;
- pAnalParams->analDelay = 100;
- pAnalParams->iMaxDelayFrames = MAX(pAnalParams->iMinTrackLength, pAnalParams->iMaxSleepingTime) + 2 +
- (pAnalParams->minGoodFrames + pAnalParams->analDelay);
- pAnalParams->fResidualAccumPerc = 0.;
- pAnalParams->preEmphasis = 1; /*!< perform pre-emphasis by default */
- pAnalParams->preEmphasisLastValue = 0.;
- /* spectral envelope params */
- pAnalParams->specEnvParams.iType = SMS_ENV_NONE; /* turn off enveloping */
- pAnalParams->specEnvParams.iOrder = 25; /* ... but set default params anyway */
- pAnalParams->specEnvParams.fLambda = 0.00001;
- pAnalParams->specEnvParams.iMaxFreq = 0;
- pAnalParams->specEnvParams.nCoeff = 0;
- pAnalParams->specEnvParams.iAnchor = 0; /* not yet implemented */
- pAnalParams->pFrames = NULL;
- /* fft */
- for(i = 0; i < SMS_MAX_SPEC; i++)
- {
- pAnalParams->magSpectrum[i] = 0.0;
- pAnalParams->phaseSpectrum[i] = 0.0;
- pAnalParams->spectrumWindow[i] = 0.0;
- pAnalParams->fftBuffer[i] = 0.0;
- pAnalParams->fftBuffer[i+SMS_MAX_SPEC] = 0.0;
- }
- /* analysis frames */
- pAnalParams->pFrames = NULL;
- pAnalParams->ppFrames = NULL;
- /* residual */
- sms_initResidualParams(&pAnalParams->residualParams);
- /* peak continuation */
- pAnalParams->guideStates = NULL;
- pAnalParams->guides = NULL;
- /* audio input frame */
- for(i = 0; i < SMS_MAX_FRAME_SIZE; i++)
- pAnalParams->inputBuffer[i] = 0.0;
- /* stochastic analysis */
- pAnalParams->stocMagSpectrum = NULL;
- pAnalParams->approxEnvelope = NULL;
- pAnalParams->ppFrames = NULL;
-}
-
-/*! \brief initialize analysis data structure's arrays
- *
- * based on the SMS_AnalParams current settings, this function will
- * initialize the sound, synth, and fft arrays. It is necessary before analysis.
- * there can be multple SMS_AnalParams at the same time
- *
- * \param pAnalParams pointer to analysis paramaters
- * \param pSoundHeader pointer to sound header
- * \return 0 on success, -1 on error
- */
-int sms_initAnalysis(SMS_AnalParams *pAnalParams)
-{
- int i;
- SMS_SndBuffer *pSynthBuf = &pAnalParams->synthBuffer;
- SMS_SndBuffer *pSoundBuf = &pAnalParams->soundBuffer;
-
- /* define the hopsize for each record */
- pAnalParams->sizeHop = (int)(pAnalParams->iSamplingRate /
- (sfloat) pAnalParams->iFrameRate);
-
- /* set the default size window to an odd length */
- pAnalParams->iDefaultSizeWindow =
- (int)((pAnalParams->iSamplingRate / pAnalParams->fDefaultFundamental) *
- pAnalParams->fSizeWindow / 2) * 2 + 1;
-
- int sizeBuffer = (pAnalParams->iMaxDelayFrames * pAnalParams->sizeHop) + SMS_MAX_WINDOW;
-
- /* if storing residual phases, restrict number of stochastic coefficients to the size of the spectrum (sizeHop = 1/2 sizeFft)*/
- if(pAnalParams->iStochasticType == SMS_STOC_IFFT)
- pAnalParams->nStochasticCoeff = sms_power2(pAnalParams->sizeHop);
-
- /* do the same if spectral envelope is to be stored in frequency bins */
- if(pAnalParams->specEnvParams.iType == SMS_ENV_FBINS)
- pAnalParams->specEnvParams.nCoeff = sms_power2(pAnalParams->specEnvParams.iOrder * 2);
- else if(pAnalParams->specEnvParams.iType == SMS_ENV_CEP)
- pAnalParams->specEnvParams.nCoeff = pAnalParams->specEnvParams.iOrder+1;
- /* if specEnvParams.iMaxFreq is still 0, set it to the same as fHighestFreq (normally what you want)*/
- if(pAnalParams->specEnvParams.iMaxFreq == 0)
- pAnalParams->specEnvParams.iMaxFreq = pAnalParams->fHighestFreq;
-
- /*\todo this probably doesn't need env coefficients - they aren't getting used */
- if(sms_allocFrame(&pAnalParams->prevFrame, pAnalParams->nGuides,
- pAnalParams->nStochasticCoeff, 1, pAnalParams->iStochasticType, 0)
- == -1)
- {
- sms_error("Could not allocate memory for prevFrame");
- return -1;
- }
-
- pAnalParams->sizeNextRead = (pAnalParams->iDefaultSizeWindow + 1) * 0.5;
-
- /* sound buffer */
- if((pSoundBuf->pFBuffer = (sfloat *) calloc(sizeBuffer, sizeof(sfloat))) == NULL)
- {
- sms_error("Could not allocate memory for sound buffer");
- return -1;
- }
- pSoundBuf->iMarker = -sizeBuffer;
- pSoundBuf->iFirstGood = sizeBuffer;
- pSoundBuf->sizeBuffer = sizeBuffer;
-
- /* check default fundamental */
- if (pAnalParams->fDefaultFundamental < pAnalParams->fLowestFundamental)
- {
- pAnalParams->fDefaultFundamental = pAnalParams->fLowestFundamental;
- }
- if (pAnalParams->fDefaultFundamental > pAnalParams->fHighestFundamental)
- {
- pAnalParams->fDefaultFundamental = pAnalParams->fHighestFundamental;
- }
-
- /* deterministic synthesis buffer */
- pSynthBuf->sizeBuffer = pAnalParams->sizeHop << 1;
- pSynthBuf->pFBuffer = calloc(pSynthBuf->sizeBuffer, sizeof(sfloat));
- if(pSynthBuf->pFBuffer == NULL)
- {
- sms_error("could not allocate memory");
- return -1;
- }
- pSynthBuf->iMarker = pSynthBuf->sizeBuffer;
- /* buffer of analysis frames */
- pAnalParams->pFrames = (SMS_AnalFrame *)malloc(pAnalParams->iMaxDelayFrames * sizeof(SMS_AnalFrame));
- if(pAnalParams->pFrames == NULL)
- {
- sms_error("could not allocate memory for delay frames");
- return -1;
- }
- pAnalParams->ppFrames = (SMS_AnalFrame **)malloc(pAnalParams->iMaxDelayFrames * sizeof(SMS_AnalFrame *));
- if(pAnalParams->ppFrames == NULL)
- {
- sms_error("could not allocate memory for pointers to delay frames");
- return -1;
- }
-
- /* initialize the frame pointers and allocate memory */
- for(i = 0; i < pAnalParams->iMaxDelayFrames; i++)
- {
- pAnalParams->pFrames[i].iStatus = SMS_FRAME_EMPTY;
- pAnalParams->pFrames[i].iFrameSample = 0;
- pAnalParams->pFrames[i].iFrameSize = 0;
- pAnalParams->pFrames[i].iFrameNum = 0;
- pAnalParams->pFrames[i].pSpectralPeaks =
- (SMS_Peak *)malloc(pAnalParams->maxPeaks * sizeof(SMS_Peak));
- if((pAnalParams->pFrames[i]).pSpectralPeaks == NULL)
- {
- sms_error("could not allocate memory for spectral peaks");
- return -1;
- }
- (pAnalParams->pFrames[i].deterministic).nTracks = pAnalParams->nGuides;
-
- (pAnalParams->pFrames[i].deterministic).pFSinFreq =
- (sfloat *)calloc(pAnalParams->nGuides, sizeof(sfloat));
- if((pAnalParams->pFrames[i].deterministic).pFSinFreq == NULL)
- {
- sms_error("could not allocate memory");
- return -1;
- }
-
- (pAnalParams->pFrames[i].deterministic).pFSinAmp =
- (sfloat *)calloc(pAnalParams->nGuides, sizeof(sfloat));
- if((pAnalParams->pFrames[i].deterministic).pFSinAmp == NULL)
- {
- sms_error("could not allocate memory");
- return -1;
- }
-
- (pAnalParams->pFrames[i].deterministic).pFSinPha =
- (sfloat *)calloc(pAnalParams->nGuides, sizeof(sfloat));
- if((pAnalParams->pFrames[i].deterministic).pFSinPha == NULL)
- {
- sms_error("could not allocate memory");
- return -1;
- }
- pAnalParams->ppFrames[i] = &pAnalParams->pFrames[i];
-
- /* set initial values */
- if(sms_clearAnalysisFrame(i, pAnalParams) < 0)
- {
- sms_error("could not set initial values for analysis frames");
- return -1;
- }
- }
-
- /* memory for residual */
- pAnalParams->residualParams.hopSize = pAnalParams->sizeHop;
- sms_initResidual(&pAnalParams->residualParams);
-
- /* memory for guide states */
- pAnalParams->guideStates = (int *)calloc(pAnalParams->nGuides, sizeof(int));
- if(pAnalParams->guideStates == NULL)
- {
- sms_error("Could not allocate memory for guide states");
- return -1;
- }
-
- /* memory for guides */
- pAnalParams->guides = (SMS_Guide *)malloc(pAnalParams->nGuides * sizeof(SMS_Guide));
- if(pAnalParams->guides == NULL)
- {
- sms_error("Could not allocate memory for guides");
- return -1;
- }
-
- /* initial guide values */
- for (i = 0; i < pAnalParams->nGuides; i++)
- {
- if(pAnalParams->iFormat == SMS_FORMAT_H || pAnalParams->iFormat == SMS_FORMAT_HP)
- {
- pAnalParams->guides[i].fFreq = pAnalParams->fDefaultFundamental * (i + 1);
- }
- else
- {
- pAnalParams->guides[i].fFreq = 0.0;
- }
- pAnalParams->guides[i].fMag = 0.0;
- pAnalParams->guides[i].iPeakChosen = -1;
- pAnalParams->guides[i].iStatus = 0;
- }
-
- /* stochastic analysis */
- pAnalParams->sizeStocMagSpectrum = sms_power2(pAnalParams->residualParams.residualSize) >> 1;
- pAnalParams->stocMagSpectrum = (sfloat *)calloc(pAnalParams->sizeStocMagSpectrum, sizeof(sfloat));
- if(pAnalParams->stocMagSpectrum == NULL)
- {
- sms_error("Could not allocate memory for stochastic magnitude spectrum");
- return -1;
- }
- pAnalParams->approxEnvelope = (sfloat *)calloc(pAnalParams->nStochasticCoeff, sizeof(sfloat));
- if(pAnalParams->approxEnvelope == NULL)
- {
- sms_error("Could not allocate memory for spectral approximation envelope");
- return -1;
- }
-
- return 0;
-}
-
-/*! \brief give default values to an SMS_SynthParams struct
- *
- * This will initialize an SMS_SynthParams with values that work
- * for common analyses. It is useful to start with and then
- * adjust the parameters manually to fit a particular sound
- *
- * \param synthParams pointer to synthesis parameters data structure
- */
-void sms_initSynthParams(SMS_SynthParams *synthParams)
-{
- synthParams->iSamplingRate = 44100;
- synthParams->iOriginalSRate = 44100;
- synthParams->iSynthesisType = SMS_STYPE_ALL;
- synthParams->iDetSynthType = SMS_DET_IFFT;
- synthParams->sizeHop = SMS_MIN_SIZE_FRAME;
- synthParams->origSizeHop = SMS_MIN_SIZE_FRAME;
- synthParams->nTracks = 60;
- synthParams->iStochasticType = SMS_STOC_APPROX;
- synthParams->nStochasticCoeff = 128;
- synthParams->pFDetWindow = NULL;
- synthParams->pFStocWindow = NULL;
- synthParams->pSynthBuff = NULL;
- synthParams->pMagBuff = NULL;
- synthParams->pPhaseBuff = NULL;
- synthParams->pSpectra = NULL;
- synthParams->approxEnvelope = NULL;
- synthParams->deEmphasis = 1; /*!< perform de-emphasis by default */
- synthParams->deEmphasisLastValue = 0;
-}
-
-/*! \brief initialize synthesis data structure's arrays
- *
- * Initialize the synthesis and fft arrays. It is necessary before synthesis.
- * there can be multple SMS_SynthParams at the same time
- * This function also sets some initial values that will create a sane synthesis
- * environment.
- *
- * This function requires an SMS_Header because it may be called to synthesize
- * a stored .sms file, which contains a header with necessary information.
- *
- * \param pSmsHeader pointer to SMS_Header
- * \param pSynthParams pointer to synthesis paramaters
- * \return 0 on success, -1 on error
- */
-int sms_initSynth(SMS_SynthParams *pSynthParams)
-{
- int sizeHop, sizeFft;
-
- /* make sure sizeHop is something to the power of 2 */
- sizeHop = sms_power2(pSynthParams->sizeHop);
- if(sizeHop != pSynthParams->sizeHop)
- {
- printf("Warning: Synthesis hop size (%d) was not a power of two.\n",
- pSynthParams->sizeHop);
- printf(" Changed to %d.\n", sizeHop);
- pSynthParams->sizeHop = sizeHop;
- }
- sizeFft = sizeHop * 2;
-
- /* TODO: check memory allocation */
- pSynthParams->pFStocWindow = (sfloat *)calloc(sizeFft, sizeof(sfloat));
- sms_getWindow(sizeFft, pSynthParams->pFStocWindow, SMS_WIN_HANNING);
- pSynthParams->pFDetWindow = (sfloat *)calloc(sizeFft, sizeof(sfloat));
- sms_getWindow(sizeFft, pSynthParams->pFDetWindow, SMS_WIN_IFFT);
-
- /* allocate memory for analysis data - size of original hopsize
- * previous frame to interpolate from */
- /* \todo why is stoch coeff + 1? */
- sms_allocFrame(&pSynthParams->prevFrame, pSynthParams->nTracks,
- pSynthParams->nStochasticCoeff + 1, 1,
- pSynthParams->iStochasticType, 0);
-
- pSynthParams->pSynthBuff = (sfloat *)calloc(sizeFft, sizeof(sfloat));
- pSynthParams->pMagBuff = (sfloat *)calloc(sizeHop, sizeof(sfloat));
- pSynthParams->pPhaseBuff = (sfloat *)calloc(sizeHop, sizeof(sfloat));
- pSynthParams->pSpectra = (sfloat *)calloc(sizeFft, sizeof(sfloat));
-
- /* approximation envelope */
- pSynthParams->approxEnvelope = (sfloat *)calloc(pSynthParams->nStochasticCoeff, sizeof(sfloat));
- if(pSynthParams->approxEnvelope == NULL)
- {
- sms_error("Could not allocate memory for spectral approximation envelope");
- return -1;
- }
-
- return SMS_OK;
-}
-
-/*! \brief give default values to an SMS_ResidualParams struct
- *
- * \param residualParams pointer to residual data structure
- */
-void sms_initResidualParams(SMS_ResidualParams *residualParams)
-{
- residualParams->samplingRate = 44100;
- residualParams->hopSize = 256;
- residualParams->residualSize = 0;
- residualParams->residual = NULL;
- residualParams->fftWindow = NULL;
- residualParams->ifftWindow = NULL;
- residualParams->windowScale = 0.0;
- residualParams->residualMag = 0.0;
- residualParams->originalMag = 0.0;
- residualParams->nCoeffs = 128;
- residualParams->stocCoeffs = NULL;
- residualParams->sizeStocMagSpectrum = 0;
- residualParams->stocMagSpectrum = NULL;
- residualParams->stocPhaseSpectrum = NULL;
- residualParams->approx = NULL;
- residualParams->approxEnvelope = NULL;
- int i;
- for(i = 0; i < SMS_MAX_SPEC; i++)
- {
- residualParams->fftBuffer[i] = 0.0;
- residualParams->fftBuffer[i+SMS_MAX_SPEC] = 0.0;
- }
-}
-
-/*! \brief initialize residual data structure
- *
- * \param residualParams pointer to synthesis paramaters
- * \return 0 on success, -1 on error
- */
-int sms_initResidual(SMS_ResidualParams *residualParams)
-{
- if(residualParams->hopSize <= 0)
- {
- sms_error("Residual hop size must be a positive integer");
- return -1;
- }
-
- /* residual signal */
- residualParams->residualSize = residualParams->hopSize * 2;
- residualParams->residual = (sfloat *)calloc(residualParams->residualSize, sizeof(sfloat));
- if(residualParams->residual == NULL)
- {
- sms_error("Could not allocate memory for residual");
- return -1;
- }
-
- /* residual fft/ifft windows */
- residualParams->fftWindow = (sfloat *)calloc(residualParams->residualSize, sizeof(sfloat));
- if(residualParams->fftWindow == NULL)
- {
- sms_error("Could not allocate memory for residual FFT window");
- return -1;
- }
- sms_getWindow(residualParams->residualSize, residualParams->fftWindow, SMS_WIN_BH_70);
- sms_scaleWindow(residualParams->residualSize, residualParams->fftWindow);
-
- residualParams->ifftWindow = (sfloat *)calloc(residualParams->residualSize, sizeof(sfloat));
- if(residualParams->ifftWindow == NULL)
- {
- sms_error("Could not allocate memory for residual IFFT window");
- return -1;
- }
- sms_getWindow(residualParams->residualSize, residualParams->ifftWindow, SMS_WIN_HANNING);
- /* compute IFFT window scaling:
- * windows per hop = hop size / window size = 0.5
- * overlap = 50% => 1 window total in each hop/frame
- * => windowScale = window size / sum(window samples) = 1.85
- * for a 1024 sized hamming window
- */
- int i;
- sfloat sum = 0.0;
- for(i = 0; i < residualParams->residualSize; i++)
- sum += residualParams->ifftWindow[i];
- residualParams->windowScale = (sfloat)residualParams->residualSize / sum;
-
- /* stochastic analysis */
- residualParams->stocCoeffs = (sfloat *)calloc(residualParams->nCoeffs, sizeof(sfloat));
- if(residualParams->stocCoeffs == NULL)
- {
- sms_error("Could not allocate memory for stochastic coefficients");
- return -1;
- }
-
- residualParams->sizeStocMagSpectrum = sms_power2(residualParams->residualSize) >> 1;
- residualParams->stocMagSpectrum = (sfloat *)calloc(residualParams->sizeStocMagSpectrum, sizeof(sfloat));
- if(residualParams->stocMagSpectrum == NULL)
- {
- sms_error("Could not allocate memory for stochastic magnitude spectrum");
- return -1;
- }
- residualParams->stocPhaseSpectrum = (sfloat *)calloc(residualParams->sizeStocMagSpectrum, sizeof(sfloat));
- if(residualParams->stocPhaseSpectrum == NULL)
- {
- sms_error("Could not allocate memory for stochastic magnitude spectrum");
- return -1;
- }
-
- residualParams->approx = (sfloat *)calloc(residualParams->residualSize, sizeof(sfloat));
- if(residualParams->approx == NULL)
- {
- sms_error("Could not allocate memory for spectral approximation");
- return -1;
- }
- residualParams->approxEnvelope = (sfloat *)calloc(residualParams->nCoeffs, sizeof(sfloat));
- if(residualParams->approxEnvelope == NULL)
- {
- sms_error("Could not allocate memory for spectral approximation envelope");
- return -1;
- }
-
- return 0;
-}
-
-/*! \brief free residual data
- *
- * frees all the memory allocated to an SMS_ResidualParams by
- * sms_initResidual
- *
- * \param residualParams pointer to residual data structure
- */
-void sms_freeResidual(SMS_ResidualParams *residualParams)
-{
- if(residualParams->residual)
- free(residualParams->residual);
- if(residualParams->fftWindow)
- free(residualParams->fftWindow);
- if(residualParams->ifftWindow)
- free(residualParams->ifftWindow);
- if(residualParams->stocCoeffs)
- free(residualParams->stocCoeffs);
- if(residualParams->stocMagSpectrum)
- free(residualParams->stocMagSpectrum);
- if(residualParams->stocPhaseSpectrum)
- free(residualParams->stocPhaseSpectrum);
- if(residualParams->approx)
- free(residualParams->approx);
- if(residualParams->approxEnvelope)
- free(residualParams->approxEnvelope);
-
- residualParams->residual = NULL;
- residualParams->fftWindow = NULL;
- residualParams->ifftWindow = NULL;
- residualParams->stocCoeffs = NULL;
- residualParams->stocMagSpectrum = NULL;
- residualParams->stocPhaseSpectrum = NULL;
- residualParams->approx = NULL;
- residualParams->approxEnvelope = NULL;
-}
-
-/*! \brief free analysis data
- *
- * frees all the memory allocated to an SMS_AnalParams by
- * sms_initAnalysis
- *
- * \param pAnalParams pointer to analysis data structure
- */
-void sms_freeAnalysis(SMS_AnalParams *pAnalParams)
-{
- if(pAnalParams->pFrames)
- {
- int i;
- for(i = 0; i < pAnalParams->iMaxDelayFrames; i++)
- {
- if((pAnalParams->pFrames[i]).pSpectralPeaks)
- free((pAnalParams->pFrames[i]).pSpectralPeaks);
- if((pAnalParams->pFrames[i].deterministic).pFSinFreq)
- free((pAnalParams->pFrames[i].deterministic).pFSinFreq);
- if((pAnalParams->pFrames[i].deterministic).pFSinAmp)
- free((pAnalParams->pFrames[i].deterministic).pFSinAmp);
- if((pAnalParams->pFrames[i].deterministic).pFSinPha)
- free((pAnalParams->pFrames[i].deterministic).pFSinPha);
- }
- free(pAnalParams->pFrames);
- }
-
- sms_freeFrame(&pAnalParams->prevFrame);
- sms_freeResidual(&pAnalParams->residualParams);
-
- if(pAnalParams->soundBuffer.pFBuffer)
- free(pAnalParams->soundBuffer.pFBuffer);
- if((pAnalParams->synthBuffer).pFBuffer)
- free((pAnalParams->synthBuffer).pFBuffer);
- if(pAnalParams->ppFrames)
- free(pAnalParams->ppFrames);
- if(pAnalParams->guideStates)
- free(pAnalParams->guideStates);
- if(pAnalParams->guides)
- free(pAnalParams->guides);
- if(pAnalParams->stocMagSpectrum)
- free(pAnalParams->stocMagSpectrum);
- if(pAnalParams->approxEnvelope)
- free(pAnalParams->approxEnvelope);
-
- pAnalParams->pFrames = NULL;
- pAnalParams->ppFrames = NULL;
- pAnalParams->soundBuffer.pFBuffer = NULL;
- pAnalParams->synthBuffer.pFBuffer = NULL;
- pAnalParams->guideStates = NULL;
- pAnalParams->guides = NULL;
- pAnalParams->stocMagSpectrum = NULL;
- pAnalParams->approxEnvelope = NULL;
-}
-
-/*! \brief free analysis data
- *
- * frees all the memory allocated to an SMS_SynthParams by
- * sms_initSynthesis
- *
- * \todo is there a way to make sure the plan has been made
- * already? as it is, it crashes if this is called without one
- * \param pSynthParams pointer to synthesis data structure
- */
-void sms_freeSynth(SMS_SynthParams *pSynthParams)
-{
- if(pSynthParams->pFStocWindow)
- free(pSynthParams->pFStocWindow);
- if(pSynthParams->pFDetWindow)
- free(pSynthParams->pFDetWindow);
- if(pSynthParams->pSynthBuff)
- free(pSynthParams->pSynthBuff);
- if(pSynthParams->pSpectra)
- free(pSynthParams->pSpectra);
- if(pSynthParams->pMagBuff)
- free(pSynthParams->pMagBuff);
- if(pSynthParams->pPhaseBuff)
- free(pSynthParams->pPhaseBuff);
- if(pSynthParams->approxEnvelope)
- free(pSynthParams->approxEnvelope);
-
- sms_freeFrame(&pSynthParams->prevFrame);
-}
-
-/*! \brief Allocate memory for an array of spectral peaks
- *
- * Creates memory and sets default values.
- *
- * \param peaks the spectral peaks
- * \param n number of peaks
- * \return 0 on success, -1 on error
- */
-int sms_initSpectralPeaks(SMS_SpectralPeaks* peaks, int n)
-{
- peaks->nPeaks = n;
- peaks->nPeaksFound = 0;
-
- peaks->pSpectralPeaks = (SMS_Peak *)malloc(n * sizeof(SMS_Peak));
- if(peaks->pSpectralPeaks == NULL)
- {
- sms_error("could not allocate memory for spectral peaks");
- return -1;
- }
- return 0;
-}
-
-/*! \brief Deallocate memory for an array of spectral peaks
- *
- * \param peaks the spectral peaks
- */
-void sms_freeSpectralPeaks(SMS_SpectralPeaks* peaks)
-{
- if(!peaks)
- return;
-
- if(peaks->pSpectralPeaks)
- free(peaks->pSpectralPeaks);
- peaks->nPeaks = 0;
- peaks->nPeaksFound = 0;
-}
-
-/*! \brief set window size for next frame
- *
- * adjusts the next window size to fit the currently detected fundamental
- * frequency, or resets to a default window size if unstable.
- *
- * \param iCurrentFrame number of current frame
- * \param pAnalParams analysis parameters
- * \return the size of the next window in samples
- */
-int sms_sizeNextWindow(int iCurrentFrame, SMS_AnalParams *pAnalParams)
-{
- sfloat fFund = pAnalParams->ppFrames[iCurrentFrame]->fFundamental;
- sfloat fPrevFund = pAnalParams->ppFrames[iCurrentFrame-1]->fFundamental;
- int sizeWindow;
-
- /* if the previous fundamental was stable use it to set the window size */
- if(fPrevFund > 0 && fabs(fPrevFund - fFund) / fFund <= .2)
- sizeWindow = (int)((pAnalParams->iSamplingRate / fFund) *
- pAnalParams->fSizeWindow * .5) * 2 + 1;
- /* otherwise use the default size window */
- else
- sizeWindow = pAnalParams->iDefaultSizeWindow;
-
- if(sizeWindow > SMS_MAX_WINDOW)
- {
- fprintf(stderr, "sms_sizeNextWindow error: sizeWindow (%d) too big, set to %d\n", sizeWindow,
- SMS_MAX_WINDOW);
- sizeWindow = SMS_MAX_WINDOW;
- }
-
- return sizeWindow;
-}
-
-/*! \brief set default values for analysis frame variables
- * \param iCurrentFrame frame number of the current frame
- * \param pAnalParams analysis parameters
- * \return 0 on success, -1 on error
- */
-int sms_clearAnalysisFrame(int iCurrentFrame, SMS_AnalParams *pAnalParams)
-{
- int i;
- SMS_AnalFrame *currentFrame = pAnalParams->ppFrames[iCurrentFrame];
-
- /* clear deterministic data */
- for(i = 0; i < pAnalParams->nGuides; i++)
- {
- currentFrame->deterministic.pFSinFreq[i] = 0.0;
- currentFrame->deterministic.pFSinAmp[i] = 0.0;
- currentFrame->deterministic.pFSinPha[i] = 0.0;
- }
-
- /* clear peaks */
- for(i = 0; i < pAnalParams->maxPeaks; i++)
- {
- currentFrame->pSpectralPeaks[i].fFreq = 0.0;
- currentFrame->pSpectralPeaks[i].fMag = 0.0;
- currentFrame->pSpectralPeaks[i].fPhase = 0.0;
- }
-
- currentFrame->nPeaks = 0;
- currentFrame->fFundamental = 0;
- currentFrame->iFrameNum = 0;
- currentFrame->iFrameSize = 0;
- currentFrame->iFrameSample = 0;
- currentFrame->iStatus = SMS_FRAME_EMPTY;
-
- return 0;
-}
-
-/*! \brief initialize the current frame
- *
- * initializes arrays to zero and sets the correct sample position.
- * Special care is taken at the end the sample source (if there is
- * not enough samples for an entire frame.
- *
- * \param iCurrentFrame frame number of current frame in buffer
- * \param pAnalParams analysis parameters
- * \param sizeWindow size of analysis window
- * \return -1 on error \todo make this return void
- */
-int sms_initFrame(int iCurrentFrame, SMS_AnalParams *pAnalParams, int sizeWindow)
-{
- /* clear deterministic data */
- memset((sfloat *)pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinFreq, 0,
- sizeof(sfloat) * pAnalParams->nGuides);
- memset((sfloat *)pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinAmp, 0,
- sizeof(sfloat) * pAnalParams->nGuides);
- memset((sfloat *)pAnalParams->ppFrames[iCurrentFrame]->deterministic.pFSinPha, 0,
- sizeof(sfloat) * pAnalParams->nGuides);
-
- /* clear peaks */
- int i;
- for(i = 0; i < pAnalParams->maxPeaks; i++)
- {
- pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks[i].fFreq = 0.0;
- pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks[i].fMag = 0.0;
- pAnalParams->ppFrames[iCurrentFrame]->pSpectralPeaks[i].fPhase = 0.0;
- }
-
- pAnalParams->ppFrames[iCurrentFrame]->nPeaks = 0;
- pAnalParams->ppFrames[iCurrentFrame]->fFundamental = 0;
-
- pAnalParams->ppFrames[iCurrentFrame]->iFrameNum =
- pAnalParams->ppFrames[iCurrentFrame - 1]->iFrameNum + 1;
- pAnalParams->ppFrames[iCurrentFrame]->iFrameSize = sizeWindow;
-
- /* if first frame set center of data around 0 */
- if(pAnalParams->ppFrames[iCurrentFrame]->iFrameNum == 1)
- pAnalParams->ppFrames[iCurrentFrame]->iFrameSample = 0;
- /* if not, increment center of data by sizeHop */
- else
- pAnalParams->ppFrames[iCurrentFrame]->iFrameSample =
- pAnalParams->ppFrames[iCurrentFrame-1]->iFrameSample + pAnalParams->sizeHop;
-
- /* check for end of sound */
- if((pAnalParams->ppFrames[iCurrentFrame]->iFrameSample + (sizeWindow+1)/2) >= pAnalParams->iSizeSound
- && pAnalParams->iSizeSound > 0)
- {
- pAnalParams->ppFrames[iCurrentFrame]->iFrameNum = -1;
- pAnalParams->ppFrames[iCurrentFrame]->iFrameSize = 0;
- pAnalParams->ppFrames[iCurrentFrame]->iStatus = SMS_FRAME_END;
- }
- else
- {
- /* good status, ready to start computing */
- pAnalParams->ppFrames[iCurrentFrame]->iStatus = SMS_FRAME_READY;
- }
- return SMS_OK;
-}
-
-/*! \brief get deviation from average fundamental
- *\
- * \param pAnalParams pointer to analysis params
- * \param iCurrentFrame number of current frame
- * \return deviation value or -1 if really off
- */
-sfloat sms_fundDeviation(SMS_AnalParams *pAnalParams, int iCurrentFrame)
-{
- sfloat fFund, fSum = 0, fAverage, fDeviation = 0;
- int i;
-
- if(pAnalParams->minGoodFrames < 1)
- return -1;
-
- /* get the sum of the past few fundamentals */
- for(i = 0; (i < pAnalParams->minGoodFrames) && (iCurrentFrame-i >= 0); i++)
- {
- fFund = pAnalParams->ppFrames[iCurrentFrame-i]->fFundamental;
- if(fFund <= 0)
- return -1;
- else
- fSum += fFund;
- }
-
- /* find the average */
- fAverage = fSum / pAnalParams->minGoodFrames;
-
- /* get the deviation from the average */
- for(i = 0; (i < pAnalParams->minGoodFrames) && (iCurrentFrame-i >= 0); i++)
- fDeviation += fabs(pAnalParams->ppFrames[iCurrentFrame-i]->fFundamental - fAverage);
-
- /* return the deviation from the average */
- return fDeviation / (pAnalParams->minGoodFrames * fAverage);
-}
-
-
-/*! \brief function to create the debug file
- *
- * \param pAnalParams pointer to analysis params
- * \return error value \see SMS_ERRORS
- */
-int sms_createDebugFile(SMS_AnalParams *pAnalParams)
-{
- if((pDebug = fopen(pChDebugFile, "w+")) == NULL)
- {
- fprintf(stderr, "Cannot open debugfile: %s\n", pChDebugFile);
- return SMS_WRERR;
- }
- return SMS_OK;
-}
-
-/*! \brief function to write to the debug file
- *
- * writes three arrays of equal size to a debug text
- * file ("./debug.txt"). There are three arrays for the
- * frequency, magnitude, phase sets.
- *
- * \param pFBuffer1 pointer to array 1
- * \param pFBuffer2 pointer to array 2
- * \param pFBuffer3 pointer to array 3
- * \param sizeBuffer the size of the buffers
- */
-void sms_writeDebugData(sfloat *pFBuffer1, sfloat *pFBuffer2,
- sfloat *pFBuffer3, int sizeBuffer)
-{
- int i;
- static int counter = 0;
-
- for(i = 0; i < sizeBuffer; i++)
- fprintf(pDebug, "%d %d %d %d\n", counter++, (int)pFBuffer1[i],
- (int)pFBuffer2[i], (int)pFBuffer3[i]);
-}
-
-/*! \brief function to write the residual sound file to disk
- *
- * writes the "debug.txt" file to disk and closes the file.
- */
-void sms_writeDebugFile ()
-{
- fclose(pDebug);
-}
-
-/*! \brief convert from magnitude to decibel
- *
- * \param x magnitude (0:1)
- * \return decibel (0: -100)
- */
-sfloat sms_magToDB(sfloat x)
-{
- if(x < mag_thresh)
- return 0.0;
- else
- //return(20. * log10(x * inv_mag_thresh));
- return TWENTY_OVER_LOG10 * log(x * inv_mag_thresh);
- /*return(TWENTY_OVER_LOG10 * log(x));*/
-}
-
-/*! \brief convert from decibel to magnitude
- *
- * \param x decibel (0-100)
- * \return magnitude (0-1)
- */
-sfloat sms_dBToMag(sfloat x)
-{
- if(x < 0.00001)
- return 0.0;
- else
- return mag_thresh * pow(10., x*0.05);
- /*return pow(10.0, x*0.05);*/
-}
-
-/*! \brief convert an array from magnitude to decibel
- *
- * Depends on a linear threshold that indicates the bottom end
- * of the dB scale (magnutdes at this value will convert to zero).
- * \see sms_setMagThresh
- *
- * \param sizeArray size of array
- * \param pArray pointer to array
- */
-void sms_arrayMagToDB(int sizeArray, sfloat *pArray)
-{
- int i;
- for(i = 0; i < sizeArray; i++)
- pArray[i] = sms_magToDB(pArray[i]);
-}
-
-/*! \brief convert and array from decibel (0-100) to magnitude (0-1)
- *
- * depends on the magnitude threshold
- * \see sms_setMagThresh
- *
- * \param sizeArray size of array
- * \param pArray pointer to array
- */
-void sms_arrayDBToMag(int sizeArray, sfloat *pArray)
-{
- int i;
- for(i = 0; i < sizeArray; i++)
- pArray[i] = sms_dBToMag(pArray[i]);
-}
-/*! \brief set the linear magnitude threshold
- *
- * magnitudes below this will go to zero when converted to db.
- * it is limited to 0.00001 (-100db)
- *
- * \param x threshold value
- */
-void sms_setMagThresh(sfloat x)
-{
- /* limit threshold to -100db */
- if(x < 0.00001)
- mag_thresh = 0.00001;
- else
- mag_thresh = x;
- inv_mag_thresh = 1. / mag_thresh;
-}
-
-/*! \brief get a string containing information about the error code
- *
- * \param pErrorMessage pointer to error message string
- */
-void sms_error(char *pErrorMessage)
-{
- strncpy(error_message, pErrorMessage, 256);
- error_status = -1;
-}
-
-/*! \brief check if an error has been reported
- *
- * \return -1 if there is an error, 0 if ok
- */
-int sms_errorCheck()
-{
- return error_status;
-}
-
-/*! \brief get a string containing information about the last error
- *
- * \return pointer to a char string, or NULL if no error
- */
-char* sms_errorString()
-{
- if (error_status)
- {
- error_status = 0;
- return error_message;
- }
- return NULL;
-}
-
-/*! \brief random number genorator
- *
- * \return random number between -1 and 1
- */
-sfloat sms_random()
-{
-#ifdef MERSENNE_TWISTER
- return genrand_real1();
-#else
- return (sfloat)(random() * 2 * INV_HALF_MAX);
-#endif
-}
-
-/*! \brief Root Mean Squared of an array
- *
- * \return RMS energy
- */
-sfloat sms_rms(int sizeArray, sfloat *pArray)
-{
- int i;
- sfloat mean_squared = 0.;
- for(i = 0; i < sizeArray; i++)
- mean_squared += pArray[i] * pArray[i];
-
- return sqrtf(mean_squared / sizeArray);
-}
-
-/*! \brief make sure a number is a power of 2
- *
- * \return a power of two integer >= input value
- */
-int sms_power2(int n)
-{
- int p = -1;
- int N = n;
- while(n)
- {
- n >>= 1;
- p++;
- }
-
- if(1<<p == N) /* n was a power of 2 */
- {
- return N;
- }
- else /* make the new value larger than n */
- {
- p++;
- return 1<<p;
- }
-}
-
-/*! \brief compute a value for scaling frequency based on the well-tempered scale
- *
- * \param x linear frequency value
- * \return (1.059...)^x, where 1.059 is the 12th root of 2 precomputed
- */
-sfloat sms_scalarTempered(sfloat x)
-{
- return powf(1.0594630943592953, x);
-}
-
-/*! \brief scale an array of linear frequencies to the well-tempered scale
- *
- * \param sizeArray size of the array
- * \param pArray pointer to array of frequencies
- */
-void sms_arrayScalarTempered(int sizeArray, sfloat *pArray)
-{
- int i;
- for(i = 0; i < sizeArray; i++)
- pArray[i] = sms_scalarTempered(pArray[i]);
-}
-
diff --git a/sms/sms.h b/sms/sms.h
deleted file mode 100644
index 0613ab3..0000000
--- a/sms/sms.h
+++ /dev/null
@@ -1,723 +0,0 @@
-/*
- * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG)
- * UNIVERSITAT POMPEU FABRA
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-/*! \file sms.h
- * \brief header file to be included in all SMS application
- */
-#ifndef _SMS_H
-#define _SMS_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <memory.h>
-#include <strings.h>
-
-#define SMS_VERSION 1.15 /*!< \brief version control number */
-
-#define SMS_MAX_NPEAKS 400 /*!< \brief maximum number of peaks */
-#define SMS_MAX_FRAME_SIZE 10000 /* maximum size of input frame in samples */
-#define SMS_MAX_SPEC 8192 /*! \brief maximum size for magnitude spectrum */
-
-#define sfloat double
-
-/*! \struct SMS_Header
- * \brief structure for the header of an SMS file
- *
- * This header contains all the information necessary to read an SMS
- * file, prepare memory and synthesizer parameters.
- *
- * The header also contains variable components for additional information
- * that may be stored along with the analysis, such as descriptors or text.
- *
- * The first four members of the Header are necessary in this order to correctly
- * open the .sms files created by this library.
- *
- * iSampleRate contains the samplerate of the analysis signal because it is
- * necessary to know this information to recreate the residual spectrum.
- *
- * In the first release, the descriptors are not used, but are here because they
- * were implemented in previous versions of this code (in the 90's). With time,
- * the documentation will be updated to reflect which members of the header
- * are useful in manipulations, and what functions to use for these manipulatinos
- */
-typedef struct
-{
- int iSmsMagic; /*!< identification constant */
- int iHeadBSize; /*!< size in bytes of header */
- int nFrames; /*!< number of data frames */
- int iFrameBSize; /*!< size in bytes of each data frame */
- int iSamplingRate; /*!< samplerate of analysis signal (necessary to recreate residual spectrum */
- int iFormat; /*!< type of data format \see SMS_Format */
- int nTracks; /*!< number of sinusoidal tracks per frame */
- int iFrameRate; /*!< rate in Hz of data frames */
- int iStochasticType; /*!< type stochastic representation */
- int nStochasticCoeff; /*!< number of stochastic coefficients per frame */
- int iEnvType; /*!< type of envelope representation */
- int nEnvCoeff; /*!< number of cepstral coefficents per frame */
- int iMaxFreq; /*!< maximum frequency of peaks (also corresponds to the last bin of the specEnv */
- sfloat fResidualPerc; /*!< percentage of the residual to original */
-} SMS_Header;
-
-/*! \struct SMS_Data
- * \brief structure with SMS data
- *
- * Here is where all the analysis data ends up. Once data is in here, it is ready
- * for synthesis.
- *
- * It is in one contigous block (pSmsData), the other pointer members point
- * specifically to each component in the block.
- *
- * pFSinPha is optional in the final output, but it is always used to construct the
- * residual signal.
- */
-typedef struct
-{
- sfloat *pSmsData; /*!< pointer to all SMS data */
- int sizeData; /*!< size of all the data */
- sfloat *pFSinFreq; /*!< frequency of sinusoids */
- sfloat *pFSinAmp; /*!< magnitude of sinusoids (stored in dB) */
- sfloat *pFSinPha; /*!< phase of sinusoids */
- int nTracks; /*!< number of sinusoidal tracks in frame */
- sfloat *pFStocGain; /*!< gain of stochastic component */
- int nCoeff; /*!< number of filter coefficients */
- sfloat *pFStocCoeff; /*!< filter coefficients for stochastic component */
- sfloat *pResPhase; /*!< residual phase spectrum */
- int nEnvCoeff; /*!< number of spectral envelope coefficients */
- sfloat *pSpecEnv;
-} SMS_Data;
-
-
-/*! \struct SMS_SndBuffer
- * \brief buffer for sound data
- *
- * This structure is used for holding a buffer of audio data. iMarker is a
- * sample number of the sound source that corresponds to the first sample
- * in the buffer.
- *
- */
-typedef struct
-{
- sfloat *pFBuffer; /*!< buffer for sound data*/
- int sizeBuffer; /*!< size of buffer */
- int iMarker; /*!< sample marker relating to sound source */
- int iFirstGood; /*!< first sample in buffer that is a good one */
-} SMS_SndBuffer;
-
-/*! \struct SMS_Peak
- * \brief structure for sinusodial peak
- */
-typedef struct
-{
- sfloat fFreq; /*!< frequency of peak */
- sfloat fMag; /*!< magnitude of peak */
- sfloat fPhase; /*!< phase of peak */
-} SMS_Peak;
-
-/* a collection of spectral peaks */
-typedef struct
-{
- SMS_Peak *pSpectralPeaks;
- int nPeaks;
- int nPeaksFound;
-} SMS_SpectralPeaks;
-
-/*! \struct SMS_AnalFrame
- * \brief structure to hold an analysis frame
- *
- * This structure has extra information for continuing the analysis,
- * which can be disregarded once the analysis is complete.
- */
-typedef struct
-{
- int iFrameSample; /*!< sample number of the middle of the frame */
- int iFrameSize; /*!< number of samples used in the frame */
- int iFrameNum; /*!< frame number */
- SMS_Peak *pSpectralPeaks; /*!< spectral peaks found in frame */
- int nPeaks; /*!< number of peaks found */
- sfloat fFundamental; /*!< fundamental frequency in frame */
- SMS_Data deterministic; /*!< deterministic data */
- int iStatus; /*!< status of frame enumerated by SMS_FRAME_STATUS \see SMS_FRAME_STATUS */
-} SMS_AnalFrame;
-
-/*! \struct SMS_SEnvParams;
- * \brief structure information and data for spectral enveloping
- *
- */
-typedef struct
-{
- int iType; /*!< envelope type \see SMS_SpecEnvType */
- int iOrder; /*!< ceptrum order */
- int iMaxFreq; /*!< maximum frequency covered by the envelope */
- sfloat fLambda; /*!< regularization factor */
- int nCoeff; /*!< number of coefficients (bins) in the envelope */
- int iAnchor; /*!< whether to make anchor points at DC / Nyquist or not */
-} SMS_SEnvParams;
-
-/*! \struct SMS_Guide
- * \brief information attached to a guide
- *
- * This structure is used to organize the detected peaks into time-varying
- * trajectories, or sinusoidal tracks. As the analysis progresses, previous
- * guides may be updated according to new information in the peak continuation
- * of new frames (two-way mismatch).
- */
-typedef struct
-{
- sfloat fFreq; /*!< frequency of guide */
- sfloat fMag; /*!< magnitude of guide */
- int iStatus; /*!< status of guide: DEAD, SLEEPING, ACTIVE */
- int iPeakChosen; /*!< peak number chosen by the guide */
-} SMS_Guide;
-
-/*! \struct SMS_ResidualParams
- * \brief structure with information for residual functions
- *
- * This structure contains all the necessary settings and memory for residual synthesis.
- *
- */
-typedef struct
-{
- int samplingRate;
- int hopSize;
- int residualSize;
- sfloat *residual;
- sfloat *fftWindow;
- sfloat *ifftWindow;
- sfloat windowScale;
- sfloat residualMag;
- sfloat originalMag;
- int nCoeffs;
- sfloat *stocCoeffs;
- int sizeStocMagSpectrum;
- sfloat *stocMagSpectrum;
- sfloat *stocPhaseSpectrum;
- sfloat *approx;
- sfloat *approxEnvelope;
- sfloat fftBuffer[SMS_MAX_SPEC * 2];
-} SMS_ResidualParams;
-
-/*! \struct SMS_AnalParams
- * \brief structure with useful information for analysis functions
- *
- * Each analysis needs one of these, which contains all settings,
- * sound data, deterministic synthesis data, and every other
- * piece of data that needs to be shared between functions.
- *
- * There is an array of already analyzed frames (hardcoded to 50 right now -
- * \todo make it variable) that are accumulated for good harmonic detection
- * and partial tracking. For instance, once the fundamental frequency of a
- * harmonic signal is located (after a few frames), the harmonic analysis
- * and peak detection/continuation process can be re-computed with more accuracy.
- *
- */
-typedef struct
-{
- int iDebugMode; /*!< debug codes enumerated by SMS_DBG \see SMS_DBG */
- int iFormat; /*!< analysis format code defined by SMS_Format \see SMS_Format */
- int iSoundType; /*!< type of sound to be analyzed \see SMS_SOUND_TYPE */
- int iStochasticType; /*!< type of stochastic model defined by SMS_StocSynthType \see SMS_StocSynthType */
- int iFrameRate; /*!< rate in Hz of data frames */
- int nStochasticCoeff; /*!< number of stochastic coefficients per frame */
- sfloat fLowestFundamental; /*!< lowest fundamental frequency in Hz */
- sfloat fHighestFundamental; /*!< highest fundamental frequency in Hz */
- sfloat fDefaultFundamental; /*!< default fundamental in Hz */
- sfloat fPeakContToGuide; /*!< contribution of previous peak to current guide (between 0 and 1) */
- sfloat fFundContToGuide; /*!< contribution of current fundamental to current guide (between 0 and 1) */
- sfloat fFreqDeviation; /*!< maximum deviation from peak to peak */
- int iSamplingRate; /*! sampling rate of sound to be analyzed */
- int iDefaultSizeWindow; /*!< default size of analysis window in samples */
- int windowSize; /*!< the current window size */
- int sizeHop; /*!< hop size of analysis window in samples */
- sfloat fSizeWindow; /*!< size of analysis window in number of periods */
- int nTracks; /*!< number of sinusoidal tracks in frame */
- int maxPeaks; /*!< maximum number of peaks in a frame */
- int nGuides; /*!< number of guides used for peak detection and continuation \see SMS_Guide */
- int iCleanTracks; /*!< whether or not to clean sinusoidal tracks */
- sfloat fMinRefHarmMag; /*!< minimum magnitude in dB for reference peak */
- sfloat fRefHarmMagDiffFromMax; /*!< maximum magnitude difference from reference peak to highest peak */
- int iRefHarmonic; /*!< reference harmonic to use in the fundamental detection */
- int iMinTrackLength; /*!< minimum length in samples of a given track */
- int iMaxSleepingTime; /*!< maximum sleeping time for a track */
- sfloat fLowestFreq; /*!< lowest frequency to be searched */
- sfloat fHighestFreq; /*!< highest frequency to be searched */
- sfloat fMinPeakMag; /*!< minimum magnitude in dB for a good peak */
- int iAnalysisDirection; /*!< analysis direction, direct or reverse */
- int iSizeSound; /*!< total size of sound to be analyzed in samples */
- int nFrames; /*!< total number of frames that will be analyzed */
- int iWindowType; /*!< type of FFT analysis window \see SMS_WINDOWS */
- int iMaxDelayFrames; /*!< maximum number of frames to delay before peak continuation */
- int minGoodFrames; /*!< minimum number of stable frames for backward search */
- sfloat maxDeviation; /*!< maximum deviation allowed */
- int analDelay; /*! number of frames in the past to be looked in possible re-analyze */
- sfloat fResidualAccumPerc; /*!< accumalitive residual percentage */
- int sizeNextRead; /*!< size of samples to read from sound file next analysis */
- int preEmphasis; /*!< whether or not to perform pre-emphasis */
- sfloat preEmphasisLastValue;
- SMS_Data prevFrame; /*!< the previous analysis frame */
- SMS_SEnvParams specEnvParams; /*!< all data for spectral enveloping */
- SMS_SndBuffer soundBuffer; /*!< signal to be analyzed */
- SMS_SndBuffer synthBuffer; /*!< resynthesized signal used to create the residual */
- SMS_AnalFrame *pFrames; /*!< an array of frames that have already been analyzed */
- sfloat magSpectrum[SMS_MAX_SPEC];
- sfloat phaseSpectrum[SMS_MAX_SPEC];
- sfloat spectrumWindow[SMS_MAX_SPEC];
- sfloat fftBuffer[SMS_MAX_SPEC * 2];
- SMS_ResidualParams residualParams;
- int *guideStates;
- SMS_Guide* guides;
- sfloat inputBuffer[SMS_MAX_FRAME_SIZE];
- int sizeStocMagSpectrum;
- sfloat *stocMagSpectrum;
- sfloat *approxEnvelope; /*!< spectral approximation envelope */
- SMS_AnalFrame **ppFrames; /*!< pointers to the frames analyzed (it is circular-shifted once the array is full */
-} SMS_AnalParams;
-
-/*! \struct SMS_ModifyParams
- *
- * \brief structure with parameters and data that will be used to modify an SMS_Data frame
- */
-typedef struct
-{
- int ready; /*!< a flag to know if the struct has been initialized) */
- int maxFreq; /*!< maximum frequency component */
- int doResGain; /*!< whether or not to scale residual gain */
- sfloat resGain; /*!< residual scale factor */
- int doTranspose; /*!< whether or not to transpose */
- sfloat transpose; /*!< transposition factor */
- int doSinEnv; /*!< whether or not to apply a new spectral envelope to the sin component */
- sfloat sinEnvInterp; /*!< value between 0 (use frame's env) and 1 (use *env). Interpolates inbetween values*/
- int sizeSinEnv; /*!< size of the envelope pointed to by env */
- sfloat *sinEnv; /*!< sinusoidal spectral envelope */
- int doResEnv; /*!< whether or not to apply a new spectral envelope to the residual component */
- sfloat resEnvInterp; /*!< value between 0 (use frame's env) and 1 (use *env). Interpolates inbetween values*/
- int sizeResEnv; /*!< size of the envelope pointed to by resEnv */
- sfloat *resEnv; /*!< residual spectral envelope */
-} SMS_ModifyParams;
-
-/*! \struct SMS_SynthParams
- * \brief structure with information for synthesis functions
- *
- * This structure contains all the necessary settings for different types of synthesis.
- * It also holds arrays for windows and the inverse-FFT, as well as the previously
- * synthesized frame.
- *
- */
-typedef struct
-{
- int iStochasticType; /*!< type of stochastic model defined by SMS_StocSynthType
- \see SMS_StocSynthType */
- int iSynthesisType; /*!< type of synthesis to perform \see SMS_SynthType */
- int iDetSynthType; /*!< method for synthesizing deterministic component \see SMS_DetSynthType */
- int iOriginalSRate; /*!< samplerate of the sound model source (for stochastic synthesis approximation) */
- int iSamplingRate; /*!< synthesis samplerate */
- int sizeHop; /*!< number of samples to synthesis for each frame */
- int origSizeHop; /*!< original number of samples used to create each analysis frame */
- int nTracks;
- int nStochasticCoeff;
- int deEmphasis; /*!< whether or not to perform de-emphasis */
- sfloat deEmphasisLastValue;
- sfloat *pFDetWindow; /*!< array to hold the window used for deterministic synthesis \see SMS_WIN_IFFT */
- sfloat *pFStocWindow; /*!< array to hold the window used for stochastic synthesis (Hanning) */
- sfloat *pSynthBuff; /*!< an array for keeping samples during overlap-add (2x sizeHop) */
- sfloat *pMagBuff; /*!< an array for keeping magnitude spectrum for stochastic synthesis */
- sfloat *pPhaseBuff; /*!< an array for keeping phase spectrum for stochastic synthesis */
- sfloat *pSpectra; /*!< array for in-place FFT transform */
- SMS_Data prevFrame; /*!< previous data frame, for interpolation between frames */
- SMS_ModifyParams modParams; /*!< modification parameters */
- sfloat *approxEnvelope; /*!< spectral approximation envelope */
-} SMS_SynthParams;
-
-/*! \struct SMS_HarmCandidate
- * \brief structure to hold information about a harmonic candidate
- *
- * This structure provides storage for accumimlated statistics when
- * trying to decide which track is the fundamental frequency, during
- * harmonic detection.
- */
-typedef struct
-{
- sfloat fFreq; /*!< frequency of harmonic */
- sfloat fMag; /*!< magnitude of harmonic */
- sfloat fMagPerc; /*!< percentage of magnitude */
- sfloat fFreqDev; /*!< deviation from perfect harmonic */
- sfloat fHarmRatio; /*!< percentage of harmonics found */
-} SMS_HarmCandidate;
-
-/*! \struct SMS_ContCandidate
- * \brief structure to hold information about a continuation candidate
- *
- * This structure holds statistics about the guides, which is used to
- * decide the status of the guide
- */
-typedef struct
-{
- sfloat fFreqDev; /*!< frequency deviation from guide */
- sfloat fMagDev; /*!< magnitude deviation from guide */
- int iPeak; /*!< peak number (organized according to frequency)*/
-} SMS_ContCandidate;
-
-/*! \brief analysis format
- *
- * Is the signal is known to be harmonic, using format harmonic (with out without
- * phase) will give more accuracy to the peak continuation algorithm. If the signal
- * is known to be inharmonic, then it is best to use one of the inharmonic settings
- * to tell the peak continuation algorithm to just look at the peaks and connect them,
- * instead of trying to look for peaks at specific frequencies (harmonic partials).
- */
-enum SMS_Format
-{
- SMS_FORMAT_H, /*!< 0, format harmonic */
- SMS_FORMAT_IH, /*!< 1, format inharmonic */
- SMS_FORMAT_HP, /*!< 2, format harmonic with phase */
- SMS_FORMAT_IHP /*!< 3, format inharmonic with phase */
-};
-
-/*! \brief synthesis types
- *
- * These values are used to determine whether to synthesize
- * both deterministic and stochastic components together,
- * the deterministic component alone, or the stochastic
- * component alone.
- */
-enum SMS_SynthType
-{
- SMS_STYPE_ALL, /*!< both components combined */
- SMS_STYPE_DET, /*!< deterministic component alone */
- SMS_STYPE_STOC /*!< stochastic component alone */
-};
-
-/*! \brief synthesis method for deterministic component
- *
- * There are two options for deterministic synthesis available to the
- * SMS synthesizer. The Inverse Fast Fourier Transform method
- * (IFFT) is more effecient for models with lots of partial tracks, but can
- * possibly smear transients. The Sinusoidal Table Lookup (SIN) can
- * theoritically support faster moving tracks at a higher fidelity, but
- * can consume lots of cpu at varying rates.
- */
-enum SMS_DetSynthType
-{
- SMS_DET_IFFT, /*!< Inverse Fast Fourier Transform (IFFT) */
- SMS_DET_SIN /*!< Sinusoidal Table Lookup (SIN) */
-};
-
-/*! \brief synthesis method for stochastic component
- *
- * Currently, Stochastic Approximation is the only reasonable choice
- * for stochastic synthesis: this method approximates the spectrum of
- * the stochastic component by a specified number of coefficients during
- * analyses, and then approximates another set of coefficients during
- * synthesis in order to fit the specified hopsize. The phases of the
- * coefficients are randomly generated, according to the theory that a
- * stochastic spectrum consists of random phases.
- *
- * The Inverse FFT method is not implemented, but is based on the idea of storing
- * the exact spectrum and phases of the residual component to file. Synthesis
- * could then be an exact reconstruction of the original signal, provided
- * interpolation is not necessary.
- *
- * No stochastic component can also be specified in order to skip the this
- * time consuming process altogether. This is especially useful when
- * performing multiple analyses to fine tune parameters pertaining to the
- * determistic component; once that is achieved, the stochastic component
- * will be much better as well.
- */
-enum SMS_StocSynthType
-{
- SMS_STOC_NONE, /*!< 0, no stochastistic component */
- SMS_STOC_APPROX, /*!< 1, Inverse FFT, magnitude approximation and generated phases */
- SMS_STOC_IFFT /*!< 2, inverse FFT, interpolated spectrum (not used) */
-};
-
-/*! \brief synthesis method for deterministic component
- *
- * There are two options for deterministic synthesis available to the
- * SMS synthesizer. The Inverse Fast Fourier Transform method
- * (IFFT) is more effecient for models with lots of partial tracks, but can
- * possibly smear transients. The Sinusoidal Table Lookup (SIN) can
- * theoritically support faster moving tracks at a higher fidelity, but
- * can consume lots of cpu at varying rates.
- */
-enum SMS_SpecEnvType
-{
- SMS_ENV_NONE, /*!< none */
- SMS_ENV_CEP, /*!< cepstral coefficients */
- SMS_ENV_FBINS /*!< frequency bins */
-};
-
-/*! \brief Error codes returned by SMS file functions */
-/* \todo remove me */
-enum SMS_ERRORS
-{
- SMS_OK, /*!< 0, no error*/
- SMS_NOPEN, /*!< 1, couldn't open file */
- SMS_NSMS , /*!< 2, not a SMS file */
- SMS_MALLOC, /*!< 3, couldn't allocate memory */
- SMS_RDERR, /*!< 4, read error */
- SMS_WRERR, /*!< 5, write error */
- SMS_SNDERR /*!< 6, sound IO error */
-};
-
-/*! \brief debug modes
- *
- * \todo write details about debug files
- */
-enum SMS_DBG
-{
- SMS_DBG_NONE, /*!< 0, no debugging */
- SMS_DBG_DET, /*!< 1, not yet implemented \todo make this show main information to look at for discovering the correct deterministic parameters*/
- SMS_DBG_PEAK_DET, /*!< 2, peak detection function */
- SMS_DBG_HARM_DET, /*!< 3, harmonic detection function */
- SMS_DBG_PEAK_CONT, /*!< 4, peak continuation function */
- SMS_DBG_CLEAN_TRAJ, /*!< 5, clean tracks function */
- SMS_DBG_SINE_SYNTH, /*!< 6, sine synthesis function */
- SMS_DBG_STOC_ANAL, /*!< 7, stochastic analysis function */
- SMS_DBG_STOC_SYNTH, /*!< 8, stochastic synthesis function */
- SMS_DBG_SMS_ANAL, /*!< 9, top level analysis function */
- SMS_DBG_ALL, /*!< 10, everything */
- SMS_DBG_RESIDUAL, /*!< 11, write residual to file */
- SMS_DBG_SYNC, /*!< 12, write original, synthesis and residual to a text file */
-};
-
-#define SMS_MAX_WINDOW 8190 /*!< \brief maximum size for analysis window */
-
-/* \brief type of sound to be analyzed
- *
- * \todo explain the differences between these two
- */
-enum SMS_SOUND_TYPE
-{
- SMS_SOUND_TYPE_MELODY, /*!< 0, sound composed of several notes */
- SMS_SOUND_TYPE_NOTE /*!< 1, sound composed of a single note */
-};
-
-/* \brief direction of analysis
- *
- * Sometimes a signal can be clearer at the end than at
- * the beginning. If the signal is very harmonic at the end then
- * doing the analysis in reverse could provide better results.
- */
-enum SMS_DIRECTION
-{
- SMS_DIR_FWD, /*!< analysis from left to right */
- SMS_DIR_REV /*!< analysis from right to left */
-};
-
-/* \brief window selection
-*/
-enum SMS_WINDOWS
-{
- SMS_WIN_HAMMING, /*!< 0: hamming */
- SMS_WIN_BH_62, /*!< 1: blackman-harris, 62dB cutoff */
- SMS_WIN_BH_70, /*!< 2: blackman-harris, 70dB cutoff */
- SMS_WIN_BH_74, /*!< 3: blackman-harris, 74dB cutoff */
- SMS_WIN_BH_92, /*!< 4: blackman-harris, 92dB cutoff */
- SMS_WIN_HANNING, /*!< 5: hanning */
- SMS_WIN_IFFT /*!< 6: window for deterministic synthesis based on the Inverse-FFT algorithm.
- This is a combination of an inverse Blackman-Harris 92dB and a triangular window. */
-};
-
-/*!
- * \brief frame status
- */
-enum SMS_FRAME_STATUS
-{
- SMS_FRAME_EMPTY,
- SMS_FRAME_READY,
- SMS_FRAME_PEAKS_FOUND,
- SMS_FRAME_FUND_FOUND,
- SMS_FRAME_TRAJ_FOUND,
- SMS_FRAME_CLEANED,
- SMS_FRAME_RECOMPUTED,
- SMS_FRAME_DETER_SYNTH,
- SMS_FRAME_STOC_COMPUTED,
- SMS_FRAME_DONE,
- SMS_FRAME_END
-};
-
-#define SMS_MIN_SIZE_FRAME 128 /* size of synthesis frame */
-
-/*! \defgroup math_macros Math Macros
- * \brief mathematical operations and values needed for functions within
- * this library
- * \{
- */
-#define PI 3.141592653589793238462643 /*!< pi */
-#define TWO_PI 6.28318530717958647692 /*!< pi * 2 */
-#define INV_TWO_PI (1 / TWO_PI) /*!< 1 / ( pi * 2) */
-#define PI_2 1.57079632679489661923 /*!< pi / 2 */
-#define LOG2 0.69314718055994529 /*!< natural logarithm of 2 */
-#define LOG10 2.3025850929940459 /*!< natural logarithm of 10 */
-#define EXP 2.7182818284590451 /*!< Eurler's number */
-
-sfloat sms_magToDB(sfloat x);
-sfloat sms_dBToMag(sfloat x);
-void sms_arrayMagToDB(int sizeArray, sfloat *pArray);
-void sms_arrayDBToMag(int sizeArray, sfloat *pArray);
-void sms_setMagThresh(sfloat x);
-sfloat sms_rms(int sizeArray, sfloat *pArray);
-sfloat sms_sine(sfloat fTheta);
-sfloat sms_sinc(sfloat fTheta);
-sfloat sms_random(void);
-int sms_power2(int n);
-sfloat sms_scalarTempered(sfloat x);
-void sms_arrayScalarTempered(int sizeArray, sfloat *pArray);
-
-#ifndef MAX
-/*! \brief returns the maximum of a and b */
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-#endif
-#ifndef MIN
-/*! \brief returns the minimum of a and b */
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
-/*! \} */
-
-/* function declarations */
-void sms_setPeaks(SMS_AnalParams *pAnalParams, int numamps, sfloat* amps,
- int numfreqs, sfloat* freqs, int numphases, sfloat* phases);
-int sms_findPeaks(int sizeWaveform, sfloat *pWaveform,
- SMS_AnalParams *pAnalParams, SMS_SpectralPeaks *pSpectralPeaks);
-int sms_findPartials(SMS_Data *pSmsFrame, SMS_AnalParams *pAnalParams);
-int sms_findResidual(int sizeSynthesis, sfloat* pSynthesis,
- int sizeOriginal, sfloat* pOriginal,
- SMS_ResidualParams *residualParams);
-void sms_approxResidual(int sizeResidual, sfloat* residual,
- int sizeApprox, sfloat* approx,
- SMS_ResidualParams *residualParams);
-int sms_analyze(int sizeWaveform, sfloat *pWaveform, SMS_Data *pSmsData,
- SMS_AnalParams *pAnalParams);
-void sms_analyzeFrame(int iCurrentFrame, SMS_AnalParams *pAnalParams, sfloat fRefFundamental);
-
-int sms_init();
-void sms_free();
-int sms_initAnalysis(SMS_AnalParams *pAnalParams);
-void sms_initAnalParams(SMS_AnalParams *pAnalParams);
-void sms_initSynthParams(SMS_SynthParams *synthParams);
-int sms_initSynth(SMS_SynthParams *pSynthParams);
-void sms_freeAnalysis(SMS_AnalParams *pAnalParams);
-void sms_freeSynth(SMS_SynthParams *pSynthParams);
-int sms_initSpectralPeaks(SMS_SpectralPeaks* peaks, int n);
-void sms_freeSpectralPeaks(SMS_SpectralPeaks* peaks);
-
-void sms_fillSoundBuffer(int sizeWaveform, sfloat *pWaveform, SMS_AnalParams *pAnalParams);
-void sms_windowCentered(int sizeWindow, sfloat *pWaveform, sfloat *pWindow, int sizeFft, sfloat *pFftBuffer);
-void sms_getWindow(int sizeWindow, sfloat *pWindow, int iWindowType);
-void sms_scaleWindow(int sizeWindow, sfloat *pWindow);
-int sms_spectrum(int sizeWindow, sfloat *pWaveform, sfloat *pWindow, int sizeMag,
- sfloat *pMag, sfloat *pPhase, sfloat *pFftBuffer);
-int sms_spectrumW(int sizeWindow, sfloat *pWaveform, sfloat *pWindow, int sizeMag,
- sfloat *pMag, sfloat *pPhase, sfloat *pFftBuffer);
-int sms_invSpectrum(int sizeWaveform, sfloat *pWaveform, sfloat *pWindow ,
- int sizeMag, sfloat *pMag, sfloat *pPhase, sfloat *pFftBuffer);
-/* \todo remove this once invSpectrum is completely implemented */
-int sms_invQuickSpectrumW(sfloat *pFMagSpectrum, sfloat *pFPhaseSpectrum,
- int sizeFft, sfloat *pFWaveform, int sizeWave,
- sfloat *pFWindow, sfloat *pFftBuffer);
-int sms_spectralApprox(sfloat *pSpec1, int sizeSpec1, int sizeSpec1Used,
- sfloat *pSpec2, int sizeSpec2, int nCoefficients,
- sfloat *envelope);
-int sms_spectrumMag(int sizeWindow, sfloat *pWaveform, sfloat *pWindow,
- int sizeMag, sfloat *pMag, sfloat *pFftBuffer);
-
-void sms_dCepstrum(int sizeCepstrum, sfloat *pCepstrum, int sizeFreq, sfloat *pFreq, sfloat *pMag,
- sfloat fLambda, int iSamplingRate);
-void sms_dCepstrumEnvelope(int sizeCepstrum, sfloat *pCepstrum, int sizeEnv, sfloat *pEnv);
-void sms_spectralEnvelope(SMS_Data *pSmsData, SMS_SEnvParams *pSpecEnvParams);
-
-int sms_sizeNextWindow(int iCurrentFrame, SMS_AnalParams *pAnalParams);
-sfloat sms_fundDeviation(SMS_AnalParams *pAnalParams, int iCurrentFrame);
-int sms_detectPeaks(int sizeSpec, sfloat *pFMag, sfloat *pPhase,
- SMS_Peak *pSpectralPeaks, SMS_AnalParams *pAnalParams);
-sfloat sms_harmDetection(int numPeaks, SMS_Peak* spectralPeaks, sfloat refFundamental,
- sfloat refHarmonic, sfloat lowestFreq, sfloat highestFreq,
- int soundType, sfloat minRefHarmMag, sfloat refHarmMagDiffFromMax);
-int sms_peakContinuation(int iFrame, SMS_AnalParams *pAnalParams);
-
-sfloat sms_preEmphasis(sfloat fInput, SMS_AnalParams *pAnalParams);
-sfloat sms_deEmphasis(sfloat fInput, SMS_SynthParams *pSynthParams);
-
-void sms_cleanTracks(int iCurrentFrame, SMS_AnalParams *pAnalParams);
-void sms_scaleDet(sfloat *pSynthBuffer, sfloat *pOriginalBuffer,
- sfloat *pSinAmp, SMS_AnalParams *pAnalParams, int nTracks);
-
-int sms_prepSine(int nTableSize);
-int sms_prepSinc(int nTableSize);
-void sms_clearSine();
-void sms_clearSinc();
-
-void sms_synthesize(SMS_Data *pSmsFrame, sfloat*pSynthesis, SMS_SynthParams *pSynthParams);
-void sms_sineSynthFrame(SMS_Data *pSmsFrame, sfloat *pBuffer,
- int sizeBuffer, SMS_Data *pLastFrame,
- int iSamplingRate);
-
-void sms_initHeader(SMS_Header *pSmsHeader);
-int sms_getHeader(char *pChFileName, SMS_Header **ppSmsHeader, FILE **ppInputFile);
-void sms_fillHeader(SMS_Header *pSmsHeader, SMS_AnalParams *pAnalParams, char *pProgramString);
-int sms_writeHeader(char *pFileName, SMS_Header *pSmsHeader, FILE **ppOutSmsFile);
-int sms_writeFile(FILE *pSmsFile, SMS_Header *pSmsHeader);
-int sms_initFrame(int iCurrentFrame, SMS_AnalParams *pAnalParams, int sizeWindow);
-int sms_clearAnalysisFrame(int iCurrentFrame, SMS_AnalParams *pAnalParams);
-int sms_allocFrame(SMS_Data *pSmsFrame, int nTracks, int nCoeff,
- int iPhase, int stochType, int nEnvCoeff);
-int sms_allocFrameH(SMS_Header *pSmsHeader, SMS_Data *pSmsFrame);
-int sms_getFrame(FILE *pInputFile, SMS_Header *pSmsHeader, int iFrame, SMS_Data *pSmsFrame);
-int sms_writeFrame(FILE *pSmsFile, SMS_Header *pSmsHeader, SMS_Data *pSmsFrame);
-void sms_freeFrame(SMS_Data *pSmsFrame);
-void sms_clearFrame(SMS_Data *pSmsFrame);
-void sms_copyFrame(SMS_Data *pCopySmsFrame, SMS_Data *pOriginalSmsFrame);
-int sms_frameSizeB(SMS_Header *pSmsHeader);
-
-void sms_initResidualParams(SMS_ResidualParams *residualParams);
-int sms_initResidual(SMS_ResidualParams *residualParams);
-void sms_freeResidual(SMS_ResidualParams *residualParams);
-int sms_residual(int sizeWindow, sfloat *pSynthesis, sfloat *pOriginal,
- SMS_ResidualParams* residualParams);
-void sms_filterHighPass(int sizeResidual, sfloat *pResidual, int iSamplingRate);
-int sms_stocAnalysis(int sizeWindow, sfloat *pResidual, sfloat *pWindow,
- SMS_Data *pSmsFrame, SMS_AnalParams *pAnalParams);
-
-void sms_interpolateFrames(SMS_Data *pSmsFrame1, SMS_Data *pSmsFrame2,
- SMS_Data *pSmsFrameOut, sfloat fInterpFactor);
-void sms_fft(int sizeFft, sfloat *pArray);
-void sms_ifft(int sizeFft, sfloat *pArray);
-void sms_RectToPolar(int sizeSpec, sfloat *pReal, sfloat *pMag, sfloat *pPhase);
-void sms_PolarToRect(int sizeSpec, sfloat *pReal, sfloat *pMag, sfloat *pPhase);
-void sms_spectrumRMS(int sizeMag, sfloat *pReal, sfloat *pMag);
-
-void sms_initModify(SMS_Header *header, SMS_ModifyParams *params);
-void sms_initModifyParams(SMS_ModifyParams *params);
-void sms_freeModify(SMS_ModifyParams *params);
-void sms_modify(SMS_Data *frame, SMS_ModifyParams *params);
-
-/***********************************************************************************/
-/************* debug functions: ******************************************************/
-
-int sms_createDebugFile(SMS_AnalParams *pAnalParams);
-void sms_writeDebugData(sfloat *pBuffer1, sfloat *pBuffer2,
- sfloat *pBuffer3, int sizeBuffer);
-void sms_writeDebugFile();
-void sms_error(char *pErrorMessage );
-int sms_errorCheck();
-char* sms_errorString();
-
-#endif /* _SMS_H */
-
diff --git a/sms/sms.i b/sms/sms.i
deleted file mode 100644
index 0b3ee5a..0000000
--- a/sms/sms.i
+++ /dev/null
@@ -1,540 +0,0 @@
-%module simplsms
-%{
- #include "sms.h"
- #define SWIG_FILE_WITH_INIT
-%}
-
-%include "../common/numpy.i"
-
-%init
-%{
- import_array();
-%}
-
-%exception
-{
- $action
- if (sms_errorCheck())
- {
- PyErr_SetString(PyExc_IndexError,sms_errorString());
- return NULL;
- }
-}
-
-/* apply all numpy typemaps to various names in sms.h */
-%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeWindow, double* pWindow)};
-%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeWaveform, double* pWaveform)};
-%apply(int DIM1, double* INPLACE_ARRAY1) {(long sizeSound, double* pSound)};
-%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeFft, double* pArray)};
-%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeFft, double* pFftBuffer)};
-%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeFreq, double* pFreq)};
-%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeAmp, double* pAmp)};
-%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeMag, double* pMag)};
-%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizePhase, double* pPhase)};
-%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeCepstrum, double* pCepstrum)};
-%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeEnv, double* pEnv)};
-%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeTrack, double* pTrack)};
-%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeArray, double* pArray)};
-%apply(int DIM1, double* IN_ARRAY1) {(int sizeInArray, double* pInArray)};
-%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeOutArray, double* pOutArray)};
-%apply(int DIM1, double* INPLACE_ARRAY1) {(int sizeHop, double* pSynthesis)};
-%apply(int DIM1, double* INPLACE_ARRAY1)
-{
- (int sizeResidual, double* residual),
- (int sizeApprox, double* approx)
-}
-%apply(int DIM1, double* IN_ARRAY1)
-{
- (int numamps, double* amps),
- (int numfreqs, double* freqs),
- (int numphases, double* phases)
-}
-%apply (int DIM1, double* IN_ARRAY1)
-{
- (int sizeSynthesis, double* pSynthesis),
- (int sizeOriginal, double* pOriginal),
- (int sizeResidual, double* pResidual)
-}
-
-%include "sms.h"
-
-/* overload the functions that will be wrapped to fit numpy typmaps (defined below)
- * by renaming the wrapped names back to originals
- */
-%rename(sms_detectPeaks) simplsms_detectPeaks;
-%rename(sms_spectrum) simplsms_spectrum;
-%rename(sms_spectrumMag) simplsms_spectrumMag;
-%rename(sms_windowCentered) simplsms_windowCentered;
-%rename(sms_invSpectrum) simplsms_invSpectrum;
-%rename(sms_dCepstrum) simplsms_dCepstrum;
-%rename(sms_synthesize) simplsms_synthesize_wrapper;
-
-%inline
-%{
- typedef struct
- {
- SMS_Header *header;
- SMS_Data *smsData;
- int allocated;
- } SMS_File;
-
- void simplsms_dCepstrum(int sizeCepstrum, sfloat *pCepstrum, int sizeFreq, sfloat *pFreq, int sizeMag, sfloat *pMag,
- sfloat fLambda, int iSamplingRate)
- {
- sms_dCepstrum(sizeCepstrum,pCepstrum, sizeFreq, pFreq, pMag,
- fLambda, iSamplingRate);
- }
- int simplsms_detectPeaks(int sizeMag, sfloat *pMag, int sizePhase, sfloat *pPhase,
- SMS_SpectralPeaks *pPeakStruct, SMS_AnalParams *pAnalParams)
- {
- if(sizeMag != sizePhase)
- {
- sms_error("sizeMag != sizePhase");
- return 0;
- }
- if(pPeakStruct->nPeaks < pAnalParams->maxPeaks)
- {
- sms_error("nPeaks in SMS_SpectralPeaks is not large enough (less than SMS_AnalParams.maxPeaks)");
- return 0;
- }
- pPeakStruct->nPeaksFound = sms_detectPeaks(sizeMag, pMag, pPhase, pPeakStruct->pSpectralPeaks, pAnalParams);
- return pPeakStruct->nPeaksFound;
- }
- int simplsms_spectrum(int sizeWaveform, sfloat *pWaveform, int sizeWindow, sfloat *pWindow,
- int sizeMag, sfloat *pMag, int sizePhase, sfloat *pPhase, sfloat *pFftBuffer)
- {
- return sms_spectrum(sizeWindow, pWaveform, pWindow, sizeMag, pMag, pPhase, pFftBuffer);
- }
- int simplsms_spectrumMag(int sizeWaveform, sfloat *pWaveform, int sizeWindow, sfloat *pWindow,
- int sizeMag, sfloat *pMag, sfloat *pFftBuffer)
- {
- return sms_spectrumMag(sizeWindow, pWaveform, pWindow, sizeMag, pMag, pFftBuffer);
- }
- int simplsms_invSpectrum(int sizeWaveform, sfloat *pWaveform, int sizeWindow, sfloat *pWindow,
- int sizeMag, sfloat *pMag, int sizePhase, sfloat *pPhase, sfloat *pFftBuffer)
- {
- return sms_invSpectrum(sizeWaveform, pWaveform, pWindow, sizeMag, pMag, pPhase, pFftBuffer);
- }
- void simplsms_windowCentered(int sizeWaveform, sfloat *pWaveform, int sizeWindow,
- sfloat *pWindow, int sizeFft, sfloat *pFftBuffer)
- {
- if (sizeWaveform != sizeWindow)
- {
- sms_error("sizeWaveform != sizeWindow");
- return;
- }
- sms_windowCentered(sizeWindow, pWaveform, pWindow, sizeFft, pFftBuffer);
- }
- void simplsms_synthesize_wrapper(SMS_Data *pSmsData, int sizeHop, sfloat *pSynthesis, SMS_SynthParams *pSynthParams)
- {
- if(sizeHop != pSynthParams->sizeHop)
- {
- sms_error("sizeHop != pSynthParams->sizeHop");
- return;
- }
- sms_synthesize(pSmsData, pSynthesis, pSynthParams);
- }
-%}
-
-%extend SMS_File
-{
- /* load an entire file to an internal numpy array */
- void load(char *pFilename)
- {
- int i;
- FILE *pSmsFile;
- $self->allocated = 0;
- sms_getHeader (pFilename, &$self->header, &pSmsFile);
- if(sms_errorCheck()) return;
-
- $self->smsData = calloc($self->header->nFrames, sizeof(SMS_Data));
- for(i = 0; i < $self->header->nFrames; i++)
- {
- sms_allocFrameH ($self->header, &$self->smsData[i]);
- if(sms_errorCheck())
- return;
- sms_getFrame (pSmsFile, $self->header, i, &$self->smsData[i]);
- if(sms_errorCheck())
- return;
- }
- $self->allocated = 1;
- }
- void close() /* todo: this should be in the destructor, no? */
- {
- int i;
- if(!$self->allocated)
- {
- sms_error("file not yet alloceted");
- return;
- }
- $self->allocated = 0;
- for(i = 0; i < $self->header->nFrames; i++)
- sms_freeFrame(&$self->smsData[i]);
- free($self->smsData);
- }
- /* return a pointer to a frame, which can be passed around to other libsms functions */
- void getFrame(int i, SMS_Data *frame)
- {
- if(i < 0 || i >= $self->header->nFrames)
- {
- sms_error("index is out of file boundaries");
- return;
- }
- frame = &$self->smsData[i];
- }
- void getTrack(int track, int sizeFreq, sfloat *pFreq, int sizeAmp, sfloat *pAmp)
- {
- /* fatal error protection first */
- if(!$self->allocated)
- {
- sms_error("file not yet alloceted");
- return;
- }
- if(track >= $self->header->nTracks)
- {
- sms_error("desired track is greater than number of tracks in file");
- return;
- }
- if(sizeFreq != sizeAmp)
- {
- sms_error("freq and amp arrays are different in size");
- return;
- }
- /* make sure arrays are big enough, or return less data */
- int nFrames = MIN(sizeFreq, $self->header->nFrames);
- int i;
- for(i=0; i < nFrames; i++)
- {
- pFreq[i] = $self->smsData[i].pFSinFreq[track];
- pAmp[i] = $self->smsData[i].pFSinAmp[track];
- }
- }
- // TODO turn into getTrackP - and check if phase exists
- void getTrack(int track, int sizeFreq, sfloat *pFreq, int sizeAmp,
- sfloat *pAmp, int sizePhase, sfloat *pPhase)
- {
- /* fatal error protection first */
- if(!$self->allocated)
- {
- sms_error("file not yet alloceted");
- return;
- }
- if(track >= $self->header->nTracks)
- {
- sms_error("desired track is greater than number of tracks in file");
- return;
- }
- if(sizeFreq != sizeAmp)
- {
- sms_error("freq and amp arrays are different in size");
- return;
- }
- /* make sure arrays are big enough, or return less data */
- int nFrames = MIN (sizeFreq, $self->header->nFrames);
- int i;
- for(i=0; i < nFrames; i++)
- {
- pFreq[i] = $self->smsData[i].pFSinFreq[track];
- pAmp[i] = $self->smsData[i].pFSinFreq[track];
- }
- if($self->header->iFormat < SMS_FORMAT_HP)
- return;
-
- if(sizePhase != sizeFreq || sizePhase != sizeAmp)
- {
- sms_error("phase array and freq/amp arrays are different in size");
- return;
- }
- for(i=0; i < nFrames; i++)
- pPhase[i] = $self->smsData[i].pFSinPha[track];
- }
- void getFrameDet(int i, int sizeFreq, sfloat *pFreq, int sizeAmp, sfloat *pAmp)
- {
- if(!$self->allocated)
- {
- sms_error("file not yet alloceted");
- return;
- }
- if(i >= $self->header->nFrames)
- {
- sms_error("index is greater than number of frames in file");
- return;
- }
- int nTracks = $self->smsData[i].nTracks;
- if(sizeFreq > nTracks)
- {
- sms_error("index is greater than number of frames in file");
- return;
- }
- if(sizeFreq != sizeAmp)
- {
- sms_error("freq and amp arrays are different in size");
- return;
- }
- memcpy(pFreq, $self->smsData[i].pFSinFreq, sizeof(sfloat) * nTracks);
- memcpy(pAmp, $self->smsData[i].pFSinAmp, sizeof(sfloat) * nTracks);
- }
- void getFrameDetP(int i, int sizeFreq, sfloat *pFreq, int sizeAmp,
- sfloat *pAmp, int sizePhase, sfloat *pPhase)
- {
- if(!$self->allocated)
- {
- sms_error("file not yet alloceted");
- return;
- }
- if($self->header->iFormat < SMS_FORMAT_HP)
- {
- sms_error("file does not contain a phase component in Deterministic (iFormat < SMS_FORMAT_HP)");
- return;
- }
- if(i >= $self->header->nFrames)
- {
- sms_error("index is greater than number of frames in file");
- return;
- }
- int nTracks = $self->smsData[i].nTracks;
- if(sizeFreq > nTracks)
- {
- sms_error("index is greater than number of frames in file");
- return;
- }
- if(sizeFreq != sizeAmp)
- {
- sms_error("freq and amp arrays are different in size");
- return;
- }
- memcpy(pFreq, $self->smsData[i].pFSinFreq, sizeof(sfloat) * nTracks);
- memcpy(pAmp, $self->smsData[i].pFSinAmp, sizeof(sfloat) * nTracks);
-
- if(sizePhase != sizeFreq || sizePhase != sizeAmp)
- {
- sms_error("phase array and freq/amp arrays are different in size");
- return;
- }
- memcpy(pPhase, $self->smsData[i].pFSinPha, sizeof(sfloat) * nTracks);
- }
- void getFrameRes(int i, int sizeRes, sfloat *pRes)
- {
- if(!$self->allocated)
- {
- sms_error("file not yet alloceted");
- return;
- }
- if($self->header->iStochasticType < 1)
- {
- sms_error("file does not contain a stochastic component");
- return;
- }
- int nCoeff = sizeRes;
- if($self->header->nStochasticCoeff > sizeRes)
- nCoeff = $self->header->nStochasticCoeff; // return what you can
-
- memcpy(pRes, $self->smsData[i].pFStocCoeff, sizeof(sfloat) * nCoeff);
- }
- void getFrameEnv(int i, int sizeEnv, sfloat *pEnv)
- {
- if(!$self->allocated)
- {
- sms_error("file not yet alloceted");
- return;
- }
- if($self->header->iEnvType < 1)
- {
- sms_error("file does not contain a spectral envelope");
- return;
- }
- int nCoeff = sizeEnv;
- if($self->header->nStochasticCoeff > sizeEnv)
- nCoeff = $self->header->nEnvCoeff; // return what you can
-
- memcpy(pEnv, $self->smsData[i].pSpecEnv, sizeof(sfloat) * nCoeff);
- }
-}
-
-%extend SMS_AnalParams
-{
- SMS_AnalParams()
- {
- SMS_AnalParams *s = (SMS_AnalParams *)malloc(sizeof(SMS_AnalParams));
- sms_initAnalParams(s);
- return s;
- }
-}
-
-%extend SMS_SynthParams
-{
- SMS_SynthParams()
- {
- SMS_SynthParams *s = (SMS_SynthParams *)malloc(sizeof(SMS_SynthParams));
- sms_initSynthParams(s);
- return s;
- }
-}
-
-%extend SMS_SpectralPeaks
-{
- SMS_SpectralPeaks(int n)
- {
- SMS_SpectralPeaks *s = (SMS_SpectralPeaks *)malloc(sizeof(SMS_SpectralPeaks));
- if(s == NULL)
- {
- sms_error("Could not allocate memory for SMS_SpectralPeaks");
- return NULL;
- }
- if(sms_initSpectralPeaks(s, n) < 0)
- {
- sms_error("Could not initialise SMS_SpectralPeaks");
- return NULL;
- }
- return s;
- }
- void getFreq(int sizeArray, sfloat *pArray )
- {
- if(sizeArray < $self->nPeaksFound)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for(i = 0; i < $self->nPeaksFound; i++)
- pArray[i] = $self->pSpectralPeaks[i].fFreq;
- }
- void getMag(int sizeArray, sfloat *pArray )
- {
- if(sizeArray < $self->nPeaksFound)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for(i = 0; i < $self->nPeaksFound; i++)
- pArray[i] = $self->pSpectralPeaks[i].fMag;
- }
- void getPhase(int sizeArray, sfloat *pArray )
- {
- if(sizeArray < $self->nPeaksFound)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for(i = 0; i < $self->nPeaksFound; i++)
- pArray[i] = $self->pSpectralPeaks[i].fPhase;
- }
-}
-
-%extend SMS_Data
-{
- void getSinAmp(int sizeArray, sfloat *pArray)
- {
- if(sizeArray < $self->nTracks)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for(i = 0; i < $self->nTracks; i++)
- pArray[i] = $self->pFSinAmp[i];
- }
- void getSinFreq(int sizeArray, sfloat *pArray)
- {
- if(sizeArray < $self->nTracks)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for(i = 0; i < $self->nTracks; i++)
- pArray[i] = $self->pFSinFreq[i];
- }
- void getSinPhase(int sizeArray, sfloat *pArray)
- {
- if(sizeArray < $self->nTracks)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for(i = 0; i < $self->nTracks; i++)
- pArray[i] = $self->pFSinPha[i];
- }
- void getSinEnv(int sizeArray, sfloat *pArray)
- {
- if(sizeArray < $self->nEnvCoeff)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for(i = 0; i < $self->nEnvCoeff; i++)
- pArray[i] = $self->pSpecEnv[i];
- }
- void setSinAmp(int sizeArray, sfloat *pArray)
- {
- if(sizeArray < $self->nTracks)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for (i = 0; i < $self->nTracks; i++)
- $self->pFSinAmp[i] = pArray[i];
- }
- void setSinFreq(int sizeArray, sfloat *pArray)
- {
- if(sizeArray < $self->nTracks)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for(i = 0; i < $self->nTracks; i++)
- $self->pFSinFreq[i] = pArray[i];
- }
- void setSinPha(int sizeArray, sfloat *pArray)
- {
- if(sizeArray < $self->nTracks)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for(i = 0; i < $self->nTracks; i++)
- $self->pFSinPha[i] = pArray[i];
- }
-}
-
-%extend SMS_ResidualParams
-{
- void getResidual(int sizeArray, sfloat *pArray)
- {
- if(sizeArray < $self->hopSize)
- {
- sms_error("numpy array not big enough");
- return;
- }
- int i;
- for(i = 0; i < $self->hopSize; i++)
- pArray[i] = $self->residual[i];
- }
-}
-
-%extend SMS_ModifyParams
-{
- /* no need to return an error code, if sms_error is called, it will throw an exception in python */
- void setSinEnv(int sizeArray, sfloat *pArray)
- {
- if(!$self->ready)
- {
- sms_error("modify parameter structure has not been initialized");
- return;
- }
- if(sizeArray != $self->sizeSinEnv)
- {
- sms_error("numpy array is not equal to envelope size");
- return;
- }
- memcpy($self->sinEnv, pArray, sizeof(sfloat) * $self->sizeSinEnv);
- }
-}
-
diff --git a/sms/soundIO.c b/sms/soundIO.c
deleted file mode 100644
index 2e2379b..0000000
--- a/sms/soundIO.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG)
- * UNIVERSITAT POMPEU FABRA
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-/*! \file soundIO.c
- * \brief soundfile input and output.
-*/
-#include "sms.h"
-
-/*! \brief fill the sound buffer
- *
- * \param sizeWaveform size of input data
- * \param pWaveform input data
- * \param pAnalParams pointer to structure of analysis parameters
- */
-void sms_fillSoundBuffer(int sizeWaveform, sfloat *pWaveform, SMS_AnalParams *pAnalParams)
-{
- int i;
- long sizeNewData = (long)sizeWaveform;
-
- /* leave space for new data */
- memcpy(pAnalParams->soundBuffer.pFBuffer, pAnalParams->soundBuffer.pFBuffer+sizeNewData,
- sizeof(sfloat) * (pAnalParams->soundBuffer.sizeBuffer - sizeNewData));
-
- pAnalParams->soundBuffer.iFirstGood = MAX(0, pAnalParams->soundBuffer.iFirstGood - sizeNewData);
- pAnalParams->soundBuffer.iMarker += sizeNewData;
-
- /* put the new data in, and do some pre-emphasis */
- if(pAnalParams->iAnalysisDirection == SMS_DIR_REV)
- for(i=0; i<sizeNewData; i++)
- pAnalParams->soundBuffer.pFBuffer[pAnalParams->soundBuffer.sizeBuffer - sizeNewData + i] =
- sms_preEmphasis(pWaveform[sizeNewData - (1 + i)], pAnalParams);
- else
- for(i=0; i<sizeNewData; i++)
- pAnalParams->soundBuffer.pFBuffer[pAnalParams->soundBuffer.sizeBuffer - sizeNewData + i] =
- sms_preEmphasis(pWaveform[i], pAnalParams);
-}
-
diff --git a/sms/spectralApprox.c b/sms/spectralApprox.c
deleted file mode 100644
index b1f65ef..0000000
--- a/sms/spectralApprox.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG)
- * UNIVERSITAT POMPEU FABRA
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-/*! \file spectralApprox.c
- * \brief line segment approximation of a magnitude spectrum
- */
-#include "sms.h"
-
-/*! \brief approximate a magnitude spectrum
- * First downsampling using local maxima and then upsampling using linear
- * interpolation. The output spectrum doesn't have to be the same size as
- * the input one.
- *
- * \param pFSpec1 magnitude spectrum to approximate
- * \param sizeSpec1 size of input spectrum
- * \param sizeSpec1Used size of the spectrum to use
- * \param pFSpec2 output envelope
- * \param sizeSpec2 size of output envelope
- * \param nCoefficients number of coefficients to use in approximation
- * \return error code \see SMS_ERRORS
- */
-int sms_spectralApprox(sfloat *pFSpec1, int sizeSpec1, int sizeSpec1Used,
- sfloat *pFSpec2, int sizeSpec2, int nCoefficients,
- sfloat *envelope)
-{
- sfloat fHopSize, fCurrentLoc = 0, fLeft = 0, fRight = 0, fValue = 0,
- fLastLocation, fSizeX, fSpec2Acum=0, fNextHop, fDeltaY;
- int iFirstGood = 0, iLastSample = 0, i, j;
-
- /* when number of coefficients is smaller than 2 do not approximate */
- if(nCoefficients < 2)
- {
- for(i = 0; i < sizeSpec2; i++)
- pFSpec2[i] = 1;
- return SMS_OK;
- }
-
- /* calculate the hop size */
- if(nCoefficients > sizeSpec1)
- nCoefficients = sizeSpec1;
-
- fHopSize = (sfloat)sizeSpec1Used / nCoefficients;
-
- /* approximate by linear interpolation */
- if(fHopSize > 1)
- {
- iFirstGood = 0;
- for(i = 0; i < nCoefficients; i++)
- {
- iLastSample = fLastLocation = fCurrentLoc + fHopSize;
- iLastSample = MIN(sizeSpec1-1, iLastSample);
- if(iLastSample < sizeSpec1-1)
- {
- fRight = pFSpec1[iLastSample] +
- (pFSpec1[iLastSample+1] - pFSpec1[iLastSample]) *
- (fLastLocation - iLastSample);
- }
- else
- {
- fRight = pFSpec1[iLastSample];
- }
-
- fValue = 0;
- for(j = iFirstGood; j <= iLastSample; j++)
- fValue = MAX (fValue, pFSpec1[j]);
- fValue = MAX(fValue, MAX (fRight, fLeft));
- envelope[i] = fValue;
-
- fLeft = fRight;
- fCurrentLoc = fLastLocation;
- iFirstGood = (int)(1+ fCurrentLoc);
- }
- }
- else if(fHopSize == 1)
- {
- for(i = 0; i < nCoefficients; i++)
- envelope[i] = pFSpec1[i];
- }
- else
- {
- sms_error("SpectralApprox: sizeSpec1 has too many nCoefficients"); /* \todo need to increase the frequency? */
- return -1;
- }
-
- /* Creates Spec2 from Envelope */
- if(nCoefficients < sizeSpec2)
- {
- fSizeX = (sfloat) (sizeSpec2-1) / nCoefficients;
-
- /* the first step */
- fNextHop = fSizeX / 2;
- fDeltaY = envelope[0] / fNextHop;
- fSpec2Acum=pFSpec2[j=0]=0;
- while(++j < fNextHop)
- pFSpec2[j] = (fSpec2Acum += fDeltaY);
-
- /* middle values */
- for(i = 0; i <= nCoefficients-2; ++i)
- {
- fDeltaY = (envelope[i+1] - envelope[i]) / fSizeX;
- /* first point of a segment */
- pFSpec2[j] = (fSpec2Acum = (envelope[i]+(fDeltaY*(j-fNextHop))));
- ++j;
- /* remaining points */
- fNextHop += fSizeX;
- while(j < fNextHop)
- pFSpec2[j++] = (fSpec2Acum += fDeltaY);
- }
-
- /* last step */
- fDeltaY = -envelope[i] * 2 / fSizeX;
- /* first point of the last segment */
- pFSpec2[j] = (fSpec2Acum = (envelope[i]+(fDeltaY*(j-fNextHop))));
- ++j;
- fNextHop += fSizeX / 2;
- while(j < sizeSpec2-1)
- pFSpec2[j++]=(fSpec2Acum += fDeltaY);
- /* last should be exactly zero */
- pFSpec2[sizeSpec2-1] = .0;
- }
- else if(nCoefficients == sizeSpec2)
- {
- for(i = 0; i < nCoefficients; i++)
- pFSpec2[i] = envelope[i];
- }
- else
- {
- sms_error("SpectralApprox: sizeSpec2 has too many nCoefficients\n");
- return -1;
- }
-
- return SMS_OK;
-}
-
-
diff --git a/sms/spectrum.c b/sms/spectrum.c
deleted file mode 100644
index 1b8e053..0000000
--- a/sms/spectrum.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG)
- * UNIVERSITAT POMPEU FABRA
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-/*! \file spectrum.c
- * \brief functions to convert between frequency (spectrum) and time (wavefrom) domain
- */
-#include "sms.h"
-
-/*! \brief compute a complex spectrum from a waveform
- *
- * \param sizeWindow size of analysis window
- * \param pWaveform pointer to input waveform
- * \param pWindow pointer to input window
- * \param sizeMag size of output magnitude and phase spectrums
- * \param pMag pointer to output magnitude spectrum
- * \param pPhase pointer to output phase spectrum
- * \return sizeFft, -1 on error \todo remove this return
- */
-int sms_spectrum(int sizeWindow, sfloat *pWaveform, sfloat *pWindow, int sizeMag,
- sfloat *pMag, sfloat *pPhase, sfloat *pFftBuffer)
-{
- int i, it2;
- sfloat fReal, fImag;
-
- int sizeFft = sizeMag << 1;
- memset(pFftBuffer, 0, sizeFft * sizeof(sfloat));
-
- /* apply window to waveform and center window around 0 (zero-phase windowing)*/
- sms_windowCentered(sizeWindow, pWaveform, pWindow, sizeFft, pFftBuffer);
- sms_fft(sizeFft, pFftBuffer);
-
- /* convert from rectangular to polar coordinates */
- for(i = 0; i < sizeMag; i++)
- {
- it2 = i << 1; //even numbers 0-N
- fReal = pFftBuffer[it2]; /*odd numbers 1->N+1 */
- fImag = pFftBuffer[it2 + 1]; /*even numbers 2->N+2 */
- pMag[i] = sqrt(fReal * fReal + fImag * fImag);
- pPhase[i] = atan2(-fImag, fReal); /* \todo why is fImag negated? */
- /*pPhase[i] = atan2(fImag, fReal);*/
- }
-
- return sizeFft;
-}
-
-/* sms_spectrum, but without zero-phase windowing, and with phase calculated
- * according by arctan(imag/real) instead of arctan2(-imag/real)
- */
-int sms_spectrumW(int sizeWindow, sfloat *pWaveform, sfloat *pWindow, int sizeMag,
- sfloat *pMag, sfloat *pPhase, sfloat *pFftBuffer)
-{
- int i, it2;
- sfloat fReal, fImag;
-
- int sizeFft = sizeMag << 1;
- memset(pFftBuffer, 0, sizeFft * sizeof(sfloat));
-
- /* apply window to waveform */
- for(i = 0; i < sizeWindow; i++)
- pFftBuffer[i] = pWaveform[i] * pWindow[i];
-
- sms_fft(sizeFft, pFftBuffer);
-
- /* convert from rectangular to polar coordinates */
- for(i = 0; i < sizeMag; i++)
- {
- it2 = i << 1; //even numbers 0-N
- fReal = pFftBuffer[it2]; /*odd numbers 1->N+1 */
- fImag = pFftBuffer[it2 + 1]; /*even numbers 2->N+2 */
- pMag[i] = sqrt(fReal * fReal + fImag * fImag);
- pPhase[i] = atan2(fImag, fReal);
- }
-
- return sizeFft;
-}
-
-/*! \brief compute the spectrum Magnitude of a waveform
- *
- * This function windows the waveform with pWindow and
- * performs a zero-padded FFT (if sizeMag*2 > sizeWindow).
- * The spectra is then converted magnitude (RMS).
- *
- * \param sizeWindow size of analysis window / input wavefrom
- * \param pWaveform pointer to input waveform
- * \param pWindow pointer to analysis window
- * \param sizeMag size of output magnitude spectrum
- * \param pMag pointer to output magnitude spectrum
- * \return 0 on success, -1 on error
- */
-int sms_spectrumMag(int sizeWindow, sfloat *pWaveform, sfloat *pWindow,
- int sizeMag, sfloat *pMag, sfloat *pFftBuffer)
-{
- int i,it2;
- int sizeFft = sizeMag << 1;
- sfloat fReal, fImag;
-
- /* apply window to waveform, zero the rest of the array */
- for(i = 0; i < sizeWindow; i++)
- pFftBuffer[i] = pWaveform[i] * pWindow[i];
- for(i = sizeWindow; i < sizeFft; i++)
- pFftBuffer[i] = 0.;
-
- /* compute real FFT */
- sms_fft(sizeFft, pFftBuffer);
-
- /* convert from rectangular to polar coordinates */
- for(i = 0; i < sizeMag; i++)
- {
- it2 = i << 1;
- fReal = pFftBuffer[it2];
- fImag = pFftBuffer[it2+1];
- pMag[i] = sqrtf(fReal * fReal + fImag * fImag);
- }
-
- return sizeFft;
-}
-
-/*! \brief function for a quick inverse spectrum, windowed
- *
- * Not done yet, but this will be a function that is the inverse of
- * sms_spectrum above.
- *
- * function to perform the inverse FFT, windowing the output
- * sfloat *pFMagSpectrum input magnitude spectrum
- * sfloat *pFPhaseSpectrum input phase spectrum
- * int sizeFft size of FFT
- * sfloat *pFWaveform output waveform
- * int sizeWave size of output waveform
- * sfloat *pFWindow synthesis window
- */
-int sms_invSpectrum(int sizeWaveform, sfloat *pWaveform, sfloat *pWindow,
- int sizeMag, sfloat *pMag, sfloat *pPhase, sfloat *pFftBuffer)
-{
- int i;
- int sizeFft = sizeMag << 1;
-
- sms_PolarToRect(sizeMag, pFftBuffer, pMag, pPhase);
- sms_ifft(sizeFft, pFftBuffer);
-
- /* assume that the output array does not need to be cleared */
- /* before, this was multiplied by .5, why? */
- for(i = 0; i < sizeWaveform; i++)
- //pWaveform[i] += pFftBuffer[i] * pWindow[i];
- pWaveform[i] = pFftBuffer[i];
-
- return sizeFft;
-}
-
-/*! \brief function for a quick inverse spectrum, windowed
- * function to perform the inverse FFT, windowing the output
- * sfloat *pFMagSpectrum input magnitude spectrum
- * sfloat *pFPhaseSpectrum input phase spectrum
- * int sizeFft size of FFT
- * sfloat *pFWaveform output waveform
- * int sizeWave size of output waveform
- * sfloat *pFWindow synthesis window
- */
-int sms_invQuickSpectrumW(sfloat *pFMagSpectrum, sfloat *pFPhaseSpectrum,
- int sizeFft, sfloat *pFWaveform, int sizeWave,
- sfloat *pFWindow, sfloat* pFftBuffer)
-{
- int i, it2;
- int sizeMag = sizeFft >> 1;
-
- /* convert from polar coordinates to rectangular */
- for(i = 0; i < sizeMag; i++)
- {
- it2 = i << 1;
- pFftBuffer[it2] = pFMagSpectrum[i] * cos(pFPhaseSpectrum[i]);
- pFftBuffer[it2+1] = pFMagSpectrum[i] * sin(pFPhaseSpectrum[i]);
- }
-
- /* compute IFFT */
- sms_ifft(sizeFft, pFftBuffer);
-
- /* assume that the output array does not need to be cleared */
- for(i = 0; i < sizeWave; i++)
- pFWaveform[i] += (pFftBuffer[i] * pFWindow[i] * .5);
-
- return sizeMag;
-}
-
-/*! \brief convert spectrum from Rectangular to Polar form
- *
- * \param sizeMag size of spectrum (pMag and pPhase arrays)
- * \param pRect pointer output spectrum in rectangular form (2x sizeSpec)
- * \param pMag pointer to sfloat array of magnitude spectrum
- * \param pPhase pointer to sfloat array of phase spectrum
- */
-void sms_RectToPolar(int sizeMag, sfloat *pRect, sfloat *pMag, sfloat *pPhase)
-{
- int i, it2;
- sfloat fReal, fImag;
-
- for(i=0; i<sizeMag; i++)
- {
- it2 = i << 1;
- fReal = pRect[it2];
- fImag = pRect[it2+1];
-
- pMag[i] = sqrtf(fReal * fReal + fImag * fImag);
- if(pPhase)
- pPhase[i] = atan2f(fImag, fReal);
- }
-}
-
-/*! \brief convert spectrum from Rectangular to Polar form
- *
- * \param sizeSpec size of spectrum (pMag and pPhase arrays)
- * \param pRect pointer output spectrum in rectangular form (2x sizeSpec)
- * \param pMag pointer to sfloat array of magnitude spectrum
- * \param pPhase pointer to sfloat array of phase spectrum
- */
-void sms_PolarToRect(int sizeSpec, sfloat *pRect, sfloat *pMag, sfloat *pPhase)
-{
- int i, it2;
- sfloat fMag;
-
- for(i = 0; i<sizeSpec; i++)
- {
- it2 = i << 1;
- fMag = pMag[i];
- pRect[it2] = fMag * cos (pPhase[i]);
- pRect[it2+1] = fMag * sin (pPhase[i]);
- }
-}
-
-/*! \brief compute magnitude spectrum of a DFT in rectangular coordinates
- *
- * \param sizeMag size of output Magnitude (half of input real FFT)
- * \param pInRect pointer to input DFT array (real/imag sfloats)
- * \param pOutMag pointer to of magnitude spectrum array
- */
-void sms_spectrumRMS(int sizeMag, sfloat *pInRect, sfloat *pOutMag)
-{
- int i, it2;
- sfloat fReal, fImag;
-
- for(i=0; i<sizeMag; i++)
- {
- it2 = i << 1;
- fReal = pInRect[it2];
- fImag = pInRect[it2+1];
- pOutMag[i] = sqrtf(fReal * fReal + fImag * fImag);
- }
-}
-
diff --git a/sms/stocAnalysis.c b/sms/stocAnalysis.c
deleted file mode 100644
index 802e41c..0000000
--- a/sms/stocAnalysis.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG)
- * UNIVERSITAT POMPEU FABRA
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, M 02111-1307 USA
- *
- */
-/*! \file stocAnalysis.c
- * \brief stochastic analysis using spectral analysis and approximation
- */
-#include "sms.h"
-
-/*! \brief main function for the stochastic analysis
- * \param sizeWindow size of buffer
- * \param pResidual pointer to residual signal
- * \param pWindow pointer to windowing array
- * \param pSmsData pointer to output SMS data
- * \param pAnalParams point to analysis parameters
- * \return 0 on success, -1 on error
- */
-int sms_stocAnalysis(int sizeWindow, sfloat *pResidual, sfloat *pWindow,
- SMS_Data *pSmsData, SMS_AnalParams* pAnalParams)
-{
- int i;
- sfloat fMag = 0.0;
-
- sms_spectrumMag(sizeWindow, pResidual, pWindow, pAnalParams->sizeStocMagSpectrum,
- pAnalParams->stocMagSpectrum, pAnalParams->fftBuffer);
-
- sms_spectralApprox(pAnalParams->stocMagSpectrum, pAnalParams->sizeStocMagSpectrum,
- pAnalParams->sizeStocMagSpectrum, pSmsData->pFStocCoeff,
- pSmsData->nCoeff, pSmsData->nCoeff,
- pAnalParams->approxEnvelope);
-
- /* get energy of spectrum */
- for(i = 0; i < pAnalParams->sizeStocMagSpectrum; i++)
- fMag += (pAnalParams->stocMagSpectrum[i] * pAnalParams->stocMagSpectrum[i]);
-
- *pSmsData->pFStocGain = fMag / pAnalParams->sizeStocMagSpectrum;
- return 0;
-}
-
diff --git a/sms/synthesis.c b/sms/synthesis.c
deleted file mode 100644
index bc739d0..0000000
--- a/sms/synthesis.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG)
- * UNIVERSITAT POMPEU FABRA
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-/*! \file synthesis.c
- * \brief main synthesis routines
- */
-#include "sms.h"
-
-/*! \brief synthesis of one frame of the deterministic component using the IFFT
- *
- * \param pSmsData pointer to SMS data structure frame
- * \param pSynthParams pointer to structure of synthesis parameters
- */
-static void SineSynthIFFT(SMS_Data *pSmsData, SMS_SynthParams *pSynthParams)
-{
- int sizeFft = pSynthParams->sizeHop << 1;
- int iHalfSamplingRate = pSynthParams->iSamplingRate >> 1;
- int sizeMag = pSynthParams->sizeHop;
- int nBins = 8;
- int nTracks = pSmsData->nTracks;
- int iFirstBin, k, i, l, b;
- sfloat fMag=0.0, fFreq=0.0, fPhase=0.0, fLoc, fSin, fCos, fBinRemainder,
- fTmp, fNewMag, fIndex;
- sfloat fSamplingPeriod = 1.0 / pSynthParams->iSamplingRate;
- memset(pSynthParams->pSpectra, 0, sizeFft * sizeof(sfloat));
- for(i = 0; i < nTracks; i++)
- {
- if(((fMag = pSmsData->pFSinAmp[i]) > 0) &&
- ((fFreq = (pSmsData->pFSinFreq[i])) < iHalfSamplingRate))
- {
- /* \todo maybe this check can be removed if the SynthParams->prevFrame gets random
- phases in sms_initSynth? */
- if(pSynthParams->prevFrame.pFSinAmp[i] <= 0)
- pSynthParams->prevFrame.pFSinPha[i] = TWO_PI * sms_random();
-
- fMag = sms_dBToMag(fMag);
- fTmp = pSynthParams->prevFrame.pFSinPha[i] +
- TWO_PI * fFreq * fSamplingPeriod * sizeMag;
- fPhase = fTmp - floor(fTmp * INV_TWO_PI) * TWO_PI;
- fLoc = sizeFft * fFreq * fSamplingPeriod;
- iFirstBin = (int) fLoc - 3;
- fBinRemainder = fLoc - floor (fLoc);
- fSin = sms_sine(fPhase);
- fCos = sms_sine(fPhase + PI_2);
- for (k = 1, l = iFirstBin; k <= nBins; k++, l++)
- {
- fIndex = (k - fBinRemainder);
- if (fIndex > 7.999) fIndex = 0;
- fNewMag = fMag * sms_sinc (fIndex);
- if(l > 0 && l < sizeMag)
- {
- pSynthParams->pSpectra[l*2+1] += fNewMag * fCos;
- pSynthParams->pSpectra[l*2] += fNewMag * fSin;
- }
- else if(l == 0)
- {
- pSynthParams->pSpectra[0] += 2 * fNewMag * fSin;
- }
- else if(l < 0)
- {
- b = abs(l);
- pSynthParams->pSpectra[b*2+1] -= fNewMag * fCos;
- pSynthParams->pSpectra[b*2] += fNewMag * fSin;
- }
- else if(l > sizeMag)
- {
- b = sizeMag - (l - sizeMag);
- pSynthParams->pSpectra[b*2+1] -= fNewMag * fCos;
- pSynthParams->pSpectra[b*2] += fNewMag * fSin;
- }
- else if(l == sizeMag)
- {
- pSynthParams->pSpectra[1] += 2 * fNewMag * fSin;
- }
- }
- }
- pSynthParams->prevFrame.pFSinAmp[i] = fMag;
- pSynthParams->prevFrame.pFSinPha[i] = fPhase;
- pSynthParams->prevFrame.pFSinFreq[i] = fFreq;
- }
-
- sms_ifft(sizeFft, pSynthParams->pSpectra);
-
- for(i = 0, k = sizeMag; i < sizeMag; i++, k++)
- pSynthParams->pSynthBuff[i] += pSynthParams->pSpectra[k] * pSynthParams->pFDetWindow[i];
- for(i= sizeMag, k = 0; i < sizeFft; i++, k++)
- pSynthParams->pSynthBuff[i] += pSynthParams->pSpectra[k] * pSynthParams->pFDetWindow[i];
-}
-
-/*! \brief synthesis of one frame of the stochastic component by apprimating phases
- *
- * computes a linearly interpolated spectral envelope to fit the correct number of output
- * audio samples. Phases are generated randomly.
- *
- * \param pSmsData pointer to the current SMS frame
- * \param pSynthParams pointer to a strucure of synthesis parameters
- * \return
- * \todo cleanup returns and various constant multipliers. check that approximation is ok
- */
-static int StocSynthApprox(SMS_Data *pSmsData, SMS_SynthParams *pSynthParams)
-{
- int i, sizeSpec1Used;
- int sizeSpec1 = pSmsData->nCoeff;
- int sizeSpec2 = pSynthParams->sizeHop;
- int sizeFft = pSynthParams->sizeHop << 1; /* 50% overlap, so sizeFft is 2x sizeHop */
-
- /* if no gain or no coefficients return */
- if(*(pSmsData->pFStocGain) <= 0)
- return 0;
-
- sizeSpec1Used = sizeSpec1 * pSynthParams->iSamplingRate / pSynthParams->iOriginalSRate;
-
- /* sizeSpec1Used cannot be more than what is available \todo check by graph */
- if(sizeSpec1Used > sizeSpec1) sizeSpec1Used = sizeSpec1;
-
- sms_spectralApprox(pSmsData->pFStocCoeff, sizeSpec1, sizeSpec1Used,
- pSynthParams->pMagBuff, sizeSpec2, sizeSpec1Used,
- pSynthParams->approxEnvelope);
-
- /* generate random phases */
- for(i = 0; i < sizeSpec2; i++)
- pSynthParams->pPhaseBuff[i] = TWO_PI * sms_random();
-
- sms_invQuickSpectrumW(pSynthParams->pMagBuff, pSynthParams->pPhaseBuff,
- sizeFft, pSynthParams->pSynthBuff, sizeFft,
- pSynthParams->pFStocWindow, pSynthParams->pSpectra);
- return 1;
-}
-
-/*! \brief synthesizes one frame of the residual signal
- *
- * \param residualParams Parameters and memory for residual synthesis
- */
-void sms_approxResidual(int sizeResidual, sfloat* residual,
- int sizeApprox, sfloat* approx,
- SMS_ResidualParams *residualParams)
-{
- int i;
-
- /* shift buffers */
- memcpy(residualParams->residual,
- residualParams->residual + residualParams->hopSize,
- sizeof(sfloat) * residualParams->hopSize);
- memcpy(residualParams->residual + residualParams->hopSize, residual,
- sizeof(sfloat) * residualParams->hopSize);
-
- memcpy(residualParams->approx,
- residualParams->approx + residualParams->hopSize,
- sizeof(sfloat) * residualParams->hopSize);
- memset(residualParams->approx + residualParams->hopSize, 0,
- sizeof(sfloat) * residualParams->hopSize);
-
- sms_spectrumMag(residualParams->residualSize,
- residualParams->residual,
- residualParams->fftWindow,
- residualParams->sizeStocMagSpectrum,
- residualParams->stocMagSpectrum,
- residualParams->fftBuffer);
-
- if(residualParams->sizeStocMagSpectrum != residualParams->nCoeffs)
- {
- sms_spectralApprox(residualParams->stocMagSpectrum,
- residualParams->sizeStocMagSpectrum,
- residualParams->sizeStocMagSpectrum,
- residualParams->stocCoeffs,
- residualParams->nCoeffs,
- residualParams->nCoeffs,
- residualParams->approxEnvelope);
-
- sms_spectralApprox(residualParams->stocCoeffs,
- residualParams->nCoeffs,
- residualParams->nCoeffs,
- residualParams->stocMagSpectrum,
- residualParams->sizeStocMagSpectrum,
- residualParams->sizeStocMagSpectrum,
- residualParams->approxEnvelope);
- }
-
- /* generate random phases */
- for(i = 0; i < residualParams->sizeStocMagSpectrum; i++)
- residualParams->stocPhaseSpectrum[i] = TWO_PI * sms_random();
-
- /* IFFT with 50% overlap */
- sms_invQuickSpectrumW(residualParams->stocMagSpectrum,
- residualParams->stocPhaseSpectrum,
- residualParams->sizeStocMagSpectrum*2,
- residualParams->approx,
- residualParams->residualSize,
- residualParams->ifftWindow,
- residualParams->fftBuffer);
-
- /* output */
- for(i = 0; i < sizeApprox; i++)
- approx[i] = residualParams->approx[i] * residualParams->windowScale;
-}
-
-/*! \brief synthesizes one frame of SMS data
- *
- * \param pSmsData input SMS data
- * \param pFSynthesis output sound buffer
- * \param pSynthParams synthesis parameters
- */
-void sms_synthesize(SMS_Data *pSmsData, sfloat *pFSynthesis, SMS_SynthParams *pSynthParams)
-{
- int i;
- int sizeHop = pSynthParams->sizeHop;
-
- memcpy(pSynthParams->pSynthBuff, (sfloat *)(pSynthParams->pSynthBuff+sizeHop),
- sizeof(sfloat) * sizeHop);
- memset(pSynthParams->pSynthBuff+sizeHop, 0, sizeof(sfloat) * sizeHop);
-
- /* convert mags from linear to db */
- sms_arrayMagToDB(pSmsData->nTracks, pSmsData->pFSinAmp);
-
- /* decide which combo of synthesis methods to use */
- if(pSynthParams->iSynthesisType == SMS_STYPE_ALL)
- {
- if(pSynthParams->iDetSynthType == SMS_DET_IFFT)
- SineSynthIFFT(pSmsData, pSynthParams);
- else /*pSynthParams->iDetSynthType == SMS_DET_SIN*/
- {
- sms_sineSynthFrame(pSmsData, pSynthParams->pSynthBuff, pSynthParams->sizeHop,
- &(pSynthParams->prevFrame), pSynthParams->iSamplingRate);
- }
- StocSynthApprox(pSmsData, pSynthParams);
- }
- else if(pSynthParams->iSynthesisType == SMS_STYPE_DET)
- {
- if(pSynthParams->iDetSynthType == SMS_DET_IFFT)
- SineSynthIFFT(pSmsData, pSynthParams);
- else /*pSynthParams->iDetSynthType == SMS_DET_SIN*/
- {
- sms_sineSynthFrame(pSmsData, pSynthParams->pSynthBuff, pSynthParams->sizeHop,
- &(pSynthParams->prevFrame), pSynthParams->iSamplingRate);
- }
- }
- else /* pSynthParams->iSynthesisType == SMS_STYPE_STOC */
- StocSynthApprox(pSmsData, pSynthParams);
-
- /* de-emphasize the sound and normalize*/
- for(i = 0; i < sizeHop; i++)
- pFSynthesis[i] = sms_deEmphasis(pSynthParams->pSynthBuff[i], pSynthParams);
-}
diff --git a/sms/tables.c b/sms/tables.c
deleted file mode 100644
index 85d21cb..0000000
--- a/sms/tables.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG)
- * UNIVERSITAT POMPEU FABRA
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-/*! \file tables.c
- * \brief sin and sinc tables.
- *
- * contains functions for creating and indexing the tables
- */
-#include "sms.h"
-
-/*! \brief value to scale the sine-table-lookup phase */
-static sfloat fSineScale;
-/*! \brief inverse of fSineScale - turns a division into multiplication */
-static sfloat fSineIncr;
-/*! \brief value to scale the sinc-table-lookup phase */
-static sfloat fSincScale;
-/*! \brief global pointer to the sine table */
-static sfloat *sms_tab_sine;
-/*! \brief global pointer to the sinc table */
-static sfloat *sms_tab_sinc;
-
-/*! \brief prepares the sine table
- * \param nTableSize size of table
- * \return error code \see SMS_MALLOC in SMS_ERRORS
- */
-int sms_prepSine(int nTableSize)
-{
- register int i;
- sfloat fTheta;
-
- sms_tab_sine = (sfloat *)malloc(nTableSize * sizeof(sfloat));
- if(sms_tab_sine == NULL)
- {
- sms_error("Could not allocate memory for sine table");
- return SMS_MALLOC;
- }
- fSineScale = (sfloat)(TWO_PI) / (sfloat)(nTableSize - 1);
- fSineIncr = 1.0 / fSineScale;
- fTheta = 0.0;
- for(i = 0; i < nTableSize; i++)
- {
- fTheta = fSineScale * (sfloat)i;
- sms_tab_sine[i] = sin(fTheta);
- }
- return SMS_OK;
-}
-/*! \brief clear sine table */
-void sms_clearSine()
-{
- if(sms_tab_sine)
- free(sms_tab_sine);
- sms_tab_sine = NULL;
-}
-
-/*! \brief table-lookup sine method
- * \param fTheta angle in radians
- * \return approximately sin(fTheta)
- */
-sfloat sms_sine(sfloat fTheta)
-{
- int i;
- fTheta = fTheta - floor(fTheta * INV_TWO_PI) * TWO_PI;
-
- if(fTheta < 0)
- {
- i = .5 - (fTheta * fSineIncr);
- return -(sms_tab_sine[i]);
- }
- else
- {
- i = fTheta * fSineIncr + .5;
- return sms_tab_sine[i];
- }
-}
-
-/*! \brief Sinc method to generate the lookup table
- */
-static sfloat Sinc(sfloat x, sfloat N)
-{
- return sinf((N/2) * x) / sinf(x/2);
-}
-
-/*! \brief prepare the Sinc table
- *
- * used for the main lobe of a frequency domain
- * BlackmanHarris92 window
- *
- * \param nTableSize size of table
- * \return error code \see SMS_MALLOC in SMS_ERRORS
- */
-int sms_prepSinc(int nTableSize)
-{
- int i, m;
- sfloat N = 512.0;
- sfloat fA[4] = {.35875, .48829, .14128, .01168};
- sfloat fMax = 0;
- sfloat fTheta = -4.0 * TWO_PI / N;
- sfloat fThetaIncr = (8.0 * TWO_PI / N) / (nTableSize);
-
- sms_tab_sinc = (sfloat *)calloc(nTableSize, sizeof(sfloat));
- if(sms_tab_sinc == NULL)
- {
- sms_error("Could not allocate memory for sinc table");
- return (SMS_MALLOC);
- }
-
- for(i = 0; i < nTableSize; i++)
- {
- for (m = 0; m < 4; m++)
- sms_tab_sinc[i] += -1 * (fA[m]/2) *
- (Sinc (fTheta - m * TWO_PI/N, N) +
- Sinc (fTheta + m * TWO_PI/N, N));
- fTheta += fThetaIncr;
- }
-
- fMax = sms_tab_sinc[(int) nTableSize / 2];
- for (i = 0; i < nTableSize; i++)
- sms_tab_sinc[i] = sms_tab_sinc[i] / fMax;
-
- fSincScale = (sfloat) nTableSize / 8.0;
- return SMS_OK;
-}
-
-/*! \brief clear sine table */
-void sms_clearSinc()
-{
- if(sms_tab_sinc)
- free(sms_tab_sinc);
- sms_tab_sinc = 0;
-}
-
-/*! \brief global sinc table-lookup method
- *
- * fTheta has to be from 0 to 8
- *
- * \param fTheta angle in radians
- * \return approximately sinc(fTheta)
- */
-sfloat sms_sinc(sfloat fTheta)
-{
- int index = (int) (.5 + fSincScale * fTheta);
- return sms_tab_sinc[index];
-}
-
-
diff --git a/sms/transforms.c b/sms/transforms.c
deleted file mode 100644
index 04ab492..0000000
--- a/sms/transforms.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG)
- * UNIVERSITAT POMPEU FABRA
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-/*! \file transforms.c
- * \brief routines for different Fast Fourier Transform Algorithms
- *
- */
-
-#include "sms.h"
-#include "OOURA.h"
-
-static int ip[NMAXSQRT +2];
-static sfloat w[NMAX * 5 / 4];
-
-/*! \brief Forward Fast Fourier Transform
- *
- * function to call the OOURA routines to calculate
- * the forward FFT. Operation is in place.
- * \todo if sizeFft != power of 2, there is a silent crash.. cuidado!
- *
- * \param sizeFft size of the FFT in samples (must be a power of 2 >= 2)
- * \param pArray pointer to real array (n >= 2, n = power of 2)
- */
-void sms_fft(int sizeFft, sfloat *pArray)
-{
- rdft(sizeFft, 1, pArray, ip, w);
-}
-
-/*! \brief Inverse Forward Fast Fourier Transform
- *
- * function to call the OOURA routines to calculate
- * the Inverse FFT. Operation is in place.
- *
- * \param sizeFft size of the FFT in samples (must be a power of 2 >= 2)
- * \param pArray pointer to real array (n >= 2, n = power of 2)
- */
-void sms_ifft(int sizeFft, sfloat *pArray)
-{
- rdft(sizeFft, -1, pArray, ip, w);
-}
diff --git a/sms/windows.c b/sms/windows.c
deleted file mode 100644
index 46ca5be..0000000
--- a/sms/windows.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (c) 2008 MUSIC TECHNOLOGY GROUP (MTG)
- * UNIVERSITAT POMPEU FABRA
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*! \file windows.c
- * \brief functions for creating various windows
- *
- * Use sms_getWindow() for selecting which window will be made
- */
-#include "sms.h"
-
-/* \brief scale a window by its integral (numeric quadrature)
- *
- * In order to get a normalized magnitude spectrum (ex. Fourier analysis
- * of a sinusoid with linear magnitude 1 gives one peak of magnitude 1 in
- * the frequency domain), the spectrum windowing function should be
- * normalized by its area under the curve.
- *
- * \param sizeWindow the size of the window
- * \param pWindow pointer to an array that will hold the window
- */
-void sms_scaleWindow(int sizeWindow, sfloat *pWindow)
-{
- int i;
- sfloat fSum = 0;
- sfloat fScale;
-
- for(i = 0; i < sizeWindow; i++)
- fSum += pWindow[i];
-
- fScale = 2. / fSum;
-
- for(i = 0; i < sizeWindow; i++)
- pWindow[i] *= fScale;
-}
-
-/*! \brief window to be used in the IFFT synthesis
- *
- * contains both an inverse Blackman-Harris and triangular window.
- *
- * \todo read X. Rodet, Ph. Depalle, "Spectral Envelopes and Inverse FFT
- * Synthesis." Proc. 93rd AES Convention, October 1992
- * \param sizeWindow the size of the window
- * \param pFWindow pointer to an array that will hold the window
- */
-void IFFTwindow(int sizeWindow, sfloat *pFWindow)
-{
- int i;
- sfloat a0 = .35875, a1 = .48829, a2 = .14128, a3 = .01168;
- double fConst = TWO_PI / sizeWindow, fIncr = 2.0 /sizeWindow, fVal = 0;
-
- /* compute inverse of Blackman-Harris 92dB window */
- for(i = 0; i < sizeWindow; i++)
- {
- pFWindow[i] = 1 / (a0 - a1 * cos(fConst * i) +
- a2 * cos(fConst * 2 * i) - a3 * cos(fConst * 3 * i));
- }
-
- /* scale function by a triangular */
- for(i = 0; i < sizeWindow / 2; i++)
- {
- pFWindow[i] = fVal * pFWindow[i] / 2.787457;
- fVal += fIncr;
- }
- for(i = sizeWindow / 2; i < sizeWindow; i++)
- {
- pFWindow[i] = fVal * pFWindow[i] / 2.787457;
- fVal -= fIncr;
- }
-}
-
-/*! \brief BlackmanHarris window with 62dB rolloff
- *
- * \todo where did these come from?
- * \param sizeWindow the size of the window
- * \param pFWindow pointer to an array that will hold the window
- */
-void BlackmanHarris62(int sizeWindow, sfloat *pFWindow)
-{
- int i;
- double fSum = 0;
- /* for 3 term -62.05 */
- sfloat a0 = .44959, a1 = .49364, a2 = .05677;
- double fConst = TWO_PI / sizeWindow;
-
- /* compute window */
- for(i = 0; i < sizeWindow; i++)
- {
- fSum += pFWindow[i] = a0 - a1 * cos(fConst * i) +
- a2 * cos(fConst * 2 * i);
- }
-}
-
-/*! \brief BlackmanHarris window with 70dB rolloff
- *
- * \param sizeWindow the size of the window
- * \param pFWindow pointer to an array that will hold the window
- */
-void BlackmanHarris70(int sizeWindow, sfloat *pFWindow)
-{
- int i;
- double fSum = 0;
- /* for 3 term -70.83 */
- sfloat a0 = .42323, a1 = .49755, a2 = .07922;
- double fConst = TWO_PI / sizeWindow;
-
- /* compute window */
- for(i = 0; i < sizeWindow; i++)
- {
- fSum += pFWindow[i] = a0 - a1 * cos(fConst * i) +
- a2 * cos(fConst * 2 * i);
- }
-}
-
-/*! \brief BlackmanHarris window with 74dB rolloff
- *
- * \param sizeWindow the size of the window
- * \param pFWindow pointer to an array that will hold the window
- */
-void BlackmanHarris74(int sizeWindow, sfloat *pFWindow)
-{
- int i;
- double fSum = 0;
- /* for -74dB from the Nuttall paper */
- sfloat a0 = .40217, a1 = .49703, a2 = .09892, a3 = .00188;
- double fConst = TWO_PI / sizeWindow;
-
- /* compute window */
- for(i = 0; i < sizeWindow; i++)
- {
- fSum += pFWindow[i] = a0 - a1 * cos(fConst * i) +
- a2 * cos(fConst * 2 * i) + a3 * cos(fConst * 3 * i);
- }
-}
-
-/*! \brief BlackmanHarris window with 92dB rolloff
- *
- * \param sizeWindow the size of the window
- * \param pFWindow pointer to an array that will hold the window
- */
-void BlackmanHarris92(int sizeWindow, sfloat *pFWindow)
-{
- int i;
- double fSum = 0;
- /* for -92dB */
- sfloat a0 = .35875, a1 = .48829, a2 = .14128, a3 = .01168;
- double fConst = TWO_PI / sizeWindow;
-
- /* compute window */
- for(i = 0; i < sizeWindow; i++)
- {
- fSum += pFWindow[i] = a0 - a1 * cos(fConst * i) +
- a2 * cos(fConst * 2 * i) + a3 * cos(fConst * 3 * i);
- }
-}
-
-/*! \brief default BlackmanHarris window (70dB rolloff)
- *
- * \param sizeWindow the size of the window
- * \param pFWindow pointer to an array that will hold the window
- */
-void BlackmanHarris(int sizeWindow, sfloat *pFWindow)
-{
- BlackmanHarris70(sizeWindow, pFWindow);
-}
-
-/*! \brief Hamming window
- *
- * \param sizeWindow window size
- * \param pWindow window array
- */
-void Hamming(int sizeWindow, sfloat *pWindow)
-{
- int i;
- sfloat fSum = 0;
-
- for(i = 0; i < sizeWindow; i++)
- {
- fSum += pWindow[i] = 0.53836 - 0.46164*cos(TWO_PI*i/(sizeWindow-1));
- }
-}
-
-/*! \brief Hanning window
- *
- * \param sizeWindow window size
- * \param pWindow window array
- */
-void Hanning(int sizeWindow, sfloat *pWindow)
-{
- int i;
- for(i = 0; i < sizeWindow; i++)
- pWindow[i] = (sin(PI*i/(sizeWindow-1)))*(sin(PI*i/(sizeWindow-1)));
-}
-
-/*! \brief main function for getting various windows
- *
- * \todo note on window scales
- *
- * \see SMS_WINDOWS for the different window types available
- * \param sizeWindow window size
- * \param pFWindow window array
- * \param iWindowType the desired window type defined by #SMS_WINDOWS
- */
-void sms_getWindow(int sizeWindow, sfloat *pFWindow, int iWindowType)
-{
- switch(iWindowType)
- {
- case SMS_WIN_BH_62:
- BlackmanHarris62(sizeWindow, pFWindow);
- break;
- case SMS_WIN_BH_70:
- BlackmanHarris70(sizeWindow, pFWindow);
- break;
- case SMS_WIN_BH_74:
- BlackmanHarris74(sizeWindow, pFWindow);
- break;
- case SMS_WIN_BH_92:
- BlackmanHarris92(sizeWindow, pFWindow);
- break;
- case SMS_WIN_HAMMING:
- Hamming(sizeWindow, pFWindow);
- break;
- case SMS_WIN_HANNING:
- Hanning(sizeWindow, pFWindow);
- break;
- case SMS_WIN_IFFT:
- IFFTwindow(sizeWindow, pFWindow);
- break;
- default:
- BlackmanHarris(sizeWindow, pFWindow);
- }
-}
-
-/*! \brief apply a window and center around sample 0
- *
- * function to center a waveform around sample 0, also known
- * as 'zero-phase windowing'. Half the samples are at the beginning,
- * half at the end, with the remaining samples (sizeFft-sizeWindow)
- * in the middle (zero-padding for an interpolated spectrum).
- *
- * \todo do I need to garuntee that sizeWindow is odd-lengthed?
- *
- * \param sizeWindow size of waveform/waveform
- * \param pWaveform pointer to waveform
- * \param pWindow pointer to window
- * \param sizeFft size of FFT
- * \param pFftBuffer pointer to FFT buffer
- */
-void sms_windowCentered(int sizeWindow, sfloat *pWaveform, sfloat *pWindow,
- int sizeFft, sfloat *pFftBuffer)
-{
- int iMiddleWindow = (sizeWindow+1) >> 1;
- int iOffset = sizeFft - (iMiddleWindow - 1);
- int i;
-
- for(i=0; i<iMiddleWindow-1; i++)
- pFftBuffer[iOffset + i] = pWindow[i] * pWaveform[i];
-
- iOffset = iMiddleWindow - 1;
-
- for(i=0; i<iMiddleWindow; i++)
- pFftBuffer[i] = pWindow[iOffset + i] * pWaveform[iOffset + i];
-}