mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-02-02 21:04:45 +01:00
Performance improvement to the FFT + code cleanup + Added an option to select the FFT window
This commit is contained in:
parent
6db8251e46
commit
ab376ea1aa
@ -118,6 +118,7 @@ int sdrpp_main(int argc, char *argv[]) {
|
|||||||
defConfig["fastFFT"] = false;
|
defConfig["fastFFT"] = false;
|
||||||
defConfig["fftHeight"] = 300;
|
defConfig["fftHeight"] = 300;
|
||||||
defConfig["fftSize"] = 65536;
|
defConfig["fftSize"] = 65536;
|
||||||
|
defConfig["fftWindow"] = 0;
|
||||||
defConfig["frequency"] = 100000000.0;
|
defConfig["frequency"] = 100000000.0;
|
||||||
defConfig["fullWaterfallUpdate"] = false;
|
defConfig["fullWaterfallUpdate"] = false;
|
||||||
defConfig["max"] = 0.0;
|
defConfig["max"] = 0.0;
|
||||||
|
@ -40,8 +40,8 @@ void MainWindow::init() {
|
|||||||
gui::waterfall.init();
|
gui::waterfall.init();
|
||||||
gui::waterfall.setRawFFTSize(fftSize);
|
gui::waterfall.setRawFFTSize(fftSize);
|
||||||
|
|
||||||
tempFFT = new float[fftSize];
|
appliedWindow = new float[fftSize];
|
||||||
FFTdata = new float[fftSize];
|
generateFFTWindow(selectedWindow, fftSize);
|
||||||
|
|
||||||
credits::init();
|
credits::init();
|
||||||
|
|
||||||
@ -201,21 +201,23 @@ void MainWindow::fftHandler(dsp::complex_t* samples, int count, void* ctx) {
|
|||||||
std::lock_guard<std::mutex> lck(_this->fft_mtx);
|
std::lock_guard<std::mutex> lck(_this->fft_mtx);
|
||||||
if (count != _this->fftSize) { return; }
|
if (count != _this->fftSize) { return; }
|
||||||
|
|
||||||
memcpy(_this->fft_in, samples, count * sizeof(dsp::complex_t));
|
// Apply window
|
||||||
fftwf_execute(_this->fftwPlan);
|
volk_32fc_32f_multiply_32fc((lv_32fc_t*)_this->fft_in, (lv_32fc_t*)samples, _this->appliedWindow, count);
|
||||||
int half = count / 2;
|
|
||||||
|
|
||||||
|
// Execute FFT
|
||||||
|
fftwf_execute(_this->fftwPlan);
|
||||||
|
|
||||||
|
// Get the FFT buffer
|
||||||
float* fftBuf = gui::waterfall.getFFTBuffer();
|
float* fftBuf = gui::waterfall.getFFTBuffer();
|
||||||
if (fftBuf == NULL) {
|
if (fftBuf == NULL) {
|
||||||
gui::waterfall.pushFFT();
|
gui::waterfall.pushFFT();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
volk_32fc_s32f_power_spectrum_32f(_this->tempFFT, (lv_32fc_t*)_this->fft_out, count, count);
|
// Take power of spectrum
|
||||||
|
volk_32fc_s32f_power_spectrum_32f(fftBuf, (lv_32fc_t*)_this->fft_out, count, count);
|
||||||
memcpy(fftBuf, &_this->tempFFT[half], half * sizeof(float));
|
|
||||||
memcpy(&fftBuf[half], _this->tempFFT, half * sizeof(float));
|
|
||||||
|
|
||||||
|
// Push back data
|
||||||
gui::waterfall.pushFFT();
|
gui::waterfall.pushFFT();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -619,6 +621,30 @@ void MainWindow::setFFTSize(int size) {
|
|||||||
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);
|
||||||
fftwPlan = fftwf_plan_dft_1d(fftSize, fft_in, fft_out, FFTW_FORWARD, FFTW_ESTIMATE);
|
fftwPlan = fftwf_plan_dft_1d(fftSize, fft_in, fft_out, FFTW_FORWARD, FFTW_ESTIMATE);
|
||||||
|
|
||||||
|
delete appliedWindow;
|
||||||
|
|
||||||
|
appliedWindow = new float[fftSize];
|
||||||
|
generateFFTWindow(selectedWindow, fftSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setFFTWindow(int win) {
|
||||||
|
std::lock_guard<std::mutex> lck(fft_mtx);
|
||||||
|
selectedWindow = win;
|
||||||
|
generateFFTWindow(selectedWindow, fftSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::generateFFTWindow(int win, int size) {
|
||||||
|
if (win == FFT_WINDOW_RECTANGULAR) {
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
appliedWindow[i] = (i%2) ? 1 : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (win == FFT_WINDOW_BLACKMAN) {
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
appliedWindow[i] = ((i%2) ? dsp::window_function::blackman(i, size) : -dsp::window_function::blackman(i, size))*2;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWindow::isPlaying() {
|
bool MainWindow::isPlaying() {
|
||||||
|
@ -11,6 +11,12 @@
|
|||||||
|
|
||||||
#define WINDOW_FLAGS ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBackground
|
#define WINDOW_FLAGS ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBackground
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FFT_WINDOW_RECTANGULAR,
|
||||||
|
FFT_WINDOW_BLACKMAN,
|
||||||
|
_FFT_WINDOW_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
class MainWindow {
|
class MainWindow {
|
||||||
public:
|
public:
|
||||||
void init();
|
void init();
|
||||||
@ -18,6 +24,7 @@ public:
|
|||||||
void setViewBandwidthSlider(float bandwidth);
|
void setViewBandwidthSlider(float bandwidth);
|
||||||
bool sdrIsRunning();
|
bool sdrIsRunning();
|
||||||
void setFFTSize(int size);
|
void setFFTSize(int size);
|
||||||
|
void setFFTWindow(int win);
|
||||||
|
|
||||||
// TODO: Replace with it's own class
|
// TODO: Replace with it's own class
|
||||||
void setVFO(double freq);
|
void setVFO(double freq);
|
||||||
@ -27,6 +34,7 @@ public:
|
|||||||
bool lockWaterfallControls = false;
|
bool lockWaterfallControls = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void generateFFTWindow(int win, int size);
|
||||||
static void fftHandler(dsp::complex_t* samples, int count, void* ctx);
|
static void fftHandler(dsp::complex_t* samples, int count, void* ctx);
|
||||||
static void vfoAddedHandler(VFOManager::VFO* vfo, void* ctx);
|
static void vfoAddedHandler(VFOManager::VFO* vfo, void* ctx);
|
||||||
|
|
||||||
@ -35,8 +43,7 @@ private:
|
|||||||
std::mutex fft_mtx;
|
std::mutex fft_mtx;
|
||||||
fftwf_complex *fft_in, *fft_out;
|
fftwf_complex *fft_in, *fft_out;
|
||||||
fftwf_plan fftwPlan;
|
fftwf_plan fftwPlan;
|
||||||
float* tempFFT;
|
float* appliedWindow;
|
||||||
float* FFTdata;
|
|
||||||
|
|
||||||
// GUI Variables
|
// GUI Variables
|
||||||
bool firstMenuRender = true;
|
bool firstMenuRender = true;
|
||||||
@ -56,6 +63,7 @@ private:
|
|||||||
int tuningMode = tuner::TUNER_MODE_NORMAL;
|
int tuningMode = tuner::TUNER_MODE_NORMAL;
|
||||||
dsp::stream<dsp::complex_t> dummyStream;
|
dsp::stream<dsp::complex_t> dummyStream;
|
||||||
bool demoWindow = false;
|
bool demoWindow = false;
|
||||||
|
int selectedWindow = 0;
|
||||||
|
|
||||||
EventHandler<VFOManager::VFO*> vfoCreatedHandler;
|
EventHandler<VFOManager::VFO*> vfoCreatedHandler;
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ namespace displaymenu {
|
|||||||
std::vector<std::string> colorMapNames;
|
std::vector<std::string> colorMapNames;
|
||||||
std::string colorMapNamesTxt = "";
|
std::string colorMapNamesTxt = "";
|
||||||
std::string colorMapAuthor = "";
|
std::string colorMapAuthor = "";
|
||||||
|
int selectedWindow = 0;
|
||||||
|
|
||||||
const int FFTSizes[] = {
|
const int FFTSizes[] = {
|
||||||
65536,
|
65536,
|
||||||
@ -70,6 +71,8 @@ namespace displaymenu {
|
|||||||
}
|
}
|
||||||
gui::mainWindow.setFFTSize(FFTSizes[fftSizeId]);
|
gui::mainWindow.setFFTSize(FFTSizes[fftSizeId]);
|
||||||
|
|
||||||
|
selectedWindow = std::clamp<int>((int)core::configManager.conf["fftWindow"], 0, _FFT_WINDOW_COUNT-1);
|
||||||
|
gui::mainWindow.setFFTWindow(selectedWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(void* ctx) {
|
void draw(void* ctx) {
|
||||||
@ -99,13 +102,23 @@ namespace displaymenu {
|
|||||||
ImGui::Text("FFT Size");
|
ImGui::Text("FFT Size");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
|
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
|
||||||
if (ImGui::Combo("##test_fft_size", &fftSizeId, FFTSizesStr)) {
|
if (ImGui::Combo("##sdrpp_fft_size", &fftSizeId, FFTSizesStr)) {
|
||||||
gui::mainWindow.setFFTSize(FFTSizes[fftSizeId]);
|
gui::mainWindow.setFFTSize(FFTSizes[fftSizeId]);
|
||||||
core::configManager.aquire();
|
core::configManager.aquire();
|
||||||
core::configManager.conf["fftSize"] = FFTSizes[fftSizeId];
|
core::configManager.conf["fftSize"] = FFTSizes[fftSizeId];
|
||||||
core::configManager.release(true);
|
core::configManager.release(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::Text("FFT Window");
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
|
||||||
|
if (ImGui::Combo("##sdrpp_fft_window", &selectedWindow, "Rectangular\0Blackman\0")) {
|
||||||
|
gui::mainWindow.setFFTWindow(selectedWindow);
|
||||||
|
core::configManager.aquire();
|
||||||
|
core::configManager.conf["fftWindow"] = selectedWindow;
|
||||||
|
core::configManager.release(true);
|
||||||
|
}
|
||||||
|
|
||||||
if (colorMapNames.size() > 0) {
|
if (colorMapNames.size() > 0) {
|
||||||
ImGui::Text("Color Map");
|
ImGui::Text("Color Map");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
SDRPP_MOD_INFO {
|
SDRPP_MOD_INFO {
|
||||||
/* Name: */ "frequency_manager",
|
/* Name: */ "frequency_manager",
|
||||||
/* Description: */ "Frequency manager module for SDR++",
|
/* Description: */ "Frequency manager module for SDR++",
|
||||||
/* Author: */ "Ryzerth;zimm",
|
/* Author: */ "Ryzerth;Zimm",
|
||||||
/* Version: */ 0, 3, 0,
|
/* Version: */ 0, 3, 0,
|
||||||
/* Max instances */ 1
|
/* Max instances */ 1
|
||||||
};
|
};
|
||||||
@ -125,8 +125,9 @@ private:
|
|||||||
if (core::modComManager.interfaceExists(vfoName)) {
|
if (core::modComManager.interfaceExists(vfoName)) {
|
||||||
if (core::modComManager.getModuleName(vfoName) == "radio") {
|
if (core::modComManager.getModuleName(vfoName) == "radio") {
|
||||||
int mode = bm.mode;
|
int mode = bm.mode;
|
||||||
|
float bandwidth = bm.bandwidth;
|
||||||
core::modComManager.callInterface(vfoName, RADIO_IFACE_CMD_SET_MODE, &mode, NULL);
|
core::modComManager.callInterface(vfoName, RADIO_IFACE_CMD_SET_MODE, &mode, NULL);
|
||||||
// TODO: Set bandwidth as well
|
core::modComManager.callInterface(vfoName, RADIO_IFACE_CMD_SET_BANDWIDTH, &bandwidth, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tuner::tune(tuner::TUNER_MODE_NORMAL, vfoName, bm.frequency);
|
tuner::tune(tuner::TUNER_MODE_NORMAL, vfoName, bm.frequency);
|
||||||
@ -594,6 +595,9 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImGui::BeginTooltip();
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text(hoveredBookmarkName.c_str());
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::Text("Frequency: %s", freqToStr(hoveredBookmark.frequency).c_str());
|
||||||
ImGui::Text("Bandwidth: %s", freqToStr(hoveredBookmark.bandwidth).c_str());
|
ImGui::Text("Bandwidth: %s", freqToStr(hoveredBookmark.bandwidth).c_str());
|
||||||
ImGui::Text("Mode: %s", demodModeList[hoveredBookmark.mode]);
|
ImGui::Text("Mode: %s", demodModeList[hoveredBookmark.mode]);
|
||||||
ImGui::EndTooltip();
|
ImGui::EndTooltip();
|
||||||
|
@ -162,8 +162,8 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
void setBandwidth(float bandWidth, bool updateWaterfall = true) {
|
void setBandwidth(float bandWidth, bool updateWaterfall = true) {
|
||||||
|
bandWidth = std::clamp<float>(bandWidth, bwMin, bwMax);
|
||||||
bw = bandWidth;
|
bw = bandWidth;
|
||||||
_vfo->setBandwidth(bw, updateWaterfall);
|
_vfo->setBandwidth(bw, updateWaterfall);
|
||||||
float audioBW = std::min<float>(audioSampRate / 2.0f, bw / 2.0f);
|
float audioBW = std::min<float>(audioSampRate / 2.0f, bw / 2.0f);
|
||||||
@ -173,6 +173,7 @@ private:
|
|||||||
resamp.updateWindow(&win);
|
resamp.updateWindow(&win);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
void setSnapInterval(float snapInt) {
|
void setSnapInterval(float snapInt) {
|
||||||
snapInterval = snapInt;
|
snapInterval = snapInt;
|
||||||
_vfo->setSnapInterval(snapInterval);
|
_vfo->setSnapInterval(snapInterval);
|
||||||
|
@ -169,12 +169,13 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
void setBandwidth(float bandWidth, bool updateWaterfall = true) {
|
void setBandwidth(float bandWidth, bool updateWaterfall = true) {
|
||||||
|
bandWidth = std::clamp<float>(bandWidth, bwMin, bwMax);
|
||||||
bw = bandWidth;
|
bw = bandWidth;
|
||||||
_vfo->setBandwidth(bw, updateWaterfall);
|
_vfo->setBandwidth(bw, updateWaterfall);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
void setSnapInterval(float snapInt) {
|
void setSnapInterval(float snapInt) {
|
||||||
snapInterval = snapInt;
|
snapInterval = snapInt;
|
||||||
_vfo->setSnapInterval(snapInterval);
|
_vfo->setSnapInterval(snapInterval);
|
||||||
|
@ -162,12 +162,13 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
void setBandwidth(float bandWidth, bool updateWaterfall = true) {
|
void setBandwidth(float bandWidth, bool updateWaterfall = true) {
|
||||||
|
bandWidth = std::clamp<float>(bandWidth, bwMin, bwMax);
|
||||||
bw = bandWidth;
|
bw = bandWidth;
|
||||||
_vfo->setBandwidth(bw, updateWaterfall);
|
_vfo->setBandwidth(bw, updateWaterfall);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
void setSnapInterval(float snapInt) {
|
void setSnapInterval(float snapInt) {
|
||||||
snapInterval = snapInt;
|
snapInterval = snapInt;
|
||||||
_vfo->setSnapInterval(snapInterval);
|
_vfo->setSnapInterval(snapInterval);
|
||||||
|
@ -154,14 +154,15 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
void setBandwidth(float bandWidth, bool updateWaterfall = true) {
|
void setBandwidth(float bandWidth, bool updateWaterfall = true) {
|
||||||
|
bandWidth = std::clamp<float>(bandWidth, bwMin, bwMax);
|
||||||
bw = bandWidth;
|
bw = bandWidth;
|
||||||
_vfo->setBandwidth(bw, updateWaterfall);
|
_vfo->setBandwidth(bw, updateWaterfall);
|
||||||
demod.setDeviation(bw / 2.0f);
|
demod.setDeviation(bw / 2.0f);
|
||||||
setAudioSampleRate(audioSampRate);
|
setAudioSampleRate(audioSampRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
void setSnapInterval(float snapInt) {
|
void setSnapInterval(float snapInt) {
|
||||||
snapInterval = snapInt;
|
snapInterval = snapInt;
|
||||||
_vfo->setSnapInterval(snapInterval);
|
_vfo->setSnapInterval(snapInterval);
|
||||||
|
@ -161,8 +161,8 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
void setBandwidth(float bandWidth, bool updateWaterfall = true) {
|
void setBandwidth(float bandWidth, bool updateWaterfall = true) {
|
||||||
|
bandWidth = std::clamp<float>(bandWidth, bwMin, bwMax);
|
||||||
bw = bandWidth;
|
bw = bandWidth;
|
||||||
_vfo->setBandwidth(bw, updateWaterfall);
|
_vfo->setBandwidth(bw, updateWaterfall);
|
||||||
demod.setBandWidth(bw);
|
demod.setBandWidth(bw);
|
||||||
@ -173,6 +173,7 @@ private:
|
|||||||
resamp.updateWindow(&win);
|
resamp.updateWindow(&win);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
void setSnapInterval(float snapInt) {
|
void setSnapInterval(float snapInt) {
|
||||||
snapInterval = snapInt;
|
snapInterval = snapInt;
|
||||||
_vfo->setSnapInterval(snapInterval);
|
_vfo->setSnapInterval(snapInterval);
|
||||||
|
@ -174,6 +174,10 @@ private:
|
|||||||
int* _in = (int*)in;
|
int* _in = (int*)in;
|
||||||
if (*_in != _this->demodId) { _this->selectDemodById(*_in); }
|
if (*_in != _this->demodId) { _this->selectDemodById(*_in); }
|
||||||
}
|
}
|
||||||
|
else if (code == RADIO_IFACE_CMD_SET_BANDWIDTH) {
|
||||||
|
float* _in = (float*)in;
|
||||||
|
_this->currentDemod->setBandwidth(*_in, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void selectDemod(Demodulator* demod) {
|
void selectDemod(Demodulator* demod) {
|
||||||
|
@ -12,6 +12,7 @@ public:
|
|||||||
virtual VFOManager::VFO* getVFO() = 0;
|
virtual VFOManager::VFO* getVFO() = 0;
|
||||||
virtual void setAudioSampleRate(float sampleRate) = 0;
|
virtual void setAudioSampleRate(float sampleRate) = 0;
|
||||||
virtual float getAudioSampleRate() = 0;
|
virtual float getAudioSampleRate() = 0;
|
||||||
|
virtual void setBandwidth(float bandWidth, bool updateWaterfall = true) = 0;
|
||||||
virtual dsp::stream<dsp::stereo_t>* getOutput() = 0;
|
virtual dsp::stream<dsp::stereo_t>* getOutput() = 0;
|
||||||
virtual void showMenu() = 0;
|
virtual void showMenu() = 0;
|
||||||
};
|
};
|
@ -118,6 +118,10 @@ public:
|
|||||||
// TODO: Allow selection of the bandwidth
|
// TODO: Allow selection of the bandwidth
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setBandwidth(float bandWidth, bool updateWaterfall = true) {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setSnapInterval(float snapInt) {
|
void setSnapInterval(float snapInt) {
|
||||||
snapInterval = snapInt;
|
snapInterval = snapInt;
|
||||||
|
@ -161,8 +161,8 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
void setBandwidth(float bandWidth, bool updateWaterfall = true) {
|
void setBandwidth(float bandWidth, bool updateWaterfall = true) {
|
||||||
|
bandWidth = std::clamp<float>(bandWidth, bwMin, bwMax);
|
||||||
bw = bandWidth;
|
bw = bandWidth;
|
||||||
_vfo->setBandwidth(bw, updateWaterfall);
|
_vfo->setBandwidth(bw, updateWaterfall);
|
||||||
demod.setBandWidth(bw);
|
demod.setBandWidth(bw);
|
||||||
@ -173,6 +173,7 @@ private:
|
|||||||
resamp.updateWindow(&win);
|
resamp.updateWindow(&win);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
void setSnapInterval(float snapInt) {
|
void setSnapInterval(float snapInt) {
|
||||||
snapInterval = snapInt;
|
snapInterval = snapInt;
|
||||||
_vfo->setSnapInterval(snapInterval);
|
_vfo->setSnapInterval(snapInterval);
|
||||||
|
@ -192,13 +192,15 @@ public:
|
|||||||
_vfo->setSnapInterval(snapInterval);
|
_vfo->setSnapInterval(snapInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
void setBandwidth(float bandWidth, bool updateWaterfall = true) {
|
void setBandwidth(float bandWidth, bool updateWaterfall = true) {
|
||||||
|
bandWidth = std::clamp<float>(bandWidth, bwMin, bwMax);
|
||||||
bw = bandWidth;
|
bw = bandWidth;
|
||||||
_vfo->setBandwidth(bw, updateWaterfall);
|
_vfo->setBandwidth(bw, updateWaterfall);
|
||||||
demod.setDeviation(bw / 2.0f);
|
demod.setDeviation(bw / 2.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
const float bwMax = 250000;
|
const float bwMax = 250000;
|
||||||
const float bwMin = 50000;
|
const float bwMin = 50000;
|
||||||
const float bbSampRate = 250000;
|
const float bbSampRate = 250000;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# SDR++, The bloat-free SDR software
|
# SDR++, The bloat-free SDR software
|
||||||
|
|
||||||
![Screenshot](https://i.imgur.com/EFOqwQQ.png)
|
![Screenshot](https://i.imgur.com/Ter2MQJ.png)
|
||||||
SDR++ is a cross-platform and open source SDR software with the aim of being bloat free and simple to use.
|
SDR++ is a cross-platform and open source SDR software with the aim of being bloat free and simple to use.
|
||||||
|
|
||||||
![Build](https://github.com/AlexandreRouma/SDRPlusPlus/workflows/Build%20Binaries/badge.svg)
|
![Build](https://github.com/AlexandreRouma/SDRPlusPlus/workflows/Build%20Binaries/badge.svg)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user