Matlab based signal processing workflows in Go. Design in Matlab and use in Go
Package filter
provides ability to infer filters created in Matlab
.
Design a filter in Matlab using Filter Design Tool and export it as an object on the workspace.
Create a JSON encoding of that object to use with this repo.
For instance a discrete time FIR low-pass filter can be created as follows:
function Hd = lowPassFilter
%LOWPASSFILTER Returns a discrete-time filter object.
% MATLAB Code
% Generated by MATLAB(R) 24.2 and Signal Processing Toolbox 24.2.
% Generated on: 24-Dec-2024 14:56:02
% Equiripple Lowpass filter designed using the FIRPM function.
% All frequency values are normalized to 1.
Fpass = 0.02; % Passband Frequency
Fstop = 0.1; % Stopband Frequency
Dpass = 0.057501127785; % Passband Ripple
Dstop = 0.0001; % Stopband Attenuation
dens = 20; % Density Factor
% Calculate the order from the parameters using FIRPMORD.
[N, Fo, Ao, W] = firpmord([Fpass, Fstop], [1 0], [Dpass, Dstop]);
% Calculate the coefficients using the FIRPM function.
b = firpm(N, Fo, Ao, W, {dens});
Hd = dfilt.dffir(b);
% [EOF]
Encode the filter to JSON string
Hd = lowPassFilter();
js = jsonencode(Hd);
package main
import (
"github.com/kubetrail/signal/pkg/filter"
"math"
"math/rand/v2"
)
// js represents the JSON encoding of filter object from Matlab
var js string = `
{
"Arithmetic": "double",
"Numerator": [
-3.178415946962565e-05,
0.00012243197558829932,
0.00020044046800350558,
0.0003488471460655481,
0.0005671834873047258,
0.0008686374904649395,
0.0012697519972841237,
0.0017879347298591607,
0.0024404612047465553,
0.00324370926934789,
0.004212343496976391,
0.005358457175976007,
0.006690726110359709,
0.008213604807760608,
0.009926598151788674,
0.011823664168543389,
0.01389279947716996,
0.016115826951839628,
0.01846838883421013,
0.02092016735730781,
0.023435371170089436,
0.025973497770710112,
0.028490327966822312,
0.03093908790591826,
0.03327174706042746,
0.03544045152939104,
0.03739905943817371,
0.03910467033841596,
0.040519017370098276,
0.041609677925945006,
0.04235122582902602,
0.04272655856897903,
0.04272655856897903,
0.04235122582902602,
0.041609677925945006,
0.040519017370098276,
0.03910467033841596,
0.03739905943817371,
0.03544045152939104,
0.03327174706042746,
0.03093908790591826,
0.028490327966822312,
0.025973497770710112,
0.023435371170089436,
0.02092016735730781,
0.01846838883421013,
0.016115826951839628,
0.01389279947716996,
0.011823664168543389,
0.009926598151788674,
0.008213604807760608,
0.006690726110359709,
0.005358457175976007,
0.004212343496976391,
0.00324370926934789,
0.0024404612047465553,
0.0017879347298591607,
0.0012697519972841237,
0.0008686374904649395,
0.0005671834873047258,
0.0003488471460655481,
0.00020044046800350558,
0.00012243197558829932,
-3.178415946962565e-05
],
"FilterStructure": "Direct-Form FIR",
"States": [
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
],
"NumSamplesProcessed": 0,
"PersistentMemory": false,
"RateChangeFactor": [
1,
1
]
}
`
func main() {
f, _ := filter.NewDffirFromJSON([]byte(js))
// handle error
// similarly, create direct form II SOS filter
// instead of FIR filter depending
// on which filter was designed in Matlab
// f, _ = filter.NewDf2sosFromJSON([]byte(js))
// create some signal with noise that will be filtered using f
x := make([]float64, 1024);
for i := range x {
x[i] = math.Sin(float64(i)/1024*10*math.Pi) + rand.Float64()/5
}
// filter signal
y, _ := f.Filter(x)
// handle error
// do something with y
_ = y;
}