Class: Wavify::DSP::Effects::EffectChain
- Inherits:
-
Object
- Object
- Wavify::DSP::Effects::EffectChain
- Defined in:
- lib/wavify/dsp/effects/effect_chain.rb,
sig/effects.rbs
Overview
Processor that applies a fixed list of effects in sequence.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#effects ⇒ Array[untyped]
readonly
Returns the value of attribute effects.
Instance Method Summary collapse
-
#apply(buffer) ⇒ Core::SampleBuffer
Applies every effect using its offline entrypoint when available.
-
#build_runtime ⇒ EffectChain
Builds a chain whose processors do not share runtime state.
-
#flush(format: nil) ⇒ Enumerator[Core::SampleBuffer, nil]
Flushes effect tails through every downstream processor.
-
#initialize(effects) ⇒ EffectChain
constructor
A new instance of EffectChain.
- #latency ⇒ Float
- #lookahead ⇒ Float
- #process(buffer) ⇒ Wavify::Core::SampleBuffer
-
#reset ⇒ EffectChain
Self.
- #tail_duration ⇒ Float
Constructor Details
#initialize(effects) ⇒ EffectChain
Returns a new instance of EffectChain.
11 12 13 14 15 |
# File 'lib/wavify/dsp/effects/effect_chain.rb', line 11 def initialize(effects) raise InvalidParameterError, "effects must be an Array" unless effects.is_a?(Array) @effects = effects.map { |effect| validate_effect!(effect) }.freeze end |
Instance Attribute Details
#effects ⇒ Array[untyped] (readonly)
Returns the value of attribute effects.
8 9 10 |
# File 'lib/wavify/dsp/effects/effect_chain.rb', line 8 def effects @effects end |
Instance Method Details
#apply(buffer) ⇒ Core::SampleBuffer
Applies every effect using its offline entrypoint when available.
29 30 31 32 33 |
# File 'lib/wavify/dsp/effects/effect_chain.rb', line 29 def apply(buffer) raise InvalidParameterError, "buffer must be Core::SampleBuffer" unless buffer.is_a?(Core::SampleBuffer) DSP::Processor.render(self, buffer) end |
#build_runtime ⇒ EffectChain
Builds a chain whose processors do not share runtime state.
58 59 60 61 62 63 |
# File 'lib/wavify/dsp/effects/effect_chain.rb', line 58 def build_runtime runtime_effects = @effects.map { |effect| DSP::Processor.build_runtime(effect) } runtime = dup runtime.instance_variable_set(:@effects, runtime_effects.freeze) runtime.reset end |
#flush(format: nil) ⇒ Enumerator[Core::SampleBuffer, nil]
Flushes effect tails through every downstream processor.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/wavify/dsp/effects/effect_chain.rb', line 36 def flush(format: nil) Enumerator.new do |yielder| @effects.each_with_index do |effect, index| DSP::Processor.flush(effect, format: format).each do |tail| next unless tail.sample_frame_count.positive? processed = @effects.drop(index + 1).reduce(tail) do |current, downstream| process_effect(downstream, current) end yielder << processed end end end end |
#latency ⇒ Float
66 67 68 |
# File 'lib/wavify/dsp/effects/effect_chain.rb', line 66 def latency @effects.sum { |effect| DSP::Processor.duration(effect, :latency) } end |
#lookahead ⇒ Float
71 72 73 |
# File 'lib/wavify/dsp/effects/effect_chain.rb', line 71 def lookahead @effects.sum { |effect| DSP::Processor.duration(effect, :lookahead) } end |
#process(buffer) ⇒ Wavify::Core::SampleBuffer
19 20 21 22 23 24 25 26 |
# File 'lib/wavify/dsp/effects/effect_chain.rb', line 19 def process(buffer) raise InvalidParameterError, "buffer must be Core::SampleBuffer" unless buffer.is_a?(Core::SampleBuffer) original_format = buffer.format float_format = original_format.with(sample_format: :float, bit_depth: 32) processed = @effects.reduce(buffer.convert(float_format)) { |current, effect| process_effect(effect, current) } processed.convert(original_format) end |
#reset ⇒ EffectChain
Returns self.
52 53 54 55 |
# File 'lib/wavify/dsp/effects/effect_chain.rb', line 52 def reset @effects.each { |effect| effect.reset if effect.respond_to?(:reset) } self end |