diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index eb1046f..3730bce 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -66,13 +66,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) { @@ -94,6 +87,15 @@ void AppFrame::OnClose(wxCommandEvent& WXUNUSED(event)) { } } } + + 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); } diff --git a/src/CubicSDRDefs.h b/src/CubicSDRDefs.h index 62c2d3a..b1d55e3 100644 --- a/src/CubicSDRDefs.h +++ b/src/CubicSDRDefs.h @@ -2,7 +2,7 @@ #define BUF_SIZE (16 * 32 * 256) #define SRATE 2500000 -#define FFT_SIZE 4096 +#define FFT_SIZE 2048 #define DEFAULT_FREQ 107500000 diff --git a/src/Gradient.h b/src/Gradient.h index ce3b974..6a529cc 100644 --- a/src/Gradient.h +++ b/src/Gradient.h @@ -21,21 +21,34 @@ public: void addColor(GradientColor c) { colors.push_back(c); } - - void generate(std::vector *out, unsigned int len) { + + std::vector &getRed() { + return r_val; + } + + std::vector &getGreen() { + return g_val; + } + + std::vector &getBlue() { + return b_val; + } + + void generate(unsigned int len) { int chunk_size = len/(colors.size()-1); - out->resize(len*3); - 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*3 < len && j == jMax-1) { - chunk_size += len-chunk_size*3; + 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+1)/(float)chunk_size; + float idx = (float)(i)/(float)chunk_size; float r1 = colors[j].r; float g1 = colors[j].g; @@ -49,9 +62,16 @@ public: float g = g1 + (g2-g1) * idx; float b = b1 + (b2-b1) * idx; - (*out)[p*3] = (unsigned char)(r*255.0); - (*out)[p*3+1] = (unsigned char)(g*255.0); - (*out)[p*3+2] = (unsigned char)(b*255.0); + 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++; } @@ -63,4 +83,7 @@ public: } private: std::vector colors; -}; \ No newline at end of file + std::vector r_val; + std::vector g_val; + std::vector b_val; +}; diff --git a/src/PrimaryGLContext.cpp b/src/PrimaryGLContext.cpp index 58d7a03..8ffa11b 100644 --- a/src/PrimaryGLContext.cpp +++ b/src/PrimaryGLContext.cpp @@ -59,17 +59,57 @@ PrimaryGLContext::PrimaryGLContext(wxGLCanvas *canvas) : glMatrixMode(GL_PROJECTION); glLoadIdentity(); + glGenTextures(1, &waterfall); + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, waterfall); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + // glTexImage2D(GL_TEXTURE_2D,0,GL_INTENSITY,FFT_SIZE,NUM_WATERFALL_LINES,0,GL_COLOR_INDEX,GL_UNSIGNED_BYTE,(GLvoid *)waterfall_tex); + float clr[16] = { 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 255 }; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + + + grad.addColor(GradientColor(0, 0, 0)); + grad.addColor(GradientColor(0, 0, 1.0)); + grad.addColor(GradientColor(0, 1.0, 0)); + grad.addColor(GradientColor(1.0, 1.0, 0)); + grad.addColor(GradientColor(1.0, 0.2, 0.0)); + + grad.generate(256); + // glTexImage2D(GL_TEXTURE_2D,0,GL_INTENSITY,FFT_SIZE,NUM_WATERFALL_LINES,0,GL_COLOR_INDEX,GL_UNSIGNED_BYTE,(GLvoid *)waterfall_tex); + + unsigned char rmap[256]; + unsigned char gmap[256]; + unsigned char bmap[256]; + + glPixelTransferi(GL_MAP_COLOR, GL_TRUE); + glPixelMapfv(GL_PIXEL_MAP_I_TO_R, 256, &(grad.getRed())[0]); + glPixelMapfv(GL_PIXEL_MAP_I_TO_G, 256, &(grad.getGreen())[0]); + glPixelMapfv(GL_PIXEL_MAP_I_TO_B, 256, &(grad.getBlue())[0]); + CheckGLError(); } -void PrimaryGLContext::Plot(std::vector &points, std::vector &points2, GLuint tex) { +void PrimaryGLContext::Plot(std::vector &points, std::vector &points2, unsigned char *waterfall_tex) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); + glBindTexture(GL_TEXTURE_2D, waterfall); +// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, FFT_SIZE, NUM_WATERFALL_LINES, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, waterfall_tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, FFT_SIZE, NUM_WATERFALL_LINES, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, (GLvoid *) waterfall_tex); // glEnable(GL_LINE_SMOOTH); + glDisable(GL_TEXTURE_2D); + + glColor3f(1.0,1.0,1.0); + if (points.size()) { glPushMatrix(); glTranslatef(-1.0f, -0.9f, 0.0f); @@ -91,21 +131,21 @@ void PrimaryGLContext::Plot(std::vector &points, std::vector &poin glDisableClientState(GL_VERTEX_ARRAY); glPopMatrix(); } - + glEnable(GL_TEXTURE_2D); // glEnable(GL_COLOR_TABLE); - glBindTexture(GL_TEXTURE_2D, tex); + glBindTexture(GL_TEXTURE_2D, waterfall); glBegin(GL_QUADS); - glTexCoord2f(0.0,0.0); - glVertex3f(-0.8,-1.0,0.0); - glTexCoord2f(1.0,0.0); - glVertex3f(1.0,-1.0,0.0); - glTexCoord2f(1.0,1.0); - glVertex3f(1.0,1.0,0.0); - glTexCoord2f(0.0,1.0); - glVertex3f(-1.0,1.0,0.0); + glTexCoord2f(0.0, 0.0); + glVertex3f(-1.0, -1.0, 0.0); + glTexCoord2f(1.0, 0.0); + glVertex3f(1.0, -1.0, 0.0); + glTexCoord2f(1.0, 1.0); + glVertex3f(1.0, 1.0, 0.0); + glTexCoord2f(0.0, 1.0); + glVertex3f(-1.0, 1.0, 0.0); glEnd(); - + glFlush(); CheckGLError(); @@ -116,13 +156,10 @@ EVT_KEY_DOWN(TestGLCanvas::OnKeyDown) EVT_IDLE(TestGLCanvas::OnIdle) wxEND_EVENT_TABLE() - - TestGLCanvas::TestGLCanvas(wxWindow *parent, int *attribList) : wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE), parent(parent) { - int in_block_size = BUF_SIZE / 2; int out_block_size = FFT_SIZE; @@ -134,40 +171,6 @@ TestGLCanvas::TestGLCanvas(wxWindow *parent, int *attribList) : fft_ceil_ma = fft_ceil_maa = 1.0; - grad.addColor(GradientColor(0,0.5,1.0)); - grad.addColor(GradientColor(1.0,0,0)); - grad.addColor(GradientColor(0,1.0,1.0)); - - grad.generate(&color_map,256); - - glGenTextures(1, &waterfall); - std::cout << waterfall << std::endl; - std::cout << waterfall << std::endl; - std::cout << waterfall << std::endl; - std::cout << waterfall << std::endl; - // for (int i = 0; i < c.size()/3; i++) { - // std::cout << i << ": r[" << (int)c[i*3] << "] g[" << (int)c[i*3+1] << "] b[" << (int)c[i*3+2] << "] " << std::endl; - // } - - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D,waterfall); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - // glTexImage2D(GL_TEXTURE_2D,0,GL_INTENSITY,FFT_SIZE,NUM_WATERFALL_LINES,0,GL_COLOR_INDEX,GL_UNSIGNED_BYTE,(GLvoid *)waterfall_tex); - float clr[16] = { 255, 0, 0, 0, - 0, 255, 0, 0, - 0, 0, 255, 0, - 255, 255, 255, 0 }; - glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,2,2,0,GL_RGBA,GL_UNSIGNED_BYTE,clr); - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - - // glColorTable(GL_TEXTURE_2D,GL_RGB8,256,GL_RGB,GL_UNSIGNED_BYTE,&color_map[0]); - } TestGLCanvas::~TestGLCanvas() { @@ -181,8 +184,7 @@ void TestGLCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { PrimaryGLContext& canvas = wxGetApp().GetContext(this); glViewport(0, 0, ClientSize.x, ClientSize.y); - - canvas.Plot(spectrum_points, test_demod.waveform_points, waterfall); + canvas.Plot(spectrum_points, test_demod.waveform_points, waterfall_tex); SwapBuffers(); } @@ -279,17 +281,19 @@ void TestGLCanvas::setData(std::vector *data) { // fftw_execute(plan[1]); - - memmove(waterfall_tex+NUM_WATERFALL_LINES,waterfall_tex,(NUM_WATERFALL_LINES-1)*FFT_SIZE); - - for (int i = 0, iMax = FFT_SIZE; i < iMax; i++) { - spectrum_points[i * 2 + 1] = log10(fft_result_maa[i]) / log10(fft_ceil_maa); -// spectrum_points[i * 2 + 1] = (fft_result_maa[i]) / (fft_ceil_maa); - float v = ((float) i / (float) iMax); - spectrum_points[i * 2] = v; - waterfall_tex[i] = (unsigned char)(v*255.0); - } + memmove(waterfall_tex + FFT_SIZE, waterfall_tex, (NUM_WATERFALL_LINES - 1) * FFT_SIZE); + for (int i = 0, iMax = FFT_SIZE; i < iMax; i++) { + float v = log10(fft_result_maa[i]) / log10(fft_ceil_maa); + + float wv = v; + if (wv<0.0) wv = 0.0; + if (wv>1.0) wv = 1.0; + waterfall_tex[i] = (unsigned char) floor(wv * 255.0); + + spectrum_points[i * 2] = ((float) i / (float) iMax); + spectrum_points[i * 2 + 1] = v; + } test_demod.writeBuffer(data); } diff --git a/src/PrimaryGLContext.h b/src/PrimaryGLContext.h index dd6b914..8e0aac0 100644 --- a/src/PrimaryGLContext.h +++ b/src/PrimaryGLContext.h @@ -12,15 +12,19 @@ #include "Gradient.h" -#define NUM_WATERFALL_LINES 256 +#define NUM_WATERFALL_LINES 512 class PrimaryGLContext: public wxGLContext { public: PrimaryGLContext(wxGLCanvas *canvas); - void Plot(std::vector &points, std::vector &points2, GLuint tex); + void Plot(std::vector &points, std::vector &points2, unsigned char *waterfall_tex); private: + + Gradient grad; + + GLuint waterfall; }; class TestGLCanvas: public wxGLCanvas { @@ -48,14 +52,10 @@ private: std::vector fft_result_ma; std::vector fft_result_maa; - Gradient grad; - - std::vector color_map; unsigned char waterfall_tex[FFT_SIZE * NUM_WATERFALL_LINES]; - GLuint waterfall; - + Demodulator test_demod; wxDECLARE_EVENT_TABLE(); };