103 lines
2.7 KiB
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|