Class: Wavify::DSP::Effects::Reverb
- Inherits:
-
EffectBase
- Object
- EffectBase
- Wavify::DSP::Effects::Reverb
- Defined in:
- lib/wavify/dsp/effects/reverb.rb,
sig/effects.rbs
Overview
Lightweight Schroeder-style reverb effect.
Constant Summary collapse
- COMB_TAPS_44K =
:nodoc:
[1116, 1188, 1277, 1356].freeze
- ALLPASS_TAPS_44K =
:nodoc:
[556, 441].freeze
Constants inherited from EffectBase
Instance Method Summary collapse
-
#initialize(room_size: 0.5, damping: 0.5, mix: 0.3, pre_delay: 0.0, width: 1.0) ⇒ Reverb
constructor
A new instance of Reverb.
-
#process(buffer) ⇒ Wavify::Core::SampleBuffer
Processes a sample buffer.
-
#process_sample(sample, channel:, sample_rate:) ⇒ Float
Processes a single sample for one channel.
-
#tail_duration ⇒ Float
Estimated reverb tail duration in seconds.
Methods inherited from EffectBase
#apply, #build_runtime, #flush, #latency, #lookahead, #reset
Constructor Details
#initialize(room_size: 0.5, damping: 0.5, mix: 0.3, pre_delay: 0.0, width: 1.0) ⇒ Reverb
Returns a new instance of Reverb.
11 12 13 14 15 16 17 18 19 |
# File 'lib/wavify/dsp/effects/reverb.rb', line 11 def initialize(room_size: 0.5, damping: 0.5, mix: 0.3, pre_delay: 0.0, width: 1.0) super() @room_size = validate_unit!(room_size, :room_size) @damping = validate_unit!(damping, :damping) @mix = validate_unit!(mix, :mix) @pre_delay = validate_time!(pre_delay, :pre_delay) @width = validate_width!(width) reset end |
Instance Method Details
#process(buffer) ⇒ Wavify::Core::SampleBuffer
Processes a sample buffer.
Stereo buffers apply width: to the wet signal before mixing it with
the dry input. Mono and multichannel buffers keep per-channel wet paths.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/wavify/dsp/effects/reverb.rb', line 28 def process(buffer) raise InvalidParameterError, "buffer must be Core::SampleBuffer" unless buffer.is_a?(Core::SampleBuffer) float_format = buffer.format.with(sample_format: :float, bit_depth: 32) float_buffer = buffer.convert(float_format) channels = float_buffer.format.channels prepare_runtime_if_needed!(sample_rate: float_format.sample_rate, channels: channels) output = Array.new(float_buffer.samples.length) float_buffer.samples.each_slice(channels).with_index do |frame, frame_index| wet_frame = frame.each_with_index.map do |sample, channel| wet_sample_for(@channels_state.fetch(channel), sample.to_f) end wet_frame = apply_stereo_width(wet_frame) if channels == 2 base = frame_index * channels frame.each_with_index do |dry, channel| output[base + channel] = mix_dry_wet(dry.to_f, wet_frame.fetch(channel)) end end Core::SampleBuffer.new(output, float_format).convert(buffer.format) end |
#process_sample(sample, channel:, sample_rate:) ⇒ Float
Processes a single sample for one channel.
58 59 60 61 62 |
# File 'lib/wavify/dsp/effects/reverb.rb', line 58 def process_sample(sample, channel:, sample_rate:) dry = sample.to_f channel_state = @channels_state.fetch(channel) mix_dry_wet(dry, wet_sample_for(channel_state, dry)) end |
#tail_duration ⇒ Float
Returns estimated reverb tail duration in seconds.
65 66 67 68 69 |
# File 'lib/wavify/dsp/effects/reverb.rb', line 65 def tail_duration return 0.0 if @mix.zero? @pre_delay + 0.25 + (@room_size * 2.5) end |