noyes 0.9.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/bin/nrec +5 -0
- data/lib/{c_impl → cext}/array_list.c +25 -25
- data/lib/cext/bent_cent_marker.c +55 -0
- data/lib/{c_impl/n_array_list.c → cext/c_array_list.c} +12 -12
- data/lib/cext/c_array_list.h +18 -0
- data/lib/{c_impl/n_bent_cent_marker.c → cext/c_bent_cent_marker.c} +13 -11
- data/lib/{c_impl/n_dft.c → cext/c_dft.c} +3 -3
- data/lib/{c_impl/n_discrete_cosine_transform.c → cext/c_discrete_cosine_transform.c} +5 -5
- data/lib/{c_impl/n_hamming_window.c → cext/c_hamming_window.c} +5 -5
- data/lib/{c_impl/n_live_cmn.c → cext/c_live_cmn.c} +5 -5
- data/lib/{c_impl/n_log_compressor.c → cext/c_log_compressor.c} +5 -5
- data/lib/cext/c_matrix.c +90 -0
- data/lib/{c_impl/n_mel_filter.c → cext/c_mel_filter.c} +13 -11
- data/lib/cext/c_mfcc_16x8.c +57 -0
- data/lib/{c_impl/noyes.h → cext/c_noyes.h} +50 -47
- data/lib/{c_impl/n_power_spec.c → cext/c_power_spec.c} +6 -6
- data/lib/{c_impl/n_preemphasis.c → cext/c_preemphasis.c} +4 -4
- data/lib/{c_impl/n_segmenter.c → cext/c_segmenter.c} +17 -11
- data/lib/cext/c_speech_trimmer.c +126 -0
- data/lib/{c_impl → cext}/discrete_cosine_transform.c +18 -20
- data/lib/{c_impl → cext}/hamming_window.c +11 -13
- data/lib/{c_impl → cext}/live_cmn.c +11 -14
- data/lib/{c_impl → cext}/log_compressor.c +11 -14
- data/lib/{c_impl → cext}/mel_filter.c +13 -17
- data/lib/cext/mfcc_16x8.c +36 -0
- data/lib/{c_impl → cext}/power_spectrum.c +10 -12
- data/lib/{c_impl → cext}/preemphasis.c +10 -13
- data/lib/{c_impl/noyes_c.c → cext/r_noyes.c} +12 -12
- data/lib/{c_impl/rnoyes.h → cext/r_noyes.h} +6 -6
- data/lib/{c_impl → cext}/segmenter.c +10 -13
- data/lib/{c_impl → cext}/speech_trimmer.c +23 -23
- data/lib/common/noyes_dsl.rb +3 -0
- data/lib/common/ruby_ext.rb +9 -0
- data/lib/noyes.rb +13 -0
- data/lib/noyes_c.rb +23 -1
- data/lib/noyes_java.rb +5 -0
- data/lib/ruby_impl/compression.rb +214 -0
- data/lib/ruby_impl/dct.rb +2 -2
- data/lib/ruby_impl/live_cmn.rb +4 -4
- data/lib/ruby_impl/mel_filter.rb +9 -9
- data/lib/ruby_impl/segment.rb +13 -2
- data/lib/ruby_impl/speech_trimmer.rb +3 -1
- data/ship/noyes.jar +0 -0
- metadata +36 -34
- data/lib/c_impl/bent_cent_marker.c +0 -36
- data/lib/c_impl/fast_8k_mfcc.c +0 -39
- data/lib/c_impl/n_array_list.h +0 -18
- data/lib/c_impl/n_fast_8k_mfcc.c +0 -55
- data/lib/c_impl/n_matrix.c +0 -72
- data/lib/c_impl/n_speech_trimmer.c +0 -96
- /data/lib/{c_impl → cext}/extconf.rb +0 -0
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
1.0.0
|
data/bin/nrec
CHANGED
@@ -107,6 +107,11 @@ def recognize file, options
|
|
107
107
|
send_incremental_features file, client, client, bits, rate
|
108
108
|
end
|
109
109
|
end
|
110
|
+
rescue Errno::ECONNREFUSED
|
111
|
+
puts "Connection refused."
|
112
|
+
puts "Possibly the IP address and port are incorrect."
|
113
|
+
puts "Or maybe the server is down. Contact Talkhouse if this persists."
|
114
|
+
exit 2
|
110
115
|
end
|
111
116
|
|
112
117
|
ARGV.each do |file|
|
@@ -1,58 +1,58 @@
|
|
1
1
|
#include "ruby.h"
|
2
|
-
#include "
|
3
|
-
#include "
|
2
|
+
#include "c_noyes.h"
|
3
|
+
#include "r_noyes.h"
|
4
4
|
|
5
5
|
static int id_push;
|
6
6
|
|
7
7
|
VALUE cArrayList;
|
8
8
|
|
9
|
-
static void
|
10
|
-
|
9
|
+
static void free_clist(void *p) {
|
10
|
+
clist_free(p);
|
11
11
|
}
|
12
12
|
|
13
13
|
static VALUE t_init(VALUE self) {
|
14
|
-
|
15
|
-
VALUE stv = Data_Wrap_Struct(cArrayList, 0,
|
16
|
-
rb_iv_set(self, "@
|
14
|
+
Clist *st = clist_new();
|
15
|
+
VALUE stv = Data_Wrap_Struct(cArrayList, 0, free_clist, st);
|
16
|
+
rb_iv_set(self, "@clist", stv);
|
17
17
|
return self;
|
18
18
|
}
|
19
19
|
|
20
20
|
static VALUE t_size(VALUE self) {
|
21
|
-
|
22
|
-
VALUE arrayv = rb_iv_get(self, "@
|
23
|
-
Data_Get_Struct(arrayv,
|
24
|
-
return INT2FIX(
|
21
|
+
Clist *array;
|
22
|
+
VALUE arrayv = rb_iv_get(self, "@clist");
|
23
|
+
Data_Get_Struct(arrayv, Clist, array);
|
24
|
+
return INT2FIX(clist_size(array));
|
25
25
|
}
|
26
26
|
|
27
27
|
static VALUE t_add(VALUE self, VALUE obj) {
|
28
|
-
|
29
|
-
VALUE arrayv = rb_iv_get(self, "@
|
30
|
-
Data_Get_Struct(arrayv,
|
31
|
-
|
28
|
+
Clist *array;
|
29
|
+
VALUE arrayv = rb_iv_get(self, "@clist");
|
30
|
+
Data_Get_Struct(arrayv, Clist, array);
|
31
|
+
clist_add(array, (void*)obj);
|
32
32
|
return Qnil;
|
33
33
|
}
|
34
34
|
|
35
35
|
static VALUE t_get(VALUE self, VALUE obj) {
|
36
|
-
|
37
|
-
VALUE arrayv = rb_iv_get(self, "@
|
38
|
-
Data_Get_Struct(arrayv,
|
39
|
-
return (VALUE)
|
36
|
+
Clist *array;
|
37
|
+
VALUE arrayv = rb_iv_get(self, "@clist");
|
38
|
+
Data_Get_Struct(arrayv, Clist, array);
|
39
|
+
return (VALUE)clist_get(array, FIX2INT(obj));
|
40
40
|
}
|
41
41
|
|
42
42
|
static VALUE t_remove(VALUE self, VALUE start, VALUE finish) {
|
43
|
-
|
44
|
-
VALUE arrayv = rb_iv_get(self, "@
|
45
|
-
Data_Get_Struct(arrayv,
|
43
|
+
Clist *array;
|
44
|
+
VALUE arrayv = rb_iv_get(self, "@clist");
|
45
|
+
Data_Get_Struct(arrayv, Clist, array);
|
46
46
|
int b = FIX2INT(start);
|
47
47
|
int e = FIX2INT(finish);
|
48
|
-
if (
|
49
|
-
int s =
|
48
|
+
if (clist_remove(array, b, e)) {
|
49
|
+
int s = clist_size(array);
|
50
50
|
rb_raise(rb_eArgError, "start = %d, finish = %d with size = %d", b, e, s);
|
51
51
|
}
|
52
52
|
return Qnil;
|
53
53
|
}
|
54
54
|
|
55
|
-
void
|
55
|
+
void Init_clist() {
|
56
56
|
VALUE m_noyes_c = rb_define_module("NoyesC");
|
57
57
|
cArrayList = rb_define_class_under(m_noyes_c, "ArrayList", rb_cObject);
|
58
58
|
rb_define_method(cArrayList, "initialize", t_init, 0);
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
#include "c_noyes.h"
|
3
|
+
#include "r_noyes.h"
|
4
|
+
|
5
|
+
VALUE cBentCentMarker;
|
6
|
+
|
7
|
+
static void _bent_cent_marker_free(void *p) {
|
8
|
+
bent_cent_marker_free(p);
|
9
|
+
}
|
10
|
+
|
11
|
+
static VALUE t_init(VALUE self, VALUE args) {
|
12
|
+
double adjustment = 0.003;
|
13
|
+
double average_number = 1.0;
|
14
|
+
double background = 100.0;
|
15
|
+
double level = 0.0;
|
16
|
+
double min_signal = 0.0;
|
17
|
+
double threshold = 10.0;
|
18
|
+
int len = RARRAY_LEN(args);
|
19
|
+
if (len > 0)
|
20
|
+
threshold = NUM2INT(rb_ary_entry(args, 0));
|
21
|
+
if (len > 1)
|
22
|
+
adjustment = NUM2INT(rb_ary_entry(args, 1));
|
23
|
+
if (len > 2)
|
24
|
+
average_number = NUM2INT(rb_ary_entry(args, 2));
|
25
|
+
if (len > 3)
|
26
|
+
background = NUM2INT(rb_ary_entry(args, 3));
|
27
|
+
if (len > 4)
|
28
|
+
level = NUM2INT(rb_ary_entry(args, 4));
|
29
|
+
if (len > 5)
|
30
|
+
min_signal = NUM2INT(rb_ary_entry(args, 5));
|
31
|
+
|
32
|
+
BentCentMarker *pre = bent_cent_marker_new(threshold, adjustment,
|
33
|
+
average_number, background, level, min_signal);
|
34
|
+
|
35
|
+
VALUE prev = Data_Wrap_Struct(cBentCentMarker, 0, _bent_cent_marker_free, pre);
|
36
|
+
rb_iv_set(self, "@bent_cent_marker", prev);
|
37
|
+
return self;
|
38
|
+
}
|
39
|
+
|
40
|
+
static VALUE t_left_shift(VALUE self, VALUE obj) {
|
41
|
+
Carr *M = r2carr(obj);
|
42
|
+
BentCentMarker *pre;
|
43
|
+
VALUE prev = rb_iv_get(self, "@bent_cent_marker");
|
44
|
+
Data_Get_Struct(prev, BentCentMarker, pre);
|
45
|
+
int res = bent_cent_marker_apply(pre, M);
|
46
|
+
carr_free(M);
|
47
|
+
return res ? Qtrue : Qfalse;
|
48
|
+
}
|
49
|
+
|
50
|
+
void Init_bent_cent_marker() {
|
51
|
+
VALUE m_noyes_c = rb_define_module("NoyesC");
|
52
|
+
cBentCentMarker = rb_define_class_under(m_noyes_c, "BentCentMarker", rb_cObject);
|
53
|
+
rb_define_method(cBentCentMarker, "initialize", t_init, -2);
|
54
|
+
rb_define_method(cBentCentMarker, "<<", t_left_shift, 1);
|
55
|
+
}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#include <string.h>
|
2
2
|
#include <stdlib.h>
|
3
3
|
#include <stdio.h>
|
4
|
-
#include "
|
4
|
+
#include "c_array_list.h"
|
5
5
|
|
6
6
|
#define NLIST_INITIAL_CAPACITY 10
|
7
7
|
#define NLIST_DELTA_CAPACITY 10
|
@@ -10,22 +10,22 @@
|
|
10
10
|
#undef FALSE
|
11
11
|
#define FALSE 0
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
self = malloc(sizeof(
|
13
|
+
Clist * clist_new() {
|
14
|
+
Clist * self;
|
15
|
+
self = malloc(sizeof(Clist));
|
16
16
|
self->capacity = NLIST_INITIAL_CAPACITY;
|
17
17
|
self->data = malloc(sizeof(void*) * self->capacity);
|
18
18
|
self->size = 0;
|
19
19
|
return self;
|
20
20
|
}
|
21
21
|
|
22
|
-
void
|
22
|
+
void clist_free(Clist * self) {
|
23
23
|
free(self->data);
|
24
24
|
free(self);
|
25
25
|
}
|
26
26
|
|
27
|
-
int
|
28
|
-
int old_size =
|
27
|
+
int clist_add(Clist * self, void * object) {
|
28
|
+
int old_size = clist_size(self);
|
29
29
|
int new_capacity;
|
30
30
|
void ** new_data;
|
31
31
|
|
@@ -42,7 +42,7 @@ int n_list_add(NList * self, void * object) {
|
|
42
42
|
return TRUE;
|
43
43
|
}
|
44
44
|
|
45
|
-
int
|
45
|
+
int clist_remove(Clist * self, int start, int finish) {
|
46
46
|
if (start > finish || finish > self->size)
|
47
47
|
return 1;
|
48
48
|
|
@@ -57,16 +57,16 @@ int n_list_remove(NList * self, int start, int finish) {
|
|
57
57
|
return 0;
|
58
58
|
}
|
59
59
|
|
60
|
-
void *
|
60
|
+
void * clist_get(const Clist * self, const int index) {
|
61
61
|
if (index < 0 || index > self->size)
|
62
62
|
return NULL;
|
63
63
|
return self->data[index];
|
64
64
|
}
|
65
65
|
|
66
|
-
int
|
67
|
-
return 0 ==
|
66
|
+
int clist_is_empty(const Clist * self) {
|
67
|
+
return 0 == clist_size(self);
|
68
68
|
}
|
69
69
|
|
70
|
-
int
|
70
|
+
int clist_size(const Clist * self) {
|
71
71
|
return self->size;
|
72
72
|
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#ifndef _N_ARRAY_LIST_H_
|
2
|
+
#define _N_ARRAY_LIST_H_
|
3
|
+
|
4
|
+
typedef struct {
|
5
|
+
int capacity;
|
6
|
+
void **data;
|
7
|
+
int size;
|
8
|
+
} Clist;
|
9
|
+
|
10
|
+
Clist * clist_new();
|
11
|
+
void clist_free(Clist * self);
|
12
|
+
int clist_size(const Clist * self);
|
13
|
+
int clist_add(Clist * self, void * object);
|
14
|
+
int clist_remove(Clist * self, int start, int finish);
|
15
|
+
void * clist_get(const Clist * self, const int index);
|
16
|
+
int clist_is_empty(const Clist * self);
|
17
|
+
|
18
|
+
#endif
|
@@ -1,23 +1,25 @@
|
|
1
|
-
#include "
|
1
|
+
#include "c_noyes.h"
|
2
2
|
#include "math.h"
|
3
3
|
#include "stdlib.h"
|
4
4
|
|
5
|
-
BentCentMarker *
|
5
|
+
BentCentMarker * bent_cent_marker_new(double threshold, double adjustment,
|
6
|
+
double average_number, double background,
|
7
|
+
double level, double min_signal) {
|
6
8
|
BentCentMarker *self = malloc(sizeof(BentCentMarker));
|
7
|
-
self->adjustment =
|
8
|
-
self->average_number =
|
9
|
-
self->background =
|
10
|
-
self->level =
|
11
|
-
self->min_signal =
|
12
|
-
self->threshold =
|
9
|
+
self->adjustment = adjustment;
|
10
|
+
self->average_number = average_number;
|
11
|
+
self->background = background;
|
12
|
+
self->level = level;
|
13
|
+
self->min_signal = min_signal;
|
14
|
+
self->threshold = threshold;
|
13
15
|
return self;
|
14
16
|
}
|
15
17
|
|
16
|
-
void
|
18
|
+
void bent_cent_marker_free(BentCentMarker *self) {
|
17
19
|
free(self);
|
18
20
|
}
|
19
21
|
|
20
|
-
double bent_cent_log_rms(BentCentMarker *self,
|
22
|
+
double bent_cent_log_rms(BentCentMarker *self, Carr *pcm) {
|
21
23
|
double sum_of_squares = 0.0;
|
22
24
|
int i;
|
23
25
|
for (i=0;i<pcm->rows;++i) {
|
@@ -28,7 +30,7 @@ double bent_cent_log_rms(BentCentMarker *self, NMatrix1 *pcm) {
|
|
28
30
|
return log(rms) * 20;
|
29
31
|
}
|
30
32
|
|
31
|
-
int bent_cent_marker_apply(BentCentMarker *self,
|
33
|
+
int bent_cent_marker_apply(BentCentMarker *self, Carr *pcm) {
|
32
34
|
int is_speech = 0;
|
33
35
|
double current = bent_cent_log_rms(self, pcm);
|
34
36
|
if (current >= self->min_signal) {
|
@@ -1,15 +1,15 @@
|
|
1
|
-
#include "
|
1
|
+
#include "c_noyes.h"
|
2
2
|
#include "stdlib.h"
|
3
3
|
#include "memory.h"
|
4
4
|
#include "math.h"
|
5
5
|
#include "stdio.h"
|
6
6
|
|
7
|
-
|
7
|
+
Cmat * dft(double * data, int datalen, int size) {
|
8
8
|
if (datalen> size) {
|
9
9
|
fprintf(stderr,"Size(%d) must be larger than data length(%d)", size, datalen);
|
10
10
|
return NULL;
|
11
11
|
}
|
12
|
-
|
12
|
+
Cmat *M = cmat_new(2, size);
|
13
13
|
double * real = M->data[0];
|
14
14
|
double * imag = M->data[1];
|
15
15
|
int j=0,i;
|
@@ -1,7 +1,7 @@
|
|
1
|
-
#include "
|
1
|
+
#include "c_noyes.h"
|
2
2
|
#include "math.h"
|
3
3
|
|
4
|
-
DiscreteCosineTransform *
|
4
|
+
DiscreteCosineTransform * dct_new(int rows, int cols) {
|
5
5
|
DiscreteCosineTransform *dct = malloc(sizeof(DiscreteCosineTransform));
|
6
6
|
dct->melcos = malloc(rows *sizeof(double*));
|
7
7
|
dct->rows = rows;
|
@@ -18,7 +18,7 @@ DiscreteCosineTransform * new_dct(int rows, int cols) {
|
|
18
18
|
return dct;
|
19
19
|
}
|
20
20
|
|
21
|
-
void
|
21
|
+
void dct_free(DiscreteCosineTransform *dct) {
|
22
22
|
int i;
|
23
23
|
for (i=0;i<dct->rows;++i) {
|
24
24
|
free(dct->melcos[i]);
|
@@ -27,8 +27,8 @@ void free_dct(DiscreteCosineTransform *dct) {
|
|
27
27
|
free(dct);
|
28
28
|
}
|
29
29
|
|
30
|
-
|
31
|
-
|
30
|
+
Cmat * dct_apply(DiscreteCosineTransform *self, Cmat *data) {
|
31
|
+
Cmat *M = cmat_new(data->rows, self->rows);
|
32
32
|
int i,j,k;
|
33
33
|
for (i=0;i<M->rows;++i) {
|
34
34
|
for (j=0;j<M->cols;++j) {
|
@@ -1,7 +1,7 @@
|
|
1
|
-
#include "
|
1
|
+
#include "c_noyes.h"
|
2
2
|
#include "math.h"
|
3
3
|
|
4
|
-
HammingWindow *
|
4
|
+
HammingWindow * hamming_window_new(int window_size) {
|
5
5
|
HammingWindow *hw = malloc(sizeof(HammingWindow));
|
6
6
|
hw->buf = malloc(window_size * sizeof(double));
|
7
7
|
hw->buflen = window_size;
|
@@ -13,13 +13,13 @@ HammingWindow * new_hamming_window(int window_size) {
|
|
13
13
|
return hw;
|
14
14
|
}
|
15
15
|
|
16
|
-
void
|
16
|
+
void hamming_window_free(HammingWindow *hw) {
|
17
17
|
free(hw->buf);
|
18
18
|
free(hw);
|
19
19
|
}
|
20
20
|
|
21
|
-
|
22
|
-
|
21
|
+
Cmat * hamming_window_apply(HammingWindow *self, Cmat* N) {
|
22
|
+
Cmat *M = cmat_new(N->rows, N->cols);
|
23
23
|
int i,j;
|
24
24
|
for (i=0;i<N->rows;++i) {
|
25
25
|
for (j=0;j<N->cols;++j) {
|
@@ -1,8 +1,8 @@
|
|
1
|
-
#include "
|
1
|
+
#include "c_noyes.h"
|
2
2
|
#include "stdlib.h"
|
3
3
|
#include "stdio.h"
|
4
4
|
|
5
|
-
LiveCMN *
|
5
|
+
LiveCMN * live_cmn_new(int dimensions, double init_mean, int window_size,
|
6
6
|
int shift) {
|
7
7
|
LiveCMN *cmn = malloc(sizeof(LiveCMN));
|
8
8
|
cmn->init_mean = init_mean;
|
@@ -16,7 +16,7 @@ LiveCMN * new_live_cmn(int dimensions, double init_mean, int window_size,
|
|
16
16
|
return cmn;
|
17
17
|
}
|
18
18
|
|
19
|
-
void
|
19
|
+
void live_cmn_free(LiveCMN *cmn) {
|
20
20
|
free(cmn->sums);
|
21
21
|
free(cmn->means);
|
22
22
|
free(cmn);
|
@@ -51,12 +51,12 @@ static void live_cmn_update(LiveCMN *self) {
|
|
51
51
|
}
|
52
52
|
}
|
53
53
|
|
54
|
-
|
54
|
+
Cmat *live_cmn_apply(LiveCMN *self, Cmat *dct) {
|
55
55
|
if (dct->cols != self->dimensions) {
|
56
56
|
fprintf(stderr, "Wrong number of dimensions in live_cmn_apply\n");
|
57
57
|
return NULL;
|
58
58
|
}
|
59
|
-
|
59
|
+
Cmat *cmn = cmat_new(dct->rows, dct->cols);
|
60
60
|
int i,j;
|
61
61
|
for (i=0;i<dct->rows;++i) {
|
62
62
|
for (j=0;j<dct->cols;++j) {
|
@@ -1,16 +1,16 @@
|
|
1
|
-
#include "
|
1
|
+
#include "c_noyes.h"
|
2
2
|
#include "math.h"
|
3
3
|
|
4
|
-
LogCompressor *
|
4
|
+
LogCompressor * log_compressor_new(double log_zero) {
|
5
5
|
return malloc(sizeof(LogCompressor));
|
6
6
|
}
|
7
7
|
|
8
|
-
void
|
8
|
+
void log_compressor_free(LogCompressor *lc) {
|
9
9
|
free(lc);
|
10
10
|
}
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
Cmat * log_compressor_apply(LogCompressor *self, Cmat *data) {
|
13
|
+
Cmat *M = cmat_new(data->rows, data->cols);
|
14
14
|
int i, j;
|
15
15
|
for (i=0;i<M->rows;++i) {
|
16
16
|
for (j=0;j<M->cols;++j) {
|
data/lib/cext/c_matrix.c
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
#include "c_noyes.h"
|
2
|
+
#include "memory.h"
|
3
|
+
|
4
|
+
// A 2 dimensional dense rectangular matrix "class".
|
5
|
+
Cmat *cmat_new(int rows, int cols) {
|
6
|
+
Cmat *M = malloc(sizeof(Cmat));
|
7
|
+
M->data = malloc(rows * sizeof(double*));
|
8
|
+
int i;
|
9
|
+
for (i=0;i<rows;++i) {
|
10
|
+
M->data[i] = malloc(cols * sizeof(double));
|
11
|
+
}
|
12
|
+
M->rows = rows;
|
13
|
+
M->cols = cols;
|
14
|
+
return M;
|
15
|
+
}
|
16
|
+
|
17
|
+
void cmat_free(Cmat *M) {
|
18
|
+
if (M) {
|
19
|
+
int i;
|
20
|
+
for (i=0;i<M->rows;++i) {
|
21
|
+
free(M->data[i]);
|
22
|
+
}
|
23
|
+
free(M->data);
|
24
|
+
free(M);
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
// A 1 dimensional matrix "class".
|
29
|
+
Carr *carr_new(int rows) {
|
30
|
+
Carr *M = malloc(sizeof(Carr));
|
31
|
+
M->data = malloc(rows * sizeof(double));
|
32
|
+
M->rows = rows;
|
33
|
+
return M;
|
34
|
+
}
|
35
|
+
|
36
|
+
void carr_free(Carr *M) {
|
37
|
+
if (M) {
|
38
|
+
free(M->data);
|
39
|
+
free(M);
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
// Converts a rectangular matrix to a list of one dimensional matrices.
|
44
|
+
// Simultaneously frees the original rectangular matrix. Actually, the matrix
|
45
|
+
// does not have to be rectangular. Column sizes may vary.
|
46
|
+
Carr ** mat2arrs(Cmat *M) {
|
47
|
+
Carr **arrs = malloc(sizeof(Carr*) * M->rows);
|
48
|
+
int i;
|
49
|
+
for (i=0;i<M->rows;++i) {
|
50
|
+
arrs[i] = malloc(sizeof(Carr));
|
51
|
+
arrs[i]->data = M->data[i];
|
52
|
+
arrs[i]->rows = M->cols;
|
53
|
+
}
|
54
|
+
free(M->data);
|
55
|
+
free(M);
|
56
|
+
return arrs;
|
57
|
+
}
|
58
|
+
|
59
|
+
// Creates an array by appending columns of a rectangular matrix. Does not
|
60
|
+
// delete the original matrix.
|
61
|
+
Carr *cmat_flatten(Cmat *M) {
|
62
|
+
Carr *flat = carr_new(M->rows * M->cols);
|
63
|
+
int i;
|
64
|
+
for (i=0;i<M->rows; ++i)
|
65
|
+
memcpy(flat->data + (M->cols * i), M->data[i], sizeof(double) * M->cols);
|
66
|
+
|
67
|
+
return flat;
|
68
|
+
}
|
69
|
+
|
70
|
+
// Converts an array of one dimensional arrays into a rectangular matrix. It
|
71
|
+
// frees these arrays in the process. All arrays must have the same length.
|
72
|
+
Cmat * arrs2mat(Carr **array, int size) {
|
73
|
+
if (size == 0) {
|
74
|
+
if (array != NULL)
|
75
|
+
free(array);
|
76
|
+
return NULL;
|
77
|
+
}
|
78
|
+
Cmat *mat = malloc(sizeof(Cmat));
|
79
|
+
mat->data = malloc(sizeof(double*) * size);
|
80
|
+
mat->rows = size;
|
81
|
+
mat->cols = array[0]->rows;
|
82
|
+
int i;
|
83
|
+
for (i=0; i<size; ++i) {
|
84
|
+
mat->data[i] = array[i]->data;
|
85
|
+
free(array[i]);
|
86
|
+
}
|
87
|
+
free(array);
|
88
|
+
|
89
|
+
return mat;
|
90
|
+
}
|
@@ -1,21 +1,21 @@
|
|
1
|
-
#include "
|
1
|
+
#include "c_noyes.h"
|
2
2
|
#include "stdlib.h"
|
3
3
|
#include "memory.h"
|
4
4
|
#include "math.h"
|
5
5
|
|
6
|
-
|
6
|
+
Carr * make_filter(double left, double center, double right,
|
7
7
|
double initFreq, double delta);
|
8
8
|
|
9
9
|
MelFilter * new_mel_filter(int srate, int nfft, int nfilt, int lowerf, int upperf) {
|
10
10
|
MelFilter *mf = malloc(sizeof(MelFilter));
|
11
|
-
|
11
|
+
Cmat *params = make_bank_parameters(srate, nfft, nfilt, lowerf, upperf);
|
12
12
|
mf->len = params->rows;
|
13
13
|
mf->indices = malloc(params->rows * sizeof(int));
|
14
14
|
mf->weights = malloc(params->rows * sizeof(double*));
|
15
15
|
mf->weightlens = malloc(params->rows * sizeof(int));
|
16
16
|
int i;
|
17
17
|
for (i=0; i<params->rows;++i) {
|
18
|
-
|
18
|
+
Carr * temp = make_filter(params->data[i][0], params->data[i][1],
|
19
19
|
params->data[i][2], params->data[i][3],
|
20
20
|
params->data[i][4]);
|
21
21
|
mf->indices[i] = round(temp->data[0]);
|
@@ -27,12 +27,14 @@ MelFilter * new_mel_filter(int srate, int nfft, int nfilt, int lowerf, int upper
|
|
27
27
|
double foo = temp->data[j+1];
|
28
28
|
mf->weights[i][j] = foo;
|
29
29
|
}
|
30
|
+
carr_free(temp);
|
30
31
|
}
|
32
|
+
cmat_free(params);
|
31
33
|
return mf;
|
32
34
|
}
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
+
Cmat * mel_filter_apply(MelFilter* self, Cmat * power_spectrum) {
|
37
|
+
Cmat *melbanks = cmat_new(power_spectrum->rows, self->len);
|
36
38
|
int i;
|
37
39
|
for (i=0;i<power_spectrum->rows; ++i) {
|
38
40
|
double * spectrum = power_spectrum->data[i];
|
@@ -55,7 +57,7 @@ NMatrix * mel_filter_apply(MelFilter* self, NMatrix * power_spectrum) {
|
|
55
57
|
return melbanks;
|
56
58
|
}
|
57
59
|
|
58
|
-
void
|
60
|
+
void mel_filter_free(MelFilter* mf) {
|
59
61
|
int i;
|
60
62
|
for (i=0;i<mf->len;++i) {
|
61
63
|
free(mf->weights[i]);
|
@@ -85,7 +87,7 @@ double melinv(double m) {
|
|
85
87
|
// return result;
|
86
88
|
//}
|
87
89
|
|
88
|
-
|
90
|
+
Cmat *make_bank_parameters(double srate, int nfft, int nfilt,
|
89
91
|
double lowerf, double upperf) {
|
90
92
|
double * leftEdge = alloca(nfilt*sizeof(double));
|
91
93
|
double * rightEdge = alloca(nfilt*sizeof(double));
|
@@ -111,7 +113,7 @@ NMatrix *make_bank_parameters(double srate, int nfft, int nfilt,
|
|
111
113
|
nextEdgeMel += deltaFreqMel;
|
112
114
|
double nextEdge = melinv(nextEdgeMel);
|
113
115
|
rightEdge[nfilt-1] = determine_bin(nextEdge, deltaFreq);
|
114
|
-
|
116
|
+
Cmat *fparams = cmat_new(nfilt, 5);
|
115
117
|
for (i=0;i<nfilt;++i) {
|
116
118
|
double initialFreqBin = determine_bin(leftEdge[i], deltaFreq);
|
117
119
|
if (initialFreqBin < leftEdge[i]) {
|
@@ -128,10 +130,10 @@ NMatrix *make_bank_parameters(double srate, int nfft, int nfilt,
|
|
128
130
|
|
129
131
|
// Returns an array of weights with one additional element at the zero
|
130
132
|
// location containing the starting index.
|
131
|
-
|
133
|
+
Carr * make_filter(double left, double center, double right,
|
132
134
|
double initFreq, double delta) {
|
133
135
|
int nElements = round((right - left)/ delta + 1);
|
134
|
-
|
136
|
+
Carr * filter = carr_new(nElements + 1);
|
135
137
|
double height=1.0;
|
136
138
|
double leftSlope = height / (center - left);
|
137
139
|
double rightSlope = height / (center - right);
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#include "c_noyes.h"
|
2
|
+
|
3
|
+
// Mfcc16x8 is a convenience class that encapsulates an entire front end that
|
4
|
+
// takes 16kHz audio and transforms it to work with 8kHz models.
|
5
|
+
Mfcc16x8 * mfcc_16x8_new() {
|
6
|
+
double factor = 0.97;
|
7
|
+
int nfilt = 32;
|
8
|
+
int min_freq = 200;
|
9
|
+
int max_freq = 3700;
|
10
|
+
int nfft = 256*2;
|
11
|
+
int freq = 8000*2;
|
12
|
+
int shift = 80*2;
|
13
|
+
int frame_size = 205*2;
|
14
|
+
double log_zero = -0.00001;
|
15
|
+
int dimensions=13;
|
16
|
+
int cmn_init_mean=45.0;
|
17
|
+
int cmn_window_size=100;
|
18
|
+
int cmn_shift=160;
|
19
|
+
|
20
|
+
Mfcc16x8 *self = malloc(sizeof(Mfcc16x8));
|
21
|
+
self->pre = new_preemphasizer(factor);
|
22
|
+
self->seg = new_segmenter(frame_size, shift);
|
23
|
+
self->ham = hamming_window_new(frame_size);
|
24
|
+
self->pow = new_power_spectrum(nfft);
|
25
|
+
self->mel = new_mel_filter(freq, nfft, nfilt, min_freq, max_freq);
|
26
|
+
self->log = log_compressor_new(log_zero);
|
27
|
+
self->dct = dct_new(dimensions, nfilt);
|
28
|
+
self->cmn = live_cmn_new(dimensions, cmn_init_mean, cmn_window_size, cmn_shift);
|
29
|
+
return self;
|
30
|
+
}
|
31
|
+
|
32
|
+
void mfcc_16x8_free(Mfcc16x8 *self) {
|
33
|
+
free(self->seg);
|
34
|
+
free(self->ham);
|
35
|
+
free(self->pow);
|
36
|
+
free(self->mel);
|
37
|
+
free(self->log);
|
38
|
+
free(self->dct);
|
39
|
+
free(self->cmn);
|
40
|
+
free(self);
|
41
|
+
}
|
42
|
+
|
43
|
+
Cmat *mfcc_16x8_apply(Mfcc16x8 *self, Carr * data) {
|
44
|
+
Cmat *M = NULL;
|
45
|
+
Cmat *N = NULL;
|
46
|
+
Carr *data1 = preemphasizer_apply(self->pre, data);
|
47
|
+
M = segmenter_apply(self->seg, data1); carr_free(data1);
|
48
|
+
if (!M)
|
49
|
+
return NULL;
|
50
|
+
N = hamming_window_apply(self->ham, M); cmat_free(M);
|
51
|
+
M = power_spectrum_apply(self->pow, N); cmat_free(N);
|
52
|
+
N = mel_filter_apply(self->mel, M); cmat_free(M);
|
53
|
+
M = log_compressor_apply(self->log, N); cmat_free(N);
|
54
|
+
N = dct_apply(self->dct, M); cmat_free(M);
|
55
|
+
M = live_cmn_apply(self->cmn, N); cmat_free(N);
|
56
|
+
return M;
|
57
|
+
}
|