mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-18 07:35:47 -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
|
set(sdrbase_HEADERS
|
||||||
include/mainwindow.h
|
sdrbase/mainwindow.h
|
||||||
|
|
||||||
include/audio/audiodeviceinfo.h
|
sdrbase/audio/audiodeviceinfo.h
|
||||||
include/audio/audiofifo.h
|
sdrbase/audio/audiofifo.h
|
||||||
include/audio/audiooutput.h
|
sdrbase/audio/audiooutput.h
|
||||||
|
|
||||||
include/dsp/afsquelch.h
|
sdrbase/dsp/afsquelch.h
|
||||||
include/dsp/channelizer.h
|
sdrbase/dsp/channelizer.h
|
||||||
include/dsp/channelmarker.h
|
sdrbase/dsp/channelmarker.h
|
||||||
include/dsp/complex.h
|
sdrbase/dsp/complex.h
|
||||||
include/dsp/decimators.h
|
sdrbase/dsp/decimators.h
|
||||||
include/dsp/dspcommands.h
|
sdrbase/dsp/dspcommands.h
|
||||||
include/dsp/dspengine.h
|
sdrbase/dsp/dspengine.h
|
||||||
include/dsp/dspdeviceengine.h
|
sdrbase/dsp/dspdeviceengine.h
|
||||||
include/dsp/dsptypes.h
|
sdrbase/dsp/dsptypes.h
|
||||||
include/dsp/fftengine.h
|
sdrbase/dsp/fftengine.h
|
||||||
include/dsp/fftfilt.h
|
sdrbase/dsp/fftfilt.h
|
||||||
include/dsp/fftwengine.h
|
sdrbase/dsp/fftwengine.h
|
||||||
include/dsp/fftwindow.h
|
sdrbase/dsp/fftwindow.h
|
||||||
include/dsp/filterrc.h
|
sdrbase/dsp/filterrc.h
|
||||||
include/dsp/filesink.h
|
sdrbase/dsp/filesink.h
|
||||||
include/dsp/gfft.h
|
sdrbase/dsp/gfft.h
|
||||||
include/dsp/interpolator.h
|
sdrbase/dsp/interpolator.h
|
||||||
include/dsp/inthalfbandfilter.h
|
sdrbase/dsp/inthalfbandfilter.h
|
||||||
include/dsp/kissfft.h
|
sdrbase/dsp/kissfft.h
|
||||||
include/dsp/kissengine.h
|
sdrbase/dsp/kissengine.h
|
||||||
include/dsp/lowpass.h
|
sdrbase/dsp/lowpass.h
|
||||||
include/dsp/misc.h
|
sdrbase/dsp/misc.h
|
||||||
include/dsp/movingaverage.h
|
sdrbase/dsp/movingaverage.h
|
||||||
include/dsp/nco.h
|
sdrbase/dsp/nco.h
|
||||||
include/dsp/phasediscri.h
|
sdrbase/dsp/phasediscri.h
|
||||||
include/dsp/phaselock.h
|
sdrbase/dsp/phaselock.h
|
||||||
sdrbase/dsp/pidcontroller.h
|
sdrbase/dsp/pidcontroller.h
|
||||||
include/dsp/samplefifo.h
|
sdrbase/dsp/samplefifo.h
|
||||||
include/dsp/samplesink.h
|
sdrbase/dsp/samplesink.h
|
||||||
include/dsp/nullsink.h
|
sdrbase/dsp/nullsink.h
|
||||||
include/dsp/scopevis.h
|
sdrbase/dsp/scopevis.h
|
||||||
include/dsp/spectrumvis.h
|
sdrbase/dsp/spectrumvis.h
|
||||||
include/dsp/threadedsamplesink.h
|
sdrbase/dsp/threadedsamplesink.h
|
||||||
|
|
||||||
include/gui/aboutdialog.h
|
sdrbase/gui/aboutdialog.h
|
||||||
include/gui/addpresetdialog.h
|
sdrbase/gui/addpresetdialog.h
|
||||||
include/gui/basicchannelsettingswidget.h
|
sdrbase/gui/basicchannelsettingswidget.h
|
||||||
include/gui/buttonswitch.h
|
sdrbase/gui/buttonswitch.h
|
||||||
include/gui/channelwindow.h
|
sdrbase/gui/channelwindow.h
|
||||||
include/gui/colormapper.h
|
sdrbase/gui/colormapper.h
|
||||||
include/gui/glscope.h
|
sdrbase/gui/glscope.h
|
||||||
include/gui/glscopegui.h
|
sdrbase/gui/glscopegui.h
|
||||||
include/gui/glshadersimple.h
|
sdrbase/gui/glshadersimple.h
|
||||||
include/gui/glshadertextured.h
|
sdrbase/gui/glshadertextured.h
|
||||||
include/gui/glspectrum.h
|
sdrbase/gui/glspectrum.h
|
||||||
include/gui/glspectrumgui.h
|
sdrbase/gui/glspectrumgui.h
|
||||||
include/gui/indicator.h
|
sdrbase/gui/indicator.h
|
||||||
include/gui/physicalunit.h
|
sdrbase/gui/physicalunit.h
|
||||||
include/gui/pluginsdialog.h
|
sdrbase/gui/pluginsdialog.h
|
||||||
include/gui/preferencesdialog.h
|
sdrbase/gui/preferencesdialog.h
|
||||||
include/gui/presetitem.h
|
sdrbase/gui/presetitem.h
|
||||||
include/gui/rollupwidget.h
|
sdrbase/gui/rollupwidget.h
|
||||||
include/gui/scale.h
|
sdrbase/gui/scale.h
|
||||||
include/gui/scaleengine.h
|
sdrbase/gui/scaleengine.h
|
||||||
include/gui/valuedial.h
|
sdrbase/gui/valuedial.h
|
||||||
|
|
||||||
include/dsp/samplesource.h
|
sdrbase/dsp/samplesource.h
|
||||||
|
|
||||||
include/plugin/pluginapi.h
|
sdrbase/plugin/pluginapi.h
|
||||||
include/plugin/plugingui.h
|
sdrbase/plugin/plugingui.h
|
||||||
include/plugin/plugininterface.h
|
sdrbase/plugin/plugininterface.h
|
||||||
include/plugin/pluginmanager.h
|
sdrbase/plugin/pluginmanager.h
|
||||||
|
|
||||||
include/settings/preferences.h
|
sdrbase/settings/preferences.h
|
||||||
include/settings/preset.h
|
sdrbase/settings/preset.h
|
||||||
include/settings/mainsettings.h
|
sdrbase/settings/mainsettings.h
|
||||||
|
|
||||||
include/util/CRC64.h
|
sdrbase/util/CRC64.h
|
||||||
include/util/db.h
|
sdrbase/util/db.h
|
||||||
include/util/export.h
|
sdrbase/util/export.h
|
||||||
include/util/message.h
|
sdrbase/util/message.h
|
||||||
include/util/messagequeue.h
|
sdrbase/util/messagequeue.h
|
||||||
include/util/prettyprint.h
|
sdrbase/util/prettyprint.h
|
||||||
include/util/syncmessenger.h
|
sdrbase/util/syncmessenger.h
|
||||||
include/util/samplesourceserializer.h
|
sdrbase/util/samplesourceserializer.h
|
||||||
include/util/simpleserializer.h
|
sdrbase/util/simpleserializer.h
|
||||||
#include/util/spinlock.h
|
#sdrbase/util/spinlock.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(sdrbase_SOURCES
|
set(sdrbase_SOURCES
|
||||||
@ -268,7 +268,7 @@ if(FFTW3F_FOUND)
|
|||||||
)
|
)
|
||||||
set(sdrbase_HEADERS
|
set(sdrbase_HEADERS
|
||||||
${sdrbase_HEADERS}
|
${sdrbase_HEADERS}
|
||||||
include/dsp/fftwengine.h
|
sdrbase/dsp/fftwengine.h
|
||||||
)
|
)
|
||||||
add_definitions(-DUSE_FFTW)
|
add_definitions(-DUSE_FFTW)
|
||||||
include_directories(${FFTW3F_INCLUDE_DIRS})
|
include_directories(${FFTW3F_INCLUDE_DIRS})
|
||||||
@ -276,11 +276,11 @@ else(FFTW3F_FOUND)
|
|||||||
set(sdrbase_SOURCES
|
set(sdrbase_SOURCES
|
||||||
${sdrbase_SOURCES}
|
${sdrbase_SOURCES}
|
||||||
sdrbase/dsp/kissengine.cpp
|
sdrbase/dsp/kissengine.cpp
|
||||||
include/dsp/kissfft.h
|
sdrbase/dsp/kissfft.h
|
||||||
)
|
)
|
||||||
set(sdrbase_HEADERS
|
set(sdrbase_HEADERS
|
||||||
${sdrbase_HEADERS}
|
${sdrbase_HEADERS}
|
||||||
include/dsp/kissengine.h
|
sdrbase/dsp/kissengine.h
|
||||||
)
|
)
|
||||||
add_definitions(-DUSE_KISSFFT)
|
add_definitions(-DUSE_KISSFFT)
|
||||||
endif(FFTW3F_FOUND)
|
endif(FFTW3F_FOUND)
|
||||||
@ -319,8 +319,7 @@ qt5_use_modules(sdrbase Core Widgets OpenGL Multimedia)
|
|||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
${CMAKE_SOURCE_DIR}/include
|
${CMAKE_SOURCE_DIR}/sdrbase
|
||||||
${CMAKE_SOURCE_DIR}/include
|
|
||||||
${OPENGL_INCLUDE_DIR}
|
${OPENGL_INCLUDE_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -341,7 +340,7 @@ endif()
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
set(sdrangel_SOURCES
|
set(sdrangel_SOURCES
|
||||||
main.cpp
|
app/main.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(WIN32)
|
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