audio_stream 1.0.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 (67) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.travis.yml +7 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +39 -0
  7. data/Rakefile +10 -0
  8. data/audio_stream.gemspec +38 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/examples/adsr.ipynb +88 -0
  12. data/examples/buffer.ipynb +160 -0
  13. data/examples/chorus.rb +41 -0
  14. data/examples/curves.ipynb +105 -0
  15. data/examples/distortion.rb +43 -0
  16. data/examples/example_options.rb +56 -0
  17. data/examples/rec.rb +53 -0
  18. data/examples/shapes.ipynb +116 -0
  19. data/examples/sin.rb +62 -0
  20. data/examples/tremolo.rb +38 -0
  21. data/examples/tuner.rb +77 -0
  22. data/lib/audio_stream.rb +30 -0
  23. data/lib/audio_stream/audio_bus.rb +28 -0
  24. data/lib/audio_stream/audio_input.rb +48 -0
  25. data/lib/audio_stream/audio_input_buffer.rb +21 -0
  26. data/lib/audio_stream/audio_input_device.rb +50 -0
  27. data/lib/audio_stream/audio_input_file.rb +30 -0
  28. data/lib/audio_stream/audio_input_metronome.rb +49 -0
  29. data/lib/audio_stream/audio_input_sin.rb +41 -0
  30. data/lib/audio_stream/audio_output.rb +17 -0
  31. data/lib/audio_stream/audio_output_device.rb +65 -0
  32. data/lib/audio_stream/audio_output_file.rb +35 -0
  33. data/lib/audio_stream/buffer.rb +84 -0
  34. data/lib/audio_stream/conductor.rb +38 -0
  35. data/lib/audio_stream/core_ext.rb +13 -0
  36. data/lib/audio_stream/error.rb +4 -0
  37. data/lib/audio_stream/fx.rb +30 -0
  38. data/lib/audio_stream/fx/a_gain.rb +26 -0
  39. data/lib/audio_stream/fx/band_pass_filter.rb +29 -0
  40. data/lib/audio_stream/fx/bang_process.rb +11 -0
  41. data/lib/audio_stream/fx/biquad_filter.rb +58 -0
  42. data/lib/audio_stream/fx/chorus.rb +59 -0
  43. data/lib/audio_stream/fx/compressor.rb +41 -0
  44. data/lib/audio_stream/fx/convolution_reverb.rb +107 -0
  45. data/lib/audio_stream/fx/delay.rb +45 -0
  46. data/lib/audio_stream/fx/distortion.rb +42 -0
  47. data/lib/audio_stream/fx/equalizer_2band.rb +23 -0
  48. data/lib/audio_stream/fx/equalizer_3band.rb +28 -0
  49. data/lib/audio_stream/fx/hanning_window.rb +29 -0
  50. data/lib/audio_stream/fx/high_pass_filter.rb +29 -0
  51. data/lib/audio_stream/fx/high_shelf_filter.rb +32 -0
  52. data/lib/audio_stream/fx/low_pass_filter.rb +29 -0
  53. data/lib/audio_stream/fx/low_shelf_filter.rb +32 -0
  54. data/lib/audio_stream/fx/mono_to_stereo.rb +18 -0
  55. data/lib/audio_stream/fx/noise_gate.rb +47 -0
  56. data/lib/audio_stream/fx/panning.rb +41 -0
  57. data/lib/audio_stream/fx/peaking_filter.rb +31 -0
  58. data/lib/audio_stream/fx/stereo_to_mono.rb +18 -0
  59. data/lib/audio_stream/fx/tremolo.rb +34 -0
  60. data/lib/audio_stream/fx/tuner.rb +98 -0
  61. data/lib/audio_stream/plot.rb +53 -0
  62. data/lib/audio_stream/ring_buffer.rb +39 -0
  63. data/lib/audio_stream/sound_info.rb +9 -0
  64. data/lib/audio_stream/sync.rb +32 -0
  65. data/lib/audio_stream/utils.rb +45 -0
  66. data/lib/audio_stream/version.rb +3 -0
  67. metadata +223 -0
@@ -0,0 +1,41 @@
1
+ module AudioStream
2
+ module Fx
3
+ class Panning
4
+ include BangProcess
5
+
6
+ def initialize(pan: 0.0)
7
+ @pan = pan
8
+
9
+ @l_gain = 1.0 - pan
10
+ @lr_gain = 0.0
11
+ if 1.0<@l_gain
12
+ @lr_gain = @l_gain - 1.0
13
+ @l_gain = 1.0
14
+ end
15
+
16
+ @r_gain = 1.0 + pan
17
+ @rl_gain = 0.0
18
+ if 1.0<@r_gain
19
+ @rl_gain = @r_gain - 1.0
20
+ @r_gain = 1.0
21
+ end
22
+
23
+ @normalize = [1.0 - pan, 1.0 + pan].max
24
+ end
25
+
26
+ def process!(input)
27
+ return if @pan==0.0
28
+
29
+ case input.channels
30
+ when 1
31
+ when 2
32
+ input.each_with_index {|fa, i|
33
+ l = (fa[0] * @l_gain + fa[1] * @lr_gain) / @normalize
34
+ r = (fa[1] * @r_gain + fa[0] * @rl_gain) / @normalize
35
+ input[i] = [l, r]
36
+ }
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,31 @@
1
+ module AudioStream
2
+ module Fx
3
+ class PeakingFilter < BiquadFilter
4
+
5
+ def initialize(soundinfo, freq:, bandwidth: 1.0, gain: 40.0)
6
+ super()
7
+ @samplerate = soundinfo.samplerate.to_f
8
+ @freq = freq
9
+ @bandwidth = bandwidth
10
+ @gain = gain
11
+
12
+ filter_coef
13
+ end
14
+
15
+ def filter_coef
16
+ omega = 2.0 * Math::PI * @freq / @samplerate
17
+ alpha = Math.sin(omega) * Math.sinh(Math.log(2.0) / 2.0 * @bandwidth * omega / Math.sin(omega))
18
+ a = 10.0 ** (@gain / 40.0)
19
+
20
+ a0 = 1.0 + alpha / a
21
+ a1 = -2.0 * Math.cos(omega)
22
+ a2 = 1.0 - alpha / a
23
+ b0 = 1.0 + alpha * a
24
+ b1 = -2.0 * Math.cos(omega)
25
+ b2 = 1.0 + alpha * a
26
+
27
+ @filter_coef = FilterCoef.new(a0, a1, a2, b0, b1, b2)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,18 @@
1
+ module AudioStream
2
+ module Fx
3
+ class StereoToMono
4
+ def process(input)
5
+ case input.channels
6
+ when 1
7
+ input.clone
8
+ when 2
9
+ output = Buffer.float(input.size, 1)
10
+ input.each_with_index {|fa, i|
11
+ output[i] = fa.sum / 2.0
12
+ }
13
+ output
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,34 @@
1
+ module AudioStream
2
+ module Fx
3
+ class Tremolo
4
+ include BangProcess
5
+
6
+ def initialize(soundinfo, freq:, depth:)
7
+ @samplerate = soundinfo.samplerate
8
+ @freq = freq.to_f
9
+ @depth = depth.to_f
10
+ @phase = 0
11
+ end
12
+
13
+ def process!(input)
14
+ window_size = input.size
15
+ channels = input.channels
16
+
17
+ period = 2 * Math::PI * @freq / @samplerate
18
+
19
+ case channels
20
+ when 1
21
+ input.each_with_index {|f, i|
22
+ input[i] *= 1.0 + @depth * Math.sin((i + @phase) * period)
23
+ }
24
+ when 2
25
+ input.each_with_index {|fa, i|
26
+ gain = 1.0 + @depth * Math.sin((i + @phase) * period)
27
+ input[i] = fa.map {|f| f * gain}
28
+ }
29
+ end
30
+ @phase = (@phase + window_size) % (window_size / period)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,98 @@
1
+ module AudioStream
2
+ module Fx
3
+ class Tuner
4
+
5
+ Tune = Struct.new("Tune", :freq, :note_num, :note, :octave, :diff, :gain, keyword_init: true)
6
+
7
+ FREQ_TABLE = 10.times.map {|i|
8
+ a = 13.75 * 2 ** i
9
+ 12.times.map {|j|
10
+ a * (2 ** (j / 12.0))
11
+ }
12
+ }.flatten.freeze
13
+
14
+ NOTE_TABLE = ["A", "A#/Bb", "B", "C", "C#/Db", "D", "D#/Eb", "E", "F", "F#/Gb", "G", "G#/Ab"].freeze
15
+
16
+ def initialize(soundinfo, window: nil)
17
+ @samplerate = soundinfo.samplerate.to_f
18
+ @window = window || HanningWindow.new
19
+ end
20
+
21
+ def process(input)
22
+ window_size = input.size
23
+
24
+ # mono window
25
+ input = StereoToMono.new.process(input)
26
+ @window.process!(input)
27
+
28
+ gain = input.to_a.flatten.max
29
+ freq = nil
30
+
31
+ if 0.01<gain
32
+ # fft
33
+ na = NArray.float(1, window_size)
34
+ na[0...na.size] = input.to_a
35
+ fft = FFTW3.fft(na, FFTW3::FORWARD) / na.length
36
+
37
+ amp = fft.map {|c|
38
+ c.real**2 + c.imag**2
39
+ }.real.to_a.flatten
40
+
41
+ # peak
42
+ i = amp.index(amp.max)
43
+
44
+ if window_size/2<i
45
+ j = window_size - i
46
+ if (amp[i]-amp[j]).abs<=0.0000001
47
+ i = j
48
+ end
49
+ end
50
+
51
+ # freq
52
+ freq_rate = @samplerate / window_size
53
+
54
+ if 0<i && i<window_size-1
55
+ freq_sum = amp[i-1] * (i-1) * freq_rate
56
+ freq_sum += amp[i] * i * freq_rate
57
+ freq_sum += amp[i+1] * (i+1) * freq_rate
58
+
59
+ amp_sum = amp[i-1] + amp[i] + amp[i+1]
60
+
61
+ freq = freq_sum / amp_sum
62
+ else
63
+ freq = i * freq_rate
64
+ end
65
+
66
+ struct(freq)
67
+ else
68
+ Tune.new
69
+ end
70
+ end
71
+
72
+ def struct(freq)
73
+ index = FREQ_TABLE.bsearch_index {|x| x>=freq}
74
+ if !index || FREQ_TABLE.length<=index+1
75
+ return Tune.new
76
+ end
77
+
78
+ if 0<index && freq-FREQ_TABLE[index-1] < FREQ_TABLE[index]-freq
79
+ diff = (freq-FREQ_TABLE[index-1]) / (FREQ_TABLE[index]-FREQ_TABLE[index-1]) * 100
80
+ index -= 1
81
+ else
82
+ diff = (freq-FREQ_TABLE[index]) / (FREQ_TABLE[index+1]-FREQ_TABLE[index]) * 100
83
+ end
84
+ note_num = index + 9
85
+ note = NOTE_TABLE[index%12]
86
+ octave = (index-3)/12
87
+
88
+ Tune.new(
89
+ freq: freq,
90
+ note_num: note_num,
91
+ note: note,
92
+ octave: octave,
93
+ diff: diff
94
+ )
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,53 @@
1
+ module AudioStream
2
+ class Plot
3
+ def initialize(input, soundinfo=nil)
4
+ @input = input
5
+ if soundinfo
6
+ @samplerate = soundinfo.samplerate.to_f
7
+ end
8
+ end
9
+
10
+ def wave
11
+ buf_to_plot(@input)
12
+ end
13
+
14
+ def fft(window=nil)
15
+ window ||= HanningWindow.new
16
+
17
+ na = window.process(@input).to_na
18
+ fft = FFTW3.fft(na, FFTW3::FORWARD) / na.length
19
+
20
+ buf = Buffer.from_na(fft)
21
+ buf_to_plot(buf, true)
22
+ end
23
+
24
+ def buf_to_plot(input, x_hz=false)
25
+ window_size = input.size
26
+ channels = input.channels
27
+ outputs = []
28
+
29
+ case channels
30
+ when 1
31
+ outputs << input.to_a
32
+ when 2
33
+ outputs << output_l = []
34
+ outputs << output_r = []
35
+ window_size.times {|i|
36
+ output_l << input[i][0]
37
+ output_r << input[i][1]
38
+ }
39
+ end
40
+
41
+ window_arr = window_size.times.to_a
42
+ if x_hz && @samplerate
43
+ window_arr.map!{|i| i * @samplerate / window_size}
44
+ end
45
+
46
+ traces = outputs.map {|output|
47
+ {x: window_arr, y: output}
48
+ }
49
+
50
+ Plotly::Plot.new(data: traces)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,39 @@
1
+ module AudioStream
2
+ class RingBuffer
3
+ include Enumerable
4
+
5
+ def initialize(*args, &block)
6
+ @array = Array.new(*args, &block)
7
+ @seek = 0
8
+ end
9
+
10
+ def each(&block)
11
+ Enumerator.new do|y|
12
+ start = @seek
13
+ @array.size.times {|i|
14
+ y << self[i]
15
+ }
16
+ end.each(&block)
17
+ end
18
+
19
+ def [](idx)
20
+ @array[(idx+@seek) % @array.size]
21
+ end
22
+
23
+ def []=(idx, val)
24
+ @array[(idx+@seek) % @array.size] = val
25
+ end
26
+
27
+ def current
28
+ self[0]
29
+ end
30
+
31
+ def current=(val)
32
+ self[0] = val
33
+ end
34
+
35
+ def rotate(step=1)
36
+ @seek = (@seek + step) % @array.size
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,9 @@
1
+ module AudioStream
2
+ class SoundInfo < RubyAudio::SoundInfo
3
+ attr_accessor :window_size
4
+
5
+ def clone
6
+ SoundInfo.new(channels: channels, samplerate: samplerate, format: format, window_size: window_size)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,32 @@
1
+ module AudioStream
2
+ class Sync
3
+ NEXT = :next
4
+ COMPLETED = :completed
5
+
6
+ def initialize
7
+ buffering = 1
8
+ @resume_queue = SizedQueue.new(buffering)
9
+ @yield_queue = SizedQueue.new(buffering)
10
+ end
11
+
12
+ def resume
13
+ @resume_queue.push true
14
+ end
15
+
16
+ def yield
17
+ @yield_queue.push NEXT
18
+ end
19
+
20
+ def finish
21
+ @yield_queue.push COMPLETED
22
+ end
23
+
24
+ def resume_wait
25
+ @resume_queue.pop
26
+ end
27
+
28
+ def yield_wait
29
+ @yield_queue.pop
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,45 @@
1
+ module AudioStream
2
+ module Utils
3
+
4
+ def self.panning(pan)
5
+ cp = cross_panning(pan)
6
+
7
+ {
8
+ l_gain: (cp[:l_gain] + cp[:lr_gain]) / cp[:normalize],
9
+ r_gain: (cp[:r_gain] + cp[:rl_gain]) / cp[:normalize]
10
+ }
11
+ end
12
+
13
+ def self.cross_panning(pan)
14
+ if pan<-1.0
15
+ pan = -1.0
16
+ elsif 1.0<pan
17
+ pan = 1.0
18
+ end
19
+
20
+ l_gain = 1.0 - pan
21
+ lr_gain = 0.0
22
+ if 1.0<l_gain
23
+ lr_gain = l_gain - 1.0
24
+ l_gain = 1.0
25
+ end
26
+
27
+ r_gain = 1.0 + pan
28
+ rl_gain = 0.0
29
+ if 1.0<r_gain
30
+ rl_gain = r_gain - 1.0
31
+ r_gain = 1.0
32
+ end
33
+
34
+ normalize = [1.0 - pan, 1.0 + pan].max
35
+
36
+ {
37
+ l_gain: l_gain,
38
+ lr_gain: lr_gain,
39
+ r_gain: r_gain,
40
+ rl_gain: rl_gain,
41
+ normalize: normalize
42
+ }
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,3 @@
1
+ module AudioStream
2
+ VERSION = "1.0.0"
3
+ end
metadata ADDED
@@ -0,0 +1,223 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: audio_stream
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Yoshida Tetsuya
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-07-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '12.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '12.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: ruby-audio
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.6.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.6.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: coreaudio
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.0.12
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.0.12
83
+ - !ruby/object:Gem::Dependency
84
+ name: ruby-fftw3
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 1.0.2
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 1.0.2
97
+ - !ruby/object:Gem::Dependency
98
+ name: rx
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.0.3
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.0.3
111
+ - !ruby/object:Gem::Dependency
112
+ name: rbplotly
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.1.2
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.1.2
125
+ description: ''
126
+ email:
127
+ - yoshida.eth0@gmail.com
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - ".gitignore"
133
+ - ".travis.yml"
134
+ - Gemfile
135
+ - LICENSE.txt
136
+ - README.md
137
+ - Rakefile
138
+ - audio_stream.gemspec
139
+ - bin/console
140
+ - bin/setup
141
+ - examples/adsr.ipynb
142
+ - examples/buffer.ipynb
143
+ - examples/chorus.rb
144
+ - examples/curves.ipynb
145
+ - examples/distortion.rb
146
+ - examples/example_options.rb
147
+ - examples/rec.rb
148
+ - examples/shapes.ipynb
149
+ - examples/sin.rb
150
+ - examples/tremolo.rb
151
+ - examples/tuner.rb
152
+ - lib/audio_stream.rb
153
+ - lib/audio_stream/audio_bus.rb
154
+ - lib/audio_stream/audio_input.rb
155
+ - lib/audio_stream/audio_input_buffer.rb
156
+ - lib/audio_stream/audio_input_device.rb
157
+ - lib/audio_stream/audio_input_file.rb
158
+ - lib/audio_stream/audio_input_metronome.rb
159
+ - lib/audio_stream/audio_input_sin.rb
160
+ - lib/audio_stream/audio_output.rb
161
+ - lib/audio_stream/audio_output_device.rb
162
+ - lib/audio_stream/audio_output_file.rb
163
+ - lib/audio_stream/buffer.rb
164
+ - lib/audio_stream/conductor.rb
165
+ - lib/audio_stream/core_ext.rb
166
+ - lib/audio_stream/error.rb
167
+ - lib/audio_stream/fx.rb
168
+ - lib/audio_stream/fx/a_gain.rb
169
+ - lib/audio_stream/fx/band_pass_filter.rb
170
+ - lib/audio_stream/fx/bang_process.rb
171
+ - lib/audio_stream/fx/biquad_filter.rb
172
+ - lib/audio_stream/fx/chorus.rb
173
+ - lib/audio_stream/fx/compressor.rb
174
+ - lib/audio_stream/fx/convolution_reverb.rb
175
+ - lib/audio_stream/fx/delay.rb
176
+ - lib/audio_stream/fx/distortion.rb
177
+ - lib/audio_stream/fx/equalizer_2band.rb
178
+ - lib/audio_stream/fx/equalizer_3band.rb
179
+ - lib/audio_stream/fx/hanning_window.rb
180
+ - lib/audio_stream/fx/high_pass_filter.rb
181
+ - lib/audio_stream/fx/high_shelf_filter.rb
182
+ - lib/audio_stream/fx/low_pass_filter.rb
183
+ - lib/audio_stream/fx/low_shelf_filter.rb
184
+ - lib/audio_stream/fx/mono_to_stereo.rb
185
+ - lib/audio_stream/fx/noise_gate.rb
186
+ - lib/audio_stream/fx/panning.rb
187
+ - lib/audio_stream/fx/peaking_filter.rb
188
+ - lib/audio_stream/fx/stereo_to_mono.rb
189
+ - lib/audio_stream/fx/tremolo.rb
190
+ - lib/audio_stream/fx/tuner.rb
191
+ - lib/audio_stream/plot.rb
192
+ - lib/audio_stream/ring_buffer.rb
193
+ - lib/audio_stream/sound_info.rb
194
+ - lib/audio_stream/sync.rb
195
+ - lib/audio_stream/utils.rb
196
+ - lib/audio_stream/version.rb
197
+ homepage: https://github.com/yoshida-eth0/ruby-audio_stream
198
+ licenses:
199
+ - MIT
200
+ metadata:
201
+ homepage_uri: https://github.com/yoshida-eth0/ruby-audio_stream
202
+ source_code_uri: https://github.com/yoshida-eth0/ruby-audio_stream
203
+ changelog_uri: https://github.com/yoshida-eth0/ruby-audio_stream
204
+ post_install_message:
205
+ rdoc_options: []
206
+ require_paths:
207
+ - lib
208
+ required_ruby_version: !ruby/object:Gem::Requirement
209
+ requirements:
210
+ - - ">="
211
+ - !ruby/object:Gem::Version
212
+ version: '0'
213
+ required_rubygems_version: !ruby/object:Gem::Requirement
214
+ requirements:
215
+ - - ">="
216
+ - !ruby/object:Gem::Version
217
+ version: '0'
218
+ requirements: []
219
+ rubygems_version: 3.0.4
220
+ signing_key:
221
+ specification_version: 4
222
+ summary: ''
223
+ test_files: []