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