Add experimental Python bindings
This commit adds some experimental Python bindings. These likely need some further refinement in the building/deployment area, but should serve as a useful testbed for experimentation and interactive analysis of filters and the library's behaviour.
This commit is contained in:
parent
911b3eab3d
commit
5681c97b4e
|
@ -0,0 +1,5 @@
|
||||||
|
.ipynb_checkpoints/
|
||||||
|
__pycache__/
|
||||||
|
build/
|
||||||
|
iir.py
|
||||||
|
pyiir_wrap.cxx
|
|
@ -0,0 +1,25 @@
|
||||||
|
Experimental Python bindings
|
||||||
|
============================
|
||||||
|
|
||||||
|
These bindings are currently experimental, as it is not yet clear how best
|
||||||
|
to create and maintain them. They are built upon the C++ interface as the
|
||||||
|
object oriented nature of it sits much better with Python.
|
||||||
|
|
||||||
|
At present, it is necessary to compile and install the C++ library before
|
||||||
|
working with the bindings.
|
||||||
|
|
||||||
|
To generate the bindings, swig 3.0.2 has been used, but earlier versions
|
||||||
|
may work too:
|
||||||
|
|
||||||
|
swig -c++ -python -py3 pyiir.i
|
||||||
|
|
||||||
|
To build the extension, distutils is used:
|
||||||
|
|
||||||
|
python3 setup.py build_ext
|
||||||
|
|
||||||
|
Note that the -L ${LIBDIR} option may be handy if libiir++ is not installed
|
||||||
|
into the system library path.
|
||||||
|
|
||||||
|
To install the extension:
|
||||||
|
|
||||||
|
python3 setup.py install
|
|
@ -0,0 +1 @@
|
||||||
|
../obj/iir++.h
|
|
@ -0,0 +1,130 @@
|
||||||
|
%module iir
|
||||||
|
%include <complex.i>
|
||||||
|
|
||||||
|
%{
|
||||||
|
#include "iir++.h"
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add bounds checking
|
||||||
|
*
|
||||||
|
* The Python library is targetted at experimentation. It is therefore
|
||||||
|
* reasonable to protect its object query and creation interfaces with code
|
||||||
|
* that performs bounds checking on arguments.
|
||||||
|
*/
|
||||||
|
%exception IIR::Coeff::c {
|
||||||
|
if(arg2 < 0 || arg2 >= arg1->nc()) {
|
||||||
|
char buf[80];
|
||||||
|
snprintf(buf, sizeof(buf), "Index of c coefficient (%d) out of bounds "
|
||||||
|
"(0,%d).", arg2, arg1->nc() - 1);
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
$action
|
||||||
|
}
|
||||||
|
|
||||||
|
%exception IIR::Coeff::d {
|
||||||
|
if(arg2 < 0 || arg2 >= arg1->nd()) {
|
||||||
|
char buf[80];
|
||||||
|
snprintf(buf, sizeof(buf), "Index of d coefficient (%d) out of bounds "
|
||||||
|
"(0,%d).", arg2, arg1->nd() - 1);
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
$action
|
||||||
|
}
|
||||||
|
|
||||||
|
%exception IIR::Filter::getCoeffSet {
|
||||||
|
if(arg2 < 0 || arg2 >= arg1->numCoeffSet()) {
|
||||||
|
char buf[80];
|
||||||
|
snprintf(buf, sizeof(buf), "Index of coefficient set (%d) out of bounds "
|
||||||
|
"(0,%d).", arg2, arg1->numCoeffSet() - 1);
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
$action
|
||||||
|
}
|
||||||
|
|
||||||
|
%exception IIR::ButterworthLowPass {
|
||||||
|
if(arg1 < 1) {
|
||||||
|
char buf[80];
|
||||||
|
snprintf(buf, sizeof(buf), "Invalid filter order (%d). Must be > 0.",
|
||||||
|
arg1);
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
$action
|
||||||
|
}
|
||||||
|
|
||||||
|
%exception IIR::ButterworthHighPass {
|
||||||
|
if(arg1 < 1) {
|
||||||
|
char buf[80];
|
||||||
|
snprintf(buf, sizeof(buf), "Invalid filter order (%d). Must be > 0.",
|
||||||
|
arg1);
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
$action
|
||||||
|
}
|
||||||
|
|
||||||
|
%exception IIR::ButterworthBandPass {
|
||||||
|
if(arg1 < 1) {
|
||||||
|
char buf[80];
|
||||||
|
snprintf(buf, sizeof(buf), "Invalid filter order (%d). Must be > 0.",
|
||||||
|
arg1);
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(arg3 > arg4) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, "Low corner frequency exceeds "
|
||||||
|
"high corner frequency.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
$action
|
||||||
|
}
|
||||||
|
|
||||||
|
%exception IIR::ButterworthBandStop {
|
||||||
|
if(arg1 < 1) {
|
||||||
|
char buf[80];
|
||||||
|
snprintf(buf, sizeof(buf), "Invalid filter order (%d). Must be > 0.",
|
||||||
|
arg1);
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(arg3 > arg4) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, "Low corner frequency exceeds "
|
||||||
|
"high corner frequency.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
$action
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Invalid filter string handling
|
||||||
|
*
|
||||||
|
* The C++ library uses a "valid()" member in IIR::Filter to avoid throwing an
|
||||||
|
* exception if the constructor is passed an invalid filter string. Python's
|
||||||
|
* exceptions are a much nicer fit, however, so use those instead.
|
||||||
|
*
|
||||||
|
* Notes:
|
||||||
|
* 1. Doesn't match if we prepend it with the namespace.
|
||||||
|
* 2. Applies to all constructors.
|
||||||
|
*/
|
||||||
|
%exception Filter {
|
||||||
|
$action
|
||||||
|
if(!result->valid()) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, "Invalid filter description string.");
|
||||||
|
delete result;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%include "iir++.h"
|
||||||
|
|
||||||
|
// vim: ts=4:sw=4
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from distutils.core import setup, Extension
|
||||||
|
|
||||||
|
iir_module = Extension('_iir',
|
||||||
|
sources=['pyiir_wrap.cxx'],
|
||||||
|
libraries=['iir++'],
|
||||||
|
)
|
||||||
|
|
||||||
|
setup(name = 'iir',
|
||||||
|
version = '1.0.3',
|
||||||
|
author = 'Laurence Withers',
|
||||||
|
description = 'IIR filter',
|
||||||
|
ext_modules = [iir_module],
|
||||||
|
py_modules = ['iir'],
|
||||||
|
)
|
Loading…
Reference in New Issue