#include #include int fd, freq[7] = { 0x8321, 0x8321 * 28 / 27, 0x8321 * 32 / 27, 0x8321 * 4 / 3, 0x8321 * 3 / 2, 0x8321 * 14 / 9, 0x8321 * 16 / 9 }; struct{ int amp, attack, release, dur, Δφ, φ, envQ30, envQ15, count, mod, out; }op[24] = { {0x1000, 0x7fff, 0x4ff0, 1, 0x1111}, /* hat */ {0x3000, 0x7fff, 0xff0, 3}, /* kick */ {0x300, 0x7fff, 0x3000, 1, 0x111}, /* kick mod */ {0x3000, 0x5fff, 0xff0, 30, 0x8321}, /* test */ }; uint hat, kick, test; short delay[32768]; uint dcnt, dlfo; void bar(void){ int i, j, x, n; uchar buf[512 * 4]; uint b; for(b = 0x80000000UL; b; b >>= 1){ if(b & hat) op[0].count = 0; if(b & kick){ op[1].Δφ = 0x9999; /* my kick drum looks like this: ⑨ */ op[1].count = 0; op[2].count = 0; } if(b & test){ op[3].Δφ = freq[nrand(7)]; op[3].count = 0; } for(n = 0; n < 12; n++){ for(i = 0; i < nelem(op); i++){ if(op[i].count++ < op[i].dur) op[i].envQ30 += (op[i].amp - op[i].envQ15) * op[i].attack; else op[i].envQ30 -= op[i].envQ15 * op[i].release; op[i].envQ15 = op[i].envQ30 >> 15; } op[1].Δφ = op[1].Δφ * 0x6fff >> 15; for(i = 0; i < sizeof buf; i += 4){ op[0].mod = op[0].out * 255; /* hat */ op[1].mod = op[2].out; /* kick */ op[2].mod = op[2].out * 111; /* kick mod */ op[3].mod = op[3].out >> 1; /* test */ for(j = 0; j < nelem(op); j++){ op[j].φ += op[j].Δφ; x = (op[j].φ >> 8) + op[j].mod & 0x7fff; x = (x * (x - 0x8000) >> 13) * (x - 0x4000) >> 13; /* cubic sine approx */ op[j].out = op[j].envQ15 * x >> 15; } dlfo = dlfo + 220 & 4095; j = (j - 4096) * (j - 2048) * j >> 14; j = dcnt + 100 + j & 32767; delay[j] = x = delay[dcnt] + op[3].out >> 1; dcnt = dcnt + 1 & 32767; x += op[0].out + op[1].out; buf[i] = buf[i | 2] = x; buf[i | 1] = buf[i | 3] = x >> 8; } write(fd, buf, sizeof buf); } } } void main(int i, char**){ USED(i); for(i = 0; i < nelem(op); i++) op[i].count = op[i].dur; fd = open("/dev/audio", OWRITE); if(fd < 0) sysfatal("open: %r"); hat = 0xffffffff; kick = 0x88888888; while(9)test = lrand(), bar(); bar(); }