1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-09-28 07:46:37 -04:00

All modulators: use buffer for input audio that is always in use while generation is running. This fixes lockup problem reported in issue #11

This commit is contained in:
f4exb 2016-12-26 01:39:34 +01:00
parent f5572eebc0
commit e02ac85e50
11 changed files with 131 additions and 79 deletions

View File

@ -57,8 +57,8 @@ AMMod::AMMod() :
apply();
//m_audioBuffer.resize(1<<14);
//m_audioBufferFill = 0;
m_audioBuffer.resize(1<<14);
m_audioBufferFill = 0;
m_movingAverage.resize(16, 0);
m_volumeAGC.resize(4096, 0.003, 0);
@ -121,6 +121,7 @@ void AMMod::pull(Sample& sample)
}
}
m_audioBufferFill++;
m_interpolatorDistanceRemain += m_interpolatorDistance;
ci *= m_carrierNco.nextIQ(); // shift to carrier frequency
@ -136,6 +137,19 @@ void AMMod::pull(Sample& sample)
sample.m_imag = (FixReal) ci.imag();
}
void AMMod::pullAudio(int nbSamples)
{
// qDebug("AMMod::pullAudio: %d", nbSamples);
if (nbSamples > m_audioBuffer.size())
{
m_audioBuffer.resize(nbSamples);
}
m_audioFifo.read(reinterpret_cast<quint8*>(&m_audioBuffer[0]), nbSamples*sizeof(AudioSample), 10);
m_audioBufferFill = 0;
}
void AMMod::modulateSample()
{
Real t;
@ -149,8 +163,6 @@ void AMMod::modulateSample()
void AMMod::pullAF(Real& sample)
{
int16_t audioSample[2];
switch (m_afInput)
{
case AMModInputTone:
@ -186,8 +198,7 @@ void AMMod::pullAF(Real& sample)
}
break;
case AMModInputAudio:
m_audioFifo.read(reinterpret_cast<quint8*>(audioSample), 1, 10);
sample = ((audioSample[0] + audioSample[1]) / 65536.0f) * m_running.m_volumeFactor;
sample = ((m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r) / 65536.0f) * m_running.m_volumeFactor;
break;
case AMModInputCWTone:
Real fadeFactor;

View File

@ -185,6 +185,7 @@ public:
bool playLoop);
virtual void pull(Sample& sample);
virtual void pullAudio(int nbSamples);
virtual void start();
virtual void stop();
virtual bool handleMessage(const Message& cmd);
@ -294,8 +295,8 @@ private:
MovingAverage<Real> m_movingAverage;
SimpleAGC m_volumeAGC;
//AudioVector m_audioBuffer;
//uint m_audioBufferFill;
AudioVector m_audioBuffer;
uint m_audioBufferFill;
AudioFifo m_audioFifo;
SampleVector m_sampleBuffer;

View File

@ -59,8 +59,8 @@ NFMMod::NFMMod() :
apply();
//m_audioBuffer.resize(1<<14);
//m_audioBufferFill = 0;
m_audioBuffer.resize(1<<14);
m_audioBufferFill = 0;
m_movingAverage.resize(16, 0);
m_volumeAGC.resize(4096, 0.003, 0);
@ -136,6 +136,7 @@ void NFMMod::pull(Sample& sample)
}
}
m_audioBufferFill++;
m_interpolatorDistanceRemain += m_interpolatorDistance;
ci *= m_carrierNco.nextIQ(); // shift to carrier frequency
@ -151,6 +152,17 @@ void NFMMod::pull(Sample& sample)
sample.m_imag = (FixReal) ci.imag();
}
void NFMMod::pullAudio(int nbSamples)
{
if (nbSamples > m_audioBuffer.size())
{
m_audioBuffer.resize(nbSamples);
}
m_audioFifo.read(reinterpret_cast<quint8*>(&m_audioBuffer[0]), nbSamples*sizeof(AudioSample), 10);
m_audioBufferFill = 0;
}
void NFMMod::modulateSample()
{
Real t;
@ -174,8 +186,6 @@ void NFMMod::modulateSample()
void NFMMod::pullAF(Real& sample)
{
int16_t audioSample[2];
switch (m_afInput)
{
case NFMModInputTone:
@ -211,8 +221,7 @@ void NFMMod::pullAF(Real& sample)
}
break;
case NFMModInputAudio:
m_audioFifo.read(reinterpret_cast<quint8*>(audioSample), 1, 10);
sample = ((audioSample[0] + audioSample[1]) / 65536.0f) * m_running.m_volumeFactor;
sample = ((m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r) / 65536.0f) * m_running.m_volumeFactor;
break;
case NFMModInputCWTone:
Real fadeFactor;

View File

@ -190,6 +190,7 @@ public:
float ctcssFrequency);
virtual void pull(Sample& sample);
virtual void pullAudio(int nbSamples);
virtual void start();
virtual void stop();
virtual bool handleMessage(const Message& cmd);
@ -342,8 +343,8 @@ private:
MovingAverage<Real> m_movingAverage;
SimpleAGC m_volumeAGC;
//AudioVector m_audioBuffer;
//uint m_audioBufferFill;
AudioVector m_audioBuffer;
uint m_audioBufferFill;
AudioFifo m_audioFifo;
SampleVector m_sampleBuffer;

View File

@ -69,8 +69,8 @@ SSBMod::SSBMod(BasebandSampleSink* sampleSink) :
m_config.m_toneFrequency = 1000.0f;
m_config.m_audioSampleRate = DSPEngine::instance()->getAudioSampleRate();
//m_audioBuffer.resize(1<<14);
//m_audioBufferFill = 0;
m_audioBuffer.resize(1<<14);
m_audioBufferFill = 0;
// m_magsqSpectrum = 0.0f;
// m_magsqSum = 0.0f;
@ -166,6 +166,7 @@ void SSBMod::pull(Sample& sample)
}
}
m_audioBufferFill++;
m_interpolatorDistanceRemain += m_interpolatorDistance;
ci *= m_carrierNco.nextIQ(); // shift to carrier frequency
@ -182,6 +183,17 @@ void SSBMod::pull(Sample& sample)
sample.m_imag = (FixReal) ci.imag();
}
void SSBMod::pullAudio(int nbSamples)
{
if (nbSamples > m_audioBuffer.size())
{
m_audioBuffer.resize(nbSamples);
}
m_audioFifo.read(reinterpret_cast<quint8*>(&m_audioBuffer[0]), nbSamples*sizeof(AudioSample), 10);
m_audioBufferFill = 0;
}
void SSBMod::modulateSample()
{
pullAF(m_modSample);
@ -197,7 +209,6 @@ void SSBMod::pullAF(Complex& sample)
return;
}
int16_t audioSample[2];
Complex ci;
fftfilt::cmplx *filtered;
int n_out = 0;
@ -279,24 +290,22 @@ void SSBMod::pullAF(Complex& sample)
}
break;
case SSBModInputAudio:
m_audioFifo.read(reinterpret_cast<quint8*>(audioSample), 1, 10);
if (m_running.m_audioBinaural)
{
if (m_running.m_audioFlipChannels)
{
ci.real((audioSample[1] / 32768.0f) * m_running.m_volumeFactor);
ci.imag((audioSample[0] / 32768.0f) * m_running.m_volumeFactor);
ci.real((m_audioBuffer[m_audioBufferFill].r / 32768.0f) * m_running.m_volumeFactor);
ci.imag((m_audioBuffer[m_audioBufferFill].l / 32768.0f) * m_running.m_volumeFactor);
}
else
{
ci.real((audioSample[0] / 32768.0f) * m_running.m_volumeFactor);
ci.imag((audioSample[1] / 32768.0f) * m_running.m_volumeFactor);
ci.real((m_audioBuffer[m_audioBufferFill].l / 32768.0f) * m_running.m_volumeFactor);
ci.imag((m_audioBuffer[m_audioBufferFill].r / 32768.0f) * m_running.m_volumeFactor);
}
}
else
{
ci.real(((audioSample[0] + audioSample[1]) / 65536.0f) * m_running.m_volumeFactor);
ci.real(((m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r) / 65536.0f) * m_running.m_volumeFactor);
ci.imag(0.0f);
}

View File

@ -190,6 +190,7 @@ public:
bool playLoop);
virtual void pull(Sample& sample);
virtual void pullAudio(int nbSamples);
virtual void start();
virtual void stop();
virtual bool handleMessage(const Message& cmd);
@ -366,8 +367,8 @@ private:
MovingAverage<Real> m_movingAverage;
SimpleAGC m_volumeAGC;
//AudioVector m_audioBuffer;
//uint m_audioBufferFill;
AudioVector m_audioBuffer;
uint m_audioBufferFill;
AudioFifo m_audioFifo;
QMutex m_settingsMutex;

View File

@ -62,8 +62,8 @@ WFMMod::WFMMod() :
apply();
//m_audioBuffer.resize(1<<14);
//m_audioBufferFill = 0;
m_audioBuffer.resize(1<<14);
m_audioBufferFill = 0;
m_movingAverage.resize(16, 0);
m_volumeAGC.resize(4096, 0.003, 0);
@ -116,8 +116,10 @@ void WFMMod::pull(Sample& sample)
{
pullAF(m_modSample);
calculateLevel(m_modSample.real());
m_audioBufferFill++;
}
m_audioBufferFill++;
m_interpolatorDistanceRemain += m_interpolatorDistance;
m_modPhasor += (m_running.m_fmDeviation / (float) m_running.m_outputSampleRate) * ri.real() * M_PI;
@ -139,10 +141,19 @@ void WFMMod::pull(Sample& sample)
sample.m_imag = (FixReal) ci.imag();
}
void WFMMod::pullAudio(int nbSamples)
{
if (nbSamples > m_audioBuffer.size())
{
m_audioBuffer.resize(nbSamples);
}
m_audioFifo.read(reinterpret_cast<quint8*>(&m_audioBuffer[0]), nbSamples*sizeof(AudioSample), 10);
m_audioBufferFill = 0;
}
void WFMMod::pullAF(Complex& sample)
{
int16_t audioSample[2];
switch (m_afInput)
{
case WFMModInputTone:
@ -184,9 +195,7 @@ void WFMMod::pullAF(Complex& sample)
break;
case WFMModInputAudio:
{
Real s = (audioSample[0] + audioSample[1]) / 65536.0f;
m_audioFifo.read(reinterpret_cast<quint8*>(audioSample), 1, 10);
sample.real(s * m_running.m_volumeFactor);
sample.real(((m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r) / 65536.0f) * m_running.m_volumeFactor);
sample.imag(0.0f);
}
break;

View File

@ -187,6 +187,7 @@ public:
bool playLoop);
virtual void pull(Sample& sample);
virtual void pullAudio(int nbSamples);
virtual void start();
virtual void stop();
virtual bool handleMessage(const Message& cmd);
@ -322,8 +323,8 @@ private:
MovingAverage<Real> m_movingAverage;
SimpleAGC m_volumeAGC;
//AudioVector m_audioBuffer;
//uint m_audioBufferFill;
AudioVector m_audioBuffer;
uint m_audioBufferFill;
AudioFifo m_audioFifo;
SampleVector m_sampleBuffer;

View File

@ -35,12 +35,14 @@ public:
virtual void start() = 0;
virtual void stop() = 0;
virtual void pull(Sample& sample) = 0;
virtual void pullAudio(int nbSamples) {}
/** direct feeding of sample source FIFO */
void feed(SampleSourceFifo* sampleFifo, int nbSamples)
{
SampleVector::iterator writeAt;
sampleFifo->getWriteIterator(writeAt);
pullAudio(nbSamples); // Pre-fetch input audio samples this is mandatory to keep things running smoothly
for (int i = 0; i < nbSamples; i++)
{

View File

@ -176,7 +176,9 @@ void DSPDeviceSinkEngine::work(int nbWriteSamples)
// single channel source handling
if ((m_threadedBasebandSampleSources.size() + m_basebandSampleSources.size()) == 1)
{
for (ThreadedBasebandSampleSources::iterator it = m_threadedBasebandSampleSources.begin(); it != m_threadedBasebandSampleSources.end(); ++it)
qDebug("DSPDeviceSinkEngine::work: single channel source handling");
for (ThreadedBasebandSampleSources::iterator it = m_threadedBasebandSampleSources.begin(); it != m_threadedBasebandSampleSources.end(); ++it)
{
(*it)->feed(sampleFifo, nbWriteSamples);
}
@ -189,47 +191,52 @@ void DSPDeviceSinkEngine::work(int nbWriteSamples)
else if ((m_threadedBasebandSampleSources.size() + m_basebandSampleSources.size()) > 1)
{
qDebug("DSPDeviceSinkEngine::work: multiple channel sources handling");
SampleVector::iterator writeBegin;
sampleFifo->getWriteIterator(writeBegin);
SampleVector::iterator writeAt = writeBegin;
Sample s;
int sourceOccurence = 0;
for (int is = 0; is < nbWriteSamples; is++)
{
// pull data from threaded sources and merge them in the device sample FIFO
for (ThreadedBasebandSampleSources::iterator it = m_threadedBasebandSampleSources.begin(); it != m_threadedBasebandSampleSources.end(); ++it)
{
(*it)->pull(s);
s /= (m_threadedBasebandSampleSources.size() + m_basebandSampleSources.size());
if (sourceOccurence == 0) {
(*writeAt) = s;
} else {
(*writeAt) += s;
}
sourceOccurence++;
}
// pull data from direct sources and merge them in the device sample FIFO
for (BasebandSampleSources::iterator it = m_basebandSampleSources.begin(); it != m_basebandSampleSources.end(); ++it)
{
(*it)->pull(s);
s /= (m_threadedBasebandSampleSources.size() + m_basebandSampleSources.size());
if (sourceOccurence == 0) {
(*writeAt) = s;
} else {
(*writeAt) += s;
}
sourceOccurence++;
}
sampleFifo->bumpIndex(writeAt);
sourceOccurence = 0;
}
// TODO properly
if (m_threadedBasebandSampleSources.size() > 0)
{
(*m_threadedBasebandSampleSources.begin())->feed(sampleFifo, nbWriteSamples);
}
// SampleVector::iterator writeBegin;
// sampleFifo->getWriteIterator(writeBegin);
// SampleVector::iterator writeAt = writeBegin;
// Sample s;
// int sourceOccurence = 0;
//
// for (int is = 0; is < nbWriteSamples; is++)
// {
// // pull data from threaded sources and merge them in the device sample FIFO
// for (ThreadedBasebandSampleSources::iterator it = m_threadedBasebandSampleSources.begin(); it != m_threadedBasebandSampleSources.end(); ++it)
// {
// (*it)->pull(s);
// s /= (m_threadedBasebandSampleSources.size() + m_basebandSampleSources.size());
//
// if (sourceOccurence == 0) {
// (*writeAt) = s;
// } else {
// (*writeAt) += s;
// }
//
// sourceOccurence++;
// }
//
// // pull data from direct sources and merge them in the device sample FIFO
// for (BasebandSampleSources::iterator it = m_basebandSampleSources.begin(); it != m_basebandSampleSources.end(); ++it)
// {
// (*it)->pull(s);
// s /= (m_threadedBasebandSampleSources.size() + m_basebandSampleSources.size());
//
// if (sourceOccurence == 0) {
// (*writeAt) = s;
// } else {
// (*writeAt) += s;
// }
//
// sourceOccurence++;
// }
//
// sampleFifo->bumpIndex(writeAt);
// sourceOccurence = 0;
// }
// feed the mix to the main spectrum sink
// if (m_spectrumSink)

View File

@ -63,6 +63,7 @@ public:
virtual void start();
virtual void stop();
virtual void pull(Sample& sample);
virtual void pullAudio(int nbSamples) { if (m_sampleSource) m_sampleSource->pullAudio(nbSamples); }
virtual bool handleMessage(const Message& cmd);