diff options
author | gramanas <anastasis.gramm2@gmail.com> | 2023-06-27 22:37:53 +0300 |
---|---|---|
committer | gramanas <anastasis.gramm2@gmail.com> | 2023-06-27 22:37:53 +0300 |
commit | 60c82a72fedd719f69c1f1de896aca00784a2881 (patch) | |
tree | 3679e0886fc12aa8eeeab60260347ee7a0c5ae0e /src/control.h | |
parent | e77d4d42cacd21bf80e4f47cba2fe85f5a5b0991 (diff) | |
download | synth-project-60c82a72fedd719f69c1f1de896aca00784a2881.tar.gz synth-project-60c82a72fedd719f69c1f1de896aca00784a2881.tar.bz2 synth-project-60c82a72fedd719f69c1f1de896aca00784a2881.zip |
Changes
Diffstat (limited to 'src/control.h')
-rw-r--r-- | src/control.h | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/src/control.h b/src/control.h new file mode 100644 index 0000000..8eee97b --- /dev/null +++ b/src/control.h @@ -0,0 +1,81 @@ +#ifndef CONTROL_H +#define CONTROL_H + +/** + Control Component + + The midi implementation polls the midi device every whenever and gets to + react to midi events. Any and all changes should not happen directly to the + active `value`, but rather to the `mod`. This way the sound engine can + smoothly interpolate the changed value while generating samples. + + The sound engine fills a buffer with samples. The buffer has BUFFER_SIZE. + Each call of the sound callback will insert BUFFER_SIZE samples in the + buffer. Before we get the samples, we poll the synth's ccs for any changes. + This will set the target value to the `value + mod`, and the sound engine + will interpolate the `value` from value to target . It should also reset the + mod since other midi events might trigger until the next buffer generation. +*/ + +typedef struct cc_t { + char name[64]; + int midi_cc; + float min, max; + float step; + float def; + float value; /* active value (start for interpolation) */ + float mod; /* stores the modified value before it is set as target */ + float target; /* target value (end for interpolation) */ +} cc_t; + +#ifndef CC +#define CC2(NAME, MIN, MAX, STEP, DEF) \ + (cc_t) { \ + .name = NAME, \ + .midi_cc = -1, \ + .min = MIN, \ + .max = MAX, \ + .step = STEP, \ + .def = DEF, \ + .value = DEF, \ + .mod = 0, \ + .target = DEF \ + }; +#define CC(SYNTH, NAME, MIN, MAX, STEP, DEF) \ + strcpy(SYNTH.name, NAME); \ + SYNTH.midi_cc = -1; \ + SYNTH.min = MIN; \ + SYNTH.max = MAX; \ + SYNTH.step = STEP; \ + SYNTH.def = DEF; \ + SYNTH.value = DEF; \ + SYNTH.mod = 0; \ + SYNTH.target = DEF; \ + synth->ccs[synth->cci++] = &SYNTH; +#endif + +/** + Step the value of the target cc for `steps`. + `steps` can be positive or negative. + + The change will occur in the mod value of the cc. + + returns 1 if the value changed, 0 otherwise + */ +int cc_step(cc_t *cc, int steps); + +/** + Reset the cc to defaults + */ +void cc_reset(cc_t *cc); + +/** + Get the interpolated value from 0 to `max` in position `i` + */ +float cc_iget(cc_t *cc, unsigned int i, unsigned int max); +void cc_prep(cc_t *cc); +void cc_fix(cc_t *cc); + +const char * cc_to_str(cc_t *cc); + +#endif /* CONTROL_H */ |