Gate control and ADSR as elements
This commit is contained in:
@@ -27,9 +27,6 @@ std::atomic<size_t> vis_write_index{0};
|
||||
// --- Control State ---
|
||||
int current_octave = 4; // C4 is middle C
|
||||
float knob_vol_val = 0.5f;
|
||||
// ADSR (A, D, R in seconds, S in 0-1)
|
||||
float adsr_vals[4] = {0.05f, 0.2f, 0.6f, 0.5f};
|
||||
float filter_vals[2] = {1.0f, 0.0f}; // LP (1.0=Open), HP (0.0=Open)
|
||||
|
||||
// --- MIDI / Keyboard Input State ---
|
||||
std::map<SDL_Scancode, int> key_to_note_map;
|
||||
@@ -357,6 +354,74 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
drawString(renderer, x + 5, y + size - 18, 10, buf);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 0, 255, 255);
|
||||
drawTypeLabel(renderer, x, y, 'L');
|
||||
} else if (cell.type == SynthEngine::GridCell::GATE) {
|
||||
SDL_Rect box = {cx - r, cy - r, r*2, r*2};
|
||||
SDL_RenderDrawRect(renderer, &box);
|
||||
if (cell.value > 0.5f) SDL_RenderFillRect(renderer, &box);
|
||||
drawString(renderer, cx - 8, cy - 5, 12, "GAT");
|
||||
drawTypeLabel(renderer, x, y, '!');
|
||||
} else if (cell.type == SynthEngine::GridCell::GATE_INPUT) {
|
||||
SDL_Rect box = {cx - r, cy - r, r*2, r*2};
|
||||
SDL_RenderDrawRect(renderer, &box);
|
||||
if (cell.value > 0.5f) SDL_RenderFillRect(renderer, &box);
|
||||
drawString(renderer, cx - 8, cy - 5, 12, "G-IN");
|
||||
drawTypeLabel(renderer, x, y, 'K');
|
||||
} else if (cell.type == SynthEngine::GridCell::ADSR_ATTACK) {
|
||||
// Draw Ramp Up
|
||||
SDL_RenderDrawLine(renderer, cx-r, cy+r, cx+r, cy-r);
|
||||
// I/O
|
||||
int inDir = (cell.rotation + 2) % 4;
|
||||
int idx=0, idy=0;
|
||||
if(inDir==0) idy=-r; else if(inDir==1) idx=r; else if(inDir==2) idy=r; else idx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx+idx, cy+idy, cx, cy);
|
||||
int odx=0, ody=0;
|
||||
if(cell.rotation==0) ody=-r; else if(cell.rotation==1) odx=r; else if(cell.rotation==2) ody=r; else odx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+odx, cy+ody);
|
||||
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 255, 255);
|
||||
drawTypeLabel(renderer, x, y, 'A');
|
||||
} else if (cell.type == SynthEngine::GridCell::ADSR_DECAY) {
|
||||
// Draw Ramp Down
|
||||
SDL_RenderDrawLine(renderer, cx-r, cy-r, cx+r, cy+r);
|
||||
// I/O
|
||||
int inDir = (cell.rotation + 2) % 4;
|
||||
int idx=0, idy=0;
|
||||
if(inDir==0) idy=-r; else if(inDir==1) idx=r; else if(inDir==2) idy=r; else idx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx+idx, cy+idy, cx, cy);
|
||||
int odx=0, ody=0;
|
||||
if(cell.rotation==0) ody=-r; else if(cell.rotation==1) odx=r; else if(cell.rotation==2) ody=r; else odx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+odx, cy+ody);
|
||||
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 255, 255);
|
||||
drawTypeLabel(renderer, x, y, 'D');
|
||||
} else if (cell.type == SynthEngine::GridCell::ADSR_SUSTAIN) {
|
||||
// Draw Level
|
||||
SDL_RenderDrawLine(renderer, cx-r, cy, cx+r, cy);
|
||||
// I/O
|
||||
int inDir = (cell.rotation + 2) % 4;
|
||||
int idx=0, idy=0;
|
||||
if(inDir==0) idy=-r; else if(inDir==1) idx=r; else if(inDir==2) idy=r; else idx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx+idx, cy+idy, cx, cy);
|
||||
int odx=0, ody=0;
|
||||
if(cell.rotation==0) ody=-r; else if(cell.rotation==1) odx=r; else if(cell.rotation==2) ody=r; else odx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+odx, cy+ody);
|
||||
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 255, 255);
|
||||
drawTypeLabel(renderer, x, y, 'S');
|
||||
} else if (cell.type == SynthEngine::GridCell::ADSR_RELEASE) {
|
||||
// Draw Ramp Down
|
||||
SDL_RenderDrawLine(renderer, cx-r, cy-r, cx+r, cy+r);
|
||||
// I/O
|
||||
int inDir = (cell.rotation + 2) % 4;
|
||||
int idx=0, idy=0;
|
||||
if(inDir==0) idy=-r; else if(inDir==1) idx=r; else if(inDir==2) idy=r; else idx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx+idx, cy+idy, cx, cy);
|
||||
int odx=0, ody=0;
|
||||
if(cell.rotation==0) ody=-r; else if(cell.rotation==1) odx=r; else if(cell.rotation==2) ody=r; else odx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+odx, cy+ody);
|
||||
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 255, 255);
|
||||
drawTypeLabel(renderer, x, y, 'E');
|
||||
} else if (cell.type == SynthEngine::GridCell::LPF || cell.type == SynthEngine::GridCell::HPF) {
|
||||
// Box
|
||||
SDL_Rect box = {cx - r, cy - r, r*2, r*2};
|
||||
@@ -432,6 +497,32 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
drawString(renderer, x + 5, y + size - 18, 10, buf);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 100, 100);
|
||||
drawTypeLabel(renderer, x, y, 'X');
|
||||
} else if (cell.type == SynthEngine::GridCell::RECTIFIER) {
|
||||
SDL_Rect box = {cx - r, cy - r, r*2, r*2};
|
||||
SDL_RenderDrawRect(renderer, &box);
|
||||
drawString(renderer, cx - 8, cy - 5, 12, "ABS");
|
||||
// I/O
|
||||
int inDir = (cell.rotation + 2) % 4;
|
||||
int idx=0, idy=0;
|
||||
if(inDir==0) idy=-r; else if(inDir==1) idx=r; else if(inDir==2) idy=r; else idx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx+idx, cy+idy, cx, cy);
|
||||
int odx=0, ody=0;
|
||||
if(cell.rotation==0) ody=-r; else if(cell.rotation==1) odx=r; else if(cell.rotation==2) ody=r; else odx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+odx, cy+ody);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 150, 0);
|
||||
drawTypeLabel(renderer, x, y, '|');
|
||||
} else if (cell.type == SynthEngine::GridCell::PITCH_SHIFTER) {
|
||||
drawString(renderer, cx - 8, cy - 5, 12, "PIT");
|
||||
// I/O
|
||||
int inDir = (cell.rotation + 2) % 4;
|
||||
int idx=0, idy=0;
|
||||
if(inDir==0) idy=-r; else if(inDir==1) idx=r; else if(inDir==2) idy=r; else idx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx+idx, cy+idy, cx, cy);
|
||||
int odx=0, ody=0;
|
||||
if(cell.rotation==0) ody=-r; else if(cell.rotation==1) odx=r; else if(cell.rotation==2) ody=r; else odx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+odx, cy+ody);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 100, 255, 100);
|
||||
drawTypeLabel(renderer, x, y, '^');
|
||||
} else if (cell.type == SynthEngine::GridCell::GLITCH) {
|
||||
drawString(renderer, cx - 8, cy - 5, 12, "GLT");
|
||||
// I/O
|
||||
@@ -559,7 +650,7 @@ void clearGrid() {
|
||||
SynthEngine::GridCell& c = engine.grid[x][y];
|
||||
if (c.type == SynthEngine::GridCell::SINK) continue;
|
||||
|
||||
if ((c.type == SynthEngine::GridCell::DELAY || c.type == SynthEngine::GridCell::REVERB) && c.buffer) {
|
||||
if ((c.type == SynthEngine::GridCell::DELAY || c.type == SynthEngine::GridCell::REVERB || c.type == SynthEngine::GridCell::PITCH_SHIFTER) && c.buffer) {
|
||||
delete[] c.buffer;
|
||||
c.buffer = nullptr;
|
||||
c.buffer_size = 0;
|
||||
@@ -583,7 +674,7 @@ void randomizeGrid() {
|
||||
for (int x = 0; x < 5; ++x) {
|
||||
for (int y = 0; y < 8; ++y) {
|
||||
SynthEngine::GridCell& c = engine.grid[x][y];
|
||||
if ((c.type == SynthEngine::GridCell::DELAY || c.type == SynthEngine::GridCell::REVERB) && c.buffer) {
|
||||
if (c.buffer) {
|
||||
delete[] c.buffer;
|
||||
c.buffer = nullptr;
|
||||
c.buffer_size = 0;
|
||||
@@ -703,7 +794,7 @@ void randomizeGrid() {
|
||||
for (int x = 0; x < 5; ++x) {
|
||||
for (int y = 0; y < 8; ++y) {
|
||||
SynthEngine::GridCell& c = engine.grid[x][y];
|
||||
if (c.type == SynthEngine::GridCell::DELAY || c.type == SynthEngine::GridCell::REVERB) {
|
||||
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;
|
||||
@@ -773,10 +864,6 @@ int main(int argc, char* argv[]) {
|
||||
engine.setVolume(knob_vol_val);
|
||||
engine.setGate(false); // Start with silence
|
||||
|
||||
// Init engine with default UI values
|
||||
engine.setADSR(adsr_vals[0]*2.0f, adsr_vals[1]*2.0f, adsr_vals[2], adsr_vals[3]*2.0f);
|
||||
engine.setFilter(20.0f + filter_vals[0]*19980.0f, 20.0f + filter_vals[1]*19980.0f);
|
||||
|
||||
// --- Main Loop ---
|
||||
const SynthEngine::GridCell::Type cellTypes[] = {
|
||||
SynthEngine::GridCell::EMPTY,
|
||||
@@ -785,6 +872,12 @@ int main(int argc, char* argv[]) {
|
||||
SynthEngine::GridCell::WAVETABLE,
|
||||
SynthEngine::GridCell::NOISE,
|
||||
SynthEngine::GridCell::LFO,
|
||||
SynthEngine::GridCell::GATE,
|
||||
SynthEngine::GridCell::GATE_INPUT,
|
||||
SynthEngine::GridCell::ADSR_ATTACK,
|
||||
SynthEngine::GridCell::ADSR_DECAY,
|
||||
SynthEngine::GridCell::ADSR_SUSTAIN,
|
||||
SynthEngine::GridCell::ADSR_RELEASE,
|
||||
SynthEngine::GridCell::FORK,
|
||||
SynthEngine::GridCell::WIRE,
|
||||
SynthEngine::GridCell::LPF,
|
||||
@@ -792,6 +885,8 @@ int main(int argc, char* argv[]) {
|
||||
SynthEngine::GridCell::VCA,
|
||||
SynthEngine::GridCell::BITCRUSHER,
|
||||
SynthEngine::GridCell::DISTORTION,
|
||||
SynthEngine::GridCell::RECTIFIER,
|
||||
SynthEngine::GridCell::PITCH_SHIFTER,
|
||||
SynthEngine::GridCell::GLITCH,
|
||||
SynthEngine::GridCell::OPERATOR,
|
||||
SynthEngine::GridCell::DELAY,
|
||||
@@ -859,14 +954,14 @@ 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) && c.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) {
|
||||
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
|
||||
@@ -945,37 +1040,6 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
if (mouseX >= GRID_PANEL_WIDTH) {
|
||||
int synthX = mouseX - GRID_PANEL_WIDTH;
|
||||
|
||||
// Handle Sliders
|
||||
// ADSR: x=200, 250, 300, 350. y=380, h=150
|
||||
// Filters: x=450, 500.
|
||||
int sliderY = 380;
|
||||
int sliderH = 150;
|
||||
int sliderW = 30;
|
||||
|
||||
auto checkSlider = [&](int idx, int sx, float* val) {
|
||||
if (synthX >= sx && synthX <= sx + sliderW && mouseY >= sliderY - 20 && mouseY <= sliderY + sliderH + 20) {
|
||||
*val = 1.0f - (float)(mouseY - sliderY) / (float)sliderH;
|
||||
if (*val < 0.0f) *val = 0.0f;
|
||||
if (*val > 1.0f) *val = 1.0f;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
bool changed = false;
|
||||
if (checkSlider(0, 200, &adsr_vals[0])) changed = true;
|
||||
if (checkSlider(1, 250, &adsr_vals[1])) changed = true;
|
||||
if (checkSlider(2, 300, &adsr_vals[2])) changed = true;
|
||||
if (checkSlider(3, 350, &adsr_vals[3])) changed = true;
|
||||
if (changed) engine.setADSR(adsr_vals[0]*2.0f, adsr_vals[1]*2.0f, adsr_vals[2], adsr_vals[3]*2.0f);
|
||||
|
||||
if (checkSlider(0, 450, &filter_vals[0]) || checkSlider(1, 500, &filter_vals[1])) {
|
||||
// Map 0-1 to 20Hz-20kHz
|
||||
float lpFreq = 20.0f + pow(filter_vals[0], 2.0f) * 19980.0f; // Exponential feel
|
||||
float hpFreq = 20.0f + pow(filter_vals[1], 2.0f) * 19980.0f;
|
||||
engine.setFilter(lpFreq, hpFreq);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (e.type == SDL_KEYDOWN) {
|
||||
@@ -1078,14 +1142,6 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
drawToggle(renderer, 580, 450, 30, auto_melody_enabled);
|
||||
|
||||
drawSlider(renderer, 200, 380, 30, 150, adsr_vals[0], "A");
|
||||
drawSlider(renderer, 250, 380, 30, 150, adsr_vals[1], "D");
|
||||
drawSlider(renderer, 300, 380, 30, 150, adsr_vals[2], "S");
|
||||
drawSlider(renderer, 350, 380, 30, 150, adsr_vals[3], "R");
|
||||
|
||||
drawSlider(renderer, 450, 380, 30, 150, filter_vals[0], "LP");
|
||||
drawSlider(renderer, 500, 380, 30, 150, filter_vals[1], "HP");
|
||||
|
||||
// --- Draw Grid Panel (Left) ---
|
||||
SDL_Rect gridViewport = {0, 0, GRID_PANEL_WIDTH, WINDOW_HEIGHT};
|
||||
SDL_RenderSetViewport(renderer, &gridViewport);
|
||||
|
||||
Reference in New Issue
Block a user