Class: Deftones::Effects::Reverb
- Inherits:
-
Core::Effect
- Object
- Core::Effect
- Deftones::Effects::Reverb
- Defined in:
- lib/deftones/effect/reverb.rb
Instance Attribute Summary collapse
-
#damping ⇒ Object
(also: #dampening)
Returns the value of attribute damping.
-
#decay ⇒ Object
Returns the value of attribute decay.
-
#freeze ⇒ Object
Returns the value of attribute freeze.
-
#pre_delay ⇒ Object
Returns the value of attribute pre_delay.
-
#wet_normalization ⇒ Object
(also: #wetNormalization)
Returns the value of attribute wet_normalization.
-
#width ⇒ Object
Returns the value of attribute width.
Attributes inherited from Core::Effect
Instance Method Summary collapse
- #apply_stereo_width(channel_data) ⇒ Object private
- #channel_times(times, channel_index, offset) ⇒ Object private
- #effective_decay ⇒ Object private
- #ensure_delay_network(channel_index) ⇒ Object private
-
#initialize(decay: 0.7, pre_delay: 0.01, damping: 0.0, freeze: false, wet_normalization: false, width: 1.0, context: Deftones.context, **options) ⇒ Reverb
constructor
A new instance of Reverb.
- #normalize_wet_sample(sample, feedback) ⇒ Object private
- #process_comb(line, delay_samples, input_sample, feedback, channel_index, comb_index) ⇒ Object private
- #process_effect(input_buffer, num_frames, _start_frame, _cache, channel_index: 0) ⇒ Object private
- #process_effect_block(input_block, num_frames, start_frame, cache) ⇒ Object private
Methods inherited from Core::Effect
#multichannel_process?, #normalize_channel_output, #process
Constructor Details
#initialize(decay: 0.7, pre_delay: 0.01, damping: 0.0, freeze: false, wet_normalization: false, width: 1.0, context: Deftones.context, **options) ⇒ Reverb
Returns a new instance of Reverb.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/deftones/effect/reverb.rb', line 9 def initialize(decay: 0.7, pre_delay: 0.01, damping: 0.0, freeze: false, wet_normalization: false, width: 1.0, context: Deftones.context, **) super(context: context, **) @decay = decay.to_f @pre_delay = pre_delay.to_f self.damping = damping self.freeze = freeze self.wet_normalization = wet_normalization self.width = width @comb_times = [0.0297, 0.0371, 0.0411, 0.0437] @allpass_times = [0.005, 0.0017] @comb_lines = [] @comb_damping_state = [] @allpass_lines = [] @pre_delay_lines = [] end |
Instance Attribute Details
#damping ⇒ Object Also known as: dampening
Returns the value of attribute damping.
7 8 9 |
# File 'lib/deftones/effect/reverb.rb', line 7 def damping @damping end |
#decay ⇒ Object
Returns the value of attribute decay.
6 7 8 |
# File 'lib/deftones/effect/reverb.rb', line 6 def decay @decay end |
#freeze ⇒ Object
Returns the value of attribute freeze.
7 8 9 |
# File 'lib/deftones/effect/reverb.rb', line 7 def freeze @freeze end |
#pre_delay ⇒ Object
Returns the value of attribute pre_delay.
6 7 8 |
# File 'lib/deftones/effect/reverb.rb', line 6 def pre_delay @pre_delay end |
#wet_normalization ⇒ Object Also known as: wetNormalization
Returns the value of attribute wet_normalization.
7 8 9 |
# File 'lib/deftones/effect/reverb.rb', line 7 def wet_normalization @wet_normalization end |
#width ⇒ Object
Returns the value of attribute width.
7 8 9 |
# File 'lib/deftones/effect/reverb.rb', line 7 def width @width end |
Instance Method Details
#apply_stereo_width(channel_data) ⇒ Object (private)
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/deftones/effect/reverb.rb', line 112 def apply_stereo_width(channel_data) return channel_data if channel_data.length < 2 || @width >= 1.0 left = channel_data[0] right = channel_data[1] widened_left = [] widened_right = [] left.each_index do |index| mid = (left[index] + right[index]) * 0.5 side = (left[index] - right[index]) * 0.5 * @width widened_left << (mid + side) widened_right << (mid - side) end [widened_left, widened_right] + channel_data.drop(2) end |
#channel_times(times, channel_index, offset) ⇒ Object (private)
106 107 108 109 110 |
# File 'lib/deftones/effect/reverb.rb', line 106 def channel_times(times, channel_index, offset) return times if channel_index.zero? times.map { |time| time + (offset * channel_index) } end |
#effective_decay ⇒ Object (private)
128 129 130 |
# File 'lib/deftones/effect/reverb.rb', line 128 def effective_decay @freeze ? 0.995 : @decay.to_f.clamp(0.0, 0.995) end |
#ensure_delay_network(channel_index) ⇒ Object (private)
96 97 98 99 100 101 102 103 104 |
# File 'lib/deftones/effect/reverb.rb', line 96 def ensure_delay_network(channel_index) required = [channel_index.to_i, 0].max while @pre_delay_lines.length <= required @pre_delay_lines << DSP::DelayLine.new((0.1 * context.sample_rate).ceil) @comb_lines << @comb_times.map { |seconds| DSP::DelayLine.new((seconds * context.sample_rate).ceil + 2) } @comb_damping_state << Array.new(@comb_times.length, 0.0) @allpass_lines << @allpass_times.map { |seconds| DSP::DelayLine.new((seconds * context.sample_rate).ceil + 2) } end end |
#normalize_wet_sample(sample, feedback) ⇒ Object (private)
132 133 134 135 136 |
# File 'lib/deftones/effect/reverb.rb', line 132 def normalize_wet_sample(sample, feedback) return sample unless @wet_normalization sample * (1.0 - ([feedback.abs, 0.95].min * 0.35)) end |
#process_comb(line, delay_samples, input_sample, feedback, channel_index, comb_index) ⇒ Object (private)
87 88 89 90 91 92 93 94 |
# File 'lib/deftones/effect/reverb.rb', line 87 def process_comb(line, delay_samples, input_sample, feedback, channel_index, comb_index) delayed_sample = line.read(delay_samples) previous = @comb_damping_state[channel_index][comb_index] filtered = DSP::Helpers.lerp(delayed_sample, previous, @damping) @comb_damping_state[channel_index][comb_index] = filtered line.write(input_sample + (filtered * feedback)) filtered end |
#process_effect(input_buffer, num_frames, _start_frame, _cache, channel_index: 0) ⇒ Object (private)
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/deftones/effect/reverb.rb', line 60 def process_effect(input_buffer, num_frames, _start_frame, _cache, channel_index: 0) ensure_delay_network(channel_index) pre_delay_line = @pre_delay_lines[channel_index] comb_lines = @comb_lines[channel_index] allpass_lines = @allpass_lines[channel_index] comb_times = channel_times(@comb_times, channel_index, 0.00037) allpass_times = channel_times(@allpass_times, channel_index, 0.00011) Array.new(num_frames) do |index| dry = input_buffer[index] delayed = pre_delay_line.tap(@pre_delay * context.sample_rate, input_sample: dry) feedback = effective_decay comb_input = @freeze ? 0.0 : delayed comb_sum = comb_lines.each_with_index.sum do |line, comb_index| process_comb(line, comb_times[comb_index] * context.sample_rate, comb_input, feedback, channel_index, comb_index) end / comb_lines.length.to_f wet_sample = allpass_lines.each_with_index.reduce(comb_sum) do |sample, (line, allpass_index)| tap = line.read(allpass_times[allpass_index] * context.sample_rate) line.write(sample + (tap * 0.5)) tap - (sample * 0.5) end normalize_wet_sample(wet_sample, feedback) end end |
#process_effect_block(input_block, num_frames, start_frame, cache) ⇒ Object (private)
49 50 51 52 53 54 55 56 57 58 |
# File 'lib/deftones/effect/reverb.rb', line 49 def process_effect_block(input_block, num_frames, start_frame, cache) output_channels = [input_block.channels, 2].max source = input_block.fit_channels(output_channels) Core::AudioBlock.from_channel_data( apply_stereo_width(source.channel_data.each_with_index.map do |channel, channel_index| process_effect(channel, num_frames, start_frame, cache, channel_index: channel_index) end) ) end |