From bd803b622a91ea7aa8dcd9cf4cf181b2e73b37d2 Mon Sep 17 00:00:00 2001 From: Brandon Smith Date: Fri, 4 Sep 2015 22:53:45 -0300 Subject: [PATCH] Added WaitVoice --- src/Discord.Net/DiscordClient.cs | 10 ++++++++++ src/Discord.Net/DiscordVoiceSocket.cs | 23 ++++++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/Discord.Net/DiscordClient.cs b/src/Discord.Net/DiscordClient.cs index 34255168a..f0d268e7c 100644 --- a/src/Discord.Net/DiscordClient.cs +++ b/src/Discord.Net/DiscordClient.cs @@ -667,6 +667,16 @@ namespace Discord RaiseOnDebugMessage(DebugMessageType.VoiceOutput, $"Cleared the voice buffer."); _voiceWebSocket.ClearPCMFrames(); } + + /// Returns a task that completes once the voice output buffer is empty. + public async Task WaitVoice() + { + CheckReady(); + if (!_config.EnableVoice) throw new InvalidOperationException("Voice is not enabled for this client."); + + _voiceWebSocket.Wait(); + await TaskHelper.CompletedTask; + } #endif //Helpers diff --git a/src/Discord.Net/DiscordVoiceSocket.cs b/src/Discord.Net/DiscordVoiceSocket.cs index 8acb58b51..ecf8f4f0c 100644 --- a/src/Discord.Net/DiscordVoiceSocket.cs +++ b/src/Discord.Net/DiscordVoiceSocket.cs @@ -26,7 +26,7 @@ namespace Discord private OpusEncoder _encoder; private ConcurrentQueue _sendQueue; - private ManualResetEventSlim _sendQueueWait; + private ManualResetEventSlim _sendQueueWait, _sendQueueEmptyWait; private UdpClient _udp; private IPEndPoint _endpoint; private bool _isReady, _isClearing; @@ -45,6 +45,7 @@ namespace Discord _connectWaitOnLogin = new ManualResetEventSlim(false); _sendQueue = new ConcurrentQueue(); _sendQueueWait = new ManualResetEventSlim(true); + _sendQueueEmptyWait = new ManualResetEventSlim(true); _encoder = new OpusEncoder(48000, 1, 20, Application.Audio); _encodingBuffer = new byte[4000]; _targetAudioBufferLength = audioBufferLength / 20; @@ -170,10 +171,6 @@ namespace Discord while (!cancelToken.IsCancellationRequested) { - //If we have less than our target data buffered, request more - if (_sendQueue.Count < _targetAudioBufferLength) - _sendQueueWait.Set(); - double ticksToNextFrame = nextTicks - sw.ElapsedTicks; if (ticksToNextFrame <= 0.0) { @@ -199,6 +196,16 @@ namespace Discord } timestamp = unchecked(timestamp + samplesPerFrame); nextTicks += ticksPerFrame; + + //If we have less than our target data buffered, request more + int count = _sendQueue.Count; + if (count == 0) + { + _sendQueueWait.Set(); + _sendQueueEmptyWait.Set(); + } + else if (count < _targetAudioBufferLength) + _sendQueueWait.Set(); } } } @@ -391,6 +398,7 @@ namespace Discord _sendQueue.Enqueue(payload); if (_sendQueue.Count >= _targetAudioBufferLength) _sendQueueWait.Reset(); + _sendQueueEmptyWait.Reset(); } public void ClearPCMFrames() { @@ -412,6 +420,11 @@ namespace Discord { return new VoiceWebSocketCommands.KeepAlive(); } + + public void Wait() + { + _sendQueueEmptyWait.Wait(); + } } } #endif \ No newline at end of file