From 4f7de09c753ece6f2099512522d489b0104a59a8 Mon Sep 17 00:00:00 2001 From: gramanas Date: Mon, 27 Nov 2023 18:33:42 +0200 Subject: cc adsr and ui --- src/synth_gui.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 126 insertions(+), 6 deletions(-) (limited to 'src/synth_gui.c') diff --git a/src/synth_gui.c b/src/synth_gui.c index dd4c75b..47a9125 100644 --- a/src/synth_gui.c +++ b/src/synth_gui.c @@ -24,7 +24,7 @@ draw_text(synth_t * synth, Font f, int x, int y) DrawRectangleLines(x - 6, y - 3, 120, 3 + (count * offset) + 3, GRAY); } - +int flag =0; void mouse(synth_t *synth, PaStream *stream) { @@ -47,6 +47,29 @@ mouse(synth_t *synth, PaStream *stream) cc_step(&synth->cc_pitch, x); } } + + if (CheckCollisionPointRec(GetMousePosition(), (Rectangle){30, 250, 30, 30})) { + SetMouseCursor(6); + if (IsMouseButtonPressed(0)) { + flag = 1; + } + } else { + SetMouseCursor(0); + } + + if (IsMouseButtonDown(0) && flag) { + SetMouseCursor(6); + Vector2 dx = GetMouseDelta(); + int x = 1; + if (IsKeyDown(KEY_LEFT_SHIFT)) { + x = 3; + } + if (dx.y < 0) cc_step(&synth->cc_adsr_s, 1*x); + if (dx.y > 0) cc_step(&synth->cc_adsr_s, -1*x); + } + if (IsMouseButtonReleased(0)) { + flag = 0; + } } void @@ -398,6 +421,77 @@ draw_osc(synth_t * synth, int x, int y, int width, int height) } +void +draw_adsr_graph(synth_t * synth, int x, int y, int width, int height) +{ + + float total = synth->adsr.a + synth->adsr.d + synth->adsr.r + 0.3; /*sustain*/ + int total_samples = total * SAMPLE_RATE; + int a = synth->adsr.a/total * width; + int d = synth->adsr.d/total * width; + int s = 0.3/total * width; + int r = synth->adsr.r/total * width; + + float adsr_graph[width]; + for (int i = 0; i < width; i++) { + float point = 0; + + if (i < a) { //draw atack + point = fix_adsr(&synth->adsr, + 1, // note On + 0, // note Off + (float)i/width * total_samples, + 0); + } else if (i < a + d) { // draw decay + point = fix_adsr(&synth->adsr, + 1, // note On + 0, // note Off + (float)i/width * total_samples, + 0); + } else if (i < a + d + s) { // draw sustain + point = fix_adsr(&synth->adsr, + 1, // note On + 0, // note Off + (float)i/width * total_samples, + 0); + } else if (i < a + d + s + r) { // draw release + point = fix_adsr(&synth->adsr, + 0, // note On + 1, // note Off + (float)i/width * total_samples, + (float)(a + d + s)/width * total_samples); + } + adsr_graph[i] = point * height; + } + adsr_graph[0] = adsr_graph[1]; // remove 1st 0 + + for (int i = 0; i < width; i++) { + DrawPixel(i + x , y + height - adsr_graph[i], RED); + } + + int off_idx = a + d + s; + for (int i = 0; i < synth->midi_active_n; i++) { + midi_note_t * note = synth->midi_active[i]; + int elapsed_samples = note->elapsed; + float elapsed_secs = (float)elapsed_samples / SAMPLE_RATE; + int j = elapsed_secs / total * width; + + if (note->noteOff == 0) { + if (j < a + d) { + DrawCircle(j + x , y + height - adsr_graph[j], 5, RED); + } else if (j < a + d + s - 1) { + DrawCircle(j + x , y + height - adsr_graph[j], 5, RED); + } else if (j > a + d + s - 1) { + DrawCircle(a + d + s + x , y + height - adsr_graph[a + d + s], 5, RED); + } + } else { // note off + int id = a + d + s + (float)(note->elapsed - note->noteOffSample)/SAMPLE_RATE / total * width; + if (id > 0 && id < width) + DrawCircle(id + x , y + height - adsr_graph[id], 5, RED); + } + } +} + void draw_signals(synth_t * synth, int x, int y, int width, int height) { @@ -445,14 +539,36 @@ draw_signals(synth_t * synth, int x, int y, int width, int height) if (synth->viz.osc_enabled) { draw_osc(synth, x + width - 80, y + height - 80, 80, 80); } + + synth->viz.adsr_graph_enabled = GuiCheckBox((Rectangle){ x + width - 270, y, 16, 16 }, "adsr graph", synth->viz.adsr_graph_enabled); + if (synth->viz.adsr_graph_enabled) { + draw_adsr_graph(synth, x + 20, y + 20, width - 40, height - 40); + } } +void +draw_cc(cc_t * cc, int x, int y, int width, int height) { + //DrawRectangleLines(x, y, width, height, WHITE); + + int min = 110; + int max = 110 + (360+70 - 110) * (cc->target) / (cc->max - cc->min); + DrawRing((Vector2){x + width/2, y + height/2}, width / 2 - 6, width / 2, min, max, 0, Fade(MAROON, 0.7f)); + DrawCircle(x + width/2, y + height/2, width / 2 - 5, BLACK); // Draw circle sector outline + + char buf[32]; + snprintf(buf, sizeof buf, "%0.2f", cc->target); + DrawText(buf, x + width/2 - MeasureText(buf, 10) / 2, y + height/2 - 10 / 2, 10, GRAY); + snprintf(buf, sizeof buf, "%s", cc->name); + DrawText(buf, x + width/2 - MeasureText(buf, 10) / 2, y + height - 10 / 2, 10, GRAY); + +} + + void rayrun(synth_t *synth){ PaTime current_time = 0; PaTime prev_time = 0; - int len; InitWindow(WIDTH, HEIGHT, "Raylib synth"); Font f = LoadFont("/usr/share/fonts/TTF/DejaVuSans.ttf"); SetTargetFPS(60); // Set our game to run at 60 frames-per-second @@ -467,13 +583,17 @@ rayrun(synth_t *synth){ BeginDrawing(); ClearBackground(BLACK); + draw_cc(&synth->cc_adsr_s, 30, 250, 30, 30); + + DrawLineBezier((Vector2){30, 250}, (Vector2){30, 300}, .3, BLUE); + // GUI char buf[64]; osc_sound(0); - snprintf(buf, sizeof buf, "%d", len); - len = GuiSlider((Rectangle){WIDTH / 2 - 108, 150 + 42 + 42, 216, 24 }, "", buf, len , 0, 157); - set_sound_start(len*2048); - set_sound_len(len*2048 + 2048); + snprintf(buf, sizeof buf, "%d", synth->wvt_pos); + synth->wvt_pos = GuiSlider((Rectangle){WIDTH / 2 - 108, 150 + 42 + 42, 216, 24 }, "", buf, synth->wvt_pos , 0, 127); + set_sound_start(synth->wvt_pos*2048); + set_sound_len(synth->wvt_pos*2048 + 2048); draw_bars(synth, 33, 20, 256, 20, 4); draw_text(synth, f, WIDTH / 2 - 108, 20); -- cgit v1.2.3