Class: Deftones::Effects::BitCrusher

Inherits:
Core::Effect show all
Includes:
Oversampling
Defined in:
lib/deftones/effect/bit_crusher.rb

Constant Summary

Constants included from Oversampling

Oversampling::OVERSAMPLE_FACTORS

Instance Attribute Summary collapse

Attributes included from Oversampling

#oversample

Attributes inherited from Core::Effect

#wet

Instance Method Summary collapse

Methods included from Oversampling

#ensure_oversample_state, #process_oversampled

Methods inherited from Core::Effect

#multichannel_process?, #normalize_channel_output, #process, #process_effect_block

Constructor Details

#initialize(bits: 8, downsample: 2, oversample: 1, **options) ⇒ BitCrusher

Returns a new instance of BitCrusher.



10
11
12
13
14
15
16
17
# File 'lib/deftones/effect/bit_crusher.rb', line 10

def initialize(bits: 8, downsample: 2, oversample: 1, **options)
  super(**options)
  @bits = bits.to_i
  @downsample = [downsample.to_i, 1].max
  self.oversample = oversample
  @hold_counters = []
  @held_samples = []
end

Instance Attribute Details

#bitsObject

Returns the value of attribute bits.



8
9
10
# File 'lib/deftones/effect/bit_crusher.rb', line 8

def bits
  @bits
end

#downsampleObject

Returns the value of attribute downsample.



8
9
10
# File 'lib/deftones/effect/bit_crusher.rb', line 8

def downsample
  @downsample
end

Instance Method Details

#ensure_state(channel_index) ⇒ Object (private)



39
40
41
42
43
# File 'lib/deftones/effect/bit_crusher.rb', line 39

def ensure_state(channel_index)
  required = [channel_index.to_i, 0].max
  @hold_counters.fill(0, @hold_counters.length..required)
  @held_samples.fill(0.0, @held_samples.length..required)
end

#process_effect(input_buffer, _num_frames, _start_frame, _cache, channel_index: 0) ⇒ Object (private)



21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/deftones/effect/bit_crusher.rb', line 21

def process_effect(input_buffer, _num_frames, _start_frame, _cache, channel_index: 0)
  step = 2.0 / (2**@bits)
  ensure_state(channel_index)

  input_buffer.map do |sample|
    if (@hold_counters[channel_index] % @downsample).zero?
      @held_samples[channel_index] =
        process_oversampled([sample], channel_index) { |candidate| quantize(candidate, step) }.first
    end
    @hold_counters[channel_index] += 1
    @held_samples[channel_index]
  end
end

#quantize(sample, step) ⇒ Object (private)



35
36
37
# File 'lib/deftones/effect/bit_crusher.rb', line 35

def quantize(sample, step)
  ((sample / step).round * step).clamp(-1.0, 1.0)
end