diff --git a/libs/plugins/reasonablesynth.lv2/lv2.c b/libs/plugins/reasonablesynth.lv2/lv2.c index b29590c78a..6b9c81d8dd 100644 --- a/libs/plugins/reasonablesynth.lv2/lv2.c +++ b/libs/plugins/reasonablesynth.lv2/lv2.c @@ -22,6 +22,7 @@ #include #include #include +#include /* LV2 */ #include "lv2/lv2plug.in/ns/lv2core/lv2.h" @@ -56,6 +57,7 @@ typedef struct { double SampleRateD; void *synth; + bool xmas; } RSynth; /* main LV2 */ @@ -98,6 +100,16 @@ instantiate(const LV2_Descriptor* descriptor, self->synth = synth_alloc(); synth_init(self->synth, rate); + + 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; + } + return (LV2_Handle)self; } @@ -146,7 +158,11 @@ run(LV2_Handle handle, uint32_t n_samples) written = synth_sound(self->synth, written, ev->time.frames, audio); } /* send midi message to synth */ - synth_parse_midi(self->synth, (const uint8_t*)(ev+1), ev->body.size); + 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() ((const uint8_t*)ev + sizeof(LV2_Atom_Event) + ((ev->body.size + 7) & ~7)); diff --git a/libs/plugins/reasonablesynth.lv2/rsynth.c b/libs/plugins/reasonablesynth.lv2/rsynth.c index d2d5b3e905..42f5b5500a 100644 --- a/libs/plugins/reasonablesynth.lv2/rsynth.c +++ b/libs/plugins/reasonablesynth.lv2/rsynth.c @@ -89,6 +89,8 @@ typedef struct { float kcgain; float kcfilt; double rate; + uint32_t xmas_on; + uint32_t xmas_off; } RSSynthesizer; @@ -446,6 +448,44 @@ static void synth_parse_midi(void *synth, const uint8_t *data, const size_t size 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); +} /** * initialize the synth * This should be called after synth_alloc() @@ -470,6 +510,8 @@ static void synth_init(void *synth, double rate) { for (c=0; c < 16; c++) { synth_load(&rs->sc[c], rate, &synthesize_sineP, &piano_adsr); } + rs->xmas_on = 0; + rs->xmas_off = 0; } /**