From 959947e7f84aa2af5821d31044e527554165d659 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 28 Feb 2019 20:56:23 +0100 Subject: NO-OP: whitespace (remove vi modelines) --- libs/plugins/reasonablesynth.lv2/lv2.c | 238 +++++---- libs/plugins/reasonablesynth.lv2/rsynth.c | 828 +++++++++++++++--------------- 2 files changed, 544 insertions(+), 522 deletions(-) (limited to 'libs/plugins/reasonablesynth.lv2') diff --git a/libs/plugins/reasonablesynth.lv2/lv2.c b/libs/plugins/reasonablesynth.lv2/lv2.c index bc3715ac4e..f8bbcdee2d 100644 --- a/libs/plugins/reasonablesynth.lv2/lv2.c +++ b/libs/plugins/reasonablesynth.lv2/lv2.c @@ -42,82 +42,82 @@ static uint32_t synth_sound (void *, uint32_t written, uint32_t nframes, fl #include "rsynth.c" typedef enum { - RSY_MIDIIN = 0, - RSY_OUTL, - RSY_OUTR + RSY_MIDIIN = 0, + RSY_OUTL, + RSY_OUTR } PortIndex; typedef struct { - const LV2_Atom_Sequence* midiin; - float* outL; - float* outR; + const LV2_Atom_Sequence* midiin; + float* outL; + float* outR; - LV2_URID_Map* map; - LV2_URID midi_MidiEvent; + LV2_URID_Map* map; + LV2_URID midi_MidiEvent; - double SampleRateD; - void *synth; - bool xmas; + double SampleRateD; + void *synth; + bool xmas; } RSynth; /* main LV2 */ static LV2_Handle -instantiate(const LV2_Descriptor* descriptor, - double rate, - const char* bundle_path, - const LV2_Feature* const* features) +instantiate (const LV2_Descriptor* descriptor, + double rate, + const char* bundle_path, + const LV2_Feature* const* features) { - (void) descriptor; /* unused variable */ - (void) bundle_path; /* unused variable */ - - if (rate < 8000) { - fprintf(stderr, "RSynth.lv2 error: unsupported sample-rate (must be > 8k)\n"); - return NULL; - } - RSynth* self = (RSynth*)calloc(1, sizeof(RSynth)); - if(!self) { - return NULL; - } - - self->SampleRateD = rate; - - int i; - for (i=0; features[i]; ++i) { - if (!strcmp(features[i]->URI, LV2_URID__map)) { - self->map = (LV2_URID_Map*)features[i]->data; - } - } - - if (!self->map) { - fprintf(stderr, "RSynth.lv2 error: Host does not support urid:map\n"); - free(self); - return NULL; - } - - self->midi_MidiEvent = self->map->map(self->map->handle, LV2_MIDI__MidiEvent); - - self->synth = synth_alloc(); - synth_init(self->synth, rate); + (void) descriptor; /* unused variable */ + (void) bundle_path; /* unused variable */ + + if (rate < 8000) { + fprintf(stderr, "RSynth.lv2 error: unsupported sample-rate (must be > 8k)\n"); + return NULL; + } + RSynth* self = (RSynth*)calloc(1, sizeof(RSynth)); + if(!self) { + return NULL; + } + + self->SampleRateD = rate; + + int i; + for (i=0; features[i]; ++i) { + if (!strcmp(features[i]->URI, LV2_URID__map)) { + self->map = (LV2_URID_Map*)features[i]->data; + } + } + + if (!self->map) { + fprintf(stderr, "RSynth.lv2 error: Host does not support urid:map\n"); + free(self); + return NULL; + } + + self->midi_MidiEvent = self->map->map(self->map->handle, LV2_MIDI__MidiEvent); + + self->synth = synth_alloc(); + synth_init(self->synth, rate); #ifndef PLATFORM_WINDOWS // easter egg is for sane platforms with native support for localtime_r only - struct tm date; - time_t now; - time(&now); - localtime_r(&now, &date); - if (getenv("ITSXMAS") || (date.tm_mon == 11 /*dec*/ && date.tm_mday == 25)) { - printf("reasonable synth.lv2 says: happy holidays!\n"); - self->xmas = true; - } + struct tm date; + time_t now; + time(&now); + localtime_r(&now, &date); + if (getenv("ITSXMAS") || (date.tm_mon == 11 /*dec*/ && date.tm_mday == 25)) { + printf("reasonable synth.lv2 says: happy holidays!\n"); + self->xmas = true; + } #endif - return (LV2_Handle)self; + return (LV2_Handle)self; } static void -connect_port(LV2_Handle handle, - uint32_t port, - void* data) +connect_port (LV2_Handle handle, + uint32_t port, + void* data) { RSynth* self = (RSynth*)handle; @@ -135,76 +135,76 @@ connect_port(LV2_Handle handle, } static void -run(LV2_Handle handle, uint32_t n_samples) +run (LV2_Handle handle, uint32_t n_samples) { - RSynth* self = (RSynth*)handle; - float* audio[2]; - - audio[0] = self->outL; - audio[1] = self->outR; - - uint32_t written = 0; - - /* Process incoming MIDI events */ - if (self->midiin) { - LV2_Atom_Event const* ev = (LV2_Atom_Event const*)((uintptr_t)((&(self->midiin)->body) + 1)); // lv2_atom_sequence_begin - while( // !lv2_atom_sequence_is_end - (const uint8_t*)ev < ((const uint8_t*) &(self->midiin)->body + (self->midiin)->atom.size) - ) - { - if (ev->body.type == self->midi_MidiEvent) { + RSynth* self = (RSynth*)handle; + float* audio[2]; + + audio[0] = self->outL; + audio[1] = self->outR; + + uint32_t written = 0; + + /* Process incoming MIDI events */ + if (self->midiin) { + LV2_Atom_Event const* ev = (LV2_Atom_Event const*)((uintptr_t)((&(self->midiin)->body) + 1)); // lv2_atom_sequence_begin + while( // !lv2_atom_sequence_is_end + (const uint8_t*)ev < ((const uint8_t*) &(self->midiin)->body + (self->midiin)->atom.size) + ) + { + if (ev->body.type == self->midi_MidiEvent) { #ifdef DEBUG_MIDI_EVENT // debug midi messages in synth -- not rt-safe(!) - printf ("%5d (%d):", ev->time.frames, ev->body.size); - for (uint8_t i = 0; i < ev->body.size; ++i) { - printf (" %02x", ((const uint8_t*)(ev+1))[i]); - } - printf ("\n"); + printf ("%5d (%d):", ev->time.frames, ev->body.size); + for (uint8_t i = 0; i < ev->body.size; ++i) { + printf (" %02x", ((const uint8_t*)(ev+1))[i]); + } + printf ("\n"); #endif - if (written + BUFFER_SIZE_SAMPLES < ev->time.frames - && ev->time.frames < n_samples) { - /* first synthesize sound up until the message timestamp */ - written = synth_sound(self->synth, written, ev->time.frames, audio); - } - /* send midi message to synth */ - if (self->xmas) { - synth_parse_xmas(self->synth, (const uint8_t*)(ev+1), ev->body.size); - } else { - synth_parse_midi(self->synth, (const uint8_t*)(ev+1), ev->body.size); - } - } - ev = (LV2_Atom_Event const*) // lv2_atom_sequence_next() - ((uintptr_t)((const uint8_t*)ev + sizeof(LV2_Atom_Event) + ((ev->body.size + 7) & ~7))); - } - } - - /* synthesize [remaining] sound */ - synth_sound(self->synth, written, n_samples, audio); + if (written + BUFFER_SIZE_SAMPLES < ev->time.frames + && ev->time.frames < n_samples) { + /* first synthesize sound up until the message timestamp */ + written = synth_sound(self->synth, written, ev->time.frames, audio); + } + /* send midi message to synth */ + if (self->xmas) { + synth_parse_xmas(self->synth, (const uint8_t*)(ev+1), ev->body.size); + } else { + synth_parse_midi(self->synth, (const uint8_t*)(ev+1), ev->body.size); + } + } + ev = (LV2_Atom_Event const*) // lv2_atom_sequence_next() + ((uintptr_t)((const uint8_t*)ev + sizeof(LV2_Atom_Event) + ((ev->body.size + 7) & ~7))); + } + } + + /* synthesize [remaining] sound */ + synth_sound(self->synth, written, n_samples, audio); } static void cleanup(LV2_Handle handle) { - RSynth* self = (RSynth*)handle; - synth_free(self->synth); - free(handle); + RSynth* self = (RSynth*)handle; + synth_free(self->synth); + free(handle); } static const void* extension_data(const char* uri) { - (void) uri; /* unused variable */ - return NULL; + (void) uri; /* unused variable */ + return NULL; } static const LV2_Descriptor descriptor = { - RSY_URI, - instantiate, - connect_port, - NULL, - run, - NULL, - cleanup, - extension_data + RSY_URI, + instantiate, + connect_port, + NULL, + run, + NULL, + cleanup, + extension_data }; #if defined(COMPILER_MSVC) @@ -215,12 +215,10 @@ __attribute__ ((visibility ("default"))) const LV2_Descriptor* lv2_descriptor(uint32_t idx) { - switch (idx) { - case 0: - return &descriptor; - default: - return NULL; - } + switch (idx) { + case 0: + return &descriptor; + default: + return NULL; + } } - -/* vi:set ts=8 sts=2 sw=2 et: */ diff --git a/libs/plugins/reasonablesynth.lv2/rsynth.c b/libs/plugins/reasonablesynth.lv2/rsynth.c index 5848bee14c..cee4042b94 100644 --- a/libs/plugins/reasonablesynth.lv2/rsynth.c +++ b/libs/plugins/reasonablesynth.lv2/rsynth.c @@ -1,6 +1,6 @@ -/* reasonable simple synth +/* reasonably simple synth * - * Copyright (C) 2013 Robin Gareus + * Copyright (C) 2013, 2019 Robin Gareus * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,65 +42,67 @@ /* internal MIDI event abstraction */ enum RMIDI_EV_TYPE { - INVALID=0, - NOTE_ON, - NOTE_OFF, - PROGRAM_CHANGE, - CONTROL_CHANGE, + INVALID=0, + NOTE_ON, + NOTE_OFF, + PROGRAM_CHANGE, + CONTROL_CHANGE, }; struct rmidi_event_t { - enum RMIDI_EV_TYPE type; - uint8_t channel; /**< the MIDI channel number 0-15 */ - union { - struct { - uint8_t note; - uint8_t velocity; - } tone; - struct { - uint8_t param; - uint8_t value; - } control; - } d; + enum RMIDI_EV_TYPE type; + uint8_t channel; /**< the MIDI channel number 0-15 */ + union { + struct { + uint8_t note; + uint8_t velocity; + } tone; + struct { + uint8_t param; + uint8_t value; + } control; + } d; }; typedef struct { - uint32_t tme[3]; // attack, decay, release times [settings:ms || internal:samples] - float vol[2]; // attack, sustain volume [0..1] - uint32_t off[3]; // internal use (added attack,decay,release times) + uint32_t tme[3]; // attack, decay, release times [settings:ms || internal:samples] + float vol[2]; // attack, sustain volume [0..1] + uint32_t off[3]; // internal use (added attack,decay,release times) } ADSRcfg; typedef struct _RSSynthChannel { - uint32_t keycomp; - uint32_t adsr_cnt[128]; - float adsr_amp[128]; - float phase[128]; // various use, zero'ed on note-on - int8_t miditable[128]; // internal, note-on/off velocity - int8_t midimsgs [128]; // internal, note-off + on in same cycle, sustained-off - int8_t sustain; // sustain pedal pressed - ADSRcfg adsr; - void (*synthesize) (struct _RSSynthChannel* sc, - const uint8_t note, const float vol, const float pc, - const size_t n_samples, float* left, float* right); + uint32_t keycomp; + uint32_t adsr_cnt[128]; + float adsr_amp[128]; + float phase[128]; // various use, zero'ed on note-on + int8_t miditable[128]; // internal, note-on/off velocity + int8_t midimsgs [128]; // internal, note-off + on in same cycle, sustained-off + int8_t sustain; // sustain pedal pressed + ADSRcfg adsr; + void (*synthesize) (struct _RSSynthChannel* sc, + const uint8_t note, const float vol, const float pc, + const size_t n_samples, float* left, float* right); } RSSynthChannel; typedef void (*SynthFunction) (RSSynthChannel* sc, - const uint8_t note, const float vol, const float pc, - const size_t n_samples, float* left, float* right); + const uint8_t note, + const float vol, + const float pc, + const size_t n_samples, + float* left, float* right); typedef struct { - uint32_t boffset; - float buf [2][BUFFER_SIZE_SAMPLES]; - RSSynthChannel sc[16]; - float freqs[128]; - float kcgain; - float kcfilt; - double rate; - uint32_t xmas_on; - uint32_t xmas_off; + uint32_t boffset; + float buf [2][BUFFER_SIZE_SAMPLES]; + RSSynthChannel sc[16]; + float freqs[128]; + float kcgain; + float kcfilt; + double rate; + uint32_t xmas_on; + uint32_t xmas_off; } RSSynthesizer; - /* initialize ADSR values * * @param rate sample-rate @@ -110,286 +112,298 @@ typedef struct { * @param avol attack gain [0..1] * @param svol sustain volume level [0..1] */ -static void init_adsr(ADSRcfg *adsr, const double rate, - const uint32_t a, const uint32_t d, const uint32_t r, - const float avol, const float svol) { - - adsr->vol[0] = avol; - adsr->vol[1] = svol; - adsr->tme[0] = a * rate / 1000.0; - adsr->tme[1] = d * rate / 1000.0; - adsr->tme[2] = r * rate / 1000.0; - - assert(adsr->tme[0] > 32); - assert(adsr->tme[1] > 32); - assert(adsr->tme[2] > 32); - assert(adsr->vol[0] >=0 && adsr->vol[1] <= 1.0); - assert(adsr->vol[1] >=0 && adsr->vol[1] <= 1.0); - - adsr->off[0] = adsr->tme[0]; - adsr->off[1] = adsr->tme[1] + adsr->off[0]; - adsr->off[2] = adsr->tme[2] + adsr->off[1]; +static void +init_adsr (ADSRcfg *adsr, const double rate, + const uint32_t a, const uint32_t d, const uint32_t r, + const float avol, const float svol) +{ + adsr->vol[0] = avol; + adsr->vol[1] = svol; + adsr->tme[0] = a * rate / 1000.0; + adsr->tme[1] = d * rate / 1000.0; + adsr->tme[2] = r * rate / 1000.0; + + assert(adsr->tme[0] > 32); + assert(adsr->tme[1] > 32); + assert(adsr->tme[2] > 32); + assert(adsr->vol[0] >=0 && adsr->vol[1] <= 1.0); + assert(adsr->vol[1] >=0 && adsr->vol[1] <= 1.0); + + adsr->off[0] = adsr->tme[0]; + adsr->off[1] = adsr->tme[1] + adsr->off[0]; + adsr->off[2] = adsr->tme[2] + adsr->off[1]; } /* calculate per-sample, per-key envelope */ -static inline float adsr_env(RSSynthChannel *sc, const uint8_t note) { - - if (sc->adsr_cnt[note] < sc->adsr.off[0]) { - // attack - const uint32_t p = ++sc->adsr_cnt[note]; - if (p == sc->adsr.tme[0]) { - sc->adsr_amp[note] = sc->adsr.vol[0]; - return sc->adsr.vol[0]; - } else { - const float d = sc->adsr.vol[0] - sc->adsr_amp[note]; - return sc->adsr_amp[note] + (p / (float) sc->adsr.tme[0]) * d; - } - } - else if (sc->adsr_cnt[note] < sc->adsr.off[1]) { - // decay - const uint32_t p = ++sc->adsr_cnt[note] - sc->adsr.off[0]; - if (p == sc->adsr.tme[1]) { - sc->adsr_amp[note] = sc->adsr.vol[1]; - return sc->adsr.vol[1]; - } else { - const float d = sc->adsr.vol[1] - sc->adsr_amp[note]; - return sc->adsr_amp[note] + (p / (float) sc->adsr.tme[1]) * d; - } - } - else if (sc->adsr_cnt[note] == sc->adsr.off[1]) { - // sustain - return sc->adsr.vol[1]; - } - else if (sc->adsr_cnt[note] < sc->adsr.off[2]) { - // release - const uint32_t p = ++sc->adsr_cnt[note] - sc->adsr.off[1]; - if (p == sc->adsr.tme[2]) { - sc->adsr_amp[note] = 0; - return 0; - } else { - const float d = 0 - sc->adsr_amp[note]; - return sc->adsr_amp[note] + (p / (float) sc->adsr.tme[2]) * d; - } - } - else { - sc->adsr_cnt[note] = 0; - return 0; - } +static inline float +adsr_env(RSSynthChannel *sc, const uint8_t note) +{ + if (sc->adsr_cnt[note] < sc->adsr.off[0]) { + // attack + const uint32_t p = ++sc->adsr_cnt[note]; + if (p == sc->adsr.tme[0]) { + sc->adsr_amp[note] = sc->adsr.vol[0]; + return sc->adsr.vol[0]; + } else { + const float d = sc->adsr.vol[0] - sc->adsr_amp[note]; + return sc->adsr_amp[note] + (p / (float) sc->adsr.tme[0]) * d; + } + } + else if (sc->adsr_cnt[note] < sc->adsr.off[1]) { + // decay + const uint32_t p = ++sc->adsr_cnt[note] - sc->adsr.off[0]; + if (p == sc->adsr.tme[1]) { + sc->adsr_amp[note] = sc->adsr.vol[1]; + return sc->adsr.vol[1]; + } else { + const float d = sc->adsr.vol[1] - sc->adsr_amp[note]; + return sc->adsr_amp[note] + (p / (float) sc->adsr.tme[1]) * d; + } + } + else if (sc->adsr_cnt[note] == sc->adsr.off[1]) { + // sustain + return sc->adsr.vol[1]; + } + else if (sc->adsr_cnt[note] < sc->adsr.off[2]) { + // release + const uint32_t p = ++sc->adsr_cnt[note] - sc->adsr.off[1]; + if (p == sc->adsr.tme[2]) { + sc->adsr_amp[note] = 0; + return 0; + } else { + const float d = 0 - sc->adsr_amp[note]; + return sc->adsr_amp[note] + (p / (float) sc->adsr.tme[2]) * d; + } + } + else { + sc->adsr_cnt[note] = 0; + return 0; + } } - /*****************************************************************************/ /* piano like sound w/slight stereo phase */ -static void synthesize_sineP (RSSynthChannel* sc, - const uint8_t note, const float vol, const float fq, - const size_t n_samples, float* left, float* right) { - - size_t i; - float phase = sc->phase[note]; - - for (i=0; i < n_samples; ++i) { - float env = adsr_env(sc, note); - if (sc->adsr_cnt[note] == 0) break; - const float amp = vol * env; - if (amp > 1e-10) { - left[i] += amp * sinf(2.0 * M_PI * phase); - left[i] += .300 * amp * sinf(2.0 * M_PI * phase * 2.0); - left[i] += .150 * amp * sinf(2.0 * M_PI * phase * 3.0); - left[i] += .080 * amp * sinf(2.0 * M_PI * phase * 4.0); - //left[i] -= .007 * amp * sinf(2.0 * M_PI * phase * 5.0); - //left[i] += .010 * amp * sinf(2.0 * M_PI * phase * 6.0); - left[i] += .020 * amp * sinf(2.0 * M_PI * phase * 7.0); - phase += fq; - right[i] += amp * sinf(2.0 * M_PI * phase); - right[i] += .300 * amp * sinf(2.0 * M_PI * phase * 2.0); - right[i] += .150 * amp * sinf(2.0 * M_PI * phase * 3.0); - right[i] -= .080 * amp * sinf(2.0 * M_PI * phase * 4.0); - //right[i] += .007 * amp * sinf(2.0 * M_PI * phase * 5.0); - //right[i] += .010 * amp * sinf(2.0 * M_PI * phase * 6.0); - right[i] -= .020 * amp * sinf(2.0 * M_PI * phase * 7.0); - } else { - phase += fq; - } - if (phase > 1.0) phase -= 2.0; - } - sc->phase[note] = phase; +static void +synthesize_sineP (RSSynthChannel* sc, + const uint8_t note, const float vol, const float fq, + const size_t n_samples, float* left, float* right) +{ + size_t i; + float phase = sc->phase[note]; + + for (i=0; i < n_samples; ++i) { + float env = adsr_env(sc, note); + if (sc->adsr_cnt[note] == 0) break; + const float amp = vol * env; + if (amp > 1e-10) { + left[i] += amp * sinf(2.0 * M_PI * phase); + left[i] += .300 * amp * sinf(2.0 * M_PI * phase * 2.0); + left[i] += .150 * amp * sinf(2.0 * M_PI * phase * 3.0); + left[i] += .080 * amp * sinf(2.0 * M_PI * phase * 4.0); + //left[i] -= .007 * amp * sinf(2.0 * M_PI * phase * 5.0); + //left[i] += .010 * amp * sinf(2.0 * M_PI * phase * 6.0); + left[i] += .020 * amp * sinf(2.0 * M_PI * phase * 7.0); + phase += fq; + right[i] += amp * sinf(2.0 * M_PI * phase); + right[i] += .300 * amp * sinf(2.0 * M_PI * phase * 2.0); + right[i] += .150 * amp * sinf(2.0 * M_PI * phase * 3.0); + right[i] -= .080 * amp * sinf(2.0 * M_PI * phase * 4.0); + //right[i] += .007 * amp * sinf(2.0 * M_PI * phase * 5.0); + //right[i] += .010 * amp * sinf(2.0 * M_PI * phase * 6.0); + right[i] -= .020 * amp * sinf(2.0 * M_PI * phase * 7.0); + } else { + phase += fq; + } + if (phase > 1.0) phase -= 2.0; + } + sc->phase[note] = phase; } -static const ADSRcfg piano_adsr = {{ 5, 800, 100}, { 1.0, 0.0}, {0,0,0}}; +static const ADSRcfg piano_adsr = {{ 5, 800, 100}, { 1.0, 0.0}, {0, 0, 0}}; /*****************************************************************************/ /* process note - move through ADSR states, count active keys,.. */ -static void process_key (void *synth, - const uint8_t chn, const uint8_t note, - const size_t n_samples, float *left, float *right) +static void +process_key (void *synth, + const uint8_t chn, const uint8_t note, + const size_t n_samples, + float *left, float *right) { - RSSynthesizer* rs = (RSSynthesizer*)synth; - RSSynthChannel* sc = &rs->sc[chn]; - const int8_t vel = sc->miditable[note]; - const int8_t msg = sc->midimsgs[note]; - const float vol = /* master_volume */ 0.1f * abs(vel) / 127.f; - const float phase = sc->phase[note]; - const int8_t sus = sc->sustain; - sc->midimsgs[note] &= ~3; - - if (phase == -10 && vel > 0) { - // new note on - sc->midimsgs[note] &= ~4; - assert(sc->adsr_cnt[note] == 0); - sc->adsr_amp[note] = 0; - sc->adsr_cnt[note] = 0; - sc->phase[note] = 0; - sc->keycomp++; - //printf("[On] Now %d keys active on chn %d\n", sc->keycomp, chn); - } - else if (phase >= -1.0 && phase <= 1.0 && vel > 0) { - // sustain note or re-start note while adsr in progress: - if (sc->adsr_cnt[note] > sc->adsr.off[1] || msg == 3 || msg == 5 || msg == 7) { - sc->midimsgs[note] &= ~4; - // x-fade to attack - sc->adsr_amp[note] = adsr_env(sc, note); - sc->adsr_cnt[note] = 0; - } - } - else if (phase >= -1.0 && phase <= 1.0 && vel < 0) { - sc->midimsgs[note] |= 4; - // note off - if (sc->adsr_cnt[note] <= sc->adsr.off[1] && !sus) { - if (sc->adsr_cnt[note] != sc->adsr.off[1]) { - // x-fade to release - sc->adsr_amp[note] = adsr_env(sc, note); - } - sc->adsr_cnt[note] = sc->adsr.off[1] + 1; - } - else if (sus && sc->adsr_cnt[note] == sc->adsr.off[1]) { - sc->adsr_cnt[note] = sc->adsr.off[1] + 1; - } - } - else { - //printf("FORCE NOTE OFF: %d %d\n", vel, sus); - /* note-on + off in same cycle */ - sc->miditable[note] = 0; - sc->adsr_cnt[note] = 0; - sc->phase[note] = -10; - return; - } - //printf("NOTE: %d (%d %d %d)\n", sc->adsr_cnt[note], sc->adsr.off[0], sc->adsr.off[1], sc->adsr.off[2]); - - // synthesize actual sound - sc->synthesize(sc, note, vol, rs->freqs[note], n_samples, left, right); - - if (sc->adsr_cnt[note] == 0) { - //printf("Note %d,%d released\n", chn, note); - sc->midimsgs[note] = 0; - sc->miditable[note] = 0; - sc->adsr_amp[note] = 0; - sc->phase[note] = -10; - sc->keycomp--; - //printf("[off] Now %d keys active on chn %d\n", sc->keycomp, chn); - } + RSSynthesizer* rs = (RSSynthesizer*)synth; + RSSynthChannel* sc = &rs->sc[chn]; + const int8_t vel = sc->miditable[note]; + const int8_t msg = sc->midimsgs[note]; + const float vol = /* master_volume */ 0.1f * abs(vel) / 127.f; + const float phase = sc->phase[note]; + const int8_t sus = sc->sustain; + sc->midimsgs[note] &= ~3; + + if (phase == -10 && vel > 0) { + // new note on + sc->midimsgs[note] &= ~4; + assert(sc->adsr_cnt[note] == 0); + sc->adsr_amp[note] = 0; + sc->adsr_cnt[note] = 0; + sc->phase[note] = 0; + sc->keycomp++; + //printf("[On] Now %d keys active on chn %d\n", sc->keycomp, chn); + } + else if (phase >= -1.0 && phase <= 1.0 && vel > 0) { + // sustain note or re-start note while adsr in progress: + if (sc->adsr_cnt[note] > sc->adsr.off[1] || msg == 3 || msg == 5 || msg == 7) { + sc->midimsgs[note] &= ~4; + // x-fade to attack + sc->adsr_amp[note] = adsr_env(sc, note); + sc->adsr_cnt[note] = 0; + } + } + else if (phase >= -1.0 && phase <= 1.0 && vel < 0) { + sc->midimsgs[note] |= 4; + // note off + if (sc->adsr_cnt[note] <= sc->adsr.off[1] && !sus) { + if (sc->adsr_cnt[note] != sc->adsr.off[1]) { + // x-fade to release + sc->adsr_amp[note] = adsr_env(sc, note); + } + sc->adsr_cnt[note] = sc->adsr.off[1] + 1; + } + else if (sus && sc->adsr_cnt[note] == sc->adsr.off[1]) { + sc->adsr_cnt[note] = sc->adsr.off[1] + 1; + } + } + else { + //printf("FORCE NOTE OFF: %d %d\n", vel, sus); + /* note-on + off in same cycle */ + sc->miditable[note] = 0; + sc->adsr_cnt[note] = 0; + sc->phase[note] = -10; + return; + } + //printf("NOTE: %d (%d %d %d)\n", sc->adsr_cnt[note], sc->adsr.off[0], sc->adsr.off[1], sc->adsr.off[2]); + + // synthesize actual sound + sc->synthesize(sc, note, vol, rs->freqs[note], n_samples, left, right); + + if (sc->adsr_cnt[note] == 0) { + //printf("Note %d,%d released\n", chn, note); + sc->midimsgs[note] = 0; + sc->miditable[note] = 0; + sc->adsr_amp[note] = 0; + sc->phase[note] = -10; + sc->keycomp--; + //printf("[off] Now %d keys active on chn %d\n", sc->keycomp, chn); + } } /* synthesize a BUFFER_SIZE_SAMPLES's of audio-data */ -static void synth_fragment (void *synth, const size_t n_samples, float *left, float *right) { - RSSynthesizer* rs = (RSSynthesizer*)synth; - memset (left, 0, n_samples * sizeof(float)); - memset (right, 0, n_samples * sizeof(float)); - uint8_t keycomp = 0; - int c,k; - size_t i; - - for (c=0; c < 16; ++c) { - for (k=0; k < 128; ++k) { - if (rs->sc[c].miditable[k] == 0) continue; - process_key(synth, c, k, n_samples, left, right); - } - keycomp += rs->sc[c].keycomp; - } +static void +synth_fragment (void *synth, const size_t n_samples, float *left, float *right) +{ + RSSynthesizer* rs = (RSSynthesizer*)synth; + memset (left, 0, n_samples * sizeof(float)); + memset (right, 0, n_samples * sizeof(float)); + uint8_t keycomp = 0; + int c,k; + size_t i; + + for (c=0; c < 16; ++c) { + for (k=0; k < 128; ++k) { + if (rs->sc[c].miditable[k] == 0) continue; + process_key(synth, c, k, n_samples, left, right); + } + keycomp += rs->sc[c].keycomp; + } #if 1 // key-compression - float kctgt = 8.0 / (float)(keycomp + 7.0); - if (kctgt < .5) kctgt = .5; - if (kctgt > 1.0) kctgt = 1.0; - const float _w = rs->kcfilt; - for (i=0; i < n_samples; ++i) { - rs->kcgain += _w * (kctgt - rs->kcgain); - left[i] *= rs->kcgain; - right[i] *= rs->kcgain; - } - rs->kcgain += 1e-12; + float kctgt = 8.0 / (float)(keycomp + 7.0); + if (kctgt < .5) kctgt = .5; + if (kctgt > 1.0) kctgt = 1.0; + const float _w = rs->kcfilt; + for (i=0; i < n_samples; ++i) { + rs->kcgain += _w * (kctgt - rs->kcgain); + left[i] *= rs->kcgain; + right[i] *= rs->kcgain; + } + rs->kcgain += 1e-12; #endif } -static void synth_reset_channel(RSSynthChannel* sc) { - int k; - for (k=0; k < 128; ++k) { - sc->adsr_cnt[k] = 0; - sc->adsr_amp[k] = 0; - sc->phase[k] = -10; - sc->miditable[k] = 0; - sc->midimsgs[k] = 0; - } - sc->keycomp = 0; +static void +synth_reset_channel(RSSynthChannel* sc) +{ + for (int k = 0; k < 128; ++k) { + sc->adsr_cnt[k] = 0; + sc->adsr_amp[k] = 0; + sc->phase[k] = -10; + sc->miditable[k] = 0; + sc->midimsgs[k] = 0; + } + sc->keycomp = 0; } -static void synth_reset(void *synth) { - RSSynthesizer* rs = (RSSynthesizer*)synth; - int c; - for (c=0; c < 16; ++c) { - synth_reset_channel(&(rs->sc[c])); - } - rs->kcgain = 0; +static void +synth_reset(void *synth) +{ + RSSynthesizer* rs = (RSSynthesizer*)synth; + int c; + for (c=0; c < 16; ++c) { + synth_reset_channel(&(rs->sc[c])); + } + rs->kcgain = 0; } -static void synth_load(RSSynthChannel *sc, const double rate, - SynthFunction synthesize, - ADSRcfg const * const adsr) { - synth_reset_channel(sc); - init_adsr(&sc->adsr, rate, - adsr->tme[0], adsr->tme[1], adsr->tme[2], - adsr->vol[0], adsr->vol[1]); - sc->synthesize = synthesize; +static void +synth_load (RSSynthChannel *sc, const double rate, + SynthFunction synthesize, + ADSRcfg const * const adsr) +{ + synth_reset_channel(sc); + init_adsr(&sc->adsr, rate, + adsr->tme[0], adsr->tme[1], adsr->tme[2], + adsr->vol[0], adsr->vol[1]); + sc->synthesize = synthesize; } - /** * internal abstraction of MIDI data handling */ -static void synth_process_midi_event(void *synth, struct rmidi_event_t *ev) { - RSSynthesizer* rs = (RSSynthesizer*)synth; - switch(ev->type) { - case NOTE_ON: - rs->sc[ev->channel].midimsgs[ev->d.tone.note] |= 1; - if (rs->sc[ev->channel].miditable[ev->d.tone.note] <= 0) - rs->sc[ev->channel].miditable[ev->d.tone.note] = ev->d.tone.velocity; - break; - case NOTE_OFF: - rs->sc[ev->channel].midimsgs[ev->d.tone.note] |= 2; - if (rs->sc[ev->channel].miditable[ev->d.tone.note] > 0) - rs->sc[ev->channel].miditable[ev->d.tone.note] *= -1.0; - break; - case PROGRAM_CHANGE: - break; - case CONTROL_CHANGE: - if (ev->d.control.param == 0x00 || ev->d.control.param == 0x20) { - /* 0x00 and 0x20 are used for BANK select */ - } else if (ev->d.control.param == 64) { - /* damper pedal*/ - rs->sc[ev->channel].sustain = ev->d.control.value < 64 ? 0: 1; - } else if (ev->d.control.param == 121) { - /* reset all controllers */ - } else if (ev->d.control.param == 120 || ev->d.control.param == 123) { - /* Midi panic: 120: all sound off, 123: all notes off*/ - synth_reset_channel(&(rs->sc[ev->channel])); - } else if (ev->d.control.param >= 120) { - /* params 122-127 are reserved - skip them. */ - } - break; - default: - break; - } +static void +synth_process_midi_event(void *synth, struct rmidi_event_t *ev) +{ + RSSynthesizer* rs = (RSSynthesizer*)synth; + switch(ev->type) { + case NOTE_ON: + rs->sc[ev->channel].midimsgs[ev->d.tone.note] |= 1; + if (rs->sc[ev->channel].miditable[ev->d.tone.note] <= 0) + rs->sc[ev->channel].miditable[ev->d.tone.note] = ev->d.tone.velocity; + break; + case NOTE_OFF: + rs->sc[ev->channel].midimsgs[ev->d.tone.note] |= 2; + if (rs->sc[ev->channel].miditable[ev->d.tone.note] > 0) + rs->sc[ev->channel].miditable[ev->d.tone.note] *= -1.0; + break; + case PROGRAM_CHANGE: + break; + case CONTROL_CHANGE: + if (ev->d.control.param == 0x00 || ev->d.control.param == 0x20) { + /* 0x00 and 0x20 are used for BANK select */ + } else if (ev->d.control.param == 64) { + /* damper pedal*/ + rs->sc[ev->channel].sustain = ev->d.control.value < 64 ? 0: 1; + } else if (ev->d.control.param == 121) { + /* reset all controllers */ + } else if (ev->d.control.param == 120 || ev->d.control.param == 123) { + /* Midi panic: 120: all sound off, 123: all notes off*/ + synth_reset_channel(&(rs->sc[ev->channel])); + } else if (ev->d.control.param >= 120) { + /* params 122-127 are reserved - skip them. */ + } + break; + default: + break; + } } /****************************************************************************** @@ -406,27 +420,29 @@ static void synth_process_midi_event(void *synth, struct rmidi_event_t *ev) { * @param out pointer to stereo output buffers * @return end of buffer (written + nframes) */ -static uint32_t synth_sound (void *synth, uint32_t written, const uint32_t nframes, float **out) { - RSSynthesizer* rs = (RSSynthesizer*)synth; +static uint32_t +synth_sound (void *synth, uint32_t written, const uint32_t nframes, float **out) +{ + RSSynthesizer* rs = (RSSynthesizer*)synth; - while (written < nframes) { - uint32_t nremain = nframes - written; + while (written < nframes) { + uint32_t nremain = nframes - written; - if (rs->boffset >= BUFFER_SIZE_SAMPLES) { - const uint32_t tosynth = MIN(BUFFER_SIZE_SAMPLES, nremain); - rs->boffset = BUFFER_SIZE_SAMPLES - tosynth; - synth_fragment(rs, tosynth, &(rs->buf[0][rs->boffset]), &(rs->buf[1][rs->boffset])); - } + if (rs->boffset >= BUFFER_SIZE_SAMPLES) { + const uint32_t tosynth = MIN(BUFFER_SIZE_SAMPLES, nremain); + rs->boffset = BUFFER_SIZE_SAMPLES - tosynth; + synth_fragment(rs, tosynth, &(rs->buf[0][rs->boffset]), &(rs->buf[1][rs->boffset])); + } - uint32_t nread = MIN(nremain, (BUFFER_SIZE_SAMPLES - rs->boffset)); + uint32_t nread = MIN(nremain, (BUFFER_SIZE_SAMPLES - rs->boffset)); - memcpy(&out[0][written], &rs->buf[0][rs->boffset], nread*sizeof(float)); - memcpy(&out[1][written], &rs->buf[1][rs->boffset], nread*sizeof(float)); + memcpy(&out[0][written], &rs->buf[0][rs->boffset], nread*sizeof(float)); + memcpy(&out[1][written], &rs->buf[1][rs->boffset], nread*sizeof(float)); - written += nread; - rs->boffset += nread; - } - return written; + written += nread; + rs->boffset += nread; + } + return written; } /** @@ -436,80 +452,84 @@ static uint32_t synth_sound (void *synth, uint32_t written, const uint32_t nfram * @param data 8bit midi message * @param size number of bytes in the midi-message */ -static void synth_parse_midi(void *synth, const uint8_t *data, const size_t size) { - if (size < 2 || size > 3) return; - // All messages need to be 3 bytes; except program-changes: 2bytes. - if (size == 2 && (data[0] & 0xf0) != 0xC0) return; - - struct rmidi_event_t ev; - - ev.channel = data[0]&0x0f; - switch (data[0] & 0xf0) { - case 0x80: - ev.type=NOTE_OFF; - ev.d.tone.note=data[1]&0x7f; - ev.d.tone.velocity=data[2]&0x7f; - break; - case 0x90: - ev.type=NOTE_ON; - ev.d.tone.note=data[1]&0x7f; - ev.d.tone.velocity=data[2]&0x7f; - if (ev.d.tone.velocity == 0) { - ev.type=NOTE_OFF; - } - break; - case 0xB0: - ev.type=CONTROL_CHANGE; - ev.d.control.param=data[1]&0x7f; - ev.d.control.value=data[2]&0x7f; - break; - case 0xC0: - ev.type=PROGRAM_CHANGE; - ev.d.control.value=data[1]&0x7f; - break; - default: - return; - } - synth_process_midi_event(synth, &ev); +static void +synth_parse_midi (void *synth, const uint8_t *data, const size_t size) +{ + if (size < 2 || size > 3) return; + // All messages need to be 3 bytes; except program-changes: 2bytes. + if (size == 2 && (data[0] & 0xf0) != 0xC0) return; + + struct rmidi_event_t ev; + + ev.channel = data[0]&0x0f; + switch (data[0] & 0xf0) { + case 0x80: + ev.type=NOTE_OFF; + ev.d.tone.note=data[1]&0x7f; + ev.d.tone.velocity=data[2]&0x7f; + break; + case 0x90: + ev.type=NOTE_ON; + ev.d.tone.note=data[1]&0x7f; + ev.d.tone.velocity=data[2]&0x7f; + if (ev.d.tone.velocity == 0) { + ev.type=NOTE_OFF; + } + break; + case 0xB0: + ev.type=CONTROL_CHANGE; + ev.d.control.param=data[1]&0x7f; + ev.d.control.value=data[2]&0x7f; + break; + case 0xC0: + ev.type=PROGRAM_CHANGE; + ev.d.control.value=data[1]&0x7f; + break; + default: + return; + } + synth_process_midi_event(synth, &ev); } static const uint8_t jingle[] = { 71 ,71 ,71 ,71 ,71 ,71 ,71 ,74 ,67 ,69 ,71 ,72 ,72 ,72 ,72 ,72 ,71 ,71 ,71 ,71 ,71 ,69 ,69 ,71 ,69 ,74 ,71 ,71 ,71 ,71 ,71 ,71 ,71 ,74 ,67 ,69 ,71 ,72 ,72 ,72 ,72 ,72 ,71 ,71 ,71 ,71 ,74 ,74 ,72 ,69 ,67 ,62 ,62 ,71 ,69 ,67 ,62 ,62 ,62 ,62 ,71 ,69 ,67 ,64 ,64 ,64 ,72 ,71 ,69 ,66 ,74 ,76 ,74 ,72 ,69 ,71 ,62 ,62 ,71 ,69 ,67 ,62 ,62 ,62 ,62 ,71 ,69 ,67 ,64 ,64 ,64 ,72 ,71 ,69 ,74 ,74 ,74 ,74 ,76 ,74 ,72 ,69 ,67 ,74 ,71 ,71 ,71 ,71 ,71 ,71 ,71 ,74 ,67 ,69 ,71 ,72 ,72 ,72 ,72 ,72 ,71 ,71 ,71 ,71 ,71 ,69 ,69 ,71 ,69 ,74 ,71 ,71 ,71 ,71 ,71 ,71 ,71 ,74 ,67 ,69 ,71 ,72 ,72 ,72 ,72 ,72 ,71 ,71 ,71 ,71 ,74 ,74 ,72 ,69 ,67 }; -static void synth_parse_xmas(void *synth, const uint8_t *data, const size_t size) { - RSSynthesizer* rs = (RSSynthesizer*)synth; - if (size < 2 || size > 3) return; - // All messages need to be 3 bytes; except program-changes: 2bytes. - if (size == 2 && (data[0] & 0xf0) != 0xC0) return; - - struct rmidi_event_t ev; - - ev.channel = data[0]&0x0f; - switch (data[0] & 0xf0) { - case 0x80: - ev.type=NOTE_OFF; - ev.d.tone.note=jingle[rs->xmas_off++]; - ev.d.tone.velocity=data[2]&0x7f; - if (rs->xmas_off >= sizeof(jingle)) rs->xmas_off = 0; - break; - case 0x90: - ev.type=NOTE_ON; - ev.d.tone.note=jingle[rs->xmas_on++]; - ev.d.tone.velocity=data[2]&0x7f; - if (rs->xmas_on >= sizeof(jingle)) rs->xmas_on = 0; - break; - case 0xB0: - ev.type=CONTROL_CHANGE; - ev.d.control.param=data[1]&0x7f; - ev.d.control.value=data[2]&0x7f; - break; - case 0xC0: - ev.type=PROGRAM_CHANGE; - ev.d.control.value=data[1]&0x7f; - break; - default: - return; - } - synth_process_midi_event(synth, &ev); +static void +synth_parse_xmas(void *synth, const uint8_t *data, const size_t size) +{ + RSSynthesizer* rs = (RSSynthesizer*)synth; + if (size < 2 || size > 3) return; + // All messages need to be 3 bytes; except program-changes: 2bytes. + if (size == 2 && (data[0] & 0xf0) != 0xC0) return; + + struct rmidi_event_t ev; + + ev.channel = data[0]&0x0f; + switch (data[0] & 0xf0) { + case 0x80: + ev.type=NOTE_OFF; + ev.d.tone.note=jingle[rs->xmas_off++]; + ev.d.tone.velocity=data[2]&0x7f; + if (rs->xmas_off >= sizeof(jingle)) rs->xmas_off = 0; + break; + case 0x90: + ev.type=NOTE_ON; + ev.d.tone.note=jingle[rs->xmas_on++]; + ev.d.tone.velocity=data[2]&0x7f; + if (rs->xmas_on >= sizeof(jingle)) rs->xmas_on = 0; + break; + case 0xB0: + ev.type=CONTROL_CHANGE; + ev.d.control.param=data[1]&0x7f; + ev.d.control.value=data[2]&0x7f; + break; + case 0xC0: + ev.type=PROGRAM_CHANGE; + ev.d.control.value=data[1]&0x7f; + break; + default: + return; + } + synth_process_midi_event(synth, &ev); } /** * initialize the synth @@ -519,24 +539,25 @@ static void synth_parse_xmas(void *synth, const uint8_t *data, const size_t size * @param synth synth-handle * @param rate sample-rate */ -static void synth_init(void *synth, double rate) { - RSSynthesizer* rs = (RSSynthesizer*)synth; - rs->rate = rate; - rs->boffset = BUFFER_SIZE_SAMPLES; - const float tuning = 440; - int c,k; - for (k=0; k < 128; k++) { - rs->freqs[k] = (tuning / 32.0f) * powf(2, (k - 9.0) / 12.0) / rate; - assert(rs->freqs[k] < M_PI/2); // otherwise spatialization may phase out.. - } - rs->kcfilt = 12.0 / rate; - synth_reset(synth); - - for (c=0; c < 16; c++) { - synth_load(&rs->sc[c], rate, &synthesize_sineP, &piano_adsr); - } - rs->xmas_on = 0; - rs->xmas_off = 0; +static void +synth_init(void* synth, double rate) { + RSSynthesizer* rs = (RSSynthesizer*)synth; + rs->rate = rate; + rs->boffset = BUFFER_SIZE_SAMPLES; + const float tuning = 440; + int c,k; + for (k=0; k < 128; k++) { + rs->freqs[k] = (tuning / 32.0f) * powf(2, (k - 9.0) / 12.0) / rate; + assert(rs->freqs[k] < M_PI/2); // otherwise spatialization may phase out.. + } + rs->kcfilt = 12.0 / rate; + synth_reset(synth); + + for (c=0; c < 16; c++) { + synth_load(&rs->sc[c], rate, &synthesize_sineP, &piano_adsr); + } + rs->xmas_on = 0; + rs->xmas_off = 0; } /** @@ -549,15 +570,18 @@ static void synth_init(void *synth, double rate) { * * @return synth-handle */ -static void * synth_alloc(void) { - return calloc(1, sizeof(RSSynthesizer)); +static void* +synth_alloc(void) +{ + return calloc(1, sizeof(RSSynthesizer)); } /** * release synth data structure * @param synth synth-handle */ -static void synth_free(void *synth) { - free(synth); +static void +synth_free(void *synth) +{ + free(synth); } -/* vi:set ts=8 sts=2 sw=2 et: */ -- cgit v1.2.3