Class: Deftones::Source::Player
Instance Attribute Summary collapse
Attributes inherited from Core::Source
#mute, #volume
Instance Method Summary
collapse
-
#dispose ⇒ Object
-
#envelope_gain(current_time) ⇒ Object
private
-
#fade_in_gain(current_time) ⇒ Object
private
-
#fade_out_gain(current_time) ⇒ Object
private
-
#fadeIn=(value) ⇒ Object
-
#fadeOut=(value) ⇒ Object
-
#initialize(buffer:, playback_rate: 1.0, loop: false, loop_start: 0.0, loop_end: nil, reverse: false, fade_in: 0.0, fade_out: 0.0, curve: :linear, autostart: false, onstop: nil, context: Deftones.context) ⇒ Player
constructor
A new instance of Player.
-
#integrated_position_at_frame(frame_index) ⇒ Object
private
-
#loaded ⇒ Object
-
#loaded? ⇒ Boolean
-
#loop_end_frame ⇒ Object
private
-
#looped_position(position) ⇒ Object
private
-
#looped_reverse_position(position, min_position, max_position) ⇒ Object
private
-
#loopEnd=(value) ⇒ Object
-
#loopStart=(value) ⇒ Object
-
#multichannel_process? ⇒ Boolean
private
-
#notify_stop(current_time) ⇒ Object
private
-
#onstop ⇒ Object
-
#onstop=(callback) ⇒ Object
-
#playbackRate=(value) ⇒ Object
-
#process(_input_buffer, num_frames, start_frame, _cache) ⇒ Object
-
#process_multichannel_buffer(num_frames, start_frame, rates) ⇒ Object
private
-
#resolve_buffer_position(base_position) ⇒ Object
private
-
#restart(time = nil, offset = nil, duration = nil) ⇒ Object
-
#reverse_position(base_position) ⇒ Object
private
-
#sample_positions_for(num_frames, start_frame, rates) ⇒ Object
private
-
#seek(time = nil) ⇒ Object
-
#shaped_gain(progress) ⇒ Object
private
-
#start(time = nil, offset = nil, duration = nil) ⇒ Object
-
#state(time = context.current_time) ⇒ Object
#active_at?, #apply_volume!, #cancel_stop, #clear_transport_event, #mute?, #notify_stop_in_window, #number_of_inputs, #render, #render_block, #resolve_time, #resolve_transport_time, #schedule_transport_event, #source_type, #stop, #sync, #synced?, #unsync, #uses_legacy_render_for_block?
Constructor Details
#initialize(buffer:, playback_rate: 1.0, loop: false, loop_start: 0.0, loop_end: nil, reverse: false, fade_in: 0.0, fade_out: 0.0, curve: :linear, autostart: false, onstop: nil, context: Deftones.context) ⇒ Player
Returns a new instance of Player.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
# File 'lib/deftones/source/player.rb', line 10
def initialize(buffer:, playback_rate: 1.0, loop: false, loop_start: 0.0, loop_end: nil,
reverse: false, fade_in: 0.0, fade_out: 0.0, curve: :linear,
autostart: false, onstop: nil, context: Deftones.context)
super(context: context)
@buffer = buffer.is_a?(IO::Buffer) ? buffer : IO::Buffer.load(buffer)
@playback_rate = Core::Signal.new(value: playback_rate, units: :number, context: context)
@loop = loop
@loop_start = loop_start.to_f
@loop_end = loop_end
@reverse = reverse
@fade_in = fade_in.to_f
@fade_out = fade_out.to_f
@curve = curve.to_sym
@autostart = !!autostart
@onstop = onstop
@seek_position = 0.0
@start_time = Float::INFINITY
@stop_notified = false
start(0.0) if @autostart
end
|
Instance Attribute Details
#autostart ⇒ Object
Returns the value of attribute autostart.
8
9
10
|
# File 'lib/deftones/source/player.rb', line 8
def autostart
@autostart
end
|
#buffer ⇒ Object
Returns the value of attribute buffer.
6
7
8
|
# File 'lib/deftones/source/player.rb', line 6
def buffer
@buffer
end
|
#curve ⇒ Object
Returns the value of attribute curve.
7
8
9
|
# File 'lib/deftones/source/player.rb', line 7
def curve
@curve
end
|
#fade_in ⇒ Object
Also known as:
fadeIn
Returns the value of attribute fade_in.
7
8
9
|
# File 'lib/deftones/source/player.rb', line 7
def fade_in
@fade_in
end
|
#fade_out ⇒ Object
Also known as:
fadeOut
Returns the value of attribute fade_out.
7
8
9
|
# File 'lib/deftones/source/player.rb', line 7
def fade_out
@fade_out
end
|
#loop ⇒ Object
Returns the value of attribute loop.
7
8
9
|
# File 'lib/deftones/source/player.rb', line 7
def loop
@loop
end
|
#loop_end ⇒ Object
Also known as:
loopEnd
Returns the value of attribute loop_end.
7
8
9
|
# File 'lib/deftones/source/player.rb', line 7
def loop_end
@loop_end
end
|
#loop_start ⇒ Object
Also known as:
loopStart
Returns the value of attribute loop_start.
7
8
9
|
# File 'lib/deftones/source/player.rb', line 7
def loop_start
@loop_start
end
|
#playback_rate ⇒ Object
Also known as:
playbackRate
Returns the value of attribute playback_rate.
6
7
8
|
# File 'lib/deftones/source/player.rb', line 6
def playback_rate
@playback_rate
end
|
#reverse ⇒ Object
Returns the value of attribute reverse.
7
8
9
|
# File 'lib/deftones/source/player.rb', line 7
def reverse
@reverse
end
|
Instance Method Details
#dispose ⇒ Object
51
52
53
54
|
# File 'lib/deftones/source/player.rb', line 51
def dispose
@buffer = nil
super
end
|
#envelope_gain(current_time) ⇒ Object
133
134
135
|
# File 'lib/deftones/source/player.rb', line 133
def envelope_gain(current_time)
fade_in_gain(current_time) * fade_out_gain(current_time)
end
|
#fade_in_gain(current_time) ⇒ Object
137
138
139
140
141
|
# File 'lib/deftones/source/player.rb', line 137
def fade_in_gain(current_time)
return 1.0 if @fade_in <= 0.0
shaped_gain((current_time - @start_time) / @fade_in)
end
|
#fade_out_gain(current_time) ⇒ Object
143
144
145
146
147
|
# File 'lib/deftones/source/player.rb', line 143
def fade_out_gain(current_time)
return 1.0 unless @stop_time && @fade_out > 0.0
shaped_gain((@stop_time - current_time) / @fade_out)
end
|
#fadeIn=(value) ⇒ Object
119
120
121
|
# File 'lib/deftones/source/player.rb', line 119
def fadeIn=(value)
self.fade_in = value
end
|
#fadeOut=(value) ⇒ Object
123
124
125
|
# File 'lib/deftones/source/player.rb', line 123
def fadeOut=(value)
self.fade_out = value
end
|
#integrated_position_at_frame(frame_index) ⇒ Object
201
202
203
204
205
206
207
208
|
# File 'lib/deftones/source/player.rb', line 201
def integrated_position_at_frame(frame_index)
start_frame = (@start_time * context.sample_rate).floor
frames_to_integrate = [frame_index - start_frame, 0].max
return @seek_position if frames_to_integrate.zero?
rates = @playback_rate.process(frames_to_integrate, start_frame)
@seek_position + (rates.sum * (@buffer.sample_rate.to_f / context.sample_rate))
end
|
#loaded ⇒ Object
47
48
49
|
# File 'lib/deftones/source/player.rb', line 47
def loaded
loaded?
end
|
#loaded? ⇒ Boolean
43
44
45
|
# File 'lib/deftones/source/player.rb', line 43
def loaded?
!@buffer.nil?
end
|
#loop_end_frame ⇒ Object
239
240
241
242
243
|
# File 'lib/deftones/source/player.rb', line 239
def loop_end_frame
return unless @loop_end
Deftones::Music::Time.parse(@loop_end) * @buffer.sample_rate
end
|
#looped_position(position) ⇒ Object
227
228
229
230
231
232
|
# File 'lib/deftones/source/player.rb', line 227
def looped_position(position)
min_position = @loop_start * @buffer.sample_rate
max_position = loop_end_frame || @buffer.frames
span = [max_position - min_position, 1.0].max
min_position + ((position - min_position) % span)
end
|
#looped_reverse_position(position, min_position, max_position) ⇒ Object
234
235
236
237
|
# File 'lib/deftones/source/player.rb', line 234
def looped_reverse_position(position, min_position, max_position)
span = [max_position - min_position, 1.0].max
min_position + ((position - min_position) % span)
end
|
#loopEnd=(value) ⇒ Object
115
116
117
|
# File 'lib/deftones/source/player.rb', line 115
def loopEnd=(value)
self.loop_end = value
end
|
#loopStart=(value) ⇒ Object
111
112
113
|
# File 'lib/deftones/source/player.rb', line 111
def loopStart=(value)
self.loop_start = value
end
|
#multichannel_process? ⇒ Boolean
129
130
131
|
# File 'lib/deftones/source/player.rb', line 129
def multichannel_process?
@buffer && @buffer.channels > 1
end
|
#notify_stop(current_time) ⇒ Object
156
157
158
159
160
161
|
# File 'lib/deftones/source/player.rb', line 156
def notify_stop(current_time)
return if @stop_notified
@stop_notified = true
@onstop&.call(current_time)
end
|
#onstop ⇒ Object
35
36
37
|
# File 'lib/deftones/source/player.rb', line 35
def onstop
@onstop
end
|
#onstop=(callback) ⇒ Object
39
40
41
|
# File 'lib/deftones/source/player.rb', line 39
def onstop=(callback)
@onstop = callback
end
|
#playbackRate=(value) ⇒ Object
107
108
109
|
# File 'lib/deftones/source/player.rb', line 107
def playbackRate=(value)
self.playback_rate = value
end
|
#process(_input_buffer, num_frames, start_frame, _cache) ⇒ Object
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
# File 'lib/deftones/source/player.rb', line 80
def process(_input_buffer, num_frames, start_frame, _cache)
rates = @playback_rate.process(num_frames, start_frame)
sample_positions = sample_positions_for(num_frames, start_frame, rates)
return process_multichannel_buffer(num_frames, start_frame, rates) if multichannel_process?
Array.new(num_frames) do |index|
current_time = (start_frame + index).to_f / context.sample_rate
notify_stop(current_time) if @stop_time && current_time >= @stop_time
next 0.0 unless active_at?(current_time)
sample_position = sample_positions[index]
if sample_position.negative?
@stop_time ||= current_time
notify_stop(current_time)
next 0.0
end
@buffer.sample_at(sample_position) * envelope_gain(current_time)
end
end
|
#process_multichannel_buffer(num_frames, start_frame, rates) ⇒ Object
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
# File 'lib/deftones/source/player.rb', line 163
def process_multichannel_buffer(num_frames, start_frame, rates)
output = Array.new(@buffer.channels) { Array.new(num_frames, 0.0) }
sample_positions = sample_positions_for(num_frames, start_frame, rates)
num_frames.times do |index|
current_time = (start_frame + index).to_f / context.sample_rate
notify_stop(current_time) if @stop_time && current_time >= @stop_time
next unless active_at?(current_time)
sample_position = sample_positions[index]
if sample_position.negative?
@stop_time ||= current_time
notify_stop(current_time)
next
end
gain = envelope_gain(current_time)
@buffer.channels.times do |channel_index|
output[channel_index][index] = @buffer.sample_at(sample_position, channel_index) * gain
end
end
Core::AudioBlock.from_channel_data(output)
end
|
#resolve_buffer_position(base_position) ⇒ Object
210
211
212
213
214
215
216
|
# File 'lib/deftones/source/player.rb', line 210
def resolve_buffer_position(base_position)
return -1 if base_position.negative?
return reverse_position(base_position) if @reverse
return looped_position(base_position) if @loop
base_position < @buffer.frames ? base_position : -1
end
|
#restart(time = nil, offset = nil, duration = nil) ⇒ Object
64
65
66
67
|
# File 'lib/deftones/source/player.rb', line 64
def restart(time = nil, offset = nil, duration = nil)
stop(time)
start(time, offset, duration)
end
|
#reverse_position(base_position) ⇒ Object
218
219
220
221
222
223
224
225
|
# File 'lib/deftones/source/player.rb', line 218
def reverse_position(base_position)
max_position = loop_end_frame || (@buffer.frames - 1)
min_position = @loop_start * @buffer.sample_rate
position = max_position - base_position
return looped_reverse_position(position, min_position, max_position) if @loop
position
end
|
#sample_positions_for(num_frames, start_frame, rates) ⇒ Object
188
189
190
191
192
193
194
195
196
197
198
199
|
# File 'lib/deftones/source/player.rb', line 188
def sample_positions_for(num_frames, start_frame, rates)
return Array.new(num_frames, -1.0) if @start_time.infinite?
ratio = @buffer.sample_rate.to_f / context.sample_rate
base_position = integrated_position_at_frame(start_frame)
Array.new(num_frames) do |index|
position = resolve_buffer_position(base_position)
base_position += rates[index].to_f * ratio
position
end
end
|
#seek(time = nil) ⇒ Object
73
74
75
76
77
78
|
# File 'lib/deftones/source/player.rb', line 73
def seek(time = nil)
return @seek_position.to_f / @buffer.sample_rate if time.nil?
@seek_position = Deftones::Music::Time.parse(time) * @buffer.sample_rate
self
end
|
#shaped_gain(progress) ⇒ Object
149
150
151
152
153
154
|
# File 'lib/deftones/source/player.rb', line 149
def shaped_gain(progress)
bounded = progress.clamp(0.0, 1.0)
return bounded if @curve == :linear
Math.sin(bounded * Math::PI * 0.5)
end
|
#start(time = nil, offset = nil, duration = nil) ⇒ Object
56
57
58
59
60
61
62
|
# File 'lib/deftones/source/player.rb', line 56
def start(time = nil, offset = nil, duration = nil)
seek(offset) if offset
@stop_notified = false
super(time)
self.stop(@start_time + Deftones::Music::Time.parse(duration)) if duration
self
end
|
#state(time = context.current_time) ⇒ Object
69
70
71
|
# File 'lib/deftones/source/player.rb', line 69
def state(time = context.current_time)
active_at?(resolve_time(time)) ? :started : :stopped
end
|