From 4d273d8a1373ff571ff2d6dd977905672fb842cd Mon Sep 17 00:00:00 2001 From: f4exb Date: Fri, 28 Oct 2016 03:18:24 +0200 Subject: [PATCH] Tx ph.2: use a specialized interpolator similar to the decimator derived from the ancient interpolator --- plugins/channeltx/modam/ammod.cpp | 25 +++++++++++++++------ plugins/samplesink/filesink/filesinkgui.cpp | 4 ++-- plugins/samplesink/filesink/filesinkgui.h | 2 +- sdrbase/dsp/interpolator.h | 25 ++++++++++----------- 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/plugins/channeltx/modam/ammod.cpp b/plugins/channeltx/modam/ammod.cpp index 3dc498c58..1d6ab3fe0 100644 --- a/plugins/channeltx/modam/ammod.cpp +++ b/plugins/channeltx/modam/ammod.cpp @@ -65,17 +65,28 @@ void AMMod::pull(Sample& sample) { Complex ci; - m_interpolator.interpolate(&m_interpolatorDistanceRemain, m_modSample, &m_interpolatorConsumed, &ci); - m_interpolatorDistanceRemain += m_interpolatorDistance; +// Resampler used for interpolation only +// m_interpolator.resample(&m_interpolatorDistanceRemain, m_modSample, &m_interpolatorConsumed, &ci); +// m_interpolatorDistanceRemain += m_interpolatorDistance; +// +// if (m_interpolatorConsumed) +// { +// Real t = m_toneNco.next(); +// m_modSample.real(((t+1.0f) * m_running.m_modFactor * 16384.0f)); // modulate and scale zero frequency carrier +// m_modSample.imag(0.0f); +// m_interpolatorConsumed = false; +// } - if (m_interpolatorConsumed) +// Specialized interpolator + if (m_interpolator.interpolate(&m_interpolatorDistanceRemain, m_modSample, &ci)) { - Real t = m_toneNco.next(); - m_modSample.real(((t+1.0f) * m_running.m_modFactor * 16384.0f)); // modulate and scale zero frequency carrier - m_modSample.imag(0.0f); - m_interpolatorConsumed = false; + Real t = m_toneNco.next(); + m_modSample.real(((t+1.0f) * m_running.m_modFactor * 16384.0f)); // modulate and scale zero frequency carrier + m_modSample.imag(0.0f); } + m_interpolatorDistanceRemain += m_interpolatorDistance; + ci *= m_carrierNco.nextIQ(); // shift to carrier frequency Real magsq = ci.real() * ci.real() + ci.imag() * ci.imag(); diff --git a/plugins/samplesink/filesink/filesinkgui.cpp b/plugins/samplesink/filesink/filesinkgui.cpp index 5effdce5a..ba512a33e 100644 --- a/plugins/samplesink/filesink/filesinkgui.cpp +++ b/plugins/samplesink/filesink/filesinkgui.cpp @@ -327,8 +327,8 @@ void FileSinkGui::tick() } } -unsigned int FileSinkSampleRates::m_rates[] = {48, 60, 64, 80}; -unsigned int FileSinkSampleRates::m_nb_rates = 4; +unsigned int FileSinkSampleRates::m_rates[] = {48, 60, 60, 64, 72}; +unsigned int FileSinkSampleRates::m_nb_rates = 5; unsigned int FileSinkSampleRates::getRate(unsigned int rate_index) { diff --git a/plugins/samplesink/filesink/filesinkgui.h b/plugins/samplesink/filesink/filesinkgui.h index fbe152598..575b1761b 100644 --- a/plugins/samplesink/filesink/filesinkgui.h +++ b/plugins/samplesink/filesink/filesinkgui.h @@ -93,7 +93,7 @@ public: static unsigned int getRateIndex(unsigned int rate); static unsigned int getNbRates(); private: - static unsigned int m_rates[4]; + static unsigned int m_rates[5]; static unsigned int m_nb_rates; }; diff --git a/sdrbase/dsp/interpolator.h b/sdrbase/dsp/interpolator.h index 3021d11c1..24f7e1b36 100644 --- a/sdrbase/dsp/interpolator.h +++ b/sdrbase/dsp/interpolator.h @@ -35,27 +35,26 @@ public: return true; } - // interpolation works nearly the same way // TODO: remove when original is used + // interpolation simplified from the generalized resampler bool interpolate(Real *distance, const Complex& next, Complex* result) { - *distance -= 1.0; + bool consumed = false; - if (*distance < 1.0) // use sample + if (*distance >= 1.0) { advanceFilter(next); - doInterpolate((int) floor(*distance * (Real)m_phaseSteps), result); - return true; // need new input sample and increment distance - } - else // use zero - { - advanceFilter(); - doInterpolate((int) floor(*distance * (Real)m_phaseSteps), result); - return false; // input sample was not used and do not increment distance + *distance -= 1.0; + consumed = true; } + + doInterpolate((int)floor(*distance * (Real)m_phaseSteps), result); + + return consumed; } - // original interpolator - bool interpolate(Real* distance, const Complex& next, bool* consumed, Complex* result) + // original interpolator which is actually an arbitrary rational resampler P/Q for any positive P, Q + // sampling frequency must be the highest of the two + bool resample(Real* distance, const Complex& next, bool* consumed, Complex* result) { while(*distance >= 1.0) {