Added virtual output stream for AudioClient

This commit is contained in:
RogueException
2016-01-05 00:23:20 -04:00
parent 4f7118f241
commit d8902f3fb1
3 changed files with 40 additions and 6 deletions

View File

@@ -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
/// <summary> Sends a PCM frame to the voice server. Will block until space frees up in the outgoing buffer. </summary>
/// <param name="data">PCM frame to send. This must be a single or collection of uncompressed 48Kz monochannel 20ms PCM frames. </param>
/// <param name="count">Number of bytes in this frame. </param>
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);
}
/// <summary> Clears the PCM buffer. </summary>

View File

@@ -29,7 +29,7 @@ namespace Discord.Audio
public bool EnableMultiserver { get { return _enableMultiserver; } set { SetValue(ref _enableMultiserver, value); } }
private bool _enableMultiserver = false;
/// <summary> Gets or sets the max buffer length (in milliseconds) for outgoing voice packets. </summary>
/// <summary> Gets or sets the buffer length (in milliseconds) for outgoing voice packets. </summary>
public int BufferLength { get { return _bufferLength; } set { SetValue(ref _bufferLength, value); } }
private int _bufferLength = 1000;

View File

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