Files
audio/engine/engine.odin

132 lines
3.8 KiB
Odin

package engine
import "core:container/queue"
import "core:log"
import "core:math/linalg"
AUDIO_ENGINE_MINIAUDIO :: #config(AUDIO_ENGINE_MINIAUDIO, false)
AUDIO_ENGINE_FMOD :: #config(AUDIO_ENGINE_FMOD, false)
AUDIO_ENGINE_WWISE :: #config(AUDIO_ENGINE_WWISE, false)
import "miniaudio"
when AUDIO_ENGINE_MINIAUDIO {
Engine_Backend :: miniaudio.Engine
Sound_Backend :: miniaudio.Sound
Sound_Instance_Backend :: miniaudio.Sound_Instance
Bus_Backend :: miniaudio.Bus
}
else when AUDIO_ENGINE_FMOD {
}
Engine :: struct {
backend: Engine_Backend,
sound_instance_ids: queue.Queue(Sound_Instance_ID),
sound_instances: []Sound_Instance,
listeners: [MAX_LISTENERS]Listener,
available_listener_ids: queue.Queue(Listener_ID),
}
init :: proc(engine: ^Engine, max_sound_instances: u32) -> bool {
assert(engine != nil)
assert(max_sound_instances > 0)
when AUDIO_ENGINE_MINIAUDIO {
// engine.§ new(miniaudio.Engine)
// if engine.data != nil {
// v := transmute(^miniaudio.Engine)(engine.data)
// if !miniaudio.init(v) {
// free(engine.data)
// engine.data = nil
// log.errorf("Failed to initialize audio-engine MINIAUDIO.")
// return false
// }
// }
if !miniaudio.init(&engine.backend) {
// free(engine.data)
// engine.data = nil
log.errorf("Failed to initialize audio-engine MINIAUDIO.")
return false
}
}
else {
#assert("No audio-engine defined. '-define:AUDIO_ENGINE_X=true' where X is the audio-engine; 'MINIAUDIO', 'FMOD', 'WWISE'.")
}
{ // Initialize sound-instances.
log.infof("Creating %v sound-instances.", max_sound_instances)
engine.sound_instances = make([]Sound_Instance, max_sound_instances)
queue_init_err := queue.init(&engine.sound_instance_ids, int(max_sound_instances))
assert(queue_init_err == .None)
for i in 0..<len(engine.sound_instances) {
queue.append(&engine.sound_instance_ids, Sound_Instance_ID(i))
}
}
{ // Initialize the array of listeners and the queue of listener-ids.
queue.init(&engine.available_listener_ids, len(engine.listeners))
for i in 0..<len(engine.listeners) {
engine.listeners[i] = Listener {
id = INVALID_LISTENER_ID,
enabled = false,
}
queue.push_back(&engine.available_listener_ids, Listener_ID(i))
}
}
return true
}
tick :: proc(engine: ^Engine) {
when AUDIO_ENGINE_MINIAUDIO {
miniaudio.tick(&engine.backend)
}
else {
#assert("TODO: SS - Implement for Audio Engine backend")
}
// Tick listeners.
for listener in engine.listeners {
if listener.id == INVALID_LISTENER_ID {
continue
}
when AUDIO_ENGINE_MINIAUDIO {
miniaudio.tick_listener(
&engine.backend,
u8(listener.id),
listener.enabled,
listener.position,
listener.velocity,
linalg.normalize(listener.direction_forward),
linalg.normalize(listener.world_up),
)
}
}
}
shutdown :: proc(engine: ^Engine) {
assert(engine != nil)
when AUDIO_ENGINE_MINIAUDIO {
miniaudio.shutdown(&engine.backend)
}
else {
#assert("TODO: SS - Implement for Audio Engine backend")
}
delete(engine.sound_instances)
engine.sound_instances = nil
queue.destroy(&engine.sound_instance_ids)
queue.destroy(&engine.available_listener_ids)
}