Skip to content

Commit 94074be

Browse files
author
Ryzerth
committed
New alpha version
1 parent a7a0be1 commit 94074be

File tree

8 files changed

+101
-18
lines changed

8 files changed

+101
-18
lines changed

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ set(CMAKE_BUILD_TYPE "RelWithDebInfo")
66
# Compiler config
77
set(CMAKE_CXX_FLAGS "-O2 /std:c++17")
88

9+
# PothosSDR
10+
link_directories(sdrpp "C:/Program Files/PothosSDR/lib/")
11+
912
# Volk
1013
include_directories(sdrpp "C:/Program Files/PothosSDR/include/volk/")
1114
link_libraries(volk)

readme.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,19 @@ SDR++ is a cross-platform and open source SDR software with the aim of being blo
2020
* Recording
2121
* Light theme (I know you weirdos exist lol)
2222
* Waterfall color scheme editor
23-
*
23+
* Switchable fft size
24+
* Bias-T enable/disable
25+
* other small customisation options
26+
* Save waterfall and demod settings between sessions
27+
* "Hide sidebar" option
28+
29+
## Known issues (please check before reporting)
30+
* Random crashes (yikes)
31+
* Gains aren't stepped
32+
* The default gains might contain a bogus value before being adjusted
33+
* Clicks in the audio
34+
* In some cases, it takes a long time to select a device (RTL-SDR in perticular)
35+
* Min and Max buttons can get unachievable values (eg. min > max or min = max);
2436

2537
# Building on Windows
2638
## Requirements

src/dsp/demodulator.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,9 @@ namespace dsp {
196196
max = outBuf[i];
197197
}
198198
}
199-
amp = (max - min);
199+
amp = (max - min) / 2.0f;
200200
for (int i = 0; i < _this->_blockSize; i++) {
201-
outBuf[i] = (outBuf[i] - min) / (max - min);
201+
outBuf[i] = (outBuf[i] - min - amp) / amp;
202202
}
203203
if (_this->output.write(outBuf, _this->_blockSize) < 0) { break; };
204204
}

src/io/soapy.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace io {
99
public:
1010
SoapyWrapper() {
1111
output.init(64000);
12+
currentGains = new float[1];
1213
refresh();
1314
setDevice(devList[0]);
1415
}
@@ -60,6 +61,18 @@ namespace io {
6061
txtSampleRateList += std::to_string((int)sampleRates[i]);
6162
txtSampleRateList += '\0';
6263
}
64+
65+
gainList = dev->listGains(SOAPY_SDR_RX, 0);
66+
gainRanges.clear();
67+
if (gainList.size() == 0) {
68+
return;
69+
}
70+
delete[] currentGains;
71+
currentGains = new float[gainList.size()];
72+
for (int i = 0; i < gainList.size(); i++) {
73+
gainRanges.push_back(dev->getGainRange(SOAPY_SDR_RX, 0, gainList[i]));
74+
currentGains[i] = dev->getGain(SOAPY_SDR_RX, 0, gainList[i]);
75+
}
6376
}
6477

6578
void setSampleRate(float sampleRate) {
@@ -74,6 +87,11 @@ namespace io {
7487
dev->setFrequency(SOAPY_SDR_RX, 0, freq);
7588
}
7689

90+
void setGain(int gainId, float gain) {
91+
currentGains[gainId] = gain;
92+
dev->setGain(SOAPY_SDR_RX, 0, gainList[gainId], gain);
93+
}
94+
7795
bool isRunning() {
7896
return running;
7997
}
@@ -83,6 +101,10 @@ namespace io {
83101
std::vector<double> sampleRates;
84102
std::string txtSampleRateList;
85103

104+
std::vector<std::string> gainList;
105+
std::vector<SoapySDR::Range> gainRanges;
106+
float* currentGains;
107+
86108
dsp::stream<dsp::complex_t> output;
87109

88110
private:

src/main_window.cpp

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ FrequencySelect fSel;
2121
fftwf_complex *fft_in, *fft_out;
2222
fftwf_plan p;
2323
float* tempData;
24+
float* uiGains;
25+
char buf[1024];
2426

2527
int fftSize = 8192 * 8;
2628

@@ -66,6 +68,8 @@ void windowInit() {
6668

6769
sigPath.init(sampleRate, 20, fftSize, &soapy.output, (dsp::complex_t*)fft_in, fftHandler);
6870
sigPath.start();
71+
72+
uiGains = new float[1];
6973
}
7074

7175
int devId = 0;
@@ -79,7 +83,7 @@ bool showExample = false;
7983
long freq = 90500000;
8084
long _freq = 90500000;
8185

82-
int demod = 0;
86+
int demod = 1;
8387

8488
bool state = false;
8589
bool mulstate = true;
@@ -220,6 +224,17 @@ void drawWindow() {
220224
if (devId != _devId) {
221225
_devId = devId;
222226
soapy.setDevice(soapy.devList[devId]);
227+
srId = 0;
228+
_srId = -1;
229+
soapy.setSampleRate(soapy.sampleRates[0]);
230+
if (soapy.gainList.size() == 0) {
231+
return;
232+
}
233+
delete[] uiGains;
234+
uiGains = new float[soapy.gainList.size()];
235+
for (int i = 0; i < soapy.gainList.size(); i++) {
236+
uiGains[i] = soapy.currentGains[i];
237+
}
223238
}
224239

225240
if (srId != _srId) {
@@ -269,11 +284,6 @@ void drawWindow() {
269284

270285
fSel.draw();
271286

272-
ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 8);
273-
ImGui::SameLine(ImGui::GetWindowWidth() - 40);
274-
ImGui::Image(icons::LOGO, ImVec2(30, 30));
275-
276-
277287
ImGui::Columns(3, "WindowColumns", false);
278288
ImVec2 winSize = ImGui::GetWindowSize();
279289
ImGui::SetColumnWidth(0, 300);
@@ -287,17 +297,34 @@ void drawWindow() {
287297
ImGui::PushItemWidth(ImGui::GetWindowSize().x);
288298
ImGui::Combo("##_0_", &devId, soapy.txtDevList.c_str());
289299

300+
ImGui::PopItemWidth();
290301
if (!playing) {
291302
ImGui::Combo("##_1_", &srId, soapy.txtSampleRateList.c_str());
292303
}
293304
else {
294305
ImGui::Text("%s Samples/s", soapy.txtSampleRateList.c_str());
295306
}
296-
297307

308+
ImGui::SameLine();
298309
if (ImGui::Button("Refresh")) {
299310
soapy.refresh();
300311
}
312+
313+
for (int i = 0; i < soapy.gainList.size(); i++) {
314+
ImGui::Text("%s gain", soapy.gainList[i].c_str());
315+
ImGui::SameLine();
316+
sprintf(buf, "##_gain_slide_%d_", i);
317+
ImGui::SliderFloat(buf, &uiGains[i], soapy.gainRanges[i].minimum(), soapy.gainRanges[i].maximum());
318+
319+
// float step = soapy.gainRanges[i].step();
320+
// printf("%f\n", step);
321+
322+
// uiGains[i] = roundf(uiGains[i] / soapy.gainRanges[i].step()) * soapy.gainRanges[i].step();
323+
324+
if (uiGains[i] != soapy.currentGains[i]) {
325+
soapy.setGain(i, uiGains[i]);
326+
}
327+
}
301328
}
302329

303330
if (ImGui::CollapsingHeader("Radio")) {
@@ -370,7 +397,7 @@ void drawWindow() {
370397
ImGui::NextColumn();
371398

372399
ImGui::Text("Zoom");
373-
ImGui::VSliderFloat("##_7_", ImVec2(20.0f, 150.0f), &bw, 1000.0f, sampleRate, "");
400+
ImGui::VSliderFloat("##_7_", ImVec2(20.0f, 150.0f), &bw, sampleRate, 1000.0f, "");
374401

375402
ImGui::NewLine();
376403

src/signal_path.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,4 +160,8 @@ void SignalPath::start() {
160160

161161
audioResamp.start();
162162
audio.start();
163+
}
164+
165+
void SignalPath::setDCBiasCorrection(bool enabled) {
166+
dcBiasRemover.bypass = !enabled;
163167
}

src/waterfall.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ void doZoom(int offset, int width, int outWidth, std::vector<float> data, float*
3535
}
3636

3737
float freq_ranges[] = {
38+
1.0f, 2.0f, 2.5f, 5.0f,
3839
10.0f, 20.0f, 25.0f, 50.0f,
3940
100.0f, 200.0f, 250.0f, 500.0f,
4041
1000.0f, 2000.0f, 2500.0f, 5000.0f,
@@ -44,9 +45,9 @@ float freq_ranges[] = {
4445
10000000.0f, 20000000.0f, 25000000.0f, 50000000.0f
4546
};
4647

47-
float findBestFreqRange(float bandwidth) {
48-
for (int i = 0; i < 28; i++) {
49-
if (bandwidth / freq_ranges[i] < 25.0f) {
48+
float findBestRange(float bandwidth, int maxSteps) {
49+
for (int i = 0; i < 32; i++) {
50+
if (bandwidth / freq_ranges[i] < (float)maxSteps) {
5051
return freq_ranges[i];
5152
}
5253
}
@@ -104,14 +105,14 @@ namespace ImGui {
104105

105106
void WaterFall::drawFFT() {
106107
// Calculate scaling factor
107-
float startLine = floorf(fftMax / 10.0f) * 10.0f;
108+
float startLine = floorf(fftMax / vRange) * vRange;
108109
float vertRange = fftMax - fftMin;
109110
float scaleFactor = fftHeight / vertRange;
110111
char buf[100];
111112

112113

113114
// Vertical scale
114-
for (float line = startLine; line > fftMin; line -= 10.0f) {
115+
for (float line = startLine; line > fftMin; line -= vRange) {
115116
float yPos = widgetPos.y + fftHeight + 10 - ((line - fftMin) * scaleFactor);
116117
window->DrawList->AddLine(ImVec2(widgetPos.x + 50, roundf(yPos)),
117118
ImVec2(widgetPos.x + dataWidth + 50, roundf(yPos)),
@@ -177,7 +178,7 @@ namespace ImGui {
177178

178179
void WaterFall::drawVFO() {
179180
float width = (vfoBandwidth / viewBandwidth) * (float)dataWidth;
180-
int center = (((vfoOffset - viewOffset) / (viewBandwidth / 2.0f)) + 1.0f) * ((float)dataWidth / 2.0f);
181+
int center = roundf((((vfoOffset - viewOffset) / (viewBandwidth / 2.0f)) + 1.0f) * ((float)dataWidth / 2.0f));
181182
int left;
182183
int right;
183184

@@ -316,6 +317,13 @@ namespace ImGui {
316317
freqAreaMin = ImVec2(widgetPos.x + 50, widgetPos.y + fftHeight + 11);
317318
freqAreaMax = ImVec2(widgetPos.x + dataWidth + 50, widgetPos.y + fftHeight + 50);
318319

320+
maxHSteps = dataWidth / 50;
321+
maxVSteps = fftHeight / 15;
322+
323+
range = findBestRange(viewBandwidth, maxHSteps);
324+
vRange = findBestRange(fftMax - fftMin, maxVSteps);
325+
vRange = 10.0f;
326+
319327
printf("Resized: %d %d\n", dataWidth, waterfallHeight);
320328

321329
updateWaterfallFb();
@@ -461,7 +469,7 @@ namespace ImGui {
461469
viewBandwidth = bandWidth;
462470
lowerFreq = (centerFreq + viewOffset) - (viewBandwidth / 2.0f);
463471
upperFreq = (centerFreq + viewOffset) + (viewBandwidth / 2.0f);
464-
range = findBestFreqRange(bandWidth);
472+
range = findBestRange(bandWidth, maxHSteps);
465473
updateWaterfallFb();
466474
}
467475

@@ -491,6 +499,7 @@ namespace ImGui {
491499

492500
void WaterFall::setFFTMin(float min) {
493501
fftMin = min;
502+
vRange = findBestRange(fftMax - fftMin, maxVSteps);
494503
}
495504

496505
float WaterFall::getFFTMin() {
@@ -499,6 +508,7 @@ namespace ImGui {
499508

500509
void WaterFall::setFFTMax(float max) {
501510
fftMax = max;
511+
vRange = findBestRange(fftMax - fftMin, maxVSteps);
502512
}
503513

504514
float WaterFall::getFFTMax() {

src/waterfall.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ namespace ImGui {
100100

101101
std::mutex buf_mtx;
102102

103+
float vRange;
104+
105+
int maxVSteps;
106+
int maxHSteps;
107+
103108
int dataWidth; // Width of the FFT and waterfall
104109
int fftHeight; // Height of the fft graph
105110
int waterfallHeight; // Height of the waterfall

0 commit comments

Comments
 (0)