Example #1
0
        /// <summary>
        /// Read all the channel data from the packet and accumulate data about the channels we are listening to
        /// </summary>
        /// <param name="reader">Packetreader to read data from</param>
        /// <param name="numChannels">The number of channels in the packet reader</param>
        /// <param name="allClosing">Indicates if all channels are closing (i.e. we should stop speech after this packet)</param>
        /// <param name="forceReset">Indicates if a reset of the playback system should be forced (i.e. stop and immediately start speaking)</param>
        /// <param name="channelsMetadata">Aggregate metadata about all playing channels</param>
        /// <param name="channelsOut"></param>
        private void ReadChannels(ref PacketReader reader, ushort numChannels, out bool allClosing, out bool forceReset, out ChannelsMetadata channelsMetadata, [NotNull] ICollection <RemoteChannel> channelsOut)
        {
            //Accumulate aggregate information about all the channels
            channelsMetadata = new ChannelsMetadata(true, 0, ChannelPriority.None);
            allClosing       = true;
            forceReset       = true;

            //Just in case someone else left a mess, clear the list before using it
            channelsOut.Clear();
            _tmpCompositeIdBuffer.Clear();

            for (var i = 0; i < numChannels; i++)
            {
                //Parse a channel of information from the header
                ChannelBitField channel;
                ushort          channelRecipient;
                reader.ReadVoicePacketChannel(out channel, out channelRecipient);

                //Skip onwards if we don't care about this channel
                var c = IsChannelToLocalPlayer(channel, channelRecipient);
                if (!c.HasValue)
                {
                    continue;
                }

                //Add an entry for this channel to the list
                channelsOut.Add(c.Value);

                //Form a unique ID for this channel so we can keep track of it across packets
                var compositeId = (int)channel.Type | (channelRecipient << 8);
                _tmpCompositeIdBuffer.Add(compositeId);

                //Accumulate aggregate metadata over all channels
                channelsMetadata = channelsMetadata.CombineWith(new ChannelsMetadata(channel.IsPositional, channel.AmplitudeMultiplier, channel.Priority));
                allClosing      &= channel.IsClosing;

                //It's possible that a channel was closed and then re-opened between the sending of two packets. If so then we want to consider the channel...
                //...as closed then re-opened (i.e. reset the channel). However we only need to perform a reset if this applies to *all* the channels this...
                //...receiver is listening to.
                forceReset &= HasChannelSessionChanged(compositeId, channel.SessionId);
            }

            //Only perform a reset if we were already open (a reset makes no sense if we're not open).
            forceReset &= Open;

            //Remove all channels from this peer which we no longer care about
            RemoveChannelsExcept(_tmpCompositeIdBuffer);
            _tmpCompositeIdBuffer.Clear();
        }
Example #2
0
            public ChannelsMetadata CombineWith(ChannelsMetadata other)
            {
                return(new ChannelsMetadata(

                           // Positional playback if *all* channels are positional
                           IsPositional & other.IsPositional,

                           // Amplitude is max amplitude of channels
                           Math.Max(AmplitudeMultiplier, other.AmplitudeMultiplier),

                           // Priority is max priority of channels
                           (ChannelPriority)Math.Max((int)Priority, (int)other.Priority)

                           ));
            }