mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-26 01:39:05 -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:
parent
f5572eebc0
commit
e02ac85e50
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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++)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user