mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-09 00:04:56 +01:00
xmas-egg
This commit is contained in:
parent
fd1d2d804f
commit
c43a1f39a6
2 changed files with 59 additions and 1 deletions
|
|
@ -22,6 +22,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
/* LV2 */
|
/* LV2 */
|
||||||
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
|
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
|
||||||
|
|
@ -56,6 +57,7 @@ typedef struct {
|
||||||
|
|
||||||
double SampleRateD;
|
double SampleRateD;
|
||||||
void *synth;
|
void *synth;
|
||||||
|
bool xmas;
|
||||||
} RSynth;
|
} RSynth;
|
||||||
|
|
||||||
/* main LV2 */
|
/* main LV2 */
|
||||||
|
|
@ -98,6 +100,16 @@ instantiate(const LV2_Descriptor* descriptor,
|
||||||
self->synth = synth_alloc();
|
self->synth = synth_alloc();
|
||||||
synth_init(self->synth, rate);
|
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;
|
return (LV2_Handle)self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,8 +158,12 @@ run(LV2_Handle handle, uint32_t n_samples)
|
||||||
written = synth_sound(self->synth, written, ev->time.frames, audio);
|
written = synth_sound(self->synth, written, ev->time.frames, audio);
|
||||||
}
|
}
|
||||||
/* send midi message to synth */
|
/* 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);
|
synth_parse_midi(self->synth, (const uint8_t*)(ev+1), ev->body.size);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ev = (LV2_Atom_Event const*) // lv2_atom_sequence_next()
|
ev = (LV2_Atom_Event const*) // lv2_atom_sequence_next()
|
||||||
((const uint8_t*)ev + sizeof(LV2_Atom_Event) + ((ev->body.size + 7) & ~7));
|
((const uint8_t*)ev + sizeof(LV2_Atom_Event) + ((ev->body.size + 7) & ~7));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,8 @@ typedef struct {
|
||||||
float kcgain;
|
float kcgain;
|
||||||
float kcfilt;
|
float kcfilt;
|
||||||
double rate;
|
double rate;
|
||||||
|
uint32_t xmas_on;
|
||||||
|
uint32_t xmas_off;
|
||||||
} RSSynthesizer;
|
} 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);
|
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
|
* initialize the synth
|
||||||
* This should be called after synth_alloc()
|
* 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++) {
|
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_off = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue