added stuff idk

pull/2/head
Ryzerth 2020-06-10 18:52:07 +02:00
rodzic 8e1c6e9da6
commit 7120e848ef
13 zmienionych plików z 300 dodań i 17 usunięć

Wyświetl plik

@ -30,4 +30,8 @@ target_link_libraries(sdrpp PRIVATE FFTW3::fftw3)
find_package(FFTW3f CONFIG REQUIRED)
target_link_libraries(sdrpp PRIVATE FFTW3::fftw3f)
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)

Wyświetl plik

@ -7,6 +7,10 @@
namespace cdsp {
class FMDemodulator {
public:
FMDemodulator() {
}
FMDemodulator(stream<complex_t>* in, float deviation, long sampleRate, int bufferSize) : output(bufferSize * 2) {
_input = in;
_bufferSize = bufferSize;
@ -14,6 +18,14 @@ namespace cdsp {
_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() {
_workerThread = std::thread(_worker, this);
}

Wyświetl plik

@ -14,11 +14,21 @@ namespace cdsp {
class RawFileSource {
public:
RawFileSource() {
}
RawFileSource(std::string path, int bufferSize) : output(bufferSize * 2) {
_bufferSize = bufferSize;
_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() {
_workerThread = std::thread(_worker, this);
}
@ -50,12 +60,22 @@ namespace cdsp {
class RawFileSink {
public:
RawFileSink() {
}
RawFileSink(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 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() {
_workerThread = std::thread(_worker, this);
}

Wyświetl plik

@ -7,6 +7,10 @@
namespace cdsp {
class FIRFilter {
public:
FIRFilter() {
}
FIRFilter(stream<complex_t>* input, std::vector<float> taps, int bufferSize) : output(bufferSize * 2) {
_in = input;
_bufferSize = bufferSize;
@ -15,6 +19,15 @@ namespace cdsp {
_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() {
_workerThread = std::thread(_worker, this);
}
@ -66,9 +79,21 @@ namespace cdsp {
class DCBiasRemover {
public:
DCBiasRemover() {
}
DCBiasRemover(stream<complex_t>* input, int bufferSize) : output(bufferSize * 2) {
_in = input;
_bufferSize = bufferSize;
bypass = false;
}
void init(stream<complex_t>* input, int bufferSize) {
output.init(bufferSize * 2);
_in = input;
_bufferSize = bufferSize;
bypass = false;
}
void start() {
@ -76,6 +101,7 @@ namespace cdsp {
}
stream<complex_t> output;
bool bypass;
private:
static void _worker(DCBiasRemover* _this) {
@ -84,6 +110,10 @@ namespace cdsp {
float qbias = 0.0f;
while (true) {
_this->_in->read(buf, _this->_bufferSize);
if (_this->bypass) {
_this->output.write(buf, _this->_bufferSize);
continue;
}
for (int i = 0; i < _this->_bufferSize; i++) {
ibias += buf[i].i;
qbias += buf[i].q;
@ -102,4 +132,45 @@ namespace cdsp {
int _bufferSize;
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*);
};
};

Wyświetl plik

@ -6,12 +6,23 @@
namespace cdsp {
class SineSource {
public:
SineSource() {
}
SineSource(float frequency, long sampleRate, int bufferSize) : output(bufferSize * 2) {
_bufferSize = bufferSize;
_phasorSpeed = (2 * 3.1415926535) / (sampleRate / frequency);
_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() {
_workerThread = std::thread(_worker, this);
}
@ -39,10 +50,19 @@ namespace cdsp {
class RandomSource {
public:
RandomSource() {
}
RandomSource(float frequency, long sampleRate, int bufferSize) : output(bufferSize * 2) {
_bufferSize = bufferSize;
}
void init(float frequency, long sampleRate, int bufferSize) {
output.init(bufferSize * 2);
_bufferSize = bufferSize;
}
void start() {
_workerThread = std::thread(_worker, this);
}
@ -66,12 +86,23 @@ namespace cdsp {
class ComplexSineSource {
public:
ComplexSineSource() {
}
ComplexSineSource(float frequency, long sampleRate, int bufferSize) : output(bufferSize * 2) {
_bufferSize = bufferSize;
_phasorSpeed = (2 * 3.1415926535) / (sampleRate / frequency);
_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() {
_workerThread = std::thread(_worker, this);
}

Wyświetl plik

@ -16,11 +16,21 @@ namespace cdsp {
class Complex2HackRF {
public:
Complex2HackRF() {
}
Complex2HackRF(stream<complex_t>* in, int bufferSize) : output(bufferSize * 2) {
_input = in;
_bufferSize = bufferSize;
}
void init(stream<complex_t>* in, int bufferSize) {
output.init(bufferSize * 2);
_input = in;
_bufferSize = bufferSize;
}
stream<hackrf_sample_t> output;
void start() {
@ -48,11 +58,21 @@ namespace cdsp {
class HackRF2Complex {
public:
HackRF2Complex() {
}
HackRF2Complex(stream<complex_t>* out, int bufferSize) : input(bufferSize * 2) {
_output = out;
_bufferSize = bufferSize;
}
void init(stream<complex_t>* out, int bufferSize) {
input.init(bufferSize * 2);
_output = out;
_bufferSize = bufferSize;
}
void start() {
_workerThread = std::thread(_worker, this);
}
@ -81,12 +101,23 @@ namespace cdsp {
class HackRFSink {
public:
HackRFSink() {
}
HackRFSink(hackrf_device* dev, int bufferSize, stream<complex_t>* input) : gen(input, bufferSize) {
_input = input;
_dev = dev;
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() {
streaming = true;
hackrf_start_tx(_dev, _worker, this);
@ -116,11 +147,22 @@ namespace cdsp {
class HackRFSource {
public:
HackRFSource() {
}
HackRFSource(hackrf_device* dev, int bufferSize) : output(bufferSize * 2), gen(&output, bufferSize) {
_dev = dev;
gen.start();
}
void init(hackrf_device* dev, int bufferSize) {
output.init(bufferSize * 2);
gen.init(&output, bufferSize);
_dev = dev;
gen.start();
}
void start() {
streaming = true;
hackrf_start_rx(_dev, _worker, this);

Wyświetl plik

@ -6,6 +6,10 @@
namespace cdsp {
class Multiplier {
public:
Multiplier() {
}
Multiplier(stream<complex_t>* a, stream<complex_t>* b, int bufferSize) : output(bufferSize * 2) {
_a = a;
_b = b;

Wyświetl plik

@ -7,12 +7,22 @@ namespace cdsp {
template <class T>
class stream {
public:
stream() {
}
stream(int size) {
_buffer = new T[size];
this->size = size;
writec = 0;
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) {

Wyświetl plik

@ -11,20 +11,22 @@
#include <cdsp/math.h>
#include <waterfall.h>
#include <fftw3.h>
#include <signal_path.h>
std::thread worker;
std::mutex fft_mtx;
ImGui::WaterFall wtf;
hackrf_device* dev;
fftwf_complex *fft_in, *fft_out;
fftwf_plan p;
bool dcbias = true;
void windowInit() {
int fftSize = 8192;
//cdsp::complex_t* iqdata = new cdsp::complex_t[fftSize * 2];
fftwf_complex *fft_in, *fft_out;
fftwf_plan p;
wtf.bandWidth = 8000000;
wtf.range = 500000;
fft_in = (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);
@ -60,8 +62,6 @@ void windowInit() {
dec.start();
mul.start();
float val_a, val_b, val_c;
while (true) {
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;
}
bias.bypass = !dcbias;
wtf.pushFFT(data, fftSize);
data.clear();
}
@ -90,6 +92,7 @@ int _freq = 98000;
void drawWindow() {
if (freq != _freq) {
_freq = freq;
wtf.centerFrequency = freq * 1000;
hackrf_set_freq(dev, freq * 1000);
}
@ -148,6 +151,7 @@ void drawWindow() {
ImGui::Columns(1, "EndRadioModeColumns", false);
ImGui::InputInt("Frequency (kHz)", &freq);
ImGui::Checkbox("DC Bias Removal", &dcbias);
ImGui::EndGroup();
}

Wyświetl plik

@ -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 100644
Wyświetl plik

@ -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;
};

Wyświetl plik

@ -30,13 +30,16 @@ namespace ImGui {
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;
char buf[100];
int fftWidth = width - 50;
// Vertical scale
for (int i = 0; i < 8; i++) {
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) {
window->DrawList->AddLine(ImVec2(pos.x + 40, 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);
}
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;
for (int i = 1; i < fftWidth; i++) {
float a = (data[(int)((float)(i - 1) * multiplier)] / 10.0f) * lineHeight;
float b = (data[(int)((float)i * multiplier)] / 10.0f) * lineHeight;
float a = (fftBuffer[0][(int)((float)(i - 1) * 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),
ImVec2(pos.x + i + 40, pos.y - b),
IM_COL32( 0, 255, 255, 255 ), 1.0f);
@ -69,6 +95,12 @@ namespace ImGui {
// 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);
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) {
@ -161,7 +193,7 @@ namespace ImGui {
if (fftBuffer.size() > 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));
buf_mtx.unlock();
}

Wyświetl plik

@ -13,13 +13,20 @@ namespace ImGui {
void draw();
void pushFFT(std::vector<float> data, int n);
float centerFrequency;
float bandWidth;
float range;
private:
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;
bool newSamples;
std::mutex buf_mtx;
GLuint textureId;
uint8_t* pixelBuffer;
};
};