deftones 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.yardopts +5 -0
- data/CHANGELOG.md +12 -0
- data/LICENSE.txt +21 -0
- data/README.md +197 -0
- data/Rakefile +8 -0
- data/examples/poly_chord.rb +14 -0
- data/examples/render_sampler.rb +16 -0
- data/examples/render_sequence.rb +13 -0
- data/examples/render_synth.rb +18 -0
- data/lib/deftones/analysis/analyser.rb +162 -0
- data/lib/deftones/analysis/dc_meter.rb +56 -0
- data/lib/deftones/analysis/fft.rb +128 -0
- data/lib/deftones/analysis/meter.rb +83 -0
- data/lib/deftones/analysis/waveform.rb +93 -0
- data/lib/deftones/component/amplitude_envelope.rb +8 -0
- data/lib/deftones/component/biquad_filter.rb +7 -0
- data/lib/deftones/component/channel.rb +109 -0
- data/lib/deftones/component/compressor.rb +64 -0
- data/lib/deftones/component/convolver.rb +99 -0
- data/lib/deftones/component/cross_fade.rb +67 -0
- data/lib/deftones/component/envelope.rb +160 -0
- data/lib/deftones/component/eq3.rb +73 -0
- data/lib/deftones/component/feedback_comb_filter.rb +75 -0
- data/lib/deftones/component/filter.rb +75 -0
- data/lib/deftones/component/follower.rb +55 -0
- data/lib/deftones/component/frequency_envelope.rb +24 -0
- data/lib/deftones/component/gate.rb +46 -0
- data/lib/deftones/component/lfo.rb +88 -0
- data/lib/deftones/component/limiter.rb +11 -0
- data/lib/deftones/component/lowpass_comb_filter.rb +43 -0
- data/lib/deftones/component/merge.rb +45 -0
- data/lib/deftones/component/mid_side_compressor.rb +43 -0
- data/lib/deftones/component/mid_side_merge.rb +53 -0
- data/lib/deftones/component/mid_side_split.rb +54 -0
- data/lib/deftones/component/mono.rb +8 -0
- data/lib/deftones/component/multiband_compressor.rb +70 -0
- data/lib/deftones/component/multiband_split.rb +133 -0
- data/lib/deftones/component/one_pole_filter.rb +71 -0
- data/lib/deftones/component/pan_vol.rb +26 -0
- data/lib/deftones/component/panner.rb +75 -0
- data/lib/deftones/component/panner3d.rb +322 -0
- data/lib/deftones/component/solo.rb +56 -0
- data/lib/deftones/component/split.rb +47 -0
- data/lib/deftones/component/volume.rb +31 -0
- data/lib/deftones/context.rb +213 -0
- data/lib/deftones/core/audio_block.rb +82 -0
- data/lib/deftones/core/audio_node.rb +262 -0
- data/lib/deftones/core/clock.rb +91 -0
- data/lib/deftones/core/computed_signal.rb +69 -0
- data/lib/deftones/core/delay.rb +44 -0
- data/lib/deftones/core/effect.rb +66 -0
- data/lib/deftones/core/emitter.rb +51 -0
- data/lib/deftones/core/gain.rb +39 -0
- data/lib/deftones/core/instrument.rb +109 -0
- data/lib/deftones/core/param.rb +31 -0
- data/lib/deftones/core/signal.rb +452 -0
- data/lib/deftones/core/signal_operator_methods.rb +73 -0
- data/lib/deftones/core/signal_operators.rb +138 -0
- data/lib/deftones/core/signal_shapers.rb +83 -0
- data/lib/deftones/core/source.rb +213 -0
- data/lib/deftones/core/synced_signal.rb +88 -0
- data/lib/deftones/destination.rb +132 -0
- data/lib/deftones/draw.rb +100 -0
- data/lib/deftones/dsp/biquad.rb +129 -0
- data/lib/deftones/dsp/delay_line.rb +41 -0
- data/lib/deftones/dsp/helpers.rb +25 -0
- data/lib/deftones/effect/auto_filter.rb +92 -0
- data/lib/deftones/effect/auto_panner.rb +57 -0
- data/lib/deftones/effect/auto_wah.rb +98 -0
- data/lib/deftones/effect/bit_crusher.rb +38 -0
- data/lib/deftones/effect/chebyshev.rb +36 -0
- data/lib/deftones/effect/chorus.rb +73 -0
- data/lib/deftones/effect/distortion.rb +22 -0
- data/lib/deftones/effect/feedback_delay.rb +38 -0
- data/lib/deftones/effect/freeverb.rb +11 -0
- data/lib/deftones/effect/frequency_shifter.rb +89 -0
- data/lib/deftones/effect/jc_reverb.rb +11 -0
- data/lib/deftones/effect/modulation_control.rb +159 -0
- data/lib/deftones/effect/phaser.rb +72 -0
- data/lib/deftones/effect/ping_pong_delay.rb +40 -0
- data/lib/deftones/effect/pitch_shift.rb +156 -0
- data/lib/deftones/effect/reverb.rb +71 -0
- data/lib/deftones/effect/stereo_widener.rb +34 -0
- data/lib/deftones/effect/tremolo.rb +52 -0
- data/lib/deftones/effect/vibrato.rb +47 -0
- data/lib/deftones/event/callback_behavior.rb +61 -0
- data/lib/deftones/event/loop.rb +53 -0
- data/lib/deftones/event/part.rb +51 -0
- data/lib/deftones/event/pattern.rb +94 -0
- data/lib/deftones/event/sequence.rb +87 -0
- data/lib/deftones/event/tone_event.rb +77 -0
- data/lib/deftones/event/transport.rb +276 -0
- data/lib/deftones/instrument/am_synth.rb +56 -0
- data/lib/deftones/instrument/duo_synth.rb +68 -0
- data/lib/deftones/instrument/fm_synth.rb +60 -0
- data/lib/deftones/instrument/membrane_synth.rb +60 -0
- data/lib/deftones/instrument/metal_synth.rb +61 -0
- data/lib/deftones/instrument/mono_synth.rb +88 -0
- data/lib/deftones/instrument/noise_synth.rb +56 -0
- data/lib/deftones/instrument/pluck_synth.rb +41 -0
- data/lib/deftones/instrument/poly_synth.rb +96 -0
- data/lib/deftones/instrument/sampler.rb +97 -0
- data/lib/deftones/instrument/synth.rb +60 -0
- data/lib/deftones/io/buffer.rb +352 -0
- data/lib/deftones/io/buffers.rb +77 -0
- data/lib/deftones/io/recorder.rb +89 -0
- data/lib/deftones/listener.rb +120 -0
- data/lib/deftones/music/frequency.rb +128 -0
- data/lib/deftones/music/midi.rb +206 -0
- data/lib/deftones/music/note.rb +58 -0
- data/lib/deftones/music/ticks.rb +106 -0
- data/lib/deftones/music/time.rb +209 -0
- data/lib/deftones/music/transport_time.rb +94 -0
- data/lib/deftones/music/unit_helpers.rb +30 -0
- data/lib/deftones/offline_context.rb +46 -0
- data/lib/deftones/portaudio_support.rb +112 -0
- data/lib/deftones/source/am_oscillator.rb +42 -0
- data/lib/deftones/source/fat_oscillator.rb +49 -0
- data/lib/deftones/source/fm_oscillator.rb +47 -0
- data/lib/deftones/source/grain_player.rb +198 -0
- data/lib/deftones/source/karplus_strong.rb +51 -0
- data/lib/deftones/source/noise.rb +99 -0
- data/lib/deftones/source/omni_oscillator.rb +175 -0
- data/lib/deftones/source/oscillator.rb +74 -0
- data/lib/deftones/source/player.rb +228 -0
- data/lib/deftones/source/players.rb +133 -0
- data/lib/deftones/source/pulse_oscillator.rb +38 -0
- data/lib/deftones/source/pwm_oscillator.rb +49 -0
- data/lib/deftones/source/tone_buffer_source.rb +136 -0
- data/lib/deftones/source/tone_oscillator_node.rb +65 -0
- data/lib/deftones/source/user_media.rb +519 -0
- data/lib/deftones/version.rb +5 -0
- data/lib/deftones.rb +542 -0
- metadata +221 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Deftones
|
|
4
|
+
module Core
|
|
5
|
+
class Instrument < AudioNode
|
|
6
|
+
class VolumeProxy
|
|
7
|
+
attr_reader :instrument
|
|
8
|
+
attr_accessor :value
|
|
9
|
+
|
|
10
|
+
def initialize(instrument, value: 0.0)
|
|
11
|
+
@instrument = instrument
|
|
12
|
+
@value = value.to_f
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def value=(new_value)
|
|
16
|
+
@value = new_value.to_f
|
|
17
|
+
instrument.apply_volume!
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def ramp_to(target_value, _duration = nil)
|
|
21
|
+
self.value = target_value
|
|
22
|
+
self
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
alias linear_ramp_to ramp_to
|
|
26
|
+
alias exponential_ramp_to ramp_to
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
attr_reader :output, :volume
|
|
30
|
+
attr_accessor :mute
|
|
31
|
+
|
|
32
|
+
def initialize(context: Deftones.context)
|
|
33
|
+
super(context: context)
|
|
34
|
+
@output = Gain.new(context: context, gain: 1.0)
|
|
35
|
+
@volume = VolumeProxy.new(self)
|
|
36
|
+
@mute = false
|
|
37
|
+
apply_volume!
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def input
|
|
41
|
+
@output
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def render(num_frames, start_frame = 0, cache = {})
|
|
45
|
+
@output.render(num_frames, start_frame, cache)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def render_block(num_frames, start_frame = 0, cache = {})
|
|
49
|
+
@output.send(:render_block, num_frames, start_frame, cache)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def mute=(value)
|
|
53
|
+
@mute = !!value
|
|
54
|
+
apply_volume!
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def mute?
|
|
58
|
+
@mute
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def set(**params)
|
|
62
|
+
params.each do |key, value|
|
|
63
|
+
writer = :"#{key}="
|
|
64
|
+
public_send(writer, value) if respond_to?(writer)
|
|
65
|
+
end
|
|
66
|
+
self
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def get(*keys)
|
|
70
|
+
requested = keys.flatten
|
|
71
|
+
requested.each_with_object({}) do |key, values|
|
|
72
|
+
reader = key.to_sym
|
|
73
|
+
values[reader] = public_send(reader) if respond_to?(reader)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def release_all(time = nil)
|
|
78
|
+
trigger_release(time) if respond_to?(:trigger_release)
|
|
79
|
+
self
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def dispose
|
|
83
|
+
@output.dispose
|
|
84
|
+
super
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def triggerAttack(*arguments)
|
|
88
|
+
trigger_attack(*arguments)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def triggerRelease(*arguments)
|
|
92
|
+
trigger_release(*arguments)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def triggerAttackRelease(*arguments)
|
|
96
|
+
trigger_attack_release(*arguments)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def releaseAll(time = nil)
|
|
100
|
+
release_all(time)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def apply_volume!
|
|
104
|
+
@output.gain.value = mute ? 0.0 : Deftones.db_to_gain(@volume.value)
|
|
105
|
+
self
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Deftones
|
|
4
|
+
module Core
|
|
5
|
+
class Param < Signal
|
|
6
|
+
attr_reader :lfo
|
|
7
|
+
|
|
8
|
+
def initialize(**options)
|
|
9
|
+
super
|
|
10
|
+
@lfo = nil
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def set_param(param)
|
|
14
|
+
@param = param
|
|
15
|
+
self
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def connect(destination, output_index: 0, input_index: 0)
|
|
19
|
+
super
|
|
20
|
+
@param = destination if destination.respond_to?(:value=)
|
|
21
|
+
self
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def lfo=(source)
|
|
25
|
+
@lfo = source
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
alias setParam set_param
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Deftones
|
|
4
|
+
module Core
|
|
5
|
+
class Signal
|
|
6
|
+
EXPONENTIAL_UNITS = %i[frequency decibels].freeze
|
|
7
|
+
|
|
8
|
+
include SignalOperatorMethods
|
|
9
|
+
|
|
10
|
+
attr_reader :context, :units, :input, :output, :default_value
|
|
11
|
+
attr_accessor :min_value, :max_value, :convert_values
|
|
12
|
+
|
|
13
|
+
def initialize(value: 0.0, units: :number, context: Deftones.context)
|
|
14
|
+
@context = context
|
|
15
|
+
@units = units
|
|
16
|
+
@input = self
|
|
17
|
+
@output = self
|
|
18
|
+
@convert_values = true
|
|
19
|
+
@base_value = coerce_value(value)
|
|
20
|
+
@default_value = @base_value
|
|
21
|
+
@min_value = -Float::INFINITY
|
|
22
|
+
@max_value = Float::INFINITY
|
|
23
|
+
@events = []
|
|
24
|
+
@disposed = false
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def value
|
|
28
|
+
@base_value
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def value=(new_value)
|
|
32
|
+
@base_value = coerce_value(new_value)
|
|
33
|
+
@events.clear
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def apply(value)
|
|
37
|
+
self.value = value.respond_to?(:value_of) ? value.value_of : value
|
|
38
|
+
self
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def ramp_to(target_value, duration)
|
|
42
|
+
if EXPONENTIAL_UNITS.include?(@units)
|
|
43
|
+
exponential_ramp_to(target_value, duration)
|
|
44
|
+
else
|
|
45
|
+
linear_ramp_to(target_value, duration)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def linear_ramp_to(target_value, duration)
|
|
50
|
+
resolved_end = context.current_time + Deftones::Music::Time.parse(duration)
|
|
51
|
+
schedule_automation(
|
|
52
|
+
:linear,
|
|
53
|
+
coerce_value(target_value),
|
|
54
|
+
start_time: resolve_automation_start_time(resolved_end),
|
|
55
|
+
end_time: resolved_end
|
|
56
|
+
)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def linear_ramp_to_value_at_time(target_value, end_time)
|
|
60
|
+
resolved_end = resolve_time(end_time)
|
|
61
|
+
schedule_automation(
|
|
62
|
+
:linear,
|
|
63
|
+
coerce_value(target_value),
|
|
64
|
+
start_time: resolve_automation_start_time(resolved_end),
|
|
65
|
+
end_time: resolved_end
|
|
66
|
+
)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def exponential_ramp_to(target_value, duration)
|
|
70
|
+
resolved_end = context.current_time + Deftones::Music::Time.parse(duration)
|
|
71
|
+
schedule_automation(
|
|
72
|
+
:exponential,
|
|
73
|
+
coerce_value(target_value),
|
|
74
|
+
start_time: resolve_automation_start_time(resolved_end),
|
|
75
|
+
end_time: resolved_end
|
|
76
|
+
)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def exponential_ramp_to_value_at_time(target_value, end_time)
|
|
80
|
+
resolved_end = resolve_time(end_time)
|
|
81
|
+
schedule_automation(
|
|
82
|
+
:exponential,
|
|
83
|
+
coerce_value(target_value),
|
|
84
|
+
start_time: resolve_automation_start_time(resolved_end),
|
|
85
|
+
end_time: resolved_end
|
|
86
|
+
)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def set_value_at_time(target_value, time)
|
|
90
|
+
@events << { type: :set, time: resolve_time(time), value: coerce_value(target_value) }
|
|
91
|
+
sort_events!
|
|
92
|
+
self
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def set_value_curve_at_time(values, start_time, duration)
|
|
96
|
+
curve = Array(values).map { |value| coerce_value(value) }
|
|
97
|
+
resolved_start = resolve_time(start_time)
|
|
98
|
+
resolved_duration = Deftones::Music::Time.parse(duration)
|
|
99
|
+
@events << {
|
|
100
|
+
type: :curve,
|
|
101
|
+
time: resolved_start,
|
|
102
|
+
start_time: resolved_start,
|
|
103
|
+
end_time: resolved_start + resolved_duration,
|
|
104
|
+
duration: resolved_duration,
|
|
105
|
+
values: curve
|
|
106
|
+
}
|
|
107
|
+
sort_events!
|
|
108
|
+
self
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def set_target_at_time(target_value, start_time, time_constant)
|
|
112
|
+
resolved_start = resolve_time(start_time)
|
|
113
|
+
@events << {
|
|
114
|
+
type: :target,
|
|
115
|
+
time: resolved_start,
|
|
116
|
+
start_time: resolved_start,
|
|
117
|
+
time_constant: [Deftones::Music::Time.parse(time_constant), 1.0e-6].max,
|
|
118
|
+
from: value_at(resolved_start),
|
|
119
|
+
to: coerce_value(target_value)
|
|
120
|
+
}
|
|
121
|
+
sort_events!
|
|
122
|
+
self
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def target_ramp_to(target_value, duration, start_time = context.current_time)
|
|
126
|
+
resolved_start = resolve_time(start_time)
|
|
127
|
+
resolved_duration = Deftones::Music::Time.parse(duration)
|
|
128
|
+
set_target_at_time(target_value, resolved_start, [resolved_duration / 5.0, 1.0e-6].max)
|
|
129
|
+
set_value_at_time(target_value, resolved_start + resolved_duration)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def cancel_scheduled_values(after_time = 0)
|
|
133
|
+
threshold = resolve_time(after_time)
|
|
134
|
+
@events.reject! do |event|
|
|
135
|
+
event.fetch(:time, event[:start_time]) >= threshold
|
|
136
|
+
end
|
|
137
|
+
self
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def cancel_and_hold_at_time(time)
|
|
141
|
+
held_time = resolve_time(time)
|
|
142
|
+
held_value = value_at(held_time)
|
|
143
|
+
cancel_scheduled_values(held_time)
|
|
144
|
+
set_value_at_time(held_value, held_time)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def set_ramp_point(time = context.current_time)
|
|
148
|
+
cancel_and_hold_at_time(time)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def get_value_at_time(time)
|
|
152
|
+
value_at(resolve_time(time))
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def dispose
|
|
156
|
+
@events.clear
|
|
157
|
+
@disposed = true
|
|
158
|
+
self
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def disposed?
|
|
162
|
+
@disposed
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
alias linearRampToValueAtTime linear_ramp_to_value_at_time
|
|
166
|
+
alias exponentialRampToValueAtTime exponential_ramp_to_value_at_time
|
|
167
|
+
alias setValueAtTime set_value_at_time
|
|
168
|
+
alias setValueCurveAtTime set_value_curve_at_time
|
|
169
|
+
alias setTargetAtTime set_target_at_time
|
|
170
|
+
alias targetRampTo target_ramp_to
|
|
171
|
+
alias cancelScheduledValues cancel_scheduled_values
|
|
172
|
+
alias cancelAndHoldAtTime cancel_and_hold_at_time
|
|
173
|
+
alias setRampPoint set_ramp_point
|
|
174
|
+
alias getValueAtTime get_value_at_time
|
|
175
|
+
|
|
176
|
+
def connect(destination, output_index: 0, input_index: 0)
|
|
177
|
+
_ = output_index
|
|
178
|
+
_ = input_index
|
|
179
|
+
return self if destination.nil?
|
|
180
|
+
|
|
181
|
+
if destination.respond_to?(:value=)
|
|
182
|
+
destination.value = value
|
|
183
|
+
elsif destination.respond_to?(:apply)
|
|
184
|
+
destination.apply(self)
|
|
185
|
+
end
|
|
186
|
+
self
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def disconnect(_destination = nil)
|
|
190
|
+
self
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def set(**params)
|
|
194
|
+
params.each do |key, entry|
|
|
195
|
+
writer = :"#{key}="
|
|
196
|
+
public_send(writer, entry) if respond_to?(writer)
|
|
197
|
+
end
|
|
198
|
+
self
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def get(*keys)
|
|
202
|
+
keys.flatten.each_with_object({}) do |key, values|
|
|
203
|
+
reader = key.to_sym
|
|
204
|
+
values[reader] = public_send(reader) if respond_to?(reader)
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def get_defaults
|
|
209
|
+
{
|
|
210
|
+
value: default_value,
|
|
211
|
+
units: units
|
|
212
|
+
}
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def now
|
|
216
|
+
context.current_time
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def immediate
|
|
220
|
+
now
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def to_seconds(time = value)
|
|
224
|
+
Deftones::Music::Time.parse(time)
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def to_ticks(time = value)
|
|
228
|
+
Deftones.transport.seconds_to_ticks(to_seconds(time))
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def to_frequency(entry = value)
|
|
232
|
+
Deftones::Music::Frequency.parse(entry)
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def overridden?
|
|
236
|
+
false
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def name
|
|
240
|
+
self.class.name.split("::").last
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def to_s
|
|
244
|
+
name
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def exponential_approach_value_at_time(target_value, start_time, ramp_time)
|
|
248
|
+
target_ramp_to(target_value, ramp_time, start_time)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
alias minValue min_value
|
|
252
|
+
alias minValue= min_value=
|
|
253
|
+
alias maxValue max_value
|
|
254
|
+
alias maxValue= max_value=
|
|
255
|
+
alias defaultValue default_value
|
|
256
|
+
alias getDefaults get_defaults
|
|
257
|
+
alias toSeconds to_seconds
|
|
258
|
+
alias toTicks to_ticks
|
|
259
|
+
alias toFrequency to_frequency
|
|
260
|
+
alias toString to_s
|
|
261
|
+
alias exponentialApproachValueAtTime exponential_approach_value_at_time
|
|
262
|
+
|
|
263
|
+
def process(num_frames, start_frame = 0)
|
|
264
|
+
Array.new(num_frames) do |offset|
|
|
265
|
+
value_at(sample_time(start_frame + offset))
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def value_at(time)
|
|
270
|
+
current_value = @base_value
|
|
271
|
+
|
|
272
|
+
@events.each do |event|
|
|
273
|
+
case event[:type]
|
|
274
|
+
when :set
|
|
275
|
+
break if time < event[:time]
|
|
276
|
+
|
|
277
|
+
current_value = event[:value]
|
|
278
|
+
when :linear, :exponential
|
|
279
|
+
break if time < event[:start_time]
|
|
280
|
+
|
|
281
|
+
if time >= event[:end_time]
|
|
282
|
+
current_value = event[:to]
|
|
283
|
+
next
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
current_value = interpolate(event, (time - event[:start_time]) / event[:duration])
|
|
287
|
+
when :curve
|
|
288
|
+
break if time < event[:start_time]
|
|
289
|
+
|
|
290
|
+
if time >= event[:end_time]
|
|
291
|
+
current_value = event[:values].last || current_value
|
|
292
|
+
next
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
current_value = curve_value(event, time)
|
|
296
|
+
when :target
|
|
297
|
+
break if time < event[:start_time]
|
|
298
|
+
|
|
299
|
+
current_value = target_value(event, time)
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
current_value
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
private
|
|
307
|
+
|
|
308
|
+
def schedule_automation(type, target_value, start_time:, end_time:)
|
|
309
|
+
duration_in_seconds = [end_time.to_f - start_time.to_f, 0.0].max
|
|
310
|
+
@events << {
|
|
311
|
+
type: type,
|
|
312
|
+
start_time: start_time,
|
|
313
|
+
end_time: end_time,
|
|
314
|
+
time: start_time,
|
|
315
|
+
duration: duration_in_seconds,
|
|
316
|
+
from: value_at(start_time),
|
|
317
|
+
to: target_value
|
|
318
|
+
}
|
|
319
|
+
sort_events!
|
|
320
|
+
self
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
def sort_events!
|
|
324
|
+
@events.sort_by! { |event| event.fetch(:time, event[:start_time]) }
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
def resolve_automation_start_time(end_time)
|
|
328
|
+
anchors = @events.filter_map do |event|
|
|
329
|
+
anchor = automation_anchor_time(event)
|
|
330
|
+
anchor if anchor <= end_time
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
anchors.max || context.current_time
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
def automation_anchor_time(event)
|
|
337
|
+
case event[:type]
|
|
338
|
+
when :linear, :exponential, :curve
|
|
339
|
+
event[:end_time]
|
|
340
|
+
else
|
|
341
|
+
event.fetch(:time, event[:start_time])
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
def interpolate(event, progress)
|
|
346
|
+
return event[:to] if event[:duration].zero?
|
|
347
|
+
|
|
348
|
+
bounded_progress = progress.clamp(0.0, 1.0)
|
|
349
|
+
case event[:type]
|
|
350
|
+
when :linear
|
|
351
|
+
event[:from] + ((event[:to] - event[:from]) * bounded_progress)
|
|
352
|
+
when :exponential
|
|
353
|
+
from = safe_exponential_value(event[:from])
|
|
354
|
+
to = safe_exponential_value(event[:to])
|
|
355
|
+
from * ((to / from)**bounded_progress)
|
|
356
|
+
else
|
|
357
|
+
event[:to]
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
def curve_value(event, time)
|
|
362
|
+
values = event[:values]
|
|
363
|
+
return values.first if values.length <= 1
|
|
364
|
+
|
|
365
|
+
progress = ((time - event[:start_time]) / event[:duration]).clamp(0.0, 1.0)
|
|
366
|
+
scaled_index = progress * (values.length - 1)
|
|
367
|
+
lower_index = scaled_index.floor
|
|
368
|
+
upper_index = [lower_index + 1, values.length - 1].min
|
|
369
|
+
fraction = scaled_index - lower_index
|
|
370
|
+
lower = values[lower_index]
|
|
371
|
+
upper = values[upper_index]
|
|
372
|
+
lower + ((upper - lower) * fraction)
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
def target_value(event, time)
|
|
376
|
+
elapsed = [time - event[:start_time], 0.0].max
|
|
377
|
+
event[:to] + ((event[:from] - event[:to]) * Math.exp(-(elapsed / event[:time_constant])))
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
def safe_exponential_value(value)
|
|
381
|
+
magnitude = value.abs < 1.0e-6 ? 1.0e-6 : value.abs
|
|
382
|
+
value.negative? ? -magnitude : magnitude
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
def sample_time(frame_index)
|
|
386
|
+
frame_index.to_f / context.sample_rate
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
def resolve_time(time)
|
|
390
|
+
return context.current_time if time.nil?
|
|
391
|
+
|
|
392
|
+
Deftones::Music::Time.parse(time)
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
public
|
|
396
|
+
|
|
397
|
+
def convert
|
|
398
|
+
@convert_values
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
def convert=(value)
|
|
402
|
+
@convert_values = !!value
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
private
|
|
406
|
+
|
|
407
|
+
def coerce_value(value)
|
|
408
|
+
return convert_without_units(value) unless @convert_values
|
|
409
|
+
|
|
410
|
+
case @units
|
|
411
|
+
when :frequency
|
|
412
|
+
convert_frequency(value)
|
|
413
|
+
when :time
|
|
414
|
+
Deftones::Music::Time.parse(value)
|
|
415
|
+
when :decibels
|
|
416
|
+
db_to_gain(value.to_f)
|
|
417
|
+
else
|
|
418
|
+
convert_generic(value)
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
def convert_without_units(value)
|
|
423
|
+
return value.value_of if value.respond_to?(:value_of)
|
|
424
|
+
return value.to_f if value.is_a?(Numeric) || value.respond_to?(:to_f)
|
|
425
|
+
|
|
426
|
+
value
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
def convert_frequency(value)
|
|
430
|
+
return value.to_f if value.is_a?(Numeric)
|
|
431
|
+
|
|
432
|
+
string_value = value.to_s
|
|
433
|
+
return Regexp.last_match(1).to_f if string_value.match(/\A(\d+(?:\.\d+)?)hz\z/i)
|
|
434
|
+
|
|
435
|
+
Deftones::Music::Note.to_frequency(string_value)
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
def convert_generic(value)
|
|
439
|
+
string_value = value.to_s
|
|
440
|
+
if string_value.match?(/\A[A-Ga-g][#b]?-?\d+\z/)
|
|
441
|
+
Deftones::Music::Note.to_frequency(string_value)
|
|
442
|
+
else
|
|
443
|
+
value.to_f
|
|
444
|
+
end
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
def db_to_gain(value)
|
|
448
|
+
10.0**(value / 20.0)
|
|
449
|
+
end
|
|
450
|
+
end
|
|
451
|
+
end
|
|
452
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Deftones
|
|
4
|
+
module Core
|
|
5
|
+
module SignalOperatorMethods
|
|
6
|
+
def add(value)
|
|
7
|
+
Add.new(input: self, addend: value, context: context)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def subtract(value)
|
|
11
|
+
Subtract.new(input: self, subtrahend: value, context: context)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def multiply(value)
|
|
15
|
+
Multiply.new(input: self, factor: value, context: context)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def negate
|
|
19
|
+
Negate.new(input: self, context: context)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def abs
|
|
23
|
+
Abs.new(input: self, context: context)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def equal_power_gain
|
|
27
|
+
EqualPowerGain.new(input: self, context: context)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def greater_than(value)
|
|
31
|
+
GreaterThan.new(input: self, threshold: value, context: context)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def greater_than_zero
|
|
35
|
+
GreaterThanZero.new(input: self, context: context)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def modulo(value)
|
|
39
|
+
Modulo.new(input: self, modulus: value, context: context)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def normalize(min, max)
|
|
43
|
+
Normalize.new(input: self, min: min, max: max, context: context)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def scale(min, max)
|
|
47
|
+
Scale.new(input: self, min: min, max: max, context: context)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def scale_exp(min, max, exponent: 2.0)
|
|
51
|
+
ScaleExp.new(input: self, min: min, max: max, exponent: exponent, context: context)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def pow(exponent)
|
|
55
|
+
Pow.new(input: self, exponent: exponent, context: context)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def wave_shaper(curve = nil, mapping: nil, &block)
|
|
59
|
+
WaveShaper.new(input: self, curve: curve, mapping: mapping, context: context, &block)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
alias waveshaper wave_shaper
|
|
63
|
+
|
|
64
|
+
def to_audio
|
|
65
|
+
GainToAudio.new(input: self, context: context)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def to_gain
|
|
69
|
+
AudioToGain.new(input: self, context: context)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|