Class: DSP::Lpc::Envelope

Inherits:
Object
  • Object
show all
Extended by:
Prepared
Defined in:
lib/dsprb/lpc.rb,
sig/dsprb.rbs

Overview

Samples 1 / |A(e^w)|^2 over [0, pi] on a fixed grid. Squaring the polynomial first leaves a sum over its autocorrelation, which is real and even, so only cosines remain and the grid precomputes once:

|A(w)|^2 = c[0] + 2 sum_{m=1..order} c[m] cos(w m)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Prepared

extended, prepared, prepared_count

Constructor Details

#initialize(points:, order:) ⇒ Envelope

Returns a new instance of Envelope.

Parameters:

  • points: (::Integer)
  • order: (::Integer)


20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/dsprb/lpc.rb', line 20

def initialize(points:, order:)
  @points = Check.at_least!(Integer(points), 2, "points")
  @order = Check.non_negative!(Integer(order), "order")

  span = (@points - 1).to_f
  @cosines = Array
    .new(@points) do |point|
      Array.new(@order + 1) { |lag| Math.cos(Math::PI * point * lag / span) }.freeze
    end
    .freeze
  freeze
end

Instance Attribute Details

#order::Integer (readonly)

Returns the value of attribute order.

Returns:

  • (::Integer)


16
17
18
# File 'lib/dsprb/lpc.rb', line 16

def order
  @order
end

#points::Integer (readonly)

Returns the value of attribute points.

Returns:

  • (::Integer)


16
17
18
# File 'lib/dsprb/lpc.rb', line 16

def points
  @points
end

Class Method Details

.for(points:, order:) ⇒ Envelope

Parameters:

  • points: (::Integer)
  • order: (::Integer)

Returns:



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

def self.for(points:, order:) = prepared([points, order]) { new(points: points, order: order) }

Instance Method Details

#call(coefficients) ⇒ ::Array[::Float]

Parameters:

  • (::Array[::Float])

Returns:

  • (::Array[::Float])


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

def call(coefficients)
  highest = coefficients.length - 1
  if highest > @order
    raise ArgumentError, "expected at most #{@order + 1} coefficients, got #{coefficients.length}"
  end

  correlation = Autocorrelation.call(coefficients, highest)
  out = Array.new(@points)

  point = 0
  while point < @points
    row = @cosines[point]
    total = correlation[0]
    lag = 1
    while lag <= highest
      total += 2.0 * correlation[lag] * row[lag]
      lag += 1
    end

    out[point] = total < DENOMINATOR_FLOOR ? UNBOUNDED_MAGNITUDE : 1.0 / total
    point += 1
  end

  out
end