]> sigrok.org Git - libsigrok.git/blob - src/analog.c
analog: Fix analog_to_float typos, and cleanup.
[libsigrok.git] / src / analog.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2014 Bert Vermeulen <bert@biot.com>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <string.h>
21 #include "libsigrok.h"
22 #include "libsigrok-internal.h"
23
24 #define LOG_PREFIX "analog"
25
26 SR_PRIV int sr_analog_init(struct sr_datafeed_analog2 *analog,
27                 struct sr_analog_encoding *encoding,
28                 struct sr_analog_meaning *meaning,
29                 struct sr_analog_spec *spec,
30                 int digits)
31 {
32         memset(analog, 0, sizeof(*analog));
33         memset(encoding, 0, sizeof(*encoding));
34         memset(meaning, 0, sizeof(*meaning));
35         memset(spec, 0, sizeof(*spec));
36
37         analog->encoding = encoding;
38         analog->meaning = meaning;
39         analog->spec = spec;
40
41         encoding->unitsize = sizeof(float);
42         encoding->is_float = TRUE;
43 #ifdef WORDS_BIGENDIAN
44         encoding->is_bigendian = TRUE;
45 #else
46         encoding->is_bigendian = FALSE;
47 #endif
48         encoding->digits = digits;
49         encoding->is_digits_decimal = TRUE;
50         encoding->scale.p = 1;
51         encoding->scale.q = 1;
52         encoding->offset.p = 0;
53         encoding->offset.q = 1;
54
55         spec->spec_digits = digits;
56
57         return SR_OK;
58 }
59
60 SR_API int sr_analog_to_float(const struct sr_datafeed_analog2 *analog,
61                 float *outbuf)
62 {
63         float offset;
64         unsigned int b, i;
65         gboolean bigendian;
66
67 #ifdef WORDS_BIGENDIAN
68         bigendian = TRUE;
69 #else
70         bigendian = FALSE;
71 #endif
72         if (!analog->encoding->is_float) {
73                 /* TODO */
74                 sr_err("Only floating-point encoding supported so far.");
75                 return SR_ERR;
76         }
77
78         if (analog->encoding->unitsize == sizeof(float)
79                         && analog->encoding->is_bigendian == bigendian
80                         && (analog->encoding->scale.p == analog->encoding->scale.q)
81                         && analog->encoding->offset.p / (float)analog->encoding->offset.q == 0) {
82                 /* The data is already in the right format. */
83                 memcpy(outbuf, analog->data, analog->num_samples * sizeof(float));
84         } else {
85                 for (i = 0; i < analog->num_samples; i += analog->encoding->unitsize) {
86                         for (b = 0; b < analog->encoding->unitsize; b++) {
87                                 if (analog->encoding->is_bigendian == bigendian)
88                                         outbuf[i + b] = ((float *)analog->data)[i * analog->encoding->unitsize + b];
89                                 else
90                                         outbuf[i + (analog->encoding->unitsize - b)] = ((float *)analog->data)[i * analog->encoding->unitsize + b];
91                         }
92                         if (analog->encoding->scale.p != analog->encoding->scale.q)
93                                 outbuf[i] = (outbuf[i] * analog->encoding->scale.p) / analog->encoding->scale.q;
94                         offset = ((float)analog->encoding->offset.p / (float)analog->encoding->offset.q);
95                         outbuf[i] += offset;
96                 }
97         }
98
99         return SR_OK;
100 }