implemented level guage on tx & rx inclduing too high warning
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 26 Nov 2012 22:48:17 +0000 (22:48 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 26 Nov 2012 22:48:17 +0000 (22:48 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1078 01035d8c-6547-0410-b346-abe4f91aad63

fdmdv2/src/fdmdv2_defines.h
fdmdv2/src/fdmdv2_main.cpp
fdmdv2/src/fdmdv2_main.h
fdmdv2/src/topFrame.cpp
fdmdv2/src/topFrame.h

index 889201cbb5decae9550f51510168cffad5d3578f..9116d7f211183958b0ceb643cb0409b20139d50d 100644 (file)
 // 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
index 824203971c0158c5f1135e6666b36b4f2245c132..fcbd8593dfd5473b7e72186cefaa3e63007584ec 100644 (file)
@@ -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<WAVEFORM_PLOT_BUF; i++)
+            if (maxDemodIn < abs(demodInPlotSamples[i]))
+                maxDemodIn = abs(demodInPlotSamples[i]);
+
+        // peak from last second
+        if (maxDemodIn > 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<WAVEFORM_PLOT_BUF; i++)
+            if (maxSpeechIn < abs(speechInPlotSamples[i]))
+                maxSpeechIn = abs(speechInPlotSamples[i]);
+
+        // peak from last second
+        if (maxSpeechIn > 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; i<nout; i++)
     //    printf("%d", varicode[i]);
     //printf("\n");
-    int ret = fifo_write(g_txDataInFifo, varicode, nout);
+    fifo_write(g_txDataInFifo, varicode, nout);
     //printf("MainFrame::OnTogBtnTxID, sending: %s nout: %d ret: %d\n", txid2, nout, ret);
 }
 
@@ -1025,9 +1075,9 @@ void MainFrame::OnRecFileFromRadio(wxCommandEvent& event)
         long secs;
         if (secsString.ToLong(&secs)) {
             wxGetApp().m_recFileFromRadioSecs = (unsigned int)secs;
-            printf(" secondsToRecord: %d\n",  (unsigned int)secs);
+            //printf(" secondsToRecord: %d\n",  (unsigned int)secs);
             g_recFromRadioSamples = FS*(unsigned int)secs;
-            printf("g_recFromRadioSamples: %d\n", g_recFromRadioSamples);
+            //printf("g_recFromRadioSamples: %d\n", g_recFromRadioSamples);
         }
         else {
             wxMessageBox(wxT("Invalid number of Seconds"), wxT("Record File From Radio"), wxOK);
@@ -1256,6 +1306,10 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
         m_txIDTimerTics = 0.0;
         m_txtCtrlRx->SetValue(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
 
index c9e4099d7e2193435d2600d688cca0abac9e21f4..53a45e0550e67145fb6797e84e2a19a7fab88fa0 100644 (file)
@@ -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);
index 10bbcf4890befaeeeb56aadb2750a50f42193a12..ec5fa1916e955d84366f4ceff65d7c50fea0c96a 100644 (file)
@@ -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;
index 4c48c1b73833ce019b82c148c22b58f532ce4b08..c2abea714ee52ac77c74a4ef763f81e06100a98a 100644 (file)
@@ -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;