synth_blocks 1.0.0 → 1.0.1

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: 482e3c24341fafb72b3f095bf688799a37a26e6559835c149b8b7db0670cd2f2
4
- data.tar.gz: 28046f996d3b9b7f7fc9ecdf183253f37257339ccf9ba37cd4f1361d74e2f1df
3
+ metadata.gz: d9e4c687fc841d59a5e910589e7cd8d584ad84bc6079ef508a02969afb547690
4
+ data.tar.gz: 7f3e2170fb0559f07b151784b16e835f032d10ab397b49ebc7477d5026aef3c4
5
5
  SHA512:
6
- metadata.gz: 2d5684ff0b78c0705a8625a3fd863f67988eb11d96a025d308e0f4f3a8999c2ed5cd2927dea6ec9503db44c812ea4717488a46d482e54ca3f61d9ede35ed44cd
7
- data.tar.gz: 871e845e0ecd1eb1e6b4a7ec82ac92971b841c99646eb004651276a4f42087b6905942902f5265a84968973d3edf2405ee93343b5397afe6f39e2fc17ddb0ef5
6
+ metadata.gz: a0a01ec77eb1d4b51ad402f82f3566e2ca9f79d37eb13eb27d5c9702f077c8c1da06b079afe248d1c710025285ac2db24a0d33e4dd6d43674b58f6a68c1682d5
7
+ data.tar.gz: fe8407848935beac13adb2f90a01a38762ebd0692d2f1265f1e24ff7813d0534c030ed58756ae81e092d8a3165cbbf7c82784608defda93bcaef3bfc16b3ed50
data/README.md CHANGED
@@ -19,6 +19,17 @@ The code is super unoptimised, as it is written for learning purposes. This mean
19
19
  takes a couple of hours to render. I'm relatively sure that there are some low hanging fruits for optimisation, especially in the sequencer code that does a lot of
20
20
  useless lookups on quite large data structures that hold the automation data, but I haven't yet gotten around to take a look at it.
21
21
 
22
+ ## Opal
23
+
24
+ Since my presentation runs in a browser I thought it could be fun to try to make this library run in Opal and thus in the browser.
25
+
26
+ It works but obviously long running code that will block the main thread is not something that makes browsers (and users) happy, but for small demonstrations, it's probably good enough.
27
+
28
+ There are two modules that do not work:
29
+
30
+ - GVerb uses prime numbers but Opal does not implement Stdlib::Prime.
31
+ - To prevent adding WaveFile as an additional dependency (and because it doesn't make a ton of sense for my usecase), WaveWriter is not functional in Opal.
32
+
22
33
  ## Examples
23
34
 
24
35
  The easiest way to test the example code is to check out the repo and then execute the code directly.
@@ -1,24 +1,35 @@
1
- require 'synth_blocks/core/sound'
2
- require 'synth_blocks/mod/adsr'
3
- require 'synth_blocks/fx/chorus'
4
- require 'synth_blocks/fx/compressor'
5
- require 'synth_blocks/fx/delay'
6
- require 'synth_blocks/mod/envelope'
7
- require 'synth_blocks/fx/eq'
8
- require 'synth_blocks/fx/g_verb'
9
- require 'synth_blocks/drum/hihat'
10
- require 'synth_blocks/drum/kick_drum'
11
- require 'synth_blocks/drum/tuned_drum'
12
- require 'synth_blocks/mixer/mixer_channel'
13
- require 'synth_blocks/synth/monosynth'
14
- require 'synth_blocks/core/moog_filter'
15
- require 'synth_blocks/core/oscillator'
16
- require 'synth_blocks/synth/polysynth'
17
- require 'synth_blocks/mixer/send_channel'
18
- require 'synth_blocks/sequencer/sequencer_dsl'
19
- require 'synth_blocks/drum/snare_drum'
20
- require 'synth_blocks/core/state_variable_filter'
21
- require 'synth_blocks/utils'
22
- require 'synth_blocks/fx/waveshaper'
23
- require 'synth_blocks/fx/limiter'
24
- require 'synth_blocks/core/wave_writer'
1
+ require_relative 'synth_blocks/core/sound'
2
+ require_relative 'synth_blocks/mod/adsr'
3
+ require_relative 'synth_blocks/fx/chorus'
4
+ require_relative 'synth_blocks/fx/compressor'
5
+ require_relative 'synth_blocks/fx/delay'
6
+ require_relative 'synth_blocks/mod/envelope'
7
+ require_relative 'synth_blocks/fx/eq'
8
+ require_relative 'synth_blocks/fx/g_verb'
9
+ require_relative 'synth_blocks/drum/hihat'
10
+ require_relative 'synth_blocks/drum/kick_drum'
11
+ require_relative 'synth_blocks/drum/tuned_drum'
12
+ require_relative 'synth_blocks/mixer/mixer_channel'
13
+ require_relative 'synth_blocks/synth/monosynth'
14
+ require_relative 'synth_blocks/core/moog_filter'
15
+ require_relative 'synth_blocks/core/oscillator'
16
+ require_relative 'synth_blocks/synth/polysynth'
17
+ require_relative 'synth_blocks/mixer/send_channel'
18
+ require_relative 'synth_blocks/sequencer/sequencer_dsl'
19
+ require_relative 'synth_blocks/drum/snare_drum'
20
+ require_relative 'synth_blocks/core/state_variable_filter'
21
+ require_relative 'synth_blocks/utils'
22
+ require_relative 'synth_blocks/fx/waveshaper'
23
+ require_relative 'synth_blocks/fx/limiter'
24
+ require_relative 'synth_blocks/core/wave_writer'
25
+
26
+ unless RUBY_ENGINE == 'opal'
27
+ # Now if we are NOT running inside of opal, set things up so opal can find
28
+ # the files. The whole thing is rescued in case the opal gem is not available.
29
+ # This would happen if the gem is being used server side ONLY.
30
+ begin
31
+ require 'opal'
32
+ Opal.append_path File.expand_path('..', __FILE__).untaint
33
+ rescue LoadError
34
+ end
35
+ end
@@ -1,26 +1,33 @@
1
- require 'wavefile'
2
-
3
1
  module SynthBlocks
4
2
  module Core
5
3
  ##
6
4
  # Writes Floating point data to a wavefile using the wave file gem
7
- class WaveWriter
8
- ##
9
- # Static method to write to file given as first argument IF given
10
- def self.write_if_name_given(samples)
11
- if (ARGV[0])
12
- WaveWriter.new(ARGV[0]).write(samples)
5
+ if RUBY_ENGINE == 'opal'
6
+ class WaveWriter
7
+ def self.write_if_name_given(samples)
8
+ raise "Not Implemented in OPAL"
13
9
  end
14
10
  end
11
+ else
12
+ require 'wavefile'
13
+ class WaveWriter
14
+ ##
15
+ # Static method to write to file given as first argument IF given
16
+ def self.write_if_name_given(samples)
17
+ if (ARGV[0])
18
+ WaveWriter.new(ARGV[0]).write(samples)
19
+ end
20
+ end
15
21
 
16
- def initialize(filename)
17
- @filename = filename
18
- end
22
+ def initialize(filename)
23
+ @filename = filename
24
+ end
19
25
 
20
- def write(float_data)
21
- buffer = WaveFile::Buffer.new(float_data, WaveFile::Format.new(:mono, :float, 44100))
22
- WaveFile::Writer.new(@filename, WaveFile::Format.new(:mono, :pcm_16, 44100)) do |writer|
23
- writer.write(buffer)
26
+ def write(float_data)
27
+ buffer = WaveFile::Buffer.new(float_data, WaveFile::Format.new(:mono, :float, 44100))
28
+ WaveFile::Writer.new(@filename, WaveFile::Format.new(:mono, :pcm_16, 44100)) do |writer|
29
+ writer.write(buffer)
30
+ end
24
31
  end
25
32
  end
26
33
  end
@@ -21,254 +21,265 @@ module SynthBlocks
21
21
  # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
22
  #
23
23
 
24
- require 'prime'
25
-
26
- class FixedDelay # :nodoc:
27
- def initialize(size)
28
- @size = size
29
- @buf = Array.new(size)
30
- @idx = 0
31
- @buf = @buf.map { |e| 0.0 }
32
- end
33
-
34
- def read(n)
35
- i = (@idx - n + @size) % @size;
36
- @buf[i]
37
- end
38
-
39
- def write(x)
40
- @buf[@idx] = x
41
- @idx = (@idx + 1) % @size
42
- end
43
- end
24
+ if RUBY_ENGINE != 'opal'
44
25
 
45
- class Damper # :nodoc:
46
- def initialize(damping)
47
- @damping = damping
48
- @delay = 0.0
49
- end
26
+ require 'prime'
50
27
 
51
- def run(x)
52
- y = x * (1.0-@damping) + @delay * @damping;
53
- @delay = y
54
- y
55
- end
56
- end
28
+ class FixedDelay # :nodoc:
29
+ def initialize(size)
30
+ @size = size
31
+ @buf = Array.new(size)
32
+ @idx = 0
33
+ @buf = @buf.map { |e| 0.0 }
34
+ end
57
35
 
58
- class Diffuser # :nodoc:
59
- def initialize(size, coeff)
60
- @size = size.floor
61
- @coeff = coeff
62
- @idx = 0
63
- @buf = Array.new(@size)
64
- @buf = @buf.map { |e| 0.0 }
65
- end
36
+ def read(n)
37
+ i = (@idx - n + @size) % @size;
38
+ @buf[i]
39
+ end
66
40
 
67
- def run(x)
68
- w = x - @buf[@idx] * @coeff;
69
- y = @buf[@idx] + w * @coeff;
70
- @buf[@idx] = w
71
- @idx = (@idx + 1) % @size;
72
- y
41
+ def write(x)
42
+ @buf[@idx] = x
43
+ @idx = (@idx + 1) % @size
44
+ end
73
45
  end
74
- end
75
- ##
76
- # GVerb is a relatively simple reverb implementation
77
- class GVerb
78
- FDNORDER = 4 # :nodoc:
79
46
 
80
-
81
- ##
82
- # Create new GVerb instance
83
- #
84
- # max_room_size is the maximum room size you'll use
85
- #
86
- # room_size is the current room size
87
- #
88
- def initialize(srate, max_room_size: 120.0, room_size: 50.0, rev_time: 2.0, damping: 0.3, spread: 15.0, input_bandwidth: 1.5, early_level: 0.8, tail_level: 0.5, mix: 0.2)
89
- @rate = srate
90
- @damping = damping
91
- @max_room_size = max_room_size
92
- @room_size = room_size
93
- @rev_time = rev_time
94
- @early_level = early_level
95
- @tail_level = tail_level
96
- @mix = mix
97
- @max_delay = @rate * @max_room_size / 340.0
98
- @largest_delay = @rate * @room_size / 340.0
99
- @input_bandwidth = input_bandwidth;
100
- @input_damper = Damper.new(1.0 - @input_bandwidth)
101
-
102
-
103
- @fdndels = FDNORDER.times.map do |i|
104
- FixedDelay.new(@max_delay + 1000)
47
+ class Damper # :nodoc:
48
+ def initialize(damping)
49
+ @damping = damping
50
+ @delay = 0.0
105
51
  end
106
- @fdngains = Array.new(FDNORDER)
107
- @fdnlens = Array.new(FDNORDER)
108
52
 
109
- @fdndamps = FDNORDER.times.map do |i|
110
- Damper.new(@damping)
53
+ def run(x)
54
+ y = x * (1.0-@damping) + @delay * @damping;
55
+ @delay = y
56
+ y
111
57
  end
58
+ end
112
59
 
113
- ga = 60.0;
114
- gt = @rev_time;
115
- ga = 10.0 ** (-ga / 20.0)
116
- n = @rate * gt
117
- @alpha = ga ** (1.0 / n)
118
- gb = 0.0;
119
- FDNORDER.times do |i|
120
- gb = 1.000000*@largest_delay if (i == 0)
121
- gb = 0.816490*@largest_delay if (i == 1)
122
- gb = 0.707100*@largest_delay if (i == 2)
123
- gb = 0.632450*@largest_delay if (i == 3)
124
-
125
- @fdnlens[i] = nearest_prime(gb, 0.5);
126
- @fdnlens[i] = gb.round;
127
- @fdngains[i] = -(@alpha ** @fdnlens[i])
60
+ class Diffuser # :nodoc:
61
+ def initialize(size, coeff)
62
+ @size = size.floor
63
+ @coeff = coeff
64
+ @idx = 0
65
+ @buf = Array.new(@size)
66
+ @buf = @buf.map { |e| 0.0 }
128
67
  end
129
68
 
130
- @d = Array.new(FDNORDER)
131
- @u = Array.new(FDNORDER)
132
- @f = Array.new(FDNORDER)
133
-
134
- # DIFFUSER SECTION
135
-
136
- diffscale = @fdnlens[3].to_f/(210+159+562+410);
137
- spread1 = spread.to_f
138
- spread2 = 3.0*spread
139
-
140
- b = 210
141
- r = 0.125541
142
- a = spread1*r
143
- c = 210+159+a
144
- cc = c-b
145
- r = 0.854046
146
- a = spread2*r
147
- d = 210+159+562+a
148
- dd = d-c
149
- e = 1341-d
150
-
151
- @ldifs = [
152
- Diffuser.new((diffscale*b),0.75),
153
- Diffuser.new((diffscale*cc),0.75),
154
- Diffuser.new((diffscale*dd),0.625),
155
- Diffuser.new((diffscale*e),0.625)
156
- ]
157
-
158
- b = 210
159
- r = -0.568366
160
- a = spread1*r
161
- c = 210+159+a
162
- cc = c-b
163
- r = -0.126815;
164
- a = spread2*r
165
- d = 210+159+562+a
166
- dd = d-c
167
- e = 1341-d
168
-
169
- @rdifs = [
170
- Diffuser.new((diffscale*b),0.75),
171
- Diffuser.new((diffscale*cc),0.75),
172
- Diffuser.new((diffscale*dd),0.625),
173
- Diffuser.new((diffscale*e),0.625)
174
- ]
175
-
176
-
177
- # Tapped delay section */
178
-
179
- @tapdelay = FixedDelay.new(44000)
180
- @taps = Array.new(FDNORDER)
181
- @tapgains = Array.new(FDNORDER)
182
-
183
- @taps[0] = 5+0.410*@largest_delay
184
- @taps[1] = 5+0.300*@largest_delay
185
- @taps[2] = 5+0.155*@largest_delay
186
- @taps[3] = 5+0.000*@largest_delay
187
-
188
- FDNORDER.times do |i|
189
- @tapgains[i] = @alpha ** @taps[i]
69
+ def run(x)
70
+ w = x - @buf[@idx] * @coeff;
71
+ y = @buf[@idx] + w * @coeff;
72
+ @buf[@idx] = w
73
+ @idx = (@idx + 1) % @size;
74
+ y
190
75
  end
191
76
  end
192
-
193
-
194
77
  ##
195
- # runs a value through the reverb, returns the reverberated signal
196
- # mixed with the original.
197
- def run(x)
198
- if x.nan? || x.abs > 100000.0
199
- x = 0.0
78
+ # GVerb is a relatively simple reverb implementation
79
+ class GVerb
80
+ FDNORDER = 4 # :nodoc:
81
+
82
+
83
+ ##
84
+ # Create new GVerb instance
85
+ #
86
+ # max_room_size is the maximum room size you'll use
87
+ #
88
+ # room_size is the current room size
89
+ #
90
+ def initialize(srate, max_room_size: 120.0, room_size: 50.0, rev_time: 2.0, damping: 0.3, spread: 15.0, input_bandwidth: 1.5, early_level: 0.8, tail_level: 0.5, mix: 0.2)
91
+ @rate = srate
92
+ @damping = damping
93
+ @max_room_size = max_room_size
94
+ @room_size = room_size
95
+ @rev_time = rev_time
96
+ @early_level = early_level
97
+ @tail_level = tail_level
98
+ @mix = mix
99
+ @max_delay = @rate * @max_room_size / 340.0
100
+ @largest_delay = @rate * @room_size / 340.0
101
+ @input_bandwidth = input_bandwidth;
102
+ @input_damper = Damper.new(1.0 - @input_bandwidth)
103
+
104
+
105
+ @fdndels = FDNORDER.times.map do |i|
106
+ FixedDelay.new(@max_delay + 1000)
107
+ end
108
+ @fdngains = Array.new(FDNORDER)
109
+ @fdnlens = Array.new(FDNORDER)
110
+
111
+ @fdndamps = FDNORDER.times.map do |i|
112
+ Damper.new(@damping)
113
+ end
114
+
115
+ ga = 60.0;
116
+ gt = @rev_time;
117
+ ga = 10.0 ** (-ga / 20.0)
118
+ n = @rate * gt
119
+ @alpha = ga ** (1.0 / n)
120
+ gb = 0.0;
121
+ FDNORDER.times do |i|
122
+ gb = 1.000000*@largest_delay if (i == 0)
123
+ gb = 0.816490*@largest_delay if (i == 1)
124
+ gb = 0.707100*@largest_delay if (i == 2)
125
+ gb = 0.632450*@largest_delay if (i == 3)
126
+
127
+ @fdnlens[i] = nearest_prime(gb, 0.5);
128
+ @fdnlens[i] = gb.round;
129
+ @fdngains[i] = -(@alpha ** @fdnlens[i])
130
+ end
131
+
132
+ @d = Array.new(FDNORDER)
133
+ @u = Array.new(FDNORDER)
134
+ @f = Array.new(FDNORDER)
135
+
136
+ # DIFFUSER SECTION
137
+
138
+ diffscale = @fdnlens[3].to_f/(210+159+562+410);
139
+ spread1 = spread.to_f
140
+ spread2 = 3.0*spread
141
+
142
+ b = 210
143
+ r = 0.125541
144
+ a = spread1*r
145
+ c = 210+159+a
146
+ cc = c-b
147
+ r = 0.854046
148
+ a = spread2*r
149
+ d = 210+159+562+a
150
+ dd = d-c
151
+ e = 1341-d
152
+
153
+ @ldifs = [
154
+ Diffuser.new((diffscale*b),0.75),
155
+ Diffuser.new((diffscale*cc),0.75),
156
+ Diffuser.new((diffscale*dd),0.625),
157
+ Diffuser.new((diffscale*e),0.625)
158
+ ]
159
+
160
+ b = 210
161
+ r = -0.568366
162
+ a = spread1*r
163
+ c = 210+159+a
164
+ cc = c-b
165
+ r = -0.126815;
166
+ a = spread2*r
167
+ d = 210+159+562+a
168
+ dd = d-c
169
+ e = 1341-d
170
+
171
+ @rdifs = [
172
+ Diffuser.new((diffscale*b),0.75),
173
+ Diffuser.new((diffscale*cc),0.75),
174
+ Diffuser.new((diffscale*dd),0.625),
175
+ Diffuser.new((diffscale*e),0.625)
176
+ ]
177
+
178
+
179
+ # Tapped delay section */
180
+
181
+ @tapdelay = FixedDelay.new(44000)
182
+ @taps = Array.new(FDNORDER)
183
+ @tapgains = Array.new(FDNORDER)
184
+
185
+ @taps[0] = 5+0.410*@largest_delay
186
+ @taps[1] = 5+0.300*@largest_delay
187
+ @taps[2] = 5+0.155*@largest_delay
188
+ @taps[3] = 5+0.000*@largest_delay
189
+
190
+ FDNORDER.times do |i|
191
+ @tapgains[i] = @alpha ** @taps[i]
192
+ end
200
193
  end
201
194
 
202
- z = @input_damper.run(x)
203
- z = @ldifs[0].run(z)
204
- FDNORDER.times do |i|
205
- @u[i] = @tapgains[i] * @tapdelay.read(@taps[i])
206
- end
207
195
 
208
- @tapdelay.write(z)
196
+ ##
197
+ # runs a value through the reverb, returns the reverberated signal
198
+ # mixed with the original.
199
+ def run(x)
200
+ if x.nan? || x.abs > 100000.0
201
+ x = 0.0
202
+ end
209
203
 
210
- FDNORDER.times do |i|
211
- @d[i] = @fdndamps[i].run(@fdngains[i] * @fdndels[i].read(@fdnlens[i]))
212
- end
204
+ z = @input_damper.run(x)
205
+ z = @ldifs[0].run(z)
206
+ FDNORDER.times do |i|
207
+ @u[i] = @tapgains[i] * @tapdelay.read(@taps[i])
208
+ end
213
209
 
214
- sum = 0.0
215
- sign = 1.0
216
- FDNORDER.times do |i|
217
- sum += sign * (@tail_level * @d[i] + @early_level * @u[i])
218
- sign = -sign
219
- end
210
+ @tapdelay.write(z)
220
211
 
221
- sum += x* @early_level
212
+ FDNORDER.times do |i|
213
+ @d[i] = @fdndamps[i].run(@fdngains[i] * @fdndels[i].read(@fdnlens[i]))
214
+ end
222
215
 
223
- lsum = sum
224
- # rsum = sum
216
+ sum = 0.0
217
+ sign = 1.0
218
+ FDNORDER.times do |i|
219
+ sum += sign * (@tail_level * @d[i] + @early_level * @u[i])
220
+ sign = -sign
221
+ end
225
222
 
226
- @f = fdn_matrix(@d)
223
+ sum += x* @early_level
227
224
 
228
- FDNORDER.times do |i|
229
- @fdndels[i].write(@u[i] + @f[i])
230
- end
225
+ lsum = sum
226
+ # rsum = sum
231
227
 
232
- lsum = @ldifs[1].run(lsum)
233
- lsum = @ldifs[2].run(lsum)
234
- lsum = @ldifs[3].run(lsum)
228
+ @f = fdn_matrix(@d)
235
229
 
236
- # rsum = @rdifs[1].run(rsum)
237
- # rsum = @rdifs[2].run(rsum)
238
- # rsum = @rdifs[3].run(rsum)
230
+ FDNORDER.times do |i|
231
+ @fdndels[i].write(@u[i] + @f[i])
232
+ end
239
233
 
240
- lsum = x * (1.0 - @mix) + lsum * @mix
241
- # rsum = x * (1.0 - mix) + rsum * mix
242
- return lsum
243
- end
234
+ lsum = @ldifs[1].run(lsum)
235
+ lsum = @ldifs[2].run(lsum)
236
+ lsum = @ldifs[3].run(lsum)
244
237
 
238
+ # rsum = @rdifs[1].run(rsum)
239
+ # rsum = @rdifs[2].run(rsum)
240
+ # rsum = @rdifs[3].run(rsum)
241
+
242
+ lsum = x * (1.0 - @mix) + lsum * @mix
243
+ # rsum = x * (1.0 - mix) + rsum * mix
244
+ return lsum
245
+ end
245
246
 
246
- private
247
247
 
248
- def nearest_prime(n_f, rerror)
249
- n = n_f.to_i
250
- return n if Prime.prime?(n)
251
- # assume n is large enough and n*rerror enough smaller than n */
252
- bound = n*rerror;
253
- 1.upto(bound) do |k|
254
- return n+k if Prime.prime?(n+k)
255
- return n-k if Prime.prime?(n-k)
248
+ private
249
+
250
+ def nearest_prime(n_f, rerror)
251
+ n = n_f.to_i
252
+ return n if Prime.prime?(n)
253
+ # assume n is large enough and n*rerror enough smaller than n */
254
+ bound = n*rerror;
255
+ 1.upto(bound) do |k|
256
+ return n+k if Prime.prime?(n+k)
257
+ return n-k if Prime.prime?(n-k)
258
+ end
259
+ return -1
256
260
  end
257
- return -1
258
- end
259
261
 
260
- def fdn_matrix(a)
261
- b = Array.new(FDNORDER)
262
- dl0 = a[0]
263
- dl1 = a[1]
264
- dl2 = a[2]
265
- dl3 = a[3]
266
-
267
- b[0] = 0.5*(dl0 + dl1 - dl2 - dl3);
268
- b[1] = 0.5*(dl0 - dl1 - dl2 + dl3);
269
- b[2] = 0.5*(-dl0 + dl1 - dl2 + dl3);
270
- b[3] = 0.5*(dl0 + dl1 + dl2 + dl3);
271
- b
262
+ def fdn_matrix(a)
263
+ b = Array.new(FDNORDER)
264
+ dl0 = a[0]
265
+ dl1 = a[1]
266
+ dl2 = a[2]
267
+ dl3 = a[3]
268
+
269
+ b[0] = 0.5*(dl0 + dl1 - dl2 - dl3);
270
+ b[1] = 0.5*(dl0 - dl1 - dl2 + dl3);
271
+ b[2] = 0.5*(-dl0 + dl1 - dl2 + dl3);
272
+ b[3] = 0.5*(dl0 + dl1 + dl2 + dl3);
273
+ b
274
+ end
275
+ end
276
+ else
277
+ class GVerb
278
+ def initialize(srate, max_room_size: 120.0, room_size: 50.0, rev_time: 2.0, damping: 0.3, spread: 15.0, input_bandwidth: 1.5, early_level: 0.8, tail_level: 0.5, mix: 0.2)
279
+ end
280
+ def run(x)
281
+ x
282
+ end
272
283
  end
273
284
  end
274
285
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: synth_blocks
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Krutisch