1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-16 05:11:49 -05: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(); apply();
//m_audioBuffer.resize(1<<14); m_audioBuffer.resize(1<<14);
//m_audioBufferFill = 0; m_audioBufferFill = 0;
m_movingAverage.resize(16, 0); m_movingAverage.resize(16, 0);
m_volumeAGC.resize(4096, 0.003, 0); m_volumeAGC.resize(4096, 0.003, 0);
@ -121,6 +121,7 @@ void AMMod::pull(Sample& sample)
} }
} }
m_audioBufferFill++;
m_interpolatorDistanceRemain += m_interpolatorDistance; m_interpolatorDistanceRemain += m_interpolatorDistance;
ci *= m_carrierNco.nextIQ(); // shift to carrier frequency ci *= m_carrierNco.nextIQ(); // shift to carrier frequency
@ -136,6 +137,19 @@ void AMMod::pull(Sample& sample)
sample.m_imag = (FixReal) ci.imag(); 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() void AMMod::modulateSample()
{ {
Real t; Real t;
@ -149,8 +163,6 @@ void AMMod::modulateSample()
void AMMod::pullAF(Real& sample) void AMMod::pullAF(Real& sample)
{ {
int16_t audioSample[2];
switch (m_afInput) switch (m_afInput)
{ {
case AMModInputTone: case AMModInputTone:
@ -186,8 +198,7 @@ void AMMod::pullAF(Real& sample)
} }
break; break;
case AMModInputAudio: case AMModInputAudio:
m_audioFifo.read(reinterpret_cast<quint8*>(audioSample), 1, 10); sample = ((m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r) / 65536.0f) * m_running.m_volumeFactor;
sample = ((audioSample[0] + audioSample[1]) / 65536.0f) * m_running.m_volumeFactor;
break; break;
case AMModInputCWTone: case AMModInputCWTone:
Real fadeFactor; Real fadeFactor;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -35,12 +35,14 @@ public:
virtual void start() = 0; virtual void start() = 0;
virtual void stop() = 0; virtual void stop() = 0;
virtual void pull(Sample& sample) = 0; virtual void pull(Sample& sample) = 0;
virtual void pullAudio(int nbSamples) {}
/** direct feeding of sample source FIFO */ /** direct feeding of sample source FIFO */
void feed(SampleSourceFifo* sampleFifo, int nbSamples) void feed(SampleSourceFifo* sampleFifo, int nbSamples)
{ {
SampleVector::iterator writeAt; SampleVector::iterator writeAt;
sampleFifo->getWriteIterator(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++) for (int i = 0; i < nbSamples; i++)
{ {

View File

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

View File

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