Optimizations 1
This commit is contained in:
+113
-50
@@ -12,6 +12,11 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <sys/select.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
// --- Configuration ---
|
||||
const uint32_t SAMPLE_RATE = 44100;
|
||||
const uint32_t CHANNELS = 1; // Mono
|
||||
@@ -73,6 +78,61 @@ void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uin
|
||||
vis_write_index.store(idx, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
void checkSerialInput(FILE* serialPort) {
|
||||
if (!serialPort) return;
|
||||
|
||||
#if !defined(_WIN32)
|
||||
int fd = fileno(serialPort);
|
||||
fd_set readfds;
|
||||
struct timeval tv;
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(fd, &readfds);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
if (select(fd + 1, &readfds, NULL, NULL, &tv) <= 0) return;
|
||||
|
||||
uint8_t buf[256];
|
||||
ssize_t n = read(fd, buf, sizeof(buf));
|
||||
if (n <= 0) return;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
|
||||
printf("Grid import maybe?\n");
|
||||
|
||||
static int state = 0;
|
||||
static int headerIdx = 0;
|
||||
static const char* header = "NSGRID";
|
||||
static uint8_t buffer[SynthEngine::SERIALIZED_GRID_SIZE];
|
||||
static int bufferIdx = 0;
|
||||
|
||||
for (ssize_t i = 0; i < n; ++i) {
|
||||
uint8_t b = buf[i];
|
||||
if (state == 0) {
|
||||
if (b == header[headerIdx]) {
|
||||
headerIdx++;
|
||||
if (headerIdx == 6) {
|
||||
state = 1;
|
||||
bufferIdx = 0;
|
||||
headerIdx = 0;
|
||||
printf("Grid import starting.\n");
|
||||
}
|
||||
} else {
|
||||
headerIdx = 0;
|
||||
if (b == 'N') headerIdx = 1;
|
||||
}
|
||||
} else if (state == 1) {
|
||||
buffer[bufferIdx++] = b;
|
||||
if (bufferIdx == SynthEngine::SERIALIZED_GRID_SIZE) {
|
||||
engine.importGrid(buffer);
|
||||
printf("Grid imported from serial.\n");
|
||||
state = 0;
|
||||
bufferIdx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- UI Drawing Helpers ---
|
||||
|
||||
void DrawCircle(SDL_Renderer * renderer, int32_t centreX, int32_t centreY, int32_t radius) {
|
||||
@@ -706,23 +766,24 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
}
|
||||
|
||||
void randomizeGrid() {
|
||||
printf("Randomizing grid...\n");
|
||||
Uint32 startTime = SDL_GetTicks();
|
||||
SynthLockGuard<SynthMutex> lock(engine.gridMutex);
|
||||
|
||||
// Number of types to choose from (excluding SINK)
|
||||
const int numTypes = (int)SynthEngine::GridCell::SINK;
|
||||
|
||||
// 1. Clear existing buffers first
|
||||
// 1. Clear existing buffers first (resets the pool)
|
||||
// engine.clearGrid(); // Avoid deadlock by clearing manually
|
||||
for (int x = 0; x < SynthEngine::GRID_W; ++x) {
|
||||
for (int y = 0; y < SynthEngine::GRID_H; ++y) {
|
||||
SynthEngine::GridCell& c = engine.grid[x][y];
|
||||
if (c.buffer) {
|
||||
delete[] c.buffer;
|
||||
c.buffer = nullptr;
|
||||
c.buffer_size = 0;
|
||||
}
|
||||
if (c.type != SynthEngine::GridCell::SINK) {
|
||||
c.type = SynthEngine::GridCell::EMPTY;
|
||||
}
|
||||
if (c.type == SynthEngine::GridCell::SINK) continue;
|
||||
c.type = SynthEngine::GridCell::EMPTY;
|
||||
c.param = 0.5f;
|
||||
c.rotation = 0;
|
||||
c.value = 0.0f;
|
||||
c.phase = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -731,6 +792,10 @@ void randomizeGrid() {
|
||||
bool visited[SynthEngine::GRID_W][SynthEngine::GRID_H];
|
||||
|
||||
while (!validGrid && attempts < 1000) {
|
||||
if (SDL_GetTicks() - startTime > 200) { // Safeguard: Timeout after 200ms
|
||||
printf("Randomization timed out.\n");
|
||||
break;
|
||||
}
|
||||
attempts++;
|
||||
|
||||
// 2. Randomize (without allocation)
|
||||
@@ -837,18 +902,6 @@ void randomizeGrid() {
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Allocate buffers for DELAYs and REVERBs
|
||||
for (int x = 0; x < SynthEngine::GRID_W; ++x) {
|
||||
for (int y = 0; y < SynthEngine::GRID_H; ++y) {
|
||||
SynthEngine::GridCell& c = engine.grid[x][y];
|
||||
if (c.type == SynthEngine::GridCell::DELAY || c.type == SynthEngine::GridCell::REVERB || c.type == SynthEngine::GridCell::PITCH_SHIFTER) {
|
||||
c.buffer_size = 2 * SAMPLE_RATE;
|
||||
c.buffer = new float[c.buffer_size]();
|
||||
c.write_idx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 6. Run Simulation
|
||||
engine.setGate(true);
|
||||
float oldFreq = engine.getFrequency();
|
||||
@@ -874,16 +927,6 @@ void randomizeGrid() {
|
||||
}
|
||||
} else {
|
||||
// Failed simulation, cleanup buffers
|
||||
for (int x = 0; x < SynthEngine::GRID_W; ++x) {
|
||||
for (int y = 0; y < SynthEngine::GRID_H; ++y) {
|
||||
SynthEngine::GridCell& c = engine.grid[x][y];
|
||||
if (c.buffer) {
|
||||
delete[] c.buffer;
|
||||
c.buffer = nullptr;
|
||||
c.buffer_size = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -902,7 +945,7 @@ void randomizeGrid() {
|
||||
}
|
||||
}
|
||||
|
||||
printf("Randomized in %d attempts. Valid: %s\n", attempts, validGrid ? "YES" : "NO");
|
||||
printf("Randomized in %d attempts (%d ms). Valid: %s\n", attempts, SDL_GetTicks() - startTime, validGrid ? "YES" : "NO");
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
@@ -943,7 +986,7 @@ int main(int argc, char* argv[]) {
|
||||
ma_device_start(&device);
|
||||
|
||||
if (argc > 1) {
|
||||
serialPort = fopen(argv[1], "wb");
|
||||
serialPort = fopen(argv[1], "r+b");
|
||||
if (serialPort) printf("Opened serial port: %s\n", argv[1]);
|
||||
else printf("Failed to open serial port: %s\n", argv[1]);
|
||||
}
|
||||
@@ -992,19 +1035,18 @@ int main(int argc, char* argv[]) {
|
||||
SynthEngine::GridCell::BITCRUSHER,
|
||||
SynthEngine::GridCell::DISTORTION,
|
||||
SynthEngine::GridCell::RECTIFIER,
|
||||
SynthEngine::GridCell::PITCH_SHIFTER,
|
||||
SynthEngine::GridCell::GLITCH,
|
||||
SynthEngine::GridCell::OPERATOR,
|
||||
SynthEngine::GridCell::DELAY,
|
||||
SynthEngine::GridCell::REVERB
|
||||
SynthEngine::GridCell::OPERATOR
|
||||
};
|
||||
const int numCellTypes = sizeof(cellTypes) / sizeof(cellTypes[0]);
|
||||
|
||||
bool quit = false;
|
||||
SDL_Event e;
|
||||
bool exportButtonPressed = false;
|
||||
bool importButtonPressed = false;
|
||||
|
||||
while (!quit) {
|
||||
checkSerialInput(serialPort);
|
||||
// --- Automated Melody Logic ---
|
||||
if (auto_melody_enabled && SDL_GetTicks() > auto_melody_next_event_time) {
|
||||
auto_melody_next_event_time = SDL_GetTicks() + 200 + (rand() % 150); // Note duration
|
||||
@@ -1060,19 +1102,7 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
if (newType != oldType) {
|
||||
// If old type was DELAY, free its buffer
|
||||
if ((oldType == SynthEngine::GridCell::DELAY || oldType == SynthEngine::GridCell::REVERB || oldType == SynthEngine::GridCell::PITCH_SHIFTER) && c.buffer) {
|
||||
delete[] c.buffer;
|
||||
c.buffer = nullptr;
|
||||
c.buffer_size = 0;
|
||||
}
|
||||
c.type = newType;
|
||||
// If new type is DELAY, allocate its buffer
|
||||
if (newType == SynthEngine::GridCell::DELAY || newType == SynthEngine::GridCell::REVERB || newType == SynthEngine::GridCell::PITCH_SHIFTER) {
|
||||
c.buffer_size = 2 * SAMPLE_RATE; // Max 2 seconds delay
|
||||
c.buffer = new float[c.buffer_size](); // Allocate and zero-initialize
|
||||
c.write_idx = 0; // Reset write index
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1101,6 +1131,12 @@ int main(int argc, char* argv[]) {
|
||||
my >= exportButtonRect.y && my <= exportButtonRect.y + exportButtonRect.h) {
|
||||
exportButtonPressed = true;
|
||||
}
|
||||
|
||||
SDL_Rect importButtonRect = {410, 435, 100, 30};
|
||||
if (synthX >= importButtonRect.x && synthX <= importButtonRect.x + importButtonRect.w &&
|
||||
my >= importButtonRect.y && my <= importButtonRect.y + importButtonRect.h) {
|
||||
importButtonPressed = true;
|
||||
}
|
||||
}
|
||||
} else if (e.type == SDL_MOUSEWHEEL) {
|
||||
SDL_Keymod modState = SDL_GetModState();
|
||||
@@ -1192,13 +1228,39 @@ int main(int argc, char* argv[]) {
|
||||
fwrite("NSGRID", 1, 6, serialPort);
|
||||
fwrite(buf, 1, sizeof(buf), serialPort);
|
||||
fflush(serialPort);
|
||||
printf("Grid exported to serial.\n");
|
||||
printf("Grid exported to serial. Waiting for response...\n");
|
||||
|
||||
char response[256];
|
||||
if (fgets(response, sizeof(response), serialPort)) {
|
||||
printf("Device response: %s", response);
|
||||
} else {
|
||||
printf("No response from device.\n");
|
||||
}
|
||||
} else {
|
||||
printf("Serial port not open. Pass device path as argument (e.g. ./NoiceSynth /dev/ttyACM0)\n");
|
||||
}
|
||||
}
|
||||
exportButtonPressed = false;
|
||||
}
|
||||
if (importButtonPressed) {
|
||||
int mx = e.button.x;
|
||||
int my = e.button.y;
|
||||
int synthX = mx - GRID_PANEL_WIDTH;
|
||||
SDL_Rect importButtonRect = {410, 435, 100, 30};
|
||||
if (mx >= GRID_PANEL_WIDTH &&
|
||||
synthX >= importButtonRect.x && synthX <= importButtonRect.x + importButtonRect.w &&
|
||||
my >= importButtonRect.y && my <= importButtonRect.y + importButtonRect.h) {
|
||||
|
||||
if (serialPort) {
|
||||
fwrite("NSLOAD", 1, 6, serialPort);
|
||||
fflush(serialPort);
|
||||
printf("Requested grid import from device...\n");
|
||||
} else {
|
||||
printf("Serial port not open.\n");
|
||||
}
|
||||
}
|
||||
importButtonPressed = false;
|
||||
}
|
||||
} else if (e.type == SDL_KEYUP) {
|
||||
if (!auto_melody_enabled && e.key.keysym.scancode == current_key_scancode) {
|
||||
engine.setGate(false);
|
||||
@@ -1278,6 +1340,7 @@ int main(int argc, char* argv[]) {
|
||||
drawToggle(renderer, 580, 450, 30, auto_melody_enabled);
|
||||
|
||||
drawButton(renderer, 300, 435, 100, 30, "EXPORT", exportButtonPressed);
|
||||
drawButton(renderer, 410, 435, 100, 30, "IMPORT", importButtonPressed);
|
||||
|
||||
// --- Draw Grid Panel (Left) ---
|
||||
SDL_Rect gridViewport = {0, 0, GRID_PANEL_WIDTH, WINDOW_HEIGHT};
|
||||
|
||||
Reference in New Issue
Block a user