NFMDemodSink: Proper audio scaling to 16-bit

pull/685/head
Kacper Michajłow 2020-11-03 14:40:14 +01:00 zatwierdzone przez f4exb
rodzic 1e5ae8ea0f
commit 00ba5115f3
5 zmienionych plików z 22 dodań i 61 usunięć

Wyświetl plik

@ -27,6 +27,7 @@
#include "dsp/dspengine.h"
#include "dsp/dspcommands.h"
#include "dsp/devicesamplemimo.h"
#include "dsp/misc.h"
#include "device/deviceapi.h"
#include "nfmdemodreport.h"
@ -58,6 +59,7 @@ NFMDemodSink::NFMDemodSink() :
{
m_agcLevel = 1.0;
m_audioBuffer.resize(1<<16);
m_phaseDiscri.setFMScaling(1.0f);
applySettings(m_settings, true);
applyChannelSettings(m_channelSampleRate, m_channelFrequencyOffset, true);
@ -174,9 +176,11 @@ void NFMDemodSink::processOneSample(Complex &ci)
if (!m_settings.m_audioMute && (m_settings.m_ctcssOn && m_ctcssIndexSelected == ctcssIndex || m_ctcssIndexSelected == 0))
{
Real audioSample = m_squelchDelayLine.readBack(m_squelchGate);
Q_ASSERT(audioSample >= -1.0f && audioSample <= 1.0f);
audioSample = m_settings.m_highPass ? m_bandpass.filter(audioSample) : m_lowpass.filter(audioSample);
audioSample *= m_settings.m_volume * m_filterTaps;
sample = std::lrint(audioSample);
audioSample *= m_settings.m_volume * std::numeric_limits<int16_t>::max();
sample = clamp<float>(std::rint(audioSample), std::numeric_limits<int16_t>::lowest(), std::numeric_limits<int16_t>::max());
}
}
@ -258,11 +262,6 @@ void NFMDemodSink::applySettings(const NFMDemodSettings& settings, bool force)
m_interpolatorDistance = (Real) m_channelSampleRate / (Real) m_audioSampleRate;
}
if ((settings.m_fmDeviation != m_settings.m_fmDeviation) || force)
{
m_phaseDiscri.setFMScaling((8.0f*m_audioSampleRate) / static_cast<float>(settings.m_fmDeviation)); // integrate 4x factor
}
if ((settings.m_afBandwidth != m_settings.m_afBandwidth) || force)
{
m_bandpass.create(m_filterTaps, m_audioSampleRate, 300.0, settings.m_afBandwidth);
@ -324,7 +323,6 @@ void NFMDemodSink::applyAudioSampleRate(unsigned int sampleRate)
m_afSquelch.setCoefficients(sampleRate/2000, 600, sampleRate, 200, 0, afSqTones); // 0.5ms test period, 300ms average span, audio SR, 100ms attack, no decay
}
m_phaseDiscri.setFMScaling((8.0f*sampleRate) / static_cast<float>(m_settings.m_fmDeviation)); // integrate 4x factor
m_audioFifo.setSize(sampleRate);
m_squelchDelayLine.resize(sampleRate/2);
m_interpolatorDistanceRemain = 0;

Wyświetl plik

@ -139,39 +139,6 @@ private:
void processOneSample(Complex &ci);
MessageQueue *getMessageQueueToGUI() { return m_messageQueueToGUI; }
inline float arctan2(Real y, Real x)
{
Real coeff_1 = M_PI / 4;
Real coeff_2 = 3 * coeff_1;
Real abs_y = fabs(y) + 1e-10; // kludge to prevent 0/0 condition
Real angle;
if( x>= 0) {
Real r = (x - abs_y) / (x + abs_y);
angle = coeff_1 - coeff_1 * r;
} else {
Real r = (x + abs_y) / (abs_y - x);
angle = coeff_2 - coeff_1 * r;
}
if(y < 0) {
return(-angle);
} else {
return(angle);
}
}
inline Real angleDist(Real a, Real b)
{
Real dist = b - a;
while(dist <= M_PI)
dist += 2 * M_PI;
while(dist >= M_PI)
dist -= 2 * M_PI;
return dist;
}
};
#endif // INCLUDE_NFMDEMODSINK_H

Wyświetl plik

@ -52,6 +52,19 @@ void generateLowPassFilter(int nTaps, double sampleRate, double cutoff, std::vec
int n = i - (nTaps - 1) / 2;
taps[i] *= 0.42 + 0.5 * cos((2.0 * M_PI * n) / nTaps) + 0.08 * cos((4.0 * M_PI * n) / nTaps);
}
Real sum = 0;
size_t i;
for (i = 0; i < taps.size() - 1; ++i) {
sum += taps[i] * 2.0;
}
sum += taps[i];
for (i = 0; i < taps.size(); ++i) {
taps[i] /= sum;
}
}
}

Wyświetl plik

@ -20,6 +20,7 @@
#include <cmath>
#include "dsp/dsptypes.h"
#include "dsp/misc.h"
#include "export.h"
namespace FirFilterGenerators
@ -74,22 +75,6 @@ protected:
}
}
void normalize(Real sum_fix = 0.0)
{
Real sum = 0;
size_t i;
for (i = 0; i < m_taps.size() - 1; ++i) {
sum += m_taps[i] * 2.0;
}
sum += m_taps[i] + sum_fix;
for (i = 0; i < m_taps.size(); ++i) {
m_taps[i] /= sum;
}
}
protected:
std::vector<Real> m_taps;
std::vector<Type> m_samples;
@ -104,7 +89,6 @@ public:
{
this->init(nTaps);
FirFilterGenerators::generateLowPassFilter(nTaps, sampleRate, cutoff, this->m_taps);
this->normalize();
}
};
@ -129,7 +113,6 @@ struct Bandpass : public FirFilter<T>
}
this->m_taps[this->m_taps.size() - 1] += 1;
this->normalize(-1.0);
}
};
@ -146,6 +129,5 @@ struct Highpass : public FirFilter<T>
}
this->m_taps[this->m_taps.size() - 1] += 1;
this->normalize(-1.0);
}
};

Wyświetl plik

@ -36,7 +36,8 @@ inline float cosc(float x)
return (fabs(x) < 1e-10) ? 0.0 : ((1.0 - cos(M_PI * x)) / (M_PI * x));
}
inline float clamp(float x, float min, float max)
template<typename T>
inline T clamp(T x, T min, T max)
{
return (x < min) ? min : ((x > max) ? max : x);
}