mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-26 21:58:37 -05:00
Merge branch 'master' into audio_recording
This commit is contained in:
commit
9b1f7b828c
@ -943,7 +943,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;
|
||||
|
||||
@ -952,9 +951,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);
|
||||
|
@ -947,8 +947,12 @@ bool CubicSDR::areDevicesReady() {
|
||||
return devicesReady.load();
|
||||
}
|
||||
|
||||
void CubicSDR::notifyMainUIOfDeviceChange() {
|
||||
void CubicSDR::notifyMainUIOfDeviceChange(bool forceRefreshOfGains) {
|
||||
appframe->notifyDeviceChanged();
|
||||
|
||||
if (forceRefreshOfGains) {
|
||||
appframe->refreshGainUI();
|
||||
}
|
||||
}
|
||||
|
||||
bool CubicSDR::areDevicesEnumerating() {
|
||||
|
@ -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);
|
||||
|
@ -395,7 +395,6 @@ void SDRDevicesDialog::OnUseSelected( wxMouseEvent& event) {
|
||||
wxGetApp().setDeviceArgs(settingArgs);
|
||||
wxGetApp().setStreamArgs(streamArgs);
|
||||
wxGetApp().setDevice(dev,0);
|
||||
wxGetApp().notifyMainUIOfDeviceChange();
|
||||
Close();
|
||||
}
|
||||
event.Skip();
|
||||
@ -494,7 +493,7 @@ void SDRDevicesDialog::OnRefreshDevices( wxMouseEvent& /* event */) {
|
||||
|
||||
void SDRDevicesDialog::OnPropGridChanged( wxPropertyGridEvent& event ) {
|
||||
|
||||
if (editId && event.GetProperty() == devSettings["name"]) {
|
||||
if (event.GetProperty() == devSettings["name"]) {
|
||||
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId());
|
||||
|
||||
wxString devName = event.GetPropertyValue().GetString();
|
||||
@ -549,7 +548,7 @@ void SDRDevicesDialog::OnPropGridChanged( wxPropertyGridEvent& event ) {
|
||||
// nop
|
||||
}
|
||||
}
|
||||
else if (editId && dev) {
|
||||
else if (dev) {
|
||||
wxPGProperty *prop = event.GetProperty();
|
||||
//change value of RuntimeProps
|
||||
for (std::map<std::string, wxPGProperty *>::iterator rtp = runtimeProps.begin(); rtp != runtimeProps.end(); rtp++) {
|
||||
@ -569,14 +568,10 @@ void SDRDevicesDialog::OnPropGridChanged( wxPropertyGridEvent& event ) {
|
||||
if (dev->isActive()) {
|
||||
wxGetApp().getSDRThread()->writeSetting(rtp->first, settingValue);
|
||||
}
|
||||
|
||||
wxGetApp().notifyMainUIOfDeviceChange();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// general refresh.
|
||||
wxGetApp().notifyMainUIOfDeviceChange();
|
||||
}
|
||||
|
||||
void SDRDevicesDialog::OnPropGridFocus( wxFocusEvent& /* event */) {
|
||||
|
@ -32,7 +32,7 @@ protected:
|
||||
private:
|
||||
std::string name;
|
||||
float low, high, current;
|
||||
bool changed;
|
||||
bool changed = false;
|
||||
GLPanel bgPanel;
|
||||
GLPanel levelPanel;
|
||||
GLPanel highlightPanel;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -153,6 +153,7 @@ bool SDRThread::init() {
|
||||
settingChanged.erase(settingChanged.begin(), settingChanged.end());
|
||||
}
|
||||
|
||||
//apply settings.
|
||||
{ //enter scoped-lock
|
||||
std::lock_guard < std::mutex > lock(setting_busy);
|
||||
|
||||
@ -174,6 +175,9 @@ bool SDRThread::init() {
|
||||
|
||||
wxGetApp().sdrThreadNotify(SDRThread::SDR_THREAD_INITIALIZED, std::string("Device Initialized."));
|
||||
|
||||
//rebuild menu now that settings are really been applied.
|
||||
wxGetApp().notifyMainUIOfDeviceChange(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -486,15 +490,14 @@ void SDRThread::updateSettings() {
|
||||
if (!agc_mode.load()) {
|
||||
updateGains();
|
||||
|
||||
//re-apply the saved configuration gains:
|
||||
DeviceConfig *devConfig = deviceConfig.load();
|
||||
ConfigGains gains = devConfig->getGains();
|
||||
|
||||
if (gains.size()) {
|
||||
for (ConfigGains::iterator gain_i = gains.begin(); gain_i != gains.end(); gain_i++) {
|
||||
setGain(gain_i->first, gain_i->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
doUpdate = true;
|
||||
}
|
||||
|
||||
@ -544,7 +547,7 @@ void SDRThread::run() {
|
||||
|
||||
SDRDeviceInfo *activeDev = deviceInfo.load();
|
||||
|
||||
if (activeDev != NULL) {
|
||||
if (activeDev != nullptr) {
|
||||
std::cout << "device init()" << std::endl;
|
||||
if (!init()) {
|
||||
std::cout << "SDR Thread stream init error." << std::endl;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "CubicSDRDefs.h"
|
||||
#include "AppFrame.h"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
wxBEGIN_EVENT_TABLE(GainCanvas, wxGLCanvas) EVT_PAINT(GainCanvas::OnPaint)
|
||||
EVT_IDLE(GainCanvas::OnIdle)
|
||||
@ -41,6 +42,8 @@ GainCanvas::GainCanvas(wxWindow *parent, std::vector<int> dispAttrs) :
|
||||
startPos = spacing/2.0;
|
||||
barHeight = 0.8f;
|
||||
refreshCounter = 0;
|
||||
|
||||
userGainAsChanged = false;
|
||||
}
|
||||
|
||||
GainCanvas::~GainCanvas() {
|
||||
@ -70,12 +73,39 @@ void GainCanvas::OnIdle(wxIdleEvent &event) {
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
bool areGainsChangedHere = false;
|
||||
|
||||
for (auto gi : gainPanels) {
|
||||
if (gi->getChanged()) {
|
||||
wxGetApp().setGain(gi->getName(), gi->getValue());
|
||||
areGainsChangedHere = true;
|
||||
// Gain only displays integer gain values, so set the applied gain
|
||||
//value to exactly that.
|
||||
wxGetApp().setGain(gi->getName(), (int)(gi->getValue()));
|
||||
//A gain may be exposed as setting also so assure refresh of the menu also.
|
||||
wxGetApp().notifyMainUIOfDeviceChange(false); //do not rebuild the gain UI
|
||||
|
||||
gi->setChanged(false);
|
||||
}
|
||||
}
|
||||
|
||||
//User input has changed the gain, so schedule an update of values
|
||||
//in 150ms in the future, else the device may not have taken the value into account.
|
||||
if (areGainsChangedHere) {
|
||||
userGainAsChanged = true;
|
||||
userGainAsChangedDelayTimer.start();
|
||||
}
|
||||
else {
|
||||
userGainAsChangedDelayTimer.update();
|
||||
|
||||
if (!userGainAsChanged || (userGainAsChanged && userGainAsChangedDelayTimer.getMilliseconds() > 150)) {
|
||||
|
||||
if (updateGainValues()) {
|
||||
Refresh();
|
||||
}
|
||||
|
||||
userGainAsChanged = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GainCanvas::SetLevel() {
|
||||
@ -87,7 +117,6 @@ void GainCanvas::SetLevel() {
|
||||
|
||||
gi->setValue(value);
|
||||
gi->setChanged(true);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -167,13 +196,12 @@ void GainCanvas::OnMouseEnterWindow(wxMouseEvent& event) {
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GainCanvas::setHelpTip(std::string tip) {
|
||||
helpTip = tip;
|
||||
}
|
||||
|
||||
void GainCanvas::updateGainUI() {
|
||||
|
||||
SDRDeviceInfo *devInfo = wxGetApp().getDevice();
|
||||
|
||||
//possible if we 'Refresh Devices' then devInfo becomes null
|
||||
@ -184,7 +212,12 @@ void GainCanvas::updateGainUI() {
|
||||
|
||||
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(devInfo->getDeviceId());
|
||||
|
||||
//read the gains from the device.
|
||||
//This may be wrong because the device is not started, or has yet
|
||||
//to take into account a user gain change. Doesn't matter,
|
||||
//UpdateGainValues() takes cares of updating the true value realtime.
|
||||
gains = devInfo->getGains(SOAPY_SDR_RX, 0);
|
||||
|
||||
SDRRangeMap::iterator gi;
|
||||
|
||||
numGains = gains.size();
|
||||
@ -221,6 +254,63 @@ 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.
|
||||
//also, do not attempt an update with the device is not started.
|
||||
if (devInfo == nullptr || !devInfo->isActive()) {
|
||||
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, round it
|
||||
float actualRoundedGain = (float)std::round(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 ((int)actualRoundedGain != (int)(gainPanels[panelIndex]->getValue())) {
|
||||
|
||||
gainPanels[panelIndex]->setValue(actualRoundedGain);
|
||||
|
||||
//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, actualRoundedGain);
|
||||
|
||||
isRefreshNeeded = true;
|
||||
}
|
||||
} //end if no external change pending.
|
||||
|
||||
panelIndex++;
|
||||
}
|
||||
|
||||
return isRefreshNeeded;
|
||||
}
|
||||
|
||||
void GainCanvas::setThemeColors() {
|
||||
RGBA4f c1, c2;
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <atomic>
|
||||
|
||||
#include "InteractiveCanvas.h"
|
||||
#include "MouseTracker.h"
|
||||
@ -28,6 +29,10 @@ public:
|
||||
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);
|
||||
|
||||
@ -50,6 +55,9 @@ private:
|
||||
float spacing, barWidth, startPos, barHeight, numGains;
|
||||
int refreshCounter;
|
||||
wxSize clientSize;
|
||||
|
||||
std::atomic_bool userGainAsChanged;
|
||||
Timer userGainAsChangedDelayTimer;
|
||||
//
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user