From 888faa063de8915e11abc42a658f568c938d4f8c Mon Sep 17 00:00:00 2001 From: cazz Date: Sun, 14 Dec 2025 12:31:57 -0500 Subject: [PATCH 1/8] feat: add bubble pop SFX with Pixabay attribution --- assets/sounds/README.md | 16 ++++++++++++++++ assets/sounds/bubble-pop.mp3 | Bin 0 -> 4368 bytes 2 files changed, 16 insertions(+) create mode 100644 assets/sounds/README.md create mode 100644 assets/sounds/bubble-pop.mp3 diff --git a/assets/sounds/README.md b/assets/sounds/README.md new file mode 100644 index 0000000..640159e --- /dev/null +++ b/assets/sounds/README.md @@ -0,0 +1,16 @@ +# Sounds + +## Attribution + +### `bubble-pop.mp3` + +Trimmed from a Pixabay sound effect. + +- Title: Bubble Pop 06 +- Creator: Universfield +- Source: [pixabay.com/sound-effects/bubble-pop-06-351337/](https://pixabay.com/sound-effects/bubble-pop-06-351337/) +- License: Pixabay Content License +- License summary: [pixabay.com/service/license-summary/](https://pixabay.com/service/license-summary/) +- License terms: [pixabay.com/service/terms/](https://pixabay.com/service/terms/) + +Optional credit line (Pixabay suggested): `by Universfield via Pixabay` diff --git a/assets/sounds/bubble-pop.mp3 b/assets/sounds/bubble-pop.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..d8065c6bc01ea7e3f823fae6c4620e3dd4b2079a GIT binary patch literal 4368 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 literal 0 HcmV?d00001 From 26ce909eb249123ad338565bae7b8c1da1e717af Mon Sep 17 00:00:00 2001 From: cazz Date: Sun, 14 Dec 2025 13:10:53 -0500 Subject: [PATCH 2/8] feat: add audio subsystem initialization --- src/helpers/audio.c | 96 +++++++++++++++++++++++++++++++++++++++++++++ src/helpers/audio.h | 31 +++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 src/helpers/audio.c create mode 100644 src/helpers/audio.h diff --git a/src/helpers/audio.c b/src/helpers/audio.c new file mode 100644 index 0000000..5992ca3 --- /dev/null +++ b/src/helpers/audio.c @@ -0,0 +1,96 @@ +#include "audio.h" + +#include +#include +#include + +bool audio_manager_create(audio_manager_t* manager) { + SDL_assert(manager != NULL); + + memset(manager, 0, sizeof(*manager)); + + if (SDL_InitSubSystem(SDL_INIT_AUDIO) == false) { + SDL_Log("Failed to initialize SDL audio subsystem: %s", SDL_GetError()); + return false; + } + + const SDL_AudioSpec spec = {.format = SDL_AUDIO_F32, .channels = 2, .freq = 44100}; + + manager->stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, NULL, NULL); + if (manager->stream == NULL) { + SDL_Log("Failed to open audio device stream: %s", SDL_GetError()); + SDL_QuitSubSystem(SDL_INIT_AUDIO); + return false; + } + + if (SDL_ResumeAudioStreamDevice(manager->stream) == false) { + SDL_Log("Failed to resume audio stream device: %s", SDL_GetError()); + SDL_DestroyAudioStream(manager->stream); + manager->stream = NULL; + SDL_QuitSubSystem(SDL_INIT_AUDIO); + return false; + } + + manager->is_initialized = true; + return true; +} + +void audio_manager_destroy(audio_manager_t* manager) { + SDL_assert(manager != NULL); + + if (manager->is_initialized == false) { + return; + } + + for (size_t i = 0; i < SOUND_COUNT; ++i) { + if (manager->sounds[i].buffer != NULL) { + SDL_free(manager->sounds[i].buffer); + manager->sounds[i].buffer = NULL; + } + manager->sounds[i].length = 0; + } + + if (manager->stream != NULL) { + SDL_DestroyAudioStream(manager->stream); + manager->stream = NULL; + } + + SDL_QuitSubSystem(SDL_INIT_AUDIO); + + manager->is_initialized = false; +} + +bool audio_manager_load_sound(audio_manager_t* manager, sound_id_t id, const char* filepath) { + SDL_assert(manager != NULL); + SDL_assert(filepath != NULL); + + if (manager->is_initialized == false) { + SDL_Log("Audio manager not initialized, cannot load sound: %s", filepath); + return false; + } + + if (id >= SOUND_COUNT) { + SDL_Log("Invalid sound ID: %d", id); + return false; + } + + // TODO: Implement sound loading + SDL_Log("Sound loading not yet implemented: %s", filepath); + return false; +} + +bool audio_manager_play_sound(audio_manager_t* manager, sound_id_t id) { + SDL_assert(manager != NULL); + + if (manager->is_initialized == false) { + return false; + } + + if (id >= SOUND_COUNT) { + SDL_Log("Invalid sound ID: %d", id); + return false; + } + + // TODO: Implement sound playback + return false; +} diff --git a/src/helpers/audio.h b/src/helpers/audio.h new file mode 100644 index 0000000..0c44556 --- /dev/null +++ b/src/helpers/audio.h @@ -0,0 +1,31 @@ +#ifndef AUDIO_H +#define AUDIO_H + +#include +#include +#include + +typedef enum { + SOUND_EAT_FOOD, + SOUND_COUNT // Must be last +} sound_id_t; + +typedef struct { + uint8_t* buffer; + size_t length; + SDL_AudioSpec spec; +} sound_data_t; + +typedef struct { + SDL_AudioStream* stream; + sound_data_t sounds[SOUND_COUNT]; + bool is_initialized; +} audio_manager_t; + +bool audio_manager_create(audio_manager_t* manager); +void audio_manager_destroy(audio_manager_t* manager); + +bool audio_manager_load_sound(audio_manager_t* manager, sound_id_t id, const char* filepath); +bool audio_manager_play_sound(audio_manager_t* manager, sound_id_t id); + +#endif // AUDIO_H From f79c3b68de9a57b6ae586e164978c5f0e94ee885 Mon Sep 17 00:00:00 2001 From: cazz Date: Sun, 14 Dec 2025 13:11:45 -0500 Subject: [PATCH 3/8] feat: implement sound loading and registration --- src/helpers/audio.c | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/src/helpers/audio.c b/src/helpers/audio.c index 5992ca3..5e81980 100644 --- a/src/helpers/audio.c +++ b/src/helpers/audio.c @@ -74,9 +74,45 @@ bool audio_manager_load_sound(audio_manager_t* manager, sound_id_t id, const cha return false; } - // TODO: Implement sound loading - SDL_Log("Sound loading not yet implemented: %s", filepath); - return false; + if (manager->sounds[id].buffer != NULL) { + SDL_Log("Sound already loaded for ID %d, skipping: %s", id, filepath); + return true; + } + + SDL_AudioSpec spec; + uint8_t* buffer = NULL; + Uint32 length = 0; + + if (SDL_LoadWAV(filepath, &spec, &buffer, &length) == false) { + SDL_Log("Failed to load audio file '%s': %s", filepath, SDL_GetError()); + return false; + } + + SDL_AudioSpec target_spec; + if (SDL_GetAudioStreamFormat(manager->stream, &target_spec, NULL) == false) { + SDL_Log("Failed to get audio stream format: %s", SDL_GetError()); + SDL_free(buffer); + return false; + } + + uint8_t* converted_buffer = NULL; + int converted_length = 0; + + if (SDL_ConvertAudioSamples(&spec, buffer, (int)length, &target_spec, &converted_buffer, &converted_length) == + false) { + SDL_Log("Failed to convert audio samples for '%s': %s", filepath, SDL_GetError()); + SDL_free(buffer); + return false; + } + + SDL_free(buffer); + + manager->sounds[id].buffer = converted_buffer; + manager->sounds[id].length = (size_t)converted_length; + manager->sounds[id].spec = target_spec; + + SDL_Log("Successfully loaded sound: %s (ID: %d, %d bytes)", filepath, id, converted_length); + return true; } bool audio_manager_play_sound(audio_manager_t* manager, sound_id_t id) { From ef5a9d07f6654a25666188c4dcaf67347cf8f3cf Mon Sep 17 00:00:00 2001 From: cazz Date: Sun, 14 Dec 2025 13:12:33 -0500 Subject: [PATCH 4/8] feat: implement sound playback mechanism --- src/helpers/audio.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/helpers/audio.c b/src/helpers/audio.c index 5e81980..3addd05 100644 --- a/src/helpers/audio.c +++ b/src/helpers/audio.c @@ -127,6 +127,16 @@ bool audio_manager_play_sound(audio_manager_t* manager, sound_id_t id) { return false; } - // TODO: Implement sound playback - return false; + if (manager->sounds[id].buffer == NULL) { + SDL_Log("Sound not loaded for ID %d, cannot play", id); + return false; + } + + if (SDL_PutAudioStreamData(manager->stream, manager->sounds[id].buffer, (int)manager->sounds[id].length) == + false) { + SDL_Log("Failed to queue audio data for playback: %s", SDL_GetError()); + return false; + } + + return true; } From 72c607c7e72b29da5d25fc61b57607e85033060f Mon Sep 17 00:00:00 2001 From: cazz Date: Sun, 14 Dec 2025 13:14:13 -0500 Subject: [PATCH 5/8] feat: integrate audio manager into game lifecycle --- src/snake.c | 9 +++++++++ src/snake.h | 2 ++ 2 files changed, 11 insertions(+) diff --git a/src/snake.c b/src/snake.c index 91f957f..b0a37f5 100644 --- a/src/snake.c +++ b/src/snake.c @@ -129,6 +129,14 @@ bool snake_create(snake_t* snake, const char* title) { return false; } + if (audio_manager_create(&snake->audio) == false) { + SDL_Log("Warning: Failed to initialize audio, continuing without sound"); + } else { + if (audio_manager_load_sound(&snake->audio, SOUND_EAT_FOOD, "assets/sounds/bubble-pop.mp3") == false) { + SDL_Log("Warning: Failed to load eating sound effect"); + } + } + Uint64 seed = SDL_GetTicksNS(); seed ^= SDL_GetPerformanceCounter(); seed ^= (Uint64)(uintptr_t)snake; @@ -175,6 +183,7 @@ void snake_destroy(snake_t* snake) { snake->text_score = NULL; } + audio_manager_destroy(&snake->audio); window_destroy(&snake->window); vector2i_set(&snake->position_head, 0, 0); diff --git a/src/snake.h b/src/snake.h index b816124..94ee747 100644 --- a/src/snake.h +++ b/src/snake.h @@ -2,6 +2,7 @@ #define SNAKE_H #include "helpers/window.h" +#include "helpers/audio.h" #include "utils/vector.h" #include "utils/dynamic_array.h" @@ -32,6 +33,7 @@ typedef struct { typedef struct { window_t window; + audio_manager_t audio; bool is_paused; From 42565933b62828d78484fbcc900d3a39bdf310af Mon Sep 17 00:00:00 2001 From: cazz Date: Sun, 14 Dec 2025 13:15:03 -0500 Subject: [PATCH 6/8] feat: play sound when snake eats food --- src/snake.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/snake.c b/src/snake.c index b0a37f5..5fb3a05 100644 --- a/src/snake.c +++ b/src/snake.c @@ -362,6 +362,8 @@ void snake_update_fixed(snake_t* snake) { // Grow the snake if it hits array_food. if (test_food_collision(snake) == true) { + audio_manager_play_sound(&snake->audio, SOUND_EAT_FOOD); + vector2i_t new_segment_position; if (dynamic_array_is_empty(&snake->array_body) == true) { new_segment_position = snake->previous_position_head; From 5ef1c26aa95faa692722a5999d0dd9e6cd39a19f Mon Sep 17 00:00:00 2001 From: cazz Date: Sun, 14 Dec 2025 13:19:14 -0500 Subject: [PATCH 7/8] fix: convert sound file from mp3 to wav for sdl compatibility --- assets/sounds/bubble-pop.mp3 | Bin 4368 -> 0 bytes assets/sounds/bubble-pop.wav | Bin 0 -> 43422 bytes src/snake.c | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 assets/sounds/bubble-pop.mp3 create mode 100644 assets/sounds/bubble-pop.wav diff --git a/assets/sounds/bubble-pop.mp3 b/assets/sounds/bubble-pop.mp3 deleted file mode 100644 index d8065c6bc01ea7e3f823fae6c4620e3dd4b2079a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4368 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 diff --git a/assets/sounds/bubble-pop.wav b/assets/sounds/bubble-pop.wav new file mode 100644 index 0000000000000000000000000000000000000000..cc884972b86e343ef42a825a3d257e6eb234c694 GIT binary patch literal 43422 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 Pf3t$uO^q+laudio) == false) { SDL_Log("Warning: Failed to initialize audio, continuing without sound"); } else { - if (audio_manager_load_sound(&snake->audio, SOUND_EAT_FOOD, "assets/sounds/bubble-pop.mp3") == false) { + if (audio_manager_load_sound(&snake->audio, SOUND_EAT_FOOD, "assets/sounds/bubble-pop.wav") == false) { SDL_Log("Warning: Failed to load eating sound effect"); } } From 1a6eceb605bc7fb68c8ce5f9b45f94570a2f92b6 Mon Sep 17 00:00:00 2001 From: cazz Date: Sun, 14 Dec 2025 13:31:35 -0500 Subject: [PATCH 8/8] fix(docs): reflect chnage from `.mp3` to `.wav` --- assets/sounds/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/sounds/README.md b/assets/sounds/README.md index 640159e..6d5fa97 100644 --- a/assets/sounds/README.md +++ b/assets/sounds/README.md @@ -2,7 +2,7 @@ ## Attribution -### `bubble-pop.mp3` +### `bubble-pop.wav` Trimmed from a Pixabay sound effect.