2014-12-19 9 views
0

SharpDX 샘플 (https://github.com/sharpdx/SharpDX-Samples/blob/master/WindowsDesktop/XAudio2/AudioPlayerApp/AudioPlayer.cs)의 스트리밍 원칙을 사용하여 동시에 여러 사운드를 재생하고 있습니다.두 개의 Xaudio2 스트리밍 소스 코드를 동기화하는 방법

동일한 노래의 여러 버전 목록이 있습니다. 나는 그들을 정확히 같은 시간에 시작하고 싶다. 각 노래에 대해 새로운 작업을 시작하고 CountDownEvent와 ManualResetEvent의 조합을 사용하여 동시에 시작할 수 있도록합니다.

작업 준비에서 버퍼를 준비하고 노래를 재생할 준비가되었음을 CountDownEvent에 알립니다. 그런 다음 노래는 ManualResetEvent에서 신호를 기다립니다. CountDownEvent가 준비중인 각 노래의 신호를 가지면 ManualResetEvent에 신호를 보내고 SubmitSourceBuffer가 호출됩니다.

9 곡 중 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는 문을 사용하여 각 노래에 대해 동일한 순서로, 여러 audiodevices에 각 노래에 대한 버퍼를 보낼 수 있습니다. 준비 상태는 메모리, 오디오 코드 등을 미리 설정하는로드 방법을 사용하여 미리 설정됩니다.

작업 세트를 동시에 사용하여 소스 보이스를 시작할 수 있다는 것을 알고 있지만 다른 방법으로 (시계 또는 다른 동기화 방법 사용) 샘플이 각 연주 곡에 대해 동시에 전송되는지 확인하십시오.

답변

0

XAudio2 Operation Sets을 사용하면 외부 사용자 지정 동기화 이벤트로 해결할 필요없이 직접이 작업을 수행 할 수 있습니다.