balance knob

This commit is contained in:
Evan Burkey 2023-01-20 15:50:34 -08:00
parent bf9b5580e0
commit 735cbf541a
1 changed files with 70 additions and 16 deletions

View File

@ -13,6 +13,7 @@ static SDL_Renderer *renderer = NULL;
static SDL_AudioDeviceID audio_device = 0; static SDL_AudioDeviceID audio_device = 0;
static SDL_AudioStream *stream = NULL; static SDL_AudioStream *stream = NULL;
static float volume_slider_value = 1.0f; static float volume_slider_value = 1.0f;
static float balance_slider_value = 0.5f;
#if defined(__clang__) || defined(__GNUC__) #if defined(__clang__) || defined(__GNUC__)
static void panic_and_abort(const char *title, const char *text) __attribute__((noreturn)); 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 Uint32 wavpos = 0;
static SDL_AudioSpec wavspec; 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) { static SDL_bool open_audio_file(const char *fname) {
SDL_FreeAudioStream(stream); SDL_FreeAudioStream(stream);
stream = NULL; 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); stream = SDL_NewAudioStream(wavspec.format, wavspec.channels, wavspec.freq, AUDIO_F32, 2, 48000);
if (!stream) { if (!stream) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create audiostream!", SDL_GetError(), window); SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create audiostream!", SDL_GetError(), window);
SDL_FreeWAV(wavbuf); stop_audio();
wavbuf = NULL;
wavlen = 0;
wavpos = 0;
return SDL_FALSE; return SDL_FALSE;
} }
if (SDL_AudioStreamPut(stream, wavbuf, wavlen) == -1) { // FIXME: graceful handling if (SDL_AudioStreamPut(stream, wavbuf, wavlen) == -1) {
panic_and_abort("Audio stream put failed", SDL_GetError()); 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; return SDL_TRUE;
} }
@ -106,6 +125,13 @@ int main(int argc, char **argv) {
20, 20,
volume_rect.h 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 paused = SDL_TRUE;
SDL_bool quit = SDL_FALSE; 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 if (SDL_PointInRect(&pt, &rewind_rect)) { // Pressed the "rewind" button
SDL_ClearQueuedAudio(audio_device); SDL_ClearQueuedAudio(audio_device);
SDL_AudioStreamClear(stream); SDL_AudioStreamClear(stream);
if (SDL_AudioStreamPut(stream, wavbuf, wavlen) == -1) { // FIXME: graceful handling if (SDL_AudioStreamPut(stream, wavbuf, wavlen) == -1) {
panic_and_abort("Audio stream put failed", SDL_GetError()); 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 } else if (SDL_PointInRect(&pt, &pause_rect)) { // Pressed the "pause" button
paused = paused ? SDL_FALSE : SDL_TRUE; paused = paused ? SDL_FALSE : SDL_TRUE;
SDL_PauseAudioDevice(audio_device, paused); 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 = pt.x - (volume_knob.w / 2);
volume_knob.x = SDL_max(volume_knob.x, volume_rect.x); 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); 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; break;
} }
@ -158,15 +194,31 @@ int main(int argc, char **argv) {
if (bytes_remaining > 0) { if (bytes_remaining > 0) {
const int new_bytes = SDL_min(bytes_remaining, KB(32)); const int new_bytes = SDL_min(bytes_remaining, KB(32));
static Uint8 converted_buffer[KB(32)]; static Uint8 converted_buffer[KB(32)];
SDL_AudioStreamGet(stream, converted_buffer, new_bytes); // FIXME: Error checking const int num_converted_bytes = SDL_AudioStreamGet(stream, converted_buffer, new_bytes);
const int num_samples = (new_bytes / sizeof(float)); if (num_converted_bytes > 0) {
const int num_samples = (num_converted_bytes / sizeof(float));
float *samples = (float*)converted_buffer; float *samples = (float*)converted_buffer;
// volume changes
if (volume_slider_value != 1.0f) {
for (size_t i = 0; i < num_samples; ++i) { for (size_t i = 0; i < num_samples; ++i) {
samples[i] *= volume_slider_value; 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);
} }
} }
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
@ -175,9 +227,11 @@ int main(int argc, char **argv) {
SDL_RenderFillRect(renderer, &rewind_rect); SDL_RenderFillRect(renderer, &rewind_rect);
SDL_RenderFillRect(renderer, &pause_rect); SDL_RenderFillRect(renderer, &pause_rect);
SDL_RenderFillRect(renderer, &volume_rect); SDL_RenderFillRect(renderer, &volume_rect);
SDL_RenderFillRect(renderer, &balance_rect);
SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255); SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
SDL_RenderFillRect(renderer, &volume_knob); SDL_RenderFillRect(renderer, &volume_knob);
SDL_RenderFillRect(renderer, &balance_knob);
SDL_RenderPresent(renderer); SDL_RenderPresent(renderer);
} }