cleaned up some unused files
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 28 May 2013 06:45:26 +0000 (06:45 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 28 May 2013 06:45:26 +0000 (06:45 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1291 01035d8c-6547-0410-b346-abe4f91aad63

fdmdv2/src/Makefile.linux
fdmdv2/src/Makefile.win32
fdmdv2/src/fdmdv2_main.h
fdmdv2/src/fdmdv2_plot_scatter.cpp
fdmdv2/src/fdmdv2_plot_scatter.h
fdmdv2/src/fdmdv2_plot_waterfall.cpp
fdmdv2/src/fdmdv2_plot_waterfall.h
fdmdv2/src/fdmdv2_plot_waterfall_linux.cpp [deleted file]
fdmdv2/src/fdmdv2_plot_waterfall_linux.h [deleted file]

index a7f9e38108f9c9b7d77ba8e4355e4d243d535527..23ec27e8ee1c02d26bd623f3cf35b6b80b4f697b 100644 (file)
@@ -97,7 +97,7 @@ fdmdv2_plot.o \
 fdmdv2_plot_scalar.o \
 fdmdv2_plot_scatter.o \
 fdmdv2_plot_spectrum.o \
-fdmdv2_plot_waterfall_linux.o \
+fdmdv2_plot_waterfall.o \
 fdmdv2_pa_wrapper.o \
 dlg_audiooptions.o \
 dlg_ptt.o \
index 0bdb703ea11ab59e062d789c50010274ebde6c78..9c761ce7e58c4084e3110fa95b3bee67859e4b8e 100644 (file)
@@ -24,7 +24,7 @@ fdmdv2_plot.o \
 fdmdv2_plot_scalar.o \
 fdmdv2_plot_scatter.o \
 fdmdv2_plot_spectrum.o \
-fdmdv2_plot_waterfall_linux.o \
+fdmdv2_plot_waterfall.o \
 fdmdv2_pa_wrapper.o \
 dlg_audiooptions.o \
 dlg_ptt.o \
index fa340dc7331ca430415a6147fde2d45e95f3c51d..6f186a8025fae4c95a6bac6ce11196824aaf9be8 100644 (file)
@@ -63,7 +63,7 @@
 #include "fdmdv2_plot.h"
 #include "fdmdv2_plot_scalar.h"
 #include "fdmdv2_plot_scatter.h"
-#include "fdmdv2_plot_waterfall_linux.h"
+#include "fdmdv2_plot_waterfall.h"
 #include "fdmdv2_plot_spectrum.h"
 #include "fdmdv2_pa_wrapper.h"
 #include "sndfile.h"
index a85e73202c7175d2509202797ae56e29ed126000..b9f5f7eb04c66712366149ceebfab054107aa37f 100644 (file)
@@ -1,6 +1,6 @@
 //==========================================================================
 // Name:            fdmdv2_plot_scatter.cpp
-// Purpose:         Implements a scatter plot derivative of fdmdv2_plot.
+// Purpose:         A scatter plot derivative of fdmdv2_plot.
 // Created:         June 24, 2012
 // Authors:         David Rowe, David Witten
 // 
index bdcbe452ec31236e3bbe8355011c00b90226fc0d..702f633360c08ffa259b8fe003728ba78438e269 100644 (file)
@@ -1,6 +1,6 @@
 //==========================================================================
 // Name:            fdmdv2_plot_scatter.h
-// Purpose:         Defines a waterfall plot derivative of fdmdv2_plot.
+// Purpose:         A scatter plot derivative of fdmdv2_plot.
 // Created:         June 24, 2012
 // Authors:         David Rowe, David Witten
 // 
index 01ea6b0e8cf803268e8aa707d2123f4bc3c8c5da..b65c2083f290c9f4ca389535279bed0143649022 100644 (file)
@@ -2,54 +2,38 @@
 // Name:            fdmdv2_plot_waterfall.cpp
 // Purpose:         Implements a waterfall plot derivative of fdmdv2_plot.
 // Created:         June 22, 2012
-// Initial author:  David Witten
-// Derived from:    code written by David Rowe
+// Authors:         David Rowe, David Witten
+// 
 // License:
 //
-//  Copyright (C) 2012 David Witten
-//
-//  All rights reserved.
-//
 //  This program is free software; you can redistribute it and/or modify
-//  it under the terms of the GNU Lesser General Public License version 2.1,
+//  it under the terms of the GNU General Public License version 2.1,
 //  as published by the Free Software Foundation.  This program is
 //  distributed in the hope that it will be useful, but WITHOUT ANY
 //  WARRANTY; without even the implied warranty of MERCHANTABILITY or
 //  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
 //  License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public License
+//  You should have received a copy of the GNU General Public License
 //  along with this program; if not, see <http://www.gnu.org/licenses/>.
 //
 //==========================================================================
 #include <string.h>
 #include "wx/wx.h"
 #include "fdmdv2_main.h"
-#include "fdmdv2_plot_waterfall.h"
-
-/*
-
-  Notes:
 
-  The height h() pixels represents WATERFALL_SECS_Y of data.  Every DT
-  seconds we get a vector of FDMDV_NSPEC spectrum samples which we use
-  to update the last row.  The height of each row is dy pixels, which
-  maps to DT seconds.  We call each dy high rectangle of pixels a
-  block.
-
-*/
-
-extern float g_avmag[];
+extern float g_avmag[];                 // av mag spec passed in to draw() 
+void fdmdv2_clickTune(float frequency); // callback to pass new click freq
 
 BEGIN_EVENT_TABLE(PlotWaterfall, PlotPanel)
     EVT_PAINT           (PlotWaterfall::OnPaint)
     EVT_MOTION          (PlotWaterfall::OnMouseMove)
-    EVT_LEFT_DOWN       (PlotWaterfall::OnMouseDown)
-    EVT_LEFT_UP         (PlotWaterfall::OnMouseUp)
+    EVT_LEFT_DOWN       (PlotWaterfall::OnMouseLeftDown)
+    EVT_RIGHT_DOWN      (PlotWaterfall::OnMouseRightDown)
+    EVT_LEFT_UP         (PlotWaterfall::OnMouseLeftUp)
     EVT_MOUSEWHEEL      (PlotWaterfall::OnMouseWheelMoved)
     EVT_SIZE            (PlotWaterfall::OnSize)
     EVT_SHOW            (PlotWaterfall::OnShow)
-//    EVT_ERASE_BACKGROUND(PlotWaterfall::OnErase)
 END_EVENT_TABLE()
 
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
@@ -62,18 +46,47 @@ END_EVENT_TABLE()
 // @brief
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
-PlotWaterfall::PlotWaterfall(wxFrame* parent): PlotPanel(parent)
+PlotWaterfall::PlotWaterfall(wxFrame* parent, bool graticule, int colour): PlotPanel(parent)
 {
+
     for(int i = 0; i < 255; i++)
     {
         m_heatmap_lut[i] = heatmap((float)i, 0.0, 255.0);
     }
-    m_greyscale     = 0;
+    m_graticule     = graticule;
+    m_colour        = colour;
     m_Bufsz         = GetMaxClientSize();
     m_newdata       = false;
     m_firstPass     = true;
     m_line_color    = 0;
     SetLabelSize(10.0);
+
+    m_pBmp = NULL;
+    m_max_mag = MAX_MAG_DB;
+    m_min_mag = MIN_MAG_DB;
+}
+
+// When the window size gets set we can work outthe size of the window
+// we plot in and allocate a bit map of the correct size
+void PlotWaterfall::OnSize(wxSizeEvent& event) 
+{
+    // resize bit map
+
+    delete m_pBmp;
+    
+    m_rCtrl  = GetClientRect();
+
+    // m_rGrid is coords of inner window we actually plot to.  We deflate it a bit
+    // to leave room for axis labels.
+
+    m_rGrid  = m_rCtrl;
+    m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+
+    // we want a bit map the size of m_rGrid
+
+    m_pBmp = new wxBitmap(m_rGrid.GetWidth(), m_rGrid.GetHeight(), 24);
+
+    m_dT = DT;
 }
 
 //----------------------------------------------------------------
@@ -91,8 +104,8 @@ PlotWaterfall::PlotWaterfall(wxFrame* parent): PlotPanel(parent)
 //----------------------------------------------------------------
 void PlotWaterfall::OnPaint(wxPaintEvent & evt)
 {
-    wxAutoBufferedPaintDC pdc(this);
-    draw(pdc);
+    wxAutoBufferedPaintDC dc(this);
+    draw(dc);
 }
 
 //----------------------------------------------------------------
@@ -145,218 +158,324 @@ unsigned PlotWaterfall::heatmap(float val, float min, float max)
     return  (b << 16) + (g << 8) + r;
 }
 
-#define PLOT_BOTTOM     0
-#define PLOT_TOP        1
+bool PlotWaterfall::checkDT(void)
+{
+    // Check dY is > 1 pixel before proceeding. For small screens
+    // and large WATERFALL_SECS_Y we might have less than one
+    // block per pixel.  In this case increase m_dT and perform draw
+    // less often
 
-//static long paint_count;
+    float px_per_sec = (float)m_rGrid.GetHeight() / WATERFALL_SECS_Y;
+    float dy = m_dT * px_per_sec;
+    
+    if (dy < 1.0) {
+        m_dT += DT;
+        return false;
+    }
+    else
+        return true;
+}
 
 //----------------------------------------------------------------
 // draw()
 //----------------------------------------------------------------
-void PlotWaterfall::draw(wxAutoBufferedPaintDC& pDC)
+void PlotWaterfall::draw(wxAutoBufferedPaintDC& dc)
 {
-    wxMemoryDC m_mDC;
-    m_mDC.SelectObject(*m_pBmp);
+
     m_rCtrl  = GetClientRect();
-    m_rGrid  = m_rCtrl;
 
+    // m_rGrid is coords of inner window we actually plot to.  We deflate it a bit
+    // to leave room for axis labels.
+
+    m_rGrid = m_rCtrl;
     m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
-    m_rGrid.Offset(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER);
-
-    pDC.Clear();
-//    m_mDC.Clear();
-    m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
-//    if(m_firstPass)
-//    {
-//        m_firstPass = false;
-//        m_mDC.FloodFill(0, 0, VERY_LTGREY_COLOR);
-
-        // Draw a filled rectangle with aborder
-//        wxBrush ltGraphBkgBrush = wxBrush(DARK_BLUE_COLOR);
-//        m_mDC.SetBrush(ltGraphBkgBrush);
-//        m_mDC.SetPen(wxPen(BLACK_COLOR, 0));
-//        m_mDC.DrawRectangle(m_rPlot);
-
-//    }
-    wxBrush ltGraphBkgBrush = wxBrush(DARK_BLUE_COLOR);
-    pDC.SetBrush(ltGraphBkgBrush);
-    pDC.SetPen(wxPen(BLACK_COLOR, 0));
-    pDC.DrawRectangle(m_rPlot);
-    drawGraticule(pDC);
-    if(m_newdata)
+
+    if (m_pBmp == NULL) 
     {
-        m_newdata = false;
-        //plotPixelData(pDC);
-//#ifdef _USE_TIMER
-        int t = m_rPlot.GetTop();
-        int l = m_rPlot.GetLeft();
-        int h = m_rPlot.GetHeight();
-        int w = m_rPlot.GetWidth();
-        int t2 = t + 1;
-        int w2 = w - 1;
-        int ht = (h - DATA_LINE_HEIGHT);
-
-        drawData();     //  m_mDC, PLOT_BOTTOM);
-        m_mDC.StretchBlit(l, t2, w2, ht, &m_mDC, l, t2 + DATA_LINE_HEIGHT, w2, ht - 2);
-        // pDC.Blit(l, t, w, h, &m_mDC, l, t);                                                  // Scroll Up from Bottom
-        pDC.StretchBlit(l, (h - t) + 4, w, (-h) + 4, &m_mDC, l, t, w, h);                       // Scroll Down from top
-//#endif
-        drawGraticule(pDC);
+        // we want a bit map the size of m_rGrid
+        m_pBmp = new wxBitmap(m_rGrid.GetWidth(), m_rGrid.GetHeight(), 24);
     }
-    m_mDC.SetBrush(wxNullBrush);
-    m_mDC.SelectObject(wxNullBitmap);
-}
 
-//-------------------------------------------------------------------------
-// drawData()
-//-------------------------------------------------------------------------
-void PlotWaterfall::drawData()  //wxMemoryDC&  pDC)
-{
-    wxNativePixelData dPix = wxNativePixelData(*m_pBmp, m_rCtrl);
-    m_pPix = &dPix;
-    if(m_pPix == NULL)
+    dc.Clear();
+
+    if(m_newdata)
     {
-        return;
+        m_newdata = false;
+        plotPixelData();
+        dc.DrawBitmap(*m_pBmp, PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER);
+        m_dT = DT;
     }
-    wxNativePixelData::Iterator p(*m_pPix);
-
-    int w = m_rPlot.GetWidth();
-    int h = m_rPlot.GetHeight();
-    p.Offset(*m_pPix, XLEFT_OFFSET + 3, h - (DATA_LINE_HEIGHT - 2));
-    for(int y = 0; y < DATA_LINE_HEIGHT; ++y)
+    else 
     {
-        wxNativePixelData::Iterator rowStart = p;
-        for(int x = 0; x < (w - 1); ++x, ++p)
-        {
-            p.Red()     = g_avmag[x];
-            p.Green()   = g_avmag[x];
-            p.Blue()    = g_avmag[x];
-        }
-        p = rowStart;
-        p.OffsetY(*m_pPix, 1);
+
+        // no data to plot so just erase to black.  Blue looks nicer
+        // but is same colour as low amplitude signal
+
+        // Bug on Linux: When Stop is pressed this code doesn't erase
+        // the lower 25% of the Waterfall Window
+
+        m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
+        wxBrush ltGraphBkgBrush = wxBrush(BLACK_COLOR);
+        dc.SetBrush(ltGraphBkgBrush);
+        dc.SetPen(wxPen(BLACK_COLOR, 0));
+        dc.DrawRectangle(m_rPlot);
     }
+    drawGraticule(dc);
 }
 
 //-------------------------------------------------------------------------
 // drawGraticule()
 //-------------------------------------------------------------------------
-void PlotWaterfall::drawGraticule(wxAutoBufferedPaintDC&  pDC)
+void PlotWaterfall::drawGraticule(wxAutoBufferedPaintDC& dc)
 {
-    int p;
-    char buf[15];
-
+    int      x, y, text_w, text_h;
+    char     buf[15];
     wxString s;
+    float    f, time, freq_hz_to_px, time_s_to_py;
 
     wxBrush ltGraphBkgBrush;
     ltGraphBkgBrush.SetStyle(wxBRUSHSTYLE_TRANSPARENT);
     ltGraphBkgBrush.SetColour(*wxBLACK);
-    pDC.SetBrush(ltGraphBkgBrush);
-    pDC.SetPen(wxPen(BLACK_COLOR, 1));
+    dc.SetBrush(ltGraphBkgBrush);
+    dc.SetPen(wxPen(BLACK_COLOR, 1));
 
-    // Vertical gridlines
-    pDC.SetPen(m_penShortDash);
-    for(p = (PLOT_BORDER + XLEFT_OFFSET + GRID_INCREMENT); p < ((m_rGrid.GetWidth() - XLEFT_OFFSET) + GRID_INCREMENT); p += GRID_INCREMENT)
-    {
-        pDC.DrawLine(p, (m_rGrid.GetHeight() + PLOT_BORDER), p, PLOT_BORDER);
-    }
-    // Horizontal gridlines
-    pDC.SetPen(m_penDotDash);
-    for(p = (m_rGrid.GetHeight() - GRID_INCREMENT); p > PLOT_BORDER; p -= GRID_INCREMENT)
-    {
-        pDC.DrawLine(PLOT_BORDER + XLEFT_OFFSET, (p + PLOT_BORDER), (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), (p + PLOT_BORDER));
-    }
-    // Label the X-Axis
-    pDC.SetPen(wxPen(GREY_COLOR, 1));
-    for(p = GRID_INCREMENT; p < (m_rGrid.GetWidth() - YBOTTOM_OFFSET); p += GRID_INCREMENT)
+    freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ);
+    time_s_to_py = (float)m_rGrid.GetHeight()/WATERFALL_SECS_Y;
+
+    // upper LH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER)
+    // lower RH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET + m_rGrid.GetWidth(), 
+    //                                   PLOT_BORDER + m_rGrid.GetHeight())
+
+    // Check if small screen size means text will overlap
+
+    int textXStep = STEP_F_HZ*freq_hz_to_px;
+    int textYStep = WATERFALL_SECS_STEP*time_s_to_py;
+    sprintf(buf, "%4.0fHz", (float)MAX_F_HZ - STEP_F_HZ);
+    GetTextExtent(buf, &text_w, &text_h);
+    int overlappedText = (text_w > textXStep) || (text_h > textYStep);
+
+    // Major Vertical gridlines and legend
+    //dc.SetPen(m_penShortDash);
+    for(f=STEP_F_HZ; f<MAX_F_HZ; f+=STEP_F_HZ) 
     {
-        sprintf(buf, "%1.1f Hz",(double)(p / 10));
-        pDC.DrawText(buf, p - PLOT_BORDER + XLEFT_OFFSET, m_rGrid.GetHeight() + YBOTTOM_OFFSET/3);
+        x = f*freq_hz_to_px;
+        x += PLOT_BORDER + XLEFT_OFFSET;
+
+        if (m_graticule)
+            dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER);
+        else
+            dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+            
+        sprintf(buf, "%4.0fHz", f);
+        GetTextExtent(buf, &text_w, &text_h);
+        if (!overlappedText)
+            dc.DrawText(buf, x - text_w/2, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
     }
-    // Label the Y-Axis
-    for(p = (m_rGrid.GetHeight() - GRID_INCREMENT); p > PLOT_BORDER; p -= GRID_INCREMENT)
+
+    for(f=STEP_MINOR_F_HZ; f<MAX_F_HZ; f+=STEP_MINOR_F_HZ) 
     {
-        sprintf(buf, "%1.0f", (double)((m_rGrid.GetHeight() - p) * -10));
-        pDC.DrawText(buf, XLEFT_TEXT_OFFSET, p);
+        x = f*freq_hz_to_px;
+        x += PLOT_BORDER + XLEFT_OFFSET;
+        dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET-5);
     }
+    
+    // Horizontal gridlines
+    dc.SetPen(m_penDotDash);
+    for(time=0; time<=WATERFALL_SECS_Y; time+=WATERFALL_SECS_STEP) {
+       y = m_rGrid.GetHeight() - time*time_s_to_py;
+       y += PLOT_BORDER;
+
+        if (m_graticule)
+            dc.DrawLine(PLOT_BORDER + XLEFT_OFFSET, y, 
+                        (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), y);
+        sprintf(buf, "%3.0fs", time);
+       GetTextExtent(buf, &text_w, &text_h);
+        if (!overlappedText)
+            dc.DrawText(buf, PLOT_BORDER + XLEFT_OFFSET - text_w - XLEFT_TEXT_OFFSET, y-text_h/2);
+   }
+
+    // red rx tuning line
+    dc.SetPen(wxPen(RED_COLOR, 2));
+    x = m_rxFreq*freq_hz_to_px;
+    x += PLOT_BORDER + XLEFT_OFFSET;
+    //printf("m_rxFreq %f x %d\n", m_rxFreq, x);
+    dc.DrawLine(x, m_rGrid.GetHeight()+ PLOT_BORDER, x, m_rCtrl.GetHeight());
+    
 }
 
 //-------------------------------------------------------------------------
 // plotPixelData()
 //-------------------------------------------------------------------------
-void PlotWaterfall::plotPixelData(wxAutoBufferedPaintDC&  dc)
+void PlotWaterfall::plotPixelData()
 {
     float       spec_index_per_px;
     float       intensity_per_dB;
-    int         px_per_sec;
+    float       px_per_sec;
     int         index;
-    int         dy;
+    float       dy;
     int         dy_blocks;
-    int         bytes_in_row_of_blocks;
     int         b;
     int         px;
     int         py;
     int         intensity;
-    unsigned    *last_row;
-    unsigned    *pdest;
-    unsigned    *psrc;
+
+    /*
+      Design Notes:
+
+      The height in pixels represents WATERFALL_SECS_Y of data.  Every DT
+      seconds we get a vector of FDMDV_NSPEC spectrum samples which we use
+      to update the last row.  The height of each row is dy pixels, which
+      maps to DT seconds.  We call each dy high rectangle of pixels a
+      block.
+
+    */
 
     // determine dy, the height of one "block"
-    px_per_sec = (float)m_rCtrl.GetHeight() / WATERFALL_SECS_Y;
-    dy = DT * px_per_sec;
+    px_per_sec = (float)m_rGrid.GetHeight() / WATERFALL_SECS_Y;
+    dy = m_dT * px_per_sec;
+
     // number of dy high blocks in spectrogram
-    dy_blocks = m_rCtrl.GetHeight()/ dy;
-    // shift previous bit map
-    bytes_in_row_of_blocks = dy * m_rCtrl.GetWidth() * sizeof(unsigned);
-    for(b = 0; b < dy_blocks - 1; b++)
+    dy_blocks = m_rGrid.GetHeight()/ dy;
+
+    // update min and max amplitude estimates
+    float max_mag = MIN_MAG_DB;
+
+    int min_fft_bin=((float)200/FDMDV_MAX_F_HZ)*FDMDV_NSPEC;
+    int max_fft_bin=((float)2800/FDMDV_MAX_F_HZ)*FDMDV_NSPEC;
+
+    for(int i=min_fft_bin; i<max_fft_bin; i++) 
     {
-        pdest = (unsigned int *)m_pBmp + b * m_rCtrl.GetWidth() * dy;
-        psrc  = (unsigned int *)m_pBmp + (b + 1) * m_rCtrl.GetWidth() * dy;
-        memcpy(pdest, psrc, bytes_in_row_of_blocks);
+        if (g_avmag[i] > max_mag)
+        {
+            max_mag = g_avmag[i];
+        }
     }
-    // create a new row of blocks at bottom
-    spec_index_per_px = (float)FDMDV_NSPEC / (float) m_rCtrl.GetWidth();
-    intensity_per_dB  = (float)256 /(MAX_DB - MIN_DB);
-    last_row = (unsigned int *)m_pBmp + dy *(dy_blocks - 1)* m_rCtrl.GetWidth();
 
+    m_max_mag = BETA*m_max_mag + (1 - BETA)*max_mag;
+    m_min_mag = max_mag - 20.0;
+    //printf("max_mag: %f m_max_mag: %f\n", max_mag, m_max_mag);
+    //intensity_per_dB  = (float)256 /(MAX_MAG_DB - MIN_MAG_DB);
+    intensity_per_dB  = (float)256 /(m_max_mag - m_min_mag);
+    spec_index_per_px = ((float)(MAX_F_HZ)/(float)FDMDV_MAX_F_HZ)*(float)FDMDV_NSPEC / (float) m_rGrid.GetWidth();
+
+    /*
+    printf("h %d w %d px_per_sec %d dy %d dy_blocks %d spec_index_per_px: %f\n", 
+       m_rGrid.GetHeight(), m_rGrid.GetWidth(), px_per_sec, 
+       dy, dy_blocks, spec_index_per_px);
+    */
+
+    // Shift previous bit map up one row of blocks ----------------------------
     wxNativePixelData data(*m_pBmp);
-    if(!data)
-    {
-        wxMessageBox(wxT("Unable to access Bitmap Data"), wxT("Error"));
-        return;
-    }
-    if(data.GetWidth() < 20 || data.GetHeight() < 20)
-    {
-        wxMessageBox(wxT("Bitmap is too small to use"), wxT("Warning"));
-        return;
-    }
-    wxNativePixelData::Iterator p(data);
-    // we draw a (10, 10)-(20, 20) rect manually using the given r, g, b
-    p.Offset(data, 10, 10);
-    for(px = 0; px < m_rCtrl.GetWidth(); px++)
+    wxNativePixelData::Iterator bitMapStart(data);
+    wxNativePixelData::Iterator p = bitMapStart;
+
+    for(b = 0; b < dy_blocks - 1; b++) 
     {
-        index = px * spec_index_per_px;
-        intensity = intensity_per_dB * (g_avmag[index] - MIN_DB);
-        if(intensity > 255)
-        {
-            intensity = 255;
-        }
-        if (intensity < 0)
-        {
-            intensity = 0;
-        }
-        if(m_greyscale)
+        wxNativePixelData::Iterator psrc = bitMapStart;
+        wxNativePixelData::Iterator pdest = bitMapStart;
+        pdest.OffsetY(data, dy * b);
+        psrc.OffsetY(data, dy * (b+1));
+
+        // copy one line of blocks
+
+        for(py = 0; py < dy; py++) 
         {
-            for(py = 0; py < dy; py++)
+            wxNativePixelData::Iterator pdestRowStart = pdest;
+            wxNativePixelData::Iterator psrcRowStart = psrc;
+
+            for(px = 0; px < m_rGrid.GetWidth(); px++) 
             {
-                last_row[px + py * m_rCtrl.GetWidth()] = intensity << 8;
+                pdest.Red() = psrc.Red();
+                pdest.Green() = psrc.Green();
+                pdest.Blue() = psrc.Blue();
+                pdest++;
+                psrc++;
             }
+            pdest = pdestRowStart;
+            pdest.OffsetY(data, 1);
+            psrc = psrcRowStart;
+            psrc.OffsetY(data, 1);         
         }
-        else
+    }
+
+    // Draw last line of blocks using latest amplitude data ------------------
+    p = bitMapStart;
+    p.OffsetY(data, dy *(dy_blocks - 1));
+    for(py = 0; py < dy; py++)
+    {
+        wxNativePixelData::Iterator rowStart = p;
+
+        for(px = 0; px < m_rGrid.GetWidth(); px++)
         {
-            for(py = 0; py < dy; py++)
-            {
-                last_row[px + py * m_rCtrl.GetWidth()] = m_heatmap_lut[intensity];
+            index = px * spec_index_per_px;
+            assert(index < FDMDV_NSPEC);
+
+            intensity = intensity_per_dB * (g_avmag[index] - m_min_mag);
+            if(intensity > 255) intensity = 255;
+            if (intensity < 0) intensity = 0;
+            //printf("%d %f %d \n", index, g_avmag[index], intensity);
+
+            switch (m_colour) {
+            case 0:
+                p.Red() = m_heatmap_lut[intensity] & 0xff;
+                p.Green() = (m_heatmap_lut[intensity] >> 8) & 0xff;
+                p.Blue() = (m_heatmap_lut[intensity] >> 16) & 0xff;
+                break;
+            case 1:
+                p.Red() = intensity;
+                p.Green() = intensity;
+                p.Blue() = intensity;       
+                break;
+            case 2:
+                p.Red() = intensity;
+                p.Green() = intensity;
+                if (intensity < 127)
+                    p.Blue() = intensity*2;
+                else
+                    p.Blue() = 255;
+                        
+                break;
             }
+            ++p;
         }
+        p = rowStart;
+        p.OffsetY(data, 1);
     }
+
 }
+
+//-------------------------------------------------------------------------
+// OnMouseLeftDown()
+//-------------------------------------------------------------------------
+void PlotWaterfall::OnMouseLeftDown(wxMouseEvent& event)
+{
+    m_mouseDown = true;
+    wxClientDC dc(this);
+
+    wxPoint pt(event.GetLogicalPosition(dc));
+
+    // map x coord to edges of actual plot
+    pt.x -= PLOT_BORDER + XLEFT_OFFSET;
+    pt.y -= PLOT_BORDER;
+
+    // valid click if inside of plot
+    if ((pt.x >= 0) && (pt.x <= m_rGrid.GetWidth()) && (pt.y >=0)) 
+    {
+        float freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ);
+        float clickFreq = (float)pt.x/freq_hz_to_px;
+
+        // communicate back to other threads
+        fdmdv2_clickTune(clickFreq);
+    }
+}
+
+//-------------------------------------------------------------------------
+// OnMouseRightDown()
+//-------------------------------------------------------------------------
+void PlotWaterfall::OnMouseRightDown(wxMouseEvent& event)
+{
+    m_colour++;
+    if (m_colour == 3)
+        m_colour = 0;
+}
+
index 0d5e022614349c13cc0ccee85a1eb6443c90bbab..e5c0e836f9cd395892674193a69290e7ad5720bc 100644 (file)
@@ -2,23 +2,19 @@
 // Name:            fdmdv2_plot_waterfall.h
 // Purpose:         Defines a waterfall plot derivative of fdmdv2_plot.
 // Created:         June 22, 2012
-// Initial author:  David Witten
-// Derived from:    code written by David Rowe
+// Authors:         David Rowe, David Witten
+// 
 // License:
 //
-//  Copyright (C) 2012 David Witten
-//
-//  All rights reserved.
-//
 //  This program is free software; you can redistribute it and/or modify
-//  it under the terms of the GNU Lesser General Public License version 2.1,
+//  it under the terms of the GNU General Public License version 2.1,
 //  as published by the Free Software Foundation.  This program is
 //  distributed in the hope that it will be useful, but WITHOUT ANY
 //  WARRANTY; without even the implied warranty of MERCHANTABILITY or
 //  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
 //  License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public License
+//  You should have received a copy of the GNU General Public License
 //  along with this program; if not, see <http://www.gnu.org/licenses/>.
 //
 //==========================================================================
 class PlotWaterfall : public PlotPanel
 {
     public:
-        PlotWaterfall(wxFrame* parent);
+    PlotWaterfall(wxFrame* parent, bool graticule, int colour);
         ~PlotWaterfall();
+        bool checkDT(void);
+        void setGreyscale(bool greyscale) { m_greyscale = greyscale; }
+        void setRxFreq(float rxFreq) { m_rxFreq = rxFreq; }
 
     protected:
         unsigned    m_heatmap_lut[256];
-        wxMemoryDC  m_mDC;
 
         unsigned    heatmap(float val, float min, float max);
 
         void        OnPaint(wxPaintEvent & evt);
+        void        OnSize(wxSizeEvent& event);
         void        OnShow(wxShowEvent& event);
         void        drawGraticule(wxAutoBufferedPaintDC&  dc);
-        void        draw(wxAutoBufferedPaintDC& pdc);
-        void        plotPixelData(wxAutoBufferedPaintDC&  dc);
-        void        drawData();     // wxMemoryDC&  pDC);
+        void        draw(wxAutoBufferedPaintDC& dc);
+        void        plotPixelData();
+        void        OnMouseLeftDown(wxMouseEvent& event);
+        void        OnMouseRightDown(wxMouseEvent& event);
+
+    private:
+        float       m_dT;
+        float       m_rxFreq;
+        bool        m_graticule;
+        float       m_min_mag;
+        float       m_max_mag;
+        int         m_colour;
 
         DECLARE_EVENT_TABLE()
 };
diff --git a/fdmdv2/src/fdmdv2_plot_waterfall_linux.cpp b/fdmdv2/src/fdmdv2_plot_waterfall_linux.cpp
deleted file mode 100644 (file)
index b65c208..0000000
+++ /dev/null
@@ -1,481 +0,0 @@
-//==========================================================================
-// Name:            fdmdv2_plot_waterfall.cpp
-// Purpose:         Implements a waterfall plot derivative of fdmdv2_plot.
-// Created:         June 22, 2012
-// Authors:         David Rowe, David Witten
-// 
-// License:
-//
-//  This program is free software; you can redistribute it and/or modify
-//  it under the terms of the GNU General Public License version 2.1,
-//  as published by the Free Software Foundation.  This program is
-//  distributed in the hope that it will be useful, but WITHOUT ANY
-//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
-//  License for more details.
-//
-//  You should have received a copy of the GNU General Public License
-//  along with this program; if not, see <http://www.gnu.org/licenses/>.
-//
-//==========================================================================
-#include <string.h>
-#include "wx/wx.h"
-#include "fdmdv2_main.h"
-
-extern float g_avmag[];                 // av mag spec passed in to draw() 
-void fdmdv2_clickTune(float frequency); // callback to pass new click freq
-
-BEGIN_EVENT_TABLE(PlotWaterfall, PlotPanel)
-    EVT_PAINT           (PlotWaterfall::OnPaint)
-    EVT_MOTION          (PlotWaterfall::OnMouseMove)
-    EVT_LEFT_DOWN       (PlotWaterfall::OnMouseLeftDown)
-    EVT_RIGHT_DOWN      (PlotWaterfall::OnMouseRightDown)
-    EVT_LEFT_UP         (PlotWaterfall::OnMouseLeftUp)
-    EVT_MOUSEWHEEL      (PlotWaterfall::OnMouseWheelMoved)
-    EVT_SIZE            (PlotWaterfall::OnSize)
-    EVT_SHOW            (PlotWaterfall::OnShow)
-END_EVENT_TABLE()
-
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
-// Class WaterfallPlot
-//
-// @class   WaterfallPlot
-// @author  David Witten
-// @date    $(Date)
-// @file    $(CurrentFileName).$(CurrentFileExt)
-// @brief
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
-PlotWaterfall::PlotWaterfall(wxFrame* parent, bool graticule, int colour): PlotPanel(parent)
-{
-
-    for(int i = 0; i < 255; i++)
-    {
-        m_heatmap_lut[i] = heatmap((float)i, 0.0, 255.0);
-    }
-    m_graticule     = graticule;
-    m_colour        = colour;
-    m_Bufsz         = GetMaxClientSize();
-    m_newdata       = false;
-    m_firstPass     = true;
-    m_line_color    = 0;
-    SetLabelSize(10.0);
-
-    m_pBmp = NULL;
-    m_max_mag = MAX_MAG_DB;
-    m_min_mag = MIN_MAG_DB;
-}
-
-// When the window size gets set we can work outthe size of the window
-// we plot in and allocate a bit map of the correct size
-void PlotWaterfall::OnSize(wxSizeEvent& event) 
-{
-    // resize bit map
-
-    delete m_pBmp;
-    
-    m_rCtrl  = GetClientRect();
-
-    // m_rGrid is coords of inner window we actually plot to.  We deflate it a bit
-    // to leave room for axis labels.
-
-    m_rGrid  = m_rCtrl;
-    m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
-
-    // we want a bit map the size of m_rGrid
-
-    m_pBmp = new wxBitmap(m_rGrid.GetWidth(), m_rGrid.GetHeight(), 24);
-
-    m_dT = DT;
-}
-
-//----------------------------------------------------------------
-// paintEvent()
-//
-// @class $(Name)
-// @author $(User)
-// @date $(Date)
-// @file $(CurrentFileName).$(CurrentFileExt)
-// @brief
-//
-// Called by the system of by wxWidgets when the panel needs
-// to be redrawn. You can also trigger this call by calling
-// Refresh()/Update().
-//----------------------------------------------------------------
-void PlotWaterfall::OnPaint(wxPaintEvent & evt)
-{
-    wxAutoBufferedPaintDC dc(this);
-    draw(dc);
-}
-
-//----------------------------------------------------------------
-// OnShow()
-//----------------------------------------------------------------
-void PlotWaterfall::OnShow(wxShowEvent& event)
-{
-}
-
-//----------------------------------------------------------------
-// ~PlotWaterfall()
-//----------------------------------------------------------------
-PlotWaterfall::~PlotWaterfall()
-{
-}
-
-//----------------------------------------------------------------
-// heatmap()
-// map val to a rgb colour
-// from http://eddiema.ca/2011/01/21/c-sharp-heatmaps/
-//----------------------------------------------------------------
-unsigned PlotWaterfall::heatmap(float val, float min, float max)
-{
-    unsigned r = 0;
-    unsigned g = 0;
-    unsigned b = 0;
-
-    val = (val - min) / (max - min);
-    if(val <= 0.2)
-    {
-        b = (unsigned)((val / 0.2) * 255);
-    }
-    else if(val >  0.2 &&  val <= 0.7)
-    {
-        b = (unsigned)((1.0 - ((val - 0.2) / 0.5)) * 255);
-    }
-    if(val >= 0.2 &&  val <= 0.6)
-    {
-        g = (unsigned)(((val - 0.2) / 0.4) * 255);
-    }
-    else if(val >  0.6 &&  val <= 0.9)
-    {
-        g = (unsigned)((1.0 - ((val - 0.6) / 0.3)) * 255);
-    }
-    if(val >= 0.5)
-    {
-        r = (unsigned)(((val - 0.5) / 0.5) * 255);
-    }
-    //printf("%f %x %x %x\n", val, r, g, b);
-    return  (b << 16) + (g << 8) + r;
-}
-
-bool PlotWaterfall::checkDT(void)
-{
-    // Check dY is > 1 pixel before proceeding. For small screens
-    // and large WATERFALL_SECS_Y we might have less than one
-    // block per pixel.  In this case increase m_dT and perform draw
-    // less often
-
-    float px_per_sec = (float)m_rGrid.GetHeight() / WATERFALL_SECS_Y;
-    float dy = m_dT * px_per_sec;
-    
-    if (dy < 1.0) {
-        m_dT += DT;
-        return false;
-    }
-    else
-        return true;
-}
-
-//----------------------------------------------------------------
-// draw()
-//----------------------------------------------------------------
-void PlotWaterfall::draw(wxAutoBufferedPaintDC& dc)
-{
-
-    m_rCtrl  = GetClientRect();
-
-    // m_rGrid is coords of inner window we actually plot to.  We deflate it a bit
-    // to leave room for axis labels.
-
-    m_rGrid = m_rCtrl;
-    m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
-
-    if (m_pBmp == NULL) 
-    {
-        // we want a bit map the size of m_rGrid
-        m_pBmp = new wxBitmap(m_rGrid.GetWidth(), m_rGrid.GetHeight(), 24);
-    }
-
-    dc.Clear();
-
-    if(m_newdata)
-    {
-        m_newdata = false;
-        plotPixelData();
-        dc.DrawBitmap(*m_pBmp, PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER);
-        m_dT = DT;
-    }
-    else 
-    {
-
-        // no data to plot so just erase to black.  Blue looks nicer
-        // but is same colour as low amplitude signal
-
-        // Bug on Linux: When Stop is pressed this code doesn't erase
-        // the lower 25% of the Waterfall Window
-
-        m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
-        wxBrush ltGraphBkgBrush = wxBrush(BLACK_COLOR);
-        dc.SetBrush(ltGraphBkgBrush);
-        dc.SetPen(wxPen(BLACK_COLOR, 0));
-        dc.DrawRectangle(m_rPlot);
-    }
-    drawGraticule(dc);
-}
-
-//-------------------------------------------------------------------------
-// drawGraticule()
-//-------------------------------------------------------------------------
-void PlotWaterfall::drawGraticule(wxAutoBufferedPaintDC& dc)
-{
-    int      x, y, text_w, text_h;
-    char     buf[15];
-    wxString s;
-    float    f, time, freq_hz_to_px, time_s_to_py;
-
-    wxBrush ltGraphBkgBrush;
-    ltGraphBkgBrush.SetStyle(wxBRUSHSTYLE_TRANSPARENT);
-    ltGraphBkgBrush.SetColour(*wxBLACK);
-    dc.SetBrush(ltGraphBkgBrush);
-    dc.SetPen(wxPen(BLACK_COLOR, 1));
-
-    freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ);
-    time_s_to_py = (float)m_rGrid.GetHeight()/WATERFALL_SECS_Y;
-
-    // upper LH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER)
-    // lower RH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET + m_rGrid.GetWidth(), 
-    //                                   PLOT_BORDER + m_rGrid.GetHeight())
-
-    // Check if small screen size means text will overlap
-
-    int textXStep = STEP_F_HZ*freq_hz_to_px;
-    int textYStep = WATERFALL_SECS_STEP*time_s_to_py;
-    sprintf(buf, "%4.0fHz", (float)MAX_F_HZ - STEP_F_HZ);
-    GetTextExtent(buf, &text_w, &text_h);
-    int overlappedText = (text_w > textXStep) || (text_h > textYStep);
-
-    // Major Vertical gridlines and legend
-    //dc.SetPen(m_penShortDash);
-    for(f=STEP_F_HZ; f<MAX_F_HZ; f+=STEP_F_HZ) 
-    {
-        x = f*freq_hz_to_px;
-        x += PLOT_BORDER + XLEFT_OFFSET;
-
-        if (m_graticule)
-            dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER);
-        else
-            dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
-            
-        sprintf(buf, "%4.0fHz", f);
-        GetTextExtent(buf, &text_w, &text_h);
-        if (!overlappedText)
-            dc.DrawText(buf, x - text_w/2, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
-    }
-
-    for(f=STEP_MINOR_F_HZ; f<MAX_F_HZ; f+=STEP_MINOR_F_HZ) 
-    {
-        x = f*freq_hz_to_px;
-        x += PLOT_BORDER + XLEFT_OFFSET;
-        dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET-5);
-    }
-    
-    // Horizontal gridlines
-    dc.SetPen(m_penDotDash);
-    for(time=0; time<=WATERFALL_SECS_Y; time+=WATERFALL_SECS_STEP) {
-       y = m_rGrid.GetHeight() - time*time_s_to_py;
-       y += PLOT_BORDER;
-
-        if (m_graticule)
-            dc.DrawLine(PLOT_BORDER + XLEFT_OFFSET, y, 
-                        (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), y);
-        sprintf(buf, "%3.0fs", time);
-       GetTextExtent(buf, &text_w, &text_h);
-        if (!overlappedText)
-            dc.DrawText(buf, PLOT_BORDER + XLEFT_OFFSET - text_w - XLEFT_TEXT_OFFSET, y-text_h/2);
-   }
-
-    // red rx tuning line
-    dc.SetPen(wxPen(RED_COLOR, 2));
-    x = m_rxFreq*freq_hz_to_px;
-    x += PLOT_BORDER + XLEFT_OFFSET;
-    //printf("m_rxFreq %f x %d\n", m_rxFreq, x);
-    dc.DrawLine(x, m_rGrid.GetHeight()+ PLOT_BORDER, x, m_rCtrl.GetHeight());
-    
-}
-
-//-------------------------------------------------------------------------
-// plotPixelData()
-//-------------------------------------------------------------------------
-void PlotWaterfall::plotPixelData()
-{
-    float       spec_index_per_px;
-    float       intensity_per_dB;
-    float       px_per_sec;
-    int         index;
-    float       dy;
-    int         dy_blocks;
-    int         b;
-    int         px;
-    int         py;
-    int         intensity;
-
-    /*
-      Design Notes:
-
-      The height in pixels represents WATERFALL_SECS_Y of data.  Every DT
-      seconds we get a vector of FDMDV_NSPEC spectrum samples which we use
-      to update the last row.  The height of each row is dy pixels, which
-      maps to DT seconds.  We call each dy high rectangle of pixels a
-      block.
-
-    */
-
-    // determine dy, the height of one "block"
-    px_per_sec = (float)m_rGrid.GetHeight() / WATERFALL_SECS_Y;
-    dy = m_dT * px_per_sec;
-
-    // number of dy high blocks in spectrogram
-    dy_blocks = m_rGrid.GetHeight()/ dy;
-
-    // update min and max amplitude estimates
-    float max_mag = MIN_MAG_DB;
-
-    int min_fft_bin=((float)200/FDMDV_MAX_F_HZ)*FDMDV_NSPEC;
-    int max_fft_bin=((float)2800/FDMDV_MAX_F_HZ)*FDMDV_NSPEC;
-
-    for(int i=min_fft_bin; i<max_fft_bin; i++) 
-    {
-        if (g_avmag[i] > max_mag)
-        {
-            max_mag = g_avmag[i];
-        }
-    }
-
-    m_max_mag = BETA*m_max_mag + (1 - BETA)*max_mag;
-    m_min_mag = max_mag - 20.0;
-    //printf("max_mag: %f m_max_mag: %f\n", max_mag, m_max_mag);
-    //intensity_per_dB  = (float)256 /(MAX_MAG_DB - MIN_MAG_DB);
-    intensity_per_dB  = (float)256 /(m_max_mag - m_min_mag);
-    spec_index_per_px = ((float)(MAX_F_HZ)/(float)FDMDV_MAX_F_HZ)*(float)FDMDV_NSPEC / (float) m_rGrid.GetWidth();
-
-    /*
-    printf("h %d w %d px_per_sec %d dy %d dy_blocks %d spec_index_per_px: %f\n", 
-       m_rGrid.GetHeight(), m_rGrid.GetWidth(), px_per_sec, 
-       dy, dy_blocks, spec_index_per_px);
-    */
-
-    // Shift previous bit map up one row of blocks ----------------------------
-    wxNativePixelData data(*m_pBmp);
-    wxNativePixelData::Iterator bitMapStart(data);
-    wxNativePixelData::Iterator p = bitMapStart;
-
-    for(b = 0; b < dy_blocks - 1; b++) 
-    {
-        wxNativePixelData::Iterator psrc = bitMapStart;
-        wxNativePixelData::Iterator pdest = bitMapStart;
-        pdest.OffsetY(data, dy * b);
-        psrc.OffsetY(data, dy * (b+1));
-
-        // copy one line of blocks
-
-        for(py = 0; py < dy; py++) 
-        {
-            wxNativePixelData::Iterator pdestRowStart = pdest;
-            wxNativePixelData::Iterator psrcRowStart = psrc;
-
-            for(px = 0; px < m_rGrid.GetWidth(); px++) 
-            {
-                pdest.Red() = psrc.Red();
-                pdest.Green() = psrc.Green();
-                pdest.Blue() = psrc.Blue();
-                pdest++;
-                psrc++;
-            }
-            pdest = pdestRowStart;
-            pdest.OffsetY(data, 1);
-            psrc = psrcRowStart;
-            psrc.OffsetY(data, 1);         
-        }
-    }
-
-    // Draw last line of blocks using latest amplitude data ------------------
-    p = bitMapStart;
-    p.OffsetY(data, dy *(dy_blocks - 1));
-    for(py = 0; py < dy; py++)
-    {
-        wxNativePixelData::Iterator rowStart = p;
-
-        for(px = 0; px < m_rGrid.GetWidth(); px++)
-        {
-            index = px * spec_index_per_px;
-            assert(index < FDMDV_NSPEC);
-
-            intensity = intensity_per_dB * (g_avmag[index] - m_min_mag);
-            if(intensity > 255) intensity = 255;
-            if (intensity < 0) intensity = 0;
-            //printf("%d %f %d \n", index, g_avmag[index], intensity);
-
-            switch (m_colour) {
-            case 0:
-                p.Red() = m_heatmap_lut[intensity] & 0xff;
-                p.Green() = (m_heatmap_lut[intensity] >> 8) & 0xff;
-                p.Blue() = (m_heatmap_lut[intensity] >> 16) & 0xff;
-                break;
-            case 1:
-                p.Red() = intensity;
-                p.Green() = intensity;
-                p.Blue() = intensity;       
-                break;
-            case 2:
-                p.Red() = intensity;
-                p.Green() = intensity;
-                if (intensity < 127)
-                    p.Blue() = intensity*2;
-                else
-                    p.Blue() = 255;
-                        
-                break;
-            }
-            ++p;
-        }
-        p = rowStart;
-        p.OffsetY(data, 1);
-    }
-
-}
-
-//-------------------------------------------------------------------------
-// OnMouseLeftDown()
-//-------------------------------------------------------------------------
-void PlotWaterfall::OnMouseLeftDown(wxMouseEvent& event)
-{
-    m_mouseDown = true;
-    wxClientDC dc(this);
-
-    wxPoint pt(event.GetLogicalPosition(dc));
-
-    // map x coord to edges of actual plot
-    pt.x -= PLOT_BORDER + XLEFT_OFFSET;
-    pt.y -= PLOT_BORDER;
-
-    // valid click if inside of plot
-    if ((pt.x >= 0) && (pt.x <= m_rGrid.GetWidth()) && (pt.y >=0)) 
-    {
-        float freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ);
-        float clickFreq = (float)pt.x/freq_hz_to_px;
-
-        // communicate back to other threads
-        fdmdv2_clickTune(clickFreq);
-    }
-}
-
-//-------------------------------------------------------------------------
-// OnMouseRightDown()
-//-------------------------------------------------------------------------
-void PlotWaterfall::OnMouseRightDown(wxMouseEvent& event)
-{
-    m_colour++;
-    if (m_colour == 3)
-        m_colour = 0;
-}
-
diff --git a/fdmdv2/src/fdmdv2_plot_waterfall_linux.h b/fdmdv2/src/fdmdv2_plot_waterfall_linux.h
deleted file mode 100644 (file)
index e5c0e83..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-//==========================================================================
-// Name:            fdmdv2_plot_waterfall.h
-// Purpose:         Defines a waterfall plot derivative of fdmdv2_plot.
-// Created:         June 22, 2012
-// Authors:         David Rowe, David Witten
-// 
-// License:
-//
-//  This program is free software; you can redistribute it and/or modify
-//  it under the terms of the GNU General Public License version 2.1,
-//  as published by the Free Software Foundation.  This program is
-//  distributed in the hope that it will be useful, but WITHOUT ANY
-//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
-//  License for more details.
-//
-//  You should have received a copy of the GNU General Public License
-//  along with this program; if not, see <http://www.gnu.org/licenses/>.
-//
-//==========================================================================
-#ifndef __FDMDV2_PLOT_WATERFALL__
-#define __FDMDV2_PLOT_WATERFALL__
-
-#include "fdmdv2_plot.h"
-#include "fdmdv2_defines.h"
-
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
-// Class PlotWaterfall
-//
-// @class $(Name)
-// @author $(User)
-// @date $(Date)
-// @file $(CurrentFileName).$(CurrentFileExt)
-// @brief
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
-class PlotWaterfall : public PlotPanel
-{
-    public:
-    PlotWaterfall(wxFrame* parent, bool graticule, int colour);
-        ~PlotWaterfall();
-        bool checkDT(void);
-        void setGreyscale(bool greyscale) { m_greyscale = greyscale; }
-        void setRxFreq(float rxFreq) { m_rxFreq = rxFreq; }
-
-    protected:
-        unsigned    m_heatmap_lut[256];
-
-        unsigned    heatmap(float val, float min, float max);
-
-        void        OnPaint(wxPaintEvent & evt);
-        void        OnSize(wxSizeEvent& event);
-        void        OnShow(wxShowEvent& event);
-        void        drawGraticule(wxAutoBufferedPaintDC&  dc);
-        void        draw(wxAutoBufferedPaintDC& dc);
-        void        plotPixelData();
-        void        OnMouseLeftDown(wxMouseEvent& event);
-        void        OnMouseRightDown(wxMouseEvent& event);
-
-    private:
-        float       m_dT;
-        float       m_rxFreq;
-        bool        m_graticule;
-        float       m_min_mag;
-        float       m_max_mag;
-        int         m_colour;
-
-        DECLARE_EVENT_TABLE()
-};
-
-#endif //__FDMDV2_PLOT_WATERFALL__