Class: Deftones::Component::Panner

Inherits:
Deftones::Core::AudioNode show all
Defined in:
lib/deftones/component/panner.rb

Constant Summary collapse

PAN_LAWS =
%i[equal_power linear].freeze

Instance Attribute Summary collapse

Attributes inherited from Deftones::Core::AudioNode

#context, #input

Instance Method Summary collapse

Methods inherited from Deftones::Core::AudioNode

#>>, #attach_destination, #attach_source, #block_time, #chain, #channel_count, #channel_count_mode, #channel_interpretation, #connect, #connected?, #default_input_channels, #default_output_channels, #destination_for_connection, #detach_all_destinations, #detach_destination, #detach_source, #disconnect, #dispose, #disposed?, #fan, #get, #immediate, #input_for_index, #inputs, #mix_source_blocks, #name, #normalize_connection_index, #normalize_output_block, #now, #number_of_inputs, #number_of_outputs, #output, #output_for_connection, #output_for_index, #outputs, #raise_connection_index_error!, #reaches_node?, #render, #render_block, #sample_time, #set, #to_destination, #to_frequency, #to_master, #to_midi, #to_output, #to_s, #to_seconds, #to_ticks, #uses_legacy_render_for_block?, #validate_connectable!, #validate_connection_index!

Constructor Details

#initialize(pan: 0.0, pan_law: :equal_power, context: Deftones.context) ⇒ Panner

Returns a new instance of Panner.



10
11
12
13
14
# File 'lib/deftones/component/panner.rb', line 10

def initialize(pan: 0.0, pan_law: :equal_power, context: Deftones.context)
  super(context: context)
  @pan = Core::Signal.new(value: pan, units: :number, context: context)
  @pan_law = normalize_pan_law(pan_law)
end

Instance Attribute Details

#panObject

Returns the value of attribute pan.



8
9
10
# File 'lib/deftones/component/panner.rb', line 8

def pan
  @pan
end

#pan_lawObject Also known as: panLaw

Returns the value of attribute pan_law.



8
9
10
# File 'lib/deftones/component/panner.rb', line 8

def pan_law
  @pan_law
end

Instance Method Details

#angle_for(pan) ⇒ Object (private)



83
84
85
# File 'lib/deftones/component/panner.rb', line 83

def angle_for(pan)
  ((pan.to_f.clamp(-1.0, 1.0) + 1.0) * Math::PI) * 0.25
end

#left_gain(pan) ⇒ Object (private)



71
72
73
74
75
# File 'lib/deftones/component/panner.rb', line 71

def left_gain(pan)
  return (1.0 - pan.to_f.clamp(-1.0, 1.0)) * 0.5 if @pan_law == :linear

  Math.cos(angle_for(pan))
end

#multichannel_process?Boolean

Returns:

  • (Boolean)


24
25
26
# File 'lib/deftones/component/panner.rb', line 24

def multichannel_process?
  true
end

#normalize_pan_law(value) ⇒ Object (private)

Raises:

  • (ArgumentError)


87
88
89
90
91
92
# File 'lib/deftones/component/panner.rb', line 87

def normalize_pan_law(value)
  normalized = value.to_sym
  return normalized if PAN_LAWS.include?(normalized)

  raise ArgumentError, "Unsupported pan law: #{value}"
end

#process(input_block, num_frames, start_frame, _cache) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/deftones/component/panner.rb', line 28

def process(input_block, num_frames, start_frame, _cache)
  pans = @pan.process(num_frames, start_frame)
  return process_mono_input(input_block, num_frames, pans) if input_block.channels == 1

  stereo_input = input_block.fit_channels(2)
  left = Array.new(num_frames)
  right = Array.new(num_frames)

  num_frames.times do |index|
    left[index] = stereo_input.channel_data[0][index] * stereo_left_gain(pans[index])
    right[index] = stereo_input.channel_data[1][index] * stereo_right_gain(pans[index])
  end

  Core::AudioBlock.from_channel_data([left, right])
end

#process_mono_input(input_block, num_frames, pans) ⇒ Object (private)



46
47
48
49
50
51
52
53
# File 'lib/deftones/component/panner.rb', line 46

def process_mono_input(input_block, num_frames, pans)
  mono_input = input_block.mono

  Core::AudioBlock.from_channel_data([
    Array.new(num_frames) { |index| mono_input[index] * left_gain(pans[index]) },
    Array.new(num_frames) { |index| mono_input[index] * right_gain(pans[index]) }
  ])
end

#right_gain(pan) ⇒ Object (private)



77
78
79
80
81
# File 'lib/deftones/component/panner.rb', line 77

def right_gain(pan)
  return (1.0 + pan.to_f.clamp(-1.0, 1.0)) * 0.5 if @pan_law == :linear

  Math.sin(angle_for(pan))
end

#stereo_left_gain(pan) ⇒ Object (private)



55
56
57
58
59
60
61
# File 'lib/deftones/component/panner.rb', line 55

def stereo_left_gain(pan)
  normalized = pan.to_f.clamp(-1.0, 1.0)
  return [1.0 - normalized, 0.0].max if @pan_law == :linear && normalized.positive?
  return 1.0 if normalized <= 0.0

  Math.cos(normalized * Math::PI * 0.5)
end

#stereo_right_gain(pan) ⇒ Object (private)



63
64
65
66
67
68
69
# File 'lib/deftones/component/panner.rb', line 63

def stereo_right_gain(pan)
  normalized = pan.to_f.clamp(-1.0, 1.0)
  return [1.0 + normalized, 0.0].max if @pan_law == :linear && normalized.negative?
  return 1.0 if normalized >= 0.0

  Math.cos(normalized.abs * Math::PI * 0.5)
end