]> sigrok.org Git - libsigrok.git/commitdiff
demo: Properly handle low samplerates
authorSoeren Apel <redacted>
Wed, 11 Oct 2017 16:14:56 +0000 (18:14 +0200)
committerUwe Hermann <redacted>
Thu, 2 Nov 2017 13:28:16 +0000 (14:28 +0100)
A "low samplerate" in this case means anything where
samples_todo is less than SAMPLES_PER_FRAME. This case
wasn't handled properly before, resulting in wrong
amounts of data being sent out.

src/hardware/demo/api.c
src/hardware/demo/protocol.c
src/hardware/demo/protocol.h

index f23cb7004f2a5115165bd5f02d5e28fd48c08b29..c5259b286144621d6f763ec611b7045df7ab49f2 100644 (file)
@@ -400,6 +400,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
 
        devc = sdi->priv;
        devc->sent_samples = 0;
+       devc->sent_frame_samples = 0;
 
        /*
         * Determine the numbers of logic and analog channels that are
index 37417f734f21e2164a43c9296185a2c4a4879b54..46808fd6cf5622b4cd2ad333906ab9159059ac3d 100644 (file)
@@ -460,9 +460,6 @@ SR_PRIV int demo_prepare_data(int fd, int revents, void *cb_data)
        samples_todo = (todo_us * devc->cur_samplerate + G_USEC_PER_SEC - 1)
                        / G_USEC_PER_SEC;
 
-       if (SAMPLES_PER_FRAME > 0)
-               samples_todo = SAMPLES_PER_FRAME;
-
        if (devc->limit_samples > 0) {
                if (devc->limit_samples < devc->sent_samples)
                        samples_todo = 0;
@@ -470,6 +467,16 @@ SR_PRIV int demo_prepare_data(int fd, int revents, void *cb_data)
                        samples_todo = devc->limit_samples - devc->sent_samples;
        }
 
+       if (samples_todo == 0)
+               return G_SOURCE_CONTINUE;
+
+#if (SAMPLES_PER_FRAME > 0) /* Avoid "comparison < 0 always false" warning. */
+       /* Never send more samples than a frame can fit... */
+       samples_todo = MIN(samples_todo, SAMPLES_PER_FRAME);
+       /* ...or than we need to finish the current frame. */
+       samples_todo = MIN(samples_todo, SAMPLES_PER_FRAME - devc->sent_frame_samples);
+#endif
+
        /* Calculate the actual time covered by this run back from the sample
         * count, rounded towards zero. This avoids getting stuck on a too-low
         * time delta with no samples being sent due to round-off.
@@ -520,8 +527,16 @@ SR_PRIV int demo_prepare_data(int fd, int revents, void *cb_data)
                return G_SOURCE_REMOVE;
        }
        devc->sent_samples += samples_todo;
+       devc->sent_frame_samples += samples_todo;
        devc->spent_us += todo_us;
 
+#if (SAMPLES_PER_FRAME > 0) /* Avoid "comparison >= 0 always true" warning. */
+       if (devc->sent_frame_samples >= SAMPLES_PER_FRAME) {
+               std_session_send_frame_end(sdi);
+               devc->sent_frame_samples = 0;
+       }
+#endif
+
        if ((devc->limit_samples > 0 && devc->sent_samples >= devc->limit_samples)
                        || (limit_us > 0 && devc->spent_us >= limit_us)) {
 
@@ -540,10 +555,10 @@ SR_PRIV int demo_prepare_data(int fd, int revents, void *cb_data)
                sr_dbg("Requested number of samples reached.");
                sr_dev_acquisition_stop(sdi);
        } else {
-               if (SAMPLES_PER_FRAME > 0) {
-                       std_session_send_frame_end(sdi);
+#if (SAMPLES_PER_FRAME > 0)
+               if (devc->sent_frame_samples == 0)
                        std_session_send_frame_begin(sdi);
-               }
+#endif
        }
 
        return G_SOURCE_CONTINUE;
index 53ad043b17845952d35a8bd72fb8b27bf1948d16..f1c667117a29264e0be4ea1221c675a83a0fa3ae 100644 (file)
@@ -41,6 +41,7 @@ struct dev_context {
        uint64_t limit_samples;
        uint64_t limit_msec;
        uint64_t sent_samples;
+       uint64_t sent_frame_samples; /* Number of samples that were sent for current frame. */
        int64_t start_us;
        int64_t spent_us;
        uint64_t step;