ref: d91c1e9bdc01912fbdd8e6786fd3c837d89dafac
parent: 732d3bbc5cb24a1e43eea16163455c0cab104f02
author: Clownacy <Clownacy@users.noreply.github.com>
date: Tue Mar 31 08:19:44 EDT 2020
Update the SDL2 audio backend Now uses the shared software mixer
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -294,7 +294,7 @@
endif()
if(BACKEND_AUDIO MATCHES "SDL2")
- target_sources(CSE2 PRIVATE "src/Backends/Audio/SDL2.cpp")
+ target_sources(CSE2 PRIVATE "src/Backends/Audio/SDL2.cpp" "src/Backends/Audio/SoftwareMixer.cpp")
elseif(BACKEND_AUDIO MATCHES "miniaudio")
target_sources(CSE2 PRIVATE "src/Backends/Audio/miniaudio.cpp" "src/Backends/Audio/SoftwareMixer.cpp")
--- a/src/Backends/Audio/SDL2.cpp
+++ b/src/Backends/Audio/SDL2.cpp
@@ -1,45 +1,14 @@
#include "../Audio.h"
-#include <math.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
#include "SDL.h"
#include "../../Organya.h"
#include "../../WindowsWrapper.h"
+#include "SoftwareMixer.h"
+
#define MIN(a, b) ((a) < (b) ? (a) : (b))
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
-#define CLAMP(x, y, z) MIN(MAX((x), (y)), (z))
-#ifdef __GNUC__
-#define ATTR_HOT __attribute__((hot))
-#else
-#define ATTR_HOT
-#endif
-
-struct AudioBackend_Sound
-{
- unsigned char *samples;
- size_t frames;
- double position;
- double advance_delta;
- BOOL playing;
- BOOL looping;
- unsigned int frequency;
- float volume;
- float pan_l;
- float pan_r;
- float volume_l;
- float volume_r;
-
- struct AudioBackend_Sound *next;
-};
-
-static AudioBackend_Sound *sound_list_head;
static SDL_AudioDeviceID device_id;
static unsigned long output_frequency;
@@ -46,77 +15,6 @@
static unsigned short organya_timer;
-static double MillibelToScale(long volume)
-{
- // Volume is in hundredths of decibels, from 0 to -10000
- volume = CLAMP(volume, -10000, 0);
- return pow(10.0, volume / 2000.0);
-}
-
-static void SetSoundFrequency(AudioBackend_Sound *sound, unsigned int frequency)
-{
- sound->frequency = frequency;
- sound->advance_delta = (double)frequency / (double)output_frequency;
-}
-
-static void SetSoundVolume(AudioBackend_Sound *sound, long volume)
-{
- sound->volume = (float)MillibelToScale(volume);
-
- sound->volume_l = sound->pan_l * sound->volume;
- sound->volume_r = sound->pan_r * sound->volume;
-}
-
-static void SetSoundPan(AudioBackend_Sound *sound, long pan)
-{
- sound->pan_l = (float)MillibelToScale(-pan);
- sound->pan_r = (float)MillibelToScale(pan);
-
- sound->volume_l = sound->pan_l * sound->volume;
- sound->volume_r = sound->pan_r * sound->volume;
-}
-
-// Most CPU-intensive function in the game (2/3rd CPU time consumption in my experience), so marked with attrHot so the compiler considers it a hot spot (as it is) when optimizing
-ATTR_HOT static void MixSounds(float *stream, unsigned int frames_total)
-{
- for (AudioBackend_Sound *sound = sound_list_head; sound != NULL; sound = sound->next)
- {
- if (sound->playing)
- {
- float *steam_pointer = stream;
-
- for (unsigned int frames_done = 0; frames_done < frames_total; ++frames_done)
- {
- // Get two samples, and normalise them to 0-1
- const float sample1 = (sound->samples[(size_t)sound->position] - 128.0f) / 128.0f;
- const float sample2 = (sound->samples[(size_t)sound->position + 1] - 128.0f) / 128.0f;
-
- // Perform linear interpolation
- const float interpolated_sample = sample1 + ((sample2 - sample1) * fmod((float)sound->position, 1.0f));
-
- *steam_pointer++ += interpolated_sample * sound->volume_l;
- *steam_pointer++ += interpolated_sample * sound->volume_r;
-
- sound->position += sound->advance_delta;
-
- if (sound->position >= sound->frames)
- {
- if (sound->looping)
- {
- sound->position = fmod(sound->position, (double)sound->frames);
- }
- else
- {
- sound->playing = FALSE;
- sound->position = 0.0;
- break;
- }
- }
- }
- }
- }
-}
-
static void Callback(void *user_data, Uint8 *stream_uint8, int len)
{
(void)user_data;
@@ -129,7 +27,7 @@
if (organya_timer == 0)
{
- MixSounds(stream, frames_total);
+ Mixer_MixSounds(stream, frames_total);
}
else
{
@@ -152,7 +50,7 @@
const unsigned int frames_to_do = MIN(organya_countdown, frames_total - frames_done);
- MixSounds(stream + frames_done * 2, frames_to_do);
+ Mixer_MixSounds(stream + frames_done * 2, frames_to_do);
frames_done += frames_to_do;
organya_countdown -= frames_to_do;
@@ -184,6 +82,7 @@
SDL_AudioSpec obtained_specification;
device_id = SDL_OpenAudioDevice(NULL, 0, &specification, &obtained_specification, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
output_frequency = obtained_specification.freq;
+ Mixer_Init(obtained_specification.freq);
if (device_id == 0)
{
@@ -207,35 +106,13 @@
AudioBackend_Sound* AudioBackend_CreateSound(unsigned int frequency, size_t frames)
{
- AudioBackend_Sound *sound = (AudioBackend_Sound*)malloc(sizeof(AudioBackend_Sound));
-
- if (sound == NULL)
- return NULL;
-
- sound->samples = (unsigned char*)malloc(frames + 1);
-
- if (sound->samples == NULL)
- {
- free(sound);
- return NULL;
- }
-
- sound->frames = frames;
- sound->playing = FALSE;
- sound->position = 0.0;
-
- SetSoundFrequency(sound, frequency);
- SetSoundVolume(sound, 0);
- SetSoundPan(sound, 0);
-
SDL_LockAudioDevice(device_id);
- sound->next = sound_list_head;
- sound_list_head = sound;
+ Mixer_Sound *sound = Mixer_CreateSound(frequency, frames);
SDL_UnlockAudioDevice(device_id);
- return sound;
+ return (AudioBackend_Sound*)sound;
}
void AudioBackend_DestroySound(AudioBackend_Sound *sound)
@@ -245,16 +122,7 @@
SDL_LockAudioDevice(device_id);
- for (AudioBackend_Sound **sound_pointer = &sound_list_head; *sound_pointer != NULL; sound_pointer = &(*sound_pointer)->next)
- {
- if (*sound_pointer == sound)
- {
- *sound_pointer = sound->next;
- free(sound->samples);
- free(sound);
- break;
- }
- }
+ Mixer_DestroySound((Mixer_Sound*)sound);
SDL_UnlockAudioDevice(device_id);
}
@@ -266,10 +134,7 @@
SDL_LockAudioDevice(device_id);
- if (size != NULL)
- *size = sound->frames;
-
- return sound->samples;
+ return Mixer_LockSound((Mixer_Sound*)sound, size);
}
void AudioBackend_UnlockSound(AudioBackend_Sound *sound)
@@ -287,11 +152,8 @@
SDL_LockAudioDevice(device_id);
- sound->playing = TRUE;
- sound->looping = looping;
+ Mixer_PlaySound((Mixer_Sound*)sound, looping);
- sound->samples[sound->frames] = looping ? sound->samples[0] : 0x80; // For the linear interpolator
-
SDL_UnlockAudioDevice(device_id);
}
@@ -302,8 +164,7 @@
SDL_LockAudioDevice(device_id);
- sound->playing = FALSE;
- sound->position = 0.0;
+ Mixer_StopSound((Mixer_Sound*)sound);
SDL_UnlockAudioDevice(device_id);
}
@@ -315,7 +176,7 @@
SDL_LockAudioDevice(device_id);
- sound->position = 0.0;
+ Mixer_RewindSound((Mixer_Sound*)sound);
SDL_UnlockAudioDevice(device_id);
}
@@ -327,7 +188,7 @@
SDL_LockAudioDevice(device_id);
- SetSoundFrequency(sound, frequency);
+ Mixer_SetSoundFrequency((Mixer_Sound*)sound, frequency);
SDL_UnlockAudioDevice(device_id);
}
@@ -339,7 +200,7 @@
SDL_LockAudioDevice(device_id);
- SetSoundVolume(sound, volume);
+ Mixer_SetSoundVolume((Mixer_Sound*)sound, volume);
SDL_UnlockAudioDevice(device_id);
}
@@ -351,7 +212,7 @@
SDL_LockAudioDevice(device_id);
- SetSoundPan(sound, pan);
+ Mixer_SetSoundPan((Mixer_Sound*)sound, pan);
SDL_UnlockAudioDevice(device_id);
}
--
⑨