From: Bert Vermeulen Date: Wed, 12 Nov 2014 16:05:13 +0000 (+0100) Subject: Add sr_analog_to_float(). X-Git-Tag: libsigrok-0.4.0~778 X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=fb019a0e4d28fe381ce8142f3ec00a6e8731e094;p=libsigrok.git Add sr_analog_to_float(). --- diff --git a/Makefile.am b/Makefile.am index 7b67a9a5..2487b2ef 100644 --- a/Makefile.am +++ b/Makefile.am @@ -35,6 +35,7 @@ libsigrok_la_SOURCES = \ src/hwdriver.c \ src/trigger.c \ src/soft-trigger.c \ + src/analog.c \ src/strutil.c \ src/log.c \ src/version.c \ diff --git a/include/libsigrok/proto.h b/include/libsigrok/proto.h index f4fbb049..dfce6aa2 100644 --- a/include/libsigrok/proto.h +++ b/include/libsigrok/proto.h @@ -26,6 +26,11 @@ * Header file containing API function prototypes. */ +/*--- analog.c --------------------------------------------------------------*/ + +SR_API int sr_analog_to_float(const struct sr_datafeed_analog2 *analog, + float *buf); + /*--- backend.c -------------------------------------------------------------*/ SR_API int sr_init(struct sr_context **ctx); diff --git a/src/analog.c b/src/analog.c new file mode 100644 index 00000000..0f7a3071 --- /dev/null +++ b/src/analog.c @@ -0,0 +1,66 @@ +/* + * This file is part of the libsigrok project. + * + * Copyright (C) 2014 Bert Vermeulen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include "libsigrok.h" +#include "libsigrok-internal.h" + +#define LOG_PREFIX "analog" + +SR_API int sr_analog_to_float(const struct sr_datafeed_analog2 *analog, + float *buf) +{ + float offset; + unsigned int b, i; + gboolean bigendian; + +#ifdef WORDS_BIGENDIAN + bigendian = TRUE; +#else + bigendian = FALSE; +#endif + if (!analog->encoding->is_float) { + /* TODO */ + sr_err("Only floating-point analog data supported so far."); + return SR_ERR; + } + + if (analog->encoding->unitsize == sizeof(float) + && analog->encoding->is_bigendian == bigendian + && (analog->encoding->scale.p == analog->encoding->scale.q) + && analog->encoding->scale.p / (float)analog->encoding->scale.q == 0) { + /* The data is already in the right format. */ + memcpy(buf, analog->data, analog->num_samples * sizeof(float)); + } else { + for (i = 0; i < analog->num_samples; i += analog->encoding->unitsize) { + for (b = 0; b < analog->encoding->unitsize; b++) { + if (analog->encoding->is_bigendian == bigendian) + buf[i + b] = ((float *)analog->data)[i * analog->encoding->unitsize + b]; + else + buf[i + (analog->encoding->unitsize - b)] = ((float *)analog->data)[i * analog->encoding->unitsize + b]; + } + if (analog->encoding->scale.p != analog->encoding->scale.q) + buf[i] = (buf[i] * analog->encoding->scale.p) / analog->encoding->scale.q; + offset = ((float)analog->encoding->scale.p / (float)analog->encoding->scale.q); + buf[i] += offset; + } + } + + return SR_OK; +}