NO-OP: whitespace

This commit is contained in:
Robin Gareus 2019-03-01 15:59:41 +01:00
parent 63200eab05
commit 6064c75fd5
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04

View File

@ -22,9 +22,9 @@
#endif #endif
#include <math.h> #include <math.h>
#include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdint.h>
#ifndef COMPILER_MSVC #ifndef COMPILER_MSVC
#include <stdbool.h> #include <stdbool.h>
@ -37,12 +37,12 @@
#endif #endif
#ifndef MIN #ifndef MIN
#define MIN(A, B) ( (A) < (B) ? (A) : (B) ) #define MIN(A, B) ((A) < (B) ? (A) : (B))
#endif #endif
/* internal MIDI event abstraction */ /* internal MIDI event abstraction */
enum RMIDI_EV_TYPE { enum RMIDI_EV_TYPE {
INVALID=0, INVALID = 0,
NOTE_ON, NOTE_ON,
NOTE_OFF, NOTE_OFF,
PROGRAM_CHANGE, PROGRAM_CHANGE,
@ -71,29 +71,29 @@ typedef struct {
} ADSRcfg; } ADSRcfg;
typedef struct _RSSynthChannel { typedef struct _RSSynthChannel {
uint32_t keycomp; uint32_t keycomp;
uint32_t adsr_cnt[128]; uint32_t adsr_cnt[128];
float adsr_amp[128]; float adsr_amp[128];
float phase[128]; // various use, zero'ed on note-on float phase[128]; // various use, zero'ed on note-on
int8_t miditable[128]; // internal, note-on/off velocity int8_t miditable[128]; // internal, note-on/off velocity
int8_t midimsgs [128]; // internal, note-off + on in same cycle, sustained-off int8_t midimsgs[128]; // internal, note-off + on in same cycle, sustained-off
int8_t sustain; // sustain pedal pressed int8_t sustain; // sustain pedal pressed
ADSRcfg adsr; ADSRcfg adsr;
void (*synthesize) (struct _RSSynthChannel* sc, void (*synthesize) (struct _RSSynthChannel* sc,
const uint8_t note, const float vol, const float pc, const uint8_t note, const float vol, const float pc,
const size_t n_samples, float* left, float* right); const size_t n_samples, float* left, float* right);
} RSSynthChannel; } RSSynthChannel;
typedef void (*SynthFunction) (RSSynthChannel* sc, typedef void (*SynthFunction) (RSSynthChannel* sc,
const uint8_t note, const uint8_t note,
const float vol, const float vol,
const float pc, const float pc,
const size_t n_samples, const size_t n_samples,
float* left, float* right); float* left, float* right);
typedef struct { typedef struct {
uint32_t boffset; uint32_t boffset;
float buf [2][BUFFER_SIZE_SAMPLES]; float buf[2][BUFFER_SIZE_SAMPLES];
RSSynthChannel sc[16]; RSSynthChannel sc[16];
float freqs[128]; float freqs[128];
float kcgain; float kcgain;
@ -113,7 +113,7 @@ typedef struct {
* @param svol sustain volume level [0..1] * @param svol sustain volume level [0..1]
*/ */
static void static void
init_adsr (ADSRcfg *adsr, const double rate, init_adsr (ADSRcfg* adsr, const double rate,
const uint32_t a, const uint32_t d, const uint32_t r, const uint32_t a, const uint32_t d, const uint32_t r,
const float avol, const float svol) const float avol, const float svol)
{ {
@ -123,11 +123,11 @@ init_adsr (ADSRcfg *adsr, const double rate,
adsr->tme[1] = d * rate / 1000.0; adsr->tme[1] = d * rate / 1000.0;
adsr->tme[2] = r * rate / 1000.0; adsr->tme[2] = r * rate / 1000.0;
assert(adsr->tme[0] > 32); assert (adsr->tme[0] > 32);
assert(adsr->tme[1] > 32); assert (adsr->tme[1] > 32);
assert(adsr->tme[2] > 32); assert (adsr->tme[2] > 32);
assert(adsr->vol[0] >=0 && adsr->vol[1] <= 1.0); assert (adsr->vol[0] >= 0 && adsr->vol[1] <= 1.0);
assert(adsr->vol[1] >=0 && adsr->vol[1] <= 1.0); assert (adsr->vol[1] >= 0 && adsr->vol[1] <= 1.0);
adsr->off[0] = adsr->tme[0]; adsr->off[0] = adsr->tme[0];
adsr->off[1] = adsr->tme[1] + adsr->off[0]; adsr->off[1] = adsr->tme[1] + adsr->off[0];
@ -136,7 +136,7 @@ init_adsr (ADSRcfg *adsr, const double rate,
/* calculate per-sample, per-key envelope */ /* calculate per-sample, per-key envelope */
static inline float static inline float
adsr_env(RSSynthChannel *sc, const uint8_t note) adsr_env (RSSynthChannel* sc, const uint8_t note)
{ {
if (sc->adsr_cnt[note] < sc->adsr.off[0]) { if (sc->adsr_cnt[note] < sc->adsr.off[0]) {
// attack // attack
@ -146,10 +146,9 @@ adsr_env(RSSynthChannel *sc, const uint8_t note)
return sc->adsr.vol[0]; return sc->adsr.vol[0];
} else { } else {
const float d = sc->adsr.vol[0] - sc->adsr_amp[note]; const float d = sc->adsr.vol[0] - sc->adsr_amp[note];
return sc->adsr_amp[note] + (p / (float) sc->adsr.tme[0]) * d; return sc->adsr_amp[note] + (p / (float)sc->adsr.tme[0]) * d;
} }
} } else if (sc->adsr_cnt[note] < sc->adsr.off[1]) {
else if (sc->adsr_cnt[note] < sc->adsr.off[1]) {
// decay // decay
const uint32_t p = ++sc->adsr_cnt[note] - sc->adsr.off[0]; const uint32_t p = ++sc->adsr_cnt[note] - sc->adsr.off[0];
if (p == sc->adsr.tme[1]) { if (p == sc->adsr.tme[1]) {
@ -157,14 +156,12 @@ adsr_env(RSSynthChannel *sc, const uint8_t note)
return sc->adsr.vol[1]; return sc->adsr.vol[1];
} else { } else {
const float d = sc->adsr.vol[1] - sc->adsr_amp[note]; const float d = sc->adsr.vol[1] - sc->adsr_amp[note];
return sc->adsr_amp[note] + (p / (float) sc->adsr.tme[1]) * d; return sc->adsr_amp[note] + (p / (float)sc->adsr.tme[1]) * d;
} }
} } else if (sc->adsr_cnt[note] == sc->adsr.off[1]) {
else if (sc->adsr_cnt[note] == sc->adsr.off[1]) {
// sustain // sustain
return sc->adsr.vol[1]; return sc->adsr.vol[1];
} } else if (sc->adsr_cnt[note] < sc->adsr.off[2]) {
else if (sc->adsr_cnt[note] < sc->adsr.off[2]) {
// release // release
const uint32_t p = ++sc->adsr_cnt[note] - sc->adsr.off[1]; const uint32_t p = ++sc->adsr_cnt[note] - sc->adsr.off[1];
if (p == sc->adsr.tme[2]) { if (p == sc->adsr.tme[2]) {
@ -172,10 +169,9 @@ adsr_env(RSSynthChannel *sc, const uint8_t note)
return 0; return 0;
} else { } else {
const float d = 0 - sc->adsr_amp[note]; const float d = 0 - sc->adsr_amp[note];
return sc->adsr_amp[note] + (p / (float) sc->adsr.tme[2]) * d; return sc->adsr_amp[note] + (p / (float)sc->adsr.tme[2]) * d;
} }
} } else {
else {
sc->adsr_cnt[note] = 0; sc->adsr_cnt[note] = 0;
return 0; return 0;
} }
@ -189,109 +185,107 @@ synthesize_sineP (RSSynthChannel* sc,
const size_t n_samples, float* left, float* right) const size_t n_samples, float* left, float* right)
{ {
size_t i; size_t i;
float phase = sc->phase[note]; float phase = sc->phase[note];
for (i=0; i < n_samples; ++i) { for (i = 0; i < n_samples; ++i) {
float env = adsr_env(sc, note); float env = adsr_env (sc, note);
if (sc->adsr_cnt[note] == 0) break; if (sc->adsr_cnt[note] == 0) {
break;
}
const float amp = vol * env; const float amp = vol * env;
if (amp > 1e-10) { if (amp > 1e-10) {
left[i] += amp * sinf(2.0 * M_PI * phase); left[i] += amp * sinf (2.0 * M_PI * phase);
left[i] += .300 * amp * sinf(2.0 * M_PI * phase * 2.0); 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] += .150 * amp * sinf (2.0 * M_PI * phase * 3.0);
left[i] += .080 * amp * sinf(2.0 * M_PI * phase * 4.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] -= .007 * amp * sinf(2.0 * M_PI * phase * 5.0);
//left[i] += .010 * amp * sinf(2.0 * M_PI * phase * 6.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); left[i] += .020 * amp * sinf (2.0 * M_PI * phase * 7.0);
phase += fq; phase += fq;
right[i] += amp * sinf(2.0 * M_PI * phase); right[i] += amp * sinf (2.0 * M_PI * phase);
right[i] += .300 * amp * sinf(2.0 * M_PI * phase * 2.0); 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] += .150 * amp * sinf (2.0 * M_PI * phase * 3.0);
right[i] -= .080 * amp * sinf(2.0 * M_PI * phase * 4.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] += .007 * amp * sinf(2.0 * M_PI * phase * 5.0);
//right[i] += .010 * amp * sinf(2.0 * M_PI * phase * 6.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); right[i] -= .020 * amp * sinf (2.0 * M_PI * phase * 7.0);
} else { } else {
phase += fq; phase += fq;
} }
if (phase > 1.0) phase -= 2.0; if (phase > 1.0)
phase -= 2.0;
} }
sc->phase[note] = phase; 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,.. */ /* process note - move through ADSR states, count active keys,.. */
static void static void
process_key (void *synth, process_key (void* synth,
const uint8_t chn, const uint8_t note, const uint8_t chn, const uint8_t note,
const size_t n_samples, const size_t n_samples,
float *left, float *right) float* left, float* right)
{ {
RSSynthesizer* rs = (RSSynthesizer*)synth; RSSynthesizer* rs = (RSSynthesizer*)synth;
RSSynthChannel* sc = &rs->sc[chn]; RSSynthChannel* sc = &rs->sc[chn];
const int8_t vel = sc->miditable[note]; const int8_t vel = sc->miditable[note];
const int8_t msg = sc->midimsgs[note]; const int8_t msg = sc->midimsgs[note];
const float vol = /* master_volume */ 0.1f * abs(vel) / 127.f; const float vol = /* master_volume */ 0.1f * abs (vel) / 127.f;
const float phase = sc->phase[note]; const float phase = sc->phase[note];
const int8_t sus = sc->sustain; const int8_t sus = sc->sustain;
sc->midimsgs[note] &= ~3; sc->midimsgs[note] &= ~3;
if (phase == -10 && vel > 0) { if (phase == -10 && vel > 0) {
// new note on // new note on
sc->midimsgs[note] &= ~4; sc->midimsgs[note] &= ~4;
assert(sc->adsr_cnt[note] == 0); assert (sc->adsr_cnt[note] == 0);
sc->adsr_amp[note] = 0; sc->adsr_amp[note] = 0;
sc->adsr_cnt[note] = 0; sc->adsr_cnt[note] = 0;
sc->phase[note] = 0; sc->phase[note] = 0;
sc->keycomp++; sc->keycomp++;
//printf("[On] Now %d keys active on chn %d\n", sc->keycomp, chn); //printf("[On] Now %d keys active on chn %d\n", sc->keycomp, chn);
} } else if (phase >= -1.0 && phase <= 1.0 && vel > 0) {
else if (phase >= -1.0 && phase <= 1.0 && vel > 0) {
// sustain note or re-start note while adsr in progress: // 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) { if (sc->adsr_cnt[note] > sc->adsr.off[1] || msg == 3 || msg == 5 || msg == 7) {
sc->midimsgs[note] &= ~4; sc->midimsgs[note] &= ~4;
// x-fade to attack // x-fade to attack
sc->adsr_amp[note] = adsr_env(sc, note); sc->adsr_amp[note] = adsr_env (sc, note);
sc->adsr_cnt[note] = 0; sc->adsr_cnt[note] = 0;
} }
} } else if (phase >= -1.0 && phase <= 1.0 && vel < 0) {
else if (phase >= -1.0 && phase <= 1.0 && vel < 0) {
sc->midimsgs[note] |= 4; sc->midimsgs[note] |= 4;
// note off // note off
if (sc->adsr_cnt[note] <= sc->adsr.off[1] && !sus) { if (sc->adsr_cnt[note] <= sc->adsr.off[1] && !sus) {
if (sc->adsr_cnt[note] != sc->adsr.off[1]) { if (sc->adsr_cnt[note] != sc->adsr.off[1]) {
// x-fade to release // x-fade to release
sc->adsr_amp[note] = adsr_env(sc, note); sc->adsr_amp[note] = adsr_env (sc, note);
} }
sc->adsr_cnt[note] = sc->adsr.off[1] + 1; sc->adsr_cnt[note] = sc->adsr.off[1] + 1;
} } else if (sus && sc->adsr_cnt[note] == sc->adsr.off[1]) {
else if (sus && sc->adsr_cnt[note] == sc->adsr.off[1]) {
sc->adsr_cnt[note] = sc->adsr.off[1] + 1; sc->adsr_cnt[note] = sc->adsr.off[1] + 1;
} }
} } else {
else {
//printf("FORCE NOTE OFF: %d %d\n", vel, sus); //printf("FORCE NOTE OFF: %d %d\n", vel, sus);
/* note-on + off in same cycle */ /* note-on + off in same cycle */
sc->miditable[note] = 0; sc->miditable[note] = 0;
sc->adsr_cnt[note] = 0; sc->adsr_cnt[note] = 0;
sc->phase[note] = -10; sc->phase[note] = -10;
return; return;
} }
//printf("NOTE: %d (%d %d %d)\n", sc->adsr_cnt[note], sc->adsr.off[0], sc->adsr.off[1], sc->adsr.off[2]); //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 // synthesize actual sound
sc->synthesize(sc, note, vol, rs->freqs[note], n_samples, left, right); sc->synthesize (sc, note, vol, rs->freqs[note], n_samples, left, right);
if (sc->adsr_cnt[note] == 0) { if (sc->adsr_cnt[note] == 0) {
//printf("Note %d,%d released\n", chn, note); //printf("Note %d,%d released\n", chn, note);
sc->midimsgs[note] = 0; sc->midimsgs[note] = 0;
sc->miditable[note] = 0; sc->miditable[note] = 0;
sc->adsr_amp[note] = 0; sc->adsr_amp[note] = 0;
sc->phase[note] = -10; sc->phase[note] = -10;
sc->keycomp--; sc->keycomp--;
//printf("[off] Now %d keys active on chn %d\n", sc->keycomp, chn); //printf("[off] Now %d keys active on chn %d\n", sc->keycomp, chn);
} }
@ -299,29 +293,32 @@ process_key (void *synth,
/* synthesize a BUFFER_SIZE_SAMPLES's of audio-data */ /* synthesize a BUFFER_SIZE_SAMPLES's of audio-data */
static void static void
synth_fragment (void *synth, const size_t n_samples, float *left, float *right) synth_fragment (void* synth, const size_t n_samples, float* left, float* right)
{ {
RSSynthesizer* rs = (RSSynthesizer*)synth; RSSynthesizer* rs = (RSSynthesizer*)synth;
memset (left, 0, n_samples * sizeof(float)); memset (left, 0, n_samples * sizeof (float));
memset (right, 0, n_samples * sizeof(float)); memset (right, 0, n_samples * sizeof (float));
uint8_t keycomp = 0; uint8_t keycomp = 0;
int c,k; int c, k;
size_t i; size_t i;
for (c=0; c < 16; ++c) { for (c = 0; c < 16; ++c) {
for (k=0; k < 128; ++k) { for (k = 0; k < 128; ++k) {
if (rs->sc[c].miditable[k] == 0) continue; if (rs->sc[c].miditable[k] == 0) {
process_key(synth, c, k, n_samples, left, right); continue;
}
process_key (synth, c, k, n_samples, left, right);
} }
keycomp += rs->sc[c].keycomp; keycomp += rs->sc[c].keycomp;
} }
#if 1 // key-compression #if 1 // key-compression
float kctgt = 8.0 / (float)(keycomp + 7.0); float kctgt = 8.0 / (float)(keycomp + 7.0);
if (kctgt < .5) kctgt = .5; if (kctgt < .5) kctgt = .5;
if (kctgt > 1.0) kctgt = 1.0; if (kctgt > 1.0) kctgt = 1.0;
const float _w = rs->kcfilt; const float _w = rs->kcfilt;
for (i=0; i < n_samples; ++i) { for (i = 0; i < n_samples; ++i) {
rs->kcgain += _w * (kctgt - rs->kcgain); rs->kcgain += _w * (kctgt - rs->kcgain);
left[i] *= rs->kcgain; left[i] *= rs->kcgain;
right[i] *= rs->kcgain; right[i] *= rs->kcgain;
@ -331,7 +328,7 @@ synth_fragment (void *synth, const size_t n_samples, float *left, float *right)
} }
static void static void
synth_reset_channel(RSSynthChannel* sc) synth_reset_channel (RSSynthChannel* sc)
{ {
int k; int k;
for (k = 0; k < 128; ++k) { for (k = 0; k < 128; ++k) {
@ -345,25 +342,25 @@ synth_reset_channel(RSSynthChannel* sc)
} }
static void static void
synth_reset(void *synth) synth_reset (void* synth)
{ {
RSSynthesizer* rs = (RSSynthesizer*)synth; RSSynthesizer* rs = (RSSynthesizer*)synth;
int c; int c;
for (c=0; c < 16; ++c) { for (c = 0; c < 16; ++c) {
synth_reset_channel(&(rs->sc[c])); synth_reset_channel (&(rs->sc[c]));
} }
rs->kcgain = 0; rs->kcgain = 0;
} }
static void static void
synth_load (RSSynthChannel *sc, const double rate, synth_load (RSSynthChannel* sc, const double rate,
SynthFunction synthesize, SynthFunction synthesize,
ADSRcfg const * const adsr) ADSRcfg const* const adsr)
{ {
synth_reset_channel(sc); synth_reset_channel (sc);
init_adsr(&sc->adsr, rate, init_adsr (&sc->adsr, rate,
adsr->tme[0], adsr->tme[1], adsr->tme[2], adsr->tme[0], adsr->tme[1], adsr->tme[2],
adsr->vol[0], adsr->vol[1]); adsr->vol[0], adsr->vol[1]);
sc->synthesize = synthesize; sc->synthesize = synthesize;
} }
@ -371,10 +368,10 @@ synth_load (RSSynthChannel *sc, const double rate,
* internal abstraction of MIDI data handling * internal abstraction of MIDI data handling
*/ */
static void static void
synth_process_midi_event(void *synth, struct rmidi_event_t *ev) synth_process_midi_event (void* synth, struct rmidi_event_t* ev)
{ {
RSSynthesizer* rs = (RSSynthesizer*)synth; RSSynthesizer* rs = (RSSynthesizer*)synth;
switch(ev->type) { switch (ev->type) {
case NOTE_ON: case NOTE_ON:
rs->sc[ev->channel].midimsgs[ev->d.tone.note] |= 1; rs->sc[ev->channel].midimsgs[ev->d.tone.note] |= 1;
if (rs->sc[ev->channel].miditable[ev->d.tone.note] <= 0) if (rs->sc[ev->channel].miditable[ev->d.tone.note] <= 0)
@ -392,12 +389,12 @@ synth_process_midi_event(void *synth, struct rmidi_event_t *ev)
/* 0x00 and 0x20 are used for BANK select */ /* 0x00 and 0x20 are used for BANK select */
} else if (ev->d.control.param == 64) { } else if (ev->d.control.param == 64) {
/* damper pedal*/ /* damper pedal*/
rs->sc[ev->channel].sustain = ev->d.control.value < 64 ? 0: 1; rs->sc[ev->channel].sustain = ev->d.control.value < 64 ? 0 : 1;
} else if (ev->d.control.param == 121) { } else if (ev->d.control.param == 121) {
/* reset all controllers */ /* reset all controllers */
} else if (ev->d.control.param == 120 || ev->d.control.param == 123) { } else if (ev->d.control.param == 120 || ev->d.control.param == 123) {
/* Midi panic: 120: all sound off, 123: all notes off*/ /* Midi panic: 120: all sound off, 123: all notes off*/
synth_reset_channel(&(rs->sc[ev->channel])); synth_reset_channel (&(rs->sc[ev->channel]));
} else if (ev->d.control.param >= 120) { } else if (ev->d.control.param >= 120) {
/* params 122-127 are reserved - skip them. */ /* params 122-127 are reserved - skip them. */
} }
@ -422,23 +419,23 @@ synth_process_midi_event(void *synth, struct rmidi_event_t *ev)
* @return end of buffer (written + nframes) * @return end of buffer (written + nframes)
*/ */
static uint32_t static uint32_t
synth_sound (void *synth, uint32_t written, const uint32_t nframes, float **out) synth_sound (void* synth, uint32_t written, const uint32_t nframes, float** out)
{ {
RSSynthesizer* rs = (RSSynthesizer*)synth; RSSynthesizer* rs = (RSSynthesizer*)synth;
while (written < nframes) { while (written < nframes) {
uint32_t nremain = nframes - written; uint32_t nremain = nframes - written;
if (rs->boffset >= BUFFER_SIZE_SAMPLES) { if (rs->boffset >= BUFFER_SIZE_SAMPLES) {
const uint32_t tosynth = MIN(BUFFER_SIZE_SAMPLES, nremain); const uint32_t tosynth = MIN (BUFFER_SIZE_SAMPLES, nremain);
rs->boffset = BUFFER_SIZE_SAMPLES - tosynth; rs->boffset = BUFFER_SIZE_SAMPLES - tosynth;
synth_fragment(rs, tosynth, &(rs->buf[0][rs->boffset]), &(rs->buf[1][rs->boffset])); 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[0][written], &rs->buf[0][rs->boffset], nread * sizeof (float));
memcpy(&out[1][written], &rs->buf[1][rs->boffset], nread*sizeof(float)); memcpy (&out[1][written], &rs->buf[1][rs->boffset], nread * sizeof (float));
written += nread; written += nread;
rs->boffset += nread; rs->boffset += nread;
@ -454,83 +451,89 @@ synth_sound (void *synth, uint32_t written, const uint32_t nframes, float **out)
* @param size number of bytes in the midi-message * @param size number of bytes in the midi-message
*/ */
static void static void
synth_parse_midi (void *synth, const uint8_t *data, const size_t size) synth_parse_midi (void* synth, const uint8_t* data, const size_t size)
{ {
if (size < 2 || size > 3) return; if (size < 2 || size > 3)
return;
// All messages need to be 3 bytes; except program-changes: 2bytes. // All messages need to be 3 bytes; except program-changes: 2bytes.
if (size == 2 && (data[0] & 0xf0) != 0xC0) return; if (size == 2 && (data[0] & 0xf0) != 0xC0)
return;
struct rmidi_event_t ev; struct rmidi_event_t ev;
ev.channel = data[0]&0x0f; ev.channel = data[0] & 0x0f;
switch (data[0] & 0xf0) { switch (data[0] & 0xf0) {
case 0x80: case 0x80:
ev.type=NOTE_OFF; ev.type = NOTE_OFF;
ev.d.tone.note=data[1]&0x7f; ev.d.tone.note = data[1] & 0x7f;
ev.d.tone.velocity=data[2]&0x7f; ev.d.tone.velocity = data[2] & 0x7f;
break; break;
case 0x90: case 0x90:
ev.type=NOTE_ON; ev.type = NOTE_ON;
ev.d.tone.note=data[1]&0x7f; ev.d.tone.note = data[1] & 0x7f;
ev.d.tone.velocity=data[2]&0x7f; ev.d.tone.velocity = data[2] & 0x7f;
if (ev.d.tone.velocity == 0) { if (ev.d.tone.velocity == 0) {
ev.type=NOTE_OFF; ev.type = NOTE_OFF;
} }
break; break;
case 0xB0: case 0xB0:
ev.type=CONTROL_CHANGE; ev.type = CONTROL_CHANGE;
ev.d.control.param=data[1]&0x7f; ev.d.control.param = data[1] & 0x7f;
ev.d.control.value=data[2]&0x7f; ev.d.control.value = data[2] & 0x7f;
break; break;
case 0xC0: case 0xC0:
ev.type=PROGRAM_CHANGE; ev.type = PROGRAM_CHANGE;
ev.d.control.value=data[1]&0x7f; ev.d.control.value = data[1] & 0x7f;
break; break;
default: default:
return; return;
} }
synth_process_midi_event(synth, &ev); 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 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 static void
synth_parse_xmas(void *synth, const uint8_t *data, const size_t size) synth_parse_xmas (void* synth, const uint8_t* data, const size_t size)
{ {
RSSynthesizer* rs = (RSSynthesizer*)synth; RSSynthesizer* rs = (RSSynthesizer*)synth;
if (size < 2 || size > 3) return; if (size < 2 || size > 3)
return;
// All messages need to be 3 bytes; except program-changes: 2bytes. // All messages need to be 3 bytes; except program-changes: 2bytes.
if (size == 2 && (data[0] & 0xf0) != 0xC0) return; if (size == 2 && (data[0] & 0xf0) != 0xC0)
return;
struct rmidi_event_t ev; struct rmidi_event_t ev;
ev.channel = data[0]&0x0f; ev.channel = data[0] & 0x0f;
switch (data[0] & 0xf0) { switch (data[0] & 0xf0) {
case 0x80: case 0x80:
ev.type=NOTE_OFF; ev.type = NOTE_OFF;
ev.d.tone.note=jingle[rs->xmas_off++]; ev.d.tone.note = jingle[rs->xmas_off++];
ev.d.tone.velocity=data[2]&0x7f; ev.d.tone.velocity = data[2] & 0x7f;
if (rs->xmas_off >= sizeof(jingle)) rs->xmas_off = 0; if (rs->xmas_off >= sizeof (jingle))
rs->xmas_off = 0;
break; break;
case 0x90: case 0x90:
ev.type=NOTE_ON; ev.type = NOTE_ON;
ev.d.tone.note=jingle[rs->xmas_on++]; ev.d.tone.note = jingle[rs->xmas_on++];
ev.d.tone.velocity=data[2]&0x7f; ev.d.tone.velocity = data[2] & 0x7f;
if (rs->xmas_on >= sizeof(jingle)) rs->xmas_on = 0; if (rs->xmas_on >= sizeof (jingle))
rs->xmas_on = 0;
break; break;
case 0xB0: case 0xB0:
ev.type=CONTROL_CHANGE; ev.type = CONTROL_CHANGE;
ev.d.control.param=data[1]&0x7f; ev.d.control.param = data[1] & 0x7f;
ev.d.control.value=data[2]&0x7f; ev.d.control.value = data[2] & 0x7f;
break; break;
case 0xC0: case 0xC0:
ev.type=PROGRAM_CHANGE; ev.type = PROGRAM_CHANGE;
ev.d.control.value=data[1]&0x7f; ev.d.control.value = data[1] & 0x7f;
break; break;
default: default:
return; return;
} }
synth_process_midi_event(synth, &ev); synth_process_midi_event (synth, &ev);
} }
/** /**
* initialize the synth * initialize the synth
@ -541,23 +544,24 @@ synth_parse_xmas(void *synth, const uint8_t *data, const size_t size)
* @param rate sample-rate * @param rate sample-rate
*/ */
static void static void
synth_init(void* synth, double rate) { synth_init (void* synth, double rate)
RSSynthesizer* rs = (RSSynthesizer*)synth; {
rs->rate = rate; RSSynthesizer* rs = (RSSynthesizer*)synth;
rs->boffset = BUFFER_SIZE_SAMPLES; rs->rate = rate;
rs->boffset = BUFFER_SIZE_SAMPLES;
const float tuning = 440; const float tuning = 440;
int c,k; int c, k;
for (k=0; k < 128; k++) { for (k = 0; k < 128; k++) {
rs->freqs[k] = (tuning / 32.0f) * powf(2, (k - 9.0) / 12.0) / rate; 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.. assert (rs->freqs[k] < M_PI / 2); // otherwise spatialization may phase out..
} }
rs->kcfilt = 12.0 / rate; rs->kcfilt = 12.0 / rate;
synth_reset(synth); synth_reset (synth);
for (c=0; c < 16; c++) { for (c = 0; c < 16; c++) {
synth_load(&rs->sc[c], rate, &synthesize_sineP, &piano_adsr); synth_load (&rs->sc[c], rate, &synthesize_sineP, &piano_adsr);
} }
rs->xmas_on = 0; rs->xmas_on = 0;
rs->xmas_off = 0; rs->xmas_off = 0;
} }
@ -572,9 +576,9 @@ synth_init(void* synth, double rate) {
* @return synth-handle * @return synth-handle
*/ */
static void* static void*
synth_alloc(void) synth_alloc (void)
{ {
return calloc(1, sizeof(RSSynthesizer)); return calloc (1, sizeof (RSSynthesizer));
} }
/** /**
@ -582,7 +586,7 @@ synth_alloc(void)
* @param synth synth-handle * @param synth synth-handle
*/ */
static void static void
synth_free(void *synth) synth_free (void* synth)
{ {
free(synth); free (synth);
} }