fix(audio): keep unavailable world slots quiescent
Construct the retail-sized world voice ledger independently of OpenAL device availability so world reveal suspension is a safe no-op on machines without an audio backend. Co-authored-by: Erik Nilsson <erikn@users.noreply.github.com>
This commit is contained in:
parent
3f1548b952
commit
a77ba06722
2 changed files with 25 additions and 2 deletions
|
|
@ -82,7 +82,7 @@ public sealed unsafe class OpenAlAudioEngine : IAudioEngine, IWorldAudioQuiescen
|
||||||
public bool InUse;
|
public bool InUse;
|
||||||
public uint PriorityBase; // raw priority from SoundEntry.Priority
|
public uint PriorityBase; // raw priority from SoundEntry.Priority
|
||||||
}
|
}
|
||||||
private readonly Slot3D[] _pool3D = new Slot3D[PoolSize3D];
|
private readonly Slot3D[] _pool3D = CreateWorldSlots();
|
||||||
private int _pool3DCursor; // round-robin start
|
private int _pool3DCursor; // round-robin start
|
||||||
private bool _worldAudioSuspended;
|
private bool _worldAudioSuspended;
|
||||||
|
|
||||||
|
|
@ -159,7 +159,7 @@ public sealed unsafe class OpenAlAudioEngine : IAudioEngine, IWorldAudioQuiescen
|
||||||
for (int i = 0; i < PoolSize3D; i++)
|
for (int i = 0; i < PoolSize3D; i++)
|
||||||
{
|
{
|
||||||
uint src = _resources.Create3DSource();
|
uint src = _resources.Create3DSource();
|
||||||
_pool3D[i] = new Slot3D { SourceId = src, InUse = false };
|
_pool3D[i].SourceId = src;
|
||||||
}
|
}
|
||||||
|
|
||||||
// UI sources are source-relative (attached to listener) so they
|
// UI sources are source-relative (attached to listener) so they
|
||||||
|
|
@ -520,4 +520,12 @@ public sealed unsafe class OpenAlAudioEngine : IAudioEngine, IWorldAudioQuiescen
|
||||||
slot.PriorityBase = 0;
|
slot.PriorityBase = 0;
|
||||||
slot.InUse = false;
|
slot.InUse = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Slot3D[] CreateWorldSlots()
|
||||||
|
{
|
||||||
|
var slots = new Slot3D[PoolSize3D];
|
||||||
|
for (int i = 0; i < slots.Length; i++)
|
||||||
|
slots[i] = new Slot3D();
|
||||||
|
return slots;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,21 @@ public sealed class OpenAlResourceLifetimeTests
|
||||||
Assert.Equal(1, api.CloseDeviceCalls);
|
Assert.Equal(1, api.CloseDeviceCalls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void UnavailableEngineWorldQuiescenceRemainsASafeNoOp()
|
||||||
|
{
|
||||||
|
var api = new RecordingApi { ContextResult = 0 };
|
||||||
|
var engine = new OpenAlAudioEngine(new Factory(api));
|
||||||
|
|
||||||
|
engine.SuspendWorldAudio();
|
||||||
|
engine.StopAllForOwner(0x50000001u);
|
||||||
|
engine.ResumeWorldAudio();
|
||||||
|
|
||||||
|
Assert.False(engine.IsAvailable);
|
||||||
|
Assert.True(engine.IsDisposalComplete);
|
||||||
|
Assert.Empty(api.GeneratedSources);
|
||||||
|
}
|
||||||
|
|
||||||
private sealed class Factory(IOpenAlResourceApi api) : IOpenAlResourceApiFactory
|
private sealed class Factory(IOpenAlResourceApi api) : IOpenAlResourceApiFactory
|
||||||
{
|
{
|
||||||
public IOpenAlResourceApi Create() => api;
|
public IOpenAlResourceApi Create() => api;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue