Class: DSP::Yin

Inherits:
Object
  • Object
show all
Defined in:
lib/dsprb/yin.rb,
sig/dsprb.rbs

Constant Summary collapse

DEFAULT_MINIMUM_HZ =

Returns:

  • (::Float)
70.0
DEFAULT_MAXIMUM_HZ =

Returns:

  • (::Float)
500.0
DEFAULT_HOP_SECONDS =

Returns:

  • (::Float)
0.008
DEFAULT_THRESHOLD =

Absolute threshold of the YIN paper: the first dip of the cumulative mean normalized difference below it is taken as the period.

Returns:

  • (::Float)
0.15
DEFAULT_VOICED_THRESHOLD =

A global minimum above this is too shallow to call the frame voiced.

Returns:

  • (::Float)
0.35
DEFAULT_WORKING_RATE =

Decimation target, an order above twice the highest tracked f0, so that periodicity survives while the O(window * lags) search stays cheap.

Returns:

  • (::Float)
5512.5
MAXIMUM_LAG =

Bounds the lag search for pathological rate and frequency combinations.

Returns:

  • (::Integer)
10_000

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(minimum_frequency: DEFAULT_MINIMUM_HZ, maximum_frequency: DEFAULT_MAXIMUM_HZ, hop_seconds: DEFAULT_HOP_SECONDS, threshold: DEFAULT_THRESHOLD, voiced_threshold: DEFAULT_VOICED_THRESHOLD, working_rate: DEFAULT_WORKING_RATE) ⇒ Yin

Returns a new instance of Yin.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/dsprb/yin.rb', line 25

def initialize(
  minimum_frequency: DEFAULT_MINIMUM_HZ,
  maximum_frequency: DEFAULT_MAXIMUM_HZ,
  hop_seconds: DEFAULT_HOP_SECONDS,
  threshold: DEFAULT_THRESHOLD,
  voiced_threshold: DEFAULT_VOICED_THRESHOLD,
  working_rate: DEFAULT_WORKING_RATE
)
  @minimum_frequency = Float(minimum_frequency)
  @maximum_frequency = Float(maximum_frequency)
  @hop_seconds = Float(hop_seconds)
  @threshold = Float(threshold)
  @voiced_threshold = Float(voiced_threshold)
  @working_rate = Float(working_rate)

  validate!
  freeze
end

Instance Attribute Details

#hop_seconds::Float (readonly)

Returns the value of attribute hop_seconds.

Returns:

  • (::Float)


23
24
25
# File 'lib/dsprb/yin.rb', line 23

def hop_seconds
  @hop_seconds
end

#maximum_frequency::Float (readonly)

Returns the value of attribute maximum_frequency.

Returns:

  • (::Float)


23
24
25
# File 'lib/dsprb/yin.rb', line 23

def maximum_frequency
  @maximum_frequency
end

#minimum_frequency::Float (readonly)

Returns the value of attribute minimum_frequency.

Returns:

  • (::Float)


23
24
25
# File 'lib/dsprb/yin.rb', line 23

def minimum_frequency
  @minimum_frequency
end

#threshold::Float (readonly)

Returns the value of attribute threshold.

Returns:

  • (::Float)


23
24
25
# File 'lib/dsprb/yin.rb', line 23

def threshold
  @threshold
end

#voiced_threshold::Float (readonly)

Returns the value of attribute voiced_threshold.

Returns:

  • (::Float)


23
24
25
# File 'lib/dsprb/yin.rb', line 23

def voiced_threshold
  @voiced_threshold
end

#working_rate::Float (readonly)

Returns the value of attribute working_rate.

Returns:

  • (::Float)


23
24
25
# File 'lib/dsprb/yin.rb', line 23

def working_rate
  @working_rate
end

Instance Method Details

#call(waveform) ⇒ PitchTrack

Parameters:

Returns:



44
45
46
47
48
49
50
51
52
53
# File 'lib/dsprb/yin.rb', line 44

def call(waveform)
  reduced = Decimator.new(Decimator.factor_for(waveform.sample_rate, @working_rate)).call(waveform)
  rate = reduced.sample_rate
  shortest = (rate / @maximum_frequency).floor.clamp(2, MAXIMUM_LAG)
  longest = (rate / @minimum_frequency).ceil.clamp(shortest + 2, MAXIMUM_LAG)
  window = longest * 2
  hop = [(rate * @hop_seconds).round, 1].max

  track(reduced.samples, rate: rate, window: window, hop: hop, shortest: shortest, longest: longest)
end