1 // ----------------------------------------------------------------------------
2 //
3 //  Copyright (C) 2008-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 "jkmeter.h"
23 
24 
25 static const char *capslabel = "Jkmeter";
26 
27 
checkbuff(PyObject * P,int nchan)28 static float *checkbuff (PyObject *P, int nchan)
29 {
30     Py_buffer B;
31     float    *F = 0;
32 
33     if (   PyObject_CheckBuffer (P)
34 	&& (PyObject_GetBuffer(P, &B, PyBUF_FULL) == 0)
35         && (B.ndim == 1)
36         && (B.shape [0] == nchan)
37         && (B.strides [0] == sizeof (float))) F = (float *)(B.buf);
38     // The Python code MUS NOT DELETE this object !!
39     PyBuffer_Release (&B);
40     return F;
41 }
42 
43 
destroy(PyObject * P)44 extern "C" void destroy (PyObject *P)
45 {
46     delete (Jkmeter *) PyCapsule_GetPointer (P, capslabel);
47 }
48 
49 
makecaps(PyObject * self,PyObject * args)50 extern "C" PyObject* makecaps (PyObject *self, PyObject *args)
51 {
52     Jkmeter  *J;
53     PyObject *P, *Prms, *Ppks;
54     const char *client_name;
55     const char *server_name;
56     int   nchan;
57     float *rms;
58     float *pks;
59 
60     if (! PyArg_ParseTuple(args, "OsziOO", &P, &client_name, &server_name, &nchan, &Prms, &Ppks)) return 0;
61     rms = checkbuff (Prms, nchan);
62     pks = checkbuff (Ppks, nchan);
63     if (!rms || !pks) return 0;
64     J = new Jkmeter (client_name, server_name, nchan, rms, pks);
65     return Py_BuildValue ("NN",
66 			  PyCapsule_New (J, capslabel, destroy),
67                           PyCapsule_New (dynamic_cast<Jclient *>(J), "Jclient", 0));
68 }
69 
70 
get_levels(PyObject * self,PyObject * args)71 extern "C" PyObject* get_levels (PyObject *self, PyObject *args)
72 {
73     Jkmeter  *J;
74     PyObject *P;
75 
76     if (! PyArg_ParseTuple(args, "O", &P)) return 0;
77     J = (Jkmeter *) PyCapsule_GetPointer (P, capslabel);
78     return Py_BuildValue ("i", J->get_levels ());
79 }
80 
81 
82 static PyMethodDef JackKmeterMethods[] =
83 {
84     {"makecaps",      makecaps,     METH_VARARGS, "Create object capsules."},
85     {"get_levels",    get_levels,   METH_VARARGS, "Get current state and levels."},
86     {NULL, NULL, 0, NULL}
87 };
88 
89 
90 
91 #if PY_VERSION_HEX >= 0x03000000
92 
93 static struct PyModuleDef JackKmeterModule =
94 {
95    PyModuleDef_HEAD_INIT,
96    "jackkmeter_ext",
97    NULL,
98    -1,
99    JackKmeterMethods
100 };
101 
PyInit_jackkmeter_ext(void)102 PyMODINIT_FUNC PyInit_jackkmeter_ext(void)
103 {
104     return PyModule_Create(&JackKmeterModule);
105 }
106 
107 #else
108 
initjackkmeter_ext(void)109 PyMODINIT_FUNC initjackkmeter_ext(void)
110 {
111     (void) Py_InitModule("jackkmeter_ext", JackKmeterMethods);
112 }
113 
114 #endif
115