summaryrefslogtreecommitdiffstats
path: root/src/synth_gui.c
diff options
context:
space:
mode:
authorgramanas <anastasis.gramm2@gmail.com>2023-04-18 16:31:25 +0300
committergramanas <anastasis.gramm2@gmail.com>2023-04-18 16:31:25 +0300
commit9c6410cc3a43d9d1e01f853cb5a8d0f8a6d93b45 (patch)
treea4c044223d224090e54828903ae223788f97c8e6 /src/synth_gui.c
downloadsynth-project-9c6410cc3a43d9d1e01f853cb5a8d0f8a6d93b45.tar.gz
synth-project-9c6410cc3a43d9d1e01f853cb5a8d0f8a6d93b45.tar.bz2
synth-project-9c6410cc3a43d9d1e01f853cb5a8d0f8a6d93b45.zip
autotools initial...
Diffstat (limited to 'src/synth_gui.c')
-rw-r--r--src/synth_gui.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/src/synth_gui.c b/src/synth_gui.c
new file mode 100644
index 0000000..3cfde6f
--- /dev/null
+++ b/src/synth_gui.c
@@ -0,0 +1,173 @@
+#include "synth_gui.h"
+#define RAYGUI_IMPLEMENTATION
+#include "raygui.h"
+//#include "raylib.h"
+
+
+void
+set_note(void *synthData, float note, PaTime time, int key)
+{
+ synth_t * synth = (synth_t *)synthData;
+
+ synth->n.key = key;
+ synth->n.freq = note;
+ synth->n.noteOn = time;
+ synth->n.noteOff = 0;
+ synth->n.elapsed = 0;
+ synth->adsr.elapsed = 0;
+}
+
+
+void
+keyboard(void *synthData, PaStream *stream)
+{
+ synth_t * synth = (synth_t *)synthData;
+
+ int keys[] = {KEY_Q, KEY_TWO, KEY_W, KEY_THREE, KEY_E, KEY_R, KEY_FIVE, KEY_T, KEY_SIX, KEY_Y, KEY_SEVEN, KEY_U, KEY_I, KEY_NINE, KEY_O, KEY_ZERO, KEY_P, KEY_LEFT_BRACKET, KEY_EQUAL, KEY_RIGHT_BRACKET, 0};
+
+ float note;
+
+ for (int i = 0; keys[i]; i++) {
+ if (IsKeyPressed(keys[i])) {
+ note = notes[i % 12][(synth->octave + (i / 12)) % 8];
+ if (note) {
+ set_note(synth, note, Pa_GetStreamTime(stream), keys[i]);
+ printf("Note On : %s[%d]\n", int_to_note(i % 12), (synth->octave + (i / 12)) % 8);
+ }
+ }
+ }
+ for (int i = 0; keys[i]; i++) {
+ if (IsKeyReleased(keys[i])) {
+ if (synth->n.key == keys[i]) {
+ synth->n.noteOff = Pa_GetStreamTime(stream);
+ printf("Note Off: %s[%d]\n", int_to_note(i % 12), (synth->octave + (i / 12)) % 8);
+ }
+ }
+ }
+}
+
+void
+draw_adsr_sliders(synth_t * synth, int x, int y, int width, int height, int offset)
+{
+ char buf[64];
+ int count = 0;
+
+ snprintf(buf, sizeof buf, "%.3f", synth->adsr.a);
+ synth->adsr.a = GuiSliderBar((Rectangle){ x, y + count++ * (height + offset), width, height }, "A: ", buf, synth->adsr.a , 0.001f, 2.0f);
+ snprintf(buf, sizeof buf, "%.3f", synth->adsr.d);
+ synth->adsr.d = GuiSliderBar((Rectangle){ x, y + count++ * (height + offset), width, height }, "D: ", buf, synth->adsr.d , 0.001f, 2.0f);
+ snprintf(buf, sizeof buf, "%.3f", synth->adsr.s);
+ synth->adsr.s = GuiSliderBar((Rectangle){ x, y + count++ * (height + offset), width, height }, "S: ", buf, synth->adsr.s , 0.0f, 1.0f);
+ snprintf(buf, sizeof buf, "%.3f", synth->adsr.r);
+ synth->adsr.r = GuiSliderBar((Rectangle){ x, y + count++ * (height + offset), width, height }, "R: ", buf, synth->adsr.r , -0.001f, 3.0f);
+ snprintf(buf, sizeof buf, "%.3f", synth->cutoff);
+ synth->cutoff = GuiSliderBar((Rectangle){ x, y + count++ * (height + offset), width, height }, "fC: ", buf, synth->cutoff , 0.0f, 11000.0f);
+ snprintf(buf, sizeof buf, "%.3f", synth->resonance);
+ synth->resonance = GuiSliderBar((Rectangle){ x, y + count++ * (height + offset), width, height }, "fR: ", buf, synth->resonance , 0.001f, 5.0f);
+}
+
+void
+draw_signals(synth_t * synth, int x, int y, int width, int height)
+{
+ DrawRectangleLines(x, y, width, height, BLACK);
+
+ int point_radius = 1.5;
+
+ GuiSpinner((Rectangle){ x+ 100, y - 24 - 6, 100, 24 }, "rate divider: ", &(synth->viz.sample_rate_divider), 1, 10, 0);
+ int period = (1 / (synth->n.freq + 1)) * SAMPLE_RATE / synth->viz.sample_rate_divider;
+
+ if (synth->multi) {
+ for (int i = x; i < WIDTH - x; i++) {
+ DrawCircle(i , y + height / 2 + floor(50 * make_sample(i - x, synth, SAMPLE_RATE / synth->viz.sample_rate_divider, 1)), point_radius, RED);
+ }
+ } else {
+ for (int i = x; i < WIDTH - x; i++) {
+ //DrawCircle((WIDTH - (1 / (synth->n.freq + 1)) * SAMPLE_RATE) / 2 + i , (HEIGHT / 2) + floor(50 * make_sample(i % period, synth, SAMPLE_RATE)), point_radius, RED);
+ DrawCircle(i , y + height / 2 + floor(50 * make_sample((i - x) % period, synth, SAMPLE_RATE / synth->viz.sample_rate_divider, 1)), point_radius, RED);
+ }
+ }
+
+ for (int i = x; i < WIDTH - x; i++) {
+ DrawCircle(i , y + height - 1+ floor((WIDTH / 24) * - adsr_amplitude(synth, synth->adsr.elapsed)), point_radius, GREEN);
+ }
+ float adsr_duration = synth->adsr.a + synth->adsr.d + (synth->adsr.a + synth->adsr.d + synth->adsr.r) / 3.0 + synth->adsr.r;
+ for (int i = x; i < WIDTH - x; i++) {
+ DrawCircle(i , y + height - 1 + floor((WIDTH / 24) * - adsr_amplitude(synth, (i - x) * (adsr_duration * SAMPLE_RATE) / WIDTH)), point_radius, BLUE);
+ }
+}
+
+void
+rayrun(void *synthData, PaStream *stream)
+{
+ synth_t * synth = (synth_t *)synthData;
+ PaTime current_time = 0;
+ PaTime prev_time = 0;
+
+ InitWindow(WIDTH, HEIGHT, "Raylib synth");
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ while (!WindowShouldClose()) {
+
+ keyboard(synth, stream);
+ int prec = 100000;
+
+ if (IsKeyPressed(KEY_ENTER)) {
+ synth->multi = !synth->multi;
+ }
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+ ClearBackground(RAYWHITE);
+
+ // GUI
+ char buf[64];
+
+ draw_adsr_sliders(synth, 30, 20, 256, 20, 4);
+
+
+ if ( GuiButton((Rectangle){ WIDTH / 2 - 108, 150 - 42 - 6 - 6, 216, 6 }, "")) {
+ synth->freq_offset = 0;
+ }
+ snprintf(buf, sizeof buf, "%.1f", synth->freq_offset);
+ synth->freq_offset = GuiSliderBar((Rectangle){ WIDTH / 2 - 108, 150 - 42, 216, 24 }, "fine", buf, synth->freq_offset , -20.0f, 20.0f);
+
+ if ( GuiButton((Rectangle){ WIDTH / 2 - 108, 150 - 6 - 6, 216, 6 }, "")) {
+ synth->gain = 1;
+ }
+ snprintf(buf, sizeof buf, "%.1f", synth->gain);
+ synth->gain = GuiSliderBar((Rectangle){ WIDTH / 2 - 108, 150, 216, 24 }, "gain", buf, synth->gain , 0.0f, 2.0f);
+
+ if ( GuiButton((Rectangle){ WIDTH / 2 - 108, 150 - 6 - 6 + 42, 216, 6 }, "")) {
+ synth->x = 1;
+ }
+ snprintf(buf, sizeof buf, "%.1f", synth->x);
+ synth->x = GuiSliderBar((Rectangle){ WIDTH / 2 - 108, 150 + 42, 216, 24 }, "x", buf, synth->x , 0.0f, 2.0f);
+
+ synth->multi = GuiToggle((Rectangle){ WIDTH - 100 - 50 - 100 - 50 , 50, 100, 24 }, "!MULTI!", synth->multi);
+ synth->filter = GuiToggle((Rectangle){ WIDTH - 100 - 50 - 100 - 50 , 50 + 24 + 6, 100, 24 }, "FILTER", synth->filter);
+
+ GuiSpinner((Rectangle){ WIDTH - 100 - 50 , 50, 100, 24 }, "oct: ", &(synth->octave), 0, 7, 0);
+ snprintf(buf, sizeof buf, "generator %d --> ", synth->geni);
+ GuiSpinner((Rectangle){ WIDTH - 100 - 50 , 50 + 24 + 6, 100, 24 }, buf, &(synth->geni), 0, 3, 0);
+
+ synth->clamp = GuiToggle((Rectangle){ WIDTH - 100 - 50, 50 + 24 + 6 + 24 + 6, 100, 24 }, "clamp", synth->clamp);
+
+
+ // signals
+ draw_signals(synth, 20, 390, WIDTH - 2*20, 200);
+
+ DrawText("THE SYNTH!!!!!!!!!!!!!!!!!!1", WIDTH / 2 - 100, 50, 20, LIGHTGRAY);
+ DrawText("KEYBOARD: Q .. ] TOGGLE MULTI: ENTER", WIDTH / 2 -300, HEIGHT - 20 - 50, 20, LIGHTGRAY);
+ snprintf(buf, sizeof buf, "time?: %lld adsr: %lld note: %lld", synth->adsr.elapsed / SAMPLE_RATE, synth->adsr.elapsed, synth->n.elapsed);
+ DrawText(buf, WIDTH / 2 -300, HEIGHT - 40 - 50, 20, LIGHTGRAY);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+
+ current_time = Pa_GetStreamTime(stream);
+ //printf("%f :: %ld\n", current_time - prev_time, phase);
+
+ prev_time = current_time;
+ }
+ CloseWindow();
+}