SoapySDR::ArgInfoList SoapyAudio::getStreamArgsInfo(const int direction, const size_t channel) const { SoapySDR::ArgInfoList streamArgs; SoapySDR::ArgInfo chanArg; chanArg.key = "chan"; chanArg.value = "mono_l"; chanArg.name = "Channel Setup"; chanArg.description = "Input channel configuration."; chanArg.type = SoapySDR::ArgInfo::STRING; std::vector<std::string> chanOpts; std::vector<std::string> chanOptNames; chanOpts.push_back("mono_l"); chanOptNames.push_back("Mono Left"); chanOpts.push_back("mono_r"); chanOptNames.push_back("Mono Right"); chanOpts.push_back("stereo_iq"); chanOptNames.push_back("Complex L/R = I/Q"); chanOpts.push_back("stereo_qi"); chanOptNames.push_back("Complex L/R = Q/I"); chanArg.options = chanOpts; chanArg.optionNames = chanOptNames; streamArgs.push_back(chanArg); return streamArgs; }
SoapySDR::ArgInfoList SoapyLMS7::getStreamArgsInfo(const int direction, const size_t channel) const { SoapySDR::ArgInfoList argInfos; //buffer length { SoapySDR::ArgInfo info; info.key = "bufferLength"; info.name = "Buffer Length"; info.description = "The buffer transfer size over the link."; info.units = "samples"; info.type = SoapySDR::ArgInfo::INT; argInfos.push_back(info); } //link format { SoapySDR::ArgInfo info; info.key = "linkFormat"; info.name = "Link Format"; info.description = "The format of the samples over the link."; info.type = SoapySDR::ArgInfo::STRING; info.options.push_back(SOAPY_SDR_CS16); info.options.push_back(SOAPY_SDR_CS12); info.optionNames.push_back("Complex int16"); info.optionNames.push_back("Complex int12"); argInfos.push_back(info); } return argInfos; }
void SDRDevicesDialog::OnUseSelected( wxMouseEvent& event) { if (dev != NULL) { SoapySDR::ArgInfoList args = dev->getSoapyDevice()->getSettingInfo(); SoapySDR::Kwargs settingArgs; SoapySDR::Kwargs streamArgs; for (SoapySDR::ArgInfo arg : args) { wxPGProperty *prop = runtimeProps[arg.key]; if (arg.type == SoapySDR::ArgInfo::STRING && arg.options.size()) { settingArgs[arg.key] = arg.options[prop->GetChoiceSelection()]; } else if (arg.type == SoapySDR::ArgInfo::BOOL) { settingArgs[arg.key] = (prop->GetValueAsString()=="True")?"true":"false"; } else { settingArgs[arg.key] = prop->GetValueAsString(); } } if (dev) { args = dev->getSoapyDevice()->getStreamArgsInfo(SOAPY_SDR_RX, 0); if (args.size()) { for (SoapySDR::ArgInfoList::const_iterator args_i = args.begin(); args_i != args.end(); args_i++) { SoapySDR::ArgInfo arg = (*args_i); wxPGProperty *prop = streamProps[arg.key]; if (arg.type == SoapySDR::ArgInfo::STRING && arg.options.size()) { streamArgs[arg.key] = arg.options[prop->GetChoiceSelection()]; } else if (arg.type == SoapySDR::ArgInfo::BOOL) { streamArgs[arg.key] = (prop->GetValueAsString()=="True")?"true":"false"; } else { streamArgs[arg.key] = prop->GetValueAsString(); } } } } AppConfig *cfg = wxGetApp().getConfig(); DeviceConfig *devConfig = cfg->getDevice(dev->getDeviceId()); devConfig->setSettings(settingArgs); devConfig->setStreamOpts(streamArgs); wxGetApp().setDeviceArgs(settingArgs); wxGetApp().setStreamArgs(streamArgs); wxGetApp().setDevice(dev,0); wxGetApp().notifyMainUIOfDeviceChange(); Close(); } event.Skip(); }
void SoapyRPCUnpacker::operator&(SoapySDR::ArgInfoList &value) { UNPACK_TYPE_HELPER(SOAPY_REMOTE_ARG_INFO_LIST); int size = 0; *this & size; value.resize(size); for (size_t i = 0; i < size_t(size); i++) *this & value[i]; }
SoapySDR::ArgInfoList SoapySDR::Device::getFrequencyArgsInfo(const int dir, const size_t chan) const { SoapySDR::ArgInfoList args; const std::vector<std::string> comps = this->listFrequencies(dir, chan); if (comps.size() < 2) return args; //no tuning options with single components //support offset tuning { SoapySDR::ArgInfo info; info.key = "OFFSET"; info.name = "LO Offset"; info.value = "0.0"; info.units = "Hz"; info.type = SoapySDR::ArgInfo::FLOAT; info.description = "Tune the LO with an offset and compensate with the baseband CORDIC."; SoapySDR::RangeList ranges = this->getFrequencyRange(dir, chan, comps.at(1)); if (not ranges.empty()) info.range = ranges.front(); args.push_back(info); } //every tunable component becomes an option for (size_t comp_i = 1; comp_i < comps.size(); comp_i++) { SoapySDR::ArgInfo info; info.key = comps[comp_i]; info.value = "DEFAULT"; info.units = "Hz"; info.type = SoapySDR::ArgInfo::FLOAT; info.description = "Specify a specific value for this component or IGNORE to skip tuning it."; info.options.push_back("DEFAULT"); info.optionNames.push_back("Default"); info.options.push_back("IGNORE"); info.optionNames.push_back("Ingore"); SoapySDR::RangeList ranges = this->getFrequencyRange(dir, chan, comps.at(comp_i)); if (not ranges.empty()) info.range = ranges.front(); args.push_back(info); } return args; }
void SDRDevicesDialog::OnSelectionChanged( wxTreeEvent& event ) { wxTreeItemId selId = devTree->GetSelection(); dev = getSelectedDevice(selId); props.erase(props.begin(), props.end()); if (dev) { m_propertyGrid->Clear(); m_propertyGrid->Append(new wxPropertyCategory("Run-time Settings")); SoapySDR::ArgInfoList::const_iterator args_i; SoapySDR::ArgInfoList args = dev->getSettingsArgInfo(); for (args_i = args.begin(); args_i != args.end(); args_i++) { SoapySDR::ArgInfo arg = (*args_i); props.push_back(addArgInfoProperty(m_propertyGrid, arg)); } if (dev->getRxChannel()) { args = dev->getRxChannel()->getStreamArgsInfo(); if (args.size()) { m_propertyGrid->Append(new wxPropertyCategory("Stream Settings")); for (args_i = args.begin(); args_i != args.end(); args_i++) { SoapySDR::ArgInfo arg = (*args_i); props.push_back(addArgInfoProperty(m_propertyGrid, arg)); } } } } event.Skip(); }
SoapySDR::ArgInfoList SoapySDRPlay::getSettingInfo(void) const { SoapySDR::ArgInfoList setArgs; // TODO: Settings SoapySDR::ArgInfo IFArg; IFArg.key="use_low_if"; IFArg.value="true"; IFArg.name = "Low IF (when available)"; IFArg.description = "Use low IF when available: 0.5MHz SR with 200 and 300khz BW, 1MHz SR with 600kHz BW, 2048kHz SR with 1536kHz BW"; IFArg.type=SoapySDR::ArgInfo::BOOL; setArgs.push_back(IFArg); SoapySDR::ArgInfo AIFArg; AIFArg.key="actual_IF"; AIFArg.value=ifMode; AIFArg.name = "Actual IF"; AIFArg.description = "Currently used IF frequency in kHz"; AIFArg.type=SoapySDR::ArgInfo::INT; setArgs.push_back(AIFArg); return setArgs; }
void SDRDevicesDialog::OnUseSelected( wxMouseEvent& event ) { wxTreeItemId selId = devTree->GetSelection(); dev = getSelectedDevice(selId); if (dev != NULL) { int i = 0; SoapySDR::ArgInfoList::const_iterator args_i; SoapySDR::ArgInfoList args = dev->getSettingsArgInfo(); SoapySDR::Kwargs settingArgs; SoapySDR::Kwargs streamArgs; for (args_i = args.begin(); args_i != args.end(); args_i++) { SoapySDR::ArgInfo arg = (*args_i); wxPGProperty *prop = props[i]; if (arg.type == SoapySDR::ArgInfo::STRING && arg.options.size()) { settingArgs[arg.key] = arg.options[prop->GetChoiceSelection()]; } else if (arg.type == SoapySDR::ArgInfo::BOOL) { settingArgs[arg.key] = (prop->GetValueAsString()=="True")?"true":"false"; } else { settingArgs[arg.key] = prop->GetValueAsString(); } i++; } if (dev->getRxChannel()) { args = dev->getRxChannel()->getStreamArgsInfo(); if (args.size()) { for (args_i = args.begin(); args_i != args.end(); args_i++) { SoapySDR::ArgInfo arg = (*args_i); wxPGProperty *prop = props[i]; if (arg.type == SoapySDR::ArgInfo::STRING && arg.options.size()) { streamArgs[arg.key] = arg.options[prop->GetChoiceSelection()]; } else if (arg.type == SoapySDR::ArgInfo::BOOL) { streamArgs[arg.key] = (prop->GetValueAsString()=="True")?"true":"false"; } else { streamArgs[arg.key] = prop->GetValueAsString(); } i++; } } } wxGetApp().setDeviceArgs(settingArgs); wxGetApp().setStreamArgs(streamArgs); wxGetApp().setDevice(dev); Close(); } }
void SDRThread::init() { //#warning Debug On // SoapySDR_setLogLevel(SOAPY_SDR_DEBUG); SDRDeviceInfo *devInfo = deviceInfo.load(); deviceConfig.store(wxGetApp().getConfig()->getDevice(devInfo->getDeviceId())); DeviceConfig *devConfig = deviceConfig.load(); ppm.store(devConfig->getPPM()); ppm_changed.store(true); std::string driverName = devInfo->getDriver(); offset = devConfig->getOffset(); SoapySDR::Kwargs args = devInfo->getDeviceArgs(); wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Initializing device.")); device = devInfo->getSoapyDevice(); SoapySDR::Kwargs currentStreamArgs = combineArgs(devInfo->getStreamArgs(),streamArgs); stream = device->setupStream(SOAPY_SDR_RX,"CF32", std::vector<size_t>(), currentStreamArgs); int streamMTU = device->getStreamMTU(stream); mtuElems.store(streamMTU); std::cout << "Stream MTU: " << mtuElems.load() << std::endl << std::flush; deviceInfo.load()->setStreamArgs(currentStreamArgs); deviceConfig.load()->setStreamOpts(currentStreamArgs); wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Activating stream.")); device->setSampleRate(SOAPY_SDR_RX,0,sampleRate.load()); device->setFrequency(SOAPY_SDR_RX,0,"RF",frequency - offset.load()); device->activateStream(stream); if (devInfo->hasCORR(SOAPY_SDR_RX, 0)) { hasPPM.store(true); device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm.load()); } else { hasPPM.store(false); } if (device->hasDCOffsetMode(SOAPY_SDR_RX, 0)) { hasHardwareDC.store(true); // wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Found hardware DC offset correction support, internal disabled.")); device->setDCOffsetMode(SOAPY_SDR_RX, 0, true); } else { hasHardwareDC.store(false); } device->setGainMode(SOAPY_SDR_RX,0,agc_mode.load()); numChannels.store(getOptimalChannelCount(sampleRate.load())); numElems.store(getOptimalElementCount(sampleRate.load(), 30)); if (!mtuElems.load()) { mtuElems.store(numElems.load()); } inpBuffer.data.resize(numElems.load()); overflowBuffer.data.resize(mtuElems.load()); buffs[0] = malloc(mtuElems.load() * 4 * sizeof(float)); numOverflow = 0; SoapySDR::ArgInfoList settingsInfo = device->getSettingInfo(); SoapySDR::ArgInfoList::const_iterator settings_i; if (!setting_value_changed.load()) { settings.erase(settings.begin(), settings.end()); settingChanged.erase(settingChanged.begin(), settingChanged.end()); } { //enter scoped-lock std::lock_guard < std::mutex > lock(setting_busy); for (settings_i = settingsInfo.begin(); settings_i != settingsInfo.end(); settings_i++) { SoapySDR::ArgInfo setting = (*settings_i); if ((settingChanged.find(setting.key) != settingChanged.end()) && (settings.find(setting.key) != settings.end())) { device->writeSetting(setting.key, settings[setting.key]); settingChanged[setting.key] = false; } else { settings[setting.key] = device->readSetting(setting.key); settingChanged[setting.key] = false; } } setting_value_changed.store(false); } //leave lock guard scope updateSettings(); wxGetApp().sdrThreadNotify(SDRThread::SDR_THREAD_INITIALIZED, std::string("Device Initialized.")); }
void SDRDevicesDialog::refreshDeviceProperties() { SDRDeviceInfo *selDev = getSelectedDevice(devTree->GetSelection()); if (selDev && selDev->isAvailable()) { dev = selDev; selId = devTree->GetSelection(); DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getName()); m_propertyGrid->Clear(); SoapySDR::Device *soapyDev = dev->getSoapyDevice(); SoapySDR::ArgInfoList args = soapyDev->getSettingInfo(); //A) General settings: name, offset, sample rate, agc, antennas (if > 1) m_propertyGrid->Append(new wxPropertyCategory("General Settings")); devSettings.clear(); //A-1) Name devSettings["name"] = m_propertyGrid->Append( new wxStringProperty("Name", wxPG_LABEL, devConfig->getDeviceName()) ); //A-2) Offset devSettings["offset"] = m_propertyGrid->Append( new wxIntProperty("Offset (KHz)", wxPG_LABEL, devConfig->getOffset() / 1000) ); //A-3) Antennas, is there are more than 1 RX antenna, else do not expose the setting. //get the saved setting const std::string& currentSetAntenna = devConfig->getAntennaName(); //compare to the list of existing antennas SoapySDR::ArgInfo antennasArg; std::vector<std::string> antennaOpts = selDev->getAntennaNames(SOAPY_SDR_RX, 0); //only do something if there is more than 1 antenna if (antennaOpts.size() > 1) { //by default, choose the first of the list. std::string antennaToSelect = antennaOpts.front(); auto found_i = std::find(antennaOpts.begin(), antennaOpts.end(), currentSetAntenna); if (found_i != antennaOpts.end()) { antennaToSelect = currentSetAntenna; } else { //erroneous antenna name, re-write device config with the first choice of teh list. devConfig->setAntennaName(antennaToSelect); } //build device settings for (std::string antenna : antennaOpts) { antennasArg.options.push_back(antenna); antennasArg.optionNames.push_back(antenna); } antennasArg.type = SoapySDR::ArgInfo::STRING; antennasArg.units = ""; antennasArg.name = "Antenna"; antennasArg.key = "antenna"; antennasArg.value = antennaToSelect; devSettings["antenna"] = addArgInfoProperty(m_propertyGrid, antennasArg); deviceArgs["antenna"] = antennasArg; } //end if more than 1 antenna else { devConfig->setAntennaName(""); } //A-4) Sample_rate: long currentSampleRate = wxGetApp().getSampleRate(); long deviceSampleRate = devConfig->getSampleRate(); if (!deviceSampleRate) { deviceSampleRate = selDev->getSampleRateNear(SOAPY_SDR_RX, 0, currentSampleRate); } SoapySDR::ArgInfo sampleRateArg; std::vector<long> rateOpts = selDev->getSampleRates(SOAPY_SDR_RX, 0); for (long rate : rateOpts) { sampleRateArg.options.push_back(std::to_string(rate)); sampleRateArg.optionNames.push_back(frequencyToStr(rate)); } sampleRateArg.type = SoapySDR::ArgInfo::STRING; sampleRateArg.units = "Hz"; sampleRateArg.name = "Sample Rate"; sampleRateArg.key = "sample_rate"; sampleRateArg.value = std::to_string(deviceSampleRate); devSettings["sample_rate"] = addArgInfoProperty(m_propertyGrid, sampleRateArg); deviceArgs["sample_rate"] = sampleRateArg; //B) Runtime Settings: runtimeArgs.clear(); runtimeProps.clear(); streamProps.clear(); if (args.size()) { m_propertyGrid->Append(new wxPropertyCategory("Run-time Settings")); for (SoapySDR::ArgInfoList::const_iterator args_i = args.begin(); args_i != args.end(); args_i++) { SoapySDR::ArgInfo arg = (*args_i); //We-reread the Device configuration, else we use the user settings. if (dev) { //Apply saved settings DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId()); arg.value = devConfig->getSetting(arg.key, soapyDev->readSetting(arg.key)); //use SoapyDevice data as fallback. } else { //re-read the SoapyDevice arg.value = soapyDev->readSetting(arg.key); } runtimeProps[arg.key] = addArgInfoProperty(m_propertyGrid, arg); runtimeArgs[arg.key] = arg; } } if (dev) { args = dev->getSoapyDevice()->getStreamArgsInfo(SOAPY_SDR_RX, 0); DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId()); ConfigSettings devStreamOpts = devConfig->getStreamOpts(); if (devStreamOpts.size()) { for (int j = 0, jMax = args.size(); j < jMax; j++) { if (devStreamOpts.find(args[j].key) != devStreamOpts.end()) { args[j].value = devStreamOpts[args[j].key]; } } } if (args.size()) { m_propertyGrid->Append(new wxPropertyCategory("Stream Settings")); for (SoapySDR::ArgInfo arg : args) { streamProps[arg.key] = addArgInfoProperty(m_propertyGrid, arg); } } } if (selDev->isManual()) { m_addRemoteButton->SetLabel("Remove"); removeId = selId; } else { m_addRemoteButton->SetLabel("Add"); removeId = nullptr; } } else if (selDev && !selDev->isAvailable() && selDev->isManual()) { m_propertyGrid->Clear(); devSettings.clear(); runtimeArgs.clear(); runtimeProps.clear(); streamProps.clear(); removeId = devTree->GetSelection(); dev = nullptr; selId = nullptr; editId = nullptr; m_addRemoteButton->SetLabel("Remove"); } else if (!selDev) { m_addRemoteButton->SetLabel("Add"); removeId = nullptr; } }
std::vector<SDRDeviceInfo *> *SDREnumerator::enumerate_devices(std::string remoteAddr, bool noInit) { if (SDREnumerator::devs[remoteAddr].size()) { return &SDREnumerator::devs[remoteAddr]; } if (noInit) { return NULL; } if (!soapy_initialized) { std::cout << "SoapySDR init.." << std::endl; std::cout << "\tAPI Version: v" << SoapySDR::getAPIVersion() << std::endl; std::cout << "\tABI Version: v" << SoapySDR::getABIVersion() << std::endl; std::cout << "\tInstall root: " << SoapySDR::getRootPath() << std::endl; std::cout << "\tLoading modules... " << std::endl; std::string userModPath = wxGetApp().getModulePath(); if (userModPath != "") { wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, "Loading SoapySDR modules from " + userModPath + ".."); std::vector<std::string> localMods = SoapySDR::listModules(userModPath); for (std::vector<std::string>::iterator mods_i = localMods.begin(); mods_i != localMods.end(); mods_i++) { wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, "Initializing user specified SoapySDR module " + (*mods_i) + ".."); std::cout << "Initializing user specified SoapySDR module " << (*mods_i) << ".." << std::endl; SoapySDR::loadModule(*mods_i); } } else { #ifdef BUNDLE_SOAPY_MODS bool localModPref = wxGetApp().getUseLocalMod(); if (localModPref) { wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, "Loading SoapySDR modules.."); std::cout << "Checking local system SoapySDR modules.." << std::flush; SoapySDR::loadModules(); } wxFileName exePath = wxFileName(wxStandardPaths::Get().GetExecutablePath()); std::vector<std::string> localMods = SoapySDR::listModules(exePath.GetPath().ToStdString() + "/modules/"); for (std::vector<std::string>::iterator mods_i = localMods.begin(); mods_i != localMods.end(); mods_i++) { wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, "Initializing bundled SoapySDR module " + (*mods_i) + ".."); std::cout << "Loading bundled SoapySDR module " << (*mods_i) << ".." << std::endl; SoapySDR::loadModule(*mods_i); } if (!localModPref) { wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, "Loading SoapySDR modules.."); std::cout << "Checking system SoapySDR modules.." << std::flush; SoapySDR::loadModules(); } #else wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, "Loading SoapySDR modules.."); SoapySDR::loadModules(); #endif } if (SDREnumerator::factories.size()) { SDREnumerator::factories.erase(SDREnumerator::factories.begin(), SDREnumerator::factories.end()); } std::cout << "\tAvailable factories..."; SoapySDR::FindFunctions factories = SoapySDR::Registry::listFindFunctions(); for (SoapySDR::FindFunctions::const_iterator it = factories.begin(); it != factories.end(); ++it) { if (it != factories.begin()) { std::cout << ", "; } std::cout << it->first; if (it->first == "remote") { has_remote = true; } SDREnumerator::factories.push_back(it->first); } if (factories.empty()) { std::cout << "No factories found!" << std::endl; } if ((factories.size() == 1) && factories.find("null") != factories.end()) { std::cout << "Just 'null' factory found." << std::endl; wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_FAILED, std::string("No modules available.")); } std::cout << std::endl; soapy_initialized = true; } modules = SoapySDR::listModules(); std::vector<SoapySDR::Kwargs> results; SoapySDR::Kwargs enumArgs; bool isRemote = false; if (remoteAddr.length()) { std::cout << "Enumerating remote address: " << remoteAddr << std::endl; enumArgs["driver"] = "remote"; enumArgs["remote"] = remoteAddr; isRemote = true; results = SoapySDR::Device::enumerate(enumArgs); } else { results = SoapySDR::Device::enumerate(); } int manualsIdx = results.size(); std::vector<std::string> manualParams; std::vector<bool> manualResult; if (manuals.size()) { for (std::vector<SDRManualDef>::const_iterator m_i = manuals.begin(); m_i != manuals.end(); m_i++) { std::vector<SoapySDR::Kwargs> manual_result; std::string strDevArgs = "driver="+m_i->factory+","+m_i->params; manualParams.push_back(m_i->params); wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Enumerating manual device '") + strDevArgs + "'.."); manual_result = SoapySDR::Device::enumerate(strDevArgs); if (manual_result.size()) { for (std::vector<SoapySDR::Kwargs>::const_iterator i = manual_result.begin(); i != manual_result.end(); i++) { results.push_back(*i); manualResult.push_back(true); } } else { SoapySDR::Kwargs failedEnum; failedEnum = argsStrToKwargs(strDevArgs); failedEnum["label"] = "Not Found ("+m_i->factory+")"; results.push_back(failedEnum); manualResult.push_back(false); } } } if (isRemote) { wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Opening remote server ") + remoteAddr + ".."); } for (size_t i = 0; i < results.size(); i++) { SDRDeviceInfo *dev = new SDRDeviceInfo(); SoapySDR::Kwargs deviceArgs = results[i]; for (SoapySDR::Kwargs::const_iterator it = deviceArgs.begin(); it != deviceArgs.end(); ++it) { std::cout << " " << it->first << " = " << it->second << std::endl; if (it->first == "driver") { dev->setDriver(it->second); } else if (it->first == "label" || it->first == "device") { dev->setName(it->second); } } if (deviceArgs.count("remote")) { isRemote = true; } else { isRemote = false; } dev->setRemote(isRemote); dev->setManual(i>=manualsIdx); if (i>=manualsIdx) { dev->setManualParams(manualParams[i-manualsIdx]); } std::cout << "Make device " << i << std::endl; if (i<manualsIdx || manualResult[i-manualsIdx]) try { SoapySDR::Device *device = SoapySDR::Device::make(deviceArgs); SoapySDR::Kwargs info = device->getHardwareInfo(); for (SoapySDR::Kwargs::const_iterator it = info.begin(); it != info.end(); ++it) { std::cout << " " << it->first << "=" << it->second << std::endl; if (it->first == "hardware") { dev->setHardware(it->second); } } if (isRemote) { wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, "Querying remote " + remoteAddr + " device #" + std::to_string(i) + ": " + dev-> getName()); } else { wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Querying device #") + std::to_string(i) + ": " + dev->getName()); } SoapySDR::ArgInfoList settingsInfo = device->getSettingInfo(); DeviceConfig *cfg = wxGetApp().getConfig()->getDevice(dev->getDeviceId()); ConfigSettings devSettings = cfg->getSettings(); if (devSettings.size()) { for (ConfigSettings::const_iterator set_i = devSettings.begin(); set_i != devSettings.end(); set_i++) { deviceArgs[set_i->first] = set_i->second; } for (int j = 0; j < settingsInfo.size(); j++) { if (deviceArgs.find(settingsInfo[j].key) != deviceArgs.end()) { settingsInfo[j].value = deviceArgs[settingsInfo[j].key]; } } } dev->setDeviceArgs(deviceArgs); dev->setSettingsInfo(settingsInfo); int numChan = device->getNumChannels(SOAPY_SDR_RX); for (int i = 0; i < numChan; i++) { SDRDeviceChannel *chan = new SDRDeviceChannel(); SoapySDR::RangeList rfRange = device->getFrequencyRange(SOAPY_SDR_RX, i); double rfMin = rfRange[0].minimum(); double rfMax = rfRange[rfRange.size()-1].maximum(); chan->setChannel(i); chan->setFullDuplex(device->getFullDuplex(SOAPY_SDR_RX, i)); chan->setRx(true); chan->setTx(false); chan->getRFRange().setLow(rfMin); chan->getRFRange().setHigh(rfMax); std::vector<std::string> freqs = device->listFrequencies(SOAPY_SDR_RX,i); if (std::find(freqs.begin(), freqs.end(), "CORR") != freqs.end()) { chan->setCORR(true); } else { chan->setCORR(false); } if (device->hasDCOffsetMode(SOAPY_SDR_RX, i)) { chan->setHardwareDC(true); } else { chan->setHardwareDC(false); } std::vector<double> rates = device->listSampleRates(SOAPY_SDR_RX, i); for (std::vector<double>::iterator i = rates.begin(); i != rates.end(); i++) { chan->getSampleRates().push_back((long)(*i)); } ConfigSettings devStreamOpts = cfg->getStreamOpts(); if (devStreamOpts.size()) { dev->setStreamArgs(devStreamOpts); } SoapySDR::ArgInfoList optArgs = device->getStreamArgsInfo(SOAPY_SDR_RX, i); if (devStreamOpts.size()) { for (int j = 0, jMax = optArgs.size(); j < jMax; j++) { if (devStreamOpts.find(optArgs[j].key) != devStreamOpts.end()) { optArgs[j].value = devStreamOpts[optArgs[j].key]; } } } chan->setStreamArgsInfo(optArgs); std::vector<std::string> gainNames = device->listGains(SOAPY_SDR_RX, i); for (std::vector<std::string>::iterator gname = gainNames.begin(); gname!= gainNames.end(); gname++) { chan->addGain((*gname),device->getGainRange(SOAPY_SDR_RX, i, (*gname))); } dev->addChannel(chan); } SoapySDR::Device::unmake(device); dev->setAvailable(true); } catch (const std::exception &ex) { std::cerr << "Error making device: " << ex.what() << std::endl; wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Error querying device #") + std::to_string(i)); dev->setAvailable(false); } else { dev->setAvailable(false); } std::cout << std::endl; SDREnumerator::devs[remoteAddr].push_back(dev); } if (SDREnumerator::devs[remoteAddr].empty()) { wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("No devices found!")); } std::cout << std::endl; return &SDREnumerator::devs[remoteAddr]; }
void SDRDevicesDialog::OnSelectionChanged( wxTreeEvent& event ) { SDRDeviceInfo *selDev = getSelectedDevice(devTree->GetSelection()); if (selDev && selDev->isAvailable()) { dev = selDev; selId = devTree->GetSelection(); DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getName()); m_propertyGrid->Clear(); SoapySDR::ArgInfoList args = dev->getSettingsArgInfo(); SoapySDR::ArgInfoList::const_iterator args_i; m_propertyGrid->Append(new wxPropertyCategory("General Settings")); devSettings.erase(devSettings.begin(),devSettings.end()); devSettings["name"] = m_propertyGrid->Append( new wxStringProperty("Name", wxPG_LABEL, devConfig->getDeviceName()) ); devSettings["offset"] = m_propertyGrid->Append( new wxIntProperty("Offset (Hz)", wxPG_LABEL, devConfig->getOffset()) ); props.erase(props.begin(), props.end()); if (args.size()) { m_propertyGrid->Append(new wxPropertyCategory("Run-time Settings")); for (args_i = args.begin(); args_i != args.end(); args_i++) { SoapySDR::ArgInfo arg = (*args_i); props.push_back(addArgInfoProperty(m_propertyGrid, arg)); } } if (dev->getRxChannel()) { args = dev->getRxChannel()->getStreamArgsInfo(); DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId()); ConfigSettings devStreamOpts = devConfig->getStreamOpts(); if (devStreamOpts.size()) { for (int j = 0, jMax = args.size(); j < jMax; j++) { if (devStreamOpts.find(args[j].key) != devStreamOpts.end()) { args[j].value = devStreamOpts[args[j].key]; } } } if (args.size()) { m_propertyGrid->Append(new wxPropertyCategory("Stream Settings")); for (args_i = args.begin(); args_i != args.end(); args_i++) { SoapySDR::ArgInfo arg = (*args_i); props.push_back(addArgInfoProperty(m_propertyGrid, arg)); } } } if (selDev->isManual()) { m_addRemoteButton->SetLabel("Remove"); removeId = selId; } else { m_addRemoteButton->SetLabel("Add"); removeId = nullptr; } } else if (selDev && !selDev->isAvailable() && selDev->isManual()) { m_propertyGrid->Clear(); devSettings.erase(devSettings.begin(),devSettings.end()); props.erase(props.begin(), props.end()); removeId = devTree->GetSelection(); dev = nullptr; selId = nullptr; editId = nullptr; m_addRemoteButton->SetLabel("Remove"); } else if (!selDev) { m_addRemoteButton->SetLabel("Add"); removeId = nullptr; } event.Skip(); }
void SDRDevicesDialog::refreshDeviceProperties() { SDRDeviceInfo *selDev = getSelectedDevice(devTree->GetSelection()); if (selDev && selDev->isAvailable()) { dev = selDev; selId = devTree->GetSelection(); DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getName()); m_propertyGrid->Clear(); SoapySDR::Device *soapyDev = dev->getSoapyDevice(); SoapySDR::ArgInfoList args = soapyDev->getSettingInfo(); SoapySDR::ArgInfoList::const_iterator args_i; m_propertyGrid->Append(new wxPropertyCategory("General Settings")); devSettings.erase(devSettings.begin(),devSettings.end()); devSettings["name"] = m_propertyGrid->Append( new wxStringProperty("Name", wxPG_LABEL, devConfig->getDeviceName()) ); devSettings["offset"] = m_propertyGrid->Append( new wxIntProperty("Offset (Hz)", wxPG_LABEL, devConfig->getOffset()) ); runtimeArgs.erase(runtimeArgs.begin(), runtimeArgs.end()); runtimeProps.erase(runtimeProps.begin(), runtimeProps.end()); streamProps.erase(streamProps.begin(), streamProps.end()); if (args.size()) { m_propertyGrid->Append(new wxPropertyCategory("Run-time Settings")); for (args_i = args.begin(); args_i != args.end(); args_i++) { SoapySDR::ArgInfo arg = (*args_i); arg.value = soapyDev->readSetting(arg.key); runtimeProps[arg.key] = addArgInfoProperty(m_propertyGrid, arg); runtimeArgs[arg.key] = arg; } } if (dev) { args = dev->getSoapyDevice()->getStreamArgsInfo(SOAPY_SDR_RX, 0); DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId()); ConfigSettings devStreamOpts = devConfig->getStreamOpts(); if (devStreamOpts.size()) { for (int j = 0, jMax = args.size(); j < jMax; j++) { if (devStreamOpts.find(args[j].key) != devStreamOpts.end()) { args[j].value = devStreamOpts[args[j].key]; } } } if (args.size()) { m_propertyGrid->Append(new wxPropertyCategory("Stream Settings")); for (args_i = args.begin(); args_i != args.end(); args_i++) { SoapySDR::ArgInfo arg = (*args_i); streamProps[arg.key] = addArgInfoProperty(m_propertyGrid, arg); } } } if (selDev->isManual()) { m_addRemoteButton->SetLabel("Remove"); removeId = selId; } else { m_addRemoteButton->SetLabel("Add"); removeId = nullptr; } } else if (selDev && !selDev->isAvailable() && selDev->isManual()) { m_propertyGrid->Clear(); devSettings.erase(devSettings.begin(),devSettings.end()); runtimeArgs.erase(runtimeArgs.begin(), runtimeArgs.end()); runtimeProps.erase(runtimeProps.begin(), runtimeProps.end()); streamProps.erase(streamProps.begin(), streamProps.end()); removeId = devTree->GetSelection(); dev = nullptr; selId = nullptr; editId = nullptr; m_addRemoteButton->SetLabel("Remove"); } else if (!selDev) { m_addRemoteButton->SetLabel("Add"); removeId = nullptr; } }