blob: 2442657d39c5abe374ddad9a538649d6f5d1ce55 [file] [log] [blame]
/******************************************************************************
*
* 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_INT32, &attdet->en1));
CTYPES_CHECK("attdet.an1", to_scalar(
PyDict_GetItemString(obj, "an1"), NPY_INT32, &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_INT32, &attdet->en1));
PyDict_SetItemString(obj, "an1",
new_scalar(NPY_INT32, &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_INT64, &hp50->s1));
CTYPES_CHECK("hp50.s2", to_scalar(
PyDict_GetItemString(obj, "s2"), NPY_INT64, &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_INT64, &hp50->s1));
PyDict_SetItemString(obj, "s2",
new_scalar(NPY_INT64, &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(*ltpf->x_12k8);
const int n_6k4 = sizeof(ltpf->x_6k4) / sizeof(*ltpf->x_6k4);
CTYPES_CHECK("ltpf", obj && PyDict_Check(obj));
CTYPES_CHECK("ltpf.active", to_scalar(
PyDict_GetItemString(obj, "active"), NPY_BOOL, &ltpf->active));
CTYPES_CHECK("ltpf.pitch", to_scalar(
PyDict_GetItemString(obj, "pitch"), NPY_INT, &ltpf->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"), &ltpf->hp50));
CTYPES_CHECK("ltpf.x_12k8", x_12k8_obj = to_1d_copy(
PyDict_GetItemString(obj, "x_12k8"), NPY_INT16, 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_INT16, 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, &ltpf->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(*ltpf->x_12k8);
const int n_6k4 = sizeof(ltpf->x_6k4) / sizeof(*ltpf->x_6k4);
if (!obj) obj = PyDict_New();
PyDict_SetItemString(obj, "active",
new_scalar(NPY_BOOL, &ltpf->active));
PyDict_SetItemString(obj, "pitch",
new_scalar(NPY_INT, &ltpf->pitch));
PyDict_SetItemString(obj, "nc",
new_1d_copy(NPY_FLOAT, 2, &ltpf->nc));
PyDict_SetItemString(obj, "hp50",
from_ltpf_hp50_state(PyDict_New(), &ltpf->hp50));
PyDict_SetItemString(obj, "x_12k8",
new_1d_copy(NPY_INT16, n_12k8, &ltpf->x_12k8));
PyDict_SetItemString(obj, "x_6k4",
new_1d_copy(NPY_INT16, n_6k4, &ltpf->x_6k4));
PyDict_SetItemString(obj, "tc",
new_scalar(NPY_INT, &ltpf->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, &ltpf->active));
CTYPES_CHECK("ltpf.pitch", to_scalar(
PyDict_GetItemString(obj, "pitch"), NPY_INT, &ltpf->pitch));
CTYPES_CHECK("ltpf.c", c_obj = to_1d_copy(
PyDict_GetItemString(obj, "c"), NPY_FLOAT, ltpf->c, 2*12));
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, &ltpf->active));
PyDict_SetItemString(obj, "pitch",
new_scalar(NPY_INT, &ltpf->pitch));
PyDict_SetItemString(obj, "c",
new_1d_copy(NPY_FLOAT, 2*12, &ltpf->c));
PyDict_SetItemString(obj, "x",
new_1d_copy(NPY_FLOAT, 12, &ltpf->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_BOOL, &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_BOOL, &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);
int nt = LC3_NT(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, "xt",
new_1d_copy(NPY_INT16, nt+ns,
(int16_t *)enc->x + enc->xt_off - nt));
PyDict_SetItemString(obj, "xs",
new_1d_copy(NPY_FLOAT, ns, enc->x + enc->xs_off));
PyDict_SetItemString(obj, "xd",
new_1d_copy(NPY_FLOAT, nd, enc->x + enc->xd_off));
return obj;
}
__attribute__((unused))
static PyObject *to_encoder(PyObject *obj, struct lc3_encoder *enc)
{
unsigned dt, sr, sr_pcm;
PyObject *xt_obj, *xs_obj, *xd_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);
int nt = LC3_NT(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.xt", xt_obj = to_1d_copy(
PyDict_GetItemString(obj, "xt"), NPY_INT16,
(int16_t *)enc->x + enc->xt_off - nt, ns+nt));
PyDict_SetItemString(obj, "xt", xt_obj);
CTYPES_CHECK("encoder.xs", xs_obj = to_1d_copy(
PyDict_GetItemString(obj, "xs"), NPY_FLOAT,
enc->x + enc->xs_off, ns));
PyDict_SetItemString(obj, "xs", xs_obj);
CTYPES_CHECK("encoder.xd", xd_obj = to_1d_copy(
PyDict_GetItemString(obj, "xd"), NPY_FLOAT,
enc->x + enc->xd_off, nd));
PyDict_SetItemString(obj, "xd", xd_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;
unsigned xs_pos = dec->xs_off - dec->xh_off;
int nh = LC3_NH(dt, sr);
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, "ltpf",
from_ltpf_synthesis(NULL, &dec->ltpf));
PyDict_SetItemString(obj, "plc",
new_plc_state(&dec->plc));
PyDict_SetItemString(obj, "xh",
new_1d_copy(NPY_FLOAT, nh, dec->x + dec->xh_off));
PyDict_SetItemString(obj, "xs_pos",
new_scalar(NPY_INT, &xs_pos));
PyDict_SetItemString(obj, "xd",
new_1d_copy(NPY_FLOAT, nd, dec->x + dec->xd_off));
PyDict_SetItemString(obj, "xg",
new_1d_copy(NPY_FLOAT, ns, dec->x + dec->xg_off));
return obj;
}
__attribute__((unused))
static PyObject *to_decoder(PyObject *obj, struct lc3_decoder *dec)
{
unsigned dt, sr, sr_pcm, xs_pos;
PyObject *xh_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 nh = LC3_NH(dt, sr);
int ns = LC3_NS(dt, sr);
int nd = LC3_ND(dt, 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.xh", xh_obj = to_1d_copy(
PyDict_GetItemString(obj, "xh"), NPY_FLOAT,
dec->x + dec->xh_off, nh));
PyDict_SetItemString(obj, "xh", xh_obj);
CTYPES_CHECK("decoder.xs", to_scalar(
PyDict_GetItemString(obj, "xs_pos"), NPY_INT, &xs_pos));
dec->xs_off = dec->xh_off + xs_pos;
CTYPES_CHECK("decoder.xd", xd_obj = to_1d_copy(
PyDict_GetItemString(obj, "xd"), NPY_FLOAT,
dec->x + dec->xd_off, nd));
PyDict_SetItemString(obj, "xd", xd_obj);
CTYPES_CHECK("decoder.xg", xg_obj = to_1d_copy(
PyDict_GetItemString(obj, "xg"), NPY_FLOAT,
dec->x + dec->xg_off, ns));
PyDict_SetItemString(obj, "xg", xg_obj);
return obj;
}
/* -------------------------------------------------------------------------- */
#endif /* __CTYPES_LC3_C */
#endif /* __CTYPES */