New stuff ++

This commit is contained in:
Ryzerth
2020-08-21 15:34:50 +02:00
parent 709627a738
commit aa2caa67ad
16 changed files with 407 additions and 252 deletions

View File

@ -3,13 +3,18 @@
#include <path.h>
#include <watcher.h>
#define CONCAT(a, b) ((std::string(a) + b).c_str())
#define CONCAT(a, b) ((std::string(a) + b).c_str())
#define DEEMP_LIST "50µS\00075µS\000none\000"
mod::API_t* API;
struct RadioContext_t {
std::string name;
int demod = 1;
int deemp = 0;
int bandWidth;
int bandWidthMin;
int bandWidthMax;
SigPath sigPath;
};
@ -17,6 +22,9 @@ MOD_EXPORT void* _INIT_(mod::API_t* _API, ImGuiContext* imctx, std::string _name
API = _API;
RadioContext_t* ctx = new RadioContext_t;
ctx->name = _name;
ctx->bandWidth = 200000;
ctx->bandWidthMin = 100000;
ctx->bandWidthMax = 200000;
ctx->sigPath.init(_name, 200000, 1000, API->registerVFO(_name, mod::API_t::REF_CENTER, 0, 200000, 200000, 1000));
ctx->sigPath.start();
ImGui::SetCurrentContext(imctx);
@ -28,41 +36,63 @@ MOD_EXPORT void _NEW_FRAME_(RadioContext_t* ctx) {
}
MOD_EXPORT void _DRAW_MENU_(RadioContext_t* ctx) {
float menuColumnWidth = ImGui::GetContentRegionAvailWidth();
ImGui::BeginGroup();
// TODO: Change VFO ref in signal path
ImGui::Columns(4, CONCAT("RadioModeColumns##_", ctx->name), false);
if (ImGui::RadioButton(CONCAT("NFM##_", ctx->name), ctx->demod == 0) && ctx->demod != 0) {
ctx->sigPath.setDemodulator(SigPath::DEMOD_NFM);
ctx->demod = 0;
ctx->demod = 0;
ctx->bandWidth = 16000;
ctx->bandWidthMin = 8000;
ctx->bandWidthMax = 16000;
ctx->sigPath.setDemodulator(SigPath::DEMOD_NFM, ctx->bandWidth);
API->setVFOReference(ctx->name, mod::API_t::REF_CENTER);
}
if (ImGui::RadioButton(CONCAT("WFM##_", ctx->name), ctx->demod == 1) && ctx->demod != 1) {
ctx->sigPath.setDemodulator(SigPath::DEMOD_FM);
ctx->demod = 1;
if (ImGui::RadioButton(CONCAT("WFM##_", ctx->name), ctx->demod == 1) && ctx->demod != 1) {
ctx->demod = 1;
ctx->bandWidth = 200000;
ctx->bandWidthMin = 100000;
ctx->bandWidthMax = 200000;
ctx->sigPath.setDemodulator(SigPath::DEMOD_FM, ctx->bandWidth);
API->setVFOReference(ctx->name, mod::API_t::REF_CENTER);
}
ImGui::NextColumn();
if (ImGui::RadioButton(CONCAT("AM##_", ctx->name), ctx->demod == 2) && ctx->demod != 2) {
ctx->sigPath.setDemodulator(SigPath::DEMOD_AM);
ctx->demod = 2;
if (ImGui::RadioButton(CONCAT("AM##_", ctx->name), ctx->demod == 2) && ctx->demod != 2) {
ctx->demod = 2;
ctx->bandWidth = 12500;
ctx->bandWidthMin = 6250;
ctx->bandWidthMax = 12500;
ctx->sigPath.setDemodulator(SigPath::DEMOD_AM, ctx->bandWidth);
API->setVFOReference(ctx->name, mod::API_t::REF_CENTER);
}
if (ImGui::RadioButton(CONCAT("DSB##_", ctx->name), ctx->demod == 3) && ctx->demod != 3) {
ctx->sigPath.setDemodulator(SigPath::DEMOD_DSB);
ctx->demod = 3;
if (ImGui::RadioButton(CONCAT("DSB##_", ctx->name), ctx->demod == 3) && ctx->demod != 3) {
ctx->demod = 3;
ctx->bandWidth = 6000;
ctx->bandWidthMin = 3000;
ctx->bandWidthMax = 6000;
ctx->sigPath.setDemodulator(SigPath::DEMOD_DSB, ctx->bandWidth);
API->setVFOReference(ctx->name, mod::API_t::REF_CENTER);
}
ImGui::NextColumn();
if (ImGui::RadioButton(CONCAT("USB##_", ctx->name), ctx->demod == 4) && ctx->demod != 4) {
ctx->sigPath.setDemodulator(SigPath::DEMOD_USB);
ctx->demod = 4;
if (ImGui::RadioButton(CONCAT("USB##_", ctx->name), ctx->demod == 4) && ctx->demod != 4) {
ctx->demod = 4;
ctx->bandWidth = 3000;
ctx->bandWidthMin = 1500;
ctx->bandWidthMax = 3000;
ctx->sigPath.setDemodulator(SigPath::DEMOD_USB, ctx->bandWidth);
API->setVFOReference(ctx->name, mod::API_t::REF_LOWER);
}
if (ImGui::RadioButton(CONCAT("CW##_", ctx->name), ctx->demod == 5) && ctx->demod != 5) { ctx->demod = 5; };
ImGui::NextColumn();
if (ImGui::RadioButton(CONCAT("LSB##_", ctx->name), ctx->demod == 6) && ctx->demod != 6) {
ctx->sigPath.setDemodulator(SigPath::DEMOD_LSB);
ctx->demod = 6;
ctx->bandWidth = 3000;
ctx->bandWidthMin = 1500;
ctx->bandWidthMax = 3000;
ctx->sigPath.setDemodulator(SigPath::DEMOD_LSB, ctx->bandWidth);
API->setVFOReference(ctx->name, mod::API_t::REF_UPPER);
}
if (ImGui::RadioButton(CONCAT("RAW##_", ctx->name), ctx->demod == 7) && ctx->demod != 7) { ctx->demod = 7; };
@ -70,7 +100,22 @@ MOD_EXPORT void _DRAW_MENU_(RadioContext_t* ctx) {
ImGui::EndGroup();
ImGui::Checkbox(CONCAT("Deemphasis##_", ctx->name), &ctx->sigPath.deemp.bypass);
ImGui::Text("WFM Deemphasis");
ImGui::SameLine();
ImGui::PushItemWidth(menuColumnWidth - ImGui::GetCursorPosX());
if (ImGui::Combo(CONCAT("##_deemp_select_", ctx->name), &ctx->deemp, DEEMP_LIST)) {
ctx->sigPath.setDeemphasis(ctx->deemp);
}
ImGui::PopItemWidth();
ImGui::Text("Bandwidth");
ImGui::SameLine();
ImGui::PushItemWidth(menuColumnWidth - ImGui::GetCursorPosX());
if (ImGui::InputInt(CONCAT("##_bw_select_", ctx->name), &ctx->bandWidth, 100, 1000)) {
ctx->bandWidth = std::clamp<int>(ctx->bandWidth, ctx->bandWidthMin, ctx->bandWidthMax);
ctx->sigPath.setBandwidth(ctx->bandWidth);
}
ImGui::PopItemWidth();
}
MOD_EXPORT void _HANDLE_EVENT_(RadioContext_t* ctx, int eventId) {

View File

@ -10,7 +10,6 @@ int SigPath::sampleRateChangeHandler(void* ctx, float sampleRate) {
_this->audioResamp.stop();
_this->deemp.stop();
float bw = std::min<float>(_this->bandwidth, sampleRate / 2.0f);
spdlog::warn("New bandwidth: {0}", bw);
_this->audioResamp.setOutputSampleRate(sampleRate, bw, bw);
_this->deemp.setBlockSize(_this->audioResamp.getOutputBlockSize());
_this->deemp.setSamplerate(sampleRate);
@ -25,6 +24,7 @@ void SigPath::init(std::string vfoName, uint64_t sampleRate, int blockSize, dsp:
this->vfoName = vfoName;
_demod = DEMOD_FM;
_deemp = DEEMP_50US;
bandwidth = 200000;
// TODO: Set default VFO options
@ -38,17 +38,17 @@ void SigPath::init(std::string vfoName, uint64_t sampleRate, int blockSize, dsp:
outputSampleRate = API->registerMonoStream(&deemp.output, vfoName, vfoName, sampleRateChangeHandler, this);
API->setBlockSize(vfoName, audioResamp.getOutputBlockSize());
setDemodulator(_demod);
setDemodulator(_demod, bandwidth);
}
void SigPath::setSampleRate(float sampleRate) {
this->sampleRate = sampleRate;
// Reset the demodulator and audio systems
setDemodulator(_demod);
setDemodulator(_demod, bandwidth);
}
void SigPath::setDemodulator(int demId) {
void SigPath::setDemodulator(int demId, float bandWidth) {
if (demId < 0 || demId >= _DEMOD_COUNT) {
return;
}
@ -56,6 +56,8 @@ void SigPath::setDemodulator(int demId) {
audioResamp.stop();
deemp.stop();
bandwidth = bandWidth;
// Stop current demodulator
if (_demod == DEMOD_FM) {
demod.stop();
@ -72,76 +74,80 @@ void SigPath::setDemodulator(int demId) {
else if (_demod == DEMOD_LSB) {
ssbDemod.stop();
}
else if (_demod == DEMOD_DSB) {
ssbDemod.stop();
}
else {
spdlog::error("UNIMPLEMENTED DEMODULATOR IN SigPath::setDemodulator (stop)");
}
_demod = demId;
// Set input of the audio resampler
// TODO: Set bandwidth from argument
if (demId == DEMOD_FM) {
API->setVFOSampleRate(vfoName, 200000, 200000);
bandwidth = 15000;
API->setVFOSampleRate(vfoName, 200000, bandwidth);
demod.setBlockSize(API->getVFOOutputBlockSize(vfoName));
demod.setSampleRate(200000);
demod.setDeviation(100000);
demod.setDeviation(bandwidth / 2.0f);
audioResamp.setInput(&demod.output);
float audioBw = std::min<float>(bandwidth, outputSampleRate / 2.0f);
audioBw = std::min<float>(bandwidth, outputSampleRate / 2.0f);
audioResamp.setInputSampleRate(200000, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw);
deemp.bypass = false;
deemp.bypass = (_deemp == DEEMP_NONE);
demod.start();
}
if (demId == DEMOD_NFM) {
API->setVFOSampleRate(vfoName, 16000, 16000);
bandwidth = 8000;
API->setVFOSampleRate(vfoName, 16000, bandwidth);
demod.setBlockSize(API->getVFOOutputBlockSize(vfoName));
demod.setSampleRate(16000);
demod.setDeviation(8000);
demod.setDeviation(bandwidth / 2.0f);
audioResamp.setInput(&demod.output);
float audioBw = std::min<float>(bandwidth, outputSampleRate / 2.0f);
audioBw = std::min<float>(bandwidth, outputSampleRate / 2.0f);
audioResamp.setInputSampleRate(16000, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw);
deemp.bypass = true;
demod.start();
}
else if (demId == DEMOD_AM) {
API->setVFOSampleRate(vfoName, 12500, 12500);
bandwidth = 6250;
API->setVFOSampleRate(vfoName, 12500, bandwidth);
amDemod.setBlockSize(API->getVFOOutputBlockSize(vfoName));
audioResamp.setInput(&amDemod.output);
float audioBw = std::min<float>(bandwidth, outputSampleRate / 2.0f);
audioBw = std::min<float>(bandwidth, outputSampleRate / 2.0f);
audioResamp.setInputSampleRate(12500, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw);
deemp.bypass = true;
amDemod.start();
}
else if (demId == DEMOD_USB) {
API->setVFOSampleRate(vfoName, 6000, 3000);
bandwidth = 3000;
API->setVFOSampleRate(vfoName, 6000, bandwidth);
ssbDemod.setBlockSize(API->getVFOOutputBlockSize(vfoName));
ssbDemod.setMode(dsp::SSBDemod::MODE_USB);
audioResamp.setInput(&ssbDemod.output);
float audioBw = std::min<float>(bandwidth, outputSampleRate / 2.0f);
audioBw = std::min<float>(bandwidth, outputSampleRate / 2.0f);
audioResamp.setInputSampleRate(6000, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw);
deemp.bypass = true;
ssbDemod.start();
}
else if (demId == DEMOD_LSB) {
API->setVFOSampleRate(vfoName, 6000, 3000);
bandwidth = 3000;
API->setVFOSampleRate(vfoName, 6000, bandwidth);
ssbDemod.setBlockSize(API->getVFOOutputBlockSize(vfoName));
ssbDemod.setMode(dsp::SSBDemod::MODE_LSB);
audioResamp.setInput(&ssbDemod.output);
float audioBw = std::min<float>(bandwidth, outputSampleRate / 2.0f);
audioBw = std::min<float>(bandwidth, outputSampleRate / 2.0f);
audioResamp.setInputSampleRate(6000, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw);
deemp.bypass = true;
ssbDemod.start();
}
else if (demId == DEMOD_DSB) {
API->setVFOSampleRate(vfoName, 6000, 6000);
bandwidth = 3000;
API->setVFOSampleRate(vfoName, 6000, bandwidth);
ssbDemod.setBlockSize(API->getVFOOutputBlockSize(vfoName));
ssbDemod.setMode(dsp::SSBDemod::MODE_DSB);
audioResamp.setInput(&ssbDemod.output);
float audioBw = std::min<float>(bandwidth, outputSampleRate / 2.0f);
audioBw = std::min<float>(bandwidth, outputSampleRate / 2.0f);
audioResamp.setInputSampleRate(6000, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw);
deemp.bypass = true;
ssbDemod.start();
}
else {
spdlog::error("UNIMPLEMENTED DEMODULATOR IN SigPath::setDemodulator (start)");
}
deemp.setBlockSize(audioResamp.getOutputBlockSize());
@ -150,7 +156,67 @@ void SigPath::setDemodulator(int demId) {
}
void SigPath::updateBlockSize() {
setDemodulator(_demod);
setDemodulator(_demod, bandwidth);
}
void SigPath::setDeemphasis(int deemph) {
_deemp = deemph;
deemp.stop();
if (_deemp == DEEMP_NONE) {
deemp.bypass = true;
}
else if (_deemp == DEEMP_50US) {
deemp.bypass = false;
deemp.setTau(50e-6);
}
else if (_deemp == DEEMP_75US) {
deemp.bypass = false;
deemp.setTau(75e-6);
}
deemp.start();
}
void SigPath::setBandwidth(float bandWidth) {
bandwidth = bandWidth;
API->setVFOBandwidth(vfoName, bandwidth);
if (_demod == DEMOD_FM) {
demod.stop();
demod.setDeviation(bandwidth / 2.0f);
demod.start();
}
else if (_demod == DEMOD_NFM) {
demod.stop();
demod.setDeviation(bandwidth / 2.0f);
demod.start();
}
else if (_demod == DEMOD_AM) {
// Notbing to change
}
else if (_demod == DEMOD_USB) {
ssbDemod.stop();
ssbDemod.setBandwidth(bandwidth);
ssbDemod.start();
}
else if (_demod == DEMOD_LSB) {
ssbDemod.stop();
ssbDemod.setBandwidth(bandwidth);
ssbDemod.start();
}
else if (_demod == DEMOD_DSB) {
ssbDemod.stop();
ssbDemod.setBandwidth(bandwidth);
ssbDemod.start();
}
else {
spdlog::error("UNIMPLEMENTED DEMODULATOR IN SigPath::setBandwidth");
}
float _audioBw = std::min<float>(bandwidth, outputSampleRate / 2.0f);
if (audioBw != _audioBw) {
audioBw = _audioBw;
audioResamp.stop();
audioResamp.setInputSampleRate(6000, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw);
audioResamp.start();
}
}
void SigPath::start() {

View File

@ -17,12 +17,11 @@ public:
void init(std::string vfoName, uint64_t sampleRate, int blockSize, dsp::stream<dsp::complex_t>* input);
void start();
void setSampleRate(float sampleRate);
void setVFOFrequency(uint64_t frequency);
void updateBlockSize();
void setDemodulator(int demod);
void setDemodulator(int demod, float bandWidth);
void setDeemphasis(int deemph);
void setBandwidth(float bandWidth);
enum {
DEMOD_FM,
@ -34,6 +33,14 @@ public:
_DEMOD_COUNT
};
enum {
DEEMP_50US,
DEEMP_75US,
DEEMP_NONE,
_DEEMP_COUNT
};
dsp::FMDeemphasis deemp;
private:
@ -56,4 +63,6 @@ private:
float outputSampleRate;
int blockSize;
int _demod;
int _deemp;
float audioBw;
};

View File

@ -106,7 +106,7 @@ MOD_EXPORT void _DRAW_MENU_(RecorderContext_t* ctx) {
ImGui::PushItemWidth(menuColumnWidth);
if (!ctx->recording) {
if (ImGui::Combo(CONCAT("##_strea_select_", ctx->name), &ctx->selectedStreamId, nameList.c_str())) {
ctx->selectedStreamName = nameList[ctx->selectedStreamId];
ctx->selectedStreamName = streamNames[ctx->selectedStreamId];
}
}
else {