1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-26 09:48:45 -05:00

UDPSink plugin: implemented VU level meter

This commit is contained in:
f4exb 2017-08-16 23:37:01 +02:00
parent 50e466c4fe
commit 66a81ec611
3 changed files with 67 additions and 1 deletions

View File

@ -28,12 +28,16 @@ UDPSink::UDPSink(MessageQueue* uiMessageQueue, UDPSinkGUI* udpSinkGUI, BasebandS
m_udpSinkGUI(udpSinkGUI),
m_spectrum(spectrum),
m_spectrumEnabled(false),
m_spectrumChunkSize(2400),
m_spectrumChunkSize(2160),
m_spectrumChunkCounter(0),
m_magsq(1e-10),
m_movingAverage(16, 0),
m_sampleRateSum(0),
m_sampleRateAvgCounter(0),
m_levelCalcCount(0),
m_peakLevel(0.0f),
m_levelSum(0.0f),
m_levelNbSamples(480),
m_settingsMutex(QMutex::Recursive)
{
setObjectName("UDPSink");
@ -110,11 +114,13 @@ void UDPSink::modulateSample()
m_udpHandler.readSample(s);
m_modSample.real(s.m_real);
m_modSample.imag(s.m_imag);
calculateLevel(m_modSample);
}
else
{
m_modSample.real(0.0f);
m_modSample.imag(0.0f);
calculateLevel(1e-10);
}
if (m_spectrum && m_spectrumEnabled && (m_spectrumChunkCounter < m_spectrumChunkSize - 1))
@ -133,6 +139,45 @@ void UDPSink::modulateSample()
}
}
void UDPSink::calculateLevel(Real sample)
{
if (m_levelCalcCount < m_levelNbSamples)
{
m_peakLevel = std::max(std::fabs(m_peakLevel), sample);
m_levelSum += sample * sample;
m_levelCalcCount++;
}
else
{
qreal rmsLevel = sqrt(m_levelSum / m_levelNbSamples);
//qDebug("NFMMod::calculateLevel: %f %f", rmsLevel, m_peakLevel);
emit levelChanged(rmsLevel, m_peakLevel, m_levelNbSamples);
m_peakLevel = 0.0f;
m_levelSum = 0.0f;
m_levelCalcCount = 0;
}
}
void UDPSink::calculateLevel(Complex sample)
{
Real t = std::abs(sample);
if (m_levelCalcCount < m_levelNbSamples)
{
m_peakLevel = std::max(std::fabs(m_peakLevel), t);
m_levelSum += (t * t);
m_levelCalcCount++;
}
else
{
qreal rmsLevel = sqrt((m_levelSum/(1<<30)) / m_levelNbSamples);
emit levelChanged(rmsLevel, m_peakLevel / 32768.0, m_levelNbSamples);
m_peakLevel = 0.0f;
m_levelSum = 0.0f;
m_levelCalcCount = 0;
}
}
bool UDPSink::handleMessage(const Message& cmd)
{
if (UpChannelizer::MsgChannelizerNotification::match(cmd))
@ -303,6 +348,10 @@ void UDPSink::apply(bool force)
m_sampleRateAvgCounter = 0;
m_spectrumChunkSize = m_config.m_inputSampleRate * 0.05; // 50 ms chunk
m_spectrumChunkCounter = 0;
m_levelNbSamples = m_config.m_inputSampleRate * 0.01; // every 10 ms
m_levelCalcCount = 0;
m_peakLevel = 0.0f;
m_levelSum = 0.0f;
m_settingsMutex.unlock();
}

View File

@ -68,6 +68,15 @@ public:
bool force = false);
void setSpectrum(MessageQueue* messageQueue, bool enabled);
signals:
/**
* Level changed
* \param rmsLevel RMS level in range 0.0 - 1.0
* \param peakLevel Peak level in range 0.0 - 1.0
* \param numSamples Number of audio samples analyzed
*/
void levelChanged(qreal rmsLevel, qreal peakLevel, int numSamples);
private:
class MsgUDPSinkConfigure : public Message {
MESSAGE_CLASS_DECLARATION
@ -206,12 +215,19 @@ private:
double m_sampleRateSum;
int m_sampleRateAvgCounter;
int m_levelCalcCount;
Real m_peakLevel;
double m_levelSum;
int m_levelNbSamples;
QMutex m_settingsMutex;
static const int m_sampleRateAverageItems = 17;
void apply(bool force);
void modulateSample();
void calculateLevel(Real sample);
void calculateLevel(Complex sample);
};

View File

@ -260,6 +260,7 @@ UDPSinkGUI::UDPSinkGUI(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI, QWidget*
applySettings(true);
connect(m_udpSink->getOutputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleSourceMessages()));
connect(m_udpSink, SIGNAL(levelChanged(qreal, qreal, int)), ui->volumeMeter, SLOT(levelChanged(qreal, qreal, int)));
}
UDPSinkGUI::~UDPSinkGUI()