mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2025-09-02 13:17:48 -04:00
Now showing 2.5MHz bandwidth over FM ranges
Moves frequency back/forth over the FM range
This commit is contained in:
parent
7fe286cf0c
commit
eb4e10140a
@ -91,7 +91,7 @@ SET (cubicsdr_headers
|
|||||||
|
|
||||||
add_executable(CubicSDR ${cubicsdr_sources} ${cubicsdr_headers})
|
add_executable(CubicSDR ${cubicsdr_sources} ${cubicsdr_headers})
|
||||||
|
|
||||||
target_link_libraries(CubicSDR rtlsdr fftw3-3 ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES})
|
target_link_libraries(CubicSDR rtlsdr fftw3 ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES})
|
||||||
# cubicvr2 glfw ${GLFW_LIBRARIES} ${OPENAL_LIBRARY}
|
# cubicvr2 glfw ${GLFW_LIBRARIES} ${OPENAL_LIBRARY}
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,8 +38,8 @@ AppFrame::AppFrame() :
|
|||||||
SetMenuBar(menuBar);
|
SetMenuBar(menuBar);
|
||||||
|
|
||||||
CreateStatusBar();
|
CreateStatusBar();
|
||||||
|
SetClientSize(1280, 400);
|
||||||
SetClientSize(400, 400);
|
Centre();
|
||||||
Show();
|
Show();
|
||||||
|
|
||||||
// static const int attribs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 };
|
// static const int attribs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 };
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define BUF_SIZE (16 * 32 * 512)
|
#define BUF_SIZE ((16 * 32 * 512)/4)
|
||||||
#define SRATE 2500000
|
#define SRATE 2500000
|
||||||
#define FFT_SIZE BUF_SIZE/2
|
#define FFT_SIZE 8192
|
||||||
|
|
||||||
|
@ -61,36 +61,19 @@ PrimaryGLContext::PrimaryGLContext(wxGLCanvas *canvas) :
|
|||||||
CheckGLError();
|
CheckGLError();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrimaryGLContext::PlotIQ(std::vector<float> &i_points, std::vector<float> &q_points) {
|
void PrimaryGLContext::Plot(std::vector<float> &points) {
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(0.0f, 0.5f, 0.0f);
|
glTranslatef(-1.0f, -0.9f, 0.0f);
|
||||||
if (q_points.size()) {
|
glScalef(2.0f, 1.8f, 1.0f);
|
||||||
// glScalef(10.0f, 1.0f, 1.0f);
|
if (points.size()) {
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
glVertexPointer(2, GL_FLOAT, 0, &q_points[0]);
|
glVertexPointer(2, GL_FLOAT, 0, &points[0]);
|
||||||
glDrawArrays(GL_LINE_STRIP, 0, q_points.size() / 2);
|
glDrawArrays(GL_LINE_STRIP, 0, points.size() / 2);
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
|
||||||
} else {
|
|
||||||
glBegin(GL_LINE_STRIP);
|
|
||||||
glColor3f(1.0f, 1.0f, 1.0f);
|
|
||||||
glVertex3f(-1.0f, 0.0f, 0.0f);
|
|
||||||
glVertex3f(1.0f, 0.0f, 0.0f);
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
glPopMatrix();
|
|
||||||
|
|
||||||
glPushMatrix();
|
|
||||||
glTranslatef(0.0f, -0.5f, 0.0f);
|
|
||||||
if (i_points.size()) {
|
|
||||||
// glScalef(10.0f, 1.0f, 1.0f);
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glVertexPointer(2, GL_FLOAT, 0, &i_points[0]);
|
|
||||||
glDrawArrays(GL_LINE_STRIP, 0, i_points.size() / 2);
|
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
} else {
|
} else {
|
||||||
glBegin(GL_LINE_STRIP);
|
glBegin(GL_LINE_STRIP);
|
||||||
@ -119,10 +102,11 @@ TestGLCanvas::TestGLCanvas(wxWindow *parent, int *attribList) :
|
|||||||
int out_block_size = FFT_SIZE;
|
int out_block_size = FFT_SIZE;
|
||||||
|
|
||||||
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * in_block_size);
|
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * in_block_size);
|
||||||
out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * out_block_size);
|
out[0] = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * out_block_size);
|
||||||
plan = fftw_plan_dft_1d(out_block_size, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
|
out[1] = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * out_block_size);
|
||||||
|
plan[0] = fftw_plan_dft_1d(out_block_size, in, out[0], FFTW_FORWARD, FFTW_MEASURE);
|
||||||
}
|
plan[1] = fftw_plan_dft_1d(out_block_size, in, out[1], FFTW_BACKWARD, FFTW_MEASURE);
|
||||||
|
}
|
||||||
|
|
||||||
void TestGLCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
void TestGLCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
||||||
wxPaintDC dc(this);
|
wxPaintDC dc(this);
|
||||||
@ -131,7 +115,7 @@ void TestGLCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
|||||||
PrimaryGLContext& canvas = wxGetApp().GetContext(this);
|
PrimaryGLContext& canvas = wxGetApp().GetContext(this);
|
||||||
glViewport(0, 0, ClientSize.x, ClientSize.y);
|
glViewport(0, 0, ClientSize.x, ClientSize.y);
|
||||||
|
|
||||||
canvas.PlotIQ(i_points, q_points);
|
canvas.Plot(points);
|
||||||
|
|
||||||
SwapBuffers();
|
SwapBuffers();
|
||||||
}
|
}
|
||||||
@ -161,50 +145,54 @@ void TestGLCanvas::setData(std::vector<signed char> *data) {
|
|||||||
|
|
||||||
if (data && data->size()) {
|
if (data && data->size()) {
|
||||||
|
|
||||||
if (i_points.size() < FFT_SIZE*2) {
|
if (points.size() < FFT_SIZE*4) {
|
||||||
i_points.resize(FFT_SIZE*2);
|
points.resize(FFT_SIZE*4);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < BUF_SIZE / 2; i++) {
|
for (int i = 0; i < BUF_SIZE / 2; i++) {
|
||||||
in[i][0] = (float) (*data)[i * 2] / 127.0f;
|
in[i][0] = (double) (*data)[i * 2] / 127.0f;
|
||||||
in[i][1] = (float) (*data)[i * 2 + 1] / 127.0f;
|
in[i][1] = (double) (*data)[i * 2 + 1] / 127.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for (int i = 0; i < BUF_SIZE / 2; i++) {
|
fftw_execute(plan[0]);
|
||||||
// double ang = (M_PI / (float) BUF_SIZE) * (float) i;
|
fftw_execute(plan[1]);
|
||||||
// double w = 0.5 * (1.0 - cos(ang));
|
|
||||||
//
|
|
||||||
// in[i][0] *= w;
|
|
||||||
// in[i][1] *= w;
|
|
||||||
// }
|
|
||||||
|
|
||||||
fftw_execute(plan);
|
double result[FFT_SIZE*2];
|
||||||
|
double fft_floor, fft_ceil;
|
||||||
|
|
||||||
float result[FFT_SIZE];
|
for (int j = 0; j < 2; j++) {
|
||||||
float fft_floor, fft_ceil;
|
for (int i = 0, iMax = FFT_SIZE; i < iMax; i++) {
|
||||||
|
double a = out[j][i][0];
|
||||||
|
double b = out[j][i][1];
|
||||||
|
|
||||||
for (int i = 0, iMax = FFT_SIZE; i < iMax; i++) {
|
double c = sqrt(a*a+b*b);
|
||||||
double a = out[i][0];
|
if (i==1) {
|
||||||
double b = out[i][1];
|
fft_floor=fft_ceil=c;
|
||||||
|
} else if (i<FFT_SIZE-1) {
|
||||||
|
if (c<fft_floor) {
|
||||||
|
fft_floor = c;
|
||||||
|
}
|
||||||
|
if (c>fft_ceil) {
|
||||||
|
fft_ceil = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double c = sqrt(a*a+b*b);
|
if (j) {
|
||||||
if (i==1) {
|
result[FFT_SIZE*2 - 1 - i] = c;
|
||||||
fft_floor=fft_ceil=c;
|
} else {
|
||||||
} else {
|
result[FFT_SIZE*2 - 1 - (FFT_SIZE+(FFT_SIZE-1-i))] = c;
|
||||||
if (c<fft_floor) {
|
}
|
||||||
fft_floor = c;
|
|
||||||
}
|
}
|
||||||
if (c>fft_ceil) {
|
}
|
||||||
fft_ceil = c;
|
|
||||||
}
|
if (fft_ceil-fft_floor < 1.0) {
|
||||||
}
|
fft_ceil = fft_floor + 1.0;
|
||||||
|
|
||||||
result[i] = c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0, iMax = FFT_SIZE; i < iMax; i++) {
|
for (int i = 0, iMax = FFT_SIZE*2; i < iMax; i++) {
|
||||||
i_points[i * 2 + 1] = (result[i]-fft_floor)/(fft_ceil-fft_floor);
|
points[i * 2 + 1] = (result[i]-fft_floor)/(fft_ceil-fft_floor);
|
||||||
i_points[i * 2] = 2.0f * ((float) i / (float) iMax) - 1.0f;
|
points[i * 2] = ((double) i / (double) iMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ class PrimaryGLContext : public wxGLContext
|
|||||||
public:
|
public:
|
||||||
PrimaryGLContext(wxGLCanvas *canvas);
|
PrimaryGLContext(wxGLCanvas *canvas);
|
||||||
|
|
||||||
void PlotIQ(std::vector<float> &i_points, std::vector<float> &q_points);
|
void Plot(std::vector<float> &points);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// textures for the cube faces
|
// textures for the cube faces
|
||||||
@ -26,11 +26,10 @@ public:
|
|||||||
|
|
||||||
void setData(std::vector<signed char> *data);
|
void setData(std::vector<signed char> *data);
|
||||||
|
|
||||||
std::vector<float> i_points;
|
std::vector<float> points;
|
||||||
std::vector<float> q_points;
|
|
||||||
|
|
||||||
fftw_complex *in, *out;
|
fftw_complex *in, *out[2];
|
||||||
fftw_plan plan;
|
fftw_plan plan[2];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void OnPaint(wxPaintEvent& event);
|
void OnPaint(wxPaintEvent& event);
|
||||||
|
@ -87,9 +87,9 @@ wxThread::ExitCode SDRThread::Entry() {
|
|||||||
|
|
||||||
enumerate_rtl();
|
enumerate_rtl();
|
||||||
|
|
||||||
rtlsdr_open(&dev, 3);
|
rtlsdr_open(&dev, 0);
|
||||||
rtlsdr_set_sample_rate(dev, SRATE);
|
rtlsdr_set_sample_rate(dev, SRATE);
|
||||||
rtlsdr_set_center_freq(dev, 105700000-(SRATE/2));
|
rtlsdr_set_center_freq(dev, 98000000);
|
||||||
rtlsdr_set_agc_mode(dev, 1);
|
rtlsdr_set_agc_mode(dev, 1);
|
||||||
rtlsdr_set_offset_tuning(dev, 1);
|
rtlsdr_set_offset_tuning(dev, 1);
|
||||||
rtlsdr_reset_buffer(dev);
|
rtlsdr_reset_buffer(dev);
|
||||||
@ -105,6 +105,12 @@ wxThread::ExitCode SDRThread::Entry() {
|
|||||||
while (!TestDestroy()) {
|
while (!TestDestroy()) {
|
||||||
|
|
||||||
rtlsdr_read_sync(dev, buf, BUF_SIZE, &n_read);
|
rtlsdr_read_sync(dev, buf, BUF_SIZE, &n_read);
|
||||||
|
// move around
|
||||||
|
long freq = 98000000+(20000000)*sin(seconds/50.0);
|
||||||
|
rtlsdr_set_center_freq(dev, freq);
|
||||||
|
|
||||||
|
std::cout << "Frequency: " << freq << std::endl;
|
||||||
|
|
||||||
if (!TestDestroy()) {
|
if (!TestDestroy()) {
|
||||||
std::vector<signed char> *new_buffer = new std::vector<signed char>();
|
std::vector<signed char> *new_buffer = new std::vector<signed char>();
|
||||||
|
|
||||||
@ -115,7 +121,7 @@ wxThread::ExitCode SDRThread::Entry() {
|
|||||||
double time_slice = (double)n_read/(double)sample_rate;
|
double time_slice = (double)n_read/(double)sample_rate;
|
||||||
seconds += time_slice;
|
seconds += time_slice;
|
||||||
|
|
||||||
std::cout << "Time Slice: " << time_slice << std::endl;
|
// std::cout << "Time Slice: " << time_slice << std::endl;
|
||||||
if (!TestDestroy()) {
|
if (!TestDestroy()) {
|
||||||
wxThreadEvent event(wxEVT_THREAD, EVENT_SDR_INPUT);
|
wxThreadEvent event(wxEVT_THREAD, EVENT_SDR_INPUT);
|
||||||
event.SetPayload(new_buffer);
|
event.SetPayload(new_buffer);
|
||||||
@ -124,7 +130,6 @@ wxThread::ExitCode SDRThread::Entry() {
|
|||||||
delete new_buffer;
|
delete new_buffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->Sleep(1);
|
|
||||||
}
|
}
|
||||||
std::cout << std::endl << "Done." << std::endl << std::endl;
|
std::cout << std::endl << "Done." << std::endl << std::endl;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user