[AFV] Add HF simulation

This commit is contained in:
Roland Rossgotterer
2019-09-30 09:48:04 +02:00
committed by Mat Sutcliffe
parent 2c1067b27e
commit 1f2d4a10b1
9 changed files with 66 additions and 16 deletions

View File

@@ -11,6 +11,7 @@
#include "callsignsampleprovider.h"
#include "callsigndelaycache.h"
#include "blacksound/sampleprovider/samples.h"
#include "blackcore/afv/audio/receiversampleprovider.h"
#include <QtMath>
#include <QDebug>
@@ -22,9 +23,10 @@ namespace BlackCore
{
namespace Audio
{
CallsignSampleProvider::CallsignSampleProvider(const QAudioFormat &audioFormat, QObject *parent) :
CallsignSampleProvider::CallsignSampleProvider(const QAudioFormat &audioFormat, const CReceiverSampleProvider *receiver, QObject *parent) :
ISampleProvider(parent),
m_audioFormat(audioFormat),
m_receiver(receiver),
m_decoder(audioFormat.sampleRate(), 1)
{
Q_ASSERT(audioFormat.channelCount() == 1);
@@ -36,6 +38,9 @@ namespace BlackCore
m_whiteNoise = new CResourceSoundSampleProvider(Samples::instance().whiteNoise(), m_mixer);
m_whiteNoise->setLooping(true);
m_whiteNoise->setGain(0.0);
m_hfWhiteNoise = new CResourceSoundSampleProvider(Samples::instance().hfWhiteNoise(), m_mixer);
m_hfWhiteNoise->setLooping(true);
m_hfWhiteNoise->setGain(0.0);
m_acBusNoise = new CSawToothGenerator(400, m_mixer);
m_audioInput = new CBufferedWaveProvider(audioFormat, m_mixer);
@@ -48,6 +53,7 @@ namespace BlackCore
m_mixer->addMixerInput(m_whiteNoise);
m_mixer->addMixerInput(m_acBusNoise);
m_mixer->addMixerInput(m_hfWhiteNoise);
m_mixer->addMixerInput(m_voiceEq);
m_timer.setInterval(100);
@@ -165,23 +171,41 @@ namespace BlackCore
{
m_crackleSoundProvider->setGain(0.0);
m_whiteNoise->setGain(0.0);
m_hfWhiteNoise->setGain(0.0);
m_acBusNoise->setGain(0.0);
m_simpleCompressorEffect->setEnabled(false);
m_voiceEq->setBypassEffects(true);
}
else
{
double crackleFactor = static_cast<double>(((qExp(m_distanceRatio) * qPow(m_distanceRatio, -4.0)) / 350) - 0.00776652);
if (m_receiver->getFrequencyHz() < 30000000)
{
float crackleFactor = (float)(((qExp(m_distanceRatio) * qPow(m_distanceRatio, -4.0)) / 350) - 0.00776652);
if (crackleFactor < 0.00) { crackleFactor = 0.0f; }
if (crackleFactor > 0.20) { crackleFactor = 0.20f; }
if (crackleFactor < 0.0f) { crackleFactor = 0.0f; }
if (crackleFactor > 0.20f) { crackleFactor = 0.20f; }
m_crackleSoundProvider->setGain(crackleFactor * 2);
m_whiteNoise->setGain(m_whiteNoiseGainMin);
m_acBusNoise->setGain(m_acBusGainMin);
m_simpleCompressorEffect->setEnabled(true);
m_voiceEq->setBypassEffects(false);
m_voiceEq->setOutputGain(1.0 - crackleFactor * 3.7);
m_hfWhiteNoise->setGain(m_hfWhiteNoiseGainMin);
m_acBusNoise->setGain(m_acBusGainMin + 0.001f);
m_simpleCompressorEffect->setEnabled(true);
m_voiceEq->setBypassEffects(false);
m_voiceEq->setOutputGain(0.38f);
m_whiteNoise->setGain(0.0);
}
else
{
float crackleFactor = (float)(((qExp(m_distanceRatio) * qPow(m_distanceRatio, -4.0)) / 350) - 0.00776652);
if (crackleFactor < 0.0f) { crackleFactor = 0.0f; }
if (crackleFactor > 0.20f) { crackleFactor = 0.20f; }
m_crackleSoundProvider->setGain(crackleFactor * 2);
m_whiteNoise->setGain(m_whiteNoiseGainMin);
m_acBusNoise->setGain(m_acBusGainMin);
m_simpleCompressorEffect->setEnabled(true);
m_voiceEq->setBypassEffects(false);
m_voiceEq->setOutputGain(1.0 - crackleFactor * 3.7);
}
}
}

View File

@@ -33,6 +33,8 @@ namespace BlackCore
{
namespace Audio
{
class CReceiverSampleProvider;
//! Callsign provide
class CallsignSampleProvider : public BlackSound::SampleProvider::ISampleProvider
{
@@ -40,7 +42,7 @@ namespace BlackCore
public:
//! Ctor
CallsignSampleProvider(const QAudioFormat &audioFormat, QObject *parent = nullptr);
CallsignSampleProvider(const QAudioFormat &audioFormat, const BlackCore::Afv::Audio::CReceiverSampleProvider *receiver, QObject *parent = nullptr);
int readSamples(QVector<qint16> &samples, qint64 count) override;
@@ -70,6 +72,7 @@ namespace BlackCore
QAudioFormat m_audioFormat;
const double m_whiteNoiseGainMin = 0.17; //0.01;
const double m_hfWhiteNoiseGainMin = 0.6; //0.01;
const double m_acBusGainMin = 0.0028; //0.002;
const int m_frameCount = 960;
const int m_idleTimeoutMs = 500;
@@ -82,9 +85,11 @@ namespace BlackCore
float m_distanceRatio = 1.0;
const CReceiverSampleProvider *m_receiver = nullptr;
BlackSound::SampleProvider::CMixingSampleProvider *m_mixer = nullptr;
BlackSound::SampleProvider::CResourceSoundSampleProvider *m_crackleSoundProvider = nullptr;
BlackSound::SampleProvider::CResourceSoundSampleProvider *m_whiteNoise = nullptr;
BlackSound::SampleProvider::CResourceSoundSampleProvider *m_hfWhiteNoise = nullptr;
BlackSound::SampleProvider::CSawToothGenerator *m_acBusNoise = nullptr;
BlackSound::SampleProvider::CSimpleCompressorEffect *m_simpleCompressorEffect = nullptr;
BlackSound::SampleProvider::CEqualizerSampleProvider *m_voiceEq = nullptr;

View File

@@ -31,7 +31,7 @@ namespace BlackCore
for (int i = 0; i < voiceInputNumber; i++)
{
auto voiceInput = new CallsignSampleProvider(audioFormat, m_mixer);
auto voiceInput = new CallsignSampleProvider(audioFormat, this, m_mixer);
m_voiceInputs.push_back(voiceInput);
m_mixer->addMixerInput(voiceInput);
}
@@ -198,8 +198,10 @@ namespace BlackCore
}
}
uint CReceiverSampleProvider::getFrequencyHz() const
{
return m_frequencyHz;
}
} // ns
} // ns

View File

@@ -72,6 +72,9 @@ namespace BlackCore
//! \remark those callsigns are transmitting and "I do receive them"
const BlackMisc::Aviation::CCallsignSet &getReceivingCallsigns() { return m_receivingCallsigns; }
//! Get frequency in Hz
uint getFrequencyHz() const;
signals:
//! Receving callsigns have changed
void receivingCallsignsChanged(const TransceiverReceivingCallsignsChangedArgs &args);

View File

@@ -93,7 +93,7 @@ namespace BlackCore
if (m_connection->isConnected()) { emit this->connectionStatusChanged(Connected); }
else { emit this->connectionStatusChanged(Disconnected); }
m_connection->getAllAliasedStations();
m_aliasedStations = m_connection->getAllAliasedStations();
}
void CAfvClient::disconnectFrom()
@@ -225,6 +225,17 @@ namespace BlackCore
// Fix rounding issues like 128074999 Hz -> 128075000 Hz
quint32 roundedFrequencyHz = static_cast<quint32>(qRound(frequencyHz / 1000.0)) * 1000;
auto it = std::find_if(m_aliasedStations.begin(), m_aliasedStations.end(), [roundedFrequencyHz](const StationDto & d)
{
return d.frequencyAlias == roundedFrequencyHz;
});
if (it != m_aliasedStations.end())
{
qDebug() << "Aliasing" << frequencyHz << "Hz [VHF] to" << it->frequency << "Hz [HF]";
roundedFrequencyHz = it->frequency;
}
if (m_transceivers.size() >= id + 1)
{
if (m_transceivers[id].frequencyHz != roundedFrequencyHz)

View File

@@ -232,6 +232,7 @@ namespace BlackCore
QTimer m_voiceServerPositionTimer;
QVector<TransceiverDto> m_transceivers;
QSet<quint16> m_enabledTransceivers;
QVector<StationDto> m_aliasedStations;
Audio::InputVolumeStreamArgs m_inputVolumeStream;
Audio::OutputVolumeStreamArgs m_outputVolumeStream;