xref: /btstack/3rd-party/lc3-google/test/lc3_py.c (revision 4930cef6e21e6da2d7571b9259c7f0fb8bed3d01)
1*4930cef6SMatthias Ringwald /******************************************************************************
2*4930cef6SMatthias Ringwald  *
3*4930cef6SMatthias Ringwald  *  Copyright 2022 Google LLC
4*4930cef6SMatthias Ringwald  *
5*4930cef6SMatthias Ringwald  *  Licensed under the Apache License, Version 2.0 (the "License");
6*4930cef6SMatthias Ringwald  *  you may not use this file except in compliance with the License.
7*4930cef6SMatthias Ringwald  *  You may obtain a copy of the License at:
8*4930cef6SMatthias Ringwald  *
9*4930cef6SMatthias Ringwald  *  http://www.apache.org/licenses/LICENSE-2.0
10*4930cef6SMatthias Ringwald  *
11*4930cef6SMatthias Ringwald  *  Unless required by applicable law or agreed to in writing, software
12*4930cef6SMatthias Ringwald  *  distributed under the License is distributed on an "AS IS" BASIS,
13*4930cef6SMatthias Ringwald  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*4930cef6SMatthias Ringwald  *  See the License for the specific language governing permissions and
15*4930cef6SMatthias Ringwald  *  limitations under the License.
16*4930cef6SMatthias Ringwald  *
17*4930cef6SMatthias Ringwald  ******************************************************************************/
18*4930cef6SMatthias Ringwald 
19*4930cef6SMatthias Ringwald #include "lc3.h"
20*4930cef6SMatthias Ringwald 
21*4930cef6SMatthias Ringwald #define PY_SSIZE_T_CLEAN
22*4930cef6SMatthias Ringwald #include <Python.h>
23*4930cef6SMatthias Ringwald #include <numpy/ndarrayobject.h>
24*4930cef6SMatthias Ringwald 
25*4930cef6SMatthias Ringwald #include <lc3.c>
26*4930cef6SMatthias Ringwald 
27*4930cef6SMatthias Ringwald #define __CTYPES_LC3_C
28*4930cef6SMatthias Ringwald #include "ctypes.h"
29*4930cef6SMatthias Ringwald 
30*4930cef6SMatthias Ringwald static PyObject *setup_encoder_py(PyObject *m, PyObject *args)
31*4930cef6SMatthias Ringwald {
32*4930cef6SMatthias Ringwald     int dt_us, sr_hz;
33*4930cef6SMatthias Ringwald 
34*4930cef6SMatthias Ringwald     if (!PyArg_ParseTuple(args, "ii", &dt_us, &sr_hz))
35*4930cef6SMatthias Ringwald         return NULL;
36*4930cef6SMatthias Ringwald 
37*4930cef6SMatthias Ringwald     CTYPES_CHECK("dt_us", LC3_CHECK_DT_US(dt_us));
38*4930cef6SMatthias Ringwald     CTYPES_CHECK("sr_hz", LC3_CHECK_SR_HZ(sr_hz));
39*4930cef6SMatthias Ringwald 
40*4930cef6SMatthias Ringwald     lc3_encoder_t encoder = lc3_setup_encoder(dt_us, sr_hz, 0,
41*4930cef6SMatthias Ringwald             malloc(lc3_encoder_size(dt_us, sr_hz)));
42*4930cef6SMatthias Ringwald 
43*4930cef6SMatthias Ringwald     PyObject *encoder_obj = from_encoder(NULL, encoder);
44*4930cef6SMatthias Ringwald 
45*4930cef6SMatthias Ringwald     free(encoder);
46*4930cef6SMatthias Ringwald 
47*4930cef6SMatthias Ringwald     return Py_BuildValue("N", encoder_obj);
48*4930cef6SMatthias Ringwald }
49*4930cef6SMatthias Ringwald 
50*4930cef6SMatthias Ringwald static PyObject *encode_py(PyObject *m, PyObject *args)
51*4930cef6SMatthias Ringwald {
52*4930cef6SMatthias Ringwald     PyObject *encoder_obj, *pcm_obj;
53*4930cef6SMatthias Ringwald     int nbytes;
54*4930cef6SMatthias Ringwald     int16_t *pcm;
55*4930cef6SMatthias Ringwald 
56*4930cef6SMatthias Ringwald     if (!PyArg_ParseTuple(args, "OOi", &encoder_obj, &pcm_obj, &nbytes))
57*4930cef6SMatthias Ringwald         return NULL;
58*4930cef6SMatthias Ringwald 
59*4930cef6SMatthias Ringwald     lc3_encoder_t encoder =
60*4930cef6SMatthias Ringwald         lc3_setup_encoder(10000, 48000, 0, &(lc3_encoder_mem_48k_t){ });
61*4930cef6SMatthias Ringwald 
62*4930cef6SMatthias Ringwald     CTYPES_CHECK(NULL, encoder_obj = to_encoder(encoder_obj, encoder));
63*4930cef6SMatthias Ringwald 
64*4930cef6SMatthias Ringwald     int ns = LC3_NS(encoder->dt, encoder->sr);
65*4930cef6SMatthias Ringwald 
66*4930cef6SMatthias Ringwald     CTYPES_CHECK("x", pcm_obj = to_1d_ptr(pcm_obj, NPY_INT16, ns, &pcm));
67*4930cef6SMatthias Ringwald     CTYPES_CHECK("nbytes", nbytes >= 20 && nbytes <= 400);
68*4930cef6SMatthias Ringwald 
69*4930cef6SMatthias Ringwald     uint8_t out[nbytes];
70*4930cef6SMatthias Ringwald 
71*4930cef6SMatthias Ringwald     lc3_encode(encoder, LC3_PCM_FORMAT_S16, pcm, 1, nbytes, out);
72*4930cef6SMatthias Ringwald 
73*4930cef6SMatthias Ringwald     from_encoder(encoder_obj, encoder);
74*4930cef6SMatthias Ringwald 
75*4930cef6SMatthias Ringwald     return Py_BuildValue("N",
76*4930cef6SMatthias Ringwald         PyBytes_FromStringAndSize((const char *)out, nbytes));
77*4930cef6SMatthias Ringwald }
78*4930cef6SMatthias Ringwald 
79*4930cef6SMatthias Ringwald static PyObject *setup_decoder_py(PyObject *m, PyObject *args)
80*4930cef6SMatthias Ringwald {
81*4930cef6SMatthias Ringwald     int dt_us, sr_hz;
82*4930cef6SMatthias Ringwald 
83*4930cef6SMatthias Ringwald     if (!PyArg_ParseTuple(args, "ii", &dt_us, &sr_hz))
84*4930cef6SMatthias Ringwald         return NULL;
85*4930cef6SMatthias Ringwald 
86*4930cef6SMatthias Ringwald     CTYPES_CHECK("dt_us", LC3_CHECK_DT_US(dt_us));
87*4930cef6SMatthias Ringwald     CTYPES_CHECK("sr_hz", LC3_CHECK_SR_HZ(sr_hz));
88*4930cef6SMatthias Ringwald 
89*4930cef6SMatthias Ringwald     lc3_decoder_t decoder = lc3_setup_decoder(dt_us, sr_hz, 0,
90*4930cef6SMatthias Ringwald             malloc(lc3_decoder_size(dt_us, sr_hz)));
91*4930cef6SMatthias Ringwald 
92*4930cef6SMatthias Ringwald     PyObject *decoder_obj = from_decoder(NULL, decoder);
93*4930cef6SMatthias Ringwald 
94*4930cef6SMatthias Ringwald     free(decoder);
95*4930cef6SMatthias Ringwald 
96*4930cef6SMatthias Ringwald     return Py_BuildValue("N", decoder_obj);
97*4930cef6SMatthias Ringwald }
98*4930cef6SMatthias Ringwald 
99*4930cef6SMatthias Ringwald static PyObject *decode_py(PyObject *m, PyObject *args)
100*4930cef6SMatthias Ringwald {
101*4930cef6SMatthias Ringwald     PyObject *decoder_obj, *pcm_obj, *in_obj;
102*4930cef6SMatthias Ringwald     int16_t *pcm;
103*4930cef6SMatthias Ringwald 
104*4930cef6SMatthias Ringwald     if (!PyArg_ParseTuple(args, "OO", &decoder_obj, &in_obj))
105*4930cef6SMatthias Ringwald         return NULL;
106*4930cef6SMatthias Ringwald 
107*4930cef6SMatthias Ringwald     CTYPES_CHECK("in", in_obj == Py_None || PyBytes_Check(in_obj));
108*4930cef6SMatthias Ringwald 
109*4930cef6SMatthias Ringwald     char *in = in_obj == Py_None ? NULL : PyBytes_AsString(in_obj);
110*4930cef6SMatthias Ringwald     int nbytes = in_obj == Py_None ? 0 : PyBytes_Size(in_obj);
111*4930cef6SMatthias Ringwald 
112*4930cef6SMatthias Ringwald     lc3_decoder_t decoder =
113*4930cef6SMatthias Ringwald         lc3_setup_decoder(10000, 48000, 0, &(lc3_decoder_mem_48k_t){ });
114*4930cef6SMatthias Ringwald 
115*4930cef6SMatthias Ringwald     CTYPES_CHECK(NULL, decoder_obj = to_decoder(decoder_obj, decoder));
116*4930cef6SMatthias Ringwald 
117*4930cef6SMatthias Ringwald     int ns = LC3_NS(decoder->dt, decoder->sr);
118*4930cef6SMatthias Ringwald     pcm_obj = new_1d_ptr(NPY_INT16, ns, &pcm);
119*4930cef6SMatthias Ringwald 
120*4930cef6SMatthias Ringwald     lc3_decode(decoder, in, nbytes, LC3_PCM_FORMAT_S16, pcm, 1);
121*4930cef6SMatthias Ringwald 
122*4930cef6SMatthias Ringwald     from_decoder(decoder_obj, decoder);
123*4930cef6SMatthias Ringwald 
124*4930cef6SMatthias Ringwald     return Py_BuildValue("N", pcm_obj);
125*4930cef6SMatthias Ringwald }
126*4930cef6SMatthias Ringwald 
127*4930cef6SMatthias Ringwald static PyMethodDef methods[] = {
128*4930cef6SMatthias Ringwald     { "setup_encoder"      , setup_encoder_py      , METH_VARARGS },
129*4930cef6SMatthias Ringwald     { "encode"             , encode_py             , METH_VARARGS },
130*4930cef6SMatthias Ringwald     { "setup_decoder"      , setup_decoder_py      , METH_VARARGS },
131*4930cef6SMatthias Ringwald     { "decode"             , decode_py             , METH_VARARGS },
132*4930cef6SMatthias Ringwald     { NULL },
133*4930cef6SMatthias Ringwald };
134*4930cef6SMatthias Ringwald 
135*4930cef6SMatthias Ringwald PyMODINIT_FUNC lc3_interface_py_init(PyObject *m)
136*4930cef6SMatthias Ringwald {
137*4930cef6SMatthias Ringwald     import_array();
138*4930cef6SMatthias Ringwald 
139*4930cef6SMatthias Ringwald     PyModule_AddFunctions(m, methods);
140*4930cef6SMatthias Ringwald 
141*4930cef6SMatthias Ringwald     return m;
142*4930cef6SMatthias Ringwald }
143