Class: Wavify::DSP::Effects::Delay

Inherits:
EffectBase show all
Defined in:
lib/wavify/dsp/effects/delay.rb,
sig/effects.rbs

Overview

Simple feedback delay effect.

Constant Summary collapse

NOTE_MULTIPLIERS =
{
  whole: 4.0,
  half: 2.0,
  quarter: 1.0,
  eighth: 0.5,
  sixteenth: 0.25,
  thirty_second: 0.125
}.freeze

Constants inherited from EffectBase

EffectBase::TAIL_CHUNK_FRAMES

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from EffectBase

#apply, #build_runtime, #flush, #latency, #lookahead, #process, #reset

Constructor Details

#initialize(time: 0.3, feedback: 0.5, mix: 0.3) ⇒ Delay

Returns a new instance of Delay.

Parameters:

  • time: (Numeric) (defaults to: 0.3)
  • feedback: (Numeric) (defaults to: 0.5)
  • mix: (Numeric) (defaults to: 0.3)
  • ping_pong: (Boolean)


36
37
38
39
40
41
42
# File 'lib/wavify/dsp/effects/delay.rb', line 36

def initialize(time: 0.3, feedback: 0.5, mix: 0.3)
  super()
  @time = validate_time!(time)
  @feedback = validate_ratio!(feedback, :feedback)
  @mix = validate_mix!(mix)
  reset
end

Class Method Details

.beat(note, tempo:, dotted: false, triplet: false, feedback: 0.5, mix: 0.3) ⇒ Delay

Builds a tempo-synced delay.

Parameters:

  • note (Symbol, String)

    note value such as :quarter or :eighth

  • tempo (Numeric)

    beats per minute

  • dotted (Boolean) (defaults to: false)

    multiply by 1.5

  • triplet (Boolean) (defaults to: false)

    multiply by 2/3

  • bpm (Numeric)
  • division: (Numeric)

Returns:

Raises:



24
25
26
27
28
29
30
31
32
33
34
# File 'lib/wavify/dsp/effects/delay.rb', line 24

def self.beat(note, tempo:, dotted: false, triplet: false, feedback: 0.5, mix: 0.3)
  multiplier = note_multiplier!(note)
  unless tempo.is_a?(Numeric) && tempo.respond_to?(:finite?) && tempo.finite? && tempo.positive?
    raise InvalidParameterError, "tempo must be a positive finite Numeric"
  end
  raise InvalidParameterError, "dotted and triplet cannot both be true" if dotted && triplet

  multiplier *= 1.5 if dotted
  multiplier *= (2.0 / 3.0) if triplet
  new(time: (60.0 / tempo.to_f) * multiplier, feedback: feedback, mix: mix)
end

Instance Method Details

#process_sample(sample, channel:, sample_rate:) ⇒ Float

Processes a single sample for one channel.

Parameters:

  • sample (Numeric)
  • channel (Integer)
  • sample_rate (Integer)

Returns:

  • (Float)


50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/wavify/dsp/effects/delay.rb', line 50

def process_sample(sample, channel:, sample_rate:)
  line = @delay_lines.fetch(channel)
  index = @write_indices.fetch(channel)
  delayed = line[index]
  dry = sample.to_f
  wet = delayed

  output = (dry * (1.0 - @mix)) + (wet * @mix)
  line[index] = dry + (wet * @feedback)
  @write_indices[channel] = (index + 1) % line.length

  output
end

#tail_durationFloat

Returns estimated feedback tail duration in seconds.

Returns:

  • (Float)

    estimated feedback tail duration in seconds



65
66
67
68
69
70
71
# File 'lib/wavify/dsp/effects/delay.rb', line 65

def tail_duration
  return 0.0 if @mix.zero?
  return @time if @feedback.zero?

  repeats = (Math.log(0.001) / Math.log(@feedback)).ceil
  @time * [[repeats, 1].max, 32].min
end