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)); } }
public void CmdSendVoice(float[] newVoice, int channels) { if (!isServer) { return; } //possibility of stealing entire history voiceSamples = new VoicePacket(newVoice, channels); }
public NetworkEvent(EventType type) { Type = type; _playerName = null; _room = null; _allRooms = null; _voicePacket = default(VoicePacket); _textMessage = default(TextMessage); }
/// <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); } }
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); } }
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); }
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")); } }
/// <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); } }
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); } }
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; } }
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); } }
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(); }
/// <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); }
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); } }
/// <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); } }
public void Push(VoicePacket frame) { _buffer.Push(frame); }
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); }
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; }