Class: Deftones::Effects::FrequencyShifter
Constant Summary
collapse
- DEFAULT_KERNEL_SIZE =
31
Instance Attribute Summary collapse
Attributes inherited from Core::Effect
#wet
Class Method Summary
collapse
Instance Method Summary
collapse
#multichannel_process?, #normalize_channel_output, #process, #process_effect
Constructor Details
#initialize(frequency: 30.0, context: Deftones.context, **options) ⇒ FrequencyShifter
Returns a new instance of FrequencyShifter.
10
11
12
13
14
15
16
17
|
# File 'lib/deftones/effect/frequency_shifter.rb', line 10
def initialize(frequency: 30.0, context: Deftones.context, **options)
super(context: context, **options)
@frequency = frequency.to_f
@phase = 0.0
@kernel = self.class.send(:hilbert_kernel, DEFAULT_KERNEL_SIZE)
@delay = (@kernel.length / 2.0).floor
@histories = []
end
|
Instance Attribute Details
#frequency ⇒ Object
Returns the value of attribute frequency.
8
9
10
|
# File 'lib/deftones/effect/frequency_shifter.rb', line 8
def frequency
@frequency
end
|
Class Method Details
.hilbert_kernel(size) ⇒ Object
74
75
76
77
78
79
80
81
82
83
84
85
86
|
# File 'lib/deftones/effect/frequency_shifter.rb', line 74
def self.hilbert_kernel(size)
raise ArgumentError, "kernel size must be odd" if size.even?
center = size / 2
Array.new(size) do |index|
offset = index - center
next 0.0 if offset.zero? || offset.even?
coefficient = 2.0 / (Math::PI * offset)
window = 0.54 - (0.46 * Math.cos((2.0 * Math::PI * index) / (size - 1)))
coefficient * window
end
end
|
Instance Method Details
#advance_phase ⇒ Object
59
60
61
|
# File 'lib/deftones/effect/frequency_shifter.rb', line 59
def advance_phase
@phase = (@phase + (shift_frequency / context.sample_rate)) % 1.0
end
|
#analytic_components(sample, channel_index) ⇒ Object
37
38
39
40
41
42
43
44
45
46
|
# File 'lib/deftones/effect/frequency_shifter.rb', line 37
def analytic_components(sample, channel_index)
history = @histories[channel_index]
history.unshift(sample)
history.pop
delayed = history[@delay] || 0.0
quadrature = @kernel.each_with_index.sum(0.0) do |coefficient, index|
coefficient * (history[index] || 0.0)
end
[delayed, quadrature]
end
|
#ensure_histories(channels) ⇒ Object
67
68
69
70
71
72
|
# File 'lib/deftones/effect/frequency_shifter.rb', line 67
def ensure_histories(channels)
required = [channels.to_i, 1].max
while @histories.length < required
@histories << Array.new(@kernel.length, 0.0)
end
end
|
#process_effect_block(input_block, num_frames, _start_frame, _cache) ⇒ Object
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
# File 'lib/deftones/effect/frequency_shifter.rb', line 21
def process_effect_block(input_block, num_frames, _start_frame, _cache)
ensure_histories(input_block.channels)
output = Array.new(input_block.channels) { Array.new(num_frames, 0.0) }
num_frames.times do |index|
phase = @phase
input_block.channel_data.each_with_index do |channel, channel_index|
analytic = analytic_components(channel[index], channel_index)
output[channel_index][index] = shift_analytic_signal(*analytic, phase)
end
advance_phase
end
Core::AudioBlock.from_channel_data(output)
end
|
#shift_analytic_signal(in_phase, quadrature, phase) ⇒ Object
48
49
50
51
52
53
54
55
56
57
|
# File 'lib/deftones/effect/frequency_shifter.rb', line 48
def shift_analytic_signal(in_phase, quadrature, phase)
radians = 2.0 * Math::PI * phase
cosine = Math.cos(radians)
sine = Math.sin(radians)
if @frequency.negative?
(in_phase * cosine) + (quadrature * sine)
else
(in_phase * cosine) - (quadrature * sine)
end
end
|
#shift_frequency ⇒ Object
63
64
65
|
# File 'lib/deftones/effect/frequency_shifter.rb', line 63
def shift_frequency
@frequency.abs
end
|