audio_stream 3.2.0 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/audio_stream.rb +1 -0
- data/lib/audio_stream/audio_bus.rb +1 -1
- data/lib/audio_stream/buffer.rb +1 -1
- data/lib/audio_stream/decibel.rb +8 -0
- data/lib/audio_stream/fx/a_gain.rb +7 -2
- data/lib/audio_stream/fx/all_pass_filter.rb +3 -0
- data/lib/audio_stream/fx/band_pass_filter.rb +3 -0
- data/lib/audio_stream/fx/comb_filter.rb +4 -2
- data/lib/audio_stream/fx/delay.rb +7 -4
- data/lib/audio_stream/fx/distortion.rb +5 -3
- data/lib/audio_stream/fx/equalizer_2band.rb +3 -0
- data/lib/audio_stream/fx/high_pass_filter.rb +3 -0
- data/lib/audio_stream/fx/high_shelf_filter.rb +8 -0
- data/lib/audio_stream/fx/low_pass_filter.rb +3 -0
- data/lib/audio_stream/fx/low_shelf_filter.rb +8 -0
- data/lib/audio_stream/fx/peaking_filter.rb +8 -0
- data/lib/audio_stream/fx/phaser.rb +11 -5
- data/lib/audio_stream/fx/vocoder.rb +3 -0
- data/lib/audio_stream/rate.rb +98 -0
- data/lib/audio_stream/sound_info.rb +12 -1
- data/lib/audio_stream/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0011df46c8c5a4ca83fac3301ca638940087710da3dd996382a354d9aa19596f
|
4
|
+
data.tar.gz: d88cb6715119d98bd02ee980be8cf9446b3a729a8de5003cf77a0dc0f958501a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7059283b291c17fec85bcd40f194d8312a0f2539fe093a31268c5361f6a00517390a5d5c56df72cedb9dcc8432100a066834dee1fde4872039cf5adc2524c58c
|
7
|
+
data.tar.gz: 55340551e2da2ce9dcd87c89261b71868687d30ab65167f05552402c10d2e227337ccc7bba0c5ae9c7ebc737e779fa85952fb3056db3a7b5a1a65423fcffeed2
|
data/lib/audio_stream.rb
CHANGED
@@ -9,6 +9,7 @@ require 'audio_stream/version'
|
|
9
9
|
require 'audio_stream/error'
|
10
10
|
require 'audio_stream/sound_info'
|
11
11
|
require 'audio_stream/decibel'
|
12
|
+
require 'audio_stream/rate'
|
12
13
|
require 'audio_stream/buffer'
|
13
14
|
require 'audio_stream/ring_buffer'
|
14
15
|
require 'audio_stream/sync'
|
data/lib/audio_stream/buffer.rb
CHANGED
data/lib/audio_stream/decibel.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
module AudioStream
|
2
2
|
module Fx
|
3
3
|
class AGain
|
4
|
-
|
5
|
-
|
4
|
+
# @param level [AudioStream::Decibel] Amplification level
|
5
|
+
def initialize(level:)
|
6
|
+
if Decibel===level
|
7
|
+
@level = level.mag
|
8
|
+
else
|
9
|
+
@level = Decibel.db(level).mag
|
10
|
+
end
|
6
11
|
end
|
7
12
|
|
8
13
|
def process(input)
|
@@ -19,6 +19,9 @@ module AudioStream
|
|
19
19
|
}
|
20
20
|
end
|
21
21
|
|
22
|
+
# @param soundinfo [AudioStream::SoundInfo]
|
23
|
+
# @param freq [Float] Cutoff frequency
|
24
|
+
# @param q [Float] Quality factor
|
22
25
|
def self.create(soundinfo, freq:, q: DEFAULT_Q)
|
23
26
|
filter = new(soundinfo)
|
24
27
|
filter.update_coef(freq: freq, q: q)
|
@@ -19,6 +19,9 @@ module AudioStream
|
|
19
19
|
}
|
20
20
|
end
|
21
21
|
|
22
|
+
# @param soundinfo [AudioStream::SoundInfo]
|
23
|
+
# @param freq [Float] Center frequency
|
24
|
+
# @param bandwidth [Float] bandwidth (octave)
|
22
25
|
def self.create(soundinfo, freq:, bandwidth: 1.0)
|
23
26
|
filter = new(soundinfo)
|
24
27
|
filter.update_coef(freq: freq, bandwidth: bandwidth)
|
@@ -2,10 +2,12 @@ module AudioStream
|
|
2
2
|
module Fx
|
3
3
|
class CombFilter
|
4
4
|
|
5
|
+
# @param soundinfo [AudioStream::SoundInfo]
|
6
|
+
# @param freq [AudioStream::Rate] frequency
|
7
|
+
# @param q [Float] Quality factor
|
5
8
|
def initialize(soundinfo, freq:, q:)
|
6
9
|
@window_size = soundinfo.window_size
|
7
|
-
@
|
8
|
-
@delaysample = (soundinfo.samplerate.to_f / freq).round
|
10
|
+
@delaysample = freq.sample(soundinfo).round
|
9
11
|
@q = q
|
10
12
|
|
11
13
|
@delaybufs = [
|
@@ -1,12 +1,15 @@
|
|
1
1
|
module AudioStream
|
2
2
|
module Fx
|
3
3
|
class Delay
|
4
|
+
# @param soundinfo [AudioStream::SoundInfo]
|
5
|
+
# @param time [AudioStream::Rate] delay time
|
6
|
+
# @param level [AudioStream::Decibel] wet gain
|
7
|
+
# @param feedback [AudioStream::Decibel] feedback level
|
4
8
|
def initialize(soundinfo, time:, level:, feedback:)
|
5
|
-
@
|
6
|
-
@
|
7
|
-
@feedback = feedback
|
9
|
+
@level = Decibel.create(level).mag
|
10
|
+
@feedback = Decibel.create(feedback).mag
|
8
11
|
|
9
|
-
@delaysample = (soundinfo
|
12
|
+
@delaysample = time.sample(soundinfo).round
|
10
13
|
@delaybuf0 = Array.new(@delaysample, 0.0)
|
11
14
|
@delaybuf1 = Array.new(@delaysample, 0.0)
|
12
15
|
@seek = 0
|
@@ -1,9 +1,11 @@
|
|
1
1
|
module AudioStream
|
2
2
|
module Fx
|
3
3
|
class Distortion
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
# @param gain [AudioStream::Decibel] input gain
|
5
|
+
# @param level [AudioStream::Decibel] output level
|
6
|
+
def initialize(gain: 40.0, level: -20.0)
|
7
|
+
@gain = Decibel.create(gain).mag
|
8
|
+
@level = Decibel.create(level).mag
|
7
9
|
end
|
8
10
|
|
9
11
|
def process(input)
|
@@ -1,6 +1,9 @@
|
|
1
1
|
module AudioStream
|
2
2
|
module Fx
|
3
3
|
class Equalizer2band
|
4
|
+
# @param freq [Float] Cutoff frequency
|
5
|
+
# @param q [Float] Quality factor
|
6
|
+
# @param gain [AudioStream::Decibel] Amplification level at cutoff frequency
|
4
7
|
def initialize(soundinfo, lowfreq: 400.0, lowgain:, highfreq: 4000.0, highgain:)
|
5
8
|
@low_filter = LowShelfFilter.create(soundinfo, freq: lowfreq, q: BiquadFilter::DEFAULT_Q, gain: lowgain)
|
6
9
|
@high_filter = HighShelfFilter.create(soundinfo, freq: highfreq, q: BiquadFilter::DEFAULT_Q, gain: highgain)
|
@@ -19,6 +19,9 @@ module AudioStream
|
|
19
19
|
}
|
20
20
|
end
|
21
21
|
|
22
|
+
# @param soundinfo [AudioStream::SoundInfo]
|
23
|
+
# @param freq [Float] Cutoff frequency
|
24
|
+
# @param q [Float] Quality factor
|
22
25
|
def self.create(soundinfo, freq:, q: DEFAULT_Q)
|
23
26
|
filter = new(soundinfo)
|
24
27
|
filter.update_coef(freq: freq, q: q)
|
@@ -3,6 +3,10 @@ module AudioStream
|
|
3
3
|
class HighShelfFilter < BiquadFilter
|
4
4
|
|
5
5
|
def update_coef(freq:, q:, gain:)
|
6
|
+
if Decibel===gain
|
7
|
+
gain = gain.db
|
8
|
+
end
|
9
|
+
|
6
10
|
omega = 2.0 * Math::PI * freq / @samplerate
|
7
11
|
alpha = Math.sin(omega) / (2.0 * q)
|
8
12
|
a = 10.0 ** (gain / 40.0)
|
@@ -21,6 +25,10 @@ module AudioStream
|
|
21
25
|
}
|
22
26
|
end
|
23
27
|
|
28
|
+
# @param soundinfo [AudioStream::SoundInfo]
|
29
|
+
# @param freq [Float] Cutoff frequency
|
30
|
+
# @param q [Float] Quality factor
|
31
|
+
# @param gain [AudioStream::Decibel] Amplification level at cutoff frequency
|
24
32
|
def self.create(soundinfo, freq:, q: DEFAULT_Q, gain: 1.0)
|
25
33
|
filter = new(soundinfo)
|
26
34
|
filter.update_coef(freq: freq, q: q, gain: gain)
|
@@ -19,6 +19,9 @@ module AudioStream
|
|
19
19
|
}
|
20
20
|
end
|
21
21
|
|
22
|
+
# @param soundinfo [AudioStream::SoundInfo]
|
23
|
+
# @param freq [Float] Cutoff frequency
|
24
|
+
# @param q [Float] Quality factor
|
22
25
|
def self.create(soundinfo, freq:, q: DEFAULT_Q)
|
23
26
|
filter = new(soundinfo)
|
24
27
|
filter.update_coef(freq: freq, q: q)
|
@@ -3,6 +3,10 @@ module AudioStream
|
|
3
3
|
class LowShelfFilter < BiquadFilter
|
4
4
|
|
5
5
|
def update_coef(freq:, q:, gain:)
|
6
|
+
if Decibel===gain
|
7
|
+
gain = gain.db
|
8
|
+
end
|
9
|
+
|
6
10
|
omega = 2.0 * Math::PI * freq / @samplerate
|
7
11
|
alpha = Math.sin(omega) / (2.0 * q)
|
8
12
|
a = 10.0 ** (gain / 40.0)
|
@@ -21,6 +25,10 @@ module AudioStream
|
|
21
25
|
}
|
22
26
|
end
|
23
27
|
|
28
|
+
# @param soundinfo [AudioStream::SoundInfo]
|
29
|
+
# @param freq [Float] Cutoff frequency
|
30
|
+
# @param q [Float] Quality factor
|
31
|
+
# @param gain [AudioStream::Decibel] Amplification level at cutoff frequency
|
24
32
|
def self.create(soundinfo, freq:, q: DEFAULT_Q, gain: 1.0)
|
25
33
|
filter = new(soundinfo)
|
26
34
|
filter.update_coef(freq: freq, q: q, gain: gain)
|
@@ -3,6 +3,10 @@ module AudioStream
|
|
3
3
|
class PeakingFilter < BiquadFilter
|
4
4
|
|
5
5
|
def update_coef(freq:, bandwidth:, gain:)
|
6
|
+
if Decibel===gain
|
7
|
+
gain = gain.db
|
8
|
+
end
|
9
|
+
|
6
10
|
omega = 2.0 * Math::PI * freq / @samplerate
|
7
11
|
alpha = Math.sin(omega) * Math.sinh(Math.log(2.0) / 2.0 * bandwidth * omega / Math.sin(omega))
|
8
12
|
a = 10.0 ** (gain / 40.0)
|
@@ -20,6 +24,10 @@ module AudioStream
|
|
20
24
|
}
|
21
25
|
end
|
22
26
|
|
27
|
+
# @param soundinfo [AudioStream::SoundInfo]
|
28
|
+
# @param freq [Float] Cutoff frequency
|
29
|
+
# @param bandwidth [Float] bandwidth (octave)
|
30
|
+
# @param gain [AudioStream::Decibel] Amplification level at cutoff frequency
|
23
31
|
def self.create(soundinfo, freq:, bandwidth: 1.0, gain: 40.0)
|
24
32
|
filter = new(soundinfo)
|
25
33
|
filter.update_coef(freq: freq, bandwidth: bandwidth, gain: gain)
|
@@ -2,7 +2,13 @@ module AudioStream
|
|
2
2
|
module Fx
|
3
3
|
class Phaser
|
4
4
|
|
5
|
-
|
5
|
+
# @param soundinfo [AudioStream::SoundInfo]
|
6
|
+
# @param rate [AudioStream::Rate] modulation speed
|
7
|
+
# @param depth [Float] frequency modulation depth
|
8
|
+
# @param freq [Float] Base cutoff frequency
|
9
|
+
# @param dry [AudioStream::Decibel] dry gain
|
10
|
+
# @param wet [AudioStream::Decibel] wet gain
|
11
|
+
def initialize(soundinfo, rate:, depth:, freq:, dry: -6.0, wet: -6.0)
|
6
12
|
@soundinfo = soundinfo
|
7
13
|
|
8
14
|
@filters = [
|
@@ -10,19 +16,19 @@ module AudioStream
|
|
10
16
|
AllPassFilter.new(soundinfo),
|
11
17
|
]
|
12
18
|
|
13
|
-
@speed =
|
19
|
+
@speed = rate.frame_phase(soundinfo)
|
14
20
|
@phase = 0
|
15
21
|
|
16
22
|
@depth = depth
|
17
23
|
@freq = freq
|
18
24
|
|
19
|
-
@dry = dry
|
20
|
-
@wet = wet
|
25
|
+
@dry = Decibel.create(dry).mag
|
26
|
+
@wet = Decibel.create(wet).mag
|
21
27
|
end
|
22
28
|
|
23
29
|
def process(input)
|
24
30
|
window_size = input.window_size
|
25
|
-
@phase = (@phase + @speed
|
31
|
+
@phase = (@phase + @speed) % (2.0 * Math::PI)
|
26
32
|
|
27
33
|
a = Math.sin(@phase) * 0.5 + 0.5
|
28
34
|
apf_freq = @freq * (1.0 + a * @depth)
|
@@ -3,6 +3,9 @@ module AudioStream
|
|
3
3
|
class Vocoder
|
4
4
|
include MultiAudioInputtable
|
5
5
|
|
6
|
+
# @param soundinfo [AudioStream::SoundInfo]
|
7
|
+
# @param shift [Float] modulator pitch shift. 1.0=1semitone
|
8
|
+
# @param bandwidth [Float] bandwidth (octave)
|
6
9
|
def initialize(soundinfo, shift: 0, bandwidth: 0.2)
|
7
10
|
regist_audio_input(:main)
|
8
11
|
regist_audio_input(:side)
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module AudioStream
|
2
|
+
class Rate
|
3
|
+
def initialize(sec: nil, sample: nil, freq: nil, sync: nil)
|
4
|
+
@sec = sec
|
5
|
+
@sample = sample
|
6
|
+
@freq = freq
|
7
|
+
@sync = sync
|
8
|
+
end
|
9
|
+
|
10
|
+
def sec(soundinfo)
|
11
|
+
sample(soundinfo).to_f / soundinfo.samplerate
|
12
|
+
end
|
13
|
+
|
14
|
+
def frame(soundinfo)
|
15
|
+
sample(soundinfo).to_f / soundinfo.window_size
|
16
|
+
end
|
17
|
+
|
18
|
+
def sample(soundinfo)
|
19
|
+
if @sample
|
20
|
+
return @sample
|
21
|
+
end
|
22
|
+
|
23
|
+
if @sec
|
24
|
+
return @sec.to_f * soundinfo.samplerate
|
25
|
+
end
|
26
|
+
|
27
|
+
if @freq
|
28
|
+
return soundinfo.samplerate.to_f / @freq
|
29
|
+
end
|
30
|
+
|
31
|
+
if @sync
|
32
|
+
return @sync / 480.0 * soundinfo.sync_rate
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def frame_phase(soundinfo)
|
37
|
+
sample_phase(soundinfo) * soundinfo.window_size
|
38
|
+
end
|
39
|
+
|
40
|
+
def sample_phase(soundinfo)
|
41
|
+
2.0 * Math::PI / sample(soundinfo)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.sec(v)
|
45
|
+
new(sec: v)
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.millisec(v)
|
49
|
+
new(sec: v*0.001)
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.sample(v)
|
53
|
+
new(sample: v)
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.freq(v)
|
57
|
+
new(freq: v)
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.sync(v)
|
61
|
+
new(sync: v)
|
62
|
+
end
|
63
|
+
|
64
|
+
|
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)
|
97
|
+
end
|
98
|
+
end
|
@@ -1,13 +1,24 @@
|
|
1
1
|
module AudioStream
|
2
2
|
class SoundInfo < RubyAudio::SoundInfo
|
3
3
|
attr_accessor :window_size
|
4
|
+
attr_reader :bpm
|
5
|
+
attr_reader :bps
|
4
6
|
|
5
7
|
def framerate
|
6
8
|
self.samplerate.to_f / self.window_size
|
7
9
|
end
|
8
10
|
|
11
|
+
def bpm=(bpm)
|
12
|
+
@bpm = bpm.to_f
|
13
|
+
@bps = @bpm / 60.0
|
14
|
+
end
|
15
|
+
|
16
|
+
def sync_rate
|
17
|
+
self.samplerate.to_f / self.bps
|
18
|
+
end
|
19
|
+
|
9
20
|
def clone
|
10
|
-
SoundInfo.new(channels: channels, samplerate: samplerate, format: format, window_size: window_size)
|
21
|
+
SoundInfo.new(channels: channels, samplerate: samplerate, format: format, window_size: window_size, bpm: bpm)
|
11
22
|
end
|
12
23
|
end
|
13
24
|
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.3.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-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -196,6 +196,7 @@ files:
|
|
196
196
|
- lib/audio_stream/fx/tremolo.rb
|
197
197
|
- lib/audio_stream/fx/tuner.rb
|
198
198
|
- lib/audio_stream/fx/vocoder.rb
|
199
|
+
- lib/audio_stream/rate.rb
|
199
200
|
- lib/audio_stream/ring_buffer.rb
|
200
201
|
- lib/audio_stream/sound_info.rb
|
201
202
|
- lib/audio_stream/sync.rb
|