xref: /btstack/3rd-party/lc3-google/test/sns_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 <sns.c>
244930cef6SMatthias Ringwald #include "ctypes.h"
254930cef6SMatthias Ringwald 
compute_scale_factors_py(PyObject * m,PyObject * args)264930cef6SMatthias Ringwald static PyObject *compute_scale_factors_py(PyObject *m, PyObject *args)
274930cef6SMatthias Ringwald {
284930cef6SMatthias Ringwald     unsigned dt, sr;
29*6897da5cSDirk Helbig     int nbytes, att;
304930cef6SMatthias Ringwald     PyObject *eb_obj, *scf_obj;
314930cef6SMatthias Ringwald     float *eb, *scf;
324930cef6SMatthias Ringwald 
33*6897da5cSDirk Helbig     if (!PyArg_ParseTuple(args, "IIiOp", &dt, &sr, &nbytes, &eb_obj, &att))
344930cef6SMatthias Ringwald         return NULL;
354930cef6SMatthias Ringwald 
36*6897da5cSDirk Helbig     CTYPES_CHECK("dt", dt < LC3_NUM_DT);
37*6897da5cSDirk Helbig     CTYPES_CHECK("sr", sr < LC3_NUM_SRATE);
384930cef6SMatthias Ringwald 
39*6897da5cSDirk Helbig     int nb = lc3_num_bands[dt][sr];
404930cef6SMatthias Ringwald 
414930cef6SMatthias Ringwald     CTYPES_CHECK("eb", to_1d_ptr(eb_obj, NPY_FLOAT, nb, &eb));
424930cef6SMatthias Ringwald     scf_obj = new_1d_ptr(NPY_FLOAT, 16, &scf);
434930cef6SMatthias Ringwald 
44*6897da5cSDirk Helbig     compute_scale_factors(dt, sr, nbytes, eb, att, scf);
454930cef6SMatthias Ringwald 
464930cef6SMatthias Ringwald     return Py_BuildValue("N", scf_obj);
474930cef6SMatthias Ringwald }
484930cef6SMatthias Ringwald 
resolve_codebooks_py(PyObject * m,PyObject * args)494930cef6SMatthias Ringwald static PyObject *resolve_codebooks_py(PyObject *m, PyObject *args)
504930cef6SMatthias Ringwald {
514930cef6SMatthias Ringwald     PyObject *scf_obj;
524930cef6SMatthias Ringwald     float *scf;
534930cef6SMatthias Ringwald     int lfcb_idx, hfcb_idx;
544930cef6SMatthias Ringwald 
554930cef6SMatthias Ringwald     if (!PyArg_ParseTuple(args, "O", &scf_obj))
564930cef6SMatthias Ringwald         return NULL;
574930cef6SMatthias Ringwald 
584930cef6SMatthias Ringwald     CTYPES_CHECK("eb", to_1d_ptr(scf_obj, NPY_FLOAT, 16, &scf));
594930cef6SMatthias Ringwald 
604930cef6SMatthias Ringwald     resolve_codebooks(scf, &lfcb_idx, &hfcb_idx);
614930cef6SMatthias Ringwald 
624930cef6SMatthias Ringwald     return Py_BuildValue("ii", lfcb_idx, hfcb_idx);
634930cef6SMatthias Ringwald }
644930cef6SMatthias Ringwald 
quantize_py(PyObject * m,PyObject * args)654930cef6SMatthias Ringwald static PyObject *quantize_py(PyObject *m, PyObject *args)
664930cef6SMatthias Ringwald {
674930cef6SMatthias Ringwald     PyObject *scf_obj, *y_obj, *yn_obj;
684930cef6SMatthias Ringwald     float *scf;
69*6897da5cSDirk Helbig 
704930cef6SMatthias Ringwald     int lfcb_idx, hfcb_idx;
714930cef6SMatthias Ringwald     int shape_idx, gain_idx;
724930cef6SMatthias Ringwald     float (*yn)[16];
734930cef6SMatthias Ringwald     int (*y)[16];
744930cef6SMatthias Ringwald 
754930cef6SMatthias Ringwald     if (!PyArg_ParseTuple(args, "Oii", &scf_obj, &lfcb_idx, &hfcb_idx))
764930cef6SMatthias Ringwald         return NULL;
774930cef6SMatthias Ringwald 
784930cef6SMatthias Ringwald     CTYPES_CHECK("scf", to_1d_ptr(scf_obj, NPY_FLOAT, 16, &scf));
794930cef6SMatthias Ringwald     CTYPES_CHECK("lfcb_idx", (unsigned)lfcb_idx < 32);
804930cef6SMatthias Ringwald     CTYPES_CHECK("hfcb_idx", (unsigned)hfcb_idx < 32);
814930cef6SMatthias Ringwald 
824930cef6SMatthias Ringwald     y_obj = new_2d_ptr(NPY_INT, 4, 16, &y);
834930cef6SMatthias Ringwald     yn_obj = new_2d_ptr(NPY_FLOAT, 4, 16, &yn);
844930cef6SMatthias Ringwald 
854930cef6SMatthias Ringwald     quantize(scf, lfcb_idx, hfcb_idx,
864930cef6SMatthias Ringwald         y, yn, &shape_idx, &gain_idx);
874930cef6SMatthias Ringwald 
884930cef6SMatthias Ringwald     return Py_BuildValue("NNii", y_obj, yn_obj, shape_idx, gain_idx);
894930cef6SMatthias Ringwald }
904930cef6SMatthias Ringwald 
unquantize_py(PyObject * m,PyObject * args)914930cef6SMatthias Ringwald static PyObject *unquantize_py(PyObject *m, PyObject *args)
924930cef6SMatthias Ringwald {
934930cef6SMatthias Ringwald     PyObject *y_obj, *scf_obj;
944930cef6SMatthias Ringwald     int lfcb_idx, hfcb_idx;
954930cef6SMatthias Ringwald     int shape, gain;
964930cef6SMatthias Ringwald     float *y, *scf;
974930cef6SMatthias Ringwald 
984930cef6SMatthias Ringwald     if (!PyArg_ParseTuple(args, "iiOii",
994930cef6SMatthias Ringwald                 &lfcb_idx, &hfcb_idx, &y_obj, &shape, &gain))
1004930cef6SMatthias Ringwald         return NULL;
1014930cef6SMatthias Ringwald 
1024930cef6SMatthias Ringwald     CTYPES_CHECK("lfcb_idx", (unsigned)lfcb_idx < 32);
1034930cef6SMatthias Ringwald     CTYPES_CHECK("hfcb_idx", (unsigned)hfcb_idx < 32);
1044930cef6SMatthias Ringwald     CTYPES_CHECK("y", to_1d_ptr(y_obj, NPY_FLOAT, 16, &y));
1054930cef6SMatthias Ringwald     CTYPES_CHECK("shape", (unsigned)shape < 4);
1064930cef6SMatthias Ringwald     CTYPES_CHECK("gain",
1074930cef6SMatthias Ringwald         (unsigned)gain < (unsigned)lc3_sns_vq_gains[shape].count);
1084930cef6SMatthias Ringwald 
1094930cef6SMatthias Ringwald     scf_obj = new_1d_ptr(NPY_FLOAT, 16, &scf);
1104930cef6SMatthias Ringwald 
1114930cef6SMatthias Ringwald     unquantize(lfcb_idx, hfcb_idx, y, shape, gain, scf);
1124930cef6SMatthias Ringwald 
1134930cef6SMatthias Ringwald     return Py_BuildValue("N", scf_obj);
1144930cef6SMatthias Ringwald }
1154930cef6SMatthias Ringwald 
spectral_shaping_py(PyObject * m,PyObject * args)1164930cef6SMatthias Ringwald static PyObject *spectral_shaping_py(PyObject *m, PyObject *args)
1174930cef6SMatthias Ringwald {
1184930cef6SMatthias Ringwald     PyObject *scf_q_obj, *x_obj;
1194930cef6SMatthias Ringwald     unsigned dt, sr;
1204930cef6SMatthias Ringwald     float *scf_q, *x;
1214930cef6SMatthias Ringwald     int inv;
1224930cef6SMatthias Ringwald 
1234930cef6SMatthias Ringwald     if (!PyArg_ParseTuple(args, "IIOpO", &dt, &sr, &scf_q_obj, &inv, &x_obj))
1244930cef6SMatthias Ringwald         return NULL;
1254930cef6SMatthias Ringwald 
126*6897da5cSDirk Helbig     CTYPES_CHECK("dt", dt < LC3_NUM_DT);
127*6897da5cSDirk Helbig     CTYPES_CHECK("sr", sr < LC3_NUM_SRATE);
1284930cef6SMatthias Ringwald 
129*6897da5cSDirk Helbig     int ne = lc3_ne(dt, sr);
1304930cef6SMatthias Ringwald 
1314930cef6SMatthias Ringwald     CTYPES_CHECK("scf_q", to_1d_ptr(scf_q_obj, NPY_FLOAT, 16, &scf_q));
1324930cef6SMatthias Ringwald     CTYPES_CHECK("x", x_obj = to_1d_ptr(x_obj, NPY_FLOAT, ne, &x));
1334930cef6SMatthias Ringwald 
1344930cef6SMatthias Ringwald     spectral_shaping(dt, sr, scf_q, inv, x, x);
1354930cef6SMatthias Ringwald 
1364930cef6SMatthias Ringwald     return Py_BuildValue("O", x_obj);
1374930cef6SMatthias Ringwald }
1384930cef6SMatthias Ringwald 
analyze_py(PyObject * m,PyObject * args)1394930cef6SMatthias Ringwald static PyObject *analyze_py(PyObject *m, PyObject *args)
1404930cef6SMatthias Ringwald {
1414930cef6SMatthias Ringwald     PyObject *eb_obj, *x_obj;
1424930cef6SMatthias Ringwald     struct lc3_sns_data data = { 0 };
1434930cef6SMatthias Ringwald     unsigned dt, sr;
144*6897da5cSDirk Helbig     int nbytes, att;
1454930cef6SMatthias Ringwald     float *eb, *x;
1464930cef6SMatthias Ringwald 
147*6897da5cSDirk Helbig     if (!PyArg_ParseTuple(args, "IIiOpO",
148*6897da5cSDirk Helbig             &dt, &sr, &nbytes, &eb_obj, &att, &x_obj))
1494930cef6SMatthias Ringwald         return NULL;
1504930cef6SMatthias Ringwald 
151*6897da5cSDirk Helbig     CTYPES_CHECK("dt", dt < LC3_NUM_DT);
152*6897da5cSDirk Helbig     CTYPES_CHECK("sr", sr < LC3_NUM_SRATE);
1534930cef6SMatthias Ringwald 
154*6897da5cSDirk Helbig     int ne = lc3_ne(dt, sr);
155*6897da5cSDirk Helbig     int nb = lc3_num_bands[dt][sr];
1564930cef6SMatthias Ringwald 
1574930cef6SMatthias Ringwald     CTYPES_CHECK("eb", to_1d_ptr(eb_obj, NPY_FLOAT, nb, &eb));
1584930cef6SMatthias Ringwald     CTYPES_CHECK("x", x_obj = to_1d_ptr(x_obj, NPY_FLOAT, ne, &x));
1594930cef6SMatthias Ringwald 
160*6897da5cSDirk Helbig     lc3_sns_analyze(dt, sr, nbytes, eb, att, &data, x, x);
1614930cef6SMatthias Ringwald 
1624930cef6SMatthias Ringwald     return Py_BuildValue("ON", x_obj, new_sns_data(&data));
1634930cef6SMatthias Ringwald }
1644930cef6SMatthias Ringwald 
synthesize_py(PyObject * m,PyObject * args)1654930cef6SMatthias Ringwald static PyObject *synthesize_py(PyObject *m, PyObject *args)
1664930cef6SMatthias Ringwald {
1674930cef6SMatthias Ringwald     PyObject *data_obj, *x_obj;
1684930cef6SMatthias Ringwald     struct lc3_sns_data data;
1694930cef6SMatthias Ringwald     unsigned dt, sr;
1704930cef6SMatthias Ringwald     float *x;
1714930cef6SMatthias Ringwald 
1724930cef6SMatthias Ringwald     if (!PyArg_ParseTuple(args, "IIOO", &dt, &sr, &data_obj, &x_obj))
1734930cef6SMatthias Ringwald         return NULL;
1744930cef6SMatthias Ringwald 
175*6897da5cSDirk Helbig     CTYPES_CHECK("dt", dt < LC3_NUM_DT);
176*6897da5cSDirk Helbig     CTYPES_CHECK("sr", sr < LC3_NUM_SRATE);
1774930cef6SMatthias Ringwald     CTYPES_CHECK(NULL, data_obj = to_sns_data(data_obj, &data));
1784930cef6SMatthias Ringwald 
179*6897da5cSDirk Helbig     int ne = lc3_ne(dt, sr);
1804930cef6SMatthias Ringwald 
1814930cef6SMatthias Ringwald     CTYPES_CHECK("x", x_obj = to_1d_ptr(x_obj, NPY_FLOAT, ne, &x));
1824930cef6SMatthias Ringwald 
1834930cef6SMatthias Ringwald     lc3_sns_synthesize(dt, sr, &data, x, x);
1844930cef6SMatthias Ringwald 
1854930cef6SMatthias Ringwald     return Py_BuildValue("O", x_obj);
1864930cef6SMatthias Ringwald }
1874930cef6SMatthias Ringwald 
get_nbits_py(PyObject * m,PyObject * args)1884930cef6SMatthias Ringwald static PyObject *get_nbits_py(PyObject *m, PyObject *args)
1894930cef6SMatthias Ringwald {
1904930cef6SMatthias Ringwald     if (!PyArg_ParseTuple(args, ""))
1914930cef6SMatthias Ringwald         return NULL;
1924930cef6SMatthias Ringwald 
1934930cef6SMatthias Ringwald     int nbits = lc3_sns_get_nbits();
1944930cef6SMatthias Ringwald 
1954930cef6SMatthias Ringwald     return Py_BuildValue("i", nbits);
1964930cef6SMatthias Ringwald }
1974930cef6SMatthias Ringwald 
1984930cef6SMatthias Ringwald static PyMethodDef methods[] = {
1994930cef6SMatthias Ringwald     { "sns_compute_scale_factors", compute_scale_factors_py, METH_VARARGS },
2004930cef6SMatthias Ringwald     { "sns_resolve_codebooks"    , resolve_codebooks_py    , METH_VARARGS },
2014930cef6SMatthias Ringwald     { "sns_quantize"             , quantize_py             , METH_VARARGS },
2024930cef6SMatthias Ringwald     { "sns_unquantize"           , unquantize_py           , METH_VARARGS },
2034930cef6SMatthias Ringwald     { "sns_spectral_shaping"     , spectral_shaping_py     , METH_VARARGS },
2044930cef6SMatthias Ringwald     { "sns_analyze"              , analyze_py              , METH_VARARGS },
2054930cef6SMatthias Ringwald     { "sns_synthesize"           , synthesize_py           , METH_VARARGS },
2064930cef6SMatthias Ringwald     { "sns_get_nbits"            , get_nbits_py            , METH_VARARGS },
2074930cef6SMatthias Ringwald     { NULL },
2084930cef6SMatthias Ringwald };
2094930cef6SMatthias Ringwald 
lc3_sns_py_init(PyObject * m)2104930cef6SMatthias Ringwald PyMODINIT_FUNC lc3_sns_py_init(PyObject *m)
2114930cef6SMatthias Ringwald {
2124930cef6SMatthias Ringwald     import_array();
2134930cef6SMatthias Ringwald 
2144930cef6SMatthias Ringwald     PyModule_AddFunctions(m, methods);
2154930cef6SMatthias Ringwald 
2164930cef6SMatthias Ringwald     return m;
2174930cef6SMatthias Ringwald }
218