From 4feb3c72425dfec9e160fff3bd794c9faf08d1f2 Mon Sep 17 00:00:00 2001 From: Katajisto Date: Wed, 28 Jan 2026 23:29:30 +0200 Subject: [PATCH] build base for mixer --- src/audio/audio.jai | 15 +------- src/audio/load.jai | 4 +++ src/audio/mixer.jai | 87 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 14 deletions(-) create mode 100644 src/audio/mixer.jai diff --git a/src/audio/audio.jai b/src/audio/audio.jai index 716ab44..cd7648a 100644 --- a/src/audio/audio.jai +++ b/src/audio/audio.jai @@ -1,19 +1,6 @@ #load "backend.jai"; #load "load.jai"; - -Mixer_Bus :: enum { - MUSIC; - SOUND_EFFECT; - DIALOGUE; -} - -Mixer :: struct { - -} - -mixer_get_samples :: (buffer: *float, mixer: *Mixer, sampleCount: s32, channelCount: s32) { - -} +#load "mixer.jai"; audio_init :: () { load_wav_file(); diff --git a/src/audio/load.jai b/src/audio/load.jai index ab9c654..e7fd234 100644 --- a/src/audio/load.jai +++ b/src/audio/load.jai @@ -1,3 +1,7 @@ +Audio_Data :: struct { + +} + Wav :: #import "Wav_File"; audio_info : Wav.Waveformatex; diff --git a/src/audio/mixer.jai b/src/audio/mixer.jai new file mode 100644 index 0000000..bd62e08 --- /dev/null +++ b/src/audio/mixer.jai @@ -0,0 +1,87 @@ +#if OS != .WASM { + Thread :: #import "Thread"; +} + +Mixer_Bus :: enum { + MUSIC; + SOUND_EFFECT; + DIALOGUE; +} + +Play_Mode :: enum { + ONESHOT; + REPEAT; +} + +Mixer_Play_Task :: struct { + audio : *Audio_Data; + bus : Mixer_Bus; + mode : Play_Mode; + curSample : s64; + + startTime : float64; + delay : float64; + silenceBeforeRepeat : float64; +} + +Mixer_Config :: struct { + masterVolume : float = 0.5; @Slider,0,1,0.1 + dialogueVolume : float = 0.5; @Slider,0,1,0.1 + soundEffectVolume : float = 0.5; @Slider,0,1,0.1 +} + +Mixer :: struct { + #if OS != .WASM { + // If we are on WASM, the Thread module mutex does not work. + // Fortunately we don't need a mutex for this, since sokol does + // not do multithreading for audio on WASM. + // + // Let's just have the mutex as a part of the struct on all platforms + // except WASM. It would probably be a good idea to have a mutex wrapper + // thing that would use the Thread module Mutex or a mutex that works with + // WASM. :NoMutexForWasm + mutex : Thread.Mutex; + } + + config : Mixer_Config; + tasks : [..]Mixer_Play_Task; +} + +// Removes tasks from the mixer's task list that +// no longer have a reason to be on the task list. +// Eg. a sound that is .ONESHOT but has already been played. +mixer_clean_tasks :: (mixer: *Mixer) { + mixer_lock(mixer); + defer mixer_unlock(mixer); + +} + +mixer_add_task :: (mixer: *Mixer, task: Mixer_Play_Task) { + mixer_lock(mixer); + defer mixer_unlock(mixer); + +} + +mixer_get_samples :: (mixer: *Mixer, samples: *float, sampleCount: s32, channelCount: s32) { + mixer_lock(mixer); + defer mixer_unlock(mixer); + + +} + +mixer_lock :: (mixer: *Mixer) { + #if OS != .WASM { + Thread.lock(*mixer.mutex); + } else { + return; // On WASM this is a no-op. See :NoMutexForWasm + } +} + +mixer_unlock :: (mixer: *Mixer) { + #if OS != .WASM { + Thread.unlock(*mixer.mutex); + } else { + return; // On WASM this is a no-op. See :NoMutexForWasm + } + +}