]> sigrok.org Git - libsigrok.git/commitdiff
output/csv: complete and improve timestamp construction support
authorGerhard Sittig <redacted>
Wed, 5 Aug 2020 17:52:17 +0000 (19:52 +0200)
committerGerhard Sittig <redacted>
Wed, 5 Aug 2020 19:03:11 +0000 (21:03 +0200)
Unbreak the timestamp calculation when session data is received in
multiple packets. Avoid a division by zero when the samplerate is not
known yet the time column is requested. Only calculate timestamps when
the time column is requested. Use floating point during the scaling,
only convert to integer immediately before printing. Change line breaks
to not split a complex sub-expression across several lines.

src/output/csv.c

index 791ddc39b9267ae4841312430847a9f06f647a33..296d9a06b0ab541037b588b63a42f7d62b13a619 100644 (file)
@@ -95,7 +95,7 @@ struct context {
        uint32_t channels_seen;
        uint64_t sample_rate;
        uint64_t sample_scale;
-       uint64_t sample_time;
+       uint64_t out_sample_count;
        uint8_t *previous_sample;
        float *analog_samples;
        uint8_t *logic_samples;
@@ -278,6 +278,10 @@ static GString *gen_header(const struct sr_output *o,
                ctx->did_header = TRUE;
        }
 
+       /* Time column requested but samplerate unknown. Emit a warning. */
+       if (ctx->time && !ctx->sample_rate)
+               sr_warn("Samplerate unknown, cannot provide timestamps.");
+
        return header;
 }
 
@@ -399,6 +403,8 @@ static void process_logic(struct context *ctx,
 static void dump_saved_values(struct context *ctx, GString **out)
 {
        unsigned int i, j, analog_size, num_channels;
+       double sample_time_dbl;
+       uint64_t sample_time_u64;
        float *analog_sample, value;
        uint8_t *logic_sample;
 
@@ -416,8 +422,8 @@ static void dump_saved_values(struct context *ctx, GString **out)
                if (ctx->label_do) {
                        if (ctx->time)
                                g_string_append_printf(*out, "%s%s",
-                                       ctx->label_names ? "Time" :
-                                       ctx->xlabel, ctx->value);
+                                       ctx->label_names ? "Time" : ctx->xlabel,
+                                       ctx->value);
                        for (i = 0; i < num_channels; i++) {
                                g_string_append_printf(*out, "%s%s",
                                        ctx->channels[i].label, ctx->value);
@@ -440,7 +446,6 @@ static void dump_saved_values(struct context *ctx, GString **out)
                        ctx->previous_sample = g_malloc0(analog_size + ctx->num_logic_channels);
 
                for (i = 0; i < ctx->num_samples; i++) {
-                       ctx->sample_time = (ctx->sample_scale * i) / ctx->sample_rate;
                        analog_sample =
                            &ctx->analog_samples[i * ctx->num_analog_channels];
                        logic_sample =
@@ -462,9 +467,16 @@ static void dump_saved_values(struct context *ctx, GString **out)
                                       analog_sample, analog_size);
                        }
 
-                       if (ctx->time)
+                       if (ctx->time && !ctx->sample_rate) {
+                               g_string_append_printf(*out, "0%s", ctx->value);
+                       } else if (ctx->time) {
+                               sample_time_dbl = ctx->out_sample_count++;
+                               sample_time_dbl /= ctx->sample_rate;
+                               sample_time_dbl *= ctx->sample_scale;
+                               sample_time_u64 = sample_time_dbl;
                                g_string_append_printf(*out, "%" PRIu64 "%s",
-                                       ctx->sample_time, ctx->value);
+                                       sample_time_u64, ctx->value);
+                       }
 
                        for (j = 0; j < num_channels; j++) {
                                if (ctx->channels[j].ch->type == SR_CHANNEL_ANALOG) {