/// <summary> /// Determine what the top priority speaker currently is and publish this priority /// </summary> public void Update() { var topPriority = ChannelPriority.None; string topSpeaker = null; //Run through all the current players and find which currently speaking player has the highest priority var players = _players.Readonly; for (var i = 0; i < players.Count; i++) { var player = players[i]; var priority = player.SpeakerPriority; if (priority.HasValue && priority > topPriority) { topPriority = priority.Value; topSpeaker = player.Name; } } if (TopPriority != topPriority) { TopPriority = topPriority; Log.Trace("Highest speaker priority is: {0} ({1})", topPriority, topSpeaker); } }
public ChannelBitField(ChannelType type, int sessionId, ChannelPriority priority, float amplitudeMult, bool positional, bool closing) : this() { _bitfield = 0; //Pack the single bit values by setting their flags if (type == ChannelType.Room) { _bitfield |= TypeMask; } if (positional) { _bitfield |= PositionalMask; } if (closing) { _bitfield |= ClosureMask; } //Pack 2 bits of priority _bitfield |= PackPriority(priority); //Pack 2 bits of session ID by wrapping it as a 2 bit number and then shifting bits into position _bitfield |= (ushort)((sessionId % 4) << SessionIdOffset); //Pack amplitude multiplier by converting range limited float (0 to 2) to byte and shifting byte into position var ampByte = (byte)Math.Round(Math.Min(2, Math.Max(0, amplitudeMult)) / 2 * byte.MaxValue); _bitfield |= (ushort)(ampByte << AmplitudeOffset); }
/// <summary> /// Determine what the top priority speaker currently is and publish this priority /// </summary> private void SyncPlaybackPriority() { var topPriority = ChannelPriority.None; string topSpeaker = null; //Run through all the current players and find which currently speaking player has the highest priority for (var i = 0; i < _players.Count; i++) { var item = _players[i].Playback; if (item == null || !item.IsSpeaking) { continue; } if (item.Priority > topPriority) { topPriority = item.Priority; topSpeaker = item.PlayerName; } } if (_topPrioritySpeaker != topPriority) { _topPrioritySpeaker = topPriority; Log.Trace("Highest speaker priority is: {0} ({1})", topPriority, topSpeaker); } }
public VoicePacket(string senderPlayerId, ChannelPriority priority, bool positional, ArraySegment <byte> encodedAudioFrame, uint sequence) { SenderPlayerId = senderPlayerId; Priority = priority; Positional = positional; EncodedAudioFrame = encodedAudioFrame; SequenceNumber = sequence; }
public Channel(int chunksize, string channelname, ChannelPriority priority, ChannelMessageTypes messagetype) { Chunksizes = chunksize; Name = channelname; Priority = priority; MessageType = messagetype; outgoing = new SocketMessage(chunksize); }
/// <summary> /// Create a new voice packet /// </summary> /// <param name="senderPlayerId"></param> /// <param name="priority"></param> /// <param name="ampMul"></param> /// <param name="positional"></param> /// <param name="encodedAudioFrame">The encoded audio data. The data will be copied out of this array as soon as it is passed to the decoder /// pipeline (i.e. you can re-use this array right away)</param> /// <param name="sequence"></param> /// <param name="channels">List of all channels this voice packet is being spoken on. Data will be copied out of the list as soon as it is /// passed to the decoder pipeline (i.e. you can re-use this array right away)</param> public VoicePacket(string senderPlayerId, ChannelPriority priority, float ampMul, bool positional, ArraySegment <byte> encodedAudioFrame, uint sequence, [CanBeNull] List <RemoteChannel> channels = null) { _options = new PlaybackOptions(positional, ampMul, priority); SenderPlayerId = senderPlayerId; EncodedAudioFrame = encodedAudioFrame; SequenceNumber = sequence; Channels = channels; }
/// <summary> /// Open a new channel /// </summary> /// <param name="id"></param> /// <param name="positional"></param> /// <param name="priority"></param> /// <param name="amplitudeMultiplier"></param> /// <returns></returns> [NotNull] public T Open([NotNull] TId id, bool positional = false, ChannelPriority priority = ChannelPriority.Default, float amplitudeMultiplier = 1) { if (EqualityComparer <TId> .Default.Equals(id, default(TId))) { throw new ArgumentNullException("id", "Cannot open a channel with a null ID"); } //Sanity check to ensure we don't enter an infinite loop if (_openChannelsBySubId.Count >= ushort.MaxValue) { throw Log.CreateUserErrorException( "Attempted to open 65535 channels", "Opening too many speech channels without closing them", "https://placeholder-software.co.uk/dissonance/docs/Tutorials/Script-Controlled-Speech.html", "7564ECCA-73C2-4720-B4C0-B873E63216AD" ); } //Generate a new ID for this channel (never zero, we use that elsewhere to indicate null channel) ushort subId; do { subId = unchecked (_nextId++); if (subId == 0) { subId++; } } while (_openChannelsBySubId.ContainsKey(subId)); var properties = _propertiesPool.Get(); properties.Id = subId; properties.Positional = positional; properties.Priority = priority; properties.AmplitudeMultiplier = amplitudeMultiplier; var channel = CreateChannel(subId, id, properties); _openChannelsBySubId.Add(channel.SubscriptionId, channel); var handler = OpenedChannel; if (handler != null) { handler(channel.TargetId, channel.Properties); } return(channel); }
public ChannelBitField(ChannelType type, int sessionId, ChannelPriority priority, bool positional, bool closing) : this() { _bitfield = 0; //Pack the single bit values by setting their flags if (type == ChannelType.Room) { _bitfield |= TypeMask; } if (positional) { _bitfield |= PositionalMask; } if (closing) { _bitfield |= ClosureMask; } //Pack priority by shiftnig bits into position switch (priority) { case ChannelPriority.Low: _bitfield |= 1 << PriorityOffset; break; case ChannelPriority.Medium: _bitfield |= 2 << PriorityOffset; break; case ChannelPriority.High: _bitfield |= 3 << PriorityOffset; break; // ReSharper disable RedundantCaseLabel, RedundantEmptyDefaultSwitchBranch (justification: I like to be explicit about these things) case ChannelPriority.None: case ChannelPriority.Default: default: break; // ReSharper restore RedundantCaseLabel, RedundantEmptyDefaultSwitchBranch } //Pack session ID by wrapping it as a 2 bit number and then shifting bits into position _bitfield |= (byte)((sessionId % 4) << SessionIdOffset); }
private static ushort PackPriority(ChannelPriority priority) { switch (priority) { case ChannelPriority.Low: return(1 << PriorityOffset); case ChannelPriority.Medium: return(2 << PriorityOffset); case ChannelPriority.High: return(3 << PriorityOffset); // ReSharper disable RedundantCaseLabel, RedundantEmptyDefaultSwitchBranch (justification: I like to be explicit about these things) case ChannelPriority.None: case ChannelPriority.Default: default: return(0); // ReSharper restore RedundantCaseLabel, RedundantEmptyDefaultSwitchBranch } }
/// <summary> /// Open a new channel /// </summary> /// <param name="id"></param> /// <param name="positional"></param> /// <param name="priority"></param> /// <returns></returns> public T Open(TId id, bool positional = false, ChannelPriority priority = ChannelPriority.Default) { if (id.Equals(default(T))) { throw new ArgumentNullException("id", "Cannot open a channel with a null ID"); } //Sanity check to ensure we don't enter an infinite loop if (_openChannelsBySubId.Count >= ushort.MaxValue) { throw _log.CreatePossibleBugException("Attempted to open 65535 channels", "7564ECCA-73C2-4720-B4C0-B873E63216AD"); } //Generate a new ID for this channel. ushort subId; do { subId = unchecked (_nextId++); } while (_openChannelsBySubId.ContainsKey(subId)); var properties = _propertiesPool.Get(); properties.Id = subId; properties.Positional = positional; properties.Priority = priority; var channel = CreateChannel(subId, id, properties); _openChannelsBySubId.Add(channel.SubscriptionId, channel); var handler = OpenedChannel; if (handler != null) { handler(channel.TargetId, channel.Properties); } return(channel); }
public ChannelsMetadata(bool isPositional, float amplitudeMultiplier, ChannelPriority priority) { IsPositional = isPositional; AmplitudeMultiplier = amplitudeMultiplier; Priority = priority; }
private void ReadChannelStates(ref PacketReader reader, ReceivingState state, ushort numChannels, out bool positional, out bool allClosing, out bool forceReset, out ChannelPriority priority) { positional = true; allClosing = true; int forcingReset = 0; priority = ChannelPriority.None; for (var i = 0; i < numChannels; i++) { byte channelBitfield; ushort channelRecipient; reader.ReadVoicePacketChannel(out channelBitfield, out channelRecipient); var channel = new ChannelBitField(channelBitfield); var compositeId = (int)(channel.Type) | channelRecipient << 8; _tmpCompositeIdBuffer.Add(compositeId); int previousSession; if (state.ExpectedPerChannelSessions.TryGetValue(compositeId, out previousSession)) { if (previousSession != channel.SessionId) { forcingReset++; } } state.ExpectedPerChannelSessions[compositeId] = channel.SessionId; if (ChannelAddressesUs(channel, channelRecipient)) { if (!channel.IsPositional) { positional = false; } if (!channel.IsClosing) { allClosing = false; } if (channel.Priority > priority) { priority = channel.Priority; } } } forceReset = forcingReset == numChannels; state.ClearChannels(_tmpCompositeIdBuffer); _tmpCompositeIdBuffer.Clear(); }
public PriorityManager(PlayerCollection players) { _players = players; TopPriority = ChannelPriority.None; }
public PlaybackOptions(bool isPositional, float amplitudeMultiplier, ChannelPriority priority) { _isPositional = isPositional; _amplitudeMultiplier = amplitudeMultiplier; _priority = priority; }