]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
added psk31 receive. switched slider values back to 0..100 from 0..255. Various other...
authorJohn Melton - G0ORX/N6LYT <john.d.melton@googlemail.com>
Fri, 5 Aug 2016 14:21:04 +0000 (14:21 +0000)
committerJohn Melton - G0ORX/N6LYT <john.d.melton@googlemail.com>
Fri, 5 Aug 2016 14:21:04 +0000 (14:21 +0000)
33 files changed:
Makefile
channel.h
configure.c
filter.c
freedv.c
freedv.h
gpio.c
gpio_mraa.c
main.c
main.h
menu.c
meter.c
mode.c
mode.h
new_protocol.c
old_protocol.c
panadapter.c
pihpsdr
psk.c [new file with mode: 0644]
psk.h [new file with mode: 0644]
psk_waterfall.c [new file with mode: 0644]
psk_waterfall.h [new file with mode: 0644]
radio.c
radio.h
release/pihpsdr.tar
release/pihpsdr/install.sh
release/pihpsdr/libpsk.so [new file with mode: 0755]
release/pihpsdr/pihpsdr
signal.c [new file with mode: 0644]
signal.h [new file with mode: 0644]
sliders.c
toolbar.c
wdsp_init.c

index 1be41a45e427804ca04bf83c128b7a366a38826b..92c9f4406d4c8b6f4f74236cfd1daad8aa3aabc7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,6 +2,13 @@
 GIT_VERSION := $(shell git --no-pager describe --tags --always --dirty)
 GIT_DATE := $(firstword $(shell git --no-pager show --date=short --format="%ai" --name-only))
 
+# uncomment the line below to include support for psk31
+PSK_INCLUDE=PSK
+
+# uncomment the line to below include support for FreeDV codec2
+FREEDV_INCLUDE=FREEDV
+
+#uncomment the line below for the platform being compiled on
 UNAME_N=raspberrypi
 #UNAME_N=odroid
 #UNAME_N=up
@@ -11,7 +18,7 @@ UNAME_N=raspberrypi
 CC=gcc
 LINK=gcc
 
-#required for LimeSDR (uncomment line below)
+# uncomment the line below for LimeSDR (uncomment line below)
 #LIMESDR_INCLUDE=LIMESDR
 
 ifeq ($(LIMESDR_INCLUDE),LIMESDR)
@@ -29,8 +36,20 @@ lime_protocol.o
 endif
 
 
-#required for FREEDV (uncomment lines below)
-FREEDV_INCLUDE=FREEDV
+ifeq ($(PSK_INCLUDE),PSK)
+PSK_OPTIONS=-D PSK
+PSKLIBS=-lpsk
+PSK_SOURCES= \
+psk.c \
+psk_waterfall.c
+PSK_HEADERS= \
+psk.h \
+psk_waterfall.h
+PSK_OBJS= \
+psk.o \
+psk_waterfall.o
+endif
+
 
 ifeq ($(FREEDV_INCLUDE),FREEDV)
 FREEDV_OPTIONS=-D FREEDV
@@ -47,6 +66,7 @@ endif
 #MRAA_INCLUDE=MRAA
 
 ifeq ($(MRAA_INCLUDE),MRAA)
+  GPIO_OPTIONS=-D GPIO
   GPIO_LIBS=-lmraa
   GPIO_SOURCES= \
   gpio_mraa.c
@@ -56,6 +76,7 @@ ifeq ($(MRAA_INCLUDE),MRAA)
   gpio_mraa.o
 else
   ifeq ($(UNAME_N),raspberrypi)
+  GPIO_OPTIONS=-D GPIO
   GPIO_LIBS=-lwiringPi -lpigpio
   endif
   ifeq ($(UNAME_N),odroid)
@@ -69,12 +90,12 @@ else
   gpio.o
 endif
 
-OPTIONS=-g -D $(UNAME_N) $(LIMESDR_OPTIONS) $(FREEDV_OPTIONS) -D GIT_DATE='"$(GIT_DATE)"' -D GIT_VERSION='"$(GIT_VERSION)"' -O3
+OPTIONS=-g -D $(UNAME_N) $(GPIO_OPTIONS) $(LIMESDR_OPTIONS) $(FREEDV_OPTIONS) $(PSK_OPTIONS) -D GIT_DATE='"$(GIT_DATE)"' -D GIT_VERSION='"$(GIT_VERSION)"' -O3
 
 GTKINCLUDES=`pkg-config --cflags gtk+-3.0`
 GTKLIBS=`pkg-config --libs gtk+-3.0`
 
-LIBS=-lrt -lm -lwdsp -lpthread -lpulse-simple -lpulse $(GTKLIBS) $(GPIO_LIBS) $(SOAPYSDRLIBS) $(FREEDVLIBS)
+LIBS=-lrt -lm -lwdsp -lpthread -lpulse-simple -lpulse $(PSKLIBS) $(GTKLIBS) $(GPIO_LIBS) $(SOAPYSDRLIBS) $(FREEDVLIBS)
 INCLUDES=$(GTKINCLUDES)
 
 COMPILE=$(CC) $(OPTIONS) $(INCLUDES)
@@ -100,6 +121,7 @@ new_protocol_programmer.c \
 panadapter.c \
 property.c \
 radio.c \
+signal.c \
 splash.c \
 toolbar.c \
 sliders.c \
@@ -130,6 +152,7 @@ new_protocol.h \
 panadapter.h \
 property.h \
 radio.h \
+signal.h \
 splash.h \
 toolbar.h \
 sliders.h \
@@ -160,6 +183,7 @@ new_protocol_programmer.o \
 panadapter.o \
 property.o \
 radio.o \
+signal.o \
 splash.o \
 toolbar.o \
 sliders.o \
@@ -167,13 +191,13 @@ vfo.o \
 waterfall.o \
 wdsp_init.o
 
-all: prebuild $(PROGRAM) $(HEADERS) $(LIMESDR_HEADERS) $(FREEDV_HEADERS) $(GPIO_HEADERS) $(SOURCES) $(LIMESDR_SOURCES) $(FREEDV_SOURCES) $(GPIO_SOURCES)
+all: prebuild $(PROGRAM) $(HEADERS) $(LIMESDR_HEADERS) $(FREEDV_HEADERS) $(GPIO_HEADERS) $(PSK_HEADERS) $(SOURCES) $(LIMESDR_SOURCES) $(FREEDV_SOURCES) $(GPIO_SOURCES) $(PSK_SOURCES)
 
 prebuild:
        rm -f version.o
 
-$(PROGRAM): $(OBJS) $(LIMESDR_OBJS) $(FREEDV_OBJS) $(GPIO_OBJS)
-       $(LINK) -o $(PROGRAM) $(OBJS) $(GPIO_OBJS) $(LIMESDR_OBJS) $(FREEDV_OBJS) $(LIBS)
+$(PROGRAM): $(OBJS) $(LIMESDR_OBJS) $(FREEDV_OBJS) $(GPIO_OBJS) $(PSK_OBJS)
+       $(LINK) -o $(PROGRAM) $(OBJS) $(GPIO_OBJS) $(LIMESDR_OBJS) $(FREEDV_OBJS) $(PSK_OBJS) $(LIBS)
 
 .c.o:
        $(COMPILE) -c -o $@ $<
index 877f7a0ee47cf7a420c58228b997d9745ab2665f..f4c0c5792490de271b30cb612ae36cafdddbd465 100644 (file)
--- a/channel.h
+++ b/channel.h
@@ -28,4 +28,7 @@
 #define CHANNEL_TX 8
 #define CHANNEL_BS 9
 #define CHANNEL_SUBRX 10
+#ifdef PSK
+#define CHANNEL_PSK 11
+#endif
 
index 7a708d8c16e800fae9959e5e90deb8e824df120e..763ff749c1c520a9d572a3a364a2d7809416387a 100644 (file)
 #include "radio.h"
 #include "gpio.h"
 
-#ifdef raspberrypi
-#define INCLUDE_GPIO
-#endif
-#ifdef odroid
-#define INCLUDE_GPIO
-#endif
-
 static void display_panadapter_cb(GtkWidget *widget, gpointer data) {
   display_panadapter=display_panadapter==1?0:1;
 }
@@ -62,7 +55,7 @@ static void toolbar_dialog_buttons_cb(GtkWidget *widget, gpointer data) {
 }
 */
 
-#ifdef INCLUDE_GPIO
+#ifdef GPIO
 void configure_gpio(GtkWidget *parent) {
   gpio_restore_state();
 
index 09a57c4b710d09e08fa1820a8ff0a9344f988e3b..84492adfe497c589ef152054eb79e5cd1af94e48 100644 (file)
--- a/filter.c
+++ b/filter.c
@@ -216,6 +216,23 @@ FILTER filterFREEDV[FILTERS]={
     };
 #endif
 
+#ifdef PSK
+FILTER filterPSK[FILTERS]={
+    {150,5150,"5.0k"},
+    {150,4550,"4.4k"},
+    {150,3950,"3.8k"},
+    {150,3150,"3k"},
+    {150,3050,"2.9k"},
+    {150,2850,"2.7k"},
+    {150,2550,"2.4k"},
+    {150,2250,"2.1k"},
+    {150,1950,"1.8k"},
+    {150,1150,"1.0k"}/*,
+    {150,2850,"Var1"},
+    {150,2850,"Var2"}*/
+    };
+#endif
+
 
 FILTER *filters[]={
     filterLSB
@@ -233,5 +250,9 @@ FILTER *filters[]={
 #ifdef FREEDV
     ,filterFREEDV
 #endif
+#ifdef PSK
+    ,filterPSK
+#endif
+
 };
 
index 7536a61e8284faf08d914ba1bb7b012fc68a7b49..8843a85d7515f4a8868abe8ca8e1a3fb96c0bdaf 100644 (file)
--- a/freedv.c
+++ b/freedv.c
@@ -24,20 +24,24 @@ float freedv_snr;
 
 int freedv_tx_text_index=0;
 
-char freedv_rx_text_data[64];
-int freedv_rx_text_data_index=0;
+char freedv_text_data[64];
+int freedv_text_data_index=0;
 
-static void my_put_next_rx_char(void *callback_state, char c) {
+static void text_data(char c) {
   int i;
-  fprintf(stderr, "freedv: my_put_next_rx_char: %c sync=%d\n", c, freedv_sync);
+  if(c==0x0D) {
+    c='|';
+  }
+  for(i=0;i<62;i++) {
+    freedv_text_data[i]=freedv_text_data[i+1];
+  }
+  freedv_text_data[62]=c;
+}
+
+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) {
-      c='|';
-    }
-    for(i=0;i<62;i++) {
-      freedv_rx_text_data[i]=freedv_rx_text_data[i+1];
-    }
-    freedv_rx_text_data[62]=c;
+    text_data(c);
   }
 }
 
@@ -48,7 +52,8 @@ static char my_get_next_tx_char(void *callback_state){
     c=0x0D;
     freedv_tx_text_index=0;
   }
-fprintf(stderr,"freedv: my_get_next_tx_char=%c\n",c);
+//fprintf(stderr,"freedv: my_get_next_tx_char=%c\n",c);
+  text_data(c);
   return c;
 }
 
@@ -85,9 +90,9 @@ fprintf(stderr,"n_speech_samples=%d n_max_modem_samples=%d\n",n_speech_samples,
 fprintf(stderr,"freedv modem sample rate=%d\n",rate);
 
   for(i=0;i<63;i++) {
-    freedv_rx_text_data[i]=' ';
+    freedv_text_data[i]=' ';
   }
-  freedv_rx_text_data[63]=0;
+  freedv_text_data[63]=0;
 }
 
 void close_freedv() {
index bfc2e82e1d8a97680e4fbf3a79ba216f752193bd..0b4c817ad9c571219f0e6caa3b07325713099166 100644 (file)
--- a/freedv.h
+++ b/freedv.h
@@ -8,7 +8,7 @@ extern short *mod_out;
 extern int freedv_sync;
 extern float freedv_snr;
 
-extern char freedv_rx_text_data[64];
+extern char freedv_text_data[64];
 
 void init_freedv();
 void close_freedv();
diff --git a/gpio.c b/gpio.c
index c6257f8ee09ebbe0b46cc7d8ee052dd06a4294ef..3faacac093f60c9dd107194b26161346c73d1e50 100644 (file)
--- a/gpio.c
+++ b/gpio.c
@@ -1,11 +1,5 @@
-#ifdef raspberrypi
-#define INCLUDE_GPIO
-#endif
-#ifdef odroid
-#define INCLUDE_GPIO
-#endif
 
-#ifdef INCLUDE_GPIO
+#ifdef GPIO
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -34,6 +28,9 @@
 #include "main.h"
 #include "property.h"
 #include "wdsp.h"
+#ifdef PSK
+#include "psk.h"
+#endif
 
 #define SYSFS_GPIO_DIR  "/sys/class/gpio"
 
@@ -717,10 +714,18 @@ static int vfo_encoder_changed(void *data) {
     int pos=*(int*)data;
 
     if(function) {
-      //RIT
-      rit-=pos;
-      if(rit>1000) rit=1000;
-      if(rit<-1000) rit=-1000;
+#ifdef PSK
+      if(mode==modePSK) {
+        psk_set_frequency(psk_get_frequency()-(pos*10));
+      } else {
+#endif
+        //RIT
+        rit-=pos;
+        if(rit>1000) rit=1000;
+        if(rit<-1000) rit=-1000;
+#ifdef PSK
+      }
+#endif
     } else {
       // VFO
       BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
@@ -741,8 +746,8 @@ static int af_encoder_changed(void *data) {
       gain+=(double)pos/100.0;
       if(gain<0.0) {
         gain=0.0;
-      } else if(gain>4.0) {
-        gain=4.0;
+      } else if(gain>1.0) {
+        gain=1.0;
       }
       set_mic_gain(gain);
     } else {
@@ -767,27 +772,21 @@ static int rf_encoder_changed(void *data) {
     if(function || tune) {
       // tune drive
       double d=getTuneDrive();
-      //d+=(double)pos/100.0;
-      d+=(double)pos;
+      d+=(double)pos/100.0;
       if(d<0.0) {
         d=0.0;
-      //} else if(d>1.0) {
-      //  d=1.0;
-      } else if(d>255.0) {
-        d=255.0;
+      } else if(d>1.0) {
+        d=1.0;
       }
       set_tune(d);
     } else {
       // drive
       double d=getDrive();
-      //d+=(double)pos/100.0;
-      d+=(double)pos;
+      d+=(double)pos/100.0;
       if(d<0.0) {
         d=0.0;
-      //} else if(d>1.0) {
-      //  d=1.0;
-      } else if(d>255.0) {
-        d=255.0;
+      } else if(d>1.0) {
+        d=1.0;
       }
       set_drive(d);
     }
index 32b9b96addc8c078873934e319bcd1f124a217a5..45c8f9c4a8dc4fc6f9697f05316dfc319a41224e 100644 (file)
@@ -359,6 +359,10 @@ fprintf(stderr,"MRAA: gpio_init\n");
 
   mraa_init();
 
+  const char* board_name = mraa_get_platform_name();
+  fprintf(stderr,"MRAA: gpio_init: board=%s\n",board_name);
+
+if(ENABLE_VFO_ENCODER) {
   vfo_a_context=mraa_gpio_init(VFO_ENCODER_A);
   if(vfo_a_context!=NULL) {
     res=mraa_gpio_dir(vfo_a_context,MRAA_GPIO_IN);
@@ -398,7 +402,9 @@ fprintf(stderr,"MRAA: gpio_init\n");
   } else {
     fprintf(stderr,"mraa_gpio_init(%d) returned NULL\n",VFO_ENCODER_B);
   }
+}
 
+if(ENABLE_AF_ENCODER) {
   af_a_context=mraa_gpio_init(AF_ENCODER_A);
   if(af_a_context!=NULL) {
     res=mraa_gpio_dir(af_a_context,MRAA_GPIO_IN);
@@ -438,7 +444,9 @@ fprintf(stderr,"MRAA: gpio_init\n");
   } else {
     fprintf(stderr,"mraa_gpio_init(%d) returned NULL\n",AF_ENCODER_B);
   }
+}
 
+if(ENABLE_RF_ENCODER) {
   rf_a_context=mraa_gpio_init(RF_ENCODER_A);
   if(rf_a_context!=NULL) {
     res=mraa_gpio_dir(rf_a_context,MRAA_GPIO_IN);
@@ -478,7 +486,9 @@ fprintf(stderr,"MRAA: gpio_init\n");
   } else {
     fprintf(stderr,"mraa_gpio_init(%d) returned NULL\n",RF_ENCODER_B);
   }
+}
 
+if(ENABLE_AGC_ENCODER) {
   agc_a_context=mraa_gpio_init(AGC_ENCODER_A);
   if(agc_a_context!=NULL) {
     res=mraa_gpio_dir(agc_a_context,MRAA_GPIO_IN);
@@ -518,7 +528,9 @@ fprintf(stderr,"MRAA: gpio_init\n");
   } else {
     fprintf(stderr,"mraa_gpio_init(%d) returned NULL\n",AGC_ENCODER_B);
   }
+}
 
+if(ENABLE_FUNCTION_BUTTON) {
   function_context=mraa_gpio_init(FUNCTION_BUTTON);
   if(function_context!=NULL) {
     res=mraa_gpio_dir(function_context,MRAA_GPIO_IN);
@@ -532,7 +544,9 @@ fprintf(stderr,"MRAA: gpio_init\n");
   } else {
     fprintf(stderr,"mraa_gpio_init(%d) returned NULL\n",FUNCTION_BUTTON);
   }
+}
 
+if(ENABLE_BAND_BUTTON) {
   band_context=mraa_gpio_init(BAND_BUTTON);
   if(band_context!=NULL) {
     res=mraa_gpio_dir(band_context,MRAA_GPIO_IN);
@@ -546,7 +560,9 @@ fprintf(stderr,"MRAA: gpio_init\n");
   } else {
     fprintf(stderr,"mraa_gpio_init(%d) returned NULL\n",BAND_BUTTON);
   }
+}
 
+if(ENABLE_BANDSTACK_BUTTON) {
   bandstack_context=mraa_gpio_init(BANDSTACK_BUTTON);
   if(bandstack_context!=NULL) {
     res=mraa_gpio_dir(bandstack_context,MRAA_GPIO_IN);
@@ -560,7 +576,9 @@ fprintf(stderr,"MRAA: gpio_init\n");
   } else {
     fprintf(stderr,"mraa_gpio_init(%d) returned NULL\n",BANDSTACK_BUTTON);
   }
+}
 
+if(ENABLE_MODE_BUTTON) {
   mode_context=mraa_gpio_init(MODE_BUTTON);
   if(mode_context!=NULL) {
     res=mraa_gpio_dir(mode_context,MRAA_GPIO_IN);
@@ -574,12 +592,9 @@ fprintf(stderr,"MRAA: gpio_init\n");
   } else {
     fprintf(stderr,"mraa_gpio_init(%d) returned NULL\n",MODE_BUTTON);
   }
+}
 
-  int rc=pthread_create(&rotary_encoder_thread_id, NULL, rotary_encoder_thread, NULL);
-  if(rc<0) {
-    fprintf(stderr,"pthread_create for rotary_encoder_thread failed %d\n",rc);
-  }
-
+if(ENABLE_FILTER_BUTTON) {
   filter_context=mraa_gpio_init(FILTER_BUTTON);
   if(filter_context!=NULL) {
     res=mraa_gpio_dir(filter_context,MRAA_GPIO_IN);
@@ -593,7 +608,9 @@ fprintf(stderr,"MRAA: gpio_init\n");
   } else {
     fprintf(stderr,"mraa_gpio_init(%d) returned NULL\n",FILTER_BUTTON);
   }
+}
 
+if(ENABLE_NOISE_BUTTON) {
   noise_context=mraa_gpio_init(NOISE_BUTTON);
   if(noise_context!=NULL) {
     res=mraa_gpio_dir(noise_context,MRAA_GPIO_IN);
@@ -607,7 +624,9 @@ fprintf(stderr,"MRAA: gpio_init\n");
   } else {
     fprintf(stderr,"mraa_gpio_init(%d) returned NULL\n",NOISE_BUTTON);
   }
+}
 
+if(ENABLE_AGC_BUTTON) {
   agc_context=mraa_gpio_init(AGC_BUTTON);
   if(agc_context!=NULL) {
     res=mraa_gpio_dir(agc_context,MRAA_GPIO_IN);
@@ -621,7 +640,9 @@ fprintf(stderr,"MRAA: gpio_init\n");
   } else {
     fprintf(stderr,"mraa_gpio_init(%d) returned NULL\n",AGC_BUTTON);
   }
+}
 
+if(ENABLE_MOX_BUTTON) {
   mox_context=mraa_gpio_init(MOX_BUTTON);
   if(mox_context!=NULL) {
     res=mraa_gpio_dir(mox_context,MRAA_GPIO_IN);
@@ -635,6 +656,12 @@ fprintf(stderr,"MRAA: gpio_init\n");
   } else {
     fprintf(stderr,"mraa_gpio_init(%d) returned NULL\n",MOX_BUTTON);
   }
+}
+
+  int rc=pthread_create(&rotary_encoder_thread_id, NULL, rotary_encoder_thread, NULL);
+  if(rc<0) {
+    fprintf(stderr,"pthread_create for rotary_encoder_thread failed %d\n",rc);
+  }
 
   return 0;
 }
diff --git a/main.c b/main.c
index 15a0edffeb4fd36f4a9c89db8d87cea26111b243..8758d4d30dddfa6f3e92120e459070e1ff7fd358 100644 (file)
--- a/main.c
+++ b/main.c
 #ifdef FREEDV
 #include "mode.h"
 #endif
-
-#ifdef raspberrypi
-#define INCLUDE_GPIO
-#endif
-#ifdef odroid
-#define INCLUDE_GPIO
+#ifdef PSK
+#include "psk.h"
+#include "psk_waterfall.h"
 #endif
 
 #define VFO_HEIGHT ((display_height/32)*4)
@@ -97,24 +94,51 @@ static sem_t wisdom_sem;
 static GdkCursor *cursor_arrow;
 static GdkCursor *cursor_watch;
 
+static GtkWidget *fixed;
+static GtkWidget *panadapter;
+static GtkWidget *waterfall;
+#ifdef PSK
+static GtkWidget *psk;
+static GtkWidget *psk_waterfall;
+#endif
+
 gint update(gpointer data) {
     int result;
     double fwd;
     double rev;
     double exciter;
     int channel=CHANNEL_RX0;
+#ifdef PSK
+    if(mode==modePSK) {
+      channel=CHANNEL_PSK;
+    }
+#endif
     if(isTransmitting()) {
       channel=CHANNEL_TX;
     }
     GetPixels(channel,0,samples,&result);
     if(result==1) {
         if(display_panadapter) {
-          panadapter_update(samples,isTransmitting());
+#ifdef PSK
+          if(mode==modePSK) {
+            psk_waterfall_update(samples);
+          } else {
+#endif
+            panadapter_update(samples,isTransmitting());
+#ifdef PSK
+          }
+#endif
         }
         if(!isTransmitting()) {
+#ifdef PSK
+          if(mode!=modePSK) {
+#endif
             if(display_waterfall) {
               waterfall_update(samples);
             }
+#ifdef PSK
+          }
+#endif
         }
     }
 
@@ -273,7 +297,7 @@ static void* wisdom_thread(void *arg) {
 }
 
 gboolean main_delete (GtkWidget *widget) {
-#ifdef INCLUDE_GPIO
+#ifdef GPIO
   gpio_close();
 #endif
   switch(protocol) {
@@ -297,14 +321,11 @@ gint init(void* arg) {
 
   GtkWidget *window;
   GtkWidget *grid;
-  GtkWidget *fixed;
   gint x;
   gint y;
   GtkWidget *vfo;
   GtkWidget *menu;
   GtkWidget *meter;
-  GtkWidget *panadapter;
-  GtkWidget *waterfall;
   GtkWidget *sliders;
   GtkWidget *toolbar;
 
@@ -376,7 +397,7 @@ gint init(void* arg) {
           discovery_dialog = gtk_dialog_new_with_buttons ("Discovered",
                                       GTK_WINDOW(splash_window),
                                       flags,
-#ifdef INCLUDE_GPIO
+#ifdef GPIO
                                       "Configure GPIO",
                                       GTK_RESPONSE_YES,
 #endif
@@ -474,7 +495,7 @@ fprintf(stderr,"protocol=%d name=%s\n",d->protocol,d->name);
           }
          
           gtk_widget_destroy(discovery_dialog);
-#ifdef INCLUDE_GPIO
+#ifdef GPIO
           if(result==GTK_RESPONSE_YES) {
               configure_gpio(splash_window);
           }
@@ -510,7 +531,7 @@ fprintf(stderr,"protocol=%d name=%s\n",d->protocol,d->name);
 
   radioRestoreState();
 
-  samples=malloc(display_width*sizeof(float));
+  samples=malloc(display_width*sizeof(float)*2);
 
   //splash_status("Initializing wdsp ...");
   wdsp_init(0,display_width,d->protocol);
@@ -533,7 +554,7 @@ fprintf(stderr,"protocol=%d name=%s\n",d->protocol,d->name);
   }
 
   splash_status("Initializing GPIO ...");
-#ifdef INCLUDE_GPIO
+#ifdef GPIO
   gpio_init();
 #endif
 
@@ -542,42 +563,23 @@ fprintf(stderr,"protocol=%d name=%s\n",d->protocol,d->name);
   gtk_container_set_border_width (GTK_CONTAINER (window), 0);
   g_signal_connect (window, "delete-event", G_CALLBACK (main_delete), NULL);
 
-#ifdef GRID_LAYOUT
-  grid = gtk_grid_new();
-  gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
-  gtk_grid_set_row_homogeneous(GTK_GRID(grid),FALSE);
-  gtk_container_add(GTK_CONTAINER(window), grid);
-#else
   fixed=gtk_fixed_new();
   gtk_container_add(GTK_CONTAINER(window), fixed);
   y=0;
-#endif
 
 fprintf(stderr,"vfo_height=%d\n",VFO_HEIGHT);
   vfo = vfo_init(VFO_WIDTH,VFO_HEIGHT,window);
-#ifdef GRID_LAYOUT
-  gtk_grid_attach(GTK_GRID(grid), vfo, 0, y, 16, 1);
-#else
   gtk_fixed_put(GTK_FIXED(fixed),vfo,0,0);
-#endif
 
 
 fprintf(stderr,"menu_height=%d\n",MENU_HEIGHT);
   menu = menu_init(MENU_WIDTH,MENU_HEIGHT,window);
-#ifdef GRID_LAYOUT
-  gtk_grid_attach(GTK_GRID(grid), menu, 16, 0, 1, 1);
-#else
   gtk_fixed_put(GTK_FIXED(fixed),menu,VFO_WIDTH,y);
-#endif
 
 fprintf(stderr,"meter_height=%d\n",METER_HEIGHT);
   meter = meter_init(METER_WIDTH,METER_HEIGHT,window);
-#ifdef GRID_LAYOUT
-  gtk_grid_attach(GTK_GRID(grid), meter, 17, 0, 15, 1);
-#else
   gtk_fixed_put(GTK_FIXED(fixed),meter,VFO_WIDTH+MENU_WIDTH,y);
   y+=VFO_HEIGHT;
-#endif
 
   if(display_panadapter) {
     int height=PANADAPTER_HEIGHT;
@@ -596,12 +598,12 @@ fprintf(stderr,"meter_height=%d\n",METER_HEIGHT);
     }
 fprintf(stderr,"panadapter_height=%d\n",height);
     panadapter = panadapter_init(display_width,height);
-#ifdef GRID_LAYOUT
-    gtk_grid_attach(GTK_GRID(grid), panadapter, 0, 1, 32, 1);
-#else
     gtk_fixed_put(GTK_FIXED(fixed),panadapter,0,VFO_HEIGHT);
-    y+=height;
+#ifdef PSK
+    psk_waterfall = psk_waterfall_init(display_width,height);
+    gtk_fixed_put(GTK_FIXED(fixed),psk_waterfall,0,VFO_HEIGHT);
 #endif
+    y+=height;
   }
 
   if(display_waterfall) {
@@ -621,39 +623,31 @@ fprintf(stderr,"panadapter_height=%d\n",height);
     }
 fprintf(stderr,"waterfall_height=%d\n",height);
     waterfall = waterfall_init(display_width,height);
-#ifdef GRID_LAYOUT
-    gtk_grid_attach(GTK_GRID(grid), waterfall, 0, 2, 32, 1);
-#else
     gtk_fixed_put(GTK_FIXED(fixed),waterfall,0,y);
-    y+=height;
+#ifdef PSK
+    psk = init_psk();
+    gtk_fixed_put(GTK_FIXED(fixed),psk,0,y);
 #endif
+    y+=height;
+
   }
 
   if(display_sliders) {
 fprintf(stderr,"sliders_height=%d\n",SLIDERS_HEIGHT);
     sliders = sliders_init(display_width,SLIDERS_HEIGHT,window);
-#ifdef GRID_LAYOUT
-    gtk_grid_attach(GTK_GRID(grid), sliders, 0, 3, 32, 1);
-#else
     gtk_fixed_put(GTK_FIXED(fixed),sliders,0,y);
     y+=SLIDERS_HEIGHT;
-#endif
   }
 
   if(display_toolbar) {
 fprintf(stderr,"toolbar_height=%d\n",TOOLBAR_HEIGHT);
     toolbar = toolbar_init(display_width,TOOLBAR_HEIGHT,window);
-#ifdef GRID_LAYOUT
-    gtk_grid_attach(GTK_GRID(grid), toolbar, 0, 4, 32, 1);
-#else
     gtk_fixed_put(GTK_FIXED(fixed),toolbar,0,y);
     y+=TOOLBAR_HEIGHT;
-#endif
   }
 
   splash_close();
 
-
   gtk_widget_show_all (window);
 
   if(full_screen) {
@@ -663,7 +657,8 @@ fprintf(stderr,"toolbar_height=%d\n",TOOLBAR_HEIGHT);
   GdkWindow *gdk_window = gtk_widget_get_window(window);
   gdk_window_set_cursor(gdk_window,cursor_arrow);
 
-  update_timer_id=gdk_threads_add_timeout(1000/updates_per_second, update, NULL);
+  //update_timer_id=gdk_threads_add_timeout(1000/updates_per_second, update, NULL);
+  update_timer_id=gdk_threads_add_timeout_full(G_PRIORITY_HIGH_IDLE,1000/updates_per_second, update, NULL, NULL);
 
   // save every 30 seconds
   save_timer_id=gdk_threads_add_timeout(30000, save_cb, NULL);
@@ -673,11 +668,35 @@ fprintf(stderr,"toolbar_height=%d\n",TOOLBAR_HEIGHT);
     setFrequency(getFrequency());
   }
 
+#ifdef PSK
+  if(mode==modePSK) {
+    show_psk();
+  } else {
+    show_waterfall();
+  }
+#endif
+
   g_idle_add(vfo_update,(gpointer)NULL);
 
   return 0;
 }
 
+#ifdef PSK
+void show_psk() {
+  gtk_widget_hide(waterfall);
+  gtk_widget_hide(panadapter);
+  gtk_widget_show(psk);
+  gtk_widget_show(psk_waterfall);
+}
+
+void show_waterfall() {
+  gtk_widget_hide(psk_waterfall);
+  gtk_widget_hide(psk);
+  gtk_widget_show(panadapter);
+  gtk_widget_show(waterfall);
+}
+#endif
+
 
 int
 main (int   argc,
diff --git a/main.h b/main.h
index dff008921bf44a9e44622c15546b0724183f4e7e..e2455207a3118813f05cb83e7a583141abab072d 100644 (file)
--- a/main.h
+++ b/main.h
@@ -19,3 +19,8 @@
 
 #include <sys/utsname.h>
 extern struct utsname unameData;
+#ifdef PSK
+void show_psk();
+void show_waterfall();
+#endif
+
diff --git a/menu.c b/menu.c
index 025928499ae6550d6bd7167513e8b59a6f2a5d57..4368da59c56ca235fb4d09375ca2eef938765d8b 100644 (file)
--- a/menu.c
+++ b/menu.c
 *
 */
 
-#ifdef raspberrypi
-#define INCLUDE_GPIO
-#endif
-#ifdef odroid
-#define INCLUDE_GPIO
-#endif
-
 #include <gtk/gtk.h>
 #include <semaphore.h>
 #include <stdio.h>
@@ -256,7 +249,7 @@ static gboolean exit_pressed_event_cb (GtkWidget *widget,
                GdkEventButton *event,
                gpointer        data)
 {
-#ifdef INCLUDE_GPIO
+#ifdef GPIO
   gpio_close();
 #endif
   switch(protocol) {
@@ -280,7 +273,7 @@ static gboolean reboot_pressed_event_cb (GtkWidget *widget,
                GdkEventButton *event,
                gpointer        data)
 {
-#ifdef INCLUDE_GPIO
+#ifdef GPIO
   gpio_close();
 #endif
   switch(protocol) {
@@ -305,7 +298,7 @@ static gboolean shutdown_pressed_event_cb (GtkWidget *widget,
                GdkEventButton *event,
                gpointer        data)
 {
-#ifdef INCLUDE_GPIO
+#ifdef GPIO
   gpio_close();
 #endif
   switch(protocol) {
diff --git a/meter.c b/meter.c
index d94b288a8c0d6178d162f35878449289320efc07..5718eab3b149c95107b231022ff25c126cf3cb93 100644 (file)
--- a/meter.c
+++ b/meter.c
@@ -42,6 +42,7 @@ static int meter_height;
 static int last_meter_type=SMETER;
 static int max_level=-200;
 static int max_count=0;
+static int max_reverse=0;
 
 static void
 meter_clear_surface (void)
@@ -117,13 +118,13 @@ meter_press_event_cb (GtkWidget *widget,
 
    
   GtkWidget *smeter_peak=gtk_radio_button_new_with_label(NULL,"S Meter Peak");
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (smeter_peak), alc==RXA_S_PK);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (smeter_peak), smeter==RXA_S_PK);
   gtk_widget_show(smeter_peak);
   gtk_grid_attach(GTK_GRID(grid),smeter_peak,0,1,1,1);
   g_signal_connect(smeter_peak,"pressed",G_CALLBACK(smeter_select_cb),(gpointer *)RXA_S_PK);
 
   GtkWidget *smeter_average=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(smeter_peak),"S Meter Average");
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (smeter_average), alc==RXA_S_AV);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (smeter_average), smeter==RXA_S_AV);
   gtk_widget_show(smeter_average);
   gtk_grid_attach(GTK_GRID(grid),smeter_average,0,2,1,1);
   g_signal_connect(smeter_average,"pressed",G_CALLBACK(smeter_select_cb),(gpointer *)RXA_S_AV);
@@ -217,6 +218,7 @@ void meter_update(int meter_type,double value,double reverse,double exciter,doub
       max_level=-200;
     } else {
       max_level=0;
+      max_reverse=0;
     }
   }
 
@@ -333,12 +335,11 @@ void meter_update(int meter_type,double value,double reverse,double exciter,doub
       cairo_move_to(cr, 10, 35);
       cairo_show_text(cr, sf);
 
-      double swr=(value+reverse)/(value-reverse);
+      double swr=(max_level+reverse)/(max_level-reverse);
       cairo_select_font_face(cr, "Arial",
             CAIRO_FONT_SLANT_NORMAL,
             CAIRO_FONT_WEIGHT_BOLD);
       cairo_set_font_size(cr, 18);
-
       sprintf(sf,"SWR: %1.1f:1",swr);
       cairo_move_to(cr, 10, 55);
       cairo_show_text(cr, sf);
diff --git a/mode.c b/mode.c
index 6450963134da4c995eaa4f47da9bbddf90f3dd51..7bb8cd0f97c5b9b4418eee73dfb6f2d484830a0a 100644 (file)
--- a/mode.c
+++ b/mode.c
@@ -33,5 +33,8 @@ char *mode_string[]={
 #ifdef FREEDV
   ,"FREEDV"
 #endif
+#ifdef PSK
+  ,"PSK"
+#endif
 };
 
diff --git a/mode.h b/mode.h
index 71d9dca7daa97cbf6b85e435a14103f62c9280f6..aa1d4fd823df489cd0af12bc996bae7e582dacad 100644 (file)
--- a/mode.h
+++ b/mode.h
 #define modeSAM 10
 #define modeDRM 11
 #ifdef FREEDV
+#ifdef PSK
 #define modeFREEDV 12
+#define modePSK 13
+#define MODES 14
+#else
+#define modeFREEDV 12
+#define MODES 13
+#endif
+#else
+#ifdef PSK
+#define modePSK 12
 #define MODES 13
 #else
 #define MODES 12
 #endif
+#endif
 
 int mode;
 
index 8c7533a0fa85caf5d428c227f2341fa23731cf53..b828ed6212b5c7331c1ae623a5bf7404ccaf3876 100644 (file)
@@ -49,6 +49,7 @@
 #include "mode.h"
 #include "filter.h"
 #include "radio.h"
+#include "signal.h"
 #include "vfo.h"
 #include "toolbar.h"
 #include "wdsp_init.h"
@@ -286,7 +287,11 @@ fprintf(stderr,"new_protocol_high_priority: run=%d tx=%d drive=%d\n", run, tx, d
     buffer[332]=phase;
 
 
-    buffer[345]=drive;
+    float d=(float)drive;
+    d=d*((float)band->pa_calibration/100.0F);
+    int power=(int)(d*255.0);
+
+    buffer[345]=power&0xFF;
 
 
     if(isTransmitting()) {
@@ -584,18 +589,6 @@ void new_protocol_stop() {
     sleep(1);
 }
 
-static float sineWave(double* buf, int samples, float phase, float freq) {
-    float phase_step = 2 * PI * freq / 48000.0F;
-    int i;
-    for (i = 0; i < samples; i++) {
-        buf[i*2] = (double) sin(phase);
-        buf[(i*2)+1] = (double) sin(phase);
-        phase += phase_step;
-    }
-    return phase;
-}
-
-
 double calibrate(int v) {
     // Angelia
     double v1;
@@ -955,7 +948,8 @@ static void full_tx_buffer() {
 
   if(tune==1) {
     double tunefrequency = (double)(filterLow+((filterHigh - filterLow) / 2));
-    phase=sineWave(micinputbuffer, BUFFER_SIZE, phase, (float)tunefrequency);
+    sineWave(micinputbuffer, BUFFER_SIZE, phase, tunefrequency);
+    phase=cosineWave(micinputbuffer, BUFFER_SIZE, phase, tunefrequency);
   }
 
   fexchange0(CHANNEL_TX, micinputbuffer, micoutputbuffer, &error);
index 3564a9a60457711ce4c2396d872e3b67367cb8c0..73c8c3c29520b9cb7752e39df308bb5e770c4a2d 100644 (file)
 #include "filter.h"
 #include "old_protocol.h"
 #include "radio.h"
+#include "signal.h"
 #include "toolbar.h"
 #ifdef FREEDV
 #include "freedv.h"
 #endif
+#ifdef PSK
+#include "psk.h"
+#endif
 
 #define SYNC0 0
 #define SYNC1 1
@@ -59,8 +63,6 @@
 #define C3 6
 #define C4 7
 
-#define PI 3.1415926535897932F
-
 #define DATA_PORT 1024
 
 #define SYNC 0x7F
@@ -120,7 +122,7 @@ static int output_buffer_size;
 static unsigned char control_in[5]={0x00,0x00,0x00,0x00,0x00};
 
 static double tuning_phase;
-static float phase=0.0f;
+static double phase=0.0;
 
 static int running;
 static long ep4_sequence;
@@ -130,6 +132,10 @@ static int samples=0;
 static int freedv_samples=0;
 static int freedv_divisor=6;
 #endif
+#ifdef PSK
+static int psk_samples=0;
+static int psk_divisor=6;
+#endif
 
 //static float left_input_buffer[BUFFER_SIZE];
 //static float right_input_buffer[BUFFER_SIZE];
@@ -188,17 +194,6 @@ void schedule_frequency_changed() {
     //sem_post(&frequency_changed_sem);
 }
 
-static float sineWave(double* buf, int samples, float phase, float freq) {
-    float phase_step = 2 * PI * freq / sample_rate;
-    int i;
-    for (i = 0; i < samples; i++) {
-        buf[i*2] = (double) sin(phase);
-        buf[(i*2)+1] = (double) sin(phase);
-        phase += phase_step;
-    }
-    return phase;
-}
-
 void old_protocol_stop() {
   metis_start_stop(0);
   running=FALSE;
@@ -210,24 +205,36 @@ void old_protocol_calc_buffers() {
       output_buffer_size=OUTPUT_BUFFER_SIZE;
 #ifdef FREEDV
       freedv_divisor=6;
+#endif
+#ifdef PSK
+      psk_divisor=6;
 #endif
       break;
     case 96000:
       output_buffer_size=OUTPUT_BUFFER_SIZE/2;
 #ifdef FREEDV
       freedv_divisor=12;
+#endif
+#ifdef PSK
+      psk_divisor=12;
 #endif
       break;
     case 192000:
       output_buffer_size=OUTPUT_BUFFER_SIZE/4;
 #ifdef FREEDV
       freedv_divisor=24;
+#endif
+#ifdef PSK
+      psk_divisor=24;
 #endif
       break;
     case 384000:
       output_buffer_size=OUTPUT_BUFFER_SIZE/8;
 #ifdef FREEDV
       freedv_divisor=48;
+#endif
+#ifdef PSK
+      psk_divisor=48;
 #endif
       break;
     default:
@@ -389,9 +396,9 @@ static void process_ozy_input_buffer(char  *buffer) {
   int left_sample;
   int right_sample;
   int mic_sample;
-  float left_sample_float;
-  float right_sample_float;
-  float mic_sample_float;
+  double left_sample_double;
+  double right_sample_double;
+  double mic_sample_double;
 
   if(buffer[b++]==SYNC && buffer[b++]==SYNC && buffer[b++]==SYNC) {
     // extract control bytes
@@ -458,28 +465,24 @@ static void process_ozy_input_buffer(char  *buffer) {
       mic_sample    = (int)((signed char) buffer[b++]) << 8;
       mic_sample   += (int)((unsigned char)buffer[b++]);
 
-      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
+      left_sample_double=(double)left_sample/8388607.0; // 24 bit sample 2^23-1
+      right_sample_double=(double)right_sample/8388607.0; // 24 bit sample 2^23-1
+      mic_sample_double=(double)mic_sample/32767.0; // 16 bit sample 2^16-1
 
       // add to buffer
       if(isTransmitting()) {
 #ifdef FREEDV
-        if(mode==modeFREEDV) {
+        if(mode==modeFREEDV && !tune) {
           if(freedv_samples==0) {
             int modem_samples=mod_sample_freedv(mic_sample);
-            //short micinput=(short)(((double)mic_sample_float*mic_gain)*32767.0);
-            //int modem_samples=mod_sample_freedv(micinput);
             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;
-                  //micinputbuffer[samples*2]=(double)mic_sample_float;
-                  //micinputbuffer[(samples*2)+1]=(double)mic_sample_float;
+                  mic_sample_double=(double)mic_sample/32767.0f; // 16 bit sample 2^16-1
+                  micinputbuffer[samples*2]=mic_sample_double*mic_gain;
+                  micinputbuffer[(samples*2)+1]=mic_sample_double*mic_gain;
                   iqinputbuffer[samples*2]=0.0;
                   iqinputbuffer[(samples*2)+1]=0.0;
                   samples++;
@@ -497,12 +500,12 @@ static void process_ozy_input_buffer(char  *buffer) {
           }
         } else {
 #endif
-          if(mode==modeCWL || mode==modeCWU) {
+          if(mode==modeCWL || mode==modeCWU || tune) {
             micinputbuffer[samples*2]=0.0;
             micinputbuffer[(samples*2)+1]=0.0;
           } else {
-            micinputbuffer[samples*2]=(double)mic_sample_float*mic_gain;
-            micinputbuffer[(samples*2)+1]=(double)mic_sample_float*mic_gain;
+            micinputbuffer[samples*2]=mic_sample_double*mic_gain;
+            micinputbuffer[(samples*2)+1]=mic_sample_double*mic_gain;
           }
           iqinputbuffer[samples*2]=0.0;
           iqinputbuffer[(samples*2)+1]=0.0;
@@ -517,8 +520,8 @@ static void process_ozy_input_buffer(char  *buffer) {
       } else {
         micinputbuffer[samples*2]=0.0;
         micinputbuffer[(samples*2)+1]=0.0;
-        iqinputbuffer[samples*2]=(double)left_sample_float;
-        iqinputbuffer[(samples*2)+1]=(double)right_sample_float;
+        iqinputbuffer[samples*2]=left_sample_double;
+        iqinputbuffer[(samples*2)+1]=right_sample_double;
         samples++;
         if(samples==buffer_size) {
           full_rx_buffer();
@@ -541,114 +544,129 @@ static void process_ozy_input_buffer(char  *buffer) {
   }
 }
 
-static void full_rx_buffer() {
-  int j;
-  int error;
 #ifdef FREEDV
-  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);
+static void process_freedv_rx_buffer() {
+  int j;
 
-    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;
-              }
-              if(local_audio) {
-                audio_write(left_rx_sample,right_rx_sample);
-              }
-              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;
-             }
+  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;
+            }
+            if(local_audio) {
+              audio_write(left_rx_sample,right_rx_sample);
+            }
+            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;
             }
           }
         }
       }
-      freedv_samples++;
-      if(freedv_samples==freedv_divisor) {
-        freedv_samples=0;
-      }
     }
-  } else {
+    freedv_samples++;
+    if(freedv_samples==freedv_divisor) {
+      freedv_samples=0;
+    }
+  }
+}
 #endif
-    // process the input
-    fexchange0(CHANNEL_RX0, iqinputbuffer, audiooutputbuffer, &error);
-    if(error!=0) {
-      fprintf(stderr,"fexchange2 (CHANNEL_RX0) returned error: %d\n", error);
+
+static void process_rx_buffer() {
+  int j;
+
+  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);
+#ifdef PSK
+    if(psk_samples==0) {
+      psk_demod((left_rx_sample+right_rx_sample)/2);
     }
-    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);
-      if(local_audio) {
-        audio_write(left_rx_sample,right_rx_sample);
-      }
-      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;
-      }
+    psk_samples++;
+    if(psk_samples==psk_divisor) {
+      psk_samples=0;
+    }
+#endif
+    if(local_audio) {
+      audio_write(left_rx_sample,right_rx_sample);
     }
+    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;
+    }
+  }
+}
+
+static void full_rx_buffer() {
+  int j;
+  int error;
+
+  // process the input
+  fexchange0(CHANNEL_RX0, iqinputbuffer, audiooutputbuffer, &error);
+  if(error!=0) {
+    fprintf(stderr,"fexchange2 (CHANNEL_RX0) returned error: %d\n", error);
+  }
+#ifdef PSK
+  if(mode!=modePSK) {
+#endif
+    Spectrum0(1, CHANNEL_RX0, 0, 0, iqinputbuffer);
+#ifdef PSK
+  }
+#endif
+
 #ifdef FREEDV
+  if(mode==modeFREEDV) {
+    process_freedv_rx_buffer();
+    return;
   }
 #endif
+  process_rx_buffer();
 }
 
 static void full_tx_buffer() {
   int j;
   int error;
-  double gain;
-  if(tune) {
-    double tunefrequency = (double)(filterLow+((filterHigh - filterLow) / 2));
-    phase=sineWave(micinputbuffer, BUFFER_SIZE, phase, (float)tunefrequency);
-  }
+  double gain=32767.0; // 2^16-1
 
   // process the output
+  fexchange0(CHANNEL_RX0, iqinputbuffer, audiooutputbuffer, &error);
   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;
+      gain=65535.0*tune_drive;
     } else {
-      gain=65535.0*255.0/(double)drive;
+      gain=65535.0*drive;
     }
   } else {
     gain=65535.0;
@@ -656,8 +674,8 @@ static void full_tx_buffer() {
   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);
+    left_tx_sample=(short)(micoutputbuffer[j*2]*gain);
+    right_tx_sample=(short)(micoutputbuffer[(j*2)+1]*gain);
     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;
@@ -838,10 +856,11 @@ void ozy_send_buffer() {
         d=(float)tune_drive;
       }
       BAND *band=band_get_current_band();
-      d=(d*(float)band->pa_calibration)/100.0F;
+      d=d*((float)band->pa_calibration/100.0F);
+      int power=(int)(d*255.0);
 
       output_buffer[C0]=0x12;
-      output_buffer[C1]=(int)d;
+      output_buffer[C1]=power&0xFF;
       output_buffer[C2]=0x00;
       if(mic_boost) {
         output_buffer[C2]|=0x01;
@@ -924,6 +943,13 @@ void ozy_send_buffer() {
       output_buffer[C3]=(cw_keyer_sidetone_frequency>>4) & 0xFF;
       output_buffer[C4]=cw_keyer_sidetone_frequency & 0x0F;
       break;
+    case 9:
+      output_buffer[C0]=0x22;
+      output_buffer[C1]=(eer_pwm_min>>2) & 0xFF;
+      output_buffer[C2]=eer_pwm_min & 0x03;
+      output_buffer[C3]=(eer_pwm_max>>3) & 0xFF;
+      output_buffer[C4]=eer_pwm_max & 0x03;
+      break;
   }
 
   // set mox
@@ -940,7 +966,7 @@ void ozy_send_buffer() {
   metis_write(0x02,output_buffer,OZY_BUFFER_SIZE);
 
   command++;
-  if(command>8) {
+  if(command>9) {
     command=0;
   }
 
index 0cde9c8a2ce93298d956e59113f082dbf60db55b..c2d3c3e8aab30d65a6cb73876162fecc67106095 100644 (file)
@@ -29,8 +29,8 @@
 #include "radio.h"
 #include "panadapter.h"
 #include "vfo.h"
-#ifdef FREEDV
 #include "mode.h"
+#ifdef FREEDV
 #include "freedv.h"
 #endif
 
@@ -199,20 +199,13 @@ void panadapter_update(float *data,int tx) {
                 saved_hz_per_pixel=hz_per_pixel;
 
                 panadapter_high=20;
-                panadapter_low=-100;
+                panadapter_low=-140;
                 if(protocol==ORIGINAL_PROTOCOL) {
                     hz_per_pixel=48000.0/(double)display_width;
                 } 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;
@@ -358,14 +351,15 @@ void panadapter_update(float *data,int tx) {
 
 #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);
+              if(tx) {
+                cairo_set_source_rgb(cr, 1, 0, 0);
+              } else {
+                cairo_set_source_rgb(cr, 0, 1, 0);
+              }
               cairo_set_font_size(cr, 16);
-              cairo_text_extents(cr, freedv_rx_text_data, &extents);
+              cairo_text_extents(cr, freedv_text_data, &extents);
               cairo_move_to(cr, (double)display_width/2.0-(extents.width/2.0),(double)panadapter_height-2.0);
-              cairo_show_text(cr, freedv_rx_text_data);
+              cairo_show_text(cr, freedv_text_data);
             }
 #endif
 
diff --git a/pihpsdr b/pihpsdr
index 7bc8d9120d0440879021b00f045f25b86fef0b36..ffbec55080275601bd6ecca86f1957557f723313 100755 (executable)
Binary files a/pihpsdr and b/pihpsdr differ
diff --git a/psk.c b/psk.c
new file mode 100644 (file)
index 0000000..25a076a
--- /dev/null
+++ b/psk.c
@@ -0,0 +1,149 @@
+#include <gtk/gtk.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pskcoresdr.h>
+#include <wdsp.h>
+
+#include "psk.h"
+#include "radio.h"
+#include "channel.h"
+#include "wdsp_init.h"
+
+static void *detector;
+
+static double buffer[PSK_BUFFER_SIZE];
+static float spectrum_buffer[PSK_BUFFER_SIZE];
+static int psk_index;
+
+#define PSK_TEXT_SIZE 128
+static char psk_text[PSK_TEXT_SIZE];
+
+GtkWidget *dialog;
+GtkWidget *psk_label;
+
+#define TEXT_LINES 10
+#define TEXT_LINE_LENGTH 80
+char text_label[TEXT_LINES][TEXT_LINE_LENGTH+1];
+int first_text_line=0;
+int current_text_line=9;
+int current_text_offset=0;
+
+static char temp_text[TEXT_LINES*(TEXT_LINE_LENGTH+1)];
+
+static void build_temp_text() {
+  int i;
+  int offset=0;
+  i=first_text_line;
+  do {
+    strcpy(&temp_text[offset],text_label[i]);
+    offset+=strlen(text_label[i]);
+    temp_text[offset]=0x0D;
+    offset++;
+    i++;
+    if(i==TEXT_LINES) {
+      i=0;
+    }
+  } while (i!=first_text_line);
+
+  // replace last \r with \0
+  temp_text[offset-1]='\0';
+}
+
+static void add_text(char *text, int length) {
+  int i;
+
+  for(i=0;i<length;i++) {
+    if(text[i]==0x0D  || text[i]==0x11 || current_text_offset>=TEXT_LINE_LENGTH) {
+      current_text_line++;
+      if(current_text_line==TEXT_LINES) {
+        current_text_line=0;
+      }
+      first_text_line++;
+      if(first_text_line==TEXT_LINES) {
+        first_text_line=0;
+      }
+      current_text_offset=0;
+    }
+    //if(text[i]!=0x0D && text[i]!=0x0A) {
+    if(text[i]>0x1F) {
+      text_label[current_text_line][current_text_offset++]=text[i];
+    }
+    text_label[current_text_line][current_text_offset]=0x00;
+  }
+}
+
+GtkWidget *init_psk() {
+  int i;
+
+  psk_index=0;
+  detector=createPSKDet(8000);
+  if(detector==NULL) {
+    fprintf(stderr,"init_psk: createPSKDet return null!\n");
+    return NULL;
+  }
+  SetRXFrequency(detector,1500);
+  ResetDetector(detector);
+
+  for(i=0;i<TEXT_LINES;i++) {
+    text_label[i][0]='\0';
+  }
+  build_temp_text();
+  psk_label=gtk_label_new(temp_text);
+  gtk_label_set_single_line_mode (GTK_LABEL(psk_label), FALSE);
+  gtk_label_set_width_chars (GTK_LABEL(psk_label), 80);
+  gtk_label_set_lines (GTK_LABEL(psk_label), TEXT_LINES);
+  gtk_label_set_line_wrap (GTK_LABEL(psk_label), TRUE);
+  gtk_misc_set_alignment (GTK_MISC(psk_label), 0, 0);
+  
+  return psk_label;
+}
+
+void close_psk() {
+  if(detector!=NULL) {
+    freePSKDet(detector);
+    gtk_widget_destroy (dialog);
+  }
+}
+
+void psk_set_frequency(int f) {
+  if(detector!=NULL) {
+    SetRXFrequency(detector,f);
+    ResetDetector(detector);
+  }
+}
+
+int psk_get_frequency() {
+  return GetRXFrequency(detector);
+}
+
+int psk_get_signal_level() {
+  return GetSignalLevel(detector);
+}
+
+static gint psk_update(void* arg) {
+  gtk_label_set_text(GTK_LABEL(psk_label),temp_text);
+  return 0;
+}
+
+int psk_demod(double sample) {
+  int i;
+  int c;
+  int new_lines;
+  if(detector!=NULL) {
+    buffer[psk_index]=sample;
+    spectrum_buffer[psk_index]=(float)sample;
+    psk_index++;
+    if(psk_index==PSK_BUFFER_SIZE) {
+      int detected=runPSKDet(detector,buffer,PSK_BUFFER_SIZE,1,psk_text,PSK_TEXT_SIZE);
+      psk_text[detected]='\0';
+      if(detected>0) {
+        add_text(psk_text,detected);
+        build_temp_text();
+        g_idle_add(psk_update,(gpointer)NULL);
+      }
+      Spectrum(CHANNEL_PSK,0,0,spectrum_buffer,spectrum_buffer);
+      psk_index=0;
+    }
+  }
+}
diff --git a/psk.h b/psk.h
new file mode 100644 (file)
index 0000000..8e22e2f
--- /dev/null
+++ b/psk.h
@@ -0,0 +1,11 @@
+#define PSK_BUFFER_SIZE 1024
+
+#define PSK_RX_TEXT_SIZE 2048
+extern char psk_rx_text_data[PSK_RX_TEXT_SIZE];
+
+extern GtkWidget *init_psk();
+extern void close_psk();
+extern void psk_set_frequency(int f);
+extern int psk_get_frequency();
+extern int psk_get_signal_level();
+extern int psk_demod(double sample);
diff --git a/psk_waterfall.c b/psk_waterfall.c
new file mode 100644 (file)
index 0000000..bc5c3bc
--- /dev/null
@@ -0,0 +1,302 @@
+/* Copyright (C)
+* 2015 - 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 <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <math.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include "filter.h"
+#include "radio.h"
+#include "vfo.h"
+#include "psk.h"
+#include "psk_waterfall.h"
+
+static GtkWidget *waterfall;
+static GdkPixbuf *pixbuf = NULL;
+
+static int colorLowR=0; // black
+static int colorLowG=0;
+static int colorLowB=0;
+
+static int colorMidR=255; // red
+static int colorMidG=0;
+static int colorMidB=0;
+
+static int colorHighR=255; // yellow
+static int colorHighG=255;
+static int colorHighB=0;
+
+
+static gint first_x;
+static gint last_x;
+static gboolean has_moved=FALSE;
+static gboolean pressed=FALSE;
+
+static gfloat hz_per_pixel;
+
+/*
+#define BANDS 7
+static long long frequency[BANDS];
+static gint mode[BANDS];
+static gint band=4;
+*/
+
+// fixed for psk waterfall?
+static int psk_waterfall_low=30;
+static int psk_waterfall_high=90;
+
+static int display_width;
+static int waterfall_height;
+
+/* Create a new surface of the appropriate size to store our scribbles */
+static gboolean
+waterfall_configure_event_cb (GtkWidget         *widget,
+            GdkEventConfigure *event,
+            gpointer           data)
+{
+  return TRUE;
+}
+
+/* Redraw the screen from the surface. Note that the ::draw
+ * signal receives a ready-to-be-used cairo_t that is already
+ * clipped to only draw the exposed areas of the widget
+ */
+static gboolean
+waterfall_draw_cb (GtkWidget *widget,
+ cairo_t   *cr,
+ gpointer   data)
+{
+  gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+  cairo_paint (cr);
+
+  int cursor_x=(int)((float)psk_get_frequency()/hz_per_pixel);
+  cairo_set_source_rgb (cr, 1, 0, 0);
+  cairo_set_line_width(cr, 1.0);
+  cairo_move_to(cr,(double)cursor_x,0.0);
+  cairo_line_to(cr,(double)cursor_x,(double)waterfall_height);
+
+  cairo_move_to(cr, (double)cursor_x+2.0,10.0);
+  char f[8];
+  sprintf(f,"%d",psk_get_frequency());
+  cairo_show_text(cr, f);
+
+  cairo_stroke(cr);
+  return TRUE;
+}
+
+static gboolean
+waterfall_button_press_event_cb (GtkWidget      *widget,
+               GdkEventButton *event,
+               gpointer        data)
+{
+  float x=(float)event->x;
+  int f=(int)(x*hz_per_pixel);
+  psk_set_frequency(f);
+  return TRUE;
+}
+
+static gboolean
+waterfall_button_release_event_cb (GtkWidget      *widget,
+               GdkEventButton *event,
+               gpointer        data)
+{
+/*
+  int x=(int)event->x;
+  if (event->button == 1) {
+    if(has_moved) {
+      // drag
+      vfo_move((int)((float)(x-last_x)*hz_per_pixel));
+    } else {
+      // move to this frequency
+      vfo_move_to((int)((float)(x-(display_width/2))*hz_per_pixel));
+    }
+    last_x=x;
+    pressed=FALSE;
+  }
+*/
+  return TRUE;
+}
+
+static gboolean
+waterfall_motion_notify_event_cb (GtkWidget      *widget,
+                GdkEventMotion *event,
+                gpointer        data)
+{
+/*
+  int x, y;
+  GdkModifierType state;
+  gdk_window_get_device_position (event->window,
+                                event->device,
+                                &x,
+                                &y,
+                                &state);
+  if((state & GDK_BUTTON1_MASK == GDK_BUTTON1_MASK) || pressed) {
+    int moved=last_x-x;
+    vfo_move((int)((float)moved*hz_per_pixel));
+    last_x=x;
+    has_moved=TRUE;
+  }
+*/
+  return TRUE;
+}
+
+static gboolean
+waterfall_scroll_event_cb (GtkWidget      *widget,
+               GdkEventScroll *event,
+               gpointer        data)
+{
+/*
+  if(event->direction==GDK_SCROLL_UP) {
+    vfo_move(step);
+  } else {
+    vfo_move(-step);
+  }
+*/
+  return TRUE;
+}
+
+void psk_waterfall_update(float *data) {
+
+    int i;
+
+    char *pixels = gdk_pixbuf_get_pixels (pixbuf);
+
+    int width=gdk_pixbuf_get_width(pixbuf);
+    int height=gdk_pixbuf_get_height(pixbuf);
+    int rowstride=gdk_pixbuf_get_rowstride(pixbuf);
+    int channels=gdk_pixbuf_get_n_channels(pixbuf);
+
+    memmove(&pixels[rowstride],pixels,(height-1)*rowstride);
+
+    float sample;
+    int average=0;
+    char *p;
+    p=pixels;
+    for(i=0;i<width;i++) {
+            sample=data[i];
+            average+=(int)sample;
+            if(sample<(float)psk_waterfall_low) {
+                *p++=colorLowR;
+                *p++=colorLowG;
+                *p++=colorLowB;
+            } else if(sample>(float)psk_waterfall_high) {
+                *p++=colorHighR;
+                *p++=colorHighG;
+                *p++=colorHighB;
+            } else {
+                float range=(float)psk_waterfall_high-(float)psk_waterfall_low;
+                float offset=sample-(float)psk_waterfall_low;
+                float percent=offset/range;
+                if(percent<(2.0f/9.0f)) {
+                    float local_percent = percent / (2.0f/9.0f);
+                    *p++ = (int)((1.0f-local_percent)*colorLowR);
+                    *p++ = (int)((1.0f-local_percent)*colorLowG);
+                    *p++ = (int)(colorLowB + local_percent*(255-colorLowB));
+                } else if(percent<(3.0f/9.0f)) {
+                    float local_percent = (percent - 2.0f/9.0f) / (1.0f/9.0f);
+                    *p++ = 0;
+                    *p++ = (int)(local_percent*255);
+                    *p++ = 255;
+                } else if(percent<(4.0f/9.0f)) {
+                     float local_percent = (percent - 3.0f/9.0f) / (1.0f/9.0f);
+                     *p++ = 0;
+                     *p++ = 255;
+                     *p++ = (int)((1.0f-local_percent)*255);
+                } else if(percent<(5.0f/9.0f)) {
+                     float local_percent = (percent - 4.0f/9.0f) / (1.0f/9.0f);
+                     *p++ = (int)(local_percent*255);
+                     *p++ = 255;
+                     *p++ = 0;
+                } else if(percent<(7.0f/9.0f)) {
+                     float local_percent = (percent - 5.0f/9.0f) / (2.0f/9.0f);
+                     *p++ = 255;
+                     *p++ = (int)((1.0f-local_percent)*255);
+                     *p++ = 0;
+                } else if(percent<(8.0f/9.0f)) {
+                     float local_percent = (percent - 7.0f/9.0f) / (1.0f/9.0f);
+                     *p++ = 255;
+                     *p++ = 0;
+                     *p++ = (int)(local_percent*255);
+                } else {
+                     float local_percent = (percent - 8.0f/9.0f) / (1.0f/9.0f);
+                     *p++ = (int)((0.75f + 0.25f*(1.0f-local_percent))*255.0f);
+                     *p++ = (int)(local_percent*255.0f*0.5f);
+                     *p++ = 255;
+                }
+            }
+    }
+
+    
+/*
+    if(waterfall_automatic) {
+      waterfall_low=average/display_width;
+      waterfall_high=waterfall_low+50;
+    }
+*/
+
+    gtk_widget_queue_draw (waterfall);
+
+}
+
+GtkWidget* psk_waterfall_init(int width,int height) {
+  display_width=width;
+  waterfall_height=height;
+
+  hz_per_pixel=(double)(8000/2)/(double)display_width;
+
+  //waterfall_frame = gtk_frame_new (NULL);
+  waterfall = gtk_drawing_area_new ();
+  gtk_widget_set_size_request (waterfall, width, height);
+
+  /* Signals used to handle the backing surface */
+  g_signal_connect (waterfall, "draw",
+            G_CALLBACK (waterfall_draw_cb), NULL);
+  g_signal_connect (waterfall,"configure-event",
+            G_CALLBACK (waterfall_configure_event_cb), NULL);
+
+  pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, width, height);
+
+  /* Event signals */
+  g_signal_connect (waterfall, "motion-notify-event",
+            G_CALLBACK (waterfall_motion_notify_event_cb), NULL);
+  g_signal_connect (waterfall, "button-press-event",
+            G_CALLBACK (waterfall_button_press_event_cb), NULL);
+  g_signal_connect (waterfall, "button-release-event",
+            G_CALLBACK (waterfall_button_release_event_cb), NULL);
+  g_signal_connect(waterfall,"scroll_event",
+            G_CALLBACK(waterfall_scroll_event_cb),NULL);
+
+  /* Ask to receive events the drawing area doesn't normally
+   * subscribe to. In particular, we need to ask for the
+   * button press and motion notify events that want to handle.
+   */
+  gtk_widget_set_events (waterfall, gtk_widget_get_events (waterfall)
+                     | GDK_BUTTON_PRESS_MASK
+                     | GDK_BUTTON_RELEASE_MASK
+                     | GDK_BUTTON1_MOTION_MASK
+                     | GDK_SCROLL_MASK
+                     | GDK_POINTER_MOTION_MASK
+                     | GDK_POINTER_MOTION_HINT_MASK);
+
+  return waterfall;
+}
diff --git a/psk_waterfall.h b/psk_waterfall.h
new file mode 100644 (file)
index 0000000..0209c1a
--- /dev/null
@@ -0,0 +1,22 @@
+/* Copyright (C)
+* 2015 - 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.
+*
+*/
+
+
+void psk_waterfall_update(float *data);
+GtkWidget* psk_waterfall_init(int width,int height);
diff --git a/radio.c b/radio.c
index 9cb01300c377a09dc7799b6c826cef637c66aad9..639537c4fcb86ef6cb5db27f56fd6399dd7845f8 100644 (file)
--- a/radio.c
+++ b/radio.c
@@ -83,7 +83,7 @@ int display_toolbar=1;
 int toolbar_dialog_buttons=1;
 
 double volume=0.2;
-double mic_gain=1.5;
+double mic_gain=0.5;
 
 int rx_dither=0;
 int rx_random=0;
@@ -111,8 +111,8 @@ int nr2_gain_method=2; // 0=Linear 1=Log 2=gamma
 int nr2_npe_method=0; // 0=OSMS 1=MMSE
 int nr2_ae=1; // 0=disable 1=enable
 
-int tune_drive=6;
-int drive=60;
+double tune_drive=0.1;
+double drive=0.6;
 
 int receivers=2;
 int adc[2]={0,1};
@@ -180,10 +180,18 @@ int alc=TXA_ALC_PK;
 
 int local_audio=0;
 
+int eer_pwm_min=100;
+int eer_pwm_max=800;
+
+int tx_filter_low=200;
+int tx_filter_high=3100;
+
 #ifdef FREEDV
 char freedv_tx_text_data[64];
 #endif
 
+static int pre_tune_mode;
+
 void init_radio() {
   int rc;
   rc=sem_init(&property_sem, 0, 0);
@@ -244,9 +252,28 @@ fprintf(stderr,"setTune: protocol=%d\n", protocol);
       schedule_general();
     }
     if(tune) {
+      pre_tune_mode = mode;
+      if(mode==modeCWL) {
+        setMode(modeLSB);
+      } else if(mode==modeCWU) {
+        setMode(modeUSB);
+      }
+      
+      if(mode==modeLSB || mode==modeCWL || mode==modeDIGL) {
+        SetTXAPostGenToneFreq(CHANNEL_TX,-(double)cw_keyer_sidetone_frequency);
+      } else {
+        SetTXAPostGenToneFreq(CHANNEL_TX,(double)cw_keyer_sidetone_frequency);
+      }
+      SetTXAPostGenToneMag(CHANNEL_TX,0.99999);
+      SetTXAPostGenMode(CHANNEL_TX,0);
+      SetTXAPostGenRun(CHANNEL_TX,1);
       SetChannelState(CHANNEL_RX0,0,1);
       SetChannelState(CHANNEL_TX,1,0);
     } else {
+      SetTXAPostGenRun(CHANNEL_TX,0);
+      if(pre_tune_mode==modeCWL || pre_tune_mode==modeCWU) {
+        setMode(pre_tune_mode);
+      }
       SetChannelState(CHANNEL_TX,0,1);
       SetChannelState(CHANNEL_RX0,1,0);
     }
@@ -258,8 +285,6 @@ int getTune() {
 }
 
 int isTransmitting() {
-  BANDSTACK_ENTRY *entry;
-  entry=bandstack_entry_get_current();
   return ptt || mox || tune;
 }
 
@@ -313,26 +338,22 @@ long long getFrequency() {
 }
 
 double getDrive() {
-    //return (double)drive/255.0;
-    return (double)drive;
+    return drive;
 }
 
 void setDrive(double value) {
-    //drive=(int)(value*255.0);
-    drive=(int)(value);
+    drive=value;
     if(protocol==NEW_PROTOCOL) {
       schedule_high_priority(6);
     }
 }
 
 double getTuneDrive() {
-    //return (double)tune_drive/255.0;
-    return (double)tune_drive;
+    return tune_drive;
 }
 
 void setTuneDrive(double value) {
-    //tune_drive=(int)(value*255.0);
-    tune_drive=(int)(value);
+    tune_drive=value;
     if(protocol==NEW_PROTOCOL) {
       schedule_high_priority(7);
     }
@@ -433,11 +454,11 @@ void radioRestoreState() {
     value=getProperty("volume");
     if(value) volume=atof(value);
     value=getProperty("drive");
-    if(value) drive=atoi(value);
+    if(value) {drive=atof(value); if(drive>1.0) drive=1.0;}
     value=getProperty("tune_drive");
-    if(value) tune_drive=atoi(value);
+    if(value) {tune_drive=atof(value); if(tune_drive>1.0) tune_drive=1.0;}
     value=getProperty("mic_gain");
-    if(value) mic_gain=atof(value);
+    if(value) { mic_gain=atof(value); if(mic_gain>1.0) mic_gain=1.0; }
     value=getProperty("mic_boost");
     if(value) mic_boost=atof(value);
     value=getProperty("mic_linein");
@@ -576,9 +597,9 @@ void radioSaveState() {
     setProperty("volume",value);
     sprintf(value,"%f",mic_gain);
     setProperty("mic_gain",value);
-    sprintf(value,"%d",drive);
+    sprintf(value,"%f",drive);
     setProperty("drive",value);
-    sprintf(value,"%d",tune_drive);
+    sprintf(value,"%f",tune_drive);
     setProperty("tune_drive",value);
     sprintf(value,"%d",mic_boost);
     setProperty("mic_boost",value);
diff --git a/radio.h b/radio.h
index dd2e597f99c18e8ed5144c209afc2d5b2cfd731e..b6af033c97cb1ece426a9764a1e9e6bd288c3f2f 100644 (file)
--- a/radio.h
+++ b/radio.h
@@ -119,8 +119,8 @@ extern int mic_bias_enabled;
 extern int mic_ptt_enabled;
 extern int mic_ptt_tip_bias_ring;
 
-extern int tune_drive;
-extern int drive;
+extern double tune_drive;
+extern double drive;
 
 int receivers;
 int adc[2];
@@ -191,6 +191,12 @@ extern int alc;
 
 extern int local_audio;
 
+extern int eer_pwm_min;
+extern int eer_pwm_max;
+
+extern int tx_filter_low;
+extern int tx_filter_high;
+
 extern void init_radio();
 extern void setSampleRate(int rate);
 extern int getSampleRate();
index 149cc69768f0d6276e060924da2a203bf2d8cfb4..df843af9a7ba1c00d630fae2401dd7b046950e4a 100644 (file)
Binary files a/release/pihpsdr.tar and b/release/pihpsdr.tar differ
index 6696c859a34fef424c094a6aedf1e17f9b15551d..7692b8f80f2efff7fa0175113e94686e03d5a6b5 100755 (executable)
@@ -1,7 +1,9 @@
 rm -rf /usr/local/lib/libwdsp.so
+rm -rf /usr/local/lib/libpsk.so
 rm -rf /usr/local/lib/libcodec2.so
 rm -rf /usr/local/lib/libSoapySDR.so
 cp libwdsp.so /usr/local/lib
+cp libpsk.so /usr/local/lib
 cp libcodec2.so.0.5 /usr/local/lib
 cp libSoapySDR.so.0.5-1 /usr/local/lib
 cd /usr/local/lib; ln -s libcodec2.so.0.5 libcodec2.so
diff --git a/release/pihpsdr/libpsk.so b/release/pihpsdr/libpsk.so
new file mode 100755 (executable)
index 0000000..0ace61f
Binary files /dev/null and b/release/pihpsdr/libpsk.so differ
index 7bc8d9120d0440879021b00f045f25b86fef0b36..ffbec55080275601bd6ecca86f1957557f723313 100755 (executable)
Binary files a/release/pihpsdr/pihpsdr and b/release/pihpsdr/pihpsdr differ
diff --git a/signal.c b/signal.c
new file mode 100644 (file)
index 0000000..9db7c7e
--- /dev/null
+++ b/signal.c
@@ -0,0 +1,61 @@
+/* Copyright (C)
+* 2015 - 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 <math.h>
+
+#include "radio.h"
+#include "signal.h"
+
+#define PI 3.1415926535897932
+
+double sineWave(double* buf, int samples, double sinphase, double freq) {
+    double phaseStep = freq / (double)sample_rate * 2.0 * PI;
+    double cosval = cos(sinphase);
+    double sinval = sin(sinphase);
+    double cosdelta = cos(phaseStep);
+    double sindelta = sin(phaseStep);
+    int i;
+
+    for (i = 0; i < samples; i++) {
+        double tmpval = cosval * cosdelta - sinval * sindelta;
+        sinval = cosval * sindelta + sinval * cosdelta;
+        cosval = tmpval;
+        buf[i*2] = sinval;
+        sinphase += phaseStep;
+    }
+    return sinphase;
+}
+
+double cosineWave(double* buf, int samples, double cosphase, double freq) {
+    double phaseStep = freq / (double)sample_rate * 2.0 * PI;
+    double cosval = cos(cosphase);
+    double sinval = sin(cosphase);
+    double cosdelta = cos(phaseStep);
+    double sindelta = sin(phaseStep);
+    int i;
+
+    for (i = 0; i < samples; i++) {
+        double tmpval = cosval * cosdelta - sinval * sindelta;
+        sinval = cosval * sindelta + sinval * cosdelta;
+        cosval = tmpval;
+        buf[(i*2)+1] = cosval;
+        cosphase += phaseStep;
+    }
+    return cosphase;
+}
diff --git a/signal.h b/signal.h
new file mode 100644 (file)
index 0000000..85f781c
--- /dev/null
+++ b/signal.h
@@ -0,0 +1,21 @@
+/* Copyright (C)
+* 2015 - 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.
+*
+*/
+
+double sineWave(double* buf, int samples, double sinphase, double freq);
+double cosineWave(double* buf, int samples, double cosphase, double freq);
index 8e9847427a91f50acd4ffc1c3c200522d76f9ce8..5f06c43caeb362fee177d2979f9e3c77aa665b83 100644 (file)
--- a/sliders.c
+++ b/sliders.c
@@ -51,7 +51,7 @@ static GtkWidget *sliders;
 #define TUNE_DRIVE 5
 #define ATTENUATION 5
 
-#define MIC_GAIN_FUDGE 25.0
+//#define MIC_GAIN_FUDGE 25.0
 
 static gint scale_timer;
 static int scale_status=NONE;
@@ -193,7 +193,7 @@ void set_af_gain(double value) {
 }
 
 static void micgain_value_changed_cb(GtkWidget *widget, gpointer data) {
-    mic_gain=gtk_range_get_value(GTK_RANGE(widget))/MIC_GAIN_FUDGE;
+    mic_gain=gtk_range_get_value(GTK_RANGE(widget))/100.0;
 fprintf(stderr,"micgain_value_changed: %f\n",mic_gain);
 }
 
@@ -201,7 +201,7 @@ void set_mic_gain(double value) {
   mic_gain=value;
 fprintf(stderr,"set_mic_gain: %f\n",mic_gain);
   if(display_sliders) {
-    gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_gain*MIC_GAIN_FUDGE);
+    gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_gain*100.0);
   } else {
     if(scale_status!=MIC_GAIN) {
       if(scale_status!=NONE) {
@@ -216,7 +216,7 @@ fprintf(stderr,"set_mic_gain: %f\n",mic_gain);
       GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog));
       mic_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.00);
       gtk_widget_set_size_request (mic_gain_scale, 400, 30);
-      gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_gain*MIC_GAIN_FUDGE);
+      gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_gain*100.0);
       gtk_widget_show(mic_gain_scale);
       gtk_container_add(GTK_CONTAINER(content),mic_gain_scale);
       scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL);
@@ -224,7 +224,7 @@ fprintf(stderr,"set_mic_gain: %f\n",mic_gain);
       int result=gtk_dialog_run(GTK_DIALOG(scale_dialog));
     } else {
       g_source_remove(scale_timer);
-      gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_gain*MIC_GAIN_FUDGE);
+      gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_gain*100.0);
       scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL);
     }
 
@@ -234,8 +234,7 @@ fprintf(stderr,"set_mic_gain: %f\n",mic_gain);
 void set_drive(double value) {
   setDrive(value);
   if(display_sliders) {
-    //gtk_range_set_value (GTK_RANGE(drive_scale),value*100.0);
-    gtk_range_set_value (GTK_RANGE(drive_scale),value);
+    gtk_range_set_value (GTK_RANGE(drive_scale),value*100.0);
   } else {
     if(scale_status!=DRIVE) {
       if(scale_status!=NONE) {
@@ -248,11 +247,9 @@ void set_drive(double value) {
       scale_status=DRIVE;
       scale_dialog=gtk_dialog_new_with_buttons("Drive",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
       GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog));
-      //drive_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.00);
-      drive_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 255.0, 1.00);
+      drive_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.00);
       gtk_widget_set_size_request (drive_scale, 400, 30);
-      //gtk_range_set_value (GTK_RANGE(drive_scale),value*100.0);
-      gtk_range_set_value (GTK_RANGE(drive_scale),value);
+      gtk_range_set_value (GTK_RANGE(drive_scale),value*100.0);
       gtk_widget_show(drive_scale);
       gtk_container_add(GTK_CONTAINER(content),drive_scale);
       scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL);
@@ -260,23 +257,20 @@ void set_drive(double value) {
       int result=gtk_dialog_run(GTK_DIALOG(scale_dialog));
     } else {
       g_source_remove(scale_timer);
-      //gtk_range_set_value (GTK_RANGE(drive_scale),value*100.0);
-      gtk_range_set_value (GTK_RANGE(drive_scale),value);
+      gtk_range_set_value (GTK_RANGE(drive_scale),value*100.0);
       scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL);
     }
   }
 }
 
 static void drive_value_changed_cb(GtkWidget *widget, gpointer data) {
-  //setDrive(gtk_range_get_value(GTK_RANGE(drive_scale))/100.0);
-  setDrive(gtk_range_get_value(GTK_RANGE(drive_scale)));
+  setDrive(gtk_range_get_value(GTK_RANGE(drive_scale))/100.0);
 }
 
 void set_tune(double value) {
   setTuneDrive(value);
   if(display_sliders) {
-    //gtk_range_set_value (GTK_RANGE(tune_scale),value*100.0);
-    gtk_range_set_value (GTK_RANGE(tune_scale),value);
+    gtk_range_set_value (GTK_RANGE(tune_scale),value*100.0);
   } else {
     if(scale_status!=TUNE_DRIVE) {
       if(scale_status!=NONE) {
@@ -289,11 +283,9 @@ void set_tune(double value) {
       scale_status=TUNE_DRIVE;
       scale_dialog=gtk_dialog_new_with_buttons("Tune Drive",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
       GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog));
-      //tune_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.00);
-      tune_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 255.0, 1.00);
+      tune_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.00);
       gtk_widget_set_size_request (tune_scale, 400, 30);
-      //gtk_range_set_value (GTK_RANGE(tune_scale),value*100.0);
-      gtk_range_set_value (GTK_RANGE(tune_scale),value);
+      gtk_range_set_value (GTK_RANGE(tune_scale),value*100.0);
       gtk_widget_show(tune_scale);
       gtk_container_add(GTK_CONTAINER(content),tune_scale);
       scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL);
@@ -301,16 +293,14 @@ void set_tune(double value) {
       int result=gtk_dialog_run(GTK_DIALOG(scale_dialog));
     } else {
       g_source_remove(scale_timer);
-      //gtk_range_set_value (GTK_RANGE(tune_scale),value*100.0);
-      gtk_range_set_value (GTK_RANGE(tune_scale),value);
+      gtk_range_set_value (GTK_RANGE(tune_scale),value*100.0);
       scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL);
     }
   }
 }
 
 static void tune_value_changed_cb(GtkWidget *widget, gpointer data) {
-  //setTuneDrive(gtk_range_get_value(GTK_RANGE(tune_scale))/100.0);
-  setTuneDrive(gtk_range_get_value(GTK_RANGE(tune_scale)));
+  setTuneDrive(gtk_range_get_value(GTK_RANGE(tune_scale))/100.0);
 }
 
 GtkWidget *sliders_init(int my_width, int my_height, GtkWidget* parent) {
@@ -366,7 +356,7 @@ GtkWidget *sliders_init(int my_width, int my_height, GtkWidget* parent) {
   gtk_grid_attach(GTK_GRID(sliders),mic_gain_label,0,1,1,1);
 
   mic_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.0);
-  gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_gain*MIC_GAIN_FUDGE);
+  gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_gain*100.0);
   gtk_widget_show(mic_gain_scale);
   gtk_grid_attach(GTK_GRID(sliders),mic_gain_scale,1,1,2,1);
   g_signal_connect(G_OBJECT(mic_gain_scale),"value_changed",G_CALLBACK(micgain_value_changed_cb),NULL);
@@ -376,10 +366,8 @@ GtkWidget *sliders_init(int my_width, int my_height, GtkWidget* parent) {
   gtk_widget_show(drive_label);
   gtk_grid_attach(GTK_GRID(sliders),drive_label,3,1,1,1);
 
-  //drive_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.0);
-  drive_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 255.0, 1.0);
-  //gtk_range_set_value (GTK_RANGE(drive_scale),getDrive()*100.0);
-  gtk_range_set_value (GTK_RANGE(drive_scale),getDrive());
+  drive_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.0);
+  gtk_range_set_value (GTK_RANGE(drive_scale),getDrive()*100.0);
   gtk_widget_show(drive_scale);
   gtk_grid_attach(GTK_GRID(sliders),drive_scale,4,1,2,1);
   g_signal_connect(G_OBJECT(drive_scale),"value_changed",G_CALLBACK(drive_value_changed_cb),NULL);
@@ -389,10 +377,8 @@ GtkWidget *sliders_init(int my_width, int my_height, GtkWidget* parent) {
   gtk_widget_show(tune_label);
   gtk_grid_attach(GTK_GRID(sliders),tune_label,6,1,1,1);
 
-  //tune_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.0);
-  tune_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 255.0, 1.0);
-  //gtk_range_set_value (GTK_RANGE(tune_scale),getTuneDrive()*100.0);
-  gtk_range_set_value (GTK_RANGE(tune_scale),getTuneDrive());
+  tune_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.0);
+  gtk_range_set_value (GTK_RANGE(tune_scale),getTuneDrive()*100.0);
   gtk_widget_show(tune_scale);
   gtk_grid_attach(GTK_GRID(sliders),tune_scale,7,1,2,1);
   g_signal_connect(G_OBJECT(tune_scale),"value_changed",G_CALLBACK(tune_value_changed_cb),NULL);
index e9c5ccbabead5a2640294fc37ec09da66dfdb752..4aad9ab544c66e618c759db667631fa2ee21ee9e 100644 (file)
--- a/toolbar.c
+++ b/toolbar.c
@@ -20,7 +20,7 @@
 #include <gtk/gtk.h>
 #include <semaphore.h>
 #include <stdio.h>
-#ifdef INCLUDE_GPIO
+#ifdef GPIO
 #include "gpio.h"
 #endif
 #include "toolbar.h"
@@ -663,7 +663,7 @@ static void stop() {
   } else {
     new_protocol_stop();
   }
-#ifdef INCLUDE_GPIO
+#ifdef GPIO
   gpio_close();
 #endif
 }
@@ -984,16 +984,22 @@ fprintf(stderr,"mox_cb\n");
   }
   if(getMox()==1) {
     setMox(0);
+    if(ptt) {
+      ptt=0;
+    }
   } else if(canTransmit() || tx_out_of_band) {
     setMox(1);
   }
+fprintf(stderr,"mox_cb: mox now %d\n",mox);
   vfo_update(NULL);
 }
 
 int ptt_update(void *data) {
+fprintf(stderr,"ptt_update\n");
   if(mode!=modeCWU && mode!=modeCWL) {
     mox_cb(NULL,NULL);
   }
+fprintf(stderr,"ptt_update: mox=%d ptt=%d tune=%d\n",mox,ptt,tune);
   return 0;
 }
 
@@ -1007,6 +1013,7 @@ fprintf(stderr,"tune_cb\n");
   } else if(canTransmit() || tx_out_of_band) {
     setTune(1);
   }
+fprintf(stderr,"tune_cb: calling vfo_update\n");
   vfo_update(NULL);
 }
 
@@ -1217,6 +1224,7 @@ void sim_mox_cb(GtkWidget *widget, gpointer data) {
   } else {
     mox_cb((GtkWidget *)NULL, (gpointer)NULL);
   }
+  vfo_update(NULL);
 }
 
 void sim_function_cb(GtkWidget *widget, gpointer data) {
index ae414d9ac4e55612aa47aa817af1265e35c21249..b1bccb90bbe6af78f0fa930f5222ff8e62dfd7bb 100644 (file)
 #ifdef FREEDV
 #include "freedv.h"
 #endif
+#ifdef PSK
+#include "main.h"
+#include "psk.h"
+#endif
 
 #define PI 3.1415926535897932F
 #define min(x,y) (x<y?x:y)
@@ -95,6 +99,16 @@ int local_mode=m;
       close_freedv();
     }
 #endif
+#ifdef PSK
+    if(mode!=modePSK && m==modePSK) {
+      local_mode=modeUSB;
+      //init_psk();
+      show_psk();
+    } else if(mode==modePSK && m!=modePSK) {
+      //close_psk();
+      show_waterfall();
+    }
+#endif
 fprintf(stderr,"setMode: %d mode=%d\n",receiver,mode);
     setRXMode(receiver,local_mode);
 fprintf(stderr,"setMode: %d mode=%d\n",CHANNEL_TX,mode);
@@ -128,6 +142,34 @@ fprintf(stderr,"setFilter: fl=%f fh=%f\n",fl,fh);
     SetRXASNBAOutputBandwidth(receiver, (double)filterLow, (double)filterHigh);
 
     SetTXABandpassFreqs(CHANNEL_TX, fl,fh);
+/*
+    switch(mode) {
+        case modeCWL:
+        case modeLSB:
+        case modeDIGL:
+            SetTXABandpassFreqs(CHANNEL_TX, -(double)tx_filter_high,-(double)tx_filter_low);
+            break;
+        case modeCWU:
+        case modeUSB:
+        case modeDIGU:
+#ifdef FREEDV
+        case modeFREEDV:
+#endif
+            SetTXABandpassFreqs(CHANNEL_TX, (double)tx_filter_low,(double)tx_filter_high);
+            break;
+        case modeDSB:
+        case modeAM:
+        case modeSAM:
+            SetTXABandpassFreqs(CHANNEL_TX, -(double)tx_filter_high,(double)tx_filter_high);
+            break;
+        case modeFMN:
+            SetTXABandpassFreqs(CHANNEL_TX, -8000.0,8000);
+            break;
+        case modeDRM:
+            SetTXABandpassFreqs(CHANNEL_TX, 7000.0,17000);
+            break;
+    }
+*/
 }
 
 int getFilterLow() {
@@ -187,7 +229,15 @@ static void setupTX(int tx) {
     SetTXAAMSQRun(tx, 0);
     SetTXACompressorRun(tx, 0);
     SetTXAosctrlRun(tx, 0);
+
+    SetTXAPreGenMode(tx, 0);
+    SetTXAPreGenToneMag(tx, 0.0);
+    SetTXAPreGenToneFreq(tx, 0.0);
     SetTXAPreGenRun(tx, 0);
+
+    SetTXAPostGenMode(tx, 0);
+    SetTXAPostGenToneMag(tx, 0.0);
+    SetTXAPostGenToneFreq(tx, 0.0);
     SetTXAPostGenRun(tx, 0);
 
     SetChannelState(tx,1,0);
@@ -293,6 +343,14 @@ void wdsp_init(int rx,int pixels,int protocol) {
     setupRX(rx);
     setupTX(CHANNEL_TX);
 
+#ifdef PSK
+    XCreateAnalyzer(CHANNEL_PSK, &success, PSK_BUFFER_SIZE, 1, 1, "");
+        if (success != 0) {
+            fprintf(stderr, "XCreateAnalyzer CHANNEL_PSK failed: %d\n" ,success);
+        }
+    initAnalyzer(CHANNEL_PSK,PSK_BUFFER_SIZE);
+#endif
+
 }
 
 void wdsp_new_sample_rate(int rate) {
@@ -331,7 +389,15 @@ static void initAnalyzer(int channel,int buffer_size) {
 
     int max_w = fft_size + (int) MIN(KEEP_TIME * (double) SPECTRUM_UPDATES_PER_SECOND, KEEP_TIME * (double) fft_size * (double) SPECTRUM_UPDATES_PER_SECOND);
 
-    fprintf(stderr,"SetAnalyzer channel=%d\n",channel);
+    fprintf(stderr,"SetAnalyzer channel=%d buffer_size=%d\n",channel,buffer_size);
+#ifdef PSK
+    if(channel==CHANNEL_PSK) {
+      data_type=0;
+      fft_size=1024;
+      overlap=0;
+      pixels=spectrumWIDTH;
+    }
+#endif
     SetAnalyzer(channel,
             n_pixout,
             spur_elimination_ffts, //number of LO frequencies = number of ffts used in elimination