Skip to content

Instantly share code, notes, and snippets.

@minerscale
Created March 12, 2019 13:10
Show Gist options
  • Save minerscale/55b15a723d26c4998e42d6f17b0dfe26 to your computer and use it in GitHub Desktop.
Save minerscale/55b15a723d26c4998e42d6f17b0dfe26 to your computer and use it in GitHub Desktop.
#include <math.h>
#include <stdio.h>
#define BITRATE 16000.0
#define TAU 6.2831853
#define R -127
double sqr(int i){
return (i%2)?1.0/i:0;
}
double saw(int i){
return 1.0/i;
}
double tri(int i){
return (i%2)?( ((i/2)%2)?-1:1) * 1.0/(i*i) :0;
}
double envelope(double p, double a, double d, double s, double h, double r, double l){
p = fmod(p,l);
if (p <= a){
return p/a;
} else if (p <= d + a){
return 1 - (1-s)/d*(p-a);
} else if (p <= a + d + h){
return s;
} else if (p <= a + d + h + r){
return s - (s/r)*(p - a - d - h);
} else {
return 0;
}
}
double organ(int t, double note, double bound, double (*partial)(int)){
if (note <= -64){
return 0;
}
double input = t*TAU*440*pow(2,note/12.0)/BITRATE;
double sum = 0;
bound += 1;
for (int i = 1; i <= (int)bound; ++i){
sum += ((i==(int)bound)?fmod(bound,1):1) * (*partial)(i)*sin(i*input);
}
return sum;
}
double drum(int t, double b, double o, double n, double l){
b = fmod(32*b,32*l) + o + 1;
t = t/((int)b);
if (b <= n*32){
return sin(BITRATE*pow(t,4)) + sin(BITRATE*pow(t+1,4));
} else {
return 0;
}
}
int melody[] = {5,R,5,5,8,5,R,R,8,R,10,15,12,R,R,R};
int bass[] = {5,3,5,3,5,R,8,R,5,3,5,3,5,-7,-7,R};
int main(){
for (int t = 0;;++t){
double beat = 1*t/BITRATE;
int melody_note = melody[(int)(4*beat) % 16];
int bass_note = bass[(int)(4*beat)%16];
int offset = (((int)(beat/8) % 3)==2?3.5:4)*((int)(beat/8) % 3);
double sample_l = (((sin(8*TAU*beat)+4)/8)*envelope(beat, 0.005, 1.0/8, 0, 0, 0, 1.0/4) * (
organ(t, melody_note - offset, 40, saw) * 0.1 +
organ(t, melody_note - 12 - offset + 24*(((int)beat/2)%2), 10, sqr) * 0.1
)*((((int)beat/2)%2)?1:0.3)*2 +
envelope(beat, 0.01, 0, 1, 1/12.0 - 0.02, 0.01, 1/8.0) * (
organ(t+20, -24 + bass_note - offset, 40, saw)*0.02 +
organ(t, -36 + bass_note - offset, 100, saw)*0.05
) +
envelope(beat, 0.01, 0, 1, 1/8.0 - 0.1, 0.1, 1/4.0) * (
organ(t, 7+((int)(4*beat + 1)%2) - 12 - offset,40, saw)*0.04 +
organ(t+80, 3+2*((int)(4*beat + 1)%2) - 12 - offset,40, tri)*0.04
) +
organ(t, 5 - 24 - offset, 20, saw)*0.02 +
organ(t, 8 - 24 - offset, 20, saw)*0.01 +
organ(t, 12 - 24 - offset, 20, saw)*0.01 +
drum(t, beat, 1+9*((int)(2*beat + 1) % 2) ,((int)(2*beat) % 2)?0.2:0.42, 0.5)*0.05) * 0.5;
double sample_r = (((sin(8*TAU*beat)+4)/8)*envelope(beat, 0.005, 1.0/8, 0, 0, 0, 1.0/4) * (
organ(t, melody_note - offset, 40, saw) * 0.1 +
organ(t, melody_note - 12 - offset + 24*(((int)beat/2)%2), 10, sqr) * 0.1
)*((((int)beat/2)%2)?0.3:1)*2 +
envelope(beat, 0.01, 0, 1, 1/12.0 - 0.02, 0.01, 1/8.0) * (
organ(t, -24 + bass_note - offset, 40, saw)*0.02 +
organ(t+20, -36 + bass_note - offset, 40, saw)*0.05
) +
envelope(beat, 0.01, 0, 1, 1/8.0 - 0.1, 0.1, 1/4.0) * (
organ(t+80, 7+((int)(4*beat + 1)%2) - 12 - offset,40, saw)*0.04 +
organ(t, 3+2*((int)(4*beat + 1)%2) - 12 - offset,40, tri)*0.04
) +
organ(t, 5 - 24 - offset, 20, saw)*0.02 +
organ(t, 8 - 24 - offset, 20, saw)*0.02 +
organ(1.01*t, 12 - 24 - offset, 20, saw)*0.01 +
drum(t+100, beat, 1+9*((int)(2*beat + 1) % 2) ,((int)(2*beat) % 2)?0.2:0.42, 0.5)*0.05) * 0.5
;
int output_l = sample_l * 65535;
int output_r = sample_r * 65535;
putchar(output_l >> 8);
putchar(output_l);
putchar(output_r >> 8);
putchar(output_r);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment