Move DC correction to channel 0, reduce demod vis CPU usage

- Demod vis now uses channelizer output instead of decimation
- DC correction now only applied to channel 0
This commit is contained in:
Charles J. Cliffe 2015-10-17 16:17:12 -04:00
parent b438fc5a42
commit f1475fb9be
7 changed files with 62 additions and 62 deletions

View File

@ -671,8 +671,6 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
DemodulatorInstance *demod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
if (demod) {
DemodulatorInstance *demod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
if (demod->isTracking()) {
if (spectrumCanvas->getViewState()) {
long long diff = abs(demod->getFrequency() - spectrumCanvas->getCenterFrequency()) + (demod->getBandwidth()/2) + (demod->getBandwidth()/4);
@ -816,7 +814,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
wxGetApp().getAudioVisualQueue()->set_max_num_items((scopeCanvas->scopeVisible()?1:0) + (scopeCanvas->spectrumVisible()?1:0));
wxGetApp().getScopeProcessor()->run();
wxGetApp().getSpectrumDistributor()->run();
// wxGetApp().getSpectrumDistributor()->run();
SpectrumVisualProcessor *proc = wxGetApp().getSpectrumProcessor();

View File

@ -59,22 +59,14 @@ bool CubicSDR::OnInit() {
pipeIQVisualData = new DemodulatorThreadInputQueue();
pipeIQVisualData->set_max_num_items(1);
spectrumDistributor.setInput(pipeIQVisualData);
pipeDemodIQVisualData = new DemodulatorThreadInputQueue();
pipeDemodIQVisualData->set_max_num_items(1);
pipeSpectrumIQVisualData = new DemodulatorThreadInputQueue();
pipeSpectrumIQVisualData->set_max_num_items(1);
pipeWaterfallIQVisualData = new DemodulatorThreadInputQueue();
pipeWaterfallIQVisualData->set_max_num_items(128);
spectrumDistributor.attachOutput(pipeDemodIQVisualData);
spectrumDistributor.attachOutput(pipeSpectrumIQVisualData);
getDemodSpectrumProcessor()->setInput(pipeDemodIQVisualData);
getSpectrumProcessor()->setInput(pipeSpectrumIQVisualData);
getSpectrumProcessor()->setInput(pipeIQVisualData);
pipeAudioVisualData = new DemodulatorThreadOutputQueue();
pipeAudioVisualData->set_max_num_items(1);
@ -89,19 +81,17 @@ bool CubicSDR::OnInit() {
sdrThread->setOutputQueue("IQDataOutput",pipeSDRIQData);
sdrPostThread = new SDRPostThread();
// sdrPostThread->setNumVisSamples(BUF_SIZE);
sdrPostThread->setInputQueue("IQDataInput", pipeSDRIQData);
sdrPostThread->setOutputQueue("IQVisualDataOutput", pipeIQVisualData);
sdrPostThread->setOutputQueue("IQDataOutput", pipeWaterfallIQVisualData);
sdrPostThread->setOutputQueue("IQActiveDemodVisualDataOutput", pipeDemodIQVisualData);
t_PostSDR = new std::thread(&SDRPostThread::threadMain, sdrPostThread);
t_SpectrumVisual = new std::thread(&SpectrumVisualDataThread::threadMain, spectrumVisualThread);
t_DemodVisual = new std::thread(&SpectrumVisualDataThread::threadMain, demodVisualThread);
// t_SDR = new std::thread(&SDRThread::threadMain, sdrThread);
sdrEnum = new SDREnumerator();
appframe = new AppFrame();
t_SDREnum = new std::thread(&SDREnumerator::threadMain, sdrEnum);
@ -371,11 +361,6 @@ SpectrumVisualProcessor *CubicSDR::getDemodSpectrumProcessor() {
return demodVisualThread->getProcessor();
}
VisualDataDistributor<DemodulatorThreadIQData> *CubicSDR::getSpectrumDistributor() {
return &spectrumDistributor;
}
DemodulatorThreadOutputQueue* CubicSDR::getAudioVisualQueue() {
return pipeAudioVisualData;
}

View File

@ -70,11 +70,11 @@ public:
ScopeVisualProcessor *getScopeProcessor();
SpectrumVisualProcessor *getSpectrumProcessor();
SpectrumVisualProcessor *getDemodSpectrumProcessor();
VisualDataDistributor<DemodulatorThreadIQData> *getSpectrumDistributor();
DemodulatorThreadOutputQueue* getAudioVisualQueue();
DemodulatorThreadInputQueue* getIQVisualQueue();
DemodulatorThreadInputQueue* getWaterfallVisualQueue();
DemodulatorThreadInputQueue* getActiveDemodVisualQueue();
DemodulatorMgr &getDemodMgr();
void bindDemodulator(DemodulatorInstance *demod);
@ -122,18 +122,15 @@ private:
SpectrumVisualDataThread *spectrumVisualThread;
SpectrumVisualDataThread *demodVisualThread;
// SDRThreadCommandQueue* pipeSDRCommand;
SDRThreadIQDataQueue* pipeSDRIQData;
DemodulatorThreadInputQueue* pipeIQVisualData;
DemodulatorThreadOutputQueue* pipeAudioVisualData;
DemodulatorThreadInputQueue* pipeDemodIQVisualData;
DemodulatorThreadInputQueue* pipeSpectrumIQVisualData;
DemodulatorThreadInputQueue* pipeWaterfallIQVisualData;
DemodulatorThreadInputQueue* pipeActiveDemodIQVisualData;
ScopeVisualProcessor scopeProcessor;
VisualDataDistributor<DemodulatorThreadIQData> spectrumDistributor;
SDRDevicesDialog *deviceSelectorDialog;
std::thread *t_SDR, *t_SDREnum, *t_PostSDR, *t_SpectrumVisual, *t_DemodVisual;

View File

@ -18,6 +18,7 @@ SDRPostThread::SDRPostThread() : IOThread() {
nRunDemods = 0;
doRefresh.store(false);
dcFilter = iirfilt_crcf_create_dc_blocker(0.0005);
}
SDRPostThread::~SDRPostThread() {
@ -65,9 +66,7 @@ void SDRPostThread::initPFBChannelizer() {
chanCenters.resize(numChannels);
demodChannelActive.resize(numChannels);
// firpfbch2 returns 2x sample rate per channel
// so, max demodulation without gaps is 1/2 chanBw ..?
// std::cout << "Channel bandwidth spacing: " << (chanBw/2) << " actual bandwidth: " << chanBw << std::endl;
// std::cout << "Channel bandwidth spacing: " << (chanBw) << std::endl;
}
void SDRPostThread::updateActiveDemodulators() {
@ -141,8 +140,11 @@ void SDRPostThread::run() {
iqDataInQueue = (SDRThreadIQDataQueue*)getInputQueue("IQDataInput");
iqDataOutQueue = (DemodulatorThreadInputQueue*)getOutputQueue("IQDataOutput");
iqVisualQueue = (DemodulatorThreadInputQueue*)getOutputQueue("IQVisualDataOutput");
iqActiveDemodVisualQueue = (DemodulatorThreadInputQueue*)getOutputQueue("IQActiveDemodVisualDataOutput");
iqDataInQueue->set_max_num_items(0);
std::vector<liquid_float_complex> dcBuf;
while (!terminated) {
SDRThreadIQData *data_in;
@ -178,24 +180,25 @@ void SDRPostThread::run() {
// }
// }
if (iqVisualQueue != NULL || iqDataOutQueue != NULL) {
bool doIQVis = iqVisualQueue && !iqVisualQueue->full();
bool doIQOut = iqDataOutQueue != NULL;
if (iqDataOutQueue != NULL && !iqDataOutQueue->full()) {
DemodulatorThreadIQData *iqDataOut = visualDataBuffers.getBuffer();
iqDataOut->setRefCount((doIQVis?1:0) + (doIQOut?1:0));
bool doVis = false;
if (iqVisualQueue != NULL && !iqVisualQueue->full()) {
doVis = true;
}
iqDataOut->setRefCount(1 + (doVis?1:0));
iqDataOut->frequency = data_in->frequency;
iqDataOut->sampleRate = data_in->sampleRate;
iqDataOut->data.assign(data_in->data.begin(), data_in->data.begin() + dataSize);
if (doIQVis) {
iqDataOutQueue->push(iqDataOut);
if (doVis) {
iqVisualQueue->push(iqDataOut);
}
if (doIQOut) {
iqDataOutQueue->push(iqDataOut);
}
}
busy_demod.lock();
@ -211,6 +214,8 @@ void SDRPostThread::run() {
doRefresh.store(false);
}
DemodulatorInstance *activeDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
int activeDemodChannel = -1;
// Find active demodulators
if (nRunDemods) {
@ -220,7 +225,7 @@ void SDRPostThread::run() {
// }
// channelize data
// firpfbch2 output rate is 2 x ( input rate / channels )
// firpfbch output rate is (input rate / channels)
for (int i = 0, iMax = dataSize; i < iMax; i+=numChannels) {
firpfbch_crcf_analyzer_execute(channelizer, &data_in->data[i], &dataOut[i]);
}
@ -239,30 +244,29 @@ void SDRPostThread::run() {
if (fdelta < minDelta) {
minDelta = fdelta;
demodChannel[i] = j;
if (demod == activeDemod) {
activeDemodChannel = j;
}
}
}
}
for (int i = 0; i < nRunDemods; i++) {
// cache channel usage refcounts
if (demodChannel[i] >= 0) {
demodChannelActive[demodChannel[i]]++;
}
}
// Run channels
for (int i = 0; i < numChannels; i++) {
if (demodChannelActive[i] == 0) {
// Nothing using this channel, skip
continue;
}
bool doVis = (activeDemodChannel == i) && (iqActiveDemodVisualQueue != NULL) && !iqActiveDemodVisualQueue->full();
DemodulatorThreadIQData *demodDataOut = buffers.getBuffer();
demodDataOut->setRefCount(demodChannelActive[i]);
demodDataOut->setRefCount(demodChannelActive[i] + (doVis?1:0));
demodDataOut->frequency = chanCenters[i];
demodDataOut->sampleRate = chanBw;
// Calculate channel buffer size
int chanDataSize = (outSize/numChannels);
@ -274,9 +278,24 @@ void SDRPostThread::run() {
}
// prepare channel data buffer
for (int j = 0, idx = i; j < chanDataSize; j++) {
idx += numChannels;
demodDataOut->data[j] = dataOut[idx];
if (i == 0) { // Channel 0 requires DC correction
if (dcBuf.size() != chanDataSize) {
dcBuf.resize(chanDataSize);
}
for (int j = 0, idx = i; j < chanDataSize; j++) {
idx += numChannels;
dcBuf[j] = dataOut[idx];
}
iirfilt_crcf_execute_block(dcFilter, &dcBuf[0], chanDataSize, &demodDataOut->data[0]);
} else {
for (int j = 0, idx = i; j < chanDataSize; j++) {
idx += numChannels;
demodDataOut->data[j] = dataOut[idx];
}
}
if (doVis) {
iqActiveDemodVisualQueue->push(demodDataOut);
}
for (int j = 0; j < nRunDemods; j++) {

View File

@ -25,7 +25,8 @@ protected:
SDRThreadIQDataQueue *iqDataInQueue;
DemodulatorThreadInputQueue *iqDataOutQueue;
DemodulatorThreadInputQueue *iqVisualQueue;
DemodulatorThreadInputQueue *iqActiveDemodVisualQueue;
std::mutex busy_demod;
std::vector<DemodulatorInstance *> demodulators;
std::atomic_bool swapIQ;
@ -51,4 +52,5 @@ private:
int numChannels, sampleRate;
long long frequency;
firpfbch_crcf channelizer;
iirfilt_crcf dcFilter;
};

View File

@ -30,7 +30,7 @@ SDRThread::SDRThread() : IOThread() {
hasHardwareDC.store(false);
numChannels.store(8);
dcFilter = iirfilt_crcf_create_dc_blocker(0.0005);
// dcFilter = iirfilt_crcf_create_dc_blocker(0.0005);
}
SDRThread::~SDRThread() {
@ -80,7 +80,7 @@ void SDRThread::init() {
}
if (chan->hasHardwareDC()) {
hasHardwareDC.store(true);
wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Found hardware DC offset correction support, internal disabled."));
// wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Found hardware DC offset correction support, internal disabled."));
device->setDCOffsetMode(SOAPY_SDR_RX, chan->getChannel(), true);
} else {
hasHardwareDC.store(false);
@ -121,14 +121,14 @@ void SDRThread::readStream(SDRThreadIQDataQueue* iqDataOutQueue) {
if (n_read > 0 && !terminated) {
SDRThreadIQData *dataOut = buffers.getBuffer();
if (hasHardwareDC) {
// if (hasHardwareDC) {
dataOut->data.assign(inpBuffer.data.begin(), inpBuffer.data.begin()+n_read);
} else {
if (dataOut->data.size() != n_read) {
dataOut->data.resize(n_read);
}
iirfilt_crcf_execute_block(dcFilter, &inpBuffer.data[0], n_read, &dataOut->data[0]);
}
// } else {
// if (dataOut->data.size() != n_read) {
// dataOut->data.resize(n_read);
// }
// iirfilt_crcf_execute_block(dcFilter, &inpBuffer.data[0], n_read, &dataOut->data[0]);
// }
dataOut->setRefCount(1);

View File

@ -77,7 +77,6 @@ protected:
SoapySDR::Device *device;
void *buffs[1];
ReBuffer<SDRThreadIQData> buffers;
iirfilt_crcf dcFilter;
SDRThreadIQData inpBuffer;
std::atomic<DeviceConfig *> deviceConfig;
std::atomic<SDRDeviceInfo *> deviceInfo;