LASP 1.0
Library for Acoustic Signal Processing
Loading...
Searching...
No Matches
lasp_dsp_pybind.cpp
Go to the documentation of this file.
1#include "arma_npy.h"
3#include "lasp_biquadbank.h"
4#include "lasp_fft.h"
5#include "lasp_filter.h"
6#include "lasp_slm.h"
7#include "lasp_streammgr.h"
8#include "lasp_window.h"
9#include <iostream>
10#include <pybind11/pybind11.h>
11
12using std::cerr;
13using std::endl;
14namespace py = pybind11;
15using rte = std::runtime_error;
16
29void init_dsp(py::module &m) {
30
31 py::class_<Fft> fft(m, "Fft");
32 fft.def(py::init<us>());
33 fft.def("fft", [](Fft &f, dpyarray dat) {
34 if (dat.ndim() == 1) {
35 return ColToNpy<c>(f.fft(NpyToCol<d, false>(dat)));
36 } else if (dat.ndim() == 2) {
37 return MatToNpy<c>(f.fft(NpyToMat<d, false>(dat)));
38 } else {
39 throw rte("Invalid dimensions of array");
40 }
41 });
42 fft.def("ifft", [](Fft &f, cpyarray dat) {
43 if (dat.ndim() == 1) {
44 return ColToNpy<d>(f.ifft(NpyToCol<c, false>(dat)));
45 } else if (dat.ndim() == 2) {
46 return MatToNpy<d>(f.ifft(NpyToMat<c, false>(dat)));
47 } else {
48 throw rte("Invalid dimensions of array");
49 }
50 });
51
52 fft.def_static("load_fft_wisdom", &Fft::load_fft_wisdom);
53 fft.def_static("store_fft_wisdom", &Fft::store_fft_wisdom);
54
56 py::class_<Window> w(m, "Window");
57
58 py::enum_<Window::WindowType>(w, "WindowType")
59 .value("Hann", Window::WindowType::Hann)
60 .value("Hamming", Window::WindowType::Hamming)
61 .value("Bartlett", Window::WindowType::Bartlett)
62 .value("Blackman", Window::WindowType::Bartlett)
63 .value("Rectangular", Window::WindowType::Rectangular);
64
65 w.def_static("toTxt", &Window::toText);
66
67 py::class_<Filter, std::shared_ptr<Filter>> filter(m, "Filter");
68
70 py::class_<SeriesBiquad, std::shared_ptr<SeriesBiquad>> sbq(m, "SeriesBiquad",
71 filter);
72 sbq.def(py::init([](dpyarray filter) {
73 return std::make_shared<SeriesBiquad>(NpyToCol<d, false>(filter));
74 }));
75 sbq.def("filter", [](SeriesBiquad &s, dpyarray input) {
76 vd res = NpyToCol<d, true>(input);
77 s.filter(res);
78 return ColToNpy<d>(res);
79 });
80
82 py::class_<BiquadBank, Filter, std::shared_ptr<BiquadBank>> bqb(m,
83 "BiquadBank");
84 bqb.def(py::init([](dpyarray coefs) {
85 return std::make_shared<BiquadBank>(NpyToMat<d, false>(coefs));
86 }));
87 bqb.def(py::init([](dpyarray coefs, dpyarray gains) {
88 vd gains_arma = NpyToMat<d, false>(gains);
89 return std::make_shared<BiquadBank>(NpyToMat<d, false>(coefs), &gains_arma);
90 }));
91
92 bqb.def("setGains",
93 [](BiquadBank &b, dpyarray gains) { b.setGains(NpyToCol(gains)); });
94 bqb.def("filter", [](BiquadBank &b, dpyarray input) {
95 // Yes, a copy here
96 vd inout = NpyToCol<d, true>(input);
97 b.filter(inout);
98 return ColToNpy(inout);
99 });
100
102 py::class_<PowerSpectra> ps(m, "PowerSpectra");
103 ps.def(py::init<const us, const Window::WindowType>());
104 ps.def("compute", [](PowerSpectra &ps, dpyarray input) {
105 return CubeToNpy<c>(ps.compute(NpyToMat<d, false>(input)));
106 });
107
109 py::class_<AvPowerSpectra> aps(m, "AvPowerSpectra");
110 aps.def(py::init<const us, const Window::WindowType, const d, const d>(),
111 py::arg("nfft") = 2048,
112 py::arg("windowType") = Window::WindowType::Hann,
113 py::arg("overlap_percentage") = 50.0, py::arg("time_constant") = -1);
114
115 aps.def("compute", [](AvPowerSpectra &aps, dpyarray timedata) {
116 std::optional<ccube> res;
117 {
118 py::gil_scoped_release release;
119 res = aps.compute(NpyToMat<d, false>(timedata));
120 }
121
122 return CubeToNpy<c>(res.value_or(ccube(0, 0, 0)));
123 });
124 aps.def("get_est", [](const AvPowerSpectra &ps) {
125 ccube est = ps.get_est();
126 return CubeToNpy<c>(est);
127 });
128
129 py::class_<SLM> slm(m, "cppSLM");
130
131 slm.def_static("fromBiquads", [](const d fs, const d Lref, const us ds,
132 const d tau, dpyarray bandpass) {
133 return SLM::fromBiquads(fs, Lref, ds, tau, NpyToMat<d, false>(bandpass));
134 });
135
136 slm.def_static("fromBiquads", [](const d fs, const d Lref, const us ds,
137 const d tau, dpyarray prefilter,
138 py::array_t<d> bandpass) {
139 return SLM::fromBiquads(fs, Lref, ds, tau, NpyToCol<d, false>(prefilter),
140 NpyToMat<d, false>(bandpass));
141 });
142
143 slm.def("run", [](SLM &slm, dpyarray in) {
144 return MatToNpy<d>(slm.run(NpyToCol<d, false>(in)));
145 });
146 slm.def("Pm", [](const SLM &slm) { return ColToNpy<d>(slm.Pm); });
147 slm.def("Pmax", [](const SLM &slm) { return ColToNpy<d>(slm.Pmax); });
148 slm.def("Ppeak", [](const SLM &slm) { return ColToNpy<d>(slm.Ppeak); });
149
150 slm.def("Leq", [](const SLM &slm) { return ColToNpy<d>(slm.Leq()); });
151 slm.def("Lmax", [](const SLM &slm) { return ColToNpy<d>(slm.Lmax()); });
152 slm.def("Lpeak", [](const SLM &slm) { return ColToNpy<d>(slm.Lpeak()); });
153 slm.def_static("suggestedDownSamplingFac", &SLM::suggestedDownSamplingFac);
154}
py::array_t< T > ColToNpy(const arma::Col< T > &data)
Convert Armadillo column vector to Numpy 1D array.
Definition arma_npy.h:23
pyarray< d > dpyarray
Definition arma_npy.h:11
arma::Mat< T > NpyToCol(pyarray< T > data)
Wrap Numpy array to 1D Armadillo column vector.
Definition arma_npy.h:127
pyarray< c > cpyarray
Definition arma_npy.h:12
Estimate cross-power spectra using Welch' method of spectral estimation. The exact amount of overlap ...
Multiple biquad filters in parallel, each multiplied with a gain value, and finally all added togethe...
virtual void filter(vd &inout) override final
Filter input, and provides output in same array as input.
void setGains(const vd &gains)
Set new gain values for each filter in the BiquadBank.
Perform forward FFT's on real time data. Computes single-sided spectra, equivalent to Numpy's rfft an...
Definition lasp_fft.h:24
static std::string store_fft_wisdom()
Return a string containing FFT wisdom storage. String is empty for backend != FFTW.
Definition lasp_fft.cpp:175
static void load_fft_wisdom(const std::string &wisdom)
Load FFT wisdom from a wisdom string. Function does nothing if FFT backend is not FFTW.
Definition lasp_fft.cpp:163
Computes single-sided cross-power spectra for a group of channels. Only a single block of length fft,...
Sound Level Meter implementation that gives a result for each channel. A channel is the result of a f...
Definition lasp_slm.h:17
static us suggestedDownSamplingFac(const d fs, const d tw)
Comput a 'suggested' downsampling factor, i.e. a lower frame rate at which sound level meter values a...
Definition lasp_slm.cpp:67
static SLM fromBiquads(const d fs, const d Lref, const us downsampling_fac, const d tau, const vd &pre_filter_coefs, const dmat &bandpass_coefs)
Convenience function to create a Sound Level meter from Biquad filters only.
Definition lasp_slm.cpp:83
A set of Biquad filters in series.
virtual void filter(vd &inout) override final
Filter input, and provides output in same array as input.
static std::string toText(const WindowType wt)
Convert a window type enum to its equivalent text.
Definition lasp_window.h:25
std::runtime_error rte
Definition lasp_daq.cpp:16
void init_dsp(py::module &m)
Initialize DSP code.
arma::Col< d > vd
arma::Cube< c > ccube
size_t us
We often use boolean values.
Definition lasp_types.h:29