xref: /btstack/3rd-party/lc3-google/test/tns_py.c (revision 6897da5c53aac5b1f90f41b5b15d0bd43d61dfff)
14930cef6SMatthias Ringwald /******************************************************************************
24930cef6SMatthias Ringwald  *
34930cef6SMatthias Ringwald  *  Copyright 2022 Google LLC
44930cef6SMatthias Ringwald  *
54930cef6SMatthias Ringwald  *  Licensed under the Apache License, Version 2.0 (the "License");
64930cef6SMatthias Ringwald  *  you may not use this file except in compliance with the License.
74930cef6SMatthias Ringwald  *  You may obtain a copy of the License at:
84930cef6SMatthias Ringwald  *
94930cef6SMatthias Ringwald  *  http://www.apache.org/licenses/LICENSE-2.0
104930cef6SMatthias Ringwald  *
114930cef6SMatthias Ringwald  *  Unless required by applicable law or agreed to in writing, software
124930cef6SMatthias Ringwald  *  distributed under the License is distributed on an "AS IS" BASIS,
134930cef6SMatthias Ringwald  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
144930cef6SMatthias Ringwald  *  See the License for the specific language governing permissions and
154930cef6SMatthias Ringwald  *  limitations under the License.
164930cef6SMatthias Ringwald  *
174930cef6SMatthias Ringwald  ******************************************************************************/
184930cef6SMatthias Ringwald 
194930cef6SMatthias Ringwald #include "lc3.h"
204930cef6SMatthias Ringwald #include <Python.h>
214930cef6SMatthias Ringwald #include <numpy/ndarrayobject.h>
224930cef6SMatthias Ringwald 
234930cef6SMatthias Ringwald #include <tns.c>
244930cef6SMatthias Ringwald #include "ctypes.h"
254930cef6SMatthias Ringwald 
compute_lpc_coeffs_py(PyObject * m,PyObject * args)264930cef6SMatthias Ringwald static PyObject *compute_lpc_coeffs_py(PyObject *m, PyObject *args)
274930cef6SMatthias Ringwald {
284930cef6SMatthias Ringwald     PyObject *x_obj, *a_obj, *g_obj;
294930cef6SMatthias Ringwald     unsigned dt, bw;
304930cef6SMatthias Ringwald     float *x, *g, (*a)[9];
314930cef6SMatthias Ringwald 
324930cef6SMatthias Ringwald     if (!PyArg_ParseTuple(args, "IIO", &dt, &bw, &x_obj))
334930cef6SMatthias Ringwald         return NULL;
344930cef6SMatthias Ringwald 
35*6897da5cSDirk Helbig     CTYPES_CHECK("dt", dt < LC3_NUM_DT);
36*6897da5cSDirk Helbig     CTYPES_CHECK("sr", bw < LC3_NUM_BANDWIDTH);
374930cef6SMatthias Ringwald 
38*6897da5cSDirk Helbig     int ne = lc3_ne(dt, bw);
39*6897da5cSDirk Helbig     int maxorder = dt <= LC3_DT_5M ? 4 : 8;
404930cef6SMatthias Ringwald 
414930cef6SMatthias Ringwald     CTYPES_CHECK("x", to_1d_ptr(x_obj, NPY_FLOAT, ne, &x));
424930cef6SMatthias Ringwald 
434930cef6SMatthias Ringwald     g_obj = new_1d_ptr(NPY_FLOAT, 2, &g);
444930cef6SMatthias Ringwald     a_obj = new_2d_ptr(NPY_FLOAT, 2, 9, &a);
454930cef6SMatthias Ringwald 
46*6897da5cSDirk Helbig     compute_lpc_coeffs(dt, bw, maxorder, x, g, a);
474930cef6SMatthias Ringwald 
484930cef6SMatthias Ringwald     return Py_BuildValue("NN", g_obj, a_obj);
494930cef6SMatthias Ringwald }
504930cef6SMatthias Ringwald 
lpc_reflection_py(PyObject * m,PyObject * args)514930cef6SMatthias Ringwald static PyObject *lpc_reflection_py(PyObject *m, PyObject *args)
524930cef6SMatthias Ringwald {
534930cef6SMatthias Ringwald     PyObject *a_obj, *rc_obj;
54*6897da5cSDirk Helbig     unsigned dt;
554930cef6SMatthias Ringwald     float *a, *rc;
564930cef6SMatthias Ringwald 
57*6897da5cSDirk Helbig     if (!PyArg_ParseTuple(args, "IO", &dt, &a_obj))
584930cef6SMatthias Ringwald         return NULL;
594930cef6SMatthias Ringwald 
60*6897da5cSDirk Helbig     CTYPES_CHECK("dt", dt < LC3_NUM_DT);
614930cef6SMatthias Ringwald 
62*6897da5cSDirk Helbig     int maxorder = dt <= LC3_DT_5M ? 4 : 8;
63*6897da5cSDirk Helbig 
64*6897da5cSDirk Helbig     CTYPES_CHECK("a", to_1d_ptr(a_obj, NPY_FLOAT, 9, &a));
65*6897da5cSDirk Helbig     rc_obj = new_1d_ptr(NPY_FLOAT, maxorder, &rc);
66*6897da5cSDirk Helbig 
67*6897da5cSDirk Helbig     lpc_reflection(a, maxorder, rc);
684930cef6SMatthias Ringwald 
694930cef6SMatthias Ringwald     return Py_BuildValue("N", rc_obj);
704930cef6SMatthias Ringwald }
714930cef6SMatthias Ringwald 
quantize_rc_py(PyObject * m,PyObject * args)724930cef6SMatthias Ringwald static PyObject *quantize_rc_py(PyObject *m, PyObject *args)
734930cef6SMatthias Ringwald {
744930cef6SMatthias Ringwald     PyObject *rc_obj, *rc_q_obj;
75*6897da5cSDirk Helbig     unsigned dt;
764930cef6SMatthias Ringwald     float *rc;
774930cef6SMatthias Ringwald     int rc_order, *rc_q;
784930cef6SMatthias Ringwald 
79*6897da5cSDirk Helbig     if (!PyArg_ParseTuple(args, "iO", &dt, &rc_obj))
804930cef6SMatthias Ringwald         return NULL;
814930cef6SMatthias Ringwald 
82*6897da5cSDirk Helbig     CTYPES_CHECK("dt", dt < LC3_NUM_DT);
834930cef6SMatthias Ringwald 
84*6897da5cSDirk Helbig     int maxorder = dt <= LC3_DT_5M ? 4 : 8;
85*6897da5cSDirk Helbig 
86*6897da5cSDirk Helbig     CTYPES_CHECK("rc", to_1d_ptr(rc_obj, NPY_FLOAT, 8, &rc));
874930cef6SMatthias Ringwald     rc_q_obj = new_1d_ptr(NPY_INT, 8, &rc_q);
884930cef6SMatthias Ringwald 
89*6897da5cSDirk Helbig     quantize_rc(rc, maxorder, &rc_order, rc_q);
904930cef6SMatthias Ringwald 
914930cef6SMatthias Ringwald     return Py_BuildValue("iN", rc_order, rc_q_obj);
924930cef6SMatthias Ringwald }
934930cef6SMatthias Ringwald 
unquantize_rc_py(PyObject * m,PyObject * args)944930cef6SMatthias Ringwald static PyObject *unquantize_rc_py(PyObject *m, PyObject *args)
954930cef6SMatthias Ringwald {
964930cef6SMatthias Ringwald     PyObject *rc_q_obj, *rc_obj;
974930cef6SMatthias Ringwald     int rc_order, *rc_q;
984930cef6SMatthias Ringwald     float *rc;
994930cef6SMatthias Ringwald 
1004930cef6SMatthias Ringwald     if (!PyArg_ParseTuple(args, "OI", &rc_q_obj, &rc_order))
1014930cef6SMatthias Ringwald         return NULL;
1024930cef6SMatthias Ringwald 
1034930cef6SMatthias Ringwald     CTYPES_CHECK("rc_q", to_1d_ptr(rc_q_obj, NPY_INT, 8, &rc_q));
1044930cef6SMatthias Ringwald     CTYPES_CHECK("rc_order", (unsigned)rc_order <= 8);
1054930cef6SMatthias Ringwald 
1064930cef6SMatthias Ringwald     rc_obj = new_1d_ptr(NPY_FLOAT, 8, &rc);
1074930cef6SMatthias Ringwald 
1084930cef6SMatthias Ringwald     unquantize_rc(rc_q, rc_order, rc);
1094930cef6SMatthias Ringwald 
1104930cef6SMatthias Ringwald     return Py_BuildValue("N", rc_obj);
1114930cef6SMatthias Ringwald }
1124930cef6SMatthias Ringwald 
analyze_py(PyObject * m,PyObject * args)1134930cef6SMatthias Ringwald static PyObject *analyze_py(PyObject *m, PyObject *args)
1144930cef6SMatthias Ringwald {
1154930cef6SMatthias Ringwald     PyObject *x_obj;
1164930cef6SMatthias Ringwald     struct lc3_tns_data data = { 0 };
1174930cef6SMatthias Ringwald     unsigned dt, bw;
118*6897da5cSDirk Helbig     int nn_flag, nbytes;
1194930cef6SMatthias Ringwald     float *x;
1204930cef6SMatthias Ringwald 
121*6897da5cSDirk Helbig     if (!PyArg_ParseTuple(args, "IIpiO",
122*6897da5cSDirk Helbig             &dt, &bw, &nn_flag, &nbytes, &x_obj))
1234930cef6SMatthias Ringwald         return NULL;
1244930cef6SMatthias Ringwald 
125*6897da5cSDirk Helbig     CTYPES_CHECK("dt", dt < LC3_NUM_DT);
126*6897da5cSDirk Helbig     CTYPES_CHECK("bw", bw < LC3_NUM_BANDWIDTH);
1274930cef6SMatthias Ringwald 
128*6897da5cSDirk Helbig     int ne = lc3_ne(dt, bw);
1294930cef6SMatthias Ringwald 
1304930cef6SMatthias Ringwald     CTYPES_CHECK("x", x_obj = to_1d_ptr(x_obj, NPY_FLOAT, ne, &x));
1314930cef6SMatthias Ringwald 
1324930cef6SMatthias Ringwald     lc3_tns_analyze(dt, bw, nn_flag, nbytes, &data, x);
1334930cef6SMatthias Ringwald 
1344930cef6SMatthias Ringwald     return Py_BuildValue("ON", x_obj, new_tns_data(&data));
1354930cef6SMatthias Ringwald }
1364930cef6SMatthias Ringwald 
synthesize_py(PyObject * m,PyObject * args)1374930cef6SMatthias Ringwald static PyObject *synthesize_py(PyObject *m, PyObject *args)
1384930cef6SMatthias Ringwald {
1394930cef6SMatthias Ringwald     PyObject *data_obj, *x_obj;
1404930cef6SMatthias Ringwald     unsigned dt, bw;
1414930cef6SMatthias Ringwald     struct lc3_tns_data data;
1424930cef6SMatthias Ringwald     float *x;
1434930cef6SMatthias Ringwald 
1444930cef6SMatthias Ringwald     if (!PyArg_ParseTuple(args, "IIOO", &dt, &bw, &data_obj, &x_obj))
1454930cef6SMatthias Ringwald         return NULL;
1464930cef6SMatthias Ringwald 
147*6897da5cSDirk Helbig     CTYPES_CHECK("dt", dt < LC3_NUM_DT);
148*6897da5cSDirk Helbig     CTYPES_CHECK("bw", bw < LC3_NUM_BANDWIDTH);
1494930cef6SMatthias Ringwald     CTYPES_CHECK(NULL, data_obj = to_tns_data(data_obj, &data));
1504930cef6SMatthias Ringwald 
151*6897da5cSDirk Helbig     int ne = lc3_ne(dt, bw);
1524930cef6SMatthias Ringwald 
1534930cef6SMatthias Ringwald     CTYPES_CHECK("x", x_obj = to_1d_ptr(x_obj, NPY_FLOAT, ne, &x));
1544930cef6SMatthias Ringwald 
1554930cef6SMatthias Ringwald     lc3_tns_synthesize(dt, bw, &data, x);
1564930cef6SMatthias Ringwald 
1574930cef6SMatthias Ringwald     return Py_BuildValue("O", x_obj);
1584930cef6SMatthias Ringwald }
1594930cef6SMatthias Ringwald 
get_nbits_py(PyObject * m,PyObject * args)1604930cef6SMatthias Ringwald static PyObject *get_nbits_py(PyObject *m, PyObject *args)
1614930cef6SMatthias Ringwald {
1624930cef6SMatthias Ringwald     PyObject *data_obj;
1634930cef6SMatthias Ringwald     struct lc3_tns_data data = { 0 };
1644930cef6SMatthias Ringwald 
1654930cef6SMatthias Ringwald     if (!PyArg_ParseTuple(args, "O", &data_obj))
1664930cef6SMatthias Ringwald         return NULL;
1674930cef6SMatthias Ringwald 
1684930cef6SMatthias Ringwald     CTYPES_CHECK("data", to_tns_data(data_obj, &data));
1694930cef6SMatthias Ringwald 
1704930cef6SMatthias Ringwald     int nbits = lc3_tns_get_nbits(&data);
1714930cef6SMatthias Ringwald 
1724930cef6SMatthias Ringwald     return Py_BuildValue("i", nbits);
1734930cef6SMatthias Ringwald }
1744930cef6SMatthias Ringwald 
1754930cef6SMatthias Ringwald static PyMethodDef methods[] = {
1764930cef6SMatthias Ringwald     { "tns_compute_lpc_coeffs", compute_lpc_coeffs_py, METH_VARARGS },
1774930cef6SMatthias Ringwald     { "tns_lpc_reflection"    , lpc_reflection_py    , METH_VARARGS },
1784930cef6SMatthias Ringwald     { "tns_quantize_rc"       , quantize_rc_py       , METH_VARARGS },
1794930cef6SMatthias Ringwald     { "tns_unquantize_rc"     , unquantize_rc_py     , METH_VARARGS },
1804930cef6SMatthias Ringwald     { "tns_analyze"           , analyze_py           , METH_VARARGS },
1814930cef6SMatthias Ringwald     { "tns_synthesize"        , synthesize_py        , METH_VARARGS },
1824930cef6SMatthias Ringwald     { "tns_get_nbits"         , get_nbits_py         , METH_VARARGS },
1834930cef6SMatthias Ringwald     { NULL },
1844930cef6SMatthias Ringwald };
1854930cef6SMatthias Ringwald 
lc3_tns_py_init(PyObject * m)1864930cef6SMatthias Ringwald PyMODINIT_FUNC lc3_tns_py_init(PyObject *m)
1874930cef6SMatthias Ringwald {
1884930cef6SMatthias Ringwald     import_array();
1894930cef6SMatthias Ringwald 
1904930cef6SMatthias Ringwald     PyModule_AddFunctions(m, methods);
1914930cef6SMatthias Ringwald 
1924930cef6SMatthias Ringwald     return m;
1934930cef6SMatthias Ringwald }
194