27 #include "libsigrok-internal.h"
30 #define LOG_PREFIX "analog"
47 struct unit_mq_string {
53 static struct unit_mq_string unit_strings[] = {
95 static struct unit_mq_string mq_strings[] = {
129 memset(analog, 0,
sizeof(*analog));
130 memset(encoding, 0,
sizeof(*encoding));
131 memset(meaning, 0,
sizeof(*meaning));
132 memset(spec, 0,
sizeof(*spec));
140 #ifdef WORDS_BIGENDIAN
145 encoding->
digits = digits;
177 unsigned int b, count;
180 if (!analog || !(analog->
data) || !(analog->
meaning)
186 #ifdef WORDS_BIGENDIAN
197 int8_t *data8 = (int8_t *)(analog->
data);
198 int16_t *data16 = (int16_t *)(analog->
data);
199 int32_t *data32 = (int32_t *)(analog->
data);
204 for (
unsigned int i = 0; i < count; i++) {
205 outbuf[i] = scale * data8[i];
209 for (
unsigned int i = 0; i < count; i++) {
210 outbuf[i] = scale * R8(data8 + i);
216 if (is_signed && is_bigendian) {
217 for (
unsigned int i = 0; i < count; i++) {
218 outbuf[i] = scale * RB16S(&data16[i]);
221 }
else if (is_bigendian) {
222 for (
unsigned int i = 0; i < count; i++) {
223 outbuf[i] = scale * RB16(&data16[i]);
226 }
else if (is_signed) {
227 for (
unsigned int i = 0; i < count; i++) {
228 outbuf[i] = scale * RL16S(&data16[i]);
232 for (
unsigned int i = 0; i < count; i++) {
233 outbuf[i] = scale * RL16(&data16[i]);
239 if (is_signed && is_bigendian) {
240 for (
unsigned int i = 0; i < count; i++) {
241 outbuf[i] = scale * RB32S(&data32[i]);
244 }
else if (is_bigendian) {
245 for (
unsigned int i = 0; i < count; i++) {
246 outbuf[i] = scale * RB32(&data32[i]);
249 }
else if (is_signed) {
250 for (
unsigned int i = 0; i < count; i++) {
251 outbuf[i] = scale * RL32S(&data32[i]);
255 for (
unsigned int i = 0; i < count; i++) {
256 outbuf[i] = scale * RL32(&data32[i]);
262 sr_err(
"Unsupported unit size '%d' for analog-to-float"
275 memcpy(outbuf, analog->
data, count *
sizeof(
float));
280 ((uint8_t *)outbuf)[i + b] =
310 #define NEG_PREFIX_COUNT 5
311 #define POS_PREFIX_COUNT (int)(ARRAY_SIZE(prefixes) - NEG_PREFIX_COUNT - 1)
313 static const char *prefixes[] = {
"f",
"p",
"n",
"µ",
"m",
"",
"k",
"M",
"G",
"T" };
315 if (!value || !digits || isnan(*value))
316 return prefixes[NEG_PREFIX_COUNT];
318 float logval = log10f(fabsf(*value));
319 int prefix = (logval / 3) - (logval < 1);
321 if (prefix < -NEG_PREFIX_COUNT)
322 prefix = -NEG_PREFIX_COUNT;
323 if (3 * prefix < -*digits)
324 prefix = (-*digits + 2 * (*digits < 0)) / 3;
325 if (prefix > POS_PREFIX_COUNT)
326 prefix = POS_PREFIX_COUNT;
328 *value *= powf(10, -3 * prefix);
329 *digits += 3 * prefix;
331 return prefixes[prefix + NEG_PREFIX_COUNT];
348 static const enum sr_unit prefix_friendly_units[] = {
366 for (i = 0; i < ARRAY_SIZE(prefix_friendly_units); i++)
367 if (unit == prefix_friendly_units[i])
394 if (!analog || !(analog->
meaning) || !result)
397 buf = g_string_new(NULL);
399 for (i = 0; unit_strings[i].value; i++) {
400 if (analog->
meaning->
unit == unit_strings[i].value) {
401 g_string_assign(buf, unit_strings[i].str);
407 for (i = 0; mq_strings[i].value; i++)
409 g_string_append(buf, mq_strings[i].str);
412 g_string_free(buf, FALSE);
435 #ifndef HAVE___INT128_T
441 struct sr_uint128_t {
446 static void mult_int64(
struct sr_int128_t *res,
const int64_t a,
449 uint64_t t1, t2, t3, t4;
451 t1 = (UINT32_MAX & a) * (UINT32_MAX & b);
452 t2 = (UINT32_MAX & a) * (b >> 32);
453 t3 = (a >> 32) * (UINT32_MAX & b);
454 t4 = (a >> 32) * (b >> 32);
456 res->low = t1 + (t2 << 32) + (t3 << 32);
457 res->high = (t1 >> 32) + (uint64_t)((uint32_t)(t2)) + (uint64_t)((uint32_t)(t3));
459 res->high += ((int64_t)t2 >> 32) + ((int64_t)t3 >> 32) + t4;
462 static void mult_uint64(
struct sr_uint128_t *res,
const uint64_t a,
465 uint64_t t1, t2, t3, t4;
468 t1 = (UINT32_MAX & a) * (UINT32_MAX & b);
469 t2 = (UINT32_MAX & a) * (b >> 32);
470 t3 = (a >> 32) * (UINT32_MAX & b);
471 t4 = (a >> 32) * (b >> 32);
473 res->low = t1 + (t2 << 32) + (t3 << 32);
474 res->high = (t1 >> 32) + (uint64_t)((uint32_t)(t2)) + (uint64_t)((uint32_t)(t3));
476 res->high += ((int64_t)t2 >> 32) + ((int64_t)t3 >> 32) + t4;
495 #ifdef HAVE___INT128_T
499 m1 = ((__int128_t)(b->
p)) * ((__uint128_t)a->
q);
500 m2 = ((__int128_t)(a->
p)) * ((__uint128_t)b->
q);
505 struct sr_int128_t m1, m2;
507 mult_int64(&m1, a->
q, b->
p);
508 mult_int64(&m2, a->
p, b->
q);
510 return (m1.high == m2.high) && (m1.low == m2.low);
535 #ifdef HAVE___INT128_T
539 p = (__int128_t)(a->
p) * (__int128_t)(b->
p);
540 q = (__uint128_t)(a->
q) * (__uint128_t)(b->
q);
542 if ((p > INT64_MAX) || (p < INT64_MIN) || (q > UINT64_MAX)) {
543 while (!((p & 1) || (q & 1))) {
549 if ((p > INT64_MAX) || (p < INT64_MIN) || (q > UINT64_MAX)) {
555 res->
q = (uint64_t)q;
560 struct sr_int128_t p;
561 struct sr_uint128_t q;
563 mult_int64(&p, a->
p, b->
p);
564 mult_uint64(&q, a->
q, b->
q);
566 while (!(p.low & 1) && !(q.low & 1)) {
569 p.low |= (1ll << 63);
573 q.low |= (1ll << 63);
579 if ((p.high >= 0) && (p.low > INT64_MAX))
584 res->
p = (int64_t)p.low;
616 if (div->
q > INT64_MAX)
Generic/unspecified error.
Time is duration (as opposed to epoch, ...).
Sound pressure level is not weighted in the frequency domain, albeit without standards-defined low an...
int sr_rational_mult(struct sr_rational *res, const struct sr_rational *a, const struct sr_rational *b)
Multiply two sr_rational.
void sr_rational_set(struct sr_rational *r, int64_t p, uint64_t q)
Set sr_rational r to the given value.
Sound pressure level is A-weighted in the frequency domain, according to IEC 61672:2003.
Measurement is four wire (e.g.
Degrees Fahrenheit (temperature).
This is a true RMS measurement.
Normalized (0 to 1) concentration of a substance or compound with 0 representing a concentration of 0...
Plane angle in 1/360th of a full circle.
Sound pressure level measurement is S-weighted (1s) in the time domain.
Unit of conductance, the inverse of resistance.
Sound pressure level measurement is F-weighted (125ms) in the time domain.
Degrees Celsius (temperature).
The public libsigrok header file to be used by frontends.
An absolute measurement of power, in decibels, referenced to 1 milliwatt (dBm).
Sound pressure level is time-averaged (LAT), also known as Equivalent Continuous A-weighted Sound Lev...
Device is in autoranging mode.
Pieces (number of items).
Sound pressure level is C-weighted in the frequency domain, according to IEC 61672:2003.
Mass in tael (variants: Hong Kong, Singapore/Malaysia, Taiwan)
struct sr_analog_encoding * encoding
Device is in "min" mode, only updating upon a new min value.
Sound pressure level represented as a percentage of measurements that were over a preset alarm level...
Voltage measurement is alternating current (AC).
int sr_analog_unit_to_string(const struct sr_datafeed_analog *analog, char **result)
Convert the unit/MQ/MQ flags in the analog struct to a string.
Device is in "hold" mode (repeating the last measurement).
int8_t spec_digits
Number of significant digits after the decimal point if positive, or number of non-significant digits...
int sr_analog_to_float(const struct sr_datafeed_analog *analog, float *outbuf)
Convert an analog datafeed payload to an array of floats.
sr_unit
Unit of measured quantity, sr_analog_meaning.unit.
struct sr_analog_meaning * meaning
Hertz (frequency, 1/s, [Hz]).
gboolean is_digits_decimal
Device is in "avg" mode, averaging upon each new value.
Voltage measurement is direct current (DC).
struct sr_analog_spec * spec
uint64_t q
Denominator of the rational number.
Mass in troy ounce [oz t].
gboolean sr_analog_si_prefix_friendly(enum sr_unit unit)
Check if a unit "accepts" an SI prefix.
int64_t p
Numerator of the rational number.
Voltage in decibel, referenced to 1 volt (dBV).
Analog datafeed payload for type SR_DF_ANALOG.
struct sr_rational offset
const char * sr_analog_si_prefix(float *value, int *digits)
Scale a float value to the appropriate SI prefix.
Sound pressure level is Z-weighted (i.e.
Relative humidity assuming air temperature of 293 Kelvin (rF).
Value is voltage drop across a diode, or NAN.
Sound pressure level, in decibels, relative to 20 micropascals.
Mass in pennyweight [dwt].
Device is in "max" mode, only updating upon a new max value.
Device is in relative mode.
int sr_rational_eq(const struct sr_rational *a, const struct sr_rational *b)
Compare two sr_rational for equality.
Wind speed in meters per second.
int sr_rational_div(struct sr_rational *res, const struct sr_rational *num, const struct sr_rational *div)
Divide rational a by rational b.
int8_t digits
Number of significant digits after the decimal point if positive, or number of non-significant digits...
Measurements that intrinsically do not have units attached, such as ratios, gains, etc.
Unstable value (hasn't settled yet).