mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-17 23:28:50 -05:00
Reorganized sdrbase library code
This commit is contained in:
parent
837715fc0f
commit
c6d7207b1a
161
CMakeLists.txt
161
CMakeLists.txt
@ -155,89 +155,89 @@ set(sdrbase_SOURCES
|
||||
)
|
||||
|
||||
set(sdrbase_HEADERS
|
||||
include/mainwindow.h
|
||||
sdrbase/mainwindow.h
|
||||
|
||||
include/audio/audiodeviceinfo.h
|
||||
include/audio/audiofifo.h
|
||||
include/audio/audiooutput.h
|
||||
sdrbase/audio/audiodeviceinfo.h
|
||||
sdrbase/audio/audiofifo.h
|
||||
sdrbase/audio/audiooutput.h
|
||||
|
||||
include/dsp/afsquelch.h
|
||||
include/dsp/channelizer.h
|
||||
include/dsp/channelmarker.h
|
||||
include/dsp/complex.h
|
||||
include/dsp/decimators.h
|
||||
include/dsp/dspcommands.h
|
||||
include/dsp/dspengine.h
|
||||
include/dsp/dspdeviceengine.h
|
||||
include/dsp/dsptypes.h
|
||||
include/dsp/fftengine.h
|
||||
include/dsp/fftfilt.h
|
||||
include/dsp/fftwengine.h
|
||||
include/dsp/fftwindow.h
|
||||
include/dsp/filterrc.h
|
||||
include/dsp/filesink.h
|
||||
include/dsp/gfft.h
|
||||
include/dsp/interpolator.h
|
||||
include/dsp/inthalfbandfilter.h
|
||||
include/dsp/kissfft.h
|
||||
include/dsp/kissengine.h
|
||||
include/dsp/lowpass.h
|
||||
include/dsp/misc.h
|
||||
include/dsp/movingaverage.h
|
||||
include/dsp/nco.h
|
||||
include/dsp/phasediscri.h
|
||||
include/dsp/phaselock.h
|
||||
sdrbase/dsp/afsquelch.h
|
||||
sdrbase/dsp/channelizer.h
|
||||
sdrbase/dsp/channelmarker.h
|
||||
sdrbase/dsp/complex.h
|
||||
sdrbase/dsp/decimators.h
|
||||
sdrbase/dsp/dspcommands.h
|
||||
sdrbase/dsp/dspengine.h
|
||||
sdrbase/dsp/dspdeviceengine.h
|
||||
sdrbase/dsp/dsptypes.h
|
||||
sdrbase/dsp/fftengine.h
|
||||
sdrbase/dsp/fftfilt.h
|
||||
sdrbase/dsp/fftwengine.h
|
||||
sdrbase/dsp/fftwindow.h
|
||||
sdrbase/dsp/filterrc.h
|
||||
sdrbase/dsp/filesink.h
|
||||
sdrbase/dsp/gfft.h
|
||||
sdrbase/dsp/interpolator.h
|
||||
sdrbase/dsp/inthalfbandfilter.h
|
||||
sdrbase/dsp/kissfft.h
|
||||
sdrbase/dsp/kissengine.h
|
||||
sdrbase/dsp/lowpass.h
|
||||
sdrbase/dsp/misc.h
|
||||
sdrbase/dsp/movingaverage.h
|
||||
sdrbase/dsp/nco.h
|
||||
sdrbase/dsp/phasediscri.h
|
||||
sdrbase/dsp/phaselock.h
|
||||
sdrbase/dsp/pidcontroller.h
|
||||
include/dsp/samplefifo.h
|
||||
include/dsp/samplesink.h
|
||||
include/dsp/nullsink.h
|
||||
include/dsp/scopevis.h
|
||||
include/dsp/spectrumvis.h
|
||||
include/dsp/threadedsamplesink.h
|
||||
sdrbase/dsp/samplefifo.h
|
||||
sdrbase/dsp/samplesink.h
|
||||
sdrbase/dsp/nullsink.h
|
||||
sdrbase/dsp/scopevis.h
|
||||
sdrbase/dsp/spectrumvis.h
|
||||
sdrbase/dsp/threadedsamplesink.h
|
||||
|
||||
include/gui/aboutdialog.h
|
||||
include/gui/addpresetdialog.h
|
||||
include/gui/basicchannelsettingswidget.h
|
||||
include/gui/buttonswitch.h
|
||||
include/gui/channelwindow.h
|
||||
include/gui/colormapper.h
|
||||
include/gui/glscope.h
|
||||
include/gui/glscopegui.h
|
||||
include/gui/glshadersimple.h
|
||||
include/gui/glshadertextured.h
|
||||
include/gui/glspectrum.h
|
||||
include/gui/glspectrumgui.h
|
||||
include/gui/indicator.h
|
||||
include/gui/physicalunit.h
|
||||
include/gui/pluginsdialog.h
|
||||
include/gui/preferencesdialog.h
|
||||
include/gui/presetitem.h
|
||||
include/gui/rollupwidget.h
|
||||
include/gui/scale.h
|
||||
include/gui/scaleengine.h
|
||||
include/gui/valuedial.h
|
||||
sdrbase/gui/aboutdialog.h
|
||||
sdrbase/gui/addpresetdialog.h
|
||||
sdrbase/gui/basicchannelsettingswidget.h
|
||||
sdrbase/gui/buttonswitch.h
|
||||
sdrbase/gui/channelwindow.h
|
||||
sdrbase/gui/colormapper.h
|
||||
sdrbase/gui/glscope.h
|
||||
sdrbase/gui/glscopegui.h
|
||||
sdrbase/gui/glshadersimple.h
|
||||
sdrbase/gui/glshadertextured.h
|
||||
sdrbase/gui/glspectrum.h
|
||||
sdrbase/gui/glspectrumgui.h
|
||||
sdrbase/gui/indicator.h
|
||||
sdrbase/gui/physicalunit.h
|
||||
sdrbase/gui/pluginsdialog.h
|
||||
sdrbase/gui/preferencesdialog.h
|
||||
sdrbase/gui/presetitem.h
|
||||
sdrbase/gui/rollupwidget.h
|
||||
sdrbase/gui/scale.h
|
||||
sdrbase/gui/scaleengine.h
|
||||
sdrbase/gui/valuedial.h
|
||||
|
||||
include/dsp/samplesource.h
|
||||
sdrbase/dsp/samplesource.h
|
||||
|
||||
include/plugin/pluginapi.h
|
||||
include/plugin/plugingui.h
|
||||
include/plugin/plugininterface.h
|
||||
include/plugin/pluginmanager.h
|
||||
sdrbase/plugin/pluginapi.h
|
||||
sdrbase/plugin/plugingui.h
|
||||
sdrbase/plugin/plugininterface.h
|
||||
sdrbase/plugin/pluginmanager.h
|
||||
|
||||
include/settings/preferences.h
|
||||
include/settings/preset.h
|
||||
include/settings/mainsettings.h
|
||||
sdrbase/settings/preferences.h
|
||||
sdrbase/settings/preset.h
|
||||
sdrbase/settings/mainsettings.h
|
||||
|
||||
include/util/CRC64.h
|
||||
include/util/db.h
|
||||
include/util/export.h
|
||||
include/util/message.h
|
||||
include/util/messagequeue.h
|
||||
include/util/prettyprint.h
|
||||
include/util/syncmessenger.h
|
||||
include/util/samplesourceserializer.h
|
||||
include/util/simpleserializer.h
|
||||
#include/util/spinlock.h
|
||||
sdrbase/util/CRC64.h
|
||||
sdrbase/util/db.h
|
||||
sdrbase/util/export.h
|
||||
sdrbase/util/message.h
|
||||
sdrbase/util/messagequeue.h
|
||||
sdrbase/util/prettyprint.h
|
||||
sdrbase/util/syncmessenger.h
|
||||
sdrbase/util/samplesourceserializer.h
|
||||
sdrbase/util/simpleserializer.h
|
||||
#sdrbase/util/spinlock.h
|
||||
)
|
||||
|
||||
set(sdrbase_SOURCES
|
||||
@ -268,7 +268,7 @@ if(FFTW3F_FOUND)
|
||||
)
|
||||
set(sdrbase_HEADERS
|
||||
${sdrbase_HEADERS}
|
||||
include/dsp/fftwengine.h
|
||||
sdrbase/dsp/fftwengine.h
|
||||
)
|
||||
add_definitions(-DUSE_FFTW)
|
||||
include_directories(${FFTW3F_INCLUDE_DIRS})
|
||||
@ -276,11 +276,11 @@ else(FFTW3F_FOUND)
|
||||
set(sdrbase_SOURCES
|
||||
${sdrbase_SOURCES}
|
||||
sdrbase/dsp/kissengine.cpp
|
||||
include/dsp/kissfft.h
|
||||
sdrbase/dsp/kissfft.h
|
||||
)
|
||||
set(sdrbase_HEADERS
|
||||
${sdrbase_HEADERS}
|
||||
include/dsp/kissengine.h
|
||||
sdrbase/dsp/kissengine.h
|
||||
)
|
||||
add_definitions(-DUSE_KISSFFT)
|
||||
endif(FFTW3F_FOUND)
|
||||
@ -319,8 +319,7 @@ qt5_use_modules(sdrbase Core Widgets OpenGL Multimedia)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
${CMAKE_SOURCE_DIR}/sdrbase
|
||||
${OPENGL_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
@ -341,7 +340,7 @@ endif()
|
||||
##############################################################################
|
||||
|
||||
set(sdrangel_SOURCES
|
||||
main.cpp
|
||||
app/main.cpp
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
|
49
sdrbase/audio/audiodeviceinfo.h
Normal file
49
sdrbase/audio/audiodeviceinfo.h
Normal file
@ -0,0 +1,49 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
|
||||
// written by Christian Daniel //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_AUDIODEVICEINFO_H
|
||||
#define INCLUDE_AUDIODEVICEINFO_H
|
||||
|
||||
#include <QStringList>
|
||||
#include "util/export.h"
|
||||
|
||||
class SDRANGEL_API AudioDeviceInfo {
|
||||
public:
|
||||
struct Device {
|
||||
QString name;
|
||||
QString api;
|
||||
int id;
|
||||
|
||||
Device(const QString& _name, const QString& _api, int _id) :
|
||||
name(_name),
|
||||
api(_api),
|
||||
id(_id)
|
||||
{ }
|
||||
};
|
||||
typedef QList<Device> Devices;
|
||||
|
||||
AudioDeviceInfo();
|
||||
|
||||
int match(const QString& api, const QString device) const;
|
||||
|
||||
const Devices& getDevices() const { return m_devices; }
|
||||
|
||||
private:
|
||||
Devices m_devices;
|
||||
};
|
||||
|
||||
#endif // INCLUDE_AUDIODEVICEINFO_H
|
67
sdrbase/audio/audiofifo.h
Normal file
67
sdrbase/audio/audiofifo.h
Normal file
@ -0,0 +1,67 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
|
||||
// written by Christian Daniel //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_AUDIOFIFO_H
|
||||
#define INCLUDE_AUDIOFIFO_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMutex>
|
||||
#include <QWaitCondition>
|
||||
#include "util/export.h"
|
||||
|
||||
class SDRANGEL_API AudioFifo : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
AudioFifo();
|
||||
AudioFifo(uint sampleSize, uint numSamples);
|
||||
~AudioFifo();
|
||||
|
||||
bool setSize(uint sampleSize, uint numSamples);
|
||||
|
||||
uint write(const quint8* data, uint numSamples, int timeout_ms = INT_MAX);
|
||||
uint read(quint8* data, uint numSamples, int timeout_ms = INT_MAX);
|
||||
|
||||
uint drain(uint numSamples);
|
||||
void clear();
|
||||
|
||||
inline uint flush() { return drain(m_fill); }
|
||||
inline uint fill() const { return m_fill; }
|
||||
inline bool isEmpty() const { return m_fill == 0; }
|
||||
inline bool isFull() const { return m_fill == m_size; }
|
||||
inline uint size() const { return m_size; }
|
||||
|
||||
private:
|
||||
QMutex m_mutex;
|
||||
|
||||
qint8* m_fifo;
|
||||
|
||||
uint m_sampleSize;
|
||||
|
||||
uint m_size;
|
||||
uint m_fill;
|
||||
uint m_head;
|
||||
uint m_tail;
|
||||
|
||||
QMutex m_writeWaitLock;
|
||||
QMutex m_readWaitLock;
|
||||
QWaitCondition m_writeWaitCondition;
|
||||
QWaitCondition m_readWaitCondition;
|
||||
|
||||
bool create(uint sampleSize, uint numSamples);
|
||||
};
|
||||
|
||||
#endif // INCLUDE_AUDIOFIFO_H
|
62
sdrbase/audio/audiooutput.h
Normal file
62
sdrbase/audio/audiooutput.h
Normal file
@ -0,0 +1,62 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
|
||||
// written by Christian Daniel //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_AUDIOOUTPUT_H
|
||||
#define INCLUDE_AUDIOOUTPUT_H
|
||||
|
||||
#include <QMutex>
|
||||
#include <QIODevice>
|
||||
#include <QAudioFormat>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include "util/export.h"
|
||||
|
||||
class QAudioOutput;
|
||||
class AudioFifo;
|
||||
class AudioOutputPipe;
|
||||
|
||||
class SDRANGEL_API AudioOutput : QIODevice {
|
||||
public:
|
||||
AudioOutput();
|
||||
virtual ~AudioOutput();
|
||||
|
||||
bool start(int device, int rate);
|
||||
void stop();
|
||||
|
||||
void addFifo(AudioFifo* audioFifo);
|
||||
void removeFifo(AudioFifo* audioFifo);
|
||||
|
||||
uint getRate() const { return m_audioFormat.sampleRate(); }
|
||||
|
||||
private:
|
||||
QMutex m_mutex;
|
||||
QAudioOutput* m_audioOutput;
|
||||
|
||||
typedef std::list<AudioFifo*> AudioFifos;
|
||||
AudioFifos m_audioFifos;
|
||||
std::vector<qint32> m_mixBuffer;
|
||||
|
||||
QAudioFormat m_audioFormat;
|
||||
|
||||
//virtual bool open(OpenMode mode);
|
||||
virtual qint64 readData(char* data, qint64 maxLen);
|
||||
virtual qint64 writeData(const char* data, qint64 len);
|
||||
|
||||
friend class AudioOutputPipe;
|
||||
};
|
||||
|
||||
#endif // INCLUDE_AUDIOOUTPUT_H
|
90
sdrbase/dsp/afsquelch.h
Normal file
90
sdrbase/dsp/afsquelch.h
Normal file
@ -0,0 +1,90 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2015 Edouard Griffiths, F4EXB. //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_GPL_DSP_AFSQUELCH_H_
|
||||
#define INCLUDE_GPL_DSP_AFSQUELCH_H_
|
||||
|
||||
#include "dsp/dsptypes.h"
|
||||
#include "dsp/movingaverage.h"
|
||||
|
||||
/** AFSquelch: AF squelch class based on the Modified Goertzel
|
||||
* algorithm.
|
||||
*/
|
||||
class AFSquelch {
|
||||
public:
|
||||
// Constructors and Destructor
|
||||
AFSquelch();
|
||||
// allows user defined tone pair
|
||||
AFSquelch(unsigned int nbTones,
|
||||
const Real *tones);
|
||||
virtual ~AFSquelch();
|
||||
|
||||
// setup the basic parameters and coefficients
|
||||
void setCoefficients(
|
||||
int N, //!< the algorithm "block" size
|
||||
unsigned int nbAvg, //!< averaging size
|
||||
int SampleRate, //!< input signal sample rate
|
||||
int _samplesAttack, //!< number of results before squelch opens
|
||||
int _samplesDecay); //!< number of results keeping squelch open
|
||||
|
||||
// set the detection threshold
|
||||
void setThreshold(double _threshold);
|
||||
|
||||
// analyze a sample set and optionally filter
|
||||
// the tone frequencies.
|
||||
bool analyze(Real sample); // input signal sample
|
||||
bool evaluate(); // evaluate result
|
||||
|
||||
// get the tone set
|
||||
const Real *getToneSet() const
|
||||
{
|
||||
return m_toneSet;
|
||||
}
|
||||
|
||||
bool open() const {
|
||||
return m_isOpen;
|
||||
}
|
||||
|
||||
void reset(); // reset the analysis algorithm
|
||||
|
||||
protected:
|
||||
void feedback(Real sample);
|
||||
void feedForward();
|
||||
|
||||
private:
|
||||
unsigned int m_nbAvg; //!< number of power samples taken for moving average
|
||||
int m_N;
|
||||
int m_sampleRate;
|
||||
int m_samplesProcessed;
|
||||
int m_maxPowerIndex;
|
||||
int m_nTones;
|
||||
int m_samplesAttack;
|
||||
int m_attackCount;
|
||||
int m_samplesDecay;
|
||||
int m_decayCount;
|
||||
bool m_isOpen;
|
||||
double m_threshold;
|
||||
double *m_k;
|
||||
double *m_coef;
|
||||
Real *m_toneSet;
|
||||
double *m_u0;
|
||||
double *m_u1;
|
||||
double *m_power;
|
||||
std::vector<MovingAverage<Real> > m_movingAverages;
|
||||
};
|
||||
|
||||
|
||||
#endif /* INCLUDE_GPL_DSP_CTCSSDETECTOR_H_ */
|
128
sdrbase/dsp/agc.h
Normal file
128
sdrbase/dsp/agc.h
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* kissagc.h
|
||||
*
|
||||
* Created on: May 12, 2015
|
||||
* Author: f4exb
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_GPL_DSP_AGC_H_
|
||||
#define INCLUDE_GPL_DSP_AGC_H_
|
||||
|
||||
#include "movingaverage.h"
|
||||
|
||||
class AGC
|
||||
{
|
||||
public:
|
||||
|
||||
AGC();
|
||||
AGC(int historySize, Real R);
|
||||
virtual ~AGC();
|
||||
|
||||
void resize(int historySize, Real R);
|
||||
Real getValue();
|
||||
Real getAverage();
|
||||
virtual void feed(Complex& ci) = 0;
|
||||
|
||||
protected:
|
||||
Real m_u0;
|
||||
Real m_R; // objective mag
|
||||
MovingAverage<Real> m_moving_average; // Averaging engine. The stack length conditions the smoothness of AGC.
|
||||
int m_historySize;
|
||||
int m_count;
|
||||
};
|
||||
|
||||
class MagSquaredAGC : public AGC
|
||||
{
|
||||
public:
|
||||
MagSquaredAGC();
|
||||
MagSquaredAGC(int historySize, Real R);
|
||||
virtual ~MagSquaredAGC();
|
||||
virtual void feed(Complex& ci);
|
||||
Real getMagSq() const { return m_magsq; }
|
||||
private:
|
||||
Real m_magsq;
|
||||
};
|
||||
|
||||
class MagAGC : public AGC
|
||||
{
|
||||
public:
|
||||
MagAGC();
|
||||
MagAGC(int historySize, Real R);
|
||||
virtual ~MagAGC();
|
||||
virtual void feed(Complex& ci);
|
||||
Real getMagSq() const { return m_magsq; }
|
||||
private:
|
||||
Real m_magsq;
|
||||
};
|
||||
|
||||
class AlphaAGC : public AGC
|
||||
{
|
||||
public:
|
||||
AlphaAGC();
|
||||
AlphaAGC(int historySize, Real R);
|
||||
AlphaAGC(int historySize, Real R, Real alpha);
|
||||
virtual ~AlphaAGC();
|
||||
void resize(int historySize, Real R, Real alpha);
|
||||
virtual void feed(Complex& ci);
|
||||
Real getMagSq() const { return m_magsq; }
|
||||
private:
|
||||
Real m_alpha;
|
||||
Real m_magsq;
|
||||
bool m_squelchOpen;
|
||||
};
|
||||
|
||||
class SimpleAGC
|
||||
{
|
||||
public:
|
||||
SimpleAGC() :
|
||||
m_squelchOpen(false),
|
||||
m_fill(0),
|
||||
m_cutoff(0),
|
||||
m_clip(0),
|
||||
m_moving_average()
|
||||
{}
|
||||
|
||||
SimpleAGC(int historySize, Real initial, Real cutoff=0, Real clip=0) :
|
||||
m_squelchOpen(false),
|
||||
m_fill(initial),
|
||||
m_cutoff(cutoff),
|
||||
m_clip(clip),
|
||||
m_moving_average(historySize, initial)
|
||||
{}
|
||||
|
||||
void resize(int historySize, Real initial, Real cutoff=0, Real clip=0)
|
||||
{
|
||||
m_fill = initial;
|
||||
m_cutoff = cutoff;
|
||||
m_clip = clip;
|
||||
m_moving_average.resize(historySize, initial);
|
||||
}
|
||||
|
||||
Real getValue()
|
||||
{
|
||||
if (m_moving_average.average() > m_clip)
|
||||
{
|
||||
return m_moving_average.average();
|
||||
} else
|
||||
{
|
||||
return m_clip;
|
||||
}
|
||||
}
|
||||
|
||||
void feed(Real value)
|
||||
{
|
||||
if (value > m_cutoff)
|
||||
{
|
||||
m_moving_average.feed(value);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_squelchOpen; // open for processing
|
||||
Real m_fill; // refill average at this level
|
||||
Real m_cutoff; // consider samples only above this level
|
||||
Real m_clip; // never go below this level
|
||||
MovingAverage<Real> m_moving_average; // Averaging engine. The stack length conditions the smoothness of AGC.
|
||||
};
|
||||
|
||||
#endif /* INCLUDE_GPL_DSP_AGC_H_ */
|
127
sdrbase/dsp/bandpass.h
Normal file
127
sdrbase/dsp/bandpass.h
Normal file
@ -0,0 +1,127 @@
|
||||
#ifndef INCLUDE_BANDPASS_H
|
||||
#define INCLUDE_BANDPASS_H
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
#include "dsp/dsptypes.h"
|
||||
|
||||
template <class Type> class Bandpass {
|
||||
public:
|
||||
Bandpass() { }
|
||||
|
||||
void create(int nTaps, double sampleRate, double lowCutoff, double highCutoff)
|
||||
{
|
||||
std::vector<Real> taps_lp;
|
||||
std::vector<Real> taps_hp;
|
||||
double wcl = 2.0 * M_PI * lowCutoff;
|
||||
double Wcl = wcl / sampleRate;
|
||||
double wch = 2.0 * M_PI * highCutoff;
|
||||
double Wch = wch / sampleRate;
|
||||
int i;
|
||||
|
||||
// check constraints
|
||||
if(!(nTaps & 1)) {
|
||||
qDebug("Bandpass filter has to have an odd number of taps");
|
||||
nTaps++;
|
||||
}
|
||||
|
||||
// make room
|
||||
m_samples.resize(nTaps);
|
||||
for(int i = 0; i < nTaps; i++)
|
||||
m_samples[i] = 0;
|
||||
m_ptr = 0;
|
||||
m_taps.resize(nTaps / 2 + 1);
|
||||
taps_lp.resize(nTaps / 2 + 1);
|
||||
taps_hp.resize(nTaps / 2 + 1);
|
||||
|
||||
// generate Sinc filter core
|
||||
for(i = 0; i < nTaps / 2 + 1; i++) {
|
||||
if(i == (nTaps - 1) / 2) {
|
||||
taps_lp[i] = Wch / M_PI;
|
||||
taps_hp[i] = -(Wcl / M_PI);
|
||||
}
|
||||
else {
|
||||
taps_lp[i] = sin(((double)i - ((double)nTaps - 1.0) / 2.0) * Wch) / (((double)i - ((double)nTaps - 1.0) / 2.0) * M_PI);
|
||||
taps_hp[i] = -sin(((double)i - ((double)nTaps - 1.0) / 2.0) * Wcl) / (((double)i - ((double)nTaps - 1.0) / 2.0) * M_PI);
|
||||
}
|
||||
}
|
||||
|
||||
taps_hp[(nTaps - 1) / 2] += 1;
|
||||
|
||||
// apply Hamming window and combine lowpass and highpass
|
||||
for(i = 0; i < nTaps / 2 + 1; i++) {
|
||||
taps_lp[i] *= 0.54 + 0.46 * cos((2.0 * M_PI * ((double)i - ((double)nTaps - 1.0) / 2.0)) / (double)nTaps);
|
||||
taps_hp[i] *= 0.54 + 0.46 * cos((2.0 * M_PI * ((double)i - ((double)nTaps - 1.0) / 2.0)) / (double)nTaps);
|
||||
m_taps[i] = -(taps_lp[i]+taps_hp[i]);
|
||||
}
|
||||
|
||||
m_taps[(nTaps - 1) / 2] += 1;
|
||||
|
||||
// normalize
|
||||
Real sum = 0;
|
||||
|
||||
for(i = 0; i < (int)m_taps.size() - 1; i++) {
|
||||
sum += m_taps[i] * 2;
|
||||
}
|
||||
|
||||
sum += m_taps[i];
|
||||
|
||||
for(i = 0; i < (int)m_taps.size(); i++) {
|
||||
m_taps[i] /= sum;
|
||||
}
|
||||
}
|
||||
|
||||
Type filter(Type sample)
|
||||
{
|
||||
Type acc = 0;
|
||||
int a = m_ptr;
|
||||
int b = a - 1;
|
||||
int i, n_taps, size;
|
||||
|
||||
m_samples[m_ptr] = sample;
|
||||
size = m_samples.size(); // Valgrind optim (2)
|
||||
|
||||
while(b < 0)
|
||||
{
|
||||
b += size;
|
||||
}
|
||||
|
||||
n_taps = m_taps.size() - 1; // Valgrind optim
|
||||
|
||||
for(i = 0; i < n_taps; i++)
|
||||
{
|
||||
acc += (m_samples[a] + m_samples[b]) * m_taps[i];
|
||||
a++;
|
||||
|
||||
while (a >= size)
|
||||
{
|
||||
a -= size;
|
||||
}
|
||||
|
||||
b--;
|
||||
|
||||
while(b < 0)
|
||||
{
|
||||
b += size;
|
||||
}
|
||||
}
|
||||
|
||||
acc += m_samples[a] * m_taps[i];
|
||||
|
||||
m_ptr++;
|
||||
|
||||
while (m_ptr >= size)
|
||||
{
|
||||
m_ptr -= size;
|
||||
}
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Real> m_taps;
|
||||
std::vector<Type> m_samples;
|
||||
int m_ptr;
|
||||
};
|
||||
|
||||
#endif // INCLUDE_BANDPASS_H
|
85
sdrbase/dsp/channelizer.h
Normal file
85
sdrbase/dsp/channelizer.h
Normal file
@ -0,0 +1,85 @@
|
||||
#ifndef INCLUDE_CHANNELIZER_H
|
||||
#define INCLUDE_CHANNELIZER_H
|
||||
|
||||
#include <list>
|
||||
#include <QMutex>
|
||||
#include "dsp/samplesink.h"
|
||||
#include "util/export.h"
|
||||
#include "util/message.h"
|
||||
|
||||
class MessageQueue;
|
||||
class IntHalfbandFilter;
|
||||
|
||||
class SDRANGEL_API Channelizer : public SampleSink {
|
||||
Q_OBJECT
|
||||
public:
|
||||
class SDRANGEL_API MsgChannelizerNotification : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
MsgChannelizerNotification(int samplerate, qint64 frequencyOffset) :
|
||||
Message(),
|
||||
m_sampleRate(samplerate),
|
||||
m_frequencyOffset(frequencyOffset)
|
||||
{ }
|
||||
|
||||
int getSampleRate() const { return m_sampleRate; }
|
||||
qint64 getFrequencyOffset() const { return m_frequencyOffset; }
|
||||
|
||||
private:
|
||||
int m_sampleRate;
|
||||
qint64 m_frequencyOffset;
|
||||
};
|
||||
|
||||
Channelizer(SampleSink* sampleSink);
|
||||
virtual ~Channelizer();
|
||||
|
||||
void configure(MessageQueue* messageQueue, int sampleRate, int centerFrequency);
|
||||
int getInputSampleRate() const { return m_inputSampleRate; }
|
||||
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
|
||||
virtual bool handleMessage(const Message& cmd);
|
||||
|
||||
protected:
|
||||
struct FilterStage {
|
||||
enum Mode {
|
||||
ModeCenter,
|
||||
ModeLowerHalf,
|
||||
ModeUpperHalf
|
||||
};
|
||||
|
||||
typedef bool (IntHalfbandFilter::*WorkFunction)(Sample* s);
|
||||
IntHalfbandFilter* m_filter;
|
||||
WorkFunction m_workFunction;
|
||||
|
||||
FilterStage(Mode mode);
|
||||
~FilterStage();
|
||||
|
||||
bool work(Sample* sample)
|
||||
{
|
||||
return (m_filter->*m_workFunction)(sample);
|
||||
}
|
||||
};
|
||||
typedef std::list<FilterStage*> FilterStages;
|
||||
FilterStages m_filterStages;
|
||||
SampleSink* m_sampleSink;
|
||||
int m_inputSampleRate;
|
||||
int m_requestedOutputSampleRate;
|
||||
int m_requestedCenterFrequency;
|
||||
int m_currentOutputSampleRate;
|
||||
int m_currentCenterFrequency;
|
||||
SampleVector m_sampleBuffer;
|
||||
QMutex m_mutex;
|
||||
|
||||
void applyConfiguration();
|
||||
bool signalContainsChannel(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd) const;
|
||||
Real createFilterChain(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd);
|
||||
void freeFilterChain();
|
||||
|
||||
signals:
|
||||
void inputSampleRateChanged();
|
||||
};
|
||||
|
||||
#endif // INCLUDE_CHANNELIZER_H
|
62
sdrbase/dsp/channelmarker.h
Normal file
62
sdrbase/dsp/channelmarker.h
Normal file
@ -0,0 +1,62 @@
|
||||
#ifndef INCLUDE_CHANNELMARKER_H
|
||||
#define INCLUDE_CHANNELMARKER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QColor>
|
||||
#include "util/export.h"
|
||||
|
||||
class SDRANGEL_API ChannelMarker : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
typedef enum sidebands_e
|
||||
{
|
||||
dsb,
|
||||
lsb,
|
||||
usb
|
||||
} sidebands_t;
|
||||
|
||||
ChannelMarker(QObject* parent = NULL);
|
||||
|
||||
void setTitle(const QString& title);
|
||||
const QString& getTitle() const { return m_title; }
|
||||
|
||||
void setCenterFrequency(int centerFrequency);
|
||||
int getCenterFrequency() const { return m_centerFrequency; }
|
||||
|
||||
void setBandwidth(int bandwidth);
|
||||
int getBandwidth() const { return m_bandwidth; }
|
||||
|
||||
void setLowCutoff(int lowCutoff);
|
||||
int getLowCutoff() const { return m_lowCutoff; }
|
||||
|
||||
void setSidebands(sidebands_t sidebands);
|
||||
sidebands_t getSidebands() const { return m_sidebands; }
|
||||
|
||||
void setVisible(bool visible);
|
||||
bool getVisible() const { return m_visible; }
|
||||
|
||||
void setHighlighted(bool highlighted);
|
||||
bool getHighlighted() const { return m_highlighted; }
|
||||
|
||||
void setColor(const QColor& color);
|
||||
const QColor& getColor() const { return m_color; }
|
||||
|
||||
protected:
|
||||
static QRgb m_colorTable[];
|
||||
static int m_nextColor;
|
||||
|
||||
QString m_title;
|
||||
int m_centerFrequency;
|
||||
int m_bandwidth;
|
||||
int m_lowCutoff;
|
||||
sidebands_t m_sidebands;
|
||||
bool m_visible;
|
||||
bool m_highlighted;
|
||||
QColor m_color;
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
};
|
||||
|
||||
#endif // INCLUDE_CHANNELMARKER_H
|
43
sdrbase/dsp/complex.h
Normal file
43
sdrbase/dsp/complex.h
Normal file
@ -0,0 +1,43 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// complex.h -- Complex arithmetic
|
||||
//
|
||||
// Copyright (C) 2006-2008
|
||||
// Dave Freese, W1HKJ
|
||||
// Copyright (C) 2008
|
||||
// Stelios Bounanos, M0GLD
|
||||
//
|
||||
// This file is part of fldigi.
|
||||
//
|
||||
// Fldigi is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Fldigi is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with fldigi. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _COMPLEX_H
|
||||
#define _COMPLEX_H
|
||||
|
||||
#include <cmath>
|
||||
#include <complex>
|
||||
|
||||
typedef std::complex<float> cmplx;
|
||||
|
||||
inline cmplx cmac (const cmplx *a, const cmplx *b, int ptr, int len) {
|
||||
cmplx z;
|
||||
ptr %= len;
|
||||
for (int i = 0; i < len; i++) {
|
||||
z += a[i] * b[ptr];
|
||||
ptr = (ptr + 1) % len;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
#endif
|
88
sdrbase/dsp/ctcssdetector.h
Normal file
88
sdrbase/dsp/ctcssdetector.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* ctcssdetector.h
|
||||
*
|
||||
* Created on: Jun 16, 2015
|
||||
* Author: f4exb
|
||||
* See: http://www.embedded.com/design/connectivity/4025660/Detecting-CTCSS-tones-with-Goertzel-s-algorithm
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_GPL_DSP_CTCSSDETECTOR_H_
|
||||
#define INCLUDE_GPL_DSP_CTCSSDETECTOR_H_
|
||||
|
||||
#include "dsp/dsptypes.h"
|
||||
|
||||
/** CTCSSDetector: Continuous Tone Coded Squelch System
|
||||
* tone detector class based on the Modified Goertzel
|
||||
* algorithm.
|
||||
*/
|
||||
class CTCSSDetector {
|
||||
public:
|
||||
// Constructors and Destructor
|
||||
CTCSSDetector();
|
||||
// allows user defined CTCSS tone set
|
||||
CTCSSDetector(int _nTones, Real *tones);
|
||||
virtual ~CTCSSDetector();
|
||||
|
||||
// setup the basic parameters and coefficients
|
||||
void setCoefficients(
|
||||
int zN, // the algorithm "block" size
|
||||
int SampleRate); // input signal sample rate
|
||||
|
||||
// set the detection threshold
|
||||
void setThreshold(double thold);
|
||||
|
||||
// analyze a sample set and optionally filter
|
||||
// the tone frequencies.
|
||||
bool analyze(Real *sample); // input signal sample
|
||||
|
||||
// get the number of defined tones.
|
||||
int getNTones() const {
|
||||
return nTones;
|
||||
}
|
||||
|
||||
// get the tone set
|
||||
const Real *getToneSet() const
|
||||
{
|
||||
return toneSet;
|
||||
}
|
||||
|
||||
// get the currently detected tone, if any
|
||||
bool getDetectedTone(int &maxTone) const
|
||||
{
|
||||
maxTone = maxPowerIndex;
|
||||
return toneDetected;
|
||||
}
|
||||
|
||||
// Get the max power at the detected tone.
|
||||
Real getMaxPower() const
|
||||
{
|
||||
return maxPower;
|
||||
}
|
||||
|
||||
void reset(); // reset the analysis algorithm
|
||||
|
||||
protected:
|
||||
// Override these to change behavior of the detector
|
||||
virtual void initializePower();
|
||||
virtual void evaluatePower();
|
||||
void feedback(Real sample);
|
||||
void feedForward();
|
||||
|
||||
private:
|
||||
int N;
|
||||
int sampleRate;
|
||||
int nTones;
|
||||
int samplesProcessed;
|
||||
int maxPowerIndex;
|
||||
bool toneDetected;
|
||||
Real maxPower;
|
||||
Real *k;
|
||||
Real *coef;
|
||||
Real *toneSet;
|
||||
Real *u0;
|
||||
Real *u1;
|
||||
Real *power;
|
||||
};
|
||||
|
||||
|
||||
#endif /* INCLUDE_GPL_DSP_CTCSSDETECTOR_H_ */
|
1538
sdrbase/dsp/decimators.h
Normal file
1538
sdrbase/dsp/decimators.h
Normal file
File diff suppressed because it is too large
Load Diff
268
sdrbase/dsp/dspcommands.h
Normal file
268
sdrbase/dsp/dspcommands.h
Normal file
@ -0,0 +1,268 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2015 F4EXB //
|
||||
// written by Edouard Griffiths //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_DSPCOMMANDS_H
|
||||
#define INCLUDE_DSPCOMMANDS_H
|
||||
|
||||
#include <QString>
|
||||
#include "util/message.h"
|
||||
#include "fftwindow.h"
|
||||
#include "util/export.h"
|
||||
|
||||
class SampleSource;
|
||||
class SampleSink;
|
||||
class ThreadedSampleSink;
|
||||
class AudioFifo;
|
||||
|
||||
class SDRANGEL_API DSPExit : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
};
|
||||
|
||||
class SDRANGEL_API DSPAcquisitionInit : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
};
|
||||
|
||||
class SDRANGEL_API DSPAcquisitionStart : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
};
|
||||
|
||||
class SDRANGEL_API DSPAcquisitionStop : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
};
|
||||
|
||||
class SDRANGEL_API DSPGetSourceDeviceDescription : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
void setDeviceDescription(const QString& text) { m_deviceDescription = text; }
|
||||
const QString& getDeviceDescription() const { return m_deviceDescription; }
|
||||
|
||||
private:
|
||||
QString m_deviceDescription;
|
||||
};
|
||||
|
||||
class SDRANGEL_API DSPGetErrorMessage : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
void setErrorMessage(const QString& text) { m_errorMessage = text; }
|
||||
const QString& getErrorMessage() const { return m_errorMessage; }
|
||||
|
||||
private:
|
||||
QString m_errorMessage;
|
||||
};
|
||||
|
||||
class SDRANGEL_API DSPSetSource : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
DSPSetSource(SampleSource* sampleSource) : Message(), m_sampleSource(sampleSource) { }
|
||||
|
||||
SampleSource* getSampleSource() const { return m_sampleSource; }
|
||||
|
||||
private:
|
||||
SampleSource* m_sampleSource;
|
||||
};
|
||||
|
||||
class SDRANGEL_API DSPAddSink : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
DSPAddSink(SampleSink* sampleSink) : Message(), m_sampleSink(sampleSink) { }
|
||||
|
||||
SampleSink* getSampleSink() const { return m_sampleSink; }
|
||||
|
||||
private:
|
||||
SampleSink* m_sampleSink;
|
||||
};
|
||||
|
||||
class SDRANGEL_API DSPRemoveSink : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
DSPRemoveSink(SampleSink* sampleSink) : Message(), m_sampleSink(sampleSink) { }
|
||||
|
||||
SampleSink* getSampleSink() const { return m_sampleSink; }
|
||||
|
||||
private:
|
||||
SampleSink* m_sampleSink;
|
||||
};
|
||||
|
||||
class SDRANGEL_API DSPAddThreadedSampleSink : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
DSPAddThreadedSampleSink(ThreadedSampleSink* threadedSampleSink) : Message(), m_threadedSampleSink(threadedSampleSink) { }
|
||||
|
||||
ThreadedSampleSink* getThreadedSampleSink() const { return m_threadedSampleSink; }
|
||||
|
||||
private:
|
||||
ThreadedSampleSink* m_threadedSampleSink;
|
||||
};
|
||||
|
||||
class SDRANGEL_API DSPRemoveThreadedSampleSink : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
DSPRemoveThreadedSampleSink(ThreadedSampleSink* threadedSampleSink) : Message(), m_threadedSampleSink(threadedSampleSink) { }
|
||||
|
||||
ThreadedSampleSink* getThreadedSampleSink() const { return m_threadedSampleSink; }
|
||||
|
||||
private:
|
||||
ThreadedSampleSink* m_threadedSampleSink;
|
||||
};
|
||||
|
||||
class SDRANGEL_API DSPAddAudioSink : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
DSPAddAudioSink(AudioFifo* audioFifo) : Message(), m_audioFifo(audioFifo) { }
|
||||
|
||||
AudioFifo* getAudioFifo() const { return m_audioFifo; }
|
||||
|
||||
private:
|
||||
AudioFifo* m_audioFifo;
|
||||
};
|
||||
|
||||
class SDRANGEL_API DSPRemoveAudioSink : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
DSPRemoveAudioSink(AudioFifo* audioFifo) : Message(), m_audioFifo(audioFifo) { }
|
||||
|
||||
AudioFifo* getAudioFifo() const { return m_audioFifo; }
|
||||
|
||||
private:
|
||||
AudioFifo* m_audioFifo;
|
||||
};
|
||||
|
||||
class SDRANGEL_API DSPConfigureSpectrumVis : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
DSPConfigureSpectrumVis(int fftSize, int overlapPercent, FFTWindow::Function window) :
|
||||
Message(),
|
||||
m_fftSize(fftSize),
|
||||
m_overlapPercent(overlapPercent),
|
||||
m_window(window)
|
||||
{ }
|
||||
|
||||
int getFFTSize() const { return m_fftSize; }
|
||||
int getOverlapPercent() const { return m_overlapPercent; }
|
||||
FFTWindow::Function getWindow() const { return m_window; }
|
||||
|
||||
private:
|
||||
int m_fftSize;
|
||||
int m_overlapPercent;
|
||||
FFTWindow::Function m_window;
|
||||
};
|
||||
|
||||
class SDRANGEL_API DSPConfigureCorrection : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
DSPConfigureCorrection(bool dcOffsetCorrection, bool iqImbalanceCorrection) :
|
||||
Message(),
|
||||
m_dcOffsetCorrection(dcOffsetCorrection),
|
||||
m_iqImbalanceCorrection(iqImbalanceCorrection)
|
||||
{ }
|
||||
|
||||
bool getDCOffsetCorrection() const { return m_dcOffsetCorrection; }
|
||||
bool getIQImbalanceCorrection() const { return m_iqImbalanceCorrection; }
|
||||
|
||||
private:
|
||||
bool m_dcOffsetCorrection;
|
||||
bool m_iqImbalanceCorrection;
|
||||
|
||||
};
|
||||
|
||||
class SDRANGEL_API DSPEngineReport : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
DSPEngineReport(int sampleRate, quint64 centerFrequency) :
|
||||
Message(),
|
||||
m_sampleRate(sampleRate),
|
||||
m_centerFrequency(centerFrequency)
|
||||
{ }
|
||||
|
||||
int getSampleRate() const { return m_sampleRate; }
|
||||
quint64 getCenterFrequency() const { return m_centerFrequency; }
|
||||
|
||||
private:
|
||||
int m_sampleRate;
|
||||
quint64 m_centerFrequency;
|
||||
};
|
||||
|
||||
class SDRANGEL_API DSPConfigureScopeVis : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
DSPConfigureScopeVis(int triggerChannel, Real triggerLevelHigh, Real triggerLevelLow) :
|
||||
Message(),
|
||||
m_triggerChannel(triggerChannel),
|
||||
m_triggerLevelHigh(triggerLevelHigh),
|
||||
m_triggerLevelLow(triggerLevelLow)
|
||||
{ }
|
||||
|
||||
int getTriggerChannel() const { return m_triggerChannel; }
|
||||
Real getTriggerLevelHigh() const { return m_triggerLevelHigh; }
|
||||
Real getTriggerLevelLow() const { return m_triggerLevelLow; }
|
||||
|
||||
private:
|
||||
int m_triggerChannel;
|
||||
Real m_triggerLevelHigh;
|
||||
Real m_triggerLevelLow;
|
||||
};
|
||||
|
||||
class SDRANGEL_API DSPSignalNotification : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
DSPSignalNotification(int samplerate, qint64 centerFrequency) :
|
||||
Message(),
|
||||
m_sampleRate(samplerate),
|
||||
m_centerFrequency(centerFrequency)
|
||||
{ }
|
||||
|
||||
int getSampleRate() const { return m_sampleRate; }
|
||||
qint64 getCenterFrequency() const { return m_centerFrequency; }
|
||||
|
||||
private:
|
||||
int m_sampleRate;
|
||||
qint64 m_centerFrequency;
|
||||
};
|
||||
|
||||
class SDRANGEL_API DSPConfigureChannelizer : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
DSPConfigureChannelizer(int sampleRate, int centerFrequency) :
|
||||
Message(),
|
||||
m_sampleRate(sampleRate),
|
||||
m_centerFrequency(centerFrequency)
|
||||
{ }
|
||||
|
||||
int getSampleRate() const { return m_sampleRate; }
|
||||
int getCenterFrequency() const { return m_centerFrequency; }
|
||||
|
||||
private:
|
||||
int m_sampleRate;
|
||||
int m_centerFrequency;
|
||||
};
|
||||
|
||||
#endif // INCLUDE_DSPCOMMANDS_H
|
125
sdrbase/dsp/dspdeviceengine.h
Normal file
125
sdrbase/dsp/dspdeviceengine.h
Normal file
@ -0,0 +1,125 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2015 F4EXB //
|
||||
// written by Edouard Griffiths //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_DSPDEVICEENGINE_H
|
||||
#define INCLUDE_DSPDEVICEENGINE_H
|
||||
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
#include <QMutex>
|
||||
#include <QWaitCondition>
|
||||
#include "dsp/dsptypes.h"
|
||||
#include "dsp/fftwindow.h"
|
||||
#include "dsp/samplefifo.h"
|
||||
#include "util/messagequeue.h"
|
||||
#include "util/syncmessenger.h"
|
||||
#include "util/export.h"
|
||||
|
||||
class SampleSource;
|
||||
class SampleSink;
|
||||
class ThreadedSampleSink;
|
||||
|
||||
class SDRANGEL_API DSPDeviceEngine : public QThread {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum State {
|
||||
StNotStarted, //!< engine is before initialization
|
||||
StIdle, //!< engine is idle
|
||||
StReady, //!< engine is ready to run
|
||||
StRunning, //!< engine is running
|
||||
StError //!< engine is in error
|
||||
};
|
||||
|
||||
DSPDeviceEngine(QObject* parent = NULL);
|
||||
~DSPDeviceEngine();
|
||||
|
||||
MessageQueue* getInputMessageQueue() { return &m_inputMessageQueue; }
|
||||
MessageQueue* getOutputMessageQueue() { return &m_outputMessageQueue; }
|
||||
|
||||
void start(); //!< This thread start
|
||||
void stop(); //!< This thread stop
|
||||
|
||||
bool initAcquisition(); //!< Initialize acquisition sequence
|
||||
bool startAcquisition(); //!< Start acquisition sequence
|
||||
void stopAcquistion(); //!< Stop acquisition sequence
|
||||
|
||||
void setSource(SampleSource* source); //!< Set the sample source type
|
||||
void setSourceSequence(int sequence); //!< Set the sample source sequence in type
|
||||
|
||||
void addSink(SampleSink* sink); //!< Add a sample sink
|
||||
void removeSink(SampleSink* sink); //!< Remove a sample sink
|
||||
|
||||
void addThreadedSink(ThreadedSampleSink* sink); //!< Add a sample sink that will run on its own thread
|
||||
void removeThreadedSink(ThreadedSampleSink* sink); //!< Remove a sample sink that runs on its own thread
|
||||
|
||||
void configureCorrections(bool dcOffsetCorrection, bool iqImbalanceCorrection); //!< Configure DSP corrections
|
||||
|
||||
State state() const { return m_state; } //!< Return DSP engine current state
|
||||
|
||||
QString errorMessage(); //!< Return the current error message
|
||||
QString sourceDeviceDescription(); //!< Return the source device description
|
||||
|
||||
private:
|
||||
MessageQueue m_inputMessageQueue; //<! Input message queue. Post here.
|
||||
MessageQueue m_outputMessageQueue; //<! Output message queue. Listen here.
|
||||
SyncMessenger m_syncMessenger; //!< Used to process messages synchronously with the thread
|
||||
|
||||
State m_state;
|
||||
|
||||
QString m_errorMessage;
|
||||
QString m_deviceDescription;
|
||||
|
||||
SampleSource* m_sampleSource;
|
||||
int m_sampleSourceSequence;
|
||||
|
||||
typedef std::list<SampleSink*> SampleSinks;
|
||||
SampleSinks m_sampleSinks; //!< sample sinks within main thread (usually spectrum, file output)
|
||||
|
||||
typedef std::list<ThreadedSampleSink*> ThreadedSampleSinks;
|
||||
ThreadedSampleSinks m_threadedSampleSinks; //!< sample sinks on their own threads (usually channels)
|
||||
|
||||
uint m_sampleRate;
|
||||
quint64 m_centerFrequency;
|
||||
|
||||
bool m_dcOffsetCorrection;
|
||||
bool m_iqImbalanceCorrection;
|
||||
double m_iOffset, m_qOffset;
|
||||
qint32 m_iRange;
|
||||
qint32 m_qRange;
|
||||
qint32 m_imbalance;
|
||||
|
||||
void run();
|
||||
|
||||
void dcOffset(SampleVector::iterator begin, SampleVector::iterator end);
|
||||
void imbalance(SampleVector::iterator begin, SampleVector::iterator end);
|
||||
void work(); //!< transfer samples from source to sinks if in running state
|
||||
|
||||
State gotoIdle(); //!< Go to the idle state
|
||||
State gotoInit(); //!< Go to the acquisition init state from idle
|
||||
State gotoRunning(); //!< Go to the running state from ready state
|
||||
State gotoError(const QString& errorMsg); //!< Go to an error state
|
||||
|
||||
void handleSetSource(SampleSource* source); //!< Manage source setting
|
||||
|
||||
private slots:
|
||||
void handleData(); //!< Handle data when samples from source FIFO are ready to be processed
|
||||
void handleInputMessages(); //!< Handle input message queue
|
||||
void handleSynchronousMessages(); //!< Handle synchronous messages with the thread
|
||||
};
|
||||
|
||||
#endif // INCLUDE_DSPDEVICEENGINE_H
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user