class SPCore::DualSincFilter

Extended windowed sinc filter. Implements bandpass and bandstop using two SincFilterBase objects.

Theoretical source: www.labbookpages.co.uk/audio/firWindowing.html

@author James Tunnell

Constants

ARG_SPECS

Use to process hashed args in initialize.

Attributes

bandpass_fir[R]
bandstop_fir[R]
left_filter[R]
right_filter[R]

Public Class Methods

new(args) click to toggle source

Given a filter order, 2 cutoff frequencies, sample rate, and window class, develop a FIR filter kernel that can be used for lowpass filtering.

# File lib/spcore/filters/fir/dual_sinc_filter.rb, line 26
def initialize args
  hash_make args, DualSincFilter::ARG_SPECS
  
  raise ArgumentError, "left_cutoff_freq is greater than 0.5 * sample_rate" if @left_cutoff_freq > (@sample_rate * 0.5)
  raise ArgumentError, "right_cutoff_freq is greater than 0.5 * sample_rate" if @right_cutoff_freq > (@sample_rate * 0.5)
  raise ArgumentError, "left_cutoff_freq is not less than right_cutoff_freq" unless @left_cutoff_freq < @right_cutoff_freq 
  
  @left_filter = SincFilter.new(
    :sample_rate => @sample_rate,
    :order => @order,
    :cutoff_freq => @left_cutoff_freq,
    :window_class => @window_class,
  )

  @right_filter = SincFilter.new(
    :sample_rate => @sample_rate,
    :order => @order,
    :cutoff_freq => @right_cutoff_freq,
    :window_class => @window_class,
  )
  
  size = @order + 1

  # make FIR filter kernels for bandpass and bandstop
  
  bandpass_kernel = Array.new(size)
  bandstop_kernel = Array.new(size)
  window = @window_class.new(size)
  
  for n in 0...(@order / 2)
    bandpass_kernel[size - 1 - n] = bandpass_kernel[n] = @right_filter.lowpass_fir.kernel[n] + @left_filter.highpass_fir.kernel[n]
    bandstop_kernel[size - 1 - n] = bandstop_kernel[n] = @left_filter.lowpass_fir.kernel[n] + @right_filter.highpass_fir.kernel[n]
  end

  left_transition_freq = @left_cutoff_freq.to_f / @sample_rate
  right_transition_freq = @right_cutoff_freq.to_f / @sample_rate
  bw_times_two = 2.0 * (right_transition_freq - left_transition_freq)
  window_center_val = window.data[@order / 2]
  
  bandpass_kernel[@order / 2] = bw_times_two * window_center_val
  bandstop_kernel[@order / 2] = (1.0 - bw_times_two) * window_center_val
  
  @bandpass_fir = FIR.new bandpass_kernel, @sample_rate
  @bandstop_fir = FIR.new bandstop_kernel, @sample_rate
end

Public Instance Methods

bandpass(input) click to toggle source

Process the input with the bandpass FIR. @return [Array] containing the filtered input.

# File lib/spcore/filters/fir/dual_sinc_filter.rb, line 74
def bandpass input
  return @bandpass_fir.convolve input
end
bandstop(input) click to toggle source

Process the input with the bandstop FIR. @return [Array] containing the filtered input.

# File lib/spcore/filters/fir/dual_sinc_filter.rb, line 80
def bandstop input
  return @bandstop_fir.convolve input
end