diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/midi.c | 4 | ||||
-rw-r--r-- | src/osc_sound.c | 5 | ||||
-rw-r--r-- | src/sound.c | 2 | ||||
-rw-r--r-- | src/synth_engine.c | 3 | ||||
-rw-r--r-- | src/synth_engine.h | 11 | ||||
-rw-r--r-- | src/synth_engine_v2.c | 49 | ||||
-rw-r--r-- | src/synth_gui.c | 432 |
7 files changed, 307 insertions, 199 deletions
@@ -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; |