summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/synth_engine.h1
-rw-r--r--src/synth_gui.c84
2 files changed, 85 insertions, 0 deletions
diff --git a/src/synth_engine.h b/src/synth_engine.h
index e198c22..8330daa 100644
--- a/src/synth_engine.h
+++ b/src/synth_engine.h
@@ -52,6 +52,7 @@ typedef struct synth_viz {
int wave_enabled;
int adsr_enabled;
int adsr_graph_enabled;
+ int filter_adsr_graph_enabled;
int osc_enabled;
int freeze;
int rate_divider;
diff --git a/src/synth_gui.c b/src/synth_gui.c
index 169d057..da90f52 100644
--- a/src/synth_gui.c
+++ b/src/synth_gui.c
@@ -482,6 +482,85 @@ draw_adsr_graph(synth_t * synth, int x, int y, int width, int height)
}
void
+draw_filter_adsr_graph(synth_t * synth, int x, int y, int width, int height)
+{
+ adsr_t f_adsr;
+
+ f_adsr.a = synth->cc_f_adsr_a.target;
+ f_adsr.peak = synth->cc_f_adsr_peak.target;
+ f_adsr.d = synth->cc_f_adsr_d.target;
+ f_adsr.s = synth->cc_f_adsr_s.target;
+ f_adsr.r = synth->cc_f_adsr_r.target;
+
+ float total = synth->cc_f_adsr_a.target + synth->cc_f_adsr_d.target + synth->cc_f_adsr_r.target + 0.3; /*sustain*/
+ int total_samples = total * SAMPLE_RATE;
+ int a = synth->cc_f_adsr_a.target/total * width;
+ int d = synth->cc_f_adsr_d.target/total * width;
+ int s = 0.3/total * width;
+ int r = synth->cc_f_adsr_r.target/total * width;
+
+ float f_adsr_graph[width];
+ for (int i = 0; i < width; i++) {
+ float point = 0;
+
+ if (i < a) { //draw attack
+ point = fix_adsr(&f_adsr,
+ 1, // note On
+ 0, // note Off
+ (float)i/width * total_samples,
+ 0);
+ } else if (i < a + d) { // draw decay
+ point = fix_adsr(&f_adsr,
+ 1, // note On
+ 0, // note Off
+ (float)i/width * total_samples,
+ 0);
+ } else if (i < a + d + s) { // draw sustain
+ point = fix_adsr(&f_adsr,
+ 1, // note On
+ 0, // note Off
+ (float)i/width * total_samples,
+ 0);
+ } else if (r && i < a + d + s + r) { // draw release
+ point = fix_adsr(&f_adsr,
+ 0, // note On
+ 1, // note Off
+ (float)i/width * total_samples,
+ (float)(a + d + s)/width * total_samples);
+ }
+ f_adsr_graph[i] = point * height;
+ }
+ f_adsr_graph[0] = f_adsr_graph[1]; // remove 1st 0
+
+ // Draw filter ADSR in blue to distinguish from amplitude ADSR
+ for (int i = 0; i < width; i++) {
+ DrawPixel(i + x , y + height - f_adsr_graph[i], BLUE);
+ }
+
+ // Draw current position indicators for active notes
+ 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 - f_adsr_graph[j], 3, BLUE);
+ } else if (j < a + d + s - 1) {
+ DrawCircle(j + x , y + height - f_adsr_graph[j], 3, BLUE);
+ } else if (j > a + d + s - 1) {
+ DrawCircle(a + d + s + x , y + height - f_adsr_graph[a + d + s], 3, BLUE);
+ }
+ } 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 - f_adsr_graph[id], 3, BLUE);
+ }
+ }
+}
+
+void
draw_signals(synth_t * synth, int x, int y, int width, int height)
{
DrawRectangleLines(x, y, width, height, WHITE);
@@ -533,6 +612,11 @@ draw_signals(synth_t * synth, int x, int y, int width, int height)
if (synth->viz.adsr_graph_enabled) {
draw_adsr_graph(synth, x + 20, y + 20, width - 40, height - 40);
}
+
+ synth->viz.filter_adsr_graph_enabled = GuiCheckBox((Rectangle){ x + width - 370, y, 16, 16 }, "filter adsr", synth->viz.filter_adsr_graph_enabled);
+ if (synth->viz.filter_adsr_graph_enabled) {
+ draw_filter_adsr_graph(synth, x + 20, y + 20, width - 40, height - 40);
+ }
}
char * flag = NULL;