mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-23 04:08:36 -05:00
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:
parent
b438fc5a42
commit
f1475fb9be
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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++) {
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user