roctave 0.0.1
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.
- checksums.yaml +7 -0
- data/LICENSE +674 -0
- data/README.md +33 -0
- data/ext/roctave/cu8_file_reader.c +331 -0
- data/ext/roctave/cu8_file_reader.h +30 -0
- data/ext/roctave/extconf.rb +6 -0
- data/ext/roctave/fir_filter.c +795 -0
- data/ext/roctave/fir_filter.h +29 -0
- data/ext/roctave/freq_shifter.c +410 -0
- data/ext/roctave/freq_shifter.h +29 -0
- data/ext/roctave/iir_filter.c +462 -0
- data/ext/roctave/iir_filter.h +29 -0
- data/ext/roctave/roctave.c +38 -0
- data/ext/roctave/roctave.h +27 -0
- data/lib/roctave.rb +168 -0
- data/lib/roctave/bilinear.rb +92 -0
- data/lib/roctave/butter.rb +87 -0
- data/lib/roctave/cheby.rb +180 -0
- data/lib/roctave/cu8_file_reader.rb +45 -0
- data/lib/roctave/dft.rb +280 -0
- data/lib/roctave/filter.rb +64 -0
- data/lib/roctave/finite_difference_coefficients.rb +73 -0
- data/lib/roctave/fir.rb +121 -0
- data/lib/roctave/fir1.rb +134 -0
- data/lib/roctave/fir2.rb +246 -0
- data/lib/roctave/fir_design.rb +311 -0
- data/lib/roctave/firls.rb +380 -0
- data/lib/roctave/firpm.rb +499 -0
- data/lib/roctave/freq_shifter.rb +47 -0
- data/lib/roctave/freqz.rb +233 -0
- data/lib/roctave/iir.rb +80 -0
- data/lib/roctave/interp1.rb +78 -0
- data/lib/roctave/plot.rb +748 -0
- data/lib/roctave/poly.rb +46 -0
- data/lib/roctave/roots.rb +73 -0
- data/lib/roctave/sftrans.rb +157 -0
- data/lib/roctave/version.rb +3 -0
- data/lib/roctave/window.rb +116 -0
- data/roctave.gemspec +79 -0
- data/samples/butter.rb +12 -0
- data/samples/cheby.rb +28 -0
- data/samples/dft.rb +18 -0
- data/samples/differentiator.rb +48 -0
- data/samples/differentiator_frequency_scaling.rb +52 -0
- data/samples/fft.rb +40 -0
- data/samples/finite_difference_coefficient.rb +53 -0
- data/samples/fir1.rb +13 -0
- data/samples/fir2.rb +14 -0
- data/samples/fir2_windows.rb +29 -0
- data/samples/fir2bank.rb +30 -0
- data/samples/fir_low_pass.rb +44 -0
- data/samples/firls.rb +77 -0
- data/samples/firpm.rb +78 -0
- data/samples/hilbert_transformer.rb +20 -0
- data/samples/hilbert_transformer_frequency_scaling.rb +47 -0
- data/samples/plot.rb +45 -0
- data/samples/stem.rb +8 -0
- data/samples/type1.rb +25 -0
- data/samples/type3.rb +24 -0
- data/samples/windows.rb +25 -0
- metadata +123 -0
data/samples/butter.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/roctave.rb'
|
4
|
+
|
5
|
+
#b, a = Roctave.butter(12, [0.3, 0.7], :stop)
|
6
|
+
b, a = Roctave.butter(12, 0.75, :low)
|
7
|
+
pp b #.collect{|v| v.round(5)}
|
8
|
+
pp a #.collect{|v| v.round(5)}
|
9
|
+
|
10
|
+
Roctave.freqz(b, a, :magnitude, :phase, :group_delay)
|
11
|
+
Roctave.zplane(b, a)
|
12
|
+
|
data/samples/cheby.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/roctave.rb'
|
4
|
+
|
5
|
+
b, a = Roctave.cheby2(5, -0.1, (0.4 .. 0.6), :stop)
|
6
|
+
pp b
|
7
|
+
pp a
|
8
|
+
|
9
|
+
Roctave.freqz(b, a, :magnitude)
|
10
|
+
Roctave.zplane(b, a)
|
11
|
+
exit
|
12
|
+
b, a = Roctave.cheby1(12, -0.01, (0.4 .. 0.6), :stop)
|
13
|
+
pp b
|
14
|
+
pp a
|
15
|
+
|
16
|
+
Roctave.freqz(b, a, :magnitude)
|
17
|
+
Roctave.zplane(b, a)
|
18
|
+
|
19
|
+
plot_args = []
|
20
|
+
(1..10).each do |i|
|
21
|
+
b, a = Roctave.cheby1(i, -0.2, 0.5)
|
22
|
+
h, w = Roctave.freqz(b, a)
|
23
|
+
plot_args << w.collect{|v| v/Math::PI}
|
24
|
+
plot_args << h.abs
|
25
|
+
plot_args << ";n = #{i};"
|
26
|
+
end
|
27
|
+
|
28
|
+
Roctave.plot(*plot_args, grid: true)
|
data/samples/dft.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/roctave.rb'
|
4
|
+
|
5
|
+
fs = 600
|
6
|
+
fn = fs/2.0
|
7
|
+
t = Roctave.linspace(0, 1, fs)
|
8
|
+
s = t.collect{|t| 1*Math.cos(2*Math::PI*100*t + 0*Math::PI/3) + 0.8*Math.cos(2*Math::PI*150*t + 1*Math::PI/3) + 0.6*Math.cos(2*Math::PI*200*t + 2*Math::PI/3)}
|
9
|
+
#Roctave.plot(t, s, grid: true)
|
10
|
+
|
11
|
+
st = Time.now
|
12
|
+
dft = Roctave.fftshift(Roctave.dft(s, 2048, window: :nuttall, normalize: true).abs)
|
13
|
+
et = Time.now
|
14
|
+
puts "Took #{(et - st).round(3)} s to compute #{dft.length}-points DFT"
|
15
|
+
dft.collect!{|e| 20.0*Math.log10(e)}
|
16
|
+
f = Roctave.linspace(-fn, fn, dft.length)
|
17
|
+
#Roctave.plot(f, dft, grid: true, title: 'DFT', xlabel: 'frequency', ylabel: 'Amplitude')
|
18
|
+
Roctave.plot(f, dft, grid: true, title: 'DFT', xlabel: 'frequency', ylabel: 'dB', ylim: [-150, 0])
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/roctave.rb'
|
4
|
+
|
5
|
+
# H(e^(jw)) = j.w, for -pi <= w <= pi
|
6
|
+
# h(n) = 0 when n == 0, else (-1)^n / n
|
7
|
+
|
8
|
+
n = 14
|
9
|
+
|
10
|
+
|
11
|
+
b = Roctave.fir_differentiator(n, window: :blackman)
|
12
|
+
Roctave.freqz(b, :magnitude, :phase, :group_delay)
|
13
|
+
exit
|
14
|
+
|
15
|
+
Roctave.stem((-n/2..n/2).to_a, b, :filled, grid: true, title: "FIR type III order #{n}")
|
16
|
+
|
17
|
+
r1 = Roctave.dft(b, 2048)
|
18
|
+
h1 = r1[0...1024].abs
|
19
|
+
p1 = r1[0...1024].arg
|
20
|
+
p1 = Roctave.unwrap(p1)
|
21
|
+
w1 = Roctave.linspace(0, 1, 1024)
|
22
|
+
Roctave.plot([0, Math::PI], '--;Ideal;', w1, h1, ";FIR type III order #{n};", grid: true, title: 'Magnitude')
|
23
|
+
Roctave.plot(w1, p1, grid: true, title: 'Phase')
|
24
|
+
|
25
|
+
###
|
26
|
+
|
27
|
+
fc = 1.0/2
|
28
|
+
b = Roctave.fir_differentiator_low_pass(n, fc, window: :hamming)
|
29
|
+
|
30
|
+
Roctave.stem((-n/2..n/2).to_a, b, :filled, grid: true, title: "FIR type III order #{n} \\\"lowpass\\\"")
|
31
|
+
|
32
|
+
r2 = Roctave.dft(b, 2048)
|
33
|
+
h2 = r2[0...1024].abs
|
34
|
+
p2 = r2[0...1024].arg
|
35
|
+
p2 = Roctave.unwrap(p2)
|
36
|
+
w2 = Roctave.linspace(0, 1, 1024)
|
37
|
+
Roctave.plot([0, fc, 2*fc, 1], [0, Math::PI * fc, 0, 0], '--;Ideal;', w2, h2, ";FIR type III order #{n} \"lowpass\";", grid: true, title: 'Magnitude')
|
38
|
+
Roctave.plot(w2, p2, grid: true, title: 'Phase')
|
39
|
+
|
40
|
+
|
41
|
+
Roctave.plot(
|
42
|
+
[0, Math::PI], '--;Ideal 1;',
|
43
|
+
[0, fc, 2*fc, 1], [0, Math::PI * fc, 0, 0], '--;Ideal 2;',
|
44
|
+
w1, h1, ";1 FIR type III order #{n};",
|
45
|
+
w2, h2, ";2 FIR type III order #{n} \"lowpass\";",
|
46
|
+
grid: true, title: 'Magnitude'
|
47
|
+
)
|
48
|
+
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/roctave.rb'
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
if true then # Type III
|
8
|
+
n = 32
|
9
|
+
f = [0, 0.75, 1]
|
10
|
+
m = [Complex(0.0, 0.0), Complex(0.0, 0.75*Math::PI), Complex(0.0, 0.0)]
|
11
|
+
else # Type IV
|
12
|
+
n = 31
|
13
|
+
f = [0, 1]
|
14
|
+
m = [Complex(0.0, 0.0), Complex(0.0, Math::PI)]
|
15
|
+
end
|
16
|
+
b = Roctave.fir2(n, f, m, :odd_symetry, window: :blackman)
|
17
|
+
|
18
|
+
Roctave.stem(b, :filled, grid: true)
|
19
|
+
|
20
|
+
r = Roctave.dft(b, 2048)
|
21
|
+
r = Roctave.fftshift(r)
|
22
|
+
h = r.abs
|
23
|
+
p = r.arg
|
24
|
+
w = Roctave.linspace(-1, 1, 2048)
|
25
|
+
Roctave.plot([-1, 0, 1], [Math::PI, 0, Math::PI], '--;Ideal;', w, h, ';Actual;', grid: true, title: 'Magnitude')
|
26
|
+
Roctave.plot(w, p, grid: true, title: 'Phase')
|
27
|
+
|
28
|
+
=begin
|
29
|
+
n = [2, order.to_i].max
|
30
|
+
n += n & 1
|
31
|
+
grid = 1024
|
32
|
+
mgridl = Roctave.linspace(0, Math::PI, grid + 1).collect{|i| Complex(0.0, i)}
|
33
|
+
mgridr = mgridl[1...-1].reverse.conj
|
34
|
+
mgrid = mgridl + mgridr
|
35
|
+
b = Roctave.idft(mgrid)
|
36
|
+
mid = (n+1) / 2.0
|
37
|
+
b = (b[-(mid.floor) .. -1] + b[0 ... mid.ceil]).collect{|e| e.real}
|
38
|
+
window = Roctave.blackman(n+1)
|
39
|
+
b = b.collect.with_index{|e, i| e*window[i]}
|
40
|
+
|
41
|
+
indexes = (-n/2..n/2).to_a
|
42
|
+
Roctave.stem(indexes, b, :filled, grid: true, title: "FIR type III order #{n}")
|
43
|
+
|
44
|
+
r = Roctave.dft(b, 2048)
|
45
|
+
h = r[0...1024].abs
|
46
|
+
p = r[0...1024].arg
|
47
|
+
w = Roctave.linspace(0, 1, 1024)
|
48
|
+
Roctave.plot([0, Math::PI], '--;Ideal;', w, h, ";FIR type III order #{n};", grid: true, title: 'Magnitude')
|
49
|
+
Roctave.plot(w, p, grid: true, title: 'Phase')
|
50
|
+
=end
|
51
|
+
|
52
|
+
|
data/samples/fft.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/roctave.rb'
|
4
|
+
|
5
|
+
fs = 8192
|
6
|
+
fn = fs/2.0
|
7
|
+
t = Roctave.linspace(0, 1, fs)
|
8
|
+
s = t.collect{|t| 1*Math.cos(2*Math::PI*100*t + 0*Math::PI/3) + 0.8*Math.cos(2*Math::PI*150*t + 1*Math::PI/3) + 0.6*Math.cos(2*Math::PI*200*t + 2*Math::PI/3)}
|
9
|
+
|
10
|
+
n = 4096
|
11
|
+
|
12
|
+
st = Time.now
|
13
|
+
fft = Roctave.fftshift(Roctave.fft(s, n, window: :nuttall, normalize: true).abs)
|
14
|
+
et = Time.now
|
15
|
+
puts "Took #{(et - st).round(3)} s to compute #{fft.length}-points FFT"
|
16
|
+
ffttime = et - st
|
17
|
+
|
18
|
+
|
19
|
+
st = Time.now
|
20
|
+
dft = Roctave.fftshift(Roctave.dft(s, n, window: :nuttall, normalize: true).abs)
|
21
|
+
et = Time.now
|
22
|
+
puts "Took #{(et - st).round(3)} s to compute #{dft.length}-points DFT"
|
23
|
+
dfttime = et - st
|
24
|
+
puts "FFT acceleration factor: #{(dfttime / ffttime).round(3)}"
|
25
|
+
|
26
|
+
fft.collect!{|e| 20.0*Math.log10(e)}
|
27
|
+
dft.collect!{|e| 20.0*Math.log10(e)}
|
28
|
+
|
29
|
+
dftf = Roctave.linspace(-fn, fn, dft.length)
|
30
|
+
fftf = Roctave.linspace(-fn, fn, fft.length)
|
31
|
+
|
32
|
+
#Roctave.plot(f, dft, grid: true, title: 'DFT', xlabel: 'frequency', ylabel: 'Amplitude')
|
33
|
+
Roctave.plot(fftf, fft, ";FFT;", dftf, dft, "--;DFT;", grid: true, title: 'DFT', xlabel: 'frequency', ylabel: 'dB', ylim: [-150, 0])
|
34
|
+
|
35
|
+
st = Time.now
|
36
|
+
si = Roctave.idft(Roctave.dft(s));
|
37
|
+
et = Time.now
|
38
|
+
puts "Took #{(et - st).round(3)} s to compute forward and inverse #{si.length}-points DFT"
|
39
|
+
Roctave.plot(t, s, ';original;', Roctave.linspace(0, 1, si.length), si, '--;reconstructed;')
|
40
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/roctave.rb'
|
4
|
+
|
5
|
+
|
6
|
+
n = 8
|
7
|
+
|
8
|
+
###
|
9
|
+
|
10
|
+
b1 = Roctave.fir_differentiator(n, window: :blackman)
|
11
|
+
|
12
|
+
Roctave.stem((-n/2..n/2).to_a, b1, :filled, grid: true, title: "Differentiator")
|
13
|
+
|
14
|
+
r1 = Roctave.dft(b1, 2048)
|
15
|
+
h1 = r1[0...1024].abs
|
16
|
+
p1 = r1[0...1024].arg
|
17
|
+
p1 = Roctave.unwrap(p1)
|
18
|
+
w1 = Roctave.linspace(0, 1, 1024)
|
19
|
+
Roctave.plot([0, Math::PI], '--;Ideal;', w1, h1, ";Filter;", grid: true, title: 'Differentiator magnitude')
|
20
|
+
Roctave.plot(w1, p1, grid: true, title: 'Differentiator phase')
|
21
|
+
|
22
|
+
###
|
23
|
+
|
24
|
+
b2 = Roctave.finite_difference_coefficients((-n/2 .. n/2), 1)
|
25
|
+
|
26
|
+
Roctave.stem((-n/2..n/2).to_a, b2, :filled, grid: true, title: "Finite difference")
|
27
|
+
|
28
|
+
r2 = Roctave.dft(b2, 2048)
|
29
|
+
h2 = r2[0...1024].abs
|
30
|
+
p2 = r2[0...1024].arg
|
31
|
+
p2 = Roctave.unwrap(p2)
|
32
|
+
w2 = Roctave.linspace(0, 1, 1024)
|
33
|
+
Roctave.plot([0, Math::PI], '--;Ideal;', w2, h2, ";Filter;", grid: true, title: 'Finite difference magnitude')
|
34
|
+
Roctave.plot(w2, p2, grid: true, title: 'Finite difference phase')
|
35
|
+
|
36
|
+
###
|
37
|
+
|
38
|
+
n = 16
|
39
|
+
d = 3
|
40
|
+
b2 = Roctave.finite_difference_coefficients((-n/2 .. n/2), d)
|
41
|
+
pp b2.reverse
|
42
|
+
|
43
|
+
Roctave.stem((-n/2..n/2).to_a, b2, :filled, grid: true, title: "Finite difference length #{n+1} derivative order #{d}")
|
44
|
+
|
45
|
+
r2 = Roctave.dft(b2, 2048)
|
46
|
+
h2 = r2[0...1024].abs
|
47
|
+
p2 = r2[0...1024].arg
|
48
|
+
p2 = Roctave.unwrap(p2)
|
49
|
+
w2 = Roctave.linspace(0, 1, 1024)
|
50
|
+
Roctave.plot(w2, w2.collect{|e| (Math::PI*e)**d}, '--;Ideal;', w2, h2, ";Filter;", grid: true, title: 'Finite difference magnitude length #{n+1} derivative order #{d}')
|
51
|
+
Roctave.plot(w2, p2, grid: true, title: 'Finite difference phase length #{n+1} derivative order #{d}')
|
52
|
+
|
53
|
+
|
data/samples/fir1.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/roctave.rb'
|
4
|
+
|
5
|
+
n = 128
|
6
|
+
fc = 0.5
|
7
|
+
|
8
|
+
b1 = Roctave.fir1(n, [0.4, 0.6, 0.8], :high)
|
9
|
+
|
10
|
+
h1 = Roctave.dft(b1, 2048).abs[0...1024]
|
11
|
+
w = Roctave.linspace(0.0, 1.0, 1024)
|
12
|
+
Roctave.plot(w, h1, [0.5], [fc], '*', grid: true, ylim: [0, 1.4])
|
13
|
+
|
data/samples/fir2.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/roctave.rb'
|
4
|
+
|
5
|
+
f = [0.0, 0.3, 0.3, 0.6, 0.6, 1.0]
|
6
|
+
m = [0, 0, 1, 0.5, 0, 0]
|
7
|
+
b = Roctave.fir2(60, f, m)
|
8
|
+
|
9
|
+
h = Roctave.dft(b, 2048).abs[0...1024]
|
10
|
+
p = Roctave.dft(b, 2048).arg[0...1024]
|
11
|
+
w = Roctave.linspace(0.0, 1.0, 1024)
|
12
|
+
Roctave.plot(f, m, ';Ideal;', w, h, '-;fir2;', title: 'Magnitude')
|
13
|
+
#Roctave.plot(w, p, title: 'Phase')
|
14
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/roctave.rb'
|
4
|
+
|
5
|
+
f = [
|
6
|
+
0.00000, 0.01000, 0.02000, 0.03000, 0.04000, 0.05000, 0.06000, 0.07000, 0.08000, 0.09000, 0.10000, 0.11000, 0.12000,
|
7
|
+
0.13000, 0.14000, 0.15000, 0.16000, 0.17000, 0.18000, 0.20000, 0.38000, 0.40000, 0.55000, 0.56200, 0.58500, 0.60000,
|
8
|
+
0.78000, 0.79000, 0.80000, 0.81000, 0.82000, 0.83000, 0.84000, 0.85000, 0.86000, 0.87000, 0.88000, 0.89000, 0.90000,
|
9
|
+
0.91000, 0.92000, 0.93000, 0.94000, 0.95000, 0.96000, 0.97000, 0.98000, 0.99000, 1.00000
|
10
|
+
]
|
11
|
+
m = [
|
12
|
+
0.50000, 0.61350, 0.70225, 0.74692, 0.73776, 0.67678, 0.57725, 0.46089, 0.35305, 0.27725, 0.25000, 0.27725, 0.35305,
|
13
|
+
0.46089, 0.57725, 0.67678, 0.73776, 0.74692, 0.70225, 0.50000, 2.30000, 1.00000, 1.00000, 0.20000, 0.20000, 1.00000,
|
14
|
+
1.00000, 0.99380, 0.92000, 0.84980, 0.78320, 0.72020, 0.66080, 0.60500, 0.55280, 0.50420, 0.45920, 0.41780, 0.38000,
|
15
|
+
0.34580, 0.31520, 0.28820, 0.26480, 0.24500, 0.22880, 0.21620, 0.20720, 0.20180, 0.20000
|
16
|
+
]
|
17
|
+
|
18
|
+
n = 128
|
19
|
+
hamming = Roctave.dft(Roctave.fir2(n, f, m, window: :hamming), 2048).abs[0...1024]
|
20
|
+
hann = Roctave.dft(Roctave.fir2(n, f, m, window: :hann), 2048).abs[0...1024]
|
21
|
+
blackman = Roctave.dft(Roctave.fir2(n, f, m, window: :blackman), 2048).abs[0...1024]
|
22
|
+
nuttall = Roctave.dft(Roctave.fir2(n, f, m, window: :nuttall), 2048).abs[0...1024]
|
23
|
+
blackman_nuttall = Roctave.dft(Roctave.fir2(n, f, m, window: :blackman_nuttall), 2048).abs[0...1024]
|
24
|
+
blackman_harris = Roctave.dft(Roctave.fir2(n, f, m, window: :blackman_harris), 2048).abs[0...1024]
|
25
|
+
gaussian = Roctave.dft(Roctave.fir2(n, f, m, window: :gaussian), 2048).abs[0...1024]
|
26
|
+
|
27
|
+
w = Roctave.linspace(0.0, 1.0, 1024)
|
28
|
+
Roctave.plot(f, m, ';Ideal;', w, hamming, ';hamming;', w, hann, ';hann;', w, blackman, ';blackman;', w, nuttall, ';nuttall;', w, blackman_nuttall, ';blackman nuttall;', w, blackman_harris, ';blackman harris;', w, gaussian, ';gaussian;', title: 'Magnitude')
|
29
|
+
|
data/samples/fir2bank.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/roctave.rb'
|
4
|
+
|
5
|
+
n = 64
|
6
|
+
f1 = [0.0, 0.2, 0.2, 1.0]
|
7
|
+
m1 = [1.0, 1.0, 0.0, 0.0]
|
8
|
+
f2 = [0.0, 0.2, 0.2, 0.4, 0.4, 1.0]
|
9
|
+
m2 = [0.0, 0.0, 1.0, 1.0, 0.0, 0.0]
|
10
|
+
f3 = [0.0, 0.4, 0.4, 0.6, 0.6, 1.0]
|
11
|
+
m3 = [0.0, 0.0, 1.0, 1.0, 0.0, 0.0]
|
12
|
+
f4 = [0.0, 0.6, 0.6, 0.8, 0.8, 1.0]
|
13
|
+
m4 = [0.0, 0.0, 1.0, 1.0, 0.0, 0.0]
|
14
|
+
f5 = [0.0, 0.8, 0.8, 1.0]
|
15
|
+
m5 = [0.0, 0.0, 1.0, 1.0]
|
16
|
+
b1 = Roctave.fir2(n, f1, m1)
|
17
|
+
b2 = Roctave.fir2(n, f2, m2)
|
18
|
+
b3 = Roctave.fir2(n, f3, m3)
|
19
|
+
b4 = Roctave.fir2(n, f4, m4)
|
20
|
+
b5 = Roctave.fir2(n, f5, m5)
|
21
|
+
|
22
|
+
w = Roctave.linspace(0.0, 1.0, 1024)
|
23
|
+
h1 = Roctave.dft(b1, 2048).abs[0...1024]
|
24
|
+
h2 = Roctave.dft(b2, 2048).abs[0...1024]
|
25
|
+
h3 = Roctave.dft(b3, 2048).abs[0...1024]
|
26
|
+
h4 = Roctave.dft(b4, 2048).abs[0...1024]
|
27
|
+
h5 = Roctave.dft(b5, 2048).abs[0...1024]
|
28
|
+
h = (0...1024).collect{|i| h1[i] + h2[i] + h3[i] + h4[i] + h5[i]}
|
29
|
+
Roctave.plot(w, h1, w, h2, w, h3, w, h4, w, h5, w, h, grid: true)
|
30
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/roctave.rb'
|
4
|
+
|
5
|
+
n = 64
|
6
|
+
fc = 0.25
|
7
|
+
width = 0.1
|
8
|
+
|
9
|
+
b = Roctave.fir_low_pass(n, fc - width/2)
|
10
|
+
Roctave.stem(b, grid: true)
|
11
|
+
w = Roctave.linspace(0.0, 1.0, 1024)
|
12
|
+
h = Roctave.dft(b, 2048).abs[0...1024]
|
13
|
+
Roctave.plot(w, h, title: 'Low-pass', xlim: [-0.1, 1.1], ylim: [-0.1, 1.1], grid: true)
|
14
|
+
|
15
|
+
b = Roctave.fir_high_pass(n, fc + width/2)
|
16
|
+
Roctave.stem(b)
|
17
|
+
w = Roctave.linspace(0.0, 1.0, 1024)
|
18
|
+
h = Roctave.dft(b, 2048).abs[0...1024]
|
19
|
+
Roctave.plot(w, h, title: 'High-pass', xlim: [-0.1, 1.1], ylim: [-0.1, 1.1], grid: true)
|
20
|
+
|
21
|
+
b = Roctave.fir_band_stop(n, fc, width, window: :hamming)
|
22
|
+
Roctave.stem(b, :filled, grid: true)
|
23
|
+
w = Roctave.linspace(0.0, 1.0, 1024)
|
24
|
+
h = Roctave.dft(b, 2048).abs[0...1024]
|
25
|
+
Roctave.plot(w, h, [fc - width / 2.0, fc + width / 2.0], [0.5, 0.5], title: 'Band-stop', xlim: [-0.1, 1.1], ylim: [-0.1, 1.1], grid: true)
|
26
|
+
|
27
|
+
b = Roctave.fir_band_pass(n & ~1, fc, width, window: :hamming)
|
28
|
+
Roctave.stem(b, :filled, grid: true, title: "Band-pass even #{b.length - 1}")
|
29
|
+
w = Roctave.linspace(0.0, 1.0, 1024)
|
30
|
+
h = Roctave.dft(b, 2048).abs[0...1024]
|
31
|
+
Roctave.plot(w, h, [fc - width / 2.0, fc + width / 2.0], [0.5, 0.5], title: "Band-pass even #{b.length - 1}", xlim: [-0.1, 1.1], ylim: [-0.1, 1.1], grid: true)
|
32
|
+
|
33
|
+
b = Roctave.fir_band_pass((n & ~1) | 1, fc, width, window: :hamming)
|
34
|
+
Roctave.stem(b, :filled, grid: true, title: "Band-pass odd #{b.length - 1}")
|
35
|
+
w = Roctave.linspace(0.0, 1.0, 1024)
|
36
|
+
h = Roctave.dft(b, 2048).abs[0...1024]
|
37
|
+
Roctave.plot(w, h, [fc - width / 2.0, fc + width / 2.0], [0.5, 0.5], title: "Band-pass odd #{b.length - 1}", xlim: [-0.1, 1.1], ylim: [-0.1, 1.1], grid: true)
|
38
|
+
|
39
|
+
b = Roctave.fir2(n, [0, fc-width/2, fc-width/2, fc+width/2, fc+width/2, 1], [0, 0, 1, 1, 0, 0])
|
40
|
+
Roctave.stem(b, :filled, grid: true, title: "Band-pass fir2 #{b.length - 1}")
|
41
|
+
w = Roctave.linspace(0.0, 1.0, 1024)
|
42
|
+
h = Roctave.dft(b, 2048).abs[0...1024]
|
43
|
+
Roctave.plot(w, h, [fc - width / 2.0, fc + width / 2.0], [0.5, 0.5], title: "Band-pass fir2 #{b.length - 1}", xlim: [-0.1, 1.1], ylim: [-0.1, 1.1], grid: true)
|
44
|
+
|
data/samples/firls.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/roctave.rb'
|
4
|
+
|
5
|
+
## Low pass type I
|
6
|
+
n = 128
|
7
|
+
delta = 0.05
|
8
|
+
f = [(0 .. 0.4-2*delta), (0.4+0*delta .. 1)]
|
9
|
+
a = [1, 0]
|
10
|
+
w = [1, 1]
|
11
|
+
b = Roctave.firls(n, f, a, w, :even_symmetry)
|
12
|
+
|
13
|
+
Roctave.freqz(b, :magnitude)
|
14
|
+
Roctave.stem(b)
|
15
|
+
|
16
|
+
exit
|
17
|
+
|
18
|
+
# ## Low pass type II
|
19
|
+
# n = 11
|
20
|
+
# f = [(0 .. 0.3), (0.7 .. 1)]
|
21
|
+
# a = [1, 0]
|
22
|
+
# w = [2, 1]
|
23
|
+
# b = Roctave.firls(n, f, a, w, :even_symmetry)
|
24
|
+
|
25
|
+
# ## Differentiator type III
|
26
|
+
# n = 10
|
27
|
+
# f = [0.05, 0.75]
|
28
|
+
# a = [f]
|
29
|
+
# w = [Roctave.linspace(f.first, f.last, 16).collect{|v| 1/v}]
|
30
|
+
# b = Roctave.firls(n, f, a, w, 16, :odd_symmetry)
|
31
|
+
|
32
|
+
# ## Hilbert transformer type IV
|
33
|
+
# n = 11
|
34
|
+
# f = [1.0/8, 7.0/8]
|
35
|
+
# a = [1]
|
36
|
+
# w = [1]
|
37
|
+
# b = Roctave.firls(n, f, a, w, :odd_symmetry)
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
# r = Roctave.dft(b, 2048)
|
42
|
+
# h = r[0..1024].abs
|
43
|
+
# p = r[0..1024].arg
|
44
|
+
# p = Roctave.unwrap(p)
|
45
|
+
# w = Roctave.linspace(0, 1, 1025)
|
46
|
+
#
|
47
|
+
# if (n & 1) == 0 then
|
48
|
+
# Roctave.stem((-n/2..n/2).to_a, b, :filled, grid: true)
|
49
|
+
# else
|
50
|
+
# Roctave.stem((n+1).times.collect{|i| i - (n+1)/2.0 + 0.5}, b, :filled, grid: true)
|
51
|
+
# end
|
52
|
+
# Roctave.plot(w, p, grid: true, title: 'Phase')
|
53
|
+
# Roctave.plot(w, h.collect{|v| 10*Math.log10(v)}, xlabel: 'Normalized frequency', ylabel: 'Magnitude response (dB)', grid: true, title: 'Magnitude')
|
54
|
+
# Roctave.plot([0, 0.3], [1, 1], '-b', [0.7, 1], [0, 0], '-b', w, h, title: 'Magnitude response', xlim: (0 .. 1), grid: true)
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
|
60
|
+
exit
|
61
|
+
n = 4
|
62
|
+
f = [(0 .. 0.4), (0.6 .. 1)]
|
63
|
+
a = [1, 0]
|
64
|
+
b = Roctave.firls(n, f, a, 1)
|
65
|
+
exit
|
66
|
+
|
67
|
+
n = 32
|
68
|
+
grid = 8
|
69
|
+
f = [[0.2, 0.3], [0.4, 0.6], [0.7, 0.8]]
|
70
|
+
a = [
|
71
|
+
0.5,
|
72
|
+
Roctave.linspace(0, Math::PI, 64).collect{|t| 1 - Math.sin(t)},
|
73
|
+
(0.5 .. 0)
|
74
|
+
]
|
75
|
+
|
76
|
+
b = Roctave.firls(n, f, a, grid)
|
77
|
+
|