From 15f7c4d80e7f6c95875d2aef42f2dea9654121c1 Mon Sep 17 00:00:00 2001
From: f4exb <f4exb06@gmail.com>
Date: Thu, 19 Apr 2018 23:03:21 +0200
Subject: [PATCH] UDP source and sink: added dialogs to specify addresses and
 ports

---
 debian/changelog                              |   7 +-
 plugins/channelrx/udpsrc/udpsrcgui.cpp        |  50 ++++++
 plugins/channelrx/udpsrc/udpsrcgui.h          |   3 +
 plugins/channelrx/udpsrc/udpsrcgui.ui         | 147 ++++++++++++++----
 plugins/channelrx/udpsrc/udpsrcsettings.cpp   |  25 ++-
 plugins/channeltx/udpsink/udpsinkgui.cpp      |  27 +++-
 plugins/channeltx/udpsink/udpsinkgui.h        |   2 +
 plugins/channeltx/udpsink/udpsinkgui.ui       |  69 +++++++-
 plugins/channeltx/udpsink/udpsinksettings.cpp |   4 +-
 sdrgui/gui/audiodialog.ui                     |   4 +-
 10 files changed, 292 insertions(+), 46 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 483635497..d9df8abf2 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,9 +1,12 @@
 sdrangel (3.14.3-1) unstable; urgency=medium
 
   * LimeSDR: compiled with LimeSuite commit 67dcef1
-  * LimeSDR: implemented transverter dialog
+  * LimeSDR: implemented transverter dialog (issue #157)
+  * UDP source and sink: make sure audio samples are always on 16 bits
+  * UDP source and sink: dialog elements for address and port
+  * Reviewed FFT destruction in many channel sources and sinks (issue #159) 
 
- -- Edouard Griffiths, F4EXB <f4exb06@gmail.com>  Sat, 21 Apr 2018 18:14:18 +0200
+ -- Edouard Griffiths, F4EXB <f4exb06@gmail.com>  Fri, 20 Apr 2018 20:14:18 +0200
 
 sdrangel (3.14.2-1) unstable; urgency=medium
 
diff --git a/plugins/channelrx/udpsrc/udpsrcgui.cpp b/plugins/channelrx/udpsrc/udpsrcgui.cpp
index 045b13029..b19b4bb83 100644
--- a/plugins/channelrx/udpsrc/udpsrcgui.cpp
+++ b/plugins/channelrx/udpsrc/udpsrcgui.cpp
@@ -219,11 +219,17 @@ void UDPSrcGUI::displaySettings()
     setTitleColor(m_settings.m_rgbColor);
     setWindowTitle(m_channelMarker.getTitle());
 
+    blockApplySettings(true);
+
     ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
 
     ui->sampleRate->setText(QString("%1").arg(m_settings.m_outputSampleRate, 0));
     setSampleFormatIndex(m_settings.m_sampleFormat);
 
+    ui->outputUDPAddress->setText(m_settings.m_udpAddress);
+    ui->outputUDPPort->setText(tr("%1").arg(m_settings.m_udpPort));
+    ui->inputUDPAudioPort->setText(tr("%1").arg(m_settings.m_audioPort));
+
     ui->squelch->setValue(m_settings.m_squelchdB);
     ui->squelchText->setText(tr("%1").arg(ui->squelch->value()*1.0, 0, 'f', 0));
 
@@ -244,6 +250,11 @@ void UDPSrcGUI::displaySettings()
     ui->gain->setValue(m_settings.m_gain*10.0);
     ui->gainText->setText(tr("%1").arg(ui->gain->value()/10.0, 0, 'f', 1));
 
+    ui->applyBtn->setEnabled(false);
+    ui->applyBtn->setStyleSheet("QPushButton { background:rgb(79,79,79); }");
+
+    blockApplySettings(false);
+
     ui->glSpectrum->setSampleRate(m_settings.m_outputSampleRate);
 }
 
@@ -391,6 +402,45 @@ void UDPSrcGUI::on_sampleFormat_currentIndexChanged(int index)
 	ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }");
 }
 
+void UDPSrcGUI::on_outputUDPAddress_editingFinished()
+{
+    m_settings.m_udpAddress = ui->outputUDPAddress->text();
+    ui->applyBtn->setEnabled(true);
+    ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }");
+}
+
+void UDPSrcGUI::on_outputUDPPort_editingFinished()
+{
+    bool ok;
+    quint16 udpPort = ui->outputUDPPort->text().toInt(&ok);
+
+    if((!ok) || (udpPort < 1024)) {
+        udpPort = 9998;
+    }
+
+    m_settings.m_udpPort = udpPort;
+    ui->outputUDPPort->setText(tr("%1").arg(m_settings.m_udpPort));
+
+    ui->applyBtn->setEnabled(true);
+    ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }");
+}
+
+void UDPSrcGUI::on_inputUDPAudioPort_editingFinished()
+{
+    bool ok;
+    quint16 udpPort = ui->inputUDPAudioPort->text().toInt(&ok);
+
+    if((!ok) || (udpPort < 1024)) {
+        udpPort = 9997;
+    }
+
+    m_settings.m_audioPort = udpPort;
+    ui->inputUDPAudioPort->setText(tr("%1").arg(m_settings.m_audioPort));
+
+    ui->applyBtn->setEnabled(true);
+    ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }");
+}
+
 void UDPSrcGUI::on_sampleRate_textEdited(const QString& arg1 __attribute__((unused)))
 {
     bool ok;
diff --git a/plugins/channelrx/udpsrc/udpsrcgui.h b/plugins/channelrx/udpsrc/udpsrcgui.h
index e6fef1ad2..12035dbb9 100644
--- a/plugins/channelrx/udpsrc/udpsrcgui.h
+++ b/plugins/channelrx/udpsrc/udpsrcgui.h
@@ -94,6 +94,9 @@ private:
 private slots:
 	void on_deltaFrequency_changed(qint64 value);
 	void on_sampleFormat_currentIndexChanged(int index);
+	void on_outputUDPAddress_editingFinished();
+	void on_outputUDPPort_editingFinished();
+	void on_inputUDPAudioPort_editingFinished();
 	void on_sampleRate_textEdited(const QString& arg1);
 	void on_rfBandwidth_textEdited(const QString& arg1);
 	void on_fmDeviation_textEdited(const QString& arg1);
diff --git a/plugins/channelrx/udpsrc/udpsrcgui.ui b/plugins/channelrx/udpsrc/udpsrcgui.ui
index 19ef8a26c..d920278bd 100644
--- a/plugins/channelrx/udpsrc/udpsrcgui.ui
+++ b/plugins/channelrx/udpsrc/udpsrcgui.ui
@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>354</width>
+    <width>383</width>
     <height>355</height>
    </rect>
   </property>
@@ -39,13 +39,13 @@
     <rect>
      <x>2</x>
      <y>2</y>
-     <width>350</width>
+     <width>380</width>
      <height>142</height>
     </rect>
    </property>
    <property name="minimumSize">
     <size>
-     <width>350</width>
+     <width>380</width>
      <height>0</height>
     </size>
    </property>
@@ -53,16 +53,7 @@
     <string>Settings</string>
    </property>
    <layout class="QGridLayout" name="gridLayout">
-    <property name="leftMargin">
-     <number>2</number>
-    </property>
-    <property name="topMargin">
-     <number>2</number>
-    </property>
-    <property name="rightMargin">
-     <number>2</number>
-    </property>
-    <property name="bottomMargin">
+    <property name="margin">
      <number>2</number>
     </property>
     <property name="spacing">
@@ -331,7 +322,7 @@
     <item row="1" column="0">
      <layout class="QHBoxLayout" name="AddressLayout">
       <item>
-       <widget class="QLabel" name="Addresslabel">
+       <widget class="QLabel" name="outputUDPAddressLabel">
         <property name="maximumSize">
          <size>
           <width>30</width>
@@ -339,23 +330,71 @@
          </size>
         </property>
         <property name="text">
-         <string>Addr</string>
+         <string>Ad</string>
         </property>
        </widget>
       </item>
       <item>
-       <widget class="QLabel" name="addressText">
+       <widget class="QLineEdit" name="outputUDPAddress">
         <property name="minimumSize">
          <size>
-          <width>170</width>
+          <width>120</width>
           <height>0</height>
          </size>
         </property>
-        <property name="statusTip">
-         <string>UDP &lt;address&gt;:&lt;data port&gt;/&lt;audio port&gt;</string>
+        <property name="toolTip">
+         <string>Destinationn UDP address</string>
+        </property>
+        <property name="inputMask">
+         <string>000.000.000.000; </string>
         </property>
         <property name="text">
-         <string>00.000.000.000:0000/0000</string>
+         <string>127.0.0.1</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <spacer name="horizontalSpacer_3">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QLabel" name="outputUDPPortLabel">
+        <property name="text">
+         <string>P</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QLineEdit" name="outputUDPPort">
+        <property name="minimumSize">
+         <size>
+          <width>50</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>50</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>Destination UDP port</string>
+        </property>
+        <property name="inputMask">
+         <string>00000; </string>
+        </property>
+        <property name="text">
+         <string>9998</string>
         </property>
        </widget>
       </item>
@@ -378,6 +417,18 @@
       </item>
       <item>
        <widget class="QComboBox" name="sampleFormat">
+        <property name="minimumSize">
+         <size>
+          <width>120</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>120</width>
+          <height>16777215</height>
+         </size>
+        </property>
         <property name="toolTip">
          <string>Samples format</string>
         </property>
@@ -441,6 +492,51 @@
         </item>
        </widget>
       </item>
+      <item>
+       <spacer name="horizontalSpacer_4">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QLabel" name="inputUDPAudioPortLabel">
+        <property name="text">
+         <string>Au</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QLineEdit" name="inputUDPAudioPort">
+        <property name="minimumSize">
+         <size>
+          <width>50</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>50</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>Audio input UDP port</string>
+        </property>
+        <property name="inputMask">
+         <string>00000; </string>
+        </property>
+        <property name="text">
+         <string>9997</string>
+        </property>
+       </widget>
+      </item>
      </layout>
     </item>
     <item row="6" column="0">
@@ -721,16 +817,7 @@
     <property name="spacing">
      <number>3</number>
     </property>
-    <property name="leftMargin">
-     <number>2</number>
-    </property>
-    <property name="topMargin">
-     <number>2</number>
-    </property>
-    <property name="rightMargin">
-     <number>2</number>
-    </property>
-    <property name="bottomMargin">
+    <property name="margin">
      <number>2</number>
     </property>
     <item>
diff --git a/plugins/channelrx/udpsrc/udpsrcsettings.cpp b/plugins/channelrx/udpsrc/udpsrcsettings.cpp
index 31578c657..6a1bdf856 100644
--- a/plugins/channelrx/udpsrc/udpsrcsettings.cpp
+++ b/plugins/channelrx/udpsrc/udpsrcsettings.cpp
@@ -45,8 +45,8 @@ void UDPSrcSettings::resetToDefaults()
     m_audioStereo = false;
     m_volume = 20;
     m_udpAddress = "127.0.0.1";
-    m_udpPort = 9999;
-    m_audioPort = 9998;
+    m_udpPort = 9998;
+    m_audioPort = 9997;
     m_rgbColor = QColor(225, 25, 99).rgb();
     m_title = "UDP Sample Source";
 }
@@ -77,6 +77,9 @@ QByteArray UDPSrcSettings::serialize() const
     s.writeS32(17, m_squelchGate);
     s.writeBool(18, m_agc);
     s.writeString(19, m_title);
+    s.writeString(20, m_udpAddress);
+    s.writeU32(21, m_udpPort);
+    s.writeU32(22, m_audioPort);
 
     return s.final();
 
@@ -97,6 +100,7 @@ bool UDPSrcSettings::deserialize(const QByteArray& data)
         QByteArray bytetmp;
         QString strtmp;
         int32_t s32tmp;
+        quint32 u32tmp;
 
         if (m_channelMarker) {
             d.readBlob(6, &bytetmp);
@@ -133,6 +137,23 @@ bool UDPSrcSettings::deserialize(const QByteArray& data)
         d.readS32(17, &m_squelchGate, 5);
         d.readBool(18, &m_agc, false);
         d.readString(19, &m_title, "UDP Sample Source");
+        d.readString(20, &m_udpAddress, "127.0.0.1");
+
+        d.readU32(21, &u32tmp, 9998);
+
+        if ((u32tmp > 1024) & (u32tmp < 65538)) {
+            m_udpPort = u32tmp;
+        } else {
+            m_udpPort = 9998;
+        }
+
+        d.readU32(22, &u32tmp, 9997);
+
+        if ((u32tmp > 1024) & (u32tmp < 65538)) {
+            m_audioPort = u32tmp;
+        } else {
+            m_audioPort = 9997;
+        }
 
         return true;
     }
diff --git a/plugins/channeltx/udpsink/udpsinkgui.cpp b/plugins/channeltx/udpsink/udpsinkgui.cpp
index 701fdf9a9..3bfa7e620 100644
--- a/plugins/channeltx/udpsink/udpsinkgui.cpp
+++ b/plugins/channeltx/udpsink/udpsinkgui.cpp
@@ -243,7 +243,8 @@ void UDPSinkGUI::displaySettings()
     ui->squelchGateText->setText(tr("%1").arg(roundf(m_settings.m_squelchGate * 1000.0), 0, 'f', 0));
     ui->squelchGate->setValue(roundf(m_settings.m_squelchGate * 100.0));
 
-    ui->addressText->setText(tr("%1:%2").arg(m_settings.m_udpAddress).arg(m_settings.m_udpPort));
+    ui->localUDPAddress->setText(m_settings.m_udpAddress);
+    ui->localUDPPort->setText(tr("%1").arg(m_settings.m_udpPort));
 
     ui->applyBtn->setEnabled(false);
     ui->applyBtn->setStyleSheet("QPushButton { background:rgb(79,79,79); }");
@@ -285,6 +286,29 @@ void UDPSinkGUI::on_sampleFormat_currentIndexChanged(int index)
     ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }");
 }
 
+void UDPSinkGUI::on_localUDPAddress_editingFinished()
+{
+    m_settings.m_udpAddress = ui->localUDPAddress->text();
+    ui->applyBtn->setEnabled(true);
+    ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }");
+}
+
+void UDPSinkGUI::on_localUDPPort_editingFinished()
+{
+    bool ok;
+    quint16 udpPort = ui->localUDPPort->text().toInt(&ok);
+
+    if((!ok) || (udpPort < 1024)) {
+        udpPort = 9998;
+    }
+
+    m_settings.m_udpPort = udpPort;
+    ui->localUDPPort->setText(tr("%1").arg(m_settings.m_udpPort));
+
+    ui->applyBtn->setEnabled(true);
+    ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }");
+}
+
 void UDPSinkGUI::on_sampleRate_textEdited(const QString& arg1 __attribute__((unused)))
 {
     bool ok;
@@ -445,7 +469,6 @@ void UDPSinkGUI::onMenuDialogCalled(const QPoint &p)
 
     setWindowTitle(m_channelMarker.getTitle());
     setTitleColor(m_settings.m_rgbColor);
-    ui->addressText->setText(tr("%1:%2").arg(m_settings.m_udpAddress).arg(m_settings.m_udpPort));
 
     applySettings();
 }
diff --git a/plugins/channeltx/udpsink/udpsinkgui.h b/plugins/channeltx/udpsink/udpsinkgui.h
index c70001189..f8190df50 100644
--- a/plugins/channeltx/udpsink/udpsinkgui.h
+++ b/plugins/channeltx/udpsink/udpsinkgui.h
@@ -90,6 +90,8 @@ private slots:
     void handleSourceMessages();
     void on_deltaFrequency_changed(qint64 value);
     void on_sampleFormat_currentIndexChanged(int index);
+    void on_localUDPAddress_editingFinished();
+    void on_localUDPPort_editingFinished();
     void on_sampleRate_textEdited(const QString& arg1);
     void on_rfBandwidth_textEdited(const QString& arg1);
     void on_fmDeviation_textEdited(const QString& arg1);
diff --git a/plugins/channeltx/udpsink/udpsinkgui.ui b/plugins/channeltx/udpsink/udpsinkgui.ui
index 0a547742d..92a6d60b3 100644
--- a/plugins/channeltx/udpsink/udpsinkgui.ui
+++ b/plugins/channeltx/udpsink/udpsinkgui.ui
@@ -770,7 +770,39 @@
     <item row="2" column="0">
      <layout class="QHBoxLayout" name="AddressLayout">
       <item>
-       <widget class="QLabel" name="addresslabel">
+       <widget class="QLabel" name="localUDPAddressLabel">
+        <property name="text">
+         <string>A</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QLineEdit" name="localUDPAddress">
+        <property name="minimumSize">
+         <size>
+          <width>110</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>110</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>Local UDP address</string>
+        </property>
+        <property name="inputMask">
+         <string>000.000.000.000; </string>
+        </property>
+        <property name="text">
+         <string>127.0.0.1</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QLabel" name="addressSeparator">
         <property name="maximumSize">
          <size>
           <width>35</width>
@@ -778,26 +810,51 @@
          </size>
         </property>
         <property name="text">
-         <string>Addr</string>
+         <string>:</string>
         </property>
        </widget>
       </item>
       <item>
-       <widget class="QLabel" name="addressText">
+       <widget class="QLineEdit" name="localUDPPort">
         <property name="minimumSize">
          <size>
-          <width>150</width>
+          <width>50</width>
           <height>0</height>
          </size>
         </property>
+        <property name="maximumSize">
+         <size>
+          <width>50</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="acceptDrops">
+         <bool>false</bool>
+        </property>
         <property name="toolTip">
-         <string>Receiving UDP address and port</string>
+         <string>Local UDP port</string>
+        </property>
+        <property name="inputMask">
+         <string>00000; </string>
         </property>
         <property name="text">
-         <string>000.000.000.000:00000</string>
+         <string>9998</string>
         </property>
        </widget>
       </item>
+      <item>
+       <spacer name="horizontalSpacer_4">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
      </layout>
     </item>
     <item row="4" column="0">
diff --git a/plugins/channeltx/udpsink/udpsinksettings.cpp b/plugins/channeltx/udpsink/udpsinksettings.cpp
index 2c0ca7a56..7bcbdab13 100644
--- a/plugins/channeltx/udpsink/udpsinksettings.cpp
+++ b/plugins/channeltx/udpsink/udpsinksettings.cpp
@@ -145,12 +145,12 @@ bool UDPSinkSettings::deserialize(const QByteArray& data)
         m_gainIn = s32tmp / 10.0;
 
         d.readString(18, &m_udpAddress, "127.0.0.1");
-        d.readU32(19, &u32tmp, 10);
+        d.readU32(19, &u32tmp, 9998);
 
         if ((u32tmp > 1024) & (u32tmp < 65538)) {
             m_udpPort = u32tmp;
         } else {
-            m_udpPort = 9999;
+            m_udpPort = 9998;
         }
 
         d.readString(20, &m_title, "UDP Sample Sink");
diff --git a/sdrgui/gui/audiodialog.ui b/sdrgui/gui/audiodialog.ui
index ce6312a16..d995c3b04 100644
--- a/sdrgui/gui/audiodialog.ui
+++ b/sdrgui/gui/audiodialog.ui
@@ -136,7 +136,7 @@
             </size>
            </property>
            <property name="toolTip">
-            <string>UDP address</string>
+            <string>Destination UDP address</string>
            </property>
            <property name="inputMask">
             <string>000.000.000.000; </string>
@@ -162,7 +162,7 @@
             </size>
            </property>
            <property name="toolTip">
-            <string>UDP port</string>
+            <string>DestinationUDP port</string>
            </property>
            <property name="inputMask">
             <string>00000; </string>