From de19df32fd5e5c5b7345848a819bb2ce9aeb34c7 Mon Sep 17 00:00:00 2001 From: John Melton - G0ORX Date: Sun, 12 Nov 2017 10:16:54 +0000 Subject: [PATCH] v1.2 source update --- Makefile | 84 +- about_menu.c | 167 +++ about_menu.h | 20 + agc_menu.c | 59 +- ant_menu.c | 283 ++-- audio.c | 31 +- audio_menu.c | 245 ---- audio_waterfall.c | 290 ++++ audio_waterfall.h | 33 + band.c | 179 ++- band.h | 26 + band_menu.c | 38 +- band_menu.h | 5 +- bandstack_menu.c | 40 +- button_text.c | 6 +- channel.h | 3 +- cw_menu.c | 24 +- discovered.h | 3 + discovery.c | 63 +- discovery.h | 2 +- display_menu.c | 23 +- diversity_menu.c | 22 +- dsp_menu.c | 25 +- encoder_menu.c | 115 +- equalizer_menu.c | 31 +- error_handler.c | 36 + error_handler.h | 1 + exit_menu.c | 21 +- ext.c | 156 ++ ext.h | 52 + fft_menu.c | 63 +- filter.c | 22 +- filter_menu.c | 74 +- fm_menu.c | 17 +- freedv.c | 250 +++- freedv.h | 37 +- freedv_menu.c | 120 +- freqent_menu.c | 42 +- frequency.c | 39 +- frequency.h | 6 +- general_menu.c | 17 +- gpio.c | 33 +- gpio.h | 14 +- gpio_mraa.c | 2 +- i2c.c | 283 ++-- i2c.h | 1 + led.c | 27 +- led.h | 5 +- main.c | 74 +- main.h | 16 - meter.c | 339 ++++- meter.h | 4 +- meter_menu.c | 40 +- mode.c | 4 - mode.h | 12 - mode_menu.c | 30 +- new_discovery.c | 16 +- new_menu.c | 70 +- new_menu.h | 5 + new_protocol.c | 1127 ++++++++++----- new_protocol.h | 27 +- noise_menu.c | 151 +- oc_menu.c | 41 +- old_discovery.c | 16 +- old_protocol.c | 814 +++++++---- old_protocol.h | 1 - pa_menu.c | 18 +- property.c | 7 +- property.h | 8 +- ps_menu.c | 525 +++++++ ps_menu.h | 20 + radio.c | 539 ++++--- radio.h | 54 +- radio_menu.c | 62 +- radio_menu.h | 2 +- radioberry.c | 223 +-- receiver.c | 449 ++++-- receiver.h | 40 +- rigctl.c | 3485 ++++++++++++++++++++++++++++++++++++--------- rigctl.h | 13 +- rigctl_menu.c | 233 +++ rigctl_menu.h | 31 + rit.c | 171 --- rx_menu.c | 63 +- rx_panadapter.c | 140 +- signal.c | 61 - sliders.c | 225 +-- sliders.h | 13 +- soundio.c | 1 - splash.c | 73 - step_menu.c | 25 +- store_menu.c | 32 +- test_menu.c | 17 +- toolbar.c | 330 +---- toolbar.h | 5 +- transmitter.c | 509 +++++-- transmitter.h | 55 + tx_menu.c | 287 +++- tx_menu.h | 3 +- tx_panadapter.c | 111 +- update.c | 4 +- vfo.c | 276 ++-- vfo.h | 4 +- vfo_menu.c | 111 +- vox.c | 18 +- vox_menu.c | 37 +- waterfall.c | 53 +- xvtr_menu.c | 85 +- 108 files changed, 10256 insertions(+), 4084 deletions(-) create mode 100644 about_menu.c create mode 100644 about_menu.h delete mode 100644 audio_menu.c create mode 100644 audio_waterfall.c create mode 100644 audio_waterfall.h create mode 100644 error_handler.c create mode 100644 error_handler.h create mode 100644 ext.c create mode 100644 ext.h create mode 100644 ps_menu.c create mode 100644 ps_menu.h create mode 100644 rigctl_menu.c create mode 100644 rigctl_menu.h delete mode 100644 rit.c delete mode 100644 signal.c delete mode 100644 splash.c diff --git a/Makefile b/Makefile index 91e27b2..2c4197c 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,9 @@ GIT_VERSION := $(shell git describe --abbrev=0 --tags) # uncomment the line below to include GPIO GPIO_INCLUDE=GPIO +# uncomment the line below to include MCP23017 I2C +#I2C_INCLUDE=I2C + # uncomment the line below to include USB Ozy support # USBOZY_INCLUDE=USBOZY @@ -13,7 +16,10 @@ GPIO_INCLUDE=GPIO #PSK_INCLUDE=PSK # uncomment the line to below include support for FreeDV codec2 -#FREEDV_INCLUDE=FREEDV +FREEDV_INCLUDE=FREEDV + +# uncomment the line below to include Pure Signal support +#PURESIGNAL_INCLUDE=PURESIGNAL # uncomment the line to below include support for sx1509 i2c expander #SX1509_INCLUDE=sx1509 @@ -21,22 +27,35 @@ GPIO_INCLUDE=GPIO # uncomment the line to below include support local CW keyer #LOCALCW_INCLUDE=LOCALCW -# uncomment the line below to include MCP23017 I2C -#I2C_INCLUDE=I2C - -#uncomment the line below for the platform being compiled on -UNAME_N=raspberrypi -#UNAME_N=odroid -#UNAME_N=up -#UNAME_N=pine64 -#UNAME_N=jetsen - CC=gcc LINK=gcc # uncomment the line below for various debug facilities #DEBUG_OPTION=-D DEBUG +ifeq ($(PURESIGNAL_INCLUDE),PURESIGNAL) +PURESIGNAL_OPTIONS=-D PURESIGNAL +PURESIGNAL_SOURCES= \ +ps_menu.c +PURESIGNAL_HEADERS= \ +ps_menu.h +PURESIGNAL_OBJS= \ +ps_menu.o +endif + +ifeq ($(REMOTE_INCLUDE),REMOTE) +REMOTE_OPTIONS=-D REMOTE +REMOTE_SOURCES= \ +remote_radio.c \ +remote_receiver.c +REMOTE_HEADERS= \ +remote_radio.h \ +remote_receiver.h +REMOTE_OBJS= \ +remote_radio.o \ +remote_receiver.o +endif + ifeq ($(USBOZY_INCLUDE),USBOZY) USBOZY_OPTIONS=-D USBOZY USBOZY_LIBS=-lusb-1.0 @@ -152,7 +171,7 @@ GTKLIBS=`pkg-config --libs gtk+-3.0` AUDIO_LIBS=-lasound #AUDIO_LIBS=-lsoundio -OPTIONS=-g -Wno-deprecated-declarations -D $(UNAME_N) $(RADIOBERRY_OPTIONS) $(USBOZY_OPTIONS) $(I2C_OPTIONS) $(GPIO_OPTIONS) $(LIMESDR_OPTIONS) $(FREEDV_OPTIONS) $(LOCALCW_OPTIONS) $(PSK_OPTIONS) -D GIT_DATE='"$(GIT_DATE)"' -D GIT_VERSION='"$(GIT_VERSION)"' $(DEBUG_OPTION) -O3 +OPTIONS=-g -Wno-deprecated-declarations $(PURESIGNAL_OPTIONS) $(REMOTE_OPTIONS) $(RADIOBERRY_OPTIONS) $(USBOZY_OPTIONS) $(I2C_OPTIONS) $(GPIO_OPTIONS) $(LIMESDR_OPTIONS) $(FREEDV_OPTIONS) $(LOCALCW_OPTIONS) $(PSK_OPTIONS) -D GIT_DATE='"$(GIT_DATE)"' -D GIT_VERSION='"$(GIT_VERSION)"' $(DEBUG_OPTION) -O3 LIBS=-lrt -lm -lwdsp -lpthread $(AUDIO_LIBS) $(USBOZY_LIBS) $(PSKLIBS) $(GTKLIBS) $(GPIO_LIBS) $(SOAPYSDRLIBS) $(FREEDVLIBS) INCLUDES=$(GTKINCLUDES) @@ -163,6 +182,7 @@ PROGRAM=pihpsdr SOURCES= \ audio.c \ +audio_waterfall.c \ band.c \ configure.c \ frequency.c \ @@ -171,6 +191,7 @@ discovery.c \ filter.c \ main.c \ new_menu.c \ +about_menu.c \ exit_menu.c \ radio_menu.c \ rx_menu.c \ @@ -210,6 +231,7 @@ property.c \ radio.c \ receiver.c \ rigctl.c \ +rigctl_menu.c \ toolbar.c \ transmitter.c \ sliders.c \ @@ -222,11 +244,14 @@ update.c \ store.c \ store_menu.c \ memory.c \ -led.c +led.c \ +ext.c \ +error_handler.c HEADERS= \ audio.h \ +audio_waterfall.h \ agc.h \ alex.h \ band.h \ @@ -238,6 +263,7 @@ discovered.h \ discovery.h \ filter.h \ new_menu.h \ +about_menu.h \ rx_menu.h \ exit_menu.h \ radio_menu.h \ @@ -276,6 +302,7 @@ property.h \ radio.h \ receiver.h \ rigctl.h \ +rigctl_menu.h \ toolbar.h \ transmitter.h \ sliders.h \ @@ -288,11 +315,14 @@ update.h \ store.h \ store_menu.h \ memory.h \ -led.h +led.h \ +ext.h \ +error_handler.h OBJS= \ audio.o \ +audio_waterfall.o \ band.o \ configure.o \ frequency.o \ @@ -302,6 +332,7 @@ filter.o \ version.o \ main.o \ new_menu.o \ +about_menu.o \ rx_menu.o \ exit_menu.o \ radio_menu.o \ @@ -341,6 +372,7 @@ property.o \ radio.o \ receiver.o \ rigctl.o \ +rigctl_menu.o \ toolbar.o \ transmitter.o \ sliders.o \ @@ -352,15 +384,17 @@ update.o \ store.o \ store_menu.o \ memory.o \ -led.o +led.o \ +ext.o \ +error_handler.o -all: prebuild $(PROGRAM) $(HEADERS) $(RADIOBERRY_HEADERS) $(USBOZY_HEADERS) $(LIMESDR_HEADERS) $(FREEDV_HEADERS) $(LOCALCW_HEADERS) $(I2C_HEADERS) $(GPIO_HEADERS) $(PSK_HEADERS) $(SOURCES) $(USBOZY_SOURCES) $(LIMESDR_SOURCES) $(FREEDV_SOURCES) $(I2C_SOURCES) $(GPIO_SOURCES) $(PSK_SOURCES) $(RADIOBERRY_SOURCES) +all: prebuild $(PROGRAM) $(HEADERS) $(REMOTE_HEADERS) $(RADIOBERRY_HEADERS) $(USBOZY_HEADERS) $(LIMESDR_HEADERS) $(FREEDV_HEADERS) $(LOCALCW_HEADERS) $(I2C_HEADERS) $(GPIO_HEADERS) $(PSK_HEADERS) $(PURESIGNAL_HEADERS) $(SOURCES) $(REMOTE_SOURCES) $(USBOZY_SOURCES) $(LIMESDR_SOURCES) $(FREEDV_SOURCES) $(I2C_SOURCES) $(GPIO_SOURCES) $(PSK_SOURCES) $(RADIOBERRY_SOURCES) $(PURESIGNAL_SOURCES) prebuild: rm -f version.o -$(PROGRAM): $(OBJS) $(USBOZY_OBJS) $(LIMESDR_OBJS) $(FREEDV_OBJS) $(LOCALCW_OBJS) $(I2C_OBJS) $(GPIO_OBJS) $(PSK_OBJS) $(RADIOBERRY_OBJS) - $(LINK) -o $(PROGRAM) $(OBJS) $(USBOZY_OBJS) $(I2C_OBJS) $(GPIO_OBJS) $(LIMESDR_OBJS) $(FREEDV_OBJS) $(LOCALCW_OBJS) $(PSK_OBJS) $(LIBS) $(RADIOBERRY_OBJS) +$(PROGRAM): $(OBJS) $(REMOTE_OBJS) $(USBOZY_OBJS) $(LIMESDR_OBJS) $(FREEDV_OBJS) $(LOCALCW_OBJS) $(I2C_OBJS) $(GPIO_OBJS) $(PSK_OBJS) $(RADIOBERRY_OBJS) $(PURESIGNAL_OBJS) + $(LINK) -o $(PROGRAM) $(OBJS) $(REMOTE_OBJS) $(USBOZY_OBJS) $(I2C_OBJS) $(GPIO_OBJS) $(LIMESDR_OBJS) $(FREEDV_OBJS) $(LOCALCW_OBJS) $(PSK_OBJS) $(LIBS) $(RADIOBERRY_OBJS) $(PURESIGNAL_OBJS) .c.o: $(COMPILE) -c -o $@ $< @@ -371,17 +405,5 @@ clean: -rm -f $(PROGRAM) install: - if [ ! -d ~/pihpsdr ];then \ - mkdir ~/pihpsdr; \ - if [ -d "./release/pihpsdr" ];then \ - cp ./release/pihpsdr/* ~/pihpsdr; \ - fi \ - fi - cp pihpsdr ~/pihpsdr - if [ -d "./release" ];then \ - cp pihpsdr ./release/pihpsdr; \ - cd release; echo $(GIT_VERSION) > pihpsdr/latest; \ - cd release; tar cvf pihpsdr_$(GIT_VERSION).tar pihpsdr; \ - cd release; tar cvf pihpsdr.tar pihpsdr; \ - fi + cp pihpsdr /usr/local/bin diff --git a/about_menu.c b/about_menu.c new file mode 100644 index 0000000..4cd0a12 --- /dev/null +++ b/about_menu.c @@ -0,0 +1,167 @@ +/* Copyright (C) +* 2017 - 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "new_menu.h" +#include "about_menu.h" +#include "discovered.h" +#include "radio.h" +#include "version.h" + +static GtkWidget *parent_window=NULL; +static GtkWidget *dialog=NULL; +static GtkWidget *label; + +static void cleanup() { + if(dialog!=NULL) { + gtk_widget_destroy(dialog); + dialog=NULL; + sub_menu=NULL; + } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); + return TRUE; +} + +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + +void about_menu(GtkWidget *parent) { + int i; + char text[2048]; + char addr[64]; + char interface_addr[64]; + + parent_window=parent; + + dialog=gtk_dialog_new(); + gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + char title[64]; + sprintf(title,"piHPSDR - About"); + gtk_window_set_title(GTK_WINDOW(dialog),title); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); + + GdkRGBA color; + color.red = 1.0; + color.green = 1.0; + color.blue = 1.0; + color.alpha = 1.0; + gtk_widget_override_background_color(dialog,GTK_STATE_FLAG_NORMAL,&color); + + GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + + GtkWidget *grid=gtk_grid_new(); + + gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); + //gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); + gtk_grid_set_column_spacing (GTK_GRID(grid),4); + //gtk_grid_set_row_spacing (GTK_GRID(grid),4); + + int row=0; + + + GtkWidget *close_b=gtk_button_new_with_label("Close"); + g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); + gtk_grid_attach(GTK_GRID(grid),close_b,0,row,1,1); + row++; + + int lines=0; + + sprintf(text,"piHPSDR by John Melton G0ORX/N6LYT"); + lines++; + sprintf(text,"%s\n\nWith help from:",text); + lines++; + sprintf(text,"%s\n Steve Wilson, KA6S, RIGCTL (CAT over TCP)",text); + lines++; + sprintf(text,"%s\n Laurence Barker, G8NJJ, USB OZY Support",text); + lines++; + sprintf(text,"%s\n Johan Maas, PA3GSB, RadioBerry support",text); + lines++; + sprintf(text,"%s\n Ken Hopper, N9VV, Testing and Documentation",text); + lines++; + lines++; + + sprintf(text,"%s\n\nBuild date: %s", text, build_date); + lines++; + + sprintf(text,"%s\nBuild version: %s", text, version); + lines++; + + sprintf(text,"%s\n\nWDSP v%d.%02d", text, GetWDSPVersion()/100, GetWDSPVersion()%100); + lines++; + + sprintf(text,"%s\n\nDevice: %s Protocol %s v%d.%d",text,radio->name,radio->protocol==ORIGINAL_PROTOCOL?"1":"2",radio->software_version/10,radio->software_version%10); + lines++; + + switch(radio->protocol) { + case ORIGINAL_PROTOCOL: + case NEW_PROTOCOL: +#ifdef USBOZY + if(d->device==DEVICE_OZY) { + sprintf(text,"%s\nDevice OZY: USB /dev/ozy",text,radio->protocol==ORIGINAL_PROTOCOL?"1":"2",radio->software_version/10,radio->software_version%10); + } else { +#endif + + strcpy(addr,inet_ntoa(radio->info.network.address.sin_addr)); + strcpy(interface_addr,inet_ntoa(radio->info.network.interface_address.sin_addr)); + sprintf(text,"%s\nDevice Mac Address: %02X:%02X:%02X:%02X:%02X:%02X",text, + radio->info.network.mac_address[0], + radio->info.network.mac_address[1], + radio->info.network.mac_address[2], + radio->info.network.mac_address[3], + radio->info.network.mac_address[4], + radio->info.network.mac_address[5]); + sprintf(text,"%s\nDevice IP Address: %s on %s (%s)",text,addr,radio->info.network.interface_name,interface_addr); + +#ifdef USBOZY + } +#endif + break; + } + lines++; + +#ifdef FREEDV + sprintf(text,"%s\n\nIncludes: FREEDV",text); + lines++; +#endif + + label=gtk_label_new(text); + gtk_label_set_justify(GTK_LABEL(label),GTK_JUSTIFY_LEFT); + gtk_grid_attach(GTK_GRID(grid),label,1,row,4,1); + gtk_container_add(GTK_CONTAINER(content),grid); + + sub_menu=dialog; + + gtk_widget_show_all(dialog); + +} diff --git a/about_menu.h b/about_menu.h new file mode 100644 index 0000000..5fb30d3 --- /dev/null +++ b/about_menu.h @@ -0,0 +1,20 @@ +/* Copyright (C) +* 2017 - 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 void about_menu(GtkWidget *parent); diff --git a/agc_menu.c b/agc_menu.c index 1f8485c..f41a5a3 100644 --- a/agc_menu.c +++ b/agc_menu.c @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include "new_menu.h" @@ -35,20 +37,29 @@ static GtkWidget *parent_window=NULL; static GtkWidget *dialog=NULL; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static gboolean agc_select_cb (GtkWidget *widget, gpointer data) { - active_receiver->agc=(int)data; + active_receiver->agc=(uintptr_t)data; //wdsp_set_agc(CHANNEL_RX0, agc); set_agc(active_receiver, active_receiver->agc); - vfo_update(NULL); + vfo_update(); } void agc_menu(GtkWidget *parent) { @@ -60,7 +71,11 @@ void agc_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + char title[64]; + sprintf(title,"piHPSDR - AGC (RX %d VFO %s)",active_receiver->id,active_receiver->id==0?"A":"B"); + gtk_window_set_title(GTK_WINDOW(dialog),title); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -78,49 +93,55 @@ void agc_menu(GtkWidget *parent) { gtk_grid_set_column_spacing (GTK_GRID(grid),5); gtk_grid_set_row_spacing (GTK_GRID(grid),5); - GtkWidget *close_b=gtk_button_new_with_label("Close AGC"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); - char label[32]; - sprintf(label,"RX %d VFO %s",active_receiver->id,active_receiver->id==0?"A":"B"); - GtkWidget *rx_label=gtk_label_new(label); - gtk_grid_attach(GTK_GRID(grid),rx_label,1,0,1,1); + int row=1; + int col=0; GtkWidget *b_off=gtk_radio_button_new_with_label(NULL,"Off"); //gtk_widget_override_font(b_off, pango_font_description_from_string("Arial 16")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_off), active_receiver->agc==AGC_OFF); gtk_widget_show(b_off); - gtk_grid_attach(GTK_GRID(grid),b_off,0,1,2,1); - g_signal_connect(b_off,"pressed",G_CALLBACK(agc_select_cb),(gpointer *)AGC_OFF); + gtk_grid_attach(GTK_GRID(grid),b_off,col,row,1,1); + g_signal_connect(b_off,"pressed",G_CALLBACK(agc_select_cb),(gpointer)(long)AGC_OFF); + + col++; GtkWidget *b_long=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_off),"Long"); //gtk_widget_override_font(b_long, pango_font_description_from_string("Arial 16")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_long), active_receiver->agc==AGC_LONG); gtk_widget_show(b_long); - gtk_grid_attach(GTK_GRID(grid),b_long,0,2,2,1); - g_signal_connect(b_long,"pressed",G_CALLBACK(agc_select_cb),(gpointer *)AGC_LONG); + gtk_grid_attach(GTK_GRID(grid),b_long,col,row,1,1); + g_signal_connect(b_long,"pressed",G_CALLBACK(agc_select_cb),(gpointer)(long)AGC_LONG); + + col++; GtkWidget *b_slow=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_long),"Slow"); //gtk_widget_override_font(b_slow, pango_font_description_from_string("Arial 16")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_slow), active_receiver->agc==AGC_SLOW); gtk_widget_show(b_slow); - gtk_grid_attach(GTK_GRID(grid),b_slow,0,3,2,1); - g_signal_connect(b_slow,"pressed",G_CALLBACK(agc_select_cb),(gpointer *)AGC_SLOW); + gtk_grid_attach(GTK_GRID(grid),b_slow,col,row,1,1); + g_signal_connect(b_slow,"pressed",G_CALLBACK(agc_select_cb),(gpointer)(long)AGC_SLOW); + + col++; GtkWidget *b_medium=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_slow),"Medium"); //gtk_widget_override_font(b_medium, pango_font_description_from_string("Arial 16")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_medium), active_receiver->agc==AGC_MEDIUM); gtk_widget_show(b_medium); - gtk_grid_attach(GTK_GRID(grid),b_medium,0,4,2,1); - g_signal_connect(b_medium,"pressed",G_CALLBACK(agc_select_cb),(gpointer *)AGC_MEDIUM); + gtk_grid_attach(GTK_GRID(grid),b_medium,col,row,1,1); + g_signal_connect(b_medium,"pressed",G_CALLBACK(agc_select_cb),(gpointer)(long)AGC_MEDIUM); + + col++; GtkWidget *b_fast=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_medium),"Fast"); //gtk_widget_override_font(b_fast, pango_font_description_from_string("Arial 16")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_fast), active_receiver->agc==AGC_FAST); gtk_widget_show(b_fast); - gtk_grid_attach(GTK_GRID(grid),b_fast,0,5,2,1); - g_signal_connect(b_fast,"pressed",G_CALLBACK(agc_select_cb),(gpointer *)AGC_FAST); + gtk_grid_attach(GTK_GRID(grid),b_fast,col,row,1,1); + g_signal_connect(b_fast,"pressed",G_CALLBACK(agc_select_cb),(gpointer)(long)AGC_FAST); gtk_container_add(GTK_CONTAINER(content),grid); diff --git a/ant_menu.c b/ant_menu.c index 9cef503..5641e52 100644 --- a/ant_menu.c +++ b/ant_menu.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include "new_menu.h" @@ -28,23 +30,31 @@ #include "radio.h" static GtkWidget *parent_window=NULL; - static GtkWidget *menu_b=NULL; - static GtkWidget *dialog=NULL; +static GtkWidget *grid=NULL; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static void rx_ant_cb(GtkWidget *widget, gpointer data) { - int b=((int)data)>>4; - int ant=((int)data)&0xF; + int b=((uintptr_t)data)>>4; + int ant=((uintptr_t)data)&0xF; BAND *band=band_get_band(b); band->alexRxAntenna=ant; if(active_receiver->id==0) { @@ -53,7 +63,7 @@ static void rx_ant_cb(GtkWidget *widget, gpointer data) { } static void rx_lime_ant_cb(GtkWidget *widget, gpointer data) { - int ant=((int)data)&0xF; + int ant=((uintptr_t)data)&0xF; BAND *band=band_get_current_band(); band->alexRxAntenna=ant; if(active_receiver->id==0) { @@ -62,8 +72,8 @@ static void rx_lime_ant_cb(GtkWidget *widget, gpointer data) { } static void tx_ant_cb(GtkWidget *widget, gpointer data) { - int b=((int)data)>>4; - int ant=((int)data)&0xF; + int b=((uintptr_t)data)>>4; + int ant=((uintptr_t)data)&0xF; BAND *band=band_get_band(b); band->alexTxAntenna=ant; if(active_receiver->id==0) { @@ -71,14 +81,175 @@ static void tx_ant_cb(GtkWidget *widget, gpointer data) { } } -void ant_menu(GtkWidget *parent) { +static void show_hf() { + int i; + for(i=0;ititle)>0) { + 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(grid),band_label,0,i+2,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(grid),rx1_b,1,i+2,1,1); + g_signal_connect(rx1_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)(long)((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(grid),rx2_b,2,i+2,1,1); + g_signal_connect(rx2_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)(long)((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(grid),rx3_b,3,i+2,1,1); + g_signal_connect(rx3_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)(long)((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(grid),ext1_b,4,i+2,1,1); + g_signal_connect(ext1_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)(long)((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(grid),ext2_b,5,i+2,1,1); + g_signal_connect(ext2_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)(long)((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(grid),xvtr_b,6,i+2,1,1); + g_signal_connect(xvtr_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)(long)((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(grid),ant_band_label,7,i+2,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(grid),tx1_b,8,i+2,1,1); + g_signal_connect(tx1_b,"pressed",G_CALLBACK(tx_ant_cb),(gpointer)(long)((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(grid),tx2_b,9,i+2,1,1); + g_signal_connect(tx2_b,"pressed",G_CALLBACK(tx_ant_cb),(gpointer)(long)((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(grid),tx3_b,10,i+2,1,1); + g_signal_connect(tx3_b,"pressed",G_CALLBACK(tx_ant_cb),(gpointer)(long)((i<<4)+2)); + } + } +} + +static void show_xvtr() { + int i; + for(i=0;ititle)>0) { + 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(grid),band_label,0,i+2,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(grid),rx1_b,1,i+2,1,1); + g_signal_connect(rx1_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)(long)(((i+BANDS)<<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(grid),rx2_b,2,i+2,1,1); + g_signal_connect(rx2_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)(long)(((i+BANDS)<<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(grid),rx3_b,3,i+2,1,1); + g_signal_connect(rx3_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)(long)(((i+BANDS)<<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(grid),ext1_b,4,i+2,1,1); + g_signal_connect(ext1_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)(long)(((i+BANDS)<<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(grid),ext2_b,5,i+2,1,1); + g_signal_connect(ext2_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)(long)(((i+BANDS)<<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(grid),xvtr_b,6,i+2,1,1); + g_signal_connect(xvtr_b,"pressed",G_CALLBACK(rx_ant_cb),(gpointer)(long)(((i+BANDS)<<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(grid),ant_band_label,7,i+2,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(grid),tx1_b,8,i+2,1,1); + g_signal_connect(tx1_b,"pressed",G_CALLBACK(tx_ant_cb),(gpointer)(long)(((i+BANDS)<<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(grid),tx2_b,9,i+2,1,1); + g_signal_connect(tx2_b,"pressed",G_CALLBACK(tx_ant_cb),(gpointer)(long)(((i+BANDS)<<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(grid),tx3_b,10,i+2,1,1); + g_signal_connect(tx3_b,"pressed",G_CALLBACK(tx_ant_cb),(gpointer)(long)(((i+BANDS)<<4)+2)); + } + } +} + +static void hf_rb_cb(GtkWidget *widget,GdkEventButton *event, gpointer data) { int i; + for(i=XVTRS-1;i>=0;i--) { + gtk_grid_remove_row (GTK_GRID(grid),i+2); + } + show_hf(); +} +static void xvtr_rb_cb(GtkWidget *widget,GdkEventButton *event, gpointer data) { + int i; + for(i=BANDS-1;i>=0;i--) { + gtk_grid_remove_row (GTK_GRID(grid),i+2); + } + show_xvtr(); +} + + +void ant_menu(GtkWidget *parent) { parent_window=parent; dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - ANT"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -89,16 +260,26 @@ void ant_menu(GtkWidget *parent) { GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog)); - GtkWidget *grid=gtk_grid_new(); + grid=gtk_grid_new(); gtk_grid_set_column_spacing (GTK_GRID(grid),10); //gtk_grid_set_row_spacing (GTK_GRID(grid),10); //gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); - GtkWidget *close_b=gtk_button_new_with_label("Close ANT"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); + GtkWidget *hf_rb=gtk_radio_button_new_with_label(NULL,"HF"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hf_rb),TRUE); + g_signal_connect(hf_rb,"toggled",G_CALLBACK(hf_rb_cb),NULL); + gtk_grid_attach(GTK_GRID(grid),hf_rb,1,0,1,1); + + GtkWidget *xvtr_rb=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(hf_rb),"XVTR"); + g_signal_connect(xvtr_rb,"toggled",G_CALLBACK(xvtr_rb_cb),NULL); + gtk_grid_attach(GTK_GRID(grid),xvtr_rb,2,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")); @@ -155,75 +336,7 @@ void ant_menu(GtkWidget *parent) { gtk_widget_show(tx3_label); gtk_grid_attach(GTK_GRID(grid),tx3_label,10,1,1,1); - for(i=0;ititle)>0) { - - 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(grid),band_label,0,i+2,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(grid),rx1_b,1,i+2,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(grid),rx2_b,2,i+2,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(grid),rx3_b,3,i+2,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(grid),ext1_b,4,i+2,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(grid),ext2_b,5,i+2,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(grid),xvtr_b,6,i+2,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(grid),ant_band_label,7,i+2,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(grid),tx1_b,8,i+2,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(grid),tx2_b,9,i+2,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(grid),tx3_b,10,i+2,1,1); - g_signal_connect(tx3_b,"pressed",G_CALLBACK(tx_ant_cb),(gpointer)((i<<4)+2)); - } - } + show_hf(); } #ifdef LIMESDR @@ -234,25 +347,25 @@ void ant_menu(GtkWidget *parent) { gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx1_none), band->alexRxAntenna==0); gtk_widget_show(rx1_none); gtk_grid_attach(GTK_GRID(grid),rx1_none,0,1,1,1); - g_signal_connect(rx1_none,"pressed",G_CALLBACK(rx_lime_ant_cb),(gpointer)0); + g_signal_connect(rx1_none,"pressed",G_CALLBACK(rx_lime_ant_cb),(gpointer)(long)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(grid),rx1_lnah,0,2,1,1); - g_signal_connect(rx1_lnah,"pressed",G_CALLBACK(rx_lime_ant_cb),(gpointer)+1); + g_signal_connect(rx1_lnah,"pressed",G_CALLBACK(rx_lime_ant_cb),(gpointer)(long)+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(grid),rx1_lnal,0,3,1,1); - g_signal_connect(rx1_lnal,"pressed",G_CALLBACK(rx_lime_ant_cb),(gpointer)2); + g_signal_connect(rx1_lnal,"pressed",G_CALLBACK(rx_lime_ant_cb),(gpointer)(long)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(grid),rx1_lnaw,0,4,1,1); - g_signal_connect(rx1_lnaw,"pressed",G_CALLBACK(rx_lime_ant_cb),(gpointer)3); + g_signal_connect(rx1_lnaw,"pressed",G_CALLBACK(rx_lime_ant_cb),(gpointer)(long)3); } #endif diff --git a/audio.c b/audio.c index 0a0fab6..b689bd7 100644 --- a/audio.c +++ b/audio.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -68,11 +67,11 @@ static int running=FALSE; static void *mic_read_thread(void *arg); -char *input_devices[16]; +char *input_devices[32]; int n_input_devices=0; //int n_selected_input_device=-1; -char *output_devices[16]; +char *output_devices[32]; int n_output_devices=0; //int n_selected_output_device=-1; @@ -83,6 +82,7 @@ int audio_open_output(RECEIVER *rx) { int dir=0; +fprintf(stderr,"audio_open_output: rx=%d audio_device=%d\n",rx->id,rx->audio_device); if(rx->audio_device<0 || rx->audio_device>=n_output_devices) { rx->audio_device=-1; return -1; @@ -108,28 +108,33 @@ fprintf(stderr,"audio_open_output: selected=%d:%s\n",rx->audio_device,selected); return -1; } +fprintf(stderr,"audio_open_output: handle=%p\n",rx->playback_handle); if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) { fprintf (stderr, "audio_open_output: cannot allocate hardware parameter structure (%s)\n", snd_strerror (err)); + audio_close_output(rx); return -1; } if ((err = snd_pcm_hw_params_any (rx->playback_handle, hw_params)) < 0) { fprintf (stderr, "audio_open_output: cannot initialize hardware parameter structure (%s)\n", snd_strerror (err)); + audio_close_output(rx); return -1; } if ((err = snd_pcm_hw_params_set_access (rx->playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { fprintf (stderr, "audio_open_output: cannot set access type (%s)\n", snd_strerror (err)); + audio_close_output(rx); return -1; } if ((err = snd_pcm_hw_params_set_format (rx->playback_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) { fprintf (stderr, "audio_open_output: cannot set sample format (%s)\n", snd_strerror (err)); + audio_close_output(rx); return -1; } @@ -137,18 +142,21 @@ fprintf(stderr,"audio_open_output: selected=%d:%s\n",rx->audio_device,selected); if ((err = snd_pcm_hw_params_set_rate_near (rx->playback_handle, hw_params, &rate, &dir)) < 0) { fprintf (stderr, "audio_open_output: cannot set sample rate (%s)\n", snd_strerror (err)); + audio_close_output(rx); return -1; } if ((err = snd_pcm_hw_params_set_channels (rx->playback_handle, hw_params, 2)) < 0) { fprintf (stderr, "audio_open_output: cannot set channel count (%s)\n", snd_strerror (err)); + audio_close_output(rx); return -1; } if ((err = snd_pcm_hw_params (rx->playback_handle, hw_params)) < 0) { fprintf (stderr, "audio_open_output: cannot set parameters (%s)\n", snd_strerror (err)); + audio_close_output(rx); return -1; } @@ -157,6 +165,7 @@ fprintf(stderr,"audio_open_output: selected=%d:%s\n",rx->audio_device,selected); rx->playback_offset=0; rx->playback_buffer=(unsigned char *)malloc(OUTPUT_BUFFER_SIZE); +fprintf(stderr,"audio_open_output: rx=%d audio_device=%d handle=%p buffer=%p\n",rx->id,rx->audio_device,rx->playback_handle,rx->playback_buffer); return 0; } @@ -173,7 +182,7 @@ fprintf(stderr,"audio_open_input: %d\n",transmitter->input_device); } int i; - char hw[16]; + char hw[64]; char *selected=input_devices[transmitter->input_device]; fprintf(stderr,"audio_open_input: selected=%d:%s\n",transmitter->input_device,selected); @@ -213,42 +222,49 @@ fprintf(stderr,"audio_open_input: %d\n",transmitter->input_device); if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) { fprintf (stderr, "audio_open_input: cannot allocate hardware parameter structure (%s)\n", snd_strerror (err)); + audio_close_input(); return -1; } if ((err = snd_pcm_hw_params_any (record_handle, hw_params)) < 0) { fprintf (stderr, "audio_open_input: cannot initialize hardware parameter structure (%s)\n", snd_strerror (err)); + audio_close_input(); return -1; } if ((err = snd_pcm_hw_params_set_access (record_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { fprintf (stderr, "audio_open_input: cannot set access type (%s)\n", snd_strerror (err)); + audio_close_input(); return -1; } if ((err = snd_pcm_hw_params_set_format (record_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) { fprintf (stderr, "audio_open_input: cannot set sample format (%s)\n", snd_strerror (err)); + audio_close_input(); return -1; } if ((err = snd_pcm_hw_params_set_rate_near (record_handle, hw_params, &rate, &dir)) < 0) { fprintf (stderr, "audio_open_input: cannot set sample rate (%s)\n", snd_strerror (err)); + audio_close_input(); return -1; } if ((err = snd_pcm_hw_params_set_channels (record_handle, hw_params, 1)) < 0) { fprintf (stderr, "audio_open_input: cannot set channel count (%s)\n", snd_strerror (err)); + audio_close_input(); return -1; } if ((err = snd_pcm_hw_params (record_handle, hw_params)) < 0) { fprintf (stderr, "audio_open_input: cannot set parameters (%s)\n", snd_strerror (err)); + audio_close_input(); return -1; } @@ -268,6 +284,7 @@ fprintf(stderr,"audio_open_input: %d\n",transmitter->input_device); } void audio_close_output(RECEIVER *rx) { +fprintf(stderr,"audio_close_output: rx=%d handle=%p buffer=%p\n",rx->id,rx->playback_handle,rx->playback_buffer); if(rx->playback_handle!=NULL) { snd_pcm_close (rx->playback_handle); rx->playback_handle=NULL; @@ -332,12 +349,12 @@ int audio_write(RECEIVER *rx,short left_sample,short right_sample) { return 0; } -static gpointer mic_read_thread(gpointer arg) { +static void *mic_read_thread(gpointer arg) { int rc; if ((rc = snd_pcm_prepare (record_handle)) < 0) { fprintf (stderr, "mic_read_thread: cannot prepare audio interface for use (%s)\n", snd_strerror (rc)); - return; + return NULL; } fprintf(stderr,"mic_read_thread: mic_buffer_size=%d\n",mic_buffer_size); while(running) { @@ -371,7 +388,7 @@ fprintf(stderr,"mic_read_thread: mic_buffer_size=%d\n",mic_buffer_size); } } fprintf(stderr,"mic_read_thread: exiting\n"); - + return NULL; } void audio_get_cards() { diff --git a/audio_menu.c b/audio_menu.c deleted file mode 100644 index 4725411..0000000 --- a/audio_menu.c +++ /dev/null @@ -1,245 +0,0 @@ -/* 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 -#include -#include -#include - -#include "new_menu.h" -#include "audio_menu.h" -#include "audio.h" -#include "channel.h" -#include "radio.h" -#include "sliders.h" -#include "wdsp.h" - -static GtkWidget *parent_window=NULL; - -static GtkWidget *menu_b=NULL; - -static GtkWidget *dialog=NULL; - -GtkWidget *linein_b; -GtkWidget *micboost_b; - -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { - if(dialog!=NULL) { - gtk_widget_destroy(dialog); - dialog=NULL; - sub_menu=NULL; - } - return TRUE; -} - -static void binaural_cb(GtkWidget *widget, gpointer data) { - binaural=gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); - SetRXAPanelBinaural(active_receiver->id, binaural); -} - -static void micboost_cb(GtkWidget *widget, gpointer data) { - mic_boost=mic_boost==1?0:1; -} - -static void linein_cb(GtkWidget *widget, gpointer data) { - mic_linein=mic_linein==1?0:1; - g_idle_add(linein_changed,NULL); -} - -static void local_audio_cb(GtkWidget *widget, gpointer data) { - if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) { - if(audio_open_output()==0) { - local_audio=1; - } else { - local_audio=0; - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE); - } - } else { - if(local_audio) { - local_audio=0; - audio_close_output(); - } - } -} - -static void local_output_changed_cb(GtkWidget *widget, gpointer data) { - n_selected_output_device=(int)(long)data; - - if(local_audio) { - audio_close_output(); - if(audio_open_output()==0) { - local_audio=1; - } - } -} - -static void local_microphone_cb(GtkWidget *widget, gpointer data) { -fprintf(stderr,"local_microphone_cb: %d\n",local_microphone); - if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) { - if(audio_open_input()==0) { - local_microphone=1; - gtk_widget_hide(linein_b); - gtk_widget_hide(micboost_b); - } else { - local_microphone=0; - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE); - gtk_widget_show(linein_b); - gtk_widget_show(micboost_b); - } - } else { - if(local_microphone) { - local_microphone=0; - audio_close_input(); - gtk_widget_show(linein_b); - gtk_widget_show(micboost_b); - } - } -} - -static void local_input_changed_cb(GtkWidget *widget, gpointer data) { - n_selected_input_device=(int)(long)data; -fprintf(stderr,"local_input_changed_cb: %d selected=%d\n",local_microphone,n_selected_input_device); - if(local_microphone) { - audio_close_input(); - if(audio_open_input()==0) { - local_microphone=1; - } else { - local_microphone=0; - } - } -} - -void audio_menu(GtkWidget *parent) { - int i; - - parent_window=parent; - - dialog=gtk_dialog_new(); - gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); - - GdkRGBA color; - color.red = 1.0; - color.green = 1.0; - color.blue = 1.0; - color.alpha = 1.0; - gtk_widget_override_background_color(dialog,GTK_STATE_FLAG_NORMAL,&color); - - GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog)); - - GtkWidget *grid=gtk_grid_new(); - gtk_grid_set_column_spacing (GTK_GRID(grid),10); - gtk_grid_set_row_spacing (GTK_GRID(grid),5); - //gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); - //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); - - GtkWidget *close_b=gtk_button_new_with_label("Close Audio"); - g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); - gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); - - GtkWidget *binaural_b=gtk_check_button_new_with_label("Binaural"); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (binaural_b), binaural); - gtk_grid_attach(GTK_GRID(grid),binaural_b,1,0,1,1); - g_signal_connect(binaural_b,"toggled",G_CALLBACK(binaural_cb),NULL); - - int row=0; - -#ifdef RADIOBERRY - if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL || protocol==RADIOBERRY_PROTOCOL) { -#else - if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL) { -#endif - linein_b=gtk_check_button_new_with_label("Mic Line In (ACC connector)"); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linein_b), mic_linein); - gtk_grid_attach(GTK_GRID(grid),linein_b,0,++row,1,1); - g_signal_connect(linein_b,"toggled",G_CALLBACK(linein_cb),NULL); - - micboost_b=gtk_check_button_new_with_label("Mic Boost (radio only)"); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (micboost_b), mic_boost); - gtk_grid_attach(GTK_GRID(grid),micboost_b,0,++row,1,1); - g_signal_connect(micboost_b,"toggled",G_CALLBACK(micboost_cb),NULL); - - } - - - - if(n_input_devices>0) { - GtkWidget *local_microphone_b=gtk_check_button_new_with_label("Local Microphone Input"); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (local_microphone_b), local_microphone); - gtk_widget_show(local_microphone_b); - gtk_grid_attach(GTK_GRID(grid),local_microphone_b,0,++row,1,1); - g_signal_connect(local_microphone_b,"toggled",G_CALLBACK(local_microphone_cb),NULL); - - if(n_selected_input_device==-1) n_selected_input_device=0; - - for(i=0;i0) { - GtkWidget *local_audio_b=gtk_check_button_new_with_label("Local Audio Output"); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (local_audio_b), local_audio); - gtk_widget_show(local_audio_b); - gtk_grid_attach(GTK_GRID(grid),local_audio_b,1,++row,1,1); - g_signal_connect(local_audio_b,"toggled",G_CALLBACK(local_audio_cb),NULL); - - if(n_selected_output_device==-1) n_selected_output_device=0; - - for(i=0;i +#include +#include +#include +#include +#include + +#include + +#include "channel.h" +#include "filter.h" +#include "radio.h" +#include "vfo.h" +#include "audio_waterfall.h" +#include "receiver.h" + +#define min(x,y) (x(float)audio_waterfall_high) { + *p++=colorHighR; + *p++=colorHighG; + *p++=colorHighB; + } else { + float range=(float)audio_waterfall_high-(float)audio_waterfall_low; + float offset=sample-(float)audio_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; + } + } + average+=(int)sample; + audio_waterfall_low=(average/width)+10; + audio_waterfall_high=audio_waterfall_low+50; + } + gtk_widget_queue_draw (waterfall); + } +} + +void audio_waterfall_setup(int rate,int cursor) { + sample_rate=rate; + cursor_frequency=cursor; + hz_per_pixel=(double)(sample_rate/2)/(double)display_width; + cursor_x=(int)((double)cursor/hz_per_pixel); +fprintf(stderr,"audio_waterfall_setup: sample_rate=%d cursor=%d width=%d hz_per_pixel=%f\n",sample_rate,cursor,display_width,hz_per_pixel); +} + + +static void initAnalyzer(RECEIVER *rx,int channel, int buffer_size, int pixels) { + int flp[] = {0}; + double keep_time = 0.1; + int n_pixout=1; + int spur_elimination_ffts = 1; + int data_type = 0; + int fft_size = 1024; + int window_type = 4; + double kaiser_pi = 14.0; + int overlap = 0; + int clip = 0; + int span_clip_l = 0; + int span_clip_h = 0; + int stitches = 1; + int calibration_data_set = 0; + double span_min_freq = 0.0; + double span_max_freq = 0.0; + + int max_w = fft_size + (int) min(keep_time * (double) rx->fps, keep_time * (double) fft_size * (double) rx->fps); + + SetAnalyzer(channel, + n_pixout, + spur_elimination_ffts, //number of LO frequencies = number of ffts used in elimination + data_type, //0 for real input data (I only); 1 for complex input data (I & Q) + flp, //vector with one elt for each LO frequency, 1 if high-side LO, 0 otherwise + fft_size, //size of the fft, i.e., number of input samples + buffer_size, //number of samples transferred for each OpenBuffer()/CloseBuffer() + window_type, //integer specifying which window function to use + kaiser_pi, //PiAlpha parameter for Kaiser window + overlap, //number of samples each fft (other than the first) is to re-use from the previous + clip, //number of fft output bins to be clipped from EACH side of each sub-span + span_clip_l, //number of bins to clip from low end of entire span + span_clip_h, //number of bins to clip from high end of entire span + pixels, //number of pixel values to return. may be either <= or > number of bins + stitches, //number of sub-spans to concatenate to form a complete span + calibration_data_set, //identifier of which set of calibration data to use + span_min_freq, //frequency at first pixel value8192 + span_max_freq, //frequency at last pixel value + max_w //max samples to hold in input ring buffers + ); + +} + +GtkWidget* audio_waterfall_init(int width,int height) { + int success; + +fprintf(stderr,"audio_waterfall_init: width=%d height=%d\n",width,height); + display_width=width; + waterfall_height=height; + + audio_samples=(float *)malloc(sizeof(float)*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); + + XCreateAnalyzer(CHANNEL_AUDIO, &success, 262144, 1, 1, ""); + if (success != 0) { + fprintf(stderr, "XCreateAnalyzer CHANNEL_AUDIO failed: %d\n" ,success); + } + initAnalyzer(active_receiver,CHANNEL_AUDIO,AUDIO_WATERFALL_SAMPLES,width); + + return waterfall; +} diff --git a/audio_waterfall.h b/audio_waterfall.h new file mode 100644 index 0000000..75388e2 --- /dev/null +++ b/audio_waterfall.h @@ -0,0 +1,33 @@ +/* Copyright (C) +* 2017 - 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. +* +*/ + +#ifndef _FREEDV_WATERFALL_H +#define _FREEDV_WATERFALL_H + +#define AUDIO_WATERFALL_SAMPLES 256 + +extern float *audio_samples; +extern int audio_samples_index; + +extern void audio_waterfall_update(); +extern GtkWidget* audio_waterfall_init(int width,int height); +extern void audio_waterfall_setup(int sample_rate,int cursor); + +#endif + diff --git a/band.c b/band.c index c3fa969..cb058df 100644 --- a/band.c +++ b/band.c @@ -56,12 +56,25 @@ BANDSTACK_ENTRY bandstack_entries80[] = {3751000LL,modeLSB,filterF5,-2800,-200,-2800,-200}, {3850000LL,modeLSB,filterF5,-2800,-200,-2800,-200}}; -BANDSTACK_ENTRY bandstack_entries60[] = - {{5330500LL,modeUSB,filterF5,-2800,-200,-2800,-200}, - {5346500LL,modeUSB,filterF5,-2800,-200,-2800,-200}, - {5366500LL,modeUSB,filterF5,-2800,-200,-2800,-200}, - {5371500LL,modeUSB,filterF5,-2800,-200,-2800,-200}, - {5403500LL,modeUSB,filterF5,-2800,-200,-2800,-200}}; +BANDSTACK_ENTRY bandstack_entries60_OTHER[] = + {{5332000LL,modeUSB,filterF5,-2800,-200,-2800,-200}, + {5348000LL,modeUSB,filterF5,-2800,-200,-2800,-200}, + {5358500LL,modeUSB,filterF5,-2800,-200,-2800,-200}, + {5373000LL,modeUSB,filterF5,-2800,-200,-2800,-200}, + {5405000LL,modeUSB,filterF5,-2800,-200,-2800,-200}}; + +BANDSTACK_ENTRY bandstack_entries60_UK[] = + {{5261250LL,modeUSB,filterF5,-2800,-200,-2800,-200}, + {5280000LL,modeUSB,filterF5,-2800,-200,-2800,-200}, + {5290250LL,modeUSB,filterF5,-2800,-200,-2800,-200}, + {5302500LL,modeUSB,filterF5,-2800,-200,-2800,-200}, + {5318000LL,modeUSB,filterF5,-2800,-200,-2800,-200}, + {5335500LL,modeUSB,filterF5,-2800,-200,-2800,-200}, + {5356000LL,modeUSB,filterF5,-2800,-200,-2800,-200}, + {5368250LL,modeUSB,filterF5,-2800,-200,-2800,-200}, + {5380000LL,modeUSB,filterF5,-2800,-200,-2800,-200}, + {5398250LL,modeUSB,filterF5,-2800,-200,-2800,-200}, + {5405000LL,modeUSB,filterF5,-2800,-200,-2800,-200}}; BANDSTACK_ENTRY bandstack_entries40[] = {{7001000LL,modeCWL,filterF6,-2800,-200,-2800,-200}, @@ -79,7 +92,7 @@ BANDSTACK_ENTRY bandstack_entries20[] = {14230000LL,modeUSB,filterF5,200,2800,200,2800}, {14336000LL,modeUSB,filterF5,200,2800,200,2800}}; -BANDSTACK_ENTRY bandstack_entries18[] = +BANDSTACK_ENTRY bandstack_entries17[] = {{18068600LL,modeCWU,filterF6,200,2800,200,2800}, {18125000LL,modeUSB,filterF5,200,2800,200,2800}, {18140000LL,modeUSB,filterF5,200,2800,200,2800}}; @@ -99,7 +112,7 @@ BANDSTACK_ENTRY bandstack_entries10[] = {28300000LL,modeUSB,filterF5,200,2800,200,2800}, {28400000LL,modeUSB,filterF5,200,2800,200,2800}}; -BANDSTACK_ENTRY bandstack_entries50[] = +BANDSTACK_ENTRY bandstack_entries6[] = {{50010000LL,modeCWU,filterF6,200,2800,200,2800}, {50125000LL,modeUSB,filterF5,200,2800,200,2800}, {50200000LL,modeUSB,filterF5,200,2800,200,2800}}; @@ -171,15 +184,15 @@ BANDSTACK_ENTRY bandstack_entriesWWV[] = BANDSTACK bandstack160={3,1,bandstack_entries160}; BANDSTACK bandstack80={3,1,bandstack_entries80}; -BANDSTACK bandstack60={5,1,bandstack_entries60}; +BANDSTACK bandstack60={5,1,bandstack_entries60_OTHER}; BANDSTACK bandstack40={3,1,bandstack_entries40}; BANDSTACK bandstack30={3,1,bandstack_entries30}; BANDSTACK bandstack20={4,1,bandstack_entries20}; -BANDSTACK bandstack18={3,1,bandstack_entries18}; +BANDSTACK bandstack17={3,1,bandstack_entries17}; BANDSTACK bandstack15={3,1,bandstack_entries15}; BANDSTACK bandstack12={3,1,bandstack_entries12}; BANDSTACK bandstack10={3,1,bandstack_entries10}; -BANDSTACK bandstack50={3,1,bandstack_entries50}; +BANDSTACK bandstack6={3,1,bandstack_entries6}; #ifdef LIMESDR BANDSTACK bandstack70={3,1,bandstack_entries70}; BANDSTACK bandstack144={6,1,bandstack_entries144}; @@ -203,71 +216,109 @@ BANDSTACK bandstack472={2,0,bandstack_entries472}; /* ----------------------------------------------------------------------------*/ BANDSTACK_ENTRY bandstack_entries_xvtr_0[] = - {{0LL,modeUSB,filterF6,150,2550,150,2550}}; + {{0LL,modeUSB,filterF6,150,2550,150,2550}, + {0LL,modeUSB,filterF6,150,2550,150,2550}, + {0LL,modeUSB,filterF6,150,2550,150,2550}}; BANDSTACK_ENTRY bandstack_entries_xvtr_1[] = - {{0LL,modeUSB,filterF6,150,2550,150,2550}}; + {{0LL,modeUSB,filterF6,150,2550,150,2550}, + {0LL,modeUSB,filterF6,150,2550,150,2550}, + {0LL,modeUSB,filterF6,150,2550,150,2550}}; BANDSTACK_ENTRY bandstack_entries_xvtr_2[] = - {{0LL,modeUSB,filterF6,150,2550,150,2550}}; + {{0LL,modeUSB,filterF6,150,2550,150,2550}, + {0LL,modeUSB,filterF6,150,2550,150,2550}, + {0LL,modeUSB,filterF6,150,2550,150,2550}}; BANDSTACK_ENTRY bandstack_entries_xvtr_3[] = - {{0LL,modeUSB,filterF6,150,2550,150,2550}}; + {{0LL,modeUSB,filterF6,150,2550,150,2550}, + {0LL,modeUSB,filterF6,150,2550,150,2550}, + {0LL,modeUSB,filterF6,150,2550,150,2550}}; BANDSTACK_ENTRY bandstack_entries_xvtr_4[] = - {{0LL,modeUSB,filterF6,150,2550,150,2550}}; + {{0LL,modeUSB,filterF6,150,2550,150,2550}, + {0LL,modeUSB,filterF6,150,2550,150,2550}, + {0LL,modeUSB,filterF6,150,2550,150,2550}}; BANDSTACK_ENTRY bandstack_entries_xvtr_5[] = - {{0LL,modeUSB,filterF6,150,2550,150,2550}}; + {{0LL,modeUSB,filterF6,150,2550,150,2550}, + {0LL,modeUSB,filterF6,150,2550,150,2550}, + {0LL,modeUSB,filterF6,150,2550,150,2550}}; BANDSTACK_ENTRY bandstack_entries_xvtr_6[] = - {{0LL,modeUSB,filterF6,150,2550,150,2550}}; + {{0LL,modeUSB,filterF6,150,2550,150,2550}, + {0LL,modeUSB,filterF6,150,2550,150,2550}, + {0LL,modeUSB,filterF6,150,2550,150,2550}}; BANDSTACK_ENTRY bandstack_entries_xvtr_7[] = - {{0LL,modeUSB,filterF6,150,2550,150,2550}}; + {{0LL,modeUSB,filterF6,150,2550,150,2550}, + {0LL,modeUSB,filterF6,150,2550,150,2550}, + {0LL,modeUSB,filterF6,150,2550,150,2550}}; -BANDSTACK bandstack_xvtr_0={1,0,bandstack_entries_xvtr_0}; -BANDSTACK bandstack_xvtr_1={1,0,bandstack_entries_xvtr_1}; -BANDSTACK bandstack_xvtr_2={1,0,bandstack_entries_xvtr_2}; -BANDSTACK bandstack_xvtr_3={1,0,bandstack_entries_xvtr_3}; -BANDSTACK bandstack_xvtr_4={1,0,bandstack_entries_xvtr_4}; -BANDSTACK bandstack_xvtr_5={1,0,bandstack_entries_xvtr_5}; -BANDSTACK bandstack_xvtr_6={1,0,bandstack_entries_xvtr_6}; -BANDSTACK bandstack_xvtr_7={1,0,bandstack_entries_xvtr_7}; +BANDSTACK bandstack_xvtr_0={3,0,bandstack_entries_xvtr_0}; +BANDSTACK bandstack_xvtr_1={3,0,bandstack_entries_xvtr_1}; +BANDSTACK bandstack_xvtr_2={3,0,bandstack_entries_xvtr_2}; +BANDSTACK bandstack_xvtr_3={3,0,bandstack_entries_xvtr_3}; +BANDSTACK bandstack_xvtr_4={3,0,bandstack_entries_xvtr_4}; +BANDSTACK bandstack_xvtr_5={3,0,bandstack_entries_xvtr_5}; +BANDSTACK bandstack_xvtr_6={3,0,bandstack_entries_xvtr_6}; +BANDSTACK bandstack_xvtr_7={3,0,bandstack_entries_xvtr_7}; BAND bands[BANDS+XVTRS] = - {{"160",&bandstack160,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,1800000LL,2000000LL,0LL,0}, - {"80",&bandstack80,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,3500000LL,4000000LL,0LL,0}, - {"60",&bandstack60,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,5330500LL,5403500LL,0LL,0}, - {"40",&bandstack40,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,7000000LL,7300000LL,0LL,0}, - {"30",&bandstack30,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,10100000LL,10150000LL,0LL,0}, - {"20",&bandstack20,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,14000000LL,14350000LL,0LL,0}, - {"18",&bandstack18,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,18068000LL,18168000LL,0LL,0}, - {"15",&bandstack15,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,21000000LL,21450000LL,0LL,0}, - {"12",&bandstack12,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,24890000LL,24990000LL,0LL,0}, - {"10",&bandstack10,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,28000000LL,29700000LL,0LL,0}, - {"50",&bandstack50,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,50000000LL,54000000LL,0LL,0}, + {{"160",&bandstack160,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,1800000LL,2000000LL,0LL,0LL,0}, + {"80",&bandstack80,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,3500000LL,4000000LL,0LL,0LL,0}, + {"60",&bandstack60,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,5330500LL,5403500LL,0LL,0LL,0}, + {"40",&bandstack40,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,7000000LL,7300000LL,0LL,0LL,0}, + {"30",&bandstack30,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,10100000LL,10150000LL,0LL,0LL,0}, + {"20",&bandstack20,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,14000000LL,14350000LL,0LL,0LL,0}, + {"17",&bandstack17,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,18068000LL,18168000LL,0LL,0LL,0}, + {"15",&bandstack15,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,21000000LL,21450000LL,0LL,0LL,0}, + {"12",&bandstack12,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,24890000LL,24990000LL,0LL,0LL,0}, + {"10",&bandstack10,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,28000000LL,29700000LL,0LL,0LL,0}, + {"6",&bandstack6,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,50000000LL,54000000LL,0LL,0LL,0}, #ifdef LIMESDR - {"70",&bandstack70,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0}, - {"144",&bandstack144,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,144000000LL,148000000LL,0LL,0}, - {"220",&bandstack144,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,222000000LL,224980000LL,0LL,0}, - {"430",&bandstack430,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,420000000LL,450000000LL,0LL,0}, - {"902",&bandstack430,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,902000000LL,928000000LL,0LL,0}, - {"1240",&bandstack1240,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,1240000000LL,1300000000LL,0LL,0}, - {"2300",&bandstack2300,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,2300000000LL,2450000000LL,0LL,0}, - {"3400",&bandstack3400,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,3400000000LL,3410000000LL,0LL,0}, - {"AIR",&bandstackAIR,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0}, + {"70",&bandstack70,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0LL,0}, + {"144",&bandstack144,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,144000000LL,148000000LL,0LL,0LL,0}, + {"220",&bandstack144,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,222000000LL,224980000LL,0LL,0LL,0}, + {"430",&bandstack430,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,420000000LL,450000000LL,0LL,0LL,0}, + {"902",&bandstack430,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,902000000LL,928000000LL,0LL,0LL,0}, + {"1240",&bandstack1240,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,1240000000LL,1300000000LL,0LL,0LL,0}, + {"2300",&bandstack2300,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,2300000000LL,2450000000LL,0LL,0LL,0}, + {"3400",&bandstack3400,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,3400000000LL,3410000000LL,0LL,0LL,0}, + {"AIR",&bandstackAIR,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0LL,0}, #endif - {"GEN",&bandstackGEN,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0}, - {"WWV",&bandstackWWV,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0}, - {"136kHz",&bandstack136,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,135700LL,137800LL,0LL,0}, - {"472kHz",&bandstack472,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,472000LL,479000LL,0LL,0}, + {"GEN",&bandstackGEN,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0LL,0}, + {"WWV",&bandstackWWV,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0LL,0}, + {"136kHz",&bandstack136,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,135700LL,137800LL,0LL,0LL,0}, + {"472kHz",&bandstack472,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,472000LL,479000LL,0LL,0LL,0}, // XVTRS - {"",&bandstack_xvtr_0,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0}, - {"",&bandstack_xvtr_1,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0}, - {"",&bandstack_xvtr_2,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0}, - {"",&bandstack_xvtr_3,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0}, - {"",&bandstack_xvtr_4,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0}, - {"",&bandstack_xvtr_5,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0}, - {"",&bandstack_xvtr_6,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0}, - {"",&bandstack_xvtr_7,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0} + {"",&bandstack_xvtr_0,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0LL,0}, + {"",&bandstack_xvtr_1,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0LL,0}, + {"",&bandstack_xvtr_2,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0LL,0}, + {"",&bandstack_xvtr_3,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0LL,0}, + {"",&bandstack_xvtr_4,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0LL,0}, + {"",&bandstack_xvtr_5,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0LL,0}, + {"",&bandstack_xvtr_6,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0LL,0}, + {"",&bandstack_xvtr_7,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,0LL,0LL,0LL,0LL,0} }; +CHANNEL band_channels_60m_UK[UK_CHANNEL_ENTRIES] = + {{5261250LL,5500LL}, + {5280000LL,8000LL}, + {5290250LL,3500LL}, + {5302500LL,9000LL}, + {5318000LL,10000LL}, + {5335500LL,5000LL}, + {5356000LL,4000LL}, + {5368250LL,12500LL}, + {5380000LL,4000LL}, + {5398250LL,6500LL}, + {5405000LL,3000LL}}; + +CHANNEL band_channels_60m_OTHER[OTHER_CHANNEL_ENTRIES] = + {{5332000LL,2800LL}, + {5348000LL,2800LL}, + {5358500LL,2800LL}, + {5373000LL,2800LL}, + {5405000LL,2800LL}}; + +int channel_entries; +CHANNEL *band_channels_60m; BANDSTACK *bandstack_get_bandstack(int band) { return bands[band].bandstack; @@ -386,6 +437,10 @@ void bandSaveState() { sprintf(name,"band.%d.frequencyLO",b); setProperty(name,value); + sprintf(value,"%lld",bands[b].errorLO); + sprintf(name,"band.%d.errorLO",b); + setProperty(name,value); + sprintf(value,"%d",bands[b].disablePA); sprintf(name,"band.%d.disablePA",b); setProperty(name,value); @@ -438,8 +493,6 @@ void bandRestoreState() { BANDSTACK_ENTRY* entry; int current; -fprintf(stderr,"bandRestoreState: restore bands\n"); - for(b=0;b #include +#include +#include #include #include "new_menu.h" @@ -37,30 +39,33 @@ static GtkWidget *dialog=NULL; static GtkWidget *last_band; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } -static gboolean band_select_cb (GtkWidget *widget, gpointer data) { +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + +gboolean band_select_cb (GtkWidget *widget, gpointer data) { GtkWidget *label; - int b=(int)data; + int b=(uintptr_t)data; set_button_text_color(last_band,"black"); last_band=widget; set_button_text_color(last_band,"orange"); - vfo_band_changed(b); } -int band_update(void *data) { - band_select_cb(NULL,(gpointer)data); - return 0; -} - void band_menu(GtkWidget *parent) { GtkWidget *b; int i; @@ -70,7 +75,11 @@ void band_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + char title[64]; + sprintf(title,"piHPSDR - Band (RX %d VFO %s)",active_receiver->id,active_receiver->id==0?"A":"B"); + gtk_window_set_title(GTK_WINDOW(dialog),title); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -88,15 +97,10 @@ void band_menu(GtkWidget *parent) { gtk_grid_set_column_spacing (GTK_GRID(grid),5); gtk_grid_set_row_spacing (GTK_GRID(grid),5); - GtkWidget *close_b=gtk_button_new_with_label("Close Band"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); - char label[32]; - sprintf(label,"RX %d VFO %s",active_receiver->id,active_receiver->id==0?"A":"B"); - GtkWidget *rx_label=gtk_label_new(label); - gtk_grid_attach(GTK_GRID(grid),rx_label,1,0,1,1); - for(i=0;i #include +#include +#include #include #include "new_menu.h" @@ -37,17 +39,26 @@ static GtkWidget *dialog=NULL; static GtkWidget *last_bandstack; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static gboolean bandstack_select_cb (GtkWidget *widget, gpointer data) { - int b=(int)data; + int b=(uintptr_t)data; set_button_text_color(last_bandstack,"black"); last_bandstack=widget; set_button_text_color(last_bandstack,"orange"); @@ -62,7 +73,11 @@ void bandstack_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + char title[64]; + sprintf(title,"piHPSDR - Band Stack (RX %d VFO %s)",active_receiver->id,active_receiver->id==0?"A":"B"); + gtk_window_set_title(GTK_WINDOW(dialog),title); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -80,18 +95,16 @@ void bandstack_menu(GtkWidget *parent) { gtk_grid_set_column_spacing (GTK_GRID(grid),5); gtk_grid_set_row_spacing (GTK_GRID(grid),5); - GtkWidget *close_b=gtk_button_new_with_label("Close Band Stack"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); - char label[32]; - sprintf(label,"RX %d VFO %s",active_receiver->id,active_receiver->id==0?"A":"B"); - GtkWidget *rx_label=gtk_label_new(label); - gtk_grid_attach(GTK_GRID(grid),rx_label,1,0,1,1); - BAND *band=band_get_band(vfo[active_receiver->id].band); BANDSTACK *bandstack=band->bandstack; + char label[32]; + int row=1; + int col=0; for(i=0;ientries;i++) { BANDSTACK_ENTRY *entry=&bandstack->entry[i]; sprintf(label,"%lld %s",entry->frequency,mode_string[entry->mode]); @@ -103,8 +116,13 @@ void bandstack_menu(GtkWidget *parent) { last_bandstack=b; } gtk_widget_show(b); - gtk_grid_attach(GTK_GRID(grid),b,i/5,1+(i%5),1,1); - g_signal_connect(b,"clicked",G_CALLBACK(bandstack_select_cb),(gpointer *)i); + gtk_grid_attach(GTK_GRID(grid),b,col,row,1,1); + g_signal_connect(b,"clicked",G_CALLBACK(bandstack_select_cb),(gpointer)(long)i); + col++; + if(col>=5) { + col=0; + row++; + } } gtk_container_add(GTK_CONTAINER(content),grid); diff --git a/button_text.c b/button_text.c index 913c442..8a1afd5 100644 --- a/button_text.c +++ b/button_text.c @@ -6,7 +6,11 @@ void set_button_text_color(GtkWidget *widget,char *color) { gchar tmp[64]; style_context = gtk_widget_get_style_context(widget); gtk_style_context_add_provider(style_context, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); - g_snprintf(tmp, sizeof tmp, "GtkButton, GtkLabel { color: %s; }", color); + if(gtk_minor_version>=20) { + g_snprintf(tmp, sizeof tmp, "button, label { color: %s; }", color); + } else { + g_snprintf(tmp, sizeof tmp, "GtkButton, GtkLabel { color: %s; }", color); + } gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(provider), tmp, -1, NULL); g_object_unref (provider); } diff --git a/channel.h b/channel.h index 48da4d0..43b2dff 100644 --- a/channel.h +++ b/channel.h @@ -31,8 +31,9 @@ #define CHANNEL_TX 8 #define CHANNEL_BS 9 #define CHANNEL_SUBRX 10 +#define CHANNEL_AUDIO 11 #ifdef PSK -#define CHANNEL_PSK 11 +#define CHANNEL_PSK 12 #endif #endif diff --git a/cw_menu.c b/cw_menu.c index 176d1ec..c2a5738 100644 --- a/cw_menu.c +++ b/cw_menu.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include "new_menu.h" @@ -29,6 +31,8 @@ #include "filter.h" #include "radio.h" #include "receiver.h" +#include "new_protocol.h" +#include "old_protocol.h" static GtkWidget *parent_window=NULL; @@ -36,15 +40,24 @@ static GtkWidget *menu_b=NULL; static GtkWidget *dialog=NULL; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static void cw_keyer_internal_cb(GtkWidget *widget, gpointer data) { cw_keyer_internal=cw_keyer_internal==1?0:1; cw_changed(); @@ -81,7 +94,7 @@ static void cw_keys_reversed_cb(GtkWidget *widget, gpointer data) { } static void cw_keyer_mode_cb(GtkWidget *widget, gpointer data) { - cw_keyer_mode=(int)data; + cw_keyer_mode=(uintptr_t)data; cw_changed(); } @@ -102,6 +115,7 @@ static void cw_keyer_sidetone_frequency_value_changed_cb(GtkWidget *widget, gpoi } */ cw_changed(); + receiver_filter_changed(active_receiver); } void cw_menu(GtkWidget *parent) { @@ -111,7 +125,9 @@ void cw_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - CW"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -128,7 +144,7 @@ void cw_menu(GtkWidget *parent) { //gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); - GtkWidget *close_b=gtk_button_new_with_label("Close CW"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); diff --git a/discovered.h b/discovered.h index d44fcde..c99f84f 100644 --- a/discovered.h +++ b/discovered.h @@ -68,6 +68,9 @@ #ifdef RADIOBERRY #define RADIOBERRY_PROTOCOL 3 #endif +#ifdef REMOTE +#define REMOTE_PROTOCOL 4 +#endif struct _DISCOVERED { int protocol; diff --git a/discovery.c b/discovery.c index 95baeb3..0d4239b 100644 --- a/discovery.c +++ b/discovery.c @@ -30,6 +30,8 @@ #include "discovered.h" #include "discovery.h" +#include "old_discovery.h" +#include "new_discovery.h" #include "main.h" #include "radio.h" #ifdef USBOZY @@ -41,12 +43,14 @@ #ifdef RADIOBERRY #include "radioberry.h" #endif +#ifdef REMOTE +#include "remote_radio.h" +#endif +#include "ext.h" static GtkWidget *discovery_dialog; static DISCOVERED *d; -int discovery(void *data); - static gboolean start_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { fprintf(stderr,"start_cb: %p\n",data); radio=(DISCOVERED *)data; @@ -64,7 +68,7 @@ static gboolean gpio_cb (GtkWidget *widget, GdkEventButton *event, gpointer data static gboolean discover_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { gtk_widget_destroy(discovery_dialog); - g_idle_add(discovery,NULL); + g_idle_add(ext_discovery,NULL); return TRUE; } @@ -74,7 +78,7 @@ static gboolean exit_cb (GtkWidget *widget, GdkEventButton *event, gpointer data return TRUE; } -int discovery(void *data) { +void discovery() { fprintf(stderr,"discovery\n"); selected_device=0; devices=0; @@ -99,10 +103,10 @@ fprintf(stderr,"discovery\n"); #endif - status_text("Old Protocol ... Discovering Devices"); + status_text("Protocol 1 ... Discovering Devices"); old_discovery(); - status_text("New Protocol ... Discovering Devices"); + status_text("Protocol 2 ... Discovering Devices"); new_discovery(); #ifdef LIMESDR @@ -121,9 +125,10 @@ fprintf(stderr,"discovery\n"); gdk_window_set_cursor(gtk_widget_get_window(top_window),gdk_cursor_new(GDK_ARROW)); discovery_dialog = gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(discovery_dialog),GTK_WINDOW(top_window)); - gtk_window_set_decorated(GTK_WINDOW(discovery_dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(discovery_dialog),"piHPSDR - Discovery"); + //gtk_window_set_decorated(GTK_WINDOW(discovery_dialog),FALSE); - gtk_widget_override_font(discovery_dialog, pango_font_description_from_string("FreeMono 16")); + //gtk_widget_override_font(discovery_dialog, pango_font_description_from_string("FreeMono 16")); GdkRGBA color; color.red = 1.0; @@ -144,20 +149,14 @@ fprintf(stderr,"discovery\n"); GtkWidget *label=gtk_label_new("No devices found!"); gtk_grid_attach(GTK_GRID(grid),label,0,0,2,1); -#ifdef GPIO - GtkWidget *gpio_b=gtk_button_new_with_label("Config GPIO"); - g_signal_connect (gpio_b, "button-press-event", G_CALLBACK(gpio_cb), NULL); - gtk_grid_attach(GTK_GRID(grid),gpio_b,0,1,1,1); -#endif + GtkWidget *exit_b=gtk_button_new_with_label("Exit"); + g_signal_connect (exit_b, "button-press-event", G_CALLBACK(exit_cb), NULL); + gtk_grid_attach(GTK_GRID(grid),exit_b,0,1,1,1); GtkWidget *discover_b=gtk_button_new_with_label("Retry Discovery"); g_signal_connect (discover_b, "button-press-event", G_CALLBACK(discover_cb), NULL); gtk_grid_attach(GTK_GRID(grid),discover_b,1,1,1,1); - GtkWidget *exit_b=gtk_button_new_with_label("Exit"); - g_signal_connect (exit_b, "button-press-event", G_CALLBACK(exit_cb), NULL); - gtk_grid_attach(GTK_GRID(grid),exit_b,2,1,1,1); - gtk_container_add (GTK_CONTAINER (content), grid); gtk_widget_show_all(discovery_dialog); } else { @@ -165,9 +164,10 @@ fprintf(stderr,"discovery\n"); gdk_window_set_cursor(gtk_widget_get_window(top_window),gdk_cursor_new(GDK_ARROW)); discovery_dialog = gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(discovery_dialog),GTK_WINDOW(top_window)); - gtk_window_set_decorated(GTK_WINDOW(discovery_dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(discovery_dialog),"piHPSDR - Discovery"); + //gtk_window_set_decorated(GTK_WINDOW(discovery_dialog),FALSE); - gtk_widget_override_font(discovery_dialog, pango_font_description_from_string("FreeMono 16")); + //gtk_widget_override_font(discovery_dialog, pango_font_description_from_string("FreeMono 16")); GdkRGBA color; color.red = 1.0; @@ -182,35 +182,29 @@ fprintf(stderr,"discovery\n"); GtkWidget *grid=gtk_grid_new(); gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); - gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); + //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); gtk_grid_set_row_spacing (GTK_GRID(grid),10); int i; char version[16]; - char text[128]; + char text[256]; for(i=0;iprotocol,d->name); - if(d->protocol==ORIGINAL_PROTOCOL) { - sprintf(version,"%d.%d", - d->software_version/10, - d->software_version%10); - } else { - sprintf(version,"%d.%d", +fprintf(stderr,"%p Protocol=%d name=%s\n",d,d->protocol,d->name); + sprintf(version,"v%d.%d", d->software_version/10, d->software_version%10); - } switch(d->protocol) { case ORIGINAL_PROTOCOL: case NEW_PROTOCOL: #ifdef USBOZY if(d->device==DEVICE_OZY) { - sprintf(text,"%s (%s) on USB /dev/ozy\n", d->name, d->protocol==ORIGINAL_PROTOCOL?"old":"new"); + sprintf(text,"%s (%s) on USB /dev/ozy", d->name, d->protocol==ORIGINAL_PROTOCOL?"Protocol 1":"Protocol 2"); } else { #endif - sprintf(text,"%s (%s %s) %s (%02X:%02X:%02X:%02X:%02X:%02X) on %s\n", + sprintf(text,"%s (%s %s) %s (%02X:%02X:%02X:%02X:%02X:%02X) on %s", d->name, - d->protocol==ORIGINAL_PROTOCOL?"old":"new", + d->protocol==ORIGINAL_PROTOCOL?"Protocol 1":"Protocol 2", version, inet_ntoa(d->info.network.address.sin_addr), d->info.network.mac_address[0], @@ -226,7 +220,7 @@ fprintf(stderr,"%p protocol=%d name=%s\n",d,d->protocol,d->name); break; #ifdef LIMESDR case LIMESDR_PROTOCOL: - sprintf(text,"%s\n", + sprintf(text,"%s", d->name); break; #endif @@ -266,6 +260,7 @@ fprintf(stderr,"%p protocol=%d name=%s\n",d,d->protocol,d->name); g_signal_connect (gpio_b, "button-press-event", G_CALLBACK(gpio_cb), NULL); gtk_grid_attach(GTK_GRID(grid),gpio_b,0,i,1,1); #endif + GtkWidget *discover_b=gtk_button_new_with_label("Discover"); g_signal_connect (discover_b, "button-press-event", G_CALLBACK(discover_cb), NULL); gtk_grid_attach(GTK_GRID(grid),discover_b,1,i,1,1); @@ -279,8 +274,6 @@ fprintf(stderr,"%p protocol=%d name=%s\n",d,d->protocol,d->name); fprintf(stderr,"showing device dialog\n"); } - return 0; - } diff --git a/discovery.h b/discovery.h index 74600f0..fdc38ad 100644 --- a/discovery.h +++ b/discovery.h @@ -17,4 +17,4 @@ * */ -int discovery(void *data); +extern void discovery(); diff --git a/display_menu.c b/display_menu.c index 027e0e4..d9a5276 100644 --- a/display_menu.c +++ b/display_menu.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include "new_menu.h" @@ -34,22 +36,31 @@ static GtkWidget *menu_b=NULL; static GtkWidget *dialog=NULL; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static void detector_mode_cb(GtkWidget *widget, gpointer data) { - display_detector_mode=(int)data; + display_detector_mode=(uintptr_t)data; SetDisplayDetectorMode(active_receiver->id, 0, display_detector_mode); } static void average_mode_cb(GtkWidget *widget, gpointer data) { - display_average_mode=(int)data; + display_average_mode=(uintptr_t)data; SetDisplayAverageMode(active_receiver->id, 0, display_average_mode); } @@ -115,7 +126,9 @@ void display_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - Display"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -132,7 +145,7 @@ void display_menu(GtkWidget *parent) { //gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); - GtkWidget *close_b=gtk_button_new_with_label("Close Display"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); diff --git a/diversity_menu.c b/diversity_menu.c index 009a206..fc60b47 100644 --- a/diversity_menu.c +++ b/diversity_menu.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -34,15 +35,24 @@ static GtkWidget *dialog=NULL; static GtkWidget *level; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static void diversity_cb(GtkWidget *widget, gpointer data) { diversity_enabled=diversity_enabled==1?0:1; SetEXTDIVRun(0,diversity_enabled); @@ -50,12 +60,12 @@ static void diversity_cb(GtkWidget *widget, gpointer data) { static void i_rotate_value_changed_cb(GtkWidget *widget, gpointer data) { i_rotate[1]=gtk_range_get_value(GTK_RANGE(widget)); - SetEXTDIVRotate (0, 2, &i_rotate, &q_rotate); + SetEXTDIVRotate (0, 2, &i_rotate[0], &q_rotate[0]); } static void q_rotate_value_changed_cb(GtkWidget *widget, gpointer data) { q_rotate[1]=gtk_range_get_value(GTK_RANGE(widget)); - SetEXTDIVRotate (0, 2, &i_rotate, &q_rotate); + SetEXTDIVRotate (0, 2, &i_rotate[0], &q_rotate[0]); } void diversity_menu(GtkWidget *parent) { @@ -65,7 +75,9 @@ void diversity_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - Diversity"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -82,7 +94,7 @@ void diversity_menu(GtkWidget *parent) { //gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); - GtkWidget *close_b=gtk_button_new_with_label("Close Diversity"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); diff --git a/dsp_menu.c b/dsp_menu.c index 690a90e..09ce553 100644 --- a/dsp_menu.c +++ b/dsp_menu.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include "new_menu.h" @@ -36,15 +38,24 @@ static GtkWidget *menu_b=NULL; static GtkWidget *dialog=NULL; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static void agc_hang_threshold_value_changed_cb(GtkWidget *widget, gpointer data) { active_receiver->agc_hang_threshold=(int)gtk_range_get_value(GTK_RANGE(widget)); if(active_receiver->agc==AGC_LONG || active_receiver->agc==AGC_SLOW) { @@ -53,18 +64,18 @@ static void agc_hang_threshold_value_changed_cb(GtkWidget *widget, gpointer data } static void pre_post_agc_cb(GtkWidget *widget, gpointer data) { - active_receiver->nr_agc=(int)data; + active_receiver->nr_agc=(uintptr_t)data; SetRXAEMNRPosition(active_receiver->id, active_receiver->nr_agc); } static void nr2_gain_cb(GtkWidget *widget, gpointer data) { - active_receiver->nr2_gain_method==(int)data; + active_receiver->nr2_gain_method==(uintptr_t)data; SetRXAEMNRgainMethod(active_receiver->id, active_receiver->nr2_gain_method); } static void nr2_npe_method_cb(GtkWidget *widget, gpointer data) { - active_receiver->nr2_npe_method=(int)data; + active_receiver->nr2_npe_method=(uintptr_t)data; SetRXAEMNRnpeMethod(active_receiver->id, active_receiver->nr2_npe_method); } @@ -84,7 +95,9 @@ void dsp_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - DSP"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -101,7 +114,7 @@ void dsp_menu(GtkWidget *parent) { //gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); - GtkWidget *close_b=gtk_button_new_with_label("Close DSP"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); diff --git a/encoder_menu.c b/encoder_menu.c index f2dabf7..1fb4724 100644 --- a/encoder_menu.c +++ b/encoder_menu.c @@ -48,20 +48,29 @@ static GtkWidget *b_cw_speed; static GtkWidget *b_cw_frequency; static GtkWidget *b_panadapter_high; static GtkWidget *b_panadapter_low; +static GtkWidget *b_squelch; +static GtkWidget *b_compression; static int encoder; - -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } - active_menu=NO_MENU; +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + void encoder_select(int pos) { int action; GtkWidget *button; @@ -70,11 +79,11 @@ void encoder_select(int pos) { if(pos>0) { e1_encoder_action--; if(e1_encoder_action<0) { - e1_encoder_action=ENCODER_LAST; + e1_encoder_action=ENCODER_LAST-1; } } if(pos<0) { e1_encoder_action++; - if(e1_encoder_action>ENCODER_LAST) { + if(e1_encoder_action>=ENCODER_LAST) { e1_encoder_action=0; } } @@ -84,11 +93,11 @@ void encoder_select(int pos) { if(pos>0) { e2_encoder_action--; if(e2_encoder_action<0) { - e2_encoder_action=ENCODER_LAST; + e2_encoder_action=ENCODER_LAST-1; } } if(pos<0) { e2_encoder_action++; - if(e2_encoder_action>ENCODER_LAST) { + if(e2_encoder_action>=ENCODER_LAST) { e2_encoder_action=0; } } @@ -98,11 +107,11 @@ void encoder_select(int pos) { if(pos>0) { e3_encoder_action--; if(e3_encoder_action<0) { - e3_encoder_action=ENCODER_LAST; + e3_encoder_action=ENCODER_LAST-1; } } if(pos<0) { e3_encoder_action++; - if(e3_encoder_action>ENCODER_LAST) { + if(e3_encoder_action>=ENCODER_LAST) { e3_encoder_action=0; } } @@ -126,9 +135,11 @@ void encoder_select(int pos) { case ENCODER_DRIVE: button=b_drive; break; +/* case ENCODER_TUNE_DRIVE: button=b_tune_drive; break; +*/ case ENCODER_RIT: button=b_rit; break; @@ -144,6 +155,12 @@ void encoder_select(int pos) { case ENCODER_PANADAPTER_LOW: button=b_panadapter_low; break; + case ENCODER_SQUELCH: + button=b_squelch; + break; + case ENCODER_COMP: + button=b_compression; + break; } gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); @@ -187,7 +204,11 @@ void encoder_menu(GtkWidget *parent,int e) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + char title[32]; + sprintf(title,"piHPSDR - Encoder E%d Action:",encoder); + gtk_window_set_title(GTK_WINDOW(dialog),title); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -205,81 +226,111 @@ void encoder_menu(GtkWidget *parent,int e) { gtk_grid_set_column_spacing (GTK_GRID(grid),5); gtk_grid_set_row_spacing (GTK_GRID(grid),5); + int row=0; + int col=0; + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); - gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); + gtk_grid_attach(GTK_GRID(grid),close_b,col,row,1,1); - char label_text[32]; - sprintf(label_text,"Encoder E%d Action:",encoder); - GtkWidget *label=gtk_label_new(label_text); - gtk_grid_attach(GTK_GRID(grid),label,0,1,2,1); + row++; + col=0; b_af_gain=gtk_radio_button_new_with_label(NULL,"AF Gain"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_af_gain), encoder_action==ENCODER_AF_GAIN); gtk_widget_show(b_af_gain); - gtk_grid_attach(GTK_GRID(grid),b_af_gain,0,2,2,1); + gtk_grid_attach(GTK_GRID(grid),b_af_gain,col,row,2,1); g_signal_connect(b_af_gain,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_AF_GAIN); + row++; + b_agc_gain=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_af_gain),"AGC Gain"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_agc_gain), encoder_action==ENCODER_AGC_GAIN); gtk_widget_show(b_agc_gain); - gtk_grid_attach(GTK_GRID(grid),b_agc_gain,0,3,2,1); + gtk_grid_attach(GTK_GRID(grid),b_agc_gain,col,row,2,1); g_signal_connect(b_agc_gain,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_AGC_GAIN); + row++; + b_attenuation=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_agc_gain),"Attenuation"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_attenuation), encoder_action==ENCODER_ATTENUATION); gtk_widget_show(b_attenuation); - gtk_grid_attach(GTK_GRID(grid),b_attenuation,0,4,2,1); + gtk_grid_attach(GTK_GRID(grid),b_attenuation,col,row,2,1); g_signal_connect(b_attenuation,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_ATTENUATION); + row++; + b_mic_gain=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_attenuation),"Mic Gain"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_mic_gain), encoder_action==ENCODER_MIC_GAIN); gtk_widget_show(b_mic_gain); - gtk_grid_attach(GTK_GRID(grid),b_mic_gain,0,5,2,1); + gtk_grid_attach(GTK_GRID(grid),b_mic_gain,col,row,2,1); g_signal_connect(b_mic_gain,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_MIC_GAIN); + row++; + b_drive=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_mic_gain),"Drive"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_drive), encoder_action==ENCODER_DRIVE); gtk_widget_show(b_drive); - gtk_grid_attach(GTK_GRID(grid),b_drive,0,6,2,1); + gtk_grid_attach(GTK_GRID(grid),b_drive,col,row,2,1); g_signal_connect(b_drive,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_DRIVE); - b_tune_drive=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_drive),"Tune Drive"); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_tune_drive), encoder_action==ENCODER_TUNE_DRIVE); - gtk_widget_show(b_tune_drive); - gtk_grid_attach(GTK_GRID(grid),b_tune_drive,0,7,2,1); - g_signal_connect(b_tune_drive,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_TUNE_DRIVE); + row++; - b_rit=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_tune_drive),"RIT"); + b_rit=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_drive),"RIT"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_rit), encoder_action==ENCODER_RIT); gtk_widget_show(b_rit); - gtk_grid_attach(GTK_GRID(grid),b_rit,2,2,2,1); + gtk_grid_attach(GTK_GRID(grid),b_rit,col,row,2,1); g_signal_connect(b_rit,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_RIT); + col=2; + row=1; + b_cw_speed=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_rit),"CW Speed"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_cw_speed), encoder_action==ENCODER_CW_SPEED); gtk_widget_show(b_cw_speed); - gtk_grid_attach(GTK_GRID(grid),b_cw_speed,2,3,2,1); + gtk_grid_attach(GTK_GRID(grid),b_cw_speed,col,row,2,1); g_signal_connect(b_cw_speed,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_CW_SPEED); + row++; + b_cw_frequency=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_cw_speed),"CW Freq"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_cw_frequency), encoder_action==ENCODER_CW_FREQUENCY); gtk_widget_show(b_cw_frequency); - gtk_grid_attach(GTK_GRID(grid),b_cw_frequency,2,4,2,1); + gtk_grid_attach(GTK_GRID(grid),b_cw_frequency,col,row,2,1); g_signal_connect(b_cw_frequency,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_CW_FREQUENCY); + row++; + b_panadapter_high=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_cw_frequency),"Panadapter High"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_panadapter_high), encoder_action==ENCODER_PANADAPTER_HIGH); gtk_widget_show(b_panadapter_high); - gtk_grid_attach(GTK_GRID(grid),b_panadapter_high,2,6,2,1); + gtk_grid_attach(GTK_GRID(grid),b_panadapter_high,col,row,2,1); g_signal_connect(b_panadapter_high,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_PANADAPTER_HIGH); - b_panadapter_low=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_cw_frequency),"Panadapter Low"); + row++; + + b_panadapter_low=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_panadapter_high),"Panadapter Low"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_panadapter_low), encoder_action==ENCODER_PANADAPTER_LOW); gtk_widget_show(b_panadapter_low); - gtk_grid_attach(GTK_GRID(grid),b_panadapter_low,2,7,2,1); + gtk_grid_attach(GTK_GRID(grid),b_panadapter_low,col,row,2,1); g_signal_connect(b_panadapter_low,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_PANADAPTER_LOW); + row++; + + b_squelch=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_panadapter_low),"Squelch"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_squelch), encoder_action==ENCODER_SQUELCH); + gtk_widget_show(b_squelch); + gtk_grid_attach(GTK_GRID(grid),b_squelch,col,row,2,1); + g_signal_connect(b_squelch,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_SQUELCH); + + row++; + + b_compression=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_squelch),"COMP"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_compression), encoder_action==ENCODER_COMP); + gtk_widget_show(b_compression); + gtk_grid_attach(GTK_GRID(grid),b_compression,col,row,2,1); + g_signal_connect(b_compression,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_COMP); + gtk_container_add(GTK_CONTAINER(content),grid); sub_menu=dialog; diff --git a/equalizer_menu.c b/equalizer_menu.c index f2c7582..514e77d 100644 --- a/equalizer_menu.c +++ b/equalizer_menu.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include @@ -40,15 +42,24 @@ static GtkWidget *high_scale; static gboolean tx_menu=TRUE; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static gboolean tx_rb_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { tx_menu=TRUE; @@ -83,8 +94,8 @@ static gboolean enable_cb (GtkWidget *widget, GdkEventButton *event, gpointer da } } -static gboolean rx_value_changed_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { - int i=(int)data; +static void value_changed_cb (GtkWidget *widget, gpointer data) { + int i=(uintptr_t)data; if(tx_menu) { tx_equalizer[i]=(int)gtk_range_get_value(GTK_RANGE(widget)); SetTXAGrphEQ(transmitter->id, tx_equalizer); @@ -101,7 +112,9 @@ void equalizer_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - Equalizer"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -118,7 +131,7 @@ void equalizer_menu(GtkWidget *parent) { gtk_grid_set_row_homogeneous(GTK_GRID(grid),FALSE); gtk_grid_set_column_homogeneous(GTK_GRID(grid),FALSE); - GtkWidget *close_b=gtk_button_new_with_label("Close Equalizer"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); @@ -153,7 +166,7 @@ void equalizer_menu(GtkWidget *parent) { preamp_scale=gtk_scale_new_with_range(GTK_ORIENTATION_VERTICAL,-12.0,15.0,1.0); gtk_range_set_value(GTK_RANGE(preamp_scale),(double)tx_equalizer[0]); - g_signal_connect(preamp_scale,"value-changed",G_CALLBACK(rx_value_changed_cb),(gpointer)0); + g_signal_connect(preamp_scale,"value-changed",G_CALLBACK(value_changed_cb),(gpointer)0); gtk_grid_attach(GTK_GRID(grid),preamp_scale,0,3,1,10); gtk_widget_set_size_request(preamp_scale,10,270); gtk_scale_add_mark(GTK_SCALE(preamp_scale),-12.0,GTK_POS_LEFT,"-12dB"); @@ -169,7 +182,7 @@ void equalizer_menu(GtkWidget *parent) { low_scale=gtk_scale_new_with_range(GTK_ORIENTATION_VERTICAL,-12.0,15.0,1.0); gtk_range_set_value(GTK_RANGE(low_scale),(double)tx_equalizer[1]); - g_signal_connect(low_scale,"value-changed",G_CALLBACK(rx_value_changed_cb),(gpointer)1); + g_signal_connect(low_scale,"value-changed",G_CALLBACK(value_changed_cb),(gpointer)1); gtk_grid_attach(GTK_GRID(grid),low_scale,1,3,1,10); gtk_scale_add_mark(GTK_SCALE(low_scale),-12.0,GTK_POS_LEFT,"-12dB"); gtk_scale_add_mark(GTK_SCALE(low_scale),-9.0,GTK_POS_LEFT,NULL); @@ -184,7 +197,7 @@ void equalizer_menu(GtkWidget *parent) { mid_scale=gtk_scale_new_with_range(GTK_ORIENTATION_VERTICAL,-12.0,15.0,1.0); gtk_range_set_value(GTK_RANGE(mid_scale),(double)tx_equalizer[2]); - g_signal_connect(mid_scale,"value-changed",G_CALLBACK(rx_value_changed_cb),(gpointer)2); + g_signal_connect(mid_scale,"value-changed",G_CALLBACK(value_changed_cb),(gpointer)2); gtk_grid_attach(GTK_GRID(grid),mid_scale,2,3,1,10); gtk_scale_add_mark(GTK_SCALE(mid_scale),-12.0,GTK_POS_LEFT,"-12dB"); gtk_scale_add_mark(GTK_SCALE(mid_scale),-9.0,GTK_POS_LEFT,NULL); @@ -199,7 +212,7 @@ void equalizer_menu(GtkWidget *parent) { high_scale=gtk_scale_new_with_range(GTK_ORIENTATION_VERTICAL,-12.0,15.0,1.0); gtk_range_set_value(GTK_RANGE(high_scale),(double)tx_equalizer[3]); - g_signal_connect(high_scale,"value-changed",G_CALLBACK(rx_value_changed_cb),(gpointer)3); + g_signal_connect(high_scale,"value-changed",G_CALLBACK(value_changed_cb),(gpointer)3); gtk_grid_attach(GTK_GRID(grid),high_scale,3,3,1,10); gtk_scale_add_mark(GTK_SCALE(high_scale),-12.0,GTK_POS_LEFT,"-12dB"); gtk_scale_add_mark(GTK_SCALE(high_scale),-9.0,GTK_POS_LEFT,NULL); diff --git a/error_handler.c b/error_handler.c new file mode 100644 index 0000000..5c7313e --- /dev/null +++ b/error_handler.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include + +#include "error_handler.h" +#include "main.h" + +static GtkWidget *dialog; +static gint timer; + +int timeout_cb(gpointer data) { + gtk_widget_destroy(dialog); + exit(1); +} + +int show_error(void *data) { + dialog=gtk_dialog_new_with_buttons("ERROR",GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL); + GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + GtkWidget *label=gtk_label_new((char *)data); + gtk_container_add(GTK_CONTAINER(content),label); + gtk_widget_show(label); + timer=g_timeout_add(5000,timeout_cb,NULL); + int result=gtk_dialog_run(GTK_DIALOG(dialog)); +} + +void error_handler(char *text,char *err) { + char message[1024]; + sprintf(message,"ERROR: %s: %s\n",text,err); + fprintf(stderr,"%s\n",message); + + sprintf(message,"ERROR\n\n %s:\n\n %s\n\npiHPSDR will terminate in 5 seconds",text,err); + + g_idle_add(show_error,message); + +} diff --git a/error_handler.h b/error_handler.h new file mode 100644 index 0000000..884d067 --- /dev/null +++ b/error_handler.h @@ -0,0 +1 @@ +extern void error_handler(char *text,char *err); diff --git a/exit_menu.c b/exit_menu.c index c950646..409ef13 100644 --- a/exit_menu.c +++ b/exit_menu.c @@ -25,6 +25,8 @@ #include "new_menu.h" #include "exit_menu.h" #include "radio.h" +#include "new_protocol.h" +#include "old_protocol.h" static GtkWidget *parent_window=NULL; @@ -32,15 +34,24 @@ static GtkWidget *menu_b=NULL; static GtkWidget *dialog=NULL; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static gboolean exit_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { #ifdef GPIO gpio_close(); @@ -90,7 +101,7 @@ static gboolean reboot_cb (GtkWidget *widget, GdkEventButton *event, gpointer da #endif } radioSaveState(); - system("reboot"); + int rc=system("reboot"); _exit(0); } @@ -117,7 +128,7 @@ static gboolean shutdown_cb (GtkWidget *widget, GdkEventButton *event, gpointer #endif } radioSaveState(); - system("shutdown -h -P now"); + int rc=system("shutdown -h -P now"); _exit(0); } @@ -127,7 +138,9 @@ void exit_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - Exit"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; diff --git a/ext.c b/ext.c new file mode 100644 index 0000000..f42a714 --- /dev/null +++ b/ext.c @@ -0,0 +1,156 @@ +/* Copyright (C) +* 2017 - 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 +#include +#include +#include +#include +#include "discovery.h" +#include "receiver.h" +#include "sliders.h" +#include "toolbar.h" +#include "band_menu.h" +#include "vfo.h" +#include "radio.h" +#include "new_menu.h" +#ifdef PURESIGNAL +#include "ps_menu.h" +#endif + +// The following calls functions can be called usig g_idle_add + +int ext_discovery(void *data) { + discovery(); + return 0; +} + +int ext_set_frequency(void *data) { + setFrequency(*(long long *)data); + free(data); +} + +int ext_vfo_update(void *data) { + vfo_update(); + return 0; +} + +int ext_vfo_filter_changed(void *data) { + vfo_filter_changed((uintptr_t)data); + return 0; +} + +int ext_band_update(void *data) { + if(data==NULL) { + start_band(); + } else { + band_select_cb(NULL,data); + } + return 0; +} + +int ext_mode_update(void *data) { + start_mode(); +} + +int ext_filter_update(void *data) { + start_filter(); +} + +int ext_noise_update(void *data) { + start_noise(); +} + +int ext_ptt_update(void *data) { + ptt_update((uintptr_t)data); + return 0; +} + +int ext_mox_update(void *data) { + mox_update((uintptr_t)data); + return 0; +} + +int ext_tune_update(void *data) { + tune_update((uintptr_t)data); + return 0; +} + +int ext_vox_changed(void *data) { + vox_changed((uintptr_t)data); + return 0; +} + +int ext_update_agc_gain(void *data) { + update_agc_gain(*(double *)data); + free(data); + return 0; +} + +int ext_update_af_gain(void *data) { + update_af_gain(); + return 0; +} + +int ext_calc_drive_level(void *data) { + calcDriveLevel(); + return 0; +} + +int ext_vfo_band_changed(void *data) { + vfo_band_changed((uintptr_t)data); + return 0; +} + +int ext_radio_change_sample_rate(void *data) { + radio_change_sample_rate((uintptr_t)data); + return 0; +} + +int ext_cw_setup() { + radio_cw_setup(); + return 0; +} + +int ext_cw_key(void *data) { + radio_cw_key((uintptr_t)data); + return 0; +} + +int ext_update_squelch(void *data) { + set_squelch(active_receiver); + return 0; +} + +int ext_sliders_update(void *data) { + sliders_update(); + return 0; +} + +#ifdef PURESIGNAL +int ext_tx_set_ps(void *data) { + tx_set_ps(transmitter,(uintptr_t)data); + return 0; +} + +int ext_ps_twotone(void *data) { + ps_twotone((uintptr_t)data); + return 0; +} +#endif diff --git a/ext.h b/ext.h new file mode 100644 index 0000000..adf7264 --- /dev/null +++ b/ext.h @@ -0,0 +1,52 @@ +/* Copyright (C) +* 2017 - 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. +* +*/ + + +// The following calls functions can be called usig g_idle_add + +extern int ext_discovery(void *data); +extern int ext_vfo_update(void *data); +extern int ext_set_frequency(void *data); +extern int ext_vfo_filter_changed(void *data); +extern int ext_band_update(void *data); +extern int ext_ptt_update(void *data); +extern int ext_mox_update(void *data); +extern int ext_tune_update(void *data); +extern int ext_linein_changed(void *data); +extern int ext_vox_changed(void *data); +extern int ext_sliders_mode_changed(void *data); +extern int ext_update_agc_gain(void *data); +extern int ext_update_af_gain(void *data); +extern int ext_calc_drive_level(void *data); +extern int ext_vfo_band_changed(void *data); +extern int ext_radio_change_sample_rate(void *data); + +extern int ext_cw_setup(); +extern int ext_cw_key(void *data); + +extern int ext_update_squelch(void *data); + +extern int ext_sliders_update(void *data); + +extern int ext_mode_update(void *data); +extern int ext_filter_update(void *data); +extern int ext_noise_update(void *data); + +extern int ext_tx_set_ps(void *data); +extern int ext_ps_twotone(void *data); diff --git a/fft_menu.c b/fft_menu.c index 5f7bca7..30f5b02 100644 --- a/fft_menu.c +++ b/fft_menu.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include "new_menu.h" @@ -32,17 +34,26 @@ static GtkWidget *menu_b=NULL; static GtkWidget *dialog=NULL; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static void filter_type_cb(GtkWidget *widget, gpointer data) { - set_filter_type((int)data); + set_filter_type((uintptr_t)data); } #ifdef SET_FILTER_SIZE @@ -56,7 +67,9 @@ void fft_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - FFT"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -77,53 +90,71 @@ void fft_menu(GtkWidget *parent) { g_signal_connect (close_b, "button_press_event", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); - int x=0; + int row=1; + int col=0; GtkWidget *filter_type_label=gtk_label_new("Filter Type: "); - gtk_grid_attach(GTK_GRID(grid),filter_type_label,x,1,1,1); + gtk_grid_attach(GTK_GRID(grid),filter_type_label,col,row,1,1); + row++; + col=0; + GtkWidget *linear_phase=gtk_radio_button_new_with_label(NULL,"Linear Phase"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linear_phase), receiver[0]->low_latency==0); - gtk_grid_attach(GTK_GRID(grid),linear_phase,x,2,1,1); + gtk_grid_attach(GTK_GRID(grid),linear_phase,col,row,1,1); g_signal_connect(linear_phase,"pressed",G_CALLBACK(filter_type_cb),(gpointer *)0); + col++; + GtkWidget *low_latency=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(linear_phase),"Low Latency"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (low_latency), receiver[0]->low_latency==1); - gtk_grid_attach(GTK_GRID(grid),low_latency,x,3,1,1); + gtk_grid_attach(GTK_GRID(grid),low_latency,col,row,1,1); g_signal_connect(low_latency,"pressed",G_CALLBACK(filter_type_cb),(gpointer *)1); - x++; - #ifdef SET_FILTER_SIZE + + row++; + col=0; + GtkWidget *filter_size_label=gtk_label_new("Filter Size: "); - gtk_grid_attach(GTK_GRID(grid),filter_size_label,x,1,1,1); + gtk_grid_attach(GTK_GRID(grid),filter_size_label,col,row,1,1); + row++; + col=0; + GtkWidget *filter_1024=gtk_radio_button_new_with_label(NULL,"1024"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (filter_1024), receiver[0]->fft_size==1024); - gtk_grid_attach(GTK_GRID(grid),filter_1024,x,2,1,1); + gtk_grid_attach(GTK_GRID(grid),filter_1024,col,row,1,1); g_signal_connect(filter_1024,"pressed",G_CALLBACK(filter_size_cb),(gpointer *)1024); + col++; + GtkWidget *filter_2048=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(filter_1024),"2048"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (filter_2048), receiver[0]->fft_size==2048); - gtk_grid_attach(GTK_GRID(grid),filter_2048,x,3,1,1); + gtk_grid_attach(GTK_GRID(grid),filter_2048,col,row,1,1); g_signal_connect(filter_2048,"pressed",G_CALLBACK(filter_size_cb),(gpointer *)2048); + col++; + GtkWidget *filter_4096=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(filter_2048),"4096"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (filter_4096), receiver[0]->fft_size==4096); - gtk_grid_attach(GTK_GRID(grid),filter_4096,x,4,1,1); + gtk_grid_attach(GTK_GRID(grid),filter_4096,col,row,1,1); g_signal_connect(filter_4096,"pressed",G_CALLBACK(filter_size_cb),(gpointer *)4096); + col++; + GtkWidget *filter_8192=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(filter_4096),"8192"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (filter_8192), receiver[0]->fft_size==8192); - gtk_grid_attach(GTK_GRID(grid),filter_8192,x,5,1,1); + gtk_grid_attach(GTK_GRID(grid),filter_8192,col,row,1,1); g_signal_connect(filter_8192,"pressed",G_CALLBACK(filter_size_cb),(gpointer *)8192); + col++; + GtkWidget *filter_16384=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(filter_8192),"16384"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (filter_16384), receiver[0]->fft_size==16384); - gtk_grid_attach(GTK_GRID(grid),filter_16384,x,6,1,1); + gtk_grid_attach(GTK_GRID(grid),filter_16384,col,row,1,1); g_signal_connect(filter_16384,"pressed",G_CALLBACK(filter_size_cb),(gpointer *)16394); - x++; #endif gtk_container_add(GTK_CONTAINER(content),grid); diff --git a/filter.c b/filter.c index 63d959c..86c1ad8 100644 --- a/filter.c +++ b/filter.c @@ -18,6 +18,8 @@ */ #include +#include + #include "filter.h" #include "property.h" @@ -201,23 +203,6 @@ FILTER filterDRM[FILTERS]={ {-3300,3300,"Var2"} }; -#ifdef FREEDV -FILTER filterFREEDV[FILTERS]={ - {150,5150,"5.0k"}, - {150,4550,"4.4k"}, - {150,3950,"3.8k"}, - {150,3450,"3.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 - #ifdef PSK FILTER filterPSK[FILTERS]={ {150,5150,"5.0k"}, @@ -249,9 +234,6 @@ FILTER *filters[]={ ,filterDIGL ,filterSAM ,filterDRM -#ifdef FREEDV - ,filterFREEDV -#endif #ifdef PSK ,filterPSK #endif diff --git a/filter_menu.c b/filter_menu.c index f0aa005..aee2b68 100644 --- a/filter_menu.c +++ b/filter_menu.c @@ -17,6 +17,8 @@ #include #include +#include +#include #include #include "new_menu.h" @@ -36,17 +38,26 @@ static GtkWidget *dialog=NULL; static GtkWidget *last_filter; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + int filter_select(void *data) { - int f=(int)data; + int f=(uintptr_t)data; vfo_filter_changed(f); return 0; } @@ -59,23 +70,27 @@ static gboolean filter_select_cb (GtkWidget *widget, gpointer data) { } static gboolean deviation_select_cb (GtkWidget *widget, gpointer data) { - deviation=(int)data; - if(deviation==2500) { + active_receiver->deviation=(uintptr_t)data; + transmitter->deviation=(uintptr_t)data; + if(active_receiver->deviation==2500) { //setFilter(-4000,4000); set_filter(active_receiver,-4000,4000); + tx_set_filter(transmitter,-4000,4000); } else { //setFilter(-8000,8000); set_filter(active_receiver,-8000,8000); + tx_set_filter(transmitter,-8000,8000); } - set_deviation(active_receiver,(double)deviation); + set_deviation(active_receiver); + transmitter_set_deviation(transmitter); set_button_text_color(last_filter,"black"); last_filter=widget; set_button_text_color(last_filter,"orange"); - vfo_update(NULL); + vfo_update(); } static void var_spin_low_cb (GtkWidget *widget, gpointer data) { - int f=(int)data; + int f=(uintptr_t)data; int id=active_receiver->id; FILTER *mode_filters=filters[vfo[id].mode]; @@ -86,12 +101,13 @@ static void var_spin_low_cb (GtkWidget *widget, gpointer data) { filter->high=filter->low; } if(f==vfo[id].filter) { - receiver_filter_changed(receiver[id]); + vfo_filter_changed(f); + //receiver_filter_changed(receiver[id]); } } static void var_spin_high_cb (GtkWidget *widget, gpointer data) { - int f=(int)data; + int f=(uintptr_t)data; int id=active_receiver->id; FILTER *mode_filters=filters[vfo[id].mode]; @@ -99,7 +115,8 @@ static void var_spin_high_cb (GtkWidget *widget, gpointer data) { filter->high=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); if(f==vfo[id].filter) { - receiver_filter_changed(receiver[id]); + vfo_filter_changed(f); + //receiver_filter_changed(receiver[id]); } } @@ -111,7 +128,11 @@ void filter_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + char title[64]; + sprintf(title,"piHPSDR - Filter (RX %d VFO %s)",active_receiver->id,active_receiver->id==0?"A":"B"); + gtk_window_set_title(GTK_WINDOW(dialog),title); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -129,45 +150,40 @@ void filter_menu(GtkWidget *parent) { gtk_grid_set_column_spacing (GTK_GRID(grid),5); gtk_grid_set_row_spacing (GTK_GRID(grid),5); - GtkWidget *close_b=gtk_button_new_with_label("Close Filter"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); - char label[32]; - sprintf(label,"RX %d VFO %s",active_receiver->id,active_receiver->id==0?"A":"B"); - GtkWidget *rx_label=gtk_label_new(label); - gtk_grid_attach(GTK_GRID(grid),rx_label,1,0,1,1); - BAND *band=band_get_band(vfo[active_receiver->id].band); BANDSTACK *bandstack=band->bandstack; BANDSTACK_ENTRY *entry=&bandstack->entry[vfo[active_receiver->id].bandstack]; FILTER* band_filters=filters[vfo[active_receiver->id].mode]; FILTER* band_filter=&band_filters[vfo[active_receiver->id].filter]; - switch(entry->mode) { + switch(vfo[active_receiver->id].mode) { case modeFMN: { GtkWidget *l=gtk_label_new("Deviation:"); gtk_grid_attach(GTK_GRID(grid),l,0,1,1,1); GtkWidget *b=gtk_button_new_with_label("2.5K"); - if(deviation==2500) { + if(active_receiver->deviation==2500) { set_button_text_color(b,"orange"); last_filter=b; } else { set_button_text_color(b,"black"); } - g_signal_connect(b,"pressed",G_CALLBACK(deviation_select_cb),(gpointer *)2500); + g_signal_connect(b,"pressed",G_CALLBACK(deviation_select_cb),(gpointer)(long)2500); gtk_grid_attach(GTK_GRID(grid),b,1,1,1,1); b=gtk_button_new_with_label("5.0K"); - if(deviation==5000) { + if(active_receiver->deviation==5000) { set_button_text_color(b,"orange"); last_filter=b; } else { set_button_text_color(b,"black"); } - g_signal_connect(b,"pressed",G_CALLBACK(deviation_select_cb),(gpointer *)5000); + g_signal_connect(b,"pressed",G_CALLBACK(deviation_select_cb),(gpointer)(long)5000); gtk_grid_attach(GTK_GRID(grid),b,2,1,1,1); } break; @@ -183,7 +199,7 @@ void filter_menu(GtkWidget *parent) { set_button_text_color(b,"black"); } gtk_grid_attach(GTK_GRID(grid),b,i%5,1+(i/5),1,1); - g_signal_connect(b,"pressed",G_CALLBACK(filter_select_cb),(gpointer *)i); + g_signal_connect(b,"pressed",G_CALLBACK(filter_select_cb),(gpointer)(long)i); } // last 2 are var1 and var2 @@ -197,18 +213,18 @@ void filter_menu(GtkWidget *parent) { set_button_text_color(b,"black"); } gtk_grid_attach(GTK_GRID(grid),b,0,row,1,1); - g_signal_connect(b,"pressed",G_CALLBACK(filter_select_cb),(gpointer *)i); + g_signal_connect(b,"pressed",G_CALLBACK(filter_select_cb),(gpointer)(long)i); GtkWidget *var1_spin_low=gtk_spin_button_new_with_range(-8000.0,+8000.0,1.0); gtk_spin_button_set_value(GTK_SPIN_BUTTON(var1_spin_low),(double)band_filter->low); gtk_grid_attach(GTK_GRID(grid),var1_spin_low,1,row,1,1); - g_signal_connect(var1_spin_low,"value-changed",G_CALLBACK(var_spin_low_cb),(gpointer *)i); + g_signal_connect(var1_spin_low,"value-changed",G_CALLBACK(var_spin_low_cb),(gpointer)(long)i); if(vfo[active_receiver->id].mode!=modeCWL && vfo[active_receiver->id].mode!=modeCWU) { GtkWidget *var1_spin_high=gtk_spin_button_new_with_range(-8000.0,+8000.0,1.0); gtk_spin_button_set_value(GTK_SPIN_BUTTON(var1_spin_high),(double)band_filter->high); gtk_grid_attach(GTK_GRID(grid),var1_spin_high,2,row,1,1); - g_signal_connect(var1_spin_high,"value-changed",G_CALLBACK(var_spin_high_cb),(gpointer *)i); + g_signal_connect(var1_spin_high,"value-changed",G_CALLBACK(var_spin_high_cb),(gpointer)(long)i); } row++; @@ -222,18 +238,18 @@ void filter_menu(GtkWidget *parent) { set_button_text_color(b,"black"); } gtk_grid_attach(GTK_GRID(grid),b,0,row,1,1); - g_signal_connect(b,"pressed",G_CALLBACK(filter_select_cb),(gpointer *)i); + g_signal_connect(b,"pressed",G_CALLBACK(filter_select_cb),(gpointer)(long)i); GtkWidget *var2_spin_low=gtk_spin_button_new_with_range(-8000.0,+8000.0,1.0); gtk_spin_button_set_value(GTK_SPIN_BUTTON(var2_spin_low),(double)band_filter->low); gtk_grid_attach(GTK_GRID(grid),var2_spin_low,1,row,1,1); - g_signal_connect(var2_spin_low,"value-changed",G_CALLBACK(var_spin_low_cb),(gpointer *)i); + g_signal_connect(var2_spin_low,"value-changed",G_CALLBACK(var_spin_low_cb),(gpointer)(long)i); if(vfo[active_receiver->id].mode!=modeCWL && vfo[active_receiver->id].mode!=modeCWU) { GtkWidget *var2_spin_high=gtk_spin_button_new_with_range(-8000.0,+8000.0,1.0); gtk_spin_button_set_value(GTK_SPIN_BUTTON(var2_spin_high),(double)band_filter->high); gtk_grid_attach(GTK_GRID(grid),var2_spin_high,2,row,1,1); - g_signal_connect(var2_spin_high,"value-changed",G_CALLBACK(var_spin_high_cb),(gpointer *)i); + g_signal_connect(var2_spin_high,"value-changed",G_CALLBACK(var_spin_high_cb),(gpointer)(long)i); } break; diff --git a/fm_menu.c b/fm_menu.c index d3d8847..0593c89 100644 --- a/fm_menu.c +++ b/fm_menu.c @@ -32,15 +32,24 @@ static GtkWidget *dialog=NULL; static GtkWidget *last_band; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static gboolean emp_cb (GtkWidget *widget, gpointer data) { if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) { pre_emphasize=1; @@ -58,7 +67,9 @@ void fm_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - FM"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -76,7 +87,7 @@ void fm_menu(GtkWidget *parent) { gtk_grid_set_column_spacing (GTK_GRID(grid),5); gtk_grid_set_row_spacing (GTK_GRID(grid),5); - GtkWidget *close_b=gtk_button_new_with_label("Close FM"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); diff --git a/freedv.c b/freedv.c index 8843a85..1c0627e 100644 --- a/freedv.c +++ b/freedv.c @@ -2,8 +2,17 @@ #include #include #include +#include +#include "freedv.h" +#include "audio_waterfall.h" +#include "channel.h" +#include "property.h" #include "radio.h" +#include "receiver.h" +#include "transmitter.h" + +#define min(x,y) (xfreedv_mutex); + close_freedv(rx); + freedv_mode=m; + init_freedv(rx); + g_mutex_unlock(&rx->freedv_mutex); + } else { + freedv_mode=m; + } +} static void text_data(char c) { int i; @@ -33,9 +98,9 @@ static void text_data(char c) { c='|'; } for(i=0;i<62;i++) { - freedv_text_data[i]=freedv_text_data[i+1]; + active_receiver->freedv_text_data[i]=active_receiver->freedv_text_data[i+1]; } - freedv_text_data[62]=c; + active_receiver->freedv_text_data[62]=c; } static void my_put_next_rx_char(void *callback_state, char c) { @@ -47,37 +112,86 @@ static void my_put_next_rx_char(void *callback_state, char c) { static char my_get_next_tx_char(void *callback_state){ - char c=freedv_tx_text_data[freedv_tx_text_index++]; + char c=transmitter->freedv_text_data[transmitter->freedv_text_index++]; if(c==0) { c=0x0D; - freedv_tx_text_index=0; + transmitter->freedv_text_index=0; } //fprintf(stderr,"freedv: my_get_next_tx_char=%c\n",c); - text_data(c); + //text_data(c); return c; } -void init_freedv() { - int i; +static void initAnalyzer(RECEIVER *rx,int channel, int buffer_size, int pixels) { + int flp[] = {0}; + double keep_time = 0.1; + int n_pixout=1; + int spur_elimination_ffts = 1; + int data_type = 0; + int fft_size = 1024; + int window_type = 4; + double kaiser_pi = 14.0; + int overlap = 0; + int clip = 0; + int span_clip_l = 0; + int span_clip_h = 0; + int stitches = 1; + int calibration_data_set = 0; + double span_min_freq = 0.0; + double span_max_freq = 0.0; + + int max_w = fft_size + (int) min(keep_time * (double) rx->fps, keep_time * (double) fft_size * (double) rx->fps); + + SetAnalyzer(channel, + n_pixout, + spur_elimination_ffts, //number of LO frequencies = number of ffts used in elimination + data_type, //0 for real input data (I only); 1 for complex input data (I & Q) + flp, //vector with one elt for each LO frequency, 1 if high-side LO, 0 otherwise + fft_size, //size of the fft, i.e., number of input samples + buffer_size, //number of samples transferred for each OpenBuffer()/CloseBuffer() + window_type, //integer specifying which window function to use + kaiser_pi, //PiAlpha parameter for Kaiser window + overlap, //number of samples each fft (other than the first) is to re-use from the previous + clip, //number of fft output bins to be clipped from EACH side of each sub-span + span_clip_l, //number of bins to clip from low end of entire span + span_clip_h, //number of bins to clip from high end of entire span + pixels, //number of pixel values to return. may be either <= or > number of bins + stitches, //number of sub-spans to concatenate to form a complete span + calibration_data_set, //identifier of which set of calibration data to use + span_min_freq, //frequency at first pixel value8192 + span_max_freq, //frequency at last pixel value + max_w //max samples to hold in input ring buffers + ); + +} + +void init_freedv(RECEIVER *rx) { + int i, success; fprintf(stderr,"init_freedv\n"); - modem=freedv_open(FREEDV_MODE_1600); + modem=freedv_open(freedv_mode); 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); + freedv_set_snr_squelch_thresh(modem, (float)freedv_snr_sq_threshold); + freedv_set_squelch_en(modem, freedv_sq_enable); 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); +fprintf(stderr,"n_speech_samples=%d n_max_modem_samples=%d n_nom_modem_samples=%d\n",n_speech_samples, n_max_modem_samples,n_nom_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); + //spectrum = (float*)malloc(sizeof(float)*n_nom_modem_samples); + + for(i=0;i<63;i++) { + rx->freedv_text_data[i]=' '; + } + rx->freedv_text_data[63]=0; nin = freedv_nin(modem); rx_samples_in=0; @@ -86,49 +200,111 @@ fprintf(stderr,"n_speech_samples=%d n_max_modem_samples=%d\n",n_speech_samples, //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); + freedv_rate=freedv_get_modem_sample_rate(modem); + freedv_resample=48000/freedv_rate; +fprintf(stderr,"freedv modem sample nin=%d rate=%d resample=%d\n",nin, freedv_rate, freedv_resample); - for(i=0;i<63;i++) { - freedv_text_data[i]=' '; + SetRXAPanelGain1 (rx->id, freedv_audio_gain); +/* + XCreateAnalyzer(CHANNEL_AUDIO, &success, 262144, 1, 1, ""); + if (success != 0) { + fprintf(stderr, "XCreateAnalyzer CHANNEL_AUDIO failed: %d\n" ,success); } - freedv_text_data[63]=0; + initAnalyzer(rx,CHANNEL_AUDIO,n_nom_modem_samples,200); + + audio_waterfall_setup(freedv_rate,1500); +*/ + + initialized=1; } -void close_freedv() { -fprintf(stderr,"freedv_close\n"); +void close_freedv(RECEIVER *rx) { +fprintf(stderr,"freedv_close rx=%p\n",rx); + initialized=0; if(modem!=NULL) { freedv_close(modem); } else { fprintf(stderr,"freedv_close: modem is null\n"); } + modem=NULL; +/* + DestroyAnalyzer(CHANNEL_AUDIO); +*/ + SetRXAPanelGain1 (rx->id, rx->volume); } 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); - } + if(initialized) { + 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); + } +#ifdef AUDIO_WATERFALL + if(audio_samples!=NULL) { + audio_samples[audio_samples_index]=(float)sample; + audio_samples_index++; + if(audio_samples_index>=AUDIO_WATERFALL_SAMPLES) { + Spectrum(CHANNEL_AUDIO,0,0,audio_samples,audio_samples); + audio_samples_index=0; + } + } +#endif + } return nout; } int mod_sample_freedv(short sample) { + int i; 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; - } + if(initialized) { + 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; +#ifdef AUDIO_WATERFALL + for(i=0;i=AUDIO_WATERFALL_SAMPLES) { + Spectrum(CHANNEL_AUDIO,0,0,audio_samples,audio_samples); + audio_samples_index=0; + } + } +#endif + } + } return nout; } void freedv_reset_tx_text_index() { - freedv_tx_text_index=0; + transmitter->freedv_text_index=0; +} + +void freedv_set_sq_enable(int state) { +fprintf(stderr,"freedv_set_sq_enable: state=%d modem=%p\n", state,modem); + freedv_sq_enable=state; + if(modem!=NULL) { + freedv_set_squelch_en(modem, freedv_sq_enable); + } +} + +void freedv_set_sq_threshold(double threshold) { + freedv_snr_sq_threshold=threshold; + if(modem!=NULL) { + freedv_set_snr_squelch_thresh(modem, freedv_snr_sq_threshold); + } +} + +void freedv_set_audio_gain(double gain) { + freedv_audio_gain=gain; + if(modem!=NULL) { + SetRXAPanelGain1 (active_receiver->id, freedv_audio_gain); + } } diff --git a/freedv.h b/freedv.h index 36bdd2b..26fe515 100644 --- a/freedv.h +++ b/freedv.h @@ -20,6 +20,8 @@ #ifndef _FREEDV_H #define _FREEDV_H +#include "receiver.h" + extern int n_speech_samples; extern int n_max_modem_samples; extern short *demod_in; @@ -30,12 +32,37 @@ extern short *mod_out; extern int freedv_sync; extern float freedv_snr; +extern int freedv_rate; +extern int freedv_resample; + +extern int freedv_mode; + extern char freedv_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(); +extern int freedv_sq_enable; +extern double freedv_snr_sq_threshold; + +extern double freedv_audio_gain; + +extern float *freedv_samples; + +extern void freedv_save_state(); +extern void freedv_restore_state(); +extern void init_freedv(RECEIVER *rx); +extern void close_freedv(RECEIVER *rx); +extern int demod_sample_freedv(short sample); +extern int mod_sample_freedv(short sample); +extern void freedv_reset_tx_text_index(); +extern void freedv_set_mode(RECEIVER *rx,int m); +extern void init_freedv(RECEIVER *rx); +extern void close_freedv(RECEIVER *rx); +extern int demod_sample_freedv(short sample); +extern int mod_sample_freedv(short sample); +extern void freedv_reset_tx_text_index(); +extern void freedv_set_mode(RECEIVER *rx,int m); +extern void freedv_set_sq_enable(int state); +extern void freedv_set_sq_threshold(double threshold); +extern void freedv_set_audio_gain(double gain); +extern char* freedv_get_mode_string(); #endif diff --git a/freedv_menu.c b/freedv_menu.c index 4ffbbdf..bceb948 100644 --- a/freedv_menu.c +++ b/freedv_menu.c @@ -1,4 +1,5 @@ -/* Copyright (C) +/* +* Copyright (C) * 2015 - John Melton, G0ORX/N6LYT * * This program is free software; you can redistribute it and/or @@ -20,12 +21,18 @@ #include #include #include +#include #include +#include +#include #include "new_menu.h" #include "freedv_menu.h" #include "freedv.h" #include "radio.h" +#include "receiver.h" +#include "vfo.h" +#include "ext.h" static GtkWidget *parent_window=NULL; @@ -33,17 +40,47 @@ static GtkWidget *menu_b=NULL; static GtkWidget *dialog=NULL; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static void freedv_text_changed_cb(GtkWidget *widget, gpointer data) { - strcpy(freedv_tx_text_data,gtk_entry_get_text(GTK_ENTRY(widget))); + strcpy(transmitter->freedv_text_data,gtk_entry_get_text(GTK_ENTRY(widget))); +} + +static void enable_cb(GtkWidget *widget, gpointer data) { + set_freedv(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))); +} + +static void sq_enable_cb(GtkWidget *widget, gpointer data) { + freedv_set_sq_enable(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))); +} + +static void sq_spin_cb (GtkWidget *widget, gpointer data) { + freedv_set_sq_threshold(gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget))); +} + +static void audio_spin_cb (GtkWidget *widget, gpointer data) { + freedv_set_audio_gain(gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget))); +} + +static void mode_cb(GtkWidget *widget, gpointer data) { + int mode=(uintptr_t)data; + freedv_set_mode(active_receiver,mode); } void freedv_menu(GtkWidget *parent) { @@ -53,7 +90,9 @@ void freedv_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - FreeDV"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -71,19 +110,84 @@ void freedv_menu(GtkWidget *parent) { gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); - GtkWidget *close_b=gtk_button_new_with_label("Close FreeDV"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); - GtkWidget *freedv_text_label=gtk_label_new("FreeDV Text Message: "); + GtkWidget *freedv_text_label=gtk_label_new("Tx Message: "); gtk_grid_attach(GTK_GRID(grid),freedv_text_label,0,1,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(grid),freedv_text,0,2,2,1); + gtk_entry_set_text(GTK_ENTRY(freedv_text),transmitter->freedv_text_data); + gtk_grid_attach(GTK_GRID(grid),freedv_text,1,1,3,1); g_signal_connect(freedv_text,"changed",G_CALLBACK(freedv_text_changed_cb),NULL); + GtkWidget *enable=gtk_check_button_new_with_label("Enable FreeDV"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (enable), active_receiver->freedv); + gtk_grid_attach(GTK_GRID(grid),enable,0,2,1,1); + g_signal_connect(enable,"toggled",G_CALLBACK(enable_cb),NULL); + + GtkWidget *sq_enable=gtk_check_button_new_with_label("SNR Squelch Enable (dB)"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sq_enable), freedv_sq_enable); + gtk_grid_attach(GTK_GRID(grid),sq_enable,1,2,1,1); + g_signal_connect(sq_enable,"toggled",G_CALLBACK(sq_enable_cb),NULL); + + GtkWidget *sq_spin=gtk_spin_button_new_with_range(-5.0,15.0,0.5); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(sq_spin),freedv_snr_sq_threshold); + gtk_grid_attach(GTK_GRID(grid),sq_spin,2,2,1,1); + g_signal_connect(sq_spin,"value-changed",G_CALLBACK(sq_spin_cb),NULL); + + GtkWidget *mode_1600=gtk_radio_button_new_with_label(NULL,"1600"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mode_1600), freedv_mode==FREEDV_MODE_1600); + gtk_widget_show(mode_1600); + gtk_grid_attach(GTK_GRID(grid),mode_1600,0,4,1,1); + g_signal_connect(mode_1600,"pressed",G_CALLBACK(mode_cb),(gpointer *)FREEDV_MODE_1600); + + GtkWidget *mode_700=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(mode_1600),"700"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mode_700), freedv_mode==FREEDV_MODE_700); + gtk_widget_show(mode_700); + gtk_grid_attach(GTK_GRID(grid),mode_700,1,4,1,1); + g_signal_connect(mode_700,"pressed",G_CALLBACK(mode_cb),(gpointer *)FREEDV_MODE_700); + + GtkWidget *mode_700B=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(mode_700),"700B"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mode_700B), freedv_mode==FREEDV_MODE_700B); + gtk_widget_show(mode_700B); + gtk_grid_attach(GTK_GRID(grid),mode_700B,2,4,1,1); + g_signal_connect(mode_700B,"pressed",G_CALLBACK(mode_cb),(gpointer *)FREEDV_MODE_700B); + + GtkWidget *mode_2400A=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(mode_700B),"2400A"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mode_2400A), freedv_mode==FREEDV_MODE_2400A); + gtk_widget_show(mode_2400A); + gtk_grid_attach(GTK_GRID(grid),mode_2400A,0,5,1,1); + g_signal_connect(mode_2400A,"pressed",G_CALLBACK(mode_cb),(gpointer *)FREEDV_MODE_2400A); + + GtkWidget *mode_2400B=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(mode_2400A),"2400B"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mode_2400B), freedv_mode==FREEDV_MODE_2400B); + gtk_widget_show(mode_2400B); + gtk_grid_attach(GTK_GRID(grid),mode_2400B,1,5,1,1); + g_signal_connect(mode_2400B,"pressed",G_CALLBACK(mode_cb),(gpointer *)FREEDV_MODE_2400B); + + GtkWidget *mode_800XA=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(mode_2400B),"800XA"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mode_800XA), freedv_mode==FREEDV_MODE_800XA); + gtk_widget_show(mode_800XA); + gtk_grid_attach(GTK_GRID(grid),mode_800XA,2,5,1,1); + g_signal_connect(mode_800XA,"pressed",G_CALLBACK(mode_cb),(gpointer *)FREEDV_MODE_800XA); + + GtkWidget *mode_700C=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(mode_800XA),"700C"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mode_700C), freedv_mode==FREEDV_MODE_700C); + gtk_widget_show(mode_700C); + gtk_grid_attach(GTK_GRID(grid),mode_700C,3,5,1,1); + g_signal_connect(mode_700C,"pressed",G_CALLBACK(mode_cb),(gpointer *)FREEDV_MODE_700C); + + GtkWidget *freedv_audio_label=gtk_label_new("Audio Gain: "); + gtk_grid_attach(GTK_GRID(grid),freedv_audio_label,0,6,1,1); + + GtkWidget *audio_spin=gtk_spin_button_new_with_range(0.0,1.0,0.1); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(audio_spin),freedv_audio_gain); + gtk_grid_attach(GTK_GRID(grid),audio_spin,1,6,1,1); + g_signal_connect(audio_spin,"value-changed",G_CALLBACK(audio_spin_cb),NULL); + gtk_container_add(GTK_CONTAINER(content),grid); sub_menu=dialog; diff --git a/freqent_menu.c b/freqent_menu.c index 987de81..004d984 100644 --- a/freqent_menu.c +++ b/freqent_menu.c @@ -18,9 +18,10 @@ */ #include +#include #include -#include #include +#include #include "new_menu.h" #include "band.h" @@ -29,6 +30,7 @@ #include "radio.h" #include "receiver.h" #include "vfo.h" +#include "button_text.h" static GtkWidget *parent_window=NULL; static GtkWidget *dialog=NULL; @@ -42,13 +44,22 @@ static char *btn_labels[] = {"1","2","3","4", "HZ","KZ","MZ","CR" }; +static void cleanup() { + if(dialog!=NULL) { + gtk_widget_destroy(dialog); + dialog=NULL; + sub_menu=NULL; + } +} + static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { - if(dialog!=NULL) { - gtk_widget_destroy(dialog); - dialog=NULL; - sub_menu=NULL; - } - return TRUE; + cleanup(); + return TRUE; +} + +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; } static gboolean freqent_select_cb (GtkWidget *widget, gpointer data) { @@ -131,12 +142,12 @@ static gboolean freqent_select_cb (GtkWidget *widget, gpointer data) { } } setFrequency(f); - vfo_update(NULL); + vfo_update(); set = 1; } } - vfo_update(NULL); + vfo_update(); } static GtkWidget *last_mode; @@ -148,7 +159,11 @@ void freqent_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + char title[64]; + sprintf(title,"piHPSDR - Frequency Entry (RX %d VFO %s)",active_receiver->id,active_receiver->id==0?"A":"B"); + gtk_window_set_title(GTK_WINDOW(dialog),title); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -166,7 +181,7 @@ void freqent_menu(GtkWidget *parent) { gtk_grid_set_column_spacing (GTK_GRID(grid),4); gtk_grid_set_row_spacing (GTK_GRID(grid),4); - GtkWidget *close_b=gtk_button_new_with_label("Close FreqEntry"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); @@ -175,11 +190,6 @@ void freqent_menu(GtkWidget *parent) { gtk_misc_set_alignment (GTK_MISC (label), 1, .5); gtk_grid_attach(GTK_GRID(grid),label,1,0,2,1); - char label[32]; - sprintf(label,"RX %d VFO %s",active_receiver->id,active_receiver->id==0?"A":"B"); - GtkWidget *rx_label=gtk_label_new(label); - gtk_grid_attach(GTK_GRID(grid),rx_label,3,0,1,1); - GtkWidget *step_rb=NULL; for (i=0; i<16; i++) { GtkWidget *b=gtk_button_new_with_label(btn_labels[i]); diff --git a/frequency.c b/frequency.c index 04a89f2..98cbdf9 100644 --- a/frequency.c +++ b/frequency.c @@ -82,11 +82,8 @@ struct frequency_info frequencyInfo[]= {5000000LL, 5000000LL, "WWV", bandWWV,FALSE}, - {5330500LL, 5330500LL, "60M Channel 1", band60, TRUE}, - {5346500LL, 5346500LL, "60M Channel 2", band60, TRUE}, - {5366500LL, 5366500LL, "60M Channel 3", band60, TRUE}, - {5371500LL, 5371500LL, "60M Channel 4", band60, TRUE}, - {5403500LL, 5403500LL, "60M Channel 5", band60, TRUE}, + {5261250LL, 5408000LL, "60M", band60, TRUE}, + {5261250LL, 5408000LL, "60M", band60, FALSE}, {5900000LL, 6200000LL, "49M Short Wave", bandGen,FALSE}, @@ -396,23 +393,46 @@ struct frequency_info frequencyInfo[]= * * @return */ -char* getFrequencyInfo(long long frequency) { +char* getFrequencyInfo(long long frequency,int filter_low,int filter_high) { char* result=outOfBand; + long long flow=frequency+(long long)filter_low; + long long fhigh=frequency+(long long)filter_high; + +//fprintf(stderr,"getFrequency: frequency=%lld filter_low=%d filter_high=%d flow=%lld fhigh=%lld\n", +// frequency,filter_low,filter_high,flow,fhigh); + info=frequencyInfo; while(info->minFrequency!=0) { - if(frequencyminFrequency) { + if(flowminFrequency) { info=0; break; - } else if(frequency>=info->minFrequency && frequency<=info->maxFrequency) { - result=info->info; + } else if(flow>=info->minFrequency && fhigh<=info->maxFrequency) { + if(info->band==band60) { + int i; + for(i=0;i=band_channels_60m[i].frequency && fhigh<=(band_channels_60m[i].frequency+band_channels_60m[i].width)) { + result=info->info; + break; + } + } + if(i>=channel_entries) { + info++; + } + break; + } else { + result=info->info; + } break; } info++; } +//fprintf(stderr,"info: %s tx=%d\n", info->info, info->transmit); + return result; } @@ -425,6 +445,7 @@ char* getFrequencyInfo(long long frequency) { * @return */ int getBand(long long frequency) { + int result=bandGen; info=frequencyInfo; diff --git a/frequency.h b/frequency.h index 9c9199f..6dcb143 100644 --- a/frequency.h +++ b/frequency.h @@ -40,8 +40,8 @@ struct frequency_info { }; -char* getFrequencyInfo(long long frequency); -int getBand(long long frequency); -int canTransmit(); +extern char* getFrequencyInfo(long long frequency,int filter_low,int filter_high); +extern int getBand(long long frequency); +extern int canTransmit(); #endif diff --git a/general_menu.c b/general_menu.c index 185bc89..9645c55 100644 --- a/general_menu.c +++ b/general_menu.c @@ -35,15 +35,24 @@ static GtkWidget *menu_b=NULL; static GtkWidget *dialog=NULL; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static void vfo_divisor_value_changed_cb(GtkWidget *widget, gpointer data) { vfo_encoder_divisor=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); } @@ -146,7 +155,9 @@ void general_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - General"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -163,7 +174,7 @@ void general_menu(GtkWidget *parent) { //gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); - GtkWidget *close_b=gtk_button_new_with_label("Close General"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "button_press_event", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); diff --git a/gpio.c b/gpio.c index 67c756f..ffed31e 100644 --- a/gpio.c +++ b/gpio.c @@ -220,7 +220,9 @@ char *encoder_string[] = { "CW SPEED", "CW FREQUENCY", "PANADAPTER HIGH", -"PANADAPTER LOW" +"PANADAPTER LOW", +"SQUELCH", +"COMP" }; static int mox_pressed(void *data) { @@ -397,7 +399,6 @@ static void moxAlert() { int level1=digitalRead(MOX_BUTTON); usleep(20000); int level2=digitalRead(MOX_BUTTON); -fprintf(stderr,"moxAlert: level1=%d level2=%d\n",level1,level2); if(level1==0 && level2==0) { g_idle_add(mox_pressed,(gpointer)NULL); } @@ -962,7 +963,7 @@ static encoder_changed(int action,int pos) { if(protocol==NEW_PROTOCOL) { schedule_high_priority(); } - vfo_update(NULL); + vfo_update(); break; case ENCODER_CW_SPEED: value=(double)cw_keyer_speed; @@ -973,7 +974,7 @@ static encoder_changed(int action,int pos) { value=60.0; } cw_keyer_speed=(int)value; - vfo_update(NULL); + vfo_update(); break; case ENCODER_CW_FREQUENCY: value=(double)cw_keyer_sidetone_frequency; @@ -984,7 +985,7 @@ static encoder_changed(int action,int pos) { value=1000.0; } cw_keyer_sidetone_frequency=(int)value; - vfo_update(NULL); + vfo_update(); break; case ENCODER_PANADAPTER_HIGH: value=(double)active_receiver->panadapter_high; @@ -996,6 +997,28 @@ static encoder_changed(int action,int pos) { value+=(double)pos; active_receiver->panadapter_low=(int)value; break; + case ENCODER_SQUELCH: + value=active_receiver->squelch; + value+=(double)pos; + if(value<0.0) { + value=0.0; + } else if(value>100.0) { + value=100.0; + } + active_receiver->squelch=value; + set_squelch(active_receiver); + break; + case ENCODER_COMP: + value=(double)transmitter->compressor_level; + value+=(double)pos; + if(value<0.0) { + value=0.0; + } else if(value>20.0) { + value=20.0; + } + transmitter->compressor_level=(int)value; + set_compression(transmitter); + break; } } diff --git a/gpio.h b/gpio.h index e6fd120..2aa643a 100644 --- a/gpio.h +++ b/gpio.h @@ -17,8 +17,8 @@ * */ -#ifndef GPIO_H -#define GPIO_H +#ifndef _GPIO_H +#define _GPIO_H enum { ENCODER_AF_GAIN=0, @@ -26,18 +26,20 @@ enum { ENCODER_ATTENUATION, ENCODER_MIC_GAIN, ENCODER_DRIVE, - ENCODER_TUNE_DRIVE, +// ENCODER_TUNE_DRIVE, ENCODER_RIT, ENCODER_CW_SPEED, ENCODER_CW_FREQUENCY, ENCODER_PANADAPTER_HIGH, - ENCODER_PANADAPTER_LOW + ENCODER_PANADAPTER_LOW, + ENCODER_SQUELCH, + ENCODER_COMP, + ENCODER_LAST }; -#define ENCODER_LAST ENCODER_PANADAPTER_LOW -extern char *encoder_string[ENCODER_LAST+1]; +extern char *encoder_string[ENCODER_LAST]; extern int e1_encoder_action; extern int e2_encoder_action; diff --git a/gpio_mraa.c b/gpio_mraa.c index 8b054ae..9cc2bb2 100644 --- a/gpio_mraa.c +++ b/gpio_mraa.c @@ -774,7 +774,7 @@ static int vfo_encoder_changed(void *data) { //entry->frequency=entry->frequency+(pos*step); //setFrequency(entry->frequency); setFrequency(entry->frequency+ddsOffset+(pos*step)); - vfo_update(NULL); + vfo_update(); } free(data); return 0; diff --git a/i2c.c b/i2c.c index d33dbec..fac927a 100644 --- a/i2c.c +++ b/i2c.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include "i2c.h" @@ -16,14 +15,12 @@ #include "radio.h" #include "toolbar.h" #include "vfo.h" +#include "ext.h" #define I2C_DEVICE "/dev/i2c-1" #define ADDRESS_1 0X20 #define ADDRESS_2 0X23 -//static pthread_t i2c_thread_id; -static GThread *i2c_thread_id; - static int write_byte_data(unsigned char addr,unsigned char reg, unsigned char data) { int fd; int rc; @@ -54,7 +51,7 @@ static unsigned char read_byte_data(unsigned char addr,unsigned char reg) { int rc; if((fd=open(I2C_DEVICE, O_RDWR))<0) { - fprintf(stderr,"c$cannot open %s: %s\n",I2C_DEVICE,strerror(errno)); + fprintf(stderr,"cannot open %s: %s\n",I2C_DEVICE,strerror(errno)); exit(1); } @@ -74,149 +71,121 @@ static unsigned char read_byte_data(unsigned char addr,unsigned char reg) { return rc; } +static unsigned int read_word_data(unsigned char addr,unsigned char reg) { + int fd; + int rc; + + if((fd=open(I2C_DEVICE, O_RDWR))<0) { + fprintf(stderr,"c$cannot open %s: %s\n",I2C_DEVICE,strerror(errno)); + exit(1); + } + + if(ioctl(fd,I2C_SLAVE,addr)<0) { + fprintf(stderr,"cannot aquire access to I2C device at 0x%x\n",addr); + exit(1); + } + + rc=i2c_smbus_read_word_data(fd,reg); + if(rc<0) { + fprintf(stderr,"i2c_smbus_read_word_data failed: 0x%2X: %s\n",reg,strerror(errno)); + exit(1); + } + + close(fd); + + return rc; +} + + static void frequencyStep(int pos) { - BANDSTACK_ENTRY* entry=bandstack_entry_get_current(); - setFrequency(entry->frequency+ddsOffset+(pos*step)); - vfo_update(NULL); + vfo_step(pos); } -static void *i2c_thread(void *arg) { - int rc_1_a; - int rc_1_b; - int prev_rc_1_a=0; - int prev_rc_1_b=0; - int rc_2_a; - int rc_2_b; - int prev_rc_2_a=0; - int prev_rc_2_b=0; - - while(1) { - rc_1_a=read_byte_data(ADDRESS_1,0x12); - if(rc_1_a!=0 && rc_1_a!=prev_rc_1_a) { - fprintf(stderr,"Dev 1: GPIOA: 0x%02X\n",rc_1_a); - switch(rc_1_a) { - case 0x01: - g_idle_add(band_update,(void *)band160); - break; - case 0x02: - g_idle_add(band_update,(void *)band80); - break; - case 0x04: - g_idle_add(band_update,(void *)band60); - break; - case 0x08: - g_idle_add(band_update,(void *)band40); - break; - case 0x10: - g_idle_add(band_update,(void *)band30); - break; - case 0x20: - g_idle_add(band_update,(void *)band20); - break; - case 0x40: - g_idle_add(band_update,(void *)band17); - break; - case 0x80: - g_idle_add(band_update,(void *)band15); - break; - } - } - prev_rc_1_a=rc_1_a; - - rc_1_b=read_byte_data(ADDRESS_1,0x13); - if(rc_1_b!=0 && rc_1_b!=prev_rc_1_b) { - fprintf(stderr,"Dev 1: GPIOB: 0x%02X\n",rc_1_b); - switch(rc_1_b) { - case 0x01: - g_idle_add(band_update,(void *)band12); - break; - case 0x02: - g_idle_add(band_update,(void *)band10); - break; - case 0x04: - g_idle_add(band_update,(void *)band6); - break; - case 0x08: - g_idle_add(band_update,(void *)bandGen); - break; - case 0x10: - frequencyStep(+1); - break; - case 0x20: - break; - case 0x40: - break; - case 0x80: - frequencyStep(-1); - break; - } - } - prev_rc_1_b=rc_1_b; - - rc_2_a=read_byte_data(ADDRESS_2,0x12); - if(rc_2_a!=0 && rc_2_a!=prev_rc_2_a) { - fprintf(stderr,"Dev 2: GPIOA: 0x%02X\n",rc_2_a); - switch(rc_2_a) { - case 0x01: - break; - case 0x02: - mox_cb(NULL,NULL); - break; - case 0x04: - tune_cb(NULL,NULL); - break; - case 0x08: - break; - case 0x10: - break; - case 0x20: - break; - case 0x40: - break; - case 0x80: - break; +void i2c_interrupt() { + int flags; + int ints; + + do { + flags=read_word_data(ADDRESS_1,0x0E); + if(flags) { + ints=read_word_data(ADDRESS_1,0x10); + fprintf(stderr,"i2c_interrupt: flags=%04X,ints=%04X\n",flags,ints); + if(ints) { + switch(ints) { + case 0x0001: + g_idle_add(ext_mox_update,NULL); + break; + case 0x0002: + g_idle_add(ext_tune_update,NULL); + break; + case 0x0004: + g_idle_add(ext_band_update,NULL); + break; + case 0x0008: + g_idle_add(ext_band_update,(void *)band40); + break; + case 0x0010: + g_idle_add(ext_band_update,(void *)band30); + break; + case 0x0020: + g_idle_add(ext_band_update,(void *)band20); + break; + case 0x0040: + g_idle_add(ext_band_update,(void *)band17); + break; + case 0x0080: + g_idle_add(ext_band_update,(void *)band15); + break; + case 0x0100: + g_idle_add(ext_band_update,(void *)band12); + break; + case 0x0200: + g_idle_add(ext_band_update,(void *)band10); + break; + case 0x0400: + g_idle_add(ext_band_update,(void *)band6); + break; + case 0x0800: + g_idle_add(ext_band_update,(void *)bandGen); + break; + case 0x1000: + g_idle_add(ext_band_update,(void *)band12); + break; + case 0x2000: + g_idle_add(ext_band_update,(void *)band10); + break; + case 0x4000: + g_idle_add(ext_band_update,(void *)band6); + break; + case 0x8000: + g_idle_add(ext_band_update,(void *)bandGen); + break; + } } } - prev_rc_2_a=rc_2_a; - - rc_2_b=read_byte_data(ADDRESS_2,0x13); - if(rc_2_b!=0 && rc_2_b!=prev_rc_2_b) { - fprintf(stderr,"Dev 2: GPIOB: 0x%02X\n",rc_2_b); - switch(rc_2_b) { - case 0x01: - break; - case 0x02: - break; - case 0x04: - break; - case 0x08: - break; - case 0x10: - break; - case 0x20: - break; - case 0x40: - break; - case 0x80: - break; - } - } - prev_rc_2_b=rc_2_b; - - usleep(200); - } - + } while(flags!=0); } void i2c_init() { + int flags, ints; + fprintf(stderr,"i2c_init\n"); // setup i2c - if(write_byte_data(ADDRESS_1,0x0A,0x22)<0) return; + if(write_byte_data(ADDRESS_1,0x0A,0x44)<0) return; + if(write_byte_data(ADDRESS_1,0x0B,0x44)<0) return; - // set GPIOA/B for input - if(write_byte_data(ADDRESS_1,0x00,0xFF)<0) return; - if(write_byte_data(ADDRESS_1,0x01,0xFF)<0) return; + // disable interrupt + if(write_byte_data(ADDRESS_1,0x04,0x00)<0) return; + if(write_byte_data(ADDRESS_1,0x05,0x00)<0) return; + + // clear defaults + if(write_byte_data(ADDRESS_1,0x06,0x00)<0) return; + if(write_byte_data(ADDRESS_1,0x07,0x00)<0) return; + + // OLAT + if(write_byte_data(ADDRESS_1,0x14,0x00)<0) return; + if(write_byte_data(ADDRESS_1,0x15,0x00)<0) return; // set GPIOA for pullups if(write_byte_data(ADDRESS_1,0x0C,0xFF)<0) return; @@ -226,33 +195,25 @@ fprintf(stderr,"i2c_init\n"); if(write_byte_data(ADDRESS_1,0x02,0xFF)<0) return; if(write_byte_data(ADDRESS_1,0x03,0xFF)<0) return; - // setup i2c - if(write_byte_data(ADDRESS_2,0x0A,0x22)<0) return; - // set GPIOA/B for input - if(write_byte_data(ADDRESS_2,0x00,0xFF)<0) return; - if(write_byte_data(ADDRESS_2,0x01,0xFF)<0) return; - - // set GPIOA for pullups - if(write_byte_data(ADDRESS_2,0x0C,0xFF)<0) return; - if(write_byte_data(ADDRESS_2,0x0D,0xFF)<0) return; - - // reverse polarity - if(write_byte_data(ADDRESS_2,0x02,0xFF)<0) return; - if(write_byte_data(ADDRESS_2,0x03,0xFF)<0) return; + if(write_byte_data(ADDRESS_1,0x00,0xFF)<0) return; + if(write_byte_data(ADDRESS_1,0x01,0xFF)<0) return; -/* - int rc; - rc=pthread_create(&i2c_thread_id,NULL,i2c_thread,NULL); - if(rc != 0) { - fprintf(stderr,"i2c_init: pthread_create failed on i2c_thread: rc=%d\n", rc); - } -*/ - i2c_thread_id = g_thread_new( "i2c", i2c_thread, NULL); - if( ! i2c_thread_id ) - { - fprintf(stderr,"g_thread_new failed on i2c_thread\n"); - } + // INTCON + if(write_byte_data(ADDRESS_1,0x08,0x00)<0) return; + if(write_byte_data(ADDRESS_1,0x09,0x00)<0) return; + // setup for an MCP23017 interrupt + if(write_byte_data(ADDRESS_1,0x04,0xFF)<0) return; + if(write_byte_data(ADDRESS_1,0x05,0xFF)<0) return; + // flush any interrupts + do { + flags=read_word_data(ADDRESS_1,0x0E); + if(flags) { + ints=read_word_data(ADDRESS_1,0x10); + fprintf(stderr,"flush interrupt: flags=%04X ints=%04X\n",flags,ints); + } + } while(flags!=0); + } diff --git a/i2c.h b/i2c.h index 14ec886..e06808d 100644 --- a/i2c.h +++ b/i2c.h @@ -1,2 +1,3 @@ void i2c_init(); +void i2c_interrupt(); diff --git a/led.c b/led.c index 00d6561..98525ba 100644 --- a/led.c +++ b/led.c @@ -19,31 +19,24 @@ #include -static GtkWidget *led; - -static double red=0.0; -static double green=1.0; -static double blue=0.0; - - -static gboolean draw_cb (GtkWidget *widget, cairo_t *cr, gpointer data) { - cairo_set_source_rgb(cr, red, green, blue); +static gboolean draw_led_cb (GtkWidget *widget, cairo_t *cr, gpointer data) { + GdkRGBA *color=(GdkRGBA *)data; +//fprintf(stderr,"draw_led_cb: %p color=%p r=%f g=%f b=%f\n",widget,color,color->red,color->green,color->blue); + cairo_set_source_rgb(cr, color->red, color->green, color->blue); cairo_paint(cr); return FALSE; } -void led_set_color(double r,double g,double b) { - red=r; - green=g; - blue=b; +void led_set_color(GtkWidget *led) { +//fprintf(stderr,"led_set_color: %p\n",led); gtk_widget_queue_draw (led); } -GtkWidget *create_led(int width,int height) { - led=gtk_drawing_area_new(); +GtkWidget *create_led(int width,int height,GdkRGBA *color) { + GtkWidget *led=gtk_drawing_area_new(); gtk_widget_set_size_request(led,width,height); + g_signal_connect (led, "draw", G_CALLBACK (draw_led_cb), (gpointer)color); - g_signal_connect (led, "draw", G_CALLBACK (draw_cb), NULL); - +fprintf(stderr,"create_led: %p: color=%p\n",led,color); return led; } diff --git a/led.h b/led.h index 905ef22..fef24a6 100644 --- a/led.h +++ b/led.h @@ -18,5 +18,6 @@ */ -extern GtkWidget *create_led(int width,int height); -extern void led_set_color(double r,double g,double b); +extern GtkWidget *create_led(int width,int height,GdkRGBA *color); +extern void led_set_color(GtkWidget *led); + diff --git a/main.c b/main.c index 8398ffa..16628ff 100644 --- a/main.c +++ b/main.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -48,6 +49,9 @@ #include "i2c.h" #endif #include "discovery.h" +#include "new_protocol.h" +#include "old_protocol.h" +#include "ext.h" struct utsname unameData; @@ -87,34 +91,37 @@ static gint save_cb(gpointer data) { static pthread_t wisdom_thread_id; static void* wisdom_thread(void *arg) { +fprintf(stderr,"Creating wisdom file: %s\n", (char *)arg); status_text("Creating FFTW Wisdom file ..."); WDSPwisdom ((char *)arg); sem_post(&wisdom_sem); } gboolean main_delete (GtkWidget *widget) { + if(radio!=NULL) { #ifdef GPIO - gpio_close(); + gpio_close(); #endif - switch(protocol) { - case ORIGINAL_PROTOCOL: - old_protocol_stop(); - break; - case NEW_PROTOCOL: - new_protocol_stop(); - break; + 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; + case LIMESDR_PROTOCOL: + lime_protocol_stop(); + break; #endif #ifdef RADIOBERRY - case RADIOBERRY_PROTOCOL: - radioberry_protocol_stop(); - break; + case RADIOBERRY_PROTOCOL: + radioberry_protocol_stop(); + break; #endif + } + radioSaveState(); } - radioSaveState(); _exit(0); } @@ -149,7 +156,7 @@ static int init(void *data) { } } - g_idle_add(discovery,NULL); + g_idle_add(ext_discovery,NULL); return 0; } @@ -160,6 +167,7 @@ static void activate_pihpsdr(GtkApplication *app, gpointer data) { fprintf(stderr,"Build: %s %s\n",build_date,version); + fprintf(stderr,"GTK+ version %d.%d.%d\n", gtk_major_version, gtk_minor_version, gtk_micro_version); uname(&unameData); fprintf(stderr,"sysname: %s\n",unameData.sysname); fprintf(stderr,"nodename: %s\n",unameData.nodename); @@ -179,6 +187,18 @@ static void activate_pihpsdr(GtkApplication *app, gpointer data) { fprintf(stderr,"width=%d height=%d\n", display_width, display_height); if(display_width>800 || display_height>480) { +/* + if(display_width>1600) { + display_width=1600; + } else { + display_width=800; + } + if(display_height>960) { + display_height=960; + } else { + display_height=480; + } +*/ display_width=800; display_height=480; full_screen=0; @@ -193,9 +213,17 @@ fprintf(stderr,"full screen\n"); gtk_window_fullscreen(GTK_WINDOW(top_window)); } gtk_widget_set_size_request(top_window, display_width, display_height); - gtk_window_set_title (GTK_WINDOW (top_window), "pihpsdr"); + gtk_window_set_title (GTK_WINDOW (top_window), "piHPSDR"); gtk_window_set_position(GTK_WINDOW(top_window),GTK_WIN_POS_CENTER_ALWAYS); gtk_window_set_resizable(GTK_WINDOW(top_window), FALSE); + fprintf(stderr,"setting top window icon\n"); + GError *error; + if(!gtk_window_set_icon_from_file (GTK_WINDOW(top_window), "hpsdr.png", &error)) { + fprintf(stderr,"Warning: failed to set icon for top_window\n"); + if(error!=NULL) { + fprintf(stderr,"%s\n",error->message); + } + } g_signal_connect (top_window, "delete-event", G_CALLBACK (main_delete), NULL); //g_signal_connect (top_window,"draw", G_CALLBACK (main_draw_cb), NULL); @@ -219,7 +247,7 @@ fprintf(stderr,"add image to grid\n"); fprintf(stderr,"create pi label\n"); char build[64]; sprintf(build,"build: %s %s",build_date, version); - GtkWidget *pi_label=gtk_label_new("pihpsdr by John Melton g0orx/n6lyt"); + GtkWidget *pi_label=gtk_label_new("piHPSDR by John Melton g0orx/n6lyt"); gtk_label_set_justify(GTK_LABEL(pi_label),GTK_JUSTIFY_LEFT); gtk_widget_show(pi_label); fprintf(stderr,"add pi label to grid\n"); @@ -235,7 +263,7 @@ fprintf(stderr,"add build label to grid\n"); fprintf(stderr,"create status\n"); status=gtk_label_new(""); gtk_label_set_justify(GTK_LABEL(status),GTK_JUSTIFY_LEFT); - gtk_widget_override_font(status, pango_font_description_from_string("FreeMono 18")); + //gtk_widget_override_font(status, pango_font_description_from_string("FreeMono 18")); gtk_widget_show(status); fprintf(stderr,"add status to grid\n"); gtk_grid_attach(GTK_GRID(grid), status, 1, 3, 1, 1); @@ -261,7 +289,13 @@ int main(int argc,char **argv) { GtkApplication *pihpsdr; int status; - pihpsdr=gtk_application_new("org.g0orx.pihpsdr", G_APPLICATION_FLAGS_NONE); + char name[1024]; + + sprintf(name,"org.g0orx.pihpsdr.pid%d",getpid()); + +fprintf(stderr,"gtk_application_new: %s\n",name); + + pihpsdr=gtk_application_new(name, G_APPLICATION_FLAGS_NONE); g_signal_connect(pihpsdr, "activate", G_CALLBACK(activate_pihpsdr), NULL); status=g_application_run(G_APPLICATION(pihpsdr), argc, argv); fprintf(stderr,"exiting ...\n"); diff --git a/main.h b/main.h index 49a76c9..5a8d605 100644 --- a/main.h +++ b/main.h @@ -20,22 +20,6 @@ #ifndef _MAIN_H #define _MAIN_H -#define DISPLAY_INCREMENT (display_height/32) -#define MENU_HEIGHT (DISPLAY_INCREMENT*2) -#define MENU_WIDTH ((display_width/32)*3) -#define VFO_HEIGHT (DISPLAY_INCREMENT*4) -#define VFO_WIDTH (display_width-METER_WIDTH-MENU_WIDTH) -#define METER_HEIGHT (DISPLAY_INCREMENT*4) -#define METER_WIDTH ((display_width/32)*8) -#define PANADAPTER_HEIGHT (DISPLAY_INCREMENT*8) -#define SLIDERS_HEIGHT (DISPLAY_INCREMENT*6) -#define TOOLBAR_HEIGHT (DISPLAY_INCREMENT*2) -#define WATERFALL_HEIGHT (display_height-(VFO_HEIGHT+PANADAPTER_HEIGHT+SLIDERS_HEIGHT+TOOLBAR_HEIGHT)) -#ifdef PSK -#define PSK_WATERFALL_HEIGHT (DISPLAY_INCREMENT*6) -#define PSK_HEIGHT (display_height-(VFO_HEIGHT+PSK_WATERFALL_HEIGHT+SLIDERS_HEIGHT+TOOLBAR_HEIGHT)) -#endif - #include extern struct utsname unameData; diff --git a/meter.c b/meter.c index 426d1c0..cd6c9cb 100644 --- a/meter.c +++ b/meter.c @@ -22,14 +22,17 @@ #include #include #include +#include #include "meter.h" #include "wdsp.h" #include "radio.h" #include "version.h" #include "mode.h" +#include "vox.h" #ifdef FREEDV #include "freedv.h" +#include "vfo.h" #endif #ifdef PSK #include "psk.h" @@ -54,12 +57,13 @@ meter_clear_surface (void) cairo_t *cr; cr = cairo_create (meter_surface); - cairo_set_source_rgb (cr, 0, 0, 0); + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); cairo_fill (cr); cairo_destroy (cr); } +static gboolean meter_configure_event_cb (GtkWidget *widget, GdkEventConfigure *event, gpointer data) @@ -75,7 +79,7 @@ meter_configure_event_cb (GtkWidget *widget, /* Initialize the surface to black */ cairo_t *cr; cr = cairo_create (meter_surface); - cairo_set_source_rgb (cr, 0, 0, 0); + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); cairo_paint (cr); cairo_destroy (cr); @@ -88,9 +92,9 @@ meter_configure_event_cb (GtkWidget *widget, */ static gboolean meter_draw_cb (GtkWidget *widget, cairo_t *cr, gpointer data) { - cairo_set_source_surface (cr, meter_surface, 0, 0); + cairo_set_source_surface (cr, meter_surface, 0.0, 0.0); cairo_paint (cr); - return TRUE; + return FALSE; } /* @@ -182,6 +186,7 @@ meter_press_event_cb (GtkWidget *widget, GtkWidget* meter_init(int width,int height,GtkWidget *parent) { + GError *error; fprintf(stderr,"meter_init: width=%d height=%d\n",width,height); meter_width=width; @@ -216,21 +221,294 @@ void meter_update(int meter_type,double value,double reverse,double exciter,doub cairo_t *cr; cr = cairo_create (meter_surface); +if(analog_meter) { + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); + cairo_paint (cr); + + cairo_set_font_size(cr, 12); + + switch(meter_type) { + case SMETER: + { + double level=value+(double)get_attenuation(); + offset=210.0; + + int i; + double x; + double y; + double angle; + double radians; + double cx=(double)meter_width/2.0; + double cy=(double)meter_width/2.0; + double radius=cy-20.0; + + cairo_set_line_width(cr, 1.0); + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); + cairo_arc(cr, cx, cy, radius, 216.0*M_PI/180.0, 324.0*M_PI/180.0); + cairo_stroke(cr); + + cairo_set_line_width(cr, 2.0); + cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); + cairo_arc(cr, cx, cy, radius+2, 264.0*M_PI/180.0, 324.0*M_PI/180.0); + cairo_stroke(cr); + + cairo_set_line_width(cr, 1.0); + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); + + for(i=1;i<10;i++) { + angle=((double)i*6.0)+offset; + radians=angle*M_PI/180.0; + + if((i%2)==1) { + cairo_arc(cr, cx, cy, radius+4, radians, radians); + cairo_get_current_point(cr, &x, &y); + cairo_arc(cr, cx, cy, radius, radians, radians); + cairo_line_to(cr, x, y); + cairo_stroke(cr); + + sprintf(sf,"%d",i); + cairo_arc(cr, cx, cy, radius+5, radians, radians); + cairo_get_current_point(cr, &x, &y); + cairo_new_path(cr); + x-=4.0; + cairo_move_to(cr, x, y); + cairo_show_text(cr, sf); + } else { + cairo_arc(cr, cx, cy, radius+2, radians, radians); + cairo_get_current_point(cr, &x, &y); + cairo_arc(cr, cx, cy, radius, radians, radians); + cairo_line_to(cr, x, y); + cairo_stroke(cr); + } + cairo_new_path(cr); + } + + for(i=20;i<=60;i+=20) { + angle=((double)i+54.0)+offset; + radians=angle*M_PI/180.0; + cairo_arc(cr, cx, cy, radius+4, radians, radians); + cairo_get_current_point(cr, &x, &y); + cairo_arc(cr, cx, cy, radius, radians, radians); + cairo_line_to(cr, x, y); + cairo_stroke(cr); + + sprintf(sf,"+%d",i); + cairo_arc(cr, cx, cy, radius+5, radians, radians); + cairo_get_current_point(cr, &x, &y); + cairo_new_path(cr); + x-=4.0; + cairo_move_to(cr, x, y); + cairo_show_text(cr, sf); + cairo_new_path(cr); + } + + + + cairo_set_line_width(cr, 1.0); + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); + + angle=level+127.0+offset; + radians=angle*M_PI/180.0; + cairo_arc(cr, cx, cy, radius+8, radians, radians); + cairo_line_to(cr, cx, cy); + cairo_stroke(cr); + + cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); + sprintf(sf,"%d dBm",(int)level); + cairo_move_to(cr, 80, meter_height-2); + cairo_show_text(cr, sf); + +#ifdef FREEDV + if(active_receiver->freedv) { + if(freedv_sync) { + cairo_set_source_rgb(cr, 0.0, 1.0, 0.0); + } else { + cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); + } + sprintf(sf,"SNR: %3.2f",freedv_snr); + cairo_move_to(cr, 70, meter_height-12); + cairo_show_text(cr, sf); + } +#endif + + + } + break; + case POWER: + { + double level=value; + offset=220.0; + + int i; + double x; + double y; + double angle; + double radians; + double cx=(double)meter_width/2.0; + double cy=(double)meter_width/2.0; + double radius=cy-20.0; + + cairo_set_line_width(cr, 1.0); + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); + cairo_arc(cr, cx, cy, radius, 220.0*M_PI/180.0, 320.0*M_PI/180.0); + cairo_stroke(cr); + + cairo_set_line_width(cr, 1.0); + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); + + for(i=0;i<=100;i++) { + angle=(double)i+offset; + radians=angle*M_PI/180.0; + + switch(i) { + //case 5: + case 0: + case 25: + case 50: + case 75: + case 100: + cairo_arc(cr, cx, cy, radius+4, radians, radians); + cairo_get_current_point(cr, &x, &y); + cairo_arc(cr, cx, cy, radius, radians, radians); + cairo_line_to(cr, x, y); + cairo_stroke(cr); + + sprintf(sf,"%d",i*2); + cairo_arc(cr, cx, cy, radius+5, radians, radians); + cairo_get_current_point(cr, &x, &y); + cairo_new_path(cr); + x-=6.0; + cairo_move_to(cr, x, y); + cairo_show_text(cr, sf); + break; + default: + if((i%5)==0) { + cairo_arc(cr, cx, cy, radius+2, radians, radians); + cairo_get_current_point(cr, &x, &y); + cairo_arc(cr, cx, cy, radius, radians, radians); + cairo_line_to(cr, x, y); + cairo_stroke(cr); + } + break; + } + cairo_new_path(cr); + } + + cairo_set_line_width(cr, 1.0); + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); + + if((int)value>max_level || max_count==10) { + max_level=(int)value; + max_count=0; + } + max_count++; + + angle=(max_level/2.0)+offset; + radians=angle*M_PI/180.0; + cairo_arc(cr, cx, cy, radius+8, radians, radians); + cairo_line_to(cr, cx, cy); + cairo_stroke(cr); + + + cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); + sprintf(sf,"%d W",(int)max_level); + cairo_move_to(cr, 80, meter_height-22); + cairo_show_text(cr, sf); + + double swr=(max_level+reverse)/(max_level-reverse); + if(swr<0.0) swr=1.0; + sprintf(sf,"SWR: %1.1f:1",swr); + cairo_move_to(cr, 60, meter_height-12); + cairo_show_text(cr, sf); + + sprintf(sf,"ALC: %2.1f dB",alc); + cairo_move_to(cr, 60, meter_height-2); + cairo_show_text(cr, sf); + + + } + break; + } + + if((meter_type==POWER) || (vox_enabled)) { + offset=((double)meter_width-100.0)/2.0; + double peak=vox_get_peak(); + peak=peak*100.0; + cairo_set_source_rgb(cr, 0.0, 1.0, 0.0); + cairo_rectangle(cr, offset, 0.0, peak, 5.0); + cairo_fill(cr); + + cairo_select_font_face(cr, "FreeMono", + CAIRO_FONT_SLANT_NORMAL, + CAIRO_FONT_WEIGHT_BOLD); + cairo_set_font_size(cr, 10); + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); + cairo_move_to(cr, 0.0, 8.0); + cairo_show_text(cr, "Mic Lvl"); + + + cairo_move_to(cr, offset, 0.0); + cairo_line_to(cr, offset, 5.0); + cairo_stroke(cr); + cairo_move_to(cr, offset+50.0, 0.0); + cairo_line_to(cr, offset+50.0, 5.0); + cairo_stroke(cr); + cairo_move_to(cr, offset+100.0, 0.0); + cairo_line_to(cr, offset+100.0, 5.0); + cairo_stroke(cr); + cairo_move_to(cr, offset, 5.0); + cairo_line_to(cr, offset+100.0, 5.0); + cairo_stroke(cr); + + if(vox_enabled) { + cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); + cairo_move_to(cr,offset+(vox_threshold*100.0),0.0); + cairo_line_to(cr,offset+(vox_threshold*100.0),5.0); + cairo_stroke(cr); + } + } + +} else { // clear the meter - cairo_set_source_rgb (cr, 0, 0, 0); + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); cairo_paint (cr); - //sprintf(text,"Version: %s %s", build_date, version); - sprintf(text,"Version: %s", version); cairo_select_font_face(cr, "FreeMono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - - cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); cairo_set_font_size(cr, 12); - cairo_move_to(cr, 5, 15); - cairo_show_text(cr, text); + cairo_set_line_width(cr, 1.0); + + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); + cairo_move_to(cr, 5.0, 15.0); + cairo_line_to(cr, 5.0, 5.0); + cairo_move_to(cr, 5.0+25.0, 15.0); + cairo_line_to(cr, 5.0+25.0, 10.0); + cairo_move_to(cr, 5.0+50.0, 15.0); + cairo_line_to(cr, 5.0+50.0, 5.0); + cairo_move_to(cr, 5.0+75.0, 15.0); + cairo_line_to(cr, 5.0+75.0, 10.0); + cairo_move_to(cr, 5.0+100.0, 15.0); + cairo_line_to(cr, 5.0+100.0, 5.0); + cairo_stroke(cr); + + double peak=vox_get_peak(); + peak=peak*100.0; + cairo_set_source_rgb(cr, 0.0, 1.0, 0.0); + cairo_rectangle(cr, 5.0, 5.0, peak, 5.0); + cairo_fill(cr); + + if(vox_enabled) { + cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); + cairo_move_to(cr,5.0+(vox_threshold*100.0),5.0); + cairo_line_to(cr,5.0+(vox_threshold*100.0),15.0); + cairo_stroke(cr); + } + + cairo_set_source_rgb(cr, 1.0, 1.0, 0.0); + cairo_move_to(cr, 115.0, 15.0); + cairo_show_text(cr, "Mic Level"); if(last_meter_type!=meter_type) { last_meter_type=meter_type; @@ -243,7 +521,7 @@ void meter_update(int meter_type,double value,double reverse,double exciter,doub } } - cairo_set_source_rgb(cr, 1, 1, 1); + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); switch(meter_type) { case SMETER: // value is dBm @@ -256,7 +534,7 @@ void meter_update(int meter_type,double value,double reverse,double exciter,doub int db=1; int i; cairo_set_line_width(cr, 1.0); - cairo_set_source_rgb(cr, 1, 1, 1); + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); for(i=0;i<54;i++) { cairo_move_to(cr,offset+(double)(i*db),(double)meter_height-10); if(i%18==0) { @@ -267,13 +545,13 @@ void meter_update(int meter_type,double value,double reverse,double exciter,doub } cairo_stroke(cr); - cairo_set_font_size(cr, 12); - cairo_move_to(cr, offset+(double)(18*db)-3.0, (double)meter_height); + cairo_set_font_size(cr, 10); + cairo_move_to(cr, offset+(double)(18*db)-3.0, (double)meter_height-1); cairo_show_text(cr, "3"); - cairo_move_to(cr, offset+(double)(36*db)-3.0, (double)meter_height); + cairo_move_to(cr, offset+(double)(36*db)-3.0, (double)meter_height-1); cairo_show_text(cr, "6"); - cairo_set_source_rgb(cr, 1, 0, 0); + cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); cairo_move_to(cr,offset+(double)(54*db),(double)meter_height-10); cairo_line_to(cr,offset+(double)(54*db),(double)(meter_height-20)); cairo_move_to(cr,offset+(double)(74*db),(double)meter_height-10); @@ -284,16 +562,16 @@ void meter_update(int meter_type,double value,double reverse,double exciter,doub cairo_line_to(cr,offset+(double)(114*db),(double)(meter_height-20)); cairo_stroke(cr); - cairo_move_to(cr, offset+(double)(54*db)-3.0, (double)meter_height); + cairo_move_to(cr, offset+(double)(54*db)-3.0, (double)meter_height-1); cairo_show_text(cr, "9"); - cairo_move_to(cr, offset+(double)(74*db)-12.0, (double)meter_height); + cairo_move_to(cr, offset+(double)(74*db)-12.0, (double)meter_height-1); cairo_show_text(cr, "+20"); - cairo_move_to(cr, offset+(double)(94*db)-9.0, (double)meter_height); + cairo_move_to(cr, offset+(double)(94*db)-9.0, (double)meter_height-1); cairo_show_text(cr, "+40"); - cairo_move_to(cr, offset+(double)(114*db)-6.0, (double)meter_height); + cairo_move_to(cr, offset+(double)(114*db)-6.0, (double)meter_height-1); cairo_show_text(cr, "+60"); - cairo_set_source_rgb(cr, 0, 1, 0); + cairo_set_source_rgb(cr, 0.0, 1.0, 0.0); cairo_rectangle(cr, offset+0.0, (double)(meter_height-40), (double)((level+127.0)*db), 20.0); cairo_fill(cr); @@ -303,7 +581,7 @@ void meter_update(int meter_type,double value,double reverse,double exciter,doub } if(max_level!=0) { - cairo_set_source_rgb(cr, 1, 1, 0); + cairo_set_source_rgb(cr, 1.0, 1.0, 0.0); cairo_move_to(cr,offset+(double)((max_level+127.0)*db),(double)meter_height-20); cairo_line_to(cr,offset+(double)((max_level+127.0)*db),(double)(meter_height-40)); } @@ -323,15 +601,15 @@ void meter_update(int meter_type,double value,double reverse,double exciter,doub cairo_show_text(cr, sf); #ifdef FREEDV - if(active_receiver->mode==modeFREEDV) { + if(active_receiver->freedv) { if(freedv_sync) { - cairo_set_source_rgb(cr, 0, 1, 0); + cairo_set_source_rgb(cr, 0.0, 1.0, 0.0); } else { - cairo_set_source_rgb(cr, 1, 0, 0); + cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); } cairo_set_font_size(cr, 12); sprintf(sf,"SNR: %3.2f",freedv_snr); - cairo_move_to(cr, text_location, 30); + cairo_move_to(cr, text_location, meter_height-10); cairo_show_text(cr, sf); } #endif @@ -342,7 +620,7 @@ void meter_update(int meter_type,double value,double reverse,double exciter,doub int i; offset=5.0; cairo_set_line_width(cr, 1.0); - cairo_set_source_rgb(cr, 1, 1, 1); + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); for(i=0;i<11;i++) { cairo_move_to(cr,offset+(double)(i*20),(double)meter_height-10); if((i%2)==0) { @@ -356,11 +634,11 @@ void meter_update(int meter_type,double value,double reverse,double exciter,doub } cairo_stroke(cr); - cairo_set_source_rgb(cr, 0, 1, 0); + cairo_set_source_rgb(cr, 0.0, 1.0, 0.0); cairo_rectangle(cr, offset+0.0, (double)(meter_height-40), value*2, 20.0); cairo_fill(cr); - cairo_set_source_rgb(cr, 0, 1, 0); + cairo_set_source_rgb(cr, 0.0, 1.0, 0.0); cairo_set_font_size(cr, 12); sprintf(sf,"Level: %d",(int)value); cairo_move_to(cr, 210, 45); @@ -406,6 +684,7 @@ void meter_update(int meter_type,double value,double reverse,double exciter,doub break; } +} cairo_destroy(cr); gtk_widget_queue_draw (meter); } diff --git a/meter.h b/meter.h index 868dc6c..aa98deb 100644 --- a/meter.h +++ b/meter.h @@ -29,7 +29,7 @@ #endif -GtkWidget* meter_init(int width,int height,GtkWidget *parent); -void meter_update(int meter_type,double value,double reverse,double exciter,double alc); +extern GtkWidget* meter_init(int width,int height,GtkWidget *parent); +extern void meter_update(int meter_type,double value,double reverse,double exciter,double alc); #endif diff --git a/meter_menu.c b/meter_menu.c index e43361d..e962a97 100644 --- a/meter_menu.c +++ b/meter_menu.c @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -32,29 +33,45 @@ static GtkWidget *parent_window=NULL; static GtkWidget *dialog=NULL; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static void smeter_select_cb (GtkWidget *widget, gpointer data) { - smeter=(int)data; + smeter=(uintptr_t)data; } static void alc_meter_select_cb (GtkWidget *widget, gpointer data) { - alc=(int)data; + alc=(uintptr_t)data; +} + +static void analog_cb(GtkWidget *widget, gpointer data) { + analog_meter=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); } + void meter_menu (GtkWidget *parent) { parent_window=parent; dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - Meter"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -73,35 +90,40 @@ void meter_menu (GtkWidget *parent) { g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); + GtkWidget *analog_b=gtk_check_button_new_with_label("Analog Meter"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (analog_b), analog_meter); + gtk_grid_attach(GTK_GRID(grid),analog_b,1,0,1,1); + g_signal_connect(analog_b,"toggled",G_CALLBACK(analog_cb),NULL); + GtkWidget *smeter_peak=gtk_radio_button_new_with_label(NULL,"S Meter Peak"); 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); + g_signal_connect(smeter_peak,"pressed",G_CALLBACK(smeter_select_cb),(gpointer)(long)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), 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); + g_signal_connect(smeter_average,"pressed",G_CALLBACK(smeter_select_cb),(gpointer)(long)RXA_S_AV); GtkWidget *alc_peak=gtk_radio_button_new_with_label(NULL,"ALC Peak"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (alc_peak), alc==TXA_ALC_PK); gtk_widget_show(alc_peak); gtk_grid_attach(GTK_GRID(grid),alc_peak,1,1,1,1); - g_signal_connect(alc_peak,"pressed",G_CALLBACK(alc_meter_select_cb),(gpointer *)TXA_ALC_PK); + g_signal_connect(alc_peak,"pressed",G_CALLBACK(alc_meter_select_cb),(gpointer)(long)TXA_ALC_PK); GtkWidget *alc_average=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(alc_peak),"ALC Average"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (alc_average), alc==TXA_ALC_AV); gtk_widget_show(alc_average); gtk_grid_attach(GTK_GRID(grid),alc_average,1,2,1,1); - g_signal_connect(alc_average,"pressed",G_CALLBACK(alc_meter_select_cb),(gpointer *)TXA_ALC_AV); + g_signal_connect(alc_average,"pressed",G_CALLBACK(alc_meter_select_cb),(gpointer)(long)TXA_ALC_AV); GtkWidget *alc_gain=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(alc_average),"ALC Gain"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (alc_gain), alc==TXA_ALC_GAIN); gtk_widget_show(alc_gain); gtk_grid_attach(GTK_GRID(grid),alc_gain,1,3,1,1); - g_signal_connect(alc_gain,"pressed",G_CALLBACK(alc_meter_select_cb),(gpointer *)TXA_ALC_GAIN); + g_signal_connect(alc_gain,"pressed",G_CALLBACK(alc_meter_select_cb),(gpointer)(long)TXA_ALC_GAIN); gtk_container_add(GTK_CONTAINER(content),grid); diff --git a/mode.c b/mode.c index 37bd12b..349d7ca 100644 --- a/mode.c +++ b/mode.c @@ -30,12 +30,8 @@ char *mode_string[]={ ,"DIGL" ,"SAM" ,"DRM" -#ifdef FREEDV - ,"FREEDV" -#endif #ifdef PSK ,"PSK" #endif }; -//int mode; diff --git a/mode.h b/mode.h index ec68810..22ca810 100644 --- a/mode.h +++ b/mode.h @@ -32,25 +32,13 @@ #define modeDIGL 9 #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 char *mode_string[MODES]; -//extern int mode; #endif diff --git a/mode_menu.c b/mode_menu.c index de525c6..b2c02bb 100644 --- a/mode_menu.c +++ b/mode_menu.c @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include "new_menu.h" @@ -38,17 +40,26 @@ static GtkWidget *dialog=NULL; static GtkWidget *last_mode; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static gboolean mode_select_cb (GtkWidget *widget, gpointer data) { - int m=(int)data; + int m=(uintptr_t)data; set_button_text_color(last_mode,"black"); last_mode=widget; set_button_text_color(last_mode,"orange"); @@ -64,7 +75,11 @@ void mode_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + char title[64]; + sprintf(title,"piHPSDR - Mode (RX %d VFO %s)",active_receiver->id,active_receiver->id==0?"A":"B"); + gtk_window_set_title(GTK_WINDOW(dialog),title); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -82,15 +97,10 @@ void mode_menu(GtkWidget *parent) { gtk_grid_set_column_spacing (GTK_GRID(grid),5); gtk_grid_set_row_spacing (GTK_GRID(grid),5); - GtkWidget *close_b=gtk_button_new_with_label("Close Mode"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); - char label[32]; - sprintf(label,"RX %d VFO %s",active_receiver->id,active_receiver->id==0?"A":"B"); - GtkWidget *rx_label=gtk_label_new(label); - gtk_grid_attach(GTK_GRID(grid),rx_label,1,0,1,1); - int mode=vfo[active_receiver->id].mode; for(i=0;i #include #include -#include #include #include @@ -49,9 +48,7 @@ static struct sockaddr_in discovery_addr; void new_discover(struct ifaddrs* iface); -//static pthread_t discover_thread_id; static GThread *discover_thread_id; -//void* new_discover_receive_thread(void* arg); gpointer new_discover_receive_thread(gpointer data); void print_device(int i) { @@ -115,6 +112,7 @@ void new_discover(struct ifaddrs* iface) { int optval = 1; setsockopt(discovery_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); + setsockopt(discovery_socket, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)); sa = (struct sockaddr_in *) iface->ifa_addr; mask = (struct sockaddr_in *) iface->ifa_netmask; @@ -150,13 +148,6 @@ void new_discover(struct ifaddrs* iface) { to_addr.sin_addr.s_addr=htonl(INADDR_BROADCAST); // start a receive thread to collect discovery response packets -/* - rc=pthread_create(&discover_thread_id,NULL,new_discover_receive_thread,NULL); - if(rc != 0) { - fprintf(stderr,"pthread_create failed on new_discover_receive_thread: rc=%d\n", rc); - exit(-1); - } -*/ discover_thread_id = g_thread_new( "new discover receive", new_discover_receive_thread, NULL); if( ! discover_thread_id ) { @@ -184,10 +175,6 @@ void new_discover(struct ifaddrs* iface) { } // wait for receive thread to complete -/* - void* status; - pthread_join(discover_thread_id,&status); -*/ g_thread_join(discover_thread_id); close(discovery_socket); @@ -287,6 +274,5 @@ gpointer new_discover_receive_thread(gpointer data) { } } fprintf(stderr,"new_discover: exiting new_discover_receive_thread\n"); - //pthread_exit(NULL); g_thread_exit(NULL); } diff --git a/new_menu.c b/new_menu.c index f45d20c..7365ae3 100644 --- a/new_menu.c +++ b/new_menu.c @@ -24,6 +24,7 @@ #include "audio.h" #include "new_menu.h" +#include "about_menu.h" #include "exit_menu.h" #include "radio_menu.h" #include "rx_menu.h" @@ -31,7 +32,10 @@ #include "display_menu.h" #include "dsp_menu.h" #include "pa_menu.h" +#include "rigctl_menu.h" #include "oc_menu.h" +#include "cw_menu.h" +#include "store_menu.h" #ifdef FREEDV #include "freedv_menu.h" #endif @@ -51,9 +55,8 @@ #include "diversity_menu.h" #include "freqent_menu.h" #include "tx_menu.h" -#ifdef GPIO +#include "ps_menu.h" #include "encoder_menu.h" -#endif #include "vfo_menu.h" #include "fft_menu.h" #include "main.h" @@ -67,7 +70,15 @@ GtkWidget *sub_menu=NULL; int active_menu=NO_MENU; -static cleanup() { +int menu_active_receiver_changed(void *data) { + if(sub_menu!=NULL) { + gtk_widget_destroy(sub_menu); + sub_menu=NULL; + } + return FALSE; +} + +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; @@ -79,11 +90,21 @@ static cleanup() { active_menu=NO_MENU; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { cleanup(); return TRUE; } +static gboolean about_b_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); + about_menu(top_window); + return TRUE; +} static gboolean exit_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { cleanup(); @@ -127,6 +148,13 @@ static gboolean pa_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) return TRUE; } +static gboolean rigctl_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); + fprintf(stderr, "new_menu: calling rigctl_menu\n"); + rigctl_menu(top_window); + return TRUE; +} + static gboolean cw_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { cleanup(); cw_menu(top_window); @@ -333,10 +361,21 @@ static gboolean tx_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) return TRUE; } +#ifdef PURESIGNAL +void start_ps() { + cleanup(); + ps_menu(top_window); +} + +static gboolean ps_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + start_ps(); + return TRUE; +} +#endif + #ifdef GPIO void start_encoder(int encoder) { int old_menu=active_menu; -fprintf(stderr,"start_encoder: encoder=%d active_menu=%d\n",encoder,active_menu); cleanup(); switch(encoder) { case 1: @@ -390,7 +429,9 @@ void new_menu() dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(top_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - Menu"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -407,7 +448,7 @@ void new_menu() gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); - GtkWidget *close_b=gtk_button_new_with_label("Close Menu"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "button-press-event", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,2,1); @@ -432,6 +473,13 @@ void new_menu() gtk_grid_attach(GTK_GRID(grid),tx_b,(i%5),i/5,1,1); i++; +#ifdef PURESIGNAL + GtkWidget *ps_b=gtk_button_new_with_label("PS"); + g_signal_connect (ps_b, "button-press-event", G_CALLBACK(ps_cb), NULL); + gtk_grid_attach(GTK_GRID(grid),ps_b,(i%5),i/5,1,1); + i++; +#endif + GtkWidget *pa_b=gtk_button_new_with_label("PA"); g_signal_connect (pa_b, "button-press-event", G_CALLBACK(pa_cb), NULL); gtk_grid_attach(GTK_GRID(grid),pa_b,(i%5),i/5,1,1); @@ -499,6 +547,16 @@ void new_menu() gtk_grid_attach(GTK_GRID(grid),fft_b,(i%5),i/5,1,1); i++; + GtkWidget *rigctl_b=gtk_button_new_with_label("RIGCTL"); + g_signal_connect (rigctl_b, "button-press-event", G_CALLBACK(rigctl_cb), NULL); + gtk_grid_attach(GTK_GRID(grid),rigctl_b,(i%5),i/5,1,1); + i++; + + GtkWidget *about_b=gtk_button_new_with_label("About"); + g_signal_connect (about_b, "button-press-event", G_CALLBACK(about_b_cb), NULL); + gtk_grid_attach(GTK_GRID(grid),about_b,(i%5),i/5,1,1); + i++; + #ifdef DIVERSITY if(RECEIVERS==2) { GtkWidget *diversity_b=gtk_button_new_with_label("Diversity"); diff --git a/new_menu.h b/new_menu.h index ea22179..a32faed 100644 --- a/new_menu.h +++ b/new_menu.h @@ -13,9 +13,14 @@ extern void start_mode(); extern void start_filter(); extern void start_noise(); extern void start_encoder(); +extern void start_vfo(); +extern void start_agc(); +extern void start_store(); extern void encoder_step(int encoder,int step); +extern int menu_active_receiver_changed(void *data); + enum { NO_MENU = 0, E1_MENU, diff --git a/new_protocol.c b/new_protocol.c index bfda677..e573ae0 100644 --- a/new_protocol.c +++ b/new_protocol.c @@ -22,10 +22,12 @@ #include +#include #include #include #include #include +#include #include #include #include @@ -61,12 +63,13 @@ #include "iambic.h" #endif #include "vox.h" +#include "ext.h" #define min(x,y) (xddc; + rc=sem_init(&iq_sem_ready[ddc], 0, 0); + rc=sem_init(&iq_sem_buffer[ddc], 0, 0); + iq_thread_id[ddc] = g_thread_new( "iq thread", iq_thread, (gpointer)(long)i); + if( ! iq_thread_id ) { + fprintf(stderr,"g_thread_new failed for iq_thread: rx=%d\n",i); + exit( -1 ); + } + fprintf(stderr, "iq_thread: rx=%d ddc=%d thread=%p\n",i, ddc, iq_thread_id); + } + +#ifdef PURESIGNAL + // for PS the two feedback streams are synced on the one DDC + if(device!=NEW_DEVICE_HERMES) { + ddc=receiver[PS_TX_FEEDBACK]->ddc; + rc=sem_init(&iq_sem_ready[ddc], 0, 0); + rc=sem_init(&iq_sem_buffer[ddc], 0, 0); + iq_thread_id[ddc] = g_thread_new( "ps iq thread", ps_iq_thread, (gpointer)(long)PS_TX_FEEDBACK); + if( ! iq_thread_id ) { + fprintf(stderr,"g_thread_new failed for ps_iq_thread: rx=%d\n",PS_TX_FEEDBACK); + exit( -1 ); + } + fprintf(stderr, "iq_thread: id=%p\n",iq_thread_id); + } +#endif + +data_socket=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP); + if(data_socket<0) { + fprintf(stderr,"metis: create socket failed for data_socket\n"); + exit(-1); + } + + int optval = 1; + setsockopt(data_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); + setsockopt(data_socket, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)); + + // bind to the interface + if(bind(data_socket,(struct sockaddr*)&radio->info.network.interface_address,radio->info.network.interface_length)<0) { + fprintf(stderr,"metis: bind socket failed for data_socket\n"); + exit(-1); + } + +fprintf(stderr,"new_protocol_thread: date_socket %d bound to interface\n",data_socket); + + memcpy(&base_addr,&radio->info.network.address,radio->info.network.address_length); + base_addr_length=radio->info.network.address_length; + base_addr.sin_port=htons(GENERAL_REGISTERS_FROM_HOST_PORT); + + memcpy(&receiver_addr,&radio->info.network.address,radio->info.network.address_length); + receiver_addr_length=radio->info.network.address_length; + receiver_addr.sin_port=htons(RECEIVER_SPECIFIC_REGISTERS_FROM_HOST_PORT); + + memcpy(&transmitter_addr,&radio->info.network.address,radio->info.network.address_length); + transmitter_addr_length=radio->info.network.address_length; + transmitter_addr.sin_port=htons(TRANSMITTER_SPECIFIC_REGISTERS_FROM_HOST_PORT); + + memcpy(&high_priority_addr,&radio->info.network.address,radio->info.network.address_length); + high_priority_addr_length=radio->info.network.address_length; + high_priority_addr.sin_port=htons(HIGH_PRIORITY_FROM_HOST_PORT); + +fprintf(stderr,"new_protocol_thread: high_priority_addr setup for port %d\n",HIGH_PRIORITY_FROM_HOST_PORT); + + memcpy(&audio_addr,&radio->info.network.address,radio->info.network.address_length); + audio_addr_length=radio->info.network.address_length; + audio_addr.sin_port=htons(AUDIO_FROM_HOST_PORT); + + memcpy(&iq_addr,&radio->info.network.address,radio->info.network.address_length); + iq_addr_length=radio->info.network.address_length; + iq_addr.sin_port=htons(TX_IQ_FROM_HOST_PORT); + + + for(i=0;iinfo.network.address,radio->info.network.address_length); + data_addr_length[i]=radio->info.network.address_length; + data_addr[i].sin_port=htons(RX_IQ_TO_HOST_PORT_0+i); + samples[i]=0; + } new_protocol_thread_id = g_thread_new( "new protocol", new_protocol_thread, NULL); if( ! new_protocol_thread_id ) @@ -272,47 +410,50 @@ void new_protocol_init(int pixels) { } fprintf(stderr, "new_protocol_thread: id=%p\n",new_protocol_thread_id); - } static void new_protocol_general() { - unsigned char buffer[60]; - BAND *band=band_get_current_band(); + BAND *band; - memset(buffer, 0, sizeof(buffer)); + if(split) { + band=band_get_band(vfo[VFO_B].band); + } else { + band=band_get_band(vfo[VFO_A].band); + } + memset(general_buffer, 0, sizeof(general_buffer)); - buffer[0]=general_sequence>>24; - buffer[1]=general_sequence>>16; - buffer[2]=general_sequence>>8; - buffer[3]=general_sequence; + general_buffer[0]=general_sequence>>24; + general_buffer[1]=general_sequence>>16; + general_buffer[2]=general_sequence>>8; + general_buffer[3]=general_sequence; // use defaults apart from - buffer[37]=0x08; // phase word (not frequency) - buffer[38]=0x01; // enable hardware timer + general_buffer[37]=0x08; // phase word (not frequency) + general_buffer[38]=0x01; // enable hardware timer - - if(band->disablePA) { - buffer[58]=0x00; + general_buffer[58]=0x00; } else { - buffer[58]=0x01; // enable PA + general_buffer[58]=0x01; // enable PA } +fprintf(stderr,"new_protocol_general: PA Enable=%02X\n",general_buffer[58]); + if(filter_board==APOLLO) { - buffer[58]|=0x02; // enable APOLLO tuner + general_buffer[58]|=0x02; // enable APOLLO tuner } if(filter_board==ALEX) { if(device==NEW_DEVICE_ORION2) { - buffer[59]=0x03; // enable Alex 0 and 1 + general_buffer[59]=0x03; // enable Alex 0 and 1 } else { - buffer[59]=0x01; // enable Alex 0 + general_buffer[59]=0x01; // enable Alex 0 } } -fprintf(stderr,"Alex Enable=%02X\n",buffer[59]); +fprintf(stderr,"Alex Enable=%02X\n",general_buffer[59]); - if(sendto(data_socket,buffer,sizeof(buffer),0,(struct sockaddr*)&base_addr,base_addr_length)<0) { + if(sendto(data_socket,general_buffer,sizeof(general_buffer),0,(struct sockaddr*)&base_addr,base_addr_length)<0) { fprintf(stderr,"sendto socket failed for general\n"); exit(1); } @@ -320,124 +461,165 @@ fprintf(stderr,"Alex Enable=%02X\n",buffer[59]); general_sequence++; } -static void new_protocol_high_priority(int run) { +static void new_protocol_high_priority() { int i, r; - unsigned char buffer[1444]; BAND *band; + int xvtr; long long rxFrequency; long long txFrequency; long phase; int mode; + int ddc; + + if(data_socket==-1) { + return; + } - memset(buffer, 0, sizeof(buffer)); + memset(high_priority_buffer_to_radio, 0, sizeof(high_priority_buffer_to_radio)); - buffer[0]=high_priority_sequence>>24; - buffer[1]=high_priority_sequence>>16; - buffer[2]=high_priority_sequence>>8; - buffer[3]=high_priority_sequence; + high_priority_buffer_to_radio[0]=high_priority_sequence>>24; + high_priority_buffer_to_radio[1]=high_priority_sequence>>16; + high_priority_buffer_to_radio[2]=high_priority_sequence>>8; + high_priority_buffer_to_radio[3]=high_priority_sequence; if(split) { mode=vfo[1].mode; } else { mode=vfo[0].mode; } - buffer[4]=run; + high_priority_buffer_to_radio[4]=running; if(mode==modeCWU || mode==modeCWL) { if(tune) { - buffer[4]|=0x02; + high_priority_buffer_to_radio[4]|=0x02; } #ifdef LOCALCW if (cw_keyer_internal == 0) { // set the ptt if we're not in breakin mode and mox is on - if(cw_breakin == 0 && getMox()) buffer[4]|=0x02; - buffer[5]|=(keyer_out) ? 0x01 : 0; - //buffer[5]|=(*kdot) ? 0x02 : 0; - //buffer[5]|=(*kdash) ? 0x04 : 0; - buffer[5]|=(key_state==SENDDOT) ? 0x02 : 0; - buffer[5]|=(key_state==SENDDASH) ? 0x04 : 0; + if(cw_breakin == 0 && getMox()) high_priority_buffer_to_radio[4]|=0x02; + high_priority_buffer_to_radio[5]|=(keyer_out) ? 0x01 : 0; + //high_priority_buffer_to_radio[5]|=(*kdot) ? 0x02 : 0; + //high_priority_buffer_to_radio[5]|=(*kdash) ? 0x04 : 0; + high_priority_buffer_to_radio[5]|=(key_state==SENDDOT) ? 0x02 : 0; + high_priority_buffer_to_radio[5]|=(key_state==SENDDASH) ? 0x04 : 0; } #endif } else { if(isTransmitting()) { - buffer[4]|=0x02; + high_priority_buffer_to_radio[4]|=0x02; } } // rx for(r=0;rdds_frequency; + int ddc=receiver[r]->ddc; int v=receiver[r]->id; rxFrequency=vfo[v].frequency-vfo[v].lo; if(vfo[v].rit_enabled) { rxFrequency+=vfo[v].rit; } - if(vfo[v].mode==modeCWU) { - rxFrequency-=cw_keyer_sidetone_frequency; - } else if(vfo[v].mode==modeCWL) { - rxFrequency+=cw_keyer_sidetone_frequency; + +/* + switch(vfo[v].mode) { + case modeCWU: + rxFrequency-=cw_keyer_sidetone_frequency; + break; + case modeCWL: + rxFrequency+=cw_keyer_sidetone_frequency; + break; + default: + break; } +*/ phase=(long)((4294967296.0*(double)rxFrequency)/122880000.0); - - i=r; - //if(device==NEW_DEVICE_ORION2 && r==1) i=3; - buffer[9+(i*4)]=phase>>24; - buffer[10+(i*4)]=phase>>16; - buffer[11+(i*4)]=phase>>8; - buffer[12+(i*4)]=phase; + high_priority_buffer_to_radio[9+(ddc*4)]=phase>>24; + high_priority_buffer_to_radio[10+(ddc*4)]=phase>>16; + high_priority_buffer_to_radio[11+(ddc*4)]=phase>>8; + high_priority_buffer_to_radio[12+(ddc*4)]=phase; } // tx - band=band_get_band(vfo[VFO_A].band); - rxFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo; - txFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo; - if(split) { - band=band_get_band(vfo[VFO_B].band); + if(active_receiver->id==VFO_A) { + txFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo; + if(split) { + txFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo; + } + } else { txFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo; + if(split) { + txFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo; + } } + switch(vfo[active_receiver->id].mode) { + case modeCWU: + txFrequency+=cw_keyer_sidetone_frequency; + break; + case modeCWL: + txFrequency-=cw_keyer_sidetone_frequency; + break; + default: + break; + } + phase=(long)((4294967296.0*(double)txFrequency)/122880000.0); - buffer[329]=phase>>24; - buffer[330]=phase>>16; - buffer[331]=phase>>8; - buffer[332]=phase; +#ifdef PURESIGNAL + if(isTransmitting() && transmitter->puresignal) { + // set puresignal rx to transmit frequency + high_priority_buffer_to_radio[9]=phase>>24; + high_priority_buffer_to_radio[10]=phase>>16; + high_priority_buffer_to_radio[11]=phase>>8; + high_priority_buffer_to_radio[12]=phase; + + high_priority_buffer_to_radio[13]=phase>>24; + high_priority_buffer_to_radio[14]=phase>>16; + high_priority_buffer_to_radio[15]=phase>>8; + high_priority_buffer_to_radio[16]=phase; + } +#endif + + high_priority_buffer_to_radio[329]=phase>>24; + high_priority_buffer_to_radio[330]=phase>>16; + high_priority_buffer_to_radio[331]=phase>>8; + high_priority_buffer_to_radio[332]=phase; int power=0; if(isTransmitting()) { - if(tune) { - power=tune_drive_level; + if(tune && !transmitter->tune_use_drive) { + power=(int)((double)transmitter->drive_level/100.0*(double)transmitter->tune_percent); } else { - power=drive_level; + power=transmitter->drive_level; } } - buffer[345]=power&0xFF; + high_priority_buffer_to_radio[345]=power&0xFF; if(isTransmitting()) { if(split) { band=band_get_band(vfo[VFO_B].band); + xvtr=vfo[VFO_B].band>=BANDS; } else { band=band_get_band(vfo[VFO_A].band); + xvtr=vfo[VFO_A].band>=BANDS; } - buffer[1401]=band->OCtx<<1; + high_priority_buffer_to_radio[1401]=band->OCtx<<1; if(tune) { if(OCmemory_tune_time!=0) { struct timeval te; gettimeofday(&te,NULL); long long now=te.tv_sec*1000LL+te.tv_usec/1000; if(tune_timeout>now) { - buffer[1401]|=OCtune<<1; + high_priority_buffer_to_radio[1401]|=OCtune<<1; } } else { - buffer[1401]|=OCtune<<1; + high_priority_buffer_to_radio[1401]|=OCtune<<1; } } } else { band=band_get_band(vfo[VFO_A].band); - buffer[1401]=band->OCrx<<1; + high_priority_buffer_to_radio[1401]=band->OCrx<<1; } if((protocol==ORIGINAL_PROTOCOL && device==DEVICE_METIS) || @@ -446,7 +628,7 @@ static void new_protocol_high_priority(int run) { #endif (protocol==NEW_PROTOCOL && device==NEW_DEVICE_ATLAS)) { for(r=0;rpreamp; + high_priority_buffer_to_radio[1403]|=receiver[i]->preamp; } } @@ -455,40 +637,87 @@ static void new_protocol_high_priority(int run) { if(isTransmitting()) { filters=0x08000000; +#ifdef PURESIGNAL + if(transmitter->puresignal) { + filters|=0x00040000; + } +#endif } - if(rxFrequency<1800000L) { - filters|=ALEX_BYPASS_HPF; - } else if(rxFrequency<6500000L) { - filters|=ALEX_1_5MHZ_HPF; - } else if(rxFrequency<9500000L) { - filters|=ALEX_6_5MHZ_HPF; - } else if(rxFrequency<13000000L) { - filters|=ALEX_9_5MHZ_HPF; - } else if(rxFrequency<20000000L) { - filters|=ALEX_13MHZ_HPF; - } else { - filters|=ALEX_20MHZ_HPF; + rxFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo; + switch(device) { + case NEW_DEVICE_ORION2: + if(rxFrequency<1500000L) { + filters|=ALEX_BYPASS_HPF; + } else if(rxFrequency<2100000L) { + filters|=ALEX_1_5MHZ_HPF; + } else if(rxFrequency<5500000L) { + filters|=ALEX_6_5MHZ_HPF; + } else if(rxFrequency<11000000L) { + filters|=ALEX_9_5MHZ_HPF; + } else if(rxFrequency<22000000L) { + filters|=ALEX_13MHZ_HPF; + } else if(rxFrequency<35000000L) { + filters|=ALEX_20MHZ_HPF; + } else { + filters|=ALEX_6M_PREAMP; + } + break; + default: + if(rxFrequency<1800000L) { + filters|=ALEX_BYPASS_HPF; + } else if(rxFrequency<6500000L) { + filters|=ALEX_1_5MHZ_HPF; + } else if(rxFrequency<9500000L) { + filters|=ALEX_6_5MHZ_HPF; + } else if(rxFrequency<13000000L) { + filters|=ALEX_9_5MHZ_HPF; + } else if(rxFrequency<20000000L) { + filters|=ALEX_13MHZ_HPF; + } else if(rxFrequency<50000000L) { + filters|=ALEX_20MHZ_HPF; + } else { + filters|=ALEX_6M_PREAMP; + } + break; } - if(rxFrequency>30000000L) { - filters|=ALEX_6M_PREAMP; - } + switch(device) { + case NEW_DEVICE_ORION2: + if(txFrequency>32000000) { + filters|=ALEX_6_BYPASS_LPF; + } else if(txFrequency>22000000) { + filters|=ALEX_12_10_LPF; + } else if(txFrequency>15000000) { + filters|=ALEX_17_15_LPF; + } else if(txFrequency>8000000) { + filters|=ALEX_30_20_LPF; + } else if(txFrequency>4500000) { + filters|=ALEX_60_40_LPF; + } else if(txFrequency>2400000) { + filters|=ALEX_80_LPF; + } else { + filters|=ALEX_160_LPF; + } + break; + default: + if(txFrequency>35600000) { + filters|=ALEX_6_BYPASS_LPF; + } else if(txFrequency>24000000) { + filters|=ALEX_12_10_LPF; + } else if(txFrequency>16500000) { + filters|=ALEX_17_15_LPF; + } else if(txFrequency>8000000) { + filters|=ALEX_30_20_LPF; + } else if(txFrequency>5000000) { + filters|=ALEX_60_40_LPF; + } else if(txFrequency>2500000) { + filters|=ALEX_80_LPF; + } else { + filters|=ALEX_160_LPF; + } + break; - if(txFrequency>32000000) { - filters|=ALEX_6_BYPASS_LPF; - } else if(txFrequency>22000000) { - filters|=ALEX_12_10_LPF; - } else if(txFrequency>15000000) { - filters|=ALEX_17_15_LPF; - } else if(txFrequency>8000000) { - filters|=ALEX_30_20_LPF; - } else if(txFrequency>4500000) { - filters|=ALEX_60_40_LPF; - } else if(txFrequency>2400000) { - filters|=ALEX_80_LPF; - } else { - filters|=ALEX_160_LPF; } switch(receiver[0]->alex_antenna) { @@ -505,7 +734,9 @@ static void new_protocol_high_priority(int run) { filters|=ALEX_RX_ANTENNA_EXT1; break; case 5: // XVTR - filters|=ALEX_RX_ANTENNA_XVTR; + if(!xvtr) { + filters|=ALEX_RX_ANTENNA_XVTR; + } break; default: // invalid value - set to 0 @@ -514,22 +745,23 @@ static void new_protocol_high_priority(int run) { } if(isTransmitting()) { - switch(transmitter->alex_antenna) { - case 0: // ANT 1 - filters|=ALEX_TX_ANTENNA_1; - break; - case 1: // ANT 2 - filters|=ALEX_TX_ANTENNA_2; - break; - case 2: // ANT 3 - filters|=ALEX_TX_ANTENNA_3; - break; - default: - // invalid value - set to 0 - filters|=ALEX_TX_ANTENNA_1; - band->alexRxAntenna=0; - break; - + if(!xvtr) { + switch(transmitter->alex_antenna) { + case 0: // ANT 1 + filters|=ALEX_TX_ANTENNA_1; + break; + case 1: // ANT 2 + filters|=ALEX_TX_ANTENNA_2; + break; + case 2: // ANT 3 + filters|=ALEX_TX_ANTENNA_3; + break; + default: + // invalid value - set to 0 + filters|=ALEX_TX_ANTENNA_1; + band->alexRxAntenna=0; + break; + } } } else { switch(receiver[0]->alex_antenna) { @@ -545,142 +777,175 @@ static void new_protocol_high_priority(int run) { case 3: // EXT 1 case 4: // EXT 2 case 5: // XVTR - switch(transmitter->alex_antenna) { - case 0: // ANT 1 - filters|=ALEX_TX_ANTENNA_1; - break; - case 1: // ANT 2 - filters|=ALEX_TX_ANTENNA_2; - break; - case 2: // ANT 3 - filters|=ALEX_TX_ANTENNA_3; - break; + if(!xvtr) { + switch(transmitter->alex_antenna) { + case 0: // ANT 1 + filters|=ALEX_TX_ANTENNA_1; + break; + case 1: // ANT 2 + filters|=ALEX_TX_ANTENNA_2; + break; + case 2: // ANT 3 + filters|=ALEX_TX_ANTENNA_3; + break; + } } break; } } - buffer[1432]=(filters>>24)&0xFF; - buffer[1433]=(filters>>16)&0xFF; - buffer[1434]=(filters>>8)&0xFF; - buffer[1435]=filters&0xFF; -//fprintf(stderr,"HPF: 0: %02X %02X for %lld\n",buffer[1434],buffer[1435],rxFrequency); + high_priority_buffer_to_radio[1432]=(filters>>24)&0xFF; + high_priority_buffer_to_radio[1433]=(filters>>16)&0xFF; + high_priority_buffer_to_radio[1434]=(filters>>8)&0xFF; + high_priority_buffer_to_radio[1435]=filters&0xFF; + +//fprintf(stderr,"filters: txrx0: %02X %02X %02X %02X for rx=%lld tx=%lld\n",high_priority_buffer_to_radio[1432],high_priority_buffer_to_radio[1433],high_priority_buffer_to_radio[1434],high_priority_buffer_to_radio[1435],rxFrequency,txFrequency); filters=0x00000000; rxFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo; - if(rxFrequency<1800000L) { - filters|=ALEX_BYPASS_HPF; - } else if(rxFrequency<6500000L) { - filters|=ALEX_1_5MHZ_HPF; - } else if(rxFrequency<9500000L) { - filters|=ALEX_6_5MHZ_HPF; - } else if(rxFrequency<13000000L) { - filters|=ALEX_9_5MHZ_HPF; - } else if(rxFrequency<20000000L) { - filters|=ALEX_13MHZ_HPF; - } else { - filters|=ALEX_20MHZ_HPF; - } - if(rxFrequency>30000000L) { - filters|=ALEX_6M_PREAMP; + switch(device) { + case NEW_DEVICE_ORION2: + if(rxFrequency<1500000L) { + filters|=ALEX_BYPASS_HPF; + } else if(rxFrequency<2100000L) { + filters|=ALEX_1_5MHZ_HPF; + } else if(rxFrequency<5500000L) { + filters|=ALEX_6_5MHZ_HPF; + } else if(rxFrequency<11000000L) { + filters|=ALEX_9_5MHZ_HPF; + } else if(rxFrequency<22000000L) { + filters|=ALEX_13MHZ_HPF; + } else if(rxFrequency<35000000L) { + filters|=ALEX_20MHZ_HPF; + } else { + filters|=ALEX_6M_PREAMP; + } + break; + default: + if(rxFrequency<1800000L) { + filters|=ALEX_BYPASS_HPF; + } else if(rxFrequency<6500000L) { + filters|=ALEX_1_5MHZ_HPF; + } else if(rxFrequency<9500000L) { + filters|=ALEX_6_5MHZ_HPF; + } else if(rxFrequency<13000000L) { + filters|=ALEX_9_5MHZ_HPF; + } else if(rxFrequency<20000000L) { + filters|=ALEX_13MHZ_HPF; + } else if(rxFrequency<50000000L) { + filters|=ALEX_20MHZ_HPF; + } else { + filters|=ALEX_6M_PREAMP; + } + break; } + //high_priority_buffer_to_radio[1428]=(filters>>24)&0xFF; + //high_priority_buffer_to_radio[1429]=(filters>>16)&0xFF; + high_priority_buffer_to_radio[1430]=(filters>>8)&0xFF; + high_priority_buffer_to_radio[1431]=filters&0xFF; - buffer[1428]=(filters>>24)&0xFF; - buffer[1429]=(filters>>16)&0xFF; - buffer[1430]=(filters>>8)&0xFF; - buffer[1431]=filters&0xFF; +//fprintf(stderr,"filters: rx1: %02X %02X for rx=%lld\n",high_priority_buffer_to_radio[1430],high_priority_buffer_to_radio[1431],rxFrequency); -//fprintf(stderr,"HPF: 1: %02X %02X for %lld\n",buffer[1430],buffer[1431],rxFrequency); -// rx_frequency +//fprintf(stderr,"new_protocol_high_priority: OC=%02X filters=%04X for frequency=%lld\n", high_priority_buffer_to_radio[1401], filters, rxFrequency); -//fprintf(stderr,"new_protocol_high_priority: OC=%02X filters=%04X for frequency=%lld\n", buffer[1401], filters, rxFrequency); - for(r=0;rattenuation; + if(isTransmitting()) { + high_priority_buffer_to_radio[1443]=transmitter->attenuation; + } else { + for(r=0;rattenuation; + } } - if(sendto(data_socket,buffer,sizeof(buffer),0,(struct sockaddr*)&high_priority_addr,high_priority_addr_length)<0) { - fprintf(stderr,"sendto socket failed for high priority\n"); - exit(1); + int rc; + if((rc=sendto(data_socket,high_priority_buffer_to_radio,sizeof(high_priority_buffer_to_radio),0,(struct sockaddr*)&high_priority_addr,high_priority_addr_length))<0) { + fprintf(stderr,"sendto socket failed for high priority: rc=%d errno=%d\n",rc,errno); + abort(); + //exit(1); } high_priority_sequence++; } +static unsigned char last_50=0; + static void new_protocol_transmit_specific() { - unsigned char buffer[60]; int mode; - memset(buffer, 0, sizeof(buffer)); + memset(transmit_specific_buffer, 0, sizeof(transmit_specific_buffer)); - buffer[0]=tx_specific_sequence>>24; - buffer[1]=tx_specific_sequence>>16; - buffer[2]=tx_specific_sequence>>8; - buffer[3]=tx_specific_sequence; + transmit_specific_buffer[0]=tx_specific_sequence>>24; + transmit_specific_buffer[1]=tx_specific_sequence>>16; + transmit_specific_buffer[2]=tx_specific_sequence>>8; + transmit_specific_buffer[3]=tx_specific_sequence; if(split) { mode=vfo[1].mode; } else { mode=vfo[0].mode; } - buffer[4]=1; // 1 DAC - buffer[5]=0; // default no CW + transmit_specific_buffer[4]=1; // 1 DAC + transmit_specific_buffer[5]=0; // default no CW // may be using local pihpsdr OR hpsdr CW if(mode==modeCWU || mode==modeCWL) { - buffer[5]|=0x02; + transmit_specific_buffer[5]|=0x02; } if(cw_keys_reversed) { - buffer[5]|=0x04; + transmit_specific_buffer[5]|=0x04; } if(cw_keyer_mode==KEYER_MODE_A) { - buffer[5]|=0x08; + transmit_specific_buffer[5]|=0x08; } if(cw_keyer_mode==KEYER_MODE_B) { - buffer[5]|=0x28; + transmit_specific_buffer[5]|=0x28; } if(cw_keyer_sidetone_volume!=0) { - buffer[5]|=0x10; + transmit_specific_buffer[5]|=0x10; } if(cw_keyer_spacing) { - buffer[5]|=0x40; + transmit_specific_buffer[5]|=0x40; } if(cw_breakin) { - buffer[5]|=0x80; - } - - buffer[6]=cw_keyer_sidetone_volume; // sidetone off - buffer[7]=cw_keyer_sidetone_frequency>>8; - buffer[8]=cw_keyer_sidetone_frequency; // sidetone frequency - buffer[9]=cw_keyer_speed; // cw keyer speed - buffer[10]=cw_keyer_weight; // cw weight - buffer[11]=cw_keyer_hang_time>>8; - buffer[12]=cw_keyer_hang_time; // cw hang delay - buffer[13]=0; // rf delay - buffer[50]=0; + transmit_specific_buffer[5]|=0x80; + } + + transmit_specific_buffer[6]=cw_keyer_sidetone_volume; // sidetone off + transmit_specific_buffer[7]=cw_keyer_sidetone_frequency>>8; + transmit_specific_buffer[8]=cw_keyer_sidetone_frequency; // sidetone frequency + transmit_specific_buffer[9]=cw_keyer_speed; // cw keyer speed + transmit_specific_buffer[10]=cw_keyer_weight; // cw weight + transmit_specific_buffer[11]=cw_keyer_hang_time>>8; + transmit_specific_buffer[12]=cw_keyer_hang_time; // cw hang delay + transmit_specific_buffer[13]=0; // rf delay + transmit_specific_buffer[50]=0; if(mic_linein) { - buffer[50]|=0x01; + transmit_specific_buffer[50]|=0x01; } if(mic_boost) { - buffer[50]|=0x02; + transmit_specific_buffer[50]|=0x02; } if(mic_ptt_enabled==0) { // set if disabled - buffer[50]|=0x04; + transmit_specific_buffer[50]|=0x04; } if(mic_ptt_tip_bias_ring) { - buffer[50]|=0x08; + transmit_specific_buffer[50]|=0x08; } if(mic_bias_enabled) { - buffer[50]|=0x10; + transmit_specific_buffer[50]|=0x10; + } + + if(last_50!=transmit_specific_buffer[50]) { + last_50=transmit_specific_buffer[50]; +fprintf(stderr,"tx_specific: 50=%02X\n",transmit_specific_buffer[50]); } // 0..31 - buffer[51]=linein_gain; + transmit_specific_buffer[51]=linein_gain; - if(sendto(data_socket,buffer,sizeof(buffer),0,(struct sockaddr*)&transmitter_addr,transmitter_addr_length)<0) { + if(sendto(data_socket,transmit_specific_buffer,sizeof(transmit_specific_buffer),0,(struct sockaddr*)&transmitter_addr,transmitter_addr_length)<0) { fprintf(stderr,"sendto socket failed for tx specific\n"); exit(1); } @@ -690,32 +955,57 @@ static void new_protocol_transmit_specific() { } static void new_protocol_receive_specific() { - unsigned char buffer[1444]; int i; + int ddc; - memset(buffer, 0, sizeof(buffer)); + memset(receive_specific_buffer, 0, sizeof(receive_specific_buffer)); - buffer[0]=rx_specific_sequence>>24; - buffer[1]=rx_specific_sequence>>16; - buffer[2]=rx_specific_sequence>>8; - buffer[3]=rx_specific_sequence; + receive_specific_buffer[0]=rx_specific_sequence>>24; + receive_specific_buffer[1]=rx_specific_sequence>>16; + receive_specific_buffer[2]=rx_specific_sequence>>8; + receive_specific_buffer[3]=rx_specific_sequence; - buffer[4]=2; // 2 ADCs + receive_specific_buffer[4]=2; // 2 ADCs for(i=0;idither<random<adc; - buffer[18+(r*6)]=((receiver[i]->sample_rate/1000)>>8)&0xFF; - buffer[19+(r*6)]=(receiver[i]->sample_rate/1000)&0xFF; - buffer[22+(r*6)]=24; + ddc=receiver[i]->ddc; + receive_specific_buffer[5]|=receiver[i]->dither<random<adc; + receive_specific_buffer[18+(ddc*6)]=((receiver[i]->sample_rate/1000)>>8)&0xFF; + receive_specific_buffer[19+(ddc*6)]=(receiver[i]->sample_rate/1000)&0xFF; + receive_specific_buffer[22+(ddc*6)]=24; } +#ifdef PURESIGNAL + if(transmitter->puresignal && isTransmitting()) { + int ps_rate=192000; + + ddc=receiver[PS_RX_FEEDBACK]->ddc; + receive_specific_buffer[5]|=receiver[PS_RX_FEEDBACK]->dither<random<adc; + receive_specific_buffer[18+(ddc*6)]=((ps_rate/1000)>>8)&0xFF; + receive_specific_buffer[19+(ddc*6)]=(ps_rate/1000)&0xFF; + receive_specific_buffer[22+(ddc*6)]=24; + + ddc=receiver[PS_TX_FEEDBACK]->ddc; + receive_specific_buffer[5]|=receiver[PS_TX_FEEDBACK]->dither<random<adc; + receive_specific_buffer[18+(ddc*6)]=((ps_rate/1000)>>8)&0xFF; + receive_specific_buffer[19+(ddc*6)]=(ps_rate/1000)&0xFF; + receive_specific_buffer[22+(ddc*6)]=24; + receive_specific_buffer[1363]=0x02; // sync DDC1 to DDC0 + + ddc=0; + receive_specific_buffer[7]|=(1<info.network.interface_address,radio->info.network.interface_length)<0) { @@ -781,6 +1075,8 @@ fprintf(stderr,"new_protocol_thread\n"); exit(-1); } +fprintf(stderr,"new_protocol_thread: date_socket %d bound to interface\n"); + memcpy(&base_addr,&radio->info.network.address,radio->info.network.address_length); base_addr_length=radio->info.network.address_length; base_addr.sin_port=htons(GENERAL_REGISTERS_FROM_HOST_PORT); @@ -797,6 +1093,8 @@ fprintf(stderr,"new_protocol_thread\n"); high_priority_addr_length=radio->info.network.address_length; high_priority_addr.sin_port=htons(HIGH_PRIORITY_FROM_HOST_PORT); +fprintf(stderr,"new_protocol_thread: high_priority_addr setup for port %d\n",HIGH_PRIORITY_FROM_HOST_PORT); + memcpy(&audio_addr,&radio->info.network.address,radio->info.network.address_length); audio_addr_length=radio->info.network.address_length; audio_addr.sin_port=htons(AUDIO_FROM_HOST_PORT); @@ -812,25 +1110,26 @@ fprintf(stderr,"new_protocol_thread\n"); data_addr[i].sin_port=htons(RX_IQ_TO_HOST_PORT_0+i); samples[i]=0; } - +*/ audioindex=4; // leave space for sequence audiosequence=0L; + running=1; new_protocol_general(); new_protocol_start(); - new_protocol_high_priority(1); + new_protocol_high_priority(); while(running) { - bytesread=recvfrom(data_socket,buffer,sizeof(buffer),0,(struct sockaddr*)&addr,&length); + + buffer=malloc(NET_BUFFER_SIZE); + bytesread=recvfrom(data_socket,buffer,NET_BUFFER_SIZE,0,(struct sockaddr*)&addr,&length); if(bytesread<0) { fprintf(stderr,"recvfrom socket failed for new_protocol_thread"); - exit(1); + exit(-1); } short sourceport=ntohs(addr.sin_port); -//fprintf(stderr,"received packet length %d from port %d\n",bytesread,sourceport); - switch(sourceport) { case RX_IQ_TO_HOST_PORT_0: case RX_IQ_TO_HOST_PORT_1: @@ -840,49 +1139,103 @@ fprintf(stderr,"new_protocol_thread\n"); case RX_IQ_TO_HOST_PORT_5: case RX_IQ_TO_HOST_PORT_6: case RX_IQ_TO_HOST_PORT_7: - i=sourceport-RX_IQ_TO_HOST_PORT_0; - //if(device==NEW_DEVICE_ORION2 && i==3) { - // i=1; - //} - process_iq_data(receiver[i],buffer); + ddc=sourceport-RX_IQ_TO_HOST_PORT_0; +//fprintf(stderr,"iq packet from port=%d ddc=%d\n",sourceport,ddc); + if(ddc>=MAX_RECEIVERS) { + fprintf(stderr,"unexpected iq data from ddc %d\n",ddc); + } else { + sem_wait(&iq_sem_ready[ddc]); + iq_buffer[ddc]=buffer; + sem_post(&iq_sem_buffer[ddc]); + } break; case COMMAND_RESPONCE_TO_HOST_PORT: - process_command_response(buffer); + sem_wait(&command_response_sem_ready); + command_response_buffer=buffer; + sem_post(&command_response_sem_buffer); + //process_command_response(); break; case HIGH_PRIORITY_TO_HOST_PORT: - process_high_priority(buffer); + sem_wait(&high_priority_sem_ready); + high_priority_buffer=buffer; + sem_post(&high_priority_sem_buffer); + //process_high_priority(); break; case MIC_LINE_TO_HOST_PORT: - if(!transmitter->local_microphone) { - process_mic_data(buffer,bytesread); - } + sem_wait(&mic_line_sem_ready); + mic_line_buffer=buffer; + mic_bytes_read=bytesread; + sem_post(&mic_line_sem_buffer); break; default: +fprintf(stderr,"new_protocol_thread: Unknown port %d\n",sourceport); + free(buffer); break; } + } - if(running) { - sem_wait(&send_high_priority_sem); - if(send_high_priority==1) { - new_protocol_high_priority(1); - send_high_priority=0; - } - sem_post(&send_high_priority_sem); + close(data_socket); +} - sem_wait(&send_general_sem); - if(send_general==1) { - new_protocol_general(); - send_general=0; - } - sem_post(&send_general_sem); - } - +static gpointer command_response_thread(gpointer data) { + while(1) { +fprintf(stderr,"command_response_thread\n"); + sem_post(&command_response_sem_ready); + sem_wait(&command_response_sem_buffer); + process_command_response(); + free(command_response_buffer); + } +} + +static gpointer high_priority_thread(gpointer data) { +fprintf(stderr,"high_priority_thread\n"); + while(1) { + sem_post(&high_priority_sem_ready); + sem_wait(&high_priority_sem_buffer); + process_high_priority(); + free(high_priority_buffer); + } +} + +static gpointer mic_line_thread(gpointer data) { +fprintf(stderr,"mic_line_thread\n"); + while(1) { + sem_post(&mic_line_sem_ready); + sem_wait(&mic_line_sem_buffer); + if(!transmitter->local_microphone) { + process_mic_data(mic_bytes_read); } + free(mic_line_buffer); + } +} - close(data_socket); +static gpointer iq_thread(gpointer data) { + int rx=(uintptr_t)data; + int ddc=receiver[rx]->ddc; +fprintf(stderr,"iq_thread: rx=%d ddc=%d\n",rx,ddc); + while(1) { + sem_post(&iq_sem_ready[ddc]); + sem_wait(&iq_sem_buffer[ddc]); + process_iq_data(receiver[rx]); + free(iq_buffer[ddc]); + } } -static void process_iq_data(RECEIVER *rx,unsigned char *buffer) { +#ifdef PURESIGNAL +static gpointer ps_iq_thread(gpointer data) { + int rx=(uintptr_t)data; + int ddc=receiver[rx]->ddc; +fprintf(stderr,"ps_iq_thread: rx=%d ddc=%d\n",rx,ddc); + while(1) { + sem_post(&iq_sem_ready[ddc]); + sem_wait(&iq_sem_buffer[ddc]); + process_ps_iq_data(receiver[rx]); + free(iq_buffer[ddc]); + } +} +#endif + +static void process_iq_data(RECEIVER *rx) { long sequence; long long timestamp; int bitspersample; @@ -892,8 +1245,18 @@ static void process_iq_data(RECEIVER *rx,unsigned char *buffer) { int rightsample; double leftsampledouble; double rightsampledouble; + unsigned char *buffer; + + buffer=iq_buffer[rx->ddc]; sequence=((buffer[0]&0xFF)<<24)+((buffer[1]&0xFF)<<16)+((buffer[2]&0xFF)<<8)+(buffer[3]&0xFF); + + if(rx->iq_sequence!=sequence) { + //fprintf(stderr,"rx %d sequence error: expected %ld got %ld\n",rx->id,rx->iq_sequence,sequence); + rx->iq_sequence=sequence; + } + rx->iq_sequence++; + timestamp=((long long)(buffer[4]&0xFF)<<56)+((long long)(buffer[5]&0xFF)<<48)+((long long)(buffer[6]&0xFF)<<40)+((long long)(buffer[7]&0xFF)<<32); ((long long)(buffer[8]&0xFF)<<24)+((long long)(buffer[9]&0xFF)<<16)+((long long)(buffer[10]&0xFF)<<8)+(long long)(buffer[11]&0xFF); bitspersample=((buffer[12]&0xFF)<<8)+(buffer[13]&0xFF); @@ -910,16 +1273,110 @@ static void process_iq_data(RECEIVER *rx,unsigned char *buffer) { rightsample |= (int)((((unsigned char)buffer[b++])<<8)&0xFF00); rightsample |= (int)((unsigned char)buffer[b++]&0xFF); - leftsampledouble=(double)leftsample/8388607.0; // for 24 bits - rightsampledouble=(double)rightsample/8388607.0; // for 24 bits + //leftsampledouble=(double)leftsample/8388607.0; // for 24 bits + //rightsampledouble=(double)rightsample/8388607.0; // for 24 bits + leftsampledouble=(double)leftsample/16777215.0; // for 24 bits + rightsampledouble=(double)rightsample/16777215.0; // for 24 bits add_iq_samples(rx, leftsampledouble,rightsampledouble); } } -static void process_command_response(unsigned char *buffer) { - response_sequence=((buffer[0]&0xFF)<<24)+((buffer[1]&0xFF)<<16)+((buffer[2]&0xFF)<<8)+(buffer[3]&0xFF); - response=buffer[4]&0xFF; +#ifdef PURESIGNAL +static void process_ps_iq_data(RECEIVER *rx) { + long sequence; + long long timestamp; + int bitspersample; + int samplesperframe; + int b; + int leftsample0; + int rightsample0; + double leftsampledouble0; + double rightsampledouble0; + int leftsample1; + int rightsample1; + double leftsampledouble1; + double rightsampledouble1; + unsigned char *buffer; + + int min_sample0; + int max_sample0; + int min_sample1; + int max_sample1; + + buffer=iq_buffer[rx->ddc]; + + sequence=((buffer[0]&0xFF)<<24)+((buffer[1]&0xFF)<<16)+((buffer[2]&0xFF)<<8)+(buffer[3]&0xFF); + + if(rx->iq_sequence!=sequence) { + //fprintf(stderr,"rx %d sequence error: expected %ld got %ld\n",rx->id,rx->iq_sequence,sequence); + rx->iq_sequence=sequence; + } + rx->iq_sequence++; + + timestamp=((long long)(buffer[4]&0xFF)<<56)+((long long)(buffer[5]&0xFF)<<48)+((long long)(buffer[6]&0xFF)<<40)+((long long)(buffer[7]&0xFF)<<32); + ((long long)(buffer[8]&0xFF)<<24)+((long long)(buffer[9]&0xFF)<<16)+((long long)(buffer[10]&0xFF)<<8)+(long long)(buffer[11]&0xFF); + bitspersample=((buffer[12]&0xFF)<<8)+(buffer[13]&0xFF); + samplesperframe=((buffer[14]&0xFF)<<8)+(buffer[15]&0xFF); + +//fprintf(stderr,"process_ps_iq_data: rx=%d seq=%ld bitspersample=%d samplesperframe=%d\n",rx->id, sequence,bitspersample,samplesperframe); + b=16; + int i; + for(i=0;imax_sample0) { + max_sample0=leftsample0; + } + if(leftsample1max_sample1) { + max_sample1=leftsample1; + } + } +*/ + } +//fprintf(stderr,"0 - min=%d max=%d 1 - min=%d max=%d\n",min_sample0,max_sample0,min_sample1,max_sample1); + +} +#endif + + +static void process_command_response() { + response_sequence=((command_response_buffer[0]&0xFF)<<24)+((command_response_buffer[1]&0xFF)<<16)+((command_response_buffer[2]&0xFF)<<8)+(command_response_buffer[3]&0xFF); + response=command_response_buffer[4]&0xFF; fprintf(stderr,"response_sequence=%ld response=%d\n",response_sequence,response); sem_post(&response_sem); } @@ -930,16 +1387,19 @@ static void process_high_priority(unsigned char *buffer) { int previous_dot; int previous_dash; - sequence=((buffer[0]&0xFF)<<24)+((buffer[1]&0xFF)<<16)+((buffer[2]&0xFF)<<8)+(buffer[3]&0xFF); + int id=active_receiver->id; + + sequence=((high_priority_buffer[0]&0xFF)<<24)+((high_priority_buffer[1]&0xFF)<<16)+((high_priority_buffer[2]&0xFF)<<8)+(high_priority_buffer[3]&0xFF); previous_ptt=ptt; previous_dot=dot; previous_dash=dash; - ptt=buffer[4]&0x01; - dot=(buffer[4]>>1)&0x01; - dash=(buffer[4]>>2)&0x01; + ptt=high_priority_buffer[4]&0x01; + dot=(high_priority_buffer[4]>>1)&0x01; + dash=(high_priority_buffer[4]>>2)&0x01; +/* if(ptt!=previous_ptt) { fprintf(stderr,"ptt=%d\n",ptt); } @@ -949,35 +1409,74 @@ if(dot!=previous_dot) { if(dash!=previous_dash) { fprintf(stderr,"dash=%d\n",dash); } - pll_locked=(buffer[4]>>3)&0x01; +*/ + pll_locked=(high_priority_buffer[4]>>3)&0x01; - adc_overload=buffer[5]&0x01; - exciter_power=((buffer[6]&0xFF)<<8)|(buffer[7]&0xFF); - alex_forward_power=((buffer[14]&0xFF)<<8)|(buffer[15]&0xFF); - alex_reverse_power=((buffer[22]&0xFF)<<8)|(buffer[23]&0xFF); - supply_volts=((buffer[49]&0xFF)<<8)|(buffer[50]&0xFF); + adc_overload=high_priority_buffer[5]&0x01; + exciter_power=((high_priority_buffer[6]&0xFF)<<8)|(high_priority_buffer[7]&0xFF); + alex_forward_power=((high_priority_buffer[14]&0xFF)<<8)|(high_priority_buffer[15]&0xFF); + alex_reverse_power=((high_priority_buffer[22]&0xFF)<<8)|(high_priority_buffer[23]&0xFF); + supply_volts=((high_priority_buffer[49]&0xFF)<<8)|(high_priority_buffer[50]&0xFF); - if(previous_ptt!=ptt) { - g_idle_add(ptt_update,(gpointer)ptt); + if(previous_ptt!=ptt && vfo[id].mode!=modeCWU && vfo[id].mode!=modeCWL) { + g_idle_add(ext_ptt_update,(gpointer)(long)(ptt)); + } else if(previous_dot!=dot && (vfo[id].mode==modeCWU || vfo[id].mode==modeCWL)) { + g_idle_add(ext_ptt_update,(gpointer)(long)(dot)); + } else if(previous_dash!=dash && (vfo[id].mode==modeCWU || vfo[id].mode==modeCWL)) { + g_idle_add(ext_ptt_update,(gpointer)(long)(dash)); } } -static void process_mic_data(unsigned char *buffer,int bytes) { +static void process_mic_data(int bytes) { long sequence; int b; + int i; short sample; - sequence=((buffer[0]&0xFF)<<24)+((buffer[1]&0xFF)<<16)+((buffer[2]&0xFF)<<8)+(buffer[3]&0xFF); + sequence=((mic_line_buffer[0]&0xFF)<<24)+((mic_line_buffer[1]&0xFF)<<16)+((mic_line_buffer[2]&0xFF)<<8)+(mic_line_buffer[3]&0xFF); b=4; + for(i=0;ifreedv) { + add_freedv_mic_sample(transmitter,sample); + } else { +#endif + add_mic_sample(transmitter,sample); +#ifdef FREEDV + } +#endif + } +} + +void new_protocol_process_local_mic(unsigned char *buffer,int le) { + int b; int i; + short sample; + + b=0; for(i=0;ifreedv) { + add_freedv_mic_sample(transmitter,sample); + } else { +#endif + add_mic_sample(transmitter,sample); +#ifdef FREEDV + } +#endif } + } + void new_protocol_audio_samples(RECEIVER *rx,short left_audio_sample,short right_audio_sample) { int rc; @@ -999,7 +1498,7 @@ void new_protocol_audio_samples(RECEIVER *rx,short left_audio_sample,short right rc=sendto(data_socket,audiobuffer,sizeof(audiobuffer),0,(struct sockaddr*)&audio_addr,audio_addr_length); if(rc!=sizeof(audiobuffer)) { - fprintf(stderr,"sendto socket failed for %d bytes of audio: %d\n",sizeof(audiobuffer),rc); + fprintf(stderr,"sendto socket failed for %ld bytes of audio: %d\n",sizeof(audiobuffer),rc); } audioindex=4; audiosequence++; @@ -1030,38 +1529,22 @@ void new_protocol_iq_samples(int isample,int qsample) { } } -void new_protocol_process_local_mic(unsigned char *buffer,int le) { - int b; - short micsample; - double micsampledouble; - double gain=pow(10.0, mic_gain / 20.0); - - b=0; - int i,j,s; - for(i=0;i #include +#include #include +#include + #include "new_menu.h" #include "noise_menu.h" #include "channel.h" @@ -38,40 +41,77 @@ static GtkWidget *dialog=NULL; static GtkWidget *last_filter; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static void update_noise() { + SetEXTANBRun(active_receiver->id, active_receiver->nb); + SetEXTNOBRun(active_receiver->id, active_receiver->nb2); SetRXAANRRun(active_receiver->id, active_receiver->nr); SetRXAEMNRRun(active_receiver->id, active_receiver->nr2); SetRXAANFRun(active_receiver->id, active_receiver->anf); SetRXASNBARun(active_receiver->id, active_receiver->snb); - vfo_update(NULL); + vfo_update(); +} + +static void nb_none_cb(GtkWidget *widget, gpointer data) { + active_receiver->nb=0; + active_receiver->nb2=0; + update_noise(); +} + +static void nb_cb(GtkWidget *widget, gpointer data) { + active_receiver->nb=1; + active_receiver->nb2=0; + update_noise(); +} + +static void nr_none_cb(GtkWidget *widget, gpointer data) { + active_receiver->nr=0; + active_receiver->nr2=0; + update_noise(); } static void nr_cb(GtkWidget *widget, gpointer data) { - active_receiver->nr=active_receiver->nr==1?0:1; + active_receiver->nr=1; + active_receiver->nr2=0; + update_noise(); +} + +static void nb2_cb(GtkWidget *widget, gpointer data) { + active_receiver->nb=0; + active_receiver->nb2=1; update_noise(); } static void nr2_cb(GtkWidget *widget, gpointer data) { - active_receiver->nr2=active_receiver->nr2==1?0:1; + active_receiver->nr=0; + active_receiver->nr2=2; update_noise(); } static void anf_cb(GtkWidget *widget, gpointer data) { - active_receiver->anf=active_receiver->anf==1?0:1; + active_receiver->anf=gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); update_noise(); } static void snb_cb(GtkWidget *widget, gpointer data) { - active_receiver->snb=active_receiver->snb==1?0:1; + active_receiver->snb=gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); update_noise(); } @@ -83,7 +123,11 @@ void noise_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + char title[64]; + sprintf(title,"piHPSDR - Noise (RX %d VFO %s)",active_receiver->id,active_receiver->id==0?"A":"B"); + gtk_window_set_title(GTK_WINDOW(dialog),title); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -101,39 +145,90 @@ void noise_menu(GtkWidget *parent) { gtk_grid_set_column_spacing (GTK_GRID(grid),5); gtk_grid_set_row_spacing (GTK_GRID(grid),5); - GtkWidget *close_b=gtk_button_new_with_label("Close Noise"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); - char label[32]; - sprintf(label,"RX %d VFO %s",active_receiver->id,active_receiver->id==0?"A":"B"); - GtkWidget *rx_label=gtk_label_new(label); - gtk_grid_attach(GTK_GRID(grid),rx_label,1,0,1,1); + int row=1; + int col=0; + + GtkWidget *nb_title=gtk_label_new("Noise Blanker"); + gtk_widget_show(nb_title); + gtk_grid_attach(GTK_GRID(grid),nb_title,col,row,1,1); + + col++; + + GtkWidget *nr_title=gtk_label_new("Noise Reduction"); + gtk_widget_show(nr_title); + gtk_grid_attach(GTK_GRID(grid),nr_title,col,row,1,1); + + row++; + col=0; + + GtkWidget *b_nb_none=gtk_radio_button_new_with_label(NULL, "None"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_nb_none), active_receiver->nb==0 && active_receiver->nb2==0); + gtk_widget_show(b_nb_none); + gtk_grid_attach(GTK_GRID(grid),b_nb_none,col,row,1,1); + g_signal_connect(b_nb_none,"pressed",G_CALLBACK(nb_none_cb),NULL); + + col++; - GtkWidget *b_nr=gtk_check_button_new_with_label("NR"); + GtkWidget *b_nr_none=gtk_radio_button_new_with_label(NULL, "None"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_nr_none), active_receiver->nr==0 && active_receiver->nr2==0); + gtk_widget_show(b_nr_none); + gtk_grid_attach(GTK_GRID(grid),b_nr_none,col,row,1,1); + g_signal_connect(b_nr_none,"pressed",G_CALLBACK(nr_none_cb),NULL); + + col++; + + GtkWidget *b_snb=gtk_check_button_new_with_label("SNB"); + //gtk_widget_override_font(b_snb, pango_font_description_from_string("Arial 16")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_snb), active_receiver->snb); + gtk_widget_show(b_snb); + gtk_grid_attach(GTK_GRID(grid),b_snb,col,row,1,1); + g_signal_connect(b_snb,"toggled",G_CALLBACK(snb_cb),NULL); + + row++; + col=0; + + GtkWidget *b_nb=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_nb_none),"NB"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_nb), active_receiver->nb); + gtk_widget_show(b_nb); + gtk_grid_attach(GTK_GRID(grid),b_nb,col,row,1,1); + g_signal_connect(b_nb,"pressed",G_CALLBACK(nb_cb),NULL); + + col++; + + GtkWidget *b_nr=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_nr_none),"NR"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_nr), active_receiver->nr); gtk_widget_show(b_nr); - gtk_grid_attach(GTK_GRID(grid),b_nr,0,2,2,1); - g_signal_connect(b_nr,"toggled",G_CALLBACK(nr_cb),NULL); + gtk_grid_attach(GTK_GRID(grid),b_nr,col,row,1,1); + g_signal_connect(b_nr,"pressed",G_CALLBACK(nr_cb),NULL); - GtkWidget *b_nr2=gtk_check_button_new_with_label("NR2"); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_nr2), active_receiver->nr2); - gtk_widget_show(b_nr2); - gtk_grid_attach(GTK_GRID(grid),b_nr2,0,3,2,1); - g_signal_connect(b_nr2,"toggled",G_CALLBACK(nr2_cb),NULL); + col++; GtkWidget *b_anf=gtk_check_button_new_with_label("ANF"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_anf), active_receiver->anf); gtk_widget_show(b_anf); - gtk_grid_attach(GTK_GRID(grid),b_anf,0,4,2,1); + gtk_grid_attach(GTK_GRID(grid),b_anf,col,row,1,1); g_signal_connect(b_anf,"toggled",G_CALLBACK(anf_cb),NULL); - - GtkWidget *b_snb=gtk_check_button_new_with_label("SNB"); - //gtk_widget_override_font(b_snb, pango_font_description_from_string("Arial 16")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_snb), active_receiver->snb); - gtk_widget_show(b_snb); - gtk_grid_attach(GTK_GRID(grid),b_snb,0,5,2,1); - g_signal_connect(b_snb,"toggled",G_CALLBACK(snb_cb),NULL); + + row++; + col=0; + + GtkWidget *b_nb2=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_nb),"NB2"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_nb2), active_receiver->nb2); + gtk_widget_show(b_nb2); + gtk_grid_attach(GTK_GRID(grid),b_nb2,col,row,1,1); + g_signal_connect(b_nb2,"pressed",G_CALLBACK(nb2_cb),NULL); + + col++; + + GtkWidget *b_nr2=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_nr),"NR2"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_nr2), active_receiver->nr2); + gtk_widget_show(b_nr2); + gtk_grid_attach(GTK_GRID(grid),b_nr2,col,row,1,1); + g_signal_connect(b_nr2,"pressed",G_CALLBACK(nr2_cb),NULL); gtk_container_add(GTK_CONTAINER(content),grid); diff --git a/oc_menu.c b/oc_menu.c index 73fc567..a7f8ee3 100644 --- a/oc_menu.c +++ b/oc_menu.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include "new_menu.h" @@ -28,6 +30,7 @@ #include "bandstack.h" #include "filter.h" #include "radio.h" +#include "new_protocol.h" static GtkWidget *parent_window=NULL; @@ -35,18 +38,27 @@ static GtkWidget *menu_b=NULL; static GtkWidget *dialog=NULL; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static void oc_rx_cb(GtkWidget *widget, gpointer data) { - int b=((int)data)>>4; - int oc=((int)data)&0xF; + int b=((uintptr_t)data)>>4; + int oc=((uintptr_t)data)&0xF; BAND *band=band_get_band(b); int mask=0x01<<(oc-1); fprintf(stderr,"oc_rx_cb: band=%d oc=%d mask=%d\n",b,oc,mask); @@ -62,8 +74,8 @@ fprintf(stderr,"oc_rx_cb: band=%d oc=%d mask=%d\n",b,oc,mask); } static void oc_tx_cb(GtkWidget *widget, gpointer data) { - int b=((int)data)>>4; - int oc=((int)data)&0xF; + int b=((uintptr_t)data)>>4; + int oc=((uintptr_t)data)&0xF; BAND *band=band_get_band(b); int mask=0x01<<(oc-1); @@ -80,7 +92,7 @@ fprintf(stderr,"oc_tx_cb: band=%d oc=%d mask=%d\n",b,oc,mask); } static void oc_tune_cb(GtkWidget *widget, gpointer data) { - int oc=((int)data)&0xF; + int oc=((uintptr_t)data)&0xF; int mask=0x01<<(oc-1); fprintf(stderr,"oc_tune_cb: oc=%d mask=%d\n",oc,mask); if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { @@ -105,7 +117,9 @@ void oc_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - Open Collector Output"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -122,7 +136,7 @@ void oc_menu(GtkWidget *parent) { //gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); - GtkWidget *close_b=gtk_button_new_with_label("Close OC"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); @@ -159,9 +173,9 @@ void oc_menu(GtkWidget *parent) { gtk_grid_attach(GTK_GRID(grid),oc_tx_title,i+7,2,1,1); } - for(i=0;ititle)>0) { 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); @@ -175,17 +189,18 @@ void oc_menu(GtkWidget *parent) { 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(grid),oc_rx_b,j,i+3,1,1); - g_signal_connect(oc_rx_b,"toggled",G_CALLBACK(oc_rx_cb),(gpointer)(j+(i<<4))); + g_signal_connect(oc_rx_b,"toggled",G_CALLBACK(oc_rx_cb),(gpointer)(long)(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(grid),oc_tx_b,j+7,i+3,1,1); - g_signal_connect(oc_tx_b,"toggled",G_CALLBACK(oc_tx_cb),(gpointer)(j+(i<<4))); + g_signal_connect(oc_tx_b,"toggled",G_CALLBACK(oc_tx_cb),(gpointer)(long)(j+(i<<4))); } } + } int mask; for(j=1;j<8;j++) { @@ -202,7 +217,7 @@ void oc_menu(GtkWidget *parent) { 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(grid),oc_tune_b,19,j+1,1,1); - g_signal_connect(oc_tune_b,"toggled",G_CALLBACK(oc_tune_cb),(gpointer)j); + g_signal_connect(oc_tune_b,"toggled",G_CALLBACK(oc_tune_cb),(gpointer)(long)j); } GtkWidget *oc_full_tune_time_title=gtk_label_new("Full Tune(ms):"); diff --git a/old_discovery.c b/old_discovery.c index 33c44cb..87992da 100644 --- a/old_discovery.c +++ b/old_discovery.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -45,8 +44,6 @@ static int interface_length; static int discovery_socket; static struct sockaddr_in discovery_addr; -//static pthread_t discover_thread_id; -//static void* discover_receive_thread(void* arg); static GThread *discover_thread_id; static gpointer discover_receive_thread(gpointer data); @@ -67,6 +64,7 @@ static void discover(struct ifaddrs* iface) { int optval = 1; setsockopt(discovery_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); + setsockopt(discovery_socket, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)); sa = (struct sockaddr_in *) iface->ifa_addr; mask = (struct sockaddr_in *) iface->ifa_netmask; @@ -99,13 +97,6 @@ static void discover(struct ifaddrs* iface) { to_addr.sin_addr.s_addr=htonl(INADDR_BROADCAST); // start a receive thread to collect discovery response packets -/* - rc=pthread_create(&discover_thread_id,NULL,discover_receive_thread,NULL); - if(rc != 0) { - fprintf(stderr,"pthread_create failed on discover_receive_thread: rc=%d\n", rc); - exit(-1); - } -*/ discover_thread_id = g_thread_new( "old discover receive", discover_receive_thread, NULL); if( ! discover_thread_id ) { @@ -131,10 +122,6 @@ static void discover(struct ifaddrs* iface) { } // wait for receive thread to complete -/* - void* status; - pthread_join(discover_thread_id,&status); -*/ g_thread_join(discover_thread_id); close(discovery_socket); @@ -230,7 +217,6 @@ fprintf(stderr,"discover_receive_thread\n"); } fprintf(stderr,"discovery: exiting discover_receive_thread\n"); - //pthread_exit(NULL); g_thread_exit(NULL); } diff --git a/old_protocol.c b/old_protocol.c index bf0f3ef..4dbbb36 100644 --- a/old_protocol.c +++ b/old_protocol.c @@ -56,6 +56,8 @@ #include "psk.h" #endif #include "vox.h" +#include "ext.h" +#include "error_handler.h" #define min(x,y) (xinfo.network.interface_address,radio->info.network.interface_length)<0) { perror("old_protocol: bind socket failed for data_socket\n"); @@ -403,8 +394,13 @@ static gpointer receive_thread(gpointer arg) { default: bytes_read=recvfrom(data_socket,buffer,sizeof(buffer),0,(struct sockaddr*)&addr,&length); if(bytes_read<0) { - perror("recvfrom socket failed for old_protocol: receive_thread"); - exit(1); + if(errno==EAGAIN) { + error_handler("old_protocol: receiver_thread: recvfrom socket failed","Radio not sending data"); + } else { + error_handler("old_protocol: receiver_thread: recvfrom socket failed",strerror(errno)); + } + running=0; + continue; } if(buffer[0]==0xEF && buffer[1]==0xFE) { @@ -473,6 +469,17 @@ static void process_ozy_input_buffer(char *buffer) { double right_sample_double; double mic_sample_double; double gain=pow(10.0, mic_gain / 20.0); + int left_sample_1; + int right_sample_1; + double left_sample_double_rx; + double right_sample_double_rx; + double left_sample_double_tx; + double right_sample_double_tx; + int nreceivers; + + int id=active_receiver->id; + + int tx_vfo=split?VFO_B:VFO_A; if(buffer[b++]==SYNC && buffer[b++]==SYNC && buffer[b++]==SYNC) { // extract control bytes @@ -489,6 +496,7 @@ static void process_ozy_input_buffer(char *buffer) { dash=(control_in[0]&0x02)==0x02; dot=(control_in[0]&0x04)==0x04; +/* if(ptt!=previous_ptt) { fprintf(stderr,"ptt=%d\n",ptt); } @@ -498,9 +506,24 @@ if(dot!=previous_dot) { if(dash!=previous_dash) { fprintf(stderr,"dash=%d\n",dash); } + if(previous_ptt!=ptt && vfo[tx_vfo].mode!=modeCWU && vfo[tx_vfo].mode!=modeCWL) { + g_idle_add(ext_ptt_update,(gpointer)(long)(ptt)); + } else if(previous_dot!=dot && (vfo[tx_vfo].mode==modeCWU || vfo[tx_vfo].mode==modeCWL)) { + g_idle_add(ext_ptt_update,(gpointer)(long)(dot)); + } else if(previous_dash!=dash && (vfo[tx_vfo].mode==modeCWU || vfo[tx_vfo].mode==modeCWL)) { + g_idle_add(ext_ptt_update,(gpointer)(long)(dash)); + } +*/ + + if(vfo[tx_vfo].mode==modeCWL || vfo[tx_vfo].mode==modeCWU) { + if(dot==0 && dash==0) { + ptt=0; + } + } - if(previous_ptt!=ptt || dot!=previous_dot || dash!=previous_dash) { - g_idle_add(ptt_update,(gpointer)(ptt | dot | dash)); + if(previous_ptt!=ptt) { +//fprintf(stderr,"ptt=%d previous_ptt=%d dot=%d dash=%d vfo=%d mode=%d\n",ptt,previous_ptt,dot,dash,tx_vfo,vfo[tx_vfo].mode); + g_idle_add(ext_ptt_update,(gpointer)(long)(ptt)); } switch((control_in[0]>>3)&0x1F) { @@ -537,10 +560,15 @@ if(dash!=previous_dash) { } - int iq_samples=(512-8)/((RECEIVERS*6)+2); +#ifdef PURESIGNAL + nreceivers=(RECEIVERS*2)+1; +#else + nreceivers=RECEIVERS; +#endif + int iq_samples=(512-8)/((nreceivers*6)+2); for(i=0;ipuresignal)) { + switch(r) { + case 0: + add_iq_samples(receiver[0], left_sample_double,right_sample_double); + break; + case 1: + break; + case 2: + add_iq_samples(receiver[1], left_sample_double,right_sample_double); + break; + case 3: + break; + case 4: + break; + } + } else { + switch(r) { + case 0: + if(device==DEVICE_METIS) { + left_sample_double_rx=left_sample_double; + right_sample_double_rx=right_sample_double; + } + break; + case 1: + if(device==DEVICE_METIS) { + left_sample_double_tx=left_sample_double; + right_sample_double_tx=right_sample_double; + add_ps_iq_samples(transmitter, left_sample_double_rx,right_sample_double_rx,left_sample_double_tx,right_sample_double_tx); + } + break; + case 2: + if(device==DEVICE_HERMES) { + left_sample_double_rx=left_sample_double; + right_sample_double_rx=right_sample_double; + } + break; + case 3: + if(device==DEVICE_METIS) { + left_sample_double_tx=left_sample_double; + right_sample_double_tx=right_sample_double; + add_ps_iq_samples(transmitter, left_sample_double_tx,right_sample_double_tx,left_sample_double_rx,right_sample_double_rx); + } else if(device==DEVICE_ANGELIA || device==DEVICE_ORION || device==DEVICE_ORION2) { + left_sample_double_rx=left_sample_double; + right_sample_double_rx=right_sample_double; + } + break; + case 4: + if(device==DEVICE_ANGELIA || device==DEVICE_ORION || device==DEVICE_ORION2) { + left_sample_double_tx=left_sample_double; + right_sample_double_tx=right_sample_double; + add_ps_iq_samples(transmitter, left_sample_double_tx,right_sample_double_tx,left_sample_double_rx,right_sample_double_rx); + } + break; + } + } +#else add_iq_samples(receiver[r], left_sample_double,right_sample_double); +#endif } + mic_sample = (short)(buffer[b++]<<8); mic_sample |= (short)(buffer[b++]&0xFF); if(!transmitter->local_microphone) { mic_samples++; if(mic_samples>=mic_sample_divisor) { // reduce to 48000 - add_mic_sample(transmitter,mic_sample); +#ifdef FREEDV + if(active_receiver->freedv) { + add_freedv_mic_sample(transmitter,mic_sample); + } else { +#endif + add_mic_sample(transmitter,mic_sample); +#ifdef FREEDV + } +#endif mic_samples=0; } } @@ -615,17 +710,26 @@ void old_protocol_iq_samples(int isample,int qsample) { void old_protocol_process_local_mic(unsigned char *buffer,int le) { int b; - short mic_sample; + int i; + short sample; + // always 48000 samples per second b=0; - int i,j,s; for(i=0;i<720;i++) { if(le) { - mic_sample = (short)((buffer[b++]&0xFF) | (buffer[b++]<<8)); + sample = (short)((buffer[b++]&0xFF) | (buffer[b++]<<8)); } else { - mic_sample = (short)((buffer[b++]<<8) | (buffer[b++]&0xFF)); + sample = (short)((buffer[b++]<<8) | (buffer[b++]&0xFF)); } - add_mic_sample(transmitter,mic_sample); +#ifdef FREEDV + if(active_receiver->freedv) { + add_freedv_mic_sample(transmitter,sample); + } else { +#endif + add_mic_sample(transmitter,sample); +#ifdef FREEDV + } +#endif } } @@ -641,313 +745,398 @@ void ozy_send_buffer() { int mode; int i; BAND *band; + int nreceivers; output_buffer[SYNC0]=SYNC; output_buffer[SYNC1]=SYNC; output_buffer[SYNC2]=SYNC; - switch(command) { - case 0: - { - - output_buffer[C0]=0x00; - - output_buffer[C1]=0x00; - switch(active_receiver->sample_rate) { - case 48000: - output_buffer[C1]|=SPEED_48K; - break; - case 96000: - output_buffer[C1]|=SPEED_96K; - break; - case 192000: - output_buffer[C1]|=SPEED_192K; - break; - case 384000: - output_buffer[C1]|=SPEED_384K; - break; - } + if(metis_offset==8) { + output_buffer[C0]=0x00; + output_buffer[C1]=0x00; + switch(active_receiver->sample_rate) { + case 48000: + output_buffer[C1]|=SPEED_48K; + break; + case 96000: + output_buffer[C1]|=SPEED_96K; + break; + case 192000: + output_buffer[C1]|=SPEED_192K; + break; + case 384000: + output_buffer[C1]|=SPEED_384K; + break; + } // set more bits for Atlas based device // CONFIG_BOTH seems to be critical to getting ozy to respond #ifdef USBOZY - if ((device == DEVICE_OZY) || (device == DEVICE_METIS)) + if ((device == DEVICE_OZY) || (device == DEVICE_METIS)) #else - if (device == DEVICE_METIS) + if (device == DEVICE_METIS) #endif - { - if (atlas_mic_source) - output_buffer[C1] |= PENELOPE_MIC; - output_buffer[C1] |= CONFIG_BOTH; - if (atlas_clock_source_128mhz) - output_buffer[C1] |= MERCURY_122_88MHZ_SOURCE; - output_buffer[C1] |= ((atlas_clock_source_10mhz & 3) << 2); - } + { + if (atlas_mic_source) + output_buffer[C1] |= PENELOPE_MIC; + output_buffer[C1] |= CONFIG_BOTH; + if (atlas_clock_source_128mhz) + output_buffer[C1] |= MERCURY_122_88MHZ_SOURCE; + output_buffer[C1] |= ((atlas_clock_source_10mhz & 3) << 2); + } - output_buffer[C2]=0x00; - if(classE) { - output_buffer[C2]|=0x01; + output_buffer[C2]=0x00; + if(classE) { + output_buffer[C2]|=0x01; + } + band=band_get_band(vfo[VFO_A].band); + if(isTransmitting()) { + if(split) { + band=band_get_band(vfo[VFO_B].band); } - band=band_get_band(vfo[VFO_A].band); - if(isTransmitting()) { - if(split) { - band=band_get_band(vfo[VFO_B].band); - } - output_buffer[C2]|=band->OCtx<<1; - if(tune) { - if(OCmemory_tune_time!=0) { - struct timeval te; - gettimeofday(&te,NULL); - long long now=te.tv_sec*1000LL+te.tv_usec/1000; - if(tune_timeout>now) { - output_buffer[C2]|=OCtune<<1; - } - } else { + output_buffer[C2]|=band->OCtx<<1; + if(tune) { + if(OCmemory_tune_time!=0) { + struct timeval te; + gettimeofday(&te,NULL); + long long now=te.tv_sec*1000LL+te.tv_usec/1000; + if(tune_timeout>now) { output_buffer[C2]|=OCtune<<1; } + } else { + output_buffer[C2]|=OCtune<<1; } - } else { - output_buffer[C2]|=band->OCrx<<1; } + } else { + output_buffer[C2]|=band->OCrx<<1; + } // TODO - add Alex Attenuation and Alex Antenna - output_buffer[C3]=0x00; - if(active_receiver->random) { - output_buffer[C3]|=LT2208_RANDOM_ON; - } - if(active_receiver->dither) { - output_buffer[C3]|=LT2208_DITHER_ON; - } - if(active_receiver->preamp) { - output_buffer[C3]|=LT2208_GAIN_ON; - } + output_buffer[C3]=0x00; + if(active_receiver->random) { + output_buffer[C3]|=LT2208_RANDOM_ON; + } + if(active_receiver->dither) { + output_buffer[C3]|=LT2208_DITHER_ON; + } + if(active_receiver->preamp) { + output_buffer[C3]|=LT2208_GAIN_ON; + } + + switch(receiver[0]->alex_antenna) { + case 0: // ANT 1 + break; + case 1: // ANT 2 + break; + case 2: // ANT 3 + break; + case 3: // EXT 1 + //output_buffer[C3]|=0xA0; + output_buffer[C3]|=0xC0; + break; + case 4: // EXT 2 + //output_buffer[C3]|=0xC0; + output_buffer[C3]|=0xA0; + break; + case 5: // XVTR + output_buffer[C3]|=0xE0; + break; + default: + break; + } + +// TODO - add Alex TX relay, duplex, receivers Mercury board frequency + output_buffer[C4]=0x04; // duplex +#ifdef PURESIGNAL + nreceivers=(RECEIVERS*2)-1; + nreceivers+=1; // for PS TX Feedback +#else + nreceivers=RECEIVERS-1; +#endif + output_buffer[C4]|=nreceivers<<3; + + if(isTransmitting()) { + switch(transmitter->alex_antenna) { + case 0: // ANT 1 + output_buffer[C4]|=0x00; + break; + case 1: // ANT 2 + output_buffer[C4]|=0x01; + break; + case 2: // ANT 3 + output_buffer[C4]|=0x02; + break; + default: + break; + } + } else { switch(receiver[0]->alex_antenna) { case 0: // ANT 1 + output_buffer[C4]|=0x00; break; case 1: // ANT 2 + output_buffer[C4]|=0x01; break; case 2: // ANT 3 + output_buffer[C4]|=0x02; break; case 3: // EXT 1 - //output_buffer[C3]|=0xA0; - output_buffer[C3]|=0xC0; - break; case 4: // EXT 2 - //output_buffer[C3]|=0xC0; - output_buffer[C3]|=0xA0; - break; case 5: // XVTR - output_buffer[C3]|=0xE0; - break; - default: + switch(transmitter->alex_antenna) { + case 0: // ANT 1 + output_buffer[C4]|=0x00; + break; + case 1: // ANT 2 + output_buffer[C4]|=0x01; + break; + case 2: // ANT 3 + output_buffer[C4]|=0x02; + break; + } break; } - - -// TODO - add Alex TX relay, duplex, receivers Mercury board frequency - output_buffer[C4]=0x04; // duplex - output_buffer[C4]|=(RECEIVERS-1)<<3; - - if(isTransmitting()) { - switch(transmitter->alex_antenna) { - case 0: // ANT 1 - output_buffer[C4]|=0x00; - break; - case 1: // ANT 2 - output_buffer[C4]|=0x01; - break; - case 2: // ANT 3 - output_buffer[C4]|=0x02; - break; - default: - break; + } + } else { + switch(command) { + case 1: // tx frequency + output_buffer[C0]=0x02; + long long txFrequency; + if(active_receiver->id==VFO_A) { + if(split) { + txFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo+vfo[VFO_B].offset; + } else { + txFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo+vfo[VFO_A].offset; + } + } else { + if(split) { + txFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo+vfo[VFO_A].offset; + } else { + txFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo+vfo[VFO_B].offset; + } } - } else { - switch(receiver[0]->alex_antenna) { - case 0: // ANT 1 - output_buffer[C4]|=0x00; - break; - case 1: // ANT 2 - output_buffer[C4]|=0x01; - break; - case 2: // ANT 3 - output_buffer[C4]|=0x02; - break; - case 3: // EXT 1 - case 4: // EXT 2 - case 5: // XVTR - switch(transmitter->alex_antenna) { - case 0: // ANT 1 - output_buffer[C4]|=0x00; - break; - case 1: // ANT 2 - output_buffer[C4]|=0x01; - break; - case 2: // ANT 3 - output_buffer[C4]|=0x02; - break; + output_buffer[C1]=txFrequency>>24; + output_buffer[C2]=txFrequency>>16; + output_buffer[C3]=txFrequency>>8; + output_buffer[C4]=txFrequency; + break; + case 2: // rx frequency +#ifdef PURESIGNAL + nreceivers=(RECEIVERS*2)+1; +#else + nreceivers=RECEIVERS; +#endif + if(current_rxid; + if(isTransmitting() && transmitter->puresignal) { + long long txFrequency; + if(active_receiver->id==VFO_A) { + if(split) { + txFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo+vfo[VFO_B].offset; + } else { + txFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo+vfo[VFO_A].offset; + } + } else { + if(split) { + txFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo+vfo[VFO_A].offset; + } else { + txFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo+vfo[VFO_B].offset; + } + } + output_buffer[C1]=txFrequency>>24; + output_buffer[C2]=txFrequency>>16; + output_buffer[C3]=txFrequency>>8; + output_buffer[C4]=txFrequency; + } else { +#else + int v=receiver[current_rx]->id; +#endif + long long rxFrequency=vfo[v].frequency-vfo[v].lo; + if(vfo[v].rit_enabled) { + rxFrequency+=vfo[v].rit; + } + if(vfo[v].mode==modeCWU) { + rxFrequency-=(long long)cw_keyer_sidetone_frequency; + } else if(vfo[v].mode==modeCWL) { + rxFrequency+=(long long)cw_keyer_sidetone_frequency; } - break; + output_buffer[C1]=rxFrequency>>24; + output_buffer[C2]=rxFrequency>>16; + output_buffer[C3]=rxFrequency>>8; + output_buffer[C4]=rxFrequency; +#ifdef PURESIGNAL + } +#endif + current_rx++; } - } - } - break; - case 1: // tx frequency - output_buffer[C0]=0x02; - long long txFrequency; - if(split) { - txFrequency=vfo[VFO_B].frequency-vfo[VFO_A].lo+vfo[VFO_B].offset; - } else { - txFrequency=vfo[VFO_A].frequency-vfo[VFO_B].lo+vfo[VFO_A].offset; - } - output_buffer[C1]=txFrequency>>24; - output_buffer[C2]=txFrequency>>16; - output_buffer[C3]=txFrequency>>8; - output_buffer[C4]=txFrequency; - break; - case 2: // rx frequency - if(current_rxid; - long long rxFrequency=vfo[v].frequency-vfo[v].lo; - if(vfo[v].rit_enabled) { - rxFrequency+=vfo[v].rit; + if(current_rx>=nreceivers) { + current_rx=0; } - if(vfo[active_receiver->id].mode==modeCWU) { - rxFrequency-=(long long)cw_keyer_sidetone_frequency; - } else if(vfo[active_receiver->id].mode==modeCWL) { - rxFrequency+=(long long)cw_keyer_sidetone_frequency; + break; + case 3: + { + BAND *band=band_get_current_band(); + int power=0; + if(isTransmitting()) { + if(tune && !transmitter->tune_use_drive) { + power=(int)((double)transmitter->drive_level/100.0*(double)transmitter->tune_percent); + } else { + power=transmitter->drive_level; + } } - output_buffer[C1]=rxFrequency>>24; - output_buffer[C2]=rxFrequency>>16; - output_buffer[C3]=rxFrequency>>8; - output_buffer[C4]=rxFrequency; - current_rx++; - } - if(current_rx>=receivers) { - current_rx=0; - } - break; - case 3: - { - BAND *band=band_get_current_band(); - int power=0; - if(isTransmitting()) { - if(tune) { - power=tune_drive_level; - } else { - power=drive_level; + + output_buffer[C0]=0x12; + output_buffer[C1]=power&0xFF; + output_buffer[C2]=0x00; + if(mic_boost) { + output_buffer[C2]|=0x01; + } + if(mic_linein) { + output_buffer[C2]|=0x02; + } + if(filter_board==APOLLO) { + output_buffer[C2]|=0x2C; + } + if((filter_board==APOLLO) && tune) { + output_buffer[C2]|=0x10; + } + output_buffer[C3]=0x00; + if(band_get_current()==band6) { + output_buffer[C3]=output_buffer[C3]|0x40; // Alex 6M low noise amplifier + } + if(band->disablePA) { + output_buffer[C3]=output_buffer[C3]|0x80; // disable PA } - } - - output_buffer[C0]=0x12; - output_buffer[C1]=power&0xFF; - output_buffer[C2]=0x00; - if(mic_boost) { - output_buffer[C2]|=0x01; - } - if(mic_linein) { - output_buffer[C2]|=0x02; - } - if(filter_board==APOLLO) { - output_buffer[C2]|=0x2C; - } - if((filter_board==APOLLO) && tune) { - output_buffer[C2]|=0x10; - } - output_buffer[C3]=0x00; - if(band_get_current()==band6) { - output_buffer[C3]=output_buffer[C3]|0x40; // Alex 6M low noise amplifier - } - if(band->disablePA) { - output_buffer[C3]=output_buffer[C3]|0x80; // disable PA - } - output_buffer[C4]=0x00; - } - break; - case 4: - output_buffer[C0]=0x14; - output_buffer[C1]=0x00; - for(i=0;ipreamp<device==DEVICE_HERMES || radio->device==DEVICE_ANGELIA || radio->device==DEVICE_ORION || radio->device==DEVICE_ORION2) { - output_buffer[C4]=0x20|receiver[0]->attenuation; - } else { output_buffer[C4]=0x00; - } - break; - case 5: - // need to add adc 2 and 3 attenuation - output_buffer[C0]=0x16; - output_buffer[C1]=0x00; - if(receivers==2) { + } + break; + case 4: + output_buffer[C0]=0x14; + output_buffer[C1]=0x00; + for(i=0;ipreamp<puresignal) { + output_buffer[C2]|=0x40; + } +#endif + output_buffer[C3]=0x00; + if(radio->device==DEVICE_HERMES || radio->device==DEVICE_ANGELIA || radio->device==DEVICE_ORION || radio->device==DEVICE_ORION2) { - output_buffer[C1]=0x20|receiver[1]->attenuation; + output_buffer[C4]=0x20|receiver[0]->attenuation; + } else { + output_buffer[C4]=0x00; } - } - output_buffer[C2]=0x00; - if(cw_keys_reversed!=0) { - output_buffer[C2]|=0x40; - } - output_buffer[C3]=cw_keyer_speed | (cw_keyer_mode<<6); - output_buffer[C4]=cw_keyer_weight | (cw_keyer_spacing<<7); - break; - case 6: - // need to add tx attenuation and rx ADC selection - output_buffer[C0]=0x1C; - output_buffer[C1]=0x00; - output_buffer[C2]=0x00; - output_buffer[C3]=0x00; - output_buffer[C4]=0x00; - break; - case 7: - output_buffer[C0]=0x1E; - if(split) { - mode=vfo[1].mode; - } else { - mode=vfo[0].mode; - } - if(mode!=modeCWU && mode!=modeCWL) { - // output_buffer[C1]|=0x00; - } else { - if((tune==1) || (vox==1) || (cw_keyer_internal==0)) { - output_buffer[C1]|=0x00; - } else if(mox==1) { - output_buffer[C1]|=0x01; + break; + case 5: + // need to add adc 2 and 3 attenuation + output_buffer[C0]=0x16; + output_buffer[C1]=0x00; + if(receivers==2) { + if(radio->device==DEVICE_HERMES || radio->device==DEVICE_ANGELIA || radio->device==DEVICE_ORION || radio->device==DEVICE_ORION2) { + output_buffer[C1]=0x20|receiver[1]->attenuation; + } + } + output_buffer[C2]=0x00; + if(cw_keys_reversed!=0) { + output_buffer[C2]|=0x40; + } + output_buffer[C3]=cw_keyer_speed | (cw_keyer_mode<<6); + output_buffer[C4]=cw_keyer_weight | (cw_keyer_spacing<<7); + break; + case 6: + // need to add tx attenuation and rx ADC selection + output_buffer[C0]=0x1C; + output_buffer[C1]=0x00; +#ifdef PURESIGNAL + output_buffer[C1]|=receiver[0]->adc; + output_buffer[C1]|=(receiver[0]->adc<<2); + output_buffer[C1]|=receiver[1]->adc<<4; + output_buffer[C1]|=(receiver[1]->adc<<6); + output_buffer[C2]=0x00; + if(transmitter->puresignal) { + output_buffer[C2]|=receiver[2]->adc; } +#else + output_buffer[C1]|=receiver[0]->adc; + output_buffer[C1]|=(receiver[1]->adc<<2); +#endif + output_buffer[C3]=0x00; + output_buffer[C3]|=transmitter->attenuation; + output_buffer[C4]=0x00; + break; + case 7: + output_buffer[C0]=0x1E; + if(split) { + mode=vfo[1].mode; + } else { + mode=vfo[0].mode; + } + output_buffer[C1]=0x00; + if(mode!=modeCWU && mode!=modeCWL) { + // output_buffer[C1]|=0x00; + } else { + if((tune==1) || (vox==1) || (cw_keyer_internal==0)) { + output_buffer[C1]|=0x00; + } else { + output_buffer[C1]|=0x01; + } + } + output_buffer[C2]=cw_keyer_sidetone_volume; + output_buffer[C3]=cw_keyer_ptt_delay; + output_buffer[C4]=0x00; + break; + case 8: + output_buffer[C0]=0x20; + output_buffer[C1]=(cw_keyer_hang_time>>2) & 0xFF; + output_buffer[C2]=cw_keyer_hang_time & 0x03; + 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; + case 10: + output_buffer[C0]=0x24; + output_buffer[C1]=0x00; + if(isTransmitting()) { + output_buffer[C1]|=0x80; // ground RX1 on transmit + } + output_buffer[C2]=0x00; + if(receiver[0]->alex_antenna==5) { // XVTR + output_buffer[C2]=0x02; + } + output_buffer[C3]=0x00; + output_buffer[C4]=0x00; + break; + } + + if(current_rx==0) { + command++; + if(command>10) { + command=1; } - output_buffer[C2]=cw_keyer_sidetone_volume; - output_buffer[C3]=cw_keyer_ptt_delay; - output_buffer[C4]=0x00; - break; - case 8: - output_buffer[C0]=0x20; - output_buffer[C1]=(cw_keyer_hang_time>>2) & 0xFF; - output_buffer[C2]=cw_keyer_hang_time & 0x03; - 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 @@ -976,11 +1165,6 @@ void ozy_send_buffer() { #endif metis_write(0x02,output_buffer,OZY_BUFFER_SIZE); - command++; - if(command>9) { - command=0; - } - //fprintf(stderr,"C0=%02X C1=%02X C2=%02X C3=%02X C4=%02X\n", // output_buffer[C0],output_buffer[C1],output_buffer[C2],output_buffer[C3],output_buffer[C4]); } @@ -1052,15 +1236,23 @@ static int metis_write(unsigned char ep,char* buffer,int length) { } static void metis_restart() { + // reset metis frame + metis_offset==8; + + // reset current rx + current_rx=0; + // send commands twice - command=0; + command=1; do { ozy_send_buffer(); - } while (command!=0); + } while (command!=1); do { ozy_send_buffer(); - } while (command!=0); + } while (command!=1); + + sleep(1); // start the data flowing metis_start_stop(1); diff --git a/old_protocol.h b/old_protocol.h index 45107ee..f179090 100644 --- a/old_protocol.h +++ b/old_protocol.h @@ -26,7 +26,6 @@ extern void old_protocol_run(); extern void old_protocol_init(int rx,int pixels,int rate); extern void old_protocol_set_mic_sample_rate(int rate); -extern void schedule_frequency_changed(); extern void old_protocol_process_local_mic(unsigned char *buffer,int le); extern void old_protocol_audio_samples(RECEIVER *rx,short left_audio_sample,short right_audio_sample); extern void old_protocol_iq_samples(int isample,int qsample); diff --git a/pa_menu.c b/pa_menu.c index 67cb6e6..aee51f6 100644 --- a/pa_menu.c +++ b/pa_menu.c @@ -34,15 +34,24 @@ static GtkWidget *menu_b=NULL; static GtkWidget *dialog=NULL; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static void pa_value_changed_cb(GtkWidget *widget, gpointer data) { BAND *band=(BAND *)data; band->pa_calibration=gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget)); @@ -52,7 +61,6 @@ static void pa_value_changed_cb(GtkWidget *widget, gpointer data) { BAND *current=band_get_band(b); if(band==current) { calcDriveLevel(); - calcTuneDriveLevel(); } } @@ -67,7 +75,9 @@ void pa_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - PA Calibration"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -84,7 +94,7 @@ void pa_menu(GtkWidget *parent) { //gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); - GtkWidget *close_b=gtk_button_new_with_label("Close PA Gain(dB)"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); diff --git a/property.c b/property.c index d960b18..110a600 100644 --- a/property.c +++ b/property.c @@ -75,7 +75,7 @@ void loadProperties(char* filename) { * @param filename */ void saveProperties(char* filename) { - PROPERTY* property=properties; + PROPERTY* property; FILE* f=fopen(filename,"w+"); char line[512]; char version[32]; @@ -84,8 +84,9 @@ void saveProperties(char* filename) { return; } - sprintf(line,"%s=%0.2f\n","property_version",PROPERTY_VERSION); - fwrite(line,1,strlen(line),f); + sprintf(line,"%0.2f",PROPERTY_VERSION); + setProperty("property_version",line); + property=properties; while(property) { sprintf(line,"%s=%s\n",property->name,property->value); fwrite(line,1,strlen(line),f); diff --git a/property.h b/property.h index 3fb103a..83e29ec 100644 --- a/property.h +++ b/property.h @@ -34,8 +34,10 @@ struct _PROPERTY { PROPERTY* next_property; }; -void loadProperties(char* filename); -char* getProperty(char* name); -void setProperty(char* name,char* value); +extern void loadProperties(char* filename); +extern char* getProperty(char* name); +extern void setProperty(char* name,char* value); + +extern void saveProperties(char* filename); #endif diff --git a/ps_menu.c b/ps_menu.c new file mode 100644 index 0000000..46bee20 --- /dev/null +++ b/ps_menu.c @@ -0,0 +1,525 @@ +/* +* 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 +#include +#include +#include +#include +#include + +#include "button_text.h" +//#include "led.h" +#include "new_menu.h" +#include "radio.h" +#include "toolbar.h" +#include "transmitter.h" +#include "new_protocol.h" +#include "vfo.h" +#include "ext.h" + +static GtkWidget *parent_window=NULL; +static GtkWidget *dialog=NULL; +static GtkWidget *feedback_l; +static GtkWidget *correcting_l; +static GtkWidget *get_pk; +static GtkWidget *set_pk; + +static GThread *info_thread_id; + +static int running=0; + +#define INFO_SIZE 16 + +static GtkWidget *entry[INFO_SIZE]; + +// results from GetPSDisp +static double ps_x[4096]; +static double ps_ym[4096]; +static double ps_yc[4096]; +static double ps_ys[4096]; +static double ps_cm[64]; +static double ps_cc[64]; +static double ps_cs[64]; + +static void destroy_cb(GtkWidget *widget, gpointer data) { +//fprintf(stderr,"ps_menu: destroy_cb\n"); + running=0; +} + +static void cleanup() { + if(transmitter->twotone) { + tx_set_twotone(transmitter,0); + } + if(dialog!=NULL) { + gtk_widget_destroy(dialog); + dialog=NULL; + sub_menu=NULL; + } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); + return TRUE; +} + +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + +static int deltadb=0; + +static gpointer info_thread(gpointer arg) { + static int info[16]; + int i; + gchar *label; + static int old5=0; + static int old5_2=0; + static int old14=0; + int display; + int counter=0; + int state=0; + int save_auto_on; + int save_single_on; + + if(transmitter->auto_on) { + transmitter->attenuation=31; + } else { + transmitter->attenuation=0; + } + + running=1; + while(running) { + GetPSInfo(transmitter->id,&info[0]); + for(i=0;i181) { + gtk_label_set_markup(GTK_LABEL(feedback_l),"Feedback Lvl"); + } else if(info[4]>128) { + gtk_label_set_markup(GTK_LABEL(feedback_l),"Feedback Lvl"); + } else if(info[4]>90) { + gtk_label_set_markup(GTK_LABEL(feedback_l),"Feedback Lvl"); + } else { + gtk_label_set_markup(GTK_LABEL(feedback_l),"Feedback Lvl"); + } + } + break; + case 6: + label=g_strdup_printf("%d",info[i]); + break; + case 13: + label=g_strdup_printf("%d",info[i]); + break; + case 14: + label=g_strdup_printf("%d",info[i]); + if(info[14]!=old14) { + old14=info[14]; + if(info[14]==0) { + gtk_label_set_markup(GTK_LABEL(correcting_l),"Correcting"); + } else { + gtk_label_set_markup(GTK_LABEL(correcting_l),"Correcting"); + } + } + display=0; + break; + case 15: + switch(info[i]) { + case 0: + label=g_strdup_printf("RESET"); + break; + case 1: + label=g_strdup_printf("WAIT"); + break; + case 2: + label=g_strdup_printf("MOXDELAY"); + break; + case 3: + label=g_strdup_printf("SETUP"); + break; + case 4: + label=g_strdup_printf("COLLECT"); + break; + case 5: + label=g_strdup_printf("MOXCHECK"); + break; + case 6: + label=g_strdup_printf("CALC"); + break; + case 7: + label=g_strdup_printf("DELAY"); + break; + case 8: + label=g_strdup_printf("STAYON"); + break; + case 9: + label=g_strdup_printf("TUNRON"); + break; + default: + label=g_strdup_printf("UNKNOWN %d=%d",i,info[i]); + break; + } + break; + default: + label=g_strdup_printf("info %d=%d",i,info[i]); + display=0; + break; + } + if(display) { + if(entry[i]!=NULL) { + gtk_entry_set_text(GTK_ENTRY(entry[i]),label); + } else { +fprintf(stderr,"ps_menu: entry %d is NULL\n", i); + } + } + + if(label!=NULL) { + g_free(label); + label=NULL; + } + + } + + double pk; + gchar *pk_label; + + GetPSMaxTX(transmitter->id,&pk); + pk_label=g_strdup_printf("%f",pk); + gtk_entry_set_text(GTK_ENTRY(get_pk),pk_label); + if(pk_label!=NULL) { + g_free(pk_label); + pk_label=NULL; + } + + + counter++; + if(counter==10) { // every 100ms + double ddb; + int newcal=info[5]!=old5_2; + old5_2=info[5]; + switch(state) { + case 0: + if(transmitter->auto_on && newcal && (info[4]>181 || (info[4]<=128 && transmitter->attenuation>0))) { + if(info[4]<=256) { + ddb= 20.0 * log10((double)info[4]/152.293); + if(isnan(ddb)) { + ddb=31.1; + } + if(ddb<-100.0) { + ddb=-100.0; + } + if(ddb > 100.0) { + ddb=100.0; + } + } else { + ddb=31.1; + } + deltadb=(int)ddb; + save_auto_on=transmitter->auto_on; + save_single_on=transmitter->single_on; + SetPSControl(transmitter->id, 1, 0, 0, 0); + state=1; + } + break; + case 1: + if((deltadb+transmitter->attenuation)>0) { + transmitter->attenuation+=deltadb; + } else { + transmitter->attenuation=0; + } + state=2; + break; + case 2: + state=0; + SetPSControl(transmitter->id, 0, save_single_on, save_auto_on, 0); + break; + } + counter=0; + } + usleep(10000); // 10 ms + } + gtk_entry_set_text(GTK_ENTRY(entry[15]),""); +} + +static void enable_cb(GtkWidget *widget, gpointer data) { + g_idle_add(ext_tx_set_ps,(gpointer)(long)gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))); +} + +static void auto_cb(GtkWidget *widget, gpointer data) { + transmitter->auto_on=gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); + if(transmitter->auto_on) { + transmitter->attenuation=31; + } else { + transmitter->attenuation=0; + } +} + +static void calibrate_cb(GtkWidget *widget, gpointer data) { + transmitter->puresignal=1; + SetPSControl(transmitter->id, 0, 1, 0, 0); +} + +static void feedback_cb(GtkWidget *widget, gpointer data) { + if(transmitter->feedback==0) { + transmitter->feedback=1; + set_button_text_color(widget,"red"); + } else { + transmitter->feedback=0; + set_button_text_color(widget,"black"); + } +} + +static void reset_cb(GtkWidget *widget, gpointer data) { + transmitter->attenuation=0; + SetPSControl(transmitter->id, 1, 0, 0, 0); +} + +void ps_twotone(int state) { + tx_set_twotone(transmitter,state); + if(transmitter->twotone) { + //set_button_text_color(widget,"red"); + } else { + //set_button_text_color(widget,"black"); + } + if(state && transmitter->puresignal) { + info_thread_id=g_thread_new( "PS info", info_thread, NULL); + } else { + running=0; + } +} + +static void twotone_cb(GtkWidget *widget, gpointer data) { + int state=transmitter->twotone?0:1; + //g_idle_add(ext_ps_twotone,(gpointer)(long)state); + tx_set_twotone(transmitter,state); + if(state) { + set_button_text_color(widget,"red"); + } else { + set_button_text_color(widget,"black"); + } + if(state && transmitter->puresignal) { + info_thread_id=g_thread_new( "PS info", info_thread, NULL); + } else { + running=0; + } +} + +void ps_menu(GtkWidget *parent) { + GtkWidget *b; + int i; + + parent_window=parent; + + dialog=gtk_dialog_new(); + g_signal_connect (dialog, "destroy", G_CALLBACK(destroy_cb), NULL); + gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - Pure Signal"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); + + GdkRGBA color; + color.red = 1.0; + color.green = 1.0; + color.blue = 1.0; + color.alpha = 1.0; + gtk_widget_override_background_color(dialog,GTK_STATE_FLAG_NORMAL,&color); + + GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + + GtkWidget *grid=gtk_grid_new(); + + //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); + //gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); + gtk_grid_set_column_spacing (GTK_GRID(grid),5); + gtk_grid_set_row_spacing (GTK_GRID(grid),5); + + int row=0; + int col=0; + + GtkWidget *close_b=gtk_button_new_with_label("Close"); + g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); + gtk_grid_attach(GTK_GRID(grid),close_b,col,row,1,1); + + row++; + col=0; + + GtkWidget *enable_b=gtk_check_button_new_with_label("Enable PS"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (enable_b), transmitter->puresignal); + gtk_grid_attach(GTK_GRID(grid),enable_b,col,row,1,1); + g_signal_connect(enable_b,"toggled",G_CALLBACK(enable_cb),NULL); + + col++; + + GtkWidget *twotone_b=gtk_button_new_with_label("Two Tone"); + gtk_widget_show(twotone_b); + gtk_grid_attach(GTK_GRID(grid),twotone_b,col,row,1,1); + g_signal_connect(twotone_b,"pressed",G_CALLBACK(twotone_cb),NULL); + if(transmitter->twotone) { + set_button_text_color(twotone_b,"red"); + } + + + col++; + + GtkWidget *auto_b=gtk_check_button_new_with_label("Auto Attenuate"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (auto_b), transmitter->auto_on); + gtk_grid_attach(GTK_GRID(grid),auto_b,col,row,1,1); + g_signal_connect(auto_b,"toggled",G_CALLBACK(auto_cb),NULL); + + col++; + + GtkWidget *reset_b=gtk_button_new_with_label("Reset"); + gtk_widget_show(reset_b); + gtk_grid_attach(GTK_GRID(grid),reset_b,col,row,1,1); + g_signal_connect(reset_b,"pressed",G_CALLBACK(reset_cb),NULL); + + col++; + + GtkWidget *feedback_b=gtk_button_new_with_label("MON"); + gtk_widget_show(feedback_b); + gtk_grid_attach(GTK_GRID(grid),feedback_b,col,row,1,1); + g_signal_connect(feedback_b,"pressed",G_CALLBACK(feedback_cb),NULL); + if(transmitter->feedback) { + set_button_text_color(feedback_b,"red"); + } + + + row++; + col=0; + + feedback_l=gtk_label_new("Feedback Lvl"); + gtk_widget_show(feedback_l); + gtk_grid_attach(GTK_GRID(grid),feedback_l,col,row,1,1); + + col++; + + correcting_l=gtk_label_new("Correcting"); + gtk_widget_show(correcting_l); + gtk_grid_attach(GTK_GRID(grid),correcting_l,col,row,1,1); + + row++; + col=0; + + for(i=0;i=6) { + row++; + col=0; + } + } else { + entry[i]=NULL; + } + } + + row++; + col=0; + GtkWidget *lbl=gtk_label_new("GetPk"); + gtk_grid_attach(GTK_GRID(grid),lbl,col,row,1,1); + col++; + + get_pk=gtk_entry_new(); + gtk_grid_attach(GTK_GRID(grid),get_pk,col,row,1,1); + col++; + + lbl=gtk_label_new("SetPk"); + gtk_grid_attach(GTK_GRID(grid),lbl,col,row,1,1); + col++; + + double pk; + char pk_text[16]; + GetPSHWPeak(transmitter->id,&pk); + sprintf(pk_text,"%f",pk); + set_pk=gtk_entry_new(); + gtk_entry_set_text(GTK_ENTRY(set_pk),pk_text); + gtk_grid_attach(GTK_GRID(grid),set_pk,col,row,1,1); + + gtk_container_add(GTK_CONTAINER(content),grid); + sub_menu=dialog; + + //if(transmitter->puresignal) { + // info_thread_id=g_thread_new( "PS info", info_thread, NULL); + //} + + gtk_widget_show_all(dialog); + +} diff --git a/ps_menu.h b/ps_menu.h new file mode 100644 index 0000000..e35d831 --- /dev/null +++ b/ps_menu.h @@ -0,0 +1,20 @@ +/* +* 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 void ps_menu(GtkWidget *parent); + +extern void ps_twotone(int state); diff --git a/radio.c b/radio.c index b908abf..18f7fcb 100644 --- a/radio.c +++ b/radio.c @@ -1,4 +1,4 @@ -/* Copyright (C) +/* Copyrieht (C) * 2015 - John Melton, G0ORX/N6LYT * * This program is free software; you can redistribute it and/or @@ -23,6 +23,9 @@ #include #include #include +#include +#include +#include #include @@ -39,6 +42,7 @@ #include "agc.h" #include "band.h" #include "property.h" +#include "new_menu.h" #include "new_protocol.h" #include "old_protocol.h" #ifdef RADIOBERRY @@ -51,36 +55,43 @@ #ifdef FREEDV #include "freedv.h" #endif +#include "audio_waterfall.h" #ifdef GPIO #include "gpio.h" #endif #include "vfo.h" +#include "vox.h" #include "meter.h" #include "rx_panadapter.h" #include "tx_panadapter.h" #include "waterfall.h" #include "sliders.h" #include "toolbar.h" +#include "rigctl.h" +#include "ext.h" #define min(x,y) (xpanel,0,y); + receiver[i]->x=0; + receiver[i]->y=y; y+=rx_height/receivers; } @@ -302,8 +321,6 @@ void reconfigure_radio() { gtk_fixed_move(GTK_FIXED(fixed),sliders,0,y); } gtk_widget_show_all(sliders); - // force change of sliders for mic or linein - g_idle_add(linein_changed,NULL); } else { if(sliders!=NULL) { gtk_container_remove(GTK_CONTAINER(fixed),sliders); @@ -334,7 +351,7 @@ void start_radio() { int i; int x; int y; -fprintf(stderr,"start_radio: selected radio=%p device=%d\n",radio,radio->device); +//fprintf(stderr,"start_radio: selected radio=%p device=%d\n",radio,radio->device); gdk_window_set_cursor(gtk_widget_get_window(top_window),gdk_cursor_new(GDK_WATCH)); int rc; @@ -345,7 +362,47 @@ fprintf(stderr,"start_radio: selected radio=%p device=%d\n",radio,radio->device) } sem_post(&property_sem); - status_text("starting radio ..."); + char text[256]; + //for(i=0;iprotocol) { + case ORIGINAL_PROTOCOL: + case NEW_PROTOCOL: +#ifdef USBOZY + if(radio->device==DEVICE_OZY) { + sprintf(text,"%s (%s) on USB /dev/ozy\n", radio->name, radio->protocol==ORIGINAL_PROTOCOL?"Protocol 1":"Protocol 2"); + } else { +#endif + sprintf(text,"Starting %s (%s v%d.%d)", + radio->name, + radio->protocol==ORIGINAL_PROTOCOL?"Protocol 1":"Protocol 2", + radio->software_version/10, + radio->software_version%10); + break; + } + //} + + + + status_text(text); + + sprintf(text,"piHPSDR: %s (%s v%d.%d) %s (%02X:%02X:%02X:%02X:%02X:%02X) on %s", + radio->name, + radio->protocol==ORIGINAL_PROTOCOL?"Protocol 1":"Protocol 2", + radio->software_version/10, + radio->software_version%10, + inet_ntoa(radio->info.network.address.sin_addr), + radio->info.network.mac_address[0], + radio->info.network.mac_address[1], + radio->info.network.mac_address[2], + radio->info.network.mac_address[3], + radio->info.network.mac_address[4], + radio->info.network.mac_address[5], + radio->info.network.interface_name); + +fprintf(stderr,"title: length=%d\n", (int)strlen(text)); + + gtk_window_set_title (GTK_WINDOW (top_window), text); + protocol=radio->protocol; device=radio->device; @@ -381,19 +438,50 @@ fprintf(stderr,"start_radio: selected radio=%p device=%d\n",radio,radio->device) #endif } + switch(radio->protocol) { + case ORIGINAL_PROTOCOL: + switch(radio->device) { + case DEVICE_ORION2: + //meter_calibration=3.0; + //display_calibration=3.36; + break; + default: + //meter_calibration=-2.44; + //display_calibration=-2.1; + break; + } + break; + case NEW_PROTOCOL: + switch(radio->device) { + case NEW_DEVICE_ORION2: + //meter_calibration=3.0; + //display_calibration=3.36; + break; + default: + //meter_calibration=-2.44; + //display_calibration=-2.1; + break; + } + break; + } + + +//fprintf(stderr,"meter_calibration=%f display_calibration=%f\n", meter_calibration, display_calibration); radioRestoreState(); + radio_change_region(region); + y=0; fixed=gtk_fixed_new(); gtk_container_remove(GTK_CONTAINER(top_window),grid); gtk_container_add(GTK_CONTAINER(top_window), fixed); -fprintf(stderr,"radio: vfo_init\n"); +//fprintf(stderr,"radio: vfo_init\n"); vfo_panel = vfo_init(VFO_WIDTH,VFO_HEIGHT,top_window); gtk_fixed_put(GTK_FIXED(fixed),vfo_panel,0,y); -fprintf(stderr,"radio: meter_init\n"); +//fprintf(stderr,"radio: meter_init\n"); meter = meter_init(METER_WIDTH,METER_HEIGHT,top_window); gtk_fixed_put(GTK_FIXED(fixed),meter,VFO_WIDTH,y); @@ -422,37 +510,52 @@ fprintf(stderr,"radio: meter_init\n"); fprintf(stderr,"Create %d receivers: height=%d\n",receivers,rx_height); - for(i=0;ipanel); + setSquelch(receiver[i]); if(ix=0; + receiver[i]->y=y; gtk_fixed_put(GTK_FIXED(fixed),receiver[i]->panel,0,y); -fprintf(stderr,"receiver %d: height=%d y=%d\n",receiver[i]->id,rx_height,y); + g_object_ref((gpointer)receiver[i]->panel); set_displaying(receiver[i],1); y+=rx_height; } else { set_displaying(receiver[i],0); } } + + if((protocol==ORIGINAL_PROTOCOL) && (RECEIVERS==2) && (receiver[0]->sample_rate!=receiver[1]->sample_rate)) { + receiver[1]->sample_rate=receiver[0]->sample_rate; + } + active_receiver=receiver[0]; fprintf(stderr,"Create transmitter\n"); transmitter=create_transmitter(CHANNEL_TX, buffer_size, fft_size, updates_per_second, display_width, tx_height); - g_object_ref((gpointer)transmitter->panel); + transmitter->x=0; + transmitter->y=VFO_HEIGHT; + //gtk_fixed_put(GTK_FIXED(fixed),transmitter->panel,0,VFO_HEIGHT); + +#ifdef PURESIGNAL + tx_set_ps_sample_rate(transmitter,protocol==NEW_PROTOCOL?192000:active_receiver->sample_rate); + if(((protocol==ORIGINAL_PROTOCOL) && (device!=DEVICE_METIS)) || ((protocol==NEW_PROTOCOL) && (device!=NEW_DEVICE_ATLAS))) { + receiver[PS_TX_FEEDBACK]=create_pure_signal_receiver(PS_TX_FEEDBACK, buffer_size,protocol==ORIGINAL_PROTOCOL?active_receiver->sample_rate:192000,display_width); + receiver[PS_RX_FEEDBACK]=create_pure_signal_receiver(PS_RX_FEEDBACK, buffer_size,protocol==ORIGINAL_PROTOCOL?active_receiver->sample_rate:192000,display_width); + } +#endif +#ifdef AUDIO_WATERFALL + audio_waterfall=audio_waterfall_init(200,100); + gtk_fixed_put(GTK_FIXED(fixed),audio_waterfall,0,VFO_HEIGHT+20); +#endif - #ifdef GPIO +#ifdef GPIO if(gpio_init()<0) { fprintf(stderr,"GPIO failed to initialize\n"); } -#ifdef LOCALCW - // init local keyer if enabled - else if (cw_keyer_internal == 0) - keyer_update(); -#endif #endif - switch(radio->protocol) { case ORIGINAL_PROTOCOL: old_protocol_init(0,display_width,receiver[0]->sample_rate); @@ -474,9 +577,9 @@ fprintf(stderr,"receiver %d: height=%d y=%d\n",receiver[i]->id,rx_height,y); -#ifdef I2C - i2c_init(); -#endif +//#ifdef I2C +// i2c_init(); +//#endif if(display_sliders) { fprintf(stderr,"create sliders\n"); @@ -485,17 +588,21 @@ fprintf(stderr,"create sliders\n"); y+=SLIDERS_HEIGHT; } + toolbar = toolbar_init(display_width,TOOLBAR_HEIGHT,top_window); gtk_fixed_put(GTK_FIXED(fixed),toolbar,0,y); y+=TOOLBAR_HEIGHT; gtk_widget_show_all (fixed); +//#ifdef FREEDV +// if(!active_receiver->freedv) { +// gtk_widget_hide(audio_waterfall); +// } +//#endif - // force change of sliders for mic or linein - g_idle_add(linein_changed,NULL); + // save every 30 seconds -fprintf(stderr,"start save timer\n"); save_timer_id=gdk_threads_add_timeout(30000, save_cb, NULL); #ifdef PSK @@ -506,36 +613,36 @@ fprintf(stderr,"start save timer\n"); } #endif - launch_rigctl(); + if(rigctl_enable) { + launch_rigctl(); + } calcDriveLevel(); - calcTuneDriveLevel(); + +#ifdef PURESIGNAL + if(transmitter->puresignal) { + tx_set_ps(transmitter,transmitter->puresignal); + } +#endif if(protocol==NEW_PROTOCOL) { schedule_high_priority(); } - g_idle_add(vfo_update,(gpointer)NULL); + g_idle_add(ext_vfo_update,(gpointer)NULL); -fprintf(stderr,"set cursor\n"); gdk_window_set_cursor(gtk_widget_get_window(top_window),gdk_cursor_new(GDK_ARROW)); -for(i=0;ifreedv) { + freedv_reset_tx_text_index(); + } +#endif +#ifdef PURESIGNAL + RECEIVER *rx_feedback=receiver[PS_RX_FEEDBACK]; + RECEIVER *tx_feedback=receiver[PS_TX_FEEDBACK]; + + rx_feedback->samples=0; + tx_feedback->samples=0; +#endif + for(i=0;iid,0,i==(receivers-1)); set_displaying(receiver[i],0); if(protocol==NEW_PROTOCOL) { schedule_high_priority(); + schedule_receive_specific(); + } + g_object_ref((gpointer)receiver[i]->panel); + g_object_ref((gpointer)receiver[i]->panadapter); + if(receiver[i]->waterfall!=NULL) { + g_object_ref((gpointer)receiver[i]->waterfall); } gtk_container_remove(GTK_CONTAINER(fixed),receiver[i]->panel); } - gtk_fixed_put(GTK_FIXED(fixed),transmitter->panel,0,y); +//#ifdef FREEDV +// if(active_receiver->freedv) { +// gtk_widget_show(audio_waterfall); +// } +//#endif + gtk_fixed_put(GTK_FIXED(fixed),transmitter->panel,transmitter->x,transmitter->y); SetChannelState(transmitter->id,1,0); tx_set_displaying(transmitter,1); -#ifdef FREEDV - if(active_receiver->mode==modeFREEDV) { - freedv_reset_tx_text_index(); - } -#endif } else { SetChannelState(transmitter->id,0,1); if(protocol==NEW_PROTOCOL) { schedule_high_priority(); + schedule_receive_specific(); } tx_set_displaying(transmitter,0); + g_object_ref((gpointer)transmitter->panel); + g_object_ref((gpointer)transmitter->panadapter); gtk_container_remove(GTK_CONTAINER(fixed),transmitter->panel); - int rx_height=display_height-VFO_HEIGHT-TOOLBAR_HEIGHT; - if(display_sliders) { - rx_height-=SLIDERS_HEIGHT; - } +//#ifdef FREEDV +// if(active_receiver->freedv) { +// gtk_widget_hide(audio_waterfall); +// } +//#endif for(i=0;ipanel,receiver[i]->x,receiver[i]->y); SetChannelState(receiver[i]->id,1,0); set_displaying(receiver[i],1); - gtk_fixed_put(GTK_FIXED(fixed),receiver[i]->panel,0,y); - y+=(rx_height/receivers); } +//#ifdef FREEDV +// if(active_receiver->freedv) { +// gtk_widget_show(audio_waterfall); +// } +//#endif } - gtk_widget_show_all(fixed); - g_idle_add(linein_changed,NULL); +#ifdef PURESIGNAL + if(transmitter->puresignal) { + SetPSMox(transmitter->id,state); + } +#endif } void setMox(int state) { -fprintf(stderr,"setMox: %d\n",state); if(mox!=state) { mox=state; if(vox_enabled && vox) { @@ -641,12 +780,11 @@ void setVox(int state) { vox=state; rxtx(state); } - g_idle_add(vfo_update,(gpointer)NULL); + g_idle_add(ext_vfo_update,(gpointer)NULL); } -int vox_changed(void *data) { - setVox((int)data); - return 0; +void vox_changed(int state) { + setVox(state); } @@ -687,63 +825,50 @@ void setTune(int state) { } } - int mode=vfo[VFO_A].mode;; + int mode=vfo[VFO_A].mode; if(split) { mode=vfo[VFO_B].mode; } - double freq=(double)cw_keyer_sidetone_frequency; - - pre_tune_filter_low=transmitter->filter_low; - pre_tune_filter_high=transmitter->filter_high; + pre_tune_mode=mode; switch(mode) { - case modeUSB: - case modeCWU: - case modeDIGU: - SetTXAPostGenToneFreq(transmitter->id,(double)cw_keyer_sidetone_frequency); - transmitter->filter_low=cw_keyer_sidetone_frequency-100; - transmitter->filter_high=cw_keyer_sidetone_frequency+100; - freq=(double)(cw_keyer_sidetone_frequency+100); - break; case modeLSB: case modeCWL: case modeDIGL: SetTXAPostGenToneFreq(transmitter->id,-(double)cw_keyer_sidetone_frequency); - transmitter->filter_low=-cw_keyer_sidetone_frequency-100; - transmitter->filter_high=-cw_keyer_sidetone_frequency+100; - freq=(double)(-cw_keyer_sidetone_frequency-100); - break; - case modeDSB: - SetTXAPostGenToneFreq(transmitter->id,(double)cw_keyer_sidetone_frequency); - transmitter->filter_low=cw_keyer_sidetone_frequency-100; - transmitter->filter_high=cw_keyer_sidetone_frequency+100; - freq=(double)(cw_keyer_sidetone_frequency+100); break; - case modeAM: - case modeSAM: - case modeFMN: + default: SetTXAPostGenToneFreq(transmitter->id,(double)cw_keyer_sidetone_frequency); - transmitter->filter_low=cw_keyer_sidetone_frequency-100; - transmitter->filter_high=cw_keyer_sidetone_frequency+100; - freq=(double)(cw_keyer_sidetone_frequency+100); break; } - SetTXABandpassFreqs(transmitter->id,transmitter->filter_low,transmitter->filter_high); - - - SetTXAMode(transmitter->id,modeDIGU); - SetTXAPostGenMode(transmitter->id,0); SetTXAPostGenToneMag(transmitter->id,0.99999); + SetTXAPostGenMode(transmitter->id,0); SetTXAPostGenRun(transmitter->id,1); + + switch(mode) { + case modeCWL: + cw_keyer_internal=0; + tx_set_mode(transmitter,modeLSB); + break; + case modeCWU: + cw_keyer_internal=0; + tx_set_mode(transmitter,modeUSB); + break; + } + rxtx(tune); } else { + rxtx(tune); SetTXAPostGenRun(transmitter->id,0); - SetTXAMode(transmitter->id,transmitter->mode); - transmitter->filter_low=pre_tune_filter_low; - transmitter->filter_high=pre_tune_filter_high; - SetTXABandpassFreqs(transmitter->id,transmitter->filter_low,transmitter->filter_high); + switch(pre_tune_mode) { + case modeCWL: + case modeCWU: + tx_set_mode(transmitter,pre_tune_mode); + cw_keyer_internal=1; + break; + } + } - rxtx(tune); } } @@ -751,8 +876,31 @@ int getTune() { return tune; } +void radio_cw_setup() { + int mode=vfo[VFO_A].mode;; + if(split) { + mode=vfo[VFO_B].mode; + } + + double freq=(double)cw_keyer_sidetone_frequency; + switch(mode) { + case modeCWU: + SetTXAPostGenToneFreq(transmitter->id,(double)cw_keyer_sidetone_frequency); + break; + case modeLSB: + SetTXAPostGenToneFreq(transmitter->id,-(double)cw_keyer_sidetone_frequency); + break; + } + SetTXAPostGenMode(transmitter->id,0); + SetTXAPostGenToneMag(transmitter->id,0.99999); +} + +void radio_cw_key(int state) { + SetTXAPostGenRun(transmitter->id,state); +} + int isTransmitting() { - return ptt || mox || vox || tune; + return ptt | mox | vox | tune; } void setFrequency(long long f) { @@ -803,7 +951,6 @@ fprintf(stderr,"setFrequency: %lld\n",f); #ifdef RADIOBERRY case RADIOBERRY_PROTOCOL: #endif - schedule_frequency_changed(); break; #ifdef LIMESDR case LIMESDR_PROTOCOL: @@ -820,7 +967,7 @@ long long getFrequency() { } double getDrive() { - return drive; + return transmitter->drive; } static int calcLevel(double d) { @@ -843,35 +990,36 @@ static int calcLevel(double d) { } level=(int)(actual_volts*255.0); + +//fprintf(stderr,"calcLevel: %f calib=%f level=%d\n",d, gbb, level); return level; } void calcDriveLevel() { - drive_level=calcLevel(drive); + transmitter->drive_level=calcLevel(transmitter->drive); if(mox && protocol==NEW_PROTOCOL) { schedule_high_priority(); } +//fprintf(stderr,"calcDriveLevel: drive=%d drive_level=%d\n",transmitter->drive,transmitter->drive_level); } void setDrive(double value) { - drive=value; + transmitter->drive=value; calcDriveLevel(); } double getTuneDrive() { - return tune_drive; + return transmitter->tune_percent; } -void calcTuneDriveLevel() { - tune_drive_level=calcLevel(tune_drive); - if(tune && protocol==NEW_PROTOCOL) { - schedule_high_priority(); - } -} +void setSquelch(RECEIVER *rx) { + double am_sq=((rx->squelch/100.0)*160.0)-160.0; + SetRXAAMSQThreshold(rx->id, am_sq); + SetRXAAMSQRun(rx->id, rx->squelch_enable); -void setTuneDrive(double value) { - tune_drive=value; - calcTuneDriveLevel(); + double fm_sq=pow(10.0, -2.0*rx->squelch/100.0); + SetRXAFMSQThreshold(rx->id, fm_sq); + SetRXAFMSQRun(rx->id, rx->squelch_enable); } void set_attenuation(int value) { @@ -928,6 +1076,8 @@ fprintf(stderr,"radioRestoreState: %s\n",property_path); sem_wait(&property_sem); loadProperties(property_path); + value=getProperty("region"); + if(value) region=atoi(value); value=getProperty("buffer_size"); if(value) buffer_size=atoi(value); value=getProperty("fft_size"); @@ -968,14 +1118,6 @@ fprintf(stderr,"radioRestoreState: %s\n",property_path); if(value) waterfall_high=atoi(value); value=getProperty("waterfall_low"); if(value) waterfall_low=atoi(value); - value=getProperty("waterfall_automatic"); - if(value) waterfall_automatic=atoi(value); -// value=getProperty("volume"); -// if(value) volume=atof(value); - value=getProperty("drive"); - if(value) drive=atof(value); - value=getProperty("tune_drive"); - if(value) tune_drive=atof(value); value=getProperty("mic_gain"); if(value) mic_gain=atof(value); value=getProperty("mic_boost"); @@ -1032,11 +1174,8 @@ fprintf(stderr,"radioRestoreState: %s\n",property_path); if(value) OCfull_tune_time=atoi(value); value=getProperty("OCmemory_tune_time"); if(value) OCmemory_tune_time=atoi(value); -#ifdef FREEDV - strcpy(freedv_tx_text_data,"NO TEXT DATA"); - value=getProperty("freedv_tx_text_data"); - if(value) strcpy(freedv_tx_text_data,value); -#endif + value=getProperty("analog_meter"); + if(value) analog_meter=atoi(value); value=getProperty("smeter"); if(value) smeter=atoi(value); value=getProperty("alc"); @@ -1073,8 +1212,6 @@ fprintf(stderr,"radioRestoreState: %s\n",property_path); if(value) rx_equalizer[3]=atoi(value); value=getProperty("rit_increment"); if(value) rit_increment=atoi(value); - value=getProperty("deviation"); - if(value) deviation=atoi(value); value=getProperty("pre_emphasize"); if(value) pre_emphasize=atoi(value); @@ -1101,6 +1238,9 @@ fprintf(stderr,"radioRestoreState: %s\n",property_path); value=getProperty("filterB"); if(value) filterB=atoi(value); + value=getProperty("tone_level"); + if(value) tone_level=atof(value); + #ifdef GPIO value=getProperty("e1_encoder_action"); if(value) e1_encoder_action=atoi(value); @@ -1117,6 +1257,13 @@ fprintf(stderr,"radioRestoreState: %s\n",property_path); bandRestoreState(); memRestoreState(); vfo_restore_state(); +#ifdef FREEDV + freedv_restore_state(); +#endif + value=getProperty("rigctl_enable"); + if(value) rigctl_enable=atoi(value); + value=getProperty("rigctl_port_base"); + if(value) rigctl_port_base=atoi(value); sem_post(&property_sem); } @@ -1126,6 +1273,8 @@ void radioSaveState() { char value[80]; sem_wait(&property_sem); + sprintf(value,"%d",region); + setProperty("region",value); sprintf(value,"%d",buffer_size); setProperty("buffer_size",value); sprintf(value,"%d",fft_size); @@ -1136,12 +1285,6 @@ void radioSaveState() { setProperty("filter_board",value); sprintf(value,"%d",tx_out_of_band); setProperty("tx_out_of_band",value); -/* - sprintf(value,"%d",apollo_tuner); - setProperty("apollo_tuner",value); - sprintf(value,"%d",pa); - setProperty("pa",value); -*/ sprintf(value,"%d",updates_per_second); setProperty("updates_per_second",value); sprintf(value,"%d",display_filled); @@ -1158,24 +1301,12 @@ void radioSaveState() { setProperty("panadapter_low",value); sprintf(value,"%d",display_sliders); setProperty("display_sliders",value); -/* - sprintf(value,"%d",display_toolbar); - setProperty("display_toolbar",value); -*/ sprintf(value,"%d",waterfall_high); setProperty("waterfall_high",value); sprintf(value,"%d",waterfall_low); setProperty("waterfall_low",value); - sprintf(value,"%d",waterfall_automatic); - setProperty("waterfall_automatic",value); -// sprintf(value,"%f",volume); -// setProperty("volume",value); sprintf(value,"%f",mic_gain); setProperty("mic_gain",value); - sprintf(value,"%f",drive); - setProperty("drive",value); - sprintf(value,"%f",tune_drive); - setProperty("tune_drive",value); sprintf(value,"%d",mic_boost); setProperty("mic_boost",value); sprintf(value,"%d",mic_linein); @@ -1227,11 +1358,8 @@ void radioSaveState() { setProperty("OCfull_tune_time",value); sprintf(value,"%d",OCmemory_tune_time); setProperty("OCmemory_tune_time",value); -#ifdef FREEDV - if(strlen(freedv_tx_text_data)>0) { - setProperty("freedv_tx_text_data",freedv_tx_text_data); - } -#endif + sprintf(value,"%d",analog_meter); + setProperty("analog_meter",value); sprintf(value,"%d",smeter); setProperty("smeter",value); sprintf(value,"%d",alc); @@ -1244,8 +1372,6 @@ void radioSaveState() { #endif sprintf(value,"%d",local_microphone); setProperty("local_microphone",value); -// sprintf(value,"%d",n_selected_input_device); -// setProperty("n_selected_input_device",value); sprintf(value,"%d",enable_tx_equalizer); setProperty("enable_tx_equalizer",value); @@ -1269,8 +1395,6 @@ void radioSaveState() { setProperty("rx_equalizer.3",value); sprintf(value,"%d",rit_increment); setProperty("rit_increment",value); - sprintf(value,"%d",deviation); - setProperty("deviation",value); sprintf(value,"%d",pre_emphasize); setProperty("pre_emphasize",value); @@ -1278,10 +1402,6 @@ void radioSaveState() { setProperty("vox_enabled",value); sprintf(value,"%f",vox_threshold); setProperty("vox_threshold",value); -/* - sprintf(value,"%f",vox_gain); - setProperty("vox_gain",value); -*/ sprintf(value,"%f",vox_hang); setProperty("vox_hang",value); @@ -1295,6 +1415,9 @@ void radioSaveState() { sprintf(value,"%d",filterB); setProperty("filterB",value); + sprintf(value,"%f",tone_level); + setProperty("tone_level",value); + #ifdef GPIO sprintf(value,"%d",e1_encoder_action); setProperty("e1_encoder_action",value); @@ -1312,10 +1435,19 @@ void radioSaveState() { receiver_save_state(receiver[i]); } transmitter_save_state(transmitter); +#ifdef FREEDV + freedv_save_state(); +#endif filterSaveState(); bandSaveState(); memSaveState(); + + sprintf(value,"%d",rigctl_enable); + setProperty("rigctl_enable",value); + sprintf(value,"%d",rigctl_port_base); + setProperty("rigctl_port_base",value); + saveProperties(property_path); sem_post(&property_sem); } @@ -1354,3 +1486,38 @@ void set_filter_size(int filter_size) { transmitter->fft_size=filter_size; TXASetNC(transmitter->id, filter_size); } + +#ifdef FREEDV +void set_freedv(int state) { +fprintf(stderr,"set_freedv: rx=%p state=%d\n",active_receiver,state); + g_mutex_lock(&active_receiver->freedv_mutex); + active_receiver->freedv=state; + if(active_receiver->freedv) { + SetRXAPanelRun(active_receiver->id, 0); + init_freedv(active_receiver); + transmitter->freedv_samples=0; + } else { + SetRXAPanelRun(active_receiver->id, 1); + close_freedv(active_receiver); + } + g_mutex_unlock(&active_receiver->freedv_mutex); + g_idle_add(ext_vfo_update,NULL); +} +#endif + +void radio_change_region(int r) { + region=r; + if(region==REGION_UK) { + channel_entries=UK_CHANNEL_ENTRIES; + band_channels_60m=&band_channels_60m_UK[0]; + bandstack60.entries=UK_CHANNEL_ENTRIES; + bandstack60.current_entry=0; + bandstack60.entry=bandstack_entries60_UK; + } else { + channel_entries=OTHER_CHANNEL_ENTRIES; + band_channels_60m=&band_channels_60m_OTHER[0]; + bandstack60.entries=OTHER_CHANNEL_ENTRIES; + bandstack60.current_entry=0; + bandstack60.entry=bandstack_entries60_OTHER; + } +} diff --git a/radio.h b/radio.h index c3bc0df..5ca4ca0 100644 --- a/radio.h +++ b/radio.h @@ -53,9 +53,18 @@ extern char property_path[]; #define ALEX 1 #define APOLLO 2 -// specify how many receivers (only 1 or 2 for now) -#define MAX_RECEIVERS 2 +#define REGION_OTHER 0 +#define REGION_UK 1 + +extern int region; + +// specify how many receivers +#define MAX_RECEIVERS 8 #define RECEIVERS 2 +#ifdef PURESIGNAL +#define PS_TX_FEEDBACK (RECEIVERS) +#define PS_RX_FEEDBACK (RECEIVERS+1) +#endif extern RECEIVER *receiver[]; extern RECEIVER *active_receiver; @@ -90,7 +99,6 @@ extern int classE; extern int tx_out_of_band; extern int tx_cfir; -extern int tx_alc; extern int tx_leveler; extern double tone_level; @@ -110,10 +118,7 @@ extern int display_average_mode; extern double display_average_time; -extern int display_waterfall; -extern int waterfall_high; -extern int waterfall_low; -extern int waterfall_automatic; +//extern int display_waterfall; extern int display_sliders; extern int display_toolbar; @@ -128,11 +133,11 @@ extern int mic_bias_enabled; extern int mic_ptt_enabled; extern int mic_ptt_tip_bias_ring; -extern double tune_drive; -extern double drive; +//extern double tune_drive; +//extern double drive; -extern int tune_drive_level; -extern int drive_level; +//extern int tune_drive_level; +//extern int drive_level; int receivers; @@ -206,10 +211,7 @@ 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 int analog_meter; extern int smeter; extern int alc; @@ -230,7 +232,6 @@ extern int tx_equalizer[4]; extern int enable_rx_equalizer; extern int rx_equalizer[4]; -extern int deviation; extern int pre_emphasize; extern int vox_setting; @@ -244,9 +245,12 @@ extern int diversity_enabled; extern double i_rotate[2]; extern double q_rotate[2]; +extern double meter_calibration; +extern double display_calibration; + extern void reconfigure_radio(); extern void start_radio(); -extern void init_radio(); +//extern void init_radio(); extern void radio_change_receivers(int r); extern void radio_change_sample_rate(int rate); extern void setMox(int state); @@ -254,13 +258,14 @@ extern int getMox(); extern void setTune(int state); extern int getTune(); extern void setVox(int state); -extern int vox_changed(void *data); +extern void vox_changed(int state); extern double getDrive(); extern void setDrive(double d); extern void calcDriveLevel(); extern double getTuneDrive(); extern void setTuneDrive(double d); extern void calcTuneDriveLevel(); +extern void setSquelch(RECEIVER *rx); extern void set_attenuation(int value); extern int get_attenuation(); @@ -280,4 +285,17 @@ extern void calculate_display_average(); extern void set_filter_type(int filter_type); extern void set_filter_size(int filter_size); + +extern void radio_cw_setup(); + +extern void radio_cw_key(int state); + +#ifdef FREEDV +extern void set_freedv(int state); +#endif + +extern void radio_change_region(int region); + +extern void disable_rigctl(); + #endif diff --git a/radio_menu.c b/radio_menu.c index 8e62c11..7d4dd17 100644 --- a/radio_menu.c +++ b/radio_menu.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include "new_menu.h" @@ -28,6 +30,8 @@ #include "filter.h" #include "radio.h" #include "receiver.h" +#include "new_protocol.h" +#include "old_protocol.h" static GtkWidget *parent_window=NULL; @@ -35,15 +39,24 @@ static GtkWidget *menu_b=NULL; static GtkWidget *dialog=NULL; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static void vfo_divisor_value_changed_cb(GtkWidget *widget, gpointer data) { vfo_encoder_divisor=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); } @@ -142,19 +155,26 @@ static void apollo_cb(GtkWidget *widget, gpointer data) { } static void sample_rate_cb(GtkWidget *widget, gpointer data) { - radio_change_sample_rate((int)data); + radio_change_sample_rate((uintptr_t)data); } static void receivers_cb(GtkWidget *widget, gpointer data) { - radio_change_receivers((int)data); + radio_change_receivers((uintptr_t)data); +} + +static void region_cb(GtkWidget *widget, gpointer data) { + radio_change_region(gtk_combo_box_get_active (GTK_COMBO_BOX(widget))); +/* + radio_change_region((uintptr_t)data); +*/ } static void rit_cb(GtkWidget *widget,gpointer data) { - rit_increment=(int)data; + rit_increment=(uintptr_t)data; } static void ck10mhz_cb(GtkWidget *widget, gpointer data) { - atlas_clock_source_10mhz = (int)data; + atlas_clock_source_10mhz = (uintptr_t)data; } static void ck128mhz_cb(GtkWidget *widget, gpointer data) { @@ -174,7 +194,9 @@ void radio_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - Radio"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -195,6 +217,28 @@ void radio_menu(GtkWidget *parent) { g_signal_connect (close_b, "button_press_event", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); + GtkWidget *region_label=gtk_label_new("Region: "); + gtk_grid_attach(GTK_GRID(grid),region_label,1,0,1,1); + + GtkWidget *region_combo=gtk_combo_box_text_new(); + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(region_combo),NULL,"Other"); + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(region_combo),NULL,"UK"); + gtk_combo_box_set_active(GTK_COMBO_BOX(region_combo),region); + gtk_grid_attach(GTK_GRID(grid),region_combo,2,0,1,1); + g_signal_connect(region_combo,"changed",G_CALLBACK(region_cb),NULL); + +/* + GtkWidget *uk_region=gtk_radio_button_new_with_label(NULL,"UK"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (uk_region), region==REGION_UK); + gtk_grid_attach(GTK_GRID(grid),uk_region,2,0,1,1); + g_signal_connect(uk_region,"pressed",G_CALLBACK(region_cb),(gpointer)REGION_UK); + + GtkWidget *other_region=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(uk_region),"Other"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (other_region),region==REGION_OTHER); + gtk_grid_attach(GTK_GRID(grid),other_region,3,0,1,1); + g_signal_connect(other_region,"pressed",G_CALLBACK(region_cb),(gpointer)REGION_OTHER); +*/ + int x=0; GtkWidget *receivers_label=gtk_label_new("Receivers: "); @@ -277,8 +321,6 @@ void radio_menu(GtkWidget *parent) { } break; #endif - - } @@ -327,10 +369,10 @@ void radio_menu(GtkWidget *parent) { } - GtkWidget *rit_label=gtk_label_new("RIT step: "); + GtkWidget *rit_label=gtk_label_new("RIT step (Hz): "); gtk_grid_attach(GTK_GRID(grid),rit_label,x,1,1,1); - GtkWidget *rit_1=gtk_radio_button_new_with_label(NULL,"1 Hz"); + GtkWidget *rit_1=gtk_radio_button_new_with_label(NULL,"1"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rit_1), rit_increment==1); gtk_grid_attach(GTK_GRID(grid),rit_1,x,2,1,1); g_signal_connect(rit_1,"pressed",G_CALLBACK(rit_cb),(gpointer *)1); diff --git a/radio_menu.h b/radio_menu.h index 9cd8b93..bd43812 100644 --- a/radio_menu.h +++ b/radio_menu.h @@ -17,4 +17,4 @@ * */ -extern void general_menu(GtkWidget *parent); +extern void radio_menu(GtkWidget *parent); diff --git a/radioberry.c b/radioberry.c index b4cf2f7..712e724 100644 --- a/radioberry.c +++ b/radioberry.c @@ -45,8 +45,10 @@ #include "receiver.h" #include "transmitter.h" #include "vfo.h" + #include +#define OUTPUT_BUFFER_SIZE 1024 #define SPEED_48K 0x00 #define SPEED_96K 0x01 #define SPEED_192K 0x02 @@ -63,28 +65,28 @@ static pthread_t radioberry_thread_id; static void start_radioberry_thread(); static void *radioberry_thread(void* arg); -static void setSampleSpeed(int r); -static void handleReceiveStream(int r); +static void setSampleSpeed(); +static void handleReceiveStream(); -struct timeval rx1_t0; -struct timeval rx1_t1; -struct timeval rx2_t0; -struct timeval rx2_t1; +struct timeval t0; +struct timeval t1; struct timeval t10; struct timeval t11; struct timeval t20; struct timeval t21; float elapsed; +#define RADIOSTATE_RX 0 +#define RADIOSTATE_TX 1 +static int radiostate = RADIOSTATE_RX; + void spiWriter(); -void rx1_spiReader(); -void rx2_spiReader(); +void spiReader(); int prev_drive_level; -static int rx1_count =0; -static int rx2_count =0; +static int rxcount =0; static int txcount =0; sem_t mutex; @@ -94,8 +96,7 @@ static int psk_samples=0; static int psk_divisor=6; #endif -static int rx1_spi_handler; -static int rx2_spi_handler; +static int h; float timedifference_msec(struct timeval t0, struct timeval t1) @@ -118,25 +119,20 @@ void radioberry_protocol_init(int rx,int pixels) { } #endif - gpioSetMode(13, PI_INPUT); //rx1_FIFOEmpty - gpioSetMode(16, PI_INPUT); //rx2_FIFOEmpty + gpioSetMode(13, PI_INPUT); gpioSetMode(20, PI_INPUT); gpioSetMode(21, PI_OUTPUT); - rx1_spi_handler = spiOpen(0, 15625000, 49155); //channel 0 - if (rx1_spi_handler < 0) { - fprintf(stderr,"radioberry_protocol: spi bus rx1 could not be initialized. \n"); + h = spiOpen(0, 15625000, 49155); + if (h < 0) { + fprintf(stderr,"radioberry_protocol: spi bus could not be initialized. \n"); exit(-1); } - rx2_spi_handler = spiOpen(1, 15625000, 49155); //channel 1 - if (rx2_spi_handler < 0) { - fprintf(stderr,"radioberry_protocol: spi bus rx2 could not be initialized. \n"); - exit(-1); - } - printf("init done \n"); - + + setSampleSpeed(); + if(transmitter->local_microphone) { if(audio_open_input()!=0) { fprintf(stderr,"audio_open_input failed\n"); @@ -163,52 +159,38 @@ static void *radioberry_thread(void* arg) { running=1; gettimeofday(&t20, 0); - gettimeofday(&rx1_t0, 0); - gettimeofday(&rx2_t0, 0); + gettimeofday(&t0, 0); gpioSetMode(13, PI_INPUT); - gpioSetMode(16, PI_INPUT); gpioSetMode(20, PI_INPUT); gpioSetMode(21, PI_OUTPUT); while(running) { - if (!isTransmitting()) + sem_wait(&mutex); + + if (isTransmitting()) + radiostate = RADIOSTATE_TX; + else + radiostate = RADIOSTATE_RX; + + if(radiostate == RADIOSTATE_TX) { + gpioWrite(21, 1); + } + else { - sem_wait(&mutex); - gpioWrite(21, 0); - - //possible to use different sample rates per receiver... - //if the sample rate differs between the receivers.. the highest sample rate - //must be called an extra time. - if (receivers==1){ - rx1_spiReader(); - } else { - if (receiver[0]->sample_rate == receiver[1]->sample_rate) { - rx1_spiReader(); - rx2_spiReader(); - } else { - if (receiver[0]->sample_rate > receiver[1]->sample_rate) { - rx1_spiReader(); - rx1_spiReader(); - rx2_spiReader(); - } else { - rx1_spiReader(); - rx2_spiReader(); - rx2_spiReader(); - } - } - } + spiReader(); + handleReceiveStream(); sem_post(&mutex); } } } void radioberry_protocol_iq_samples(int isample,int qsample) { + + if(radiostate == RADIOSTATE_TX) { - sem_wait(&mutex); - tx_iqdata[0] = 0; tx_iqdata[1] = drive / 6.4; // convert drive level from 0-255 to 0-39 ) if (prev_drive_level != drive) { @@ -221,8 +203,10 @@ void radioberry_protocol_iq_samples(int isample,int qsample) { tx_iqdata[5] = qsample; spiWriter(); - + sem_post(&mutex); + } + } void *radioberry_protocol_process_local_mic(unsigned char *buffer,int le) { @@ -238,15 +222,20 @@ void *radioberry_protocol_process_local_mic(unsigned char *buffer,int le) { } else { mic_sample = (short)((buffer[b++]<<8) | (buffer[b++]&0xFF)); } - add_mic_sample(transmitter,mic_sample); + if(active_receiver->freedv) { + add_freedv_mic_sample(transmitter,mic_sample); + } else { + add_mic_sample(transmitter,mic_sample); + } } } -static void handleReceiveStream(int r) { +static void handleReceiveStream() { int left_sample; int right_sample; double left_sample_double; double right_sample_double; + int r; left_sample = (int)((signed char) iqdata[0]) << 16; left_sample += (int)((unsigned char)iqdata[1]) << 8; @@ -258,14 +247,13 @@ static void handleReceiveStream(int r) { 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 - // add the samples to the receiver.. - add_iq_samples(receiver[r], left_sample_double,right_sample_double); - + for(r=0;rsample_rate) { +void setSampleSpeed() { + switch(active_receiver->sample_rate) { case 48000: sampleSpeed=SPEED_48K; break; @@ -285,10 +273,8 @@ void radioberry_protocol_stop() { running=FALSE; - if (rx1_spi_handler !=0) - spiClose(rx1_spi_handler); - if (rx2_spi_handler !=0) - spiClose(rx2_spi_handler); + if (h !=0) + spiClose(h); #ifndef GPIO gpioTerminate(); @@ -296,110 +282,47 @@ void radioberry_protocol_stop() { } -void rx1_spiReader() { +void spiReader() { // wait till rxFIFO buffer is filled with at least one element while ( gpioRead(13) == 1) {}; - setSampleSpeed(0); - - long long rxFrequency=vfo[0].frequency-vfo[0].lo; - if(vfo[0].rit_enabled) { - rxFrequency+=vfo[0].rit; - } - if (active_receiver->id==0) { - if(vfo[0].mode==modeCWU) { - rxFrequency-=(long long)cw_keyer_sidetone_frequency; - } else if(vfo[0].mode==modeCWL) { - rxFrequency+=(long long)cw_keyer_sidetone_frequency; - } - } + setSampleSpeed(); - iqdata[0] = (sampleSpeed & 0x03); - iqdata[1] = (((active_receiver->random << 6) & 0x40) | ((active_receiver->dither <<5) & 0x20) | (attenuation & 0x1F)); - iqdata[2] = ((rxFrequency >> 24) & 0xFF); - iqdata[3] = ((rxFrequency >> 16) & 0xFF); - iqdata[4] = ((rxFrequency >> 8) & 0xFF); - iqdata[5] = (rxFrequency & 0xFF); - - spiXfer(rx1_spi_handler, iqdata, iqdata, 6); - - //firmware: tdata(56'h00010203040506) -> 0-1-2-3-4-5-6 (element 0 contains 0; second element contains 1) - rx1_count ++; - if (rx1_count == 48000) { - rx1_count = 0; - gettimeofday(&rx1_t1, 0); - elapsed = timedifference_msec(rx1_t0, rx1_t1); - printf("Code rx1 mode spi executed in %f milliseconds.\n", elapsed); - gettimeofday(&rx1_t0, 0); + int v=receiver[0]->id; + long long rxFrequency=vfo[v].frequency-vfo[v].lo; + if(vfo[v].rit_enabled) { + rxFrequency+=vfo[v].rit; } - - handleReceiveStream(0); -} - -void rx2_spiReader() { - - // wait till rx2FIFO buffer is filled with at least one element - while ( gpioRead(16) == 1) {}; - - setSampleSpeed(1); - - long long rxFrequency=vfo[1].frequency-vfo[1].lo; - if(vfo[1].rit_enabled) { - rxFrequency+=vfo[1].rit; - } - if (active_receiver->id==1) { - if(vfo[1].mode==modeCWU) { - rxFrequency-=(long long)cw_keyer_sidetone_frequency; - } else if(vfo[1].mode==modeCWL) { - rxFrequency+=(long long)cw_keyer_sidetone_frequency; - } + if(vfo[active_receiver->id].mode==modeCWU) { + rxFrequency-=(long long)cw_keyer_sidetone_frequency; + } else if(vfo[active_receiver->id].mode==modeCWL) { + rxFrequency+=(long long)cw_keyer_sidetone_frequency; } iqdata[0] = (sampleSpeed & 0x03); - iqdata[1] = 0x00; //not used by firmware; the active receiver settings are set via rx1 + iqdata[1] = (((active_receiver->random << 6) & 0x40) | ((active_receiver->dither <<5) & 0x20) | (attenuation & 0x1F)); iqdata[2] = ((rxFrequency >> 24) & 0xFF); iqdata[3] = ((rxFrequency >> 16) & 0xFF); iqdata[4] = ((rxFrequency >> 8) & 0xFF); iqdata[5] = (rxFrequency & 0xFF); - spiXfer(rx2_spi_handler, iqdata, iqdata, 6); + spiXfer(h, iqdata, iqdata, 6); //firmware: tdata(56'h00010203040506) -> 0-1-2-3-4-5-6 (element 0 contains 0; second element contains 1) - rx2_count ++; - if (rx2_count == 48000) { - rx2_count = 0; - gettimeofday(&rx2_t1, 0); - elapsed = timedifference_msec(rx2_t0, rx2_t1); - printf("Code rx2 mode spi executed in %f milliseconds.\n", elapsed); - gettimeofday(&rx2_t0, 0); + rxcount ++; + if (rxcount == 48000) { + rxcount = 0; + gettimeofday(&t1, 0); + elapsed = timedifference_msec(t0, t1); + printf("Code rx mode spi executed in %f milliseconds.\n", elapsed); + gettimeofday(&t0, 0); } - - handleReceiveStream(1); } - void spiWriter() { - - gpioWrite(21, 1); - while ( gpioRead(20) == 1) {}; - spiXfer(rx1_spi_handler, tx_iqdata, tx_iqdata, 6); - - long long txFrequency; - if(split) { - txFrequency=vfo[VFO_B].frequency-vfo[VFO_A].lo+vfo[VFO_B].offset; - } else { - txFrequency=vfo[VFO_A].frequency-vfo[VFO_B].lo+vfo[VFO_A].offset; - } - tx_iqdata[0] = 0x00; - tx_iqdata[1] = 0x00; - tx_iqdata[2] = ((txFrequency >> 24) & 0xFF); - tx_iqdata[3] = ((txFrequency >> 16) & 0xFF); - tx_iqdata[4] = ((txFrequency >> 8) & 0xFF); - tx_iqdata[5] = (txFrequency & 0xFF); - - spiXfer(rx2_spi_handler, tx_iqdata, tx_iqdata, 6); + spiXfer(h, tx_iqdata, tx_iqdata, 6); txcount ++; if (txcount == 48000) { diff --git a/receiver.c b/receiver.c index 6bad5f3..197252c 100644 --- a/receiver.c +++ b/receiver.c @@ -25,8 +25,10 @@ #include #include "agc.h" +#include "audio.h" #include "band.h" #include "bandstack.h" +#include "channel.h" #include "discovered.h" #include "filter.h" #include "main.h" @@ -40,6 +42,7 @@ #include "property.h" #include "radio.h" #include "receiver.h" +#include "transmitter.h" #include "vfo.h" #include "meter.h" #include "rx_panadapter.h" @@ -48,18 +51,17 @@ #ifdef FREEDV #include "freedv.h" #endif +#include "audio_waterfall.h" #ifdef RADIOBERRY #include "radioberry.h" #endif +#include "ext.h" +#include "new_menu.h" #define min(x,y) (xid, obj); +} + gboolean receiver_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data) { RECEIVER *rx=(RECEIVER *)data; if(rx==active_receiver) { @@ -90,8 +100,9 @@ gboolean receiver_button_release_event(GtkWidget *widget, GdkEventButton *event, if(making_active) { active_receiver=rx; making_active=FALSE; - g_idle_add(vfo_update,NULL); - g_idle_add(active_receiver_changed,NULL); + g_idle_add(menu_active_receiver_changed,NULL); + g_idle_add(ext_vfo_update,NULL); + g_idle_add(sliders_active_receiver_changed,NULL); } else { int display_width=gtk_widget_get_allocated_width (rx->panadapter); int display_height=gtk_widget_get_allocated_height (rx->panadapter); @@ -223,6 +234,12 @@ void receiver_save_state(RECEIVER *rx) { sprintf(name,"receiver.%d.preamp",rx->id); sprintf(value,"%d",rx->preamp); setProperty(name,value); + sprintf(name,"receiver.%d.nb",rx->id); + sprintf(value,"%d",rx->nb); + setProperty(name,value); + sprintf(name,"receiver.%d.nb2",rx->id); + sprintf(value,"%d",rx->nb2); + setProperty(name,value); sprintf(name,"receiver.%d.nr",rx->id); sprintf(value,"%d",rx->nr); setProperty(name,value); @@ -260,10 +277,30 @@ void receiver_save_state(RECEIVER *rx) { sprintf(name,"receiver.%d.audio_device",rx->id); sprintf(value,"%d",rx->audio_device); setProperty(name,value); + sprintf(name,"receiver.%d.mute_radio",rx->id); + sprintf(value,"%d",rx->mute_radio); + setProperty(name,value); sprintf(name,"receiver.%d.low_latency",rx->id); sprintf(value,"%d",rx->low_latency); setProperty(name,value); + + sprintf(name,"receiver.%d.deviation",rx->id); + sprintf(value,"%d",rx->deviation); + setProperty(name,value); + + sprintf(name,"receiver.%d.squelch_enable",rx->id); + sprintf(value,"%d",rx->squelch_enable); + setProperty(name,value); + sprintf(name,"receiver.%d.squelch",rx->id); + sprintf(value,"%f",rx->squelch); + setProperty(name,value); + +#ifdef FREEDV + sprintf(name,"receiver.%d.freedv",rx->id); + sprintf(value,"%d",rx->freedv); + setProperty(name,value); +#endif } void receiver_restore_state(RECEIVER *rx) { @@ -356,6 +393,12 @@ fprintf(stderr,"receiver_restore_state: id=%d\n",rx->id); sprintf(name,"receiver.%d.preamp",rx->id); value=getProperty(name); if(value) rx->preamp=atoi(value); + sprintf(name,"receiver.%d.nb",rx->id); + value=getProperty(name); + if(value) rx->nb=atoi(value); + sprintf(name,"receiver.%d.nb2",rx->id); + value=getProperty(name); + if(value) rx->nb2=atoi(value); sprintf(name,"receiver.%d.nr",rx->id); value=getProperty(name); if(value) rx->nr=atoi(value); @@ -393,9 +436,29 @@ fprintf(stderr,"receiver_restore_state: id=%d\n",rx->id); sprintf(name,"receiver.%d.audio_device",rx->id); value=getProperty(name); if(value) rx->audio_device=atoi(value); + sprintf(name,"receiver.%d.mute_radio",rx->id); + value=getProperty(name); + if(value) rx->mute_radio=atoi(value); sprintf(name,"receiver.%d.low_latency",rx->id); value=getProperty(name); if(value) rx->low_latency=atoi(value); + + sprintf(name,"receiver.%d.deviation",rx->id); + value=getProperty(name); + if(value) rx->deviation=atoi(value); + + sprintf(name,"receiver.%d.squelch_enable",rx->id); + value=getProperty(name); + if(value) rx->squelch_enable=atoi(value); + sprintf(name,"receiver.%d.squelch",rx->id); + value=getProperty(name); + if(value) rx->squelch=atof(value); + +#ifdef FREEDV + sprintf(name,"receiver.%d.freedv",rx->id); + value=getProperty(name); + if(value) rx->freedv=atoi(value); +#endif } void reconfigure_receiver(RECEIVER *rx,int height) { @@ -459,6 +522,8 @@ static gint update_display(gpointer data) { RECEIVER *rx=(RECEIVER *)data; int rc; +//fprintf(stderr,"update_display: %d displaying=%d\n",rx->id,rx->displaying); + if(rx->displaying) { GetPixels(rx->id,0,rx->pixel_samples,&rc); if(rc) { @@ -479,8 +544,18 @@ static gint update_display(gpointer data) { } } +#ifdef AUDIO_SAMPLES + if(audio_samples!=NULL) { + GetPixels(CHANNEL_AUDIO,0,audio_samples,&rc); + if(rc) { + //audio_waterfall_update(); + } + } +#endif + + if(active_receiver==rx) { - double m=GetRXAMeter(rx->id,smeter); + double m=GetRXAMeter(rx->id,smeter)+meter_calibration; meter_update(SMETER,m,0.0,0.0,0.0); } return TRUE; @@ -497,14 +572,6 @@ void set_displaying(RECEIVER *rx,int state) { void set_mode(RECEIVER *rx,int m) { int local_mode=m; -#ifdef FREEDV - if(vfo[rx->d].mode!=modeFREEDV && m==modeFREEDV) { - local_mode=modeUSB; - init_freedv(); - } else if(vfo[rx->id].mode==modeFREEDV && m!=modeFREEDV) { - close_freedv(); - } -#endif #ifdef PSK if(vfo[rx->id].mode!=modePSK && m==modePSK) { local_mode=modeUSB; @@ -534,8 +601,8 @@ void set_filter(RECEIVER *rx,int low,int high) { RXASetPassband(rx->id,(double)rx->filter_low,(double)rx->filter_high); } -void set_deviation(RECEIVER *rx,double deviation) { - SetRXAFMDeviation(rx->id, deviation); +void set_deviation(RECEIVER *rx) { + SetRXAFMDeviation(rx->id, (double)rx->deviation); } void set_agc(RECEIVER *rx, int agc) { @@ -643,8 +710,9 @@ static void init_analyzer(RECEIVER *rx) { static void create_visual(RECEIVER *rx) { int y=0; -fprintf(stderr,"receiver: create_visual: id=%d width=%d height=%d\n",rx->id, rx->width, rx->height); rx->panel=gtk_fixed_new(); +fprintf(stderr,"receiver: create_visual: id=%d width=%d height=%d %p\n",rx->id, rx->width, rx->height, rx->panel); + g_object_weak_ref(G_OBJECT(rx->panel),receiver_weak_notify,(gpointer)rx); gtk_widget_set_size_request (rx->panel, rx->width, rx->height); rx->panadapter=NULL; @@ -655,27 +723,128 @@ fprintf(stderr,"receiver: create_visual: id=%d width=%d height=%d\n",rx->id, rx- height=height/2; } -fprintf(stderr,"receiver: panadapter_init: height=%d y=%d\n",height,y); rx_panadapter_init(rx, rx->width,height); +fprintf(stderr,"receiver: panadapter_init: height=%d y=%d %p\n",height,y,rx->panadapter); + g_object_weak_ref(G_OBJECT(rx->panadapter),receiver_weak_notify,(gpointer)rx); gtk_fixed_put(GTK_FIXED(rx->panel),rx->panadapter,0,y); y+=height; if(rx->display_waterfall) { -fprintf(stderr,"receiver: waterfall_init: height=%d y=%d\n",height,y); waterfall_init(rx,rx->width,height); +fprintf(stderr,"receiver: waterfall_init: height=%d y=%d %p\n",height,y,rx->waterfall); + g_object_weak_ref(G_OBJECT(rx->waterfall),receiver_weak_notify,(gpointer)rx); gtk_fixed_put(GTK_FIXED(rx->panel),rx->waterfall,0,y); } + + gtk_widget_show_all(rx->panel); } +#ifdef PURESIGNAL +RECEIVER *create_pure_signal_receiver(int id, int buffer_size,int sample_rate,int pixels) { +fprintf(stderr,"create_pure_signal_receiver: id=%d buffer_size=%d\n",id,buffer_size); + RECEIVER *rx=malloc(sizeof(RECEIVER)); + rx->id=id; + + rx->ddc=4; + rx->adc=0; // one more than actual adc + + rx->sample_rate=sample_rate; + rx->buffer_size=buffer_size; + rx->fft_size=fft_size; + rx->pixels=0; + rx->fps=0; + + rx->width=0; + rx->height=0; + rx->display_panadapter=0; + rx->display_waterfall=0; + + // allocate buffers + rx->iq_sequence=0; + rx->iq_input_buffer=malloc(sizeof(double)*2*rx->buffer_size); + rx->audio_buffer=NULL; + rx->audio_sequence=0L; + rx->pixel_samples=malloc(sizeof(float)*pixels); + + rx->samples=0; + rx->displaying=0; + rx->display_panadapter=0; + rx->display_waterfall=0; + + rx->panadapter_high=-40; + rx->panadapter_low=-140; + + rx->volume=0.0; + rx->attenuation=0; + + rx->dither=0; + rx->random=0; + rx->preamp=0; + + rx->nb=0; + rx->nb2=0; + rx->nr=0; + rx->nr2=0; + rx->anf=0; + rx->snb=0; + + rx->nr_agc=0; + rx->nr2_gain_method=2; + rx->nr2_npe_method=0; + rx->nr2_ae=1; + + rx->alex_antenna=0; + rx->alex_attenuation=0; + + rx->agc=AGC_MEDIUM; + rx->agc_gain=80.0; + rx->agc_slope=35.0; + rx->agc_hang_threshold=0.0; + + rx->playback_handle=NULL; + rx->playback_buffer=NULL; + rx->local_audio=0; + rx->mute_when_not_active=0; + rx->audio_channel=STEREO; + rx->audio_device=-1; + rx->mute_radio=0; + + rx->low_latency=0; + + int result; + XCreateAnalyzer(rx->id, &result, 262144, 1, 1, ""); + if(result != 0) { + fprintf(stderr, "XCreateAnalyzer id=%d failed: %d\n", rx->id, result); + } else { + init_analyzer(rx); + } + + SetDisplayDetectorMode(rx->id, 0, display_detector_mode); + SetDisplayAverageMode(rx->id, 0, display_average_mode); + + return rx; +} +#endif + RECEIVER *create_receiver(int id, int buffer_size, int fft_size, int pixels, int fps, int width, int height) { fprintf(stderr,"create_receiver: id=%d buffer_size=%d fft_size=%d pixels=%d fps=%d\n",id,buffer_size, fft_size, pixels, fps); RECEIVER *rx=malloc(sizeof(RECEIVER)); rx->id=id; switch(id) { case 0: + if(protocol==NEW_PROTOCOL && device==NEW_DEVICE_HERMES) { + rx->ddc=0; + } else { + rx->ddc=2; + } rx->adc=0; break; default: + if(protocol==NEW_PROTOCOL && device==NEW_DEVICE_HERMES) { + rx->ddc=1; + } else { + rx->ddc=3; + } switch(protocol) { case ORIGINAL_PROTOCOL: #ifdef RADIOBERRY @@ -708,24 +877,22 @@ fprintf(stderr,"create_receiver: id=%d buffer_size=%d fft_size=%d pixels=%d fps= break; } } -fprintf(stderr,"create_receiver: id=%d default adc=%d\n",rx->id, rx->adc); +fprintf(stderr,"create_receiver: id=%d default ddc=%d adc=%d\n",rx->id, rx->ddc, rx->adc); rx->sample_rate=48000; rx->buffer_size=buffer_size; rx->fft_size=fft_size; rx->pixels=pixels; rx->fps=fps; - BAND *b=band_get_band(vfo[rx->id].band); // rx->dds_offset=0; // rx->rit=0; rx->width=width; rx->height=height; - rx->display_panadapter=1; - rx->display_waterfall=1; // allocate buffers + rx->iq_sequence=0; rx->iq_input_buffer=malloc(sizeof(double)*2*rx->buffer_size); rx->audio_buffer=malloc(AUDIO_BUFFER_SIZE); rx->audio_sequence=0L; @@ -739,13 +906,19 @@ fprintf(stderr,"create_receiver: id=%d default adc=%d\n",rx->id, rx->adc); rx->panadapter_high=-40; rx->panadapter_low=-140; - rx->volume=0.2; + rx->waterfall_high=-40; + rx->waterfall_low=-140; + rx->waterfall_automatic=1; + + rx->volume=0.1; rx->attenuation=0; rx->dither=0; rx->random=0; rx->preamp=0; + rx->nb=0; + rx->nb2=0; rx->nr=0; rx->nr2=0; rx->anf=0; @@ -756,6 +929,7 @@ fprintf(stderr,"create_receiver: id=%d default adc=%d\n",rx->id, rx->adc); rx->nr2_npe_method=0; rx->nr2_ae=1; + BAND *b=band_get_band(vfo[rx->id].band); rx->alex_antenna=b->alexRxAntenna; rx->alex_attenuation=b->alexAttenuation; @@ -772,17 +946,36 @@ fprintf(stderr,"create_receiver: id=%d default adc=%d\n",rx->id, rx->adc); rx->low_latency=0; + rx->squelch_enable=0; + rx->squelch=0; + + rx->filter_high=525; + rx->filter_low=275; +#ifdef FREEDV + g_mutex_init(&rx->freedv_mutex); + rx->freedv=0; + rx->freedv_samples=0; + strcpy(rx->freedv_text_data,""); + rx->freedv_text_index=0; +#endif + + rx->deviation=2500; + + rx->mute_radio=0; + receiver_restore_state(rx); int scale=rx->sample_rate/48000; rx->output_samples=rx->buffer_size/scale; rx->audio_output_buffer=malloc(sizeof(double)*2*rx->output_samples); + fprintf(stderr,"create_receiver: id=%d output_samples=%d\n",rx->id,rx->output_samples); rx->hz_per_pixel=(double)rx->sample_rate/(double)rx->width; + // setup wdsp for this receiver -fprintf(stderr,"create_receiver: id=%d after restore adc=%d\n",rx->id, rx->adc); +fprintf(stderr,"create_receiver: id=%d after restore ddc=%d adc=%d\n",rx->id, rx->ddc, rx->adc); fprintf(stderr,"create_receiver: OpenChannel id=%d buffer_size=%d fft_size=%d sample_rate=%d\n", rx->id, @@ -799,26 +992,22 @@ fprintf(stderr,"create_receiver: OpenChannel id=%d buffer_size=%d fft_size=%d sa 1, // run 0.010, 0.025, 0.0, 0.010, 0); + create_anbEXT(rx->id,1,rx->buffer_size,rx->sample_rate,0.0001,0.0001,0.0001,0.05,20); + create_nobEXT(rx->id,1,0,rx->buffer_size,rx->sample_rate,0.0001,0.0001,0.0001,0.05,20); + fprintf(stderr,"RXASetNC %d\n",rx->fft_size); RXASetNC(rx->id, rx->fft_size); fprintf(stderr,"RXASetMP %d\n",rx->low_latency); RXASetMP(rx->id, rx->low_latency); - b=band_get_band(vfo[rx->id].band); - BANDSTACK *bs=b->bandstack; - BANDSTACK_ENTRY *entry=&bs->entry[vfo[rx->id].bandstack]; - FILTER *band_filters=filters[vfo[rx->id].mode]; - FILTER *band_filter=&band_filters[vfo[rx->id].filter]; - set_filter(rx,band_filter->low,band_filter->high); - - - SetRXAFMDeviation(rx->id,(double)deviation); - set_agc(rx, rx->agc); SetRXAAMDSBMode(rx->id, 0); SetRXAShiftRun(rx->id, 0); + SetEXTANBRun(rx->id, rx->nb); + SetEXTNOBRun(rx->id, rx->nb2); + SetRXAEMNRPosition(rx->id, rx->nr_agc); SetRXAEMNRgainMethod(rx->id, rx->nr2_gain_method); SetRXAEMNRnpeMethod(rx->id, rx->nr2_npe_method); @@ -830,9 +1019,18 @@ fprintf(stderr,"RXASetMP %d\n",rx->low_latency); SetRXAANFRun(rx->id, rx->anf); SetRXASNBARun(rx->id, rx->snb); + SetRXAPanelGain1(rx->id, rx->volume); SetRXAPanelBinaural(rx->id, binaural); - SetRXAPanelRun(rx->id, 1); +#ifdef FREEDV + if(rx->freedv) { + SetRXAPanelRun(rx->id, 0); + } else { +#endif + SetRXAPanelRun(rx->id, 1); +#ifdef FREEDV + } +#endif if(enable_rx_equalizer) { SetRXAGrphEQ(rx->id, rx_equalizer); @@ -843,9 +1041,12 @@ fprintf(stderr,"RXASetMP %d\n",rx->low_latency); // setup for diversity create_divEXT(0,0,2,rx->buffer_size); - SetEXTDIVRotate(0, 2, &i_rotate, &q_rotate); + SetEXTDIVRotate(0, 2, &i_rotate[0], &q_rotate[0]); SetEXTDIVRun(0,diversity_enabled); + receiver_mode_changed(rx); + //set_mode(rx,vfo[rx->id].mode); + //set_filter(rx,rx->filter_low,rx->filter_high); int result; XCreateAnalyzer(rx->id, &result, 262144, 1, 1, ""); @@ -858,6 +1059,12 @@ fprintf(stderr,"RXASetMP %d\n",rx->low_latency); SetDisplayDetectorMode(rx->id, 0, display_detector_mode); SetDisplayAverageMode(rx->id, 0, display_average_mode); +#ifdef FREEDV + if(rx->freedv) { + init_freedv(rx); + } +#endif + calculate_display_average(rx); create_visual(rx); @@ -875,21 +1082,19 @@ void receiver_change_adc(RECEIVER *rx,int adc) { void receiver_change_sample_rate(RECEIVER *rx,int sample_rate) { - rx->sample_rate=sample_rate; - SetChannelState(rx->id,0,1); + rx->sample_rate=sample_rate; int scale=rx->sample_rate/48000; rx->output_samples=rx->buffer_size/scale; free(rx->audio_output_buffer); rx->audio_output_buffer=malloc(sizeof(double)*2*rx->output_samples); rx->audio_buffer=malloc(AUDIO_BUFFER_SIZE); rx->hz_per_pixel=(double)rx->sample_rate/(double)rx->width; - SetInputSamplerate(rx->id, sample_rate); - init_analyzer(rx); - + SetEXTANBSamplerate (rx->id, sample_rate); + SetEXTNOBSamplerate (rx->id, sample_rate); fprintf(stderr,"receiver_change_sample_rate: id=%d rate=%d buffer_size=%d output_samples=%d\n",rx->id, rx->sample_rate, rx->buffer_size, rx->output_samples); SetChannelState(rx->id,1,0); } @@ -905,20 +1110,31 @@ void receiver_frequency_changed(RECEIVER *rx) { } } -void receiver_mode_changed(RECEIVER *rx) { - set_mode(rx,vfo[rx->id].mode); +void receiver_filter_changed(RECEIVER *rx) { + int m=vfo[rx->id].mode; + if(m==modeFMN) { + if(rx->deviation==2500) { + set_filter(rx,-4000,4000); + } else { + set_filter(rx,-8000,8000); + } + set_deviation(rx); + } else { + FILTER *mode_filters=filters[m]; + FILTER *filter=&mode_filters[vfo[rx->id].filter]; + set_filter(rx,filter->low,filter->high); + } } -void receiver_filter_changed(RECEIVER *rx) { - FILTER *mode_filters=filters[vfo[rx->id].mode]; - FILTER *filter=&mode_filters[vfo[rx->id].filter]; - set_filter(rx,filter->low,filter->high); +void receiver_mode_changed(RECEIVER *rx) { + set_mode(rx,vfo[rx->id].mode); + receiver_filter_changed(rx); } void receiver_vfo_changed(RECEIVER *rx) { receiver_frequency_changed(rx); receiver_mode_changed(rx); - receiver_filter_changed(rx); + //receiver_filter_changed(rx); } #ifdef FREEDV @@ -928,50 +1144,71 @@ static void process_freedv_rx_buffer(RECEIVER *rx) { int i; int demod_samples; for(i=0;ioutput_samples;i++) { - if(freedv_samples==0) { - left_audio_sample=(short)(rx->audio_output_buffer[i*2]*32767.0); - right_audio_sample=(short)(rx->audio_output_buffer[(i*2)+1]*32767.0); - demod_samples=demod_sample_freedv(left_audio_sample); + if(rx->freedv_samples==0) { + if(isTransmitting()) { + left_audio_sample=0; + right_audio_sample=0; + } else { + left_audio_sample=(short)(rx->audio_output_buffer[i*2]*32767.0); + right_audio_sample=(short)(rx->audio_output_buffer[(i*2)+1]*32767.0); + } + demod_samples=demod_sample_freedv((left_audio_sample+right_audio_sample)/2); if(demod_samples!=0) { int s; int t; for(s=0;svolume); } else { - left_audio_sample=right_audio_sample=0; + left_audio_sample=right_audio_sample=(short)((double)speech_out[s]*rx->volume); + //left_audio_sample=right_audio_sample=0; } - for(t=0;t<6;t++) { // 8k to 48k - if(local_audio) { - audio_write(left_audio_sample,right_audio_sample); - left_audio_sample=0; - right_audio_sample=0; + for(t=0;tlocal_audio) { + if(rx!=active_receiver && rx->mute_when_not_active) { + audio_write(rx,0,0); + } else { + switch(rx->audio_channel) { + case STEREO: + audio_write(rx,left_audio_sample,right_audio_sample); + break; + case LEFT: + audio_write(rx,left_audio_sample,0); + break; + case RIGHT: + audio_write(rx,0,right_audio_sample); + break; + } + } } - switch(protocol) { - case ORIGINAL_PROTOCOL: - old_protocol_audio_samples(left_audio_sample,right_audio_sample); - break; - case NEW_PROTOCOL: - new_protocol_audio_samples(left_audio_sample,right_audio_sample); - break; + if(rx==active_receiver) { + switch(protocol) { + case ORIGINAL_PROTOCOL: + old_protocol_audio_samples(rx,left_audio_sample,right_audio_sample); + break; + case NEW_PROTOCOL: + new_protocol_audio_samples(rx,left_audio_sample,right_audio_sample); + break; #ifdef LIMESDR - case LIMESDR_PROTOCOL: - break; + case LIMESDR_PROTOCOL: + break; #endif #ifdef RADIOBERRY - case RADIOBERRY_PROTOCOL: - //no audio stream to radioberry hardware, using local audio of rpi. - break; + case RADIOBERRY_PROTOCOL: + //no audio stream to radioberry hardware, using local audio of rpi. + break; #endif + } } } } } - freedv_samples++; - if(freedv_samples==freedv_resample) { - freedv_samples=0; - } + } + rx->freedv_samples++; + if(rx->freedv_samples>=freedv_resample) { + rx->freedv_samples=0; } } } @@ -1022,11 +1259,19 @@ static void process_rx_buffer(RECEIVER *rx) { if(rx==active_receiver) { switch(protocol) { case ORIGINAL_PROTOCOL: - old_protocol_audio_samples(rx,left_audio_sample,right_audio_sample); + if(rx->mute_radio) { + old_protocol_audio_samples(rx,(short)0,(short)0); + } else { + old_protocol_audio_samples(rx,left_audio_sample,right_audio_sample); + } break; case NEW_PROTOCOL: if(!(echo&&isTransmitting())) { - new_protocol_audio_samples(rx,left_audio_sample,right_audio_sample); + if(rx->mute_radio) { + new_protocol_audio_samples(rx,(short)0,(short)0); + } else { + new_protocol_audio_samples(rx,left_audio_sample,right_audio_sample); + } } break; #ifdef LIMESDR @@ -1039,6 +1284,24 @@ static void process_rx_buffer(RECEIVER *rx) { break; #endif } + +#ifdef AUDIO_WATERFALL + if(audio_samples!=NULL) { + if(waterfall_samples==0) { + audio_samples[audio_samples_index]=(float)left_audio_sample; + audio_samples_index++; + if(audio_samples_index>=AUDIO_WATERFALL_SAMPLES) { + //Spectrum(CHANNEL_AUDIO,0,0,audio_samples,audio_samples); + audio_samples_index=0; + } + } + waterfall_samples++; + if(waterfall_samples==waterfall_resample) { + waterfall_samples=0; + } + } +#endif + } } @@ -1048,6 +1311,14 @@ void full_rx_buffer(RECEIVER *rx) { int j; int error; + // noise blanker works on origianl IQ samples + if(rx->nb) { + xanbEXT (rx->id, rx->iq_input_buffer, rx->iq_input_buffer); + } + if(rx->nb2) { + xnobEXT (rx->id, rx->iq_input_buffer, rx->iq_input_buffer); + } + fexchange0(rx->id, rx->iq_input_buffer, rx->audio_output_buffer, &error); if(error!=0) { fprintf(stderr,"full_rx_buffer: id=%d fexchange0: error=%d\n",rx->id,error); @@ -1057,23 +1328,27 @@ void full_rx_buffer(RECEIVER *rx) { Spectrum0(1, rx->id, 0, 0, rx->iq_input_buffer); } - switch(vfo[rx->id].mode) { #ifdef FREEDV - case modeFREEDV: - process_freedv_rx_buffer(rx); - break; + g_mutex_lock(&rx->freedv_mutex); + if(rx->freedv) { + process_freedv_rx_buffer(rx); + } else { #endif - default: - process_rx_buffer(rx); - break; + process_rx_buffer(rx); +#ifdef FREEDV } + g_mutex_unlock(&rx->freedv_mutex); +#endif } +static int rx_buffer_seen=0; +static int tx_buffer_seen=0; + void add_iq_samples(RECEIVER *rx, double i_sample,double q_sample) { rx->iq_input_buffer[rx->samples*2]=i_sample; rx->iq_input_buffer[(rx->samples*2)+1]=q_sample; rx->samples=rx->samples+1; - if(rx->samples==rx->buffer_size) { + if(rx->samples>=rx->buffer_size) { full_rx_buffer(rx); rx->samples=0; } diff --git a/receiver.h b/receiver.h index 40cfc69..58546af 100644 --- a/receiver.h +++ b/receiver.h @@ -35,6 +35,7 @@ typedef enum _audio_t audio_t; typedef struct _receiver { int id; + int ddc; int adc; double volume; @@ -51,6 +52,7 @@ typedef struct _receiver { int pixels; int samples; int output_samples; + long iq_sequence; double *iq_input_buffer; double *audio_output_buffer; unsigned char *audio_buffer; @@ -63,17 +65,12 @@ typedef struct _receiver { double hz_per_pixel; -// long long frequency; -// long long display_frequency; -// long long dds_frequency; -// long long dds_offset; - -// int rit; - int dither; int random; int preamp; + int nb; + int nb2; int nr; int nr2; int anf; @@ -105,23 +102,42 @@ typedef struct _receiver { int waterfall_low; int waterfall_high; int waterfall_automatic; - cairo_surface_t *panadapter_surface; GdkPixbuf *pixbuf; - int local_audio; int mute_when_not_active; int audio_device; snd_pcm_t *playback_handle; int playback_offset; unsigned char *playback_buffer; - int low_latency; + int squelch_enable; + double squelch; + + int deviation; + + long long waterfall_frequency; + int waterfall_sample_rate; + + int mute_radio; + +#ifdef FREEDV + GMutex freedv_mutex; + int freedv; + int freedv_samples; + char freedv_text_data[64]; + int freedv_text_index; +#endif + + int x; + int y; } RECEIVER; +extern RECEIVER *create_pure_signal_receiver(int id, int buffer_size,int sample_rate,int pixels); extern RECEIVER *create_receiver(int id, int buffer_size, int fft_size, int pixels, int fps, int width, int height); extern void receiver_change_sample_rate(RECEIVER *rx,int sample_rate); +extern void receiver_change_adc(RECEIVER *rx,int adc); extern void receiver_frequency_changed(RECEIVER *rx); extern void receiver_mode_changed(RECEIVER *rx); extern void receiver_filter_changed(RECEIVER *rx); @@ -131,7 +147,7 @@ extern void set_mode(RECEIVER* rx,int m); extern void set_filter(RECEIVER *rx,int low,int high); extern void set_agc(RECEIVER *rx, int agc); extern void set_offset(RECEIVER *rx, long long offset); -extern void set_deviation(RECEIVER *rx, double deviation); +extern void set_deviation(RECEIVER *rx); extern void add_iq_samples(RECEIVER *rx, double i_sample,double q_sample); @@ -144,4 +160,6 @@ extern gboolean receiver_button_release_event(GtkWidget *widget, GdkEventButton extern gboolean receiver_motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data); extern gboolean receiver_scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data); +extern void set_displaying(RECEIVER *rx,int state); + #endif diff --git a/rigctl.c b/rigctl.c index 90b76dd..adb52a4 100644 --- a/rigctl.c +++ b/rigctl.c @@ -22,28 +22,37 @@ */ #include #include +#include +#include +#include +#include #include //#include #include +#include #include +#include "receiver.h" #include "toolbar.h" +#include "band_menu.h" #include "sliders.h" #include "rigctl.h" #include "radio.h" -#include "receiver.h" #include "channel.h" #include "filter.h" -#include #include "mode.h" #include "filter.h" #include "band.h" #include "bandstack.h" +#include "filter_menu.h" #include "vfo.h" #include "sliders.h" -#include +#include "transmitter.h" #include "agc.h" #include #include "store.h" +#include "ext.h" +#include "rigctl_menu.h" +#include // IP stuff below #include @@ -52,6 +61,9 @@ //#undef RIGCTL_DEBUG #define RIGCTL_DEBUG +int rigctl_port_base=19090; +int rigctl_enable=0; + // the port client will be connecting to // 2-26-17 K5JAE - Changed the defines to const ints to allow use via pointers. static const int TelnetPortA = 19090; @@ -61,8 +73,10 @@ static const int TelnetPortC = 19092; // max number of bytes we can get at once #define MAXDATASIZE 300 -int init_server (); void parse_cmd (); +int cw_busy = 0; // Used to signal that the system is in a busy state for sending CW - assert busy back to the user +int cw_reset = 0; // Signals reset the transceiver +int connect_cnt = 0; int rigctlGetFilterLow(); int rigctlGetFilterHigh(); @@ -70,27 +84,50 @@ int rigctlSetFilterLow(int val); int rigctlSetFilterHigh(int val); int new_level; int active_transmitter = 0; +int rigctl_busy = 0; // Used to tell rigctl_menu that launch has already occured int cat_control; extern int enable_tx_equalizer; +//extern int serial_baud_rate; +//extern int serial_parity; -/* -pthread_mutex_t mutex_a = PTHREAD_MUTEX_INITIALIZER; -pthread_mutex_t mutex_b = PTHREAD_MUTEX_INITIALIZER; -*/ typedef struct {GMutex m; } GT_MUTEX; GT_MUTEX * mutex_a; GT_MUTEX * mutex_b; +GT_MUTEX * mutex_c; +GT_MUTEX * mutex_d; + +int mutex_b_exists = 0; + FILE * out; int output; FILTER * band_filter; -//static pthread_t rigctl_a_thread_id, rigctl_b_thread_id, rigctl_c_thread_id; -static GThread *rigctl_a_thread_id, *rigctl_b_thread_id, *rigctl_c_thread_id; +#define MAX_CLIENTS 3 +static GThread *rigctl_server_thread_id = NULL; +static int server_running; + +static GThread *serial_server_thread_id = NULL; + +static int server_socket=-1; +static int server_address_length; +static struct sockaddr_in server_address; + +typedef struct _client { + int socket; + int address_length; + struct sockaddr_in address; + GThread *thread_id; +} CLIENT; -int squelch=100; //local sim of squelch level +int fd; // Serial port file descriptor + +static CLIENT client[MAX_CLIENTS]; + +int squelch=-160; //local sim of squelch level +int fine = 0; // FINE status for TS-2000 decides whether rit_increment is 1Hz/10Hz. int read_size; @@ -115,10 +152,261 @@ int mox_state = 0; int ctcss_tone; // Numbers 01-38 are legal values - set by CN command, read by CT command int ctcss_mode; // Numbers 0/1 - on off. +static gpointer rigctl_client (gpointer data); + +void close_rigctl_ports() { + int i; + struct linger linger = { 0 }; + linger.l_onoff = 1; + linger.l_linger = 0; + + fprintf(stderr,"close_rigctl_ports: server_socket=%d\n",server_socket); + server_running=0; + for(i=0;i=0) { + fprintf(stderr,"setting SO_LINGER to 0 for server_socket: %d\n",server_socket); + if(setsockopt(server_socket,SOL_SOCKET,SO_LINGER,(const char *)&linger,sizeof(linger))==-1) { + perror("setsockopt(...,SO_LINGER,...) failed for server"); + } + fprintf(stderr,"closing server_socket: %d\n",server_socket); + close(server_socket); + server_socket=-1; + } +} +// +// Used to convert transmitter->ctcss_frequency into 1-39 value for TS2000. +// This COULD be done with a simple table lookup - but I've already written the code +// so at this point... +// +int convert_ctcss() { + int local_tone = 1; + if(transmitter->ctcss_frequency == (double) 67.0) { + local_tone = 1; + } else if (transmitter->ctcss_frequency == (double) 71.9) { + local_tone = 2; + } else if (transmitter->ctcss_frequency == (double) 74.4) { + local_tone = 3; + } else if (transmitter->ctcss_frequency == (double) 77.0) { + local_tone = 4; + } else if (transmitter->ctcss_frequency == (double) 79.7) { + local_tone = 5; + } else if (transmitter->ctcss_frequency == (double) 82.5) { + local_tone = 6; + } else if (transmitter->ctcss_frequency == (double) 85.4) { + local_tone = 7; + } else if (transmitter->ctcss_frequency == (double) 88.5) { + local_tone = 8; + } else if (transmitter->ctcss_frequency == (double) 91.5) { + local_tone = 9; + } else if (transmitter->ctcss_frequency == (double) 94.8) { + local_tone = 10; + } else if (transmitter->ctcss_frequency == (double) 97.4) { + local_tone = 11; + } else if (transmitter->ctcss_frequency == (double) 100.0) { + local_tone = 12; + } else if (transmitter->ctcss_frequency == (double) 103.5) { + local_tone = 13; + } else if (transmitter->ctcss_frequency == (double) 107.2) { + local_tone = 14; + } else if (transmitter->ctcss_frequency == (double) 110.9) { + local_tone = 15; + } else if (transmitter->ctcss_frequency == (double) 114.8) { + local_tone = 16; + } else if (transmitter->ctcss_frequency == (double) 118.8) { + local_tone = 17; + } else if (transmitter->ctcss_frequency == (double) 123.0) { + local_tone = 18; + } else if (transmitter->ctcss_frequency == (double) 127.3) { + local_tone = 19; + } else if (transmitter->ctcss_frequency == (double) 131.8) { + local_tone = 20; + } else if (transmitter->ctcss_frequency == (double) 136.5) { + local_tone = 21; + } else if (transmitter->ctcss_frequency == (double) 141.3) { + local_tone = 22; + } else if (transmitter->ctcss_frequency == (double) 146.2) { + local_tone = 23; + } else if (transmitter->ctcss_frequency == (double) 151.4) { + local_tone = 24; + } else if (transmitter->ctcss_frequency == (double) 156.7) { + local_tone = 25; + } else if (transmitter->ctcss_frequency == (double) 162.2) { + local_tone = 26; + } else if (transmitter->ctcss_frequency == (double) 167.9) { + local_tone = 27; + } else if (transmitter->ctcss_frequency == (double) 173.8) { + local_tone = 28; + } else if (transmitter->ctcss_frequency == (double) 179.9) { + local_tone = 29; + } else if (transmitter->ctcss_frequency == (double) 186.2) { + local_tone = 30; + } else if (transmitter->ctcss_frequency == (double) 192.8) { + local_tone = 31; + } else if (transmitter->ctcss_frequency == (double) 203.5) { + local_tone = 32; + } else if (transmitter->ctcss_frequency == (double) 210.7) { + local_tone = 33; + } else if (transmitter->ctcss_frequency == (double) 218.1) { + local_tone = 34; + } else if (transmitter->ctcss_frequency == (double) 225.7) { + local_tone = 35; + } else if (transmitter->ctcss_frequency == (double) 233.6) { + local_tone = 36; + } else if (transmitter->ctcss_frequency == (double) 241.8) { + local_tone = 37; + } else if (transmitter->ctcss_frequency == (double) 250.3) { + local_tone = 38; + } else if (transmitter->ctcss_frequency == (double) 1750.0) { + local_tone = 39; + } + return(local_tone); +} int vfo_sm=0; // VFO State Machine - this keeps track of // Now my stuff // +void send_dash() { + //long delay = (1200000L * ((long)cw_keyer_weight/10L))/(long)cw_keyer_speed ; + int dot_delay = 1200/cw_keyer_speed; + int delay = (dot_delay * 3 * cw_keyer_weight)/50; + g_idle_add(ext_cw_key, (gpointer)(long)1); + usleep((long)delay*3000L); + g_idle_add(ext_cw_key, (gpointer)(long)0); + usleep((long)delay * 1000L); + //fprintf(stderr,"_%d",mox); + +} +void send_dot() { + int dot_delay = 1200/cw_keyer_speed; + g_idle_add(ext_cw_key, (gpointer)(long)1); + usleep((long)dot_delay * 1000L); + g_idle_add(ext_cw_key, (gpointer)(long)0); + usleep((long)dot_delay* 1000L); + //fprintf(stderr,".%d",mox); +} +void send_space() { + int dot_delay = 1200/cw_keyer_speed; + usleep((long)dot_delay* 7000L); + //fprintf(stderr," %d",mox); +} + +void rigctl_send_cw_char(char cw_char) { + char pattern[9],*ptr; + strcpy(pattern,""); + ptr = &pattern[0]; + switch (cw_char) { + case 'a': + case 'A': strcpy(pattern,".-"); break; + case 'b': + case 'B': strcpy(pattern,"-..."); break; + case 'c': + case 'C': strcpy(pattern,"-.-."); break; + case 'd': + case 'D': strcpy(pattern,"-.."); break; + case 'e': + case 'E': strcpy(pattern,"."); break; + case 'f': + case 'F': strcpy(pattern,"..-."); break; + case 'g': + case 'G': strcpy(pattern,"--."); break; + case 'h': + case 'H': strcpy(pattern,"...."); break; + case 'i': + case 'I': strcpy(pattern,".."); break; + case 'j': + case 'J': strcpy(pattern,".---"); break; + case 'k': + case 'K': strcpy(pattern,"-.-"); break; + case 'l': + case 'L': strcpy(pattern,".-.."); break; + case 'm': + case 'M': strcpy(pattern,"--"); break; + case 'n': + case 'N': strcpy(pattern,"-."); break; + case 'o': + case 'O': strcpy(pattern,"---"); break; + case 'p': + case 'P': strcpy(pattern,".--."); break; + case 'q': + case 'Q': strcpy(pattern,"-.--"); break; + case 'r': + case 'R': strcpy(pattern,".-."); break; + case 's': + case 'S': strcpy(pattern,"..."); break; + case 't': + case 'T': strcpy(pattern,"-"); break; + case 'u': + case 'U': strcpy(pattern,"..-"); break; + case 'v': + case 'V': strcpy(pattern,"...-"); break; + case 'w': + case 'W': strcpy(pattern,".--"); break; + case 'x': + case 'X': strcpy(pattern,"-..-"); break; + case 'z': + case 'Z': strcpy(pattern,"--.."); break; + case '0': strcpy(pattern,"-----"); break; + case '1': strcpy(pattern,".----"); break; + case '2': strcpy(pattern,"..---"); break; + case '3': strcpy(pattern,"...--"); break; + case '4': strcpy(pattern,"....-"); break; + case '5': strcpy(pattern,".....");break; + case '6': strcpy(pattern,"-....");break; + case '7': strcpy(pattern,"--...");break; + case '8': strcpy(pattern,"---..");break; + case '9': strcpy(pattern,"----.");break; + case '.': strcpy(pattern,".-.-.-");break; + case '/': strcpy(pattern,"-..-.");break; + case ',': strcpy(pattern,"--..--");break; + case '!': strcpy(pattern,"-.-.--");break; + case ')': strcpy(pattern,"-.--.-");break; + case '(': strcpy(pattern,"-.--.-");break; + case '&': strcpy(pattern,".-...");break; + case ':': strcpy(pattern,"---..");break; + case '+': strcpy(pattern,".-.-.");break; + case '-': strcpy(pattern,"-....-");break; + case '_': strcpy(pattern,".--.-.");break; + case '@': strcpy(pattern,"..--.-");break; + case ' ': strcpy(pattern," ");break; + default: strcpy(pattern," "); + } + //fprintf(stderr,"Sending %c:",cw_char); + g_idle_add(ext_cw_key, (gpointer)(long)0); + + while(*ptr != '\0') { + if(*ptr == '-') { + send_dash(); + } + if(*ptr == '.') { + send_dot(); + } + if(*ptr == ' ') { + send_space(); + } + ptr++; + } + // Need a delay HERE between characters + long delay = (1200000L * ((long)cw_keyer_weight/10L))/(long)cw_keyer_speed ; + usleep(delay*3L); + //fprintf(stderr,"\n"); +} +void gui_vfo_move_to(gpointer data) { + long long freq = *(long long *) data; + fprintf(stderr,"GUI: %11lld\n",freq); + return; + //vfo_move_to(freq); +} // This looks up the frequency of the Active receiver with // protection for 1 versus 2 receivers @@ -136,32 +424,107 @@ void send_resp (int client_sock,char * msg) { #ifdef RIGCTL_DEBUG fprintf(stderr,"RIGCTL: RESP=%s\n",msg); #endif - write(client_sock, msg, strlen(msg)); + if(client_sock == -1) { // Serial port + int bytes=write(fd,msg,strlen(msg)); + } else { // TCP/IP port + int bytes=write(client_sock, msg, strlen(msg)); + } } // // 2-25-17 - K5JAE - removed duplicate rigctl // -//static void * rigctl_a (void * arg) { -static gpointer rigctl (gpointer data) { +static gpointer rigctl_server(gpointer data) { + int port=(uintptr_t)data; + int rc; + int on=1; + int i; + + fprintf(stderr,"rigctl_server: starting server on port %d\n",port); + + server_socket=socket(AF_INET,SOCK_STREAM,0); + if(server_socket<0) { + perror("rigctl_server: listen socket failed"); + return NULL; + } + + setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + setsockopt(server_socket, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)); + + // bind to listening port + memset(&server_address,0,sizeof(server_address)); + server_address.sin_family=AF_INET; + server_address.sin_addr.s_addr=INADDR_ANY; + server_address.sin_port=htons(port); + if(bind(server_socket,(struct sockaddr*)&server_address,sizeof(server_address))<0) { + perror("rigctl_server: listen socket bind failed"); + close(server_socket); + return NULL; + } + + for(i=0;isocket); g_mutex_lock(&mutex_a->m); cat_control++; //#ifdef RIGCTL_DEBUG -fprintf(stderr,"RIGCTL: CTLA INC cat_contro=%d\n",cat_control); + fprintf(stderr,"RIGCTL: CTLA INC cat_contro=%d\n",cat_control); //#endif g_mutex_unlock(&mutex_a->m); - g_idle_add(vfo_update,NULL); + g_idle_add(ext_vfo_update,NULL); int save_flag = 0; // Used to concatenate two cmd lines together int semi_number = 0; @@ -171,10 +534,9 @@ fprintf(stderr,"RIGCTL: CTLA INC cat_contro=%d\n",cat_control); int numbytes; char cmd_input[MAXDATASIZE] ; char cmd_save[80]; + char cw_check_buf[4]; - for(;;) { - fprintf(stderr,"RIGCTL - New run on server port: %d\n", port); - while((numbytes=recv(client_sock , cmd_input , MAXDATASIZE-2 , 0)) > 0 ) { + while(server_running && (numbytes=recv(client->socket , cmd_input , MAXDATASIZE-2 , 0)) > 0 ) { for(i=0;i2) { + cw_check_buf[0] = work_ptr[0]; + cw_check_buf[1] = work_ptr[1]; + cw_check_buf[2] = '\0'; + if(strcmp("ZZ",cw_check_buf)==0) { + if(strlen(work_ptr)>4) { + cw_check_buf[0] = work_ptr[2]; + cw_check_buf[1] = work_ptr[3]; + cw_check_buf[2] = '\0'; + } else { + send_resp(client->socket,"?;"); + } + } + } else { + // Illegal Command + send_resp(client->socket,"?;"); + } + // Got here because we have a legal command in cw_check_buf + // Look for RESET and BUSY which re respond to else - send ?; + if(strcmp("BY",cw_check_buf)==0) { + send_resp(client->socket,"BY11;"); // Indicate that we are BUSY + } else if (strcmp("SR",cw_check_buf) == 0) { + // Reset the transceiver + g_mutex_lock(&mutex_c->m); + cw_reset = 1; + g_mutex_unlock(&mutex_c->m); + // Wait till BUSY clears + while(cw_busy); + g_mutex_lock(&mutex_c->m); + cw_reset = 0; + g_mutex_unlock(&mutex_c->m); + } + + } + // Lock so only one user goes into this at a time g_mutex_lock(&mutex_b->m); - parse_cmd(work_ptr,strlen(work_ptr),client_sock); - /* - pthread_mutex_unlock (& mutex_b); - */ + parse_cmd(work_ptr,strlen(work_ptr),client->socket); g_mutex_unlock(&mutex_b->m); work_ptr = strtok(NULL,";"); } @@ -224,35 +617,27 @@ fprintf(stderr,"RIGCTL: CTLA INC cat_contro=%d\n",cat_control); } // Got here because socket closed } - if(numbytes == 0) { - fprintf(stderr,"RIGCTL: Client disconnected\n"); - close(client_sock); - - // Decrement CAT_CONTROL - g_mutex_lock(&mutex_a->m); - cat_control--; -#ifdef RIGCTL_DEBUG -fprintf(stderr,"RIGCTL: CTLA DEC - cat_control=%d\n",cat_control); -#endif - g_mutex_unlock(&mutex_a->m); - g_idle_add(vfo_update,NULL); - - //sleep(1); - c = sizeof(struct sockaddr_in); - client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c); - - // Increment CAT_CONTROL - g_mutex_lock(&mutex_a->m); - cat_control++; +fprintf(stderr,"RIGCTL: Leaving rigctl_client thread"); + if(client->socket!=-1) { + fprintf(stderr,"setting SO_LINGER to 0 for client_socket: %d\n",client->socket); + struct linger linger = { 0 }; + linger.l_onoff = 1; + linger.l_linger = 0; + if(setsockopt(client->socket,SOL_SOCKET,SO_LINGER,(const char *)&linger,sizeof(linger))==-1) { + perror("setsockopt(...,SO_LINGER,...) failed for client"); + } + close(client->socket); + client->socket=-1; + // Decrement CAT_CONTROL + g_mutex_lock(&mutex_a->m); + cat_control--; #ifdef RIGCTL_DEBUG -fprintf(stderr,"RIGCTL: CTLA INC - cat_control=%d\n",cat_control); + fprintf(stderr,"RIGCTL: CTLA DEC - cat_control=%d\n",cat_control); #endif - g_mutex_unlock(&mutex_a->m); - g_idle_add(vfo_update,NULL); - - //sleep(1); - } - } + g_mutex_unlock(&mutex_a->m); + g_idle_add(ext_vfo_update,NULL); + } + return NULL; } // @@ -279,81 +664,287 @@ int rit_on () { } } } +// +// TS-2000 parser +// -- Now extended with zzid_flag to indicate PSDR extended command set +// void parse_cmd ( char * cmd_input,int len,int client_sock) { int work_int; int new_low, new_high; + int zzid_flag; double meter; - char msg[80]; - char buf[80]; + double forward; + double reverse; + double vswr; + char msg[200]; + char buf[200]; BANDSTACK_ENTRY *entry; // Parse the cmd_input //int space = command.indexOf(' '); //char cmd_char = com_head->cmd_string[0]; // Assume the command is first thing! char cmd_str[3]; + cmd_str[0] = cmd_input[0]; cmd_str[1] = cmd_input[1]; cmd_str[2] = '\0'; - if(strcmp(cmd_str,"AC")==0) { // Sets or reads the internal antenna tuner status - // P1 0:RX-AT Thru, 1: RX-AT IN - // P2 0: TX-AT Thru 1: TX-AT In - // - if(len <= 2) { - send_resp(client_sock,"AC000;"); - } + + // Added support for PSDR extended command set - they all start + // with ZZ so: + // + // Check to see if first part of string is ZZ - if so + // strip the ZZ out and set the zzid_flag = 1; + + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: CMD=%s\n",cmd_input); + #endif + zzid_flag = 0; // Set to indicate we haven't seen ZZ + char * zzid_ptr; + char temp[80]; + int cnt; + if(strcmp(cmd_str,"ZZ")==0) { + + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: Init=%s\n",cmd_str); + #endif + + // Adjust the Parse input like there hadn't been a ZZ in front - but + // set the ZZ flag to indicate we saw it. + zzid_ptr = &temp[0]; + + // It is 4AM and this was the only safe way for me to get a strcpy to work + // so - there ya go... + for(cnt=2; cnt<=len;cnt++) { + //fprintf(stderr,"[%d]=%c:",cnt,cmd_input[cnt]); + *zzid_ptr++= cmd_input[cnt]; + } + temp[len+1] = '\0'; + + strcpy(cmd_input,temp); + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: Cmd_input=%s\n",cmd_input); + #endif + // + cmd_str[0] = cmd_input[0]; + cmd_str[1] = cmd_input[1]; + cmd_str[2] = '\0'; + zzid_flag = 1; + len = strlen (temp); + } + + if(strcmp(cmd_str,"AC")==0) { + // TS-2000 - AC - STEP Command + // PiHPSDR - ZZAC - Step Command + if(zzid_flag ==1) { // Set or Read the Step Size (replaces ZZST) + if(len <= 2) { + switch(step) { + case 1: work_int = 0; break; + case 10: work_int = 1; break; + case 25: work_int = 2; break; + case 50: work_int = 3; break; + case 100: work_int = 4; break; + case 250: work_int = 5; break; + case 500: work_int = 6; break; + case 1000: work_int = 7; break; + case 2500: work_int = 8; break; + case 5000: work_int = 9; break; + case 6250: work_int = 10; break; + case 9000: work_int = 11; break; + case 10000: work_int = 12; break; + case 12500: work_int = 13; break; + case 15000: work_int = 14; break; + case 20000: work_int = 15; break; + case 25000: work_int = 16; break; + case 30000: work_int = 17; break; + case 50000: work_int = 18; break; + case 100000: work_int = 19; break; + default: + work_int = 0; + fprintf(stderr,"RIGCTL: ERROR step out of range\n"); + send_resp(client_sock,"?;"); + break; + } + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RESP: ZZAC%02d;",work_int); + #endif + sprintf(msg,"ZZAC%02d;",work_int); + send_resp(client_sock,msg); + + } else { // Legal vals between 00 and 22. + switch(atoi(&cmd_input[2])) { + case 0: step = 1; break; + case 1: step = 10; break; + case 2: step = 25; break; + case 3: step = 50; break; + case 4: step = 100; break; + case 5: step = 250; break; + case 6: step = 500; break; + case 7: step = 1000; break; + case 8: step = 2500; break; + case 9: step = 5000; break; + case 10: step = 6250; break; + case 11: step = 9000; break; + case 12: step = 10000; break; + case 13: step = 12500; break; + case 14: step = 15000; break; + case 15: step = 20000; break; + case 16: step = 25000; break; + case 17: step = 30000; break; + case 18: step = 50000; break; + case 19: step = 100000; break; + default: + fprintf(stderr,"RIGCTL: ERROR - ZZAC out of range\n"); + send_resp(client_sock,"?;"); + } + } + } else { // Sets or reads the internal antenna tuner status + // P1 0:RX-AT Thru, 1: RX-AT IN + // P2 0: TX-AT Thru 1: TX-AT In + // + if(len <= 2) { + send_resp(client_sock,"AC000;"); + } + } } - else if(strcmp(cmd_str,"AG")==0) { // Set Audio Gain - + else if((strcmp(cmd_str,"AD")==0) && (zzid_flag==1)) { + // PiHPSDR - ZZAD - Move VFO A Down by step + vfo_step(-1); + g_idle_add(ext_vfo_update,NULL); + } + else if(strcmp(cmd_str,"AG")==0) { + if(zzid_flag == 1) { + // PiHPSDR - ZZAG - Set/read Audio Gain + // Values are 000-100 + if(len<=2) { // Send ZZAGxxx; - active_receiver->volume 0.00-1.00 + sprintf(msg,"ZZAG%03d;",(int) (roundf(active_receiver->volume *100.0))); + send_resp(client_sock,msg); + } else { // Set Audio Gain + work_int = atoi(&cmd_input[2]); + active_receiver->volume = ((double) work_int)/100.0; + g_idle_add(ext_update_af_gain,NULL); + } + } else { + // TS-2000 - AG - Set Audio Gain // AG123; Value of 0- // AG1 = Sub receiver - what is the value set // Response - AG<0/1>123; Where 123 is 0-260 - int lcl_receiver; - if(receivers == 1) { - lcl_receiver = 0; - } else { - lcl_receiver = active_receiver->id; - } - if(len>4) { // Set Audio Gain - active_receiver->volume = (double) atoi(&cmd_input[3])/260; - g_idle_add(update_af_gain,NULL); - } else { // Read Audio Gain - sprintf(msg,"AG%1d%03d;",lcl_receiver,(int) (2.6 * active_receiver->volume)); - send_resp(client_sock,msg); - } + int lcl_receiver; + if(receivers == 1) { + lcl_receiver = 0; + } else { + lcl_receiver = active_receiver->id; + } + if(len>4) { // Set Audio Gain + if((atoi(&cmd_input[3]) >=0) && (atoi(&cmd_input[3])<=260)) { + active_receiver->volume = ((double) atoi(&cmd_input[3]))/260; + g_idle_add(ext_update_af_gain,NULL); + } else { + send_resp(client_sock,"?;"); + } + } else { // Read Audio Gain + sprintf(msg,"AG%1d%03d;",lcl_receiver,(int) (260 * active_receiver->volume)); + send_resp(client_sock,msg); + } + } } - else if(strcmp(cmd_str,"AI")==0) { // Allow rebroadcast of set frequency after set - not supported + else if((strcmp(cmd_str,"AI")==0) && (zzid_flag == 0)) { + // TS-2000 - AI- Allow rebroadcast of set frequency after set - not supported if(len <=2) { //send_resp(client_sock,"AI0;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"AL")==0) { // Set/Reads the auto Notch level + else if((strcmp(cmd_str,"AL")==0) && (zzid_flag == 0)) { + // TS-2000 - AL - Set/Reads the auto Notch level - not supported if(len <=2) { //send_resp(client_sock,"AL000;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"AM")==0) { // Sets or reads the Auto Mode + else if((strcmp(cmd_str,"AM")==0) && (zzid_flag == 0)) { + // TS-2000 - AM - Sets or reads the Auto Mode - not supported if(len <=2) { //send_resp(client_sock,"AM0;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"AN")==0) { // Selects the antenna connector (ANT1/2) + else if((strcmp(cmd_str,"AN")==0) && (zzid_flag == 0)) { + // TS-2000 - AN - Selects the antenna connector (ANT1/2) - not supported if(len <=2) { //send_resp(client_sock,"AN0;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"AR")==0) { // Sets or reads the ASC function on/off - if(len <=2) { - //send_resp(client_sock,"AR0;"); - send_resp(client_sock,"?;"); - } + else if((strcmp(cmd_str,"AP")==0) && (zzid_flag == 1)) { + // PiHPSDR - ZZAP - Set/Read Power Amp Settings. + // format - P1P1P1 P2P2.P2 + // P1 - Band P2 - 3.1 float WITH decimal point required! + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: ZZAP len=%d\n",len); + #endif + if(len<=5) { // Read Command + work_int = lookup_band(atoi(&cmd_input[2])); + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL ZZAP work_int=%d\n",work_int); + #endif + BAND *band = band_get_band(work_int); + sprintf(msg,"ZZAP%03d%3.1f;",atoi(&cmd_input[2]),band->pa_calibration); + send_resp(client_sock,msg); + } else { + /* isolate the command band from the value */ + char lcl_char = cmd_input[5];; + cmd_input[5]='\0'; // Make a temp string + work_int = atoi(&cmd_input[2]); + cmd_input[5] = lcl_char; // Restore the orig string.. + double lcl_float = atof(&cmd_input[5]); + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL ZZAP - band=%d setting=%3.1f\n",work_int, lcl_float); + #endif + work_int = lookup_band(work_int); + + // Sequence below lifted from pa_menu + BAND *band = band_get_band(work_int); + band->pa_calibration = lcl_float; + work_int = VFO_A; + if(split) work_int = VFO_B; + int b = vfo[work_int].band; + BAND *current = band_get_band(b); + if(band == current) { + g_idle_add( ext_calc_drive_level,(gpointer) NULL); + //g_idle_add( ext_calc_tune_drive_level,(gpointer) NULL); + } + } + } + else if(strcmp(cmd_str,"AR")==0) { + if(zzid_flag ==1) { + // PiHPSDR - ZZAR - Set or reads the RX1 AGC Threshold Control + if(len <=2) { // Read Response + // X is +/- sign + if(active_receiver->agc_gain >=0) { + sprintf(msg,"ZZAR+%03d;",(int)active_receiver->agc_gain); + } else { + sprintf(msg,"ZZAR-%03d;",abs((int)active_receiver->agc_gain)); + } + send_resp(client_sock,msg); + } else { + double new_gain = (double) atoi(&cmd_input[2]); + double *p_gain=malloc(sizeof(double)); + *p_gain=new_gain; + g_idle_add(ext_update_agc_gain,(gpointer)p_gain); + } + } else { + // TS-2000 - AR - Sets or reads the ASC function on/off - not supported + if(len <=2) { + //send_resp(client_sock,"AR0;"); + send_resp(client_sock,"?;"); + } + } } - else if(strcmp(cmd_str,"AS")==0) { // Sets/reads automode function parameters - // AS<2xP2><11P3>; - // AS<2xP2><11P3>; + else if((strcmp(cmd_str,"AS")==0) && (zzid_flag == 0)) { + // TS-2000 - AS - Sets/reads automode function parameters + // AS<2xP2><11P3>; + // AS<2xP2><11P3>; if(len < 6) { - /* sprintf(msg,"AS%1d%02d%011lld%01d;", + /* sprintf(msg,"AS%1d%02d%011lld%01d;", 0, // P1 0, // Automode getFrequency(), @@ -363,95 +954,553 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) { } } - else if(strcmp(cmd_str,"BC")==0) { // Beat Cancellor OFF + else if((strcmp(cmd_str,"AU")==0) && (zzid_flag==1)) { + // PiHPSDR - ZZAU - Move VFO A Up by step + vfo_step(1); + g_idle_add(ext_vfo_update,NULL); + } + else if((strcmp(cmd_str,"BC")==0) && (zzid_flag == 0)) { + // TS-2000 - BC - Beat Cancellor OFF - not supported if(len <=2) { //send_resp(client_sock,"BC0;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"BD")==0) { // Moves down the frequency band - // No response + else if(strcmp(cmd_str,"BD")==0) { + // PiHPSDR - ZZBD - Moves down the frequency band selector + // TS-2000 - BD - Moves down the frequency band selector + // No response + // This reacts to both BD and ZZBD - only works for active receiver + int cur_band = vfo[active_receiver->id].band; + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: BD - current band=%d\n",cur_band); + #endif + if(cur_band == 0) { + #ifdef LIMESDR + cur_band = band472; + #else + cur_band = band6; + #endif + } else { + --cur_band; + } + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: BD - new band=%d\n",cur_band); + #endif + g_idle_add(ext_vfo_band_changed,(gpointer)(long)cur_band); } - else if(strcmp(cmd_str,"BP")==0) { // Reads the manual beat canceller frequency setting + else if((strcmp(cmd_str,"BP")==0) && (zzid_flag == 0)) { + // TS-2000 - BP - Reads the manual beat canceller freq - not supported if(len <=2) { //send_resp(client_sock,"BP000;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"BS")==0) { // Sets or reads Beat Canceller status - if(len <=2) { - //send_resp(client_sock,"BS0;"); - send_resp(client_sock,"?;"); - } + else if(strcmp(cmd_str,"BS")==0) { + if(zzid_flag == 1) { + // PiHPSDR - ZZBS - Read the RX1 Band switch + int cur_band = vfo[active_receiver->id].band; + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: BS - band=%d\n",cur_band); + #endif + + switch(cur_band) { + case 0: work_int = 160; break; + case 1: work_int = 80; break; + case 2: work_int = 60; break; + case 3: work_int = 40; break; + case 4: work_int = 30; break; + case 5: work_int = 20; break; + case 6: work_int = 17; break; + case 7: work_int = 15; break; + case 8: work_int = 12; break; + case 9: work_int = 10; break; + case 10: work_int = 6; break; + case 11: work_int = 888; break; + case 12: work_int = 999; break; + case 13: work_int = 136; break; + case 14: work_int = 472; break; + } + sprintf(msg,"ZZBS%03d;",work_int); + send_resp(client_sock,msg); + + } else { + // Sets or reads Beat Canceller status + if(len <=2) { + //send_resp(client_sock,"BS0;"); + send_resp(client_sock,"?;"); + } + } } - else if(strcmp(cmd_str,"BU")==0) { // Moves Up the frequency band + else if(strcmp(cmd_str,"BU")==0) { + // PiHPSDR - ZZBU - Moves Up the frequency band + // TS-2000 - BU - Moves Up the frequency band // No response + int cur_band = vfo[active_receiver->id].band; + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: BU - Max Band = %d current band=%d\n",BANDS,cur_band); + #endif + if(cur_band >= 10) { + cur_band = band160; + } else { + ++cur_band; + } + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: BU - new band=%d\n",cur_band); + #endif + g_idle_add(ext_vfo_band_changed,(gpointer)(long)cur_band); } - else if(strcmp(cmd_str,"BY")==0) { // Read the busy signal status + else if((strcmp(cmd_str,"BY")==0) && (zzid_flag == 0)) { + // TS-2000 - BY - Read the busy signal status if(len <=2) { //send_resp(client_sock,"BY00;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"CA")==0) { // Sets/reads cw auto tune function status + else if((strcmp(cmd_str,"CA")==0) && (zzid_flag == 0)) { + // TS-2000 - CA - Sets/reads cw auto tune f(x) status - not supported if(len <=2) { //send_resp(client_sock,"CA0;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"CG")==0) { // Sets/reads the carrier gain status - // 0-100 legal values - if(len <=2) { + else if((strcmp(cmd_str,"CB")==0) && (zzid_flag==1)) { + // PIHPSDR - ZZCB - Sets/reads CW Break In checkbox status + // P1 = 0 for disabled, 1 for enabled + if(len <= 2) { + sprintf(msg,"ZZCB%01d;",cw_breakin); + send_resp(client_sock,msg); + } else { + cw_breakin = atoi(&cmd_input[2]); + } + } + else if((strcmp(cmd_str,"CG")==0) && (zzid_flag == 0)) { + // TS-2000 - CD - Sets/Reads the carrier gain status - not supported + // 0-100 legal values + if(len <=2) { //send_resp(client_sock,"CG000;"); send_resp(client_sock,"?;"); - } + } + } + else if((strcmp(cmd_str,"CH")==0) && (zzid_flag == 0)) { + // TS-2000 - CH - Sets the current frequency to call Channel -no response } - else if(strcmp(cmd_str,"CH")==0) { // Sets the current frequency to call Channel - // No response + else if((strcmp(cmd_str,"CI")==0) && (zzid_flag == 0)) { + // TS-2000 - CI - In VFO md or Mem recall md, sets freq 2 call channel - no response } - else if(strcmp(cmd_str,"CI")==0) { // While in VFO mode or memory recall mode, sets freq to the call channel - // No response + else if((strcmp(cmd_str,"CL")==0) && (zzid_flag == 1)) { + // PiHPSDR - ZZCL - CW Pitch set + // 0200 - 1200 + if(len <=2) { + sprintf(msg,"ZZCL%04d;",cw_keyer_sidetone_frequency); + send_resp(client_sock,msg); + } else { + int local_freq = atoi(&cmd_input[2]); + if((local_freq >= 200) && (local_freq <=1200)) { + cw_keyer_sidetone_frequency = atoi(&cmd_input[2]); + g_idle_add(ext_vfo_update,NULL); + } else { + fprintf(stderr,"RIGCTL: ZZCL illegal freq=%d\n",local_freq); + } + } } - else if(strcmp(cmd_str,"CM")==0) { // Sets or reads the packet cluster tune f(x) on/off - // 0-100 legal values + else if((strcmp(cmd_str,"CM")==0) && (zzid_flag == 0)) { + // TS-2000 - CM - Sets or reads the packet cluster tune f(x) on/off -not supported + // 0-100 legal values if(len <=2) { //send_resp(client_sock,"CM0;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"CN")==0) { // Sets and reads CTSS function - 01-38 legal values - // Stored locally in rigctl - not used. - if(len <=2) { - sprintf(msg,"CN%02d;",ctcss_tone); - send_resp(client_sock,msg); - send_resp(client_sock,"?;"); - } else { + else if((strcmp(cmd_str,"CN")==0) && (zzid_flag == 0)) { + // TS-2000 - CN - Sets and reads CTSS function - 01-38 legal values + // Stored locally in rigctl - not used. + if(len >2) { ctcss_tone = atoi(&cmd_input[2]); - } + if((ctcss_tone > 0) && (ctcss_tone <= 39)) { + switch(ctcss_tone) { + case 1: transmitter->ctcss_frequency = (double) 67.0;break; + case 2: transmitter->ctcss_frequency = (double) 71.9;break; + case 3: transmitter->ctcss_frequency = (double) 74.4;break; + case 4: transmitter->ctcss_frequency = (double) 77.0;break; + case 5: transmitter->ctcss_frequency = (double) 79.7;break; + case 6: transmitter->ctcss_frequency = (double) 82.5;break; + case 7: transmitter->ctcss_frequency = (double) 85.4;break; + case 8: transmitter->ctcss_frequency = (double) 88.5;break; + case 9: transmitter->ctcss_frequency = (double) 91.5;break; + case 10: transmitter->ctcss_frequency = (double) 94.8;break; + case 11: transmitter->ctcss_frequency = (double) 97.4;break; + case 12: transmitter->ctcss_frequency = (double) 100.0;break; + case 13: transmitter->ctcss_frequency = (double) 103.5;break; + case 14: transmitter->ctcss_frequency = (double) 107.2;break; + case 15: transmitter->ctcss_frequency = (double) 110.9;break; + case 16: transmitter->ctcss_frequency = (double) 114.8;break; + case 17: transmitter->ctcss_frequency = (double) 118.8;break; + case 18: transmitter->ctcss_frequency = (double) 123.0;break; + case 19: transmitter->ctcss_frequency = (double) 127.3;break; + case 20: transmitter->ctcss_frequency = (double) 131.8;break; + case 21: transmitter->ctcss_frequency = (double) 136.5;break; + case 22: transmitter->ctcss_frequency = (double) 141.3;break; + case 23: transmitter->ctcss_frequency = (double) 146.2;break; + case 24: transmitter->ctcss_frequency = (double) 151.4;break; + case 25: transmitter->ctcss_frequency = (double) 156.7;break; + case 26: transmitter->ctcss_frequency = (double) 162.2;break; + case 27: transmitter->ctcss_frequency = (double) 167.9;break; + case 28: transmitter->ctcss_frequency = (double) 173.8;break; + case 29: transmitter->ctcss_frequency = (double) 179.9;break; + case 30: transmitter->ctcss_frequency = (double) 186.2;break; + case 31: transmitter->ctcss_frequency = (double) 192.8;break; + case 32: transmitter->ctcss_frequency = (double) 203.5;break; + case 33: transmitter->ctcss_frequency = (double) 210.7;break; + case 34: transmitter->ctcss_frequency = (double) 218.1;break; + case 35: transmitter->ctcss_frequency = (double) 225.7;break; + case 36: transmitter->ctcss_frequency = (double) 233.6;break; + case 37: transmitter->ctcss_frequency = (double) 241.8;break; + case 38: transmitter->ctcss_frequency = (double) 250.3;break; + case 39: transmitter->ctcss_frequency = (double) 1750.0;break; + } + transmitter_set_ctcss(transmitter,transmitter->ctcss,transmitter->ctcss_frequency); + } + } else { + ctcss_tone = -1; + if(transmitter->ctcss_frequency == (double) 67.0) { + ctcss_tone = 1; + } else if (transmitter->ctcss_frequency == (double) 71.9) { + ctcss_tone = 2; + } else if (transmitter->ctcss_frequency == (double) 74.4) { + ctcss_tone = 3; + } else if (transmitter->ctcss_frequency == (double) 77.0) { + ctcss_tone = 4; + } else if (transmitter->ctcss_frequency == (double) 79.7) { + ctcss_tone = 5; + } else if (transmitter->ctcss_frequency == (double) 82.5) { + ctcss_tone = 6; + } else if (transmitter->ctcss_frequency == (double) 85.4) { + ctcss_tone = 7; + } else if (transmitter->ctcss_frequency == (double) 88.5) { + ctcss_tone = 8; + } else if (transmitter->ctcss_frequency == (double) 91.5) { + ctcss_tone = 9; + } else if (transmitter->ctcss_frequency == (double) 94.8) { + ctcss_tone = 10; + } else if (transmitter->ctcss_frequency == (double) 97.4) { + ctcss_tone = 11; + } else if (transmitter->ctcss_frequency == (double) 100.0) { + ctcss_tone = 12; + } else if (transmitter->ctcss_frequency == (double) 103.5) { + ctcss_tone = 13; + } else if (transmitter->ctcss_frequency == (double) 107.2) { + ctcss_tone = 14; + } else if (transmitter->ctcss_frequency == (double) 110.9) { + ctcss_tone = 15; + } else if (transmitter->ctcss_frequency == (double) 114.8) { + ctcss_tone = 16; + } else if (transmitter->ctcss_frequency == (double) 118.8) { + ctcss_tone = 17; + } else if (transmitter->ctcss_frequency == (double) 123.0) { + ctcss_tone = 18; + } else if (transmitter->ctcss_frequency == (double) 127.3) { + ctcss_tone = 19; + } else if (transmitter->ctcss_frequency == (double) 131.8) { + ctcss_tone = 20; + } else if (transmitter->ctcss_frequency == (double) 136.5) { + ctcss_tone = 21; + } else if (transmitter->ctcss_frequency == (double) 141.3) { + ctcss_tone = 22; + } else if (transmitter->ctcss_frequency == (double) 146.2) { + ctcss_tone = 23; + } else if (transmitter->ctcss_frequency == (double) 151.4) { + ctcss_tone = 24; + } else if (transmitter->ctcss_frequency == (double) 156.7) { + ctcss_tone = 25; + } else if (transmitter->ctcss_frequency == (double) 162.2) { + ctcss_tone = 26; + } else if (transmitter->ctcss_frequency == (double) 167.9) { + ctcss_tone = 27; + } else if (transmitter->ctcss_frequency == (double) 173.8) { + ctcss_tone = 28; + } else if (transmitter->ctcss_frequency == (double) 179.9) { + ctcss_tone = 29; + } else if (transmitter->ctcss_frequency == (double) 186.2) { + ctcss_tone = 30; + } else if (transmitter->ctcss_frequency == (double) 192.8) { + ctcss_tone = 31; + } else if (transmitter->ctcss_frequency == (double) 203.5) { + ctcss_tone = 32; + } else if (transmitter->ctcss_frequency == (double) 210.7) { + ctcss_tone = 33; + } else if (transmitter->ctcss_frequency == (double) 218.1) { + ctcss_tone = 34; + } else if (transmitter->ctcss_frequency == (double) 225.7) { + ctcss_tone = 35; + } else if (transmitter->ctcss_frequency == (double) 233.6) { + ctcss_tone = 36; + } else if (transmitter->ctcss_frequency == (double) 241.8) { + ctcss_tone = 37; + } else if (transmitter->ctcss_frequency == (double) 250.3) { + ctcss_tone = 38; + } else if (transmitter->ctcss_frequency == (double) 1750.0) { + ctcss_tone = 39; + } else { + send_resp(client_sock,"?;"); + } + if(ctcss_tone != -1) { + sprintf(msg,"CN%02d;",ctcss_tone); + send_resp(client_sock,msg); + } + } } - else if(strcmp(cmd_str,"CT")==0) { // Sets and reads CTSS function status - // Stored locally in rigctl - not used. - if(len <=2) { - sprintf(msg,"CT%01d;",ctcss_mode); + // ZZCS - Keyer Speed implemented within "KS" command + else if((strcmp(cmd_str,"CT")==0) && (zzid_flag == 0)) { + // TS-2000 - CS - Sets and reads CTSS function status + // Stored locally in rigctl - not used. + if(len <=2) { + sprintf(msg,"CT%01d;",transmitter->ctcss); send_resp(client_sock,msg); - } else { - ctcss_mode = atoi(&cmd_input[2]); - } + } else { + if((atoi(&cmd_input[2]) == 0) ||(atoi(&cmd_input[2]) == 1)) { + transmitter->ctcss = atoi(&cmd_input[2]); + transmitter_set_ctcss(transmitter,transmitter->ctcss,transmitter->ctcss_frequency); + } else { + send_resp(client_sock,"?;"); + } + } } - else if(strcmp(cmd_str,"DC")==0) { // Sets/Reads TX band status - if(len <=2) { + else if((strcmp(cmd_str,"DA")==0) && (zzid_flag == 1)) { + // PiHPSDR - DA - Set/Clear Waterfall Automatic on Display Menu + if(len <=2) { + sprintf(msg,"ZZDA%0d;",active_receiver->waterfall_automatic); + send_resp(client_sock,msg); + } else { + if((cmd_input[2] == '0') || (cmd_input[2] == '1')) { + active_receiver->waterfall_automatic = atoi(&cmd_input[2]); + } else { + send_resp(client_sock,"?;"); + } + } + } + else if((strcmp(cmd_str,"DC")==0) && (zzid_flag == 0)) { + // TS-2000 - DC - Sets/Reads TX band status + if(len <=2) { //send_resp(client_sock,"DC00;"); send_resp(client_sock,"?;"); - } + } + } + else if(strcmp(cmd_str,"DN")==0) { + // TS-2000 - DN - Emulate Mic down key - Not supported + // PiHPSDR - ZZDN - Set/Read Waterfall Lo Limit + int lcl_waterfall_low; + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: DN - init val=%d\n",active_receiver->waterfall_low); + #endif + if(zzid_flag == 1) { // ZZDN + if(len<=2) { + if(active_receiver->waterfall_low <0) { + sprintf(msg,"ZZDN-%03d;",abs(active_receiver->waterfall_low)); + } else { + sprintf(msg,"ZZDN+%03d;",active_receiver->waterfall_low); + } + send_resp(client_sock,msg); + } else { + lcl_waterfall_low = atoi(&cmd_input[3]); + if((lcl_waterfall_low >= -200) && (lcl_waterfall_low <=200)) { + if(cmd_input[2]=='-') { + //waterfall_low = lcl_waterfall_low; + active_receiver->waterfall_low = -lcl_waterfall_low; + } else { + active_receiver->waterfall_low = lcl_waterfall_low; + } + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: DN - fin val=%d\n",active_receiver->waterfall_low); + #endif + } else { + fprintf(stderr,"RIGCTL: ZZDN illegal val=%d\n",lcl_waterfall_low); + send_resp(client_sock,"?;"); + } + } + } } - else if(strcmp(cmd_str,"DN")==0) { // Emulate Mic down key + else if((strcmp(cmd_str,"DO")==0) && zzid_flag == 1) { + // PiHPSDR - ZZDO - Set/Read Waterfall Hi Limit + if(zzid_flag == 1) { // ZZDO + if(len<=2) { + if(active_receiver->waterfall_high <0) { + sprintf(msg,"ZZDO-%03d;",abs(active_receiver->waterfall_high)); + } else { + sprintf(msg,"ZZDO+%03d;",active_receiver->waterfall_high); + } + send_resp(client_sock,msg); + } else { + int lcl_waterfall_high = atoi(&cmd_input[3]); + if((lcl_waterfall_high >= -200) && (lcl_waterfall_high <=200)) { + if(cmd_input[2]=='-') { + active_receiver->waterfall_high = -lcl_waterfall_high; + } else { + active_receiver->waterfall_high = lcl_waterfall_high; + } + } else { + fprintf(stderr,"RIGCTL: ZZDO illegal val=%d\n",lcl_waterfall_high); + send_resp(client_sock,"?;"); + } + } + } } - else if(strcmp(cmd_str,"DQ")==0) { // ETs/and reads the DCS function status + else if((strcmp(cmd_str,"DQ")==0) && (zzid_flag == 0)) { + // TS-2000 - DQ - ETs/and reads the DCS function status - not supported if(len <=2) { //send_resp(client_sock,"DQ0;"); send_resp(client_sock,"?;"); } } + else if((strcmp(cmd_str,"DU")==0) && zzid_flag ==1) { + // PiHPSDR - ZZDU - Read Status Word - NOT compatible with PSDR!! + int smeter = (int) GetRXAMeter(active_receiver->id, smeter) ; + sprintf(msg,"ZZDU%1d%1d%1d%1d%1d%1d%1d%1d%1d%06d%1d%03d%1c%1d%1d%1d%1c%06lld%1d%011lld%011lld%c%03d%1d%1d%1d%1d;", + split, //P1 + tune, // P2, + mox, // P3 + receivers, // P4 + active_receiver->id, // P5 + active_receiver->alex_antenna, // P6 + rit_on(), // P7 + active_receiver->agc, // P8 + vfo[active_receiver->id].mode, //P9 + (int) step, // P10 + vfo[active_receiver->id].band, // P11 6d + ((int) transmitter->drive)*100, // P12 + (int)active_receiver->agc_gain >=0 ? '+' : '-', // P13 sign + (int)active_receiver->agc_gain, // P13 3d + (int)active_receiver->volume, // P14 3d + vfo[active_receiver->id].rit_enabled, + vfo[active_receiver->id].rit >=0 ? '+' : '-', // P15 sign + vfo[active_receiver->id].rit, // P15 6d + vfo[active_receiver->id].ctun, // P16 1d + vfo[active_receiver->id].frequency, // P17 11d + vfo[active_receiver->id].ctun_frequency, // P18 11d + smeter>=0 ? '+': '-', + abs(smeter), + active_receiver->nr , active_receiver->nr2 , + active_receiver->anf , active_receiver->snb); + send_resp(client_sock,msg); + } + + else if((strcmp(cmd_str,"EA")==0) && zzid_flag ==1) { + // PiHPSDR - ZZEA - sets/reads RX EQ values + if(len<=2) { + sprintf(msg,"ZZEA%1d%1c%03d%1c%03d%1c%03d%1c%03d;", + enable_rx_equalizer, + rx_equalizer[0]>=0? '+' : '-', + abs((int) rx_equalizer[0]), + rx_equalizer[1]>=0? '+' : '-', + abs((int) rx_equalizer[1]), + rx_equalizer[2]>=0? '+' : '-', + abs((int) rx_equalizer[2]), + rx_equalizer[3]>=0? '+' : '-', + abs((int) rx_equalizer[3])); + send_resp(client_sock,msg); + + } else { + //if(len !=19) { + // fprintf(stderr,"RIGCTL: ZZEA - incorrect number of arguments\n"); + // send_resp(client_sock,"?;"); + // return; + // } + double work_do; + enable_rx_equalizer = atoi(&cmd_input[2]); + work_do = (double) atoi(&cmd_input[3]); + if((work_do < -12) || (work_do > 15)) { + fprintf(stderr,"RIGCTL: ZZEA - Preamp arg out of range=%d \n",(int) work_do); + send_resp(client_sock,"?;"); + return; + } + rx_equalizer[0] = work_do; + + work_do = (double) atoi(&cmd_input[7]); + if((work_do < -12) || (work_do > 15)) { + fprintf(stderr,"RIGCTL: ZZEA - Low arg out of range=%d \n",(int) work_do); + send_resp(client_sock,"?;"); + return; + } + rx_equalizer[1] = work_do; + + work_do = (double) atoi(&cmd_input[11]); + if((work_do < -12) || (work_do > 15)) { + fprintf(stderr,"RIGCTL: ZZEA - Mid arg out of range=%d \n",(int) work_do); + send_resp(client_sock,"?;"); + return; + } + rx_equalizer[2] = work_do; + + work_do = (double) atoi(&cmd_input[15]); + if((work_do < -12) || (work_do > 15)) { + fprintf(stderr,"RIGCTL: ZZEA - Hi arg out of range=%d \n",(int) work_do); + send_resp(client_sock,"?;"); + return; + } + rx_equalizer[3] = work_do; + + SetRXAGrphEQ(active_receiver->id, rx_equalizer); + } + } + else if((strcmp(cmd_str,"EB")==0) && zzid_flag ==1) { + // PiHPSDR - ZZEB - sets/reads TX EQ values + if(len<=2) { + sprintf(msg,"ZZEB%1d%1c%03d%1c%03d%1c%03d%1c%03d;", + enable_tx_equalizer, + tx_equalizer[0]>=0? '+' : '-', + abs((int) tx_equalizer[0]), + tx_equalizer[1]>=0? '+' : '-', + abs((int) tx_equalizer[1]), + tx_equalizer[2]>=0? '+' : '-', + abs((int) tx_equalizer[2]), + tx_equalizer[3]>=0? '+' : '-', + abs((int) tx_equalizer[3])); + send_resp(client_sock,msg); + + } else { + if(len !=19) { + fprintf(stderr,"RIGCTL: ZZEB - incorrect number of arguments\n"); + send_resp(client_sock,"?;"); + return; + } + double work_do; + enable_tx_equalizer = atoi(&cmd_input[2]); + + work_do = (double) atoi(&cmd_input[3]); + if((work_do < -12) || (work_do > 15)) { + fprintf(stderr,"RIGCTL: ZZEB - Preamp arg out of range=%d \n",(int) work_do); + send_resp(client_sock,"?;"); + return; + } + tx_equalizer[0] = work_do; + + work_do = (double) atoi(&cmd_input[7]); + if((work_do < -12) || (work_do > 15)) { + fprintf(stderr,"RIGCTL: ZZEB - Low arg out of range=%d \n",(int) work_do); + send_resp(client_sock,"?;"); + return; + } + tx_equalizer[1] = work_do; + + work_do = (double) atoi(&cmd_input[11]); + if((work_do < -12) || (work_do > 15)) { + fprintf(stderr,"RIGCTL: ZZEB - Mid arg out of range=%d \n",(int) work_do); + send_resp(client_sock,"?;"); + return; + } + tx_equalizer[2] = work_do; + + work_do = (double) atoi(&cmd_input[15]); + if((work_do < -12) || (work_do > 15)) { + fprintf(stderr,"RIGCTL: ZZEB - Hi arg out of range=%d \n",(int) work_do); + send_resp(client_sock,"?;"); + return; + } + tx_equalizer[3] = work_do; + + SetTXAGrphEQ(transmitter->id, tx_equalizer); + } + } else if(strcmp(cmd_str,"EX")==0) { // Set/reads the extension menu // This routine only can look up specific information; // And only performs reads at this point.. @@ -493,30 +1542,71 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) { } } } - else if(strcmp(cmd_str,"FA")==0) { // VFO A frequency + else if(strcmp(cmd_str,"FA")==0) { + // PiHPSDR - ZZFA - VFO A frequency + // TS2000 - FA - VFO A frequency // LEN=7 - set frequency // Next data will be rest of freq if(len == 13) { //We are receiving freq info new_freqA = atoll(&cmd_input[2]); - set_band(new_freqA,(int)-1); + long long *p=malloc(sizeof(long long)); + *p= new_freqA; + g_idle_add(ext_set_frequency,(gpointer)p); + g_idle_add(ext_vfo_update,NULL); + //g_idle_add(set_band,(gpointer) p_int); + //long long * freq_p; + //*freq_p=new_freqA; //setFrequency(new_freqA); - //g_idle_add(vfo_update,NULL); + //g_idle_add(gui_vfo_move_to,(gpointer)freq_p); + return; } else { if(len==2) { - //sprintf(msg,"FA%011lld;",getFrequency()); - sprintf(msg,"FA%011lld;",vfo[VFO_A].frequency); + if(zzid_flag == 0) { + if(vfo[VFO_A].ctun == 1) { + sprintf(msg,"FA%011lld;",vfo[VFO_A].frequency+vfo[VFO_A].offset); + } else { + sprintf(msg,"FA%011lld;",vfo[VFO_A].frequency); + } + } else { + if(vfo[VFO_A].ctun == 1) { + sprintf(msg,"ZZFA%011lld;",vfo[VFO_A].frequency+vfo[VFO_A].offset); + } else { + sprintf(msg,"ZZFA%011lld;",vfo[VFO_A].frequency); + } + } + fprintf(stderr,"RIGCTL: FA=%s\n",msg); send_resp(client_sock,msg); } } } - else if(strcmp(cmd_str,"FB")==0) { // VFO B frequency + else if(strcmp(cmd_str,"FB")==0) { + // TS-2000 - FB - VFO B frequency + // PiHPSDR - ZZFB - VFO B frequency if(len==13) { //We are receiving freq info - new_freqB = atoll(&cmd_input[2]); - set_freqB(new_freqB); + new_freqB = atoll(&cmd_input[2]); + long long *p=malloc(sizeof(long long)); + *p=new_freqB; + g_idle_add(ext_set_frequency,(gpointer)p); + g_idle_add(ext_vfo_update,NULL); + //new_freqB = atoll(&cmd_input[2]); + //set_freqB(new_freqB); //setFrequency(new_freqA); - //g_idle_add(vfo_update,NULL); + //g_idle_add(ext_vfo_update,NULL); } else if(len == 2) { - sprintf(msg,"FB%011lld;",vfo[VFO_B].frequency); + if(zzid_flag == 0) { + if(vfo[VFO_B].ctun == 1) { + sprintf(msg,"FB%011lld;",vfo[VFO_B].frequency + vfo[VFO_B].offset); + } else { + sprintf(msg,"FB%011lld;",vfo[VFO_B].frequency); + } + } else { + if(vfo[VFO_B].ctun == 1) { + sprintf(msg,"ZZFB%011lld;",vfo[VFO_B].frequency + vfo[VFO_B].offset); + } else { + sprintf(msg,"ZZFB%011lld;",vfo[VFO_B].frequency); + } + } + fprintf(stderr,"RIGCTL: FB=%s\n",msg); send_resp(client_sock,msg); } } @@ -533,10 +1623,71 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) { send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"FD")==0) { // Read the filter display dot pattern - send_resp(client_sock,"FD00000000;"); + else if((strcmp(cmd_str,"FD")==0) & (zzid_flag==0)) { + // TS-2000 - FD - Read the filter display dot pattern + send_resp(client_sock,"FD00000000;"); + } + else if((strcmp(cmd_str,"FH")==0) & (zzid_flag==1)) { + // PiHPSDR - ZZFH - Set/Read Selected current DSP Filter Low High + // P1 = (0)XXXX 5 chars --9999-09999 + if(len<=2) { + sprintf(msg,"ZZFH%05d;",active_receiver->filter_high); + send_resp(client_sock,msg); + } else { + // Insure that we have a variable filter selected! + if(vfo[active_receiver->id].filter > 9) { + work_int = atoi(&cmd_input[2]); + if((work_int >= -9999) && (work_int <=9999)) { + active_receiver->filter_high = work_int; + } else { + fprintf(stderr,"RIGCTL Warning ZZFH Value=%d out of range\n",work_int); + send_resp(client_sock,"?;"); + } + } else { + fprintf(stderr,"RIGCTL Warning ZZFH not applied - VAR1/2 not selected\n"); + send_resp(client_sock,"?;"); + } + } } - else if(strcmp(cmd_str,"FR")==0) { // Set/reads the extension menu + else if((strcmp(cmd_str,"FI")==0) & (zzid_flag==1)) { + // PiHPSDR - ZZFI - Set/Read current DSP filter selected filter + if(len<=2) { + sprintf(msg,"ZZFI%02d;",vfo[active_receiver->id].filter); + send_resp(client_sock,msg); + } else { + work_int = atoi(&cmd_input[2]); + if((work_int >=0) && (work_int<=11)) { + g_idle_add(filter_select,(gpointer)(long)work_int); + } else { + fprintf(stderr,"RIGCTL: ERROR ZZFI incorrect filter value=%d",work_int); + send_resp(client_sock,"?;"); + } + } + } + else if((strcmp(cmd_str,"FL")==0) & (zzid_flag==1)) { + // PiHPSDR - ZZFL - Set/Read Selected current DSP Filter Low + // P1 = (0)XXXX 5 chars --9999-09999 + if(len<=2) { + sprintf(msg,"ZZFL%05d;",active_receiver->filter_low); + send_resp(client_sock,msg); + } else { + // Insure that we have a variable filter selected! + if(vfo[active_receiver->id].filter > 9) { + work_int = atoi(&cmd_input[2]); + if((work_int >= -9999) && (work_int <=9999)) { + active_receiver->filter_low = work_int; + } else { + fprintf(stderr,"RIGCTL Warning ZZFH Value=%d out of range\n",work_int); + send_resp(client_sock,"?;"); + } + } else { + fprintf(stderr,"RIGCTL Warning ZZFH not applied - VAR1/2 not selected\n"); + send_resp(client_sock,"?;"); + } + } + } + else if((strcmp(cmd_str,"FR")==0) && (zzid_flag == 0)) { + // TS-2000 - FR - Set/reads the extension menu if(len <=2) { if(receivers == 1) { sprintf(msg,"FR0;"); @@ -552,42 +1703,81 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) { if(active_receiver->id != lcl_cmd) { //active_receiver->id = lcl_cmd; active_receiver = receiver[lcl_cmd]; - g_idle_add(vfo_update,NULL); - g_idle_add(active_receiver_changed,NULL); + g_idle_add(ext_vfo_update,NULL); + // SDW + //g_idle_add(active_receiver_changed,NULL); } } } - else if(strcmp(cmd_str,"FS")==0) { // Set/reads fine funct status + else if((strcmp(cmd_str,"FS")==0) && (zzid_flag == 0)) { + // TS-2000 - FS - Set/reads fine funct status - if(len <=2) { - send_resp(client_sock,"FS0;"); - } + sprintf(msg,"FS%1d;",fine); + send_resp(client_sock,msg); + } else { + int lcl_fine; + lcl_fine = atoi(&cmd_input[2]); + if((lcl_fine >=0) && (lcl_fine <=1)) { + fine = lcl_fine; + } else { + send_resp(client_sock,"?;"); + } + } } - else if(strcmp(cmd_str,"FT")==0) { // Sel or reads the transmitters VFO, M, ch or Call comm + else if(strcmp(cmd_str,"FT")==0) { + // TS-2000 - FT - Set/Read Active Transmitter + // PiHPSDR - ZZFT - Set/Read Active Transmitter if(len <=2) { - sprintf(msg,"FT%1d",active_transmitter); - send_resp(client_sock,msg); + if(zzid_flag == 0) { + sprintf(msg,"FT%1d;",active_transmitter); + } else { + sprintf(msg,"ZZFT%1d;",active_transmitter); + } + send_resp(client_sock,msg); } else { lcl_cmd = atoi(&cmd_input[2]); - if(lcl_cmd != active_receiver->id) { - split = 1; + if((lcl_cmd ==0) ||(lcl_cmd == 1)) { + if(lcl_cmd != active_receiver->id) { + split = 1; + } else { + split = 0; + } + active_transmitter = lcl_cmd; + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: FT New=%d\n",active_transmitter); + #endif + g_idle_add(ext_vfo_update,NULL); } else { - split = 0; + send_resp(client_sock,"?;"); } - active_transmitter = lcl_cmd; - g_idle_add(vfo_update,NULL); } } - else if(strcmp(cmd_str,"FW")==0) { // Sets/Reas DSP receive filter width in hz 0-9999hz - // CW - legal values 50 80 100 150 200 300 400 500 600 1000 2000 - // PiHPSDR map 50 100 100 100 250 250 400 500 600 1000 - // 25 750 - entry= (BANDSTACK_ENTRY *) + else if((strcmp(cmd_str,"FW")==0) & (zzid_flag==0)) { + // TS-2000 - FW - Sets/Read DSP receive filter width in hz 0-9999hz + // CW - legal values 50 80 100 150 200 300 400 500 600 1000 2000 + // Pi HPSDR map 50 100 100 100 250 250 400 500 600 1000 + // 25 750 + /*entry= (BANDSTACK_ENTRY *) bandstack_entry_get_current(); FILTER* band_filters=filters[entry->mode]; - FILTER* band_filter=&band_filters[entry->filter]; - if(len <=2) { + FILTER* band_filter=&band_filters[entry->filter];*/ + BAND *band=band_get_band(vfo[active_receiver->id].band); + BANDSTACK *bandstack=band->bandstack; + BANDSTACK_ENTRY *entry=&bandstack->entry[vfo[active_receiver->id].bandstack]; + FILTER* band_filters=filters[vfo[active_receiver->id].mode]; + FILTER* band_filter=&band_filters[vfo[active_receiver->id].filter]; + int cur_rad_mode= vfo[active_receiver->id].mode; + // SDW1 + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: FW - active recv mode =%d\n",cur_rad_mode); + #endif + if((cur_rad_mode == modeCWL) || (cur_rad_mode == modeCWU)) { + if(len <=2) { // CW filter high and low are always the same and the filter value is 2*filter val - int filter_val = band_filter->high * 2; + int filter_val = abs(band_filter->high * 2); + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: Filter Value=%d\n",filter_val); + #endif switch(filter_val) { case 25: case 50: @@ -625,39 +1815,50 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) { fprintf(stderr,"RIGCTL: FW Filter Act=%d work_int=%d\n",band_filter->high,work_int); #endif send_resp(client_sock,msg); - } else { - // Try to set filters here! - // CW - legal values 50 80 100 150 200 300 400 500 600 1000 2000 - // PiHPSDR map 50 100 100 100 250 250 400 500 600 1000 - // 25 750 - work_int = atoi(&cmd_input[2]); - switch (work_int) { - - case 50: new_low = 25; new_high = 25; break; - case 80: new_low = 50; new_high = 50; break; - case 100: new_low = 50; new_high = 50; break; - case 150: new_low = 50; new_high = 50; break; - case 200: new_low = 125; new_high = 125; break; - case 300: new_low = 125; new_high = 125; break; - case 400: new_low = 200; new_high = 200; break; - case 500: new_low = 250; new_high = 250; break; - case 600: new_low = 300; new_high = 300; break; - case 1000: new_low = 500; new_high = 500; break; - case 2000: new_low = 500; new_high = 500; break; + } else { + // Try to set filters here! + // CW - legal values 50 80 100 150 200 300 400 500 600 1000 2000 + // Pi HPSDR map 50 100 100 100 250 250 400 500 600 1000 + // 25 750 + work_int = atoi(&cmd_input[2]); + int f=5; + switch (work_int) { + + case 50: new_low = 25; new_high = 25; f=8; break; + case 80: new_low = 50; new_high = 50; f=7; break; + case 100: new_low = 50; new_high = 50; f=7; break; + case 150: new_low = 50; new_high = 50; f=7; break; + case 200: new_low = 125; new_high = 125; f=6; break; + case 300: new_low = 125; new_high = 125; f=6; break; + case 400: new_low = 200; new_high = 200; f=5; break; + case 500: new_low = 250; new_high = 250; f=4; break; + case 600: new_low = 300; new_high = 300; f=3; break; + case 1000: new_low = 500; new_high = 500; f=0; break; + case 2000: new_low = 500; new_high = 500; f=0; break; default: new_low = band_filter->low; new_high = band_filter->high; + f=10; - } + } #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: FW Filter new_low=%d new_high=%d\n",new_low,new_high); + fprintf(stderr,"RIGCTL: FW Filter new_low=%d new_high=%d f=%d\n",new_low,new_high,f); #endif // entry->filter = new_low * 2 ; //setFilter(new_low,new_high); - set_filter(active_receiver,new_low,new_high); - g_idle_add(vfo_update,NULL); - } + //set_filter(active_receiver,new_low,new_high); + //g_idle_add(ext_vfo_update,NULL); + g_idle_add(ext_vfo_filter_changed,(gpointer)(long)f); + } + } else { + /* Not in CW mode */ + send_resp(client_sock,"?;"); + } } - else if(strcmp(cmd_str,"GT")==0) { // Sets/Read AGC constant status 000-020 + else if(strcmp(cmd_str,"GT")==0) { + // TS-2000 - GT - Sets/Reads AGC Constant + // PiHPSDR - ZZGT - AGC Constant 0-4 are legal values + if(zzid_flag == 0) { + // Sets/Read AGC constant status 000-020 // Map 000 - Off, 001-4 - Fast, 4-9 - Medium 10-14 Slow 15-20 Long //fprintf(stderr,"GT command seen\n"); int agc_resp = 0; @@ -671,15 +1872,18 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) { case AGC_LONG: agc_resp = 20; break; default: agc_resp = 0; } - - sprintf(msg,"GT%03d;",agc_resp); + if(zzid_flag == 0) { + sprintf(msg,"GT%03d;",agc_resp); + } else { + sprintf(msg,"ZZGT%03d;",agc_resp); + } send_resp(client_sock,msg); } else { //fprintf(stderr,"GT command Set\n"); agc_resp = atoi(&cmd_input[2]); // AGC powers of 84 is broken Hamlib... - // Hamlib TS-2000 is broken here + // Hamlib TS 2000 is broken here if(agc_resp == 0) { active_receiver->agc = AGC_OFF; @@ -696,15 +1900,34 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) { active_receiver->agc = AGC_LONG; // fprintf(stderr,"GT command LONG\n"); } - g_idle_add(vfo_update,NULL); + g_idle_add(ext_vfo_update,NULL); } + } else { + if(len<=2) { + sprintf(msg,"ZZGT%01d;",active_receiver->agc); + send_resp(client_sock,msg); + } else { + int lcl_agc = atoi(&cmd_input[2]); + if(lcl_agc >= AGC_OFF && lcl_agc<=AGC_FAST) { + active_receiver->agc = lcl_agc; + g_idle_add(ext_vfo_update,NULL); + } + } + } } - else if(strcmp(cmd_str,"ID")==0) { // Read ID - Default to TS-2000 which is type 019. - sprintf(msg,"ID019;"); - send_resp(client_sock,msg); - } - else if(strcmp(cmd_str,"IF")==0) { // Reads Transceiver status + else if(strcmp(cmd_str,"ID")==0) { + // TS-2000 - ID - Read ID - Default to TS-2000 which is type 019. + // PiHPSDR - ZZID - Read ID - 240, i.e. hamlib number + if(zzid_flag == 0) { + sprintf(msg,"ID019;"); + } else { + sprintf(msg,"ZZID240;"); + } + send_resp(client_sock,msg); + } + else if((strcmp(cmd_str,"IF")==0) && (zzid_flag == 0)) { + // TS-2000 - IF - Reads Transceiver status // IF // P1: FFFFFFFFFFF -11 chars : Frequency in Hz (blanks are "0") // P2: OFFS - 4 chars : Offset in powers of 10 @@ -724,7 +1947,7 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) { // convert first half of the msg // IF P1 P2 P3 P4 P5 P6 - sprintf(msg,"IF%011lld%04lld%06d%01d%01d%01d", + sprintf(msg,"IF%011lld%04lld%06lld%01d%01d%01d", //getFrequency(), rigctl_getFrequency(), // P1 step, // P2 @@ -743,8 +1966,8 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) { 0, // P10 0, // P11 ft_read(), // P12 - ctcss_tone, // P13 - 0, // P14 + transmitter->ctcss, // P14 + convert_ctcss(), // P13 0); // P15 send_resp(client_sock,msg); } @@ -753,53 +1976,103 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) { send_resp(client_sock,"IS00000;"); } } - else if(strcmp(cmd_str,"KS")==0) { // Sets/Reads keying freq - 0-060 max + else if((strcmp(cmd_str,"KS")==0) && (zzid_flag == 0) || + (strcmp(cmd_str,"CS")==0) && (zzid_flag==1)) { + // TS-2000 - KS - Set/Reads keying speed 0-060 max + // PiHPSDR - ZZCS - Sets/Reads Keying speed if(len <=2) { - sprintf(msg,"KS%03d;",cw_keyer_speed); + if(zzid_flag ==0) { + sprintf(msg,"KS%03d;",cw_keyer_speed); + } else { + sprintf(msg,"ZZCS%02d;",cw_keyer_speed); + } send_resp(client_sock,msg); } else { int key_speed; key_speed = atoi(&cmd_input[2]); - if(key_speed >1 && key_speed <= 60) { + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: Set CW speed=%d",key_speed); + #endif + if(key_speed >= 1 && key_speed <= 60) { cw_keyer_speed=key_speed; - g_idle_add(vfo_update,NULL); + g_idle_add(ext_vfo_update,NULL); + } else { + send_resp(client_sock,"?;"); } } } - else if(strcmp(cmd_str,"KY")==0) { // Convert char to morse code + else if((strcmp(cmd_str,"KY")==0) && (zzid_flag == 0)) { + // TS-2000 - KY - Convert char to morse code - not supported + int index = 2; + long delay = 1200000L/(long)cw_keyer_speed; // uS + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: KY DELAY=%ld, cw_keyer_speed=%d cw_keyer_weight=%d\n",delay,cw_keyer_speed,cw_keyer_weight); + #endif if(len <=2) { send_resp(client_sock,"KY0;"); + } else { + // Set CW BUSY flag + g_mutex_lock(&mutex_c->m); + cw_busy = 1; + g_mutex_unlock(&mutex_c->m); + while((cmd_input[index] != '\0') && (!cw_reset)) { + //fprintf(stderr,"send=%c\n",cmd_input[index]); + rigctl_send_cw_char(cmd_input[index]); + //fprintf(stderr,"RIGCTL: 0 mox=%d\n",mox); + index++; + } + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: KY - Done sending cw\n"); + fprintf(stderr,"RIGCTL: 1 mox=%d\n",mox); + #endif } + g_mutex_lock(&mutex_c->m); + cw_busy = 0; + g_mutex_unlock(&mutex_c->m); + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: 2 mox=%d\n",mox); + #endif } - else if(strcmp(cmd_str,"LK")==0) { // Set/read key lock function status + else if(strcmp(cmd_str,"LK")==0) { + // TS-2000 - LK - Set/read key lock function status + // PiHPSDR - ZZLK - Set/read key lock function status if(len <=2) { - sprintf(msg,"LK%01d%01d;",locked,locked); + if(zzid_flag == 0) { + sprintf(msg,"LK%01d%01d;",locked,locked); + } else { + sprintf(msg,"ZZLK%01d%01d;",locked,locked); + } send_resp(client_sock,msg); } else { - if(cmd_input[3] == '0') { - locked = 0; - } else if(cmd_input[3] == '1') { + if((cmd_input[2] == '1') || (cmd_input[3]=='1')) { locked = 1; + } else { + locked = 0; } - g_idle_add(vfo_update,NULL); + g_idle_add(ext_vfo_update,NULL); } } - else if(strcmp(cmd_str,"LM")==0) { // Set/read DRU 3A unit or elect keyer recording status + else if(strcmp(cmd_str,"LM")==0) { + // TS-2000 - LM - Set/Read DRU 3A keyer recording status - not supported if(len <=2) { - send_resp(client_sock,"LM0;"); + send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"LT")==0) { // Set/read Alt function + else if(strcmp(cmd_str,"LT")==0) { + // TS-2000 - LT - Set/read Alt function - not supported if(len <=2) { - send_resp(client_sock,"LT0;"); + send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"MC")==0) { // Recalls or reads memory channel + else if(strcmp(cmd_str,"MC")==0) { + // TS-2000 - MC - Recalls or reads memory channel - not supported if(len <=2) { - send_resp(client_sock,"MC000;"); // Link this to band stack at some point + send_resp(client_sock,"?;"); // Link this to band stack at some point } } - else if(strcmp(cmd_str,"MD")==0) { // Mode - digit selects mode + else if((strcmp(cmd_str,"MD")==0) && (zzid_flag == 0)) { + // TS-2000 - MD - Set/Read Mode + // Mode - digit selects mode // 1 = LSB // 2 = USB // 3 = CWU @@ -847,22 +2120,22 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) { entry= (BANDSTACK_ENTRY *) bandstack_entry_get_current(); entry->mode=new_mode; - // BUG - kills the system when there is some + // BUG - kills the system when there is some // GPIO activity and Mode sets occur. Used twittling the // frequency along with setting mode between USB/LSB with // flrig. Tried doing the g_idle_add trick - but don't know the // the magic to get that to compile without warnings //setMode(entry->mode); set_mode(active_receiver,entry->mode); - // Moved the vfo_update down after filter updated. (John G0ORX) - //g_idle_add(vfo_update,NULL); + // Moved the ext_vfo_update down after filter updated. (John G0ORX) + //g_idle_add(ext_vfo_update,NULL); FILTER* band_filters=filters[entry->mode]; FILTER* band_filter=&band_filters[entry->filter]; //setFilter(band_filter->low,band_filter->high); set_filter(active_receiver,band_filter->low,band_filter->high); /* Need a way to update VFO info here..*/ - g_idle_add(vfo_update,NULL); + g_idle_add(ext_vfo_update,NULL); } else { // Read Mode int curr_mode; switch (vfo[active_receiver->id].mode) { @@ -876,158 +2149,461 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) { break; case modeFMN: curr_mode = 4; // FMN break; - case modeAM: curr_mode = 5; // AM - break; - case modeDIGU: curr_mode = 9; // DIGU - break; - case modeDIGL: curr_mode = 6; // DIGL - break; - default: - #ifdef RIGCTL_DEBUG - fprintf(stderr, - "RIGCTL: MD command doesn't support %d\n", - vfo[active_receiver->id].mode); - #endif - break; + case modeAM: curr_mode = 5; // AM + break; + case modeDIGU: curr_mode = 9; // DIGU + break; + case modeDIGL: curr_mode = 6; // DIGL + break; + default: + #ifdef RIGCTL_DEBUG + fprintf(stderr, + "RIGCTL: MD command doesn't support %d\n", + vfo[active_receiver->id].mode); + #endif + break; + } + sprintf(msg,"MD%1d;",curr_mode); + send_resp(client_sock,msg); + } + } + else if((strcmp(cmd_str,"MD")==0) && (zzid_flag == 1)) { + // PiHPSDR - ZZMD - Set/Read Modulation Mode + if(len <= 2) { // Set Mode + sprintf(msg,"ZZMD%02d;",vfo[active_receiver->id].mode); + send_resp(client_sock,msg); + } else { + work_int = atoi(&cmd_input[2]); + if((work_int >=0) && (work_int <=11)) { + // Other stuff to switch modes goes here.. + // since new_mode has the interpreted command in + // in it now. + entry= (BANDSTACK_ENTRY *) + bandstack_entry_get_current(); + entry->mode=work_int; + set_mode(active_receiver,entry->mode); + FILTER* band_filters=filters[entry->mode]; + FILTER* band_filter=&band_filters[entry->filter]; + //setFilter(band_filter->low,band_filter->high); + set_filter(active_receiver,band_filter->low,band_filter->high); + /* Need a way to update VFO info here..*/ + g_idle_add(ext_vfo_update,NULL); + } else { + fprintf(stderr,"RIGCTL: Error - ZZMD - Illegal cmd received=%d",work_int); + } + } + } + else if((strcmp(cmd_str,"MF")==0) && (zzid_flag == 0)) { + // TS-2000 - MF - Set/read menu A/B - not supported + if(len <=2) { + send_resp(client_sock,"?;"); + } + } + else if(strcmp(cmd_str,"MG")==0) { + // PiHPSDR - ZZMG - Mic Gain P1=+/-P2=2digits (-10-50) + // TS-2000 - MG - Mike Gain - 3 digits + if(zzid_flag == 0) { + if(len <=2) { + work_int = (int) ((mic_gain +10.0)* 100.0/60.0); + if(zzid_flag == 0) { + sprintf(msg,"MG%03d;",work_int); + } else { + sprintf(msg,"ZZMG%03d;",work_int); + } + send_resp(client_sock,msg); + } else { + int tval = atoi(&cmd_input[2]); + new_vol = (double) (tval * 60/100) - 10; + //set_mic_gain(new_vol); + double *p_mic_gain=malloc(sizeof(double)); + *p_mic_gain=new_vol; + g_idle_add(update_mic_gain,(void *)p_mic_gain); + } + } else { + if(len <=2) { + sprintf(msg,"ZZMG%c%02d;",mic_gain>=0 ? '+' : '-',abs((int)mic_gain)); + send_resp(client_sock,msg); + } else { + int new_vol = atoi(&cmd_input[2]); + if((new_vol >= -10) && (new_vol <= 50)) { + double *p_mic_gain=malloc(sizeof(double)); + *p_mic_gain=new_vol; + g_idle_add(update_mic_gain,(void *)p_mic_gain); + } else { + send_resp(client_sock,"?;"); + } + } + } + } + else if((strcmp(cmd_str,"ML")==0) && (zzid_flag == 0)) { + // TS-2000 - ML - Set/read the monitor function level - not supported + if(len <=2) { + send_resp(client_sock,"?;"); + } + } + else if(strcmp(cmd_str,"MO")==0) { + // TS-2000 - MO - Set Monitor on/off - not supported + if(len <=2) { + send_resp(client_sock,"?;"); + } + } + else if((strcmp(cmd_str,"MR")==0) && (zzid_flag == 0)) { + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: Command seen\n"); + #endif + + // TS-2000 - MR - Read Memory Channel data + sprintf(msg,"MR%1d%1d%02d%011lld%1d%1d%1d%02d%02d%03d%1d%1d%09d%02d%1d%08d;", + 0, // P1 - Rx Freq - 1 Tx Freq + 0, // P2 Bankd and channel number -- see MC comment + 0, // P3 - see MC comment + rigctl_getFrequency(), // P4 - frequency + rigctlGetMode(), // P5 - Mode + locked, // P6 - Locked status + transmitter->ctcss, // P7 - O-off, 1-tone, 2-CTCSS, 3 =DCS + convert_ctcss(), // P8 - Tone Number - see page 35 + convert_ctcss(), // P9 - CTCSS tone number - see CN command + 0, // P10 - DCS code - see QC command + 0, // P11 - Reverse status + 0, // P12 - Shift status - see OS command + 0, // P13 - Offset freq - see OS command + 0, // P14 - Step Size - see ST command + 0, // P15 - Memory Group Number (0-9) + 0); // P16 - Memory Name - 8 char max + send_resp(client_sock,msg); + //send_resp(client_sock,"?;"); + } + else if((strcmp(cmd_str,"MT")==0) && (zzid_flag == 1)) { + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: MT Command seen\n"); + #endif + // PiHPSDR - ZZMT - Read TX Meter Mode + // Mapped from PSDR + // 0= ALC Peak + // 1= ALC Average + // 2= ALG Gain + int * p_alc; + if(len<=2) { + switch((int)alc) { + case TXA_ALC_PK: work_int = 0; break; + case TXA_ALC_AV: work_int = 1; break; + case TXA_ALC_GAIN: work_int = 2; break; + default: work_int = 0; + } + sprintf(msg,"ZZMT%01d;",(int)work_int); + send_resp(client_sock,msg); + } else { + work_int = atoi(&cmd_input[2]); + switch (work_int) { + case 0: work_int = TXA_ALC_PK; break; + case 1: work_int = TXA_ALC_AV; break; + case 2: work_int = TXA_ALC_GAIN; break; + default: work_int = TXA_ALC_PK; + } + p_alc=(int *) malloc(sizeof(double)); + *p_alc=work_int; + g_idle_add(set_alc,(gpointer )p_alc); + } + } + else if(strcmp(cmd_str,"MU")==0) { if(zzid_flag == 1) { + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: MU Command seen\n"); + #endif + // PiHPSDR - ZZMU - Sets or Read the MultiRX status + if(len<=2) { + #ifdef RIGCTL_DEBUG + fprintf(stderr,"ZZMU =%d\n",receivers); + #endif + sprintf(msg,"ZZMU%1d;",receivers); + send_resp(client_sock,msg); + } else { + int lcl_rcvr = atoi(&cmd_input[2]); + #ifdef RIGCTL_DEBUG + fprintf(stderr,"ZZMU Set=%d\n",lcl_rcvr); + #endif + /*if (lcl_rcvr <1 || lcl_rcvr >2) { + fprintf(stderr,"RIGCTL: ZZMU - illegal recevier number\n"); + return; + }*/ + g_idle_add(ext_radio_change_sample_rate,(gpointer)(long)lcl_rcvr); + g_idle_add(ext_vfo_update,NULL); + } + + } else { + // TS-2000 - MU - Set/Read Memory Group Data - not supported + if(len <=2) { + send_resp(client_sock,"MU0000000000;"); + } + } + } + else if((strcmp(cmd_str,"MW")==0) && (zzid_flag == 0)) { + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: MW Command seen\n"); + #endif + // TS-2000 - MW - Store Data to Memory Channel -not supported + } + else if(strcmp(cmd_str,"NB")==0) { + // PiHPSDR - ZZNB - Set/Read Noise Blanker func status (on/off) + // TS-2000 - NB - Set/Read Noise Blanker func status (on/off) + if(len <=2) { + if (zzid_flag == 0) { + sprintf(msg,"NB%1d;",active_receiver->snb); + } else { + sprintf(msg,"ZZNB%1d;",active_receiver->snb); + } + send_resp(client_sock,msg); + } else { + if(cmd_input[2]=='0') { // Turn off ANF + active_receiver->snb=0; + } else { // Turn on ANF + active_receiver->snb=1; + } + // Update filters + SetRXASNBARun(active_receiver->id, active_receiver->snb); + g_idle_add(ext_vfo_update,NULL); + } + } + else if((strcmp(cmd_str,"NE")==0) && (zzid_flag == 1)) { + // PiHPSDR - ZZNE - NPS AE FIlter - DSP Menu + // P1 - 0=Off + // P1 - 1=On + if(len<=2) { + sprintf(msg,"ZZNE%1d;",(int) active_receiver->nr2_ae); + send_resp(client_sock,msg); + } else { + work_int = atoi(&cmd_input[2]); + if(work_int >=0 && work_int <=1) { + active_receiver->nr2_ae = work_int; + SetRXAEMNRaeRun(active_receiver->id, active_receiver->nr2_ae); + } else { + fprintf(stderr,"RIGCTL: ZZNE - ERROR illegal value=%d s/b 0 to 2\n",work_int); + send_resp(client_sock,"?;"); + } + } + } + else if((strcmp(cmd_str,"NG")==0) && (zzid_flag == 1)) { + // PiHPSDR - ZZNG - NR Pre AGC/Post AGC- DSP Menu + if(len<=2) { + sprintf(msg,"ZZNG%1d;",(int) active_receiver->nr_agc); + send_resp(client_sock,msg); + } else { + work_int = atoi(&cmd_input[2]); + if(work_int >=0 && work_int <=1) { + active_receiver->nr_agc = atoi(&cmd_input[2]); + SetRXAEMNRPosition(active_receiver->id, active_receiver->nr_agc); + } else { + fprintf(stderr,"RIGCTL: ZZNG - illegal value=%d s/b 0 or 1\n",work_int); + send_resp(client_sock,"?;"); + } + } + } + + else if((strcmp(cmd_str,"NM")==0) && (zzid_flag == 1)) { + // PiHPSDR - ZZNM - NR2 Gain Method - DSP Menu + // P1 - 0=Linear + // P1 - 1=Log + // P1 - 2=Gamma + if(len<=2) { + sprintf(msg,"ZZNM%1d;",(int) active_receiver->nr2_gain_method); + send_resp(client_sock,msg); + } else { + work_int = atoi(&cmd_input[2]); + if(work_int >=0 && work_int <=2) { + active_receiver->nr2_gain_method = work_int; + SetRXAEMNRgainMethod(active_receiver->id, active_receiver->nr2_gain_method); + } else { + fprintf(stderr,"RIGCTL: ZZNM - illegal value=%d s/b 0 to 2\n",work_int); + send_resp(client_sock,"?;"); + } + } + } + else if(strcmp(cmd_str,"AB")==0) { + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: Command seen\n"); + #endif + } + else if((strcmp(cmd_str,"NP")==0) && (zzid_flag == 1)) { + // PiHPSDR - ZZNP - NPS Method - DSP Menu + // P1 - 0=OSMS + // P1 - 1=MMSE + if(len<=2) { + sprintf(msg,"ZZNP%1d;",(int) active_receiver->nr2_npe_method); + send_resp(client_sock,msg); + } else { + work_int = atoi(&cmd_input[2]); + if(work_int >=0 && work_int <=1) { + active_receiver->nr2_npe_method = work_int; + SetRXAEMNRnpeMethod(active_receiver->id, active_receiver->nr2_npe_method); + } else { + fprintf(stderr, "RIGCTL: ZZNP - ERROR illegal value=%d s/b 0 to 2\n",work_int); + send_resp(client_sock,"?;"); + } + } + } + else if(strcmp(cmd_str,"NL")==0) {if(zzid_flag == 0) { + // TS-2000 - NL - Set/Read Noise Reduction Level - Not Supported + if(len <=2) { + send_resp(client_sock,"?;"); + } + } else { + // PiHPSDR - ZZNL - AGC Hang Threshold - DSP Menu slider + // P1P1P1 - 0 - 100 + if(len <=2) { + sprintf(msg,"ZZNL%03d;",(int) active_receiver->agc_hang_threshold); + send_resp(client_sock,msg); + } else { + work_int = atoi(&cmd_input[2]); + if((work_int >= 0) && (work_int<=100)) { + active_receiver->agc_hang_threshold = work_int; + if(active_receiver->agc==AGC_LONG || active_receiver->agc==AGC_SLOW) { + SetRXAAGCHangThreshold(active_receiver->id, (int)active_receiver->agc_hang_threshold); + } + } + } + } + } + else if(strcmp(cmd_str,"NR")==0) { + // TS-2000 - NR - Set/Read Noise Reduction function status + // PiHPSDR - ZZNR - Set/Read Noise Reduction function status + if(len <=2) { + if(zzid_flag == 0) { + if (active_receiver->nr==1 & active_receiver->nr2==0) { + send_resp(client_sock,"NR1;"); + } else if (active_receiver->nr==1 & active_receiver->nr2==1) { + send_resp(client_sock,"NR2;"); + } else { + send_resp(client_sock,"NR0;"); + } + } else { + if (active_receiver->nr==1 & active_receiver->nr2==0) { + send_resp(client_sock,"ZZNR1;"); + } else if (active_receiver->nr==1 & active_receiver->nr2==1) { + send_resp(client_sock,"ZZNR2;"); + } else { + send_resp(client_sock,"ZZNR0;"); + } + } + } else { + if((atoi(&cmd_input[2]) >=0) && (atoi(&cmd_input[2]) <=2)) { + if(cmd_input[2] == '0') { + active_receiver->nr = 0; + active_receiver->nr2 = 0; + } else if(cmd_input[2] == '1') { + active_receiver->nr = 1; + } else if(cmd_input[2] == '2') { + active_receiver->nr2 = 1; + } + SetRXAANRRun(active_receiver->id, active_receiver->nr); + SetRXAEMNRRun(active_receiver->id, active_receiver->nr2); + g_idle_add(ext_vfo_update,NULL); + } else { + send_resp(client_sock,"?;"); + } + } + } + else if(strcmp(cmd_str,"NT")==0) { + // TS-2000 - NT - Set/Read autonotch function - + // PiHPSDR - ZZNT - Sets/reads ANF status + if(len <=2) { + if(zzid_flag == 0) { + sprintf(msg,"NT%1d;",active_receiver->anf); + } else { + sprintf(msg,"ZZNT%1d;",active_receiver->anf); } - sprintf(msg,"MD%1d;",curr_mode); - send_resp(client_sock,msg); - } - } - else if(strcmp(cmd_str,"MF")==0) { // Set/read menu A/B - if(len <=2) { - send_resp(client_sock,"MF0;"); - } - } - else if(strcmp(cmd_str,"MG")==0) { // Mike Gain - 3 digit value - if(len <=2) { - work_int = (int) ((mic_gain +10.0)* 100.0/60.0); - sprintf(msg,"MG%03d;",work_int); - send_resp(client_sock,msg); - } else { - int tval = atoi(&cmd_input[2]); - new_vol = (double) (tval * 60/100) - 10; - //set_mic_gain(new_vol); - double *p_mic_gain=malloc(sizeof(double)); - *p_mic_gain=new_vol; - g_idle_add(update_mic_gain,(void *)p_mic_gain); - } - } - else if(strcmp(cmd_str,"ML")==0) { // Set/read the monitor function level - if(len <=2) { - send_resp(client_sock,"ML000;"); - } - } - else if(strcmp(cmd_str,"MO")==0) { // Set Monitor on/off - if(len <=2) { - send_resp(client_sock,"MO0;"); - } - } - /* Not supported */ - else if(strcmp(cmd_str,"MR")==0) { // Read Memory Channel data - sprintf(msg,"MR%1d%02d%02d%011lld%1d%1d%1d%02d%02d%03d%1d%1d%09d%02d%1d%08d;", - 0, // P1 - Rx Freq - 1 Tx Freq - 0, // P2 Bankd and channel number -- see MC comment - 0, // P3 - see MC comment - rigctl_getFrequency(), // P4 - frequency - rigctlGetMode(), // P5 - Mode - locked, // P6 - Locked status - 0, // P7 - O-off, 1-tone, 2-CTCSS, 3 =DCS - 0, // P8 - Tone Number - see page 35 - ctcss_tone, // P9 - CTCSS tone number - see CN command - 0, // P10 - DCS code - see QC command - 0, // P11 - Reverse status - 0, // P12 - Shift status - see OS command - 0, // P13 - Offset freq - see OS command - 0, // P14 - Step Size - see ST command - 0, // P15 - Memory Group Number (0-9) - 0); // P16 - Memory Name - 8 char max - //send_resp(client_sock,msg); - send_resp(client_sock,"?;"); - } - else if(strcmp(cmd_str,"MU")==0) { // Set/Read Memory Group Data - if(len <=2) { - send_resp(client_sock,"MU0000000000;"); - } - } - else if(strcmp(cmd_str,"MW")==0) { // Store Data to Memory Channel - } - else if(strcmp(cmd_str,"NB")==0) { // Set/Read Noise Blanker func status (on/off) - if(len <=2) { - sprintf(msg,"NB%1d;",active_receiver->snb); send_resp(client_sock,msg); } else { - if(cmd_input[2]=='0') { // Turn off ANF - active_receiver->snb=0; - } else { // Turn on ANF - active_receiver->snb=1; + if((atoi(&cmd_input[2]) >=0) && (atoi(&cmd_input[2]) <=1)) { + if(cmd_input[2] == '0') { // Clear ANF + active_receiver->anf = 0; + } else { // Set ANF + active_receiver->anf = 1; + } + } else { + send_resp(client_sock,"?;"); } - // Update filters - SetRXASNBARun(active_receiver->id, active_receiver->snb); - g_idle_add(vfo_update,NULL); } - } - else if(strcmp(cmd_str,"NL")==0) { // Set/Read Noise Reduction Level - if(len <=2) { - send_resp(client_sock,"NL000;"); + SetRXAANFRun(active_receiver->id, active_receiver->anf); + g_idle_add(ext_vfo_update,NULL); + } + else if((strcmp(cmd_str,"OA")==0) && (zzid_flag ==1)) { + // PiHPSDR - ZZOA - Set/Read RX Antenna by band + // P1P1P1 - Band + // P2 - 1,2,3,EXT1,EXT2, XVTR + int int_band; + int b; + if(len<=5) { + int_band = atoi(&cmd_input[2]); + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL OA band =%d\n",int_band); + #endif + //b = lookup_band(int_band); + BAND *band=band_get_band(int_band); + work_int = band->alexRxAntenna; + sprintf(msg,"ZZOA%03d%1d;",int_band,work_int); + send_resp(client_sock,msg); + } else { + char lcl_char = cmd_input[5]; + cmd_input[5] = '\0'; + b = atoi(&cmd_input[2]); + //b = lookup_band(int_band); + cmd_input[5] = lcl_char; + work_int = atoi(&cmd_input[5]); + if(work_int >=0 && work_int <=5) { + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL ZZOA Band=%d Val=%d\n",b,work_int); + #endif + BAND *band=band_get_band(b); + band->alexRxAntenna = work_int; + } else { + fprintf(stderr,"RIGCTL ZZOA illegal val Band=%d Val=%d\n",int_band,work_int); + } } } - else if(strcmp(cmd_str,"NR")==0) { // Set/Read Noise Reduction function status - if(len <=2) { -/* - if(nr_none == 1) { - send_resp(client_sock,"NR0;"); - } else if ((nr_none == 0) && (nr==1)) { - send_resp(client_sock,"NR1;"); - } else if (nr2 == 1) { - send_resp(client_sock,"NR2;"); - } else { - send_resp(client_sock,"NR0;"); - } -*/ + else if((strcmp(cmd_str,"OB")==0) && (zzid_flag ==1)) { + // PiHPSDR - ZZOB - Set/Read TX Antenna by band + // P1P1P1 - Band + // P2 - 1,2,3 + int int_band; + int b ; + if(len<=5) { + int_band = atoi(&cmd_input[2]); + //b = lookup_band(int_band); + b = int_band; + BAND *band=band_get_band(b); + work_int = band->alexTxAntenna; + sprintf(msg,"ZZOB%03d%1d;",int_band,work_int); + send_resp(client_sock,msg); - // FIX now allow multiple set - if (active_receiver->nr==1) { - send_resp(client_sock,"NR1;"); - } else { - send_resp(client_sock,"NR0;"); - } - } else { - if(cmd_input[2] == '0') { - active_receiver->nr = 0; - active_receiver->nr2 = 0; - } else if(cmd_input[2] == '1') { - active_receiver->nr = 1; - } else if(cmd_input[2] == '2') { - active_receiver->nr2 = 1; - } - SetRXAANRRun(active_receiver->id, active_receiver->nr); - SetRXAEMNRRun(active_receiver->id, active_receiver->nr2); - g_idle_add(vfo_update,NULL); - } - } - else if(strcmp(cmd_str,"NT")==0) { // Set/Read autonotch function - if(len <=2) { - sprintf(msg,"NT%1d;",active_receiver->anf); - send_resp(client_sock,msg); } else { - if(cmd_input[2] == '0') { // Clear ANF - active_receiver->anf = 0; - } else { // Set ANF - active_receiver->anf = 1; - } + char lcl_char = cmd_input[5]; + cmd_input[5] = '\0'; + int_band = atoi(&cmd_input[2]); + //b = lookup_band(int_band); + b = int_band; + cmd_input[5] = lcl_char; + work_int = atoi(&cmd_input[5]); + if(work_int >=0 && work_int <=2) { + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL ZZOB Band=%d Val=%d\n",int_band,work_int); + #endif + BAND *band=band_get_band(b); + band->alexTxAntenna = work_int; + } else { + fprintf(stderr,"RIGCTL ZZOB illegal val Band=%d Val=%d\n",int_band,work_int); + } } - SetRXAANFRun(active_receiver->id, active_receiver->anf); - g_idle_add(vfo_update,NULL); } - else if(strcmp(cmd_str,"OF")==0) { // Set/Read Offset freq (9 digits - hz) + else if((strcmp(cmd_str,"OF")==0) && (zzid_flag == 0)) { + // TS-2000 - OF - Set/Read Offset freq (9 digits - hz) -not supported if(len <=2) { - send_resp(client_sock,"OF000000000;"); + //send_resp(client_sock,"OF000000000;"); + send_resp(client_sock,"?;"); } } /* Not Supported */ - else if(strcmp(cmd_str,"OI")==0) { // Read Memory Channel Data - if(len <=2) { + else if((strcmp(cmd_str,"OI")==0) && (zzid_flag == 0)) { + // TS-2000 - OI - Read Memory Channel Data - not supported + /*if(len <=2) { sprintf(msg,"OI%011lld%04d%06d%1d%1d%1d%02d%1d%1d%1d%1d%1d%1d%02d%1d;", rigctl_getFrequency(), 0, // P2 - Freq Step size @@ -1043,146 +2619,295 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) { 0, // P13 Off, 1, 2, 0,// P14 Tone freq - See TN command 0,0); + */ send_resp(client_sock,"?;"); - } } - else if(strcmp(cmd_str,"OS")==0) { // Set/Read Offset freq (9 digits - hz) + else if(strcmp(cmd_str,"OS")==0) { + // TS-2000 - OS - Set/Read Offset freq (9 digits - hz) -not supported if(len <=2) { //send_resp(client_sock,"OS0;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"PA")==0) { // Set/Read Preamp function status + else if(strcmp(cmd_str,"PA")==0) { + // TS-2000 - PA - Set/Read Preamp function status + // PiHPSDR - ZZPA - Set/Read Preamp function status if(len <=2) { - sprintf(msg,"PA0%1d;",enable_tx_equalizer); + if(zzid_flag == 0) { + sprintf(msg,"PA%1d%1d;",active_receiver->preamp,active_receiver->preamp); + } else { + sprintf(msg,"ZZPA%1d;",active_receiver->preamp); + } send_resp(client_sock,msg); } else { - if(cmd_input[2] =='0') { - enable_tx_equalizer=0; - SetTXAEQRun(transmitter->id, enable_tx_equalizer); + work_int = atoi(&cmd_input[2]); + if((work_int >= 0) && (work_int <= 1)) { + active_receiver->preamp = work_int; } else { - enable_tx_equalizer=1; - SetTXAEQRun(transmitter->id, enable_tx_equalizer); + send_resp(client_sock,"?;"); } } } - else if(strcmp(cmd_str,"PB")==0) { // Set/Read DRU-3A Playback status + else if(strcmp(cmd_str,"PB")==0) { + // TS-2000 - PB - DRU-3A Playback status - not supported if(len <=2) { - send_resp(client_sock,"PB0;"); + send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"PC")==0) { // Set/Read Drive Power output + else if(strcmp(cmd_str,"PC")==0) { + // TS-2000 - PC - Set/Read Drive Power output + // PiHPSDR - ZZPC - Set/Read Drive Power output if(len<=2) { - sprintf(msg,"PC%03d;",(int) drive); + if(zzid_flag == 0) { + sprintf(msg,"PC%03d;",(int) transmitter->drive); + } else { + sprintf(msg,"ZZPC%03d;",(int) transmitter->drive); + } send_resp(client_sock,msg); } else { - // Power Control - 3 digit number- 0 to 100 - //Scales to 0.00-1.00 + int lcl_pc = atoi(&cmd_input[2]); + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: PC received=%d\n",lcl_pc); + #endif + if((lcl_pc >=0) && (lcl_pc<=100)) { + // Power Control - 3 digit number- 0 to 100 + //Scales to 0.00-1.00 - double drive_val = - (double)(atoi(&cmd_input[2])); - // setDrive(drive_val); - double *p_drive=malloc(sizeof(double)); - *p_drive=drive_val; - g_idle_add(update_drive,(gpointer)p_drive); - //set_drive(drive_val); + double drive_val = + (double)(atoi(&cmd_input[2])); + // setDrive(drive_val); + double *p_drive=malloc(sizeof(double)); + *p_drive=drive_val; + g_idle_add(update_drive,(gpointer)p_drive); + //set_drive(drive_val); + } else { + fprintf(stderr,"RIGCTL: PC received=%d - Illegal value\n",lcl_pc); + send_resp(client_sock,"?;"); + } } } - else if(strcmp(cmd_str,"PI")==0) { // STore the programmable memory channel + else if((strcmp(cmd_str,"PI")==0) && (zzid_flag == 0)) + { + // TS-2000 - PI - Store the programmable memory channel - not supported } - else if(strcmp(cmd_str,"PK")==0) { // Reads the packet cluster data - // send_resp(client_sock,"PK000000000000000000000000000000000000000000000000;"); + else if(strcmp(cmd_str,"PK")==0) { + // TS-2000 - PK - Reads the packet cluster data - not supported + // send_resp(client_sock,"PK000000000000000000000000000000000000000000000000;"); send_resp(client_sock,"?;"); } - else if(strcmp(cmd_str,"PL")==0) { // Set/Read Speech processor level + else if((strcmp(cmd_str,"PL")==0) && (zzid_flag == 0)) { + // TS-2000 - PL - Set/Read Speech processor level + // PL 000 000 ; // P1 000 - min-100 max // P2 000 - min - 100 max + double lcl_comp_level; if(len <=2) { // send_resp(client_sock,"PL000000;"); - send_resp(client_sock,"?;"); + lcl_comp_level = 100 *(transmitter->compressor_level)/20; + sprintf(msg,"PL%03d000;",(int)lcl_comp_level); + send_resp(client_sock,msg); + } else { + // Isolate 1st command + cmd_input[5] = '\0'; + lcl_comp_level = 20.0 *(((double)atoi(&cmd_input[2]))/100.0); + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL - PR new level=%f4.1",lcl_comp_level); + #endif + transmitter_set_compressor_level(transmitter,lcl_comp_level); + g_idle_add(ext_vfo_update,NULL); + //transmitter->compressor_level = lcl_comp_level; } } - else if(strcmp(cmd_str,"PM")==0) { // Recalls the Programmable memory + else if((strcmp(cmd_str,"PM")==0) && ( zzid_flag == 0)) { + // TS-2000 - PM - Recalls the Programmable memory - not supported if(len <=2) { //send_resp(client_sock,"PM0;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"PR")==0) { // Sets/reads the speech processor function on/off + else if((strcmp(cmd_str,"PR")==0) && (zzid_flag == 0)) { + // TS-2000 - PR - Sets/reads the speech processor function on/off // 0 - off, 1=on if(len <=2) { - //send_resp(client_sock,"PR0;"); - send_resp(client_sock,"?;"); + sprintf(msg,"PR%01d;",transmitter->compressor); + send_resp(client_sock,msg); + } else { + transmitter_set_compressor(transmitter,atoi(&cmd_input[2])); + + g_idle_add(ext_vfo_update,NULL); + //transmitter->compressor = atoi(&cmd_input[2]); } } - else if(strcmp(cmd_str,"PS")==0) { // Sets/reads Power on/off state + else if(strcmp(cmd_str,"PS")==0) { + // PiHPSDR - ZZPS - Sets/reads Power on/off state- always on + // TS-2000 - PS - Sets/reads Power on/off state // 0 - off, 1=on if(len <=2) { send_resp(client_sock,"PS1;"); // Lets pretend we're powered up ;-) } } - else if(strcmp(cmd_str,"QC")==0) { // Sets/reads DCS code + else if(strcmp(cmd_str,"PZ")==0) { if(zzid_flag == 1) { + // PiHPSDR - ZZPZ - Sets/Reads Radio Sample Rate + // Valid values are 048000, 096000, 192000, 384000 + #ifdef RIGCTL_DEBUG + fprintf(stderr,"ZZPZ command\n"); + #endif + if(len<=2) { + sprintf(msg,"ZZPZ%06d;",active_receiver->sample_rate); + send_resp(client_sock,msg); + } else { + long lcl_rate = atoi(&cmd_input[2]); + #ifdef RIGCTL_DEBUG + fprintf(stderr,"ZZPZ Set=%ld\n",lcl_rate); + #endif + if (lcl_rate !=48000L && lcl_rate !=96000L && + lcl_rate !=192000L && lcl_rate != 384000L) { + fprintf(stderr,"RIGCTL: ZZPZ - illegal frequency=%ld\n",lcl_rate); + send_resp(client_sock,"?;"); + return; + } + + g_idle_add(ext_radio_change_sample_rate,(gpointer)(long)lcl_rate); + g_idle_add(ext_vfo_update,NULL); + } + } + } + else if(strcmp(cmd_str,"QC")==0) { + // TS-2000 - QC - Sets/reads DCS code - not supported // Codes numbered from 000 to 103. if(len <=2) { - //send_resp(client_sock,"QC000;"); // Lets pretend we're powered up ;-) + //send_resp(client_sock,"QC000;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"QI")==0) { // Store the settings in quick memory + else if(strcmp(cmd_str,"QI")==0) { + // TS-2000 - QI - Store the settings in quick memory - not supported } - else if(strcmp(cmd_str,"QR")==0) { // Send the Quick memory channel data + else if(strcmp(cmd_str,"QR")==0) { + // TS-2000 - QR - Send the Quick memory channel data - not supported // P1 - Quick mem off, 1 quick mem on // P2 - Quick mem channel number if(len <=2) { - //send_resp(client_sock,"QR00;"); // Lets pretend we're powered up ;-) + //send_resp(client_sock,"QR00;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"RA")==0) { // Sets/reads Attenuator function status + else if((strcmp(cmd_str,"RA")==0) && (zzid_flag == 0)) { + // TS-2000 - RA - Sets/reads Attenuator function status // 00-off, 1-99 -on - Main and sub receivers reported + int lcl_attenuation; + float calc_atten; if(len <=2) { //send_resp(client_sock,"RA0000;"); - send_resp(client_sock,"?;"); + calc_atten = round((float)active_receiver->attenuation*99.0/30.0); + if(calc_atten > 99.0) { + calc_atten = 99.0; + } + sprintf(msg,"RA%02d%02d;",(int)calc_atten,(int)calc_atten); + send_resp(client_sock,msg); + } else { + lcl_attenuation = atoi(&cmd_input[2]); + if((lcl_attenuation >=0) && (lcl_attenuation <= 99)) { + lcl_attenuation = (int)((float)lcl_attenuation * 30.0/99.0); + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: lcl_att=%d\n",lcl_attenuation); + #endif + //set_attenuation(lcl_attenuation); + set_attenuation_value((double) lcl_attenuation); + g_idle_add(ext_vfo_update,NULL); + } else { + send_resp(client_sock,"?;"); + } } } - else if(strcmp(cmd_str,"RC")==0) { // Clears the RIT offset freq - } - else if(strcmp(cmd_str,"RD")==0) { // Move the RIT offset freq down, slow down the scan speed in scan mode - if(len <=2) { - vfo[active_receiver->id].rit = vfo[active_receiver->id].rit-rit_increment; - sprintf(msg,"RD%1d;",rit_on()); - send_resp(client_sock,msg); + else if(strcmp(cmd_str,"RC")==0) { + // TS-2000 - RC - Clears the RIT offset freq + // PiHPSDR - ZZRC - Clears the RIT offset freq + vfo[active_receiver->id].rit = 0; + g_idle_add(ext_vfo_update,NULL); + } + else if(strcmp(cmd_str,"RD")==0) { // + // TS-2000 - RD - Move the RIT offset freq down - P1=rit_increment! + // P1=No Argument - decrement frequency + // P1=NonZero - load rit offset + // FS controls fine variable 1 or 0. rit increment 1 hz or 10hz + // PiHPSDR - ZZRD - Move the RIT offset freq down by rit_increment + int lcl_rit; + int lcl_rit_increment = fine ? 1 : 10; + if(len <=2) { + vfo[active_receiver->id].rit = vfo[active_receiver->id].rit-lcl_rit_increment; } else { if(len > 3) { - // Non scan mode when RDxxxxx; - - vfo[active_receiver->id].rit = vfo[active_receiver->id].rit-rit_increment; + lcl_rit = atoi(&cmd_input[2]); + if((lcl_rit >=0) &&(lcl_rit <=99999)) { + vfo[active_receiver->id].rit = -lcl_rit; + } else { + send_resp(client_sock,"?;"); + } } } - g_idle_add(vfo_update,NULL); - } - else if(strcmp(cmd_str,"RG")==0) { // RF Gain - 3 digit number - // RG123; 0-255 value - // Scale from -20 - 120 - if(len>4) { // Set Audio Gain - int base_value = atoi(&cmd_input[2]); - double new_gain = ((((double) base_value)/255) * 140) - 20; - //set_agc_gain(new_gain); - double *p_gain=malloc(sizeof(double)); - *p_gain=new_gain; - g_idle_add(update_agc_gain,(gpointer)p_gain); - } else { // Read Audio Gain - sprintf(msg,"RG%03d;",((256 * (int) active_receiver->agc_gain)/140)+36); - send_resp(client_sock,msg); + g_idle_add(ext_vfo_update,NULL); + } + else if((strcmp(cmd_str,"RF")==0) && (zzid_flag == 1)) { + // PiHPSDR - ZZRR - Read Forward Power + forward = transmitter->fwd; + sprintf(msg,"RF%09.7f;",forward); + send_resp(client_sock,msg); + } + else if(strcmp(cmd_str,"RG")==0) { + // TS-2000 - RG - RF Gain Control + // PiHPSDR - ZZRG - AGC Gain Control -20 to 120 legal range + // TS 2000 settings 0-255 value scaled to -20 to 120 range + if(zzid_flag == 0) { + if(len>4) { // Set Audio Gain + int base_value = atoi(&cmd_input[2]); + double new_gain = roundf(((((double) base_value+1)/256.0) * 141.0))- 21.0; + //set_agc_gain(new_gain); + double *p_gain=malloc(sizeof(double)); + *p_gain=new_gain; + g_idle_add(ext_update_agc_gain,(gpointer)p_gain); + } else { // Read Audio Gain + double lcl_gain = (active_receiver->agc_gain+21.0)/141.0; + sprintf(msg,"RG%03d;",(int)((256.0 * lcl_gain) -1)); + send_resp(client_sock,msg); + } + } else { + // Pi HPSDR version + if(len <= 2) { + if(active_receiver->agc_gain<0) { + sprintf(msg,"ZZRG-%03d;",(int) abs((int)active_receiver->agc_gain)); + } else { + sprintf(msg,"ZZRG+%03d;",(int)active_receiver->agc_gain); + } + send_resp(client_sock,msg); + + } else { + work_int = atoi(&cmd_input[3]); + if(cmd_input[2] == '-') { // Negative number found + work_int = -work_int; + } + if((work_int >= -20) && (work_int <=120)) { + double *p_gain=malloc(sizeof(double)); + *p_gain=(double) work_int; + g_idle_add(ext_update_agc_gain,(gpointer)p_gain); + } else { + fprintf(stderr,"RIGCTL: ZZRG ERROR - Illegal AGC Value=%d\n", work_int); + send_resp(client_sock,"?;"); + } + } } + g_idle_add(ext_vfo_update,NULL); } - else if(strcmp(cmd_str,"RL")==0) { // Set/read Noise reduction level + else if((strcmp(cmd_str,"RL")==0) && (zzid_flag == 0)) { + // TS-2000 - RL - Set/read Noise reduction level - not supported if(len <=2) { //send_resp(client_sock,"RL00;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"RM")==0) { // Set/read Meter function + else if((strcmp(cmd_str,"RM")==0) && (zzid_flag == 0)) { + // TS-2000 - RM - Set/read Meter function - not supported // P1- 0, unsel, 1 SWR, 2 Comp, 3 ALC // P2 - 4 dig - Meter value in dots - 000-0030 if(len <=2) { @@ -1190,88 +2915,147 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) { send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"RT")==0) { // Set/read the RIT function status + else if((strcmp(cmd_str,"RR")==0) && (zzid_flag == 1)) { + // PiHPSDR - ZZRR - Read Reverse Power + reverse = transmitter->rev; + sprintf(msg,"RR%09.7f;",reverse); + send_resp(client_sock,msg); + } + else if((strcmp(cmd_str,"RS")==0) && (zzid_flag == 1)) { + // PiHPSDR - ZZRS - Read SWR + forward = transmitter->fwd; + reverse = transmitter->rev; + vswr = (forward+reverse)/(forward-reverse); + sprintf(msg,"RS%04.2f;",vswr); + send_resp(client_sock,msg); + } + else if(strcmp(cmd_str,"RT")==0) { + // TS-2000 - RT - Set/read the RIT function status + // PiHPSDR - ZZRT - Set/read the RIT function status + int lcl_rit_val; if(len <=2) { - sprintf(msg,"RT%01d;",rit_on()); - send_resp(client_sock,msg); + if(zzid_flag == 0) { + sprintf(msg,"RT%01d;",rit_on()); + } else { + sprintf(msg,"ZZRT%01d;",rit_on()); + } + send_resp(client_sock,msg); } else { - if(atoi(&cmd_input[2]) == 0) { - vfo[active_receiver->id].rit = 0; + lcl_rit_val = atoi(&cmd_input[2]); + if((lcl_rit_val >=0) && (lcl_rit_val <=1)) { + vfo[active_receiver->id].rit = lcl_rit_val; + } else { + send_resp(client_sock,"?;"); } } } - else if(strcmp(cmd_str,"RU")==0) { // Set/move RIT frequency up + else if(strcmp(cmd_str,"RU")==0) { + // TS-2000 - RU - Set/move RIT frequency up + // PiHPSDR - ZZRU - Set/move RIT frequency up + int lcl_incr; if(len <=2) { - vfo[active_receiver->id].rit = vfo[active_receiver->id].rit+rit_increment; - sprintf(msg,"RU%01d;",rit_on()); - send_resp(client_sock,msg); + lcl_incr = fine ? 1 : 10; + vfo[active_receiver->id].rit = vfo[active_receiver->id].rit+lcl_incr; } else { if(len > 3) { - vfo[active_receiver->id].rit = vfo[active_receiver->id].rit+rit_increment; + lcl_incr = atoi(&cmd_input[2]); + if((lcl_incr >=0) && (lcl_incr <= 99999)) { + vfo[active_receiver->id].rit = lcl_incr; + } else { + send_resp(client_sock,"?;"); + } } } - g_idle_add(vfo_update,NULL); + g_idle_add(ext_vfo_update,NULL); } - else if(strcmp(cmd_str,"RX")==0) { // Unkey Xmitter + else if(strcmp(cmd_str,"RX")==0) { + // TS-2000 - RX - Unkey Xmitter + // PiHPSDR - ZZRX - Unkey Xmitter //setMox(0); - mox_state=0; - g_idle_add(mox_update,(gpointer)mox_state); - g_idle_add(vfo_update,NULL); + if(!((vfo[active_receiver->id].mode == modeCWL) || + (vfo[active_receiver->id].mode == modeCWU))) { + #ifdef RIGCTL_DEBUG + fprintf(stderr, "RIGCTL: Inside RX command\n"); + #endif + mox_state=0; + g_idle_add(ext_mox_update,(gpointer)(long)mox_state); + g_idle_add(ext_vfo_update,NULL); + } else { + // Clear External MOX in CW mode + g_idle_add(ext_mox_update,(gpointer)(long)0); // Turn on xmitter (set Mox) + } } - else if(strcmp(cmd_str,"SA")==0) { // Set/reads satellite mode status + else if(strcmp(cmd_str,"SA")==0) { + // TS-2000 - SA - Set/reads satellite mode status - not supported // 0-main, 1=sub if(len <=2) { //send_resp(client_sock,"SA000000000000000;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"SB")==0) { // Set/read the SUB TF-W status + else if(strcmp(cmd_str,"SB")==0) { + // TS-2000 - SB - Set/read the SUB TF-W status - not supported if(len <=2) { //send_resp(client_sock,"SB0;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"SC")==0) { // Set/read the Scan function status + else if(strcmp(cmd_str,"SC")==0) { + // TS-2000 - SC - Set/read the Scan function status - not supported if(len <=2) { //send_resp(client_sock,"SC0;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"SD")==0) { // Set/read CW break-in time delay + else if((strcmp(cmd_str,"SD")==0) && (zzid_flag == 0) || + (strcmp(cmd_str,"CD")==0) && (zzid_flag ==1)) { + // PiHPSDR - ZZCD - Set/Read CW Keyer Hang Time + // TS-2000 - SD - Set/Read Break In Delay + // // 0000-1000 ms (in steps of 50 ms) 0000 is full break in - int local_cw_breakin=cw_keyer_hang_time; - // Limit report value to 1000 for TS-2000 - if(local_cw_breakin > 1000) { local_cw_breakin = 1000; } - if(len <=2) { - sprintf(msg,"SD%04d;",local_cw_breakin); - send_resp(client_sock,msg); - } else { - local_cw_breakin = atoi(&cmd_input[2]); - if(cw_keyer_hang_time <= 1000) { - if(local_cw_breakin==0) { - cw_breakin = 1; - } else { - cw_breakin = 0; - } - cw_keyer_hang_time = local_cw_breakin; - } - } + int local_cw_breakin=cw_keyer_hang_time; + // Limit report value to 1000 for TS 2000 + if(local_cw_breakin > 1000) { local_cw_breakin = 1000; } + if(len <=2) { + if(zzid_flag == 0) { // TS 2000 + sprintf(msg,"SD%04d;",local_cw_breakin); + } else { // ZZ command response + sprintf(msg,"ZZCD%04d;",local_cw_breakin); + } + send_resp(client_sock,msg); + } else { + local_cw_breakin = atoi(&cmd_input[2]); + if(cw_keyer_hang_time <= 1000) { + if(local_cw_breakin==0) { + cw_breakin = 1; + } else { + cw_breakin = 0; + } + cw_keyer_hang_time = local_cw_breakin; + } + } + } - else if(strcmp(cmd_str,"SH")==0) { // Set/read the DSP filter settings + else if(strcmp(cmd_str,"SH")==0) { + // TS-2000 - SH - Set/read the DSP filter settings - not supported if(len <=2) { // send_resp(client_sock,"SH00;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"SI")==0) { // Enters the satellite memory name + else if(strcmp(cmd_str,"SI")==0) { + // TS-2000 - SI - Enters the satellite memory name - not supported } - else if(strcmp(cmd_str,"SL")==0) { // Set/read the DSP filter settings - this appears twice? See SH + else if(strcmp(cmd_str,"SL")==0) { + // TS-2000 - SL - Set/read the DSP filter settings - not supported if(len <=2) { //send_resp(client_sock,"SL00;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"SM")==0) { // Read SMETER + else if(strcmp(cmd_str,"SM")==0) { + // PiHPSDR - ZZSM - Read SMeter - same range as TS 2000 + // TI-2000 - SM - Read SMETER // SMx; x=0 RX1, x=1 RX2 // meter is in dbm - value will be 0<260 // Translate to 00-30 for main, 0-15 fo sub @@ -1307,35 +3091,69 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) { if(new_level < 0) { new_level = 0; } if(new_level > 15) { new_level = 15;} } - sprintf(msg,"SM%1c%04d;", - cmd_input[2],new_level); + if(zzid_flag == 0) { + sprintf(msg,"SM%1c%04d;", + cmd_input[2],new_level); + } else { + sprintf(msg,"ZZSM%1c%04d;", + cmd_input[2],new_level); + } send_resp(client_sock,msg); } - else if(strcmp(cmd_str,"SQ")==0) { // Set/read the squelch level + + else if(strcmp(cmd_str,"SQ")==0) { + // TS-2000 - SQ - Set/read the squelch level - not supported // P1 - 0- main, 1=sub // P2 - 0-255 + float float_sq; + if(len <=3) { - sprintf(msg,"SQ%04d;",squelch); - send_resp(client_sock,msg); - } else { - squelch = atoi(&cmd_input[2]); + float_sq = (float) active_receiver->squelch; + float_sq = roundf((float_sq/100.0)*256.0); + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: float_sq=%6.2f\n", + float_sq); + #endif + sprintf(msg,"SQ0%03d;",(int) float_sq); + send_resp(client_sock,msg); + } else { // Set the value + int lcl_sq = atoi(&cmd_input[3]); // Note we skip the first char! + if((lcl_sq >= 0) && (lcl_sq <=255)) { + float_sq = roundf(((float)lcl_sq/256.0)*100); + active_receiver->squelch = (int)float_sq; + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: SetSq float_sq=%6.2f\n", + float_sq); + #endif + + //setSquelch(active_receiver); + g_idle_add(ext_update_squelch,NULL); + g_idle_add(ext_vfo_update,NULL); + } else { + send_resp(client_sock,"?;"); + } } + } + + else if(strcmp(cmd_str,"SR")==0) { + // TS-2000 - SR - Resets the transceiver - not supported } - else if(strcmp(cmd_str,"SR")==0) { // Resets the transceiver - } - else if(strcmp(cmd_str,"SS")==0) { // Set/read Scan pause freq + else if(strcmp(cmd_str,"SS")==0) { + // TS-2000 - SS - Set/read Scan pause freq - not supported if(len <=2) { //send_resp(client_sock,"SS0;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"ST")==0) { // Set/read the multi/ch control freq steps + else if(strcmp(cmd_str,"ST")==0) { + // TS-2000 - ST - Set/read the multi/ch control freq steps + // PiHPSDR - ZZST - Set/read the multi/ch control freq steps // SSB/CW/FSK - values 00-03 // 00: 1KHz, 01: 2.5Khz 02:5KHz 03: 10Khz // AM/FM mode 00-09 // 00: 5KHz, // 01: 6.25KHz, - // 02:10Khz, + // 02: 10Khz, // 03: 12.5Khz, // 04: 15Khz, // 05: 20Khz, @@ -1343,6 +3161,7 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) { // 07: 30Khz // 08: 50Khz // 09: 100Khz + if(zzid_flag == 0) { int coded_step_val; entry= (BANDSTACK_ENTRY *) bandstack_entry_get_current(); @@ -1391,7 +3210,11 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) { } break; } - sprintf(msg,"ST%02d;",coded_step_val); + if(zzid_flag == 0) { + sprintf(msg,"ST%02d;",coded_step_val); + } else { + sprintf(msg,"ZZST%02d;",coded_step_val); + } send_resp(client_sock,msg); } else { coded_step_val = atoi(&cmd_input[2]); @@ -1424,83 +3247,210 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) { } default: break; // No change if not a valid number } - g_idle_add(vfo_update,NULL); } + } else { + // Pi HPSDR handling + if(len <= 2) { + sprintf(msg,"ZZST%06lld;", step); + send_resp(client_sock,msg); + } else { + int okay= 0; + work_int = atoi(&cmd_input[2]); + switch(work_int) { + case 100000: okay = 1; break; + case 50000: okay = 1; break; + case 30000: okay = 1; break; + case 25000: okay = 1; break; + case 20000: okay = 1; break; + case 15000: okay = 1; break; + case 12500: okay = 1; break; + case 10000: okay = 1; break; + case 9000: okay = 1; break; + case 6250: okay = 1; break; + case 5000: okay = 1; break; + case 2500: okay = 1; break; + case 1000: okay = 1; break; + case 500: okay = 1; break; + case 250: okay = 1; break; + case 100: okay = 1; break; + case 50: okay = 1; break; + case 10: okay = 1; break; + case 1: okay = 1; break; + default: okay = 0; break; + } + if(okay == 0) { + fprintf(stderr,"RIGCTL: ZZST ERROR - illegal step val=%d\n",work_int); + send_resp(client_sock,"?;"); + } else { + step = work_int; + } + } + } + g_idle_add(ext_vfo_update,NULL); } - else if(strcmp(cmd_str,"SU")==0) { // Set/read the scan pause freq + else if((strcmp(cmd_str,"SU")==0) && (zzid_flag == 0)) { + // TS-2000 - SU - Set/read the scan pause freq - not supported if(len <=2) { //send_resp(client_sock,"SU00000000000;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"SV")==0) { // Execute the memory transfer function + else if((strcmp(cmd_str,"SV")==0) && (zzid_flag == 0)) { + // TS-2000 - SV - Execute the memory transfer function - not supported } - else if(strcmp(cmd_str,"TC")==0) { // Set/read the internal TNC mode + else if((strcmp(cmd_str,"TC")==0) && (zzid_flag == 0)) { + // TS-2000 - TC - Set/read the internal TNC mode - not supported if(len <=2) { //send_resp(client_sock,"TC00;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"TD")==0) { // Sends the DTMF memory channel + else if((strcmp(cmd_str,"TD")==0) && (zzid_flag == 0)) { + // TS-2000 - TD - Sends the DTMF memory channel - not supported } - else if(strcmp(cmd_str,"TI")==0) { // Reads the TNC LED status + else if((strcmp(cmd_str,"TI")==0) && (zzid_flag == 0)) { + // TS-2000 - TI - Reads the TNC LED status - not supported if(len <=2) { //send_resp(client_sock,"TI00;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"TN")==0) { // Set/Read sub tone freq + else if((strcmp(cmd_str,"TN")==0) && (zzid_flag == 0)) { + // TS-2000 - TN - Set/Read sub tone freq - not supported if(len <=2) { //send_resp(client_sock,"TN00;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"TO")==0) { // Set/Read tone function + else if((strcmp(cmd_str,"TO")==0) && (zzid_flag == 0)) { + // TI-2000 - TO - Set/Read tone function - not supported if(len <=2) { //send_resp(client_sock,"TO0;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"TS")==0) { // Set/Read TF Set function status + else if((strcmp(cmd_str,"TS")==0) && (zzid_flag == 0)) { + // TI-2000 - TS - Set/Read TF Set function status if(len <=2) { //send_resp(client_sock,"TS0;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"TX")==0) { // Key Xmitter - P1 - transmit on main/sub freq - - /*if(len >=3) { - // K5JAE: The TS-2000 real hardware does not respond - // to this command, thus hamlib is not expecting response. - //send_resp(client_sock,"TX0;"); - }*/ - mox_state=1; - g_idle_add(mox_update,(gpointer)mox_state); - g_idle_add(vfo_update,NULL); + else if(strcmp(cmd_str,"TX")==0) { + // TS-2000 - TX - Key Xmitter - P1 - transmit on main/sub freq + // PiHPSDR - ZZTX - Key Xmitter - P1 - transmit on main/sub freq + if(!((vfo[active_receiver->id].mode == modeCWL) || + (vfo[active_receiver->id].mode == modeCWU))) { + //*if(len >=3) { + // K5JAE: The TS 2000 real hardware does not respond + // to this command, thus hamlib is not expecting response. + //send_resp(client_sock,"TX0;"); */ + mox_state = 1; + g_idle_add(ext_mox_update,(gpointer)(long)mox_state); + g_idle_add(ext_vfo_update,NULL); + } else { + g_idle_add(ext_cw_setup,NULL); // Initialize for external transmit + g_idle_add(ext_mox_update,(gpointer)(long)1); // Turn on External MOX + } } - else if(strcmp(cmd_str,"TY")==0) { // Set/Read uP firmware type + else if(strcmp(cmd_str,"TY")==0) { + // TI-2000 - TY -- Set/Read uP firmware type if(len <=2) { send_resp(client_sock,"TY000;"); } } - else if(strcmp(cmd_str,"UL")==0) { // Detects the PLL unlock status - this should never occur - xmit only + else if((strcmp(cmd_str,"UA")==0) && (zzid_flag == 1)) { + // PiHPSDR - ZZUA - Xvrt Set/Read + // RW P1 - 1 Char - Entry number 0-7 + // W P1 - Disable PA - 1 char + // W P2 - 15 Char - Title - 16th char with last being '\0' + // W P3 - 11 Chars - Min Freq HZ + // W P4 - 11 Chars - Max Freq HZ + // W P5 - 11 Chars - Low Freq HZ + char lcl_buf[] = " "; + char tempc; + if(len<=3) { + work_int = atoi(&cmd_input[2]); + if((work_int >=0) && (work_int <=7)) { + BAND *xvtr=band_get_band(BANDS+work_int); + BANDSTACK *bandstack=xvtr->bandstack; + BANDSTACK_ENTRY *entry=bandstack->entry; + strcpy(lcl_buf,xvtr->title); + lcl_buf[strlen(lcl_buf)] = ' '; // Replace the last entry with ' '; + lcl_buf[15] = '\0'; + sprintf(msg,"ZZUA%1d%1d%s%011lld%011lld%011lld;",work_int,xvtr->disablePA,lcl_buf, + xvtr->frequencyMin,xvtr->frequencyMax,xvtr->frequencyLO); + send_resp(client_sock,msg); + } + } else if(len==52) { + + tempc = cmd_input[3]; + cmd_input[3] = '\0'; + work_int = atoi(&cmd_input[2]); + cmd_input[3] = tempc; + if((work_int >=0) && (work_int <=7)) { + + BAND *xvtr=band_get_band(BANDS+work_int); + BANDSTACK *bandstack=xvtr->bandstack; + BANDSTACK_ENTRY *entry=bandstack->entry; + tempc = cmd_input[4]; + cmd_input[4]='\0'; + xvtr->disablePA = atoi(&cmd_input[3]); + cmd_input[4]=tempc; + + /* Get the title of the XVTR */ + tempc = cmd_input[19]; + cmd_input[19] = '\0'; + strncpy(xvtr->title,&cmd_input[4],16); + cmd_input[19] = tempc; + + /* Pull out the Min freq */ + tempc = cmd_input[30]; + cmd_input[30]='\0'; + xvtr->frequencyMin = (long long) atoi(&cmd_input[19]); + cmd_input[30] = tempc; + + /* Pull out the Max freq */ + tempc = cmd_input[41]; + cmd_input[41]='\0'; + xvtr->frequencyMax = (long long) atoi(&cmd_input[30]); + cmd_input[41] = tempc; + + + /* Pull out the LO freq */ + xvtr->frequencyLO = (long long) atoi(&cmd_input[41]); + } else { + fprintf(stderr,"RIGCTL: ERROR ZZUA - incorrect length command received=%d",len); + send_resp(client_sock,"?;"); + } + } + } + else if((strcmp(cmd_str,"UL")==0) && (zzid_flag == 0)) { + // TS-2000 - UL - Detects the PLL unlock status - not supported if(len <=2) { //send_resp(client_sock,"UL0;"); send_resp(client_sock,"?;"); } } - else if(strcmp(cmd_str,"UP")==0) { // Emulates the mic up key + else if((strcmp(cmd_str,"UP")==0) && (zzid_flag == 0)) { + // TS-2000 - UP - Emulates the mic up key } - else if(strcmp(cmd_str,"VD")==0) { // Sets/Reads VOX dleay time - 0000-3000ms in steps of 150 - // We want vox_hang variable in PiHPSDR + else if(strcmp(cmd_str,"VD")==0) { + // TS-2000 - VD - Sets/Reads VOX delay time - 0000-3000ms in steps of 150 + // PiHPSDR - ZZVD - Sets/Reads VOX Hang time + // We want vox_hang variable in Pi HPSDR // Max value in variable in ms... so 250 = 250ms if(len <=2) { work_int = (int) vox_hang; - sprintf(msg,"VD%04d;",work_int); + if(zzid_flag == 0) { + sprintf(msg,"VD%04d;",work_int); + } else { + sprintf(msg,"ZZVD%04d;",work_int); + } send_resp(client_sock,msg); } else { work_int = atoi(&cmd_input[2]); - // Bounds check for legal values for PiHPSDR + // Bounds check for legal values for Pi HPSDR if(work_int > 1000) { work_int = 1000; } if(work_int < 0) { work_int = 0; } vox_hang = (double) work_int; @@ -1509,42 +3459,86 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) { #endif } } - else if(strcmp(cmd_str,"VG")==0) { // Sets/Reads VOX gain 000-009 - // We want vox_threshold variable in PiHPSDR + else if(strcmp(cmd_str,"VG")==0) { + // TI-2000 - VG - Sets/Reads VOX gain 000-009 + // PiHPSDR - ZZVG - Set/Read VOX Threshold - 0-1000 + // We want vox_threshold variable in Pi HPSDR // Max value in variable 0.1 // 3 char 000-009 valid ranges - if(len <=2) { - work_int = (int) ((vox_threshold) * 100.0); - sprintf(msg,"VG00%1d;",work_int); + if(len <=2) { + if(zzid_flag == 0) { + work_int = (int) ((vox_threshold) * 100.0); + sprintf(msg,"VG00%1d;",work_int); + } else { + work_int = (int) ((vox_threshold) * 1000.0); + sprintf(msg,"ZZVG%04d;",work_int); + } send_resp(client_sock,msg); } else { - // Set the threshold here - work_int = atoi(&cmd_input[2]); - vox_threshold = ((double) work_int)/100.0; - #ifdef RIGCTL_DEBUG - fprintf(stderr,"RIGCTL: Vox thresh=%0.20f\n",vox_threshold); - #endif + work_int = atoi(&cmd_input[2]); + if((work_int >=0) && (work_int<=9)) { + if(zzid_flag == 0) { + // Set the threshold here + vox_threshold = ((double) work_int)/100.0; + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: Vox thresh=%0.20f\n",vox_threshold); + #endif + } else { + vox_threshold = ((double) work_int)/1000.0; + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL: Vox thresh=%0.20f\n",vox_threshold); + #endif + } + } else { + send_resp(client_sock,"?;"); + } } } - else if(strcmp(cmd_str,"VR")==0) { // Emulates the voice 1/2 key + else if((strcmp(cmd_str,"VR")==0) && (zzid_flag == 0)) { + // TS-2000 - VR - Emulates the voice 1/2 key - not supported } - else if(strcmp(cmd_str,"VX")==0) { // Sets/reads vox f(x) state + else if(strcmp(cmd_str,"VX")==0) { + // TS-2000 - VX - Sets/reads vox f(x) state + // PiHPSDR - ZZVX - Set/Read VOX enabled if(len <=2) { - sprintf(msg,"VX%1d;",vox_enabled); + if(zzid_flag == 0 ) { + sprintf(msg,"VX%1d;",vox_enabled); + } else { + sprintf(msg,"ZZVX%1d;",vox_enabled); + } send_resp(client_sock,msg); } else { work_int = atoi(&cmd_input[2]); - if(work_int>1) { vox_enabled = 1; vox= 1;} - if(work_int<1) { vox_enabled = 0; vox=0; } + if(work_int==1) { vox_enabled = 1; vox= 1;} + if(work_int!=1) { vox_enabled = 0; vox=0; } } } - else if(strcmp(cmd_str,"XT")==0) { // Sets/reads the XIT f(x) state + else if((strcmp(cmd_str,"XC")==0) && (zzid_flag == 1)) { + // PiHPSDR - ZZXC - Turn off External MOX- + g_idle_add(ext_mox_update,(gpointer)(long)0); // Turn on xmitter (set Mox) + } + else if((strcmp(cmd_str,"XI")==0) && (zzid_flag == 1)) { + // PiHPSDR - ZZXI - Initialize the transmitter for external CW + g_idle_add(ext_cw_setup,NULL); // Initialize for external transmit + g_idle_add(ext_mox_update,(gpointer)(long)1); // Turn on External MOX + } + else if((strcmp(cmd_str,"XO")==0) && (zzid_flag == 1)) { + // PiHPSDR - ZZXT - Turn CW Note off when in CW mode + g_idle_add(ext_cw_key, (gpointer)(long)0); + } + else if(strcmp(cmd_str,"XT")==0) { + if(zzid_flag == 0 ) { + // TS-2000 - XT - Sets/reads the XIT f(x) state - not supported if(len <=2) { //send_resp(client_sock,"XT0;"); send_resp(client_sock,"?;"); } + } else { + // PiHPSDR - ZZXT - Turn CW Note on when in CW mode + g_idle_add(ext_cw_key, (gpointer)(long)1); + } } - else if(strcmp(cmd_str,"XX")==0) { // + else if((strcmp(cmd_str,"XX")==0) && (zzid_flag == 0)) { // // Format RL01234: First dig 0=neg, 1=pos number // 1-4- digital offset in hertz. if(len > 4) { // It is set instead of a read @@ -1595,117 +3589,198 @@ void parse_cmd ( char * cmd_input,int len,int client_sock) { // +// Serial Port Launch +int set_interface_attribs (int fd, int speed, int parity) +{ + struct termios tty; + memset (&tty, 0, sizeof tty); + if (tcgetattr (fd, &tty) != 0) + { + fprintf (stderr,"RIGCTL: Error %d from tcgetattr", errno); + return -1; + } + + cfsetospeed (&tty, speed); + cfsetispeed (&tty, speed); + + tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars + // disable IGNBRK for mismatched speed tests; otherwise receive break + // as \000 chars + tty.c_iflag &= ~IGNBRK; // disable break processing + tty.c_lflag = 0; // no signaling chars, no echo, + // no canonical processing + tty.c_oflag = 0; // no remapping, no delays + tty.c_cc[VMIN] = 0; // read doesn't block + tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout + + //tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl + tty.c_iflag |= (IXON | IXOFF | IXANY); // shut off xon/xoff ctrl + + tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls, + // enable reading + tty.c_cflag &= ~(PARENB | PARODD); // shut off parity + tty.c_cflag |= parity; + tty.c_cflag &= ~CSTOPB; + tty.c_cflag &= ~CRTSCTS; + + if (tcsetattr (fd, TCSANOW, &tty) != 0) + { + fprintf(stderr, "RIGCTL: Error %d from tcsetattr", errno); + return -1; + } + return 0; +} + +void set_blocking (int fd, int should_block) +{ + struct termios tty; + memset (&tty, 0, sizeof tty); + if (tcgetattr (fd, &tty) != 0) + { + fprintf (stderr,"RIGCTL: Error %d from tggetattr\n", errno); + return; + } + tty.c_cc[VMIN] = should_block ? 1 : 0; + tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout + + if (tcsetattr (fd, TCSANOW, &tty) != 0) + fprintf (stderr,"RIGCTL: error %d setting term attributes\n", errno); +} +static gpointer serial_server(gpointer data) { + // We're going to Read the Serial port and + // when we get data we'll send it to parse_cmd + int num_chars; + char ser_buf[100]; + char work_buf[100]; + const char s[2]=";"; + char *p; + char *d; + char save_buf[100] = ""; + int str_len = 0; + cat_control++; + while(1) { + int num_chars = read (fd, ser_buf, sizeof ser_buf); + if( num_chars != 0) { + //fprintf(stderr,"RIGCTL: RECEVIED=%s<<\n",ser_buf); + strcat(work_buf,ser_buf); + strcpy(ser_buf,""); // Clear away serial buffer + p = &work_buf[0]; + while((d=strstr(p,";")) != NULL) { + *d = '\0'; + g_mutex_lock(&mutex_b->m); + parse_cmd(p,strlen(p),-1); + g_mutex_unlock(&mutex_b->m); + p = ++d; + //fprintf(stderr,"RIGCTL: STRLEFT=%s\n",p); + } + strcpy(save_buf,p); + for(str_len=0; str_len<=99; str_len++) { + ser_buf[str_len] = '\0'; + work_buf[str_len] = '\0'; + } + strcpy(work_buf,save_buf); + for(str_len=0; str_len<=99; str_len++) { + save_buf[str_len] = '\0'; + } +/* + if(strstr(ser_buf,";") != NULL) { + p = strtok(ser_buf,s); + fprintf(stderr,"RIGCTL: Tok=%s\n",p); + while(p != NULL) { + strcpy(work_buf,p); + g_mutex_lock(&mutex_b->m); + parse_cmd(work_buf,strlen(work_buf),-1); + g_mutex_unlock(&mutex_b->m); + p = strtok(NULL,s); + fprintf(stderr,"RIGCTL: Tok=%s\n",p); + } + } else { + strcat(work_buf,ser_buf); + fprintf(stderr,"RIGCTL: Work_buf=%s\n",work_buf); + } +*/ + } /*else { + usleep(100L); + }*/ + } +} + +int launch_serial () { + fprintf(stderr,"RIGCTL: Launch Serial port %s\n",ser_port); + + + if(mutex_b_exists == 0) { + mutex_b = g_new(GT_MUTEX,1); + g_mutex_init(&mutex_b->m); + mutex_b_exists = 1; + } + + fd = open (ser_port, O_RDWR | O_NOCTTY | O_SYNC); + if (fd < 0) + { + fprintf (stderr,"RIGCTL: Error %d opening %s: %s\n", errno, ser_port, strerror (errno)); + return 0 ; + } + //set_interface_attribs (fd, B38400, 0); // set speed to 115,200 bps, 8n1 (no parity) + set_interface_attribs (fd, serial_baud_rate, 0); + /* + if(serial_parity == 1) { + set_interface_attribs (fd, PARENB, 0); + } + if(serial_parity == 2) { + set_interface_attribs (fd, PARODD, 0); + } + */ + set_blocking (fd, 1); // set no blocking + + + serial_server_thread_id = g_thread_new( "Serial server", serial_server, NULL); + if( ! serial_server_thread_id ) + { + fprintf(stderr,"g_thread_new failed on serial_server\n"); + return 0; + } + return 1; +} +// Serial Port close +void disable_serial () { + fprintf(stderr,"RIGCTL: Disable Serial port %s\n",ser_port); + cat_control--; +} + // // 2-25-17 - K5JAE - create each thread with the pointer to the port number // (Port numbers now const ints instead of defines..) // void launch_rigctl () { int err; + fprintf(stderr, "LAUNCHING RIGCTL!!\n"); + rigctl_busy = 1; mutex_a = g_new(GT_MUTEX,1); g_mutex_init(&mutex_a->m); - mutex_b = g_new(GT_MUTEX,1); - g_mutex_init(&mutex_b->m); - - // This routine encapsulates the pthread call -/* - err = pthread_create (&rigctl_a_thread_id,NULL,rigctl_a,NULL); - if(err != 0) { - fprintf(stderr, "pthread_create failed on rigctl_a launch\n"); - } -*/ - - rigctl_a_thread_id = g_thread_new( "rigctl a", rigctl, (gpointer)&TelnetPortA); - if( ! rigctl_a_thread_id ) - { - fprintf(stderr,"g_thread_new failed on rigctl_a\n"); - } - - -/* - err = pthread_create (&rigctl_b_thread_id,NULL,rigctl_b,NULL); - if(err != 0) { - fprintf(stderr, "pthread_create failed on rigctl_b launch\n"); - } -*/ - - rigctl_b_thread_id = g_thread_new( "rigctl b", rigctl, (gpointer)&TelnetPortB); - if( ! rigctl_b_thread_id ) - { - fprintf(stderr,"g_thread_new failed on rigctl_b\n"); + if(mutex_b_exists == 0) { + mutex_b = g_new(GT_MUTEX,1); + g_mutex_init(&mutex_b->m); + mutex_b_exists = 1; } + + mutex_c = g_new(GT_MUTEX,1); + g_mutex_init(&mutex_c->m); -/* - err = pthread_create (&rigctl_c_thread_id,NULL,rigctl_c,NULL); - if(err != 0) { - fprintf(stderr, "pthread_create failed on rigctl_c launch\n"); - } -*/ - - rigctl_c_thread_id = g_thread_new( "rigctl c", rigctl, (gpointer)&TelnetPortC); - if( ! rigctl_c_thread_id ) + // This routine encapsulates the thread call + rigctl_server_thread_id = g_thread_new( "rigctl server", rigctl_server, (gpointer)(long)rigctl_port_base); + if( ! rigctl_server_thread_id ) { - fprintf(stderr,"g_thread_new failed on rigctl_c\n"); + fprintf(stderr,"g_thread_new failed on rigctl_server\n"); } - } -// Telnet Server launch code below -// max number of bytes we can get at once #define MAXDATASIZE 300 -// -// 2-25-17 - K5JAE - removed duplicate init servers. -// - - -int init_server ( int * socket_desc_ptr, struct sockaddr_in * client, struct sockaddr_in * server, int telnet_port) { - int client_sock; - int c; - //Create socket - *socket_desc_ptr = socket(AF_INET , SOCK_STREAM , 0); - - if (*socket_desc_ptr == -1) - { - fprintf(stderr,"RIGCTL: Could not create socket"); - } - fprintf(stderr, "RIGCTL: Socket created\n"); - - //Prepare the sockaddr_in structure - server->sin_family = AF_INET; - server->sin_addr.s_addr = INADDR_ANY; - server->sin_port = htons( telnet_port ); - - //Bind - if( bind(*socket_desc_ptr,(struct sockaddr *) server , sizeof(struct sockaddr_in)) < 0) - { - //print the error message - fprintf(stderr,"RIGCTL: bind failed. Error\n"); - return 1; - } - fprintf(stderr,"RIGCTL: Bind done on port %d\n",telnet_port); - - //Listen - listen(*socket_desc_ptr, 3); - - //Accept and incoming connection - fprintf(stderr,"RIGCTL: Waiting for incoming connections...\n"); - c = sizeof(struct sockaddr_in); - - //accept connection from an incoming client - client_sock = accept(*socket_desc_ptr,(struct sockaddr *)client, (socklen_t*)&c); - if (client_sock < 0) - { - fprintf(stderr,"RIGCTL: Accept failed\n"); - } - fprintf(stderr,"RIGCTL: Connection accepted\n"); - - return client_sock; -} - int rigctlGetMode() { switch(vfo[active_receiver->id].mode) { case modeLSB: return(1); // LSB @@ -1720,61 +3795,155 @@ int rigctlGetMode() { } } + int rigctlSetFilterLow(int val){ }; int rigctlSetFilterHigh(int val){ }; -void set_band(long long new_freqA, int ctl) { +void set_freqB(long long new_freqB) { - fprintf(stderr,"set_band: f=%11lld ctl=%d\n",new_freqA,ctl ); - BANDSTACK_ENTRY *entry; - BAND *band; - FILTER* band_filters; - FILTER* band_filter; + //BANDSTACK_ENTRY *bandstack = bandstack_entry_get_current(); + //bandstack->frequencyB = new_freqB; + //frequencyB = new_freqB; + vfo[VFO_B].frequency = new_freqB; + g_idle_add(ext_vfo_update,NULL); +} - int b = get_band_from_frequency(new_freqA); - if(b == -1) { // Out of ham bands... - fprintf(stderr,"set_band: out of ham bands\n"); - setFrequency(new_freqA); - g_idle_add(vfo_update,NULL); - return; - } +int set_band (gpointer data) { + + BANDSTACK *bandstack; + long long new_freq = *(long long *) data; + free(data); - band=band_set_current(b); + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL set_band: New freq=%lld\n",new_freq); + #endif - entry=bandstack_entry_next(); - entry->mode = vfo[VFO_A].mode; - set_mode(active_receiver,entry->mode); // From current band setting - + // If CTUN=1 - can only change frequencies within the sample_rate range! + if((vfo[active_receiver->id].ctun == 1) && + ((vfo[active_receiver->id].ctun_frequency + (active_receiver->sample_rate/2) < new_freq) || + (vfo[active_receiver->id].ctun_frequency - (active_receiver->sample_rate/2) > new_freq))) { + fprintf(stderr,"RIGCTL: *** set_band: CTUN Bounce ***\n"); + return 0; + } + + int b = get_band_from_frequency (new_freq); - band_filters=filters[entry->mode]; - band_filter=&band_filters[entry->filter]; + if(b == -1) { // Not in the ham bands! + // We're not going to update the bandstack - but rather just + // change the frequency and move on + vfo[active_receiver->id].frequency=new_freq; + receiver_vfo_changed(receiver[active_receiver->id]); + g_idle_add(ext_vfo_update,NULL); + return 0; + } - set_filter(active_receiver,band_filter->low,band_filter->high); - setFrequency(new_freqA); + #ifdef RIGCTL_DEBUG + fprintf(stderr,"RIGCTL set_band: New Band=%d\n",b); + #endif + int id=active_receiver->id; + + //if(id==0) { + // fprintf(stderr,"RIGCTL set_band: id=0\n"); + // vfo_save_bandstack(); + //} + if(b==vfo[id].band) { + //fprintf(stderr,"RIGCTL set_band:b=cur_band \n"); + // same band selected - step to the next band stack + bandstack=bandstack_get_bandstack(b); + vfo[id].bandstack++; + if(vfo[id].bandstack>=bandstack->entries) { + //fprintf(stderr,"VFO_BAND_CHANGED: bandstack set to 0\n"); + vfo[id].bandstack=0; + } + } else { + // new band - get band stack entry + //fprintf(stderr,"VFO_BAND_CHANGED: new_band\n"); + bandstack=bandstack_get_bandstack(b) ; + vfo[id].bandstack=bandstack->current_entry; + //fprintf(stderr,"VFO_BAND_CHANGED: vfo[id].banstack=%d\n",vfo[id].bandstack); + } - // BAND *band=band_get_current_band(); - band=band_set_current(b); - if(active_receiver->id==0) { - set_alex_rx_antenna(band->alexRxAntenna); - set_alex_tx_antenna(band->alexTxAntenna); - set_alex_attenuation(band->alexAttenuation); + BAND *band=band_get_band(b); + BANDSTACK_ENTRY *entry=&bandstack->entry[vfo[id].bandstack]; + if(vfo[id].band != b) { + vfo[id].mode=entry->mode; + } + vfo[id].band=b; + entry->frequency = new_freq; + //vfo[id].frequency=entry->frequency; + if(vfo[id].ctun == 1) { + fprintf(stderr,"RIGCTL: set_band #### Change frequency"); + if(new_freq > vfo[id].ctun_frequency) { + vfo[id].offset = new_freq - vfo[id].ctun_frequency; + } else { + vfo[id].offset = vfo[id].ctun_frequency - new_freq; + } + fprintf(stderr,"RIGCTL: set_band OFSET= %011lld\n",vfo[id].offset); + } else { + entry->frequency = new_freq; } - //setFrequency(new_freqA); - g_idle_add(vfo_update,NULL); + //vfo[id].mode=entry->mode; + vfo[id].filter=entry->filter; + vfo[id].lo=band->frequencyLO; + + switch(id) { + case 0: + bandstack->current_entry=vfo[id].bandstack; + receiver_vfo_changed(receiver[id]); + BAND *band=band_get_band(vfo[id].band); + set_alex_rx_antenna(band->alexRxAntenna); + set_alex_tx_antenna(band->alexTxAntenna); + set_alex_attenuation(band->alexAttenuation); + receiver_vfo_changed(receiver[0]); + break; + case 1: + if(receivers==2) { + receiver_vfo_changed(receiver[1]); + } + break; + } + if(split) { + tx_set_mode(transmitter,vfo[VFO_B].mode); + } else { + tx_set_mode(transmitter,vfo[VFO_A].mode); + } calcDriveLevel(); - calcTuneDriveLevel(); -} + //calcTuneDriveLevel(); + g_idle_add(ext_vfo_update,NULL); -void set_freqB(long long new_freqB) { + return 0; +} +int set_alc(gpointer data) { + int * lcl_ptr = (int *) data; + alc = *lcl_ptr; + fprintf(stderr,"RIGCTL: set_alc=%d\n",alc); + return 0; +} - //BANDSTACK_ENTRY *bandstack = bandstack_entry_get_current(); - //bandstack->frequencyB = new_freqB; - //frequencyB = new_freqB; - vfo[VFO_B].frequency = new_freqB; - g_idle_add(vfo_update,NULL); +int lookup_band(int val) { + int work_int; + switch(val) { + case 160: work_int = 0; break; + case 80: work_int = 1; break; + case 60: work_int = 2; break; + case 40: work_int = 3; break; + case 30: work_int = 4; break; + case 20: work_int = 5; break; + case 17: work_int = 6; break; + case 15: work_int = 7; break; + case 12: work_int = 8; break; + case 10: work_int = 9; break; + case 6: work_int = 10; break; + case 888: work_int = 11; break; // General coverage + case 999: work_int = 12; break; // WWV + case 136: work_int = 13; break; // WWV + case 472: work_int = 14; break; // WWV + default: work_int = 0; + } + return work_int; } diff --git a/rigctl.h b/rigctl.h index 51e59ed..da827eb 100644 --- a/rigctl.h +++ b/rigctl.h @@ -2,10 +2,21 @@ #define RIGCTL_H void launch_rigctl (); +int launch_serial (); +void disable_sreial (); + +void close_rigctl_ports (); int rigctlGetMode(); +int lookup_band(int); char * rigctlGetFilter(); void set_freqB(long long); -void set_band(long long, int); +int set_band(void *); extern int cat_control; +int set_alc(gpointer); +extern int rigctl_busy; + +extern int rigctl_port_base; +extern int rigctl_enable; + #endif // RIGCTL_H diff --git a/rigctl_menu.c b/rigctl_menu.c new file mode 100644 index 0000000..b728f80 --- /dev/null +++ b/rigctl_menu.c @@ -0,0 +1,233 @@ +/* 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 +#include +#include +#include +#include +#include +#include + +#include "new_menu.h" +#include "rigctl_menu.h" +#include "rigctl.h" +#include "band.h" +#include "radio.h" +#include "vfo.h" + +int serial_enable; +char ser_port[64]="/dev/ttyUSB0"; +int serial_baud_rate = B4800; +int serial_parity = 0; // 0=none, 1=even, 2=odd + +static GtkWidget *parent_window=NULL; + +static GtkWidget *menu_b=NULL; + +static GtkWidget *dialog=NULL; + +static void cleanup() { + if(dialog!=NULL) { + gtk_widget_destroy(dialog); + dialog=NULL; + sub_menu=NULL; + } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); + return TRUE; +} + +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + +static void rigctl_value_changed_cb(GtkWidget *widget, gpointer data) { + rigctl_port_base = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget)); +} + +static void serial_value_changed_cb(GtkWidget *widget, gpointer data) { + sprintf(ser_port,"/dev/ttyUSB%0d",(int) gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget))); + fprintf(stderr,"RIGCTL_MENU: New Serial port=%s\n",ser_port); +} + +static void rigctl_enable_cb(GtkWidget *widget, gpointer data) { + rigctl_enable=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); + if(rigctl_enable) { + launch_rigctl(); + } else { + disable_rigctl(); + } +} + +static void serial_enable_cb(GtkWidget *widget, gpointer data) { + serial_enable=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); + if(serial_enable) { + if(launch_serial() == 0) { + gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(widget),FALSE) ; + } + } else { + disable_serial(); + } +} + +// Set Baud Rate +static void baud_rate_cb(GtkWidget *widget, gpointer data) { + serial_baud_rate = (uintptr_t) data; + fprintf(stderr,"RIGCTL_MENU: Baud rate changed\n"); +} + +// Set Parity 0=None, 1=Even, 2=0dd +static void parity_cb(GtkWidget *widget, gpointer data) { + serial_parity = (uintptr_t) data; + fprintf(stderr,"RITCTL_MENU: Serial Parity changed=%d\n", serial_parity); +} + +void rigctl_menu(GtkWidget *parent) { + int i; + + parent_window=parent; + + dialog=gtk_dialog_new(); + gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - RIGCTL"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); + + GdkRGBA color; + color.red = 1.0; + color.green = 1.0; + color.blue = 1.0; + color.alpha = 1.0; + gtk_widget_override_background_color(dialog,GTK_STATE_FLAG_NORMAL,&color); + + GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + + GtkWidget *grid=gtk_grid_new(); + gtk_grid_set_column_spacing (GTK_GRID(grid),10); + //gtk_grid_set_row_spacing (GTK_GRID(grid),10); + //gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); + //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); + + GtkWidget *close_b=gtk_button_new_with_label("Close"); + g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); + gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); + + + GtkWidget *rigctl_enable_b=gtk_check_button_new_with_label("Rigctl Enable"); + //gtk_widget_override_font(tx_out_of_band_b, pango_font_description_from_string("Arial 18")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rigctl_enable_b), rigctl_enable); + gtk_widget_show(rigctl_enable_b); + gtk_grid_attach(GTK_GRID(grid),rigctl_enable_b,0,1,1,1); + g_signal_connect(rigctl_enable_b,"toggled",G_CALLBACK(rigctl_enable_cb),NULL); + + GtkWidget *rigctl_port_label =gtk_label_new("RigCtl Port Number"); + //gtk_widget_override_font(band_label, pango_font_description_from_string("Arial 18")); + gtk_widget_show(rigctl_port_label); + gtk_grid_attach(GTK_GRID(grid),rigctl_port_label,0,2,1,1); + + GtkWidget *rigctl_port_spinner =gtk_spin_button_new_with_range(18000,21000,1); + //gtk_widget_override_font(rigctl_r, pango_font_description_from_string("Arial 18")); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(rigctl_port_spinner),(double)19090); + gtk_widget_show(rigctl_port_spinner); + gtk_grid_attach(GTK_GRID(grid),rigctl_port_spinner,1,2,1,1); + g_signal_connect(rigctl_port_spinner,"value_changed",G_CALLBACK(rigctl_value_changed_cb),NULL); + + /* Put the Serial Port stuff here */ + GtkWidget *serial_enable_b=gtk_check_button_new_with_label("Serial Port Enable"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (serial_enable_b), serial_enable); + gtk_widget_show(serial_enable_b); + gtk_grid_attach(GTK_GRID(grid),serial_enable_b,0,3,1,1); + g_signal_connect(serial_enable_b,"toggled",G_CALLBACK(serial_enable_cb),NULL); + + GtkWidget *serial_text_label=gtk_label_new("Serial Port: /dev/ttyUSB"); + gtk_grid_attach(GTK_GRID(grid),serial_text_label,0,4,1,1); + + GtkWidget *serial_port_spinner =gtk_spin_button_new_with_range(0,7,1); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(serial_port_spinner),(double)0); + gtk_widget_show(serial_port_spinner); + gtk_grid_attach(GTK_GRID(grid),serial_port_spinner,1,4,1,1); + g_signal_connect(serial_port_spinner,"value_changed",G_CALLBACK(serial_value_changed_cb),NULL); + + // Serial baud rate here + GtkWidget *baud_rate_label =gtk_label_new("Baud Rate:"); + gtk_widget_show(baud_rate_label); + gtk_grid_attach(GTK_GRID(grid),baud_rate_label,0,5,1,1); + + GtkWidget *baud_rate_b4800=gtk_radio_button_new_with_label(NULL,"4800"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (baud_rate_b4800), serial_baud_rate == B4800); + gtk_widget_show(baud_rate_b4800); + gtk_grid_attach(GTK_GRID(grid),baud_rate_b4800,1,5,1,1); + g_signal_connect(baud_rate_b4800,"toggled",G_CALLBACK(baud_rate_cb),(gpointer *) B4800); + + GtkWidget *baud_rate_b9600=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(baud_rate_b4800),"9600"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (baud_rate_b9600), serial_baud_rate == B9600); + gtk_widget_show(baud_rate_b9600); + gtk_grid_attach(GTK_GRID(grid),baud_rate_b9600,2,5,1,1); + g_signal_connect(baud_rate_b9600,"toggled",G_CALLBACK(baud_rate_cb),(gpointer *) B9600); + + GtkWidget *baud_rate_b19200=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(baud_rate_b9600),"19200"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (baud_rate_b19200),serial_baud_rate == B19200); + gtk_widget_show(baud_rate_b19200); + gtk_grid_attach(GTK_GRID(grid),baud_rate_b19200,3,5,1,1); + g_signal_connect(baud_rate_b19200,"toggled",G_CALLBACK(baud_rate_cb),(gpointer *) B19200); + + GtkWidget *baud_rate_b38400=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(baud_rate_b19200),"38400"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (baud_rate_b38400),serial_baud_rate == B38400); + gtk_widget_show(baud_rate_b38400); + gtk_grid_attach(GTK_GRID(grid),baud_rate_b38400,4,5,1,1); + g_signal_connect(baud_rate_b38400,"toggled",G_CALLBACK(baud_rate_cb),(gpointer *) B38400); + + // Serial parity +/* + GtkWidget *parity_label =gtk_label_new("Parity:"); + gtk_widget_show(parity_label); + gtk_grid_attach(GTK_GRID(grid),parity_label,0,6,1,1); + + GtkWidget *parity_none_b=gtk_radio_button_new_with_label(NULL,"None"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (parity_none_b), serial_parity == 0); + gtk_widget_show(parity_none_b); + gtk_grid_attach(GTK_GRID(grid),parity_none_b,1,6,1,1); + g_signal_connect(parity_none_b,"toggled",G_CALLBACK(parity_cb),(gpointer *) 0); + + GtkWidget *parity_even_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(parity_none_b),"Even"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (parity_even_b), serial_parity == 1); + gtk_widget_show(parity_even_b); + gtk_grid_attach(GTK_GRID(grid),parity_even_b,2,6,1,1); + g_signal_connect(parity_even_b,"toggled",G_CALLBACK(parity_cb),(gpointer *) 1); + + GtkWidget *parity_odd_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(parity_even_b),"Odd"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (parity_odd_b), serial_parity == 2); + gtk_widget_show(parity_odd_b); + gtk_grid_attach(GTK_GRID(grid),parity_odd_b,3,6,1,1); + g_signal_connect(parity_odd_b,"toggled",G_CALLBACK(parity_cb),(gpointer *) 1); +*/ + + // Below stays put + gtk_container_add(GTK_CONTAINER(content),grid); + + sub_menu=dialog; + + gtk_widget_show_all(dialog); + +} + diff --git a/rigctl_menu.h b/rigctl_menu.h new file mode 100644 index 0000000..bfb2719 --- /dev/null +++ b/rigctl_menu.h @@ -0,0 +1,31 @@ +/* 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 +#include +#include +#include + +extern void rigctl_menu(GtkWidget *parent); +extern char ser_port[]; +extern void disable_rigctl(); +extern void disable_serial(); + +extern int serial_baud_rate; +extern int serial_parity; diff --git a/rit.c b/rit.c deleted file mode 100644 index e9091b6..0000000 --- a/rit.c +++ /dev/null @@ -1,171 +0,0 @@ -/* 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 -#include -#include -#include - -#include "radio.h" -#include "rit.h" -#include "vfo.h" - -static GtkWidget *parent_window; - -static GtkWidget *h_box; -static GtkWidget *v_box_1; -static GtkWidget *v_box_2; -static GtkWidget *ctun_b; -static GtkWidget *rit_b; -static GtkWidget *rit_plus_b; -static GtkWidget *rit_minus_b; -static gint rit_timer; - -static gboolean rit_enabled=FALSE; - -static void set_button_text_color(GtkWidget *widget,char *color) { - GtkStyleContext *style_context; - GtkCssProvider *provider = gtk_css_provider_new (); - gchar tmp[64]; - style_context = gtk_widget_get_style_context(widget); - gtk_style_context_add_provider(style_context, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); - g_snprintf(tmp, sizeof tmp, "GtkButton, GtkLabel { color: %s; }", color); - gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(provider), tmp, -1, NULL); - g_object_unref (provider); -} - -static gboolean ctun_pressed_event_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { - ctun=ctun==1?0:1; - - if(ctun) { - set_button_text_color(ctun_b,"red"); - } else { - set_button_text_color(ctun_b,"black"); - vfo[active_receiver->id].offset=0; - set_offset(active_receiver,0); - vfo_update(NULL); - } - return TRUE; -} - -static gboolean rit_timer_cb(gpointer data) { - int v=active_receiver->id; - if((GtkWidget*)data==rit_plus_b) { - vfo[v].rit+=rit_increment; - } else { - vfo[v].rit-=rit_increment; - } - if(vfo[v].rit>1000) vfo[v].rit=1000; - if(vfo[v].rit<-1000) vfo[v].rit=-1000; - vfo_update(NULL); - return TRUE; -} - -static gboolean rit_pressed_event_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { - if(rit_enabled) { - rit_enabled=FALSE; - set_button_text_color(rit_b,"black"); - vfo[active_receiver->id].offset=0; - gtk_widget_set_sensitive(rit_plus_b,FALSE); - gtk_widget_set_sensitive(rit_minus_b,FALSE); - } else { - rit_enabled=TRUE; - set_button_text_color(rit_b,"red"); - gtk_widget_set_sensitive(rit_plus_b,TRUE); - gtk_widget_set_sensitive(rit_minus_b,TRUE); - } - vfo_update(NULL); -} - -static gboolean rit_step_pressed_event_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { - int v=active_receiver->id; - if(widget==rit_plus_b) { - vfo[v].rit+=rit_increment; - } else { - vfo[v].rit-=rit_increment; - } - if(vfo[v].rit>1000) vfo[v].rit=1000; - if(vfo[v].rit<-1000) vfo[v].rit=-1000; - vfo_update(NULL); - rit_timer=g_timeout_add(200,rit_timer_cb,widget); - return TRUE; -} - - -static gboolean rit_step_released_event_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { - g_source_remove(rit_timer); - return TRUE; -} - - -GtkWidget* rit_init(int width,int height,GtkWidget *parent) { - - GdkRGBA black; - black.red=0.0; - black.green=0.0; - black.blue=0.0; - black.alpha=0.0; - - fprintf(stderr,"rit_init: width=%d height=%d\n",width,height); - - parent_window=parent; - - h_box=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0); - gtk_widget_set_size_request (h_box, width, height); - gtk_widget_override_background_color(h_box, GTK_STATE_NORMAL, &black); - - v_box_2=gtk_box_new(GTK_ORIENTATION_VERTICAL,0); - gtk_widget_override_background_color(v_box_2, GTK_STATE_NORMAL, &black); - - rit_plus_b=gtk_button_new_with_label("RIT+"); - gtk_widget_override_font(rit_plus_b, pango_font_description_from_string("FreeMono Bold 10")); - g_signal_connect (rit_plus_b, "pressed", G_CALLBACK(rit_step_pressed_event_cb), NULL); - g_signal_connect (rit_plus_b, "released", G_CALLBACK(rit_step_released_event_cb), NULL); - gtk_box_pack_start (GTK_BOX(v_box_2),rit_plus_b,TRUE,TRUE,0); - - rit_minus_b=gtk_button_new_with_label("RIT-"); - gtk_widget_override_font(rit_minus_b, pango_font_description_from_string("FreeMono Bold 10")); - g_signal_connect (rit_minus_b, "pressed", G_CALLBACK(rit_step_pressed_event_cb), NULL); - g_signal_connect (rit_minus_b, "released", G_CALLBACK(rit_step_released_event_cb), NULL); - gtk_box_pack_start (GTK_BOX(v_box_2),rit_minus_b,TRUE,TRUE,0); - - gtk_widget_set_sensitive(rit_plus_b,FALSE); - gtk_widget_set_sensitive(rit_minus_b,FALSE); - - gtk_box_pack_start (GTK_BOX(h_box),v_box_2,TRUE,TRUE,0); - - v_box_1=gtk_box_new(GTK_ORIENTATION_VERTICAL,0); - gtk_widget_override_background_color(v_box_1, GTK_STATE_NORMAL, &black); - - ctun_b=gtk_button_new_with_label("CTUN"); - gtk_widget_override_font(ctun_b, pango_font_description_from_string("FreeMono Bold 10")); - g_signal_connect (ctun_b, "pressed", G_CALLBACK(ctun_pressed_event_cb), NULL); - gtk_box_pack_start (GTK_BOX(v_box_1),ctun_b,TRUE,TRUE,0); - - rit_b=gtk_button_new_with_label("RIT"); - gtk_widget_override_font(rit_b, pango_font_description_from_string("FreeMono Bold 10")); - g_signal_connect (rit_b, "pressed", G_CALLBACK(rit_pressed_event_cb), NULL); - gtk_box_pack_start (GTK_BOX(v_box_1),rit_b,TRUE,TRUE,0); - - gtk_box_pack_start (GTK_BOX(h_box),v_box_1,TRUE,TRUE,0); - - gtk_widget_show_all(h_box); - - return h_box; -} diff --git a/rx_menu.c b/rx_menu.c index 02e1537..af86bdf 100644 --- a/rx_menu.c +++ b/rx_menu.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "audio.h" @@ -37,15 +38,24 @@ static GtkWidget *menu_b=NULL; static GtkWidget *dialog=NULL; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static void dither_cb(GtkWidget *widget, gpointer data) { active_receiver->dither=active_receiver->dither==1?0:1; } @@ -59,18 +69,20 @@ static void preamp_cb(GtkWidget *widget, gpointer data) { } static void sample_rate_cb(GtkWidget *widget, gpointer data) { - receiver_change_sample_rate(active_receiver,(int)data); + receiver_change_sample_rate(active_receiver,(uintptr_t)data); } static void adc_cb(GtkWidget *widget, gpointer data) { - receiver_change_adc(active_receiver,(int)data); + receiver_change_adc(active_receiver,(uintptr_t)data); } static void local_audio_cb(GtkWidget *widget, gpointer data) { +fprintf(stderr,"local_audio_cb: rx=%d\n",active_receiver->id); if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) { if(audio_open_output(active_receiver)==0) { active_receiver->local_audio=1; } else { +fprintf(stderr,"local_audio_cb: audio_open_output failed\n"); active_receiver->local_audio=0; gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE); } @@ -80,25 +92,34 @@ static void local_audio_cb(GtkWidget *widget, gpointer data) { audio_close_output(active_receiver); } } +fprintf(stderr,"local_audio_cb: local_audio=%d\n",active_receiver->local_audio); } static void mute_audio_cb(GtkWidget *widget, gpointer data) { active_receiver->mute_when_not_active=gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); } +static void mute_radio_cb(GtkWidget *widget, gpointer data) { + active_receiver->mute_radio=gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); +} + static void local_output_changed_cb(GtkWidget *widget, gpointer data) { active_receiver->audio_device=(int)(long)data; +fprintf(stderr,"local_output_changed rx=%d to %d\n",active_receiver->id,active_receiver->audio_device); if(active_receiver->local_audio) { audio_close_output(active_receiver); if(audio_open_output(active_receiver)==0) { active_receiver->local_audio=1; + } else { + active_receiver->local_audio=0; } +fprintf(stderr,"local_output_changed rx=%d local_audio=%d\n",active_receiver->id,active_receiver->local_audio); } } static void audio_channel_cb(GtkWidget *widget, gpointer data) { if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { - active_receiver->audio_channel=(int)data; + active_receiver->audio_channel=(uintptr_t)data; } } @@ -110,7 +131,11 @@ void rx_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + char title[64]; + sprintf(title,"piHPSDR - Receive (RX %d VFO %s)",active_receiver->id,active_receiver->id==0?"A":"B"); + gtk_window_set_title(GTK_WINDOW(dialog),title); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -127,14 +152,10 @@ void rx_menu(GtkWidget *parent) { //gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); - GtkWidget *close_b=gtk_button_new_with_label("Close RX"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "button_press_event", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); - sprintf(label,"RX %d VFO %s",active_receiver->id,active_receiver->id==0?"A":"B"); - GtkWidget *rx_label=gtk_label_new(label); - gtk_grid_attach(GTK_GRID(grid),rx_label,1,0,1,1); - int x=0; switch(protocol) { @@ -166,7 +187,7 @@ void rx_menu(GtkWidget *parent) { gtk_grid_attach(GTK_GRID(grid),sample_rate_384,x,5,1,1); g_signal_connect(sample_rate_384,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)384000); -#ifndef GPIO +#ifndef raspberrypi GtkWidget *sample_rate_768=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_384),"768000"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_768), active_receiver->sample_rate==768000); gtk_grid_attach(GTK_GRID(grid),sample_rate_768,x,6,1,1); @@ -282,7 +303,7 @@ void rx_menu(GtkWidget *parent) { } gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (adc_b), active_receiver->adc==i); gtk_grid_attach(GTK_GRID(grid),adc_b,x,2+i,1,1); - g_signal_connect(adc_b,"pressed",G_CALLBACK(adc_cb),(gpointer *)i); + g_signal_connect(adc_b,"pressed",G_CALLBACK(adc_cb),(gpointer)(long)i); } x++; } @@ -298,17 +319,13 @@ void rx_menu(GtkWidget *parent) { if(active_receiver->audio_device==-1) active_receiver->audio_device=0; + GtkWidget *output=NULL; for(i=0;iaudio_device==i); gtk_widget_show(output); gtk_grid_attach(GTK_GRID(grid),output,x,++row,1,1); - g_signal_connect(output,"pressed",G_CALLBACK(local_output_changed_cb),(gpointer *)i); + g_signal_connect(output,"pressed",G_CALLBACK(local_output_changed_cb),(gpointer)(long)i); } row=0; @@ -339,6 +356,14 @@ void rx_menu(GtkWidget *parent) { gtk_grid_attach(GTK_GRID(grid),mute_audio_b,x,++row,1,1); g_signal_connect(mute_audio_b,"toggled",G_CALLBACK(mute_audio_cb),NULL); + row++; + + GtkWidget *mute_radio_b=gtk_check_button_new_with_label("Mute audio to radio"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mute_radio_b), active_receiver->mute_radio); + gtk_widget_show(mute_radio_b); + gtk_grid_attach(GTK_GRID(grid),mute_radio_b,x,++row,1,1); + g_signal_connect(mute_radio_b,"toggled",G_CALLBACK(mute_radio_cb),NULL); + gtk_container_add(GTK_CONTAINER(content),grid); sub_menu=dialog; diff --git a/rx_panadapter.c b/rx_panadapter.c index 45f956d..4e82d19 100644 --- a/rx_panadapter.c +++ b/rx_panadapter.c @@ -24,6 +24,9 @@ #include #include #include + +#include + #include "agc.h" #include "band.h" #include "channel.h" @@ -37,13 +40,16 @@ #ifdef FREEDV #include "freedv.h" #endif +#ifdef GPIO #include "gpio.h" +#endif //static float panadapter_max=-60.0; //static float panadapter_min=-160.0; static gfloat filter_left; static gfloat filter_right; +static gfloat cw_frequency; /* Create a new surface of the appropriate size to store our scribbles */ static gboolean @@ -66,7 +72,7 @@ panadapter_configure_event_cb (GtkWidget *widget, display_height); cairo_t *cr=cairo_create(rx->panadapter_surface); - cairo_set_source_rgb(cr, 0, 0, 0); + cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); cairo_paint(cr); cairo_destroy(cr); return TRUE; @@ -83,11 +89,11 @@ panadapter_draw_cb (GtkWidget *widget, { RECEIVER *rx=(RECEIVER *)data; if(rx->panadapter_surface) { - cairo_set_source_surface (cr, rx->panadapter_surface, 0, 0); + cairo_set_source_surface (cr, rx->panadapter_surface, 0.0, 0.0); cairo_paint (cr); } - return TRUE; + return FALSE; } static gboolean panadapter_button_press_event_cb(GtkWidget *widget, GdkEventButton *event, gpointer data) { @@ -108,6 +114,7 @@ static gboolean panadapter_scroll_event_cb(GtkWidget *widget, GdkEventScroll *ev void rx_panadapter_update(RECEIVER *rx) { int i; + int x1,x2; int result; float *samples; float saved_max; @@ -119,28 +126,73 @@ void rx_panadapter_update(RECEIVER *rx) { int display_width=gtk_widget_get_allocated_width (rx->panadapter); int display_height=gtk_widget_get_allocated_height (rx->panadapter); +#ifdef FREEDV + if(rx->freedv) { + display_height=display_height-20; + } +#endif samples=rx->pixel_samples; //clear_panadater_surface(); cairo_t *cr; cr = cairo_create (rx->panadapter_surface); - cairo_set_source_rgb (cr, 0, 0, 0); + cairo_set_line_width(cr, 1.0); + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); cairo_rectangle(cr,0,0,display_width,display_height); cairo_fill(cr); //cairo_paint (cr); + long long frequency=vfo[rx->id].frequency; + long half=(long)rx->sample_rate/2L; + long long min_display=frequency-half; + long long max_display=frequency+half; + BAND *band=band_get_band(vfo[rx->id].band); + + if(vfo[rx->id].band==band60) { + for(i=0;ihz_per_pixel; + x2=(hi_freq-min_display)/(long long)rx->hz_per_pixel; + cairo_set_source_rgb (cr, 0.6, 0.3, 0.3); + cairo_rectangle(cr, x1, 0.0, x2-x1, (double)display_height); + cairo_fill(cr); +/* + cairo_set_source_rgba (cr, 0.5, 1.0, 0.0, 1.0); + cairo_move_to(cr,(double)x1,0.0); + cairo_line_to(cr,(double)x1,(double)display_height); + cairo_stroke(cr); + cairo_move_to(cr,(double)x2,0.0); + cairo_line_to(cr,(double)x2,(double)display_height); + cairo_stroke(cr); +*/ + } + } + // filter - cairo_set_source_rgb (cr, 0.25, 0.25, 0.25); + cairo_set_source_rgba (cr, 0.25, 0.25, 0.25, 0.75); filter_left=(double)display_width/2.0+(((double)rx->filter_low+vfo[rx->id].offset)/rx->hz_per_pixel); filter_right=(double)display_width/2.0+(((double)rx->filter_high+vfo[rx->id].offset)/rx->hz_per_pixel); cairo_rectangle(cr, filter_left, 0.0, filter_right-filter_left, (double)display_height); cairo_fill(cr); + if(vfo[rx->id].mode==modeCWU || vfo[rx->id].mode==modeCWL) { + if(active) { + cairo_set_source_rgb (cr, 1.0, 1.0, 0.0); + } else { + cairo_set_source_rgb (cr, 0.25, 0.25, 0.0); + } + cw_frequency=filter_left+((filter_right-filter_left)/2.0); + cairo_move_to(cr,cw_frequency,10.0); + cairo_line_to(cr,cw_frequency,(double)display_height); + cairo_stroke(cr); + } + // plot the levels if(active) { - cairo_set_source_rgb (cr, 0, 1, 1); + cairo_set_source_rgb (cr, 0.0, 1.0, 1.0); } else { - cairo_set_source_rgb (cr, 0, 0.5, 0.5); + cairo_set_source_rgb (cr, 0.0, 0.5, 0.5); } double dbm_per_line=(double)display_height/((double)rx->panadapter_high-(double)rx->panadapter_low); @@ -166,8 +218,6 @@ void rx_panadapter_update(RECEIVER *rx) { // plot frequency markers long long f; long divisor=20000; - long half=(long)rx->sample_rate/2L; - long long frequency=vfo[rx->id].frequency; switch(rx->sample_rate) { case 48000: divisor=5000L; @@ -180,7 +230,7 @@ void rx_panadapter_update(RECEIVER *rx) { divisor=20000L; break; case 384000: - divisor=25000L; + divisor=50000L; break; case 768000: divisor=50000L; @@ -215,24 +265,23 @@ void rx_panadapter_update(RECEIVER *rx) { } cairo_stroke(cr); - // band edges - long long min_display=frequency-half; - long long max_display=frequency+half; - BAND *band=band_get_band(vfo[rx->id].band); - if(band->frequencyMin!=0LL) { - cairo_set_source_rgb (cr, 1, 0, 0); - cairo_set_line_width(cr, 2.0); - if((min_displayfrequencyMin)&&(max_display>band->frequencyMin)) { - i=(band->frequencyMin-min_display)/(long long)rx->hz_per_pixel; - cairo_move_to(cr,(double)i,0.0); - cairo_line_to(cr,(double)i,(double)display_height); - cairo_stroke(cr); - } - if((min_displayfrequencyMax)&&(max_display>band->frequencyMax)) { - i=(band->frequencyMax-min_display)/(long long)rx->hz_per_pixel; - cairo_move_to(cr,(double)i,0.0); - cairo_line_to(cr,(double)i,(double)display_height); - cairo_stroke(cr); + if(vfo[rx->id].band!=band60) { + // band edges + if(band->frequencyMin!=0LL) { + cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); + cairo_set_line_width(cr, 2.0); + if((min_displayfrequencyMin)&&(max_display>band->frequencyMin)) { + i=(band->frequencyMin-min_display)/(long long)rx->hz_per_pixel; + cairo_move_to(cr,(double)i,0.0); + cairo_line_to(cr,(double)i,(double)display_height); + cairo_stroke(cr); + } + if((min_displayfrequencyMax)&&(max_display>band->frequencyMax)) { + i=(band->frequencyMax-min_display)/(long long)rx->hz_per_pixel; + cairo_move_to(cr,(double)i,0.0); + cairo_line_to(cr,(double)i,(double)display_height); + cairo_stroke(cr); + } } } @@ -289,9 +338,9 @@ void rx_panadapter_update(RECEIVER *rx) { // cursor if(active) { - cairo_set_source_rgb (cr, 1, 0, 0); + cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); } else { - cairo_set_source_rgb (cr, 0.5, 0, 0); + cairo_set_source_rgb (cr, 0.5, 0.0, 0.0); } cairo_set_line_width(cr, 1.0); cairo_move_to(cr,(double)(display_width/2.0)+(vfo[rx->id].offset/rx->hz_per_pixel),0.0); @@ -319,14 +368,14 @@ void rx_panadapter_update(RECEIVER *rx) { if(display_filled) { cairo_close_path (cr); if(active) { - cairo_set_source_rgba(cr, 1, 1, 1,0.5); + cairo_set_source_rgba(cr, 1.0, 1.0, 1.0,0.5); } else { cairo_set_source_rgba(cr, 0.5, 0.5, 0.5,0.5); } cairo_fill_preserve (cr); } if(active) { - cairo_set_source_rgb(cr, 1, 1, 1); + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); } else { cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); } @@ -334,37 +383,40 @@ void rx_panadapter_update(RECEIVER *rx) { cairo_stroke(cr); #ifdef FREEDV - int mode=rx->mode; - if(mode==modeFREEDV) { - cairo_set_source_rgb(cr, 0, 1, 0); - cairo_set_font_size(cr, 16); - cairo_text_extents(cr, freedv_text_data, &extents); - cairo_move_to(cr, (double)display_width/2.0-(extents.width/2.0),(double)display_height-2.0); - cairo_show_text(cr, freedv_text_data); + if(rx->freedv) { + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); + cairo_rectangle(cr,0,display_height,display_width,display_height+20); + cairo_fill(cr); + + cairo_set_source_rgb(cr, 0.0, 1.0, 0.0); + cairo_set_font_size(cr, 18); + cairo_move_to(cr, 0.0, (double)display_height+20.0-2.0); + cairo_show_text(cr, rx->freedv_text_data); } #endif #ifdef GPIO if(active) { - cairo_set_source_rgb(cr,1,1,0); - cairo_set_font_size(cr,12); + cairo_set_source_rgb(cr,1.0,1.0,0.0); + cairo_set_font_size(cr,16); if(ENABLE_E1_ENCODER) { - cairo_move_to(cr, display_width-100,20); + cairo_move_to(cr, display_width-150,30); cairo_show_text(cr, encoder_string[e1_encoder_action]); } if(ENABLE_E2_ENCODER) { - cairo_move_to(cr, display_width-100,40); + cairo_move_to(cr, display_width-150,50); cairo_show_text(cr, encoder_string[e2_encoder_action]); } if(ENABLE_E3_ENCODER) { - cairo_move_to(cr, display_width-100,60); + cairo_move_to(cr, display_width-150,70); cairo_show_text(cr, encoder_string[e3_encoder_action]); } } #endif + cairo_destroy (cr); gtk_widget_queue_draw (rx->panadapter); diff --git a/signal.c b/signal.c deleted file mode 100644 index 9db7c7e..0000000 --- a/signal.c +++ /dev/null @@ -1,61 +0,0 @@ -/* 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 - -#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/sliders.c b/sliders.c index 4b02904..b91cb49 100644 --- a/sliders.c +++ b/sliders.c @@ -23,6 +23,7 @@ #include #include +#include "receiver.h" #include "sliders.h" #include "mode.h" #include "filter.h" @@ -37,9 +38,10 @@ #include "channel.h" #include "wdsp.h" #include "radio.h" -#include "receiver.h" +#include "transmitter.h" #include "property.h" #include "main.h" +#include "ext.h" static int width; static int height; @@ -52,8 +54,9 @@ static GtkWidget *sliders; #define LINEIN_GAIN 3 #define AGC_GAIN 4 #define DRIVE 5 -#define TUNE_DRIVE 6 -#define ATTENUATION 7 +#define ATTENUATION 6 +#define SQUELCH 7 +#define COMP 8 static gint scale_timer; static int scale_status=NONE; @@ -66,40 +69,41 @@ static GtkWidget *attenuation_label; static GtkWidget *attenuation_scale; static GtkWidget *mic_gain_label; static GtkWidget *mic_gain_scale; -static GtkWidget *linein_gain_label; -static GtkWidget *linein_gain_scale; static GtkWidget *drive_label; static GtkWidget *drive_scale; -static GtkWidget *tune_label; -static GtkWidget *tune_scale; +static GtkWidget *squelch_label; +static GtkWidget *squelch_scale; +static GtkWidget *squelch_enable; +static GtkWidget *comp_label; +static GtkWidget *comp_scale; +static GtkWidget *comp_enable; static GtkWidget *dummy_label; static GdkRGBA white; static GdkRGBA gray; -int linein_changed(void *data) { +void sliders_update() { if(display_sliders) { if(mic_linein) { - gtk_widget_hide(mic_gain_label); - gtk_widget_hide(mic_gain_scale); - gtk_widget_show(linein_gain_label); - gtk_widget_show(linein_gain_scale); + gtk_label_set_text(GTK_LABEL(mic_gain_label),"Linein:"); + gtk_range_set_range(GTK_RANGE(mic_gain_scale),0.0,31.0); + gtk_range_set_value (GTK_RANGE(mic_gain_scale),linein_gain); } else { - gtk_widget_hide(linein_gain_label); - gtk_widget_hide(linein_gain_scale); - gtk_widget_show(mic_gain_label); - gtk_widget_show(mic_gain_scale); + gtk_label_set_text(GTK_LABEL(mic_gain_label),"Mic (dB):"); + gtk_range_set_range(GTK_RANGE(mic_gain_scale),-10.0,50.0); + gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_gain); } } - return 0; } -int active_receiver_changed(void *data) { +int sliders_active_receiver_changed(void *data) { if(display_sliders) { gtk_range_set_value(GTK_RANGE(af_gain_scale),active_receiver->volume*100.0); gtk_range_set_value (GTK_RANGE(agc_scale),active_receiver->agc_gain); gtk_range_set_value (GTK_RANGE(attenuation_scale),active_receiver->attenuation); + sliders_update(); } + return FALSE; } int scale_timeout_cb(gpointer data) { @@ -184,20 +188,23 @@ void set_agc_gain(double value) { } } -int update_agc_gain(void *data) { - set_agc_gain(*(double*)data); - free(data); - return 0; +void update_agc_gain(double gain) { + set_agc_gain(gain); } static void afgain_value_changed_cb(GtkWidget *widget, gpointer data) { active_receiver->volume=gtk_range_get_value(GTK_RANGE(af_gain_scale))/100.0; - SetRXAPanelGain1 (active_receiver->id, active_receiver->volume); +#ifdef FREEDV + if(!active_receiver->freedv) { +#endif + SetRXAPanelGain1 (active_receiver->id, active_receiver->volume); +#ifdef FREEDV + } +#endif } -int update_af_gain(void *data) { +void update_af_gain() { set_af_gain(active_receiver->volume); - return 0; } void set_af_gain(double value) { @@ -234,9 +241,13 @@ 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)); - double gain=pow(10.0, mic_gain / 20.0); - SetTXAPanelGain1(transmitter->id,gain); + if(mic_linein) { + linein_gain=(int)gtk_range_get_value(GTK_RANGE(widget)); + } else { + mic_gain=gtk_range_get_value(GTK_RANGE(widget)); + double gain=pow(10.0, mic_gain / 20.0); + SetTXAPanelGain1(transmitter->id,gain); + } } void set_mic_gain(double value) { @@ -280,14 +291,10 @@ int update_mic_gain(void *data) { return 0; } -static void lineingain_value_changed_cb(GtkWidget *widget, gpointer data) { - linein_gain=(int)gtk_range_get_value(GTK_RANGE(widget)); -} - void set_linein_gain(int value) { linein_gain=value; if(display_sliders) { - gtk_range_set_value (GTK_RANGE(linein_gain_scale),linein_gain); + gtk_range_set_value (GTK_RANGE(mic_gain_scale),linein_gain); } else { if(scale_status!=LINEIN_GAIN) { if(scale_status!=NONE) { @@ -300,20 +307,19 @@ void set_linein_gain(int value) { scale_status=LINEIN_GAIN; scale_dialog=gtk_dialog_new_with_buttons("Linein Gain",GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL); GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog)); - linein_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 31.0, 1.00); - gtk_widget_set_size_request (linein_gain_scale, 400, 30); - gtk_range_set_value (GTK_RANGE(linein_gain_scale),linein_gain); - gtk_widget_show(linein_gain_scale); - gtk_container_add(GTK_CONTAINER(content),linein_gain_scale); + mic_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 31.0, 1.00); + gtk_widget_set_size_request (mic_gain_scale, 400, 30); + gtk_range_set_value (GTK_RANGE(mic_gain_scale),linein_gain); + 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); //gtk_widget_show_all(scale_dialog); int result=gtk_dialog_run(GTK_DIALOG(scale_dialog)); } else { g_source_remove(scale_timer); - gtk_range_set_value (GTK_RANGE(linein_gain_scale),linein_gain); + gtk_range_set_value (GTK_RANGE(mic_gain_scale),linein_gain); scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL); } - } } @@ -365,12 +371,30 @@ int update_drive(void *data) { return 0; } -void set_tune(double value) { - setTuneDrive(value); +static void squelch_value_changed_cb(GtkWidget *widget, gpointer data) { + active_receiver->squelch=gtk_range_get_value(GTK_RANGE(widget)); + setSquelch(active_receiver); +} + +static void squelch_enable_cb(GtkWidget *widget, gpointer data) { + active_receiver->squelch_enable=gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); + setSquelch(active_receiver); +} + +static void compressor_value_changed_cb(GtkWidget *widget, gpointer data) { + transmitter_set_compressor_level(transmitter,gtk_range_get_value(GTK_RANGE(widget))); +} + +static void compressor_enable_cb(GtkWidget *widget, gpointer data) { + transmitter_set_compressor(transmitter,gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))); +} + +void set_squelch(RECEIVER* rx) { + setSquelch(active_receiver); if(display_sliders) { - gtk_range_set_value (GTK_RANGE(tune_scale),value); + gtk_range_set_value (GTK_RANGE(squelch_scale),active_receiver->squelch); } else { - if(scale_status!=TUNE_DRIVE) { + if(scale_status!=SQUELCH) { if(scale_status!=NONE) { g_source_remove(scale_timer); gtk_widget_destroy(scale_dialog); @@ -378,42 +402,66 @@ void set_tune(double value) { } } if(scale_status==NONE) { - scale_status=TUNE_DRIVE; - scale_dialog=gtk_dialog_new_with_buttons("Tune Drive",GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL); + scale_status=SQUELCH; + scale_dialog=gtk_dialog_new_with_buttons("Squelch",GTK_WINDOW(top_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); - gtk_widget_set_size_request (tune_scale, 400, 30); - gtk_range_set_value (GTK_RANGE(tune_scale),value); - gtk_widget_show(tune_scale); - gtk_container_add(GTK_CONTAINER(content),tune_scale); + squelch_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.00); + gtk_range_set_value (GTK_RANGE(squelch_scale),active_receiver->squelch); + gtk_widget_set_size_request (squelch_scale, 400, 30); + gtk_widget_show(squelch_scale); + gtk_container_add(GTK_CONTAINER(content),squelch_scale); scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL); - //gtk_widget_show_all(scale_dialog); int result=gtk_dialog_run(GTK_DIALOG(scale_dialog)); } else { g_source_remove(scale_timer); - gtk_range_set_value (GTK_RANGE(tune_scale),value); + gtk_range_set_value (GTK_RANGE(squelch_scale),active_receiver->squelch); 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))); +void set_compression(TRANSMITTER* tx) { +// if(display_sliders) { +// gtk_range_set_value (GTK_RANGE(comp_scale),tx->compressor_level); +// } else { + if(scale_status!=COMP) { + if(scale_status!=NONE) { + g_source_remove(scale_timer); + gtk_widget_destroy(scale_dialog); + scale_status=NONE; + } + } + if(scale_status==NONE) { + scale_status=COMP; + scale_dialog=gtk_dialog_new_with_buttons("COMP",GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL); + GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog)); + comp_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 20.0, 1.00); + gtk_range_set_value (GTK_RANGE(comp_scale),tx->compressor_level); + gtk_widget_set_size_request (comp_scale, 400, 30); + gtk_widget_show(comp_scale); + gtk_container_add(GTK_CONTAINER(content),comp_scale); + scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL); + int result=gtk_dialog_run(GTK_DIALOG(scale_dialog)); + } else { + g_source_remove(scale_timer); + gtk_range_set_value (GTK_RANGE(comp_scale),tx->compressor_level); + scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL); + } + //} } GtkWidget *sliders_init(int my_width, int my_height) { - width=my_width; - height=my_height; + width=my_width; + height=my_height; - fprintf(stderr,"sliders_init: width=%d height=%d\n", width,height); +fprintf(stderr,"sliders_init: width=%d height=%d\n", width,height); - sliders=gtk_grid_new(); - gtk_widget_set_size_request (sliders, width, height); - gtk_grid_set_row_homogeneous(GTK_GRID(sliders), FALSE); - gtk_grid_set_column_homogeneous(GTK_GRID(sliders),TRUE); + sliders=gtk_grid_new(); + gtk_widget_set_size_request (sliders, width, height); + gtk_grid_set_row_homogeneous(GTK_GRID(sliders), FALSE); + gtk_grid_set_column_homogeneous(GTK_GRID(sliders),TRUE); af_gain_label=gtk_label_new("AF:"); - //gtk_widget_override_font(af_gain_label, pango_font_description_from_string("Arial 16")); gtk_widget_show(af_gain_label); gtk_grid_attach(GTK_GRID(sliders),af_gain_label,0,0,1,1); @@ -424,7 +472,6 @@ GtkWidget *sliders_init(int my_width, int my_height) { g_signal_connect(G_OBJECT(af_gain_scale),"value_changed",G_CALLBACK(afgain_value_changed_cb),NULL); agc_gain_label=gtk_label_new("AGC:"); - //gtk_widget_override_font(agc_gain_label, pango_font_description_from_string("Arial 16")); gtk_widget_show(agc_gain_label); gtk_grid_attach(GTK_GRID(sliders),agc_gain_label,3,0,1,1); @@ -435,7 +482,6 @@ GtkWidget *sliders_init(int my_width, int my_height) { g_signal_connect(G_OBJECT(agc_scale),"value_changed",G_CALLBACK(agcgain_value_changed_cb),NULL); attenuation_label=gtk_label_new("ATT (dB):"); - //gtk_widget_override_font(attenuation_label, pango_font_description_from_string("Arial 16")); gtk_widget_show(attenuation_label); gtk_grid_attach(GTK_GRID(sliders),attenuation_label,6,0,1,1); @@ -446,28 +492,15 @@ GtkWidget *sliders_init(int my_width, int my_height) { g_signal_connect(G_OBJECT(attenuation_scale),"value_changed",G_CALLBACK(attenuation_value_changed_cb),NULL); - - mic_gain_label=gtk_label_new("Mic (dB):"); - //gtk_widget_override_font(mic_gain_label, pango_font_description_from_string("Arial 16")); + mic_gain_label=gtk_label_new(mic_linein?"Linein:":"Mic (dB):"); gtk_grid_attach(GTK_GRID(sliders),mic_gain_label,0,1,1,1); - mic_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,-10.0, 50.0, 1.0); - gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_gain); + mic_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,mic_linein?0.0:-10.0,mic_linein?31.0:50.0, 1.0); + gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_linein?linein_gain:mic_gain); 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); - linein_gain_label=gtk_label_new("Linein:"); - gtk_grid_attach(GTK_GRID(sliders),linein_gain_label,0,1,1,1); - - linein_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 31.0, 1.0); - gtk_range_set_value (GTK_RANGE(linein_gain_scale),linein_gain); - gtk_widget_show(linein_gain_scale); - gtk_grid_attach(GTK_GRID(sliders),linein_gain_scale,1,1,2,1); - g_signal_connect(G_OBJECT(linein_gain_scale),"value_changed",G_CALLBACK(lineingain_value_changed_cb),NULL); - drive_label=gtk_label_new("Drive:"); - //gtk_widget_override_font(drive_label, pango_font_description_from_string("Arial 16")); - 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); @@ -476,21 +509,21 @@ GtkWidget *sliders_init(int my_width, int my_height) { 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); - tune_label=gtk_label_new("Tune:"); - //gtk_widget_override_font(tune_label, pango_font_description_from_string("Arial 16")); - 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); - gtk_range_set_value (GTK_RANGE(tune_scale),getTuneDrive()); - 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); - - dummy_label=gtk_label_new(" "); - //gtk_widget_override_font(dummy_label, pango_font_description_from_string("Arial 16")); - gtk_widget_show(dummy_label); - gtk_grid_attach(GTK_GRID(sliders),dummy_label,9,1,1,1); + squelch_label=gtk_label_new("Squelch:"); + gtk_widget_show(squelch_label); + gtk_grid_attach(GTK_GRID(sliders),squelch_label,6,1,1,1); + + squelch_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.0); + gtk_range_set_value (GTK_RANGE(squelch_scale),active_receiver->squelch); + gtk_widget_show(squelch_scale); + gtk_grid_attach(GTK_GRID(sliders),squelch_scale,7,1,2,1); + g_signal_connect(G_OBJECT(squelch_scale),"value_changed",G_CALLBACK(squelch_value_changed_cb),NULL); + + squelch_enable=gtk_check_button_new(); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(squelch_enable),active_receiver->squelch_enable); + gtk_widget_show(squelch_enable); + gtk_grid_attach(GTK_GRID(sliders),squelch_enable,9,1,1,1); + g_signal_connect(squelch_enable,"toggled",G_CALLBACK(squelch_enable_cb),NULL); return sliders; } diff --git a/sliders.h b/sliders.h index 17aa927..14b55f5 100644 --- a/sliders.h +++ b/sliders.h @@ -20,10 +20,9 @@ #ifndef _SLIDERS_H #define _SLIDERS_H -extern int linein_changed(void *data); -extern int active_receiver_changed(void *data); -extern int update_agc_gain(void *); -extern int update_af_gain(void *); +extern int sliders_active_receiver_changed(void *data); +extern void update_agc_gain(double gain); +extern void update_af_gain(); extern int update_mic_gain(void *); extern int update_drive(void *); @@ -31,8 +30,12 @@ extern void set_agc_gain(double value); extern void set_af_gain(double value); extern void set_mic_gain(double value); extern void set_drive(double drive); -extern void set_tune(double tune); +//extern void set_tune(double tune); extern void set_attenuation_value(double attenuation); extern GtkWidget *sliders_init(int my_width, int my_height); +extern void sliders_update(); + +extern void set_squelch(RECEIVER* rx); + #endif diff --git a/soundio.c b/soundio.c index 8b1f983..d711fcf 100644 --- a/soundio.c +++ b/soundio.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/splash.c b/splash.c deleted file mode 100644 index 0520d5b..0000000 --- a/splash.c +++ /dev/null @@ -1,73 +0,0 @@ -/* 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 -#include "version.h" - -GtkWidget *grid; -GtkWidget *status; -static cairo_surface_t *splash_surface = NULL; - - -/* Close the splash screen */ -void splash_close() -{ - gtk_widget_destroy(grid); -} - -GtkWidget *splash_create(char* image_name,int width,int height) -{ - GtkWidget *image; - - grid = gtk_grid_new(); - gtk_widget_set_size_request(grid, width, height); - gtk_grid_set_row_homogeneous(GTK_GRID(grid),FALSE); - gtk_grid_set_column_homogeneous(GTK_GRID(grid),FALSE); - - image=gtk_image_new_from_file(image_name); - gtk_grid_attach(GTK_GRID(grid), image, 0, 0, 1, 4); - - char build[64]; - sprintf(build,"build: %s %s",build_date, version); - - GtkWidget *pi_label=gtk_label_new("pihpsdr by John Melton g0orx/n6lyt"); - gtk_label_set_justify(GTK_LABEL(pi_label),GTK_JUSTIFY_LEFT); - gtk_widget_show(pi_label); - gtk_grid_attach(GTK_GRID(grid),pi_label,1,0,1,1); - GtkWidget *build_date_label=gtk_label_new(build); - gtk_label_set_justify(GTK_LABEL(build_date_label),GTK_JUSTIFY_LEFT); - gtk_widget_show(build_date_label); - gtk_grid_attach(GTK_GRID(grid),build_date_label,1,1,1,1); - - status=gtk_label_new(""); - gtk_label_set_justify(GTK_LABEL(status),GTK_JUSTIFY_LEFT); - gtk_widget_override_font(status, pango_font_description_from_string("FreeMono 18")); - gtk_widget_show(status); - gtk_grid_attach(GTK_GRID(grid), status, 1, 3, 1, 1); - - return grid; -} - -void splash_status(char *text) { - //fprintf(stderr,"splash_status: %s\n",text); - gtk_label_set_text(GTK_LABEL(status),text); - usleep(10000); - while (gtk_events_pending ()) - gtk_main_iteration (); -} diff --git a/step_menu.c b/step_menu.c index cf1a9fc..d1d0a87 100644 --- a/step_menu.c +++ b/step_menu.c @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include "new_menu.h" @@ -29,18 +31,27 @@ static GtkWidget *parent_window=NULL; static GtkWidget *dialog=NULL; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static gboolean step_select_cb (GtkWidget *widget, gpointer data) { - step=steps[(int)data]; - vfo_update(NULL); + step=steps[(uintptr_t)data]; + vfo_update(); } void step_menu(GtkWidget *parent) { @@ -49,7 +60,9 @@ void step_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - VFO Step"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -65,7 +78,7 @@ void step_menu(GtkWidget *parent) { gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); - GtkWidget *close_b=gtk_button_new_with_label("Close Step"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); @@ -81,7 +94,7 @@ void step_menu(GtkWidget *parent) { gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (step_rb), steps[i]==step); gtk_widget_show(step_rb); gtk_grid_attach(GTK_GRID(grid),step_rb,i%5,1+(i/5),1,1); - g_signal_connect(step_rb,"pressed",G_CALLBACK(step_select_cb),(gpointer *)i); + g_signal_connect(step_rb,"pressed",G_CALLBACK(step_select_cb),(gpointer)(long)i); i++; } diff --git a/store_menu.c b/store_menu.c index 71e79ae..80f3871 100644 --- a/store_menu.c +++ b/store_menu.c @@ -20,6 +20,8 @@ #include #include +#include +#include #include #include "new_menu.h" @@ -34,6 +36,7 @@ #include "vfo.h" #include "button_text.h" #include "store.h" +#include "ext.h" static GtkWidget *parent_window=NULL; @@ -41,17 +44,26 @@ static GtkWidget *dialog=NULL; GtkWidget *store_button[NUM_OF_MEMORYS]; -static gboolean store_close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static gboolean store_select_cb (GtkWidget *widget, gpointer data) { - int index = (int) data; + int index = (uintptr_t) data; fprintf(stderr,"STORE BUTTON PUSHED=%d\n",index); char workstr[40]; @@ -74,7 +86,7 @@ static gboolean store_select_cb (GtkWidget *widget, gpointer data) { } static gboolean recall_select_cb (GtkWidget *widget, gpointer data) { - int index = (int) data; + int index = (uintptr_t) data; long long new_freq; //new_freq = mem[index].frequency; @@ -93,7 +105,7 @@ static gboolean recall_select_cb (GtkWidget *widget, gpointer data) { //vfo_band_changed(vfo[active_receiver->id].band); vfo_filter_changed(mem[index].filter); vfo_mode_changed(mem[index].mode); - g_idle_add(vfo_update,NULL); + g_idle_add(ext_vfo_update,NULL); } @@ -107,7 +119,9 @@ void store_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - Store"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -125,20 +139,20 @@ void store_menu(GtkWidget *parent) { gtk_grid_set_column_spacing (GTK_GRID(grid),5); gtk_grid_set_row_spacing (GTK_GRID(grid),5); - GtkWidget *close_b=gtk_button_new_with_label("Close Store"); - g_signal_connect (close_b, "pressed", G_CALLBACK(store_close_cb), NULL); + GtkWidget *close_b=gtk_button_new_with_label("Close"); + g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); for(i=0;i #include #include +#include +#include #include #ifdef GPIO #include "gpio.h" @@ -32,6 +34,7 @@ #include "band.h" #include "discovered.h" #include "new_protocol.h" +#include "old_protocol.h" #include "vfo.h" #include "alex.h" #include "agc.h" @@ -46,6 +49,7 @@ #ifdef RADIOBERRY #include "radioberry.h" #endif +#include "ext.h" #define MAX_FUNCTION 3 int function=0; @@ -80,11 +84,14 @@ static gint rit_plus_timer=-1; static gint rit_minus_timer=-1; static gboolean rit_timer_cb(gpointer data) { - int i=(int)data; + int i=(uintptr_t)data; vfo[active_receiver->id].rit+=(i*rit_increment); if(vfo[active_receiver->id].rit>1000) vfo[active_receiver->id].rit=1000; if(vfo[active_receiver->id].rit<-1000) vfo[active_receiver->id].rit=-1000; - vfo_update(NULL); + if(protocol==NEW_PROTOCOL) { + schedule_high_priority(); + } + vfo_update(); return TRUE; } @@ -116,7 +123,7 @@ void update_toolbar_labels() { gtk_button_set_label(GTK_BUTTON(sim_s1),"Freq"); gtk_button_set_label(GTK_BUTTON(sim_s2),"Mem"); //gtk_button_set_label(GTK_BUTTON(sim_s3),"Vox"); - gtk_button_set_label(GTK_BUTTON(sim_s3),vfo[active_receiver->id].rit_enabled==0?"RIT On":"RIT Off"); + gtk_button_set_label(GTK_BUTTON(sim_s3),"RIT"); gtk_button_set_label(GTK_BUTTON(sim_s4),"RIT+"); gtk_button_set_label(GTK_BUTTON(sim_s5),"RIT-"); @@ -140,10 +147,10 @@ void update_toolbar_labels() { } else { gtk_button_set_label(GTK_BUTTON(sim_s2),""); } - gtk_button_set_label(GTK_BUTTON(sim_s3),""); - gtk_button_set_label(GTK_BUTTON(sim_s4),""); - gtk_button_set_label(GTK_BUTTON(sim_s5),""); - gtk_button_set_label(GTK_BUTTON(sim_s6),""); + gtk_button_set_label(GTK_BUTTON(sim_s3),"Band"); + gtk_button_set_label(GTK_BUTTON(sim_s4),"Mode"); + gtk_button_set_label(GTK_BUTTON(sim_s5),"Filter"); + gtk_button_set_label(GTK_BUTTON(sim_s6),"Mox"); if(full_tune) { set_button_text_color(sim_s1,"red"); } @@ -191,7 +198,7 @@ void ctun_cb (GtkWidget *widget, gpointer data) { } vfo[id].ctun_frequency=vfo[id].frequency; set_offset(active_receiver,vfo[id].offset); - vfo_update(NULL); + vfo_update(); } static void atob_cb (GtkWidget *widget, gpointer data) { @@ -213,31 +220,36 @@ static void split_cb (GtkWidget *widget, gpointer data) { } else { tx_set_mode(transmitter,vfo[VFO_A].mode); } - vfo_update(NULL); + vfo_update(); } static void rit_enable_cb(GtkWidget *widget, gpointer data) { vfo[active_receiver->id].rit_enabled=vfo[active_receiver->id].rit_enabled==1?0:1; - gtk_button_set_label(GTK_BUTTON(widget),vfo[active_receiver->id].rit_enabled==0?"RIT On":"RIT Off"); - vfo_update(NULL); + if(protocol==NEW_PROTOCOL) { + schedule_high_priority(); + } + vfo_update(); } static void rit_cb(GtkWidget *widget, gpointer data) { - int i=(int)data; + int i=(uintptr_t)data; vfo[active_receiver->id].rit+=i*rit_increment; if(vfo[active_receiver->id].rit>1000) vfo[active_receiver->id].rit=1000; if(vfo[active_receiver->id].rit<-1000) vfo[active_receiver->id].rit=-1000; - vfo_update(NULL); + if(protocol==NEW_PROTOCOL) { + schedule_high_priority(); + } + vfo_update(); if(i<0) { - rit_minus_timer=g_timeout_add(200,rit_timer_cb,(void *)i); + rit_minus_timer=g_timeout_add(200,rit_timer_cb,(gpointer)(long)i); } else { - rit_plus_timer=g_timeout_add(200,rit_timer_cb,(void *)i); + rit_plus_timer=g_timeout_add(200,rit_timer_cb,(gpointer)(long)i); } } static void rit_clear_cb(GtkWidget *widget, gpointer data) { vfo[active_receiver->id].rit=0; - vfo_update(NULL); + vfo_update(); } static void freq_cb(GtkWidget *widget, gpointer data) { @@ -250,7 +262,7 @@ static void mem_cb(GtkWidget *widget, gpointer data) { static void vox_cb(GtkWidget *widget, gpointer data) { vox_enabled=vox_enabled==1?0:1; - vfo_update(NULL); + vfo_update(); } static void stop() { @@ -267,6 +279,9 @@ static void stop() { #ifdef GPIO gpio_close(); #endif +#ifdef WIRIINGPI + gpio_close(); +#endif } static void yes_cb(GtkWidget *widget, gpointer data) { @@ -323,241 +338,13 @@ static void exit_cb(GtkWidget *widget, gpointer data) { } -static void cw_keyer_internal_cb(GtkWidget *widget, gpointer data) { - cw_keyer_internal=cw_keyer_internal==1?0:1; - cw_changed(); -} - -static void cw_keyer_speed_value_changed_cb(GtkWidget *widget, gpointer data) { - cw_keyer_speed=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); - cw_changed(); -} - -static void cw_breakin_cb(GtkWidget *widget, gpointer data) { - cw_breakin=cw_breakin==1?0:1; - cw_changed(); -} - -static void cw_keyer_hang_time_value_changed_cb(GtkWidget *widget, gpointer data) { - cw_keyer_hang_time=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); - cw_changed(); -} - -static void cw_keys_reversed_cb(GtkWidget *widget, gpointer data) { - cw_keys_reversed=cw_keys_reversed==1?0:1; - cw_changed(); -} - -static void cw_keyer_mode_cb(GtkWidget *widget, gpointer data) { - cw_keyer_mode=(int)data; - cw_changed(); -} - -static void vfo_divisor_value_changed_cb(GtkWidget *widget, gpointer data) { - vfo_encoder_divisor=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); -} - -static void panadapter_high_value_changed_cb(GtkWidget *widget, gpointer data) { - panadapter_high=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); -} - -static void panadapter_low_value_changed_cb(GtkWidget *widget, gpointer data) { - panadapter_low=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); -} - -static void waterfall_high_value_changed_cb(GtkWidget *widget, gpointer data) { - waterfall_high=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); -} - -static void waterfall_low_value_changed_cb(GtkWidget *widget, gpointer data) { - waterfall_low=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); -} - -static void waterfall_automatic_cb(GtkWidget *widget, gpointer data) { - waterfall_automatic=waterfall_automatic==1?0:1; -} - -static void config_cb(GtkWidget *widget, gpointer data) { - GtkWidget *dialog=gtk_dialog_new_with_buttons("Audio",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL); - GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog)); - GtkWidget *grid=gtk_grid_new(); - gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); - gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); - - 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,0,1,1); - - GtkWidget *panadapter_high_label=gtk_label_new("Panadapter High: "); - //gtk_widget_override_font(panadapter_high_label, pango_font_description_from_string("Arial 18")); - gtk_widget_show(panadapter_high_label); - gtk_grid_attach(GTK_GRID(grid),panadapter_high_label,0,1,1,1); - - GtkWidget *panadapter_high_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0); - //gtk_widget_override_font(panadapter_high_r, pango_font_description_from_string("Arial 18")); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(panadapter_high_r),(double)panadapter_high); - gtk_widget_show(panadapter_high_r); - gtk_grid_attach(GTK_GRID(grid),panadapter_high_r,1,1,1,1); - g_signal_connect(panadapter_high_r,"value_changed",G_CALLBACK(panadapter_high_value_changed_cb),NULL); - - GtkWidget *panadapter_low_label=gtk_label_new("Panadapter Low: "); - //gtk_widget_override_font(panadapter_low_label, pango_font_description_from_string("Arial 18")); - gtk_widget_show(panadapter_low_label); - gtk_grid_attach(GTK_GRID(grid),panadapter_low_label,0,2,1,1); - - GtkWidget *panadapter_low_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0); - //gtk_widget_override_font(panadapter_low_r, pango_font_description_from_string("Arial 18")); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(panadapter_low_r),(double)panadapter_low); - gtk_widget_show(panadapter_low_r); - gtk_grid_attach(GTK_GRID(grid),panadapter_low_r,1,2,1,1); - g_signal_connect(panadapter_low_r,"value_changed",G_CALLBACK(panadapter_low_value_changed_cb),NULL); - - GtkWidget *waterfall_automatic_label=gtk_label_new("Waterfall Automatic: "); - //gtk_widget_override_font(waterfall_automatic_label, pango_font_description_from_string("Arial 18")); - gtk_widget_show(waterfall_automatic_label); - gtk_grid_attach(GTK_GRID(grid),waterfall_automatic_label,0,3,1,1); - - GtkWidget *waterfall_automatic_b=gtk_check_button_new(); - ////gtk_widget_override_font(waterfall_automatic_b, pango_font_description_from_string("Arial 18")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (waterfall_automatic_b), waterfall_automatic); - gtk_widget_show(waterfall_automatic_b); - gtk_grid_attach(GTK_GRID(grid),waterfall_automatic_b,1,3,1,1); - g_signal_connect(waterfall_automatic_b,"toggled",G_CALLBACK(waterfall_automatic_cb),NULL); - - GtkWidget *waterfall_high_label=gtk_label_new("Waterfall High: "); - //gtk_widget_override_font(waterfall_high_label, pango_font_description_from_string("Arial 18")); - gtk_widget_show(waterfall_high_label); - gtk_grid_attach(GTK_GRID(grid),waterfall_high_label,0,4,1,1); - - GtkWidget *waterfall_high_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0); - //gtk_widget_override_font(waterfall_high_r, pango_font_description_from_string("Arial 18")); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(waterfall_high_r),(double)waterfall_high); - gtk_widget_show(waterfall_high_r); - gtk_grid_attach(GTK_GRID(grid),waterfall_high_r,1,4,1,1); - g_signal_connect(waterfall_high_r,"value_changed",G_CALLBACK(waterfall_high_value_changed_cb),NULL); - - GtkWidget *waterfall_low_label=gtk_label_new("Waterfall Low: "); - //gtk_widget_override_font(waterfall_low_label, pango_font_description_from_string("Arial 18")); - gtk_widget_show(waterfall_low_label); - gtk_grid_attach(GTK_GRID(grid),waterfall_low_label,0,5,1,1); - - GtkWidget *waterfall_low_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0); - //gtk_widget_override_font(waterfall_low_r, pango_font_description_from_string("Arial 18")); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(waterfall_low_r),(double)waterfall_low); - gtk_widget_show(waterfall_low_r); - gtk_grid_attach(GTK_GRID(grid),waterfall_low_r,1,5,1,1); - g_signal_connect(waterfall_low_r,"value_changed",G_CALLBACK(waterfall_low_value_changed_cb),NULL); - - - GtkWidget *vfo_encoder_label=gtk_label_new("VFO Encoder: "); - //gtk_widget_override_font(vfo_encoder_label, pango_font_description_from_string("Arial 18")); - gtk_widget_show(vfo_encoder_label); - gtk_grid_attach(GTK_GRID(grid),vfo_encoder_label,0,6,1,1); - - GtkWidget *vfo_divisor_label=gtk_label_new("Divisor: "); - //gtk_widget_override_font(vfo_divisor_label, pango_font_description_from_string("Arial 18")); - gtk_widget_show(vfo_divisor_label); - gtk_grid_attach(GTK_GRID(grid),vfo_divisor_label,0,7,1,1); - - GtkWidget *vfo_divisor=gtk_spin_button_new_with_range(1.0,60.0,1.0); - //gtk_widget_override_font(vfo_divisor, pango_font_description_from_string("Arial 18")); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(vfo_divisor),(double)vfo_encoder_divisor); - gtk_widget_show(vfo_divisor); - gtk_grid_attach(GTK_GRID(grid),vfo_divisor,1,7,1,1); - g_signal_connect(vfo_divisor,"value_changed",G_CALLBACK(vfo_divisor_value_changed_cb),NULL); - - gtk_container_add(GTK_CONTAINER(content),grid); - GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK); - //gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 18")); - gtk_widget_show_all(dialog); - - g_signal_connect_swapped (dialog, - "response", - G_CALLBACK (gtk_widget_destroy), - dialog); - - int result=gtk_dialog_run(GTK_DIALOG(dialog)); -} - -static void cw_cb(GtkWidget *widget, gpointer data) { - GtkWidget *dialog=gtk_dialog_new_with_buttons("CW",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL); - GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog)); - GtkWidget *grid=gtk_grid_new(); - //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); - gtk_grid_set_row_homogeneous(GTK_GRID(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(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(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(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(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(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(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(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); - - gtk_container_add(GTK_CONTAINER(content),grid); - GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK); - //gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 18")); - gtk_widget_show_all(dialog); - - g_signal_connect_swapped (dialog, - "response", - G_CALLBACK (gtk_widget_destroy), - dialog); - - int result=gtk_dialog_run(GTK_DIALOG(dialog)); -} - void lock_cb(GtkWidget *widget, gpointer data) { locked=locked==1?0:1; - vfo_update(NULL); + vfo_update(); } void mox_cb(GtkWidget *widget, gpointer data) { -fprintf(stderr,"mox_cb: mox=%d\n",mox); if(getTune()==1) { setTune(0); } @@ -571,11 +358,10 @@ fprintf(stderr,"mox_cb: mox=%d\n",mox); } else { transmitter_set_out_of_band(transmitter); } - g_idle_add(vfo_update,NULL); + g_idle_add(ext_vfo_update,NULL); } -int mox_update(void *data) { - int state=(int)data; +void mox_update(int state) { if(getTune()==1) { setTune(0); } @@ -588,26 +374,11 @@ int mox_update(void *data) { } else { setMox(state); } - g_idle_add(vfo_update,NULL); - return 0; + g_idle_add(ext_vfo_update,NULL); } -int ptt_update(void *data) { - - return mox_update(data); -/* - int mode; - if(split) { - mode=vfo[1].mode; - } else { - mode=vfo[0].mode; - } - if(protocol==NEW_PROTOCOL || protocol==ORIGINAL_PROTOCOL || (mode!=modeCWU && mode!=modeCWL)) { - mox_cb(NULL,NULL); - } - g_idle_add(vfo_update,NULL); - return 0; -*/ +void ptt_update(int state) { + mox_update(state); } void tune_cb(GtkWidget *widget, gpointer data) { @@ -621,7 +392,24 @@ void tune_cb(GtkWidget *widget, gpointer data) { } else { transmitter_set_out_of_band(transmitter); } - vfo_update(NULL); + g_idle_add(ext_vfo_update,NULL); +} + +void tune_update(int state) { + if(getMox()==1) { + setMox(0); + } + if(state) { + setTune(0); + if(canTransmit() || tx_out_of_band) { + setTune(1); + } else { + transmitter_set_out_of_band(transmitter); + } + } else { + setTune(state); + } + g_idle_add(ext_vfo_update,NULL); } void sim_s1_pressed_cb(GtkWidget *widget, gpointer data) { @@ -711,6 +499,7 @@ void sim_s3_pressed_cb(GtkWidget *widget, gpointer data) { rit_enable_cb(widget,data); break; case 3: + band_cb(widget,data); break; } } @@ -743,6 +532,7 @@ void sim_s4_pressed_cb(GtkWidget *widget, gpointer data) { } break; case 3: + mode_cb(widget,data); break; } } @@ -779,6 +569,7 @@ void sim_s5_pressed_cb(GtkWidget *widget, gpointer data) { } break; case 3: + filter_cb(widget,data); break; } } @@ -825,6 +616,7 @@ void sim_s6_released_cb(GtkWidget *widget, gpointer data) { case 2: break; case 3: + mox_cb((GtkWidget *)NULL, (gpointer)NULL); break; } } @@ -848,7 +640,7 @@ void sim_function_cb(GtkWidget *widget, gpointer data) { function=0; } update_toolbar_labels(); - vfo_update(NULL); + vfo_update(); } GtkWidget *toolbar_init(int my_width, int my_height, GtkWidget* parent) { diff --git a/toolbar.h b/toolbar.h index 203b606..38b2487 100644 --- a/toolbar.h +++ b/toolbar.h @@ -24,8 +24,9 @@ extern int function; void update_toolbar_labels(); -int ptt_update(void *data); -int mox_update(void *data); +void ptt_update(int state); +void mox_update(int state); +void tune_update(int state); void tune_cb(GtkWidget *widget, gpointer data); void sim_mox_cb(GtkWidget *widget, gpointer data); diff --git a/transmitter.c b/transmitter.c index 3a9420a..0e3adce 100644 --- a/transmitter.c +++ b/transmitter.c @@ -34,10 +34,20 @@ #include "property.h" #include "radio.h" #include "vfo.h" +#include "vox.h" #include "meter.h" +#include "toolbar.h" #include "tx_panadapter.h" #include "waterfall.h" +#include "receiver.h" #include "transmitter.h" +#include "new_protocol.h" +#include "old_protocol.h" +#ifdef FREEDV +#include "freedv.h" +#endif +#include "audio_waterfall.h" +#include "ext.h" #define min(x,y) (xout_of_band=0; - vfo_update(NULL); + vfo_update(); return FALSE; } @@ -57,6 +70,32 @@ void transmitter_set_out_of_band(TRANSMITTER *tx) { tx->out_of_band_timer_id=gdk_threads_add_timeout_full(G_PRIORITY_HIGH_IDLE,1000,update_out_of_band, tx, NULL); } +void transmitter_set_deviation(TRANSMITTER *tx) { + SetTXAFMDeviation(tx->id, (double)tx->deviation); +} + +void transmitter_set_am_carrier_level(TRANSMITTER *tx) { + SetTXAAMCarrierLevel(tx->id, tx->am_carrier_level); +} + +void transmitter_set_ctcss(TRANSMITTER *tx,int run,double frequency) { + tx->ctcss=run; + tx->ctcss_frequency=frequency; +fprintf(stderr,"transmitter_set_ctcss: ctcss_frequency=%f run=%d\n",tx->ctcss_frequency,tx->ctcss); + SetTXACTCSSFreq(tx->id, tx->ctcss_frequency); + SetTXACTCSSRun(tx->id, tx->ctcss); +} + +void transmitter_set_compressor_level(TRANSMITTER *tx,double level) { + tx->compressor_level=level; + SetTXACompressorGain(tx->id, tx->compressor_level); +} + +void transmitter_set_compressor(TRANSMITTER *tx,int state) { + tx->compressor=state; + SetTXACompressorRun(tx->id, tx->compressor); +} + void reconfigure_transmitter(TRANSMITTER *tx,int height) { gtk_widget_set_size_request(tx->panadapter, tx->width, height); } @@ -78,6 +117,13 @@ void transmitter_save_state(TRANSMITTER *tx) { sprintf(value,"%d",tx->alex_antenna); setProperty(name,value); + sprintf(name,"transmitter.%d.panadapter_low",tx->id); + sprintf(value,"%d",tx->panadapter_low); + setProperty(name,value); + sprintf(name,"transmitter.%d.panadapter_high",tx->id); + sprintf(value,"%d",tx->panadapter_high); + setProperty(name,value); + sprintf(name,"transmitter.%d.local_microphone",tx->id); sprintf(value,"%d",tx->local_microphone); setProperty(name,value); @@ -88,6 +134,54 @@ void transmitter_save_state(TRANSMITTER *tx) { sprintf(name,"transmitter.%d.low_latency",tx->id); sprintf(value,"%d",tx->low_latency); setProperty(name,value); +#ifdef PURESIGNAL + sprintf(name,"transmitter.%d.puresignal",tx->id); + sprintf(value,"%d",tx->puresignal); + setProperty(name,value); + sprintf(name,"transmitter.%d.auto_on",tx->id); + sprintf(value,"%d",tx->auto_on); + setProperty(name,value); + sprintf(name,"transmitter.%d.single_on",tx->id); + sprintf(value,"%d",tx->single_on); + setProperty(name,value); +#endif + sprintf(name,"transmitter.%d.ctcss",tx->id); + sprintf(value,"%d",tx->ctcss); + setProperty(name,value); + sprintf(name,"transmitter.%d.ctcss_frequency",tx->id); + sprintf(value,"%f",tx->ctcss_frequency); + setProperty(name,value); + sprintf(name,"transmitter.%d.deviation",tx->id); + sprintf(value,"%d",tx->deviation); + setProperty(name,value); + sprintf(name,"transmitter.%d.am_carrier_level",tx->id); + sprintf(value,"%f",tx->am_carrier_level); + setProperty(name,value); +#ifdef FREEDV + if(strlen(tx->freedv_text_data)>0) { + sprintf(name,"transmitter.%d.freedv_text_data",tx->id); + sprintf(value,"%s",tx->freedv_text_data); + setProperty(name,value); + } +#endif + sprintf(name,"transmitter.%d.drive",tx->id); + sprintf(value,"%d",tx->drive); + setProperty(name,value); + sprintf(name,"transmitter.%d.tune_percent",tx->id); + sprintf(value,"%d",tx->tune_percent); + setProperty(name,value); + sprintf(name,"transmitter.%d.tune_use_drive",tx->id); + sprintf(value,"%d",tx->tune_use_drive); + setProperty(name,value); + sprintf(name,"transmitter.%d.drive_level",tx->id); + sprintf(value,"%d",tx->drive_level); + setProperty(name,value); + sprintf(name,"transmitter.%d.compressor",tx->id); + sprintf(value,"%d",tx->compressor); + setProperty(name,value); + sprintf(name,"transmitter.%d.compressor_level",tx->id); + sprintf(value,"%f",tx->compressor_level); + setProperty(name,value); } void transmitter_restore_state(TRANSMITTER *tx) { @@ -107,6 +201,13 @@ void transmitter_restore_state(TRANSMITTER *tx) { value=getProperty(name); if(value) tx->alex_antenna=atoi(value); + sprintf(name,"transmitter.%d.panadapter_low",tx->id); + value=getProperty(name); + if(value) tx->panadapter_low=atoi(value); + sprintf(name,"transmitter.%d.panadapter_high",tx->id); + value=getProperty(name); + if(value) tx->panadapter_high=atoi(value); + sprintf(name,"transmitter.%d.local_microphone",tx->id); value=getProperty(name); if(value) tx->local_microphone=atoi(value); @@ -116,24 +217,86 @@ void transmitter_restore_state(TRANSMITTER *tx) { sprintf(name,"transmitter.%d.low_latency",tx->id); value=getProperty(name); if(value) tx->low_latency=atoi(value); +#ifdef PURESIGNAL + sprintf(name,"transmitter.%d.puresignal",tx->id); + value=getProperty(name); + if(value) tx->puresignal=atoi(value); + sprintf(name,"transmitter.%d.auto_on",tx->id); + value=getProperty(name); + if(value) tx->auto_on=atoi(value); + sprintf(name,"transmitter.%d.single_on",tx->id); + value=getProperty(name); + if(value) tx->single_on=atoi(value); +#endif + sprintf(name,"transmitter.%d.ctcss",tx->id); + value=getProperty(name); + if(value) tx->ctcss=atoi(value); + sprintf(name,"transmitter.%d.ctcss_frequency",tx->id); + value=getProperty(name); + if(value) tx->ctcss_frequency=atof(value); + sprintf(name,"transmitter.%d.deviation",tx->id); + value=getProperty(name); + if(value) tx->deviation=atoi(value); + sprintf(name,"transmitter.%d.am_carrier_level",tx->id); + value=getProperty(name); + if(value) tx->am_carrier_level=atof(value); +#ifdef FREEDV + sprintf(name,"transmitter.%d.freedv_text_data",tx->id); + value=getProperty(name); + if(value) strcpy(tx->freedv_text_data,value); +#endif + sprintf(name,"transmitter.%d.drive",tx->id); + value=getProperty(name); + if(value) tx->drive=atoi(value); + sprintf(name,"transmitter.%d.tune_percent",tx->id); + value=getProperty(name); + if(value) tx->tune_percent=atoi(value); + sprintf(name,"transmitter.%d.tune_use_drive",tx->id); + value=getProperty(name); + if(value) tx->tune_use_drive=atoi(value); + sprintf(name,"transmitter.%d.drive_level",tx->id); + value=getProperty(name); + if(value) tx->drive_level=atoi(value); + sprintf(name,"transmitter.%d.compressor",tx->id); + value=getProperty(name); + if(value) tx->compressor=atoi(value); + sprintf(name,"transmitter.%d.compressor_level",tx->id); + value=getProperty(name); + if(value) tx->compressor_level=atof(value); } -static gint update_display(gpointer data) { +static gboolean update_display(gpointer data) { TRANSMITTER *tx=(TRANSMITTER *)data; int rc; - double fwd; - double rev; - double exciter; + int i; + +//fprintf(stderr,"update_display: tx id=%d\n",tx->id); if(tx->displaying) { - GetPixels(tx->id,0,tx->pixel_samples,&rc); +#ifdef AUDIO_SAMPLES + if(audio_samples!=NULL) { + GetPixels(CHANNEL_AUDIO,0,audio_samples,&rc); + if(rc) { + audio_waterfall_update(); + } + } +#endif +#ifdef PURESIGNAL + if(tx->puresignal && tx->feedback) { + RECEIVER *tx_feedback=receiver[PS_TX_FEEDBACK]; + GetPixels(tx_feedback->id,0,tx_feedback->pixel_samples,&rc); + memcpy(tx->pixel_samples,tx_feedback->pixel_samples,sizeof(float)*tx->pixels); + } else { +#endif + GetPixels(tx->id,0,tx->pixel_samples,&rc); +#ifdef PURESIGNAL + } +#endif if(rc) { tx_panadapter_update(tx); - } else { -//fprintf(stderr,"tx: update_display: GetPixels: id=%d returned %d\n",tx->id,rc); } - double alc=GetTXAMeter(tx->id, alc); + transmitter->alc=GetTXAMeter(tx->id, alc); double constant1=3.3; double constant2=0.095; @@ -177,17 +340,17 @@ static gint update_display(gpointer data) { } double v1; v1=((double)power/4095.0)*constant1; - fwd=(v1*v1)/constant2; + transmitter->fwd=(v1*v1)/constant2; power=exciter_power; v1=((double)power/4095.0)*constant1; - exciter=(v1*v1)/constant2; + transmitter->exciter=(v1*v1)/constant2; - rev=0.0; + transmitter->rev=0.0; if(alex_forward_power!=0) { power=alex_reverse_power; v1=((double)power/4095.0)*constant1; - rev=(v1*v1)/constant2; + transmitter->rev=(v1*v1)/constant2; } } else { switch(device) { @@ -233,21 +396,21 @@ static gint update_display(gpointer data) { } double v1; v1=((double)power/4095.0)*constant1; - fwd=(v1*v1)/constant2; + transmitter->fwd=(v1*v1)/constant2; power=exciter_power; v1=((double)power/4095.0)*constant1; - exciter=(v1*v1)/constant2; + transmitter->exciter=(v1*v1)/constant2; - rev=0.0; + transmitter->rev=0.0; if(alex_forward_power!=0) { power=alex_reverse_power; v1=((double)power/4095.0)*constant1; - rev=(v1*v1)/constant2; + transmitter->rev=(v1*v1)/constant2; } } - meter_update(POWER,fwd,rev,exciter,alc); + meter_update(POWER,transmitter->fwd,transmitter->rev,transmitter->exciter,transmitter->alc); return TRUE; // keep going } @@ -306,19 +469,6 @@ static void init_analyzer(TRANSMITTER *tx) { } -#ifdef INCLUDED -void transmitter_change_sample_rate(TRANSMITTER *tx,int sample_rate) { - SetChannelState(tx->id,0,1); - tx->mic_sample_rate=sample_rate; - tx->output_samples=tx->buffer_size/(tx->mic_sample_rate/48000); - free(tx->mic_input_buffer); - tx->mic_input_buffer=malloc(sizeof(double)*2*tx->buffer_size); - init_analyzer(tx); -fprintf(stderr,"transmitter_change_sample_rate: id=%d rate=%d output_samples=%d\n",tx->id, tx->mic_sample_rate, tx->output_samples); - SetChannelState(tx->id,1,0); -} -#endif - static void create_visual(TRANSMITTER *tx) { fprintf(stderr,"transmitter: create_visual: id=%d\n",tx->id); @@ -331,6 +481,8 @@ static void create_visual(TRANSMITTER *tx) { gtk_fixed_put(GTK_FIXED(tx->panel),tx->panadapter,0,0); } + gtk_widget_show_all(tx->panel); + } TRANSMITTER *create_transmitter(int id, int buffer_size, int fft_size, int fps, int width, int height) { @@ -348,18 +500,16 @@ TRANSMITTER *create_transmitter(int id, int buffer_size, int fft_size, int fps, if(protocol==ORIGINAL_PROTOCOL) { #endif tx->mic_sample_rate=48000; -// tx->mic_sample_rate=receiver[0]->sample_rate; tx->mic_dsp_rate=48000; tx->iq_output_rate=48000; -// tx->output_samples=tx->buffer_size/(tx->mic_sample_rate/48000); tx->output_samples=tx->buffer_size; - tx->pixels=width; + tx->pixels=width; // to allow 48k to 24k conversion } else { tx->mic_sample_rate=48000; - tx->mic_dsp_rate=48000; + tx->mic_dsp_rate=96000; tx->iq_output_rate=192000; tx->output_samples=tx->buffer_size*4; - tx->pixels=width*4; // to allow 192k to 48k conversion + tx->pixels=width*4; // to allow 192k to 24k conversion } tx->width=width; @@ -367,8 +517,8 @@ TRANSMITTER *create_transmitter(int id, int buffer_size, int fft_size, int fps, tx->display_panadapter=1; tx->display_waterfall=0; - tx->panadapter_high=20; - tx->panadapter_low=-80; + tx->panadapter_high=0; + tx->panadapter_low=-60; tx->displaying=0; @@ -383,13 +533,36 @@ fprintf(stderr,"create_transmitter: id=%d buffer_size=%d mic_sample_rate=%d mic_ tx->low_latency=0; +#ifdef PURESIGNAL + tx->puresignal=0; + tx->feedback=0; + tx->twotone=0; + tx->auto_on=0; + tx->single_on=0; +#endif + + tx->ctcss=0; + tx->ctcss_frequency=100.0; + + tx->deviation=2500; + tx->am_carrier_level=0.5; + +#ifdef FREEDV + strcpy(tx->freedv_text_data,"Call, Name and Location"); + tx->freedv_samples=0; +#endif + + tx->drive=50; + tx->tune_percent=10; + tx->tune_use_drive=0; + + tx->compressor=0; + tx->compressor_level=0.0; + + tx->local_microphone=0; + transmitter_restore_state(tx); - if(split) { - tx->mode=vfo[VFO_B].mode; - } else { - tx->mode=vfo[VFO_A].mode; - } // allocate buffers fprintf(stderr,"transmitter: allocate buffers: mic_input_buffer=%d iq_output_buffer=%d pixels=%d\n",tx->buffer_size,tx->output_samples,tx->pixels); @@ -397,6 +570,7 @@ fprintf(stderr,"transmitter: allocate buffers: mic_input_buffer=%d iq_output_buf tx->iq_output_buffer=malloc(sizeof(double)*2*tx->output_samples); tx->samples=0; tx->pixel_samples=malloc(sizeof(float)*tx->pixels); +fprintf(stderr,"transmitter: allocate buffers: mic_input_buffer=%p iq_output_buffer=%p pixels=%p\n",tx->mic_input_buffer,tx->iq_output_buffer,tx->pixel_samples); fprintf(stderr,"create_transmitter: OpenChannel id=%d buffer_size=%d fft_size=%d sample_rate=%d dspRate=%d outputRate=%d\n", tx->id, @@ -416,17 +590,18 @@ fprintf(stderr,"transmitter: allocate buffers: mic_input_buffer=%d iq_output_buf 0, // run 0.010, 0.025, 0.0, 0.010, 0); -fprintf(stderr,"TXASetNC: %d\n",tx->fft_size); TXASetNC(tx->id, tx->fft_size); -fprintf(stderr,"TXASetMP: %d\n",tx->low_latency); TXASetMP(tx->id, tx->low_latency); - SetTXAMode(tx->id, tx->mode); - tx_set_filter(tx,tx_filter_low,tx_filter_high); + + int mode=vfo[VFO_A].mode; + if(split) { + mode=vfo[VFO_B].mode; + } + SetTXABandpassWindow(tx->id, 1); SetTXABandpassRun(tx->id, 1); - SetTXAFMDeviation(tx->id,(double)deviation); SetTXAFMEmphPosition(tx->id,pre_emphasize); SetTXACFIRRun(tx->id, protocol==NEW_PROTOCOL?1:0); // turned on if new protocol @@ -436,14 +611,14 @@ fprintf(stderr,"TXASetMP: %d\n",tx->low_latency); } else { SetTXAEQRun(tx->id, 0); } - SetTXACTCSSRun(tx->id, 0); + + transmitter_set_ctcss(tx,tx->ctcss,tx->ctcss_frequency); SetTXAAMSQRun(tx->id, 0); - SetTXACompressorRun(tx->id, 0); SetTXAosctrlRun(tx->id, 0); SetTXAALCAttack(tx->id, 1); SetTXAALCDecay(tx->id, 10); - SetTXAALCSt(tx->id, tx_alc); + SetTXAALCSt(tx->id, 1); // turn it on (always on) SetTXALevelerAttack(tx->id, 1); SetTXALevelerDecay(tx->id, 500); @@ -457,6 +632,7 @@ fprintf(stderr,"TXASetMP: %d\n",tx->low_latency); SetTXAPostGenMode(tx->id, 0); SetTXAPostGenToneMag(tx->id, tone_level); + SetTXAPostGenTTMag(tx->id, tone_level,tone_level); SetTXAPostGenToneFreq(tx->id, 0.0); SetTXAPostGenRun(tx->id, 0); @@ -464,6 +640,13 @@ fprintf(stderr,"TXASetMP: %d\n",tx->low_latency); SetTXAPanelGain1(tx->id,gain); SetTXAPanelRun(tx->id, 1); + SetTXAFMDeviation(tx->id, (double)tx->deviation); + SetTXAAMCarrierLevel(tx->id, tx->am_carrier_level); + + SetTXACompressorGain(tx->id, tx->compressor_level); + SetTXACompressorRun(tx->id, tx->compressor); + + tx_set_mode(tx,mode); XCreateAnalyzer(tx->id, &rc, 262144, 1, 1, ""); if (rc != 0) { @@ -492,6 +675,7 @@ void tx_set_filter(TRANSMITTER *tx,int low,int high) { } else { mode=vfo[0].mode; } +//fprintf(stderr,"tx_set_filter: tx=%p mode=%d low=%d high=%d\n",tx,mode,low,high); switch(mode) { case modeLSB: case modeCWL: @@ -512,7 +696,7 @@ void tx_set_filter(TRANSMITTER *tx,int low,int high) { tx->filter_high=high; break; case modeFMN: - if(deviation==2500) { + if(tx->deviation==2500) { tx->filter_low=-4000; tx->filter_high=4000; } else { @@ -553,7 +737,7 @@ static void full_tx_buffer(TRANSMITTER *tx) { switch(protocol) { #ifdef RADIOBERRY - case RADIOBERRY_PROTOCOL: + case RADIOBERRY_PROTOCOL: #endif case ORIGINAL_PROTOCOL: gain=32767.0; // 16 bit @@ -563,83 +747,59 @@ static void full_tx_buffer(TRANSMITTER *tx) { break; } - if(vox_enabled || vox_setting) { - if(split) { - mode=vfo[1].mode; - } else { - mode=vfo[0].mode; - } - switch(mode) { - case modeLSB: - case modeUSB: - case modeDSB: - case modeFMN: - case modeAM: - case modeSAM: -#ifdef FREEDV - case modeFREEDV: -#endif - update_vox(tx); - break; - } - } + update_vox(tx); fexchange0(tx->id, tx->mic_input_buffer, tx->iq_output_buffer, &error); if(error!=0) { fprintf(stderr,"full_tx_buffer: id=%d fexchange0: error=%d\n",tx->id,error); } +#ifdef PURESIGNAL + if(tx->displaying && !(tx->puresignal && tx->feedback)) { +#else if(tx->displaying) { +#endif Spectrum0(1, tx->id, 0, 0, tx->iq_output_buffer); } -if(isTransmitting()) { -#ifdef FREEDV - int mode; - if(split) { - mode=vfo[VFO_B].mode; - } else { - mode=vfo[VFO_A].mode; - } - - if(mode==modeFREEDV) { - gain=8388607.0; - } -#endif + if(isTransmitting()) { - if(radio->device==NEW_DEVICE_ATLAS && atlas_penelope) { - if(tune) { - gain=gain*tune_drive; - } else { - gain=gain*(double)drive; + if(radio->device==NEW_DEVICE_ATLAS && atlas_penelope) { + if(tune && !transmitter->tune_use_drive) { + gain=gain*((double)transmitter->drive_level*100.0/(double)transmitter->tune_percent); + } else { + gain=gain*(double)transmitter->drive_level; + } } - } - for(j=0;joutput_samples;j++) { - isample=(long)(tx->iq_output_buffer[j*2]*gain); - qsample=(long)(tx->iq_output_buffer[(j*2)+1]*gain); - switch(protocol) { - case ORIGINAL_PROTOCOL: - old_protocol_iq_samples(isample,qsample); - break; - case NEW_PROTOCOL: - new_protocol_iq_samples(isample,qsample); - break; + for(j=0;joutput_samples;j++) { + double is=tx->iq_output_buffer[j*2]; + double qs=tx->iq_output_buffer[(j*2)+1]; + isample=is>=0.0?(long)floor(is*gain+0.5):(long)ceil(is*gain-0.5); + qsample=qs>=0.0?(long)floor(qs*gain+0.5):(long)ceil(qs*gain-0.5); + switch(protocol) { + case ORIGINAL_PROTOCOL: + old_protocol_iq_samples(isample,qsample); + break; + case NEW_PROTOCOL: + new_protocol_iq_samples(isample,qsample); + break; #ifdef RADIOBERRY - case RADIOBERRY_PROTOCOL: - radioberry_protocol_iq_samples(isample,qsample); - break; + case RADIOBERRY_PROTOCOL: + radioberry_protocol_iq_samples(isample,qsample); + break; #endif + } } } - } } void add_mic_sample(TRANSMITTER *tx,short mic_sample) { - double mic_sample_double; int mode; - long sample; + double sample; + double mic_sample_double; + int i,s; if(split) { mode=vfo[1].mode; @@ -647,35 +807,128 @@ void add_mic_sample(TRANSMITTER *tx,short mic_sample) { mode=vfo[0].mode; } - switch(mode) { -#ifdef FREEDV - case modeFREEDV: - break; + if(mode==modeCWL || mode==modeCWU || tune) { + mic_sample_double=0.0; + } else { + //long sam=mic_sample<<16; + //sample=(double)sam; + //mic_sample_double=(1.0 / 2147483648.0) * sample; + mic_sample_double=(double)mic_sample/32768.0; + } + tx->mic_input_buffer[tx->samples*2]=mic_sample_double; + tx->mic_input_buffer[(tx->samples*2)+1]=0.0; //mic_sample_double; + tx->samples++; + if(tx->samples==tx->buffer_size) { + full_tx_buffer(tx); + tx->samples=0; + } + +#ifdef AUDIO_WATERFALL + if(audio_samples!=NULL && isTransmitting()) { + if(waterfall_samples==0) { + audio_samples[audio_samples_index]=(float)mic_sample; + audio_samples_index++; + if(audio_samples_index>=AUDIO_WATERFALL_SAMPLES) { + //Spectrum(CHANNEL_AUDIO,0,0,audio_samples,audio_samples); + audio_samples_index=0; + } + } + waterfall_samples++; + if(waterfall_samples==waterfall_resample) { + waterfall_samples=0; + } + } #endif - default: - if(mode==modeCWL || mode==modeCWU || tune) { - mic_sample_double=0.0; - } else { - sample=mic_sample<<16; - mic_sample_double=(1.0 / 2147483648.0) * (double)(sample); +} + +#ifdef PURESIGNAL +void add_ps_iq_samples(TRANSMITTER *tx, double i_sample_tx,double q_sample_tx, double i_sample_rx, double q_sample_rx) { + RECEIVER *tx_feedback=receiver[PS_TX_FEEDBACK]; + RECEIVER *rx_feedback=receiver[PS_RX_FEEDBACK]; + +//fprintf(stderr,"add_ps_iq_samples: samples=%d i_rx=%f q_rx=%f i_tx=%f q_tx=%f\n",rx_feedback->samples, i_sample_rx,q_sample_rx,i_sample_tx,q_sample_tx); + + tx_feedback->iq_input_buffer[tx_feedback->samples*2]=i_sample_tx; + tx_feedback->iq_input_buffer[(tx_feedback->samples*2)+1]=q_sample_tx; + rx_feedback->iq_input_buffer[rx_feedback->samples*2]=i_sample_rx; + rx_feedback->iq_input_buffer[(rx_feedback->samples*2)+1]=q_sample_rx; + + tx_feedback->samples=tx_feedback->samples+1; + rx_feedback->samples=rx_feedback->samples+1; + + if(rx_feedback->samples>=rx_feedback->buffer_size) { + if(isTransmitting()) { + pscc(transmitter->id, rx_feedback->buffer_size, tx_feedback->iq_input_buffer, rx_feedback->iq_input_buffer); + if(transmitter->displaying) { + if(transmitter->feedback) { + Spectrum0(1, tx_feedback->id, 0, 0, tx_feedback->iq_input_buffer); + //} else { + // Spectrum0(1, rx_feedback->id, 0, 0, rx_feedback->iq_input_buffer); + } } -//fprintf(stderr,"add_mic_sample: id=%d sample=%f (%d,%ld)\n",tx->id,mic_sample_double,mic_sample,sample); - tx->mic_input_buffer[tx->samples*2]=mic_sample_double; - tx->mic_input_buffer[(tx->samples*2)+1]=mic_sample_double; - tx->samples++; - if(tx->samples==tx->buffer_size) { - full_tx_buffer(tx); - tx->samples=0; + } + rx_feedback->samples=0; + tx_feedback->samples=0; + } +} +#endif + +#ifdef FREEDV +void add_freedv_mic_sample(TRANSMITTER *tx, short mic_sample) { + int i,s; + + //if(active_receiver->freedv && isTransmitting() && !tune) { + if(!tune) { + if(tx->freedv_samples==0) { + //int modem_samples=mod_sample_freedv(mic_sample); + short vs=(short)((double)mic_sample*pow(10.0, mic_gain / 20.0)); + int modem_samples=mod_sample_freedv(vs); + if(modem_samples!=0) { + for(s=0;sfreedv_samples++; + if(tx->freedv_samples>=freedv_resample) { + tx->freedv_samples=0; + } } } +#endif void tx_set_displaying(TRANSMITTER *tx,int state) { tx->displaying=state; if(state) { -fprintf(stderr,"start tx display update timer: %d\n", 1000/tx->fps); - tx->update_timer_id=gdk_threads_add_timeout_full(G_PRIORITY_HIGH_IDLE,1000/tx->fps, update_display, tx, NULL); + tx->update_timer_id=gdk_threads_add_timeout_full(G_PRIORITY_HIGH_IDLE,1000/tx->fps, update_display, (gpointer)tx, NULL); + } +} + +#ifdef PURESIGNAL +void tx_set_ps(TRANSMITTER *tx,int state) { + tx->puresignal=state; + if(state) { + SetPSControl(tx->id, 0, 0, 1, 0); + } else { + SetPSControl(tx->id, 1, 0, 0, 0); } + vfo_update(); } +void tx_set_twotone(TRANSMITTER *tx,int state) { + transmitter->twotone=state; + if(state) { + SetTXAPostGenMode(transmitter->id, 1); + SetTXAPostGenRun(transmitter->id, 1); + } else { + SetTXAPostGenRun(transmitter->id, 0); + } + g_idle_add(ext_mox_update,(gpointer)(long)state); +} + +void tx_set_ps_sample_rate(TRANSMITTER *tx,int rate) { + SetPSFeedbackRate (tx->id,rate); +} +#endif diff --git a/transmitter.h b/transmitter.h index 20aaf99..6d670a3 100644 --- a/transmitter.h +++ b/transmitter.h @@ -75,18 +75,73 @@ typedef struct _transmitter { int low_latency; +#ifdef PURESIGNAL + int puresignal; + int twotone; + int feedback; + int auto_on; + int single_on; +#endif + + double ctcss_frequency; + int ctcss; + + int deviation; + + double am_carrier_level; + + int attenuation; + + int drive; + int tune_use_drive; + int tune_percent; + + int drive_level; + +#ifdef FREEDV + char freedv_text_data[64]; + int freedv_text_index; + int freedv_samples; +#endif + + int compressor; + double compressor_level; + + double fwd; + double exciter; + double rev; + double alc; + + int x; + int y; + } TRANSMITTER; extern TRANSMITTER *create_transmitter(int id, int buffer_size, int fft_size, int fps, int width, int height); void reconfigure_transmitter(TRANSMITTER *tx,int height); + extern void tx_set_mode(TRANSMITTER* tx,int m); extern void tx_set_filter(TRANSMITTER *tx,int low,int high); +extern void transmitter_set_deviation(TRANSMITTER *tx); +extern void transmitter_set_am_carrier_level(TRANSMITTER *tx); extern void tx_set_pre_emphasize(TRANSMITTER *tx,int state); +extern void transmitter_set_ctcss(TRANSMITTER *tx,int run,double frequency); extern void add_mic_sample(TRANSMITTER *tx,short mic_sample); +extern void add_freedv_mic_sample(TRANSMITTER *tx,short mic_sample); extern void transmitter_save_state(TRANSMITTER *tx); extern void transmitter_set_out_of_band(TRANSMITTER *tx); +extern void tx_set_displaying(TRANSMITTER *tx,int state); + +extern void tx_set_ps(TRANSMITTER *tx,int state); +extern void tx_set_twotone(TRANSMITTER *tx,int state); + +extern void transmitter_set_compressor_level(TRANSMITTER *tx,double level); +extern void transmitter_set_compressor(TRANSMITTER *tx,int state); + +extern void tx_set_ps_sample_rate(TRANSMITTER *tx,int rate); +extern void add_ps_iq_samples(TRANSMITTER *tx, double i_sample_0,double q_sample_0, double i_sample_1, double q_sample_1); #endif diff --git a/tx_menu.c b/tx_menu.c index 0ba3f00..ffad2a2 100644 --- a/tx_menu.c +++ b/tx_menu.c @@ -24,6 +24,7 @@ #include "radio.h" #include "sliders.h" #include "transmitter.h" +#include "ext.h" static GtkWidget *parent_window=NULL; @@ -31,18 +32,39 @@ static GtkWidget *dialog=NULL; static GtkWidget *last_filter; +static GtkWidget *micin_b; static GtkWidget *linein_b; static GtkWidget *micboost_b; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static GtkWidget *tune_label; +static GtkWidget *tune_scale; + +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + +static void comp_enable_cb(GtkWidget *widget, gpointer data) { + transmitter->compressor=gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); +} + +static void comp_cb(GtkWidget *widget, gpointer data) { + transmitter_set_compressor_level(transmitter,gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget))); +} + static void tx_spin_low_cb (GtkWidget *widget, gpointer data) { tx_filter_low=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); tx_set_filter(transmitter,tx_filter_low,tx_filter_high); @@ -57,20 +79,48 @@ static void micboost_cb(GtkWidget *widget, gpointer data) { mic_boost=gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); } -static void linein_cb(GtkWidget *widget, gpointer data) { - mic_linein=gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); - g_idle_add(linein_changed,NULL); +static void panadapter_high_value_changed_cb(GtkWidget *widget, gpointer data) { + transmitter->panadapter_high=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); +} + +static void panadapter_low_value_changed_cb(GtkWidget *widget, gpointer data) { + transmitter->panadapter_low=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); +} + +static void am_carrier_level_value_changed_cb(GtkWidget *widget, gpointer data) { + transmitter->am_carrier_level=gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget)); + transmitter_set_am_carrier_level(transmitter); +} + +static void ctcss_cb (GtkWidget *widget, gpointer data) { + int state=gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); + transmitter_set_ctcss(transmitter,state,transmitter->ctcss_frequency); +} + +static void ctcss_spin_cb (GtkWidget *widget, gpointer data) { + double frequency=gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget)); + transmitter_set_ctcss(transmitter,transmitter->ctcss,frequency); +} + +static void tune_use_drive_cb (GtkWidget *widget, gpointer data) { + transmitter->tune_use_drive=gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); +} + +static void tune_percent_cb (GtkWidget *widget, gpointer data) { + transmitter->tune_percent=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); } static void local_microphone_cb(GtkWidget *widget, gpointer data) { if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) { if(audio_open_input()==0) { transmitter->local_microphone=1; + gtk_widget_hide(micin_b); gtk_widget_hide(linein_b); gtk_widget_hide(micboost_b); } else { transmitter->local_microphone=0; gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE); + gtk_widget_show(micin_b); gtk_widget_show(linein_b); gtk_widget_show(micboost_b); } @@ -78,12 +128,23 @@ static void local_microphone_cb(GtkWidget *widget, gpointer data) { if(transmitter->local_microphone) { transmitter->local_microphone=0; audio_close_input(); + gtk_widget_show(micin_b); gtk_widget_show(linein_b); gtk_widget_show(micboost_b); } } } +static void micin_changed(GtkWidget *widget, gpointer data) { + mic_linein=0; + g_idle_add(ext_sliders_update,NULL); +} + +static void linein_changed(GtkWidget *widget, gpointer data) { + mic_linein=1; + g_idle_add(ext_sliders_update,NULL); +} + static void local_input_changed_cb(GtkWidget *widget, gpointer data) { transmitter->input_device=(int)(long)data; if(transmitter->local_microphone) { @@ -101,6 +162,10 @@ static gboolean emp_cb (GtkWidget *widget, gpointer data) { tx_set_pre_emphasize(transmitter,pre_emphasize); } +static void tune_value_changed_cb(GtkWidget *widget, gpointer data) { + setTuneDrive(gtk_range_get_value(GTK_RANGE(tune_scale))); +} + void tx_menu(GtkWidget *parent) { GtkWidget *b; int i; @@ -109,7 +174,9 @@ void tx_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - Transmit"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -122,8 +189,8 @@ void tx_menu(GtkWidget *parent) { GtkWidget *grid=gtk_grid_new(); - gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); - gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); + //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); + //gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); gtk_grid_set_column_spacing (GTK_GRID(grid),5); gtk_grid_set_row_spacing (GTK_GRID(grid),5); @@ -134,16 +201,85 @@ void tx_menu(GtkWidget *parent) { g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,col,row,1,1); - col++; - - GtkWidget *label=gtk_label_new("Transmit"); - gtk_grid_attach(GTK_GRID(grid),label,col,row,1,1); - row++; col=0; +#ifdef RADIOBERRY + if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL || protocol==RADIOBERRY_PROTOCOL) { +#else + if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL) { +#endif + + micin_b=gtk_radio_button_new_with_label_from_widget(NULL,"Mic In"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (micin_b), mic_linein==0); + gtk_widget_show(micin_b); + gtk_grid_attach(GTK_GRID(grid),micin_b,col,row,1,1); + g_signal_connect(micin_b,"pressed",G_CALLBACK(micin_changed),NULL); + + col++; + + linein_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(micin_b),"Line In"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linein_b), mic_linein==1); + gtk_widget_show(linein_b); + gtk_grid_attach(GTK_GRID(grid),linein_b,col,row,1,1); + g_signal_connect(linein_b,"pressed",G_CALLBACK(linein_changed),NULL); + + row++; + col=0; + + micboost_b=gtk_check_button_new_with_label("Mic Boost (radio only)"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (micboost_b), mic_boost); + gtk_grid_attach(GTK_GRID(grid),micboost_b,col,row,2,1); + g_signal_connect(micboost_b,"toggled",G_CALLBACK(micboost_cb),NULL); + + row++; + col=0; + + GtkWidget *comp_enable=gtk_check_button_new_with_label("Compression (dB):"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (comp_enable), transmitter->compressor); + gtk_grid_attach(GTK_GRID(grid),comp_enable,col,row,1,1); + g_signal_connect(comp_enable,"toggled",G_CALLBACK(comp_enable_cb),NULL); + + col++; + + GtkWidget *comp=gtk_spin_button_new_with_range(0.0,20.0,1.0); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(comp),(double)transmitter->compressor_level); + gtk_grid_attach(GTK_GRID(grid),comp,col,row,1,1); + g_signal_connect(comp,"value-changed",G_CALLBACK(comp_cb),NULL); + + row++; + col=0; - label=gtk_label_new("Filter: "); + } + + if(n_input_devices>0) { + GtkWidget *local_microphone_b=gtk_check_button_new_with_label("Local Microphone Input"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (local_microphone_b), transmitter->local_microphone); + gtk_widget_show(local_microphone_b); + gtk_grid_attach(GTK_GRID(grid),local_microphone_b,col,row++,2,1); + g_signal_connect(local_microphone_b,"toggled",G_CALLBACK(local_microphone_cb),NULL); + + if(transmitter->input_device==-1) { + transmitter->input_device=0; + } + + GtkWidget *input=NULL; + for(i=0;iinput_device==i); + gtk_widget_show(input); + gtk_grid_attach(GTK_GRID(grid),input,col,row++,2,1); + g_signal_connect(input,"pressed",G_CALLBACK(local_input_changed_cb),(gpointer)(long)i); + } + } + + row=1; + col=3; + + GtkWidget *label=gtk_label_new("TX Filter: "); +#ifdef GTK316 + gtk_label_set_xalign(GTK_LABEL(label),0); +#endif gtk_grid_attach(GTK_GRID(grid),label,col,row,1,1); col++; @@ -160,58 +296,111 @@ void tx_menu(GtkWidget *parent) { gtk_grid_attach(GTK_GRID(grid),tx_spin_high,col,row,1,1); g_signal_connect(tx_spin_high,"value-changed",G_CALLBACK(tx_spin_high_cb),NULL); + row++; - col=0; + col=3; -#ifdef RADIOBERRY - if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL || protocol==RADIOBERRY_PROTOCOL) { -#else - if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL) { + GtkWidget *panadapter_high_label=gtk_label_new("Panadapter High: "); +#ifdef GTK316 + gtk_label_set_xalign(GTK_LABEL(panadapter_high_label),0); #endif - linein_b=gtk_check_button_new_with_label("Mic Line In (ACC connector)"); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linein_b), mic_linein); - gtk_grid_attach(GTK_GRID(grid),linein_b,col,++row,3,1); - g_signal_connect(linein_b,"toggled",G_CALLBACK(linein_cb),NULL); + gtk_widget_show(panadapter_high_label); + gtk_grid_attach(GTK_GRID(grid),panadapter_high_label,col,row,1,1); - micboost_b=gtk_check_button_new_with_label("Mic Boost (radio only)"); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (micboost_b), mic_boost); - gtk_grid_attach(GTK_GRID(grid),micboost_b,col,++row,3,1); - g_signal_connect(micboost_b,"toggled",G_CALLBACK(micboost_cb),NULL); + col++; - } + GtkWidget *panadapter_high_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(panadapter_high_r),(double)transmitter->panadapter_high); + gtk_widget_show(panadapter_high_r); + gtk_grid_attach(GTK_GRID(grid),panadapter_high_r,col,row,1,1); + g_signal_connect(panadapter_high_r,"value_changed",G_CALLBACK(panadapter_high_value_changed_cb),NULL); - if(n_input_devices>0) { - GtkWidget *local_microphone_b=gtk_check_button_new_with_label("Local Microphone Input"); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (local_microphone_b), transmitter->local_microphone); - gtk_widget_show(local_microphone_b); - gtk_grid_attach(GTK_GRID(grid),local_microphone_b,col,++row,3,1); - g_signal_connect(local_microphone_b,"toggled",G_CALLBACK(local_microphone_cb),NULL); + row++; + col=3; - if(transmitter->input_device==-1) transmitter->input_device=0; + GtkWidget *panadapter_low_label=gtk_label_new("Panadapter Low: "); +#ifdef GTK316 + gtk_label_set_xalign(GTK_LABEL(panadapter_low_label),0); +#endif + gtk_widget_show(panadapter_low_label); + gtk_grid_attach(GTK_GRID(grid),panadapter_low_label,col,row,1,1); - for(i=0;iinput_device==i); - gtk_widget_show(input); - gtk_grid_attach(GTK_GRID(grid),input,col,++row,3,1); - g_signal_connect(input,"pressed",G_CALLBACK(local_input_changed_cb),(gpointer *)i); - } - } + col++; + + GtkWidget *panadapter_low_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(panadapter_low_r),(double)transmitter->panadapter_low); + gtk_widget_show(panadapter_low_r); + gtk_grid_attach(GTK_GRID(grid),panadapter_low_r,col,row,1,1); + g_signal_connect(panadapter_low_r,"value_changed",G_CALLBACK(panadapter_low_value_changed_cb),NULL); row++; - col=0; + col=3; + + GtkWidget *am_carrier_level_label=gtk_label_new("AM Carrier Level: "); +#ifdef GTK316 + gtk_label_set_xalign(GTK_LABEL(am_carrier_level_label),0); +#endif + gtk_widget_show(am_carrier_level_label); + gtk_grid_attach(GTK_GRID(grid),am_carrier_level_label,col,row,1,1); + + col++; + + GtkWidget *am_carrier_level=gtk_spin_button_new_with_range(0.0,1.0,0.1); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(am_carrier_level),(double)transmitter->am_carrier_level); + gtk_widget_show(am_carrier_level); + gtk_grid_attach(GTK_GRID(grid),am_carrier_level,col,row,1,1); + g_signal_connect(am_carrier_level,"value_changed",G_CALLBACK(am_carrier_level_value_changed_cb),NULL); + + row++; + col=3; GtkWidget *emp_b=gtk_check_button_new_with_label("FM TX Pre-emphasize before limiting"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (emp_b), pre_emphasize); gtk_widget_show(emp_b); - gtk_grid_attach(GTK_GRID(grid),emp_b,col,row,3,1); + gtk_grid_attach(GTK_GRID(grid),emp_b,col,row,2,1); g_signal_connect(emp_b,"toggled",G_CALLBACK(emp_cb),NULL); + row++; + col=3; + + GtkWidget *ctcss_b=gtk_check_button_new_with_label("CTCSS Enable"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ctcss_b), transmitter->ctcss); + gtk_widget_show(ctcss_b); + gtk_grid_attach(GTK_GRID(grid),ctcss_b,col,row,1,1); + g_signal_connect(ctcss_b,"toggled",G_CALLBACK(ctcss_cb),NULL); + + col++; + GtkWidget *ctcss_spin=gtk_spin_button_new_with_range(67.0,250.3,0.1); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(ctcss_spin),(double)transmitter->ctcss_frequency); + gtk_grid_attach(GTK_GRID(grid),ctcss_spin,col,row,1,1); + g_signal_connect(ctcss_spin,"value-changed",G_CALLBACK(ctcss_spin_cb),NULL); + + row++; + col=3; + + GtkWidget *tune_use_drive_b=gtk_check_button_new_with_label("Tune use drive"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tune_use_drive_b), transmitter->tune_use_drive); + gtk_widget_show(tune_use_drive_b); + gtk_grid_attach(GTK_GRID(grid),tune_use_drive_b,col,row,1,1); + g_signal_connect(tune_use_drive_b,"toggled",G_CALLBACK(tune_use_drive_cb),NULL); + + row++; + col=3; + + GtkWidget *tune_percent_label=gtk_label_new("Tune Percent: "); +#ifdef GTK316 + gtk_label_set_xalign(GTK_LABEL(tune_percent_label),0); +#endif + gtk_widget_show(tune_percent_label); + gtk_grid_attach(GTK_GRID(grid),tune_percent_label,col,row,1,1); + + col++; + GtkWidget *tune_percent=gtk_spin_button_new_with_range(1.0,100.0,1.0); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(tune_percent),(double)transmitter->tune_percent); + gtk_grid_attach(GTK_GRID(grid),tune_percent,col,row,1,1); + g_signal_connect(tune_percent,"value-changed",G_CALLBACK(tune_percent_cb),NULL); + + gtk_container_add(GTK_CONTAINER(content),grid); sub_menu=dialog; diff --git a/tx_menu.h b/tx_menu.h index 40408c6..7920fe3 100644 --- a/tx_menu.h +++ b/tx_menu.h @@ -15,4 +15,5 @@ * */ -void tx_menu(GtkWidget *parent); +extern void tx_menu(GtkWidget *parent); +extern void set_tune(double value); diff --git a/tx_panadapter.c b/tx_panadapter.c index 10c09f1..28eb3fc 100644 --- a/tx_panadapter.c +++ b/tx_panadapter.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "agc.h" #include "band.h" #include "channel.h" @@ -51,7 +52,7 @@ static gfloat filter_right; /* Create a new surface of the appropriate size to store our scribbles */ static gboolean -panadapter_configure_event_cb (GtkWidget *widget, +tx_panadapter_configure_event_cb (GtkWidget *widget, GdkEventConfigure *event, gpointer data) { @@ -68,7 +69,7 @@ panadapter_configure_event_cb (GtkWidget *widget, display_height); cairo_t *cr=cairo_create(tx->panadapter_surface); - cairo_set_source_rgb(cr, 0, 0, 0); + cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); cairo_paint(cr); cairo_destroy(cr); return TRUE; @@ -79,20 +80,20 @@ panadapter_configure_event_cb (GtkWidget *widget, * clipped to only draw the exposed areas of the widget */ static gboolean -panadapter_draw_cb (GtkWidget *widget, +tx_panadapter_draw_cb (GtkWidget *widget, cairo_t *cr, gpointer data) { TRANSMITTER *tx=(TRANSMITTER *)data; if(tx->panadapter_surface) { - cairo_set_source_surface (cr, tx->panadapter_surface, 0, 0); + cairo_set_source_surface (cr, tx->panadapter_surface, 0.0, 0.0); cairo_paint (cr); } - return TRUE; + return FALSE; } static gboolean -panadapter_button_press_event_cb (GtkWidget *widget, +tx_panadapter_button_press_event_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { @@ -106,7 +107,7 @@ panadapter_button_press_event_cb (GtkWidget *widget, } static gboolean -panadapter_button_release_event_cb (GtkWidget *widget, +tx_panadapter_button_release_event_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { @@ -132,7 +133,7 @@ panadapter_button_release_event_cb (GtkWidget *widget, } static gboolean -panadapter_motion_notify_event_cb (GtkWidget *widget, +tx_panadapter_motion_notify_event_cb (GtkWidget *widget, GdkEventMotion *event, gpointer data) { @@ -154,7 +155,7 @@ panadapter_motion_notify_event_cb (GtkWidget *widget, } static gboolean -panadapter_scroll_event_cb (GtkWidget *widget, +tx_panadapter_scroll_event_cb (GtkWidget *widget, GdkEventScroll *event, gpointer data) { @@ -174,6 +175,8 @@ void tx_panadapter_update(TRANSMITTER *tx) { gfloat saved_hz_per_pixel; cairo_text_extents_t extents; + if(tx->panadapter_surface) { + int display_width=gtk_widget_get_allocated_width (tx->panadapter); int display_height=gtk_widget_get_allocated_height (tx->panadapter); @@ -182,13 +185,15 @@ void tx_panadapter_update(TRANSMITTER *tx) { id=1; } samples=tx->pixel_samples; + //hz_per_pixel=(double)tx->output_rate/(double)display_width; + //hz_per_pixel=24000.0/(double)display_width; hz_per_pixel=48000.0/(double)display_width; //clear_panadater_surface(); cairo_t *cr; cr = cairo_create (tx->panadapter_surface); - cairo_set_source_rgb (cr, 0, 0, 0); + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); cairo_paint (cr); // filter @@ -204,12 +209,12 @@ void tx_panadapter_update(TRANSMITTER *tx) { for (i = 1; i < numSteps; i++) { int num = tx->panadapter_high - i * 20; int y = (int)floor((tx->panadapter_high - num) * display_height / V); - cairo_set_source_rgb (cr, 0, 1, 1); + cairo_set_source_rgb (cr, 0.0, 1.0, 1.0); cairo_set_line_width(cr, 1.0); cairo_move_to(cr,0.0,(double)y); cairo_line_to(cr,(double)display_width,(double)y); - cairo_set_source_rgb (cr, 0, 1, 1); + cairo_set_source_rgb (cr, 0.0, 1.0, 1.0); cairo_select_font_face(cr, "FreeMono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, 12); char v[32]; @@ -222,6 +227,7 @@ void tx_panadapter_update(TRANSMITTER *tx) { // plot frequency markers long long f; long long divisor=20000; + //long long half=12000LL; //(long long)(tx->output_rate/2); long long half=24000LL; //(long long)(tx->output_rate/2); long long frequency; frequency=vfo[id].frequency+vfo[VFO_B].offset; @@ -230,12 +236,12 @@ void tx_panadapter_update(TRANSMITTER *tx) { f = frequency - half + (long) (hz_per_pixel * i); if (f > 0) { if ((f % divisor) < (long) hz_per_pixel) { - cairo_set_source_rgb (cr, 0, 1, 1); + cairo_set_source_rgb (cr, 0.0, 1.0, 1.0); cairo_set_line_width(cr, 1.0); cairo_move_to(cr,(double)i,10.0); cairo_line_to(cr,(double)i,(double)display_height); - cairo_set_source_rgb (cr, 0, 1, 1); + cairo_set_source_rgb (cr, 0.0, 1.0, 1.0); cairo_select_font_face(cr, "FreeMono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); @@ -262,7 +268,7 @@ void tx_panadapter_update(TRANSMITTER *tx) { } BAND *band=band_get_band(b); if(band->frequencyMin!=0LL) { - cairo_set_source_rgb (cr, 1, 0, 0); + cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); cairo_set_line_width(cr, 2.0); if((min_displayfrequencyMin)&&(max_display>band->frequencyMin)) { i=(band->frequencyMin-min_display)/(long long)hz_per_pixel; @@ -279,7 +285,7 @@ void tx_panadapter_update(TRANSMITTER *tx) { } // cursor - cairo_set_source_rgb (cr, 1, 0, 0); + cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); cairo_set_line_width(cr, 1.0); //fprintf(stderr,"cursor: x=%f\n",(double)(display_width/2.0)+(vfo[tx->id].offset/hz_per_pixel)); cairo_move_to(cr,(double)(display_width/2.0)+(vfo[id].offset/hz_per_pixel),0.0); @@ -293,16 +299,24 @@ void tx_panadapter_update(TRANSMITTER *tx) { int offset=0; - if(protocol==NEW_PROTOCOL) { - offset=1200; + switch(protocol) { + case ORIGINAL_PROTOCOL: + //offset=(tx->pixels/4)*1; + offset=0; + break; + case NEW_PROTOCOL: + //offset=(tx->pixels/16)*7; + offset=(tx->pixels/8)*3; + break; } - s1=(double)samples[0+offset]+(double)get_attenuation(); + + s1=(double)samples[0+offset]/*+(double)get_attenuation()*/; s1 = floor((tx->panadapter_high - s1) * (double) display_height / (tx->panadapter_high - tx->panadapter_low)); cairo_move_to(cr, 0.0, s1); for(i=1;ipanadapter_high - s2) * (double) display_height / (tx->panadapter_high - tx->panadapter_low)); @@ -311,47 +325,64 @@ void tx_panadapter_update(TRANSMITTER *tx) { if(display_filled) { cairo_close_path (cr); - cairo_set_source_rgba(cr, 1, 1, 1,0.5); + cairo_set_source_rgba(cr, 1.0, 1.0, 1.0,0.5); cairo_fill_preserve (cr); } - cairo_set_source_rgb(cr, 1, 1, 1); + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); cairo_set_line_width(cr, 1.0); cairo_stroke(cr); #ifdef FREEDV - int mode; - mode=tx->mode; - if(mode==modeFREEDV) { - cairo_set_source_rgb(cr, 1, 0, 0); + if(active_receiver->freedv) { + cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); cairo_set_font_size(cr, 16); - cairo_text_extents(cr, freedv_text_data, &extents); + cairo_text_extents(cr, transmitter->freedv_text_data, &extents); cairo_move_to(cr, (double)display_width/2.0-(extents.width/2.0),(double)display_height-2.0); - cairo_show_text(cr, freedv_text_data); + cairo_show_text(cr, transmitter->freedv_text_data); } #endif #ifdef GPIO - cairo_set_source_rgb(cr,1,1,0); - cairo_set_font_size(cr,12); + cairo_set_source_rgb(cr,1.0,1.0,0.0); + cairo_set_font_size(cr,16); if(ENABLE_E1_ENCODER) { - cairo_move_to(cr, display_width-100,30); + cairo_move_to(cr, display_width-150,30); cairo_show_text(cr, encoder_string[e1_encoder_action]); } if(ENABLE_E2_ENCODER) { - cairo_move_to(cr, display_width-100,50); + cairo_move_to(cr, display_width-150,50); cairo_show_text(cr, encoder_string[e2_encoder_action]); } if(ENABLE_E3_ENCODER) { - cairo_move_to(cr, display_width-100,70); + cairo_move_to(cr, display_width-150,70); cairo_show_text(cr, encoder_string[e3_encoder_action]); } #endif +#ifdef PURESIGNAL + if(tx->puresignal) { + cairo_set_source_rgb(cr,0.0,1.0,0.0); + cairo_move_to(cr,display_width/2,display_height-10); + cairo_show_text(cr, "PureSignal"); + + int info[16]; + GetPSInfo(tx->id,&info[0]); + if(info[14]==0) { + cairo_set_source_rgb(cr,1.0,0.0,0.0); + } else { + cairo_set_source_rgb(cr,0.0,1.0,0.0); + } + cairo_move_to(cr,(display_width/2)+100,display_height-10); + cairo_show_text(cr, "Correcting"); + } +#endif + cairo_destroy (cr); gtk_widget_queue_draw (tx->panadapter); + } } void tx_panadapter_init(TRANSMITTER *tx, int width,int height) { @@ -359,25 +390,27 @@ void tx_panadapter_init(TRANSMITTER *tx, int width,int height) { int display_width=width; int display_height=height; +fprintf(stderr,"tx_panadapter_init: %d x %d\n",display_width,display_height); + tx->panadapter_surface=NULL; tx->panadapter=gtk_drawing_area_new (); gtk_widget_set_size_request (tx->panadapter, width, height); /* Signals used to handle the backing surface */ g_signal_connect (tx->panadapter, "draw", - G_CALLBACK (panadapter_draw_cb), tx); + G_CALLBACK (tx_panadapter_draw_cb), tx); g_signal_connect (tx->panadapter,"configure-event", - G_CALLBACK (panadapter_configure_event_cb), tx); + G_CALLBACK (tx_panadapter_configure_event_cb), tx); /* Event signals */ g_signal_connect (tx->panadapter, "motion-notify-event", - G_CALLBACK (panadapter_motion_notify_event_cb), tx); + G_CALLBACK (tx_panadapter_motion_notify_event_cb), tx); g_signal_connect (tx->panadapter, "button-press-event", - G_CALLBACK (panadapter_button_press_event_cb), tx); + G_CALLBACK (tx_panadapter_button_press_event_cb), tx); g_signal_connect (tx->panadapter, "button-release-event", - G_CALLBACK (panadapter_button_release_event_cb), tx); + G_CALLBACK (tx_panadapter_button_release_event_cb), tx); g_signal_connect(tx->panadapter,"scroll_event", - G_CALLBACK(panadapter_scroll_event_cb),tx); + G_CALLBACK(tx_panadapter_scroll_event_cb),tx); /* Ask to receive events the drawing area doesn't normally * subscribe to. In particular, we need to ask for the diff --git a/update.c b/update.c index b4f7d49..5f2756a 100644 --- a/update.c +++ b/update.c @@ -23,7 +23,7 @@ int check_update() { FILE* f=fopen("latest","r"); if(f) { - fgets(new_version,sizeof(new_version),f); + char *s=fgets(new_version,sizeof(new_version),f); fclose(f); } else { fprintf(stderr,"check_update: could not read latest version\n"); @@ -42,7 +42,7 @@ int check_update() { fprintf(stderr,"check_version: latest version is %s\n",new_version); - fprintf(stderr,"check_version: length of version=%d length of new_version=%d\n", strlen(version), strlen(new_version)); + fprintf(stderr,"check_version: length of version=%ld length of new_version=%ld\n", strlen(version), strlen(new_version)); rc=strcmp(version,new_version); return rc; diff --git a/vfo.c b/vfo.c index b73484a..4666596 100644 --- a/vfo.c +++ b/vfo.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -53,6 +52,10 @@ #ifdef RADIOBERRY #include "radioberry.h" #endif +#include "ext.h" +#ifdef FREEDV +#include "freedv.h" +#endif static GtkWidget *parent_window; static int my_width; @@ -169,6 +172,17 @@ void vfo_restore_state() { } } +void vfo_xvtr_changed() { + if(vfo[0].band>=BANDS) { + BAND *band=band_get_band(vfo[0].band); + vfo[0].lo=band->frequencyLO+band->errorLO; + } + if(vfo[1].band>=BANDS) { + BAND *band=band_get_band(vfo[1].band); + vfo[1].lo=band->frequencyLO+band->errorLO; + } +} + void vfo_band_changed(int b) { BANDSTACK *bandstack; @@ -196,7 +210,7 @@ void vfo_band_changed(int b) { vfo[id].frequency=entry->frequency; vfo[id].mode=entry->mode; vfo[id].filter=entry->filter; - vfo[id].lo=band->frequencyLO; + vfo[id].lo=band->frequencyLO+band->errorLO; switch(id) { case 0: @@ -221,8 +235,7 @@ void vfo_band_changed(int b) { tx_set_mode(transmitter,vfo[VFO_A].mode); } calcDriveLevel(); - calcTuneDriveLevel(); - vfo_update(NULL); + vfo_update(); } void vfo_bandstack_changed(int b) { @@ -261,8 +274,7 @@ void vfo_bandstack_changed(int b) { tx_set_mode(transmitter,vfo[VFO_A].mode); } calcDriveLevel(); - calcTuneDriveLevel(); - vfo_update(NULL); + vfo_update(); } @@ -287,7 +299,7 @@ void vfo_mode_changed(int m) { tx_set_mode(transmitter,vfo[VFO_A].mode); } - vfo_update(NULL); + vfo_update(); } void vfo_filter_changed(int f) { @@ -304,7 +316,7 @@ void vfo_filter_changed(int f) { break; } - vfo_update(NULL); + vfo_update(); } void vfo_a_to_b() { @@ -313,7 +325,6 @@ void vfo_a_to_b() { vfo[VFO_B].frequency=vfo[VFO_A].frequency; vfo[VFO_B].mode=vfo[VFO_A].mode; vfo[VFO_B].filter=vfo[VFO_A].filter; - vfo[VFO_B].filter=vfo[VFO_A].filter; vfo[VFO_B].lo=vfo[VFO_A].lo; vfo[VFO_B].offset=vfo[VFO_A].offset; vfo[VFO_B].rit_enabled=vfo[VFO_A].rit_enabled; @@ -325,7 +336,7 @@ void vfo_a_to_b() { if(split) { tx_set_mode(transmitter,vfo[VFO_B].mode); } - vfo_update(NULL); + vfo_update(); } void vfo_b_to_a() { @@ -342,7 +353,7 @@ void vfo_b_to_a() { if(!split) { tx_set_mode(transmitter,vfo[VFO_B].mode); } - vfo_update(NULL); + vfo_update(); } void vfo_a_swap_b() { @@ -395,7 +406,7 @@ void vfo_a_swap_b() { } else { tx_set_mode(transmitter,vfo[VFO_A].mode); } - vfo_update(NULL); + vfo_update(); } void vfo_step(int steps) { @@ -411,7 +422,7 @@ void vfo_step(int steps) { BANDSTACK_ENTRY* entry=bandstack_entry_get_current(); setFrequency(active_receiver->frequency+(steps*step)); #endif - vfo_update(NULL); + vfo_update(); } } @@ -433,7 +444,7 @@ void vfo_move(long long hz) { break; } receiver_frequency_changed(active_receiver); - vfo_update(NULL); + vfo_update(); } } @@ -490,7 +501,7 @@ void vfo_move_to(long long hz) { } #endif #endif - vfo_update(NULL); + vfo_update(); } } @@ -523,10 +534,10 @@ static gboolean vfo_configure_event_cb (GtkWidget *widget, /* Initialize the surface to black */ cairo_t *cr; cr = cairo_create (vfo_surface); - cairo_set_source_rgb (cr, 0, 0, 0); + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); cairo_paint (cr); cairo_destroy(cr); - g_idle_add(vfo_update,NULL); + g_idle_add(ext_vfo_update,NULL); return TRUE; } @@ -534,12 +545,12 @@ static gboolean vfo_draw_cb (GtkWidget *widget, cairo_t *cr, gpointer data) { - cairo_set_source_surface (cr, vfo_surface, 0, 0); + cairo_set_source_surface (cr, vfo_surface, 0.0, 0.0); cairo_paint (cr); - return TRUE; + return FALSE; } -int vfo_update(void *data) { +void vfo_update() { int id=active_receiver->id; FILTER* band_filters=filters[vfo[id].mode]; @@ -548,89 +559,62 @@ int vfo_update(void *data) { char temp_text[32]; cairo_t *cr; cr = cairo_create (vfo_surface); - cairo_set_source_rgb (cr, 0, 0, 0); + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); cairo_paint (cr); cairo_select_font_face(cr, "FreeMono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - char version[16]; - char text[128]; -#ifdef RADIOBERRY - if(radio->protocol==ORIGINAL_PROTOCOL || radio->protocol==RADIOBERRY_PROTOCOL ) { -#else - if(radio->protocol==ORIGINAL_PROTOCOL) { -#endif - switch(radio->device) { -#ifdef USBOZY - case DEVICE_OZY: - strcpy(version,""); - break; -#endif - default: - sprintf(version,"%d.%d", - radio->software_version/10, - radio->software_version%10); - break; - } - } else { - sprintf(version,"%d.%d", - radio->software_version/10, - radio->software_version%10); + char dv[32]; + strcpy(dv,""); +#ifdef FREEDV + if(active_receiver->freedv) { + sprintf(dv,"FreeDV %s", freedv_get_mode_string()); } - - switch(radio->protocol) { - case ORIGINAL_PROTOCOL: - switch(radio->device) { -#ifdef USBOZY - case DEVICE_OZY: - sprintf(text,"%s", radio->name); - break; -#endif - default: - sprintf(text,"%s %s %s", - radio->name, - version, - inet_ntoa(radio->info.network.address.sin_addr)); - break; - } - break; - case NEW_PROTOCOL: - sprintf(text,"%s %s %s", - radio->name, - version, - inet_ntoa(radio->info.network.address.sin_addr)); - break; -#ifdef LIMESDR - case LIMESDR_PROTOCOL: - sprintf(text,"%s", radio->name); - break; -#endif -#ifdef RADIOBERRY - case RADIOBERRY_PROTOCOL: - sprintf(text,"%s", radio->name); - break; #endif - } - cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); cairo_set_font_size(cr, 12); - cairo_move_to(cr, 5, 15); - cairo_show_text(cr, text); + cairo_set_source_rgb(cr, 1.0, 1.0, 0.0); + cairo_move_to(cr, 5, 15); + + switch(vfo[id].mode) { + case modeFMN: + if(active_receiver->deviation==2500) { + sprintf(temp_text,"%s 8k %s",mode_string[vfo[id].mode],dv); + } else { + sprintf(temp_text,"%s 16k %s",mode_string[vfo[id].mode],dv); + } + break; + case modeCWL: + case modeCWU: + sprintf(temp_text,"%s %s %d wpm %d Hz",mode_string[vfo[id].mode],band_filter->title,cw_keyer_speed,cw_keyer_sidetone_frequency); + break; + case modeLSB: + case modeUSB: + case modeDSB: + case modeAM: + sprintf(temp_text,"%s %s %s",mode_string[vfo[id].mode],band_filter->title,dv); + break; + default: + sprintf(temp_text,"%s %s",mode_string[vfo[id].mode],band_filter->title); + break; + } + cairo_show_text(cr, temp_text); + long long af=vfo[0].frequency+vfo[0].offset; if(transmitter->out_of_band && !split) { - cairo_set_source_rgb(cr, 1, 0, 0); + cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); sprintf(temp_text,"VFO A: Out of band"); } else { sprintf(temp_text,"VFO A: %0lld.%06lld",af/(long long)1000000,af%(long long)1000000); if(isTransmitting() && !split) { - cairo_set_source_rgb(cr, 1, 0, 0); + cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); } else { if(active_receiver->id==0) { - cairo_set_source_rgb(cr, 0, 1, 0); + cairo_set_source_rgb(cr, 0.0, 1.0, 0.0); } else { - cairo_set_source_rgb(cr, 0, 0.65, 0); + cairo_set_source_rgb(cr, 0.0, 0.65, 0.0); } } } @@ -641,65 +625,50 @@ int vfo_update(void *data) { long long bf=vfo[1].frequency+vfo[1].offset; if(transmitter->out_of_band && split) { - cairo_set_source_rgb(cr, 1, 0, 0); + cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); sprintf(temp_text,"VFO B: Out of band"); } else { sprintf(temp_text,"VFO B: %0lld.%06lld",bf/(long long)1000000,bf%(long long)1000000); if(isTransmitting() && split) { - cairo_set_source_rgb(cr, 1, 0, 0); + cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); } else { if(active_receiver->id==1) { - cairo_set_source_rgb(cr, 0, 1, 0); + cairo_set_source_rgb(cr, 0.0, 1.0, 0.0); } else { - cairo_set_source_rgb(cr, 0, 0.65, 0); + cairo_set_source_rgb(cr, 0.0, 0.65, 0.0); } } } cairo_move_to(cr, 260, 38); cairo_show_text(cr, temp_text); - cairo_set_font_size(cr, 12); - if(vfo[id].rit_enabled==0) { cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); } else { - cairo_set_source_rgb(cr, 1, 1, 0); + cairo_set_source_rgb(cr, 1.0, 1.0, 0.0); } sprintf(temp_text,"RIT: %lld Hz",vfo[id].rit); - cairo_move_to(cr, 5, 50); + cairo_move_to(cr, 210, 15); cairo_set_font_size(cr, 12); cairo_show_text(cr, temp_text); - cairo_move_to(cr, 190, 15); - if(vox_enabled) { - cairo_set_source_rgb(cr, 1, 0, 0); + cairo_move_to(cr, 150, 50); + if(active_receiver->nb) { + cairo_set_source_rgb(cr, 1.0, 1.0, 0.0); } else { cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); } - cairo_show_text(cr, "VOX"); - - cairo_move_to(cr, 220, 15); - if(locked) { - cairo_set_source_rgb(cr, 1, 0, 0); + cairo_show_text(cr, "NB"); + + cairo_move_to(cr, 175, 50); + if(active_receiver->nb2) { + cairo_set_source_rgb(cr, 1.0, 1.0, 0.0); } else { cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); } - cairo_show_text(cr, "Locked"); - - cairo_set_source_rgb(cr, 1, 1, 0); - cairo_move_to(cr, 100, 50); - if(vfo[id].mode==modeFMN) { - if(deviation==2500) { - sprintf(temp_text,"%s 8k",mode_string[vfo[id].mode]); - } else { - sprintf(temp_text,"%s 16k",mode_string[vfo[id].mode]); - } - } else { - sprintf(temp_text,"%s %s",mode_string[vfo[id].mode],band_filter->title); - } - cairo_show_text(cr, temp_text); + cairo_show_text(cr, "NB2"); - cairo_move_to(cr, 170, 50); + cairo_move_to(cr, 200, 50); if(active_receiver->nr) { cairo_set_source_rgb(cr, 1.0, 1.0, 0.0); } else { @@ -707,7 +676,7 @@ int vfo_update(void *data) { } cairo_show_text(cr, "NR"); - cairo_move_to(cr, 200, 50); + cairo_move_to(cr, 225, 50); if(active_receiver->nr2) { cairo_set_source_rgb(cr, 1.0, 1.0, 0.0); } else { @@ -715,7 +684,7 @@ int vfo_update(void *data) { } cairo_show_text(cr, "NR2"); - cairo_move_to(cr, 230, 50); + cairo_move_to(cr, 250, 50); if(active_receiver->anf) { cairo_set_source_rgb(cr, 1.0, 1.0, 0.0); } else { @@ -723,7 +692,7 @@ int vfo_update(void *data) { } cairo_show_text(cr, "ANF"); - cairo_move_to(cr, 260, 50); + cairo_move_to(cr, 275, 50); if(active_receiver->snb) { cairo_set_source_rgb(cr, 1.0, 1.0, 0.0); } else { @@ -731,26 +700,26 @@ int vfo_update(void *data) { } cairo_show_text(cr, "SNB"); - cairo_move_to(cr, 290, 50); + cairo_move_to(cr, 350, 50); switch(active_receiver->agc) { case AGC_OFF: cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); cairo_show_text(cr, "AGC OFF"); break; case AGC_LONG: - cairo_set_source_rgb(cr, 1, 1, 0); + cairo_set_source_rgb(cr, 1.0, 1.0, 0.0); cairo_show_text(cr, "AGC LONG"); break; case AGC_SLOW: - cairo_set_source_rgb(cr, 1, 1, 0); + cairo_set_source_rgb(cr, 1.0, 1.0, 0.0); cairo_show_text(cr, "AGC SLOW"); break; case AGC_MEDIUM: - cairo_set_source_rgb(cr, 1, 1, 0); + cairo_set_source_rgb(cr, 1.0, 1.0, 0.0); cairo_show_text(cr, "AGC MEDIUM"); break; case AGC_FAST: - cairo_set_source_rgb(cr, 1, 1, 0); + cairo_set_source_rgb(cr, 1.0, 1.0, 0.0); cairo_show_text(cr, "AGC FAST"); break; } @@ -760,55 +729,73 @@ int vfo_update(void *data) { s++; } sprintf(temp_text,"Step %s",step_labels[s]); - cairo_move_to(cr, 375, 50); - cairo_set_source_rgb(cr, 1, 1, 0); + cairo_move_to(cr, 300, 15); + cairo_set_source_rgb(cr, 1.0, 1.0, 0.0); cairo_show_text(cr, temp_text); - char *info=getFrequencyInfo(af); + char *info=getFrequencyInfo(af,active_receiver->filter_low,active_receiver->filter_high); /* cairo_move_to(cr, (my_width/4)*3, 50); cairo_show_text(cr, getFrequencyInfo(af)); */ - cairo_move_to(cr, 460, 50); + cairo_move_to(cr, 400, 15); if(vfo[id].ctun) { - cairo_set_source_rgb(cr, 1, 1, 0); + cairo_set_source_rgb(cr, 1.0, 1.0, 0.0); } else { cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); } cairo_show_text(cr, "CTUN"); - cairo_move_to(cr, 500, 50); + cairo_move_to(cr, 450, 15); if(cat_control>0) { - cairo_set_source_rgb(cr, 1, 1, 0); + cairo_set_source_rgb(cr, 1.0, 1.0, 0.0); } else { cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); } cairo_show_text(cr, "CAT"); - cairo_move_to(cr, 270, 15); + cairo_move_to(cr, 500, 15); + if(vox_enabled) { + cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); + } else { + cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); + } + cairo_show_text(cr, "VOX"); + + cairo_move_to(cr, 5, 50); + if(locked) { + cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); + } else { + cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); + } + cairo_show_text(cr, "Locked"); + + cairo_move_to(cr, 55, 50); if(split) { - cairo_set_source_rgb(cr, 1, 0, 0); + cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); } else { cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); } cairo_show_text(cr, "Split"); - - cairo_move_to(cr, 310, 15); - if(vfo[id].mode==modeCWL || vfo[id].mode==modeCWU) { - cairo_set_source_rgb(cr, 1, 1, 0); + +#ifdef PURESIGNAL + cairo_move_to(cr, 105, 50); + if(transmitter->puresignal) { + cairo_set_source_rgb(cr, 1.0, 1.0, 0.0); } else { cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); } - sprintf(temp_text,"CW %d wpm, sidetone %d Hz",cw_keyer_speed,cw_keyer_sidetone_frequency); - cairo_show_text(cr, temp_text); + cairo_show_text(cr, "PS"); +#endif + + cairo_destroy (cr); gtk_widget_queue_draw (vfo_panel); } else { fprintf(stderr,"vfo_update: no surface!\n"); } - return 0; } /* @@ -817,7 +804,7 @@ vfo_step_select_cb (GtkWidget *widget, gpointer data) { step=steps[(int)data]; - vfo_update(NULL); + vfo_update(); } */ @@ -826,15 +813,6 @@ vfo_press_event_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { -/* - if((int)event->x < (my_width/4)) { - //lock_cb(NULL,NULL); - } else if((int)event->x < (my_width/2) && (int)event->x > (my_width/4)) { - start_freqent(); - } else { - start_step(); - } -*/ start_vfo(); return TRUE; } diff --git a/vfo.h b/vfo.h index 1862979..5b812d1 100644 --- a/vfo.h +++ b/vfo.h @@ -52,7 +52,7 @@ extern GtkWidget* vfo_init(int width,int height,GtkWidget *parent); extern void vfo_step(int steps); extern void vfo_move(long long hz); extern void vfo_move_to(long long hz); -extern int vfo_update(void*); +extern void vfo_update(); extern void set_frequency(); extern void vfo_save_state(); @@ -65,4 +65,6 @@ extern void vfo_filter_changed(int f); extern void vfo_a_to_b(); extern void vfo_b_to_a(); extern void vfo_a_swap_b(); + +extern void vfo_xvtr_changed(); #endif diff --git a/vfo_menu.c b/vfo_menu.c index a9dfc35..5afcdc5 100644 --- a/vfo_menu.c +++ b/vfo_menu.c @@ -18,9 +18,11 @@ */ #include +#include #include #include #include +#include #include "new_menu.h" #include "band.h" @@ -28,7 +30,13 @@ #include "mode.h" #include "radio.h" #include "receiver.h" +#include "transmitter.h" #include "vfo.h" +#include "button_text.h" +#include "ext.h" +#ifdef FREEDV +#include "freedv.h" +#endif static GtkWidget *parent_window=NULL; static GtkWidget *dialog=NULL; @@ -44,15 +52,31 @@ static char *btn_labels[] = {"1","2","3", ,"CL" }; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static GtkWidget *btn[16]; + +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + +static void squelch_enable_cb(GtkWidget *widget, gpointer data) { + active_receiver->squelch_enable=gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); + setSquelch(active_receiver); +} + static gboolean freqent_select_cb (GtkWidget *widget, gpointer data) { char *str = (char *) data; const char *labelText; @@ -133,12 +157,12 @@ static gboolean freqent_select_cb (GtkWidget *widget, gpointer data) { } } setFrequency(f); - vfo_update(NULL); + vfo_update(); set = 1; } } - vfo_update(NULL); + vfo_update(); } static void rit_cb(GtkComboBox *widget,gpointer data) { @@ -153,12 +177,38 @@ static void rit_cb(GtkComboBox *widget,gpointer data) { rit_increment=100; break; } - vfo_update(NULL); + vfo_update(); } static void vfo_cb(GtkComboBox *widget,gpointer data) { step=steps[gtk_combo_box_get_active(widget)]; - vfo_update(NULL); + vfo_update(); +} + +#ifdef FREEDV +static void enable_freedv_cb(GtkWidget *widget, gpointer data) { + set_freedv(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))); +} +#endif + +#ifdef FREEDV +static void enable_ps_cb(GtkWidget *widget, gpointer data) { + tx_set_ps(transmitter,gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))); +} +#endif + +static void set_btn_state() { + int i; + + for(i=0;i<16;i++) { + gtk_widget_set_sensitive(btn[i], locked==0); + } +} + +static void lock_cb(GtkWidget *widget, gpointer data) { + locked=locked==1?0:1; + set_btn_state(); + vfo_update(); } static GtkWidget *last_mode; @@ -170,7 +220,11 @@ void vfo_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + char title[64]; + sprintf(title,"piHPSDR - VFO (RX %d VFO %s)",active_receiver->id,active_receiver->id==0?"A":"B"); + gtk_window_set_title(GTK_WINDOW(dialog),title); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -192,10 +246,10 @@ void vfo_menu(GtkWidget *parent) { g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); - char rx_id[32]; - sprintf(rx_id,"RX %d VFO %s",active_receiver->id,active_receiver->id==0?"A":"B"); - GtkWidget *rx_label=gtk_label_new(rx_id); - gtk_grid_attach(GTK_GRID(grid),rx_label,1,0,1,1); + GtkWidget *lock_b=gtk_check_button_new_with_label("Lock VFO"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lock_b), locked); + gtk_grid_attach(GTK_GRID(grid),lock_b,1,0,1,1); + g_signal_connect(lock_b,"toggled",G_CALLBACK(lock_cb),NULL); label = gtk_label_new (NULL); gtk_label_set_markup (GTK_LABEL (label), "0"); @@ -204,15 +258,16 @@ void vfo_menu(GtkWidget *parent) { GtkWidget *step_rb=NULL; for (i=0; i<16; i++) { - GtkWidget *b=gtk_button_new_with_label(btn_labels[i]); - set_button_text_color(b,"black"); - gtk_widget_show(b); - gtk_grid_attach(GTK_GRID(grid),b,i%3,2+(i/3),1,1); - g_signal_connect(b,"pressed",G_CALLBACK(freqent_select_cb),(gpointer *)btn_labels[i]); + btn[i]=gtk_button_new_with_label(btn_labels[i]); + set_button_text_color(btn[i],"black"); + gtk_widget_show(btn[i]); + gtk_grid_attach(GTK_GRID(grid),btn[i],i%3,2+(i/3),1,1); + g_signal_connect(btn[i],"pressed",G_CALLBACK(freqent_select_cb),(gpointer *)btn_labels[i]); } + set_btn_state(); GtkWidget *rit_label=gtk_label_new("RIT step: "); - gtk_grid_attach(GTK_GRID(grid),rit_label,3,1,1,1); + gtk_grid_attach(GTK_GRID(grid),rit_label,3,2,1,1); GtkWidget *rit_b=gtk_combo_box_text_new(); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(rit_b),NULL,"1 Hz"); @@ -230,7 +285,7 @@ void vfo_menu(GtkWidget *parent) { break; } g_signal_connect(rit_b,"changed",G_CALLBACK(rit_cb),NULL); - gtk_grid_attach(GTK_GRID(grid),rit_b,3,2,1,1); + gtk_grid_attach(GTK_GRID(grid),rit_b,4,2,1,1); GtkWidget *vfo_label=gtk_label_new("VFO step: "); gtk_grid_attach(GTK_GRID(grid),vfo_label,3,3,1,1); @@ -245,7 +300,27 @@ void vfo_menu(GtkWidget *parent) { i++; } g_signal_connect(vfo_b,"changed",G_CALLBACK(vfo_cb),NULL); - gtk_grid_attach(GTK_GRID(grid),vfo_b,3,4,1,1); + gtk_grid_attach(GTK_GRID(grid),vfo_b,4,3,1,1); + + + GtkWidget *enable_squelch=gtk_check_button_new_with_label("Enable Squelch"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (enable_squelch), active_receiver->squelch_enable); + gtk_grid_attach(GTK_GRID(grid),enable_squelch,3,5,1,1); + g_signal_connect(enable_squelch,"toggled",G_CALLBACK(squelch_enable_cb),NULL); + +#ifdef FREEDV + GtkWidget *enable_freedv=gtk_check_button_new_with_label("Enable FreeDV"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (enable_freedv), active_receiver->freedv); + gtk_grid_attach(GTK_GRID(grid),enable_freedv,3,6,1,1); + g_signal_connect(enable_freedv,"toggled",G_CALLBACK(enable_freedv_cb),NULL); +#endif + +#ifdef PURESIGNAL + GtkWidget *enable_ps=gtk_check_button_new_with_label("Enable Pure Signal"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (enable_ps), transmitter->puresignal); + gtk_grid_attach(GTK_GRID(grid),enable_ps,3,7,1,1); + g_signal_connect(enable_ps,"toggled",G_CALLBACK(enable_ps_cb),NULL); +#endif gtk_container_add(GTK_CONTAINER(content),grid); diff --git a/vox.c b/vox.c index 7b99e55..5b9cbb2 100644 --- a/vox.c +++ b/vox.c @@ -23,6 +23,7 @@ #include "transmitter.h" #include "vox.h" #include "vfo.h" +#include "ext.h" static guint vox_timeout; @@ -30,8 +31,8 @@ static double peak=0.0; static int vox_timeout_cb(gpointer data) { //setVox(0); - g_idle_add(vox_changed,(gpointer)0); - g_idle_add(vfo_update,NULL); + g_idle_add(ext_vox_changed,(gpointer)0); + g_idle_add(ext_vfo_update,NULL); return FALSE; } @@ -42,7 +43,8 @@ double vox_get_peak() { } void update_vox(TRANSMITTER *tx) { - // assumes in is interleaved left and right channel with length samples + // calculate peak microphone input + // assumes it is interleaved left and right channel with length samples int previous_vox=vox; int i; double sample; @@ -57,19 +59,17 @@ void update_vox(TRANSMITTER *tx) { } } - if(vox_enabled) { if(peak>vox_threshold) { if(previous_vox) { g_source_remove(vox_timeout); } else { - //setVox(1); - g_idle_add(vox_changed,(gpointer)1); + g_idle_add(ext_vox_changed,(gpointer)1); } vox_timeout=g_timeout_add((int)vox_hang,vox_timeout_cb,NULL); } if(vox!=previous_vox) { - g_idle_add(vfo_update,NULL); + g_idle_add(ext_vfo_update,NULL); } } } @@ -78,7 +78,7 @@ void vox_cancel() { if(vox) { g_source_remove(vox_timeout); //setVox(0); - g_idle_add(vox_changed,(gpointer)0); - g_idle_add(vfo_update,NULL); + g_idle_add(ext_vox_changed,(gpointer)0); + g_idle_add(ext_vfo_update,NULL); } } diff --git a/vox_menu.c b/vox_menu.c index 8b710f7..460ac43 100644 --- a/vox_menu.c +++ b/vox_menu.c @@ -20,13 +20,14 @@ #include #include #include +#include #include -#include #include "led.h" #include "new_menu.h" #include "radio.h" #include "transmitter.h" +#include "vfo.h" #include "vox_menu.h" #include "vox.h" @@ -37,6 +38,7 @@ static GtkWidget *dialog=NULL; static GtkWidget *level; static GtkWidget *led; +static GdkRGBA led_color={0.0,0.0,0.0,1.0}; static GdkRGBA white={1.0,1.0,1.0,1.0}; static GdkRGBA red={1.0,0.0,0.0,1.0}; @@ -60,7 +62,10 @@ static int level_update(void *data) { if(peak>vox_threshold) { // red indicator - led_set_color(1.0,0.0,0.0); // red + led_color.red=1.0; + led_color.green=0.0; + led_color.blue=0.0; + led_set_color(led); // red if(hold==0) { hold=1; } else { @@ -70,14 +75,17 @@ static int level_update(void *data) { } else { // green indicator if(hold==0) { - led_set_color(0.0,1.0,0.0); // green + led_color.red=0.0; + led_color.green=1.0; + led_color.blue=0.0; + led_set_color(led); // green } } } return 0; } -static void *level_thread(void* arg) { +static gpointer level_thread(gpointer arg) { while(run_level) { peak=vox_get_peak(); g_idle_add(level_update,NULL); @@ -85,19 +93,28 @@ static void *level_thread(void* arg) { } } -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void cleanup() { if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + static gboolean enable_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { vox_enabled=vox_enabled==1?0:1; gtk_button_set_label(GTK_BUTTON(widget),vox_enabled==0?"VOX Enable":"VOX Disable"); - vfo_update(NULL); + vfo_update(); return TRUE; } @@ -136,7 +153,9 @@ void vox_menu(GtkWidget *parent) { dialog=gtk_dialog_new(); g_signal_connect (dialog, "destroy", G_CALLBACK(destroy_cb), NULL); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - VOX"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); gtk_widget_override_background_color(dialog,GTK_STATE_FLAG_NORMAL,&white); @@ -148,11 +167,11 @@ void vox_menu(GtkWidget *parent) { //gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); - GtkWidget *close_b=gtk_button_new_with_label("Close VOX"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); - led=create_led(10,10); + led=create_led(10,10,&led_color); gtk_grid_attach(GTK_GRID(grid),led,2,0,1,1); GtkWidget *enable_b=gtk_button_new_with_label(vox_enabled==0?"VOX Enable":"VOX Disable"); diff --git a/waterfall.c b/waterfall.c index 3af56d4..4f75027 100644 --- a/waterfall.c +++ b/waterfall.c @@ -49,14 +49,6 @@ 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; -*/ - static int display_width; static int display_height; @@ -90,7 +82,7 @@ waterfall_draw_cb (GtkWidget *widget, RECEIVER *rx=(RECEIVER *)data; gdk_cairo_set_source_pixbuf (cr, rx->pixbuf, 0, 0); cairo_paint (cr); - return TRUE; + return FALSE; } static gboolean @@ -137,6 +129,42 @@ void waterfall_update(RECEIVER *rx) { int rowstride=gdk_pixbuf_get_rowstride(rx->pixbuf); int channels=gdk_pixbuf_get_n_channels(rx->pixbuf); + hz_per_pixel=(double)rx->sample_rate/(double)display_width; + + if(rx->waterfall_frequency!=0 && (rx->sample_rate==rx->waterfall_sample_rate)) { + if(rx->waterfall_frequency!=vfo[rx->id].frequency) { + // scrolled or band change + long long half=(long long)(rx->sample_rate/2); + if(rx->waterfall_frequency<(vfo[rx->id].frequency-half) || rx->waterfall_frequency>(vfo[rx->id].frequency+half)) { + // outside of the range - blank waterfall +//fprintf(stderr,"waterfall_update: clear waterfall from %lld to %lld\n",rx->waterfall_frequency,vfo[rx->id].frequency); + memset(pixels, 0, display_width*display_height*3); + } else { + // rotate waterfall + int rotate_pixels=(int)((double)(rx->waterfall_frequency-vfo[rx->id].frequency)/hz_per_pixel); +//fprintf(stderr,"waterfall_update: rotate waterfall from %lld to %lld pixels=%d\n",rx->waterfall_frequency,vfo[rx->id].frequency,rotate_pixels); + if(rotate_pixels<0) { + memmove(pixels,&pixels[-rotate_pixels*3],((display_width*display_height)+rotate_pixels)*3); + //now clear the right hand side + for(i=0;iwaterfall_frequency=vfo[rx->id].frequency; + rx->waterfall_sample_rate=rx->sample_rate; + memmove(&pixels[rowstride],pixels,(height-1)*rowstride); float sample; @@ -214,11 +242,8 @@ void waterfall_init(RECEIVER *rx,int width,int height) { display_height=height; rx->pixbuf=NULL; - rx->waterfall_low=waterfall_low; - rx->waterfall_high=waterfall_high; - rx->waterfall_automatic=waterfall_automatic; - - hz_per_pixel=(double)rx->sample_rate/(double)display_width; + rx->waterfall_frequency=0; + rx->waterfall_sample_rate=0; //waterfall_frame = gtk_frame_new (NULL); rx->waterfall = gtk_drawing_area_new (); diff --git a/xvtr_menu.c b/xvtr_menu.c index 2736864..962d583 100644 --- a/xvtr_menu.c +++ b/xvtr_menu.c @@ -29,6 +29,7 @@ #include "mode.h" #include "xvtr_menu.h" #include "radio.h" +#include "vfo.h" static GtkWidget *parent_window=NULL; static GtkWidget *menu_b=NULL; @@ -37,47 +38,71 @@ static GtkWidget *title[BANDS+XVTRS]; static GtkWidget *min_frequency[BANDS+XVTRS]; static GtkWidget *max_frequency[BANDS+XVTRS]; static GtkWidget *lo_frequency[BANDS+XVTRS]; +static GtkWidget *lo_error[BANDS+XVTRS]; static GtkWidget *disable_pa[BANDS+XVTRS]; -static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { +static void save_xvtr () { int i; + int b; if(dialog!=NULL) { const char *t; const char *minf; const char *maxf; const char *lof; + const char *loerr; for(i=BANDS;ibandstack; - BANDSTACK_ENTRY *entry=bandstack->entry; t=gtk_entry_get_text(GTK_ENTRY(title[i])); strcpy(xvtr->title,t); if(strlen(t)!=0) { minf=gtk_entry_get_text(GTK_ENTRY(min_frequency[i])); - xvtr->frequencyMin=atoll(minf); + xvtr->frequencyMin=atoll(minf)*1000000; maxf=gtk_entry_get_text(GTK_ENTRY(max_frequency[i])); - xvtr->frequencyMax=atoll(maxf); + xvtr->frequencyMax=atoll(maxf)*1000000; lof=gtk_entry_get_text(GTK_ENTRY(lo_frequency[i])); - xvtr->frequencyLO=atoll(lof); + xvtr->frequencyLO=atoll(lof)*1000000; + loerr=gtk_entry_get_text(GTK_ENTRY(lo_error[i])); + xvtr->errorLO=atoll(loerr); xvtr->disablePA=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(disable_pa[i])); - entry->frequency=xvtr->frequencyMin; - entry->mode=modeUSB; - entry->filter=filterF6; + for(b=0;bentries;b++) { + BANDSTACK_ENTRY *entry=&bandstack->entry[b]; + entry->frequency=xvtr->frequencyMin; + entry->mode=modeUSB; + entry->filter=filterF6; + } fprintf(stderr,"min=%s:%lld max=%s:%lld lo=%s:%lld\n",minf,xvtr->frequencyMin,maxf,xvtr->frequencyMax,lof,xvtr->frequencyLO); } else { xvtr->frequencyMin=0; xvtr->frequencyMax=0; xvtr->frequencyLO=0; + xvtr->errorLO=0; xvtr->disablePA=0; } } + vfo_xvtr_changed(); + } +} + +static void cleanup() { + save_xvtr(); + if(dialog!=NULL) { gtk_widget_destroy(dialog); dialog=NULL; sub_menu=NULL; } +} + +static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) { + cleanup(); return TRUE; } +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + cleanup(); + return FALSE; +} + void xvtr_menu(GtkWidget *parent) { int i,j; char f[16]; @@ -87,7 +112,9 @@ fprintf(stderr,"xvtr_menu\n"); dialog=gtk_dialog_new(); gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window)); - gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE); + gtk_window_set_title(GTK_WINDOW(dialog),"piHPSDR - XVTR"); + g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL); GdkRGBA color; color.red = 1.0; @@ -100,55 +127,63 @@ fprintf(stderr,"xvtr_menu\n"); GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog)); GtkWidget *grid=gtk_grid_new(); - //gtk_grid_set_column_spacing (GTK_GRID(grid),10); - //gtk_grid_set_row_spacing (GTK_GRID(grid),10); - //gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE); - //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE); + gtk_grid_set_column_spacing (GTK_GRID(grid),10); + gtk_grid_set_row_homogeneous(GTK_GRID(grid),FALSE); + gtk_grid_set_column_homogeneous(GTK_GRID(grid),FALSE); - GtkWidget *close_b=gtk_button_new_with_label("Close XVTR"); + GtkWidget *close_b=gtk_button_new_with_label("Close"); g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL); gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1); GtkWidget *label=gtk_label_new("Title"); gtk_grid_attach(GTK_GRID(grid),label,0,1,1,1); - label=gtk_label_new("Min Freq (Hz)"); + label=gtk_label_new("Min Frequency(MHz)"); gtk_grid_attach(GTK_GRID(grid),label,1,1,1,1); - label=gtk_label_new("Max Freq (Hz)"); + label=gtk_label_new("Max Frequency(MHz)"); gtk_grid_attach(GTK_GRID(grid),label,2,1,1,1); - label=gtk_label_new("LO Freq (Hz)"); + label=gtk_label_new("LO Frequency(MHz)"); gtk_grid_attach(GTK_GRID(grid),label,3,1,1,1); - label=gtk_label_new("Disable PA"); + label=gtk_label_new("LO Error(Hz)"); gtk_grid_attach(GTK_GRID(grid),label,4,1,1,1); - + label=gtk_label_new("Disable PA"); + gtk_grid_attach(GTK_GRID(grid),label,5,1,1,1); for(i=BANDS;ititle); title[i]=gtk_entry_new(); + gtk_entry_set_width_chars(GTK_ENTRY(title[i]),7); gtk_entry_set_text(GTK_ENTRY(title[i]),xvtr->title); gtk_grid_attach(GTK_GRID(grid),title[i],0,i+2,1,1); min_frequency[i]=gtk_entry_new(); - sprintf(f,"%lld",xvtr->frequencyMin); + gtk_entry_set_width_chars(GTK_ENTRY(min_frequency[i]),7); + sprintf(f,"%lld",xvtr->frequencyMin/1000000LL); gtk_entry_set_text(GTK_ENTRY(min_frequency[i]),f); gtk_grid_attach(GTK_GRID(grid),min_frequency[i],1,i+2,1,1); max_frequency[i]=gtk_entry_new(); - sprintf(f,"%lld",xvtr->frequencyMax); + gtk_entry_set_width_chars(GTK_ENTRY(max_frequency[i]),7); + sprintf(f,"%lld",xvtr->frequencyMax/1000000LL); gtk_entry_set_text(GTK_ENTRY(max_frequency[i]),f); gtk_grid_attach(GTK_GRID(grid),max_frequency[i],2,i+2,1,1); lo_frequency[i]=gtk_entry_new(); - sprintf(f,"%lld",xvtr->frequencyLO); + gtk_entry_set_width_chars(GTK_ENTRY(lo_frequency[i]),7); + sprintf(f,"%lld",xvtr->frequencyLO/1000000LL); gtk_entry_set_text(GTK_ENTRY(lo_frequency[i]),f); gtk_grid_attach(GTK_GRID(grid),lo_frequency[i],3,i+2,1,1); + lo_error[i]=gtk_entry_new(); + gtk_entry_set_width_chars(GTK_ENTRY(lo_error[i]),9); + sprintf(f,"%lld",xvtr->errorLO); + gtk_entry_set_text(GTK_ENTRY(lo_error[i]),f); + gtk_grid_attach(GTK_GRID(grid),lo_error[i],4,i+2,1,1); + disable_pa[i]=gtk_check_button_new(); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(disable_pa[i]),xvtr->disablePA); - gtk_grid_attach(GTK_GRID(grid),disable_pa[i],4,i+2,1,1); + gtk_grid_attach(GTK_GRID(grid),disable_pa[i],5,i+2,1,1); } -- 2.45.2