private void AddRadioEffectIntercom(TransmittedAudio clientAudio)
        {
            var mixedAudio = clientAudio.PcmAudioShort;

            for (var i = 0; i < mixedAudio.Length; i++)
            {
                var audio = mixedAudio[i] / 32768f;

                audio = _highPassFilter.Transform(audio);

                if (float.IsNaN(audio))
                {
                    audio = _lowPassFilter.Transform(mixedAudio[i]);
                }
                else
                {
                    audio = _lowPassFilter.Transform(audio);
                }

                if (!float.IsNaN(audio))
                {
                    // clip
                    if (audio > 1.0f)
                    {
                        audio = 1.0f;
                    }
                    if (audio < -1.0f)
                    {
                        audio = -1.0f;
                    }

                    mixedAudio[i] = (short)(audio * 32767);
                }
            }
        }
        public byte[] AddClientAudioSamples(TransmittedAudio audio, short[] pcmShort)
        {
            audio.PcmAudioShort = pcmShort;

            if (audio.Modulation == (short)RadioInformation.Modulation.INTERCOM ||
                audio.Modulation == (short)RadioInformation.Modulation.MIDS)
            {
                if (profileSettings.GetClientSettingBool(ProfileSettingsKeys.RadioEffects))
                {
                    AddRadioEffectIntercom(audio);
                }
            }
            else
            {
                AddRadioEffect(audio);
            }

            return(ConversionHelpers.ShortArrayToByteArray(audio.PcmAudioShort));
        }
        public byte[] AddClientAudioSamples(TransmittedAudio audio, short[] pcmShort)
        {
            audio.PcmAudioShort = pcmShort;

            //only get settings every 3 seconds - and cache them - issues with performance
            long now = DateTime.Now.Ticks;

            if (TimeSpan.FromTicks(now - lastRefresh).TotalSeconds > 3) //3 seconds since last refresh
            {
                lastRefresh = now;

                natoToneEnabled     = profileSettings.GetClientSettingBool(ProfileSettingsKeys.NATOTone);
                hqToneEnabled       = profileSettings.GetClientSettingBool(ProfileSettingsKeys.HAVEQUICKTone);
                radioEffectsEnabled = profileSettings.GetClientSettingBool(ProfileSettingsKeys.RadioEffects);
                clippingEnabled     = profileSettings.GetClientSettingBool(ProfileSettingsKeys.RadioEffectsClipping);
                hqToneVolume        = profileSettings.GetClientSettingFloat(ProfileSettingsKeys.HQToneVolume);
                natoToneVolume      = profileSettings.GetClientSettingFloat(ProfileSettingsKeys.NATOToneVolume);

                fmVol  = profileSettings.GetClientSettingFloat(ProfileSettingsKeys.FMNoiseVolume);
                hfVol  = profileSettings.GetClientSettingFloat(ProfileSettingsKeys.HFNoiseVolume);
                uhfVol = profileSettings.GetClientSettingFloat(ProfileSettingsKeys.UHFNoiseVolume);
                vhfVol = profileSettings.GetClientSettingFloat(ProfileSettingsKeys.VHFNoiseVolume);
            }

            if (audio.Modulation == (short)RadioInformation.Modulation.INTERCOM ||
                audio.Modulation == (short)RadioInformation.Modulation.MIDS)
            {
                if (profileSettings.GetClientSettingBool(ProfileSettingsKeys.RadioEffects))
                {
                    AddRadioEffectIntercom(audio);
                }
            }
            else
            {
                AddRadioEffect(audio);
            }

            return(ConversionHelpers.ShortArrayToByteArray(audio.PcmAudioShort));
        }
        private double AddRadioBackgroundNoiseEffect(double audio, TransmittedAudio clientAudio)
        {
            var fmVol = profileSettings.GetClientSetting(ProfileSettingsKeys.FMNoiseVolume)
                        .DoubleValue;

            var hfVol = profileSettings.GetClientSetting(ProfileSettingsKeys.HFNoiseVolume)
                        .DoubleValue;
            var uhfVol = profileSettings.GetClientSetting(ProfileSettingsKeys.UHFNoiseVolume)
                         .DoubleValue;
            var vhfVol = profileSettings.GetClientSetting(ProfileSettingsKeys.VHFNoiseVolume)
                         .DoubleValue;

            if (profileSettings.GetClientSettingBool(ProfileSettingsKeys.RadioBackgroundNoiseEffect))
            {
                if (clientAudio.Modulation == HQ || clientAudio.Modulation == AM)
                {
                    //mix in based on frequency
                    if (clientAudio.Frequency >= 200d * 1000000)
                    {
                        if (effectProvider.UHFNoise.Loaded)
                        {
                            var noise = effectProvider.UHFNoise.AudioEffectDouble;
                            //UHF Band?
                            audio += ((noise[uhfNoisePosition]) * uhfVol);
                            uhfNoisePosition++;

                            if (uhfNoisePosition == noise.Length)
                            {
                                uhfNoisePosition = 0;
                            }
                        }
                    }
                    else if (clientAudio.Frequency > 80d * 1000000)
                    {
                        if (effectProvider.VHFNoise.Loaded)
                        {
                            //VHF Band? - Very rough
                            var noise = effectProvider.VHFNoise.AudioEffectDouble;
                            audio += ((double)(noise[vhfNoisePosition]) * vhfVol);
                            vhfNoisePosition++;

                            if (vhfNoisePosition == noise.Length)
                            {
                                vhfNoisePosition = 0;
                            }
                        }
                    }
                    else
                    {
                        if (effectProvider.HFNoise.Loaded)
                        {
                            //HF!
                            var noise = effectProvider.HFNoise.AudioEffectDouble;
                            audio += ((double)(noise[hfNoisePosition]) * hfVol);
                            hfNoisePosition++;

                            if (hfNoisePosition == noise.Length)
                            {
                                hfNoisePosition = 0;
                            }
                        }
                    }
                }
                else if (clientAudio.Modulation == FM)
                {
                    if (effectProvider.FMNoise.Loaded)
                    {
                        //FM picks up most of the 20-60 ish range + has a different effect
                        //HF!
                        var noise = effectProvider.FMNoise.AudioEffectDouble;
                        //UHF Band?
                        audio += ((double)(noise[fmNoisePosition]) * fmVol);
                        fmNoisePosition++;

                        if (fmNoisePosition == noise.Length)
                        {
                            fmNoisePosition = 0;
                        }
                    }
                }
            }

            return(audio);
        }
        private void AddRadioEffect(TransmittedAudio clientAudio)
        {
            var mixedAudio          = clientAudio.PcmAudioShort;
            var natoToneEnabled     = profileSettings.GetClientSettingBool(ProfileSettingsKeys.NATOTone);
            var hqToneEnabled       = profileSettings.GetClientSettingBool(ProfileSettingsKeys.HAVEQUICKTone);
            var radioEffectsEnabled = profileSettings.GetClientSettingBool(ProfileSettingsKeys.RadioEffects);
            var clippingEnabled     = profileSettings.GetClientSettingBool(ProfileSettingsKeys.RadioEffectsClipping);
            var hqToneVolume        = profileSettings.GetClientSetting(ProfileSettingsKeys.HQToneVolume)
                                      .DoubleValue;
            var natoToneVolume = profileSettings.GetClientSetting(ProfileSettingsKeys.NATOToneVolume)
                                 .DoubleValue;

            for (var i = 0; i < mixedAudio.Length; i++)
            {
                var audio = (double)mixedAudio[i] / 32768f;

                if (radioEffectsEnabled)
                {
                    if (clippingEnabled)
                    {
                        if (audio > RadioFilter.CLIPPING_MAX)
                        {
                            audio = RadioFilter.CLIPPING_MAX;
                        }
                        else if (audio < RadioFilter.CLIPPING_MIN)
                        {
                            audio = RadioFilter.CLIPPING_MIN;
                        }
                    }

                    //high and low pass filter
                    for (int j = 0; j < _filters.Length; j++)
                    {
                        var filter = _filters[j];
                        audio = filter.ProcessSample(audio);
                        if (double.IsNaN(audio))
                        {
                            audio = mixedAudio[j];
                        }

                        audio *= RadioFilter.BOOST;
                    }
                }

                if (clientAudio.Modulation == FM &&
                    effectProvider.NATOTone.Loaded &&
                    natoToneEnabled)
                {
                    var natoTone = effectProvider.NATOTone.AudioEffectDouble;
                    audio += ((double)(natoTone[natoPosition]) * natoToneVolume);
                    natoPosition++;

                    if (natoPosition == natoTone.Length)
                    {
                        natoPosition = 0;
                    }
                }

                if (clientAudio.Modulation == HQ &&
                    effectProvider.HAVEQUICKTone.Loaded &&
                    hqToneEnabled)
                {
                    var hqTone = effectProvider.HAVEQUICKTone.AudioEffectDouble;

                    audio += ((double)(hqTone[hqTonePosition]) * hqToneVolume);
                    hqTonePosition++;

                    if (hqTonePosition == hqTone.Length)
                    {
                        var reset = _random.NextDouble();

                        if (reset > HQ_RESET_CHANCE)
                        {
                            hqTonePosition = 0;
                        }
                        else
                        {
                            //one back to try again
                            hqTonePosition += -1;
                        }
                    }
                }

                audio = AddRadioBackgroundNoiseEffect(audio, clientAudio);

                // clip
                if (audio > 1.0f)
                {
                    audio = 1.0f;
                }
                if (audio < -1.0f)
                {
                    audio = -1.0f;
                }

                mixedAudio[i] = (short)(audio * 32768f);
            }
        }
Exemple #6
0
        public TransmittedAudio 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 TransmittedAudio
                        {
                            Frequency = frequencies[0], Modulation = modulations[0]
                        };
                        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);
        }