lots o shit

This commit is contained in:
AlexandreRouma
2022-06-15 16:08:28 +02:00
parent 79a15ed186
commit 343ec6ca1c
109 changed files with 496 additions and 18305 deletions

View File

@ -1,278 +0,0 @@
#include <signal_path/dsp.h>
#include <core.h>
SignalPath::SignalPath() {
}
void SignalPath::init(uint64_t sampleRate, int fftRate, int fftSize, dsp::stream<dsp::complex_t>* input, dsp::complex_t* fftBuffer, void fftHandler(dsp::complex_t*, int, void*), void* fftHandlerCtx) {
this->sampleRate = sampleRate;
this->sourceSampleRate = sampleRate;
this->fftRate = fftRate;
this->fftSize = fftSize;
inputBlockSize = sampleRate / 200.0f;
halfBandWindow.init(1000000, 200000, 4000000);
inputBuffer.init(input);
corrector.init(&inputBuffer.out, 50.0f / sampleRate);
split.init(&inputBuffer.out);
// Allocate the fft taps
fftTaps = new float[fftSize];
// Calculate the parameters for the reshaper
int fftInterval = sampleRate / fftRate;
fftOutputSampleCount = std::min<int>(fftInterval, fftSize);
int fftSkip = fftInterval - fftOutputSampleCount;
// Generate FFT Windows
generateFFTWindow(fftWindow, fftTaps, fftOutputSampleCount);
reshape.init(&fftStream, fftSize, fftSkip);
split.bindStream(&fftStream);
fftHandlerSink.init(&reshape.out, fftHandler, fftHandlerCtx);
}
void SignalPath::setSampleRate(double sampleRate) {
this->sampleRate = sampleRate;
// Stop the splitter
split.stop();
reshape.stop();
// Stop all VFOs
for (auto const& [name, vfo] : vfos) {
vfo.vfo->stop();
}
updateFFTDSP();
// Update the sample rate for all VFOs and start them up
for (auto const& [name, vfo] : vfos) {
vfo.vfo->setInSampleRate(sampleRate);
vfo.vfo->start();
}
// Update correction rate on the IQ corrector
corrector.setCorrectionRate(50.0f / sampleRate);
// Start the splitter
split.start();
reshape.start();
}
double SignalPath::getSampleRate() {
return sampleRate;
}
void SignalPath::start() {
for (auto& decimator : decimators) {
decimator->start();
}
inputBuffer.start();
if (iqCorrection) { corrector.start(); }
split.start();
reshape.start();
fftHandlerSink.start();
running = true;
}
void SignalPath::stop() {
for (auto& decimator : decimators) {
decimator->stop();
}
inputBuffer.stop();
if (iqCorrection) { corrector.stop(); }
split.stop();
reshape.stop();
fftHandlerSink.stop();
running = false;
}
dsp::VFO* SignalPath::addVFO(std::string name, double outSampleRate, double bandwidth, double offset) {
if (vfos.find(name) != vfos.end()) {
return NULL;
}
VFO_t vfo;
vfo.inputStream = new dsp::stream<dsp::complex_t>;
split.bindStream(vfo.inputStream);
vfo.vfo = new dsp::VFO();
vfo.vfo->init(vfo.inputStream, offset, sampleRate, outSampleRate, bandwidth);
vfo.vfo->start();
vfos[name] = vfo;
return vfo.vfo;
}
void SignalPath::removeVFO(std::string name) {
if (vfos.find(name) == vfos.end()) {
return;
}
VFO_t vfo = vfos[name];
vfo.vfo->stop();
split.unbindStream(vfo.inputStream);
delete vfo.vfo;
delete vfo.inputStream;
vfos.erase(name);
}
void SignalPath::setInput(dsp::stream<dsp::complex_t>* input) {
inputBuffer.setInput(input);
}
void SignalPath::bindIQStream(dsp::stream<dsp::complex_t>* stream) {
split.bindStream(stream);
}
void SignalPath::unbindIQStream(dsp::stream<dsp::complex_t>* stream) {
split.unbindStream(stream);
}
void SignalPath::setFFTSize(int size) {
fftSize = size;
reshape.stop();
updateFFTDSP();
reshape.start();
}
void SignalPath::setFFTRate(double rate) {
fftRate = rate;
reshape.stop();
updateFFTDSP();
reshape.start();
}
void SignalPath::startFFT() {
reshape.start();
fftHandlerSink.start();
}
void SignalPath::stopFFT() {
reshape.stop();
fftHandlerSink.stop();
}
void SignalPath::setBuffering(bool enabled) {
inputBuffer.bypass = !enabled;
}
void SignalPath::setDecimation(int dec) {
decimation = dec;
if (running) { split.stop(); }
// Stop existing decimators
if (!decimators.empty()) {
for (auto& decimator : decimators) {
decimator->stop();
}
for (auto& decimator : decimators) {
delete decimator;
}
}
decimators.clear();
// If no decimation, reconnect
if (!dec) {
if (iqCorrection) {
split.setInput(&corrector.out);
}
else {
split.setInput(&inputBuffer.out);
}
if (running) { split.start(); }
core::setInputSampleRate(sourceSampleRate);
return;
}
// Create new decimators
for (int i = 0; i < dec; i++) {
dsp::HalfDecimator<dsp::complex_t>* decimator;
if (iqCorrection && i == 0) {
decimator = new dsp::HalfDecimator<dsp::complex_t>(&corrector.out, &halfBandWindow);
}
else if (i == 0) {
decimator = new dsp::HalfDecimator<dsp::complex_t>(&inputBuffer.out, &halfBandWindow);
}
else {
decimator = new dsp::HalfDecimator<dsp::complex_t>(&decimators[i - 1]->out, &halfBandWindow);
}
if (running) { decimator->start(); }
decimators.push_back(decimator);
}
split.setInput(&decimators[decimators.size() - 1]->out);
if (running) { split.start(); }
// Update the DSP sample rate
core::setInputSampleRate(sourceSampleRate);
}
void SignalPath::setIQCorrection(bool enabled) {
if (iqCorrection == enabled) { return; }
if (!iqCorrection && enabled) {
if (decimation) {
decimators[0]->setInput(&corrector.out);
}
else {
split.setInput(&corrector.out);
}
if (running) { corrector.start(); }
}
else if (iqCorrection && !enabled) {
if (running) { corrector.stop(); }
if (decimation) {
decimators[0]->setInput(&inputBuffer.out);
}
else {
split.setInput(&inputBuffer.out);
}
}
iqCorrection = enabled;
if (!enabled) {
corrector.offset.re = 0;
corrector.offset.im = 0;
}
}
void SignalPath::setFFTWindow(int win) {
fftWindow = win;
reshape.stop();
updateFFTDSP();
reshape.start();
}
void SignalPath::generateFFTWindow(int win, float* taps, int size) {
if (win == FFT_WINDOW_RECTANGULAR) {
for (int i = 0; i < size; i++) {
taps[i] = (i % 2) ? 1 : -1;
}
}
else if (win == FFT_WINDOW_BLACKMAN) {
for (int i = 0; i < size; i++) {
taps[i] = ((i % 2) ? dsp::window_function::blackman(i, size) : -dsp::window_function::blackman(i, size)) * 2;
}
}
}
void SignalPath::updateFFTDSP() {
// Allocate the fft taps
if (fftTaps != NULL) { delete[] fftTaps; }
fftTaps = new float[fftSize];
// Calculate the parameters for the reshaper
int fftInterval = sampleRate / fftRate;
fftOutputSampleCount = std::min<int>(fftInterval, fftSize);
int fftSkip = fftInterval - fftOutputSampleCount;
// Generate FFT Windows
generateFFTWindow(fftWindow, fftTaps, fftOutputSampleCount);
// Update parameters of the reshaper
reshape.setKeep(fftOutputSampleCount);
reshape.setSkip(fftSkip);
spdlog::info("Updating FFT DSP settings: Keep: {0}, Skip: {1}", fftOutputSampleCount, fftSkip);
}

View File

@ -1,74 +0,0 @@
#pragma once
#include <dsp/routing.h>
#include <dsp/vfo.h>
#include <map>
#include <dsp/sink.h>
#include <dsp/decimation.h>
#include <dsp/correction.h>
enum {
FFT_WINDOW_RECTANGULAR,
FFT_WINDOW_BLACKMAN,
_FFT_WINDOW_COUNT
};
class SignalPath {
public:
SignalPath();
void init(uint64_t sampleRate, int fftRate, int fftSize, dsp::stream<dsp::complex_t>* input, dsp::complex_t* fftBuffer, void fftHandler(dsp::complex_t*, int, void*), void* fftHandlerCtx);
void start();
void stop();
void setSampleRate(double sampleRate);
double getSampleRate();
dsp::VFO* addVFO(std::string name, double outSampleRate, double bandwidth, double offset);
void removeVFO(std::string name);
void setInput(dsp::stream<dsp::complex_t>* input);
void bindIQStream(dsp::stream<dsp::complex_t>* stream);
void unbindIQStream(dsp::stream<dsp::complex_t>* stream);
void setFFTSize(int size);
void setFFTRate(double rate);
void startFFT();
void stopFFT();
void setBuffering(bool enabled);
void setDecimation(int dec);
void setIQCorrection(bool enabled);
void setFFTWindow(int win);
dsp::SampleFrameBuffer<dsp::complex_t> inputBuffer;
double sourceSampleRate = 0;
int decimation = 0;
float* fftTaps = NULL;
private:
void generateFFTWindow(int win, float* taps, int size);
void updateFFTDSP();
struct VFO_t {
dsp::stream<dsp::complex_t>* inputStream;
dsp::VFO* vfo;
};
dsp::Splitter<dsp::complex_t> split;
dsp::IQCorrector corrector;
// FFT
dsp::stream<dsp::complex_t> fftStream;
dsp::Reshaper<dsp::complex_t> reshape;
dsp::HandlerSink<dsp::complex_t> fftHandlerSink;
// VFO
std::map<std::string, VFO_t> vfos;
std::vector<dsp::HalfDecimator<dsp::complex_t>*> decimators;
dsp::filter_window::BlackmanWindow halfBandWindow;
int fftOutputSampleCount = 0;
double sampleRate;
double fftRate;
int fftSize;
int inputBlockSize;
int fftWindow = FFT_WINDOW_RECTANGULAR;
bool bufferingEnabled = false;
bool running = false;
bool iqCorrection = false;
};

View File

@ -1,7 +1,7 @@
#include <signal_path/signal_path.h>
namespace sigpath {
SignalPath signalPath;
IQFrontEnd iqFrontEnd;
VFOManager vfoManager;
SourceManager sourceManager;
SinkManager sinkManager;

View File

@ -1,12 +1,12 @@
#pragma once
#include <signal_path/dsp.h>
#include <signal_path/vfo_manager.h>
#include <signal_path/source.h>
#include <signal_path/sink.h>
#include "iq_frontend.h"
#include "vfo_manager.h"
#include "source.h"
#include "sink.h"
#include <module.h>
namespace sigpath {
SDRPP_EXPORT SignalPath signalPath;
SDRPP_EXPORT IQFrontEnd iqFrontEnd;
SDRPP_EXPORT VFOManager vfoManager;
SDRPP_EXPORT SourceManager sourceManager;
SDRPP_EXPORT SinkManager sinkManager;

View File

@ -24,7 +24,7 @@ void SinkManager::Stream::init(dsp::stream<dsp::stereo_t>* in, EventHandler<floa
_sampleRate = sampleRate;
splitter.init(_in);
splitter.bindStream(&volumeInput);
volumeAjust.init(&volumeInput, 1.0f);
volumeAjust.init(&volumeInput, 1.0f, false);
sinkOut = &volumeAjust.out;
}

View File

@ -3,9 +3,9 @@
#include <string>
#include <dsp/stream.h>
#include <dsp/types.h>
#include <dsp/routing.h>
#include <dsp/processing.h>
#include <dsp/sink.h>
#include "../dsp/routing/splitter.h"
#include "../dsp/audio/volume.h"
#include "../dsp/sink/null_sink.h"
#include <mutex>
#include <utils/event.h>
#include <vector>
@ -52,10 +52,10 @@ public:
private:
dsp::stream<dsp::stereo_t>* _in;
dsp::Splitter<dsp::stereo_t> splitter;
dsp::routing::Splitter<dsp::stereo_t> splitter;
SinkManager::Sink* sink;
dsp::stream<dsp::stereo_t> volumeInput;
dsp::Volume<dsp::stereo_t> volumeAjust;
dsp::audio::Volume volumeAjust;
std::mutex ctrlMtx;
float _sampleRate;
int providerId = 0;
@ -85,7 +85,7 @@ public:
}
private:
dsp::NullSink<dsp::stereo_t> ns;
dsp::sink::Null<dsp::stereo_t> ns;
};
void registerSinkProvider(std::string name, SinkProvider provider);

View File

@ -26,7 +26,7 @@ void SourceManager::unregisterSource(std::string name) {
if (selectedHandler != NULL) {
sources[selectedName]->deselectHandler(sources[selectedName]->ctx);
}
sigpath::signalPath.setInput(&nullSource);
sigpath::iqFrontEnd.setInput(&nullSource);
selectedHandler = NULL;
}
sources.erase(name);
@ -54,7 +54,7 @@ void SourceManager::selectSource(std::string name) {
server::setInput(selectedHandler->stream);
}
else {
sigpath::signalPath.setInput(selectedHandler->stream);
sigpath::iqFrontEnd.setInput(selectedHandler->stream);
}
// Set server input here
}

View File

@ -4,7 +4,7 @@
VFOManager::VFO::VFO(std::string name, int reference, double offset, double bandwidth, double sampleRate, double minBandwidth, double maxBandwidth, bool bandwidthLocked) {
this->name = name;
dspVFO = sigpath::signalPath.addVFO(name, sampleRate, bandwidth, offset);
dspVFO = sigpath::iqFrontEnd.addVFO(name, sampleRate, bandwidth, offset);
wtfVFO = new ImGui::WaterfallVFO;
wtfVFO->setReference(reference);
wtfVFO->setBandwidth(bandwidth);
@ -12,7 +12,7 @@ VFOManager::VFO::VFO(std::string name, int reference, double offset, double band
wtfVFO->minBandwidth = minBandwidth;
wtfVFO->maxBandwidth = maxBandwidth;
wtfVFO->bandwidthLocked = bandwidthLocked;
output = dspVFO->out;
output = &dspVFO->out;
gui::waterfall.vfos[name] = wtfVFO;
}
@ -22,7 +22,7 @@ VFOManager::VFO::~VFO() {
if (gui::waterfall.selectedVFO == name) {
gui::waterfall.selectFirstVFO();
}
sigpath::signalPath.removeVFO(name);
sigpath::iqFrontEnd.removeVFO(name);
delete wtfVFO;
}
@ -46,7 +46,7 @@ void VFOManager::VFO::setBandwidth(double bandwidth, bool updateWaterfall) {
}
void VFOManager::VFO::setSampleRate(double sampleRate, double bandwidth) {
dspVFO->setOutSampleRate(sampleRate, bandwidth);
dspVFO->setOutSamplerate(sampleRate, bandwidth);
wtfVFO->setBandwidth(bandwidth);
}

View File

@ -1,5 +1,5 @@
#pragma once
#include <dsp/vfo.h>
#include "../dsp/channel/rx_vfo.h"
#include <gui/widgets/waterfall.h>
#include <utils/event.h>
@ -30,7 +30,7 @@ public:
friend class VFOManager;
dsp::VFO* dspVFO;
dsp::channel::RxVFO* dspVFO;
ImGui::WaterfallVFO* wtfVFO;
private: