diff --git a/src/core/math.h b/src/core/math.h index 9af7604f..26128a22 100644 --- a/src/core/math.h +++ b/src/core/math.h @@ -13,6 +13,17 @@ #define ALIGN_UP(v, alignment) (((v) + (alignment)-1) & ~((alignment)-1)) #define ALIGN_DOWN(v, alignment) ((v) & ~((alignment)-1)) +static inline uint32_t npow2(uint32_t v) { + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v++; + return v; +} + static inline uint32_t bswap24(uint32_t v) { return ((v & 0xff) << 16) | (v & 0x00ff00) | ((v & 0xff0000) >> 16); } diff --git a/src/host/sdl_host.c b/src/host/sdl_host.c index ce6075a7..dcf9abbe 100644 --- a/src/host/sdl_host.c +++ b/src/host/sdl_host.c @@ -151,13 +151,17 @@ static void audio_destroy_device(struct host *host) { } static int audio_create_device(struct host *host) { + /* SDL expects the number of buffered frames to be a power of two */ + int target_frames = MS_TO_AUDIO_FRAMES(OPTION_latency); + target_frames = (int)npow2((uint32_t)target_frames); + /* match AICA output format */ SDL_AudioSpec want; SDL_zero(want); want.freq = AUDIO_FREQ; want.format = AUDIO_S16LSB; want.channels = 2; - want.samples = MS_TO_AUDIO_FRAMES(OPTION_latency); + want.samples = target_frames; want.userdata = host; want.callback = audio_write_cb; diff --git a/src/options.c b/src/options.c index 3a544af6..373a9ceb 100644 --- a/src/options.c +++ b/src/options.c @@ -2,7 +2,7 @@ #include "core/core.h" #include "host/keycode.h" -const int LATENCY_PRESETS[] = {50, 75, 100, 125, 150}; +const int LATENCY_PRESETS[] = {45, 90, 180}; const int NUM_LATENCY_PRESETS = ARRAY_SIZE(LATENCY_PRESETS); const char *ASPECT_RATIOS[] = {