Class: SPCore::SincFilter

Inherits:
Object
  • Object
show all
Includes:
Hashmake::HashMakeable
Defined in:
lib/spcore/filters/fir/sinc_filter.rb

Overview

Base windowed sinc filter. Implements lowpass and highpass. A bandpass and bandstop filter would be implemented using two of these.

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

Author:

  • James Tunnell

Constant Summary collapse

ARG_SPECS =

Use to process hashed args in #initialize.

{
  :order => arg_spec(:reqd => true, :type => Fixnum, :validator => ->(a){ a % 2 == 0 } ),
  :sample_rate => arg_spec(:reqd => true, :type => Fixnum, :validator => ->(a){ a > 0 } ),
  :cutoff_freq => arg_spec(:reqd => true, :type => Numeric, :validator => ->(a){ a > 0.0 } ),
  :window_class => arg_spec(:reqd => false, :type => Class, :default => BlackmanWindow ),
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args) ⇒ SincFilter

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

Raises:

  • (ArgumentError)


26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/spcore/filters/fir/sinc_filter.rb', line 26

def initialize args
  hash_make args, SincFilter::ARG_SPECS
  
  raise ArgumentError, "cutoff_freq is greater than 0.5 * sample_rate" if @cutoff_freq > (@sample_rate / 2.0)
  
  size = @order + 1
  transition_freq = @cutoff_freq.to_f / @sample_rate
  b = TWO_PI * transition_freq
  
  # make FIR filter kernels for lowpass and highpass
  
  lowpass_kernel = Array.new(size)
  highpass_kernel = Array.new(size)
  window = @window_class.new(size)
  
  for n in 0...(@order / 2)
    c = n - (@order / 2)
    y = Math::sin(b * c) / (Math::PI * (c))
    lowpass_kernel[size - 1 - n] = lowpass_kernel[n] = y * window.data[n]
    highpass_kernel[size - 1 - n] = highpass_kernel[n] = -lowpass_kernel[n]
  end
  lowpass_kernel[@order / 2] = 2 * transition_freq * window.data[@order / 2]
  highpass_kernel[@order / 2] = (1 - 2 * transition_freq) * window.data[@order / 2]
  
  @lowpass_fir = FIR.new lowpass_kernel, @sample_rate
  @highpass_fir = FIR.new highpass_kernel, @sample_rate
end

Instance Attribute Details

#highpass_firObject (readonly)

Returns the value of attribute highpass_fir.



22
23
24
# File 'lib/spcore/filters/fir/sinc_filter.rb', line 22

def highpass_fir
  @highpass_fir
end

#lowpass_firObject (readonly)

Returns the value of attribute lowpass_fir.



22
23
24
# File 'lib/spcore/filters/fir/sinc_filter.rb', line 22

def lowpass_fir
  @lowpass_fir
end

Instance Method Details

#highpass(input) ⇒ Array

Process the input with the highpass FIR.

Returns:

  • (Array)

    containing the filtered input.



62
63
64
# File 'lib/spcore/filters/fir/sinc_filter.rb', line 62

def highpass input
  return @highpass_fir.convolve input
end

#lowpass(input) ⇒ Array

Process the input with the lowpass FIR.

Returns:

  • (Array)

    containing the filtered input.



56
57
58
# File 'lib/spcore/filters/fir/sinc_filter.rb', line 56

def lowpass input
  return @lowpass_fir.convolve input
end