From 4bb9a933059bcd4a46fa8a112f4de711d2a74de1 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Tue, 13 Nov 2012 08:18:53 +0000 Subject: [PATCH] first pass at a test tool for audio config dialog that plots input to a little screen. Just rx in at this stage. Some indication that it is occasionally unstable. Might need to convert to async/callback model git-svn-id: https://svn.code.sf.net/p/freetel/code@967 01035d8c-6547-0410-b346-abe4f91aad63 --- fdmdv2/src/Makefile.linux | 2 +- fdmdv2/src/Makefile.win32 | 2 +- fdmdv2/src/dlg_audiooptions.cpp | 140 +++++++++++++++++++++++++++++- fdmdv2/src/dlg_audiooptions.h | 11 +++ fdmdv2/src/fdmdv2_main.cpp | 32 +++---- fdmdv2/src/fdmdv2_main.h | 12 ++- fdmdv2/src/fdmdv2_plot_scalar.cpp | 62 +++++++++---- fdmdv2/src/fdmdv2_plot_scalar.h | 4 +- 8 files changed, 227 insertions(+), 38 deletions(-) diff --git a/fdmdv2/src/Makefile.linux b/fdmdv2/src/Makefile.linux index c3315f37..0bd97661 100644 --- a/fdmdv2/src/Makefile.linux +++ b/fdmdv2/src/Makefile.linux @@ -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 diff --git a/fdmdv2/src/Makefile.win32 b/fdmdv2/src/Makefile.win32 index 33fe92cd..d7475f8c 100644 --- a/fdmdv2/src/Makefile.win32 +++ b/fdmdv2/src/Makefile.win32 @@ -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 diff --git a/fdmdv2/src/dlg_audiooptions.cpp b/fdmdv2/src/dlg_audiooptions.cpp index cd3d4add..1d62c0ba 100644 --- a/fdmdv2/src/dlg_audiooptions.cpp +++ b/fdmdv2/src/dlg_audiooptions.cpp @@ -13,6 +13,17 @@ #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 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() //------------------------------------------------------------------------- diff --git a/fdmdv2/src/dlg_audiooptions.h b/fdmdv2/src/dlg_audiooptions.h index 8cd54969..2f274af6 100644 --- a/fdmdv2/src/dlg_audiooptions.h +++ b/fdmdv2/src/dlg_audiooptions.h @@ -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 ); diff --git a/fdmdv2/src/fdmdv2_main.cpp b/fdmdv2/src/fdmdv2_main.cpp index ce46ce4c..1010f80b 100644 --- a/fdmdv2/src/fdmdv2_main.cpp +++ b/fdmdv2/src/fdmdv2_main.cpp @@ -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 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 buf[i]) min = buf[i]; + } + dec_samples[sample] = max; + dec_samples[sample+1] = min; } fifo_write(plotFifo, dec_samples, nSamples); diff --git a/fdmdv2/src/fdmdv2_main.h b/fdmdv2/src/fdmdv2_main.h index 64edc46c..025a2b64 100644 --- a/fdmdv2/src/fdmdv2_main.h +++ b/fdmdv2/src/fdmdv2_main.h @@ -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__ diff --git a/fdmdv2/src/fdmdv2_plot_scalar.cpp b/fdmdv2/src/fdmdv2_plot_scalar.cpp index 49d57e6d..a79215ae 100644 --- a/fdmdv2/src/fdmdv2_plot_scalar.cpp +++ b/fdmdv2/src/fdmdv2_plot_scalar.cpp @@ -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