/****************************************************************************** * * 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, <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_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, <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(*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, <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_INT16, n_12k8, <pf->x_12k8)); PyDict_SetItemString(obj, "x_6k4", new_1d_copy(NPY_INT16, 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_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, <pf->active)); PyDict_SetItemString(obj, "pitch", new_scalar(NPY_INT, <pf->pitch)); PyDict_SetItemString(obj, "c", new_1d_copy(NPY_FLOAT, 2*12, <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_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 + ns, 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 + ns)); 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 */