ampler/markov.c

103 lines
2.7 KiB
C

// markov.c
/* TODO:
* remove hardcoded FRAME_SAMPLES
*/
// !!!YOU WERE HERE!!!! //
// write a proper markov chain, only run for 256 samples per chain
// - make sure we DONT EVER fall into a zero len state
// - test with sine wave, should work on any freq
// s8 to u8 conversion macros ?
// lo / hi nibble extracion macros
void markov_gen(Markov_4 *m, s8 *audio) {
const u8 cur_1st = (u8)(((s32) audio[0]) + 128);
const u8 cur_2nd = (u8)(((s32) audio[1]) + 128);
// 1st goes in low bits, 2nd in high
m -> start = (cur_1st >> 4) | (cur_2nd & 0xf0);
for int sam = 0; sam < 512; sam += 2 do {
const u8 cur_1st = (u8)(((s32) audio[sam]) + 128);
const u8 cur_2nd = (u8)(((s32) audio[sam + 1]) + 128);
// 1st goes in low bits, 2nd in high
const u8 cur = (cur_1st >> 4) | (cur_2nd & 0xf0);
const int nex_sam = sam == 510 ?
0 : // loop back to first sample
sam + 2;
const u8 nex_1st = (u8)(((s32) audio[nex_sam]) + 128);
const u8 nex_2nd = (u8)(((s32) audio[nex_sam + 1]) + 128);
// 1st goes in low bits, 2nd in high
const u8 nex = (nex_1st >> 4) | (nex_2nd & 0xf0);
m->chain[cur][nex] = MIN(m->chain[cur][nex] + 1, 255);
}
for int x = 0; x < 256; x++ do {
static u8 x_copy[256];
for int i = 0; i < 256; i++ do
x_copy[i] = m->chain[x][i];
u8 len = 0;
for int y = 0; y < 256; y++ do
for ; len < x_copy[y]; len++ do
m -> chain[x][len] = y;
m -> lens[x] = len;
}
}
void markov_synth(Markov_4 *m, s8 *audio_out) {
if SDL_GetKeyboardState(NULL)[SDL_SCANCODE_SPACE] do return;
u8 x = m -> start;
for int sam = 0; sam < FRAME_SAMPLES; sam += 2 do {
if m->lens[x] == 0 do {
puts("asdsdgsdgKLJASDUGEAKLJASKLJSDILKWJASDKLJ, WHY IS THERE A ZERO");
break;
}
// split x into low + hi
s8 lo = (x & 0xf), hi = ((x & 0xf0) >> 4);
//audio_out[sam] = (lo - 8) << 4;
//audio_out[sam + 1] = (hi - 8) << 4;
if 1 do { // bit crush
const int b = 4;
audio_out[sam] = (audio_out[sam] >> b) << b;
audio_out[sam + 1] = (audio_out[sam + 1] >> b) << b;
}
u8 rnd_y = rnd_u8() % m->lens[x];
x = m->chain[x][rnd_y];
}
}
void markov_draw(Markov_4 *mar, SDL_Renderer *r) {
const int w = 256;
for int x = 0; x < 256; x += 1 do
//for int y = 0; y < mar->lens[x]; y += 1 do {
for int y = 0; y < 256; y += 1 do {
s32 m = mar->chain[x][y];
SDL_SetRenderDrawColor(r,
m >= 10 ? m : 0,
MIN(255, m < 4 ? m * 100 : 0),
MIN(255, m < 10 and m >= 4 ? m * 100 : 0), 255);
//SDL_SetRenderDrawColor(r, m * 32, 0, 0, 255);
if m != 0 do {
const int y2 = 255 - y;
SDL_RenderDrawPoint(r, x * 2, y2 * 2);
SDL_RenderDrawPoint(r, x * 2 + 1, y2 * 2);
SDL_RenderDrawPoint(r, x * 2, y2 * 2 + 1);
SDL_RenderDrawPoint(r, x * 2 + 1, y2 * 2 + 1);
}
}
}