Merge branch 'windows' into devel
This commit is contained in:
commit
93c4146982
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,4 +4,5 @@ stmdspgui
|
||||
stmdspgui.exe
|
||||
perf.data*
|
||||
*.o
|
||||
*.dll
|
||||
.*
|
||||
|
34
Makefile
34
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)))
|
||||
OUTPUT := stmdspgui
|
||||
|
||||
#CXXFLAGS := -std=c++20 -O2 \
|
||||
# -Isource -Isource/imgui -Isource/stmdsp -Isource/serial/include
|
||||
CXXFLAGS := -std=c++20 -ggdb -O0 -g3 \
|
||||
CXXFLAGS := -std=c++20 -O2 \
|
||||
-Isource -Isource/imgui -Isource/stmdsp -Isource/serial/include \
|
||||
-Wall -Wextra -pedantic
|
||||
-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
|
||||
|
||||
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 $@
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user