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 =

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

Returns:

  • (::Float)
5512.5
MAXIMUM_LAG =

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, minimum_rms: 0.0) ⇒ Yin

minimum_rms reports frames quieter than it unvoiced without searching.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/dsprb/yin.rb', line 33

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_rms: 0.0
)
  @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)
  @minimum_rms = Float(minimum_rms)

  validate!
  freeze
end

Instance Attribute Details

#hop_seconds::Float (readonly)

Returns the value of attribute hop_seconds.

Returns:

  • (::Float)


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

def hop_seconds
  @hop_seconds
end

#maximum_frequency::Float (readonly)

Returns the value of attribute maximum_frequency.

Returns:

  • (::Float)


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

def maximum_frequency
  @maximum_frequency
end

#minimum_frequency::Float (readonly)

Returns the value of attribute minimum_frequency.

Returns:

  • (::Float)


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

def minimum_frequency
  @minimum_frequency
end

#minimum_rms::Float (readonly)

Returns the value of attribute minimum_rms.

Returns:

  • (::Float)


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

def minimum_rms
  @minimum_rms
end

#threshold::Float (readonly)

Returns the value of attribute threshold.

Returns:

  • (::Float)


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

def threshold
  @threshold
end

#voiced_threshold::Float (readonly)

Returns the value of attribute voiced_threshold.

Returns:

  • (::Float)


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

def voiced_threshold
  @voiced_threshold
end

#working_rate::Float (readonly)

Returns the value of attribute working_rate.

Returns:

  • (::Float)


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

def working_rate
  @working_rate
end

Instance Method Details

#call(waveform) ⇒ PitchTrack

Parameters:

Returns:



54
55
56
57
58
59
60
61
62
63
# File 'lib/dsprb/yin.rb', line 54

def call(waveform)
  reduced = Decimator.to(waveform, @working_rate)
  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