audio_stream 3.1.0 → 3.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e0dd181cb0224f6603451bf72f635deaa9d406ba76f8e587de6b512f1483a1c0
4
- data.tar.gz: b38c9e486e71646a7db650e1c8731d1cb4d8078f7e788bda1897c3ca89334d2d
3
+ metadata.gz: e1bdc59349cd6ef2c49c5cbc140c15037225f32f852a32ca6e951041b7a30711
4
+ data.tar.gz: 31694954a02b8920b3da085cba2ac5dfa46c851e44d44f5cf0cefa871b76e1ce
5
5
  SHA512:
6
- metadata.gz: 8d5a04e5334b1786b16578cdca72bb0f9b296453d7293f61700ebb6447c102d7cbe0509b41505edeaff0bdbcd00382bf2a10e7dcb92bd4033e6df76b48d89e27
7
- data.tar.gz: f013bc564ea68724eae776ba5c37244d0167617bbd42032cfa0399e3a03e0e6a6c089d41aaf6de42e8d440204cb5bf5b340b6ddba3b4ae0428ea4181371f7d86
6
+ metadata.gz: f88c300ac5d2e45e2c7b8b9d4de0aba54a49b22542478c7ba0ae7408140df727cc6ffb66b68f8d6a1353cea462a678ec2bcd6ed4681684ec2c87cfa71d2404a5
7
+ data.tar.gz: b5281f647673f887c4e001e72c29e678614a064be79fc199156774dfeba2a9c9a51da49f4a58fdbd14a05fa339ced998186b54146f1a7d7c26f134c676d2a9a5
data/audio_stream.gemspec CHANGED
@@ -30,7 +30,7 @@ Gem::Specification.new do |spec|
30
30
  spec.add_development_dependency "rake", "~> 12.0"
31
31
  spec.add_development_dependency "minitest", "~> 5.0"
32
32
 
33
- spec.add_dependency "vdsp", ">= 1.10.0"
33
+ spec.add_dependency "vdsp", ">= 1.13.0"
34
34
  spec.add_dependency "ruby-audio", ">= 1.6.1"
35
35
  spec.add_dependency "coreaudio", ">= 0.0.12"
36
36
  spec.add_dependency "ruby-fftw3", ">= 1.0.2"
data/lib/audio_stream.rb CHANGED
@@ -17,6 +17,7 @@ require 'audio_stream/audio_observer'
17
17
  require 'audio_stream/audio_observer_lambda'
18
18
  require 'audio_stream/audio_observable'
19
19
  require 'audio_stream/audio_observable_fx'
20
+ require 'audio_stream/audio_observable_fx_bus'
20
21
  require 'audio_stream/audio_observable_lambda'
21
22
  require 'audio_stream/audio_notification'
22
23
  require 'audio_stream/audio_input'
@@ -15,10 +15,19 @@ module AudioStream
15
15
  notify_observers(AudioNotification.new(AudioNotification::STAT_COMPLETE, nil, self))
16
16
  end
17
17
 
18
- def fx(effector)
19
- observer = AudioObservableFx.new(effector)
20
- add_observer(observer)
21
- observer
18
+ def fx(effector, **kwargs)
19
+ if Fx::MultiAudioInputtable===effector
20
+ bus = AudioObservableFxBus.new(effector)
21
+ bus.connect_observable(:main, self)
22
+ kwargs.each {|key, observable|
23
+ bus.connect_observable(key, observable)
24
+ }
25
+ bus
26
+ else
27
+ observer = AudioObservableFx.new(effector)
28
+ add_observer(observer)
29
+ observer
30
+ end
22
31
  end
23
32
 
24
33
  def stereo
@@ -0,0 +1,76 @@
1
+ module AudioStream
2
+ class AudioObservableFxBus
3
+ include AudioObserver
4
+ include AudioObservable
5
+
6
+ def initialize(effector)
7
+ @effector = effector
8
+ @mutex = Mutex.new
9
+ @observable_keys = {}
10
+ @notifications = {}
11
+ end
12
+
13
+ def connect_observable(key, observable)
14
+ @mutex.synchronize {
15
+ if !@effector.audio_input_keys.include?(key)
16
+ raise Error.new("audio input key is not registed: %s => %s", @effector.class.name, key)
17
+ end
18
+
19
+ # delete
20
+ @observable_keys.select {|obs, key1|
21
+ key1==key
22
+ }.each {|obs, key1|
23
+ obs.delete_observer(self)
24
+ @observable_keys.delete(obs)
25
+ }
26
+
27
+ # add
28
+ @observable_keys[observable] = key
29
+ observable.add_observer(self)
30
+ }
31
+ end
32
+
33
+ def update(notification)
34
+ do_notify = false
35
+ is_completed = false
36
+ next_inputs = nil
37
+
38
+ @mutex.synchronize {
39
+ @notifications[notification.caller_obj] = notification
40
+
41
+ if @notifications.length==@observable_keys.length
42
+ next_inputs = {}
43
+ @notifications.each {|caller_obj, notification|
44
+ key = @observable_keys[notification.caller_obj]
45
+ case notification.stat
46
+ when AudioNotification::STAT_NEXT
47
+ next_inputs[key] = notification.input
48
+ when AudioNotification::STAT_COMPLETE
49
+ is_completed = true
50
+ end
51
+ }
52
+
53
+ do_notify = true
54
+ @notifications.clear
55
+ end
56
+ }
57
+
58
+ if do_notify
59
+ if !is_completed
60
+ on_next(next_inputs)
61
+ else
62
+ on_complete
63
+ end
64
+ end
65
+ end
66
+
67
+ def on_next(inputs)
68
+ output = @effector.process(inputs)
69
+ notify_next(output)
70
+ end
71
+
72
+ def on_complete
73
+ notify_complete
74
+ end
75
+ end
76
+ end
@@ -1,4 +1,5 @@
1
1
  require 'audio_stream/fx/bang_process'
2
+ require 'audio_stream/fx/multi_audio_inputtable'
2
3
 
3
4
  require 'audio_stream/fx/a_gain'
4
5
  require 'audio_stream/fx/panning'
@@ -20,6 +21,7 @@ require 'audio_stream/fx/tremolo'
20
21
  require 'audio_stream/fx/delay'
21
22
  require 'audio_stream/fx/chorus'
22
23
  require 'audio_stream/fx/phaser'
24
+ require 'audio_stream/fx/vocoder'
23
25
  require 'audio_stream/fx/convolution_reverb'
24
26
  require 'audio_stream/fx/comb_filter'
25
27
  require 'audio_stream/fx/schroeder_reverb'
@@ -0,0 +1,14 @@
1
+ module AudioStream
2
+ module Fx
3
+
4
+ module MultiAudioInputtable
5
+ def audio_input_keys
6
+ @audio_input_keys ||= Set.new
7
+ end
8
+
9
+ def regist_audio_input(key)
10
+ audio_input_keys << key
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,53 @@
1
+ module AudioStream
2
+ module Fx
3
+ class Vocoder
4
+ include MultiAudioInputtable
5
+
6
+ def initialize(soundinfo, shift: 0, bandwidth: 0.2)
7
+ regist_audio_input(:main)
8
+ regist_audio_input(:side)
9
+
10
+ band_num = 16
11
+ nyquist = soundinfo.samplerate * 0.5
12
+
13
+ @modulator_bpfs = band_num.times.map {|i|
14
+ [i, 6.875 * (2 ** (i*0.5 + 3 - (shift/12.0)))]
15
+ }.select {|i, freq|
16
+ 0<freq && freq<nyquist
17
+ }.map {|i, freq|
18
+ [i, BandPassFilter.create(soundinfo, freq: freq, bandwidth: bandwidth)]
19
+ }.to_h
20
+
21
+ @carrier_bpfs = band_num.times.map {|i|
22
+ [i, 6.875 * (2 ** (i*0.5 + 3))]
23
+ }.select {|i, freq|
24
+ 0<freq && freq<nyquist
25
+ }.map {|i, freq|
26
+ [i, BandPassFilter.create(soundinfo, freq: freq, bandwidth: bandwidth)]
27
+ }.to_h
28
+
29
+ @band_keys = @modulator_bpfs.keys & @carrier_bpfs.keys
30
+ end
31
+
32
+ def process(inputs)
33
+ carrier = inputs[:main]
34
+ modulator = inputs[:side]
35
+
36
+ channels = [carrier.channels, modulator.channels].max
37
+ if channels==2
38
+ carrier = carrier.stereo
39
+ modulator = modulator.stereo
40
+ end
41
+
42
+ dsts = channels.times.map {|i|
43
+ @band_keys.map {|key|
44
+ level = @modulator_bpfs[key].process(modulator).streams[i].max
45
+ @carrier_bpfs[key].process(carrier).streams[i] * level
46
+ }.inject(:+)
47
+ }
48
+
49
+ Buffer.new(*dsts)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -1,3 +1,3 @@
1
1
  module AudioStream
2
- VERSION = "3.1.0"
2
+ VERSION = "3.2.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.1.0
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yoshida Tetsuya
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-10-24 00:00:00.000000000 Z
11
+ date: 2019-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 1.10.0
61
+ version: 1.13.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 1.10.0
68
+ version: 1.13.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: ruby-audio
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -156,6 +156,7 @@ files:
156
156
  - lib/audio_stream/audio_notification.rb
157
157
  - lib/audio_stream/audio_observable.rb
158
158
  - lib/audio_stream/audio_observable_fx.rb
159
+ - lib/audio_stream/audio_observable_fx_bus.rb
159
160
  - lib/audio_stream/audio_observable_lambda.rb
160
161
  - lib/audio_stream/audio_observer.rb
161
162
  - lib/audio_stream/audio_observer_lambda.rb
@@ -186,6 +187,7 @@ files:
186
187
  - lib/audio_stream/fx/high_shelf_filter.rb
187
188
  - lib/audio_stream/fx/low_pass_filter.rb
188
189
  - lib/audio_stream/fx/low_shelf_filter.rb
190
+ - lib/audio_stream/fx/multi_audio_inputtable.rb
189
191
  - lib/audio_stream/fx/noise_gate.rb
190
192
  - lib/audio_stream/fx/panning.rb
191
193
  - lib/audio_stream/fx/peaking_filter.rb
@@ -193,6 +195,7 @@ files:
193
195
  - lib/audio_stream/fx/schroeder_reverb.rb
194
196
  - lib/audio_stream/fx/tremolo.rb
195
197
  - lib/audio_stream/fx/tuner.rb
198
+ - lib/audio_stream/fx/vocoder.rb
196
199
  - lib/audio_stream/ring_buffer.rb
197
200
  - lib/audio_stream/sound_info.rb
198
201
  - lib/audio_stream/sync.rb
@@ -219,7 +222,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
219
222
  - !ruby/object:Gem::Version
220
223
  version: '0'
221
224
  requirements: []
222
- rubygems_version: 3.0.4
225
+ rubygems_version: 3.0.3
223
226
  signing_key:
224
227
  specification_version: 4
225
228
  summary: AudioStream is a Digital Audio Workstation for CLI