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 +4 -4
- data/audio_stream.gemspec +1 -1
- data/lib/audio_stream.rb +1 -0
- data/lib/audio_stream/audio_observable.rb +13 -4
- data/lib/audio_stream/audio_observable_fx_bus.rb +76 -0
- data/lib/audio_stream/fx.rb +2 -0
- data/lib/audio_stream/fx/multi_audio_inputtable.rb +14 -0
- data/lib/audio_stream/fx/vocoder.rb +53 -0
- data/lib/audio_stream/version.rb +1 -1
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e1bdc59349cd6ef2c49c5cbc140c15037225f32f852a32ca6e951041b7a30711
|
4
|
+
data.tar.gz: 31694954a02b8920b3da085cba2ac5dfa46c851e44d44f5cf0cefa871b76e1ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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
|
-
|
20
|
-
|
21
|
-
|
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
|
data/lib/audio_stream/fx.rb
CHANGED
@@ -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,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
|
data/lib/audio_stream/version.rb
CHANGED
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.
|
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-
|
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.
|
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.
|
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.
|
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
|