#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; synth->active = 1; } 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] %fHz\n", int_to_note(i % 12), (synth->octave + (i / 12)) % 8, note); synth->midi_note[i].freq = 16.35 * pow(2, (synth->octave + i / 12.0)); //notes[i % 12][(synth->octave + (i / 12)) % 8]; //synth->midi_note[i].freq = notes[i % 12][(synth->octave + (i / 12)) % 8]; synth->midi_note[i].channel = -1; synth->midi_note[i].noteOn = Pa_GetStreamTime(synth->stream); synth->midi_note[i].noteOff = 0; synth->midi_note[i].velocity = 1.0; synth->midi_note[i].elapsed = 0; synth->midi_note[i].active = 1; } } } for (int i = 0; keys[i]; i++) { if (IsKeyReleased(keys[i])) { synth->midi_note[i].noteOff = Pa_GetStreamTime(synth->stream); note = notes[i % 12][(synth->octave + (i / 12)) % 8]; if (synth->n.key == keys[i]) { synth->n.noteOff = Pa_GetStreamTime(stream); synth->midi_note[i].noteOff = Pa_GetStreamTime(synth->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 = GuiSlider((Rectangle){ x, y + count++ * (height + offset), width, height }, "A: ", buf, synth->adsr.a , 0.0f, 2.0f); snprintf(buf, sizeof buf, "%.3f", synth->adsr.peak); synth->adsr.peak = GuiSlider((Rectangle){ x, y + count++ * (height + offset), width, height }, "P: ", buf, synth->adsr.peak , 0.0f, 1.0f); snprintf(buf, sizeof buf, "%.3f", synth->adsr.d); synth->adsr.d = GuiSlider((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 = GuiSlider((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 = GuiSlider((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); snprintf(buf, sizeof buf, "%.3f", synth->lfo.freq); synth->lfo.freq = GuiSliderBar((Rectangle){ x, y + count++ * (height + offset), width, height }, "lfo freq: ", buf, synth->lfo.freq , 0.001f, 10.0f); snprintf(buf, sizeof buf, "%.3f", synth->lfo.amp); synth->lfo.amp = GuiSliderBar((Rectangle){ x, y + count++ * (height + offset), width, height }, "lfo amprrrrrr: ", buf, synth->lfo.amp , 0.0f, 0.93f); } 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; for (int i = x; i < WIDTH - x; i++) { DrawCircle(i , y + height / 2 + floor(250 * synth->viz.wave[i - x]), point_radius, MAGENTA); } 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(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, synth->n.noteOn, synth->n.noteOff)), 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, synth->n.noteOn, synth->n.noteOff)), point_radius, BLUE); } } void rayrun(void *synthData) { 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, synth->stream); int prec = 100000; if (IsKeyPressed(KEY_ENTER)) { synth->multi = !synth->multi; } // Draw //---------------------------------------------------------------------------------- BeginDrawing(); ClearBackground(BLACK); // 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 = GuiSlider((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 = GuiSlider((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 = GuiSlider((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); synth->poly = GuiToggle((Rectangle){ WIDTH - 100 - 50 - 100 - 50 , 50 + 24 + 6 + 24 + 6, 100, 24 }, "POLY", synth->poly); 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, "%f", synth->viz.wave[0]); DrawText(buf, WIDTH / 2 -300, HEIGHT - 40 - 50, 20, LIGHTGRAY); EndDrawing(); //---------------------------------------------------------------------------------- current_time = Pa_GetStreamTime(synth->stream); //printf("%f :: %ld\n", current_time - prev_time, phase); prev_time = current_time; } CloseWindow(); }