1 // ----------------------------------------------------------------------------
2 //
3 // Copyright (C) 2012-2020 Fons Adriaensen <fons@linuxaudio.org>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // ----------------------------------------------------------------------------
19
20
21 #include <Python.h>
22 #include "jmatconv.h"
23
24
25 static const char *capslabel = "Jmatconv";
26
27
destroy(PyObject * P)28 extern "C" void destroy (PyObject *P)
29 {
30 delete (Jmatconv *) PyCapsule_GetPointer (P, capslabel);
31 }
32
33
makecaps(PyObject * self,PyObject * args)34 extern "C" PyObject* makecaps (PyObject *self, PyObject *args)
35 {
36 Jmatconv *J;
37 PyObject *P;
38 int size, ninp, nout, nthr;
39 const char *client_name;
40 const char *server_name;
41
42 if (! PyArg_ParseTuple (args, "Osziiii", &P, &client_name, &server_name,
43 &size, &ninp, &nout, &nthr)) return NULL;
44 J = new Jmatconv (client_name, server_name, size, ninp, nout, nthr);
45 return Py_BuildValue ("NN",
46 PyCapsule_New ((void *) J, capslabel, destroy),
47 PyCapsule_New (dynamic_cast<Jclient *>(J), "Jclient", 0));
48 }
49
50
set_state(PyObject * self,PyObject * args)51 extern "C" PyObject* set_state (PyObject *self, PyObject *args)
52 {
53 Jmatconv *J;
54 PyObject *P;
55 int state;
56
57 if (! PyArg_ParseTuple(args, "Oi", &P, &state)) return NULL;
58 J = (Jmatconv *) PyCapsule_GetPointer (P, capslabel);
59 J->set_state (state);
60 Py_RETURN_NONE;
61 }
62
63
check_format(Py_buffer * B)64 static int check_format (Py_buffer *B)
65 {
66 if (strcmp (B->format, "f"))
67 {
68 PyErr_SetString (PyExc_TypeError, "Data type must be float32");
69 return 1;
70 }
71 if (B->ndim != 1)
72 {
73 PyErr_SetString (PyExc_TypeError, "Array must be single dimension");
74 return 1;
75 }
76 return 0;
77 }
78
79
load_impulse(PyObject * self,PyObject * args)80 extern "C" PyObject* load_impulse (PyObject *self, PyObject *args)
81 {
82 Jmatconv *J;
83 PyObject *P, *Q;
84 Py_buffer B;
85 int inp, out, rv;
86 float gain;
87
88 if (! PyArg_ParseTuple (args, "OOiif", &P, &Q, &inp, &out, &gain)) return 0;
89 J = (Jmatconv *) PyCapsule_GetPointer (P, capslabel);
90 if (Q == Py_None) rv = J->convproc ()->setimp (inp, out, 0.0f, 0, 0, 0);
91 else
92 {
93 if (PyObject_GetBuffer (Q, &B, PyBUF_FULL_RO)) return 0;
94 if (check_format (&B))
95 {
96 PyBuffer_Release (&B);
97 return 0;
98
99 }
100 rv = J->convproc ()->setimp (inp, out, gain, (float *)(B.buf), B.shape [0], B.strides [0] / sizeof (float));
101 PyBuffer_Release (&B);
102 }
103 return Py_BuildValue ("i", rv);
104 }
105
106
107 static PyMethodDef JackMatconvMethods[] =
108 {
109 {"makecaps", makecaps, METH_VARARGS, "Create object capsules."},
110 {"set_state", set_state, METH_VARARGS, "Set new state."},
111 {"load_impulse", load_impulse, METH_VARARGS, "Load single impulse."},
112 {NULL, NULL, 0, NULL}
113 };
114
115
116
117 #if PY_VERSION_HEX >= 0x03000000
118
119 static struct PyModuleDef JackMatconvModule =
120 {
121 PyModuleDef_HEAD_INIT,
122 "jackmatconv_ext",
123 NULL,
124 -1,
125 JackMatconvMethods
126 };
127
PyInit_jackmatconv_ext(void)128 PyMODINIT_FUNC PyInit_jackmatconv_ext(void)
129 {
130 return PyModule_Create(&JackMatconvModule);
131 }
132
133 #else
134
initjackmatconv_ext(void)135 PyMODINIT_FUNC initjackmatconv_ext(void)
136 {
137 (void) Py_InitModule("jackmatconv_ext", JackMatconvMethods);
138 }
139
140 #endif
141