mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-01-09 15:39:08 +00:00
143 lines
3.9 KiB
C
143 lines
3.9 KiB
C
|
/******************************************************************************
|
||
|
*
|
||
|
* Copyright 2022 Google LLC
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at:
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*
|
||
|
******************************************************************************/
|
||
|
|
||
|
#include "lc3.h"
|
||
|
|
||
|
#define PY_SSIZE_T_CLEAN
|
||
|
#include <Python.h>
|
||
|
#include <numpy/ndarrayobject.h>
|
||
|
|
||
|
#include <lc3.c>
|
||
|
|
||
|
#define __CTYPES_LC3_C
|
||
|
#include "ctypes.h"
|
||
|
|
||
|
static PyObject *setup_encoder_py(PyObject *m, PyObject *args)
|
||
|
{
|
||
|
int dt_us, sr_hz;
|
||
|
|
||
|
if (!PyArg_ParseTuple(args, "ii", &dt_us, &sr_hz))
|
||
|
return NULL;
|
||
|
|
||
|
CTYPES_CHECK("dt_us", LC3_CHECK_DT_US(dt_us));
|
||
|
CTYPES_CHECK("sr_hz", LC3_CHECK_SR_HZ(sr_hz));
|
||
|
|
||
|
lc3_encoder_t encoder = lc3_setup_encoder(dt_us, sr_hz, 0,
|
||
|
malloc(lc3_encoder_size(dt_us, sr_hz)));
|
||
|
|
||
|
PyObject *encoder_obj = from_encoder(NULL, encoder);
|
||
|
|
||
|
free(encoder);
|
||
|
|
||
|
return Py_BuildValue("N", encoder_obj);
|
||
|
}
|
||
|
|
||
|
static PyObject *encode_py(PyObject *m, PyObject *args)
|
||
|
{
|
||
|
PyObject *encoder_obj, *pcm_obj;
|
||
|
int nbytes;
|
||
|
int16_t *pcm;
|
||
|
|
||
|
if (!PyArg_ParseTuple(args, "OOi", &encoder_obj, &pcm_obj, &nbytes))
|
||
|
return NULL;
|
||
|
|
||
|
lc3_encoder_t encoder =
|
||
|
lc3_setup_encoder(10000, 48000, 0, &(lc3_encoder_mem_48k_t){ });
|
||
|
|
||
|
CTYPES_CHECK(NULL, encoder_obj = to_encoder(encoder_obj, encoder));
|
||
|
|
||
|
int ns = LC3_NS(encoder->dt, encoder->sr);
|
||
|
|
||
|
CTYPES_CHECK("x", pcm_obj = to_1d_ptr(pcm_obj, NPY_INT16, ns, &pcm));
|
||
|
CTYPES_CHECK("nbytes", nbytes >= 20 && nbytes <= 400);
|
||
|
|
||
|
uint8_t out[nbytes];
|
||
|
|
||
|
lc3_encode(encoder, LC3_PCM_FORMAT_S16, pcm, 1, nbytes, out);
|
||
|
|
||
|
from_encoder(encoder_obj, encoder);
|
||
|
|
||
|
return Py_BuildValue("N",
|
||
|
PyBytes_FromStringAndSize((const char *)out, nbytes));
|
||
|
}
|
||
|
|
||
|
static PyObject *setup_decoder_py(PyObject *m, PyObject *args)
|
||
|
{
|
||
|
int dt_us, sr_hz;
|
||
|
|
||
|
if (!PyArg_ParseTuple(args, "ii", &dt_us, &sr_hz))
|
||
|
return NULL;
|
||
|
|
||
|
CTYPES_CHECK("dt_us", LC3_CHECK_DT_US(dt_us));
|
||
|
CTYPES_CHECK("sr_hz", LC3_CHECK_SR_HZ(sr_hz));
|
||
|
|
||
|
lc3_decoder_t decoder = lc3_setup_decoder(dt_us, sr_hz, 0,
|
||
|
malloc(lc3_decoder_size(dt_us, sr_hz)));
|
||
|
|
||
|
PyObject *decoder_obj = from_decoder(NULL, decoder);
|
||
|
|
||
|
free(decoder);
|
||
|
|
||
|
return Py_BuildValue("N", decoder_obj);
|
||
|
}
|
||
|
|
||
|
static PyObject *decode_py(PyObject *m, PyObject *args)
|
||
|
{
|
||
|
PyObject *decoder_obj, *pcm_obj, *in_obj;
|
||
|
int16_t *pcm;
|
||
|
|
||
|
if (!PyArg_ParseTuple(args, "OO", &decoder_obj, &in_obj))
|
||
|
return NULL;
|
||
|
|
||
|
CTYPES_CHECK("in", in_obj == Py_None || PyBytes_Check(in_obj));
|
||
|
|
||
|
char *in = in_obj == Py_None ? NULL : PyBytes_AsString(in_obj);
|
||
|
int nbytes = in_obj == Py_None ? 0 : PyBytes_Size(in_obj);
|
||
|
|
||
|
lc3_decoder_t decoder =
|
||
|
lc3_setup_decoder(10000, 48000, 0, &(lc3_decoder_mem_48k_t){ });
|
||
|
|
||
|
CTYPES_CHECK(NULL, decoder_obj = to_decoder(decoder_obj, decoder));
|
||
|
|
||
|
int ns = LC3_NS(decoder->dt, decoder->sr);
|
||
|
pcm_obj = new_1d_ptr(NPY_INT16, ns, &pcm);
|
||
|
|
||
|
lc3_decode(decoder, in, nbytes, LC3_PCM_FORMAT_S16, pcm, 1);
|
||
|
|
||
|
from_decoder(decoder_obj, decoder);
|
||
|
|
||
|
return Py_BuildValue("N", pcm_obj);
|
||
|
}
|
||
|
|
||
|
static PyMethodDef methods[] = {
|
||
|
{ "setup_encoder" , setup_encoder_py , METH_VARARGS },
|
||
|
{ "encode" , encode_py , METH_VARARGS },
|
||
|
{ "setup_decoder" , setup_decoder_py , METH_VARARGS },
|
||
|
{ "decode" , decode_py , METH_VARARGS },
|
||
|
{ NULL },
|
||
|
};
|
||
|
|
||
|
PyMODINIT_FUNC lc3_interface_py_init(PyObject *m)
|
||
|
{
|
||
|
import_array();
|
||
|
|
||
|
PyModule_AddFunctions(m, methods);
|
||
|
|
||
|
return m;
|
||
|
}
|