]> sigrok.org Git - libsigrok.git/blobdiff - src/hardware/demo/protocol.c
demo: Properly handle low samplerates
[libsigrok.git] / src / hardware / demo / protocol.c
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;