diff --git a/plugins/channelrx/demodam/amdemodsink.cpp b/plugins/channelrx/demodam/amdemodsink.cpp index 64353f7ca..c09c47092 100644 --- a/plugins/channelrx/demodam/amdemodsink.cpp +++ b/plugins/channelrx/demodam/amdemodsink.cpp @@ -189,7 +189,6 @@ void AMDemodSink::processOneSample(Complex &ci) if (m_settings.m_bandpassEnable) { demod = m_bandpass.filter(demod); - demod /= 301.0f; } else { diff --git a/plugins/channelrx/demodnfm/nfmdemodsink.cpp b/plugins/channelrx/demodnfm/nfmdemodsink.cpp index a1f8bc245..ba4216ddc 100644 --- a/plugins/channelrx/demodnfm/nfmdemodsink.cpp +++ b/plugins/channelrx/demodnfm/nfmdemodsink.cpp @@ -121,7 +121,7 @@ void NFMDemodSink::processOneSample(Complex &ci) if (m_settings.m_deltaSquelch) { - if (m_afSquelch.analyze(demod * m_discriCompensation)) + if (m_afSquelch.analyze(demod)) { m_afSquelchOpen = m_afSquelch.evaluate(); // ? m_squelchGate + m_squelchDecay : 0; @@ -132,7 +132,7 @@ void NFMDemodSink::processOneSample(Complex &ci) if (m_afSquelchOpen) { - m_squelchDelayLine.write(demod * m_discriCompensation); + m_squelchDelayLine.write(demod); if (m_squelchCount < 2*m_squelchGate) { m_squelchCount++; @@ -159,7 +159,7 @@ void NFMDemodSink::processOneSample(Complex &ci) } else { - m_squelchDelayLine.write(demod * m_discriCompensation); + m_squelchDelayLine.write(demod); if (m_squelchCount < 2*m_squelchGate) { m_squelchCount++; @@ -179,7 +179,7 @@ void NFMDemodSink::processOneSample(Complex &ci) { if (m_settings.m_ctcssOn) { - Real ctcss_sample = m_ctcssLowpass.filter(demod * m_discriCompensation); + Real ctcss_sample = m_ctcssLowpass.filter(demod); if ((m_sampleCount & 7) == 7) // decimate 48k -> 6k { @@ -224,7 +224,7 @@ void NFMDemodSink::processOneSample(Complex &ci) else { if (m_settings.m_highPass) { - sample = m_bandpass.filter(m_squelchDelayLine.readBack(m_squelchGate)) * m_settings.m_volume; + sample = m_bandpass.filter(m_squelchDelayLine.readBack(m_squelchGate)) * m_settings.m_volume * 301.0f; } else { sample = m_lowpass.filter(m_squelchDelayLine.readBack(m_squelchGate)) * m_settings.m_volume * 301.0f; } @@ -375,17 +375,13 @@ void NFMDemodSink::applyAudioSampleRate(unsigned int sampleRate) if (sampleRate < 16000) { m_afSquelch.setCoefficients(sampleRate/2000, 600, sampleRate, 200, 0, afSqTones_lowrate); // 0.5ms test period, 300ms average span, audio SR, 100ms attack, no decay - } else { m_afSquelch.setCoefficients(sampleRate/2000, 600, sampleRate, 200, 0, afSqTones); // 0.5ms test period, 300ms average span, audio SR, 100ms attack, no decay } - m_discriCompensation = (sampleRate/48000.0f); - m_discriCompensation *= sqrt(m_discriCompensation); - m_phaseDiscri.setFMScaling((8.0f*sampleRate) / static_cast(m_settings.m_fmDeviation)); // integrate 4x factor m_audioFifo.setSize(sampleRate); m_squelchDelayLine.resize(sampleRate/2); m_audioSampleRate = sampleRate; -} \ No newline at end of file +} diff --git a/plugins/channelrx/demodnfm/nfmdemodsink.h b/plugins/channelrx/demodnfm/nfmdemodsink.h index 70684a0b1..952603464 100644 --- a/plugins/channelrx/demodnfm/nfmdemodsink.h +++ b/plugins/channelrx/demodnfm/nfmdemodsink.h @@ -104,8 +104,6 @@ private: uint m_audioBufferFill; AudioFifo m_audioFifo; - float m_discriCompensation; //!< compensation factor that depends on audio rate (1 for 48 kS/s) - NCO m_nco; Interpolator m_interpolator; Real m_interpolatorDistance; diff --git a/plugins/channelrx/udpsink/udpsinksink.cpp b/plugins/channelrx/udpsink/udpsinksink.cpp index fa0dede04..d8f3eea5f 100644 --- a/plugins/channelrx/udpsink/udpsinksink.cpp +++ b/plugins/channelrx/udpsink/udpsinksink.cpp @@ -256,7 +256,6 @@ void UDPSinkSink::feed(const SampleVector::const_iterator& begin, const SampleVe { double demodf = sqrt(inMagSq); demodf = m_bandpass.filter(demodf); - demodf /= 301.0; Real amplitude = demodf * agcFactor * m_settings.m_gain; FixReal demod = (FixReal) amplitude; udpWriteMono(demod); diff --git a/plugins/channeltx/modnfm/nfmmodsource.cpp b/plugins/channeltx/modnfm/nfmmodsource.cpp index d3731ffe7..bc0d5e0c1 100644 --- a/plugins/channeltx/modnfm/nfmmodsource.cpp +++ b/plugins/channeltx/modnfm/nfmmodsource.cpp @@ -134,14 +134,11 @@ void NFMModSource::modulateSample() calculateLevel(t); m_audioBufferFill++; - if (m_settings.m_ctcssOn) - { - m_modPhasor += (m_settings.m_fmDeviation / (float) m_audioSampleRate) * (0.85f * m_bandpass.filter(t) + 0.15f * 189.0f * m_ctcssNco.next()) * (M_PI / 189.0f); - } - else - { - // 378 = 302 * 1.25; 302 = number of filter taps (established experimentally) and 189 = 378/2 for 2*PI - m_modPhasor += (m_settings.m_fmDeviation / (float) m_audioSampleRate) * m_bandpass.filter(t) * (M_PI / 189.0f); + // 0.625 = 1/1.25 (heuristic) + if (m_settings.m_ctcssOn) { + m_modPhasor += (m_settings.m_fmDeviation / (float) m_audioSampleRate) * (0.85f * m_bandpass.filter(t) + 0.15f * 0.625f * m_ctcssNco.next()) * (M_PI / 0.625f); + } else { + m_modPhasor += (m_settings.m_fmDeviation / (float) m_audioSampleRate) * m_bandpass.filter(t) * (M_PI / 0.625f); } // limit phasor range to ]-pi,pi] @@ -368,4 +365,4 @@ void NFMModSource::applyChannelSettings(int channelSampleRate, int channelFreque m_channelSampleRate = channelSampleRate; m_channelFrequencyOffset = channelFrequencyOffset; -} \ No newline at end of file +} diff --git a/sdrbase/dsp/bandpass.h b/sdrbase/dsp/bandpass.h index f46489fd7..658ede7c0 100644 --- a/sdrbase/dsp/bandpass.h +++ b/sdrbase/dsp/bandpass.h @@ -23,27 +23,34 @@ public: int i; // check constraints - if(!(nTaps & 1)) { + if (!(nTaps & 1)) + { qDebug("Bandpass filter has to have an odd number of taps"); nTaps++; } // make room m_samples.resize(nTaps); - for(int i = 0; i < nTaps; i++) + + for (int i = 0; i < nTaps; i++) { m_samples[i] = 0; + } + m_ptr = 0; m_taps.resize(nTaps / 2 + 1); taps_lp.resize(nTaps / 2 + 1); taps_hp.resize(nTaps / 2 + 1); // generate Sinc filter core - for(i = 0; i < nTaps / 2 + 1; i++) { - if(i == (nTaps - 1) / 2) { + for (i = 0; i < nTaps / 2 + 1; i++) + { + if (i == (nTaps - 1) / 2) + { taps_lp[i] = Wch / M_PI; taps_hp[i] = -(Wcl / M_PI); } - else { + else + { taps_lp[i] = sin(((double)i - ((double)nTaps - 1.0) / 2.0) * Wch) / (((double)i - ((double)nTaps - 1.0) / 2.0) * M_PI); taps_hp[i] = -sin(((double)i - ((double)nTaps - 1.0) / 2.0) * Wcl) / (((double)i - ((double)nTaps - 1.0) / 2.0) * M_PI); } @@ -52,7 +59,8 @@ public: taps_hp[(nTaps - 1) / 2] += 1; // apply Hamming window and combine lowpass and highpass - for(i = 0; i < nTaps / 2 + 1; i++) { + for (i = 0; i < nTaps / 2 + 1; i++) + { taps_lp[i] *= 0.54 + 0.46 * cos((2.0 * M_PI * ((double)i - ((double)nTaps - 1.0) / 2.0)) / (double)nTaps); taps_hp[i] *= 0.54 + 0.46 * cos((2.0 * M_PI * ((double)i - ((double)nTaps - 1.0) / 2.0)) / (double)nTaps); m_taps[i] = -(taps_lp[i]+taps_hp[i]); @@ -63,13 +71,13 @@ public: // normalize Real sum = 0; - for(i = 0; i < (int)m_taps.size() - 1; i++) { + for (i = 0; i < (int)m_taps.size() - 1; i++) { sum += m_taps[i] * 2; } - sum += m_taps[i]; + sum += m_taps[i] - 1; - for(i = 0; i < (int)m_taps.size(); i++) { + for (i = 0; i < (int)m_taps.size(); i++) { m_taps[i] /= sum; } } @@ -84,8 +92,7 @@ public: m_samples[m_ptr] = sample; size = m_samples.size(); // Valgrind optim (2) - while(b < 0) - { + while (b < 0) { b += size; } @@ -96,15 +103,13 @@ public: acc += (m_samples[a] + m_samples[b]) * m_taps[i]; a++; - while (a >= size) - { + while (a >= size) { a -= size; } b--; - while(b < 0) - { + while(b < 0) { b += size; } } @@ -113,8 +118,7 @@ public: m_ptr++; - while (m_ptr >= size) - { + while (m_ptr >= size) { m_ptr -= size; } diff --git a/sdrbase/dsp/highpass.h b/sdrbase/dsp/highpass.h index de293b4b1..9d3d50c30 100644 --- a/sdrbase/dsp/highpass.h +++ b/sdrbase/dsp/highpass.h @@ -16,39 +16,51 @@ public: int i; // check constraints - if(!(nTaps & 1)) { + if (!(nTaps & 1)) + { qDebug("Highpass filter has to have an odd number of taps"); nTaps++; } // make room m_samples.resize(nTaps); - for(int i = 0; i < nTaps; i++) + + for (int i = 0; i < nTaps; i++) { m_samples[i] = 0; + } + m_ptr = 0; m_taps.resize(nTaps / 2 + 1); // generate Sinc filter core for lowpass but inverting every other tap for highpass keeping center tap - for(i = 0; i < nTaps / 2 + 1; i++) { - if(i == (nTaps - 1) / 2) + for (i = 0; i < nTaps / 2 + 1; i++) + { + if (i == (nTaps - 1) / 2) { m_taps[i] = -(Wc / M_PI); - else + } else { m_taps[i] = -sin(((double)i - ((double)nTaps - 1.0) / 2.0) * Wc) / (((double)i - ((double)nTaps - 1.0) / 2.0) * M_PI); + } } m_taps[(nTaps - 1) / 2] += 1; // apply Hamming window - for(i = 0; i < nTaps / 2 + 1; i++) + for (i = 0; i < nTaps / 2 + 1; i++) { m_taps[i] *= 0.54 + 0.46 * cos((2.0 * M_PI * ((double)i - ((double)nTaps - 1.0) / 2.0)) / (double)nTaps); + } // normalize Real sum = 0; - for(i = 0; i < (int)m_taps.size() - 1; i++) + + for (i = 0; i < (int)m_taps.size() - 1; i++) { sum += m_taps[i] * 2; - sum += m_taps[i]; - for(i = 0; i < (int)m_taps.size(); i++) + } + + sum += m_taps[i] - 1; + + for (i = 0; i < (int)m_taps.size(); i++) { m_taps[i] /= sum; + } } Type filter(Type sample) @@ -61,8 +73,7 @@ public: m_samples[m_ptr] = sample; size = m_samples.size(); // Valgrind optim (2) - while(b < 0) - { + while (b < 0) { b += size; } @@ -73,15 +84,13 @@ public: acc += (m_samples[a] + m_samples[b]) * m_taps[i]; a++; - while (a >= size) - { + while (a >= size) { a -= size; } b--; - while (b < 0) - { + while (b < 0) { b += size; } } @@ -89,8 +98,7 @@ public: acc += m_samples[a] * m_taps[i]; m_ptr++; - while (m_ptr >= size) - { + while (m_ptr >= size) { m_ptr -= size; } diff --git a/sdrbase/dsp/lowpass.h b/sdrbase/dsp/lowpass.h index b7b5e6ed4..3400f1c05 100644 --- a/sdrbase/dsp/lowpass.h +++ b/sdrbase/dsp/lowpass.h @@ -16,37 +16,49 @@ public: int i; // check constraints - if(!(nTaps & 1)) { + if (!(nTaps & 1)) + { qDebug("Lowpass filter has to have an odd number of taps"); nTaps++; } // make room m_samples.resize(nTaps); - for(int i = 0; i < nTaps; i++) + + for (int i = 0; i < nTaps; i++) { m_samples[i] = 0; + } + m_ptr = 0; m_taps.resize(nTaps / 2 + 1); // generate Sinc filter core - for(i = 0; i < nTaps / 2 + 1; i++) { - if(i == (nTaps - 1) / 2) + for (i = 0; i < nTaps / 2 + 1; i++) + { + if(i == (nTaps - 1) / 2) { m_taps[i] = Wc / M_PI; - else + } else { m_taps[i] = sin(((double)i - ((double)nTaps - 1.0) / 2.0) * Wc) / (((double)i - ((double)nTaps - 1.0) / 2.0) * M_PI); + } } // apply Hamming window - for(i = 0; i < nTaps / 2 + 1; i++) + for (i = 0; i < nTaps / 2 + 1; i++) { m_taps[i] *= 0.54 + 0.46 * cos((2.0 * M_PI * ((double)i - ((double)nTaps - 1.0) / 2.0)) / (double)nTaps); + } // normalize Real sum = 0; - for(i = 0; i < (int)m_taps.size() - 1; i++) + + for (i = 0; i < (int)m_taps.size() - 1; i++) { sum += m_taps[i] * 2; + } + sum += m_taps[i]; - for(i = 0; i < (int)m_taps.size(); i++) + + for (i = 0; i < (int)m_taps.size(); i++) { m_taps[i] /= sum; + } } Type filter(Type sample) @@ -59,8 +71,7 @@ public: m_samples[m_ptr] = sample; size = m_samples.size(); // Valgrind optim (2) - while (b < 0) - { + while (b < 0) { b += size; } @@ -71,15 +82,13 @@ public: acc += (m_samples[a] + m_samples[b]) * m_taps[i]; a++; - while (a >= size) - { + while (a >= size) { a -= size; } b--; - while(b < 0) - { + while(b < 0) { b += size; } } @@ -87,8 +96,7 @@ public: acc += m_samples[a] * m_taps[i]; m_ptr++; - while(m_ptr >= size) - { + while(m_ptr >= size) { m_ptr -= size; }