MoonWorks/src/Audio/StaticSoundInstance.cs

144 lines
2.7 KiB
C#
Raw Normal View History

2022-02-23 05:14:32 +00:00
using System;
2021-01-20 02:06:10 +00:00
namespace MoonWorks.Audio
{
2022-02-23 05:14:32 +00:00
public class StaticSoundInstance : SoundInstance
{
public StaticSound Parent { get; }
public bool Loop { get; set; }
2022-02-23 05:14:32 +00:00
private SoundState _state = SoundState.Stopped;
public override SoundState State
{
get
{
FAudio.FAudioSourceVoice_GetState(
2023-03-02 01:47:09 +00:00
Voice,
2022-02-23 05:14:32 +00:00
out var state,
FAudio.FAUDIO_VOICE_NOSAMPLESPLAYED
);
if (state.BuffersQueued == 0)
{
StopImmediate();
2022-02-23 05:14:32 +00:00
}
2021-01-20 03:26:30 +00:00
2022-02-23 05:14:32 +00:00
return _state;
}
2021-01-20 03:26:30 +00:00
2022-02-23 05:14:32 +00:00
protected set
{
_state = value;
}
}
2021-01-20 02:06:10 +00:00
2023-05-12 00:56:40 +00:00
public bool AutoFree { get; }
2022-02-23 05:14:32 +00:00
internal StaticSoundInstance(
AudioDevice device,
2023-05-12 00:56:40 +00:00
StaticSound parent,
bool autoFree
2022-04-07 21:19:43 +00:00
) : base(device, parent.FormatTag, parent.BitsPerSample, parent.BlockAlign, parent.Channels, parent.SamplesPerSecond)
2022-02-23 05:14:32 +00:00
{
Parent = parent;
2023-05-12 00:56:40 +00:00
AutoFree = autoFree;
if (AutoFree)
{
device.AddAutoFreeStaticSoundInstance(this);
}
2022-02-23 05:14:32 +00:00
}
2021-01-20 02:06:10 +00:00
public override void Play()
{
PlayUsingOperationSet(0);
}
public override void QueueSyncPlay()
{
PlayUsingOperationSet(1);
}
private void PlayUsingOperationSet(uint operationSet)
2022-02-23 05:14:32 +00:00
{
if (State == SoundState.Playing)
{
return;
}
2021-01-20 02:06:10 +00:00
2022-02-23 05:14:32 +00:00
if (Loop)
{
Parent.Handle.LoopCount = 255;
Parent.Handle.LoopBegin = Parent.LoopStart;
Parent.Handle.LoopLength = Parent.LoopLength;
}
else
{
Parent.Handle.LoopCount = 0;
Parent.Handle.LoopBegin = 0;
Parent.Handle.LoopLength = 0;
}
2021-01-20 02:06:10 +00:00
2022-02-23 05:14:32 +00:00
FAudio.FAudioSourceVoice_SubmitSourceBuffer(
2023-03-02 01:47:09 +00:00
Voice,
2022-02-23 05:14:32 +00:00
ref Parent.Handle,
IntPtr.Zero
);
2021-01-20 02:06:10 +00:00
2023-03-02 01:47:09 +00:00
FAudio.FAudioSourceVoice_Start(Voice, 0, operationSet);
2022-02-23 05:14:32 +00:00
State = SoundState.Playing;
}
2021-01-20 02:06:10 +00:00
2022-02-23 05:14:32 +00:00
public override void Pause()
{
if (State == SoundState.Paused)
{
2023-03-02 01:47:09 +00:00
FAudio.FAudioSourceVoice_Stop(Voice, 0, 0);
2022-02-23 05:14:32 +00:00
State = SoundState.Paused;
}
}
2021-01-20 02:06:10 +00:00
public override void Stop()
2022-02-23 05:14:32 +00:00
{
2023-03-02 01:47:09 +00:00
FAudio.FAudioSourceVoice_ExitLoop(Voice, 0);
State = SoundState.Stopped;
2022-02-23 05:14:32 +00:00
}
public override void StopImmediate()
{
2023-03-02 01:47:09 +00:00
FAudio.FAudioSourceVoice_Stop(Voice, 0, 0);
FAudio.FAudioSourceVoice_FlushSourceBuffers(Voice);
State = SoundState.Stopped;
}
public void Seek(uint sampleFrame)
2022-04-20 21:29:46 +00:00
{
if (State == SoundState.Playing)
{
2023-03-02 01:47:09 +00:00
FAudio.FAudioSourceVoice_Stop(Voice, 0, 0);
FAudio.FAudioSourceVoice_FlushSourceBuffers(Voice);
2022-04-20 21:29:46 +00:00
}
Parent.Handle.PlayBegin = sampleFrame;
}
2023-05-12 00:56:40 +00:00
// Call this when you no longer need the sound instance.
// If AutoFree is set, this will automatically be called when the sound instance stops playing.
// If the sound isn't stopped when you call this, things might get weird!
public void Free()
{
Parent.FreeInstance(this);
}
internal void Reset()
{
Pan = 0;
Pitch = 0;
Volume = 1;
Loop = false;
Is3D = false;
FilterType = FilterType.None;
}
2022-02-23 05:14:32 +00:00
}
2021-01-20 02:06:10 +00:00
}