audio_stream 3.3.0 → 3.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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/examples/bench_fx.rb +89 -0
  4. data/examples/canon.wav +0 -0
  5. data/examples/example_options.rb +2 -0
  6. data/examples/{chorus.rb → fx_chorus.rb} +2 -7
  7. data/examples/fx_compressor.rb +34 -0
  8. data/examples/fx_convolution_reverb.rb +37 -0
  9. data/examples/fx_delay.rb +33 -0
  10. data/examples/{distortion.rb → fx_distortion.rb} +4 -8
  11. data/examples/fx_noise_gate.rb +33 -0
  12. data/examples/fx_phaser.rb +36 -0
  13. data/examples/fx_schroeder_reverb.rb +34 -0
  14. data/examples/fx_vocoder.rb +44 -0
  15. data/examples/impulse_shaker.wav +0 -0
  16. data/examples/impulse_shaker_bigroom.wav +0 -0
  17. data/examples/impulse_shaker_smallhall.wav +0 -0
  18. data/examples/tuner.rb +4 -3
  19. data/jupyter/band_pass_filter.ipynb +117 -0
  20. data/jupyter/biquad.ipynb +372 -0
  21. data/jupyter/equalizer.ipynb +198 -0
  22. data/lib/audio_stream/audio_input_device.rb +20 -3
  23. data/lib/audio_stream/audio_observable.rb +5 -0
  24. data/lib/audio_stream/audio_output_device.rb +20 -3
  25. data/lib/audio_stream/buffer.rb +22 -0
  26. data/lib/audio_stream/decibel.rb +8 -8
  27. data/lib/audio_stream/fx/a_gain.rb +2 -6
  28. data/lib/audio_stream/fx/all_pass_filter.rb +4 -2
  29. data/lib/audio_stream/fx/band_pass_filter.rb +4 -2
  30. data/lib/audio_stream/fx/biquad_filter.rb +8 -3
  31. data/lib/audio_stream/fx/chorus.rb +6 -5
  32. data/lib/audio_stream/fx/comb_filter.rb +4 -2
  33. data/lib/audio_stream/fx/convolution_reverb.rb +8 -5
  34. data/lib/audio_stream/fx/delay.rb +6 -5
  35. data/lib/audio_stream/fx/distortion.rb +4 -4
  36. data/lib/audio_stream/fx/equalizer_2band.rb +5 -3
  37. data/lib/audio_stream/fx/equalizer_3band.rb +7 -0
  38. data/lib/audio_stream/fx/graphic_equalizer.rb +4 -0
  39. data/lib/audio_stream/fx/hanning_window.rb +0 -9
  40. data/lib/audio_stream/fx/high_pass_filter.rb +4 -2
  41. data/lib/audio_stream/fx/high_shelf_filter.rb +6 -7
  42. data/lib/audio_stream/fx/low_pass_filter.rb +4 -2
  43. data/lib/audio_stream/fx/low_shelf_filter.rb +6 -7
  44. data/lib/audio_stream/fx/noise_gate.rb +5 -4
  45. data/lib/audio_stream/fx/panning.rb +2 -1
  46. data/lib/audio_stream/fx/peaking_filter.rb +6 -7
  47. data/lib/audio_stream/fx/phaser.rb +7 -6
  48. data/lib/audio_stream/fx/schroeder_reverb.rb +12 -13
  49. data/lib/audio_stream/fx/tremolo.rb +7 -5
  50. data/lib/audio_stream/rate.rb +89 -38
  51. data/lib/audio_stream/version.rb +1 -1
  52. metadata +23 -10
  53. data/examples/biquad.ipynb +0 -428
  54. data/examples/equalizer.ipynb +0 -233
@@ -2,21 +2,24 @@ module AudioStream
2
2
  module Fx
3
3
  class SchroederReverb
4
4
 
5
- def initialize(soundinfo, time:, dry: 1.0, wet: 0.7)
5
+ # @param soundinfo [AudioStream::SoundInfo]
6
+ # @param dry [AudioStream::Decibel | Float] dry gain
7
+ # @param wet [AudioStream::Decibel | Float] wet gain
8
+ def initialize(soundinfo, dry: -1.0, wet: -20.0)
6
9
  @window_size = soundinfo.window_size
7
10
  @combs = [
8
- CombFilter.new(soundinfo, freq: ms2freq(39.85 / 2.0 * time), q: 0.871402),
9
- CombFilter.new(soundinfo, freq: ms2freq(36.10 / 2.0 * time), q: 0.882762),
10
- CombFilter.new(soundinfo, freq: ms2freq(33.27 / 2.0 * time), q: 0.891443),
11
- CombFilter.new(soundinfo, freq: ms2freq(30.15 / 2.0 * time), q: 0.901117),
11
+ CombFilter.new(soundinfo, freq: Rate.msec(39.85), q: 0.871402),
12
+ CombFilter.new(soundinfo, freq: Rate.msec(36.10), q: 0.882762),
13
+ CombFilter.new(soundinfo, freq: Rate.msec(33.27), q: 0.891443),
14
+ CombFilter.new(soundinfo, freq: Rate.msec(30.15), q: 0.901117),
12
15
  ]
13
16
  @allpasss = [
14
- AllPassFilter.create(soundinfo, freq: ms2freq(5.0), q: 0.7),
15
- AllPassFilter.create(soundinfo, freq: ms2freq(1.7), q: 0.7),
17
+ AllPassFilter.create(soundinfo, freq: Rate.msec(5.0).freq(soundinfo), q: BiquadFilter::DEFAULT_Q),
18
+ AllPassFilter.create(soundinfo, freq: Rate.msec(1.7).freq(soundinfo), q: BiquadFilter::DEFAULT_Q),
16
19
  ]
17
20
 
18
- @dry = dry.to_f
19
- @wet = wet.to_f
21
+ @dry = Decibel.db(dry).mag
22
+ @wet = Decibel.db(wet).mag
20
23
  end
21
24
 
22
25
  def process(input)
@@ -43,10 +46,6 @@ module AudioStream
43
46
 
44
47
  Buffer.new(*streams)
45
48
  end
46
-
47
- def ms2freq(ms)
48
- 1.0 / (ms / 1000.0)
49
- end
50
49
  end
51
50
  end
52
51
  end
@@ -1,23 +1,25 @@
1
1
  module AudioStream
2
2
  module Fx
3
3
  class Tremolo
4
+ # @param soundinfo [AudioStream::SoundInfo]
5
+ # @param freq [AudioStream::Rate | Float] Tremolo speed (0.0~)
6
+ # @param depth [Float] Tremolo depth (0.0~)
4
7
  def initialize(soundinfo, freq:, depth:)
5
- @samplerate = soundinfo.samplerate
6
- @freq = freq.to_f
8
+ @freq = Rate.freq(freq)
7
9
  @depth = depth.to_f
8
10
  @phase = 0
11
+ @period = @freq.sample_phase(soundinfo)
9
12
  end
10
13
 
11
14
  def process(input)
12
15
  window_size = input.window_size
13
- period = 2 * Math::PI * @freq / @samplerate
14
16
 
15
17
  streams = input.streams.map {|stream|
16
18
  stream.map.with_index {|f, i|
17
- f * (1.0 + @depth * Math.sin((i + @phase) * period))
19
+ f * (1.0 + @depth * Math.sin((i + @phase) * @period))
18
20
  }
19
21
  }
20
- @phase = (@phase + window_size) % (window_size / period)
22
+ @phase = (@phase + window_size) % (window_size / @period)
21
23
 
22
24
  Buffer.new(*streams)
23
25
  end
@@ -8,6 +8,7 @@ module AudioStream
8
8
  end
9
9
 
10
10
  def sec(soundinfo)
11
+ return @sec if @sec
11
12
  sample(soundinfo).to_f / soundinfo.samplerate
12
13
  end
13
14
 
@@ -33,6 +34,11 @@ module AudioStream
33
34
  end
34
35
  end
35
36
 
37
+ def freq(soundinfo)
38
+ return @freq if @freq
39
+ soundinfo.samplerate.to_f / sample(soundinfo)
40
+ end
41
+
36
42
  def frame_phase(soundinfo)
37
43
  sample_phase(soundinfo) * soundinfo.window_size
38
44
  end
@@ -41,58 +47,103 @@ module AudioStream
41
47
  2.0 * Math::PI / sample(soundinfo)
42
48
  end
43
49
 
50
+ def add(other, soundinfo)
51
+ other = self.class.sec(other)
52
+ self.class.new(sec: self.sec(soundinfo) + other.sec(soundinfo))
53
+ end
54
+
55
+ def *(other)
56
+ other = other.to_f
57
+
58
+ if @sample
59
+ return self.class.new(sample: @sample * other)
60
+ end
61
+
62
+ if @sec
63
+ return self.class.new(sec: @sec * other)
64
+ end
65
+
66
+ if @freq
67
+ return self.class.new(freq: @freq / other)
68
+ end
69
+
70
+ if @sync
71
+ return self.class.new(sync: @sync * other)
72
+ end
73
+ end
74
+
44
75
  def self.sec(v)
45
- new(sec: v)
76
+ if self===v
77
+ v
78
+ else
79
+ new(sec: v)
80
+ end
46
81
  end
47
82
 
48
- def self.millisec(v)
49
- new(sec: v*0.001)
83
+ def self.msec(v)
84
+ if self===v
85
+ v
86
+ else
87
+ new(sec: v*0.001)
88
+ end
50
89
  end
51
90
 
52
91
  def self.sample(v)
53
- new(sample: v)
92
+ if self===v
93
+ v
94
+ else
95
+ new(sample: v)
96
+ end
54
97
  end
55
98
 
56
99
  def self.freq(v)
57
- new(freq: v)
100
+ if self===v
101
+ v
102
+ else
103
+ new(freq: v)
104
+ end
58
105
  end
59
106
 
60
107
  def self.sync(v)
61
- new(sync: v)
108
+ if self===v
109
+ v
110
+ else
111
+ new(sync: v)
112
+ end
62
113
  end
63
114
 
64
115
 
65
- SYNC_64 = sync(480 * 64)
66
- SYNC_32 = sync(480 * 32)
67
- SYNC_16 = sync(480 * 16)
68
- SYNC_8 = sync(480 * 8)
69
- SYNC_6 = sync(480 * 6)
70
- SYNC_4 = sync(480 * 4)
71
- SYNC_3 = sync(480 * 3)
72
- SYNC_2 = sync(480 * 2)
73
- SYNC_7_4 = sync(480 * 7 / 4)
74
- SYNC_6_4 = sync(480 * 6 / 4)
75
- SYNC_5_4 = sync(480 * 5 / 4)
76
- SYNC_1 = sync(480 * 1)
77
- SYNC_3_4 = sync(480 * 3 / 4)
78
- SYNC_1_2 = sync(480 * 1 / 2)
79
- SYNC_1_4D = sync(480 * 1 / 4 * 3 / 2)
80
- SYNC_1_4 = sync(480 * 1 / 4)
81
- SYNC_1_4T = sync(480 * 1 / 4 * 2 / 3)
82
- SYNC_1_8D = sync(480 * 1 / 8 * 3 / 2)
83
- SYNC_1_8 = sync(480 * 1 / 8)
84
- SYNC_1_8T = sync(480 * 1 / 8 * 2 / 3)
85
- SYNC_1_16D = sync(480 * 1 / 16 * 3 / 2)
86
- SYNC_1_16 = sync(480 * 1 / 16)
87
- SYNC_1_16T = sync(480 * 1 / 16 * 2 / 3)
88
- SYNC_1_32D = sync(480 * 1 / 32 * 3 / 2)
89
- SYNC_1_32 = sync(480 * 1 / 32)
90
- SYNC_1_32T = sync(480 * 1 / 32 * 2 / 3)
91
- SYNC_1_64D = sync(480 * 1 / 64 * 3 / 2)
92
- SYNC_1_64 = sync(480 * 1 / 64)
93
- SYNC_1_64T = sync(480 * 1 / 64 * 2 / 3)
94
- SYNC_1_128D = sync(480 * 1 / 128 * 3 / 2)
95
- SYNC_1_128 = sync(480 * 1 / 128)
96
- SYNC_1_128T = sync(480 * 1 / 128 * 2 / 3)
116
+ SYNC_64 = sync(480 * 4 * 64)
117
+ SYNC_32 = sync(480 * 4 * 32)
118
+ SYNC_16 = sync(480 * 4 * 16)
119
+ SYNC_8 = sync(480 * 4 * 8)
120
+ SYNC_6 = sync(480 * 4 * 6)
121
+ SYNC_4 = sync(480 * 4 * 4)
122
+ SYNC_3 = sync(480 * 4 * 3)
123
+ SYNC_2 = sync(480 * 4 * 2)
124
+ SYNC_7_4 = sync(480 * 4 * 7 / 4)
125
+ SYNC_6_4 = sync(480 * 4 * 6 / 4)
126
+ SYNC_5_4 = sync(480 * 4 * 5 / 4)
127
+ SYNC_1 = sync(480 * 4 * 1)
128
+ SYNC_3_4 = sync(480 * 4 * 3 / 4)
129
+ SYNC_1_2 = sync(480 * 4 * 1 / 2)
130
+ SYNC_1_4D = sync(480 * 4 * 1 / 4 * 3 / 2)
131
+ SYNC_1_4 = sync(480 * 4 * 1 / 4)
132
+ SYNC_1_4T = sync(480 * 4 * 1 / 4 * 2 / 3)
133
+ SYNC_1_8D = sync(480 * 4 * 1 / 8 * 3 / 2)
134
+ SYNC_1_8 = sync(480 * 4 * 1 / 8)
135
+ SYNC_1_8T = sync(480 * 4 * 1 / 8 * 2 / 3)
136
+ SYNC_1_16D = sync(480 * 4 * 1 / 16 * 3 / 2)
137
+ SYNC_1_16 = sync(480 * 4 * 1 / 16)
138
+ SYNC_1_16T = sync(480 * 4 * 1 / 16 * 2 / 3)
139
+ SYNC_1_32D = sync(480 * 4 * 1 / 32 * 3 / 2)
140
+ SYNC_1_32 = sync(480 * 4 * 1 / 32)
141
+ SYNC_1_32T = sync(480 * 4 * 1 / 32 * 2 / 3)
142
+ SYNC_1_64D = sync(480 * 4 * 1 / 64 * 3 / 2)
143
+ SYNC_1_64 = sync(480 * 4 * 1 / 64)
144
+ SYNC_1_64T = sync(480 * 4 * 1 / 64 * 2 / 3)
145
+ SYNC_1_128D = sync(480 * 4 * 1 / 128 * 3 / 2)
146
+ SYNC_1_128 = sync(480 * 4 * 1 / 128)
147
+ SYNC_1_128T = sync(480 * 4 * 1 / 128 * 2 / 3)
97
148
  end
98
149
  end
@@ -1,3 +1,3 @@
1
1
  module AudioStream
2
- VERSION = "3.3.0"
2
+ VERSION = "3.4.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: audio_stream
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yoshida Tetsuya
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-12-02 00:00:00.000000000 Z
11
+ date: 2021-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -138,15 +138,28 @@ files:
138
138
  - audio_stream.gemspec
139
139
  - bin/console
140
140
  - bin/setup
141
- - examples/biquad.ipynb
142
- - examples/chorus.rb
143
- - examples/distortion.rb
144
- - examples/equalizer.ipynb
141
+ - examples/bench_fx.rb
142
+ - examples/canon.wav
145
143
  - examples/example_options.rb
144
+ - examples/fx_chorus.rb
145
+ - examples/fx_compressor.rb
146
+ - examples/fx_convolution_reverb.rb
147
+ - examples/fx_delay.rb
148
+ - examples/fx_distortion.rb
149
+ - examples/fx_noise_gate.rb
150
+ - examples/fx_phaser.rb
151
+ - examples/fx_schroeder_reverb.rb
152
+ - examples/fx_vocoder.rb
153
+ - examples/impulse_shaker.wav
154
+ - examples/impulse_shaker_bigroom.wav
155
+ - examples/impulse_shaker_smallhall.wav
146
156
  - examples/lpf.rb
147
157
  - examples/rec.rb
148
158
  - examples/tremolo.rb
149
159
  - examples/tuner.rb
160
+ - jupyter/band_pass_filter.ipynb
161
+ - jupyter/biquad.ipynb
162
+ - jupyter/equalizer.ipynb
150
163
  - lib/audio_stream.rb
151
164
  - lib/audio_stream/audio_bus.rb
152
165
  - lib/audio_stream/audio_input.rb
@@ -208,7 +221,7 @@ metadata:
208
221
  homepage_uri: https://github.com/yoshida-eth0/ruby-audio_stream
209
222
  source_code_uri: https://github.com/yoshida-eth0/ruby-audio_stream
210
223
  changelog_uri: https://github.com/yoshida-eth0/ruby-audio_stream
211
- post_install_message:
224
+ post_install_message:
212
225
  rdoc_options: []
213
226
  require_paths:
214
227
  - lib
@@ -223,8 +236,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
223
236
  - !ruby/object:Gem::Version
224
237
  version: '0'
225
238
  requirements: []
226
- rubygems_version: 3.0.3
227
- signing_key:
239
+ rubygems_version: 3.2.3
240
+ signing_key:
228
241
  specification_version: 4
229
242
  summary: AudioStream is a Digital Audio Workstation for CLI
230
243
  test_files: []