Class: Wavify::DSP::Effects::EffectBase
- Inherits:
-
Object
- Object
- Wavify::DSP::Effects::EffectBase
- Defined in:
- lib/wavify/dsp/effects/effect_base.rb,
sig/effects.rbs
Overview
Base class for sample-by-sample effects with runtime channel state.
Direct Known Subclasses
AutoPan, Bitcrusher, Chorus, Compressor, Delay, Distortion, Expander, Flanger, Limiter, NoiseGate, Phaser, Reverb, SoftLimiter, Tremolo, Vibrato
Constant Summary collapse
- TAIL_CHUNK_FRAMES =
DSP::Processor::TAIL_CHUNK_FRAMES
Instance Method Summary collapse
-
#apply(buffer) ⇒ Wavify::Core::SampleBuffer
Applies the effect to a sample buffer.
-
#build_runtime ⇒ EffectBase
Builds an independent runtime instance for offline rendering.
-
#flush(format: nil) ⇒ Enumerator<Wavify::Core::SampleBuffer>?
Emits effect tail after input has ended.
-
#latency ⇒ Float
Processing latency in seconds.
-
#lookahead ⇒ Float
Lookahead duration in seconds.
- #process(buffer) ⇒ Core::SampleBuffer
- #process_sample(_sample, channel:, sample_rate:) ⇒ Numeric
-
#reset ⇒ EffectBase
Resets runtime state and cached channel/sample-rate information.
-
#tail_duration ⇒ Float
Tail duration in seconds emitted by #flush.
Instance Method Details
#apply(buffer) ⇒ Wavify::Core::SampleBuffer
Applies the effect to a sample buffer.
14 15 16 |
# File 'lib/wavify/dsp/effects/effect_base.rb', line 14 def apply(buffer) DSP::Processor.render(self, buffer) end |
#build_runtime ⇒ EffectBase
Builds an independent runtime instance for offline rendering.
103 104 105 |
# File 'lib/wavify/dsp/effects/effect_base.rb', line 103 def build_runtime dup.reset end |
#flush(format: nil) ⇒ Enumerator<Wavify::Core::SampleBuffer>?
Emits effect tail after input has ended.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/wavify/dsp/effects/effect_base.rb', line 42 def flush(format: nil) return nil unless runtime_prepared? frames = tail_frame_count return nil if frames.zero? target_format = format || Core::Format.new( channels: @runtime_channels, sample_rate: @runtime_sample_rate, bit_depth: 32, sample_format: :float ) runtime_format = Core::Format.new( channels: @runtime_channels, sample_rate: @runtime_sample_rate, bit_depth: 32, sample_format: :float ) Enumerator.new do |yielder| remaining = frames while remaining.positive? chunk_frames = [remaining, TAIL_CHUNK_FRAMES].min silence = Core::SampleBuffer.new(Array.new(chunk_frames * @runtime_channels, 0.0), runtime_format) yielder << process(silence).convert(target_format) remaining -= chunk_frames end ensure reset end end |
#latency ⇒ Float
Returns processing latency in seconds.
79 80 81 |
# File 'lib/wavify/dsp/effects/effect_base.rb', line 79 def latency 0.0 end |
#lookahead ⇒ Float
Returns lookahead duration in seconds.
84 85 86 |
# File 'lib/wavify/dsp/effects/effect_base.rb', line 84 def lookahead 0.0 end |
#process(buffer) ⇒ Core::SampleBuffer
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/wavify/dsp/effects/effect_base.rb', line 18 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) prepare_runtime_if_needed!( sample_rate: float_format.sample_rate, channels: float_buffer.format.channels ) output = Array.new(float_buffer.samples.length) float_buffer.samples.each_with_index do |sample, sample_index| channel = sample_index % @runtime_channels output[sample_index] = process_sample(sample, channel: channel, sample_rate: @runtime_sample_rate) end Core::SampleBuffer.new(output, float_format).convert(buffer.format) end |
#process_sample(_sample, channel:, sample_rate:) ⇒ Numeric
88 89 90 |
# File 'lib/wavify/dsp/effects/effect_base.rb', line 88 def process_sample(_sample, channel:, sample_rate:) raise NotImplementedError end |
#reset ⇒ EffectBase
Resets runtime state and cached channel/sample-rate information.
95 96 97 98 99 100 |
# File 'lib/wavify/dsp/effects/effect_base.rb', line 95 def reset @runtime_sample_rate = nil @runtime_channels = nil reset_runtime_state self end |
#tail_duration ⇒ Float
Returns tail duration in seconds emitted by #flush.
74 75 76 |
# File 'lib/wavify/dsp/effects/effect_base.rb', line 74 def tail_duration 0.0 end |