diff --git a/plugins/feature/denoiser/denoiserplugin.cpp b/plugins/feature/denoiser/denoiserplugin.cpp index 198d4feb8..4e46e1092 100644 --- a/plugins/feature/denoiser/denoiserplugin.cpp +++ b/plugins/feature/denoiser/denoiserplugin.cpp @@ -27,7 +27,7 @@ const PluginDescriptor DenoiserPlugin::m_pluginDescriptor = { Denoiser::m_featureId, QStringLiteral("Denoiser"), - QStringLiteral("7.23.0"), + QStringLiteral("7.22.11"), QStringLiteral("(c) Edouard Griffiths, F4EXB"), QStringLiteral("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/feature/denoiser/denoiserworker.cpp b/plugins/feature/denoiser/denoiserworker.cpp index 7ba4727ef..a22821f8d 100644 --- a/plugins/feature/denoiser/denoiserworker.cpp +++ b/plugins/feature/denoiser/denoiserworker.cpp @@ -333,158 +333,183 @@ void DenoiserWorker::processSample( int i ) { - // Periodic debug to verify runtime settings and branch selection - // static uint32_t s_dbgCount = 0; - // if ((s_dbgCount++ % 48000) == 0) { // approx. once per second at 48 kS/s - // qDebug() << "DenoiserWorker::processSample: dataType=" << (int)dataType - // << " enable=" << m_settings.m_enableDenoiser - // << " type=" << static_cast(m_settings.m_denoiserType); - // } - switch(dataType) { - case DataFifo::DataTypeI16: { + case DataFifo::DataTypeI16: + { int16_t *s = (int16_t*) begin; - double re = s[i] / (double) std::numeric_limits::max(); - calculateLevel(re * (m_settings.m_volumeTenths / 10.0)); + double samplefp = s[i] * (m_settings.m_volumeTenths / 10.0); + double re = samplefp / (double) std::numeric_limits::max(); + calculateLevel(re); m_magsq = re*re; m_channelPowerAvg(m_magsq); - if ((!m_settings.m_enableDenoiser || m_settings.m_denoiserType == DenoiserSettings::DenoiserType::DenoiserType_None) && !m_settings.m_audioMute) - { - // if ((s_dbgCount % 48000) == 1) { - // qDebug() << "DenoiserWorker::processSample[I16]: passthrough branch"; - // } - m_sampleBuffer.push_back(Sample(re * SDR_RX_SCALEF, 0)); - m_audioBuffer[m_audioBufferFill].l = static_cast(s[i]*(m_settings.m_volumeTenths / 10.0f)); - m_audioBuffer[m_audioBufferFill].r = static_cast(s[i]*(m_settings.m_volumeTenths / 10.0f)); - ++m_audioBufferFill; - - if (m_audioBufferFill >= m_audioBuffer.size()) - { - std::size_t res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill); - if (res != m_audioBufferFill) - { - qDebug("DenoiserWorker::processSample: %lu/%lu audio samples written", res, m_audioBufferFill); - m_audioFifo.clear(); - } - m_audioBufferFill = 0; - } + if ((!m_settings.m_enableDenoiser || m_settings.m_denoiserType == DenoiserSettings::DenoiserType::DenoiserType_None) && !m_settings.m_audioMute) { + processI16DenoiserNone(samplefp); } - else if ((m_settings.m_denoiserType == DenoiserSettings::DenoiserType::DenoiserType_RNnoise) && !m_settings.m_audioMute) - { - // if ((s_dbgCount % 48000) == 1) { - // qDebug() << "DenoiserWorker::processSample[I16]: RNNoise branch"; - // } - // feed RNNoise input buffer - m_rnnoiseIn[m_rnnoiseFill] = static_cast(s[i])*(m_settings.m_volumeTenths / 10.0f); // already in [-32768..32767] range - m_rnnoiseFill++; - - if (m_rnnoiseFill >= 480) - { - // process RNNoise frame - rnnoise_process_frame(m_rnnoiseState, m_rnnoiseOut, m_rnnoiseIn); - - // output RNNoise processed samples - for (int j = 0; j < 480; j++) - { - float outSample = m_rnnoiseOut[j]; - m_sampleBuffer.push_back(Sample(outSample * 181, 0)); // 181 = sqrt(32768) - int16_t audioSample = static_cast(outSample); - m_audioBuffer[m_audioBufferFill].l = audioSample; - m_audioBuffer[m_audioBufferFill].r = audioSample; - ++m_audioBufferFill; - - if (m_audioBufferFill >= m_audioBuffer.size()) - { - std::size_t res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill); - if (res != m_audioBufferFill) - { - qDebug("DenoiserWorker::processSample: %lu/%lu audio samples written", res, m_audioBufferFill); - m_audioFifo.clear(); - } - m_audioBufferFill = 0; - } - } - - m_rnnoiseFill = 0; - } + else if ((m_settings.m_denoiserType == DenoiserSettings::DenoiserType::DenoiserType_RNnoise) && !m_settings.m_audioMute) { + processI16DenoiserRNNoise(samplefp); } } break; - case DataFifo::DataTypeCI16: { + case DataFifo::DataTypeCI16: + { int16_t *s = (int16_t*) begin; - double re = s[2*i] / (double) std::numeric_limits::max(); - double im = s[2*i+1] / (double) std::numeric_limits::max(); - calculateLevel((re + im) * (m_settings.m_volumeTenths / 20.0)); + double samplefpRe = s[2*i] * (m_settings.m_volumeTenths / 10.0); + double samplefpIm = s[2*i+1] * (m_settings.m_volumeTenths / 10.0); + double re = samplefpRe / (double) std::numeric_limits::max(); + double im = samplefpIm / (double) std::numeric_limits::max(); + calculateLevel((re + im) / 2.0); m_magsq = re*re + im*im; m_channelPowerAvg(m_magsq); - if ((!m_settings.m_enableDenoiser || m_settings.m_denoiserType == DenoiserSettings::DenoiserType::DenoiserType_None) && !m_settings.m_audioMute) - { - // if ((s_dbgCount % 48000) == 1) { - // qDebug() << "DenoiserWorker::processSample[CI16]: passthrough branch"; - // } - m_sampleBuffer.push_back(Sample(re * SDR_RX_SCALEF, im * SDR_RX_SCALEF)); - m_audioBuffer[m_audioBufferFill].l = static_cast(s[2*i]*(m_settings.m_volumeTenths / 10.0f)); - m_audioBuffer[m_audioBufferFill].r = static_cast(s[2*i+1]*(m_settings.m_volumeTenths / 10.0f)); - ++m_audioBufferFill; - - if (m_audioBufferFill >= m_audioBuffer.size()) - { - std::size_t res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill); - if (res != m_audioBufferFill) - { - qDebug("DenoiserWorker::processSample: %lu/%lu audio samples written", res, m_audioBufferFill); - m_audioFifo.clear(); - } - m_audioBufferFill = 0; - } + if ((!m_settings.m_enableDenoiser || m_settings.m_denoiserType == DenoiserSettings::DenoiserType::DenoiserType_None) && !m_settings.m_audioMute) { + processCI16DenoiserNone(samplefpRe, samplefpIm); } - else if ((m_settings.m_denoiserType == DenoiserSettings::DenoiserType::DenoiserType_RNnoise) && !m_settings.m_audioMute) - { - // if ((s_dbgCount % 48000) == 1) { - // qDebug() << "DenoiserWorker::processSample[CI16]: RNNoise branch"; - // } - // feed RNNoise input buffer - m_rnnoiseIn[m_rnnoiseFill] = static_cast(s[2*i] + s[2*i+1]) * (m_settings.m_volumeTenths / 20.0f); // average I/Q in [-32768..32767] range - m_rnnoiseFill++; - - if (m_rnnoiseFill >= 480) - { - // process RNNoise frame - rnnoise_process_frame(m_rnnoiseState, m_rnnoiseOut, m_rnnoiseIn); - - // output RNNoise processed samples - for (int j = 0; j < 480; j++) - { - float outSample = m_rnnoiseOut[j]; - m_sampleBuffer.push_back(Sample(outSample * 181, outSample * 181)); // 181 = sqrt(32768) - int16_t audioSample = static_cast(outSample); - m_audioBuffer[m_audioBufferFill].l = audioSample; - m_audioBuffer[m_audioBufferFill].r = audioSample; - ++m_audioBufferFill; - - if (m_audioBufferFill >= m_audioBuffer.size()) - { - std::size_t res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill); - if (res != m_audioBufferFill) - { - qDebug("DenoiserWorker::processSample: %lu/%lu audio samples written", res, m_audioBufferFill); - m_audioFifo.clear(); - } - m_audioBufferFill = 0; - } - } - - m_rnnoiseFill = 0; - } + else if ((m_settings.m_denoiserType == DenoiserSettings::DenoiserType::DenoiserType_RNnoise) && !m_settings.m_audioMute) { + processCI16DenoiserRNNoise(samplefpRe, samplefpIm); } } break; } } +void DenoiserWorker::processI16DenoiserNone(const double& samplefp) +{ + if (m_channelPowerAvg.asDouble() > 1e-4) { // -40 dB threshold + m_sampleBuffer.push_back(Sample(samplefp, 0)); + } + + m_audioBuffer[m_audioBufferFill].l = static_cast(samplefp); + m_audioBuffer[m_audioBufferFill].r = static_cast(samplefp); + ++m_audioBufferFill; + + if (m_audioBufferFill >= m_audioBuffer.size()) + { + std::size_t res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill); + + if (res != m_audioBufferFill) + { + qDebug("DenoiserWorker::processSample: %lu/%lu audio samples written", res, m_audioBufferFill); + m_audioFifo.clear(); + } + + m_audioBufferFill = 0; + } +} + +void DenoiserWorker::processI16DenoiserRNNoise(const double& samplefp) +{ + // feed RNNoise input buffer + m_rnnoiseIn[m_rnnoiseFill] = static_cast(samplefp); // already in [-32768..32767] range + m_rnnoiseFill++; + + if (m_rnnoiseFill >= 480) + { + // process RNNoise frame + rnnoise_process_frame(m_rnnoiseState, m_rnnoiseOut, m_rnnoiseIn); + + // output RNNoise processed samples + for (int j = 0; j < 480; j++) + { + float outSample = m_rnnoiseOut[j]; + + if (m_channelPowerAvg.asDouble() > 1e-4) { // -40 dB threshold + m_sampleBuffer.push_back(Sample(outSample * 181, 0)); // 181 = sqrt(32768) + } + + int16_t audioSample = static_cast(outSample); + m_audioBuffer[m_audioBufferFill].l = audioSample; + m_audioBuffer[m_audioBufferFill].r = audioSample; + ++m_audioBufferFill; + + if (m_audioBufferFill >= m_audioBuffer.size()) + { + std::size_t res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill); + + if (res != m_audioBufferFill) + { + qDebug("DenoiserWorker::processSample: %lu/%lu audio samples written", res, m_audioBufferFill); + m_audioFifo.clear(); + } + + m_audioBufferFill = 0; + } + } + + m_rnnoiseFill = 0; + } +} + +void DenoiserWorker::processCI16DenoiserNone(const double& samplefpRe, const double& samplefpIm) +{ + if (m_channelPowerAvg.asDouble() > 1e-4) { // -40 dB threshold + m_sampleBuffer.push_back(Sample(samplefpRe, samplefpIm)); + } + + m_audioBuffer[m_audioBufferFill].l = static_cast(samplefpRe); + m_audioBuffer[m_audioBufferFill].r = static_cast(samplefpIm); + ++m_audioBufferFill; + + if (m_audioBufferFill >= m_audioBuffer.size()) + { + std::size_t res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill); + + if (res != m_audioBufferFill) + { + qDebug("DenoiserWorker::processSample: %lu/%lu audio samples written", res, m_audioBufferFill); + m_audioFifo.clear(); + } + + m_audioBufferFill = 0; + } +} + +void DenoiserWorker::processCI16DenoiserRNNoise(const double& samplefpRe, const double& samplefpIm) +{ + Q_UNUSED(samplefpRe); + Q_UNUSED(samplefpIm); + // feed RNNoise input buffer + m_rnnoiseIn[m_rnnoiseFill] = static_cast((samplefpRe + samplefpIm) / 2.0f); // average I/Q in [-32768..32767] range + m_rnnoiseFill++; + + if (m_rnnoiseFill >= 480) + { + // process RNNoise frame + rnnoise_process_frame(m_rnnoiseState, m_rnnoiseOut, m_rnnoiseIn); + + // output RNNoise processed samples + for (int j = 0; j < 480; j++) + { + float outSample = m_rnnoiseOut[j]; + + if (m_channelPowerAvg.asDouble() > 1e-4) { // -40 dB threshold + m_sampleBuffer.push_back(Sample(outSample * 181, outSample * 181)); // 181 = sqrt(32768) + } + + int16_t audioSample = static_cast(outSample); + m_audioBuffer[m_audioBufferFill].l = audioSample; + m_audioBuffer[m_audioBufferFill].r = audioSample; + ++m_audioBufferFill; + + if (m_audioBufferFill >= m_audioBuffer.size()) + { + std::size_t res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill); + + if (res != m_audioBufferFill) + { + qDebug("DenoiserWorker::processSample: %lu/%lu audio samples written", res, m_audioBufferFill); + m_audioFifo.clear(); + } + + m_audioBufferFill = 0; + } + } + + m_rnnoiseFill = 0; + } +} + void DenoiserWorker::calculateLevel(const Real& sample) { if (m_levelCalcCount < m_levelNbSamples) diff --git a/plugins/feature/denoiser/denoiserworker.h b/plugins/feature/denoiser/denoiserworker.h index f72eca8dc..40a658799 100644 --- a/plugins/feature/denoiser/denoiserworker.h +++ b/plugins/feature/denoiser/denoiserworker.h @@ -150,6 +150,10 @@ private: const QByteArray::const_iterator& begin, int i ); + void processI16DenoiserNone(const double& samplefp); + void processI16DenoiserRNNoise(const double& samplefp); + void processCI16DenoiserNone(const double& samplefpRe, const double& samplefpIm); + void processCI16DenoiserRNNoise(const double& samplefpRe, const double& samplefpIm); void calculateLevel(const Real& sample); private slots: