]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
added FreeDV support
authorJohn Melton g0orx/n6lyt <john.d.melton@googlemail.com>
Sat, 11 Jun 2016 06:42:04 +0000 (06:42 +0000)
committerJohn Melton g0orx/n6lyt <john.d.melton@googlemail.com>
Sat, 11 Jun 2016 06:42:04 +0000 (06:42 +0000)
34 files changed:
Makefile
audio.c [new file with mode: 0644]
audio.h [new file with mode: 0644]
band.c
band.h
discovered.h
filter.c
freedv.c [new file with mode: 0644]
freedv.h [new file with mode: 0644]
frequency.c
gpio.c
lime_discovery.c
lime_protocol.c [new file with mode: 0644]
lime_protocol.h [new file with mode: 0644]
main.c
menu.c
meter.c
mode.c
mode.h
new_discovery.c
new_protocol.c
new_protocol_programmer.c
old_discovery.c
old_protocol.c
panadapter.c
pihpsdr
radio.c
radio.h
release/pihpsdr.tar
release/pihpsdr/pihpsdr
toolbar.c
vfo.c
wdsp_init.c
wdsp_init.h

index 1ab6bda035b6fdf05c3010780eeaa972fd018380..763ade8f730a7feb9dcb9c8749ef5ff913dae1bd 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,26 +2,40 @@ UNAME_N := $(shell uname -n)
 CC=gcc
 LINK=gcc
 
-#required for LimeSDR (uncomment lines below)
+#required for LimeSDR (uncomment line below)
+#LIMESDR_INCLUDE=LIMESDR
+
+ifeq ($(LIMESDR_INCLUDE),LIMESDR)
 #LIMESDR_OPTIONS=-D LIMESDR
-#SOAPYSDRLIBS=-lSoapySDR
-#LIMESDR_SOURCES= \
-#lime_discovery.c
-#LIMESDR_HEADERS= \
-#lime_discovery.h
-#LIMESDR_OBJS= \
-#lime_discovery.o
+SOAPYSDRLIBS=-lSoapySDR -lpulse-simple -lpulse
+LIMESDR_SOURCES= \
+audio.c \
+lime_discovery.c \
+lime_protocol.c
+LIMESDR_HEADERS= \
+audio.h \
+lime_discovery.h \
+lime_protocol.h
+LIMESDR_OBJS= \
+audio.o \
+lime_discovery.o \
+lime_protocol.o
+endif
 
 
 #required for FREEDV (uncomment lines below)
-#FREEDV_OPTIONS=-D FREEDV
-#FREEDVLIBS=-lcodec2
-#FREEDV_SOURCES= \
-#freedv.c
-#FREEDV_HEADERS= \
-#freedv.h
-#FREEDV_OBJS= \
-#freedv.o
+FREEDV_INCLUDE=FREEDV
+
+ifeq ($(FREEDV_INCLUDE),FREEDV)
+FREEDV_OPTIONS=-D FREEDV
+FREEDVLIBS=-lcodec2
+FREEDV_SOURCES= \
+freedv.c
+FREEDV_HEADERS= \
+freedv.h
+FREEDV_OBJS= \
+freedv.o
+endif
 
 OPTIONS=-g -D $(UNAME_N) $(LIMESDR_OPTIONS) $(FREEDV_OPTIONS) -O3
 GTKINCLUDES=`pkg-config --cflags gtk+-3.0`
diff --git a/audio.c b/audio.c
new file mode 100644 (file)
index 0000000..17e99eb
--- /dev/null
+++ b/audio.c
@@ -0,0 +1,146 @@
+/* Copyright (C)
+* 2016 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+*
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <sched.h>
+#include <semaphore.h>
+
+#include <pulse/simple.h>
+#include <pulse/error.h>
+
+#include "audio.h"
+
+int audio = 0;
+int audio_buffer_size = 2016; // samples (both left and right)
+
+static pa_simple *stream;
+
+static sem_t audioBufferFull;
+static sem_t audioBufferEmpty;
+static pthread_t audioThreadId;
+
+// each buffer contains 63 samples of left and right audio at 16 bits
+#define AUDIO_SAMPLES 63
+#define AUDIO_SAMPLE_SIZE 2
+#define AUDIO_CHANNELS 2
+#define AUDIO_BUFFERS 10
+#define AUDIO_BUFFER_SIZE (AUDIO_SAMPLE_SIZE*AUDIO_CHANNELS*audio_buffer_size)
+
+static unsigned char *audio_buffer;
+static int audio_offset=0;
+
+void* audioThread(void* arg);
+
+void audio_init() {
+
+    static const pa_sample_spec spec= {
+        .format = PA_SAMPLE_S16RE,
+        .rate =  48000,
+        .channels = 2
+    };
+
+    int error;
+
+fprintf(stderr,"audio_init audio_buffer_size=%d\n",audio_buffer_size);
+
+    audio_buffer=(unsigned char *)malloc(AUDIO_BUFFER_SIZE);
+
+    if (!(stream = pa_simple_new(NULL, "pihpsdr", PA_STREAM_PLAYBACK, NULL, "playback", &spec, NULL, NULL, &error))) {
+        fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
+        _exit(1);
+    }
+
+    int res=sem_init(&audioBufferFull, 0, 0);
+    if(res!=0) {
+        fprintf(stderr,"audio_init: sem_init failed for audioBufferFull%d\n", res);
+        _exit(1);
+    }
+
+    res=sem_init(&audioBufferEmpty, 0, 0);
+    if(res!=0) {
+        fprintf(stderr,"audio_init: sem_init failed for audioBufferEmpty%d\n", res);
+        _exit(1);
+    }
+
+    res=pthread_create(&audioThreadId, NULL, audioThread, NULL);
+    if(res<0) {
+        fprintf(stderr, "Error creating DFC thread: %d\n", res);
+        _exit(1);
+    }
+
+fprintf(stderr,"... audio_init\n");
+}
+
+
+void audio_write(double* buffer,int samples) {
+    int i;
+    int error;
+
+    for(i=0;i<samples;i++) {
+        int source_index=i*2;
+        short left_sample=(short)(buffer[source_index]*32768.0);
+        short right_sample=(short)(buffer[source_index+1]*32768.0);
+        audio_buffer[audio_offset++]=left_sample>>8;
+        audio_buffer[audio_offset++]=left_sample;
+        audio_buffer[audio_offset++]=right_sample>>8;
+        audio_buffer[audio_offset++]=right_sample;
+
+        if(audio_offset==AUDIO_BUFFER_SIZE) {
+            if (pa_simple_write(stream, audio_buffer, (size_t)AUDIO_BUFFER_SIZE, &error) < 0) {
+                fprintf(stderr, __FILE__": pa_simple_write() failed: %s\n", pa_strerror(error));
+                _exit(1);
+            }
+            audio_offset=0;
+        }
+    }
+
+}
+
+void* audioThread(void* arg) {
+    int error;
+    fprintf(stderr,"audioThread running on cpu%d\n", sched_getcpu());
+
+    while(1) {
+
+/*
+        error=sem_post(&audioBufferEmpty);
+        if(error!=0) {
+            fprintf(stderr, "audioThread: sem_post failed for audioBufferEmpty: %d\n", error);
+            _exit(1);
+        }
+*/
+        error=sem_wait(&audioBufferFull);
+        if(error!=0) {
+            fprintf(stderr, "audioThread: sem_wait failed for audioBufferFull: %d\n", error);
+            _exit(1);
+        }
+
+        if (pa_simple_write(stream, audio_buffer, (size_t)AUDIO_BUFFER_SIZE, &error) < 0) {
+            fprintf(stderr, __FILE__": pa_simple_write() failed: %s\n", pa_strerror(error));
+            _exit(1);
+        }
+    }
+}
diff --git a/audio.h b/audio.h
new file mode 100644 (file)
index 0000000..e6d2da5
--- /dev/null
+++ b/audio.h
@@ -0,0 +1,24 @@
+/* Copyright (C)
+* 2016 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+*
+*/
+
+extern int audio;
+extern int audio_buffer_size;
+
+void audio_init();
+void audio_write(double *buffer,int samples);
diff --git a/band.c b/band.c
index daf9569b492cac4d8a4c1d3fcf8639780f1eb5f6..9667ac8634bcef59c6523d1b6a252f57676c528f 100644 (file)
--- a/band.c
+++ b/band.c
@@ -103,7 +103,10 @@ BANDSTACK_ENTRY bandstack_entries70[] =
 BANDSTACK_ENTRY bandstack_entries144[] =
     {{144010000LL,modeCWU,filterF0,200,2800,200,2800},
      {144200000LL,modeUSB,filterF5,200,2800,200,2800},
-     {144250000LL,modeUSB,filterF5,200,2800,200,2800}};
+     {144250000LL,modeUSB,filterF5,200,2800,200,2800},
+     {145600000LL,modeFMN,filterF1,200,2800,200,2800},
+     {145725000LL,modeFMN,filterF1,200,2800,200,2800},
+     {145900000LL,modeFMN,filterF1,200,2800,200,2800}};
 
 BANDSTACK_ENTRY bandstack_entries220[] =
     {{220010000LL,modeCWU,filterF0,200,2800,200,2800},
@@ -134,6 +137,14 @@ BANDSTACK_ENTRY bandstack_entries3400[] =
     {{3400010000LL,modeCWU,filterF0,200,2800,200,2800},
      {3400100000LL,modeUSB,filterF5,200,2800,200,2800},
      {3400300000LL,modeUSB,filterF5,200,2800,200,2800}};
+
+BANDSTACK_ENTRY bandstack_entriesAIR[] =
+    {{118800000LL,modeAM,filterF1,200,2800,200,2800},
+     {120000000LL,modeAM,filterF1,200,2800,200,2800},
+     {121700000LL,modeAM,filterF1,200,2800,200,2800},
+     {124100000LL,modeAM,filterF1,200,2800,200,2800},
+     {126600000LL,modeAM,filterF1,200,2800,200,2800},
+     {136500000LL,modeAM,filterF1,200,2800,200,2800}};
 #endif
 
 BANDSTACK_ENTRY bandstack_entriesGEN[] =
@@ -161,13 +172,14 @@ BANDSTACK bandstack10={3,1,bandstack_entries10};
 BANDSTACK bandstack50={3,1,bandstack_entries50};
 #ifdef LIMESDR
 BANDSTACK bandstack70={3,1,bandstack_entries70};
-BANDSTACK bandstack144={3,1,bandstack_entries144};
+BANDSTACK bandstack144={6,1,bandstack_entries144};
 BANDSTACK bandstack220={3,1,bandstack_entries220};
 BANDSTACK bandstack430={3,1,bandstack_entries430};
 BANDSTACK bandstack902={3,1,bandstack_entries902};
 BANDSTACK bandstack1240={3,1,bandstack_entries1240};
 BANDSTACK bandstack2300={3,1,bandstack_entries2300};
 BANDSTACK bandstack3400={3,1,bandstack_entries3400};
+BANDSTACK bandstackAIR={6,1,bandstack_entriesAIR};
 #endif
 BANDSTACK bandstackGEN={3,1,bandstack_entriesGEN};
 BANDSTACK bandstackWWV={5,1,bandstack_entriesWWV};
@@ -193,6 +205,7 @@ BAND bands[BANDS] =
      {"1240",&bandstack1240,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB,30},
      {"2300",&bandstack2300,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB,30},
      {"3400",&bandstack3400,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB,30},
+     {"AIR",&bandstackAIR,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB,30},
 #endif
      {"GEN",&bandstackGEN,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB,0},
      {"WWV",&bandstackWWV,0,0,0,ALEX_RX_ANTENNA_NONE,ALEX_TX_ANTENNA_1,ALEX_ATTENUATION_0dB,0}};
diff --git a/band.h b/band.h
index 5916e5da4f1686842d3c7589c7f2fc54a814ca5a..4c35de6d70e7f91f6a1979f64b77f4af0c61bc13 100644 (file)
--- a/band.h
+++ b/band.h
 #define band1240 16
 #define band2300 17
 #define band3400 18
-#define bandGen 19
-#define bandWWV 20
-#define BANDS 21
+#define bandAIR 19
+#define bandGen 20
+#define bandWWV 21
+#define BANDS 22
 #define HAM_BANDS 19
 #else
 #define bandGen 11
index d57010aa50ecbc931050f10b43bf55357e57d9a7..a3ac2efd4866e121c9de2e3a50e506d498ae2f9c 100644 (file)
@@ -18,6 +18,7 @@
 */
 
 #include <netinet/in.h>
+#include <SoapySDR/Device.h>
 
 #define MAX_DEVICES 16
 
@@ -36,7 +37,7 @@
 #define NEW_DEVICE_ORION2 5
 #define NEW_DEVICE_HERMES_LITE 6
 
-#define LIMESDR_DEVICE 0
+#define LIMESDR_USB_DEVICE 0
 
 #define STATE_AVAILABLE 2
 #define STATE_SENDING 3
 struct _DISCOVERED {
     int protocol;
     int device;
-    char name[16];
+    char name[64];
     int software_version;
-    unsigned char mac_address[6];
     int status;
-    int address_length;
-    struct sockaddr_in address;
-    int interface_length;
-    struct sockaddr_in interface_address;
-    struct sockaddr_in interface_netmask;
-    char interface_name[64];
+    union {
+      struct network {
+        unsigned char mac_address[6];
+        int address_length;
+        struct sockaddr_in address;
+        int interface_length;
+        struct sockaddr_in interface_address;
+        struct sockaddr_in interface_netmask;
+        char interface_name[64];
+      } network;
+      struct soapy {
+        SoapySDRKwargs *args;
+      } soapy;
+    } info;
 };
 
 typedef struct _DISCOVERED DISCOVERED;
index 84f12e375100e9a93e39ba49e45a8d0459174022..09a57c4b710d09e08fa1820a8ff0a9344f988e3b 100644 (file)
--- a/filter.c
+++ b/filter.c
@@ -199,6 +199,7 @@ FILTER filterDRM[FILTERS]={
     {-3300,3300,"Var2"}*/
     };
 
+#ifdef FREEDV
 FILTER filterFREEDV[FILTERS]={
     {150,5150,"5.0k"},
     {150,4550,"4.4k"},
@@ -213,7 +214,24 @@ FILTER filterFREEDV[FILTERS]={
     {150,2850,"Var1"},
     {150,2850,"Var2"}*/
     };
-
-
-FILTER *filters[]={filterLSB,filterUSB,filterDSB,filterCWL,filterCWU,filterFMN,filterAM,filterDIGU,filterSPEC,filterDIGL,filterSAM,filterDRM,filterFREEDV};
+#endif
+
+
+FILTER *filters[]={
+    filterLSB
+    ,filterUSB
+    ,filterDSB
+    ,filterCWL
+    ,filterCWU
+    ,filterFMN
+    ,filterAM
+    ,filterDIGU
+    ,filterSPEC
+    ,filterDIGL
+    ,filterSAM
+    ,filterDRM
+#ifdef FREEDV
+    ,filterFREEDV
+#endif
+};
 
diff --git a/freedv.c b/freedv.c
new file mode 100644 (file)
index 0000000..ccdf478
--- /dev/null
+++ b/freedv.c
@@ -0,0 +1,125 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <codec2/freedv_api.h>
+
+#include "radio.h"
+
+static struct freedv* modem;
+
+int n_speech_samples;
+int n_max_modem_samples;
+int n_nom_modem_samples;
+short *speech_out;
+short *demod_in;
+short *speech_in;
+short *mod_out;
+int rx_samples_in;
+int tx_samples_in;
+int samples_out;
+int nin;
+
+int freedv_sync;
+float freedv_snr;
+
+int freedv_tx_text_index=0;
+
+char freedv_rx_text_data[64];
+int freedv_rx_text_data_index=0;
+
+static void my_put_next_rx_char(void *callback_state, char c) {
+  fprintf(stderr, "freedv: my_put_next_rx_char: %c sync=%d\n", c, freedv_sync);
+  if(freedv_sync) {
+    if(c==0x0D) {
+      freedv_rx_text_data_index=0;
+    } else {
+      freedv_rx_text_data[freedv_rx_text_data_index++]=c;
+      freedv_rx_text_data[freedv_rx_text_data_index]=0;
+      if(freedv_rx_text_data_index>=62) {
+        freedv_rx_text_data_index=0;
+      }
+    }
+  }
+}
+
+
+static char my_get_next_tx_char(void *callback_state){
+  char c=freedv_tx_text_data[freedv_tx_text_index++];
+  if(c==0) {
+    c=0x0D;
+    freedv_tx_text_index=0;
+  }
+fprintf(stderr,"freedv: my_get_next_tx_char=%c\n",c);
+  return c;
+}
+
+void init_freedv() {
+fprintf(stderr,"init_freedv\n");
+  modem=freedv_open(FREEDV_MODE_1600);
+  if(modem==NULL) {
+    fprintf(stderr,"freedv_open: modem is null\n");
+    return;
+  }
+
+  freedv_set_snr_squelch_thresh(modem, -100.0);
+  freedv_set_squelch_en(modem, 1);
+
+  n_speech_samples = freedv_get_n_speech_samples(modem);
+  n_max_modem_samples = freedv_get_n_max_modem_samples(modem);
+  n_nom_modem_samples = freedv_get_n_nom_modem_samples(modem);
+fprintf(stderr,"n_speech_samples=%d n_max_modem_samples=%d\n",n_speech_samples, n_max_modem_samples);
+  speech_out = (short*)malloc(sizeof(short)*n_speech_samples);
+  demod_in = (short*)malloc(sizeof(short)*n_max_modem_samples);
+  speech_in = (short*)malloc(sizeof(short)*n_speech_samples);
+  mod_out = (short*)malloc(sizeof(short)*n_nom_modem_samples);
+
+  nin = freedv_nin(modem);
+  rx_samples_in=0;
+  tx_samples_in=0;
+  freedv_set_callback_txt(modem, &my_put_next_rx_char, &my_get_next_tx_char, NULL);
+  //freedv_set_callback_protocol(modem, &my_put_next_rx_proto, NULL, NULL);
+  //freedv_set_callback_data(modem, my_datarx, my_datatx, NULL);
+
+  int rate=freedv_get_modem_sample_rate(modem);
+fprintf(stderr,"freedv modem sample rate=%d\n",rate);
+
+  strcpy(freedv_rx_text_data,"");
+}
+
+void close_freedv() {
+fprintf(stderr,"freedv_close\n");
+  if(modem!=NULL) {
+    freedv_close(modem);
+  } else {
+    fprintf(stderr,"freedv_close: modem is null\n");
+  }
+}
+
+int demod_sample_freedv(short sample) {
+  int nout=0;
+  demod_in[rx_samples_in]=sample;
+  rx_samples_in++;
+  if(rx_samples_in==nin) {
+    nout=freedv_rx(modem,speech_out,demod_in);
+    nin=freedv_nin(modem);
+    rx_samples_in=0;
+    freedv_get_modem_stats(modem, &freedv_sync, &freedv_snr);
+  } 
+  return nout;
+}
+
+int mod_sample_freedv(short sample) {
+  int nout=0;
+  speech_in[tx_samples_in]=sample;
+  tx_samples_in++;
+  if(tx_samples_in==n_speech_samples) {
+    freedv_tx(modem,mod_out,speech_in);
+    tx_samples_in=0;
+    nout=n_nom_modem_samples;
+  } 
+  return nout;
+}
+
+void freedv_reset_tx_text_index() {
+  freedv_tx_text_index=0;
+}
diff --git a/freedv.h b/freedv.h
new file mode 100644 (file)
index 0000000..bfc2e82
--- /dev/null
+++ b/freedv.h
@@ -0,0 +1,18 @@
+extern int n_speech_samples;
+extern int n_max_modem_samples;
+extern short *demod_in;
+extern short *speech_out;
+extern short *speech_in;
+extern short *mod_out;
+
+extern int freedv_sync;
+extern float freedv_snr;
+
+extern char freedv_rx_text_data[64];
+
+void init_freedv();
+void close_freedv();
+int demod_sample_freedv(short sample);
+int mod_sample_freedv(short sample);
+void reset_freedv_tx_text_index();
+
index 9b309d3ded11d8a594819cdb6b412631854f7d5f..ac13728d70b711ff72cb3cb8acd6f30f0edf2119 100644 (file)
@@ -66,7 +66,9 @@ struct frequency_info frequencyInfo[]=
         {3590000LL, 3590000LL, "80M RTTY DX",                      band80, TRUE},
         {3590001LL, 3599999LL, "80M RTTY",                         band80, TRUE},
         {3600000LL, 3699999LL, "75M Extra SSB",                    band80, TRUE},
-        {3700000LL, 3789999LL, "75M Ext/Adv SSB",                  band80, TRUE},
+        {3700000LL, 3719999LL, "75M Ext/Adv SSB",                  band80, TRUE},
+        {3720000LL, 3723999LL, "75M Digital Voice",              band20, TRUE},
+        {3724000LL, 3789999LL, "75M Ext/Adv SSB",                  band80, TRUE},
         {3790000LL, 3799999LL, "75M Ext/Adv DX Window",            band80, TRUE},
         {3800000LL, 3844999LL, "75M SSB",                          band80, TRUE},
         {3845000LL, 3845000LL, "75M SSTV",                         band80, TRUE},
@@ -122,8 +124,9 @@ struct frequency_info frequencyInfo[]=
         {14150000LL, 14174999LL, "20M Extra SSB",                  band20, TRUE},
         {14175000LL, 14224999LL, "20M Ext/Adv SSB",                band20, TRUE},
         {14225000LL, 14229999LL, "20M SSB",                        band20, TRUE},
-        {14230000LL, 14230000LL, "20M SSTV",                       band20, TRUE},
-        {14230000LL, 14284999LL, "20M SSB",                        band20, TRUE},
+        {14230000LL, 14235999LL, "20M SSTV",                       band20, TRUE},
+        {14236000LL, 14239999LL, "20M Digital Voice",              band20, TRUE},
+        {14240000LL, 14284999LL, "20M SSB",                        band20, TRUE},
         {14285000LL, 14285000LL, "20M SSB QRP Calling Frequency",  band20, TRUE},
         {14285000LL, 14285999LL, "20M SSB",                        band20, TRUE},
         {14286000LL, 14286000LL, "20M AM Calling Frequency",       band20, TRUE},
diff --git a/gpio.c b/gpio.c
index b30a50ebfb6e546219af42029d0fe08140e8713f..c2060a8354fbc80593ad1ac3f9eb02ec5eee029a 100644 (file)
--- a/gpio.c
+++ b/gpio.c
@@ -754,8 +754,9 @@ static int vfo_encoder_changed(void *data) {
   if(!locked) {
     int pos=*(int*)data;
     BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
-    entry->frequencyA=entry->frequencyA+(pos*step);
-    setFrequency(entry->frequencyA);
+    //entry->frequencyA=entry->frequencyA+(pos*step);
+    //setFrequency(entry->frequencyA);
+    setFrequency(entry->frequencyA+ddsOffset+(pos*step));
     vfo_update(NULL);
   }
   free(data);
index 941420857d3eba25716df3c17ed0aa0c86157bea..86979bb9c5dbe6f0b8cad8bbc1bb7c3d584cdfd6 100644 (file)
@@ -1,5 +1,7 @@
 #include <stdio.h>
+#include <string.h>
 #include <SoapySDR/Device.h>
+#include "discovered.h"
 #include "lime_discovery.h"
 
 void lime_discovery() {
@@ -7,13 +9,77 @@ void lime_discovery() {
   size_t length;
   int i;
   args.size=0;
-  SoapySDRKwargs *devices=SoapySDRDevice_enumerate(&args, &length);
+  SoapySDRKwargs *devs=SoapySDRDevice_enumerate(&args, &length);
 
-fprintf(stderr,"lime_discovery: length=%d devices->size=%d\n",length,devices->size);
+fprintf(stderr,"lime_discovery: length=%ld devs->size=%ld\n",length,devs->size);
 
-  for(i=0;i<length;i++) {
-fprintf(stderr,"lime_discovery: key=%s val=%s\n",devices->keys[i], devices->vals[i]);
+  for(i=0;i<devs->size;i++) {
+fprintf(stderr,"lime_discovery:device key=%s val=%s\n",devs->keys[i], devs->vals[i]);
+    if(strcmp(devs->keys[i],"name")==0) {
+      discovered[devices].protocol=LIMESDR_PROTOCOL;
+      discovered[devices].device=LIMESDR_USB_DEVICE;
+      strcpy(discovered[devices].name,devs->vals[i]);
+      discovered[devices].status=STATE_AVAILABLE;
+      discovered[devices].info.soapy.args=devs;
+      devices++;
+    }
   }
 
+/*
+  SoapySDRDevice *device=SoapySDRDevice_make(devs);
+  if(device==NULL) {
+    fprintf(stderr,"SoapySDRDevice_make failed: %s\n",SoapySDRDevice_lastError());
+    return;
+  }
+
+  SoapySDRKwargs info=SoapySDRDevice_getHardwareInfo(device);
+  int version=0;
+  for(i=0;i<info.size;i++) {
+fprintf(stderr,"lime_discovery: info key=%s val=%s\n",info.keys[i], info.vals[i]);
+    if(strcmp(info.keys[i],"firmwareVersion")==0) {
+      version+=atoi(info.vals[i])*100;
+    }
+    if(strcmp(info.keys[i],"hardwareVersion")==0) {
+      version+=atoi(info.vals[i])*10;
+    }
+    if(strcmp(info.keys[i],"protocolVersion")==0) {
+      version+=atoi(info.vals[i]);
+    }
+  }
+  
+  discovered[devices].software_version=version;
+*/
+
+/*
+  fprintf(stderr,"SampleRates\n");
+  int rates;
+  double *rate;
+  rate=SoapySDRDevice_listSampleRates(device,SOAPY_SDR_RX,0,&rates);
+  for(i=0;i<rates;i++) {
+    fprintf(stderr,"rate=%f\n",rate[i]);
+  }
+
+  fprintf(stderr,"Bandwidths\n");
+  int bandwidths;
+  double *bandwidth;
+  bandwidth=SoapySDRDevice_listSampleRates(device,SOAPY_SDR_RX,0,&bandwidths);
+  for(i=0;i<bandwidths;i++) {
+    fprintf(stderr,"bandwidth=%f\n",bandwidth[i]);
+  }
+
+  fprintf(stderr,"Antennas\n");
+  int antennas;
+  char **antenna;
+  antenna=SoapySDRDevice_listAntennas(device,SOAPY_SDR_RX,0,&antennas);
+  for(i=0;i<antennas;i++) {
+    fprintf(stderr,"antenna=%s\n",antenna[i]);
+  }
+
+  char *ant=SoapySDRDevice_getAntenna(device,SOAPY_SDR_RX,0);
+  fprintf(stderr,"selected antenna=%s\n",ant);
+
+  SoapySDRDevice_unmake(device);
+
+*/
   fprintf(stderr,"lime_discovery found %d devices\n",length);
 }
diff --git a/lime_protocol.c b/lime_protocol.c
new file mode 100644 (file)
index 0000000..c7332eb
--- /dev/null
@@ -0,0 +1,365 @@
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <wdsp.h>
+
+//#define TIMING
+#ifdef TIMING
+#include <sys/time.h>
+#endif
+
+#include "audio.h"
+#include "channel.h"
+#include "discovered.h"
+#include "lime_protocol.h"
+#include "radio.h"
+#include "SoapySDR/Constants.h"
+#include "SoapySDR/Device.h"
+
+static double bandwidth=3000000.0;
+
+static DISCOVERED *d;
+static size_t receiver;
+static SoapySDRDevice *lime_device;
+static SoapySDRStream *stream;
+static int display_width;
+static int buffer_size=BUFFER_SIZE;
+static int outputsamples;
+static int fft_size=4096;
+static int dspRate=48000;
+static int outputRate=48000;
+static float *buffer;
+static int max_samples;
+
+static long long saved_frequency=0LL;
+static int saved_antenna=-1;
+
+static double iqinputbuffer[BUFFER_SIZE*2];
+static double audiooutputbuffer[BUFFER_SIZE*2];
+static int samples=0;
+
+static pthread_t receive_thread_id;
+static void *receive_thread(void* arg);
+
+static void *resampler;
+static int actual_rate;
+static double resamples[1024*2];
+static double resampled[1024*2];
+
+#ifdef TIMING
+static int rate_samples;
+#endif
+
+static int running;
+
+void lime_protocol_init(int rx,int pixels) {
+  SoapySDRKwargs args;
+  int rc;
+
+fprintf(stderr,"lime_protocol_init: receiver=%d pixels=%d\n",rx,pixels);
+
+  d=&discovered[selected_device];
+  receiver=(size_t)rx;
+  display_width=pixels;
+
+  outputsamples=BUFFER_SIZE/(sample_rate/48000);
+/*
+  switch(sample_rate) {
+    case 48000:
+      outputsamples=BUFFER_SIZE;
+      break;
+    case 96000:
+      outputsamples=BUFFER_SIZE/2;
+      break;
+    case 192000:
+      outputsamples=BUFFER_SIZE/4;
+      break;
+    case 384000:
+      outputsamples=BUFFER_SIZE/8;
+      break;
+    case 768000:
+      outputsamples=BUFFER_SIZE/16;
+      break;
+    case 1536000:
+      outputsamples=BUFFER_SIZE/32;
+      break;
+  }
+*/
+
+
+
+
+  args.size=0;
+
+  // initialize the radio
+fprintf(stderr,"lime_protocol: receive_thread: SoapySDRDevice_make\n");
+  lime_device=SoapySDRDevice_make(d->info.soapy.args);
+  if(lime_device==NULL) {
+    fprintf(stderr,"lime_protocol: SoapySDRDevice_make failed: %s\n",SoapySDRDevice_lastError());
+    _exit(-1);
+  }
+
+fprintf(stderr,"lime_protocol: set antenna to NONE\n");
+  lime_protocol_set_antenna(0);
+
+fprintf(stderr,"lime_protocol: setting samplerate=%f\n",(double)sample_rate);
+  rc=SoapySDRDevice_setSampleRate(lime_device,SOAPY_SDR_RX,receiver,(double)sample_rate);
+  if(rc!=0) {
+    fprintf(stderr,"lime_protocol: SoapySDRDevice_setSampleRate(%f) failed: %s\n",(double)sample_rate,SoapySDRDevice_lastError());
+  }
+
+  actual_rate=(int)SoapySDRDevice_getSampleRate(lime_device, SOAPY_SDR_RX, receiver);
+fprintf(stderr,"lime_protocol: actual samplerate= %d\n",actual_rate);
+if(sample_rate==768000 && actual_rate==767999) {
+  actual_rate=768000;
+  fprintf(stderr,"lime_protocol: forced actual_rate\n");
+}
+
+fprintf(stderr,"lime_protocol: setting bandwidth =%f\n",bandwidth);
+  rc=SoapySDRDevice_setBandwidth(lime_device,SOAPY_SDR_RX,receiver,bandwidth);
+  if(rc!=0) {
+    fprintf(stderr,"lime_protocol: SoapySDRDevice_setBandwidth(%f) failed: %s\n",bandwidth,SoapySDRDevice_lastError());
+  }
+
+if(saved_frequency!=0LL) {
+fprintf(stderr,"lime_protocol: setting save_frequency: %lld\n",saved_frequency);
+    lime_protocol_set_frequency(saved_frequency);
+}
+
+/*
+fprintf(stderr,"lime_protocol: set baseband frequency\n");
+  rc=SoapySDRDevice_setFrequencyComponent(lime_device,SOAPY_SDR_RX,receiver,"BB",0.0,&args);
+  if(rc!=0) {
+    fprintf(stderr,"lime_protocol: SoapySDRDevice_setFrequencyComponent(BB) failed: %s\n",SoapySDRDevice_lastError());
+  }
+*/
+  
+fprintf(stderr,"setting antennal to LNAL\n");
+  lime_protocol_set_antenna(2);
+
+fprintf(stderr,"setting Gain LNA=30.0\n");
+  rc=SoapySDRDevice_setGainElement(lime_device,SOAPY_SDR_RX,receiver,"LNA",30.0);
+  if(rc!=0) {
+    fprintf(stderr,"lime_protocol: SoapySDRDevice_setGain LNA failed: %s\n",SoapySDRDevice_lastError());
+  }
+fprintf(stderr,"setting Gain PGA=19.0\n");
+  rc=SoapySDRDevice_setGainElement(lime_device,SOAPY_SDR_RX,receiver,"PGA",19.0);
+  if(rc!=0) {
+    fprintf(stderr,"lime_protocol: SoapySDRDevice_setGain PGA failed: %s\n",SoapySDRDevice_lastError());
+  }
+fprintf(stderr,"setting Gain TIA=12.0\n");
+  rc=SoapySDRDevice_setGainElement(lime_device,SOAPY_SDR_RX,receiver,"TIA",12.0);
+  if(rc!=0) {
+    fprintf(stderr,"lime_protocol: SoapySDRDevice_setGain TIA failed: %s\n",SoapySDRDevice_lastError());
+  }
+
+fprintf(stderr,"lime_protocol: receive_thread: SoapySDRDevice_setupStream\n");
+  size_t channels=(size_t)receiver;
+  rc=SoapySDRDevice_setupStream(lime_device,&stream,SOAPY_SDR_RX,"CF32",&channels,1,&args);
+  if(rc!=0) {
+    fprintf(stderr,"lime_protocol: SoapySDRDevice_setupStream failed: %s\n",SoapySDRDevice_lastError());
+    _exit(-1);
+  }
+
+  max_samples=SoapySDRDevice_getStreamMTU(lime_device,stream);
+fprintf(stderr,"max_samples=%d\n",max_samples);
+
+  buffer=(float *)malloc(max_samples*sizeof(float)*2);
+
+  if(actual_rate!=sample_rate) {
+fprintf(stderr,"lime_protocol: creating resampler from %d to %d\n",actual_rate,sample_rate);
+    resampler=create_resample (1, max_samples, resamples, resampled, actual_rate, sample_rate, 0.0, 0, 1.0);
+  }
+
+  rc=SoapySDRDevice_activateStream(lime_device, stream, 0, 0LL, 0);
+  if(rc!=0) {
+    fprintf(stderr,"lime_protocol: SoapySDRDevice_activateStream failed: %s\n",SoapySDRDevice_lastError());
+    _exit(-1);
+  }
+
+
+  if(saved_antenna!=-1) {
+fprintf(stderr,"lime_protocol: setting save_antenna: %d\n",saved_antenna);
+    lime_protocol_set_antenna(saved_antenna);
+  }
+
+  if(saved_frequency!=0LL) {
+fprintf(stderr,"lime_protocol: setting save_frequency: %lld\n",saved_frequency);
+      lime_protocol_set_frequency(saved_frequency);
+  }
+
+fprintf(stderr,"lime_protocol_init: audio_init\n");
+  audio_init();
+
+fprintf(stderr,"lime_protocol_init: create receive_thread\n");
+  rc=pthread_create(&receive_thread_id,NULL,receive_thread,NULL);
+  if(rc != 0) {
+    fprintf(stderr,"lime_protocol: pthread_create failed on receive_thread: rc=%d\n", rc);
+    _exit(-1);
+  }
+
+
+
+}
+
+static void *receive_thread(void *arg) {
+  float isample;
+  float qsample;
+  int outsamples;
+  int elements;
+  int flags=0;
+  long long timeNs=0;
+  long timeoutUs=10000L;
+  int i;
+#ifdef TIMING
+  struct timeval tv;
+  long start_time, end_time;
+  rate_samples=0;
+  gettimeofday(&tv, NULL); start_time=tv.tv_usec + 1000000 * tv.tv_sec;
+#endif
+  running=1;
+fprintf(stderr,"lime_protocol: receive_thread\n");
+  while(running) {
+    elements=SoapySDRDevice_readStream(lime_device,stream,(void *)&buffer,max_samples,&flags,&timeNs,timeoutUs);
+//fprintf(stderr,"read %d elements\n",elements);
+    if(actual_rate!=sample_rate) {
+      for(i=0;i<elements;i++) {
+        resamples[i*2]=(double)buffer[i*2];
+        resamples[(i*2)+1]=(double)buffer[(i*2)+1];
+      }
+
+      outsamples=xresample(resampler);
+
+      for(i=0;i<outsamples;i++) {
+        iqinputbuffer[samples*2]=(double)resampled[i*2];
+        iqinputbuffer[(samples*2)+1]=(double)resampled[(i*2)+1];
+        samples++;
+#ifdef TIMING
+        rate_samples++;
+        if(rate_samples==sample_rate) {
+          gettimeofday(&tv, NULL); end_time=tv.tv_usec + 1000000 * tv.tv_sec;
+          fprintf(stderr,"%d samples in %ld\n",rate_samples, end_time-start_time);
+          start_time=end_time;
+          rate_samples=0;
+        }
+#endif
+        if(samples==buffer_size) {
+          int error;
+          fexchange0(CHANNEL_RX0, iqinputbuffer, audiooutputbuffer, &error);
+          if(error!=0) {
+            fprintf(stderr,"fexchange0 (CHANNEL_RX0) returned error: %d\n", error);
+          }
+
+          audio_write(audiooutputbuffer,outputsamples);
+          Spectrum0(1, CHANNEL_RX0, 0, 0, iqinputbuffer);
+          samples=0;
+        }
+      }
+    } else {
+      for(i=0;i<elements;i++) {
+        iqinputbuffer[samples*2]=(double)buffer[i*2];
+        iqinputbuffer[(samples*2)+1]=(double)buffer[(i*2)+1];
+        samples++;
+        if(samples==buffer_size) {
+          int error;
+          fexchange0(CHANNEL_RX0, iqinputbuffer, audiooutputbuffer, &error);
+          if(error!=0) {
+            fprintf(stderr,"fexchange0 (CHANNEL_RX0) returned error: %d\n", error);
+          }
+
+          audio_write(audiooutputbuffer,outputsamples);
+          Spectrum0(1, CHANNEL_RX0, 0, 0, iqinputbuffer);
+          samples=0;
+        }
+      }
+    }
+  }
+
+fprintf(stderr,"lime_protocol: receive_thread: SoapySDRDevice_closeStream\n");
+  SoapySDRDevice_closeStream(lime_device,stream);
+fprintf(stderr,"lime_protocol: receive_thread: SoapySDRDevice_unmake\n");
+  SoapySDRDevice_unmake(lime_device);
+
+}
+
+
+void lime_protocol_stop() {
+  running=0;
+}
+
+void lime_protocol_set_frequency(long long f) {
+  int rc;
+  char *ant;
+
+  if(lime_device!=NULL) {
+    SoapySDRKwargs args;
+    args.size=0;
+fprintf(stderr,"lime_protocol: setFrequency: %lld\n",f);
+    //rc=SoapySDRDevice_setFrequencyComponent(lime_device,SOAPY_SDR_RX,receiver,"RF",(double)f,&args);
+    rc=SoapySDRDevice_setFrequency(lime_device,SOAPY_SDR_RX,receiver,(double)f,&args);
+    if(rc!=0) {
+      fprintf(stderr,"lime_protocol: SoapySDRDevice_setFrequency() failed: %s\n",SoapySDRDevice_lastError());
+    }
+  } else {
+fprintf(stderr,"lime_protocol: setFrequency: %lld device is NULL\n",f);
+    saved_frequency=f;
+  }
+}
+
+void lime_protocol_set_antenna(int ant) {
+  int rc;
+ // char *antstr;
+  if(lime_device!=NULL) {
+/*
+    antstr=SoapySDRDevice_getAntenna(lime_device,SOAPY_SDR_RX,receiver);
+    fprintf(stderr,"lime_protocol: set_antenna: current antenna=%s\n",antstr);
+*/
+    switch(ant) {
+      case 0:
+fprintf(stderr,"lime_protocol: setAntenna: NONE\n");
+        rc=SoapySDRDevice_setAntenna(lime_device,SOAPY_SDR_RX,receiver,"NONE");
+        if(rc!=0) {
+          fprintf(stderr,"lime_protocol: SoapySDRDevice_setAntenna NONE failed: %s\n",SoapySDRDevice_lastError());
+        }
+        break;
+      case 1:
+fprintf(stderr,"lime_protocol: setAntenna: LNAH\n");
+        rc=SoapySDRDevice_setAntenna(lime_device,SOAPY_SDR_RX,receiver,"LNAH");
+        if(rc!=0) {
+          fprintf(stderr,"lime_protocol: SoapySDRDevice_setAntenna LNAH failed: %s\n",SoapySDRDevice_lastError());
+        }
+        break;
+      case 2:
+fprintf(stderr,"lime_protocol: setAntenna: LNAL\n");
+        rc=SoapySDRDevice_setAntenna(lime_device,SOAPY_SDR_RX,receiver,"LNAL");
+        if(rc!=0) {
+          fprintf(stderr,"lime_protocol: SoapySDRDevice_setAntenna LNAL failed: %s\n",SoapySDRDevice_lastError());
+        }
+        break;
+      case 3:
+fprintf(stderr,"lime_protocol: setAntenna: LNAW\n");
+        rc=SoapySDRDevice_setAntenna(lime_device,SOAPY_SDR_RX,receiver,"LNAW");
+        if(rc!=0) {
+          fprintf(stderr,"lime_protocol: SoapySDRDevice_setAntenna LNAW failed: %s\n",SoapySDRDevice_lastError());
+        }
+        break;
+    }
+/*
+    antstr=SoapySDRDevice_getAntenna(lime_device,SOAPY_SDR_RX,receiver);
+    fprintf(stderr,"lime_protocol: set_antenna: antenna=%s\n",antstr);
+*/
+  } else {
+    fprintf(stderr,"lime_protocol: setAntenna: device is NULL\n");
+    saved_antenna=ant;
+  }
+}
+
+void lime_protocol_set_attenuation(int attenuation) {
+  int rc;
+  fprintf(stderr,"setting Gain LNA=%f\n",30.0-(double)attenuation);
+  rc=SoapySDRDevice_setGainElement(lime_device,SOAPY_SDR_RX,receiver,"LNA",30.0-(double)attenuation);
+  if(rc!=0) {
+    fprintf(stderr,"lime_protocol: SoapySDRDevice_setGain LNA failed: %s\n",SoapySDRDevice_lastError());
+  }
+}
diff --git a/lime_protocol.h b/lime_protocol.h
new file mode 100644 (file)
index 0000000..aa349d3
--- /dev/null
@@ -0,0 +1,7 @@
+#define BUFFER_SIZE 1024
+
+void lime_protocol_init(int rx,int pixels);
+void lime_protocol_stop();
+void lime_protocol_set_frequency(long long f);
+void lime_protocol_set_antenna(int ant);
+void lime_protocol_set_attenuation(int attenuation);
diff --git a/main.c b/main.c
index b7e64ebef8e564eb991849edfbe97b5919f4a630..f0e109a409d121069dfb1a71483547ff7d2265af 100644 (file)
--- a/main.c
+++ b/main.c
 #include "gpio.h"
 #include "old_discovery.h"
 #include "new_discovery.h"
+#ifdef LIMESDR
 #include "lime_discovery.h"
+#endif
+#include "old_protocol.h"
 #include "new_protocol.h"
+#ifdef LIMESDR
+#include "lime_protocol.h"
+#endif
 #include "wdsp.h"
 #include "vfo.h"
 #include "menu.h"
@@ -47,6 +53,9 @@
 #include "radio.h"
 #include "wdsp_init.h"
 #include "version.h"
+#ifdef FREEDV
+#include "mode.h"
+#endif
 
 #ifdef raspberrypi
 #define INCLUDE_GPIO
@@ -92,8 +101,11 @@ gint update(gpointer data) {
     double fwd;
     double rev;
     double exciter;
-
-    GetPixels(isTransmitting()==0?CHANNEL_RX0:CHANNEL_TX,0,samples,&result);
+    int channel=CHANNEL_RX0;
+    if(isTransmitting()) {
+      channel=CHANNEL_TX;
+    }
+    GetPixels(channel,0,samples,&result);
     if(result==1) {
         if(display_panadapter) {
           panadapter_update(samples,isTransmitting());
@@ -534,13 +546,23 @@ static void configure_gpio() {
 static void configure_cb(GtkWidget *widget, gpointer data) {
   DISCOVERED* d;
   d=&discovered[(int)data];
-  sprintf(property_path,"%02X-%02X-%02X-%02X-%02X-%02X.props",
-                        d->mac_address[0],
-                        d->mac_address[1],
-                        d->mac_address[2],
-                        d->mac_address[3],
-                        d->mac_address[4],
-                        d->mac_address[5]);
+  switch(d->protocol) {
+    case ORIGINAL_PROTOCOL:
+    case NEW_PROTOCOL:
+      sprintf(property_path,"%02X-%02X-%02X-%02X-%02X-%02X.props",
+                        d->info.network.mac_address[0],
+                        d->info.network.mac_address[1],
+                        d->info.network.mac_address[2],
+                        d->info.network.mac_address[3],
+                        d->info.network.mac_address[4],
+                        d->info.network.mac_address[5]);
+      break;
+#ifdef LIMESDR
+    case LIMESDR_PROTOCOL:
+      sprintf(property_path,"limesdr.props");
+      break;
+#endif
+  }
   radioRestoreState();
   
   GtkWidget *dialog=gtk_dialog_new_with_buttons("Configure",GTK_WINDOW(splash_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
@@ -582,7 +604,7 @@ static void configure_cb(GtkWidget *widget, gpointer data) {
   gtk_grid_attach(GTK_GRID(grid),sample_rate_384,0,4,1,1);
   g_signal_connect(sample_rate_384,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)384000);
 
-  if(d->protocol==NEW_PROTOCOL) {
+  if(d->protocol==NEW_PROTOCOL || d->protocol==LIMESDR_PROTOCOL) {
     GtkWidget *sample_rate_768=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_384),"768000");
     //gtk_widget_override_font(sample_rate_768, pango_font_description_from_string("Arial 18"));
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_768), sample_rate==768000);
@@ -590,53 +612,78 @@ static void configure_cb(GtkWidget *widget, gpointer data) {
     gtk_grid_attach(GTK_GRID(grid),sample_rate_768,0,5,1,1);
     g_signal_connect(sample_rate_768,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)768000);
 
-    GtkWidget *sample_rate_1536=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_768),"1536000");
+    GtkWidget *sample_rate_921=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_768),"921180");
+    //gtk_widget_override_font(sample_rate_921, pango_font_description_from_string("Arial 18"));
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_921), sample_rate==921180);
+    gtk_widget_show(sample_rate_921);
+    gtk_grid_attach(GTK_GRID(grid),sample_rate_921,0,6,1,1);
+    g_signal_connect(sample_rate_921,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)921180);
+
+    GtkWidget *sample_rate_1536=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_921),"1536000");
     //gtk_widget_override_font(sample_rate_1536, pango_font_description_from_string("Arial 18"));
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_1536), sample_rate==1536000);
     gtk_widget_show(sample_rate_1536);
-    gtk_grid_attach(GTK_GRID(grid),sample_rate_1536,0,6,1,1);
+    gtk_grid_attach(GTK_GRID(grid),sample_rate_1536,0,7,1,1);
     g_signal_connect(sample_rate_1536,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)1536000);
+
+#ifdef LIMESDR
+    if(d->protocol==LIMESDR_PROTOCOL) {
+      GtkWidget *sample_rate_1M=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_1536),"1048576");
+      //gtk_widget_override_font(sample_rate_1M, pango_font_description_from_string("Arial 18"));
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_1M), sample_rate==1048576);
+      gtk_widget_show(sample_rate_1M);
+      gtk_grid_attach(GTK_GRID(grid),sample_rate_1M,0,8,1,1);
+      g_signal_connect(sample_rate_1M,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)1048576);
+  
+      GtkWidget *sample_rate_2M=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_1M),"2097152");
+      //gtk_widget_override_font(sample_rate_2M, pango_font_description_from_string("Arial 18"));
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_2M), sample_rate==2097152);
+      gtk_widget_show(sample_rate_2M);
+      gtk_grid_attach(GTK_GRID(grid),sample_rate_2M,0,9,1,1);
+      g_signal_connect(sample_rate_2M,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)2097152);
+    }
+#endif
   }
 
 
   GtkWidget *display_label=gtk_label_new("Display:");
   //gtk_widget_override_font(display_label, pango_font_description_from_string("Arial 18"));
   gtk_widget_show(display_label);
-  gtk_grid_attach(GTK_GRID(grid),display_label,0,7,1,1);
+  gtk_grid_attach(GTK_GRID(grid),display_label,0,9,1,1);
 
   GtkWidget *b_display_panadapter=gtk_check_button_new_with_label("Display Panadapter");
   //gtk_widget_override_font(b_display_panadapter, pango_font_description_from_string("Arial 18"));
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_display_panadapter), display_panadapter);
   gtk_widget_show(b_display_panadapter);
-  gtk_grid_attach(GTK_GRID(grid),b_display_panadapter,0,8,1,1);
+  gtk_grid_attach(GTK_GRID(grid),b_display_panadapter,0,10,1,1);
   g_signal_connect(b_display_panadapter,"toggled",G_CALLBACK(display_panadapter_cb),(gpointer *)NULL);
 
   GtkWidget *b_display_waterfall=gtk_check_button_new_with_label("Display Waterfall");
   //gtk_widget_override_font(b_display_waterfall, pango_font_description_from_string("Arial 18"));
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_display_waterfall), display_waterfall);
   gtk_widget_show(b_display_waterfall);
-  gtk_grid_attach(GTK_GRID(grid),b_display_waterfall,0,9,1,1);
+  gtk_grid_attach(GTK_GRID(grid),b_display_waterfall,0,11,1,1);
   g_signal_connect(b_display_waterfall,"toggled",G_CALLBACK(display_waterfall_cb),(gpointer *)NULL);
 
   GtkWidget *b_display_sliders=gtk_check_button_new_with_label("Display Sliders");
   //gtk_widget_override_font(b_display_sliders, pango_font_description_from_string("Arial 18"));
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_display_sliders), display_sliders);
   gtk_widget_show(b_display_sliders);
-  gtk_grid_attach(GTK_GRID(grid),b_display_sliders,0,10,1,1);
+  gtk_grid_attach(GTK_GRID(grid),b_display_sliders,0,12,1,1);
   g_signal_connect(b_display_sliders,"toggled",G_CALLBACK(display_sliders_cb),(gpointer *)NULL);
 
   GtkWidget *b_display_toolbar=gtk_check_button_new_with_label("Display Toolbar");
   //gtk_widget_override_font(b_display_toolbar, pango_font_description_from_string("Arial 18"));
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_display_toolbar), display_toolbar);
   gtk_widget_show(b_display_toolbar);
-  gtk_grid_attach(GTK_GRID(grid),b_display_toolbar,0,11,1,1);
+  gtk_grid_attach(GTK_GRID(grid),b_display_toolbar,0,13,1,1);
   g_signal_connect(b_display_toolbar,"toggled",G_CALLBACK(display_toolbar_cb),(gpointer *)NULL);
 
   GtkWidget *b_toolbar_simulate_buttons=gtk_check_button_new_with_label("Toolbar Simulate Buttons");
   //gtk_widget_override_font(b_toolbar_simulate_buttons, pango_font_description_from_string("Arial 18"));
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_toolbar_simulate_buttons), toolbar_simulate_buttons);
   gtk_widget_show(b_toolbar_simulate_buttons);
-  gtk_grid_attach(GTK_GRID(grid),b_toolbar_simulate_buttons,0,12,1,1);
+  gtk_grid_attach(GTK_GRID(grid),b_toolbar_simulate_buttons,0,14,1,1);
   g_signal_connect(b_toolbar_simulate_buttons,"toggled",G_CALLBACK(toolbar_simulate_buttons_cb),(gpointer *)NULL);
   gtk_container_add(GTK_CONTAINER(content),grid);
 
@@ -667,10 +714,18 @@ gboolean main_delete (GtkWidget *widget) {
 #ifdef INCLUDE_GPIO
   gpio_close();
 #endif
-  if(protocol==ORIGINAL_PROTOCOL) {
-    old_protocol_stop();
-  } else {
-    new_protocol_stop();
+  switch(protocol) {
+    case ORIGINAL_PROTOCOL:
+      old_protocol_stop();
+      break;
+    case NEW_PROTOCOL:
+      new_protocol_stop();
+      break;
+#ifdef LIMESDR
+    case LIMESDR_PROTOCOL:
+      lime_protocol_stop();
+      break;
+#endif
   }
   radioSaveState();
   _exit(0);
@@ -782,21 +837,41 @@ gint init(void* arg) {
           char text[128];
           for(i=0;i<devices;i++) {
               d=&discovered[i];
-              sprintf(text,"%s (%s %d.%d) %s (%02X:%02X:%02X:%02X:%02X:%02X) on %s\n",
+fprintf(stderr,"protocol=%d name=%s\n",d->protocol,d->name);
+              switch(d->protocol) {
+                case ORIGINAL_PROTOCOL:
+                case NEW_PROTOCOL:
+                  sprintf(text,"%s (%s %d.%d) %s (%02X:%02X:%02X:%02X:%02X:%02X) on %s\n",
                         d->name,
                         d->protocol==ORIGINAL_PROTOCOL?"old":"new",
                         //d->protocol==ORIGINAL_PROTOCOL?d->software_version/10:d->software_version/100,
                         //d->protocol==ORIGINAL_PROTOCOL?d->software_version%10:d->software_version%100,
                         d->software_version/10,
                         d->software_version%10,
-                        inet_ntoa(d->address.sin_addr),
-                        d->mac_address[0],
-                        d->mac_address[1],
-                        d->mac_address[2],
-                        d->mac_address[3],
-                        d->mac_address[4],
-                        d->mac_address[5],
-                        d->interface_name);
+                        inet_ntoa(d->info.network.address.sin_addr),
+                        d->info.network.mac_address[0],
+                        d->info.network.mac_address[1],
+                        d->info.network.mac_address[2],
+                        d->info.network.mac_address[3],
+                        d->info.network.mac_address[4],
+                        d->info.network.mac_address[5],
+                        d->info.network.interface_name);
+                  break;
+#ifdef LIMESDR
+                case LIMESDR_PROTOCOL:
+/*
+                  sprintf(text,"%s (%s %d.%d.%d)\n",
+                        d->name,
+                        "lime",
+                        d->software_version/100,
+                        (d->software_version%100)/10,
+                        d->software_version%10);
+*/
+                  sprintf(text,"%s\n",
+                        d->name);
+                  break;
+#endif
+              }
 
               GtkWidget *label=gtk_label_new(text);
               gtk_widget_override_font(label, pango_font_description_from_string("Arial 12"));
@@ -816,7 +891,7 @@ gint init(void* arg) {
               }
 
               // if not on the same subnet then cannot start it
-              if((d->interface_address.sin_addr.s_addr&d->interface_netmask.sin_addr.s_addr) != (d->address.sin_addr.s_addr&d->interface_netmask.sin_addr.s_addr)) {
+              if((d->info.network.interface_address.sin_addr.s_addr&d->info.network.interface_netmask.sin_addr.s_addr) != (d->info.network.address.sin_addr.s_addr&d->info.network.interface_netmask.sin_addr.s_addr)) {
                 gtk_button_set_label(GTK_BUTTON(start_button),"Subnet!");
                 gtk_widget_set_sensitive(start_button, FALSE);
               }
@@ -853,13 +928,23 @@ gint init(void* arg) {
   protocol=d->protocol;
   device=d->device;
 
-  sprintf(property_path,"%02X-%02X-%02X-%02X-%02X-%02X.props",
-                        d->mac_address[0],
-                        d->mac_address[1],
-                        d->mac_address[2],
-                        d->mac_address[3],
-                        d->mac_address[4],
-                        d->mac_address[5]);
+  switch(d->protocol) {
+    case ORIGINAL_PROTOCOL:
+    case NEW_PROTOCOL:
+      sprintf(property_path,"%02X-%02X-%02X-%02X-%02X-%02X.props",
+                        d->info.network.mac_address[0],
+                        d->info.network.mac_address[1],
+                        d->info.network.mac_address[2],
+                        d->info.network.mac_address[3],
+                        d->info.network.mac_address[4],
+                        d->info.network.mac_address[5]);
+      break;
+#ifdef LIMESDR
+    case LIMESDR_PROTOCOL:
+      sprintf(property_path,"limesdr.props");
+      break;
+#endif
+  }
 
   radioRestoreState();
 
@@ -868,12 +953,21 @@ gint init(void* arg) {
   //splash_status("Initializing wdsp ...");
   wdsp_init(0,display_width,d->protocol);
 
-  if(d->protocol==ORIGINAL_PROTOCOL) {
+  switch(d->protocol) {
+    case ORIGINAL_PROTOCOL:
       splash_status("Initializing old protocol ...");
       old_protocol_init(0,display_width);
-  } else {
+      break;
+    case NEW_PROTOCOL:
       splash_status("Initializing new protocol ...");
       new_protocol_init(0,display_width);
+      break;
+#ifdef LIMESDR
+    case LIMESDR_PROTOCOL:
+      splash_status("Initializing lime protocol ...");
+      lime_protocol_init(0,display_width);
+      break;
+#endif
   }
 
   splash_status("Initializing GPIO ...");
@@ -1012,12 +1106,13 @@ fprintf(stderr,"toolbar_height=%d\n",TOOLBAR_HEIGHT);
   // save every 30 seconds
   save_timer_id=gdk_threads_add_timeout(30000, save_cb, NULL);
 
-  vfo_update(NULL);
 
-  if(protocol==ORIGINAL_PROTOCOL) {
+  if(protocol!=NEW_PROTOCOL) {
     setFrequency(getFrequency());
   }
 
+  g_idle_add(vfo_update,(gpointer)NULL);
+
   return 0;
 }
 
@@ -1047,6 +1142,7 @@ main (int   argc,
   display_width=gdk_screen_get_width(screen);
   display_height=gdk_screen_get_height(screen);
 
+fprintf(stderr,"width=%d height=%d\n", display_width, display_height);
   if(display_width>800 || display_height>480) {
     display_width=800;
     display_height=480;
diff --git a/menu.c b/menu.c
index b43810e093860f31070d48b201d87b2017bd71d8..b72b96006fe73761d83165f8dafc4e43a054a2b0 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -27,6 +27,7 @@
 #include <gtk/gtk.h>
 #include <semaphore.h>
 #include <stdio.h>
+#include <string.h>
 
 #include "band.h"
 #include "channel.h"
@@ -35,6 +36,9 @@
 #include "radio.h"
 #include "version.h"
 #include "wdsp.h"
+#ifdef FREEDV
+#include "freedv.h"
+#endif
 
 static GtkWidget *parent_window;
 
@@ -214,10 +218,18 @@ static gboolean exit_pressed_event_cb (GtkWidget *widget,
 #ifdef INCLUDE_GPIO
   gpio_close();
 #endif
-  if(protocol==ORIGINAL_PROTOCOL) {
-    old_protocol_stop();
-  } else {
-    new_protocol_stop();
+  switch(protocol) {
+    case ORIGINAL_PROTOCOL:
+      old_protocol_stop();
+      break;
+    case NEW_PROTOCOL:
+      new_protocol_stop();
+      break;
+#ifdef LIMESDR
+    case LIMESDR_PROTOCOL:
+      lime_protocol_stop();
+      break;
+#endif
   }
   radioSaveState();
   _exit(0);
@@ -230,10 +242,18 @@ static gboolean reboot_pressed_event_cb (GtkWidget *widget,
 #ifdef INCLUDE_GPIO
   gpio_close();
 #endif
-  if(protocol==ORIGINAL_PROTOCOL) {
-    old_protocol_stop();
-  } else {
-    new_protocol_stop();
+  switch(protocol) {
+    case ORIGINAL_PROTOCOL:
+      old_protocol_stop();
+      break;
+    case NEW_PROTOCOL:
+      new_protocol_stop();
+      break;
+#ifdef LIMESDR
+    case LIMESDR_PROTOCOL:
+      lime_protocol_stop();
+      break;
+#endif
   }
   radioSaveState();
   system("reboot");
@@ -247,10 +267,18 @@ static gboolean shutdown_pressed_event_cb (GtkWidget *widget,
 #ifdef INCLUDE_GPIO
   gpio_close();
 #endif
-  if(protocol==ORIGINAL_PROTOCOL) {
-    old_protocol_stop();
-  } else {
-    new_protocol_stop();
+  switch(protocol) {
+    case ORIGINAL_PROTOCOL:
+      old_protocol_stop();
+      break;
+    case NEW_PROTOCOL:
+      new_protocol_stop();
+      break;
+#ifdef LIMESDR
+    case LIMESDR_PROTOCOL:
+      lime_protocol_stop();
+      break;
+#endif
   }
   radioSaveState();
   system("shutdown -h -P now");
@@ -358,6 +386,13 @@ static void rx_ant_cb(GtkWidget *widget, gpointer data) {
   set_alex_rx_antenna(ant);
 }
 
+static void rx_lime_ant_cb(GtkWidget *widget, gpointer data) {
+  int ant=((int)data)&0xF;
+  BAND *band=band_get_current_band();
+  band->alexRxAntenna=ant;
+  set_alex_rx_antenna(ant);
+}
+
 static void tx_ant_cb(GtkWidget *widget, gpointer data) {
   int b=((int)data)>>4;
   int ant=((int)data)&0xF;
@@ -366,6 +401,10 @@ static void tx_ant_cb(GtkWidget *widget, gpointer data) {
   set_alex_tx_antenna(ant);
 }
 
+static void freedv_text_changed_cb(GtkWidget *widget, gpointer data) {
+  strcpy(freedv_tx_text_data,gtk_entry_get_text(GTK_ENTRY(widget)));
+}
+
 static void switch_page_cb(GtkNotebook *notebook,
                GtkWidget   *page,
                guint        page_num,
@@ -373,19 +412,21 @@ static void switch_page_cb(GtkNotebook *notebook,
 {
   int i, j;
   GtkWidget *child;
-  if(page_num==ant_id) {
-    if(filter_board==ALEX) {
-      for(i=0;i<HAM_BANDS;i++) {
-        for(j=0;j<11;j++) {
-          child=gtk_grid_get_child_at(GTK_GRID(ant_grid),j,i+1);
-          gtk_widget_set_sensitive(child,TRUE);
+  if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL) {
+    if(page_num==ant_id) {
+      if(filter_board==ALEX) {
+        for(i=0;i<HAM_BANDS;i++) {
+          for(j=0;j<11;j++) {
+            child=gtk_grid_get_child_at(GTK_GRID(ant_grid),j,i+1);
+            gtk_widget_set_sensitive(child,TRUE);
+          }
         }
-      }
-    } else {
-      for(i=0;i<HAM_BANDS;i++) {
-        for(j=0;j<11;j++) {
-          child=gtk_grid_get_child_at(GTK_GRID(ant_grid),j,i+1);
-          gtk_widget_set_sensitive(child,FALSE);
+      } else {
+        for(i=0;i<HAM_BANDS;i++) {
+          for(j=0;j<11;j++) {
+            child=gtk_grid_get_child_at(GTK_GRID(ant_grid),j,i+1);
+            gtk_widget_set_sensitive(child,FALSE);
+          }
         }
       }
     }
@@ -426,106 +467,109 @@ static gboolean menu_pressed_event_cb (GtkWidget *widget,
   g_signal_connect(vfo_divisor,"value_changed",G_CALLBACK(vfo_divisor_value_changed_cb),NULL);
 
 
-  GtkWidget *rx_dither_b=gtk_check_button_new_with_label("Dither");
-  //gtk_widget_override_font(rx_dither_b, pango_font_description_from_string("Arial 18"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx_dither_b), rx_dither);
-  gtk_widget_show(rx_dither_b);
-  gtk_grid_attach(GTK_GRID(general_grid),rx_dither_b,0,1,1,1);
-  g_signal_connect(rx_dither_b,"toggled",G_CALLBACK(rx_dither_cb),NULL);
+  if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL) {
+    GtkWidget *rx_dither_b=gtk_check_button_new_with_label("Dither");
+    //gtk_widget_override_font(rx_dither_b, pango_font_description_from_string("Arial 18"));
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx_dither_b), rx_dither);
+    gtk_widget_show(rx_dither_b);
+    gtk_grid_attach(GTK_GRID(general_grid),rx_dither_b,0,1,1,1);
+    g_signal_connect(rx_dither_b,"toggled",G_CALLBACK(rx_dither_cb),NULL);
 
-  GtkWidget *rx_random_b=gtk_check_button_new_with_label("Random");
-  //gtk_widget_override_font(rx_random_b, pango_font_description_from_string("Arial 18"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx_random_b), rx_random);
-  gtk_widget_show(rx_random_b);
-  gtk_grid_attach(GTK_GRID(general_grid),rx_random_b,0,2,1,1);
-  g_signal_connect(rx_random_b,"toggled",G_CALLBACK(rx_random_cb),NULL);
+    GtkWidget *rx_random_b=gtk_check_button_new_with_label("Random");
+    //gtk_widget_override_font(rx_random_b, pango_font_description_from_string("Arial 18"));
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx_random_b), rx_random);
+    gtk_widget_show(rx_random_b);
+    gtk_grid_attach(GTK_GRID(general_grid),rx_random_b,0,2,1,1);
+    g_signal_connect(rx_random_b,"toggled",G_CALLBACK(rx_random_cb),NULL);
 
 /*
-  GtkWidget *rx_preamp_b=gtk_check_button_new_with_label("Preamp");
-  //gtk_widget_override_font(rx_preamp_b, pango_font_description_from_string("Arial 18"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx_preamp_b), rx_preamp);
-  gtk_widget_show(rx_preamp_b);
-  gtk_grid_attach(GTK_GRID(general_grid),rx_preamp_b,0,3,1,1);
-  g_signal_connect(rx_preamp_b,"toggled",G_CALLBACK(rx_preamp_cb),NULL);
+    GtkWidget *rx_preamp_b=gtk_check_button_new_with_label("Preamp");
+    //gtk_widget_override_font(rx_preamp_b, pango_font_description_from_string("Arial 18"));
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx_preamp_b), rx_preamp);
+    gtk_widget_show(rx_preamp_b);
+    gtk_grid_attach(GTK_GRID(general_grid),rx_preamp_b,0,3,1,1);
+    g_signal_connect(rx_preamp_b,"toggled",G_CALLBACK(rx_preamp_cb),NULL);
 */
 
-  GtkWidget *linein_b=gtk_check_button_new_with_label("Mic Line In");
-  //gtk_widget_override_font(linein_b, pango_font_description_from_string("Arial 18"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linein_b), mic_linein);
-  gtk_widget_show(linein_b);
-  gtk_grid_attach(GTK_GRID(general_grid),linein_b,1,1,1,1);
-  g_signal_connect(linein_b,"toggled",G_CALLBACK(linein_cb),NULL);
-
-  GtkWidget *micboost_b=gtk_check_button_new_with_label("Mic Boost");
-  //gtk_widget_override_font(micboost_b, pango_font_description_from_string("Arial 18"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (micboost_b), mic_boost);
-  gtk_widget_show(micboost_b);
-  gtk_grid_attach(GTK_GRID(general_grid),micboost_b,1,2,1,1);
-  g_signal_connect(micboost_b,"toggled",G_CALLBACK(micboost_cb),NULL);
-
-
-  if((protocol==NEW_PROTOCOL && device==NEW_DEVICE_ORION) ||
-     (protocol==NEW_PROTOCOL && device==NEW_DEVICE_ORION2) ||
-     (protocol==ORIGINAL_PROTOCOL && device==DEVICE_ORION)) {
-
-    GtkWidget *ptt_ring_b=gtk_radio_button_new_with_label(NULL,"PTT On Ring, Mic and Bias on Tip");
-    //gtk_widget_override_font(ptt_ring_b, pango_font_description_from_string("Arial 18"));
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_ring_b), mic_ptt_tip_bias_ring==0);
-    gtk_widget_show(ptt_ring_b);
-    gtk_grid_attach(GTK_GRID(general_grid),ptt_ring_b,1,3,1,1);
-    g_signal_connect(ptt_ring_b,"pressed",G_CALLBACK(ptt_ring_cb),NULL);
-
-    GtkWidget *ptt_tip_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(ptt_ring_b),"PTT On Tip, Mic and Bias on Ring");
-    //gtk_widget_override_font(ptt_tip_b, pango_font_description_from_string("Arial 18"));
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_tip_b), mic_ptt_tip_bias_ring==1);
-    gtk_widget_show(ptt_tip_b);
-    gtk_grid_attach(GTK_GRID(general_grid),ptt_tip_b,1,4,1,1);
-    g_signal_connect(ptt_tip_b,"pressed",G_CALLBACK(ptt_tip_cb),NULL);
-
-    GtkWidget *ptt_b=gtk_check_button_new_with_label("PTT Enabled");
-    //gtk_widget_override_font(ptt_b, pango_font_description_from_string("Arial 18"));
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_b), mic_ptt_enabled);
-    gtk_widget_show(ptt_b);
-    gtk_grid_attach(GTK_GRID(general_grid),ptt_b,1,5,1,1);
-    g_signal_connect(ptt_b,"toggled",G_CALLBACK(ptt_cb),NULL);
-
-    GtkWidget *bias_b=gtk_check_button_new_with_label("BIAS Enabled");
-    //gtk_widget_override_font(bias_b, pango_font_description_from_string("Arial 18"));
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bias_b), mic_bias_enabled);
-    gtk_widget_show(bias_b);
-    gtk_grid_attach(GTK_GRID(general_grid),bias_b,1,6,1,1);
-    g_signal_connect(bias_b,"toggled",G_CALLBACK(bias_cb),NULL);
-  }
-
-
-  GtkWidget *alex_b=gtk_check_button_new_with_label("ALEX");
-  //gtk_widget_override_font(alex_b, pango_font_description_from_string("Arial 18"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (alex_b), filter_board==ALEX);
-  gtk_widget_show(alex_b);
-  gtk_grid_attach(GTK_GRID(general_grid),alex_b,2,1,1,1);
-
-  GtkWidget *apollo_b=gtk_check_button_new_with_label("APOLLO");
-  //gtk_widget_override_font(apollo_b, pango_font_description_from_string("Arial 18"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (apollo_b), filter_board==APOLLO);
-  gtk_widget_show(apollo_b);
-  gtk_grid_attach(GTK_GRID(general_grid),apollo_b,2,2,1,1);
+    GtkWidget *linein_b=gtk_check_button_new_with_label("Mic Line In");
+    //gtk_widget_override_font(linein_b, pango_font_description_from_string("Arial 18"));
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linein_b), mic_linein);
+    gtk_widget_show(linein_b);
+    gtk_grid_attach(GTK_GRID(general_grid),linein_b,1,1,1,1);
+    g_signal_connect(linein_b,"toggled",G_CALLBACK(linein_cb),NULL);
+
+    GtkWidget *micboost_b=gtk_check_button_new_with_label("Mic Boost");
+    //gtk_widget_override_font(micboost_b, pango_font_description_from_string("Arial 18"));
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (micboost_b), mic_boost);
+    gtk_widget_show(micboost_b);
+    gtk_grid_attach(GTK_GRID(general_grid),micboost_b,1,2,1,1);
+    g_signal_connect(micboost_b,"toggled",G_CALLBACK(micboost_cb),NULL);
+
+
+    if((protocol==NEW_PROTOCOL && device==NEW_DEVICE_ORION) ||
+       (protocol==NEW_PROTOCOL && device==NEW_DEVICE_ORION2) ||
+       (protocol==ORIGINAL_PROTOCOL && device==DEVICE_ORION)) {
+
+      GtkWidget *ptt_ring_b=gtk_radio_button_new_with_label(NULL,"PTT On Ring, Mic and Bias on Tip");
+      //gtk_widget_override_font(ptt_ring_b, pango_font_description_from_string("Arial 18"));
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_ring_b), mic_ptt_tip_bias_ring==0);
+      gtk_widget_show(ptt_ring_b);
+      gtk_grid_attach(GTK_GRID(general_grid),ptt_ring_b,1,3,1,1);
+      g_signal_connect(ptt_ring_b,"pressed",G_CALLBACK(ptt_ring_cb),NULL);
+
+      GtkWidget *ptt_tip_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(ptt_ring_b),"PTT On Tip, Mic and Bias on Ring");
+      //gtk_widget_override_font(ptt_tip_b, pango_font_description_from_string("Arial 18"));
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_tip_b), mic_ptt_tip_bias_ring==1);
+      gtk_widget_show(ptt_tip_b);
+      gtk_grid_attach(GTK_GRID(general_grid),ptt_tip_b,1,4,1,1);
+      g_signal_connect(ptt_tip_b,"pressed",G_CALLBACK(ptt_tip_cb),NULL);
+
+      GtkWidget *ptt_b=gtk_check_button_new_with_label("PTT Enabled");
+      //gtk_widget_override_font(ptt_b, pango_font_description_from_string("Arial 18"));
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_b), mic_ptt_enabled);
+      gtk_widget_show(ptt_b);
+      gtk_grid_attach(GTK_GRID(general_grid),ptt_b,1,5,1,1);
+      g_signal_connect(ptt_b,"toggled",G_CALLBACK(ptt_cb),NULL);
+
+      GtkWidget *bias_b=gtk_check_button_new_with_label("BIAS Enabled");
+      //gtk_widget_override_font(bias_b, pango_font_description_from_string("Arial 18"));
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bias_b), mic_bias_enabled);
+      gtk_widget_show(bias_b);
+      gtk_grid_attach(GTK_GRID(general_grid),bias_b,1,6,1,1);
+      g_signal_connect(bias_b,"toggled",G_CALLBACK(bias_cb),NULL);
+    }
 
-  g_signal_connect(alex_b,"toggled",G_CALLBACK(alex_cb),apollo_b);
-  g_signal_connect(apollo_b,"toggled",G_CALLBACK(apollo_cb),alex_b);
 
-  GtkWidget *apollo_tuner_b=gtk_check_button_new_with_label("Auto Tuner");
-  //gtk_widget_override_font(apollo_tuner_b, pango_font_description_from_string("Arial 18"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (apollo_tuner_b), apollo_tuner);
-  gtk_widget_show(apollo_tuner_b);
-  gtk_grid_attach(GTK_GRID(general_grid),apollo_tuner_b,2,3,1,1);
-  g_signal_connect(apollo_tuner_b,"toggled",G_CALLBACK(apollo_tuner_cb),NULL);
+    GtkWidget *alex_b=gtk_check_button_new_with_label("ALEX");
+    //gtk_widget_override_font(alex_b, pango_font_description_from_string("Arial 18"));
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (alex_b), filter_board==ALEX);
+    gtk_widget_show(alex_b);
+    gtk_grid_attach(GTK_GRID(general_grid),alex_b,2,1,1,1);
 
-  GtkWidget *pa_b=gtk_check_button_new_with_label("PA");
-  //gtk_widget_override_font(pa_b, pango_font_description_from_string("Arial 18"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pa_b), pa);
-  gtk_widget_show(pa_b);
-  gtk_grid_attach(GTK_GRID(general_grid),pa_b,2,4,1,1);
-  g_signal_connect(pa_b,"toggled",G_CALLBACK(pa_cb),NULL);
+    GtkWidget *apollo_b=gtk_check_button_new_with_label("APOLLO");
+    //gtk_widget_override_font(apollo_b, pango_font_description_from_string("Arial 18"));
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (apollo_b), filter_board==APOLLO);
+    gtk_widget_show(apollo_b);
+    gtk_grid_attach(GTK_GRID(general_grid),apollo_b,2,2,1,1);
+  
+    g_signal_connect(alex_b,"toggled",G_CALLBACK(alex_cb),apollo_b);
+    g_signal_connect(apollo_b,"toggled",G_CALLBACK(apollo_cb),alex_b);
+  
+    GtkWidget *apollo_tuner_b=gtk_check_button_new_with_label("Auto Tuner");
+    //gtk_widget_override_font(apollo_tuner_b, pango_font_description_from_string("Arial 18"));
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (apollo_tuner_b), apollo_tuner);
+    gtk_widget_show(apollo_tuner_b);
+    gtk_grid_attach(GTK_GRID(general_grid),apollo_tuner_b,2,3,1,1);
+    g_signal_connect(apollo_tuner_b,"toggled",G_CALLBACK(apollo_tuner_cb),NULL);
+  
+    GtkWidget *pa_b=gtk_check_button_new_with_label("PA");
+    //gtk_widget_override_font(pa_b, pango_font_description_from_string("Arial 18"));
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pa_b), pa);
+    gtk_widget_show(pa_b);
+    gtk_grid_attach(GTK_GRID(general_grid),pa_b,2,4,1,1);
+    g_signal_connect(pa_b,"toggled",G_CALLBACK(pa_cb),NULL);
+  
+  }
 
   id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),general_grid,general_label);
 
@@ -534,131 +578,163 @@ static gboolean menu_pressed_event_cb (GtkWidget *widget,
   gtk_grid_set_row_homogeneous(GTK_GRID(ant_grid),TRUE);
   gtk_grid_set_column_spacing (GTK_GRID(ant_grid),10);
 
-  GtkWidget *rx_ant_label=gtk_label_new("Receive");
-  //gtk_widget_override_font(rx_ant_label, pango_font_description_from_string("Arial 18"));
-  gtk_widget_show(rx_ant_label);
-  gtk_grid_attach(GTK_GRID(ant_grid),rx_ant_label,0,0,1,1);
-
-  GtkWidget *rx1_label=gtk_label_new("1");
-  //gtk_widget_override_font(rx1_label, pango_font_description_from_string("Arial 18"));
-  gtk_widget_show(rx1_label);
-  gtk_grid_attach(GTK_GRID(ant_grid),rx1_label,1,0,1,1);
-
-  GtkWidget *rx2_label=gtk_label_new("2");
-  //gtk_widget_override_font(rx2_label, pango_font_description_from_string("Arial 18"));
-  gtk_widget_show(rx2_label);
-  gtk_grid_attach(GTK_GRID(ant_grid),rx2_label,2,0,1,1);
-
-  GtkWidget *rx3_label=gtk_label_new("3");
-  //gtk_widget_override_font(rx3_label, pango_font_description_from_string("Arial 18"));
-  gtk_widget_show(rx3_label);
-  gtk_grid_attach(GTK_GRID(ant_grid),rx3_label,3,0,1,1);
-
-  GtkWidget *ext1_label=gtk_label_new("EXT1");
-  //gtk_widget_override_font(ext1_label, pango_font_description_from_string("Arial 18"));
-  gtk_widget_show(ext1_label);
-  gtk_grid_attach(GTK_GRID(ant_grid),ext1_label,4,0,1,1);
-
-  GtkWidget *ext2_label=gtk_label_new("EXT2");
-  //gtk_widget_override_font(ext2_label, pango_font_description_from_string("Arial 18"));
-  gtk_widget_show(ext2_label);
-  gtk_grid_attach(GTK_GRID(ant_grid),ext2_label,5,0,1,1);
-
-  GtkWidget *xvtr_label=gtk_label_new("XVTR");
-  //gtk_widget_override_font(xvtr_label, pango_font_description_from_string("Arial 18"));
-  gtk_widget_show(xvtr_label);
-  gtk_grid_attach(GTK_GRID(ant_grid),xvtr_label,6,0,1,1);
-
-  GtkWidget *tx_ant_label=gtk_label_new("Transmit");
-  //gtk_widget_override_font(tx_ant_label, pango_font_description_from_string("Arial 18"));
-  gtk_widget_show(tx_ant_label);
-  gtk_grid_attach(GTK_GRID(ant_grid),tx_ant_label,7,0,1,1);
-
-  GtkWidget *tx1_label=gtk_label_new("1");
-  //gtk_widget_override_font(tx1_label, pango_font_description_from_string("Arial 18"));
-  gtk_widget_show(tx1_label);
-  gtk_grid_attach(GTK_GRID(ant_grid),tx1_label,8,0,1,1);
-
-  GtkWidget *tx2_label=gtk_label_new("2");
-  //gtk_widget_override_font(tx2_label, pango_font_description_from_string("Arial 18"));
-  gtk_widget_show(tx2_label);
-  gtk_grid_attach(GTK_GRID(ant_grid),tx2_label,9,0,1,1);
-
-  GtkWidget *tx3_label=gtk_label_new("3");
-  //gtk_widget_override_font(tx3_label, pango_font_description_from_string("Arial 18"));
-  gtk_widget_show(tx3_label);
-  gtk_grid_attach(GTK_GRID(ant_grid),tx3_label,10,0,1,1);
+  if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL) {
+    GtkWidget *rx_ant_label=gtk_label_new("Receive");
+    //gtk_widget_override_font(rx_ant_label, pango_font_description_from_string("Arial 18"));
+    gtk_widget_show(rx_ant_label);
+    gtk_grid_attach(GTK_GRID(ant_grid),rx_ant_label,0,0,1,1);
+
+    GtkWidget *rx1_label=gtk_label_new("1");
+    //gtk_widget_override_font(rx1_label, pango_font_description_from_string("Arial 18"));
+    gtk_widget_show(rx1_label);
+    gtk_grid_attach(GTK_GRID(ant_grid),rx1_label,1,0,1,1);
+
+    GtkWidget *rx2_label=gtk_label_new("2");
+    //gtk_widget_override_font(rx2_label, pango_font_description_from_string("Arial 18"));
+    gtk_widget_show(rx2_label);
+    gtk_grid_attach(GTK_GRID(ant_grid),rx2_label,2,0,1,1);
+
+    GtkWidget *rx3_label=gtk_label_new("3");
+    //gtk_widget_override_font(rx3_label, pango_font_description_from_string("Arial 18"));
+    gtk_widget_show(rx3_label);
+    gtk_grid_attach(GTK_GRID(ant_grid),rx3_label,3,0,1,1);
+
+    GtkWidget *ext1_label=gtk_label_new("EXT1");
+    //gtk_widget_override_font(ext1_label, pango_font_description_from_string("Arial 18"));
+    gtk_widget_show(ext1_label);
+    gtk_grid_attach(GTK_GRID(ant_grid),ext1_label,4,0,1,1);
+
+    GtkWidget *ext2_label=gtk_label_new("EXT2");
+    //gtk_widget_override_font(ext2_label, pango_font_description_from_string("Arial 18"));
+    gtk_widget_show(ext2_label);
+    gtk_grid_attach(GTK_GRID(ant_grid),ext2_label,5,0,1,1);
+
+    GtkWidget *xvtr_label=gtk_label_new("XVTR");
+    //gtk_widget_override_font(xvtr_label, pango_font_description_from_string("Arial 18"));
+    gtk_widget_show(xvtr_label);
+    gtk_grid_attach(GTK_GRID(ant_grid),xvtr_label,6,0,1,1);
+
+    GtkWidget *tx_ant_label=gtk_label_new("Transmit");
+    //gtk_widget_override_font(tx_ant_label, pango_font_description_from_string("Arial 18"));
+    gtk_widget_show(tx_ant_label);
+    gtk_grid_attach(GTK_GRID(ant_grid),tx_ant_label,7,0,1,1);
+
+    GtkWidget *tx1_label=gtk_label_new("1");
+    //gtk_widget_override_font(tx1_label, pango_font_description_from_string("Arial 18"));
+    gtk_widget_show(tx1_label);
+    gtk_grid_attach(GTK_GRID(ant_grid),tx1_label,8,0,1,1);
+
+    GtkWidget *tx2_label=gtk_label_new("2");
+    //gtk_widget_override_font(tx2_label, pango_font_description_from_string("Arial 18"));
+    gtk_widget_show(tx2_label);
+    gtk_grid_attach(GTK_GRID(ant_grid),tx2_label,9,0,1,1);
+
+    GtkWidget *tx3_label=gtk_label_new("3");
+    //gtk_widget_override_font(tx3_label, pango_font_description_from_string("Arial 18"));
+    gtk_widget_show(tx3_label);
+    gtk_grid_attach(GTK_GRID(ant_grid),tx3_label,10,0,1,1);
 
 
   
-  for(i=0;i<HAM_BANDS;i++) {
-    BAND *band=band_get_band(i);
-
-    GtkWidget *band_label=gtk_label_new(band->title);
-    //gtk_widget_override_font(band_label, pango_font_description_from_string("Arial 18"));
-    gtk_widget_show(band_label);
-    gtk_grid_attach(GTK_GRID(ant_grid),band_label,0,i+1,1,1);
-
-    GtkWidget *rx1_b=gtk_radio_button_new(NULL);
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx1_b), band->alexRxAntenna==0);
-    gtk_widget_show(rx1_b);
-    gtk_grid_attach(GTK_GRID(ant_grid),rx1_b,1,i+1,1,1);
-    g_signal_connect(rx1_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)((i<<4)+0));
-
-    GtkWidget *rx2_b=gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(rx1_b));
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx2_b), band->alexRxAntenna==1);
-    gtk_widget_show(rx2_b);
-    gtk_grid_attach(GTK_GRID(ant_grid),rx2_b,2,i+1,1,1);
-    g_signal_connect(rx2_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)((i<<4)+1));
-
-    GtkWidget *rx3_b=gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(rx2_b));
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx3_b), band->alexRxAntenna==2);
-    gtk_widget_show(rx3_b);
-    gtk_grid_attach(GTK_GRID(ant_grid),rx3_b,3,i+1,1,1);
-    g_signal_connect(rx3_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)((i<<4)+2));
-
-    GtkWidget *ext1_b=gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(rx3_b));
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ext1_b), band->alexRxAntenna==3);
-    gtk_widget_show(ext1_b);
-    gtk_grid_attach(GTK_GRID(ant_grid),ext1_b,4,i+1,1,1);
-    g_signal_connect(ext1_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)((i<<4)+3));
-
-    GtkWidget *ext2_b=gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(ext1_b));
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ext2_b), band->alexRxAntenna==4);
-    gtk_widget_show(ext2_b);
-    gtk_grid_attach(GTK_GRID(ant_grid),ext2_b,5,i+1,1,1);
-    g_signal_connect(ext2_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)((i<<4)+4));
-
-    GtkWidget *xvtr_b=gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(ext2_b));
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (xvtr_b), band->alexRxAntenna==5);
-    gtk_widget_show(xvtr_b);
-    gtk_grid_attach(GTK_GRID(ant_grid),xvtr_b,6,i+1,1,1);
-    g_signal_connect(xvtr_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)((i<<4)+5));
-
-    GtkWidget *ant_band_label=gtk_label_new(band->title);
-    //gtk_widget_override_font(ant_band_label, pango_font_description_from_string("Arial 18"));
-    gtk_widget_show(ant_band_label);
-    gtk_grid_attach(GTK_GRID(ant_grid),ant_band_label,7,i+1,1,1);
-
-    GtkWidget *tx1_b=gtk_radio_button_new(NULL);
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tx1_b), band->alexTxAntenna==0);
-    gtk_widget_show(tx1_b);
-    gtk_grid_attach(GTK_GRID(ant_grid),tx1_b,8,i+1,1,1);
-    g_signal_connect(tx1_b,"pressed",G_CALLBACK(tx_ant_cb),(gpointer)((i<<4)+0));
-
-    GtkWidget *tx2_b=gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(tx1_b));
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tx2_b), band->alexTxAntenna==1);
-    gtk_widget_show(tx2_b);
-    gtk_grid_attach(GTK_GRID(ant_grid),tx2_b,9,i+1,1,1);
-    g_signal_connect(tx2_b,"pressed",G_CALLBACK(tx_ant_cb),(gpointer)((i<<4)+1));
-
-    GtkWidget *tx3_b=gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(tx2_b));
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tx3_b), band->alexTxAntenna==2);
-    gtk_widget_show(tx3_b);
-    gtk_grid_attach(GTK_GRID(ant_grid),tx3_b,10,i+1,1,1);
-    g_signal_connect(tx3_b,"pressed",G_CALLBACK(tx_ant_cb),(gpointer)((i<<4)+2));
+    for(i=0;i<HAM_BANDS;i++) {
+      BAND *band=band_get_band(i);
+  
+      GtkWidget *band_label=gtk_label_new(band->title);
+      //gtk_widget_override_font(band_label, pango_font_description_from_string("Arial 18"));
+      gtk_widget_show(band_label);
+      gtk_grid_attach(GTK_GRID(ant_grid),band_label,0,i+1,1,1);
+  
+      GtkWidget *rx1_b=gtk_radio_button_new(NULL);
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx1_b), band->alexRxAntenna==0);
+      gtk_widget_show(rx1_b);
+      gtk_grid_attach(GTK_GRID(ant_grid),rx1_b,1,i+1,1,1);
+      g_signal_connect(rx1_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)((i<<4)+0));
+  
+      GtkWidget *rx2_b=gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(rx1_b));
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx2_b), band->alexRxAntenna==1);
+      gtk_widget_show(rx2_b);
+      gtk_grid_attach(GTK_GRID(ant_grid),rx2_b,2,i+1,1,1);
+      g_signal_connect(rx2_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)((i<<4)+1));
+  
+      GtkWidget *rx3_b=gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(rx2_b));
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx3_b), band->alexRxAntenna==2);
+      gtk_widget_show(rx3_b);
+      gtk_grid_attach(GTK_GRID(ant_grid),rx3_b,3,i+1,1,1);
+      g_signal_connect(rx3_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)((i<<4)+2));
+  
+      GtkWidget *ext1_b=gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(rx3_b));
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ext1_b), band->alexRxAntenna==3);
+      gtk_widget_show(ext1_b);
+      gtk_grid_attach(GTK_GRID(ant_grid),ext1_b,4,i+1,1,1);
+      g_signal_connect(ext1_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)((i<<4)+3));
+  
+      GtkWidget *ext2_b=gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(ext1_b));
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ext2_b), band->alexRxAntenna==4);
+      gtk_widget_show(ext2_b);
+      gtk_grid_attach(GTK_GRID(ant_grid),ext2_b,5,i+1,1,1);
+      g_signal_connect(ext2_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)((i<<4)+4));
+  
+      GtkWidget *xvtr_b=gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(ext2_b));
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (xvtr_b), band->alexRxAntenna==5);
+      gtk_widget_show(xvtr_b);
+      gtk_grid_attach(GTK_GRID(ant_grid),xvtr_b,6,i+1,1,1);
+      g_signal_connect(xvtr_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)((i<<4)+5));
+  
+      GtkWidget *ant_band_label=gtk_label_new(band->title);
+      //gtk_widget_override_font(ant_band_label, pango_font_description_from_string("Arial 18"));
+      gtk_widget_show(ant_band_label);
+      gtk_grid_attach(GTK_GRID(ant_grid),ant_band_label,7,i+1,1,1);
+  
+      GtkWidget *tx1_b=gtk_radio_button_new(NULL);
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tx1_b), band->alexTxAntenna==0);
+      gtk_widget_show(tx1_b);
+      gtk_grid_attach(GTK_GRID(ant_grid),tx1_b,8,i+1,1,1);
+      g_signal_connect(tx1_b,"pressed",G_CALLBACK(tx_ant_cb),(gpointer)((i<<4)+0));
+  
+      GtkWidget *tx2_b=gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(tx1_b));
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tx2_b), band->alexTxAntenna==1);
+      gtk_widget_show(tx2_b);
+      gtk_grid_attach(GTK_GRID(ant_grid),tx2_b,9,i+1,1,1);
+      g_signal_connect(tx2_b,"pressed",G_CALLBACK(tx_ant_cb),(gpointer)((i<<4)+1));
+  
+      GtkWidget *tx3_b=gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(tx2_b));
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tx3_b), band->alexTxAntenna==2);
+      gtk_widget_show(tx3_b);
+      gtk_grid_attach(GTK_GRID(ant_grid),tx3_b,10,i+1,1,1);
+      g_signal_connect(tx3_b,"pressed",G_CALLBACK(tx_ant_cb),(gpointer)((i<<4)+2));
+  
+    }
+  }
 
+#ifdef LIMESDR
+  if(protocol==LIMESDR_PROTOCOL) {
+    BAND *band=band_get_current_band();
+
+    GtkWidget *rx1_none=gtk_radio_button_new_with_label(NULL,"RX 1: NONE");
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx1_none), band->alexRxAntenna==0);
+    gtk_widget_show(rx1_none);
+    gtk_grid_attach(GTK_GRID(ant_grid),rx1_none,0,0,1,1);
+    g_signal_connect(rx1_none,"pressed",G_CALLBACK(rx_lime_ant_cb),(gpointer)0);
+
+    GtkWidget *rx1_lnah=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(rx1_none),"RX1: LNAH");
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx1_lnah), band->alexRxAntenna==1);
+    gtk_widget_show(rx1_lnah);
+    gtk_grid_attach(GTK_GRID(ant_grid),rx1_lnah,0,1,1,1);
+    g_signal_connect(rx1_lnah,"pressed",G_CALLBACK(rx_lime_ant_cb),(gpointer)+1);
+
+    GtkWidget *rx1_lnal=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(rx1_lnah),"RX1: LNAL");
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx1_lnal), band->alexRxAntenna==2);
+    gtk_widget_show(rx1_lnal);
+    gtk_grid_attach(GTK_GRID(ant_grid),rx1_lnal,0,2,1,1);
+    g_signal_connect(rx1_lnal,"pressed",G_CALLBACK(rx_lime_ant_cb),(gpointer)2);
+
+    GtkWidget *rx1_lnaw=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(rx1_lnal),"RX1: LNAW");
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx1_lnaw), band->alexRxAntenna==3);
+    gtk_widget_show(rx1_lnaw);
+    gtk_grid_attach(GTK_GRID(ant_grid),rx1_lnaw,0,3,1,1);
+    g_signal_connect(rx1_lnaw,"pressed",G_CALLBACK(rx_lime_ant_cb),(gpointer)3);
   }
+#endif
 
   ant_id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),ant_grid,ant_label);
 
@@ -895,250 +971,274 @@ static gboolean menu_pressed_event_cb (GtkWidget *widget,
 
   id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),dsp_grid,dsp_label);
 
-  GtkWidget *tx_label=gtk_label_new("PA Gain");
-  GtkWidget *tx_grid=gtk_grid_new();
-  gtk_grid_set_row_homogeneous(GTK_GRID(tx_grid),TRUE);
-  gtk_grid_set_column_spacing (GTK_GRID(tx_grid),10);
-
-  for(i=0;i<HAM_BANDS;i++) {
-    BAND *band=band_get_band(i);
-
-    GtkWidget *band_label=gtk_label_new(band->title);
-    //gtk_widget_override_font(band_label, pango_font_description_from_string("Arial 18"));
-    gtk_widget_show(band_label);
-    gtk_grid_attach(GTK_GRID(tx_grid),band_label,(i/6)*2,i%6,1,1);
-
-    GtkWidget *pa_r=gtk_spin_button_new_with_range(0.0,100.0,1.0);
-    //gtk_widget_override_font(pa_r, pango_font_description_from_string("Arial 18"));
-    gtk_spin_button_set_value(GTK_SPIN_BUTTON(pa_r),(double)band->pa_calibration);
-    gtk_widget_show(pa_r);
-    gtk_grid_attach(GTK_GRID(tx_grid),pa_r,((i/6)*2)+1,i%6,1,1);
-    g_signal_connect(pa_r,"value_changed",G_CALLBACK(pa_value_changed_cb),band);
+  if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL) {
+    GtkWidget *tx_label=gtk_label_new("PA Gain");
+    GtkWidget *tx_grid=gtk_grid_new();
+    gtk_grid_set_row_homogeneous(GTK_GRID(tx_grid),TRUE);
+    gtk_grid_set_column_spacing (GTK_GRID(tx_grid),10);
+
+    for(i=0;i<HAM_BANDS;i++) {
+      BAND *band=band_get_band(i);
+
+      GtkWidget *band_label=gtk_label_new(band->title);
+      //gtk_widget_override_font(band_label, pango_font_description_from_string("Arial 18"));
+      gtk_widget_show(band_label);
+      gtk_grid_attach(GTK_GRID(tx_grid),band_label,(i/6)*2,i%6,1,1);
+
+      GtkWidget *pa_r=gtk_spin_button_new_with_range(0.0,100.0,1.0);
+      //gtk_widget_override_font(pa_r, pango_font_description_from_string("Arial 18"));
+      gtk_spin_button_set_value(GTK_SPIN_BUTTON(pa_r),(double)band->pa_calibration);
+      gtk_widget_show(pa_r);
+      gtk_grid_attach(GTK_GRID(tx_grid),pa_r,((i/6)*2)+1,i%6,1,1);
+      g_signal_connect(pa_r,"value_changed",G_CALLBACK(pa_value_changed_cb),band);
+    }
+
+    GtkWidget *tx_out_of_band_b=gtk_check_button_new_with_label("Transmit out of band");
+    //gtk_widget_override_font(tx_out_of_band_b, pango_font_description_from_string("Arial 18"));
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tx_out_of_band_b), tx_out_of_band);
+    gtk_widget_show(tx_out_of_band_b);
+    gtk_grid_attach(GTK_GRID(tx_grid),tx_out_of_band_b,0,7,4,1);
+    g_signal_connect(tx_out_of_band_b,"toggled",G_CALLBACK(tx_out_of_band_cb),NULL);
+
+    id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),tx_grid,tx_label);
   }
 
-  GtkWidget *tx_out_of_band_b=gtk_check_button_new_with_label("Transmit out of band");
-  //gtk_widget_override_font(tx_out_of_band_b, pango_font_description_from_string("Arial 18"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tx_out_of_band_b), tx_out_of_band);
-  gtk_widget_show(tx_out_of_band_b);
-  gtk_grid_attach(GTK_GRID(tx_grid),tx_out_of_band_b,0,7,4,1);
-  g_signal_connect(tx_out_of_band_b,"toggled",G_CALLBACK(tx_out_of_band_cb),NULL);
-
-  id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),tx_grid,tx_label);
-
-  GtkWidget *cw_label=gtk_label_new("CW");
-  GtkWidget *cw_grid=gtk_grid_new();
-  gtk_grid_set_row_homogeneous(GTK_GRID(cw_grid),TRUE);
-
-  GtkWidget *cw_keyer_internal_b=gtk_check_button_new_with_label("CW Internal - Speed (WPM)");
-  //gtk_widget_override_font(cw_keyer_internal_b, pango_font_description_from_string("Arial 18"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keyer_internal_b), cw_keyer_internal);
-  gtk_widget_show(cw_keyer_internal_b);
-  gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_internal_b,0,0,1,1);
-  g_signal_connect(cw_keyer_internal_b,"toggled",G_CALLBACK(cw_keyer_internal_cb),NULL);
-
-  GtkWidget *cw_keyer_speed_b=gtk_spin_button_new_with_range(1.0,60.0,1.0);
-  //gtk_widget_override_font(cw_keyer_speed_b, pango_font_description_from_string("Arial 18"));
-  gtk_spin_button_set_value(GTK_SPIN_BUTTON(cw_keyer_speed_b),(double)cw_keyer_speed);
-  gtk_widget_show(cw_keyer_speed_b);
-  gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_speed_b,1,0,1,1);
-  g_signal_connect(cw_keyer_speed_b,"value_changed",G_CALLBACK(cw_keyer_speed_value_changed_cb),NULL);
-
-  GtkWidget *cw_breakin_b=gtk_check_button_new_with_label("CW Break In - Delay (ms)");
-  //gtk_widget_override_font(cw_breakin_b, pango_font_description_from_string("Arial 18"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_breakin_b), cw_breakin);
-  gtk_widget_show(cw_breakin_b);
-  gtk_grid_attach(GTK_GRID(cw_grid),cw_breakin_b,0,1,1,1);
-  g_signal_connect(cw_breakin_b,"toggled",G_CALLBACK(cw_breakin_cb),NULL);
-
-  GtkWidget *cw_keyer_hang_time_b=gtk_spin_button_new_with_range(0.0,1000.0,1.0);
-  //gtk_widget_override_font(cw_keyer_hang_time_b, pango_font_description_from_string("Arial 18"));
-  gtk_spin_button_set_value(GTK_SPIN_BUTTON(cw_keyer_hang_time_b),(double)cw_keyer_hang_time);
-  gtk_widget_show(cw_keyer_hang_time_b);
-  gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_hang_time_b,1,1,1,1);
-  g_signal_connect(cw_keyer_hang_time_b,"value_changed",G_CALLBACK(cw_keyer_hang_time_value_changed_cb),NULL);
+  if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL) {
+    GtkWidget *cw_label=gtk_label_new("CW");
+    GtkWidget *cw_grid=gtk_grid_new();
+    gtk_grid_set_row_homogeneous(GTK_GRID(cw_grid),TRUE);
+
+    GtkWidget *cw_keyer_internal_b=gtk_check_button_new_with_label("CW Internal - Speed (WPM)");
+    //gtk_widget_override_font(cw_keyer_internal_b, pango_font_description_from_string("Arial 18"));
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keyer_internal_b), cw_keyer_internal);
+    gtk_widget_show(cw_keyer_internal_b);
+    gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_internal_b,0,0,1,1);
+    g_signal_connect(cw_keyer_internal_b,"toggled",G_CALLBACK(cw_keyer_internal_cb),NULL);
+
+    GtkWidget *cw_keyer_speed_b=gtk_spin_button_new_with_range(1.0,60.0,1.0);
+    //gtk_widget_override_font(cw_keyer_speed_b, pango_font_description_from_string("Arial 18"));
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(cw_keyer_speed_b),(double)cw_keyer_speed);
+    gtk_widget_show(cw_keyer_speed_b);
+    gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_speed_b,1,0,1,1);
+    g_signal_connect(cw_keyer_speed_b,"value_changed",G_CALLBACK(cw_keyer_speed_value_changed_cb),NULL);
+
+    GtkWidget *cw_breakin_b=gtk_check_button_new_with_label("CW Break In - Delay (ms)");
+    //gtk_widget_override_font(cw_breakin_b, pango_font_description_from_string("Arial 18"));
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_breakin_b), cw_breakin);
+    gtk_widget_show(cw_breakin_b);
+    gtk_grid_attach(GTK_GRID(cw_grid),cw_breakin_b,0,1,1,1);
+    g_signal_connect(cw_breakin_b,"toggled",G_CALLBACK(cw_breakin_cb),NULL);
+
+    GtkWidget *cw_keyer_hang_time_b=gtk_spin_button_new_with_range(0.0,1000.0,1.0);
+    //gtk_widget_override_font(cw_keyer_hang_time_b, pango_font_description_from_string("Arial 18"));
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(cw_keyer_hang_time_b),(double)cw_keyer_hang_time);
+    gtk_widget_show(cw_keyer_hang_time_b);
+    gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_hang_time_b,1,1,1,1);
+    g_signal_connect(cw_keyer_hang_time_b,"value_changed",G_CALLBACK(cw_keyer_hang_time_value_changed_cb),NULL);
  
-  GtkWidget *cw_keyer_straight=gtk_radio_button_new_with_label(NULL,"CW KEYER STRAIGHT");
-  //gtk_widget_override_font(cw_keyer_straight, pango_font_description_from_string("Arial 18"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keyer_straight), cw_keyer_mode==KEYER_STRAIGHT);
-  gtk_widget_show(cw_keyer_straight);
-  gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_straight,0,2,1,1);
-  g_signal_connect(cw_keyer_straight,"pressed",G_CALLBACK(cw_keyer_mode_cb),(gpointer *)KEYER_STRAIGHT);
-
-  GtkWidget *cw_keyer_mode_a=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(cw_keyer_straight),"CW KEYER MODE A");
-  //gtk_widget_override_font(cw_keyer_mode_a, pango_font_description_from_string("Arial 18"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keyer_mode_a), cw_keyer_mode==KEYER_MODE_A);
-  gtk_widget_show(cw_keyer_mode_a);
-  gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_mode_a,0,3,1,1);
-  g_signal_connect(cw_keyer_mode_a,"pressed",G_CALLBACK(cw_keyer_mode_cb),(gpointer *)KEYER_MODE_A);
-
-  GtkWidget *cw_keyer_mode_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(cw_keyer_mode_a),"CW KEYER MODE B");
-  //gtk_widget_override_font(cw_keyer_mode_b, pango_font_description_from_string("Arial 18"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keyer_mode_b), cw_keyer_mode==KEYER_MODE_B);
-  gtk_widget_show(cw_keyer_mode_b);
-  gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_mode_b,0,4,1,1);
-  g_signal_connect(cw_keyer_mode_b,"pressed",G_CALLBACK(cw_keyer_mode_cb),(gpointer *)KEYER_MODE_B);
-
-  GtkWidget *cw_keys_reversed_b=gtk_check_button_new_with_label("Keys reversed");
-  //gtk_widget_override_font(cw_keys_reversed_b, pango_font_description_from_string("Arial 18"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keys_reversed_b), cw_keys_reversed);
-  gtk_widget_show(cw_keys_reversed_b);
-  gtk_grid_attach(GTK_GRID(cw_grid),cw_keys_reversed_b,0,5,1,1);
-  g_signal_connect(cw_keys_reversed_b,"toggled",G_CALLBACK(cw_keys_reversed_cb),NULL);
-
-  GtkWidget *cw_keyer_sidetone_level_label=gtk_label_new("Sidetone Level:");
-  //gtk_widget_override_font(cw_keyer_sidetone_level_label, pango_font_description_from_string("Arial 18"));
-  gtk_widget_show(cw_keyer_sidetone_level_label);
-  gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_sidetone_level_label,0,6,1,1);
-
-  GtkWidget *cw_keyer_sidetone_level_b=gtk_spin_button_new_with_range(1.0,protocol==NEW_PROTOCOL?255.0:127.0,1.0);
-  //gtk_widget_override_font(cw_keyer_sidetone_level_b, pango_font_description_from_string("Arial 18"));
-  gtk_spin_button_set_value(GTK_SPIN_BUTTON(cw_keyer_sidetone_level_b),(double)cw_keyer_sidetone_volume);
-  gtk_widget_show(cw_keyer_sidetone_level_b);
-  gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_sidetone_level_b,1,6,1,1);
-  g_signal_connect(cw_keyer_sidetone_level_b,"value_changed",G_CALLBACK(cw_keyer_sidetone_level_value_changed_cb),NULL);
-
-  GtkWidget *cw_keyer_sidetone_frequency_label=gtk_label_new("Sidetone Freq:");
-  //gtk_widget_override_font(cw_keyer_sidetone_frequency_label, pango_font_description_from_string("Arial 18"));
-  gtk_widget_show(cw_keyer_sidetone_frequency_label);
-  gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_sidetone_frequency_label,0,7,1,1);
-
-  GtkWidget *cw_keyer_sidetone_frequency_b=gtk_spin_button_new_with_range(100.0,1000.0,1.0);
-  //gtk_widget_override_font(cw_keyer_sidetone_frequency_b, pango_font_description_from_string("Arial 18"));
-  gtk_spin_button_set_value(GTK_SPIN_BUTTON(cw_keyer_sidetone_frequency_b),(double)cw_keyer_sidetone_frequency);
-  gtk_widget_show(cw_keyer_sidetone_frequency_b);
-  gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_sidetone_frequency_b,1,7,1,1);
-  g_signal_connect(cw_keyer_sidetone_frequency_b,"value_changed",G_CALLBACK(cw_keyer_sidetone_frequency_value_changed_cb),NULL);
-
-  id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),cw_grid,cw_label);
-
-  GtkWidget *oc_label=gtk_label_new("OC");
-  GtkWidget *oc_grid=gtk_grid_new();
-  //gtk_grid_set_row_homogeneous(GTK_GRID(oc_grid),TRUE);
-  gtk_grid_set_column_spacing (GTK_GRID(oc_grid),10);
-
-  GtkWidget *band_title=gtk_label_new("Band");
-  //gtk_widget_override_font(band_title, pango_font_description_from_string("Arial 18"));
-  gtk_widget_show(band_title);
-  gtk_grid_attach(GTK_GRID(oc_grid),band_title,0,0,1,1);
-
-  GtkWidget *rx_title=gtk_label_new("Rx");
-  //gtk_widget_override_font(rx_title, pango_font_description_from_string("Arial 18"));
-  gtk_widget_show(rx_title);
-  gtk_grid_attach(GTK_GRID(oc_grid),rx_title,4,0,1,1);
-
-  GtkWidget *tx_title=gtk_label_new("Tx");
-  //gtk_widget_override_font(tx_title, pango_font_description_from_string("Arial 18"));
-  gtk_widget_show(tx_title);
-  gtk_grid_attach(GTK_GRID(oc_grid),tx_title,11,0,1,1);
-
-  GtkWidget *tune_title=gtk_label_new("Tune (ORed with TX)");
-  //gtk_widget_override_font(tune_title, pango_font_description_from_string("Arial 18"));
-  gtk_widget_show(tune_title);
-  gtk_grid_attach(GTK_GRID(oc_grid),tune_title,18,0,2,1);
-
-  for(i=1;i<8;i++) {
-    char oc_id[8];
-    sprintf(oc_id,"%d",i);
-    GtkWidget *oc_rx_title=gtk_label_new(oc_id);
-    //gtk_widget_override_font(oc_rx_title, pango_font_description_from_string("Arial 18"));
-    gtk_widget_show(oc_rx_title);
-    gtk_grid_attach(GTK_GRID(oc_grid),oc_rx_title,i,1,1,1);
-    GtkWidget *oc_tx_title=gtk_label_new(oc_id);
-    //gtk_widget_override_font(oc_tx_title, pango_font_description_from_string("Arial 18"));
-    gtk_widget_show(oc_tx_title);
-    gtk_grid_attach(GTK_GRID(oc_grid),oc_tx_title,i+7,1,1,1);
+    GtkWidget *cw_keyer_straight=gtk_radio_button_new_with_label(NULL,"CW KEYER STRAIGHT");
+    //gtk_widget_override_font(cw_keyer_straight, pango_font_description_from_string("Arial 18"));
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keyer_straight), cw_keyer_mode==KEYER_STRAIGHT);
+    gtk_widget_show(cw_keyer_straight);
+    gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_straight,0,2,1,1);
+    g_signal_connect(cw_keyer_straight,"pressed",G_CALLBACK(cw_keyer_mode_cb),(gpointer *)KEYER_STRAIGHT);
+
+    GtkWidget *cw_keyer_mode_a=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(cw_keyer_straight),"CW KEYER MODE A");
+    //gtk_widget_override_font(cw_keyer_mode_a, pango_font_description_from_string("Arial 18"));
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keyer_mode_a), cw_keyer_mode==KEYER_MODE_A);
+    gtk_widget_show(cw_keyer_mode_a);
+    gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_mode_a,0,3,1,1);
+    g_signal_connect(cw_keyer_mode_a,"pressed",G_CALLBACK(cw_keyer_mode_cb),(gpointer *)KEYER_MODE_A);
+
+    GtkWidget *cw_keyer_mode_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(cw_keyer_mode_a),"CW KEYER MODE B");
+    //gtk_widget_override_font(cw_keyer_mode_b, pango_font_description_from_string("Arial 18"));
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keyer_mode_b), cw_keyer_mode==KEYER_MODE_B);
+    gtk_widget_show(cw_keyer_mode_b);
+    gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_mode_b,0,4,1,1);
+    g_signal_connect(cw_keyer_mode_b,"pressed",G_CALLBACK(cw_keyer_mode_cb),(gpointer *)KEYER_MODE_B);
+
+    GtkWidget *cw_keys_reversed_b=gtk_check_button_new_with_label("Keys reversed");
+    //gtk_widget_override_font(cw_keys_reversed_b, pango_font_description_from_string("Arial 18"));
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keys_reversed_b), cw_keys_reversed);
+    gtk_widget_show(cw_keys_reversed_b);
+    gtk_grid_attach(GTK_GRID(cw_grid),cw_keys_reversed_b,0,5,1,1);
+    g_signal_connect(cw_keys_reversed_b,"toggled",G_CALLBACK(cw_keys_reversed_cb),NULL);
+  
+    GtkWidget *cw_keyer_sidetone_level_label=gtk_label_new("Sidetone Level:");
+    //gtk_widget_override_font(cw_keyer_sidetone_level_label, pango_font_description_from_string("Arial 18"));
+    gtk_widget_show(cw_keyer_sidetone_level_label);
+    gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_sidetone_level_label,0,6,1,1);
+  
+    GtkWidget *cw_keyer_sidetone_level_b=gtk_spin_button_new_with_range(1.0,protocol==NEW_PROTOCOL?255.0:127.0,1.0);
+    //gtk_widget_override_font(cw_keyer_sidetone_level_b, pango_font_description_from_string("Arial 18"));
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(cw_keyer_sidetone_level_b),(double)cw_keyer_sidetone_volume);
+    gtk_widget_show(cw_keyer_sidetone_level_b);
+    gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_sidetone_level_b,1,6,1,1);
+    g_signal_connect(cw_keyer_sidetone_level_b,"value_changed",G_CALLBACK(cw_keyer_sidetone_level_value_changed_cb),NULL);
+
+    GtkWidget *cw_keyer_sidetone_frequency_label=gtk_label_new("Sidetone Freq:");
+    //gtk_widget_override_font(cw_keyer_sidetone_frequency_label, pango_font_description_from_string("Arial 18"));
+    gtk_widget_show(cw_keyer_sidetone_frequency_label);
+    gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_sidetone_frequency_label,0,7,1,1);
+
+    GtkWidget *cw_keyer_sidetone_frequency_b=gtk_spin_button_new_with_range(100.0,1000.0,1.0);
+    //gtk_widget_override_font(cw_keyer_sidetone_frequency_b, pango_font_description_from_string("Arial 18"));
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(cw_keyer_sidetone_frequency_b),(double)cw_keyer_sidetone_frequency);
+    gtk_widget_show(cw_keyer_sidetone_frequency_b);
+    gtk_grid_attach(GTK_GRID(cw_grid),cw_keyer_sidetone_frequency_b,1,7,1,1);
+    g_signal_connect(cw_keyer_sidetone_frequency_b,"value_changed",G_CALLBACK(cw_keyer_sidetone_frequency_value_changed_cb),NULL);
+  
+    id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),cw_grid,cw_label);
+  }
+
+  if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL) {
+    GtkWidget *oc_label=gtk_label_new("OC");
+    GtkWidget *oc_grid=gtk_grid_new();
+    //gtk_grid_set_row_homogeneous(GTK_GRID(oc_grid),TRUE);
+    gtk_grid_set_column_spacing (GTK_GRID(oc_grid),10);
+
+    GtkWidget *band_title=gtk_label_new("Band");
+    //gtk_widget_override_font(band_title, pango_font_description_from_string("Arial 18"));
+    gtk_widget_show(band_title);
+    gtk_grid_attach(GTK_GRID(oc_grid),band_title,0,0,1,1);
+
+    GtkWidget *rx_title=gtk_label_new("Rx");
+    //gtk_widget_override_font(rx_title, pango_font_description_from_string("Arial 18"));
+    gtk_widget_show(rx_title);
+    gtk_grid_attach(GTK_GRID(oc_grid),rx_title,4,0,1,1);
+
+    GtkWidget *tx_title=gtk_label_new("Tx");
+    //gtk_widget_override_font(tx_title, pango_font_description_from_string("Arial 18"));
+    gtk_widget_show(tx_title);
+    gtk_grid_attach(GTK_GRID(oc_grid),tx_title,11,0,1,1);
+  
+    GtkWidget *tune_title=gtk_label_new("Tune (ORed with TX)");
+    //gtk_widget_override_font(tune_title, pango_font_description_from_string("Arial 18"));
+    gtk_widget_show(tune_title);
+    gtk_grid_attach(GTK_GRID(oc_grid),tune_title,18,0,2,1);
+  
+    for(i=1;i<8;i++) {
+      char oc_id[8];
+      sprintf(oc_id,"%d",i);
+      GtkWidget *oc_rx_title=gtk_label_new(oc_id);
+      //gtk_widget_override_font(oc_rx_title, pango_font_description_from_string("Arial 18"));
+      gtk_widget_show(oc_rx_title);
+      gtk_grid_attach(GTK_GRID(oc_grid),oc_rx_title,i,1,1,1);
+      GtkWidget *oc_tx_title=gtk_label_new(oc_id);
+      //gtk_widget_override_font(oc_tx_title, pango_font_description_from_string("Arial 18"));
+      gtk_widget_show(oc_tx_title);
+      gtk_grid_attach(GTK_GRID(oc_grid),oc_tx_title,i+7,1,1,1);
 /*
-    GtkWidget *oc_tune_title=gtk_label_new(oc_id);
-    //gtk_widget_override_font(oc_tune_title, pango_font_description_from_string("Arial 18"));
-    gtk_widget_show(oc_tune_title);
-    gtk_grid_attach(GTK_GRID(oc_grid),oc_tune_title,i+14,1,1,1);
+      GtkWidget *oc_tune_title=gtk_label_new(oc_id);
+      //gtk_widget_override_font(oc_tune_title, pango_font_description_from_string("Arial 18"));
+      gtk_widget_show(oc_tune_title);
+      gtk_grid_attach(GTK_GRID(oc_grid),oc_tune_title,i+14,1,1,1);
 */
   }
 
-  for(i=0;i<HAM_BANDS;i++) {
-    BAND *band=band_get_band(i);
+    for(i=0;i<HAM_BANDS;i++) {
+      BAND *band=band_get_band(i);
+  
+      GtkWidget *band_label=gtk_label_new(band->title);
+      //gtk_widget_override_font(band_label, pango_font_description_from_string("Arial 18"));
+      gtk_widget_show(band_label);
+      gtk_grid_attach(GTK_GRID(oc_grid),band_label,0,i+2,1,1);
+  
+      int mask;
+      for(j=1;j<8;j++) {
+        mask=0x01<<j;
+        GtkWidget *oc_rx_b=gtk_check_button_new();
+        //gtk_widget_override_font(oc_rx_b, pango_font_description_from_string("Arial 18"));
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (oc_rx_b), (band->OCrx&mask)==mask);
+        gtk_widget_show(oc_rx_b);
+        gtk_grid_attach(GTK_GRID(oc_grid),oc_rx_b,j,i+2,1,1);
+        g_signal_connect(oc_rx_b,"toggled",G_CALLBACK(oc_rx_cb),(gpointer)(j+(i<<4)));
+  
+        GtkWidget *oc_tx_b=gtk_check_button_new();
+        //gtk_widget_override_font(oc_tx_b, pango_font_description_from_string("Arial 18"));
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (oc_tx_b), (band->OCtx&mask)==mask);
+        gtk_widget_show(oc_tx_b);
+        gtk_grid_attach(GTK_GRID(oc_grid),oc_tx_b,j+7,i+2,1,1);
+        g_signal_connect(oc_tx_b,"toggled",G_CALLBACK(oc_tx_cb),(gpointer)(j+(i<<4)));
+  
+/*
+        GtkWidget *oc_tune_b=gtk_check_button_new();
+        //gtk_widget_override_font(oc_tune_b, pango_font_description_from_string("Arial 18"));
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (oc_tune_b), (band->OCtune&mask)==mask);
+        gtk_widget_show(oc_tune_b);
+        gtk_grid_attach(GTK_GRID(oc_grid),oc_tune_b,j+14,i+2,1,1);
+        g_signal_connect(oc_tune_b,"toggled",G_CALLBACK(oc_tune_cb),(gpointer)(j+(i<<4)));
+*/
+      }
+    }
 
-    GtkWidget *band_label=gtk_label_new(band->title);
-    //gtk_widget_override_font(band_label, pango_font_description_from_string("Arial 18"));
-    gtk_widget_show(band_label);
-    gtk_grid_attach(GTK_GRID(oc_grid),band_label,0,i+2,1,1);
 
     int mask;
     for(j=1;j<8;j++) {
+      char oc_id[8];
+      sprintf(oc_id,"%d",j);
+      GtkWidget *oc_tune_title=gtk_label_new(oc_id);
+      //gtk_widget_override_font(oc_tune_title, pango_font_description_from_string("Arial 18"));
+      gtk_widget_show(oc_tune_title);
+      gtk_grid_attach(GTK_GRID(oc_grid),oc_tune_title,18,j,1,1);
+  
       mask=0x01<<j;
-      GtkWidget *oc_rx_b=gtk_check_button_new();
-      //gtk_widget_override_font(oc_rx_b, pango_font_description_from_string("Arial 18"));
-      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (oc_rx_b), (band->OCrx&mask)==mask);
-      gtk_widget_show(oc_rx_b);
-      gtk_grid_attach(GTK_GRID(oc_grid),oc_rx_b,j,i+2,1,1);
-      g_signal_connect(oc_rx_b,"toggled",G_CALLBACK(oc_rx_cb),(gpointer)(j+(i<<4)));
-
-      GtkWidget *oc_tx_b=gtk_check_button_new();
-      //gtk_widget_override_font(oc_tx_b, pango_font_description_from_string("Arial 18"));
-      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (oc_tx_b), (band->OCtx&mask)==mask);
-      gtk_widget_show(oc_tx_b);
-      gtk_grid_attach(GTK_GRID(oc_grid),oc_tx_b,j+7,i+2,1,1);
-      g_signal_connect(oc_tx_b,"toggled",G_CALLBACK(oc_tx_cb),(gpointer)(j+(i<<4)));
-
-/*
       GtkWidget *oc_tune_b=gtk_check_button_new();
       //gtk_widget_override_font(oc_tune_b, pango_font_description_from_string("Arial 18"));
-      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (oc_tune_b), (band->OCtune&mask)==mask);
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (oc_tune_b), (OCtune&mask)==mask);
       gtk_widget_show(oc_tune_b);
-      gtk_grid_attach(GTK_GRID(oc_grid),oc_tune_b,j+14,i+2,1,1);
-      g_signal_connect(oc_tune_b,"toggled",G_CALLBACK(oc_tune_cb),(gpointer)(j+(i<<4)));
-*/
+      gtk_grid_attach(GTK_GRID(oc_grid),oc_tune_b,19,j,1,1);
+      g_signal_connect(oc_tune_b,"toggled",G_CALLBACK(oc_tune_cb),(gpointer)j);
     }
+
+    GtkWidget *oc_full_tune_time_title=gtk_label_new("Full Tune(ms):");
+    //gtk_widget_override_font(oc_full_tune_time_title, pango_font_description_from_string("Arial 18"));
+    gtk_widget_show(oc_full_tune_time_title);
+    gtk_grid_attach(GTK_GRID(oc_grid),oc_full_tune_time_title,18,j,2,1);
+    j++;
+  
+    GtkWidget *oc_full_tune_time_b=gtk_spin_button_new_with_range(0.0,9999.0,1.0);
+    //gtk_widget_override_font(oc_full_tune_time_b, pango_font_description_from_string("Arial 18"));
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(oc_full_tune_time_b),(double)OCfull_tune_time);
+    gtk_widget_show(oc_full_tune_time_b);
+    gtk_grid_attach(GTK_GRID(oc_grid),oc_full_tune_time_b,18,j,2,1);
+    g_signal_connect(oc_full_tune_time_b,"value_changed",G_CALLBACK(oc_full_tune_time_cb),NULL);
+    j++;
+  
+    GtkWidget *oc_memory_tune_time_title=gtk_label_new("Memory Tune(ms):");
+    //gtk_widget_override_font(oc_memory_tune_time_title, pango_font_description_from_string("Arial 18"));
+    gtk_widget_show(oc_memory_tune_time_title);
+    gtk_grid_attach(GTK_GRID(oc_grid),oc_memory_tune_time_title,18,j,2,1);
+    j++;
+
+    GtkWidget *oc_memory_tune_time_b=gtk_spin_button_new_with_range(0.0,9999.0,1.0);
+    //gtk_widget_override_font(oc_memory_tune_time_b, pango_font_description_from_string("Arial 18"));
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(oc_memory_tune_time_b),(double)OCmemory_tune_time);
+    gtk_widget_show(oc_memory_tune_time_b);
+    gtk_grid_attach(GTK_GRID(oc_grid),oc_memory_tune_time_b,18,j,2,1);
+    g_signal_connect(oc_memory_tune_time_b,"value_changed",G_CALLBACK(oc_memory_tune_time_cb),NULL);
+    j++;
+  
+    id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),oc_grid,oc_label);
   }
 
 
-  int mask;
-  for(j=1;j<8;j++) {
-    char oc_id[8];
-    sprintf(oc_id,"%d",j);
-    GtkWidget *oc_tune_title=gtk_label_new(oc_id);
-    //gtk_widget_override_font(oc_tune_title, pango_font_description_from_string("Arial 18"));
-    gtk_widget_show(oc_tune_title);
-    gtk_grid_attach(GTK_GRID(oc_grid),oc_tune_title,18,j,1,1);
-
-    mask=0x01<<j;
-    GtkWidget *oc_tune_b=gtk_check_button_new();
-    //gtk_widget_override_font(oc_tune_b, pango_font_description_from_string("Arial 18"));
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (oc_tune_b), (OCtune&mask)==mask);
-    gtk_widget_show(oc_tune_b);
-    gtk_grid_attach(GTK_GRID(oc_grid),oc_tune_b,19,j,1,1);
-    g_signal_connect(oc_tune_b,"toggled",G_CALLBACK(oc_tune_cb),(gpointer)j);
-  }
 
-  GtkWidget *oc_full_tune_time_title=gtk_label_new("Full Tune(ms):");
-  //gtk_widget_override_font(oc_full_tune_time_title, pango_font_description_from_string("Arial 18"));
-  gtk_widget_show(oc_full_tune_time_title);
-  gtk_grid_attach(GTK_GRID(oc_grid),oc_full_tune_time_title,18,j,2,1);
-  j++;
-
-  GtkWidget *oc_full_tune_time_b=gtk_spin_button_new_with_range(0.0,9999.0,1.0);
-  //gtk_widget_override_font(oc_full_tune_time_b, pango_font_description_from_string("Arial 18"));
-  gtk_spin_button_set_value(GTK_SPIN_BUTTON(oc_full_tune_time_b),(double)OCfull_tune_time);
-  gtk_widget_show(oc_full_tune_time_b);
-  gtk_grid_attach(GTK_GRID(oc_grid),oc_full_tune_time_b,18,j,2,1);
-  g_signal_connect(oc_full_tune_time_b,"value_changed",G_CALLBACK(oc_full_tune_time_cb),NULL);
-  j++;
-
-  GtkWidget *oc_memory_tune_time_title=gtk_label_new("Memory Tune(ms):");
-  //gtk_widget_override_font(oc_memory_tune_time_title, pango_font_description_from_string("Arial 18"));
-  gtk_widget_show(oc_memory_tune_time_title);
-  gtk_grid_attach(GTK_GRID(oc_grid),oc_memory_tune_time_title,18,j,2,1);
-  j++;
-
-  GtkWidget *oc_memory_tune_time_b=gtk_spin_button_new_with_range(0.0,9999.0,1.0);
-  //gtk_widget_override_font(oc_memory_tune_time_b, pango_font_description_from_string("Arial 18"));
-  gtk_spin_button_set_value(GTK_SPIN_BUTTON(oc_memory_tune_time_b),(double)OCmemory_tune_time);
-  gtk_widget_show(oc_memory_tune_time_b);
-  gtk_grid_attach(GTK_GRID(oc_grid),oc_memory_tune_time_b,18,j,2,1);
-  g_signal_connect(oc_memory_tune_time_b,"value_changed",G_CALLBACK(oc_memory_tune_time_cb),NULL);
-  j++;
-
-  id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),oc_grid,oc_label);
+#ifdef FREEDV
+  GtkWidget *freedv_label=gtk_label_new("FREEDV");
+  GtkWidget *freedv_grid=gtk_grid_new();
+
+  GtkWidget *freedv_text_label=gtk_label_new("Text Message: ");
+  gtk_grid_attach(GTK_GRID(freedv_grid),freedv_text_label,0,0,1,1);
+
+  GtkWidget *freedv_text=gtk_entry_new();
+  gtk_entry_set_text(GTK_ENTRY(freedv_text),freedv_tx_text_data);
+  gtk_grid_attach(GTK_GRID(freedv_grid),freedv_text,0,1,4,1);
+  g_signal_connect(freedv_text,"changed",G_CALLBACK(freedv_text_changed_cb),NULL);
+
+  id=gtk_notebook_append_page(GTK_NOTEBOOK(notebook),freedv_grid,freedv_label);
+#endif
+
 
 
   GtkWidget *exit_label=gtk_label_new("Exit");
diff --git a/meter.c b/meter.c
index 5c774bd0b22b2942169e1e94fde45c776fa4ff2c..f93e58ea3d3fd0e54741a21b0b7235054ef190b0 100644 (file)
--- a/meter.c
+++ b/meter.c
 #include <unistd.h>
 
 #include "meter.h"
+#ifdef FREEDV
+#include "radio.h"
+#include "mode.h"
+#include "freedv.h"
+#endif
 
 static GtkWidget *meter;
 static cairo_surface_t *meter_surface = NULL;
@@ -201,6 +206,21 @@ void meter_update(int meter_type,double value,double reverse,double exciter) {
       sprintf(sf,"%d dBm",(int)level);
       cairo_move_to(cr, text_location, 45);
       cairo_show_text(cr, sf);
+
+#ifdef FREEDV
+      if(mode==modeFREEDV) {
+        if(freedv_sync) {
+          cairo_set_source_rgb(cr, 0, 1, 0);
+        } else {
+          cairo_set_source_rgb(cr, 1, 0, 0);
+        }
+        cairo_set_font_size(cr, 16);
+        sprintf(sf,"SNR: %3.2f",freedv_snr);
+        cairo_move_to(cr, text_location, 20);
+        cairo_show_text(cr, sf);
+      }
+#endif
+
       break;
     case POWER:
       // value is Watts
diff --git a/mode.c b/mode.c
index 8bf7706cde46620a8e4d5c25fa90ce69cef40e73..6450963134da4c995eaa4f47da9bbddf90f3dd51 100644 (file)
--- a/mode.c
+++ b/mode.c
 *
 */
 
-char *mode_string[]={"LSB","USB","DSB","CWL","CWU","FMN","AM","DIGU","SPEC","DIGL","SAM","DRM","FREEDV"};
+char *mode_string[]={
+  "LSB"
+  ,"USB"
+  ,"DSB"
+  ,"CWL"
+  ,"CWU"
+  ,"FMN"
+  ,"AM"
+  ,"DIGU"
+  ,"SPEC"
+  ,"DIGL"
+  ,"SAM"
+  ,"DRM"
+#ifdef FREEDV
+  ,"FREEDV"
+#endif
+};
 
diff --git a/mode.h b/mode.h
index 6176396ca86eb14c244801aa1c033efa1d618f3d..71d9dca7daa97cbf6b85e435a14103f62c9280f6 100644 (file)
--- a/mode.h
+++ b/mode.h
 #define modeDIGL 9
 #define modeSAM 10
 #define modeDRM 11
+#ifdef FREEDV
 #define modeFREEDV 12
-
 #define MODES 13
+#else
+#define MODES 12
+#endif
 
 int mode;
 
index dc4a8f3c8e04b81f9724dbf31827f86450fa5ac8..1d3658aafe87091f544a738f898d2c908f4c00d6 100644 (file)
@@ -57,14 +57,14 @@ void print_device(int i) {
         discovered[i].device,
         discovered[i].software_version,
         discovered[i].status,
-        inet_ntoa(discovered[i].address.sin_addr),
-        discovered[i].mac_address[0],
-        discovered[i].mac_address[1],
-        discovered[i].mac_address[2],
-        discovered[i].mac_address[3],
-        discovered[i].mac_address[4],
-        discovered[i].mac_address[5],
-        discovered[i].interface_name);
+        inet_ntoa(discovered[i].info.network.address.sin_addr),
+        discovered[i].info.network.mac_address[0],
+        discovered[i].info.network.mac_address[1],
+        discovered[i].info.network.mac_address[2],
+        discovered[i].info.network.mac_address[3],
+        discovered[i].info.network.mac_address[4],
+        discovered[i].info.network.mac_address[5],
+        discovered[i].info.network.interface_name);
 }
 
 void new_discovery() {
@@ -240,28 +240,28 @@ void* new_discover_receive_thread(void* arg) {
                     }
                     discovered[devices].software_version=buffer[13]&0xFF;
                     for(i=0;i<6;i++) {
-                        discovered[devices].mac_address[i]=buffer[i+5];
+                        discovered[devices].info.network.mac_address[i]=buffer[i+5];
                     }
                     discovered[devices].status=status;
-                    memcpy((void*)&discovered[devices].address,(void*)&addr,sizeof(addr));
-                    discovered[devices].address_length=sizeof(addr);
-                    memcpy((void*)&discovered[devices].interface_address,(void*)&interface_addr,sizeof(interface_addr));
-                    memcpy((void*)&discovered[devices].interface_netmask,(void*)&interface_netmask,sizeof(interface_netmask));
-                    discovered[devices].interface_length=sizeof(interface_addr);
-                    strcpy(discovered[devices].interface_name,interface_name);
+                    memcpy((void*)&discovered[devices].info.network.address,(void*)&addr,sizeof(addr));
+                    discovered[devices].info.network.address_length=sizeof(addr);
+                    memcpy((void*)&discovered[devices].info.network.interface_address,(void*)&interface_addr,sizeof(interface_addr));
+                    memcpy((void*)&discovered[devices].info.network.interface_netmask,(void*)&interface_netmask,sizeof(interface_netmask));
+                    discovered[devices].info.network.interface_length=sizeof(interface_addr);
+                    strcpy(discovered[devices].info.network.interface_name,interface_name);
                     fprintf(stderr,"new_discover: found protocol=%d device=%d software_version=%d status=%d address=%s (%02X:%02X:%02X:%02X:%02X:%02X) on %s\n", 
                             discovered[devices].protocol,
                             discovered[devices].device,
                             discovered[devices].software_version,
                             discovered[devices].status,
-                            inet_ntoa(discovered[devices].address.sin_addr),
-                            discovered[devices].mac_address[0],
-                            discovered[devices].mac_address[1],
-                            discovered[devices].mac_address[2],
-                            discovered[devices].mac_address[3],
-                            discovered[devices].mac_address[4],
-                            discovered[devices].mac_address[5],
-                            discovered[devices].interface_name);
+                            inet_ntoa(discovered[devices].info.network.address.sin_addr),
+                            discovered[devices].info.network.mac_address[0],
+                            discovered[devices].info.network.mac_address[1],
+                            discovered[devices].info.network.mac_address[2],
+                            discovered[devices].info.network.mac_address[3],
+                            discovered[devices].info.network.mac_address[4],
+                            discovered[devices].info.network.mac_address[5],
+                            discovered[devices].info.network.interface_name);
                     devices++;
                 }
             }
index a308cf738e4e103036e633a299c5b141734f5828..97d40e89d967d131ccc7cc9ff681796b164f6392 100644 (file)
@@ -647,37 +647,37 @@ fprintf(stderr,"outputsamples=%d\n", outputsamples);
     setsockopt(data_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
 
     // bind to the interface
-    if(bind(data_socket,(struct sockaddr*)&d->interface_address,d->interface_length)<0) {
+    if(bind(data_socket,(struct sockaddr*)&d->info.network.interface_address,d->info.network.interface_length)<0) {
         fprintf(stderr,"metis: bind socket failed for data_socket: receiver=%d\n",receiver);
         exit(-1);
     }
 
-    memcpy(&base_addr,&d->address,d->address_length);
-    base_addr_length=d->address_length;
+    memcpy(&base_addr,&d->info.network.address,d->info.network.address_length);
+    base_addr_length=d->info.network.address_length;
     base_addr.sin_port=htons(GENERAL_REGISTERS_FROM_HOST_PORT);
 
-    memcpy(&receiver_addr,&d->address,d->address_length);
-    receiver_addr_length=d->address_length;
+    memcpy(&receiver_addr,&d->info.network.address,d->info.network.address_length);
+    receiver_addr_length=d->info.network.address_length;
     receiver_addr.sin_port=htons(RECEIVER_SPECIFIC_REGISTERS_FROM_HOST_PORT);
 
-    memcpy(&transmitter_addr,&d->address,d->address_length);
-    transmitter_addr_length=d->address_length;
+    memcpy(&transmitter_addr,&d->info.network.address,d->info.network.address_length);
+    transmitter_addr_length=d->info.network.address_length;
     transmitter_addr.sin_port=htons(TRANSMITTER_SPECIFIC_REGISTERS_FROM_HOST_PORT);
 
-    memcpy(&high_priority_addr,&d->address,d->address_length);
-    high_priority_addr_length=d->address_length;
+    memcpy(&high_priority_addr,&d->info.network.address,d->info.network.address_length);
+    high_priority_addr_length=d->info.network.address_length;
     high_priority_addr.sin_port=htons(HIGH_PRIORITY_FROM_HOST_PORT);
 
-    memcpy(&audio_addr,&d->address,d->address_length);
-    audio_addr_length=d->address_length;
+    memcpy(&audio_addr,&d->info.network.address,d->info.network.address_length);
+    audio_addr_length=d->info.network.address_length;
     audio_addr.sin_port=htons(AUDIO_FROM_HOST_PORT);
 
-    memcpy(&iq_addr,&d->address,d->address_length);
-    iq_addr_length=d->address_length;
+    memcpy(&iq_addr,&d->info.network.address,d->info.network.address_length);
+    iq_addr_length=d->info.network.address_length;
     iq_addr.sin_port=htons(TX_IQ_FROM_HOST_PORT);
 
-    memcpy(&data_addr,&d->address,d->address_length);
-    data_addr_length=d->address_length;
+    memcpy(&data_addr,&d->info.network.address,d->info.network.address_length);
+    data_addr_length=d->info.network.address_length;
     data_addr.sin_port=htons(RX_IQ_TO_HOST_PORT+receiver);
 
     samples=0;
index 728970c1af224dd15f832bf638d08e3848de6861..0692a7582587140dc7c0a787ee5fe4127d26dce3 100644 (file)
@@ -69,8 +69,8 @@ void new_protocol_programmer(char *filename ) {
 
     DISCOVERED* d=&discovered[selected_device];
 
-    memcpy(&program_addr,&d->address,d->address_length);
-    program_addr_length=d->address_length;
+    memcpy(&program_addr,&d->info.network.address,d->info.network.address_length);
+    program_addr_length=d->info.network.address_length;
     program_addr.sin_port=htons(PROGRAMMING_FROM_HOST_PORT);
 
     FILE *fp;
index 7867f6e4524167718ecb5bb307015e5db350ec57..6a22fe1d4d9528266756c5d7989936bcf8be8e6d 100644 (file)
@@ -72,7 +72,8 @@ static void discover(struct ifaddrs* iface) {
     // bind to this interface and the discovery port
     interface_addr.sin_family = AF_INET;
     interface_addr.sin_addr.s_addr = sa->sin_addr.s_addr;
-    interface_addr.sin_port = htons(DISCOVERY_PORT*2);
+    //interface_addr.sin_port = htons(DISCOVERY_PORT*2);
+    interface_addr.sin_port = htons(0); // system assigned port
     if(bind(discovery_socket,(struct sockaddr*)&interface_addr,sizeof(interface_addr))<0) {
         perror("discover: bind socket failed for discovery_socket\n");
         exit(-1);
@@ -182,27 +183,27 @@ fprintf(stderr,"discover_receive_thread\n");
                     }
                     discovered[devices].software_version=buffer[9]&0xFF;
                     for(i=0;i<6;i++) {
-                        discovered[devices].mac_address[i]=buffer[i+3];
+                        discovered[devices].info.network.mac_address[i]=buffer[i+3];
                     }
                     discovered[devices].status=status;
-                    memcpy((void*)&discovered[devices].address,(void*)&addr,sizeof(addr));
-                    discovered[devices].address_length=sizeof(addr);
-                    memcpy((void*)&discovered[devices].interface_address,(void*)&interface_addr,sizeof(interface_addr));
-                    memcpy((void*)&discovered[devices].interface_netmask,(void*)&interface_netmask,sizeof(interface_netmask));
-                    discovered[devices].interface_length=sizeof(interface_addr);
-                    strcpy(discovered[devices].interface_name,interface_name);
+                    memcpy((void*)&discovered[devices].info.network.address,(void*)&addr,sizeof(addr));
+                    discovered[devices].info.network.address_length=sizeof(addr);
+                    memcpy((void*)&discovered[devices].info.network.interface_address,(void*)&interface_addr,sizeof(interface_addr));
+                    memcpy((void*)&discovered[devices].info.network.interface_netmask,(void*)&interface_netmask,sizeof(interface_netmask));
+                    discovered[devices].info.network.interface_length=sizeof(interface_addr);
+                    strcpy(discovered[devices].info.network.interface_name,interface_name);
                     fprintf(stderr,"discovery: found device=%d software_version=%d status=%d address=%s (%02X:%02X:%02X:%02X:%02X:%02X) on %s\n",
                             discovered[devices].device,
                             discovered[devices].software_version,
                             discovered[devices].status,
-                            inet_ntoa(discovered[devices].address.sin_addr),
-                            discovered[devices].mac_address[0],
-                            discovered[devices].mac_address[1],
-                            discovered[devices].mac_address[2],
-                            discovered[devices].mac_address[3],
-                            discovered[devices].mac_address[4],
-                            discovered[devices].mac_address[5],
-                            discovered[devices].interface_name);
+                            inet_ntoa(discovered[devices].info.network.address.sin_addr),
+                            discovered[devices].info.network.mac_address[0],
+                            discovered[devices].info.network.mac_address[1],
+                            discovered[devices].info.network.mac_address[2],
+                            discovered[devices].info.network.mac_address[3],
+                            discovered[devices].info.network.mac_address[4],
+                            discovered[devices].info.network.mac_address[5],
+                            discovered[devices].info.network.interface_name);
                     devices++;
                 }
             }
@@ -240,14 +241,14 @@ fprintf(stderr,"old_discovery\n");
                             discovered[i].device,
                             discovered[i].software_version,
                             discovered[i].status,
-                            inet_ntoa(discovered[i].address.sin_addr),
-                            discovered[i].mac_address[0],
-                            discovered[i].mac_address[1],
-                            discovered[i].mac_address[2],
-                            discovered[i].mac_address[3],
-                            discovered[i].mac_address[4],
-                            discovered[i].mac_address[5],
-                            discovered[i].interface_name);
+                            inet_ntoa(discovered[i].info.network.address.sin_addr),
+                            discovered[i].info.network.mac_address[0],
+                            discovered[i].info.network.mac_address[1],
+                            discovered[i].info.network.mac_address[2],
+                            discovered[i].info.network.mac_address[3],
+                            discovered[i].info.network.mac_address[4],
+                            discovered[i].info.network.mac_address[5],
+                            discovered[i].info.network.interface_name);
     }
 
 }
index b33f5b7bf02547cdef119ab8a30a59a010a5be03..88a32398601529120a67160b0c7f91c8d71dadf5 100644 (file)
@@ -23,6 +23,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/ioctl.h>
+#include <sys/time.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
@@ -34,6 +35,7 @@
 #include <string.h>
 #include <errno.h>
 #include <math.h>
+#include <wdsp.h>
 
 #include "band.h"
 #include "channel.h"
@@ -123,6 +125,8 @@ static int running;
 static long ep4_sequence;
 
 static int samples=0;
+static int freedv_samples=0;
+static int freedv_divisor=6;
 
 //static float left_input_buffer[BUFFER_SIZE];
 //static float right_input_buffer[BUFFER_SIZE];
@@ -170,6 +174,8 @@ static sem_t frequency_changed_sem;
 static int metis_write(unsigned char ep,char* buffer,int length);
 static void metis_start_stop(int command);
 static void metis_send_buffer(char* buffer,int length);
+static void full_rx_buffer();
+static void full_tx_buffer();
 
 void schedule_frequency_changed() {
 //fprintf(stderr,"old_protocol: schedule_frequency_changed\n");
@@ -208,15 +214,19 @@ void old_protocol_init(int rx,int pixels) {
   switch(sample_rate) {
     case 48000:
       output_buffer_size=OUTPUT_BUFFER_SIZE;
+      freedv_divisor=6;
       break;
     case 96000:
       output_buffer_size=OUTPUT_BUFFER_SIZE/2;
+      freedv_divisor=12;
       break;
     case 192000:
       output_buffer_size=OUTPUT_BUFFER_SIZE/4;
+      freedv_divisor=24;
       break;
     case 384000:
       output_buffer_size=OUTPUT_BUFFER_SIZE/8;
+      freedv_divisor=48;
       break;
     default:
       fprintf(stderr,"Invalid sample rate: %d. Defaulting to 48K.\n",sample_rate);
@@ -250,7 +260,7 @@ static void start_receive_thread() {
   int rc;
   struct hostent *h;
 
-  fprintf(stderr,"old_protocol starting receive thread\n");
+  fprintf(stderr,"old_protocol starting receive thread: buffer_size=%d output_buffer_size=%d\n",buffer_size,output_buffer_size);
 
   data_socket=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
   if(data_socket<0) {
@@ -262,13 +272,13 @@ static void start_receive_thread() {
   setsockopt(data_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
 
   // bind to the interface
-  if(bind(data_socket,(struct sockaddr*)&d->interface_address,d->interface_length)<0) {
+  if(bind(data_socket,(struct sockaddr*)&d->info.network.interface_address,d->info.network.interface_length)<0) {
     perror("old_protocol: bind socket failed for data_socket\n");
     exit(-1);
   }
 
-  memcpy(&data_addr,&d->address,d->address_length);
-  data_addr_length=d->address_length;
+  memcpy(&data_addr,&d->info.network.address,d->info.network.address_length);
+  data_addr_length=d->info.network.address_length;
   data_addr.sin_port=htons(DATA_PORT);
 
   rc=pthread_create(&receive_thread_id,NULL,receive_thread,NULL);
@@ -426,16 +436,7 @@ static void process_ozy_input_buffer(char  *buffer) {
       right_sample += (int)((unsigned char)buffer[b++]);
       mic_sample    = (int)((signed char) buffer[b++]) << 8;
       mic_sample   += (int)((unsigned char)buffer[b++]);
-/*
-      left_sample  = ((int)buffer[b++]) << 16;
-      left_sample  = (((unsigned char)buffer[b++]) << 8) | left_sample;
-      left_sample  = ((unsigned char)buffer[b++]) | left_sample;
-      right_sample = ((int)buffer[b++]) << 16;
-      right_sample = (((unsigned char)buffer[b++]) << 8) | right_sample;
-      right_sample = ((unsigned char)buffer[b++]) | right_sample;
-      mic_sample   = ((int)buffer[b++]) << 8;
-      mic_sample   = ((unsigned char)buffer[b++]) | mic_sample;
-*/
+
       left_sample_float=(float)left_sample/8388607.0; // 24 bit sample 2^23-1
       right_sample_float=(float)right_sample/8388607.0; // 24 bit sample 2^23-1
       mic_sample_float=(float)mic_sample/32767.0f; // 16 bit sample 2^16-1
@@ -444,9 +445,30 @@ static void process_ozy_input_buffer(char  *buffer) {
       if(isTransmitting()) {
 #ifdef FREEDV
         if(mode==modeFREEDV) {
-          int modem_samples=mod_sample_freedv(mic_sample);
-          if(modem_samples!=0) {
-            
+          if(freedv_samples==0) {
+            int modem_samples=mod_sample_freedv(mic_sample);
+            if(modem_samples!=0) {
+              int s;
+              for(s=0;s<modem_samples;s++) {
+                for(j=0;j<freedv_divisor;j++) {
+                  mic_sample=mod_out[s];
+                  mic_sample_float=(float)mic_sample/32767.0f; // 16 bit sample 2^16-1
+                  micinputbuffer[samples*2]=(double)mic_sample_float*mic_gain;
+                  micinputbuffer[(samples*2)+1]=(double)mic_sample_float*mic_gain;
+                  iqinputbuffer[samples*2]=0.0;
+                  iqinputbuffer[(samples*2)+1]=0.0;
+                  samples++;
+                  if(samples==buffer_size) {
+                    full_tx_buffer();
+                    samples=0;
+                  }
+                }
+              }
+            }
+          }
+          freedv_samples++;
+          if(freedv_samples==freedv_divisor) {
+            freedv_samples=0;
           }
         } else {
 #endif
@@ -455,6 +477,10 @@ static void process_ozy_input_buffer(char  *buffer) {
           iqinputbuffer[samples*2]=0.0;
           iqinputbuffer[(samples*2)+1]=0.0;
           samples++;
+          if(samples==buffer_size) {
+            full_tx_buffer();
+            samples=0;
+          }
 #ifdef FREEDV
         }
 #endif
@@ -464,128 +490,147 @@ static void process_ozy_input_buffer(char  *buffer) {
         iqinputbuffer[samples*2]=(double)left_sample_float;
         iqinputbuffer[(samples*2)+1]=(double)right_sample_float;
         samples++;
+        if(samples==buffer_size) {
+          full_rx_buffer();
+          samples=0;
+        }
       }
+    }
+  } else {
+    time_t t;
+    struct tm* gmt;
+    time(&t);
+    gmt=gmtime(&t);
 
-      // when we have enough samples give them to WDSP and get the results
-      if(samples==buffer_size) {
-        int error;
-        if(isTransmitting()) {
-          if(tune) {
-            double tunefrequency = (double)((filterHigh - filterLow) / 2);
-            phase=sineWave(micinputbuffer, BUFFER_SIZE, phase, (float)tunefrequency);
-          }
-          // process the output
-          fexchange0(CHANNEL_TX, micinputbuffer, micoutputbuffer, &error);
-          if(error!=0) {
-            fprintf(stderr,"fexchange0 (CHANNEL_TX) returned error: %d\n", error);
-          }
-          Spectrum0(1, CHANNEL_TX, 0, 0, micoutputbuffer);
-          if(d->device!=DEVICE_METIS || atlas_penelope) {
-            if(tune) {
-              gain=65535.0*255.0/(double)tune_drive;
-            } else {
-              gain=65535.0*255.0/(double)drive;
-            }
-          } else {
-            gain=65535.0;
-          }
-          for(j=0;j<output_buffer_size;j++) {
-            left_rx_sample=0;
-            right_rx_sample=0;
-            left_tx_sample=(short)(micoutputbuffer[j*2]*gain*2);
-            right_tx_sample=(short)(micoutputbuffer[(j*2)+1]*gain*2);
-            output_buffer[output_buffer_index++]=left_rx_sample>>8;
-            output_buffer[output_buffer_index++]=left_rx_sample;
-            output_buffer[output_buffer_index++]=right_rx_sample>>8;
-            output_buffer[output_buffer_index++]=right_rx_sample;
-            output_buffer[output_buffer_index++]=left_tx_sample>>8;
-            output_buffer[output_buffer_index++]=left_tx_sample;
-            output_buffer[output_buffer_index++]=right_tx_sample>>8;
-            output_buffer[output_buffer_index++]=right_tx_sample;
-            if(output_buffer_index>=OZY_BUFFER_SIZE) {
-              ozy_send_buffer();
-              output_buffer_index=8;
-            }
-          }
-        } else {
-          // process the input
-          fexchange0(CHANNEL_RX0, iqinputbuffer, audiooutputbuffer, &error);
-          if(error!=0) {
-            fprintf(stderr,"fexchange2 (CHANNEL_RX0) returned error: %d\n", error);
-          }
-          Spectrum0(1, CHANNEL_RX0, 0, 0, iqinputbuffer);
+    fprintf(stderr,"%s: process_ozy_input_buffer: did not find sync\n",
+            asctime(gmt));
+    exit(1);
+  }
+}
 
+static void full_rx_buffer() {
+  int j;
+  int error;
 #ifdef FREEDV
-          if(mode==modeFREEDV) {
-            int demod_samples;
-            int increment=6; // 48000 to 8000
-            for(j=0;j<output_buffer_size;j+=increment) {
-              left_rx_sample=(short)(audiooutputbuffer[j*2]*32767.0*volume);
-              demod_samples=demod_sample_freedv(left_rx_sample);
-              if(demod_samples!=0) {
-                int s;
-                int t;
-                for(s=0;s<demod_samples;s++) {
-                  for(t=0;t<6;t++) { // 8k to 48k
-                    left_rx_sample=speech_out[s];
-                    right_rx_sample=speech_out[s];
-                    left_tx_sample=0;
-                    right_tx_sample=0;
-                   output_buffer[output_buffer_index++]=left_rx_sample>>8;
-                   output_buffer[output_buffer_index++]=left_rx_sample;
-                   output_buffer[output_buffer_index++]=right_rx_sample>>8;
-                   output_buffer[output_buffer_index++]=right_rx_sample;
-                   output_buffer[output_buffer_index++]=left_tx_sample>>8;
-                   output_buffer[output_buffer_index++]=left_tx_sample;
-                   output_buffer[output_buffer_index++]=right_tx_sample>>8;
-                   output_buffer[output_buffer_index++]=right_tx_sample;
-                   if(output_buffer_index>=OZY_BUFFER_SIZE) {
-                     ozy_send_buffer();
-                     output_buffer_index=8;
-                   }
-                  }
-                }
+  if(mode==modeFREEDV) {
+    // process the input
+    fexchange0(CHANNEL_RX0, iqinputbuffer, audiooutputbuffer, &error);
+    if(error!=0) {
+      fprintf(stderr,"fexchange2 (CHANNEL_RX0) returned error: %d\n", error);
+    }
+    Spectrum0(1, CHANNEL_RX0, 0, 0, iqinputbuffer);
+
+    int demod_samples;
+    for(j=0;j<output_buffer_size;j++) {
+      if(freedv_samples==0) {
+        left_rx_sample=(short)(audiooutputbuffer[j*2]*32767.0*volume);
+        right_rx_sample=(short)(audiooutputbuffer[(j*2)+1]*32767.0*volume);
+        demod_samples=demod_sample_freedv(left_rx_sample);
+        if(demod_samples!=0) {
+          int s;
+          int t;
+          for(s=0;s<demod_samples;s++) {
+            for(t=0;t<6;t++) { // 8k to 48k
+              if(freedv_sync) {
+                left_rx_sample=right_rx_sample=(short)((double)speech_out[s]*volume);
+              } else {
+                left_rx_sample=right_rx_sample=0;
               }
-            }
-          } else {
-#endif
-            for(j=0;j<output_buffer_size;j++) {
-              left_rx_sample=(short)(audiooutputbuffer[j*2]*32767.0*volume);
-              right_rx_sample=(short)(audiooutputbuffer[(j*2)+1]*32767.0*volume);
-              left_tx_sample=0;
-              right_tx_sample=0;
               output_buffer[output_buffer_index++]=left_rx_sample>>8;
               output_buffer[output_buffer_index++]=left_rx_sample;
               output_buffer[output_buffer_index++]=right_rx_sample>>8;
               output_buffer[output_buffer_index++]=right_rx_sample;
+              left_tx_sample=right_tx_sample=0;
               output_buffer[output_buffer_index++]=left_tx_sample>>8;
-              output_buffer[output_buffer_index++]=left_tx_sample;
-              output_buffer[output_buffer_index++]=right_tx_sample>>8;
-              output_buffer[output_buffer_index++]=right_tx_sample;
-              if(output_buffer_index>=OZY_BUFFER_SIZE) {
-                ozy_send_buffer();
-                output_buffer_index=8;
-              }
+             output_buffer[output_buffer_index++]=left_tx_sample;
+             output_buffer[output_buffer_index++]=right_tx_sample>>8;
+             output_buffer[output_buffer_index++]=right_tx_sample;
+             if(output_buffer_index>=OZY_BUFFER_SIZE) {
+               ozy_send_buffer();
+               output_buffer_index=8;
+             }
             }
-#ifdef FREEDV
           }
-#endif
         }
-        samples=0;
+      }
+      freedv_samples++;
+      if(freedv_samples==freedv_divisor) {
+        freedv_samples=0;
       }
     }
   } else {
-    time_t t;
-    struct tm* gmt;
-    time(&t);
-    gmt=gmtime(&t);
-
-    fprintf(stderr,"%s: process_ozy_input_buffer: did not find sync\n",
-            asctime(gmt));
-    exit(1);
+#endif
+    // process the input
+    fexchange0(CHANNEL_RX0, iqinputbuffer, audiooutputbuffer, &error);
+    if(error!=0) {
+      fprintf(stderr,"fexchange2 (CHANNEL_RX0) returned error: %d\n", error);
+    }
+    Spectrum0(1, CHANNEL_RX0, 0, 0, iqinputbuffer);
+    for(j=0;j<output_buffer_size;j++) {
+      left_rx_sample=(short)(audiooutputbuffer[j*2]*32767.0*volume);
+      right_rx_sample=(short)(audiooutputbuffer[(j*2)+1]*32767.0*volume);
+      left_tx_sample=0;
+      right_tx_sample=0;
+      output_buffer[output_buffer_index++]=left_rx_sample>>8;
+      output_buffer[output_buffer_index++]=left_rx_sample;
+      output_buffer[output_buffer_index++]=right_rx_sample>>8;
+      output_buffer[output_buffer_index++]=right_rx_sample;
+      output_buffer[output_buffer_index++]=left_tx_sample>>8;
+      output_buffer[output_buffer_index++]=left_tx_sample;
+      output_buffer[output_buffer_index++]=right_tx_sample>>8;
+      output_buffer[output_buffer_index++]=right_tx_sample;
+      if(output_buffer_index>=OZY_BUFFER_SIZE) {
+        ozy_send_buffer();
+        output_buffer_index=8;
+      }
+    }
+#ifdef FREEDV
   }
+#endif
 }
 
+static void full_tx_buffer() {
+  int j;
+  int error;
+  double gain;
+  if(tune) {
+    double tunefrequency = (double)((filterHigh - filterLow) / 2);
+    phase=sineWave(micinputbuffer, BUFFER_SIZE, phase, (float)tunefrequency);
+  }
+  // process the output
+  fexchange0(CHANNEL_TX, micinputbuffer, micoutputbuffer, &error);
+  if(error!=0) {
+    fprintf(stderr,"fexchange0 (CHANNEL_TX) returned error: %d\n", error);
+  }
+  Spectrum0(1, CHANNEL_TX, 0, 0, micoutputbuffer);
+  if(d->device!=DEVICE_METIS || atlas_penelope) {
+    if(tune) {
+      gain=65535.0*255.0/(double)tune_drive;
+    } else {
+      gain=65535.0*255.0/(double)drive;
+    }
+  } else {
+    gain=65535.0;
+  }
+  for(j=0;j<output_buffer_size;j++) {
+    left_rx_sample=0;
+    right_rx_sample=0;
+    left_tx_sample=(short)(micoutputbuffer[j*2]*gain*2);
+    right_tx_sample=(short)(micoutputbuffer[(j*2)+1]*gain*2);
+    output_buffer[output_buffer_index++]=left_rx_sample>>8;
+    output_buffer[output_buffer_index++]=left_rx_sample;
+    output_buffer[output_buffer_index++]=right_rx_sample>>8;
+    output_buffer[output_buffer_index++]=right_rx_sample;
+    output_buffer[output_buffer_index++]=left_tx_sample>>8;
+    output_buffer[output_buffer_index++]=left_tx_sample;
+    output_buffer[output_buffer_index++]=right_tx_sample>>8;
+    output_buffer[output_buffer_index++]=right_tx_sample;
+    if(output_buffer_index>=OZY_BUFFER_SIZE) {
+      ozy_send_buffer();
+      output_buffer_index=8;
+    }
+  }
+}
 /*
 static void process_bandscope_buffer(char  *buffer) {
 }
index 95490b836c2b2f6d9a17365241ccb0dae4849d88..fbe109b894ac11a0b70a5fea1009c2945702a310 100644 (file)
 #include "radio.h"
 #include "panadapter.h"
 #include "vfo.h"
+#ifdef FREEDV
+#include "mode.h"
+#include "freedv.h"
+#endif
 
 static GtkWidget *panadapter;
 static cairo_surface_t *panadapter_surface = NULL;
@@ -124,7 +128,7 @@ panadapter_button_release_event_cb (GtkWidget      *widget,
       vfo_move((int)((float)(x-last_x)*hz_per_pixel));
     } else {
       // move to this frequency
-      vfo_move((int)((float)(x-(display_width/2))*hz_per_pixel));
+      vfo_move_to((int)((float)(x-(display_width/2))*hz_per_pixel));
     }
     last_x=x;
     pressed=FALSE;
@@ -199,7 +203,14 @@ void panadapter_update(float *data,int tx) {
                 } else {
                     hz_per_pixel=192000.0/(double)display_width;
                 }
-            }
+            } /* else if(mode==modeFREEDV) {
+                saved_max=panadapter_high;
+                saved_min=panadapter_low;
+                saved_hz_per_pixel=hz_per_pixel;
+                panadapter_high=20;
+                panadapter_low=-100;
+                hz_per_pixel=48000.0/(double)display_width;
+            } */
 
             //clear_panadater_surface();
             cairo_t *cr;
@@ -209,8 +220,8 @@ void panadapter_update(float *data,int tx) {
 
             // filter
             cairo_set_source_rgb (cr, 0.25, 0.25, 0.25);
-            filter_left=(double)display_width/2.0+((double)getFilterLow()/hz_per_pixel);
-            filter_right=(double)display_width/2.0+((double)getFilterHigh()/hz_per_pixel);
+            filter_left=(double)display_width/2.0+(((double)getFilterLow()+ddsOffset)/hz_per_pixel);
+            filter_right=(double)display_width/2.0+(((double)getFilterHigh()+ddsOffset)/hz_per_pixel);
             cairo_rectangle(cr, filter_left, 0.0, filter_right-filter_left, (double)panadapter_height);
             cairo_fill(cr);
 
@@ -248,6 +259,7 @@ void panadapter_update(float *data,int tx) {
                 divisor=5000L;
                 break;
               case 96000:
+              case 100000:
                 divisor=10000L;
                 break;
               case 192000:
@@ -259,7 +271,9 @@ void panadapter_update(float *data,int tx) {
               case 768000:
                 divisor=50000L;
                 break;
+              case 1048576:
               case 1536000:
+              case 2097152:
                 divisor=100000L;
                 break;
             }
@@ -340,15 +354,30 @@ void panadapter_update(float *data,int tx) {
             cairo_set_line_width(cr, 1.0);
             cairo_stroke(cr);
 
+#ifdef FREEDV
+            if(mode==modeFREEDV) {
+              cairo_set_source_rgb(cr, 0, 0, 0);
+              cairo_rectangle(cr, (double)display_width/2.0+2.0, (double)panadapter_height-20.0, (double)display_width, (double)panadapter_height);
+              cairo_fill(cr);
+              cairo_set_source_rgb(cr, 0, 1, 0);
+              cairo_set_font_size(cr, 16);
+              cairo_move_to(cr,(double)display_width/2.0+5.0,(double)panadapter_height-2.0);
+              cairo_show_text(cr, freedv_rx_text_data);
+            }
+#endif
+
             cairo_destroy (cr);
             gtk_widget_queue_draw (panadapter);
 
             if(tx) {
-                panadapter_high=saved_max;
-                panadapter_low=saved_min;
-                hz_per_pixel=saved_hz_per_pixel;
-            }
-
+              panadapter_high=saved_max;
+              panadapter_low=saved_min;
+              hz_per_pixel=saved_hz_per_pixel;
+            } /* else if(mode==modeFREEDV) {
+              panadapter_high=saved_max;
+              panadapter_low=saved_min;
+              hz_per_pixel=saved_hz_per_pixel;
+            } */
         }
     //}
 }
diff --git a/pihpsdr b/pihpsdr
index 0d93d75eba890aca74d95d7fa8d238d60ee3c68a..5caddc8cd7d00fa637cef8c4b978c988b93851ec 100755 (executable)
Binary files a/pihpsdr and b/pihpsdr differ
diff --git a/radio.c b/radio.c
index 657811f0d2d4248fdc0d4d4b1ecf402d2fed2c44..5570dc35c0ba47ca710e7f8e12ceeb4cf2881ae9 100644 (file)
--- a/radio.c
+++ b/radio.c
 #include "discovered.h"
 #include "property.h"
 #include "new_protocol.h"
+#ifdef LIMESDR
+#include "lime_protocol.h"
+#endif
 #include "wdsp.h"
+#ifdef FREEDV
+#include "freedv.h"
+#endif
 
 #define min(x,y) (x<y?x:y)
 #define max(x,y) (x<y?y:x)
@@ -162,12 +168,17 @@ int mox;
 int tune;
 
 long long ddsFrequency=14250000;
+long long ddsOffset=0;
 
 unsigned char OCtune=0;
 int OCfull_tune_time=2800; // ms
 int OCmemory_tune_time=550; // ms
 long long tune_timeout;
 
+#ifdef FREEDV
+char freedv_tx_text_data[64];
+#endif
+
 void init_radio() {
   int rc;
   rc=sem_init(&property_sem, 0, 0);
@@ -194,6 +205,11 @@ fprintf(stderr,"setMox: protocol=%d\n", protocol);
       schedule_high_priority(3);
     }
     if(mox) {
+#ifdef FREEDV
+      if(mode==modeFREEDV) {
+        freedv_reset_tx_text_index();
+      }
+#endif
       SetChannelState(CHANNEL_RX0,0,1);
       SetChannelState(CHANNEL_TX,1,0);
     } else {
@@ -241,12 +257,47 @@ int isTransmitting() {
 }
 
 void setFrequency(long long f) {
+  BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
+
+  if(entry->frequencyA!=f) {
+    switch(protocol) {
+      case NEW_PROTOCOL:
+      case ORIGINAL_PROTOCOL:
+        entry->frequencyA=f;
+        break;
+#ifdef LIMESDR
+      case LIMESDR_PROTOCOL:
+        {
+        long long minf=entry->frequencyA-(long long)(sample_rate/2);
+        long long maxf=entry->frequencyA+(long long)(sample_rate/2);
+        if(f<minf) f=minf;
+        if(f>maxf) f=maxf;
+        ddsOffset=f-entry->frequencyA;
+fprintf(stderr,"radio.c: setFrequency: ddsOffset=%lld\n",ddsOffset);
+        wdsp_set_offset(ddsOffset);
+        return;
+        }
+        break;
+#endif
+    }
+  }
+
 //fprintf(stderr,"setFrequency: protocol=%d f=%lld\n", protocol, f);
   ddsFrequency=f;
-  if(protocol==NEW_PROTOCOL) {
-    schedule_high_priority(5);
-  } else {
-    schedule_frequency_changed();
+  switch(protocol) {
+    case NEW_PROTOCOL:
+      schedule_high_priority(5);
+      break;
+    case ORIGINAL_PROTOCOL:
+      schedule_frequency_changed();
+      break;
+#ifdef LIMESDR
+    case LIMESDR_PROTOCOL:
+      lime_protocol_set_frequency(f);
+      ddsOffset=0;
+      wdsp_set_offset(ddsOffset);
+      break;
+#endif
   }
 }
 
@@ -279,8 +330,15 @@ fprintf(stderr,"setTuneDrive: protocol=%d\n", protocol);
 
 void set_attenuation(int value) {
     //attenuation=value;
-    if(protocol==NEW_PROTOCOL) {
+    switch(protocol) {
+      case NEW_PROTOCOL:
         schedule_high_priority(8);
+        break;
+#ifdef LIMESDR
+      case LIMESDR_PROTOCOL:
+        lime_protocol_set_attenuation(value);
+        break;
+#endif
     }
 }
 
@@ -293,6 +351,11 @@ void set_alex_rx_antenna(int v) {
     if(protocol==NEW_PROTOCOL) {
         schedule_high_priority(1);
     }
+#ifdef LIMESDR
+    if(protocol==LIMESDR_PROTOCOL) {
+        lime_protocol_set_antenna(v);;
+    }
+#endif
 }
 
 void set_alex_tx_antenna(int v) {
@@ -439,7 +502,10 @@ void radioRestoreState() {
     if(value) rx_random=atoi(value);
     value=getProperty("rx_preamp");
     if(value) rx_preamp=atoi(value);
-
+#ifdef FREEDV
+    value=getProperty("freedv_tx_text_data");
+    if(value) strcpy(freedv_tx_text_data,value);
+#endif
     bandRestoreState();
     sem_post(&property_sem);
 }
@@ -570,7 +636,11 @@ void radioSaveState() {
     setProperty("rx_random",value);
     sprintf(value,"%d",rx_preamp);
     setProperty("rx_preamp",value);
-
+#ifdef FREEDV
+    if(strlen(freedv_tx_text_data)>0) {
+      setProperty("freedv_tx_text_data",freedv_tx_text_data);
+    }
+#endif
     bandSaveState();
 
     saveProperties(property_path);
diff --git a/radio.h b/radio.h
index ab23048ca639d931971faa7e8fea5bef5e481e5c..c1d6aed00220e9819c57ec74d776d5109f677625 100644 (file)
--- a/radio.h
+++ b/radio.h
@@ -175,12 +175,17 @@ extern unsigned int AIN6;
 extern int supply_volts;
 
 extern long long ddsFrequency;
+extern long long ddsOffset;
 
 extern unsigned char OCtune;
 extern int OCfull_tune_time;
 extern int OCmemory_tune_time;
 extern long long tune_timeout;
 
+#ifdef FREEDV
+extern char freedv_tx_text_data[64];
+#endif
+
 extern void init_radio();
 extern void setSampleRate(int rate);
 extern int getSampleRate();
index 8247a5e212f607f7cd03b637d22c4ea1666b71e6..3382e1f6998d07dc8e3797e0ed3c425493eeb077 100644 (file)
Binary files a/release/pihpsdr.tar and b/release/pihpsdr.tar differ
index 0d93d75eba890aca74d95d7fa8d238d60ee3c68a..5caddc8cd7d00fa637cef8c4b978c988b93851ec 100755 (executable)
Binary files a/release/pihpsdr/pihpsdr and b/release/pihpsdr/pihpsdr differ
index 3c413c9702e7fa43fa85a04c762d8ba86f2ee641..6793b331a3f47fc69b76e40f7ab46bd864840d75 100644 (file)
--- a/toolbar.c
+++ b/toolbar.c
@@ -20,8 +20,9 @@
 #include <gtk/gtk.h>
 #include <semaphore.h>
 #include <stdio.h>
-
+#ifdef INCLUDE_GPIO
 #include "gpio.h"
+#endif
 #include "toolbar.h"
 #include "mode.h"
 #include "filter.h"
@@ -440,7 +441,9 @@ static void stop() {
   } else {
     new_protocol_stop();
   }
+#ifdef INCLUDE_GPIO
   gpio_close();
+#endif
 }
 
 static void yes_cb(GtkWidget *widget, gpointer data) {
@@ -868,6 +871,7 @@ fprintf(stderr,"sim_mode_cb\n");
   }
   setMode(entry->mode);
 
+fprintf(stderr,"sim_mode_cb: entry->mode=%d entry->filter=%d\n",entry->mode,entry->filter);
   FILTER* band_filters=filters[entry->mode];
   FILTER* band_filter=&band_filters[entry->filter];
   setFilter(band_filter->low,band_filter->high);
@@ -895,6 +899,7 @@ fprintf(stderr,"sim_filter_cb\n");
     }
   }
 
+fprintf(stderr,"sim_filter_cb: entry->mode=%d entry->filter=%d\n",entry->mode,entry->filter);
   FILTER* band_filters=filters[entry->mode];
   FILTER* band_filter=&band_filters[entry->filter];
   setFilter(band_filter->low,band_filter->high);
diff --git a/vfo.c b/vfo.c
index c3f2a16e97d1639579e8562f2966e0a5ea2f05a9..0cf2fc2333ae8b012f0825f09995389c73f795cf 100644 (file)
--- a/vfo.c
+++ b/vfo.c
@@ -39,6 +39,7 @@
 #include "channel.h"
 #include "toolbar.h"
 #include "wdsp.h"
+#include "wdsp_init.h"
 
 static GtkWidget *parent_window;
 static int my_width;
@@ -56,8 +57,9 @@ static GtkWidget* band_menu=NULL;
 void vfo_step(int steps) {
   if(!locked) {
     BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
-    entry->frequencyA=entry->frequencyA+(steps*step);
-    setFrequency(entry->frequencyA);
+    //entry->frequencyA=entry->frequencyA+(steps*step);
+    //setFrequency(entry->frequencyA);
+    setFrequency(entry->frequencyA+(steps*step));
     vfo_update(NULL);
   }
 }
@@ -65,12 +67,24 @@ void vfo_step(int steps) {
 void vfo_move(int hz) {
   if(!locked) {
     BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
-    entry->frequencyA=(entry->frequencyA+hz)/step*step;
-    setFrequency(entry->frequencyA);
+    //entry->frequencyA=(entry->frequencyA+hz)/step*step;
+    //setFrequency(entry->frequencyA);
+    //setFrequency((entry->frequencyA+ddsOffset+hz)/step*step);
+    setFrequency((entry->frequencyA+ddsOffset-hz)/step*step);
+    vfo_update(NULL);
+  }
+}
+void vfo_move_to(int hz) {
+  if(!locked) {
+    BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
+    //entry->frequencyA=(entry->frequencyA+hz)/step*step;
+    //setFrequency(entry->frequencyA);
+    setFrequency((entry->frequencyA+hz)/step*step);
     vfo_update(NULL);
   }
 }
 
+
 static gboolean vfo_configure_event_cb (GtkWidget         *widget,
             GdkEventConfigure *event,
             gpointer           data)
@@ -92,6 +106,8 @@ fprintf(stderr,"vfo_configure_event_cb: width=%d height=%d\n",
   cairo_set_source_rgb (cr, 0, 0, 0);
   cairo_paint (cr);
 
+  g_idle_add(vfo_update,NULL);
+
   /* We've handled the configure event, no need for further processing. */
   return TRUE;
 }
@@ -128,18 +144,22 @@ int vfo_update(void *data) {
             cairo_set_source_rgb(cr, 0, 1, 0);
         }
 
+        long long f=entry->frequencyA+ddsOffset;
+
         char sf[32];
-        sprintf(sf,"%0lld.%06lld MHz",entry->frequencyA/(long long)1000000,entry->frequencyA%(long long)1000000);
+        //sprintf(sf,"%0lld.%06lld MHz",entry->frequencyA/(long long)1000000,entry->frequencyA%(long long)1000000);
+        sprintf(sf,"%0lld.%06lld MHz",f/(long long)1000000,f%(long long)1000000);
         cairo_move_to(cr, 5, 30);  
         cairo_show_text(cr, sf);
 
         cairo_set_font_size(cr, 12);
 
-        cairo_move_to(cr, (my_width/2)+20, 30);  
-        cairo_show_text(cr, getFrequencyInfo(entry->frequencyA));
+        cairo_move_to(cr, (my_width/2)+40, 30);  
+        //cairo_show_text(cr, getFrequencyInfo(entry->frequencyA));
+        cairo_show_text(cr, getFrequencyInfo(f));
 
         sprintf(sf,"Step %dHz",step);
-        cairo_move_to(cr, (my_width/2)+20, 15);  
+        cairo_move_to(cr, (my_width/2)+40, 15);  
         cairo_show_text(cr, sf);
 
         if(locked) {
@@ -202,6 +222,8 @@ int vfo_update(void *data) {
 
         cairo_destroy (cr);
         gtk_widget_queue_draw (vfo);
+    } else {
+fprintf(stderr,"vfo_update: no surface!\n");
     }
     return 0;
 }
@@ -281,6 +303,7 @@ fprintf(stderr,"vfo_init: width=%d height=%d\n", width, height);
   gtk_widget_set_events (vfo, gtk_widget_get_events (vfo)
                      | GDK_BUTTON_PRESS_MASK);
 
+fprintf(stderr,"vfo_init: set Frequency,Mode,Filter\n");
   BAND *band=band_get_current_band();
   BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
   setFrequency(entry->frequencyA);
index 994e3fabc9c576cd8e52488022986734158060bf..76d84c4cc302b19b3126b571733f5f0d2f1f9c9c 100644 (file)
@@ -63,6 +63,7 @@ static int tx_buffer_size=BUFFER_SIZE;
 static int fft_size=4096;
 static int dspRate=48000;
 static int outputRate=48000;
+static int dvOutputRate=8000;
 
 static int micSampleRate=48000;
 static int micDspRate=48000;
@@ -73,25 +74,32 @@ static int SPECTRUM_UPDATES_PER_SECOND=10;
 
 static void initAnalyzer(int channel,int buffer_size);
 
-void setRXMode(int m) {
-    SetRXAMode(receiver, mode==modeFREEDV?modeUSB:mode);
+void setRXMode(int rx,int m) {
+fprintf(stderr,"SetRXAMode: rx=%d mode=%d\n",rx,m);
+  SetRXAMode(rx, m);
 }
 
-void setTXMode(int m) {
-    SetTXAMode(CHANNEL_TX, mode==modeFREEDV?modeUSB:mode);
+void setTXMode(int tx,int m) {
+fprintf(stderr,"SetTXAMode: tx=%d mode=%d\n",tx,m);
+  SetTXAMode(tx, m);
 }
 
 void setMode(int m) {
+fprintf(stderr,"setMode: mode=%d m=%d\n",mode,m);
+int local_mode=m;
 #ifdef FREEDV
     if(mode!=modeFREEDV && m==modeFREEDV) {
+      local_mode=modeUSB;
       init_freedv();
-    } if(mode==modeFREEDV && m!=modeFREEDV) {
+    } else if(mode==modeFREEDV && m!=modeFREEDV) {
       close_freedv();
     }
 #endif
+fprintf(stderr,"setMode: %d mode=%d\n",receiver,mode);
+    setRXMode(receiver,local_mode);
+fprintf(stderr,"setMode: %d mode=%d\n",CHANNEL_TX,mode);
+    setTXMode(CHANNEL_TX,local_mode);
     mode=m;
-    setRXMode(m);
-    setTXMode(m);
 }
 
 int getMode() {
@@ -99,6 +107,7 @@ int getMode() {
 }
 
 void setFilter(int low,int high) {
+fprintf(stderr,"setFilter: %d %d\n",low,high);
     if(mode==modeCWL) {
         filterLow=-cwPitch-low;
         filterHigh=-cwPitch+high;
@@ -110,11 +119,15 @@ void setFilter(int low,int high) {
         filterHigh=high;
     }
 
+    double fl=filterLow+ddsOffset;
+    double fh=filterHigh+ddsOffset;
+
+fprintf(stderr,"setFilter: fl=%f fh=%f\n",fl,fh);
     RXANBPSetFreqs(receiver,(double)filterLow,(double)filterHigh);
-    SetRXABandpassFreqs(receiver, (double)filterLow, (double)filterHigh);
+    SetRXABandpassFreqs(receiver, fl,fh);
     SetRXASNBAOutputBandwidth(receiver, (double)filterLow, (double)filterHigh);
 
-    SetTXABandpassFreqs(CHANNEL_TX, (double)filterLow, (double)filterHigh);
+    SetTXABandpassFreqs(CHANNEL_TX, fl,fh);
 }
 
 int getFilterLow() {
@@ -125,6 +138,62 @@ int getFilterHigh() {
     return filterHigh;
 }
 
+void wdsp_set_offset(long long offset) {
+    if(offset==0) {
+      SetRXAShiftFreq(receiver, (double)offset);
+      SetRXAShiftRun(receiver, 0);
+    } else {
+      SetRXAShiftFreq(receiver, (double)offset);
+      SetRXAShiftRun(receiver, 1);
+    }
+
+    setFilter(filterLow,filterHigh);
+}
+
+void wdsp_set_input_rate(double rate) {
+    SetInputSamplerate(receiver, (int)rate);
+}
+
+static void setupRX(int rx) {
+    setRXMode(rx,mode);
+    SetRXABandpassFreqs(rx, (double)filterLow, (double)filterHigh);
+    SetRXAAGCMode(rx, agc);
+    SetRXAAGCTop(rx,agc_gain);
+
+    SetRXAAMDSBMode(rx, 0);
+    SetRXAShiftRun(rx, 0);
+
+    SetRXAEMNRPosition(rx, nr_agc);
+    SetRXAEMNRgainMethod(rx, nr2_gain_method);
+    SetRXAEMNRnpeMethod(rx, nr2_npe_method);
+    SetRXAEMNRRun(rx, nr2);
+    SetRXAEMNRaeRun(rx, nr2_ae);
+
+    SetRXAANRVals(rx, 64, 16, 16e-4, 10e-7); // defaults
+    SetRXAANRRun(rx, nr);
+    SetRXAANFRun(rx, anf);
+    SetRXASNBARun(rx, snb);
+}
+
+static void setupTX(int tx) {
+    setTXMode(tx,mode);
+    SetTXABandpassFreqs(tx, (double)filterLow, (double)filterHigh);
+    SetTXABandpassWindow(tx, 1);
+    SetTXABandpassRun(tx, 1);
+
+    SetTXACFIRRun(tx, 1);
+    SetTXAEQRun(tx, 0);
+    SetTXACTCSSRun(tx, 0);
+    SetTXAAMSQRun(tx, 0);
+    SetTXACompressorRun(tx, 0);
+    SetTXAosctrlRun(tx, 0);
+    SetTXAPreGenRun(tx, 0);
+    SetTXAPostGenRun(tx, 0);
+
+    SetChannelState(tx,1,0);
+    SetChannelState(tx,1,0);
+}
+
 void wdsp_init(int rx,int pixels,int protocol) {
     int rc;
     receiver=rx;
@@ -159,6 +228,7 @@ void wdsp_init(int rx,int pixels,int protocol) {
                 1, // run
                 0.010, 0.025, 0.0, 0.010, 0);
 
+
     while (gtk_events_pending ())
       gtk_main_iteration ();
 
@@ -221,41 +291,8 @@ void wdsp_init(int rx,int pixels,int protocol) {
         }
     initAnalyzer(CHANNEL_TX,tx_buffer_size);
 
-    setRXMode(mode);
-    SetRXABandpassFreqs(rx, (double)filterLow, (double)filterHigh);
-    SetRXAAGCMode(rx, agc);
-    SetRXAAGCTop(rx,agc_gain);
-
-    SetRXAAMDSBMode(CHANNEL_RX0, 0);
-    SetRXAShiftRun(CHANNEL_RX0, 0);
-
-    SetRXAEMNRPosition(CHANNEL_RX0, nr_agc);
-    SetRXAEMNRgainMethod(CHANNEL_RX0, nr2_gain_method);
-    SetRXAEMNRnpeMethod(CHANNEL_RX0, nr2_npe_method);
-    SetRXAEMNRRun(CHANNEL_RX0, nr2);
-    SetRXAEMNRaeRun(CHANNEL_RX0, nr2_ae);
-
-    SetRXAANRVals(CHANNEL_RX0, 64, 16, 16e-4, 10e-7); // defaults
-    SetRXAANRRun(CHANNEL_RX0, nr);
-    SetRXAANFRun(CHANNEL_RX0, anf);
-    SetRXASNBARun(CHANNEL_RX0, snb);
-
-    setTXMode(mode);
-    SetTXABandpassFreqs(CHANNEL_TX, (double)filterLow, (double)filterHigh);
-    SetTXABandpassWindow(CHANNEL_TX, 1);
-    SetTXABandpassRun(CHANNEL_TX, 1);
-
-    SetTXACFIRRun(CHANNEL_TX, 1);
-    SetTXAEQRun(CHANNEL_TX, 0);
-    SetTXACTCSSRun(CHANNEL_TX, 0);
-    SetTXAAMSQRun(CHANNEL_TX, 0);
-    SetTXACompressorRun(CHANNEL_TX, 0);
-    SetTXAosctrlRun(CHANNEL_TX, 0);
-    SetTXAPreGenRun(CHANNEL_TX, 0);
-    SetTXAPostGenRun(CHANNEL_TX, 0);
-
-    SetChannelState(CHANNEL_TX,1,0);
-    SetChannelState(CHANNEL_RX0,1,0);
+    setupRX(rx);
+    setupTX(CHANNEL_TX);
 
 }
 
index 041737d8f2e02a6684120532181270ccaf603024..80325219c2f861f5fff19d6e2b1577a063a78a1c 100644 (file)
@@ -17,6 +17,8 @@
 *
 */
 
+extern void wdsp_set_input_rate(double rate);
+extern void wdsp_set_offset(long long offset);
 extern void setMode(int m);
 extern int getMode();
 extern void setFilter(int low,int high);