using NativeEngine;
namespace Sandbox.Audio;
///
/// A mix frame size is 512 samples
/// A second is made up of 44100 samples
/// This means one frame is about 11.6ms
/// So as long as mixing takes less than 10ms we're okay
///
internal static partial class AudioEngine
{
public static bool IsValid => g_pAudioDevice.IsValid();
///
/// How many output channels do we have? Generally 2, but if they have a 7.1 setup it can be more.
///
public static int ChannelCount { get; private set; } = 2;
///
/// How many seconds one sample lasts
///
public static float SecondsPerSample => 1.0f / SamplingRate;
///
/// The engine's output sampling rate. This doesn't change.
///
public static float SamplingRate => 44100.0f; // MIX_DEFAULT_SAMPLING_RATE
///
/// The size of one
///
public static int MixBufferSize => 512; // MIX_BUFFER_SIZE
[ConVar( "voice_loopback", ConVarFlags.Protected )]
public static bool VoiceLoopback { get; set; } = false;
static AudioEngine()
{
if ( Application.IsUnitTest )
return;
if ( IsValid )
{
ChannelCount = (int)g_pAudioDevice.ChannelCount();
}
DspFactory.CreateBuiltIn();
}
public static void ClearBuffer()
{
if ( !IsValid )
return;
g_pAudioDevice.ClearBuffer();
}
[ConVar( "snd_mute", ConVarFlags.Saved )]
public static bool Mute { get; set; }
[ConVar( "snd_mute_losefocus", ConVarFlags.Saved )]
public static bool MuteLoseFocus { get; set; }
///
/// Called every frame.
///
internal static void Tick()
{
if ( !g_pAudioDevice.IsValid() )
return;
// calling g_pAudioDevice.MuteDevice actually starts the audio system for the first time.
// if we never call it, the audio system will never start.
var mute = Mute || (MuteLoseFocus && !InputSystem.IsAppActive());
g_pAudioDevice.MuteDevice( mute );
}
}