+/*
+ * Analog devices can have samples of different types. Since each
+ * packet has only one meaning, it is restricted to having at most one
+ * type of data. So they can send multiple packets for a single sample.
+ * To further complicate things, they can send multiple samples in a
+ * single packet.
+ *
+ * So we need to pull any channels of interest out of a packet and save
+ * them until we have complete samples to output. Some devices make this
+ * simple by sending DF_FRAME_BEGIN/DF_FRAME_END packets, the latter of which
+ * signals the end of a set of samples, so we can dump things there.
+ *
+ * At least one driver (the demo driver) sends packets that contain parts of
+ * multiple samples without wrapping them in DF_FRAME. Possibly this driver
+ * is buggy, but it's also the standard for testing, so it has to be supported
+ * as is.
+ *
+ * Many assumptions about the "shape" of the data here:
+ *
+ * All of the data for a channel is assumed to be in one frame;
+ * otherwise the data in the second packet will overwrite the data in
+ * the first packet.
+ */
+static void process_analog(struct context *ctx,
+ const struct sr_datafeed_analog *analog)
+{
+ 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)