+ int ret;
+ unsigned int i, j, c, num_channels;
+ struct sr_analog_meaning *meaning;
+ GSList *l;
+ float *fdata = NULL;
+
+ if (!ctx->analog_samples) {
+ ctx->analog_samples = g_malloc(analog->num_samples
+ * sizeof(float) * ctx->num_analog_channels);
+ if (!ctx->num_samples)
+ ctx->num_samples = analog->num_samples;
+ }
+ if (ctx->num_samples != analog->num_samples)
+ sr_warn("Expecting %u analog samples, got %u.",
+ ctx->num_samples, analog->num_samples);
+
+ meaning = analog->meaning;
+ num_channels = g_slist_length(meaning->channels);
+ ctx->channels_seen += num_channels;
+ sr_dbg("Processing packet of %u analog channels", num_channels);
+ fdata = g_malloc(analog->num_samples * num_channels * sizeof(float));
+ if ((ret = sr_analog_to_float(analog, fdata)) != SR_OK)
+ sr_warn("Problems converting data to floating point values.");
+
+ for (i = 0; i < ctx->num_analog_channels + ctx->num_logic_channels; i++) {
+ if (ctx->channels[i].ch->type == SR_CHANNEL_ANALOG) {
+ sr_dbg("Looking for channel %s",
+ ctx->channels[i].ch->name);
+ for (l = meaning->channels, c = 0; l; l = l->next, c++) {
+ struct sr_channel *ch = l->data;
+ sr_dbg("Checking %s", ch->name);
+ if (ctx->channels[i].ch == l->data) {
+ if (ctx->label_do && !ctx->label_names) {
+ sr_analog_unit_to_string(analog,
+ &ctx->channels[i].label);
+ }
+ for (j = 0; j < analog->num_samples; j++)
+ ctx->analog_samples[j * ctx->num_analog_channels + i] = fdata[j * num_channels + c];
+ break;
+ }
+ }
+ }
+ }
+ g_free(fdata);
+}
+
+/*
+ * We treat logic packets the same as analog packets, though it's not
+ * strictly required. This allows us to process mixed signals properly.
+ */
+static void process_logic(struct context *ctx,
+ const struct sr_datafeed_logic *logic)
+{
+ unsigned int i, j, ch, num_samples;
+ int idx;
+ uint8_t *sample;
+
+ num_samples = logic->length / logic->unitsize;
+ ctx->channels_seen += ctx->logic_channel_count;
+ sr_dbg("Logic packet had %d channels", logic->unitsize * 8);
+ if (!ctx->logic_samples) {
+ ctx->logic_samples = g_malloc(num_samples * ctx->num_logic_channels);
+ if (!ctx->num_samples)
+ ctx->num_samples = num_samples;
+ }
+ if (ctx->num_samples != num_samples)
+ sr_warn("Expecting %u samples, got %u",
+ ctx->num_samples, num_samples);
+
+ for (j = ch = 0; ch < ctx->num_logic_channels; j++) {
+ if (ctx->channels[j].ch->type == SR_CHANNEL_LOGIC) {
+ for (i = 0; i < num_samples; i++) {
+ sample = logic->data + i * logic->unitsize;
+ idx = ctx->channels[j].ch->index;
+ if (ctx->label_do && !ctx->label_names)
+ ctx->channels[j].label = "logic";
+ ctx->logic_samples[i * ctx->num_logic_channels + ch] = sample[idx / 8] & (1 << (idx % 8));
+ }
+ ch++;
+ }
+ }
+}
+
+static void dump_saved_values(struct context *ctx, GString **out)
+{
+ unsigned int i, j, analog_size, num_channels;
+ float *analog_sample, value;
+ uint8_t *logic_sample;
+
+ /* If we haven't seen samples we're expecting, skip them. */
+ if ((ctx->num_analog_channels && !ctx->analog_samples) ||
+ (ctx->num_logic_channels && !ctx->logic_samples)) {
+ sr_warn("Discarding partial packet");