1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-16 13:21:50 -05:00

Tx ph.2: use a specialized interpolator similar to the decimator derived from the ancient interpolator

This commit is contained in:
f4exb 2016-10-28 03:18:24 +02:00
parent 9540a99ac4
commit 4d273d8a13
4 changed files with 33 additions and 23 deletions

View File

@ -65,17 +65,28 @@ void AMMod::pull(Sample& sample)
{ {
Complex ci; Complex ci;
m_interpolator.interpolate(&m_interpolatorDistanceRemain, m_modSample, &m_interpolatorConsumed, &ci); // Resampler used for interpolation only
m_interpolatorDistanceRemain += m_interpolatorDistance; // 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(); 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.real(((t+1.0f) * m_running.m_modFactor * 16384.0f)); // modulate and scale zero frequency carrier
m_modSample.imag(0.0f); m_modSample.imag(0.0f);
m_interpolatorConsumed = false;
} }
m_interpolatorDistanceRemain += m_interpolatorDistance;
ci *= m_carrierNco.nextIQ(); // shift to carrier frequency ci *= m_carrierNco.nextIQ(); // shift to carrier frequency
Real magsq = ci.real() * ci.real() + ci.imag() * ci.imag(); Real magsq = ci.real() * ci.real() + ci.imag() * ci.imag();

View File

@ -327,8 +327,8 @@ void FileSinkGui::tick()
} }
} }
unsigned int FileSinkSampleRates::m_rates[] = {48, 60, 64, 80}; unsigned int FileSinkSampleRates::m_rates[] = {48, 60, 60, 64, 72};
unsigned int FileSinkSampleRates::m_nb_rates = 4; unsigned int FileSinkSampleRates::m_nb_rates = 5;
unsigned int FileSinkSampleRates::getRate(unsigned int rate_index) unsigned int FileSinkSampleRates::getRate(unsigned int rate_index)
{ {

View File

@ -93,7 +93,7 @@ public:
static unsigned int getRateIndex(unsigned int rate); static unsigned int getRateIndex(unsigned int rate);
static unsigned int getNbRates(); static unsigned int getNbRates();
private: private:
static unsigned int m_rates[4]; static unsigned int m_rates[5];
static unsigned int m_nb_rates; static unsigned int m_nb_rates;
}; };

View File

@ -35,27 +35,26 @@ public:
return true; 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) 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); advanceFilter(next);
doInterpolate((int) floor(*distance * (Real)m_phaseSteps), result); *distance -= 1.0;
return true; // need new input sample and increment distance consumed = true;
}
else // use zero
{
advanceFilter();
doInterpolate((int) floor(*distance * (Real)m_phaseSteps), result);
return false; // input sample was not used and do not increment distance
} }
doInterpolate((int)floor(*distance * (Real)m_phaseSteps), result);
return consumed;
} }
// original interpolator // original interpolator which is actually an arbitrary rational resampler P/Q for any positive P, Q
bool interpolate(Real* distance, const Complex& next, bool* consumed, Complex* result) // sampling frequency must be the highest of the two
bool resample(Real* distance, const Complex& next, bool* consumed, Complex* result)
{ {
while(*distance >= 1.0) while(*distance >= 1.0)
{ {