shithub: cstory

Download patch

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);
 }
--