Skip to content

Commit 0fca788

Browse files
committed
fixup! Port XAudio to Silk.NET
1 parent 7f6cbdc commit 0fca788

File tree

2 files changed

+77
-4
lines changed

2 files changed

+77
-4
lines changed

sources/engine/Stride.Audio/Layers/XAudio/AudioProvider.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#if WINDOWS
44

55
using System;
6+
using System.Runtime.CompilerServices;
67
using System.Runtime.InteropServices;
78
using Silk.NET.Core.Native;
89
using Silk.NET.XAudio;
@@ -183,8 +184,10 @@ public unsafe Source SourceCreate(Listener listener, int sampleRate, int maxNumb
183184
pcmWaveFormat.WBitsPerSample = 16;
184185
pcmWaveFormat.NBlockAlign = (ushort)(pcmWaveFormat.NChannels * pcmWaveFormat.WBitsPerSample / 8);
185186

186-
187-
int result = listener.device.xAudio->CreateSourceVoice(ref source.sourceVoice, &pcmWaveFormat, 0, XAUDIO2_MAX_FREQ_RATIO, null, null, null);
187+
dynamic d = source;
188+
IXAudio2VoiceCallback callback = d;
189+
190+
int result = listener.device.xAudio->CreateSourceVoice(ref source.sourceVoice, &pcmWaveFormat, 0, XAUDIO2_MAX_FREQ_RATIO, ref callback, null, null);
188191
if (HResult.IndicatesFailure(result))
189192
{
190193
return null;

sources/engine/Stride.Audio/Layers/XAudio/Source.cs

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
22
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
33
#if WINDOWS
4+
using System.Runtime.InteropServices;
45
using Silk.NET.XAudio;
56
using Stride.Audio.Layers.XAudio;
7+
using Buffer = Silk.NET.XAudio.Buffer;
68

79
namespace Stride.Audio;
810

911
public sealed unsafe partial class Source
1012
{
11-
public IXAudio2VoiceCallback value = new();
1213
public IXAudio2MasteringVoice* masteringVoice;
1314
public IXAudio2SourceVoice* sourceVoice;
1415
public X3DAudioEmitter emitter;
@@ -27,9 +28,78 @@ public sealed unsafe partial class Source
2728

2829
public volatile int samplesAtBegin = 0;
2930

30-
public unsafe void GetState(VoiceState* state)
31+
public void GetState(VoiceState* state)
3132
{
3233
sourceVoice->GetState(state, 0);
3334
}
35+
36+
public void OnVoiceProcessingPassStart(uint BytesRequired) {}
37+
public void OnVoiceProcessingPassEnd() {}
38+
39+
public void OnStreamEnd()
40+
{
41+
if (playing)
42+
{
43+
if (Streamed)
44+
{
45+
//buffer was flagged as end of stream
46+
//looping is handled by the streamer, in the top level layer
47+
new AudioProvider().SourceStop(this);
48+
}
49+
else if (!looped)
50+
{
51+
playing = false;
52+
pause = false;
53+
}
54+
}
55+
}
56+
57+
public void OnBufferStart(void* pBufferContext)
58+
{
59+
if (Streamed)
60+
{
61+
var buffer = Marshal.PtrToStructure<AudioBuffer>(new(pBufferContext));
62+
63+
if (buffer.Type == BufferType.BeginOfStream)
64+
{
65+
//we need this info to compute position of stream
66+
VoiceState state;
67+
GetState(&state);
68+
69+
samplesAtBegin = (int)state.SamplesPlayed;
70+
}
71+
}
72+
}
73+
74+
public void OnBufferEnd(void* pBufferContext)
75+
{
76+
if (Streamed)
77+
{
78+
var buffer = Marshal.PtrToStructure<AudioBuffer>(new(pBufferContext));
79+
80+
for (int i = 0; i < freeBuffersMax; i++)
81+
{
82+
if (freeBuffers[i] == null)
83+
{
84+
freeBuffers[i] = buffer;
85+
break;
86+
}
87+
}
88+
89+
}
90+
}
91+
92+
public void OnLoopEnd(void* pBufferContext)
93+
{
94+
if (!Streamed)
95+
{
96+
VoiceState state;
97+
GetState(&state);
98+
99+
samplesAtBegin = (int)state.SamplesPlayed;
100+
}
101+
}
102+
103+
public void OnVoiceError(void* pBufferContext, int Error) { }
34104
}
35105
#endif

0 commit comments

Comments
 (0)