diff --git a/audio/AudioMixer.h b/audio/AudioMixer.h index f3e2d4e..5f5c9c7 100644 --- a/audio/AudioMixer.h +++ b/audio/AudioMixer.h @@ -12,10 +12,17 @@ #include "../stdlib/Types.h" #include "Audio.h" #include "AudioSetting.h" +#include "../utils/Utils.h" #include "../utils/MathUtils.h" #include "../memory/ChunkMemory.h" #include "../math/matrix/MatrixFloat32.h" +#if _WIN32 + #include "../platform/win32/threading/Atomic.h" +#elif __linux__ + #include "../platform/linux/threading/Atomic.h" +#endif + #if DIRECT_SOUND #include "../platform/win32/audio/DirectSound.h" #elif XAUDIO2 @@ -52,9 +59,17 @@ struct AudioInstance { uint32 sample_index; }; +enum AudioMixerState { + AUDIO_MIXER_STATE_UNINITIALIZED, + AUDIO_MIXER_STATE_INACTIVE, + AUDIO_MIXER_STATE_SHOULD_PLAY, + AUDIO_MIXER_STATE_ACTIVE, +}; + struct AudioMixer { ChunkMemory audio_instances; - bool is_active; + AudioMixerState state_old; + AudioMixerState state_new; uint64 effect; @@ -67,12 +82,43 @@ struct AudioMixer { XAudio2Setting api_setting; #endif + // @todo Replace HWND with our own typedef for linux + HWND window; + int16* buffer_temp; // @todo add mutex for locking and create threaded functions // do we need a condition or semaphore? }; +bool audio_mixer_is_active(AudioMixer* mixer) { + if (mixer->state_new == AUDIO_MIXER_STATE_ACTIVE + && atomic_get((int32 *) &mixer->state_new) == AUDIO_MIXER_STATE_ACTIVE + ) { + return true; + } + + AudioMixerState mixer_state; + if ((mixer_state = (AudioMixerState) atomic_get((int32 *) &mixer->state_new)) != mixer->state_old) { + if (mixer_state != AUDIO_MIXER_STATE_UNINITIALIZED) { + audio_load( + mixer->window, + &mixer->settings, + &mixer->api_setting + ); + + mixer_state = AUDIO_MIXER_STATE_INACTIVE; + } + + if (mixer_state == AUDIO_MIXER_STATE_ACTIVE) { + audio_play(&mixer->settings, &mixer->api_setting); + mixer_state = AUDIO_MIXER_STATE_ACTIVE; + } + } + + return (mixer->state_old = mixer_state) == AUDIO_MIXER_STATE_ACTIVE; +} + // @todo expand AudioLocationSetting so that it also includes audio effects, repeat etc. void audio_mixer_add(AudioMixer* mixer, int64 id, Audio* audio, AudioLocationSetting* origin) { diff --git a/platform/win32/threading/Atomic.h b/platform/win32/threading/Atomic.h index 7812fe2..25c3be6 100644 --- a/platform/win32/threading/Atomic.h +++ b/platform/win32/threading/Atomic.h @@ -151,11 +151,26 @@ void atomic_sub(volatile int64* value, int64 decrement) { InterlockedAdd((long *) value, -1 * ((long) decrement)); } +inline +f32 atomic_compare_exchange_weak(volatile f32* value, f32* expected, f32 desired) { + return (f32) InterlockedCompareExchange((long *) value, (long) desired, (long) *expected); +} + +inline +f64 atomic_compare_exchange_weak(volatile f64* value, f64* expected, f64 desired) { + return (f64) InterlockedCompareExchange((long *) value, (long) desired, (long) *expected); +} + inline int32 atomic_compare_exchange_weak(volatile int32* value, int32* expected, int32 desired) { return (int32) InterlockedCompareExchange((long *) value, desired, *expected); } +inline +int64 atomic_compare_exchange_weak(volatile int64* value, int64* expected, int64 desired) { + return (int64) InterlockedCompareExchange((long *) value, (long) desired, (long) *expected); +} + inline int32 atomic_fetch_add(volatile int32* value, int32 operand) { return (int32) InterlockedExchangeAdd((long *) value, operand); @@ -257,6 +272,11 @@ uint32 atomic_compare_exchange_weak(volatile uint32* value, uint32* expected, ui return (uint32) InterlockedCompareExchange((long *) value, desired, *expected); } +inline +uint64 atomic_compare_exchange_weak(volatile uint64* value, uint64* expected, uint64 desired) { + return (uint64) InterlockedCompareExchange((unsigned long long *) value, (unsigned long long) desired, (unsigned long long) *expected); +} + inline uint32 atomic_fetch_add(volatile uint32* value, uint32 operand) { return (uint32) InterlockedExchangeAdd((long *) value, operand);