Class: Deftones::Source::Oscillator
Constant Summary
collapse
- TYPES =
%i[sine square sawtooth triangle].freeze
- GENERATORS =
{
sine: ->(phase) { Math.sin(2.0 * Math::PI * phase) },
square: ->(phase) { phase < 0.5 ? 1.0 : -1.0 },
sawtooth: ->(phase) { (2.0 * phase) - 1.0 },
triangle: ->(phase) { (4.0 * (phase < 0.5 ? phase : 1.0 - phase)) - 1.0 }
}.freeze
Instance Attribute Summary collapse
Attributes inherited from Core::Source
#mute, #onstop, #volume
Class Method Summary
collapse
Instance Method Summary
collapse
#active_at?, #apply_volume!, #cancel_stop, #clear_transport_event, #dispose, #mute?, #notify_stop_in_window, #number_of_inputs, #render, #render_block, #resolve_time, #resolve_transport_time, #restart, #schedule_transport_event, #source_type, #start, #state, #stop, #sync, #synced?, #unsync, #uses_legacy_render_for_block?
Constructor Details
#initialize(type: :sine, frequency: 440.0, detune: 0.0, phase: 0.0, context: Deftones.context) ⇒ Oscillator
Returns a new instance of Oscillator.
79
80
81
82
83
84
85
|
# File 'lib/deftones/source/oscillator.rb', line 79
def initialize(type: :sine, frequency: 440.0, detune: 0.0, phase: 0.0, context: Deftones.context)
super(context: context)
self.type = type
@frequency = Core::Signal.new(value: frequency, units: :frequency, context: context)
@detune = Core::Signal.new(value: detune, units: :number, context: context)
self.phase = phase
end
|
Instance Attribute Details
#detune ⇒ Object
Returns the value of attribute detune.
77
78
79
|
# File 'lib/deftones/source/oscillator.rb', line 77
def detune
@detune
end
|
#frequency ⇒ Object
Returns the value of attribute frequency.
77
78
79
|
# File 'lib/deftones/source/oscillator.rb', line 77
def frequency
@frequency
end
|
#type ⇒ Object
Returns the value of attribute type.
77
78
79
|
# File 'lib/deftones/source/oscillator.rb', line 77
def type
@type
end
|
Class Method Details
.bandlimited_sawtooth(phase, phase_increment) ⇒ Object
37
38
39
|
# File 'lib/deftones/source/oscillator.rb', line 37
def bandlimited_sawtooth(phase, phase_increment)
((2.0 * phase) - 1.0) - poly_blep(phase, phase_increment)
end
|
.bandlimited_square(phase, phase_increment) ⇒ Object
30
31
32
33
34
35
|
# File 'lib/deftones/source/oscillator.rb', line 30
def bandlimited_square(phase, phase_increment)
sample = phase < 0.5 ? 1.0 : -1.0
sample += poly_blep(phase, phase_increment)
sample -= poly_blep((phase + 0.5) % 1.0, phase_increment)
sample
end
|
.bandlimited_triangle(phase, phase_increment) ⇒ Object
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
# File 'lib/deftones/source/oscillator.rb', line 41
def bandlimited_triangle(phase, phase_increment)
return naive_triangle(phase) unless phase_increment.positive?
max_harmonic = (0.5 / phase_increment.abs).floor
return naive_triangle(phase) if max_harmonic < 1
sum = 0.0
harmonic = 1
while harmonic <= max_harmonic
sum += Math.cos(2.0 * Math::PI * harmonic * phase) / (harmonic * harmonic)
harmonic += 2
end
-(8.0 / (Math::PI * Math::PI)) * sum
end
|
.naive_triangle(phase) ⇒ Object
56
57
58
|
# File 'lib/deftones/source/oscillator.rb', line 56
def naive_triangle(phase)
(4.0 * (phase < 0.5 ? phase : 1.0 - phase)) - 1.0
end
|
.poly_blep(phase, phase_increment) ⇒ Object
60
61
62
63
64
65
66
|
# File 'lib/deftones/source/oscillator.rb', line 60
def poly_blep(phase, phase_increment)
increment = [phase_increment.abs, 1.0e-9].max
return poly_blep_start(phase / increment) if phase < increment
return poly_blep_end((phase - 1.0) / increment) if phase > 1.0 - increment
0.0
end
|
.poly_blep_end(t) ⇒ Object
72
73
74
|
# File 'lib/deftones/source/oscillator.rb', line 72
def poly_blep_end(t)
(t * t) + (t + t) + 1.0
end
|
.poly_blep_start(t) ⇒ Object
68
69
70
|
# File 'lib/deftones/source/oscillator.rb', line 68
def poly_blep_start(t)
(t + t) - (t * t) - 1.0
end
|
.sample(type, phase, phase_increment = 0.0) ⇒ Object
15
16
17
18
19
20
21
22
23
24
25
26
|
# File 'lib/deftones/source/oscillator.rb', line 15
def sample(type, phase, phase_increment = 0.0)
case type
when :sine
Math.sin(2.0 * Math::PI * phase)
when :square
bandlimited_square(phase, phase_increment)
when :sawtooth
bandlimited_sawtooth(phase, phase_increment)
when :triangle
bandlimited_triangle(phase, phase_increment)
end
end
|
Instance Method Details
#detune_ratio(cents) ⇒ Object
126
127
128
|
# File 'lib/deftones/source/oscillator.rb', line 126
def detune_ratio(cents)
2.0**(cents.to_f / 1200.0)
end
|
#normalize_type(type) ⇒ Object
130
131
132
133
134
135
|
# File 'lib/deftones/source/oscillator.rb', line 130
def normalize_type(type)
normalized = type.to_sym
return normalized if TYPES.include?(normalized)
raise ArgumentError, "Unsupported oscillator type: #{type}"
end
|
#phase ⇒ Object
91
92
93
|
# File 'lib/deftones/source/oscillator.rb', line 91
def phase
@phase
end
|
#phase=(value) ⇒ Object
95
96
97
|
# File 'lib/deftones/source/oscillator.rb', line 95
def phase=(value)
@phase = value.to_f % 1.0
end
|
#process(_input_buffer, num_frames, start_frame, _cache) ⇒ Object
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
# File 'lib/deftones/source/oscillator.rb', line 103
def process(_input_buffer, num_frames, start_frame, _cache)
oscillator_type = normalize_type(@type)
frequencies = @frequency.process(num_frames, start_frame)
detunes = @detune.process(num_frames, start_frame)
Array.new(num_frames) do |index|
current_time = (start_frame + index).to_f / context.sample_rate
next 0.0 unless active_at?(current_time)
frequency = frequencies[index] * detune_ratio(detunes[index])
phase_increment = frequency / context.sample_rate
sample = sample_for(oscillator_type, @phase, phase_increment)
@phase = (@phase + phase_increment) % 1.0
sample
end
end
|
#sample_for(type, phase, phase_increment) ⇒ Object
122
123
124
|
# File 'lib/deftones/source/oscillator.rb', line 122
def sample_for(type, phase, phase_increment)
Oscillator.sample(type, phase, phase_increment)
end
|