audio: floating point mixing

This commit is contained in:
Zack Buhman 2026-06-01 13:08:45 -05:00
parent afef1b8a2e
commit 0dbe1a3c7a

View File

@ -58,7 +58,7 @@ namespace audio {
void init() void init()
{ {
audio_spec.channels = channels; audio_spec.channels = channels;
audio_spec.format = SDL_AUDIO_S16LE; audio_spec.format = SDL_AUDIO_F32LE;
audio_spec.freq = sample_rate; audio_spec.freq = sample_rate;
audio_stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &audio_spec, NULL, NULL); audio_stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &audio_spec, NULL, NULL);
assert(audio_stream); assert(audio_stream);
@ -199,15 +199,12 @@ namespace audio {
audio_instances_count = 0; audio_instances_count = 0;
} }
static inline void saturation_add(int16_t * mix_buffer, int32_t value) static inline float clampf(float v)
{ {
int32_t mix_value = *mix_buffer; if (v > 1.0f)
mix_value += value; return 1.0f;
if (mix_value > 32767) if (v < -1.0f)
mix_value = 32767; return -1.0f;
if (mix_value < -32768)
mix_value = -32768;
*mix_buffer = mix_value;
} }
static inline void remove_instance(int instance_index) static inline void remove_instance(int instance_index)
@ -220,7 +217,7 @@ namespace audio {
audio_instances_count -= 1; audio_instances_count -= 1;
} }
static inline void update_instance(int16_t * mix_buffer, AudioInstance & instance) static inline void update_instance(float * mix_buffer, AudioInstance & instance)
{ {
int16_t const * const buf = instance.audio_buffer->buf; int16_t const * const buf = instance.audio_buffer->buf;
uint32_t const sample_count = instance.audio_buffer->sample_count; uint32_t const sample_count = instance.audio_buffer->sample_count;
@ -259,7 +256,8 @@ namespace audio {
if (instance.tail_index != sample_count) { if (instance.tail_index != sample_count) {
value += buf[instance.tail_index * channels + ch]; value += buf[instance.tail_index * channels + ch];
} }
saturation_add(&mix_buffer[mix_index * channels + ch], (double)value * fadeout * attenuation); constexpr double scale = 1.0f / 32768.0f;
mix_buffer[mix_index * channels + ch] += (double)value * fadeout * attenuation * scale;
} }
instance.sample_index += 1; instance.sample_index += 1;
instance.fadeout_index += 1; instance.fadeout_index += 1;
@ -312,10 +310,11 @@ namespace audio {
void update() void update()
{ {
if (SDL_GetAudioStreamQueued(audio_stream) >= half_period_size) float mix_buffer[half_period_samples * channels];
if (SDL_GetAudioStreamQueued(audio_stream) >= (int)(sizeof (mix_buffer)))
return; return;
int16_t mix_buffer[half_period_samples * channels];
memset(mix_buffer, 0, (sizeof (mix_buffer))); memset(mix_buffer, 0, (sizeof (mix_buffer)));
poem_playing = nullptr; poem_playing = nullptr;
@ -337,6 +336,6 @@ namespace audio {
} }
} }
SDL_PutAudioStreamData(audio_stream, (void *)mix_buffer, half_period_size); SDL_PutAudioStreamData(audio_stream, (void *)mix_buffer, (int)(sizeof (mix_buffer)));
} }
} }