#include "arma_npy.h" #include "lasp_avpowerspectra.h" #include "lasp_biquadbank.h" #include "lasp_fft.h" #include "lasp_filter.h" #include "lasp_slm.h" #include "lasp_streammgr.h" #include "lasp_window.h" #include #include using std::cerr; using std::endl; namespace py = pybind11; using rte = std::runtime_error; /** * \ingroup pybind * @{ * */ /** * @brief Initialize DSP code * * @param m The Python module to add classes and methods to */ void init_dsp(py::module &m) { py::class_ fft(m, "Fft"); fft.def(py::init()); fft.def("fft", [](Fft &f, dpyarray dat) { if (dat.ndim() == 1) { return ColToNpy(f.fft(NpyToCol(dat))); } else if (dat.ndim() == 2) { return MatToNpy(f.fft(NpyToMat(dat))); } else { throw rte("Invalid dimensions of array"); } }); fft.def("ifft", [](Fft &f, cpyarray dat) { if (dat.ndim() == 1) { return ColToNpy(f.ifft(NpyToCol(dat))); } else if (dat.ndim() == 2) { return MatToNpy(f.ifft(NpyToMat(dat))); } else { throw rte("Invalid dimensions of array"); } }); fft.def_static("load_fft_wisdom", &Fft::load_fft_wisdom); fft.def_static("store_fft_wisdom", &Fft::store_fft_wisdom); /// Window py::class_ w(m, "Window"); py::enum_(w, "WindowType") .value("Hann", Window::WindowType::Hann) .value("Hamming", Window::WindowType::Hamming) .value("Bartlett", Window::WindowType::Bartlett) .value("Blackman", Window::WindowType::Bartlett) .value("Rectangular", Window::WindowType::Rectangular); w.def_static("toTxt", &Window::toText); py::class_> filter(m, "Filter"); /// SeriesBiquad py::class_> sbq(m, "SeriesBiquad", filter); sbq.def(py::init([](dpyarray filter) { return std::make_shared(NpyToCol(filter)); })); sbq.def("filter", [](SeriesBiquad &s, dpyarray input) { vd res = NpyToCol(input); s.filter(res); return ColToNpy(res); }); /// BiquadBank py::class_> bqb(m, "BiquadBank"); bqb.def(py::init([](dpyarray coefs) { return std::make_shared(NpyToMat(coefs)); })); bqb.def(py::init([](dpyarray coefs, dpyarray gains) { vd gains_arma = NpyToMat(gains); return std::make_shared(NpyToMat(coefs), &gains_arma); })); bqb.def("setGains", [](BiquadBank &b, dpyarray gains) { b.setGains(NpyToCol(gains)); }); bqb.def("filter", [](BiquadBank &b, dpyarray input) { // Yes, a copy here vd inout = NpyToCol(input); b.filter(inout); return ColToNpy(inout); }); /// PowerSpectra py::class_ ps(m, "PowerSpectra"); ps.def(py::init()); ps.def("compute", [](PowerSpectra &ps, dpyarray input) { return CubeToNpy(ps.compute(NpyToMat(input))); }); /// AvPowerSpectra py::class_ aps(m, "AvPowerSpectra"); aps.def(py::init(), py::arg("nfft") = 2048, py::arg("windowType") = Window::WindowType::Hann, py::arg("overlap_percentage") = 50.0, py::arg("time_constant") = -1); aps.def("compute", [](AvPowerSpectra &aps, dpyarray timedata) { std::optional res; { py::gil_scoped_release release; res = aps.compute(NpyToMat(timedata)); } return CubeToNpy(res.value_or(ccube(0, 0, 0))); }); aps.def("get_est", [](const AvPowerSpectra &ps) { ccube est = ps.get_est(); return CubeToNpy(est); }); py::class_ slm(m, "cppSLM"); slm.def_static("fromBiquads", [](const d fs, const d Lref, const us ds, const d tau, dpyarray bandpass) { return SLM::fromBiquads(fs, Lref, ds, tau, NpyToMat(bandpass)); }); slm.def_static("fromBiquads", [](const d fs, const d Lref, const us ds, const d tau, dpyarray prefilter, py::array_t bandpass) { return SLM::fromBiquads(fs, Lref, ds, tau, NpyToCol(prefilter), NpyToMat(bandpass)); }); slm.def("run", [](SLM &slm, dpyarray in) { return MatToNpy(slm.run(NpyToCol(in))); }); slm.def("Pm", [](const SLM &slm) { return ColToNpy(slm.Pm); }); slm.def("Pmax", [](const SLM &slm) { return ColToNpy(slm.Pmax); }); slm.def("Ppeak", [](const SLM &slm) { return ColToNpy(slm.Ppeak); }); slm.def("Leq", [](const SLM &slm) { return ColToNpy(slm.Leq()); }); slm.def("Lmax", [](const SLM &slm) { return ColToNpy(slm.Lmax()); }); slm.def("Lpeak", [](const SLM &slm) { return ColToNpy(slm.Lpeak()); }); slm.def_static("suggestedDownSamplingFac", &SLM::suggestedDownSamplingFac); } /** @} */