mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-25 21:28:38 -05:00
Merge pull request #12 from cjcliffe/remove_dc_spike
Remove DC spike from IQ stream and visuals
This commit is contained in:
commit
be33bbce4c
@ -90,6 +90,7 @@ SET (cubicsdr_sources
|
||||
src/CubicSDR.cpp
|
||||
src/AppFrame.cpp
|
||||
src/sdr/SDRThread.cpp
|
||||
src/sdr/SDRPostThread.cpp
|
||||
src/demod/DemodulatorThread.cpp
|
||||
src/demod/DemodulatorMgr.cpp
|
||||
src/audio/AudioThread.cpp
|
||||
@ -110,6 +111,7 @@ SET (cubicsdr_headers
|
||||
src/CubicSDR.h
|
||||
src/AppFrame.h
|
||||
src/sdr/SDRThread.h
|
||||
src/sdr/SDRPostThread.h
|
||||
src/demod/DemodulatorThread.h
|
||||
src/demod/DemodulatorMgr.h
|
||||
src/audio/AudioThread.h
|
||||
|
@ -36,11 +36,19 @@ bool CubicSDR::OnInit() {
|
||||
|
||||
threadCmdQueueSDR = new SDRThreadCommandQueue;
|
||||
sdrThread = new SDRThread(threadCmdQueueSDR);
|
||||
sdrThread->bindDemodulator(demodulatorTest);
|
||||
|
||||
sdrPostThread = new SDRPostThread();
|
||||
|
||||
iqPostDataQueue = new SDRThreadIQDataQueue;
|
||||
iqVisualQueue = new SDRThreadIQDataQueue;
|
||||
sdrThread->setIQVisualQueue(iqVisualQueue);
|
||||
|
||||
sdrThread->setIQDataOutQueue(iqPostDataQueue);
|
||||
sdrPostThread->setIQDataInQueue(iqPostDataQueue);
|
||||
sdrPostThread->setIQVisualQueue(iqVisualQueue);
|
||||
|
||||
sdrPostThread->bindDemodulator(demodulatorTest);
|
||||
|
||||
threadPostSDR = new std::thread(&SDRPostThread::threadMain, sdrPostThread);
|
||||
threadSDR = new std::thread(&SDRThread::threadMain, sdrThread);
|
||||
|
||||
AppFrame *appframe = new AppFrame();
|
||||
@ -53,9 +61,15 @@ int CubicSDR::OnExit() {
|
||||
sdrThread->terminate();
|
||||
threadSDR->join();
|
||||
|
||||
sdrPostThread->terminate();
|
||||
threadPostSDR->join();
|
||||
|
||||
delete sdrThread;
|
||||
delete threadSDR;
|
||||
|
||||
delete sdrPostThread;
|
||||
delete threadPostSDR;
|
||||
|
||||
demodMgr.terminateAll();
|
||||
|
||||
audioThread->terminate();
|
||||
@ -69,6 +83,8 @@ int CubicSDR::OnExit() {
|
||||
|
||||
delete iqVisualQueue;
|
||||
delete audioVisualQueue;
|
||||
delete iqPostDataQueue;
|
||||
|
||||
delete m_glContext;
|
||||
|
||||
return wxApp::OnExit();
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "ThreadQueue.h"
|
||||
#include "SDRThread.h"
|
||||
#include "SDRPostThread.h"
|
||||
#include "AudioThread.h"
|
||||
#include "DemodulatorMgr.h"
|
||||
|
||||
@ -57,12 +58,15 @@ private:
|
||||
AudioThread *audioThread;
|
||||
|
||||
SDRThread *sdrThread;
|
||||
SDRPostThread *sdrPostThread;
|
||||
SDRThreadCommandQueue* threadCmdQueueSDR;
|
||||
SDRThreadIQDataQueue* iqVisualQueue;
|
||||
SDRThreadIQDataQueue* iqPostDataQueue;
|
||||
DemodulatorThreadOutputQueue* audioVisualQueue;
|
||||
|
||||
std::thread *threadAudio;
|
||||
std::thread *threadSDR;
|
||||
std::thread *threadPostSDR;
|
||||
};
|
||||
|
||||
DECLARE_APP(CubicSDR)
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#define BUF_SIZE (16 * 32 * 128)
|
||||
#define BUF_SIZE (16384*6)
|
||||
#define SRATE 2000000
|
||||
#define FFT_SIZE 2048
|
||||
|
||||
|
78
src/sdr/SDRPostThread.cpp
Normal file
78
src/sdr/SDRPostThread.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
#include "SDRPostThread.h"
|
||||
#include "CubicSDRDefs.h"
|
||||
#include <vector>
|
||||
#include "CubicSDR.h"
|
||||
|
||||
SDRPostThread::SDRPostThread() :
|
||||
iqDataInQueue(NULL), iqDataOutQueue(NULL), iqVisualQueue(NULL), terminated(false) {
|
||||
dev = NULL;
|
||||
sample_rate = SRATE;
|
||||
}
|
||||
|
||||
SDRPostThread::~SDRPostThread() {
|
||||
std::cout << std::endl << "SDR post-process thread done." << std::endl << std::endl;
|
||||
rtlsdr_close(dev);
|
||||
}
|
||||
|
||||
void SDRPostThread::threadMain() {
|
||||
|
||||
std::cout << "SDR post-process thread starting.." << std::endl;
|
||||
|
||||
int n_read;
|
||||
double seconds = 0.0;
|
||||
|
||||
dcFilter = iirfilt_crcf_create_dc_blocker(0.0005);
|
||||
|
||||
liquid_float_complex x, y;
|
||||
|
||||
std::cout << "Sampling..";
|
||||
while (!terminated) {
|
||||
SDRThreadIQData data_in;
|
||||
|
||||
iqDataInQueue.load()->pop(data_in);
|
||||
|
||||
if (data_in.data.size()) {
|
||||
SDRThreadIQData dataOut;
|
||||
|
||||
dataOut.frequency = data_in.frequency;
|
||||
dataOut.bandwidth = data_in.bandwidth;
|
||||
dataOut.data = data_in.data;
|
||||
|
||||
for (int i = 0, iMax = dataOut.data.size() / 2; i < iMax; i++) {
|
||||
x.real = (float) dataOut.data[i * 2] / 127.0;
|
||||
x.imag = (float) dataOut.data[i * 2 + 1] / 127.0;
|
||||
|
||||
iirfilt_crcf_execute(dcFilter, x, &y);
|
||||
|
||||
dataOut.data[i * 2] = (signed char) floor(y.real * 127.0);
|
||||
dataOut.data[i * 2 + 1] = (signed char) floor(y.imag * 127.0);
|
||||
}
|
||||
|
||||
if (iqDataOutQueue != NULL) {
|
||||
iqDataOutQueue.load()->push(dataOut);
|
||||
}
|
||||
|
||||
if (iqVisualQueue != NULL) {
|
||||
iqVisualQueue.load()->push(dataOut);
|
||||
}
|
||||
|
||||
if (demodulators.size()) {
|
||||
DemodulatorThreadIQData demodDataOut;
|
||||
demodDataOut.frequency = data_in.frequency;
|
||||
demodDataOut.bandwidth = data_in.bandwidth;
|
||||
demodDataOut.data = data_in.data;
|
||||
|
||||
for (int i = 0, iMax = demodulators.size(); i < iMax; i++) {
|
||||
DemodulatorInstance *demod = demodulators[i];
|
||||
DemodulatorThreadInputQueue *demodQueue = demod->threadQueueDemod;
|
||||
demodQueue->push(demodDataOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SDRPostThread::terminate() {
|
||||
terminated = true;
|
||||
}
|
43
src/sdr/SDRPostThread.h
Normal file
43
src/sdr/SDRPostThread.h
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include "SDRThread.h"
|
||||
|
||||
class SDRPostThread {
|
||||
public:
|
||||
rtlsdr_dev_t *dev;
|
||||
|
||||
SDRPostThread();
|
||||
~SDRPostThread();
|
||||
|
||||
int enumerate_rtl();
|
||||
|
||||
void bindDemodulator(DemodulatorInstance *demod) {
|
||||
demodulators.push_back(demod);
|
||||
}
|
||||
|
||||
void threadMain();
|
||||
|
||||
void setIQDataInQueue(SDRThreadIQDataQueue* iqDataQueue) {
|
||||
iqDataInQueue = iqDataQueue;
|
||||
}
|
||||
void setIQDataOutQueue(SDRThreadIQDataQueue* iqDataQueue) {
|
||||
iqDataOutQueue = iqDataQueue;
|
||||
}
|
||||
void setIQVisualQueue(SDRThreadIQDataQueue *iqVisQueue) {
|
||||
iqVisualQueue = iqVisQueue;
|
||||
iqVisualQueue.load()->set_max_num_items(1);
|
||||
}
|
||||
|
||||
void terminate();
|
||||
protected:
|
||||
|
||||
uint32_t sample_rate;
|
||||
|
||||
std::atomic<SDRThreadIQDataQueue*> iqDataOutQueue;
|
||||
std::atomic<SDRThreadIQDataQueue*> iqDataInQueue;
|
||||
std::atomic<SDRThreadIQDataQueue*> iqVisualQueue;
|
||||
|
||||
std::vector<DemodulatorInstance *> demodulators;
|
||||
std::atomic<bool> terminated;
|
||||
iirfilt_crcf dcFilter;
|
||||
};
|
@ -4,7 +4,7 @@
|
||||
#include "CubicSDR.h"
|
||||
|
||||
SDRThread::SDRThread(SDRThreadCommandQueue* pQueue) :
|
||||
m_pQueue(pQueue), iqDataOutQueue(NULL), iqVisualQueue(NULL), terminated(false) {
|
||||
m_pQueue(pQueue), iqDataOutQueue(NULL), terminated(false) {
|
||||
dev = NULL;
|
||||
sample_rate = SRATE;
|
||||
}
|
||||
@ -110,7 +110,7 @@ void SDRThread::threadMain() {
|
||||
rtlsdr_set_sample_rate(dev, bandwidth);
|
||||
rtlsdr_set_center_freq(dev, frequency);
|
||||
rtlsdr_set_agc_mode(dev, 1);
|
||||
rtlsdr_set_offset_tuning(dev, 1);
|
||||
rtlsdr_set_offset_tuning(dev, 0);
|
||||
rtlsdr_reset_buffer(dev);
|
||||
|
||||
sample_rate = rtlsdr_get_sample_rate(dev);
|
||||
@ -122,13 +122,15 @@ void SDRThread::threadMain() {
|
||||
|
||||
std::cout << "Sampling..";
|
||||
while (!terminated) {
|
||||
if (!m_pQueue->empty()) {
|
||||
SDRThreadCommandQueue *cmdQueue = m_pQueue.load();
|
||||
|
||||
if (!cmdQueue->empty()) {
|
||||
bool freq_changed = false;
|
||||
float new_freq;
|
||||
|
||||
while (!m_pQueue->empty()) {
|
||||
while (!cmdQueue->empty()) {
|
||||
SDRThreadCommand command;
|
||||
m_pQueue->pop(command);
|
||||
cmdQueue->pop(command);
|
||||
|
||||
switch (command.cmd) {
|
||||
case SDRThreadCommand::SDR_THREAD_CMD_TUNE:
|
||||
@ -162,26 +164,8 @@ void SDRThread::threadMain() {
|
||||
dataOut.data = new_buffer;
|
||||
|
||||
if (iqDataOutQueue != NULL) {
|
||||
iqDataOutQueue->push(dataOut);
|
||||
iqDataOutQueue.load()->push(dataOut);
|
||||
}
|
||||
|
||||
if (iqVisualQueue != NULL) {
|
||||
iqVisualQueue->push(dataOut);
|
||||
}
|
||||
|
||||
if (demodulators.size()) {
|
||||
DemodulatorThreadIQData demodDataOut;
|
||||
demodDataOut.frequency = frequency;
|
||||
demodDataOut.bandwidth = bandwidth;
|
||||
demodDataOut.data = new_buffer;
|
||||
|
||||
for (int i = 0, iMax = demodulators.size(); i < iMax; i++) {
|
||||
DemodulatorInstance *demod = demodulators[i];
|
||||
DemodulatorThreadInputQueue *demodQueue = demod->threadQueueDemod;
|
||||
demodQueue->push(demodDataOut);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -66,28 +66,17 @@ public:
|
||||
|
||||
int enumerate_rtl();
|
||||
|
||||
void bindDemodulator(DemodulatorInstance *demod) {
|
||||
demodulators.push_back(demod);
|
||||
}
|
||||
|
||||
void threadMain();
|
||||
|
||||
void setIQDataOutQueue(SDRThreadIQDataQueue* iqDataQueue) {
|
||||
iqDataOutQueue = iqDataQueue;
|
||||
}
|
||||
void setIQVisualQueue(SDRThreadIQDataQueue *iqVisQueue) {
|
||||
iqVisualQueue = iqVisQueue;
|
||||
iqVisualQueue->set_max_num_items(1);
|
||||
}
|
||||
|
||||
void terminate();
|
||||
protected:
|
||||
|
||||
uint32_t sample_rate;
|
||||
SDRThreadCommandQueue* m_pQueue;
|
||||
SDRThreadIQDataQueue* iqDataOutQueue;
|
||||
SDRThreadIQDataQueue* iqVisualQueue;
|
||||
std::atomic<SDRThreadCommandQueue*> m_pQueue;
|
||||
std::atomic<SDRThreadIQDataQueue*> iqDataOutQueue;
|
||||
|
||||
std::vector<DemodulatorInstance *> demodulators;
|
||||
std::atomic<bool> terminated;
|
||||
};
|
||||
|
@ -117,19 +117,20 @@ void SpectrumCanvas::setData(std::vector<signed char> *data) {
|
||||
fft_result_maa.resize(FFT_SIZE);
|
||||
}
|
||||
|
||||
for (int j = 0; j < 2; j++) {
|
||||
for (int i = 0, iMax = FFT_SIZE / 2; i < iMax; i++) {
|
||||
double a = out[i][0];
|
||||
double b = out[i][1];
|
||||
double c = sqrt(a * a + b * b);
|
||||
int n;
|
||||
for (int i = 0, iMax = FFT_SIZE / 2; i < iMax; i++) {
|
||||
n = (i == 0)?1:i;
|
||||
double a = out[n][0];
|
||||
double b = out[n][1];
|
||||
double c = sqrt(a * a + b * b);
|
||||
|
||||
double x = out[FFT_SIZE / 2 + i][0];
|
||||
double y = out[FFT_SIZE / 2 + i][1];
|
||||
double z = sqrt(x * x + y * y);
|
||||
n = (i == FFT_SIZE/2)?(FFT_SIZE/2+1):i;
|
||||
double x = out[FFT_SIZE / 2 + n][0];
|
||||
double y = out[FFT_SIZE / 2 + n][1];
|
||||
double z = sqrt(x * x + y * y);
|
||||
|
||||
fft_result[i] = (z);
|
||||
fft_result[FFT_SIZE / 2 + i] = (c);
|
||||
}
|
||||
fft_result[i] = (z);
|
||||
fft_result[FFT_SIZE / 2 + i] = (c);
|
||||
}
|
||||
|
||||
float time_slice = (float) SRATE / (float) (BUF_SIZE / 2);
|
||||
|
@ -85,13 +85,13 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
|
||||
switch (event.GetKeyCode()) {
|
||||
case WXK_RIGHT:
|
||||
freq = wxGetApp().getFrequency();
|
||||
freq += SRATE/2;
|
||||
freq += SRATE / 2;
|
||||
wxGetApp().setFrequency(freq);
|
||||
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
|
||||
break;
|
||||
case WXK_LEFT:
|
||||
freq = wxGetApp().getFrequency();
|
||||
freq -= SRATE/2;
|
||||
freq -= SRATE / 2;
|
||||
wxGetApp().setFrequency(freq);
|
||||
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
|
||||
break;
|
||||
@ -129,19 +129,20 @@ void WaterfallCanvas::setData(std::vector<signed char> *data) {
|
||||
fft_result_maa.resize(FFT_SIZE);
|
||||
}
|
||||
|
||||
for (int j = 0; j < 2; j++) {
|
||||
for (int i = 0, iMax = FFT_SIZE / 2; i < iMax; i++) {
|
||||
double a = out[i][0];
|
||||
double b = out[i][1];
|
||||
double c = sqrt(a * a + b * b);
|
||||
int n;
|
||||
for (int i = 0, iMax = FFT_SIZE / 2; i < iMax; i++) {
|
||||
n = (i == 0) ? 1 : i;
|
||||
double a = out[n][0];
|
||||
double b = out[n][1];
|
||||
double c = sqrt(a * a + b * b);
|
||||
|
||||
double x = out[FFT_SIZE / 2 + i][0];
|
||||
double y = out[FFT_SIZE / 2 + i][1];
|
||||
double z = sqrt(x * x + y * y);
|
||||
n = (i == FFT_SIZE / 2) ? (FFT_SIZE / 2 + 1) : i;
|
||||
double x = out[FFT_SIZE / 2 + n][0];
|
||||
double y = out[FFT_SIZE / 2 + n][1];
|
||||
double z = sqrt(x * x + y * y);
|
||||
|
||||
fft_result[i] = (z);
|
||||
fft_result[FFT_SIZE / 2 + i] = (c);
|
||||
}
|
||||
fft_result[i] = (z);
|
||||
fft_result[FFT_SIZE / 2 + i] = (c);
|
||||
}
|
||||
|
||||
float time_slice = (float) SRATE / (float) (BUF_SIZE / 2);
|
||||
@ -192,7 +193,7 @@ void WaterfallCanvas::mouseMoved(wxMouseEvent& event) {
|
||||
|
||||
if (mTracker.mouseDown()) {
|
||||
if (demod && mTracker.getDeltaMouseY()) {
|
||||
int bwDiff = (int)(mTracker.getDeltaMouseY() * 100000.0);
|
||||
int bwDiff = (int) (mTracker.getDeltaMouseY() * 100000.0);
|
||||
|
||||
if (!demodBW) {
|
||||
demodBW = demod->getParams().bandwidth;
|
||||
@ -249,7 +250,7 @@ void WaterfallCanvas::mouseReleased(wxMouseEvent& event) {
|
||||
|
||||
DemodulatorInstance *demod = wxGetApp().getDemodTest();
|
||||
|
||||
int freq = center_freq - (int)(0.5 * (float)SRATE) + (int)((float)pos * (float)SRATE);
|
||||
int freq = center_freq - (int) (0.5 * (float) SRATE) + (int) ((float) pos * (float) SRATE);
|
||||
|
||||
DemodulatorThreadCommand command;
|
||||
command.cmd = DemodulatorThreadCommand::SDR_THREAD_CMD_SET_FREQUENCY;
|
||||
|
Loading…
Reference in New Issue
Block a user