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
@@ -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
|
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
|
data/lib/ruby_impl/live_cmn.rb
CHANGED
@@ -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
|
-
|
32
|
+
else
|
33
33
|
@sums = @sums.map {|x| x * per_frame * @ws}
|
34
34
|
@frame_count = @ws
|
35
35
|
end
|
data/lib/ruby_impl/mel_filter.rb
CHANGED
@@ -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
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
data/lib/ruby_impl/segment.rb
CHANGED
@@ -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 *
|
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
|
-
|
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.
|
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-
|
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/
|
35
|
+
- lib/cext/extconf.rb
|
36
36
|
extra_rdoc_files:
|
37
37
|
- COPYING
|
38
38
|
- FAQ
|
39
39
|
files:
|
40
40
|
- VERSION
|
41
|
-
- lib/
|
42
|
-
- lib/
|
43
|
-
- lib/
|
44
|
-
- lib/
|
45
|
-
- lib/
|
46
|
-
- lib/
|
47
|
-
- lib/
|
48
|
-
- lib/
|
49
|
-
- lib/
|
50
|
-
- lib/
|
51
|
-
- lib/
|
52
|
-
- lib/
|
53
|
-
- lib/
|
54
|
-
- lib/
|
55
|
-
- lib/
|
56
|
-
- lib/
|
57
|
-
- lib/
|
58
|
-
- lib/
|
59
|
-
- lib/
|
60
|
-
- lib/
|
61
|
-
- lib/
|
62
|
-
- lib/
|
63
|
-
- lib/
|
64
|
-
- lib/
|
65
|
-
- lib/
|
66
|
-
- lib/
|
67
|
-
- lib/
|
68
|
-
- lib/
|
69
|
-
- lib/
|
70
|
-
- lib/
|
71
|
-
- lib/
|
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
|
-
}
|
data/lib/c_impl/fast_8k_mfcc.c
DELETED
@@ -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
|
-
}
|
data/lib/c_impl/n_array_list.h
DELETED
@@ -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
|
data/lib/c_impl/n_fast_8k_mfcc.c
DELETED
@@ -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
|
-
}
|
data/lib/c_impl/n_matrix.c
DELETED
@@ -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
|
-
}
|