From 5b93cb456bf0247e802b60fed21afd6f494e4a09 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Sun, 15 Jan 2017 22:35:51 +0000 Subject: [PATCH] first pass at eye diagram for 800XA git-svn-id: https://svn.code.sf.net/p/freetel/code@2978 01035d8c-6547-0410-b346-abe4f91aad63 --- freedv-dev/src/fdmdv2_defines.h | 1 + freedv-dev/src/fdmdv2_main.cpp | 60 ++++++--- freedv-dev/src/fdmdv2_plot_scatter.cpp | 162 +++++++++++++++++++------ freedv-dev/src/fdmdv2_plot_scatter.h | 13 +- 4 files changed, 178 insertions(+), 58 deletions(-) diff --git a/freedv-dev/src/fdmdv2_defines.h b/freedv-dev/src/fdmdv2_defines.h index c1f8c327..a6878890 100644 --- a/freedv-dev/src/fdmdv2_defines.h +++ b/freedv-dev/src/fdmdv2_defines.h @@ -46,6 +46,7 @@ // (symbols/frame)/(graphics update period) = symbols/s sent to scatter memory // memory (symbols) = secs of memory * symbols/sec #define SCATTER_MEM_SYMS_MAX ((int)(SCATTER_MEM_SECS*((MODEM_STATS_NC_MAX+1)/DT))) +#define SCATTER_EYE_MEM_ROWS ((int)(SCATTER_MEM_SECS/DT)) // Waveform plotting constants diff --git a/freedv-dev/src/fdmdv2_main.cpp b/freedv-dev/src/fdmdv2_main.cpp index 134502e0..ef69c23b 100644 --- a/freedv-dev/src/fdmdv2_main.cpp +++ b/freedv-dev/src/fdmdv2_main.cpp @@ -967,31 +967,44 @@ void MainFrame::OnTimer(wxTimerEvent &evt) m_panelSpectrum->m_newdata = true; m_panelSpectrum->Refresh(); - /* update scatter plot -----------------------------------------------------------------*/ + /* update scatter/eye plot ------------------------------------------------------------*/ - for (r=0; radd_new_samples(&g_stats.rx_symbols[r][0]); + /* add samples row by row */ + + int i; + for (i=0; iadd_new_samples_eye(&g_stats.rx_eye[i][0], g_stats.neyesamp); } + } + else { + /* PSK Modes - scatter plot -------------------------------------------------------*/ + for (r=0; radd_new_samples_scatter(&g_stats.rx_symbols[r][0]); + } + + if ((freedv_get_mode(g_pfreedv) == FREEDV_MODE_700B) || (freedv_get_mode(g_pfreedv) == FREEDV_MODE_700C)) { - /* - FreeDV 700 uses diversity, so combine symbols for - scatter plot, as combined symbols are used for - demodulation. Note we need to use a copy of the - symbols, as we are not sure when the stats will be - updated. - */ - - COMP rx_symbols_copy[g_Nc/2]; - - for(c=0; cadd_new_samples(rx_symbols_copy); - } + /* + FreeDV 700 uses diversity, so combine symbols for + scatter plot, as combined symbols are used for + demodulation. Note we need to use a copy of the + symbols, as we are not sure when the stats will be + updated. + */ + + COMP rx_symbols_copy[g_Nc/2]; + + for(c=0; cadd_new_samples_scatter(rx_symbols_copy); + } + } } m_panelScatter->Refresh(); @@ -2431,6 +2444,13 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event) g_snr = 0.0; g_half_duplex = wxGetApp().m_boolHalfDuplex; + if (g_mode == FREEDV_MODE_800XA) { + m_panelScatter->setEyeScatter(PLOT_SCATTER_MODE_EYE); + } + else { + m_panelScatter->setEyeScatter(PLOT_SCATTER_MODE_SCATTER); + } + m_pcallsign = m_callsign; memset(m_callsign, 0, sizeof(m_callsign)); m_checksumGood = m_checksumBad = 0; @@ -3617,7 +3637,7 @@ void per_frame_rx_processing( } freq_shift_coh(rx_fdm_offset, rx_fdm, g_RxFreqOffsetHz, freedv_get_modem_sample_rate(g_pfreedv), &g_RxFreqOffsetPhaseRect, nin); nout = freedv_comprx(g_pfreedv, output_buf, rx_fdm_offset); - printf("nout %d outbuf_buf[0]: %d\n", nout, output_buf[0]); + //kprintf("nout %d outbuf_buf[0]: %d\n", nout, output_buf[0]); fifo_write(output_fifo, output_buf, nout); nin = freedv_nin(g_pfreedv); diff --git a/freedv-dev/src/fdmdv2_plot_scatter.cpp b/freedv-dev/src/fdmdv2_plot_scatter.cpp index 85b2a573..12957f44 100644 --- a/freedv-dev/src/fdmdv2_plot_scatter.cpp +++ b/freedv-dev/src/fdmdv2_plot_scatter.cpp @@ -44,14 +44,18 @@ PlotScatter::PlotScatter(wxFrame* parent) : PlotPanel(parent) m_mem[i].imag = 0.0; } - m_filter_max_xy = 0.1; + m_filter_max_xy = m_filter_max_y = 0.1; // defaults so we start off with something sensible Nsym = 14+1; scatterMemSyms = ((int)(SCATTER_MEM_SECS*(Nsym/DT))); assert(scatterMemSyms <= SCATTER_MEM_SYMS_MAX); - + + Ncol = 0; + memset(eye_mem, 0, sizeof(eye_mem)); + + mode = PLOT_SCATTER_MODE_SCATTER; } // changing number of carriers changes number of symbols to plot @@ -69,7 +73,7 @@ void PlotScatter::draw(wxAutoBufferedPaintDC& dc) { float x_scale; float y_scale; - int i; + int i,j; int x; int y; wxColour sym_to_colour[] = {wxColor(0,0,255), @@ -109,52 +113,114 @@ void PlotScatter::draw(wxAutoBufferedPaintDC& dc) wxPen pen; pen.SetWidth(1); // note this is ignored by DrawPoint - // automatically scale, first measure the maximum value - - float max_xy = 1E-12; - float real,imag; - for(i=0; i< scatterMemSyms; i++) { - real = fabs(m_mem[i].real); - imag = fabs(m_mem[i].imag); - if (real > max_xy) - max_xy = real; - if (imag > max_xy) - max_xy = imag; - } + if (mode == PLOT_SCATTER_MODE_SCATTER) { - // smooth it out and set a lower limit to prevent didev by 0 issues + // automatically scale, first measure the maximum value - m_filter_max_xy = BETA*m_filter_max_xy + (1 - BETA)*2.5*max_xy; - if (m_filter_max_xy < 0.001) - m_filter_max_xy = 0.001; + float max_xy = 1E-12; + float real,imag; + for(i=0; i< scatterMemSyms; i++) { + real = fabs(m_mem[i].real); + imag = fabs(m_mem[i].imag); + if (real > max_xy) + max_xy = real; + if (imag > max_xy) + max_xy = imag; + } - // quantise to log steps to prevent scatter scaling bobbing about too - // much as scaling varies + // smooth it out and set a lower limit to prevent divide by 0 issues - float quant_m_filter_max_xy = exp(floor(0.5+log(m_filter_max_xy))); - //printf("max_xy: %f m_filter_max_xy: %f quant_m_filter_max_xy: %f\n", max_xy, m_filter_max_xy, quant_m_filter_max_xy); + m_filter_max_xy = BETA*m_filter_max_xy + (1 - BETA)*2.5*max_xy; + if (m_filter_max_xy < 0.001) + m_filter_max_xy = 0.001; - x_scale = (float)m_rGrid.GetWidth()/quant_m_filter_max_xy; - y_scale = (float)m_rGrid.GetHeight()/quant_m_filter_max_xy; + // quantise to log steps to prevent scatter scaling bobbing about too + // much as scaling varies - // draw all samples + float quant_m_filter_max_xy = exp(floor(0.5+log(m_filter_max_xy))); + //printf("max_xy: %f m_filter_max_xy: %f quant_m_filter_max_xy: %f\n", max_xy, m_filter_max_xy, quant_m_filter_max_xy); - for(i = 0; i < scatterMemSyms; i++) - { - x = x_scale * m_mem[i].real + m_rGrid.GetWidth()/2; - y = y_scale * m_mem[i].imag + m_rGrid.GetHeight()/2; - x += PLOT_BORDER + XLEFT_OFFSET; - y += PLOT_BORDER; - pen.SetColour(sym_to_colour[i%Nsym]); + x_scale = (float)m_rGrid.GetWidth()/quant_m_filter_max_xy; + y_scale = (float)m_rGrid.GetHeight()/quant_m_filter_max_xy; + + // draw all samples + + for(i = 0; i < scatterMemSyms; i++) { + x = x_scale * m_mem[i].real + m_rGrid.GetWidth()/2; + y = y_scale * m_mem[i].imag + m_rGrid.GetHeight()/2; + x += PLOT_BORDER + XLEFT_OFFSET; + y += PLOT_BORDER; + pen.SetColour(sym_to_colour[i%Nsym]); + dc.SetPen(pen); + dc.DrawPoint(x, y); + } + } + + if (mode == PLOT_SCATTER_MODE_EYE) { + + pen.SetColour(DARK_GREEN_COLOR); + pen.SetWidth(1); dc.SetPen(pen); - dc.DrawPoint(x, y); + + // automatically scale, first measure the maximum Y value + + float max_y = 1E-12; + float min_y = 1E+12; + for(i=0; i max_y) { + max_y = eye_mem[i][j]; + } + if (eye_mem[i][j] < min_y) { + min_y = eye_mem[i][j]; + } + } + } + + // smooth it out and set a lower limit to prevent divide by 0 issues + + m_filter_max_y = BETA*m_filter_max_y + (1 - BETA)*2.5*max_y; + if (m_filter_max_y < 0.001) + m_filter_max_y = 0.001; + + // quantise to log steps to prevent scatter scaling bobbing about too + // much as scaling varies + + float quant_m_filter_max_y = exp(floor(0.5+log(m_filter_max_y))); + //printf("min_y: %4.3f max_y: %4.3f quant_m_filter_max_y: %4.3f\n", min_y, max_y, quant_m_filter_max_y); + + x_scale = (float)m_rGrid.GetWidth()/Ncol; + y_scale = (float)m_rGrid.GetHeight()/quant_m_filter_max_y; + //printf("GetWidth(): %d GetHeight(): %d\n", m_rGrid.GetWidth(), m_rGrid.GetHeight()); + + // plot eye traces row by row + + int prev_x, prev_y; + prev_x = prev_y = 0; + for(i=0; i