Class: Deftones::Analysis::Meter

Inherits:
Core::AudioNode show all
Defined in:
lib/deftones/analysis/meter.rb

Instance Attribute Summary collapse

Attributes inherited from Core::AudioNode

#context, #input

Instance Method Summary collapse

Methods inherited from 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(smoothing: 0.8, normal_range: false, channels: 1, clip_threshold: 1.0, context: Deftones.context) ⇒ Meter

Returns a new instance of Meter.



8
9
10
11
12
13
14
15
16
17
# File 'lib/deftones/analysis/meter.rb', line 8

def initialize(smoothing: 0.8, normal_range: false, channels: 1, clip_threshold: 1.0, context: Deftones.context)
  super(context: context)
  @channels = [channels.to_i, 1].max
  @peak_values = Array.new(@channels, 0.0)
  @rms_values = Array.new(@channels, 0.0)
  @clip_counts = Array.new(@channels, 0)
  @normal_range = !!normal_range
  @clip_threshold = clip_threshold.to_f
  self.smoothing = smoothing
end

Instance Attribute Details

#clip_thresholdObject Also known as: clipThreshold

Returns the value of attribute clip_threshold.



6
7
8
# File 'lib/deftones/analysis/meter.rb', line 6

def clip_threshold
  @clip_threshold
end

#normal_rangeObject Also known as: normalRange

Returns the value of attribute normal_range.



6
7
8
# File 'lib/deftones/analysis/meter.rb', line 6

def normal_range
  @normal_range
end

Instance Method Details

#channelsObject



19
20
21
# File 'lib/deftones/analysis/meter.rb', line 19

def channels
  @channels
end

#clip_countObject Also known as: clipCount



31
32
33
# File 'lib/deftones/analysis/meter.rb', line 31

def clip_count
  @clip_counts.length == 1 ? @clip_counts.first : @clip_counts.dup
end

#clipThreshold=(value) ⇒ Object



90
91
92
# File 'lib/deftones/analysis/meter.rb', line 90

def clipThreshold=(value)
  self.clip_threshold = value
end

#get_valueObject Also known as: getValue



50
51
52
53
54
55
56
57
58
59
60
# File 'lib/deftones/analysis/meter.rb', line 50

def get_value
  values = @rms_values.map do |value|
    if @normal_range
      Deftones::DSP::Helpers.clamp(value, 0.0, 1.0)
    else
      Deftones.gain_to_db([value.abs, 1.0e-12].max)
    end
  end

  values.length == 1 ? values.first : values
end

#multichannel_process?Boolean

Returns:

  • (Boolean)


62
63
64
# File 'lib/deftones/analysis/meter.rb', line 62

def multichannel_process?
  true
end

#normalRange=(value) ⇒ Object



86
87
88
# File 'lib/deftones/analysis/meter.rb', line 86

def normalRange=(value)
  self.normal_range = value
end

#peakObject



23
24
25
# File 'lib/deftones/analysis/meter.rb', line 23

def peak
  @peak_values.length == 1 ? @peak_values.first : @peak_values.dup
end

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



66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/deftones/analysis/meter.rb', line 66

def process(input_block, num_frames, _start_frame, _cache)
  analysis_block = input_block.fit_channels(@channels)

  @channels.times do |channel_index|
    segment = analysis_block.channel_data[channel_index].first(num_frames)
    instantaneous_peak = segment.map(&:abs).max || 0.0
    instantaneous_rms = Math.sqrt(segment.sum { |sample| sample * sample } / [segment.length, 1].max)
    @clip_counts[channel_index] += segment.count { |sample| sample.abs >= @clip_threshold }
    @peak_values[channel_index] = smooth(@peak_values[channel_index], instantaneous_peak)
    @rms_values[channel_index] = smooth(@rms_values[channel_index], instantaneous_rms)
  end

  input_block
end

#resetObject



35
36
37
38
39
40
# File 'lib/deftones/analysis/meter.rb', line 35

def reset
  @peak_values.fill(0.0)
  @rms_values.fill(0.0)
  @clip_counts.fill(0)
  self
end

#rmsObject



27
28
29
# File 'lib/deftones/analysis/meter.rb', line 27

def rms
  @rms_values.length == 1 ? @rms_values.first : @rms_values.dup
end

#smooth(previous, current) ⇒ Object (private)



96
97
98
99
100
# File 'lib/deftones/analysis/meter.rb', line 96

def smooth(previous, current)
  return current if @smoothing.zero?

  (previous.to_f * @smoothing) + (current.to_f * (1.0 - @smoothing))
end

#smoothingObject



42
43
44
# File 'lib/deftones/analysis/meter.rb', line 42

def smoothing
  @smoothing
end

#smoothing=(value) ⇒ Object



46
47
48
# File 'lib/deftones/analysis/meter.rb', line 46

def smoothing=(value)
  @smoothing = Deftones::DSP::Helpers.clamp(value.to_f, 0.0, 1.0)
end