summaryrefslogtreecommitdiffstats
path: root/src/synth_gui.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/synth_gui.c')
-rw-r--r--src/synth_gui.c432
1 files changed, 266 insertions, 166 deletions
diff --git a/src/synth_gui.c b/src/synth_gui.c
index 47a9125..85a5be2 100644
--- a/src/synth_gui.c
+++ b/src/synth_gui.c
@@ -4,7 +4,7 @@
//#include "raylib.h"
void
-draw_text(synth_t * synth, Font f, int x, int y)
+draw_text(synth_t * synth, int x, int y)
{
char buf[64];
int count = 0;
@@ -24,7 +24,6 @@ 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)
{
@@ -48,28 +47,28 @@ mouse(synth_t *synth, PaStream *stream)
}
}
- if (CheckCollisionPointRec(GetMousePosition(), (Rectangle){30, 250, 30, 30})) {
- SetMouseCursor(6);
- if (IsMouseButtonPressed(0)) {
- flag = 1;
- }
- } else {
- SetMouseCursor(0);
- }
+ /* 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;
- }
+ /* 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
@@ -104,6 +103,7 @@ keyboard(synth_t * synth, PaStream *stream)
synth->active = 1;
}
}
+
for (int i = 0; keys[i]; i++) {
if (IsKeyReleased(keys[i])) {
synth->midi_note[i].noteOff = Pa_GetStreamTime(synth->stream);
@@ -111,13 +111,13 @@ keyboard(synth_t * synth, PaStream *stream)
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};
+
+ int patates[] = {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];
- }
+ for (int i = 0; patates[i]; i++) {
+ if (IsKeyDown(patates[i])) {
+ synth->modifiers[synth->modi++] = patates[i];
+ }
}
if (IsKeyDown(265)) { // up
@@ -179,77 +179,53 @@ keyboard(synth_t * synth, PaStream *stream)
}
}
-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.3f);
-}
-
void frequencyToColor(float frequency, int *red, int *green, int *blue) {
- // Assuming frequency ranges from 20 to 20000 Hz
- float minFrequency = 20.0;
- float maxFrequency = 20000.0;
-
- // Map the frequency to a value between 0 and 1
- float normalizedFrequency = (frequency - minFrequency) / (maxFrequency - minFrequency);
-
- // Define colors for the rainbow spectrum
- float hue = normalizedFrequency * 360.0;
-
- // Convert HSV to RGB
- float c = 1.0;
- float x = c * (1.0 - fabs(fmod(hue / 60.0, 2.0) - 1.0));
- float m = 0.0;
-
- float r, g, b;
-
- if (hue >= 0 && hue < 60) {
- r = c;
- g = x;
- b = 0;
- } else if (hue >= 60 && hue < 120) {
- r = x;
- g = c;
- b = 0;
- } else if (hue >= 120 && hue < 180) {
- r = 0;
- g = c;
- b = x;
- } else if (hue >= 180 && hue < 240) {
- r = 0;
- g = x;
- b = c;
- } else if (hue >= 240 && hue < 300) {
- r = x;
- g = 0;
- b = c;
- } else {
- r = c;
- g = 0;
- b = x;
- }
+ // Assuming frequency ranges from 20 to 20000 Hz
+ float minFrequency = 20.0;
+ float maxFrequency = 20000.0;
+
+ // Map the frequency to a value between 0 and 1
+ float normalizedFrequency = (frequency - minFrequency) / (maxFrequency - minFrequency);
+
+ // Define colors for the rainbow spectrum
+ float hue = normalizedFrequency * 360.0;
+
+ // Convert HSV to RGB
+ float c = 1.0;
+ float x = c * (1.0 - fabs(fmod(hue / 60.0, 2.0) - 1.0));
+ float m = 0.0;
+
+ float r, g, b;
+
+ if (hue >= 0 && hue < 60) {
+ r = c;
+ g = x;
+ b = 0;
+ } else if (hue >= 60 && hue < 120) {
+ r = x;
+ g = c;
+ b = 0;
+ } else if (hue >= 120 && hue < 180) {
+ r = 0;
+ g = c;
+ b = x;
+ } else if (hue >= 180 && hue < 240) {
+ r = 0;
+ g = x;
+ b = c;
+ } else if (hue >= 240 && hue < 300) {
+ r = x;
+ g = 0;
+ b = c;
+ } else {
+ r = c;
+ g = 0;
+ b = x;
+ }
- *red = (int)((r + m) * 255);
- *green = (int)((g + m) * 255);
- *blue = (int)((b + m) * 255);
+ *red = (int)((r + m) * 255);
+ *green = (int)((g + m) * 255);
+ *blue = (int)((b + m) * 255);
}
#include "fftw3.h"
@@ -315,66 +291,67 @@ draw_wave(synth_t *synth, int x, int y, int width, int height)
void
draw_fft(synth_t *synth, int x, int y, int width, int height)
{
- int viz_size = width * synth->viz.rate_divider;
- int fft_output_len = viz_size / 2 + 1;
+ int viz_size = width * synth->viz.rate_divider;
+ int fft_output_len = viz_size / 2 + 1;
- fftwf_complex* output = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fft_output_len);
+ fftwf_complex* output = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fft_output_len);
- fftwf_plan forward_plan = fftwf_plan_dft_r2c_1d(fft_output_len, synth->viz.fft_input_buffer, output, FFTW_ESTIMATE);
+ fftwf_plan forward_plan = fftwf_plan_dft_r2c_1d(fft_output_len, synth->viz.fft_input_buffer, output, FFTW_ESTIMATE);
- fftwf_execute(forward_plan);
+ fftwf_execute(forward_plan);
- fftwf_destroy_plan(forward_plan);
+ fftwf_destroy_plan(forward_plan);
- // "Squash" into the Logarithmic Scale
- float step = 1.06;
- float lowf = 1.0f;
- size_t m = 0;
- float max_amp_tso = 1.0f;
- for (float f = lowf; (size_t) f < fft_output_len/2; f = ceilf(f*step)) {
- float f1 = ceilf(f*step);
- float a = 0.0f;
- for (size_t q = (size_t) f; q < fft_output_len/2 && q < (size_t) f1; ++q) {
- float b = log(sqrt(output[q][0]*output[q][0] + output[q][1]*output[q][1]));
- if (b > a) a = b;
- }
- if (max_amp_tso < a) max_amp_tso = a;
- synth->viz.fft_output_buffer[m++] = a;
+ // "Squash" into the Logarithmic Scale
+ float step = 1.06;
+ float lowf = 1.0f;
+ size_t m = 0;
+ float max_amp_tso = 1.0f;
+ for (float f = lowf; (size_t) f < fft_output_len/2; f = ceilf(f*step)) {
+ float f1 = ceilf(f*step);
+ float a = 0.0f;
+ for (size_t q = (size_t) f; q < fft_output_len/2 && q < (size_t) f1; ++q) {
+ // maybe take the log? maybe not
+ float b = log(sqrt(output[q][0]*output[q][0] + output[q][1]*output[q][1]));
+ if (b > a) a = b;
}
+ if (max_amp_tso < a) max_amp_tso = a;
+ synth->viz.fft_output_buffer[m++] = a;
+ }
- // Normalize Frequencies to 0..1 range
- for (size_t i = 0; i < m; ++i) {
- synth->viz.fft_output_buffer[i] /= max_amp_tso;
- }
+ // Normalize Frequencies to 0..1 range
+ for (size_t i = 0; i < m; ++i) {
+ synth->viz.fft_output_buffer[i] /= max_amp_tso;
+ }
- // Smooth out and smear the values
- for (size_t i = 0; i < m; ++i) {
- float smoothness = 4;
- synth->viz.fft_smooth_buffer[i] += (synth->viz.fft_output_buffer[i] - synth->viz.fft_smooth_buffer[i])*smoothness*((float)1/30);
- /* float smearness = 3; */
- /* ss_smear[i] += (synth->viz.fft_smooth_buffer[i] - ss_smear[i])*smearness*((float)1/30); */
- }
- // Display the Bars
- float cell_width = (float)width/m;
- for (size_t i = 0; i < m; ++i) {
- float t = synth->viz.fft_smooth_buffer[i];
- float saturation = 0.75f;
- float value = 1.0f;
- float hue = (float)i/m;
- Color color = ColorFromHSV(hue*360, saturation, value);
- Vector2 startPos = {
- x + i*cell_width + cell_width/2,
- y + height - height*2/3*t,
- };
- Vector2 endPos = {
- x + i*cell_width + cell_width/2,
- y + height,
- };
- float thick = cell_width/3*sqrtf(t);
- DrawLineEx(startPos, endPos, thick, BLUE);
- }
+ // Smooth out and smear the values
+ for (size_t i = 0; i < m; ++i) {
+ float smoothness = 4;
+ synth->viz.fft_smooth_buffer[i] += (synth->viz.fft_output_buffer[i] - synth->viz.fft_smooth_buffer[i])*smoothness*((float)1/30);
+ /* float smearness = 3; */
+ /* ss_smear[i] += (synth->viz.fft_smooth_buffer[i] - ss_smear[i])*smearness*((float)1/30); */
+ }
+ // Display the Bars
+ float cell_width = (float)width/m;
+ for (size_t i = 0; i < m; ++i) {
+ float t = synth->viz.fft_smooth_buffer[i];
+ float saturation = 0.75f;
+ float value = 1.0f;
+ float hue = (float)i/m;
+ Color color = ColorFromHSV(hue*360, saturation, value);
+ Vector2 startPos = {
+ x + i*cell_width + cell_width/2,
+ y + height - height*2/3*t,
+ };
+ Vector2 endPos = {
+ x + i*cell_width + cell_width/2,
+ y + height,
+ };
+ float thick = cell_width/3*sqrtf(t);
+ DrawLineEx(startPos, endPos, thick, BLUE);
+ }
- fftwf_free(output);
+ fftwf_free(output);
}
void
@@ -424,38 +401,45 @@ 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)
{
+ adsr_t adsr;
- float total = synth->adsr.a + synth->adsr.d + synth->adsr.r + 0.3; /*sustain*/
+ adsr.a = synth->cc_adsr_a.target;
+ adsr.peak = synth->cc_adsr_peak.target;
+ adsr.d = synth->cc_adsr_d.target;
+ adsr.s = synth->cc_adsr_s.target;
+ adsr.r = synth->cc_adsr_r.target;
+
+ float total = synth->cc_adsr_a.target + synth->cc_adsr_d.target + synth->cc_adsr_r.target + 0.3; /*sustain*/
int total_samples = total * SAMPLE_RATE;
- int a = synth->adsr.a/total * width;
- int d = synth->adsr.d/total * width;
+ int a = synth->cc_adsr_a.target/total * width;
+ int d = synth->cc_adsr_d.target/total * width;
int s = 0.3/total * width;
- int r = synth->adsr.r/total * width;
+ int r = synth->cc_adsr_r.target/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,
+ point = fix_adsr(&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,
+ point = fix_adsr(&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,
+ point = fix_adsr(&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,
+ point = fix_adsr(&adsr,
0, // note On
1, // note Off
(float)i/width * total_samples,
@@ -545,10 +529,30 @@ draw_signals(synth_t * synth, int x, int y, int width, int height)
draw_adsr_graph(synth, x + 20, y + 20, width - 40, height - 40);
}
}
+char * flag = NULL;
void
-draw_cc(cc_t * cc, int x, int y, int width, int height) {
+draw_cc_circle(cc_t * cc, int x, int y, int width, int height) {
//DrawRectangleLines(x, y, width, height, WHITE);
+ if (CheckCollisionPointRec(GetMousePosition(), (Rectangle){x, y, width, height})) {
+ if (IsMouseButtonPressed(0)) {
+ flag = cc->name;
+ }
+ }
+
+ if (IsMouseButtonDown(0) && flag == cc->name) {
+ Vector2 dx = GetMouseDelta();
+ int x = 1;
+ if (IsKeyDown(KEY_LEFT_SHIFT)) {
+ x = 3;
+ }
+ if (dx.y < 0) cc_step(cc, 1*x);
+ if (dx.y > 0) cc_step(cc, -1*x);
+ }
+ if (IsMouseButtonReleased(0) && flag == cc->name) {
+ flag = 0;
+ }
+
int min = 110;
int max = 110 + (360+70 - 110) * (cc->target) / (cc->max - cc->min);
@@ -563,40 +567,136 @@ draw_cc(cc_t * cc, int x, int y, int width, int height) {
}
+float
+map(float value, float start1, float end1, float start2, float end2) {
+ return start2 + (end2 - start2) * ((value - start1) / (end1 - start1));
+}
+
+
+void
+draw_cc_hbar(cc_t * cc, int x, int y, int width, int height) {
+ char buf1[32], buf2[32];
+
+ Vector2 p = GetMousePosition();
+
+ if (CheckCollisionPointRec(p, (Rectangle){x, y, width, height})) {
+ if (IsMouseButtonPressed(0)) {
+ flag = cc->name;
+ }
+ }
+ if (IsMouseButtonDown(0) && flag == cc->name) {
+ if (p.x < x) {
+ cc->target = cc->min;
+ } else if (p.x >= x + width) {
+ cc->target = cc->max;
+ } else {
+ cc->target = (cc->min + (cc->max - cc->min) * ((((p.x - x) * (float)1/width) - 0) / (1 - 0)));
+ }
+ }
+ if (IsMouseButtonReleased(0) && flag == cc->name) {
+ flag = 0;
+ }
+
+ int current = width * (cc->target - cc->min) / (cc->max - cc->min) + cc->min;
+ int fill_width = map(cc->target, cc->min, cc->max, 0, width - 2);
+
+
+ snprintf(buf1, sizeof buf1, "%.2f", cc->target);
+ snprintf(buf2, sizeof buf2, "%s", cc->name);
+
+ DrawRectangleLines(x, y, width, height, WHITE);
+ DrawRectangle(x+1, y+1, fill_width, height-2, Fade(MAROON, 0.7f));
+
+ DrawText(buf2, x + width/2 - MeasureText(buf2, 10) / 2, y + height - 10 - 2, 10, WHITE);
+ DrawText(buf1, x + 3, y + height / 2 - 10 / 2, 10, WHITE);
+}
+
+void
+draw_cc_vbar(cc_t * cc, int x, int y, int width, int height) {
+ char buf1[32], buf2[32];
+ int current = height * (cc->target - cc->min) / (cc->max - cc->min) + cc->min - 1;
+
+ Vector2 p = GetMousePosition();
+
+ if (CheckCollisionPointRec(p, (Rectangle){x, y, width, height})) {
+ if (IsMouseButtonPressed(0)) {
+ flag = cc->name;
+ }
+ }
+ if (IsMouseButtonDown(0) && flag == cc->name) {
+ if (p.y < y) {
+ cc->target = cc->max;
+ } else if (p.y >= y + height) {
+ cc->target = cc->min;
+ } else {
+ cc->target = cc->min + cc->max - (cc->min + (cc->max - cc->min) * ((((p.y - y) * (float)1/height) - 0) / (1 - 0)));
+ }
+ }
+ if (IsMouseButtonReleased(0) && flag == cc->name) {
+ flag = 0;
+ }
+
+ snprintf(buf1, sizeof buf1, "%.2f", cc->target);
+ snprintf(buf2, sizeof buf2, "%s", cc->name);
+
+ int fill_height = map(cc->target, cc->min, cc->max, 0, height - 2);
+
+ DrawRectangleLines(x, y, width, height, WHITE);
+ DrawRectangle(x + 1, y + height - fill_height - 1, width - 2, fill_height, Fade(MAROON, 0.7f));
+
+ DrawText(buf2, x + width/2 - MeasureText(buf2, 10) / 2, y + height + 10, 10, WHITE);
+ DrawText(buf1, x + width/2 - MeasureText(buf1, 10) / 2, y - 10, 10, WHITE);
+}
+
+
+void
+draw_bars(synth_t * synth, int x, int y, int width, int height, int offset)
+{
+ int count = 0;
+
+ draw_cc_hbar(&synth->cc_adsr_a, x, y + count++ * (height + offset), width, height);
+ draw_cc_hbar(&synth->cc_adsr_peak, x, y + count++ * (height + offset), width, height);
+ draw_cc_hbar(&synth->cc_adsr_d, x, y + count++ * (height + offset), width, height);
+ draw_cc_hbar(&synth->cc_adsr_s, x, y + count++ * (height + offset), width, height);
+ draw_cc_hbar(&synth->cc_adsr_r, x, y + count++ * (height + offset), width, height);
+ draw_cc_hbar(&synth->cc_gain, x, y + count++ * (height + offset), width, height);
+ draw_cc_hbar(&synth->cc_del_feedback, x, y + count++ * (height + offset), width, height);
+ draw_cc_hbar(&synth->cc_del_time, x, y + count++ * (height + offset), width, height);
+}
void
rayrun(synth_t *synth){
PaTime current_time = 0;
PaTime prev_time = 0;
+ osc_sound(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);
- draw_cc(&synth->cc_adsr_s, 30, 250, 30, 30);
+ draw_cc_circle(&synth->cc_pitch, 30, 250, 30, 30);
+ draw_cc_hbar(&synth->cc_cutoff, 30, 300, 256, 24);
+ draw_cc_vbar(&synth->cc_resonance, 330, 20, 24, 256);
+ //draw_cc_vbar(&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", 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);
+ draw_bars(synth, 20, 20, 200, 16, 3);
+ draw_text(synth, WIDTH / 2 - 108, 20);
if ( GuiButton((Rectangle){ WIDTH / 2 - 108, 150 - 6 - 6 + 42, 216, 6 }, "")) {
synth->x = 1;