From e8b40589d2f4467da3e85dc82577f76669b6d3f5 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Mon, 26 Nov 2012 22:48:17 +0000 Subject: [PATCH] implemented level guage on tx & rx inclduing too high warning git-svn-id: https://svn.code.sf.net/p/freetel/code@1078 01035d8c-6547-0410-b346-abe4f91aad63 --- fdmdv2/src/fdmdv2_defines.h | 6 +++ fdmdv2/src/fdmdv2_main.cpp | 79 +++++++++++++++++++++++++++++++------ fdmdv2/src/fdmdv2_main.h | 3 ++ fdmdv2/src/topFrame.cpp | 10 ++++- fdmdv2/src/topFrame.h | 1 + 5 files changed, 85 insertions(+), 14 deletions(-) diff --git a/fdmdv2/src/fdmdv2_defines.h b/fdmdv2/src/fdmdv2_defines.h index 889201cb..9116d7f2 100644 --- a/fdmdv2/src/fdmdv2_defines.h +++ b/fdmdv2/src/fdmdv2_defines.h @@ -67,6 +67,12 @@ // Squelch #define SQ_DEFAULT_SNR 4.0 +// Level Gauge +#define FROM_RADIO_MAX 0.8 +#define FROM_MIC_MAX 0.8 +#define LEVEL_BETA 0.99 + +// SNR #define SNRSLOW_BETA 0.5 // time constant for slow SNR for display // Data diff --git a/fdmdv2/src/fdmdv2_main.cpp b/fdmdv2/src/fdmdv2_main.cpp index 82420397..fcbd8593 100644 --- a/fdmdv2/src/fdmdv2_main.cpp +++ b/fdmdv2/src/fdmdv2_main.cpp @@ -548,7 +548,7 @@ void MainFrame::OnTimer(wxTimerEvent &evt) m_panelFreqOffset->add_new_sample(g_stats.foff); m_panelFreqOffset->Refresh(); - // SNR text box and guage ------------------------------------------------------------ + // SNR text box and gauge ------------------------------------------------------------ // LP filter g_stats.snr_est some more to stabilise the // display. g_stats.snr_est already has some low pass filtering @@ -573,6 +573,51 @@ void MainFrame::OnTimer(wxTimerEvent &evt) if (snr_limited > 20.0) snr_limited = 20.0; m_gaugeSNR->SetValue((int)(snr_limited)); + // Level Guage ----------------------------------------------------------------------- + + float tooHighThresh; + if (!g_tx && m_RxRunning) { + // receive mode - display From Radio peaks + + // peak from this DT sampling period + int maxDemodIn = 0; + for(int i=0; i m_maxLevel) + m_maxLevel = maxDemodIn; + + tooHighThresh = FROM_RADIO_MAX; + } + else { + // transmit mode - display From Mic peaks + + // peak from this DT sampling period + int maxSpeechIn = 0; + for(int i=0; i m_maxLevel) + m_maxLevel = maxSpeechIn; + + tooHighThresh = FROM_MIC_MAX; + } + + // Peak Readng meter: updates peaks immediately, then slowly decays + + int maxScaled = (int)(100.0 * ((float)m_maxLevel/32767.0)); + m_gaugeLevel->SetValue(maxScaled); + if (((float)maxScaled/100) > tooHighThresh) + m_textLevel->SetLabel("Too High"); + else + m_textLevel->SetLabel(""); + + m_maxLevel *= LEVEL_BETA; + // sync LED (Colours don't work on Windows) if (g_State) { @@ -756,9 +801,14 @@ void MainFrame::OnTogBtnTXClick(wxCommandEvent& event) else { // rx-> tx transition, swap to Mic In page to monitor speech m_auiNbookCtrl->ChangeSelection(4); // is there a way to avoid hard coding this? - } + } g_tx = m_btnTogTX->GetValue(); + // reset level gauge + m_maxLevel = 0; + m_textLevel->SetLabel(wxT("")); + m_gaugeLevel->SetValue(0); + event.Skip(); } @@ -787,7 +837,7 @@ void MainFrame::sendTxID(void) //for(int i=0; iSetValue(wxT("")); + m_maxLevel = 0; + m_textLevel->SetLabel(wxT("")); + m_gaugeLevel->SetValue(0); + //printf("g_stats.snr: %f\n", g_stats.snr_est); // attempt to start sound cards and tx/rx processing @@ -1376,12 +1430,10 @@ void MainFrame::initPortAudioDevice(PortAudioWrap *pa, int inDevice, int outDev // portaudio struct so can't return any errors. So no need to trap // any errors in this function. - printf("indDevice: %d outDevice: %d\n", inDevice, outDevice); // init input params pa->setInputDevice(inDevice); pa->setInputChannelCount(inputChannels); // stereo input - printf("maxInputChannels: %d\n", inputChannels); pa->setInputSampleFormat(PA_SAMPLE_TYPE); pa->setInputLatency(pa->getInputDefaultLowLatency()); pa->setInputHostApiStreamInfo(NULL); @@ -1404,7 +1456,6 @@ void MainFrame::initPortAudioDevice(PortAudioWrap *pa, int inDevice, int outDev */ pa->setFramesPerBuffer(wxGetApp().m_framesPerBuffer); - printf("framesPerBuffer: %d\n", wxGetApp().m_framesPerBuffer); pa->setSampleRate(sampleRate); pa->setStreamFlags(paClipOff); } @@ -1873,8 +1924,8 @@ int MainFrame::rxCallback( wxMutexLocker lock(g_mutexProtectingCallbackData); - if (statusFlags) - printf("cb1 statusFlags: 0x%x\n", (int)statusFlags); + //if (statusFlags) + // printf("cb1 statusFlags: 0x%x\n", (int)statusFlags); // // RX side processing -------------------------------------------- @@ -2150,7 +2201,9 @@ void per_frame_tx_processing( data_flag_index = codec2_get_spare_bit_index(c2); assert(data_flag_index != -1); // not supported for all rates - // if there is low speech energy and data to send, then send data frame + // potential bug: this should really track background noise level + // e.g. look at minimum frame energy. OW a high backfround level might + // mean no data.... if ((peak < SILENCE_THRESHOLD) && fifo_used(g_txDataInFifo)) { //printf("sending data ...\n"); @@ -2237,8 +2290,8 @@ int MainFrame::txCallback( wxMutexLocker lock(g_mutexProtectingCallbackData); - if (statusFlags) - printf("cb2 statusFlags: 0x%x\n", (int)statusFlags); + // if (statusFlags) + // printf("cb2 statusFlags: 0x%x\n", (int)statusFlags); // assemble a mono buffer (just use left channel) and write to FIFO diff --git a/fdmdv2/src/fdmdv2_main.h b/fdmdv2/src/fdmdv2_main.h index c9e4099d..53a45e05 100644 --- a/fdmdv2/src/fdmdv2_main.h +++ b/fdmdv2/src/fdmdv2_main.h @@ -348,6 +348,9 @@ class MainFrame : public TopFrame int m_zoom; float m_snrBeta; float m_txIDTimerTics; + + // level Gauge + float m_maxLevel; }; void resample_for_plot(struct FIFO *plotFifo, short buf[], int length); diff --git a/fdmdv2/src/topFrame.cpp b/fdmdv2/src/topFrame.cpp index 10bbcf48..ec5fa191 100644 --- a/fdmdv2/src/topFrame.cpp +++ b/fdmdv2/src/topFrame.cpp @@ -127,9 +127,15 @@ TopFrame::TopFrame(wxWindow* parent, wxWindowID id, const wxString& title, const //------------------------------ wxStaticBoxSizer* levelSizer; levelSizer = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Level")), wxVERTICAL); + + m_textLevel = new wxStaticText(this, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(50,-1), wxALIGN_CENTRE); + m_textLevel->SetForegroundColour(wxColour(255,0,0)); + levelSizer->Add(m_textLevel, 0, wxALIGN_LEFT, 1); + m_gaugeLevel = new wxGauge(this, wxID_ANY, 100, wxDefaultPosition, wxSize(15,135), wxGA_SMOOTH|wxGA_VERTICAL); - m_gaugeLevel->SetToolTip(_("Display signal level.")); + m_gaugeLevel->SetToolTip(_("Peak of From Radio in Rx, or peak of From Mic in Tx mode. If Red you should reduce your levels")); levelSizer->Add(m_gaugeLevel, 1, wxALIGN_CENTER_HORIZONTAL|wxALL, 10); + leftSizer->Add(levelSizer, 2, wxALIGN_CENTER|wxALL|wxEXPAND, 1); bSizer1->Add(leftSizer, 0, wxALL|wxEXPAND, 5); @@ -188,9 +194,11 @@ TopFrame::TopFrame(wxWindow* parent, wxWindowID id, const wxString& title, const bSizer15 = new wxBoxSizer(wxVERTICAL); m_txtCtrlTx = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_txtCtrlTx->SetToolTip(_("Text in this box wll be sent when TxID button is pressed")); bSizer15->Add(m_txtCtrlTx, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5); m_txtCtrlRx = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY|wxTE_MULTILINE); bSizer15->Add(m_txtCtrlRx, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5); + m_txtCtrlRx->SetToolTip(_("Text will be received here when RxID button is pressed")); lowerSizer->Add(bSizer15, 1, wxEXPAND, 5); wxBoxSizer* bSizer141; diff --git a/fdmdv2/src/topFrame.h b/fdmdv2/src/topFrame.h index 4c48c1b7..c2abea71 100644 --- a/fdmdv2/src/topFrame.h +++ b/fdmdv2/src/topFrame.h @@ -89,6 +89,7 @@ class TopFrame : public wxFrame wxStaticText* m_textSNR; wxCheckBox* m_ckboxSNR; wxGauge* m_gaugeLevel; + wxStaticText* m_textLevel; wxTextCtrl* m_txtCtrlTx; wxTextCtrl* m_txtCtrlRx; wxSlider* m_sliderSQ; -- 2.25.1