noyes 0.6.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +2 -2
- data/VERSION +1 -0
- data/bin/mock_noyes_server +27 -0
- data/bin/nrec +80 -21
- data/lib/c_impl/discrete_cosine_transform.c +60 -0
- data/lib/c_impl/extconf.rb +2 -0
- data/lib/c_impl/fast_8k_mfcc.c +39 -0
- data/lib/c_impl/hamming_window.c +41 -0
- data/lib/c_impl/live_cmn.c +49 -0
- data/lib/c_impl/log_compressor.c +43 -0
- data/lib/c_impl/mel_filter.c +115 -0
- data/lib/c_impl/n_dft.c +63 -0
- data/lib/c_impl/n_discrete_cosine_transform.c +46 -0
- data/lib/c_impl/n_fast_8k_mfcc.c +55 -0
- data/lib/c_impl/n_hamming_window.c +30 -0
- data/lib/c_impl/n_live_cmn.c +72 -0
- data/lib/c_impl/n_log_compressor.c +21 -0
- data/lib/c_impl/n_matrix.c +40 -0
- data/lib/c_impl/n_mel_filter.c +152 -0
- data/lib/c_impl/n_power_spec.c +27 -0
- data/lib/c_impl/n_preemphasis.c +25 -0
- data/lib/c_impl/n_segmenter.c +61 -0
- data/lib/c_impl/noyes.h +151 -0
- data/lib/c_impl/noyes_c.c +88 -0
- data/lib/c_impl/power_spectrum.c +42 -0
- data/lib/c_impl/preemphasis.c +43 -0
- data/lib/c_impl/rnoyes.h +17 -0
- data/lib/c_impl/segmenter.c +48 -0
- data/lib/common/file2pcm.rb +9 -0
- data/lib/common/mock_noyes_server.rb +102 -0
- data/lib/common/noyes_protocol.rb +10 -0
- data/lib/common/send_incrementally.rb +48 -23
- data/lib/common.rb +1 -0
- data/lib/noyes_c.rb +2 -0
- data/ship/noyes.jar +0 -0
- metadata +45 -6
@@ -0,0 +1,55 @@
|
|
1
|
+
#include "noyes.h"
|
2
|
+
|
3
|
+
Fast8kMfcc * new_fast_8k_mfcc() {
|
4
|
+
double factor = 0.97;
|
5
|
+
int nfilt = 32;
|
6
|
+
int min_freq = 200;
|
7
|
+
int max_freq = 3700;
|
8
|
+
int nfft = 256*2;
|
9
|
+
int freq = 8000*2;
|
10
|
+
int shift = 80*2;
|
11
|
+
int frame_size = 205*2;
|
12
|
+
double log_zero = -0.00001;
|
13
|
+
int dimensions=13;
|
14
|
+
int cmn_init_mean=45.0;
|
15
|
+
int cmn_window_size=100;
|
16
|
+
int cmn_shift=160;
|
17
|
+
|
18
|
+
Fast8kMfcc *self = malloc(sizeof(Fast8kMfcc));
|
19
|
+
self->pre = new_preemphasizer(factor);
|
20
|
+
self->seg = new_segmenter(frame_size, shift);
|
21
|
+
self->ham = new_hamming_window(frame_size);
|
22
|
+
self->pow = new_power_spectrum(nfft);
|
23
|
+
self->mel = new_mel_filter(freq, nfft, nfilt, min_freq, max_freq);
|
24
|
+
self->log = new_log_compressor(log_zero);
|
25
|
+
self->dct = new_dct(dimensions, nfilt);
|
26
|
+
self->cmn = new_live_cmn(dimensions, cmn_init_mean, cmn_window_size, cmn_shift);
|
27
|
+
return self;
|
28
|
+
}
|
29
|
+
|
30
|
+
void free_fast_8k_mfcc(Fast8kMfcc *self) {
|
31
|
+
free(self->seg);
|
32
|
+
free(self->ham);
|
33
|
+
free(self->pow);
|
34
|
+
free(self->mel);
|
35
|
+
free(self->log);
|
36
|
+
free(self->dct);
|
37
|
+
free(self->cmn);
|
38
|
+
free(self);
|
39
|
+
}
|
40
|
+
|
41
|
+
NMatrix *fast_8k_mfcc_apply(Fast8kMfcc *self, NMatrix1 * data) {
|
42
|
+
NMatrix *M = NULL;
|
43
|
+
NMatrix *N = NULL;
|
44
|
+
NMatrix1 *data1 = preemphasizer_apply(self->pre, data);
|
45
|
+
M = segmenter_apply(self->seg, data1); free_nmatrix1(data1);
|
46
|
+
if (!M)
|
47
|
+
return NULL;
|
48
|
+
N = hamming_window_apply(self->ham, M); free_nmatrix(M);
|
49
|
+
M = power_spectrum_apply(self->pow, N); free_nmatrix(N);
|
50
|
+
N = mel_filter_apply(self->mel, M); free_nmatrix(M);
|
51
|
+
M = log_compressor_apply(self->log, N); free_nmatrix(N);
|
52
|
+
N = dct_apply(self->dct, M); free_nmatrix(M);
|
53
|
+
M = live_cmn_apply(self->cmn, N); free_nmatrix(N);
|
54
|
+
return M;
|
55
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#include "noyes.h"
|
2
|
+
#include "math.h"
|
3
|
+
|
4
|
+
HammingWindow * new_hamming_window(int window_size) {
|
5
|
+
HammingWindow *hw = malloc(sizeof(HammingWindow));
|
6
|
+
hw->buf = malloc(window_size * sizeof(double));
|
7
|
+
hw->buflen = window_size;
|
8
|
+
double twopi = M_PI * 2;
|
9
|
+
int i;
|
10
|
+
for (i=0;i<window_size;++i) {
|
11
|
+
hw->buf[i] = 0.54 - 0.46*cos(twopi*i/(window_size-1));
|
12
|
+
}
|
13
|
+
return hw;
|
14
|
+
}
|
15
|
+
|
16
|
+
void free_hamming_window(HammingWindow *hw) {
|
17
|
+
free(hw->buf);
|
18
|
+
free(hw);
|
19
|
+
}
|
20
|
+
|
21
|
+
NMatrix * hamming_window_apply(HammingWindow *self, NMatrix* N) {
|
22
|
+
NMatrix *M = new_nmatrix(N->rows, N->cols);
|
23
|
+
int i,j;
|
24
|
+
for (i=0;i<N->rows;++i) {
|
25
|
+
for (j=0;j<N->cols;++j) {
|
26
|
+
M->data[i][j] = self->buf[j] * N->data[i][j];
|
27
|
+
}
|
28
|
+
}
|
29
|
+
return M;
|
30
|
+
}
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#include "noyes.h"
|
2
|
+
#include "stdlib.h"
|
3
|
+
#include "stdio.h"
|
4
|
+
|
5
|
+
LiveCMN * new_live_cmn(int dimensions, double init_mean, int window_size,
|
6
|
+
int shift) {
|
7
|
+
LiveCMN *cmn = malloc(sizeof(LiveCMN));
|
8
|
+
cmn->init_mean = init_mean;
|
9
|
+
cmn->window_size = window_size;
|
10
|
+
cmn->shift = shift;
|
11
|
+
cmn->sums = calloc(dimensions, sizeof(double));
|
12
|
+
cmn->dimensions = dimensions;
|
13
|
+
cmn->means = calloc(dimensions, sizeof(double));
|
14
|
+
cmn->means[0] = init_mean;
|
15
|
+
cmn->frame_count=0;
|
16
|
+
return cmn;
|
17
|
+
}
|
18
|
+
|
19
|
+
void free_live_cmn(LiveCMN *cmn) {
|
20
|
+
free(cmn->sums);
|
21
|
+
free(cmn->means);
|
22
|
+
free(cmn);
|
23
|
+
}
|
24
|
+
|
25
|
+
static void live_cmn_reset(LiveCMN *self) {
|
26
|
+
int i;
|
27
|
+
for (i=0; i<self->dimensions; ++i) {
|
28
|
+
self->sums[i] = 0.0;
|
29
|
+
}
|
30
|
+
for (i=0; i<self->dimensions; ++i) {
|
31
|
+
self->means[i] = 0.0;
|
32
|
+
}
|
33
|
+
self->means[0] = self->init_mean;
|
34
|
+
self->frame_count = 0;
|
35
|
+
}
|
36
|
+
|
37
|
+
static void live_cmn_update(LiveCMN *self) {
|
38
|
+
double per_frame = 1.0 / self->frame_count;
|
39
|
+
int i;
|
40
|
+
for (i=0; i< self->dimensions; ++i) {
|
41
|
+
self->means[i] = self->sums[i] * per_frame;
|
42
|
+
}
|
43
|
+
|
44
|
+
if (self->means[0] > 70 || self->means[0] < 5) {
|
45
|
+
live_cmn_reset(self);
|
46
|
+
} else if (self->frame_count >= self->shift) {
|
47
|
+
for (i=0; i < self->dimensions; ++i) {
|
48
|
+
self->sums[i] = self->sums[i] * per_frame * self->window_size;
|
49
|
+
self->frame_count = self->window_size;
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
NMatrix *live_cmn_apply(LiveCMN *self, NMatrix *dct) {
|
55
|
+
if (dct->cols != self->dimensions) {
|
56
|
+
fprintf(stderr, "Wrong number of dimensions in live_cmn_apply\n");
|
57
|
+
return NULL;
|
58
|
+
}
|
59
|
+
NMatrix *cmn = new_nmatrix(dct->rows, dct->cols);
|
60
|
+
int i,j;
|
61
|
+
for (i=0;i<dct->rows;++i) {
|
62
|
+
for (j=0;j<dct->cols;++j) {
|
63
|
+
self->sums[j] += dct->data[i][j];
|
64
|
+
cmn->data[i][j] = dct->data[i][j] - self->means[j];
|
65
|
+
}
|
66
|
+
++self->frame_count;
|
67
|
+
if (self->frame_count > self->shift) {
|
68
|
+
live_cmn_update(self);
|
69
|
+
}
|
70
|
+
}
|
71
|
+
return cmn;
|
72
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#include "noyes.h"
|
2
|
+
#include "math.h"
|
3
|
+
|
4
|
+
LogCompressor * new_log_compressor(double log_zero) {
|
5
|
+
return malloc(sizeof(LogCompressor));
|
6
|
+
}
|
7
|
+
|
8
|
+
void free_log_compressor(LogCompressor *lc) {
|
9
|
+
free(lc);
|
10
|
+
}
|
11
|
+
|
12
|
+
NMatrix * log_compressor_apply(LogCompressor *self, NMatrix *data) {
|
13
|
+
NMatrix *M = new_nmatrix(data->rows, data->cols);
|
14
|
+
int i, j;
|
15
|
+
for (i=0;i<M->rows;++i) {
|
16
|
+
for (j=0;j<M->cols;++j) {
|
17
|
+
M->data[i][j] = data->data[i][j] > 0 ? log(data->data[i][j]) : self->log_zero;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
return M;
|
21
|
+
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#include "noyes.h"
|
2
|
+
|
3
|
+
// A 2 dimensional matrix "class".
|
4
|
+
NMatrix *new_nmatrix(int rows, int cols) {
|
5
|
+
NMatrix *M = malloc(sizeof(NMatrix));
|
6
|
+
M->data = malloc(rows * sizeof(double*));
|
7
|
+
int i;
|
8
|
+
for (i=0;i<rows;++i) {
|
9
|
+
M->data[i] = malloc(cols * sizeof(double));
|
10
|
+
}
|
11
|
+
M->rows = rows;
|
12
|
+
M->cols = cols;
|
13
|
+
return M;
|
14
|
+
}
|
15
|
+
|
16
|
+
void free_nmatrix(NMatrix *M) {
|
17
|
+
if (M) {
|
18
|
+
int i;
|
19
|
+
for (i=0;i<M->rows;++i) {
|
20
|
+
free(M->data[i]);
|
21
|
+
}
|
22
|
+
free(M->data);
|
23
|
+
free(M);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
// A 1 dimensional matrix "class".
|
28
|
+
NMatrix1 *new_nmatrix1(int rows) {
|
29
|
+
NMatrix1 *M = malloc(sizeof(NMatrix1));
|
30
|
+
M->data = malloc(rows * sizeof(double));
|
31
|
+
M->rows = rows;
|
32
|
+
return M;
|
33
|
+
}
|
34
|
+
|
35
|
+
void free_nmatrix1(NMatrix1 *M) {
|
36
|
+
if (M) {
|
37
|
+
free(M->data);
|
38
|
+
free(M);
|
39
|
+
}
|
40
|
+
}
|
@@ -0,0 +1,152 @@
|
|
1
|
+
#include "noyes.h"
|
2
|
+
#include "stdlib.h"
|
3
|
+
#include "memory.h"
|
4
|
+
#include "math.h"
|
5
|
+
|
6
|
+
NMatrix1 * make_filter(double left, double center, double right,
|
7
|
+
double initFreq, double delta);
|
8
|
+
|
9
|
+
MelFilter * new_mel_filter(int srate, int nfft, int nfilt, int lowerf, int upperf) {
|
10
|
+
MelFilter *mf = malloc(sizeof(MelFilter));
|
11
|
+
NMatrix *params = make_bank_parameters(srate, nfft, nfilt, lowerf, upperf);
|
12
|
+
mf->len = params->rows;
|
13
|
+
mf->indices = malloc(params->rows * sizeof(int));
|
14
|
+
mf->weights = malloc(params->rows * sizeof(double*));
|
15
|
+
mf->weightlens = malloc(params->rows * sizeof(int));
|
16
|
+
int i;
|
17
|
+
for (i=0; i<params->rows;++i) {
|
18
|
+
NMatrix1 * temp = make_filter(params->data[i][0], params->data[i][1],
|
19
|
+
params->data[i][2], params->data[i][3],
|
20
|
+
params->data[i][4]);
|
21
|
+
mf->indices[i] = round(temp->data[0]);
|
22
|
+
int weightlen = temp->rows-1;
|
23
|
+
mf->weights[i] = malloc(sizeof(double) * weightlen);
|
24
|
+
mf->weightlens[i] = weightlen;
|
25
|
+
int j;
|
26
|
+
for (j=0; j<weightlen; ++j) {
|
27
|
+
double foo = temp->data[j+1];
|
28
|
+
mf->weights[i][j] = foo;
|
29
|
+
}
|
30
|
+
}
|
31
|
+
return mf;
|
32
|
+
}
|
33
|
+
|
34
|
+
NMatrix * mel_filter_apply(MelFilter* self, NMatrix * power_spectrum) {
|
35
|
+
NMatrix *melbanks = new_nmatrix(power_spectrum->rows, self->len);
|
36
|
+
int i;
|
37
|
+
for (i=0;i<power_spectrum->rows; ++i) {
|
38
|
+
double * spectrum = power_spectrum->data[i];
|
39
|
+
int j;
|
40
|
+
for (j=0;j<self->len; ++j) {
|
41
|
+
int initialIndex = self->indices[j];
|
42
|
+
int lenw = self->weightlens[j];
|
43
|
+
double * w = self->weights[j];
|
44
|
+
double output = 0.0;
|
45
|
+
int k;
|
46
|
+
for (k=0;k<lenw;++k) {
|
47
|
+
int index = initialIndex + k;
|
48
|
+
if (index < power_spectrum->cols) {
|
49
|
+
output += spectrum[index] * w[k];
|
50
|
+
}
|
51
|
+
}
|
52
|
+
melbanks->data[i][j] = output;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
return melbanks;
|
56
|
+
}
|
57
|
+
|
58
|
+
void free_mel_filter(MelFilter* mf) {
|
59
|
+
int i;
|
60
|
+
for (i=0;i<mf->len;++i) {
|
61
|
+
free(mf->weights[i]);
|
62
|
+
}
|
63
|
+
free(mf->weights);
|
64
|
+
free(mf->weightlens);
|
65
|
+
free(mf->indices);
|
66
|
+
}
|
67
|
+
|
68
|
+
double mel(double f) {
|
69
|
+
return 2595.0 * log10(1.0 + f/700.0);
|
70
|
+
}
|
71
|
+
|
72
|
+
static double determine_bin(double inFreq,double stepFreq) {
|
73
|
+
return stepFreq * round(inFreq / stepFreq);
|
74
|
+
}
|
75
|
+
|
76
|
+
double melinv(double m) {
|
77
|
+
return 700.0 * (pow(10, m/2595.0) - 1.0);
|
78
|
+
}
|
79
|
+
|
80
|
+
//static double[] melinv_array(double[] m) {
|
81
|
+
// double[] result = new double[m.length];
|
82
|
+
// for (int i=0;i<m.length;++i) {
|
83
|
+
// result[i] = melinv(m[i]);
|
84
|
+
// }
|
85
|
+
// return result;
|
86
|
+
//}
|
87
|
+
|
88
|
+
NMatrix *make_bank_parameters(double srate, int nfft, int nfilt,
|
89
|
+
double lowerf, double upperf) {
|
90
|
+
double * leftEdge = alloca(nfilt*sizeof(double));
|
91
|
+
double * rightEdge = alloca(nfilt*sizeof(double));
|
92
|
+
double * centerFreq = alloca(nfilt*sizeof(double));
|
93
|
+
double melmax = mel(upperf);
|
94
|
+
double melmin = mel(lowerf);
|
95
|
+
double deltaFreqMel = (melmax - melmin) / (nfilt + 1.0);
|
96
|
+
double deltaFreq = srate/nfft;
|
97
|
+
leftEdge[0] = determine_bin(lowerf, deltaFreq);
|
98
|
+
double nextEdgeMel = melmin;
|
99
|
+
int i;
|
100
|
+
for (i=0;i<nfilt;++i) {
|
101
|
+
nextEdgeMel += deltaFreqMel;
|
102
|
+
double nextEdge = melinv(nextEdgeMel);
|
103
|
+
centerFreq[i] = determine_bin(nextEdge, deltaFreq);
|
104
|
+
if (i > 0) {
|
105
|
+
rightEdge[i-1] = centerFreq[i];
|
106
|
+
} if (i < nfilt -1) {
|
107
|
+
leftEdge[i+1] = centerFreq[i];
|
108
|
+
}
|
109
|
+
}
|
110
|
+
|
111
|
+
nextEdgeMel += deltaFreqMel;
|
112
|
+
double nextEdge = melinv(nextEdgeMel);
|
113
|
+
rightEdge[nfilt-1] = determine_bin(nextEdge, deltaFreq);
|
114
|
+
NMatrix *fparams = new_nmatrix(nfilt, 5);
|
115
|
+
for (i=0;i<nfilt;++i) {
|
116
|
+
double initialFreqBin = determine_bin(leftEdge[i], deltaFreq);
|
117
|
+
if (initialFreqBin < leftEdge[i]) {
|
118
|
+
initialFreqBin += deltaFreq;
|
119
|
+
}
|
120
|
+
fparams->data[i][0] = leftEdge[i];
|
121
|
+
fparams->data[i][1] = centerFreq[i];
|
122
|
+
fparams->data[i][2] = rightEdge[i];
|
123
|
+
fparams->data[i][3] = initialFreqBin;
|
124
|
+
fparams->data[i][4] = deltaFreq;
|
125
|
+
}
|
126
|
+
return fparams;
|
127
|
+
}
|
128
|
+
|
129
|
+
// Returns an array of weights with one additional element at the zero
|
130
|
+
// location containing the starting index.
|
131
|
+
NMatrix1 * make_filter(double left, double center, double right,
|
132
|
+
double initFreq, double delta) {
|
133
|
+
int nElements = round((right - left)/ delta + 1);
|
134
|
+
NMatrix1 * filter = new_nmatrix1(nElements + 1);
|
135
|
+
double height=1.0;
|
136
|
+
double leftSlope = height / (center - left);
|
137
|
+
double rightSlope = height / (center - right);
|
138
|
+
int indexFW =1;
|
139
|
+
filter->data[0] = round(initFreq/delta);
|
140
|
+
double current;
|
141
|
+
for (current=initFreq; current<=right; current+= delta) {
|
142
|
+
if (current < center) {
|
143
|
+
filter->data[indexFW] = leftSlope * (current - left);
|
144
|
+
} else {
|
145
|
+
filter->data[indexFW] = height + rightSlope * (current - center);
|
146
|
+
}
|
147
|
+
indexFW += 1;
|
148
|
+
}
|
149
|
+
|
150
|
+
return filter;
|
151
|
+
}
|
152
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#include "noyes.h"
|
2
|
+
#include "stdlib.h"
|
3
|
+
#include "math.h"
|
4
|
+
|
5
|
+
PowerSpectrum * new_power_spectrum(int nfft) {
|
6
|
+
PowerSpectrum *ps = malloc(sizeof(PowerSpectrum));
|
7
|
+
ps->nfft = nfft;
|
8
|
+
ps->n_uniq_fft_points = nfft/2 + 1;
|
9
|
+
return ps;
|
10
|
+
}
|
11
|
+
|
12
|
+
void free_power_spectrum(PowerSpectrum * self) {
|
13
|
+
free(self);
|
14
|
+
}
|
15
|
+
|
16
|
+
NMatrix *power_spectrum_apply(PowerSpectrum *self, NMatrix *data) {
|
17
|
+
NMatrix *ps = new_nmatrix(data->rows, self->n_uniq_fft_points);
|
18
|
+
int i,j;
|
19
|
+
for (i=0;i<data->rows;++i) {
|
20
|
+
NMatrix * ffts = dft(data->data[i], data->cols, self->nfft);
|
21
|
+
for (j=0;j<self->n_uniq_fft_points;++j) {
|
22
|
+
ps->data[i][j] = pow(ffts->data[0][j],2) + pow(ffts->data[1][j],2);
|
23
|
+
}
|
24
|
+
free_nmatrix(ffts);
|
25
|
+
}
|
26
|
+
return ps;
|
27
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#include "noyes.h"
|
2
|
+
|
3
|
+
Preemphasizer * new_preemphasizer(double factor) {
|
4
|
+
Preemphasizer *self = malloc(sizeof(Preemphasizer));
|
5
|
+
self->factor = factor;
|
6
|
+
self->prior = 0;
|
7
|
+
return self;
|
8
|
+
}
|
9
|
+
|
10
|
+
void free_preemphasizer(Preemphasizer *self) {
|
11
|
+
free(self);
|
12
|
+
}
|
13
|
+
|
14
|
+
NMatrix1 *preemphasizer_apply(Preemphasizer *self, NMatrix1 *data) {
|
15
|
+
NMatrix1 *res = new_nmatrix1(data->rows);
|
16
|
+
double current_prior = self->prior;
|
17
|
+
self->prior = data->data[data->rows-1];
|
18
|
+
int i;
|
19
|
+
for (i = 0; i < data->rows; ++i) {
|
20
|
+
double current = data->data[i];
|
21
|
+
res->data[i] = current - self->factor * current_prior;
|
22
|
+
current_prior = current;
|
23
|
+
}
|
24
|
+
return res;
|
25
|
+
}
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#include "noyes.h"
|
2
|
+
#include "memory.h"
|
3
|
+
|
4
|
+
Segmenter * new_segmenter(int winsz, int winshift) {
|
5
|
+
Segmenter *s = malloc(sizeof(Segmenter));
|
6
|
+
s->buf = NULL;
|
7
|
+
s->buflen = 0;
|
8
|
+
s->winsz = winsz;
|
9
|
+
s->winshift = winshift;
|
10
|
+
return s;
|
11
|
+
};
|
12
|
+
|
13
|
+
void free_segmenter(Segmenter *s) {
|
14
|
+
if (s->buf) {
|
15
|
+
free(s->buf);
|
16
|
+
}
|
17
|
+
|
18
|
+
free(s);
|
19
|
+
}
|
20
|
+
|
21
|
+
NMatrix * segmenter_apply(Segmenter* self, NMatrix1 *data) {
|
22
|
+
double * combo;
|
23
|
+
int combolen = 0;
|
24
|
+
if (self->buf != NULL) {
|
25
|
+
combolen = self->buflen + data->rows;
|
26
|
+
combo = alloca((combolen) * sizeof(double));
|
27
|
+
memcpy(combo, self->buf, self->buflen * sizeof(double));
|
28
|
+
memcpy(combo + self->buflen, data->data, data->rows * sizeof(double));
|
29
|
+
} else {
|
30
|
+
combo = alloca((data->rows) * sizeof(double));
|
31
|
+
combolen = data->rows;
|
32
|
+
memcpy(combo, data->data, combolen * sizeof(double));
|
33
|
+
}
|
34
|
+
if (combolen < self->winsz + self->winshift * 5) {
|
35
|
+
self->buf = realloc(self->buf, combolen * sizeof(double));
|
36
|
+
memcpy(self->buf, combo, combolen*sizeof(double));
|
37
|
+
self->buflen = combolen;
|
38
|
+
return NULL;
|
39
|
+
} else {
|
40
|
+
self->buf = NULL;
|
41
|
+
}
|
42
|
+
NMatrix *M = new_nmatrix((combolen - self->winsz)/ self->winshift+1, self->winsz);
|
43
|
+
int i = 0;
|
44
|
+
int j=0;
|
45
|
+
while (i+self->winsz <= combolen) {
|
46
|
+
memcpy(M->data[j++], combo + i, self->winsz * sizeof(double));
|
47
|
+
i+=self->winshift;
|
48
|
+
}
|
49
|
+
|
50
|
+
int bufsize = combolen- i;
|
51
|
+
if (bufsize > 0) {
|
52
|
+
// Copy the tail end of combo into buf.
|
53
|
+
self->buf = realloc(self->buf, bufsize * sizeof(double));
|
54
|
+
self->buflen = bufsize;
|
55
|
+
memcpy(self->buf, combo + (combolen - bufsize), bufsize*sizeof(double));
|
56
|
+
} else {
|
57
|
+
self->buf = NULL;
|
58
|
+
self->buflen = 0;
|
59
|
+
}
|
60
|
+
return M;
|
61
|
+
}
|
data/lib/c_impl/noyes.h
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
#include "stdlib.h"
|
2
|
+
#ifndef _NOYES_H_
|
3
|
+
#define _NOYES_H_
|
4
|
+
|
5
|
+
#ifdef __cplusplus
|
6
|
+
extern "C" {
|
7
|
+
#endif
|
8
|
+
|
9
|
+
// Matrix handling routines.
|
10
|
+
typedef struct {
|
11
|
+
double **data;
|
12
|
+
int rows;
|
13
|
+
int cols;
|
14
|
+
} NMatrix;
|
15
|
+
|
16
|
+
typedef struct {
|
17
|
+
double ***data;
|
18
|
+
int rows;
|
19
|
+
int cols;
|
20
|
+
int z;
|
21
|
+
} NMatrix3;
|
22
|
+
|
23
|
+
typedef struct {
|
24
|
+
double *data;
|
25
|
+
int rows;
|
26
|
+
} NMatrix1;
|
27
|
+
|
28
|
+
NMatrix *new_nmatrix(int rows, int cols);
|
29
|
+
void free_nmatrix(NMatrix *);
|
30
|
+
|
31
|
+
NMatrix1 *new_nmatrix1(int rows);
|
32
|
+
void free_nmatrix1(NMatrix1 *);
|
33
|
+
|
34
|
+
// Preemphasizer
|
35
|
+
typedef struct {
|
36
|
+
double factor;
|
37
|
+
double prior;
|
38
|
+
} Preemphasizer;
|
39
|
+
|
40
|
+
Preemphasizer * new_preemphasizer(double factor);
|
41
|
+
void free_preemphasizer(Preemphasizer *self);
|
42
|
+
NMatrix1 *preemphasizer_apply(Preemphasizer *self, NMatrix1 *data);
|
43
|
+
|
44
|
+
// Segmenter
|
45
|
+
typedef struct {
|
46
|
+
double * buf;
|
47
|
+
size_t buflen;
|
48
|
+
int winsz;
|
49
|
+
int winshift;
|
50
|
+
} Segmenter;
|
51
|
+
|
52
|
+
Segmenter * new_segmenter(int winsz, int winshift);
|
53
|
+
void free_segmenter(Segmenter *s);
|
54
|
+
NMatrix * segmenter_apply(Segmenter* self, NMatrix1 *data);
|
55
|
+
|
56
|
+
// Hamming Window
|
57
|
+
typedef struct {
|
58
|
+
double * buf;
|
59
|
+
size_t buflen;
|
60
|
+
} HammingWindow;
|
61
|
+
|
62
|
+
HammingWindow * new_hamming_window(int window_size);
|
63
|
+
void free_hamming_window(HammingWindow *s);
|
64
|
+
NMatrix * hamming_window_apply(HammingWindow* self, NMatrix *data);
|
65
|
+
|
66
|
+
// Power spectrum
|
67
|
+
typedef struct {
|
68
|
+
int nfft, n_uniq_fft_points;
|
69
|
+
} PowerSpectrum;
|
70
|
+
|
71
|
+
PowerSpectrum * new_power_spectrum(int nfft);
|
72
|
+
void free_power_spectrum(PowerSpectrum *);
|
73
|
+
NMatrix *power_spectrum_apply(PowerSpectrum *self, NMatrix *data);
|
74
|
+
NMatrix * dft(double * data, int datalen, int size);
|
75
|
+
|
76
|
+
// Mel Filter
|
77
|
+
typedef struct {
|
78
|
+
int len;
|
79
|
+
int * indices;
|
80
|
+
double ** weights;
|
81
|
+
int *weightlens;
|
82
|
+
} MelFilter;
|
83
|
+
|
84
|
+
MelFilter * new_mel_filter(int srate, int nfft, int nfilt, int lowerf,
|
85
|
+
int upperf);
|
86
|
+
void free_mel_filter(MelFilter* mf);
|
87
|
+
NMatrix *make_bank_parameters(double srate, int nfft, int nfilt,
|
88
|
+
double lowerf, double upperf);
|
89
|
+
NMatrix * mel_filter_apply(MelFilter* self, NMatrix * power_spectrum);
|
90
|
+
NMatrix1 * make_filter(double left, double center, double right,
|
91
|
+
double initFreq, double delta);
|
92
|
+
double melinv(double m);
|
93
|
+
double mel(double m);
|
94
|
+
|
95
|
+
// Log Compressor
|
96
|
+
typedef struct {
|
97
|
+
double log_zero;
|
98
|
+
} LogCompressor;
|
99
|
+
|
100
|
+
LogCompressor * new_log_compressor(double log_zero);
|
101
|
+
void free_log_compressor(LogCompressor *lc);
|
102
|
+
NMatrix * log_compressor_apply(LogCompressor *self, NMatrix *data);
|
103
|
+
|
104
|
+
// Discrete Cosine Transform
|
105
|
+
typedef struct {
|
106
|
+
int rows;
|
107
|
+
int cols;
|
108
|
+
double **melcos;
|
109
|
+
} DiscreteCosineTransform;
|
110
|
+
|
111
|
+
DiscreteCosineTransform * new_dct(int order, int ncol);
|
112
|
+
void free_dct(DiscreteCosineTransform *dct);
|
113
|
+
NMatrix * dct_apply(DiscreteCosineTransform *self, NMatrix *data);
|
114
|
+
|
115
|
+
typedef struct {
|
116
|
+
double * sums;
|
117
|
+
double * means;
|
118
|
+
double init_mean;
|
119
|
+
int dimensions;
|
120
|
+
int frame_count;
|
121
|
+
int window_size;
|
122
|
+
int shift;
|
123
|
+
} LiveCMN;
|
124
|
+
|
125
|
+
LiveCMN * new_live_cmn(int dimensions, double init_mean, int window_size, int shift);
|
126
|
+
void free_live_cmn(LiveCMN *lcmn);
|
127
|
+
NMatrix *live_cmn_apply(LiveCMN *self, NMatrix *data);
|
128
|
+
|
129
|
+
|
130
|
+
// Fast 8k mfcc
|
131
|
+
// This strings together all the algorithms necessary to make mfcc's from an 8k
|
132
|
+
// signal so you don't have to.
|
133
|
+
typedef struct {
|
134
|
+
Preemphasizer *pre;
|
135
|
+
Segmenter *seg;
|
136
|
+
HammingWindow *ham;
|
137
|
+
PowerSpectrum *pow;
|
138
|
+
MelFilter *mel;
|
139
|
+
LogCompressor *log;
|
140
|
+
DiscreteCosineTransform *dct;
|
141
|
+
LiveCMN *cmn;
|
142
|
+
} Fast8kMfcc;
|
143
|
+
|
144
|
+
Fast8kMfcc* new_fast_8k_mfcc();
|
145
|
+
void free_fast_8k_mfcc(Fast8kMfcc *self);
|
146
|
+
NMatrix *fast_8k_mfcc_apply(Fast8kMfcc *self, NMatrix1 *data);
|
147
|
+
|
148
|
+
#ifdef __cplusplus
|
149
|
+
}
|
150
|
+
#endif
|
151
|
+
#endif
|