示例#1
0
        /// <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);
            }
        }
示例#2
0
        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);
        }
示例#3
0
        /// <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);
            }
        }
示例#4
0
 public VoicePacket(string senderPlayerId, ChannelPriority priority, bool positional, ArraySegment <byte> encodedAudioFrame, uint sequence)
 {
     SenderPlayerId    = senderPlayerId;
     Priority          = priority;
     Positional        = positional;
     EncodedAudioFrame = encodedAudioFrame;
     SequenceNumber    = sequence;
 }
示例#5
0
 public Channel(int chunksize, string channelname, ChannelPriority priority, ChannelMessageTypes messagetype)
 {
     Chunksizes  = chunksize;
     Name        = channelname;
     Priority    = priority;
     MessageType = messagetype;
     outgoing    = new SocketMessage(chunksize);
 }
示例#6
0
        /// <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;
        }
示例#7
0
        /// <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);
        }
示例#8
0
        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);
        }
示例#9
0
        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
            }
        }
示例#10
0
        /// <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);
        }
示例#11
0
 public ChannelsMetadata(bool isPositional, float amplitudeMultiplier, ChannelPriority priority)
 {
     IsPositional        = isPositional;
     AmplitudeMultiplier = amplitudeMultiplier;
     Priority            = priority;
 }
示例#12
0
        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();
        }
示例#13
0
        public PriorityManager(PlayerCollection players)
        {
            _players = players;

            TopPriority = ChannelPriority.None;
        }
示例#14
0
 public PlaybackOptions(bool isPositional, float amplitudeMultiplier, ChannelPriority priority)
 {
     _isPositional        = isPositional;
     _amplitudeMultiplier = amplitudeMultiplier;
     _priority            = priority;
 }