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); } }
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); }