4 Commits
1.0.1 ... 1.0.3

9 changed files with 110 additions and 6 deletions

View File

@ -35,6 +35,7 @@ namespace sdrpp_credits {
const char* patrons[] = { const char* patrons[] = {
"Croccydile", "Croccydile",
"Daniele D'Agnelli", "Daniele D'Agnelli",
"EB3FRN",
"Eric Johnson", "Eric Johnson",
"W4IPA", "W4IPA",
"Lee Donaghy", "Lee Donaghy",

View File

@ -213,6 +213,11 @@ void MainWindow::fftHandler(dsp::complex_t* samples, int count, void* ctx) {
MainWindow* _this = (MainWindow*)ctx; MainWindow* _this = (MainWindow*)ctx;
std::lock_guard<std::mutex> lck(_this->fft_mtx); std::lock_guard<std::mutex> lck(_this->fft_mtx);
// Check if the count is valid
if (count > _this->fftSize) {
return;
}
// Apply window // Apply window
volk_32fc_32f_multiply_32fc((lv_32fc_t*)_this->fft_in, (lv_32fc_t*)samples, sigpath::signalPath.fftTaps, count); volk_32fc_32f_multiply_32fc((lv_32fc_t*)_this->fft_in, (lv_32fc_t*)samples, sigpath::signalPath.fftTaps, count);
@ -657,9 +662,9 @@ void MainWindow::setFFTSize(int size) {
gui::waterfall.setRawFFTSize(fftSize); gui::waterfall.setRawFFTSize(fftSize);
sigpath::signalPath.setFFTSize(fftSize); sigpath::signalPath.setFFTSize(fftSize);
fftwf_destroy_plan(fftwPlan);
fftwf_free(fft_in); fftwf_free(fft_in);
fftwf_free(fft_out); fftwf_free(fft_out);
fftwf_destroy_plan(fftwPlan);
fft_in = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize); fft_in = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize);
fft_out = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize); fft_out = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize);

View File

@ -1,3 +1,3 @@
#pragma once #pragma once
#define VERSION_STR "1.0.1" #define VERSION_STR "1.0.3"

View File

@ -335,7 +335,7 @@ private:
// Setup and start stream // Setup and start stream
int sampCount = _this->sampleRate / 200; int sampCount = _this->sampleRate / 200;
_this->devStream.isTx = false; _this->devStream.isTx = false;
_this->devStream.channel = 0; _this->devStream.channel = _this->chanId;
_this->devStream.fifoSize = sampCount; // TODO: Check what it's actually supposed to be _this->devStream.fifoSize = sampCount; // TODO: Check what it's actually supposed to be
_this->devStream.throughputVsLatency = 0.5f; _this->devStream.throughputVsLatency = 0.5f;
_this->devStream.dataFmt = _this->devStream.LMS_FMT_F32; _this->devStream.dataFmt = _this->devStream.LMS_FMT_F32;

View File

@ -312,6 +312,14 @@ Modules in beta are still included in releases for the most part but not enabled
First, please make sure you're running the latest automated build. If your issue is linked to a bug it is likely that is has already been fixed in later releases First, please make sure you're running the latest automated build. If your issue is linked to a bug it is likely that is has already been fixed in later releases
## SDR++ crashes then it won't start again no matter what
This is a bug in 1.0.0 that was fixed in 1.0.1
In some cases, if a crash happened while the config was being saved, the config file woul be corrupted and SDR++ would refuse to start because of it.
This has now been fixed. If a config file is corrupted it'll just reset it to its default state.
## "hash collision" error when starting ## "hash collision" error when starting
You likely installed the `soapysdr-module-all` package on Ubuntu/Debian. If not it's still a SoapySDR bug caused by multiple soapy modules coming in conflict. Uninstall anything related to SoapySDR then install soapysdr itself and only the soapy modules you actually need. You likely installed the `soapysdr-module-all` package on Ubuntu/Debian. If not it's still a SoapySDR bug caused by multiple soapy modules coming in conflict. Uninstall anything related to SoapySDR then install soapysdr itself and only the soapy modules you actually need.
@ -347,6 +355,7 @@ I will soon publish a contributing.md listing the code style to use.
* [Croccydile](https://example.com/) * [Croccydile](https://example.com/)
* [Daniele D'Agnelli](https://linkedin.com/in/dagnelli) * [Daniele D'Agnelli](https://linkedin.com/in/dagnelli)
* [EB3FRN](https://www.eb3frn.net/)
* [Eric Johnson](https://example.com/) * [Eric Johnson](https://example.com/)
* [W4IPA](https://twitter.com/W4IPAstroke5) * [W4IPA](https://twitter.com/W4IPAstroke5)
* [Lee Donaghy](https://github.com/github) * [Lee Donaghy](https://github.com/github)

View File

@ -365,7 +365,7 @@ private:
if (parts.size() == 0) { return; } if (parts.size() == 0) { return; }
// If the command is a compound command, execute each one separately // If the command is a compound command, execute each one separately
if (parts[0].size() > 1 && parts[0][0] != '\\') { if (parts[0].size() > 1 && parts[0][0] != '\\' && parts[0] != "AOS" && parts[0] != "LOS") {
std::string arguments; std::string arguments;
if (parts.size() > 1) { arguments = cmd.substr(parts[0].size()); } if (parts.size() > 1) { arguments = cmd.substr(parts[0].size()); }
for (char c : parts[0]) { for (char c : parts[0]) {

View File

@ -162,6 +162,7 @@ public:
created = true; created = true;
config.conf["devices"][selectedDevName]["sampleRate"] = 2400000.0; config.conf["devices"][selectedDevName]["sampleRate"] = 2400000.0;
config.conf["devices"][selectedDevName]["directSampling"] = directSamplingMode; config.conf["devices"][selectedDevName]["directSampling"] = directSamplingMode;
config.conf["devices"][selectedDevName]["ppm"] = 0;
config.conf["devices"][selectedDevName]["biasT"] = biasT; config.conf["devices"][selectedDevName]["biasT"] = biasT;
config.conf["devices"][selectedDevName]["offsetTuning"] = offsetTuning; config.conf["devices"][selectedDevName]["offsetTuning"] = offsetTuning;
config.conf["devices"][selectedDevName]["rtlAgc"] = rtlAgc; config.conf["devices"][selectedDevName]["rtlAgc"] = rtlAgc;
@ -187,6 +188,10 @@ public:
directSamplingMode = config.conf["devices"][selectedDevName]["directSampling"]; directSamplingMode = config.conf["devices"][selectedDevName]["directSampling"];
} }
if (config.conf["devices"][selectedDevName].contains("ppm")) {
ppm = config.conf["devices"][selectedDevName]["ppm"];
}
if (config.conf["devices"][selectedDevName].contains("biasT")) { if (config.conf["devices"][selectedDevName].contains("biasT")) {
biasT = config.conf["devices"][selectedDevName]["biasT"]; biasT = config.conf["devices"][selectedDevName]["biasT"];
} }
@ -256,6 +261,7 @@ private:
rtlsdr_set_sample_rate(_this->openDev, _this->sampleRate); rtlsdr_set_sample_rate(_this->openDev, _this->sampleRate);
rtlsdr_set_center_freq(_this->openDev, _this->freq); rtlsdr_set_center_freq(_this->openDev, _this->freq);
rtlsdr_set_freq_correction(_this->openDev, _this->ppm);
rtlsdr_set_tuner_bandwidth(_this->openDev, 0); rtlsdr_set_tuner_bandwidth(_this->openDev, 0);
rtlsdr_set_direct_sampling(_this->openDev, _this->directSamplingMode); rtlsdr_set_direct_sampling(_this->openDev, _this->directSamplingMode);
rtlsdr_set_bias_tee(_this->openDev, _this->biasT); rtlsdr_set_bias_tee(_this->openDev, _this->biasT);
@ -372,6 +378,21 @@ private:
} }
} }
ImGui::Text("PPM Correction");
ImGui::SameLine();
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::InputInt(CONCAT("##_rtlsdr_ppm_", _this->name), &_this->ppm, 1, 10)) {
_this->ppm = std::clamp<int>(_this->ppm, -1000000, 1000000);
if (_this->running) {
rtlsdr_set_freq_correction(_this->openDev, _this->ppm);
}
if (_this->selectedDevName != "") {
config.acquire();
config.conf["devices"][_this->selectedDevName]["ppm"] = _this->ppm;
config.release(true);
}
}
if (ImGui::Checkbox(CONCAT("Bias T##_rtlsdr_rtl_biast_", _this->name), &_this->biasT)) { if (ImGui::Checkbox(CONCAT("Bias T##_rtlsdr_rtl_biast_", _this->name), &_this->biasT)) {
if (_this->running) { if (_this->running) {
rtlsdr_set_bias_tee(_this->openDev, _this->biasT); rtlsdr_set_bias_tee(_this->openDev, _this->biasT);
@ -471,6 +492,8 @@ private:
int devCount = 0; int devCount = 0;
std::thread workerThread; std::thread workerThread;
int ppm = 0;
bool biasT = false; bool biasT = false;
int gainId = 0; int gainId = 0;

View File

@ -48,6 +48,8 @@ const char* sampleRatesTxt[] = {
"3.2MHz" "3.2MHz"
}; };
#define SAMPLE_RATE_COUNT (sizeof(sampleRates) / sizeof(double))
class RTLTCPSourceModule : public ModuleManager::Instance { class RTLTCPSourceModule : public ModuleManager::Instance {
public: public:
RTLTCPSourceModule(std::string name) { RTLTCPSourceModule(std::string name) {
@ -55,8 +57,9 @@ public:
sampleRate = 2400000.0; sampleRate = 2400000.0;
int srCount = sizeof(sampleRatesTxt) / sizeof(char*); int _24id = 0;
for (int i = 0; i < srCount; i++) { for (int i = 0; i < SAMPLE_RATE_COUNT; i++) {
if (sampleRates[i] == 2400000) { _24id = i; }
srTxt += sampleRatesTxt[i]; srTxt += sampleRatesTxt[i];
srTxt += '\0'; srTxt += '\0';
} }
@ -65,7 +68,9 @@ public:
config.acquire(); config.acquire();
std::string hostStr = config.conf["host"]; std::string hostStr = config.conf["host"];
port = config.conf["port"]; port = config.conf["port"];
double wantedSr = config.conf["sampleRate"];
directSamplingMode = config.conf["directSamplingMode"]; directSamplingMode = config.conf["directSamplingMode"];
ppm = config.conf["ppm"];
rtlAGC = config.conf["rtlAGC"]; rtlAGC = config.conf["rtlAGC"];
tunerAGC = config.conf["tunerAGC"]; tunerAGC = config.conf["tunerAGC"];
gain = std::clamp<int>(config.conf["gainIndex"], 0, 28); gain = std::clamp<int>(config.conf["gainIndex"], 0, 28);
@ -75,6 +80,20 @@ public:
strcpy(ip, hostStr.c_str()); strcpy(ip, hostStr.c_str());
config.release(); config.release();
bool found = false;
for (int i = 0; i < SAMPLE_RATE_COUNT; i++) {
if (sampleRates[i] == wantedSr) {
found = true;
srId = i;
sampleRate = sampleRates[i];
break;
}
}
if (!found) {
srId = _24id;
sampleRate = sampleRates[_24id];
}
handler.ctx = this; handler.ctx = this;
handler.selectHandler = menuSelected; handler.selectHandler = menuSelected;
handler.deselectHandler = menuDeselected; handler.deselectHandler = menuDeselected;
@ -127,6 +146,7 @@ private:
spdlog::warn("Setting sample rate to {0}", _this->sampleRate); spdlog::warn("Setting sample rate to {0}", _this->sampleRate);
_this->client.setFrequency(_this->freq); _this->client.setFrequency(_this->freq);
_this->client.setSampleRate(_this->sampleRate); _this->client.setSampleRate(_this->sampleRate);
_this->client.setPPM(_this->ppm);
_this->client.setDirectSampling(_this->directSamplingMode); _this->client.setDirectSampling(_this->directSamplingMode);
_this->client.setAGCMode(_this->rtlAGC); _this->client.setAGCMode(_this->rtlAGC);
_this->client.setBiasTee(_this->biasTee); _this->client.setBiasTee(_this->biasTee);
@ -191,6 +211,9 @@ private:
if (ImGui::Combo(CONCAT("##_rtltcp_sr_", _this->name), &_this->srId, _this->srTxt.c_str())) { if (ImGui::Combo(CONCAT("##_rtltcp_sr_", _this->name), &_this->srId, _this->srTxt.c_str())) {
_this->sampleRate = sampleRates[_this->srId]; _this->sampleRate = sampleRates[_this->srId];
core::setInputSampleRate(_this->sampleRate); core::setInputSampleRate(_this->sampleRate);
config.acquire();
config.conf["sampleRate"] = _this->sampleRate;
config.release(true);
} }
if (_this->running) { style::endDisabled(); } if (_this->running) { style::endDisabled(); }
@ -203,18 +226,39 @@ private:
_this->client.setDirectSampling(_this->directSamplingMode); _this->client.setDirectSampling(_this->directSamplingMode);
_this->client.setGainIndex(_this->gain); _this->client.setGainIndex(_this->gain);
} }
config.acquire();
config.conf["directSamplingMode"] = _this->directSamplingMode;
config.release(true);
}
ImGui::Text("PPM Correction");
ImGui::SameLine();
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::InputInt(CONCAT("##_rtltcp_ppm_", _this->name), &_this->ppm, 1, 10)) {
if (_this->running) {
_this->client.setPPM(_this->ppm);
}
config.acquire();
config.conf["ppm"] = _this->ppm;
config.release(true);
} }
if (ImGui::Checkbox(CONCAT("Bias-T##_biast_select_", _this->name), &_this->biasTee)) { if (ImGui::Checkbox(CONCAT("Bias-T##_biast_select_", _this->name), &_this->biasTee)) {
if (_this->running) { if (_this->running) {
_this->client.setBiasTee(_this->biasTee); _this->client.setBiasTee(_this->biasTee);
} }
config.acquire();
config.conf["biasTee"] = _this->biasTee;
config.release(true);
} }
if (ImGui::Checkbox(CONCAT("Offset Tuning##_biast_select_", _this->name), &_this->offsetTuning)) { if (ImGui::Checkbox(CONCAT("Offset Tuning##_biast_select_", _this->name), &_this->offsetTuning)) {
if (_this->running) { if (_this->running) {
_this->client.setOffsetTuning(_this->offsetTuning); _this->client.setOffsetTuning(_this->offsetTuning);
} }
config.acquire();
config.conf["offsetTuning"] = _this->offsetTuning;
config.release(true);
} }
if (ImGui::Checkbox("RTL AGC", &_this->rtlAGC)) { if (ImGui::Checkbox("RTL AGC", &_this->rtlAGC)) {
@ -224,6 +268,9 @@ private:
_this->client.setGainIndex(_this->gain); _this->client.setGainIndex(_this->gain);
} }
} }
config.acquire();
config.conf["rtlAGC"] = _this->rtlAGC;
config.release(true);
} }
if (ImGui::Checkbox("Tuner AGC", &_this->tunerAGC)) { if (ImGui::Checkbox("Tuner AGC", &_this->tunerAGC)) {
@ -233,6 +280,9 @@ private:
_this->client.setGainIndex(_this->gain); _this->client.setGainIndex(_this->gain);
} }
} }
config.acquire();
config.conf["tunerAGC"] = _this->tunerAGC;
config.release(true);
} }
if (_this->tunerAGC) { style::beginDisabled(); } if (_this->tunerAGC) { style::beginDisabled(); }
@ -241,6 +291,9 @@ private:
if (_this->running) { if (_this->running) {
_this->client.setGainIndex(_this->gain); _this->client.setGainIndex(_this->gain);
} }
config.acquire();
config.conf["gainIndex"] = _this->gain;
config.release(true);
} }
if (_this->tunerAGC) { style::endDisabled(); } if (_this->tunerAGC) { style::endDisabled(); }
} }
@ -275,6 +328,7 @@ private:
char ip[1024] = "localhost"; char ip[1024] = "localhost";
int port = 1234; int port = 1234;
int gain = 0; int gain = 0;
int ppm = 0;
bool rtlAGC = false; bool rtlAGC = false;
bool tunerAGC = false; bool tunerAGC = false;
int directSamplingMode = 0; int directSamplingMode = 0;
@ -290,7 +344,9 @@ MOD_EXPORT void _INIT_() {
json defConf; json defConf;
defConf["host"] = "localhost"; defConf["host"] = "localhost";
defConf["port"] = 1234; defConf["port"] = 1234;
defConf["sampleRate"] = 2400000.0;
defConf["directSamplingMode"] = 0; defConf["directSamplingMode"] = 0;
defConf["ppm"] = 0;
defConf["rtlAGC"] = false; defConf["rtlAGC"] = false;
defConf["tunerAGC"] = false; defConf["tunerAGC"] = false;
defConf["gainIndex"] = 0; defConf["gainIndex"] = 0;
@ -306,6 +362,12 @@ MOD_EXPORT void _INIT_() {
if (!config.conf.contains("offsetTuning")) { if (!config.conf.contains("offsetTuning")) {
config.conf["offsetTuning"] = false; config.conf["offsetTuning"] = false;
} }
if (!config.conf.contains("ppm")) {
config.conf["ppm"] = 0;
}
if (!config.conf.contains("sampleRate")) {
config.conf["sampleRate"] = 2400000.0;
}
config.release(true); config.release(true);
} }

View File

@ -166,6 +166,10 @@ public:
sendCommand(4, gain); sendCommand(4, gain);
} }
void setPPM(int ppm) {
sendCommand(5, (uint32_t)ppm);
}
void setAGCMode(int mode) { void setAGCMode(int mode) {
sendCommand(8, mode); sendCommand(8, mode);
} }