noyes 0.3.2 → 0.4.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/lib/common/noyes_dsl.rb +46 -0
- data/lib/common/parallel_filter.rb +36 -0
- data/lib/common/serial_filter.rb +30 -0
- data/lib/noyes.rb +15 -13
- data/lib/ruby_impl/delta.rb +5 -9
- data/lib/ruby_impl/discrete_fourier_transform.rb +1 -4
- data/lib/ruby_impl/live_cmn.rb +39 -37
- data/lib/ruby_impl/segment.rb +7 -8
- metadata +4 -2
data/lib/common/noyes_dsl.rb
CHANGED
@@ -4,3 +4,49 @@ class Array
|
|
4
4
|
other << self
|
5
5
|
end
|
6
6
|
end
|
7
|
+
|
8
|
+
# This portion is still highly experimental. It allows filters to be combined
|
9
|
+
# in complicated ways using a syntax similar to Backus Naur Form.
|
10
|
+
module NoyesFilterDSL
|
11
|
+
def + other
|
12
|
+
other_filters = other.kind_of?(SerialFilter) ? other.filters.clone : other
|
13
|
+
SerialFilter.new [self, other].flatten
|
14
|
+
end
|
15
|
+
def | other
|
16
|
+
other_filters = other.kind_of?(ParallelFilter) ? other.filtes.clone : other
|
17
|
+
ParallelFilter.new [self, other].flatten
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module Noyes
|
22
|
+
class DCT
|
23
|
+
include NoyesFilterDSL
|
24
|
+
end
|
25
|
+
class DoubleDeltaFilter
|
26
|
+
include NoyesFilterDSL
|
27
|
+
end
|
28
|
+
class Filter
|
29
|
+
include NoyesFilterDSL
|
30
|
+
end
|
31
|
+
class HammingWindow
|
32
|
+
include NoyesFilterDSL
|
33
|
+
end
|
34
|
+
class LiveCMN
|
35
|
+
include NoyesFilterDSL
|
36
|
+
end
|
37
|
+
class LogCompressor
|
38
|
+
include NoyesFilterDSL
|
39
|
+
end
|
40
|
+
class MelFilter
|
41
|
+
include NoyesFilterDSL
|
42
|
+
end
|
43
|
+
class PowerSpectrumFilter
|
44
|
+
include NoyesFilterDSL
|
45
|
+
end
|
46
|
+
class Preemphasizer
|
47
|
+
include NoyesFilterDSL
|
48
|
+
end
|
49
|
+
class Segmenter
|
50
|
+
include NoyesFilterDSL
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module NoyesFilterDSL
|
2
|
+
class ParallelFilter
|
3
|
+
attr_reader :filters
|
4
|
+
def initialize filters=[]
|
5
|
+
@filters = filters.kind_of?(Array) ? filters : [filters]
|
6
|
+
end
|
7
|
+
def << data
|
8
|
+
if data.size != @filters.size
|
9
|
+
raise "data (%d) and filters (%d) must have same dimensions." %
|
10
|
+
[data.size, @filters.size]
|
11
|
+
end
|
12
|
+
offset = -1
|
13
|
+
@filters.map {|f| f << data[offset+=1]}
|
14
|
+
end
|
15
|
+
def + other
|
16
|
+
raise "Parameter does not respond to <<." unless other.respond_to? :<<
|
17
|
+
if other.kind_of?(ParallelFilter) && filters.size != other.filters.size
|
18
|
+
raise "Parallel filters must have equal dimensions %d vs %d " %
|
19
|
+
[filters.size, other.filters.size]
|
20
|
+
end
|
21
|
+
other_filters = if other.kind_of? SerialFilter
|
22
|
+
other.filters.clone
|
23
|
+
else
|
24
|
+
other
|
25
|
+
end
|
26
|
+
SerialFilter.new([ParallelFilter.new(filters.clone), other_filters].flatten)
|
27
|
+
end
|
28
|
+
def | other
|
29
|
+
raise "Parameter does not respond to <<." unless other.respond_to? :<<
|
30
|
+
if other.kind_of? ParallelFilter
|
31
|
+
return ParallelFilter.new(@filters + other.filters)
|
32
|
+
end
|
33
|
+
ParallelFilter.new((@filters + other).flatten)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module NoyesFilterDSL
|
2
|
+
class SerialFilter
|
3
|
+
attr_reader :filters
|
4
|
+
def initialize filters = []
|
5
|
+
@filters = filters.kind_of?(Array) ? filters : [filters]
|
6
|
+
end
|
7
|
+
def << data
|
8
|
+
@filters.each {|f| data >>= f}
|
9
|
+
data
|
10
|
+
end
|
11
|
+
def + other
|
12
|
+
raise "Parameter does not respond to <<." unless other.respond_to? :<<
|
13
|
+
if other.kind_of? SerialFilter
|
14
|
+
return SerialFilter.new(@filters.clone + other.filters.clone)
|
15
|
+
end
|
16
|
+
SerialFilter.new((@filters + [other]).flatten)
|
17
|
+
end
|
18
|
+
def | other
|
19
|
+
raise "Parameter does not respond to <<." unless other.respond_to? :<<
|
20
|
+
other_filters = if other.kind_of? Array
|
21
|
+
SerialFilter.new other
|
22
|
+
elsif other.kind_of? ParallelFilter
|
23
|
+
other_filters = other.filters
|
24
|
+
else
|
25
|
+
other
|
26
|
+
end
|
27
|
+
ParallelFilter.new([SerialFilter.new(filters), other_filters])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/noyes.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
1
|
+
require 'serial_filter'
|
2
|
+
require 'parallel_filter'
|
3
|
+
require 'noyes_dsl'
|
4
|
+
require 'noyes_math'
|
5
|
+
require 'live_cmn'
|
6
|
+
require 'dct'
|
7
|
+
require 'delta'
|
8
|
+
require 'filter'
|
9
|
+
require 'mel_filter'
|
10
|
+
require 'hamming_window'
|
11
|
+
require 'log_compress'
|
12
|
+
require 'discrete_fourier_transform'
|
13
|
+
require 'power_spec'
|
14
|
+
require 'preemphasis'
|
15
|
+
require 'segment'
|
data/lib/ruby_impl/delta.rb
CHANGED
@@ -10,15 +10,11 @@ module Noyes
|
|
10
10
|
buf = @previous + cepstra
|
11
11
|
result = []
|
12
12
|
for i in 3...(buf.size-3)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
double_delta.size.times do |k|
|
19
|
-
double_delta[k] = buf[i+3][k] - buf[i-1][k] - buf[i+1][k] + buf[i-3][k]
|
20
|
-
end
|
21
|
-
result << [buf[i], delta, double_delta]
|
13
|
+
delta = Array.new(buf[i].size) {|k| buf[i+2][k] - buf[i-2][k]}
|
14
|
+
double_delta = Array.new(buf[i].size) do |k|
|
15
|
+
buf[i+3][k] - buf[i-1][k] - buf[i+1][k] + buf[i-3][k]
|
16
|
+
end
|
17
|
+
result << [buf[i], delta, double_delta]
|
22
18
|
end
|
23
19
|
@previous = buf[-6..-1]
|
24
20
|
result
|
@@ -4,10 +4,7 @@ module Noyes
|
|
4
4
|
include Math
|
5
5
|
# Takes the discrete Fourier transform.
|
6
6
|
def dft data,size
|
7
|
-
|
8
|
-
data.size.times {|i| vals[i] = Complex(data[i],0)}
|
9
|
-
(data.size).upto(size-1) {|i| vals[i] = Complex(0,0)}
|
10
|
-
|
7
|
+
vals = Array.new(size) {|i| i < data.size ? Complex(data[i],0) : Complex(0,0)}
|
11
8
|
j=0
|
12
9
|
size.times do |i|
|
13
10
|
vals[j],vals[i] = vals[i],vals[j] if i<j
|
data/lib/ruby_impl/live_cmn.rb
CHANGED
@@ -1,42 +1,44 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
@
|
18
|
-
|
1
|
+
module Noyes
|
2
|
+
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
|
+
def initialize dimensions=13, init_mean=45.0, window_size=100, shift=160
|
7
|
+
@init_mean = init_mean; @shift = shift; @ws = window_size
|
8
|
+
@sums = Array.new dimensions, 0
|
9
|
+
@means = Array.new dimensions, 0
|
10
|
+
@means[0] = @init_mean
|
11
|
+
@frame_count = 0
|
12
|
+
end
|
13
|
+
def << dct
|
14
|
+
raise "Wrong number of dimensions" if dct[0].size != @means.size
|
15
|
+
dct.map do |mfc|
|
16
|
+
cmn = Array.new @means.size
|
17
|
+
@means.size.times do |i|
|
18
|
+
@sums[i] += mfc[i]
|
19
|
+
cmn[i] = mfc[i] - @means[i]
|
20
|
+
end
|
21
|
+
@frame_count += 1
|
22
|
+
update if @frame_count > @shift
|
23
|
+
cmn
|
19
24
|
end
|
20
|
-
@frame_count += 1
|
21
|
-
update if @frame_count > @shift
|
22
|
-
cmn
|
23
25
|
end
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
26
|
+
def update
|
27
|
+
per_frame = 1.0 / @frame_count
|
28
|
+
@means = @sums.map {|x| x * per_frame}
|
29
|
+
|
30
|
+
if @means.first > 70 || @means.first < 5
|
31
|
+
reset
|
32
|
+
elsif @frame_count >= @shift
|
33
|
+
@sums = @sums.map {|x| x * per_frame * @ws}
|
34
|
+
@frame_count = @ws
|
35
|
+
end
|
36
|
+
end
|
37
|
+
def reset
|
38
|
+
@sums.map! {0}
|
39
|
+
@means.map! {0}
|
40
|
+
@means[0] = @init_mean
|
41
|
+
@frame_count = 0
|
34
42
|
end
|
35
|
-
end
|
36
|
-
def reset
|
37
|
-
@sums.map! {0}
|
38
|
-
@means.map! {0}
|
39
|
-
@means[0] = @init_mean
|
40
|
-
@frame_count = 0
|
41
43
|
end
|
42
44
|
end
|
data/lib/ruby_impl/segment.rb
CHANGED
@@ -6,7 +6,6 @@ module Noyes
|
|
6
6
|
@winsz = window_size; @winshift = shift
|
7
7
|
@overflow = nil
|
8
8
|
end
|
9
|
-
|
10
9
|
def << data
|
11
10
|
data = @overflow + data if @overflow
|
12
11
|
if data.size < @winsz + @winshift * 5
|
@@ -15,14 +14,14 @@ module Noyes
|
|
15
14
|
else
|
16
15
|
@overflow = nil
|
17
16
|
end
|
18
|
-
|
19
|
-
|
20
|
-
while
|
21
|
-
|
22
|
-
|
17
|
+
segments = []
|
18
|
+
offset = 0
|
19
|
+
while offset + @winsz <= data.length
|
20
|
+
segments << data[offset, @winsz]
|
21
|
+
offset += @winshift
|
23
22
|
end
|
24
|
-
@overflow = data[
|
25
|
-
|
23
|
+
@overflow = data[offset..-1]
|
24
|
+
segments
|
26
25
|
end
|
27
26
|
end
|
28
27
|
end
|
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: 0.4.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-02-
|
12
|
+
date: 2010-02-02 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -28,7 +28,9 @@ extra_rdoc_files:
|
|
28
28
|
files:
|
29
29
|
- lib/common/noyes_dsl.rb
|
30
30
|
- lib/common/noyes_math.rb
|
31
|
+
- lib/common/parallel_filter.rb
|
31
32
|
- lib/common/send_incrementally.rb
|
33
|
+
- lib/common/serial_filter.rb
|
32
34
|
- lib/noyes.rb
|
33
35
|
- lib/ruby_impl/dct.rb
|
34
36
|
- lib/ruby_impl/delta.rb
|