roctave 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +674 -0
  3. data/README.md +33 -0
  4. data/ext/roctave/cu8_file_reader.c +331 -0
  5. data/ext/roctave/cu8_file_reader.h +30 -0
  6. data/ext/roctave/extconf.rb +6 -0
  7. data/ext/roctave/fir_filter.c +795 -0
  8. data/ext/roctave/fir_filter.h +29 -0
  9. data/ext/roctave/freq_shifter.c +410 -0
  10. data/ext/roctave/freq_shifter.h +29 -0
  11. data/ext/roctave/iir_filter.c +462 -0
  12. data/ext/roctave/iir_filter.h +29 -0
  13. data/ext/roctave/roctave.c +38 -0
  14. data/ext/roctave/roctave.h +27 -0
  15. data/lib/roctave.rb +168 -0
  16. data/lib/roctave/bilinear.rb +92 -0
  17. data/lib/roctave/butter.rb +87 -0
  18. data/lib/roctave/cheby.rb +180 -0
  19. data/lib/roctave/cu8_file_reader.rb +45 -0
  20. data/lib/roctave/dft.rb +280 -0
  21. data/lib/roctave/filter.rb +64 -0
  22. data/lib/roctave/finite_difference_coefficients.rb +73 -0
  23. data/lib/roctave/fir.rb +121 -0
  24. data/lib/roctave/fir1.rb +134 -0
  25. data/lib/roctave/fir2.rb +246 -0
  26. data/lib/roctave/fir_design.rb +311 -0
  27. data/lib/roctave/firls.rb +380 -0
  28. data/lib/roctave/firpm.rb +499 -0
  29. data/lib/roctave/freq_shifter.rb +47 -0
  30. data/lib/roctave/freqz.rb +233 -0
  31. data/lib/roctave/iir.rb +80 -0
  32. data/lib/roctave/interp1.rb +78 -0
  33. data/lib/roctave/plot.rb +748 -0
  34. data/lib/roctave/poly.rb +46 -0
  35. data/lib/roctave/roots.rb +73 -0
  36. data/lib/roctave/sftrans.rb +157 -0
  37. data/lib/roctave/version.rb +3 -0
  38. data/lib/roctave/window.rb +116 -0
  39. data/roctave.gemspec +79 -0
  40. data/samples/butter.rb +12 -0
  41. data/samples/cheby.rb +28 -0
  42. data/samples/dft.rb +18 -0
  43. data/samples/differentiator.rb +48 -0
  44. data/samples/differentiator_frequency_scaling.rb +52 -0
  45. data/samples/fft.rb +40 -0
  46. data/samples/finite_difference_coefficient.rb +53 -0
  47. data/samples/fir1.rb +13 -0
  48. data/samples/fir2.rb +14 -0
  49. data/samples/fir2_windows.rb +29 -0
  50. data/samples/fir2bank.rb +30 -0
  51. data/samples/fir_low_pass.rb +44 -0
  52. data/samples/firls.rb +77 -0
  53. data/samples/firpm.rb +78 -0
  54. data/samples/hilbert_transformer.rb +20 -0
  55. data/samples/hilbert_transformer_frequency_scaling.rb +47 -0
  56. data/samples/plot.rb +45 -0
  57. data/samples/stem.rb +8 -0
  58. data/samples/type1.rb +25 -0
  59. data/samples/type3.rb +24 -0
  60. data/samples/windows.rb +25 -0
  61. metadata +123 -0
@@ -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
+
@@ -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)
@@ -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
+
@@ -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
+
@@ -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
+
@@ -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
+
@@ -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
+
@@ -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
+