class AudioStream::Fx::BiquadFilter

Constants

DEFAULT_Q

Public Class Methods

new(soundinfo) click to toggle source
# File lib/audio_stream/fx/biquad_filter.rb, line 6
def initialize(soundinfo)
  @samplerate = soundinfo.samplerate.to_f
  @biquads = [
    Vdsp::DoubleBiquad.new(1),
    Vdsp::DoubleBiquad.new(1),
  ]
end

Public Instance Methods

plot(width=500) click to toggle source
# File lib/audio_stream/fx/biquad_filter.rb, line 67
def plot(width=500)
  data = plot_data(width)

  Plotly::Plot.new(
    data: [{x: data[:x], y: data[:magnitude], name: 'Magnitude', yaxis: 'y1'}, {x: data[:x], y: data[:phase], name: 'Phase', yaxis: 'y2'}],
    layout: {
      xaxis: {title: 'Frequency (Hz)', type: 'log'},
      yaxis: {side: 'left', title: 'Magnitude (dB)', showgrid: false},
      yaxis2: {side: 'right', title: 'Phase (deg)', showgrid: false, overlaying: 'y'}
    }
  )
end
plot_data(width=500) click to toggle source
# File lib/audio_stream/fx/biquad_filter.rb, line 32
def plot_data(width=500)
  b0 = @coef.b0
  b1 = @coef.b1
  b2 = @coef.b2
  a1 = @coef.a1
  a2 = @coef.a2

  noctaves = 10
  nyquist = @samplerate * 0.5

  freq = []
  x = []
  width.times {|i|
    f = i.to_f / width
    f = 2.0 ** (noctaves * (f - 1.0))
    freq << f
    x << (f * nyquist)
  }

  mag_res = []
  phase_res = []
  width.times {|i|
    omega = -Math::PI * freq[i]
    z = Complex(Math.cos(omega), Math.sin(omega))
    num = b0 + (b1 + b2 * z) * z
    den = 1 + (a1 + a2 * z) * z
    res = num / den

    mag_res << Decibel.mag(res.abs).db
    phase_res << 180 / Math::PI * Math.atan2(res.imag, res.real)
  }

  {x: x, magnitude: mag_res, phase: phase_res}
end
process(input) click to toggle source
# File lib/audio_stream/fx/biquad_filter.rb, line 18
def process(input)
  channels = input.channels

  case channels
  when 1
    dst0 = @biquads[0].apply(input.streams[0])
    Buffer.new(dst0)
  when 2
    dst0 = @biquads[0].apply(input.streams[0])
    dst1 = @biquads[1].apply(input.streams[1])
    Buffer.new(dst0, dst1)
  end
end
update_coef(*args, **kwargs) click to toggle source
# File lib/audio_stream/fx/biquad_filter.rb, line 14
def update_coef(*args, **kwargs)
  raise Error, "#{self.class.name}.update_coef is not implemented"
end