add from_int16_buffer, from_uint16_buffer functions
This commit is contained in:
parent
48418d46ab
commit
663a7d2fe0
4 changed files with 159 additions and 22 deletions
|
|
@ -619,6 +619,14 @@
|
|||
#define ULAB_HAS_UTILS_MODULE (1)
|
||||
#endif
|
||||
|
||||
#ifndef ULAB_UTILS_HAS_FROM_INT16_BUFFER
|
||||
#define ULAB_UTILS_HAS_FROM_INT16_BUFFER (1)
|
||||
#endif
|
||||
|
||||
#ifndef ULAB_UTILS_HAS_FROM_UINT16_BUFFER
|
||||
#define ULAB_UTILS_HAS_FROM_UINT16_BUFFER (1)
|
||||
#endif
|
||||
|
||||
#ifndef ULAB_UTILS_HAS_FROM_INT32_BUFFER
|
||||
#define ULAB_UTILS_HAS_FROM_INT32_BUFFER (1)
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -19,11 +19,13 @@
|
|||
#if ULAB_HAS_UTILS_MODULE
|
||||
|
||||
enum UTILS_BUFFER_TYPE {
|
||||
UTILS_INT16_BUFFER,
|
||||
UTILS_UINT16_BUFFER,
|
||||
UTILS_INT32_BUFFER,
|
||||
UTILS_UINT32_BUFFER,
|
||||
};
|
||||
|
||||
#if ULAB_UTILS_HAS_FROM_INT32_BUFFER | ULAB_UTILS_HAS_FROM_UINT32_BUFFER
|
||||
#if ULAB_UTILS_HAS_FROM_INT16_BUFFER | ULAB_UTILS_HAS_FROM_UINT16_BUFFER | ULAB_UTILS_HAS_FROM_INT32_BUFFER | ULAB_UTILS_HAS_FROM_UINT32_BUFFER
|
||||
static mp_obj_t utils_from_intbuffer_helper(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args, uint8_t buffer_type) {
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_rom_obj = mp_const_none } } ,
|
||||
|
|
@ -52,8 +54,15 @@ static mp_obj_t utils_from_intbuffer_helper(size_t n_args, const mp_obj_t *pos_a
|
|||
if(bufinfo.len < offset) {
|
||||
mp_raise_ValueError(translate("offset is too large"));
|
||||
}
|
||||
size_t len = (bufinfo.len - offset) / sizeof(int32_t);
|
||||
if((len * sizeof(int32_t)) != (bufinfo.len - offset)) {
|
||||
uint8_t sz = sizeof(int16_t);
|
||||
#if ULAB_UTILS_HAS_FROM_INT32_BUFFER | ULAB_UTILS_HAS_FROM_UINT32_BUFFER
|
||||
if((buffer_type == UTILS_INT32_BUFFER) || (buffer_type == UTILS_UINT32_BUFFER)) {
|
||||
sz = sizeof(int32_t);
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t len = (bufinfo.len - offset) / sz;
|
||||
if((len * sz) != (bufinfo.len - offset)) {
|
||||
mp_raise_ValueError(translate("buffer size must be a multiple of element size"));
|
||||
}
|
||||
if(mp_obj_get_int(args[1].u_obj) > 0) {
|
||||
|
|
@ -76,52 +85,118 @@ static mp_obj_t utils_from_intbuffer_helper(size_t n_args, const mp_obj_t *pos_a
|
|||
mp_float_t *array = (mp_float_t *)ndarray->array;
|
||||
if(args[4].u_obj == mp_const_true) {
|
||||
// swap the bytes before conversion
|
||||
uint8_t *tmpbuff = m_new(uint8_t, sizeof(int32_t));
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
tmpbuff += sizeof(int32_t);
|
||||
for(uint8_t j = 0; j < sizeof(int32_t); j++) {
|
||||
memcpy(--tmpbuff, buffer++, 1);
|
||||
}
|
||||
if(buffer_type == UTILS_INT32_BUFFER) {
|
||||
*array++ = (mp_float_t)(*(int32_t *)tmpbuff);
|
||||
} else {
|
||||
*array++ = (mp_float_t)(*(uint32_t *)tmpbuff);
|
||||
uint8_t *tmpbuff = m_new(uint8_t, sz);
|
||||
#if ULAB_UTILS_HAS_FROM_INT16_BUFFER | ULAB_UTILS_HAS_FROM_UINT16_BUFFER
|
||||
if((buffer_type == UTILS_INT16_BUFFER) || (buffer_type == UTILS_UINT16_BUFFER)) {
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
tmpbuff += sz;
|
||||
for(uint8_t j = 0; j < sz; j++) {
|
||||
memcpy(--tmpbuff, buffer++, 1);
|
||||
}
|
||||
if(buffer_type == UTILS_INT16_BUFFER) {
|
||||
*array++ = (mp_float_t)(*(int16_t *)tmpbuff);
|
||||
} else {
|
||||
*array++ = (mp_float_t)(*(uint16_t *)tmpbuff);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if ULAB_UTILS_HAS_FROM_INT32_BUFFER | ULAB_UTILS_HAS_FROM_UINT32_BUFFER
|
||||
if((buffer_type == UTILS_INT32_BUFFER) || (buffer_type == UTILS_UINT32_BUFFER)) {
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
tmpbuff += sz;
|
||||
for(uint8_t j = 0; j < sz; j++) {
|
||||
memcpy(--tmpbuff, buffer++, 1);
|
||||
}
|
||||
if(buffer_type == UTILS_INT32_BUFFER) {
|
||||
*array++ = (mp_float_t)(*(int32_t *)tmpbuff);
|
||||
} else {
|
||||
*array++ = (mp_float_t)(*(uint32_t *)tmpbuff);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
#if ULAB_UTILS_HAS_FROM_INT16_BUFFER
|
||||
if(buffer_type == UTILS_INT16_BUFFER) {
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
*array++ = (mp_float_t)(*(int16_t *)buffer);
|
||||
buffer += sz;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if ULAB_UTILS_HAS_FROM_UINT16_BUFFER
|
||||
if(buffer_type == UTILS_UINT16_BUFFER) {
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
*array++ = (mp_float_t)(*(uint16_t *)buffer);
|
||||
buffer += sz;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if ULAB_UTILS_HAS_FROM_INT32_BUFFER
|
||||
if(buffer_type == UTILS_INT32_BUFFER) {
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
*array++ = (mp_float_t)(*(int32_t *)buffer);
|
||||
buffer += sizeof(int32_t);
|
||||
}
|
||||
} else {
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
*array++ = (mp_float_t)(*(uint32_t *)buffer);
|
||||
buffer += sizeof(int32_t);
|
||||
buffer += sz;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if ULAB_UTILS_HAS_FROM_UINT32_BUFFER
|
||||
if(buffer_type == UTILS_UINT32_BUFFER) {
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
*array++ = (mp_float_t)(*(uint32_t *)buffer);
|
||||
buffer += sz;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return MP_OBJ_FROM_PTR(ndarray);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
#ifdef ULAB_UTILS_HAS_FROM_INT16_BUFFER
|
||||
static mp_obj_t utils_from_int16_buffer(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
return utils_from_intbuffer_helper(n_args, pos_args, kw_args, UTILS_INT16_BUFFER);
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(utils_from_int16_buffer_obj, 1, utils_from_int16_buffer);
|
||||
#endif
|
||||
|
||||
#ifdef ULAB_UTILS_HAS_FROM_UINT16_BUFFER
|
||||
static mp_obj_t utils_from_uint16_buffer(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
return utils_from_intbuffer_helper(n_args, pos_args, kw_args, UTILS_UINT16_BUFFER);
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(utils_from_uint16_buffer_obj, 1, utils_from_uint16_buffer);
|
||||
#endif
|
||||
|
||||
#ifdef ULAB_UTILS_HAS_FROM_INT32_BUFFER
|
||||
static mp_obj_t utils_from_int32_buffer(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
return utils_from_intbuffer_helper(n_args, pos_args, kw_args, UTILS_INT32_BUFFER);
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(utils_from_int32_buffer_obj, 1, utils_from_int32_buffer);
|
||||
#endif
|
||||
|
||||
#ifdef ULAB_UTILS_HAS_FROM_UINT32_BUFFER
|
||||
static mp_obj_t utils_from_uint32_buffer(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
return utils_from_intbuffer_helper(n_args, pos_args, kw_args, UTILS_UINT32_BUFFER);
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(utils_from_uint32_buffer_obj, 1, utils_from_uint32_buffer);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
static const mp_rom_map_elem_t ulab_utils_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_utils) },
|
||||
#if ULAB_UTILS_HAS_FROM_INT16_BUFFER
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_from_int16_buffer), (mp_obj_t)&utils_from_int16_buffer_obj },
|
||||
#endif
|
||||
#if ULAB_UTILS_HAS_FROM_UINT16_BUFFER
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_from_uint16_buffer), (mp_obj_t)&utils_from_uint16_buffer_obj },
|
||||
#endif
|
||||
#if ULAB_UTILS_HAS_FROM_INT32_BUFFER
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_from_int32_buffer), (mp_obj_t)&utils_from_int32_buffer_obj },
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -6,8 +6,29 @@ There might be cases, when the format of your data does not conform to
|
|||
``ulab``, i.e., there is no obvious way to map the data to any of the
|
||||
five supported ``dtype``\ s. A trivial example is an ADC or microphone
|
||||
signal with 32-bit resolution. For such cases, ``ulab`` defines the
|
||||
``utils`` module, which, at the moment, has two functions that are not
|
||||
``numpy`` compatible.
|
||||
``utils`` module, which, at the moment, has four functions that are not
|
||||
``numpy`` compatible, but which should ease interfacing ``ndarray``\ s
|
||||
to peripheral devices.
|
||||
|
||||
The ``utils`` module can be enabled by setting the
|
||||
``ULAB_HAS_UTILS_MODULE`` constant to 1 in
|
||||
`ulab.h <https://github.com/v923z/micropython-ulab/blob/master/code/ulab.h>`__:
|
||||
|
||||
.. code:: c
|
||||
|
||||
#ifndef ULAB_HAS_UTILS_MODULE
|
||||
#define ULAB_HAS_UTILS_MODULE (1)
|
||||
#endif
|
||||
|
||||
This still does not compile any functions into the firmware. You can add
|
||||
a function by setting the corresponding pre-processor constant to 1.
|
||||
E.g.,
|
||||
|
||||
.. code:: c
|
||||
|
||||
#ifndef ULAB_UTILS_HAS_FROM_INT16_BUFFER
|
||||
#define ULAB_UTILS_HAS_FROM_INT16_BUFFER (1)
|
||||
#endif
|
||||
|
||||
from_int32_buffer, from_uint32_buffer
|
||||
-------------------------------------
|
||||
|
|
@ -109,6 +130,13 @@ microcontroller, ``from_(u)intbuffer`` allows a conversion via the
|
|||
|
||||
|
||||
|
||||
from_int16_buffer, from_uint16_buffer
|
||||
-------------------------------------
|
||||
|
||||
These two functions are identical to ``utils.from_int32_buffer``, and
|
||||
``utils.from_uint32_buffer``, with the exception that they convert
|
||||
16-bit integers to floating point ``ndarray``\ s.
|
||||
|
||||
.. code::
|
||||
|
||||
# code to be run in CPython
|
||||
|
|
|
|||
|
|
@ -225,7 +225,24 @@
|
|||
"source": [
|
||||
"# ulab utilities\n",
|
||||
"\n",
|
||||
"There might be cases, when the format of your data does not conform to `ulab`, i.e., there is no obvious way to map the data to any of the five supported `dtype`s. A trivial example is an ADC or microphone signal with 32-bit resolution. For such cases, `ulab` defines the `utils` module, which, at the moment, has two functions that are not `numpy` compatible. "
|
||||
"\n",
|
||||
"There might be cases, when the format of your data does not conform to `ulab`, i.e., there is no obvious way to map the data to any of the five supported `dtype`s. A trivial example is an ADC or microphone signal with 32-bit resolution. For such cases, `ulab` defines the `utils` module, which, at the moment, has four functions that are not `numpy` compatible, but which should ease interfacing `ndarray`s to peripheral devices. \n",
|
||||
"\n",
|
||||
"The `utils` module can be enabled by setting the `ULAB_HAS_UTILS_MODULE` constant to 1 in [ulab.h](https://github.com/v923z/micropython-ulab/blob/master/code/ulab.h):\n",
|
||||
"\n",
|
||||
"```c\n",
|
||||
"#ifndef ULAB_HAS_UTILS_MODULE\n",
|
||||
"#define ULAB_HAS_UTILS_MODULE (1)\n",
|
||||
"#endif\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"This still does not compile any functions into the firmware. You can add a function by setting the corresponding pre-processor constant to 1. E.g., \n",
|
||||
"\n",
|
||||
"```c\n",
|
||||
"#ifndef ULAB_UTILS_HAS_FROM_INT16_BUFFER\n",
|
||||
"#define ULAB_UTILS_HAS_FROM_INT16_BUFFER (1)\n",
|
||||
"#endif\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -366,6 +383,15 @@
|
|||
"print('buffer with byteswapping: ', utils.from_uint32_buffer(a, byteswap=True))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## from_int16_buffer, from_uint16_buffer\n",
|
||||
"\n",
|
||||
"These two functions are identical to `utils.from_int32_buffer`, and `utils.from_uint32_buffer`, with the exception that they convert 16-bit integers to floating point `ndarray`s. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
|
|
|
|||
Loading…
Reference in a new issue