From 9d06fa77c70a9ef25358ba864e5993349120a9bc Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Wed, 30 Sep 2015 23:45:06 -0400 Subject: [PATCH] Use hardware DC when available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - un-comment code in SoapySDRThread for remote testing… --- src/process/FFTDataDistributor.h | 1 + src/sdr/SDRDeviceInfo.cpp | 20 ++++++++++-- src/sdr/SDRDeviceInfo.h | 11 +++++-- src/sdr/SDRPostThread.cpp | 53 ++++++++++++++++++++------------ src/sdr/SoapySDRThread.cpp | 41 +++++++++++++++++++----- src/sdr/SoapySDRThread.h | 3 +- 6 files changed, 97 insertions(+), 32 deletions(-) diff --git a/src/process/FFTDataDistributor.h b/src/process/FFTDataDistributor.h index 8caaaa9..677248e 100644 --- a/src/process/FFTDataDistributor.h +++ b/src/process/FFTDataDistributor.h @@ -3,6 +3,7 @@ #include "VisualProcessor.h" #include "DemodDefs.h" #include +#include class FFTDataDistributor : public VisualProcessor { public: diff --git a/src/sdr/SDRDeviceInfo.cpp b/src/sdr/SDRDeviceInfo.cpp index 6a0958a..5058d3f 100644 --- a/src/sdr/SDRDeviceInfo.cpp +++ b/src/sdr/SDRDeviceInfo.cpp @@ -59,7 +59,7 @@ const std::vector &SDRDeviceChannel::getFilterBandwidths() const { -SDRDeviceInfo::SDRDeviceInfo() : name(""), serial(""), available(false) { +SDRDeviceInfo::SDRDeviceInfo() : name(""), serial(""), available(false), hardwareDC(false) { } @@ -145,6 +145,15 @@ void SDRDeviceInfo::setHardware(const std::string& hardware) { this->hardware = hardware; } +const bool& SDRDeviceInfo::hasHardwareDC() const { + return hardwareDC; +} + +void SDRDeviceInfo::setHardwareDC(const bool& hardware) { + hardwareDC = hardware; +} + + bool SDRDeviceInfo::hasTimestamps() const { return timestamps; } @@ -159,5 +168,12 @@ void SDRDeviceInfo::setDeviceArgs(SoapySDR::Kwargs deviceArgs) { SoapySDR::Kwargs SDRDeviceInfo::getDeviceArgs() { return deviceArgs; -// return "driver=" + driver + "," + getDriver() + "=" + std::to_string(getIndex()); +} + +void SDRDeviceInfo::setStreamArgs(SoapySDR::Kwargs streamArgs) { + this->streamArgs = streamArgs; +} + +SoapySDR::Kwargs SDRDeviceInfo::getStreamArgs() { + return streamArgs; } diff --git a/src/sdr/SDRDeviceInfo.h b/src/sdr/SDRDeviceInfo.h index 774f34a..64ac47b 100644 --- a/src/sdr/SDRDeviceInfo.h +++ b/src/sdr/SDRDeviceInfo.h @@ -108,6 +108,9 @@ public: const std::string& getHardware() const; void setHardware(const std::string& hardware); + const bool& hasHardwareDC() const; + void setHardwareDC(const bool& hardware); + bool hasTimestamps() const; void setTimestamps(bool timestamps); @@ -115,12 +118,16 @@ public: void setDeviceArgs(SoapySDR::Kwargs deviceArgs); SoapySDR::Kwargs getDeviceArgs(); + + void setStreamArgs(SoapySDR::Kwargs deviceArgs); + SoapySDR::Kwargs getStreamArgs(); + private: int index; std::string name, serial, product, manufacturer, tuner; std::string driver, hardware; - bool timestamps, available; + bool timestamps, available, hardwareDC; - SoapySDR::Kwargs deviceArgs; + SoapySDR::Kwargs deviceArgs, streamArgs; std::vector channels; }; diff --git a/src/sdr/SDRPostThread.cpp b/src/sdr/SDRPostThread.cpp index 8168df7..7836c2b 100644 --- a/src/sdr/SDRPostThread.cpp +++ b/src/sdr/SDRPostThread.cpp @@ -88,32 +88,45 @@ void SDRPostThread::run() { if (data_in && data_in->data.size()) { int dataSize = data_in->data.size()/2; - if (dataSize > fpData.capacity()) { - fpData.reserve(dataSize); + + if (dataSize > dataOut.capacity()) { dataOut.reserve(dataSize); } - if (dataSize != fpData.size()) { - fpData.resize(dataSize); + if (dataSize != dataOut.size()) { dataOut.resize(dataSize); } - - for (int i = 0; i < dataSize; i++) { - fpData[i].real = data_in->data[i*2]; - fpData[i].imag = data_in->data[i*2+1]; - } - -// 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])]; -// } -// } - iirfilt_crcf_execute_block(dcFilter, &fpData[0], dataSize, &dataOut[0]); + // 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])]; + // } + // } + + if (data_in->dcCorrected) { + for (int i = 0; i < dataSize; i++) { + dataOut[i].real = data_in->data[i*2]; + dataOut[i].imag = data_in->data[i*2+1]; + } + } else { + if (dataSize > fpData.capacity()) { + fpData.reserve(dataSize); + } + if (dataSize != fpData.size()) { + fpData.resize(dataSize); + } + + for (int i = 0; i < dataSize; i++) { + fpData[i].real = data_in->data[i*2]; + fpData[i].imag = data_in->data[i*2+1]; + } + + iirfilt_crcf_execute_block(dcFilter, &fpData[0], dataSize, &dataOut[0]); + } if (iqVisualQueue != NULL && !iqVisualQueue->full()) { DemodulatorThreadIQData *visualDataOut = visualDataBuffers.getBuffer(); diff --git a/src/sdr/SoapySDRThread.cpp b/src/sdr/SoapySDRThread.cpp index 89c50f4..562a193 100644 --- a/src/sdr/SoapySDRThread.cpp +++ b/src/sdr/SoapySDRThread.cpp @@ -74,15 +74,22 @@ std::vector *SDRThread::enumerate_devices() { 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.107"; +// remoteArgs["remote"] = "127.0.0.1"; + remoteArgs["remote"] = "192.168.1.103"; remoteArgs["remote:driver"] = "rtlsdr"; - remoteArgs["remote:format"] = "CS8"; 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); // */ @@ -110,7 +117,17 @@ std::vector *SDRThread::enumerate_devices() { dev->setHardware(it->second); } } + + if (device->hasDCOffsetMode(SOAPY_SDR_RX, 0)) { + device->setDCOffsetMode(SOAPY_SDR_RX, 0, true); + std::cout << "Hardware DC offset support detected; internal DC offset correction will be disabled." << std::endl; + dev->setHardwareDC(true); + } else { + dev->setHardwareDC(false); + } + SoapySDR::Device::unmake(device); + dev->setAvailable(true); } catch (const std::exception &ex) { std::cerr << "Error making device: " << ex.what() << std::endl; @@ -155,6 +172,7 @@ void SDRThread::run() { int direct_sampling_mode = devConfig->getDirectSampling(); int numElems = 0; bool hasPPM = false; + bool hasHardwareDC = false; offset.store(devConfig->getOffset()); wxGetApp().setSwapIQ(devConfig->getIQSwap()); @@ -174,15 +192,17 @@ void SDRThread::run() { args["buflen"] = "16384"; SoapySDR::Device *device = SoapySDR::Device::make(args); + SoapySDR::Stream *stream = device->setupStream(SOAPY_SDR_RX,"CF32", std::vector(), dev->getStreamArgs()); + + device->activateStream(stream); device->setSampleRate(SOAPY_SDR_RX,0,sampleRate.load()); device->setFrequency(SOAPY_SDR_RX,0,"RF",frequency - offset.load()); if (hasPPM) { device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm); } - device->setGainMode(SOAPY_SDR_RX,0,true); - SoapySDR::Stream *stream = device->setupStream(SOAPY_SDR_RX,"CF32"); - device->activateStream(stream); + device->setGainMode(SOAPY_SDR_RX,0,true); + hasHardwareDC = dev->hasHardwareDC(); numElems = getOptimalElementCount(sampleRate.load(), 60); @@ -274,9 +294,15 @@ void SDRThread::run() { device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm); } device->setGainMode(SOAPY_SDR_RX,0, true); + hasHardwareDC = dev->hasHardwareDC(); + if (hasHardwareDC) { + device->setDCOffsetMode(SOAPY_SDR_RX, 0, true); + std::cout << "Hardware DC offset support detected; internal DC offset compensation disabled." << std::endl; + } - SoapySDR::Stream *stream = device->setupStream(SOAPY_SDR_RX,"CF32"); + SoapySDR::Stream *stream = device->setupStream(SOAPY_SDR_RX,"CF32", std::vector(), dev->getStreamArgs()); device->activateStream(stream); + } if (offset_changed) { @@ -331,6 +357,7 @@ void SDRThread::run() { dataOut->setRefCount(1); dataOut->frequency = frequency; dataOut->sampleRate = sampleRate.load(); + dataOut->dcCorrected = hasHardwareDC; if (iqDataOutQueue != NULL) { iqDataOutQueue->push(dataOut); diff --git a/src/sdr/SoapySDRThread.h b/src/sdr/SoapySDRThread.h index 8189025..f75c575 100644 --- a/src/sdr/SoapySDRThread.h +++ b/src/sdr/SoapySDRThread.h @@ -30,11 +30,12 @@ class SDRThreadIQData: public ReferenceCounter { public: long long frequency; long long sampleRate; + bool dcCorrected; // std::vector data; std::vector data; SDRThreadIQData() : - frequency(0), sampleRate(DEFAULT_SAMPLE_RATE) { + frequency(0), sampleRate(DEFAULT_SAMPLE_RATE), dcCorrected(true) { }