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.
Files changed (52) hide show
  1. data/VERSION +1 -1
  2. data/bin/nrec +5 -0
  3. data/lib/{c_impl → cext}/array_list.c +25 -25
  4. data/lib/cext/bent_cent_marker.c +55 -0
  5. data/lib/{c_impl/n_array_list.c → cext/c_array_list.c} +12 -12
  6. data/lib/cext/c_array_list.h +18 -0
  7. data/lib/{c_impl/n_bent_cent_marker.c → cext/c_bent_cent_marker.c} +13 -11
  8. data/lib/{c_impl/n_dft.c → cext/c_dft.c} +3 -3
  9. data/lib/{c_impl/n_discrete_cosine_transform.c → cext/c_discrete_cosine_transform.c} +5 -5
  10. data/lib/{c_impl/n_hamming_window.c → cext/c_hamming_window.c} +5 -5
  11. data/lib/{c_impl/n_live_cmn.c → cext/c_live_cmn.c} +5 -5
  12. data/lib/{c_impl/n_log_compressor.c → cext/c_log_compressor.c} +5 -5
  13. data/lib/cext/c_matrix.c +90 -0
  14. data/lib/{c_impl/n_mel_filter.c → cext/c_mel_filter.c} +13 -11
  15. data/lib/cext/c_mfcc_16x8.c +57 -0
  16. data/lib/{c_impl/noyes.h → cext/c_noyes.h} +50 -47
  17. data/lib/{c_impl/n_power_spec.c → cext/c_power_spec.c} +6 -6
  18. data/lib/{c_impl/n_preemphasis.c → cext/c_preemphasis.c} +4 -4
  19. data/lib/{c_impl/n_segmenter.c → cext/c_segmenter.c} +17 -11
  20. data/lib/cext/c_speech_trimmer.c +126 -0
  21. data/lib/{c_impl → cext}/discrete_cosine_transform.c +18 -20
  22. data/lib/{c_impl → cext}/hamming_window.c +11 -13
  23. data/lib/{c_impl → cext}/live_cmn.c +11 -14
  24. data/lib/{c_impl → cext}/log_compressor.c +11 -14
  25. data/lib/{c_impl → cext}/mel_filter.c +13 -17
  26. data/lib/cext/mfcc_16x8.c +36 -0
  27. data/lib/{c_impl → cext}/power_spectrum.c +10 -12
  28. data/lib/{c_impl → cext}/preemphasis.c +10 -13
  29. data/lib/{c_impl/noyes_c.c → cext/r_noyes.c} +12 -12
  30. data/lib/{c_impl/rnoyes.h → cext/r_noyes.h} +6 -6
  31. data/lib/{c_impl → cext}/segmenter.c +10 -13
  32. data/lib/{c_impl → cext}/speech_trimmer.c +23 -23
  33. data/lib/common/noyes_dsl.rb +3 -0
  34. data/lib/common/ruby_ext.rb +9 -0
  35. data/lib/noyes.rb +13 -0
  36. data/lib/noyes_c.rb +23 -1
  37. data/lib/noyes_java.rb +5 -0
  38. data/lib/ruby_impl/compression.rb +214 -0
  39. data/lib/ruby_impl/dct.rb +2 -2
  40. data/lib/ruby_impl/live_cmn.rb +4 -4
  41. data/lib/ruby_impl/mel_filter.rb +9 -9
  42. data/lib/ruby_impl/segment.rb +13 -2
  43. data/lib/ruby_impl/speech_trimmer.rb +3 -1
  44. data/ship/noyes.jar +0 -0
  45. metadata +36 -34
  46. data/lib/c_impl/bent_cent_marker.c +0 -36
  47. data/lib/c_impl/fast_8k_mfcc.c +0 -39
  48. data/lib/c_impl/n_array_list.h +0 -18
  49. data/lib/c_impl/n_fast_8k_mfcc.c +0 -55
  50. data/lib/c_impl/n_matrix.c +0 -72
  51. data/lib/c_impl/n_speech_trimmer.c +0 -96
  52. /data/lib/{c_impl → cext}/extconf.rb +0 -0
@@ -0,0 +1,214 @@
1
+ module Noyes
2
+
3
+ class ULaw
4
+ def << data
5
+ result = data.map do |cmn|
6
+ cmn.map do |x|
7
+ e2x = Math::E ** x.abs
8
+ Math.log(1 + 255 * e2x) / Math.log(1 + e2x)
9
+ end
10
+ end
11
+ end
12
+ end
13
+
14
+ class Compressor
15
+ def << data
16
+ @last = Array.new(data.first.size){0.0} unless @last
17
+ result = data.map do |signal|
18
+ signal.zip(@last).map do |both|
19
+ both[0] - both[1]
20
+ end
21
+ end
22
+ @last = data.last
23
+ result
24
+ end
25
+ end
26
+
27
+ class DeltaEncoder
28
+ def initialize dimensions=13
29
+ @dimensions = dimensions
30
+ @delta = Array.new dimensions, 0.0
31
+ end
32
+
33
+ def << data
34
+ data.each_slice(@dimensions).map do |array|
35
+ array.each_with_index.map do |element, index|
36
+ current_delta = @delta[index]
37
+ @delta[index] = element
38
+ element - current_delta
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ class DeltaDecoder
45
+ def initialize dimensions=13
46
+ @dimensions = dimensions
47
+ @delta = Array.new dimensions, 0.0
48
+ end
49
+
50
+ def << data
51
+ data.each_slice(@dimensions).map do |array|
52
+ array.each_with_index.map do |element, index|
53
+ @delta[index] += element
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ # Splits a float into an array containint its sign bit, its exponent, and its
60
+ # significand
61
+ class FloatSplitter
62
+ def << data
63
+ data.pack('g*').unpack('N*').map do |bits|
64
+ signbit = bits >> 31
65
+ exponent = (bits & 0x7F800000) >> 23
66
+ significand = bits & 0x007FFFFF
67
+ [signbit, exponent - 127, significand]
68
+ end
69
+ end
70
+ end
71
+
72
+ # Reassembles a float that has been dissassembled using FloatSplitter.
73
+ class FloatAssembler
74
+ def << data
75
+ data.map do |signbit, exponent, significand|
76
+ bits = signbit << 31 | 127 + exponent << 23 | significand
77
+ end.pack('N*').unpack('g*')
78
+ end
79
+ end
80
+
81
+ class BitArray
82
+ def initialize
83
+ @array = []
84
+ @end_bit = 0
85
+ @start_bit = 0
86
+ end
87
+
88
+ def size
89
+ @end_bit - @start_bit
90
+ end
91
+
92
+ def empty?
93
+ size <= 0
94
+ end
95
+
96
+ def to_s
97
+ @array.pack('N*').unpack('B*').join[@start_bit...@end_bit]
98
+ end
99
+
100
+ # Add a bit to the end of the bit array. Bits may be anything that
101
+ # evaluates to either 1 or 0. Anything else is undefined. If you can't
102
+ # afford zeros and only have the letter O, amazingly, that works too.
103
+ def push bit
104
+ @array.push 0 if @array.size <= @end_bit / 32
105
+ @array[-1] = set_bit(@array.last, @end_bit % 32) if bit == 1
106
+ @end_bit +=1
107
+ end
108
+
109
+ # Our bit array is packed into an array of 32 bit integers. This
110
+ # function sets the ith bit of an integer.
111
+ def set_bit integer, i
112
+ integer | 0x80000000 >> i
113
+ end
114
+
115
+ # Returns the first bit and removes it, shifting all bits by one.
116
+ def shift
117
+ return if @array.empty?
118
+ bit = @array.first & 0x80000000 >> @start_bit == 0 ? 0 : 1
119
+ if @start_bit == 31
120
+ @start_bit = 0
121
+ @end_bit -= 32
122
+ @array.shift
123
+ else
124
+ @start_bit += 1
125
+ end
126
+ bit
127
+ end
128
+
129
+ # Returns the ith bit of the array.
130
+ def [] i
131
+ @array[i/32] & (0x80000000 >> (i + @start_bit)) != 0 ? 1 : 0
132
+ end
133
+ end
134
+
135
+ # Takes disassembled floats and compresses them. We want them dissassembled
136
+ # because compressing exponents and signs have you unique properties and can
137
+ # be efficiently compressed with rice coding. The same is not true of the
138
+ # significand.
139
+ class GolombRiceEncoder
140
+ def initialize m = 8
141
+ @M = m
142
+ @b = Math.log2(m).to_i
143
+ end
144
+
145
+ # data is a list of disassembled floats
146
+ def << data
147
+ data.map do |b,e,s|
148
+ exp_sign_combo = b |(e << 1)
149
+ [interleave(exp_sign_combo), s]
150
+ end
151
+ end
152
+
153
+ # Map negative nubers to odd postive numbers and postive numbers to even
154
+ # positive numbers. We need to do this because negative numbers don't
155
+ # compress well with rice encoding.
156
+ def interleave x
157
+ x < 0 ? 2 * x.abs - 1 : 2 * x.abs
158
+ end
159
+
160
+ # Rice encoding returned as a BitArray.
161
+ def encode integer_array
162
+ integer_array = integer_array.clone
163
+ bits = BitArray.new
164
+ integer_array.each do |x|
165
+ q = x/@M
166
+ q.times {bits.push 1}
167
+ bits.push 0
168
+ r = x % @M
169
+ (@b-1).downto(0){|i| bits.push r[i]}
170
+ end
171
+ bits
172
+ end
173
+ end
174
+
175
+ class GolombRiceDecoder
176
+ def initialize m = 8
177
+ @M = m
178
+ @b = Math.log2(m).to_i
179
+ end
180
+ def << data
181
+ data.map do |exp_sign_combo, significand|
182
+ exp_sign_combo = deinterleave exp_sign_combo
183
+ sign = exp_sign_combo & 0x00000001
184
+ exp = exp_sign_combo >> 1
185
+ [sign, exp, significand]
186
+ end
187
+ end
188
+ def deinterleave x
189
+ x.odd? ? (x + 1)/-2 : x/2
190
+ end
191
+
192
+ def decode bits
193
+ int_array = []
194
+ while !bits.empty?
195
+ q = 0
196
+ nr = 0
197
+ q+=1 while bits.shift == 1
198
+ (@b-1).downto(0) do |a|
199
+ break if bits.empty?
200
+ nr += (1 << a) if bits.shift == 1
201
+ end
202
+ nr += q * @M
203
+ int_array.push nr
204
+ end
205
+ int_array
206
+ end
207
+ end
208
+
209
+ class NullCompressor
210
+ def << data
211
+ data
212
+ end
213
+ end
214
+ end
data/lib/ruby_impl/dct.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  require 'common/noyes_math'
2
2
 
3
3
  module Noyes
4
- # Takes the discrete cosing transform. Converts a n x m matrix to an n x order
5
- # matrix. ncol should be set to m.
4
+ # Takes the discrete cosing transform. Converts an n x m matrix to an n x
5
+ # order matrix. ncol should be set to m.
6
6
  class DCT
7
7
  include Math
8
8
  attr_accessor :melcos
@@ -1,8 +1,8 @@
1
1
  module Noyes
2
+ # Normalizes cepstrum means and applies them. Dimensionality remains
3
+ # unchanged. NOTE: This class resets itself automatically if bounds drift
4
+ # too much. Possibly these bounds should be parameterized.
2
5
  class LiveCMN
3
- # Normalizes cepstrum means and applies them. Dimensionality remains
4
- # unchanged. NOTE: This class resets itself automatically if bounds drift
5
- # too much. Possibly these bounds should be parameterized.
6
6
  def initialize dimensions=13, init_mean=45.0, window_size=100, shift=160
7
7
  @init_mean = init_mean; @shift = shift; @ws = window_size
8
8
  @sums = Array.new dimensions, 0
@@ -29,7 +29,7 @@ module Noyes
29
29
 
30
30
  if @means.first > 70 || @means.first < 5
31
31
  reset
32
- elsif @frame_count >= @shift
32
+ else
33
33
  @sums = @sums.map {|x| x * per_frame * @ws}
34
34
  @frame_count = @ws
35
35
  end
@@ -19,15 +19,15 @@ module Noyes
19
19
  def << power_spectra
20
20
  power_spectra.map do |spectrum|
21
21
  mel_bank = Array.new @indices.size
22
- @indices.size.times do |i|
23
- initial_index, weights = @indices[i], @weights[i]
24
- output = 0.0
25
- weights.size.times do |j|
26
- index = initial_index + j
27
- output += spectrum[index] * weights[j] if index < spectrum.length
28
- end
29
- mel_bank[i] = output
30
- end
22
+ @indices.size.times do |i|
23
+ initial_index, weights = @indices[i], @weights[i]
24
+ output = 0.0
25
+ weights.size.times do |j|
26
+ index = initial_index + j
27
+ output += spectrum[index] * weights[j] if index < spectrum.length
28
+ end
29
+ mel_bank[i] = output
30
+ end
31
31
  mel_bank
32
32
  end
33
33
  end
@@ -1,14 +1,25 @@
1
1
  module Noyes
2
2
  # Segments an array of data into an array of arrays. Inner arrays are the
3
- # size of the window.
3
+ # size of the window. The segmenter will not return less than three
4
+ # segments at a time. Here is the forumla for determining the number
5
+ # of segments produced by an array of data:
6
+ #
7
+ # if combolen >= winsize:
8
+ # nsegs = 1 + (arrlen - wsize - (arrlen - wise) % shift)/shift
9
+ # else
10
+ # combolen = 0
11
+ #
12
+ # This formula is derived from the following equation:
13
+ # arrlen = wsize + shift (nsegs - 1) + (arrlen - wsize) % shift
4
14
  class Segmenter
15
+ @@MIN_SEGMENTS = 3
5
16
  def initialize window_size, shift
6
17
  @winsz = window_size; @winshift = shift
7
18
  @overflow = nil
8
19
  end
9
20
  def << data
10
21
  data = @overflow + data if @overflow
11
- if data.size < @winsz + @winshift * 5
22
+ if data.size < @winsz + @winshift * @@MIN_SEGMENTS
12
23
  @overflow = data
13
24
  return nil
14
25
  else
@@ -20,7 +20,9 @@ module Noyes
20
20
 
21
21
  def << pcm
22
22
  return if eos?
23
- (@segmenter << pcm).inject [] do |memo, centisec|
23
+ segments = @segmenter << pcm
24
+ return unless segments
25
+ segments.inject [] do |memo, centisec|
24
26
  enqueue centisec unless eos?
25
27
  while x = dequeue
26
28
  memo << x
data/ship/noyes.jar ADDED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: noyes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe Woelfel
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-06-30 00:00:00 -04:00
12
+ date: 2010-08-03 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -32,43 +32,43 @@ executables:
32
32
  - noyes_dump8k
33
33
  - nrec
34
34
  extensions:
35
- - lib/c_impl/extconf.rb
35
+ - lib/cext/extconf.rb
36
36
  extra_rdoc_files:
37
37
  - COPYING
38
38
  - FAQ
39
39
  files:
40
40
  - VERSION
41
- - lib/c_impl/array_list.c
42
- - lib/c_impl/bent_cent_marker.c
43
- - lib/c_impl/discrete_cosine_transform.c
44
- - lib/c_impl/extconf.rb
45
- - lib/c_impl/fast_8k_mfcc.c
46
- - lib/c_impl/hamming_window.c
47
- - lib/c_impl/live_cmn.c
48
- - lib/c_impl/log_compressor.c
49
- - lib/c_impl/mel_filter.c
50
- - lib/c_impl/n_array_list.c
51
- - lib/c_impl/n_array_list.h
52
- - lib/c_impl/n_bent_cent_marker.c
53
- - lib/c_impl/n_dft.c
54
- - lib/c_impl/n_discrete_cosine_transform.c
55
- - lib/c_impl/n_fast_8k_mfcc.c
56
- - lib/c_impl/n_hamming_window.c
57
- - lib/c_impl/n_live_cmn.c
58
- - lib/c_impl/n_log_compressor.c
59
- - lib/c_impl/n_matrix.c
60
- - lib/c_impl/n_mel_filter.c
61
- - lib/c_impl/n_power_spec.c
62
- - lib/c_impl/n_preemphasis.c
63
- - lib/c_impl/n_segmenter.c
64
- - lib/c_impl/n_speech_trimmer.c
65
- - lib/c_impl/noyes.h
66
- - lib/c_impl/noyes_c.c
67
- - lib/c_impl/power_spectrum.c
68
- - lib/c_impl/preemphasis.c
69
- - lib/c_impl/rnoyes.h
70
- - lib/c_impl/segmenter.c
71
- - lib/c_impl/speech_trimmer.c
41
+ - lib/cext/array_list.c
42
+ - lib/cext/bent_cent_marker.c
43
+ - lib/cext/c_array_list.c
44
+ - lib/cext/c_array_list.h
45
+ - lib/cext/c_bent_cent_marker.c
46
+ - lib/cext/c_dft.c
47
+ - lib/cext/c_discrete_cosine_transform.c
48
+ - lib/cext/c_hamming_window.c
49
+ - lib/cext/c_live_cmn.c
50
+ - lib/cext/c_log_compressor.c
51
+ - lib/cext/c_matrix.c
52
+ - lib/cext/c_mel_filter.c
53
+ - lib/cext/c_mfcc_16x8.c
54
+ - lib/cext/c_noyes.h
55
+ - lib/cext/c_power_spec.c
56
+ - lib/cext/c_preemphasis.c
57
+ - lib/cext/c_segmenter.c
58
+ - lib/cext/c_speech_trimmer.c
59
+ - lib/cext/discrete_cosine_transform.c
60
+ - lib/cext/extconf.rb
61
+ - lib/cext/hamming_window.c
62
+ - lib/cext/live_cmn.c
63
+ - lib/cext/log_compressor.c
64
+ - lib/cext/mel_filter.c
65
+ - lib/cext/mfcc_16x8.c
66
+ - lib/cext/power_spectrum.c
67
+ - lib/cext/preemphasis.c
68
+ - lib/cext/r_noyes.c
69
+ - lib/cext/r_noyes.h
70
+ - lib/cext/segmenter.c
71
+ - lib/cext/speech_trimmer.c
72
72
  - lib/common.rb
73
73
  - lib/common/file2pcm.rb
74
74
  - lib/common/mock_noyes_server.rb
@@ -97,6 +97,7 @@ files:
97
97
  - lib/noyes_c.rb
98
98
  - lib/noyes_java.rb
99
99
  - lib/ruby_impl/bent_cent_marker.rb
100
+ - lib/ruby_impl/compression.rb
100
101
  - lib/ruby_impl/dct.rb
101
102
  - lib/ruby_impl/delta.rb
102
103
  - lib/ruby_impl/discrete_fourier_transform.rb
@@ -109,6 +110,7 @@ files:
109
110
  - lib/ruby_impl/preemphasis.rb
110
111
  - lib/ruby_impl/segment.rb
111
112
  - lib/ruby_impl/speech_trimmer.rb
113
+ - ship/noyes.jar
112
114
  - COPYING
113
115
  - FAQ
114
116
  has_rdoc: true
@@ -1,36 +0,0 @@
1
- #include "ruby.h"
2
- #include "noyes.h"
3
- #include "rnoyes.h"
4
-
5
- static int id_push;
6
-
7
- VALUE cBentCentMarker;
8
-
9
- static void bent_cent_marker_free(void *p) {
10
- free_bent_cent_marker(p);
11
- }
12
-
13
- static VALUE t_init(VALUE self) {
14
- BentCentMarker *pre = new_bent_cent_marker();
15
- VALUE prev = Data_Wrap_Struct(cBentCentMarker, 0, bent_cent_marker_free, pre);
16
- rb_iv_set(self, "@bent_cent_marker", prev);
17
- return self;
18
- }
19
-
20
- static VALUE t_left_shift(VALUE self, VALUE obj) {
21
- NMatrix1 *M = v_2_nmatrix1(obj);
22
- BentCentMarker *pre;
23
- VALUE prev = rb_iv_get(self, "@bent_cent_marker");
24
- Data_Get_Struct(prev, BentCentMarker, pre);
25
- int res = bent_cent_marker_apply(pre, M);
26
- free_nmatrix1(M);
27
- return res ? Qtrue : Qfalse;
28
- }
29
-
30
- void Init_bent_cent_marker() {
31
- VALUE m_noyes_c = rb_define_module("NoyesC");
32
- cBentCentMarker = rb_define_class_under(m_noyes_c, "BentCentMarker", rb_cObject);
33
- rb_define_method(cBentCentMarker, "initialize", t_init, 0);
34
- rb_define_method(cBentCentMarker, "<<", t_left_shift, 1);
35
- id_push = rb_intern("push");
36
- }
@@ -1,39 +0,0 @@
1
- #include "ruby.h"
2
- #include "noyes.h"
3
- #include "rnoyes.h"
4
-
5
- static int id_push;
6
-
7
- VALUE cFast8kMfcc;
8
-
9
- static void fast_8k_mfcc_free(Fast8kMfcc *p) {
10
- free_fast_8k_mfcc(p);
11
- }
12
-
13
- static VALUE t_init(VALUE self, VALUE args) {
14
- Fast8kMfcc *s = new_fast_8k_mfcc();
15
- VALUE fast_8k_mfcc = Data_Wrap_Struct(cFast8kMfcc, 0, fast_8k_mfcc_free, s);
16
- rb_iv_set(self, "@fast_8k_mfcc", fast_8k_mfcc);
17
-
18
- return self;
19
- }
20
-
21
- static VALUE t_left_shift(VALUE self, VALUE obj) {
22
- NMatrix1 *M = v_2_nmatrix1(obj);
23
- VALUE fast_8k_mfcc = rb_iv_get(self, "@fast_8k_mfcc");
24
- Fast8kMfcc *s;
25
- Data_Get_Struct(fast_8k_mfcc, Fast8kMfcc, s);
26
- NMatrix *N = fast_8k_mfcc_apply(s, M);
27
- VALUE result = nmatrix_2_v(N);
28
- free_nmatrix(N);
29
- free_nmatrix1(M);
30
- return result;
31
- }
32
-
33
- void Init_fast_8k_mfcc() {
34
- VALUE m_noyes_c = rb_define_module("NoyesC");
35
- cFast8kMfcc = rb_define_class_under(m_noyes_c, "Fast8kMfcc", rb_cObject);
36
- rb_define_method(cFast8kMfcc, "initialize", t_init, -2);
37
- rb_define_method(cFast8kMfcc, "<<", t_left_shift, 1);
38
- id_push = rb_intern("push");
39
- }
@@ -1,18 +0,0 @@
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
- } NList;
9
-
10
- NList * n_list_new();
11
- void n_list_free(NList * self);
12
- int n_list_size(const NList * self);
13
- int n_list_add(NList * self, void * object);
14
- int n_list_remove(NList * self, int start, int finish);
15
- void * n_list_get(const NList * self, const int index);
16
- int n_list_is_empty(const NList * self);
17
-
18
- #endif
@@ -1,55 +0,0 @@
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
- }
@@ -1,72 +0,0 @@
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
- }
41
-
42
- // Converts a square matrix to a list of one dimensional matrices.
43
- // Simultaneously frees the original square matrix.
44
- NMatrix1 ** nmatrix_2_nmatrix1s(NMatrix *M) {
45
- NMatrix1 **single = malloc(sizeof(NMatrix1*) * M->rows);
46
- int i;
47
- for (i=0;i<M->rows;++i) {
48
- single[i] = malloc(sizeof(NMatrix1));
49
- single[i]->data = M->data[i];
50
- single[i]->rows = M->cols;
51
- }
52
- free(M->data);
53
- free(M);
54
- return single;
55
- }
56
-
57
- // Converts an array of one dimensional arrays into a square matrix. It frees
58
- // these arrays in the process.
59
- NMatrix * nmatrix1_2_nmatrix(NMatrix1 **array, int size) {
60
- if (size ==0)
61
- return NULL;
62
- NMatrix *result = malloc(sizeof(NMatrix));
63
- result->data = malloc(sizeof(double*) * size);
64
- result->rows = size;
65
- int i;
66
- for (i=0; i<size; ++i) {
67
- result->data[i] = array[i]->data;
68
- free(array[i]);
69
- }
70
-
71
- return result;
72
- }