Reorganized sdrbase library code

This commit is contained in:
f4exb 2016-03-08 04:54:12 +01:00
parent 837715fc0f
commit c6d7207b1a
171 changed files with 11529 additions and 81 deletions

View File

@ -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)

View 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
View 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

View 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
View 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
View 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
View 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
View 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

View 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
View 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

View 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

File diff suppressed because it is too large Load Diff

268
sdrbase/dsp/dspcommands.h Normal file
View 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

View 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