public SerialPacketStream(VoipMessageVoice item, bool isEncoded)
 {
     Id = item.FromUserId;
     StreamNumber = item.StreamNumber;
     RoomName = item.RoomName;
     IsTeamOnly = item.IsTeamOnly;
     IsEncoded = isEncoded;
     Parts = new List<SerialPacket>();
 }
        public void AddMessage(VoipMessageVoice item)
        {
            if (VoipSession.DebugSaveReceivedPackets)
                SavePacket(item);

            lock (_voices)
            {
                if (!ShouldAddToStream(item))
                    return;

                CalcJitter(item.MessageNumber);

                if (item.MessageNumber > _maxPlayNumber)
                    _maxPlayNumber = item.MessageNumber;

                var index = item.MessageNumber % _voices.Length;
                _voices[index] = item;
            }
        }
 private static IVoipMessage Instantiate(byte mType)
 {
     IVoipMessage m;
     switch (mType)
     {
         case (VoipMessageVoice.MType):
             m = new VoipMessageVoice();
             break;
         case (VoipMessageJoinRoom.MType):
             m = new VoipMessageJoinRoom();
             break;
         case (VoipMessageLeaveRoom.MType):
             m = new VoipMessageLeaveRoom();
             break;
         default:
             m = null;
             break;
     }
     return m;
 }
 public SerialPacket(VoipMessageVoice item)
 {
     RxTime = DateTimePrecise.UtcNow;
     MessageNumber = item.MessageNumber;
     Audio = item.Audio;
 }
        private void _nAudioTest_AudioRecordEnded()
        {
            var vt = _voiceTester;
            if (vt != null)
            {
                vt.RecordEnded();
                return;
            }

            if (_speakingRoom == null)
                return;

            var message = new VoipMessageVoice
            {
                RoomName = _speakingRoom.R.AudioRoomId,
                FromUserId = _userData.User.Id,
                Audio = new byte[0],
                IsTeamOnly = _speakingRoomTeamOnly,
                MessageNumber = _messageNumber++,
                StreamNumber = _streamNumber,
            };

            _audioChatClient.Send(message);
            _speakingRoom.OnVoiceStopped(_userData.User);
            _speakingRoom = null;

            if (DebugSaveSentPackets)
            {
                _audioRec.Write(SerialPacketStream.AppDataPath(_audioRec));
                _audioRec = null;
            }
        }
        private void _nAudioTest_AudioRecorded(AudioHardwareSession source, byte[] encoded, double signalPower)
        {
            var vt = _voiceTester;
            if (vt != null)
            {
                vt.Recorded(encoded, signalPower);
                return;
            }

            var isFirst = _speakingRoom == null;
            if (isFirst)
            {
                _speakingRoom = GetSpeakingRoom();
                _messageNumber = 0;
                _streamNumber++;

                _micTrigger.Index = 0;
            }

            if (_speakingRoom == null)
                return;

            if (isFirst)
            {
                if (UserDataManager.UserData.Settings.MicTriggerSoundOffEnabled)
                    Play(_micTrigger);

                _speakingRoomTeamOnly = _speakingRoom.R.IsVoiceTeamOnly;

                if (DebugSaveSentPackets)
                    _audioRec = new SerialPacketStream
                    {
                        Id = _userData.User.Id,
                        Parts = new List<SerialPacket>(),
                        IsEncoded = true,
                        RoomName = _speakingRoom.R.AudioRoomId,
                        StreamNumber = _streamNumber,
                    };
            }

            var message = new VoipMessageVoice
            {
                RoomName = _speakingRoom.R.AudioRoomId,
                FromUserId = _userData.User.Id,
                Audio = encoded,
                IsTeamOnly = _speakingRoomTeamOnly,
                MessageNumber = _messageNumber++,
                StreamNumber = _streamNumber,
            };

            if (DebugSaveSentPackets)
                _audioRec.Parts.Add(new SerialPacket(_audioRec.Parts.Count, encoded));

            _audioChatClient.Send(message);
            if (isFirst)
                _speakingRoom.OnVoiceSent(_userData.User);
        }
        private void ReceivedVoice(VoipMessageVoice voiceMessage)
        {
            if (voiceMessage.FromUserId == _userData.User.Id)
                return;

            PacketOrderer vo;
            lock (_messageOrderers)
            {
                if (!_messageOrderers.TryGetValue(voiceMessage.FromUserId, out vo))
                {
                    vo = new PacketOrderer(this);
                    _messageOrderers[voiceMessage.FromUserId] = vo;
                }
            }
            vo.AddMessage(voiceMessage);
        }
        internal void PlayVoice(VoipMessageVoice voiceMessage)
        {
            var isEnd = voiceMessage.Audio.Length == 0;

            //App.LogLine(obj.FromUserId + " " + obj.MessageNumber + " " + obj.Audio.Length);

            var user = _userData.GetPgUser(voiceMessage.FromUserId);

            var isListening = false;
            AudioRoomEx roomEx;
            lock (_joinedRooms)
            {
                if (_joinedRooms.TryGetValue(voiceMessage.RoomName, out roomEx))
                {
                    isListening = roomEx.R.IsVoiceEnabled && !user.IsMuted;

                    if (isListening && roomEx.R.IsVoiceTeamOnly)
                        isListening = _userData.User.Team == user.Team;
                }
            }

            if (isEnd)
            {
                Stop(user, roomEx);
            }
            else
            {
                if (isListening)
                    _nAudioTest.AudioReceived(user.Id, voiceMessage.Audio, true);
                if (roomEx != null)
                    roomEx.OnVoiceSent(user);
                lock (_receivedTimes)
                {
                    _receivedTimes[new Tuple<PgUser, AudioRoomEx>(user, roomEx)] = DateTime.UtcNow;
                }
            }
        }
        public void Process()
        {
            VoipMessageVoice cur;

            lock (_voices)
            {
                if (_nextPlayNumber > _maxPlayNumber)
                    return;
                if (_nextPlayNumber == 0)
                {
                    _jitterWait++;
                    if (_jitterWait <= _jitterNumberActive)
                        return;
                }

                var ix = _nextPlayNumber % _voices.Length;
                cur = _voices[ix];
                _voices[ix] = null;

                if (cur == null)
                {
                    cur = new VoipMessageVoice
                    {
                        Audio = _static,
                        FromUserId = _firstItem.FromUserId,
                        IsTeamOnly = _firstItem.IsTeamOnly,
                        MessageNumber = _nextPlayNumber,
                        RoomName = _firstItem.RoomName,
                    };
                }

                _nextPlayNumber++;
            }

            _voipSession.CountTick(cur.FromUserId);

            _voipSession.PlayVoice(cur);
        }
        private bool ShouldAddToStream(VoipMessageVoice item)
        {
            if (item.StreamNumber == _lastStreamNumber)
                return true;

            if (_prevStreamNumbers.Contains(item.StreamNumber))
                return false;// don't play packets from recently played streams

            if (_maxPlayNumber > 50)
                SetActiveJitter();

            InitStream(item);

            return true;
        }
 private void SavePacket(VoipMessageVoice item)
 {
     if (_ps == null)
         _ps = new SerialPacketStream(item, true);
     var poco = new SerialPacket(item);
     _ps.Parts.Add(poco);
 }
        private void InitStream(VoipMessageVoice item)
        {
            if (VoipSession.DebugSaveReceivedPackets)
                SavePacketStream();

            _nextPlayNumber = 0;
            _maxPlayNumber = -1;
            _jitterNumber = 0;
            _jitterWait = 0;
            _firstItem = item;
            _streamStartTime = DateTime.UtcNow;

            _lastStreamNumber = item.StreamNumber;
            while (_prevStreamNumbers.Count >= 4)
                _prevStreamNumbers.RemoveAt(3);
            _prevStreamNumbers.Insert(0, _lastStreamNumber);
        }