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