Use hardware DC when available

- un-comment code in SoapySDRThread for remote testing…
This commit is contained in:
Charles J. Cliffe 2015-09-30 23:45:06 -04:00
parent 748bb39795
commit 9d06fa77c7
6 changed files with 97 additions and 32 deletions

View File

@ -3,6 +3,7 @@
#include "VisualProcessor.h" #include "VisualProcessor.h"
#include "DemodDefs.h" #include "DemodDefs.h"
#include <cmath> #include <cmath>
#include <cstring>
class FFTDataDistributor : public VisualProcessor<DemodulatorThreadIQData, DemodulatorThreadIQData> { class FFTDataDistributor : public VisualProcessor<DemodulatorThreadIQData, DemodulatorThreadIQData> {
public: public:

View File

@ -59,7 +59,7 @@ const std::vector<long long> &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; this->hardware = hardware;
} }
const bool& SDRDeviceInfo::hasHardwareDC() const {
return hardwareDC;
}
void SDRDeviceInfo::setHardwareDC(const bool& hardware) {
hardwareDC = hardware;
}
bool SDRDeviceInfo::hasTimestamps() const { bool SDRDeviceInfo::hasTimestamps() const {
return timestamps; return timestamps;
} }
@ -159,5 +168,12 @@ void SDRDeviceInfo::setDeviceArgs(SoapySDR::Kwargs deviceArgs) {
SoapySDR::Kwargs SDRDeviceInfo::getDeviceArgs() { SoapySDR::Kwargs SDRDeviceInfo::getDeviceArgs() {
return deviceArgs; 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;
} }

View File

@ -108,6 +108,9 @@ public:
const std::string& getHardware() const; const std::string& getHardware() const;
void setHardware(const std::string& hardware); void setHardware(const std::string& hardware);
const bool& hasHardwareDC() const;
void setHardwareDC(const bool& hardware);
bool hasTimestamps() const; bool hasTimestamps() const;
void setTimestamps(bool timestamps); void setTimestamps(bool timestamps);
@ -115,12 +118,16 @@ public:
void setDeviceArgs(SoapySDR::Kwargs deviceArgs); void setDeviceArgs(SoapySDR::Kwargs deviceArgs);
SoapySDR::Kwargs getDeviceArgs(); SoapySDR::Kwargs getDeviceArgs();
void setStreamArgs(SoapySDR::Kwargs deviceArgs);
SoapySDR::Kwargs getStreamArgs();
private: private:
int index; int index;
std::string name, serial, product, manufacturer, tuner; std::string name, serial, product, manufacturer, tuner;
std::string driver, hardware; std::string driver, hardware;
bool timestamps, available; bool timestamps, available, hardwareDC;
SoapySDR::Kwargs deviceArgs; SoapySDR::Kwargs deviceArgs, streamArgs;
std::vector<SDRDeviceChannel> channels; std::vector<SDRDeviceChannel> channels;
}; };

View File

@ -88,32 +88,45 @@ void SDRPostThread::run() {
if (data_in && data_in->data.size()) { if (data_in && data_in->data.size()) {
int dataSize = data_in->data.size()/2; int dataSize = data_in->data.size()/2;
if (dataSize > fpData.capacity()) {
fpData.reserve(dataSize); if (dataSize > dataOut.capacity()) {
dataOut.reserve(dataSize); dataOut.reserve(dataSize);
} }
if (dataSize != fpData.size()) { if (dataSize != dataOut.size()) {
fpData.resize(dataSize);
dataOut.resize(dataSize); dataOut.resize(dataSize);
} }
// 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++) { for (int i = 0; i < dataSize; i++) {
fpData[i].real = data_in->data[i*2]; fpData[i].real = data_in->data[i*2];
fpData[i].imag = data_in->data[i*2+1]; 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]); iirfilt_crcf_execute_block(dcFilter, &fpData[0], dataSize, &dataOut[0]);
}
if (iqVisualQueue != NULL && !iqVisualQueue->full()) { if (iqVisualQueue != NULL && !iqVisualQueue->full()) {
DemodulatorThreadIQData *visualDataOut = visualDataBuffers.getBuffer(); DemodulatorThreadIQData *visualDataOut = visualDataBuffers.getBuffer();

View File

@ -74,15 +74,22 @@ std::vector<SDRDeviceInfo *> *SDRThread::enumerate_devices() {
SDRDeviceInfo *remoteDev = new SDRDeviceInfo(); SDRDeviceInfo *remoteDev = new SDRDeviceInfo();
remoteDev->setDriver("remote"); remoteDev->setDriver("remote");
remoteDev->setName("SoapySDR Remote Test"); remoteDev->setName("SoapySDR Remote Test");
SoapySDR::Kwargs remoteArgs; SoapySDR::Kwargs remoteArgs;
remoteArgs["driver"] = "remote"; remoteArgs["driver"] = "remote";
remoteArgs["remote"] = "127.0.0.1"; // remoteArgs["remote"] = "127.0.0.1";
// remoteArgs["remote"] = "192.168.1.107"; remoteArgs["remote"] = "192.168.1.103";
remoteArgs["remote:driver"] = "rtlsdr"; remoteArgs["remote:driver"] = "rtlsdr";
remoteArgs["remote:format"] = "CS8";
remoteArgs["buffers"] = "6"; remoteArgs["buffers"] = "6";
remoteArgs["buflen"] = "16384"; remoteArgs["buflen"] = "16384";
remoteDev->setDeviceArgs(remoteArgs); 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); SDRThread::devs.push_back(remoteDev);
// */ // */
@ -110,7 +117,17 @@ std::vector<SDRDeviceInfo *> *SDRThread::enumerate_devices() {
dev->setHardware(it->second); 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); SoapySDR::Device::unmake(device);
dev->setAvailable(true); dev->setAvailable(true);
} catch (const std::exception &ex) { } catch (const std::exception &ex) {
std::cerr << "Error making device: " << ex.what() << std::endl; std::cerr << "Error making device: " << ex.what() << std::endl;
@ -155,6 +172,7 @@ void SDRThread::run() {
int direct_sampling_mode = devConfig->getDirectSampling(); int direct_sampling_mode = devConfig->getDirectSampling();
int numElems = 0; int numElems = 0;
bool hasPPM = false; bool hasPPM = false;
bool hasHardwareDC = false;
offset.store(devConfig->getOffset()); offset.store(devConfig->getOffset());
wxGetApp().setSwapIQ(devConfig->getIQSwap()); wxGetApp().setSwapIQ(devConfig->getIQSwap());
@ -174,15 +192,17 @@ void SDRThread::run() {
args["buflen"] = "16384"; args["buflen"] = "16384";
SoapySDR::Device *device = SoapySDR::Device::make(args); SoapySDR::Device *device = SoapySDR::Device::make(args);
SoapySDR::Stream *stream = device->setupStream(SOAPY_SDR_RX,"CF32", std::vector<size_t>(), dev->getStreamArgs());
device->activateStream(stream);
device->setSampleRate(SOAPY_SDR_RX,0,sampleRate.load()); device->setSampleRate(SOAPY_SDR_RX,0,sampleRate.load());
device->setFrequency(SOAPY_SDR_RX,0,"RF",frequency - offset.load()); device->setFrequency(SOAPY_SDR_RX,0,"RF",frequency - offset.load());
if (hasPPM) { if (hasPPM) {
device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm); 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->setGainMode(SOAPY_SDR_RX,0,true);
device->activateStream(stream); hasHardwareDC = dev->hasHardwareDC();
numElems = getOptimalElementCount(sampleRate.load(), 60); numElems = getOptimalElementCount(sampleRate.load(), 60);
@ -274,9 +294,15 @@ void SDRThread::run() {
device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm); device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm);
} }
device->setGainMode(SOAPY_SDR_RX,0, true); 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<size_t>(), dev->getStreamArgs());
device->activateStream(stream); device->activateStream(stream);
} }
if (offset_changed) { if (offset_changed) {
@ -331,6 +357,7 @@ void SDRThread::run() {
dataOut->setRefCount(1); dataOut->setRefCount(1);
dataOut->frequency = frequency; dataOut->frequency = frequency;
dataOut->sampleRate = sampleRate.load(); dataOut->sampleRate = sampleRate.load();
dataOut->dcCorrected = hasHardwareDC;
if (iqDataOutQueue != NULL) { if (iqDataOutQueue != NULL) {
iqDataOutQueue->push(dataOut); iqDataOutQueue->push(dataOut);

View File

@ -30,11 +30,12 @@ class SDRThreadIQData: public ReferenceCounter {
public: public:
long long frequency; long long frequency;
long long sampleRate; long long sampleRate;
bool dcCorrected;
// std::vector<unsigned char> data; // std::vector<unsigned char> data;
std::vector<float> data; std::vector<float> data;
SDRThreadIQData() : SDRThreadIQData() :
frequency(0), sampleRate(DEFAULT_SAMPLE_RATE) { frequency(0), sampleRate(DEFAULT_SAMPLE_RATE), dcCorrected(true) {
} }