From 412d2588cb0373ae3a3e0bcfb134a08799360fe9 Mon Sep 17 00:00:00 2001 From: bxwtf Date: Sun, 19 Dec 2021 22:44:48 +0000 Subject: [PATCH] audio finally loads and plays --- .gitignore | 1 + ampler.c | 55 +++++++++++++-------------------------------------- ampler.h | 35 ++++++++++++++++++++++++++++++++ audio.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++------- core.c | 2 +- draw.c | 5 +++++ 6 files changed, 107 insertions(+), 49 deletions(-) create mode 100644 ampler.h create mode 100644 draw.c diff --git a/.gitignore b/.gitignore index 32d7226..5075450 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.exe *.dll reload-trigger +*.wav diff --git a/ampler.c b/ampler.c index ffb9cc5..79e945a 100644 --- a/ampler.c +++ b/ampler.c @@ -6,39 +6,10 @@ #include -#define SAMPLE_RATE (44100) -#define CHANNELS (2) -#define FRAME_SAMPLES (SAMPLE_RATE / 60) +#include "ampler.h" -typedef uint8_t s8; -typedef uint16_t s16; - -typedef struct Ampler_state Ampler_state; -struct Ampler_state { - int size; - SDL_AudioDeviceID playdev; - s8 track_l[SAMPLE_RATE * 120]; // 2 minutes - s8 track_r[SAMPLE_RATE * 120]; // 2 minutes -}; - -int audio_frame(Ampler_state *state) { - int queued = SDL_GetQueuedAudioSize(state -> playdev); - queued /= sizeof s16; // queued is in bytes - - if(queued > FRAME_SAMPLES * CHANNELS * 2) return 0; - // else puts("queued audio."); - - s16 silence[FRAME_SAMPLES * CHANNELS] = { 0 }; - for (int i = 0; i < FRAME_SAMPLES; i += CHANNELS) { - int vol = 10; - silence[i] = (i/2) * vol - FRAME_SAMPLES / 2; - silence[i + 1] = (i/2) * vol - FRAME_SAMPLES / 2; - } - if(SDL_QueueAudio(state -> playdev, silence, sizeof silence)) - puts(SDL_GetError()); - - return 1; // audio was qued -} +#include "audio.c" +#include "draw.c" Ampler_state *init() { Ampler_state *state = malloc(sizeof Ampler_state); @@ -61,7 +32,7 @@ Ampler_state *init() { &have, 0 // no changes allowed ); - if(!(state -> playdev)) + if !(state -> playdev) do puts(SDL_GetError()); puts("init."); @@ -69,10 +40,10 @@ Ampler_state *init() { } int ampler_main(SDL_Window *w, SDL_Renderer *r, Ampler_state **u_data) { - if(*u_data == NULL) *u_data = init(); + if *u_data == NULL do *u_data = init(); - int old_size = (*u_data) -> size, new_size = sizeof Ampler_state; - if(old_size < new_size) { + u32 old_size = (*u_data) -> size, new_size = sizeof Ampler_state; + if old_size < new_size do { printf("increasing size. %i to %i\n", old_size, new_size); Ampler_state *nu = malloc(new_size); SDL_memset(nu, 0, new_size); @@ -84,20 +55,22 @@ int ampler_main(SDL_Window *w, SDL_Renderer *r, Ampler_state **u_data) { Ampler_state *state = *u_data; + load_track(state); + SDL_PauseAudioDevice(state -> playdev, 0); // unpause audio - while (1) { + while 1 do { SDL_Event e; - while(SDL_PollEvent(&e)) - if (e.type == SDL_QUIT) + while SDL_PollEvent(&e) do + if e.type == SDL_QUIT do return 1; audio_frame(state); - // draw_frame(w, r, state); + draw_frame(w, r, state); SDL_RenderPresent(r); SDL_Delay(1); - if (!remove("reload-trigger")) { + if !remove("reload-trigger") do { SDL_PauseAudioDevice(state -> playdev, 1); // pause audio puts("removed reload-trigger, reloading..."); return 0; diff --git a/ampler.h b/ampler.h new file mode 100644 index 0000000..579a4ca --- /dev/null +++ b/ampler.h @@ -0,0 +1,35 @@ +// ampler.h + +#define if if( +#define while while( +#define for for( +#define do ) + +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; + +typedef float f32; +typedef double f64; + + + + +#define arraylen(a) (sizeof (a) / sizeof ((a)[0])) + +#define SAMPLE_RATE (44100) +#define CHANNELS (2) +#define FRAME_SAMPLES (SAMPLE_RATE / 60) + +typedef struct Ampler_state Ampler_state; +struct Ampler_state { + u32 size; + SDL_AudioDeviceID playdev; + s8 track_l[SAMPLE_RATE * 120]; // 2 minutes + s8 track_r[SAMPLE_RATE * 120]; // 2 minutes +}; + diff --git a/audio.c b/audio.c index cec4486..71ab628 100644 --- a/audio.c +++ b/audio.c @@ -4,18 +4,62 @@ int audio_frame(Ampler_state *state) { int queued = SDL_GetQueuedAudioSize(state -> playdev); queued /= sizeof s16; // queued is in bytes - if(queued > FRAME_SAMPLES * CHANNELS * 2) return 0; + if queued > FRAME_SAMPLES * CHANNELS * 2 do return 0; // else puts("queued audio."); - s16 silence[FRAME_SAMPLES * CHANNELS] = { 0 }; - for (int i = 0; i < FRAME_SAMPLES; i += CHANNELS) { - int vol = 10; - silence[i] = (i/2) * vol - FRAME_SAMPLES / 2; - silence[i + 1] = (i/2) * vol - FRAME_SAMPLES / 2; + static s16 frame[SAMPLE_RATE * CHANNELS * 7] = { 0 }; + for int i = 0; i < arraylen(frame); i += CHANNELS do { + int vol = 64; + frame[i] = ((s16) (state -> track_l[i])) * vol; + frame[i + 1] = ((s16) (state -> track_r[i])) * vol; } - if(SDL_QueueAudio(state -> playdev, silence, sizeof silence)) + if SDL_QueueAudio(state -> playdev, frame, sizeof frame) do puts(SDL_GetError()); return 1; // audio was qued } +void load_track(Ampler_state *state) { + SDL_AudioSpec spec; + s16 *buffer = NULL; + u32 bytes = 0; + + SDL_LoadWAV("sample.wav", &spec, &buffer, &bytes); + + if spec.format != AUDIO_S16 do { + puts("error: sample.wav is not s16"); + return; + } + + const int len = bytes / sizeof s16; + + // TODO: Use floats to print out total number of seconds + printf("loading sample.wav\n"); + + s8 *tracks[] = { state -> track_l, state -> track_r, }; + for int i = 0; i < len; i += spec.channels do + for int c = 0; c < spec.channels; c++ do { + tracks[c][i] = (s8) (buffer[i + c] >> 8); + } + + SDL_FreeWAV((void *) buffer); +} + +void load_track_f32() { // idk if we're ever gonna be loading floats + /* + f32 max = 0.0f; + for int i = 0; i < len; i++ do + if buffer[i] > max do + max = buffer[i]; + else if buffer[i] < -max do + max = -buffer[i]; + printf("%f max\n", max); + for int i = 0; i < len; i += 2 do { + buffer[i] /= max; + buffer[i + 1] /= max; + state -> track_l[i] = ((s8)(buffer[i] * 127.0f)); + state -> track_r[i] = ((s8)(buffer[i + 1] * 127.0f)); + } + */ +} + diff --git a/core.c b/core.c index 3229bc8..49d3c62 100644 --- a/core.c +++ b/core.c @@ -21,7 +21,7 @@ int main(int argc, char **argv) { w = SDL_CreateWindow("core", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - 480, 480, SDL_WINDOW_RESIZABLE); + 512, 512, SDL_WINDOW_RESIZABLE); r = SDL_CreateRenderer(w, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); diff --git a/draw.c b/draw.c new file mode 100644 index 0000000..7df037d --- /dev/null +++ b/draw.c @@ -0,0 +1,5 @@ +// draw.c + +void draw_frame(SDL_Window *w, SDL_Renderer *r, Ampler_state *state) { + // todo: draw track l / r wave forms +}