This commit is contained in:
AlexandreRouma 2022-06-20 18:15:35 +02:00
parent ce1b0d0170
commit 53afaeda9e
17 changed files with 90 additions and 29 deletions

View File

@ -54,14 +54,13 @@ namespace dsp::channel {
void setBandwidth(double bandwidth) {
assert(base_type::_block_init);
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
base_type::tempStop();
std::lock_guard<std::mutex> lck2(filterMtx);
_bandwidth = bandwidth;
filterNeeded = (_bandwidth != _outSamplerate);
if (filterNeeded) {
generateTaps();
filter.setTaps(ftaps);
}
base_type::tempStart();
}
void setOffset(double offset) {
@ -87,7 +86,10 @@ namespace dsp::channel {
return resamp.process(count, out, out);
}
count = resamp.process(count, out, out);
{
std::lock_guard<std::mutex> lck(filterMtx);
filter.process(count, out, out);
}
return count;
}
@ -110,7 +112,6 @@ namespace dsp::channel {
taps::free(ftaps);
double filterWidth = _bandwidth / 2.0;
ftaps = taps::lowPass(filterWidth, filterWidth * 0.1, _outSamplerate);
printf("New taps just dropped: %lf %lf %lf\n", filterWidth, filterWidth*0.1, _outSamplerate);
}
FrequencyXlator xlator;
@ -123,5 +124,7 @@ namespace dsp::channel {
double _outSamplerate;
double _bandwidth;
double _offset;
std::mutex filterMtx;
};
}

View File

@ -23,6 +23,9 @@ namespace dsp::demod {
audioAgc.init(NULL, 1.0, agcAttack, agcDecay, 10e6, 10.0);
dcBlock.init(NULL, dcBlockRate);
audioAgc.out.free();
dcBlock.out.free();
base_type::init(in);
}

View File

@ -52,6 +52,11 @@ namespace dsp::demod {
l = buffer::alloc<float>(STREAM_BUFFER_SIZE);
r = buffer::alloc<float>(STREAM_BUFFER_SIZE);
lprDelay.out.free();
lmrDelay.out.free();
arFir.out.free();
alFir.out.free();
base_type::init(in);
}

View File

@ -22,8 +22,12 @@ namespace dsp::demod {
_mode = mode;
_bandwidth = bandwidth;
_samplerate = samplerate;
xlator.init(NULL, getTranslation(), _samplerate);
agc.init(NULL, 1.0, agcAttack, agcDecay, 10e6, 10.0);
agc.out.free();
base_type::init(in);
}

View File

@ -33,11 +33,20 @@ namespace dsp::filter {
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
base_type::tempStop();
int oldTC = _taps.size;
_taps = taps;
// Reset buffer
// Update start of buffer
bufStart = &buffer[_taps.size - 1];
buffer::clear<D>(buffer, _taps.size - 1);
// Move existing data to make transition seemless
if (_taps.size < oldTC) {
memcpy(buffer, &buffer[oldTC - _taps.size], (_taps.size - 1) * sizeof(D));
}
else if (_taps.size > oldTC) {
memcpy(&buffer[_taps.size - oldTC], buffer, (oldTC - 1) * sizeof(D));
buffer::clear<D>(buffer, _taps.size - oldTC);
}
base_type::tempStart();
}

View File

@ -19,7 +19,7 @@ namespace dsp::loop {
_maxGain = maxGain;
_maxOutputAmp = maxOutputAmp;
_initGain = initGain;
gain = _initGain;
amp = _setPoint / _initGain;
base_type::init(in);
}
@ -64,14 +64,13 @@ namespace dsp::loop {
void reset() {
assert(base_type::_block_init);
std::lock_guard<std::recursive_mutex> lck(base_type::ctrlMtx);
gain = _initGain;
amp = 1.0f;
amp = _setPoint / _initGain;
}
inline int process(int count, T* in, T* out) {
for (int i = 0; i < count; i++) {
// Get signal amplitude
float inAmp;
float inAmp, gain;
if constexpr (std::is_same_v<T, complex_t>) {
inAmp = in[i].amplitude();
}
@ -85,6 +84,22 @@ namespace dsp::loop {
gain = std::min<float>(_setPoint / amp, _maxGain);
}
// If clipping is detected look ahead and correct
if (inAmp*gain > _maxOutputAmp) {
float maxAmp = 0;
for (int j = i; j < count; j++) {
if constexpr (std::is_same_v<T, complex_t>) {
inAmp = in[i].amplitude();
}
if constexpr (std::is_same_v<T, float>) {
inAmp = fabsf(in[i]);
}
if (inAmp > maxAmp) { maxAmp = inAmp; }
}
amp = maxAmp;
gain = _setPoint / maxAmp;
}
// Scale output by gain
out[i] = in[i] * gain;
}
@ -112,7 +127,6 @@ namespace dsp::loop {
float _maxOutputAmp;
float _initGain;
float gain;
float amp = 1.0;
};

View File

@ -100,6 +100,7 @@ namespace dsp::multirate {
for (int i = 0; i < stageCount; i++) {
tap<float> taps = taps::fromArray<float>(plan.stages[i].tapcount, plan.stages[i].taps);
auto fir = new filter::DecimatingFIR<T, float>(NULL, taps, plan.stages[i].decimation);
fir->out.free();
decimTaps.push_back(taps);
decimFirs.push_back(fir);
}

View File

@ -27,6 +27,9 @@ namespace dsp::multirate {
decim.init(NULL, 2);
resamp.init(NULL, 1, 1, rtaps);
decim.out.free();
resamp.out.free();
// Proper configuration
reconfigure();

View File

@ -10,8 +10,16 @@ namespace dsp::noise_reduction {
Squelch(stream<complex_t>* in, double level) {}
~Squelch() {
if (!base_type::_block_init) { return; }
buffer::free(normBuffer);
}
void init(stream<complex_t>* in, double level) {
_level = level;
normBuffer = buffer::alloc<float>(STREAM_BUFFER_SIZE);
base_type::init(in);
}

View File

@ -29,8 +29,7 @@ namespace dsp {
}
virtual ~stream() {
buffer::free(writeBuf);
buffer::free(readBuf);
free();
}
virtual void setBufferSize(int samples) {
@ -115,6 +114,13 @@ namespace dsp {
readerStop = false;
}
void free() {
if (writeBuf) { buffer::free(writeBuf); }
if (readBuf) { buffer::free(readBuf); }
writeBuf = NULL;
readBuf = NULL;
}
T* writeBuf;
T* readBuf;

View File

@ -4,6 +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;
_bandwidth = bandwidth;
dspVFO = sigpath::iqFrontEnd.addVFO(name, sampleRate, bandwidth, offset);
wtfVFO = new ImGui::WaterfallVFO;
wtfVFO->setReference(reference);
@ -41,6 +42,8 @@ void VFOManager::VFO::setCenterOffset(double offset) {
}
void VFOManager::VFO::setBandwidth(double bandwidth, bool updateWaterfall) {
if (_bandwidth == bandwidth) { return; }
_bandwidth = bandwidth;
if (updateWaterfall) { wtfVFO->setBandwidth(bandwidth); }
dspVFO->setBandwidth(bandwidth);
}

View File

@ -35,6 +35,8 @@ public:
private:
std::string name;
double _bandwidth;
};
VFOManager::VFO* createVFO(std::string name, int reference, double offset, double bandwidth, double sampleRate, double minBandwidth, double maxBandwidth, bool bandwidthLocked);

View File

@ -52,7 +52,7 @@ namespace demod {
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)) {
if (ImGui::SliderFloat(("##_radio_am_agc_attack_" + name).c_str(), &agcAttack, 1.0f, 100.0f)) {
demod.setAGCAttack(agcAttack / getIFSampleRate());
_config->acquire();
_config->conf[name][getName()]["agcAttack"] = agcAttack;
@ -60,7 +60,7 @@ namespace demod {
}
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)) {
if (ImGui::SliderFloat(("AGC Decay##_radio_am_agc_decay_" + name).c_str(), &agcDecay, 1.0f, 20.0f)) {
demod.setAGCDecay(agcDecay / getIFSampleRate());
_config->acquire();
_config->conf[name][getName()]["agcDecay"] = agcDecay;
@ -109,7 +109,7 @@ namespace demod {
ConfigManager* _config = NULL;
float agcAttack = 40.0f;
float agcAttack = 50.0f;
float agcDecay = 5.0f;
bool carrierAgc = false;

View File

@ -62,7 +62,7 @@ namespace demod {
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)) {
if (ImGui::SliderFloat(("##_radio_cw_agc_attack_" + name).c_str(), &agcAttack, 1.0f, 100.0f)) {
agc.setAttack(agcAttack / getIFSampleRate());
_config->acquire();
_config->conf[name][getName()]["agcAttack"] = agcAttack;
@ -70,7 +70,7 @@ namespace demod {
}
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)) {
if (ImGui::SliderFloat(("AGC Decay##_radio_cw_agc_decay_" + name).c_str(), &agcDecay, 1.0f, 20.0f)) {
agc.setDecay(agcDecay / getIFSampleRate());
_config->acquire();
_config->conf[name][getName()]["agcDecay"] = agcDecay;
@ -101,7 +101,7 @@ namespace demod {
const char* getName() { return "CW"; }
double getIFSampleRate() { return 3000.0; }
double getAFSampleRate() { return getIFSampleRate(); }
double getDefaultBandwidth() { return 500.0; }
double getDefaultBandwidth() { return 200.0; }
double getMinBandwidth() { return 50.0; }
double getMaxBandwidth() { return 500.0; }
bool getBandwidthLocked() { return false; }
@ -126,7 +126,7 @@ namespace demod {
std::string name;
float agcAttack = 40.0f;
float agcAttack = 50.0f;
float agcDecay = 5.0f;
int tone = 800;
double _bandwidth;

View File

@ -49,7 +49,7 @@ namespace demod {
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)) {
if (ImGui::SliderFloat(("##_radio_dsb_agc_attack_" + name).c_str(), &agcAttack, 1.0f, 100.0f)) {
demod.setAGCAttack(agcAttack / getIFSampleRate());
_config->acquire();
_config->conf[name][getName()]["agcAttack"] = agcAttack;
@ -57,7 +57,7 @@ namespace demod {
}
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)) {
if (ImGui::SliderFloat(("AGC Decay##_radio_dsb_agc_decay_" + name).c_str(), &agcDecay, 1.0f, 20.0f)) {
demod.setAGCDecay(agcDecay / getIFSampleRate());
_config->acquire();
_config->conf[name][getName()]["agcDecay"] = agcDecay;
@ -102,7 +102,7 @@ namespace demod {
ConfigManager* _config;
float agcAttack = 40.0f;
float agcAttack = 50.0f;
float agcDecay = 5.0f;
std::string name;

View File

@ -49,7 +49,7 @@ namespace demod {
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)) {
if (ImGui::SliderFloat(("##_radio_lsb_agc_attack_" + name).c_str(), &agcAttack, 1.0f, 100.0f)) {
demod.setAGCAttack(agcAttack / getIFSampleRate());
_config->acquire();
_config->conf[name][getName()]["agcAttack"] = agcAttack;
@ -57,7 +57,7 @@ namespace demod {
}
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)) {
if (ImGui::SliderFloat(("AGC Decay##_radio_lsb_agc_decay_" + name).c_str(), &agcDecay, 1.0f, 20.0f)) {
demod.setAGCDecay(agcDecay / getIFSampleRate());
_config->acquire();
_config->conf[name][getName()]["agcDecay"] = agcDecay;
@ -102,7 +102,7 @@ namespace demod {
ConfigManager* _config;
float agcAttack = 40.0f;
float agcAttack = 50.0f;
float agcDecay = 5.0f;
std::string name;

View File

@ -49,7 +49,7 @@ namespace demod {
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)) {
if (ImGui::SliderFloat(("##_radio_usb_agc_attack_" + name).c_str(), &agcAttack, 1.0f, 100.0f)) {
demod.setAGCAttack(agcAttack / getIFSampleRate());
_config->acquire();
_config->conf[name][getName()]["agcAttack"] = agcAttack;
@ -57,7 +57,7 @@ namespace demod {
}
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)) {
if (ImGui::SliderFloat(("AGC Decay##_radio_usb_agc_decay_" + name).c_str(), &agcDecay, 1.0f, 20.0f)) {
demod.setAGCDecay(agcDecay / getIFSampleRate());
_config->acquire();
_config->conf[name][getName()]["agcDecay"] = agcDecay;
@ -102,7 +102,7 @@ namespace demod {
ConfigManager* _config;
float agcAttack = 40.0f;
float agcAttack = 50.0f;
float agcDecay = 5.0f;
std::string name;