a LOT of new stuff
This commit is contained in:
@@ -9,6 +9,7 @@ fftwf_plan p;
|
||||
float* tempData;
|
||||
float* uiGains;
|
||||
char buf[1024];
|
||||
ImFont* bigFont;
|
||||
|
||||
int fftSize = 8192 * 8;
|
||||
|
||||
@@ -37,14 +38,68 @@ void fftHandler(dsp::complex_t* samples) {
|
||||
}
|
||||
|
||||
dsp::NullSink sink;
|
||||
int devId = 0;
|
||||
int srId = 0;
|
||||
watcher<int> bandplanId(0, true);
|
||||
watcher<long> freq(90500000L);
|
||||
int demod = 1;
|
||||
watcher<float> vfoFreq(92000000.0f);
|
||||
float dummyVolume = 1.0f;
|
||||
float* volume = &dummyVolume;
|
||||
float fftMin = -70.0f;
|
||||
float fftMax = 0.0f;
|
||||
watcher<float> offset(0.0f, true);
|
||||
watcher<float> bw(8000000.0f, true);
|
||||
int sampleRate = 8000000;
|
||||
bool playing = false;
|
||||
watcher<bool> dcbias(false, false);
|
||||
watcher<bool> bandPlanEnabled(true, false);
|
||||
bool showCredits = false;
|
||||
std::string audioStreamName = "";
|
||||
std::string sourceName = "";
|
||||
|
||||
void saveCurrentSource() {
|
||||
int i = 0;
|
||||
for (std::string gainName : soapy.gainList) {
|
||||
config::config["sourceSettings"][sourceName]["gains"][gainName] = uiGains[i];
|
||||
i++;
|
||||
}
|
||||
config::config["sourceSettings"][sourceName]["sampleRate"] = soapy.sampleRates[srId];
|
||||
}
|
||||
|
||||
void loadSourceConfig(std::string name) {
|
||||
json sourceSettings = config::config["sourceSettings"][name];
|
||||
|
||||
// Set sample rate
|
||||
|
||||
spdlog::warn("Type {0}", sourceSettings.contains("sampleRate"));
|
||||
|
||||
sampleRate = sourceSettings["sampleRate"];
|
||||
|
||||
sigPath.setSampleRate(sampleRate);
|
||||
soapy.setSampleRate(sampleRate);
|
||||
auto _srIt = std::find(soapy.sampleRates.begin(), soapy.sampleRates.end(), sampleRate);
|
||||
srId = std::distance(soapy.sampleRates.begin(), _srIt);
|
||||
spdlog::warn("sr {0}", srId);
|
||||
|
||||
// Set gains
|
||||
delete uiGains;
|
||||
uiGains = new float[soapy.gainList.size()];
|
||||
int i = 0;
|
||||
for (std::string gainName : soapy.gainList) {
|
||||
uiGains[i] = sourceSettings["gains"][gainName];
|
||||
soapy.setGain(i, uiGains[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
// Update GUI
|
||||
wtf.setBandwidth(sampleRate);
|
||||
wtf.setViewBandwidth(sampleRate);
|
||||
bw.val = sampleRate;
|
||||
}
|
||||
|
||||
void windowInit() {
|
||||
int sampleRate = 8000000;
|
||||
wtf.setBandwidth(sampleRate);
|
||||
wtf.setCenterFrequency(90500000);
|
||||
|
||||
fSel.init();
|
||||
fSel.setFrequency(90500000);
|
||||
|
||||
fft_in = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fftSize);
|
||||
fft_out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fftSize);
|
||||
@@ -60,24 +115,92 @@ void windowInit() {
|
||||
spdlog::info("Loading modules");
|
||||
mod::initAPI(&wtf);
|
||||
mod::loadFromList("module_list.json");
|
||||
}
|
||||
|
||||
watcher<int> devId(0, true);
|
||||
watcher<int> srId(0, true);
|
||||
watcher<int> bandplanId(0, true);
|
||||
watcher<long> freq(90500000L);
|
||||
int demod = 1;
|
||||
watcher<float> vfoFreq(92000000.0f);
|
||||
float dummyVolume = 1.0f;
|
||||
float* volume = &dummyVolume;
|
||||
float fftMin = -70.0f;
|
||||
float fftMax = 0.0f;
|
||||
watcher<float> offset(0.0f, true);
|
||||
watcher<float> bw(8000000.0f, true);
|
||||
int sampleRate = 1000000;
|
||||
bool playing = false;
|
||||
watcher<bool> dcbias(false, false);
|
||||
watcher<bool> bandPlanEnabled(true, false);
|
||||
bigFont = ImGui::GetIO().Fonts->AddFontFromFileTTF("res/fonts/Roboto-Medium.ttf", 128.0f);
|
||||
|
||||
// Load last source configuration
|
||||
uint64_t frequency = config::config["frequency"];
|
||||
sourceName = config::config["source"];
|
||||
auto _sourceIt = std::find(soapy.devNameList.begin(), soapy.devNameList.end(), sourceName);
|
||||
if (_sourceIt != soapy.devNameList.end() && config::config["sourceSettings"].contains(sourceName)) {
|
||||
json sourceSettings = config::config["sourceSettings"][sourceName];
|
||||
devId = std::distance(soapy.devNameList.begin(), _sourceIt);
|
||||
soapy.setDevice(soapy.devList[devId]);
|
||||
loadSourceConfig(sourceName);
|
||||
}
|
||||
else {
|
||||
int i = 0;
|
||||
bool settingsFound = false;
|
||||
for (std::string devName : soapy.devNameList) {
|
||||
if (config::config["sourceSettings"].contains(devName)) {
|
||||
sourceName = devName;
|
||||
settingsFound = true;
|
||||
devId = i;
|
||||
soapy.setDevice(soapy.devList[i]);
|
||||
loadSourceConfig(sourceName);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (!settingsFound) {
|
||||
sampleRate = soapy.getSampleRate();
|
||||
}
|
||||
// Search for the first source in the list to have a config
|
||||
// If no pre-defined source, selected default device
|
||||
}
|
||||
|
||||
// Load last band plan configuration
|
||||
|
||||
// TODO: Save/load config for audio streams + window size/fullscreen
|
||||
|
||||
|
||||
// Update UI settings
|
||||
fftMin = config::config["min"];
|
||||
fftMax = config::config["max"];
|
||||
wtf.setFFTMin(fftMin);
|
||||
wtf.setWaterfallMin(fftMin);
|
||||
wtf.setFFTMax(fftMax);
|
||||
wtf.setWaterfallMax(fftMax);
|
||||
|
||||
bandPlanEnabled.val = config::config["bandPlanEnabled"];
|
||||
bandPlanEnabled.markAsChanged();
|
||||
|
||||
std::string bandPlanName = config::config["bandPlan"];
|
||||
auto _bandplanIt = bandplan::bandplans.find(bandPlanName);
|
||||
if (_bandplanIt != bandplan::bandplans.end()) {
|
||||
bandplanId.val = std::distance(bandplan::bandplans.begin(), bandplan::bandplans.find(bandPlanName));
|
||||
spdlog::warn("{0} => {1}", bandplanId.val, bandPlanName);
|
||||
|
||||
if (bandPlanEnabled.val) {
|
||||
wtf.bandplan = &bandplan::bandplans[bandPlanName];
|
||||
}
|
||||
else {
|
||||
wtf.bandplan = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
bandplanId.val = 0;
|
||||
}
|
||||
bandplanId.markAsChanged();
|
||||
|
||||
|
||||
fSel.setFrequency(frequency);
|
||||
fSel.frequencyChanged = false;
|
||||
soapy.setFrequency(frequency);
|
||||
wtf.setCenterFrequency(frequency);
|
||||
wtf.setBandwidth(sampleRate);
|
||||
wtf.setViewBandwidth(sampleRate);
|
||||
bw.val = sampleRate;
|
||||
wtf.vfoFreqChanged = false;
|
||||
wtf.centerFreqMoved = false;
|
||||
wtf.selectFirstVFO();
|
||||
|
||||
|
||||
audioStreamName = audio::getNameFromVFO(wtf.selectedVFO);
|
||||
if (audioStreamName != "") {
|
||||
volume = &audio::streams[audioStreamName]->volume;
|
||||
}
|
||||
}
|
||||
|
||||
void setVFO(float freq) {
|
||||
ImGui::WaterfallVFO* vfo = wtf.vfos[wtf.selectedVFO];
|
||||
@@ -165,14 +288,15 @@ void setVFO(float freq) {
|
||||
}
|
||||
|
||||
void drawWindow() {
|
||||
if (wtf.selectedVFO == "" && wtf.vfos.size() > 0) {
|
||||
wtf.selectFirstVFO();
|
||||
}
|
||||
ImGui::Begin("Main", NULL, WINDOW_FLAGS);
|
||||
|
||||
ImGui::WaterfallVFO* vfo = wtf.vfos[wtf.selectedVFO];
|
||||
|
||||
if (vfo->centerOffsetChanged) {
|
||||
fSel.setFrequency(wtf.getCenterFrequency() + vfo->generalOffset);
|
||||
fSel.frequencyChanged = false;
|
||||
config::config["frequency"] = fSel.frequency;
|
||||
config::configModified = true;
|
||||
}
|
||||
|
||||
vfoman::updateFromWaterfall();
|
||||
@@ -180,7 +304,14 @@ void drawWindow() {
|
||||
if (wtf.selectedVFOChanged) {
|
||||
wtf.selectedVFOChanged = false;
|
||||
fSel.setFrequency(vfo->generalOffset + wtf.getCenterFrequency());
|
||||
fSel.frequencyChanged = false;
|
||||
mod::broadcastEvent(mod::EVENT_SELECTED_VFO_CHANGED);
|
||||
audioStreamName = audio::getNameFromVFO(wtf.selectedVFO);
|
||||
if (audioStreamName != "") {
|
||||
volume = &audio::streams[audioStreamName]->volume;
|
||||
}
|
||||
config::config["frequency"] = fSel.frequency;
|
||||
config::configModified = true;
|
||||
}
|
||||
|
||||
if (fSel.frequencyChanged) {
|
||||
@@ -189,36 +320,16 @@ void drawWindow() {
|
||||
vfo->centerOffsetChanged = false;
|
||||
vfo->lowerOffsetChanged = false;
|
||||
vfo->upperOffsetChanged = false;
|
||||
config::config["frequency"] = fSel.frequency;
|
||||
config::configModified = true;
|
||||
}
|
||||
|
||||
if (wtf.centerFreqMoved) {
|
||||
wtf.centerFreqMoved = false;
|
||||
soapy.setFrequency(wtf.getCenterFrequency());
|
||||
fSel.setFrequency(wtf.getCenterFrequency() + vfo->generalOffset);
|
||||
}
|
||||
|
||||
if (devId.changed() && soapy.devList.size() > 0) {
|
||||
spdlog::info("Changed input device: {0}", devId.val);
|
||||
soapy.setDevice(soapy.devList[devId.val]);
|
||||
srId.markAsChanged();
|
||||
if (soapy.gainList.size() == 0) {
|
||||
return;
|
||||
}
|
||||
delete[] uiGains;
|
||||
uiGains = new float[soapy.gainList.size()];
|
||||
for (int i = 0; i < soapy.gainList.size(); i++) {
|
||||
uiGains[i] = soapy.currentGains[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (srId.changed() && soapy.devList.size() > 0) {
|
||||
spdlog::info("Changed sample rate: {0}", srId.val);
|
||||
sampleRate = soapy.sampleRates[srId.val];
|
||||
soapy.setSampleRate(sampleRate);
|
||||
wtf.setBandwidth(sampleRate);
|
||||
wtf.setViewBandwidth(sampleRate);
|
||||
sigPath.setSampleRate(sampleRate);
|
||||
bw.val = sampleRate;
|
||||
config::config["frequency"] = fSel.frequency;
|
||||
config::configModified = true;
|
||||
}
|
||||
|
||||
if (dcbias.changed()) {
|
||||
@@ -248,13 +359,13 @@ void drawWindow() {
|
||||
|
||||
// To Bar
|
||||
if (playing) {
|
||||
if (ImGui::ImageButton(icons::STOP_RAW, ImVec2(30, 30))) {
|
||||
if (ImGui::ImageButton(icons::STOP, ImVec2(40, 40), ImVec2(0, 0), ImVec2(1, 1), 0)) {
|
||||
soapy.stop();
|
||||
playing = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ImGui::ImageButton(icons::PLAY_RAW, ImVec2(30, 30)) && soapy.devList.size() > 0) {
|
||||
if (ImGui::ImageButton(icons::PLAY, ImVec2(40, 40), ImVec2(0, 0), ImVec2(1, 1), 0) && soapy.devList.size() > 0) {
|
||||
soapy.start();
|
||||
soapy.setFrequency(wtf.getCenterFrequency());
|
||||
playing = true;
|
||||
@@ -265,12 +376,31 @@ void drawWindow() {
|
||||
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 8);
|
||||
ImGui::SetNextItemWidth(200);
|
||||
ImGui::SliderFloat("##_2_", volume, 0.0f, 1.0f, "");
|
||||
if (ImGui::SliderFloat("##_2_", volume, 0.0f, 1.0f, "")) {
|
||||
if (audioStreamName != "") {
|
||||
audio::streams[audioStreamName]->audio->setVolume(*volume);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
fSel.draw();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
// Logo button
|
||||
ImGui::SetCursorPosX(ImGui::GetWindowSize().x - 48);
|
||||
ImGui::SetCursorPosY(10);
|
||||
if (ImGui::ImageButton(icons::LOGO, ImVec2(32, 32), ImVec2(0, 0), ImVec2(1, 1), 0)) {
|
||||
showCredits = true;
|
||||
}
|
||||
if (ImGui::IsMouseDown(ImGuiMouseButton_Left)) {
|
||||
showCredits = false;
|
||||
}
|
||||
if (ImGui::IsKeyPressed(GLFW_KEY_ESCAPE)) {
|
||||
showCredits = false;
|
||||
}
|
||||
|
||||
ImGui::Columns(3, "WindowColumns", false);
|
||||
ImVec2 winSize = ImGui::GetWindowSize();
|
||||
ImGui::SetColumnWidth(0, 300);
|
||||
@@ -279,88 +409,223 @@ void drawWindow() {
|
||||
|
||||
// Left Column
|
||||
ImGui::BeginChild("Left Column");
|
||||
float menuColumnWidth = ImGui::GetContentRegionAvailWidth();
|
||||
|
||||
if (ImGui::CollapsingHeader("Source")) {
|
||||
ImGui::PushItemWidth(ImGui::GetWindowSize().x);
|
||||
ImGui::Combo("##_0_", &devId.val, soapy.txtDevList.c_str());
|
||||
if (ImGui::CollapsingHeader("Source", ImGuiTreeNodeFlags_DefaultOpen)) {
|
||||
if (playing) { style::beginDisabled(); };
|
||||
|
||||
ImGui::PushItemWidth(menuColumnWidth);
|
||||
if (ImGui::Combo("##_0_", &devId, soapy.txtDevList.c_str())) {
|
||||
spdlog::info("Changed input device: {0}", devId);
|
||||
sourceName = soapy.devNameList[devId];
|
||||
soapy.setDevice(soapy.devList[devId]);
|
||||
if (soapy.gainList.size() == 0) {
|
||||
return;
|
||||
}
|
||||
delete[] uiGains;
|
||||
uiGains = new float[soapy.gainList.size()];
|
||||
for (int i = 0; i < soapy.gainList.size(); i++) {
|
||||
uiGains[i] = soapy.currentGains[i];
|
||||
}
|
||||
|
||||
if (config::config["sourceSettings"].contains(sourceName)) {
|
||||
loadSourceConfig(sourceName);
|
||||
}
|
||||
else {
|
||||
srId = 0;
|
||||
sampleRate = soapy.getSampleRate();
|
||||
bw.val = sampleRate;
|
||||
wtf.setBandwidth(sampleRate);
|
||||
wtf.setViewBandwidth(sampleRate);
|
||||
sigPath.setSampleRate(sampleRate);
|
||||
for (int i = 0; i < soapy.gainList.size(); i++) {
|
||||
uiGains[i] = soapy.gainRanges[i].minimum();
|
||||
}
|
||||
}
|
||||
setVFO(fSel.frequency);
|
||||
config::config["source"] = sourceName;
|
||||
config::configModified = true;
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
if (!playing) {
|
||||
ImGui::Combo("##_1_", &srId.val, soapy.txtSampleRateList.c_str());
|
||||
}
|
||||
else {
|
||||
ImGui::Text("%.0f Samples/s", soapy.sampleRates[srId.val]);
|
||||
if (ImGui::Combo("##_1_", &srId, soapy.txtSampleRateList.c_str())) {
|
||||
spdlog::info("Changed sample rate: {0}", srId);
|
||||
sampleRate = soapy.sampleRates[srId];
|
||||
soapy.setSampleRate(sampleRate);
|
||||
wtf.setBandwidth(sampleRate);
|
||||
wtf.setViewBandwidth(sampleRate);
|
||||
sigPath.setSampleRate(sampleRate);
|
||||
bw.val = sampleRate;
|
||||
|
||||
if (!config::config["sourceSettings"].contains(sourceName)) {
|
||||
saveCurrentSource();
|
||||
}
|
||||
config::config["sourceSettings"][sourceName]["sampleRate"] = sampleRate;
|
||||
config::configModified = true;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Refresh")) {
|
||||
if (ImGui::Button("Refresh", ImVec2(menuColumnWidth - ImGui::GetCursorPosX(), 0.0f))) {
|
||||
soapy.refresh();
|
||||
}
|
||||
|
||||
if (playing) { style::endDisabled(); };
|
||||
|
||||
float maxTextLength = 0;
|
||||
float txtLen = 0;
|
||||
char buf[100];
|
||||
|
||||
// Calculate the spacing
|
||||
for (int i = 0; i < soapy.gainList.size(); i++) {
|
||||
sprintf(buf, "%s gain", soapy.gainList[i].c_str());
|
||||
txtLen = ImGui::CalcTextSize(buf).x;
|
||||
if (txtLen > maxTextLength) {
|
||||
maxTextLength = txtLen;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < soapy.gainList.size(); i++) {
|
||||
ImGui::Text("%s gain", soapy.gainList[i].c_str());
|
||||
ImGui::SameLine();
|
||||
sprintf(buf, "##_gain_slide_%d_", i);
|
||||
ImGui::SliderFloat(buf, &uiGains[i], soapy.gainRanges[i].minimum(), soapy.gainRanges[i].maximum());
|
||||
|
||||
ImGui::SetCursorPosX(maxTextLength + 5);
|
||||
ImGui::PushItemWidth(menuColumnWidth - (maxTextLength + 5));
|
||||
if (ImGui::SliderFloat(buf, &uiGains[i], soapy.gainRanges[i].minimum(), soapy.gainRanges[i].maximum())) {
|
||||
soapy.setGain(i, uiGains[i]);
|
||||
config::config["sourceSettings"][sourceName]["gains"][soapy.gainList[i]] = uiGains[i];
|
||||
config::configModified = true;
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
if (uiGains[i] != soapy.currentGains[i]) {
|
||||
soapy.setGain(i, uiGains[i]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
}
|
||||
|
||||
for (int i = 0; i < modCount; i++) {
|
||||
if (ImGui::CollapsingHeader(mod::moduleNames[i].c_str())) {
|
||||
if (ImGui::CollapsingHeader(mod::moduleNames[i].c_str(), ImGuiTreeNodeFlags_DefaultOpen)) {
|
||||
mod = mod::modules[mod::moduleNames[i]];
|
||||
mod._DRAW_MENU_(mod.ctx);
|
||||
ImGui::Spacing();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::CollapsingHeader("Audio");
|
||||
|
||||
if (ImGui::CollapsingHeader("Band Plan")) {
|
||||
ImGui::PushItemWidth(ImGui::GetWindowSize().x);
|
||||
ImGui::Combo("##_4_", &bandplanId.val, bandplan::bandplanNameTxt.c_str());
|
||||
if (ImGui::CollapsingHeader("Audio", ImGuiTreeNodeFlags_DefaultOpen)) {
|
||||
int count = 0;
|
||||
int maxCount = audio::streams.size();
|
||||
for (auto const& [name, stream] : audio::streams) {
|
||||
int deviceId;
|
||||
float vol = 1.0f;
|
||||
deviceId = stream->audio->getDeviceId();
|
||||
|
||||
ImGui::SetCursorPosX((menuColumnWidth / 2.0f) - (ImGui::CalcTextSize(name.c_str()).x / 2.0f));
|
||||
ImGui::Text(name.c_str());
|
||||
|
||||
ImGui::PushItemWidth(menuColumnWidth);
|
||||
if (ImGui::Combo(("##_audio_dev_0_"+ name).c_str(), &stream->deviceId, stream->audio->devTxtList.c_str())) {
|
||||
audio::stopStream(name);
|
||||
audio::setAudioDevice(name, stream->deviceId, stream->audio->devices[deviceId].sampleRates[0]);
|
||||
audio::startStream(name);
|
||||
stream->sampleRateId = 0;
|
||||
}
|
||||
if (ImGui::Combo(("##_audio_sr_0_" + name).c_str(), &stream->sampleRateId, stream->audio->devices[deviceId].txtSampleRates.c_str())) {
|
||||
audio::stopStream(name);
|
||||
audio::setSampleRate(name, stream->audio->devices[deviceId].sampleRates[stream->sampleRateId]);
|
||||
audio::startStream(name);
|
||||
}
|
||||
if (ImGui::SliderFloat(("##_audio_vol_0_" + name).c_str(), &stream->volume, 0.0f, 1.0f, "")) {
|
||||
stream->audio->setVolume(stream->volume);
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
count++;
|
||||
if (count < maxCount) {
|
||||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
}
|
||||
ImGui::Spacing();
|
||||
}
|
||||
ImGui::Spacing();
|
||||
}
|
||||
|
||||
if (ImGui::CollapsingHeader("Band Plan", ImGuiTreeNodeFlags_DefaultOpen)) {
|
||||
ImGui::PushItemWidth(menuColumnWidth);
|
||||
if (ImGui::Combo("##_4_", &bandplanId.val, bandplan::bandplanNameTxt.c_str())) {
|
||||
config::config["bandPlan"] = bandplan::bandplanNames[bandplanId.val];
|
||||
config::configModified = true;
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::Checkbox("Enabled", &bandPlanEnabled.val);
|
||||
if (ImGui::Checkbox("Enabled", &bandPlanEnabled.val)) {
|
||||
config::config["bandPlanEnabled"] = bandPlanEnabled.val;
|
||||
config::configModified = true;
|
||||
}
|
||||
bandplan::BandPlan_t plan = bandplan::bandplans[bandplan::bandplanNames[bandplanId.val]];
|
||||
ImGui::Text("Country: %s (%s)", plan.countryName, plan.countryCode);
|
||||
ImGui::Text("Author: %s", plan.authorName);
|
||||
ImGui::Spacing();
|
||||
}
|
||||
|
||||
ImGui::CollapsingHeader("Display");
|
||||
if (ImGui::CollapsingHeader("Display")) {
|
||||
ImGui::Spacing();
|
||||
}
|
||||
|
||||
ImGui::CollapsingHeader("Recording");
|
||||
if (ImGui::CollapsingHeader("Recording")) {
|
||||
ImGui::Spacing();
|
||||
}
|
||||
|
||||
if(ImGui::CollapsingHeader("Debug")) {
|
||||
ImGui::Text("Frame time: %.3f ms/frame", 1000.0f / ImGui::GetIO().Framerate);
|
||||
ImGui::Text("Framerate: %.1f FPS", ImGui::GetIO().Framerate);
|
||||
ImGui::Text("Center Frequency: %.1f FPS", wtf.getCenterFrequency());
|
||||
ImGui::Text("Center Frequency: %.0f Hz", wtf.getCenterFrequency());
|
||||
|
||||
ImGui::Spacing();
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
// Right Column
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
|
||||
ImGui::NextColumn();
|
||||
|
||||
ImGui::BeginChild("Waterfall");
|
||||
|
||||
wtf.draw();
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::NextColumn();
|
||||
ImGui::BeginChild("WaterfallControls");
|
||||
|
||||
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0f) - (ImGui::CalcTextSize("Zoom").x / 2.0f));
|
||||
ImGui::Text("Zoom");
|
||||
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0f) - 10);
|
||||
ImGui::VSliderFloat("##_7_", ImVec2(20.0f, 150.0f), &bw.val, sampleRate, 1000.0f, "");
|
||||
|
||||
ImGui::NewLine();
|
||||
|
||||
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0f) - (ImGui::CalcTextSize("Max").x / 2.0f));
|
||||
ImGui::Text("Max");
|
||||
ImGui::VSliderFloat("##_8_", ImVec2(20.0f, 150.0f), &fftMax, 0.0f, -100.0f, "");
|
||||
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0f) - 10);
|
||||
if (ImGui::VSliderFloat("##_8_", ImVec2(20.0f, 150.0f), &fftMax, 0.0f, -100.0f, "")) {
|
||||
config::config["max"] = fftMax;
|
||||
config::configModified = true;
|
||||
}
|
||||
|
||||
ImGui::NewLine();
|
||||
|
||||
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0f) - (ImGui::CalcTextSize("Min").x / 2.0f));
|
||||
ImGui::Text("Min");
|
||||
ImGui::VSliderFloat("##_9_", ImVec2(20.0f, 150.0f), &fftMin, 0.0f, -100.0f, "");
|
||||
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0f) - 10);
|
||||
if (ImGui::VSliderFloat("##_9_", ImVec2(20.0f, 150.0f), &fftMin, 0.0f, -100.0f, "")) {
|
||||
config::config["min"] = fftMin;
|
||||
config::configModified = true;
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
if (bw.changed()) {
|
||||
wtf.setViewBandwidth(bw.val);
|
||||
@@ -371,6 +636,52 @@ void drawWindow() {
|
||||
wtf.setFFTMax(fftMax);
|
||||
wtf.setWaterfallMin(fftMin);
|
||||
wtf.setWaterfallMax(fftMax);
|
||||
|
||||
ImGui::End();
|
||||
|
||||
if (showCredits) {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20.0f, 20.0f));
|
||||
ImGui::OpenPopup("Credits");
|
||||
ImGui::BeginPopupModal("Credits", NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove);
|
||||
|
||||
ImGui::PushFont(bigFont);
|
||||
ImGui::Text("SDR++ ");
|
||||
ImGui::PopFont();
|
||||
ImGui::SameLine();
|
||||
ImGui::Image(icons::LOGO, ImVec2(128, 128));
|
||||
ImGui::Spacing();
|
||||
ImGui::Spacing();
|
||||
ImGui::Spacing();
|
||||
|
||||
ImGui::Text("This software is brought to you by\n\n");
|
||||
|
||||
ImGui::Columns(3, "CreditColumns", true);
|
||||
|
||||
// Contributors
|
||||
ImGui::Text("Contributors");
|
||||
ImGui::BulletText("Ryzerth (Creator)");
|
||||
ImGui::BulletText("aosync");
|
||||
ImGui::BulletText("Benjamin Kyd");
|
||||
ImGui::BulletText("Tobias Mädel");
|
||||
ImGui::BulletText("Raov");
|
||||
|
||||
// Libraries
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("Libraries");
|
||||
ImGui::BulletText("SoapySDR (PothosWare)");
|
||||
ImGui::BulletText("Dear ImGui (ocornut)");
|
||||
ImGui::BulletText("spdlog (gabime)");
|
||||
ImGui::BulletText("json (nlohmann)");
|
||||
ImGui::BulletText("portaudio (PA Comm.)");
|
||||
|
||||
// Patrons
|
||||
ImGui::NextColumn();
|
||||
ImGui::Text("Patrons");
|
||||
ImGui::BulletText("SignalsEverywhere");
|
||||
|
||||
ImGui::EndPopup();
|
||||
ImGui::PopStyleVar(1);
|
||||
}
|
||||
}
|
||||
|
||||
void bindVolumeVariable(float* vol) {
|
||||
|
||||
Reference in New Issue
Block a user