From e8125217e52bfb1f042241f8f5189a55fa8eef7b Mon Sep 17 00:00:00 2001 From: drowe67 Date: Mon, 5 Nov 2012 05:04:49 +0000 Subject: [PATCH] improved speech plots with a better decimation algorithm git-svn-id: https://svn.code.sf.net/p/freetel/code@930 01035d8c-6547-0410-b346-abe4f91aad63 --- fdmdv2/src/fdmdv2_defines.h | 4 +- fdmdv2/src/fdmdv2_main.cpp | 72 ++++++++++++++++++++++--------- fdmdv2/src/fdmdv2_plot.h | 8 ++-- fdmdv2/src/fdmdv2_plot_scalar.cpp | 13 ++++++ fdmdv2/src/fdmdv2_plot_scalar.h | 1 + 5 files changed, 71 insertions(+), 27 deletions(-) diff --git a/fdmdv2/src/fdmdv2_defines.h b/fdmdv2/src/fdmdv2_defines.h index 64bf8c40..94f9a5c5 100644 --- a/fdmdv2/src/fdmdv2_defines.h +++ b/fdmdv2/src/fdmdv2_defines.h @@ -54,9 +54,9 @@ // Waveform plotting constants -#define WAVEFORM_PLOT_FS 100 // sample rate (points/s) of waveform plotted to screen +#define WAVEFORM_PLOT_FS 400 // sample rate (points/s) of waveform plotted to screen #define WAVEFORM_PLOT_TIME 5 // length or entire waveform on screen -#define WAVEFORM_PLOT_BUF ((int)(DT*WAVEFORM_PLOT_FS)) // number of sample we add per update +#define WAVEFORM_PLOT_BUF ((int)(DT*WAVEFORM_PLOT_FS)) // number of new samples we plot per DT // sample rate I/O & conversion constants diff --git a/fdmdv2/src/fdmdv2_main.cpp b/fdmdv2/src/fdmdv2_main.cpp index 8d997df6..5608aac5 100644 --- a/fdmdv2/src/fdmdv2_main.cpp +++ b/fdmdv2/src/fdmdv2_main.cpp @@ -39,9 +39,9 @@ struct CODEC2 *g_pCodec2; struct FDMDV *g_pFDMDV; struct FDMDV_STATS g_stats; -short g_speechIn[WAVEFORM_PLOT_BUF]; -short g_speechOut[WAVEFORM_PLOT_BUF]; -short g_demodIn[WAVEFORM_PLOT_BUF]; +struct FIFO *g_plotDemodInFifo; +struct FIFO *g_plotSpeechOutFifo; +struct FIFO *g_plotSpeechInFifo; int g_nSoundCards = 2; @@ -188,7 +188,7 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent) if(wxGetApp().m_show_freq) { // Add Frequency Offset window - m_panelFreqOffset = new PlotScalar((wxFrame*) m_auiNbookCtrl, 5.0, DT, -200, 200, 1, 50, "%3fHz"); + m_panelFreqOffset = new PlotScalar((wxFrame*) m_auiNbookCtrl, 5.0, DT, -200, 200, 1, 50, "%3.0fHz"); m_auiNbookCtrl->AddPage(m_panelFreqOffset, L"Frequency \u0394", true, wxNullBitmap); } @@ -198,6 +198,7 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent) m_panelSpeechIn = new PlotScalar((wxFrame*) m_auiNbookCtrl, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f"); m_auiNbookCtrl->AddPage(m_panelSpeechIn, _("Speech In"), true, wxNullBitmap); + g_plotSpeechInFifo = fifo_create(2*WAVEFORM_PLOT_BUF); } if(wxGetApp().m_show_speech_out) @@ -206,6 +207,7 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent) m_panelSpeechOut = new PlotScalar((wxFrame*) m_auiNbookCtrl, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f"); m_auiNbookCtrl->AddPage(m_panelSpeechOut, _("Speech Out"), true, wxNullBitmap); + g_plotSpeechOutFifo = fifo_create(2*WAVEFORM_PLOT_BUF); } if(wxGetApp().m_show_demod_in) @@ -214,6 +216,7 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent) m_panelDemodIn = new PlotScalar((wxFrame*) m_auiNbookCtrl, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f"); m_auiNbookCtrl->AddPage(m_panelDemodIn, _("Demod In"), true, wxNullBitmap); + g_plotDemodInFifo = fifo_create(2*WAVEFORM_PLOT_BUF); } wxGetApp().m_strRxInAudio = pConfig->Read(wxT("/Audio/RxIn"), wxT("")); @@ -348,20 +351,19 @@ void MainFrame::OnTimer(wxTimerEvent &evt) m_panelFreqOffset->add_new_sample(g_stats.foff); m_panelFreqOffset->Refresh(); - int nsam = DT*WAVEFORM_PLOT_FS; - for(int i=0; iadd_new_sample((float)g_speechIn[i]/32767); - } + short speechInPlotSamples[WAVEFORM_PLOT_BUF]; + fifo_read(g_plotSpeechInFifo, speechInPlotSamples, WAVEFORM_PLOT_BUF); + m_panelSpeechIn->add_new_short_samples(speechInPlotSamples, WAVEFORM_PLOT_BUF, 32767); m_panelSpeechIn->Refresh(); - for(int i=0; iadd_new_sample((float)g_speechOut[i]/32767); - } + short speechOutPlotSamples[WAVEFORM_PLOT_BUF]; + fifo_read(g_plotSpeechOutFifo, speechOutPlotSamples, WAVEFORM_PLOT_BUF); + m_panelSpeechOut->add_new_short_samples(speechOutPlotSamples, WAVEFORM_PLOT_BUF, 32767); m_panelSpeechOut->Refresh(); - for(int i=0; iadd_new_sample((float)g_demodIn[i]/32767); - } + short demodInPlotSamples[WAVEFORM_PLOT_BUF]; + fifo_read(g_plotDemodInFifo, demodInPlotSamples, WAVEFORM_PLOT_BUF); + m_panelDemodIn->add_new_short_samples(demodInPlotSamples, WAVEFORM_PLOT_BUF, 32767); m_panelDemodIn->Refresh(); } #endif @@ -1325,6 +1327,37 @@ static int resample(SRC_STATE *src, } +// Decimates samples using an algorithm that produces nice plots of +// speech signals at a low sample rate. We want a low sample rate so +// we don't hammer the graphics system too hard. Saves decimated data +// to a fifo for plotting on screen. + +static void resample_for_plot(struct FIFO *plotFifo, short buf[], int length) +{ + int decimation = FS/WAVEFORM_PLOT_FS; + int nSamples, sample; + int i, st, en, max, min; + short dec_samples[2*N8]; + + assert(length <= 2*N8); + + nSamples = length/decimation; + + for(sample=0; sample buf[i]) min = buf[i]; + } + dec_samples[sample] = max; + dec_samples[sample+1] = min; + } + + fifo_write(plotFifo, dec_samples, nSamples); +} + //------------------------------------------------------------------------- // rxCallback() //------------------------------------------------------------------------- @@ -1406,8 +1439,7 @@ int MainFrame::rxCallback( n8k = resample(cbData->insrc1, in8k_short, in48k_short, FS, g_soundCard1SampleRate, N8, N48); fifo_write(cbData->rxinfifo, in8k_short, n8k); - assert(sizeof(g_demodIn) <= sizeof(in8k_short)); - memcpy(g_demodIn, in8k_short, sizeof(g_demodIn)); // undersampled buffer for plotting + resample_for_plot(g_plotDemodInFifo, in8k_short, n8k); per_frame_rx_processing(cbData->rxoutfifo, g_CodecBits, cbData->rxinfifo, &g_nRxIn, &g_State, g_pCodec2); @@ -1421,8 +1453,7 @@ int MainFrame::rxCallback( fifo_read(cbData->rxoutfifo, out8k_short, N8); } - assert(sizeof(g_speechOut) <= sizeof(out8k_short)); - memcpy(g_speechOut, out8k_short, sizeof(g_speechOut)); // undersampled buffer for plotting + resample_for_plot(g_plotSpeechOutFifo, out8k_short, N8); if (g_nSoundCards == 1) { nout = resample(cbData->outsrc2, out48k_short, out8k_short, g_soundCard1SampleRate, FS, N48, N8); @@ -1472,9 +1503,6 @@ int MainFrame::rxCallback( nout = resample(cbData->insrc2, in8k_short, in48k_short, FS, g_soundCard2SampleRate, 2*N8, nsam); - assert(sizeof(g_speechIn) <= sizeof(in8k_short)); - memcpy(g_speechIn, in8k_short, sizeof(g_speechIn)); // undersampled buffer for plotting - if (write_file) { fwrite( in8k_short, sizeof(short), nout, g_write_file); } @@ -1486,6 +1514,8 @@ int MainFrame::rxCallback( } } + resample_for_plot(g_plotSpeechInFifo, in8k_short, nout); + per_frame_tx_processing(out8k_short, in8k_short, g_pCodec2); // output 40ms of modem tone diff --git a/fdmdv2/src/fdmdv2_plot.h b/fdmdv2/src/fdmdv2_plot.h index fb220e49..a57cd6dd 100644 --- a/fdmdv2/src/fdmdv2_plot.h +++ b/fdmdv2/src/fdmdv2_plot.h @@ -30,11 +30,11 @@ #define wxUSE_PCX 1 #define wxUSE_LIBTIFF 1 -#define PLOT_BORDER 8 +#define PLOT_BORDER 12 #define XLEFT_OFFSET 30 -#define XLEFT_TEXT_OFFSET 8 -#define YBOTTOM_OFFSET 25 -#define YBOTTOM_TEXT_OFFSET 8 +#define XLEFT_TEXT_OFFSET 6 +#define YBOTTOM_OFFSET 20 +#define YBOTTOM_TEXT_OFFSET 6 #define GRID_INCREMENT 50 #define BLACK_COLOR wxColor(0x00, 0x00, 0x00) diff --git a/fdmdv2/src/fdmdv2_plot_scalar.cpp b/fdmdv2/src/fdmdv2_plot_scalar.cpp index 8bc90afb..49d57e6d 100644 --- a/fdmdv2/src/fdmdv2_plot_scalar.cpp +++ b/fdmdv2/src/fdmdv2_plot_scalar.cpp @@ -95,6 +95,19 @@ void PlotScalar::add_new_sample(float sample) m_mem[m_samples-1] = sample; } +//---------------------------------------------------------------- +// add_new_samples() +//---------------------------------------------------------------- +void PlotScalar::add_new_short_samples(short samples[], int length, float scale_factor) +{ + int i; + + for(i = 0; i < m_samples-length; i++) + m_mem[i] = m_mem[i+length]; + for(; i < m_samples; i++) + m_mem[i] = (float)*samples++/scale_factor; +} + //---------------------------------------------------------------- // draw() //---------------------------------------------------------------- diff --git a/fdmdv2/src/fdmdv2_plot_scalar.h b/fdmdv2/src/fdmdv2_plot_scalar.h index 1f69b32d..e6b64e6e 100644 --- a/fdmdv2/src/fdmdv2_plot_scalar.h +++ b/fdmdv2/src/fdmdv2_plot_scalar.h @@ -46,6 +46,7 @@ class PlotScalar: public PlotPanel ); ~PlotScalar(); void add_new_sample(float sample); + void add_new_short_samples(short samples[], int length, float scale_factor); protected: -- 2.25.1