예제 #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);
        }
예제 #2
0
        public bool Speak(byte[] audio, uint bitrate, AudioApplication usedFor = AudioApplication.Mixed)
        {
            while (Speaking)
            {
                Thread.Sleep(1);
            }

            Speaking = true;

            var encoder = new OpusEncoder((int)bitrate, usedFor, 0);

            int offset = 0;

            long nextTick = Environment.TickCount;

            try
            {
                while (offset + OpusEncoder.FrameBytes < audio.Length && !_stopCurrent)
                {
                    SetSpeaking(true);

                    long dist = nextTick - Environment.TickCount;

                    if (dist <= 0)
                    {
                        SendAudioData(encoder, ref audio, offset, _sequence, _timestamp);

                        nextTick += OpusEncoder.TimeBetweenFrames;
                        offset   += OpusEncoder.FrameBytes;
                        _sequence++;
                        _timestamp += OpusEncoder.FrameSamplesPerChannel;
                    }
                    else
                    {
                        Thread.Sleep((int)dist);
                    }
                }

                SetSpeaking(false);

                _stopCurrent = false;
                Speaking     = false;

                return(true);
            }
            catch
            {
                Speaking = false;

                return(false);
            }
        }
예제 #3
0
 internal DiscordVoiceStream(DiscordVoiceSession client, int bitrate, AudioApplication application = AudioApplication.Mixed)
 {
     _session  = client;
     _encoder  = new OpusEncoder(bitrate, application, 0);
     _nextTick = -1;
 }