1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-19 06:41:47 -05:00

DSD demod plugin: DSD proper integration interim state #2

This commit is contained in:
f4exb 2016-04-09 19:14:19 +02:00
parent 5872ee0ca7
commit 497ce458dc
4 changed files with 43 additions and 48 deletions

View File

@ -104,9 +104,10 @@ typedef struct
int exitflag; // the former global that cannot be a global within SDRangel and is not of much use with it anyway int exitflag; // the former global that cannot be a global within SDRangel and is not of much use with it anyway
// New from original DSD for in-memory processing support with SDRangel: // New from original DSD for in-memory processing support with SDRangel:
const short *input_samples; //!< demodulator samples short *input_samples; //!< demodulator samples
int input_length; //!< 0: data not ready, >0: data ready for this amount of demodulator samples int input_length; //!< 0: data not ready, >0: data ready for this amount of demodulator samples
int input_offset; //!< consumer pointer int input_offset; //!< consumer pointer
int input_buffer_size; //!< Size of buffer in number of samples
short *output_buffer; //!< Output of decoder single S16LE short *output_buffer; //!< Output of decoder single S16LE
int output_offset; //!< producer pointer int output_offset; //!< producer pointer

View File

@ -52,8 +52,10 @@ DSDDecoder::DSDDecoder()
m_dsdParams.opts.mod_gfsk = 1; m_dsdParams.opts.mod_gfsk = 1;
m_dsdParams.state.rf_mod = 0; m_dsdParams.state.rf_mod = 0;
m_dsdParams.state.input_samples = (short *) malloc(1<<18);
m_dsdParams.state.input_length = 0; m_dsdParams.state.input_length = 0;
m_dsdParams.state.input_offset = 0; m_dsdParams.state.input_offset = 0;
m_dsdParams.state.input_buffer_size = 1<<17;
m_dsdParams.state.output_buffer = (short *) malloc(1<<18); // Raw output buffer with single S16LE samples @ 8k (max: 128 kS) m_dsdParams.state.output_buffer = (short *) malloc(1<<18); // Raw output buffer with single S16LE samples @ 8k (max: 128 kS)
m_dsdParams.state.output_offset = 0; m_dsdParams.state.output_offset = 0;
@ -82,14 +84,10 @@ DSDDecoder::~DSDDecoder()
{ {
free(m_dsdParams.state.output_samples); free(m_dsdParams.state.output_samples);
free(m_dsdParams.state.output_buffer); free(m_dsdParams.state.output_buffer);
free(m_dsdParams.state.input_samples);
} }
void DSDDecoder::setInBuffer(const short *inBuffer) void DSDDecoder::pushSamples(const short *samples,int nbSamples)
{
m_dsdParams.state.input_samples = inBuffer;
}
void DSDDecoder::pushSamples(int nbSamples)
{ {
if (nbSamples == 0) if (nbSamples == 0)
{ {
@ -98,6 +96,7 @@ void DSDDecoder::pushSamples(int nbSamples)
} }
else else
{ {
memcpy((void *) m_dsdParams.state.input_samples, (const void *) samples, nbSamples * sizeof(short));
m_dsdParams.state.input_offset = 0; m_dsdParams.state.input_offset = 0;
m_dsdParams.state.input_length = nbSamples; m_dsdParams.state.input_length = nbSamples;
m_dsdParams.state.output_finished = 0; m_dsdParams.state.output_finished = 0;

View File

@ -28,9 +28,7 @@ public:
DSDDecoder(); DSDDecoder();
~DSDDecoder(); ~DSDDecoder();
void setInBuffer(const short *inBuffer); void pushSamples(const short *samples, int nbSamples); // Push this amount of samples to the DSD decoder thread
void pushSample(short sample);
void pushSamples(int nbSamples); // Push this amount of samples to the DSD decoder thread
void popAudioSamples(AudioFifo *audioFifo, bool audioMute); void popAudioSamples(AudioFifo *audioFifo, bool audioMute);
void start(); void start();

View File

@ -44,7 +44,6 @@ DSDDemod::DSDDemod(SampleSink* sampleSink) :
setObjectName("DSDDemod"); setObjectName("DSDDemod");
m_dsdInBuffer = new qint16[1<<18]; // 128 k Samples is the maximum size of all input devices sample buffers (Airspy or HackRF) = 2^(17+1) for 2 byte samples m_dsdInBuffer = new qint16[1<<18]; // 128 k Samples is the maximum size of all input devices sample buffers (Airspy or HackRF) = 2^(17+1) for 2 byte samples
m_dsdDecoder.setInBuffer(m_dsdInBuffer);
m_config.m_inputSampleRate = 96000; m_config.m_inputSampleRate = 96000;
m_config.m_inputFrequencyOffset = 0; m_config.m_inputFrequencyOffset = 0;
@ -105,45 +104,44 @@ void DSDDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
Complex c(it->real(), it->imag()); Complex c(it->real(), it->imag());
c *= m_nco.nextIQ(); c *= m_nco.nextIQ();
{ if (m_interpolator.interpolate(&m_interpolatorDistanceRemain, c, &ci))
if (m_interpolator.interpolate(&m_interpolatorDistanceRemain, c, &ci)) {
{ qint16 sample;
qint16 sample;
m_magsq = ((ci.real()*ci.real() + ci.imag()*ci.imag())) / (Real) (1<<30); m_magsq = ((ci.real()*ci.real() + ci.imag()*ci.imag())) / (Real) (1<<30);
m_movingAverage.feed(m_magsq); m_movingAverage.feed(m_magsq);
Real demod = 32768.0f * m_phaseDiscri.phaseDiscriminator(ci) * ((float) m_running.m_demodGain / 100.0f); Real demod = 32768.0f * m_phaseDiscri.phaseDiscriminator(ci) * ((float) m_running.m_demodGain / 100.0f);
m_sampleCount++; m_sampleCount++;
// AF processing // AF processing
if (getMagSq() > m_squelchLevel) if (getMagSq() > m_squelchLevel)
{ {
if (m_squelchCount < m_squelchGate) if (m_squelchCount < m_squelchGate)
{ {
m_squelchCount++; m_squelchCount++;
} }
} }
else else
{ {
m_squelchCount = 0; m_squelchCount = 0;
} }
m_squelchOpen = m_squelchCount == m_squelchGate; m_squelchOpen = m_squelchCount == m_squelchGate;
if (m_squelchOpen) if (m_squelchOpen)
{ {
sample = demod; sample = demod;
} }
else else
{ {
sample = 0; sample = 0;
} }
Sample s(sample, 0.0); Sample s(sample, 0.0);
m_scopeSampleBuffer.push_back(s); m_scopeSampleBuffer.push_back(s);
m_dsdInBuffer[m_dsdInCount++] = sample; m_dsdInBuffer[m_dsdInCount++] = sample;
// if (m_running.m_audioMute) // if (m_running.m_audioMute)
// { // {
@ -170,9 +168,8 @@ void DSDDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
// m_audioBufferFill = 0; // m_audioBufferFill = 0;
// } // }
m_interpolatorDistanceRemain += m_interpolatorDistance; m_interpolatorDistanceRemain += m_interpolatorDistance;
} }
}
} }
@ -189,9 +186,9 @@ void DSDDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
// } // }
m_dsdDecoder.popAudioSamples(&m_audioFifo, m_running.m_audioMute); m_dsdDecoder.popAudioSamples(&m_audioFifo, m_running.m_audioMute);
m_dsdDecoder.pushSamples(m_dsdInCount); m_dsdDecoder.pushSamples(m_dsdInBuffer, m_dsdInCount);
if((m_scope != 0) && (m_scopeEnabled)) if ((m_scope != 0) && (m_scopeEnabled))
{ {
m_scope->feed(m_scopeSampleBuffer.begin(), m_scopeSampleBuffer.end(), true); // true = real samples for what it's worth m_scope->feed(m_scopeSampleBuffer.begin(), m_scopeSampleBuffer.end(), true); // true = real samples for what it's worth
} }