Sound_Handle :: #type, distinct u32; audio_system : *Audio_System; Sound :: struct { fmod_sound: *FMOD_SOUND; } Audio_Event :: struct { instance : *FMOD_STUDIO_EVENTINSTANCE; }; Delayed_Audio_Event :: struct { event: Audio_Event; time_left: float; } Audio_System :: struct { fmod: *FMOD_SYSTEM; studio: *FMOD_STUDIO_SYSTEM; sounds: PArray(Sound, Sound_Handle); delayed_events: [..] Delayed_Audio_Event; } init_audio_system :: () { audio_system = New(Audio_System); assert(FMOD_System_Create(*audio_system.fmod, FMOD_VERSION) == .FMOD_OK); assert(FMOD_System_Init(audio_system.fmod, 32, 0, null) == .FMOD_OK); assert(FMOD_Studio_System_Create(*audio_system.studio, FMOD_VERSION) == .FMOD_OK); assert(FMOD_Studio_System_Initialize(audio_system.studio, 512, FMOD_STUDIO_INIT_LIVEUPDATE, FMOD_INIT_PROFILE_ENABLE, null) == .FMOD_OK); } instance : *FMOD_STUDIO_EVENTINSTANCE; load_fmod_bank :: (path: string) { bank : *FMOD_STUDIO_BANK; result := FMOD_Studio_System_LoadBankFile(audio_system.studio, to_temp_c_string(path), FMOD_STUDIO_LOAD_BANK_NORMAL, *bank); assert(result == .FMOD_OK); loading_state : FMOD_STUDIO_LOADING_STATE; res := FMOD_Studio_Bank_GetLoadingState(bank, *loading_state); } create_audio_event :: (path: string) -> Audio_Event { event : *FMOD_STUDIO_EVENTDESCRIPTION; result := FMOD_Studio_System_GetEvent(audio_system.studio, to_temp_c_string(path), *event); assert(result == .FMOD_OK); evt : Audio_Event; assert(FMOD_Studio_EventDescription_CreateInstance(event, *evt.instance) == .FMOD_OK); return evt; } play_audio_event :: (evt: Audio_Event, delay: float = -1.0) { if delay > 0.0 { array_add(*audio_system.delayed_events, .{evt, delay}); } else { assert(FMOD_Studio_EventInstance_Start(evt.instance) == .FMOD_OK); } } stop_audio_event :: (evt: Audio_Event) { assert(FMOD_Studio_EventInstance_Stop(evt.instance, .ALLOWFADEOUT) == .FMOD_OK); } create_sound :: (path: string) -> Sound_Handle { sound: Sound; assert(FMOD_System_CreateSound(audio_system.fmod, to_temp_c_string(path), FMOD_DEFAULT, null, *sound.fmod_sound) == .FMOD_OK); return parray_add(*audio_system.sounds, sound); } play_sound :: (handle: Sound_Handle) { sound := parray_get(audio_system.sounds, handle); FMOD_System_PlaySound(audio_system.fmod, sound.fmod_sound, null, 0, null); } update_audio :: (dt: float) { for * audio_system.delayed_events { if it.time_left <= 0.0 { play_audio_event(it.event); remove it; } else { it.time_left -= dt; } } FMOD_Studio_System_Update(audio_system.studio); } #import "fmod";