synth_blocks 1.0.0 → 1.0.1

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.
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