From d6b6846669dcf831426e10937b144421960e5c06 Mon Sep 17 00:00:00 2001 From: bx Date: Thu, 10 Feb 2022 19:26:20 +0000 Subject: [PATCH] last commit of markov thing, gonna try change to granular stuff now --- ampler.c | 3 ++ ampler.h | 10 ++++++ audio.c | 11 ++++++ draw.c | 98 +++++++++++++++++++++++++++------------------------- markov.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ random.c | 59 ++++++++++++++++++++++++++++++++ 6 files changed, 236 insertions(+), 47 deletions(-) create mode 100644 markov.c create mode 100644 random.c diff --git a/ampler.c b/ampler.c index 8743ec1..0c4f920 100644 --- a/ampler.c +++ b/ampler.c @@ -2,6 +2,8 @@ #include "ampler.h" +#include "random.c" +#include "markov.c" #include "audio.c" #include "draw.c" @@ -41,6 +43,7 @@ Ampler_state *init() { // TODO: iterate a directory to load samples //load_sample(state, "./mix.wav"); + load_sample(state, "./haunted.wav"); //load_sample(state, "./loop2.wav"); //load_sample(state, "./loop.wav"); //load_sample(state, "./chord.wav"); diff --git a/ampler.h b/ampler.h index 5fa1cf2..5b5d6d3 100644 --- a/ampler.h +++ b/ampler.h @@ -13,6 +13,7 @@ typedef int32_t s32; typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; +typedef uint64_t u64; typedef float f32; typedef double f64; @@ -59,6 +60,13 @@ struct Udp_msg { enum { MSG_FREE = 0, MSG_TRIGGER, } state; }; +typedef struct Markov_4 Markov_4; +struct Markov_4 { + u8 start; + u8 chain[256][256]; + u8 lens[256]; +}; + typedef struct Ampler_state Ampler_state; struct Ampler_state { u32 size; // in bytes, off this struct @@ -69,6 +77,8 @@ struct Ampler_state { Udp_msg messages[64]; s8 frame_mix[CHANNELS][FRAME_SAMPLES]; s8 frame_rec[CHANNELS][FRAME_SAMPLES]; + + Markov_4 markov; }; diff --git a/audio.c b/audio.c index 0a960dc..2c77954 100644 --- a/audio.c +++ b/audio.c @@ -103,6 +103,16 @@ int audio_frame(Ampler_state *state) { foreach_ptr(Sound_src, snd, state -> sounds) sound_src_frame(snd, mix); + // MARKOV TEST + SDL_memset(&(state->markov), 0, sizeof state->markov); + markov_gen(&(state->markov), mix_l); + markov_synth(&(state->markov), mix_l); + for int i = 0; i < FRAME_SAMPLES; i += 1 do + mix_r[i] = mix_l[i]; + // MARKOV TEST + + + const int vol = 100; static s16 frame[FRAME_SAMPLES * CHANNELS] = { 0 }; for int i = 0; i < FRAME_SAMPLES; i += 1 do @@ -132,6 +142,7 @@ void load_sample(Ampler_state *state, const char *file_name) { u32 bytes = 0; SDL_LoadWAV(file_name, &spec, (u8 **) &buffer, &bytes); + // TODO: Check for error from LoadWAV if spec.format != AUDIO_S16 do { puts("error: sample.wav is not s16"); diff --git a/draw.c b/draw.c index b6b98fc..9c8c770 100644 --- a/draw.c +++ b/draw.c @@ -1,15 +1,6 @@ // draw.c -void draw_frame(SDL_Window *w, SDL_Renderer *r, Ampler_state *state) { - SDL_SetRenderDrawColor(r, 0x1D, 0x2B, 0x53, 255); - - SDL_SetRenderDrawBlendMode(r, SDL_BLENDMODE_BLEND); - SDL_SetRenderDrawBlendMode(r, SDL_BLENDMODE_NONE); - SDL_SetRenderDrawColor(r, 10, 10, 10, 40); - SDL_Rect screen = { 0, 0, 512, 512 }; - SDL_RenderFillRect(r, &screen); - // SDL_RenderClear(r); - +void draw_snd_waves(SDL_Window *w, SDL_Renderer *r, Ampler_state *state) { // TODO: DRAW WITH X SCALE FACTOR // TODO: DRAW SMOLER SDL_SetRenderDrawColor(r, 0xFF, 0x00, 0x4D, 255); @@ -34,29 +25,58 @@ void draw_frame(SDL_Window *w, SDL_Renderer *r, Ampler_state *state) { SDL_RenderDrawLine(r, snd->start / space, top, snd->start / space, bot); SDL_RenderDrawLine(r, snd->end / space, top, snd->end / space, bot); } +} - static u8 markov[256][256]; - SDL_memset(markov, 0, sizeof markov); - for int x = 0; x < FRAME_SAMPLES - 1; x += 1 do { - u8 cur = state->frame_mix[0][x] + 128; - u8 next = state->frame_mix[0][x + 1] + 128; +void draw_frame(SDL_Window *w, SDL_Renderer *r, Ampler_state *state) { + SDL_SetRenderDrawColor(r, 0x1D, 0x2B, 0x53, 255); - cur = state->frame_rec[0][x] + 128; - next = state->frame_rec[0][x + 1] + 128; + SDL_SetRenderDrawBlendMode(r, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawBlendMode(r, SDL_BLENDMODE_NONE); + SDL_SetRenderDrawColor(r, 10, 10, 10, 40); + SDL_Rect screen = { 0, 0, /*512*/ FRAME_SAMPLES, 512 }; + SDL_RenderFillRect(r, &screen); + // SDL_RenderClear(r); - markov[cur][next] += 1; - } + //markov_draw(&(state->markov), r); + SDL_memset(&(state->markov), 0, sizeof state->markov); + markov_gen(&(state->markov), state->frame_mix[1]); + markov_draw(&(state->markov), r); + + SDL_RenderPresent(r); /* - for int x = 0; x < 256; x += 1 do { - u8 to = 0; - for int y = 0; y < 255; y += 1 do to += markov[x][y]; - markov[x][255] = to; - } + for int x = 0; x < 256; x += 1 do + // for int y = 0; y < markov_lens[x]; y += 1 do { + for int y = 0; y < 256; y += 1 do { + s32 m = markov[x + y * 256]; + 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); + 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); + } + } */ - int start_x = 255, end_x = 0; + /* + for int x = 0; x < FRAME_SAMPLES - 1; x += 1 do { + // playing + u8 cur = state->frame_mix[0][x] + 128; + u8 next = state->frame_mix[0][x + 1] + 128; + // recing + //cur = state->frame_rec[0][x] + 128; + //next = state->frame_rec[0][x + 1] + 128; + markov[cur + next * 256] += 1; + } + int start_x = 0, end_x = 255; + + // converts from graph plot to prob table for int x = 0; x < 256; x += 1 do { // for each colum // copy into temp col, store how filed, col is @@ -64,32 +84,16 @@ void draw_frame(SDL_Window *w, SDL_Renderer *r, Ampler_state *state) { // for remainder of col fill with re-roll value u8 temp[256] = { 0 }; // amount of each dest, by index for int i = 0; i < 256; i++ - do temp[i] = markov[x][i]; + do temp[i] = markov[x + i * 256]; s32 next = 0; - for int i = 0; i < 256; i++ do + for int i = 0; i < 256; i++ do { for int j = 0; j < temp[i] and next < 256; j++ do { - markov[x][next++] = i; + markov[x + (next++) * 256] = i; if x < start_x do start_x = x; if x > end_x do end_x = x; } - } - - //for int x = 0; x < 256; x++ do markov[x][0] = x, markov[0][x] = x; - - for int x = start_x; x < end_x; x += 1 do - for int y = 0; y < 256; y += 1 do { - s32 m = markov[x][255 - 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); - if m != 0 do { - SDL_RenderDrawPoint(r, x * 2, y * 2); - SDL_RenderDrawPoint(r, x * 2 + 1, y * 2); - SDL_RenderDrawPoint(r, x * 2, y * 2 + 1); - SDL_RenderDrawPoint(r, x * 2 + 1, y * 2 + 1); - } + markov_lens[x] = next; } - - SDL_RenderPresent(r); + } + */ } diff --git a/markov.c b/markov.c new file mode 100644 index 0000000..12f4571 --- /dev/null +++ b/markov.c @@ -0,0 +1,102 @@ +// 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); + } + } +} + + + diff --git a/random.c b/random.c new file mode 100644 index 0000000..4910e07 --- /dev/null +++ b/random.c @@ -0,0 +1,59 @@ +// random.c + +// !!!!YOU WERE HERE!!!!!// +// MAKE A DOOM STYLE SHUFFLED RANDOMIZER, FOR JUST 8 BITS +// + +// original uses unsigned long, tcc says that it's 4 bytes +// public domain impl from: +// http://lomont.org/papers/2008/Lomont_PRNG_2008.pdf +u32 well_512() { + // TODO: Make this more random / make sure it's correct ? + /* new Uint32Array([2 << 30]).map(x => Math.random() * x).join(",\n") */ + static u32 state[16] = { + 1096601398, 347948986, 707021053, 1924450882, + 1184298871, 1860618357, 1301703596, 86165936, + 160838326, 1276044826, 98793404, 1014941842, + 1604941344,1520346171, 726203645, 1872316350, + }; + + static u32 index = 0; + + + u32 a, b, c, d; + a = state[index]; + c = state[(index + 13) & 15]; + b = a ^ c ^ (a << 16) ^ (c << 15); + c = state[(index + 9) & 15]; + c ^= (c >> 11); + a = state[index] = b ^ c; + d = a ^ ((a << 5) & 0xda442d24UL); + index = (index + 15) & 15; + a = state[index]; + state[index] = a ^ b ^ d ^ (a << 2) ^ (b << 18) ^ (c << 28); + return state[index]; +} + +u8 rnd_u8() { + return well_512() & 0xff; +} + + + + + + + + + + + + + + + + + + + +