From 6b3c8210b5cbad1be7c315f25d53e51bfee80e1e Mon Sep 17 00:00:00 2001 From: bx Date: Mon, 27 Dec 2021 06:23:29 +0000 Subject: [PATCH] visualiser now runns on defaut input device --- ampler.c | 20 ++++++++++++++++---- ampler.h | 2 ++ audio.c | 26 +++++++++++++++++++++++++- draw.c | 4 ++++ 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/ampler.c b/ampler.c index 3af3f7f..8743ec1 100644 --- a/ampler.c +++ b/ampler.c @@ -29,11 +29,21 @@ Ampler_state *init() { if !(state -> playdev) do puts(SDL_GetError()); + state -> recdev = SDL_OpenAudioDevice( + NULL, // default device + 1, // is capture + &want, + &have, + 0 // no changes allowed + ); + if !(state -> playdev) do + puts(SDL_GetError()); + // TODO: iterate a directory to load samples - //load_sample(state, "mix.wav"); - //load_sample(state, "loop2.wav"); - //load_sample(state, "loop.wav"); - //load_sample(state, "chord.wav"); + //load_sample(state, "./mix.wav"); + //load_sample(state, "./loop2.wav"); + //load_sample(state, "./loop.wav"); + //load_sample(state, "./chord.wav"); puts("init."); return state; @@ -60,6 +70,7 @@ int ampler_main(SDL_Window *w, SDL_Renderer *r, Ampler_state **u_data) { // put results in state for last frame's perf, so that we can draw it SDL_SetWindowTitle(w, "ampler"); SDL_PauseAudioDevice(state -> playdev, 0); // unpause audio + SDL_PauseAudioDevice(state -> recdev, 0); // unpause audio udp_init(state); while 1 do { SDL_Event e; @@ -80,6 +91,7 @@ int ampler_main(SDL_Window *w, SDL_Renderer *r, Ampler_state **u_data) { if !remove("reload-trigger") do { SDL_PauseAudioDevice(state -> playdev, 1); // pause audio + SDL_PauseAudioDevice(state -> recdev, 1); // pause audio udp_quit(state); puts("removed reload-trigger, reloading..."); return 0; diff --git a/ampler.h b/ampler.h index aacb853..5fa1cf2 100644 --- a/ampler.h +++ b/ampler.h @@ -63,10 +63,12 @@ typedef struct Ampler_state Ampler_state; struct Ampler_state { u32 size; // in bytes, off this struct SDL_AudioDeviceID playdev; + SDL_AudioDeviceID recdev; Sound_src sounds[64]; s32 played_audio_last_frame; Udp_msg messages[64]; s8 frame_mix[CHANNELS][FRAME_SAMPLES]; + s8 frame_rec[CHANNELS][FRAME_SAMPLES]; }; diff --git a/audio.c b/audio.c index d2d0055..0a960dc 100644 --- a/audio.c +++ b/audio.c @@ -60,7 +60,31 @@ void sound_src_frame(Sound_src *s, s8 *mix[]) { } } +void rec_frame(Ampler_state *state) { + // const int frame_bytes = FRAME_SAMPLES * CHANNELS * sizeof(s16); + static s16 buf[FRAME_SAMPLES * CHANNELS * sizeof(s16)]; + + u32 samps = SDL_GetQueuedAudioSize(state->recdev) / sizeof(s16); + + // TODO: this introduces a frame of lag, but should make sure we always + // deque a full frame, maybe find a less laggy way ? + if samps > FRAME_SAMPLES * CHANNELS * 2 do { + u32 bytes = SDL_DequeueAudio(state->recdev, buf, sizeof(buf)); + // printf("%i %i %i samples\n", samps, bytes / sizeof(s16), sizeof(buf) / 2); + } + + // TODO: test with stero recording input to make sure this works + for int i = 0; i < FRAME_SAMPLES; i += 1 do + for int c = 0; c < CHANNELS; c += 1 do { + state->frame_rec[c][i] = buf[i * CHANNELS + c] >> 8; + } +} + int audio_frame(Ampler_state *state) { + // TODO: it's unlikely but possible that we can miss recorded data because + // gur rec buffer was filled on a frame where we didn't play anything + rec_frame(state); + int queued = SDL_GetQueuedAudioSize(state -> playdev); queued /= sizeof (s16); // queued is in bytes @@ -107,7 +131,7 @@ void load_sample(Ampler_state *state, const char *file_name) { s16 *buffer = NULL; u32 bytes = 0; - SDL_LoadWAV(file_name, &spec, &buffer, &bytes); + SDL_LoadWAV(file_name, &spec, (u8 **) &buffer, &bytes); if spec.format != AUDIO_S16 do { puts("error: sample.wav is not s16"); diff --git a/draw.c b/draw.c index 47057ec..b6b98fc 100644 --- a/draw.c +++ b/draw.c @@ -40,6 +40,10 @@ void draw_frame(SDL_Window *w, SDL_Renderer *r, Ampler_state *state) { 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; }