Module: DSP::Lpc

Defined in:
lib/dsprb/lpc.rb,
sig/dsprb.rbs

Defined Under Namespace

Classes: Model

Constant Summary collapse

DENOMINATOR_FLOOR =

Below this the all-pole denominator is treated as a pole on the unit circle.

Returns:

  • (::Float)
1e-18
UNBOUNDED_MAGNITUDE =

Returns:

  • (::Float)
1e9

Class Method Summary collapse

Class Method Details

.advance(coefficients, step, reflection) ⇒ ::Array[::Float]

Parameters:

  • (::Array[::Float])
  • (::Integer)
  • (::Float)

Returns:

  • (::Array[::Float])


70
71
72
73
74
75
# File 'lib/dsprb/lpc.rb', line 70

def advance(coefficients, step, reflection)
  updated = coefficients.dup
  (1...step).each { |index| updated[index] = coefficients[index] + (reflection * coefficients[step - index]) }
  updated[step] = reflection
  updated
end

.levinson(autocorrelation, order) ⇒ Model

Levinson-Durbin recursion: solves the Yule-Walker system in O(order^2), stopping early when a reflection coefficient leaves the unit circle.

Parameters:

  • (::Array[::Float])
  • (::Integer)

Returns:



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/dsprb/lpc.rb', line 50

def levinson(autocorrelation, order)
  coefficients = Array.new(order + 1, 0.0)
  coefficients[0] = 1.0
  error = autocorrelation[0].to_f
  return Model.new(coefficients: coefficients, error: 0.0) unless error.positive?

  (1..order).each do |step|
    total = autocorrelation[step]
    (1...step).each { |index| total += coefficients[index] * autocorrelation[step - index] }
    reflection = -total / error
    return Model.new(coefficients: coefficients, error: error) if reflection.abs >= 1.0

    coefficients = advance(coefficients, step, reflection)
    error *= 1.0 - (reflection * reflection)
    return Model.new(coefficients: coefficients, error: error) unless error.positive?
  end

  Model.new(coefficients: coefficients, error: error)
end

.solve(frame, order:) ⇒ Model

Parameters:

  • (frame)
  • order: (::Integer)

Returns:



46
# File 'lib/dsprb/lpc.rb', line 46

def solve(frame, order:) = levinson(Autocorrelation.call(frame, order), order)