From d8902f3fb111c6e8def0018b2454b4c1ea014354 Mon Sep 17 00:00:00 2001 From: RogueException Date: Tue, 5 Jan 2016 00:23:20 -0400 Subject: [PATCH] Added virtual output stream for AudioClient --- src/Discord.Net.Audio/AudioClient.cs | 39 ++++++++++++++++++++++++++--- src/Discord.Net.Audio/AudioServiceConfig.cs | 2 +- src/Discord.Net.Audio/SimpleAudioClient.cs | 5 ++-- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/Discord.Net.Audio/AudioClient.cs b/src/Discord.Net.Audio/AudioClient.cs index 8d6dbf693..20aaed2db 100644 --- a/src/Discord.Net.Audio/AudioClient.cs +++ b/src/Discord.Net.Audio/AudioClient.cs @@ -4,6 +4,7 @@ using Discord.Net.WebSockets; using Newtonsoft.Json; using Nito.AsyncEx; using System; +using System.IO; using System.Threading; using System.Threading.Tasks; @@ -11,6 +12,35 @@ namespace Discord.Audio { internal class AudioClient : IAudioClient { + private class OutStream : Stream + { + public override bool CanRead => false; + public override bool CanSeek => false; + public override bool CanWrite => true; + + private readonly AudioClient _client; + + internal OutStream(AudioClient client) + { + _client = client; + } + + public override long Length { get { throw new InvalidOperationException(); } } + public override long Position + { + get { throw new InvalidOperationException(); } + set { throw new InvalidOperationException(); } + } + public override void Flush() { throw new InvalidOperationException(); } + public override long Seek(long offset, SeekOrigin origin) { throw new InvalidOperationException(); } + public override void SetLength(long value) { throw new InvalidOperationException(); } + public override int Read(byte[] buffer, int offset, int count) { throw new InvalidOperationException(); } + public override void Write(byte[] buffer, int offset, int count) + { + _client.Send(buffer, offset, count); + } + } + private readonly AsyncLock _connectionLock; private readonly JsonSerializer _serializer; private CancellationTokenSource _cancelTokenSource; @@ -20,6 +50,7 @@ namespace Discord.Audio public int Id { get; } public GatewaySocket GatewaySocket { get; } public VoiceWebSocket VoiceSocket { get; } + public Stream OutputStream { get; } public ConnectionState State => VoiceSocket.State; public Server Server => VoiceSocket.Server; @@ -31,7 +62,8 @@ namespace Discord.Audio Id = clientId; GatewaySocket = gatewaySocket; Logger = logger; - + OutputStream = new OutStream(this); + _connectionLock = new AsyncLock(); _serializer = new JsonSerializer(); @@ -169,14 +201,15 @@ namespace Discord.Audio /// Sends a PCM frame to the voice server. Will block until space frees up in the outgoing buffer. /// PCM frame to send. This must be a single or collection of uncompressed 48Kz monochannel 20ms PCM frames. /// Number of bytes in this frame. - public void Send(byte[] data, int count) + public void Send(byte[] data, int offset, int count) { if (data == null) throw new ArgumentException(nameof(data)); if (count < 0) throw new ArgumentOutOfRangeException(nameof(count)); + if (offset < 0) throw new ArgumentOutOfRangeException(nameof(count)); if (VoiceSocket.Server == null) return; //Has been closed if (count != 0) - VoiceSocket.SendPCMFrames(data, count); + VoiceSocket.SendPCMFrames(data, offset, count); } /// Clears the PCM buffer. diff --git a/src/Discord.Net.Audio/AudioServiceConfig.cs b/src/Discord.Net.Audio/AudioServiceConfig.cs index 4a63cb249..a832554ce 100644 --- a/src/Discord.Net.Audio/AudioServiceConfig.cs +++ b/src/Discord.Net.Audio/AudioServiceConfig.cs @@ -29,7 +29,7 @@ namespace Discord.Audio public bool EnableMultiserver { get { return _enableMultiserver; } set { SetValue(ref _enableMultiserver, value); } } private bool _enableMultiserver = false; - /// Gets or sets the max buffer length (in milliseconds) for outgoing voice packets. + /// Gets or sets the buffer length (in milliseconds) for outgoing voice packets. public int BufferLength { get { return _bufferLength; } set { SetValue(ref _bufferLength, value); } } private int _bufferLength = 1000; diff --git a/src/Discord.Net.Audio/SimpleAudioClient.cs b/src/Discord.Net.Audio/SimpleAudioClient.cs index 580b62e9c..222dc691d 100644 --- a/src/Discord.Net.Audio/SimpleAudioClient.cs +++ b/src/Discord.Net.Audio/SimpleAudioClient.cs @@ -1,6 +1,6 @@ using Discord.Logging; using Nito.AsyncEx; -using System.Threading; +using System.IO; using System.Threading.Tasks; namespace Discord.Audio @@ -14,6 +14,7 @@ namespace Discord.Audio ConnectionState IAudioClient.State => _client.VoiceSocket.State; Server IAudioClient.Server => _client.VoiceSocket.Server; Channel IAudioClient.Channel => _client.VoiceSocket.Channel; + Stream IAudioClient.OutputStream => _client.OutputStream; public VirtualClient(SimpleAudioClient client) { @@ -23,7 +24,7 @@ namespace Discord.Audio Task IAudioClient.Disconnect() => _client.Leave(this); Task IAudioClient.Join(Channel channel) => _client.Join(channel); - void IAudioClient.Send(byte[] data, int count) => _client.Send(data, count); + void IAudioClient.Send(byte[] data, int offset, int count) => _client.Send(data, offset, count); void IAudioClient.Clear() => _client.Clear(); void IAudioClient.Wait() => _client.Wait(); }