last commit of markov thing, gonna try change to granular stuff now

master
bx 2022-02-10 19:26:20 +00:00
parent 91f280ba3a
commit d6b6846669
6 changed files with 236 additions and 47 deletions

View File

@ -2,6 +2,8 @@
#include "ampler.h" #include "ampler.h"
#include "random.c"
#include "markov.c"
#include "audio.c" #include "audio.c"
#include "draw.c" #include "draw.c"
@ -41,6 +43,7 @@ Ampler_state *init() {
// TODO: iterate a directory to load samples // TODO: iterate a directory to load samples
//load_sample(state, "./mix.wav"); //load_sample(state, "./mix.wav");
load_sample(state, "./haunted.wav");
//load_sample(state, "./loop2.wav"); //load_sample(state, "./loop2.wav");
//load_sample(state, "./loop.wav"); //load_sample(state, "./loop.wav");
//load_sample(state, "./chord.wav"); //load_sample(state, "./chord.wav");

View File

@ -13,6 +13,7 @@ typedef int32_t s32;
typedef uint8_t u8; typedef uint8_t u8;
typedef uint16_t u16; typedef uint16_t u16;
typedef uint32_t u32; typedef uint32_t u32;
typedef uint64_t u64;
typedef float f32; typedef float f32;
typedef double f64; typedef double f64;
@ -59,6 +60,13 @@ struct Udp_msg {
enum { MSG_FREE = 0, MSG_TRIGGER, } state; 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; typedef struct Ampler_state Ampler_state;
struct Ampler_state { struct Ampler_state {
u32 size; // in bytes, off this struct u32 size; // in bytes, off this struct
@ -69,6 +77,8 @@ struct Ampler_state {
Udp_msg messages[64]; Udp_msg messages[64];
s8 frame_mix[CHANNELS][FRAME_SAMPLES]; s8 frame_mix[CHANNELS][FRAME_SAMPLES];
s8 frame_rec[CHANNELS][FRAME_SAMPLES]; s8 frame_rec[CHANNELS][FRAME_SAMPLES];
Markov_4 markov;
}; };

11
audio.c
View File

@ -103,6 +103,16 @@ int audio_frame(Ampler_state *state) {
foreach_ptr(Sound_src, snd, state -> sounds) foreach_ptr(Sound_src, snd, state -> sounds)
sound_src_frame(snd, mix); 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; const int vol = 100;
static s16 frame[FRAME_SAMPLES * CHANNELS] = { 0 }; static s16 frame[FRAME_SAMPLES * CHANNELS] = { 0 };
for int i = 0; i < FRAME_SAMPLES; i += 1 do 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; u32 bytes = 0;
SDL_LoadWAV(file_name, &spec, (u8 **) &buffer, &bytes); SDL_LoadWAV(file_name, &spec, (u8 **) &buffer, &bytes);
// TODO: Check for error from LoadWAV
if spec.format != AUDIO_S16 do { if spec.format != AUDIO_S16 do {
puts("error: sample.wav is not s16"); puts("error: sample.wav is not s16");

98
draw.c
View File

@ -1,15 +1,6 @@
// draw.c // draw.c
void draw_frame(SDL_Window *w, SDL_Renderer *r, Ampler_state *state) { void draw_snd_waves(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);
// TODO: DRAW WITH X SCALE FACTOR // TODO: DRAW WITH X SCALE FACTOR
// TODO: DRAW SMOLER // TODO: DRAW SMOLER
SDL_SetRenderDrawColor(r, 0xFF, 0x00, 0x4D, 255); 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->start / space, top, snd->start / space, bot);
SDL_RenderDrawLine(r, snd->end / space, top, snd->end / 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;
cur = state->frame_rec[0][x] + 128;
next = state->frame_rec[0][x + 1] + 128;
markov[cur][next] += 1;
} }
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*/ FRAME_SAMPLES, 512 };
SDL_RenderFillRect(r, &screen);
// SDL_RenderClear(r);
//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 { for int x = 0; x < 256; x += 1 do
u8 to = 0; // for int y = 0; y < markov_lens[x]; y += 1 do {
for int y = 0; y < 255; y += 1 do to += markov[x][y]; for int y = 0; y < 256; y += 1 do {
markov[x][255] = to; 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 int x = 0; x < 256; x += 1 do {
// for each colum // for each colum
// copy into temp col, store how filed, col is // 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 // for remainder of col fill with re-roll value
u8 temp[256] = { 0 }; // amount of each dest, by index u8 temp[256] = { 0 }; // amount of each dest, by index
for int i = 0; i < 256; i++ for int i = 0; i < 256; i++
do temp[i] = markov[x][i]; do temp[i] = markov[x + i * 256];
s32 next = 0; 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 { 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 < start_x do start_x = x;
if x > end_x do end_x = x; if x > end_x do end_x = x;
} }
} markov_lens[x] = next;
//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);
} }
} }
*/
SDL_RenderPresent(r);
} }

102
markov.c 100644
View File

@ -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);
}
}
}

59
random.c 100644
View File

@ -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;
}