MoonWorks/src/Audio/SourceVoice.cs

124 lines
2.2 KiB
C#

using System;
namespace MoonWorks.Audio
{
public class SourceVoice : Voice
{
protected FAudio.FAudioWaveFormatEx Format;
protected object StateLock = new object();
public uint BuffersQueued
{
get
{
FAudio.FAudioSourceVoice_GetState(
Handle,
out var state,
FAudio.FAUDIO_VOICE_NOSAMPLESPLAYED
);
return state.BuffersQueued;
}
}
private SoundState state;
public SoundState State
{
get
{
if (BuffersQueued == 0)
{
Stop();
}
return state;
}
internal set
{
state = value;
}
}
public delegate void OnUpdateFunc();
public OnUpdateFunc OnUpdate; // called by AudioDevice thread
public SourceVoice(
AudioDevice device,
ushort formatTag,
ushort bitsPerSample,
ushort blockAlign,
ushort channels,
uint samplesPerSecond
) : base(device)
{
Format = new FAudio.FAudioWaveFormatEx
{
wFormatTag = formatTag,
wBitsPerSample = bitsPerSample,
nChannels = channels,
nBlockAlign = blockAlign,
nSamplesPerSec = samplesPerSecond,
nAvgBytesPerSec = blockAlign * samplesPerSecond
};
FAudio.FAudio_CreateSourceVoice(
device.Handle,
out var Handle,
ref Format,
FAudio.FAUDIO_VOICE_USEFILTER,
FAudio.FAUDIO_DEFAULT_FREQ_RATIO,
IntPtr.Zero,
IntPtr.Zero, // default sends to mastering voice!
IntPtr.Zero
);
}
public void Play(uint syncGroup = FAudio.FAUDIO_COMMIT_NOW)
{
lock (StateLock)
{
FAudio.FAudioSourceVoice_Start(Handle, 0, syncGroup);
State = SoundState.Playing;
}
}
public void Pause(uint syncGroup = FAudio.FAUDIO_COMMIT_NOW)
{
lock (StateLock)
{
FAudio.FAudioSourceVoice_Stop(Handle, 0, syncGroup);
State = SoundState.Paused;
}
}
public void ExitLoop(uint syncGroup = FAudio.FAUDIO_COMMIT_NOW)
{
lock (StateLock)
{
FAudio.FAudioSourceVoice_ExitLoop(Handle, syncGroup);
}
}
public void Stop(uint syncGroup = FAudio.FAUDIO_COMMIT_NOW)
{
lock (StateLock)
{
FAudio.FAudioSourceVoice_Stop(Handle, 0, syncGroup);
FAudio.FAudioSourceVoice_FlushSourceBuffers(Handle);
State = SoundState.Stopped;
}
}
protected override unsafe void Destroy()
{
Stop();
base.Destroy();
}
}
}