From 1bbc6395e74f1144d1835774a73a56afb0225077 Mon Sep 17 00:00:00 2001
From: c vw <dl1ycf@darc.de>
Date: Tue, 19 Jul 2022 19:21:38 +0200
Subject: [PATCH] Added support for HermesLite-II with an audio codec.

---
 old_protocol.c | 14 ++++++++++----
 radio.c        |  8 ++++++++
 radio.h        |  2 ++
 radio_menu.c   | 41 +++++++++++++++++++++++++++++------------
 4 files changed, 49 insertions(+), 16 deletions(-)

diff --git a/old_protocol.c b/old_protocol.c
index 728e81c..97fe4aa 100644
--- a/old_protocol.c
+++ b/old_protocol.c
@@ -1274,11 +1274,10 @@ void old_protocol_audio_samples(RECEIVER *rx,short left_audio_sample,short right
     //
     // The HL2 makes no use of audio samples, but instead
     // uses them to write to extended addrs which we do not
-    // want to do un-intentionally, therefore send zeros
-    // We could also stop this data stream during TX
-    // completely
+    // want to do un-intentionally, therefore send zeros.
+    // Note special variants of the HL2 *do* have an audio codec!
     //
-    if (device == DEVICE_HERMES_LITE2) {
+    if (device == DEVICE_HERMES_LITE2 && !hl2_audio_codec) {
       TXRINGBUF[txring_inptr++]=0;
       TXRINGBUF[txring_inptr++]=0;
       TXRINGBUF[txring_inptr++]=0;
@@ -1497,6 +1496,13 @@ void ozy_send_buffer() {
     if(active_receiver->dither) {
 	output_buffer[C3]|=LT2208_DITHER_ON;
     }
+    //
+    // Some  HL2 firmware variants (ab-) uses this bit for indicating an audio codec is present
+    // We also  accept explicit use  of the "dither" box
+    //
+    if(device == DEVICE_HERMES_LITE2 && hl2_audio_codec) {
+	output_buffer[C3]|=LT2208_DITHER_ON;
+    }
     if (filter_board == CHARLY25 && active_receiver->preamp) {
       output_buffer[C3]|=LT2208_GAIN_ON;
     }
diff --git a/radio.c b/radio.c
index d50e5d5..9ce3da5 100644
--- a/radio.c
+++ b/radio.c
@@ -161,6 +161,14 @@ int atlas_config=0;
 int atlas_mic_source=0;
 int atlas_janus=0;
 
+//
+// if hl2_audio_codec is set,  audio data is included in the HPSDR
+// data stream and the "dither" bit is set. This is used by a
+// "compagnion board" and  a variant of the HL2 firmware
+// This bit can be set in the "RADIO" menu.
+//
+int hl2_audio_codec=0;
+
 int classE=0;
 
 int tx_out_of_band=0;
diff --git a/radio.h b/radio.h
index 4beb186..af7647b 100644
--- a/radio.h
+++ b/radio.h
@@ -328,6 +328,8 @@ extern GMutex property_mutex;
 extern gboolean server;
 #endif
 
+extern int hl2_audio_codec;
+
 extern void radio_stop(void);
 extern void reconfigure_radio(void);
 extern void start_radio(void);
diff --git a/radio_menu.c b/radio_menu.c
index a1eee35..86964de 100644
--- a/radio_menu.c
+++ b/radio_menu.c
@@ -219,6 +219,10 @@ static void touchscreen_cb(GtkWidget *widget, gpointer data) {
   optimize_for_touchscreen=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
 }
 
+static void hl2audio_cb(GtkWidget *widget, gpointer data) {
+  hl2_audio_codec=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+}
+
 static void split_cb(GtkWidget *widget, gpointer data) {
   int new=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
   if (new != split) g_idle_add(ext_split_toggle, NULL);
@@ -850,18 +854,37 @@ void radio_menu(GtkWidget *parent) {
   gtk_grid_attach(GTK_GRID(grid),mute_rx_b,col,row,1,1);
   g_signal_connect(mute_rx_b,"toggled",G_CALLBACK(mute_rx_cb),NULL);
 
-  col++;
+  row++;
 
+  col=0;
+  GtkWidget *touchscreen_b=gtk_check_button_new_with_label("TouchScreen");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (touchscreen_b), optimize_for_touchscreen);
+  gtk_grid_attach(GTK_GRID(grid),touchscreen_b,col,row,1,1);
+  g_signal_connect(touchscreen_b,"toggled",G_CALLBACK(touchscreen_cb),NULL);
+  
+  col++;
   GtkWidget *PA_enable_b=gtk_check_button_new_with_label("PA enable");
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (PA_enable_b), pa_enabled);
   gtk_grid_attach(GTK_GRID(grid),PA_enable_b,col,row,1,1);
   g_signal_connect(PA_enable_b,"toggled",G_CALLBACK(PA_enable_cb),NULL);
 
-  col++;
-  GtkWidget *iqswap_b=gtk_check_button_new_with_label("Swap IQ");
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (iqswap_b), iqswap);
-  gtk_grid_attach(GTK_GRID(grid),iqswap_b,col,row,1,1);
-  g_signal_connect(iqswap_b,"toggled",G_CALLBACK(iqswap_cb),NULL);
+  if (protocol == ORIGINAL_PROTOCOL && device==DEVICE_HERMES_LITE2) {
+    col++;
+    GtkWidget *hl2audio_b=gtk_check_button_new_with_label("HL2 audio codec");
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hl2audio_b), hl2_audio_codec);
+    gtk_grid_attach(GTK_GRID(grid),hl2audio_b,col,row,1,1);
+    g_signal_connect(hl2audio_b,"toggled",G_CALLBACK(hl2audio_cb),NULL);
+  }
+
+#ifdef SOAPYSDR
+  if (protocol == SOAPYSDR_PROTOCOL) {
+    col++;
+    GtkWidget *iqswap_b=gtk_check_button_new_with_label("Swap IQ");
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (iqswap_b), iqswap);
+    gtk_grid_attach(GTK_GRID(grid),iqswap_b,col,row,1,1);
+    g_signal_connect(iqswap_b,"toggled",G_CALLBACK(iqswap_cb),NULL);
+  }
+#endif
 
   row++;
   col=0;
@@ -889,12 +912,6 @@ void radio_menu(GtkWidget *parent) {
     g_signal_connect(rx_gain_calibration_b,"value_changed",G_CALLBACK(rx_gain_calibration_value_changed_cb),NULL);
   }
 
-  col++;
-  GtkWidget *touchscreen_b=gtk_check_button_new_with_label("TouchScreen");
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (touchscreen_b), optimize_for_touchscreen);
-  gtk_grid_attach(GTK_GRID(grid),touchscreen_b,col,row,1,1);
-  g_signal_connect(touchscreen_b,"toggled",G_CALLBACK(touchscreen_cb),NULL);
-
   row++;
 
   if(row>temp_row) temp_row=row;
-- 
2.45.2