usynth

simple midi synth for sndio
git clone git://nsmpr.xyz/usynth.git
Log | Files | Refs

commit a63175a99c62a0d07ccf4fa51c36e11b3bef0add
parent cee75e2bb82c9a8f9430164a7d5efe92ee581133
Author: zavok <an2qzavok@gmail.com>
Date:   Mon,  4 Nov 2019 20:12:25 +0300

implemented polyphony

Diffstat:
Mfm.c | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 53 insertions(+), 10 deletions(-)

diff --git a/fm.c b/fm.c @@ -16,18 +16,46 @@ double tune[]={ 30.87, //B 47 }; -size_t c, dt; +size_t c; int16_t vol; +struct schan{ + int id; + uint8_t note; + uint8_t velocity; +}; +struct schan fm_sounds[32]; + +int16_t fm_synth(int); +int16_t fm_mix(void); -int16_t fmsynth(void); +int16_t +fm_synth(int i) +{ + struct schan *sc; + sc = &fm_sounds[i]; + if (sc->id < 0) return 0; + if (sc->velocity == 0) return 0; + size_t dt; + int16_t out; + out = 0x7fff * sc->velocity / 0xff; + dt = 44100.0 / (tune[sc->note%12] * (1 << (sc->note/12))); + if (c%dt > dt/2) out = -out; + return out; +} int16_t -fm_synth(void) +fm_mix(void) { + int64_t out; + int i; c++; - if (dt == 0) return 0; - if (c%dt > dt / 2) return vol; - return -vol; + out = 0; + for (i=0; i<32; i++){ + out += fm_synth(i); + } + if (out > 0x7fff) out = 0x7fff; + if (out < -0x7fff) out = -0x7fff; + return out; } void @@ -35,19 +63,34 @@ fm_fillbuf(int16_t *buf, size_t nsamples) { size_t i; for (i=0; i < nsamples; i+=2){ - buf[i] = buf[i+1] = fm_synth(); + buf[i] = buf[i+1] = fm_mix(); } } void fm_note_on(uint8_t *mm) { - dt = 44100.0 / (tune[mm[2]%12] * (1 << mm[2]/12)); - vol = 0x7fff * mm[3] / 0xff; + int i, nmin, nmax; + nmin = 32; + nmax = 32; + for (i=0;i<32;i++){ + if (fm_sounds[i].id<fm_sounds[nmin].id) nmin = i; + if (fm_sounds[i].id>fm_sounds[nmax].id) nmax = i; + //if (fm_sounds[i].id<=0) break; + } + fm_sounds[nmin].id = nmax+1; + fm_sounds[nmin].note = mm[2]; + fm_sounds[nmin].velocity = mm[3]; } void fm_note_off(uint8_t *mm) { - vol = 0; + int i; + for (i=0; i<32; i++){ + if (fm_sounds[i].note == mm[2]){ + fm_sounds[i].velocity = mm[3]; + fm_sounds[i].id = -1; + } + } }