From 57a30c98ea05473e85c68e81b6fffaf645cc4e53 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Fri, 23 Nov 2012 22:39:17 +0000 Subject: [PATCH] higher resn FFT, red tuning line, automatic page switching on tx/rx, works OK on Linux git-svn-id: https://svn.code.sf.net/p/freetel/code@1054 01035d8c-6547-0410-b346-abe4f91aad63 --- fdmdv2/src/fdmdv2_defines.h | 4 +-- fdmdv2/src/fdmdv2_main.cpp | 36 ++++++++++++++++++--- fdmdv2/src/fdmdv2_main.h | 1 + fdmdv2/src/fdmdv2_plot_spectrum.cpp | 8 ++++- fdmdv2/src/fdmdv2_plot_spectrum.h | 2 ++ fdmdv2/src/fdmdv2_plot_waterfall_linux.cpp | 37 +++++++++++++++++----- fdmdv2/src/fdmdv2_plot_waterfall_linux.h | 5 ++- 7 files changed, 75 insertions(+), 18 deletions(-) diff --git a/fdmdv2/src/fdmdv2_defines.h b/fdmdv2/src/fdmdv2_defines.h index f71154d1..616d3855 100644 --- a/fdmdv2/src/fdmdv2_defines.h +++ b/fdmdv2/src/fdmdv2_defines.h @@ -26,12 +26,10 @@ // Spectrogram and Waterfall -#define FDMDV_NSPEC 512 - #define MIN_MAG_DB -40.0 // min of spectrogram/waterfall magnitude axis #define MAX_MAG_DB 0.0 // max of spectrogram/waterfall magnitude axis #define STEP_MAG_DB 5.0 // magnitude axis step -#define BETA 0.9 // constant for time averaging spectrum data +#define BETA 0.95 // constant for time averaging spectrum data #define MIN_F_HZ 0 // min freq on Waterfall and Spectrum #define MAX_F_HZ 4000 // max freq on Waterfall and Spectrum #define STEP_F_HZ 500 // freq step on Waterfall and Spectrum graticule diff --git a/fdmdv2/src/fdmdv2_main.cpp b/fdmdv2/src/fdmdv2_main.cpp index f6ed9c65..5b6c7975 100644 --- a/fdmdv2/src/fdmdv2_main.cpp +++ b/fdmdv2/src/fdmdv2_main.cpp @@ -217,7 +217,8 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent) if(wxGetApp().m_show_wf) { // Add Waterfall Plot window - m_panelWaterfall = new PlotWaterfall((wxFrame*) m_auiNbookCtrl); + + m_panelWaterfall = new PlotWaterfall((wxFrame*) m_auiNbookCtrl, false); m_auiNbookCtrl->AddPage(m_panelWaterfall, _("Waterfall"), true, wxNullBitmap); } if(wxGetApp().m_show_spect) @@ -362,6 +363,8 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent) g_RxFreqOffsetFreqRect.imag = sin(g_RxFreqOffsetHz); g_RxFreqOffsetPhaseRect.real = cos(0.0); g_RxFreqOffsetPhaseRect.imag = sin(0.0); + m_panelWaterfall->setRxFreq(FDMDV_FCENTRE - g_RxFreqOffsetHz); + m_panelSpectrum->setRxFreq(FDMDV_FCENTRE - g_RxFreqOffsetHz); g_TxFreqOffsetHz = 0.0; g_TxFreqOffsetFreqRect.real = cos(g_TxFreqOffsetHz); @@ -476,10 +479,12 @@ MainFrame::~MainFrame() void MainFrame::OnTimer(wxTimerEvent &evt) { if (m_panelWaterfall->checkDT()) { + m_panelWaterfall->setRxFreq(FDMDV_FCENTRE - g_RxFreqOffsetHz); m_panelWaterfall->m_newdata = true; m_panelWaterfall->Refresh(); } + m_panelSpectrum->setRxFreq(FDMDV_FCENTRE - g_RxFreqOffsetHz); m_panelSpectrum->m_newdata = true; m_panelSpectrum->Refresh(); @@ -693,10 +698,15 @@ void MainFrame::OnCheckSNRClick(wxCommandEvent& event) //------------------------------------------------------------------------- void MainFrame::OnTogBtnTXClick(wxCommandEvent& event) { - if (g_tx) - g_tx = 0; - else - g_tx = 1; + if (g_tx) { + // tx-> rx transition, swap to Waterfall + m_auiNbookCtrl->ChangeSelection(0); + } + else { + // rx-> tx transition, swap to Mic In page to monitor speech + m_auiNbookCtrl->ChangeSelection(4); // is there a way to avoid hard coding this? + } + g_tx = m_btnTogTX->GetValue(); event.Skip(); } @@ -1091,11 +1101,27 @@ void MainFrame::OnHelpAbout(wxCommandEvent& event) wxString msg; msg.Printf( wxT("FreeDV: Open Source Narrow Band Digital Voice over Radio\n\n") + wxT("http://freedv.org\n\n") wxT("GNU Public License V2.1\n\n") wxT("Copyright (c) David Witten KD0EAG and David Rowe VK5DGR\n\n") wxT("svn revision: %s\n") + svnLatestRev, SVN_REV); wxMessageBox(msg, wxT("About"), wxOK | wxICON_INFORMATION, this); + +#ifdef TRY_WX_ABOUT + + // DR: I tried this but I like out home made dialog better + + wxAboutDialogInfo aboutInfo; + aboutInfo.SetName("FreeDV"); + aboutInfo.SetVersion(wxT("svn revision: %s\n") + svnLatestRev, SVN_REV); + aboutInfo.SetDescription(_("Open Source Narrow Band Digital Voice over Radio")); + aboutInfo.SetCopyright("Copyright (C) 2012"); + aboutInfo.SetWebSite("http://freedv.org"); + aboutInfo.AddDeveloper("David Witten KD0EAG and David Rowe VK5DGR"); + wxAboutBox(aboutInfo); +#endif + } diff --git a/fdmdv2/src/fdmdv2_main.h b/fdmdv2/src/fdmdv2_main.h index 766815d5..5f436a36 100644 --- a/fdmdv2/src/fdmdv2_main.h +++ b/fdmdv2/src/fdmdv2_main.h @@ -26,6 +26,7 @@ #include #include +#include #include "wx/rawbmp.h" #include "wx/file.h" #include "wx/filename.h" diff --git a/fdmdv2/src/fdmdv2_plot_spectrum.cpp b/fdmdv2/src/fdmdv2_plot_spectrum.cpp index 80fb3793..b4a171fe 100644 --- a/fdmdv2/src/fdmdv2_plot_spectrum.cpp +++ b/fdmdv2/src/fdmdv2_plot_spectrum.cpp @@ -198,6 +198,12 @@ void PlotSpectrum::drawGraticule(wxAutoBufferedPaintDC& dc) 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_rGrid.GetHeight() + m_rCtrl.GetHeight()); } @@ -216,7 +222,7 @@ void PlotSpectrum::OnMouseDown(wxMouseEvent& event) pt.y -= PLOT_BORDER; // valid click if inside of plot - if ((pt.x >= 0) && (pt.x <= m_rGrid.GetWidth()) && (pt.y >=0) && (pt.y < m_rGrid.GetHeight())) { + 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; diff --git a/fdmdv2/src/fdmdv2_plot_spectrum.h b/fdmdv2/src/fdmdv2_plot_spectrum.h index 39173d48..9fa813c5 100644 --- a/fdmdv2/src/fdmdv2_plot_spectrum.h +++ b/fdmdv2/src/fdmdv2_plot_spectrum.h @@ -32,6 +32,7 @@ class PlotSpectrum : public PlotPanel public: PlotSpectrum(wxFrame* parent); ~PlotSpectrum(); + void setRxFreq(float rxFreq) { m_rxFreq = rxFreq; } protected: void OnPaint(wxPaintEvent& event); @@ -42,6 +43,7 @@ class PlotSpectrum : public PlotPanel void OnMouseDown(wxMouseEvent& event); private: + float m_rxFreq; DECLARE_EVENT_TABLE() }; diff --git a/fdmdv2/src/fdmdv2_plot_waterfall_linux.cpp b/fdmdv2/src/fdmdv2_plot_waterfall_linux.cpp index 15c88eac..0d039e78 100644 --- a/fdmdv2/src/fdmdv2_plot_waterfall_linux.cpp +++ b/fdmdv2/src/fdmdv2_plot_waterfall_linux.cpp @@ -45,14 +45,14 @@ END_EVENT_TABLE() // @brief // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-= -PlotWaterfall::PlotWaterfall(wxFrame* parent): PlotPanel(parent) +PlotWaterfall::PlotWaterfall(wxFrame* parent, bool greyscale): PlotPanel(parent) { for(int i = 0; i < 255; i++) { m_heatmap_lut[i] = heatmap((float)i, 0.0, 255.0); } - m_greyscale = 0; + m_greyscale = greyscale; m_Bufsz = GetMaxClientSize(); m_newdata = false; m_firstPass = true; @@ -247,8 +247,8 @@ void PlotWaterfall::drawGraticule(wxAutoBufferedPaintDC& dc) { x = f*freq_hz_to_px; x += PLOT_BORDER + XLEFT_OFFSET; - dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER); - sprintf(buf, "%4.0fHz", f); + dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER); + sprintf(buf, "%4.0fHz", f); GetTextExtent(buf, &text_w, &text_h); dc.DrawText(buf, x - text_w/2, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET); } @@ -265,6 +265,13 @@ void PlotWaterfall::drawGraticule(wxAutoBufferedPaintDC& dc) 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_rGrid.GetHeight() + m_rCtrl.GetHeight()); + } //------------------------------------------------------------------------- @@ -363,9 +370,23 @@ void PlotWaterfall::plotPixelData() if (intensity < 0) intensity = 0; //printf("%d %f %d \n", index, g_avmag[index], intensity); - p.Red() = m_heatmap_lut[intensity] & 0xff; - p.Green() = (m_heatmap_lut[intensity] >> 8) & 0xff; - p.Blue() = (m_heatmap_lut[intensity] >> 16) & 0xff; + if (m_greyscale) { + if (intensity > 200) { + p.Red() = intensity; + p.Green() = intensity; + p.Blue() = intensity; + } + else { + p.Red() = 0; + p.Green() = 0; + p.Blue() = intensity; + } + } + else { + p.Red() = m_heatmap_lut[intensity] & 0xff; + p.Green() = (m_heatmap_lut[intensity] >> 8) & 0xff; + p.Blue() = (m_heatmap_lut[intensity] >> 16) & 0xff; + } ++p; } p = rowStart; @@ -389,7 +410,7 @@ void PlotWaterfall::OnMouseDown(wxMouseEvent& event) pt.y -= PLOT_BORDER; // valid click if inside of plot - if ((pt.x >= 0) && (pt.x <= m_rGrid.GetWidth()) && (pt.y >=0) && (pt.y < m_rGrid.GetHeight())) + 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; diff --git a/fdmdv2/src/fdmdv2_plot_waterfall_linux.h b/fdmdv2/src/fdmdv2_plot_waterfall_linux.h index 4a1d2aed..92ecfa88 100644 --- a/fdmdv2/src/fdmdv2_plot_waterfall_linux.h +++ b/fdmdv2/src/fdmdv2_plot_waterfall_linux.h @@ -37,9 +37,11 @@ class PlotWaterfall : public PlotPanel { public: - PlotWaterfall(wxFrame* parent); + PlotWaterfall(wxFrame* parent, bool greyscale); ~PlotWaterfall(); bool checkDT(void); + void setGreyscale(bool greyscale) { m_greyscale = greyscale; } + void setRxFreq(float rxFreq) { m_rxFreq = rxFreq; } protected: unsigned m_heatmap_lut[256]; @@ -56,6 +58,7 @@ class PlotWaterfall : public PlotPanel private: float m_dT; + float m_rxFreq; DECLARE_EVENT_TABLE() }; -- 2.25.1