Exemple #1
0
        private void SendAudioData(OpusEncoder encoder, ref byte[] audio, int offset, ushort seq, uint timestamp)
        {
            byte[] packet = new byte[OpusEncoder.FrameBytes + 12];

            byte[] header = new byte[12];
            header[0]  = 0x80;
            header[1]  = 0x78;
            header[2]  = (byte)(seq >> 8);
            header[3]  = (byte)(seq >> 0);
            header[4]  = (byte)(timestamp >> 24);
            header[5]  = (byte)(timestamp >> 16);
            header[6]  = (byte)(timestamp >> 8);
            header[7]  = (byte)(timestamp >> 0);
            header[8]  = (byte)(_ssrc >> 24);
            header[9]  = (byte)(_ssrc >> 16);
            header[10] = (byte)(_ssrc >> 8);
            header[11] = (byte)(_ssrc >> 0);

            Buffer.BlockCopy(header, 0, packet, 0, 12);

            int frameSize = encoder.EncodeFrame(audio, offset, packet, 12);
            int encSize   = Sodium.Encrypt(packet, 12, frameSize, packet, 12, header, _secretKey);

            _udpClient.Send(packet, encSize + 12);
        }
        /// <summary>
        /// Sends audio data to the voice channel
        /// </summary>
        /// <param name="buffer">Audio data</param>
        /// <param name="offset">Offset to start from</param>
        /// <returns>The new offset, which u can use in your next Write call</returns>
        public int Write(byte[] buffer, int offset)
        {
            if (_session.State != DiscordVoiceClientState.Connected)
            {
                throw new InvalidOperationException("Connection has been closed.");
            }

            lock (_session.VoiceLock)
            {
                if (_nextTick == -1)
                {
                    _nextTick = Environment.TickCount;
                }
                else
                {
                    long distance = _nextTick - Environment.TickCount;

                    if (distance > 0)
                    {
                        Thread.Sleep((int)distance);
                    }
                }

                byte[] packet = new byte[OpusEncoder.FrameBytes + 12];

                byte[] header = new byte[12];
                header[0]  = 0x80;
                header[1]  = 0x78;
                header[2]  = (byte)(_session.Sequence >> 8);
                header[3]  = (byte)(_session.Sequence >> 0);
                header[4]  = (byte)(_session.Timestamp >> 24);
                header[5]  = (byte)(_session.Timestamp >> 16);
                header[6]  = (byte)(_session.Timestamp >> 8);
                header[7]  = (byte)(_session.Timestamp >> 0);
                header[8]  = (byte)(_session.SSRC >> 24);
                header[9]  = (byte)(_session.SSRC >> 16);
                header[10] = (byte)(_session.SSRC >> 8);
                header[11] = (byte)(_session.SSRC >> 0);

                Buffer.BlockCopy(header, 0, packet, 0, 12);

                int frameSize = _encoder.EncodeFrame(buffer, offset, packet, 12);
                int encSize   = Sodium.Encrypt(packet, 12, frameSize, packet, 12, header, _session.SecretKey);

                _session.SetSpeaking(true);
                _session.UdpClient.Send(packet, encSize + 12);


                _nextTick += OpusEncoder.TimeBetweenFrames;
                _session.Sequence++;
                _session.Timestamp += OpusEncoder.FrameSamplesPerChannel;

                return(offset + OpusEncoder.FrameBytes);
            }
        }