Beispiel #1
0
        protected override void PacketRecieved(string packetstr) {
            VoicePacket packet = new VoicePacket(packetstr);
            VoicePacketType type = packet.GetPacketType();

            if (type == VoicePacketType.Hello) {
                Logger.Info("Voice server says hello!");
                SendIdentityPacket();
            } else if (type == VoicePacketType.Ready) {
                readyData = packet.GetData<VoiceChannelReady>();

                try {
                    stream = new AudioStream(readyData);
                    stream.Connect();

                    BasicPacket spacket = new SelectProtocol(readyData.ip, readyData.port);
                    Send(spacket);
                } catch (Exception e) {
                    Logger.Error($"AudioStream connection error: {e.Message}");
                    Disconnect();
                }
            } else if (type == VoicePacketType.ClientDisconnect) {
                Disconnect();
            } else if (type == VoicePacketType.CodecInformation) {
                CodecInformation codecinfo = packet.GetData<CodecInformation>();
                Logger.Info($"Audio codec is {codecinfo.audio_codec}");
                stream.SetCodec(codecinfo.audio_codec);
            } else {
                Logger.Debug($"Unchecked type: {type}");
            }
        }
 public void EnqueueVoiceData(VoicePacket data)
 {
     using (var events = _queuedEvents.Lock())
     {
         _pendingVoicePackets++;
         events.Value.Add(new NetworkEvent(data));
     }
 }
Beispiel #3
0
    public void CmdSendVoice(float[] newVoice, int channels)
    {
        if (!isServer)
        {
            return;
        }
        //possibility of stealing entire history

        voiceSamples = new VoicePacket(newVoice, channels);
    }
Beispiel #4
0
            public NetworkEvent(EventType type)
            {
                Type = type;

                _playerName  = null;
                _room        = null;
                _allRooms    = null;
                _voicePacket = default(VoicePacket);
                _textMessage = default(TextMessage);
            }
Beispiel #5
0
        /// <summary>
        /// Deliver a new encoded audio packet
        /// </summary>
        /// <remarks>It will be placed into a transfer buffer and will be moved into the actual buffer when FlushTransferBuffer is called on the audio playback thread</remarks>
        /// <param name="packet"></param>
        /// <param name="now"></param>
        /// <returns>How delayed this packet is from when it should arrive</returns>
        public float Push(VoicePacket packet, DateTime now)
        {
            Log.Trace("Received frame {0} from network", packet.SequenceNumber);

            // copy the data out of the frame, as the network thread will re-use the heap allocated things
            List <RemoteChannel> channelsCopy = null;

            if (packet.Channels != null)
            {
                channelsCopy = _channelListPool.Get();
                channelsCopy.Clear();
                channelsCopy.AddRange(packet.Channels);
            }

            var frameCopy = packet.EncodedAudioFrame.CopyTo(_bytePool.Get());

            var packetCopy = new VoicePacket(
                packet.SenderPlayerId,
                packet.PlaybackOptions.Priority,
                packet.PlaybackOptions.AmplitudeMultiplier,
                packet.PlaybackOptions.IsPositional,
                frameCopy,
                packet.SequenceNumber,
                channelsCopy
                );

            // queue the frame onto the transfer buffer
            if (!_inputBuffer.TryWrite(packetCopy))
            {
                Log.Warn("Failed to write an encoded audio packet into the input transfer buffer");
            }

            // We've received a packet but not been prepared yet, which means audio playback hasn't started yet - immediately flush the transfer buffer
            // It's safe to do this because we know playback isn't going, so the audio thread won't be accessing the buffer at the same time as we're flushing
            if (!_prepared)
            {
                FlushTransferBuffer();
            }

            // calculate how late the packet is
            if (!_firstFrameArrival.HasValue)
            {
                _firstFrameArrival = now;
                _firstFrameSeq     = packet.SequenceNumber;

                return(0);
            }
            else
            {
                var expectedTime = _firstFrameArrival.Value + TimeSpan.FromTicks(_frameDuration.Ticks * (packet.SequenceNumber - _firstFrameSeq));
                var delay        = now - expectedTime;

                return((float)delay.TotalSeconds);
            }
        }
Beispiel #6
0
        private void RecycleFrame(VoicePacket packet)
        {
            // ReSharper disable once AssignNullToNotNullAttribute (Justification: Arr segment internal array is not null)
            _bytePool.Put(packet.EncodedAudioFrame.Array);

            if (packet.Channels != null)
            {
                packet.Channels.Clear();
                _channelListPool.Put(packet.Channels);
            }
        }
Beispiel #7
0
        public void Push(VoicePacket frame)
        {
            //If this is the first packet extract the channel data ahead of time so that it is available in the PlayerStartedSpeaking event
            if (!_receivedFirstPacket)
            {
                ExtractChannels(frame);
            }

            _buffer.Push(frame);
            _receivedFirstPacket = true;
        }
        /// <summary>
        ///     Queues an encoded audio frame for playback in the current session.
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="now">The current time (or null, to use DateTime.Now)</param>
        public void ReceiveFrame(VoicePacket packet, DateTime?now = null)
        {
            if (packet.SenderPlayerId != PlayerName)
            {
                throw Log.CreatePossibleBugException(string.Format("Attempted to deliver voice from player {0} to playback queue for player {1}", packet.SenderPlayerId, PlayerName), "F55DB7D5-621B-4F5B-8C19-700B1FBC9871");
            }

            var delay = _active.Push(packet, now ?? DateTime.UtcNow);

            _arrivalJitterMeter.Update(delay);
        }
Beispiel #9
0
        public void Push(VoicePacket frame)
        {
            Log.Trace("Buffering encoded audio frame {0}", frame.SequenceNumber);

            _heap.Add(frame);
            Interlocked.Increment(ref _count);

            if (_count > 39 && _count % 10 == 0)
            {
                Log.Warn("Encoded audio heap is getting very large ({0} items)", _count);
            }
        }
        public void Push(VoicePacket frame)
        {
            Log.Trace("Buffering encoded audio frame {0}", frame.SequenceNumber);

            _heap.Add(frame);
            Interlocked.Increment(ref _count);

            if (_heap.Count > 40)
            {
                Log.Warn(Log.PossibleBugMessage(string.Format("Encoded audio heap is getting very large ({0} items)", _heap.Count), "59EE0102-FF75-467A-A50D-00BF670E9B8C"));
            }
        }
Beispiel #11
0
        /// <summary>
        /// Push a new encoded audio packet
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="now"></param>
        /// <returns>How delayed this packet is from when it should arrive</returns>
        public float Push(VoicePacket packet, DateTime now)
        {
            Log.Trace("Received frame {0} from network", packet.SequenceNumber);

            // copy the data out of the frame, as the network thread will re-use the heap allocated things
            List <RemoteChannel> channelsCopy = null;

            if (packet.Channels != null)
            {
                channelsCopy = _channelListPool.Get();
                channelsCopy.Clear();
                channelsCopy.AddRange(packet.Channels);
            }

            var frameCopy = packet.EncodedAudioFrame.CopyTo(_bytePool.Get());

            var packetCopy = new VoicePacket(
                packet.SenderPlayerId,
                packet.PlaybackOptions.Priority,
                packet.PlaybackOptions.AmplitudeMultiplier,
                packet.PlaybackOptions.IsPositional,
                frameCopy,
                packet.SequenceNumber,
                channelsCopy
                );

            // queue the frame onto the transfer buffer
            if (!_inputBuffer.TryWrite(packetCopy))
            {
                Log.Warn("Failed to write an encoded audio packet into the input transfer buffer");
            }

            // calculate how late the packet is
            if (!_firstFrameArrival.HasValue)
            {
                _firstFrameArrival = now;
                _firstFrameSeq     = packet.SequenceNumber;

                return(0);
            }
            else
            {
                var expectedTime = _firstFrameArrival.Value + TimeSpan.FromTicks(_frameDuration.Ticks * (packet.SequenceNumber - _firstFrameSeq));
                var delay        = now - expectedTime;

                return((float)delay.TotalSeconds);
            }
        }
Beispiel #12
0
        private void Net_VoicePacketReceived(VoicePacket packet)
        {
            // ReSharper disable once ConditionIsAlwaysTrueOrFalse (Justification: Sanity check against network system returning incorrect values)
            // ReSharper disable once HeuristicUnreachableCode
            if (Log.AssertAndLogError(packet.SenderPlayerId != null, "C0FE4E98-3CC9-466E-AA39-51F0B6D22D09", "Discarding a voice packet with a null player ID"))
            {
                return;
            }

            VoicePlayerState state;

            if (_players.TryGet(packet.SenderPlayerId, out state) && state.Playback != null)
            {
                state.Playback.ReceiveAudioPacket(packet);
            }
        }
Beispiel #13
0
        private void ExtractChannels(VoicePacket encoded)
        {
            //Expose the channel list for this packet (if it's null just assume the previous value is still correct)
            if (encoded.Channels != null)
            {
                using (var l = _channels.Lock())
                {
                    _approxChannelCount = encoded.Channels.Count;

                    l.Value.Clear();
                    l.Value.AddRange(encoded.Channels);
                }

                _receivedFirstPacket = true;
            }
        }
Beispiel #14
0
        private void Net_VoicePacketReceived(VoicePacket packet)
        {
            // ReSharper disable once ConditionIsAlwaysTrueOrFalse (Justification: Sanity check against network system returning incorrect values)
            if (packet.SenderPlayerId == null)
            {
                Log.Warn(Log.PossibleBugMessage("Received a voice packet with a null player ID (discarding)", "C0FE4E98-3CC9-466E-AA39-51F0B6D22D09"));
                return;
            }

            VoicePlayerState state;

            if (_playersLookup.TryGetValue(packet.SenderPlayerId, out state) && state.Playback != null)
            {
                state.Playback.ReceiveAudioPacket(packet);
            }
        }
Beispiel #15
0
    void UpdateAudioSource(VoicePacket newVoice)
    {
        //return;
        if (play == null)
        {
            play      = this.GetComponents <AudioSource>()[1];
            play.clip = AudioClip.Create("Playing", 999, newVoice.channels, maxf, false);
        }

        play.Stop();
        play.clip.SetData(newVoice.voiceSamples, 0);
        foreach (float f in newVoice.voiceSamples)
        {
            Debug.Log(f);
        }
        play.Play();
    }
Beispiel #16
0
        /// <summary>
        ///     Queues an encoded audio frame for playback in the current session.
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="now">The current time (or null, to use DateTime.Now)</param>
        public void ReceiveFrame(VoicePacket packet, DateTime?now = null)
        {
            if (packet.SenderPlayerId != PlayerName)
            {
                throw Log.CreatePossibleBugException(string.Format("Attempted to deliver voice from player {0} to playback queue for player {1}", packet.SenderPlayerId, PlayerName), "F55DB7D5-621B-4F5B-8C19-700B1FBC9871");
            }

            if (_active == null)
            {
                Log.Warn(Log.PossibleBugMessage(string.Format("Attempted to deliver voice from player {0} with no active session", packet.SenderPlayerId), "1BD954EC-B455-421F-9D6E-2E3D087BC0A9"));
                return;
            }

            var delay = _active.Push(packet, now ?? DateTime.UtcNow);

            Metrics.Sample(_metricArrivalDelay, delay);

            _arrivalJitterMeter.Update(delay);
        }
Beispiel #17
0
    void SendPacket(CustomConn conn, byte[] data)
    {
        var packet = new VoicePacket
        {
            Dest  = conn.token,
            IsP2P = false,
            Data  = data,
        };

        // if (conn.token.Equals(networkController.Token))
        // {
        //     packet.Token = conn.token;
        //     networkController.voiceHolderClient.Add(packet);
        // }
        // else
        // {
        string json = Newtonsoft.Json.JsonConvert.SerializeObject(packet);

        networkController.WebSocket.SendText(json);
        // }
    }
    void SendPacket(byte[] data, bool isP2P)
    {
        var packet = new VoicePacket
        {
            Dest  = isP2P ? "" : networkController.ServerToken,
            IsP2P = isP2P,
            Data  = data,
        };

        // For when client is also server loopback
        // if (networkController.IsServer && !networkController.comms.IsNetworkInitialized)
        if (networkController.IsServer)
        {
            packet.Token = networkController.Token;
            networkController.voiceHolderServer.Add(packet);
        }
        else
        {
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(packet);
            networkController.WebSocket.SendText(json);
        }
    }
Beispiel #19
0
        /// <summary>
        /// Push a new encoded audio packet
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="now"></param>
        /// <returns>How delayed this packet is from when it should arrive</returns>
        public float Push(VoicePacket packet, DateTime now)
        {
            Log.Trace("Received frame {0} from network", packet.SequenceNumber);

            // copy the data out of the frame, as the network thread will re-use the array
            var array = _bytePool.Get();
            var frame = packet.EncodedAudioFrame.CopyTo(array);

            // queue the frame onto the transfer buffer
            var copy = new EncodedAudio(packet.SequenceNumber, frame);

            if (!_inputBuffer.Write(copy))
            {
                Log.Warn("Failed to write an encoded audio packet into the input transfer buffer");
            }

            //Copy across the stream metadata
            //N.b. doing this means the metadata is surfaced <buffer length> too early
            Priority   = packet.Priority;
            Positional = packet.Positional;

            // calculate how late the packet is
            if (!_firstFrameArrival.HasValue)
            {
                _firstFrameArrival = now;
                _firstFrameSeq     = packet.SequenceNumber;

                return(0);
            }
            else
            {
                var expectedTime = _firstFrameArrival.Value + TimeSpan.FromTicks(_frameDuration.Ticks * (packet.SequenceNumber - _firstFrameSeq));
                var delay        = now - expectedTime;

                return((float)delay.TotalSeconds);
            }
        }
Beispiel #20
0
 public void Push(VoicePacket frame)
 {
     _buffer.Push(frame);
 }
Beispiel #21
0
 void IVoicePlaybackInternal.ReceiveAudioPacket(VoicePacket packet)
 {
     _sessions.ReceiveFrame(packet);
 }
 internal void EnqueuePacket(VoicePacket packet)
 => this.PacketQueue.Enqueue(packet);
 internal void ReceiveAudioPacket(VoicePacket packet)
 {
     _sessions.ReceiveFrame(packet);
 }
Beispiel #24
0
    public async void StartWebSocket()
    {
        WebSocket = new WebSocket("ws://cops-and-robert-server.herokuapp.com/ws/" + roomId);

        WebSocket.OnOpen += () =>
        {
            Debug.Log("Connection open!");
        };

        WebSocket.OnError += (e) =>
        {
            Debug.Log("Error! " + e);
        };

        WebSocket.OnClose += (e) =>
        {
            Debug.Log("Connection closed!");
            Token         = null;
            comms.enabled = false;
            locationPanel.SetActive(false);
            menuPanel.SetActive(true);
            Destroy(player);
            Destroy(Camera.main.gameObject);
        };

        WebSocket.OnMessage += (bytes) =>
        {
            string json = System.Text.Encoding.UTF8.GetString(bytes);
            // Debug.Log(json);
            // foreach (string json in jsonHolder.Replace("\n", string.Empty).Replace("\r", string.Empty).Replace("}{", "}|{").Split('|'))
            // foreach (string json in Regex.Replace(jsonHolder, "/(\r\n)|\n|\r/gm", "|").Split('|'))
            // foreach (string json in jsonHolder.Split('|'))
            // {
            if (!json.Contains("Data"))
            {
                PlayerPacket packet = JsonConvert.DeserializeObject <PlayerPacket>(json);
                if (packet.Token.Equals(Token))
                {
                    return;
                }
                if (Token == null)
                {
                    Token    = packet.Token;
                    IsServer = packet.IsServer;
                    // username = packet.Username;
                    SpawnPlayer();
                }
                else
                {
                    if (otherPlayers.TryGetValue(packet.Token, out OtherController oc))
                    {
                        oc.UpdateTransform(packet);
                    }
                    else
                    {
                        GameObject obj = Instantiate(prefabOtherPlayer, new Vector3(packet.PosX, packet.PosY, packet.PosZ), Quaternion.Euler(packet.RotX, packet.RotY, packet.RotZ));
                        // obj.name = packet.Token;
                        obj.GetComponent <VoiceController>().StartVoice(packet.Token);
                        otherPlayers.Add(packet.Token, obj.GetComponent <OtherController>());
                    }
                }
            }
            else
            {
                VoicePacket packet = JsonConvert.DeserializeObject <VoicePacket>(json);
                if (packet.IsServer)
                {
                    ServerToken = packet.Token;
                }
                if (IsServer && !packet.IsServer && !packet.IsP2P)
                {
                    Debug.Log("SERVER: " + packet.Token + " - " + packet.IsServer + " - " + packet.IsP2P + " - " + comms.IsNetworkInitialized);
                    voiceHolderServer.Add(packet);
                }
                else if (packet.IsServer || packet.IsP2P)
                {
                    Debug.Log("CLIENT: " + packet.Token + " - " + packet.IsServer + " - " + packet.IsP2P + " - " + comms.IsNetworkInitialized);
                    voiceHolderClient.Add(packet);
                }
                else
                {
                    Debug.Log("Unknown voice packet");
                }
            }
            // }
        };

        await WebSocket.Connect();
    }
 public NetworkEvent(VoicePacket voice)
     : this(EventType.VoiceData)
 {
     _voicePacket = voice;
 }