-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsinglepolehighpassfilter.zig
56 lines (44 loc) · 2.26 KB
/
singlepolehighpassfilter.zig
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
54
55
56
const std = @import("std");
const Block = @import("../../radio.zig").Block;
const ProcessResult = @import("../../radio.zig").ProcessResult;
const _IIRFilterBlock = @import("./iirfilter.zig")._IIRFilterBlock;
////////////////////////////////////////////////////////////////////////////////
// Singlepole Highpass Filter Block
////////////////////////////////////////////////////////////////////////////////
pub fn SinglepoleHighpassFilterBlock(comptime T: type) type {
return _IIRFilterBlock(T, 2, 2, struct {
cutoff: f32,
pub fn init(cutoff: f32) SinglepoleHighpassFilterBlock(T) {
return SinglepoleHighpassFilterBlock(T)._init(.{ .cutoff = cutoff });
}
pub fn initialize(self: *SinglepoleHighpassFilterBlock(T), _: std.mem.Allocator) !void {
// Compute wraped tau
const rate = try self.block.getRate(f32);
const tau = 1 / (2 * rate * std.math.tan((std.math.pi * self.context.cutoff) / rate));
// Populate taps
self.b_taps[0] = (2 * tau * rate) / (1 + 2 * tau * rate);
self.b_taps[1] = -(2 * tau * rate) / (1 + 2 * tau * rate);
self.a_taps[0] = 1;
self.a_taps[1] = (1 - 2 * tau * rate) / (1 + 2 * tau * rate);
}
});
}
////////////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////////////
const BlockTester = @import("../../radio.zig").testing.BlockTester;
const vectors = @import("../../vectors/blocks/signal/singlepolehighpassfilter.zig");
test "SinglepoleHighpassFilterBlock" {
// 1e-2 cutoff, ComplexFloat32
{
var block = SinglepoleHighpassFilterBlock(std.math.Complex(f32)).init(0.01);
var tester = BlockTester.init(&block.block, 1e-6);
try tester.check(2, &[1]type{std.math.Complex(f32)}, .{&vectors.input_complexfloat32}, &[1]type{std.math.Complex(f32)}, .{&vectors.output_cutoff_0_01_complexfloat32});
}
// 1e-2 cutoff, Float32
{
var block = SinglepoleHighpassFilterBlock(f32).init(0.01);
var tester = BlockTester.init(&block.block, 1e-6);
try tester.check(2, &[1]type{f32}, .{&vectors.input_float32}, &[1]type{f32}, .{&vectors.output_cutoff_0_01_float32});
}
}