+
+ analog_size = ctx->num_analog_channels * sizeof(float);
+ if (ctx->dedup && !ctx->previous_sample)
+ ctx->previous_sample = g_malloc0(analog_size + ctx->num_logic_channels);
+
+ for (i = 0; i < ctx->num_samples; i++) {
+ analog_sample =
+ &ctx->analog_samples[i * ctx->num_analog_channels];
+ logic_sample =
+ &ctx->logic_samples[i * ctx->num_logic_channels];
+
+ if (ctx->dedup) {
+ if (i > 0 && i < ctx->num_samples - 1 &&
+ !memcmp(logic_sample, ctx->previous_sample,
+ ctx->num_logic_channels) &&
+ !memcmp(analog_sample,
+ ctx->previous_sample +
+ ctx->num_logic_channels,
+ analog_size))
+ continue;
+ memcpy(ctx->previous_sample, logic_sample,
+ ctx->num_logic_channels);
+ memcpy(ctx->previous_sample
+ + ctx->num_logic_channels,
+ analog_sample, analog_size);
+ }
+
+ 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",
+ sample_time_u64, ctx->value);
+ }
+
+ for (j = 0; j < num_channels; j++) {
+ if (ctx->channels[j].ch->type == SR_CHANNEL_ANALOG) {
+ value = ctx->analog_samples[i * ctx->num_analog_channels + j];
+ ctx->channels[j].max =
+ fmax(value, ctx->channels[j].max);
+ ctx->channels[j].min =
+ fmin(value, ctx->channels[j].min);
+ g_string_append_printf(*out, "%g%s",
+ value, ctx->value);
+ } else if (ctx->channels[j].ch->type == SR_CHANNEL_LOGIC) {
+ g_string_append_printf(*out, "%c%s",
+ ctx->logic_samples[i * ctx->num_logic_channels + j] ? '1' : '0', ctx->value);
+ } else {
+ sr_warn("Unexpected channel type: %d",
+ ctx->channels[i].ch->type);
+ }
+ }
+
+ if (ctx->do_trigger) {
+ g_string_append_printf(*out, "%d%s",
+ ctx->trigger, ctx->value);
+ ctx->trigger = FALSE;
+ }
+ g_string_truncate(*out, (*out)->len - 1);
+ g_string_append(*out, ctx->record);
+ }
+ }
+
+ /* Discard all of the working space. */
+ g_free(ctx->previous_sample);
+ g_free(ctx->analog_samples);
+ g_free(ctx->logic_samples);
+ ctx->channels_seen = 0;
+ ctx->num_samples = 0;
+ ctx->previous_sample = NULL;
+ ctx->analog_samples = NULL;
+ ctx->logic_samples = NULL;
+}
+
+static void save_gnuplot(struct context *ctx)
+{
+ float offset, max, sum;
+ unsigned int i, num_channels;
+ GString *script;
+
+ script = g_string_sized_new(512);
+ g_string_append_printf(script, "set datafile separator '%s'\n",
+ ctx->value);
+ if (ctx->label_did)
+ g_string_append(script, "set key autotitle columnhead\n");
+ if (ctx->xlabel && ctx->time)
+ g_string_append_printf(script, "set xlabel '%s'\n",
+ ctx->xlabel);
+
+ g_string_append(script, "plot ");
+
+ num_channels = ctx->num_analog_channels + ctx->num_logic_channels;
+
+ /* Graph position and scaling. */
+ max = FLT_MIN;
+ sum = 0;
+ for (i = 0; i < num_channels; i++) {
+ ctx->channels[i].max =
+ ctx->channels[i].max - ctx->channels[i].min;
+ max = fmax(max, ctx->channels[i].max);
+ sum += ctx->channels[i].max;
+ }
+ sum = (ctx->scale ? max : sum / num_channels) / 4;
+ offset = sum;
+ for (i = num_channels; i > 0;) {
+ i--;
+ ctx->channels[i].min = offset - ctx->channels[i].min;
+ offset += sum + (ctx->scale ? max : ctx->channels[i].max);