-
Notifications
You must be signed in to change notification settings - Fork 62
/
bandpassfilter.lua
53 lines (43 loc) · 1.79 KB
/
bandpassfilter.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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
53
---
-- Filter a complex or real valued signal with a real-valued FIR band-pass
-- filter generated by the window design method.
--
-- $$ y[n] = (x * h_{bpf})[n] $$
--
-- @category Filtering
-- @block BandpassFilterBlock
-- @tparam int num_taps Number of FIR taps, must be odd
-- @tparam {number,number} cutoffs Cutoff frequencies in Hz
-- @tparam[opt=nil] number nyquist Nyquist frequency, if specifying
-- normalized cutoff frequencies
-- @tparam[opt='hamming'] string window Window type
--
-- @signature in:ComplexFloat32 > out:ComplexFloat32
-- @signature in:Float32 > out:Float32
--
-- @usage
-- -- Bandpass filter, 128 taps, 18 kHz to 20 kHz
-- local bpf = radio.BandpassFilterBlock(128, {18e3, 20e3})
local ffi = require('ffi')
local block = require('radio.core.block')
local types = require('radio.types')
local filter_utils = require('radio.utilities.filter_utils')
local FIRFilterBlock = require('radio.blocks.signal.firfilter')
local BandpassFilterBlock = block.factory("BandpassFilterBlock", FIRFilterBlock)
function BandpassFilterBlock:instantiate(num_taps, cutoffs, nyquist, window)
assert(num_taps, "Missing argument #1 (num_taps)")
self.cutoffs = assert(cutoffs, "Missing argument #2 (cutoffs)")
self.window = window or "hamming"
self.nyquist = nyquist
FIRFilterBlock.instantiate(self, types.Float32.vector(num_taps))
end
function BandpassFilterBlock:initialize()
-- Compute Nyquist frequency
local nyquist = self.nyquist or (self:get_rate()/2)
-- Generate taps
local cutoffs = {self.cutoffs[1]/nyquist, self.cutoffs[2]/nyquist}
local taps = filter_utils.firwin_bandpass(self.taps.length, cutoffs, self.window)
self.taps = types.Float32.vector_from_array(taps)
FIRFilterBlock.initialize(self)
end
return BandpassFilterBlock