]> code.bitgloo.com Git - clyne/stmdspgui.git/commitdiff
fix serial timeout to prevent incomplete IO
authorClyne Sullivan <clyne@bitgloo.com>
Tue, 17 May 2022 19:42:14 +0000 (11:42 -0800)
committerClyne Sullivan <clyne@bitgloo.com>
Tue, 17 May 2022 19:42:14 +0000 (11:42 -0800)
.gitignore
Makefile
source/device.cpp
source/device_formula.cpp
source/stmdsp/stmdsp.cpp

index d7ed0eb94bec6c79ec5f8375efdee97d7b464e7b..9c562a6e88b1526c822f9796dcd0f8b2213bfe58 100644 (file)
@@ -4,4 +4,5 @@ stmdspgui
 stmdspgui.exe
 perf.data*
 *.o
+*.dll
 .*
index fdf87d64bb73dbda79d6c02c02c2157564f1eae2..1f4b1e1e406a73cad243496db225cecf48b08395 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,9 @@
 #linux: CXXFILES += source/serial/src/impl/unix.cc source/serial/src/impl/list_ports/list_ports_unix.cc
 #linux: LDFLAGS = -lSDL2 -lGL -lpthread
 
-CROSS = x86_64-w64-mingw32-
-CXX = $(CROSS)g++
+#CROSS = x86_64-w64-mingw32-
+#CXX = $(CROSS)g++
+CXX = g++
 
 CXXFILES := \
     source/serial/src/serial.cc \
index 11e181e8a3671b43597788337713685731938034..edd950c1b7caf3cab8286bb2980808465b8102cb 100644 (file)
@@ -96,8 +96,10 @@ static void drawSamplesTask(std::shared_ptr<stmdsp::device> device)
     if (!device)
         return;
 
-    const auto bufferTime = getBufferPeriod(device);
+    // This is the amount of time to wait between device reads.
+    const auto bufferTime = getBufferPeriod(device, 1);
 
+    // Adds the given chunk of samples to the given queue.
     const auto addToQueue = [](auto& queue, const auto& chunk) {
         std::scoped_lock lock (mutexDrawSamples);
         std::copy(chunk.cbegin(), chunk.cend(), std::back_inserter(queue));
@@ -114,13 +116,14 @@ static void drawSamplesTask(std::shared_ptr<stmdsp::device> device)
             lockDevice.unlock();
 
             addToQueue(drawSamplesQueue, chunk);
+
             if (logSamplesFile.is_open()) {
                 for (const auto& s : chunk)
                     logSamplesFile << s << '\n';
             }
         } else {
-            // Device must be busy, cooldown.
-            std::this_thread::sleep_for(std::chrono::milliseconds(500));
+            // Device must be busy, back off for a bit.
+            std::this_thread::sleep_for(std::chrono::milliseconds(50));
         }
 
         if (drawSamplesInput) {
@@ -417,12 +420,25 @@ std::size_t pullFromQueue(
     CircularBuffer<std::vector, stmdsp::dacsample_t>& circ,
     double timeframe)
 {
+    // We know how big the circular buffer should be to hold enough samples to
+    // fill the current draw samples view.
+    // If the given buffer does not match this size, notify the caller.
+    // TODO this could be done better... drawSamplesBufferSize should be a GUI-
+    // only thing.
     if (circ.size() != drawSamplesBufferSize)
         return drawSamplesBufferSize;
 
     std::scoped_lock lock (mutexDrawSamples);
 
-    const auto desiredCount = drawSamplesBufferSize / (60. * timeframe) * 1.025;
+    // The render code will draw all of the new samples we add to the buffer.
+    // So, we must provide a certain amount of samples at a time to make the
+    // render appear smooth.
+    // The 1.025 factor keeps us on top of the stream; don't want to fall
+    // behind.
+    const double FPS = ImGui::GetIO().Framerate;
+    const auto desiredCount = m_device->get_sample_rate() / FPS;
+
+    // Transfer from the queue to the render buffer.
     auto count = std::min(queue.size(), static_cast<std::size_t>(desiredCount));
     while (count--) {
         circ.put(queue.front());
@@ -432,6 +448,10 @@ std::size_t pullFromQueue(
     return 0;
 }
 
+/**
+ * Pulls a render frame's worth of samples from the draw samples queue, adding
+ * the samples to the given buffer.
+ */
 std::size_t pullFromDrawQueue(
     CircularBuffer<std::vector, stmdsp::dacsample_t>& circ,
     double timeframe)
index a70f4652ca60f3b3834ecd72d7ae0450be548c53..9a3372ff5bbf7943c26265e51cb89357f97b3cfb 100644 (file)
  * If not, see <https://www.gnu.org/licenses/>.
  */
 
-#include "stmdsp.hpp"
+#define exprtk_disable_comments
+#define exprtk_disable_break_continue
+#define exprtk_disable_sc_andor
+#define exprtk_disable_return_statement
+#define exprtk_disable_enhanced_features
+//#define exprtk_disable_string_capabilities
+#define exprtk_disable_superscalar_unroll
+#define exprtk_disable_rtl_io_file
+#define exprtk_disable_rtl_vecops
+//#define exprtk_disable_caseinsensitivity
 #include "exprtk.hpp"
 
+#include "stmdsp.hpp"
+
 #include <algorithm>
 #include <random>
 #include <string_view>
index 22523647aacc8736ba7a0fd740423d00b5ab3a8a..c83525793e5b41862249b9914a30ce9616c7e329 100644 (file)
@@ -45,7 +45,9 @@ namespace stmdsp
     device::device(const std::string& file)
     {
         // This could throw!
-        m_serial.reset(new serial::Serial(file, 8'000'000, serial::Timeout::simpleTimeout(50)));
+       // Note: Windows needs a not-simple, positive timeout like this to
+       // ensure that reads block.
+        m_serial.reset(new serial::Serial(file, 921'600 /*8'000'000*/, serial::Timeout(1000, 1000, 1, 1000, 1)));
 
         // Test the ID command.
         m_serial->flush();