Guaranteed random grid output

This commit is contained in:
Dejvino 2026-02-28 20:13:32 +01:00
parent 0e7b5925d2
commit 9380e3e79e

View File

@ -739,6 +739,8 @@ void randomizeGrid() {
c.type = (SynthEngine::GridCell::Type)(rand() % numTypes); c.type = (SynthEngine::GridCell::Type)(rand() % numTypes);
c.rotation = rand() % 4; c.rotation = rand() % 4;
c.param = (float)rand() / (float)RAND_MAX; c.param = (float)rand() / (float)RAND_MAX;
c.value = 0.0f;
c.phase = 0.0f;
} }
} }
@ -819,30 +821,80 @@ void randomizeGrid() {
} }
} }
} }
validGrid = hasSoundSource && hasGate;
}
// 4. Prune unreachable elements if a valid grid was found if (hasSoundSource && hasGate) {
if (validGrid) { // 4. Prune unreachable elements
for (int x = 0; x < SynthEngine::GRID_W; ++x) { for (int x = 0; x < SynthEngine::GRID_W; ++x) {
for (int y = 0; y < SynthEngine::GRID_H; ++y) { for (int y = 0; y < SynthEngine::GRID_H; ++y) {
if (!visited[x][y]) { if (!visited[x][y]) {
engine.grid[x][y].type = SynthEngine::GridCell::EMPTY; engine.grid[x][y].type = SynthEngine::GridCell::EMPTY;
engine.grid[x][y].param = 0.5f; engine.grid[x][y].param = 0.5f;
engine.grid[x][y].rotation = 0; engine.grid[x][y].rotation = 0;
}
}
}
// 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();
engine.setFrequency(440.0f);
bool soundDetected = false;
for(int i=0; i<1000; ++i) {
float val = engine.processGridStep();
if (fabsf(val) > 0.001f) {
soundDetected = true;
break;
}
}
engine.setGate(false);
engine.setFrequency(oldFreq);
if (soundDetected) {
validGrid = true;
// Reset values to avoid initial pop
for (int x = 0; x < SynthEngine::GRID_W; ++x) {
for (int y = 0; y < SynthEngine::GRID_H; ++y) {
engine.grid[x][y].value = 0.0f;
}
}
} 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;
}
}
} }
} }
} }
} }
// 5. Allocate buffers for DELAYs and REVERBs that are still present // If failed after all attempts, ensure grid is clean
for (int x = 0; x < SynthEngine::GRID_W; ++x) { if (!validGrid) {
for (int y = 0; y < SynthEngine::GRID_H; ++y) { for (int x = 0; x < SynthEngine::GRID_W; ++x) {
SynthEngine::GridCell& c = engine.grid[x][y]; for (int y = 0; y < SynthEngine::GRID_H; ++y) {
if (c.type == SynthEngine::GridCell::DELAY || c.type == SynthEngine::GridCell::REVERB || c.type == SynthEngine::GridCell::PITCH_SHIFTER) { SynthEngine::GridCell& c = engine.grid[x][y];
c.buffer_size = 2 * SAMPLE_RATE; if (c.type != SynthEngine::GridCell::SINK) {
c.buffer = new float[c.buffer_size](); c.type = SynthEngine::GridCell::EMPTY;
c.write_idx = 0; c.param = 0.5f;
c.rotation = 0;
}
} }
} }
} }