From 735cbf541a3fcf9d41c38d494facb3163ee5f171 Mon Sep 17 00:00:00 2001 From: Evan Burkey Date: Fri, 20 Jan 2023 15:50:34 -0800 Subject: [PATCH] balance knob --- sdlamp.c | 86 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 70 insertions(+), 16 deletions(-) diff --git a/sdlamp.c b/sdlamp.c index 68402d3..320e819 100644 --- a/sdlamp.c +++ b/sdlamp.c @@ -13,6 +13,7 @@ static SDL_Renderer *renderer = NULL; static SDL_AudioDeviceID audio_device = 0; static SDL_AudioStream *stream = NULL; static float volume_slider_value = 1.0f; +static float balance_slider_value = 0.5f; #if defined(__clang__) || defined(__GNUC__) static void panic_and_abort(const char *title, const char *text) __attribute__((noreturn)); @@ -30,6 +31,21 @@ static Uint32 wavlen = 0; static Uint32 wavpos = 0; static SDL_AudioSpec wavspec; +static void stop_audio(void) { + if (stream) { + SDL_FreeAudioStream(stream); + stream = NULL; + } + + if (wavbuf) { + SDL_FreeWAV(wavbuf); + wavbuf = NULL; + } + + wavlen = 0; + wavpos = 0; +} + static SDL_bool open_audio_file(const char *fname) { SDL_FreeAudioStream(stream); stream = NULL; @@ -46,18 +62,21 @@ static SDL_bool open_audio_file(const char *fname) { stream = SDL_NewAudioStream(wavspec.format, wavspec.channels, wavspec.freq, AUDIO_F32, 2, 48000); if (!stream) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create audiostream!", SDL_GetError(), window); - SDL_FreeWAV(wavbuf); - wavbuf = NULL; - wavlen = 0; - wavpos = 0; + stop_audio(); return SDL_FALSE; } - if (SDL_AudioStreamPut(stream, wavbuf, wavlen) == -1) { // FIXME: graceful handling - panic_and_abort("Audio stream put failed", SDL_GetError()); + if (SDL_AudioStreamPut(stream, wavbuf, wavlen) == -1) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "AudioStreamPut failed!", SDL_GetError(), window); + stop_audio(); + return SDL_FALSE; } - SDL_AudioStreamFlush(stream); // FIXME: error handling + if (SDL_AudioStreamFlush(stream) == -1) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "AudioStreamFlush failed!", SDL_GetError(), window); + stop_audio(); + return SDL_FALSE; + } return SDL_TRUE; } @@ -106,6 +125,13 @@ int main(int argc, char **argv) { 20, volume_rect.h }; + const SDL_Rect balance_rect = {(1024 - 500) / 2, 300, 500, 20}; + SDL_Rect balance_knob = { + (balance_rect.x + (balance_rect.w / 2)) - balance_knob.w, + balance_rect.y, + 20, + balance_rect.h + }; SDL_bool paused = SDL_TRUE; SDL_bool quit = SDL_FALSE; @@ -122,10 +148,14 @@ int main(int argc, char **argv) { if (SDL_PointInRect(&pt, &rewind_rect)) { // Pressed the "rewind" button SDL_ClearQueuedAudio(audio_device); SDL_AudioStreamClear(stream); - if (SDL_AudioStreamPut(stream, wavbuf, wavlen) == -1) { // FIXME: graceful handling - panic_and_abort("Audio stream put failed", SDL_GetError()); + if (SDL_AudioStreamPut(stream, wavbuf, wavlen) == -1) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "AudioStreamPut failed!", SDL_GetError(), window); + stop_audio(); + } + if (SDL_AudioStreamFlush(stream) == -1) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "AudioStreamPut failed!", SDL_GetError(), window); + stop_audio(); } - SDL_AudioStreamFlush(stream); } else if (SDL_PointInRect(&pt, &pause_rect)) { // Pressed the "pause" button paused = paused ? SDL_FALSE : SDL_TRUE; SDL_PauseAudioDevice(audio_device, paused); @@ -141,6 +171,12 @@ int main(int argc, char **argv) { volume_knob.x = pt.x - (volume_knob.w / 2); volume_knob.x = SDL_max(volume_knob.x, volume_rect.x); volume_knob.x = SDL_min(volume_knob.x, (volume_rect.x + volume_rect.w) - volume_knob.w); + } else if (SDL_PointInRect(&pt, &balance_rect) && (e.motion.state & SDL_BUTTON_LMASK)) { // left mouse pressed inside the "balance" slider + const float fx = (float)(pt.x - balance_rect.x); + balance_slider_value = (fx / (float)balance_rect.w); + balance_knob.x = pt.x - (balance_knob.w / 2); + balance_knob.x = SDL_max(balance_knob.x, balance_rect.x); + balance_knob.x = SDL_min(balance_knob.x, (balance_rect.x + balance_rect.w) - balance_knob.w); } break; } @@ -158,13 +194,29 @@ int main(int argc, char **argv) { if (bytes_remaining > 0) { const int new_bytes = SDL_min(bytes_remaining, KB(32)); static Uint8 converted_buffer[KB(32)]; - SDL_AudioStreamGet(stream, converted_buffer, new_bytes); // FIXME: Error checking - const int num_samples = (new_bytes / sizeof(float)); - float *samples = (float*)converted_buffer; - for (size_t i = 0; i < num_samples; ++i) { - samples[i] *= volume_slider_value; + const int num_converted_bytes = SDL_AudioStreamGet(stream, converted_buffer, new_bytes); + if (num_converted_bytes > 0) { + const int num_samples = (num_converted_bytes / sizeof(float)); + float *samples = (float*)converted_buffer; + + // volume changes + if (volume_slider_value != 1.0f) { + for (size_t i = 0; i < num_samples; ++i) { + samples[i] *= volume_slider_value; + } + } + + // balance changes + if (balance_slider_value != 0.5f) { + for (size_t i = 0; i < num_samples; i += 2) { + // first sample is left, second is right + samples[i] *= (1.0f - balance_slider_value); + samples[i + 1] *= balance_slider_value; + } + } + + SDL_QueueAudio(audio_device, converted_buffer, new_bytes); } - SDL_QueueAudio(audio_device, converted_buffer, new_bytes); } } @@ -175,9 +227,11 @@ int main(int argc, char **argv) { SDL_RenderFillRect(renderer, &rewind_rect); SDL_RenderFillRect(renderer, &pause_rect); SDL_RenderFillRect(renderer, &volume_rect); + SDL_RenderFillRect(renderer, &balance_rect); SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255); SDL_RenderFillRect(renderer, &volume_knob); + SDL_RenderFillRect(renderer, &balance_knob); SDL_RenderPresent(renderer); }