From 1ef25d9be2b5358f3da7429bf0b27d5a9e9fa1a8 Mon Sep 17 00:00:00 2001 From: gramanas Date: Sat, 2 Sep 2023 19:39:15 +0300 Subject: DELAY --- src/generator.c | 16 +++++++++++++ src/generator.h | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/synth_engine.c | 63 ++++++++++++++++++++++++++++++++----------------- src/synth_engine.h | 7 ++++++ src/synth_gui.c | 5 ++++ 5 files changed, 139 insertions(+), 21 deletions(-) create mode 100644 src/generator.c create mode 100644 src/generator.h (limited to 'src') diff --git a/src/generator.c b/src/generator.c new file mode 100644 index 0000000..4e81297 --- /dev/null +++ b/src/generator.c @@ -0,0 +1,16 @@ +#include "generator.h" + + + +float +generate(generator * g, synth_t * s, int i) +{ + float sample = 0; + + float f = get_frequency(g, s, i);' + + sample = osc_saw(midi_note->wvt_index); + midi_note->wvt_index = osc_saw_next(f, midi_note->wvt_index); + + return sample; +} diff --git a/src/generator.h b/src/generator.h new file mode 100644 index 0000000..df90578 --- /dev/null +++ b/src/generator.h @@ -0,0 +1,69 @@ +#ifndef GENERATOR_H +#define GENERATOR_H + +#include "adsr.h" +#include "osc.h" +#include "synth_engine.h" + +#define MAX_CMP 64 + +enum osc_enum { + SIN, + SAW, + DIGISAW, + TRI, + SQR +}; + +enum adsr_type { + LINEAR, + CUBIC +}; + +enum target_enum { + OSC_FREQ, + OSC_AMP, + ADSR_AMP, + OUTPUT +}; + +// ints are: +// negative if false +// the id of the component if true +typedef struct sound_node { + int osc; + enum osc_enum osc_type; + int lfo; + enum adsr_enum adsr_type; + int adsr; + float target_amp; + enum target_enum target; + + struct sound_node ** children; + int n; +} sound_node; + +struct generator { + // list of indexes for oscilators, lfos and adsrs + float osc[MAX_CMP]; + float lfo[MAX_CMP]; + float adsr[MAX_CMP]; + + // need to include some info about the wiring of the oscs lfos and adsrs + // e.g. : + // adsr 0 -> osc 0 frequency + // lfo 0 -> osc 0 frequency + // lfo 1 -> lfo 0 frequency + // osc 0 -> output + + //o0-saw:l0-sin:l1-sin:a0-linear + //a0-o0/frequency:l0-o0/frequency:l1-l0/frequency:o0-1 +}; + +int sound_tree_add_node(sound_node * root, const char * cmp); + +// needs to "play" the wiring defined in the struct +// using sounds from `s` and the midi note `i` +float generate(generator * g, synth_t * s, int i); + +#endif /* GENERATOR_H */ diff --git a/src/synth_engine.c b/src/synth_engine.c index 4a4fd03..09c50bb 100644 --- a/src/synth_engine.c +++ b/src/synth_engine.c @@ -49,9 +49,6 @@ gen10(float f, unsigned long long phase, float x, unsigned int sample_rate) float gen110(float f, unsigned long long phase, float x, unsigned int sample_rate) { - /* return sawX_sample(0.5, f, 5, midi_note->elapsed, sample_rate) */ - /* + saw_sample(0.3, 2 * f / 5, midi_note->elapsed, sample_rate) */ - /* + sin_sample(0.2, f * 5.0 / 7.0 , midi_note->elapsed, sample_rate); */ float a = fmodf(phase, sample_rate/f); return a > (sample_rate/f) / 2.0f ? 0.9999f : -0.9999f; } @@ -62,16 +59,6 @@ gen0(float f, midi_note_t * midi_note, float x, unsigned int sample_rate) float sample = osc_sin(midi_note->wvt_index); midi_note->wvt_index = osc_sin_next(f, midi_note->wvt_index); return sample; - /* return sin_sample(1, f, midi_note->elapsed, sample_rate); */ - //return chirp(midi_note->elapsed, f); - /* return sqr_sample(0.1, f, 0.3, midi_note->elapsed, sample_rate) */ - /* + sqr_sample(0.1, f * 3.0 / 2.0 , 0.5, midi_note->elapsed, sample_rate) */ - /* + saw_sample(0.3, f, midi_note->elapsed, sample_rate) */ - /* + sin_sample(0.1, f, midi_note->elapsed, sample_rate) */ - /* + sin_sample(0.1, f * 5, midi_note->elapsed, sample_rate) */ - /* /\* + sin_sample(0.1, freq * 50 * 1021, midi_note->elapsed, sample_rate) *\/ */ - /* /\* + sin_sample(0.1, freq * 50 * 3531021, midi_note->elapsed, sample_rate) *\/ */ - /* + sin_sample(0.1, f * 7, midi_note->elapsed, sample_rate); */ } float @@ -243,6 +230,16 @@ add_to_viz(synth_t *synth, float sample) } } +void +add_to_delay(synth_t *synth, float sample) +{ + synth->del[synth->deli++] = sample; + + if (synth->deli >= SAMPLE_RATE * 10) { + synth->deli = 0; + } +} + void increment_synth(synth_t *synth) { @@ -264,24 +261,41 @@ get_frame(void *outputBuffer, synth_t *synth, int i) if (!synth->active) { - *out++ = 0.0f; - *out++ = 0.0f; + /* *out++ = 0.0f; */ + /* *out++ = 0.0f; */ - add_to_viz(synth, 0.0f); + //add_to_viz(synth, 0.0f); lfo_index = 0; - return; + // return; } if (!notes_active(synth)) { synth->active = 0; - *out++ = 0.0f; - *out++ = 0.0f; - add_to_viz(synth, 0.0f); + /* *out++ = 0.0f; */ + /* *out++ = 0.0f; */ + //add_to_viz(synth, 0.0f); lfo_index = 0; - return; + // return; + } + + if (!synth->delay) { + synth->counter = 0; } 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); + float tmp; + if (idx >= 0) { + tmp = synth->del[idx]; + } else { + tmp = synth->del[SAMPLE_RATE * 10 + idx]; + } + + s = clamp(s + synth->del_feedback * tmp, -1, 1); + } + add_to_delay(synth, s); *out++ = s; *out++ = s; @@ -449,6 +463,13 @@ init_synth(synth_t * synth) synth->octave = 3; + synth->delay = 0; + synth->del[SAMPLE_RATE * 10]; + synth->deli = 0; + synth->del_time = .1; + synth->del_feedback = 0.5f; + synth->counter; + synth->poly = 0; synth->multi = 0; synth->filter = 1; diff --git a/src/synth_engine.h b/src/synth_engine.h index c3175ec..b3b16d6 100644 --- a/src/synth_engine.h +++ b/src/synth_engine.h @@ -68,6 +68,13 @@ typedef struct { int octave; + int delay; + float del[SAMPLE_RATE * 10]; + int deli; + float del_time; + float del_feedback; + unsigned long long counter; + int poly; int multi; int filter; diff --git a/src/synth_gui.c b/src/synth_gui.c index 46ec71f..89782ed 100644 --- a/src/synth_gui.c +++ b/src/synth_gui.c @@ -176,6 +176,10 @@ draw_bars(synth_t * synth, int x, int y, int width, int height, int offset) synth->lfo.amp = GuiSliderBar((Rectangle){ x, y + count++ * (height + offset), width, height }, "lfo amp: ", buf, synth->lfo.amp , 0.0f, 0.93f); 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 @@ -263,6 +267,7 @@ rayrun(void *synthData){ 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); -- cgit v1.2.3