#include "synth_gui.h" #define RAYGUI_IMPLEMENTATION #include "raygui.h" //#include "raylib.h" void draw_text(synth_t * synth, Font f, int x, int y) { char buf[64]; int count = 0; float text_size = 10; int offset = 12; snprintf(buf, sizeof buf, "lfo freq %.4f", synth->cc_lfo_freq.value); DrawText(buf, x, y + offset * count++, text_size, GRAY); snprintf(buf, sizeof buf, "lfo amp %.4f", synth->cc_lfo_amp.value); DrawText(buf, x, y + offset * count++, text_size, GRAY); snprintf(buf, sizeof buf, "filter reso %.4f", synth->cc_resonance.value); DrawText(buf, x, y + offset * count++, text_size, GRAY); snprintf(buf, sizeof buf, "filter cutoff %.1f", synth->cc_cutoff.value); DrawText(buf, x, y + offset * count++, text_size, GRAY); snprintf(buf, sizeof buf, "extra pitch %.4f", synth->cc_pitch.value); DrawText(buf, x, y + offset * count++, text_size, GRAY); DrawRectangleLines(x - 6, y - 3, 120, 3 + (count * offset) + 3, GRAY); } void mouse(void *synthData, PaStream *stream) { synth_t * synth = (synth_t *)synthData; float m = GetMouseWheelMove(); int x = 0; if (m < 0) x = -1; else if (m > 0) x = 1; int y = GetMouseY(); if (x) { if (y > 20 && y <= 32) { cc_step(&synth->cc_lfo_freq, x); } else if (y > 32 && y <= 44) { cc_step(&synth->cc_lfo_amp, x); } else if (y > 44 && y <= 56) { cc_step(&synth->cc_resonance, x); } else if (y > 56 && y <= 68) { cc_step(&synth->cc_cutoff, x); } else if (y > 68 && y <= 80) { cc_step(&synth->cc_pitch, x); } } } 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])) { //printf("Note On : %s[%d] %fHz\n", int_to_note(i % 12), (synth->octave + (i / 12)) % 8, note); synth->midi_note[i].freq = 16.35160 * pow(2, (synth->octave + i / 12.0)); //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; //synth->adsr.elapsed = 0; synth->active = 1; } } for (int i = 0; keys[i]; i++) { if (IsKeyReleased(keys[i])) { synth->midi_note[i].noteOff = Pa_GetStreamTime(synth->stream); synth->midi_note[i].noteOffSample = synth->midi_note[i].elapsed; note = notes[i % 12][(synth->octave + (i / 12)) % 8]; } } int mods[] = {KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, KEY_N, KEY_M, 0}; synth->modi = 0; for (int i = 0; mods[i]; i++) { if (IsKeyDown(mods[i])) { synth->modifiers[synth->modi++] = mods[i]; } } if (IsKeyDown(265)) { // up for (int i = 0; i < synth->modi; i++) { if (synth->modifiers[i] == KEY_Z) { cc_step(&synth->cc_cutoff, 1); } if (synth->modifiers[i] == KEY_X) { cc_step(&synth->cc_resonance, 1); } if (synth->modifiers[i] == KEY_C) { cc_step(&synth->cc_pitch, 1); } if (synth->modifiers[i] == KEY_V) { cc_step(&synth->cc_lfo_freq, 1); } if (synth->modifiers[i] == KEY_B) { cc_step(&synth->cc_lfo_amp, 1); } } } if (IsKeyDown(264)) { // down for (int i = 0; i < synth->modi; i++) { if (synth->modifiers[i] == KEY_Z) { cc_step(&synth->cc_cutoff, -1); } if (synth->modifiers[i] == KEY_X) { cc_step(&synth->cc_resonance, -1); } if (synth->modifiers[i] == KEY_C) { cc_step(&synth->cc_pitch, -1); } if (synth->modifiers[i] == KEY_V) { cc_step(&synth->cc_lfo_freq, -1); } if (synth->modifiers[i] == KEY_B) { cc_step(&synth->cc_lfo_amp, -1); } } } if (IsKeyDown(KEY_ENTER)) { // down for (int i = 0; i < synth->modi; i++) { if (synth->modifiers[i] == KEY_Z) { cc_reset(&synth->cc_cutoff); } if (synth->modifiers[i] == KEY_X) { cc_reset(&synth->cc_resonance); } if (synth->modifiers[i] == KEY_C) { cc_reset(&synth->cc_pitch); } if (synth->modifiers[i] == KEY_V) { cc_reset(&synth->cc_lfo_freq); } if (synth->modifiers[i] == KEY_B) { cc_reset(&synth->cc_lfo_amp); } } } } void draw_bars(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.00001f, 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->gain); synth->gain = GuiSlider((Rectangle){ x, y + count++ * (height + offset), width, height }, "gain: ", buf, synth->gain , 0.0f, 2.0f); snprintf(buf, sizeof buf, "%.3f", synth->del_feedback); synth->del_feedback = GuiSlider((Rectangle){ x, y + count++ * (height + offset), width, height }, "fb: ", buf, synth->del_feedback , 0.0f, 1.0f); snprintf(buf, sizeof buf, "%.3f", synth->del_time); synth->del_time = GuiSlider((Rectangle){ x, y + count++ * (height + offset), width, height }, "del_time: ", buf, synth->del_time , 0.0f, 0.1f); } 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); for (int i = x; i < WIDTH - x; i++) { if (synth->viz.wave[i - x] > 1 || synth->viz.wave[i - x] < -1) DrawCircle(i , y + height / 2 + floor(50 * synth->viz.wave[i - x]), point_radius, RED); else if (synth->viz.wave[i - x] >= 0.99 || synth->viz.wave[i - x] <= -0.99) DrawCircle(i , y + height / 2 + floor(50 * synth->viz.wave[i - x]), point_radius, MAGENTA); else DrawCircle(i , y + height / 2 + floor(50 * synth->viz.wave[i - x]), point_radius, RAYWHITE); } int c = 0; for (int i = 0; i < MIDI_NOTES; i++) { if (!synth->midi_note[i].active) continue; c++; } int x_prev = x; for (int i = 0; i < MIDI_NOTES; i++) { if (!synth->midi_note[i].active) continue; int rec_y = y + height - 1 + 4.5 * floor( (WIDTH / 24) * - fix_adsr(&synth->adsr, synth->midi_note[i].noteOn, synth->midi_note[i].noteOff, synth->midi_note[i].elapsed, synth->midi_note[i].noteOffSample)); int rec_width = (WIDTH - x - x) / c; int rec_height = HEIGHT - rec_y; //DrawLine(x_prev, v, x_prev + (WIDTH - x) / c, v , WHITE); DrawRectangleGradientV(x_prev, rec_y, rec_width, rec_height, ColorAlpha(GREEN, .2) ,ColorAlpha(RED, .2)); DrawRectangleLines(x_prev, rec_y, rec_width, rec_height, GRAY); x_prev += rec_width; } } void rayrun(void *synthData){ synth_t * synth = (synth_t *)synthData; PaTime current_time = 0; PaTime prev_time = 0; 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 while (!WindowShouldClose()) { keyboard(synth, synth->stream); mouse(synth, synth->stream); int prec = 100000; // Draw //---------------------------------------------------------------------------------- BeginDrawing(); ClearBackground(BLACK); // GUI char buf[64]; draw_bars(synth, 33, 20, 256, 20, 4); draw_text(synth, f, WIDTH / 2 - 108, 20); 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->filter = GuiToggle((Rectangle){ WIDTH - 100 - 50 - 100 - 50 , 50 , 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, 6, 0); synth->clamp = GuiToggle((Rectangle){ WIDTH - 100 - 50, 50 + 24 + 6 + 24 + 6, 100, 24 }, "clamp", synth->clamp); synth->delay = GuiToggle((Rectangle){ WIDTH - 100 - 50, 50 + 24 + 6 + 24 + 6 + 24 + 6, 100, 24 }, "delay", synth->delay); // signals draw_signals(synth, 20, 390, WIDTH - 2*20, 200); //DrawText("THE SYNTH!!!!!!!!!!!!!!!!!!1", WIDTH / 2 - 100, 50, 20, LIGHTGRAY); /* DrawText("KEYBOARD: Q .. ]", WIDTH / 2 -300, HEIGHT - 300 - 50, 20, LIGHTGRAY); */ /* snprintf(buf, sizeof buf, "stream time: %f", Pa_GetStreamTime(synth->stream)); */ /* DrawText(buf, WIDTH / 2 -300, HEIGHT - 300, 11, LIGHTGRAY); */ EndDrawing(); //---------------------------------------------------------------------------------- current_time = Pa_GetStreamTime(synth->stream); //printf("%f :: %ld\n", current_time - prev_time, phase); prev_time = current_time; } CloseWindow(); }