From 42479d2ed8fcbad5fb3ffb52553dad05a329590f Mon Sep 17 00:00:00 2001 From: gramanas Date: Sun, 30 Jul 2023 20:51:05 +0300 Subject: oop --- src/osc.h | 28 +++++++++++++++++++++------- src/osc_tri.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/synth_engine.c | 25 +++++++++++++++++-------- src/synth_engine.h | 5 ++++- 4 files changed, 85 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/osc.h b/src/osc.h index 732f134..7fd0303 100644 --- a/src/osc.h +++ b/src/osc.h @@ -2,6 +2,9 @@ #define OSC_H #include +#include +#include +#include /** * The main idea of the osc is the following: @@ -19,6 +22,14 @@ enum osc_type { WAVE, SAMPLE }; +struct osc_t; +struct osc_ops { + void (*set_start)(struct osc_t *, long); + void (*set_end) (struct osc_t *, long); + void (*set_len) (struct osc_t *, long); + float (*sample) (struct osc_t *, float); + float (*next) (struct osc_t *, float, float); +}; typedef struct osc_t { char name[16]; @@ -27,15 +38,16 @@ typedef struct osc_t { long start; long end; enum osc_type type; + const struct osc_ops * ops; } osc_t; -#define MAKE_OSC(_name, _len, _type) {\ - .name = _name, \ - .data = 0, \ - .len = _len, \ - .start = 0, \ - .end = _len, \ - .type = _type, \ +#define MAKE_OSC(_name, _len, _type) { \ + .name = _name, \ + .data = 0, \ + .len = _len, \ + .start = 0, \ + .end = _len, \ + .type = _type, \ }; /* Initializes the wavetables and functions for the oscilators */ @@ -47,6 +59,8 @@ int osc_next_index(osc_t * osc, float offset); int osc_load_wav(osc_t * osc, const char * path); +osc_t * make_tri(const char * name); + /***************/ /* OSCILATORS */ /***************/ diff --git a/src/osc_tri.c b/src/osc_tri.c index c4a56f5..8d2ef82 100644 --- a/src/osc_tri.c +++ b/src/osc_tri.c @@ -28,3 +28,46 @@ osc_tri_next(float f, float offset) { return osc_next_offset(&OSC_tri, f, offset); } + + +static float +tri_sample(osc_t * osc, float offset) +{ + return osc_interpolate(offset, + tri((int)offset), + tri(osc_next_index(osc, offset))); +} + +static float +tri_next(osc_t * osc, float f, float offset) +{ + return osc_next_offset(osc, f, offset); +} + +static const struct osc_ops osc_operations = { + .sample = tri_sample, + .next = tri_next, +}; + +osc_t * +make_tri(const char * name) +{ + osc_t * osc = (osc_t *)malloc(sizeof(osc_t)); + + int len = strlen(name); + strncpy(osc->name, name, 16); + osc->data = NULL; + osc->len = 2; + osc->start = 0; + osc->end = 2; + osc->type = WAVE; + osc->ops = &osc_operations; + + return osc; +} + +void +free_tri(osc_t * osc) +{ + free(osc); +} diff --git a/src/synth_engine.c b/src/synth_engine.c index d17ba49..8fc8221 100644 --- a/src/synth_engine.c +++ b/src/synth_engine.c @@ -92,8 +92,8 @@ gen3(float f, midi_note_t * midi_note, float x, unsigned int sample_rate) //return sqr_sample(1, f, .5, midi_note->elapsed, sample_rate); //return wvt_next(wvt_sound, f, sample_rate, &midi_note->wvt_index); - float sample = osc_saw(midi_note->wvt_index); - midi_note->wvt_index = osc_saw_next(f, midi_note->wvt_index); + float sample = osc_sound(midi_note->wvt_index); + midi_note->wvt_index = osc_sound_next(f, midi_note->wvt_index); return sample; /* return sawX_sample(0.7, f, 5, midi_note->elapsed, sample_rate) */ @@ -103,7 +103,10 @@ gen3(float f, midi_note_t * midi_note, float x, unsigned int sample_rate) float gen4(float f, midi_note_t * midi_note, float x, unsigned int sample_rate) { - return wvt_next(wvt_tri, f, sample_rate, &midi_note->wvt_index); + float sample = osc_tri(midi_note->wvt_index); + midi_note->wvt_index = osc_tri_next(f, midi_note->wvt_index); + return sample; + //return wvt_next(wvt_tri, f, sample_rate, &midi_note->wvt_index); } float @@ -176,6 +179,9 @@ make_sample(void *synthData, unsigned int sample_rate, int frame) rms += synth->midi_note[i].velocity * synth->midi_note[i].velocity; } + // if rms == 0 we can deduce there are no notes however notes_active handles + // stopping any already playing notes and if we remove it we need to make + // sure that notes stop some other way (it laso happens every frame) rms = sqrt(rms / n); for (int i = 0; i < MIDI_NOTES; i++) { @@ -194,10 +200,12 @@ make_sample(void *synthData, unsigned int sample_rate, int frame) // (1.05946309436/24.0) * (wvt_next(wvt_tri, (wvt_next(wvt_sound, 2 * cc_iget(&synth->cc_lfo_freq, frame, FRAMES_PER_BUFFER), SAMPLE_RATE, &lfo_index) / 2.0 + 0.5) * cc_iget(&synth->cc_lfo_freq, frame, FRAMES_PER_BUFFER), SAMPLE_RATE, &synth->midi_note[i].lfo_index) / 2.0 + 0.5); - float synth_sample = synth->gen[synth->geni](targ_freq, - &synth->midi_note[i], - synth->x, - sample_rate); + float synth_sample = synth->osctri->ops->sample(synth->osctri, synth->midi_note[i].wvt_index); + synth->midi_note[i].wvt_index = synth->osctri->ops->next(synth->osctri, targ_freq, synth->midi_note[i].wvt_index); + /* float synth_sample = synth->gen[synth->geni](targ_freq, */ + /* &synth->midi_note[i], */ + /* synth->x, */ + /* sample_rate); */ sample += 0.2 * rms * adsr * synth_sample; } @@ -414,7 +422,6 @@ init_synth(synth_t * synth) synth->modi = 0; - synth->freq_offset = 0; synth->gain = 1; synth->x = 1; @@ -470,6 +477,8 @@ init_synth(synth_t * synth) init_sound(synth, sound_gen); wvt_init(); + + synth->osctri = make_tri("triangle"); } void diff --git a/src/synth_engine.h b/src/synth_engine.h index 38ff740..c3175ec 100644 --- a/src/synth_engine.h +++ b/src/synth_engine.h @@ -11,6 +11,7 @@ #include "filter.h" #include "adsr.h" #include "control.h" +#include "osc.h" #ifndef M_PI @@ -55,8 +56,8 @@ typedef struct { cc_t cc_lfo_freq; cc_t cc_lfo_amp; - float freq_offset; float gain; + float x; midi_note_t midi_note[MIDI_NOTES]; @@ -86,6 +87,8 @@ typedef struct { int active; viz_t viz; + + osc_t * osctri; } synth_t; void init_synth(synth_t * synth); -- cgit v1.2.3