| @@ -14,8 +14,6 @@ namespace Discord.Audio | |||||
| { | { | ||||
| internal class AudioClient : IAudioClient, IDisposable | internal class AudioClient : IAudioClient, IDisposable | ||||
| { | { | ||||
| public const int SampleRate = 48000; | |||||
| public event Func<Task> Connected | public event Func<Task> Connected | ||||
| { | { | ||||
| add { _connectedEvent.Add(value); } | add { _connectedEvent.Add(value); } | ||||
| @@ -81,6 +79,7 @@ namespace Discord.Audio | |||||
| ApiClient.SentGatewayMessage += async opCode => await _audioLogger.DebugAsync($"Sent {opCode}").ConfigureAwait(false); | ApiClient.SentGatewayMessage += async opCode => await _audioLogger.DebugAsync($"Sent {opCode}").ConfigureAwait(false); | ||||
| ApiClient.SentDiscovery += async () => await _audioLogger.DebugAsync($"Sent Discovery").ConfigureAwait(false); | ApiClient.SentDiscovery += async () => await _audioLogger.DebugAsync($"Sent Discovery").ConfigureAwait(false); | ||||
| ApiClient.SentData += async bytes => await _audioLogger.DebugAsync($"Sent {bytes} Bytes").ConfigureAwait(false); | |||||
| ApiClient.ReceivedEvent += ProcessMessageAsync; | ApiClient.ReceivedEvent += ProcessMessageAsync; | ||||
| ApiClient.ReceivedPacket += ProcessPacketAsync; | ApiClient.ReceivedPacket += ProcessPacketAsync; | ||||
| ApiClient.Disconnected += async ex => | ApiClient.Disconnected += async ex => | ||||
| @@ -185,10 +184,10 @@ namespace Discord.Audio | |||||
| { | { | ||||
| return new RTPWriteStream(this, _secretKey, samplesPerFrame, _ssrc, bufferSize = 4000); | return new RTPWriteStream(this, _secretKey, samplesPerFrame, _ssrc, bufferSize = 4000); | ||||
| } | } | ||||
| public OpusEncodeStream CreatePCMStream(int samplesPerFrame, int? bitrate = null, int channels = 2, | |||||
| public OpusEncodeStream CreatePCMStream(int samplesPerFrame, int? bitrate = null, | |||||
| OpusApplication application = OpusApplication.MusicOrMixed, int bufferSize = 4000) | OpusApplication application = OpusApplication.MusicOrMixed, int bufferSize = 4000) | ||||
| { | { | ||||
| return new OpusEncodeStream(this, _secretKey, samplesPerFrame, _ssrc, SampleRate, bitrate, channels, application, bufferSize); | |||||
| return new OpusEncodeStream(this, _secretKey, samplesPerFrame, _ssrc, bitrate, application, bufferSize); | |||||
| } | } | ||||
| private async Task ProcessMessageAsync(VoiceOpCode opCode, object payload) | private async Task ProcessMessageAsync(VoiceOpCode opCode, object payload) | ||||
| @@ -283,7 +282,7 @@ namespace Discord.Audio | |||||
| try | try | ||||
| { | { | ||||
| ip = Encoding.UTF8.GetString(packet, 4, 70 - 6).TrimEnd('\0'); | ip = Encoding.UTF8.GetString(packet, 4, 70 - 6).TrimEnd('\0'); | ||||
| port = packet[68] | packet[69] << 8; | |||||
| port = packet[69] | (packet[68] << 8); | |||||
| } | } | ||||
| catch { return; } | catch { return; } | ||||
| @@ -18,7 +18,6 @@ namespace Discord.Audio | |||||
| Task DisconnectAsync(); | Task DisconnectAsync(); | ||||
| RTPWriteStream CreateOpusStream(int samplesPerFrame, int bufferSize = 4000); | RTPWriteStream CreateOpusStream(int samplesPerFrame, int bufferSize = 4000); | ||||
| OpusEncodeStream CreatePCMStream(int samplesPerFrame, int? bitrate = null, int channels = 2, | |||||
| OpusApplication application = OpusApplication.MusicOrMixed, int bufferSize = 4000); | |||||
| OpusEncodeStream CreatePCMStream(int samplesPerFrame, int? bitrate = null, OpusApplication application = OpusApplication.MusicOrMixed, int bufferSize = 4000); | |||||
| } | } | ||||
| } | } | ||||
| @@ -2,15 +2,18 @@ | |||||
| { | { | ||||
| public class OpusEncodeStream : RTPWriteStream | public class OpusEncodeStream : RTPWriteStream | ||||
| { | { | ||||
| public int SampleRate = 48000; | |||||
| public int Channels = 2; | |||||
| private readonly byte[] _buffer; | private readonly byte[] _buffer; | ||||
| private readonly OpusEncoder _encoder; | private readonly OpusEncoder _encoder; | ||||
| internal OpusEncodeStream(AudioClient audioClient, byte[] secretKey, int samplesPerFrame, uint ssrc, int samplingRate, int? bitrate = null, | |||||
| int channels = OpusConverter.MaxChannels, OpusApplication application = OpusApplication.MusicOrMixed, int bufferSize = 4000) | |||||
| internal OpusEncodeStream(AudioClient audioClient, byte[] secretKey, int samplesPerFrame, uint ssrc, int? bitrate = null, | |||||
| OpusApplication application = OpusApplication.MusicOrMixed, int bufferSize = 4000) | |||||
| : base(audioClient, secretKey, samplesPerFrame, ssrc) | : base(audioClient, secretKey, samplesPerFrame, ssrc) | ||||
| { | { | ||||
| _buffer = new byte[bufferSize]; | _buffer = new byte[bufferSize]; | ||||
| _encoder = new OpusEncoder(samplingRate, channels); | |||||
| _encoder = new OpusEncoder(SampleRate, Channels); | |||||
| _encoder.SetForwardErrorCorrection(true); | _encoder.SetForwardErrorCorrection(true); | ||||
| if (bitrate != null) | if (bitrate != null) | ||||
| @@ -36,7 +36,7 @@ namespace Discord.Audio | |||||
| unchecked | unchecked | ||||
| { | { | ||||
| if (_buffer[3]++ == byte.MaxValue) | if (_buffer[3]++ == byte.MaxValue) | ||||
| _buffer[4]++; | |||||
| _buffer[2]++; | |||||
| _timestamp += (uint)_samplesPerFrame; | _timestamp += (uint)_samplesPerFrame; | ||||
| _buffer[4] = (byte)(_timestamp >> 24); | _buffer[4] = (byte)(_timestamp >> 24); | ||||
| @@ -45,9 +45,9 @@ namespace Discord.Audio | |||||
| _buffer[7] = (byte)(_timestamp >> 0); | _buffer[7] = (byte)(_timestamp >> 0); | ||||
| } | } | ||||
| Buffer.BlockCopy(buffer, 0, _nonce, 0, 12); | |||||
| Buffer.BlockCopy(_buffer, 0, _nonce, 0, 12); //Copy the 12-byte header to be used for nonce | |||||
| count = SecretBox.Encrypt(buffer, offset, count, _buffer, 12, _nonce, _secretKey); | count = SecretBox.Encrypt(buffer, offset, count, _buffer, 12, _nonce, _secretKey); | ||||
| _audioClient.Send(_buffer, count); | |||||
| _audioClient.Send(_buffer, count + 12); | |||||
| } | } | ||||
| public override void Flush() { } | public override void Flush() { } | ||||