xref: /aosp_15_r20/external/liblc3/test/ltpf_py.c (revision 49fe348c0058011ee60b6957cdd9d52742df84bc)
1*49fe348cSAndroid Build Coastguard Worker /******************************************************************************
2*49fe348cSAndroid Build Coastguard Worker  *
3*49fe348cSAndroid Build Coastguard Worker  *  Copyright 2022 Google LLC
4*49fe348cSAndroid Build Coastguard Worker  *
5*49fe348cSAndroid Build Coastguard Worker  *  Licensed under the Apache License, Version 2.0 (the "License");
6*49fe348cSAndroid Build Coastguard Worker  *  you may not use this file except in compliance with the License.
7*49fe348cSAndroid Build Coastguard Worker  *  You may obtain a copy of the License at:
8*49fe348cSAndroid Build Coastguard Worker  *
9*49fe348cSAndroid Build Coastguard Worker  *  http://www.apache.org/licenses/LICENSE-2.0
10*49fe348cSAndroid Build Coastguard Worker  *
11*49fe348cSAndroid Build Coastguard Worker  *  Unless required by applicable law or agreed to in writing, software
12*49fe348cSAndroid Build Coastguard Worker  *  distributed under the License is distributed on an "AS IS" BASIS,
13*49fe348cSAndroid Build Coastguard Worker  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*49fe348cSAndroid Build Coastguard Worker  *  See the License for the specific language governing permissions and
15*49fe348cSAndroid Build Coastguard Worker  *  limitations under the License.
16*49fe348cSAndroid Build Coastguard Worker  *
17*49fe348cSAndroid Build Coastguard Worker  ******************************************************************************/
18*49fe348cSAndroid Build Coastguard Worker 
19*49fe348cSAndroid Build Coastguard Worker #include <Python.h>
20*49fe348cSAndroid Build Coastguard Worker #include <numpy/ndarrayobject.h>
21*49fe348cSAndroid Build Coastguard Worker 
22*49fe348cSAndroid Build Coastguard Worker #include <ltpf.c>
23*49fe348cSAndroid Build Coastguard Worker #include "ctypes.h"
24*49fe348cSAndroid Build Coastguard Worker 
resample_py(PyObject * m,PyObject * args)25*49fe348cSAndroid Build Coastguard Worker static PyObject *resample_py(PyObject *m, PyObject *args)
26*49fe348cSAndroid Build Coastguard Worker {
27*49fe348cSAndroid Build Coastguard Worker     unsigned dt, sr;
28*49fe348cSAndroid Build Coastguard Worker     PyObject *hp50_obj, *x_obj, *y_obj;
29*49fe348cSAndroid Build Coastguard Worker     struct lc3_ltpf_hp50_state hp50;
30*49fe348cSAndroid Build Coastguard Worker     int16_t *x, *y;
31*49fe348cSAndroid Build Coastguard Worker 
32*49fe348cSAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, "IIOOO", &dt, &sr, &hp50_obj, &x_obj, &y_obj))
33*49fe348cSAndroid Build Coastguard Worker         return NULL;
34*49fe348cSAndroid Build Coastguard Worker 
35*49fe348cSAndroid Build Coastguard Worker     CTYPES_CHECK("dt", (unsigned)dt < LC3_NUM_DT);
36*49fe348cSAndroid Build Coastguard Worker     CTYPES_CHECK("sr", (unsigned)sr < LC3_NUM_SRATE);
37*49fe348cSAndroid Build Coastguard Worker     CTYPES_CHECK(NULL, hp50_obj = to_ltpf_hp50_state(hp50_obj, &hp50));
38*49fe348cSAndroid Build Coastguard Worker 
39*49fe348cSAndroid Build Coastguard Worker     int ns = lc3_ns(dt, sr), nt = lc3_nt(sr);
40*49fe348cSAndroid Build Coastguard Worker     int ny = sizeof((struct lc3_ltpf_analysis){ }.x_12k8) / sizeof(int16_t);
41*49fe348cSAndroid Build Coastguard Worker     int n  = (1 + dt) * 32;
42*49fe348cSAndroid Build Coastguard Worker 
43*49fe348cSAndroid Build Coastguard Worker     CTYPES_CHECK("x", x_obj = to_1d_ptr(x_obj, NPY_INT16, ns+nt, &x));
44*49fe348cSAndroid Build Coastguard Worker     CTYPES_CHECK("y", y_obj = to_1d_ptr(y_obj, NPY_INT16, ny, &y));
45*49fe348cSAndroid Build Coastguard Worker 
46*49fe348cSAndroid Build Coastguard Worker     resample_12k8[sr](&hp50, x + nt, y + (ny - n), n);
47*49fe348cSAndroid Build Coastguard Worker 
48*49fe348cSAndroid Build Coastguard Worker     from_ltpf_hp50_state(hp50_obj, &hp50);
49*49fe348cSAndroid Build Coastguard Worker     return Py_BuildValue("O", y_obj);
50*49fe348cSAndroid Build Coastguard Worker }
51*49fe348cSAndroid Build Coastguard Worker 
analyse_py(PyObject * m,PyObject * args)52*49fe348cSAndroid Build Coastguard Worker static PyObject *analyse_py(PyObject *m, PyObject *args)
53*49fe348cSAndroid Build Coastguard Worker {
54*49fe348cSAndroid Build Coastguard Worker     PyObject *ltpf_obj, *x_obj;
55*49fe348cSAndroid Build Coastguard Worker     unsigned dt, sr;
56*49fe348cSAndroid Build Coastguard Worker     struct lc3_ltpf_analysis ltpf;
57*49fe348cSAndroid Build Coastguard Worker     struct lc3_ltpf_data data = { 0 };
58*49fe348cSAndroid Build Coastguard Worker     int16_t *x;
59*49fe348cSAndroid Build Coastguard Worker 
60*49fe348cSAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, "IIOO", &dt, &sr, &ltpf_obj, &x_obj))
61*49fe348cSAndroid Build Coastguard Worker         return NULL;
62*49fe348cSAndroid Build Coastguard Worker 
63*49fe348cSAndroid Build Coastguard Worker     CTYPES_CHECK("dt", dt < LC3_NUM_DT);
64*49fe348cSAndroid Build Coastguard Worker     CTYPES_CHECK("sr", sr < LC3_NUM_SRATE);
65*49fe348cSAndroid Build Coastguard Worker     CTYPES_CHECK(NULL, ltpf_obj = to_ltpf_analysis(ltpf_obj, &ltpf));
66*49fe348cSAndroid Build Coastguard Worker 
67*49fe348cSAndroid Build Coastguard Worker     int ns = lc3_ns(dt, sr), nt = lc3_nt(sr);
68*49fe348cSAndroid Build Coastguard Worker 
69*49fe348cSAndroid Build Coastguard Worker     CTYPES_CHECK("x", x_obj = to_1d_ptr(x_obj, NPY_INT16, ns+nt, &x));
70*49fe348cSAndroid Build Coastguard Worker 
71*49fe348cSAndroid Build Coastguard Worker     int pitch_present =
72*49fe348cSAndroid Build Coastguard Worker         lc3_ltpf_analyse(dt, sr, &ltpf, x + nt, &data);
73*49fe348cSAndroid Build Coastguard Worker 
74*49fe348cSAndroid Build Coastguard Worker     from_ltpf_analysis(ltpf_obj, &ltpf);
75*49fe348cSAndroid Build Coastguard Worker     return Py_BuildValue("iN", pitch_present, new_ltpf_data(&data));
76*49fe348cSAndroid Build Coastguard Worker }
77*49fe348cSAndroid Build Coastguard Worker 
synthesize_py(PyObject * m,PyObject * args)78*49fe348cSAndroid Build Coastguard Worker static PyObject *synthesize_py(PyObject *m, PyObject *args)
79*49fe348cSAndroid Build Coastguard Worker {
80*49fe348cSAndroid Build Coastguard Worker     PyObject *ltpf_obj, *data_obj, *x_obj;
81*49fe348cSAndroid Build Coastguard Worker     struct lc3_ltpf_synthesis ltpf;
82*49fe348cSAndroid Build Coastguard Worker     struct lc3_ltpf_data data;
83*49fe348cSAndroid Build Coastguard Worker     bool pitch_present;
84*49fe348cSAndroid Build Coastguard Worker     unsigned dt, sr;
85*49fe348cSAndroid Build Coastguard Worker     int nbytes;
86*49fe348cSAndroid Build Coastguard Worker     float *x;
87*49fe348cSAndroid Build Coastguard Worker 
88*49fe348cSAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, "IIiOOO",
89*49fe348cSAndroid Build Coastguard Worker                 &dt, &sr, &nbytes, &ltpf_obj, &data_obj, &x_obj))
90*49fe348cSAndroid Build Coastguard Worker         return NULL;
91*49fe348cSAndroid Build Coastguard Worker 
92*49fe348cSAndroid Build Coastguard Worker     CTYPES_CHECK("dt", dt < LC3_NUM_DT);
93*49fe348cSAndroid Build Coastguard Worker     CTYPES_CHECK("sr", sr < LC3_NUM_SRATE);
94*49fe348cSAndroid Build Coastguard Worker     CTYPES_CHECK("nbytes", nbytes >= 20 && nbytes <= 400);
95*49fe348cSAndroid Build Coastguard Worker     CTYPES_CHECK(NULL, ltpf_obj = to_ltpf_synthesis(ltpf_obj, &ltpf));
96*49fe348cSAndroid Build Coastguard Worker 
97*49fe348cSAndroid Build Coastguard Worker     if ((pitch_present = (data_obj != Py_None)))
98*49fe348cSAndroid Build Coastguard Worker         CTYPES_CHECK(NULL, data_obj = to_ltpf_data(data_obj, &data));
99*49fe348cSAndroid Build Coastguard Worker 
100*49fe348cSAndroid Build Coastguard Worker     int ns = lc3_ns(dt,sr), nd = 18 * (lc3_ns_4m[sr] / 4);
101*49fe348cSAndroid Build Coastguard Worker 
102*49fe348cSAndroid Build Coastguard Worker     CTYPES_CHECK("x", x_obj = to_1d_ptr(x_obj, NPY_FLOAT, nd+ns, &x));
103*49fe348cSAndroid Build Coastguard Worker 
104*49fe348cSAndroid Build Coastguard Worker     lc3_ltpf_synthesize(dt, sr, nbytes,
105*49fe348cSAndroid Build Coastguard Worker         &ltpf, pitch_present ? &data : NULL, x, x + nd);
106*49fe348cSAndroid Build Coastguard Worker 
107*49fe348cSAndroid Build Coastguard Worker     from_ltpf_synthesis(ltpf_obj, &ltpf);
108*49fe348cSAndroid Build Coastguard Worker     return Py_BuildValue("O", x_obj);
109*49fe348cSAndroid Build Coastguard Worker }
110*49fe348cSAndroid Build Coastguard Worker 
get_nbits_py(PyObject * m,PyObject * args)111*49fe348cSAndroid Build Coastguard Worker static PyObject *get_nbits_py(PyObject *m, PyObject *args)
112*49fe348cSAndroid Build Coastguard Worker {
113*49fe348cSAndroid Build Coastguard Worker     int pitch_present;
114*49fe348cSAndroid Build Coastguard Worker 
115*49fe348cSAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, "i", &pitch_present))
116*49fe348cSAndroid Build Coastguard Worker         return NULL;
117*49fe348cSAndroid Build Coastguard Worker 
118*49fe348cSAndroid Build Coastguard Worker     int nbits = lc3_ltpf_get_nbits(pitch_present);
119*49fe348cSAndroid Build Coastguard Worker 
120*49fe348cSAndroid Build Coastguard Worker     return Py_BuildValue("i", nbits);
121*49fe348cSAndroid Build Coastguard Worker }
122*49fe348cSAndroid Build Coastguard Worker 
123*49fe348cSAndroid Build Coastguard Worker static PyMethodDef methods[] = {
124*49fe348cSAndroid Build Coastguard Worker     { "ltpf_resample"  , resample_py  , METH_VARARGS },
125*49fe348cSAndroid Build Coastguard Worker     { "ltpf_analyse"   , analyse_py   , METH_VARARGS },
126*49fe348cSAndroid Build Coastguard Worker     { "ltpf_synthesize", synthesize_py, METH_VARARGS },
127*49fe348cSAndroid Build Coastguard Worker     { "ltpf_get_nbits" , get_nbits_py , METH_VARARGS },
128*49fe348cSAndroid Build Coastguard Worker     { NULL },
129*49fe348cSAndroid Build Coastguard Worker };
130*49fe348cSAndroid Build Coastguard Worker 
lc3_ltpf_py_init(PyObject * m)131*49fe348cSAndroid Build Coastguard Worker PyMODINIT_FUNC lc3_ltpf_py_init(PyObject *m)
132*49fe348cSAndroid Build Coastguard Worker {
133*49fe348cSAndroid Build Coastguard Worker     import_array();
134*49fe348cSAndroid Build Coastguard Worker 
135*49fe348cSAndroid Build Coastguard Worker     PyModule_AddFunctions(m, methods);
136*49fe348cSAndroid Build Coastguard Worker 
137*49fe348cSAndroid Build Coastguard Worker     return m;
138*49fe348cSAndroid Build Coastguard Worker }
139