summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgramanas <anastasis.gramm2@gmail.com>2023-12-02 17:44:20 +0200
committergramanas <anastasis.gramm2@gmail.com>2023-12-02 17:44:20 +0200
commit89b515395310c4e84a84992d3f0bd11f8ded6d03 (patch)
tree7c8554dedd0e6736a0b7db5d5f2285fbd31fe3f9
parent4f7de09c753ece6f2099512522d489b0104a59a8 (diff)
downloadsynth-project-89b515395310c4e84a84992d3f0bd11f8ded6d03.tar.gz
synth-project-89b515395310c4e84a84992d3f0bd11f8ded6d03.tar.bz2
synth-project-89b515395310c4e84a84992d3f0bd11f8ded6d03.zip
gui is mine
-rw-r--r--src/midi.c4
-rw-r--r--src/osc_sound.c5
-rw-r--r--src/sound.c2
-rw-r--r--src/synth_engine.c3
-rw-r--r--src/synth_engine.h11
-rw-r--r--src/synth_engine_v2.c49
-rw-r--r--src/synth_gui.c432
7 files changed, 307 insertions, 199 deletions
diff --git a/src/midi.c b/src/midi.c
index 11029b0..389a670 100644
--- a/src/midi.c
+++ b/src/midi.c
@@ -123,12 +123,13 @@ void midi_decode(uint32_t msg, synth_t * synth) {
}
}
-
+int enable = 0;
void
midiCallback(PtTimestamp timestamp, void *userData) {
midi_t * m = (midi_t *)userData;
if (!m->stream) return;
+ if (!enable) return;
// if (!Pm_Poll(m->stream)) return;
@@ -174,6 +175,7 @@ init_midi(midi_t *m, synth_t *synth)
128,
NULL,
NULL);
+ enable = 1;
}
void
diff --git a/src/osc_sound.c b/src/osc_sound.c
index 49d9867..cbdd7b5 100644
--- a/src/osc_sound.c
+++ b/src/osc_sound.c
@@ -23,8 +23,9 @@ osc_sound(float offset)
//osc_load_wav(&OSC_sound, "/home/gramanas/code/synth-project/waves/Free Wavetables[128]/FM Synthesis[128-44.1khz-16bit]/FM Sq- NotPM.wav");
//osc_load_wav(&OSC_sound, "/home/gramanas/code/synth-project/waves/Free Wavetables[2048]/Melda Oscillator[2048-44.1khz-32bit]/Melda SKEW.wav");
//osc_load_wav(&OSC_sound, "/home/gramanas/code/synth-project/waves/Free Wavetables[2048]/Filter Sweep[2048-44.1khz-32bit]/SweepSaw.wav");
- //osc_load_wav(&OSC_sound, "/home/gramanas/code/synth-project/waves/Free Wavetables[2048]/Additive Synth[2048-44.1khz-32bit]/Add Synth7.wavw");
- osc_load_wav(&OSC_sound, "/home/gramanas/code/synth-project/waves/Free Wavetables[2048]/Korg Analog Synth PhaseShift[2048-44.1khz-32bit]/MS 20 Saw MPS.wav");
+ //osc_load_wav(&OSC_sound, "/home/gramanas/code/synth-project/waves/Free Wavetables[2048]/Additive Synth[2048-44.1khz-32bit]/Add Synth7.wav");
+ //osc_load_wav(&OSC_sound, "/home/gramanas/code/synth-project/waves/Free Wavetables[2048]/Korg Analog Synth PhaseShift[2048-44.1khz-32bit]/MS 20 Saw MPS.wav");
+ osc_load_wav(&OSC_sound, "/home/gramanas/code/synth-project/waves/Free Wavetables[2048]/Korg Analog Synth PhaseShift[2048-44.1khz-32bit]/MonoPoly Saw PS1.wav");
OSC_sound.start = wvt_size*0;
OSC_sound.len = OSC_sound.start + wvt_size;
}
diff --git a/src/sound.c b/src/sound.c
index aaffd13..57baa6b 100644
--- a/src/sound.c
+++ b/src/sound.c
@@ -42,6 +42,8 @@ init_sound(synth_t * synth, PaStreamCallback *streamCallback)
Pa_SetStreamFinishedCallback(synth->stream, &StreamFinished);
Pa_StartStream(synth->stream);
+
+ synth->sound_active = 1;
}
void
diff --git a/src/synth_engine.c b/src/synth_engine.c
index 15dda16..34f876a 100644
--- a/src/synth_engine.c
+++ b/src/synth_engine.c
@@ -485,7 +485,7 @@ init_synth(synth_t * synth)
synth->lfo.amp = 0.0f;
synth->lfo.elapsed = 0;
- for (int i = 0; i < MIDI_NOTES; i++) {
+ for (int i =0; i<MIDI_NOTES; i++) {
synth->midi_note[i].freq = 0;
synth->midi_note[i].channel = -1;
synth->midi_note[i].noteOn = -1;
@@ -533,7 +533,6 @@ init_synth(synth_t * synth)
init_sound(synth, sound_gen);
synth->osctri = make_tri("triangle");
-
}
void
diff --git a/src/synth_engine.h b/src/synth_engine.h
index 674c287..3b0b238 100644
--- a/src/synth_engine.h
+++ b/src/synth_engine.h
@@ -78,12 +78,12 @@ typedef struct {
cc_t cc_lfo_freq;
cc_t cc_lfo_amp;
cc_t cc_adsr_a;
+ cc_t cc_adsr_peak;
cc_t cc_adsr_d;
cc_t cc_adsr_s;
cc_t cc_adsr_r;
+ cc_t cc_gain;
- float gain;
-
float x;
midi_note_t midi_note[MIDI_NOTES];
@@ -99,8 +99,8 @@ typedef struct {
int delay;
float * del;
int deli;
- float del_time;
- float del_feedback;
+ cc_t cc_del_time;
+ cc_t cc_del_feedback;
unsigned long long counter;
int filter;
@@ -116,10 +116,9 @@ typedef struct {
BWBandStop* fff2;
int active;
+ int sound_active;
synth_viz viz;
-
- osc_t * osctri;
} synth_t;
synth_t * init_synth();
diff --git a/src/synth_engine_v2.c b/src/synth_engine_v2.c
index 9beae33..bfd1d4a 100644
--- a/src/synth_engine_v2.c
+++ b/src/synth_engine_v2.c
@@ -178,6 +178,7 @@ make_sample(synth_t * synth, unsigned int sample_rate, int frame)
//float max = get_max_sample(synth, 20);
synth->adsr.a = CC_GET(adsr_a);
+ synth->adsr.peak = CC_GET(adsr_peak);
synth->adsr.d = CC_GET(adsr_d);
synth->adsr.s = CC_GET(adsr_s);
synth->adsr.r = CC_GET(adsr_r);
@@ -204,7 +205,7 @@ make_sample(synth_t * synth, unsigned int sample_rate, int frame)
/* filter */
do_fliter(synth, &sample, sample_rate, frame);
- sample = synth->gain * sample;
+ sample = CC_GET(gain) * sample;
// band stop for high freqs
//sample = bw_band_stop(synth->fff2, sample);
@@ -254,8 +255,8 @@ get_frame(void *outputBuffer, synth_t *synth, int i)
s = make_sample(synth, SAMPLE_RATE, i);
synth->counter++;
- if (synth->counter >= (int)(synth->del_time * SAMPLE_RATE * 10)) {
- int idx = (synth->deli - (int)(synth->del_time * SAMPLE_RATE * 10)) % (SAMPLE_RATE * 10);
+ if (synth->counter >= (int)(synth->cc_del_time.target * SAMPLE_RATE)) {
+ int idx = (synth->deli - (int)(synth->cc_del_time.target * SAMPLE_RATE)) % (SAMPLE_RATE * 10);
float tmp;
if (idx >= 0) {
tmp = synth->del[idx];
@@ -263,7 +264,7 @@ get_frame(void *outputBuffer, synth_t *synth, int i)
tmp = synth->del[SAMPLE_RATE * 10 + idx];
}
- s = clamp(s + synth->del_feedback * tmp, -1, 1);
+ s = clamp(s + synth->cc_del_feedback.target * tmp, -1, 1);
}
add_to_delay(synth, s);
@@ -288,6 +289,8 @@ sound_gen(const void *inputBuffer, void *outputBuffer,
synth_t *synth = (synth_t*)synthData;
float *out = (float*)outputBuffer;
+ if (!synth->sound_active) return 0; //paContinue;
+
float buffer[2 * FRAMES_PER_BUFFER];
float buffer2[2 * FRAMES_PER_BUFFER];
@@ -341,20 +344,23 @@ init_synth(void)
if (!synth) return NULL;
synth->cci = 0;
- // CC(SYNTH, NAME, MIN, MAX, STEP, DEF)
- CC(synth->cc_cutoff, "cutoff", 10, 22000, 30, 5000);
- CC(synth->cc_resonance, "resonance", 1, 10, .02, 1);
- CC(synth->cc_lfo_freq, "lfo_freq", 1, 1000, 2, 1);
- CC(synth->cc_lfo_amp, "lfo_amp", 0, 1, .01f, 0);
- CC(synth->cc_pitch, "pitch", -3, 4, 0.01f, 1);
- CC(synth->cc_adsr_a, "attack", 0, 3, 0.01f, 0.00);
- CC(synth->cc_adsr_d, "decay", 0, 2, 0.01f, 0.3);
- CC(synth->cc_adsr_s, "sustain", 0, 1.0f, 0.01f, 0.7f);
- CC(synth->cc_adsr_r, "release", 0, 5, 0.01f, 0.2f);
-
- synth->modi = 0;
-
- synth->gain = 0.5;
+ // CC(SYNTH, NAME, MIN, MAX, STEP, DEF)
+ CC(synth->cc_cutoff, "cutoff", 10, 22000, 30, 5000);
+ CC(synth->cc_resonance, "resonance", 1, 10, .02, 1);
+ CC(synth->cc_lfo_freq, "lfo_freq", 1, 1000, 2, 1);
+ CC(synth->cc_lfo_amp, "lfo_amp", 0, 1, .01f, 0);
+ CC(synth->cc_pitch, "pitch", -3, 4, 0.01f, 1);
+ CC(synth->cc_adsr_a, "attack", 0, 3, 0.01f, 0.00);
+ CC(synth->cc_adsr_peak, "peak", 0, 1, 0.01f, 1.00);
+ CC(synth->cc_adsr_d, "decay", 0, 2, 0.01f, 0.3);
+ CC(synth->cc_adsr_s, "sustain", 0, 1.0f, 0.01f, 0.7f);
+ CC(synth->cc_adsr_r, "release", 0, 5, 0.01f, 0.2f);
+ CC(synth->cc_del_time, "time", 0, 3, 0.01f, 0.5f);
+ CC(synth->cc_del_feedback, "feedback", 0, 1, 0.01f, 0.5f);
+ CC(synth->cc_gain, "gain", 0, 1, 0.01f, 0.5f);
+
+ //synth->modi = 0;
+
synth->x = 1;
synth->adsr.a = 0.00001f;
@@ -388,8 +394,6 @@ init_synth(void)
synth->delay = 0;
synth->del = (float *) calloc(sizeof(float), SAMPLE_RATE * 30);
synth->deli = 0;
- synth->del_time = .1;
- synth->del_feedback = 0.5f;
synth->counter;
synth->filter = 1;
@@ -410,10 +414,9 @@ init_synth(void)
synth->fff = create_bw_low_pass_filter(2, SAMPLE_RATE, 400);
synth->fff2 = create_bw_band_stop_filter(8, SAMPLE_RATE, 15000, 22000);
+ synth->sound_active = 0;
init_sound(synth, sound_gen);
- synth->osctri = make_tri("triangle");
-
synth->viz.rate_divider = 15;
// for (int i = 0; i < RING_SIZE; i++) synth->viz.wave_buffer_data[i] = 0;
synth->viz.wave_buffer_data = (float *)calloc(sizeof(float), RING_SIZE);
@@ -437,6 +440,8 @@ init_synth(void)
synth->viz.tmp_index = 0;
synth->wvt_pos = 0;
+
+ return synth;
}
void
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;