From 92d3e150cbf494cd00c762408e6c78a01d42ceb3 Mon Sep 17 00:00:00 2001 From: Sheldon Lee Date: Sun, 13 Oct 2024 14:06:35 +0800 Subject: [PATCH] Better manage devices/memory management --- main.c | 142 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 78 insertions(+), 64 deletions(-) diff --git a/main.c b/main.c index 70d24d9..c63cafb 100644 --- a/main.c +++ b/main.c @@ -8,7 +8,6 @@ const int SCREEN_HEIGHT = 480; const int MAX_RECORDING_DEVICES = 10; const int MAX_RECORDING_SECONDS = 1; -const int RECORDING_BUFFER_SECONDS = MAX_RECORDING_SECONDS + 1; /* * Application */ @@ -60,15 +59,13 @@ SDL_AudioSpec received_playback_spec; Uint8* recording_buffer = NULL; unsigned int recording_buffer_size = 0; unsigned int recording_buffer_position = 0; -unsigned int recording_buffer_position_max = 0; -SDL_AudioDeviceID audio_recording_init(int index, void* userdata); -SDL_AudioDeviceID audio_playback_init(void* userdata); -void audio_buffer_destroy(); +SDL_AudioDeviceID audio_recording_init(int index); +SDL_AudioDeviceID audio_playback_init(); void audio_recording_callback( void* userdata, Uint8* stream, int len ); void audio_playback_callback( void* userdata, Uint8* stream, int len ); -void handle_input(SDL_Event* event, state* state); +int handle_input(SDL_Event* event, state* state); void handle_task(state* state); int main(int argc, char* argv[]) { @@ -103,6 +100,22 @@ int main(int argc, char* argv[]) application_state_to_string(state.application_state, char_buffer); text_texture_load(&state_text_texture, char_buffer); + SDL_zero(recording_spec); + recording_spec.freq = 44100; + recording_spec.format = AUDIO_S16; + recording_spec.channels = 2; + recording_spec.samples = 4096; + recording_spec.callback = audio_recording_callback; + recording_spec.userdata = &state; + + SDL_zero(playback_spec); + playback_spec.freq = 44100; + playback_spec.format = AUDIO_S16; + playback_spec.channels = 2; + playback_spec.samples = 4096; + playback_spec.callback = audio_playback_callback; + playback_spec.userdata = &state; + SDL_Event event; while (1) { while (SDL_PollEvent(&event)) { @@ -114,7 +127,7 @@ int main(int argc, char* argv[]) break; case SDL_KEYDOWN: - handle_input(&event, &state); + if (!handle_input(&event, &state)) goto cleanup; break; } @@ -150,7 +163,7 @@ int main(int argc, char* argv[]) } cleanup: - printf("Cleanup"); + printf("Cleanup\n"); SDL_CloseAudioDevice(state.recording_device_id); SDL_CloseAudioDevice(state.playback_device_id); text_texture_free(&display_text_texture); @@ -162,7 +175,7 @@ cleanup: return 0; } -void handle_input(SDL_Event* event, state* state) +int handle_input(SDL_Event* event, state* state) { SDL_Keycode keysym = event->key.keysym.sym; switch (state->application_state) { @@ -171,23 +184,28 @@ void handle_input(SDL_Event* event, state* state) switch (keysym) { case SDLK_y: case SDLK_RETURN: - if (state->recording_device_id) - SDL_CloseAudioDevice(state->recording_device_id); - state->recording_device_id = audio_recording_init(state->device_index, NULL); + /*if (state->recording_device_id)*/ + /* SDL_CloseAudioDevice(state->recording_device_id);*/ + /*state->recording_device_id = audio_recording_init(state->device_index, NULL);*/ if (state->device_index == -1 || !state->recording_device_id) break; + SDL_LockAudioDevice(state->recording_device_id); + memset(recording_buffer, 0, recording_buffer_size); recording_buffer_position = 0; + SDL_UnlockAudioDevice(state->recording_device_id); SDL_PauseAudioDevice(state->recording_device_id, 0); state->application_state = RECORDING; break; + case SDLK_q: case SDLK_ESCAPE: - /*state->device_index = -1;*/ - /*SDL_CloseAudioDevice(state->recording_device_id);*/ + return 0; break; } int device_index_new = select_device(&event->key, num_devices); if (device_index_new == -1) break; - if (state->device_index != -1 && device_index_new == -1) break; + if (device_index_new == state->device_index) break; state->device_index = device_index_new; + SDL_CloseAudioDevice(state->recording_device_id); + state->recording_device_id = audio_recording_init(state->device_index); break; @@ -196,7 +214,6 @@ void handle_input(SDL_Event* event, state* state) case SDLK_q: case SDLK_ESCAPE: SDL_PauseAudioDevice(state->recording_device_id, 1); - audio_buffer_destroy(); state->application_state = SELECTING_DEVICE; break; } @@ -206,16 +223,16 @@ void handle_input(SDL_Event* event, state* state) switch (keysym) { case SDLK_y: case SDLK_RETURN: - if (state->playback_device_id) - SDL_CloseAudioDevice(state->playback_device_id); - state->playback_device_id = audio_playback_init(NULL); + if (!state->playback_device_id) + state->playback_device_id = audio_playback_init(); + SDL_LockAudioDevice(state->playback_device_id); recording_buffer_position = 0; + SDL_UnlockAudioDevice(state->playback_device_id); SDL_PauseAudioDevice(state->playback_device_id, 0); state->application_state = PLAYBACK; break; case SDLK_q: case SDLK_ESCAPE: - audio_buffer_destroy(); state->application_state = SELECTING_DEVICE; break; } @@ -232,6 +249,7 @@ void handle_input(SDL_Event* event, state* state) break; } + return 1; } void handle_task(state* state) @@ -242,28 +260,16 @@ void handle_task(state* state) break; case RECORDING: - SDL_LockAudioDevice(state->recording_device_id); - if (recording_buffer_position >= recording_buffer_position_max) { - SDL_UnlockAudioDevice(state->recording_device_id); - SDL_CloseAudioDevice(state->recording_device_id); + if (recording_buffer_position >= recording_buffer_size) state->application_state = RECORDED; - break; - } - SDL_UnlockAudioDevice(state->recording_device_id); break; case RECORDED: break; case PLAYBACK: - SDL_LockAudioDevice(state->playback_device_id); - if (recording_buffer_position >= recording_buffer_position_max) { - SDL_UnlockAudioDevice(state->playback_device_id); - SDL_CloseAudioDevice(state->playback_device_id); + if (recording_buffer_position >= recording_buffer_size) state->application_state = RECORDED; - break; - } - SDL_UnlockAudioDevice(state->playback_device_id); break; } @@ -302,20 +308,6 @@ int init() return 0; } - SDL_zero(recording_spec); - recording_spec.freq = 44100; - recording_spec.format = AUDIO_S16; - recording_spec.channels = 2; - recording_spec.samples = 4096; - recording_spec.callback = audio_recording_callback; - - SDL_zero(playback_spec); - playback_spec.freq = 44100; - playback_spec.format = AUDIO_S16; - playback_spec.channels = 2; - playback_spec.samples = 4096; - playback_spec.callback = audio_playback_callback; - return 1; } @@ -432,7 +424,7 @@ int text_texture_free(text_texture* text_texture) return 1; } -SDL_AudioDeviceID audio_recording_init(int index, void* userdata) +SDL_AudioDeviceID audio_recording_init(int index) { SDL_AudioDeviceID device_id = SDL_OpenAudioDevice(SDL_GetAudioDeviceName(index, 1), 1, &recording_spec, &received_recording_spec, SDL_AUDIO_ALLOW_FORMAT_CHANGE); printf("Recording Device: %s\n", SDL_GetAudioDeviceName(index, 1)); @@ -443,16 +435,16 @@ 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; - recording_buffer_size = RECORDING_BUFFER_SECONDS * bytes_per_second; - recording_buffer_position_max = MAX_RECORDING_SECONDS * bytes_per_second; + recording_buffer_size = MAX_RECORDING_SECONDS * bytes_per_second; + if (recording_buffer) free(recording_buffer); recording_buffer = malloc(recording_buffer_size); memset(recording_buffer, 0, recording_buffer_size); return device_id; } -SDL_AudioDeviceID audio_playback_init(void* userdata) +SDL_AudioDeviceID audio_playback_init() { if (!recording_buffer) { printf("Audio buffer not initialized"); @@ -475,28 +467,50 @@ int audio_device_stop(int device_id) return 1; } -void audio_buffer_destroy() -{ - free(recording_buffer); - recording_buffer = NULL; - recording_buffer_size = 0; - recording_buffer_position = 0; -} - void audio_recording_callback(void* userdata, Uint8* stream, int len) { + char string[64]; + state* state = userdata; + + int space_left = recording_buffer_size - recording_buffer_position; + if (space_left <= 0) { + sprintf(string, "Stopping recording ID: %i", state->recording_device_id); + log_message(LOG_INFO, string); + SDL_PauseAudioDevice(state->recording_device_id, 1); + return; + } + + if (len > space_left) { + len = space_left; + } + memcpy(&recording_buffer[recording_buffer_position], stream, len); recording_buffer_position += len; - char string[64]; - sprintf(string, "Record pos: %u %u", recording_buffer_position, len); + + sprintf(string, "Record pos: %u/%u (%u)", recording_buffer_position, recording_buffer_size, len); log_message(LOG_INFO, string); } void audio_playback_callback(void* userdata, Uint8* stream, int len) { + char string[64]; + state* state = userdata; + + int space_left = recording_buffer_size - recording_buffer_position; + if (space_left <= 0) { + sprintf(string, "Stopping playback ID: %i", state->recording_device_id); + log_message(LOG_INFO, string); + SDL_PauseAudioDevice(state->playback_device_id, 1); + return; + } + + if (len > space_left) { + len = space_left; + } + memcpy(stream, &recording_buffer[recording_buffer_position], len); recording_buffer_position += len; - char string[64]; - sprintf(string, "Playback pos: %u %u", recording_buffer_position, len); + + sprintf(string, "Playback pos: %u/%u (%u)", recording_buffer_position, recording_buffer_size, len); log_message(LOG_INFO, string); }