-
-
Notifications
You must be signed in to change notification settings - Fork 604
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ea3675d
commit 4799d0e
Showing
8 changed files
with
2,366 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
cmake_minimum_required(VERSION 3.13) | ||
project(vor_receiver) | ||
|
||
file(GLOB_RECURSE SRC "src/*.cpp") | ||
|
||
include(${SDRPP_MODULE_CMAKE}) | ||
|
||
target_include_directories(vor_receiver PRIVATE "src/") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
#include <imgui.h> | ||
#include <config.h> | ||
#include <core.h> | ||
#include <gui/style.h> | ||
#include <gui/gui.h> | ||
#include <signal_path/signal_path.h> | ||
#include <module.h> | ||
#include <filesystem> | ||
#include <dsp/buffer/reshaper.h> | ||
#include <dsp/sink/handler_sink.h> | ||
#include <gui/widgets/constellation_diagram.h> | ||
#include "vor_decoder.h" | ||
#include <fstream> | ||
|
||
#define CONCAT(a, b) ((std::string(a) + b).c_str()) | ||
|
||
SDRPP_MOD_INFO{ | ||
/* Name: */ "vor_receiver", | ||
/* Description: */ "VOR Receiver for SDR++", | ||
/* Author: */ "Ryzerth", | ||
/* Version: */ 0, 1, 0, | ||
/* Max instances */ -1 | ||
}; | ||
|
||
ConfigManager config; | ||
|
||
#define INPUT_SAMPLE_RATE VOR_IN_SR | ||
|
||
class VORReceiverModule : public ModuleManager::Instance { | ||
public: | ||
VORReceiverModule(std::string name) { | ||
this->name = name; | ||
|
||
// Load config | ||
config.acquire(); | ||
// TODO: Load config | ||
config.release(); | ||
|
||
vfo = sigpath::vfoManager.createVFO(name, ImGui::WaterfallVFO::REF_CENTER, 0, INPUT_SAMPLE_RATE, INPUT_SAMPLE_RATE, INPUT_SAMPLE_RATE, INPUT_SAMPLE_RATE, true); | ||
decoder = new vor::Decoder(vfo->output, 1); | ||
decoder->onBearing.bind(&VORReceiverModule::onBearing, this); | ||
|
||
decoder->start(); | ||
|
||
gui::menu.registerEntry(name, menuHandler, this, this); | ||
} | ||
|
||
~VORReceiverModule() { | ||
decoder->stop(); | ||
sigpath::vfoManager.deleteVFO(vfo); | ||
gui::menu.removeEntry(name); | ||
delete decoder; | ||
} | ||
|
||
void postInit() {} | ||
|
||
void enable() { | ||
double bw = gui::waterfall.getBandwidth(); | ||
vfo = sigpath::vfoManager.createVFO(name, ImGui::WaterfallVFO::REF_CENTER, 0, INPUT_SAMPLE_RATE, INPUT_SAMPLE_RATE, INPUT_SAMPLE_RATE, INPUT_SAMPLE_RATE, true); | ||
|
||
decoder->setInput(vfo->output); | ||
|
||
decoder->start(); | ||
|
||
enabled = true; | ||
} | ||
|
||
void disable() { | ||
decoder->stop(); | ||
|
||
sigpath::vfoManager.deleteVFO(vfo); | ||
enabled = false; | ||
} | ||
|
||
bool isEnabled() { | ||
return enabled; | ||
} | ||
|
||
private: | ||
static void menuHandler(void* ctx) { | ||
VORReceiverModule* _this = (VORReceiverModule*)ctx; | ||
|
||
float menuWidth = ImGui::GetContentRegionAvail().x; | ||
|
||
if (!_this->enabled) { style::beginDisabled(); } | ||
|
||
ImGui::Text("Bearing: %f°", _this->bearing); | ||
ImGui::Text("Quality: %0.1f%%", _this->quality); | ||
|
||
if (!_this->enabled) { style::endDisabled(); } | ||
} | ||
|
||
void onBearing(float nbearing, float nquality) { | ||
bearing = (180.0f * nbearing / FL_M_PI); | ||
quality = nquality * 100.0f; | ||
} | ||
|
||
std::string name; | ||
bool enabled = true; | ||
|
||
// DSP Chain | ||
VFOManager::VFO* vfo; | ||
vor::Decoder* decoder; | ||
|
||
float bearing = 0.0f, quality = 0.0f; | ||
}; | ||
|
||
MOD_EXPORT void _INIT_() { | ||
// Create default recording directory | ||
std::string root = (std::string)core::args["root"]; | ||
json def = json({}); | ||
config.setPath(root + "/vor_receiver_config.json"); | ||
config.load(def); | ||
config.enableAutoSave(); | ||
} | ||
|
||
MOD_EXPORT ModuleManager::Instance* _CREATE_INSTANCE_(std::string name) { | ||
return new VORReceiverModule(name); | ||
} | ||
|
||
MOD_EXPORT void _DELETE_INSTANCE_(void* instance) { | ||
delete (VORReceiverModule*)instance; | ||
} | ||
|
||
MOD_EXPORT void _END_() { | ||
config.disableAutoSave(); | ||
config.save(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#include "vor_decoder.h" | ||
|
||
#define STDDEV_NORM_FACTOR 1.813799364234218f // 2.0f * FL_M_PI / sqrt(12) | ||
|
||
namespace vor { | ||
Decoder::Decoder(dsp::stream<dsp::complex_t>* in, double integrationTime) { | ||
rx.init(in); | ||
reshape.init(&rx.out, round(1000.0 * integrationTime), 0); | ||
symSink.init(&reshape.out, dataHandler, this); | ||
} | ||
|
||
Decoder::~Decoder() { | ||
// TODO | ||
} | ||
|
||
void Decoder::setInput(dsp::stream<dsp::complex_t>* in) { | ||
rx.setInput(in); | ||
} | ||
|
||
void Decoder::start() { | ||
rx.start(); | ||
reshape.start(); | ||
symSink.start(); | ||
} | ||
|
||
void Decoder::stop() { | ||
rx.stop(); | ||
reshape.stop(); | ||
symSink.stop(); | ||
} | ||
|
||
void Decoder::dataHandler(float* data, int count, void* ctx) { | ||
// Get the instance from context | ||
Decoder* _this = (Decoder*)ctx; | ||
|
||
// Compute the mean and standard deviation of the | ||
float mean, stddev; | ||
volk_32f_stddev_and_mean_32f_x2(&stddev, &mean, data, count); | ||
|
||
// Compute the signal quality | ||
float quality = std::max<float>(1.0f - (stddev / STDDEV_NORM_FACTOR), 0.0f); | ||
|
||
// Convert the phase difference to a compass heading | ||
mean = -mean; | ||
if (mean < 0) { mean = 2.0f*FL_M_PI + mean; } | ||
|
||
// Call the handler | ||
_this->onBearing(mean, quality); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#include "vor_receiver.h" | ||
#include <dsp/buffer/reshaper.h> | ||
#include <dsp/sink/handler_sink.h> | ||
#include <utils/new_event.h> | ||
|
||
namespace vor { | ||
// Note: hard coded to 22KHz samplerate | ||
class Decoder { | ||
public: | ||
/** | ||
* Create an instance of a VOR decoder. | ||
* @param in Input IQ stream at 22 KHz sampling rate. | ||
* @param integrationTime Integration time of the bearing data in seconds. | ||
*/ | ||
Decoder(dsp::stream<dsp::complex_t>* in, double integrationTime); | ||
|
||
// Destructor | ||
~Decoder(); | ||
|
||
/** | ||
* Set the input stream. | ||
* @param in Input IQ stream at 22 KHz sampling rate. | ||
*/ | ||
void setInput(dsp::stream<dsp::complex_t>* in); | ||
|
||
/** | ||
* Start the decoder. | ||
*/ | ||
void start(); | ||
|
||
/** | ||
* Stop the decoder. | ||
*/ | ||
void stop(); | ||
|
||
/** | ||
* handler(bearing, signalQuality); | ||
*/ | ||
NewEvent<float, float> onBearing; | ||
|
||
private: | ||
static void dataHandler(float* data, int count, void* ctx); | ||
|
||
// DSP | ||
Receiver rx; | ||
dsp::buffer::Reshaper<float> reshape; | ||
dsp::sink::Handler<float> symSink; | ||
}; | ||
} |
Oops, something went wrong.