Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addition of waterfall and separation of visual components #3

Merged
merged 7 commits into from
Nov 16, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ SET (cubicsdr_sources
src/SDRThreadQueue.cpp
src/SDRThreadTask.cpp
src/Demodulator.cpp
src/Gradient.cpp
src/visual/ScopeCanvas.cpp
src/visual/ScopeContext.cpp
src/visual/SpectrumCanvas.cpp
src/visual/SpectrumContext.cpp
src/visual/WaterfallCanvas.cpp
src/visual/WaterfallContext.cpp
)

SET (cubicsdr_headers
Expand All @@ -103,7 +110,18 @@ SET (cubicsdr_headers
src/SDRThreadQueue.h
src/SDRThreadTask.h
src/Demodulator.h
src/Gradient.h
src/visual/ScopeCanvas.h
src/visual/ScopeContext.h
src/visual/SpectrumCanvas.h
src/visual/SpectrumContext.h
src/visual/WaterfallCanvas.h
src/visual/WaterfallContext.h
)

include_directories ( ${PROJECT_SOURCE_DIR}/src/visual
${PROJECT_SOURCE_DIR}/src )

#configure_files(${PROJECT_SOURCE_DIR}/shaders ${PROJECT_BINARY_DIR}/shaders COPYONLY)
#configure_files(${PROJECT_SOURCE_DIR}/png ${PROJECT_BINARY_DIR}/png COPYONLY)

Expand Down
55 changes: 34 additions & 21 deletions src/AppFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,18 @@ wxEND_EVENT_TABLE()
AppFrame::AppFrame() :
wxFrame(NULL, wxID_ANY, wxT("CubicSDR")), frequency(DEFAULT_FREQ) {

canvas = new TestGLCanvas(this, NULL);
wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);

scopeCanvas = new ScopeCanvas(this, NULL);
vbox->Add(scopeCanvas, 1, wxEXPAND | wxALL, 0);
vbox->AddSpacer(2);
spectrumCanvas = new SpectrumCanvas(this, NULL);
vbox->Add(spectrumCanvas, 1, wxEXPAND | wxALL, 0);
vbox->AddSpacer(2);
waterfallCanvas = new WaterfallCanvas(this, NULL);
vbox->Add(waterfallCanvas, 4, wxEXPAND | wxALL, 0);

this->SetSizer(vbox);

// SetIcon(wxICON(sample));

Expand Down Expand Up @@ -66,13 +77,6 @@ AppFrame::AppFrame() :
}

AppFrame::~AppFrame() {
delete t_SDR;
// delete t_IQBuffer;
delete m_pQueue;
}

void AppFrame::OnClose(wxCommandEvent& WXUNUSED(event)) {

{
wxCriticalSectionLocker enter(m_pThreadCS);
if (t_SDR) {
Expand All @@ -84,16 +88,24 @@ void AppFrame::OnClose(wxCommandEvent& WXUNUSED(event)) {
}
}

{
wxCriticalSectionLocker enter(m_pThreadCS);
if (t_IQBuffer) {
wxMessageOutputDebug().Printf("CubicSDR: deleting thread");
if (t_IQBuffer->Delete() != wxTHREAD_NO_ERROR) {
wxLogError
("Can't delete the thread!");
}
}
}
// {
// wxCriticalSectionLocker enter(m_pThreadCS);
// if (t_IQBuffer) {
// wxMessageOutputDebug().Printf("CubicSDR: deleting thread");
// if (t_IQBuffer->Delete() != wxTHREAD_NO_ERROR) {
// wxLogError
// ("Can't delete the thread!");
// }
// }
// }

delete t_SDR;
// delete t_IQBuffer;
delete m_pQueue;
}

void AppFrame::OnClose(wxCommandEvent& WXUNUSED(event)) {

// true is to force the frame to close
Close(true);
}
Expand All @@ -105,9 +117,10 @@ void AppFrame::OnNewWindow(wxCommandEvent& WXUNUSED(event)) {
void AppFrame::OnEventInput(wxThreadEvent& event) {
std::vector<signed char> *new_buffer = event.GetPayload<std::vector<signed char> *>();

// std::cout << "Got IQ buffer, length: " << new_buffer->size() << std::endl;

canvas->setData(new_buffer);
test_demod.writeBuffer(new_buffer);
scopeCanvas->setWaveformPoints(test_demod.waveform_points);
spectrumCanvas->setData(new_buffer);
waterfallCanvas->setData(new_buffer);

delete new_buffer;
}
Expand Down
11 changes: 10 additions & 1 deletion src/AppFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
#include "wx/frame.h"
#include "PrimaryGLContext.h"
#include "SDRThread.h"
#include "ScopeCanvas.h"
#include "SpectrumCanvas.h"
#include "WaterfallCanvas.h"
#include "Demodulator.h"

// Define a new frame type
class AppFrame: public wxFrame {
Expand All @@ -19,12 +23,17 @@ class AppFrame: public wxFrame {
void OnNewWindow(wxCommandEvent& event);
void OnIdle(wxIdleEvent& event);

TestGLCanvas *canvas;
ScopeCanvas *scopeCanvas;
SpectrumCanvas *spectrumCanvas;
WaterfallCanvas *waterfallCanvas;
SDRThread *t_SDR;
IQBufferThread *t_IQBuffer;
wxCriticalSection m_pThreadCS;
SDRThreadQueue* m_pQueue;
unsigned int frequency;

Demodulator test_demod;

// event table
wxDECLARE_EVENT_TABLE();
};
2 changes: 1 addition & 1 deletion src/CubicSDR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ int CubicSDR::OnExit() {
PrimaryGLContext& CubicSDR::GetContext(wxGLCanvas *canvas) {
PrimaryGLContext *glContext;
if (!m_glContext) {
m_glContext = new PrimaryGLContext(canvas);
m_glContext = new PrimaryGLContext(canvas, NULL);
}
glContext = m_glContext;

Expand Down
6 changes: 3 additions & 3 deletions src/CubicSDRDefs.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#pragma once

#define BUF_SIZE (16 * 32 * 256)
#define SRATE 2500000
#define FFT_SIZE 8192
#define SRATE 2000000
#define FFT_SIZE 2048

#define DEFAULT_FREQ 107500000
#define DEFAULT_FREQ 98900000

47 changes: 36 additions & 11 deletions src/Demodulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ static int patestCallback(const void *inputBuffer, void *outputBuffer, unsigned

Demodulator::Demodulator() {

bandwidth = 800000;
bandwidth = 200000;
resample_ratio = (float) (bandwidth) / (float) SRATE;
audio_frequency = 44100;
audio_resample_ratio = (float) (audio_frequency) / (float) bandwidth;
wbfm_frequency = 100000;
wbfm_resample_ratio = (float) (wbfm_frequency) / (float) bandwidth;
audio_frequency = 48000;
audio_resample_ratio = (float) (audio_frequency) / (float) wbfm_frequency;

PaError err;
err = Pa_Initialize();
Expand Down Expand Up @@ -83,15 +85,15 @@ Demodulator::Demodulator() {

stream = NULL;

err = Pa_OpenStream(&stream, NULL, &outputParameters, 44100, 256, paClipOff, &patestCallback, this);
err = Pa_OpenStream(&stream, NULL, &outputParameters, audio_frequency, 1024, paClipOff, &patestCallback, this);

err = Pa_StartStream(stream);
if (err != paNoError) {
std::cout << "Error starting stream: " << Pa_GetErrorText(err) << std::endl;
std::cout << "\tPortAudio error: " << Pa_GetErrorText(err) << std::endl;
}

float fc = 0.5f * (bandwidth / SRATE); // filter cutoff frequency
float fc = 0.5f * ((float)bandwidth / (float)SRATE) * 0.75; // filter cutoff frequency
float ft = 0.05f; // filter transition
float As = 60.0f; // stop-band attenuation [dB]
float mu = 0.0f; // fractional timing offset
Expand All @@ -103,14 +105,22 @@ Demodulator::Demodulator() {

fir_filter = firfilt_crcf_create(h, h_len);

h_len = estimate_req_filter_len(ft, As);
liquid_firdes_kaiser(h_len, 32000.0/(float)wbfm_frequency, As, mu, h);

fir_audio_filter = firfilt_crcf_create(h, h_len);

// create multi-stage arbitrary resampler object
resampler = msresamp_crcf_create(resample_ratio, As);
msresamp_crcf_print(resampler);

wbfm_resampler = msresamp_crcf_create(wbfm_resample_ratio, As);
msresamp_crcf_print(wbfm_resampler);

audio_resampler = msresamp_crcf_create(audio_resample_ratio, As);
msresamp_crcf_print(audio_resampler);

float kf = 0.1f; // modulation factor
float kf = 0.75; // modulation factor

fdem = freqdem_create(kf);
freqdem_print(fdem);
Expand Down Expand Up @@ -166,17 +176,32 @@ void Demodulator::writeBuffer(std::vector<signed char> *data) {
}
}

int audio_out_size = ceil((float) (num_written) * audio_resample_ratio);

int wbfm_out_size = ceil((float) (num_written) * wbfm_resample_ratio);
liquid_float_complex resampled_wbfm_output[wbfm_out_size];

unsigned int num_wbfm_written;
msresamp_crcf_execute(wbfm_resampler, resampled_output, num_written, resampled_wbfm_output, &num_wbfm_written);


for (int i = 0; i < num_wbfm_written; i++) {
firfilt_crcf_push(fir_audio_filter, resampled_wbfm_output[i]);
firfilt_crcf_execute(fir_audio_filter, &resampled_wbfm_output[i]);
}

int audio_out_size = ceil((float) (num_wbfm_written) * audio_resample_ratio);
liquid_float_complex resampled_audio_output[audio_out_size];

unsigned int num_audio_written; // number of values written to buffer
msresamp_crcf_execute(audio_resampler, resampled_output, num_written, resampled_audio_output, &num_audio_written);
unsigned int num_audio_written;
msresamp_crcf_execute(audio_resampler, resampled_wbfm_output, num_wbfm_written, resampled_audio_output, &num_audio_written);

std::vector<float> *newBuffer = new std::vector<float>;
newBuffer->resize(num_audio_written * 2);
for (int i = 0; i < num_audio_written; i++) {
(*newBuffer)[i * 2] = resampled_audio_output[i].real;
(*newBuffer)[i * 2 + 1] = resampled_audio_output[i].real;
liquid_float_complex y = resampled_audio_output[i];

(*newBuffer)[i * 2] = y.real;
(*newBuffer)[i * 2 + 1] = y.real;
}

audio_queue.push(newBuffer);
Expand Down
14 changes: 11 additions & 3 deletions src/Demodulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,22 @@ class Demodulator {

private:
firfilt_crcf fir_filter;
firfilt_crcf fir_audio_filter;

unsigned int bandwidth;

msresamp_crcf resampler;
msresamp_crcf audio_resampler;
float resample_ratio;
unsigned int bandwidth;
unsigned int audio_frequency;

msresamp_crcf wbfm_resampler;
float wbfm_resample_ratio;
unsigned int wbfm_frequency;

msresamp_crcf audio_resampler;
float audio_resample_ratio;

unsigned int audio_frequency;

PaStreamParameters outputParameters;
PaStream *stream;
freqdem fdem;
Expand Down
75 changes: 75 additions & 0 deletions src/Gradient.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include "Gradient.h"

Gradient::Gradient() {

}

void Gradient::addColor(GradientColor c) {
colors.push_back(c);
}

std::vector<float> &Gradient::getRed() {
return r_val;
}

std::vector<float> &Gradient::getGreen() {
return g_val;
}

std::vector<float> &Gradient::getBlue() {
return b_val;
}

void Gradient::generate(unsigned int len) {
int chunk_size = len / (colors.size() - 1);

int p = 0;
r_val.resize(len);
g_val.resize(len);
b_val.resize(len);

for (unsigned int j = 0, jMax = colors.size() - 1; j < jMax; j++) {
if (chunk_size * (jMax + 1) < len && j == jMax - 1) {
chunk_size += len - chunk_size * (jMax + 1);
}

for (unsigned int i = 0; i < chunk_size; i++) {
float idx = (float) (i) / (float) chunk_size;

float r1 = colors[j].r;
float g1 = colors[j].g;
float b1 = colors[j].b;

float r2 = colors[j + 1].r;
float g2 = colors[j + 1].g;
float b2 = colors[j + 1].b;

float r = r1 + (r2 - r1) * idx;
float g = g1 + (g2 - g1) * idx;
float b = b1 + (b2 - b1) * idx;

if (r < 0.0)
r = 0.0;
if (r > 1.0)
r = 1.0;
if (g < 0.0)
g = 0.0;
if (g > 1.0)
g = 1.0;
if (b < 0.0)
b = 0.0;
if (b > 1.0)
b = 1.0;

r_val[p] = r;
g_val[p] = g;
b_val[p] = b;

p++;
}
}
}

Gradient::~Gradient() {

}
33 changes: 33 additions & 0 deletions src/Gradient.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once

#include <vector>

class GradientColor {
public:
float r, g, b;
float w;

GradientColor(float r_in, float g_in, float b_in) :
r(r_in), g(g_in), b(b_in), w(1) {
}
};

class Gradient {
public:
Gradient();

void addColor(GradientColor c);

std::vector<float> &getRed();;
std::vector<float> &getGreen();
std::vector<float> &getBlue();

void generate(unsigned int len);

~Gradient();
private:
std::vector<GradientColor> colors;
std::vector<float> r_val;
std::vector<float> g_val;
std::vector<float> b_val;
};
Loading