C# 如何同步两个Xaudio2流媒体源语音
我使用SharpDX样本中的流媒体原理同时播放多个声音 我有一个同一首歌的多个版本的列表。我想在完全相同的时间启动它们。我为每首歌曲启动一个新任务,并结合使用CountDownEvent和ManualResetEvent确保它们同时启动: 在任务中,我准备缓冲区并向倒计时事件发送信号,表示歌曲已准备好播放。然后,乐曲等待ManualReset事件的信号。当倒计时事件有一个来自每首歌曲的信号准备就绪时,它向ManualResetEvent发出信号,并调用SubmitSourceBuffer 10首歌曲中有9首开始采样同步,歌曲之间没有可检测到的相位,只是声音更大,但有时其中一首稍微关闭 下面是一些需要详细说明的代码:C# 如何同步两个Xaudio2流媒体源语音,c#,sharpdx,xaudio2,C#,Sharpdx,Xaudio2,我使用SharpDX样本中的流媒体原理同时播放多个声音 我有一个同一首歌的多个版本的列表。我想在完全相同的时间启动它们。我为每首歌曲启动一个新任务,并结合使用CountDownEvent和ManualResetEvent确保它们同时启动: 在任务中,我准备缓冲区并向倒计时事件发送信号,表示歌曲已准备好播放。然后,乐曲等待ManualReset事件的信号。当倒计时事件有一个来自每首歌曲的信号准备就绪时,它向ManualResetEvent发出信号,并调用SubmitSourceBuffer 10首
Task playingtask = Task.Factory.StartNew(() =>
{
int nextbuffer = 0;
long zeroticks = MasterClock.Elapsed.Ticks;
try
{
while (true)
{
if (oursong.ADecoder == null || oursong.Status == PlaybackStatus.Stop) { break; }
var sampleiterator = oursong.ADecoder.GetSamples(TimeSpan.FromTicks(oursong.Position)).GetEnumerator();
while (true)
{
if (oursong.ADecoder == null || oursong.Status == PlaybackStatus.Stop) { break; }
foreach (SourceVoice SVoice in oursong.SVoices)
{
while (SVoice.State.BuffersQueued == oursong.BufferRing.Length && oursong.ADecoder != null)
{
BufferEndEvent.WaitOne(1);
}
}
if (!sampleiterator.MoveNext())
{
break;
}
var bufferpointer = sampleiterator.Current;
if (bufferpointer.Size > oursong.MBufferRing[nextbuffer].Size)
{
if (oursong.MBufferRing[nextbuffer].Pointer != IntPtr.Zero)
{
SharpDX.Utilities.FreeMemory(oursong.MBufferRing[nextbuffer].Pointer);
}
oursong.MBufferRing[nextbuffer].Pointer = SharpDX.Utilities.AllocateMemory(bufferpointer.Size);
oursong.MBufferRing[nextbuffer].Size = bufferpointer.Size;
}
SharpDX.Utilities.CopyMemory(oursong.MBufferRing[nextbuffer].Pointer, bufferpointer.Pointer, bufferpointer.Size);
oursong.BufferRing[nextbuffer].AudioDataPointer = oursong.MBufferRing[nextbuffer].Pointer;
oursong.BufferRing[nextbuffer].AudioBytes = bufferpointer.Size;
if (oursong.Status == PlaybackStatus.Ready)
{
CountDownEvent.Signal();
SongManualResetEvent.WaitOne();
oursong.Status = PlaybackStatus.Start;
}
foreach (SourceVoice SVoice in oursong.SVoices)
{
SVoice.SubmitSourceBuffer(oursong.BufferRing[nextbuffer], null);
}
oursong.Position += MasterClock.Elapsed.Ticks - zeroticks;
zeroticks = MasterClock.Elapsed.Ticks;
nextbuffer = ++nextbuffer % oursong.BufferRing.Length;
}
}
}
finally
{
DisposeAudio(oursong);
oursong.Position = oursong.Start;
}
}, TaskCreationOptions.LongRunning);
旁注:我使用foreach语句将每首歌曲的缓冲区以相同的顺序发送到多个音频设备。使用预先设置存储器、音频解码器等的加载方法预先设置就绪状态
我知道可以使用操作集同时启动sourcevoices,但是有没有其他方法可以使用时钟或其他同步方法来确保在播放每首歌曲的同时发送样本?您应该能够通过使用直接实现这一点,而不必使用外部自定义同步来解决它事件