diff --git a/CMakeLists.txt b/CMakeLists.txt index 972c167..fc6a1b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,7 +82,7 @@ find_package(wxWidgets COMPONENTS gl core base REQUIRED) set(wxWidgets_CONFIGURATION mswu) include(${wxWidgets_USE_FILE}) -find_package(SoapySDR NO_MODULE REQUIRED) +find_package(SoapySDR "0.4.0" NO_MODULE REQUIRED) include_directories(${SOAPY_SDR_INCLUDE_DIR}) SET(OTHER_LIBRARIES ${SOAPY_SDR_LIBRARY} ${OTHER_LIBRARIES}) ADD_DEFINITIONS( @@ -181,7 +181,7 @@ ENDIF(USE_AUDIO_OSS) ENDIF(UNIX AND NOT APPLE) IF (APPLE) - SET(CMAKE_OSX_DEPLOYMENT_TARGET, "10.9") + SET(CMAKE_OSX_DEPLOYMENT_TARGET, "10.10") SET(FFTW_LIB fftw3f) SET(LIQUID_LIB liquid) @@ -415,7 +415,7 @@ ENDIF(MSVC) IF (APPLE) ADD_DEFINITIONS( -DHAVE_TYPE_TRAITS=1 - -mmacosx-version-min=10.9 + -mmacosx-version-min=10.10 ) ENDIF(APPLE) diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index b215d2a..0bc8903 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -363,13 +363,13 @@ int CubicSDR::getDirectSampling() { } void CubicSDR::setSwapIQ(bool swapIQ) { - sdrPostThread->setSwapIQ(swapIQ); + sdrThread->setIQSwap(swapIQ); SDRDeviceInfo *dev = getDevice(); config.getDevice(dev->getDeviceId())->setIQSwap(swapIQ); } bool CubicSDR::getSwapIQ() { - return sdrPostThread->getSwapIQ(); + return sdrThread->getIQSwap(); } long long CubicSDR::getFrequency() { diff --git a/src/sdr/SDRDeviceInfo.cpp b/src/sdr/SDRDeviceInfo.cpp index a0ad2b8..f059cd9 100644 --- a/src/sdr/SDRDeviceInfo.cpp +++ b/src/sdr/SDRDeviceInfo.cpp @@ -111,8 +111,6 @@ void SDRDeviceChannel::setHardwareDC(const bool& hardware) { hardwareDC = hardware; } - - const bool& SDRDeviceChannel::hasCORR() const { return hasCorr; } @@ -121,6 +119,22 @@ void SDRDeviceChannel::setCORR(const bool& hasCorr) { this->hasCorr = hasCorr; } +void SDRDeviceChannel::setStreamArgsInfo(SoapySDR::ArgInfoList streamArgs) { + streamArgInfo = streamArgs; +} + +SoapySDR::ArgInfoList SDRDeviceChannel::getStreamArgsInfo() { + return streamArgInfo; +} + +std::vector SDRDeviceChannel::getStreamArgNames() { + std::vector names; + for (SoapySDR::ArgInfoList::const_iterator i = streamArgInfo.begin(); i != streamArgInfo.end(); i++) { + names.push_back((*i).key); + } + return names; +} + SDRDeviceInfo::SDRDeviceInfo() : name(""), serial(""), available(false) { @@ -232,6 +246,23 @@ SoapySDR::Kwargs SDRDeviceInfo::getStreamArgs() { return streamArgs; } +void SDRDeviceInfo::setSettingsInfo(SoapySDR::ArgInfoList settingsArgs) { + settingInfo = settingsArgs; +} + +SoapySDR::ArgInfoList SDRDeviceInfo::getSettingsArgInfo() { + return settingInfo; +} + +std::vector SDRDeviceInfo::getSettingNames() { + std::vector names; + for (SoapySDR::ArgInfoList::const_iterator i = settingInfo.begin(); i != settingInfo.end(); i++) { + names.push_back((*i).key); + } + return names; +} + + void SDRDeviceInfo::addChannel(SDRDeviceChannel *chan) { channels.push_back(chan); } diff --git a/src/sdr/SDRDeviceInfo.h b/src/sdr/SDRDeviceInfo.h index 5a153a8..ebcbb8c 100644 --- a/src/sdr/SDRDeviceInfo.h +++ b/src/sdr/SDRDeviceInfo.h @@ -78,13 +78,17 @@ public: const bool& hasCORR() const; void setCORR(const bool& corr); - + void setStreamArgsInfo(SoapySDR::ArgInfoList streamArgs); + SoapySDR::ArgInfoList getStreamArgsInfo(); + std::vector getStreamArgNames(); + private: int channel; bool fullDuplex, tx, rx, hardwareDC, hasCorr; SDRDeviceRange rangeGain, rangeLNA, rangeFull, rangeRF; std::vector sampleRates; std::vector filterBandwidths; + SoapySDR::ArgInfoList streamArgInfo; }; @@ -135,6 +139,11 @@ public: void setStreamArgs(SoapySDR::Kwargs deviceArgs); SoapySDR::Kwargs getStreamArgs(); + void setSettingsInfo(SoapySDR::ArgInfoList settingsArgs); + SoapySDR::ArgInfoList getSettingsArgInfo(); + + std::vector getSettingNames(); + private: int index; std::string name, serial, product, manufacturer, tuner; @@ -142,5 +151,6 @@ private: bool timestamps, available; SoapySDR::Kwargs deviceArgs, streamArgs; + SoapySDR::ArgInfoList settingInfo; std::vector channels; }; diff --git a/src/sdr/SDREnumerator.cpp b/src/sdr/SDREnumerator.cpp index 7b1233d..a2ed22a 100644 --- a/src/sdr/SDREnumerator.cpp +++ b/src/sdr/SDREnumerator.cpp @@ -88,30 +88,6 @@ std::vector *SDREnumerator::enumerate_devices(std::string remot results = SoapySDR::Device::enumerate(); } - - // Remote driver test.. -/* * / - SDRDeviceInfo *remoteDev = new SDRDeviceInfo(); - remoteDev->setDriver("remote"); - remoteDev->setName("SoapySDR Remote Test"); - - SoapySDR::Kwargs remoteArgs; - remoteArgs["driver"] = "remote"; -// remoteArgs["remote"] = "127.0.0.1"; - remoteArgs["remote"] = "192.168.1.103"; - remoteArgs["remote:driver"] = "rtlsdr"; - remoteArgs["buffers"] = "6"; - remoteArgs["buflen"] = "16384"; - remoteDev->setDeviceArgs(remoteArgs); - - SoapySDR::Kwargs streamArgs; - streamArgs["remote:mtu"] = "8192"; - streamArgs["remote:format"] = "CS8"; - streamArgs["remote:window"] = "16384000"; - remoteDev->setStreamArgs(streamArgs); - - SDRThread::devs.push_back(remoteDev); -// */ if (isRemote) { wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Opening remote server ") + remoteAddr + ".."); } @@ -134,11 +110,6 @@ std::vector *SDREnumerator::enumerate_devices(std::string remot wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Found local device #") + std::to_string(i)); } - if (deviceArgs.count("rtl") != 0 || (deviceArgs.count("driver") != 0 && (deviceArgs["driver"] == "rtl" || deviceArgs["driver"] == "rtlsdr"))) { - streamArgs["buffers"] = "6"; - streamArgs["buflen"] = "16384"; - } - for (SoapySDR::Kwargs::const_iterator it = deviceArgs.begin(); it != deviceArgs.end(); ++it) { std::cout << " " << it->first << " = " << it->second << std::endl; if (it->first == "driver") { @@ -149,7 +120,7 @@ std::vector *SDREnumerator::enumerate_devices(std::string remot } dev->setDeviceArgs(deviceArgs); - dev->setStreamArgs(deviceArgs); + dev->setStreamArgs(streamArgs); std::cout << "Make device " << i << std::endl; try { @@ -193,10 +164,13 @@ std::vector *SDREnumerator::enumerate_devices(std::string remot for (std::vector::iterator i = rates.begin(); i != rates.end(); i++) { chan->getSampleRates().push_back((long)(*i)); } + + chan->setStreamArgsInfo(device->getStreamArgsInfo(SOAPY_SDR_RX, i)); + dev->addChannel(chan); } - + dev->setSettingsInfo(device->getSettingInfo()); SoapySDR::Device::unmake(device); diff --git a/src/sdr/SDRPostThread.cpp b/src/sdr/SDRPostThread.cpp index 31ec0b7..e4eefaa 100644 --- a/src/sdr/SDRPostThread.cpp +++ b/src/sdr/SDRPostThread.cpp @@ -10,7 +10,6 @@ SDRPostThread::SDRPostThread() : IOThread() { iqDataOutQueue = NULL; iqVisualQueue = NULL; - swapIQ.store(false); numChannels = 0; channelizer = NULL; @@ -49,14 +48,6 @@ void SDRPostThread::removeDemodulator(DemodulatorInstance *demod) { busy_demod.unlock(); } -void SDRPostThread::setSwapIQ(bool swapIQ) { - this->swapIQ.store(swapIQ); -} - -bool SDRPostThread::getSwapIQ() { - return this->swapIQ.load(); -} - void SDRPostThread::initPFBChannelizer() { // std::cout << "Initializing post-process FIR polyphase filterbank channelizer with " << numChannels << " channels." << std::endl; if (channelizer) { @@ -191,17 +182,6 @@ void SDRPostThread::run() { if (outSize != dataOut.size()) { dataOut.resize(outSize); } - - // if (swapIQ) { - // for (int i = 0; i < dataSize; i++) { - // fpData[i] = _lut_swap[*((uint16_t*)&data_in->data[2*i])]; - // } - // } else { - // for (int i = 0; i < dataSize; i++) { - // fpData[i] = _lut[*((uint16_t*)&data_in->data[2*i])]; - // } - // } - int activeVisChannel = -1; // if (visBandwidth.load() && visBandwidth.load() < (chanBw/2)) { diff --git a/src/sdr/SDRPostThread.h b/src/sdr/SDRPostThread.h index 7a9b634..f89d6e1 100644 --- a/src/sdr/SDRPostThread.h +++ b/src/sdr/SDRPostThread.h @@ -14,9 +14,6 @@ public: void bindDemodulator(DemodulatorInstance *demod); void removeDemodulator(DemodulatorInstance *demod); - - void setSwapIQ(bool swapIQ); - bool getSwapIQ(); void run(); void terminate(); @@ -31,7 +28,6 @@ protected: std::mutex busy_demod; std::vector demodulators; - std::atomic_bool swapIQ; private: void initPFBChannelizer(); diff --git a/src/sdr/SoapySDRThread.cpp b/src/sdr/SoapySDRThread.cpp index 3c17b8d..c36563d 100644 --- a/src/sdr/SoapySDRThread.cpp +++ b/src/sdr/SoapySDRThread.cpp @@ -25,12 +25,14 @@ SDRThread::SDRThread() : IOThread() { ppm_changed .store(false); direct_sampling_changed.store(false); device_changed.store(false); + iq_swap.store(false); + iq_swap_changed.store(false); hasPPM.store(false); hasHardwareDC.store(false); numChannels.store(8); - -// dcFilter = iirfilt_crcf_create_dc_blocker(0.0005); + hasDirectSampling.store(false); + hasIQSwap.store(false); } SDRThread::~SDRThread() { @@ -43,26 +45,20 @@ void SDRThread::init() { DeviceConfig *devConfig = deviceConfig.load(); ppm.store(devConfig->getPPM()); + ppm_changed.store(true); + direct_sampling_mode.store(devConfig->getDirectSampling()); - + direct_sampling_changed.store(true); + + iq_swap.store(devConfig->getIQSwap()); + iq_swap_changed.store(true); + std::string driverName = devInfo->getDriver(); offset = devConfig->getOffset(); - wxGetApp().setSwapIQ(devConfig->getIQSwap()); SoapySDR::Kwargs args = devInfo->getDeviceArgs(); - args["direct_samp"] = std::to_string(devConfig->getDirectSampling()); - - if (driverName == "rtl" || driverName == "rtlsdr") { - args["iq_swap"] = std::to_string(devConfig->getIQSwap()?1:0); - args["buffers"] = "6"; - args["buflen"] = "16384"; - hasPPM = true; - } else { - hasPPM = false; - } - wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Initializing device.")); device = SoapySDR::Device::make(args); stream = device->setupStream(SOAPY_SDR_RX,"CF32", std::vector(), devInfo->getStreamArgs()); @@ -86,6 +82,14 @@ void SDRThread::init() { hasHardwareDC.store(false); } + std::vector settingNames = devInfo->getSettingNames(); + if (std::find(settingNames.begin(), settingNames.end(), "direct_samp") != settingNames.end()) { + hasDirectSampling.store(true); + } + if (std::find(settingNames.begin(), settingNames.end(), "iq_swap") != settingNames.end()) { + hasIQSwap.store(true); + } + device->setGainMode(SOAPY_SDR_RX,0,true); numChannels.store(getOptimalChannelCount(sampleRate.load())); @@ -168,14 +172,19 @@ void SDRThread::readLoop() { } if (ppm_changed.load() && hasPPM.load()) { device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm.load()); - direct_sampling_changed.store(false); + ppm_changed.store(false); } if (freq_changed.load()) { device->setFrequency(SOAPY_SDR_RX,0,"RF",frequency.load() - offset.load()); freq_changed.store(false); } - if (direct_sampling_changed.load()) { - // rtlsdr_set_direct_sampling(dev, direct_sampling_mode); + if (hasDirectSampling.load() && direct_sampling_changed.load()) { + device->writeSetting("direct_samp", std::to_string(direct_sampling_mode)); + direct_sampling_changed.store(false); + } + if (hasIQSwap.load() && iq_swap_changed.load()) { + device->writeSetting("iq_swap", iq_swap.load()?"true":"false"); + iq_swap_changed.store(false); } readStream(iqDataOutQueue); @@ -302,3 +311,12 @@ void SDRThread::setDirectSampling(int dsMode) { int SDRThread::getDirectSampling() { return direct_sampling_mode.load(); } + +void SDRThread::setIQSwap(bool iqSwap) { + iq_swap.store(iqSwap); + iq_swap_changed.store(true); +} + +bool SDRThread::getIQSwap() { + return iq_swap.load(); +} diff --git a/src/sdr/SoapySDRThread.h b/src/sdr/SoapySDRThread.h index d86044f..3f94864 100644 --- a/src/sdr/SoapySDRThread.h +++ b/src/sdr/SoapySDRThread.h @@ -71,6 +71,9 @@ public: void setDirectSampling(int dsMode); int getDirectSampling(); + + void setIQSwap(bool iqSwap); + bool getIQSwap(); protected: SoapySDR::Stream *stream; @@ -84,8 +87,7 @@ protected: std::atomic sampleRate; std::atomic_llong frequency, offset; std::atomic_int ppm, direct_sampling_mode, numElems, numChannels; - std::atomic_bool hasPPM, hasHardwareDC; - - std::atomic_bool rate_changed, freq_changed, offset_changed, - ppm_changed, direct_sampling_changed, device_changed; + std::atomic_bool hasPPM, hasHardwareDC, hasDirectSampling, hasIQSwap; + std::atomic_bool iq_swap, rate_changed, freq_changed, offset_changed, + ppm_changed, direct_sampling_changed, device_changed, iq_swap_changed; };