diff --git a/src/Discord.Net.WebSocket/Audio/AudioClient.cs b/src/Discord.Net.WebSocket/Audio/AudioClient.cs index 0f5079caa..0f2f50309 100644 --- a/src/Discord.Net.WebSocket/Audio/AudioClient.cs +++ b/src/Discord.Net.WebSocket/Audio/AudioClient.cs @@ -314,6 +314,7 @@ namespace Discord.Audio internal void Dispose(bool disposing) { + DisconnectInternalAsync(null).GetAwaiter().GetResult(); if (!_isDisposed) _isDisposed = true; ApiClient.Dispose(); diff --git a/src/Discord.Net.WebSocket/Audio/Streams/OpusEncodeStream.cs b/src/Discord.Net.WebSocket/Audio/Streams/OpusEncodeStream.cs index d207e3cf7..a7c6e45a0 100644 --- a/src/Discord.Net.WebSocket/Audio/Streams/OpusEncodeStream.cs +++ b/src/Discord.Net.WebSocket/Audio/Streams/OpusEncodeStream.cs @@ -1,4 +1,6 @@ using System; +using System.Threading; +using System.Threading.Tasks; namespace Discord.Audio { @@ -25,6 +27,10 @@ namespace Discord.Audio public override void Write(byte[] buffer, int offset, int count) { + WriteAsync(buffer, offset, count, CancellationToken.None).GetAwaiter().GetResult(); + } + public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { //Assume threadsafe while (count > 0) { @@ -37,7 +43,7 @@ namespace Discord.Audio _partialFramePos = 0; int encFrameSize = _encoder.EncodeFrame(_partialFrameBuffer, 0, _frameSize, _buffer, 0); - base.Write(_buffer, 0, encFrameSize); + await base.WriteAsync(_buffer, 0, encFrameSize, cancellationToken).ConfigureAwait(false); } else { @@ -48,6 +54,22 @@ namespace Discord.Audio } } + public override void Flush() + { + FlushAsync(CancellationToken.None).GetAwaiter().GetResult(); + } + public override async Task FlushAsync(CancellationToken cancellationToken) + { + try + { + int encFrameSize = _encoder.EncodeFrame(_partialFrameBuffer, 0, _partialFramePos, _buffer, 0); + base.Write(_buffer, 0, encFrameSize); + } + catch (Exception) { } //Incomplete frame + _partialFramePos = 0; + await base.FlushAsync(cancellationToken).ConfigureAwait(false); + } + protected override void Dispose(bool disposing) { base.Dispose(disposing); diff --git a/src/Discord.Net.WebSocket/Audio/Streams/RTPWriteStream.cs b/src/Discord.Net.WebSocket/Audio/Streams/RTPWriteStream.cs index 217555052..300cd194c 100644 --- a/src/Discord.Net.WebSocket/Audio/Streams/RTPWriteStream.cs +++ b/src/Discord.Net.WebSocket/Audio/Streams/RTPWriteStream.cs @@ -1,5 +1,7 @@ using System; using System.IO; +using System.Threading; +using System.Threading.Tasks; namespace Discord.Audio { @@ -34,6 +36,10 @@ namespace Discord.Audio public override void Write(byte[] buffer, int offset, int count) { + WriteAsync(buffer, offset, count, CancellationToken.None).GetAwaiter().GetResult(); + } + public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { unchecked { if (_nonce[3]++ == byte.MaxValue) @@ -48,10 +54,17 @@ namespace Discord.Audio count = SecretBox.Encrypt(buffer, offset, count, _buffer, 12, _nonce, _secretKey); Buffer.BlockCopy(_nonce, 0, _buffer, 0, 12); //Copy the RTP header from nonce to buffer - _target.SendAsync(_buffer, count + 12).GetAwaiter().GetResult(); + await _target.SendAsync(_buffer, count + 12).ConfigureAwait(false); } - public override void Flush() { } + public override void Flush() + { + FlushAsync(CancellationToken.None).GetAwaiter().GetResult(); + } + public override async Task FlushAsync(CancellationToken cancellationToken) + { + await _target.FlushAsync().ConfigureAwait(false); + } public override long Length { get { throw new NotSupportedException(); } } public override long Position diff --git a/src/Discord.Net.WebSocket/Audio/Targets/BufferedAudioTarget.cs b/src/Discord.Net.WebSocket/Audio/Targets/BufferedAudioTarget.cs index 848a77131..e227a975c 100644 --- a/src/Discord.Net.WebSocket/Audio/Targets/BufferedAudioTarget.cs +++ b/src/Discord.Net.WebSocket/Audio/Targets/BufferedAudioTarget.cs @@ -65,6 +65,16 @@ namespace Discord.Audio return Task.Delay(0); } + public async Task FlushAsync() + { + while (true) + { + if (_queue.Count == 0) + return; + await Task.Delay(250).ConfigureAwait(false); + } + } + protected void Dispose(bool disposing) { if (disposing) diff --git a/src/Discord.Net.WebSocket/Audio/Targets/DirectAudioTarget.cs b/src/Discord.Net.WebSocket/Audio/Targets/DirectAudioTarget.cs index 08cdfcfe6..c5b0983d0 100644 --- a/src/Discord.Net.WebSocket/Audio/Targets/DirectAudioTarget.cs +++ b/src/Discord.Net.WebSocket/Audio/Targets/DirectAudioTarget.cs @@ -12,5 +12,8 @@ namespace Discord.Audio public Task SendAsync(byte[] buffer, int count) => _client.SendAsync(buffer, count); + + public Task FlushAsync() + => Task.Delay(0); } } diff --git a/src/Discord.Net.WebSocket/Audio/Targets/IAudioTarget.cs b/src/Discord.Net.WebSocket/Audio/Targets/IAudioTarget.cs index 51b19a862..8c4384550 100644 --- a/src/Discord.Net.WebSocket/Audio/Targets/IAudioTarget.cs +++ b/src/Discord.Net.WebSocket/Audio/Targets/IAudioTarget.cs @@ -5,5 +5,6 @@ namespace Discord.Audio internal interface IAudioTarget { Task SendAsync(byte[] buffer, int count); + Task FlushAsync(); } }