first pass at a test tool for audio config dialog that plots input to a little screen...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 13 Nov 2012 08:18:53 +0000 (08:18 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 13 Nov 2012 08:18:53 +0000 (08:18 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@967 01035d8c-6547-0410-b346-abe4f91aad63

fdmdv2/src/Makefile.linux
fdmdv2/src/Makefile.win32
fdmdv2/src/dlg_audiooptions.cpp
fdmdv2/src/dlg_audiooptions.h
fdmdv2/src/fdmdv2_main.cpp
fdmdv2/src/fdmdv2_main.h
fdmdv2/src/fdmdv2_plot_scalar.cpp
fdmdv2/src/fdmdv2_plot_scalar.h

index c3315f37203e6bd304e4a46eaf63e59f638ebe59..0bd976613f4c3f9e2250f432c065f16a724f7da4 100644 (file)
@@ -30,7 +30,7 @@ dlg_audiooptions.o \
 dlg_comports.o \
 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
+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
 
index 33fe92cdd158356cd9c2fe47c3d14d70751a115f..d7475f8c42899c3a212e42c07424c6414615ff8c 100644 (file)
@@ -30,7 +30,7 @@ dlg_audiooptions.o \
 dlg_comports.o \
 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
+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
 
index cd3d4add73b504dba1499861d39f0aba6a04c71a..1d62c0ba4f403e7a7c634dbc285457c670d3a9bd 100644 (file)
 #include "fdmdv2_main.h"
 #include "dlg_audiooptions.h"
 
+// constants for test waveform plots
+
+#define TEST_WAVEFORM_X          100
+#define TEST_WAVEFORM_Y          100
+#define TEST_WAVEFORM_PLOT_TIME  2.0
+#define TEST_WAVEFORM_PLOT_FS    400
+#define TEST_BUF_SIZE           1024
+#define TEST_FS                 48000.0
+#define TEST_DT                 0.1      // time between plot updates in seconds
+#define TEST_WAVEFORM_PLOT_BUF  ((int)(DT*400))
+
 void AudioOptsDialog::Pa_Init(void)
 {
     m_isPaInitialized = false;
@@ -29,6 +40,17 @@ void AudioOptsDialog::Pa_Init(void)
 }
 
 
+void AudioOptsDialog::buildTestControls(PlotScalar **plotScalar, wxButton **btnTest, wxPanel *parentPanel, wxBoxSizer *bSizer)
+{
+    *btnTest = new wxButton(parentPanel, wxID_ANY, _("Test"), wxDefaultPosition, wxDefaultSize);
+    bSizer->Add(*btnTest, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2);
+
+    wxPanel *panel = new wxPanel(parentPanel, wxID_ANY, wxDefaultPosition, wxSize(TEST_WAVEFORM_X, TEST_WAVEFORM_Y), 0);
+    *plotScalar = new PlotScalar((wxFrame*) panel, TEST_WAVEFORM_PLOT_TIME, 1.0/TEST_WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "", 1);
+    (*plotScalar)->SetClientSize(wxSize(TEST_WAVEFORM_X,TEST_WAVEFORM_Y));
+    bSizer->Add(panel, 0);
+}
+
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
 // AudioOptsDialog()
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
@@ -64,7 +86,18 @@ AudioOptsDialog::AudioOptsDialog(wxWindow* parent, wxWindowID id, const wxString
     m_staticText6->Wrap(-1);
     bSizer811->Add(m_staticText6, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);
     m_cbSampleRateRxIn = new wxComboBox(m_panelRx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_DROPDOWN);
-    bSizer811->Add(m_cbSampleRateRxIn, 0, wxALL, 2);
+    bSizer811->Add(m_cbSampleRateRxIn, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2);
+
+    buildTestControls(&m_plotScalarRxIn, &m_btnRxInTest, m_panelRx, bSizer811);
+    /*
+    m_btnRxInTest = new wxButton(m_panelRx, wxID_ANY, _("Test"), wxDefaultPosition, wxDefaultSize);
+    bSizer811->Add(m_btnRxInTest, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2);
+    m_panelRxInTest = new wxPanel(m_panelRx, wxID_ANY, wxDefaultPosition, wxSize(TEST_WAVEFORM_X, TEST_WAVEFORM_Y), 0);
+    m_plotScalarRxIn = new PlotScalar((wxFrame*) m_panelRxInTest, TEST_WAVEFORM_PLOT_TIME, 1.0/TEST_WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "", 1);
+    m_plotScalarRxIn->SetClientSize(wxSize(TEST_WAVEFORM_X,TEST_WAVEFORM_Y));
+    bSizer811->Add(m_panelRxInTest, 0);
+    */
+
     sbSizer2->Add(bSizer811, 0, wxEXPAND, 5);
     gSizer4->Add(sbSizer2, 1, wxEXPAND, 5);
 
@@ -249,6 +282,9 @@ AudioOptsDialog::AudioOptsDialog(wxWindow* parent, wxWindowID id, const wxString
     m_listCtrlRxOutDevices->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( AudioOptsDialog::OnRxOutDeviceSelect ), NULL, this );
     m_listCtrlTxInDevices->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( AudioOptsDialog::OnTxInDeviceSelect ), NULL, this );
     m_listCtrlTxOutDevices->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( AudioOptsDialog::OnTxOutDeviceSelect ), NULL, this );
+
+    m_btnRxInTest->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnRxInTest ), NULL, this );
+
     m_btnRefresh->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnRefreshClick ), NULL, this );
     m_sdbSizer1Apply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnApplyAudioParameters ), NULL, this );
     m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnCancelAudioParameters ), NULL, this );
@@ -281,6 +317,9 @@ AudioOptsDialog::~AudioOptsDialog()
     m_listCtrlRxOutDevices->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(AudioOptsDialog::OnRxOutDeviceSelect), NULL, this);
     m_listCtrlTxInDevices->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(AudioOptsDialog::OnTxInDeviceSelect), NULL, this);
     m_listCtrlTxOutDevices->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(AudioOptsDialog::OnTxOutDeviceSelect), NULL, this);
+
+    m_btnRxInTest->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnRxInTest ), NULL, this );
+
     m_btnRefresh->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AudioOptsDialog::OnRefreshClick), NULL, this);
     m_sdbSizer1Apply->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AudioOptsDialog::OnApplyAudioParameters), NULL, this);
     m_sdbSizer1Cancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AudioOptsDialog::OnCancelAudioParameters), NULL, this);
@@ -572,6 +611,11 @@ int AudioOptsDialog:: buildListOfSupportedSampleRates(wxComboBox *cbSampleRate,
     int                  i, numSampleRates;
 
     deviceInfo = Pa_GetDeviceInfo(devNum);
+    if (deviceInfo == NULL) {
+        printf("Pa_GetDeviceInfo(%d) failed!\n", devNum);
+        cbSampleRate->Clear();
+        return 0;
+    }
 
     inputParameters.device = devNum;
     inputParameters.channelCount = deviceInfo->maxInputChannels;
@@ -823,6 +867,100 @@ void AudioOptsDialog::OnTxOutDeviceSelect(wxListEvent& evt)
                    AUDIO_OUT);
 }
 
+// opens a record device and plots the input speech for a few seconds.  This is "modal" using
+// synchronous portaudio functions, so the GUI will not respond until after test sample has been
+// taken
+
+void AudioOptsDialog::plotDeviceInputForAFewSecs(int devNum, PlotScalar *plotScalar) {
+    PaStreamParameters  inputParameters;
+    PaStream           *stream = NULL;
+    PaError             err;
+    short               in48k_stereo_short[2*TEST_BUF_SIZE];
+    short               in48k_short[TEST_BUF_SIZE];
+    short               in8k_short[TEST_BUF_SIZE];
+    int                 numDevices, nBufs, i, j, src_error;
+    float               t;
+    SRC_STATE          *src;
+    FIFO               *fifo;
+
+    // a basic sanity check
+    numDevices = Pa_GetDeviceCount();
+    if (devNum >= numDevices)
+        return;
+    if (devNum < 0)
+        return;
+    printf("devNum %d\n", devNum);
+
+    fifo = fifo_create((int)(DT*TEST_WAVEFORM_PLOT_FS*2)); assert(fifo != NULL);
+    src = src_new(SRC_SINC_FASTEST, 1, &src_error); assert(src != NULL);
+
+    inputParameters.device = devNum;
+    inputParameters.channelCount = 2;
+    inputParameters.sampleFormat = paInt16;
+    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultHighInputLatency;
+    inputParameters.hostApiSpecificStreamInfo = NULL;
+
+    nBufs = TEST_WAVEFORM_PLOT_TIME*TEST_FS/TEST_BUF_SIZE;
+    printf("nBufs %d\n", nBufs);
+
+    err = Pa_OpenStream(
+              &stream,
+              &inputParameters,
+              NULL,
+              TEST_FS,
+              TEST_BUF_SIZE,
+              paClipOff,    
+              NULL,       // no callback, use blocking API
+              NULL ); 
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't initialise sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+
+    err = Pa_StartStream(stream);
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't start sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+
+    for(i=0, t=0.0; i<nBufs; i++, t+=(float)TEST_BUF_SIZE/TEST_FS) {
+        Pa_ReadStream(stream, in48k_stereo_short, TEST_BUF_SIZE);
+        for(j=0; j<TEST_BUF_SIZE; j++)
+            in48k_short[j] = in48k_stereo_short[2*j]; // left channel only
+        int n8k = resample(src, in8k_short, in48k_short, 8000, TEST_FS, TEST_BUF_SIZE, TEST_BUF_SIZE);
+        resample_for_plot(fifo, in8k_short, n8k);
+
+        // every TEST_DT seconds update plot
+
+        if (t > TEST_DT) {
+            t -= TEST_DT;
+            short plotSamples[TEST_WAVEFORM_PLOT_BUF];
+            if (fifo_read(fifo, plotSamples, TEST_WAVEFORM_PLOT_BUF))
+                memset(plotSamples, 0, TEST_WAVEFORM_PLOT_BUF*sizeof(short));
+            plotScalar->add_new_short_samples(plotSamples, TEST_WAVEFORM_PLOT_BUF, 32767);
+            plotScalar->Refresh();
+       }
+    }
+   
+    err = Pa_StopStream(stream);
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't stop sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+    Pa_CloseStream(stream);
+
+    fifo_destroy(fifo);
+    src_delete(src);
+}
+
+//-------------------------------------------------------------------------
+// OnRxInTest()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnRxInTest(wxCommandEvent& event)
+{
+    plotDeviceInputForAFewSecs(rxInAudioDeviceNum, m_plotScalarRxIn);
+}
+
 //-------------------------------------------------------------------------
 // OnRefreshClick()
 //-------------------------------------------------------------------------
index 8cd54969a631ddc50a026291516a5967fdc9bde1..2f274af63ff2c41fa83a54ef92b4b34b134cf3c7 100644 (file)
@@ -25,6 +25,7 @@
 #include "pa_asio.h"
 #endif
 #endif
+#include "fifo.h"
 
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
 // AudioInfoDisplay
@@ -54,6 +55,9 @@ class AudioOptsDialog : public wxDialog
         int             txInAudioDeviceNum;
         int             txOutAudioDeviceNum;
 
+        void buildTestControls(PlotScalar **plotScalar, wxButton **btnTest, wxPanel *parentPanel, wxBoxSizer *bSizer);
+        void plotDeviceInputForAFewSecs(int devNum, PlotScalar *plotScalar);
+
         int buildListOfSupportedSampleRates(wxComboBox *cbSampleRate, int devNum, int in_out);
         void populateParams(AudioInfoDisplay);
         void showAPIInfo();
@@ -72,12 +76,18 @@ class AudioOptsDialog : public wxDialog
         AudioInfoDisplay m_TxOutDevices;
         wxPanel* m_panel1;
         wxNotebook* m_notebook1;
+
         wxPanel* m_panelRx;
         wxListCtrl* m_listCtrlRxInDevices;
         wxStaticText* m_staticText51;
         wxTextCtrl* m_textCtrlRxIn;
         wxStaticText* m_staticText6;
         wxComboBox* m_cbSampleRateRxIn;
+
+        wxButton* m_btnRxInTest;
+        wxPanel* m_panelRxInTest;
+        PlotScalar* m_plotScalarRxIn;
+
         wxListCtrl* m_listCtrlRxOutDevices;
         wxStaticText* m_staticText9;
         wxTextCtrl* m_textCtrlRxOut;
@@ -113,6 +123,7 @@ class AudioOptsDialog : public wxDialog
         //virtual void OnActivateApp( wxActivateEvent& event ) { event.Skip(); }
 //        virtual void OnCloseFrame( wxCloseEvent& event ) { event.Skip(); }
         void OnRxInDeviceSelect( wxListEvent& event );
+        void OnRxInTest( wxCommandEvent& event );
         void OnRxOutDeviceSelect( wxListEvent& event );
         void OnTxInDeviceSelect( wxListEvent& event );
         void OnTxOutDeviceSelect( wxListEvent& event );
index ce46ce4c5600fe9aa098eab486b9ce182ece1d31..1010f80b568c5d247f5f0cdbea2ace8644838ffa 100644 (file)
@@ -199,7 +199,7 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent)
     {
         // Add Demod Input window
 
-       m_panelDemodIn = new PlotScalar((wxFrame*) m_auiNbookCtrl, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f");
+        m_panelDemodIn = new PlotScalar((wxFrame*) m_auiNbookCtrl, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f", 0);
        m_auiNbookCtrl->AddPage(m_panelDemodIn, _("Demod In"), true, wxNullBitmap);
        g_plotDemodInFifo = fifo_create(2*WAVEFORM_PLOT_BUF);
     }
@@ -208,7 +208,7 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent)
     {
         // Add Speech Input window
 
-       m_panelSpeechIn = new PlotScalar((wxFrame*) m_auiNbookCtrl, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f");
+        m_panelSpeechIn = new PlotScalar((wxFrame*) m_auiNbookCtrl, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f", 0);
        m_auiNbookCtrl->AddPage(m_panelSpeechIn, _("Speech In"), true, wxNullBitmap);
        g_plotSpeechInFifo = fifo_create(2*WAVEFORM_PLOT_BUF);
     }
@@ -217,7 +217,7 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent)
     {
         // Add Speech Output window
 
-       m_panelSpeechOut = new PlotScalar((wxFrame*) m_auiNbookCtrl, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f");
+        m_panelSpeechOut = new PlotScalar((wxFrame*) m_auiNbookCtrl, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f", 0);
        m_auiNbookCtrl->AddPage(m_panelSpeechOut, _("Speech Out"), true, wxNullBitmap);
        g_plotSpeechOutFifo = fifo_create(2*WAVEFORM_PLOT_BUF);
     }
@@ -225,13 +225,13 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent)
     if(wxGetApp().m_show_timing)
     {
         // Add Timing Offset window
-        m_panelTimeOffset = new PlotScalar((wxFrame*) m_auiNbookCtrl, 5.0, DT, -0.5, 0.5, 1, 0.1, "%2.1f");
+        m_panelTimeOffset = new PlotScalar((wxFrame*) m_auiNbookCtrl, 5.0, DT, -0.5, 0.5, 1, 0.1, "%2.1f", 0);
         m_auiNbookCtrl->AddPage(m_panelTimeOffset, L"Timing \u0394", true, wxNullBitmap);
     }
     if(wxGetApp().m_show_freq)
     {
         // Add Frequency Offset window
-        m_panelFreqOffset = new PlotScalar((wxFrame*) m_auiNbookCtrl, 5.0, DT, -200, 200, 1, 50, "%3.0fHz");
+        m_panelFreqOffset = new PlotScalar((wxFrame*) m_auiNbookCtrl, 5.0, DT, -200, 200, 1, 50, "%3.0fHz", 0);
         m_auiNbookCtrl->AddPage(m_panelFreqOffset, L"Frequency \u0394", true, wxNullBitmap);
     }
 
@@ -1394,7 +1394,7 @@ void MainFrame::averageData(float mag_dB[])
 
 // returns number of output samples generated by resampling
 
-static int resample(SRC_STATE *src,
+int resample(SRC_STATE *src,
             short      output_short[],
             short      input_short[],
             int        output_sample_rate,
@@ -1434,7 +1434,7 @@ static int resample(SRC_STATE *src,
 // 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)
+void resample_for_plot(struct FIFO *plotFifo, short buf[], int length)
 {
     int decimation = FS/WAVEFORM_PLOT_FS;
     int nSamples, sample;
@@ -1446,15 +1446,15 @@ static void resample_for_plot(struct FIFO *plotFifo, short buf[], int length)
     nSamples = length/decimation;
 
     for(sample=0; sample<nSamples; sample+=2) {
-    st = decimation*sample;
-    en = decimation*(sample+2);
-    max = min = 0;
-    for(i=st; i<en; i++ ) {
-        if (max < buf[i]) max = buf[i];
-        if (min > buf[i]) min = buf[i];
-    }
-    dec_samples[sample] = max;
-    dec_samples[sample+1] = min;
+        st = decimation*sample;
+        en = decimation*(sample+2);
+        max = min = 0;
+        for(i=st; i<en; i++ ) {
+            if (max < buf[i]) max = buf[i];
+            if (min > buf[i]) min = buf[i];
+        }
+        dec_samples[sample] = max;
+        dec_samples[sample+1] = min;
     }
 
     fifo_write(plotFifo, dec_samples, nSamples);
index 64edc46cb04896c028d70827e4f3ba0ef2cc5a70..025a2b645b3ef574c1adbf6576aa70b6633ea7e3 100644 (file)
@@ -36,7 +36,6 @@
 
 #include "topFrame.h"
 #include "dlg_about.h"
-#include "dlg_audiooptions.h"
 #include "dlg_options.h"
 #include "dlg_comports.h"
 #include "fdmdv2_plot.h"
@@ -47,6 +46,7 @@
 #include "fdmdv2_pa_wrapper.h"
 #include "sndfile.h"
 #include "portaudio.h"
+#include "dlg_audiooptions.h"
 
 #define _USE_TIMER              1
 //#define _USE_ONIDLE             1
@@ -327,4 +327,14 @@ class MainFrame : public TopFrame
         int         m_zoom;
 };
 
+void resample_for_plot(struct FIFO *plotFifo, short buf[], int length);
+int resample(SRC_STATE *src,
+             short      output_short[],
+             short      input_short[],
+             int        output_sample_rate,
+             int        input_sample_rate,
+             int        length_output_short, // maximum output array length in samples
+             int        length_input_short
+             );
+
 #endif //__FDMDV2_MAIN__
index 49d57e6db01375275e6581d30d689efa425c0425..a79215ae89a4be4e925ebfab69820d85a7a215f6 100644 (file)
@@ -43,16 +43,19 @@ END_EVENT_TABLE()
 //----------------------------------------------------------------
 PlotScalar::PlotScalar(wxFrame* parent, 
                       float  t_secs,             // time covered by entire x axis in seconds
-                      float  sample_period_secs, // tiem between each sample in seconds
+                      float  sample_period_secs, // time between each sample in seconds
                       float  a_min,              // min ampltude of samples being plotted
                       float  a_max,              // max ampltude of samples being plotted
                       float  graticule_t_step,   // time step of x (time) axis graticule in seconds
                       float  graticule_a_step,   // step of amplitude axis graticule
-                      const char a_fmt[]         // printf format string for amlitude axis labels
+                      const char a_fmt[],        // printf format string for amlitude axis labels
+                       int    mini                // true for mini-plot - don't draw graticule
                       ): PlotPanel(parent)
 {
     int i;
 
+    m_rCtrl = GetClientRect();
+
     m_t_secs = t_secs;
     m_sample_period_secs = sample_period_secs;
     m_a_min = a_min;
@@ -61,6 +64,7 @@ PlotScalar::PlotScalar(wxFrame* parent,
     m_graticule_a_step = graticule_a_step;
     assert(strlen(a_fmt) < 15);
     strcpy(m_a_fmt, a_fmt);
+    m_mini = mini;
 
     // work out number of samples we will store and allocate storage
 
@@ -122,12 +126,20 @@ void PlotScalar::draw(wxAutoBufferedPaintDC&  dc)
 
     m_rCtrl = GetClientRect();
     m_rGrid = m_rCtrl;
-    m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+    if (!m_mini)
+        m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+
+    //printf("h %d w %d\n", m_rCtrl.GetWidth(), m_rCtrl.GetHeight());
+    //printf("h %d w %d\n", m_rGrid.GetWidth(), m_rGrid.GetHeight());
 
     // black background
 
     dc.Clear();
-    m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
+    if (m_mini)
+        m_rPlot = wxRect(0, 0, m_rGrid.GetWidth(), m_rGrid.GetHeight());        
+    else
+        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));
@@ -158,8 +170,10 @@ void PlotScalar::draw(wxAutoBufferedPaintDC&  dc)
 
        // put inside plot window
 
-       x += PLOT_BORDER + XLEFT_OFFSET;
-       y += PLOT_BORDER;
+       if (!m_mini) {
+            x += PLOT_BORDER + XLEFT_OFFSET;
+            y += PLOT_BORDER;
+        }
 
        if (i)
            dc.DrawLine(x, y, prev_x, prev_y);
@@ -199,11 +213,18 @@ void PlotScalar::drawGraticule(wxAutoBufferedPaintDC&  dc)
     dc.SetPen(m_penShortDash);
     for(t=0; t<=m_t_secs; t+=m_graticule_t_step) {
        x = t*sec_to_px;
-       x += PLOT_BORDER + XLEFT_OFFSET;
-        dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER);
-        sprintf(buf, "%2.1fs", t);
-       GetTextExtent(buf, &text_w, &text_h);
-        dc.DrawText(buf, x - text_w/2, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+       if (m_mini) {
+            dc.DrawLine(x, m_rGrid.GetHeight(), x, 0);
+        }
+        else {
+            x += PLOT_BORDER + XLEFT_OFFSET;
+            dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER);
+        }
+        if (!m_mini) {
+            sprintf(buf, "%2.1fs", t);
+            GetTextExtent(buf, &text_w, &text_h);
+            dc.DrawText(buf, x - text_w/2, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+        }
     }
 
     // Horizontal gridlines
@@ -211,12 +232,19 @@ void PlotScalar::drawGraticule(wxAutoBufferedPaintDC&  dc)
     dc.SetPen(m_penDotDash);
     for(a=m_a_min; a<m_a_max; a+=m_graticule_a_step) {
        y = m_rGrid.GetHeight() - a*a_to_py + m_a_min*a_to_py;
-       y += PLOT_BORDER;
-       dc.DrawLine(PLOT_BORDER + XLEFT_OFFSET, y, 
-                   (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), y);
-        sprintf(buf, m_a_fmt, a);
-       GetTextExtent(buf, &text_w, &text_h);
-        dc.DrawText(buf, PLOT_BORDER + XLEFT_OFFSET - text_w - XLEFT_TEXT_OFFSET, y-text_h/2);
+       if (m_mini) {
+            dc.DrawLine(0, y, m_rGrid.GetWidth(), y);
+        }
+        else {
+            y += PLOT_BORDER;
+            dc.DrawLine(PLOT_BORDER + XLEFT_OFFSET, y, 
+                        (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), y);
+        }
+        if (!m_mini) {
+            sprintf(buf, m_a_fmt, a);
+            GetTextExtent(buf, &text_w, &text_h);
+            dc.DrawText(buf, PLOT_BORDER + XLEFT_OFFSET - text_w - XLEFT_TEXT_OFFSET, y-text_h/2);
+        }
    }
 
 
index e6b64e6e1b7403f00e44618a9e2d1584b4446b18..c49c956e37e73417d291a07dad7c70a8ab9e7e26 100644 (file)
@@ -42,7 +42,8 @@ class PlotScalar: public PlotPanel
               float a_max,
               float graticule_t_step,   
               float graticule_a_step,
-              const char  a_fmt[]
+              const char  a_fmt[],
+               int   mini
               );
         ~PlotScalar();
          void add_new_sample(float sample);
@@ -57,6 +58,7 @@ class PlotScalar: public PlotPanel
         float    m_graticule_t_step;   
         float    m_graticule_a_step;
         char     m_a_fmt[15];
+         int      m_mini;
         int      m_samples;
         float   *m_mem;