From: drowe67 Date: Wed, 21 Nov 2012 04:32:21 +0000 (+0000) Subject: first pass at click to tune for rx. It works OK, but the communication of the click... X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=34d7059159c87378c4b8187cc8714e895a2b450d;p=freetel-svn-tracking.git first pass at click to tune for rx. It works OK, but the communication of the click freq sucks so I might try re-writing that bit git-svn-id: https://svn.code.sf.net/p/freetel/code@1041 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/fdmdv2/src/Makefile.linux b/fdmdv2/src/Makefile.linux index ac444e0f..bde04f04 100644 --- a/fdmdv2/src/Makefile.linux +++ b/fdmdv2/src/Makefile.linux @@ -33,10 +33,10 @@ dlg_options.o HDRS = fdmdv2_main.h fdmdv2_defines.h fdmdv2_plot.h fdmdv2_plot_scalar.h fdmdv2_plot_waterfall_linux.h fdmdv2_plot_scatter.h fdmdv2_plot_spectrum.h fdmdv2_pa_wrapper.h topFrame.h dlg_audiooptions.h -all: fdmdv2 +all: freedv -fdmdv2: $(OBJS) - g++ -o fdmdv2 $(OBJS) $(CPP_FLAGS) $(LIBS) +freedv: $(OBJS) + g++ -o freedv $(OBJS) $(CPP_FLAGS) $(LIBS) %.o: %.cpp $(HDRS) Makefile.linux g++ $(CPP_FLAGS) -c $< -o $@ diff --git a/fdmdv2/src/Makefile.win32 b/fdmdv2/src/Makefile.win32 index bdadcd9c..69260510 100644 --- a/fdmdv2/src/Makefile.win32 +++ b/fdmdv2/src/Makefile.win32 @@ -33,10 +33,10 @@ dlg_options.o HDRS = fdmdv2_main.h fdmdv2_defines.h fdmdv2_plot.h fdmdv2_plot_scalar.h fdmdv2_plot_waterfall_linux.h fdmdv2_plot_scatter.h fdmdv2_plot_spectrum.h fdmdv2_pa_wrapper.h topFrame.h dlg_audiooptions.h -all: fdmdv2 +all: freedv -fdmdv2: $(OBJS) - g++ -o fdmdv2 $(OBJS) $(CPP_FLAGS) $(LIBS) +freedv: $(OBJS) + g++ -o freedv $(OBJS) $(CPP_FLAGS) $(LIBS) %.o: %.cpp $(HDRS) Makefile.win32 g++ $(CPP_FLAGS) -c $< -o $@ diff --git a/fdmdv2/src/fdmdv2_main.cpp b/fdmdv2/src/fdmdv2_main.cpp index 6335fdae..1c2f4741 100644 --- a/fdmdv2/src/fdmdv2_main.cpp +++ b/fdmdv2/src/fdmdv2_main.cpp @@ -132,7 +132,7 @@ bool MainApp::OnInit() return false; } SetVendorName(wxT("CODEC2-Project")); - SetAppName(wxT("FDMDV2")); // not needed, it's the default value + SetAppName(wxT("FreeDV")); // not needed, it's the default value wxConfigBase *pConfig = wxConfigBase::Get(); pConfig->SetRecordDefaults(); @@ -210,12 +210,14 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent) // Add Waterfall Plot window m_panelWaterfall = new PlotWaterfall((wxFrame*) m_auiNbookCtrl); m_auiNbookCtrl->AddPage(m_panelWaterfall, _("Waterfall"), true, wxNullBitmap); + m_panelWaterfall->setClickFreq(FDMDV_FCENTRE); } if(wxGetApp().m_show_spect) { // Add Spectrum Plot window m_panelSpectrum = new PlotSpectrum((wxFrame*) m_auiNbookCtrl); m_auiNbookCtrl->AddPage(m_panelSpectrum, _("Spectrum"), true, wxNullBitmap); + m_panelSpectrum->setClickFreq(FDMDV_FCENTRE); } if(wxGetApp().m_show_scatter) { @@ -338,7 +340,15 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent) g_loopPlayFileToMicIn = false; g_sfRecFile = NULL; g_recFileFromRadio = false; - //g_parent = parent; + + // init click-tune states + + g_RxFreqOffsetHz = 0.0; + g_RxFreqOffsetFreqRect.real = cos(g_RxFreqOffsetHz); + g_RxFreqOffsetFreqRect.imag = sin(g_RxFreqOffsetHz); + g_RxFreqOffsetPhaseRect.real = cos(0.0); + g_RxFreqOffsetPhaseRect.imag = sin(0.0); + } //------------------------------------------------------------------------- @@ -435,8 +445,8 @@ MainFrame::~MainFrame() // OnTimer() //---------------------------------------------------------------- -// when the timer fires every DT seconds we update the GUI displays -// On the tabbed display that is visible actually gets updated, this +// when the timer fires every DT seconds we update the GUI displays. +// the tabs only the plot that is visible actually gets updated, this // keeps CPU load reasonable void MainFrame::OnTimer(wxTimerEvent &evt) @@ -450,13 +460,32 @@ void MainFrame::OnTimer(wxTimerEvent &evt) m_panelScatter->add_new_samples(g_stats.rx_symbols); m_panelScatter->Refresh(); - m_panelTimeOffset->add_new_sample((float)g_stats.rx_timing/FDMDV_NOM_SAMPLES_PER_FRAME); - m_panelTimeOffset->Refresh(); - - m_panelFreqOffset->add_new_sample(g_stats.foff); - m_panelFreqOffset->Refresh(); - - // Osciliscope type speech plots ------------------------------------------------------- + // This is a convenient time to update the click-tune frequency + // The demod is hard-wired to expect a centre frequency of + // FDMDV_FCENTRE. So we want to take the signal centered on the + // click tune freq and re-centre it on FDMDV_FCENTRE. For example + // if the click tune freq is 1500Hz, and FDMDV_CENTRE is 1200 Hz, + // we need to shift the input signal centred on 1500Hz down to + // 1200Hz, an offset of -300Hz. + + // The current design has the last click freq stored in both the + // Waterfall and the Spectrum. This is messy. What would be + // better is the musedown event setting the global freq offset + // directl, or communicating via an event to this thread. + + if (m_auiNbookCtrl->GetCurrentPage() == m_panelWaterfall) { + g_RxFreqOffsetHz = FDMDV_FCENTRE - m_panelWaterfall->getClickFreq(); + m_panelSpectrum->setClickFreq(m_panelWaterfall->getClickFreq()); + //printf("Waterfall g_RxFreqOffsetHz: %f\n", g_RxFreqOffsetHz); + } + + if (m_auiNbookCtrl->GetCurrentPage() == m_panelSpectrum) { + g_RxFreqOffsetHz = FDMDV_FCENTRE - m_panelSpectrum->getClickFreq(); + m_panelWaterfall->setClickFreq(m_panelSpectrum->getClickFreq()); + //printf("Spectrum g_RxFreqOffsetHz: %f\n", g_RxFreqOffsetHz); + } + + // Oscilliscope type speech plots ------------------------------------------------------- short speechInPlotSamples[WAVEFORM_PLOT_BUF]; if (fifo_read(g_plotSpeechInFifo, speechInPlotSamples, WAVEFORM_PLOT_BUF)) @@ -476,6 +505,14 @@ void MainFrame::OnTimer(wxTimerEvent &evt) m_panelDemodIn->add_new_short_samples(demodInPlotSamples, WAVEFORM_PLOT_BUF, 32767); m_panelDemodIn->Refresh(); + // Demod states ----------------------------------------------------------------------- + + m_panelTimeOffset->add_new_sample((float)g_stats.rx_timing/FDMDV_NOM_SAMPLES_PER_FRAME); + m_panelTimeOffset->Refresh(); + + m_panelFreqOffset->add_new_sample(g_stats.foff); + m_panelFreqOffset->Refresh(); + // SNR text box and guage ------------------------------------------------------------ float snr_limited = g_stats.snr_est; @@ -490,14 +527,14 @@ void MainFrame::OnTimer(wxTimerEvent &evt) if (snr_limited > 20.0) snr_limited = 20.0; m_gaugeSNR->SetValue((int)(snr_limited)); - // sync LED + // sync LED (Colours don't work on Windows) if (g_State) { - m_rbSync->SetForegroundColour( wxColour( 0, 255, 0 ) ); + m_rbSync->SetForegroundColour( wxColour( 0, 255, 0 ) ); // green m_rbSync->SetValue(true); } else { - m_rbSync->SetForegroundColour( wxColour( 255, 0, 0 ) ); + m_rbSync->SetForegroundColour( wxColour( 255, 0, 0 ) ); // red m_rbSync->SetValue(false); } } @@ -1116,13 +1153,12 @@ void MainFrame::OnHelpAbout(wxCommandEvent& event) if(url.GetError() == wxURL_NOERR) { - printf("URL OK\n"); wxString htmldata; wxInputStream *in = url.GetInputStream(); if(in && in->IsOk()) { - printf("In OK\n"); + //printf("In OK\n"); wxStringOutputStream html_stream(&htmldata); in->Read(html_stream); wxLogDebug(htmldata); @@ -1131,17 +1167,15 @@ void MainFrame::OnHelpAbout(wxCommandEvent& event) int startIndex = htmldata.find(s) + s.Length(); int endIndex = htmldata.find(wxT(": /fdmdv2")); svnLatestRev = wxT("Latest svn revision: ") + htmldata.SubString(startIndex, endIndex-1); - printf("startIndex: %d endIndex: %d\n", startIndex, endIndex); + //printf("startIndex: %d endIndex: %d\n", startIndex, endIndex); } delete in; } - else - printf("failed to parse URL\n"); wxString msg; - msg.Printf( wxT("FreeDV: Narrow Band Digital Voice over Radio Application.\n\n") - wxT("GNU Public License V2.1\n") + msg.Printf( wxT("FreeDV: Open Source Narrow Band Digital Voice over Radio\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); @@ -1197,14 +1231,6 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event) g_State = 0; printf("g_stats.snr: %f\n", g_stats.snr_est); - // init click-tune states - - g_RxFreqOffsetHz = 50.0; - g_RxFreqOffsetFreqRect.real = cos(g_RxFreqOffsetHz); - g_RxFreqOffsetFreqRect.imag = sin(g_RxFreqOffsetHz); - g_RxFreqOffsetPhaseRect.real = cos(0.0); - g_RxFreqOffsetPhaseRect.imag = sin(0.0); - // attempt to start sound cards and tx/rx processing startRxStream(); @@ -1684,7 +1710,7 @@ void txRxProcessing() short out48k_short[2*N48]; int nout; - //wxLogDebug("start infifo1: %5d outfifo1: %5d\n", fifo_n(cbData->infifo1), fifo_n(cbData->outfifo1)); + //wxLogDebug("start infifo1: %5d outfifo1: %5d\n", fifo_n(cbData->infifo1), fifo_n(cbData->outfifo1)); // // RX side processing -------------------------------------------- diff --git a/fdmdv2/src/fdmdv2_plot.cpp b/fdmdv2/src/fdmdv2_plot.cpp index 97b72757..bc62c8dd 100644 --- a/fdmdv2/src/fdmdv2_plot.cpp +++ b/fdmdv2/src/fdmdv2_plot.cpp @@ -144,7 +144,6 @@ void PlotPanel::OnMouseMove(wxMouseEvent& event) //------------------------------------------------------------------------- void PlotPanel::OnMouseDown(wxMouseEvent& event) { - m_mouseDown = true; } //------------------------------------------------------------------------- diff --git a/fdmdv2/src/fdmdv2_plot.h b/fdmdv2/src/fdmdv2_plot.h index f887178f..9b23f096 100644 --- a/fdmdv2/src/fdmdv2_plot.h +++ b/fdmdv2/src/fdmdv2_plot.h @@ -109,7 +109,7 @@ class PlotPanel : public wxPanel // some useful events void OnMouseMove(wxMouseEvent& event); - void OnMouseDown(wxMouseEvent& event); + virtual void OnMouseDown(wxMouseEvent& event); void OnMouseUp(wxMouseEvent& event); void OnMouseWheelMoved(wxMouseEvent& event); void OnClose(wxCloseEvent& event ){ event.Skip(); } diff --git a/fdmdv2/src/fdmdv2_plot_spectrum.cpp b/fdmdv2/src/fdmdv2_plot_spectrum.cpp index 8da96534..0a18b9b6 100644 --- a/fdmdv2/src/fdmdv2_plot_spectrum.cpp +++ b/fdmdv2/src/fdmdv2_plot_spectrum.cpp @@ -200,3 +200,24 @@ void PlotSpectrum::drawGraticule(wxAutoBufferedPaintDC& dc) } +//------------------------------------------------------------------------- +// OnMouseDown() +//------------------------------------------------------------------------- +void PlotSpectrum::OnMouseDown(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) && (pt.y < m_rGrid.GetHeight())) { + float freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ); + m_clickFreq = (float)pt.x/freq_hz_to_px; + printf("PlotSpectrum::OnMouseDown m_clickFreq: %f\n", m_clickFreq); + } +} diff --git a/fdmdv2/src/fdmdv2_plot_spectrum.h b/fdmdv2/src/fdmdv2_plot_spectrum.h index d6e94e16..b7187f70 100644 --- a/fdmdv2/src/fdmdv2_plot_spectrum.h +++ b/fdmdv2/src/fdmdv2_plot_spectrum.h @@ -33,12 +33,19 @@ class PlotSpectrum : public PlotPanel PlotSpectrum(wxFrame* parent); ~PlotSpectrum(); + void setClickFreq(float clickFreq) { m_clickFreq = clickFreq; } + float getClickFreq(void) { return m_clickFreq; } + protected: void OnPaint(wxPaintEvent& event); void OnSize(wxSizeEvent& event); void OnShow(wxShowEvent& event); void drawGraticule(wxAutoBufferedPaintDC& dc); void draw(wxAutoBufferedPaintDC& dc); + void OnMouseDown(wxMouseEvent& event); + + private: + float m_clickFreq; DECLARE_EVENT_TABLE() }; diff --git a/fdmdv2/src/fdmdv2_plot_waterfall.h b/fdmdv2/src/fdmdv2_plot_waterfall.h index 38d62856..0d5e0226 100644 --- a/fdmdv2/src/fdmdv2_plot_waterfall.h +++ b/fdmdv2/src/fdmdv2_plot_waterfall.h @@ -56,7 +56,6 @@ class PlotWaterfall : public PlotPanel void draw(wxAutoBufferedPaintDC& pdc); void plotPixelData(wxAutoBufferedPaintDC& dc); void drawData(); // wxMemoryDC& pDC); - void drawData2(wxMemoryDC& pDC, int barpos, int l, int t, int w, int h); DECLARE_EVENT_TABLE() }; diff --git a/fdmdv2/src/fdmdv2_plot_waterfall_linux.cpp b/fdmdv2/src/fdmdv2_plot_waterfall_linux.cpp index e9ade682..9a019da1 100644 --- a/fdmdv2/src/fdmdv2_plot_waterfall_linux.cpp +++ b/fdmdv2/src/fdmdv2_plot_waterfall_linux.cpp @@ -183,8 +183,8 @@ void PlotWaterfall::draw(wxAutoBufferedPaintDC& dc) // no data to plot so just erase to black. Blue looks nicer // but is same colour as low amplitude signal - // Bug: When Stop is pressed this code doesn't erase the lower - // 25% of the Waterfall Window + // 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); @@ -355,3 +355,26 @@ void PlotWaterfall::plotPixelData() p.OffsetY(data, 1); } } + +//------------------------------------------------------------------------- +// OnMouseDown() +//------------------------------------------------------------------------- +void PlotWaterfall::OnMouseDown(wxMouseEvent& event) +{ + printf("PlotWaterfall::OnMouseDown\n"); + 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) && (pt.y < m_rGrid.GetHeight())) { + float freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ); + m_clickFreq = (float)pt.x/freq_hz_to_px; + printf("PlotWaterfall::OnMouseDown m_clickFreq: %f\n", m_clickFreq); + } +} diff --git a/fdmdv2/src/fdmdv2_plot_waterfall_linux.h b/fdmdv2/src/fdmdv2_plot_waterfall_linux.h index 4e9380ac..b54270c6 100644 --- a/fdmdv2/src/fdmdv2_plot_waterfall_linux.h +++ b/fdmdv2/src/fdmdv2_plot_waterfall_linux.h @@ -39,6 +39,8 @@ class PlotWaterfall : public PlotPanel public: PlotWaterfall(wxFrame* parent); ~PlotWaterfall(); + void setClickFreq(float clickFreq) { m_clickFreq = clickFreq; } + float getClickFreq(void) { return m_clickFreq; } protected: unsigned m_heatmap_lut[256]; @@ -51,6 +53,10 @@ class PlotWaterfall : public PlotPanel void drawGraticule(wxAutoBufferedPaintDC& dc); void draw(wxAutoBufferedPaintDC& dc); void plotPixelData(); + void OnMouseDown(wxMouseEvent& event); + + private: + float m_clickFreq; DECLARE_EVENT_TABLE() }; diff --git a/fdmdv2/src/topFrame.h b/fdmdv2/src/topFrame.h index adb05142..2450d958 100644 --- a/fdmdv2/src/topFrame.h +++ b/fdmdv2/src/topFrame.h @@ -167,7 +167,7 @@ class TopFrame : public wxFrame wxAuiNotebook* m_auiNbookCtrl; - TopFrame( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("FDMDV2"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 761,500 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + TopFrame( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("FreeDV"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 761,500 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); ~TopFrame(); @@ -193,7 +193,7 @@ class DlgAbout : public wxDialog public: - DlgAbout( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About FDMDV2"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 352,343 ), long style = wxDEFAULT_DIALOG_STYLE ); + DlgAbout( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About FreeDV"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 352,343 ), long style = wxDEFAULT_DIALOG_STYLE ); ~DlgAbout(); };