audio_stream 3.1.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
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