Assure Gain control <==> Settings menu synchronization in case of mutually depdendent updates

This commit is contained in:
vsonnier 2017-11-18 22:38:05 +01:00
parent 6dc9b86855
commit e44af72b00
8 changed files with 108 additions and 12 deletions

View File

@ -941,7 +941,6 @@ void AppFrame::updateDeviceParams() {
newSampleRateMenu->AppendSeparator();
sampleRateMenuItems[wxID_BANDWIDTH_MANUAL_DIALOG] = newSampleRateMenu->Append(wxID_BANDWIDTH_MANUAL_DIALOG, wxT("Manual Entry..."));
menuBar->Replace(2, newSampleRateMenu, wxT("Sample &Rate"));
sampleRateMenu = newSampleRateMenu;
@ -950,9 +949,6 @@ void AppFrame::updateDeviceParams() {
gainSizerItem->Show(true);
gainSizerItem->SetMinSize(devInfo->getSoapyDevice()->listGains(SOAPY_SDR_RX,0).size()*50,0);
demodTray->Layout();
gainCanvas->updateGainUI();
gainCanvas->Refresh();
gainCanvas->Refresh();
} else {
gainSpacerItem->Show(false);
gainSizerItem->Show(false);

View File

@ -944,8 +944,12 @@ bool CubicSDR::areDevicesReady() {
return devicesReady.load();
}
void CubicSDR::notifyMainUIOfDeviceChange() {
void CubicSDR::notifyMainUIOfDeviceChange(bool forceRefreshOfGains) {
appframe->notifyDeviceChanged();
if (forceRefreshOfGains) {
appframe->refreshGainUI();
}
}
bool CubicSDR::areDevicesEnumerating() {

View File

@ -143,7 +143,7 @@ public:
bool areModulesMissing();
std::string getNotification();
void notifyMainUIOfDeviceChange();
void notifyMainUIOfDeviceChange(bool forceRefreshOfGains = false);
void addRemote(std::string remoteAddr);
void removeRemote(std::string remoteAddr);

View File

@ -395,7 +395,8 @@ void SDRDevicesDialog::OnUseSelected( wxMouseEvent& event) {
wxGetApp().setDeviceArgs(settingArgs);
wxGetApp().setStreamArgs(streamArgs);
wxGetApp().setDevice(dev,0);
wxGetApp().notifyMainUIOfDeviceChange();
wxGetApp().notifyMainUIOfDeviceChange(true);
Refresh();
Close();
}
event.Skip();
@ -570,13 +571,13 @@ void SDRDevicesDialog::OnPropGridChanged( wxPropertyGridEvent& event ) {
wxGetApp().getSDRThread()->writeSetting(rtp->first, settingValue);
}
wxGetApp().notifyMainUIOfDeviceChange();
wxGetApp().notifyMainUIOfDeviceChange(true);
return;
}
}
}
// general refresh.
wxGetApp().notifyMainUIOfDeviceChange();
wxGetApp().notifyMainUIOfDeviceChange(true);
}
void SDRDevicesDialog::OnPropGridFocus( wxFocusEvent& /* event */) {

View File

@ -269,3 +269,24 @@ SDRRangeMap SDRDeviceInfo::getGains(int direction, size_t channel) {
return gainMap;
}
//read the current gain of name gainName (must exit in getGains(), else return 0)
//in the device.
double SDRDeviceInfo::getCurrentGain(int direction, size_t channel, const std::string& gainName) {
SoapySDR::Device *dev = getSoapyDevice();
if (dev) {
std::vector<std::string> gainNames = dev->listGains(direction, channel);
auto itFoundName = std::find(gainNames.begin(), gainNames.end(), gainName);
if (itFoundName != gainNames.end()) {
return dev->getGain(direction, channel, gainName);
}
}
return 0.0;
}

View File

@ -92,6 +92,10 @@ public:
SDRRangeMap getGains(int direction, size_t channel);
//read the current gain of name gainName (must exist in getGains(), else return 0)
//in the device.
double getCurrentGain(int direction, size_t channel, const std::string& gainName);
private:
int index = 0;
std::string name, serial, product, manufacturer, tuner;

View File

@ -69,13 +69,25 @@ void GainCanvas::OnIdle(wxIdleEvent &event) {
} else {
event.Skip();
}
bool areGainsChangedHere = false;
for (auto gi : gainPanels) {
if (gi->getChanged()) {
areGainsChangedHere = true;
wxGetApp().setGain(gi->getName(), gi->getValue());
//A gain may be exposed as setting also so assure refresh of the menu also.
wxGetApp().notifyMainUIOfDeviceChange(false); //do not piggyback to us...
gi->setChanged(false);
}
}
if (!areGainsChangedHere) {
if (updateGainValues()) {
Refresh();
}
}
}
void GainCanvas::SetLevel() {
@ -167,8 +179,6 @@ void GainCanvas::OnMouseEnterWindow(wxMouseEvent& event) {
#endif
}
void GainCanvas::setHelpTip(std::string tip) {
helpTip = tip;
}
@ -221,6 +231,62 @@ void GainCanvas::updateGainUI() {
setThemeColors();
}
// call this to refresh the gain values only, not the whole UI.
bool GainCanvas::updateGainValues() {
bool isRefreshNeeded = false;
SDRDeviceInfo *devInfo = wxGetApp().getDevice();
//possible if we 'Refresh Devices' then devInfo becomes null
//until a new device is selected.
if (devInfo == nullptr) {
return false;
}
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(devInfo->getDeviceId());
gains = devInfo->getGains(SOAPY_SDR_RX, 0);
SDRRangeMap::iterator gi;
size_t numGainsToRefresh = std::min(gains.size(), gainPanels.size());
size_t panelIndex = 0;
//actually the order of gains iteration should be constant because map of string,
//and gainPanels were built in that order in updateGainUI()
for (auto gi : gains) {
if (panelIndex >= numGainsToRefresh) {
break;
}
// do not update if a change is already pending.
if (!gainPanels[panelIndex]->getChanged()) {
//read the actual gain from the device.
float actualGain = (float)devInfo->getCurrentGain(SOAPY_SDR_RX, 0, gi.first);
//do nothing if the difference is less than 1.0, since the panel do not show it anyway.
if (std::abs(actualGain - gainPanels[panelIndex]->getValue()) > 1.0) {
gainPanels[panelIndex]->setValue(actualGain);
//update the config with this value :
//a consequence of such updates is that the use setting
// is overriden by the current one in AGC mode.
//TODO: if it not desirable, do not update in AGC mode.
devConfig->setGain(gi.first, actualGain);
isRefreshNeeded = true;
}
} //end if no external change pending.
panelIndex++;
}
return isRefreshNeeded;
}
void GainCanvas::setThemeColors() {
RGBA4f c1, c2;

View File

@ -25,9 +25,13 @@ public:
void setHelpTip(std::string tip);
void updateGainUI();
void setThemeColors();
void setThemeColors();
private:
// call this to refresh the gain values only, return true if refresh is needed
bool updateGainValues();
void OnPaint(wxPaintEvent& event);
void OnIdle(wxIdleEvent &event);