mirror of
https://github.com/google/liblc3.git
synced 2026-04-16 12:45:31 +00:00
870 lines
23 KiB
C
870 lines
23 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.
|
|
*
|
|
******************************************************************************/
|
|
|
|
#ifndef __CTYPES_H
|
|
#define __CTYPES_H
|
|
|
|
#include <Python.h>
|
|
#include <numpy/ndarrayobject.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
|
#define CTYPES_CHECK(exc, t) \
|
|
do { \
|
|
if (!(t)) return (exc) ? PyErr_Format(PyExc_TypeError, exc) : NULL; \
|
|
} while(0)
|
|
|
|
|
|
/**
|
|
* From C types to Numpy Array types
|
|
*/
|
|
|
|
#define to_scalar(obj, t, ptr) \
|
|
__to_scalar(obj, t, (void *)(ptr))
|
|
|
|
#define to_1d_ptr(obj, t, n, ptr) \
|
|
__to_1d_ptr(obj, t, n, (void **)(ptr))
|
|
|
|
#define to_2d_ptr(obj, t, n1, n2, ptr) \
|
|
__to_2d_ptr(obj, t, n1, n2, (void **)(ptr))
|
|
|
|
#define to_1d_copy(obj, t, ptr, n) \
|
|
__to_1d_copy(obj, t, ptr, n)
|
|
|
|
#define to_2d_copy(obj, t, ptr, n1, n2) \
|
|
__to_2d_copy(obj, t, ptr, n1, n2)
|
|
|
|
|
|
/**
|
|
* From Numpy Array types to C types
|
|
*/
|
|
|
|
#define new_scalar(obj, ptr) \
|
|
__new_scalar(obj, ptr)
|
|
|
|
#define new_1d_ptr(t, n, ptr) \
|
|
__new_1d_ptr(t, n, (void **)(ptr))
|
|
|
|
#define new_2d_ptr(t, n1, n2, ptr) \
|
|
__new_2d_ptr(t, n1, n2, (void **)(ptr))
|
|
|
|
#define new_1d_copy(t, n, src) \
|
|
__new_1d_copy(t, n, src)
|
|
|
|
#define new_2d_copy(t, n1, n2, src) \
|
|
__new_2d_copy(t, n1, n2, src)
|
|
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
__attribute__((unused))
|
|
static PyObject *__to_scalar(PyObject *obj, int t, void *ptr)
|
|
{
|
|
obj = obj ? PyArray_FROMANY(obj, t, 0, 0, NPY_ARRAY_FORCECAST) : obj;
|
|
if (!obj)
|
|
return NULL;
|
|
|
|
memcpy(ptr, PyArray_DATA((PyArrayObject *)obj),
|
|
PyArray_NBYTES((PyArrayObject *)obj));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *__to_1d_ptr(PyObject *obj, int t, int n, void **ptr)
|
|
{
|
|
obj = obj ? PyArray_FROMANY(obj,
|
|
t, 1, 1, NPY_ARRAY_FORCECAST|NPY_ARRAY_CARRAY) : obj;
|
|
if (!obj || (n && PyArray_SIZE((PyArrayObject *)obj) != n))
|
|
return NULL;
|
|
|
|
*ptr = PyArray_DATA((PyArrayObject *)obj);
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *__to_2d_ptr(PyObject *obj, int t, int n1, int n2, void **ptr)
|
|
{
|
|
obj = obj ? PyArray_FROMANY(obj,
|
|
t, 2, 2, NPY_ARRAY_FORCECAST|NPY_ARRAY_CARRAY) : obj;
|
|
if (!obj || (n1 && PyArray_DIMS((PyArrayObject *)obj)[0] != n1)
|
|
|| (n2 && PyArray_DIMS((PyArrayObject *)obj)[1] != n2))
|
|
return NULL;
|
|
|
|
*ptr = PyArray_DATA((PyArrayObject *)obj);
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *__to_1d_copy(PyObject *obj, int t, void *v, int n)
|
|
{
|
|
void *src;
|
|
|
|
if ((obj = to_1d_ptr(obj, t, n, &src)))
|
|
memcpy(v, src, PyArray_NBYTES((PyArrayObject *)obj));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *__to_2d_copy(PyObject *obj, int t, void *v, int n1, int n2)
|
|
{
|
|
void *src;
|
|
|
|
if ((obj = to_2d_ptr(obj, t, n1, n2, &src)))
|
|
memcpy(v, src, PyArray_NBYTES((PyArrayObject *)obj));
|
|
|
|
return obj;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
__attribute__((unused))
|
|
static PyObject *__new_scalar(int t, const void *ptr)
|
|
{
|
|
PyObject *obj = PyArray_SimpleNew(0, NULL, t);
|
|
|
|
memcpy(PyArray_DATA((PyArrayObject *)obj), ptr,
|
|
PyArray_NBYTES((PyArrayObject *)obj));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *__new_1d_ptr(int t, int n, void **ptr)
|
|
{
|
|
PyObject *obj = PyArray_SimpleNew(1, (const npy_intp []){ n }, t);
|
|
|
|
*ptr = PyArray_DATA((PyArrayObject *)obj);
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *__new_2d_ptr(int t, int n1, int n2, void **ptr)
|
|
{
|
|
PyObject *obj;
|
|
|
|
obj = PyArray_SimpleNew(2, ((const npy_intp []){ n1, n2 }), t);
|
|
|
|
*ptr = PyArray_DATA((PyArrayObject *)obj);
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *__new_1d_copy(int t, int n, const void *src)
|
|
{
|
|
PyObject *obj;
|
|
void *dst;
|
|
|
|
if ((obj = new_1d_ptr(t, n, &dst)))
|
|
memcpy(dst, src, PyArray_NBYTES((PyArrayObject *)obj));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *__new_2d_copy(int t, int n1, int n2, const void *src)
|
|
{
|
|
PyObject *obj;
|
|
void *dst;
|
|
|
|
if ((obj = new_2d_ptr(t, n1, n2, &dst)))
|
|
memcpy(dst, src, PyArray_NBYTES((PyArrayObject *)obj));
|
|
|
|
return obj;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
#include <lc3.h>
|
|
|
|
__attribute__((unused))
|
|
static PyObject *to_attdet_analysis(
|
|
PyObject *obj, struct lc3_attdet_analysis *attdet)
|
|
{
|
|
CTYPES_CHECK("attdet", obj && PyDict_Check(obj));
|
|
|
|
CTYPES_CHECK("attdet.en1", to_scalar(
|
|
PyDict_GetItemString(obj, "en1"), NPY_FLOAT, &attdet->en1));
|
|
|
|
CTYPES_CHECK("attdet.an1", to_scalar(
|
|
PyDict_GetItemString(obj, "an1"), NPY_FLOAT, &attdet->an1));
|
|
|
|
CTYPES_CHECK("attdet.p_att", to_scalar(
|
|
PyDict_GetItemString(obj, "p_att"), NPY_INT, &attdet->p_att));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *from_attdet_analysis(
|
|
PyObject *obj, const struct lc3_attdet_analysis *attdet)
|
|
{
|
|
if (!obj) obj = PyDict_New();
|
|
|
|
PyDict_SetItemString(obj, "en1",
|
|
new_scalar(NPY_FLOAT, &attdet->en1));
|
|
|
|
PyDict_SetItemString(obj, "an1",
|
|
new_scalar(NPY_FLOAT, &attdet->an1));
|
|
|
|
PyDict_SetItemString(obj, "p_att",
|
|
new_scalar(NPY_INT, &attdet->p_att));
|
|
|
|
return obj;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
#include <ltpf.h>
|
|
|
|
__attribute__((unused))
|
|
static PyObject *to_ltpf_hp50_state(
|
|
PyObject *obj, struct lc3_ltpf_hp50_state *hp50)
|
|
{
|
|
CTYPES_CHECK("hp50", obj && PyDict_Check(obj));
|
|
|
|
CTYPES_CHECK("hp50.s1", to_scalar(
|
|
PyDict_GetItemString(obj, "s1"), NPY_FLOAT, &hp50->s1));
|
|
|
|
CTYPES_CHECK("hp50.s2", to_scalar(
|
|
PyDict_GetItemString(obj, "s2"), NPY_FLOAT, &hp50->s2));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *from_ltpf_hp50_state(
|
|
PyObject *obj, const struct lc3_ltpf_hp50_state *hp50)
|
|
{
|
|
PyDict_SetItemString(obj, "s1",
|
|
new_scalar(NPY_FLOAT, &hp50->s1));
|
|
|
|
PyDict_SetItemString(obj, "s2",
|
|
new_scalar(NPY_FLOAT, &hp50->s2));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *to_ltpf_analysis(
|
|
PyObject *obj, struct lc3_ltpf_analysis *ltpf)
|
|
{
|
|
PyObject *nc_obj, *x_12k8_obj, *x_6k4_obj;
|
|
const int n_12k8 = sizeof(ltpf->x_12k8) / sizeof(float);
|
|
const int n_6k4 = sizeof(ltpf->x_6k4) / sizeof(float);
|
|
|
|
CTYPES_CHECK("ltpf", obj && PyDict_Check(obj));
|
|
|
|
CTYPES_CHECK("ltpf.active", to_scalar(
|
|
PyDict_GetItemString(obj, "active"), NPY_BOOL, <pf->active));
|
|
|
|
CTYPES_CHECK("ltpf.pitch", to_scalar(
|
|
PyDict_GetItemString(obj, "pitch"), NPY_INT, <pf->pitch));
|
|
|
|
CTYPES_CHECK("ltpf.nc", nc_obj = to_1d_copy(
|
|
PyDict_GetItemString(obj, "nc"), NPY_FLOAT, ltpf->nc, 2));
|
|
PyDict_SetItemString(obj, "nc", nc_obj);
|
|
|
|
CTYPES_CHECK(NULL, to_ltpf_hp50_state(
|
|
PyDict_GetItemString(obj, "hp50"), <pf->hp50));
|
|
|
|
CTYPES_CHECK("ltpf.x_12k8", x_12k8_obj = to_1d_copy(
|
|
PyDict_GetItemString(obj, "x_12k8"), NPY_FLOAT, ltpf->x_12k8, n_12k8));
|
|
PyDict_SetItemString(obj, "x_12k8", x_12k8_obj);
|
|
|
|
CTYPES_CHECK("ltpf.x_6k4", x_6k4_obj = to_1d_copy(
|
|
PyDict_GetItemString(obj, "x_6k4"), NPY_FLOAT, ltpf->x_6k4, n_6k4));
|
|
PyDict_SetItemString(obj, "x_6k4", x_6k4_obj);
|
|
|
|
CTYPES_CHECK("ltpf.tc", to_scalar(
|
|
PyDict_GetItemString(obj, "tc"), NPY_INT, <pf->tc));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *from_ltpf_analysis(
|
|
PyObject *obj, const struct lc3_ltpf_analysis *ltpf)
|
|
{
|
|
const int n_12k8 = sizeof(ltpf->x_12k8) / sizeof(float);
|
|
const int n_6k4 = sizeof(ltpf->x_6k4) / sizeof(float);
|
|
|
|
if (!obj) obj = PyDict_New();
|
|
|
|
PyDict_SetItemString(obj, "active",
|
|
new_scalar(NPY_BOOL, <pf->active));
|
|
|
|
PyDict_SetItemString(obj, "pitch",
|
|
new_scalar(NPY_INT, <pf->pitch));
|
|
|
|
PyDict_SetItemString(obj, "nc",
|
|
new_1d_copy(NPY_FLOAT, 2, <pf->nc));
|
|
|
|
PyDict_SetItemString(obj, "hp50",
|
|
from_ltpf_hp50_state(PyDict_New(), <pf->hp50));
|
|
|
|
PyDict_SetItemString(obj, "x_12k8",
|
|
new_1d_copy(NPY_FLOAT, n_12k8, <pf->x_12k8));
|
|
|
|
PyDict_SetItemString(obj, "x_6k4",
|
|
new_1d_copy(NPY_FLOAT, n_6k4, <pf->x_6k4));
|
|
|
|
PyDict_SetItemString(obj, "tc",
|
|
new_scalar(NPY_INT, <pf->tc));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *to_ltpf_synthesis(
|
|
PyObject *obj, struct lc3_ltpf_synthesis *ltpf)
|
|
{
|
|
PyObject *c_obj, *x_obj;
|
|
|
|
CTYPES_CHECK("ltpf", obj && PyDict_Check(obj));
|
|
|
|
CTYPES_CHECK("ltpf.active", to_scalar(
|
|
PyDict_GetItemString(obj, "active"), NPY_BOOL, <pf->active));
|
|
|
|
CTYPES_CHECK("ltpf.pitch", to_scalar(
|
|
PyDict_GetItemString(obj, "pitch"), NPY_INT, <pf->pitch));
|
|
|
|
CTYPES_CHECK("ltpf.c", c_obj = to_2d_copy(
|
|
PyDict_GetItemString(obj, "c"), NPY_FLOAT, ltpf->c, 12, 2));
|
|
PyDict_SetItemString(obj, "c", c_obj);
|
|
|
|
CTYPES_CHECK("ltpf.x", x_obj = to_1d_copy(
|
|
PyDict_GetItemString(obj, "x"), NPY_FLOAT, ltpf->x, 12));
|
|
PyDict_SetItemString(obj, "x", x_obj);
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *from_ltpf_synthesis(
|
|
PyObject *obj, const struct lc3_ltpf_synthesis *ltpf)
|
|
{
|
|
if (!obj) obj = PyDict_New();
|
|
|
|
PyDict_SetItemString(obj, "active",
|
|
new_scalar(NPY_BOOL, <pf->active));
|
|
|
|
PyDict_SetItemString(obj, "pitch",
|
|
new_scalar(NPY_INT, <pf->pitch));
|
|
|
|
PyDict_SetItemString(obj, "c",
|
|
new_2d_copy(NPY_FLOAT, 12, 2, <pf->c));
|
|
|
|
PyDict_SetItemString(obj, "x",
|
|
new_1d_copy(NPY_FLOAT, 12, <pf->x));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *new_ltpf_data(const struct lc3_ltpf_data *data)
|
|
{
|
|
PyObject *obj = PyDict_New();
|
|
|
|
PyDict_SetItemString(obj, "active",
|
|
new_scalar(NPY_BOOL, &data->active));
|
|
|
|
PyDict_SetItemString(obj, "pitch_index",
|
|
new_scalar(NPY_INT, &data->pitch_index));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *to_ltpf_data(
|
|
PyObject *obj, const struct lc3_ltpf_data *data)
|
|
{
|
|
PyObject *item;
|
|
|
|
CTYPES_CHECK("ltpf", obj && PyDict_Check(obj));
|
|
|
|
if ((item = PyDict_GetItemString(obj, "active")))
|
|
CTYPES_CHECK("ltpf.active",
|
|
to_scalar(item, NPY_BOOL, &data->active));
|
|
|
|
if ((item = PyDict_GetItemString(obj, "pitch_index")))
|
|
CTYPES_CHECK("ltpf.pitch_index",
|
|
to_scalar(item, NPY_INT, &data->pitch_index));
|
|
|
|
return obj;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
#include <sns.h>
|
|
|
|
__attribute__((unused))
|
|
static PyObject *new_sns_data(const struct lc3_sns_data *data)
|
|
{
|
|
PyObject *obj = PyDict_New();
|
|
|
|
PyDict_SetItemString(obj, "lfcb",
|
|
new_scalar(NPY_INT, &data->lfcb));
|
|
|
|
PyDict_SetItemString(obj, "hfcb",
|
|
new_scalar(NPY_INT, &data->hfcb));
|
|
|
|
PyDict_SetItemString(obj, "shape",
|
|
new_scalar(NPY_INT, &data->shape));
|
|
|
|
PyDict_SetItemString(obj, "gain",
|
|
new_scalar(NPY_INT, &data->gain));
|
|
|
|
PyDict_SetItemString(obj, "idx_a",
|
|
new_scalar(NPY_INT, &data->idx_a));
|
|
|
|
PyDict_SetItemString(obj, "ls_a",
|
|
new_scalar(NPY_BOOL, &data->ls_a));
|
|
|
|
PyDict_SetItemString(obj, "idx_b",
|
|
new_scalar(NPY_INT, &data->idx_b));
|
|
|
|
PyDict_SetItemString(obj, "ls_b",
|
|
new_scalar(NPY_BOOL, &data->ls_b));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *to_sns_data(PyObject *obj, struct lc3_sns_data *data)
|
|
{
|
|
PyObject *item;
|
|
|
|
CTYPES_CHECK("sns", obj && PyDict_Check(obj));
|
|
|
|
if ((item = PyDict_GetItemString(obj, "lfcb")))
|
|
CTYPES_CHECK("sns.lfcb", to_scalar(item, NPY_INT, &data->lfcb));
|
|
|
|
if ((item = PyDict_GetItemString(obj, "hfcb")))
|
|
CTYPES_CHECK("sns.hfcb", to_scalar(item, NPY_INT, &data->hfcb));
|
|
|
|
if ((item = PyDict_GetItemString(obj, "shape")))
|
|
CTYPES_CHECK("sns.shape", to_scalar(item, NPY_INT, &data->shape));
|
|
|
|
if ((item = PyDict_GetItemString(obj, "gain")))
|
|
CTYPES_CHECK("sns.gain", to_scalar(item, NPY_INT, &data->gain));
|
|
|
|
if ((item = PyDict_GetItemString(obj, "idx_a")))
|
|
CTYPES_CHECK("sns.idx_a", to_scalar(item, NPY_INT, &data->idx_a));
|
|
|
|
if ((item = PyDict_GetItemString(obj, "ls_a")))
|
|
CTYPES_CHECK("sns.ls_a", to_scalar(item, NPY_INT, &data->ls_a));
|
|
|
|
if ((item = PyDict_GetItemString(obj, "idx_b")))
|
|
CTYPES_CHECK("sns.idx_b", to_scalar(item, NPY_INT, &data->idx_b));
|
|
|
|
if ((item = PyDict_GetItemString(obj, "ls_b")))
|
|
CTYPES_CHECK("sns.ls_b", to_scalar(item, NPY_INT, &data->ls_b));
|
|
|
|
return obj;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
#include <tns.h>
|
|
|
|
__attribute__((unused))
|
|
static PyObject *new_tns_data(const struct lc3_tns_data *side)
|
|
{
|
|
PyObject *obj = PyDict_New();
|
|
|
|
PyDict_SetItemString(obj, "nfilters",
|
|
new_scalar(NPY_INT, &side->nfilters));
|
|
|
|
PyDict_SetItemString(obj, "lpc_weighting",
|
|
new_scalar(NPY_BOOL, &side->lpc_weighting));
|
|
|
|
PyDict_SetItemString(obj, "rc_order",
|
|
new_1d_copy(NPY_INT, 2, side->rc_order));
|
|
|
|
PyDict_SetItemString(obj, "rc",
|
|
new_2d_copy(NPY_INT, 2, 8, side->rc));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *to_tns_data(PyObject *obj, struct lc3_tns_data *side)
|
|
{
|
|
PyObject *item;
|
|
|
|
CTYPES_CHECK("tns", obj && PyDict_Check(obj));
|
|
|
|
if ((item = PyDict_GetItemString(obj, "nfilters")))
|
|
CTYPES_CHECK("tns.nfilters",
|
|
to_scalar(item, NPY_INT, &side->nfilters));
|
|
|
|
if ((item = PyDict_GetItemString(obj, "lpc_weighting"))) {
|
|
CTYPES_CHECK("tns.lpc_weighting",
|
|
to_scalar(item, NPY_BOOL, &side->lpc_weighting));
|
|
}
|
|
|
|
if ((item = PyDict_GetItemString(obj, "rc_order"))) {
|
|
CTYPES_CHECK("tns.rc_order",
|
|
item = to_1d_copy(item, NPY_INT, side->rc_order, 2));
|
|
PyDict_SetItemString(obj, "rc_order", item);
|
|
}
|
|
|
|
if ((item = PyDict_GetItemString(obj, "rc"))) {
|
|
CTYPES_CHECK("tns.rc",
|
|
item = to_2d_copy(item, NPY_INT, side->rc, 2, 8));
|
|
PyDict_SetItemString(obj, "rc", item);
|
|
}
|
|
|
|
return obj;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
#include <spec.h>
|
|
|
|
__attribute__((unused))
|
|
static PyObject *from_spec_analysis(
|
|
PyObject *obj, const struct lc3_spec_analysis *spec)
|
|
{
|
|
if (!obj) obj = PyDict_New();
|
|
|
|
PyDict_SetItemString(obj, "nbits_off",
|
|
new_scalar(NPY_FLOAT, &spec->nbits_off));
|
|
|
|
PyDict_SetItemString(obj, "nbits_spare",
|
|
new_scalar(NPY_INT, &spec->nbits_spare));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *to_spec_analysis(
|
|
PyObject *obj, struct lc3_spec_analysis *spec)
|
|
{
|
|
CTYPES_CHECK("spec", obj && PyDict_Check(obj));
|
|
|
|
CTYPES_CHECK("spec.nbits_off",
|
|
to_scalar(PyDict_GetItemString(obj, "nbits_off"),
|
|
NPY_FLOAT, &spec->nbits_off));
|
|
|
|
CTYPES_CHECK("spec.nbits_spare",
|
|
to_scalar(PyDict_GetItemString(obj, "nbits_spare"),
|
|
NPY_INT, &spec->nbits_spare));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *new_spec_side(const struct lc3_spec_side *side)
|
|
{
|
|
PyObject *obj = PyDict_New();
|
|
|
|
PyDict_SetItemString(obj, "g_idx",
|
|
new_scalar(NPY_INT, &side->g_idx));
|
|
|
|
PyDict_SetItemString(obj, "nq",
|
|
new_scalar(NPY_INT, &side->nq));
|
|
|
|
PyDict_SetItemString(obj, "lsb_mode",
|
|
new_scalar(NPY_BOOL, &side->lsb_mode));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *to_spec_data(
|
|
PyObject *obj, struct lc3_spec_side *side)
|
|
{
|
|
PyObject *item;
|
|
|
|
CTYPES_CHECK("side", obj && PyDict_Check(obj));
|
|
|
|
if ((item = PyDict_GetItemString(obj, "g_idx")))
|
|
CTYPES_CHECK("side.g_idx",
|
|
to_scalar(item, NPY_INT, &side->g_idx));
|
|
|
|
if ((item = PyDict_GetItemString(obj, "nq")))
|
|
CTYPES_CHECK("side.nq",
|
|
to_scalar(item, NPY_INT, &side->nq));
|
|
|
|
if ((item = PyDict_GetItemString(obj, "lsb_mode")))
|
|
CTYPES_CHECK("side.lsb_mode",
|
|
to_scalar(item, NPY_BOOL, &side->lsb_mode));
|
|
|
|
return obj;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
#ifdef __CTYPES_LC3_C
|
|
|
|
__attribute__((unused))
|
|
static PyObject *new_side_data(const struct side_data *side)
|
|
{
|
|
PyObject *obj = PyDict_New();
|
|
|
|
PyDict_SetItemString(obj, "bw",
|
|
new_scalar(NPY_INT, &(int){ side->bw }));
|
|
|
|
PyDict_SetItemString(obj, "ltpf",
|
|
new_ltpf_data(&side->ltpf));
|
|
|
|
PyDict_SetItemString(obj, "sns",
|
|
new_sns_data(&side->sns));
|
|
|
|
PyDict_SetItemString(obj, "tns",
|
|
new_tns_data(&side->tns));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *to_side_data(PyObject *obj, struct side_data *side)
|
|
{
|
|
PyObject *item;
|
|
|
|
CTYPES_CHECK("frame", obj && PyDict_Check(obj));
|
|
|
|
if ((item = PyDict_GetItemString(obj, "bw"))) {
|
|
int bw;
|
|
CTYPES_CHECK("frame.bw", to_scalar(item, NPY_INT, &bw));
|
|
side->bw = bw;
|
|
}
|
|
|
|
if ((item = PyDict_GetItemString(obj, "ltpf")))
|
|
to_ltpf_data(item, &side->ltpf);
|
|
|
|
if ((item = PyDict_GetItemString(obj, "sns")))
|
|
to_sns_data(item, &side->sns);
|
|
|
|
if ((item = PyDict_GetItemString(obj, "tns")))
|
|
to_tns_data(item, &side->tns);
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *new_plc_state(const struct lc3_plc_state *plc)
|
|
{
|
|
PyObject *obj = PyDict_New();
|
|
|
|
PyDict_SetItemString(obj, "seed",
|
|
new_scalar(NPY_UINT16, &plc->seed));
|
|
|
|
PyDict_SetItemString(obj, "count",
|
|
new_scalar(NPY_INT, &plc->count));
|
|
|
|
PyDict_SetItemString(obj, "alpha",
|
|
new_scalar(NPY_FLOAT, &plc->alpha));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *to_plc_state(
|
|
PyObject *obj, struct lc3_plc_state *plc)
|
|
{
|
|
CTYPES_CHECK("plc", obj && PyDict_Check(obj));
|
|
|
|
CTYPES_CHECK("plc.seed", to_scalar(
|
|
PyDict_GetItemString(obj, "seed"), NPY_UINT16, &plc->seed));
|
|
|
|
CTYPES_CHECK("plc.count", to_scalar(
|
|
PyDict_GetItemString(obj, "count"), NPY_INT, &plc->count));
|
|
|
|
CTYPES_CHECK("plc.alpha", to_scalar(
|
|
PyDict_GetItemString(obj, "alpha"), NPY_FLOAT, &plc->alpha));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *from_encoder(PyObject *obj, const struct lc3_encoder *enc)
|
|
{
|
|
unsigned dt = enc->dt, sr = enc->sr;
|
|
unsigned sr_pcm = enc->sr_pcm;
|
|
int ns = LC3_NS(dt, sr);
|
|
int nd = LC3_ND(dt, sr);
|
|
|
|
if (!obj) obj = PyDict_New();
|
|
|
|
PyDict_SetItemString(obj, "dt",
|
|
new_scalar(NPY_INT, &dt));
|
|
|
|
PyDict_SetItemString(obj, "sr",
|
|
new_scalar(NPY_INT, &sr));
|
|
|
|
PyDict_SetItemString(obj, "sr_pcm",
|
|
new_scalar(NPY_INT, &sr_pcm));
|
|
|
|
PyDict_SetItemString(obj, "attdet",
|
|
from_attdet_analysis(NULL, &enc->attdet));
|
|
|
|
PyDict_SetItemString(obj, "ltpf",
|
|
from_ltpf_analysis(NULL, &enc->ltpf));
|
|
|
|
PyDict_SetItemString(obj, "quant",
|
|
from_spec_analysis(NULL, &enc->spec));
|
|
|
|
PyDict_SetItemString(obj, "xs",
|
|
new_1d_copy(NPY_FLOAT, ns+nd, enc->xs-nd));
|
|
|
|
PyDict_SetItemString(obj, "xf",
|
|
new_1d_copy(NPY_FLOAT, ns, enc->xf));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *to_encoder(PyObject *obj, struct lc3_encoder *enc)
|
|
{
|
|
unsigned dt, sr, sr_pcm;
|
|
PyObject *xs_obj, *xf_obj;
|
|
|
|
CTYPES_CHECK("encoder", obj && PyDict_Check(obj));
|
|
|
|
CTYPES_CHECK("encoder.dt", to_scalar(
|
|
PyDict_GetItemString(obj, "dt"), NPY_INT, &dt));
|
|
CTYPES_CHECK("encoder.dt", (unsigned)(enc->dt = dt) < LC3_NUM_DT);
|
|
|
|
CTYPES_CHECK("encoder.sr", to_scalar(
|
|
PyDict_GetItemString(obj, "sr"), NPY_INT, &sr));
|
|
CTYPES_CHECK("encoder.sr", (unsigned)(enc->sr = sr) < LC3_NUM_SRATE);
|
|
|
|
CTYPES_CHECK("encoder.sr_pcm", to_scalar(
|
|
PyDict_GetItemString(obj, "sr_pcm"), NPY_INT, &sr_pcm));
|
|
CTYPES_CHECK("encoder.s_pcmr",
|
|
(unsigned)(enc->sr_pcm = sr_pcm) < LC3_NUM_SRATE);
|
|
|
|
int ns = LC3_NS(dt, sr);
|
|
int nd = LC3_ND(dt, sr);
|
|
|
|
CTYPES_CHECK(NULL, to_attdet_analysis(
|
|
PyDict_GetItemString(obj, "attdet"), &enc->attdet));
|
|
|
|
CTYPES_CHECK(NULL, to_ltpf_analysis(
|
|
PyDict_GetItemString(obj, "ltpf"), &enc->ltpf));
|
|
|
|
CTYPES_CHECK(NULL, to_spec_analysis(
|
|
PyDict_GetItemString(obj, "quant"), &enc->spec));
|
|
|
|
CTYPES_CHECK("encoder.xs", xs_obj = to_1d_copy(
|
|
PyDict_GetItemString(obj, "xs"), NPY_FLOAT, enc->xs-nd, ns+nd));
|
|
PyDict_SetItemString(obj, "xs", xs_obj);
|
|
|
|
CTYPES_CHECK("encoder.xf", xf_obj = to_1d_copy(
|
|
PyDict_GetItemString(obj, "xf"), NPY_FLOAT, enc->xf, ns));
|
|
PyDict_SetItemString(obj, "xf", xf_obj);
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *from_decoder(PyObject *obj, const struct lc3_decoder *dec)
|
|
{
|
|
unsigned dt = dec->dt, sr = dec->sr;
|
|
unsigned sr_pcm = dec->sr_pcm;
|
|
int ns = LC3_NS(dt, sr);
|
|
int nd = LC3_ND(dt, sr);
|
|
int nh = LC3_NH(sr);
|
|
|
|
if (!obj) obj = PyDict_New();
|
|
|
|
PyDict_SetItemString(obj, "dt",
|
|
new_scalar(NPY_INT, &dt));
|
|
|
|
PyDict_SetItemString(obj, "sr",
|
|
new_scalar(NPY_INT, &sr));
|
|
|
|
PyDict_SetItemString(obj, "sr_pcm",
|
|
new_scalar(NPY_INT, &sr_pcm));
|
|
|
|
PyDict_SetItemString(obj, "ltpf",
|
|
from_ltpf_synthesis(NULL, &dec->ltpf));
|
|
|
|
PyDict_SetItemString(obj, "plc",
|
|
new_plc_state(&dec->plc));
|
|
|
|
PyDict_SetItemString(obj, "xs",
|
|
new_1d_copy(NPY_FLOAT, nh+ns, dec->xs-nh));
|
|
|
|
PyDict_SetItemString(obj, "xd",
|
|
new_1d_copy(NPY_FLOAT, nd, dec->xd));
|
|
|
|
PyDict_SetItemString(obj, "xg",
|
|
new_1d_copy(NPY_FLOAT, ns, dec->xg));
|
|
|
|
return obj;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
static PyObject *to_decoder(PyObject *obj, struct lc3_decoder *dec)
|
|
{
|
|
unsigned dt, sr, sr_pcm;
|
|
PyObject *xs_obj, *xd_obj, *xg_obj;
|
|
|
|
CTYPES_CHECK("decoder", obj && PyDict_Check(obj));
|
|
|
|
CTYPES_CHECK("decoder.dt", to_scalar(
|
|
PyDict_GetItemString(obj, "dt"), NPY_INT, &dt));
|
|
CTYPES_CHECK("decoder.dt", (unsigned)(dec->dt = dt) < LC3_NUM_DT);
|
|
|
|
CTYPES_CHECK("decoder.sr", to_scalar(
|
|
PyDict_GetItemString(obj, "sr"), NPY_INT, &sr));
|
|
CTYPES_CHECK("decoder.sr", (unsigned)(dec->sr = sr) < LC3_NUM_SRATE);
|
|
|
|
CTYPES_CHECK("decoder.sr_pcm", to_scalar(
|
|
PyDict_GetItemString(obj, "sr_pcm"), NPY_INT, &sr_pcm));
|
|
CTYPES_CHECK("decoder.sr_pcm",
|
|
(unsigned)(dec->sr_pcm = sr_pcm) < LC3_NUM_SRATE);
|
|
|
|
int ns = LC3_NS(dt, sr);
|
|
int nd = LC3_ND(dt, sr);
|
|
int nh = LC3_NH(sr);
|
|
|
|
CTYPES_CHECK(NULL, to_ltpf_synthesis(
|
|
PyDict_GetItemString(obj, "ltpf"), &dec->ltpf));
|
|
|
|
CTYPES_CHECK(NULL, to_plc_state(
|
|
PyDict_GetItemString(obj, "plc"), &dec->plc));
|
|
|
|
CTYPES_CHECK("decoder.xs", xs_obj = to_1d_copy(
|
|
PyDict_GetItemString(obj, "xs"), NPY_FLOAT, dec->xs-nh, nh+ns));
|
|
PyDict_SetItemString(obj, "xs", xs_obj);
|
|
|
|
CTYPES_CHECK("decoder.xd", xd_obj = to_1d_copy(
|
|
PyDict_GetItemString(obj, "xd"), NPY_FLOAT, dec->xd, nd));
|
|
PyDict_SetItemString(obj, "xd", xd_obj);
|
|
|
|
CTYPES_CHECK("decoder.xg", xg_obj = to_1d_copy(
|
|
PyDict_GetItemString(obj, "xg"), NPY_FLOAT, dec->xg, ns));
|
|
PyDict_SetItemString(obj, "xg", xg_obj);
|
|
|
|
return obj;
|
|
}
|
|
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
#endif /* __CTYPES_LC3_C */
|
|
|
|
#endif /* __CTYPES */
|