1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-27 02:09:14 -05:00

Removed old sdrbase include directory

This commit is contained in:
f4exb 2016-03-10 02:08:20 +01:00
parent 90d6cd89e9
commit 6cc4434019
85 changed files with 0 additions and 11477 deletions

View File

@ -1,49 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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

View File

@ -1,67 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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

@ -1,62 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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

View File

@ -1,90 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_ */

View File

@ -1,128 +0,0 @@
/*
* 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_ */

View File

@ -1,127 +0,0 @@
#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

View File

@ -1,85 +0,0 @@
#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

@ -1,62 +0,0 @@
#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

View File

@ -1,43 +0,0 @@
// ----------------------------------------------------------------------------
// 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

@ -1,88 +0,0 @@
/*
* 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_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,268 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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

@ -1,125 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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

View File

@ -1,74 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_DSPENGINE_H
#define INCLUDE_DSPENGINE_H
#include <QObject>
#include "dsp/dspdeviceengine.h"
#include "audio/audiooutput.h"
#include "util/export.h"
class DSPDeviceEngine;
class ThreadedSampleSink;
class SDRANGEL_API DSPEngine : public QObject {
Q_OBJECT
public:
DSPEngine();
~DSPEngine();
static DSPEngine *instance();
MessageQueue* getInputMessageQueue();
MessageQueue* getOutputMessageQueue();
uint getAudioSampleRate() const { return m_audioSampleRate; }
void start(); //!< Device engine(s) start
void stop(); //!< Device engine(s) 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 addAudioSink(AudioFifo* audioFifo); //!< Add the audio sink
void removeAudioSink(AudioFifo* audioFifo); //!< Remove the audio sink
void configureCorrections(bool dcOffsetCorrection, bool iqImbalanceCorrection); //!< Configure DSP corrections
DSPDeviceEngine::State state() const;
QString errorMessage(); //!< Return the current error message
QString sourceDeviceDescription(); //!< Return the source device description
private:
DSPDeviceEngine *m_deviceEngine;
AudioOutput m_audioOutput;
uint m_audioSampleRate;
};
#endif // INCLUDE_DSPENGINE_H

View File

@ -1,57 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_DSPTYPES_H
#define INCLUDE_DSPTYPES_H
#include <complex>
#include <vector>
#include <QtGlobal>
#define SDR_SAMP_SZ 16 // internal fixed arithmetic sample size
typedef float Real;
typedef std::complex<Real> Complex;
typedef qint16 FixReal;
#pragma pack(push, 1)
struct Sample
{
Sample() {}
Sample(FixReal real) : m_real(real), m_imag(0) {}
Sample(FixReal real, FixReal imag) : m_real(real), m_imag(imag) {}
Sample(const Sample& other) : m_real(other.m_real), m_imag(other.m_imag) {}
inline Sample& operator=(const Sample& other) { m_real = other.m_real; m_imag = other.m_imag; return *this; }
inline Sample& operator+=(const Sample& other) { m_real += other.m_real; m_imag += other.m_imag; return *this; }
inline Sample& operator-=(const Sample& other) { m_real -= other.m_real; m_imag -= other.m_imag; return *this; }
inline void setReal(FixReal v) { m_real = v; }
inline void setImag(FixReal v) { m_imag = v; }
inline FixReal real() const { return m_real; }
inline FixReal imag() const { return m_imag; }
FixReal m_real;
FixReal m_imag;
};
#pragma pack(pop)
typedef std::vector<Sample> SampleVector;
#endif // INCLUDE_DSPTYPES_H

View File

@ -1,20 +0,0 @@
#ifndef INCLUDE_FFTENGINE_H
#define INCLUDE_FFTENGINE_H
#include "dsp/dsptypes.h"
#include "util/export.h"
class SDRANGEL_API FFTEngine {
public:
virtual ~FFTEngine();
virtual void configure(int n, bool inverse) = 0;
virtual void transform() = 0;
virtual Complex* in() = 0;
virtual Complex* out() = 0;
static FFTEngine* create();
};
#endif // INCLUDE_FFTENGINE_H

View File

@ -1,82 +0,0 @@
/*
* Filters from Fldigi.
*/
#ifndef _FFTFILT_H
#define _FFTFILT_H
#include <complex>
#include "gfft.h"
//----------------------------------------------------------------------
class fftfilt {
enum {NONE, BLACKMAN, HAMMING, HANNING};
public:
typedef std::complex<float> cmplx;
fftfilt(float f1, float f2, int len);
fftfilt(float f2, int len);
~fftfilt();
// f1 < f2 ==> bandpass
// f1 > f2 ==> band reject
void create_filter(float f1, float f2);
void create_dsb_filter(float f2);
int noFilt(const cmplx& in, cmplx **out);
int runFilt(const cmplx& in, cmplx **out);
int runSSB(const cmplx& in, cmplx **out, bool usb);
int runDSB(const cmplx& in, cmplx **out);
protected:
int flen;
int flen2;
g_fft<float> *fft;
g_fft<float> *ift;
cmplx *filter;
cmplx *data;
cmplx *ovlbuf;
cmplx *output;
int inptr;
int pass;
int window;
inline float fsinc(float fc, int i, int len) {
return (i == len/2) ? 2.0 * fc:
sin(2 * M_PI * fc * (i - len/2)) / (M_PI * (i - len/2));
}
inline float _blackman(int i, int len) {
return (0.42 -
0.50 * cos(2.0 * M_PI * i / len) +
0.08 * cos(4.0 * M_PI * i / len));
}
void init_filter();
void init_dsb_filter();
};
/* Sliding FFT filter from Fldigi */
class sfft {
#define K1 0.99999
public:
typedef std::complex<float> cmplx;
sfft(int len);
~sfft();
void run(const cmplx& input);
void fetch(float *result);
private:
int fftlen;
int first;
int last;
int ptr;
struct vrot_bins_pair;
vrot_bins_pair *vrot_bins;
cmplx *delay;
float k2;
};
#endif

View File

@ -1,37 +0,0 @@
#ifndef INCLUDE_FFTWENGINE_H
#define INCLUDE_FFTWENGINE_H
#include <QMutex>
#include <fftw3.h>
#include <list>
#include "dsp/fftengine.h"
class FFTWEngine : public FFTEngine {
public:
FFTWEngine();
~FFTWEngine();
void configure(int n, bool inverse);
void transform();
Complex* in();
Complex* out();
protected:
static QMutex m_globalPlanMutex;
struct Plan {
int n;
bool inverse;
fftwf_plan plan;
fftwf_complex* in;
fftwf_complex* out;
};
typedef std::list<Plan*> Plans;
Plans m_plans;
Plan* m_currentPlan;
void freeAll();
};
#endif // INCLUDE_FFTWENGINE_H

View File

@ -1,82 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_FFTWINDOW_H
#define INCLUDE_FFTWINDOW_H
#include <vector>
#define _USE_MATH_DEFINES
#include <math.h>
#include "dsp/dsptypes.h"
#include "util/export.h"
class SDRANGEL_API FFTWindow {
public:
enum Function {
Bartlett,
BlackmanHarris,
Flattop,
Hamming,
Hanning,
Rectangle
};
void create(Function function, int n);
void apply(const std::vector<Real>& in, std::vector<Real>* out);
void apply(const std::vector<Complex>& in, std::vector<Complex>* out);
void apply(const Complex* in, Complex* out);
private:
std::vector<float> m_window;
static inline Real flatTop(Real n, Real i)
{
// correction ?
return 1.0 - 1.93 * cos((2.0 * M_PI * i) / n) + 1.29 * cos((4.0 * M_PI * i) / n) - 0.388 * cos((6.0 * M_PI * i) / n) + 0.03222 * cos((8.0 * M_PI * i) / n);
}
static inline Real bartlett(Real n, Real i)
{
// amplitude correction = 2.0
return (2.0 / (n - 1.0)) * ( (n - 1.0) / 2.0 - fabs(i - (n - 1.0) / 2.0)) * 2.0;
}
static inline Real blackmanHarris(Real n, Real i)
{
// amplitude correction = 2.79
return (0.35875 - 0.48829 * cos((2.0 * M_PI * i) / n) + 0.14128 * cos((4.0 * M_PI * i) / n) - 0.01168 * cos((6.0 * M_PI * i) / n)) * 2.79;
}
static inline Real hamming(Real n, Real i)
{
// amplitude correction = 1.855, energy correction = 1.586
return (0.54 - 0.46 * cos((2.0 * M_PI * i) / n)) * 1.855;
}
static inline Real hanning(Real n, Real i)
{
// amplitude correction = 2.0, energy correction = 1.633
return (0.5 - 0.5 * cos((2.0 * M_PI * i) / n)) * 2.0;
}
static inline Real rectangle(Real, Real)
{
return 1.0;
}
};
#endif // INCLUDE_FFTWINDOWS_H

View File

@ -1,72 +0,0 @@
#ifndef INCLUDE_FILESINK_H
#define INCLUDE_FILESINK_H
#include <string>
#include <iostream>
#include <fstream>
#include <ctime>
#include "dsp/samplesink.h"
#include "util/export.h"
#include "util/message.h"
#include "util/messagequeue.h"
class SDRANGEL_API FileSink : public SampleSink {
public:
struct Header
{
int sampleRate;
quint64 centerFrequency;
std::time_t startTimeStamp;
};
FileSink();
virtual ~FileSink();
quint64 getByteCount() const { return m_byteCount; }
void configure(MessageQueue* msgQueue, const std::string& filename);
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
virtual void start();
virtual void stop();
virtual bool handleMessage(const Message& message);
void startRecording();
void stopRecording();
static void readHeader(std::ifstream& samplefile, Header& header);
private:
class MsgConfigureFileSink : public Message {
MESSAGE_CLASS_DECLARATION
public:
const std::string& getFileName() const { return m_fileName; }
static MsgConfigureFileSink* create(const std::string& fileName)
{
return new MsgConfigureFileSink(fileName);
}
private:
std::string m_fileName;
MsgConfigureFileSink(const std::string& fileName) :
Message(),
m_fileName(fileName)
{ }
};
std::string m_fileName;
int m_sampleRate;
quint64 m_centerFrequency;
bool m_recordOn;
bool m_recordStart;
std::ofstream m_sampleFile;
quint64 m_byteCount;
void handleConfigure(const std::string& fileName);
void writeHeader();
};
#endif // INCLUDE_FILESINK_H

View File

@ -1,50 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_DSP_FILTERRC_H_
#define INCLUDE_DSP_FILTERRC_H_
#include "dsp/dsptypes.h"
/** First order low-pass IIR filter for real-valued signals. */
class LowPassFilterRC
{
public:
/**
* Construct 1st order low-pass IIR filter.
*
* timeconst :: RC time constant in seconds (1 / (2 * PI * cutoff_freq)
*/
LowPassFilterRC(Real timeconst);
/**
* Reconfigure filter with new time constant
*/
void configure(Real timeout);
/** Process samples. */
void process(const Real& sample_in, Real& sample_out);
private:
Real m_timeconst;
Real m_y1;
Real m_a1;
Real m_b0;
};
#endif /* INCLUDE_DSP_FILTERRC_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,106 +0,0 @@
#ifndef INCLUDE_HIGHPASS_H
#define INCLUDE_HIGHPASS_H
#define _USE_MATH_DEFINES
#include <math.h>
#include "dsp/dsptypes.h"
template <class Type> class Highpass {
public:
Highpass() { }
void create(int nTaps, double sampleRate, double cutoff)
{
double wc = 2.0 * M_PI * cutoff;
double Wc = wc / sampleRate;
int i;
// check constraints
if(!(nTaps & 1)) {
qDebug("Highpass 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);
// generate Sinc filter core for lowpass but inverting every other tap for highpass keeping center tap
for(i = 0; i < nTaps / 2 + 1; i++) {
if(i == (nTaps - 1) / 2)
m_taps[i] = -(Wc / M_PI);
else
m_taps[i] = -sin(((double)i - ((double)nTaps - 1.0) / 2.0) * Wc) / (((double)i - ((double)nTaps - 1.0) / 2.0) * M_PI);
}
m_taps[(nTaps - 1) / 2] += 1;
// apply Hamming window
for(i = 0; i < nTaps / 2 + 1; i++)
m_taps[i] *= 0.54 + 0.46 * cos((2.0 * M_PI * ((double)i - ((double)nTaps - 1.0) / 2.0)) / (double)nTaps);
// 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_HIGHPASS_H

View File

@ -1,135 +0,0 @@
#ifndef INCLUDE_INTERPOLATOR_H
#define INCLUDE_INTERPOLATOR_H
#ifdef USE_SIMD
#include <immintrin.h>
#endif
#include "dsp/dsptypes.h"
#include "util/export.h"
#include <stdio.h>
#ifndef WIN32
#include <unistd.h>
#endif
class SDRANGEL_API Interpolator {
public:
Interpolator();
~Interpolator();
void create(int phaseSteps, double sampleRate, double cutoff);
void free();
// Original code allowed for upsampling, but was never used that way
bool interpolate(Real *distance, const Complex& next, Complex* result)
{
advanceFilter(next);
*distance -= 1.0;
if (*distance >= 1.0)
{
return false;
}
doInterpolate((int) floor(*distance * (Real)m_phaseSteps), result);
return true;
}
private:
float* m_taps;
float* m_alignedTaps;
float* m_taps2;
float* m_alignedTaps2;
std::vector<Complex> m_samples;
int m_ptr;
int m_phaseSteps;
int m_nTaps;
void createTaps(int nTaps, double sampleRate, double cutoff, std::vector<Real>* taps);
void advanceFilter(const Complex& next)
{
m_ptr--;
if(m_ptr < 0)
m_ptr = m_nTaps - 1;
m_samples[m_ptr] = next;
}
void doInterpolate(int phase, Complex* result)
{
if (phase < 0)
phase = 0;
#if USE_SIMD
// beware of the ringbuffer
if(m_ptr == 0) {
// only one straight block
const float* src = (const float*)&m_samples[0];
const __m128* filter = (const __m128*)&m_alignedTaps[phase * m_nTaps * 2];
__m128 sum = _mm_setzero_ps();
int todo = m_nTaps / 2;
for(int i = 0; i < todo; i++) {
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(src), *filter));
src += 4;
filter += 1;
}
// add upper half to lower half and store
_mm_storel_pi((__m64*)result, _mm_add_ps(sum, _mm_shuffle_ps(sum, _mm_setzero_ps(), _MM_SHUFFLE(1, 0, 3, 2))));
} else {
// two blocks
const float* src = (const float*)&m_samples[m_ptr];
const __m128* filter = (const __m128*)&m_alignedTaps[phase * m_nTaps * 2];
__m128 sum = _mm_setzero_ps();
// first block
int block = m_nTaps - m_ptr;
int todo = block / 2;
if(block & 1)
todo++;
for(int i = 0; i < todo; i++) {
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(src), *filter));
src += 4;
filter += 1;
}
if(block & 1) {
// one sample beyond the end -> switch coefficient table
filter = (const __m128*)&m_alignedTaps2[phase * m_nTaps * 2 + todo * 4 - 4];
}
// second block
src = (const float*)&m_samples[0];
block = m_ptr;
todo = block / 2;
for(int i = 0; i < todo; i++) {
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(src), *filter));
src += 4;
filter += 1;
}
if(block & 1) {
// one sample remaining
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadl_pi(_mm_setzero_ps(), (const __m64*)src), filter[0]));
}
// add upper half to lower half and store
_mm_storel_pi((__m64*)result, _mm_add_ps(sum, _mm_shuffle_ps(sum, _mm_setzero_ps(), _MM_SHUFFLE(1, 0, 3, 2))));
}
#else
int sample = m_ptr;
const Real* coeff = &m_alignedTaps[phase * m_nTaps * 2];
Real rAcc = 0;
Real iAcc = 0;
for(int i = 0; i < m_nTaps; i++) {
rAcc += *coeff * m_samples[sample].real();
iAcc += *coeff * m_samples[sample].imag();
sample = (sample + 1) % m_nTaps;
coeff += 2;
}
*result = Complex(rAcc, iAcc);
#endif
}
};
#endif // INCLUDE_INTERPOLATOR_H

View File

@ -1,476 +0,0 @@
#ifndef INCLUDE_INTHALFBANDFILTER_H
#define INCLUDE_INTHALFBANDFILTER_H
#include <QtGlobal>
#include "dsp/dsptypes.h"
#include "util/export.h"
// uses Q1.14 format internally, input and output are S16
/*
* supported filter orders: 64, 48, 32
*/
#define HB_FILTERORDER 32
#define HB_SHIFT 14
class SDRANGEL_API IntHalfbandFilter {
public:
IntHalfbandFilter();
// downsample by 2, return center part of original spectrum
bool workDecimateCenter(Sample* sample)
{
// insert sample into ring-buffer
m_samples[m_ptr][0] = sample->real();
m_samples[m_ptr][1] = sample->imag();
switch(m_state)
{
case 0:
// advance write-pointer
m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1);
// next state
m_state = 1;
// tell caller we don't have a new sample
return false;
default:
// save result
doFIR(sample);
// advance write-pointer
m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1);
// next state
m_state = 0;
// tell caller we have a new sample
return true;
}
}
bool workDecimateCenter(qint32 *x, qint32 *y)
{
// insert sample into ring-buffer
m_samples[m_ptr][0] = *x;
m_samples[m_ptr][1] = *y;
switch(m_state)
{
case 0:
// advance write-pointer
m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1);
// next state
m_state = 1;
// tell caller we don't have a new sample
return false;
default:
// save result
doFIR(x, y);
// advance write-pointer
m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1);
// next state
m_state = 0;
// tell caller we have a new sample
return true;
}
}
// downsample by 2, return edges of spectrum rotated into center
bool workDecimateFullRotate(Sample* sample)
{
switch(m_state)
{
case 0:
// insert sample into ring-buffer
m_samples[m_ptr][0] = sample->real();
m_samples[m_ptr][1] = sample->imag();
// advance write-pointer
m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1);
// next state
m_state = 1;
// tell caller we don't have a new sample
return false;
default:
// insert sample into ring-buffer
m_samples[m_ptr][0] = -sample->real();
m_samples[m_ptr][1] = sample->imag();
// save result
doFIR(sample);
// advance write-pointer
m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1);
// next state
m_state = 0;
// tell caller we have a new sample
return true;
}
}
// downsample by 2, return lower half of original spectrum
bool workDecimateLowerHalf(Sample* sample)
{
switch(m_state)
{
case 0:
// insert sample into ring-buffer
m_samples[m_ptr][0] = -sample->imag();
m_samples[m_ptr][1] = sample->real();
// advance write-pointer
m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1);
// next state
m_state = 1;
// tell caller we don't have a new sample
return false;
case 1:
// insert sample into ring-buffer
m_samples[m_ptr][0] = -sample->real();
m_samples[m_ptr][1] = -sample->imag();
// save result
doFIR(sample);
// advance write-pointer
m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1);
// next state
m_state = 2;
// tell caller we have a new sample
return true;
case 2:
// insert sample into ring-buffer
m_samples[m_ptr][0] = sample->imag();
m_samples[m_ptr][1] = -sample->real();
// advance write-pointer
m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1);
// next state
m_state = 3;
// tell caller we don't have a new sample
return false;
default:
// insert sample into ring-buffer
m_samples[m_ptr][0] = sample->real();
m_samples[m_ptr][1] = sample->imag();
// save result
doFIR(sample);
// advance write-pointer
m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1);
// next state
m_state = 0;
// tell caller we have a new sample
return true;
}
}
// downsample by 2, return upper half of original spectrum
bool workDecimateUpperHalf(Sample* sample)
{
switch(m_state)
{
case 0:
// insert sample into ring-buffer
m_samples[m_ptr][0] = sample->imag();
m_samples[m_ptr][1] = -sample->real();
// advance write-pointer
m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1);
// next state
m_state = 1;
// tell caller we don't have a new sample
return false;
case 1:
// insert sample into ring-buffer
m_samples[m_ptr][0] = -sample->real();
m_samples[m_ptr][1] = -sample->imag();
// save result
doFIR(sample);
// advance write-pointer
m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1);
// next state
m_state = 2;
// tell caller we have a new sample
return true;
case 2:
// insert sample into ring-buffer
m_samples[m_ptr][0] = -sample->imag();
m_samples[m_ptr][1] = sample->real();
// advance write-pointer
m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1);
// next state
m_state = 3;
// tell caller we don't have a new sample
return false;
default:
// insert sample into ring-buffer
m_samples[m_ptr][0] = sample->real();
m_samples[m_ptr][1] = sample->imag();
// save result
doFIR(sample);
// advance write-pointer
m_ptr = (m_ptr + HB_FILTERORDER) % (HB_FILTERORDER + 1);
// next state
m_state = 0;
// tell caller we have a new sample
return true;
}
}
void myDecimate(const Sample* sample1, Sample* sample2)
{
static const qint16 mod33[38] = { 31,32,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,30,31,32,0,1,2};
m_samples[m_ptr][0] = sample1->real();
m_samples[m_ptr][1] = sample1->imag();
m_ptr = mod33[m_ptr + 2 - 1];
m_samples[m_ptr][0] = sample2->real();
m_samples[m_ptr][1] = sample2->imag();
doFIR(sample2);
m_ptr = mod33[m_ptr + 2 - 1];
}
void myDecimate(qint32 x1, qint32 y1, qint32 *x2, qint32 *y2)
{
static const qint16 mod33[38] = { 31,32,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,30,31,32,0,1,2};
m_samples[m_ptr][0] = x1;
m_samples[m_ptr][1] = y1;
m_ptr = mod33[m_ptr + 2 - 1];
m_samples[m_ptr][0] = *x2;
m_samples[m_ptr][1] = *y2;
doFIR(x2, y2);
m_ptr = mod33[m_ptr + 2 - 1];
}
protected:
qint32 m_samples[HB_FILTERORDER + 1][2]; // Valgrind optim (from qint16)
qint16 m_ptr;
int m_state;
void doFIR(Sample* sample)
{
// coefficents
#if HB_FILTERORDER == 64
static const qint32 COEFF[16] = {
-0.001114417441601693505720538368564120901 * (1 << HB_SHIFT),
0.001268007827185253051302527005361753254 * (1 << HB_SHIFT),
-0.001959831378850490895410230152151598304 * (1 << HB_SHIFT),
0.002878308307661380308073439948657323839 * (1 << HB_SHIFT),
-0.004071361818258721100571850826099762344 * (1 << HB_SHIFT),
0.005597288494657440618973431867289036745 * (1 << HB_SHIFT),
-0.007532345003308904551886371336877346039 * (1 << HB_SHIFT),
0.009980346844667375288961963519795972388 * (1 << HB_SHIFT),
-0.013092614174300500062830820979797863401 * (1 << HB_SHIFT),
0.01710934914871829748417297878404497169 * (1 << HB_SHIFT),
-0.022443558692997273018576720460259821266 * (1 << HB_SHIFT),
0.029875811511593811098386197500076377764 * (1 << HB_SHIFT),
-0.041086352085710403647667021687084343284 * (1 << HB_SHIFT),
0.060465467462665789533104998554335907102 * (1 << HB_SHIFT),
-0.104159517495977321788203084906854201108 * (1 << HB_SHIFT),
0.317657589850154464805598308885237202048 * (1 << HB_SHIFT),
};
#elif HB_FILTERORDER == 48
static const qint32 COEFF[12] = {
-0.004102576237611492253332112767338912818 * (1 << HB_SHIFT),
0.003950551047979387886410762575906119309 * (1 << HB_SHIFT),
-0.005807875789391703583164350277456833282 * (1 << HB_SHIFT),
0.00823497890520805998770814682075069868 * (1 << HB_SHIFT),
-0.011372226513199541059195851744334504474 * (1 << HB_SHIFT),
0.015471557140973646315984524335362948477 * (1 << HB_SHIFT),
-0.020944996398689276484450516591095947661 * (1 << HB_SHIFT),
0.028568078132034283034279553703527199104 * (1 << HB_SHIFT),
-0.040015143905614086738964374490024056286 * (1 << HB_SHIFT),
0.059669519431831075095828964549582451582 * (1 << HB_SHIFT),
-0.103669138691865420076609893840213771909 * (1 << HB_SHIFT),
0.317491986549921390015072120149852707982 * (1 << HB_SHIFT)
};
#elif HB_FILTERORDER == 32
static const qint16 mod33[38] = { 31,32,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,30,31,32,0,1,2} ;
static const qint32 COEFF[8] = {
(qint32)(-0.015956912844043127236437484839370881673 * (1 << HB_SHIFT)),
(qint32)( 0.013023031678944928940522274274371739011 * (1 << HB_SHIFT)),
(qint32)(-0.01866942273717486777684371190844103694 * (1 << HB_SHIFT)),
(qint32)( 0.026550887571157304190005987720724078827 * (1 << HB_SHIFT)),
(qint32)(-0.038350314277854319344740474662103224546 * (1 << HB_SHIFT)),
(qint32)( 0.058429248652825838128421764849917963147 * (1 << HB_SHIFT)),
(qint32)(-0.102889802028955756885153505209018476307 * (1 << HB_SHIFT)),
(qint32)( 0.317237706405931241260276465254719369113 * (1 << HB_SHIFT))
};
#else
#error unsupported filter order
#endif
// init read-pointer
int a = mod33[m_ptr + 2 + 1]; // 0 + 1
int b = mod33[m_ptr + 2 - 2]; //-1 - 1
// go through samples in buffer
qint32 iAcc = 0;
qint32 qAcc = 0;
for (int i = 0; i < HB_FILTERORDER / 4; i++)
{
// do multiply-accumulate
//qint32 iTmp = m_samples[a][0] + m_samples[b][0]; // Valgrind optim
//qint32 qTmp = m_samples[a][1] + m_samples[b][1]; // Valgrind optim
iAcc += (m_samples[a][0] + m_samples[b][0]) * COEFF[i];
qAcc += (m_samples[a][1] + m_samples[b][1]) * COEFF[i];
// update read-pointer
a = mod33[a + 2 + 2];
b = mod33[b + 2 - 2];
}
a = mod33[a + 2 - 1];
iAcc += ((qint32)m_samples[a][0] + 1) << (HB_SHIFT - 1);
qAcc += ((qint32)m_samples[a][1] + 1) << (HB_SHIFT - 1);
sample->setReal(iAcc >> HB_SHIFT);
sample->setImag(qAcc >> HB_SHIFT);
}
void doFIR(qint32 *x, qint32 *y)
{
// coefficents
#if HB_FILTERORDER == 64
static const qint32 COEFF[16] = {
-0.001114417441601693505720538368564120901 * (1 << HB_SHIFT),
0.001268007827185253051302527005361753254 * (1 << HB_SHIFT),
-0.001959831378850490895410230152151598304 * (1 << HB_SHIFT),
0.002878308307661380308073439948657323839 * (1 << HB_SHIFT),
-0.004071361818258721100571850826099762344 * (1 << HB_SHIFT),
0.005597288494657440618973431867289036745 * (1 << HB_SHIFT),
-0.007532345003308904551886371336877346039 * (1 << HB_SHIFT),
0.009980346844667375288961963519795972388 * (1 << HB_SHIFT),
-0.013092614174300500062830820979797863401 * (1 << HB_SHIFT),
0.01710934914871829748417297878404497169 * (1 << HB_SHIFT),
-0.022443558692997273018576720460259821266 * (1 << HB_SHIFT),
0.029875811511593811098386197500076377764 * (1 << HB_SHIFT),
-0.041086352085710403647667021687084343284 * (1 << HB_SHIFT),
0.060465467462665789533104998554335907102 * (1 << HB_SHIFT),
-0.104159517495977321788203084906854201108 * (1 << HB_SHIFT),
0.317657589850154464805598308885237202048 * (1 << HB_SHIFT),
};
#elif HB_FILTERORDER == 48
static const qint32 COEFF[12] = {
-0.004102576237611492253332112767338912818 * (1 << HB_SHIFT),
0.003950551047979387886410762575906119309 * (1 << HB_SHIFT),
-0.005807875789391703583164350277456833282 * (1 << HB_SHIFT),
0.00823497890520805998770814682075069868 * (1 << HB_SHIFT),
-0.011372226513199541059195851744334504474 * (1 << HB_SHIFT),
0.015471557140973646315984524335362948477 * (1 << HB_SHIFT),
-0.020944996398689276484450516591095947661 * (1 << HB_SHIFT),
0.028568078132034283034279553703527199104 * (1 << HB_SHIFT),
-0.040015143905614086738964374490024056286 * (1 << HB_SHIFT),
0.059669519431831075095828964549582451582 * (1 << HB_SHIFT),
-0.103669138691865420076609893840213771909 * (1 << HB_SHIFT),
0.317491986549921390015072120149852707982 * (1 << HB_SHIFT)
};
#elif HB_FILTERORDER == 32
static const int mod33[38] = { 31,32,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,30,31,32,0,1,2} ;
static const qint32 COEFF[8] = {
(qint32)(-0.015956912844043127236437484839370881673 * (1 << HB_SHIFT)),
(qint32)( 0.013023031678944928940522274274371739011 * (1 << HB_SHIFT)),
(qint32)(-0.01866942273717486777684371190844103694 * (1 << HB_SHIFT)),
(qint32)( 0.026550887571157304190005987720724078827 * (1 << HB_SHIFT)),
(qint32)(-0.038350314277854319344740474662103224546 * (1 << HB_SHIFT)),
(qint32)( 0.058429248652825838128421764849917963147 * (1 << HB_SHIFT)),
(qint32)(-0.102889802028955756885153505209018476307 * (1 << HB_SHIFT)),
(qint32)( 0.317237706405931241260276465254719369113 * (1 << HB_SHIFT))
};
#else
#error unsupported filter order
#endif
// init read-pointer
int a = mod33[m_ptr + 2 + 1]; // 0 + 1
int b = mod33[m_ptr + 2 - 2]; //-1 - 1
// go through samples in buffer
qint32 iAcc = 0;
qint32 qAcc = 0;
for (int i = 0; i < HB_FILTERORDER / 4; i++)
{
// do multiply-accumulate
//qint32 iTmp = m_samples[a][0] + m_samples[b][0]; // Valgrind optim
//qint32 qTmp = m_samples[a][1] + m_samples[b][1]; // Valgrind optim
iAcc += (m_samples[a][0] + m_samples[b][0]) * COEFF[i];
qAcc += (m_samples[a][1] + m_samples[b][1]) * COEFF[i];
// update read-pointer
a = mod33[a + 2 + 2];
b = mod33[b + 2 - 2];
}
a = mod33[a + 2 - 1];
iAcc += ((qint32)m_samples[a][0] + 1) << (HB_SHIFT - 1);
qAcc += ((qint32)m_samples[a][1] + 1) << (HB_SHIFT - 1);
*x = iAcc >> (HB_SHIFT -1); // HB_SHIFT incorrect do not loose the gained bit
*y = qAcc >> (HB_SHIFT -1);
}
};
#endif // INCLUDE_INTHALFBANDFILTER_H

View File

@ -1,23 +0,0 @@
#ifndef INCLUDE_KISSENGINE_H
#define INCLUDE_KISSENGINE_H
#include "dsp/fftengine.h"
#include "dsp/kissfft.h"
class KissEngine : public FFTEngine {
public:
void configure(int n, bool inverse);
void transform();
Complex* in();
Complex* out();
protected:
typedef kissfft<Real, Complex> KissFFT;
KissFFT m_fft;
std::vector<Complex> m_in;
std::vector<Complex> m_out;
};
#endif // INCLUDE_KISSENGINE_H

View File

@ -1,391 +0,0 @@
#ifndef INCLUDE_KISSFFT_H
#define INCLUDE_KISSFFT_H
#include <complex>
#include <vector>
/*
Copyright (c) 2003-2010 Mark Borgerding
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the author nor the names of any contributors may be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace kissfft_utils {
template<typename T_scalar, typename T_complex>
struct traits {
typedef T_scalar scalar_type;
typedef T_complex cpx_type;
void fill_twiddles(std::complex<T_scalar>* dst, int nfft, bool inverse)
{
T_scalar phinc = (inverse ? 2 : -2) * acos((T_scalar)-1) / nfft;
for(int i = 0; i < nfft; ++i)
dst[i] = exp(std::complex<T_scalar>(0, i * phinc));
}
void prepare(std::vector<std::complex<T_scalar> >& dst, int nfft, bool inverse, std::vector<int>& stageRadix, std::vector<int>& stageRemainder)
{
_twiddles.resize(nfft);
fill_twiddles(&_twiddles[0], nfft, inverse);
dst = _twiddles;
//factorize
//start factoring out 4's, then 2's, then 3,5,7,9,...
int n = nfft;
int p = 4;
do {
while(n % p) {
switch(p) {
case 4:
p = 2;
break;
case 2:
p = 3;
break;
default:
p += 2;
break;
}
if(p * p > n)
p = n;// no more factors
}
n /= p;
stageRadix.push_back(p);
stageRemainder.push_back(n);
} while(n > 1);
}
std::vector<cpx_type> _twiddles;
const cpx_type twiddle(int i)
{
return _twiddles[i];
}
};
} // namespace
template<typename T_Scalar, typename T_Complex, typename T_traits = kissfft_utils::traits<T_Scalar, T_Complex> >
class kissfft {
public:
typedef T_traits traits_type;
typedef typename traits_type::scalar_type scalar_type;
typedef typename traits_type::cpx_type cpx_type;
kissfft()
{
}
kissfft(int nfft, bool inverse, const traits_type & traits = traits_type()) :
_nfft(nfft), _inverse(inverse), _traits(traits)
{
_traits.prepare(_twiddles, _nfft, _inverse, _stageRadix, _stageRemainder);
}
void configure(int nfft, bool inverse, const traits_type & traits = traits_type())
{
_twiddles.clear();
_stageRadix.clear();
_stageRemainder.clear();
_nfft = nfft;
_inverse = inverse;
_traits = traits;
_traits.prepare(_twiddles, _nfft, _inverse, _stageRadix, _stageRemainder);
}
void transform(const cpx_type* src, cpx_type* dst)
{
kf_work(0, dst, src, 1, 1);
}
private:
void kf_work(int stage, cpx_type* Fout, const cpx_type* f, size_t fstride, size_t in_stride)
{
int p = _stageRadix[stage];
int m = _stageRemainder[stage];
cpx_type * Fout_beg = Fout;
cpx_type * Fout_end = Fout + p * m;
if(m == 1) {
do {
*Fout = *f;
f += fstride * in_stride;
} while(++Fout != Fout_end);
} else {
do {
// recursive call:
// DFT of size m*p performed by doing
// p instances of smaller DFTs of size m,
// each one takes a decimated version of the input
kf_work(stage + 1, Fout, f, fstride * p, in_stride);
f += fstride * in_stride;
} while((Fout += m) != Fout_end);
}
Fout = Fout_beg;
// recombine the p smaller DFTs
switch(p) {
case 2:
kf_bfly2(Fout, fstride, m);
break;
case 3:
kf_bfly3(Fout, fstride, m);
break;
case 4:
kf_bfly4(Fout, fstride, m);
break;
case 5:
kf_bfly5(Fout, fstride, m);
break;
default:
kf_bfly_generic(Fout, fstride, m, p);
break;
}
}
// these were #define macros in the original kiss_fft
void C_ADD(cpx_type& c, const cpx_type& a, const cpx_type& b)
{
c = a + b;
}
void C_MUL(cpx_type& c, const cpx_type& a, const cpx_type& b)
{
//c = a * b;
c = cpx_type(a.real() * b.real() - a.imag() * b.imag(), a.real() * b.imag() + a.imag() * b.real());
}
void C_SUB(cpx_type& c, const cpx_type& a, const cpx_type& b)
{
c = a - b;
}
void C_ADDTO(cpx_type& c, const cpx_type& a)
{
c += a;
}
void C_FIXDIV(cpx_type&, int)
{
} // NO-OP for float types
scalar_type S_MUL(const scalar_type& a, const scalar_type& b)
{
return a * b;
}
scalar_type HALF_OF(const scalar_type& a)
{
return a * .5;
}
void C_MULBYSCALAR(cpx_type& c, const scalar_type& a)
{
c *= a;
}
void kf_bfly2(cpx_type* Fout, const size_t fstride, int m)
{
for(int k = 0; k < m; ++k) {
//cpx_type t = Fout[m + k] * _traits.twiddle(k * fstride);
cpx_type t;
C_MUL(t, Fout[m + k], _traits.twiddle(k * fstride));
Fout[m + k] = Fout[k] - t;
Fout[k] += t;
}
}
void kf_bfly4(cpx_type* Fout, const size_t fstride, const size_t m)
{
cpx_type scratch[7];
int negative_if_inverse = _inverse * -2 + 1;
for(size_t k = 0; k < m; ++k) {
//scratch[0] = Fout[k + m] * _traits.twiddle(k * fstride);
C_MUL(scratch[0], Fout[k + m], _traits.twiddle(k * fstride));
C_MUL(scratch[1], Fout[k + 2 * m], _traits.twiddle(k * fstride * 2));
C_MUL(scratch[2], Fout[k + 3 * m], _traits.twiddle(k * fstride * 3));
scratch[5] = Fout[k] - scratch[1];
Fout[k] += scratch[1];
scratch[3] = scratch[0] + scratch[2];
scratch[4] = scratch[0] - scratch[2];
scratch[4] = cpx_type(scratch[4].imag() * negative_if_inverse, -scratch[4].real() * negative_if_inverse);
Fout[k + 2 * m] = Fout[k] - scratch[3];
Fout[k] += scratch[3];
Fout[k + m] = scratch[5] + scratch[4];
Fout[k + 3 * m] = scratch[5] - scratch[4];
}
}
void kf_bfly3(cpx_type* Fout, const size_t fstride, const size_t m)
{
size_t k = m;
const size_t m2 = 2 * m;
cpx_type* tw1;
cpx_type* tw2;
cpx_type scratch[5];
cpx_type epi3;
epi3 = _twiddles[fstride * m];
tw1 = tw2 = &_twiddles[0];
do {
C_FIXDIV(*Fout, 3);
C_FIXDIV(Fout[m], 3);
C_FIXDIV(Fout[m2], 3);
C_MUL(scratch[1], Fout[m], *tw1);
C_MUL(scratch[2], Fout[m2], *tw2);
C_ADD(scratch[3], scratch[1], scratch[2]);
C_SUB(scratch[0], scratch[1], scratch[2]);
tw1 += fstride;
tw2 += fstride * 2;
Fout[m] = cpx_type(Fout->real() - HALF_OF(scratch[3].real()), Fout->imag() - HALF_OF(scratch[3].imag()));
C_MULBYSCALAR(scratch[0], epi3.imag());
C_ADDTO(*Fout, scratch[3]);
Fout[m2] = cpx_type(Fout[m].real() + scratch[0].imag(), Fout[m].imag() - scratch[0].real());
C_ADDTO(Fout[m], cpx_type(-scratch[0].imag(), scratch[0].real()));
++Fout;
} while(--k);
}
void kf_bfly5(cpx_type* Fout, const size_t fstride, const size_t m)
{
cpx_type* Fout0;
cpx_type* Fout1;
cpx_type* Fout2;
cpx_type* Fout3;
cpx_type* Fout4;
size_t u;
cpx_type scratch[13];
cpx_type* twiddles = &_twiddles[0];
cpx_type* tw;
cpx_type ya, yb;
ya = twiddles[fstride * m];
yb = twiddles[fstride * 2 * m];
Fout0 = Fout;
Fout1 = Fout0 + m;
Fout2 = Fout0 + 2 * m;
Fout3 = Fout0 + 3 * m;
Fout4 = Fout0 + 4 * m;
tw = twiddles;
for(u = 0; u < m; ++u) {
C_FIXDIV(*Fout0, 5);
C_FIXDIV(*Fout1, 5);
C_FIXDIV(*Fout2, 5);
C_FIXDIV(*Fout3, 5);
C_FIXDIV(*Fout4, 5);
scratch[0] = *Fout0;
C_MUL(scratch[1], *Fout1, tw[u * fstride]);
C_MUL(scratch[2], *Fout2, tw[2 * u * fstride]);
C_MUL(scratch[3], *Fout3, tw[3 * u * fstride]);
C_MUL(scratch[4], *Fout4, tw[4 * u * fstride]);
C_ADD(scratch[7], scratch[1], scratch[4]);
C_SUB(scratch[10], scratch[1], scratch[4]);
C_ADD(scratch[8], scratch[2], scratch[3]);
C_SUB(scratch[9], scratch[2], scratch[3]);
C_ADDTO(*Fout0, scratch[7]);
C_ADDTO(*Fout0, scratch[8]);
scratch[5] = scratch[0] + cpx_type(S_MUL(scratch[7].real(), ya.real()) + S_MUL(scratch[8].real(), yb.real()), S_MUL(scratch[7].imag(), ya.real())
+ S_MUL(scratch[8].imag(), yb.real()));
scratch[6] = cpx_type(S_MUL(scratch[10].imag(), ya.imag()) + S_MUL(scratch[9].imag(), yb.imag()), -S_MUL(scratch[10].real(), ya.imag()) - S_MUL(
scratch[9].real(), yb.imag()));
C_SUB(*Fout1, scratch[5], scratch[6]);
C_ADD(*Fout4, scratch[5], scratch[6]);
scratch[11] = scratch[0] + cpx_type(S_MUL(scratch[7].real(), yb.real()) + S_MUL(scratch[8].real(), ya.real()), S_MUL(scratch[7].imag(), yb.real())
+ S_MUL(scratch[8].imag(), ya.real()));
scratch[12] = cpx_type(-S_MUL(scratch[10].imag(), yb.imag()) + S_MUL(scratch[9].imag(), ya.imag()), S_MUL(scratch[10].real(), yb.imag()) - S_MUL(
scratch[9].real(), ya.imag()));
C_ADD(*Fout2, scratch[11], scratch[12]);
C_SUB(*Fout3, scratch[11], scratch[12]);
++Fout0;
++Fout1;
++Fout2;
++Fout3;
++Fout4;
}
}
/* perform the butterfly for one stage of a mixed radix FFT */
void kf_bfly_generic(cpx_type* Fout, const size_t fstride, int m, int p)
{
int u;
int k;
int q1;
int q;
cpx_type* twiddles = &_twiddles[0];
cpx_type t;
int Norig = _nfft;
cpx_type* scratchbuf = new cpx_type[p];
for(u = 0; u < m; ++u) {
k = u;
for(q1 = 0; q1 < p; ++q1) {
scratchbuf[q1] = Fout[k];
C_FIXDIV(scratchbuf[q1], p);
k += m;
}
k = u;
for(q1 = 0; q1 < p; ++q1) {
int twidx = 0;
Fout[k] = scratchbuf[0];
for(q = 1; q < p; ++q) {
twidx += fstride * k;
if(twidx >= Norig)
twidx -= Norig;
C_MUL(t, scratchbuf[q], twiddles[twidx]);
C_ADDTO(Fout[k], t);
}
k += m;
}
}
delete[] scratchbuf;
}
int _nfft;
bool _inverse;
std::vector<cpx_type> _twiddles;
std::vector<int> _stageRadix;
std::vector<int> _stageRemainder;
traits_type _traits;
};
#endif

View File

@ -1,104 +0,0 @@
#ifndef INCLUDE_LOWPASS_H
#define INCLUDE_LOWPASS_H
#define _USE_MATH_DEFINES
#include <math.h>
#include "dsp/dsptypes.h"
template <class Type> class Lowpass {
public:
Lowpass() { }
void create(int nTaps, double sampleRate, double cutoff)
{
double wc = 2.0 * M_PI * cutoff;
double Wc = wc / sampleRate;
int i;
// check constraints
if(!(nTaps & 1)) {
qDebug("Lowpass 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);
// generate Sinc filter core
for(i = 0; i < nTaps / 2 + 1; i++) {
if(i == (nTaps - 1) / 2)
m_taps[i] = Wc / M_PI;
else
m_taps[i] = sin(((double)i - ((double)nTaps - 1.0) / 2.0) * Wc) / (((double)i - ((double)nTaps - 1.0) / 2.0) * M_PI);
}
// apply Hamming window
for(i = 0; i < nTaps / 2 + 1; i++)
m_taps[i] *= 0.54 + 0.46 * cos((2.0 * M_PI * ((double)i - ((double)nTaps - 1.0) / 2.0)) / (double)nTaps);
// 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_LOWPASS_H

View File

@ -1,75 +0,0 @@
// ----------------------------------------------------------------------------
// misc.h -- Miscellaneous helper functions
//
// Copyright (C) 2006-2008
// Dave Freese, W1HKJ
//
// This file is part of fldigi. These filters were adapted from code contained
// in the gmfsk source code distribution.
//
// 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 _MISC_H
#define _MISC_H
#include <cmath>
inline float sinc(float x)
{
return (fabs(x) < 1e-10) ? 1.0 : (sin(M_PI * x) / (M_PI * x));
}
inline float cosc(float x)
{
return (fabs(x) < 1e-10) ? 0.0 : ((1.0 - cos(M_PI * x)) / (M_PI * x));
}
inline float clamp(float x, float min, float max)
{
return (x < min) ? min : ((x > max) ? max : x);
}
/// This is always called with an int weight
inline float decayavg(float average, float input, int weight)
{
if (weight <= 1) return input;
return ( ( input - average ) / (float)weight ) + average ;
}
// following are defined inline to provide best performance
inline float blackman(float x)
{
return (0.42 - 0.50 * cos(2 * M_PI * x) + 0.08 * cos(4 * M_PI * x));
}
inline float hamming(float x)
{
return 0.54 - 0.46 * cos(2 * M_PI * x);
}
inline float hanning(float x)
{
return 0.5 - 0.5 * cos(2 * M_PI * x);
}
inline float rcos( float t, float T, float alpha=1.0 )
{
if( t == 0 ) return 1.0;
float taT = T / (2.0 * alpha);
if( fabs(t) == taT ) return ((alpha/2.0) * sin(M_PI/(2.0*alpha)));
return (sin(M_PI*t/T)/(M_PI*t/T))*cos(alpha*M_PI*t/T)/(1.0-(t/taT)*(t/taT));
}
#endif

View File

@ -1,65 +0,0 @@
#ifndef INCLUDE_MOVINGAVERAGE_H
#define INCLUDE_MOVINGAVERAGE_H
#include <vector>
#include "dsp/dsptypes.h"
template<class Type> class MovingAverage {
public:
MovingAverage() :
m_history(),
m_sum(0),
m_ptr(0)
{
}
MovingAverage(int historySize, Type initial) :
m_history(historySize, initial),
m_sum((float) historySize * initial),
m_ptr(0)
{
}
void resize(int historySize, Type initial)
{
m_history.resize(historySize);
for(size_t i = 0; i < m_history.size(); i++)
m_history[i] = initial;
m_sum = (float) m_history.size() * initial;
m_ptr = 0;
}
void feed(Type value)
{
m_sum -= m_history[m_ptr];
m_history[m_ptr] = value;
m_sum += value;
m_ptr++;
if(m_ptr >= m_history.size())
m_ptr = 0;
}
void fill(Type value)
{
for(size_t i = 0; i < m_history.size(); i++)
m_history[i] = value;
m_sum = (float) m_history.size() * value;
}
Type average() const
{
return m_sum / (float) m_history.size();
}
Type sum() const
{
return m_sum;
}
protected:
std::vector<Type> m_history;
Type m_sum;
uint m_ptr;
};
#endif // INCLUDE_MOVINGAVERAGE_H

View File

@ -1,45 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_NCO_H
#define INCLUDE_NCO_H
#include "dsp/dsptypes.h"
#include "util/export.h"
class SDRANGEL_API NCO {
private:
enum {
TableSize = (1 << 12),
};
static Real m_table[TableSize];
static bool m_tableInitialized;
static void initTable();
int m_phaseIncrement;
int m_phase;
public:
NCO();
void setFreq(Real freq, Real sampleRate);
Real next();
Complex nextIQ();
};
#endif // INCLUDE_NCO_H

View File

@ -1,22 +0,0 @@
#ifndef INCLUDE_NULLSINK_H
#define INCLUDE_NULLSINK_H
#include "dsp/samplesink.h"
#include "util/export.h"
class Message;
class SDRANGEL_API NullSink : public SampleSink {
public:
NullSink();
virtual ~NullSink();
virtual bool init(const Message& cmd);
virtual void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly);
virtual void start();
virtual void stop();
virtual bool handleMessage(const Message& message);
};
#endif // INCLUDE_NULLSINK_H

View File

@ -1,78 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_DSP_PHASEDISCRI_H_
#define INCLUDE_DSP_PHASEDISCRI_H_
#include "dsp/dsptypes.h"
class PhaseDiscriminators
{
public:
/**
* Reset stored values
*/
void reset()
{
m_m1Sample = 0;
m_m2Sample = 0;
}
/**
* Scaling factor so that resulting excursion maps to [-1,+1]
*/
void setFMScaling(Real fmScaling)
{
m_fmScaling = fmScaling;
}
/**
* Standard discriminator using atan2. On modern processors this is as efficient as the non atan2 one.
* This is better for high fidelity.
*/
Real phaseDiscriminator(const Complex& sample)
{
Complex d(std::conj(m_m1Sample) * sample);
m_m1Sample = sample;
return (std::atan2(d.imag(), d.real()) / M_PI_2) * m_fmScaling;
}
/**
* Alternative without atan at the expense of a slight distorsion on very wideband signals
* http://www.embedded.com/design/configurable-systems/4212086/DSP-Tricks--Frequency-demodulation-algorithms-
* in addition it needs scaling by instantaneous magnitude squared and volume (0..10) adjustment factor
*/
Real phaseDiscriminator2(const Complex& sample)
{
Real ip = sample.real() - m_m2Sample.real();
Real qp = sample.imag() - m_m2Sample.imag();
Real h1 = m_m1Sample.real() * qp;
Real h2 = m_m1Sample.imag() * ip;
m_m2Sample = m_m1Sample;
m_m1Sample = sample;
return ((h1 - h2) / M_PI_2) * m_fmScaling;
}
private:
Complex m_m1Sample;
Complex m_m2Sample;
Real m_fmScaling;
};
#endif /* INCLUDE_DSP_PHASEDISCRI_H_ */

View File

@ -1,159 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <vector>
#include "dsp/dsptypes.h"
/** Phase-locked loop mainly for broadcadt FM stereo pilot. */
class PhaseLock
{
public:
/** Expected pilot frequency (used for PPS events). */
static const int pilot_frequency = 19000;
/** Timestamp event produced once every 19000 pilot periods. */
struct PpsEvent
{
quint64 pps_index;
quint64 sample_index;
double block_position;
};
/**
* Construct phase-locked loop.
*
* freq :: 19 kHz center frequency relative to sample freq
* (0.5 is Nyquist)
* bandwidth :: bandwidth relative to sample frequency
* minsignal :: minimum pilot amplitude
*/
PhaseLock(Real freq, Real bandwidth, Real minsignal);
virtual ~PhaseLock()
{}
/**
* Change phase locked loop parameters
*
* freq :: 19 kHz center frequency relative to sample freq
* (0.5 is Nyquist)
* bandwidth :: bandwidth relative to sample frequency
* minsignal :: minimum pilot amplitude
*/
void configure(Real freq, Real bandwidth, Real minsignal);
/**
* Process samples and extract 19 kHz pilot tone.
* Generate phase-locked 38 kHz tone with unit amplitude.
* Bufferized version with input and output vectors
*/
void process(const std::vector<Real>& samples_in, std::vector<Real>& samples_out);
/**
* Process samples and track a pilot tone. Generate samples for single or multiple phase-locked
* signals. Implement the processPhase virtual method to produce the output samples.
* In flow version. Ex: Use 19 kHz stereo pilot tone to generate 38 kHz (stereo) and 57 kHz
* pilots (see RDSPhaseLock class below).
* This is the in flow version
*/
void process(const Real& sample_in, Real *samples_out);
/** Return true if the phase-locked loop is locked. */
bool locked() const
{
return m_lock_cnt >= m_lock_delay;
}
/** Return detected amplitude of pilot signal. */
Real get_pilot_level() const
{
return 2 * m_pilot_level;
}
protected:
Real m_phase;
Real m_psin;
Real m_pcos;
/**
* Callback method to produce multiple outputs from the current phase value in m_phase
* and/or the sin and cos values in m_psin and m_pcos
*/
virtual void processPhase(Real *samples_out) const {};
private:
Real m_minfreq, m_maxfreq;
Real m_phasor_b0, m_phasor_a1, m_phasor_a2;
Real m_phasor_i1, m_phasor_i2, m_phasor_q1, m_phasor_q2;
Real m_loopfilter_b0, m_loopfilter_b1;
Real m_loopfilter_x1;
Real m_freq;
Real m_minsignal;
Real m_pilot_level;
int m_lock_delay;
int m_lock_cnt;
int m_pilot_periods;
quint64 m_pps_cnt;
quint64 m_sample_cnt;
std::vector<PpsEvent> m_pps_events;
};
class StereoPhaseLock : public PhaseLock
{
public:
StereoPhaseLock(Real freq, Real bandwidth, Real minsignal) :
PhaseLock(freq, bandwidth, minsignal)
{}
virtual ~StereoPhaseLock()
{}
protected:
virtual void processPhase(Real *samples_out) const
{
samples_out[0] = m_psin; // f Pilot
// Generate double-frequency output.
// sin(2*x) = 2 * sin(x) * cos(x)
samples_out[1] = 2.0 * m_psin * m_pcos; // 2f Pilot sin
// cos(2*x) = 2 * cos(x) * cos(x) - 1
samples_out[2] = (2.0 * m_pcos * m_pcos) - 1.0; // 2f Pilot cos
}
};
class RDSPhaseLock : public PhaseLock
{
public:
RDSPhaseLock(Real freq, Real bandwidth, Real minsignal) :
PhaseLock(freq, bandwidth, minsignal)
{}
virtual ~RDSPhaseLock()
{}
protected:
virtual void processPhase(Real *samples_out) const
{
samples_out[0] = m_psin; // Pilot signal (f)
// Generate double-frequency output.
// sin(2*x) = 2 * sin(x) * cos(x)
samples_out[1] = 2.0 * m_psin * m_pcos; // Pilot signal (2f)
// cos(2*x) = 2 * cos(x) * cos(x) - 1
samples_out[2] = (2.0 * m_pcos * m_pcos) - 1.0; // 2f Pilot cos
samples_out[3] = m_phase; // Pilot phase
}
};

View File

@ -1,28 +0,0 @@
#ifndef INCLUDE_PIDCONTROLLER_H
#define INCLUDE_PIDCONTROLLER_H
#include "dsp/dsptypes.h"
class PIDController {
private:
Real m_p;
Real m_i;
Real m_d;
Real m_int;
Real m_diff;
public:
PIDController();
void setup(Real p, Real i, Real d);
Real feed(Real v)
{
m_int += v * m_i;
Real d = m_d * (m_diff - v);
m_diff = v;
return (v * m_p) + m_int + d;
}
};
#endif // INCLUDE_PIDCONTROLLER_H

View File

@ -1,67 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_SAMPLEFIFO_H
#define INCLUDE_SAMPLEFIFO_H
#include <QObject>
#include <QMutex>
#include <QTime>
#include "dsp/dsptypes.h"
#include "util/export.h"
class SDRANGEL_API SampleFifo : public QObject {
Q_OBJECT
private:
QMutex m_mutex;
QTime m_msgRateTimer;
int m_suppressed;
SampleVector m_data;
uint m_size;
uint m_fill;
uint m_head;
uint m_tail;
void create(uint s);
public:
SampleFifo(QObject* parent = NULL);
SampleFifo(int size, QObject* parent = NULL);
~SampleFifo();
bool setSize(int size);
inline uint size() const { return m_size; }
inline uint fill() { QMutexLocker mutexLocker(&m_mutex); uint fill = m_fill; return fill; }
uint write(const quint8* data, uint count);
uint write(SampleVector::const_iterator begin, SampleVector::const_iterator end);
uint read(SampleVector::iterator begin, SampleVector::iterator end);
uint readBegin(uint count,
SampleVector::iterator* part1Begin, SampleVector::iterator* part1End,
SampleVector::iterator* part2Begin, SampleVector::iterator* part2End);
uint readCommit(uint count);
signals:
void dataReady();
};
#endif // INCLUDE_SAMPLEFIFO_H

View File

@ -1,33 +0,0 @@
#ifndef INCLUDE_SAMPLESINK_H
#define INCLUDE_SAMPLESINK_H
#include <QObject>
#include "dsptypes.h"
#include "util/export.h"
#include "util/messagequeue.h"
class Message;
class SDRANGEL_API SampleSink : public QObject {
Q_OBJECT
public:
SampleSink();
virtual ~SampleSink();
virtual void start() = 0;
virtual void stop() = 0;
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly) = 0;
virtual bool handleMessage(const Message& cmd) = 0; //!< Processing of a message. Returns true if message has actually been processed
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication
MessageQueue *getOutputMessageQueue() { return &m_outputMessageQueue; } //!< Get the queue for asynchronous outbound communication
protected:
MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication
MessageQueue m_outputMessageQueue; //!< Queue for asynchronous outbound communication
protected slots:
void handleInputMessages();
};
#endif // INCLUDE_SAMPLESINK_H

View File

@ -1,56 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_SAMPLESOURCE_H
#define INCLUDE_SAMPLESOURCE_H
#include <QtGlobal>
#include "dsp/samplefifo.h"
#include "util/message.h"
#include "util/messagequeue.h"
#include "util/export.h"
class SDRANGEL_API SampleSource : public QObject {
Q_OBJECT
public:
SampleSource();
virtual ~SampleSource();
virtual bool init(const Message& cmd) = 0;
virtual bool start(int device) = 0;
virtual void stop() = 0;
virtual const QString& getDeviceDescription() const = 0;
virtual int getSampleRate() const = 0; //!< Sample rate exposed by the source
virtual quint64 getCenterFrequency() const = 0; //!< Center frequency exposed by the source
virtual bool handleMessage(const Message& message) = 0;
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
MessageQueue *getOutputMessageQueueToGUI() { return &m_outputMessageQueueToGUI; }
SampleFifo* getSampleFifo() { return &m_sampleFifo; }
protected slots:
void handleInputMessages();
protected:
SampleFifo m_sampleFifo;
MessageQueue m_inputMessageQueue; //!< Input queue to the source
MessageQueue m_outputMessageQueueToGUI; //!< Output queue specialized for the source GUI
};
#endif // INCLUDE_SAMPLESOURCE_H

View File

@ -1,169 +0,0 @@
#ifndef INCLUDE_SCOPEVIS_H
#define INCLUDE_SCOPEVIS_H
#include <boost/circular_buffer.hpp>
#include "dsp/samplesink.h"
#include "util/export.h"
#include "util/message.h"
class GLScope;
class MessageQueue;
class SDRANGEL_API ScopeVis : public SampleSink {
public:
enum TriggerChannel {
TriggerFreeRun,
TriggerChannelI,
TriggerChannelQ,
TriggerMagLin,
TriggerMagDb,
TriggerPhase,
TriggerDPhase
};
static const uint m_traceChunkSize;
static const uint m_nbTriggers = 10;
ScopeVis(GLScope* glScope = NULL);
virtual ~ScopeVis();
void configure(MessageQueue* msgQueue,
uint triggerIndex,
TriggerChannel triggerChannel,
Real triggerLevel,
bool triggerPositiveEdge,
bool triggerBothEdges,
uint triggerPre,
uint triggerDelay,
uint triggerCounts,
uint traceSize);
void setOneShot(bool oneShot);
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
virtual void start();
virtual void stop();
virtual bool handleMessage(const Message& message);
void setSampleRate(int sampleRate);
int getSampleRate() const { return m_sampleRate; }
SampleVector::const_iterator getTriggerPoint() const { return m_triggerPoint; }
private:
class MsgConfigureScopeVis : public Message {
MESSAGE_CLASS_DECLARATION
public:
uint getTriggerIndex() const { return m_triggerIndex; }
int getTriggerChannel() const { return m_triggerChannel; }
Real getTriggerLevel() const { return m_triggerLevel; }
Real getTriggerPositiveEdge() const { return m_triggerPositiveEdge; }
Real getTriggerBothEdges() const { return m_triggerBothEdges; }
uint getTriggerPre() const { return m_triggerPre; }
uint getTriggerDelay() const { return m_triggerDelay; }
uint getTriggerCounts() const { return m_triggerCounts; }
uint getTraceSize() const { return m_traceSize; }
static MsgConfigureScopeVis* create(uint triggerIndex,
int triggerChannel,
Real triggerLevel,
bool triggerPositiveEdge,
bool triggerBothEdges,
uint triggerPre,
uint triggerDelay,
uint triggerCounts,
uint traceSize)
{
return new MsgConfigureScopeVis(triggerIndex,
triggerChannel,
triggerLevel,
triggerPositiveEdge,
triggerBothEdges,
triggerPre,
triggerDelay,
triggerCounts,
traceSize);
}
private:
uint m_triggerIndex;
int m_triggerChannel;
Real m_triggerLevel;
bool m_triggerPositiveEdge;
bool m_triggerBothEdges;
uint m_triggerPre;
uint m_triggerDelay;
uint m_triggerCounts;
uint m_traceSize;
MsgConfigureScopeVis(uint triggerIndex,
int triggerChannel,
Real triggerLevel,
bool triggerPositiveEdge,
bool triggerBothEdges,
uint triggerPre,
uint triggerDelay,
uint triggerCounts,
uint traceSize) :
Message(),
m_triggerIndex(triggerIndex),
m_triggerChannel(triggerChannel),
m_triggerLevel(triggerLevel),
m_triggerPositiveEdge(triggerPositiveEdge),
m_triggerBothEdges(triggerBothEdges),
m_triggerPre(triggerPre),
m_triggerDelay(triggerDelay),
m_triggerCounts(triggerCounts),
m_traceSize(traceSize)
{ }
};
/**
* TriggerState: (repeat at each successive non freerun trigger)
*
* send a Trigger condition +--------------------+
* dummy trace - Immediate m_triggerOneShot | |
* Config -------------> Untriggered ----------------------------------> Triggered ----------------> WaitForReset |
* ^ ^ | ^ | | ^ |
* | | | - Delayed Delay expired | | | | setOneShot(true)|
* | | +---------------------> Delay ----------------+ | | +-----------------+
* | | !m_triggerOneShot | |
* | +--------------------------------------------------+ setOneShot(false) |
* +-------------------------------------------------------------------------------+
*/
enum TriggerState {
Untriggered, //!< Search for trigger
Config, //!< New configuration has just been received
Triggered, //!< Trigger was kicked off
WaitForReset, //!< Wait for release from GUI
Delay //!< Trigger delay engaged
};
GLScope* m_glScope;
std::vector<Complex> m_trace; //!< Raw trace to be used by GLScope
boost::circular_buffer<Complex> m_traceback; //!< FIFO for samples prior to triggering point to support pre-trigger (when in triggered mode)
uint m_tracebackCount; //!< Count of samples stored into trace memory since triggering is active up to trace memory size
uint m_fill;
TriggerState m_triggerState;
uint m_triggerIndex; //!< current active trigger index
TriggerChannel m_triggerChannel[m_nbTriggers];
Real m_triggerLevel[m_nbTriggers];
bool m_triggerPositiveEdge[m_nbTriggers];
bool m_triggerBothEdges[m_nbTriggers];
bool m_prevTrigger;
uint m_triggerPre; //!< Pre-trigger delay in number of samples
bool m_triggerOneShot;
bool m_armed;
uint m_triggerDelay[m_nbTriggers]; //!< Trigger delay in number of trace sizes
uint m_triggerDelayCount; //!< trace sizes delay counter
uint m_triggerCounts[m_nbTriggers]; //!< Number of trigger events before the actual trigger is kicked off
uint m_triggerCount;
int m_sampleRate;
SampleVector::const_iterator m_triggerPoint;
Real m_prevArg;
bool m_firstArg;
bool triggerCondition(SampleVector::const_iterator& it);
bool nextTrigger(); //!< move to next trigger. Returns true if next trigger is active.
};
#endif // INCLUDE_SCOPEVIS_H

View File

@ -1,27 +0,0 @@
#ifndef INCLUDE_SPECTRUMSCOPECOMBOVIS_H
#define INCLUDE_SPECTRUMSCOPECOMBOVIS_H
#include "dsp/samplesink.h"
#include "dsp/spectrumvis.h"
#include "dsp/scopevis.h"
#include "util/export.h"
class Message;
class SDRANGEL_API SpectrumScopeComboVis : public SampleSink {
public:
SpectrumScopeComboVis(SpectrumVis* spectrumVis, ScopeVis* scopeVis);
virtual ~SpectrumScopeComboVis();
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
virtual void start();
virtual void stop();
virtual bool handleMessage(const Message& message);
private:
SpectrumVis* m_spectrumVis;
ScopeVis* m_scopeVis;
};
#endif // INCLUDE_SPECTRUMSCOPECOMBOVIS_H

View File

@ -1,70 +0,0 @@
#ifndef INCLUDE_SPECTRUMVIS_H
#define INCLUDE_SPECTRUMVIS_H
#include <QMutex>
#include "dsp/samplesink.h"
#include "dsp/fftengine.h"
#include "fftwindow.h"
#include "util/export.h"
#include "util/message.h"
class GLSpectrum;
class MessageQueue;
class SDRANGEL_API SpectrumVis : public SampleSink {
public:
class SDRANGEL_API MsgConfigureSpectrumVis : public Message {
MESSAGE_CLASS_DECLARATION
public:
MsgConfigureSpectrumVis(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;
};
SpectrumVis(GLSpectrum* glSpectrum = NULL);
virtual ~SpectrumVis();
void configure(MessageQueue* msgQueue, int fftSize, int overlapPercent, FFTWindow::Function window);
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
void feedTriggered(const SampleVector::const_iterator& triggerPoint, const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
virtual void start();
virtual void stop();
virtual bool handleMessage(const Message& message);
private:
FFTEngine* m_fft;
FFTWindow m_window;
std::vector<Complex> m_fftBuffer;
std::vector<Real> m_logPowerSpectrum;
std::size_t m_fftSize;
std::size_t m_overlapPercent;
std::size_t m_overlapSize;
std::size_t m_refillSize;
std::size_t m_fftBufferFill;
bool m_needMoreSamples;
GLSpectrum* m_glSpectrum;
QMutex m_mutex;
void handleConfigure(int fftSize, int overlapPercent, FFTWindow::Function window);
};
#endif // INCLUDE_SPECTRUMVIS_H

View File

@ -1,78 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_THREADEDSAMPLESINK_H
#define INCLUDE_THREADEDSAMPLESINK_H
#include <QMutex>
#include "samplesink.h"
#include "dsp/samplefifo.h"
#include "util/messagequeue.h"
#include "util/export.h"
class SampleSink;
class QThread;
/**
* Because Qt is a piece of shit this class cannot be a nested protected class of ThreadedSampleSink
* So let's make everything public
*/
class ThreadedSampleFifo : public QObject {
Q_OBJECT
public:
ThreadedSampleFifo(SampleSink* sampleSink, std::size_t size = 1<<18);
~ThreadedSampleFifo();
void writeToFifo(SampleVector::const_iterator& begin, SampleVector::const_iterator& end);
SampleSink* m_sampleSink;
SampleFifo m_sampleFifo;
public slots:
void handleFifoData();
};
/**
* This class is a wrapper for SampleSink that runs the SampleSink object in its own thread
*/
class SDRANGEL_API ThreadedSampleSink : public QObject {
Q_OBJECT
public:
ThreadedSampleSink(SampleSink* sampleSink, QObject *parent = 0);
~ThreadedSampleSink();
const SampleSink *getSink() const { return m_sampleSink; }
MessageQueue* getInputMessageQueue() { return m_sampleSink->getInputMessageQueue(); } //!< Return pointer to sample sink's input message queue
MessageQueue* getOutputMessageQueue() { return m_sampleSink->getOutputMessageQueue(); } //!< Return pointer to sample sink's output message queue
void start(); //!< this thread start()
void stop(); //!< this thread exit() and wait()
bool handleSinkMessage(const Message& cmd); //!< Send message to sink synchronously
void feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool positiveOnly); //!< Feed sink with samples
QString getSampleSinkObjectName() const;
protected:
QThread *m_thread; //!< The thead object
ThreadedSampleFifo *m_threadedSampleFifo;
SampleSink* m_sampleSink;
};
#endif // INCLUDE_THREADEDSAMPLESINK_H

View File

@ -1,21 +0,0 @@
#ifndef INCLUDE_ABOUTDIALOG_H
#define INCLUDE_ABOUTDIALOG_H
#include <QDialog>
namespace Ui {
class AboutDialog;
}
class AboutDialog : public QDialog {
Q_OBJECT
public:
explicit AboutDialog(QWidget* parent = NULL);
~AboutDialog();
private:
Ui::AboutDialog* ui;
};
#endif // INCLUDE_ABOUTDIALOG_H

View File

@ -1,32 +0,0 @@
#ifndef INCLUDE_ADDPRESETDIALOG_H
#define INCLUDE_ADDPRESETDIALOG_H
#include <QDialog>
namespace Ui {
class AddPresetDialog;
}
class AddPresetDialog : public QDialog {
Q_OBJECT
public:
explicit AddPresetDialog(const QStringList& groups, const QString& group, QWidget* parent = NULL);
~AddPresetDialog();
QString group() const;
QString description() const;
void setGroup(QString& group);
void setDescription(QString& description);
private:
enum Audio {
ATDefault,
ATInterface,
ATDevice
};
Ui::AddPresetDialog* ui;
};
#endif // INCLUDE_ADDPRESETDIALOG_H

View File

@ -1,34 +0,0 @@
#ifndef INCLUDE_BASICCHANNELSETTINGSWIDGET_H
#define INCLUDE_BASICCHANNELSETTINGSWIDGET_H
#include <QWidget>
#include "util/export.h"
namespace Ui {
class BasicChannelSettingsWidget;
}
class ChannelMarker;
class SDRANGEL_API BasicChannelSettingsWidget : public QWidget {
Q_OBJECT
public:
explicit BasicChannelSettingsWidget(ChannelMarker* marker, QWidget* parent = NULL);
~BasicChannelSettingsWidget();
private slots:
void on_title_textChanged(const QString& text);
void on_colorBtn_clicked();
void on_red_valueChanged(int value);
void on_green_valueChanged(int value);
void on_blue_valueChanged(int value);
private:
Ui::BasicChannelSettingsWidget* ui;
ChannelMarker* m_channelMarker;
void paintColor();
};
#endif // INCLUDE_BASICCHANNELSETTINGSWIDGET_H

View File

@ -1,19 +0,0 @@
#ifndef INCLUDE_BUTTONSWITCH_H
#define INCLUDE_BUTTONSWITCH_H
#include <QToolButton>
class ButtonSwitch : public QToolButton {
Q_OBJECT
public:
ButtonSwitch(QWidget* parent = NULL);
private slots:
void onToggled(bool checked);
private:
QPalette m_originalPalette;
};
#endif // INCLUDE_BUTTONSWITCH_H

View File

@ -1,25 +0,0 @@
#ifndef INCLUDE_CHANNELWINDOW_H
#define INCLUDE_CHANNELWINDOW_H
#include <QScrollArea>
class QBoxLayout;
class QSpacerItem;
class RollupWidget;
class ChannelWindow : public QScrollArea {
Q_OBJECT
public:
ChannelWindow(QWidget* parent = NULL);
void addRollupWidget(QWidget* rollupWidget);
protected:
QWidget* m_container;
QBoxLayout* m_layout;
void resizeEvent(QResizeEvent* event);
};
#endif // INCLUDE_CHANNELWINDOW_H

View File

@ -1,46 +0,0 @@
/*
* colormap.h
*
* Created on: Jul 19, 2015
* Author: f4exb
*/
#ifndef INCLUDE_GPL_GUI_COLORMAPPER_H_
#define INCLUDE_GPL_GUI_COLORMAPPER_H_
#include <QColor>
#include <vector>
#include <utility>
#include "util/export.h"
class SDRANGEL_API ColorMapper
{
public:
enum Theme {
Normal,
Gold,
ReverseGold,
};
typedef std::vector<std::pair<float, QColor> > colormap;
ColorMapper(Theme theme = Normal);
~ColorMapper();
const colormap& getDialBackgroundColorMap() const { return m_dialBackgroundcolorMap; };
const QColor& getForegroundColor() const { return m_foregroundColor; };
const QColor& getSecondaryForegroundColor() const { return m_secondaryForegroundColor; };
const QColor& getHighlightColor() const { return m_highlightColor; };
const QColor& getBoundaryColor() const { return m_boundaryColor; };
const QColor& getBoundaryAlphaColor() const { return m_boundaryAlphaColor; };
private:
Theme m_theme;
std::vector<std::pair<float, QColor> > m_dialBackgroundcolorMap;
QColor m_foregroundColor;
QColor m_secondaryForegroundColor;
QColor m_highlightColor;
QColor m_boundaryColor;
QColor m_boundaryAlphaColor;
};
#endif /* INCLUDE_GPL_GUI_COLORMAPPER_H_ */

View File

@ -1,190 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 F4EXB //
// written by Edouard Griffiths //
// //
// OpenGL interface modernization. //
// See: http://doc.qt.io/qt-5/qopenglshaderprogram.html //
// //
// 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_GLSCOPE_H
#define INCLUDE_GLSCOPE_H
#include <QGLWidget>
#include <QPen>
#include <QTimer>
#include <QMutex>
#include <QFont>
#include <QMatrix4x4>
#include "dsp/dsptypes.h"
#include "dsp/scopevis.h"
#include "gui/scaleengine.h"
#include "gui/glshadersimple.h"
#include "gui/glshadertextured.h"
#include "util/export.h"
#include "util/bitfieldindex.h"
class DSPEngine;
class ScopeVis;
class QPainter;
class SDRANGEL_API GLScope: public QGLWidget {
Q_OBJECT
public:
enum Mode {
ModeIQ,
ModeMagLinPha,
ModeMagdBPha,
ModeMagLinDPha,
ModeMagdBDPha,
ModeDerived12,
ModeCyclostationary,
ModeIQPolar
};
enum Displays {
DisplayBoth,
DisplayFirstOnly,
DisplaySecondOnly
};
GLScope(QWidget* parent = NULL);
~GLScope();
void setDSPEngine(DSPEngine* dspEngine);
void setAmp1(Real amp);
void setAmp1Ofs(Real ampOfs);
void setAmp2(Real amp);
void setAmp2Ofs(Real ampOfs);
void setTimeBase(int timeBase);
void setTimeOfsProMill(int timeOfsProMill);
void setMode(Mode mode);
void setDisplays(Displays displays);
void setOrientation(Qt::Orientation orientation);
void setDisplayGridIntensity(int intensity);
void setDisplayTraceIntensity(int intensity);
void setTriggerChannel(ScopeVis::TriggerChannel triggerChannel);
void setTriggerLevel(Real triggerLevel);
void setTriggerPre(Real triggerPre);
void setMemHistoryShift(int value);
void newTrace(const std::vector<Complex>& trace, int sampleRate);
int getTraceSize() const { return m_rawTrace[m_memTraceIndex - m_memTraceHistory].size(); }
void setSampleRate(int sampleRate);
int getSampleRate() const { return m_sampleRates[m_memTraceIndex - m_memTraceHistory]; }
Mode getDataMode() const { return m_mode; }
void connectTimer(const QTimer& timer);
static const int m_memHistorySizeLog2 = 5;
signals:
void traceSizeChanged(int);
void sampleRateChanged(int);
private:
// state
QTimer m_timer;
QMutex m_mutex;
bool m_dataChanged;
bool m_configChanged;
Mode m_mode;
Displays m_displays;
Qt::Orientation m_orientation;
// traces
std::vector<Complex> m_rawTrace[1<<m_memHistorySizeLog2];
int m_sampleRates[1<<m_memHistorySizeLog2];
BitfieldIndex<m_memHistorySizeLog2> m_memTraceIndex; //!< current index of trace being written
BitfieldIndex<m_memHistorySizeLog2> m_memTraceHistory; //!< trace index shift into history
int m_memTraceIndexMax;
bool m_memTraceRecall;
std::vector<Complex> m_mathTrace;
std::vector<Complex>* m_displayTrace;
std::vector<Real> m_powTrace;
Real m_maxPow;
Real m_sumPow;
int m_oldTraceSize;
int m_sampleRate;
Real m_amp1;
Real m_amp2;
Real m_ofs1;
Real m_ofs2;
// sample sink
DSPEngine* m_dspEngine;
ScopeVis* m_scopeVis;
// config
int m_timeBase;
int m_timeOfsProMill;
ScopeVis::TriggerChannel m_triggerChannel;
Real m_triggerLevel;
Real m_triggerPre;
Real m_triggerLevelDis1;
Real m_triggerLevelDis2;
int m_nbPow;
Real m_prevArg;
// graphics stuff
QRectF m_glScopeRect1;
QRectF m_glScopeRect2;
QMatrix4x4 m_glScopeMatrix1;
QMatrix4x4 m_glScopeMatrix2;
QMatrix4x4 m_glLeft1ScaleMatrix;
QMatrix4x4 m_glRight1ScaleMatrix;
QMatrix4x4 m_glLeft2ScaleMatrix;
QMatrix4x4 m_glBot1ScaleMatrix;
QMatrix4x4 m_glBot2ScaleMatrix;
QPixmap m_left1ScalePixmap;
QPixmap m_left2ScalePixmap;
QPixmap m_bot1ScalePixmap;
QPixmap m_bot2ScalePixmap;
QPixmap m_powerOverlayPixmap1;
int m_displayGridIntensity;
int m_displayTraceIntensity;
ScaleEngine m_x1Scale;
ScaleEngine m_x2Scale;
ScaleEngine m_y1Scale;
ScaleEngine m_y2Scale;
QFont m_powerOverlayFont;
GLShaderSimple m_glShaderSimple;
GLShaderTextured m_glShaderLeft1Scale;
GLShaderTextured m_glShaderBottom1Scale;
GLShaderTextured m_glShaderLeft2Scale;
GLShaderTextured m_glShaderBottom2Scale;
GLShaderTextured m_glShaderPowerOverlay;
void initializeGL();
void resizeGL(int width, int height);
void paintGL();
void mousePressEvent(QMouseEvent*);
void handleMode();
void applyConfig();
void drawPowerOverlay();
protected slots:
void cleanup();
void tick();
};
#endif // INCLUDE_GLSCOPE_H

View File

@ -1,117 +0,0 @@
#ifndef INCLUDE_GLSCOPEGUI_H
#define INCLUDE_GLSCOPEGUI_H
#include <QWidget>
#include "dsp/dsptypes.h"
#include "util/export.h"
#include "util/message.h"
#include "dsp/scopevis.h"
namespace Ui {
class GLScopeGUI;
}
class MessageQueue;
class GLScope;
class SDRANGEL_API GLScopeGUI : public QWidget {
Q_OBJECT
public:
explicit GLScopeGUI(QWidget* parent = NULL);
~GLScopeGUI();
void setBuddies(MessageQueue* messageQueue, ScopeVis* scopeVis, GLScope* glScope);
void setSampleRate(int sampleRate);
void resetToDefaults();
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
bool handleMessage(Message* message);
private:
Ui::GLScopeGUI* ui;
MessageQueue* m_messageQueue;
ScopeVis* m_scopeVis;
GLScope* m_glScope;
int m_sampleRate;
qint32 m_displayData;
qint32 m_displayOrientation;
qint32 m_displays;
qint32 m_timeBase;
qint32 m_timeOffset;
qint32 m_amplification1;
qint32 m_amp1OffsetCoarse;
qint32 m_amp1OffsetFine;
qint32 m_amplification2;
qint32 m_amp2OffsetCoarse;
qint32 m_amp2OffsetFine;
int m_displayGridIntensity;
int m_displayTraceIntensity;
quint32 m_triggerIndex;
qint32 m_triggerChannel[ScopeVis::m_nbTriggers];
qint32 m_triggerLevelCoarse[ScopeVis::m_nbTriggers]; // percent of full range
qint32 m_triggerLevelFine[ScopeVis::m_nbTriggers]; // percent of coarse
bool m_triggerPositiveEdge[ScopeVis::m_nbTriggers];
bool m_triggerBothEdges[ScopeVis::m_nbTriggers];
qint32 m_triggerPre;
qint32 m_triggerDelay[ScopeVis::m_nbTriggers];
qint32 m_triggerCounts[ScopeVis::m_nbTriggers];
qint32 m_traceLenMult;
static const qreal amps[11];
void applySettings();
void applyTriggerSettings();
void setTimeScaleDisplay();
void setTraceLenDisplay();
void setTimeOfsDisplay();
void setAmp1ScaleDisplay();
void setAmp1OfsDisplay();
void setAmp2ScaleDisplay();
void setAmp2OfsDisplay();
void setTrigLevelDisplay();
void setTrigPreDisplay();
void setTrigDelayDisplay();
void setTrigUI(uint index);
private slots:
void on_amp1_valueChanged(int value);
void on_amp1OfsCoarse_valueChanged(int value);
void on_amp1OfsFine_valueChanged(int value);
void on_amp2_valueChanged(int value);
void on_amp2OfsCoarse_valueChanged(int value);
void on_amp2OfsFine_valueChanged(int value);
void on_scope_traceSizeChanged(int value);
void on_scope_sampleRateChanged(int value);
void on_time_valueChanged(int value);
void on_traceLen_valueChanged(int value);
void on_timeOfs_valueChanged(int value);
void on_dataMode_currentIndexChanged(int index);
void on_gridIntensity_valueChanged(int index);
void on_traceIntensity_valueChanged(int index);
void on_trigPre_valueChanged(int value);
void on_trigDelay_valueChanged(int value);
void on_memIndex_valueChanged(int value);
void on_trigCount_valueChanged(int value);
void on_trigIndex_valueChanged(int value);
void on_horizView_clicked();
void on_vertView_clicked();
void on_onlyPrimeView_clicked();
void on_onlySecondView_clicked();
void on_trigMode_currentIndexChanged(int index);
void on_slopePos_clicked();
void on_slopeNeg_clicked();
void on_slopeBoth_clicked();
void on_oneShot_clicked();
void on_trigLevelCoarse_valueChanged(int value);
void on_trigLevelFine_valueChanged(int value);
};
#endif // INCLUDE_GLSCOPEGUI_H

View File

@ -1,51 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 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_GUI_GLSHADERSIMPLE_H_
#define INCLUDE_GUI_GLSHADERSIMPLE_H_
#include <QString>
#include <QOpenGLFunctions>
class QOpenGLShaderProgram;
class QMatrix4x4;
class QVector4D;
class GLShaderSimple
{
public:
GLShaderSimple();
~GLShaderSimple();
void initializeGL();
void drawPolyline(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices);
void drawSegments(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices);
void drawContour(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices);
void drawSurface(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices);
void cleanup();
private:
void draw(unsigned int mode, const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices);
QOpenGLShaderProgram *m_program;
int m_matrixLoc;
int m_colorLoc;
static const QString m_vertexShaderSourceSimple;
static const QString m_fragmentShaderSourceColored;
};
#endif /* INCLUDE_GUI_GLSHADERSIMPLE_H_ */

View File

@ -1,55 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 F4EXB //
// written by Edouard Griffiths //
// //
// See: http://glslstudio.com/primer/#gl2frag //
// https://gitlab.com/pteam/korvins-qtbase/blob/5.4/examples/opengl/cube/mainwidget.cpp //
// //
// 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_GUI_GLSHADERTEXTURED_H_
#define INCLUDE_GUI_GLSHADERTEXTURED_H_
#include <QString>
#include <QOpenGLTexture>
#include <QOpenGLFunctions>
class QOpenGLShaderProgram;
class QMatrix4x4;
class QImage;
class GLShaderTextured
{
public:
GLShaderTextured();
~GLShaderTextured();
void initializeGL();
void initTexture(const QImage& image, QOpenGLTexture::WrapMode wrapMode = QOpenGLTexture::Repeat);
void subTexture(int xOffset, int yOffset, int width, int height, const void *pixels);
void drawSurface(const QMatrix4x4& transformMatrix, GLfloat* textureCoords, GLfloat *vertices, int nbVertices);
void cleanup();
private:
void draw(unsigned int mode, const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices);
QOpenGLShaderProgram *m_program;
QOpenGLTexture *m_texture;
int m_matrixLoc;
int m_textureLoc;
static const QString m_vertexShaderSourceTextured;
static const QString m_fragmentShaderSourceTextured;
};
#endif /* INCLUDE_GUI_GLSHADERTEXTURED_H_ */

View File

@ -1,193 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 F4EXB //
// written by Edouard Griffiths //
// //
// OpenGL interface modernization. //
// See: http://doc.qt.io/qt-5/qopenglshaderprogram.html //
// //
// 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_GLSPECTRUM_H
#define INCLUDE_GLSPECTRUM_H
#include <QOpenGLWidget>
#include <QTimer>
#include <QMutex>
#include <QOpenGLBuffer>
#include <QOpenGLVertexArrayObject>
#include <QMatrix4x4>
#include <QGLWidget>
#include "dsp/dsptypes.h"
#include "gui/scaleengine.h"
#include "gui/glshadersimple.h"
#include "gui/glshadertextured.h"
#include "dsp/channelmarker.h"
#include "util/export.h"
class QOpenGLShaderProgram;
class SDRANGEL_API GLSpectrum : public QGLWidget {
Q_OBJECT
public:
GLSpectrum(QWidget* parent = NULL);
~GLSpectrum();
void setCenterFrequency(quint64 frequency);
void setSampleRate(qint32 sampleRate);
void setReferenceLevel(Real referenceLevel);
void setPowerRange(Real powerRange);
void setDecay(int decay);
void setHistoLateHoldoff(int lateHoldoff);
void setHistoStroke(int stroke);
void setDisplayWaterfall(bool display);
void setSsbSpectrum(bool ssbSpectrum);
void setInvertedWaterfall(bool inv);
void setDisplayMaxHold(bool display);
void setDisplayCurrent(bool display);
void setDisplayHistogram(bool display);
void setDisplayGrid(bool display);
void setDisplayGridIntensity(int intensity);
void setDisplayTraceIntensity(int intensity);
void addChannelMarker(ChannelMarker* channelMarker);
void removeChannelMarker(ChannelMarker* channelMarker);
void newSpectrum(const std::vector<Real>& spectrum, int fftSize);
void clearSpectrumHistogram();
Real getWaterfallShare() const { return m_waterfallShare; }
void setWaterfallShare(Real waterfallShare);
void connectTimer(const QTimer& timer);
private:
struct ChannelMarkerState {
ChannelMarker* m_channelMarker;
QMatrix4x4 m_glMatrixWaterfall;
QMatrix4x4 m_glMatrixDsbWaterfall;
QMatrix4x4 m_glMatrixFreqScale;
QMatrix4x4 m_glMatrixDsbFreqScale;
QMatrix4x4 m_glMatrixHistogram;
QMatrix4x4 m_glMatrixDsbHistogram;
QRect m_rect;
ChannelMarkerState(ChannelMarker* channelMarker) :
m_channelMarker(channelMarker)
{ }
};
QList<ChannelMarkerState*> m_channelMarkerStates;
enum CursorState {
CSNormal,
CSSplitter,
CSSplitterMoving,
CSChannel,
CSChannelMoving
};
CursorState m_cursorState;
int m_cursorChannel;
QTimer m_timer;
QMutex m_mutex;
bool m_mouseInside;
bool m_changesPending;
qint64 m_centerFrequency;
Real m_referenceLevel;
Real m_powerRange;
int m_decay;
quint32 m_sampleRate;
int m_fftSize;
bool m_displayGrid;
int m_displayGridIntensity;
int m_displayTraceIntensity;
bool m_invertedWaterfall;
std::vector<Real> m_maxHold;
bool m_displayMaxHold;
const std::vector<Real> *m_currentSpectrum;
bool m_displayCurrent;
Real m_waterfallShare;
QPixmap m_leftMarginPixmap;
QPixmap m_frequencyPixmap;
ScaleEngine m_timeScale;
ScaleEngine m_powerScale;
ScaleEngine m_frequencyScale;
QRect m_frequencyScaleRect;
QMatrix4x4 m_glFrequencyScaleBoxMatrix;
QMatrix4x4 m_glLeftScaleBoxMatrix;
QRgb m_waterfallPalette[240];
QImage* m_waterfallBuffer;
int m_waterfallBufferPos;
int m_waterfallTextureHeight;
int m_waterfallTexturePos;
QMatrix4x4 m_glWaterfallBoxMatrix;
bool m_displayWaterfall;
bool m_ssbSpectrum;
QRgb m_histogramPalette[240];
QImage* m_histogramBuffer;
quint8* m_histogram;
quint8* m_histogramHoldoff;
int m_histogramHoldoffBase;
int m_histogramHoldoffCount;
int m_histogramLateHoldoff;
int m_histogramStroke;
QMatrix4x4 m_glHistogramSpectrumMatrix;
QMatrix4x4 m_glHistogramBoxMatrix;
bool m_displayHistogram;
bool m_displayChanged;
GLShaderSimple m_glShaderSimple;
GLShaderTextured m_glShaderLeftScale;
GLShaderTextured m_glShaderFrequencyScale;
GLShaderTextured m_glShaderWaterfall;
GLShaderTextured m_glShaderHistogram;
int m_matrixLoc;
int m_colorLoc;
static const int m_waterfallBufferHeight = 256;
void updateWaterfall(const std::vector<Real>& spectrum);
void updateHistogram(const std::vector<Real>& spectrum);
void initializeGL();
void resizeGL(int width, int height);
void paintGL();
void stopDrag();
void applyChanges();
void mouseMoveEvent(QMouseEvent* event);
void mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
void enterEvent(QEvent* event);
void leaveEvent(QEvent* event);
private slots:
void cleanup();
void tick();
void channelMarkerChanged();
void channelMarkerDestroyed(QObject* object);
};
#endif // INCLUDE_GLSPECTRUM_H

View File

@ -1,76 +0,0 @@
#ifndef INCLUDE_GLSPECTRUMGUI_H
#define INCLUDE_GLSPECTRUMGUI_H
#include <QWidget>
#include "dsp/dsptypes.h"
#include "util/export.h"
namespace Ui {
class GLSpectrumGUI;
}
class MessageQueue;
class SpectrumVis;
class GLSpectrum;
class SDRANGEL_API GLSpectrumGUI : public QWidget {
Q_OBJECT
public:
explicit GLSpectrumGUI(QWidget* parent = NULL);
~GLSpectrumGUI();
void setBuddies(MessageQueue* messageQueue, SpectrumVis* spectrumVis, GLSpectrum* glSpectrum);
void resetToDefaults();
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
private:
Ui::GLSpectrumGUI* ui;
MessageQueue* m_messageQueue;
SpectrumVis* m_spectrumVis;
GLSpectrum* m_glSpectrum;
qint32 m_fftSize;
qint32 m_fftOverlap;
qint32 m_fftWindow;
Real m_refLevel;
Real m_powerRange;
int m_decay;
int m_histogramLateHoldoff;
int m_histogramStroke;
int m_displayGridIntensity;
int m_displayTraceIntensity;
bool m_displayWaterfall;
bool m_invertedWaterfall;
bool m_displayMaxHold;
bool m_displayCurrent;
bool m_displayHistogram;
bool m_displayGrid;
bool m_invert;
void applySettings();
private slots:
void on_fftWindow_currentIndexChanged(int index);
void on_fftSize_currentIndexChanged(int index);
void on_refLevel_currentIndexChanged(int index);
void on_levelRange_currentIndexChanged(int index);
void on_decay_valueChanged(int index);
void on_holdoff_valueChanged(int index);
void on_stroke_valueChanged(int index);
void on_gridIntensity_valueChanged(int index);
void on_traceIntensity_valueChanged(int index);
void on_waterfall_toggled(bool checked);
void on_histogram_toggled(bool checked);
void on_maxHold_toggled(bool checked);
void on_current_toggled(bool checked);
void on_invert_toggled(bool checked);
void on_grid_toggled(bool checked);
void on_clearSpectrum_clicked(bool checked);
};
#endif // INCLUDE_GLSPECTRUMGUI_H

View File

@ -1,41 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_INDICATOR_H
#define INCLUDE_INDICATOR_H
#include <QWidget>
#include "util/export.h"
class SDRANGEL_API Indicator : public QWidget {
private:
Q_OBJECT;
QColor m_color;
QString m_text;
protected:
void paintEvent(QPaintEvent* event);
QSize sizeHint() const;
public:
Indicator(const QString& text, QWidget* parent = NULL);
void setColor(const QColor& color);
};
#endif // INCLUDE_INDICATOR_H

View File

@ -1,36 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_PHYSICALUNIT_H
#define INCLUDE_PHYSICALUNIT_H
namespace Unit {
enum Physical {
None,
Frequency,
Information,
Percent,
Decibel,
DecibelMilliWatt,
DecibelMicroVolt,
AngleDegrees,
Time,
Volt
};
};
#endif // INCLUDE_PHYSICALUNIT_H

View File

@ -1,22 +0,0 @@
#ifndef INCLUDE_PLUGINSDIALOG_H
#define INCLUDE_PLUGINSDIALOG_H
#include <QDialog>
#include "plugin/pluginmanager.h"
namespace Ui {
class PluginsDialog;
}
class PluginsDialog : public QDialog {
Q_OBJECT
public:
explicit PluginsDialog(PluginManager* pluginManager, QWidget* parent = NULL);
~PluginsDialog();
private:
Ui::PluginsDialog* ui;
};
#endif // INCLUDE_PLUGINSDIALOG_H

View File

@ -1,34 +0,0 @@
#ifndef INCLUDE_PREFERENCESDIALOG_H
#define INCLUDE_PREFERENCESDIALOG_H
#include <QDialog>
class AudioDeviceInfo;
namespace Ui {
class PreferencesDialog;
}
class PreferencesDialog : public QDialog {
Q_OBJECT
public:
explicit PreferencesDialog(AudioDeviceInfo* audioDeviceInfo, QWidget* parent = NULL);
~PreferencesDialog();
private:
enum Audio {
ATDefault,
ATInterface,
ATDevice
};
Ui::PreferencesDialog* ui;
AudioDeviceInfo* m_audioDeviceInfo;
private slots:
void accept();
};
#endif // INCLUDE_PREFERENCESDIALOG_H

View File

@ -1,27 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <QTreeWidgetItem>
class PresetItem : public QTreeWidgetItem {
public:
PresetItem(QTreeWidgetItem* parent, const QStringList& strings, quint64 frequency, int type);
bool operator<(const QTreeWidgetItem& other) const;
private:
quint64 m_frequency;
};

View File

@ -1,42 +0,0 @@
#ifndef INCLUDE_ROLLUPWIDGET_H
#define INCLUDE_ROLLUPWIDGET_H
#include <QWidget>
#include "util/export.h"
class SDRANGEL_API RollupWidget : public QWidget {
Q_OBJECT
public:
RollupWidget(QWidget* parent = NULL);
QByteArray saveState(int version = 0) const;
bool restoreState(const QByteArray& state, int version = 0);
void setTitleColor(const QColor& c);
signals:
void widgetRolled(QWidget* widget, bool rollDown);
void menuDoubleClickEvent();
protected:
enum {
VersionMarker = 0xff
};
QColor m_titleColor;
int arrangeRollups();
void paintEvent(QPaintEvent*);
int paintRollup(QWidget* rollup, int pos, QPainter* p, bool last, const QColor& frame);
void resizeEvent(QResizeEvent* size);
void mousePressEvent(QMouseEvent* event);
void mouseDoubleClickEvent(QMouseEvent* event);
bool event(QEvent* event);
bool eventFilter(QObject* object, QEvent* event);
};
#endif // INCLUDE_ROLLUPWIDGET_H

View File

@ -1,37 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <QWidget>
#include "gui/scaleengine.h"
#include "util/export.h"
class SDRANGEL_API Scale : public QWidget {
Q_OBJECT
public:
Scale(QWidget* parent = NULL);
void setOrientation(Qt::Orientation orientation);
void setRange(Unit::Physical physicalUnit, float rangeMin, float rangeMax);
private:
Qt::Orientation m_orientation;
ScaleEngine m_scaleEngine;
void paintEvent(QPaintEvent*);
void resizeEvent(QResizeEvent*);
};

View File

@ -1,90 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_SCALEENGINE_H
#define INCLUDE_SCALEENGINE_H
#include <QFont>
#include <QString>
#include <QList>
#include "physicalunit.h"
#include "util/export.h"
class SDRANGEL_API ScaleEngine {
public:
struct Tick {
float pos;
bool major;
float textPos;
float textSize;
QString text;
};
typedef QList<Tick> TickList;
private:
// base configuration
Qt::Orientation m_orientation;
QFont m_font;
float m_charSize;
// graph configuration
float m_size;
Unit::Physical m_physicalUnit;
float m_rangeMin;
float m_rangeMax;
// calculated values
bool m_recalc;
double m_scale;
QString m_unitStr;
TickList m_tickList;
double m_majorTickValueDistance;
double m_firstMajorTickValue;
int m_numMinorTicks;
int m_decimalPlaces;
QString formatTick(double value, int decimalPlaces, bool fancyTime = true);
void calcCharSize();
void calcScaleFactor();
double calcMajorTickUnits(double distance, int* retDecimalPlaces);
int calcTickTextSize();
void forceTwoTicks();
void reCalc();
double majorTickValue(int tick);
double minorTickValue(int tick);
public:
ScaleEngine();
void setOrientation(Qt::Orientation orientation);
void setFont(const QFont& font);
void setSize(float size);
float getSize() { return m_size; }
void setRange(Unit::Physical physicalUnit, float rangeMin, float rangeMax);
float getPosFromValue(double value);
float getValueFromPos(double pos);
const TickList& getTickList();
QString getRangeMinStr();
QString getRangeMaxStr();
float getScaleWidth();
};
#endif // INCLUDE_SCALEENGINE_H

View File

@ -1,78 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <QWidget>
#include <QTimer>
#include "gui/colormapper.h"
#include "util/export.h"
class SDRANGEL_API ValueDial : public QWidget {
Q_OBJECT
public:
ValueDial(QWidget* parent = NULL, ColorMapper colorMapper = ColorMapper(ColorMapper::Normal));
void setValue(quint64 value);
void setValueRange(uint numDigits, quint64 min, quint64 max);
void setFont(const QFont& font);
void setBold(bool bold);
void setColorMapper(ColorMapper colorMapper);
quint64 getValue() const { return m_value; }
signals:
void changed(quint64 value);
private:
QLinearGradient m_background;
int m_numDigits;
int m_numDecimalPoints;
int m_digitWidth;
int m_digitHeight;
int m_hightlightedDigit;
int m_cursor;
bool m_cursorState;
quint64 m_value;
quint64 m_valueMax;
quint64 m_valueMin;
QString m_text;
quint64 m_valueNew;
QString m_textNew;
int m_animationState;
QTimer m_animationTimer;
QTimer m_blinkTimer;
ColorMapper m_colorMapper;
quint64 findExponent(int digit);
QChar digitNeigh(QChar c, bool dir);
QString formatText(quint64 value);
void paintEvent(QPaintEvent*);
void mousePressEvent(QMouseEvent*);
void mouseMoveEvent(QMouseEvent*);
void wheelEvent(QWheelEvent*);
void leaveEvent(QEvent*);
void keyPressEvent(QKeyEvent*);
void focusInEvent(QFocusEvent*);
void focusOutEvent(QFocusEvent*);
private slots:
void animate();
void blink();
};

View File

@ -1,158 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_MAINWINDOW_H
#define INCLUDE_MAINWINDOW_H
#include <QMainWindow>
#include <QTimer>
#include "settings/mainsettings.h"
#include "util/messagequeue.h"
#include "util/export.h"
class QLabel;
class QTreeWidgetItem;
class QDir;
class QComboBox;
class AudioDeviceInfo;
class DSPEngine;
class Indicator;
class SpectrumVis;
class GLSpectrum;
class GLSpectrumGUI;
class ChannelWindow;
class FileSink;
class SampleSource;
class PluginAPI;
class PluginGUI;
class ChannelMarker;
class PluginManager;
class PluginInterface;
namespace Ui {
class MainWindow;
}
class SDRANGEL_API MainWindow : public QMainWindow {
Q_OBJECT
public:
struct DeviceUISet
{
SpectrumVis *m_spectrumVis;
GLSpectrum *m_spectrum;
GLSpectrumGUI *m_spectrumGUI;
ChannelWindow *m_channelWindow;
QComboBox *m_sampleSource;
DeviceUISet(QTimer& timer);
~DeviceUISet();
};
explicit MainWindow(QWidget* parent = 0);
~MainWindow();
MessageQueue* getInputMessageQueue() { return &m_inputMessageQueue; }
void addChannelCreateAction(QAction* action);
void addChannelRollup(QWidget* widget);
void addViewAction(QAction* action);
void addChannelMarker(ChannelMarker* channelMarker);
void removeChannelMarker(ChannelMarker* channelMarker);
void setInputGUI(QWidget* gui);
const QTimer& getMasterTimer() const { return m_masterTimer; }
private:
enum {
PGroup,
PItem
};
Ui::MainWindow* ui;
AudioDeviceInfo* m_audioDeviceInfo;
MessageQueue m_inputMessageQueue;
MainSettings m_settings;
SpectrumVis* m_rxSpectrumVis;
FileSink *m_fileSink;
std::vector<DeviceUISet*> m_deviceUIs;
DSPEngine* m_dspEngine;
QTimer m_masterTimer;
QTimer m_statusTimer;
int m_lastEngineState;
QLabel* m_sampleRateWidget;
Indicator* m_recording;
Indicator* m_engineIdle;
Indicator* m_engineRunning;
Indicator* m_engineError;
bool m_startOsmoSDRUpdateAfterStop;
QWidget* m_inputGUI;
int m_sampleRate;
quint64 m_centerFrequency;
std::string m_sampleFileName;
PluginManager* m_pluginManager;
void loadSettings();
void loadPresetSettings(const Preset* preset);
void savePresetSettings(Preset* preset);
void saveSettings();
void createStatusBar();
void closeEvent(QCloseEvent*);
void updateCenterFreqDisplay();
void updateSampleRate();
void updatePresetControls();
QTreeWidgetItem* addPresetToTree(const Preset* preset);
void applySettings();
private slots:
void handleDSPMessages();
void handleMessages();
void updateStatus();
void on_action_Start_triggered();
void on_action_Stop_triggered();
void on_action_Start_Recording_triggered();
void on_action_Stop_Recording_triggered();
void on_action_View_Fullscreen_toggled(bool checked);
void on_presetSave_clicked();
void on_presetUpdate_clicked();
void on_settingsSave_clicked();
void on_presetLoad_clicked();
void on_presetDelete_clicked();
void on_presetTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
void on_presetTree_itemActivated(QTreeWidgetItem *item, int column);
void on_action_Loaded_Plugins_triggered();
void on_action_Preferences_triggered();
void on_sampleSource_currentIndexChanged(int index);
void on_action_About_triggered();
};
#endif // INCLUDE_MAINWINDOW_H

View File

@ -1,65 +0,0 @@
#ifndef INCLUDE_PLUGINAPI_H
#define INCLUDE_PLUGINAPI_H
#include <QObject>
#include "util/export.h"
class QDockWidget;
class QAction;
class PluginManager;
class PluginInterface;
class SampleSource;
class SampleSink;
class DSPEngine;
class AudioFifo;
class MessageQueue;
class MainWindow;
class ChannelMarker;
class PluginGUI;
class SDRANGEL_API PluginAPI : public QObject {
Q_OBJECT
public:
// MainWindow access
QDockWidget* createMainWindowDock(Qt::DockWidgetArea dockWidgetArea, const QString& title);
MessageQueue* getMainWindowMessageQueue();
void setInputGUI(QWidget* inputGUI);
// Channel stuff
void registerChannel(const QString& channelName, PluginInterface* plugin, QAction* action);
void registerChannelInstance(const QString& channelName, PluginGUI* pluginGUI);
void addChannelRollup(QWidget* pluginGUI);
void removeChannelInstance(PluginGUI* pluginGUI);
void addChannelMarker(ChannelMarker* channelMarker);
void removeChannelMarker(ChannelMarker* channelMarker);
// DSPEngine access
/* Direct access with DSP engine singleton
void setSampleSource(SampleSource* sampleSource);
void addSampleSink(SampleSink* sampleSink);
void removeSampleSink(SampleSink* sampleSink);
MessageQueue* getDSPEngineMessageQueue();
void addAudioSource(AudioFifo* audioFifo);
void removeAudioSource(AudioFifo* audioFifo);
*/
// Sample Source stuff
void registerSampleSource(const QString& sourceName, PluginInterface* plugin);
// R/O access to main window
const MainWindow* getMainWindow() const { return m_mainWindow; }
protected:
PluginManager* m_pluginManager;
MainWindow* m_mainWindow;
DSPEngine* m_dspEngine;
PluginAPI(PluginManager* pluginManager, MainWindow* mainWindow, DSPEngine* dspEngine);
friend class PluginManager;
};
#endif // INCLUDE_PLUGINAPI_H

View File

@ -1,30 +0,0 @@
#ifndef INCLUDE_PLUGINGUI_H
#define INCLUDE_PLUGINGUI_H
#include <QWidget>
#include "util/export.h"
class Message;
class SDRANGEL_API PluginGUI {
public:
PluginGUI() { };
virtual ~PluginGUI() { };
virtual void destroy() = 0;
virtual void setName(const QString& name) = 0;
virtual QString getName() const = 0;
virtual void resetToDefaults() = 0;
virtual qint64 getCenterFrequency() const = 0;
virtual void setCenterFrequency(qint64 centerFrequency) = 0;
virtual QByteArray serialize() const = 0;
virtual bool deserialize(const QByteArray& data) = 0;
virtual bool handleMessage(const Message& message) = 0;
};
#endif // INCLUDE_PLUGINGUI_H

View File

@ -1,54 +0,0 @@
#ifndef INCLUDE_PLUGININTERFACE_H
#define INCLUDE_PLUGININTERFACE_H
#include <QtPlugin>
#include <QString>
struct PluginDescriptor {
// general plugin description
const QString displayedName;
const QString version;
const QString copyright;
const QString website;
bool licenseIsGPL;
const QString sourceCodeURL;
};
class PluginAPI;
class PluginGUI;
class PluginInterface {
public:
struct SampleSourceDevice
{
QString displayedName;
QString id;
QString serial;
int sequence;
SampleSourceDevice(const QString& _displayedName,
const QString& _id,
const QString& _serial,
int _sequence) :
displayedName(_displayedName),
id(_id),
serial(_serial),
sequence(_sequence)
{ }
};
typedef QList<SampleSourceDevice> SampleSourceDevices;
virtual ~PluginInterface() { };
virtual const PluginDescriptor& getPluginDescriptor() const = 0;
virtual void initPlugin(PluginAPI* pluginAPI) = 0;
virtual PluginGUI* createChannel(const QString& channelName) { return 0; }
virtual SampleSourceDevices enumSampleSources() { return SampleSourceDevices(); }
virtual PluginGUI* createSampleSourcePluginGUI(const QString& sourceId) { return 0; }
};
Q_DECLARE_INTERFACE(PluginInterface, "SDRangel.PluginInterface/0.1");
#endif // INCLUDE_PLUGININTERFACE_H

View File

@ -1,146 +0,0 @@
#ifndef INCLUDE_PLUGINMANAGER_H
#define INCLUDE_PLUGINMANAGER_H
#include <QObject>
#include <QDir>
#include "plugin/plugininterface.h"
#include "plugin/pluginapi.h"
#include "util/export.h"
class QAction;
class QComboBox;
class QPluginLoader;
class Preset;
class MainWindow;
class SampleSource;
class Message;
class SDRANGEL_API PluginManager : public QObject {
Q_OBJECT
public:
struct Plugin
{
QString filename;
QPluginLoader* loader;
PluginInterface* pluginInterface;
Plugin(const QString& _filename, QPluginLoader* pluginLoader, PluginInterface* _plugin) :
filename(_filename),
loader(pluginLoader),
pluginInterface(_plugin)
{ }
};
typedef QList<Plugin> Plugins;
explicit PluginManager(MainWindow* mainWindow, DSPEngine* dspEngine, QObject* parent = NULL);
~PluginManager();
void loadPlugins();
const Plugins& getPlugins() const { return m_plugins; }
void registerChannel(const QString& channelName, PluginInterface* plugin, QAction* action);
void registerChannelInstance(const QString& channelName, PluginGUI* pluginGUI);
void addChannelRollup(QWidget* pluginGUI);
void removeChannelInstance(PluginGUI* pluginGUI);
void registerSampleSource(const QString& sourceName, PluginInterface* plugin);
void loadSettings(const Preset* preset);
void loadSourceSettings(const Preset* preset);
void saveSettings(Preset* preset);
void saveSourceSettings(Preset* preset);
void freeAll();
bool handleMessage(const Message& message);
void updateSampleSourceDevices();
void fillSampleSourceSelector(QComboBox* comboBox);
int selectSampleSourceByIndex(int index);
int selectFirstSampleSource(const QString& sourceId);
int selectSampleSourceBySerialOrSequence(const QString& sourceId, const QString& sourceSerial, int sourceSequence);
private:
struct ChannelRegistration {
QString m_channelName;
PluginInterface* m_plugin;
ChannelRegistration(const QString& channelName, PluginInterface* plugin) :
m_channelName(channelName),
m_plugin(plugin)
{ }
};
typedef QList<ChannelRegistration> ChannelRegistrations;
struct ChannelInstanceRegistration {
QString m_channelName;
PluginGUI* m_gui;
ChannelInstanceRegistration() :
m_channelName(),
m_gui(NULL)
{ }
ChannelInstanceRegistration(const QString& channelName, PluginGUI* pluginGUI) :
m_channelName(channelName),
m_gui(pluginGUI)
{ }
bool operator<(const ChannelInstanceRegistration& other) const;
};
typedef QList<ChannelInstanceRegistration> ChannelInstanceRegistrations;
struct SampleSourceRegistration {
QString m_sourceId;
PluginInterface* m_plugin;
SampleSourceRegistration(const QString& sourceId, PluginInterface* plugin) :
m_sourceId(sourceId),
m_plugin(plugin)
{ }
};
typedef QList<SampleSourceRegistration> SampleSourceRegistrations;
struct SampleSourceDevice {
PluginInterface* m_plugin;
QString m_displayName;
QString m_sourceId;
QString m_sourceSerial;
int m_sourceSequence;
SampleSourceDevice(PluginInterface* plugin,
const QString& displayName,
const QString& sourceId,
const QString& sourceSerial,
int sourceSequence) :
m_plugin(plugin),
m_displayName(displayName),
m_sourceId(sourceId),
m_sourceSerial(sourceSerial),
m_sourceSequence(sourceSequence)
{ }
};
typedef QList<SampleSourceDevice> SampleSourceDevices;
PluginAPI m_pluginAPI;
MainWindow* m_mainWindow;
DSPEngine* m_dspEngine;
Plugins m_plugins;
ChannelRegistrations m_channelRegistrations;
ChannelInstanceRegistrations m_channelInstanceRegistrations;
SampleSourceRegistrations m_sampleSourceRegistrations;
SampleSourceDevices m_sampleSourceDevices;
QString m_sampleSourceId;
QString m_sampleSourceSerial;
int m_sampleSourceSequence;
PluginGUI* m_sampleSourcePluginGUI;
void loadPlugins(const QDir& dir);
void renameChannelInstances();
};
static inline bool operator<(const PluginManager::Plugin& a, const PluginManager::Plugin& b)
{
return a.pluginInterface->getPluginDescriptor().displayedName < b.pluginInterface->getPluginDescriptor().displayedName;
}
#endif // INCLUDE_PLUGINMANAGER_H

View File

@ -1,34 +0,0 @@
#ifndef INCLUDE_SETTINGS_H
#define INCLUDE_SETTINGS_H
#include <QString>
#include "preferences.h"
#include "preset.h"
class MainSettings {
public:
MainSettings();
~MainSettings();
void load();
void save() const;
void resetToDefaults();
Preset* newPreset(const QString& group, const QString& description);
void deletePreset(const Preset* preset);
int getPresetCount() const { return m_presets.count(); }
const Preset* getPreset(int index) const { return m_presets[index]; }
Preset* getWorkingPreset() { return &m_workingPreset; }
int getSourceIndex() const { return m_preferences.getSourceIndex(); }
void setSourceIndex(int value) { m_preferences.setSourceIndex(value); }
protected:
Preferences m_preferences;
Preset m_workingPreset;
typedef QList<Preset*> Presets;
Presets m_presets;
};
#endif // INCLUDE_SETTINGS_H

View File

@ -1,35 +0,0 @@
#ifndef INCLUDE_PREFERENCES_H
#define INCLUDE_PREFERENCES_H
#include <QString>
class Preferences {
public:
Preferences();
void resetToDefaults();
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
void setSourceType(const QString& value) { m_sourceType = value; }
const QString& getSourceType() const { return m_sourceType; }
void setSourceDevice(const QString& value) { m_sourceDevice= value; }
const QString& getSourceDevice() const { return m_sourceDevice; }
void setSourceIndex(const int value) { m_sourceIndex = value; }
int getSourceIndex() const { return m_sourceIndex; }
void setAudioType(const QString& value) { m_audioType = value; }
const QString& getAudioType() const { return m_audioType; }
void setAudioDevice(const QString& value) { m_audioDevice= value; }
const QString& getAudioDevice() const { return m_audioDevice; }
protected:
QString m_sourceType;
QString m_sourceDevice;
int m_sourceIndex;
QString m_audioType;
QString m_audioDevice;
};
#endif // INCLUDE_PREFERENCES_H

View File

@ -1,110 +0,0 @@
#ifndef INCLUDE_PRESET_H
#define INCLUDE_PRESET_H
#include <QString>
#include <QList>
#include <QMetaType>
class Preset {
public:
struct ChannelConfig {
QString m_channel;
QByteArray m_config;
ChannelConfig(const QString& channel, const QByteArray& config) :
m_channel(channel),
m_config(config)
{ }
};
typedef QList<ChannelConfig> ChannelConfigs;
struct SourceConfig
{
QString m_sourceId;
QString m_sourceSerial;
int m_sourceSequence;
QByteArray m_config;
SourceConfig(const QString& sourceId,
const QString& sourceSerial,
int sourceSequence,
const QByteArray& config) :
m_sourceId(sourceId),
m_sourceSerial(sourceSerial),
m_sourceSequence(sourceSequence),
m_config(config)
{ }
};
typedef QList<SourceConfig> SourceConfigs;
Preset();
void resetToDefaults();
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
void setGroup(const QString& group) { m_group = group; }
const QString& getGroup() const { return m_group; }
void setDescription(const QString& description) { m_description = description; }
const QString& getDescription() const { return m_description; }
void setCenterFrequency(const quint64 centerFrequency) { m_centerFrequency = centerFrequency; }
quint64 getCenterFrequency() const { return m_centerFrequency; }
void setSpectrumConfig(const QByteArray& data) { m_spectrumConfig = data; }
const QByteArray& getSpectrumConfig() const { return m_spectrumConfig; }
void setLayout(const QByteArray& data) { m_layout = data; }
const QByteArray& getLayout() const { return m_layout; }
void clearChannels() { m_channelConfigs.clear(); }
void addChannel(const QString& channel, const QByteArray& config) { m_channelConfigs.append(ChannelConfig(channel, config)); }
int getChannelCount() const { return m_channelConfigs.count(); }
const ChannelConfig& getChannelConfig(int index) const { return m_channelConfigs.at(index); }
void setSourceConfig(const QString& sourceId, const QString& sourceSerial, int sourceSequence, const QByteArray& config)
{
addOrUpdateSourceConfig(sourceId, sourceSerial, sourceSequence, config);
}
void addOrUpdateSourceConfig(const QString& sourceId,
const QString& sourceSerial,
int sourceSequence,
const QByteArray& config);
const QByteArray* findBestSourceConfig(const QString& sourceId,
const QString& sourceSerial,
int sourceSequence) const;
protected:
// group and preset description
QString m_group;
QString m_description;
quint64 m_centerFrequency;
// general configuration
QByteArray m_spectrumConfig;
// dc offset and i/q imbalance correction TODO: move it into the source data
bool m_dcOffsetCorrection;
bool m_iqImbalanceCorrection;
// sample source and sample source configuration
QString m_sourceId;
QString m_sourceSerial;
int m_sourceSequence;
QByteArray m_sourceConfig;
// channels and configurations
ChannelConfigs m_channelConfigs;
// sources and configurations
SourceConfigs m_sourceConfigs;
// screen and dock layout
QByteArray m_layout;
};
Q_DECLARE_METATYPE(const Preset*);
Q_DECLARE_METATYPE(Preset*);
#endif // INCLUDE_PRESET_H

View File

@ -1,38 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 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_CRC64_H_
#define INCLUDE_CRC64_H_
#include <stdint.h>
class CRC64
{
public:
CRC64();
~CRC64();
uint64_t calculate_crc(uint8_t *stream, int length);
private:
void build_crc_table();
uint64_t m_crcTable[256];
static const uint64_t m_poly;
};
#endif /* INCLUDE_CRC64_H_ */

View File

@ -1,53 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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 _UTIL_BITFIELDINDEX_H_
#define _UTIL_BITFIELDINDEX_H_
#include <stdint.h>
template <unsigned int size>
struct BitfieldIndex
{
uint32_t v : size;
BitfieldIndex() {}
BitfieldIndex(int i) { v = i; }
BitfieldIndex& operator=(const BitfieldIndex& rhs) { v = rhs.v; return *this; }
BitfieldIndex& operator=(const int& rhi) { v = rhi; return *this; }
BitfieldIndex& operator++() { v++; return *this; }
BitfieldIndex operator++(int) { BitfieldIndex x(*this); ++(*this); return x; }
BitfieldIndex& operator+=(const BitfieldIndex& b) { v += b.v; return *this; }
BitfieldIndex& operator-=(const BitfieldIndex& b) { v -= b.v; return *this; }
BitfieldIndex& operator+=(int i) { v += i; return *this; }
BitfieldIndex& operator-=(int i) { v -= i; return *this; }
BitfieldIndex operator+(const BitfieldIndex& b) const { BitfieldIndex x(*this); x.v += b.v; return x; }
BitfieldIndex operator-(const BitfieldIndex& b) const { BitfieldIndex x(*this); x.v -= b.v; return x; }
BitfieldIndex operator+(int i) const { BitfieldIndex x(*this); x.v += i; return x; }
BitfieldIndex operator-(int i) const { BitfieldIndex x(*this); x.v -= i; return x; }
operator int() const { return v; }
};
template <unsigned int size>
BitfieldIndex<size> operator+(const BitfieldIndex<size> &a, const BitfieldIndex<size> &b) { BitfieldIndex<size> x; x.v = x.a + x.b; return x; }
template <unsigned int size>
BitfieldIndex<size> operator-(const BitfieldIndex<size> &a, const BitfieldIndex<size> &b) { BitfieldIndex<size> x; x.v = x.a - x.b; return x; }
#endif // _UTIL_BITFIELDINDEX_H_

View File

@ -1,28 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_UTIL_DB_H_
#define INCLUDE_UTIL_DB_H_
#include "dsp/dsptypes.h"
class CalcDb
{
public:
static Real dbPower(Real magsq);
};
#endif /* INCLUDE_UTIL_DB_H_ */

View File

@ -1,45 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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 __SDRANGEL_EXPORT_H
#define __SDRANGEL_EXPORT_H
#if defined __GNUC__
# if __GNUC__ >= 4
# define __SDR_EXPORT __attribute__((visibility("default")))
# define __SDR_IMPORT __attribute__((visibility("default")))
# else
# define __SDR_EXPORT
# define __SDR_IMPORT
# endif
#elif _MSC_VER
# define __SDR_EXPORT __declspec(dllexport)
# define __SDR_IMPORT __declspec(dllimport)
#else
# define __SDR_EXPORT
# define __SDR_IMPORT
#endif
#ifndef sdrangel_STATIC
# ifdef sdrangel_EXPORTS
# define SDRANGEL_API __SDR_EXPORT
# else
# define SDRANGEL_API __SDR_IMPORT
# endif
#else
#define SDRANGEL_API
#endif
#endif /* __SDRANGEL_EXPORT_H */

View File

@ -1,59 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_MESSAGE_H
#define INCLUDE_MESSAGE_H
#include <stdlib.h>
#include "util/export.h"
class SDRANGEL_API Message {
public:
Message();
virtual ~Message();
virtual const char* getIdentifier() const;
virtual bool matchIdentifier(const char* identifier) const;
static bool match(const Message* message);
void* getDestination() const { return m_destination; }
void setDestination(void *destination) { m_destination = destination; }
protected:
// addressing
static const char* m_identifier;
void* m_destination;
};
#define MESSAGE_CLASS_DECLARATION \
public: \
const char* getIdentifier() const; \
bool matchIdentifier(const char* identifier) const; \
static bool match(const Message& message); \
protected: \
static const char* m_identifier; \
private:
#define MESSAGE_CLASS_DEFINITION(Name, BaseClass) \
const char* Name::m_identifier = #Name; \
const char* Name::getIdentifier() const { return m_identifier; } \
bool Name::matchIdentifier(const char* identifier) const {\
return (m_identifier == identifier) ? true : BaseClass::matchIdentifier(identifier); \
} \
bool Name::match(const Message& message) { return message.matchIdentifier(m_identifier); }
#endif // INCLUDE_MESSAGE_H

View File

@ -1,49 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_MESSAGEQUEUE_H
#define INCLUDE_MESSAGEQUEUE_H
#include <QObject>
#include <QQueue>
#include <QMutex>
#include "util/export.h"
class Message;
class SDRANGEL_API MessageQueue : public QObject {
Q_OBJECT
public:
MessageQueue(QObject* parent = NULL);
~MessageQueue();
void push(Message* message, bool emitSignal = true); //!< Push message onto queue
Message* pop(); //!< Pop message from queue
int size(); //!< Returns queue size
void clear(); //!< Empty queue
signals:
void messageEnqueued();
private:
QMutex m_lock;
QQueue<Message*> m_queue;
};
#endif // INCLUDE_MESSAGEQUEUE_H

View File

@ -1,40 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_UTIL_PRETTYPRINT_H_
#define INCLUDE_UTIL_PRETTYPRINT_H_
#include <QString>
class EscapeColors
{
public:
static const QString red;
static const QString blue;
static const QString green;
static const QString cyan;
static const QString purple;
static const QString yellow;
static const QString lightRed;
static const QString lightBlue;
static const QString lightGreen;
static const QString lightCyan;
static const QString lightPurple;
static const QString brown;
static const QString terminator;
};
#endif /* INCLUDE_UTIL_PRETTYPRINT_H_ */

View File

@ -1,50 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_UTIL_SAMPLESOURCESERIALIZER_H_
#define INCLUDE_UTIL_SAMPLESOURCESERIALIZER_H_
#include "util/simpleserializer.h"
class SampleSourceSerializer
{
public:
struct Data
{
quint64 m_frequency; //!< RF center frequency
qint32 m_correction; //!< LO correction factor
qint32 m_rate; //!< RF sampler sample rate
quint32 m_log2Decim; //!< Decimation ratio log2
qint32 m_bandwidth; //!< RF bandwidth
qint32 m_fcPosition; //!< Decimated band placement (infradyne, supradyne, centered)
qint32 m_lnaGain; //!< RF LNA gain
qint32 m_RxGain1; //!< Rx first stage amplifier gain
qint32 m_RxGain2; //!< Rx second stage amplifier gain
qint32 m_RxGain3; //!< Rx third stage amplifier gain
};
static void writeSerializedData(const Data& data, QByteArray& serializedData);
static bool readSerializedData(const QByteArray& serializedData, Data& data);
static void setDefaults(Data& data);
static uint getSerializerVersion() { return m_version; }
protected:
static const uint m_version;
};
#endif /* INCLUDE_UTIL_SAMPLESOURCESERIALIZER_H_ */

View File

@ -1,112 +0,0 @@
#ifndef INCLUDE_SIMPLESERIALIZER_H
#define INCLUDE_SIMPLESERIALIZER_H
#include <QString>
#include <QMap>
#include "dsp/dsptypes.h"
#include "util/export.h"
class SDRANGEL_API SimpleSerializer {
public:
SimpleSerializer(quint32 version);
void writeS32(quint32 id, qint32 value);
void writeU32(quint32 id, quint32 value);
void writeS64(quint32 id, qint64 value);
void writeU64(quint32 id, quint64 value);
void writeFloat(quint32 id, float value);
void writeDouble(quint32 id, double value);
void writeReal(quint32 id, Real value)
{
if(sizeof(Real) == 4)
writeFloat(id, value);
else writeDouble(id, value);
}
void writeBool(quint32 id, bool value);
void writeString(quint32 id, const QString& value);
void writeBlob(quint32 id, const QByteArray& value);
const QByteArray& final();
protected:
enum Type {
TSigned32 = 0,
TUnsigned32 = 1,
TSigned64 = 2,
TUnsigned64 = 3,
TFloat = 4,
TDouble = 5,
TBool = 6,
TString = 7,
TBlob = 8,
TVersion = 9
};
QByteArray m_data;
bool m_finalized;
bool writeTag(Type type, quint32 id, quint32 length);
};
class SDRANGEL_API SimpleDeserializer {
public:
SimpleDeserializer(const QByteArray& data);
bool readS32(quint32 id, qint32* result, qint32 def = 0) const;
bool readU32(quint32 id, quint32* result, quint32 def = 0) const;
bool readS64(quint32 id, qint64* result, qint64 def = 0) const;
bool readU64(quint32 id, quint64* result, quint64 def = 0) const;
bool readFloat(quint32 id, float* result, float def = 0) const;
bool readDouble(quint32 id, double* result, double def = 0) const;
bool readReal(quint32 id, Real* result, Real def = 0) const;
bool readBool(quint32 id, bool* result, bool def = false) const;
bool readString(quint32 id, QString* result, const QString& def = QString::null) const;
bool readBlob(quint32 id, QByteArray* result, const QByteArray& def = QByteArray()) const;
bool isValid() const { return m_valid; }
quint32 getVersion() const { return m_version; }
void dump() const;
private:
enum Type {
TSigned32 = 0,
TUnsigned32 = 1,
TSigned64 = 2,
TUnsigned64 = 3,
TFloat = 4,
TDouble = 5,
TBool = 6,
TString = 7,
TBlob = 8,
TVersion = 9
};
struct Element {
Type type;
quint32 ofs;
quint32 length;
Element(Type _type, quint32 _ofs, quint32 _length) :
type(_type),
ofs(_ofs),
length(_length)
{ }
};
typedef QMap<quint32, Element> Elements;
QByteArray m_data;
bool m_valid;
Elements m_elements;
quint32 m_version;
bool parseAll();
bool readTag(uint* readOfs, uint readEnd, Type* type, quint32* id, quint32* length) const;
quint8 readByte(uint* readOfs) const
{
quint8 res = m_data[*readOfs];
(*readOfs)++;
return res;
}
};
#endif // INCLUDE_SIMPLESERIALIZER_H

View File

@ -1,39 +0,0 @@
#ifndef INCLUDE_SPINLOCK_H
#define INCLUDE_SPINLOCK_H
#include <QAtomicInt>
class Spinlock {
public:
void lock()
{
while(!m_atomic.testAndSetAcquire(0, 1)) ;
}
void unlock()
{
while(!m_atomic.testAndSetRelease(1, 0)) ;
}
protected:
QAtomicInt m_atomic;
};
class SpinlockHolder {
public:
SpinlockHolder(Spinlock* spinlock) :
m_spinlock(spinlock)
{
m_spinlock->lock();
}
~SpinlockHolder()
{
m_spinlock->unlock();
}
protected:
Spinlock* m_spinlock;
};
#endif // INCLUDE_SPINLOCK_H

View File

@ -1,93 +0,0 @@
// stacktrace.h (c) 2008, Timo Bingmann from http://idlebox.net/
// published under the WTFPL v2.0
#ifndef _STACKTRACE_H_
#define _STACKTRACE_H_
#include <stdio.h>
#include <stdlib.h>
#include <execinfo.h>
#include <cxxabi.h>
/** Print a demangled stack backtrace of the caller function to FILE* out. */
static inline void print_stacktrace(FILE *out = stderr, unsigned int max_frames = 63)
{
fprintf(out, "stack trace:\n");
// storage array for stack trace address data
void* addrlist[max_frames+1];
// retrieve current stack addresses
int addrlen = backtrace(addrlist, sizeof(addrlist) / sizeof(void*));
if (addrlen == 0) {
fprintf(out, " <empty, possibly corrupt>\n");
return;
}
// resolve addresses into strings containing "filename(function+address)",
// this array must be free()-ed
char** symbollist = backtrace_symbols(addrlist, addrlen);
// allocate string which will be filled with the demangled function name
size_t funcnamesize = 256;
char* funcname = (char*)malloc(funcnamesize);
// iterate over the returned symbol lines. skip the first, it is the
// address of this function.
for (int i = 1; i < addrlen; i++)
{
char *begin_name = 0, *begin_offset = 0, *end_offset = 0;
// find parentheses and +address offset surrounding the mangled name:
// ./module(function+0x15c) [0x8048a6d]
for (char *p = symbollist[i]; *p; ++p)
{
if (*p == '(')
begin_name = p;
else if (*p == '+')
begin_offset = p;
else if (*p == ')' && begin_offset) {
end_offset = p;
break;
}
}
if (begin_name && begin_offset && end_offset
&& begin_name < begin_offset)
{
*begin_name++ = '\0';
*begin_offset++ = '\0';
*end_offset = '\0';
// mangled name is now in [begin_name, begin_offset) and caller
// offset in [begin_offset, end_offset). now apply
// __cxa_demangle():
int status;
char* ret = abi::__cxa_demangle(begin_name,
funcname, &funcnamesize, &status);
if (status == 0) {
funcname = ret; // use possibly realloc()-ed string
fprintf(out, " %s : %s+%s\n",
symbollist[i], funcname, begin_offset);
}
else {
// demangling failed. Output function name as a C function with
// no arguments.
fprintf(out, " %s : %s()+%s\n",
symbollist[i], begin_name, begin_offset);
}
}
else
{
// couldn't parse the line? print the whole line.
fprintf(out, " %s\n", symbollist[i]);
}
}
free(funcname);
free(symbollist);
}
#endif // _STACKTRACE_H_

View File

@ -1,57 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_UTIL_SYNCMESSENGER_H_
#define INCLUDE_UTIL_SYNCMESSENGER_H_
#include <QObject>
#include <QWaitCondition>
#include <QMutex>
#include <QAtomicInt>
#include "util/export.h"
class Message;
/**
* This class is responsible of managing the synchronous processing of a message across threads
*/
class SDRANGEL_API SyncMessenger : public QObject {
Q_OBJECT
public:
SyncMessenger();
~SyncMessenger();
int sendWait(Message& message, unsigned long msPollTime = 100); //!< Send message and waits for its process completion
Message* getMessage() const { return m_message; }
void storeMessage(Message& message) { m_message = &message; }
void done(int result = 0); //!< Processing of the message is complete
signals:
void messageSent();
protected:
QWaitCondition m_waitCondition;
QMutex m_mutex;
QAtomicInt m_complete;
Message *m_message;
int m_result;
};
#endif /* INCLUDE_UTIL_SYNCMESSENGER_H_ */

View File

@ -1,39 +0,0 @@
/*
* threadsafesingleton.h
*
* Created on: Aug 7, 2015
* Author: f4exb
*/
#ifndef INCLUDE_UTIL_THREADSAFESINGLETON_H_
#define INCLUDE_UTIL_THREADSAFESINGLETON_H_
//! Template class used to make from a class a singleton.
/** S is the type of the singleton object to instantiate.
<br> This class permits to gather all singleton code in the same place
and not to pollute object interface with singleton methods.
<br> Accessing to the instance of S is made through ThreadSafeSingleton<S>::instance()
<br><B>Note :</B> The class using this adapter should have constructor and
destructor protected and copy constructor and operator= private.
<br>Besides it should declare the class ThreadSafeSingleton<S> friend in order
this class can make the construction.
*/
template <class S> class ThreadSafeSingleton
{
public:
static S& instance() { return *_pInstance; }
protected:
ThreadSafeSingleton() {}
~ThreadSafeSingleton() { delete _pInstance; }
static S* _pInstance;
private:
ThreadSafeSingleton(const ThreadSafeSingleton&) {}
ThreadSafeSingleton& operator = (const ThreadSafeSingleton&) {return *this;}
};
template <class S> S *ThreadSafeSingleton<S>::_pInstance = new S;
#endif /* INCLUDE_UTIL_THREADSAFESINGLETON_H_ */

View File

@ -1,81 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////
// 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_UTIL_UDPSINK_H_
#define INCLUDE_UTIL_UDPSINK_H_
#include <QObject>
#include <QUdpSocket>
#include <QHostAddress>
template<typename T>
class UDPSink
{
public:
UDPSink(QObject *parent, unsigned int udpSize, unsigned int port) :
m_udpSize(udpSize),
m_address(QHostAddress::LocalHost),
m_port(port),
m_sampleBufferIndex(0)
{
m_sampleBuffer = new T[m_udpSize];
m_socket = new QUdpSocket(parent);
}
UDPSink (QObject *parent, unsigned int udpSize, QHostAddress& address, unsigned int port) :
m_udpSize(udpSize),
m_address(address),
m_port(port),
m_sampleBufferIndex(0)
{
m_sampleBuffer = new T[m_udpSize];
m_socket = new QUdpSocket(parent);
}
~UDPSink()
{
delete[] m_sampleBuffer;
delete m_socket;
}
void write(T sample)
{
m_sampleBuffer[m_sampleBufferIndex] = sample;
if (m_sampleBufferIndex < m_udpSize)
{
m_sampleBufferIndex++;
}
else
{
m_socket->writeDatagram((const char*)&m_sampleBuffer[0], (qint64 ) (m_udpSize * sizeof(T)), m_address, m_port);
m_sampleBufferIndex = 0;
}
}
private:
unsigned int m_udpSize;
QHostAddress m_address;
unsigned int m_port;
QUdpSocket *m_socket;
T *m_sampleBuffer;;
int m_sampleBufferIndex;
};
#endif /* INCLUDE_UTIL_UDPSINK_H_ */