示例#1
0
        public void AddClientAudioSamples(ClientAudio audio)
        {
            var newTransmission = LikelyNewTransmission();

            if (newTransmission)
            {
                Logger.Debug($"{LogClientId}| Likely New Transmission");
            }

            var decoded = Decoder.Decode(audio.EncodedAudio,
                                         audio.EncodedAudio.Length, out var decodedLength, newTransmission);

            if (decodedLength > 0)
            {
                // for some reason if this is removed then it lags?!
                //guess it makes a giant buffer and only uses a little?
                //Answer: makes a buffer of 4000 bytes - so throw away most of it
                var tmp = new byte[decodedLength];
                Buffer.BlockCopy(decoded, 0, tmp, 0, decodedLength);

                audio.PcmAudioShort = ConversionHelpers.ByteArrayToShortArray(tmp);

                if (newTransmission)
                {
                    // System.Diagnostics.Debug.WriteLine(audio.ClientGuid+"ADDED");
                    //append ms of silence - this functions as our jitter buffer??
                    var silencePad = AudioManager.InputSampleRate / 1000 * SilencePad;

                    var newAudio = new short[audio.PcmAudioShort.Length + silencePad];

                    Buffer.BlockCopy(audio.PcmAudioShort, 0, newAudio, silencePad, audio.PcmAudioShort.Length);

                    audio.PcmAudioShort = newAudio;
                }

                LastUpdate = DateTime.Now.Ticks;

                var pcmAudio = ConversionHelpers.ShortArrayToByteArray(audio.PcmAudioShort);
                _speechAudioProvider.AddSamples(pcmAudio, 0, pcmAudio.Length);
            }
            else
            {
                Logger.Debug($"{LogClientId}| Failed to decode audio from Packet for client");
            }
        }
示例#2
0
        private void TaskAudioSub(CancellationToken cancelToken, BlockingCollection <ClientAudio> outputQueue, string address)
        {
            using (var subSocket = new SubscriberSocket())
            {
                //subSocket.Options.ReceiveHighWatermark = 1000;
                subSocket.Connect(address);
                subSocket.Subscribe(callsign);

                while (!cancelToken.IsCancellationRequested)
                {
                    var         messageTopicReceived = subSocket.ReceiveFrameString(); //Should always == _username
                    int         bytesReceived        = 0;
                    ClientAudio clientAudio          = subSocket.Deserialise <ClientAudio>(out bytesReceived);
                    ClientStatistics.AudioBytesReceived += bytesReceived;
                    outputQueue.Add(clientAudio);
                }
            }
            taskAudioSub = null;
        }
        public void AddAudio(ClientAudio audio)
        {
            lock (_lock)
            {
                var radioBuffer = _clientRadioBuffers[audio.ReceivedRadio];

                if (!radioBuffer.ContainsKey(audio.ClientGuid))
                {
                    radioBuffer[audio.ClientGuid] = new List <ClientAudio> {
                        audio
                    };
                }
                else
                {
                    //   logger.Info("adding");
                    radioBuffer[audio.ClientGuid].Add(audio);
                }
            }
        }
示例#4
0
        public void AddClientAudio(ClientAudio audio)
        {
            //sort out effects!

            //16bit PCM Audio
            //TODO: Clean  - remove if we havent received audio in a while?
            // If we have recieved audio, create a new buffered audio and read it
            ClientAudioProvider client = null;

            if (_clientsBufferedAudio.ContainsKey(audio.ClientGuid))
            {
                client = _clientsBufferedAudio[audio.ClientGuid];
            }
            else
            {
                client = new ClientAudioProvider();
                _clientsBufferedAudio[audio.ClientGuid] = client;

                _clientAudioMixer.AddMixerInput(client.SampleProvider);
            }

            client.AddClientAudioSamples(audio);
        }
        private void UdpAudioDecode()
        {
            try
            {
                while (!_stop)
                {
                    try
                    {
                        var encodedOpusAudio = new byte[0];
                        _encodedAudio.TryTake(out encodedOpusAudio, 100000, _stopFlag.Token);

                        var time = GetTickCount64(); //should add at the receive instead?

                        if ((encodedOpusAudio != null) && (encodedOpusAudio.Length > 36))
                        {
                            //  process
                            // check if we should play audio

                            var myClient = IsClientMetaDataValid(_guid);

                            if ((myClient != null) && _clientStateSingleton.DcsPlayerRadioInfo.IsCurrent())
                            {
                                //Decode bytes
                                var udpVoicePacket = UDPVoicePacket.DecodeVoicePacket(encodedOpusAudio);

                                // check the radio
                                RadioReceivingState receivingState = null;
                                var receivingRadio =
                                    _clientStateSingleton.DcsPlayerRadioInfo.CanHearTransmission(
                                        udpVoicePacket.Frequency,
                                        (RadioInformation.Modulation)udpVoicePacket.Modulation,
                                        udpVoicePacket.UnitId, out receivingState);

                                //Check that we're not transmitting on this radio

                                double receivingPowerLossPercent = 0;
                                float  lineOfSightLoss           = 0;

                                if ((receivingRadio != null) && (receivingState != null)
                                    &&
                                    ((receivingRadio.modulation == RadioInformation.Modulation.INTERCOM)
                                     // INTERCOM Modulation is 2 so if its two dont bother checking LOS and Range
                                     ||
                                     (
                                         HasLineOfSight(udpVoicePacket, out lineOfSightLoss)
                                         &&
                                         InRange(udpVoicePacket, out receivingPowerLossPercent)
                                         &&
                                         !ShouldBlockRxAsTransmitting(receivingState.ReceivedOn)
                                     )
                                    )
                                    )
                                {
                                    //  RadioReceivingState[receivingState.ReceivedOn] = receivingState;

                                    //DECODE audio
                                    int len1;
                                    var decoded = _decoder.Decode(udpVoicePacket.AudioPart1Bytes,
                                                                  udpVoicePacket.AudioPart1Bytes.Length, out len1);


                                    if (len1 > 0)
                                    {
                                        // for some reason if this is removed then it lags?!
                                        //guess it makes a giant buffer and only uses a little?
                                        var tmp = new byte[len1];
                                        Buffer.BlockCopy(decoded, 0, tmp, 0, len1);

                                        //ALL GOOD!
                                        //create marker for bytes
                                        var audio = new ClientAudio
                                        {
                                            ClientGuid    = udpVoicePacket.Guid,
                                            PcmAudioShort = ConversionHelpers.ByteArrayToShortArray(tmp),
                                            //Convert to Shorts!
                                            ReceiveTime   = GetTickCount64(),
                                            Frequency     = udpVoicePacket.Frequency,
                                            Modulation    = udpVoicePacket.Modulation,
                                            Volume        = receivingRadio.volume,
                                            ReceivedRadio = receivingState.ReceivedOn,
                                            UnitId        = udpVoicePacket.UnitId,
                                            Encryption    = udpVoicePacket.Encryption,
                                            Decryptable   =
                                                (udpVoicePacket.Encryption == receivingRadio.encKey) &&
                                                receivingRadio.enc,
                                            // mark if we can decrypt it
                                            RadioReceivingState = receivingState,
                                            RecevingPower       =
                                                receivingPowerLossPercent,     //loss of 1.0 or greater is total loss
                                            LineOfSightLoss = lineOfSightLoss, // Loss of 1.0 or greater is total loss
                                            PacketNumber    = udpVoicePacket.PacketNumber
                                        };


                                        //handle effects
                                        var radioState = RadioReceivingState[audio.ReceivedRadio];

                                        if ((radioState == null) || radioState.PlayedEndOfTransmission ||
                                            !radioState.IsReceiving)
                                        {
                                            var decrytable = audio.Decryptable || (audio.Encryption == 0);

                                            //mark that we have decrpyted encrypted audio for sound effects
                                            if (decrytable && (audio.Encryption > 0))
                                            {
                                                _audioManager.PlaySoundEffectStartReceive(audio.ReceivedRadio,
                                                                                          true,
                                                                                          audio.Volume);
                                            }
                                            else
                                            {
                                                _audioManager.PlaySoundEffectStartReceive(audio.ReceivedRadio,
                                                                                          false,
                                                                                          audio.Volume);
                                            }
                                        }

                                        RadioReceivingState[audio.ReceivedRadio] = new RadioReceivingState
                                        {
                                            IsSecondary             = receivingState.IsSecondary,
                                            LastReceviedAt          = DateTime.Now.Ticks,
                                            PlayedEndOfTransmission = false,
                                            ReceivedOn = receivingState.ReceivedOn
                                        };

                                        _audioManager.AddClientAudio(audio);
                                    }
                                    else
                                    {
                                        Logger.Info("Failed to decode audio from Packet");
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.Info("Failed to decode audio from Packet");
                    }
                }
            }
            catch (OperationCanceledException)
            {
                Logger.Info("Stopped DeJitter Buffer");
            }
        }
        private void UdpAudioDecode()
        {
            try
            {
                while (!_stop)
                {
                    try
                    {
                        var encodedOpusAudio = new byte[0];
                        _encodedAudio.TryTake(out encodedOpusAudio, 100000, _stopFlag.Token);

                        var time = DateTime.Now.Ticks; //should add at the receive instead?

                        if ((encodedOpusAudio != null) &&
                            (encodedOpusAudio.Length >=
                             (UDPVoicePacket.PacketHeaderLength + UDPVoicePacket.FixedPacketLength +
                              UDPVoicePacket.FrequencySegmentLength)))
                        {
                            //  process
                            // check if we should play audio

                            var myClient = IsClientMetaDataValid(_guid);

                            if ((myClient != null))
                            {
                                //Decode bytes
                                var udpVoicePacket = UDPVoicePacket.DecodeVoicePacket(encodedOpusAudio);

                                if (udpVoicePacket != null)
                                {
                                    var vehicleId = -1;
                                    if (_clients.TryGetValue(udpVoicePacket.Guid, out var transmittingClient))
                                    {
                                        vehicleId = transmittingClient.GameState.vehicleId;
                                    }

                                    var globalFrequencies = _serverSettings.GlobalFrequencies;

                                    var frequencyCount = udpVoicePacket.Frequencies.Length;

                                    List <RadioReceivingPriority> radioReceivingPriorities =
                                        new List <RadioReceivingPriority>(frequencyCount);
                                    List <int> blockedRadios = CurrentlyBlockedRadios();

                                    // Parse frequencies into receiving radio priority for selection below
                                    for (var i = 0; i < frequencyCount; i++)
                                    {
                                        RadioReceivingState state = null;
                                        bool decryptable;

                                        //Check if Global
                                        bool globalFrequency = globalFrequencies.Contains(udpVoicePacket.Frequencies[i]);


                                        var radio = _clientStateSingleton.PlayerGameState.CanHearTransmission(
                                            udpVoicePacket.Frequencies[i],
                                            (RadioInformation.Modulation)udpVoicePacket.Modulations[i],
                                            udpVoicePacket.UnitId,
                                            vehicleId,
                                            blockedRadios,
                                            out state);

                                        float  losLoss = 0.0f;
                                        double receivPowerLossPercent = 0.0;

                                        if (radio != null && state != null)
                                        {
                                            if (
                                                radio.modulation == RadioInformation.Modulation.INTERCOM ||
                                                globalFrequency ||
                                                (!blockedRadios.Contains(state.ReceivedOn)
                                                )
                                                )
                                            {
                                                radioReceivingPriorities.Add(new RadioReceivingPriority()
                                                {
                                                    Frequency      = udpVoicePacket.Frequencies[i],
                                                    Modulation     = udpVoicePacket.Modulations[i],
                                                    ReceivingRadio = radio,
                                                    ReceivingState = state
                                                });
                                            }
                                        }
                                    }

                                    // Sort receiving radios to play audio on correct one
                                    radioReceivingPriorities.Sort(SortRadioReceivingPriorities);

                                    if (radioReceivingPriorities.Count > 0)
                                    {
                                        //ALL GOOD!
                                        //create marker for bytes
                                        for (int i = 0; i < radioReceivingPriorities.Count; i++)
                                        {
                                            var destinationRadio           = radioReceivingPriorities[i];
                                            var isSimultaneousTransmission = radioReceivingPriorities.Count > 1 && i > 0;

                                            var audio = new ClientAudio
                                            {
                                                ClientGuid   = udpVoicePacket.Guid,
                                                EncodedAudio = udpVoicePacket.AudioPart1Bytes,
                                                //Convert to Shorts!
                                                ReceiveTime   = DateTime.Now.Ticks,
                                                Frequency     = destinationRadio.Frequency,
                                                Modulation    = destinationRadio.Modulation,
                                                Volume        = destinationRadio.ReceivingRadio.volume,
                                                ReceivedRadio = destinationRadio.ReceivingState.ReceivedOn,
                                                UnitId        = udpVoicePacket.UnitId,

                                                RadioReceivingState = destinationRadio.ReceivingState,
                                                PacketNumber        = udpVoicePacket.PacketNumber,
                                                OriginalClientGuid  = udpVoicePacket.OriginalClientGuid
                                            };


                                            //handle effects
                                            var radioState = _radioReceivingState[audio.ReceivedRadio];

                                            if (!isSimultaneousTransmission &&
                                                (radioState == null || radioState.PlayedEndOfTransmission ||
                                                 !radioState.IsReceiving))
                                            {
                                                _audioManager.PlaySoundEffectStartReceive(audio.ReceivedRadio,
                                                                                          false,
                                                                                          audio.Volume, (RadioInformation.Modulation)audio.Modulation);
                                            }

                                            var transmitterName = "";
                                            if (_serverSettings.GetSettingAsBool(ServerSettingsKeys.SHOW_TRANSMITTER_NAME) &&
                                                _globalSettings.GetClientSettingBool(GlobalSettingsKeys.ShowTransmitterName) &&
                                                transmittingClient != null)

                                            {
                                                transmitterName = transmittingClient.Name;
                                            }

                                            var newRadioReceivingState = new RadioReceivingState
                                            {
                                                IsSecondary             = destinationRadio.ReceivingState.IsSecondary,
                                                LastReceivedAt          = DateTime.Now.Ticks,
                                                PlayedEndOfTransmission = false,
                                                ReceivedOn = destinationRadio.ReceivingState.ReceivedOn,
                                                SentBy     = transmitterName
                                            };

                                            _radioReceivingState[audio.ReceivedRadio] = newRadioReceivingState;

                                            // Only play actual audio once
                                            if (i == 0)
                                            {
                                                _audioManager.AddClientAudio(audio);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (!_stop)
                        {
                            Logger.Info(ex, "Failed to decode audio from Packet");
                        }
                    }
                }
            }
            catch (OperationCanceledException)
            {
                Logger.Info("Stopped DeJitter Buffer");
            }
        }
示例#7
0
        private void UdpAudioDecode()
        {
            try
            {
                while (!_stop)
                {
                    try
                    {
                        var encodedOpusAudio = new byte[0];
                        _encodedAudio.TryTake(out encodedOpusAudio, 100000, _stopFlag.Token);

                        var time = DateTime.Now.Ticks; //should add at the receive instead?

                        if ((encodedOpusAudio != null) &&
                            (encodedOpusAudio.Length >=
                             (UDPVoicePacket.PacketHeaderLength + UDPVoicePacket.FixedPacketLength +
                              UDPVoicePacket.FrequencySegmentLength)))
                        {
                            //  process
                            // check if we should play audio

                            var myClient = IsClientMetaDataValid(_guid);

                            if ((myClient != null) && _clientStateSingleton.DcsPlayerRadioInfo.IsCurrent())
                            {
                                //Decode bytes
                                var udpVoicePacket = UDPVoicePacket.DecodeVoicePacket(encodedOpusAudio);

                                if (udpVoicePacket != null && udpVoicePacket.Modulations[0] != 4)
                                {
                                    var globalFrequencies = _serverSettings.GlobalFrequencies;

                                    var frequencyCount = udpVoicePacket.Frequencies.Length;

                                    List <RadioReceivingPriority> radioReceivingPriorities =
                                        new List <RadioReceivingPriority>(frequencyCount);
                                    List <int> blockedRadios = CurrentlyBlockedRadios();

                                    // Parse frequencies into receiving radio priority for selection below
                                    for (var i = 0; i < frequencyCount; i++)
                                    {
                                        RadioReceivingState state = null;
                                        bool decryptable;

                                        //Check if Global
                                        bool globalFrequency = globalFrequencies.Contains(udpVoicePacket.Frequencies[i]);

                                        if (globalFrequency)
                                        {
                                            //remove encryption for global
                                            udpVoicePacket.Encryptions[i] = 0;
                                        }

                                        var radio = _clientStateSingleton.DcsPlayerRadioInfo.CanHearTransmission(
                                            udpVoicePacket.Frequencies[i],
                                            (RadioInformation.Modulation)udpVoicePacket.Modulations[i],
                                            udpVoicePacket.Encryptions[i],
                                            udpVoicePacket.UnitId,
                                            blockedRadios,
                                            out state,
                                            out decryptable);

                                        float  losLoss = 0.0f;
                                        double receivPowerLossPercent = 0.0;

                                        if (radio != null && state != null)
                                        {
                                            if (
                                                radio.modulation == RadioInformation.Modulation.INTERCOM ||
                                                globalFrequency ||
                                                (
                                                    HasLineOfSight(udpVoicePacket, out losLoss) &&
                                                    InRange(udpVoicePacket.Guid, udpVoicePacket.Frequencies[i],
                                                            out receivPowerLossPercent) &&
                                                    !blockedRadios.Contains(state.ReceivedOn)
                                                )
                                                )
                                            {
                                                decryptable =
                                                    (udpVoicePacket.Encryptions[i] == 0) ||
                                                    (udpVoicePacket.Encryptions[i] == radio.encKey && radio.enc);

                                                radioReceivingPriorities.Add(new RadioReceivingPriority()
                                                {
                                                    Decryptable               = decryptable,
                                                    Encryption                = udpVoicePacket.Encryptions[i],
                                                    Frequency                 = udpVoicePacket.Frequencies[i],
                                                    LineOfSightLoss           = losLoss,
                                                    Modulation                = udpVoicePacket.Modulations[i],
                                                    ReceivingPowerLossPercent = receivPowerLossPercent,
                                                    ReceivingRadio            = radio,
                                                    ReceivingState            = state
                                                });
                                            }
                                        }
                                    }

                                    // Sort receiving radios to play audio on correct one
                                    radioReceivingPriorities.Sort(SortRadioReceivingPriorities);

                                    if (radioReceivingPriorities.Count > 0)
                                    {
                                        //ALL GOOD!
                                        //create marker for bytes
                                        for (int i = 0; i < radioReceivingPriorities.Count; i++)
                                        {
                                            var destinationRadio           = radioReceivingPriorities[i];
                                            var isSimultaneousTransmission = radioReceivingPriorities.Count > 1 && i > 0;

                                            var audio = new ClientAudio
                                            {
                                                ClientGuid   = udpVoicePacket.Guid,
                                                EncodedAudio = udpVoicePacket.AudioPart1Bytes,
                                                //Convert to Shorts!
                                                ReceiveTime   = DateTime.Now.Ticks,
                                                Frequency     = destinationRadio.Frequency,
                                                Modulation    = destinationRadio.Modulation,
                                                Volume        = destinationRadio.ReceivingRadio.volume,
                                                ReceivedRadio = destinationRadio.ReceivingState.ReceivedOn,
                                                UnitId        = udpVoicePacket.UnitId,
                                                Encryption    = destinationRadio.Encryption,
                                                Decryptable   = destinationRadio.Decryptable,
                                                // mark if we can decrypt it
                                                RadioReceivingState = destinationRadio.ReceivingState,
                                                RecevingPower       =
                                                    destinationRadio
                                                    .ReceivingPowerLossPercent,     //loss of 1.0 or greater is total loss
                                                LineOfSightLoss =
                                                    destinationRadio
                                                    .LineOfSightLoss,     // Loss of 1.0 or greater is total loss
                                                PacketNumber = udpVoicePacket.PacketNumber
                                            };


                                            //handle effects
                                            var radioState = RadioReceivingState[audio.ReceivedRadio];

                                            if (!isSimultaneousTransmission &&
                                                (radioState == null || radioState.PlayedEndOfTransmission ||
                                                 !radioState.IsReceiving))
                                            {
                                                var audioDecryptable = audio.Decryptable || (audio.Encryption == 0);

                                                //mark that we have decrpyted encrypted audio for sound effects
                                                if (audioDecryptable && (audio.Encryption > 0))
                                                {
                                                    _audioManager.PlaySoundEffectStartReceive(audio.ReceivedRadio,
                                                                                              true,
                                                                                              audio.Volume);
                                                }
                                                else
                                                {
                                                    _audioManager.PlaySoundEffectStartReceive(audio.ReceivedRadio,
                                                                                              false,
                                                                                              audio.Volume);
                                                }
                                            }

                                            RadioReceivingState[audio.ReceivedRadio] = new RadioReceivingState
                                            {
                                                IsSecondary             = destinationRadio.ReceivingState.IsSecondary,
                                                IsSimultaneous          = isSimultaneousTransmission,
                                                LastReceviedAt          = DateTime.Now.Ticks,
                                                PlayedEndOfTransmission = false,
                                                ReceivedOn = destinationRadio.ReceivingState.ReceivedOn
                                            };

                                            // Only play actual audio once
                                            if (i == 0)
                                            {
                                                _audioManager.AddClientAudio(audio);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (!_stop)
                        {
                            Logger.Info(ex, "Failed to decode audio from Packet");
                        }
                    }
                }
            }
            catch (OperationCanceledException)
            {
                Logger.Info("Stopped DeJitter Buffer");
            }
        }
        private void UdpAudioDecode()
        {
            try
            {
                while (!_stop)
                {
                    try
                    {
                        var encodedOpusAudio = new byte[0];

                        try
                        {
                            _encodedAudio.TryTake(out encodedOpusAudio, 100000, _stopFlag.Token);
                        } catch (OperationCanceledException ex)
                        {
                            Logger.Debug(ex, $"{_mainClient.LogClientId}| Cancelled operating to get encoded audio");
                        }

                        if (encodedOpusAudio == null ||
                            encodedOpusAudio.Length <
                            UDPVoicePacket.PacketHeaderLength + UDPVoicePacket.FixedPacketLength +
                            UDPVoicePacket.FrequencySegmentLength)
                        {
                            continue;
                        }
                        //  process
                        // check if we should play audio

                        var myClient = IsClientMetaDataValid(_guid);

                        if (myClient == null)
                        {
                            continue;
                        }
                        //Decode bytes
                        var udpVoicePacket = UDPVoicePacket.DecodeVoicePacket(encodedOpusAudio);

                        if (udpVoicePacket == null || (Modulation)udpVoicePacket.Modulations[0] != Modulation.AM &&
                            (Modulation)udpVoicePacket.Modulations[0] != Modulation.FM)
                        {
                            continue;
                        }
                        var globalFrequencies = _serverSettings.GlobalFrequencies;

                        var frequencyCount = udpVoicePacket.Frequencies.Length;

                        var radioReceivingPriorities =
                            new List <RadioReceivingPriority>(frequencyCount);
                        var blockedRadios = CurrentlyBlockedRadios();

                        // Parse frequencies into receiving radio priority for selection below
                        for (var i = 0; i < frequencyCount; i++)
                        {
                            //Check if Global
                            var globalFrequency = globalFrequencies.Contains(udpVoicePacket.Frequencies[i]);

                            if (globalFrequency)
                            {
                                //remove encryption for global
                                udpVoicePacket.Encryptions[i] = 0;
                            }

                            var radio = _mainClient.DcsPlayerRadioInfo.CanHearTransmission(
                                udpVoicePacket.Frequencies[i],
                                (Modulation)udpVoicePacket.Modulations[i],
                                udpVoicePacket.Encryptions[i],
                                udpVoicePacket.UnitId,
                                blockedRadios,
                                out var state,
                                out var decryptable);

                            var losLoss = 0.0f;
                            var receivPowerLossPercent = 0.0;

                            if (radio == null || state == null)
                            {
                                continue;
                            }
                            if (radio.modulation != Modulation.INTERCOM && !globalFrequency &&
                                (!HasLineOfSight(udpVoicePacket, out losLoss) || !InRange(udpVoicePacket.Guid,
                                                                                          udpVoicePacket.Frequencies[i],
                                                                                          out receivPowerLossPercent) || blockedRadios.Contains(state.ReceivedOn)))
                            {
                                continue;
                            }
                            decryptable =
                                udpVoicePacket.Encryptions[i] == 0 ||
                                udpVoicePacket.Encryptions[i] == radio.encKey && radio.enc;

                            radioReceivingPriorities.Add(new RadioReceivingPriority
                            {
                                Decryptable               = decryptable,
                                Encryption                = udpVoicePacket.Encryptions[i],
                                Frequency                 = udpVoicePacket.Frequencies[i],
                                LineOfSightLoss           = losLoss,
                                Modulation                = udpVoicePacket.Modulations[i],
                                ReceivingPowerLossPercent = receivPowerLossPercent,
                                ReceivingRadio            = radio,
                                ReceivingState            = state
                            });
                        }

                        // Sort receiving radios to play audio on correct one
                        radioReceivingPriorities.Sort(SortRadioReceivingPriorities);

                        if (radioReceivingPriorities.Count <= 0)
                        {
                            continue;
                        }
                        {
                            //ALL GOOD!
                            //create marker for bytes
                            for (var i = 0; i < radioReceivingPriorities.Count; i++)
                            {
                                var destinationRadio           = radioReceivingPriorities[i];
                                var isSimultaneousTransmission = radioReceivingPriorities.Count > 1 && i > 0;

                                var audio = new ClientAudio
                                {
                                    ClientGuid   = udpVoicePacket.Guid,
                                    EncodedAudio = udpVoicePacket.AudioPart1Bytes,
                                    //Convert to Shorts!
                                    ReceiveTime   = DateTime.Now.Ticks,
                                    Frequency     = destinationRadio.Frequency,
                                    Modulation    = destinationRadio.Modulation,
                                    Volume        = destinationRadio.ReceivingRadio.volume,
                                    ReceivedRadio = destinationRadio.ReceivingState.ReceivedOn,
                                    UnitId        = udpVoicePacket.UnitId,
                                    Encryption    = destinationRadio.Encryption,
                                    Decryptable   = destinationRadio.Decryptable,
                                    // mark if we can decrypt it
                                    RadioReceivingState = destinationRadio.ReceivingState,
                                    RecevingPower       =
                                        destinationRadio
                                        .ReceivingPowerLossPercent,     //loss of 1.0 or greater is total loss
                                    LineOfSightLoss =
                                        destinationRadio
                                        .LineOfSightLoss,     // Loss of 1.0 or greater is total loss
                                    PacketNumber = udpVoicePacket.PacketNumber
                                };

                                RadioReceivingState[audio.ReceivedRadio] = new RadioReceivingState
                                {
                                    IsSecondary             = destinationRadio.ReceivingState.IsSecondary,
                                    IsSimultaneous          = isSimultaneousTransmission,
                                    LastReceviedAt          = DateTime.Now.Ticks,
                                    PlayedEndOfTransmission = false,
                                    ReceivedOn = destinationRadio.ReceivingState.ReceivedOn
                                };

                                // Only play actual audio once
                                if (i == 0)
                                {
                                    _mainClient.AudioManager.AddClientAudio(audio);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (!_stop)
                        {
                            Logger.Info(ex, $"{_mainClient.LogClientId}| Failed to decode audio from Packet");
                        }
                    }
                }
            }
            catch (OperationCanceledException)
            {
                Logger.Info($"{_mainClient.LogClientId}| Stopped DeJitter Buffer");
            }
        }
示例#9
0
 public void AddClientAudio(ClientAudio audio)
 {
     BotAudioProvider.AddClientAudioSamples(audio);
 }
示例#10
0
        public ClientAudio Send(byte[] bytes, int len)
        {
            // List of radios the transmission is sent to (can me multiple if simultaneous transmission is enabled)
            List <RadioInformation> transmittingRadios;
            //if either PTT is true, a microphone is available && socket connected etc
            var sendingOn = -1;

            if (_ready &&
                _listener != null &&
                _clientStateSingleton.DcsPlayerRadioInfo.IsCurrent() &&
                _audioInputSingleton.MicrophoneAvailable &&
                (bytes != null) &&
                (transmittingRadios = PTTPressed(out sendingOn)).Count > 0)
            //can only send if DCS is connected
            {
                try
                {
                    if (transmittingRadios.Count > 0)
                    {
                        List <double> frequencies = new List <double>(transmittingRadios.Count);
                        List <byte>   encryptions = new List <byte>(transmittingRadios.Count);
                        List <byte>   modulations = new List <byte>(transmittingRadios.Count);

                        for (int i = 0; i < transmittingRadios.Count; i++)
                        {
                            var radio = transmittingRadios[i];

                            // Further deduplicate transmitted frequencies if they have the same freq./modulation/encryption (caused by differently named radios)
                            bool alreadyIncluded = false;
                            for (int j = 0; j < frequencies.Count; j++)
                            {
                                if (frequencies[j] == radio.freq &&
                                    modulations[j] == (byte)radio.modulation &&
                                    encryptions[j] == (radio.enc ? radio.encKey : (byte)0))
                                {
                                    alreadyIncluded = true;
                                    break;
                                }
                            }

                            if (alreadyIncluded)
                            {
                                continue;
                            }

                            frequencies.Add(radio.freq);
                            encryptions.Add(radio.enc ? radio.encKey : (byte)0);
                            modulations.Add((byte)radio.modulation);
                        }

                        //generate packet
                        var udpVoicePacket = new UDPVoicePacket
                        {
                            GuidBytes               = _guidAsciiBytes,
                            AudioPart1Bytes         = bytes,
                            AudioPart1Length        = (ushort)bytes.Length,
                            Frequencies             = frequencies.ToArray(),
                            UnitId                  = _clientStateSingleton.DcsPlayerRadioInfo.unitId,
                            Encryptions             = encryptions.ToArray(),
                            Modulations             = modulations.ToArray(),
                            PacketNumber            = _packetNumber++,
                            OriginalClientGuidBytes = _guidAsciiBytes
                        };

                        var encodedUdpVoicePacket = udpVoicePacket.EncodePacket();

                        _listener.Send(encodedUdpVoicePacket, encodedUdpVoicePacket.Length, new IPEndPoint(_address, _port));

                        var currentlySelectedRadio = _clientStateSingleton.DcsPlayerRadioInfo.radios[sendingOn];

                        //not sending or really quickly switched sending
                        if (currentlySelectedRadio != null &&
                            (!_clientStateSingleton.RadioSendingState.IsSending || _clientStateSingleton.RadioSendingState.SendingOn != sendingOn))
                        {
                            _audioManager.PlaySoundEffectStartTransmit(sendingOn,
                                                                       currentlySelectedRadio.enc && (currentlySelectedRadio.encKey > 0),
                                                                       currentlySelectedRadio.volume, currentlySelectedRadio.modulation);
                        }

                        //set radio overlay state
                        _clientStateSingleton.RadioSendingState = new RadioSendingState
                        {
                            IsSending  = true,
                            LastSentAt = DateTime.Now.Ticks,
                            SendingOn  = sendingOn
                        };
                        var send = new ClientAudio()
                        {
                            Frequency       = frequencies[0], Modulation = modulations[0],
                            EncodedAudio    = bytes,
                            Encryption      = 0,
                            Volume          = 1,
                            Decryptable     = true,
                            LineOfSightLoss = 0,
                            RecevingPower   = 0,
                            ReceivedRadio   = 1
                        };
                        return(send);
                    }
                }
                catch (Exception e)
                {
                    Logger.Error(e, "Exception Sending Audio Message " + e.Message);
                }
            }
            else
            {
                if (_clientStateSingleton.RadioSendingState.IsSending)
                {
                    _clientStateSingleton.RadioSendingState.IsSending = false;

                    if (_clientStateSingleton.RadioSendingState.SendingOn >= 0)
                    {
                        var radio = _clientStateSingleton.DcsPlayerRadioInfo.radios[_clientStateSingleton.RadioSendingState.SendingOn];

                        _audioManager.PlaySoundEffectEndTransmit(_clientStateSingleton.RadioSendingState.SendingOn, radio.volume, radio.modulation);
                    }
                }
            }

            return(null);
        }
示例#11
0
        private void UdpAudioDecode()
        {
            try
            {
                while (!_stop)
                {
                    try
                    {
                        var encodedOpusAudio = new byte[0];
                        _encodedAudio.TryTake(out encodedOpusAudio, 100000, _stopFlag.Token);

                        var time = GetTickCount64(); //should add at the receive instead?

                        if (encodedOpusAudio != null && encodedOpusAudio.Length > 36)
                        {
                            //  process
                            // check if we should play audio

                            var myClient = IsClientMetaDataValid(_guid);

                            if (myClient != null && RadioDCSSyncServer.DcsPlayerRadioInfo.IsCurrent())
                            {
                                //Decode bytes
                                var udpVoicePacket = UDPVoicePacket.DecodeVoicePacket(encodedOpusAudio);

                                // check the radio
                                RadioReceivingState receivingState = null;
                                var receivingRadio =
                                    RadioDCSSyncServer.DcsPlayerRadioInfo.CanHearTransmission(udpVoicePacket.Frequency,
                                                                                              udpVoicePacket.Modulation,
                                                                                              udpVoicePacket.UnitId, out receivingState);

                                //Check that we're not transmitting on this radio

                                double receivingPower  = 0;
                                float  lineOfSightLoss = 0;

                                if (receivingRadio != null && receivingState != null
                                    &&
                                    (receivingRadio.modulation == 2
                                     // INTERCOM Modulation is 2 so if its two dont bother checking LOS and Range
                                     ||
                                     (
                                         HasLineOfSight(udpVoicePacket, out lineOfSightLoss)
                                         &&
                                         InRange(udpVoicePacket, out receivingPower)
                                         &&
                                         !ShouldBlockRxAsTransmitting(receivingState.ReceivedOn)
                                     )
                                    )
                                    )
                                {
                                    //  RadioReceivingState[receivingState.ReceivedOn] = receivingState;

                                    //DECODE audio
                                    int len1;
                                    var decoded = _decoder.Decode(udpVoicePacket.AudioPart1Bytes,
                                                                  udpVoicePacket.AudioPart1Bytes.Length, out len1);

                                    int len2;
                                    var decoded2 = _decoder.Decode(udpVoicePacket.AudioPart2Bytes,
                                                                   udpVoicePacket.AudioPart2Bytes.Length, out len2);

                                    if (len1 > 0 && len2 > 0)
                                    {
                                        // for some reason if this is removed then it lags?!
                                        //guess it makes a giant buffer and only uses a little?
                                        var tmp = new byte[len1 + len2];
                                        Buffer.BlockCopy(decoded, 0, tmp, 0, len1);
                                        Buffer.BlockCopy(decoded2, 0, tmp, len1, len2);

                                        //ALL GOOD!
                                        //create marker for bytes
                                        var audio = new ClientAudio
                                        {
                                            ClientGuid    = udpVoicePacket.Guid,
                                            PcmAudioShort = ConversionHelpers.ByteArrayToShortArray(tmp),
                                            //Convert to Shorts!
                                            ReceiveTime   = GetTickCount64(),
                                            Frequency     = udpVoicePacket.Frequency,
                                            Modulation    = udpVoicePacket.Modulation,
                                            Volume        = receivingRadio.volume,
                                            ReceivedRadio = receivingState.ReceivedOn,
                                            UnitId        = udpVoicePacket.UnitId,
                                            Encryption    = udpVoicePacket.Encryption,
                                            Decryptable   =
                                                udpVoicePacket.Encryption == receivingRadio.encKey && receivingRadio.enc,
                                            // mark if we can decrypt it
                                            RadioReceivingState = receivingState,
                                            RecevingPower       = receivingPower,
                                            LineOfSightLoss     = lineOfSightLoss // Loss of 1.0 or greater is total loss
                                        };

                                        //add to JitterBuffer!
                                        lock (_lock)
                                        {
                                            _jitterBuffer.AddAudio(audio);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.Info("Failed Decoding");
                    }
                }
            }
            catch (OperationCanceledException)
            {
                Logger.Info("Stopped DeJitter Buffer");
            }
        }
示例#12
0
        private void UdpAudioDecode()
        {
            try
            {
                while (!_stop)
                {
                    try
                    {
                        var encodedOpusAudio = new byte[0];
                        _encodedAudio.TryTake(out encodedOpusAudio, 100000, _stopFlag.Token);

                        var time = DateTime.Now.Ticks; //should add at the receive instead?

                        if ((encodedOpusAudio != null) &&
                            (encodedOpusAudio.Length >=
                             (UDPVoicePacket.PacketHeaderLength + UDPVoicePacket.FixedPacketLength +
                              UDPVoicePacket.FrequencySegmentLength)))
                        {
                            //  process
                            // check if we should play audio

                            var myClient = IsClientMetaDataValid(_guid);

                            if ((myClient != null) && _clientStateSingleton.DcsPlayerRadioInfo.IsCurrent())
                            {
                                //Decode bytes
                                var udpVoicePacket = UDPVoicePacket.DecodeVoicePacket(encodedOpusAudio);

                                if (udpVoicePacket != null)
                                {
                                    var globalFrequencies = _serverSettings.GlobalFrequencies;

                                    var frequencyCount = udpVoicePacket.Frequencies.Length;

                                    List <RadioReceivingPriority> radioReceivingPriorities =
                                        new List <RadioReceivingPriority>(frequencyCount);
                                    List <int> blockedRadios = CurrentlyBlockedRadios();

                                    var strictEncryption = _serverSettings.GetSettingAsBool(ServerSettingsKeys.STRICT_RADIO_ENCRYPTION);

                                    // Parse frequencies into receiving radio priority for selection below
                                    for (var i = 0; i < frequencyCount; i++)
                                    {
                                        RadioReceivingState state = null;
                                        bool decryptable;

                                        //Check if Global
                                        bool globalFrequency = globalFrequencies.Contains(udpVoicePacket.Frequencies[i]);

                                        if (globalFrequency)
                                        {
                                            //remove encryption for global
                                            udpVoicePacket.Encryptions[i] = 0;
                                        }

                                        var radio = _clientStateSingleton.DcsPlayerRadioInfo.CanHearTransmission(
                                            udpVoicePacket.Frequencies[i],
                                            (RadioInformation.Modulation)udpVoicePacket.Modulations[i],
                                            udpVoicePacket.Encryptions[i],
                                            strictEncryption,
                                            udpVoicePacket.UnitId,
                                            blockedRadios,
                                            out state,
                                            out decryptable);

                                        float  losLoss = 0.0f;
                                        double receivPowerLossPercent = 0.0;

                                        if (radio != null && state != null)
                                        {
                                            if (
                                                radio.modulation == RadioInformation.Modulation.INTERCOM ||
                                                radio.modulation == RadioInformation.Modulation.MIDS || // IGNORE LOS and Distance for MIDS - we assume a Link16 Network is in place
                                                globalFrequency ||
                                                (
                                                    HasLineOfSight(udpVoicePacket, out losLoss) &&
                                                    InRange(udpVoicePacket.Guid, udpVoicePacket.Frequencies[i],
                                                            out receivPowerLossPercent) &&
                                                    !blockedRadios.Contains(state.ReceivedOn)
                                                )
                                                )
                                            {
                                                // This is already done in CanHearTransmission!!
                                                //decryptable =
                                                //    (udpVoicePacket.Encryptions[i] == radio.encKey && radio.enc) ||
                                                //    (!strictEncryption && udpVoicePacket.Encryptions[i] == 0);

                                                radioReceivingPriorities.Add(new RadioReceivingPriority()
                                                {
                                                    Decryptable               = decryptable,
                                                    Encryption                = udpVoicePacket.Encryptions[i],
                                                    Frequency                 = udpVoicePacket.Frequencies[i],
                                                    LineOfSightLoss           = losLoss,
                                                    Modulation                = udpVoicePacket.Modulations[i],
                                                    ReceivingPowerLossPercent = receivPowerLossPercent,
                                                    ReceivingRadio            = radio,
                                                    ReceivingState            = state
                                                });
                                            }
                                        }
                                    }

                                    // Sort receiving radios to play audio on correct one
                                    radioReceivingPriorities.Sort(SortRadioReceivingPriorities);

                                    if (radioReceivingPriorities.Count > 0)
                                    {
                                        //ALL GOOD!
                                        //create marker for bytes
                                        for (int i = 0; i < radioReceivingPriorities.Count; i++)
                                        {
                                            var destinationRadio           = radioReceivingPriorities[i];
                                            var isSimultaneousTransmission = radioReceivingPriorities.Count > 1 && i > 0;

                                            var audio = new ClientAudio
                                            {
                                                ClientGuid   = udpVoicePacket.Guid,
                                                EncodedAudio = udpVoicePacket.AudioPart1Bytes,
                                                //Convert to Shorts!
                                                ReceiveTime   = DateTime.Now.Ticks,
                                                Frequency     = destinationRadio.Frequency,
                                                Modulation    = destinationRadio.Modulation,
                                                Volume        = destinationRadio.ReceivingRadio.volume,
                                                ReceivedRadio = destinationRadio.ReceivingState.ReceivedOn,
                                                UnitId        = udpVoicePacket.UnitId,
                                                Encryption    = destinationRadio.Encryption,
                                                Decryptable   = destinationRadio.Decryptable,
                                                // mark if we can decrypt it
                                                RadioReceivingState = destinationRadio.ReceivingState,
                                                RecevingPower       =
                                                    destinationRadio
                                                    .ReceivingPowerLossPercent,     //loss of 1.0 or greater is total loss
                                                LineOfSightLoss =
                                                    destinationRadio
                                                    .LineOfSightLoss,     // Loss of 1.0 or greater is total loss
                                                PacketNumber       = udpVoicePacket.PacketNumber,
                                                OriginalClientGuid = udpVoicePacket.OriginalClientGuid
                                            };


                                            //handle effects
                                            var radioState = _radioReceivingState[audio.ReceivedRadio];

                                            if (!isSimultaneousTransmission &&
                                                (radioState == null || radioState.PlayedEndOfTransmission ||
                                                 !radioState.IsReceiving))
                                            {
                                                var audioDecryptable = audio.Decryptable /* || (audio.Encryption == 0) <--- this has already been tested above */;

                                                //mark that we have decrypted encrypted audio for sound effects
                                                if (audioDecryptable && (audio.Encryption > 0))
                                                {
                                                    _audioManager.PlaySoundEffectStartReceive(audio.ReceivedRadio,
                                                                                              true,
                                                                                              audio.Volume, (Modulation)audio.Modulation);
                                                }
                                                else
                                                {
                                                    _audioManager.PlaySoundEffectStartReceive(audio.ReceivedRadio,
                                                                                              false,
                                                                                              audio.Volume, (Modulation)audio.Modulation);
                                                }
                                            }

                                            var transmitterName = "";
                                            if (_serverSettings.GetSettingAsBool(ServerSettingsKeys.SHOW_TRANSMITTER_NAME) &&
                                                _globalSettings.GetClientSettingBool(GlobalSettingsKeys.ShowTransmitterName) &&
                                                _clients.TryGetValue(udpVoicePacket.Guid, out var transmittingClient))

                                            {
                                                transmitterName = transmittingClient.Name;
                                            }

                                            var newRadioReceivingState = new RadioReceivingState
                                            {
                                                IsSecondary             = destinationRadio.ReceivingState.IsSecondary,
                                                IsSimultaneous          = isSimultaneousTransmission,
                                                LastReceviedAt          = DateTime.Now.Ticks,
                                                PlayedEndOfTransmission = false,
                                                ReceivedOn = destinationRadio.ReceivingState.ReceivedOn,
                                                SentBy     = transmitterName
                                            };

                                            _radioReceivingState[audio.ReceivedRadio] = newRadioReceivingState;

                                            if (i == 0)
                                            {
                                                bool overrideEffects = false;

                                                if (_serverSettings.GetSettingAsBool(ServerSettingsKeys
                                                                                     .RADIO_EFFECT_OVERRIDE))
                                                {
                                                    overrideEffects = _serverSettings.GlobalFrequencies.Contains(audio.Frequency);
                                                }

                                                _audioManager.AddClientAudio(audio, overrideEffects);
                                            }
                                        }

                                        //handle retransmission
                                        RetransmitAudio(udpVoicePacket, radioReceivingPriorities);
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (!_stop)
                        {
                            Logger.Info(ex, "Failed to decode audio from Packet");
                        }
                    }
                }
            }
            catch (OperationCanceledException)
            {
                Logger.Info("Stopped DeJitter Buffer");
            }
        }