mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-26 17:58:43 -05:00
Make a dedicated CW transition smoothing class
This commit is contained in:
parent
599ff3d672
commit
98b9e20392
@ -52,12 +52,7 @@ SSBMod::SSBMod(BasebandSampleSink* sampleSink) :
|
|||||||
m_afInput(SSBModInputNone),
|
m_afInput(SSBModInputNone),
|
||||||
m_levelCalcCount(0),
|
m_levelCalcCount(0),
|
||||||
m_peakLevel(0.0f),
|
m_peakLevel(0.0f),
|
||||||
m_levelSum(0.0f),
|
m_levelSum(0.0f)
|
||||||
m_fadeInCounter(0),
|
|
||||||
m_fadeOutCounter(0),
|
|
||||||
m_nbFadeSamples(96),
|
|
||||||
m_fadeInSamples(0),
|
|
||||||
m_fadeOutSamples(0)
|
|
||||||
{
|
{
|
||||||
setObjectName("SSBMod");
|
setObjectName("SSBMod");
|
||||||
|
|
||||||
@ -98,7 +93,7 @@ SSBMod::SSBMod(BasebandSampleSink* sampleSink) :
|
|||||||
m_cwKeyer.setWPM(13);
|
m_cwKeyer.setWPM(13);
|
||||||
m_cwKeyer.setMode(CWKeyer::CWNone);
|
m_cwKeyer.setMode(CWKeyer::CWNone);
|
||||||
|
|
||||||
makeFadeSamples();
|
m_cwSmoother.setNbFadeSamples(96); // 2 ms at 48 kHz
|
||||||
apply();
|
apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,9 +115,6 @@ SSBMod::~SSBMod()
|
|||||||
delete m_DSBFilterBuffer;
|
delete m_DSBFilterBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] m_fadeInSamples;
|
|
||||||
delete[] m_fadeOutSamples;
|
|
||||||
|
|
||||||
DSPEngine::instance()->removeAudioSource(&m_audioFifo);
|
DSPEngine::instance()->removeAudioSource(&m_audioFifo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,17 +306,7 @@ void SSBMod::pullAF(Complex& sample)
|
|||||||
|
|
||||||
if (m_cwKeyer.getSample())
|
if (m_cwKeyer.getSample())
|
||||||
{
|
{
|
||||||
m_fadeOutCounter = 0;
|
m_cwSmoother.getFadeSample(true, fadeFactor);
|
||||||
|
|
||||||
if (m_fadeInCounter < m_nbFadeSamples)
|
|
||||||
{
|
|
||||||
fadeFactor = m_fadeInSamples[m_fadeInCounter];
|
|
||||||
m_fadeInCounter++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fadeFactor = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_running.m_dsb)
|
if (m_running.m_dsb)
|
||||||
{
|
{
|
||||||
@ -343,13 +325,8 @@ void SSBMod::pullAF(Complex& sample)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_fadeInCounter = 0;
|
if (m_cwSmoother.getFadeSample(false, fadeFactor))
|
||||||
|
|
||||||
if (m_fadeOutCounter < m_nbFadeSamples)
|
|
||||||
{
|
{
|
||||||
fadeFactor = m_fadeOutSamples[m_fadeOutCounter];
|
|
||||||
m_fadeOutCounter++;
|
|
||||||
|
|
||||||
if (m_running.m_dsb)
|
if (m_running.m_dsb)
|
||||||
{
|
{
|
||||||
Real t = m_toneNco.next() * fadeFactor;
|
Real t = m_toneNco.next() * fadeFactor;
|
||||||
@ -502,29 +479,6 @@ void SSBMod::pullAF(Complex& sample)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSBMod::makeFadeSamples()
|
|
||||||
{
|
|
||||||
if (m_fadeInSamples) {
|
|
||||||
delete[] m_fadeInSamples;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_fadeOutSamples) {
|
|
||||||
delete[] m_fadeOutSamples;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_fadeInSamples = new Real[m_nbFadeSamples];
|
|
||||||
m_fadeOutSamples = new Real[m_nbFadeSamples];
|
|
||||||
|
|
||||||
for (int i = 0; i < m_nbFadeSamples; i++)
|
|
||||||
{
|
|
||||||
m_fadeInSamples[i] = sin((i/ (Real) m_nbFadeSamples) * M_PI_2);
|
|
||||||
m_fadeOutSamples[i] = cos((i/ (Real) m_nbFadeSamples) * M_PI_2);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_fadeInCounter = 0;
|
|
||||||
m_fadeOutCounter = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SSBMod::calculateLevel(Complex& sample)
|
void SSBMod::calculateLevel(Complex& sample)
|
||||||
{
|
{
|
||||||
Real t = sample.real(); // TODO: possibly adjust depending on sample type
|
Real t = sample.real(); // TODO: possibly adjust depending on sample type
|
||||||
@ -720,8 +674,7 @@ void SSBMod::apply()
|
|||||||
{
|
{
|
||||||
m_settingsMutex.lock();
|
m_settingsMutex.lock();
|
||||||
m_cwKeyer.setSampleRate(m_config.m_audioSampleRate);
|
m_cwKeyer.setSampleRate(m_config.m_audioSampleRate);
|
||||||
m_nbFadeSamples = m_config.m_audioSampleRate / 500; // 2ms
|
m_cwSmoother.setNbFadeSamples(m_config.m_audioSampleRate / 500); // 2 ms
|
||||||
makeFadeSamples();
|
|
||||||
m_settingsMutex.unlock();
|
m_settingsMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,11 +383,7 @@ private:
|
|||||||
Real m_peakLevel;
|
Real m_peakLevel;
|
||||||
Real m_levelSum;
|
Real m_levelSum;
|
||||||
CWKeyer m_cwKeyer;
|
CWKeyer m_cwKeyer;
|
||||||
int m_fadeInCounter;
|
CWSmoother m_cwSmoother;
|
||||||
int m_fadeOutCounter;
|
|
||||||
int m_nbFadeSamples;
|
|
||||||
Real *m_fadeInSamples;
|
|
||||||
Real *m_fadeOutSamples;
|
|
||||||
|
|
||||||
static const int m_levelNbSamples;
|
static const int m_levelNbSamples;
|
||||||
|
|
||||||
@ -395,7 +391,6 @@ private:
|
|||||||
void pullAF(Complex& sample);
|
void pullAF(Complex& sample);
|
||||||
void calculateLevel(Complex& sample);
|
void calculateLevel(Complex& sample);
|
||||||
void modulateSample();
|
void modulateSample();
|
||||||
void makeFadeSamples();
|
|
||||||
void openFileStream();
|
void openFileStream();
|
||||||
void seekFileStream(int seekPercentage);
|
void seekFileStream(int seekPercentage);
|
||||||
};
|
};
|
||||||
|
@ -451,3 +451,82 @@ bool CWKeyer::eom()
|
|||||||
{
|
{
|
||||||
return !(m_textPointer < m_text.length());
|
return !(m_textPointer < m_text.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CWSmoother::CWSmoother() :
|
||||||
|
m_fadeInCounter(0),
|
||||||
|
m_fadeOutCounter(0),
|
||||||
|
m_nbFadeSamples(0),
|
||||||
|
m_fadeInSamples(0),
|
||||||
|
m_fadeOutSamples(0)
|
||||||
|
{
|
||||||
|
setNbFadeSamples(96); // default is 2ms at 48 kHz sample rate
|
||||||
|
}
|
||||||
|
|
||||||
|
CWSmoother::~CWSmoother()
|
||||||
|
{
|
||||||
|
delete[] m_fadeInSamples;
|
||||||
|
delete[] m_fadeOutSamples;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWSmoother::setNbFadeSamples(unsigned int nbFadeSamples)
|
||||||
|
{
|
||||||
|
if (nbFadeSamples != m_nbFadeSamples)
|
||||||
|
{
|
||||||
|
QMutexLocker mutexLocker(&m_mutex);
|
||||||
|
|
||||||
|
m_nbFadeSamples = nbFadeSamples;
|
||||||
|
|
||||||
|
if (m_fadeInSamples) delete[] m_fadeInSamples;
|
||||||
|
if (m_fadeOutSamples) delete[] m_fadeOutSamples;
|
||||||
|
|
||||||
|
m_fadeInSamples = new float[m_nbFadeSamples];
|
||||||
|
m_fadeOutSamples = new float[m_nbFadeSamples];
|
||||||
|
|
||||||
|
for (int i = 0; i < m_nbFadeSamples; i++)
|
||||||
|
{
|
||||||
|
m_fadeInSamples[i] = sin((i/ (float) m_nbFadeSamples) * M_PI_2);
|
||||||
|
m_fadeOutSamples[i] = cos((i/ (float) m_nbFadeSamples) * M_PI_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_fadeInCounter = 0;
|
||||||
|
m_fadeOutCounter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWSmoother::getFadeSample(bool on, float& sample)
|
||||||
|
{
|
||||||
|
QMutexLocker mutexLocker(&m_mutex);
|
||||||
|
|
||||||
|
if (on)
|
||||||
|
{
|
||||||
|
m_fadeOutCounter = 0;
|
||||||
|
|
||||||
|
if (m_fadeInCounter < m_nbFadeSamples)
|
||||||
|
{
|
||||||
|
sample = m_fadeInSamples[m_fadeInCounter];
|
||||||
|
m_fadeInCounter++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sample = 1.0f;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_fadeInCounter = 0;
|
||||||
|
|
||||||
|
if (m_fadeOutCounter < m_nbFadeSamples)
|
||||||
|
{
|
||||||
|
sample = m_fadeOutSamples[m_fadeOutCounter];
|
||||||
|
m_fadeOutCounter++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sample = 0.0f;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -99,6 +99,25 @@ private:
|
|||||||
void nextStateText();
|
void nextStateText();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ancillary class to smooth out CW transitions with a sine shape
|
||||||
|
*/
|
||||||
|
class CWSmoother
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CWSmoother();
|
||||||
|
~CWSmoother();
|
||||||
|
|
||||||
|
void setNbFadeSamples(unsigned int nbFadeSamples);
|
||||||
|
bool getFadeSample(bool on, float& sample);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMutex m_mutex;
|
||||||
|
int m_fadeInCounter;
|
||||||
|
int m_fadeOutCounter;
|
||||||
|
unsigned int m_nbFadeSamples;
|
||||||
|
float *m_fadeInSamples;
|
||||||
|
float *m_fadeOutSamples;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* SDRBASE_DSP_CWKEYER_H_ */
|
#endif /* SDRBASE_DSP_CWKEYER_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user