public void Send(ArraySegment <byte> encodedAudio) { if (encodedAudio.Array == null) { throw new ArgumentNullException("encodedAudio"); } //Sanity check (cannot send before assigned an ID) if (Log.AssertAndLogWarn(_session.LocalId.HasValue, "Attempted to send voice before assigned a client ID by the host")) { return; } using (var unlocker = _openChannels.Lock()) { var openChannels = unlocker.Value; //Early exit (no point sending to no one) if (openChannels.Count == 0) { Log.Debug("Attempted to send voice with no open channels"); return; } //Who is interested in this audio? var destinations = GetVoiceDestinations(openChannels); if (destinations.Count > 0) { //Write the packet var packet = new PacketWriter(_sender.SendBufferPool.Get()) .WriteVoiceData(_session.SessionId, _session.LocalId.Value, _sequenceNumber, _channelSessionId, openChannels, encodedAudio) .Written; unchecked { _sequenceNumber++; } //Send packet _sender.EnqueueUnreliableP2P(_session.LocalId.Value, destinations, packet); //Now that the channels have been sent in a packet we can remove the closing ones from the list ClearClosedChannels(); } else { Log.Trace("Dropping voice packet (no listening destinations)"); } //Clean up destinations.Clear(); } }
public void Send(ArraySegment <byte> encodedAudio) { if (encodedAudio.Array == null) { throw new ArgumentNullException("encodedAudio"); } //Sanity check (cannot send before assigned an ID) if (!_session.LocalId.HasValue) { //ncrunch: no coverage start (Sanity check, should never happen - client ID should never be unset once it has been set) if (_hadId) { Log.Warn("Attempted to send voice but client ID has been unset"); return; } //ncrunch: no coverage end //It's possible that we try to send voice before being assigned an ID (simply because we're still joining the session). Delay the notification for a short period... //...and also don't spam it once it does happen if (_noIdSendCount++ >= 99 && _noIdSendCount % 50 == 0) { Log.Warn("Attempted to send voice before assigned a client ID by the host ({0} packets discarded so far)", _noIdSendCount); } else { Log.Debug("Attempted to send voice before assigned a client ID by the host ({0} packets discarded so far)", _noIdSendCount); } return; } _hadId = true; _noIdSendCount = 0; using (var unlocker = _openChannels.Lock()) { var openChannels = unlocker.Value; //Early exit (no point sending to no one) if (openChannels.Count == 0) { Log.Debug("Attempted to send voice with no open channels"); return; } //Who is interested in this audio? var destinations = GetVoiceDestinations(openChannels); if (destinations.Count > 0) { //Write the packet var packet = new PacketWriter(_sender.SendBufferPool.Get()) .WriteVoiceData(_session.SessionId, _session.LocalId.Value, _sequenceNumber, _channelSessionId, openChannels, encodedAudio) .Written; unchecked { _sequenceNumber++; } //Send packet _sender.EnqueueUnreliableP2P(_session.LocalId.Value, destinations, packet); //Now that the channels have been sent in a packet we can remove the closing ones from the list ClearClosedChannels(); } else { Log.Trace("Dropping voice packet (no listening destinations)"); } //Clean up destinations.Clear(); } }