analog: add conversion from various integer formats to float

This commit is contained in:
Stefan Brüns 2015-11-25 01:41:41 +01:00 committed by Uwe Hermann
parent 74c9a8d2bd
commit 4d376e082c
2 changed files with 94 additions and 3 deletions

View File

@ -187,10 +187,81 @@ SR_API int sr_analog_to_float(const struct sr_datafeed_analog *analog,
bigendian = FALSE;
#endif
if (!analog->encoding->is_float) {
/* TODO */
sr_err("Only floating-point encoding supported so far.");
float offset = analog->encoding->offset.p / (float)analog->encoding->offset.q;
float scale = analog->encoding->scale.p / (float)analog->encoding->scale.q;
gboolean is_signed = analog->encoding->is_signed;
gboolean is_bigendian = analog->encoding->is_bigendian;
int8_t *data8 = (int8_t *)(analog->data);
int16_t *data16 = (int16_t *)(analog->data);
int32_t *data32 = (int32_t *)(analog->data);
switch (analog->encoding->unitsize) {
case 1:
if (is_signed) {
for (unsigned int i = 0; i < count; i++) {
outbuf[i] = scale * data8[i];
outbuf[i] += offset;
}
} else {
for (unsigned int i = 0; i < count; i++) {
outbuf[i] = scale * R8(data8 + i);
outbuf[i] += offset;
}
}
break;
case 2:
if (is_signed && is_bigendian) {
for (unsigned int i = 0; i < count; i++) {
outbuf[i] = scale * RB16S(&data16[i]);
outbuf[i] += offset;
}
} else if (is_bigendian) {
for (unsigned int i = 0; i < count; i++) {
outbuf[i] = scale * RB16(&data16[i]);
outbuf[i] += offset;
}
} else if (is_signed) {
for (unsigned int i = 0; i < count; i++) {
outbuf[i] = scale * RL16S(&data16[i]);
outbuf[i] += offset;
}
} else {
for (unsigned int i = 0; i < count; i++) {
outbuf[i] = scale * RL16(&data16[i]);
outbuf[i] += offset;
}
}
break;
case 4:
if (is_signed && is_bigendian) {
for (unsigned int i = 0; i < count; i++) {
outbuf[i] = scale * RB32S(&data32[i]);
outbuf[i] += offset;
}
} else if (is_bigendian) {
for (unsigned int i = 0; i < count; i++) {
outbuf[i] = scale * RB32(&data32[i]);
outbuf[i] += offset;
}
} else if (is_signed) {
for (unsigned int i = 0; i < count; i++) {
outbuf[i] = scale * RL32S(&data32[i]);
outbuf[i] += offset;
}
} else {
for (unsigned int i = 0; i < count; i++) {
outbuf[i] = scale * RL32(&data32[i]);
outbuf[i] += offset;
}
}
break;
default:
sr_err("Unsupported unit size '%d' for analog-to-float conversion.",
analog->encoding->unitsize);
return SR_ERR;
}
return SR_OK;
}
if (analog->encoding->unitsize == sizeof(float)
&& analog->encoding->is_bigendian == bigendian

View File

@ -76,6 +76,15 @@ struct zip_stat;
#define RL16(x) (((unsigned)((const uint8_t*)(x))[1] << 8) | \
(unsigned)((const uint8_t*)(x))[0])
/**
* Read a 16 bits big endian signed integer out of memory.
* @param x a pointer to the input memory
* @return the corresponding signed integer
*/
#define RB16S(x) ((int16_t) \
(((unsigned)((const uint8_t*)(x))[0] << 8) | \
(unsigned)((const uint8_t*)(x))[1]))
/**
* Read a 16 bits little endian signed integer out of memory.
* @param x a pointer to the input memory
@ -105,6 +114,17 @@ struct zip_stat;
((unsigned)((const uint8_t*)(x))[1] << 8) | \
(unsigned)((const uint8_t*)(x))[0])
/**
* Read a 32 bits big endian signed integer out of memory.
* @param x a pointer to the input memory
* @return the corresponding signed integer
*/
#define RB32S(x) ((int32_t) \
(((unsigned)((const uint8_t*)(x))[0] << 24) | \
((unsigned)((const uint8_t*)(x))[1] << 16) | \
((unsigned)((const uint8_t*)(x))[2] << 8) | \
(unsigned)((const uint8_t*)(x))[3]))
/**
* Read a 32 bits little endian signed integer out of memory.
* @param x a pointer to the input memory