aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2022-05-22 20:45:34 -0800
committerClyne Sullivan <clyne@bitgloo.com>2022-05-22 20:45:34 -0800
commit93c41469829e339df9732f290dd0941bc91acefb (patch)
treeb1fb1d2859dacb2a3e9e91ccd22cf22715b0fc29
parent074c596605a9b64ad99f39d6edc37d31bbfb6536 (diff)
parent77ff957e5eb03fb459ea1d56f7bd3b3c3f164699 (diff)
Merge branch 'windows' into devel
-rw-r--r--.gitignore1
-rw-r--r--Makefile32
-rw-r--r--source/device.cpp40
-rw-r--r--source/device_formula.cpp24
-rw-r--r--source/file.cpp2
-rw-r--r--source/gui.cpp2
-rw-r--r--source/gui_device.cpp14
-rw-r--r--source/main.cpp2
-rw-r--r--source/stmdsp/stmdsp.cpp4
9 files changed, 85 insertions, 36 deletions
diff --git a/.gitignore b/.gitignore
index d7ed0eb..9c562a6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,4 +4,5 @@ stmdspgui
stmdspgui.exe
perf.data*
*.o
+*.dll
.*
diff --git a/Makefile b/Makefile
index 81e580d..dc62d10 100644
--- a/Makefile
+++ b/Makefile
@@ -1,26 +1,36 @@
+CXX = g++
+
CXXFILES := \
source/serial/src/serial.cc \
- source/serial/src/impl/unix.cc \
- source/serial/src/impl/list_ports/list_ports_linux.cc \
$(wildcard source/imgui/backends/*.cpp) \
$(wildcard source/imgui/*.cpp) \
$(wildcard source/stmdsp/*.cpp) \
$(wildcard source/*.cpp)
-OFILES := $(patsubst %.cc, %.o, $(patsubst %.cpp, %.o, $(CXXFILES)))
+CXXFLAGS := -std=c++20 -O2 \
+ -Isource -Isource/imgui -Isource/stmdsp -Isource/serial/include \
+ -Wall -Wextra -pedantic #-DSTMDSP_DISABLE_FORMULAS
+
+ifeq ($(OS),Windows_NT)
+CXXFILES += source/serial/src/impl/win.cc \
+ source/serial/src/impl/list_ports/list_ports_win.cc
+CXXFLAGS += -DSTMDSP_WIN32 -Wa,-mbig-obj
+LDFLAGS = -mwindows -lSDL2 -lopengl32 -lsetupapi -lole32
+OUTPUT := stmdspgui.exe
+else
+CXXFILES += source/serial/src/impl/unix.cc \
+ source/serial/src/impl/list_ports/list_ports_unix.cc
+LDFLAGS = -lSDL2 -lGL -lpthread
OUTPUT := stmdspgui
+endif
-#CXXFLAGS := -std=c++20 -O2 \
-# -Isource -Isource/imgui -Isource/stmdsp -Isource/serial/include
-CXXFLAGS := -std=c++20 -ggdb -O0 -g3 \
- -Isource -Isource/imgui -Isource/stmdsp -Isource/serial/include \
- -Wall -Wextra -pedantic
+OFILES := $(patsubst %.cc, %.o, $(patsubst %.cpp, %.o, $(CXXFILES)))
all: $(OUTPUT)
$(OUTPUT): $(OFILES)
@echo " LD " $(OUTPUT)
- @g++ $(OFILES) -o $(OUTPUT) -lSDL2 -lGL -lpthread
+ @$(CXX) $(OFILES) -o $(OUTPUT) $(LDFLAGS)
clean:
@echo " CLEAN"
@@ -28,9 +38,9 @@ clean:
%.o: %.cpp
@echo " CXX " $<
- @g++ $(CXXFLAGS) -c $< -o $@
+ @$(CXX) $(CXXFLAGS) -c $< -o $@
%.o: %.cc
@echo " CXX " $<
- @g++ $(CXXFLAGS) -c $< -o $@
+ @$(CXX) $(CXXFLAGS) -c $< -o $@
diff --git a/source/device.cpp b/source/device.cpp
index 60b1bc9..9c50a0d 100644
--- a/source/device.cpp
+++ b/source/device.cpp
@@ -103,8 +103,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));
@@ -136,8 +138,8 @@ static void drawSamplesTask(std::shared_ptr<stmdsp::device> device)
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));
}
std::this_thread::sleep_until(next);
@@ -431,15 +433,27 @@ void deviceGenLoadFormula(const std::string& formula)
std::size_t pullFromQueue(
std::deque<stmdsp::dacsample_t>& queue,
- CircularBuffer<std::vector, stmdsp::dacsample_t>& circ,
- double timeframe)
+ CircularBuffer<std::vector, stmdsp::dacsample_t>& circ)
{
+ // 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());
@@ -449,17 +463,19 @@ 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)
+ CircularBuffer<std::vector, stmdsp::dacsample_t>& circ)
{
- return pullFromQueue(drawSamplesQueue, circ, timeframe);
+ return pullFromQueue(drawSamplesQueue, circ);
}
std::size_t pullFromInputDrawQueue(
- CircularBuffer<std::vector, stmdsp::dacsample_t>& circ,
- double timeframe)
+ CircularBuffer<std::vector, stmdsp::dacsample_t>& circ)
{
- return pullFromQueue(drawSamplesInputQueue, circ, timeframe);
+ return pullFromQueue(drawSamplesInputQueue, circ);
}
diff --git a/source/device_formula.cpp b/source/device_formula.cpp
index a70f465..e21d374 100644
--- a/source/device_formula.cpp
+++ b/source/device_formula.cpp
@@ -11,13 +11,26 @@
*/
#include "stmdsp.hpp"
-#include "exprtk.hpp"
#include <algorithm>
#include <random>
#include <string_view>
#include <vector>
+#ifndef STMDSP_DISABLE_FORMULAS
+
+#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"
+
static std::random_device randomDevice;
std::vector<stmdsp::dacsample_t> deviceGenLoadFormulaEval(const std::string& formulaString)
@@ -62,3 +75,12 @@ std::vector<stmdsp::dacsample_t> deviceGenLoadFormulaEval(const std::string& for
return samples;
}
+#else // no formula support
+
+std::vector<stmdsp::dacsample_t> deviceGenLoadFormulaEval(const std::string&)
+{
+ return {};
+}
+
+#endif // STMDSP_DISABLE_FORMULAS
+
diff --git a/source/file.cpp b/source/file.cpp
index fe5dafb..b4332f4 100644
--- a/source/file.cpp
+++ b/source/file.cpp
@@ -104,7 +104,7 @@ void fileRenderMenu()
if (ImGui::BeginMenu("Open Example")) {
for (const auto& file : fileExampleList) {
- if (ImGui::MenuItem(file.filename().c_str())) {
+ if (ImGui::MenuItem(file.filename().string().c_str())) {
fileCurrentPath = file.string();
openCurrentFile();
diff --git a/source/gui.cpp b/source/gui.cpp
index 0e67446..43c95df 100644
--- a/source/gui.cpp
+++ b/source/gui.cpp
@@ -40,7 +40,7 @@ bool guiInitialize()
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
window = SDL_CreateWindow("stmdsp gui",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
- 550, 700,
+ 640, 700,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE /*| SDL_WINDOW_ALLOW_HIGHDPI*/);
if (window == nullptr) {
diff --git a/source/gui_device.cpp b/source/gui_device.cpp
index f846414..689ef54 100644
--- a/source/gui_device.cpp
+++ b/source/gui_device.cpp
@@ -28,11 +28,9 @@ void deviceStart(bool logResults, bool drawSamples);
void deviceStartMeasurement();
void deviceUpdateDrawBufferSize(double timeframe);
std::size_t pullFromDrawQueue(
- CircularBuffer<std::vector, stmdsp::dacsample_t>& circ,
- double timeframe);
+ CircularBuffer<std::vector, stmdsp::dacsample_t>& circ);
std::size_t pullFromInputDrawQueue(
- CircularBuffer<std::vector, stmdsp::dacsample_t>& circ,
- double timeframe);
+ CircularBuffer<std::vector, stmdsp::dacsample_t>& circ);
static std::string sampleRatePreview = "?";
static bool measureCodeTime = false;
@@ -319,19 +317,19 @@ void deviceRenderDraw()
yMinMax = std::min(4095u, (yMinMax << 1) | 1);
}
- auto newSize = pullFromDrawQueue(bufferCirc, drawSamplesTimeframe);
+ auto newSize = pullFromDrawQueue(bufferCirc);
if (newSize > 0) {
buffer.resize(newSize);
bufferCirc = CircularBuffer(buffer);
- pullFromDrawQueue(bufferCirc, drawSamplesTimeframe);
+ pullFromDrawQueue(bufferCirc);
}
if (drawSamplesInput) {
- auto newSize = pullFromInputDrawQueue(bufferInputCirc, drawSamplesTimeframe);
+ auto newSize = pullFromInputDrawQueue(bufferInputCirc);
if (newSize > 0) {
bufferInput.resize(newSize);
bufferInputCirc = CircularBuffer(bufferInput);
- pullFromInputDrawQueue(bufferInputCirc, drawSamplesTimeframe);
+ pullFromInputDrawQueue(bufferInputCirc);
}
}
diff --git a/source/main.cpp b/source/main.cpp
index f913cf1..e0d893e 100644
--- a/source/main.cpp
+++ b/source/main.cpp
@@ -47,7 +47,7 @@ static ImFont *fontMono = nullptr;
template<bool first = false>
static void renderWindow();
-int main(int, char **)
+int main(int argc, char *argv[])
{
if (!guiInitialize())
return -1;
diff --git a/source/stmdsp/stmdsp.cpp b/source/stmdsp/stmdsp.cpp
index d7e977b..294e98f 100644
--- a/source/stmdsp/stmdsp.cpp
+++ b/source/stmdsp/stmdsp.cpp
@@ -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();