mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-01-11 18:57:11 +01:00
More work
This commit is contained in:
parent
ccc57cddc7
commit
1dddbadd04
10
.github/workflows/build_all.yml
vendored
10
.github/workflows/build_all.yml
vendored
@ -95,18 +95,18 @@ jobs:
|
|||||||
- name: Install SDRplay API
|
- name: Install SDRplay API
|
||||||
run: wget https://www.sdrplay.com/software/SDRplay_RSP_API-MacOSX-3.07.3.pkg && sudo installer -pkg SDRplay_RSP_API-MacOSX-3.07.3.pkg -target /
|
run: wget https://www.sdrplay.com/software/SDRplay_RSP_API-MacOSX-3.07.3.pkg && sudo installer -pkg SDRplay_RSP_API-MacOSX-3.07.3.pkg -target /
|
||||||
|
|
||||||
- name: Install libiio
|
# - name: Install libiio
|
||||||
run: git clone https://github.com/analogdevicesinc/libiio && cd libiio && mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../
|
# run: git clone https://github.com/analogdevicesinc/libiio && cd libiio && mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../
|
||||||
|
|
||||||
- name: Install libad9361
|
# - name: Install libad9361
|
||||||
run: git clone https://github.com/analogdevicesinc/libad9361-iio && cd libad9361-iio && mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../
|
# run: git clone https://github.com/analogdevicesinc/libad9361-iio && cd libad9361-iio && mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../
|
||||||
|
|
||||||
- name: Install LimeSuite
|
- name: Install LimeSuite
|
||||||
run: git clone https://github.com/myriadrf/LimeSuite && cd LimeSuite && mkdir builddir && cd builddir && cmake -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../
|
run: git clone https://github.com/myriadrf/LimeSuite && cd LimeSuite && mkdir builddir && cd builddir && cmake -DCMAKE_BUILD_TYPE=Release .. && make -j3 && sudo make install && cd ../../
|
||||||
|
|
||||||
- name: Prepare CMake
|
- name: Prepare CMake
|
||||||
working-directory: ${{runner.workspace}}/build
|
working-directory: ${{runner.workspace}}/build
|
||||||
run: cmake $GITHUB_WORKSPACE -DOPT_BUILD_PLUTOSDR_SOURCE=ON -DOPT_BUILD_SOAPY_SOURCE=OFF -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_AUDIO_SINK=OFF -DOPT_BUILD_PORTAUDIO_SINK=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=OFF -DUSE_BUNDLE_DEFAULTS=ON -DCMAKE_BUILD_TYPE=Release
|
run: cmake $GITHUB_WORKSPACE -DOPT_BUILD_PLUTOSDR_SOURCE=OFF -DOPT_BUILD_SOAPY_SOURCE=OFF -DOPT_BUILD_BLADERF_SOURCE=ON -DOPT_BUILD_SDRPLAY_SOURCE=ON -DOPT_BUILD_LIMESDR_SOURCE=ON -DOPT_BUILD_AUDIO_SINK=OFF -DOPT_BUILD_PORTAUDIO_SINK=ON -DOPT_BUILD_NEW_PORTAUDIO_SINK=ON -DOPT_BUILD_M17_DECODER=OFF -DUSE_BUNDLE_DEFAULTS=ON -DCMAKE_BUILD_TYPE=Release
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
working-directory: ${{runner.workspace}}/build
|
working-directory: ${{runner.workspace}}/build
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "../processor.h"
|
#include "../processor.h"
|
||||||
#include "../loop/agc.h"
|
#include "../loop/agc.h"
|
||||||
|
#include "../correction/dc_blocker.h"
|
||||||
|
|
||||||
namespace dsp::demod {
|
namespace dsp::demod {
|
||||||
class AM : public Processor<dsp::complex_t, float> {
|
class AM : public Processor<dsp::complex_t, float> {
|
||||||
@ -13,13 +14,14 @@ namespace dsp::demod {
|
|||||||
|
|
||||||
AM() {}
|
AM() {}
|
||||||
|
|
||||||
AM(stream<complex_t>* in, AGCMode agcMode, double agcRate) { init(in, agcMode, agcRate); }
|
AM(stream<complex_t>* in, AGCMode agcMode, double agcAttack, double agcDecay, double dcBlockRate) { init(in, agcMode, agcAttack, agcDecay, dcBlockRate); }
|
||||||
|
|
||||||
void init(stream<complex_t>* in, AGCMode agcMode, double agcRate) {
|
void init(stream<complex_t>* in, AGCMode agcMode, double agcAttack, double agcDecay, double dcBlockRate) {
|
||||||
_agcMode = agcMode;
|
_agcMode = agcMode;
|
||||||
|
|
||||||
carrierAgc.init(NULL, 1.0, agcRate, 10e6, 10.0);
|
carrierAgc.init(NULL, 1.0, agcAttack, agcDecay, 10e6, 10.0);
|
||||||
audioAgc.init(NULL, 1.0, agcRate, 10e6, 10.0);
|
audioAgc.init(NULL, 1.0, agcAttack, agcDecay, 10e6, 10.0);
|
||||||
|
dcBlock.init(NULL, dcBlockRate);
|
||||||
|
|
||||||
base_type::init(in);
|
base_type::init(in);
|
||||||
}
|
}
|
||||||
@ -33,11 +35,24 @@ namespace dsp::demod {
|
|||||||
base_type::tempStart();
|
base_type::tempStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setAGCRate(double agcRate) {
|
void setAGCAttack(double attack) {
|
||||||
assert(base_type::_block_init);
|
assert(base_type::_block_init);
|
||||||
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
||||||
carrierAgc.setRate(agcRate);
|
carrierAgc.setAttack(attack);
|
||||||
audioAgc.setRate(agcRate);
|
audioAgc.setAttack(attack);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAGCDecay(double decay) {
|
||||||
|
assert(base_type::_block_init);
|
||||||
|
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
||||||
|
carrierAgc.setDecay(decay);
|
||||||
|
audioAgc.setDecay(decay);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDCBlockRate(double rate) {
|
||||||
|
assert(base_type::_block_init);
|
||||||
|
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
||||||
|
dcBlock.setRate(rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
@ -46,6 +61,7 @@ namespace dsp::demod {
|
|||||||
base_type::tempStop();
|
base_type::tempStop();
|
||||||
carrierAgc.reset();
|
carrierAgc.reset();
|
||||||
audioAgc.reset();
|
audioAgc.reset();
|
||||||
|
dcBlock.reset();
|
||||||
base_type::tempStart();
|
base_type::tempStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,19 +72,14 @@ namespace dsp::demod {
|
|||||||
in = carrierAgc.out.writeBuf;
|
in = carrierAgc.out.writeBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get magnitude of each sample (TODO: use block instead)
|
// Get magnitude of each sample and remove DC (TODO: use block instead)
|
||||||
volk_32fc_magnitude_32f(out, (lv_32fc_t*)in, count);
|
volk_32fc_magnitude_32f(out, (lv_32fc_t*)in, count);
|
||||||
|
dcBlock.process(count, out, out);
|
||||||
|
|
||||||
// Apply audio AGC if needed
|
// Apply audio AGC if needed
|
||||||
if (_agcMode == AGCMode::AUDIO) {
|
if (_agcMode == AGCMode::AUDIO) {
|
||||||
audioAgc.process(count, out, out);
|
audioAgc.process(count, out, out);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// TODO: Find a volk function for it
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
out[i] -= 1.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
@ -89,6 +100,7 @@ namespace dsp::demod {
|
|||||||
|
|
||||||
loop::AGC<complex_t> carrierAgc;
|
loop::AGC<complex_t> carrierAgc;
|
||||||
loop::AGC<float> audioAgc;
|
loop::AGC<float> audioAgc;
|
||||||
|
correction::DCBlocker<float> dcBlock;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -16,29 +16,17 @@ namespace dsp::demod {
|
|||||||
|
|
||||||
SSB() {}
|
SSB() {}
|
||||||
|
|
||||||
/** Calls the init function
|
SSB(stream<complex_t>* in, Mode mode, double bandwidth, double samplerate, double agcAttack, double agcDecay) { init(in, mode, bandwidth, samplerate, agcAttack, agcDecay); }
|
||||||
*/
|
|
||||||
SSB(stream<complex_t>* in, Mode mode, double bandwidth, double samplerate, double agcRate) { init(in, mode, bandwidth, samplerate, agcRate); }
|
|
||||||
|
|
||||||
/** Initialize the SSB/DSB Demodulator
|
void init(stream<complex_t>* in, Mode mode, double bandwidth, double samplerate, double agcAttack, double agcDecay) {
|
||||||
* \param in Input stream
|
|
||||||
* \param mode Demodulation mode, can be USB, LSB or DSB
|
|
||||||
* \param bandwidth Bandwidth needed to shift back the IQ correctly
|
|
||||||
* \param samplerate Samplerate of the IQ data
|
|
||||||
* \param agcRate Speed at which the AGC corrects the audio level. This is NOT automatically scaled to the samplerate.
|
|
||||||
*/
|
|
||||||
void init(stream<complex_t>* in, Mode mode, double bandwidth, double samplerate, double agcRate) {
|
|
||||||
_mode = mode;
|
_mode = mode;
|
||||||
_bandwidth = bandwidth;
|
_bandwidth = bandwidth;
|
||||||
_samplerate = samplerate;
|
_samplerate = samplerate;
|
||||||
xlator.init(NULL, getTranslation(), _samplerate);
|
xlator.init(NULL, getTranslation(), _samplerate);
|
||||||
agc.init(NULL, 1.0, agcRate, 10e6, 10.0);
|
agc.init(NULL, 1.0, agcAttack, agcDecay, 10e6, 10.0);
|
||||||
base_type::init(in);
|
base_type::init(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set demodulation mode
|
|
||||||
* \param mode Either USB, LSB or DSB
|
|
||||||
*/
|
|
||||||
void setMode(Mode mode) {
|
void setMode(Mode mode) {
|
||||||
assert(base_type::_block_init);
|
assert(base_type::_block_init);
|
||||||
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
||||||
@ -48,9 +36,6 @@ namespace dsp::demod {
|
|||||||
base_type::tempStart();
|
base_type::tempStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set bandwidth
|
|
||||||
* \param bandwidth Bandwidth in Hz
|
|
||||||
*/
|
|
||||||
void setBandwidth(double bandwidth) {
|
void setBandwidth(double bandwidth) {
|
||||||
assert(base_type::_block_init);
|
assert(base_type::_block_init);
|
||||||
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
||||||
@ -60,9 +45,6 @@ namespace dsp::demod {
|
|||||||
base_type::tempStart();
|
base_type::tempStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set samplerate
|
|
||||||
* \param samplerate Samplerate in Hz
|
|
||||||
*/
|
|
||||||
void setSamplerate(double samplerate) {
|
void setSamplerate(double samplerate) {
|
||||||
assert(base_type::_block_init);
|
assert(base_type::_block_init);
|
||||||
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
||||||
@ -72,20 +54,18 @@ namespace dsp::demod {
|
|||||||
base_type::tempStart();
|
base_type::tempStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set AGC rate
|
void setAGCAttack(double attack) {
|
||||||
* \param agcRate AGC rate in units per second
|
|
||||||
*/
|
|
||||||
void setAGCRate(double agcRate) {
|
|
||||||
assert(base_type::_block_init);
|
assert(base_type::_block_init);
|
||||||
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
||||||
agc.setRate(agcRate);
|
agc.setAttack(attack);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAGCDecay(double decay) {
|
||||||
|
assert(base_type::_block_init);
|
||||||
|
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
||||||
|
agc.setDecay(decay);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Process data
|
|
||||||
* \param count Number of samples
|
|
||||||
* \param in Input buffer
|
|
||||||
* \param out Output buffer
|
|
||||||
*/
|
|
||||||
int process(int count, const complex_t* in, float* out) {
|
int process(int count, const complex_t* in, float* out) {
|
||||||
// Move back sideband
|
// Move back sideband
|
||||||
xlator.process(count, in, xlator.out.writeBuf);
|
xlator.process(count, in, xlator.out.writeBuf);
|
||||||
|
@ -8,12 +8,14 @@ namespace dsp::loop {
|
|||||||
public:
|
public:
|
||||||
AGC() {}
|
AGC() {}
|
||||||
|
|
||||||
AGC(stream<T>* in, double setPoint, double rate, double maxGain, double maxOutputAmp, double initGain = 1.0) { init(in, setPoint, rate, maxGain, maxOutputAmp, initGain); }
|
AGC(stream<T>* in, double setPoint, double attack, double decay, double maxGain, double maxOutputAmp, double initGain = 1.0) { init(in, setPoint, attack, decay, maxGain, maxOutputAmp, initGain); }
|
||||||
|
|
||||||
void init(stream<T>* in, double setPoint, double rate, double maxGain, double maxOutputAmp, double initGain = 1.0) {
|
void init(stream<T>* in, double setPoint, double attack, double decay, double maxGain, double maxOutputAmp, double initGain = 1.0) {
|
||||||
_setPoint = setPoint;
|
_setPoint = setPoint;
|
||||||
_rate = rate;
|
_attack = attack;
|
||||||
_invRate = 1.0f - _rate;
|
_invAttack = 1.0f - _attack;
|
||||||
|
_decay = decay;
|
||||||
|
_invDecay = 1.0f - _decay;
|
||||||
_maxGain = maxGain;
|
_maxGain = maxGain;
|
||||||
_maxOutputAmp = maxOutputAmp;
|
_maxOutputAmp = maxOutputAmp;
|
||||||
_initGain = initGain;
|
_initGain = initGain;
|
||||||
@ -27,11 +29,18 @@ namespace dsp::loop {
|
|||||||
_setPoint = setPoint;
|
_setPoint = setPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRate(double rate) {
|
void setAttack(double attack) {
|
||||||
assert(base_type::_block_init);
|
assert(base_type::_block_init);
|
||||||
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
||||||
_rate = rate;
|
_attack = attack;
|
||||||
_invRate = 1.0f - _rate;
|
_invAttack = 1.0f - _attack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDecay(double decay) {
|
||||||
|
assert(base_type::_block_init);
|
||||||
|
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
|
||||||
|
_decay = decay;
|
||||||
|
_invDecay = 1.0f - _decay;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setMaxGain(double maxGain) {
|
void setMaxGain(double maxGain) {
|
||||||
@ -72,7 +81,7 @@ namespace dsp::loop {
|
|||||||
|
|
||||||
// Update average amplitude
|
// Update average amplitude
|
||||||
if (inAmp != 0.0f) {
|
if (inAmp != 0.0f) {
|
||||||
amp = (amp * _invRate) + (inAmp * _rate);
|
amp = (inAmp > amp) ? ((amp * _invAttack) + (inAmp * _attack)) : ((amp * _invDecay) + (inAmp * _decay));
|
||||||
gain = std::min<float>(_setPoint / amp, _maxGain);
|
gain = std::min<float>(_setPoint / amp, _maxGain);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,8 +104,10 @@ namespace dsp::loop {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
float _setPoint;
|
float _setPoint;
|
||||||
float _rate;
|
float _attack;
|
||||||
float _invRate;
|
float _invAttack;
|
||||||
|
float _decay;
|
||||||
|
float _invDecay;
|
||||||
float _maxGain;
|
float _maxGain;
|
||||||
float _maxOutputAmp;
|
float _maxOutputAmp;
|
||||||
float _initGain;
|
float _initGain;
|
||||||
|
@ -18,9 +18,23 @@ namespace demod {
|
|||||||
|
|
||||||
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, EventHandler<dsp::stream<dsp::stereo_t>*> outputChangeHandler, EventHandler<float> afbwChangeHandler, double audioSR) {
|
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, EventHandler<dsp::stream<dsp::stereo_t>*> outputChangeHandler, EventHandler<float> afbwChangeHandler, double audioSR) {
|
||||||
this->name = name;
|
this->name = name;
|
||||||
|
_config = config;
|
||||||
|
|
||||||
|
// Load config
|
||||||
|
config->acquire();
|
||||||
|
if (config->conf[name][getName()].contains("agcAttack")) {
|
||||||
|
agcAttack = config->conf[name][getName()]["agcAttack"];
|
||||||
|
}
|
||||||
|
if (config->conf[name][getName()].contains("agcDecay")) {
|
||||||
|
agcDecay = config->conf[name][getName()]["agcDecay"];
|
||||||
|
}
|
||||||
|
if (config->conf[name][getName()].contains("carrierAgc")) {
|
||||||
|
carrierAgc = config->conf[name][getName()]["carrierAgc"];
|
||||||
|
}
|
||||||
|
config->release();
|
||||||
|
|
||||||
// Define structure
|
// Define structure
|
||||||
demod.init(input, dsp::demod::AM::AGCMode::CARRIER, 24.0 / getIFSampleRate());
|
demod.init(input, carrierAgc ? dsp::demod::AM::AGCMode::CARRIER : dsp::demod::AM::AGCMode::AUDIO, agcAttack / getIFSampleRate(), agcDecay / getIFSampleRate(), 100.0 / getIFSampleRate());
|
||||||
m2s.init(&demod.out);
|
m2s.init(&demod.out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +49,29 @@ namespace demod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void showMenu() {
|
void showMenu() {
|
||||||
// TODO: Adjust AGC settings
|
float menuWidth = ImGui::GetContentRegionAvail().x;
|
||||||
|
ImGui::LeftLabel("AGC Attack");
|
||||||
|
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
|
||||||
|
if (ImGui::SliderFloat(("##_radio_am_agc_attack_" + name).c_str(), &agcAttack, 1.0f, 50.0f)) {
|
||||||
|
demod.setAGCAttack(agcAttack / getIFSampleRate());
|
||||||
|
_config->acquire();
|
||||||
|
_config->conf[name][getName()]["agcAttack"] = agcAttack;
|
||||||
|
_config->release(true);
|
||||||
|
}
|
||||||
|
ImGui::LeftLabel("AGC Decay");
|
||||||
|
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
|
||||||
|
if (ImGui::SliderFloat(("AGC Decay##_radio_am_agc_decay_" + name).c_str(), &agcDecay, 1.0f, 50.0f)) {
|
||||||
|
demod.setAGCDecay(agcDecay / getIFSampleRate());
|
||||||
|
_config->acquire();
|
||||||
|
_config->conf[name][getName()]["agcDecay"] = agcDecay;
|
||||||
|
_config->release(true);
|
||||||
|
}
|
||||||
|
if (ImGui::Checkbox(("Carrier AGC (W.I.P.)##_radio_am_carrier_agc_" + name).c_str(), &carrierAgc)) {
|
||||||
|
demod.setAGCMode(carrierAgc ? dsp::demod::AM::AGCMode::CARRIER : dsp::demod::AM::AGCMode::AUDIO);
|
||||||
|
_config->acquire();
|
||||||
|
_config->conf[name][getName()]["carrierAgc"] = carrierAgc;
|
||||||
|
_config->release(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setBandwidth(double bandwidth) {}
|
void setBandwidth(double bandwidth) {}
|
||||||
@ -71,6 +107,12 @@ namespace demod {
|
|||||||
dsp::demod::AM demod;
|
dsp::demod::AM demod;
|
||||||
dsp::convert::MonoToStereo m2s;
|
dsp::convert::MonoToStereo m2s;
|
||||||
|
|
||||||
|
ConfigManager* _config = NULL;
|
||||||
|
|
||||||
|
float agcAttack = 40.0f;
|
||||||
|
float agcDecay = 5.0f;
|
||||||
|
bool carrierAgc = false;
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -26,6 +26,12 @@ namespace demod {
|
|||||||
|
|
||||||
// Load config
|
// Load config
|
||||||
config->acquire();
|
config->acquire();
|
||||||
|
if (config->conf[name][getName()].contains("agcAttack")) {
|
||||||
|
agcAttack = config->conf[name][getName()]["agcAttack"];
|
||||||
|
}
|
||||||
|
if (config->conf[name][getName()].contains("agcDecay")) {
|
||||||
|
agcDecay = config->conf[name][getName()]["agcDecay"];
|
||||||
|
}
|
||||||
if (config->conf[name][getName()].contains("tone")) {
|
if (config->conf[name][getName()].contains("tone")) {
|
||||||
tone = config->conf[name][getName()]["tone"];
|
tone = config->conf[name][getName()]["tone"];
|
||||||
}
|
}
|
||||||
@ -34,7 +40,7 @@ namespace demod {
|
|||||||
// Define structure
|
// Define structure
|
||||||
xlator.init(input, tone, getIFSampleRate());
|
xlator.init(input, tone, getIFSampleRate());
|
||||||
c2r.init(&xlator.out);
|
c2r.init(&xlator.out);
|
||||||
agc.init(&c2r.out, 1.0, 24.0 / getIFSampleRate(), 10e6, 10.0);
|
agc.init(&c2r.out, 1.0, agcAttack / getIFSampleRate(), agcDecay / getIFSampleRate(), 10e6, 10.0);
|
||||||
m2s.init(&agc.out);
|
m2s.init(&agc.out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,6 +59,23 @@ namespace demod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void showMenu() {
|
void showMenu() {
|
||||||
|
float menuWidth = ImGui::GetContentRegionAvail().x;
|
||||||
|
ImGui::LeftLabel("AGC Attack");
|
||||||
|
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
|
||||||
|
if (ImGui::SliderFloat(("##_radio_cw_agc_attack_" + name).c_str(), &agcAttack, 1.0f, 50.0f)) {
|
||||||
|
agc.setAttack(agcAttack / getIFSampleRate());
|
||||||
|
_config->acquire();
|
||||||
|
_config->conf[name][getName()]["agcAttack"] = agcAttack;
|
||||||
|
_config->release(true);
|
||||||
|
}
|
||||||
|
ImGui::LeftLabel("AGC Decay");
|
||||||
|
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
|
||||||
|
if (ImGui::SliderFloat(("AGC Decay##_radio_cw_agc_decay_" + name).c_str(), &agcDecay, 1.0f, 50.0f)) {
|
||||||
|
agc.setDecay(agcDecay / getIFSampleRate());
|
||||||
|
_config->acquire();
|
||||||
|
_config->conf[name][getName()]["agcDecay"] = agcDecay;
|
||||||
|
_config->release(true);
|
||||||
|
}
|
||||||
ImGui::LeftLabel("Tone Frequency");
|
ImGui::LeftLabel("Tone Frequency");
|
||||||
ImGui::FillWidth();
|
ImGui::FillWidth();
|
||||||
if (ImGui::InputInt(("Stereo##_radio_cw_tone_" + name).c_str(), &tone, 10, 100)) {
|
if (ImGui::InputInt(("Stereo##_radio_cw_tone_" + name).c_str(), &tone, 10, 100)) {
|
||||||
@ -103,6 +126,8 @@ namespace demod {
|
|||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
|
float agcAttack = 40.0f;
|
||||||
|
float agcDecay = 5.0f;
|
||||||
int tone = 800;
|
int tone = 800;
|
||||||
double _bandwidth;
|
double _bandwidth;
|
||||||
|
|
||||||
|
@ -18,9 +18,20 @@ namespace demod {
|
|||||||
|
|
||||||
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, EventHandler<dsp::stream<dsp::stereo_t>*> outputChangeHandler, EventHandler<float> afbwChangeHandler, double audioSR) {
|
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, EventHandler<dsp::stream<dsp::stereo_t>*> outputChangeHandler, EventHandler<float> afbwChangeHandler, double audioSR) {
|
||||||
this->name = name;
|
this->name = name;
|
||||||
|
_config = config;
|
||||||
|
|
||||||
|
// Load config
|
||||||
|
config->acquire();
|
||||||
|
if (config->conf[name][getName()].contains("agcAttack")) {
|
||||||
|
agcAttack = config->conf[name][getName()]["agcAttack"];
|
||||||
|
}
|
||||||
|
if (config->conf[name][getName()].contains("agcDecay")) {
|
||||||
|
agcDecay = config->conf[name][getName()]["agcDecay"];
|
||||||
|
}
|
||||||
|
config->release();
|
||||||
|
|
||||||
// Define structure
|
// Define structure
|
||||||
demod.init(input, dsp::demod::SSB::Mode::DSB, bandwidth, getIFSampleRate(), 24.0 / getIFSampleRate());
|
demod.init(input, dsp::demod::SSB::Mode::DSB, bandwidth, getIFSampleRate(), agcAttack / getIFSampleRate(), agcDecay / getIFSampleRate());
|
||||||
m2s.init(&demod.out);
|
m2s.init(&demod.out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +46,23 @@ namespace demod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void showMenu() {
|
void showMenu() {
|
||||||
// TODO: Adjust AGC settings
|
float menuWidth = ImGui::GetContentRegionAvail().x;
|
||||||
|
ImGui::LeftLabel("AGC Attack");
|
||||||
|
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
|
||||||
|
if (ImGui::SliderFloat(("##_radio_dsb_agc_attack_" + name).c_str(), &agcAttack, 1.0f, 50.0f)) {
|
||||||
|
demod.setAGCAttack(agcAttack / getIFSampleRate());
|
||||||
|
_config->acquire();
|
||||||
|
_config->conf[name][getName()]["agcAttack"] = agcAttack;
|
||||||
|
_config->release(true);
|
||||||
|
}
|
||||||
|
ImGui::LeftLabel("AGC Decay");
|
||||||
|
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
|
||||||
|
if (ImGui::SliderFloat(("AGC Decay##_radio_dsb_agc_decay_" + name).c_str(), &agcDecay, 1.0f, 50.0f)) {
|
||||||
|
demod.setAGCDecay(agcDecay / getIFSampleRate());
|
||||||
|
_config->acquire();
|
||||||
|
_config->conf[name][getName()]["agcDecay"] = agcDecay;
|
||||||
|
_config->release(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setBandwidth(double bandwidth) {
|
void setBandwidth(double bandwidth) {
|
||||||
@ -73,6 +100,11 @@ namespace demod {
|
|||||||
dsp::demod::SSB demod;
|
dsp::demod::SSB demod;
|
||||||
dsp::convert::MonoToStereo m2s;
|
dsp::convert::MonoToStereo m2s;
|
||||||
|
|
||||||
|
ConfigManager* _config;
|
||||||
|
|
||||||
|
float agcAttack = 40.0f;
|
||||||
|
float agcDecay = 5.0f;
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -18,9 +18,20 @@ namespace demod {
|
|||||||
|
|
||||||
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, EventHandler<dsp::stream<dsp::stereo_t>*> outputChangeHandler, EventHandler<float> afbwChangeHandler, double audioSR) {
|
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, EventHandler<dsp::stream<dsp::stereo_t>*> outputChangeHandler, EventHandler<float> afbwChangeHandler, double audioSR) {
|
||||||
this->name = name;
|
this->name = name;
|
||||||
|
_config = config;
|
||||||
|
|
||||||
|
// Load config
|
||||||
|
config->acquire();
|
||||||
|
if (config->conf[name][getName()].contains("agcAttack")) {
|
||||||
|
agcAttack = config->conf[name][getName()]["agcAttack"];
|
||||||
|
}
|
||||||
|
if (config->conf[name][getName()].contains("agcDecay")) {
|
||||||
|
agcDecay = config->conf[name][getName()]["agcDecay"];
|
||||||
|
}
|
||||||
|
config->release();
|
||||||
|
|
||||||
// Define structure
|
// Define structure
|
||||||
demod.init(input, dsp::demod::SSB::Mode::LSB, bandwidth, getIFSampleRate(), 24.0 / getIFSampleRate());
|
demod.init(input, dsp::demod::SSB::Mode::LSB, bandwidth, getIFSampleRate(), agcAttack / getIFSampleRate(), agcDecay / getIFSampleRate());
|
||||||
m2s.init(&demod.out);
|
m2s.init(&demod.out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +46,23 @@ namespace demod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void showMenu() {
|
void showMenu() {
|
||||||
// TODO: Adjust AGC settings
|
float menuWidth = ImGui::GetContentRegionAvail().x;
|
||||||
|
ImGui::LeftLabel("AGC Attack");
|
||||||
|
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
|
||||||
|
if (ImGui::SliderFloat(("##_radio_lsb_agc_attack_" + name).c_str(), &agcAttack, 1.0f, 50.0f)) {
|
||||||
|
demod.setAGCAttack(agcAttack / getIFSampleRate());
|
||||||
|
_config->acquire();
|
||||||
|
_config->conf[name][getName()]["agcAttack"] = agcAttack;
|
||||||
|
_config->release(true);
|
||||||
|
}
|
||||||
|
ImGui::LeftLabel("AGC Decay");
|
||||||
|
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
|
||||||
|
if (ImGui::SliderFloat(("AGC Decay##_radio_lsb_agc_decay_" + name).c_str(), &agcDecay, 1.0f, 50.0f)) {
|
||||||
|
demod.setAGCDecay(agcDecay / getIFSampleRate());
|
||||||
|
_config->acquire();
|
||||||
|
_config->conf[name][getName()]["agcDecay"] = agcDecay;
|
||||||
|
_config->release(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setBandwidth(double bandwidth) {
|
void setBandwidth(double bandwidth) {
|
||||||
@ -73,6 +100,11 @@ namespace demod {
|
|||||||
dsp::demod::SSB demod;
|
dsp::demod::SSB demod;
|
||||||
dsp::convert::MonoToStereo m2s;
|
dsp::convert::MonoToStereo m2s;
|
||||||
|
|
||||||
|
ConfigManager* _config;
|
||||||
|
|
||||||
|
float agcAttack = 40.0f;
|
||||||
|
float agcDecay = 5.0f;
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -18,9 +18,20 @@ namespace demod {
|
|||||||
|
|
||||||
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, EventHandler<dsp::stream<dsp::stereo_t>*> outputChangeHandler, EventHandler<float> afbwChangeHandler, double audioSR) {
|
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, EventHandler<dsp::stream<dsp::stereo_t>*> outputChangeHandler, EventHandler<float> afbwChangeHandler, double audioSR) {
|
||||||
this->name = name;
|
this->name = name;
|
||||||
|
_config = config;
|
||||||
|
|
||||||
|
// Load config
|
||||||
|
config->acquire();
|
||||||
|
if (config->conf[name][getName()].contains("agcAttack")) {
|
||||||
|
agcAttack = config->conf[name][getName()]["agcAttack"];
|
||||||
|
}
|
||||||
|
if (config->conf[name][getName()].contains("agcDecay")) {
|
||||||
|
agcDecay = config->conf[name][getName()]["agcDecay"];
|
||||||
|
}
|
||||||
|
config->release();
|
||||||
|
|
||||||
// Define structure
|
// Define structure
|
||||||
demod.init(input, dsp::demod::SSB::Mode::USB, bandwidth, getIFSampleRate(), 24.0 / getIFSampleRate());
|
demod.init(input, dsp::demod::SSB::Mode::USB, bandwidth, getIFSampleRate(), agcAttack / getIFSampleRate(), agcDecay / getIFSampleRate());
|
||||||
m2s.init(&demod.out);
|
m2s.init(&demod.out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +46,23 @@ namespace demod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void showMenu() {
|
void showMenu() {
|
||||||
// TODO: Adjust AGC settings
|
float menuWidth = ImGui::GetContentRegionAvail().x;
|
||||||
|
ImGui::LeftLabel("AGC Attack");
|
||||||
|
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
|
||||||
|
if (ImGui::SliderFloat(("##_radio_usb_agc_attack_" + name).c_str(), &agcAttack, 1.0f, 50.0f)) {
|
||||||
|
demod.setAGCAttack(agcAttack / getIFSampleRate());
|
||||||
|
_config->acquire();
|
||||||
|
_config->conf[name][getName()]["agcAttack"] = agcAttack;
|
||||||
|
_config->release(true);
|
||||||
|
}
|
||||||
|
ImGui::LeftLabel("AGC Decay");
|
||||||
|
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
|
||||||
|
if (ImGui::SliderFloat(("AGC Decay##_radio_usb_agc_decay_" + name).c_str(), &agcDecay, 1.0f, 50.0f)) {
|
||||||
|
demod.setAGCDecay(agcDecay / getIFSampleRate());
|
||||||
|
_config->acquire();
|
||||||
|
_config->conf[name][getName()]["agcDecay"] = agcDecay;
|
||||||
|
_config->release(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setBandwidth(double bandwidth) {
|
void setBandwidth(double bandwidth) {
|
||||||
@ -73,6 +100,11 @@ namespace demod {
|
|||||||
dsp::demod::SSB demod;
|
dsp::demod::SSB demod;
|
||||||
dsp::convert::MonoToStereo m2s;
|
dsp::convert::MonoToStereo m2s;
|
||||||
|
|
||||||
|
ConfigManager* _config;
|
||||||
|
|
||||||
|
float agcAttack = 40.0f;
|
||||||
|
float agcDecay = 5.0f;
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -26,10 +26,13 @@ namespace demod {
|
|||||||
if (config->conf[name][getName()].contains("stereo")) {
|
if (config->conf[name][getName()].contains("stereo")) {
|
||||||
_stereo = config->conf[name][getName()]["stereo"];
|
_stereo = config->conf[name][getName()]["stereo"];
|
||||||
}
|
}
|
||||||
|
if (config->conf[name][getName()].contains("lowPass")) {
|
||||||
|
_lowPass = config->conf[name][getName()]["lowPass"];
|
||||||
|
}
|
||||||
_config->release(modified);
|
_config->release(modified);
|
||||||
|
|
||||||
// Define structure
|
// Define structure
|
||||||
demod.init(input, bandwidth / 2.0f, getIFSampleRate(), _stereo);
|
demod.init(input, bandwidth / 2.0f, getIFSampleRate(), _stereo, _lowPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
@ -49,6 +52,9 @@ namespace demod {
|
|||||||
}
|
}
|
||||||
if (ImGui::Checkbox(("Low Pass##_radio_wfm_lowpass_" + name).c_str(), &_lowPass)) {
|
if (ImGui::Checkbox(("Low Pass##_radio_wfm_lowpass_" + name).c_str(), &_lowPass)) {
|
||||||
demod.setLowPass(_lowPass);
|
demod.setLowPass(_lowPass);
|
||||||
|
_config->acquire();
|
||||||
|
_config->conf[name][getName()]["lowPass"] = _lowPass;
|
||||||
|
_config->release(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user