1
0
Fork 0
jerdehl/major_sunrise.c

91 lines
2.3 KiB
C

#include <stdio.h>
#include <stdint.h>
#include <math.h>
float sinetab[2048];
typedef struct oscillator {
uint32_t phasor;
uint32_t step;
float value;
} osc_t;
void update_osc(osc_t* o) {
uint16_t index;
o->phasor += o->step;
index = o->phasor >> (32-11);
o->value = sinetab[index];
}
void set_osc_freq(osc_t* o, float f) {
o->step = (uint32_t) ((f / 16000.0) * UINT32_MAX);
}
int main() {
FILE *fp;
osc_t oscbank[5];
osc_t lfobank[4];
osc_t lisa[2];
osc_t env;
float freq;
float coldtab[2048];
float oddtab[2048];
float eventab[2048];
uint16_t out16;
float out;//, outA, outB, outC, outD;
fp = fopen("/dev/stdout", "w");
for(int i=0; i<2048; i++) {
coldtab[i] = sin(i*2*M_PI/2048);
eventab[i] = 0.5*sin(i*2*M_PI/2048) + 0.3*sin(i*2*M_PI/2048) + 0.2*sin(i*4*M_PI/2048);
oddtab[i] = 0.5*sin(i*2*M_PI/2048) + 0.3*sin(i*3*M_PI/2048) + 0.2*sin(i*5*M_PI/2048);
sinetab[i] = coldtab[i];
}
set_osc_freq(&lisa[0], 0.0015);
set_osc_freq(&lisa[1], 0.0025);
lisa[1].phasor = 0.25*UINT32_MAX;
set_osc_freq(&lfobank[0], 0.010);
set_osc_freq(&lfobank[1], 0.050);
set_osc_freq(&lfobank[2], 0.030);
set_osc_freq(&lfobank[3], 0.070);
set_osc_freq(&oscbank[0], 130.813);
set_osc_freq(&oscbank[1], 164.814);
set_osc_freq(&oscbank[2], 195.998);
set_osc_freq(&oscbank[3], 130.813/2);
set_osc_freq(&env, 0.0005);
env.phasor = 0.75*UINT32_MAX;
while(1) {
update_osc(&lisa[0]);
update_osc(&lisa[1]);
for(int i=0; i<2048; i++) {
sinetab[i] = 0.5*((0.5+0.5*lisa[0].value)*coldtab[i] + (1 - 0.5 - 0.5*lisa[0].value)*eventab[i]) +
0.5*((0.5+0.5*lisa[1].value)*coldtab[i] + (1 - 0.5 - 0.5*lisa[1].value)*oddtab[i]);
}
for(int i=0; i<4; i++) {
update_osc(&lfobank[i]);
}
set_osc_freq(&oscbank[0], 130.813 + 0.1*(lfobank[0].value));
set_osc_freq(&oscbank[1], 164.814 - 0.5*(lfobank[1].value));
set_osc_freq(&oscbank[2], 195.998 + 0.3*(lfobank[2].value));
set_osc_freq(&oscbank[3], 130.813/2 - 5*(lfobank[3].value));
for(int i=0; i<5; i++) {
update_osc(&oscbank[i]);
}
out = 0.25*oscbank[0].value +
0.25*oscbank[1].value +
0.25*oscbank[2].value +
0.25*oscbank[3].value*(0.5 + 0.5*env.value);
out16 = (uint16_t) (UINT16_MAX/2)*(0.5 + 0.5*out);
fputc(out16 & 0xFF, fp);
fputc(out16 >> 8, fp);
}
return 1;
}