mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-02-04 13:54:43 +01:00
added stuff idk
This commit is contained in:
parent
8e1c6e9da6
commit
7120e848ef
@ -31,3 +31,7 @@ find_package(FFTW3f CONFIG REQUIRED)
|
|||||||
target_link_libraries(sdrpp PRIVATE FFTW3::fftw3f)
|
target_link_libraries(sdrpp PRIVATE FFTW3::fftw3f)
|
||||||
find_package(FFTW3l CONFIG REQUIRED)
|
find_package(FFTW3l CONFIG REQUIRED)
|
||||||
target_link_libraries(sdrpp PRIVATE FFTW3::fftw3l)
|
target_link_libraries(sdrpp PRIVATE FFTW3::fftw3l)
|
||||||
|
|
||||||
|
# PortAudio
|
||||||
|
find_package(portaudio CONFIG REQUIRED)
|
||||||
|
target_link_libraries(sdrpp PRIVATE portaudio portaudio_static)
|
@ -7,6 +7,10 @@
|
|||||||
namespace cdsp {
|
namespace cdsp {
|
||||||
class FMDemodulator {
|
class FMDemodulator {
|
||||||
public:
|
public:
|
||||||
|
FMDemodulator() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
FMDemodulator(stream<complex_t>* in, float deviation, long sampleRate, int bufferSize) : output(bufferSize * 2) {
|
FMDemodulator(stream<complex_t>* in, float deviation, long sampleRate, int bufferSize) : output(bufferSize * 2) {
|
||||||
_input = in;
|
_input = in;
|
||||||
_bufferSize = bufferSize;
|
_bufferSize = bufferSize;
|
||||||
@ -14,6 +18,14 @@ namespace cdsp {
|
|||||||
_phasorSpeed = (2 * 3.1415926535) / (sampleRate / deviation);
|
_phasorSpeed = (2 * 3.1415926535) / (sampleRate / deviation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init(stream<complex_t>* in, float deviation, long sampleRate, int bufferSize) {
|
||||||
|
output.init(bufferSize * 2);
|
||||||
|
_input = in;
|
||||||
|
_bufferSize = bufferSize;
|
||||||
|
_phase = 0.0f;
|
||||||
|
_phasorSpeed = (2 * 3.1415926535) / (sampleRate / deviation);
|
||||||
|
}
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
_workerThread = std::thread(_worker, this);
|
_workerThread = std::thread(_worker, this);
|
||||||
}
|
}
|
||||||
|
@ -14,11 +14,21 @@ namespace cdsp {
|
|||||||
|
|
||||||
class RawFileSource {
|
class RawFileSource {
|
||||||
public:
|
public:
|
||||||
|
RawFileSource() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
RawFileSource(std::string path, int bufferSize) : output(bufferSize * 2) {
|
RawFileSource(std::string path, int bufferSize) : output(bufferSize * 2) {
|
||||||
_bufferSize = bufferSize;
|
_bufferSize = bufferSize;
|
||||||
_file = std::ifstream(path.c_str(), std::ios::in | std::ios::binary);
|
_file = std::ifstream(path.c_str(), std::ios::in | std::ios::binary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init(std::string path, int bufferSize) {
|
||||||
|
output.init(bufferSize * 2);
|
||||||
|
_bufferSize = bufferSize;
|
||||||
|
_file = std::ifstream(path.c_str(), std::ios::in | std::ios::binary);
|
||||||
|
}
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
_workerThread = std::thread(_worker, this);
|
_workerThread = std::thread(_worker, this);
|
||||||
}
|
}
|
||||||
@ -50,12 +60,22 @@ namespace cdsp {
|
|||||||
|
|
||||||
class RawFileSink {
|
class RawFileSink {
|
||||||
public:
|
public:
|
||||||
|
RawFileSink() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
RawFileSink(std::string path, stream<float>* in, int bufferSize) {
|
RawFileSink(std::string path, stream<float>* in, int bufferSize) {
|
||||||
_bufferSize = bufferSize;
|
_bufferSize = bufferSize;
|
||||||
_input = in;
|
_input = in;
|
||||||
_file = std::ofstream(path.c_str(), std::ios::out | std::ios::binary);
|
_file = std::ofstream(path.c_str(), std::ios::out | std::ios::binary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init(std::string path, stream<float>* in, int bufferSize) {
|
||||||
|
_bufferSize = bufferSize;
|
||||||
|
_input = in;
|
||||||
|
_file = std::ofstream(path.c_str(), std::ios::out | std::ios::binary);
|
||||||
|
}
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
_workerThread = std::thread(_worker, this);
|
_workerThread = std::thread(_worker, this);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,10 @@
|
|||||||
namespace cdsp {
|
namespace cdsp {
|
||||||
class FIRFilter {
|
class FIRFilter {
|
||||||
public:
|
public:
|
||||||
|
FIRFilter() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
FIRFilter(stream<complex_t>* input, std::vector<float> taps, int bufferSize) : output(bufferSize * 2) {
|
FIRFilter(stream<complex_t>* input, std::vector<float> taps, int bufferSize) : output(bufferSize * 2) {
|
||||||
_in = input;
|
_in = input;
|
||||||
_bufferSize = bufferSize;
|
_bufferSize = bufferSize;
|
||||||
@ -15,6 +19,15 @@ namespace cdsp {
|
|||||||
_taps = taps;
|
_taps = taps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init(stream<complex_t>* input, std::vector<float> taps, int bufferSize) {
|
||||||
|
output.init(bufferSize * 2);
|
||||||
|
_in = input;
|
||||||
|
_bufferSize = bufferSize;
|
||||||
|
_tapCount = taps.size();
|
||||||
|
delayBuf = new complex_t[_tapCount];
|
||||||
|
_taps = taps;
|
||||||
|
}
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
_workerThread = std::thread(_worker, this);
|
_workerThread = std::thread(_worker, this);
|
||||||
}
|
}
|
||||||
@ -66,9 +79,21 @@ namespace cdsp {
|
|||||||
|
|
||||||
class DCBiasRemover {
|
class DCBiasRemover {
|
||||||
public:
|
public:
|
||||||
|
DCBiasRemover() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
DCBiasRemover(stream<complex_t>* input, int bufferSize) : output(bufferSize * 2) {
|
DCBiasRemover(stream<complex_t>* input, int bufferSize) : output(bufferSize * 2) {
|
||||||
_in = input;
|
_in = input;
|
||||||
_bufferSize = bufferSize;
|
_bufferSize = bufferSize;
|
||||||
|
bypass = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(stream<complex_t>* input, int bufferSize) {
|
||||||
|
output.init(bufferSize * 2);
|
||||||
|
_in = input;
|
||||||
|
_bufferSize = bufferSize;
|
||||||
|
bypass = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
@ -76,6 +101,7 @@ namespace cdsp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stream<complex_t> output;
|
stream<complex_t> output;
|
||||||
|
bool bypass;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void _worker(DCBiasRemover* _this) {
|
static void _worker(DCBiasRemover* _this) {
|
||||||
@ -84,6 +110,10 @@ namespace cdsp {
|
|||||||
float qbias = 0.0f;
|
float qbias = 0.0f;
|
||||||
while (true) {
|
while (true) {
|
||||||
_this->_in->read(buf, _this->_bufferSize);
|
_this->_in->read(buf, _this->_bufferSize);
|
||||||
|
if (_this->bypass) {
|
||||||
|
_this->output.write(buf, _this->_bufferSize);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (int i = 0; i < _this->_bufferSize; i++) {
|
for (int i = 0; i < _this->_bufferSize; i++) {
|
||||||
ibias += buf[i].i;
|
ibias += buf[i].i;
|
||||||
qbias += buf[i].q;
|
qbias += buf[i].q;
|
||||||
@ -102,4 +132,45 @@ namespace cdsp {
|
|||||||
int _bufferSize;
|
int _bufferSize;
|
||||||
std::thread _workerThread;
|
std::thread _workerThread;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class HandlerSink {
|
||||||
|
public:
|
||||||
|
HandlerSink() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
HandlerSink(stream<complex_t>* input, complex_t* buffer, int bufferSize, void handler(complex_t*)) {
|
||||||
|
_in = input;
|
||||||
|
_bufferSize = bufferSize;
|
||||||
|
_buffer = buffer;
|
||||||
|
_handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(stream<complex_t>* input, complex_t* buffer, int bufferSize, void handler(complex_t*)) {
|
||||||
|
_in = input;
|
||||||
|
_bufferSize = bufferSize;
|
||||||
|
_buffer = buffer;
|
||||||
|
_handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start() {
|
||||||
|
_workerThread = std::thread(_worker, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bypass;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void _worker(HandlerSink* _this) {
|
||||||
|
while (true) {
|
||||||
|
_this->_in->read(_this->_buffer, _this->_bufferSize);
|
||||||
|
_this->_handler(_this->_buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stream<complex_t>* _in;
|
||||||
|
int _bufferSize;
|
||||||
|
complex_t* _buffer;
|
||||||
|
std::thread _workerThread;
|
||||||
|
void (*_handler)(complex_t*);
|
||||||
|
};
|
||||||
};
|
};
|
@ -6,12 +6,23 @@
|
|||||||
namespace cdsp {
|
namespace cdsp {
|
||||||
class SineSource {
|
class SineSource {
|
||||||
public:
|
public:
|
||||||
|
SineSource() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
SineSource(float frequency, long sampleRate, int bufferSize) : output(bufferSize * 2) {
|
SineSource(float frequency, long sampleRate, int bufferSize) : output(bufferSize * 2) {
|
||||||
_bufferSize = bufferSize;
|
_bufferSize = bufferSize;
|
||||||
_phasorSpeed = (2 * 3.1415926535) / (sampleRate / frequency);
|
_phasorSpeed = (2 * 3.1415926535) / (sampleRate / frequency);
|
||||||
_phase = 0;
|
_phase = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init(float frequency, long sampleRate, int bufferSize) {
|
||||||
|
output.init(bufferSize * 2);
|
||||||
|
_bufferSize = bufferSize;
|
||||||
|
_phasorSpeed = (2 * 3.1415926535) / (sampleRate / frequency);
|
||||||
|
_phase = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
_workerThread = std::thread(_worker, this);
|
_workerThread = std::thread(_worker, this);
|
||||||
}
|
}
|
||||||
@ -39,10 +50,19 @@ namespace cdsp {
|
|||||||
|
|
||||||
class RandomSource {
|
class RandomSource {
|
||||||
public:
|
public:
|
||||||
|
RandomSource() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
RandomSource(float frequency, long sampleRate, int bufferSize) : output(bufferSize * 2) {
|
RandomSource(float frequency, long sampleRate, int bufferSize) : output(bufferSize * 2) {
|
||||||
_bufferSize = bufferSize;
|
_bufferSize = bufferSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init(float frequency, long sampleRate, int bufferSize) {
|
||||||
|
output.init(bufferSize * 2);
|
||||||
|
_bufferSize = bufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
_workerThread = std::thread(_worker, this);
|
_workerThread = std::thread(_worker, this);
|
||||||
}
|
}
|
||||||
@ -66,12 +86,23 @@ namespace cdsp {
|
|||||||
|
|
||||||
class ComplexSineSource {
|
class ComplexSineSource {
|
||||||
public:
|
public:
|
||||||
|
ComplexSineSource() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ComplexSineSource(float frequency, long sampleRate, int bufferSize) : output(bufferSize * 2) {
|
ComplexSineSource(float frequency, long sampleRate, int bufferSize) : output(bufferSize * 2) {
|
||||||
_bufferSize = bufferSize;
|
_bufferSize = bufferSize;
|
||||||
_phasorSpeed = (2 * 3.1415926535) / (sampleRate / frequency);
|
_phasorSpeed = (2 * 3.1415926535) / (sampleRate / frequency);
|
||||||
_phase = 0;
|
_phase = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init(float frequency, long sampleRate, int bufferSize) {
|
||||||
|
output.init(bufferSize * 2);
|
||||||
|
_bufferSize = bufferSize;
|
||||||
|
_phasorSpeed = (2 * 3.1415926535) / (sampleRate / frequency);
|
||||||
|
_phase = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
_workerThread = std::thread(_worker, this);
|
_workerThread = std::thread(_worker, this);
|
||||||
}
|
}
|
||||||
|
@ -16,11 +16,21 @@ namespace cdsp {
|
|||||||
|
|
||||||
class Complex2HackRF {
|
class Complex2HackRF {
|
||||||
public:
|
public:
|
||||||
|
Complex2HackRF() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Complex2HackRF(stream<complex_t>* in, int bufferSize) : output(bufferSize * 2) {
|
Complex2HackRF(stream<complex_t>* in, int bufferSize) : output(bufferSize * 2) {
|
||||||
_input = in;
|
_input = in;
|
||||||
_bufferSize = bufferSize;
|
_bufferSize = bufferSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init(stream<complex_t>* in, int bufferSize) {
|
||||||
|
output.init(bufferSize * 2);
|
||||||
|
_input = in;
|
||||||
|
_bufferSize = bufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
stream<hackrf_sample_t> output;
|
stream<hackrf_sample_t> output;
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
@ -48,11 +58,21 @@ namespace cdsp {
|
|||||||
|
|
||||||
class HackRF2Complex {
|
class HackRF2Complex {
|
||||||
public:
|
public:
|
||||||
|
HackRF2Complex() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
HackRF2Complex(stream<complex_t>* out, int bufferSize) : input(bufferSize * 2) {
|
HackRF2Complex(stream<complex_t>* out, int bufferSize) : input(bufferSize * 2) {
|
||||||
_output = out;
|
_output = out;
|
||||||
_bufferSize = bufferSize;
|
_bufferSize = bufferSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init(stream<complex_t>* out, int bufferSize) {
|
||||||
|
input.init(bufferSize * 2);
|
||||||
|
_output = out;
|
||||||
|
_bufferSize = bufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
_workerThread = std::thread(_worker, this);
|
_workerThread = std::thread(_worker, this);
|
||||||
}
|
}
|
||||||
@ -81,12 +101,23 @@ namespace cdsp {
|
|||||||
|
|
||||||
class HackRFSink {
|
class HackRFSink {
|
||||||
public:
|
public:
|
||||||
|
HackRFSink() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
HackRFSink(hackrf_device* dev, int bufferSize, stream<complex_t>* input) : gen(input, bufferSize) {
|
HackRFSink(hackrf_device* dev, int bufferSize, stream<complex_t>* input) : gen(input, bufferSize) {
|
||||||
_input = input;
|
_input = input;
|
||||||
_dev = dev;
|
_dev = dev;
|
||||||
gen.start();
|
gen.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init(hackrf_device* dev, int bufferSize, stream<complex_t>* input) {
|
||||||
|
gen.init(input, bufferSize);
|
||||||
|
_input = input;
|
||||||
|
_dev = dev;
|
||||||
|
gen.start();
|
||||||
|
}
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
streaming = true;
|
streaming = true;
|
||||||
hackrf_start_tx(_dev, _worker, this);
|
hackrf_start_tx(_dev, _worker, this);
|
||||||
@ -116,11 +147,22 @@ namespace cdsp {
|
|||||||
|
|
||||||
class HackRFSource {
|
class HackRFSource {
|
||||||
public:
|
public:
|
||||||
|
HackRFSource() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
HackRFSource(hackrf_device* dev, int bufferSize) : output(bufferSize * 2), gen(&output, bufferSize) {
|
HackRFSource(hackrf_device* dev, int bufferSize) : output(bufferSize * 2), gen(&output, bufferSize) {
|
||||||
_dev = dev;
|
_dev = dev;
|
||||||
gen.start();
|
gen.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init(hackrf_device* dev, int bufferSize) {
|
||||||
|
output.init(bufferSize * 2);
|
||||||
|
gen.init(&output, bufferSize);
|
||||||
|
_dev = dev;
|
||||||
|
gen.start();
|
||||||
|
}
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
streaming = true;
|
streaming = true;
|
||||||
hackrf_start_rx(_dev, _worker, this);
|
hackrf_start_rx(_dev, _worker, this);
|
||||||
|
@ -6,6 +6,10 @@
|
|||||||
namespace cdsp {
|
namespace cdsp {
|
||||||
class Multiplier {
|
class Multiplier {
|
||||||
public:
|
public:
|
||||||
|
Multiplier() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Multiplier(stream<complex_t>* a, stream<complex_t>* b, int bufferSize) : output(bufferSize * 2) {
|
Multiplier(stream<complex_t>* a, stream<complex_t>* b, int bufferSize) : output(bufferSize * 2) {
|
||||||
_a = a;
|
_a = a;
|
||||||
_b = b;
|
_b = b;
|
||||||
|
@ -7,12 +7,22 @@ namespace cdsp {
|
|||||||
template <class T>
|
template <class T>
|
||||||
class stream {
|
class stream {
|
||||||
public:
|
public:
|
||||||
|
stream() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
stream(int size) {
|
stream(int size) {
|
||||||
_buffer = new T[size];
|
_buffer = new T[size];
|
||||||
this->size = size;
|
this->size = size;
|
||||||
writec = 0;
|
writec = 0;
|
||||||
readc = size - 1;
|
readc = size - 1;
|
||||||
//printf("Stream init\n");
|
}
|
||||||
|
|
||||||
|
void init(int size) {
|
||||||
|
_buffer = new T[size];
|
||||||
|
this->size = size;
|
||||||
|
writec = 0;
|
||||||
|
readc = size - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void read(T* data, int len) {
|
void read(T* data, int len) {
|
||||||
|
@ -11,20 +11,22 @@
|
|||||||
#include <cdsp/math.h>
|
#include <cdsp/math.h>
|
||||||
#include <waterfall.h>
|
#include <waterfall.h>
|
||||||
#include <fftw3.h>
|
#include <fftw3.h>
|
||||||
|
#include <signal_path.h>
|
||||||
|
|
||||||
std::thread worker;
|
std::thread worker;
|
||||||
|
|
||||||
std::mutex fft_mtx;
|
std::mutex fft_mtx;
|
||||||
ImGui::WaterFall wtf;
|
ImGui::WaterFall wtf;
|
||||||
|
|
||||||
hackrf_device* dev;
|
hackrf_device* dev;
|
||||||
|
fftwf_complex *fft_in, *fft_out;
|
||||||
|
fftwf_plan p;
|
||||||
|
|
||||||
|
bool dcbias = true;
|
||||||
|
|
||||||
void windowInit() {
|
void windowInit() {
|
||||||
int fftSize = 8192;
|
int fftSize = 8192;
|
||||||
//cdsp::complex_t* iqdata = new cdsp::complex_t[fftSize * 2];
|
wtf.bandWidth = 8000000;
|
||||||
|
wtf.range = 500000;
|
||||||
|
|
||||||
fftwf_complex *fft_in, *fft_out;
|
|
||||||
fftwf_plan p;
|
|
||||||
fft_in = (fftwf_complex*) fftw_malloc(sizeof(fftw_complex) * fftSize);
|
fft_in = (fftwf_complex*) fftw_malloc(sizeof(fftw_complex) * fftSize);
|
||||||
fft_out = (fftwf_complex*) fftw_malloc(sizeof(fftw_complex) * fftSize);
|
fft_out = (fftwf_complex*) fftw_malloc(sizeof(fftw_complex) * fftSize);
|
||||||
p = fftwf_plan_dft_1d(fftSize, fft_in, fft_out, FFTW_FORWARD, FFTW_ESTIMATE);
|
p = fftwf_plan_dft_1d(fftSize, fft_in, fft_out, FFTW_FORWARD, FFTW_ESTIMATE);
|
||||||
@ -60,8 +62,6 @@ void windowInit() {
|
|||||||
dec.start();
|
dec.start();
|
||||||
mul.start();
|
mul.start();
|
||||||
|
|
||||||
float val_a, val_b, val_c;
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
mul.output.read((cdsp::complex_t*)fft_in, fftSize);
|
mul.output.read((cdsp::complex_t*)fft_in, fftSize);
|
||||||
|
|
||||||
@ -75,6 +75,8 @@ void windowInit() {
|
|||||||
data[i] = (data[i - 3] + data[i - 2] + data[i - 1] + data[i]) / 4.0f;
|
data[i] = (data[i - 3] + data[i - 2] + data[i - 1] + data[i]) / 4.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bias.bypass = !dcbias;
|
||||||
|
|
||||||
wtf.pushFFT(data, fftSize);
|
wtf.pushFFT(data, fftSize);
|
||||||
data.clear();
|
data.clear();
|
||||||
}
|
}
|
||||||
@ -90,6 +92,7 @@ int _freq = 98000;
|
|||||||
void drawWindow() {
|
void drawWindow() {
|
||||||
if (freq != _freq) {
|
if (freq != _freq) {
|
||||||
_freq = freq;
|
_freq = freq;
|
||||||
|
wtf.centerFrequency = freq * 1000;
|
||||||
hackrf_set_freq(dev, freq * 1000);
|
hackrf_set_freq(dev, freq * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,6 +151,7 @@ void drawWindow() {
|
|||||||
ImGui::Columns(1, "EndRadioModeColumns", false);
|
ImGui::Columns(1, "EndRadioModeColumns", false);
|
||||||
|
|
||||||
ImGui::InputInt("Frequency (kHz)", &freq);
|
ImGui::InputInt("Frequency (kHz)", &freq);
|
||||||
|
ImGui::Checkbox("DC Bias Removal", &dcbias);
|
||||||
|
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
}
|
}
|
||||||
|
20
src/signal_path.cpp
Normal file
20
src/signal_path.cpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#include <signal_path.h>
|
||||||
|
|
||||||
|
SignalPath::SignalPath(cdsp::stream<cdsp::complex_t>* source, float sampleRate, float fftRate, int fftSize, cdsp::complex_t* fftBuffer, void fftHandler(cdsp::complex_t*)) :
|
||||||
|
dcBiasRemover(source, 64000),
|
||||||
|
fftBlockDec(&dcBiasRemover.output, (sampleRate / fftRate) - fftSize, fftSize),
|
||||||
|
fftSineSource(sampleRate / 2.0f, sampleRate, fftSize),
|
||||||
|
fftMul(&fftBlockDec.output, &fftSineSource.output, fftSize),
|
||||||
|
fftHandler(&fftMul.output, fftBuffer, fftSize, fftHandler) {
|
||||||
|
this->sampleRate = sampleRate;
|
||||||
|
this->fftRate = fftRate;
|
||||||
|
this->fftSize = fftSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalPath::start() {
|
||||||
|
dcBiasRemover.start();
|
||||||
|
fftBlockDec.start();
|
||||||
|
fftSineSource.start();
|
||||||
|
fftMul.start();
|
||||||
|
fftHandler.start();
|
||||||
|
}
|
26
src/signal_path.h
Normal file
26
src/signal_path.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <cdsp/filter.h>
|
||||||
|
#include <cdsp/resampling.h>
|
||||||
|
#include <cdsp/generator.h>
|
||||||
|
#include <cdsp/math.h>
|
||||||
|
|
||||||
|
class SignalPath {
|
||||||
|
public:
|
||||||
|
SignalPath();
|
||||||
|
SignalPath(cdsp::stream<cdsp::complex_t>* source, float sampleRate, float fftRate, int fftSize, cdsp::complex_t* fftBuffer, void fftHandler(cdsp::complex_t*));
|
||||||
|
void start();
|
||||||
|
void setSampleRate(float sampleRate);
|
||||||
|
void setDCBiasCorrection(bool enabled);
|
||||||
|
void setFFTRate(float rate);
|
||||||
|
|
||||||
|
private:
|
||||||
|
cdsp::DCBiasRemover dcBiasRemover;
|
||||||
|
cdsp::BlockDecimator fftBlockDec;
|
||||||
|
cdsp::ComplexSineSource fftSineSource;
|
||||||
|
cdsp::Multiplier fftMul;
|
||||||
|
cdsp::HandlerSink fftHandler;
|
||||||
|
|
||||||
|
float sampleRate;
|
||||||
|
float fftRate;
|
||||||
|
int fftSize;
|
||||||
|
};
|
@ -30,13 +30,16 @@ namespace ImGui {
|
|||||||
glGenTextures(1, &textureId);
|
glGenTextures(1, &textureId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawFFT(ImGuiWindow* window, int width, int height, ImVec2 pos, std::vector<float>& data) {
|
void WaterFall::drawFFT(ImGuiWindow* window, int width, int height, ImVec2 pos) {
|
||||||
float lineHeight = (float)(height - 20 - 30) / 7.0f;
|
float lineHeight = (float)(height - 20 - 30) / 7.0f;
|
||||||
char buf[100];
|
char buf[100];
|
||||||
|
int fftWidth = width - 50;
|
||||||
|
|
||||||
|
// Vertical scale
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
sprintf(buf, "%d", -i * 10);
|
sprintf(buf, "%d", -i * 10);
|
||||||
window->DrawList->AddText(ImVec2(pos.x + 7, pos.y + (i * lineHeight) + 2), IM_COL32( 255, 255, 255, 255 ), buf);
|
ImVec2 txtSz = ImGui::CalcTextSize(buf);
|
||||||
|
window->DrawList->AddText(ImVec2(pos.x + 30 - txtSz.x, pos.y + (i * lineHeight) + 2), IM_COL32( 255, 255, 255, 255 ), buf);
|
||||||
if (i == 7) {
|
if (i == 7) {
|
||||||
window->DrawList->AddLine(ImVec2(pos.x + 40, pos.y + (i * lineHeight) + 10),
|
window->DrawList->AddLine(ImVec2(pos.x + 40, pos.y + (i * lineHeight) + 10),
|
||||||
ImVec2(pos.x + width - 10, pos.y + (i * lineHeight) + 10),
|
ImVec2(pos.x + width - 10, pos.y + (i * lineHeight) + 10),
|
||||||
@ -48,13 +51,36 @@ namespace ImGui {
|
|||||||
IM_COL32( 70, 70, 70, 255 ), 1.0f);
|
IM_COL32( 70, 70, 70, 255 ), 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
int fftWidth = width - 50;
|
// Horizontal scale
|
||||||
|
float start = ceilf((centerFrequency - (bandWidth / 2)) / range) * range;
|
||||||
|
float end = centerFrequency + (bandWidth / 2);
|
||||||
|
float offsetStart = start - (centerFrequency - (bandWidth / 2));
|
||||||
|
float pixelOffset = (offsetStart * fftWidth) / bandWidth;
|
||||||
|
float pixelWidth = (range * fftWidth) / bandWidth;
|
||||||
|
int count = 0;
|
||||||
|
for (; start < end; start += range) {
|
||||||
|
window->DrawList->AddLine(ImVec2(pos.x + pixelOffset + (pixelWidth * count) + 40, pos.y + 10),
|
||||||
|
ImVec2(pos.x + pixelOffset + (pixelWidth * count) + 40, pos.y + (7 * lineHeight) + 10),
|
||||||
|
IM_COL32( 70, 70, 70, 255 ), 1.0f);
|
||||||
|
|
||||||
int dataCount = data.size();
|
window->DrawList->AddLine(ImVec2(pos.x + pixelOffset + (pixelWidth * count) + 40, pos.y + (7 * lineHeight) + 10),
|
||||||
|
ImVec2(pos.x + pixelOffset + (pixelWidth * count) + 40, pos.y + (7 * lineHeight) + 20),
|
||||||
|
IM_COL32( 255, 255, 255, 255 ), 1.0f);
|
||||||
|
|
||||||
|
sprintf(buf, "%.1fM", start / 1000000.0f);
|
||||||
|
|
||||||
|
ImVec2 txtSz = ImGui::CalcTextSize(buf);
|
||||||
|
|
||||||
|
window->DrawList->AddText(ImVec2(pos.x + pixelOffset + (pixelWidth * count) + 40 - (txtSz.x / 2.0f), pos.y + (7 * lineHeight) + 25), IM_COL32( 255, 255, 255, 255 ), buf);
|
||||||
|
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dataCount = fftBuffer[0].size();
|
||||||
float multiplier = (float)dataCount / (float)fftWidth;
|
float multiplier = (float)dataCount / (float)fftWidth;
|
||||||
for (int i = 1; i < fftWidth; i++) {
|
for (int i = 1; i < fftWidth; i++) {
|
||||||
float a = (data[(int)((float)(i - 1) * multiplier)] / 10.0f) * lineHeight;
|
float a = (fftBuffer[0][(int)((float)(i - 1) * multiplier)] / 10.0f) * lineHeight;
|
||||||
float b = (data[(int)((float)i * multiplier)] / 10.0f) * lineHeight;
|
float b = (fftBuffer[0][(int)((float)i * multiplier)] / 10.0f) * lineHeight;
|
||||||
window->DrawList->AddLine(ImVec2(pos.x + i + 39, pos.y - a),
|
window->DrawList->AddLine(ImVec2(pos.x + i + 39, pos.y - a),
|
||||||
ImVec2(pos.x + i + 40, pos.y - b),
|
ImVec2(pos.x + i + 40, pos.y - b),
|
||||||
IM_COL32( 0, 255, 255, 255 ), 1.0f);
|
IM_COL32( 0, 255, 255, 255 ), 1.0f);
|
||||||
@ -69,6 +95,12 @@ namespace ImGui {
|
|||||||
// IM_COL32( 0, 255, 255, 255 ), 1.0f);
|
// IM_COL32( 0, 255, 255, 255 ), 1.0f);
|
||||||
|
|
||||||
window->DrawList->AddLine(ImVec2(pos.x + 40, pos.y + 10), ImVec2(pos.x + 40, pos.y + (7 * lineHeight) + 10), IM_COL32( 255, 255, 255, 255 ), 1.0f);
|
window->DrawList->AddLine(ImVec2(pos.x + 40, pos.y + 10), ImVec2(pos.x + 40, pos.y + (7 * lineHeight) + 10), IM_COL32( 255, 255, 255, 255 ), 1.0f);
|
||||||
|
|
||||||
|
ImVec2 mPos = ImGui::GetMousePos();
|
||||||
|
window->DrawList->AddRectFilled(ImVec2(mPos.x - 20, pos.y + 1), ImVec2(mPos.x + 20, pos.y + (7 * lineHeight) + 10), IM_COL32( 255, 255, 255, 50 ));
|
||||||
|
window->DrawList->AddLine(ImVec2(mPos.x, pos.y + 1), ImVec2(mPos.x, pos.y + (7 * lineHeight) + 10), IM_COL32( 255, 0, 0, 255 ), 1.0f);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t mapColor(float val) {
|
uint32_t mapColor(float val) {
|
||||||
@ -161,7 +193,7 @@ namespace ImGui {
|
|||||||
if (fftBuffer.size() > height - 302) {
|
if (fftBuffer.size() > height - 302) {
|
||||||
fftBuffer.resize(height - 302);
|
fftBuffer.resize(height - 302);
|
||||||
}
|
}
|
||||||
drawFFT(window, width, 300, vMin, fftBuffer[0]);
|
drawFFT(window, width, 300, vMin);
|
||||||
drawWaterfall(window, width - 2, height - 302, ImVec2(vMin.x + 1, vMin.y + 301));
|
drawWaterfall(window, width - 2, height - 302, ImVec2(vMin.x + 1, vMin.y + 301));
|
||||||
buf_mtx.unlock();
|
buf_mtx.unlock();
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,20 @@ namespace ImGui {
|
|||||||
void draw();
|
void draw();
|
||||||
void pushFFT(std::vector<float> data, int n);
|
void pushFFT(std::vector<float> data, int n);
|
||||||
|
|
||||||
|
float centerFrequency;
|
||||||
|
float bandWidth;
|
||||||
|
float range;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void drawWaterfall(ImGuiWindow* window, int width, int height, ImVec2 pos);
|
void drawWaterfall(ImGuiWindow* window, int width, int height, ImVec2 pos);
|
||||||
|
void drawFFT(ImGuiWindow* window, int width, int height, ImVec2 pos);
|
||||||
|
|
||||||
std::vector<std::vector<float>> fftBuffer;
|
std::vector<std::vector<float>> fftBuffer;
|
||||||
bool newSamples;
|
bool newSamples;
|
||||||
std::mutex buf_mtx;
|
std::mutex buf_mtx;
|
||||||
GLuint textureId;
|
GLuint textureId;
|
||||||
uint8_t* pixelBuffer;
|
uint8_t* pixelBuffer;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
Loading…
x
Reference in New Issue
Block a user