[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:
Roland Rossgotterer
2019-10-01 11:58:02 +02:00
committed by Mat Sutcliffe
parent fbb126370c
commit 240df93406
29 changed files with 77 additions and 80 deletions

View File

@@ -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();

View File

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

View File

@@ -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");

View File

@@ -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;

View File

@@ -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();

View File

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

View File

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

View File

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