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();
}