From 0b8f5a562048c4b040a1799b47e70b5a96eb6c85 Mon Sep 17 00:00:00 2001 From: Sheldon Lee Date: Thu, 10 Oct 2024 20:53:49 +0800 Subject: [PATCH] Add comments and README --- README.md | 14 +++++++++++ example-test-code/README.md | 1 + main.c | 50 +++++++++++++++++++++++++++---------- 3 files changed, 52 insertions(+), 13 deletions(-) create mode 100644 README.md create mode 100644 example-test-code/README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..ca9f9ea --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +Make run to compile and run +``` +make run +``` +I'm using the whole new pipewire + wireplumber audio stack, which has +compatibility with pulse audio. + +Seems like there is ``SDL_AUDIODRIVER=alsa`` environment variable that SDL can +use. I don't think my code works with this enabled. + +[Maybe related GitHub issue](https://github.com/libsdl-org/SDL/issues/9706) + +I'm using SDL2 version 2.28.5. Downgrading from 2.30.7 seems to make it work a +bit better, but still not consistent. diff --git a/example-test-code/README.md b/example-test-code/README.md new file mode 100644 index 0000000..4690677 --- /dev/null +++ b/example-test-code/README.md @@ -0,0 +1 @@ +Some code here is from ChatGPT diff --git a/main.c b/main.c index e025d94..2b179e2 100644 --- a/main.c +++ b/main.c @@ -5,7 +5,9 @@ #include #include "log.h" - +/* + * INFO: I will mark places to look at with INFO: + */ const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; @@ -52,7 +54,7 @@ int text_texture_load(text_texture* text_texture, char* string); int text_texture_render(text_texture* text_texture, int x, int y); int text_texture_free(text_texture* text_texture); /* - * Audio + * Audio INFO: audio related declarations and callback here. */ int num_devices = 0; @@ -107,23 +109,24 @@ int main(int argc, char* argv[]) text_texture_load(&state_text_texture, char_buffer); SDL_Event event; - int running = 1; - while (running) { + while (1) { while (SDL_PollEvent(&event)) { SDL_Keycode keysym = event.key.keysym.sym; switch (event.type) { case SDL_QUIT: - running = 0; + goto cleanup; break; case SDL_KEYDOWN: + // INFO: main state logic here. handle_input(&event, &state); break; } } + // INFO: more state logic here. I check the buffer write position here handle_task(&state); sprintf(char_buffer, default_fmt, state.device_index); @@ -153,6 +156,9 @@ int main(int argc, char* argv[]) SDL_RenderPresent(renderer); } +cleanup: + SDL_CloseAudioDevice(state.recording_device_id); + SDL_CloseAudioDevice(state.playback_device_id); text_texture_free(&display_text_texture); for (int i = 0; i < num_devices; i++) { text_texture_free(&device_textures[i]); @@ -166,17 +172,24 @@ void handle_input(SDL_Event* event, state* state) { SDL_Keycode keysym = event->key.keysym.sym; switch (state->application_state) { - + // INFO: init of recording audio device here case SELECTING_DEVICE: switch (keysym) { case SDLK_y: case SDLK_RETURN: + // INFO: init audio device here and below + // Here it initialises everytime you press enter or y, and + // unpauses device immediately. Seems to work mor consistently SDL_CloseAudioDevice(state->recording_device_id); - state->recording_device_id = audio_recording_init(state->device_index, NULL); + state->recording_device_id = + audio_recording_init(state->device_index, NULL); + if (state->device_index == -1 || !state->recording_device_id) break; recording_buffer_position = 0; + // INFO: calling this should unpause the device and start calling the callback SDL_PauseAudioDevice(state->recording_device_id, 0); /*SDL_UnlockAudioDevice(state->recording_device_id);*/ + // INFO: state change looks like this here state->application_state = RECORDING; break; case SDLK_ESCAPE: @@ -188,6 +201,12 @@ void handle_input(SDL_Event* event, state* state) if (device_index_new == -1) break; if (state->device_index != -1 && device_index_new == -1) break; state->device_index = device_index_new; + // INFO: inititialising here seems to be less consistent. When I + // spam enter or y after initialising here, Sometimes I see + // callback being called sometimes not. + /*SDL_CloseAudioDevice(state->recording_device_id);*/ + /*state->recording_device_id = audio_recording_init(state->device_index, NULL);*/ + break; case RECORDING: @@ -203,7 +222,7 @@ void handle_input(SDL_Event* event, state* state) break; } break; - + // INFO: init of playback audio device here. Can't seem to get it to play / call callback case RECORDED: switch (keysym) { case SDLK_y: @@ -243,6 +262,7 @@ void handle_task(state* state) break; case RECORDING: + // INFO: check buffer position here and stop if reaces the end SDL_LockAudioDevice(state->recording_device_id); /*printf("buf pos: %u\n", recording_buffer_position);*/ if (recording_buffer_position >= recording_buffer_position_max) { @@ -259,6 +279,7 @@ void handle_task(state* state) break; case PLAYBACK: + // INFO: SDL_LockAudioDevice(state->playback_device_id); if (recording_buffer_position >= recording_buffer_position_max) { SDL_UnlockAudioDevice(state->playback_device_id); @@ -421,9 +442,11 @@ int text_texture_free(text_texture* text_texture) SDL_DestroyTexture(text_texture->texture); return 1; } - +// INFO: device init here +// Most of the audio stuff I copied from an example SDL_AudioDeviceID audio_recording_init(int index, void* userdata) { + // INFO: audio spec and callback SDL_zero(recording_spec); recording_spec.freq = 44100; recording_spec.format = AUDIO_F32; @@ -441,6 +464,7 @@ SDL_AudioDeviceID audio_recording_init(int index, void* userdata) unsigned int bytes_per_sample = received_recording_spec.channels * (SDL_AUDIO_BITSIZE(received_recording_spec.format)/8); unsigned int bytes_per_second = received_recording_spec.freq * bytes_per_sample; + // INFO: I just copied example where they allocated 1 second worth of buffer so it doesn't die recording_buffer_size = RECORDING_BUFFER_SECONDS * bytes_per_second; recording_buffer_position_max = MAX_RECORDING_SECONDS * bytes_per_second; @@ -449,14 +473,14 @@ SDL_AudioDeviceID audio_recording_init(int index, void* userdata) return device_id; } - +// INFO: SDL_AudioDeviceID audio_playback_init(void* userdata) { if (!recording_buffer) { printf("Audio buffer not initialized"); return 0; } - + // INFO: audio spec and callback SDL_zero(playback_spec); playback_spec.freq = 44100; playback_spec.format = AUDIO_F32; @@ -488,7 +512,7 @@ void audio_buffer_destroy() recording_buffer_size = 0; recording_buffer_position = 0; } - +// INFO: callback here void audio_recording_callback(void* userdata, Uint8* stream, int len) { memcpy(&recording_buffer[recording_buffer_position], stream, len); @@ -498,7 +522,7 @@ void audio_recording_callback(void* userdata, Uint8* stream, int len) printf(string, "Record pos: %u %u\n", recording_buffer_position, len); log_message(LOG_INFO, string); } - +// INFO: void audio_playback_callback(void* userdata, Uint8* stream, int len) { memcpy(stream, &recording_buffer[recording_buffer_position], len);