mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-01 05:26:45 +08:00
[AFV] Change output format and processing to 32 bit float
32 bit float is what is used in C# reference and has a much higher dynamic range. 16 bit integer was clipping very often with all the VHF simulation applied.
This commit is contained in:
committed by
Mat Sutcliffe
parent
fbb126370c
commit
240df93406
@@ -11,6 +11,7 @@
|
||||
#include "callsignsampleprovider.h"
|
||||
#include "callsigndelaycache.h"
|
||||
#include "blacksound/sampleprovider/samples.h"
|
||||
#include "blacksound/audioutilities.h"
|
||||
#include "blackcore/afv/audio/receiversampleprovider.h"
|
||||
#include <QtMath>
|
||||
#include <QDebug>
|
||||
@@ -60,7 +61,7 @@ namespace BlackCore
|
||||
connect(&m_timer, &QTimer::timeout, this, &CallsignSampleProvider::timerElapsed);
|
||||
}
|
||||
|
||||
int CallsignSampleProvider::readSamples(QVector<qint16> &samples, qint64 count)
|
||||
int CallsignSampleProvider::readSamples(QVector<float> &samples, qint64 count)
|
||||
{
|
||||
int noOfSamples = m_mixer->readSamples(samples, count);
|
||||
|
||||
@@ -103,7 +104,7 @@ namespace BlackCore
|
||||
if (delayMs > 0)
|
||||
{
|
||||
int phaseDelayLength = (m_audioFormat.sampleRate() / 1000) * delayMs;
|
||||
QVector<qint16> phaseDelay(phaseDelayLength * 2, 0);
|
||||
QVector<float> phaseDelay(phaseDelayLength * 2, 0);
|
||||
m_audioInput->addSamples(phaseDelay);
|
||||
}
|
||||
}
|
||||
@@ -131,7 +132,7 @@ namespace BlackCore
|
||||
setEffects();
|
||||
|
||||
QVector<qint16> audio = decodeOpus(audioDto.audio);
|
||||
m_audioInput->addSamples(audio);
|
||||
m_audioInput->addSamples(BlackSound::convertFromShortToFloat(audio));
|
||||
m_lastPacketLatch = audioDto.lastPacket;
|
||||
if (audioDto.lastPacket && !m_underflow) { CallsignDelayCache::instance().success(m_callsign); }
|
||||
m_lastSamplesAddedUtc = QDateTime::currentDateTimeUtc();
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace BlackCore
|
||||
//! Ctor
|
||||
CallsignSampleProvider(const QAudioFormat &audioFormat, const BlackCore::Afv::Audio::CReceiverSampleProvider *receiver, QObject *parent = nullptr);
|
||||
|
||||
int readSamples(QVector<qint16> &samples, qint64 count) override;
|
||||
int readSamples(QVector<float> &samples, qint64 count) override;
|
||||
|
||||
//! The callsign
|
||||
const QString &callsign() const { return m_callsign; }
|
||||
|
||||
@@ -36,22 +36,20 @@ namespace BlackCore
|
||||
int sampleBytes = m_outputFormat.sampleSize() / 8;
|
||||
int channelCount = m_outputFormat.channelCount();
|
||||
qint64 count = maxlen / (sampleBytes * channelCount);
|
||||
QVector<qint16> buffer;
|
||||
QVector<float> buffer;
|
||||
m_sampleProvider->readSamples(buffer, count);
|
||||
|
||||
for (const qint16 sample : buffer)
|
||||
for (float sample : buffer)
|
||||
{
|
||||
qint16 sampleInput = sample;
|
||||
sampleInput = qAbs(sampleInput);
|
||||
if (sampleInput > m_maxSampleOutput) { m_maxSampleOutput = sampleInput; }
|
||||
float absSample = qAbs(sample);
|
||||
if (absSample > m_maxSampleOutput) { m_maxSampleOutput = absSample; }
|
||||
}
|
||||
|
||||
m_sampleCount += buffer.size();
|
||||
if (m_sampleCount >= SampleCountPerEvent)
|
||||
{
|
||||
OutputVolumeStreamArgs outputVolumeStreamArgs;
|
||||
qint16 maxInt = std::numeric_limits<qint16>::max();
|
||||
outputVolumeStreamArgs.PeakRaw = m_maxSampleOutput / maxInt;
|
||||
outputVolumeStreamArgs.PeakRaw = m_maxSampleOutput / 1.0;
|
||||
outputVolumeStreamArgs.PeakDB = static_cast<float>(20 * std::log10(outputVolumeStreamArgs.PeakRaw));
|
||||
const double db = qBound(m_minDb, outputVolumeStreamArgs.PeakDB, m_maxDb);
|
||||
double ratio = (db - m_minDb) / (m_maxDb - m_minDb);
|
||||
@@ -91,8 +89,8 @@ namespace BlackCore
|
||||
QAudioFormat outputFormat;
|
||||
outputFormat.setSampleRate(48000);
|
||||
outputFormat.setChannelCount(1);
|
||||
outputFormat.setSampleSize(16);
|
||||
outputFormat.setSampleType(QAudioFormat::SignedInt);
|
||||
outputFormat.setSampleSize(32);
|
||||
outputFormat.setSampleType(QAudioFormat::Float);
|
||||
outputFormat.setByteOrder(QAudioFormat::LittleEndian);
|
||||
outputFormat.setCodec("audio/pcm");
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace BlackCore
|
||||
|
||||
static constexpr int SampleCountPerEvent = 4800;
|
||||
QAudioFormat m_outputFormat;
|
||||
double m_maxSampleOutput = 0;
|
||||
float m_maxSampleOutput = 0.0;
|
||||
int m_sampleCount = 0;
|
||||
const double m_maxDb = 0;
|
||||
const double m_minDb = -40;
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace BlackCore
|
||||
}
|
||||
}
|
||||
|
||||
int CReceiverSampleProvider::readSamples(QVector<qint16> &samples, qint64 count)
|
||||
int CReceiverSampleProvider::readSamples(QVector<float> &samples, qint64 count)
|
||||
{
|
||||
int numberOfInUseInputs = activeCallsigns();
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace BlackCore
|
||||
//! @}
|
||||
|
||||
//! \copydoc BlackSound::SampleProvider::ISampleProvider::readSamples
|
||||
virtual int readSamples(QVector<qint16> &samples, qint64 count) override;
|
||||
virtual int readSamples(QVector<float> &samples, qint64 count) override;
|
||||
|
||||
void addOpusSamples(const IAudioDto &audioDto, uint frequency, float distanceRatio);
|
||||
void addSilentSamples(const IAudioDto &audioDto, uint frequency, float distanceRatio);
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace BlackCore
|
||||
}
|
||||
}
|
||||
|
||||
int CSoundcardSampleProvider::readSamples(QVector<qint16> &samples, qint64 count)
|
||||
int CSoundcardSampleProvider::readSamples(QVector<float> &samples, qint64 count)
|
||||
{
|
||||
return m_mixer->readSamples(samples, count);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace BlackCore
|
||||
void pttUpdate(bool active, const QVector<TxTransceiverDto> &txTransceivers);
|
||||
|
||||
//! \copydoc ISampleProvider::readSamples
|
||||
virtual int readSamples(QVector<qint16> &samples, qint64 count) override;
|
||||
virtual int readSamples(QVector<float> &samples, qint64 count) override;
|
||||
|
||||
//! Add OPUS samples
|
||||
void addOpusSamples(const IAudioDto &audioDto, const QVector<RxTransceiverDto> &rxTransceivers);
|
||||
|
||||
Reference in New Issue
Block a user