GIT_DATE := $(firstword $(shell git --no-pager show --date=short --format="%ai" --name-only))
GIT_VERSION := $(shell git describe --abbrev=0 --tags)
+# uncomment the line below to include GPIO
+GPIO_INCLUDE=GPIO
+
+# uncomment the line below to include USB Ozy support
+USBOZY_INCLUDE=USBOZY
+
# uncomment the line below to include support for psk31
-PSK_INCLUDE=PSK
+#PSK_INCLUDE=PSK
# uncomment the line to below include support for FreeDV codec2
-FREEDV_INCLUDE=FREEDV
+#FREEDV_INCLUDE=FREEDV
# uncomment the line to below include support for sx1509 i2c expander
#SX1509_INCLUDE=sx1509
# uncomment the line to below include support local CW keyer
#LOCALCW_INCLUDE=LOCALCW
+# uncomment the line below to include MCP23017 I2C
+#I2C_INCLUDE=I2C
+
#uncomment the line below for the platform being compiled on
-UNAME_N=raspberrypi
+#UNAME_N=raspberrypi
#UNAME_N=odroid
#UNAME_N=up
#UNAME_N=pine64
-#UNAME_N=x86
+UNAME_N=x86
CC=gcc
LINK=gcc
# uncomment the line below for various debug facilities
#DEBUG_OPTION=-D DEBUG
+ifeq ($(USBOZY_INCLUDE),USBOZY)
+USBOZY_OPTIONS=-D USBOZY
+USBOZY_LIBS=-lusb-1.0
+USBOZY_SOURCES= \
+ozyio.c
+USBOZY_HEADERS= \
+ozyio.h
+USBOZY_OBJS= \
+ozyio.o
+endif
+
# uncomment the line below for LimeSDR (uncomment line below)
#LIMESDR_INCLUDE=LIMESDR
iambic.o
endif
-#required for MRAA GPIO
-#MRAA_INCLUDE=MRAA
-
-ifeq ($(MRAA_INCLUDE),MRAA)
- GPIO_OPTIONS=-D GPIO
- GPIO_LIBS=-lmraa
- GPIO_SOURCES= \
- gpio_mraa.c
- GPIO_HEADERS= \
- gpio.h
- GPIO_OBJS= \
- gpio_mraa.o
-else
- ifeq ($(UNAME_N),raspberrypi)
+ifeq ($(GPIO_INCLUDE),GPIO)
GPIO_OPTIONS=-D GPIO
GPIO_LIBS=-lwiringPi -lpigpio
- endif
- ifeq ($(UNAME_N),odroid)
- GPIO_LIBS=-lwiringPi
- endif
- ifeq ($(SX1509_INCLUDE),sx1509)
- GPIO_OPTIONS=-D GPIO
- GPIO_OPTIONS+=-D sx1509
- GPIO_LIBS+=-lsx1509
- endif
GPIO_SOURCES= \
- gpio.c
+ gpio.c \
+ encoder_menu.c
GPIO_HEADERS= \
- gpio.h
+ gpio.h \
+ encoder_menu.h
GPIO_OBJS= \
- gpio.o
+ gpio.o \
+ encoder_menu.o
+endif
+
+ifeq ($(I2C_INCLUDE),I2C)
+ I2C_OPTIONS=-D I2C
+ I2C_SOURCES=i2c.c
+ I2C_HEADERS=i2c.h
+ I2C_OBJS=i2c.o
endif
#uncomment if build for SHORT FRAMES (MIC and Audio)
-SHORT_FRAMES="-D SHORT_FRAMES"
+SHORT_FRAMES=-D SHORT_FRAMES
GTKINCLUDES=`pkg-config --cflags gtk+-3.0`
GTKLIBS=`pkg-config --libs gtk+-3.0`
AUDIO_LIBS=-lasound
+#AUDIO_LIBS=-lsoundio
-OPTIONS=-g -D $(UNAME_N) $(GPIO_OPTIONS) $(LIMESDR_OPTIONS) $(FREEDV_OPTIONS) $(LOCALCW_OPTIONS) $(PSK_OPTIONS) $(SHORT_FRAMES) -D GIT_DATE='"$(GIT_DATE)"' -D GIT_VERSION='"$(GIT_VERSION)"' $(DEBUG_OPTION) -O3
+OPTIONS=-g -Wno-deprecated-declarations -D $(UNAME_N) $(USBOZY_OPTIONS) $(I2C_OPTIONS) $(GPIO_OPTIONS) $(LIMESDR_OPTIONS) $(FREEDV_OPTIONS) $(LOCALCW_OPTIONS) $(PSK_OPTIONS) $(SHORT_FRAMES) -D GIT_DATE='"$(GIT_DATE)"' -D GIT_VERSION='"$(GIT_VERSION)"' $(DEBUG_OPTION) -O3
-LIBS=-lrt -lm -lwdsp -lpthread $(AUDIO_LIBS) $(PSKLIBS) $(GTKLIBS) $(GPIO_LIBS) $(SOAPYSDRLIBS) $(FREEDVLIBS)
+LIBS=-lrt -lm -lwdsp -lpthread $(AUDIO_LIBS) $(USBOZY_LIBS) $(PSKLIBS) $(GTKLIBS) $(GPIO_LIBS) $(SOAPYSDRLIBS) $(FREEDVLIBS)
INCLUDES=$(GTKINCLUDES)
COMPILE=$(CC) $(OPTIONS) $(INCLUDES)
configure.c \
frequency.c \
discovered.c \
+discovery.c \
filter.c \
main.c \
new_menu.c \
exit_menu.c \
-general_menu.c \
-audio_menu.c \
+radio_menu.c \
+rx_menu.c \
ant_menu.c \
display_menu.c \
dsp_menu.c \
filter_menu.c \
noise_menu.c \
agc_menu.c \
-fm_menu.c \
vox_menu.c \
diversity_menu.c \
freqent_menu.c \
+tx_menu.c \
+vfo_menu.c \
test_menu.c \
-rit.c \
meter.c \
mode.c \
old_discovery.c \
old_protocol.c \
new_protocol.c \
new_protocol_programmer.c \
-panadapter.c \
+rx_panadapter.c \
+tx_panadapter.c \
property.c \
radio.c \
+receiver.c \
rigctl.c \
-signal.c \
-splash.c \
toolbar.c \
+transmitter.c \
sliders.c \
version.c \
vfo.c \
waterfall.c \
-wdsp_init.c \
button_text.c \
vox.c \
update.c \
+store.c \
+store_menu.c \
memory.c
bandstack.h \
channel.h \
discovered.h \
+discovery.h \
filter.h \
new_menu.h \
+rx_menu.h \
exit_menu.h \
-general_menu.h \
-audio_menu.h \
+radio_menu.h \
ant_menu.h \
display_menu.h \
dsp_menu.h \
filter_menu.h \
noise_menu.h \
agc_menu.h \
-fm_menu.h \
vox_menu.h \
diversity_menu.h \
freqent_menu.h \
+tx_menu.h \
+vfo_menu.h \
test_menu.h \
-rit.h \
meter.h \
mode.h \
old_discovery.h \
new_discovery.h \
old_protocol.h \
new_protocol.h \
-panadapter.h \
+rx_panadapter.h \
+tx_panadapter.h \
property.h \
radio.h \
+receiver.h \
rigctl.h \
-signal.h \
-splash.h \
toolbar.h \
+transmitter.h \
sliders.h \
version.h \
vfo.h \
waterfall.h \
-wdsp_init.h \
button_text.h \
vox.h \
update.h \
+store.h \
+store_menu.h \
memory.h
configure.o \
frequency.o \
discovered.o \
+discovery.o \
filter.o \
version.o \
main.o \
new_menu.o \
+rx_menu.o \
exit_menu.o \
-general_menu.o \
-audio_menu.o \
+radio_menu.o \
ant_menu.o \
display_menu.o \
dsp_menu.o \
filter_menu.o \
noise_menu.o \
agc_menu.o \
-fm_menu.o \
vox_menu.o \
diversity_menu.o \
freqent_menu.o \
+tx_menu.o \
+vfo_menu.o \
test_menu.o \
-rit.o \
meter.o \
mode.o \
old_discovery.o \
old_protocol.o \
new_protocol.o \
new_protocol_programmer.o \
-panadapter.o \
+rx_panadapter.o \
+tx_panadapter.o \
property.o \
radio.o \
+receiver.o \
rigctl.o \
-signal.o \
-splash.o \
toolbar.o \
+transmitter.o \
sliders.o \
vfo.o \
waterfall.o \
-wdsp_init.o \
button_text.o \
vox.o \
update.o \
+store.o \
+store_menu.o \
memory.o
-all: prebuild $(PROGRAM) $(HEADERS) $(LIMESDR_HEADERS) $(FREEDV_HEADERS) $(LOCALCW_HEADERS) $(GPIO_HEADERS) $(PSK_HEADERS) $(SOURCES) $(LIMESDR_SOURCES) $(FREEDV_SOURCES) $(GPIO_SOURCES) $(PSK_SOURCES)
+all: prebuild $(PROGRAM) $(HEADERS) $(USBOZY_HEADERS) $(LIMESDR_HEADERS) $(FREEDV_HEADERS) $(LOCALCW_HEADERS) $(I2C_HEADERS) $(GPIO_HEADERS) $(PSK_HEADERS) $(SOURCES) $(USBOZY_SOURCES) $(LIMESDR_SOURCES) $(FREEDV_SOURCES) $(I2C_SOURCES) $(GPIO_SOURCES) $(PSK_SOURCES)
prebuild:
rm -f version.o
-$(PROGRAM): $(OBJS) $(LIMESDR_OBJS) $(FREEDV_OBJS) $(LOCALCW_OBJS) $(GPIO_OBJS) $(PSK_OBJS)
- $(LINK) -o $(PROGRAM) $(OBJS) $(GPIO_OBJS) $(LIMESDR_OBJS) $(FREEDV_OBJS) $(LOCALCW_OBJS) $(PSK_OBJS) $(LIBS)
+$(PROGRAM): $(OBJS) $(USBOZY_OBJS) $(LIMESDR_OBJS) $(FREEDV_OBJS) $(LOCALCW_OBJS) $(I2C_OBJS) $(GPIO_OBJS) $(PSK_OBJS)
+ $(LINK) -o $(PROGRAM) $(OBJS) $(USBOZY_OBJS) $(I2C_OBJS) $(GPIO_OBJS) $(LIMESDR_OBJS) $(FREEDV_OBJS) $(LOCALCW_OBJS) $(PSK_OBJS) $(LIBS)
.c.o:
$(COMPILE) -c -o $@ $<
#include "band.h"
#include "channel.h"
#include "radio.h"
+#include "receiver.h"
#include "vfo.h"
#include "button_text.h"
}
static gboolean agc_select_cb (GtkWidget *widget, gpointer data) {
- agc=(int)data;
- wdsp_set_agc(CHANNEL_RX0, agc);
+ active_receiver->agc=(int)data;
+ //wdsp_set_agc(CHANNEL_RX0, agc);
+ set_agc(active_receiver, active_receiver->agc);
vfo_update(NULL);
}
g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL);
gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1);
+ char label[32];
+ sprintf(label,"RX %d VFO %s",active_receiver->id,active_receiver->id==0?"A":"B");
+ GtkWidget *rx_label=gtk_label_new(label);
+ gtk_grid_attach(GTK_GRID(grid),rx_label,1,0,1,1);
+
GtkWidget *b_off=gtk_radio_button_new_with_label(NULL,"Off");
//gtk_widget_override_font(b_off, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_off), agc==AGC_OFF);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_off), active_receiver->agc==AGC_OFF);
gtk_widget_show(b_off);
gtk_grid_attach(GTK_GRID(grid),b_off,0,1,2,1);
g_signal_connect(b_off,"pressed",G_CALLBACK(agc_select_cb),(gpointer *)AGC_OFF);
GtkWidget *b_long=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_off),"Long");
//gtk_widget_override_font(b_long, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_long), agc==AGC_LONG);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_long), active_receiver->agc==AGC_LONG);
gtk_widget_show(b_long);
gtk_grid_attach(GTK_GRID(grid),b_long,0,2,2,1);
g_signal_connect(b_long,"pressed",G_CALLBACK(agc_select_cb),(gpointer *)AGC_LONG);
GtkWidget *b_slow=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_long),"Slow");
//gtk_widget_override_font(b_slow, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_slow), agc==AGC_SLOW);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_slow), active_receiver->agc==AGC_SLOW);
gtk_widget_show(b_slow);
gtk_grid_attach(GTK_GRID(grid),b_slow,0,3,2,1);
g_signal_connect(b_slow,"pressed",G_CALLBACK(agc_select_cb),(gpointer *)AGC_SLOW);
GtkWidget *b_medium=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_slow),"Medium");
//gtk_widget_override_font(b_medium, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_medium), agc==AGC_MEDIUM);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_medium), active_receiver->agc==AGC_MEDIUM);
gtk_widget_show(b_medium);
gtk_grid_attach(GTK_GRID(grid),b_medium,0,4,2,1);
g_signal_connect(b_medium,"pressed",G_CALLBACK(agc_select_cb),(gpointer *)AGC_MEDIUM);
GtkWidget *b_fast=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_medium),"Fast");
//gtk_widget_override_font(b_fast, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_fast), agc==AGC_FAST);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_fast), active_receiver->agc==AGC_FAST);
gtk_widget_show(b_fast);
gtk_grid_attach(GTK_GRID(grid),b_fast,0,5,2,1);
g_signal_connect(b_fast,"pressed",G_CALLBACK(agc_select_cb),(gpointer *)AGC_FAST);
int ant=((int)data)&0xF;
BAND *band=band_get_band(b);
band->alexRxAntenna=ant;
- set_alex_rx_antenna(ant);
+ if(active_receiver->id==0) {
+ 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);
+ if(active_receiver->id==0) {
+ set_alex_rx_antenna(ant);
+ }
}
static void tx_ant_cb(GtkWidget *widget, gpointer data) {
int ant=((int)data)&0xF;
BAND *band=band_get_band(b);
band->alexTxAntenna=ant;
- set_alex_tx_antenna(ant);
+ if(active_receiver->id==0) {
+ set_alex_tx_antenna(ant);
+ }
}
void ant_menu(GtkWidget *parent) {
#include <alsa/asoundlib.h>
-#include "audio.h"
#include "new_protocol.h"
#include "old_protocol.h"
#include "radio.h"
+#include "receiver.h"
+#include "audio.h"
int audio = 0;
int audio_buffer_size = 256; // samples (both left and right)
int mic_buffer_size = 720; // samples (both left and right)
-static snd_pcm_t *playback_handle=NULL;
+//static snd_pcm_t *playback_handle=NULL;
static snd_pcm_t *record_handle=NULL;
// each buffer contains 63 samples of left and right audio at 16 bits
#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)
+#define OUTPUT_BUFFER_SIZE (AUDIO_SAMPLE_SIZE*AUDIO_CHANNELS*audio_buffer_size)
#define MIC_BUFFER_SIZE (AUDIO_SAMPLE_SIZE*AUDIO_CHANNELS*mic_buffer_size)
-static unsigned char *audio_buffer=NULL;
-static int audio_offset=0;
+//static unsigned char *audio_buffer=NULL;
+//static int audio_offset=0;
static unsigned char *mic_buffer=NULL;
-static pthread_t mic_read_thread_id;
+static GThread *mic_read_thread_id;
static int running=FALSE;
char *input_devices[16];
int n_input_devices=0;
-int n_selected_input_device=-1;
+//int n_selected_input_device=-1;
char *output_devices[16];
int n_output_devices=0;
-int n_selected_output_device=-1;
+//int n_selected_output_device=-1;
-int audio_open_output() {
+int audio_open_output(RECEIVER *rx) {
int err;
snd_pcm_hw_params_t *hw_params;
int rate=48000;
int dir=0;
- if(n_selected_output_device<0 || n_selected_output_device>=n_output_devices) {
- n_selected_output_device=-1;
+ if(rx->audio_device<0 || rx->audio_device>=n_output_devices) {
+ rx->audio_device=-1;
return -1;
}
int i;
- char hw[16];
- char *selected=output_devices[n_selected_output_device];
+ char hw[64];
+ char *selected=output_devices[rx->audio_device];
-fprintf(stderr,"audio_open_output: selected=%d:%s\n",n_selected_output_device,selected);
+fprintf(stderr,"audio_open_output: selected=%d:%s\n",rx->audio_device,selected);
i=0;
while(selected[i]!=' ') {
}
hw[i]='\0';
- if ((err = snd_pcm_open (&playback_handle, hw, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
+ if ((err = snd_pcm_open (&rx->playback_handle, hw, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
fprintf (stderr, "audio_open_output: cannot open audio device %s (%s)\n",
hw,
snd_strerror (err));
return -1;
}
- if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) {
+ if ((err = snd_pcm_hw_params_any (rx->playback_handle, hw_params)) < 0) {
fprintf (stderr, "audio_open_output: cannot initialize hardware parameter structure (%s)\n",
snd_strerror (err));
return -1;
}
- if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
+ if ((err = snd_pcm_hw_params_set_access (rx->playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
fprintf (stderr, "audio_open_output: cannot set access type (%s)\n",
snd_strerror (err));
return -1;
}
- if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
+ if ((err = snd_pcm_hw_params_set_format (rx->playback_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
fprintf (stderr, "audio_open_output: cannot set sample format (%s)\n",
snd_strerror (err));
return -1;
}
- if ((err = snd_pcm_hw_params_set_rate_near (playback_handle, hw_params, &rate, &dir)) < 0) {
+ if ((err = snd_pcm_hw_params_set_rate_near (rx->playback_handle, hw_params, &rate, &dir)) < 0) {
fprintf (stderr, "audio_open_output: cannot set sample rate (%s)\n",
snd_strerror (err));
return -1;
}
- if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params, 2)) < 0) {
+ if ((err = snd_pcm_hw_params_set_channels (rx->playback_handle, hw_params, 2)) < 0) {
fprintf (stderr, "audio_open_output: cannot set channel count (%s)\n",
snd_strerror (err));
return -1;
}
- if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) {
+ if ((err = snd_pcm_hw_params (rx->playback_handle, hw_params)) < 0) {
fprintf (stderr, "audio_open_output: cannot set parameters (%s)\n",
snd_strerror (err));
return -1;
snd_pcm_hw_params_free (hw_params);
- audio_offset=0;
- audio_buffer=(unsigned char *)malloc(AUDIO_BUFFER_SIZE);
+ rx->playback_offset=0;
+ rx->playback_buffer=(unsigned char *)malloc(OUTPUT_BUFFER_SIZE);
return 0;
}
int rate=48000;
int dir=0;
-fprintf(stderr,"audio_open_input: %d\n",n_selected_input_device);
- if(n_selected_input_device<0 || n_selected_input_device>=n_input_devices) {
- n_selected_input_device=-1;
+fprintf(stderr,"audio_open_input: %d\n",transmitter->input_device);
+ if(transmitter->input_device<0 || transmitter->input_device>=n_input_devices) {
+ transmitter->input_device=0;
return -1;
}
int i;
char hw[16];
- char *selected=input_devices[n_selected_input_device];
- fprintf(stderr,"audio_open_input: selected=%d:%s\n",n_selected_input_device,selected);
+ char *selected=input_devices[transmitter->input_device];
+ fprintf(stderr,"audio_open_input: selected=%d:%s\n",transmitter->input_device,selected);
switch(protocol) {
case ORIGINAL_PROTOCOL:
mic_buffer=(unsigned char *)malloc(MIC_BUFFER_SIZE);
running=TRUE;
- err=pthread_create(&mic_read_thread_id,NULL,mic_read_thread,NULL);
- if(err != 0) {
- fprintf(stderr,"pthread_create failed on mic_read_thread: rc=%d\n", err);
- return -1;
+ mic_read_thread_id = g_thread_new( "local mic", mic_read_thread, NULL);
+ if(!mic_read_thread_id )
+ {
+ fprintf(stderr,"g_thread_new failed on mic_read_thread\n");
}
+
return 0;
}
-void audio_close_output() {
- if(playback_handle!=NULL) {
- snd_pcm_close (playback_handle);
- playback_handle=NULL;
+void audio_close_output(RECEIVER *rx) {
+ if(rx->playback_handle!=NULL) {
+ snd_pcm_close (rx->playback_handle);
+ rx->playback_handle=NULL;
}
- if(audio_buffer!=NULL) {
- free(audio_buffer);
- audio_buffer=NULL;
+ if(rx->playback_buffer!=NULL) {
+ free(rx->playback_buffer);
+ rx->playback_buffer=NULL;
}
}
}
}
-int audio_write(short left_sample,short right_sample) {
+int audio_write(RECEIVER *rx,short left_sample,short right_sample) {
snd_pcm_sframes_t delay;
int error;
long trim;
- if(playback_handle!=NULL && audio_buffer!=NULL) {
- audio_buffer[audio_offset++]=left_sample;
- audio_buffer[audio_offset++]=left_sample>>8;
- audio_buffer[audio_offset++]=right_sample;
- audio_buffer[audio_offset++]=right_sample>>8;
+ if(rx->playback_handle!=NULL && rx->playback_buffer!=NULL) {
+ rx->playback_buffer[rx->playback_offset++]=right_sample;
+ rx->playback_buffer[rx->playback_offset++]=right_sample>>8;
+ rx->playback_buffer[rx->playback_offset++]=left_sample;
+ rx->playback_buffer[rx->playback_offset++]=left_sample>>8;
- if(audio_offset==AUDIO_BUFFER_SIZE) {
+ if(rx->playback_offset==OUTPUT_BUFFER_SIZE) {
trim=0;
- if(snd_pcm_delay(playback_handle,&delay)==0) {
+ if(snd_pcm_delay(rx->playback_handle,&delay)==0) {
if(delay>2048) {
trim=delay-2048;
//fprintf(stderr,"audio delay=%ld trim=%ld\n",delay,trim);
}
}
- if ((error = snd_pcm_writei (playback_handle, audio_buffer, audio_buffer_size-trim)) != audio_buffer_size-trim) {
+ if ((error = snd_pcm_writei (rx->playback_handle, rx->playback_buffer, audio_buffer_size-trim)) != audio_buffer_size-trim) {
if(error==-EPIPE) {
- if ((error = snd_pcm_prepare (playback_handle)) < 0) {
+ if ((error = snd_pcm_prepare (rx->playback_handle)) < 0) {
fprintf (stderr, "audio_write: cannot prepare audio interface for use (%s)\n",
snd_strerror (error));
return -1;
}
- if ((error = snd_pcm_writei (playback_handle, audio_buffer, audio_buffer_size)) != audio_buffer_size) {
+ if ((error = snd_pcm_writei (rx->playback_handle, rx->playback_buffer, audio_buffer_size-trim)) != audio_buffer_size) {
fprintf (stderr, "audio_write: write to audio interface failed (%s)\n",
snd_strerror (error));
return -1;
}
}
}
- audio_offset=0;
+ rx->playback_offset=0;
}
}
return 0;
}
-static void *mic_read_thread(void *arg) {
+static gpointer mic_read_thread(gpointer arg) {
int rc;
if ((rc = snd_pcm_prepare (record_handle)) < 0) {
fprintf (stderr, "mic_read_thread: cannot prepare audio interface for use (%s)\n",
}
-void audio_get_cards(int input) {
+void audio_get_cards() {
snd_ctl_card_info_t *info;
snd_pcm_info_t *pcminfo;
snd_ctl_card_info_alloca(&info);
snd_pcm_info_alloca(&pcminfo);
int i;
+ char *device_id=malloc(64);
+ int card = -1;
- if(input) {
- for(i=0;i<n_input_devices;i++) {
- free(input_devices[i]);
- }
- n_input_devices=0;
- } else {
- for(i=0;i<n_output_devices;i++) {
- free(output_devices[i]);
- }
- n_output_devices=0;
+fprintf(stderr,"audio_get_cards\n");
+
+ for(i=0;i<n_input_devices;i++) {
+ free(input_devices[i]);
}
- int card = -1;
+ n_input_devices=0;
+
+ for(i=0;i<n_output_devices;i++) {
+ free(output_devices[i]);
+ }
+ n_output_devices=0;
+
while (snd_card_next(&card) >= 0 && card >= 0) {
int err = 0;
snd_ctl_t *handle;
}
int dev = -1;
+
while (snd_ctl_pcm_next_device(handle, &dev) >= 0 && dev >= 0) {
snd_pcm_info_set_device(pcminfo, dev);
snd_pcm_info_set_subdevice(pcminfo, 0);
- snd_pcm_info_set_stream(pcminfo, input ? SND_PCM_STREAM_CAPTURE
- : SND_PCM_STREAM_PLAYBACK);
- if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
- continue;
- }
- char *device_id=malloc(64);
-
- snprintf(device_id, 64, "plughw:%d,%d %s", card, dev, snd_ctl_card_info_get_name(info));
- if(input) {
-fprintf(stderr,"input_device: %s\n",device_id);
+ // input devices
+ snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE);
+ if ((err = snd_ctl_pcm_info(handle, pcminfo)) == 0) {
+ snprintf(device_id, 64, "plughw:%d,%d %s", card, dev, snd_ctl_card_info_get_name(info));
input_devices[n_input_devices++]=device_id;
- } else {
+fprintf(stderr,"input_device: %s\n",device_id);
+ }
+
+ // ouput devices
+ snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK);
+ if ((err = snd_ctl_pcm_info(handle, pcminfo)) == 0) {
+ snprintf(device_id, 64, "plughw:%d,%d %s", card, dev, snd_ctl_card_info_get_name(info));
output_devices[n_output_devices++]=device_id;
fprintf(stderr,"output_device: %s\n",device_id);
}
-
}
snd_ctl_close(handle);
+
+ }
+
+ // look for dmix
+ void **hints, **n;
+ char *name, *descr, *io;
+
+ if (snd_device_name_hint(-1, "pcm", &hints) < 0)
+ return;
+ n = hints;
+ while (*n != NULL) {
+ name = snd_device_name_get_hint(*n, "NAME");
+ descr = snd_device_name_get_hint(*n, "DESC");
+ io = snd_device_name_get_hint(*n, "IOID");
+
+ if(strncmp("dmix:", name, 5)==0/* || strncmp("pulse", name, 5)==0*/) {
+ fprintf(stderr,"name=%s descr=%s io=%s\n",name, descr, io);
+ char *device_id=malloc(64);
+
+ snprintf(device_id, 64, "%s", name);
+ output_devices[n_output_devices++]=device_id;
+fprintf(stderr,"output_device: %s\n",device_id);
+ }
+ if (name != NULL)
+ free(name);
+ if (descr != NULL)
+ free(descr);
+ if (io != NULL)
+ free(io);
+ n++;
}
+ snd_device_name_free_hint(hints);
}
#ifndef _AUDIO_H
#define _AUDIO_H
+#include "receiver.h"
+
extern char *input_devices[];
extern int n_input_devices;
-extern int n_selected_input_device;
+//extern int n_selected_input_device;
extern char *output_devices[];
extern int n_output_devices;
-extern int n_selected_output_device;
+//extern int n_selected_output_device;
-extern int audio_open_output();
extern int audio_open_input();
-extern void audio_close_output();
extern void audio_close_input();
-extern int audio_write(short left_sample,short right_sample);
+extern int audio_open_output(RECEIVER *rx);
+extern void audio_close_output(RECEIVER *rx);
+extern int audio_write(RECEIVER *rx,short left_sample,short right_sample);
extern void audio_get_cards();
#endif
static void binaural_cb(GtkWidget *widget, gpointer data) {
binaural=gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
- SetRXAPanelBinaural(CHANNEL_RX0, binaural);
+ SetRXAPanelBinaural(active_receiver->id, binaural);
}
static void micboost_cb(GtkWidget *widget, gpointer data) {
static void linein_cb(GtkWidget *widget, gpointer data) {
mic_linein=mic_linein==1?0:1;
- linein_changed();
+ g_idle_add(linein_changed,NULL);
}
static void local_audio_cb(GtkWidget *widget, gpointer data) {
*/
/* ----------------------------------------------------------------------------*/
BANDSTACK_ENTRY bandstack_entries136[] =
- {{135800,135800,modeCWL,filterF4,-2800,-200,-2800,-200},
- {137100,137100,modeCWL,filterF4,-2800,-200,-2800,-200}};
+ {{135800,modeCWL,filterF6,-2800,-200,-2800,-200},
+ {137100,modeCWL,filterF6,-2800,-200,-2800,-200}};
BANDSTACK_ENTRY bandstack_entries472[] =
- {{472100LL,472100LL,modeCWL,filterF4,-2800,-200,-2800,-200},
- {475100LL,475100LL,modeCWL,filterF4,-2800,-200,-2800,-200}};
+ {{472100LL,modeCWL,filterF6,-2800,-200,-2800,-200},
+ {475100LL,modeCWL,filterF6,-2800,-200,-2800,-200}};
BANDSTACK_ENTRY bandstack_entries160[] =
- {{1810000LL,1810000LL,modeCWL,filterF4,-2800,-200,-2800,-200},
- {1835000LL,1835000LL,modeCWU,filterF0,-2800,-200,-2800,-200},
- {1845000LL,1845000LL,modeUSB,filterF5,-2800,-200,-2800,-200}};
+ {{1810000LL,modeCWL,filterF6,-2800,-200,-2800,-200},
+ {1835000LL,modeCWU,filterF6,-2800,-200,-2800,-200},
+ {1845000LL,modeUSB,filterF5,-2800,-200,-2800,-200}};
BANDSTACK_ENTRY bandstack_entries80[] =
- {{3501000LL,3501000LL,modeCWL,filterF0,-2800,-200,-2800,-200},
- {3751000LL,3751000LL,modeLSB,filterF5,-2800,-200,-2800,-200},
- {3850000LL,3850000LL,modeLSB,filterF5,-2800,-200,-2800,-200}};
+ {{3501000LL,modeCWL,filterF6,-2800,-200,-2800,-200},
+ {3751000LL,modeLSB,filterF5,-2800,-200,-2800,-200},
+ {3850000LL,modeLSB,filterF5,-2800,-200,-2800,-200}};
BANDSTACK_ENTRY bandstack_entries60[] =
- {{5330500LL,5330500LL,modeUSB,filterF5,-2800,-200,-2800,-200},
- {5346500LL,5346500LL,modeUSB,filterF5,-2800,-200,-2800,-200},
- {5366500LL,5366500LL,modeUSB,filterF5,-2800,-200,-2800,-200},
- {5371500LL,5371500LL,modeUSB,filterF5,-2800,-200,-2800,-200},
- {5403500LL,5403500LL,modeUSB,filterF5,-2800,-200,-2800,-200}};
+ {{5330500LL,modeUSB,filterF5,-2800,-200,-2800,-200},
+ {5346500LL,modeUSB,filterF5,-2800,-200,-2800,-200},
+ {5366500LL,modeUSB,filterF5,-2800,-200,-2800,-200},
+ {5371500LL,modeUSB,filterF5,-2800,-200,-2800,-200},
+ {5403500LL,modeUSB,filterF5,-2800,-200,-2800,-200}};
BANDSTACK_ENTRY bandstack_entries40[] =
- {{7001000LL,7001000LL,modeCWL,filterF0,-2800,-200,-2800,-200},
- {7152000LL,7152000LL,modeLSB,filterF5,-2800,-200,-2800,-200},
- {7255000LL,7255000LL,modeLSB,filterF5,-2800,-200,-2800,-200}};
+ {{7001000LL,modeCWL,filterF6,-2800,-200,-2800,-200},
+ {7152000LL,modeLSB,filterF5,-2800,-200,-2800,-200},
+ {7255000LL,modeLSB,filterF5,-2800,-200,-2800,-200}};
BANDSTACK_ENTRY bandstack_entries30[] =
- {{10120000LL,10120000LL,modeCWU,filterF0,200,2800,200,2800},
- {10130000LL,10130000LL,modeCWU,filterF0,200,2800,200,2800},
- {10140000LL,10140000LL,modeCWU,filterF4,200,2800,200,2800}};
+ {{10120000LL,modeCWU,filterF6,200,2800,200,2800},
+ {10130000LL,modeCWU,filterF6,200,2800,200,2800},
+ {10140000LL,modeCWU,filterF6,200,2800,200,2800}};
BANDSTACK_ENTRY bandstack_entries20[] =
- {{14010000LL,14010000LL,modeCWU,filterF0,200,2800,200,2800},
- {14150000LL,14010000LL,modeUSB,filterF5,200,2800,200,2800},
- {14230000LL,14010000LL,modeUSB,filterF5,200,2800,200,2800},
- {14336000LL,14010000LL,modeUSB,filterF5,200,2800,200,2800}};
+ {{14010000LL,modeCWU,filterF6,200,2800,200,2800},
+ {14150000LL,modeUSB,filterF5,200,2800,200,2800},
+ {14230000LL,modeUSB,filterF5,200,2800,200,2800},
+ {14336000LL,modeUSB,filterF5,200,2800,200,2800}};
BANDSTACK_ENTRY bandstack_entries18[] =
- {{18068600LL,18068600LL,modeCWU,filterF0,200,2800,200,2800},
- {18125000LL,18068600LL,modeUSB,filterF5,200,2800,200,2800},
- {18140000LL,18068600LL,modeUSB,filterF5,200,2800,200,2800}};
+ {{18068600LL,modeCWU,filterF6,200,2800,200,2800},
+ {18125000LL,modeUSB,filterF5,200,2800,200,2800},
+ {18140000LL,modeUSB,filterF5,200,2800,200,2800}};
BANDSTACK_ENTRY bandstack_entries15[] =
- {{21001000LL,21001000LL,modeCWU,filterF0,200,2800,200,2800},
- {21255000LL,21001000LL,modeUSB,filterF5,200,2800,200,2800},
- {21300000LL,21001000LL,modeUSB,filterF5,200,2800,200,2800}};
+ {{21001000LL,modeCWU,filterF6,200,2800,200,2800},
+ {21255000LL,modeUSB,filterF5,200,2800,200,2800},
+ {21300000LL,modeUSB,filterF5,200,2800,200,2800}};
BANDSTACK_ENTRY bandstack_entries12[] =
- {{24895000LL,24895000LL,modeCWU,filterF0,200,2800,200,2800},
- {24900000LL,24895000LL,modeUSB,filterF5,200,2800,200,2800},
- {24910000LL,24895000LL,modeUSB,filterF5,200,2800,200,2800}};
+ {{24895000LL,modeCWU,filterF6,200,2800,200,2800},
+ {24900000LL,modeUSB,filterF5,200,2800,200,2800},
+ {24910000LL,modeUSB,filterF5,200,2800,200,2800}};
BANDSTACK_ENTRY bandstack_entries10[] =
- {{28010000LL,28010000LL,modeCWU,filterF0,200,2800,200,2800},
- {28300000LL,28010000LL,modeUSB,filterF5,200,2800,200,2800},
- {28400000LL,28010000LL,modeUSB,filterF5,200,2800,200,2800}};
+ {{28010000LL,modeCWU,filterF6,200,2800,200,2800},
+ {28300000LL,modeUSB,filterF5,200,2800,200,2800},
+ {28400000LL,modeUSB,filterF5,200,2800,200,2800}};
BANDSTACK_ENTRY bandstack_entries50[] =
- {{50010000LL,50010000LL,modeCWU,filterF0,200,2800,200,2800},
- {50125000LL,50010000LL,modeUSB,filterF5,200,2800,200,2800},
- {50200000LL,50010000LL,modeUSB,filterF5,200,2800,200,2800}};
+ {{50010000LL,modeCWU,filterF6,200,2800,200,2800},
+ {50125000LL,modeUSB,filterF5,200,2800,200,2800},
+ {50200000LL,modeUSB,filterF5,200,2800,200,2800}};
#ifdef LIMESDR
BANDSTACK_ENTRY bandstack_entries70[] =
- {{70010000LL,70010000LL,modeCWU,filterF0,200,2800,200,2800},
- {70200000LL,70010000LL,modeUSB,filterF5,200,2800,200,2800},
- {70250000LL,70010000LL,modeUSB,filterF5,200,2800,200,2800}};
+ {{70010000LL,modeCWU,filterF6,200,2800,200,2800},
+ {70200000LL,modeUSB,filterF5,200,2800,200,2800},
+ {70250000LL,modeUSB,filterF5,200,2800,200,2800}};
BANDSTACK_ENTRY bandstack_entries144[] =
- {{144010000LL,144010000LL,modeCWU,filterF0,200,2800,200,2800},
- {144200000LL,144010000LL,modeUSB,filterF5,200,2800,200,2800},
- {144250000LL,144010000LL,modeUSB,filterF5,200,2800,200,2800},
- {145600000LL,144010000LL,modeFMN,filterF1,200,2800,200,2800},
- {145725000LL,144010000LL,modeFMN,filterF1,200,2800,200,2800},
- {145900000LL,144010000LL,modeFMN,filterF1,200,2800,200,2800}};
+ {{144010000LL,modeCWU,filterF6,200,2800,200,2800},
+ {144200000LL,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,220010000,modeCWU,filterF0,200,2800,200,2800},
- {220200000LL,220010000,modeUSB,filterF5,200,2800,200,2800},
- {220250000LL,220010000,modeUSB,filterF5,200,2800,200,2800}};
+ {{220010000LL,modeCWU,filterF6,200,2800,200,2800},
+ {220200000LL,modeUSB,filterF5,200,2800,200,2800},
+ {220250000LL,modeUSB,filterF5,200,2800,200,2800}};
BANDSTACK_ENTRY bandstack_entries430[] =
- {{430010000LL,430010000LL,modeCWU,filterF0,200,2800,200,2800},
- {432100000LL,430010000LL,modeUSB,filterF5,200,2800,200,2800},
- {432300000LL,430010000LL,modeUSB,filterF5,200,2800,200,2800}};
+ {{430010000LL,modeCWU,filterF6,200,2800,200,2800},
+ {432100000LL,modeUSB,filterF5,200,2800,200,2800},
+ {432300000LL,modeUSB,filterF5,200,2800,200,2800}};
BANDSTACK_ENTRY bandstack_entries902[] =
- {{902010000LL,902010000LL,modeCWU,filterF0,200,2800,200,2800},
- {902100000LL,902010000LL,modeUSB,filterF5,200,2800,200,2800},
- {902300000LL,902010000LL,modeUSB,filterF5,200,2800,200,2800}};
+ {{902010000LL,modeCWU,filterF6,200,2800,200,2800},
+ {902100000LL,modeUSB,filterF5,200,2800,200,2800},
+ {902300000LL,modeUSB,filterF5,200,2800,200,2800}};
BANDSTACK_ENTRY bandstack_entries1240[] =
- {{1240010000LL,1240010000LL,modeCWU,filterF0,200,2800,200,2800},
- {1240100000LL,1240010000LL,modeUSB,filterF5,200,2800,200,2800},
- {1240300000LL,1240010000LL,modeUSB,filterF5,200,2800,200,2800}};
+ {{1240010000LL,modeCWU,filterF6,200,2800,200,2800},
+ {1240100000LL,modeUSB,filterF5,200,2800,200,2800},
+ {1240300000LL,modeUSB,filterF5,200,2800,200,2800}};
BANDSTACK_ENTRY bandstack_entries2300[] =
- {{2300010000LL,2300010000LL,modeCWU,filterF0,200,2800,200,2800},
- {2300100000LL,2300010000LL,modeUSB,filterF5,200,2800,200,2800},
- {2300300000LL,2300010000LL,modeUSB,filterF5,200,2800,200,2800}};
+ {{2300010000LL,modeCWU,filterF6,200,2800,200,2800},
+ {2300100000LL,modeUSB,filterF5,200,2800,200,2800},
+ {2300300000LL,modeUSB,filterF5,200,2800,200,2800}};
BANDSTACK_ENTRY bandstack_entries3400[] =
- {{3400010000LL,3400010000LL,modeCWU,filterF0,200,2800,200,2800},
- {3400100000LL,3400010000LL,modeUSB,filterF5,200,2800,200,2800},
- {3400300000LL,3400010000LL,modeUSB,filterF5,200,2800,200,2800}};
+ {{3400010000LL,modeCWU,filterF6,200,2800,200,2800},
+ {3400100000LL,modeUSB,filterF5,200,2800,200,2800},
+ {3400300000LL,modeUSB,filterF5,200,2800,200,2800}};
BANDSTACK_ENTRY bandstack_entriesAIR[] =
- {{118800000LL,118800000LL,modeAM,filterF1,200,2800,200,2800},
- {120000000LL,118800000LL,modeAM,filterF1,200,2800,200,2800},
- {121700000LL,118800000LL,modeAM,filterF1,200,2800,200,2800},
- {124100000LL,118800000LL,modeAM,filterF1,200,2800,200,2800},
- {126600000LL,118800000LL,modeAM,filterF1,200,2800,200,2800},
- {136500000LL,118800000LL,modeAM,filterF1,200,2800,200,2800}};
+ {{118800000LL,modeAM,filterF3,200,2800,200,2800},
+ {120000000LL,modeAM,filterF3,200,2800,200,2800},
+ {121700000LL,modeAM,filterF3,200,2800,200,2800},
+ {124100000LL,modeAM,filterF3,200,2800,200,2800},
+ {126600000LL,modeAM,filterF3,200,2800,200,2800},
+ {136500000LL,modeAM,filterF3,200,2800,200,2800}};
#endif
BANDSTACK_ENTRY bandstack_entriesGEN[] =
- {{909000LL,909000LL,modeAM,filterF6,-6000,6000,-6000,60000},
- {5975000LL,909000LL,modeAM,filterF6,-6000,6000,-6000,60000},
- {13845000LL,909000LL,modeAM,filterF6,-6000,6000,-6000,60000}};
+ {{909000LL,modeAM,filterF3,-6000,6000,-6000,60000},
+ {5975000LL,modeAM,filterF3,-6000,6000,-6000,60000},
+ {13845000LL,modeAM,filterF3,-6000,6000,-6000,60000}};
BANDSTACK_ENTRY bandstack_entriesWWV[] =
- {{2500000LL,2500000LL,modeSAM,filterF6,200,2800,200,2800},
- {5000000LL,2500000LL,modeSAM,filterF6,200,2800,200,2800},
- {10000000LL,2500000LL,modeSAM,filterF6,200,2800,200,2800},
- {15000000LL,2500000LL,modeSAM,filterF6,200,2800,200,2800},
- {20000000LL,2500000LL,modeSAM,filterF6,200,2800,200,2800}};
+ {{2500000LL,modeSAM,filterF3,200,2800,200,2800},
+ {5000000LL,modeSAM,filterF3,200,2800,200,2800},
+ {10000000LL,modeSAM,filterF3,200,2800,200,2800},
+ {15000000LL,modeSAM,filterF3,200,2800,200,2800},
+ {20000000LL,modeSAM,filterF3,200,2800,200,2800}};
BANDSTACK bandstack160={3,1,bandstack_entries160};
BANDSTACK bandstack80={3,1,bandstack_entries80};
BAND bands[BANDS+XVTRS] =
- {{"160",&bandstack160,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,1800000LL,1800000LL,0LL,0},
- {"80",&bandstack80,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,3500000LL,3500000LL,0LL,0},
+ {{"160",&bandstack160,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,1800000LL,2000000LL,0LL,0},
+ {"80",&bandstack80,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,3500000LL,4000000LL,0LL,0},
{"60",&bandstack60,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,5330500LL,5403500LL,0LL,0},
{"40",&bandstack40,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,7000000LL,7300000LL,0LL,0},
{"30",&bandstack30,0,0,0,0,0,ALEX_ATTENUATION_0dB,53.0,10100000LL,10150000LL,0LL,0},
};
+BANDSTACK *bandstack_get_bandstack(int band) {
+ return bands[band].bandstack;
+}
+
+BANDSTACK_ENTRY *bandstack_get_bandstack_entry(int band,int entry) {
+ BANDSTACK *bandstack=bands[band].bandstack;
+ return &bandstack->entry[entry];
+}
+
BANDSTACK_ENTRY *bandstack_entry_get_current() {
BANDSTACK *bandstack=bands[band].bandstack;
BANDSTACK_ENTRY *entry=&bandstack->entry[bandstack->current_entry];
entry=bands[b].bandstack->entry;
entry+=stack;
- sprintf(value,"%lld",entry->frequencyA);
+ sprintf(value,"%lld",entry->frequency);
sprintf(name,"band.%d.stack.%d.a",b,stack);
setProperty(name,value);
sprintf(name,"band.%d.stack.%d.a",b,stack);
value=getProperty(name);
- if(value) entry->frequencyA=atoll(value);
+ if(value) entry->frequency=atoll(value);
sprintf(name,"band.%d.stack.%d.mode",b,stack);
value=getProperty(name);
int band;
gboolean displayHF;
-int band_get_current();
-BAND *band_get_current_band();
-BAND *band_get_band(int b);
-BAND *band_set_current(int b);
-int get_band_from_frequency(long long f);
+extern int band_get_current();
+extern BAND *band_get_current_band();
+extern BAND *band_get_band(int b);
+extern BAND *band_set_current(int b);
+extern int get_band_from_frequency(long long f);
-BANDSTACK_ENTRY *bandstack_entry_next();
-BANDSTACK_ENTRY *bandstack_entry_previous();
-BANDSTACK_ENTRY *bandstack_entry_get_current();
+extern BANDSTACK *bandstack_get_bandstack(int band);
+extern BANDSTACK_ENTRY *bandstack_get_bandstack_entry(int band,int entry);
+
+extern BANDSTACK_ENTRY *bandstack_entry_next();
+extern BANDSTACK_ENTRY *bandstack_entry_previous();
+extern BANDSTACK_ENTRY *bandstack_entry_get_current();
#endif
#include "bandstack.h"
#include "filter.h"
#include "radio.h"
+#include "receiver.h"
#include "vfo.h"
#include "button_text.h"
static gboolean band_select_cb (GtkWidget *widget, gpointer data) {
GtkWidget *label;
int b=(int)data;
- BANDSTACK_ENTRY *entry;
- if(b==band_get_current()) {
- entry=bandstack_entry_next();
- } else {
- BAND* band=band_set_current(b);
- entry=bandstack_entry_get_current();
- set_button_text_color(last_band,"black");
- last_band=widget;
- set_button_text_color(last_band,"orange");
- }
- setMode(entry->mode);
- FILTER* band_filters=filters[entry->mode];
- FILTER* band_filter=&band_filters[entry->filter];
- setFilter(band_filter->low,band_filter->high);
- setFrequency(entry->frequencyA);
-
- BAND *band=band_get_current_band();
- set_alex_rx_antenna(band->alexRxAntenna);
- set_alex_tx_antenna(band->alexTxAntenna);
- set_alex_attenuation(band->alexAttenuation);
-
- vfo_update(NULL);
+ set_button_text_color(last_band,"black");
+ last_band=widget;
+ set_button_text_color(last_band,"orange");
- setFrequency(entry->frequencyA);
+ vfo_band_changed(b);
+}
- calcDriveLevel();
- calcTuneDriveLevel();
+int band_update(void *data) {
+ band_select_cb(NULL,(gpointer)data);
+ return 0;
}
void band_menu(GtkWidget *parent) {
g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL);
gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1);
+ char label[32];
+ sprintf(label,"RX %d VFO %s",active_receiver->id,active_receiver->id==0?"A":"B");
+ GtkWidget *rx_label=gtk_label_new(label);
+ gtk_grid_attach(GTK_GRID(grid),rx_label,1,0,1,1);
+
for(i=0;i<BANDS+XVTRS;i++) {
#ifdef LIMESDR
if(protocol!=LIMESDR_PROTOCOL) {
if(strlen(band->title)>0) {
GtkWidget *b=gtk_button_new_with_label(band->title);
set_button_text_color(b,"black");
- if(i==band_get_current()) {
+ //if(i==band_get_current()) {
+ if(i==vfo[active_receiver->id].band) {
set_button_text_color(b,"orange");
last_band=b;
}
*/
void band_menu(GtkWidget *parent);
+int band_update(void *data);
* @brief Bandstack definition
*/
struct _BANDSTACK_ENTRY {
- long long frequencyA;
- long long frequencyB;
+ long long frequency;
int mode;
int filter;
int var1Low;
#include "bandstack.h"
#include "filter.h"
#include "radio.h"
+#include "receiver.h"
#include "vfo.h"
#include "button_text.h"
static gboolean bandstack_select_cb (GtkWidget *widget, gpointer data) {
int b=(int)data;
- BAND *band=band_get_current_band();
- BANDSTACK *bandstack=band->bandstack;
-
- bandstack->current_entry=b;
-
set_button_text_color(last_bandstack,"black");
last_bandstack=widget;
set_button_text_color(last_bandstack,"orange");
-
- BANDSTACK_ENTRY *entry;
- entry=&(bandstack->entry[b]);
-
- setMode(entry->mode);
- FILTER* band_filters=filters[entry->mode];
- FILTER* band_filter=&band_filters[entry->filter];
- setFilter(band_filter->low,band_filter->high);
- setFrequency(entry->frequencyA);
-
- set_alex_rx_antenna(band->alexRxAntenna);
- set_alex_tx_antenna(band->alexTxAntenna);
- set_alex_attenuation(band->alexAttenuation);
-
- vfo_update(NULL);
-
- setFrequency(entry->frequencyA);
+ vfo_bandstack_changed(b);
}
void bandstack_menu(GtkWidget *parent) {
g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL);
gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1);
- char label[16];
+ char label[32];
+ sprintf(label,"RX %d VFO %s",active_receiver->id,active_receiver->id==0?"A":"B");
+ GtkWidget *rx_label=gtk_label_new(label);
+ gtk_grid_attach(GTK_GRID(grid),rx_label,1,0,1,1);
- BAND *band=band_get_current_band();
+ BAND *band=band_get_band(vfo[active_receiver->id].band);
BANDSTACK *bandstack=band->bandstack;
for(i=0;i<bandstack->entries;i++) {
BANDSTACK_ENTRY *entry=&bandstack->entry[i];
- sprintf(label,"%lld %s",entry->frequencyA,mode_string[entry->mode]);
+ sprintf(label,"%lld %s",entry->frequency,mode_string[entry->mode]);
GtkWidget *b=gtk_button_new_with_label(label);
set_button_text_color(b,"black");
//gtk_widget_override_font(b, pango_font_description_from_string("Arial 20"));
- if(i==bandstack->current_entry) {
+ if(i==vfo[active_receiver->id].bandstack) {
set_button_text_color(b,"orange");
last_bandstack=b;
}
#include "main.h"
#include "channel.h"
#include "discovered.h"
-#include "radio.h"
+//#include "radio.h"
#include "gpio.h"
+
#ifdef GPIO
+
+static GtkWidget *dialog;
+
+static GtkWidget *b_enable_vfo_encoder;
+static GtkWidget *vfo_a_label;
+static GtkWidget *vfo_a;
+static GtkWidget *vfo_b_label;
+static GtkWidget *vfo_b;
+static GtkWidget *b_enable_vfo_pullup;
+static GtkWidget *b_enable_E1_encoder;
+static GtkWidget *E1_a_label;
+static GtkWidget *E1_a;
+static GtkWidget *E1_b_label;
+static GtkWidget *E1_b;
+static GtkWidget *b_enable_E1_pullup;
+static GtkWidget *b_enable_E2_encoder;
+static GtkWidget *E2_a_label;
+static GtkWidget *E2_a;
+static GtkWidget *E2_b_label;
+static GtkWidget *E2_b;
+static GtkWidget *b_enable_E2_pullup;
+static GtkWidget *b_enable_E3_encoder;
+static GtkWidget *E3_a_label;
+static GtkWidget *E3_a;
+static GtkWidget *E3_b_label;
+static GtkWidget *E3_b;
+static GtkWidget *b_enable_E3_pullup;
+static GtkWidget *b_enable_mox;
+static GtkWidget *mox_label;
+static GtkWidget *mox;
+
+static GtkWidget *b_enable_S1;
+static GtkWidget *S1_label;
+static GtkWidget *S1;
+
+static GtkWidget *b_enable_S2;
+static GtkWidget *S2_label;
+static GtkWidget *S2;
+
+static GtkWidget *b_enable_S3;
+static GtkWidget *S3_label;
+static GtkWidget *S3;
+
+static GtkWidget *b_enable_S4;
+static GtkWidget *S4_label;
+static GtkWidget *S4;
+
+static GtkWidget *b_enable_S5;
+static GtkWidget *S5_label;
+static GtkWidget *S5;
+
+static GtkWidget *b_enable_S6;
+static GtkWidget *S6_label;
+static GtkWidget *S6;
+
+static GtkWidget *b_enable_function;
+static GtkWidget *function_label;
+static GtkWidget *function;
+
+#ifdef LOCALCW
+static GtkWidget *cwl_label;
+static GtkWidget *cwl_gpio_label;
+static GtkWidget *cwl;
+static GtkWidget *cwr_label;
+static GtkWidget *cwr_gpio_label;
+static GtkWidget *cwr;
+#endif
+
+static gboolean save_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ if(dialog!=NULL) {
+ ENABLE_VFO_ENCODER=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_vfo_encoder))?1:0;
+ VFO_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(vfo_a));
+ VFO_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(vfo_b));
+ ENABLE_VFO_PULLUP=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_vfo_pullup))?1:0;
+
+ ENABLE_E1_ENCODER=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_E1_encoder))?1:0;
+ E1_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E1_a));
+ E1_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E1_b));
+ ENABLE_E1_PULLUP=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_E1_pullup))?1:0;
+
+ ENABLE_E2_ENCODER=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_E2_encoder))?1:0;
+ E2_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E2_a));
+ E2_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E2_b));
+ ENABLE_E2_PULLUP=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_E2_pullup))?1:0;
+
+ ENABLE_E3_ENCODER=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_E3_encoder))?1:0;
+ E3_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E3_a));
+ E3_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E3_b));
+ ENABLE_E3_PULLUP=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_E3_pullup))?1:0;
+
+ ENABLE_MOX_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_mox))?1:0;
+ MOX_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(mox));
+
+ ENABLE_S1_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_S1))?1:0;
+ S1_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(S1));
+
+ ENABLE_S2_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_S2))?1:0;
+ S2_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(S2));
+
+ ENABLE_S3_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_S3))?1:0;
+ S3_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(S3));
+
+ ENABLE_S4_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_S4))?1:0;
+ S4_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(S4));
+
+ ENABLE_S5_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_S5))?1:0;
+ S5_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(S5));
+
+ ENABLE_S6_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_S6))?1:0;
+ S6_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(S6));
+
+ ENABLE_FUNCTION_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_function))?1:0;
+ FUNCTION_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(function));
+#ifdef LOCALCW
+ CWL_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(cwl));
+ CWR_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(cwr));
+#endif
+
+ gpio_save_state();
+ gtk_widget_destroy(dialog);
+ }
+ return TRUE;
+}
+
+static gboolean cancel_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ if(dialog!=NULL) {
+ gtk_widget_destroy(dialog);
+ }
+ return TRUE;
+}
+
void configure_gpio(GtkWidget *parent) {
gpio_restore_state();
- GtkWidget *dialog=gtk_dialog_new_with_buttons("Configure GPIO",GTK_WINDOW(parent),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
+ dialog=gtk_dialog_new_with_buttons("Configure GPIO",GTK_WINDOW(parent),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
GtkWidget *grid=gtk_grid_new();
//gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
+ int y=0;
- GtkWidget *b_enable_vfo_encoder=gtk_check_button_new_with_label("Enable VFO");
+ b_enable_vfo_encoder=gtk_check_button_new_with_label("Enable VFO");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_vfo_encoder), ENABLE_VFO_ENCODER);
gtk_widget_show(b_enable_vfo_encoder);
- gtk_grid_attach(GTK_GRID(grid),b_enable_vfo_encoder,0,0,1,1);
+ gtk_grid_attach(GTK_GRID(grid),b_enable_vfo_encoder,0,y,1,1);
- GtkWidget *vfo_a_label=gtk_label_new("GPIO A:");
+ vfo_a_label=gtk_label_new("GPIO A:");
gtk_widget_show(vfo_a_label);
- gtk_grid_attach(GTK_GRID(grid),vfo_a_label,1,0,1,1);
+ gtk_grid_attach(GTK_GRID(grid),vfo_a_label,1,y,1,1);
- GtkWidget *vfo_a=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+ vfo_a=gtk_spin_button_new_with_range (0.0,100.0,1.0);
gtk_spin_button_set_value (GTK_SPIN_BUTTON(vfo_a),VFO_ENCODER_A);
gtk_widget_show(vfo_a);
- gtk_grid_attach(GTK_GRID(grid),vfo_a,2,0,1,1);
+ gtk_grid_attach(GTK_GRID(grid),vfo_a,2,y,1,1);
- GtkWidget *vfo_b_label=gtk_label_new("GPIO B:");
+ vfo_b_label=gtk_label_new("GPIO B:");
gtk_widget_show(vfo_b_label);
- gtk_grid_attach(GTK_GRID(grid),vfo_b_label,3,0,1,1);
+ gtk_grid_attach(GTK_GRID(grid),vfo_b_label,3,y,1,1);
- GtkWidget *vfo_b=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+ vfo_b=gtk_spin_button_new_with_range (0.0,100.0,1.0);
gtk_spin_button_set_value (GTK_SPIN_BUTTON(vfo_b),VFO_ENCODER_B);
gtk_widget_show(vfo_b);
- gtk_grid_attach(GTK_GRID(grid),vfo_b,4,0,1,1);
+ gtk_grid_attach(GTK_GRID(grid),vfo_b,4,y,1,1);
- GtkWidget *b_enable_vfo_pullup=gtk_check_button_new_with_label("Enable Pull-up");
+ b_enable_vfo_pullup=gtk_check_button_new_with_label("Enable Pull-up");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_vfo_pullup), ENABLE_VFO_PULLUP);
gtk_widget_show(b_enable_vfo_pullup);
- gtk_grid_attach(GTK_GRID(grid),b_enable_vfo_pullup,5,0,1,1);
+ gtk_grid_attach(GTK_GRID(grid),b_enable_vfo_pullup,5,y,1,1);
+ y++;
- GtkWidget *b_enable_af_encoder=gtk_check_button_new_with_label("Enable E1");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_af_encoder), ENABLE_E1_ENCODER);
- gtk_widget_show(b_enable_af_encoder);
- gtk_grid_attach(GTK_GRID(grid),b_enable_af_encoder,0,1,1,1);
+ b_enable_E1_encoder=gtk_check_button_new_with_label("Enable E1");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_E1_encoder), ENABLE_E1_ENCODER);
+ gtk_widget_show(b_enable_E1_encoder);
+ gtk_grid_attach(GTK_GRID(grid),b_enable_E1_encoder,0,y,1,1);
- GtkWidget *af_a_label=gtk_label_new("GPIO A:");
- gtk_widget_show(af_a_label);
- gtk_grid_attach(GTK_GRID(grid),af_a_label,1,1,1,1);
+ E1_a_label=gtk_label_new("GPIO A:");
+ gtk_widget_show(E1_a_label);
+ gtk_grid_attach(GTK_GRID(grid),E1_a_label,1,y,1,1);
- GtkWidget *af_a=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(af_a),E1_ENCODER_A);
- gtk_widget_show(af_a);
- gtk_grid_attach(GTK_GRID(grid),af_a,2,1,1,1);
+ E1_a=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON(E1_a),E1_ENCODER_A);
+ gtk_widget_show(E1_a);
+ gtk_grid_attach(GTK_GRID(grid),E1_a,2,y,1,1);
- GtkWidget *af_b_label=gtk_label_new("GPIO B:");
- gtk_widget_show(af_b_label);
- gtk_grid_attach(GTK_GRID(grid),af_b_label,3,1,1,1);
+ E1_b_label=gtk_label_new("GPIO B:");
+ gtk_widget_show(E1_b_label);
+ gtk_grid_attach(GTK_GRID(grid),E1_b_label,3,y,1,1);
- GtkWidget *af_b=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(af_b),E1_ENCODER_B);
- gtk_widget_show(af_b);
- gtk_grid_attach(GTK_GRID(grid),af_b,4,1,1,1);
+ E1_b=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON(E1_b),E1_ENCODER_B);
+ gtk_widget_show(E1_b);
+ gtk_grid_attach(GTK_GRID(grid),E1_b,4,y,1,1);
- GtkWidget *b_enable_af_pullup=gtk_check_button_new_with_label("Enable Pull-up");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_af_pullup), ENABLE_E1_PULLUP);
- gtk_widget_show(b_enable_af_pullup);
- gtk_grid_attach(GTK_GRID(grid),b_enable_af_pullup,5,1,1,1);
+ b_enable_E1_pullup=gtk_check_button_new_with_label("Enable Pull-up");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_E1_pullup), ENABLE_E1_PULLUP);
+ gtk_widget_show(b_enable_E1_pullup);
+ gtk_grid_attach(GTK_GRID(grid),b_enable_E1_pullup,5,y,1,1);
+ y++;
- GtkWidget *b_enable_rf_encoder=gtk_check_button_new_with_label("Enable RF");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_rf_encoder), ENABLE_E2_ENCODER);
- gtk_widget_show(b_enable_rf_encoder);
- gtk_grid_attach(GTK_GRID(grid),b_enable_rf_encoder,0,2,1,1);
+ b_enable_E2_encoder=gtk_check_button_new_with_label("Enable E2");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_E2_encoder), ENABLE_E2_ENCODER);
+ gtk_widget_show(b_enable_E2_encoder);
+ gtk_grid_attach(GTK_GRID(grid),b_enable_E2_encoder,0,y,1,1);
- GtkWidget *rf_a_label=gtk_label_new("GPIO A:");
- gtk_widget_show(rf_a_label);
- gtk_grid_attach(GTK_GRID(grid),rf_a_label,1,2,1,1);
+ E2_a_label=gtk_label_new("GPIO A:");
+ gtk_widget_show(E2_a_label);
+ gtk_grid_attach(GTK_GRID(grid),E2_a_label,1,y,1,1);
- GtkWidget *rf_a=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(rf_a),E2_ENCODER_A);
- gtk_widget_show(rf_a);
- gtk_grid_attach(GTK_GRID(grid),rf_a,2,2,1,1);
+ E2_a=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON(E2_a),E2_ENCODER_A);
+ gtk_widget_show(E2_a);
+ gtk_grid_attach(GTK_GRID(grid),E2_a,2,y,1,1);
- GtkWidget *rf_b_label=gtk_label_new("GPIO B:");
- gtk_widget_show(rf_b_label);
- gtk_grid_attach(GTK_GRID(grid),rf_b_label,3,2,1,1);
+ E2_b_label=gtk_label_new("GPIO B:");
+ gtk_widget_show(E2_b_label);
+ gtk_grid_attach(GTK_GRID(grid),E2_b_label,3,y,1,1);
- GtkWidget *rf_b=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(rf_b),E2_ENCODER_B);
- gtk_widget_show(rf_b);
- gtk_grid_attach(GTK_GRID(grid),rf_b,4,2,1,1);
+ E2_b=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON(E2_b),E2_ENCODER_B);
+ gtk_widget_show(E2_b);
+ gtk_grid_attach(GTK_GRID(grid),E2_b,4,y,1,1);
- GtkWidget *b_enable_rf_pullup=gtk_check_button_new_with_label("Enable Pull-up");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_rf_pullup), ENABLE_E2_PULLUP);
- gtk_widget_show(b_enable_rf_pullup);
- gtk_grid_attach(GTK_GRID(grid),b_enable_rf_pullup,5,2,1,1);
+ b_enable_E2_pullup=gtk_check_button_new_with_label("Enable Pull-up");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_E2_pullup), ENABLE_E2_PULLUP);
+ gtk_widget_show(b_enable_E2_pullup);
+ gtk_grid_attach(GTK_GRID(grid),b_enable_E2_pullup,5,y,1,1);
+ y++;
- GtkWidget *b_enable_agc_encoder=gtk_check_button_new_with_label("Enable AGC");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_agc_encoder), ENABLE_E3_ENCODER);
- gtk_widget_show(b_enable_agc_encoder);
- gtk_grid_attach(GTK_GRID(grid),b_enable_agc_encoder,0,3,1,1);
+ b_enable_E3_encoder=gtk_check_button_new_with_label("Enable E3");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_E3_encoder), ENABLE_E3_ENCODER);
+ gtk_widget_show(b_enable_E3_encoder);
+ gtk_grid_attach(GTK_GRID(grid),b_enable_E3_encoder,0,y,1,1);
- GtkWidget *agc_a_label=gtk_label_new("GPIO A:");
- gtk_widget_show(agc_a_label);
- gtk_grid_attach(GTK_GRID(grid),agc_a_label,1,3,1,1);
+ E3_a_label=gtk_label_new("GPIO A:");
+ gtk_widget_show(E3_a_label);
+ gtk_grid_attach(GTK_GRID(grid),E3_a_label,1,y,1,1);
- GtkWidget *agc_a=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(agc_a),E3_ENCODER_A);
- gtk_widget_show(agc_a);
- gtk_grid_attach(GTK_GRID(grid),agc_a,2,3,1,1);
+ E3_a=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON(E3_a),E3_ENCODER_A);
+ gtk_widget_show(E3_a);
+ gtk_grid_attach(GTK_GRID(grid),E3_a,2,y,1,1);
- GtkWidget *agc_b_label=gtk_label_new("GPIO B:");
- gtk_widget_show(agc_b_label);
- gtk_grid_attach(GTK_GRID(grid),agc_b_label,3,3,1,1);
+ E3_b_label=gtk_label_new("GPIO B:");
+ gtk_widget_show(E3_b_label);
+ gtk_grid_attach(GTK_GRID(grid),E3_b_label,3,y,1,1);
- GtkWidget *agc_b=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(agc_b),E3_ENCODER_B);
- gtk_widget_show(agc_b);
- gtk_grid_attach(GTK_GRID(grid),agc_b,4,3,1,1);
+ E3_b=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON(E3_b),E3_ENCODER_B);
+ gtk_widget_show(E3_b);
+ gtk_grid_attach(GTK_GRID(grid),E3_b,4,y,1,1);
- GtkWidget *b_enable_agc_pullup=gtk_check_button_new_with_label("Enable Pull-up");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_agc_pullup), ENABLE_E3_PULLUP);
- gtk_widget_show(b_enable_agc_pullup);
- gtk_grid_attach(GTK_GRID(grid),b_enable_agc_pullup,5,3,1,1);
+ b_enable_E3_pullup=gtk_check_button_new_with_label("Enable Pull-up");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_E3_pullup), ENABLE_E3_PULLUP);
+ gtk_widget_show(b_enable_E3_pullup);
+ gtk_grid_attach(GTK_GRID(grid),b_enable_E3_pullup,5,y,1,1);
+ y++;
- GtkWidget *b_enable_band=gtk_check_button_new_with_label("Enable Band");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_band), ENABLE_S1_BUTTON);
- gtk_widget_show(b_enable_band);
- gtk_grid_attach(GTK_GRID(grid),b_enable_band,0,4,1,1);
+ b_enable_mox=gtk_check_button_new_with_label("Enable MOX/TUN");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_mox), ENABLE_MOX_BUTTON);
+ gtk_widget_show(b_enable_mox);
+ gtk_grid_attach(GTK_GRID(grid),b_enable_mox,0,y,1,1);
- GtkWidget *band_label=gtk_label_new("GPIO:");
- gtk_widget_show(band_label);
- gtk_grid_attach(GTK_GRID(grid),band_label,1,4,1,1);
+ mox_label=gtk_label_new("GPIO:");
+ gtk_widget_show(mox_label);
+ gtk_grid_attach(GTK_GRID(grid),mox_label,1,y,1,1);
- GtkWidget *band=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(band),S1_BUTTON);
- gtk_widget_show(band);
- gtk_grid_attach(GTK_GRID(grid),band,2,4,1,1);
+ mox=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON(mox),MOX_BUTTON);
+ gtk_widget_show(mox);
+ gtk_grid_attach(GTK_GRID(grid),mox,2,y,1,1);
+ y++;
- GtkWidget *b_enable_mode=gtk_check_button_new_with_label("Enable Mode");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_mode), ENABLE_S3_BUTTON);
- gtk_widget_show(b_enable_mode);
- gtk_grid_attach(GTK_GRID(grid),b_enable_mode,0,5,1,1);
+ b_enable_S1=gtk_check_button_new_with_label("Enable S1");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_S1), ENABLE_S1_BUTTON);
+ gtk_widget_show(b_enable_S1);
+ gtk_grid_attach(GTK_GRID(grid),b_enable_S1,0,y,1,1);
- GtkWidget *mode_label=gtk_label_new("GPIO:");
- gtk_widget_show(mode_label);
- gtk_grid_attach(GTK_GRID(grid),mode_label,1,5,1,1);
+ S1_label=gtk_label_new("GPIO:");
+ gtk_widget_show(S1_label);
+ gtk_grid_attach(GTK_GRID(grid),S1_label,1,y,1,1);
- GtkWidget *mode=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(mode),S3_BUTTON);
- gtk_widget_show(mode);
- gtk_grid_attach(GTK_GRID(grid),mode,2,5,1,1);
+ S1=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON(S1),S1_BUTTON);
+ gtk_widget_show(S1);
+ gtk_grid_attach(GTK_GRID(grid),S1,2,y,1,1);
- GtkWidget *b_enable_filter=gtk_check_button_new_with_label("Enable Filter");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_filter), ENABLE_S4_BUTTON);
- gtk_widget_show(b_enable_filter);
- gtk_grid_attach(GTK_GRID(grid),b_enable_filter,0,6,1,1);
+ y++;
- GtkWidget *filter_label=gtk_label_new("GPIO:");
- gtk_widget_show(filter_label);
- gtk_grid_attach(GTK_GRID(grid),filter_label,1,6,1,1);
+ b_enable_S2=gtk_check_button_new_with_label("Enable S2");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_S2), ENABLE_S2_BUTTON);
+ gtk_widget_show(b_enable_S2);
+ gtk_grid_attach(GTK_GRID(grid),b_enable_S2,0,y,1,1);
- GtkWidget *filter=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(filter),S4_BUTTON);
- gtk_widget_show(filter);
- gtk_grid_attach(GTK_GRID(grid),filter,2,6,1,1);
+ S2_label=gtk_label_new("GPIO:");
+ gtk_widget_show(S2_label);
+ gtk_grid_attach(GTK_GRID(grid),S2_label,1,y,1,1);
+ S2=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON(S2),S2_BUTTON);
+ gtk_widget_show(S2);
+ gtk_grid_attach(GTK_GRID(grid),S2,2,y,1,1);
- GtkWidget *b_enable_noise=gtk_check_button_new_with_label("Enable Noise");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_noise), ENABLE_S5_BUTTON);
- gtk_widget_show(b_enable_noise);
- gtk_grid_attach(GTK_GRID(grid),b_enable_noise,0,7,1,1);
+ y++;
- GtkWidget *noise_label=gtk_label_new("GPIO:");
- gtk_widget_show(noise_label);
- gtk_grid_attach(GTK_GRID(grid),noise_label,1,7,1,1);
+ b_enable_S3=gtk_check_button_new_with_label("Enable S3");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_S3), ENABLE_S3_BUTTON);
+ gtk_widget_show(b_enable_S3);
+ gtk_grid_attach(GTK_GRID(grid),b_enable_S3,0,y,1,1);
- GtkWidget *noise=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(noise),S5_BUTTON);
- gtk_widget_show(noise);
- gtk_grid_attach(GTK_GRID(grid),noise,2,7,1,1);
+ S3_label=gtk_label_new("GPIO:");
+ gtk_widget_show(S3_label);
+ gtk_grid_attach(GTK_GRID(grid),S3_label,1,y,1,1);
+ S3=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON(S3),S3_BUTTON);
+ gtk_widget_show(S3);
+ gtk_grid_attach(GTK_GRID(grid),S3,2,y,1,1);
- GtkWidget *b_enable_agc=gtk_check_button_new_with_label("Enable AGC");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_agc), ENABLE_S6_BUTTON);
- gtk_widget_show(b_enable_agc);
- gtk_grid_attach(GTK_GRID(grid),b_enable_agc,0,8,1,1);
+ y++;
- GtkWidget *agc_label=gtk_label_new("GPIO:");
- gtk_widget_show(agc_label);
- gtk_grid_attach(GTK_GRID(grid),agc_label,1,8,1,1);
+ b_enable_S4=gtk_check_button_new_with_label("Enable S4");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_S4), ENABLE_S4_BUTTON);
+ gtk_widget_show(b_enable_S4);
+ gtk_grid_attach(GTK_GRID(grid),b_enable_S4,0,y,1,1);
- GtkWidget *agc=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(agc),S6_BUTTON);
- gtk_widget_show(agc);
- gtk_grid_attach(GTK_GRID(grid),agc,2,8,1,1);
+ S4_label=gtk_label_new("GPIO:");
+ gtk_widget_show(S4_label);
+ gtk_grid_attach(GTK_GRID(grid),S4_label,1,y,1,1);
+ S4=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON(S4),S4_BUTTON);
+ gtk_widget_show(S4);
+ gtk_grid_attach(GTK_GRID(grid),S4,2,y,1,1);
- GtkWidget *b_enable_mox=gtk_check_button_new_with_label("Enable MOX");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_mox), ENABLE_MOX_BUTTON);
- gtk_widget_show(b_enable_mox);
- gtk_grid_attach(GTK_GRID(grid),b_enable_mox,0,9,1,1);
+ y++;
- GtkWidget *mox_label=gtk_label_new("GPIO:");
- gtk_widget_show(mox_label);
- gtk_grid_attach(GTK_GRID(grid),mox_label,1,9,1,1);
+ b_enable_S5=gtk_check_button_new_with_label("Enable S5");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_S5), ENABLE_S5_BUTTON);
+ gtk_widget_show(b_enable_S5);
+ gtk_grid_attach(GTK_GRID(grid),b_enable_S5,0,y,1,1);
- GtkWidget *mox=gtk_spin_button_new_with_range (0.0,100.0,1.0);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON(mox),MOX_BUTTON);
- gtk_widget_show(mox);
- gtk_grid_attach(GTK_GRID(grid),mox,2,9,1,1);
+ S5_label=gtk_label_new("GPIO:");
+ gtk_widget_show(S5_label);
+ gtk_grid_attach(GTK_GRID(grid),S5_label,1,y,1,1);
+
+ S5=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON(S5),S5_BUTTON);
+ gtk_widget_show(S5);
+ gtk_grid_attach(GTK_GRID(grid),S5,2,y,1,1);
+
+ y++;
+ b_enable_S6=gtk_check_button_new_with_label("Enable S6");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_S6), ENABLE_S6_BUTTON);
+ gtk_widget_show(b_enable_S6);
+ gtk_grid_attach(GTK_GRID(grid),b_enable_S6,0,y,1,1);
- GtkWidget *b_enable_function=gtk_check_button_new_with_label("Enable Function");
+ S6_label=gtk_label_new("GPIO:");
+ gtk_widget_show(S6_label);
+ gtk_grid_attach(GTK_GRID(grid),S6_label,1,y,1,1);
+
+ S6=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON(S6),S6_BUTTON);
+ gtk_widget_show(S6);
+ gtk_grid_attach(GTK_GRID(grid),S6,2,y,1,1);
+
+ y++;
+
+ b_enable_function=gtk_check_button_new_with_label("Enable Function");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_enable_function), ENABLE_FUNCTION_BUTTON);
gtk_widget_show(b_enable_function);
- gtk_grid_attach(GTK_GRID(grid),b_enable_function,0,10,1,1);
+ gtk_grid_attach(GTK_GRID(grid),b_enable_function,0,y,1,1);
- GtkWidget *function_label=gtk_label_new("GPIO:");
+ function_label=gtk_label_new("GPIO:");
gtk_widget_show(function_label);
- gtk_grid_attach(GTK_GRID(grid),function_label,1,10,1,1);
+ gtk_grid_attach(GTK_GRID(grid),function_label,1,y,1,1);
- GtkWidget *function=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+ function=gtk_spin_button_new_with_range (0.0,100.0,1.0);
gtk_spin_button_set_value (GTK_SPIN_BUTTON(function),FUNCTION_BUTTON);
gtk_widget_show(function);
- gtk_grid_attach(GTK_GRID(grid),function,2,10,1,1);
+ gtk_grid_attach(GTK_GRID(grid),function,2,y,1,1);
+
+ y++;
#ifdef LOCALCW
- GtkWidget *cwl_label=gtk_label_new("CWL");
+ cwl_label=gtk_label_new("CWL");
gtk_widget_show(cwl_label);
- gtk_grid_attach(GTK_GRID(grid),cwl_label,0,11,1,1);
+ gtk_grid_attach(GTK_GRID(grid),cwl_label,0,y,1,1);
- GtkWidget *cwl_gpio_label=gtk_label_new("GPIO:");
+ cwl_gpio_label=gtk_label_new("GPIO:");
gtk_widget_show(cwl_gpio_label);
- gtk_grid_attach(GTK_GRID(grid),cwl_gpio_label,1,11,1,1);
+ gtk_grid_attach(GTK_GRID(grid),cwl_gpio_label,1,y,1,1);
- GtkWidget *cwl=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+ cwl=gtk_spin_button_new_with_range (0.0,100.0,1.0);
gtk_spin_button_set_value (GTK_SPIN_BUTTON(cwl),CWL_BUTTON);
gtk_widget_show(cwl);
- gtk_grid_attach(GTK_GRID(grid),cwl,2,11,1,1);
+ gtk_grid_attach(GTK_GRID(grid),cwl,2,y,1,1);
+
+ y++;
- GtkWidget *cwr_label=gtk_label_new("CWR");
+ cwr_label=gtk_label_new("CWR");
gtk_widget_show(cwr_label);
- gtk_grid_attach(GTK_GRID(grid),cwr_label,0,12,1,1);
+ gtk_grid_attach(GTK_GRID(grid),cwr_label,0,y,1,1);
- GtkWidget *cwr_gpio_label=gtk_label_new("GPIO:");
+ cwr_gpio_label=gtk_label_new("GPIO:");
gtk_widget_show(cwr_gpio_label);
- gtk_grid_attach(GTK_GRID(grid),cwr_gpio_label,1,12,1,1);
+ gtk_grid_attach(GTK_GRID(grid),cwr_gpio_label,1,y,1,1);
- GtkWidget *cwr=gtk_spin_button_new_with_range (0.0,100.0,1.0);
+ cwr=gtk_spin_button_new_with_range (0.0,100.0,1.0);
gtk_spin_button_set_value (GTK_SPIN_BUTTON(cwr),CWR_BUTTON);
gtk_widget_show(cwr);
- gtk_grid_attach(GTK_GRID(grid),cwr,2,12,1,1);
-#endif
+ gtk_grid_attach(GTK_GRID(grid),cwr,2,y,1,1);
+ y++;
+#endif
+
+ GtkWidget *save_b=gtk_button_new_with_label("Save");
+ g_signal_connect (save_b, "button_press_event", G_CALLBACK(save_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),save_b,4,y-1,1,1);
- gtk_container_add(GTK_CONTAINER(content),grid);
+ GtkWidget *cancel_b=gtk_button_new_with_label("Cancel");
+ g_signal_connect (cancel_b, "button_press_event", G_CALLBACK(cancel_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),cancel_b,5,y-1,1,1);
gtk_container_add(GTK_CONTAINER(content),grid);
- GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK);
+/*
+ GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Save",GTK_RESPONSE_OK);
//gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 20"));
+*/
gtk_widget_show_all(dialog);
-
int result=gtk_dialog_run(GTK_DIALOG(dialog));
+/*
ENABLE_VFO_ENCODER=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_vfo_encoder))?1:0;
VFO_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(vfo_a));
VFO_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(vfo_b));
ENABLE_VFO_PULLUP=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_vfo_pullup))?1:0;
- ENABLE_E1_ENCODER=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_af_encoder))?1:0;
- E1_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(af_a));
- E1_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(af_b));
- ENABLE_E1_PULLUP=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_af_pullup))?1:0;
- ENABLE_E2_ENCODER=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_rf_encoder))?1:0;
- E2_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(rf_a));
- E2_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(rf_b));
- ENABLE_E2_PULLUP=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_rf_pullup))?1:0;
- ENABLE_E3_ENCODER=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_agc_encoder))?1:0;
- E3_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(agc_a));
- E3_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(agc_b));
- ENABLE_E3_PULLUP=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_agc_pullup))?1:0;
- ENABLE_S1_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_band))?1:0;
- S1_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(band));
- ENABLE_S2_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_band))?1:0;
- S2_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(band));
- ENABLE_S3_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_mode))?1:0;
- S3_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(mode));
- ENABLE_S4_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_filter))?1:0;
- S4_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(filter));
- ENABLE_S5_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_noise))?1:0;
- S5_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(noise));
- ENABLE_S6_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_agc))?1:0;
- S6_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(agc));
+ ENABLE_E1_ENCODER=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_E1_encoder))?1:0;
+ E1_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E1_a));
+ E1_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E1_b));
+ ENABLE_E1_PULLUP=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_E1_pullup))?1:0;
+ ENABLE_E2_ENCODER=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_E2_encoder))?1:0;
+ E2_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E2_a));
+ E2_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(E2_b));
+ ENABLE_E2_PULLUP=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_E2_pullup))?1:0;
+ ENABLE_E3_ENCODER=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_S6_encoder))?1:0;
+ E3_ENCODER_A=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(S6_a));
+ E3_ENCODER_B=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(S6_b));
+ ENABLE_E3_PULLUP=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_S6_pullup))?1:0;
+ ENABLE_S1_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_S1))?1:0;
+ S1_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(S1));
+ ENABLE_S2_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_S2))?1:0;
+ S2_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(S2));
+ ENABLE_S3_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_S3))?1:0;
+ S3_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(S3));
+ ENABLE_S4_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_S4))?1:0;
+ S4_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(S4));
+ ENABLE_S5_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_S5))?1:0;
+ S5_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(S5));
+ ENABLE_S6_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_S6))?1:0;
+ S6_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(S6));
ENABLE_MOX_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_mox))?1:0;
MOX_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(mox));
ENABLE_FUNCTION_BUTTON=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_enable_function))?1:0;
CWL_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(cwl));
CWR_BUTTON=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(cwr));
#endif
+*/
gtk_widget_destroy(dialog);
- gpio_save_state();
+// gpio_save_state();
+
}
#endif
#include "bandstack.h"
#include "filter.h"
#include "radio.h"
+#include "receiver.h"
static GtkWidget *parent_window=NULL;
static void cw_keyer_sidetone_frequency_value_changed_cb(GtkWidget *widget, gpointer data) {
cw_keyer_sidetone_frequency=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
- if(mode==modeCWL || mode==modeCWU) {
+/*
+ if(transmitter->mode==modeCWL || transmitter->mode==modeCWU) {
BANDSTACK_ENTRY *entry=bandstack_entry_get_current();
FILTER* band_filters=filters[entry->mode];
FILTER* band_filter=&band_filters[entry->filter];
- setFilter(band_filter->low,band_filter->high);
+ //setFilter(band_filter->low,band_filter->high);
+ set_filter(active_receiver,band_filter->low,band_filter->high);
}
+*/
cw_changed();
}
#define MAX_DEVICES 16
+
#define DEVICE_METIS 0
#define DEVICE_HERMES 1
#define DEVICE_GRIFFIN 2
#define DEVICE_ANGELIA 4
#define DEVICE_ORION 5
#define DEVICE_HERMES_LITE 6
+// 8000DLE uses 10 as the device type in old protocol
+#define DEVICE_ORION2 10
+
+#ifdef USBOZY
+#define DEVICE_OZY 7
+#endif
#define NEW_DEVICE_ATLAS 0
#define NEW_DEVICE_HERMES 1
--- /dev/null
+/* Copyright (C)
+* 2015 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*/
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <math.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <semaphore.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "discovered.h"
+#include "discovery.h"
+#include "main.h"
+#include "radio.h"
+#ifdef USBOZY
+#include "ozyio.h"
+#endif
+
+static GtkWidget *discovery_dialog;
+static DISCOVERED *d;
+
+int discovery(void *data);
+
+static gboolean start_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+fprintf(stderr,"start_cb: %p\n",data);
+ radio=(DISCOVERED *)data;
+ gtk_widget_destroy(discovery_dialog);
+ start_radio();
+ return TRUE;
+}
+
+#ifdef GPIO
+static gboolean gpio_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ configure_gpio(discovery_dialog);
+ return TRUE;
+}
+#endif
+
+static gboolean discover_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ gtk_widget_destroy(discovery_dialog);
+ g_idle_add(discovery,NULL);
+ return TRUE;
+}
+
+static gboolean exit_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ gtk_widget_destroy(discovery_dialog);
+ _exit(0);
+ return TRUE;
+}
+
+int discovery(void *data) {
+fprintf(stderr,"discovery\n");
+ selected_device=0;
+ devices=0;
+
+#ifdef USBOZY
+//
+// first: look on USB for an Ozy
+//
+ fprintf(stderr,"looking for USB based OZY devices\n");
+
+ if (ozy_discover() != 0)
+ {
+ discovered[devices].protocol = ORIGINAL_PROTOCOL;
+ discovered[devices].device = DEVICE_OZY;
+ discovered[devices].software_version = 10; // we can't know yet so this isn't a real response
+ discovered[devices].status = STATE_AVAILABLE;
+ strcpy(discovered[devices].name,"Ozy on USB");
+
+ strcpy(discovered[devices].info.network.interface_name,"USB");
+ devices++;
+ }
+#endif
+
+
+ status_text("Old Protocol ... Discovering Devices");
+ old_discovery();
+
+ status_text("New Protocol ... Discovering Devices");
+ new_discovery();
+
+#ifdef LIMESDR
+ status_text("LimeSDR ... Discovering Devices");
+ lime_discovery();
+#endif
+
+
+ if(devices==0) {
+ gdk_window_set_cursor(gtk_widget_get_window(top_window),gdk_cursor_new(GDK_ARROW));
+ discovery_dialog = gtk_dialog_new();
+ gtk_window_set_transient_for(GTK_WINDOW(discovery_dialog),GTK_WINDOW(top_window));
+ gtk_window_set_decorated(GTK_WINDOW(discovery_dialog),FALSE);
+
+ gtk_widget_override_font(discovery_dialog, pango_font_description_from_string("FreeMono 16"));
+
+ GdkRGBA color;
+ color.red = 1.0;
+ color.green = 1.0;
+ color.blue = 1.0;
+ color.alpha = 1.0;
+ gtk_widget_override_background_color(discovery_dialog,GTK_STATE_FLAG_NORMAL,&color);
+
+ GtkWidget *content;
+
+ content=gtk_dialog_get_content_area(GTK_DIALOG(discovery_dialog));
+
+ GtkWidget *grid=gtk_grid_new();
+ gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
+ gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
+ gtk_grid_set_row_spacing (GTK_GRID(grid),10);
+
+ GtkWidget *label=gtk_label_new("No devices found!");
+ gtk_grid_attach(GTK_GRID(grid),label,0,0,2,1);
+
+ GtkWidget *exit_b=gtk_button_new_with_label("Exit");
+ g_signal_connect (exit_b, "button-press-event", G_CALLBACK(exit_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),exit_b,0,1,1,1);
+
+ GtkWidget *discover_b=gtk_button_new_with_label("Retry Discovery");
+ g_signal_connect (discover_b, "button-press-event", G_CALLBACK(discover_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),discover_b,1,1,1,1);
+
+ gtk_container_add (GTK_CONTAINER (content), grid);
+ gtk_widget_show_all(discovery_dialog);
+ } else {
+ fprintf(stderr,"discovery: found %d devices\n", devices);
+ gdk_window_set_cursor(gtk_widget_get_window(top_window),gdk_cursor_new(GDK_ARROW));
+ discovery_dialog = gtk_dialog_new();
+ gtk_window_set_transient_for(GTK_WINDOW(discovery_dialog),GTK_WINDOW(top_window));
+ gtk_window_set_decorated(GTK_WINDOW(discovery_dialog),FALSE);
+
+ gtk_widget_override_font(discovery_dialog, pango_font_description_from_string("FreeMono 16"));
+
+ GdkRGBA color;
+ color.red = 1.0;
+ color.green = 1.0;
+ color.blue = 1.0;
+ color.alpha = 1.0;
+ gtk_widget_override_background_color(discovery_dialog,GTK_STATE_FLAG_NORMAL,&color);
+
+ GtkWidget *content;
+
+ content=gtk_dialog_get_content_area(GTK_DIALOG(discovery_dialog));
+
+ GtkWidget *grid=gtk_grid_new();
+ gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
+ gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
+ gtk_grid_set_row_spacing (GTK_GRID(grid),10);
+
+ int i;
+ char version[16];
+ char text[128];
+ for(i=0;i<devices;i++) {
+ d=&discovered[i];
+fprintf(stderr,"%p protocol=%d name=%s\n",d,d->protocol,d->name);
+ if(d->protocol==ORIGINAL_PROTOCOL) {
+ sprintf(version,"%d.%d",
+ d->software_version/10,
+ d->software_version%10);
+ } else {
+ sprintf(version,"%d.%d",
+ d->software_version/10,
+ d->software_version%10);
+ }
+ switch(d->protocol) {
+ case ORIGINAL_PROTOCOL:
+ case NEW_PROTOCOL:
+#ifdef USBOZY
+ if(d->device==DEVICE_OZY) {
+ sprintf(text,"%s (%s) on USB /dev/ozy\n", d->name, d->protocol==ORIGINAL_PROTOCOL?"old":"new");
+ } else {
+#endif
+ sprintf(text,"%s (%s %s) %s (%02X:%02X:%02X:%02X:%02X:%02X) on %s\n",
+ d->name,
+ d->protocol==ORIGINAL_PROTOCOL?"old":"new",
+ version,
+ 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);
+#ifdef USBOZY
+ }
+#endif
+ break;
+#ifdef LIMESDR
+ case LIMESDR_PROTOCOL:
+ sprintf(text,"%s\n",
+ d->name);
+ break;
+#endif
+ }
+
+ GtkWidget *label=gtk_label_new(text);
+ gtk_widget_override_font(label, pango_font_description_from_string("FreeMono 12"));
+ gtk_widget_show(label);
+ gtk_grid_attach(GTK_GRID(grid),label,0,i,3,1);
+
+ GtkWidget *start_button=gtk_button_new_with_label("Start");
+ gtk_widget_override_font(start_button, pango_font_description_from_string("FreeMono 18"));
+ gtk_widget_show(start_button);
+ gtk_grid_attach(GTK_GRID(grid),start_button,3,i,1,1);
+ g_signal_connect(start_button,"button_press_event",G_CALLBACK(start_cb),(gpointer)d);
+
+ // if not available then cannot start it
+ if(d->status!=STATE_AVAILABLE) {
+ gtk_button_set_label(GTK_BUTTON(start_button),"In Use");
+ gtk_widget_set_sensitive(start_button, FALSE);
+ }
+
+ // if not on the same subnet then cannot start it
+ 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);
+ }
+
+ }
+#ifdef GPIO
+ GtkWidget *gpio_b=gtk_button_new_with_label("Config GPIO");
+ g_signal_connect (gpio_b, "button-press-event", G_CALLBACK(gpio_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),gpio_b,0,i,1,1);
+#endif
+ GtkWidget *discover_b=gtk_button_new_with_label("Discover");
+ g_signal_connect (discover_b, "button-press-event", G_CALLBACK(discover_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),discover_b,1,i,1,1);
+
+ GtkWidget *exit_b=gtk_button_new_with_label("Exit");
+ g_signal_connect (exit_b, "button-press-event", G_CALLBACK(exit_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),exit_b,2,i,1,1);
+
+ gtk_container_add (GTK_CONTAINER (content), grid);
+ gtk_widget_show_all(discovery_dialog);
+fprintf(stderr,"showing device dialog\n");
+ }
+
+ return 0;
+
+}
+
+
--- /dev/null
+/* Copyright (C)
+* 2015 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*/
+
+int discovery(void *data);
static void detector_mode_cb(GtkWidget *widget, gpointer data) {
display_detector_mode=(int)data;
- SetDisplayDetectorMode(CHANNEL_RX0, 0, display_detector_mode);
+ SetDisplayDetectorMode(active_receiver->id, 0, display_detector_mode);
}
static void average_mode_cb(GtkWidget *widget, gpointer data) {
display_average_mode=(int)data;
- SetDisplayAverageMode(CHANNEL_RX0, 0, display_average_mode);
+ SetDisplayAverageMode(active_receiver->id, 0, display_average_mode);
}
static void time_value_changed_cb(GtkWidget *widget, gpointer data) {
display_average_time=gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget));
- calculate_display_average();
- //SetDisplayAvBackmult(CHANNEL_RX0, 0, display_avb);
- //SetDisplayNumAverage(CHANNEL_RX0, 0, display_average);
+ calculate_display_average(active_receiver);
}
static void filled_cb(GtkWidget *widget, gpointer data) {
static void frames_per_second_value_changed_cb(GtkWidget *widget, gpointer data) {
updates_per_second=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
- calculate_display_average();
+ calculate_display_average(active_receiver);
}
static void panadapter_high_value_changed_cb(GtkWidget *widget, gpointer data) {
- panadapter_high=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
+ active_receiver->panadapter_high=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
}
static void panadapter_low_value_changed_cb(GtkWidget *widget, gpointer data) {
- panadapter_low=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
+ active_receiver->panadapter_low=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
}
static void waterfall_high_value_changed_cb(GtkWidget *widget, gpointer data) {
- waterfall_high=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
+ active_receiver->waterfall_high=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
}
static void waterfall_low_value_changed_cb(GtkWidget *widget, gpointer data) {
- waterfall_low=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
+ active_receiver->waterfall_low=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
}
static void waterfall_automatic_cb(GtkWidget *widget, gpointer data) {
- waterfall_automatic=waterfall_automatic==1?0:1;
+ active_receiver->waterfall_automatic=active_receiver->waterfall_automatic==1?0:1;
}
static void display_panadapter_cb(GtkWidget *widget, gpointer data) {
- display_panadapter=display_panadapter==1?0:1;
- reconfigure_display();
+ active_receiver->display_panadapter=active_receiver->display_panadapter==1?0:1;
+ reconfigure_radio();
}
static void display_waterfall_cb(GtkWidget *widget, gpointer data) {
- display_waterfall=display_waterfall==1?0:1;
- reconfigure_display();
+ active_receiver->display_waterfall=active_receiver->display_waterfall==1?0:1;
+ reconfigure_radio();
}
static void display_sliders_cb(GtkWidget *widget, gpointer data) {
display_sliders=display_sliders==1?0:1;
- reconfigure_display();
+ reconfigure_radio();
}
+/*
static void display_toolbar_cb(GtkWidget *widget, gpointer data) {
display_toolbar=display_toolbar==1?0:1;
- reconfigure_display();
+ reconfigure_radio();
}
-
-static void toolbar_dialog_buttons_cb(GtkWidget *widget, gpointer data) {
- toolbar_dialog_buttons=toolbar_dialog_buttons==1?0:1;
- update_toolbar_labels();
-}
-
+*/
void display_menu(GtkWidget *parent) {
int i;
GtkWidget *panadapter_high_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0);
//gtk_widget_override_font(panadapter_high_r, pango_font_description_from_string("Arial 18"));
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(panadapter_high_r),(double)panadapter_high);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(panadapter_high_r),(double)active_receiver->panadapter_high);
gtk_widget_show(panadapter_high_r);
gtk_grid_attach(GTK_GRID(grid),panadapter_high_r,1,3,1,1);
g_signal_connect(panadapter_high_r,"value_changed",G_CALLBACK(panadapter_high_value_changed_cb),NULL);
GtkWidget *panadapter_low_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0);
//gtk_widget_override_font(panadapter_low_r, pango_font_description_from_string("Arial 18"));
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(panadapter_low_r),(double)panadapter_low);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(panadapter_low_r),(double)active_receiver->panadapter_low);
gtk_widget_show(panadapter_low_r);
gtk_grid_attach(GTK_GRID(grid),panadapter_low_r,1,4,1,1);
g_signal_connect(panadapter_low_r,"value_changed",G_CALLBACK(panadapter_low_value_changed_cb),NULL);
GtkWidget *waterfall_automatic_b=gtk_check_button_new();
//gtk_widget_override_font(waterfall_automatic_b, pango_font_description_from_string("Arial 18"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (waterfall_automatic_b), waterfall_automatic);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (waterfall_automatic_b), active_receiver->waterfall_automatic);
gtk_widget_show(waterfall_automatic_b);
gtk_grid_attach(GTK_GRID(grid),waterfall_automatic_b,1,5,1,1);
g_signal_connect(waterfall_automatic_b,"toggled",G_CALLBACK(waterfall_automatic_cb),NULL);
GtkWidget *waterfall_high_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0);
//gtk_widget_override_font(waterfall_high_r, pango_font_description_from_string("Arial 18"));
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(waterfall_high_r),(double)waterfall_high);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(waterfall_high_r),(double)active_receiver->waterfall_high);
gtk_widget_show(waterfall_high_r);
gtk_grid_attach(GTK_GRID(grid),waterfall_high_r,1,6,1,1);
g_signal_connect(waterfall_high_r,"value_changed",G_CALLBACK(waterfall_high_value_changed_cb),NULL);
GtkWidget *waterfall_low_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0);
//gtk_widget_override_font(waterfall_low_r, pango_font_description_from_string("Arial 18"));
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(waterfall_low_r),(double)waterfall_low);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(waterfall_low_r),(double)active_receiver->waterfall_low);
gtk_widget_show(waterfall_low_r);
gtk_grid_attach(GTK_GRID(grid),waterfall_low_r,1,7,1,1);
g_signal_connect(waterfall_low_r,"value_changed",G_CALLBACK(waterfall_low_value_changed_cb),NULL);
gtk_grid_attach(GTK_GRID(grid),time_r,4,6,1,1);
g_signal_connect(time_r,"value_changed",G_CALLBACK(time_value_changed_cb),NULL);
+/*
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);
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_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_display_waterfall), active_receiver->display_waterfall);
gtk_widget_show(b_display_waterfall);
gtk_grid_attach(GTK_GRID(grid),b_display_waterfall,1,8,1,1);
g_signal_connect(b_display_waterfall,"toggled",G_CALLBACK(display_waterfall_cb),(gpointer *)NULL);
gtk_grid_attach(GTK_GRID(grid),b_display_sliders,2,8,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,3,8,1,1);
g_signal_connect(b_display_toolbar,"toggled",G_CALLBACK(display_toolbar_cb),(gpointer *)NULL);
-
- GtkWidget *b_toolbar_dialog_buttons=gtk_check_button_new_with_label("Buttons Display Dialog");
- //gtk_widget_override_font(b_toolbar_dialog_buttons, pango_font_description_from_string("Arial 18"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_toolbar_dialog_buttons), toolbar_dialog_buttons);
- gtk_widget_show(b_toolbar_dialog_buttons);
- gtk_grid_attach(GTK_GRID(grid),b_toolbar_dialog_buttons,0,9,1,1);
- g_signal_connect(b_toolbar_dialog_buttons,"toggled",G_CALLBACK(toolbar_dialog_buttons_cb),(gpointer *)NULL);
-
+*/
gtk_container_add(GTK_CONTAINER(content),grid);
sub_menu=dialog;
#include "agc.h"
#include "channel.h"
#include "radio.h"
+#include "receiver.h"
#include "wdsp.h"
static GtkWidget *parent_window=NULL;
}
static void agc_hang_threshold_value_changed_cb(GtkWidget *widget, gpointer data) {
- agc_hang_threshold=(int)gtk_range_get_value(GTK_RANGE(widget));
- if(agc==AGC_LONG || agc==AGC_SLOW) {
- SetRXAAGCHangThreshold(CHANNEL_RX0, (int)agc_hang_threshold);
+ active_receiver->agc_hang_threshold=(int)gtk_range_get_value(GTK_RANGE(widget));
+ if(active_receiver->agc==AGC_LONG || active_receiver->agc==AGC_SLOW) {
+ SetRXAAGCHangThreshold(active_receiver->id, (int)active_receiver->agc_hang_threshold);
}
}
static void pre_post_agc_cb(GtkWidget *widget, gpointer data) {
- nr_agc=(int)data;
- SetRXAEMNRPosition(CHANNEL_RX0, nr_agc);
+ active_receiver->nr_agc=(int)data;
+ SetRXAEMNRPosition(active_receiver->id, active_receiver->nr_agc);
}
static void nr2_gain_cb(GtkWidget *widget, gpointer data) {
- nr2_gain_method==(int)data;
- SetRXAEMNRgainMethod(CHANNEL_RX0, nr2_gain_method);
+ active_receiver->nr2_gain_method==(int)data;
+ SetRXAEMNRgainMethod(active_receiver->id, active_receiver->nr2_gain_method);
}
static void nr2_npe_method_cb(GtkWidget *widget, gpointer data) {
- nr2_npe_method=(int)data;
- SetRXAEMNRnpeMethod(CHANNEL_RX0, nr2_npe_method);
+ active_receiver->nr2_npe_method=(int)data;
+ SetRXAEMNRnpeMethod(active_receiver->id, active_receiver->nr2_npe_method);
}
static void ae_cb(GtkWidget *widget, gpointer data) {
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
- nr2_ae=1;
+ active_receiver->nr2_ae=1;
} else {
- nr2_ae=0;
+ active_receiver->nr2_ae=0;
}
- SetRXAEMNRaeRun(CHANNEL_RX0, nr2_ae);
+ SetRXAEMNRaeRun(active_receiver->id, active_receiver->nr2_ae);
}
void dsp_menu(GtkWidget *parent) {
gtk_widget_show(agc_hang_threshold_label);
gtk_grid_attach(GTK_GRID(grid),agc_hang_threshold_label,0,1,1,1);
GtkWidget *agc_hang_threshold_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0.0, 100.0, 1.0);
- gtk_range_set_value (GTK_RANGE(agc_hang_threshold_scale),agc_hang_threshold);
+ gtk_range_set_value (GTK_RANGE(agc_hang_threshold_scale),active_receiver->agc_hang_threshold);
gtk_widget_show(agc_hang_threshold_scale);
gtk_grid_attach(GTK_GRID(grid),agc_hang_threshold_scale,1,1,2,1);
g_signal_connect(G_OBJECT(agc_hang_threshold_scale),"value_changed",G_CALLBACK(agc_hang_threshold_value_changed_cb),NULL);
gtk_grid_attach(GTK_GRID(grid),pre_post_agc_label,0,2,1,1);
GtkWidget *pre_agc_b=gtk_radio_button_new_with_label(NULL,"Pre AGC");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pre_agc_b),nr_agc==0);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pre_agc_b),active_receiver->nr_agc==0);
gtk_widget_show(pre_agc_b);
gtk_grid_attach(GTK_GRID(grid),pre_agc_b,1,2,1,1);
g_signal_connect(pre_agc_b,"pressed",G_CALLBACK(pre_post_agc_cb),(gpointer *)0);
GtkWidget *post_agc_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(pre_agc_b),"Post AGC");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (post_agc_b), nr_agc==1);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (post_agc_b), active_receiver->nr_agc==1);
gtk_widget_show(post_agc_b);
gtk_grid_attach(GTK_GRID(grid),post_agc_b,2,2,1,1);
g_signal_connect(post_agc_b,"pressed",G_CALLBACK(pre_post_agc_cb),(gpointer *)1);
gtk_grid_attach(GTK_GRID(grid),nr2_gain_label,0,3,1,1);
GtkWidget *linear_b=gtk_radio_button_new_with_label(NULL,"Linear");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linear_b),nr2_gain_method==0);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linear_b),active_receiver->nr2_gain_method==0);
gtk_widget_show(linear_b);
gtk_grid_attach(GTK_GRID(grid),linear_b,1,3,1,1);
g_signal_connect(linear_b,"pressed",G_CALLBACK(nr2_gain_cb),(gpointer *)0);
GtkWidget *log_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(linear_b),"Log");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (log_b), nr2_gain_method==1);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (log_b), active_receiver->nr2_gain_method==1);
gtk_widget_show(log_b);
gtk_grid_attach(GTK_GRID(grid),log_b,2,3,1,1);
g_signal_connect(log_b,"pressed",G_CALLBACK(nr2_gain_cb),(gpointer *)1);
GtkWidget *gamma_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(log_b),"Gamma");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gamma_b), nr2_gain_method==2);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gamma_b), active_receiver->nr2_gain_method==2);
gtk_widget_show(gamma_b);
gtk_grid_attach(GTK_GRID(grid),gamma_b,3,3,1,1);
g_signal_connect(gamma_b,"pressed",G_CALLBACK(nr2_gain_cb),(gpointer *)2);
gtk_grid_attach(GTK_GRID(grid),nr2_npe_method_label,0,4,1,1);
GtkWidget *osms_b=gtk_radio_button_new_with_label(NULL,"OSMS");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (osms_b),nr2_npe_method==0);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (osms_b),active_receiver->nr2_npe_method==0);
gtk_widget_show(osms_b);
gtk_grid_attach(GTK_GRID(grid),osms_b,1,4,1,1);
g_signal_connect(osms_b,"pressed",G_CALLBACK(nr2_npe_method_cb),(gpointer *)0);
GtkWidget *mmse_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(osms_b),"MMSE");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mmse_b), nr2_npe_method==1);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mmse_b), active_receiver->nr2_npe_method==1);
gtk_widget_show(mmse_b);
gtk_grid_attach(GTK_GRID(grid),mmse_b,2,4,1,1);
g_signal_connect(mmse_b,"pressed",G_CALLBACK(nr2_npe_method_cb),(gpointer *)1);
GtkWidget *ae_b=gtk_check_button_new_with_label("NR2 AE Filter");
//gtk_widget_override_font(ae_b, pango_font_description_from_string("Arial 18"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ae_b), nr2_ae);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ae_b), active_receiver->nr2_ae);
gtk_widget_show(ae_b);
gtk_grid_attach(GTK_GRID(grid),ae_b,0,5,1,1);
g_signal_connect(ae_b,"toggled",G_CALLBACK(ae_cb),NULL);
--- /dev/null
+/* 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 <gtk/gtk.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "main.h"
+#include "new_menu.h"
+#include "agc_menu.h"
+#include "agc.h"
+#include "band.h"
+#include "channel.h"
+#include "radio.h"
+#include "receiver.h"
+#include "vfo.h"
+#include "button_text.h"
+#include "gpio.h"
+
+static GtkWidget *parent_window=NULL;
+
+static GtkWidget *dialog=NULL;
+
+static GtkWidget *b_af_gain;
+static GtkWidget *b_agc_gain;
+static GtkWidget *b_attenuation;
+static GtkWidget *b_mic_gain;
+static GtkWidget *b_drive;
+static GtkWidget *b_tune_drive;
+static GtkWidget *b_rit;
+static GtkWidget *b_cw_speed;
+static GtkWidget *b_cw_frequency;
+static GtkWidget *b_panadapter_high;
+static GtkWidget *b_panadapter_low;
+
+static int encoder;
+
+
+static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ if(dialog!=NULL) {
+ gtk_widget_destroy(dialog);
+ dialog=NULL;
+ sub_menu=NULL;
+ }
+ active_menu=NO_MENU;
+ return TRUE;
+}
+
+void encoder_select(int pos) {
+ int action;
+ GtkWidget *button;
+ switch(encoder) {
+ case 1:
+ if(pos>0) {
+ e1_encoder_action--;
+ if(e1_encoder_action<0) {
+ e1_encoder_action=ENCODER_LAST;
+ }
+ } if(pos<0) {
+ e1_encoder_action++;
+ if(e1_encoder_action>ENCODER_LAST) {
+ e1_encoder_action=0;
+ }
+ }
+ action=e1_encoder_action;
+ break;
+ case 2:
+ if(pos>0) {
+ e2_encoder_action--;
+ if(e2_encoder_action<0) {
+ e2_encoder_action=ENCODER_LAST;
+ }
+ } if(pos<0) {
+ e2_encoder_action++;
+ if(e2_encoder_action>ENCODER_LAST) {
+ e2_encoder_action=0;
+ }
+ }
+ action=e2_encoder_action;
+ break;
+ case 3:
+ if(pos>0) {
+ e3_encoder_action--;
+ if(e3_encoder_action<0) {
+ e3_encoder_action=ENCODER_LAST;
+ }
+ } if(pos<0) {
+ e3_encoder_action++;
+ if(e3_encoder_action>ENCODER_LAST) {
+ e3_encoder_action=0;
+ }
+ }
+ action=e3_encoder_action;
+ break;
+ }
+
+ switch(action) {
+ case ENCODER_AF_GAIN:
+ button=b_af_gain;
+ break;
+ case ENCODER_AGC_GAIN:
+ button=b_agc_gain;
+ break;
+ case ENCODER_ATTENUATION:
+ button=b_attenuation;
+ break;
+ case ENCODER_MIC_GAIN:
+ button=b_mic_gain;
+ break;
+ case ENCODER_DRIVE:
+ button=b_drive;
+ break;
+ case ENCODER_TUNE_DRIVE:
+ button=b_tune_drive;
+ break;
+ case ENCODER_RIT:
+ button=b_rit;
+ break;
+ case ENCODER_CW_SPEED:
+ button=b_cw_speed;
+ break;
+ case ENCODER_CW_FREQUENCY:
+ button=b_cw_frequency;
+ break;
+ case ENCODER_PANADAPTER_HIGH:
+ button=b_panadapter_high;
+ break;
+ case ENCODER_PANADAPTER_LOW:
+ button=b_panadapter_low;
+ break;
+ }
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+
+}
+
+static gboolean action_select_cb (GtkWidget *widget, gpointer data) {
+ int action=(int)data;
+ switch(encoder) {
+ case 1:
+ e1_encoder_action=action;
+ break;
+ case 2:
+ e2_encoder_action=action;
+ break;
+ case 3:
+ e3_encoder_action=action;
+ break;
+ }
+}
+
+void encoder_menu(GtkWidget *parent,int e) {
+ GtkWidget *b;
+ int i;
+ BAND *band;
+
+ encoder=e;
+
+ int encoder_action;
+ switch(encoder) {
+ case 1:
+ encoder_action=e1_encoder_action;
+ break;
+ case 2:
+ encoder_action=e2_encoder_action;
+ break;
+ case 3:
+ encoder_action=e3_encoder_action;
+ break;
+ }
+ parent_window=parent;
+
+ dialog=gtk_dialog_new();
+ gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window));
+ gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE);
+
+ GdkRGBA color;
+ color.red = 1.0;
+ color.green = 1.0;
+ color.blue = 1.0;
+ color.alpha = 1.0;
+ gtk_widget_override_background_color(dialog,GTK_STATE_FLAG_NORMAL,&color);
+
+ GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+
+ GtkWidget *grid=gtk_grid_new();
+
+ gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
+ gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
+ gtk_grid_set_column_spacing (GTK_GRID(grid),5);
+ gtk_grid_set_row_spacing (GTK_GRID(grid),5);
+
+ GtkWidget *close_b=gtk_button_new_with_label("Close");
+ g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1);
+
+ char label_text[32];
+ sprintf(label_text,"Encoder E%d Action:",encoder);
+ GtkWidget *label=gtk_label_new(label_text);
+ gtk_grid_attach(GTK_GRID(grid),label,0,1,2,1);
+
+ b_af_gain=gtk_radio_button_new_with_label(NULL,"AF Gain");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_af_gain), encoder_action==ENCODER_AF_GAIN);
+ gtk_widget_show(b_af_gain);
+ gtk_grid_attach(GTK_GRID(grid),b_af_gain,0,2,2,1);
+ g_signal_connect(b_af_gain,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_AF_GAIN);
+
+ b_agc_gain=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_af_gain),"AGC Gain");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_agc_gain), encoder_action==ENCODER_AGC_GAIN);
+ gtk_widget_show(b_agc_gain);
+ gtk_grid_attach(GTK_GRID(grid),b_agc_gain,0,3,2,1);
+ g_signal_connect(b_agc_gain,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_AGC_GAIN);
+
+ b_attenuation=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_agc_gain),"Attenuation");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_attenuation), encoder_action==ENCODER_ATTENUATION);
+ gtk_widget_show(b_attenuation);
+ gtk_grid_attach(GTK_GRID(grid),b_attenuation,0,4,2,1);
+ g_signal_connect(b_attenuation,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_ATTENUATION);
+
+ b_mic_gain=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_attenuation),"Mic Gain");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_mic_gain), encoder_action==ENCODER_MIC_GAIN);
+ gtk_widget_show(b_mic_gain);
+ gtk_grid_attach(GTK_GRID(grid),b_mic_gain,0,5,2,1);
+ g_signal_connect(b_mic_gain,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_MIC_GAIN);
+
+ b_drive=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_mic_gain),"Drive");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_drive), encoder_action==ENCODER_DRIVE);
+ gtk_widget_show(b_drive);
+ gtk_grid_attach(GTK_GRID(grid),b_drive,0,6,2,1);
+ g_signal_connect(b_drive,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_DRIVE);
+
+ b_tune_drive=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_drive),"Tune Drive");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_tune_drive), encoder_action==ENCODER_TUNE_DRIVE);
+ gtk_widget_show(b_tune_drive);
+ gtk_grid_attach(GTK_GRID(grid),b_tune_drive,0,7,2,1);
+ g_signal_connect(b_tune_drive,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_TUNE_DRIVE);
+
+ b_rit=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_tune_drive),"RIT");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_rit), encoder_action==ENCODER_RIT);
+ gtk_widget_show(b_rit);
+ gtk_grid_attach(GTK_GRID(grid),b_rit,2,2,2,1);
+ g_signal_connect(b_rit,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_RIT);
+
+ b_cw_speed=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_rit),"CW Speed");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_cw_speed), encoder_action==ENCODER_CW_SPEED);
+ gtk_widget_show(b_cw_speed);
+ gtk_grid_attach(GTK_GRID(grid),b_cw_speed,2,3,2,1);
+ g_signal_connect(b_cw_speed,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_CW_SPEED);
+
+ b_cw_frequency=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_cw_speed),"CW Freq");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_cw_frequency), encoder_action==ENCODER_CW_FREQUENCY);
+ gtk_widget_show(b_cw_frequency);
+ gtk_grid_attach(GTK_GRID(grid),b_cw_frequency,2,4,2,1);
+ g_signal_connect(b_cw_frequency,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_CW_FREQUENCY);
+
+ b_panadapter_high=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_cw_frequency),"Panadapter High");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_panadapter_high), encoder_action==ENCODER_PANADAPTER_HIGH);
+ gtk_widget_show(b_panadapter_high);
+ gtk_grid_attach(GTK_GRID(grid),b_panadapter_high,2,6,2,1);
+ g_signal_connect(b_panadapter_high,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_PANADAPTER_HIGH);
+
+ b_panadapter_low=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_cw_frequency),"Panadapter Low");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_panadapter_low), encoder_action==ENCODER_PANADAPTER_LOW);
+ gtk_widget_show(b_panadapter_low);
+ gtk_grid_attach(GTK_GRID(grid),b_panadapter_low,2,7,2,1);
+ g_signal_connect(b_panadapter_low,"pressed",G_CALLBACK(action_select_cb),(gpointer *)ENCODER_PANADAPTER_LOW);
+
+ gtk_container_add(GTK_CONTAINER(content),grid);
+
+ sub_menu=dialog;
+
+ gtk_widget_show_all(dialog);
+
+}
--- /dev/null
+/* 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.
+*
+*/
+
+#ifndef _ENCODER_MENU_H
+#define _ENCODER_MENU_H
+
+extern void encoder_menu(GtkWidget *parent,int e);
+
+extern void encoder_select(int pos);
+#endif
static gboolean enable_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
if(tx_menu) {
enable_tx_equalizer=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
- SetTXAEQRun(CHANNEL_TX, enable_tx_equalizer);
+ SetTXAEQRun(transmitter->id, enable_tx_equalizer);
} else {
enable_rx_equalizer=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
- SetRXAEQRun(CHANNEL_RX0, enable_rx_equalizer);
+ SetRXAEQRun(active_receiver->id, enable_rx_equalizer);
}
}
int i=(int)data;
if(tx_menu) {
tx_equalizer[i]=(int)gtk_range_get_value(GTK_RANGE(widget));
- SetTXAGrphEQ(CHANNEL_TX, tx_equalizer);
+ SetTXAGrphEQ(transmitter->id, tx_equalizer);
} else {
rx_equalizer[i]=(int)gtk_range_get_value(GTK_RANGE(widget));
- SetRXAGrphEQ(CHANNEL_RX0, rx_equalizer);
+ SetRXAGrphEQ(active_receiver->id, rx_equalizer);
}
}
*
*/
+#include <stdio.h>
#include "filter.h"
+#include "property.h"
FILTER filterLSB[FILTERS]={
{-5150,-150,"5.0k"},
{-2550,-150,"2.4k"},
{-2250,-150,"2.1k"},
{-1950,-150,"1.8k"},
- {-1150,-150,"1.0k"}/*,
+ {-1150,-150,"1.0k"},
{-2850,-150,"Var1"},
- {-2850,-150,"Var2"}*/
+ {-2850,-150,"Var2"}
};
FILTER filterDIGL[FILTERS]={
{-2550,-150,"2.4k"},
{-2250,-150,"2.1k"},
{-1950,-150,"1.8k"},
- {-1150,-150,"1.0k"}/*,
+ {-1150,-150,"1.0k"},
{-2850,-150,"Var1"},
- {-2850,-150,"Var2"}*/
+ {-2850,-150,"Var2"}
};
FILTER filterUSB[FILTERS]={
{150,2550,"2.4k"},
{150,2250,"2.1k"},
{150,1950,"1.8k"},
- {150,1150,"1.0k"}/*,
+ {150,1150,"1.0k"},
{150,2850,"Var1"},
- {150,2850,"Var2"}*/
+ {150,2850,"Var2"}
};
FILTER filterDIGU[FILTERS]={
{150,2550,"2.4k"},
{150,2250,"2.1k"},
{150,1950,"1.8k"},
- {150,1150,"1.0k"}/*,
+ {150,1150,"1.0k"},
{150,2850,"Var1"},
- {150,2850,"Var2"}*/
+ {150,2850,"Var2"}
};
FILTER filterCWL[FILTERS]={
{125,125,"250"},
{50,50,"100"},
{25,25,"50"},
- {13,13,"25"}/*,
+ {13,13,"25"},
{250,250,"Var1"},
- {250,250,"Var2"}*/
+ {250,250,"Var2"}
};
FILTER filterCWU[FILTERS]={
{125,125,"250"},
{50,50,"100"},
{25,25,"50"},
- {13,13,"25"}/*,
+ {13,13,"25"},
{250,250,"Var1"},
- {250,250,"Var2"}*/
+ {250,250,"Var2"}
};
FILTER filterAM[FILTERS]={
{-2000,2000,"4.0k"},
{-1550,1550,"3.1k"},
{-1450,1450,"2.9k"},
- {-1200,1200,"2.4k"}/*,
+ {-1200,1200,"2.4k"},
{-3300,3300,"Var1"},
- {-3300,3300,"Var2"}*/
+ {-3300,3300,"Var2"}
};
FILTER filterSAM[FILTERS]={
{-2000,2000,"4.0k"},
{-1550,1550,"3.1k"},
{-1450,1450,"2.9k"},
- {-1200,1200,"2.4k"}/*,
+ {-1200,1200,"2.4k"},
{-3300,3300,"Var1"},
- {-3300,3300,"Var2"}*/
+ {-3300,3300,"Var2"}
};
FILTER filterFMN[FILTERS]={
{-2000,2000,"4.0k"},
{-1550,1550,"3.1k"},
{-1450,1450,"2.9k"},
- {-1200,1200,"2.4k"}/*,
+ {-1200,1200,"2.4k"},
{-3300,3300,"Var1"},
- {-3300,3300,"Var2"}*/
+ {-3300,3300,"Var2"}
};
FILTER filterDSB[FILTERS]={
{-2000,2000,"4.0k"},
{-1550,1550,"3.1k"},
{-1450,1450,"2.9k"},
- {-1200,1200,"2.4k"}/*,
+ {-1200,1200,"2.4k"},
{-3300,3300,"Var1"},
- {-3300,3300,"Var2"}*/
+ {-3300,3300,"Var2"}
};
FILTER filterSPEC[FILTERS]={
{-2000,2000,"4.0k"},
{-1550,1550,"3.1k"},
{-1450,1450,"2.9k"},
- {-1200,1200,"2.4k"}/*,
+ {-1200,1200,"2.4k"},
{-3300,3300,"Var1"},
- {-3300,3300,"Var2"}*/
+ {-3300,3300,"Var2"}
};
FILTER filterDRM[FILTERS]={
{-2000,2000,"4.0k"},
{-1550,1550,"3.1k"},
{-1450,1450,"2.9k"},
- {-1200,1200,"2.4k"}/*,
+ {-1200,1200,"2.4k"},
{-3300,3300,"Var1"},
- {-3300,3300,"Var2"}*/
+ {-3300,3300,"Var2"}
};
#ifdef FREEDV
{150,2550,"2.4k"},
{150,2250,"2.1k"},
{150,1950,"1.8k"},
- {150,1150,"1.0k"}/*,
+ {150,1150,"1.0k"},
{150,2850,"Var1"},
- {150,2850,"Var2"}*/
+ {150,2850,"Var2"}
};
#endif
{150,2550,"2.4k"},
{150,2250,"2.1k"},
{150,1950,"1.8k"},
- {150,1150,"1.0k"}/*,
+ {150,1150,"1.0k"},
{150,2850,"Var1"},
- {150,2850,"Var2"}*/
+ {150,2850,"Var2"}
};
#endif
};
+void filterSaveState() {
+ char value[128];
+
+ // save the Var1 and Var2 settings
+ sprintf(value,"%d",filterLSB[filterVar1].low);
+ setProperty("filter.lsb.var1.low",value);
+ sprintf(value,"%d",filterLSB[filterVar1].high);
+ setProperty("filter.lsb.var1.high",value);
+ sprintf(value,"%d",filterLSB[filterVar2].low);
+ setProperty("filter.lsb.var2.low",value);
+ sprintf(value,"%d",filterLSB[filterVar2].high);
+ setProperty("filter.lsb.var2.high",value);
+
+ sprintf(value,"%d",filterDIGL[filterVar1].low);
+ setProperty("filter.digl.var1.low",value);
+ sprintf(value,"%d",filterDIGL[filterVar1].high);
+ setProperty("filter.digl.var1.high",value);
+ sprintf(value,"%d",filterDIGL[filterVar2].low);
+ setProperty("filter.digl.var2.low",value);
+ sprintf(value,"%d",filterDIGL[filterVar2].high);
+ setProperty("filter.digl.var2.high",value);
+
+ sprintf(value,"%d",filterCWL[filterVar1].low);
+ setProperty("filter.cwl.var1.low",value);
+ sprintf(value,"%d",filterCWL[filterVar1].high);
+ setProperty("filter.cwl.var1.high",value);
+ sprintf(value,"%d",filterCWL[filterVar2].low);
+ setProperty("filter.cwl.var2.low",value);
+ sprintf(value,"%d",filterCWL[filterVar2].high);
+ setProperty("filter.cwl.var2.high",value);
+
+ sprintf(value,"%d",filterUSB[filterVar1].low);
+ setProperty("filter.usb.var1.low",value);
+ sprintf(value,"%d",filterUSB[filterVar1].high);
+ setProperty("filter.usb.var1.high",value);
+ sprintf(value,"%d",filterUSB[filterVar2].low);
+ setProperty("filter.usb.var2.low",value);
+ sprintf(value,"%d",filterUSB[filterVar2].high);
+ setProperty("filter.usb.var2.high",value);
+
+ sprintf(value,"%d",filterDIGU[filterVar1].low);
+ setProperty("filter.digu.var1.low",value);
+ sprintf(value,"%d",filterDIGU[filterVar1].high);
+ setProperty("filter.digu.var1.high",value);
+ sprintf(value,"%d",filterDIGU[filterVar2].low);
+ setProperty("filter.digu.var2.low",value);
+ sprintf(value,"%d",filterDIGU[filterVar2].high);
+ setProperty("filter.digu.var2.high",value);
+
+ sprintf(value,"%d",filterCWU[filterVar1].low);
+ setProperty("filter.cwu.var1.low",value);
+ sprintf(value,"%d",filterCWU[filterVar1].high);
+ setProperty("filter.cwu.var1.high",value);
+ sprintf(value,"%d",filterCWU[filterVar2].low);
+ setProperty("filter.cwu.var2.low",value);
+ sprintf(value,"%d",filterCWU[filterVar2].high);
+ setProperty("filter.cwu.var2.high",value);
+
+ sprintf(value,"%d",filterAM[filterVar1].low);
+ setProperty("filter.am.var1.low",value);
+ sprintf(value,"%d",filterAM[filterVar1].high);
+ setProperty("filter.am.var1.high",value);
+ sprintf(value,"%d",filterAM[filterVar2].low);
+ setProperty("filter.am.var2.low",value);
+ sprintf(value,"%d",filterAM[filterVar2].high);
+ setProperty("filter.am.var2.high",value);
+
+ sprintf(value,"%d",filterSAM[filterVar1].low);
+ setProperty("filter.sam.var1.low",value);
+ sprintf(value,"%d",filterSAM[filterVar1].high);
+ setProperty("filter.sam.var1.high",value);
+ sprintf(value,"%d",filterSAM[filterVar2].low);
+ setProperty("filter.sam.var2.low",value);
+ sprintf(value,"%d",filterSAM[filterVar2].high);
+ setProperty("filter.sam.var2.high",value);
+
+ sprintf(value,"%d",filterFMN[filterVar1].low);
+ setProperty("filter.fmn.var1.low",value);
+ sprintf(value,"%d",filterFMN[filterVar1].high);
+ setProperty("filter.fmn.var1.high",value);
+ sprintf(value,"%d",filterFMN[filterVar2].low);
+ setProperty("filter.fmn.var2.low",value);
+ sprintf(value,"%d",filterFMN[filterVar2].high);
+ setProperty("filter.fmn.var2.high",value);
+
+ sprintf(value,"%d",filterDSB[filterVar1].low);
+ setProperty("filter.dsb.var1.low",value);
+ sprintf(value,"%d",filterDSB[filterVar1].high);
+ setProperty("filter.dsb.var1.high",value);
+ sprintf(value,"%d",filterDSB[filterVar2].low);
+ setProperty("filter.dsb.var2.low",value);
+ sprintf(value,"%d",filterDSB[filterVar2].high);
+ setProperty("filter.dsb.var2.high",value);
+
+}
+
+void filterRestoreState() {
+ char* value;
+
+ value=getProperty("filter.lsb.var1.low");
+ if(value) filterLSB[filterVar1].low=atoi(value);
+ value=getProperty("filter.lsb.var1.high");
+ if(value) filterLSB[filterVar1].high=atoi(value);
+ value=getProperty("filter.lsb.var2.low");
+ if(value) filterLSB[filterVar2].low=atoi(value);
+ value=getProperty("filter.lsb.var2.high");
+ if(value) filterLSB[filterVar2].high=atoi(value);
+
+ value=getProperty("filter.digl.var1.low");
+ if(value) filterDIGL[filterVar1].low=atoi(value);
+ value=getProperty("filter.digl.var1.high");
+ if(value) filterDIGL[filterVar1].high=atoi(value);
+ value=getProperty("filter.digl.var2.low");
+ if(value) filterDIGL[filterVar2].low=atoi(value);
+ value=getProperty("filter.digl.var2.high");
+ if(value) filterDIGL[filterVar2].high=atoi(value);
+
+ value=getProperty("filter.cwl.var1.low");
+ if(value) filterCWL[filterVar1].low=atoi(value);
+ value=getProperty("filter.cwl.var1.high");
+ if(value) filterCWL[filterVar1].high=atoi(value);
+ value=getProperty("filter.cwl.var2.low");
+ if(value) filterCWL[filterVar2].low=atoi(value);
+ value=getProperty("filter.cwl.var2.high");
+ if(value) filterCWL[filterVar2].high=atoi(value);
+
+ value=getProperty("filter.usb.var1.low");
+ if(value) filterUSB[filterVar1].low=atoi(value);
+ value=getProperty("filter.usb.var1.high");
+ if(value) filterUSB[filterVar1].high=atoi(value);
+ value=getProperty("filter.usb.var2.low");
+ if(value) filterUSB[filterVar2].low=atoi(value);
+ value=getProperty("filter.usb.var2.high");
+ if(value) filterUSB[filterVar2].high=atoi(value);
+
+ value=getProperty("filter.digu.var1.low");
+ if(value) filterDIGU[filterVar1].low=atoi(value);
+ value=getProperty("filter.digu.var1.high");
+ if(value) filterDIGU[filterVar1].high=atoi(value);
+ value=getProperty("filter.digu.var2.low");
+ if(value) filterDIGU[filterVar2].low=atoi(value);
+ value=getProperty("filter.digu.var2.high");
+ if(value) filterDIGU[filterVar2].high=atoi(value);
+
+ value=getProperty("filter.cwu.var1.low");
+ if(value) filterCWU[filterVar1].low=atoi(value);
+ value=getProperty("filter.cwu.var1.high");
+ if(value) filterCWU[filterVar1].high=atoi(value);
+ value=getProperty("filter.cwu.var2.low");
+ if(value) filterCWU[filterVar2].low=atoi(value);
+ value=getProperty("filter.cwu.var2.high");
+ if(value) filterCWU[filterVar2].high=atoi(value);
+
+ value=getProperty("filter.am.var1.low");
+ if(value) filterAM[filterVar1].low=atoi(value);
+ value=getProperty("filter.am.var1.high");
+ if(value) filterAM[filterVar1].high=atoi(value);
+ value=getProperty("filter.am.var2.low");
+ if(value) filterAM[filterVar2].low=atoi(value);
+ value=getProperty("filter.am.var2.high");
+ if(value) filterAM[filterVar2].high=atoi(value);
+
+ value=getProperty("filter.sam.var1.low");
+ if(value) filterSAM[filterVar1].low=atoi(value);
+ value=getProperty("filter.sam.var1.high");
+ if(value) filterSAM[filterVar1].high=atoi(value);
+ value=getProperty("filter.sam.var2.low");
+ if(value) filterSAM[filterVar2].low=atoi(value);
+ value=getProperty("filter.sam.var2.high");
+ if(value) filterSAM[filterVar2].high=atoi(value);
+
+ value=getProperty("filter.fmn.var1.low");
+ if(value) filterFMN[filterVar1].low=atoi(value);
+ value=getProperty("filter.fmn.var1.high");
+ if(value) filterFMN[filterVar1].high=atoi(value);
+ value=getProperty("filter.fmn.var2.low");
+ if(value) filterFMN[filterVar2].low=atoi(value);
+ value=getProperty("filter.fmn.var2.high");
+ if(value) filterFMN[filterVar2].high=atoi(value);
+
+ value=getProperty("filter.dsb.var1.low");
+ if(value) filterDSB[filterVar1].low=atoi(value);
+ value=getProperty("filter.dsb.var1.high");
+ if(value) filterDSB[filterVar1].high=atoi(value);
+ value=getProperty("filter.dsb.var2.low");
+ if(value) filterDSB[filterVar2].low=atoi(value);
+ value=getProperty("filter.dsb.var2.high");
+ if(value) filterDSB[filterVar2].high=atoi(value);
+
+}
+
#include "mode.h"
-// disable Var1 and Var2 (change to 12 to enable)
-#define FILTERS 10
+#define FILTERS 12
#define CW_PITCH 600
int txFilterLowCut;
int txFilterHighCut;
-int filterVar1Low;
-int filterVar1High;
-int filterVar2Low;
-int filterVar2High;
-
-
FILTER *filters[MODES];
+void filterSaveState();
+void filterRestoreState();
#endif
-/* 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
#include "filter.h"
#include "mode.h"
#include "radio.h"
+#include "receiver.h"
#include "vfo.h"
#include "button_text.h"
-#include "wdsp_init.h"
static GtkWidget *parent_window=NULL;
return TRUE;
}
-static gboolean filter_select_cb (GtkWidget *widget, gpointer data) {
+int filter_select(void *data) {
int f=(int)data;
- BANDSTACK_ENTRY *entry;
- entry=bandstack_entry_get_current();
- entry->filter=f;
- FILTER* band_filters=filters[entry->mode];
- FILTER* band_filter=&band_filters[entry->filter];
- setFilter(band_filter->low,band_filter->high);
+ vfo_filter_changed(f);
+ return 0;
+}
+
+static gboolean filter_select_cb (GtkWidget *widget, gpointer data) {
+ filter_select(data);
set_button_text_color(last_filter,"black");
last_filter=widget;
set_button_text_color(last_filter,"orange");
- vfo_update(NULL);
}
-static gboolean deviation_select_cb (GtkWidget *widget, gpointer data) {
+static gboolean deviation_select_cb (GtkWidget *widget, gpointer data) {
deviation=(int)data;
if(deviation==2500) {
- setFilter(-4000,4000);
+ //setFilter(-4000,4000);
+ set_filter(active_receiver,-4000,4000);
} else {
- setFilter(-8000,8000);
+ //setFilter(-8000,8000);
+ set_filter(active_receiver,-8000,8000);
}
- wdsp_set_deviation((double)deviation);
+ set_deviation(active_receiver,(double)deviation);
set_button_text_color(last_filter,"black");
last_filter=widget;
set_button_text_color(last_filter,"orange");
vfo_update(NULL);
}
+static void var_spin_low_cb (GtkWidget *widget, gpointer data) {
+ int f=(int)data;
+ int id=active_receiver->id;
+
+ FILTER *mode_filters=filters[vfo[id].mode];
+ FILTER *filter=&mode_filters[f];
+
+ filter->low=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
+ if(vfo[id].mode==modeCWL || vfo[id].mode==modeCWU) {
+ filter->high=filter->low;
+ }
+ if(f==vfo[id].filter) {
+ receiver_filter_changed(receiver[id]);
+ }
+}
+
+static void var_spin_high_cb (GtkWidget *widget, gpointer data) {
+ int f=(int)data;
+ int id=active_receiver->id;
+
+ FILTER *mode_filters=filters[vfo[id].mode];
+ FILTER *filter=&mode_filters[f];
+
+ filter->high=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
+ if(f==vfo[id].filter) {
+ receiver_filter_changed(receiver[id]);
+ }
+}
+
void filter_menu(GtkWidget *parent) {
GtkWidget *b;
int i;
- BAND *band;
parent_window=parent;
g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL);
gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1);
- BANDSTACK_ENTRY *entry=bandstack_entry_get_current();
- FILTER* band_filters=filters[entry->mode];
+ char label[32];
+ sprintf(label,"RX %d VFO %s",active_receiver->id,active_receiver->id==0?"A":"B");
+ GtkWidget *rx_label=gtk_label_new(label);
+ gtk_grid_attach(GTK_GRID(grid),rx_label,1,0,1,1);
+
+ BAND *band=band_get_band(vfo[active_receiver->id].band);
+ BANDSTACK *bandstack=band->bandstack;
+ BANDSTACK_ENTRY *entry=&bandstack->entry[vfo[active_receiver->id].bandstack];
+ FILTER* band_filters=filters[vfo[active_receiver->id].mode];
+ FILTER* band_filter=&band_filters[vfo[active_receiver->id].filter];
switch(entry->mode) {
case modeFMN:
break;
default:
- for(i=0;i<FILTERS;i++) {
+ for(i=0;i<FILTERS-2;i++) {
FILTER* band_filter=&band_filters[i];
GtkWidget *b=gtk_button_new_with_label(band_filters[i].title);
- if(i==entry->filter) {
+ if(i==vfo[active_receiver->id].filter) {
set_button_text_color(b,"orange");
last_filter=b;
} else {
gtk_grid_attach(GTK_GRID(grid),b,i%5,1+(i/5),1,1);
g_signal_connect(b,"pressed",G_CALLBACK(filter_select_cb),(gpointer *)i);
}
+
+ // last 2 are var1 and var2
+ int row=1+((i+4)/5);
+ FILTER* band_filter=&band_filters[i];
+ GtkWidget *b=gtk_button_new_with_label(band_filters[i].title);
+ if(i==vfo[active_receiver->id].filter) {
+ set_button_text_color(b,"orange");
+ last_filter=b;
+ } else {
+ set_button_text_color(b,"black");
+ }
+ gtk_grid_attach(GTK_GRID(grid),b,0,row,1,1);
+ g_signal_connect(b,"pressed",G_CALLBACK(filter_select_cb),(gpointer *)i);
+
+ GtkWidget *var1_spin_low=gtk_spin_button_new_with_range(-8000.0,+8000.0,1.0);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(var1_spin_low),(double)band_filter->low);
+ gtk_grid_attach(GTK_GRID(grid),var1_spin_low,1,row,1,1);
+ g_signal_connect(var1_spin_low,"value-changed",G_CALLBACK(var_spin_low_cb),(gpointer *)i);
+
+ if(vfo[active_receiver->id].mode!=modeCWL && vfo[active_receiver->id].mode!=modeCWU) {
+ GtkWidget *var1_spin_high=gtk_spin_button_new_with_range(-8000.0,+8000.0,1.0);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(var1_spin_high),(double)band_filter->high);
+ gtk_grid_attach(GTK_GRID(grid),var1_spin_high,2,row,1,1);
+ g_signal_connect(var1_spin_high,"value-changed",G_CALLBACK(var_spin_high_cb),(gpointer *)i);
+ }
+
+ row++;
+ i++;
+ band_filter=&band_filters[i];
+ b=gtk_button_new_with_label(band_filters[i].title);
+ if(i==vfo[active_receiver->id].filter) {
+ set_button_text_color(b,"orange");
+ last_filter=b;
+ } else {
+ set_button_text_color(b,"black");
+ }
+ gtk_grid_attach(GTK_GRID(grid),b,0,row,1,1);
+ g_signal_connect(b,"pressed",G_CALLBACK(filter_select_cb),(gpointer *)i);
+
+ GtkWidget *var2_spin_low=gtk_spin_button_new_with_range(-8000.0,+8000.0,1.0);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(var2_spin_low),(double)band_filter->low);
+ gtk_grid_attach(GTK_GRID(grid),var2_spin_low,1,row,1,1);
+ g_signal_connect(var2_spin_low,"value-changed",G_CALLBACK(var_spin_low_cb),(gpointer *)i);
+
+ if(vfo[active_receiver->id].mode!=modeCWL && vfo[active_receiver->id].mode!=modeCWU) {
+ GtkWidget *var2_spin_high=gtk_spin_button_new_with_range(-8000.0,+8000.0,1.0);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(var2_spin_high),(double)band_filter->high);
+ gtk_grid_attach(GTK_GRID(grid),var2_spin_high,2,row,1,1);
+ g_signal_connect(var2_spin_high,"value-changed",G_CALLBACK(var_spin_high_cb),(gpointer *)i);
+ }
+
break;
}
*/
extern void filter_menu(GtkWidget *parent);
+extern int filter_select(void *data);
#include "new_menu.h"
#include "fm_menu.h"
#include "radio.h"
-#include "wdsp_init.h"
+#include "transmitter.h"
static GtkWidget *parent_window=NULL;
} else {
pre_emphasize=0;
}
- wdsp_set_pre_emphasize(pre_emphasize);
+ tx_set_pre_emphasize(transmitter,pre_emphasize);
}
void fm_menu(GtkWidget *parent) {
#include "filter.h"
#include "mode.h"
#include "radio.h"
+#include "receiver.h"
#include "vfo.h"
static GtkWidget *parent_window=NULL;
if(b!=band_get_current()) {
BAND *band=band_set_current(b);
BANDSTACK_ENTRY *entry=bandstack_entry_get_current();
- setMode(entry->mode);
+ //setMode(entry->mode);
+ set_mode(active_receiver,entry->mode);
FILTER* band_filters=filters[entry->mode];
FILTER* band_filter=&band_filters[entry->filter];
- setFilter(band_filter->low,band_filter->high);
- set_alex_rx_antenna(band->alexRxAntenna);
- set_alex_tx_antenna(band->alexTxAntenna);
- set_alex_attenuation(band->alexAttenuation);
-
+ //setFilter(band_filter->low,band_filter->high);
+ set_filter(active_receiver,band_filter->low,band_filter->high);
+ if(active_receiver->id==0) {
+ set_alex_rx_antenna(band->alexRxAntenna);
+ set_alex_tx_antenna(band->alexTxAntenna);
+ set_alex_attenuation(band->alexAttenuation);
+ }
}
setFrequency(f);
vfo_update(NULL);
label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), "<big>0</big>");
gtk_misc_set_alignment (GTK_MISC (label), 1, .5);
- gtk_grid_attach(GTK_GRID(grid),label,1,0,1,1);
+ gtk_grid_attach(GTK_GRID(grid),label,1,0,2,1);
+
+ char label[32];
+ sprintf(label,"RX %d VFO %s",active_receiver->id,active_receiver->id==0?"A":"B");
+ GtkWidget *rx_label=gtk_label_new(label);
+ gtk_grid_attach(GTK_GRID(grid),rx_label,3,0,1,1);
GtkWidget *step_rb=NULL;
for (i=0; i<16; i++) {
#include "band.h"
#include "filter.h"
#include "radio.h"
+#include "receiver.h"
static GtkWidget *parent_window=NULL;
vfo_encoder_divisor=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
}
+/*
static void toolbar_dialog_buttons_cb(GtkWidget *widget, gpointer data) {
toolbar_dialog_buttons=toolbar_dialog_buttons==1?0:1;
update_toolbar_labels();
}
+*/
static void ptt_cb(GtkWidget *widget, gpointer data) {
mic_ptt_enabled=mic_ptt_enabled==1?0:1;
if(filter_board==ALEX) {
BAND *band=band_get_current_band();
BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
- setFrequency(entry->frequencyA);
- setMode(entry->mode);
+ setFrequency(entry->frequency);
+ //setMode(entry->mode);
+ set_mode(active_receiver,entry->mode);
FILTER* band_filters=filters[entry->mode];
FILTER* band_filter=&band_filters[entry->filter];
- setFilter(band_filter->low,band_filter->high);
- set_alex_rx_antenna(band->alexRxAntenna);
- set_alex_tx_antenna(band->alexTxAntenna);
- set_alex_attenuation(band->alexAttenuation);
+ //setFilter(band_filter->low,band_filter->high);
+ set_filter(active_receiver,band_filter->low,band_filter->high);
+ if(active_receiver->id==0) {
+ set_alex_rx_antenna(band->alexRxAntenna);
+ set_alex_tx_antenna(band->alexTxAntenna);
+ set_alex_attenuation(band->alexAttenuation);
+ }
}
}
if(filter_board==APOLLO) {
BAND *band=band_get_current_band();
BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
- setFrequency(entry->frequencyA);
- setMode(entry->mode);
+ setFrequency(entry->frequency);
+ //setMode(entry->mode);
+ set_mode(active_receiver,entry->mode);
FILTER* band_filters=filters[entry->mode];
FILTER* band_filter=&band_filters[entry->filter];
- setFilter(band_filter->low,band_filter->high);
- }
-}
-/*
-static void apollo_tuner_cb(GtkWidget *widget, gpointer data) {
- apollo_tuner=apollo_tuner==1?0:1;
- if(protocol==NEW_PROTOCOL) {
- tuner_changed();
- }
-}
-
-static void pa_cb(GtkWidget *widget, gpointer data) {
- pa=pa==1?0:1;
- if(protocol==NEW_PROTOCOL) {
- pa_changed();
- }
-}
-*/
-
-static void rx_dither_cb(GtkWidget *widget, gpointer data) {
- rx_dither=rx_dither==1?0:1;
- if(protocol==NEW_PROTOCOL) {
- }
-}
-
-static void rx_random_cb(GtkWidget *widget, gpointer data) {
- rx_random=rx_random==1?0:1;
- if(protocol==NEW_PROTOCOL) {
- }
-}
-
-static void rx_preamp_cb(GtkWidget *widget, gpointer data) {
- rx_preamp=rx_preamp==1?0:1;
- if(protocol==NEW_PROTOCOL) {
+ //setFilter(band_filter->low,band_filter->high);
+ set_filter(active_receiver,band_filter->low,band_filter->high);
}
}
static void sample_rate_cb(GtkWidget *widget, gpointer data) {
- if(protocol==ORIGINAL_PROTOCOL) {
- old_protocol_new_sample_rate((int)data);
- } else {
- new_protocol_new_sample_rate((int)data);
- }
+ radio_change_sample_rate((int)data);
}
static void rit_cb(GtkWidget *widget,gpointer data) {
g_signal_connect(vfo_divisor,"value_changed",G_CALLBACK(vfo_divisor_value_changed_cb),NULL);
if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL) {
- GtkWidget *rx_dither_b=gtk_check_button_new_with_label("Dither");
- //gtk_widget_override_font(rx_dither_b, pango_font_description_from_string("Arial 18"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx_dither_b), rx_dither);
- gtk_grid_attach(GTK_GRID(grid),rx_dither_b,1,4,1,1);
- g_signal_connect(rx_dither_b,"toggled",G_CALLBACK(rx_dither_cb),NULL);
-
- GtkWidget *rx_random_b=gtk_check_button_new_with_label("Random");
- //gtk_widget_override_font(rx_random_b, pango_font_description_from_string("Arial 18"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx_random_b), rx_random);
- gtk_grid_attach(GTK_GRID(grid),rx_random_b,1,5,1,1);
- g_signal_connect(rx_random_b,"toggled",G_CALLBACK(rx_random_cb),NULL);
if((protocol==NEW_PROTOCOL && device==NEW_DEVICE_ORION) ||
(protocol==NEW_PROTOCOL && device==NEW_DEVICE_ORION2) ||
- (protocol==ORIGINAL_PROTOCOL && device==DEVICE_ORION)) {
+ (protocol==ORIGINAL_PROTOCOL && device==DEVICE_ORION) ||
+ (protocol==ORIGINAL_PROTOCOL && device==DEVICE_ORION2)) {
GtkWidget *ptt_ring_b=gtk_radio_button_new_with_label(NULL,"PTT On Ring, Mic and Bias on Tip");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_ring_b), mic_ptt_tip_bias_ring==0);
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 raspberrypi
+#ifdef GPIO
gtk_widget_set_sensitive(sample_rate_768,FALSE);
gtk_widget_set_sensitive(sample_rate_1536,FALSE);
#endif
+#include <gtk/gtk.h>
#ifdef GPIO
#include <stdio.h>
#include <fcntl.h>
#include <poll.h>
#include <sched.h>
-#include <pthread.h>
+//#include <pthread.h>
#include <wiringPi.h>
#include <semaphore.h>
-#ifdef raspberrypi
+#ifdef GPIO
#include <pigpio.h>
#endif
#ifdef sx1509
#ifdef PSK
#include "psk.h"
#endif
+#include "new_menu.h"
+#include "encoder_menu.h"
#define SYSFS_GPIO_DIR "/sys/class/gpio"
int ENABLE_VFO_ENCODER=1;
int ENABLE_VFO_PULLUP=1;
-int VFO_ENCODER_A=17;
-int VFO_ENCODER_B=18;
+int VFO_ENCODER_A=18;
+int VFO_ENCODER_B=17;
#if defined odroid && !defined sx1509
int VFO_ENCODER_A_PIN=0;
int VFO_ENCODER_B_PIN=1;
int ENABLE_E1_PULLUP=0;
int E1_ENCODER_A=20;
int E1_ENCODER_B=26;
-#ifndef sx1509
+//#ifndef sx1509
int E1_FUNCTION=25;
-#else
-int E1_FUNCTION=2; //RRK, was 25 now taken by waveshare LCD TS, disable i2c
-#endif
+//#else
+//int E1_FUNCTION=2; //RRK, was 25 now taken by waveshare LCD TS, disable i2c
+//#endif
int ENABLE_E2_ENCODER=1;
int ENABLE_E2_PULLUP=0;
int E2_ENCODER_A=16;
int ENABLE_E3_PULLUP=0;
int E3_ENCODER_A=4;
int E3_ENCODER_B=21;
-#if defined sx1509
+//#if defined sx1509
int E3_FUNCTION=7;
-#else
-int E3_FUNCTION=3; //RRK, was 7 now taken by waveshare LCD TS, disable i2c
-#endif
+//#else
+//int E3_FUNCTION=3; //RRK, was 7 now taken by waveshare LCD TS, disable i2c
+//#endif
int ENABLE_S1_BUTTON=1;
int S1_BUTTON=13;
int ENABLE_S2_BUTTON=1;
int ENABLE_FUNCTION_BUTTON=1;
int FUNCTION_BUTTON=22;
int ENABLE_E1_BUTTON=1;
+int ENABLE_E2_BUTTON=1;
+int ENABLE_E3_BUTTON=1;
int ENABLE_CW_BUTTONS=1;
// make sure to disable UART0 for next 2 gpios
+#ifdef LOCALCW
int CWL_BUTTON=9;
int CWR_BUTTON=10;
+#endif
#ifdef sx1509
/* Hardware Hookup:
static volatile int vfoEncoderPos;
static volatile int e1EncoderPos;
static volatile int e1Function;
+int e1_encoder_action=ENCODER_AF_GAIN;
static volatile int e2EncoderPos;
static volatile int e2Function;
+int e2_encoder_action=ENCODER_DRIVE;
static volatile int e3EncoderPos;
static volatile int e3Function;
+int e3_encoder_action=ENCODER_ATTENUATION;
static volatile int function_state;
static volatile int band_state;
static volatile int bandstack_state;
static volatile int mox_state;
static volatile int lock_state;
-static void* rotary_encoder_thread(void *arg);
-static pthread_t rotary_encoder_thread_id;
+//static void* rotary_encoder_thread(void *arg);
+static gpointer rotary_encoder_thread(gpointer data);
+//static pthread_t rotary_encoder_thread_id;
+static GThread *rotary_encoder_thread_id;
static int previous_function_button=0;
static int e1_function=0;
static int previous_e1_function=0;
static int e2_function=0;
static int previous_e2_function=0;
+static int e3_function=0;
+static int previous_e3_function=0;
static int band_button=0;
static int previous_band_button=0;
static int bandstack_button=0;
static int previous_agc_button=0;
static int mox_button=0;
static int previous_mox_button=0;
-static int lock_button=0;
-static int previous_lock_button=0;
-static int running=1;
+//static GMutex m_running;
+static int running=0;
+
+char *encoder_string[] = {
+"AF GAIN",
+"AGC GAIN",
+"ATTENUATION",
+"MIC GAIN",
+"DRIVE",
+"TUNE DRIVE",
+"RIT",
+"CW SPEED",
+"CW FREQUENCY",
+"PANADAPTER HIGH",
+"PANADAPTER LOW",
+};
-static void e1FunctionAlert(int gpio, int level, uint32_t tick) {
- e1Function=(level==0);
+static int mox_pressed(void *data) {
+ if(running) sim_mox_cb(NULL,NULL);
+ return 0;
}
-static void e3FunctionAlert(int gpio, int level, uint32_t tick) {
+static int s1_pressed(void *data) {
+ if(running) sim_s1_pressed_cb(NULL,NULL);
+ return 0;
+}
+
+static int s1_released(void *data) {
+ if(running) sim_s1_released_cb(NULL,NULL);
+ return 0;
+}
+
+static int s2_pressed(void *data) {
+ if(running) sim_s2_pressed_cb(NULL,NULL);
+ return 0;
+}
+
+static int s2_released(void *data) {
+ if(running) sim_s2_released_cb(NULL,NULL);
+ return 0;
+}
+
+static int s3_pressed(void *data) {
+ if(running) sim_s3_pressed_cb(NULL,NULL);
+ return 0;
+}
+
+static int s3_released(void *data) {
+ if(running) sim_s3_released_cb(NULL,NULL);
+ return 0;
+}
+
+static int s4_pressed(void *data) {
+ if(running) sim_s4_pressed_cb(NULL,NULL);
+ return 0;
+}
+
+static int s4_released(void *data) {
+ if(running) sim_s4_released_cb(NULL,NULL);
+ return 0;
+}
+
+static int s5_pressed(void *data) {
+ if(running) sim_s5_pressed_cb(NULL,NULL);
+ return 0;
+}
+
+static int s5_released(void *data) {
+ if(running) sim_s5_released_cb(NULL,NULL);
+ return 0;
+}
+
+static int s6_pressed(void *data) {
+ if(running) sim_s6_pressed_cb(NULL,NULL);
+ return 0;
+}
+
+static int s6_released(void *data) {
+ if(running) sim_s6_released_cb(NULL,NULL);
+ return 0;
+}
+
+static int function_pressed(void *data) {
+ if(running) sim_function_cb(NULL,NULL);
+ return 0;
+}
+
+static int e_function_pressed(void *data) {
+ int encoder=(int)data;
+ start_encoder(encoder);
+ return 0;
+}
+
+static void e1FunctionAlert(int gpio, int level, uint32_t tick) {
if(level==0) {
- e3Function=e3Function==0?1:0;
+ if(running) g_idle_add(e_function_pressed,(gpointer)1);
}
}
static void e2FunctionAlert(int gpio, int level, uint32_t tick) {
- e2Function=(level==0);
+ if(level==0) {
+ if(running) g_idle_add(e_function_pressed,(gpointer)2);
+ }
+}
+
+static void e3FunctionAlert(int gpio, int level, uint32_t tick) {
+ if(level==0) {
+ if(running) g_idle_add(e_function_pressed,(gpointer)3);
+ }
}
static void functionAlert(int gpio, int level, uint32_t tick) {
- function_state=(level==0);
+ if(level==0) {
+ if(running) g_idle_add(function_pressed,NULL);
+ }
}
-static void bandAlert(int gpio, int level, uint32_t tick) {
- band_state=(level==0);
+
+static void s1Alert(int gpio, int level, uint32_t tick) {
+ if(level==0) {
+ g_idle_add(s1_pressed,NULL);
+ } else {
+ g_idle_add(s1_released,NULL);
+ }
}
-static void bandstackAlert(int gpio, int level, uint32_t tick) {
- bandstack_state=(level==0);
+static void s2Alert(int gpio, int level, uint32_t tick) {
+ if(level==0) {
+ g_idle_add(s2_pressed,NULL);
+ } else {
+ g_idle_add(s2_released,NULL);
+ }
}
-static void modeAlert(int gpio, int level, uint32_t tick) {
- mode_state=(level==0);
+static void s3Alert(int gpio, int level, uint32_t tick) {
+ if(level==0) {
+ g_idle_add(s3_pressed,NULL);
+ } else {
+ g_idle_add(s3_released,NULL);
+ }
}
-static void filterAlert(int gpio, int level, uint32_t tick) {
- filter_state=(level==0);
+static void s4Alert(int gpio, int level, uint32_t tick) {
+ if(level==0) {
+ g_idle_add(s4_pressed,NULL);
+ } else {
+ g_idle_add(s4_released,NULL);
+ }
}
-static void noiseAlert(int gpio, int level, uint32_t tick) {
- noise_state=(level==0);
+static void s5Alert(int gpio, int level, uint32_t tick) {
+ if(level==0) {
+ g_idle_add(s5_pressed,NULL);
+ } else {
+ g_idle_add(s5_released,NULL);
+ }
}
-static void agcAlert(int gpio, int level, uint32_t tick) {
- agc_state=(level==0);
+static void s6Alert(int gpio, int level, uint32_t tick) {
+ if(level==0) {
+ g_idle_add(s6_pressed,NULL);
+ } else {
+ g_idle_add(s6_released,NULL);
+ }
}
static void moxAlert(int gpio, int level, uint32_t tick) {
- mox_state=(level==0);
+ if(level==0) {
+ g_idle_add(mox_pressed,(gpointer)NULL);
+ } else {
+ }
}
static void lockAlert(int gpio, int level, uint32_t tick) {
lock_state=(level==0);
}
-static void cwAlert(int gpio, int level, uint32_t tick) {
-fprintf(stderr,"cwAlert: gpio=%d level=%d internal=%d\n",gpio,level,cw_keyer_internal);
#ifdef LOCALCW
+static void cwAlert(int gpio, int level, uint32_t tick) {
if (cw_keyer_internal == 0 && (mode==modeCWL || mode==modeCWU))
keyer_event(gpio, cw_active_level == 0 ? level : (level==0));
-#endif
}
+#endif
static void vfoEncoderPulse(int gpio, int level, unsigned int tick) {
static int levA=0, levB=0, lastGpio = -1;
value=getProperty("E1_FUNCTION");
if(value) E1_FUNCTION=atoi(value);
#endif
+
+ value=getProperty("ENABLE_E2_BUTTON");
+ if(value) ENABLE_E2_BUTTON=atoi(value);
+#ifndef sx1509
+ value=getProperty("E2_FUNCTION");
+ if(value) E2_FUNCTION=atoi(value);
+#endif
+
+ value=getProperty("ENABLE_E3_BUTTON");
+ if(value) ENABLE_E3_BUTTON=atoi(value);
+#ifndef sx1509
+ value=getProperty("E3_FUNCTION");
+ if(value) E3_FUNCTION=atoi(value);
+#endif
+
+#ifdef LOCALCW
value=getProperty("ENABLE_CW_BUTTONS");
if(value) ENABLE_CW_BUTTONS=atoi(value);
value=getProperty("CWL_BUTTON");
if(value) CWL_BUTTON=atoi(value);
value=getProperty("CWR_BUTTON");
if(value) CWR_BUTTON=atoi(value);
+#endif
}
void gpio_save_state() {
setProperty("ENABLE_MOX_BUTTON",value);
sprintf(value,"%d",MOX_BUTTON);
setProperty("MOX_BUTTON",value);
+
sprintf(value,"%d",ENABLE_E1_BUTTON);
setProperty("ENABLE_E1_BUTTON",value);
#ifndef sx1509
sprintf(value,"%d",E1_FUNCTION);
setProperty("E1_FUNCTION",value);
#endif
+
+ sprintf(value,"%d",ENABLE_E2_BUTTON);
+ setProperty("ENABLE_E2_BUTTON",value);
+#ifndef sx1509
+ sprintf(value,"%d",E2_FUNCTION);
+ setProperty("E2_FUNCTION",value);
+#endif
+
+ sprintf(value,"%d",ENABLE_E3_BUTTON);
+ setProperty("ENABLE_E3_BUTTON",value);
+#ifndef sx1509
+ sprintf(value,"%d",E3_FUNCTION);
+ setProperty("E3_FUNCTION",value);
+#endif
+
+#ifdef LOCALCW
sprintf(value,"%d",ENABLE_CW_BUTTONS);
setProperty("ENABLE_CW_BUTTONS",value);
sprintf(value,"%d",CWL_BUTTON);
setProperty("CWL_BUTTON",value);
sprintf(value,"%d",CWR_BUTTON);
setProperty("CWR_BUTTON",value);
+#endif
saveProperties("gpio.props");
}
+#define BUTTON_STEADY_TIME_US 5000
+static void setup_button(int button, gpioAlertFunc_t pAlert) {
+ gpioSetMode(button, PI_INPUT);
+ gpioSetPullUpDown(button,PI_PUD_UP);
+ // give time to settle to avoid false triggers
+ usleep(10000);
+ gpioSetAlertFunc(button, pAlert);
+ gpioGlitchFilter(button, BUTTON_STEADY_TIME_US);
+}
int gpio_init() {
-fprintf(stderr,"encoder_init\n");
+ fprintf(stderr,"gpio_init\n");
+
+ //g_mutex_init(&m_running);
#if defined odroid && !defined sx1509
VFO_ENCODER_A=88;
#endif
gpio_restore_state();
-#ifdef raspberrypi
-
-#define BUTTON_STEADY_TIME_US 5000
-
- void setup_button(int button, gpioAlertFunc_t pAlert) {
- gpioSetMode(button, PI_INPUT);
- gpioSetPullUpDown(button,PI_PUD_UP);
- // give time to settle to avoid false triggers
- usleep(10000);
- gpioSetAlertFunc(button, pAlert);
- gpioGlitchFilter(button, BUTTON_STEADY_TIME_US);
- }
+#ifdef GPIO
- fprintf(stderr,"encoder_init: VFO_ENCODER_A=%d VFO_ENCODER_B=%d\n",VFO_ENCODER_A,VFO_ENCODER_B);
+ fprintf(stderr,"gpio_init: VFO_ENCODER_A=%d VFO_ENCODER_B=%d\n",VFO_ENCODER_A,VFO_ENCODER_B);
- fprintf(stderr,"gpioInitialize\n");
+ fprintf(stderr,"gpioInitialise\n");
if(gpioInitialise()<0) {
fprintf(stderr,"Cannot initialize GPIO\n");
return -1;
}
+fprintf(stderr,"setup_button: E1 %d\n",E1_FUNCTION);
setup_button(E1_FUNCTION, e1FunctionAlert);
e1Function=0;
e1EncoderPos=0;
}
- setup_button(E2_FUNCTION, e2FunctionAlert);
- e2Function=0;
+fprintf(stderr,"setup_button: E2 %d\n",E2_FUNCTION);
+ setup_button(E2_FUNCTION, e2FunctionAlert);
+ e2Function=0;
if(ENABLE_E2_ENCODER) {
gpioSetMode(E2_ENCODER_A, PI_INPUT);
gpioSetMode(E2_ENCODER_B, PI_INPUT);
- if(ENABLE_E1_PULLUP) {
+ if(ENABLE_E2_PULLUP) {
gpioSetPullUpDown(E2_ENCODER_A, PI_PUD_UP);
gpioSetPullUpDown(E2_ENCODER_B, PI_PUD_UP);
} else {
e2EncoderPos=0;
}
+fprintf(stderr,"setup_button: E3 %d\n",E3_FUNCTION);
setup_button(E3_FUNCTION, e3FunctionAlert);
e3Function=0;
if(ENABLE_E3_ENCODER) {
gpioSetMode(E3_ENCODER_A, PI_INPUT);
gpioSetMode(E3_ENCODER_B, PI_INPUT);
- if(ENABLE_E1_PULLUP) {
+ if(ENABLE_E3_PULLUP) {
gpioSetPullUpDown(E3_ENCODER_A, PI_PUD_UP);
gpioSetPullUpDown(E3_ENCODER_B, PI_PUD_UP);
} else {
if(ENABLE_S1_BUTTON) {
- setup_button(S1_BUTTON, bandAlert);
+ setup_button(S1_BUTTON, s1Alert);
}
if(ENABLE_S2_BUTTON) {
- setup_button(S2_BUTTON, bandstackAlert);
+ setup_button(S2_BUTTON, s2Alert);
}
if(ENABLE_S3_BUTTON) {
- setup_button(S3_BUTTON, modeAlert);
+ setup_button(S3_BUTTON, s3Alert);
}
if(ENABLE_S4_BUTTON) {
- setup_button(S4_BUTTON, filterAlert);
+ setup_button(S4_BUTTON, s4Alert);
}
if(ENABLE_S5_BUTTON) {
- setup_button(S5_BUTTON, noiseAlert);
+ setup_button(S5_BUTTON, s5Alert);
}
if(ENABLE_S6_BUTTON) {
- setup_button(S6_BUTTON, agcAlert);
+ setup_button(S6_BUTTON, s6Alert);
}
if(ENABLE_MOX_BUTTON) {
setup_button(MOX_BUTTON, moxAlert);
}
+/*
#ifndef sx1509
if(ENABLE_E1_BUTTON) {
setup_button(E1_FUNCTION, lockAlert);
}
#endif
+*/
+#ifdef LOCALCW
fprintf(stderr,"GPIO: ENABLE_CW_BUTTONS=%d CWL_BUTTON=%d CWR_BUTTON=%d\n",ENABLE_CW_BUTTONS, CWL_BUTTON, CWR_BUTTON);
if(ENABLE_CW_BUTTONS) {
setup_button(CWL_BUTTON, cwAlert);
gpioGlitchFilter(CWR_BUTTON, 5000);
*/
}
+#endif
#endif
E3_ENCODER_A=14;
E3_ENCODER_B=15;
- fprintf(stderr,"sx1509 encoder_init: VFO_ENCODER_A=%d VFO_ENCODER_B=%d\n",VFO_ENCODER_A,VFO_ENCODER_B);
+ fprintf(stderr,"sx1509 gpio_init: VFO_ENCODER_A=%d VFO_ENCODER_B=%d\n",VFO_ENCODER_A,VFO_ENCODER_B);
pSX1509 = newSX1509();
//VFO_ENCODER_A_PIN=ODROID_VFO_ENCODER_A_PIN;
//VFO_ENCODER_B_PIN=ODROID_VFO_ENCODER_B_PIN;
- fprintf(stderr,"encoder_init: VFO_ENCODER_A=%d VFO_ENCODER_B=%d\n",VFO_ENCODER_A,VFO_ENCODER_B);
+ fprintf(stderr,"gpio_init: VFO_ENCODER_A=%d VFO_ENCODER_B=%d\n",VFO_ENCODER_A,VFO_ENCODER_B);
fprintf(stderr,"wiringPiSetup\n");
if (wiringPiSetup () < 0) {
}
#endif
- int rc=pthread_create(&rotary_encoder_thread_id, NULL, rotary_encoder_thread, NULL);
- if(rc<0) {
- fprintf(stderr,"pthread_create for rotary_encoder_thread failed %d\n",rc);
+ rotary_encoder_thread_id = g_thread_new( "rotary encoder", rotary_encoder_thread, NULL);
+ if( ! rotary_encoder_thread_id )
+ {
+ fprintf(stderr,"g_thread_new failed on rotary_encoder_thread\n");
+ exit( -1 );
}
+ fprintf(stderr, "rotary_encoder_thread: id=%p\n",rotary_encoder_thread_id);
return 0;
}
void gpio_close() {
+fprintf(stderr,"gpio_close: lock\n");
+ //g_mutex_lock(&m_running);
running=0;
+#ifdef GPIO
+fprintf(stderr,"gpioTerminate\n");
+ gpioTerminate();
+#endif
+fprintf(stderr,"gpio_close: unlock\n");
+ //g_mutex_unlock(&m_running);
#if defined odroid && !defined sx1509
FILE *fp;
- fp = popen("echo 97 > /sys/class/gpio/unexport\n", "r");
+ fp = popen("echo 87 > /sys/class/gpio/unexport\n", "r");
pclose(fp);
- fp = popen("echo 108 > /sys/class/gpio/unexport\n", "r");
+ fp = popen("echo 88 > /sys/class/gpio/unexport\n", "r");
pclose(fp);
#endif
}
return pos;
}
-int e1_function_get_state() {
- return e1Function;
-}
-
int e2_encoder_get_pos() {
int pos=e2EncoderPos;
e2EncoderPos=0;
e3EncoderPos=0;
return pos;
}
-
-int agc_function_get_state() {
+int e3_function_get_state() {
return e3Function;
}
-int e2_function_get_state() {
- return e2Function;
-}
-
int function_get_state() {
return function_state;
}
static int vfo_encoder_changed(void *data) {
if(!locked) {
- int pos=*(int*)data;
-
- // VFO
- BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
- setFrequency(entry->frequencyA+ddsOffset+(pos*step));
- vfo_update(NULL);
+ int pos=(int)data;
+ vfo_step(pos);
}
- free(data);
+ //free(data);
return 0;
}
-static int e1_encoder_changed(void *data) {
- int pos=*(int*)data;
- if(pos!=0) {
- if(function || isTransmitting()) {
- // mic gain
- double gain=mic_gain;
+static encoder_changed(int action,int pos) {
+ double value;
+ switch(action) {
+ case ENCODER_AF_GAIN:
+ value=active_receiver->volume;
+ value+=(double)pos/100.0;
+ if(value<0.0) {
+ value=0.0;
+ } else if(value>1.0) {
+ value=1.0;
+ }
+ set_af_gain(value);
+ break;
+ case ENCODER_AGC_GAIN:
+ value=active_receiver->agc_gain;
+ value+=(double)pos;
+ if(value<-20.0) {
+ value=-20.0;
+ } else if(value>120.0) {
+ value=120.0;
+ }
+ set_agc_gain(value);
+ break;
+ case ENCODER_ATTENUATION:
+ value=active_receiver->attenuation;
+ value+=pos;
+ if(value<0) {
+ value=0;
+ } else if (value>31) {
+ value=31;
+ }
+ set_attenuation_value(value);
+ break;
+ case ENCODER_MIC_GAIN:
+ value=mic_gain;
//gain+=(double)pos/100.0;
- gain+=(double)pos;
- if(gain<-10.0) {
- gain=-10.0;
- } else if(gain>50.0) {
- gain=50.0;
+ value+=(double)pos;
+ if(value<-10.0) {
+ value=-10.0;
+ } else if(value>50.0) {
+ value=50.0;
}
- set_mic_gain(gain);
- } else {
- // af gain
- double gain=volume;
- gain+=(double)pos/100.0;
- if(gain<0.0) {
- gain=0.0;
- } else if(gain>1.0) {
- gain=1.0;
+ set_mic_gain(value);
+ break;
+ case ENCODER_DRIVE:
+ value=getDrive();
+ value+=(double)pos;
+ if(value<0.0) {
+ value=0.0;
+ } else if(value>100.0) {
+ value=100.0;
}
- set_af_gain(gain);
- }
- }
- free(data);
- return 0;
-}
-
-static int e2_encoder_changed(void *data) {
- int pos=*(int*)data;
- if(pos!=0) {
- if(function || tune) {
- // tune drive
- double d=getTuneDrive();
- d+=(double)pos;
- if(d<0.0) {
- d=0.0;
- } else if(d>100.0) {
- d=100.0;
+ set_drive(value);
+ break;
+ case ENCODER_TUNE_DRIVE:
+ value=getTuneDrive();
+ value+=(double)pos;
+ if(value<0.0) {
+ value=0.0;
+ } else if(value>100.0) {
+ value=100.0;
}
- set_tune(d);
- } else {
- // drive
- double d=getDrive();
- d+=(double)pos;
- if(d<0.0) {
- d=0.0;
- } else if(d>100.0) {
- d=100.0;
+ set_tune(value);
+ break;
+ case ENCODER_RIT:
+ value=(double)vfo[active_receiver->id].rit;
+ value+=(double)(pos*rit_increment);
+ if(value<-1000.0) {
+ value=-1000.0;
+ } else if(value>1000.0) {
+ value=1000.0;
}
- set_drive(d);
- }
- }
- free(data);
- return 0;
-}
-
-static int e3_encoder_changed(void *data) {
- int pos=*(int*)data;
- if(pos!=0) {
- if(function) {
- int att=attenuation;
- att+=pos;
- if(att<0) {
- att=0;
- } else if (att>31) {
- att=31;
+ vfo[active_receiver->id].rit=(int)value;
+ vfo_update(NULL);
+ break;
+ case ENCODER_CW_SPEED:
+ value=(double)cw_keyer_speed;
+ value+=(double)pos;
+ if(value<1.0) {
+ value=1.0;
+ } else if(value>60.0) {
+ value=60.0;
}
- set_attenuation_value((double)att);
- } else {
- double gain=agc_gain;
- gain+=(double)pos;
- if(gain<-20.0) {
- gain=-20.0;
- } else if(gain>120.0) {
- gain=120.0;
+ cw_keyer_speed=(int)value;
+ vfo_update(NULL);
+ break;
+ case ENCODER_CW_FREQUENCY:
+ value=(double)cw_keyer_sidetone_frequency;
+ value+=(double)pos;
+ if(value<0.0) {
+ value=0.0;
+ } else if(value>1000.0) {
+ value=1000.0;
}
- set_agc_gain(gain);
- }
+ cw_keyer_sidetone_frequency=(int)value;
+ vfo_update(NULL);
+ break;
+ case ENCODER_PANADAPTER_HIGH:
+ value=(double)active_receiver->panadapter_high;
+ value+=(double)pos;
+ active_receiver->panadapter_high=(int)value;
+ break;
+ case ENCODER_PANADAPTER_LOW:
+ value=(double)active_receiver->panadapter_low;
+ value+=(double)pos;
+ active_receiver->panadapter_low=(int)value;
+ break;
}
- return 0;
-}
-
-static int band_pressed(void *data) {
- sim_s1_pressed_cb(NULL,NULL);
- return 0;
-}
-
-static int band_released(void *data) {
- sim_s1_released_cb(NULL,NULL);
- return 0;
-}
-
-static int bandstack_pressed(void *data) {
- sim_s2_pressed_cb(NULL,NULL);
- return 0;
}
-static int bandstack_released(void *data) {
- sim_s2_released_cb(NULL,NULL);
- return 0;
-}
-
-static int function_pressed(void *data) {
- sim_function_cb(NULL,NULL);
- return 0;
-}
-
-static int mox_pressed(void *data) {
- sim_mox_cb(NULL,NULL);
- return 0;
-}
-
-static int lock_pressed(void *data) {
- lock_cb((GtkWidget *)NULL, (gpointer)NULL);
+static int e1_encoder_changed(void *data) {
+ int pos=(int)data;
+ if(active_menu==E1_MENU) {
+ encoder_select(pos);
+ } else {
+ encoder_changed(e1_encoder_action,pos);
+ }
+ //free(data);
return 0;
}
-static int mode_pressed(void *data) {
- sim_s3_cb(NULL,NULL);
+static int e2_encoder_changed(void *data) {
+ int pos=(int)data;
+ if(active_menu==E2_MENU) {
+ encoder_select(pos);
+ } else {
+ encoder_changed(e2_encoder_action,pos);
+ }
+ //free(data);
return 0;
}
-static int filter_pressed(void *data) {
- sim_s4_cb(NULL,NULL);
+static int e3_encoder_changed(void *data) {
+ int pos=(int)data;
+ if(active_menu==E3_MENU) {
+ encoder_select(pos);
+ } else {
+ encoder_changed(e3_encoder_action,pos);
+ }
+ //free(data);
return 0;
}
-static int noise_pressed(void *data) {
- sim_s5_cb(NULL,NULL);
- return 0;
-}
+static gpointer rotary_encoder_thread(gpointer data) {
+ int pos;
-static int agc_pressed(void *data) {
- sim_s6_cb(NULL,NULL);
- return 0;
-}
+ // ignore startup glitches
+ sleep(2);
-static void* rotary_encoder_thread(void *arg) {
- int pos;
+ //g_mutex_lock(&m_running);
running=1;
- while(running) {
-
- int function_button=function_get_state();
- if(function_button!=previous_function_button) {
- previous_function_button=function_button;
- if(function_button) {
- g_idle_add(function_pressed,(gpointer)NULL);
- }
- }
+ //g_mutex_unlock(&m_running);
+ while(1) {
pos=vfo_encoder_get_pos();
if(pos!=0) {
- int *p=malloc(sizeof(int));
- *p=pos;
- g_idle_add(vfo_encoder_changed,(gpointer)p);
+ g_idle_add(vfo_encoder_changed,(gpointer)pos);
}
-/*
- e1_function=e1_function_get_state();
- if(e1_function!=previous_e1_function) {
- previous_e1_function=e1_function;
- }
-*/
pos=e1_encoder_get_pos();
if(pos!=0) {
- int *p=malloc(sizeof(int));
- *p=pos;
- g_idle_add(e1_encoder_changed,(gpointer)p);
+ g_idle_add(e1_encoder_changed,(gpointer)pos);
}
-/*
- e2_function=e2_function_get_state();
- if(e2_function!=previous_e2_function) {
- previous_e2_function=e2_function;
- }
-*/
pos=e2_encoder_get_pos();
if(pos!=0) {
- int *p=malloc(sizeof(int));
- *p=pos;
- g_idle_add(e2_encoder_changed,(gpointer)p);
+ g_idle_add(e2_encoder_changed,(gpointer)pos);
}
pos=e3_encoder_get_pos();
if(pos!=0) {
- int *p=malloc(sizeof(int));
- *p=pos;
- g_idle_add(e3_encoder_changed,(gpointer)p);
- }
-
-
- int band_button=band_get_state();
- if(band_button!=previous_band_button) {
- previous_band_button=band_button;
- if(band_button) {
- g_idle_add(band_pressed,(gpointer)NULL);
- } else {
- g_idle_add(band_released,(gpointer)NULL);
- }
- }
-
- int bandstack_button=bandstack_get_state();
- if(bandstack_button!=previous_bandstack_button) {
- previous_bandstack_button=bandstack_button;
- if(bandstack_button) {
- g_idle_add(bandstack_pressed,(gpointer)NULL);
- } else {
- g_idle_add(bandstack_released,(gpointer)NULL);
- }
- }
-
- int mode_button=mode_get_state();
- if(mode_button!=previous_mode_button) {
- previous_mode_button=mode_button;
- if(mode_button) {
- g_idle_add(mode_pressed,(gpointer)NULL);
- }
- }
-
- int filter_button=filter_get_state();
- if(filter_button!=previous_filter_button) {
- previous_filter_button=filter_button;
- if(filter_button) {
- g_idle_add(filter_pressed,(gpointer)NULL);
- }
- }
-
- int noise_button=noise_get_state();
- if(noise_button!=previous_noise_button) {
- previous_noise_button=noise_button;
- if(noise_button) {
- g_idle_add(noise_pressed,(gpointer)NULL);
- }
- }
-
- int agc_button=agc_get_state();
- if(agc_button!=previous_agc_button) {
- previous_agc_button=agc_button;
- if(agc_button) {
- g_idle_add(agc_pressed,(gpointer)NULL);
- }
- }
-
- int mox_button=mox_get_state();
- if(mox_button!=previous_mox_button) {
- previous_mox_button=mox_button;
- if(mox_button) {
- g_idle_add(mox_pressed,(gpointer)NULL);
- }
- }
-
- int lock_button=lock_get_state();
- if(lock_button!=previous_lock_button) {
- previous_lock_button=lock_button;
- if(lock_button) {
- g_idle_add(lock_pressed,(gpointer)NULL);
- }
+ g_idle_add(e3_encoder_changed,(gpointer)pos);
}
#ifdef sx1509
// buttons only generate interrupt when
- // pushed on, so clear them now
+ // pushed onODER_AF_GAIN = 0,
function_state = 0;
band_state = 0;
bandstack_state = 0;
mox_state = 0;
lock_state = 0;
#endif
-
-#ifdef raspberrypi
- if(running) gpioDelay(100000); // 10 per second
+//fprintf(stderr,"gpio_thread: lock\n");
+ //g_mutex_lock(&m_running);
+ if(running==0) {
+fprintf(stderr,"gpio_thread: unlock (running==0)\n");
+ //g_mutex_unlock(&m_running);
+ g_thread_exit(NULL);
+ }
+#ifdef GPIO
+ usleep(100000);
+ //gpioDelay(100000); // 10 per second
#endif
#ifdef odroid
- if(running) usleep(100000);
+ usleep(100000);
#endif
+//fprintf(stderr,"gpio_thread: unlock (running==1)\n");
+ //g_mutex_unlock(&m_running);
}
-#ifdef raspberrypi
- gpioTerminate();
-#endif
+ return NULL;
}
#endif
#ifndef _GPIO_H
#define _GPIO_H
+enum {
+ ENCODER_AF_GAIN=0,
+ ENCODER_AGC_GAIN,
+ ENCODER_ATTENUATION,
+ ENCODER_MIC_GAIN,
+ ENCODER_DRIVE,
+ ENCODER_TUNE_DRIVE,
+ ENCODER_RIT,
+ ENCODER_CW_SPEED,
+ ENCODER_CW_FREQUENCY,
+ ENCODER_PANADAPTER_HIGH,
+ ENCODER_PANADAPTER_LOW
+};
+
+
+#define ENCODER_LAST ENCODER_PANADAPTER_LOW
+
+extern char *encoder_string[ENCODER_LAST+1];
+
+extern int e1_encoder_action;
+extern int e2_encoder_action;
+extern int e3_encoder_action;
+
extern int ENABLE_VFO_ENCODER;
extern int ENABLE_VFO_PULLUP;
extern int VFO_ENCODER_A;
if(!locked) {
int pos=*(int*)data;
BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
- //entry->frequencyA=entry->frequencyA+(pos*step);
- //setFrequency(entry->frequencyA);
- setFrequency(entry->frequencyA+ddsOffset+(pos*step));
+ //entry->frequency=entry->frequency+(pos*step);
+ //setFrequency(entry->frequency);
+ setFrequency(entry->frequency+ddsOffset+(pos*step));
vfo_update(NULL);
}
free(data);
--- /dev/null
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <linux/i2c-dev.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <pthread.h>
+
+#include <gtk/gtk.h>
+#include "i2c.h"
+#include "band.h"
+#include "band_menu.h"
+#include "bandstack.h"
+#include "radio.h"
+#include "toolbar.h"
+#include "vfo.h"
+
+#define I2C_DEVICE "/dev/i2c-1"
+#define ADDRESS_1 0X20
+#define ADDRESS_2 0X23
+
+//static pthread_t i2c_thread_id;
+static GThread *i2c_thread_id;
+
+static int write_byte_data(unsigned char addr,unsigned char reg, unsigned char data) {
+ int fd;
+ int rc;
+
+ if((fd=open(I2C_DEVICE, O_RDWR))<0) {
+ fprintf(stderr,"cannot open %s: %s\n",I2C_DEVICE,strerror(errno));
+ return(-1);
+ }
+
+ if(ioctl(fd,I2C_SLAVE,addr)<0) {
+ fprintf(stderr,"cannot aquire access to I2C device at 0x%02X\n",addr);
+ return(-1);
+ }
+
+ rc=i2c_smbus_write_byte_data(fd,reg,data);
+ if(rc<0) {
+ fprintf(stderr,"i2c_smbus_write_byte_data failed: device=%02X 0x%02X to 0x%02X: %s\n",addr,data,reg,strerror(errno));
+ return(-1);
+ }
+
+ close(fd);
+
+ return 0;
+}
+
+static unsigned char read_byte_data(unsigned char addr,unsigned char reg) {
+ int fd;
+ int rc;
+
+ if((fd=open(I2C_DEVICE, O_RDWR))<0) {
+ fprintf(stderr,"c$cannot open %s: %s\n",I2C_DEVICE,strerror(errno));
+ exit(1);
+ }
+
+ if(ioctl(fd,I2C_SLAVE,addr)<0) {
+ fprintf(stderr,"cannot aquire access to I2C device at 0x%x\n",addr);
+ exit(1);
+ }
+
+ rc=i2c_smbus_read_byte_data(fd,reg);
+ if(rc<0) {
+ fprintf(stderr,"i2c_smbus_read_byte_data failed: 0x%2X: %s\n",reg,strerror(errno));
+ exit(1);
+ }
+
+ close(fd);
+
+ return rc;
+}
+
+static void frequencyStep(int pos) {
+ BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
+ setFrequency(entry->frequency+ddsOffset+(pos*step));
+ vfo_update(NULL);
+}
+
+static void *i2c_thread(void *arg) {
+ int rc_1_a;
+ int rc_1_b;
+ int prev_rc_1_a=0;
+ int prev_rc_1_b=0;
+ int rc_2_a;
+ int rc_2_b;
+ int prev_rc_2_a=0;
+ int prev_rc_2_b=0;
+
+ while(1) {
+ rc_1_a=read_byte_data(ADDRESS_1,0x12);
+ if(rc_1_a!=0 && rc_1_a!=prev_rc_1_a) {
+ fprintf(stderr,"Dev 1: GPIOA: 0x%02X\n",rc_1_a);
+ switch(rc_1_a) {
+ case 0x01:
+ g_idle_add(band_update,(void *)band160);
+ break;
+ case 0x02:
+ g_idle_add(band_update,(void *)band80);
+ break;
+ case 0x04:
+ g_idle_add(band_update,(void *)band60);
+ break;
+ case 0x08:
+ g_idle_add(band_update,(void *)band40);
+ break;
+ case 0x10:
+ g_idle_add(band_update,(void *)band30);
+ break;
+ case 0x20:
+ g_idle_add(band_update,(void *)band20);
+ break;
+ case 0x40:
+ g_idle_add(band_update,(void *)band17);
+ break;
+ case 0x80:
+ g_idle_add(band_update,(void *)band15);
+ break;
+ }
+ }
+ prev_rc_1_a=rc_1_a;
+
+ rc_1_b=read_byte_data(ADDRESS_1,0x13);
+ if(rc_1_b!=0 && rc_1_b!=prev_rc_1_b) {
+ fprintf(stderr,"Dev 1: GPIOB: 0x%02X\n",rc_1_b);
+ switch(rc_1_b) {
+ case 0x01:
+ g_idle_add(band_update,(void *)band12);
+ break;
+ case 0x02:
+ g_idle_add(band_update,(void *)band10);
+ break;
+ case 0x04:
+ g_idle_add(band_update,(void *)band6);
+ break;
+ case 0x08:
+ g_idle_add(band_update,(void *)bandGen);
+ break;
+ case 0x10:
+ frequencyStep(+1);
+ break;
+ case 0x20:
+ break;
+ case 0x40:
+ break;
+ case 0x80:
+ frequencyStep(-1);
+ break;
+ }
+ }
+ prev_rc_1_b=rc_1_b;
+
+ rc_2_a=read_byte_data(ADDRESS_2,0x12);
+ if(rc_2_a!=0 && rc_2_a!=prev_rc_2_a) {
+ fprintf(stderr,"Dev 2: GPIOA: 0x%02X\n",rc_2_a);
+ switch(rc_2_a) {
+ case 0x01:
+ break;
+ case 0x02:
+ mox_cb(NULL,NULL);
+ break;
+ case 0x04:
+ tune_cb(NULL,NULL);
+ break;
+ case 0x08:
+ break;
+ case 0x10:
+ break;
+ case 0x20:
+ break;
+ case 0x40:
+ break;
+ case 0x80:
+ break;
+ }
+ }
+ prev_rc_2_a=rc_2_a;
+
+ rc_2_b=read_byte_data(ADDRESS_2,0x13);
+ if(rc_2_b!=0 && rc_2_b!=prev_rc_2_b) {
+ fprintf(stderr,"Dev 2: GPIOB: 0x%02X\n",rc_2_b);
+ switch(rc_2_b) {
+ case 0x01:
+ break;
+ case 0x02:
+ break;
+ case 0x04:
+ break;
+ case 0x08:
+ break;
+ case 0x10:
+ break;
+ case 0x20:
+ break;
+ case 0x40:
+ break;
+ case 0x80:
+ break;
+ }
+ }
+ prev_rc_2_b=rc_2_b;
+
+ usleep(200);
+ }
+
+}
+
+void i2c_init() {
+
+fprintf(stderr,"i2c_init\n");
+ // setup i2c
+ if(write_byte_data(ADDRESS_1,0x0A,0x22)<0) return;
+
+ // set GPIOA/B for input
+ if(write_byte_data(ADDRESS_1,0x00,0xFF)<0) return;
+ if(write_byte_data(ADDRESS_1,0x01,0xFF)<0) return;
+
+ // set GPIOA for pullups
+ if(write_byte_data(ADDRESS_1,0x0C,0xFF)<0) return;
+ if(write_byte_data(ADDRESS_1,0x0D,0xFF)<0) return;
+
+ // reverse polarity
+ if(write_byte_data(ADDRESS_1,0x02,0xFF)<0) return;
+ if(write_byte_data(ADDRESS_1,0x03,0xFF)<0) return;
+
+ // setup i2c
+ if(write_byte_data(ADDRESS_2,0x0A,0x22)<0) return;
+
+ // set GPIOA/B for input
+ if(write_byte_data(ADDRESS_2,0x00,0xFF)<0) return;
+ if(write_byte_data(ADDRESS_2,0x01,0xFF)<0) return;
+
+ // set GPIOA for pullups
+ if(write_byte_data(ADDRESS_2,0x0C,0xFF)<0) return;
+ if(write_byte_data(ADDRESS_2,0x0D,0xFF)<0) return;
+
+ // reverse polarity
+ if(write_byte_data(ADDRESS_2,0x02,0xFF)<0) return;
+ if(write_byte_data(ADDRESS_2,0x03,0xFF)<0) return;
+
+/*
+ int rc;
+ rc=pthread_create(&i2c_thread_id,NULL,i2c_thread,NULL);
+ if(rc != 0) {
+ fprintf(stderr,"i2c_init: pthread_create failed on i2c_thread: rc=%d\n", rc);
+ }
+*/
+ i2c_thread_id = g_thread_new( "i2c", i2c_thread, NULL);
+ if( ! i2c_thread_id )
+ {
+ fprintf(stderr,"g_thread_new failed on i2c_thread\n");
+ }
+
+
+}
--- /dev/null
+
+void i2c_init();
--- /dev/null
+/*
+ * File: libusbio.c
+ * Author: jm57878
+ *
+ * Created on 18 February 2009, 21:16
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <libusb-1.0/libusb.h>
+
+#include "libusbio.h"
+
+/*
+ * interface to libusb1.0
+ */
+
+#define OZY_PID (0x0007)
+#define OZY_VID (0xfffe)
+
+#define VRQ_SDR1K_CTL 0x0d
+#define SDR1KCTRL_READ_VERSION 0x7
+#define VRT_VENDOR_IN 0xC0
+
+#define OZY_IO_TIMEOUT 500
+
+static int init=0;
+static libusb_device_handle* ozy_handle;
+static libusb_context* context;
+
+int libusb_open_ozy(void) {
+ int rc;
+
+fprintf(stderr,"libusb_open_ozy\n");
+
+ if(init==0) {
+ rc=libusb_init(NULL);
+ if(rc<0) {
+ fprintf(stderr,"libusb_init failed: %d\n",rc);
+ return rc;
+ }
+ init=1;
+ }
+
+ ozy_handle=libusb_open_device_with_vid_pid(NULL, OZY_VID, OZY_PID);
+ if(ozy_handle==NULL) {
+ fprintf(stderr,"libusbio: cannot find ozy device\n");
+ return -1;
+ }
+
+ rc=libusb_claim_interface(ozy_handle,0);
+ if(rc<0) {
+ fprintf(stderr,"libusb_claim_interface failed: %d\n",rc);
+ return rc;
+ }
+
+fprintf(stderr,"libusb_open_ozy: SUCCESS\n");
+ return 0;
+
+}
+
+void libusb_close_ozy() {
+ libusb_close(ozy_handle);
+}
+
+int libusb_get_ozy_firmware_string(char* buffer,int buffersize) {
+ int rc;
+ rc=libusb_control_transfer(ozy_handle, VRT_VENDOR_IN, VRQ_SDR1K_CTL, SDR1KCTRL_READ_VERSION, 0, buffer, buffersize, OZY_IO_TIMEOUT);
+ if(rc<0) {
+ fprintf(stderr,"libusb_get_ozy_firmware failed: %d\n",rc);
+ return rc;
+ }
+ buffer[rc]=0x00;
+ return 0;
+}
+
+int libusb_write_ozy(int ep,void* buffer,int buffersize)
+{
+ int rc;
+ int bytes;
+ rc = libusb_bulk_transfer(ozy_handle, (unsigned char)ep, (unsigned char *)buffer, buffersize,&bytes, OZY_IO_TIMEOUT);
+ if(rc==0) {
+ rc=bytes;
+ }
+ return rc;
+}
+
+
+int libusb_read_ozy(int ep,void* buffer,int buffersize)
+{
+ int rc;
+ int bytes;
+ rc = libusb_bulk_transfer(ozy_handle, (unsigned char)ep, (unsigned char *)buffer, buffersize,&bytes, OZY_IO_TIMEOUT);
+ if(rc==0) {
+ rc=bytes;
+ }
+ return rc;
+}
--- /dev/null
+/**
+* @file libusbio.h
+* @brief Header file for the USB I/O functions, interface to libusb1.0
+* @author
+* @version 0.1
+* @date 2009-05-18
+*/
+
+#ifndef _LIBUSBIO_H
+#define _LIBUSBIO_H
+
+int libusb_open_ozy(void);
+void libusb_close_ozy();
+int libusb_get_ozy_firmware_string(char* buffer,int buffersize);
+int libusb_write_ozy(int ep,void* buffer,int buffersize);
+int libusb_read_ozy(int ep,void* buffer,int buffersize);
+
+#endif /* _LIBUSBIO_H */
+
#include <arpa/inet.h>
#include "audio.h"
+#include "band.h"
+#include "bandstack.h"
#include "main.h"
#include "channel.h"
#include "discovered.h"
#include "configure.h"
#include "gpio.h"
-#include "old_discovery.h"
-#include "new_discovery.h"
-#ifdef LIMESDR
-#include "lime_discovery.h"
-#endif
-#include "old_protocol.h"
-#include "new_protocol.h"
-#ifdef LIMESDR
-#include "lime_protocol.h"
-#endif
#include "wdsp.h"
-#include "vfo.h"
-//#include "menu.h"
#include "new_menu.h"
-#include "rit.h"
-#include "meter.h"
-#include "panadapter.h"
-#include "splash.h"
-#include "waterfall.h"
-#include "toolbar.h"
-#include "sliders.h"
#include "radio.h"
-#include "rigctl.h"
-#include "wdsp_init.h"
#include "version.h"
-#include "mode.h"
-#ifdef PSK
-#include "psk.h"
-#include "psk_waterfall.h"
-#endif
-
-#define DISPLAY_INCREMENT (display_height/32)
-#define VFO_HEIGHT (DISPLAY_INCREMENT*4)
-//#define VFO_HEIGHT (DISPLAY_INCREMENT*8)
-#define VFO_WIDTH ((display_width/32)*21)
-#define MENU_HEIGHT VFO_HEIGHT
-//#define MENU_HEIGHT (DISPLAY_INCREMENT*4)
-#define MENU_WIDTH ((display_width/32)*3)
-//#define RIT_WIDTH ((MENU_WIDTH/3)*2)
-#define METER_HEIGHT VFO_HEIGHT
-//#define METER_HEIGHT (DISPLAY_INCREMENT*4)
-#define METER_WIDTH ((display_width/32)*8)
-#define PANADAPTER_HEIGHT (DISPLAY_INCREMENT*8)
-#define SLIDERS_HEIGHT (DISPLAY_INCREMENT*6)
-#define TOOLBAR_HEIGHT (DISPLAY_INCREMENT*2)
-#define WATERFALL_HEIGHT (display_height-(VFO_HEIGHT+PANADAPTER_HEIGHT+SLIDERS_HEIGHT+TOOLBAR_HEIGHT))
-#ifdef PSK
-#define PSK_WATERFALL_HEIGHT (DISPLAY_INCREMENT*6)
-#define PSK_HEIGHT (display_height-(VFO_HEIGHT+PSK_WATERFALL_HEIGHT+SLIDERS_HEIGHT+TOOLBAR_HEIGHT))
+#include "button_text.h"
+#ifdef I2C
+#include "i2c.h"
#endif
+#include "discovery.h"
struct utsname unameData;
gint display_height;
gint full_screen=1;
-static gint update_timer_id;
-
-static gint save_timer_id;
-
-static float *samples;
-
static GtkWidget *discovery_dialog;
static sem_t wisdom_sem;
static GdkCursor *cursor_arrow;
static GdkCursor *cursor_watch;
-static GdkWindow *splash_window;
-
-static GtkWidget *window;
-static GtkWidget *grid;
-static GtkWidget *fixed;
-static GtkWidget *vfo;
-static GtkWidget *rit_control;
-static GtkWidget *menu;
-static GtkWidget *meter;
-static GtkWidget *sliders;
-static GtkWidget *toolbar;
-static GtkWidget *panadapter;
-static GtkWidget *waterfall;
-#ifdef PSK
-static GtkWidget *psk;
-static GtkWidget *psk_waterfall;
-#endif
+static GtkWidget *splash;
+
+GtkWidget *top_window;
+GtkWidget *grid;
static DISCOVERED* d;
-static void start_radio();
-static void discover_devices();
-
-gint update(gpointer data) {
- int result;
- double fwd;
- double rev;
- double exciter;
- int channel=CHANNEL_RX0;
-#ifdef PSK
- if(mode==modePSK) {
- channel=CHANNEL_PSK;
- }
-#endif
- if(isTransmitting()) {
- channel=CHANNEL_TX;
- }
- GetPixels(channel,0,samples,&result);
- if(result==1) {
- if(display_panadapter) {
-#ifdef PSK
- if(mode==modePSK) {
- psk_waterfall_update(samples);
- } else {
-#endif
- panadapter_update(samples,isTransmitting());
-#ifdef PSK
- }
-#endif
- }
- if(!isTransmitting()) {
-#ifdef PSK
- if(mode!=modePSK) {
-#endif
- if(display_waterfall) {
- waterfall_update(samples);
- }
-#ifdef PSK
- }
-#endif
- }
- }
-
- if(!isTransmitting()) {
- double m;
- switch(mode) {
-#ifdef PSK
- case modePSK:
- m=(double)psk_get_signal_level();
- meter_update(PSKMETER,m,0.0,0.0,0.0);
- break;
-#endif
- default:
- m=GetRXAMeter(CHANNEL_RX0, smeter);
- meter_update(SMETER,m,0.0,0.0,0.0);
- break;
- }
- } else {
-
- double alc=GetTXAMeter(CHANNEL_TX, alc);
-
- DISCOVERED *d=&discovered[selected_device];
-
- double constant1=3.3;
- double constant2=0.095;
-
- if(d->protocol==ORIGINAL_PROTOCOL) {
- switch(d->device) {
- case DEVICE_METIS:
- constant1=3.3;
- constant2=0.09;
- break;
- case DEVICE_HERMES:
- constant1=3.3;
- constant2=0.095;
- break;
- case DEVICE_ANGELIA:
- constant1=3.3;
- constant2=0.095;
- break;
- case DEVICE_ORION:
- constant1=5.0;
- constant2=0.108;
- break;
- case DEVICE_HERMES_LITE:
- break;
- }
-
- int power=alex_forward_power;
- if(power==0) {
- power=exciter_power;
- }
- double v1;
- v1=((double)power/4095.0)*constant1;
- fwd=(v1*v1)/constant2;
-
- power=exciter_power;
- v1=((double)power/4095.0)*constant1;
- exciter=(v1*v1)/constant2;
-
- rev=0.0;
- if(alex_forward_power!=0) {
- power=alex_reverse_power;
- v1=((double)power/4095.0)*constant1;
- rev=(v1*v1)/constant2;
- }
-
- } else {
- switch(d->device) {
- case NEW_DEVICE_ATLAS:
- constant1=3.3;
- constant2=0.09;
- break;
- case NEW_DEVICE_HERMES:
- constant1=3.3;
- constant2=0.09;
- break;
- case NEW_DEVICE_HERMES2:
- constant1=3.3;
- constant2=0.095;
- break;
- case NEW_DEVICE_ANGELIA:
- constant1=3.3;
- constant2=0.095;
- break;
- case NEW_DEVICE_ORION:
- constant1=5.0;
- constant2=0.108;
- break;
- case NEW_DEVICE_ORION2:
- constant1=5.0;
- constant2=0.108;
- break;
- case NEW_DEVICE_HERMES_LITE:
- constant1=3.3;
- constant2=0.09;
- break;
- }
-
- int power=alex_forward_power;
- if(power==0) {
- power=exciter_power;
- }
- double v1;
- v1=((double)power/4095.0)*constant1;
- fwd=(v1*v1)/constant2;
-
- power=exciter_power;
- v1=((double)power/4095.0)*constant1;
- exciter=(v1*v1)/constant2;
-
- rev=0.0;
- if(alex_forward_power!=0) {
- power=alex_reverse_power;
- v1=((double)power/4095.0)*constant1;
- rev=(v1*v1)/constant2;
- }
- }
-
- meter_update(POWER,fwd,rev,exciter,alc);
- }
+static GtkWidget *status;
- return TRUE;
+void status_text(char *text) {
+ //fprintf(stderr,"splash_status: %s\n",text);
+ gtk_label_set_text(GTK_LABEL(status),text);
+ usleep(10000);
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
}
static gint save_cb(gpointer data) {
static pthread_t wisdom_thread_id;
static void* wisdom_thread(void *arg) {
- splash_status("Creating FFTW Wisdom file ...");
+ status_text("Creating FFTW Wisdom file ...");
WDSPwisdom ((char *)arg);
sem_post(&wisdom_sem);
}
_exit(0);
}
-static gboolean start_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
-fprintf(stderr,"start_cb: %p\n",data);
- radio=(DISCOVERED *)data;
- gtk_widget_destroy(discovery_dialog);
- start_radio();
- return TRUE;
-}
-
-#ifdef GPIO
-static gboolean gpio_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
- configure_gpio(discovery_dialog);
- return TRUE;
-}
-#endif
-
-static gboolean discover_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
- gtk_widget_destroy(discovery_dialog);
- discover_devices();
- return TRUE;
-}
-
-static gboolean exit_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
- gtk_widget_destroy(discovery_dialog);
- _exit(0);
- return TRUE;
-}
-
-static void discover_devices() {
-
- gdk_window_set_cursor(splash_window,cursor_watch);
- selected_device=0;
- devices=0;
- splash_status("Old Protocol ... Discovering Devices");
- old_discovery();
- splash_status("New Protocol ... Discovering Devices");
- new_discovery();
-#ifdef LIMESDR
- splash_status("LimeSDR ... Discovering Devices");
- lime_discovery();
-#endif
- splash_status("Discovery");
- if(devices==0) {
- gdk_window_set_cursor(splash_window,cursor_arrow);
- fprintf(stderr,"No devices found!\n");
- GtkDialogFlags flags = GTK_DIALOG_DESTROY_WITH_PARENT;
-/*
- discovery_dialog = gtk_message_dialog_new (GTK_WINDOW(splash_screen),
- flags,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK_CANCEL,
- "No devices found! Retry Discovery?");
-*/
- discovery_dialog = gtk_dialog_new();
- gtk_window_set_transient_for(GTK_WINDOW(discovery_dialog),GTK_WINDOW(splash_screen));
- gtk_window_set_decorated(GTK_WINDOW(discovery_dialog),FALSE);
-
- gtk_widget_override_font(discovery_dialog, pango_font_description_from_string("FreeMono 16"));
-
- GdkRGBA color;
- color.red = 1.0;
- color.green = 1.0;
- color.blue = 1.0;
- color.alpha = 1.0;
- gtk_widget_override_background_color(discovery_dialog,GTK_STATE_FLAG_NORMAL,&color);
-
- GtkWidget *content;
-
- content=gtk_dialog_get_content_area(GTK_DIALOG(discovery_dialog));
-
- GtkWidget *grid=gtk_grid_new();
- gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
- gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
- gtk_grid_set_row_spacing (GTK_GRID(grid),10);
-
- GtkWidget *label=gtk_label_new("No devices found!");
- gtk_grid_attach(GTK_GRID(grid),label,0,0,2,1);
-
- GtkWidget *exit_b=gtk_button_new_with_label("Exit");
- g_signal_connect (exit_b, "button-press-event", G_CALLBACK(exit_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),exit_b,0,1,1,1);
-
- GtkWidget *discover_b=gtk_button_new_with_label("Retry Discovery");
- g_signal_connect (discover_b, "button-press-event", G_CALLBACK(discover_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),discover_b,1,1,1,1);
-
- gtk_container_add (GTK_CONTAINER (content), grid);
- gtk_widget_show_all(discovery_dialog);
- } else {
- //fprintf(stderr,"%s: found %d devices.\n", (char *)arg, devices);
- gdk_window_set_cursor(splash_window,cursor_arrow);
-/*
- GtkDialogFlags flags=GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT;
- discovery_dialog = gtk_dialog_new_with_buttons ("Discovered",
- GTK_WINDOW(splash_window),
- flags,
-#ifdef GPIO
- "Configure GPIO",
- GTK_RESPONSE_YES,
-#endif
- "Discover",
- GTK_RESPONSE_REJECT,
- "Exit",
- GTK_RESPONSE_CLOSE,
- NULL);
-*/
-
- discovery_dialog = gtk_dialog_new();
- gtk_window_set_transient_for(GTK_WINDOW(discovery_dialog),GTK_WINDOW(splash_screen));
- gtk_window_set_decorated(GTK_WINDOW(discovery_dialog),FALSE);
-
- gtk_widget_override_font(discovery_dialog, pango_font_description_from_string("FreeMono 16"));
-
- GdkRGBA color;
- color.red = 1.0;
- color.green = 1.0;
- color.blue = 1.0;
- color.alpha = 1.0;
- gtk_widget_override_background_color(discovery_dialog,GTK_STATE_FLAG_NORMAL,&color);
-
- GtkWidget *content;
-
- content=gtk_dialog_get_content_area(GTK_DIALOG(discovery_dialog));
-
- GtkWidget *grid=gtk_grid_new();
- gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
- gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
- gtk_grid_set_row_spacing (GTK_GRID(grid),10);
-
- int i;
- char version[16];
- char text[128];
- for(i=0;i<devices;i++) {
- d=&discovered[i];
-fprintf(stderr,"%p protocol=%d name=%s\n",d,d->protocol,d->name);
- if(d->protocol==ORIGINAL_PROTOCOL) {
- sprintf(version,"%d.%d",
- d->software_version/10,
- d->software_version%10);
- } else {
- sprintf(version,"%d.%d.%d",
- d->software_version/100,
- (d->software_version%100)/10,
- d->software_version%10);
- }
- switch(d->protocol) {
- case ORIGINAL_PROTOCOL:
- case NEW_PROTOCOL:
- sprintf(text,"%s (%s %s) %s (%02X:%02X:%02X:%02X:%02X:%02X) on %s\n",
- d->name,
- d->protocol==ORIGINAL_PROTOCOL?"old":"new",
- version,
- 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 %s)\n",
- d->name,
- "lime",
- version);
-*/
- sprintf(text,"%s\n",
- d->name);
- break;
-#endif
- }
-
- GtkWidget *label=gtk_label_new(text);
- gtk_widget_override_font(label, pango_font_description_from_string("FreeMono 12"));
- gtk_widget_show(label);
- gtk_grid_attach(GTK_GRID(grid),label,0,i,3,1);
-
- GtkWidget *start_button=gtk_button_new_with_label("Start");
- gtk_widget_override_font(start_button, pango_font_description_from_string("FreeMono 18"));
- gtk_widget_show(start_button);
- gtk_grid_attach(GTK_GRID(grid),start_button,3,i,1,1);
- g_signal_connect(start_button,"button_press_event",G_CALLBACK(start_cb),(gpointer)d);
-
- // if not available then cannot start it
- if(d->status!=STATE_AVAILABLE) {
- gtk_button_set_label(GTK_BUTTON(start_button),"In Use");
- gtk_widget_set_sensitive(start_button, FALSE);
- }
-
- // if not on the same subnet then cannot start it
- 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);
- }
-
- }
-
-#ifdef GPIO
- GtkWidget *gpio_b=gtk_button_new_with_label("Config GPIO");
- g_signal_connect (gpio_b, "button-press-event", G_CALLBACK(gpio_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),gpio_b,0,i,1,1);
-#endif
- GtkWidget *discover_b=gtk_button_new_with_label("Discover");
- g_signal_connect (discover_b, "button-press-event", G_CALLBACK(discover_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),discover_b,1,i,1,1);
-
- GtkWidget *exit_b=gtk_button_new_with_label("Exit");
- g_signal_connect (exit_b, "button-press-event", G_CALLBACK(exit_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),exit_b,2,i,1,1);
-
-
- gtk_container_add (GTK_CONTAINER (content), grid);
- gtk_widget_show_all(discovery_dialog);
- }
-}
-
-static gboolean minimize_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
- gtk_window_iconify(GTK_WINDOW(window));
- return TRUE;
-}
-
-static void start_radio() {
- int y;
-fprintf(stderr,"start: selected radio=%p device=%d\n",radio,radio->device);
- gdk_window_set_cursor(splash_window,cursor_watch);
-
- splash_status("Initializing wdsp ...");
- protocol=radio->protocol;
- device=radio->device;
-
- switch(radio->protocol) {
- case ORIGINAL_PROTOCOL:
- case NEW_PROTOCOL:
- sprintf(property_path,"%02X-%02X-%02X-%02X-%02X-%02X.props",
- radio->info.network.mac_address[0],
- radio->info.network.mac_address[1],
- radio->info.network.mac_address[2],
- radio->info.network.mac_address[3],
- radio->info.network.mac_address[4],
- radio->info.network.mac_address[5]);
- break;
-#ifdef LIMESDR
- case LIMESDR_PROTOCOL:
- sprintf(property_path,"limesdr.props");
- break;
-#endif
- }
-
- radioRestoreState();
-
- fprintf(stderr,"malloc samples\n");
- if(radio->protocol==NEW_PROTOCOL) {
- samples=malloc(display_width*sizeof(float)*2*4); // 192 -> 48
- } else {
- samples=malloc(display_width*sizeof(float)*2);
- }
-
- //splash_status("Initializing wdsp ...");
- fprintf(stderr,"wdsp_init\n");
- wdsp_init(0,display_width,radio->protocol);
-
- switch(radio->protocol) {
- case ORIGINAL_PROTOCOL:
- splash_status("Initializing old protocol ...");
- fprintf(stderr,"old_protocol_init\n");
- old_protocol_init(0,display_width);
- break;
- case NEW_PROTOCOL:
- splash_status("Initializing new protocol ...");
- fprintf(stderr,"new_protocol_init\n");
- new_protocol_init(display_width);
- break;
-#ifdef LIMESDR
- case LIMESDR_PROTOCOL:
- splash_status("Initializing lime protocol ...");
- lime_protocol_init(0,display_width);
- break;
-#endif
- }
-
-#ifdef GPIO
- fprintf(stderr,"gpio_init\n");
- splash_status("Initializing GPIO ...");
- if(gpio_init()<0) {
- }
-#ifdef LOCALCW
- // init local keyer if enabled
- else if (cw_keyer_internal == 0)
- keyer_update();
-#endif
-#endif
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title (GTK_WINDOW (window), "pihpsdr");
- gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER_ALWAYS);
- gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
- g_signal_connect (window, "delete-event", G_CALLBACK (main_delete), NULL);
-
- fixed=gtk_fixed_new();
- gtk_container_add(GTK_CONTAINER(window), fixed);
- y=0;
-
- vfo = vfo_init(VFO_WIDTH,VFO_HEIGHT,window);
- gtk_fixed_put(GTK_FIXED(fixed),vfo,0,0);
-
-
-
- //rit_control = rit_init(RIT_WIDTH,MENU_HEIGHT,window);
- //gtk_fixed_put(GTK_FIXED(fixed),rit_control,VFO_WIDTH,y);
-
- GtkWidget *minimize_b=gtk_button_new_with_label("Hide");
- gtk_widget_override_font(minimize_b, pango_font_description_from_string("FreeMono Bold 10"));
- gtk_widget_set_size_request (minimize_b, MENU_WIDTH, MENU_HEIGHT/2);
- g_signal_connect (minimize_b, "button-press-event", G_CALLBACK(minimize_cb), NULL);
- gtk_widget_show(minimize_b);
- gtk_fixed_put(GTK_FIXED(fixed),minimize_b,VFO_WIDTH,y);
-
- //menu = menu_init(MENU_WIDTH,MENU_HEIGHT,window);
- menu = new_menu_init(MENU_WIDTH,MENU_HEIGHT/2,window);
- gtk_fixed_put(GTK_FIXED(fixed),menu,VFO_WIDTH,y+(MENU_HEIGHT/2));
-
- meter = meter_init(METER_WIDTH,METER_HEIGHT,window);
- gtk_fixed_put(GTK_FIXED(fixed),meter,VFO_WIDTH+MENU_WIDTH,y);
- y+=VFO_HEIGHT;
-
- if(display_panadapter) {
- int height=PANADAPTER_HEIGHT;
- if(!display_waterfall) {
- height+=WATERFALL_HEIGHT;
- if(!display_sliders) {
- height+=SLIDERS_HEIGHT;
- }
- if(!display_toolbar) {
- height+=TOOLBAR_HEIGHT;
- }
- } else {
- if(!display_sliders) {
- height+=SLIDERS_HEIGHT/2;
- }
- }
- panadapter = panadapter_init(display_width,height);
- gtk_fixed_put(GTK_FIXED(fixed),panadapter,0,VFO_HEIGHT);
- y+=height;
- }
-
- if(display_waterfall) {
- int height=WATERFALL_HEIGHT;
- if(!display_panadapter) {
- height+=PANADAPTER_HEIGHT;
- }
- if(!display_sliders) {
- if(display_panadapter) {
- height+=SLIDERS_HEIGHT/2;
- } else {
- height+=SLIDERS_HEIGHT;
- }
- }
- if(!display_toolbar) {
- height+=TOOLBAR_HEIGHT;
- }
- waterfall = waterfall_init(display_width,height);
- gtk_fixed_put(GTK_FIXED(fixed),waterfall,0,y);
- y+=height;
-
- }
-
-#ifdef PSK
- int psk_height=PSK_WATERFALL_HEIGHT;
- if(!display_sliders) {
- psk_height+=SLIDERS_HEIGHT/2;
- }
- if(!display_toolbar) {
- psk_height+=TOOLBAR_HEIGHT/2;
- }
- psk_waterfall = psk_waterfall_init(display_width,psk_height);
- gtk_fixed_put(GTK_FIXED(fixed),psk_waterfall,0,VFO_HEIGHT);
- psk = init_psk();
- gtk_fixed_put(GTK_FIXED(fixed),psk,0,VFO_HEIGHT+psk_height);
-#endif
-
- if(display_sliders) {
- sliders = sliders_init(display_width,SLIDERS_HEIGHT,window);
- gtk_fixed_put(GTK_FIXED(fixed),sliders,0,y);
- y+=SLIDERS_HEIGHT;
- }
-
- if(display_toolbar) {
- toolbar = toolbar_init(display_width,TOOLBAR_HEIGHT,window);
- gtk_fixed_put(GTK_FIXED(fixed),toolbar,0,y);
- y+=TOOLBAR_HEIGHT;
- }
-
- splash_close();
-
- gtk_widget_show_all (window);
-
- linein_changed();
-
- if(full_screen) {
- gtk_window_fullscreen(GTK_WINDOW(window));
- }
-
- GdkWindow *gdk_window = gtk_widget_get_window(window);
- gdk_window_set_cursor(gdk_window,cursor_arrow);
-
- // start the receiver
- SetChannelState(CHANNEL_RX0,1,1);
-
- //update_timer_id=gdk_threads_add_timeout(1000/updates_per_second, update, NULL);
- update_timer_id=gdk_threads_add_timeout_full(G_PRIORITY_HIGH_IDLE,1000/updates_per_second, update, NULL, NULL);
-
- // save every 30 seconds
- save_timer_id=gdk_threads_add_timeout(30000, save_cb, NULL);
-
-
- if(protocol!=NEW_PROTOCOL) {
- setFrequency(getFrequency());
- }
-
-#ifdef PSK
- if(mode==modePSK) {
- show_psk();
- } else {
- show_waterfall();
- }
-#endif
-
- launch_rigctl();
-
- g_idle_add(vfo_update,(gpointer)NULL);
-
-}
-
-#ifdef PSK
-void show_psk() {
- if(display_waterfall) {
- gtk_widget_hide(waterfall);
- }
- if(display_panadapter) {
- gtk_widget_hide(panadapter);
- }
- gtk_widget_show(psk);
- gtk_widget_show(psk_waterfall);
-}
-
-void show_waterfall() {
- gtk_widget_hide(psk_waterfall);
- gtk_widget_hide(psk);
- if(display_panadapter) {
- gtk_widget_show(panadapter);
- }
- if(display_waterfall) {
- gtk_widget_show(waterfall);
- }
-}
-#endif
-
-void reconfigure_display() {
- int y=VFO_HEIGHT;
-
- // configure panadapter
- if(display_panadapter) {
- int height=PANADAPTER_HEIGHT;
- if(!display_waterfall) {
- height+=WATERFALL_HEIGHT;
- if(!display_sliders) {
- height+=SLIDERS_HEIGHT;
- }
- if(!display_toolbar) {
- height+=TOOLBAR_HEIGHT;
- }
- } else {
- if(!display_sliders) {
- height+=SLIDERS_HEIGHT/2;
- }
- if(!display_toolbar) {
- height+=TOOLBAR_HEIGHT/2;
- }
- }
-fprintf(stderr,"panadapter_height=%d\n",height);
- if(panadapter==NULL) {
-fprintf(stderr,"reconfigure_display: panadapter_init: width:%d height:%d\n",display_width,height);
- panadapter = panadapter_init(display_width,height);
- gtk_fixed_put(GTK_FIXED(fixed),panadapter,0,y);
- } else {
- // set the size
-fprintf(stderr,"reconfigure_display: panadapter set_size_request: width:%d height:%d\n",display_width,height);
- gtk_widget_set_size_request(panadapter, display_width, height);
- // move the current one
- gtk_fixed_move(GTK_FIXED(fixed),panadapter,0,y);
- }
- gtk_widget_show_all(panadapter);
- y+=height;
- } else {
- gtk_widget_hide(panadapter);
- }
-
- // configure waterfall
- if(display_waterfall) {
- int height=WATERFALL_HEIGHT;
-
- if(!display_panadapter) {
- height+=PANADAPTER_HEIGHT;
- if(!display_sliders) {
- height+=SLIDERS_HEIGHT;
- }
- if(!display_toolbar) {
- height+=TOOLBAR_HEIGHT;
- }
- } else {
- if(!display_sliders) {
- height+=SLIDERS_HEIGHT/2;
- }
- if(!display_toolbar) {
- height+=TOOLBAR_HEIGHT/2;
- }
- }
-fprintf(stderr,"waterfall_height=%d\n",height);
- if(waterfall==NULL) {
-fprintf(stderr,"reconfigure_display: waterfall_init: width:%d height:%d\n",display_width,height);
- waterfall = waterfall_init(display_width,height);
- gtk_fixed_put(GTK_FIXED(fixed),waterfall,0,y);
- } else {
- // set the size
-fprintf(stderr,"reconfigure_display: waterfall set_size_request: width:%d height:%d\n",display_width,height);
- gtk_widget_set_size_request (waterfall, display_width, height);
- // move the current one
- gtk_fixed_move(GTK_FIXED(fixed),waterfall,0,y);
- }
- gtk_widget_show_all(waterfall);
- y+=height;
- } else {
- gtk_widget_hide(waterfall);
- }
-
- if(display_sliders) {
-fprintf(stderr,"sliders_height=%d\n",SLIDERS_HEIGHT);
- if(sliders==NULL) {
-fprintf(stderr,"reconfigure_display: sliders_init: width:%d height:%d\n",display_width,SLIDERS_HEIGHT);
- sliders = sliders_init(display_width,SLIDERS_HEIGHT,window);
- gtk_fixed_put(GTK_FIXED(fixed),sliders,0,y);
- } else {
- gtk_fixed_move(GTK_FIXED(fixed),sliders,0,y);
- gtk_widget_show(sliders);
- }
- gtk_widget_show_all(sliders);
- linein_changed();
- y+=SLIDERS_HEIGHT;
- } else {
- gtk_widget_hide(sliders);
- }
-
- if(display_toolbar) {
-fprintf(stderr,"toolbar_height=%d\n",TOOLBAR_HEIGHT);
- if(toolbar==NULL) {
-fprintf(stderr,"reconfigure_display: toolbar_init: width:%d height:%d\n",display_width,TOOLBAR_HEIGHT);
- toolbar = toolbar_init(display_width,TOOLBAR_HEIGHT,window);
- gtk_fixed_put(GTK_FIXED(fixed),toolbar,0,y);
- } else {
- gtk_fixed_move(GTK_FIXED(fixed),toolbar,0,y);
- gtk_widget_show(toolbar);
- }
- gtk_widget_show_all(toolbar);
- y+=TOOLBAR_HEIGHT;
- } else {
- gtk_widget_hide(toolbar);
- }
-
-}
-
-gint init(void* arg) {
+static int init(void *data) {
char *res;
char wisdom_directory[1024];
char wisdom_file[1024];
fprintf(stderr,"init\n");
- audio_get_cards(0);
- audio_get_cards(1);
+ audio_get_cards();
cursor_arrow=gdk_cursor_new(GDK_ARROW);
cursor_watch=gdk_cursor_new(GDK_WATCH);
- splash_window = gtk_widget_get_window(splash_screen);
- gdk_window_set_cursor(splash_window,cursor_watch);
-
- init_radio();
+ gdk_window_set_cursor(gtk_widget_get_window(top_window),cursor_watch);
// check if wisdom file exists
res=getcwd(wisdom_directory, sizeof(wisdom_directory));
strcpy(&wisdom_directory[strlen(wisdom_directory)],"/");
strcpy(wisdom_file,wisdom_directory);
strcpy(&wisdom_file[strlen(wisdom_file)],"wdspWisdom");
- splash_status("Checking FFTW Wisdom file ...");
+ status_text("Checking FFTW Wisdom file ...");
if(access(wisdom_file,F_OK)<0) {
int rc=sem_init(&wisdom_sem, 0, 0);
rc=pthread_create(&wisdom_thread_id, NULL, wisdom_thread, (void *)wisdom_directory);
while(sem_trywait(&wisdom_sem)<0) {
- splash_status(wisdom_get_status());
+ status_text(wisdom_get_status());
while (gtk_events_pending ())
gtk_main_iteration ();
usleep(100000); // 100ms
}
}
- discover_devices();
-
+ g_idle_add(discovery,NULL);
return 0;
}
-int main (int argc, char *argv[]) {
- gtk_init (&argc, &argv);
+static void activate_pihpsdr(GtkApplication *app, gpointer data) {
+
+
+ //gtk_init (&argc, &argv);
fprintf(stderr,"Build: %s %s\n",build_date,version);
full_screen=0;
}
- fprintf(stderr,"display_width=%d display_height=%d\n", display_width, display_height);
+fprintf(stderr,"display_width=%d display_height=%d\n", display_width, display_height);
- splash_show("hpsdr.png", display_width, display_height, full_screen);
+ fprintf(stderr,"create top level window\n");
+ top_window = gtk_application_window_new (app);
+ if(full_screen) {
+fprintf(stderr,"full screen\n");
+ gtk_window_fullscreen(GTK_WINDOW(top_window));
+ }
+ gtk_widget_set_size_request(top_window, display_width, display_height);
+ gtk_window_set_title (GTK_WINDOW (top_window), "pihpsdr");
+ gtk_window_set_position(GTK_WINDOW(top_window),GTK_WIN_POS_CENTER_ALWAYS);
+ gtk_window_set_resizable(GTK_WINDOW(top_window), FALSE);
+ g_signal_connect (top_window, "delete-event", G_CALLBACK (main_delete), NULL);
+ //g_signal_connect (top_window,"draw", G_CALLBACK (main_draw_cb), NULL);
+
+//fprintf(stderr,"create fixed container\n");
+ //fixed=gtk_fixed_new();
+ //gtk_container_add(GTK_CONTAINER(top_window), fixed);
+
+fprintf(stderr,"create grid\n");
+ grid = gtk_grid_new();
+ gtk_widget_set_size_request(grid, display_width, display_height);
+ gtk_grid_set_row_homogeneous(GTK_GRID(grid),FALSE);
+ gtk_grid_set_column_homogeneous(GTK_GRID(grid),FALSE);
+fprintf(stderr,"add grid\n");
+ gtk_container_add (GTK_CONTAINER (top_window), grid);
+
+fprintf(stderr,"create image\n");
+ GtkWidget *image=gtk_image_new_from_file("hpsdr.png");
+fprintf(stderr,"add image to grid\n");
+ gtk_grid_attach(GTK_GRID(grid), image, 0, 0, 1, 4);
+
+fprintf(stderr,"create pi label\n");
+ char build[64];
+ sprintf(build,"build: %s %s",build_date, version);
+ GtkWidget *pi_label=gtk_label_new("pihpsdr by John Melton g0orx/n6lyt");
+ gtk_label_set_justify(GTK_LABEL(pi_label),GTK_JUSTIFY_LEFT);
+ gtk_widget_show(pi_label);
+fprintf(stderr,"add pi label to grid\n");
+ gtk_grid_attach(GTK_GRID(grid),pi_label,1,0,1,1);
+
+fprintf(stderr,"create build label\n");
+ GtkWidget *build_date_label=gtk_label_new(build);
+ gtk_label_set_justify(GTK_LABEL(build_date_label),GTK_JUSTIFY_LEFT);
+ gtk_widget_show(build_date_label);
+fprintf(stderr,"add build label to grid\n");
+ gtk_grid_attach(GTK_GRID(grid),build_date_label,1,1,1,1);
+
+fprintf(stderr,"create status\n");
+ status=gtk_label_new("");
+ gtk_label_set_justify(GTK_LABEL(status),GTK_JUSTIFY_LEFT);
+ gtk_widget_override_font(status, pango_font_description_from_string("FreeMono 18"));
+ gtk_widget_show(status);
+fprintf(stderr,"add status to grid\n");
+ gtk_grid_attach(GTK_GRID(grid), status, 1, 3, 1, 1);
- g_idle_add(init,(void *)argv[0]);
+/*
+fprintf(stderr,"create exit button\n");
+ GtkWidget *button = gtk_button_new_with_label ("Exit");
+ //g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
+ g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), top_window);
+fprintf(stderr,"add exit button to grid\n");
+ gtk_grid_attach(GTK_GRID(grid), button, 1, 4, 1, 1);
+*/
- gtk_main();
+ gtk_widget_show_all(top_window);
- return 0;
+ g_idle_add(init,NULL);
+ //g_idle_add(discovery,NULL);
+
+
+}
+
+int main(int argc,char **argv) {
+ GtkApplication *pihpsdr;
+ int status;
+
+ pihpsdr=gtk_application_new("org.g0orx.pihpsdr", G_APPLICATION_FLAGS_NONE);
+ g_signal_connect(pihpsdr, "activate", G_CALLBACK(activate_pihpsdr), NULL);
+ status=g_application_run(G_APPLICATION(pihpsdr), argc, argv);
+fprintf(stderr,"exiting ...\n");
+ g_object_unref(pihpsdr);
+ return status;
}
#ifndef _MAIN_H
#define _MAIN_H
-#include <sys/utsname.h>
-extern struct utsname unameData;
-void reconfigure_display();
+#define DISPLAY_INCREMENT (display_height/32)
+#define MENU_HEIGHT (DISPLAY_INCREMENT*2)
+#define MENU_WIDTH ((display_width/32)*3)
+#define VFO_HEIGHT (DISPLAY_INCREMENT*4)
+#define VFO_WIDTH (display_width-METER_WIDTH-MENU_WIDTH)
+#define METER_HEIGHT (DISPLAY_INCREMENT*4)
+#define METER_WIDTH ((display_width/32)*8)
+#define PANADAPTER_HEIGHT (DISPLAY_INCREMENT*8)
+#define SLIDERS_HEIGHT (DISPLAY_INCREMENT*6)
+#define TOOLBAR_HEIGHT (DISPLAY_INCREMENT*2)
+#define WATERFALL_HEIGHT (display_height-(VFO_HEIGHT+PANADAPTER_HEIGHT+SLIDERS_HEIGHT+TOOLBAR_HEIGHT))
#ifdef PSK
-void show_psk();
-void show_waterfall();
+#define PSK_WATERFALL_HEIGHT (DISPLAY_INCREMENT*6)
+#define PSK_HEIGHT (display_height-(VFO_HEIGHT+PSK_WATERFALL_HEIGHT+SLIDERS_HEIGHT+TOOLBAR_HEIGHT))
#endif
+#include <sys/utsname.h>
+extern struct utsname unameData;
+
+extern gint display_width;
+extern gint display_height;
+extern gint full_screen;
+extern GtkWidget *top_window;
+extern GtkWidget *grid;
+extern void status_text(char *text);
+
#endif
cr = cairo_create (meter_surface);
cairo_set_source_rgb (cr, 0, 0, 0);
- cairo_paint (cr);
+ cairo_fill (cr);
cairo_destroy (cr);
}
GdkEventConfigure *event,
gpointer data)
{
-fprintf(stderr,"meter_configure_event_cb: width=%d height=%d\n",
- gtk_widget_get_allocated_width (widget),
- gtk_widget_get_allocated_height (widget));
if (meter_surface)
cairo_surface_destroy (meter_surface);
gtk_widget_get_allocated_height (widget));
/* Initialize the surface to black */
- meter_clear_surface ();
+ cairo_t *cr;
+ cr = cairo_create (meter_surface);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
return TRUE;
}
meter_draw_cb (GtkWidget *widget, cairo_t *cr, gpointer data) {
cairo_set_source_surface (cr, meter_surface, 0, 0);
cairo_paint (cr);
-
- return FALSE;
+ return TRUE;
}
/*
cairo_select_font_face(cr, "FreeMono",
CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_WEIGHT_BOLD);
- cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
- cairo_set_font_size(cr, 10);
+
+ cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
+ cairo_set_font_size(cr, 12);
cairo_move_to(cr, 5, 15);
cairo_show_text(cr, text);
+
if(last_meter_type!=meter_type) {
last_meter_type=meter_type;
max_count=0;
cairo_show_text(cr, sf);
#ifdef FREEDV
- if(mode==modeFREEDV) {
+ if(active_receiver->mode==modeFREEDV) {
if(freedv_sync) {
cairo_set_source_rgb(cr, 0, 1, 0);
} else {
#ifndef _METER_H
#define _METER_H
+#include <gtk/gtk.h>
+
#define SMETER 0
#define POWER 1
#ifdef PSK
gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
- GtkWidget *close_b=gtk_button_new_with_label("Close Meter");
+ GtkWidget *close_b=gtk_button_new_with_label("Close");
g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL);
gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1);
#endif
#endif
-int mode;
-
char *mode_string[MODES];
+//extern int mode;
#endif
#include "filter.h"
#include "mode.h"
#include "radio.h"
+#include "receiver.h"
#include "vfo.h"
#include "button_text.h"
static gboolean mode_select_cb (GtkWidget *widget, gpointer data) {
int m=(int)data;
- BANDSTACK_ENTRY *entry;
- entry=bandstack_entry_get_current();
- entry->mode=m;
- setMode(entry->mode);
- FILTER* band_filters=filters[entry->mode];
- FILTER* band_filter=&band_filters[entry->filter];
- setFilter(band_filter->low,band_filter->high);
set_button_text_color(last_mode,"black");
last_mode=widget;
set_button_text_color(last_mode,"orange");
- vfo_update(NULL);
+ vfo_mode_changed(m);
}
void mode_menu(GtkWidget *parent) {
g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL);
gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1);
- BANDSTACK_ENTRY *entry=bandstack_entry_get_current();
+ char label[32];
+ sprintf(label,"RX %d VFO %s",active_receiver->id,active_receiver->id==0?"A":"B");
+ GtkWidget *rx_label=gtk_label_new(label);
+ gtk_grid_attach(GTK_GRID(grid),rx_label,1,0,1,1);
+
+ int mode=vfo[active_receiver->id].mode;
for(i=0;i<MODES;i++) {
GtkWidget *b=gtk_button_new_with_label(mode_string[i]);
- if(i==entry->mode) {
+ if(i==mode) {
set_button_text_color(b,"orange");
last_mode=b;
} else {
*
*/
+#include <gtk/gtk.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
void new_discover(struct ifaddrs* iface);
-static pthread_t discover_thread_id;
-void* new_discover_receive_thread(void* arg);
+//static pthread_t discover_thread_id;
+static GThread *discover_thread_id;
+//void* new_discover_receive_thread(void* arg);
+gpointer new_discover_receive_thread(gpointer data);
void print_device(int i) {
fprintf(stderr,"discovery: found protocol=%d device=%d software_version=%d status=%d address=%s (%02X:%02X:%02X:%02X:%02X:%02X) on %s\n",
// 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);
+ interface_addr.sin_port = htons(0);
if(bind(discovery_socket,(struct sockaddr*)&interface_addr,sizeof(interface_addr))<0) {
perror("new_discover: bind socket failed for discovery_socket\n");
exit(-1);
to_addr.sin_addr.s_addr=htonl(INADDR_BROADCAST);
// start a receive thread to collect discovery response packets
+/*
rc=pthread_create(&discover_thread_id,NULL,new_discover_receive_thread,NULL);
if(rc != 0) {
fprintf(stderr,"pthread_create failed on new_discover_receive_thread: rc=%d\n", rc);
exit(-1);
}
+*/
+ discover_thread_id = g_thread_new( "new discover receive", new_discover_receive_thread, NULL);
+ if( ! discover_thread_id )
+ {
+ fprintf(stderr,"g_thread_new failed on new_discover_receive_thread\n");
+ exit( -1 );
+ }
+ fprintf(stderr,"new_disovery: thread_id=%p\n",discover_thread_id);
+
// send discovery packet
unsigned char buffer[60];
}
// wait for receive thread to complete
+/*
void* status;
pthread_join(discover_thread_id,&status);
+*/
+ g_thread_join(discover_thread_id);
close(discovery_socket);
fprintf(stderr,"new_discover: exiting discover for %s\n",iface->ifa_name);
}
-void* new_discover_receive_thread(void* arg) {
+//void* new_discover_receive_thread(void* arg) {
+gpointer new_discover_receive_thread(gpointer data) {
struct sockaddr_in addr;
int len;
unsigned char buffer[2048];
}
}
fprintf(stderr,"new_discover: exiting new_discover_receive_thread\n");
- pthread_exit(NULL);
+ //pthread_exit(NULL);
+ g_thread_exit(NULL);
}
#include "audio.h"
#include "new_menu.h"
#include "exit_menu.h"
-#include "general_menu.h"
-#include "audio_menu.h"
+#include "radio_menu.h"
+#include "rx_menu.h"
#include "ant_menu.h"
#include "display_menu.h"
#include "dsp_menu.h"
#include "filter_menu.h"
#include "noise_menu.h"
#include "agc_menu.h"
-#include "fm_menu.h"
#include "test_menu.h"
#include "vox_menu.h"
#include "diversity_menu.h"
#include "freqent_menu.h"
+#include "tx_menu.h"
+#ifdef GPIO
+#include "encoder_menu.h"
+#endif
+#include "vfo_menu.h"
+#include "main.h"
-static GtkWidget *parent_window=NULL;
-
static GtkWidget *menu_b=NULL;
static GtkWidget *dialog=NULL;
GtkWidget *sub_menu=NULL;
+int active_menu=NO_MENU;
+
static cleanup() {
if(dialog!=NULL) {
gtk_widget_destroy(dialog);
gtk_widget_destroy(sub_menu);
sub_menu=NULL;
}
+ active_menu=NO_MENU;
}
static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
static gboolean exit_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
cleanup();
- exit_menu(parent_window);
+ exit_menu(top_window);
return TRUE;
}
-static gboolean general_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+static gboolean radio_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
cleanup();
- general_menu(parent_window);
+ radio_menu(top_window);
return TRUE;
}
-static gboolean audio_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+static gboolean rx_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
cleanup();
- audio_menu(parent_window);
+ rx_menu(top_window);
return TRUE;
}
static gboolean ant_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
cleanup();
- ant_menu(parent_window);
+ ant_menu(top_window);
return TRUE;
}
static gboolean display_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
cleanup();
- display_menu(parent_window);
+ display_menu(top_window);
return TRUE;
}
static gboolean dsp_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
cleanup();
- dsp_menu(parent_window);
+ dsp_menu(top_window);
return TRUE;
}
static gboolean pa_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
cleanup();
- pa_menu(parent_window);
+ pa_menu(top_window);
return TRUE;
}
static gboolean cw_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
cleanup();
- cw_menu(parent_window);
+ cw_menu(top_window);
return TRUE;
}
static gboolean oc_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
cleanup();
- oc_menu(parent_window);
+ oc_menu(top_window);
return TRUE;
}
#ifdef FREEDV
static gboolean freedv_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
cleanup();
- freedv_menu(parent_window);
+ freedv_menu(top_window);
return TRUE;
}
#endif
static gboolean xvtr_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
cleanup();
- xvtr_menu(parent_window);
+ xvtr_menu(top_window);
return TRUE;
}
static gboolean equalizer_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
cleanup();
- equalizer_menu(parent_window);
+ equalizer_menu(top_window);
return TRUE;
}
void start_step() {
cleanup();
- step_menu(parent_window);
+ step_menu(top_window);
}
static gboolean step_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
void start_meter() {
cleanup();
- meter_menu(parent_window);
+ meter_menu(top_window);
}
static gboolean meter_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
}
void start_band() {
+ int old_menu=active_menu;
cleanup();
- band_menu(parent_window);
+ if(old_menu!=BAND_MENU) {
+ band_menu(top_window);
+ active_menu=BAND_MENU;
+ }
}
static gboolean band_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
}
void start_bandstack() {
+ int old_menu=active_menu;
cleanup();
- bandstack_menu(parent_window);
+ if(old_menu!=BANDSTACK_MENU) {
+ bandstack_menu(top_window);
+ active_menu=BANDSTACK_MENU;
+ }
}
static gboolean bandstack_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
}
void start_mode() {
+ int old_menu=active_menu;
cleanup();
- mode_menu(parent_window);
+ if(old_menu!=MODE_MENU) {
+ mode_menu(top_window);
+ active_menu=MODE_MENU;
+ }
}
static gboolean mode_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
}
void start_filter() {
+ int old_menu=active_menu;
cleanup();
- filter_menu(parent_window);
+ if(old_menu!=FILTER_MENU) {
+ filter_menu(top_window);
+ active_menu=FILTER_MENU;
+ }
}
static gboolean filter_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
}
void start_noise() {
+ int old_menu=active_menu;
cleanup();
- noise_menu(parent_window);
+ if(old_menu!=NOISE_MENU) {
+ noise_menu(top_window);
+ active_menu=NOISE_MENU;
+ }
}
static gboolean noise_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
}
void start_agc() {
+ int old_menu=active_menu;
cleanup();
- agc_menu(parent_window);
+ if(old_menu!=AGC_MENU) {
+ agc_menu(top_window);
+ active_menu=AGC_MENU;
+ }
}
static gboolean agc_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
return TRUE;
}
-void start_fm() {
- cleanup();
- fm_menu(parent_window);
-}
-
-static gboolean fm_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
- start_fm();
- return TRUE;
-}
-
void start_vox() {
cleanup();
- vox_menu(parent_window);
+ vox_menu(top_window);
}
-static gboolean vox_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+static gboolean vox_b_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
start_vox();
return TRUE;
}
void start_diversity() {
cleanup();
- diversity_menu(parent_window);
+ diversity_menu(top_window);
}
static gboolean diversity_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
void start_freqent() {
cleanup();
- freqent_menu(parent_window);
+ freqent_menu(top_window);
}
static gboolean freqent_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
return TRUE;
}
+void start_vfo() {
+ cleanup();
+ vfo_menu(top_window);
+}
+
+static gboolean vfo_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ start_vfo();
+ return TRUE;
+}
+
+void start_store() {
+ cleanup();
+ store_menu(top_window);
+}
+
+static gboolean store_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ start_store();
+ return TRUE;
+}
+
+void start_tx() {
+ cleanup();
+ tx_menu(top_window);
+}
+
+static gboolean tx_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ start_tx();
+ return TRUE;
+}
+
+#ifdef GPIO
+void start_encoder(int encoder) {
+ int old_menu=active_menu;
+fprintf(stderr,"start_encoder: encoder=%d active_menu=%d\n",encoder,active_menu);
+ cleanup();
+ switch(encoder) {
+ case 1:
+ if(old_menu!=E1_MENU) {
+ encoder_menu(top_window,encoder);
+ active_menu=E1_MENU;
+ }
+ break;
+ case 2:
+ if(old_menu!=E2_MENU) {
+ encoder_menu(top_window,encoder);
+ active_menu=E2_MENU;
+ }
+ break;
+ case 3:
+ if(old_menu!=E3_MENU) {
+ encoder_menu(top_window,encoder);
+ active_menu=E3_MENU;
+ }
+ break;
+ }
+}
+
+static gboolean encoder_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ int encoder=(int)data;
+ start_encoder(encoder);
+ return TRUE;
+}
+#endif
+
void start_test() {
cleanup();
- test_menu(parent_window);
+ test_menu(top_window);
}
static gboolean test_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
return TRUE;
}
-static gboolean new_menu_pressed_event_cb (GtkWidget *widget,
- GdkEventButton *event,
- gpointer data)
+void new_menu()
{
int i, j, id;
-
if(dialog==NULL) {
if(sub_menu!=NULL) {
}
dialog=gtk_dialog_new();
- gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window));
+ gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(top_window));
gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE);
GdkRGBA color;
g_signal_connect (exit_b, "button-press-event", G_CALLBACK(exit_cb), NULL);
gtk_grid_attach(GTK_GRID(grid),exit_b,4,0,2,1);
- GtkWidget *general_b=gtk_button_new_with_label("General");
- g_signal_connect (general_b, "button-press-event", G_CALLBACK(general_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),general_b,0,1,1,1);
+ i=5;
- GtkWidget *audio_b=gtk_button_new_with_label("Audio");
- g_signal_connect (audio_b, "button-press-event", G_CALLBACK(audio_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),audio_b,1,1,1,1);
+ GtkWidget *radio_b=gtk_button_new_with_label("Radio");
+ g_signal_connect (radio_b, "button-press-event", G_CALLBACK(radio_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),radio_b,(i%5),i/5,1,1);
+ i++;
- GtkWidget *ant_b=gtk_button_new_with_label("Ant");
- g_signal_connect (ant_b, "button-press-event", G_CALLBACK(ant_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),ant_b,2,1,1,1);
+ GtkWidget *rx_b=gtk_button_new_with_label("RX");
+ g_signal_connect (rx_b, "button-press-event", G_CALLBACK(rx_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),rx_b,(i%5),i/5,1,1);
+ i++;
- GtkWidget *display_b=gtk_button_new_with_label("Display");
- g_signal_connect (display_b, "button-press-event", G_CALLBACK(display_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),display_b,3,1,1,1);
-
- GtkWidget *dsp_b=gtk_button_new_with_label("DSP");
- g_signal_connect (dsp_b, "button-press-event", G_CALLBACK(dsp_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),dsp_b,4,1,1,1);
+ GtkWidget *tx_b=gtk_button_new_with_label("TX");
+ g_signal_connect (tx_b, "button-press-event", G_CALLBACK(tx_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),tx_b,(i%5),i/5,1,1);
+ i++;
GtkWidget *pa_b=gtk_button_new_with_label("PA");
g_signal_connect (pa_b, "button-press-event", G_CALLBACK(pa_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),pa_b,5,1,1,1);
+ gtk_grid_attach(GTK_GRID(grid),pa_b,(i%5),i/5,1,1);
+ i++;
GtkWidget *cw_b=gtk_button_new_with_label("CW");
g_signal_connect (cw_b, "button-press-event", G_CALLBACK(cw_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),cw_b,0,2,1,1);
+ gtk_grid_attach(GTK_GRID(grid),cw_b,(i%5),i/5,1,1);
+ i++;
+
+ GtkWidget *ant_b=gtk_button_new_with_label("Ant");
+ g_signal_connect (ant_b, "button-press-event", G_CALLBACK(ant_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),ant_b,(i%5),i/5,1,1);
+ i++;
+
+ GtkWidget *dsp_b=gtk_button_new_with_label("DSP");
+ g_signal_connect (dsp_b, "button-press-event", G_CALLBACK(dsp_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),dsp_b,(i%5),i/5,1,1);
+ i++;
GtkWidget *oc_b=gtk_button_new_with_label("OC");
g_signal_connect (oc_b, "button-press-event", G_CALLBACK(oc_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),oc_b,1,2,1,1);
+ gtk_grid_attach(GTK_GRID(grid),oc_b,(i%5),i/5,1,1);
+ i++;
#ifdef FREEDV
GtkWidget *freedv_b=gtk_button_new_with_label("FreeDV");
g_signal_connect (freedv_b, "button-press-event", G_CALLBACK(freedv_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),freedv_b,2,2,1,1);
+ gtk_grid_attach(GTK_GRID(grid),freedv_b,(i%5),i/5,1,1);
+ i++;
#endif
+ GtkWidget *display_b=gtk_button_new_with_label("Display");
+ g_signal_connect (display_b, "button-press-event", G_CALLBACK(display_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),display_b,(i%5),i/5,1,1);
+ i++;
+
GtkWidget *xvtr_b=gtk_button_new_with_label("XVTR");
g_signal_connect (xvtr_b, "button-press-event", G_CALLBACK(xvtr_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),xvtr_b,3,2,1,1);
+ gtk_grid_attach(GTK_GRID(grid),xvtr_b,(i%5),i/5,1,1);
+ i++;
GtkWidget *equalizer_b=gtk_button_new_with_label("Equalizer");
g_signal_connect (equalizer_b, "button-press-event", G_CALLBACK(equalizer_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),equalizer_b,4,2,1,1);
-
- GtkWidget *fm_b=gtk_button_new_with_label("FM");
- g_signal_connect (fm_b, "button-press-event", G_CALLBACK(fm_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),fm_b,5,2,1,1);
+ gtk_grid_attach(GTK_GRID(grid),equalizer_b,(i%5),i/5,1,1);
+ i++;
GtkWidget *step_b=gtk_button_new_with_label("Step");
g_signal_connect (step_b, "button-press-event", G_CALLBACK(step_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),step_b,0,3,1,1);
+ gtk_grid_attach(GTK_GRID(grid),step_b,(i%5),i/5,1,1);
+ i++;
GtkWidget *meter_b=gtk_button_new_with_label("Meter");
g_signal_connect (meter_b, "button-press-event", G_CALLBACK(meter_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),meter_b,1,3,1,1);
+ gtk_grid_attach(GTK_GRID(grid),meter_b,(i%5),i/5,1,1);
+ i++;
GtkWidget *vox_b=gtk_button_new_with_label("VOX");
- g_signal_connect (vox_b, "button-press-event", G_CALLBACK(vox_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),vox_b,2,3,1,1);
-
- GtkWidget *frequency_b=gtk_button_new_with_label("Frequency");
- g_signal_connect (frequency_b, "button-press-event", G_CALLBACK(freqent_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),frequency_b,3,3,1,1);
+ g_signal_connect (vox_b, "button-press-event", G_CALLBACK(vox_b_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),vox_b,(i%5),i/5,1,1);
+ i++;
+#ifdef DIVERSITY
if(RECEIVERS==2) {
GtkWidget *diversity_b=gtk_button_new_with_label("Diversity");
g_signal_connect (diversity_b, "button-press-event", G_CALLBACK(diversity_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),diversity_b,4,3,1,1);
+ gtk_grid_attach(GTK_GRID(grid),diversity_b,(i%5),i/5,1,1);
+ i++;
}
-
- GtkWidget *band_b=gtk_button_new_with_label("Band");
- g_signal_connect (band_b, "button-press-event", G_CALLBACK(band_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),band_b,0,4,1,1);
-
- GtkWidget *bandstack_b=gtk_button_new_with_label("Band Stack");
- g_signal_connect (bandstack_b, "button-press-event", G_CALLBACK(bandstack_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),bandstack_b,1,4,1,1);
-
- GtkWidget *mode_b=gtk_button_new_with_label("Mode");
- g_signal_connect (mode_b, "button-press-event", G_CALLBACK(mode_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),mode_b,2,4,1,1);
-
- GtkWidget *filter_b=gtk_button_new_with_label("Filter");
- g_signal_connect (filter_b, "button-press-event", G_CALLBACK(filter_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),filter_b,3,4,1,1);
-
- GtkWidget *noise_b=gtk_button_new_with_label("Noise");
- g_signal_connect (noise_b, "button-press-event", G_CALLBACK(noise_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),noise_b,4,4,1,1);
-
- GtkWidget *agc_b=gtk_button_new_with_label("AGC");
- g_signal_connect (agc_b, "button-press-event", G_CALLBACK(agc_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),agc_b,5,4,1,1);
-
- GtkWidget *test_b=gtk_button_new_with_label("Test");
- g_signal_connect (test_b, "button-press-event", G_CALLBACK(test_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),test_b,0,5,1,1);
+#endif
gtk_container_add(GTK_CONTAINER(content),grid);
dialog=NULL;
}
- return TRUE;
-}
-
-GtkWidget* new_menu_init(int width,int height,GtkWidget *parent) {
-
- parent_window=parent;
-
- menu_b=gtk_button_new_with_label("Menu");
- gtk_widget_override_font(menu_b, pango_font_description_from_string("FreeMono Bold 10"));
- gtk_widget_set_size_request (menu_b, width, height);
- g_signal_connect (menu_b, "button-press-event", G_CALLBACK(new_menu_pressed_event_cb), NULL);
- gtk_widget_show(menu_b);
-
- return menu_b;
}
GtkWidget *sub_menu;
-GtkWidget* new_menu_init(int width,int height,GtkWidget *parent);
-
-void start_step();
-void start_meter();
-void start_band();
-void start_bandstack();
-void start_mode();
-void start_filter();
-void start_noise();
+extern void new_menu();
+
+/*
+extern GtkWidget* new_menu_init(int width,int height,GtkWidget *parent);
+*/
+extern void start_step();
+extern void start_meter();
+extern void start_band();
+extern void start_bandstack();
+extern void start_mode();
+extern void start_filter();
+extern void start_noise();
+extern void start_encoder();
+
+extern void encoder_step(int encoder,int step);
+
+enum {
+ NO_MENU = 0,
+ E1_MENU,
+ E2_MENU,
+ E3_MENU,
+ BAND_MENU,
+ BANDSTACK_MENU,
+ MODE_MENU,
+ FILTER_MENU,
+ NOISE_MENU,
+ AGC_MENU
+};
+
+extern int active_menu;
#include <net/if_arp.h>
#include <net/if.h>
#include <ifaddrs.h>
-#include <pthread.h>
#include <semaphore.h>
#include <math.h>
+#include <wdsp.h>
+
#include "alex.h"
#include "audio.h"
#include "band.h"
#include "new_protocol.h"
#include "channel.h"
#include "discovered.h"
-#include "wdsp.h"
#include "mode.h"
#include "filter.h"
#include "radio.h"
+#include "receiver.h"
+#include "transmitter.h"
#include "signal.h"
#include "vfo.h"
#include "toolbar.h"
-#include "wdsp_init.h"
#ifdef FREEDV
#include "freedv.h"
#endif
static struct sockaddr_in iq_addr;
static int iq_addr_length;
-static struct sockaddr_in data_addr[RECEIVERS];
-static int data_addr_length[RECEIVERS];
+static struct sockaddr_in data_addr[MAX_RECEIVERS];
+static int data_addr_length[MAX_RECEIVERS];
-static pthread_t new_protocol_thread_id;
-static pthread_t new_protocol_timer_thread_id;
+static GThread *new_protocol_thread_id;
+static GThread *new_protocol_timer_thread_id;
static long rx_sequence = 0;
static long rx_specific_sequence = 0;
static long tx_specific_sequence = 0;
-static int buffer_size=BUFFER_SIZE;
-static int fft_size=4096;
+//static int buffer_size=BUFFER_SIZE;
+//static int fft_size=4096;
static int dspRate=48000;
static int outputRate=48000;
static int micSampleRate=48000;
static int micDspRate=48000;
static int micOutputRate=192000;
-static int micoutputsamples=BUFFER_SIZE*4; // 48000 in, 192000 out
+static int micoutputsamples; // 48000 in, 192000 out
-static double micinputbuffer[BUFFER_SIZE*2]; // 48000
-static double iqoutputbuffer[BUFFER_SIZE*4*2]; //192000
+static double micinputbuffer[MAX_BUFFER_SIZE*2]; // 48000
+static double iqoutputbuffer[MAX_BUFFER_SIZE*4*2]; //192000
static long tx_iq_sequence;
static unsigned char iqbuffer[1444];
static sem_t send_general_sem;
static int send_general=0;
-static int samples[RECEIVERS];
-static int outputsamples=BUFFER_SIZE;
-
-static double iqinputbuffer[RECEIVERS][BUFFER_SIZE*2];
-static double audiooutputbuffer[BUFFER_SIZE*2];
+static int samples[MAX_RECEIVERS];
+#ifdef INCLUDED
+static int outputsamples;
+#endif
static int leftaudiosample;
static int rightaudiosample;
static int psk_resample=6; // convert from 48000 to 8000
#endif
+static struct sockaddr_in addr;
+static int length;
+static unsigned char buffer[2048];
+static int bytesread;
+
static void new_protocol_high_priority(int run);
-static void* new_protocol_thread(void* arg);
-static void* new_protocol_timer_thread(void* arg);
-static void process_iq_data(int rx,unsigned char *buffer);
+//static void* new_protocol_thread(void* arg);
+static gpointer new_protocol_thread(gpointer data);
+//static void* new_protocol_timer_thread(void* arg);
+static gpointer new_protocol_timer_thread(gpointer data);
+static void process_iq_data(RECEIVER *rx,unsigned char *buffer);
static void process_command_response(unsigned char *buffer);
static void process_high_priority(unsigned char *buffer);
-static void process_mic_data(unsigned char *buffer);
-static void full_rx_buffer();
+static void process_mic_data(unsigned char *buffer,int bytes);
static void full_tx_buffer();
+#ifdef INCLUDED
static void new_protocol_calc_buffers() {
switch(sample_rate) {
case 48000:
- outputsamples=BUFFER_SIZE;
+ outputsamples=buffer_size;
break;
case 96000:
- outputsamples=BUFFER_SIZE/2;
+ outputsamples=buffer_size/2;
break;
case 192000:
- outputsamples=BUFFER_SIZE/4;
+ outputsamples=buffer_size/4;
break;
case 384000:
- outputsamples=BUFFER_SIZE/8;
+ outputsamples=buffer_size/8;
break;
case 768000:
- outputsamples=BUFFER_SIZE/16;
+ outputsamples=buffer_size/16;
break;
case 1536000:
- outputsamples=BUFFER_SIZE/32;
+ outputsamples=buffer_size/32;
break;
}
}
+#endif
-void schedule_high_priority(int source) {
+void schedule_high_priority() {
sem_wait(&send_high_priority_sem);
send_high_priority=1;
sem_post(&send_high_priority_sem);
int rc;
spectrumWIDTH=pixels;
- fprintf(stderr,"new_protocol_init\n");
+ fprintf(stderr,"new_protocol_init: MIC_SAMPLES=%d\n",MIC_SAMPLES);
+#ifdef INCLUDED
+ outputsamples=buffer_size;
+#endif
+ micoutputsamples=buffer_size*4;
+
+#ifdef OLD_AUDIO
if(local_audio) {
if(audio_open_output()!=0) {
fprintf(stderr,"audio_open_output failed\n");
local_audio=0;
}
}
+#endif
- if(local_microphone) {
+ if(transmitter->local_microphone) {
if(audio_open_input()!=0) {
fprintf(stderr,"audio_open_input failed\n");
- local_microphone=0;
+ transmitter->local_microphone=0;
}
}
+#ifdef INCLUDED
new_protocol_calc_buffers();
+#endif
rc=sem_init(&response_sem, 0, 0);
rc=sem_init(&send_high_priority_sem, 0, 1);
rc=sem_init(&send_general_sem, 0, 1);
- rc=pthread_create(&new_protocol_thread_id,NULL,new_protocol_thread,NULL);
- if(rc != 0) {
- fprintf(stderr,"pthread_create failed on new_protocol_thread: rc=%d\n", rc);
- exit(-1);
+ new_protocol_thread_id = g_thread_new( "new protocol", new_protocol_thread, NULL);
+ if( ! new_protocol_thread_id )
+ {
+ fprintf(stderr,"g_thread_new failed on new_protocol_thread\n");
+ exit( -1 );
}
+ fprintf(stderr, "new_protocol_thread: id=%p\n",new_protocol_thread_id);
-}
-void new_protocol_new_sample_rate(int rate) {
- new_protocol_high_priority(0);
- sample_rate=rate;
- new_protocol_calc_buffers();
- wdsp_new_sample_rate(rate);
- new_protocol_high_priority(1);
}
static void new_protocol_general() {
}
if(filter_board==APOLLO) {
- buffer[58]|=0x02; // enable APOLLO tuner
+ buffer[58]|=0x02; // enable APOLLO tuner
}
if(filter_board==ALEX) {
+ if(device==NEW_DEVICE_ORION2) {
+ buffer[59]=0x03; // enable Alex 0 and 1
+ } else {
buffer[59]=0x01; // enable Alex 0
+ }
}
+fprintf(stderr,"Alex Enable=%02X\n",buffer[59]);
+
if(sendto(data_socket,buffer,sizeof(buffer),0,(struct sockaddr*)&base_addr,base_addr_length)<0) {
fprintf(stderr,"sendto socket failed for general\n");
exit(1);
}
static void new_protocol_high_priority(int run) {
- int r;
+ int i, r;
unsigned char buffer[1444];
- BAND *band=band_get_current_band();
+ BAND *band;
+ long long rxFrequency;
+ long long txFrequency;
+ long phase;
+ int mode;
memset(buffer, 0, sizeof(buffer));
buffer[2]=high_priority_sequence>>8;
buffer[3]=high_priority_sequence;
+ if(split) {
+ mode=vfo[1].mode;
+ } else {
+ mode=vfo[0].mode;
+ }
buffer[4]=run;
if(mode==modeCWU || mode==modeCWL) {
if(tune) {
}
}
- long rxFrequency=ddsFrequency;
- if(mode==modeCWU) {
- rxFrequency-=cw_keyer_sidetone_frequency;
- } else if(mode==modeCWL) {
- rxFrequency+=cw_keyer_sidetone_frequency;
- }
- long phase=(long)((4294967296.0*(double)rxFrequency)/122880000.0);
-
// rx
for(r=0;r<receivers;r++) {
- buffer[9+(r*4)]=phase>>24;
- buffer[10+(r*4)]=phase>>16;
- buffer[11+(r*4)]=phase>>8;
- buffer[12+(r*4)]=phase;
+ //long long rxFrequency=ddsFrequency;
+ //rxFrequency=receiver[r]->dds_frequency;
+ int v=receiver[r]->id;
+ rxFrequency=vfo[v].frequency-vfo[v].lo+vfo[v].rit;
+
+ if(vfo[v].mode==modeCWU) {
+ rxFrequency-=cw_keyer_sidetone_frequency;
+ } else if(vfo[v].mode==modeCWL) {
+ rxFrequency+=cw_keyer_sidetone_frequency;
+ }
+ phase=(long)((4294967296.0*(double)rxFrequency)/122880000.0);
+
+ i=r;
+ //if(device==NEW_DEVICE_ORION2 && r==1) i=3;
+ buffer[9+(i*4)]=phase>>24;
+ buffer[10+(i*4)]=phase>>16;
+ buffer[11+(i*4)]=phase>>8;
+ buffer[12+(i*4)]=phase;
}
-// tx (no split yet)
- long long txFrequency=ddsFrequency;
- if(ctun) {
- txFrequency+=ddsOffset;
+ // tx
+ band=band_get_band(vfo[VFO_A].band);
+ rxFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo;
+ txFrequency=vfo[VFO_A].frequency-vfo[VFO_A].lo;
+ if(split) {
+ band=band_get_band(vfo[VFO_B].band);
+ txFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo;
}
+
phase=(long)((4294967296.0*(double)txFrequency)/122880000.0);
buffer[329]=phase>>24;
buffer[345]=power&0xFF;
if(isTransmitting()) {
- buffer[1401]=band->OCtx;
+
+ if(split) {
+ band=band_get_band(vfo[VFO_B].band);
+ } else {
+ band=band_get_band(vfo[VFO_A].band);
+ }
+ buffer[1401]=band->OCtx<<1;
if(tune) {
if(OCmemory_tune_time!=0) {
struct timeval te;
gettimeofday(&te,NULL);
long long now=te.tv_sec*1000LL+te.tv_usec/1000;
if(tune_timeout>now) {
- buffer[1401]|=OCtune;
+ buffer[1401]|=OCtune<<1;
}
} else {
- buffer[1401]|=OCtune;
+ buffer[1401]|=OCtune<<1;
}
}
} else {
- buffer[1401]=band->OCrx;
+ band=band_get_band(vfo[VFO_A].band);
+ buffer[1401]=band->OCrx<<1;
+ }
+
+ if((protocol==ORIGINAL_PROTOCOL && device==DEVICE_METIS) ||
+#ifdef USBOZY
+ (protocol==ORIGINAL_PROTOCOL && device==DEVICE_OZY) ||
+#endif
+ (protocol==NEW_PROTOCOL && device==NEW_DEVICE_ATLAS)) {
+ for(r=0;r<receivers;r++) {
+ buffer[1403]|=receiver[i]->preamp;
+ }
}
filters=0x08000000;
}
-// Alex RX HPF filters
-/*
-if (frequency < 1800000) HPF <= 6'b100000; // bypass
-else if (frequency < 6500000) HPF <= 6'b010000; // 1.5MHz HPF
-else if (frequency < 9500000) HPF <= 6'b001000; // 6.5MHz HPF
-else if (frequency < 13000000) HPF <= 6'b000100; // 9.5MHz HPF
-else if (frequency < 20000000) HPF <= 6'b000001; // 13MHz HPF
-else HPF <= 6'b000010; // 20MHz HPF
-*/
-
- if(ddsFrequency<1800000L) {
+ if(rxFrequency<1800000L) {
filters|=ALEX_BYPASS_HPF;
- } else if(ddsFrequency<6500000L) {
+ } else if(rxFrequency<6500000L) {
filters|=ALEX_1_5MHZ_HPF;
- } else if(ddsFrequency<9500000L) {
+ } else if(rxFrequency<9500000L) {
filters|=ALEX_6_5MHZ_HPF;
- } else if(ddsFrequency<13000000L) {
+ } else if(rxFrequency<13000000L) {
filters|=ALEX_9_5MHZ_HPF;
- } else if(ddsFrequency<20000000L) {
+ } else if(rxFrequency<20000000L) {
filters|=ALEX_13MHZ_HPF;
} else {
filters|=ALEX_20MHZ_HPF;
}
-// Alex TX LPF filters
-/*
-if (frequency > 32000000) LPF <= 7'b0010000; // > 10m so use 6m LPF^M
-else if (frequency > 22000000) LPF <= 7'b0100000; // > 15m so use 12/10m LPF^M
-else if (frequency > 15000000) LPF <= 7'b1000000; // > 20m so use 17/15m LPF^M
-else if (frequency > 8000000) LPF <= 7'b0000001; // > 40m so use 30/20m LPF ^M
-else if (frequency > 4500000) LPF <= 7'b0000010; // > 80m so use 60/40m LPF^M
-else if (frequency > 2400000) LPF <= 7'b0000100; // > 160m so use 80m LPF ^M
-else LPF <= 7'b0001000; // < 2.4MHz so use 160m LPF^M
-*/
+ if(rxFrequency>30000000L) {
+ filters|=ALEX_6M_PREAMP;
+ }
- if(ddsFrequency>32000000) {
+ if(txFrequency>32000000) {
filters|=ALEX_6_BYPASS_LPF;
- } else if(ddsFrequency>22000000) {
+ } else if(txFrequency>22000000) {
filters|=ALEX_12_10_LPF;
- } else if(ddsFrequency>15000000) {
+ } else if(txFrequency>15000000) {
filters|=ALEX_17_15_LPF;
- } else if(ddsFrequency>8000000) {
+ } else if(txFrequency>8000000) {
filters|=ALEX_30_20_LPF;
- } else if(ddsFrequency>4500000) {
+ } else if(txFrequency>4500000) {
filters|=ALEX_60_40_LPF;
- } else if(ddsFrequency>2400000) {
+ } else if(txFrequency>2400000) {
filters|=ALEX_80_LPF;
} else {
filters|=ALEX_160_LPF;
}
-
- switch(band->alexRxAntenna) {
+ switch(receiver[0]->alex_antenna) {
case 0: // ANT 1
break;
case 1: // ANT 2
}
if(isTransmitting()) {
- switch(band->alexTxAntenna) {
+ switch(transmitter->alex_antenna) {
case 0: // ANT 1
filters|=ALEX_TX_ANTENNA_1;
break;
}
} else {
- switch(band->alexRxAntenna) {
+ switch(receiver[0]->alex_antenna) {
case 0: // ANT 1
filters|=ALEX_TX_ANTENNA_1;
break;
case 3: // EXT 1
case 4: // EXT 2
case 5: // XVTR
- switch(band->alexTxAntenna) {
+ switch(transmitter->alex_antenna) {
case 0: // ANT 1
filters|=ALEX_TX_ANTENNA_1;
break;
buffer[1433]=(filters>>16)&0xFF;
buffer[1434]=(filters>>8)&0xFF;
buffer[1435]=filters&0xFF;
+//fprintf(stderr,"HPF: 0: %02X %02X for %lld\n",buffer[1434],buffer[1435],rxFrequency);
+
+ filters=0x00000000;
+ rxFrequency=vfo[VFO_B].frequency-vfo[VFO_B].lo;
+ if(rxFrequency<1800000L) {
+ filters|=ALEX_BYPASS_HPF;
+ } else if(rxFrequency<6500000L) {
+ filters|=ALEX_1_5MHZ_HPF;
+ } else if(rxFrequency<9500000L) {
+ filters|=ALEX_6_5MHZ_HPF;
+ } else if(rxFrequency<13000000L) {
+ filters|=ALEX_9_5MHZ_HPF;
+ } else if(rxFrequency<20000000L) {
+ filters|=ALEX_13MHZ_HPF;
+ } else {
+ filters|=ALEX_20MHZ_HPF;
+ }
+
+ if(rxFrequency>30000000L) {
+ filters|=ALEX_6M_PREAMP;
+ }
- //buffer[1442]=attenuation;
- buffer[1443]=attenuation;
-//fprintf(stderr,"high_priority[4]=0x%02X\n", buffer[4]);
-//fprintf(stderr,"filters=%04X\n", filters);
+ buffer[1428]=(filters>>24)&0xFF;
+ buffer[1429]=(filters>>16)&0xFF;
+ buffer[1430]=(filters>>8)&0xFF;
+ buffer[1431]=filters&0xFF;
+
+//fprintf(stderr,"HPF: 1: %02X %02X for %lld\n",buffer[1430],buffer[1431],rxFrequency);
+// rx_frequency
+
+//fprintf(stderr,"new_protocol_high_priority: OC=%02X filters=%04X for frequency=%lld\n", buffer[1401], filters, rxFrequency);
+
+ for(r=0;r<receivers;r++) {
+ i=r;
+ //if(device==NEW_DEVICE_ORION2 && r==1) i=3;
+ buffer[1443-i]=receiver[r]->attenuation;
+ }
if(sendto(data_socket,buffer,sizeof(buffer),0,(struct sockaddr*)&high_priority_addr,high_priority_addr_length)<0) {
fprintf(stderr,"sendto socket failed for high priority\n");
static void new_protocol_transmit_specific() {
unsigned char buffer[60];
+ int mode;
memset(buffer, 0, sizeof(buffer));
buffer[2]=tx_specific_sequence>>8;
buffer[3]=tx_specific_sequence;
+ if(split) {
+ mode=vfo[1].mode;
+ } else {
+ mode=vfo[0].mode;
+ }
buffer[4]=1; // 1 DAC
buffer[5]=0; // default no CW
// may be using local pihpsdr OR hpsdr CW
}
buffer[6]=cw_keyer_sidetone_volume; // sidetone off
- buffer[7]=cw_keyer_sidetone_frequency>>8; buffer[8]=cw_keyer_sidetone_frequency; // sidetone frequency
+ buffer[7]=cw_keyer_sidetone_frequency>>8;
+ buffer[8]=cw_keyer_sidetone_frequency; // sidetone frequency
buffer[9]=cw_keyer_speed; // cw keyer speed
buffer[10]=cw_keyer_weight; // cw weight
- buffer[11]=cw_keyer_hang_time>>8; buffer[12]=cw_keyer_hang_time; // cw hang delay
+ buffer[11]=cw_keyer_hang_time>>8;
+ buffer[12]=cw_keyer_hang_time; // cw hang delay
buffer[13]=0; // rf delay
buffer[50]=0;
if(mic_linein) {
if(mic_boost) {
buffer[50]|=0x02;
}
- if(mic_ptt_enabled==0) {
+ if(mic_ptt_enabled==0) { // set if disabled
buffer[50]|=0x04;
}
- if(mic_bias_enabled) {
- buffer[50]|=0x10;
- }
if(mic_ptt_tip_bias_ring) {
buffer[50]|=0x08;
}
+ if(mic_bias_enabled) {
+ buffer[50]|=0x10;
+ }
// 0..31
buffer[51]=linein_gain;
buffer[3]=rx_specific_sequence;
buffer[4]=2; // 2 ADCs
- buffer[5]=0; // dither off
- if(lt2208Dither) {
- for(i=0;i<receivers;i++) {
- buffer[5]|=0x01<<i;
- }
- }
- buffer[6]=0; // random off
- if(lt2208Random) {
- for(i=0;i<receivers;i++) {
- buffer[6]|=0x01<<i;
- }
- }
- buffer[7]=0x00;
- for(i=0;i<receivers;i++) {
- buffer[7]|=(1<<i);
- }
-
+
for(i=0;i<receivers;i++) {
- buffer[17+(i*6)]=adc[i];
+ int r=i;
+ //if(device==NEW_DEVICE_ORION2 && r==1) r=3;
+ buffer[5]|=receiver[i]->dither<<r; // dither enable
+ buffer[6]|=receiver[i]->random<<r; // random enable
+ buffer[7]|=(1<<r); // DDC enbale
+ buffer[17+(r*6)]=receiver[i]->adc;
+ buffer[18+(r*6)]=((receiver[i]->sample_rate/1000)>>8)&0xFF;
+ buffer[19+(r*6)]=(receiver[i]->sample_rate/1000)&0xFF;
+ buffer[22+(r*6)]=24;
}
- buffer[18]=((sample_rate/1000)>>8)&0xFF;
- buffer[19]=(sample_rate/1000)&0xFF;
- buffer[22]=24;
-
- buffer[24]=((sample_rate/1000)>>8)&0xFF;
- buffer[25]=(sample_rate/1000)&0xFF;
- buffer[28]=24;
if(sendto(data_socket,buffer,sizeof(buffer),0,(struct sockaddr*)&receiver_addr,receiver_addr_length)<0) {
fprintf(stderr,"sendto socket failed for start\n");
running=1;
new_protocol_transmit_specific();
new_protocol_receive_specific();
- int rc=pthread_create(&new_protocol_timer_thread_id,NULL,new_protocol_timer_thread,NULL);
- if(rc != 0) {
- fprintf(stderr,"pthread_create failed on new_protocol_timer_thread: %d\n", rc);
- exit(-1);
+ new_protocol_timer_thread_id = g_thread_new( "new protocol timer", new_protocol_timer_thread, NULL);
+ if( ! new_protocol_timer_thread_id )
+ {
+ fprintf(stderr,"g_thread_new failed on new_protocol_timer_thread\n");
+ exit( -1 );
}
+ fprintf(stderr, "new_protocol_timer_thread: id=%p\n",new_protocol_timer_thread_id);
+
}
void new_protocol_stop() {
new_protocol_high_priority(0);
- running=0;
- sleep(1);
+ usleep(100000); // 100 ms
+}
+
+void new_protocol_run() {
+ new_protocol_high_priority(1);
}
double calibrate(int v) {
return (v1*v1)/0.095;
}
-void* new_protocol_thread(void* arg) {
+//void* new_protocol_thread(void* arg) {
+static gpointer new_protocol_thread(gpointer data) {
int i;
- struct sockaddr_in addr;
- int length;
- unsigned char buffer[2048];
- int bytesread;
short sourceport;
fprintf(stderr,"new_protocol_thread\n");
iqindex=4;
-fprintf(stderr,"outputsamples=%d\n", outputsamples);
data_socket=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(data_socket<0) {
fprintf(stderr,"metis: create socket failed for data_socket\n");
iq_addr.sin_port=htons(TX_IQ_FROM_HOST_PORT);
- for(i=0;i<RECEIVERS;i++) {
+ for(i=0;i<MAX_RECEIVERS;i++) {
memcpy(&data_addr[i],&radio->info.network.address,radio->info.network.address_length);
data_addr_length[i]=radio->info.network.address_length;
data_addr[i].sin_port=htons(RX_IQ_TO_HOST_PORT_0+i);
case RX_IQ_TO_HOST_PORT_5:
case RX_IQ_TO_HOST_PORT_6:
case RX_IQ_TO_HOST_PORT_7:
- process_iq_data(sourceport-RX_IQ_TO_HOST_PORT_0,buffer);
+ i=sourceport-RX_IQ_TO_HOST_PORT_0;
+ //if(device==NEW_DEVICE_ORION2 && i==3) {
+ // i=1;
+ //}
+ process_iq_data(receiver[i],buffer);
break;
case COMMAND_RESPONCE_TO_HOST_PORT:
process_command_response(buffer);
process_high_priority(buffer);
break;
case MIC_LINE_TO_HOST_PORT:
- if(!local_microphone) {
- process_mic_data(buffer);
+ if(!transmitter->local_microphone) {
+ process_mic_data(buffer,bytesread);
}
break;
default:
}
if(running) {
- sem_wait(&send_general_sem);
- if(send_general==1) {
- new_protocol_general();
- send_general=0;
- }
- sem_post(&send_general_sem);
-
sem_wait(&send_high_priority_sem);
if(send_high_priority==1) {
new_protocol_high_priority(1);
send_high_priority=0;
}
sem_post(&send_high_priority_sem);
+
+ sem_wait(&send_general_sem);
+ if(send_general==1) {
+ new_protocol_general();
+ send_general=0;
+ }
+ sem_post(&send_general_sem);
}
}
close(data_socket);
}
-static void process_iq_data(int rx,unsigned char *buffer) {
- long sequence;
- long long timestamp;
- int bitspersample;
- int samplesperframe;
- int b;
- int leftsample;
- int rightsample;
- double leftsampledouble;
- double rightsampledouble;
-
- sequence=((buffer[0]&0xFF)<<24)+((buffer[1]&0xFF)<<16)+((buffer[2]&0xFF)<<8)+(buffer[3]&0xFF);
- timestamp=((long long)(buffer[4]&0xFF)<<56)+((long long)(buffer[5]&0xFF)<<48)+((long long)(buffer[6]&0xFF)<<40)+((long long)(buffer[7]&0xFF)<<32);
- ((long long)(buffer[8]&0xFF)<<24)+((long long)(buffer[9]&0xFF)<<16)+((long long)(buffer[10]&0xFF)<<8)+(long long)(buffer[11]&0xFF);
- bitspersample=((buffer[12]&0xFF)<<8)+(buffer[13]&0xFF);
- samplesperframe=((buffer[14]&0xFF)<<8)+(buffer[15]&0xFF);
-
- //if(!isTransmitting()) {
- b=16;
- int i;
- for(i=0;i<samplesperframe;i++) {
- leftsample = (int)((signed char) buffer[b++]) << 16;
- leftsample += (int)((unsigned char)buffer[b++]) << 8;
- leftsample += (int)((unsigned char)buffer[b++]);
- rightsample = (int)((signed char) buffer[b++]) << 16;
- rightsample += (int)((unsigned char)buffer[b++]) << 8;
- rightsample += (int)((unsigned char)buffer[b++]);
-
- leftsampledouble=(double)leftsample/8388607.0; // for 24 bits
- rightsampledouble=(double)rightsample/8388607.0; // for 24 bits
-
- iqinputbuffer[rx][samples[rx]*2]=leftsampledouble;
- iqinputbuffer[rx][(samples[rx]*2)+1]=rightsampledouble;
-
- samples[rx]++;
- if(samples[rx]==BUFFER_SIZE) {
- full_rx_buffer(rx);
- samples[rx]=0;
- }
- }
- //}
+static void process_iq_data(RECEIVER *rx,unsigned char *buffer) {
+ long sequence;
+ long long timestamp;
+ int bitspersample;
+ int samplesperframe;
+ int b;
+ int leftsample;
+ int rightsample;
+ double leftsampledouble;
+ double rightsampledouble;
+
+ sequence=((buffer[0]&0xFF)<<24)+((buffer[1]&0xFF)<<16)+((buffer[2]&0xFF)<<8)+(buffer[3]&0xFF);
+ timestamp=((long long)(buffer[4]&0xFF)<<56)+((long long)(buffer[5]&0xFF)<<48)+((long long)(buffer[6]&0xFF)<<40)+((long long)(buffer[7]&0xFF)<<32);
+ ((long long)(buffer[8]&0xFF)<<24)+((long long)(buffer[9]&0xFF)<<16)+((long long)(buffer[10]&0xFF)<<8)+(long long)(buffer[11]&0xFF);
+ bitspersample=((buffer[12]&0xFF)<<8)+(buffer[13]&0xFF);
+ samplesperframe=((buffer[14]&0xFF)<<8)+(buffer[15]&0xFF);
+
+//fprintf(stderr,"process_iq_data: rx=%d seq=%ld bitspersample=%d samplesperframe=%d\n",rx->id, sequence,bitspersample,samplesperframe);
+ b=16;
+ int i;
+ for(i=0;i<samplesperframe;i++) {
+ leftsample = (int)((signed char) buffer[b++])<<16;
+ leftsample |= (int)((((unsigned char)buffer[b++])<<8)&0xFF00);
+ leftsample |= (int)((unsigned char)buffer[b++]&0xFF);
+ rightsample = (int)((signed char)buffer[b++]) << 16;
+ rightsample |= (int)((((unsigned char)buffer[b++])<<8)&0xFF00);
+ rightsample |= (int)((unsigned char)buffer[b++]&0xFF);
+
+ leftsampledouble=(double)leftsample/8388607.0; // for 24 bits
+ rightsampledouble=(double)rightsample/8388607.0; // for 24 bits
+
+ add_iq_samples(rx, leftsampledouble,rightsampledouble);
+ }
}
static void process_command_response(unsigned char *buffer) {
}
-static void process_mic_data(unsigned char *buffer) {
- long sequence;
- int b;
- int micsample;
- double micsampledouble;
- double gain=pow(10, mic_gain/20.0);
-
- sequence=((buffer[0]&0xFF)<<24)+((buffer[1]&0xFF)<<16)+((buffer[2]&0xFF)<<8)+(buffer[3]&0xFF);
-// if(isTransmitting()) {
- b=4;
- int i,j,s;
- for(i=0;i<MIC_SAMPLES;i++) {
- micsample = (int)((signed char) buffer[b++]) << 8;
- micsample |= (int)((unsigned char)buffer[b++] & 0xFF);
- micsampledouble = (1.0 / 2147483648.0) * (double)(micsample<<16);
-#ifdef FREEDV
- if(mode==modeFREEDV && isTransmitting()) {
- if(freedv_samples==0) { // 48K to 8K
- int sample=(int)((double)micsample*pow(10.0, mic_gain / 20.0));
- int modem_samples=mod_sample_freedv(sample);
- if(modem_samples!=0) {
- for(s=0;s<modem_samples;s++) {
- for(j=0;j<freedv_resample;j++) { // 8K to 48K
- micsample=mod_out[s];
- micsampledouble = (1.0 / 2147483648.0) * (double)(micsample<<16);
- micinputbuffer[micsamples*2]=micsampledouble;
- micinputbuffer[(micsamples*2)+1]=micsampledouble;
- micsamples++;
- if(micsamples==BUFFER_SIZE) {
- full_tx_buffer();
- micsamples=0;
- }
- }
- }
- }
- }
- freedv_samples++;
- if(freedv_samples==freedv_resample) {
- freedv_samples=0;
- }
- } else {
-#endif
- if(mode==modeCWL || mode==modeCWU || tune /*|| !isTransmitting()*/) {
- micinputbuffer[micsamples*2]=0.0;
- micinputbuffer[(micsamples*2)+1]=0.0;
- } else {
- micinputbuffer[micsamples*2]=micsampledouble;
- micinputbuffer[(micsamples*2)+1]=micsampledouble;
- }
-
- micsamples++;
-
- if(micsamples==BUFFER_SIZE) {
- full_tx_buffer();
- micsamples=0;
- }
-#ifdef FREEDV
- }
-#endif
-
- }
-// }
-
-}
-
-#ifdef FREEDV
-static void process_freedv_rx_buffer() {
- int j;
- int demod_samples;
- for(j=0;j<outputsamples;j++) {
- if(freedv_samples==0) {
- leftaudiosample=(short)(audiooutputbuffer[j*2]*32767.0);
- rightaudiosample=(short)(audiooutputbuffer[(j*2)+1]*32767.0);
- demod_samples=demod_sample_freedv(leftaudiosample);
- if(demod_samples!=0) {
- int s;
- int t;
- for(s=0;s<demod_samples;s++) {
- if(freedv_sync) {
- leftaudiosample=rightaudiosample=(short)((double)speech_out[s]);
- } else {
- leftaudiosample=rightaudiosample=0;
- }
- for(t=0;t<6;t++) { // 8k to 48k
- if(local_audio) {
- audio_write(leftaudiosample,rightaudiosample);
- leftaudiosample=0;
- rightaudiosample=0;
- }
-
- audiobuffer[audioindex++]=leftaudiosample>>8;
- audiobuffer[audioindex++]=leftaudiosample;
- audiobuffer[audioindex++]=rightaudiosample>>8;
- audiobuffer[audioindex++]=rightaudiosample;
-
- if(audioindex>=sizeof(audiobuffer)) {
- // insert the sequence
- audiobuffer[0]=audiosequence>>24;
- audiobuffer[1]=audiosequence>>16;
- audiobuffer[2]=audiosequence>>8;
- audiobuffer[3]=audiosequence;
- // send the buffer
- if(sendto(data_socket,audiobuffer,sizeof(audiobuffer),0,(struct sockaddr*)&audio_addr,audio_addr_length)<0) {
- fprintf(stderr,"sendto socket failed for audio\n");
- exit(1);
- }
- audioindex=4;
- audiosequence++;
- }
- }
- }
- }
- freedv_samples++;
- if(freedv_samples==freedv_resample) {
- freedv_samples=0;
- }
- }
+static void process_mic_data(unsigned char *buffer,int bytes) {
+ long sequence;
+ int b;
+ short sample;
+
+ sequence=((buffer[0]&0xFF)<<24)+((buffer[1]&0xFF)<<16)+((buffer[2]&0xFF)<<8)+(buffer[3]&0xFF);
+ b=4;
+ int i;
+ for(i=0;i<MIC_SAMPLES;i++) {
+ sample=(short)((buffer[b++]<<8) | (buffer[b++]&0xFF));
+ add_mic_sample(transmitter,sample);
}
}
-#endif
-static void process_rx_buffer() {
- int j;
- for(j=0;j<outputsamples;j++) {
- if(isTransmitting()) {
- leftaudiosample=0;
- rightaudiosample=0;
- } else {
- leftaudiosample=(short)(audiooutputbuffer[j*2]*32767.0);
- rightaudiosample=(short)(audiooutputbuffer[(j*2)+1]*32767.0);
+void new_protocol_audio_samples(RECEIVER *rx,short left_audio_sample,short right_audio_sample) {
+ int rc;
-#ifdef PSK
- if(mode==modePSK) {
- if(psk_samples==0) {
- psk_demod((double)((leftaudiosample+rightaudiosample)/2));
- }
- psk_samples++;
- if(psk_samples==psk_resample) {
- psk_samples=0;
- }
- }
-#endif
- }
-
- if(local_audio) {
- audio_write(leftaudiosample,rightaudiosample);
- }
-
- audiobuffer[audioindex++]=leftaudiosample>>8;
- audiobuffer[audioindex++]=leftaudiosample;
- audiobuffer[audioindex++]=rightaudiosample>>8;
- audiobuffer[audioindex++]=rightaudiosample;
-
- if(audioindex>=sizeof(audiobuffer)) {
- // insert the sequence
- audiobuffer[0]=audiosequence>>24;
- audiobuffer[1]=audiosequence>>16;
- audiobuffer[2]=audiosequence>>8;
- audiobuffer[3]=audiosequence;
- // send the buffer
- if(sendto(data_socket,audiobuffer,sizeof(audiobuffer),0,(struct sockaddr*)&audio_addr,audio_addr_length)<0) {
- fprintf(stderr,"sendto socket failed for audio\n");
- exit(1);
- }
- audioindex=4;
- audiosequence++;
- }
- }
-}
+ // insert the samples
+ audiobuffer[audioindex++]=left_audio_sample>>8;
+ audiobuffer[audioindex++]=left_audio_sample;
+ audiobuffer[audioindex++]=right_audio_sample>>8;
+ audiobuffer[audioindex++]=right_audio_sample;
+
+ if(audioindex>=sizeof(audiobuffer)) {
-static void full_rx_buffer(int rx) {
- int j;
- int error;
+ // insert the sequence
+ audiobuffer[0]=audiosequence>>24;
+ audiobuffer[1]=audiosequence>>16;
+ audiobuffer[2]=audiosequence>>8;
+ audiobuffer[3]=audiosequence;
- Spectrum0(1, CHANNEL_RX0, 0, 0, iqinputbuffer[rx]);
+ // send the buffer
- if(rx==active_receiver) {
- fexchange0(CHANNEL_RX0, iqinputbuffer[rx], audiooutputbuffer, &error);
- if(error!=0) {
- fprintf(stderr,"full_rx_buffer: fexchange0: error=%d\n",error);
- }
-/*
- switch(mode) {
-#ifdef PSK
- case modePSK:
- break;
-#endif
- default:
- Spectrum0(1, CHANNEL_RX0, 0, 0, iqinputbuffer[rx]);
- break;
- }
-*/
- switch(mode) {
-#ifdef FREEDV
- case modeFREEDV:
- process_freedv_rx_buffer();
- break;
-#endif
- default:
- process_rx_buffer();
- break;
+ rc=sendto(data_socket,audiobuffer,sizeof(audiobuffer),0,(struct sockaddr*)&audio_addr,audio_addr_length);
+ if(rc!=sizeof(audiobuffer)) {
+ fprintf(stderr,"sendto socket failed for %d bytes of audio: %d\n",sizeof(audiobuffer),rc);
}
+ audioindex=4;
+ audiosequence++;
}
}
-static void full_tx_buffer() {
- long isample;
- long qsample;
- double gain=8388607.0;
- int j;
- int error;
-
- if(vox_enabled) {
- switch(mode) {
- case modeLSB:
- case modeUSB:
- case modeDSB:
- case modeFMN:
- case modeAM:
- case modeSAM:
-#ifdef FREEDV
- case modeFREEDV:
-#endif
- update_vox(micinputbuffer,BUFFER_SIZE);
- break;
+void new_protocol_iq_samples(int isample,int qsample) {
+ iqbuffer[iqindex++]=isample>>16;
+ iqbuffer[iqindex++]=isample>>8;
+ iqbuffer[iqindex++]=isample;
+ iqbuffer[iqindex++]=qsample>>16;
+ iqbuffer[iqindex++]=qsample>>8;
+ iqbuffer[iqindex++]=qsample;
+
+ if(iqindex==sizeof(iqbuffer)) {
+ iqbuffer[0]=tx_iq_sequence>>24;
+ iqbuffer[1]=tx_iq_sequence>>16;
+ iqbuffer[2]=tx_iq_sequence>>8;
+ iqbuffer[3]=tx_iq_sequence;
+
+ // send the buffer
+ if(sendto(data_socket,iqbuffer,sizeof(iqbuffer),0,(struct sockaddr*)&iq_addr,iq_addr_length)<0) {
+ fprintf(stderr,"sendto socket failed for iq\n");
+ exit(1);
}
+ iqindex=4;
+ tx_iq_sequence++;
}
+}
- fexchange0(CHANNEL_TX, micinputbuffer, iqoutputbuffer, &error);
- Spectrum0(1, CHANNEL_TX, 0, 0, iqoutputbuffer);
-
-#ifdef FREEDV
- if(mode==modeFREEDV) {
- gain=8388607.0;
- }
-#endif
-
- if(radio->device==NEW_DEVICE_ATLAS && atlas_penelope) {
- if(tune) {
- gain=gain*tune_drive;
+void new_protocol_process_local_mic(unsigned char *buffer,int le) {
+ int b;
+ short micsample;
+ double micsampledouble;
+ double gain=pow(10.0, mic_gain / 20.0);
+
+ b=0;
+ int i,j,s;
+ for(i=0;i<MIC_SAMPLES;i++) {
+ if(le) {
+ micsample = (short)((buffer[b++]&0xFF) | (buffer[b++]<<8));
} else {
- gain=gain*(double)drive;
+ micsample = (short)((buffer[b++]<<8) | (buffer[b++]&0xFF));
}
+ add_mic_sample(transmitter,micsample);
}
- for(j=0;j<micoutputsamples;j++) {
- isample=(long)(iqoutputbuffer[j*2]*gain);
- qsample=(long)(iqoutputbuffer[(j*2)+1]*gain);
-
- iqbuffer[iqindex++]=isample>>16;
- iqbuffer[iqindex++]=isample>>8;
- iqbuffer[iqindex++]=isample;
- iqbuffer[iqindex++]=qsample>>16;
- iqbuffer[iqindex++]=qsample>>8;
- iqbuffer[iqindex++]=qsample;
-
- if(iqindex>=sizeof(iqbuffer)) {
- // insert the sequence
- iqbuffer[0]=tx_iq_sequence>>24;
- iqbuffer[1]=tx_iq_sequence>>16;
- iqbuffer[2]=tx_iq_sequence>>8;
- iqbuffer[3]=tx_iq_sequence;
-
- // send the buffer
- if(sendto(data_socket,iqbuffer,sizeof(iqbuffer),0,(struct sockaddr*)&iq_addr,iq_addr_length)<0) {
- fprintf(stderr,"sendto socket failed for iq\n");
- exit(1);
- }
- iqindex=4;
- tx_iq_sequence++;
- }
-
- }
-}
-
-void new_protocol_process_local_mic(unsigned char *buffer,int le) {
- int b;
- int micsample;
- double micsampledouble;
- double gain=pow(10.0, mic_gain / 20.0);
-
-// if(isTransmitting()) {
- b=0;
- int i,j,s;
- for(i=0;i<MIC_SAMPLES;i++) {
- if(le) {
- micsample = (int)((unsigned char)buffer[b++] & 0xFF);
- micsample |= (int)((signed char) buffer[b++]) << 8;
- } else {
- micsample = (int)((signed char) buffer[b++]) << 8;
- micsample |= (int)((unsigned char)buffer[b++] & 0xFF);
- }
- micsampledouble=(1.0 / 2147483648.0) * (double)(micsample<<16);
-#ifdef FREEDV
- if(mode==modeFREEDV && isTransmitting()) {
- if(freedv_samples==0) { // 48K to 8K
- int modem_samples=mod_sample_freedv(micsample*gain);
- if(modem_samples!=0) {
- for(s=0;s<modem_samples;s++) {
- for(j=0;j<freedv_resample;j++) { // 8K to 48K
- micsample=mod_out[s];
- micsampledouble=(1.0 / 2147483648.0) * (double)(micsample<<16);
- micinputbuffer[micsamples*2]=micsampledouble;
- micinputbuffer[(micsamples*2)+1]=micsampledouble;
- micsamples++;
- if(micsamples==BUFFER_SIZE) {
- full_tx_buffer();
- micsamples=0;
- }
- }
- }
- }
- }
- freedv_samples++;
- if(freedv_samples==freedv_resample) {
- freedv_samples=0;
- }
- } else {
-#endif
- if(mode==modeCWL || mode==modeCWU || tune /*|| !isTransmitting()*/) {
- micinputbuffer[micsamples*2]=0.0;
- micinputbuffer[(micsamples*2)+1]=0.0;
- } else {
- micinputbuffer[micsamples*2]=micsampledouble;
- micinputbuffer[(micsamples*2)+1]=micsampledouble;
- }
-
- micsamples++;
-
- if(micsamples==BUFFER_SIZE) {
- full_tx_buffer();
- micsamples=0;
- }
-#ifdef FREEDV
- }
-#endif
-
- }
-// }
-
}
void* new_protocol_timer_thread(void* arg) {
- int count=0;
+ int count=0;
fprintf(stderr,"new_protocol_timer_thread\n");
- while(running) {
- usleep(100000); // 100ms
- if(running) {
- if(count==0) {
- new_protocol_transmit_specific();
- count=1;
- } else {
- new_protocol_receive_specific();
- count=0;
- }
- }
+ while(running) {
+ usleep(100000); // 100ms
+ if(running) {
+ if(count==0) {
+ new_protocol_transmit_specific();
+ count=1;
+ } else {
+ new_protocol_receive_specific();
+ count=0;
+ }
}
+ }
}
#ifndef _NEW_PROTOCOL_H
#define _NEW_PROTOCOL_H
+#include <semaphore.h>
+#include "receiver.h"
+
// port definitions from host
#define GENERAL_REGISTERS_FROM_HOST_PORT 1024
#define PROGRAMMING_FROM_HOST_PORT 1024
#define RX_IQ_TO_HOST_PORT_6 1041
#define RX_IQ_TO_HOST_PORT_7 1042
-#define BUFFER_SIZE 1024
+//#define BUFFER_SIZE 1024
#ifdef SHORT_FRAMES
#define MIC_SAMPLES 64
extern int send_general;
*/
-void schedule_high_priority(int source);
+void schedule_high_priority();
void schedule_general();
void new_protocol_init(int pixels);
void new_protocol_stop();
+void new_protocol_run();
void filter_board_changed();
void pa_changed();
int getTune();
int isTransmitting();
-void new_protocol_process_local_mic(unsigned char *buffer,int le);
+extern void new_protocol_process_local_mic(unsigned char *buffer,int le);
+extern void new_protocol_audio_samples(RECEIVER *rx,short left_audio_sample,short right_audio_sample);
+extern void new_protocol_iq_samples(int isample,int qsample);
#endif
}
static void update_noise() {
- SetRXAANRRun(CHANNEL_RX0, nr);
- SetRXAEMNRRun(CHANNEL_RX0, nr2);
- SetRXAANFRun(CHANNEL_RX0, anf);
- SetRXASNBARun(CHANNEL_RX0, snb);
+ SetRXAANRRun(active_receiver->id, active_receiver->nr);
+ SetRXAEMNRRun(active_receiver->id, active_receiver->nr2);
+ SetRXAANFRun(active_receiver->id, active_receiver->anf);
+ SetRXASNBARun(active_receiver->id, active_receiver->snb);
vfo_update(NULL);
}
-static void nr_none_cb(GtkWidget *widget, gpointer data) {
- nr=0;
- nr2=0;
- nb=0;
- nb2=0;
- anf=0;
- snb=0;
- update_noise();
-}
-
static void nr_cb(GtkWidget *widget, gpointer data) {
- nr=1;
- nr2=0;
- nb=0;
- nb2=0;
- anf=0;
- snb=0;
+ active_receiver->nr=active_receiver->nr==1?0:1;
update_noise();
}
static void nr2_cb(GtkWidget *widget, gpointer data) {
- nr=0;
- nr2=1;
- nb=0;
- nb2=0;
- anf=0;
- snb=0;
- update_noise();
-}
-
-static void nb_cb(GtkWidget *widget, gpointer data) {
- nr=0;
- nr2=0;
- nb=1;
- nb2=0;
- anf=0;
- snb=0;
- update_noise();
-}
-
-static void nb2_cb(GtkWidget *widget, gpointer data) {
- nr=0;
- nr2=0;
- nb=0;
- nb2=1;
- anf=0;
- snb=0;
+ active_receiver->nr2=active_receiver->nr2==1?0:1;
update_noise();
}
static void anf_cb(GtkWidget *widget, gpointer data) {
- nr=0;
- nr2=0;
- nb=0;
- nb2=0;
- anf=1;
- snb=0;
+ active_receiver->anf=active_receiver->anf==1?0:1;
update_noise();
}
static void snb_cb(GtkWidget *widget, gpointer data) {
- nr=0;
- nr2=0;
- nb=0;
- nb2=0;
- anf=0;
- snb=1;
+ active_receiver->snb=active_receiver->snb==1?0:1;
update_noise();
}
g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL);
gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1);
- GtkWidget *b_nr_none=gtk_radio_button_new_with_label(NULL,"None");
- //gtk_widget_override_font(b_none, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_nr_none), nr_none==1);
- gtk_widget_show(b_nr_none);
- gtk_grid_attach(GTK_GRID(grid),b_nr_none,0,1,2,1);
- g_signal_connect(b_nr_none,"pressed",G_CALLBACK(nr_none_cb),NULL);
+ char label[32];
+ sprintf(label,"RX %d VFO %s",active_receiver->id,active_receiver->id==0?"A":"B");
+ GtkWidget *rx_label=gtk_label_new(label);
+ gtk_grid_attach(GTK_GRID(grid),rx_label,1,0,1,1);
- GtkWidget *b_nr=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_nr_none),"NR");
- //gtk_widget_override_font(b_nr, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_nr), nr==1);
+ GtkWidget *b_nr=gtk_check_button_new_with_label("NR");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_nr), active_receiver->nr);
gtk_widget_show(b_nr);
gtk_grid_attach(GTK_GRID(grid),b_nr,0,2,2,1);
- g_signal_connect(b_nr,"pressed",G_CALLBACK(nr_cb),NULL);
+ g_signal_connect(b_nr,"toggled",G_CALLBACK(nr_cb),NULL);
- GtkWidget *b_nr2=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_nr),"NR2");
- //gtk_widget_override_font(b_nr2, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_nr2), nr2==1);
+ GtkWidget *b_nr2=gtk_check_button_new_with_label("NR2");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_nr2), active_receiver->nr2);
gtk_widget_show(b_nr2);
gtk_grid_attach(GTK_GRID(grid),b_nr2,0,3,2,1);
- g_signal_connect(b_nr2,"pressed",G_CALLBACK(nr2_cb),NULL);
-
-/*
- GtkWidget *b_nb=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_nr2),"NB");
- //gtk_widget_override_font(b_nb, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_nb), nb==1);
- gtk_widget_show(b_nb);
- gtk_grid_attach(GTK_GRID(grid),b_nb,0,4,2,1);
- g_signal_connect(b_nb,"pressed",G_CALLBACK(nb_cb),NULL);
-
- GtkWidget *b_nb2=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_nb),"NB2");
- //gtk_widget_override_font(b_nb2, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_nb2), nb2==1);
- gtk_widget_show(b_nb2);
- gtk_grid_attach(GTK_GRID(grid),b_nb2,0,5,2,1);
- g_signal_connect(b_nb2,"pressed",G_CALLBACK(nb2_cb),NULL);
-*/
+ g_signal_connect(b_nr2,"toggled",G_CALLBACK(nr2_cb),NULL);
- GtkWidget *b_anf=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_nr2),"ANF");
- //gtk_widget_override_font(b_anf, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_anf), anf==1);
+ GtkWidget *b_anf=gtk_check_button_new_with_label("ANF");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_anf), active_receiver->anf);
gtk_widget_show(b_anf);
gtk_grid_attach(GTK_GRID(grid),b_anf,0,4,2,1);
- g_signal_connect(b_anf,"pressed",G_CALLBACK(anf_cb),NULL);
+ g_signal_connect(b_anf,"toggled",G_CALLBACK(anf_cb),NULL);
- GtkWidget *b_snb=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_anf),"SNB");
+ GtkWidget *b_snb=gtk_check_button_new_with_label("SNB");
//gtk_widget_override_font(b_snb, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_snb), snb==1);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_snb), active_receiver->snb);
gtk_widget_show(b_snb);
gtk_grid_attach(GTK_GRID(grid),b_snb,0,5,2,1);
- g_signal_connect(b_snb,"pressed",G_CALLBACK(snb_cb),NULL);
+ g_signal_connect(b_snb,"toggled",G_CALLBACK(snb_cb),NULL);
gtk_container_add(GTK_CONTAINER(content),grid);
int b=((int)data)>>4;
int oc=((int)data)&0xF;
BAND *band=band_get_band(b);
- int mask=0x01<<oc;
+ int mask=0x01<<(oc-1);
+fprintf(stderr,"oc_rx_cb: band=%d oc=%d mask=%d\n",b,oc,mask);
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
band->OCrx|=mask;
} else {
band->OCrx&=~mask;
}
+
+ if(protocol==NEW_PROTOCOL) {
+ schedule_high_priority();
+ }
}
static void oc_tx_cb(GtkWidget *widget, gpointer data) {
int b=((int)data)>>4;
int oc=((int)data)&0xF;
BAND *band=band_get_band(b);
- int mask=0x01<<oc;
+ int mask=0x01<<(oc-1);
+
+fprintf(stderr,"oc_tx_cb: band=%d oc=%d mask=%d\n",b,oc,mask);
+
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
band->OCtx|=mask;
} else {
band->OCtx&=~mask;
}
+ if(protocol==NEW_PROTOCOL) {
+ schedule_high_priority();
+ }
}
static void oc_tune_cb(GtkWidget *widget, gpointer data) {
int oc=((int)data)&0xF;
- int mask=0x01<<oc;
+ int mask=0x01<<(oc-1);
+fprintf(stderr,"oc_tune_cb: oc=%d mask=%d\n",oc,mask);
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
OCtune|=mask;
} else {
int mask;
for(j=1;j<8;j++) {
- mask=0x01<<j;
+ mask=0x01<<(j-1);
GtkWidget *oc_rx_b=gtk_check_button_new();
//gtk_widget_override_font(oc_rx_b, pango_font_description_from_string("Arial 18"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (oc_rx_b), (band->OCrx&mask)==mask);
gtk_widget_show(oc_tune_title);
gtk_grid_attach(GTK_GRID(grid),oc_tune_title,18,j+1,1,1);
- mask=0x01<<j;
+ mask=0x01<<(j-1);
GtkWidget *oc_tune_b=gtk_check_button_new();
//gtk_widget_override_font(oc_tune_b, pango_font_description_from_string("Arial 18"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (oc_tune_b), (OCtune&mask)==mask);
*
*/
+#include <gtk/gtk.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
static int discovery_socket;
static struct sockaddr_in discovery_addr;
-static pthread_t discover_thread_id;
-static void* discover_receive_thread(void* arg);
+//static pthread_t discover_thread_id;
+//static void* discover_receive_thread(void* arg);
+static GThread *discover_thread_id;
+static gpointer discover_receive_thread(gpointer data);
static void discover(struct ifaddrs* iface) {
int rc;
to_addr.sin_addr.s_addr=htonl(INADDR_BROADCAST);
// start a receive thread to collect discovery response packets
+/*
rc=pthread_create(&discover_thread_id,NULL,discover_receive_thread,NULL);
if(rc != 0) {
fprintf(stderr,"pthread_create failed on discover_receive_thread: rc=%d\n", rc);
exit(-1);
}
+*/
+ discover_thread_id = g_thread_new( "old discover receive", discover_receive_thread, NULL);
+ if( ! discover_thread_id )
+ {
+ fprintf(stderr,"g_thread_new failed on discover_receive_thread\n");
+ exit( -1 );
+ }
+
// send discovery packet
}
// wait for receive thread to complete
+/*
void* status;
pthread_join(discover_thread_id,&status);
+*/
+ g_thread_join(discover_thread_id);
close(discovery_socket);
}
-static void* discover_receive_thread(void* arg) {
+//static void *discover_receive_thread(void* arg) {
+static gpointer discover_receive_thread(gpointer data) {
struct sockaddr_in addr;
int len;
unsigned char buffer[2048];
case DEVICE_HERMES_LITE:
strcpy(discovered[devices].name,"Hermes Lite");
break;
+ case DEVICE_ORION2:
+ strcpy(discovered[devices].name,"Orion 2");
+ break;
default:
strcpy(discovered[devices].name,"Unknown");
break;
}
fprintf(stderr,"discovery: exiting discover_receive_thread\n");
- pthread_exit(NULL);
+ //pthread_exit(NULL);
+ g_thread_exit(NULL);
}
void old_discovery() {
#include <net/if_arp.h>
#include <net/if.h>
#include <ifaddrs.h>
-#include <pthread.h>
#include <semaphore.h>
#include <string.h>
#include <errno.h>
#include "filter.h"
#include "old_protocol.h"
#include "radio.h"
+#include "receiver.h"
+#include "transmitter.h"
#include "signal.h"
#include "toolbar.h"
+#include "vfo.h"
#ifdef FREEDV
#include "freedv.h"
#endif
#define SYNC 0x7F
#define OZY_BUFFER_SIZE 512
-#define OUTPUT_BUFFER_SIZE 1024
+//#define OUTPUT_BUFFER_SIZE 1024
// ozy command and control
#define MOX_DISABLED 0x00
#define LT2208_RANDOM_OFF 0x00
#define LT2208_RANDOM_ON 0x10
-static int buffer_size=BUFFER_SIZE;
+//static int buffer_size=BUFFER_SIZE;
-static int receiver;
static int display_width;
static int speed;
static int running;
static long ep4_sequence;
+static int current_rx=0;
+
static int samples=0;
static int mic_samples=0;
+static int mic_sample_divisor=1;
#ifdef FREEDV
static int freedv_samples=0;
static int freedv_divisor=6;
//static float left_input_buffer[BUFFER_SIZE];
//static float right_input_buffer[BUFFER_SIZE];
-static double iqinputbuffer[RECEIVERS][BUFFER_SIZE*2];
+//static double iqinputbuffer[MAX_RECEIVERS][MAX_BUFFER_SIZE*2];
-//static float mic_left_buffer[BUFFER_SIZE];
-//static float mic_right_buffer[BUFFER_SIZE];
-static double micinputbuffer[BUFFER_SIZE*2];
+//static float mic_left_buffer[MAX_BUFFER_SIZE];
+//static float mic_right_buffer[MAX_BUFFER_SIZE];
+static double micinputbuffer[MAX_BUFFER_SIZE*2];
//static float left_output_buffer[OUTPUT_BUFFER_SIZE];
//static float right_output_buffer[OUTPUT_BUFFER_SIZE];
-static double audiooutputbuffer[BUFFER_SIZE*2];
+//static double audiooutputbuffer[MAX_BUFFER_SIZE*2];
//static float left_subrx_output_buffer[OUTPUT_BUFFER_SIZE];
//static float right_subrx_output_buffer[OUTPUT_BUFFER_SIZE];
//static float left_tx_buffer[OUTPUT_BUFFER_SIZE];
//static float right_tx_buffer[OUTPUT_BUFFER_SIZE];
-static double iqoutputbuffer[BUFFER_SIZE*2];
+//static double iqoutputbuffer[MAX_BUFFER_SIZE*2];
static int left_rx_sample;
static int right_rx_sample;
static int command=0;
-static pthread_t receive_thread_id;
+static GThread *receive_thread_id;
static void start_receive_thread();
-static void *receive_thread(void* arg);
+static gpointer receive_thread(gpointer arg);
static void process_ozy_input_buffer(char *buffer);
static void process_bandscope_buffer(char *buffer);
void ozy_send_buffer();
static sem_t frequency_changed_sem;
static int metis_write(unsigned char ep,char* buffer,int length);
-static void metis_restart();
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();
+static void metis_restart();
+
+#define COMMON_MERCURY_FREQUENCY 0x80
+#define PENELOPE_MIC 0x80
+
+#ifdef USBOZY
+//
+// additional defines if we include USB Ozy support
+//
+#include "ozyio.h"
+
+static GThread *ozy_EP4_rx_thread_id;
+static GThread *ozy_EP6_rx_thread_id;
+static gpointer ozy_ep4_rx_thread(gpointer arg);
+static gpointer ozy_ep6_rx_thread(gpointer arg);
+static void start_usb_receive_threads();
+static int ozyusb_write(char* buffer,int length);
+#define EP6_IN_ID 0x86 // end point = 6, direction toward PC
+#define EP2_OUT_ID 0x02 // end point = 2, direction from PC
+#define EP6_BUFFER_SIZE 2048
+static unsigned char usb_output_buffer[EP6_BUFFER_SIZE];
+static unsigned char ep6_inbuffer[EP6_BUFFER_SIZE];
+static unsigned char usb_buffer_block = 0;
+#endif
void schedule_frequency_changed() {
-//fprintf(stderr,"old_protocol: schedule_frequency_changed\n");
- //sem_wait(&frequency_changed_sem);
frequencyChanged=1;
- //sem_post(&frequency_changed_sem);
}
void old_protocol_stop() {
metis_start_stop(0);
- running=FALSE;
}
-void old_protocol_calc_buffers() {
- switch(sample_rate) {
- case 48000:
- output_buffer_size=OUTPUT_BUFFER_SIZE;
- break;
- case 96000:
- output_buffer_size=OUTPUT_BUFFER_SIZE/2;
- break;
- case 192000:
- output_buffer_size=OUTPUT_BUFFER_SIZE/4;
- break;
- case 384000:
- output_buffer_size=OUTPUT_BUFFER_SIZE/8;
- break;
- default:
- fprintf(stderr,"Invalid sample rate: %d. Defaulting to 48K.\n",sample_rate);
- break;
- }
+void old_protocol_run() {
+ metis_restart();
}
-void old_protocol_new_sample_rate(int rate) {
- metis_start_stop(0);
- sample_rate=rate;
- old_protocol_calc_buffers();
- wdsp_new_sample_rate(rate);
- metis_restart();
+void old_protocol_set_mic_sample_rate(int rate) {
+ mic_sample_divisor=rate/48000;
}
-void old_protocol_init(int rx,int pixels) {
+void old_protocol_init(int rx,int pixels,int rate) {
int i;
fprintf(stderr,"old_protocol_init\n");
- //int result=sem_init(&frequency_changed_sem, 0, 1);
-
- if(local_audio) {
- if(audio_open_output()!=0) {
- fprintf(stderr,"audio_open_output failed\n");
- local_audio=0;
- }
- }
+ old_protocol_set_mic_sample_rate(rate);
- if(local_microphone) {
+ if(transmitter->local_microphone) {
if(audio_open_input()!=0) {
fprintf(stderr,"audio_open_input failed\n");
- local_microphone=0;
+ transmitter->local_microphone=0;
}
}
- receiver=rx;
display_width=pixels;
- old_protocol_calc_buffers();
-
+#ifdef USBOZY
+//
+// if we have a USB interfaced Ozy device:
+//
+ if (device == DEVICE_OZY) {
+ fprintf(stderr,"old_protocol_init: initialise ozy on USB\n");
+ ozy_initialise();
+ start_usb_receive_threads();
+ }
+ else
+#endif
start_receive_thread();
fprintf(stderr,"old_protocol_init: prime radio\n");
}
+#ifdef USBOZY
+//
+// starts the threads for USB receive
+// EP4 is the bandscope endpoint (not yet used)
+// EP6 is the "normal" USB frame endpoint
+//
+static void start_usb_receive_threads()
+{
+ int rc;
+
+ fprintf(stderr,"old_protocol starting USB receive thread: buffer_size=%d\n",buffer_size);
+
+ ozy_EP6_rx_thread_id = g_thread_new( "OZY EP6 RX", ozy_ep6_rx_thread, NULL);
+ if( ! ozy_EP6_rx_thread_id )
+ {
+ fprintf(stderr,"g_thread_new failed for ozy_ep6_rx_thread\n");
+ exit( -1 );
+ }
+}
+
+//
+// receive threat for USB EP4 (bandscope) not currently used.
+//
+static gpointer ozy_ep4_rx_thread(gpointer arg)
+{
+}
+
+//
+// receive threat for USB EP6 (512 byte USB Ozy frames)
+// this function loops reading 4 frames at a time through USB
+// then processes them one at a time.
+//
+static gpointer ozy_ep6_rx_thread(gpointer arg) {
+ int bytes;
+ unsigned char buffer[2048];
+
+ fprintf(stderr, "old_protocol: USB EP6 receive_thread\n");
+ running=1;
+
+ while (running)
+ {
+ bytes = ozy_read(EP6_IN_ID,ep6_inbuffer,EP6_BUFFER_SIZE); // read a 2K buffer at a time
+
+ if (bytes == 0)
+ {
+ fprintf(stderr,"old_protocol_ep6_read: ozy_read returned 0 bytes... retrying\n");
+ continue;
+ }
+ else if (bytes != EP6_BUFFER_SIZE)
+ {
+ fprintf(stderr,"old_protocol_ep6_read: OzyBulkRead failed %d bytes\n",bytes);
+ perror("ozy_read(EP6 read failed");
+ //exit(1);
+ }
+ else
+// process the received data normally
+ {
+ process_ozy_input_buffer(&ep6_inbuffer[0]);
+ process_ozy_input_buffer(&ep6_inbuffer[512]);
+ process_ozy_input_buffer(&ep6_inbuffer[1024]);
+ process_ozy_input_buffer(&ep6_inbuffer[1024+512]);
+ }
+
+ }
+}
+#endif
+
static void start_receive_thread() {
int i;
int rc;
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) {
- perror("old_protocol: create socket failed for data_socket\n");
- exit(-1);
- }
+ switch(device) {
+#ifdef USBOZY
+ case DEVICE_OZY:
+ break;
+#endif
+ default:
+ data_socket=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
+ if(data_socket<0) {
+ perror("old_protocol: create socket failed for data_socket\n");
+ exit(-1);
+ }
- int optval = 1;
- setsockopt(data_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
+ int optval = 1;
+ setsockopt(data_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
- // bind to the interface
- if(bind(data_socket,(struct sockaddr*)&radio->info.network.interface_address,radio->info.network.interface_length)<0) {
- perror("old_protocol: bind socket failed for data_socket\n");
- exit(-1);
- }
+ // bind to the interface
+ if(bind(data_socket,(struct sockaddr*)&radio->info.network.interface_address,radio->info.network.interface_length)<0) {
+ perror("old_protocol: bind socket failed for data_socket\n");
+ exit(-1);
+ }
- memcpy(&data_addr,&radio->info.network.address,radio->info.network.address_length);
- data_addr_length=radio->info.network.address_length;
- data_addr.sin_port=htons(DATA_PORT);
+ memcpy(&data_addr,&radio->info.network.address,radio->info.network.address_length);
+ data_addr_length=radio->info.network.address_length;
+ data_addr.sin_port=htons(DATA_PORT);
+ break;
+ }
- rc=pthread_create(&receive_thread_id,NULL,receive_thread,NULL);
- if(rc != 0) {
- fprintf(stderr,"old_protocol: pthread_create failed on receive_thread: rc=%d\n", rc);
- exit(-1);
+ receive_thread_id = g_thread_new( "old protocol", receive_thread, NULL);
+ if( ! receive_thread_id )
+ {
+ fprintf(stderr,"g_thread_new failed on receive_thread\n");
+ exit( -1 );
}
+ fprintf(stderr, "receive_thread: id=%p\n",receive_thread_id);
}
-static void *receive_thread(void* arg) {
+static gpointer receive_thread(gpointer arg) {
struct sockaddr_in addr;
int length;
unsigned char buffer[2048];
length=sizeof(addr);
while(running) {
- bytes_read=recvfrom(data_socket,buffer,sizeof(buffer),0,(struct sockaddr*)&addr,&length);
- if(bytes_read<0) {
- perror("recvfrom socket failed for old_protocol: receive_thread");
- exit(1);
- }
- if(buffer[0]==0xEF && buffer[1]==0xFE) {
- switch(buffer[2]) {
- case 1:
- // get the end point
- ep=buffer[3]&0xFF;
+ switch(device) {
+#ifdef USBOZY
+ case DEVICE_OZY:
+ // should not happen
+ break;
+#endif
- // get the sequence number
- sequence=((buffer[4]&0xFF)<<24)+((buffer[5]&0xFF)<<16)+((buffer[6]&0xFF)<<8)+(buffer[7]&0xFF);
+ default:
+ bytes_read=recvfrom(data_socket,buffer,sizeof(buffer),0,(struct sockaddr*)&addr,&length);
+ if(bytes_read<0) {
+ perror("recvfrom socket failed for old_protocol: receive_thread");
+ exit(1);
+ }
- switch(ep) {
- case 6: // EP6
- // process the data
- process_ozy_input_buffer(&buffer[8]);
- process_ozy_input_buffer(&buffer[520]);
- break;
- case 4: // EP4
+ if(buffer[0]==0xEF && buffer[1]==0xFE) {
+ switch(buffer[2]) {
+ case 1:
+ // get the end point
+ ep=buffer[3]&0xFF;
+
+ // get the sequence number
+ sequence=((buffer[4]&0xFF)<<24)+((buffer[5]&0xFF)<<16)+((buffer[6]&0xFF)<<8)+(buffer[7]&0xFF);
+
+ switch(ep) {
+ case 6: // EP6
+ // process the data
+ process_ozy_input_buffer(&buffer[8]);
+ process_ozy_input_buffer(&buffer[520]);
+ break;
+ case 4: // EP4
/*
- ep4_sequence++;
- if(sequence!=ep4_sequence) {
- ep4_sequence=sequence;
- } else {
- int seq=(int)(sequence%32L);
- if((sequence%32L)==0L) {
- reset_bandscope_buffer_index();
- }
- process_bandscope_buffer(&buffer[8]);
- process_bandscope_buffer(&buffer[520]);
- }
+ ep4_sequence++;
+ if(sequence!=ep4_sequence) {
+ ep4_sequence=sequence;
+ } else {
+ int seq=(int)(sequence%32L);
+ if((sequence%32L)==0L) {
+ reset_bandscope_buffer_index();
+ }
+ process_bandscope_buffer(&buffer[8]);
+ process_bandscope_buffer(&buffer[520]);
+ }
*/
+ break;
+ default:
+ fprintf(stderr,"unexpected EP %d length=%d\n",ep,bytes_read);
+ break;
+ }
+ break;
+ case 2: // response to a discovery packet
+ fprintf(stderr,"unexepected discovery response when not in discovery mode\n");
break;
default:
- fprintf(stderr,"unexpected EP %d length=%d\n",ep,bytes_read);
+ fprintf(stderr,"unexpected packet type: 0x%02X\n",buffer[2]);
break;
}
- break;
- case 2: // response to a discovery packet
- fprintf(stderr,"unexepected discovery response when not in discovery mode\n");
- break;
- default:
- fprintf(stderr,"unexpected packet type: 0x%02X\n",buffer[2]);
- break;
- }
- } else {
- fprintf(stderr,"received bad header bytes on data port %02X,%02X\n",buffer[0],buffer[1]);
+ } else {
+ fprintf(stderr,"received bad header bytes on data port %02X,%02X\n",buffer[0],buffer[1]);
+ }
+ break;
}
}
}
int last_dash;
int left_sample;
int right_sample;
- int mic_sample;
- double left_sample_double[RECEIVERS];
- double right_sample_double[RECEIVERS];
+ short mic_sample;
+ double left_sample_double;
+ double right_sample_double;
double mic_sample_double;
double gain=pow(10.0, mic_gain / 20.0);
}
- int iq_samples = (512 -8) / ((RECEIVERS*6)+2);
+ int iq_samples=(512-8)/((RECEIVERS*6)+2);
for(i=0;i<iq_samples;i++) {
-
for(r=0;r<RECEIVERS;r++) {
- left_sample = (int)((signed char) buffer[b++]) << 16;
- left_sample += (int)((unsigned char)buffer[b++]) << 8;
- left_sample += (int)((unsigned char)buffer[b++]);
- right_sample = (int)((signed char) buffer[b++]) << 16;
- right_sample += (int)((unsigned char)buffer[b++]) << 8;
- right_sample += (int)((unsigned char)buffer[b++]);
- left_sample_double[r]=(double)left_sample/8388607.0; // 24 bit sample 2^23-1
- right_sample_double[r]=(double)right_sample/8388607.0; // 24 bit sample 2^23-1
- }
- mic_sample = (int)((signed char) buffer[b++]) << 8;
- mic_sample |= (int)((unsigned char)buffer[b++]);
- mic_sample_double = (1.0 / 2147483648.0) * (double)(mic_sample<<16);
+ left_sample = (int)((signed char) buffer[b++])<<16;
+ left_sample |= (int)((((unsigned char)buffer[b++])<<8)&0xFF00);
+ left_sample |= (int)((unsigned char)buffer[b++]&0xFF);
+ right_sample = (int)((signed char)buffer[b++]) << 16;
+ right_sample |= (int)((((unsigned char)buffer[b++])<<8)&0xFF00);
+ right_sample |= (int)((unsigned char)buffer[b++]&0xFF);
- // add to buffer
- if(isTransmitting() && !local_microphone) {
-#ifdef FREEDV
- if(mode==modeFREEDV && !tune) {
- if(freedv_samples==0) {
- int sample=(int)((double)mic_sample*gain);
- int modem_samples=mod_sample_freedv(sample);
- if(modem_samples!=0) {
- int s;
- for(s=0;s<modem_samples;s++) {
- for(j=0;j<freedv_divisor;j++) {
- mic_sample=mod_out[s];
- mic_sample_double = (1.0 / 2147483648.0) * (double)(mic_sample<<16);
- micinputbuffer[samples*2]=mic_sample_double;
- micinputbuffer[(samples*2)+1]=mic_sample_double;
- iqinputbuffer[0][samples*2]=0.0;
- iqinputbuffer[0][(samples*2)+1]=0.0;
- samples++;
- if(samples==buffer_size) {
- full_tx_buffer();
- samples=0;
- }
- }
- }
- }
- }
- freedv_samples++;
- if(freedv_samples==freedv_divisor) {
- freedv_samples=0;
- }
- } else {
-#endif
- if(mode==modeCWL || mode==modeCWU || tune) {
- micinputbuffer[samples*2]=0.0;
- micinputbuffer[(samples*2)+1]=0.0;
- } else {
- micinputbuffer[samples*2]=mic_sample_double;
- micinputbuffer[(samples*2)+1]=mic_sample_double;
- }
- iqinputbuffer[0][samples*2]=0.0;
- iqinputbuffer[0][(samples*2)+1]=0.0;
- samples++;
- if(samples==buffer_size) {
- full_tx_buffer();
- samples=0;
- }
-#ifdef FREEDV
- }
-#endif
- } else {
- if(!isTransmitting()) {
- micinputbuffer[samples*2]=mic_sample_double;
- micinputbuffer[(samples*2)+1]=mic_sample_double;
- iqinputbuffer[0][samples*2]=left_sample_double[0];
- iqinputbuffer[0][(samples*2)+1]=right_sample_double[0];
- samples++;
- if(samples==buffer_size) {
- full_rx_buffer();
- samples=0;
- }
+ left_sample_double=(double)left_sample/8388607.0; // 24 bit sample 2^23-1
+ right_sample_double=(double)right_sample/8388607.0; // 24 bit sample 2^23-1
+
+ add_iq_samples(receiver[r], left_sample_double,right_sample_double);
+ }
+ mic_sample = (short)(buffer[b++]<<8);
+ mic_sample |= (short)(buffer[b++]&0xFF);
+ if(!transmitter->local_microphone) {
+ mic_samples++;
+ if(mic_samples>=mic_sample_divisor) { // reduce to 48000
+ add_mic_sample(transmitter,mic_sample);
+ mic_samples=0;
}
}
}
}
}
-#ifdef FREEDV
-static void process_freedv_rx_buffer() {
- int j;
-
- int demod_samples;
- for(j=0;j<output_buffer_size;j++) {
- if(freedv_samples==0) {
- left_rx_sample=(short)(audiooutputbuffer[j*2]*32767.0);
- right_rx_sample=(short)(audiooutputbuffer[(j*2)+1]*32767.0);
- demod_samples=demod_sample_freedv(left_rx_sample);
- if(demod_samples!=0) {
- int s;
- int t;
- for(s=0;s<demod_samples;s++) {
- for(t=0;t<6;t++) { // 8k to 48k
- if(freedv_sync) {
- left_rx_sample=right_rx_sample=(short)((double)speech_out[s]);
- } else {
- left_rx_sample=right_rx_sample=0;
- }
- if(local_audio) {
- audio_write(left_rx_sample,right_rx_sample);
- }
- output_buffer[output_buffer_index++]=left_rx_sample>>8;
- output_buffer[output_buffer_index++]=left_rx_sample;
- output_buffer[output_buffer_index++]=right_rx_sample>>8;
- output_buffer[output_buffer_index++]=right_rx_sample;
- left_tx_sample=right_tx_sample=0;
- output_buffer[output_buffer_index++]=left_tx_sample>>8;
- output_buffer[output_buffer_index++]=left_tx_sample;
- output_buffer[output_buffer_index++]=right_tx_sample>>8;
- output_buffer[output_buffer_index++]=right_tx_sample;
- if(output_buffer_index>=OZY_BUFFER_SIZE) {
- ozy_send_buffer();
- output_buffer_index=8;
- }
- }
- }
- }
- }
- freedv_samples++;
- if(freedv_samples==freedv_divisor) {
- freedv_samples=0;
- }
- }
-}
-#endif
-
-static void process_rx_buffer() {
- int j;
-
- for(j=0;j<output_buffer_size;j++) {
- left_rx_sample=(short)(audiooutputbuffer[j*2]*32767.0);
- right_rx_sample=(short)(audiooutputbuffer[(j*2)+1]*32767.0);
-#ifdef PSK
- if(mode==modePSK) {
- if(psk_samples==0) {
- psk_demod((double)((left_rx_sample+right_rx_sample)/2));
- }
- psk_samples++;
- if(psk_samples==psk_divisor) {
- psk_samples=0;
- }
- }
-#endif
- if(local_audio) {
- audio_write(left_rx_sample,right_rx_sample);
- }
- left_tx_sample=0;
- right_tx_sample=0;
- output_buffer[output_buffer_index++]=left_rx_sample>>8;
- output_buffer[output_buffer_index++]=left_rx_sample;
- output_buffer[output_buffer_index++]=right_rx_sample>>8;
- output_buffer[output_buffer_index++]=right_rx_sample;
- output_buffer[output_buffer_index++]=left_tx_sample>>8;
- output_buffer[output_buffer_index++]=left_tx_sample;
- output_buffer[output_buffer_index++]=right_tx_sample>>8;
- output_buffer[output_buffer_index++]=right_tx_sample;
+void old_protocol_audio_samples(RECEIVER *rx,short left_audio_sample,short right_audio_sample) {
+ if(!isTransmitting()) {
+ output_buffer[output_buffer_index++]=left_audio_sample>>8;
+ output_buffer[output_buffer_index++]=left_audio_sample;
+ output_buffer[output_buffer_index++]=right_audio_sample>>8;
+ output_buffer[output_buffer_index++]=right_audio_sample;
+ output_buffer[output_buffer_index++]=0;
+ output_buffer[output_buffer_index++]=0;
+ output_buffer[output_buffer_index++]=0;
+ output_buffer[output_buffer_index++]=0;
if(output_buffer_index>=OZY_BUFFER_SIZE) {
ozy_send_buffer();
output_buffer_index=8;
}
}
-static void full_rx_buffer() {
- int j;
- int error;
-
- if(vox_enabled && !local_microphone) {
- switch(mode) {
- case modeLSB:
- case modeUSB:
- case modeDSB:
- case modeFMN:
- case modeAM:
- case modeSAM:
-#ifdef FREEDV
- case modeFREEDV:
-#endif
- update_vox(micinputbuffer,BUFFER_SIZE);
- break;
- }
- }
-
- if(diversity_enabled) {
- double *pin[2];
- pin[0]=iqinputbuffer[0];
- pin[1]=iqinputbuffer[1];
-
- xdivEXT(0,BUFFER_SIZE,pin,iqinputbuffer[0]);
- }
-
- fexchange0(CHANNEL_RX0, iqinputbuffer[0], audiooutputbuffer, &error);
-
-#ifdef PSK
- if(mode!=modePSK) {
-#endif
- Spectrum0(1, CHANNEL_RX0, 0, 0, iqinputbuffer[0]);
-#ifdef PSK
- }
-#endif
-
-#ifdef FREEDV
- if(mode==modeFREEDV) {
- process_freedv_rx_buffer();
- return;
- }
-#endif
- process_rx_buffer();
-}
-
-static void full_tx_buffer() {
- int j;
- int error;
- double gain=32767.0; // 2^16-1
-
- if(vox_enabled && (vox || local_microphone)) {
- update_vox(micinputbuffer,BUFFER_SIZE);
- }
-
+void old_protocol_iq_samples(int isample,int qsample) {
if(isTransmitting()) {
- fexchange0(CHANNEL_TX, micinputbuffer, iqoutputbuffer, &error);
- if(error!=0) {
- fprintf(stderr,"full_tx_buffer: fexchange0: error=%d\n",error);
- }
- Spectrum0(1, CHANNEL_TX, 0, 0, iqoutputbuffer);
-
- if(radio->device==DEVICE_METIS && atlas_penelope) {
- if(tune) {
- gain=gain*tune_drive;
- } else {
- gain=gain*drive;
- }
- }
- for(j=0;j<output_buffer_size;j++) {
- left_rx_sample=0;
- right_rx_sample=0;
- left_tx_sample=(int)(iqoutputbuffer[j*2]*gain);
- right_tx_sample=(int)(iqoutputbuffer[(j*2)+1]*gain);
-
- output_buffer[output_buffer_index++]=0;
- output_buffer[output_buffer_index++]=0;
- output_buffer[output_buffer_index++]=0;
- output_buffer[output_buffer_index++]=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++]=0;
+ output_buffer[output_buffer_index++]=0;
+ output_buffer[output_buffer_index++]=0;
+ output_buffer[output_buffer_index++]=0;
+ output_buffer[output_buffer_index++]=isample>>8;
+ output_buffer[output_buffer_index++]=isample;
+ output_buffer[output_buffer_index++]=qsample>>8;
+ output_buffer[output_buffer_index++]=qsample;
+ if(output_buffer_index>=OZY_BUFFER_SIZE) {
+ ozy_send_buffer();
+ output_buffer_index=8;
}
}
}
+
void old_protocol_process_local_mic(unsigned char *buffer,int le) {
int b;
- int mic_sample;
- double mic_sample_double;
- double gain=pow(10.0, mic_gain / 20.0);
-
- //if(isTransmitting()) {
- b=0;
- int i,j,s;
- for(i=0;i<720;i++) {
- if(le) {
- mic_sample = (int)((unsigned char)buffer[b++] & 0xFF);
- mic_sample |= (int)((signed char) buffer[b++]) << 8;
- } else {
- mic_sample = (int)((signed char) buffer[b++]) << 8;
- mic_sample |= (int)((unsigned char)buffer[b++] & 0xFF);
- }
- mic_sample_double=(1.0 / 2147483648.0) * (double)(mic_sample<<16);
-#ifdef FREEDV
- if(mode==modeFREEDV && !tune) {
- if(freedv_samples==0) { // 48K to 8K
- int modem_samples=mod_sample_freedv(mic_sample*gain);
- if(modem_samples!=0) {
- for(s=0;s<modem_samples;s++) {
- for(j=0;j<freedv_divisor;j++) { // 8K to 48K
- mic_sample=mod_out[s];
- mic_sample_double = (1.0 / 2147483648.0) * (double)(mic_sample<<16);
- micinputbuffer[mic_samples*2]=mic_sample_double;
- micinputbuffer[(mic_samples*2)+1]=mic_sample_double;
- //iqinputbuffer[0][samples*2]=0.0;
- //iqinputbuffer[0][(samples*2)+1]=0.0;
- mic_samples++;
- if(mic_samples==buffer_size) {
- full_tx_buffer();
- mic_samples=0;
- }
- }
- }
- }
- }
- freedv_samples++;
- if(freedv_samples==freedv_divisor) {
- freedv_samples=0;
- }
- } else {
-#endif
- if(mode==modeCWL || mode==modeCWU || tune) {
- micinputbuffer[mic_samples*2]=0.0;
- micinputbuffer[(mic_samples*2)+1]=0.0;
- } else {
- micinputbuffer[mic_samples*2]=mic_sample_double;
- micinputbuffer[(mic_samples*2)+1]=mic_sample_double;
- }
-// iqinputbuffer[0][samples*2]=0.0;
-// iqinputbuffer[0][(samples*2)+1]=0.0;
- mic_samples++;
- if(mic_samples==buffer_size) {
- full_tx_buffer();
- mic_samples=0;
- }
-#ifdef FREEDV
- }
-#endif
-
+ short mic_sample;
+// always 48000 samples per second
+ b=0;
+ int i,j,s;
+ for(i=0;i<720;i++) {
+ if(le) {
+ mic_sample = (short)((buffer[b++]&0xFF) | (buffer[b++]<<8));
+ } else {
+ mic_sample = (short)((buffer[b++]<<8) | (buffer[b++]&0xFF));
}
- //}
+ add_mic_sample(transmitter,mic_sample);
+ }
}
/*
*/
-int current_rx=0;
void ozy_send_buffer() {
+ int mode;
+ int i;
+ BAND *band;
+
output_buffer[SYNC0]=SYNC;
output_buffer[SYNC1]=SYNC;
output_buffer[SYNC2]=SYNC;
switch(command) {
case 0:
{
- BAND *band=band_get_current_band();
output_buffer[C0]=0x00;
output_buffer[C1]=0x00;
- switch(sample_rate) {
+ switch(active_receiver->sample_rate) {
case 48000:
output_buffer[C1]|=SPEED_48K;
break;
output_buffer[C1]|=SPEED_384K;
break;
}
- if(radio->device==DEVICE_METIS) {
+
+// set more bits for Atlas based device
+// CONFIG_BOTH seems to be critical to getting ozy to respond
+#ifdef USBOZY
+ if ((device == DEVICE_OZY) || (device == DEVICE_METIS))
+#else
+ if (device == DEVICE_METIS)
+#endif
+ {
+ if (atlas_mic_source)
+ output_buffer[C1] |= PENELOPE_MIC;
+ output_buffer[C1] |= CONFIG_BOTH;
+ if (atlas_clock_source_128mhz)
+ output_buffer[C1] |= MERCURY_122_88MHZ_SOURCE;
+ output_buffer[C1] |= ((atlas_clock_source_10mhz & 3) << 2);
}
output_buffer[C2]=0x00;
if(classE) {
output_buffer[C2]|=0x01;
}
+ band=band_get_band(vfo[VFO_A].band);
if(isTransmitting()) {
- output_buffer[C2]|=band->OCtx;
+ if(split) {
+ band=band_get_band(vfo[VFO_B].band);
+ }
+ output_buffer[C2]|=band->OCtx<<1;
if(tune) {
if(OCmemory_tune_time!=0) {
struct timeval te;
gettimeofday(&te,NULL);
long long now=te.tv_sec*1000LL+te.tv_usec/1000;
if(tune_timeout>now) {
- output_buffer[C2]|=OCtune;
+ output_buffer[C2]|=OCtune<<1;
}
} else {
- output_buffer[C2]|=OCtune;
+ output_buffer[C2]|=OCtune<<1;
}
}
} else {
- output_buffer[C2]|=band->OCrx;
+ output_buffer[C2]|=band->OCrx<<1;
}
// TODO - add Alex Attenuation and Alex Antenna
output_buffer[C3]=0x00;
- if(rx_random) {
+ if(active_receiver->random) {
output_buffer[C3]|=LT2208_RANDOM_ON;
}
- if(rx_dither) {
+ if(active_receiver->dither) {
output_buffer[C3]|=LT2208_DITHER_ON;
}
-/*
- if(rx_preamp) {
+ if(active_receiver->preamp) {
output_buffer[C3]|=LT2208_GAIN_ON;
}
-*/
- switch(band->alexRxAntenna) {
+ switch(receiver[0]->alex_antenna) {
case 0: // ANT 1
break;
case 1: // ANT 2
output_buffer[C3]|=0xE0;
break;
default:
- // invalid - set to 0
- band->alexRxAntenna=0;
break;
}
output_buffer[C4]|=(RECEIVERS-1)<<3;
if(isTransmitting()) {
- switch(band->alexTxAntenna) {
+ switch(transmitter->alex_antenna) {
case 0: // ANT 1
output_buffer[C4]|=0x00;
break;
output_buffer[C4]|=0x02;
break;
default:
- // invalid - set to 0
- band->alexRxAntenna=0;
break;
}
} else {
- switch(band->alexRxAntenna) {
+ switch(receiver[0]->alex_antenna) {
case 0: // ANT 1
output_buffer[C4]|=0x00;
break;
case 3: // EXT 1
case 4: // EXT 2
case 5: // XVTR
- switch(band->alexTxAntenna) {
+ switch(transmitter->alex_antenna) {
case 0: // ANT 1
output_buffer[C4]|=0x00;
break;
break;
case 1: // tx frequency
output_buffer[C0]=0x02;
- long long txFrequency=ddsFrequency;
- if(ctun) {
- txFrequency+=ddsOffset;
+ long long txFrequency;
+ if(split) {
+ txFrequency=vfo[VFO_B].frequency-vfo[VFO_A].lo+vfo[VFO_B].offset;
+ } else {
+ txFrequency=vfo[VFO_A].frequency-vfo[VFO_B].lo+vfo[VFO_A].offset;
}
output_buffer[C1]=txFrequency>>24;
output_buffer[C2]=txFrequency>>16;
output_buffer[C4]=txFrequency;
break;
case 2: // rx frequency
- output_buffer[C0]=0x04+(current_rx*2);
- long long rxFrequency=ddsFrequency+(long long)rit;
- if(mode==modeCWU) {
- rxFrequency-=(long long)cw_keyer_sidetone_frequency;
- } else if(mode==modeCWL) {
- rxFrequency+=(long long)cw_keyer_sidetone_frequency;
+ if(current_rx<receivers) {
+ output_buffer[C0]=0x04+(current_rx*2);
+ int v=receiver[current_rx]->id;
+ long long rxFrequency=vfo[v].frequency+vfo[v].rit;
+ if(vfo[active_receiver->id].mode==modeCWU) {
+ rxFrequency-=(long long)cw_keyer_sidetone_frequency;
+ } else if(vfo[active_receiver->id].mode==modeCWL) {
+ rxFrequency+=(long long)cw_keyer_sidetone_frequency;
+ }
+ output_buffer[C1]=rxFrequency>>24;
+ output_buffer[C2]=rxFrequency>>16;
+ output_buffer[C3]=rxFrequency>>8;
+ output_buffer[C4]=rxFrequency;
+ current_rx++;
}
- output_buffer[C1]=rxFrequency>>24;
- output_buffer[C2]=rxFrequency>>16;
- output_buffer[C3]=rxFrequency>>8;
- output_buffer[C4]=rxFrequency;
- current_rx++;
- if(current_rx==RECEIVERS) {
+ if(current_rx>=receivers) {
current_rx=0;
}
break;
case 4:
output_buffer[C0]=0x14;
output_buffer[C1]=0x00;
+ for(i=0;i<receivers;i++) {
+ output_buffer[C1]|=(receiver[i]->preamp<<i);
+ }
if(mic_ptt_enabled==0) {
output_buffer[C1]|=0x40;
}
output_buffer[C2]=linein_gain;
output_buffer[C3]=0x00;
- if(radio->device==DEVICE_HERMES || radio->device==DEVICE_ANGELIA || radio->device==DEVICE_ORION) {
- output_buffer[C4]=0x20|attenuation;
+ if(radio->device==DEVICE_HERMES || radio->device==DEVICE_ANGELIA || radio->device==DEVICE_ORION || radio->device==DEVICE_ORION2) {
+ output_buffer[C4]=0x20|receiver[0]->attenuation;
} else {
output_buffer[C4]=0x00;
}
// need to add adc 2 and 3 attenuation
output_buffer[C0]=0x16;
output_buffer[C1]=0x00;
+ if(receivers==2) {
+ if(radio->device==DEVICE_HERMES || radio->device==DEVICE_ANGELIA || radio->device==DEVICE_ORION || radio->device==DEVICE_ORION2) {
+ output_buffer[C1]=0x20|receiver[1]->attenuation;
+ }
+ }
output_buffer[C2]=0x00;
if(cw_keys_reversed!=0) {
output_buffer[C2]|=0x40;
break;
case 7:
output_buffer[C0]=0x1E;
+ if(split) {
+ mode=vfo[1].mode;
+ } else {
+ mode=vfo[0].mode;
+ }
if(mode!=modeCWU && mode!=modeCWL) {
// output_buffer[C1]|=0x00;
} else {
}
}
+#ifdef USBOZY
+//
+// if we have a USB interfaced Ozy device:
+//
+ if (device == DEVICE_OZY)
+ ozyusb_write(output_buffer,OZY_BUFFER_SIZE);
+ else
+#endif
metis_write(0x02,output_buffer,OZY_BUFFER_SIZE);
command++;
// output_buffer[C0],output_buffer[C1],output_buffer[C2],output_buffer[C3],output_buffer[C4]);
}
+#ifdef USBOZY
+static int ozyusb_write(char* buffer,int length)
+{
+ int i;
+
+// batch up 4 USB frames (2048 bytes) then do a USB write
+ switch(usb_buffer_block++)
+ {
+ case 0:
+ default:
+ memcpy(usb_output_buffer, buffer, length);
+ break;
+
+ case 1:
+ memcpy(usb_output_buffer + 512, buffer, length);
+ break;
+
+ case 2:
+ memcpy(usb_output_buffer + 1024, buffer, length);
+ break;
+
+ case 3:
+ memcpy(usb_output_buffer + 1024 + 512, buffer, length);
+ usb_buffer_block = 0; // reset counter
+// and write the 4 usb frames to the usb in one 2k packet
+ i = ozy_write(EP2_OUT_ID,usb_output_buffer,EP6_BUFFER_SIZE);
+ if(i != EP6_BUFFER_SIZE)
+ {
+ perror("old_protocol: OzyWrite ozy failed");
+ }
+ break;
+ }
+}
+#endif
+
static int metis_write(unsigned char ep,char* buffer,int length) {
int i;
metis_buffer[6]=(send_sequence>>8)&0xFF;
metis_buffer[7]=(send_sequence)&0xFF;
+
// send the buffer
metis_send_buffer(&metis_buffer[0],1032);
metis_offset=8;
int i;
unsigned char buffer[64];
+#ifdef USBOZY
+ if(device!=DEVICE_OZY)
+ {
+#endif
+
buffer[0]=0xEF;
buffer[1]=0xFE;
buffer[2]=0x04; // start/stop command
}
metis_send_buffer(buffer,sizeof(buffer));
+#ifdef USBOZY
+ }
+#endif
}
static void metis_send_buffer(char* buffer,int length) {
#ifndef _OLD_PROTOCOL_H
#define _OLD_PROTOCOL_H
-#define BUFFER_SIZE 1024
-void old_protocol_stop();
-void old_protocol_init(int rx,int pixels);
-void old_protocol_new_sample_rate(int rate);
-void schedule_frequency_changed();
-void old_protocol_process_local_mic(unsigned char *buffer,int le);
+extern void old_protocol_stop();
+extern void old_protocol_run();
+extern void old_protocol_init(int rx,int pixels,int rate);
+extern void old_protocol_set_mic_sample_rate(int rate);
+
+extern void schedule_frequency_changed();
+extern void old_protocol_process_local_mic(unsigned char *buffer,int le);
+extern void old_protocol_audio_samples(RECEIVER *rx,short left_audio_sample,short right_audio_sample);
+extern void old_protocol_iq_samples(int isample,int qsample);
#endif
--- /dev/null
+/**
+* @file ozyio.c
+* @brief USB I/O with Ozy
+* @author John Melton, G0ORX/N6LYT
+* @version 0.1
+* @date 2009-10-13
+*/
+
+
+/* Copyright (C)
+* 2009 - 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.
+*
+*/
+
+/*
+* modified by Bob Wisdom VK4YA May 2015 to create ozymetis
+* modified further Laurence Barker G8NJJ to add USB functionality to pihpsdr
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h> // tolower
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h> // for stat
+#include <unistd.h> // for readlink, sleep, getcwd
+
+#include <libusb-1.0/libusb.h>
+
+#include "ozyio.h"
+
+#define OZY_PID (0x0007)
+#define OZY_VID (0xfffe)
+
+#define VRQ_SDR1K_CTL 0x0d
+#define SDR1KCTRL_READ_VERSION 0x7
+#define VRT_VENDOR_IN 0xC0
+
+#define VENDOR_REQ_TYPE_IN 0xc0
+#define VENDOR_REQ_TYPE_OUT 0x40
+
+#define VRQ_I2C_WRITE (0x08)
+#define VRT_VENDOR_OUT (0x40)
+
+
+#define VENDOR_REQ_SET_LED 0x01
+#define VENDOR_REQ_FPGA_LOAD 0x02
+
+#define FL_BEGIN 0
+#define FL_XFER 1
+#define FL_END 2
+
+#define OZY_BUFFER_SIZE 512
+
+//#define OZY_IO_TIMEOUT 500
+#define OZY_IO_TIMEOUT 2000
+#define MAX_EPO_PACKET_SIZE 64
+
+static int init=0;
+extern unsigned char penny_fw, mercury_fw;
+extern unsigned short penny_fp, penny_rp, penny_alc;
+extern int adc_overflow;
+void writepenny(unsigned char mode);
+static libusb_device_handle* ozy_handle;
+//static libusb_context* context;
+
+
+static char ozy_firmware[64] = {0};
+static char ozy_fpga[64] = {0};
+static unsigned char ozy_firmware_version[9];
+static unsigned char ozy_output_buffer[OZY_BUFFER_SIZE];
+
+// variables accessed via ozy_i2c_readvars:
+unsigned char penny_fw =0, mercury_fw = 0;
+
+// variables accessed via ozy_i2c_readpwr
+unsigned short penny_fp =0, penny_rp = 0, penny_alc = 0;
+int adc_overflow;
+
+
+
+
+
+int ozy_open(void) {
+ int rc;
+
+ if(init==0) {
+ rc=libusb_init(NULL);
+ if(rc<0) {
+ fprintf(stderr,"libusb_init failed: %d\n",rc);
+ return rc;
+ }
+ init=1;
+ }
+
+ ozy_handle=libusb_open_device_with_vid_pid(NULL, OZY_VID, OZY_PID);
+ if(ozy_handle==NULL) {
+ fprintf(stderr,"libusbio: cannot find ozy device\n");
+ return -1;
+ }
+
+ rc=libusb_detach_kernel_driver(ozy_handle,0);
+ if(rc<0) {
+ // fprintf(stderr,"libusb_detach_kernel_driver failed: %d\n",rc);
+ }
+
+ rc=libusb_claim_interface(ozy_handle,0);
+ if(rc<0) {
+ fprintf(stderr,"libusb_claim_interface failed: %d\n",rc);
+ return rc;
+ }
+
+ return 0;
+}
+
+int ozy_close() {
+ int rc;
+
+ rc=libusb_attach_kernel_driver(ozy_handle,0);
+ if(rc<0) {
+ // fprintf(stderr,"libusb_attach_kernel_driver failed: %d\n",rc);
+ }
+
+ libusb_close(ozy_handle);
+
+ return 0;
+}
+
+int ozy_get_firmware_string(unsigned char* buffer,int buffer_size) {
+ int rc;
+
+ rc=libusb_control_transfer(ozy_handle, VRT_VENDOR_IN, VRQ_SDR1K_CTL, SDR1KCTRL_READ_VERSION, 0, buffer, buffer_size, OZY_IO_TIMEOUT);
+ if(rc<0) {
+ fprintf(stderr,"ozy__get_firmware_string failed: %d\n",rc);
+ return rc;
+ }
+ buffer[rc]='\0';
+
+ return 0;
+}
+
+int ozy_write(int ep,unsigned char* buffer,int buffer_size) {
+ int rc;
+ int bytes;
+
+ rc = libusb_bulk_transfer(ozy_handle,(unsigned char)ep,buffer,buffer_size,&bytes,OZY_IO_TIMEOUT);
+ if(rc==0) {
+ rc=bytes;
+ }
+
+ return rc;
+}
+
+int ozy_read(int ep,unsigned char* buffer,int buffer_size) {
+ int rc;
+ int bytes;
+
+ rc = libusb_bulk_transfer(ozy_handle,(unsigned char)ep,buffer,buffer_size,&bytes,OZY_IO_TIMEOUT);
+ if(rc==0) {
+ rc=bytes;
+ }
+
+ return rc;
+}
+
+int ozy_write_ram(int fx2_start_addr, unsigned char *bufp, int count) {
+ int pkt_size = MAX_EPO_PACKET_SIZE;
+ int len = count;
+ int bytes_written = 0;
+ int addr;
+ int bytes_written_this_write;
+ int nsize;
+
+ for ( addr = fx2_start_addr; addr < fx2_start_addr + len; addr += pkt_size, bufp += pkt_size ) {
+ nsize = len + fx2_start_addr - addr;
+ if ( nsize > pkt_size ) nsize = pkt_size;
+ bytes_written_this_write = libusb_control_transfer(ozy_handle, 0x40, 0xa0, addr, 0, bufp, nsize, OZY_IO_TIMEOUT);
+ if ( bytes_written_this_write >= 0 ) {
+ bytes_written += bytes_written_this_write;
+ }
+ else {
+ return bytes_written_this_write;
+ }
+ }
+ return bytes_written;
+}
+
+int ozy_reset_cpu(int reset) {
+ unsigned char write_buf;
+
+ if ( reset ) write_buf = 1;
+ else write_buf = 0;
+
+ if ( ozy_write_ram(0xe600, &write_buf, 1) != 1 ) return 0;
+ else return 1;
+
+}
+
+static unsigned int hexitToUInt(char c) {
+ c = tolower(c);
+ if ( c >= '0' && c <= '9' ) {
+ return c - '0';
+ }
+ else if ( c >= 'a' && c <= 'f' ) {
+ return 10 + (c - 'a');
+ }
+ return 0;
+}
+
+static int ishexit(unsigned char c) {
+ c = tolower(c);
+ if ( c >= '0' && c <= '9' ) return 1;
+ if ( c >= 'a' && c <= 'f' ) return 1;
+ return 0;
+}
+
+static int hexitsToUInt(char *p, int count) {
+ unsigned int result = 0;
+ int i;
+ char c;
+ unsigned int this_hex;
+ for ( i = 0; i < count; i++ ) {
+ c = *p;
+ ++p;
+ if ( !ishexit(c) ) {
+ return -1;
+ }
+ this_hex = hexitToUInt(c);
+ result *= 16;
+ result += this_hex;
+ }
+ return result;
+}
+
+int ozy_load_firmware(char *fnamep) {
+ FILE *ifile;
+ int linecount = 0;
+ int length;
+ int addr;
+ int type;
+ char readbuf[1030];
+ unsigned char wbuf[256];
+ unsigned char my_cksum;
+ unsigned char cksum;
+ int this_val;
+ int i;
+
+ fprintf(stderr,"loading ozy firmware: %s\n",fnamep);
+
+ ifile = fopen(fnamep, "r");
+ if ( ifile == NULL ) {
+ fprintf(stderr, "Could not open: \'%s\'\n", fnamep);
+ return 0;
+ }
+
+ while ( fgets(readbuf, sizeof(readbuf), ifile) != NULL ) {
+ ++linecount;
+ if ( readbuf[0] != ':' ) {
+ fprintf(stderr, "ozy_upload_firmware: bad record\n");
+ return 0;
+ }
+ length = hexitsToUInt(readbuf+1, 2);
+ addr = hexitsToUInt(readbuf+3, 4);
+ type = hexitsToUInt(readbuf+7, 2);
+ if ( length < 0 || addr < 0 || type < 0 ) {
+ fprintf(stderr, "ozy_upload_firmware: bad length, addr or type\n");
+ return 0;
+ }
+ switch ( type ) {
+ case 0: /* record */
+ my_cksum = (unsigned char)(length + (addr & 0xff) + ((addr >> 8) + type));
+ for ( i = 0; i < length; i++ ) {
+ this_val = hexitsToUInt(readbuf+9+(i*2),2);
+ #if 0
+ printf("i: %d val: 0x%02x\n", i, this_val);
+ #endif
+
+ if ( this_val < 0 ) {
+ fprintf(stderr, "ozy_upload_firmware: bad record data\n");
+ return 0;
+ }
+ wbuf[i] = (unsigned char)this_val;
+ my_cksum += wbuf[i];
+ }
+
+ this_val = hexitsToUInt(readbuf+9+(length*2),2);
+ if ( this_val < 0 ) {
+ fprintf(stderr, "ozy_upload_firmware: bad checksum data\n");
+ return 0;
+ }
+ cksum = (unsigned char)this_val;
+ #if 0
+ printf("\n%s", readbuf);
+ printf("len: %d (0x%02x) addr: 0x%04x mychk: 0x%02x chk: 0x%02x",
+ length, length, addr, my_cksum, cksum);
+ #endif
+
+ if ( ((cksum + my_cksum) & 0xff) != 0 ) {
+ fprintf(stderr, "ozy_upload_firmware: bad checksum\n");
+ return 0;
+ }
+ if ( ozy_write_ram(addr, wbuf, length) < 1 ) {
+ fprintf(stderr, "ozy_upload_firmware: bad write\n");
+ return 0;
+ }
+ break;
+
+ case 1: /* EOF */
+ break;
+
+ default: /* invalid */
+ fprintf(stderr, "ozy_upload_firmware: invalid type\n");
+ return 0;
+
+ }
+ }
+ // fprintf(stderr, "ozy_upload_firmware: Processed %d lines.\n", linecount);
+ return linecount;
+}
+
+int ozy_set_led(int which, int on) {
+ int rc;
+ int val;
+
+ if ( on ) {
+ val = 1;
+ }
+ else {
+ val = 0;
+ }
+
+ rc = libusb_control_transfer(ozy_handle, VENDOR_REQ_TYPE_OUT, VENDOR_REQ_SET_LED,
+ val, which, NULL, 0, OZY_IO_TIMEOUT);
+
+ if ( rc < 0 ) {
+ return 0;
+ }
+ return 1;
+}
+
+int ozy_load_fpga(char *rbf_fnamep) {
+
+ FILE *rbffile;
+ unsigned char buf[MAX_EPO_PACKET_SIZE];
+ int bytes_read;
+ int total_bytes_xferd = 0;
+ int rc;
+
+ fprintf(stderr,"loading ozy fpga: %s\n",rbf_fnamep);
+
+ rbffile = fopen(rbf_fnamep, "rb");
+ if ( rbffile == NULL ) {
+ fprintf(stderr, "Failed to open: \'%s\'\n", rbf_fnamep);
+ return 0;
+ }
+
+ rc = libusb_control_transfer(ozy_handle, VENDOR_REQ_TYPE_OUT, VENDOR_REQ_FPGA_LOAD,
+ 0, FL_BEGIN, NULL, 0, OZY_IO_TIMEOUT);
+
+ if ( rc < 0 ) {
+ fprintf(stderr, "ozy_load_fpga: failed @ FL_BEGIN rc=%d\n",rc);
+ fclose(rbffile);
+ return 0;
+ }
+
+ /*
+ * read the rbf and send it over the wire, 64 bytes at a time
+ */
+ while ( (bytes_read = fread(buf, 1, sizeof(buf), rbffile)) > 0 ) {
+ rc = libusb_control_transfer(ozy_handle, VENDOR_REQ_TYPE_OUT, VENDOR_REQ_FPGA_LOAD,
+ 0, FL_XFER, buf, bytes_read, OZY_IO_TIMEOUT);
+ total_bytes_xferd += bytes_read;
+ if ( rc < 0 ) {
+ fprintf(stderr, "ozy_load_fpga: failed @ FL_XFER\n");
+ fclose(rbffile);
+ return 0;
+ }
+ }
+ printf("%d bytes transferred.\n", total_bytes_xferd);
+ fclose(rbffile);
+ rc = libusb_control_transfer(ozy_handle, VENDOR_REQ_TYPE_OUT, VENDOR_REQ_FPGA_LOAD,
+ 0, FL_END, NULL, 0, OZY_IO_TIMEOUT);
+ if ( rc < 0 ) {
+ fprintf(stderr, "ozy_load_fpga: failed @ FL_END\n");
+ return 0;
+ }
+
+ return 1;
+}
+
+int ozy_i2c_write(unsigned char* buffer,int buffer_size, unsigned char cmd) {
+ int rc;
+
+ rc=libusb_control_transfer(ozy_handle, VRT_VENDOR_OUT, VRQ_I2C_WRITE, cmd, 0, buffer, buffer_size, OZY_IO_TIMEOUT);
+ if(rc<0) {
+ fprintf(stderr,"ozy_i2c_write failed: %d\n",rc);
+ return rc;
+ }
+ return rc;
+}
+
+int ozy_i2c_read(unsigned char* buffer,int buffer_size, unsigned char cmd) {
+ int rc;
+
+ rc=libusb_control_transfer(ozy_handle, VRT_VENDOR_IN, VRQ_I2C_READ, cmd, 0, buffer, buffer_size, OZY_IO_TIMEOUT);
+ if(rc<0) {
+ fprintf(stderr,"ozy_i2c_read failed: %d\n",rc);
+ return rc;
+ }
+ return rc;
+}
+
+
+void ozy_i2c_readpwr(int addr) {
+ int rc = 0;
+ unsigned char buffer[8];
+
+ switch (addr) {
+ case I2C_PENNY_ALC:
+ rc = ozy_i2c_read(buffer,2,I2C_PENNY_ALC);
+ if(rc<0) {
+ perror("ozy_i2c_init4: failed");
+ //exit(1);
+ }
+ penny_alc = (buffer[0] << 8) + buffer[1];
+ break;
+
+ case I2C_PENNY_FWD:
+ rc = ozy_i2c_read(buffer,2,I2C_PENNY_FWD);
+ if(rc<0) {
+ perror("ozy_i2c_init5: failed");
+ //exit(1);
+ }
+ penny_fp = (buffer[0] << 8) + buffer[1];
+ break;
+
+ case I2C_PENNY_REV:
+ rc = ozy_i2c_read(buffer,2,I2C_PENNY_REV);
+ if(rc<0) {
+ perror("ozy_i2c_init6: failed");
+ //exit(1);
+ }
+ penny_rp = (buffer[0] << 8) + buffer[1];
+ break;
+
+ case I2C_ADC_OFS:
+ // adc overload
+ rc = ozy_i2c_read(buffer,2,I2C_ADC_OFS); // adc1 overflow status
+ if(rc<0) {
+ perror("ozy_i2c_init6: failed");
+ //exit(1);
+ }
+ if (buffer[0] == 0) { // its overloaded
+ adc_overflow = 2000; // counts down to give hold time to client
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void ozy_i2c_readvars() {
+ int rc = 0;
+ unsigned char buffer[8];
+
+
+ fprintf(stderr,"ozy_i2c_init: starting\n");
+
+ if (rc != 0) {
+ fprintf(stderr,"ozy_i2c_init: failed open %d\n",rc);
+ }
+
+ rc = ozy_i2c_read(buffer,2,I2C_MERC1_FW);
+ if(rc<0) {
+ perror("ozy_i2c_init2: failed");
+ //exit(1);
+ }
+ mercury_fw = buffer[1];
+ fprintf(stderr,"mercury firmware=%d\n",(int)buffer[1]);
+
+ rc = ozy_i2c_read(buffer,2,I2C_PENNY_FW);
+ if(rc<0) {
+ perror("ozy_i2c_init3: failed");
+ //exit(1);
+ }
+ penny_fw = buffer[1];
+ fprintf(stderr,"penny firmware=%d\n",(int)buffer[1]);
+
+ writepenny((unsigned char)1);
+}
+
+void writepenny(unsigned char mode)
+{
+ unsigned char Penny_TLV320[2];
+ unsigned char *Penny_TLV320_data; // 16 byte
+ int x;
+ // This is used to set the MicGain and Line in when Ozy/Magister is used
+ // The I2C settings are as follows:
+
+ // For mic input and boost on/off
+ // 1E 00 - Reset chip
+ // 12 01 - set digital interface active
+ // 08 15 - D/A on, mic input, mic 20dB boost
+ // 08 14 - ditto but no mic boost
+ // 0C 00 - All chip power on
+ // 0E 02 - Slave, 16 bit, I2S
+ // 10 00 - 48k, Normal mode
+ // 0A 00 - turn D/A mute off
+ // 00 00 - set Line in gain to 0
+
+ // For line input
+ // 1E 00 - Reset chip
+ // 12 01 - set digital interface active
+ // 08 10 - D/A on, line input
+ // 0C 00 - All chip power on
+ // 0E 02 - Slave, 16 bit, I2S
+ // 10 00 - 48k, Normal mode
+ // 0A 00 - turn D/A mute off
+ // 00 00 - set Line in gain to 0
+ fprintf(stderr,"write Penny\n");
+
+ // update mic gain on Penny or PennyLane TLV320
+
+ // need to select the config data depending on the Mic Gain (20dB) selected
+ if (mode == 0x01)
+ Penny_TLV320_data = (unsigned char []) { 0x1e, 0x00, 0x12, 0x01, 0x08, 0x15, 0x0c, 0x00, 0x0e, 0x02, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00 }; // mic in 20db gain
+ else if (mode & 2) // line in
+ Penny_TLV320_data = (unsigned char []) { 0x1e, 0x00, 0x12, 0x01, 0x08, 0x10, 0x0c, 0x00, 0x0e, 0x02, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00 }; // line in
+ else
+ Penny_TLV320_data = (unsigned char []) { 0x1e, 0x00, 0x12, 0x01, 0x08, 0x14, 0x0c, 0x00, 0x0e, 0x02, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00 }; // mic in not 20db gain
+
+ // // set the I2C interface speed to 400kHZ
+ // if (!(OZY.Set_I2C_Speed(hdev, 1)))
+ // {
+ // fprintf(stderr,"Unable to set I2C speed to 400kHz", "System Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ // return;
+
+ // send the configuration data to the TLV320 on Penelope or PennyLane
+ for (x = 0; x < 16; x += 2)
+ {
+ Penny_TLV320[0] = Penny_TLV320_data[x]; Penny_TLV320[1] = Penny_TLV320_data[x + 1];
+ int ozy_write_i2c(int ep,unsigned char* buffer,int buffer_size);
+ if (!(ozy_i2c_write(Penny_TLV320,2, 0x1b)))
+ {
+ fprintf(stderr,"Unable to configure TLV320 on Penelope via I2C\n");
+ // break out of the configuration loop
+ break;
+ }
+ }
+ fprintf(stderr,"write Penny done..\n");
+}
+
+
+
+static int file_exists (const char * fileName)
+{
+ struct stat buf;
+ int i = stat ( fileName, &buf );
+ return ( i == 0 ) ? 1 : 0 ;
+}
+
+#ifdef __linux__
+int filePath (char *sOut, const char *sIn) {
+ int rc = 0;
+
+ if ((rc = file_exists (sIn))) {
+ strcpy (sOut, sIn);
+ rc = 1;
+ } else {
+ char cwd[PATH_MAX];
+ char s[PATH_MAX];
+ char xPath [PATH_MAX] = {0};
+ char *p;
+
+ int rc = readlink ("/proc/self/exe", xPath, sizeof(xPath));
+
+ // try to detect the directory from which the executable has been loaded
+ if (rc >= 0) {
+
+ if ( (p = strrchr (xPath, '/')) ) *(p+1) = '\0';
+ fprintf (stderr, "%d, Path of executable: [%s]\n", rc, xPath);
+
+ strcpy (s, xPath); strcat (s, sIn);
+
+ if ((rc = file_exists (s))) {
+ // found in the same dir of executable
+ fprintf (stderr, "File: [%s]\n", s);
+ strcpy(sOut, s);
+ } else {
+ if (getcwd(cwd, sizeof(cwd)) != NULL) {
+ fprintf(stdout, "Current working dir: %s\n", cwd);
+
+ strcpy (s, cwd); strcat (s, "/"); strcat (s, sIn);
+ if ((rc = file_exists (s))) {
+ fprintf (stderr, "File: [%s]\n", s);
+ strcpy(sOut, s);
+ }
+ }
+ }
+ } else {
+ fprintf (stderr, "%d: %s\n", errno, strerror(errno));
+ }
+ }
+ return rc;
+}
+#endif
+
+
+
+//
+// initialise a USB ozy device.
+// renamed as "initialise" and combined with the "ozyinit" code
+//
+int ozy_initialise()
+{
+ int rc;
+
+ if (strlen(ozy_firmware) == 0) filePath (ozy_firmware,"ozyfw-sdr1k.hex");
+ if (strlen(ozy_fpga) == 0) filePath (ozy_fpga,"Ozy_Janus.rbf");
+
+// open ozy
+ rc = ozy_open();
+ if (rc != 0) {
+ fprintf(stderr,"Cannot locate Ozy\n");
+ //exit(1);
+ }
+// load Ozy FW
+ ozy_reset_cpu(1);
+ ozy_load_firmware(ozy_firmware);
+ ozy_reset_cpu(0);
+ ozy_close();
+ sleep(4);
+ ozy_open();
+ ozy_set_led(1,1);
+ ozy_load_fpga(ozy_fpga);
+ ozy_set_led(1,0);
+ ozy_close();
+ ozy_open();
+ rc=ozy_get_firmware_string(ozy_firmware_version,8);
+ fprintf(stderr,"Ozy FX2 version: %s\n",ozy_firmware_version);
+
+ ozy_i2c_readvars();
+ ozy_close();
+ sleep(1);
+ ozy_open();
+ return 0;
+}
+
+
+
+//
+// modified from "ozy_open" code: just finds out if there is a USB
+// ozy on the bus. Closes the connection after discovering.
+// returns 1 if a device found on USB
+//
+//
+int ozy_discover(void)
+{
+ int success = 0; // function return code
+ int rc;
+
+ if(init==0)
+ {
+ rc=libusb_init(NULL);
+ if(rc<0)
+ {
+ fprintf(stderr,"libusb_init failed: %d\n",rc);
+ return success;
+ }
+ init=1;
+ }
+//
+// do a trial open with thr PID and VID of ozy
+//
+ ozy_handle=libusb_open_device_with_vid_pid(NULL, OZY_VID, OZY_PID);
+ if(ozy_handle==NULL)
+ {
+ fprintf(stderr,"libusbio: cannot find ozy device\n");
+ return success;
+ }
+ else
+ {
+ success = 1;
+ fprintf(stderr,"libusbio: ozy device found on USB port\n");
+ }
+//
+// if we get this far, we have an ozy on the bus so discover successful.
+// we don't know that it will be selected for use, so close it again
+// for now; re-open if the user selects Ozy
+//
+ libusb_close(ozy_handle);
+ return success;
+}
--- /dev/null
+/**
+* @file ozyio.h
+* @brief USB I/O with Ozy
+* @author John Melton, G0ORX/N6LYT
+* @version 0.1
+* @date 2009-10-13
+*/
+
+/* Copyright (C)
+* 2009 - 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.
+*
+*/
+
+/*
+* modified by Bob Wisdom VK4YA May 2015 to create ozymetis
+* modified further Laurence Barker G8NJJ to add USB functionality to pihpsdr
+*/
+
+
+/*
+ * code modified from that in Ozy_Metis_RPI_Gateway
+ * Laurence Barker, G8NJJ December 2016
+ * this gathers all Ozy functionality in one file (merging code
+ * from ozy.c).
+ * Further modified to add a "discover" function
+ *
+*/
+
+#if !defined __OZYIO_H__
+#define __OZYIO_H__
+
+//
+// penelope forward, reverse power and ALC settings
+//
+extern unsigned short penny_fp, penny_rp, penny_alc;
+extern int adc_overflow;
+
+int ozy_open(void);
+int ozy_close();
+int ozy_get_firmware_string(unsigned char* buffer,int buffer_size);
+int ozy_write(int ep,unsigned char* buffer,int buffer_size);
+int ozy_read(int ep,unsigned char* buffer,int buffer_size);
+
+void ozy_load_fw();
+int ozy_load_fpga(char *rbf_fnamep);
+int ozy_set_led(int which, int on);
+int ozy_reset_cpu(int reset);
+int ozy_load_firmware(char *fnamep);
+int ozy_initialise();
+int ozy_discover(void); // returns 1 if a device found on USB
+void ozy_i2c_readpwr(int addr); // sets local variables
+
+
+
+// Ozy I2C commands for polling firmware versions, power levels, ADC overload.
+#define I2C_MERC1_FW 0x10 // Mercury1 firmware version
+#define I2C_MERC2_FW 0x11 // Mercury2 firmware version
+#define I2C_MERC3_FW 0x12 // Mercury3 firmware version
+#define I2C_MERC4_FW 0x13 // Mercury4 firmware version
+
+#define I2C_MERC1_ADC_OFS 0x10 // adc1 overflow status
+#define I2C_MERC2_ADC_OFS 0x11 // adc2 overflow status
+#define I2C_MERC3_ADC_OFS 0x12 // adc3 overflow status
+#define I2C_MERC4_ADC_OFS 0x13 // adc4 overflow status
+
+#define I2C_PENNY_FW 0x15 // Penny firmware version
+#define I2C_PENNY_ALC 0x16 // Penny forward power
+#define I2C_PENNY_FWD 0x17 // Penny forward power from Alex
+#define I2C_PENNY_REV 0x18 // Penny reverse power from Alex
+#define I2C_ADC_OFS (0x10) // ADC overload status
+#define VRQ_I2C_READ 0x81 // i2c address; length; how much to read
+
+#endif
#include "pa_menu.h"
#include "band.h"
#include "radio.h"
+#include "vfo.h"
static GtkWidget *parent_window=NULL;
static void pa_value_changed_cb(GtkWidget *widget, gpointer data) {
BAND *band=(BAND *)data;
band->pa_calibration=gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget));
- calcDriveLevel();
- calcTuneDriveLevel();
+ int v=VFO_A;
+ if(split) v=VFO_B;
+ int b=vfo[v].band;
+ BAND *current=band_get_band(b);
+ if(band==current) {
+ calcDriveLevel();
+ calcTuneDriveLevel();
+ }
}
static void tx_out_of_band_cb(GtkWidget *widget, gpointer data) {
+++ /dev/null
-/* Copyright (C)
-* 2015 - John Melton, G0ORX/N6LYT
-*
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-*/
-
-#include <gtk/gtk.h>
-#include <gdk/gdk.h>
-#include <math.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <semaphore.h>
-#include "agc.h"
-#include "band.h"
-#include "channel.h"
-#include "discovered.h"
-#include "radio.h"
-#include "panadapter.h"
-#include "vfo.h"
-#include "mode.h"
-#ifdef FREEDV
-#include "freedv.h"
-#endif
-#include "wdsp_init.h"
-
-static GtkWidget *panadapter;
-static cairo_surface_t *panadapter_surface = NULL;
-
-static float* samples;
-
-static gint last_x;
-static gboolean has_moved=FALSE;
-static gboolean pressed=FALSE;
-
-//static float panadapter_max=-60.0;
-//static float panadapter_min=-160.0;
-
-static gfloat hz_per_pixel;
-static gfloat filter_left;
-static gfloat filter_right;
-
-static int display_width;
-static int display_height;
-
-/* Create a new surface of the appropriate size to store our scribbles */
-static gboolean
-panadapter_configure_event_cb (GtkWidget *widget,
- GdkEventConfigure *event,
- gpointer data)
-{
- display_width=gtk_widget_get_allocated_width (widget);
- display_height=gtk_widget_get_allocated_height (widget);
-
-fprintf(stderr,"panadapter_configure_event_cb: width:%d height:%d\n",display_width,display_height);
- if (panadapter_surface)
- cairo_surface_destroy (panadapter_surface);
-
- panadapter_surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget),
- CAIRO_CONTENT_COLOR,
- display_width,
- display_height);
-
- cairo_t *cr=cairo_create(panadapter_surface);
- cairo_set_source_rgb(cr, 0, 0, 0);
- cairo_paint(cr);
- cairo_destroy(cr);
-
- return TRUE;
-}
-
-/* Redraw the screen from the surface. Note that the ::draw
- * signal receives a ready-to-be-used cairo_t that is already
- * clipped to only draw the exposed areas of the widget
- */
-static gboolean
-panadapter_draw_cb (GtkWidget *widget,
- cairo_t *cr,
- gpointer data)
-{
- cairo_set_source_surface (cr, panadapter_surface, 0, 0);
- cairo_paint (cr);
-
- return FALSE;
-}
-
-static gboolean
-panadapter_button_press_event_cb (GtkWidget *widget,
- GdkEventButton *event,
- gpointer data)
-{
- int x=(int)event->x;
- if (event->button == 1) {
- last_x=(int)event->x;
- has_moved=FALSE;
- pressed=TRUE;
- }
- return TRUE;
-}
-
-static gboolean
-panadapter_button_release_event_cb (GtkWidget *widget,
- GdkEventButton *event,
- gpointer data)
-{
- if(pressed) {
- int x=(int)event->x;
- if (event->button == 1) {
- if(has_moved) {
- // drag
- vfo_move((int)((float)(x-last_x)*hz_per_pixel));
- } else {
- // move to this frequency
- vfo_move_to((int)((float)(x-(display_width/2))*hz_per_pixel));
- }
- last_x=x;
- pressed=FALSE;
- }
- }
- return TRUE;
-}
-
-static gboolean
-panadapter_motion_notify_event_cb (GtkWidget *widget,
- GdkEventMotion *event,
- gpointer data)
-{
- int x, y;
- GdkModifierType state;
- gdk_window_get_device_position (event->window,
- event->device,
- &x,
- &y,
- &state);
- if((state & GDK_BUTTON1_MASK == GDK_BUTTON1_MASK) || pressed) {
- int moved=last_x-x;
- vfo_move((int)((float)moved*hz_per_pixel));
- last_x=x;
- has_moved=TRUE;
- }
-
- return TRUE;
-}
-
-static gboolean
-panadapter_scroll_event_cb (GtkWidget *widget,
- GdkEventScroll *event,
- gpointer data)
-{
- if(event->direction==GDK_SCROLL_UP) {
- vfo_move(step);
- } else {
- vfo_move(-step);
- }
-}
-
-static void
-close_window (void)
-{
- if (panadapter_surface)
- cairo_surface_destroy (panadapter_surface);
-
- gtk_main_quit ();
-}
-
-void panadapter_update(float *data,int tx) {
- int i;
- int result;
-
- float saved_max;
- float saved_min;
- gfloat saved_hz_per_pixel;
- cairo_text_extents_t extents;
-
- hz_per_pixel=(double)getSampleRate()/(double)display_width;
- samples=data;
- //if(result==1) {
- if(panadapter_surface) {
-
- if(tx) {
- saved_max=panadapter_high;
- saved_min=panadapter_low;
- saved_hz_per_pixel=hz_per_pixel;
-
- panadapter_high=20;
- panadapter_low=-80;
- //if(protocol==ORIGINAL_PROTOCOL) {
- hz_per_pixel=48000.0/(double)display_width;
- //} else {
- // hz_per_pixel=192000.0/(double)display_width;
- //}
- }
-
- //clear_panadater_surface();
- cairo_t *cr;
- cr = cairo_create (panadapter_surface);
- cairo_set_source_rgb (cr, 0, 0, 0);
- cairo_paint (cr);
-
- // filter
- cairo_set_source_rgb (cr, 0.25, 0.25, 0.25);
- if(ctun && isTransmitting()) {
- filter_left=(double)display_width/2.0+((double)getFilterLow()/hz_per_pixel);
- filter_right=(double)display_width/2.0+((double)getFilterHigh()/hz_per_pixel);
- } else {
- 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)display_height);
- cairo_fill(cr);
-
- // plot the levels
- int V = (int)(panadapter_high - panadapter_low);
- int numSteps = V / 20;
- for (i = 1; i < numSteps; i++) {
- int num = panadapter_high - i * 20;
- int y = (int)floor((panadapter_high - num) * display_height / V);
-
- cairo_set_source_rgb (cr, 0, 1, 1);
- cairo_set_line_width(cr, 1.0);
- cairo_move_to(cr,0.0,(double)y);
- cairo_line_to(cr,(double)display_width,(double)y);
-
- cairo_set_source_rgb (cr, 0, 1, 1);
- cairo_select_font_face(cr, "FreeMono",
- CAIRO_FONT_SLANT_NORMAL,
- CAIRO_FONT_WEIGHT_BOLD);
- cairo_set_font_size(cr, 12);
- char v[32];
- sprintf(v,"%d dBm",num);
- cairo_move_to(cr, 1, (double)y);
- cairo_show_text(cr, v);
- }
- cairo_stroke(cr);
-
- // plot frequency markers
- long f;
- long divisor=20000;
- long half=(long)getSampleRate()/2L;
- long long frequency=displayFrequency;
- if(ctun && isTransmitting()) {
- frequency+=ddsOffset;
- }
- switch(sample_rate) {
- case 48000:
- divisor=5000L;
- break;
- case 96000:
- case 100000:
- divisor=10000L;
- break;
- case 192000:
- divisor=20000L;
- break;
- case 384000:
- divisor=25000L;
- break;
- case 768000:
- divisor=50000L;
- break;
- case 1048576:
- case 1536000:
- case 2097152:
- divisor=100000L;
- break;
- }
- for(i=0;i<display_width;i++) {
- f = frequency - half + (long) (hz_per_pixel * i);
- if (f > 0) {
- if ((f % divisor) < (long) hz_per_pixel) {
- cairo_set_source_rgb (cr, 0, 1, 1);
- cairo_set_line_width(cr, 1.0);
- //cairo_move_to(cr,(double)i,0.0);
- cairo_move_to(cr,(double)i,10.0);
- cairo_line_to(cr,(double)i,(double)display_height);
-
- cairo_set_source_rgb (cr, 0, 1, 1);
- cairo_select_font_face(cr, "FreeMono",
- CAIRO_FONT_SLANT_NORMAL,
- CAIRO_FONT_WEIGHT_BOLD);
- cairo_set_font_size(cr, 12);
- char v[32];
- sprintf(v,"%0ld.%03ld",f/1000000,(f%1000000)/1000);
- //cairo_move_to(cr, (double)i, (double)(display_height-10));
- cairo_text_extents(cr, v, &extents);
- cairo_move_to(cr, (double)i-(extents.width/2.0), 10.0);
- cairo_show_text(cr, v);
- }
- }
- }
- cairo_stroke(cr);
-
- // band edges
- long long min_display=frequency-half;
- long long max_display=frequency+half;
- BAND *band=band_get_current_band();
- if(band->frequencyMin!=0LL) {
- cairo_set_source_rgb (cr, 1, 0, 0);
- cairo_set_line_width(cr, 2.0);
- if((min_display<band->frequencyMin)&&(max_display>band->frequencyMin)) {
- i=(band->frequencyMin-min_display)/(long long)hz_per_pixel;
- cairo_move_to(cr,(double)i,0.0);
- cairo_line_to(cr,(double)i,(double)display_height);
- cairo_stroke(cr);
- }
- if((min_display<band->frequencyMax)&&(max_display>band->frequencyMax)) {
- i=(band->frequencyMax-min_display)/(long long)hz_per_pixel;
- cairo_move_to(cr,(double)i,0.0);
- cairo_line_to(cr,(double)i,(double)display_height);
- cairo_stroke(cr);
- }
- }
-
- // agc
- if(agc!=AGC_OFF && !tx) {
- double hang=0.0;
- double thresh=0;
-
- GetRXAAGCHangLevel(CHANNEL_RX0, &hang);
- GetRXAAGCThresh(CHANNEL_RX0, &thresh, 4096.0, (double)sample_rate);
-
- double knee_y=thresh+(double)get_attenuation();
- knee_y = floor((panadapter_high - knee_y)
- * (double) display_height
- / (panadapter_high - panadapter_low));
-
- double hang_y=hang+(double)get_attenuation();
- hang_y = floor((panadapter_high - hang_y)
- * (double) display_height
- / (panadapter_high - panadapter_low));
-
-//fprintf(stderr,"hang=%f thresh=%f hang_y=%f knee_y=%f\n",rx1_hang,rx1_thresh,hang_y,knee_y);
- if(agc!=AGC_MEDIUM && agc!=AGC_FAST) {
- cairo_set_source_rgb (cr, 1.0, 1.0, 0.0);
- cairo_move_to(cr,40.0,hang_y-8.0);
- cairo_rectangle(cr, 40, hang_y-8.0,8.0,8.0);
- cairo_fill(cr);
- cairo_move_to(cr,40.0,hang_y);
- cairo_line_to(cr,(double)display_width-40.0,hang_y);
- cairo_stroke(cr);
- cairo_move_to(cr,48.0,hang_y);
- cairo_show_text(cr, "-H");
- }
-
- cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
- cairo_move_to(cr,40.0,knee_y-8.0);
- cairo_rectangle(cr, 40, knee_y-8.0,8.0,8.0);
- cairo_fill(cr);
- cairo_move_to(cr,40.0,knee_y);
- cairo_line_to(cr,(double)display_width-40.0,knee_y);
- cairo_stroke(cr);
- cairo_move_to(cr,48.0,knee_y);
- cairo_show_text(cr, "-G");
- }
-
-
- // cursor
- cairo_set_source_rgb (cr, 1, 0, 0);
- cairo_set_line_width(cr, 1.0);
- cairo_move_to(cr,(double)(display_width/2.0)+(ddsOffset/hz_per_pixel),0.0);
- cairo_line_to(cr,(double)(display_width/2.0)+(ddsOffset/hz_per_pixel),(double)display_height);
- cairo_stroke(cr);
-
- // signal
- double s1,s2;
- samples[0]=-200.0;
- samples[display_width-1]=-200.0;
-
- if(tx && protocol==NEW_PROTOCOL) {
- int offset=1200;
- s1=(double)samples[0+offset]+(double)get_attenuation();
- s1 = floor((panadapter_high - s1)
- * (double) display_height
- / (panadapter_high - panadapter_low));
- cairo_move_to(cr, 0.0, s1);
- for(i=1;i<display_width;i++) {
- s2=(double)samples[i+offset]+(double)get_attenuation();
- s2 = floor((panadapter_high - s2)
- * (double) display_height
- / (panadapter_high - panadapter_low));
- cairo_line_to(cr, (double)i, s2);
- }
- } else {
- s1=(double)samples[0]+(double)get_attenuation();
- s1 = floor((panadapter_high - s1)
- * (double) display_height
- / (panadapter_high - panadapter_low));
- cairo_move_to(cr, 0.0, s1);
- for(i=1;i<display_width;i++) {
- s2=(double)samples[i]+(double)get_attenuation();
- s2 = floor((panadapter_high - s2)
- * (double) display_height
- / (panadapter_high - panadapter_low));
- cairo_line_to(cr, (double)i, s2);
- }
- }
- if(display_filled) {
- cairo_close_path (cr);
- cairo_set_source_rgba(cr, 1, 1, 1,0.5);
- cairo_fill_preserve (cr);
- }
- cairo_set_source_rgb(cr, 1, 1, 1);
- cairo_set_line_width(cr, 1.0);
- cairo_stroke(cr);
-
-#ifdef FREEDV
- if(mode==modeFREEDV) {
- if(tx) {
- cairo_set_source_rgb(cr, 1, 0, 0);
- } else {
- cairo_set_source_rgb(cr, 0, 1, 0);
- }
- cairo_set_font_size(cr, 16);
- cairo_text_extents(cr, freedv_text_data, &extents);
- cairo_move_to(cr, (double)display_width/2.0-(extents.width/2.0),(double)display_height-2.0);
- cairo_show_text(cr, freedv_text_data);
- }
-#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;
- } /* else if(mode==modeFREEDV) {
- panadapter_high=saved_max;
- panadapter_low=saved_min;
- hz_per_pixel=saved_hz_per_pixel;
- } */
- }
- //}
-}
-
-GtkWidget* panadapter_init(int width,int height) {
-
- display_width=width;
- display_height=height;
-
- samples=malloc(display_width*sizeof(float));
- hz_per_pixel=(double)getSampleRate()/(double)display_width;
-
- panadapter = gtk_drawing_area_new ();
- gtk_widget_set_size_request (panadapter, width, height);
-
- /* Signals used to handle the backing surface */
- g_signal_connect (panadapter, "draw",
- G_CALLBACK (panadapter_draw_cb), NULL);
- g_signal_connect (panadapter,"configure-event",
- G_CALLBACK (panadapter_configure_event_cb), NULL);
-
- /* Event signals */
- g_signal_connect (panadapter, "motion-notify-event",
- G_CALLBACK (panadapter_motion_notify_event_cb), NULL);
- g_signal_connect (panadapter, "button-press-event",
- G_CALLBACK (panadapter_button_press_event_cb), NULL);
- g_signal_connect (panadapter, "button-release-event",
- G_CALLBACK (panadapter_button_release_event_cb), NULL);
- g_signal_connect(panadapter,"scroll_event",
- G_CALLBACK(panadapter_scroll_event_cb),NULL);
-
- /* Ask to receive events the drawing area doesn't normally
- * subscribe to. In particular, we need to ask for the
- * button press and motion notify events that want to handle.
- */
- gtk_widget_set_events (panadapter, gtk_widget_get_events (panadapter)
- | GDK_BUTTON_PRESS_MASK
- | GDK_BUTTON_RELEASE_MASK
- | GDK_BUTTON1_MOTION_MASK
- | GDK_SCROLL_MASK
- | GDK_POINTER_MOTION_MASK
- | GDK_POINTER_MOTION_HINT_MASK);
-
- return panadapter;
-}
+++ /dev/null
-/* Copyright (C)
-* 2015 - John Melton, G0ORX/N6LYT
-*
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-*/
-
-#ifndef _PANADAPTER_H
-#define _PANADAPTER_H
-
-void panadapter_update(float* data,int tx);
-
-GtkWidget* panadapter_init(int width,int height);
-
-
-#endif
PROPERTY* properties;
+static double version=0.0;
+
/* --------------------------------------------------------------------------*/
/**
* @brief Load Properties
strcpy(property->value,value);
property->next_property=properties;
properties=property;
+ if(strcmp(name,"property_version")==0) {
+ version=atof(value);
+ }
}
}
fclose(f);
}
- fprintf(stderr,"loadProperties: done\n");
+
+ if(version!=PROPERTY_VERSION) {
+ properties=NULL;
+ fprintf(stderr,"loadProperties: version=%f expected version=%f ignoring\n",version,PROPERTY_VERSION);
+ }
}
/* --------------------------------------------------------------------------*/
return;
}
- sprintf(version,"%0.2f", PROPERTY_VERSION);
- setProperty("property_version",version);
+ sprintf(line,"%s=%0.2f\n","property_version",PROPERTY_VERSION);
+ fwrite(line,1,strlen(line),f);
while(property) {
sprintf(line,"%s=%s\n",property->name,property->value);
fwrite(line,1,strlen(line),f);
#ifndef _PROPERTY_H
#define _PROPERTY_H
-#define PROPERTY_VERSION 1.0
+#define PROPERTY_VERSION 2.0
typedef struct _PROPERTY PROPERTY;
#include "psk.h"
#include "radio.h"
#include "channel.h"
-#include "wdsp_init.h"
static void *detector;
#include "vfo.h"
#include "psk.h"
#include "psk_waterfall.h"
+#include "receiver.h"
static GtkWidget *waterfall;
static GdkPixbuf *pixbuf = NULL;
if (event->button == 1) {
if(has_moved) {
// drag
- vfo_move((int)((float)(x-last_x)*hz_per_pixel));
+ vfo_move((long long)((float)(x-last_x)*hz_per_pixel));
} else {
// move to this frequency
- vfo_move_to((int)((float)(x-(display_width/2))*hz_per_pixel));
+ vfo_move_to((long long)((float)(x-(display_width/2))*hz_per_pixel));
}
last_x=x;
pressed=FALSE;
&state);
if((state & GDK_BUTTON1_MASK == GDK_BUTTON1_MASK) || pressed) {
int moved=last_x-x;
- vfo_move((int)((float)moved*hz_per_pixel));
+ vfo_move((long long)((float)moved*hz_per_pixel));
last_x=x;
has_moved=TRUE;
}
return TRUE;
}
-void psk_waterfall_update(float *data) {
+void psk_waterfall_update(RECEIVER *rx) {
int i;
#ifndef _PSK_WATERFALL_H
#define _PSK_WATERFALL_H
-void psk_waterfall_update(float *data);
+void psk_waterfall_update(RECEIVER *rx);
GtkWidget* psk_waterfall_init(int width,int height);
#endif
*
*/
+#include <gtk/gtk.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <semaphore.h>
#include <math.h>
+#include <wdsp.h>
+
#include "audio.h"
#include "discovered.h"
//#include "discovery.h"
+#include "filter.h"
+#include "main.h"
#include "mode.h"
#include "radio.h"
+#include "receiver.h"
+#include "transmitter.h"
#include "channel.h"
#include "agc.h"
#include "band.h"
#include "property.h"
#include "new_protocol.h"
+#include "old_protocol.h"
+#include "store.h"
#ifdef LIMESDR
#include "lime_protocol.h"
#endif
-#include "wdsp.h"
#ifdef FREEDV
#include "freedv.h"
#endif
+#ifdef GPIO
+#include "gpio.h"
+#endif
+#include "vfo.h"
+#include "meter.h"
+#include "rx_panadapter.h"
+#include "tx_panadapter.h"
+#include "waterfall.h"
+#include "sliders.h"
+#include "toolbar.h"
#define min(x,y) (x<y?x:y)
#define max(x,y) (x<y?y:x)
+#define DISPLAY_INCREMENT (display_height/32)
+#define MENU_HEIGHT (DISPLAY_INCREMENT*2)
+#define MENU_WIDTH ((display_width/32)*3)
+#define VFO_HEIGHT (DISPLAY_INCREMENT*4)
+#define VFO_WIDTH (display_width-METER_WIDTH-MENU_WIDTH)
+#define METER_HEIGHT (DISPLAY_INCREMENT*4)
+#define METER_WIDTH ((display_width/32)*8)
+#define PANADAPTER_HEIGHT (DISPLAY_INCREMENT*8)
+#define SLIDERS_HEIGHT (DISPLAY_INCREMENT*6)
+#define TOOLBAR_HEIGHT (DISPLAY_INCREMENT*2)
+#define WATERFALL_HEIGHT (display_height-(VFO_HEIGHT+PANADAPTER_HEIGHT+SLIDERS_HEIGHT+TOOLBAR_HEIGHT))
+#ifdef PSK
+#define PSK_WATERFALL_HEIGHT (DISPLAY_INCREMENT*6)
+#define PSK_HEIGHT (display_height-(VFO_HEIGHT+PSK_WATERFALL_HEIGHT+SLIDERS_HEIGHT+TOOLBAR_HEIGHT))
+#endif
+
+static GtkWidget *fixed;
+static GtkWidget *vfo_panel;
+static GtkWidget *meter;
+static GtkWidget *menu;
+static GtkWidget *sliders;
+static GtkWidget *toolbar;
+static GtkWidget *panadapter;
+static GtkWidget *waterfall;
+#ifdef PSK
+static GtkWidget *psk;
+static GtkWidget *psk_waterfall;
+#endif
+
+#ifdef GPIO
+static GtkWidget *encoders;
+static cairo_surface_t *encoders_surface = NULL;
+#endif
+
+int echo=0;
+
+static gint save_timer_id;
+
DISCOVERED *radio;
char property_path[128];
sem_t property_sem;
+RECEIVER *receiver[MAX_RECEIVERS];
+RECEIVER *active_receiver;
+TRANSMITTER *transmitter;
+
+int buffer_size=1024; // 64, 128, 256, 512, 1024
+int fft_size=4096; // 1024, 2048, 4096, 8192, 16384
+
int atlas_penelope=0;
int atlas_clock_source_10mhz=0;
int atlas_clock_source_128mhz=0;
double tone_level=0.0;
-int sample_rate=48000;
int filter_board=ALEX;
//int pa=PA_ENABLED;
//int apollo_tuner=0;
int updates_per_second=10;
-int display_panadapter=1;
int panadapter_high=-40;
int panadapter_low=-140;
double display_average_time=120.0;
-int display_waterfall=1;
int waterfall_high=-100;
int waterfall_low=-150;
int waterfall_automatic=1;
int display_sliders=1;
-int display_toolbar=1;
-int toolbar_dialog_buttons=1;
-double volume=0.2;
+//double volume=0.2;
double mic_gain=0.0;
int binaural=0;
-int rx_dither=0;
-int rx_random=0;
-int rx_preamp=0;
-
int mic_linein=0;
int linein_gain=16; // 0..31
int mic_boost=0;
int mic_ptt_enabled=0;
int mic_ptt_tip_bias_ring=0;
-int agc=AGC_MEDIUM;
-double agc_gain=80.0;
-double agc_slope=35.0;
-double agc_hang_threshold=0.0;
-
-int nr_none=1;
-int nr=0;
-int nr2=0;
-int nb=0;
-int nb2=0;
-int anf=0;
-int snb=0;
-
-int nr_agc=0; // 0=pre AGC 1=post AGC
-int nr2_gain_method=2; // 0=Linear 1=Log 2=gamma
-int nr2_npe_method=0; // 0=OSMS 1=MMSE
-int nr2_ae=1; // 0=disable 1=enable
-
double tune_drive=10;
double drive=50;
int tune_drive_level=0;
int receivers=RECEIVERS;
-int active_receiver=0;
-
-int adc[2]={0,1};
int locked=0;
-int step=100;
+long long step=100;
-int rit=0;
+//int rit=0;
int rit_increment=10;
int lt2208Dither = 0;
int supply_volts;
int mox;
int tune;
+int memory_tune=0;
+int full_tune=0;
+
+//long long displayFrequency=14250000;
+//long long ddsFrequency=14250000;
+//long long ddsOffset=0;
-long long displayFrequency=14250000;
-long long ddsFrequency=14250000;
-long long ddsOffset=0;
+long long frequencyB=14250000;
+int modeB=modeUSB;
+int filterB=5;
+
+int split=0;
unsigned char OCtune=0;
int OCfull_tune_time=2800; // ms
int eer_pwm_min=100;
int eer_pwm_max=800;
-int tx_filter_low=200;
-int tx_filter_high=3100;
+int tx_filter_low=150;
+int tx_filter_high=2850;
#ifdef FREEDV
char freedv_tx_text_data[64];
#endif
-static int pre_tune_mode;
-
-int ctun=0;
+static int pre_tune_filter_low;
+static int pre_tune_filter_high;
int enable_tx_equalizer=0;
int tx_equalizer[4]={0,0,0,0};
int deviation=2500;
int pre_emphasize=0;
+int vox_setting=0;
int vox_enabled=0;
double vox_threshold=0.001;
double vox_gain=10.0;
double i_rotate[2]={1.0,1.0};
double q_rotate[2]={0.0,0.0};
-void init_radio() {
+void reconfigure_radio() {
+ int i;
+ int y;
+ int rx_height=display_height-VFO_HEIGHT-TOOLBAR_HEIGHT;
+ if(display_sliders) {
+ rx_height-=SLIDERS_HEIGHT;
+ }
+
+ y=VFO_HEIGHT;
+ for(i=0;i<receivers;i++) {
+ reconfigure_receiver(receiver[i],rx_height/receivers);
+ gtk_fixed_move(GTK_FIXED(fixed),receiver[i]->panel,0,y);
+ y+=rx_height/receivers;
+ }
+
+ if(display_sliders) {
+ if(sliders==NULL) {
+ sliders = sliders_init(display_width,SLIDERS_HEIGHT);
+ gtk_fixed_put(GTK_FIXED(fixed),sliders,0,y);
+ } else {
+ gtk_fixed_move(GTK_FIXED(fixed),sliders,0,y);
+ }
+ gtk_widget_show_all(sliders);
+ // force change of sliders for mic or linein
+ g_idle_add(linein_changed,NULL);
+ } else {
+ if(sliders!=NULL) {
+ gtk_container_remove(GTK_CONTAINER(fixed),sliders);
+ sliders=NULL;
+ }
+ }
+
+ reconfigure_transmitter(transmitter,rx_height);
+
+}
+
+static gboolean save_cb(gpointer data) {
+ radioSaveState();
+ return TRUE;
+}
+
+static gboolean minimize_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ gtk_window_iconify(GTK_WINDOW(top_window));
+ return TRUE;
+}
+
+static gboolean menu_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ new_menu(top_window);
+ return TRUE;
+}
+
+void start_radio() {
+ int i;
+ int x;
+ int y;
+fprintf(stderr,"start_radio: selected radio=%p device=%d\n",radio,radio->device);
+ gdk_window_set_cursor(gtk_widget_get_window(top_window),gdk_cursor_new(GDK_WATCH));
+
int rc;
rc=sem_init(&property_sem, 0, 0);
if(rc!=0) {
- fprintf(stderr,"init_radio: sem_init failed for property_sem: %d\n", rc);
+ fprintf(stderr,"start_radio: sem_init failed for property_sem: %d\n", rc);
exit(-1);
}
sem_post(&property_sem);
+
+ status_text("starting radio ...");
+ protocol=radio->protocol;
+ device=radio->device;
+
+ switch(radio->protocol) {
+ case ORIGINAL_PROTOCOL:
+ case NEW_PROTOCOL:
+ switch(radio->device) {
+#ifdef USBOZY
+ case DEVICE_OZY:
+ sprintf(property_path,"ozy.props");
+ break;
+#endif
+ default:
+ sprintf(property_path,"%02X-%02X-%02X-%02X-%02X-%02X.props",
+ radio->info.network.mac_address[0],
+ radio->info.network.mac_address[1],
+ radio->info.network.mac_address[2],
+ radio->info.network.mac_address[3],
+ radio->info.network.mac_address[4],
+ radio->info.network.mac_address[5]);
+ break;
+ }
+ break;
+#ifdef LIMESDR
+ case LIMESDR_PROTOCOL:
+ sprintf(property_path,"limesdr.props");
+ break;
+#endif
+ }
+
+ radioRestoreState();
+
+ y=0;
+
+ fixed=gtk_fixed_new();
+ gtk_container_remove(GTK_CONTAINER(top_window),grid);
+ gtk_container_add(GTK_CONTAINER(top_window), fixed);
+
+fprintf(stderr,"radio: vfo_init\n");
+ vfo_panel = vfo_init(VFO_WIDTH,VFO_HEIGHT,top_window);
+ gtk_fixed_put(GTK_FIXED(fixed),vfo_panel,0,y);
+
+fprintf(stderr,"radio: meter_init\n");
+ meter = meter_init(METER_WIDTH,METER_HEIGHT,top_window);
+ gtk_fixed_put(GTK_FIXED(fixed),meter,VFO_WIDTH,y);
+
+
+ GtkWidget *minimize_b=gtk_button_new_with_label("Hide");
+ gtk_widget_override_font(minimize_b, pango_font_description_from_string("FreeMono Bold 10"));
+ gtk_widget_set_size_request (minimize_b, MENU_WIDTH, MENU_HEIGHT);
+ g_signal_connect (minimize_b, "button-press-event", G_CALLBACK(minimize_cb), NULL) ;
+ gtk_fixed_put(GTK_FIXED(fixed),minimize_b,VFO_WIDTH+METER_WIDTH,y);
+ y+=MENU_HEIGHT;
+
+ GtkWidget *menu_b=gtk_button_new_with_label("Menu");
+ gtk_widget_override_font(menu_b, pango_font_description_from_string("FreeMono Bold 10"));
+ gtk_widget_set_size_request (menu_b, MENU_WIDTH, MENU_HEIGHT);
+ g_signal_connect (menu_b, "button-press-event", G_CALLBACK(menu_cb), NULL) ;
+ gtk_fixed_put(GTK_FIXED(fixed),menu_b,VFO_WIDTH+METER_WIDTH,y);
+ y+=MENU_HEIGHT;
+
+
+ int rx_height=display_height-VFO_HEIGHT-TOOLBAR_HEIGHT;
+ if(display_sliders) {
+ rx_height-=SLIDERS_HEIGHT;
+ }
+ int tx_height=rx_height;
+ rx_height=rx_height/receivers;
+
+
+fprintf(stderr,"Create %d receivers: height=%d\n",receivers,rx_height);
+ for(i=0;i<MAX_RECEIVERS;i++) {
+ receiver[i]=create_receiver(i, buffer_size, fft_size, display_width, updates_per_second, display_width, rx_height);
+ g_object_ref((gpointer)receiver[i]->panel);
+ if(i<receivers) {
+ gtk_fixed_put(GTK_FIXED(fixed),receiver[i]->panel,0,y);
+fprintf(stderr,"receiver %d: height=%d y=%d\n",receiver[i]->id,rx_height,y);
+ set_displaying(receiver[i],1);
+ y+=rx_height;
+ } else {
+ set_displaying(receiver[i],0);
+ }
+ }
+ active_receiver=receiver[0];
+
+ fprintf(stderr,"Create transmitter\n");
+ transmitter=create_transmitter(CHANNEL_TX, buffer_size, fft_size, updates_per_second, display_width, tx_height);
+ g_object_ref((gpointer)transmitter->panel);
+
+ switch(radio->protocol) {
+ case ORIGINAL_PROTOCOL:
+ old_protocol_init(0,display_width,receiver[0]->sample_rate);
+ break;
+ case NEW_PROTOCOL:
+ new_protocol_init(display_width);
+ break;
+#ifdef LIMESDR
+ case LIMESDR_PROTOCOL:
+ lime_protocol_init(0,display_width);
+ break;
+#endif
+ }
+
+#ifdef GPIO
+ if(gpio_init()<0) {
+ fprintf(stderr,"GPIO failed to initialize\n");
+ }
+#ifdef LOCALCW
+ // init local keyer if enabled
+ else if (cw_keyer_internal == 0)
+ keyer_update();
+#endif
+#endif
+
+#ifdef I2C
+ i2c_init();
+#endif
+
+ if(display_sliders) {
+fprintf(stderr,"create sliders\n");
+ sliders = sliders_init(display_width,SLIDERS_HEIGHT);
+ gtk_fixed_put(GTK_FIXED(fixed),sliders,0,y);
+ y+=SLIDERS_HEIGHT;
+ }
+
+ toolbar = toolbar_init(display_width,TOOLBAR_HEIGHT,top_window);
+ gtk_fixed_put(GTK_FIXED(fixed),toolbar,0,y);
+ y+=TOOLBAR_HEIGHT;
+
+ gtk_widget_show_all (fixed);
+
+ // force change of sliders for mic or linein
+ g_idle_add(linein_changed,NULL);
+
+ // save every 30 seconds
+fprintf(stderr,"start save timer\n");
+ save_timer_id=gdk_threads_add_timeout(30000, save_cb, NULL);
+
+#ifdef PSK
+ if(active_receiver->mode==modePSK) {
+ show_psk();
+ } else {
+ show_waterfall();
+ }
+#endif
+
+ launch_rigctl();
+
+ calcDriveLevel();
+ calcTuneDriveLevel();
+
+ if(protocol==NEW_PROTOCOL) {
+ schedule_high_priority();
+ }
+
+ g_idle_add(vfo_update,(gpointer)NULL);
+
+fprintf(stderr,"set cursor\n");
+ gdk_window_set_cursor(gtk_widget_get_window(top_window),gdk_cursor_new(GDK_ARROW));
+
+for(i=0;i<MAX_VFOS;i++) {
+ fprintf(stderr,"start_radio: vfo %d band=%d bandstack=%d frequency=%lld mode=%d filter=%d rit=%lld lo=%%ld offset=%lld\n",
+ i,
+ vfo[i].band,
+ vfo[i].bandstack,
+ vfo[i].frequency,
+ vfo[i].mode,
+ vfo[i].filter,
+ vfo[i].rit,
+ vfo[i].lo,
+ vfo[i].offset);
}
+}
+
-void setSampleRate(int rate) {
- sample_rate=rate;
+void radio_change_receivers(int r) {
+ switch(r) {
+ case 1:
+ if(receivers==2) {
+ set_displaying(receiver[1],0);
+ gtk_container_remove(GTK_CONTAINER(fixed),receiver[1]->panel);
+ }
+ receivers=1;
+ break;
+ case 2:
+ gtk_fixed_put(GTK_FIXED(fixed),receiver[1]->panel,0,0);
+ set_displaying(receiver[1],1);
+ receivers=2;
+ break;
+ }
+ reconfigure_radio();
+ active_receiver=receiver[0];
}
-int getSampleRate() {
- return sample_rate;
+void radio_change_sample_rate(int rate) {
+ int i;
+ switch(protocol) {
+ case ORIGINAL_PROTOCOL:
+ old_protocol_stop();
+ for(i=0;i<receivers;i++) {
+ receiver_change_sample_rate(receiver[i],rate);
+ }
+ old_protocol_set_mic_sample_rate(rate);
+ old_protocol_run();
+ break;
+#ifdef LIMESDR
+ case LIMESDR_PROTOCOL:
+ break;
+#endif
+ }
}
static void rxtx(int state) {
+ int i;
+ int y=VFO_HEIGHT;
+
if(state) {
// switch to tx
- SetChannelState(CHANNEL_RX0,0,1);
- if(protocol==NEW_PROTOCOL) {
- schedule_high_priority(3);
+ for(i=0;i<receivers;i++) {
+ SetChannelState(receiver[i]->id,0,i==(receivers-1));
+ set_displaying(receiver[i],0);
+ if(protocol==NEW_PROTOCOL) {
+ schedule_high_priority();
+ }
+ gtk_container_remove(GTK_CONTAINER(fixed),receiver[i]->panel);
}
- SetChannelState(CHANNEL_TX,1,0);
+ gtk_fixed_put(GTK_FIXED(fixed),transmitter->panel,0,y);
+ SetChannelState(transmitter->id,1,0);
+ tx_set_displaying(transmitter,1);
#ifdef FREEDV
- if(mode==modeFREEDV) {
+ if(active_receiver->mode==modeFREEDV) {
freedv_reset_tx_text_index();
}
#endif
} else {
- SetChannelState(CHANNEL_TX,0,1);
+ SetChannelState(transmitter->id,0,1);
if(protocol==NEW_PROTOCOL) {
- schedule_high_priority(3);
+ schedule_high_priority();
+ }
+ tx_set_displaying(transmitter,0);
+ gtk_container_remove(GTK_CONTAINER(fixed),transmitter->panel);
+ int rx_height=display_height-VFO_HEIGHT-TOOLBAR_HEIGHT;
+ if(display_sliders) {
+ rx_height-=SLIDERS_HEIGHT;
+ }
+ for(i=0;i<receivers;i++) {
+ SetChannelState(receiver[i]->id,1,0);
+ set_displaying(receiver[i],1);
+ gtk_fixed_put(GTK_FIXED(fixed),receiver[i]->panel,0,y);
+ y+=(rx_height/receivers);
}
- SetChannelState(CHANNEL_RX0,1,0);
}
+
+ gtk_widget_show_all(fixed);
+ g_idle_add(linein_changed,NULL);
}
void setMox(int state) {
}
void setTune(int state) {
+ int i;
+
if(tune!=state) {
tune=state;
if(vox_enabled && vox) {
vox_cancel();
}
if(tune) {
- if(OCmemory_tune_time!=0) {
- struct timeval te;
- gettimeofday(&te,NULL);
- tune_timeout=(te.tv_sec*1000LL+te.tv_usec/1000)+(long long)OCmemory_tune_time;
+ if(full_tune) {
+ if(OCfull_tune_time!=0) {
+ struct timeval te;
+ gettimeofday(&te,NULL);
+ tune_timeout=(te.tv_sec*1000LL+te.tv_usec/1000)+(long long)OCfull_tune_time;
+ }
+ }
+ if(memory_tune) {
+ if(OCmemory_tune_time!=0) {
+ struct timeval te;
+ gettimeofday(&te,NULL);
+ tune_timeout=(te.tv_sec*1000LL+te.tv_usec/1000)+(long long)OCmemory_tune_time;
+ }
}
}
if(protocol==NEW_PROTOCOL) {
- schedule_high_priority(4);
+ schedule_high_priority();
//schedule_general();
}
if(tune) {
- SetChannelState(CHANNEL_RX0,0,1);
- pre_tune_mode = mode;
- if(mode==modeCWL) {
- setMode(modeLSB);
- } else if(mode==modeCWU) {
- setMode(modeUSB);
+ for(i=0;i<receivers;i++) {
+ SetChannelState(receiver[i]->id,0,i==(receivers-1));
+ set_displaying(receiver[i],0);
+ if(protocol==NEW_PROTOCOL) {
+ schedule_high_priority();
+ }
}
- SetTXAPostGenMode(CHANNEL_TX,0);
- if(mode==modeLSB || mode==modeCWL || mode==modeDIGL) {
- SetTXAPostGenToneFreq(CHANNEL_TX,-(double)cw_keyer_sidetone_frequency);
- } else {
- SetTXAPostGenToneFreq(CHANNEL_TX,(double)cw_keyer_sidetone_frequency);
+
+ int mode=vfo[VFO_A].mode;;
+ if(split) {
+ mode=vfo[VFO_B].mode;
}
- SetTXAPostGenToneMag(CHANNEL_TX,0.99999);
- SetTXAPostGenRun(CHANNEL_TX,1);
- SetChannelState(CHANNEL_TX,1,0);
- } else {
- SetChannelState(CHANNEL_TX,0,1);
- SetTXAPostGenRun(CHANNEL_TX,0);
- if(pre_tune_mode==modeCWL || pre_tune_mode==modeCWU) {
- setMode(pre_tune_mode);
+ double freq=(double)cw_keyer_sidetone_frequency;
+
+ pre_tune_filter_low=transmitter->filter_low;
+ pre_tune_filter_high=transmitter->filter_high;
+
+ switch(mode) {
+ case modeUSB:
+ case modeCWU:
+ case modeDIGU:
+ SetTXAPostGenToneFreq(transmitter->id,(double)cw_keyer_sidetone_frequency);
+ transmitter->filter_low=cw_keyer_sidetone_frequency-100;
+ transmitter->filter_high=cw_keyer_sidetone_frequency+100;
+ freq=(double)(cw_keyer_sidetone_frequency+100);
+ break;
+ case modeLSB:
+ case modeCWL:
+ case modeDIGL:
+ SetTXAPostGenToneFreq(transmitter->id,-(double)cw_keyer_sidetone_frequency);
+ transmitter->filter_low=-cw_keyer_sidetone_frequency-100;
+ transmitter->filter_high=-cw_keyer_sidetone_frequency+100;
+ freq=(double)(-cw_keyer_sidetone_frequency-100);
+ break;
+ case modeDSB:
+ SetTXAPostGenToneFreq(transmitter->id,(double)cw_keyer_sidetone_frequency);
+ transmitter->filter_low=cw_keyer_sidetone_frequency-100;
+ transmitter->filter_high=cw_keyer_sidetone_frequency+100;
+ freq=(double)(cw_keyer_sidetone_frequency+100);
+ break;
+ case modeAM:
+ case modeSAM:
+ case modeFMN:
+ SetTXAPostGenToneFreq(transmitter->id,(double)cw_keyer_sidetone_frequency);
+ transmitter->filter_low=cw_keyer_sidetone_frequency-100;
+ transmitter->filter_high=cw_keyer_sidetone_frequency+100;
+ freq=(double)(cw_keyer_sidetone_frequency+100);
+ break;
}
- SetChannelState(CHANNEL_RX0,1,0);
+
+ SetTXABandpassFreqs(transmitter->id,transmitter->filter_low,transmitter->filter_high);
+
+
+ SetTXAMode(transmitter->id,modeDIGU);
+ SetTXAPostGenMode(transmitter->id,0);
+ SetTXAPostGenToneMag(transmitter->id,0.99999);
+ SetTXAPostGenRun(transmitter->id,1);
+ } else {
+ SetTXAPostGenRun(transmitter->id,0);
+ SetTXAMode(transmitter->id,transmitter->mode);
+ transmitter->filter_low=pre_tune_filter_low;
+ transmitter->filter_high=pre_tune_filter_high;
+ SetTXABandpassFreqs(transmitter->id,transmitter->filter_low,transmitter->filter_high);
}
+ rxtx(tune);
}
}
void setFrequency(long long f) {
BAND *band=band_get_current_band();
BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
+ int v=active_receiver->id;
switch(protocol) {
case NEW_PROTOCOL:
case ORIGINAL_PROTOCOL:
- if(ctun) {
- long long minf=entry->frequencyA-(long long)(sample_rate/2);
- long long maxf=entry->frequencyA+(long long)(sample_rate/2);
+ if(vfo[v].ctun) {
+ long long minf=vfo[v].frequency-(long long)(active_receiver->sample_rate/2);
+ long long maxf=vfo[v].frequency+(long long)(active_receiver->sample_rate/2);
if(f<minf) f=minf;
if(f>maxf) f=maxf;
- ddsOffset=f-entry->frequencyA;
- wdsp_set_offset(ddsOffset);
+ vfo[v].offset=f-vfo[v].frequency;
+ set_offset(active_receiver,vfo[v].offset);
return;
} else {
- entry->frequencyA=f;
+ //entry->frequency=f;
+ vfo[v].frequency=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);
+ long long minf=entry->frequency-(long long)(active_receiver->sample_rate/2);
+ long long maxf=entry->frequency+(long long)(active_receiver->sample_rate/2);
if(f<minf) f=minf;
if(f>maxf) f=maxf;
- ddsOffset=f-entry->frequencyA;
+ ddsOffset=f-entry->frequency;
wdsp_set_offset(ddsOffset);
return;
}
#endif
}
- displayFrequency=f;
- ddsFrequency=f;
- if(band->frequencyLO!=0LL) {
- ddsFrequency=f-band->frequencyLO;
- }
switch(protocol) {
case NEW_PROTOCOL:
- schedule_high_priority(5);
+ schedule_high_priority();
break;
case ORIGINAL_PROTOCOL:
schedule_frequency_changed();
}
long long getFrequency() {
- return ddsFrequency;
+ return vfo[active_receiver->id].frequency;
}
double getDrive() {
static int calcLevel(double d) {
int level=0;
- BAND *band=band_get_current_band();
+ int v=VFO_A;
+ if(split) v=VFO_B;
+
+ BAND *band=band_get_band(vfo[v].band);
double target_dbm = 10.0 * log10(d * 1000.0);
double gbb=band->pa_calibration;
target_dbm-=gbb;
double target_volts = sqrt(pow(10, target_dbm * 0.1) * 0.05);
double volts=min((target_volts / 0.8), 1.0);
- double v=volts*(1.0/0.98);
+ double actual_volts=volts*(1.0/0.98);
- if(v<0.0) {
- v=0.0;
- } else if(v>1.0) {
- v=1.0;
+ if(actual_volts<0.0) {
+ actual_volts=0.0;
+ } else if(actual_volts>1.0) {
+ actual_volts=1.0;
}
- level=(int)(v*255.0);
+ level=(int)(actual_volts*255.0);
return level;
}
void calcDriveLevel() {
drive_level=calcLevel(drive);
if(mox && protocol==NEW_PROTOCOL) {
- schedule_high_priority(6);
+ schedule_high_priority();
}
}
void calcTuneDriveLevel() {
tune_drive_level=calcLevel(tune_drive);
if(tune && protocol==NEW_PROTOCOL) {
- schedule_high_priority(7);
+ schedule_high_priority();
}
}
}
void set_attenuation(int value) {
- //attenuation=value;
switch(protocol) {
case NEW_PROTOCOL:
- schedule_high_priority(8);
+ schedule_high_priority();
break;
#ifdef LIMESDR
case LIMESDR_PROTOCOL:
}
int get_attenuation() {
- return attenuation;
+ return active_receiver->attenuation;
}
void set_alex_rx_antenna(int v) {
- //alex_rx_antenna=v;
- if(protocol==NEW_PROTOCOL) {
- schedule_high_priority(1);
+ if(active_receiver->id==0) {
+ active_receiver->alex_antenna=v;
+ if(protocol==NEW_PROTOCOL) {
+ schedule_high_priority();
+ }
}
#ifdef LIMESDR
if(protocol==LIMESDR_PROTOCOL) {
}
void set_alex_tx_antenna(int v) {
- //alex_tx_antenna=v;
+ transmitter->alex_antenna=v;
if(protocol==NEW_PROTOCOL) {
- schedule_high_priority(2);
+ schedule_high_priority();
}
}
void set_alex_attenuation(int v) {
- //alex_attenuation=v;
- if(protocol==NEW_PROTOCOL) {
- schedule_high_priority(0);
+ if(active_receiver->id==0) {
+ active_receiver->alex_attenuation=v;
+ if(protocol==NEW_PROTOCOL) {
+ schedule_high_priority();
+ }
}
}
sem_wait(&property_sem);
loadProperties(property_path);
+ value=getProperty("buffer_size");
+ if(value) buffer_size=atoi(value);
+ value=getProperty("fft_size");
+ if(value) fft_size=atoi(value);
value=getProperty("atlas_penelope");
if(value) atlas_penelope=atoi(value);
value=getProperty("tx_out_of_band");
if(value) tx_out_of_band=atoi(value);
- value=getProperty("sample_rate");
- if(value) sample_rate=atoi(value);
value=getProperty("filter_board");
if(value) filter_board=atoi(value);
/*
*/
value=getProperty("updates_per_second");
if(value) updates_per_second=atoi(value);
- value=getProperty("display_panadapter");
- if(value) display_panadapter=atoi(value);
value=getProperty("display_filled");
if(value) display_filled=atoi(value);
value=getProperty("display_detector_mode");
if(value) panadapter_high=atoi(value);
value=getProperty("panadapter_low");
if(value) panadapter_low=atoi(value);
- value=getProperty("display_waterfall");
- if(value) display_waterfall=atoi(value);
value=getProperty("display_sliders");
if(value) display_sliders=atoi(value);
+/*
value=getProperty("display_toolbar");
if(value) display_toolbar=atoi(value);
- value=getProperty("toolbar_dialog_buttons");
- if(value) toolbar_dialog_buttons=atoi(value);
+*/
value=getProperty("waterfall_high");
if(value) waterfall_high=atoi(value);
value=getProperty("waterfall_low");
if(value) waterfall_low=atoi(value);
value=getProperty("waterfall_automatic");
if(value) waterfall_automatic=atoi(value);
- value=getProperty("volume");
- if(value) volume=atof(value);
+// value=getProperty("volume");
+// if(value) volume=atof(value);
value=getProperty("drive");
if(value) drive=atof(value);
value=getProperty("tune_drive");
if(value) mic_bias_enabled=atof(value);
value=getProperty("mic_ptt_tip_bias_ring");
if(value) mic_ptt_tip_bias_ring=atof(value);
- value=getProperty("nr_none");
- if(value) nr_none=atoi(value);
- value=getProperty("nr");
- if(value) nr=atoi(value);
- value=getProperty("nr2");
- if(value) nr2=atoi(value);
- value=getProperty("nb");
- if(value) nb=atoi(value);
- value=getProperty("nb2");
- if(value) nb2=atoi(value);
- value=getProperty("anf");
- if(value) anf=atoi(value);
- value=getProperty("snb");
- if(value) snb=atoi(value);
- value=getProperty("nr_agc");
- if(value) nr_agc=atoi(value);
- value=getProperty("nr2_gain_method");
- if(value) nr2_gain_method=atoi(value);
- value=getProperty("nr2_npe_method");
- if(value) nr2_npe_method=atoi(value);
- value=getProperty("nr2_ae");
- if(value) nr2_ae=atoi(value);
- value=getProperty("agc");
- if(value) agc=atoi(value);
- value=getProperty("agc_gain");
- if(value) agc_gain=atof(value);
- value=getProperty("agc_slope");
- if(value) agc_slope=atof(value);
- value=getProperty("agc_hang_threshold");
- if(value) agc_hang_threshold=atof(value);
+
+ value=getProperty("tx_filter_low");
+ if(value) tx_filter_low=atoi(value);
+ value=getProperty("tx_filter_high");
+ if(value) tx_filter_high=atoi(value);
+
value=getProperty("step");
- if(value) step=atoi(value);
+ if(value) step=atoll(value);
value=getProperty("cw_keys_reversed");
if(value) cw_keys_reversed=atoi(value);
value=getProperty("cw_keyer_speed");
if(value) OCfull_tune_time=atoi(value);
value=getProperty("OCmemory_tune_time");
if(value) OCmemory_tune_time=atoi(value);
- value=getProperty("attenuation");
- if(value) attenuation=atoi(value);
- value=getProperty("rx_dither");
- if(value) rx_dither=atoi(value);
- value=getProperty("rx_random");
- if(value) rx_random=atoi(value);
- value=getProperty("rx_preamp");
- if(value) rx_preamp=atoi(value);
#ifdef FREEDV
strcpy(freedv_tx_text_data,"NO TEXT DATA");
value=getProperty("freedv_tx_text_data");
if(value) smeter=atoi(value);
value=getProperty("alc");
if(value) alc=atoi(value);
+#ifdef OLD_AUDIO
value=getProperty("local_audio");
if(value) local_audio=atoi(value);
value=getProperty("n_selected_output_device");
if(value) n_selected_output_device=atoi(value);
+#endif
value=getProperty("local_microphone");
if(value) local_microphone=atoi(value);
- value=getProperty("n_selected_input_device");
- if(value) n_selected_input_device=atoi(value);
+// value=getProperty("n_selected_input_device");
+// if(value) n_selected_input_device=atoi(value);
value=getProperty("enable_tx_equalizer");
if(value) enable_tx_equalizer=atoi(value);
value=getProperty("tx_equalizer.0");
value=getProperty("binaural");
if(value) binaural=atoi(value);
+ value=getProperty("frequencyB");
+ if(value) frequencyB=atol(value);
+
+ value=getProperty("modeB");
+ if(value) modeB=atoi(value);
+
+ value=getProperty("filterB");
+ if(value) filterB=atoi(value);
+
+#ifdef GPIO
+ value=getProperty("e1_encoder_action");
+ if(value) e1_encoder_action=atoi(value);
+ value=getProperty("e2_encoder_action");
+ if(value) e2_encoder_action=atoi(value);
+ value=getProperty("e3_encoder_action");
+ if(value) e3_encoder_action=atoi(value);
+#endif
+
+ value=getProperty("receivers");
+ if(value) receivers=atoi(value);
+
+ filterRestoreState();
bandRestoreState();
+ memRestoreState();
+ vfo_restore_state();
sem_post(&property_sem);
}
void radioSaveState() {
+ int i;
char value[80];
sem_wait(&property_sem);
+ sprintf(value,"%d",buffer_size);
+ setProperty("buffer_size",value);
+ sprintf(value,"%d",fft_size);
+ setProperty("fft_size",value);
sprintf(value,"%d",atlas_penelope);
setProperty("atlas_penelope",value);
- sprintf(value,"%d",sample_rate);
- setProperty("sample_rate",value);
sprintf(value,"%d",filter_board);
setProperty("filter_board",value);
+ sprintf(value,"%d",tx_out_of_band);
+ setProperty("tx_out_of_band",value);
/*
sprintf(value,"%d",apollo_tuner);
setProperty("apollo_tuner",value);
*/
sprintf(value,"%d",updates_per_second);
setProperty("updates_per_second",value);
- sprintf(value,"%d",display_panadapter);
- setProperty("display_panadapter",value);
sprintf(value,"%d",display_filled);
setProperty("display_filled",value);
sprintf(value,"%d",display_detector_mode);
setProperty("panadapter_high",value);
sprintf(value,"%d",panadapter_low);
setProperty("panadapter_low",value);
- sprintf(value,"%d",display_waterfall);
- setProperty("display_waterfall",value);
sprintf(value,"%d",display_sliders);
setProperty("display_sliders",value);
+/*
sprintf(value,"%d",display_toolbar);
setProperty("display_toolbar",value);
- sprintf(value,"%d",toolbar_dialog_buttons);
- setProperty("toolbar_dialog_buttons",value);
+*/
sprintf(value,"%d",waterfall_high);
setProperty("waterfall_high",value);
sprintf(value,"%d",waterfall_low);
setProperty("waterfall_low",value);
sprintf(value,"%d",waterfall_automatic);
setProperty("waterfall_automatic",value);
- sprintf(value,"%f",volume);
- setProperty("volume",value);
+// sprintf(value,"%f",volume);
+// setProperty("volume",value);
sprintf(value,"%f",mic_gain);
setProperty("mic_gain",value);
sprintf(value,"%f",drive);
setProperty("mic_bias_enabled",value);
sprintf(value,"%d",mic_ptt_tip_bias_ring);
setProperty("mic_ptt_tip_bias_ring",value);
- sprintf(value,"%d",nr_none);
- setProperty("nr_none",value);
- sprintf(value,"%d",nr);
- setProperty("nr",value);
- sprintf(value,"%d",nr2);
- setProperty("nr2",value);
- sprintf(value,"%d",nb);
- setProperty("nb",value);
- sprintf(value,"%d",nb2);
- setProperty("nb2",value);
- sprintf(value,"%d",anf);
- setProperty("anf",value);
- sprintf(value,"%d",snb);
- setProperty("snb",value);
- sprintf(value,"%d",nr_agc);
- setProperty("nr_agc",value);
- sprintf(value,"%d",nr2_gain_method);
- setProperty("nr2_gain_method",value);
- sprintf(value,"%d",nr2_npe_method);
- setProperty("nr2_npe_method",value);
- sprintf(value,"%d",nr2_ae);
- setProperty("nr2_ae",value);
- sprintf(value,"%d",agc);
- setProperty("agc",value);
- sprintf(value,"%f",agc_gain);
- setProperty("agc_gain",value);
- sprintf(value,"%f",agc_slope);
- setProperty("agc_slope",value);
- sprintf(value,"%f",agc_hang_threshold);
- setProperty("agc_hang_threshold",value);
- sprintf(value,"%d",step);
+ sprintf(value,"%d",tx_filter_low);
+ setProperty("tx_filter_low",value);
+ sprintf(value,"%d",tx_filter_high);
+ setProperty("tx_filter_high",value);
+
+ sprintf(value,"%lld",step);
setProperty("step",value);
sprintf(value,"%d",cw_keys_reversed);
setProperty("cw_keys_reversed",value);
setProperty("OCfull_tune_time",value);
sprintf(value,"%d",OCmemory_tune_time);
setProperty("OCmemory_tune_time",value);
- sprintf(value,"%d",attenuation);
- setProperty("attenuation",value);
- sprintf(value,"%d",rx_dither);
- setProperty("rx_dither",value);
- sprintf(value,"%d",rx_random);
- 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);
setProperty("smeter",value);
sprintf(value,"%d",alc);
setProperty("alc",value);
+#ifdef OLD_AUDIO
sprintf(value,"%d",local_audio);
setProperty("local_audio",value);
sprintf(value,"%d",n_selected_output_device);
setProperty("n_selected_output_device",value);
+#endif
sprintf(value,"%d",local_microphone);
setProperty("local_microphone",value);
- sprintf(value,"%d",n_selected_input_device);
- setProperty("n_selected_input_device",value);
+// sprintf(value,"%d",n_selected_input_device);
+// setProperty("n_selected_input_device",value);
sprintf(value,"%d",enable_tx_equalizer);
setProperty("enable_tx_equalizer",value);
sprintf(value,"%d",binaural);
setProperty("binaural",value);
- bandSaveState();
+ sprintf(value,"%lld",frequencyB);
+ setProperty("frequencyB",value);
+ sprintf(value,"%d",modeB);
+ setProperty("modeB",value);
+ sprintf(value,"%d",filterB);
+ setProperty("filterB",value);
+
+#ifdef GPIO
+ sprintf(value,"%d",e1_encoder_action);
+ setProperty("e1_encoder_action",value);
+ sprintf(value,"%d",e2_encoder_action);
+ setProperty("e2_encoder_action",value);
+ sprintf(value,"%d",e3_encoder_action);
+ setProperty("e3_encoder_action",value);
+#endif
+
+ vfo_save_state();
+ sprintf(value,"%d",receivers);
+ setProperty("receivers",value);
+ for(i=0;i<receivers;i++) {
+ receiver_save_state(receiver[i]);
+ }
+ transmitter_save_state(transmitter);
+
+ filterSaveState();
+ bandSaveState();
+ memSaveState();
saveProperties(property_path);
sem_post(&property_sem);
}
-void calculate_display_average() {
+void calculate_display_average(RECEIVER *rx) {
double display_avb;
int display_average;
double t=0.001*display_average_time;
- display_avb = exp(-1.0 / ((double)updates_per_second * t));
- display_average = max(2, (int)min(60, (double)updates_per_second * t));
- SetDisplayAvBackmult(CHANNEL_RX0, 0, display_avb);
- SetDisplayNumAverage(CHANNEL_RX0, 0, display_average);
+ display_avb = exp(-1.0 / ((double)rx->fps * t));
+ display_average = max(2, (int)min(60, (double)rx->fps * t));
+ SetDisplayAvBackmult(rx->id, 0, display_avb);
+ SetDisplayNumAverage(rx->id, 0, display_average);
}
#define _RADIO_H
#include "discovered.h"
+#include "receiver.h"
+#include "transmitter.h"
#define NEW_MIC_IN 0x00
#define NEW_LINE_IN 0x01
#define ALEX 1
#define APOLLO 2
-// soecify how many receivers (only 1 or 2 for now)
-#define RECEIVERS 1
+// specify how many receivers (only 1 or 2 for now)
+#define MAX_RECEIVERS 2
+#define RECEIVERS 2
+
+extern RECEIVER *receiver[];
+extern RECEIVER *active_receiver;
+
+extern TRANSMITTER *transmitter;
/*
#define PA_DISABLED 0
#define KEYER_MODE_A 1
#define KEYER_MODE_B 2
-extern int rx_dither;
-extern int rx_random;
-extern int rx_preamp;
+extern int echo;
+
+#define MAX_BUFFER_SIZE 2048
+
+extern int buffer_size;
+extern int fft_size;
extern int atlas_penelope;
extern int atlas_clock_source_10mhz;
extern double tone_level;
-extern int sample_rate;
extern int filter_board;
extern int pa;
extern int apollo_tuner;
extern int display_sliders;
extern int display_toolbar;
-extern int toolbar_dialog_buttons;
-extern double volume;
extern double mic_gain;
extern int binaural;
-extern int agc;
-extern double agc_gain;
-extern double agc_slope;
-extern double agc_hang_threshold;
-
-extern int nr_none;
-extern int nr;
-extern int nr2;
-extern int nb;
-extern int nb2;
-extern int anf;
-extern int snb;
-
-extern int nr_agc;
-extern int nr2_gain_method;
-extern int nr2_npe_method;
-extern int nr2_ae;
extern int mic_linein;
extern int linein_gain;
extern int drive_level;
int receivers;
-int active_receiver;
int adc[2];
int locked;
-extern int step;
-extern int rit;
+extern long long step;
+//extern int rit;
extern int rit_increment;
extern int lt2208Dither;
extern int penelope_software_version;
extern int mox;
extern int tune;
+extern int memory_tune;
+extern int full_tune;
extern int ptt;
extern int dot;
extern int dash;
extern unsigned int AIN6;
extern int supply_volts;
-extern long long displayFrequency;
-extern long long ddsFrequency;
-extern long long ddsOffset;
+//extern long long displayFrequency;
+//extern long long ddsFrequency;
+//extern long long ddsOffset;
+
+extern long long frequencyB;
+extern int modeB;
+extern int filterB;
+
+extern int split;
extern unsigned char OCtune;
extern int OCfull_tune_time;
extern int smeter;
extern int alc;
-extern int local_audio;
-extern int local_microphone;
+//extern int local_audio;
+//extern int local_microphone;
extern int eer_pwm_min;
extern int eer_pwm_max;
extern int deviation;
extern int pre_emphasize;
+extern int vox_setting;
extern int vox_enabled;
extern double vox_threshold;
extern double vox_gain;
extern double i_rotate[2];
extern double q_rotate[2];
+extern void reconfigure_radio();
+extern void start_radio();
extern void init_radio();
-extern void setSampleRate(int rate);
-extern int getSampleRate();
+extern void radio_change_receivers(int r);
+extern void radio_change_sample_rate(int rate);
extern void setMox(int state);
extern int getMox();
extern void setTune(int state);
--- /dev/null
+/* Copyright (C)
+* 2015 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*/
+
+#include <gtk/gtk.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "new_menu.h"
+#include "radio_menu.h"
+#include "band.h"
+#include "filter.h"
+#include "radio.h"
+#include "receiver.h"
+
+static GtkWidget *parent_window=NULL;
+
+static GtkWidget *menu_b=NULL;
+
+static GtkWidget *dialog=NULL;
+
+static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ if(dialog!=NULL) {
+ gtk_widget_destroy(dialog);
+ dialog=NULL;
+ sub_menu=NULL;
+ }
+ return TRUE;
+}
+
+static void vfo_divisor_value_changed_cb(GtkWidget *widget, gpointer data) {
+ vfo_encoder_divisor=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
+}
+
+/*
+static void toolbar_dialog_buttons_cb(GtkWidget *widget, gpointer data) {
+ toolbar_dialog_buttons=toolbar_dialog_buttons==1?0:1;
+ update_toolbar_labels();
+}
+*/
+
+static void ptt_cb(GtkWidget *widget, gpointer data) {
+ mic_ptt_enabled=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+}
+
+static void ptt_ring_cb(GtkWidget *widget, gpointer data) {
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
+ mic_ptt_tip_bias_ring=0;
+ }
+}
+
+static void ptt_tip_cb(GtkWidget *widget, gpointer data) {
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
+ mic_ptt_tip_bias_ring=1;
+ }
+}
+
+static void bias_cb(GtkWidget *widget, gpointer data) {
+ mic_bias_enabled=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+}
+
+static void apollo_cb(GtkWidget *widget, gpointer data);
+
+static void alex_cb(GtkWidget *widget, gpointer data) {
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
+ if(filter_board==ALEX) {
+ filter_board=NONE;
+ } else if(filter_board==NONE) {
+ filter_board=ALEX;
+ } else if(filter_board==APOLLO) {
+ GtkWidget *w=(GtkWidget *)data;
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), FALSE);
+ filter_board=ALEX;
+ }
+
+ if(protocol==NEW_PROTOCOL) {
+ filter_board_changed();
+ }
+
+ if(filter_board==ALEX) {
+ BAND *band=band_get_current_band();
+ BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
+ setFrequency(entry->frequency);
+ //setMode(entry->mode);
+ set_mode(active_receiver,entry->mode);
+ FILTER* band_filters=filters[entry->mode];
+ FILTER* band_filter=&band_filters[entry->filter];
+ //setFilter(band_filter->low,band_filter->high);
+ set_filter(active_receiver,band_filter->low,band_filter->high);
+ if(active_receiver->id==0) {
+ set_alex_rx_antenna(band->alexRxAntenna);
+ set_alex_tx_antenna(band->alexTxAntenna);
+ set_alex_attenuation(band->alexAttenuation);
+ }
+ }
+ }
+}
+
+static void apollo_cb(GtkWidget *widget, gpointer data) {
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
+ if(filter_board==APOLLO) {
+ filter_board=NONE;
+ } else if(filter_board==NONE) {
+ filter_board=APOLLO;
+ } else if(filter_board==ALEX) {
+ GtkWidget *w=(GtkWidget *)data;
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), FALSE);
+ filter_board=APOLLO;
+ }
+ if(protocol==NEW_PROTOCOL) {
+ filter_board_changed();
+ }
+
+ if(filter_board==APOLLO) {
+ BAND *band=band_get_current_band();
+ BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
+ setFrequency(entry->frequency);
+ //setMode(entry->mode);
+ set_mode(active_receiver,entry->mode);
+ FILTER* band_filters=filters[entry->mode];
+ FILTER* band_filter=&band_filters[entry->filter];
+ //setFilter(band_filter->low,band_filter->high);
+ set_filter(active_receiver,band_filter->low,band_filter->high);
+ }
+ }
+}
+
+static void sample_rate_cb(GtkWidget *widget, gpointer data) {
+ radio_change_sample_rate((int)data);
+}
+
+static void receivers_cb(GtkWidget *widget, gpointer data) {
+ radio_change_receivers((int)data);
+}
+
+static void rit_cb(GtkWidget *widget,gpointer data) {
+ rit_increment=(int)data;
+}
+
+static void ck10mhz_cb(GtkWidget *widget, gpointer data) {
+ atlas_clock_source_10mhz = (int)data;
+}
+
+static void ck128mhz_cb(GtkWidget *widget, gpointer data) {
+ atlas_clock_source_128mhz=atlas_clock_source_128mhz==1?0:1;
+}
+
+static void micsource_cb(GtkWidget *widget, gpointer data) {
+ atlas_mic_source=atlas_mic_source==1?0:1;
+}
+
+static void penelopetx_cb(GtkWidget *widget, gpointer data) {
+ atlas_penelope=atlas_penelope==1?0:1;
+}
+
+void radio_menu(GtkWidget *parent) {
+ parent_window=parent;
+
+ dialog=gtk_dialog_new();
+ gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window));
+ gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE);
+
+ GdkRGBA color;
+ color.red = 1.0;
+ color.green = 1.0;
+ color.blue = 1.0;
+ color.alpha = 1.0;
+ gtk_widget_override_background_color(dialog,GTK_STATE_FLAG_NORMAL,&color);
+
+ GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+
+ GtkWidget *grid=gtk_grid_new();
+ gtk_grid_set_column_spacing (GTK_GRID(grid),10);
+ //gtk_grid_set_row_spacing (GTK_GRID(grid),10);
+ //gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
+ //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
+
+ GtkWidget *close_b=gtk_button_new_with_label("Close");
+ g_signal_connect (close_b, "button_press_event", G_CALLBACK(close_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1);
+
+ int x=0;
+
+ GtkWidget *receivers_label=gtk_label_new("Receivers: ");
+ gtk_grid_attach(GTK_GRID(grid),receivers_label,x,1,1,1);
+
+ GtkWidget *receivers_1=gtk_radio_button_new_with_label(NULL,"1");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (receivers_1), receivers==1);
+ gtk_grid_attach(GTK_GRID(grid),receivers_1,x,2,1,1);
+ g_signal_connect(receivers_1,"pressed",G_CALLBACK(receivers_cb),(gpointer *)1);
+
+ GtkWidget *receivers_2=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(receivers_1),"2");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (receivers_2), receivers==2);
+ gtk_grid_attach(GTK_GRID(grid),receivers_2,x,3,1,1);
+ g_signal_connect(receivers_2,"pressed",G_CALLBACK(receivers_cb),(gpointer *)2);
+
+ x++;
+
+ switch(protocol) {
+ case ORIGINAL_PROTOCOL:
+ {
+ GtkWidget *sample_rate_label=gtk_label_new("Sample Rate:");
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_label,x,1,1,1);
+
+ GtkWidget *sample_rate_48=gtk_radio_button_new_with_label(NULL,"48000");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_48), active_receiver->sample_rate==48000);
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_48,x,2,1,1);
+ g_signal_connect(sample_rate_48,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)48000);
+
+ GtkWidget *sample_rate_96=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_48),"96000");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_96), active_receiver->sample_rate==96000);
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_96,x,3,1,1);
+ g_signal_connect(sample_rate_96,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)96000);
+
+ GtkWidget *sample_rate_192=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_96),"192000");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_192), active_receiver->sample_rate==192000);
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_192,x,4,1,1);
+ g_signal_connect(sample_rate_192,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)192000);
+
+ GtkWidget *sample_rate_384=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_192),"384000");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_384), active_receiver->sample_rate==384000);
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_384,x,5,1,1);
+ g_signal_connect(sample_rate_384,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)384000);
+
+ if(protocol==NEW_PROTOCOL) {
+ GtkWidget *sample_rate_768=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_384),"768000");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_768), active_receiver->sample_rate==768000);
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_768,x,6,1,1);
+ 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");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_1536), active_receiver->sample_rate==1536000);
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_1536,x,7,1,1);
+ g_signal_connect(sample_rate_1536,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)1536000);
+
+ #ifdef GPIO
+ gtk_widget_set_sensitive(sample_rate_768,FALSE);
+ gtk_widget_set_sensitive(sample_rate_1536,FALSE);
+ #endif
+ }
+ x++;
+ }
+ break;
+
+#ifdef LIMESDR
+ case LIMESDR_PROTOCOL:
+ {
+ GtkWidget *sample_rate_label=gtk_label_new("Sample Rate:");
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_label,x,1,1,1);
+
+ GtkWidget *sample_rate_1M=gtk_radio_button_new_with_label(NULL,"1000000");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_1M), active_receiver->sample_rate==1000000);
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_1M,x,2,1,1);
+ g_signal_connect(sample_rate_1M,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)1000000);
+
+ GtkWidget *sample_rate_2M=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_1M),"2000000");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_2M), active_receiver->sample_rate==2000000);
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_2M,x,3,1,1);
+ g_signal_connect(sample_rate_2M,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)2000000);
+ x++;
+ }
+ break;
+#endif
+
+
+ }
+
+
+ if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL) {
+
+ if((protocol==NEW_PROTOCOL && device==NEW_DEVICE_ORION) ||
+ (protocol==NEW_PROTOCOL && device==NEW_DEVICE_ORION2) ||
+ (protocol==ORIGINAL_PROTOCOL && device==DEVICE_ORION) ||
+ (protocol==ORIGINAL_PROTOCOL && device==DEVICE_ORION2)) {
+
+ GtkWidget *ptt_ring_b=gtk_radio_button_new_with_label(NULL,"PTT On Ring, Mic and Bias on Tip");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_ring_b), mic_ptt_tip_bias_ring==0);
+ gtk_grid_attach(GTK_GRID(grid),ptt_ring_b,x,1,1,1);
+ g_signal_connect(ptt_ring_b,"toggled",G_CALLBACK(ptt_ring_cb),NULL);
+
+ GtkWidget *ptt_tip_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(ptt_ring_b),"PTT On Tip, Mic and Bias on Ring");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_tip_b), mic_ptt_tip_bias_ring==1);
+ gtk_grid_attach(GTK_GRID(grid),ptt_tip_b,x,2,1,1);
+ g_signal_connect(ptt_tip_b,"toggled",G_CALLBACK(ptt_tip_cb),NULL);
+
+ GtkWidget *ptt_b=gtk_check_button_new_with_label("PTT Enabled");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_b), mic_ptt_enabled);
+ gtk_grid_attach(GTK_GRID(grid),ptt_b,x,3,1,1);
+ g_signal_connect(ptt_b,"toggled",G_CALLBACK(ptt_cb),NULL);
+
+ GtkWidget *bias_b=gtk_check_button_new_with_label("BIAS Enabled");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bias_b), mic_bias_enabled);
+ gtk_grid_attach(GTK_GRID(grid),bias_b,x,4,1,1);
+ g_signal_connect(bias_b,"toggled",G_CALLBACK(bias_cb),NULL);
+
+ x++;
+ }
+
+ GtkWidget *alex_b=gtk_check_button_new_with_label("ALEX");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (alex_b), filter_board==ALEX);
+ gtk_grid_attach(GTK_GRID(grid),alex_b,x,1,1,1);
+
+ GtkWidget *apollo_b=gtk_check_button_new_with_label("APOLLO");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (apollo_b), filter_board==APOLLO);
+ gtk_grid_attach(GTK_GRID(grid),apollo_b,x,2,1,1);
+
+ g_signal_connect(alex_b,"toggled",G_CALLBACK(alex_cb),apollo_b);
+ g_signal_connect(apollo_b,"toggled",G_CALLBACK(apollo_cb),alex_b);
+
+ x++;
+ }
+
+
+ GtkWidget *rit_label=gtk_label_new("RIT step: ");
+ gtk_grid_attach(GTK_GRID(grid),rit_label,x,1,1,1);
+
+ GtkWidget *rit_1=gtk_radio_button_new_with_label(NULL,"1 Hz");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rit_1), rit_increment==1);
+ gtk_grid_attach(GTK_GRID(grid),rit_1,x,2,1,1);
+ g_signal_connect(rit_1,"pressed",G_CALLBACK(rit_cb),(gpointer *)1);
+
+ GtkWidget *rit_10=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(rit_1),"10");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rit_10), rit_increment==10);
+ gtk_grid_attach(GTK_GRID(grid),rit_10,x,3,1,1);
+ g_signal_connect(rit_10,"pressed",G_CALLBACK(rit_cb),(gpointer *)10);
+
+ GtkWidget *rit_100=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(rit_10),"100");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rit_100), rit_increment==100);
+ gtk_grid_attach(GTK_GRID(grid),rit_100,x,4,1,1);
+ g_signal_connect(rit_100,"pressed",G_CALLBACK(rit_cb),(gpointer *)100);
+
+ x++;
+
+ GtkWidget *vfo_divisor_label=gtk_label_new("VFO Encoder Divisor: ");
+ gtk_grid_attach(GTK_GRID(grid),vfo_divisor_label,x,1,1,1);
+
+ GtkWidget *vfo_divisor=gtk_spin_button_new_with_range(1.0,60.0,1.0);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(vfo_divisor),(double)vfo_encoder_divisor);
+ gtk_grid_attach(GTK_GRID(grid),vfo_divisor,x,2,1,1);
+ g_signal_connect(vfo_divisor,"value_changed",G_CALLBACK(vfo_divisor_value_changed_cb),NULL);
+
+ x++;
+
+#ifdef USBOZY
+ if (protocol==ORIGINAL_PROTOCOL && (device == DEVICE_OZY) || (device == DEVICE_METIS))
+#else
+ if (protocol==ORIGINAL_PROTOCOL && radio->device == DEVICE_METIS)
+#endif
+ {
+ GtkWidget *atlas_label=gtk_label_new("Atlas bus: ");
+ gtk_grid_attach(GTK_GRID(grid),atlas_label,x,1,1,1);
+
+ GtkWidget *ck10mhz_1=gtk_radio_button_new_with_label(NULL,"10MHz clock=Atlas");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ck10mhz_1), atlas_clock_source_10mhz==0);
+ gtk_grid_attach(GTK_GRID(grid),ck10mhz_1,x,2,1,1);
+ g_signal_connect(ck10mhz_1,"toggled",G_CALLBACK(ck10mhz_cb),(gpointer *)0);
+
+ GtkWidget *ck10mhz_2=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(ck10mhz_1),"10MHz clock=Penelope");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ck10mhz_2), atlas_clock_source_10mhz==1);
+ gtk_grid_attach(GTK_GRID(grid),ck10mhz_2,x,3,1,1);
+ g_signal_connect(ck10mhz_2,"toggled",G_CALLBACK(ck10mhz_cb),(gpointer *)1);
+
+ GtkWidget *ck10mhz_3=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(ck10mhz_2),"10MHz clock=Mercury");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ck10mhz_3), atlas_clock_source_10mhz==2);
+ gtk_grid_attach(GTK_GRID(grid),ck10mhz_3,x,4,1,1);
+ g_signal_connect(ck10mhz_3,"toggled",G_CALLBACK(ck10mhz_cb),(gpointer *)2);
+
+ GtkWidget *ck128_b=gtk_check_button_new_with_label("122.88MHz ck=Mercury");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ck128_b), atlas_clock_source_128mhz);
+ gtk_grid_attach(GTK_GRID(grid),ck128_b,x,5,1,1);
+ g_signal_connect(ck128_b,"toggled",G_CALLBACK(ck128mhz_cb),NULL);
+
+ GtkWidget *mic_src_b=gtk_check_button_new_with_label("Mic src=Penelope");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (mic_src_b), atlas_mic_source);
+ gtk_grid_attach(GTK_GRID(grid),mic_src_b,x,6,1,1);
+ g_signal_connect(mic_src_b,"toggled",G_CALLBACK(micsource_cb),NULL);
+
+ GtkWidget *pene_tx_b=gtk_check_button_new_with_label("Penelope TX");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pene_tx_b), atlas_penelope);
+ gtk_grid_attach(GTK_GRID(grid),pene_tx_b,x,7,1,1);
+ g_signal_connect(pene_tx_b,"toggled",G_CALLBACK(penelopetx_cb),NULL);
+ }
+
+ gtk_container_add(GTK_CONTAINER(content),grid);
+
+ sub_menu=dialog;
+
+ gtk_widget_show_all(dialog);
+
+}
+
--- /dev/null
+/* Copyright (C)
+* 2015 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*/
+
+extern void general_menu(GtkWidget *parent);
--- /dev/null
+/* Copyright (C)
+* 2017 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*/
+
+#include <gtk/gtk.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <wdsp.h>
+
+#include "agc.h"
+#include "band.h"
+#include "bandstack.h"
+#include "discovered.h"
+#include "filter.h"
+#include "main.h"
+#include "meter.h"
+#include "mode.h"
+#include "new_protocol.h"
+#include "old_protocol.h"
+#include "property.h"
+#include "radio.h"
+#include "receiver.h"
+#include "vfo.h"
+#include "meter.h"
+#include "rx_panadapter.h"
+#include "sliders.h"
+#include "waterfall.h"
+#ifdef FREEDV
+#include "freedv.h"
+#endif
+
+
+#define min(x,y) (x<y?x:y)
+#define max(x,y) (x<y?y:x)
+
+#ifdef FREEDV
+static int freedv_samples=0;
+static int freedv_resample=6; // convert from 48000 to 8000
+#endif
+#ifdef PSK
+static int psk_samples=0;
+static int psk_resample=6; // convert from 48000 to 8000
+#endif
+
+static gint last_x;
+static gboolean has_moved=FALSE;
+static gboolean pressed=FALSE;
+static gboolean making_active=FALSE;
+
+gboolean receiver_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ RECEIVER *rx=(RECEIVER *)data;
+ if(rx==active_receiver) {
+ int x=(int)event->x;
+ if (event->button == 1) {
+ last_x=(int)event->x;
+ has_moved=FALSE;
+ pressed=TRUE;
+ }
+ } else {
+ making_active=TRUE;
+ }
+ return TRUE;
+}
+
+gboolean receiver_button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ RECEIVER *rx=(RECEIVER *)data;
+ if(making_active) {
+ active_receiver=rx;
+ making_active=FALSE;
+ g_idle_add(vfo_update,NULL);
+ g_idle_add(active_receiver_changed,NULL);
+ } else {
+ int display_width=gtk_widget_get_allocated_width (rx->panadapter);
+ int display_height=gtk_widget_get_allocated_height (rx->panadapter);
+ if(pressed) {
+ int x=(int)event->x;
+ if (event->button == 1) {
+ if(has_moved) {
+ // drag
+ vfo_move((long long)((float)(x-last_x)*rx->hz_per_pixel));
+ } else {
+ // move to this frequency
+ vfo_move_to((long long)((float)(x-(display_width/2))*rx->hz_per_pixel));
+ }
+ last_x=x;
+ pressed=FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+gboolean receiver_motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data) {
+ int x, y;
+ GdkModifierType state;
+ RECEIVER *rx=(RECEIVER *)data;
+ if(!making_active) {
+ gdk_window_get_device_position (event->window,
+ event->device,
+ &x,
+ &y,
+ &state);
+ if((state & GDK_BUTTON1_MASK == GDK_BUTTON1_MASK) || pressed) {
+ int moved=last_x-x;
+ vfo_move((long long)((float)moved*rx->hz_per_pixel));
+ last_x=x;
+ has_moved=TRUE;
+ }
+ }
+
+ return TRUE;
+}
+
+gboolean receiver_scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data) {
+ if(event->direction==GDK_SCROLL_UP) {
+ if(vfo[active_receiver->id].ctun) {
+ vfo_move(-step);
+ } else {
+ vfo_move(step);
+ }
+ } else {
+ if(vfo[active_receiver->id].ctun) {
+ vfo_move(step);
+ } else {
+ vfo_move(-step);
+ }
+ }
+ return TRUE;
+}
+
+void receiver_save_state(RECEIVER *rx) {
+ char name[128];
+ char value[128];
+
+ sprintf(name,"receiver.%d.sample_rate",rx->id);
+ sprintf(value,"%d",rx->sample_rate);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.adc",rx->id);
+ sprintf(value,"%d",rx->adc);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.filter_low",rx->id);
+ sprintf(value,"%d",rx->filter_low);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.filter_high",rx->id);
+ sprintf(value,"%d",rx->filter_high);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.fps",rx->id);
+ sprintf(value,"%d",rx->fps);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.panadapter_low",rx->id);
+ sprintf(value,"%d",rx->panadapter_low);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.panadapter_high",rx->id);
+ sprintf(value,"%d",rx->panadapter_high);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.display_waterfall",rx->id);
+ sprintf(value,"%d",rx->display_waterfall);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.waterfall_low",rx->id);
+ sprintf(value,"%d",rx->waterfall_low);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.waterfall_high",rx->id);
+ sprintf(value,"%d",rx->waterfall_high);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.waterfall_automatic",rx->id);
+ sprintf(value,"%d",rx->waterfall_automatic);
+ setProperty(name,value);
+
+ sprintf(name,"receiver.%d.alex_antenna",rx->id);
+ sprintf(value,"%d",rx->alex_antenna);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.alex_attenuation",rx->id);
+ sprintf(value,"%d",rx->alex_attenuation);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.volume",rx->id);
+ sprintf(value,"%f",rx->volume);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.agc",rx->id);
+ sprintf(value,"%d",rx->agc);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.agc_gain",rx->id);
+ sprintf(value,"%f",rx->agc_gain);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.agc_slope",rx->id);
+ sprintf(value,"%f",rx->agc_slope);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.agc_hang_threshold",rx->id);
+ sprintf(value,"%f",rx->agc_hang_threshold);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.attenuation",rx->id);
+ sprintf(value,"%d",rx->attenuation);
+ setProperty(name,value);
+
+ sprintf(name,"receiver.%d.dither",rx->id);
+ sprintf(value,"%d",rx->dither);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.random",rx->id);
+ sprintf(value,"%d",rx->random);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.preamp",rx->id);
+ sprintf(value,"%d",rx->preamp);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.nr",rx->id);
+ sprintf(value,"%d",rx->nr);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.nr2",rx->id);
+ sprintf(value,"%d",rx->nr2);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.anf",rx->id);
+ sprintf(value,"%d",rx->anf);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.snb",rx->id);
+ sprintf(value,"%d",rx->snb);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.nr_agc",rx->id);
+ sprintf(value,"%d",rx->nr_agc);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.nr2_gain_method",rx->id);
+ sprintf(value,"%d",rx->nr2_gain_method);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.nr2_npe_method",rx->id);
+ sprintf(value,"%d",rx->nr2_npe_method);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.nr2_ae",rx->id);
+ sprintf(value,"%d",rx->nr2_ae);
+ setProperty(name,value);
+
+ sprintf(name,"receiver.%d.audio_channel",rx->id);
+ sprintf(value,"%d",rx->audio_channel);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.local_audio",rx->id);
+ sprintf(value,"%d",rx->local_audio);
+ setProperty(name,value);
+ sprintf(name,"receiver.%d.audio_device",rx->id);
+ sprintf(value,"%d",rx->audio_device);
+ setProperty(name,value);
+
+}
+
+void receiver_restore_state(RECEIVER *rx) {
+ char name[128];
+ char *value;
+
+fprintf(stderr,"receiver_restore_state: id=%d\n",rx->id);
+ sprintf(name,"receiver.%d.sample_rate",rx->id);
+ value=getProperty(name);
+ if(value) rx->sample_rate=atoi(value);
+ sprintf(name,"receiver.%d.adc",rx->id);
+ value=getProperty(name);
+ if(value) rx->adc=atoi(value);
+ sprintf(name,"receiver.%d.filter_low",rx->id);
+ value=getProperty(name);
+ if(value) rx->filter_low=atoi(value);
+ sprintf(name,"receiver.%d.filter_high",rx->id);
+ value=getProperty(name);
+ if(value) rx->filter_high=atoi(value);
+ sprintf(name,"receiver.%d.fps",rx->id);
+ value=getProperty(name);
+ if(value) rx->fps=atoi(value);
+/*
+ sprintf(name,"receiver.%d.frequency",rx->id);
+ value=getProperty(name);
+ if(value) rx->frequency=atoll(value);
+ sprintf(name,"receiver.%d.display_frequency",rx->id);
+ value=getProperty(name);
+ if(value) rx->display_frequency=atoll(value);
+ sprintf(name,"receiver.%d.dds_frequency",rx->id);
+ value=getProperty(name);
+ if(value) rx->dds_frequency=atoll(value);
+ sprintf(name,"receiver.%d.dds_offset",rx->id);
+ value=getProperty(name);
+ if(value) rx->dds_offset=atoll(value);
+ sprintf(name,"receiver.%d.rit",rx->id);
+ value=getProperty(name);
+ if(value) rx->rit=atoi(value);
+*/
+ sprintf(name,"receiver.%d.panadapter_low",rx->id);
+ value=getProperty(name);
+ if(value) rx->panadapter_low=atoi(value);
+ sprintf(name,"receiver.%d.panadapter_high",rx->id);
+ value=getProperty(name);
+ if(value) rx->panadapter_high=atoi(value);
+ sprintf(name,"receiver.%d.display_waterfall",rx->id);
+ value=getProperty(name);
+ if(value) rx->display_waterfall=atoi(value);
+ sprintf(name,"receiver.%d.waterfall_low",rx->id);
+ value=getProperty(name);
+ if(value) rx->waterfall_low=atoi(value);
+ sprintf(name,"receiver.%d.waterfall_high",rx->id);
+ value=getProperty(name);
+ if(value) rx->waterfall_high=atoi(value);
+ sprintf(name,"receiver.%d.waterfall_automatic",rx->id);
+ value=getProperty(name);
+ if(value) rx->waterfall_automatic=atoi(value);
+
+ sprintf(name,"receiver.%d.alex_antenna",rx->id);
+ value=getProperty(name);
+ if(value) rx->alex_antenna=atoi(value);
+ sprintf(name,"receiver.%d.alex_attenuation",rx->id);
+ value=getProperty(name);
+ if(value) rx->alex_attenuation=atoi(value);
+ sprintf(name,"receiver.%d.volume",rx->id);
+ value=getProperty(name);
+ if(value) rx->volume=atof(value);
+ sprintf(name,"receiver.%d.agc",rx->id);
+ value=getProperty(name);
+ if(value) rx->agc=atoi(value);
+ sprintf(name,"receiver.%d.agc_gain",rx->id);
+ value=getProperty(name);
+ if(value) rx->agc_gain=atof(value);
+ sprintf(name,"receiver.%d.agc_slope",rx->id);
+ value=getProperty(name);
+ if(value) rx->agc_slope=atof(value);
+ sprintf(name,"receiver.%d.hang_threshold",rx->id);
+ value=getProperty(name);
+ if(value) rx->agc_hang_threshold=atof(value);
+ sprintf(name,"receiver.%d.attenuation",rx->id);
+ value=getProperty(name);
+ if(value) rx->attenuation=atoi(value);
+
+ sprintf(name,"receiver.%d.dither",rx->id);
+ value=getProperty(name);
+ if(value) rx->dither=atoi(value);
+ sprintf(name,"receiver.%d.random",rx->id);
+ value=getProperty(name);
+ if(value) rx->random=atoi(value);
+ sprintf(name,"receiver.%d.preamp",rx->id);
+ value=getProperty(name);
+ if(value) rx->preamp=atoi(value);
+ sprintf(name,"receiver.%d.nr",rx->id);
+ value=getProperty(name);
+ if(value) rx->nr=atoi(value);
+ sprintf(name,"receiver.%d.nr2",rx->id);
+ value=getProperty(name);
+ if(value) rx->nr2=atoi(value);
+ sprintf(name,"receiver.%d.anf",rx->id);
+ value=getProperty(name);
+ if(value) rx->anf=atoi(value);
+ sprintf(name,"receiver.%d.snb",rx->id);
+ value=getProperty(name);
+ if(value) rx->snb=atoi(value);
+ sprintf(name,"receiver.%d.nr_agc",rx->id);
+ value=getProperty(name);
+ if(value) rx->nr_agc=atoi(value);
+ sprintf(name,"receiver.%d.nr2_gain_method",rx->id);
+ value=getProperty(name);
+ if(value) rx->nr2_gain_method=atoi(value);
+ sprintf(name,"receiver.%d.nr2_npe_method",rx->id);
+ value=getProperty(name);
+ if(value) rx->nr2_npe_method=atoi(value);
+ sprintf(name,"receiver.%d.ae",rx->id);
+ value=getProperty(name);
+ if(value) rx->nr2_ae=atoi(value);
+
+ sprintf(name,"receiver.%d.audio_channel",rx->id);
+ value=getProperty(name);
+ if(value) rx->audio_channel=atoi(value);
+ sprintf(name,"receiver.%d.local_audio",rx->id);
+ value=getProperty(name);
+ if(value) rx->local_audio=atoi(value);
+ sprintf(name,"receiver.%d.audio_device",rx->id);
+ value=getProperty(name);
+ if(value) rx->audio_device=atoi(value);
+}
+
+void reconfigure_receiver(RECEIVER *rx,int height) {
+ int y=0;
+
+ rx->height=height;
+
+ if(rx->display_panadapter) {
+ int height=rx->height;
+ if(rx->display_waterfall) {
+ height=height/2;
+ }
+ if(rx->panadapter==NULL) {
+fprintf(stderr,"reconfigure_receiver: panadapter_init: width:%d height:%d\n",rx->width,height);
+ rx_panadapter_init(rx, rx->width,height);
+ gtk_fixed_put(GTK_FIXED(rx->panel),rx->panadapter,0,y);
+ } else {
+ // set the size
+fprintf(stderr,"reconfigure_receiver: panadapter set_size_request: width:%d height:%d\n",rx->width,height);
+ gtk_widget_set_size_request(rx->panadapter, rx->width, height);
+ // move the current one
+ gtk_fixed_move(GTK_FIXED(rx->panel),rx->panadapter,0,y);
+ }
+ y+=height;
+ } else {
+ if(rx->panadapter!=NULL) {
+ gtk_container_remove(GTK_CONTAINER(rx->panel),rx->panadapter);
+ gtk_widget_destroy(rx->panadapter);
+ rx->panadapter=NULL;
+ }
+ }
+
+ if(rx->display_waterfall) {
+ int height=rx->height;
+ if(rx->display_panadapter) {
+ height=height/2;
+ }
+ if(rx->waterfall==NULL) {
+fprintf(stderr,"reconfigure_receiver: waterfall_init: width:%d height:%d\n",rx->width,height);
+ waterfall_init(rx,rx->width,height);
+ gtk_fixed_put(GTK_FIXED(rx->panel),rx->waterfall,0,y);
+ } else {
+ // set the size
+fprintf(stderr,"reconfigure_receiver: waterfall set_size_request: width:%d height:%d\n",rx->width,height);
+ gtk_widget_set_size_request(rx->waterfall, rx->width, height);
+ // move the current one
+ gtk_fixed_move(GTK_FIXED(rx->panel),rx->waterfall,0,y);
+ }
+ } else {
+ if(rx->waterfall!=NULL) {
+ gtk_container_remove(GTK_CONTAINER(rx->panel),rx->waterfall);
+ gtk_widget_destroy(rx->waterfall);
+ rx->waterfall=NULL;
+ }
+ }
+
+ gtk_widget_show_all(rx->panel);
+}
+
+static gint update_display(gpointer data) {
+ RECEIVER *rx=(RECEIVER *)data;
+ int rc;
+
+ if(rx->displaying) {
+ GetPixels(rx->id,0,rx->pixel_samples,&rc);
+ if(rc) {
+ if(rx->display_panadapter) {
+ switch(vfo[rx->id].mode) {
+#ifdef PSK
+ case modePSK:
+ psk_waterfall_update(rx);
+ break;
+#endif
+ default:
+ rx_panadapter_update(rx);
+ break;
+ }
+ }
+ if(rx->display_waterfall) {
+ waterfall_update(rx);
+ }
+ }
+
+ if(active_receiver==rx) {
+ double m=GetRXAMeter(rx->id,smeter);
+ meter_update(SMETER,m,0.0,0.0,0.0);
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void set_displaying(RECEIVER *rx,int state) {
+ rx->displaying=state;
+ if(state) {
+ rx->update_timer_id=gdk_threads_add_timeout_full(G_PRIORITY_HIGH_IDLE,1000/rx->fps, update_display, rx, NULL);
+ }
+}
+
+void set_mode(RECEIVER *rx,int m) {
+ int local_mode=m;
+#ifdef FREEDV
+ if(vfo[rx->d].mode!=modeFREEDV && m==modeFREEDV) {
+ local_mode=modeUSB;
+ init_freedv();
+ } else if(vfo[rx->id].mode==modeFREEDV && m!=modeFREEDV) {
+ close_freedv();
+ }
+#endif
+#ifdef PSK
+ if(vfo[rx->id].mode!=modePSK && m==modePSK) {
+ local_mode=modeUSB;
+ //init_psk();
+ show_psk();
+ } else if(vfo[rx->id].mode==modePSK && m!=modePSK) {
+ //close_psk();
+ show_waterfall();
+ }
+#endif
+ vfo[rx->id].mode=m;
+ SetRXAMode(rx->id, vfo[rx->id].mode);
+}
+
+void set_filter(RECEIVER *rx,int low,int high) {
+ if(vfo[rx->id].mode==modeCWL) {
+ rx->filter_low=-cw_keyer_sidetone_frequency-low;
+ rx->filter_high=-cw_keyer_sidetone_frequency+high;
+ } else if(vfo[rx->id].mode==modeCWU) {
+ rx->filter_low=cw_keyer_sidetone_frequency-low;
+ rx->filter_high=cw_keyer_sidetone_frequency+high;
+ } else {
+ rx->filter_low=low;
+ rx->filter_high=high;
+ }
+
+ RXASetPassband(rx->id,(double)rx->filter_low,(double)rx->filter_high);
+}
+
+void set_deviation(RECEIVER *rx,double deviation) {
+ SetRXAFMDeviation(rx->id, deviation);
+}
+
+void set_agc(RECEIVER *rx, int agc) {
+
+ SetRXAAGCMode(rx->id, agc);
+ //SetRXAAGCThresh(rx->id, agc_thresh_point, 4096.0, rx->sample_rate);
+ SetRXAAGCSlope(rx->id,rx->agc_slope);
+ SetRXAAGCTop(rx->id,rx->agc_gain);
+ switch(agc) {
+ case AGC_OFF:
+ break;
+ case AGC_LONG:
+ SetRXAAGCAttack(rx->id,2);
+ SetRXAAGCHang(rx->id,2000);
+ SetRXAAGCDecay(rx->id,2000);
+ SetRXAAGCHangThreshold(rx->id,(int)rx->agc_hang_threshold);
+ break;
+ case AGC_SLOW:
+ SetRXAAGCAttack(rx->id,2);
+ SetRXAAGCHang(rx->id,1000);
+ SetRXAAGCDecay(rx->id,500);
+ SetRXAAGCHangThreshold(rx->id,(int)rx->agc_hang_threshold);
+ break;
+ case AGC_MEDIUM:
+ SetRXAAGCAttack(rx->id,2);
+ SetRXAAGCHang(rx->id,0);
+ SetRXAAGCDecay(rx->id,250);
+ SetRXAAGCHangThreshold(rx->id,100);
+ break;
+ case AGC_FAST:
+ SetRXAAGCAttack(rx->id,2);
+ SetRXAAGCHang(rx->id,0);
+ SetRXAAGCDecay(rx->id,50);
+ SetRXAAGCHangThreshold(rx->id,100);
+ break;
+ }
+}
+
+void set_offset(RECEIVER *rx,long long offset) {
+fprintf(stderr,"set_offset: id=%d ofset=%lld\n",rx->id,offset);
+fprintf(stderr,"set_offset: frequency=%lld ctun_freqeuncy=%lld offset=%lld\n",vfo[rx->id].frequency,vfo[rx->id].ctun_frequency,vfo[rx->id].offset);
+ if(offset==0) {
+ SetRXAShiftFreq(rx->id, (double)offset);
+ RXANBPSetShiftFrequency(rx->id, (double)offset);
+ SetRXAShiftRun(rx->id, 0);
+ } else {
+ SetRXAShiftFreq(rx->id, (double)offset);
+ RXANBPSetShiftFrequency(rx->id, (double)offset);
+ SetRXAShiftRun(rx->id, 1);
+ }
+}
+
+static void init_analyzer(RECEIVER *rx) {
+ int flp[] = {0};
+ double keep_time = 0.1;
+ int n_pixout=1;
+ int spur_elimination_ffts = 1;
+ int data_type = 1;
+ int fft_size = 8192;
+ int window_type = 4;
+ double kaiser_pi = 14.0;
+ int overlap = 2048;
+ int clip = 0;
+ int span_clip_l = 0;
+ int span_clip_h = 0;
+ int pixels=rx->pixels;
+ int stitches = 1;
+ int avm = 0;
+ double tau = 0.001 * 120.0;
+ int calibration_data_set = 0;
+ double span_min_freq = 0.0;
+ double span_max_freq = 0.0;
+
+ int max_w = fft_size + (int) min(keep_time * (double) rx->fps, keep_time * (double) fft_size * (double) rx->fps);
+
+ overlap = (int)max(0.0, ceil(fft_size - (double)rx->sample_rate / (double)rx->fps));
+
+ fprintf(stderr,"SetAnalyzer id=%d buffer_size=%d overlap=%d\n",rx->id,rx->buffer_size,overlap);
+
+
+ SetAnalyzer(rx->id,
+ n_pixout,
+ spur_elimination_ffts, //number of LO frequencies = number of ffts used in elimination
+ data_type, //0 for real input data (I only); 1 for complex input data (I & Q)
+ flp, //vector with one elt for each LO frequency, 1 if high-side LO, 0 otherwise
+ fft_size, //size of the fft, i.e., number of input samples
+ rx->buffer_size, //number of samples transferred for each OpenBuffer()/CloseBuffer()
+ window_type, //integer specifying which window function to use
+ kaiser_pi, //PiAlpha parameter for Kaiser window
+ overlap, //number of samples each fft (other than the first) is to re-use from the previous
+ clip, //number of fft output bins to be clipped from EACH side of each sub-span
+ span_clip_l, //number of bins to clip from low end of entire span
+ span_clip_h, //number of bins to clip from high end of entire span
+ pixels, //number of pixel values to return. may be either <= or > number of bins
+ stitches, //number of sub-spans to concatenate to form a complete span
+ calibration_data_set, //identifier of which set of calibration data to use
+ span_min_freq, //frequency at first pixel value8192
+ span_max_freq, //frequency at last pixel value
+ max_w //max samples to hold in input ring buffers
+ );
+
+
+}
+
+static void create_visual(RECEIVER *rx) {
+ int y=0;
+
+fprintf(stderr,"receiver: create_visual: id=%d width=%d height=%d\n",rx->id, rx->width, rx->height);
+ rx->panel=gtk_fixed_new();
+ gtk_widget_set_size_request (rx->panel, rx->width, rx->height);
+
+ rx->panadapter=NULL;
+ rx->waterfall=NULL;
+
+ int height=rx->height;
+ if(rx->display_waterfall) {
+ height=height/2;
+ }
+
+fprintf(stderr,"receiver: panadapter_init: height=%d y=%d\n",height,y);
+ rx_panadapter_init(rx, rx->width,height);
+ gtk_fixed_put(GTK_FIXED(rx->panel),rx->panadapter,0,y);
+ y+=height;
+
+ if(rx->display_waterfall) {
+fprintf(stderr,"receiver: waterfall_init: height=%d y=%d\n",height,y);
+ waterfall_init(rx,rx->width,height);
+ gtk_fixed_put(GTK_FIXED(rx->panel),rx->waterfall,0,y);
+ }
+}
+
+RECEIVER *create_receiver(int id, int buffer_size, int fft_size, int pixels, int fps, int width, int height) {
+fprintf(stderr,"create_receiver: id=%d buffer_size=%d fft_size=%d pixels=%d fps=%d\n",id,buffer_size, fft_size, pixels, fps);
+ RECEIVER *rx=malloc(sizeof(RECEIVER));
+ rx->id=id;
+ switch(id) {
+ case 0:
+ rx->adc=0;
+ break;
+ default:
+ switch(protocol) {
+ case ORIGINAL_PROTOCOL:
+ switch(device) {
+ case DEVICE_METIS:
+ case DEVICE_HERMES:
+ case DEVICE_HERMES_LITE:
+ rx->adc=0;
+ break;
+ default:
+ rx->adc=1;
+ break;
+ }
+ break;
+ default:
+ switch(device) {
+ case NEW_DEVICE_ATLAS:
+ case NEW_DEVICE_HERMES:
+ rx->adc=0;
+ break;
+ default:
+ rx->adc=1;
+ break;
+ }
+ break;
+ }
+ }
+fprintf(stderr,"create_receiver: id=%d default adc=%d\n",rx->id, rx->adc);
+ rx->sample_rate=48000;
+ rx->buffer_size=buffer_size;
+ rx->fft_size=fft_size;
+ rx->pixels=pixels;
+ rx->fps=fps;
+
+ BAND *b=band_get_band(vfo[rx->id].band);
+
+// rx->dds_offset=0;
+// rx->rit=0;
+
+ rx->width=width;
+ rx->height=height;
+ rx->display_panadapter=1;
+ rx->display_waterfall=1;
+
+ // allocate buffers
+ rx->iq_input_buffer=malloc(sizeof(double)*2*rx->buffer_size);
+ rx->audio_buffer=malloc(AUDIO_BUFFER_SIZE);
+ rx->audio_sequence=0L;
+ rx->pixel_samples=malloc(sizeof(float)*pixels);
+
+ rx->samples=0;
+ rx->displaying=0;
+ rx->display_panadapter=1;
+ rx->display_waterfall=1;
+
+ rx->panadapter_high=-40;
+ rx->panadapter_low=-140;
+
+ rx->volume=0.2;
+ rx->attenuation=0;
+
+ rx->dither=0;
+ rx->random=0;
+ rx->preamp=0;
+
+ rx->nr=0;
+ rx->nr2=0;
+ rx->anf=0;
+ rx->snb=0;
+
+ rx->nr_agc=0;
+ rx->nr2_gain_method=2;
+ rx->nr2_npe_method=0;
+ rx->nr2_ae=1;
+
+ rx->alex_antenna=b->alexRxAntenna;
+ rx->alex_attenuation=b->alexAttenuation;
+
+ rx->agc=AGC_MEDIUM;
+ rx->agc_gain=80.0;
+ rx->agc_slope=35.0;
+ rx->agc_hang_threshold=0.0;
+
+ rx->playback_handle=NULL;
+ rx->local_audio=0;
+ rx->audio_channel=STEREO;
+ rx->audio_device=-1;
+
+ receiver_restore_state(rx);
+
+ int scale=rx->sample_rate/48000;
+ rx->output_samples=rx->buffer_size/scale;
+ rx->audio_output_buffer=malloc(sizeof(double)*2*rx->output_samples);
+fprintf(stderr,"create_receiver: id=%d output_samples=%d\n",rx->id,rx->output_samples);
+
+ rx->hz_per_pixel=(double)rx->sample_rate/(double)rx->width;
+ // setup wdsp for this receiver
+
+fprintf(stderr,"create_receiver: id=%d after restore adc=%d\n",rx->id, rx->adc);
+
+fprintf(stderr,"create_receiver: OpenChannel id=%d buffer_size=%d fft_size=%d sample_rate=%d\n",rx->id,rx->buffer_size, rx->fft_size, rx->sample_rate);
+ OpenChannel(rx->id,
+ rx->buffer_size,
+ rx->fft_size,
+ rx->sample_rate,
+ 48000, // dsp rate
+ 48000, // output rate
+ 0, // receive
+ 1, // run
+ 0.010, 0.025, 0.0, 0.010, 0);
+
+ b=band_get_band(vfo[rx->id].band);
+ BANDSTACK *bs=b->bandstack;
+ BANDSTACK_ENTRY *entry=&bs->entry[vfo[rx->id].bandstack];
+ FILTER *band_filters=filters[vfo[rx->id].mode];
+ FILTER *band_filter=&band_filters[vfo[rx->id].filter];
+ set_filter(rx,band_filter->low,band_filter->high);
+
+ SetRXAFMDeviation(rx->id,(double)deviation);
+
+ set_agc(rx, rx->agc);
+
+ SetRXAAMDSBMode(rx->id, 0);
+ SetRXAShiftRun(rx->id, 0);
+
+ SetRXAEMNRPosition(rx->id, rx->nr_agc);
+ SetRXAEMNRgainMethod(rx->id, rx->nr2_gain_method);
+ SetRXAEMNRnpeMethod(rx->id, rx->nr2_npe_method);
+ SetRXAEMNRRun(rx->id, rx->nr2);
+ SetRXAEMNRaeRun(rx->id, rx->nr2_ae);
+
+ SetRXAANRVals(rx->id, 64, 16, 16e-4, 10e-7); // defaults
+ SetRXAANRRun(rx->id, rx->nr);
+ SetRXAANFRun(rx->id, rx->anf);
+ SetRXASNBARun(rx->id, rx->snb);
+
+ SetRXAPanelGain1(rx->id, rx->volume);
+ SetRXAPanelBinaural(rx->id, binaural);
+ SetRXAPanelRun(rx->id, 1);
+
+ if(enable_rx_equalizer) {
+ SetRXAGrphEQ(rx->id, rx_equalizer);
+ SetRXAEQRun(rx->id, 1);
+ } else {
+ SetRXAEQRun(rx->id, 0);
+ }
+
+ // setup for diversity
+ create_divEXT(0,0,2,rx->buffer_size);
+ SetEXTDIVRotate(0, 2, &i_rotate, &q_rotate);
+ SetEXTDIVRun(0,diversity_enabled);
+
+
+ int result;
+ XCreateAnalyzer(rx->id, &result, 262144, 1, 1, "");
+ if(result != 0) {
+ fprintf(stderr, "XCreateAnalyzer id=%d failed: %d\n", rx->id, result);
+ } else {
+ init_analyzer(rx);
+ }
+
+ SetDisplayDetectorMode(rx->id, 0, display_detector_mode);
+ SetDisplayAverageMode(rx->id, 0, display_average_mode);
+
+ calculate_display_average(rx);
+
+ create_visual(rx);
+
+ if(rx->local_audio) {
+ audio_open_output(rx);
+ }
+
+ return rx;
+}
+
+void receiver_change_adc(RECEIVER *rx,int adc) {
+ rx->adc=adc;
+}
+
+void receiver_change_sample_rate(RECEIVER *rx,int sample_rate) {
+
+ rx->sample_rate=sample_rate;
+
+ SetChannelState(rx->id,0,1);
+
+ int scale=rx->sample_rate/48000;
+ rx->output_samples=rx->buffer_size/scale;
+ free(rx->audio_output_buffer);
+ rx->audio_output_buffer=malloc(sizeof(double)*2*rx->output_samples);
+ rx->audio_buffer=malloc(AUDIO_BUFFER_SIZE);
+ rx->hz_per_pixel=(double)rx->sample_rate/(double)rx->width;
+
+ SetInputSamplerate(rx->id, sample_rate);
+
+ init_analyzer(rx);
+
+fprintf(stderr,"receiver_change_sample_rate: id=%d rate=%d buffer_size=%d output_samples=%d\n",rx->id, rx->sample_rate, rx->buffer_size, rx->output_samples);
+ SetChannelState(rx->id,1,0);
+}
+
+void receiver_frequency_changed(RECEIVER *rx) {
+ int id=rx->id;
+
+ if(vfo[id].ctun) {
+ vfo[id].offset=vfo[id].ctun_frequency-vfo[id].frequency;
+ set_offset(rx,vfo[id].offset);
+ } else if(protocol==NEW_PROTOCOL) {
+ schedule_high_priority(); // send new frequency
+ }
+}
+
+void receiver_mode_changed(RECEIVER *rx) {
+ set_mode(rx,vfo[rx->id].mode);
+}
+
+void receiver_filter_changed(RECEIVER *rx) {
+ FILTER *mode_filters=filters[vfo[rx->id].mode];
+ FILTER *filter=&mode_filters[vfo[rx->id].filter];
+ set_filter(rx,filter->low,filter->high);
+}
+
+void receiver_vfo_changed(RECEIVER *rx) {
+ receiver_frequency_changed(rx);
+ receiver_mode_changed(rx);
+ receiver_filter_changed(rx);
+}
+
+#ifdef FREEDV
+static void process_freedv_rx_buffer(RECEIVER *rx) {
+ short left_audio_sample;
+ short right_audio_sample;
+ int i;
+ int demod_samples;
+ for(i=0;i<rx->output_samples;i++) {
+ if(freedv_samples==0) {
+ left_audio_sample=(short)(rx->audio_output_buffer[i*2]*32767.0);
+ right_audio_sample=(short)(rx->audio_output_buffer[(i*2)+1]*32767.0);
+ demod_samples=demod_sample_freedv(left_audio_sample);
+ if(demod_samples!=0) {
+ int s;
+ int t;
+ for(s=0;s<demod_samples;s++) {
+ if(freedv_sync) {
+ left_audio_sample=right_audio_sample=(short)((double)speech_out[s]);
+ } else {
+ left_audio_sample=right_audio_sample=0;
+ }
+ for(t=0;t<6;t++) { // 8k to 48k
+ if(local_audio) {
+ audio_write(left_audio_sample,right_audio_sample);
+ left_audio_sample=0;
+ right_audio_sample=0;
+ }
+
+ switch(protocol) {
+ case ORIGINAL_PROTOCOL:
+ old_protocol_audio_samples(left_audio_sample,right_audio_sample);
+ break;
+ case NEW_PROTOCOL:
+ new_protocol_audio_samples(left_audio_sample,right_audio_sample);
+ break;
+#ifdef LIMESDR
+ case LIMESDR_PROTOCOL:
+ break;
+#endif
+ }
+ }
+ }
+ }
+ freedv_samples++;
+ if(freedv_samples==freedv_resample) {
+ freedv_samples=0;
+ }
+ }
+ }
+}
+#endif
+
+static void process_rx_buffer(RECEIVER *rx) {
+ short left_audio_sample;
+ short right_audio_sample;
+ int i;
+ for(i=0;i<rx->output_samples;i++) {
+ if(isTransmitting()) {
+ left_audio_sample=0;
+ right_audio_sample=0;
+ } else {
+ left_audio_sample=(short)(rx->audio_output_buffer[i*2]*32767.0);
+ right_audio_sample=(short)(rx->audio_output_buffer[(i*2)+1]*32767.0);
+#ifdef PSK
+ if(vfo[rx->id].mode==modePSK) {
+ if(psk_samples==0) {
+ psk_demod((double)((left_audio_sample+right_audio_sample)/2));
+ }
+ psk_samples++;
+ if(psk_samples==psk_resample) {
+ psk_samples=0;
+ }
+ }
+#endif
+ }
+
+ if(rx->local_audio) {
+ switch(rx->audio_channel) {
+ case STEREO:
+ audio_write(rx,left_audio_sample,right_audio_sample);
+ break;
+ case LEFT:
+ audio_write(rx,left_audio_sample,0);
+ break;
+ case RIGHT:
+ audio_write(rx,0,right_audio_sample);
+ break;
+ }
+ }
+
+ if(rx==active_receiver) {
+ switch(protocol) {
+ case ORIGINAL_PROTOCOL:
+ old_protocol_audio_samples(rx,left_audio_sample,right_audio_sample);
+ break;
+ case NEW_PROTOCOL:
+ if(!(echo&&isTransmitting())) {
+ new_protocol_audio_samples(rx,left_audio_sample,right_audio_sample);
+ }
+ break;
+#ifdef LIMESDR
+ case LIMESDR_PROTOCOL:
+ break;
+#endif
+ }
+ }
+
+ }
+}
+
+void full_rx_buffer(RECEIVER *rx) {
+ int j;
+ int error;
+
+ fexchange0(rx->id, rx->iq_input_buffer, rx->audio_output_buffer, &error);
+ if(error!=0) {
+ fprintf(stderr,"full_rx_buffer: id=%d fexchange0: error=%d\n",rx->id,error);
+ }
+
+ if(rx->displaying) {
+ Spectrum0(1, rx->id, 0, 0, rx->iq_input_buffer);
+ }
+
+ switch(vfo[rx->id].mode) {
+#ifdef FREEDV
+ case modeFREEDV:
+ process_freedv_rx_buffer(rx);
+ break;
+#endif
+ default:
+ process_rx_buffer(rx);
+ break;
+ }
+}
+
+void add_iq_samples(RECEIVER *rx, double i_sample,double q_sample) {
+ rx->iq_input_buffer[rx->samples*2]=i_sample;
+ rx->iq_input_buffer[(rx->samples*2)+1]=q_sample;
+ rx->samples=rx->samples+1;
+ if(rx->samples==rx->buffer_size) {
+ full_rx_buffer(rx);
+ rx->samples=0;
+ }
+}
-#define MAX_RECEIVERS 2
+/* Copyright (C)
+* 2017 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*/
+#ifndef _RECEIVER_H
+#define _RECEIVER_H
-struct _receiver {
+#include <gtk/gtk.h>
+#include <alsa/asoundlib.h>
+
+#define AUDIO_BUFFER_SIZE 260
+
+enum _audio_t {
+ STEREO=0,
+ LEFT,
+ RIGHT
+};
+
+typedef enum _audio_t audio_t;
+
+typedef struct _receiver {
+ int id;
+
+ int adc;
+
+ double volume;
+ int agc;
+ double agc_gain;
+ double agc_slope;
+ double agc_hang_threshold;
+ int fps;
+ int displaying;
+ audio_t audio_channel;
int sample_rate;
int buffer_size;
- int band;
- int bandstack;
- int mode;
- int filter;
- int audio;
-} rx[MAX_RECEIVERS];
+ int fft_size;
+ int pixels;
+ int samples;
+ int output_samples;
+ double *iq_input_buffer;
+ double *audio_output_buffer;
+ unsigned char *audio_buffer;
+ int audio_index;
+ long audio_sequence;
+ float *pixel_samples;
+ int display_panadapter;
+ int display_waterfall;
+ gint update_timer_id;
+
+ double hz_per_pixel;
+
+// long long frequency;
+// long long display_frequency;
+// long long dds_frequency;
+// long long dds_offset;
+
+// int rit;
+
+ int dither;
+ int random;
+ int preamp;
+
+ int nr;
+ int nr2;
+ int anf;
+ int snb;
+
+ int nr_agc;
+ int nr2_gain_method;
+ int nr2_npe_method;
+ int nr2_ae;
+
+
+ int attenuation;
+ int alex_antenna;
+ int alex_attenuation;
+
+ int filter_low;
+ int filter_high;
+
+ int width;
+ int height;
+
+ GtkWidget *panel;
+ GtkWidget *panadapter;
+ GtkWidget *waterfall;
+
+ int panadapter_low;
+ int panadapter_high;
+
+ int waterfall_low;
+ int waterfall_high;
+ int waterfall_automatic;
+
+ cairo_surface_t *panadapter_surface;
+ GdkPixbuf *pixbuf;
+
+ int local_audio;
+ int audio_device;
+ snd_pcm_t *playback_handle;
+ int playback_offset;
+ unsigned char *playback_buffer;
+
+} RECEIVER;
+
+extern RECEIVER *create_receiver(int id, int buffer_size, int fft_size, int pixels, int fps, int width, int height);
+extern void receiver_change_sample_rate(RECEIVER *rx,int sample_rate);
+extern void receiver_frequency_changed(RECEIVER *rx);
+extern void receiver_mode_changed(RECEIVER *rx);
+extern void receiver_filter_changed(RECEIVER *rx);
+extern void receiver_vfo_changed(RECEIVER *rx);
+
+extern void set_mode(RECEIVER* rx,int m);
+extern void set_filter(RECEIVER *rx,int low,int high);
+extern void set_agc(RECEIVER *rx, int agc);
+extern void set_offset(RECEIVER *rx, long long offset);
+extern void set_deviation(RECEIVER *rx, double deviation);
+
+extern void add_iq_samples(RECEIVER *rx, double i_sample,double q_sample);
+
+extern void reconfigure_receiver(RECEIVER *rx,int height);
+
+extern void receiver_save_state(RECEIVER *rx);
+extern gboolean receiver_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data);
+extern gboolean receiver_button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer data);
+extern gboolean receiver_motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data);
+extern gboolean receiver_scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data);
+#endif
-\r
-/* S-2000 emulation via TCP\r
- * Copyright (C) 2016 Steve Wilson <wevets@gmail.com>\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License as\r
- * published by the Free Software Foundation, either version 2 of the\r
- * License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
- */\r
-\r
-/*\r
- * PiHPSDR RigCtl by Steve KA6S Oct 16 2016\r
- * \r
- */\r
-#include <gtk/gtk.h>\r
-#include <gdk/gdk.h>\r
-#include <unistd.h>\r
-#include <semaphore.h>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include "toolbar.h"\r
-#include "sliders.h"\r
-#include "rigctl.h"\r
-#include "radio.h"\r
-#include "channel.h"\r
-#include "filter.h"\r
-#include <string.h>\r
-#include "mode.h"\r
-#include "filter.h"\r
-#include "wdsp_init.h"\r
-#include "band.h"\r
-#include "bandstack.h"\r
-#include "vfo.h"\r
-#include "sliders.h"\r
-#include <pthread.h>\r
-#include <wdsp.h>\r
-\r
-// IP stuff below\r
-#include<sys/socket.h>\r
-#include<arpa/inet.h> //inet_addr\r
-\r
-#undef RIGCTL_DEBUG\r
-\r
-// the port client will be connecting to\r
-#define TELNET_PORT 19090 // This is the HAMLIB port\r
-// max number of bytes we can get at once\r
-#define MAXDATASIZE 300\r
-\r
-int init_server ();\r
-\r
-int rigctlGetFilterLow();\r
-int rigctlGetFilterHigh();\r
-int rigctlSetFilterLow(int val);\r
-int rigctlSetFilterHigh(int val);\r
-int new_level;\r
-void parse_cmd ( char *,int );\r
-\r
-extern int enable_tx_equalizer;\r
-\r
-typedef struct com_list {\r
- char cmd_string[80];\r
- struct com_list * next_ent; \r
- } com_list_t;\r
-com_list_t cmd_list;\r
-char cmd_save[80];\r
-\r
-char cmd_input[MAXDATASIZE] ;\r
-char * wptr;\r
-com_list_t * work_input; \r
-com_list_t * work_list; \r
-com_list_t * follow_list; \r
-com_list_t * com_head = NULL;\r
-com_list_t * cur_ent;\r
-int cmdlistcnt;\r
-int retcode = 1;\r
-char workvar[100];\r
-\r
-char command[80];\r
-char msg[80];\r
-char msg2[80];\r
-char * newf;\r
-\r
-FILE * TTYFILE;\r
-FILE * out;\r
-int output;\r
-FILTER * band_filter;\r
-\r
-static pthread_t rigctl_thread_id;\r
-static void * rigctl (void * arg);\r
-\r
-int squelch=100; //local sim of squelch level\r
-// This stuff from the telnet server\r
-int sockfd, numbytes;\r
-char buf[MAXDATASIZE];\r
-struct hostent *he;\r
-\r
-// connector’s address information\r
-struct sockaddr_in their_addr;\r
-\r
-int socket_desc , client_sock , c , read_size;\r
-struct sockaddr_in server , client;\r
-char client_message[MAXDATASIZE];\r
-\r
-int freq_flag; // Determines if we are in the middle of receiving frequency info\r
-\r
-int digl_offset = 0;\r
-int digl_pol = 0;\r
-int digu_offset = 0;\r
-int digu_pol = 0;\r
-double new_vol = 0;\r
-\r
-// Radio functions - \r
-// Memory channel stuff and things that aren't \r
-// implemented - but here for a more complete emulation\r
-int ctcss_tone; // Numbers 01-38 are legal values - set by CN command, read by CT command\r
-int ctcss_mode; // Numbers 0/1 - on off.\r
-\r
-// Now my stuff\r
-//\r
-// Looks up entry INDEX_NUM in the command structure and\r
-// returns the command string\r
-//\r
-\r
-void send_resp (char * msg) {\r
- #ifdef RIGCTL_DEBUG\r
- fprintf(stderr,"RIGCTL: RESP=%s\n",msg);\r
- #endif\r
- write(client_sock, msg, strlen(msg));\r
-}\r
-\r
-char * cmd_lookup (int index_num) {\r
- com_list_t * lcl_p;\r
- lcl_p = com_head;\r
- if(index_num == 0) {\r
- return(lcl_p->cmd_string);\r
- } else {\r
- while((lcl_p->next_ent != (com_list_t * ) NULL) && (index_num != 0)) {\r
- lcl_p = lcl_p->next_ent;\r
- index_num--;\r
- }\r
- }\r
- if(index_num == 0) {\r
- return(lcl_p->cmd_string);\r
- } else {\r
- return ((char *) NULL);\r
- } \r
-}\r
-\r
-static void * rigctl (void * arg) {\r
- int len;\r
- init_server();\r
- int save_flag = 0; // Used to concatenate two cmd lines together\r
- int semi_number = 0;\r
- int i;\r
- char * work_ptr;\r
- char work_buf[MAXDATASIZE];\r
-\r
- for(;;) {\r
- fprintf(stderr,"RIGCTL - New run\n");\r
- while((numbytes=recv(client_sock , cmd_input , MAXDATASIZE-2 , 0)) > 0 ) {\r
- //cmd_input[numbytes+1]='\0'; // Turn into a C string\r
- //i=strlen(cmd_input);\r
- //#ifdef RIGCTL_DEBUG\r
- //fprintf(stderr,"RIGCTL: RCVD=%s NB=%d LEN=%d\n",cmd_input,numbytes,i);\r
- //#endif\r
- for(i=0;i<numbytes;i++) { work_buf[i] = cmd_input[i]; }\r
- work_buf[i+1] = '\0';\r
- #ifdef RIGCTL_DEBUG\r
- fprintf(stderr,"RIGCTL: RCVD=%s<-\n",work_buf);\r
- #endif\r
-\r
- // Need to handle two cases\r
- // 1. Command is short, i.e. no semicolon - that will set save_flag=1 and\r
- // read another line..\r
- // 2. 1 to N commands per line. Turns out N1MM sends multiple commands per line\r
- \r
- if(save_flag == 0) { // Count the number of semicolons if we aren't already in mode 1.\r
- semi_number = 0;\r
- for(i=0;i<numbytes;i++) {\r
- if(cmd_input[i] == ';') { semi_number++;};\r
- } \r
- }\r
- if((save_flag == 0) && (semi_number == 0)) {\r
- cmd_input[numbytes] = '\0'; // Turn it into a C string\r
- strcpy(cmd_save,cmd_input); // And save a copy of it till next time through\r
- save_flag = 1;\r
- } else if(save_flag == 1) {\r
- save_flag = 0;\r
- cmd_input[numbytes] = '\0'; // Turn it into a C string\r
- strcat(cmd_save,cmd_input);\r
- strcpy(cmd_input,cmd_save); // Cat them together and replace cmd_input\r
- numbytes = strlen(cmd_input);\r
- } \r
- if(save_flag != 1) {\r
- work_ptr = strtok(cmd_input,";");\r
- while(work_ptr != NULL) {\r
- parse_cmd(work_ptr,strlen(work_ptr));\r
- work_ptr = strtok(NULL,";");\r
- }\r
- for(i=0;i<MAXDATASIZE;i++){\r
- cmd_input[i] = '\0'; \r
- work_buf[i] = '\0'; // Clear the input buffer\r
- }\r
- }\r
- // Got here because pipe closed \r
- }\r
- if(numbytes == 0) {\r
- fprintf(stderr,"RIGCTL: Client disconnected\n");\r
- close(client_sock);\r
- sleep(1);\r
- client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);\r
- }\r
- }\r
-}\r
-\r
-void parse_cmd ( char * cmd_input,int len) {\r
- int work_int; \r
- int new_low, new_high;\r
- double meter;\r
- BANDSTACK_ENTRY *entry;\r
- // Parse the cmd_input\r
- //int space = command.indexOf(' ');\r
- //char cmd_char = com_head->cmd_string[0]; // Assume the command is first thing!\r
- char cmd_str[3];\r
- cmd_str[0] = cmd_input[0];\r
- cmd_str[1] = cmd_input[1];\r
- cmd_str[2] = '\0';\r
- if(strcmp(cmd_str,"AC")==0) { // Sets or reads the internal antenna tuner status\r
- // P1 0:RX-AT Thru, 1: RX-AT IN\r
- // P2 0: TX-AT Thru 1: TX-AT In\r
- // \r
- if(len <= 2) {\r
- send_resp("AC000;");\r
- }\r
- }\r
- else if(strcmp(cmd_str,"AG")==0) { // Set Audio Gain - \r
- // AG123; Value of 0-\r
- // AG1 = Sub receiver - what is the value set\r
- // Response - AG<0/1>123; Where 123 is 0-260\r
- if(len>4) { // Set Audio Gain\r
- volume = (double) atoi(&cmd_input[3])/260; \r
- g_idle_add(update_af_gain,NULL); \r
- } else { // Read Audio Gain\r
- sprintf(msg,"AG0%03d;",(int) (2.6 * volume));\r
- send_resp(msg);\r
- #ifdef RIGCTL_DEBUG\r
- fprintf(stderr,":%s\n",msg);\r
- #endif\r
- }\r
- }\r
- else if(strcmp(cmd_str,"AI")==0) { // Allow rebroadcast of set frequency after set - not supported\r
- if(len <=2) {\r
- send_resp("AI0;");\r
- } \r
- }\r
- else if(strcmp(cmd_str,"AL")==0) { // Set/Reads the auto Notch level \r
- if(len <=2) {\r
- send_resp("AL000;");\r
- } \r
- }\r
- else if(strcmp(cmd_str,"AM")==0) { // Sets or reads the Auto Mode\r
- if(len <=2) {\r
- send_resp("AM0;");\r
- } \r
- }\r
- else if(strcmp(cmd_str,"AN")==0) { // Selects the antenna connector (ANT1/2)\r
- if(len <=2) {\r
- send_resp("AN0;");\r
- } \r
- }\r
- else if(strcmp(cmd_str,"AR")==0) { // Sets or reads the ASC function on/off\r
- if(len <=2) {\r
- send_resp("AR0;");\r
- } \r
- }\r
- else if(strcmp(cmd_str,"AS")==0) { // Sets/reads automode function parameters\r
- // AS<P1><2xP2><11P3><P4>;\r
- // AS<P1><2xP2><11P3><P4>;\r
- if(len < 6) { \r
- sprintf(msg,"AS%1d%02d%011lld%01d;",\r
- 0, // P1\r
- 0, // Automode \r
- getFrequency(),\r
- rigctlGetMode());\r
- send_resp(msg);\r
- \r
- } \r
- }\r
- else if(strcmp(cmd_str,"BC")==0) { // Beat Cancellor OFF\r
- if(len <=2) {\r
- send_resp("BC0;");\r
- } \r
- }\r
- else if(strcmp(cmd_str,"BD")==0) { // Moves down the frequency band\r
- // No response \r
- }\r
- else if(strcmp(cmd_str,"BP")==0) { // Reads the manual beat canceller frequency setting\r
- if(len <=2) {\r
- send_resp("BP000;");\r
- } \r
- }\r
- else if(strcmp(cmd_str,"BS")==0) { // Sets or reads Beat Canceller status\r
- if(len <=2) {\r
- send_resp("BS0;");\r
- } \r
- }\r
- else if(strcmp(cmd_str,"BU")==0) { // Moves Up the frequency band\r
- // No response \r
- }\r
- else if(strcmp(cmd_str,"BY")==0) { // Read the busy signal status\r
- if(len <=2) {\r
- send_resp("BY00;");\r
- } \r
- }\r
- else if(strcmp(cmd_str,"CA")==0) { // Sets/reads cw auto tune function status\r
- if(len <=2) {\r
- send_resp("CA0;");\r
- } \r
- }\r
- else if(strcmp(cmd_str,"CG")==0) { // Sets/reads the carrier gain status\r
- // 0-100 legal values\r
- if(len <=2) {\r
- send_resp("CG000;");\r
- } \r
- }\r
- else if(strcmp(cmd_str,"CH")==0) { // Sets the current frequency to call Channel\r
- // No response\r
- }\r
- else if(strcmp(cmd_str,"CI")==0) { // While in VFO mode or memory recall mode, sets freq to the call channel\r
- // No response\r
- }\r
- else if(strcmp(cmd_str,"CM")==0) { // Sets or reads the packet cluster tune f(x) on/off\r
- // 0-100 legal values\r
- if(len <=2) {\r
- send_resp("CM0;");\r
- } \r
- }\r
- else if(strcmp(cmd_str,"CN")==0) { // Sets and reads CTSS function - 01-38 legal values\r
- // Stored locally in rigctl - not used.\r
- if(len <=2) {\r
- sprintf(msg,"CN%02d;",ctcss_tone);\r
- send_resp(msg);\r
- } else {\r
- ctcss_tone = atoi(&cmd_input[2]);\r
- }\r
- }\r
- else if(strcmp(cmd_str,"CT")==0) { // Sets and reads CTSS function status\r
- // Stored locally in rigctl - not used.\r
- if(len <=2) {\r
- sprintf(msg,"CT%01d;",ctcss_mode);\r
- send_resp(msg);\r
- } else {\r
- ctcss_mode = atoi(&cmd_input[2]);\r
- }\r
- }\r
- else if(strcmp(cmd_str,"DC")==0) { // Sets/Reads TX band status\r
- if(len <=2) {\r
- send_resp("DC00;");\r
- } \r
- }\r
- else if(strcmp(cmd_str,"DN")==0) { // Emulate Mic down key \r
- }\r
- else if(strcmp(cmd_str,"DQ")==0) { // ETs/and reads the DCS function status\r
- if(len <=2) {\r
- send_resp("DQ0;");\r
- } \r
- }\r
- else if(strcmp(cmd_str,"EX")==0) { // Set/reads the extension menu\r
- cmd_input[9] = '\0'; // Make sure we have a C string\r
- sprintf(msg,"EX%s0;",&cmd_input[2]);\r
- send_resp(msg);\r
- }\r
- else if(strcmp(cmd_str,"FA")==0) { // VFO A frequency\r
- // LEN=7 - set frequency\r
- // Next data will be rest of freq\r
- if(len == 13) { //We are receiving freq info\r
- long long new_freqA = atoll(&cmd_input[2]);\r
- set_band(new_freqA);\r
- //setFrequency(new_freqA);\r
- //g_idle_add(vfo_update,NULL);\r
- } else {\r
- if(len==2) {\r
- sprintf(msg,"FA%011lld;",getFrequency());\r
- send_resp(msg);\r
- }\r
- }\r
- }\r
- else if(strcmp(cmd_str,"FB")==0) { // VFO B frequency\r
- if(len==13) { //We are receiving freq info\r
- long long new_freqA = atoll(&cmd_input[2]); \r
- set_band(new_freqA);\r
- //setFrequency(new_freqA);\r
- //g_idle_add(vfo_update,NULL);\r
- } else if(len == 2) {\r
- sprintf(msg,"FB%011lld;",getFrequency());\r
- send_resp(msg);\r
- }\r
- }\r
- else if(strcmp(cmd_str,"FC")==0) { // Set Sub receiver freq\r
- // LEN=7 - set frequency\r
- // Next data will be rest of freq\r
- // Len<7 - frequency?\r
- if(len>4) { //We are receiving freq info\r
- long long new_freqA = atoll(&cmd_input[2]); \r
- //setFrequency(new_freqA);\r
- } else {\r
- sprintf(msg,"FC%011lld;",getFrequency());\r
-/*\r
- send_resp(msg);\r
-*/\r
- }\r
- }\r
- else if(strcmp(cmd_str,"FD")==0) { // Read the filter display dot pattern\r
- send_resp("FD00000000;");\r
- }\r
- else if(strcmp(cmd_str,"FR")==0) { // Set/reads the extension menu\r
- if(len <=2) {\r
- send_resp("FR0;");\r
- } \r
- }\r
- else if(strcmp(cmd_str,"FS")==0) { // Set/reads fine funct status\r
- if(len <=2) {\r
- send_resp("FS0;");\r
- } \r
- }\r
- else if(strcmp(cmd_str,"FT")==0) { // Sel or reads the transmitters VFO, M, ch or Call comm \r
- if(len <=2) {\r
- send_resp("FT0;");\r
- } \r
- } \r
- else if(strcmp(cmd_str,"FW")==0) { // Sets/Reas DSP receive filter width in hz 0-9999hz \r
- // CW - legal values 50 80 100 150 200 300 400 500 600 1000 2000\r
- // PiHPSDR map 50 100 100 100 250 250 400 500 600 1000\r
- // 25 750\r
- entry= (BANDSTACK_ENTRY *) \r
- bandstack_entry_get_current();\r
- FILTER* band_filters=filters[entry->mode];\r
- FILTER* band_filter=&band_filters[entry->filter];\r
- if(len <=2) {\r
- // CW filter high and low are always the same and the filter value is 2*filter val\r
- int filter_val = band_filter->high * 2;\r
- switch(filter_val) {\r
- case 25: \r
- case 50:\r
- work_int = 50;\r
- break;\r
- case 100:\r
- work_int = 100; \r
- break;\r
- case 250:\r
- work_int = 300; \r
- break;\r
- case 400:\r
- work_int = 400; \r
- break;\r
- case 500:\r
- work_int = 500; \r
- break;\r
- case 600:\r
- work_int = 600; \r
- break;\r
- case 750:\r
- work_int = 1000; \r
- break;\r
- case 800:\r
- work_int = 1000; \r
- break;\r
- case 1000:\r
- work_int = 1000; \r
- break;\r
- default: work_int = 500; \r
- break;\r
- } \r
- sprintf(msg,"FW%04d;",work_int);\r
- #ifdef RIGCTL_DEBUG\r
- fprintf(stderr,"RIGCTL: FW Filter Act=%d work_int=%d\n",band_filter->high,work_int);\r
- #endif\r
- send_resp(msg);\r
- } else {\r
- // Try to set filters here!\r
- // CW - legal values 50 80 100 150 200 300 400 500 600 1000 2000\r
- // PiHPSDR map 50 100 100 100 250 250 400 500 600 1000\r
- // 25 750\r
- work_int = atoi(&cmd_input[2]);\r
- switch (work_int) {\r
-\r
- case 50: new_low = 25; new_high = 25; break;\r
- case 80: new_low = 50; new_high = 50; break;\r
- case 100: new_low = 50; new_high = 50; break;\r
- case 150: new_low = 50; new_high = 50; break;\r
- case 200: new_low = 125; new_high = 125; break;\r
- case 300: new_low = 125; new_high = 125; break;\r
- case 400: new_low = 200; new_high = 200; break;\r
- case 500: new_low = 250; new_high = 250; break;\r
- case 600: new_low = 300; new_high = 300; break;\r
- case 1000: new_low = 500; new_high = 500; break;\r
- case 2000: new_low = 500; new_high = 500; break;\r
- default: new_low = band_filter->low;\r
- new_high = band_filter->high;\r
-\r
- }\r
- #ifdef RIGCTL_DEBUG\r
- fprintf(stderr,"RIGCTL: FW Filter new_low=%d new_high=%d\n",new_low,new_high);\r
- #endif\r
- // entry->filter = new_low * 2 ;\r
- setFilter(new_low,new_high);\r
- g_idle_add(vfo_update,NULL);\r
- }\r
- } \r
- else if(strcmp(cmd_str,"GT")==0) { // Sets/Reas AGC constant status\r
- if(len <=2) {\r
- send_resp("GT000;");\r
- } \r
- } \r
- else if(strcmp(cmd_str,"ID")==0) { // Read ID - Default to TS-2000 which is type 019.\r
- sprintf(msg,"ID019;");\r
- send_resp(msg);\r
- }\r
- else if(strcmp(cmd_str,"IF")==0) { // Reads Transceiver status\r
- // IFFFFFFFFFFFF - Frequency \r
- // OFFS - 4 chars Offset in powers of 10\r
- // RITRIT - 6 chars RIT/XIT Frequency - Not supported =0\r
- // R - 1 char RIT Status = 0 is off\r
- // X - 1 char XIT Status = 0 is off\r
- // 0 - 1 char Channel Bank number - not used\r
- // 00 - 2 char Channel Bank number - not used\r
- // C - 1 char Mox Status 0=off, 1=on\r
- // M - 1 char Operating mode - align with MD commands\r
- // V - 1 char VFO Split status - not supported \r
- // 0 - 1 char Scan status - not supported\r
- // A - 1 char - same as FT command\r
- // 0 - 1 char - CTCSS tone - not used\r
- // 00 - 2 char - More tone control\r
- // 0 - 1 char - Shift status\r
- sprintf(msg,"IF%011lld%04d%06d%1d%1d%1d%02d%01d%01d%01d%01d%01d%01d%02d%01d;",\r
- getFrequency(),\r
- step, // Shift Offset\r
- 0, // Rit Freq\r
- 0, // Rit Status\r
- 0, // XIT Status\r
- 0, // Channel Bank num\r
- 0, // Channel Bank num\r
- 0, // Mox Status\r
- rigctlGetMode(), // Mode Status - same as MD Command\r
- 0, // VFO Status\r
- 0, // Scan status\r
- 0, // FT command \r
- ctcss_tone, // CTSS Tone\r
- 0, // More tone control\r
- 0); // Shift status\r
- send_resp(msg);\r
- }\r
- else if(strcmp(cmd_str,"IS")==0) { // Sets/Reas IF shift funct status\r
- if(len <=2) {\r
- send_resp("IS00000;");\r
- } \r
- } \r
- else if(strcmp(cmd_str,"KS")==0) { // Sets/Reads keying freq - 0-060 max\r
- if(len <=2) {\r
- sprintf(msg,"KS%03d;",cw_keyer_speed);\r
- send_resp(msg);\r
- } else {\r
- int key_speed;\r
- key_speed = atoi(&cmd_input[2]);\r
- if(key_speed >1 && key_speed <= 60) {\r
- cw_keyer_speed=key_speed;\r
- g_idle_add(vfo_update,NULL);\r
- } \r
- }\r
- } \r
- else if(strcmp(cmd_str,"KY")==0) { // Convert char to morse code\r
- if(len <=2) {\r
- send_resp("KY0;");\r
- } \r
- } \r
- else if(strcmp(cmd_str,"LK")==0) { // Set/read key lock function status\r
- if(len <=2) {\r
- sprintf(msg,"LK%01d%01d;",locked,locked);\r
- send_resp(msg);\r
- } else {\r
- if(cmd_input[3] == '0') {\r
- locked = 0;\r
- } else if(cmd_input[3] == '1') {\r
- locked = 1;\r
- }\r
- g_idle_add(vfo_update,NULL);\r
- }\r
- } \r
- else if(strcmp(cmd_str,"LM")==0) { // Set/read DRU 3A unit or elect keyer recording status\r
- if(len <=2) {\r
- send_resp("LM0;");\r
- } \r
- } \r
- else if(strcmp(cmd_str,"LT")==0) { // Set/read Alt function\r
- if(len <=2) {\r
- send_resp("LT0;");\r
- } \r
- } \r
- else if(strcmp(cmd_str,"MC")==0) { // Recalls or reads memory channel\r
- if(len <=2) {\r
- send_resp("MC000;"); // Link this to band stack at some point\r
- }\r
- }\r
- else if(strcmp(cmd_str,"MD")==0) { // Mode - digit selects mode\r
- // 1 = LSB\r
- // 2 = USB\r
- // 3 = CWU\r
- // 4 = FM\r
- // 5 = AM\r
- // 6 = DIGL\r
- // 7 = CWL\r
- // 9 = DIGU \r
- int new_mode;\r
- if(len > 2) { // Set Mode\r
- switch(atoi(&cmd_input[2])) { \r
- case 1: \r
- new_mode = modeLSB;\r
- break;\r
- case 2: \r
- new_mode = modeUSB;\r
- break;\r
- case 3: \r
- new_mode = modeCWU;\r
- break;\r
- case 4: \r
- new_mode = modeFMN;\r
- break;\r
- case 5: \r
- new_mode = modeAM;\r
- break;\r
- case 6: \r
- new_mode = modeDIGL;\r
- break;\r
- case 7: \r
- new_mode = modeCWL;\r
- break;\r
- case 9: \r
- new_mode = modeDIGU;\r
- break;\r
- default:\r
- break;\r
- #ifdef RIGCTL_DEBUG\r
- fprintf(stderr,"MD command Unknown\n");\r
- #endif\r
- }\r
- // Other stuff to switch modes goes here..\r
- // since new_mode has the interpreted command in \r
- // in it now.\r
- entry= (BANDSTACK_ENTRY *) \r
- bandstack_entry_get_current();\r
- entry->mode=new_mode;\r
- // BUG - kills the system when there is some\r
- // GPIO activity and Mode sets occur. Used twittling the\r
- // frequency along with setting mode between USB/LSB with\r
- // flrig. Tried doing the g_idle_add trick - but don't know the\r
- // the magic to get that to compile without warnings \r
- setMode(entry->mode);\r
- // Moved the vfo_update down after filter updated. (John G0ORX)\r
- //g_idle_add(vfo_update,NULL);\r
- \r
- FILTER* band_filters=filters[entry->mode];\r
- FILTER* band_filter=&band_filters[entry->filter];\r
- setFilter(band_filter->low,band_filter->high);\r
- /* Need a way to update VFO info here..*/\r
- g_idle_add(vfo_update,NULL);\r
- } else { // Read Mode\r
- int curr_mode;\r
- switch (mode) {\r
- case modeLSB: curr_mode = 1; \r
- break; \r
- case modeUSB: curr_mode = 2;\r
- break;\r
- case modeCWL: curr_mode = 7; // CWL\r
- break;\r
- case modeCWU: curr_mode = 3; // CWU\r
- break;\r
- case modeFMN: curr_mode = 4; // FMN\r
- break;\r
- case modeAM: curr_mode = 5; // AM\r
- break;\r
- case modeDIGU: curr_mode = 9; // DIGU\r
- break;\r
- case modeDIGL: curr_mode = 6; // DIGL\r
- break;\r
- default: \r
- #ifdef RIGCTL_DEBUG\r
- fprintf(stderr,\r
- "RIGCTL: MD command doesn't support %d\n",\r
- mode);\r
- #endif\r
- break;\r
- }\r
- sprintf(msg,"MD%1d;",curr_mode);\r
- send_resp(msg);\r
- }\r
- }\r
- else if(strcmp(cmd_str,"MF")==0) { // Set/read menu A/B\r
- if(len <=2) {\r
- send_resp("MF0;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"MG")==0) { // Mike Gain - 3 digit value \r
- if(len <=2) {\r
- work_int = (int) ((mic_gain +10.0)* 100.0/60.0);\r
- sprintf(msg,"MG%03d;",work_int);\r
- send_resp(msg);\r
- } else {\r
- int tval = atoi(&cmd_input[2]); \r
- new_vol = (double) (tval * 60/100) - 10; \r
- //set_mic_gain(new_vol); \r
- double *p_mic_gain=malloc(sizeof(double));\r
- *p_mic_gain=new_vol;\r
- g_idle_add(update_mic_gain,(void *)p_mic_gain);\r
- }\r
- }\r
- else if(strcmp(cmd_str,"ML")==0) { // Set/read the monitor function level\r
- if(len <=2) {\r
- send_resp("ML000;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"MO")==0) { // Set Monitor on/off\r
- if(len <=2) {\r
- send_resp("MO0;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"MR")==0) { // Read Memory Channel data\r
- sprintf(msg,"MR%1d%02d%02d%011lld%1d%1d%1d%02d%02d%03d%1d%1d%09d%02d%1d%08d;",\r
- 0, // P1 - Rx Freq - 1 Tx Freq\r
- 0, // P2 Bankd and channel number -- see MC comment\r
- 0, // P3 - see MC comment \r
- getFrequency(), // P4 - frequency\r
- rigctlGetMode(), // P5 - Mode\r
- locked, // P6 - Locked status\r
- 0, // P7 - O-off, 1-tone, 2-CTCSS, 3 =DCS\r
- 0, // P8 - Tone Number - see page 35\r
- ctcss_tone, // P9 - CTCSS tone number - see CN command\r
- 0, // P10 - DCS code - see QC command \r
- 0, // P11 - Reverse status\r
- 0, // P12 - Shift status - see OS command\r
- 0, // P13 - Offset freq - see OS command\r
- 0, // P14 - Step Size - see ST command\r
- 0, // P15 - Memory Group Number (0-9)\r
- 0); // P16 - Memory Name - 8 char max\r
- send_resp(msg);\r
- }\r
- else if(strcmp(cmd_str,"MU")==0) { // Set/Read Memory Group Data\r
- if(len <=2) {\r
- send_resp("MU0000000000;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"MW")==0) { // Store Data to Memory Channel\r
- }\r
- else if(strcmp(cmd_str,"NB")==0) { // Set/Read Noise Blanker func status (on/off)\r
- if(len <=2) {\r
- sprintf(msg,"NB%1d;",snb);\r
- send_resp(msg);\r
- } else {\r
- if(cmd_input[2]=='0') { // Turn off ANF\r
- snb=0;\r
- } else { // Turn on ANF\r
- snb=1;\r
- }\r
- // Update ALL the filters\r
- SetRXAANRRun(CHANNEL_RX0, nr);\r
- SetRXAEMNRRun(CHANNEL_RX0, nr2);\r
- SetRXAANFRun(CHANNEL_RX0, anf);\r
- SetRXASNBARun(CHANNEL_RX0, snb);\r
- g_idle_add(vfo_update,NULL);\r
- }\r
- }\r
- else if(strcmp(cmd_str,"NL")==0) { // Set/Read Noise Reduction Level\r
- if(len <=2) {\r
- send_resp("NL000;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"NR")==0) { // Set/Read Noise Reduction function status\r
- if(len <=2) {\r
- if(nr_none == 1) {\r
- send_resp("NR0;"); \r
- } else if ((nr_none == 0) && (nr==1)) { \r
- send_resp("NR1;"); \r
- } else if (nr2 == 1) { \r
- send_resp("NR2;"); \r
- } else {\r
- send_resp("NR0;"); \r
- }\r
- } else {\r
- if(cmd_input[2] == '0') {\r
- nr_none = 1;\r
- nr = 0;\r
- nr2 = 0;\r
- } else if(cmd_input[2] == '1') {\r
- nr_none = 0;\r
- nr = 1;\r
- nr2 = 0;\r
- } else if(cmd_input[2] == '2') {\r
- nr_none = 0;\r
- nr = 0;\r
- nr2 = 1;\r
- } \r
- SetRXAANRRun(CHANNEL_RX0, nr_none);\r
- SetRXAEMNRRun(CHANNEL_RX0, nr2);\r
- SetRXAANFRun(CHANNEL_RX0, anf);\r
- SetRXASNBARun(CHANNEL_RX0, snb);\r
- g_idle_add(vfo_update,NULL);\r
- }\r
- }\r
- else if(strcmp(cmd_str,"NT")==0) { // Set/Read autonotch function\r
- if(len <=2) {\r
- sprintf(msg,"NT%1d;",anf);\r
- send_resp(msg);\r
- } else {\r
- if(cmd_input[2] == '0') { // Clear ANF\r
- anf = 0;\r
- } else { // Set ANF\r
- anf = 1;\r
- }\r
- }\r
- SetRXAANRRun(CHANNEL_RX0, nr_none);\r
- SetRXAEMNRRun(CHANNEL_RX0, nr2);\r
- SetRXAANFRun(CHANNEL_RX0, anf);\r
- SetRXASNBARun(CHANNEL_RX0, snb);\r
- g_idle_add(vfo_update,NULL);\r
- }\r
- else if(strcmp(cmd_str,"OF")==0) { // Set/Read Offset freq (9 digits - hz)\r
- if(len <=2) {\r
- send_resp("OF000000000;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"OI")==0) { // Read Memory Channel Data\r
- if(len <=2) {\r
- sprintf(msg,"OI%011lld%04d%06d%1d%1d%1d%02d%1d%1d%1d%1d%1d%1d%02d%1d;",\r
- getFrequency(),\r
- 0, // P2 - Freq Step size\r
- 0, // P3 - Rit/Xit Freq \r
- 0, // P4 - RIT off/Rit On\r
- 0, // P5 - XIT off/on\r
- 0, // P6 - Channel\r
- 0, // P7 - Bank\r
- 0, // P8 - 0RX, 1TX\r
- rigctlGetMode(), // P10 - MD\r
- 0, // P11 - SC command\r
- 0, // P12 Split op - SP command\r
- 0, // P13 Off, 1, 2, \r
- 0,// P14 Tone freq - See TN command\r
- 0,0);\r
- send_resp(msg);\r
- }\r
- }\r
- else if(strcmp(cmd_str,"OS")==0) { // Set/Read Offset freq (9 digits - hz)\r
- if(len <=2) {\r
- send_resp("OS0;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"PA")==0) { // Set/Read Preamp function status\r
- if(len <=2) {\r
- sprintf(msg,"PA0%1d;",enable_tx_equalizer);\r
- send_resp(msg);\r
- } else {\r
- if(cmd_input[2] =='0') {\r
- enable_tx_equalizer=0;\r
- SetTXAEQRun(CHANNEL_TX, enable_tx_equalizer);\r
- } else {\r
- enable_tx_equalizer=1;\r
- SetTXAEQRun(CHANNEL_TX, enable_tx_equalizer);\r
- }\r
- }\r
- }\r
- else if(strcmp(cmd_str,"PB")==0) { // Set/Read DRU-3A Playback status\r
- if(len <=2) {\r
- send_resp("PB0;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"PC")==0) { // Set/Read Drive Power output\r
- if(len<=2) {\r
- sprintf(msg,"PC%03d;",(int) drive);\r
- send_resp(msg); \r
- } else {\r
- // Power Control - 3 digit number- 0 to 100\r
- //Scales to 0.00-1.00\r
- \r
- double drive_val = \r
- (double)(atoi(&cmd_input[2])); \r
- // setDrive(drive_val);\r
- double *p_drive=malloc(sizeof(double));\r
- *p_drive=drive_val;\r
- g_idle_add(update_drive,(gpointer)p_drive);\r
- //set_drive(drive_val);\r
- }\r
- }\r
- else if(strcmp(cmd_str,"PI")==0) { // STore the programmable memory channel\r
- }\r
- else if(strcmp(cmd_str,"PK")==0) { // Reads the packet cluster data\r
- send_resp("PK000000000000000000000000000000000000000000000000;"); \r
- }\r
- else if(strcmp(cmd_str,"PL")==0) { // Set/Read Speech processor level\r
- // P1 000 - min-100 max\r
- // P2 000 - min - 100 max\r
- if(len <=2) {\r
- send_resp("PL000000;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"PM")==0) { // Recalls the Programmable memory\r
- if(len <=2) {\r
- send_resp("PM0;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"PR")==0) { // Sets/reads the speech processor function on/off\r
- // 0 - off, 1=on\r
- if(len <=2) {\r
- send_resp("PR0;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"PS")==0) { // Sets/reads Power on/off state\r
- // 0 - off, 1=on\r
- if(len <=2) {\r
- send_resp("PS1;"); // Lets pretend we're powered up ;-) \r
- }\r
- }\r
- else if(strcmp(cmd_str,"PS")==0) { // Sets/reads DCS code\r
- // Codes numbered from 000 to 103.\r
- if(len <=2) {\r
- send_resp("QC000;"); // Lets pretend we're powered up ;-) \r
- }\r
- }\r
- else if(strcmp(cmd_str,"QI")==0) { // Store the settings in quick memory\r
- }\r
- else if(strcmp(cmd_str,"QR")==0) { // Send the Quick memory channel data\r
- // P1 - Quick mem off, 1 quick mem on\r
- // P2 - Quick mem channel number\r
- if(len <=2) {\r
- send_resp("QR00;"); // Lets pretend we're powered up ;-) \r
- }\r
- }\r
- else if(strcmp(cmd_str,"RA")==0) { // Sets/reads Attenuator function status\r
- // 00-off, 1-99 -on - Main and sub receivers reported\r
- if(len <=2) {\r
- send_resp("RA0000;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"RC")==0) { // Clears the RIT offset freq\r
- }\r
- else if(strcmp(cmd_str,"RD")==0) { // Move the RIT offset freq down, slow down the scan speed in scan mode\r
- if(len <=2) {\r
- send_resp("RD0;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"RG")==0) { // RF Gain - 3 digit number\r
- // RG123; 0-255 value\r
- // Scale from -20 - 120\r
- if(len>4) { // Set Audio Gain\r
- int base_value = atoi(&cmd_input[2]);\r
- double new_gain = ((((double) base_value)/255) * 140) - 20; \r
- //set_agc_gain(new_gain); \r
- double *p_gain=malloc(sizeof(double));\r
- *p_gain=new_gain;\r
- g_idle_add(update_agc_gain,(gpointer)p_gain);\r
- } else { // Read Audio Gain\r
- sprintf(msg,"RG%03d;",((256 * (int) agc_gain)/140)+36);\r
- send_resp(msg);\r
- }\r
- }\r
- else if(strcmp(cmd_str,"RL")==0) { // Set/read Noise reduction level\r
- if(len <=2) {\r
- send_resp("RL00;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"RM")==0) { // Set/read Meter function\r
- // P1- 0, unsel, 1 SWR, 2 Comp, 3 ALC\r
- // P2 - 4 dig - Meter value in dots - 000-0030\r
- if(len <=2) {\r
- send_resp("RM00000;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"RT")==0) { // Set/read the RIT function status\r
- if(len <=2) {\r
- send_resp("RT0;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"RU")==0) { // Set/move RIT frequency up\r
- if(len <=2) {\r
- send_resp("RU0;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"RX")==0) { // Unkey Xmitter\r
- setMox(0);\r
- // 0-main, 1=sub\r
- if(len <=2) {\r
- send_resp("RX0;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"SA")==0) { // Set/reads satellite mode status\r
- // 0-main, 1=sub\r
- if(len <=2) {\r
- send_resp("SA000000000000000;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"SB")==0) { // Set/read the SUB TF-W status\r
- if(len <=2) {\r
- send_resp("SB0;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"SC")==0) { // Set/read the Scan function status\r
- if(len <=2) {\r
- send_resp("SC0;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"SD")==0) { // Set/read CW break-in time delay\r
- // 0000-1000 ms (in steps of 50 ms) 0000 is full break in\r
- if(len <=2) {\r
- send_resp("SD0000;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"SH")==0) { // Set/read the DSP filter settings\r
- if(len <=2) {\r
- send_resp("SH00;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"SI")==0) { // Enters the satellite memory name\r
- }\r
- else if(strcmp(cmd_str,"SL")==0) { // Set/read the DSP filter settings - this appears twice? See SH\r
- if(len <=2) {\r
- send_resp("SL00;");\r
- } \r
- }\r
- else if(strcmp(cmd_str,"SM")==0) { // Read SMETER\r
- // SMx; x=0 RX1, x=1 RX2 \r
- // meter is in dbm - value will be 0<260\r
- // Translate to 00-30 for main, 0-15 fo sub\r
- // Resp= SMxAABB; \r
- // Received range from the SMeter can be -127 for S0, S9 is -73, and S9+60=-13.;\r
- // PowerSDR returns S9=0015 code. \r
- // Let's make S9 half scale or a value of 70. \r
- double level;\r
- level = GetRXAMeter(CHANNEL_RX0, smeter); \r
- // Determine how high above 127 we are..making a range of 114 from S0 to S9+60db\r
- // 5 is a fugdge factor that shouldn't be there - but seems to get us to S9=SM015\r
- level = abs(127+(level + (double) get_attenuation()))+5;\r
- \r
- // Clip the value just in case\r
- if(cmd_input[2] == '0') { \r
- new_level = (int) ((level * 30.0)/114.0);\r
- // Do saturation check\r
- if(new_level < 0) { new_level = 0; }\r
- if(new_level > 30) { new_level = 30;}\r
- } else { //Assume we are using sub receiver where range is 0-15\r
- new_level = (int) ((level * 15.0)/114.0);\r
- // Do saturation check\r
- if(new_level < 0) { new_level = 0; }\r
- if(new_level > 15) { new_level = 15;}\r
- }\r
- sprintf(msg,"SM%1c%04d;",\r
- cmd_input[2],new_level);\r
- send_resp(msg);\r
- } \r
- else if(strcmp(cmd_str,"SQ")==0) { // Set/read the squelch level\r
- // P1 - 0- main, 1=sub\r
- // P2 - 0-255\r
- if(len <=3) {\r
- sprintf(msg,"SQ%04d;",squelch);\r
- send_resp(msg);\r
- } else {\r
- squelch = atoi(&cmd_input[2]);\r
- }\r
- }\r
- else if(strcmp(cmd_str,"SR")==0) { // Resets the transceiver\r
- }\r
- else if(strcmp(cmd_str,"SS")==0) { // Set/read Scan pause freq\r
- if(len <=2) {\r
- send_resp("SS0;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"ST")==0) { // Set/read the multi/ch control freq steps\r
- // SSB/CW/FSK - values 00-03\r
- // 00: 1KHz, 01: 2.5Khz 02:5KHz 03: 10Khz\r
- // AM/FM mode 00-09\r
- // 00: 5KHz, \r
- // 01: 6.25KHz, \r
- // 02:10Khz, \r
- // 03: 12.5Khz,\r
- // 04: 15Khz, \r
- // 05: 20Khz, \r
- // 06: 25KHz\r
- // 07: 30Khz\r
- // 08: 50Khz\r
- // 09: 100Khz \r
- int coded_step_val;\r
- entry= (BANDSTACK_ENTRY *) \r
- bandstack_entry_get_current();\r
- if(len <=2) {\r
- switch(entry->mode) {\r
- case modeLSB: \r
- case modeUSB: \r
- case modeCWL: \r
- case modeCWU: \r
- case modeDIGU: \r
- case modeDIGL: \r
- if(step >0 && step <= 1000) {\r
- coded_step_val = 0; \r
- } else if (step >1000 && step <=2500) {\r
- coded_step_val = 1; \r
- } else if (step >2500 && step <=5000) {\r
- coded_step_val = 2; \r
- } else {\r
- coded_step_val = 3; \r
- }\r
- break;\r
- case modeFMN: \r
- case modeAM: \r
- if(step >0 && step <= 5000) {\r
- coded_step_val = 0; \r
- } else if (step >5000 && step <=6250) {\r
- coded_step_val = 1; \r
- } else if (step >6250 && step <=10000) {\r
- coded_step_val = 2; \r
- } else if (step >10000 && step <=12500) {\r
- coded_step_val = 3; \r
- } else if (step >12500 && step <=15000) {\r
- coded_step_val = 4; \r
- } else if (step >15000 && step <=20000) {\r
- coded_step_val = 5; \r
- } else if (step >20000 && step <=25000) {\r
- coded_step_val = 6; \r
- } else if (step >25000 && step <=30000) {\r
- coded_step_val = 7; \r
- } else if (step >30000 && step <=50000) {\r
- coded_step_val = 8; \r
- } else if (step >50000 && step <=100000) {\r
- coded_step_val = 9; \r
- } else {\r
- coded_step_val = 0; \r
- }\r
- break;\r
- } \r
- sprintf(msg,"ST%02d;",coded_step_val);\r
- send_resp(msg); \r
- } else {\r
- coded_step_val = atoi(&cmd_input[2]); \r
- switch(entry->mode) {\r
- case modeLSB: \r
- case modeUSB: \r
- case modeCWL: \r
- case modeCWU: \r
- case modeDIGU: \r
- case modeDIGL: \r
- if(coded_step_val==0) { step = 1000;}\r
- if(coded_step_val==1) { step = 2500;}\r
- if(coded_step_val==2) { step = 5000;}\r
- if(coded_step_val==3) { step = 10000;}\r
- break; \r
- case modeFMN: \r
- case modeAM: \r
- switch(coded_step_val) {\r
- case 0: step = 5000; break;\r
- case 1: step = 6250; break;\r
- case 2: step = 10000; break;\r
- case 3: step = 12500; break;\r
- case 4: step = 15000; break;\r
- case 5: step = 20000; break;\r
- case 6: step = 25000; break;\r
- case 7: step = 30000; break;\r
- case 8: step = 50000; break;\r
- case 9: step = 100000; break;\r
- default: break; // No change if not a valid number\r
- } \r
- default: break; // No change if not a valid number\r
- } \r
- g_idle_add(vfo_update,NULL);\r
- }\r
- }\r
- else if(strcmp(cmd_str,"SU")==0) { // Set/read the scan pause freq\r
- if(len <=2) {\r
- send_resp("SU00000000000;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"SV")==0) { // Execute the memory transfer function\r
- }\r
- else if(strcmp(cmd_str,"TC")==0) { // Set/read the internal TNC mode\r
- if(len <=2) {\r
- send_resp("TC00;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"TD")==0) { // Sends the DTMF memory channel\r
- }\r
- else if(strcmp(cmd_str,"TI")==0) { // Reads the TNC LED status\r
- if(len <=2) {\r
- send_resp("TI00;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"TN")==0) { // Set/Read sub tone freq\r
- if(len <=2) {\r
- send_resp("TN00;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"TO")==0) { // Set/Read tone function\r
- if(len <=2) {\r
- send_resp("TO0;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"TS")==0) { // Set/Read TF Set function status\r
- if(len <=2) {\r
- send_resp("TS0;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"TX")==0) { // Key Xmitter - P1 - transmit on main/sub freq\r
- setMox(1);\r
- if(len <=2) {\r
- send_resp("TS0;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"TY")==0) { // Set/Read uP firmware type\r
- if(len <=2) {\r
- send_resp("TY000;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"UL")==0) { // Detects the PLL unlock status - this should never occur - xmit only\r
- if(len <=2) {\r
- send_resp("UL0;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"UP")==0) { // Emulates the mic up key\r
- }\r
- else if(strcmp(cmd_str,"VD")==0) { // Sets/Reads VOX dleay time - 0000-3000ms in steps of 150\r
- // We want vox_hang variable in PiHPSDR\r
- // Max value in variable in ms... so 250 = 250ms\r
- #ifdef RIGCTL_DEBUG\r
- fprintf(stderr,"RIGCTL: Vox hang=%0.20f\n",vox_hang);\r
- #endif\r
- if(len <=2) {\r
- work_int = (int) vox_hang;\r
- sprintf(msg,"VD%04d;",work_int); \r
- send_resp(msg);\r
- } else {\r
- work_int = atoi(&cmd_input[2]);\r
- // Bounds check for legal values for PiHPSDR\r
- if(work_int > 1000) { work_int = 1000; }\r
- if(work_int < 0) { work_int = 0; }\r
- vox_hang = (double) work_int;\r
- #ifdef RIGCTL_DEBUG\r
- fprintf(stderr,"RIGCTL: Vox hang=%0.20f\n",vox_hang);\r
- #endif\r
- }\r
- }\r
- else if(strcmp(cmd_str,"VG")==0) { // Sets/Reads VOX gain 000-009\r
- // We want vox_threshold variable in PiHPSDR\r
- // Max value in variable 0.1 \r
- // 3 char 000-009 valid ranges\r
- #ifdef RIGCTL_DEBUG\r
- fprintf(stderr,"RIGCTL: Vox thesh=%0.20f\n",vox_threshold);\r
- #endif\r
- if(len <=2) {\r
- work_int = (int) ((vox_threshold) * 100.0);\r
- sprintf(msg,"VG00%1d;",work_int);\r
- send_resp(msg);\r
- } else {\r
- // Set the threshold here\r
- work_int = atoi(&cmd_input[2]);\r
- vox_threshold = ((double) work_int)/100.0;\r
- #ifdef RIGCTL_DEBUG\r
- fprintf(stderr,"RIGCTL: Vox thresh=%0.20f\n",vox_threshold);\r
- #endif\r
- }\r
- }\r
- else if(strcmp(cmd_str,"VR")==0) { // Emulates the voice 1/2 key\r
- }\r
- else if(strcmp(cmd_str,"VX")==0) { // Sets/reads vox f(x) state\r
- if(len <=2) {\r
- sprintf(msg,"VX%1d;",vox_enabled); \r
- send_resp(msg);\r
- } else {\r
- work_int = atoi(&cmd_input[2]);\r
- if(work_int>1) { vox_enabled = 1; vox= 1;}\r
- if(work_int<1) { vox_enabled = 0; vox=0; }\r
- }\r
- }\r
- else if(strcmp(cmd_str,"XT")==0) { // Sets/reads the XIT f(x) state\r
- if(len <=2) {\r
- send_resp("XT0;"); \r
- }\r
- }\r
- else if(strcmp(cmd_str,"XX")==0) { // \r
- // Format RL01234: First dig 0=neg, 1=pos number\r
- // 1-4- digital offset in hertz.\r
- if(len > 4) { // It is set instead of a read\r
- digl_pol = (cmd_input[2]=='0') ? -1 : 1;\r
- digl_offset = atoi(&cmd_input[3]); \r
- #ifdef RIGCTL_DEBUG\r
- fprintf(stderr,"RIGCTL:RL set %d %d\n",digl_pol,digl_offset); \r
- #endif\r
- } else {\r
- if(digl_pol==1) { // Nah - its a read\r
- sprintf(msg,"RL1%04d;",0);\r
- } else {\r
- sprintf(msg,"RL0%04d;",0);\r
- } \r
- send_resp(msg);\r
- #ifdef RIGCTL_DEBUG\r
- fprintf(stderr,":%s\n",msg);\r
- #endif\r
- }\r
- }\r
- else if(strcmp(cmd_str,"XY")==0) { // set/read RTTY DIGL offset frequency - Not available - just store values\r
- // Format RL01234: First dig 0=neg, 1=pos number\r
- // 1-4- digital offset in hertz.\r
- if(len > 4) { // It is set instead of a read\r
- digl_pol = (cmd_input[2]=='0') ? -1 : 1;\r
- digl_offset = atoi(&cmd_input[3]); \r
- #ifdef RIGCTL_DEBUG\r
- fprintf(stderr,"RIGCTL:RL set %d %d\n",digl_pol,digl_offset); \r
- #endif\r
- } else {\r
- if(digl_pol==1) { // Nah - its a read\r
- sprintf(msg,"RL1%04d;",0);\r
- } else {\r
- sprintf(msg,"RL0%04d;",0);\r
- } \r
- send_resp(msg);\r
- #ifdef RIGCTL_DEBUG\r
- fprintf(stderr,":%s\n",msg);\r
- #endif\r
- }\r
- }\r
- else {\r
- fprintf(stderr,"RIGCTL: UNKNOWN=%s\n",cmd_str);\r
- }\r
-}\r
-//\r
-// End of Parser\r
-// \r
-/*\r
-char * rigctlGetFilter()\r
-{\r
- \r
- char * m = mode_string[mode];\r
-\r
- if (strcmp(m,"CWU") == 0){\r
- return (char *) (getFilterHigh() + getFilterLow());\r
- }\r
- else\r
- if (strcmp(m,"CWL") == 0){\r
- return (char *) (getFilterHigh() + getFilterLow());\r
- }\r
- else\r
- return (char *) (getFilterHigh() - getFilterLow());\r
-}\r
-*/\r
-\r
-void launch_rigctl () {\r
- int err;\r
- fprintf(stderr, "LAUNCHING RIGCTL!!\n");\r
- // This routine encapsulates the pthread call\r
- err = pthread_create (&rigctl_thread_id,NULL,rigctl,NULL);\r
- if(err != 0) {\r
- fprintf(stderr, "pthread_create failed on rigctl launch\n");\r
- } \r
-}\r
-\r
-//\r
-// Telnet Server Code below:\r
-//\r
- // max number of bytes we can get at once\r
- #define MAXDATASIZE 300\r
-\r
-int init_server () {\r
-\r
- //Create socket\r
- socket_desc = socket(AF_INET , SOCK_STREAM , 0);\r
- if (socket_desc == -1)\r
- {\r
- fprintf(stderr,"RIGCTL: Could not create socket");\r
- }\r
- fprintf(stderr, "RIGCTL: Socket created\n");\r
- \r
- //Prepare the sockaddr_in structure\r
- server.sin_family = AF_INET;\r
- server.sin_addr.s_addr = INADDR_ANY;\r
- server.sin_port = htons( TELNET_PORT );\r
- \r
- //Bind\r
- if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)\r
- {\r
- //print the error message\r
- fprintf(stderr,"RIGCLT: bind failed. Error\n");\r
- return 1;\r
- }\r
- fprintf(stderr,"RIGCTL: bind done\n");\r
- \r
- //Listen\r
- listen(socket_desc , 3);\r
- \r
- //Accept and incoming connection\r
- fprintf(stderr,"RIGCTL: Waiting for incoming connections...\n");\r
- c = sizeof(struct sockaddr_in);\r
- \r
- //accept connection from an incoming client\r
- client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);\r
- if (client_sock < 0)\r
- {\r
- fprintf(stderr,"RIGCTL: Accept failed\n");\r
- return 1;\r
- }\r
- fprintf(stderr,"RIGCTL: Connection accepted\n");\r
-}\r
-/*\r
-int rigctlGetFilterLow() {\r
- int lookup;\r
- int rval;\r
-\r
- BANDSTACK_ENTRY *entry;\r
- entry = (BANDSTACK_ENTRY *) bandstack_entry_get_current();\r
-\r
- FILTER* band_filters=filters[entry->mode];\r
- FILTER* band_filter=&band_filters[entry->filter];\r
- rval = 0;\r
- for(lookup = 0; lookup<=9; lookup++) {\r
- if(band_filter[lookup].low == -150) {\r
- rval = lookup;\r
- break;\r
- } \r
- }\r
- return rval;\r
-}\r
-\r
-int rigctlGetFilterHigh() {\r
- int lookup;\r
- int rval;\r
-\r
- BANDSTACK_ENTRY *entry;\r
- entry = (BANDSTACK_ENTRY *) bandstack_entry_get_current();\r
-\r
- FILTER* band_filters=filters[entry->mode];\r
- FILTER* band_filter=&band_filters[entry->filter];\r
- rval = 0;\r
- for(lookup = 0; lookup<=9; lookup++) {\r
- if(band_filter[lookup].high == -150) {\r
- rval = lookup;\r
- break;\r
- } \r
- }\r
- return rval;\r
-}\r
-*/\r
-int rigctlGetMode() {\r
- BANDSTACK_ENTRY *entry;\r
- entry= (BANDSTACK_ENTRY *) \r
- bandstack_entry_get_current();\r
- switch(entry->mode) {\r
- case modeLSB: return(1); // LSB\r
- case modeUSB: return(2); // USB\r
- case modeCWL: return(7); // CWL\r
- case modeCWU: return(3); // CWU\r
- case modeFMN: return(4); // FMN\r
- case modeAM: return(5); // AM\r
- case modeDIGU: return(9); // DIGU\r
- case modeDIGL: return(6); // DIGL\r
- default: return(0);\r
- }\r
-}\r
-\r
-int rigctlSetFilterLow(int val){\r
-};\r
-int rigctlSetFilterHigh(int val){\r
-};\r
-\r
-void set_band(long long new_freqA) { \r
-\r
- BANDSTACK_ENTRY *entry;\r
- int b = get_band_from_frequency(new_freqA);\r
- if(b == -1) { // Out of ham bands...\r
- setFrequency(new_freqA);\r
- g_idle_add(vfo_update,NULL);\r
- return;\r
- } \r
-\r
- if(b==band_get_current()) {\r
- entry = bandstack_entry_next(); \r
- setFrequency(new_freqA);\r
- g_idle_add(vfo_update,NULL);\r
- return;\r
- } else {\r
- BAND* band=band_set_current(b);\r
- entry=bandstack_entry_get_current();\r
- }\r
- setMode(entry->mode);\r
- FILTER* band_filters=filters[entry->mode];\r
- FILTER* band_filter=&band_filters[entry->filter];\r
- setFilter(band_filter->low,band_filter->high);\r
- setFrequency(new_freqA);\r
-\r
- BAND *band=band_get_current_band();\r
- set_alex_rx_antenna(band->alexRxAntenna);\r
- set_alex_tx_antenna(band->alexTxAntenna);\r
- set_alex_attenuation(band->alexAttenuation);\r
-\r
- setFrequency(new_freqA);\r
- g_idle_add(vfo_update,NULL);\r
-\r
-\r
- calcDriveLevel();\r
- calcTuneDriveLevel();\r
-}\r
+
+/* TS-2000 emulation via TCP
+ * Copyright (C) 2016 Steve Wilson <wevets@gmail.com>
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * PiHPSDR RigCtl by Steve KA6S Oct 16 2016
+ * With a kindly assist from Jae, K5JAE who has helped
+ * greatly with hamlib integration!
+ */
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <unistd.h>
+//#include <semaphore.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "toolbar.h"
+#include "sliders.h"
+#include "rigctl.h"
+#include "radio.h"
+#include "receiver.h"
+#include "channel.h"
+#include "filter.h"
+#include <string.h>
+#include "mode.h"
+#include "filter.h"
+#include "band.h"
+#include "bandstack.h"
+#include "vfo.h"
+#include "sliders.h"
+#include <pthread.h>
+#include "agc.h"
+#include <wdsp.h>
+#include "store.h"
+
+// IP stuff below
+#include <sys/socket.h>
+#include <arpa/inet.h> //inet_addr
+
+//#undef RIGCTL_DEBUG
+#define RIGCTL_DEBUG
+
+// the port client will be connecting to
+// 2-26-17 K5JAE - Changed the defines to const ints to allow use via pointers.
+static const int TelnetPortA = 19090;
+static const int TelnetPortB = 19091;
+static const int TelnetPortC = 19092;
+
+// max number of bytes we can get at once
+#define MAXDATASIZE 300
+
+int init_server ();
+void parse_cmd ();
+
+int rigctlGetFilterLow();
+int rigctlGetFilterHigh();
+int rigctlSetFilterLow(int val);
+int rigctlSetFilterHigh(int val);
+int new_level;
+int active_transmitter = 0;
+
+int cat_control;
+
+extern int enable_tx_equalizer;
+
+/*
+pthread_mutex_t mutex_a = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t mutex_b = PTHREAD_MUTEX_INITIALIZER;
+*/
+typedef struct {GMutex m; } GT_MUTEX;
+GT_MUTEX * mutex_a;
+GT_MUTEX * mutex_b;
+
+FILE * out;
+int output;
+FILTER * band_filter;
+
+//static pthread_t rigctl_a_thread_id, rigctl_b_thread_id, rigctl_c_thread_id;
+static GThread *rigctl_a_thread_id, *rigctl_b_thread_id, *rigctl_c_thread_id;
+
+int squelch=100; //local sim of squelch level
+
+
+int read_size;
+
+int freq_flag; // Determines if we are in the middle of receiving frequency info
+
+int digl_offset = 0;
+int digl_pol = 0;
+int digu_offset = 0;
+int digu_pol = 0;
+double new_vol = 0;
+int lcl_cmd=0;
+long long new_freqA = 0;
+long long new_freqB = 0;
+long long orig_freqA = 0;
+long long orig_freqB = 0;
+int lcl_split = 0;
+int mox_state = 0;
+// Radio functions -
+// Memory channel stuff and things that aren't
+// implemented - but here for a more complete emulation
+int ctcss_tone; // Numbers 01-38 are legal values - set by CN command, read by CT command
+int ctcss_mode; // Numbers 0/1 - on off.
+
+int vfo_sm=0; // VFO State Machine - this keeps track of
+
+// Now my stuff
+//
+
+// This looks up the frequency of the Active receiver with
+// protection for 1 versus 2 receivers
+long long rigctl_getFrequency() {
+ if(receivers == 1) {
+ return vfo[VFO_A].frequency;
+ } else {
+ return vfo[active_receiver->id].frequency;
+ }
+}
+// Looks up entry INDEX_NUM in the command structure and
+// returns the command string
+//
+void send_resp (int client_sock,char * msg) {
+ #ifdef RIGCTL_DEBUG
+ fprintf(stderr,"RIGCTL: RESP=%s\n",msg);
+ #endif
+ write(client_sock, msg, strlen(msg));
+}
+
+//
+// 2-25-17 - K5JAE - removed duplicate rigctl
+//
+
+//static void * rigctl_a (void * arg) {
+static gpointer rigctl (gpointer data) {
+ int len;
+ int c;
+ int socket_desc;
+ struct sockaddr_in client;
+ struct sockaddr_in server;
+
+ // user data void* is really an int* of the port
+ int port = *((int*) data);
+ int client_sock = init_server(&socket_desc, &client, &server, port);
+
+ g_mutex_lock(&mutex_a->m);
+ cat_control++;
+//#ifdef RIGCTL_DEBUG
+fprintf(stderr,"RIGCTL: CTLA INC cat_contro=%d\n",cat_control);
+//#endif
+ g_mutex_unlock(&mutex_a->m);
+ g_idle_add(vfo_update,NULL);
+
+ int save_flag = 0; // Used to concatenate two cmd lines together
+ int semi_number = 0;
+ int i;
+ char * work_ptr;
+ char work_buf[MAXDATASIZE];
+ int numbytes;
+ char cmd_input[MAXDATASIZE] ;
+ char cmd_save[80];
+
+ for(;;) {
+ fprintf(stderr,"RIGCTL - New run on server port: %d\n", port);
+ while((numbytes=recv(client_sock , cmd_input , MAXDATASIZE-2 , 0)) > 0 ) {
+ for(i=0;i<numbytes;i++) { work_buf[i] = cmd_input[i]; }
+ work_buf[i+1] = '\0';
+ #ifdef RIGCTL_DEBUG
+ fprintf(stderr,"RIGCTL: RCVD=%s<-\n",work_buf);
+ #endif
+
+ // Need to handle two cases
+ // 1. Command is short, i.e. no semicolon - that will set save_flag=1 and
+ // read another line..
+ // 2. 1 to N commands per line. Turns out N1MM sends multiple commands per line
+
+ if(save_flag == 0) { // Count the number of semicolons if we aren't already in mode 1.
+ semi_number = 0;
+ for(i=0;i<numbytes;i++) {
+ if(cmd_input[i] == ';') { semi_number++;};
+ }
+ }
+ if((save_flag == 0) && (semi_number == 0)) {
+ cmd_input[numbytes] = '\0'; // Turn it into a C string
+ strcpy(cmd_save,cmd_input); // And save a copy of it till next time through
+ save_flag = 1;
+ } else if(save_flag == 1) {
+ save_flag = 0;
+ cmd_input[numbytes] = '\0'; // Turn it into a C string
+ strcat(cmd_save,cmd_input);
+ strcpy(cmd_input,cmd_save); // Cat them together and replace cmd_input
+ numbytes = strlen(cmd_input);
+ }
+ if(save_flag != 1) {
+ work_ptr = strtok(cmd_input,";");
+ while(work_ptr != NULL) {
+ /*
+ pthread_mutex_lock (& mutex_b);
+ */
+ g_mutex_lock(&mutex_b->m);
+ parse_cmd(work_ptr,strlen(work_ptr),client_sock);
+ /*
+ pthread_mutex_unlock (& mutex_b);
+ */
+ g_mutex_unlock(&mutex_b->m);
+ work_ptr = strtok(NULL,";");
+ }
+ for(i=0;i<MAXDATASIZE;i++){
+ cmd_input[i] = '\0';
+ work_buf[i] = '\0'; // Clear the input buffer
+ }
+ }
+ // Got here because socket closed
+ }
+ if(numbytes == 0) {
+ fprintf(stderr,"RIGCTL: Client disconnected\n");
+ close(client_sock);
+
+ // Decrement CAT_CONTROL
+ g_mutex_lock(&mutex_a->m);
+ cat_control--;
+#ifdef RIGCTL_DEBUG
+fprintf(stderr,"RIGCTL: CTLA DEC - cat_control=%d\n",cat_control);
+#endif
+ g_mutex_unlock(&mutex_a->m);
+ g_idle_add(vfo_update,NULL);
+
+ //sleep(1);
+ c = sizeof(struct sockaddr_in);
+ client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
+
+ // Increment CAT_CONTROL
+ g_mutex_lock(&mutex_a->m);
+ cat_control++;
+#ifdef RIGCTL_DEBUG
+fprintf(stderr,"RIGCTL: CTLA INC - cat_control=%d\n",cat_control);
+#endif
+ g_mutex_unlock(&mutex_a->m);
+ g_idle_add(vfo_update,NULL);
+
+ //sleep(1);
+ }
+ }
+}
+
+//
+// FT command intepret vfo_sm state - used by IF command
+//
+int ft_read() {
+ return(active_transmitter);
+}
+//
+// Determines RIT state - used by IF command
+//
+int rit_on () {
+ if(receivers == 1) { // Worry about 1 versus 2 radios
+ if(vfo[VFO_A].rit != 0) {
+ return 1;
+ } else {
+ return 0;
+ }
+ } else { // Well - we have two so use active_reciever->id
+ if(vfo[active_receiver->id].rit != 0) {
+ return 1 ;
+ } else {
+ return 0;
+ }
+ }
+}
+void parse_cmd ( char * cmd_input,int len,int client_sock) {
+ int work_int;
+ int new_low, new_high;
+ double meter;
+ char msg[80];
+ char buf[80];
+ BANDSTACK_ENTRY *entry;
+ // Parse the cmd_input
+ //int space = command.indexOf(' ');
+ //char cmd_char = com_head->cmd_string[0]; // Assume the command is first thing!
+ char cmd_str[3];
+ cmd_str[0] = cmd_input[0];
+ cmd_str[1] = cmd_input[1];
+ cmd_str[2] = '\0';
+ if(strcmp(cmd_str,"AC")==0) { // Sets or reads the internal antenna tuner status
+ // P1 0:RX-AT Thru, 1: RX-AT IN
+ // P2 0: TX-AT Thru 1: TX-AT In
+ //
+ if(len <= 2) {
+ send_resp(client_sock,"AC000;");
+ }
+ }
+ else if(strcmp(cmd_str,"AG")==0) { // Set Audio Gain -
+ // AG123; Value of 0-
+ // AG1 = Sub receiver - what is the value set
+ // Response - AG<0/1>123; Where 123 is 0-260
+ int lcl_receiver;
+ if(receivers == 1) {
+ lcl_receiver = 0;
+ } else {
+ lcl_receiver = active_receiver->id;
+ }
+ if(len>4) { // Set Audio Gain
+ active_receiver->volume = (double) atoi(&cmd_input[3])/260;
+ g_idle_add(update_af_gain,NULL);
+ } else { // Read Audio Gain
+ sprintf(msg,"AG%1d%03d;",lcl_receiver,(int) (2.6 * active_receiver->volume));
+ send_resp(client_sock,msg);
+ }
+ }
+ else if(strcmp(cmd_str,"AI")==0) { // Allow rebroadcast of set frequency after set - not supported
+ if(len <=2) {
+ //send_resp(client_sock,"AI0;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"AL")==0) { // Set/Reads the auto Notch level
+ if(len <=2) {
+ //send_resp(client_sock,"AL000;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"AM")==0) { // Sets or reads the Auto Mode
+ if(len <=2) {
+ //send_resp(client_sock,"AM0;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"AN")==0) { // Selects the antenna connector (ANT1/2)
+ if(len <=2) {
+ //send_resp(client_sock,"AN0;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"AR")==0) { // Sets or reads the ASC function on/off
+ if(len <=2) {
+ //send_resp(client_sock,"AR0;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"AS")==0) { // Sets/reads automode function parameters
+ // AS<P1><2xP2><11P3><P4>;
+ // AS<P1><2xP2><11P3><P4>;
+ if(len < 6) {
+ /* sprintf(msg,"AS%1d%02d%011lld%01d;",
+ 0, // P1
+ 0, // Automode
+ getFrequency(),
+ rigctlGetMode());
+ send_resp(client_sock,msg);*/
+ send_resp(client_sock,"?;");
+
+ }
+ }
+ else if(strcmp(cmd_str,"BC")==0) { // Beat Cancellor OFF
+ if(len <=2) {
+ //send_resp(client_sock,"BC0;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"BD")==0) { // Moves down the frequency band
+ // No response
+ }
+ else if(strcmp(cmd_str,"BP")==0) { // Reads the manual beat canceller frequency setting
+ if(len <=2) {
+ //send_resp(client_sock,"BP000;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"BS")==0) { // Sets or reads Beat Canceller status
+ if(len <=2) {
+ //send_resp(client_sock,"BS0;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"BU")==0) { // Moves Up the frequency band
+ // No response
+ }
+ else if(strcmp(cmd_str,"BY")==0) { // Read the busy signal status
+ if(len <=2) {
+ //send_resp(client_sock,"BY00;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"CA")==0) { // Sets/reads cw auto tune function status
+ if(len <=2) {
+ //send_resp(client_sock,"CA0;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"CG")==0) { // Sets/reads the carrier gain status
+ // 0-100 legal values
+ if(len <=2) {
+ //send_resp(client_sock,"CG000;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"CH")==0) { // Sets the current frequency to call Channel
+ // No response
+ }
+ else if(strcmp(cmd_str,"CI")==0) { // While in VFO mode or memory recall mode, sets freq to the call channel
+ // No response
+ }
+ else if(strcmp(cmd_str,"CM")==0) { // Sets or reads the packet cluster tune f(x) on/off
+ // 0-100 legal values
+ if(len <=2) {
+ //send_resp(client_sock,"CM0;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"CN")==0) { // Sets and reads CTSS function - 01-38 legal values
+ // Stored locally in rigctl - not used.
+ if(len <=2) {
+ sprintf(msg,"CN%02d;",ctcss_tone);
+ send_resp(client_sock,msg);
+ send_resp(client_sock,"?;");
+ } else {
+ ctcss_tone = atoi(&cmd_input[2]);
+ }
+ }
+ else if(strcmp(cmd_str,"CT")==0) { // Sets and reads CTSS function status
+ // Stored locally in rigctl - not used.
+ if(len <=2) {
+ sprintf(msg,"CT%01d;",ctcss_mode);
+ send_resp(client_sock,msg);
+ } else {
+ ctcss_mode = atoi(&cmd_input[2]);
+ }
+ }
+ else if(strcmp(cmd_str,"DC")==0) { // Sets/Reads TX band status
+ if(len <=2) {
+ //send_resp(client_sock,"DC00;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"DN")==0) { // Emulate Mic down key
+ }
+ else if(strcmp(cmd_str,"DQ")==0) { // ETs/and reads the DCS function status
+ if(len <=2) {
+ //send_resp(client_sock,"DQ0;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"EX")==0) { // Set/reads the extension menu
+ // This routine only can look up specific information;
+ // And only performs reads at this point..
+ // EX P1 P1 P1 P2 P2 P3 P4 ; - Read command
+ int p5=0;
+ strncpy(buf,cmd_input,9); // Get the front of the response
+ if(len == 10) { // Read command
+ // CW Sidetone frequendcy
+ if(strncmp(&cmd_input[2],"031",3) == 0) {
+ if(cw_keyer_sidetone_frequency <=400) {
+ p5 = 0;
+ } else if (cw_keyer_sidetone_frequency <=450) {
+ p5 = 1;
+ } else if (cw_keyer_sidetone_frequency <=500) {
+ p5 = 2;
+ } else if (cw_keyer_sidetone_frequency <=550) {
+ p5 = 3;
+ } else if (cw_keyer_sidetone_frequency <=600) {
+ p5 = 4;
+ } else if (cw_keyer_sidetone_frequency <=650) {
+ p5 = 5;
+ } else if (cw_keyer_sidetone_frequency <=700) {
+ p5 = 6;
+ } else if (cw_keyer_sidetone_frequency <=750) {
+ p5 = 7;
+ } else if (cw_keyer_sidetone_frequency <=800) {
+ p5 = 8;
+ } else if (cw_keyer_sidetone_frequency <=850) {
+ p5 = 9;
+ }
+ sprintf(msg,"%s%01d;",buf,p5);
+ send_resp(client_sock,msg);
+ // SPLIT
+ } else if(strncmp(&cmd_input[2],"06A",3) == 0) {
+ sprintf(msg,"%s%01d;",buf,split);
+ send_resp(client_sock,msg);
+ } else {
+ send_resp(client_sock,"?;");
+ }
+ }
+ }
+ else if(strcmp(cmd_str,"FA")==0) { // VFO A frequency
+ // LEN=7 - set frequency
+ // Next data will be rest of freq
+ if(len == 13) { //We are receiving freq info
+ new_freqA = atoll(&cmd_input[2]);
+ set_band(new_freqA,(int)-1);
+ //setFrequency(new_freqA);
+ //g_idle_add(vfo_update,NULL);
+ } else {
+ if(len==2) {
+ //sprintf(msg,"FA%011lld;",getFrequency());
+ sprintf(msg,"FA%011lld;",vfo[VFO_A].frequency);
+ send_resp(client_sock,msg);
+ }
+ }
+ }
+ else if(strcmp(cmd_str,"FB")==0) { // VFO B frequency
+ if(len==13) { //We are receiving freq info
+ new_freqB = atoll(&cmd_input[2]);
+ set_freqB(new_freqB);
+ //setFrequency(new_freqA);
+ //g_idle_add(vfo_update,NULL);
+ } else if(len == 2) {
+ sprintf(msg,"FB%011lld;",vfo[VFO_B].frequency);
+ send_resp(client_sock,msg);
+ }
+ }
+ /* Not supported */
+ else if(strcmp(cmd_str,"FC")==0) { // Set Sub receiver freq
+ // LEN=7 - set frequency
+ // Next data will be rest of freq
+ // Len<7 - frequency?
+ if(len>4) { //We are receiving freq info
+ long long new_freqA = atoll(&cmd_input[2]);
+ //setFrequency(new_freqA);
+ } else {
+ sprintf(msg,"FC%011lld;",rigctl_getFrequency());
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"FD")==0) { // Read the filter display dot pattern
+ send_resp(client_sock,"FD00000000;");
+ }
+ else if(strcmp(cmd_str,"FR")==0) { // Set/reads the extension menu
+ if(len <=2) {
+ if(receivers == 1) {
+ sprintf(msg,"FR0;");
+ } else {
+ sprintf(msg,"FR%1d;",active_receiver->id);
+ }
+ send_resp(client_sock,msg);
+ } else if (receivers != 1) {
+ lcl_cmd = atoi(&cmd_input[2]);
+ if(active_transmitter != lcl_cmd) {
+ split = 1;
+ }
+ if(active_receiver->id != lcl_cmd) {
+ //active_receiver->id = lcl_cmd;
+ active_receiver = receiver[lcl_cmd];
+ g_idle_add(vfo_update,NULL);
+ g_idle_add(active_receiver_changed,NULL);
+ }
+ }
+ }
+ else if(strcmp(cmd_str,"FS")==0) { // Set/reads fine funct status
+ if(len <=2) {
+ send_resp(client_sock,"FS0;");
+ }
+ }
+ else if(strcmp(cmd_str,"FT")==0) { // Sel or reads the transmitters VFO, M, ch or Call comm
+ if(len <=2) {
+ sprintf(msg,"FT%1d",active_transmitter);
+ send_resp(client_sock,msg);
+ } else {
+ lcl_cmd = atoi(&cmd_input[2]);
+ if(lcl_cmd != active_receiver->id) {
+ split = 1;
+ } else {
+ split = 0;
+ }
+ active_transmitter = lcl_cmd;
+ g_idle_add(vfo_update,NULL);
+ }
+ }
+ else if(strcmp(cmd_str,"FW")==0) { // Sets/Reas DSP receive filter width in hz 0-9999hz
+ // CW - legal values 50 80 100 150 200 300 400 500 600 1000 2000
+ // PiHPSDR map 50 100 100 100 250 250 400 500 600 1000
+ // 25 750
+ entry= (BANDSTACK_ENTRY *)
+ bandstack_entry_get_current();
+ FILTER* band_filters=filters[entry->mode];
+ FILTER* band_filter=&band_filters[entry->filter];
+ if(len <=2) {
+ // CW filter high and low are always the same and the filter value is 2*filter val
+ int filter_val = band_filter->high * 2;
+ switch(filter_val) {
+ case 25:
+ case 50:
+ work_int = 50;
+ break;
+ case 100:
+ work_int = 100;
+ break;
+ case 250:
+ work_int = 300;
+ break;
+ case 400:
+ work_int = 400;
+ break;
+ case 500:
+ work_int = 500;
+ break;
+ case 600:
+ work_int = 600;
+ break;
+ case 750:
+ work_int = 1000;
+ break;
+ case 800:
+ work_int = 1000;
+ break;
+ case 1000:
+ work_int = 1000;
+ break;
+ default: work_int = 500;
+ break;
+ }
+ sprintf(msg,"FW%04d;",work_int);
+ #ifdef RIGCTL_DEBUG
+ fprintf(stderr,"RIGCTL: FW Filter Act=%d work_int=%d\n",band_filter->high,work_int);
+ #endif
+ send_resp(client_sock,msg);
+ } else {
+ // Try to set filters here!
+ // CW - legal values 50 80 100 150 200 300 400 500 600 1000 2000
+ // PiHPSDR map 50 100 100 100 250 250 400 500 600 1000
+ // 25 750
+ work_int = atoi(&cmd_input[2]);
+ switch (work_int) {
+
+ case 50: new_low = 25; new_high = 25; break;
+ case 80: new_low = 50; new_high = 50; break;
+ case 100: new_low = 50; new_high = 50; break;
+ case 150: new_low = 50; new_high = 50; break;
+ case 200: new_low = 125; new_high = 125; break;
+ case 300: new_low = 125; new_high = 125; break;
+ case 400: new_low = 200; new_high = 200; break;
+ case 500: new_low = 250; new_high = 250; break;
+ case 600: new_low = 300; new_high = 300; break;
+ case 1000: new_low = 500; new_high = 500; break;
+ case 2000: new_low = 500; new_high = 500; break;
+ default: new_low = band_filter->low;
+ new_high = band_filter->high;
+
+ }
+ #ifdef RIGCTL_DEBUG
+ fprintf(stderr,"RIGCTL: FW Filter new_low=%d new_high=%d\n",new_low,new_high);
+ #endif
+ // entry->filter = new_low * 2 ;
+ //setFilter(new_low,new_high);
+ set_filter(active_receiver,new_low,new_high);
+ g_idle_add(vfo_update,NULL);
+ }
+ }
+ else if(strcmp(cmd_str,"GT")==0) { // Sets/Read AGC constant status 000-020
+ // Map 000 - Off, 001-4 - Fast, 4-9 - Medium 10-14 Slow 15-20 Long
+ //fprintf(stderr,"GT command seen\n");
+ int agc_resp = 0;
+ if(len <=2) {
+
+ switch(active_receiver->agc) {
+ case AGC_OFF : agc_resp = 0; break;
+ case AGC_FAST: agc_resp = 5; break;
+ case AGC_MEDIUM: agc_resp = 10; break;
+ case AGC_SLOW: agc_resp = 15; break;
+ case AGC_LONG: agc_resp = 20; break;
+ default: agc_resp = 0;
+ }
+
+ sprintf(msg,"GT%03d;",agc_resp);
+ send_resp(client_sock,msg);
+ } else {
+ //fprintf(stderr,"GT command Set\n");
+ agc_resp = atoi(&cmd_input[2]);
+
+ // AGC powers of 84 is broken Hamlib...
+ // Hamlib TS-2000 is broken here
+
+ if(agc_resp == 0) {
+ active_receiver->agc = AGC_OFF;
+ } else if(agc_resp >0 && agc_resp <= 5 || (agc_resp == 84)) {
+ active_receiver->agc = AGC_FAST;
+ // fprintf(stderr,"GT command FAST\n");
+ } else if(agc_resp >6 && agc_resp <= 10 || (agc_resp == 2*84)) {
+ active_receiver->agc = AGC_MEDIUM;
+ // fprintf(stderr,"GT command MED\n");
+ } else if(agc_resp >11 && agc_resp <= 15 || (agc_resp == 3*84)) {
+ active_receiver->agc = AGC_SLOW;
+ //fprintf(stderr,"GT command SLOW\n");
+ } else if(agc_resp >16 && agc_resp <= 20 || (agc_resp == 4*84)) {
+ active_receiver->agc = AGC_LONG;
+ // fprintf(stderr,"GT command LONG\n");
+ }
+ g_idle_add(vfo_update,NULL);
+
+ }
+ }
+ else if(strcmp(cmd_str,"ID")==0) { // Read ID - Default to TS-2000 which is type 019.
+ sprintf(msg,"ID019;");
+ send_resp(client_sock,msg);
+ }
+ else if(strcmp(cmd_str,"IF")==0) { // Reads Transceiver status
+ // IF
+ // P1: FFFFFFFFFFF -11 chars : Frequency in Hz (blanks are "0")
+ // P2: OFFS - 4 chars : Offset in powers of 10
+ // P3: RITXIT - 6 chars : RIT/XIT Frequency, Not supported = "000000"
+ // P4: R - 1 char : RIT Status "1"= On, "0"= off
+ // P5: X - 1 char : XIT Status "1"= On, "0"= off
+ // P6: 0 - 1 char : Channel Bank number - not used (see MC command)
+ // P7: 00 - 2 chars : Channel Bank number - not used
+ // P8: C - 1 char : Mox Status "1"= TX, "0"= RX
+ // P9: M - 1 char : Operating mode (see MD command)
+ // P10: V - 1 char : VFO Split status - not supported
+ // P11: 0 - 1 char : Scan status - not supported
+ // P12: A - 1 char : same as FT command
+ // P13: 0 - 1 char : CTCSS tone - not used
+ // P14: 00 - 2 chars : More tone control
+ // P15: 0 - 1 char : Shift status
+
+ // convert first half of the msg
+ // IF P1 P2 P3 P4 P5 P6
+ sprintf(msg,"IF%011lld%04lld%06d%01d%01d%01d",
+ //getFrequency(),
+ rigctl_getFrequency(), // P1
+ step, // P2
+ vfo[active_receiver->id].rit, // P3
+ rit_on(), // P4
+ rit_on(), // P5
+ 0 // P6
+ );
+
+ // convert second half of the msg
+ // P7 P8 P9 P10 P11 P12 P13 P14 P15;
+ sprintf(msg+26,"%02d%01d%01d%01d%01d%01d%01d%02d%01d;",
+ 0, // P7
+ mox, // P8
+ rigctlGetMode(), // P9
+ 0, // P10
+ 0, // P11
+ ft_read(), // P12
+ ctcss_tone, // P13
+ 0, // P14
+ 0); // P15
+ send_resp(client_sock,msg);
+ }
+ else if(strcmp(cmd_str,"IS")==0) { // Sets/Reas IF shift funct status
+ if(len <=2) {
+ send_resp(client_sock,"IS00000;");
+ }
+ }
+ else if(strcmp(cmd_str,"KS")==0) { // Sets/Reads keying freq - 0-060 max
+ if(len <=2) {
+ sprintf(msg,"KS%03d;",cw_keyer_speed);
+ send_resp(client_sock,msg);
+ } else {
+ int key_speed;
+ key_speed = atoi(&cmd_input[2]);
+ if(key_speed >1 && key_speed <= 60) {
+ cw_keyer_speed=key_speed;
+ g_idle_add(vfo_update,NULL);
+ }
+ }
+ }
+ else if(strcmp(cmd_str,"KY")==0) { // Convert char to morse code
+ if(len <=2) {
+ send_resp(client_sock,"KY0;");
+ }
+ }
+ else if(strcmp(cmd_str,"LK")==0) { // Set/read key lock function status
+ if(len <=2) {
+ sprintf(msg,"LK%01d%01d;",locked,locked);
+ send_resp(client_sock,msg);
+ } else {
+ if(cmd_input[3] == '0') {
+ locked = 0;
+ } else if(cmd_input[3] == '1') {
+ locked = 1;
+ }
+ g_idle_add(vfo_update,NULL);
+ }
+ }
+ else if(strcmp(cmd_str,"LM")==0) { // Set/read DRU 3A unit or elect keyer recording status
+ if(len <=2) {
+ send_resp(client_sock,"LM0;");
+ }
+ }
+ else if(strcmp(cmd_str,"LT")==0) { // Set/read Alt function
+ if(len <=2) {
+ send_resp(client_sock,"LT0;");
+ }
+ }
+ else if(strcmp(cmd_str,"MC")==0) { // Recalls or reads memory channel
+ if(len <=2) {
+ send_resp(client_sock,"MC000;"); // Link this to band stack at some point
+ }
+ }
+ else if(strcmp(cmd_str,"MD")==0) { // Mode - digit selects mode
+ // 1 = LSB
+ // 2 = USB
+ // 3 = CWU
+ // 4 = FM
+ // 5 = AM
+ // 6 = DIGL
+ // 7 = CWL
+ // 9 = DIGU
+ int new_mode;
+ if(len > 2) { // Set Mode
+ switch(atoi(&cmd_input[2])) {
+ case 1:
+ new_mode = modeLSB;
+ break;
+ case 2:
+ new_mode = modeUSB;
+ break;
+ case 3:
+ new_mode = modeCWU;
+ break;
+ case 4:
+ new_mode = modeFMN;
+ break;
+ case 5:
+ new_mode = modeAM;
+ break;
+ case 6:
+ new_mode = modeDIGL;
+ break;
+ case 7:
+ new_mode = modeCWL;
+ break;
+ case 9:
+ new_mode = modeDIGU;
+ break;
+ default:
+ break;
+ #ifdef RIGCTL_DEBUG
+ fprintf(stderr,"MD command Unknown\n");
+ #endif
+ }
+ // Other stuff to switch modes goes here..
+ // since new_mode has the interpreted command in
+ // in it now.
+ entry= (BANDSTACK_ENTRY *)
+ bandstack_entry_get_current();
+ entry->mode=new_mode;
+ // BUG - kills the system when there is some
+ // GPIO activity and Mode sets occur. Used twittling the
+ // frequency along with setting mode between USB/LSB with
+ // flrig. Tried doing the g_idle_add trick - but don't know the
+ // the magic to get that to compile without warnings
+ //setMode(entry->mode);
+ set_mode(active_receiver,entry->mode);
+ // Moved the vfo_update down after filter updated. (John G0ORX)
+ //g_idle_add(vfo_update,NULL);
+
+ FILTER* band_filters=filters[entry->mode];
+ FILTER* band_filter=&band_filters[entry->filter];
+ //setFilter(band_filter->low,band_filter->high);
+ set_filter(active_receiver,band_filter->low,band_filter->high);
+ /* Need a way to update VFO info here..*/
+ g_idle_add(vfo_update,NULL);
+ } else { // Read Mode
+ int curr_mode;
+ switch (vfo[active_receiver->id].mode) {
+ case modeLSB: curr_mode = 1;
+ break;
+ case modeUSB: curr_mode = 2;
+ break;
+ case modeCWL: curr_mode = 7; // CWL
+ break;
+ case modeCWU: curr_mode = 3; // CWU
+ break;
+ case modeFMN: curr_mode = 4; // FMN
+ break;
+ case modeAM: curr_mode = 5; // AM
+ break;
+ case modeDIGU: curr_mode = 9; // DIGU
+ break;
+ case modeDIGL: curr_mode = 6; // DIGL
+ break;
+ default:
+ #ifdef RIGCTL_DEBUG
+ fprintf(stderr,
+ "RIGCTL: MD command doesn't support %d\n",
+ vfo[active_receiver->id].mode);
+ #endif
+ break;
+ }
+ sprintf(msg,"MD%1d;",curr_mode);
+ send_resp(client_sock,msg);
+ }
+ }
+ else if(strcmp(cmd_str,"MF")==0) { // Set/read menu A/B
+ if(len <=2) {
+ send_resp(client_sock,"MF0;");
+ }
+ }
+ else if(strcmp(cmd_str,"MG")==0) { // Mike Gain - 3 digit value
+ if(len <=2) {
+ work_int = (int) ((mic_gain +10.0)* 100.0/60.0);
+ sprintf(msg,"MG%03d;",work_int);
+ send_resp(client_sock,msg);
+ } else {
+ int tval = atoi(&cmd_input[2]);
+ new_vol = (double) (tval * 60/100) - 10;
+ //set_mic_gain(new_vol);
+ double *p_mic_gain=malloc(sizeof(double));
+ *p_mic_gain=new_vol;
+ g_idle_add(update_mic_gain,(void *)p_mic_gain);
+ }
+ }
+ else if(strcmp(cmd_str,"ML")==0) { // Set/read the monitor function level
+ if(len <=2) {
+ send_resp(client_sock,"ML000;");
+ }
+ }
+ else if(strcmp(cmd_str,"MO")==0) { // Set Monitor on/off
+ if(len <=2) {
+ send_resp(client_sock,"MO0;");
+ }
+ }
+ /* Not supported */
+ else if(strcmp(cmd_str,"MR")==0) { // Read Memory Channel data
+ sprintf(msg,"MR%1d%02d%02d%011lld%1d%1d%1d%02d%02d%03d%1d%1d%09d%02d%1d%08d;",
+ 0, // P1 - Rx Freq - 1 Tx Freq
+ 0, // P2 Bankd and channel number -- see MC comment
+ 0, // P3 - see MC comment
+ rigctl_getFrequency(), // P4 - frequency
+ rigctlGetMode(), // P5 - Mode
+ locked, // P6 - Locked status
+ 0, // P7 - O-off, 1-tone, 2-CTCSS, 3 =DCS
+ 0, // P8 - Tone Number - see page 35
+ ctcss_tone, // P9 - CTCSS tone number - see CN command
+ 0, // P10 - DCS code - see QC command
+ 0, // P11 - Reverse status
+ 0, // P12 - Shift status - see OS command
+ 0, // P13 - Offset freq - see OS command
+ 0, // P14 - Step Size - see ST command
+ 0, // P15 - Memory Group Number (0-9)
+ 0); // P16 - Memory Name - 8 char max
+ //send_resp(client_sock,msg);
+ send_resp(client_sock,"?;");
+ }
+ else if(strcmp(cmd_str,"MU")==0) { // Set/Read Memory Group Data
+ if(len <=2) {
+ send_resp(client_sock,"MU0000000000;");
+ }
+ }
+ else if(strcmp(cmd_str,"MW")==0) { // Store Data to Memory Channel
+ }
+ else if(strcmp(cmd_str,"NB")==0) { // Set/Read Noise Blanker func status (on/off)
+ if(len <=2) {
+ sprintf(msg,"NB%1d;",active_receiver->snb);
+ send_resp(client_sock,msg);
+ } else {
+ if(cmd_input[2]=='0') { // Turn off ANF
+ active_receiver->snb=0;
+ } else { // Turn on ANF
+ active_receiver->snb=1;
+ }
+ // Update filters
+ SetRXASNBARun(active_receiver->id, active_receiver->snb);
+ g_idle_add(vfo_update,NULL);
+ }
+ }
+ else if(strcmp(cmd_str,"NL")==0) { // Set/Read Noise Reduction Level
+ if(len <=2) {
+ send_resp(client_sock,"NL000;");
+ }
+ }
+ else if(strcmp(cmd_str,"NR")==0) { // Set/Read Noise Reduction function status
+ if(len <=2) {
+/*
+ if(nr_none == 1) {
+ send_resp(client_sock,"NR0;");
+ } else if ((nr_none == 0) && (nr==1)) {
+ send_resp(client_sock,"NR1;");
+ } else if (nr2 == 1) {
+ send_resp(client_sock,"NR2;");
+ } else {
+ send_resp(client_sock,"NR0;");
+ }
+*/
+
+ // FIX now allow multiple set
+ if (active_receiver->nr==1) {
+ send_resp(client_sock,"NR1;");
+ } else {
+ send_resp(client_sock,"NR0;");
+ }
+ } else {
+ if(cmd_input[2] == '0') {
+ active_receiver->nr = 0;
+ active_receiver->nr2 = 0;
+ } else if(cmd_input[2] == '1') {
+ active_receiver->nr = 1;
+ } else if(cmd_input[2] == '2') {
+ active_receiver->nr2 = 1;
+ }
+ SetRXAANRRun(active_receiver->id, active_receiver->nr);
+ SetRXAEMNRRun(active_receiver->id, active_receiver->nr2);
+ g_idle_add(vfo_update,NULL);
+ }
+ }
+ else if(strcmp(cmd_str,"NT")==0) { // Set/Read autonotch function
+ if(len <=2) {
+ sprintf(msg,"NT%1d;",active_receiver->anf);
+ send_resp(client_sock,msg);
+ } else {
+ if(cmd_input[2] == '0') { // Clear ANF
+ active_receiver->anf = 0;
+ } else { // Set ANF
+ active_receiver->anf = 1;
+ }
+ }
+ SetRXAANFRun(active_receiver->id, active_receiver->anf);
+ g_idle_add(vfo_update,NULL);
+ }
+ else if(strcmp(cmd_str,"OF")==0) { // Set/Read Offset freq (9 digits - hz)
+ if(len <=2) {
+ send_resp(client_sock,"OF000000000;");
+ }
+ }
+ /* Not Supported */
+ else if(strcmp(cmd_str,"OI")==0) { // Read Memory Channel Data
+ if(len <=2) {
+ sprintf(msg,"OI%011lld%04d%06d%1d%1d%1d%02d%1d%1d%1d%1d%1d%1d%02d%1d;",
+ rigctl_getFrequency(),
+ 0, // P2 - Freq Step size
+ 0, // P3 - Rit/Xit Freq
+ 0, // P4 - RIT off/Rit On
+ 0, // P5 - XIT off/on
+ 0, // P6 - Channel
+ 0, // P7 - Bank
+ 0, // P8 - 0RX, 1TX
+ rigctlGetMode(), // P10 - MD
+ 0, // P11 - SC command
+ 0, // P12 Split op - SP command
+ 0, // P13 Off, 1, 2,
+ 0,// P14 Tone freq - See TN command
+ 0,0);
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"OS")==0) { // Set/Read Offset freq (9 digits - hz)
+ if(len <=2) {
+ //send_resp(client_sock,"OS0;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"PA")==0) { // Set/Read Preamp function status
+ if(len <=2) {
+ sprintf(msg,"PA0%1d;",enable_tx_equalizer);
+ send_resp(client_sock,msg);
+ } else {
+ if(cmd_input[2] =='0') {
+ enable_tx_equalizer=0;
+ SetTXAEQRun(transmitter->id, enable_tx_equalizer);
+ } else {
+ enable_tx_equalizer=1;
+ SetTXAEQRun(transmitter->id, enable_tx_equalizer);
+ }
+ }
+ }
+ else if(strcmp(cmd_str,"PB")==0) { // Set/Read DRU-3A Playback status
+ if(len <=2) {
+ send_resp(client_sock,"PB0;");
+ }
+ }
+ else if(strcmp(cmd_str,"PC")==0) { // Set/Read Drive Power output
+ if(len<=2) {
+ sprintf(msg,"PC%03d;",(int) drive);
+ send_resp(client_sock,msg);
+ } else {
+ // Power Control - 3 digit number- 0 to 100
+ //Scales to 0.00-1.00
+
+ double drive_val =
+ (double)(atoi(&cmd_input[2]));
+ // setDrive(drive_val);
+ double *p_drive=malloc(sizeof(double));
+ *p_drive=drive_val;
+ g_idle_add(update_drive,(gpointer)p_drive);
+ //set_drive(drive_val);
+ }
+ }
+ else if(strcmp(cmd_str,"PI")==0) { // STore the programmable memory channel
+ }
+ else if(strcmp(cmd_str,"PK")==0) { // Reads the packet cluster data
+ // send_resp(client_sock,"PK000000000000000000000000000000000000000000000000;");
+ send_resp(client_sock,"?;");
+
+ }
+ else if(strcmp(cmd_str,"PL")==0) { // Set/Read Speech processor level
+ // P1 000 - min-100 max
+ // P2 000 - min - 100 max
+ if(len <=2) {
+ // send_resp(client_sock,"PL000000;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"PM")==0) { // Recalls the Programmable memory
+ if(len <=2) {
+ //send_resp(client_sock,"PM0;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"PR")==0) { // Sets/reads the speech processor function on/off
+ // 0 - off, 1=on
+ if(len <=2) {
+ //send_resp(client_sock,"PR0;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"PS")==0) { // Sets/reads Power on/off state
+ // 0 - off, 1=on
+ if(len <=2) {
+ send_resp(client_sock,"PS1;"); // Lets pretend we're powered up ;-)
+ }
+ }
+ else if(strcmp(cmd_str,"QC")==0) { // Sets/reads DCS code
+ // Codes numbered from 000 to 103.
+ if(len <=2) {
+ //send_resp(client_sock,"QC000;"); // Lets pretend we're powered up ;-)
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"QI")==0) { // Store the settings in quick memory
+ }
+ else if(strcmp(cmd_str,"QR")==0) { // Send the Quick memory channel data
+ // P1 - Quick mem off, 1 quick mem on
+ // P2 - Quick mem channel number
+ if(len <=2) {
+ //send_resp(client_sock,"QR00;"); // Lets pretend we're powered up ;-)
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"RA")==0) { // Sets/reads Attenuator function status
+ // 00-off, 1-99 -on - Main and sub receivers reported
+ if(len <=2) {
+ //send_resp(client_sock,"RA0000;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"RC")==0) { // Clears the RIT offset freq
+ }
+ else if(strcmp(cmd_str,"RD")==0) { // Move the RIT offset freq down, slow down the scan speed in scan mode
+ if(len <=2) {
+ vfo[active_receiver->id].rit = vfo[active_receiver->id].rit-rit_increment;
+ sprintf(msg,"RD%1d;",rit_on());
+ send_resp(client_sock,msg);
+ } else {
+ if(len > 3) {
+ // Non scan mode when RDxxxxx; -
+ vfo[active_receiver->id].rit = vfo[active_receiver->id].rit-rit_increment;
+ }
+ }
+ g_idle_add(vfo_update,NULL);
+ }
+ else if(strcmp(cmd_str,"RG")==0) { // RF Gain - 3 digit number
+ // RG123; 0-255 value
+ // Scale from -20 - 120
+ if(len>4) { // Set Audio Gain
+ int base_value = atoi(&cmd_input[2]);
+ double new_gain = ((((double) base_value)/255) * 140) - 20;
+ //set_agc_gain(new_gain);
+ double *p_gain=malloc(sizeof(double));
+ *p_gain=new_gain;
+ g_idle_add(update_agc_gain,(gpointer)p_gain);
+ } else { // Read Audio Gain
+ sprintf(msg,"RG%03d;",((256 * (int) active_receiver->agc_gain)/140)+36);
+ send_resp(client_sock,msg);
+ }
+ }
+ else if(strcmp(cmd_str,"RL")==0) { // Set/read Noise reduction level
+ if(len <=2) {
+ //send_resp(client_sock,"RL00;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"RM")==0) { // Set/read Meter function
+ // P1- 0, unsel, 1 SWR, 2 Comp, 3 ALC
+ // P2 - 4 dig - Meter value in dots - 000-0030
+ if(len <=2) {
+ //send_resp(client_sock,"RM00000;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"RT")==0) { // Set/read the RIT function status
+ if(len <=2) {
+ sprintf(msg,"RT%01d;",rit_on());
+ send_resp(client_sock,msg);
+ } else {
+ if(atoi(&cmd_input[2]) == 0) {
+ vfo[active_receiver->id].rit = 0;
+ }
+ }
+ }
+ else if(strcmp(cmd_str,"RU")==0) { // Set/move RIT frequency up
+ if(len <=2) {
+ vfo[active_receiver->id].rit = vfo[active_receiver->id].rit+rit_increment;
+ sprintf(msg,"RU%01d;",rit_on());
+ send_resp(client_sock,msg);
+ } else {
+ if(len > 3) {
+ vfo[active_receiver->id].rit = vfo[active_receiver->id].rit+rit_increment;
+ }
+ }
+ g_idle_add(vfo_update,NULL);
+ }
+ else if(strcmp(cmd_str,"RX")==0) { // Unkey Xmitter
+ //setMox(0);
+ mox_state=0;
+ g_idle_add(mox_update,(gpointer)mox_state);
+ g_idle_add(vfo_update,NULL);
+ }
+ else if(strcmp(cmd_str,"SA")==0) { // Set/reads satellite mode status
+ // 0-main, 1=sub
+ if(len <=2) {
+ //send_resp(client_sock,"SA000000000000000;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"SB")==0) { // Set/read the SUB TF-W status
+ if(len <=2) {
+ //send_resp(client_sock,"SB0;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"SC")==0) { // Set/read the Scan function status
+ if(len <=2) {
+ //send_resp(client_sock,"SC0;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"SD")==0) { // Set/read CW break-in time delay
+ // 0000-1000 ms (in steps of 50 ms) 0000 is full break in
+ int local_cw_breakin=cw_keyer_hang_time;
+ // Limit report value to 1000 for TS-2000
+ if(local_cw_breakin > 1000) { local_cw_breakin = 1000; }
+ if(len <=2) {
+ sprintf(msg,"SD%04d;",local_cw_breakin);
+ send_resp(client_sock,msg);
+ } else {
+ local_cw_breakin = atoi(&cmd_input[2]);
+ if(cw_keyer_hang_time <= 1000) {
+ if(local_cw_breakin==0) {
+ cw_breakin = 1;
+ } else {
+ cw_breakin = 0;
+ }
+ cw_keyer_hang_time = local_cw_breakin;
+ }
+ }
+ }
+ else if(strcmp(cmd_str,"SH")==0) { // Set/read the DSP filter settings
+ if(len <=2) {
+ // send_resp(client_sock,"SH00;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"SI")==0) { // Enters the satellite memory name
+ }
+ else if(strcmp(cmd_str,"SL")==0) { // Set/read the DSP filter settings - this appears twice? See SH
+ if(len <=2) {
+ //send_resp(client_sock,"SL00;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"SM")==0) { // Read SMETER
+ // SMx; x=0 RX1, x=1 RX2
+ // meter is in dbm - value will be 0<260
+ // Translate to 00-30 for main, 0-15 fo sub
+ // Resp= SMxAABB;
+ // Received range from the SMeter can be -127 for S0, S9 is -73, and S9+60=-13.;
+ // PowerSDR returns S9=0015 code.
+ // Let's make S9 half scale or a value of 70.
+ double level=0.0;
+
+ if(cmd_input[2] == '0') {
+ level = GetRXAMeter(receiver[0]->id, smeter);
+ } else if(cmd_input[2] == '1') {
+ if(receivers==2) {
+ level = GetRXAMeter(receiver[1]->id, smeter);
+ }
+ }
+
+
+ level = GetRXAMeter(active_receiver->id, smeter);
+ // Determine how high above 127 we are..making a range of 114 from S0 to S9+60db
+ // 5 is a fugdge factor that shouldn't be there - but seems to get us to S9=SM015
+ level = abs(127+(level + (double) get_attenuation()))+5;
+
+ // Clip the value just in case
+ if(cmd_input[2] == '0') {
+ new_level = (int) ((level * 30.0)/114.0);
+ // Do saturation check
+ if(new_level < 0) { new_level = 0; }
+ if(new_level > 30) { new_level = 30;}
+ } else { //Assume we are using sub receiver where range is 0-15
+ new_level = (int) ((level * 15.0)/114.0);
+ // Do saturation check
+ if(new_level < 0) { new_level = 0; }
+ if(new_level > 15) { new_level = 15;}
+ }
+ sprintf(msg,"SM%1c%04d;",
+ cmd_input[2],new_level);
+ send_resp(client_sock,msg);
+ }
+ else if(strcmp(cmd_str,"SQ")==0) { // Set/read the squelch level
+ // P1 - 0- main, 1=sub
+ // P2 - 0-255
+ if(len <=3) {
+ sprintf(msg,"SQ%04d;",squelch);
+ send_resp(client_sock,msg);
+ } else {
+ squelch = atoi(&cmd_input[2]);
+ }
+ }
+ else if(strcmp(cmd_str,"SR")==0) { // Resets the transceiver
+ }
+ else if(strcmp(cmd_str,"SS")==0) { // Set/read Scan pause freq
+ if(len <=2) {
+ //send_resp(client_sock,"SS0;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"ST")==0) { // Set/read the multi/ch control freq steps
+ // SSB/CW/FSK - values 00-03
+ // 00: 1KHz, 01: 2.5Khz 02:5KHz 03: 10Khz
+ // AM/FM mode 00-09
+ // 00: 5KHz,
+ // 01: 6.25KHz,
+ // 02:10Khz,
+ // 03: 12.5Khz,
+ // 04: 15Khz,
+ // 05: 20Khz,
+ // 06: 25KHz
+ // 07: 30Khz
+ // 08: 50Khz
+ // 09: 100Khz
+ int coded_step_val;
+ entry= (BANDSTACK_ENTRY *)
+ bandstack_entry_get_current();
+ if(len <=2) {
+ switch(entry->mode) {
+ case modeLSB:
+ case modeUSB:
+ case modeCWL:
+ case modeCWU:
+ case modeDIGU:
+ case modeDIGL:
+ if(step >0 && step <= 1000) {
+ coded_step_val = 0;
+ } else if (step >1000 && step <=2500) {
+ coded_step_val = 1;
+ } else if (step >2500 && step <=5000) {
+ coded_step_val = 2;
+ } else {
+ coded_step_val = 3;
+ }
+ break;
+ case modeFMN:
+ case modeAM:
+ if(step >0 && step <= 5000) {
+ coded_step_val = 0;
+ } else if (step >5000 && step <=6250) {
+ coded_step_val = 1;
+ } else if (step >6250 && step <=10000) {
+ coded_step_val = 2;
+ } else if (step >10000 && step <=12500) {
+ coded_step_val = 3;
+ } else if (step >12500 && step <=15000) {
+ coded_step_val = 4;
+ } else if (step >15000 && step <=20000) {
+ coded_step_val = 5;
+ } else if (step >20000 && step <=25000) {
+ coded_step_val = 6;
+ } else if (step >25000 && step <=30000) {
+ coded_step_val = 7;
+ } else if (step >30000 && step <=50000) {
+ coded_step_val = 8;
+ } else if (step >50000 && step <=100000) {
+ coded_step_val = 9;
+ } else {
+ coded_step_val = 0;
+ }
+ break;
+ }
+ sprintf(msg,"ST%02d;",coded_step_val);
+ send_resp(client_sock,msg);
+ } else {
+ coded_step_val = atoi(&cmd_input[2]);
+ switch(entry->mode) {
+ case modeLSB:
+ case modeUSB:
+ case modeCWL:
+ case modeCWU:
+ case modeDIGU:
+ case modeDIGL:
+ if(coded_step_val==0) { step = 1000;}
+ if(coded_step_val==1) { step = 2500;}
+ if(coded_step_val==2) { step = 5000;}
+ if(coded_step_val==3) { step = 10000;}
+ break;
+ case modeFMN:
+ case modeAM:
+ switch(coded_step_val) {
+ case 0: step = 5000; break;
+ case 1: step = 6250; break;
+ case 2: step = 10000; break;
+ case 3: step = 12500; break;
+ case 4: step = 15000; break;
+ case 5: step = 20000; break;
+ case 6: step = 25000; break;
+ case 7: step = 30000; break;
+ case 8: step = 50000; break;
+ case 9: step = 100000; break;
+ default: break; // No change if not a valid number
+ }
+ default: break; // No change if not a valid number
+ }
+ g_idle_add(vfo_update,NULL);
+ }
+ }
+ else if(strcmp(cmd_str,"SU")==0) { // Set/read the scan pause freq
+ if(len <=2) {
+ //send_resp(client_sock,"SU00000000000;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"SV")==0) { // Execute the memory transfer function
+ }
+ else if(strcmp(cmd_str,"TC")==0) { // Set/read the internal TNC mode
+ if(len <=2) {
+ //send_resp(client_sock,"TC00;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"TD")==0) { // Sends the DTMF memory channel
+ }
+ else if(strcmp(cmd_str,"TI")==0) { // Reads the TNC LED status
+ if(len <=2) {
+ //send_resp(client_sock,"TI00;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"TN")==0) { // Set/Read sub tone freq
+ if(len <=2) {
+ //send_resp(client_sock,"TN00;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"TO")==0) { // Set/Read tone function
+ if(len <=2) {
+ //send_resp(client_sock,"TO0;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"TS")==0) { // Set/Read TF Set function status
+ if(len <=2) {
+ //send_resp(client_sock,"TS0;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"TX")==0) { // Key Xmitter - P1 - transmit on main/sub freq
+
+ /*if(len >=3) {
+ // K5JAE: The TS-2000 real hardware does not respond
+ // to this command, thus hamlib is not expecting response.
+ //send_resp(client_sock,"TX0;");
+ }*/
+ mox_state=1;
+ g_idle_add(mox_update,(gpointer)mox_state);
+ g_idle_add(vfo_update,NULL);
+ }
+ else if(strcmp(cmd_str,"TY")==0) { // Set/Read uP firmware type
+ if(len <=2) {
+ send_resp(client_sock,"TY000;");
+ }
+ }
+ else if(strcmp(cmd_str,"UL")==0) { // Detects the PLL unlock status - this should never occur - xmit only
+ if(len <=2) {
+ //send_resp(client_sock,"UL0;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"UP")==0) { // Emulates the mic up key
+ }
+ else if(strcmp(cmd_str,"VD")==0) { // Sets/Reads VOX dleay time - 0000-3000ms in steps of 150
+ // We want vox_hang variable in PiHPSDR
+ // Max value in variable in ms... so 250 = 250ms
+ if(len <=2) {
+ work_int = (int) vox_hang;
+ sprintf(msg,"VD%04d;",work_int);
+ send_resp(client_sock,msg);
+ } else {
+ work_int = atoi(&cmd_input[2]);
+ // Bounds check for legal values for PiHPSDR
+ if(work_int > 1000) { work_int = 1000; }
+ if(work_int < 0) { work_int = 0; }
+ vox_hang = (double) work_int;
+ #ifdef RIGCTL_DEBUG
+ fprintf(stderr,"RIGCTL: Vox hang=%0.20f\n",vox_hang);
+ #endif
+ }
+ }
+ else if(strcmp(cmd_str,"VG")==0) { // Sets/Reads VOX gain 000-009
+ // We want vox_threshold variable in PiHPSDR
+ // Max value in variable 0.1
+ // 3 char 000-009 valid ranges
+ if(len <=2) {
+ work_int = (int) ((vox_threshold) * 100.0);
+ sprintf(msg,"VG00%1d;",work_int);
+ send_resp(client_sock,msg);
+ } else {
+ // Set the threshold here
+ work_int = atoi(&cmd_input[2]);
+ vox_threshold = ((double) work_int)/100.0;
+ #ifdef RIGCTL_DEBUG
+ fprintf(stderr,"RIGCTL: Vox thresh=%0.20f\n",vox_threshold);
+ #endif
+ }
+ }
+ else if(strcmp(cmd_str,"VR")==0) { // Emulates the voice 1/2 key
+ }
+ else if(strcmp(cmd_str,"VX")==0) { // Sets/reads vox f(x) state
+ if(len <=2) {
+ sprintf(msg,"VX%1d;",vox_enabled);
+ send_resp(client_sock,msg);
+ } else {
+ work_int = atoi(&cmd_input[2]);
+ if(work_int>1) { vox_enabled = 1; vox= 1;}
+ if(work_int<1) { vox_enabled = 0; vox=0; }
+ }
+ }
+ else if(strcmp(cmd_str,"XT")==0) { // Sets/reads the XIT f(x) state
+ if(len <=2) {
+ //send_resp(client_sock,"XT0;");
+ send_resp(client_sock,"?;");
+ }
+ }
+ else if(strcmp(cmd_str,"XX")==0) { //
+ // Format RL01234: First dig 0=neg, 1=pos number
+ // 1-4- digital offset in hertz.
+ if(len > 4) { // It is set instead of a read
+ digl_pol = (cmd_input[2]=='0') ? -1 : 1;
+ digl_offset = atoi(&cmd_input[3]);
+ #ifdef RIGCTL_DEBUG
+ fprintf(stderr,"RIGCTL:RL set %d %d\n",digl_pol,digl_offset);
+ #endif
+ } else {
+ if(digl_pol==1) { // Nah - its a read
+ sprintf(msg,"RL1%04d;",0);
+ } else {
+ sprintf(msg,"RL0%04d;",0);
+ }
+ send_resp(client_sock,msg);
+ #ifdef RIGCTL_DEBUG
+ fprintf(stderr,":%s\n",msg);
+ #endif
+ }
+ }
+ else if(strcmp(cmd_str,"XY")==0) { // set/read RTTY DIGL offset frequency - Not available - just store values
+ // Format RL01234: First dig 0=neg, 1=pos number
+ // 1-4- digital offset in hertz.
+ if(len > 4) { // It is set instead of a read
+ digl_pol = (cmd_input[2]=='0') ? -1 : 1;
+ digl_offset = atoi(&cmd_input[3]);
+ #ifdef RIGCTL_DEBUG
+ fprintf(stderr,"RIGCTL:RL set %d %d\n",digl_pol,digl_offset);
+ #endif
+ } else {
+ if(digl_pol==1) { // Nah - its a read
+ sprintf(msg,"RL1%04d;",0);
+ } else {
+ sprintf(msg,"RL0%04d;",0);
+ }
+ send_resp(client_sock,msg);
+ #ifdef RIGCTL_DEBUG
+ fprintf(stderr,":%s\n",msg);
+ #endif
+ }
+ }
+ else {
+ fprintf(stderr,"RIGCTL: UNKNOWN=%s\n",cmd_str);
+ }
+}
+//
+// End of Parser
+//
+
+
+//
+// 2-25-17 - K5JAE - create each thread with the pointer to the port number
+// (Port numbers now const ints instead of defines..)
+//
+void launch_rigctl () {
+ int err;
+ fprintf(stderr, "LAUNCHING RIGCTL!!\n");
+
+ mutex_a = g_new(GT_MUTEX,1);
+ g_mutex_init(&mutex_a->m);
+
+ mutex_b = g_new(GT_MUTEX,1);
+ g_mutex_init(&mutex_b->m);
+
+ // This routine encapsulates the pthread call
+/*
+ err = pthread_create (&rigctl_a_thread_id,NULL,rigctl_a,NULL);
+ if(err != 0) {
+ fprintf(stderr, "pthread_create failed on rigctl_a launch\n");
+ }
+*/
+
+ rigctl_a_thread_id = g_thread_new( "rigctl a", rigctl, (gpointer)&TelnetPortA);
+ if( ! rigctl_a_thread_id )
+ {
+ fprintf(stderr,"g_thread_new failed on rigctl_a\n");
+ }
+
+
+/*
+ err = pthread_create (&rigctl_b_thread_id,NULL,rigctl_b,NULL);
+ if(err != 0) {
+ fprintf(stderr, "pthread_create failed on rigctl_b launch\n");
+ }
+*/
+
+ rigctl_b_thread_id = g_thread_new( "rigctl b", rigctl, (gpointer)&TelnetPortB);
+ if( ! rigctl_b_thread_id )
+ {
+ fprintf(stderr,"g_thread_new failed on rigctl_b\n");
+ }
+
+/*
+ err = pthread_create (&rigctl_c_thread_id,NULL,rigctl_c,NULL);
+ if(err != 0) {
+ fprintf(stderr, "pthread_create failed on rigctl_c launch\n");
+ }
+*/
+
+ rigctl_c_thread_id = g_thread_new( "rigctl c", rigctl, (gpointer)&TelnetPortC);
+ if( ! rigctl_c_thread_id )
+ {
+ fprintf(stderr,"g_thread_new failed on rigctl_c\n");
+ }
+
+}
+
+
+// Telnet Server launch code below
+// max number of bytes we can get at once
+#define MAXDATASIZE 300
+
+//
+// 2-25-17 - K5JAE - removed duplicate init servers.
+//
+
+
+int init_server ( int * socket_desc_ptr, struct sockaddr_in * client, struct sockaddr_in * server, int telnet_port) {
+ int client_sock;
+ int c;
+ //Create socket
+ *socket_desc_ptr = socket(AF_INET , SOCK_STREAM , 0);
+
+ if (*socket_desc_ptr == -1)
+ {
+ fprintf(stderr,"RIGCTL: Could not create socket");
+ }
+ fprintf(stderr, "RIGCTL: Socket created\n");
+
+ //Prepare the sockaddr_in structure
+ server->sin_family = AF_INET;
+ server->sin_addr.s_addr = INADDR_ANY;
+ server->sin_port = htons( telnet_port );
+
+ //Bind
+ if( bind(*socket_desc_ptr,(struct sockaddr *) server , sizeof(struct sockaddr_in)) < 0)
+ {
+ //print the error message
+ fprintf(stderr,"RIGCTL: bind failed. Error\n");
+ return 1;
+ }
+ fprintf(stderr,"RIGCTL: Bind done on port %d\n",telnet_port);
+
+ //Listen
+ listen(*socket_desc_ptr, 3);
+
+ //Accept and incoming connection
+ fprintf(stderr,"RIGCTL: Waiting for incoming connections...\n");
+ c = sizeof(struct sockaddr_in);
+
+ //accept connection from an incoming client
+ client_sock = accept(*socket_desc_ptr,(struct sockaddr *)client, (socklen_t*)&c);
+ if (client_sock < 0)
+ {
+ fprintf(stderr,"RIGCTL: Accept failed\n");
+ }
+ fprintf(stderr,"RIGCTL: Connection accepted\n");
+
+ return client_sock;
+}
+
+int rigctlGetMode() {
+ switch(vfo[active_receiver->id].mode) {
+ case modeLSB: return(1); // LSB
+ case modeUSB: return(2); // USB
+ case modeCWL: return(7); // CWL
+ case modeCWU: return(3); // CWU
+ case modeFMN: return(4); // FMN
+ case modeAM: return(5); // AM
+ case modeDIGU: return(9); // DIGU
+ case modeDIGL: return(6); // DIGL
+ default: return(0);
+ }
+}
+
+int rigctlSetFilterLow(int val){
+};
+int rigctlSetFilterHigh(int val){
+};
+
+void set_band(long long new_freqA, int ctl) {
+
+ fprintf(stderr,"set_band: f=%11lld ctl=%d\n",new_freqA,ctl );
+ BANDSTACK_ENTRY *entry;
+ BAND *band;
+ FILTER* band_filters;
+ FILTER* band_filter;
+
+ int b = get_band_from_frequency(new_freqA);
+
+ if(b == -1) { // Out of ham bands...
+ fprintf(stderr,"set_band: out of ham bands\n");
+ setFrequency(new_freqA);
+ g_idle_add(vfo_update,NULL);
+ return;
+ }
+
+ band=band_set_current(b);
+
+ entry=bandstack_entry_next();
+ entry->mode = vfo[VFO_A].mode;
+ set_mode(active_receiver,entry->mode); // From current band setting
+
+
+ band_filters=filters[entry->mode];
+ band_filter=&band_filters[entry->filter];
+
+ set_filter(active_receiver,band_filter->low,band_filter->high);
+ setFrequency(new_freqA);
+
+ // BAND *band=band_get_current_band();
+ band=band_set_current(b);
+ if(active_receiver->id==0) {
+ set_alex_rx_antenna(band->alexRxAntenna);
+ set_alex_tx_antenna(band->alexTxAntenna);
+ set_alex_attenuation(band->alexAttenuation);
+ }
+
+ //setFrequency(new_freqA);
+ g_idle_add(vfo_update,NULL);
+
+ calcDriveLevel();
+ calcTuneDriveLevel();
+}
+
+void set_freqB(long long new_freqB) {
+
+ //BANDSTACK_ENTRY *bandstack = bandstack_entry_get_current();
+ //bandstack->frequencyB = new_freqB;
+ //frequencyB = new_freqB;
+ vfo[VFO_B].frequency = new_freqB;
+ g_idle_add(vfo_update,NULL);
+}
#define RIGCTL_H
void launch_rigctl ();
-void parse_cmd(char *,int);
int rigctlGetMode();
char * rigctlGetFilter();
-void set_band(long long);
+void set_freqB(long long);
+void set_band(long long, int);
+extern int cat_control;
#endif // RIGCTL_H
set_button_text_color(ctun_b,"red");
} else {
set_button_text_color(ctun_b,"black");
- if(ddsOffset!=0) {
- ddsOffset=0;
- wdsp_set_offset(ddsOffset);
- vfo_update(NULL);
- }
+ vfo[active_receiver->id].offset=0;
+ set_offset(active_receiver,0);
+ vfo_update(NULL);
}
return TRUE;
}
static gboolean rit_timer_cb(gpointer data) {
+ int v=active_receiver->id;
if((GtkWidget*)data==rit_plus_b) {
- rit+=rit_increment;
+ vfo[v].rit+=rit_increment;
} else {
- rit-=rit_increment;
+ vfo[v].rit-=rit_increment;
}
- if(rit>1000) rit=1000;
- if(rit<-1000) rit=-1000;
+ if(vfo[v].rit>1000) vfo[v].rit=1000;
+ if(vfo[v].rit<-1000) vfo[v].rit=-1000;
vfo_update(NULL);
return TRUE;
}
if(rit_enabled) {
rit_enabled=FALSE;
set_button_text_color(rit_b,"black");
- rit=0;
+ vfo[active_receiver->id].offset=0;
gtk_widget_set_sensitive(rit_plus_b,FALSE);
gtk_widget_set_sensitive(rit_minus_b,FALSE);
} else {
}
static gboolean rit_step_pressed_event_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ int v=active_receiver->id;
if(widget==rit_plus_b) {
- rit+=rit_increment;
+ vfo[v].rit+=rit_increment;
} else {
- rit-=rit_increment;
+ vfo[v].rit-=rit_increment;
}
- if(rit>1000) rit=1000;
- if(rit<-1000) rit=-1000;
+ if(vfo[v].rit>1000) vfo[v].rit=1000;
+ if(vfo[v].rit<-1000) vfo[v].rit=-1000;
vfo_update(NULL);
rit_timer=g_timeout_add(200,rit_timer_cb,widget);
return TRUE;
--- /dev/null
+/* Copyright (C)
+* 2015 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*/
+
+#include <gtk/gtk.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "audio.h"
+#include "new_menu.h"
+#include "rx_menu.h"
+#include "band.h"
+#include "discovered.h"
+#include "filter.h"
+#include "radio.h"
+#include "receiver.h"
+
+static GtkWidget *parent_window=NULL;
+
+static GtkWidget *menu_b=NULL;
+
+static GtkWidget *dialog=NULL;
+
+static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ if(dialog!=NULL) {
+ gtk_widget_destroy(dialog);
+ dialog=NULL;
+ sub_menu=NULL;
+ }
+ return TRUE;
+}
+
+static void dither_cb(GtkWidget *widget, gpointer data) {
+ active_receiver->dither=active_receiver->dither==1?0:1;
+}
+
+static void random_cb(GtkWidget *widget, gpointer data) {
+ active_receiver->random=active_receiver->random==1?0:1;
+}
+
+static void preamp_cb(GtkWidget *widget, gpointer data) {
+ active_receiver->preamp=active_receiver->preamp==1?0:1;
+}
+
+static void sample_rate_cb(GtkWidget *widget, gpointer data) {
+ receiver_change_sample_rate(active_receiver,(int)data);
+}
+
+static void adc_cb(GtkWidget *widget, gpointer data) {
+ receiver_change_adc(active_receiver,(int)data);
+}
+
+static void local_audio_cb(GtkWidget *widget, gpointer data) {
+ if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
+ if(audio_open_output(active_receiver)==0) {
+ active_receiver->local_audio=1;
+ } else {
+ active_receiver->local_audio=0;
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
+ }
+ } else {
+ if(active_receiver->local_audio) {
+ active_receiver->local_audio=0;
+ audio_close_output(active_receiver);
+ }
+ }
+}
+
+static void local_output_changed_cb(GtkWidget *widget, gpointer data) {
+ active_receiver->audio_device=(int)(long)data;
+ if(active_receiver->local_audio) {
+ audio_close_output(active_receiver);
+ if(audio_open_output(active_receiver)==0) {
+ active_receiver->local_audio=1;
+ }
+ }
+}
+
+static void audio_channel_cb(GtkWidget *widget, gpointer data) {
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
+ active_receiver->audio_channel=(int)data;
+ }
+}
+
+void rx_menu(GtkWidget *parent) {
+ char label[32];
+ GtkWidget *adc_b;
+ int i;
+ parent_window=parent;
+
+ dialog=gtk_dialog_new();
+ gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window));
+ gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE);
+
+ GdkRGBA color;
+ color.red = 1.0;
+ color.green = 1.0;
+ color.blue = 1.0;
+ color.alpha = 1.0;
+ gtk_widget_override_background_color(dialog,GTK_STATE_FLAG_NORMAL,&color);
+
+ GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+
+ GtkWidget *grid=gtk_grid_new();
+ gtk_grid_set_column_spacing (GTK_GRID(grid),10);
+ //gtk_grid_set_row_spacing (GTK_GRID(grid),10);
+ //gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
+ //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
+
+ GtkWidget *close_b=gtk_button_new_with_label("Close RX");
+ g_signal_connect (close_b, "button_press_event", G_CALLBACK(close_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1);
+
+ sprintf(label,"RX %d VFO %s",active_receiver->id,active_receiver->id==0?"A":"B");
+ GtkWidget *rx_label=gtk_label_new(label);
+ gtk_grid_attach(GTK_GRID(grid),rx_label,1,0,1,1);
+
+ int x=0;
+
+ switch(protocol) {
+ case NEW_PROTOCOL:
+ {
+ GtkWidget *sample_rate_label=gtk_label_new("Sample Rate");
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_label,x,1,1,1);
+
+ GtkWidget *sample_rate_48=gtk_radio_button_new_with_label(NULL,"48000");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_48), active_receiver->sample_rate==48000);
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_48,x,2,1,1);
+ g_signal_connect(sample_rate_48,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)48000);
+
+ GtkWidget *sample_rate_96=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_48),"96000");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_96), active_receiver->sample_rate==96000);
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_96,x,3,1,1);
+ g_signal_connect(sample_rate_96,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)96000);
+
+ GtkWidget *sample_rate_192=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_96),"192000");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_192), active_receiver->sample_rate==192000);
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_192,x,4,1,1);
+ g_signal_connect(sample_rate_192,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)192000);
+
+ GtkWidget *sample_rate_384=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_192),"384000");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_384), active_receiver->sample_rate==384000);
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_384,x,5,1,1);
+ g_signal_connect(sample_rate_384,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)384000);
+
+#ifndef GPIO
+ GtkWidget *sample_rate_768=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_384),"768000");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_768), active_receiver->sample_rate==768000);
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_768,x,6,1,1);
+ 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");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_1536), active_receiver->sample_rate==1536000);
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_1536,x,7,1,1);
+ g_signal_connect(sample_rate_1536,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)1536000);
+#endif
+ }
+ x++;
+ break;
+
+#ifdef LIMESDR
+ case LIMESDR_PROTOCOL:
+ {
+ GtkWidget *sample_rate_label=gtk_label_new("Sample Rate");
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_label,x,1,1,1);
+
+ GtkWidget *sample_rate_1M=gtk_radio_button_new_with_label(NULL,"1000000");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_1M), active_receiver->sample_rate==1000000);
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_1M,x,2,1,1);
+ g_signal_connect(sample_rate_1M,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)1000000);
+
+ GtkWidget *sample_rate_2M=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_1M),"2000000");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_2M), active_receiver->sample_rate==2000000);
+ gtk_grid_attach(GTK_GRID(grid),sample_rate_2M,x,3,1,1);
+ g_signal_connect(sample_rate_2M,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)2000000);
+ }
+ x++;
+ break;
+#endif
+ }
+
+ switch(protocol) {
+ case ORIGINAL_PROTOCOL:
+ case NEW_PROTOCOL:
+ {
+ GtkWidget *dither_b=gtk_check_button_new_with_label("Dither");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dither_b), active_receiver->dither);
+ gtk_grid_attach(GTK_GRID(grid),dither_b,x,2,1,1);
+ g_signal_connect(dither_b,"toggled",G_CALLBACK(dither_cb),NULL);
+
+ GtkWidget *random_b=gtk_check_button_new_with_label("Random");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (random_b), active_receiver->random);
+ gtk_grid_attach(GTK_GRID(grid),random_b,x,3,1,1);
+ g_signal_connect(random_b,"toggled",G_CALLBACK(random_cb),NULL);
+
+ if((protocol==ORIGINAL_PROTOCOL && device==DEVICE_METIS) ||
+#ifdef USBOZY
+ (protocol==ORIGINAL_PROTOCOL && device==DEVICE_OZY) ||
+#endif
+ (protocol==NEW_PROTOCOL && device==NEW_DEVICE_ATLAS)) {
+
+ GtkWidget *preamp_b=gtk_check_button_new_with_label("Preamp");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (preamp_b), active_receiver->preamp);
+ gtk_grid_attach(GTK_GRID(grid),preamp_b,x,4,1,1);
+ g_signal_connect(preamp_b,"toggled",G_CALLBACK(preamp_cb),NULL);
+ }
+ }
+ x++;
+ break;
+ default:
+ break;
+ }
+
+ int n_adc=1;
+ switch(protocol) {
+ case ORIGINAL_PROTOCOL:
+ switch(device) {
+ case DEVICE_METIS:
+ n_adc=1; // FIX for multiple Mercury cards
+ break;
+ case DEVICE_HERMES:
+ case DEVICE_HERMES_LITE:
+ n_adc=1;
+ break;
+ default:
+ n_adc=2;
+ break;
+ }
+ break;
+ case NEW_PROTOCOL:
+ switch(device) {
+ case NEW_DEVICE_ATLAS:
+ n_adc=1; // FIX for multiple Mercury cards
+ break;
+ case NEW_DEVICE_HERMES:
+ case NEW_DEVICE_HERMES2:
+ case NEW_DEVICE_HERMES_LITE:
+ n_adc=1;
+ break;
+ default:
+ n_adc=2;
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if(n_adc>1) {
+ for(i=0;i<n_adc;i++) {
+ sprintf(label,"ADC-%d",i);
+ if(i==0) {
+ adc_b=gtk_radio_button_new_with_label(NULL,label);
+ } else {
+ adc_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(adc_b),label);
+ }
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (adc_b), active_receiver->adc==i);
+ gtk_grid_attach(GTK_GRID(grid),adc_b,x,2+i,1,1);
+ g_signal_connect(adc_b,"pressed",G_CALLBACK(adc_cb),(gpointer *)i);
+ }
+ x++;
+ }
+
+
+ int row=0;
+ if(n_output_devices>0) {
+ GtkWidget *local_audio_b=gtk_check_button_new_with_label("Local Audio Output");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (local_audio_b), active_receiver->local_audio);
+ gtk_widget_show(local_audio_b);
+ gtk_grid_attach(GTK_GRID(grid),local_audio_b,x,++row,1,1);
+ g_signal_connect(local_audio_b,"toggled",G_CALLBACK(local_audio_cb),NULL);
+
+ if(active_receiver->audio_device==-1) active_receiver->audio_device=0;
+
+ for(i=0;i<n_output_devices;i++) {
+ GtkWidget *output;
+ if(i==0) {
+ output=gtk_radio_button_new_with_label(NULL,output_devices[i]);
+ } else {
+ output=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(output),output_devices[i]);
+ }
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (output), active_receiver->audio_device==i);
+ gtk_widget_show(output);
+ gtk_grid_attach(GTK_GRID(grid),output,x,++row,1,1);
+ g_signal_connect(output,"pressed",G_CALLBACK(local_output_changed_cb),(gpointer *)i);
+ }
+
+ row=0;
+ x++;
+
+ GtkWidget *stereo_b=gtk_radio_button_new_with_label(NULL,"Stereo");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (stereo_b), active_receiver->audio_channel==STEREO);
+ gtk_widget_show(stereo_b);
+ gtk_grid_attach(GTK_GRID(grid),stereo_b,x,++row,1,1);
+ g_signal_connect(stereo_b,"toggled",G_CALLBACK(audio_channel_cb),(gpointer)STEREO);
+
+ GtkWidget *left_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(stereo_b),"Left");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (left_b), active_receiver->audio_channel==LEFT);
+ gtk_widget_show(left_b);
+ gtk_grid_attach(GTK_GRID(grid),left_b,x,++row,1,1);
+ g_signal_connect(left_b,"toggled",G_CALLBACK(audio_channel_cb),(gpointer)LEFT);
+
+ GtkWidget *right_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(left_b),"Right");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (right_b), active_receiver->audio_channel==RIGHT);
+ gtk_widget_show(right_b);
+ gtk_grid_attach(GTK_GRID(grid),right_b,x,++row,1,1);
+ g_signal_connect(right_b,"toggled",G_CALLBACK(audio_channel_cb),(gpointer)RIGHT);
+ }
+
+ gtk_container_add(GTK_CONTAINER(content),grid);
+
+ sub_menu=dialog;
+
+ gtk_widget_show_all(dialog);
+
+}
+
--- /dev/null
+/* Copyright (C)
+* 2015 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*/
+
+extern void rx_menu(GtkWidget *parent);
--- /dev/null
+/* Copyright (C)
+* 2015 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*/
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <math.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <semaphore.h>
+#include "agc.h"
+#include "band.h"
+#include "channel.h"
+#include "discovered.h"
+#include "radio.h"
+#include "receiver.h"
+#include "transmitter.h"
+#include "rx_panadapter.h"
+#include "vfo.h"
+#include "mode.h"
+#ifdef FREEDV
+#include "freedv.h"
+#endif
+#include "gpio.h"
+
+//static float panadapter_max=-60.0;
+//static float panadapter_min=-160.0;
+
+static gfloat filter_left;
+static gfloat filter_right;
+
+/* Create a new surface of the appropriate size to store our scribbles */
+static gboolean
+panadapter_configure_event_cb (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer data)
+{
+
+ RECEIVER *rx=(RECEIVER *)data;
+
+ int display_width=gtk_widget_get_allocated_width (widget);
+ int display_height=gtk_widget_get_allocated_height (widget);
+
+ if (rx->panadapter_surface)
+ cairo_surface_destroy (rx->panadapter_surface);
+
+ rx->panadapter_surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget),
+ CAIRO_CONTENT_COLOR,
+ display_width,
+ display_height);
+
+ cairo_t *cr=cairo_create(rx->panadapter_surface);
+ cairo_set_source_rgb(cr, 0, 0, 0);
+ cairo_paint(cr);
+ cairo_destroy(cr);
+ return TRUE;
+}
+
+/* Redraw the screen from the surface. Note that the ::draw
+ * signal receives a ready-to-be-used cairo_t that is already
+ * clipped to only draw the exposed areas of the widget
+ */
+static gboolean
+panadapter_draw_cb (GtkWidget *widget,
+ cairo_t *cr,
+ gpointer data)
+{
+ RECEIVER *rx=(RECEIVER *)data;
+ if(rx->panadapter_surface) {
+ cairo_set_source_surface (cr, rx->panadapter_surface, 0, 0);
+ cairo_paint (cr);
+ }
+
+ return TRUE;
+}
+
+static gboolean panadapter_button_press_event_cb(GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ return receiver_button_press_event(widget,event,data);
+}
+
+static gboolean panadapter_button_release_event_cb(GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ return receiver_button_release_event(widget,event,data);
+}
+
+static gboolean panadapter_motion_notify_event_cb(GtkWidget *widget, GdkEventMotion *event, gpointer data) {
+ return receiver_motion_notify_event(widget,event,data);
+}
+
+static gboolean panadapter_scroll_event_cb(GtkWidget *widget, GdkEventScroll *event, gpointer data) {
+ return receiver_scroll_event(widget,event,data);
+}
+
+void rx_panadapter_update(RECEIVER *rx) {
+ int i;
+ int result;
+ float *samples;
+ float saved_max;
+ float saved_min;
+ cairo_text_extents_t extents;
+
+ gboolean active=active_receiver==rx;
+
+ int display_width=gtk_widget_get_allocated_width (rx->panadapter);
+ int display_height=gtk_widget_get_allocated_height (rx->panadapter);
+
+ samples=rx->pixel_samples;
+
+ //clear_panadater_surface();
+ cairo_t *cr;
+ cr = cairo_create (rx->panadapter_surface);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_rectangle(cr,0,0,display_width,display_height);
+ cairo_fill(cr);
+ //cairo_paint (cr);
+
+ // filter
+ cairo_set_source_rgb (cr, 0.25, 0.25, 0.25);
+ filter_left=(double)display_width/2.0+(((double)rx->filter_low+vfo[rx->id].offset)/rx->hz_per_pixel);
+ filter_right=(double)display_width/2.0+(((double)rx->filter_high+vfo[rx->id].offset)/rx->hz_per_pixel);
+ cairo_rectangle(cr, filter_left, 0.0, filter_right-filter_left, (double)display_height);
+ cairo_fill(cr);
+
+ // plot the levels
+ if(active) {
+ cairo_set_source_rgb (cr, 0, 1, 1);
+ } else {
+ cairo_set_source_rgb (cr, 0, 0.5, 0.5);
+ }
+
+ double dbm_per_line=(double)display_height/((double)rx->panadapter_high-(double)rx->panadapter_low);
+ cairo_set_line_width(cr, 1.0);
+ cairo_select_font_face(cr, "FreeMono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+ cairo_set_font_size(cr, 12);
+ char v[32];
+
+ for(i=rx->panadapter_high;i>=rx->panadapter_low;i--) {
+ int mod=abs(i)%20;
+ if(mod==0) {
+ double y = (double)(rx->panadapter_high-i)*dbm_per_line;
+ cairo_move_to(cr,0.0,y);
+ cairo_line_to(cr,(double)display_width,y);
+
+ sprintf(v,"%d dBm",i);
+ cairo_move_to(cr, 1, y);
+ cairo_show_text(cr, v);
+ }
+ }
+ cairo_stroke(cr);
+
+ // plot frequency markers
+ long long f;
+ long divisor=20000;
+ long half=(long)rx->sample_rate/2L;
+ long long frequency=vfo[rx->id].frequency;
+ switch(rx->sample_rate) {
+ case 48000:
+ divisor=5000L;
+ break;
+ case 96000:
+ case 100000:
+ divisor=10000L;
+ break;
+ case 192000:
+ divisor=20000L;
+ break;
+ case 384000:
+ divisor=25000L;
+ break;
+ case 768000:
+ divisor=50000L;
+ break;
+ case 1048576:
+ case 1536000:
+ case 2097152:
+ divisor=100000L;
+ break;
+ }
+ for(i=0;i<display_width;i++) {
+ f = frequency - half + (long) (rx->hz_per_pixel * i);
+ if (f > 0) {
+ if ((f % divisor) < (long) rx->hz_per_pixel) {
+ cairo_set_line_width(cr, 1.0);
+ //cairo_move_to(cr,(double)i,0.0);
+ cairo_move_to(cr,(double)i,10.0);
+ cairo_line_to(cr,(double)i,(double)display_height);
+
+ cairo_select_font_face(cr, "FreeMono",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_BOLD);
+ cairo_set_font_size(cr, 12);
+ char v[32];
+ sprintf(v,"%0lld.%03lld",f/1000000,(f%1000000)/1000);
+ //cairo_move_to(cr, (double)i, (double)(display_height-10));
+ cairo_text_extents(cr, v, &extents);
+ cairo_move_to(cr, (double)i-(extents.width/2.0), 10.0);
+ cairo_show_text(cr, v);
+ }
+ }
+ }
+ cairo_stroke(cr);
+
+ // band edges
+ long long min_display=frequency-half;
+ long long max_display=frequency+half;
+ BAND *band=band_get_band(vfo[rx->id].band);
+ if(band->frequencyMin!=0LL) {
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_set_line_width(cr, 2.0);
+ if((min_display<band->frequencyMin)&&(max_display>band->frequencyMin)) {
+ i=(band->frequencyMin-min_display)/(long long)rx->hz_per_pixel;
+ cairo_move_to(cr,(double)i,0.0);
+ cairo_line_to(cr,(double)i,(double)display_height);
+ cairo_stroke(cr);
+ }
+ if((min_display<band->frequencyMax)&&(max_display>band->frequencyMax)) {
+ i=(band->frequencyMax-min_display)/(long long)rx->hz_per_pixel;
+ cairo_move_to(cr,(double)i,0.0);
+ cairo_line_to(cr,(double)i,(double)display_height);
+ cairo_stroke(cr);
+ }
+ }
+
+ // agc
+ if(rx->agc!=AGC_OFF) {
+ double hang=0.0;
+ double thresh=0;
+
+ GetRXAAGCHangLevel(rx->id, &hang);
+ GetRXAAGCThresh(rx->id, &thresh, 4096.0, (double)rx->sample_rate);
+
+ double knee_y=thresh+(double)get_attenuation();
+ knee_y = floor((rx->panadapter_high - knee_y)
+ * (double) display_height
+ / (rx->panadapter_high - rx->panadapter_low));
+
+ double hang_y=hang+(double)get_attenuation();
+ hang_y = floor((rx->panadapter_high - hang_y)
+ * (double) display_height
+ / (rx->panadapter_high - rx->panadapter_low));
+
+//fprintf(stderr,"hang=%f thresh=%f hang_y=%f knee_y=%f\n",rx1_hang,rx1_thresh,hang_y,knee_y);
+ if(rx->agc!=AGC_MEDIUM && rx->agc!=AGC_FAST) {
+ if(active) {
+ cairo_set_source_rgb (cr, 1.0, 1.0, 0.0);
+ } else {
+ cairo_set_source_rgb (cr, 0.5, 0.5, 0.0);
+ }
+ cairo_move_to(cr,40.0,hang_y-8.0);
+ cairo_rectangle(cr, 40, hang_y-8.0,8.0,8.0);
+ cairo_fill(cr);
+ cairo_move_to(cr,40.0,hang_y);
+ cairo_line_to(cr,(double)display_width-40.0,hang_y);
+ cairo_stroke(cr);
+ cairo_move_to(cr,48.0,hang_y);
+ cairo_show_text(cr, "-H");
+ }
+
+ if(active) {
+ cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
+ } else {
+ cairo_set_source_rgb (cr, 0.0, 0.5, 0.0);
+ }
+ cairo_move_to(cr,40.0,knee_y-8.0);
+ cairo_rectangle(cr, 40, knee_y-8.0,8.0,8.0);
+ cairo_fill(cr);
+ cairo_move_to(cr,40.0,knee_y);
+ cairo_line_to(cr,(double)display_width-40.0,knee_y);
+ cairo_stroke(cr);
+ cairo_move_to(cr,48.0,knee_y);
+ cairo_show_text(cr, "-G");
+ }
+
+
+ // cursor
+ if(active) {
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ } else {
+ cairo_set_source_rgb (cr, 0.5, 0, 0);
+ }
+ cairo_set_line_width(cr, 1.0);
+ cairo_move_to(cr,(double)(display_width/2.0)+(vfo[rx->id].offset/rx->hz_per_pixel),0.0);
+ cairo_line_to(cr,(double)(display_width/2.0)+(vfo[rx->id].offset/rx->hz_per_pixel),(double)display_height);
+ cairo_stroke(cr);
+
+ // signal
+ double s1,s2;
+ samples[0]=-200.0;
+ samples[display_width-1]=-200.0;
+
+ s1=(double)samples[0]+(double)get_attenuation();
+ s1 = floor((rx->panadapter_high - s1)
+ * (double) display_height
+ / (rx->panadapter_high - rx->panadapter_low));
+ cairo_move_to(cr, 0.0, s1);
+ for(i=1;i<display_width;i++) {
+ s2=(double)samples[i]+(double)get_attenuation();
+ s2 = floor((rx->panadapter_high - s2)
+ * (double) display_height
+ / (rx->panadapter_high - rx->panadapter_low));
+ cairo_line_to(cr, (double)i, s2);
+ }
+
+ if(display_filled) {
+ cairo_close_path (cr);
+ if(active) {
+ cairo_set_source_rgba(cr, 1, 1, 1,0.5);
+ } else {
+ cairo_set_source_rgba(cr, 0.5, 0.5, 0.5,0.5);
+ }
+ cairo_fill_preserve (cr);
+ }
+ if(active) {
+ cairo_set_source_rgb(cr, 1, 1, 1);
+ } else {
+ cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
+ }
+ cairo_set_line_width(cr, 1.0);
+ cairo_stroke(cr);
+
+#ifdef FREEDV
+ int mode=rx->mode;
+ if(mode==modeFREEDV) {
+ cairo_set_source_rgb(cr, 0, 1, 0);
+ cairo_set_font_size(cr, 16);
+ cairo_text_extents(cr, freedv_text_data, &extents);
+ cairo_move_to(cr, (double)display_width/2.0-(extents.width/2.0),(double)display_height-2.0);
+ cairo_show_text(cr, freedv_text_data);
+ }
+#endif
+
+#ifdef GPIO
+ if(active) {
+ cairo_set_source_rgb(cr,1,1,0);
+ cairo_set_font_size(cr,12);
+ if(ENABLE_E1_ENCODER) {
+ cairo_move_to(cr, display_width-100,20);
+ cairo_show_text(cr, encoder_string[e1_encoder_action]);
+ }
+
+ if(ENABLE_E2_ENCODER) {
+ cairo_move_to(cr, display_width-100,40);
+ cairo_show_text(cr, encoder_string[e2_encoder_action]);
+ }
+
+ if(ENABLE_E3_ENCODER) {
+ cairo_move_to(cr, display_width-100,60);
+ cairo_show_text(cr, encoder_string[e3_encoder_action]);
+ }
+ }
+#endif
+
+ cairo_destroy (cr);
+ gtk_widget_queue_draw (rx->panadapter);
+
+}
+
+void rx_panadapter_init(RECEIVER *rx, int width,int height) {
+
+ int display_width=width;
+ int display_height=height;
+
+ rx->panadapter_surface=NULL;
+ rx->panadapter = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (rx->panadapter, width, height);
+
+ /* Signals used to handle the backing surface */
+ g_signal_connect (rx->panadapter, "draw",
+ G_CALLBACK (panadapter_draw_cb), rx);
+ g_signal_connect (rx->panadapter,"configure-event",
+ G_CALLBACK (panadapter_configure_event_cb), rx);
+
+ /* Event signals */
+ g_signal_connect (rx->panadapter, "motion-notify-event",
+ G_CALLBACK (panadapter_motion_notify_event_cb), rx);
+ g_signal_connect (rx->panadapter, "button-press-event",
+ G_CALLBACK (panadapter_button_press_event_cb), rx);
+ g_signal_connect (rx->panadapter, "button-release-event",
+ G_CALLBACK (panadapter_button_release_event_cb), rx);
+ g_signal_connect(rx->panadapter,"scroll_event",
+ G_CALLBACK(panadapter_scroll_event_cb),rx);
+
+ /* Ask to receive events the drawing area doesn't normally
+ * subscribe to. In particular, we need to ask for the
+ * button press and motion notify events that want to handle.
+ */
+ gtk_widget_set_events (rx->panadapter, gtk_widget_get_events (rx->panadapter)
+ | GDK_BUTTON_PRESS_MASK
+ | GDK_BUTTON_RELEASE_MASK
+ | GDK_BUTTON1_MOTION_MASK
+ | GDK_SCROLL_MASK
+ | GDK_POINTER_MOTION_MASK
+ | GDK_POINTER_MOTION_HINT_MASK);
+
+}
--- /dev/null
+/* Copyright (C)
+* 2015 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*/
+
+#ifndef _PANADAPTER_H
+#define _PANADAPTER_H
+
+void rx_panadapter_update(RECEIVER* rx);
+
+void rx_panadapter_init(RECEIVER *rx,int width,int height);
+
+
+#endif
#include "channel.h"
#include "wdsp.h"
#include "radio.h"
+#include "receiver.h"
#include "property.h"
+#include "main.h"
static int width;
static int height;
-static GtkWidget *parent_window;
static GtkWidget *sliders;
#define NONE 0
static GdkRGBA white;
static GdkRGBA gray;
-void linein_changed() {
+int linein_changed(void *data) {
if(display_sliders) {
if(mic_linein) {
gtk_widget_hide(mic_gain_label);
gtk_widget_show(mic_gain_scale);
}
}
+ return 0;
+}
+
+int active_receiver_changed(void *data) {
+ if(display_sliders) {
+ gtk_range_set_value(GTK_RANGE(af_gain_scale),active_receiver->volume*100.0);
+ gtk_range_set_value (GTK_RANGE(agc_scale),active_receiver->agc_gain);
+ gtk_range_set_value (GTK_RANGE(attenuation_scale),active_receiver->attenuation);
+ }
}
int scale_timeout_cb(gpointer data) {
}
static void attenuation_value_changed_cb(GtkWidget *widget, gpointer data) {
- attenuation=(int)gtk_range_get_value(GTK_RANGE(attenuation_scale));
- set_attenuation(attenuation);
+ active_receiver->attenuation=(int)gtk_range_get_value(GTK_RANGE(attenuation_scale));
+ set_attenuation(active_receiver->attenuation);
}
void set_attenuation_value(double value) {
- attenuation=(int)value;
+ active_receiver->attenuation=(int)value;
if(display_sliders) {
- gtk_range_set_value (GTK_RANGE(attenuation_scale),attenuation);
+ gtk_range_set_value (GTK_RANGE(attenuation_scale),active_receiver->attenuation);
} else {
if(scale_status!=ATTENUATION) {
if(scale_status!=NONE) {
}
if(scale_status==NONE) {
scale_status=ATTENUATION;
- scale_dialog=gtk_dialog_new_with_buttons("Attenuation (dB)",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
+ scale_dialog=gtk_dialog_new_with_buttons("Attenuation (dB)",GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog));
attenuation_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 31.0, 1.00);
gtk_widget_set_size_request (attenuation_scale, 400, 30);
- gtk_range_set_value (GTK_RANGE(attenuation_scale),attenuation);
+ gtk_range_set_value (GTK_RANGE(attenuation_scale),active_receiver->attenuation);
gtk_widget_show(attenuation_scale);
gtk_container_add(GTK_CONTAINER(content),attenuation_scale);
scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL);
int result=gtk_dialog_run(GTK_DIALOG(scale_dialog));
} else {
g_source_remove(scale_timer);
- gtk_range_set_value (GTK_RANGE(attenuation_scale),attenuation);
+ gtk_range_set_value (GTK_RANGE(attenuation_scale),active_receiver->attenuation);
scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL);
}
}
- set_attenuation(attenuation);
+ set_attenuation(active_receiver->attenuation);
}
static void agcgain_value_changed_cb(GtkWidget *widget, gpointer data) {
- agc_gain=gtk_range_get_value(GTK_RANGE(agc_scale));
- SetRXAAGCTop(CHANNEL_RX0, agc_gain);
+ active_receiver->agc_gain=gtk_range_get_value(GTK_RANGE(agc_scale));
+ SetRXAAGCTop(active_receiver->id, active_receiver->agc_gain);
}
void set_agc_gain(double value) {
- agc_gain=value;
- SetRXAAGCTop(CHANNEL_RX0, agc_gain);
+ active_receiver->agc_gain=value;
+ SetRXAAGCTop(active_receiver->id, active_receiver->agc_gain);
if(display_sliders) {
- gtk_range_set_value (GTK_RANGE(agc_scale),agc_gain);
+ gtk_range_set_value (GTK_RANGE(agc_scale),active_receiver->agc_gain);
} else {
if(scale_status!=AGC_GAIN) {
if(scale_status!=NONE) {
}
if(scale_status==NONE) {
scale_status=AGC_GAIN;
- scale_dialog=gtk_dialog_new_with_buttons("AGC Gain",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
+ scale_dialog=gtk_dialog_new_with_buttons("AGC Gain",GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog));
agc_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,-20.0, 120.0, 1.00);
gtk_widget_set_size_request (agc_scale, 400, 30);
- gtk_range_set_value (GTK_RANGE(agc_scale),agc_gain);
+ gtk_range_set_value (GTK_RANGE(agc_scale),active_receiver->agc_gain);
gtk_widget_show(agc_scale);
gtk_container_add(GTK_CONTAINER(content),agc_scale);
scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL);
int result=gtk_dialog_run(GTK_DIALOG(scale_dialog));
} else {
g_source_remove(scale_timer);
- gtk_range_set_value (GTK_RANGE(agc_scale),agc_gain);
+ gtk_range_set_value (GTK_RANGE(agc_scale),active_receiver->agc_gain);
scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL);
}
}
}
static void afgain_value_changed_cb(GtkWidget *widget, gpointer data) {
- volume=gtk_range_get_value(GTK_RANGE(af_gain_scale))/100.0;
- SetRXAPanelGain1 (CHANNEL_RX0, volume);
+ active_receiver->volume=gtk_range_get_value(GTK_RANGE(af_gain_scale))/100.0;
+ SetRXAPanelGain1 (active_receiver->id, active_receiver->volume);
}
int update_af_gain(void *data) {
- set_af_gain(volume);
+ set_af_gain(active_receiver->volume);
return 0;
}
void set_af_gain(double value) {
- volume=value;
- SetRXAPanelGain1 (CHANNEL_RX0, volume);
+ active_receiver->volume=value;
+ SetRXAPanelGain1 (active_receiver->id, active_receiver->volume);
if(display_sliders) {
- gtk_range_set_value (GTK_RANGE(af_gain_scale),volume*100.0);
+ gtk_range_set_value (GTK_RANGE(af_gain_scale),active_receiver->volume*100.0);
} else {
if(scale_status!=AF_GAIN) {
if(scale_status!=NONE) {
}
if(scale_status==NONE) {
scale_status=AF_GAIN;
- scale_dialog=gtk_dialog_new_with_buttons("AF Gain",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
+ scale_dialog=gtk_dialog_new_with_buttons("AF Gain",GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog));
af_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.00);
gtk_widget_set_size_request (af_gain_scale, 400, 30);
- gtk_range_set_value (GTK_RANGE(af_gain_scale),volume*100.0);
+ gtk_range_set_value (GTK_RANGE(af_gain_scale),active_receiver->volume*100.0);
gtk_widget_show(af_gain_scale);
gtk_container_add(GTK_CONTAINER(content),af_gain_scale);
scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL);
int result=gtk_dialog_run(GTK_DIALOG(scale_dialog));
} else {
g_source_remove(scale_timer);
- gtk_range_set_value (GTK_RANGE(af_gain_scale),volume*100.0);
+ gtk_range_set_value (GTK_RANGE(af_gain_scale),active_receiver->volume*100.0);
scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL);
}
}
static void micgain_value_changed_cb(GtkWidget *widget, gpointer data) {
mic_gain=gtk_range_get_value(GTK_RANGE(widget));
double gain=pow(10.0, mic_gain / 20.0);
- SetTXAPanelGain1(CHANNEL_TX,gain);
+ SetTXAPanelGain1(transmitter->id,gain);
}
void set_mic_gain(double value) {
mic_gain=value;
double gain=pow(10.0, mic_gain / 20.0);
- SetTXAPanelGain1(CHANNEL_TX,gain);
+ SetTXAPanelGain1(transmitter->id,gain);
if(display_sliders) {
gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_gain);
} else {
}
if(scale_status==NONE) {
scale_status=MIC_GAIN;
- scale_dialog=gtk_dialog_new_with_buttons("Mic Gain (dB)",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
+ scale_dialog=gtk_dialog_new_with_buttons("Mic Gain (dB)",GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog));
mic_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,-10.0, 50.0, 1.00);
gtk_widget_set_size_request (mic_gain_scale, 400, 30);
}
if(scale_status==NONE) {
scale_status=LINEIN_GAIN;
- scale_dialog=gtk_dialog_new_with_buttons("Linein Gain",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
+ scale_dialog=gtk_dialog_new_with_buttons("Linein Gain",GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog));
linein_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 31.0, 1.00);
gtk_widget_set_size_request (linein_gain_scale, 400, 30);
}
if(scale_status==NONE) {
scale_status=DRIVE;
- scale_dialog=gtk_dialog_new_with_buttons("Drive",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
+ scale_dialog=gtk_dialog_new_with_buttons("Drive",GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog));
drive_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.00);
gtk_widget_set_size_request (drive_scale, 400, 30);
}
if(scale_status==NONE) {
scale_status=TUNE_DRIVE;
- scale_dialog=gtk_dialog_new_with_buttons("Tune Drive",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
+ scale_dialog=gtk_dialog_new_with_buttons("Tune Drive",GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog));
tune_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.00);
gtk_widget_set_size_request (tune_scale, 400, 30);
setTuneDrive(gtk_range_get_value(GTK_RANGE(tune_scale)));
}
-GtkWidget *sliders_init(int my_width, int my_height, GtkWidget* parent) {
+GtkWidget *sliders_init(int my_width, int my_height) {
width=my_width;
height=my_height;
- parent_window=parent;
fprintf(stderr,"sliders_init: width=%d height=%d\n", width,height);
gtk_grid_attach(GTK_GRID(sliders),af_gain_label,0,0,1,1);
af_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.00);
- gtk_range_set_value (GTK_RANGE(af_gain_scale),volume*100.0);
+ gtk_range_set_value (GTK_RANGE(af_gain_scale),active_receiver->volume*100.0);
gtk_widget_show(af_gain_scale);
gtk_grid_attach(GTK_GRID(sliders),af_gain_scale,1,0,2,1);
g_signal_connect(G_OBJECT(af_gain_scale),"value_changed",G_CALLBACK(afgain_value_changed_cb),NULL);
gtk_grid_attach(GTK_GRID(sliders),agc_gain_label,3,0,1,1);
agc_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,-20.0, 120.0, 1.0);
- gtk_range_set_value (GTK_RANGE(agc_scale),agc_gain);
+ gtk_range_set_value (GTK_RANGE(agc_scale),active_receiver->agc_gain);
gtk_widget_show(agc_scale);
gtk_grid_attach(GTK_GRID(sliders),agc_scale,4,0,2,1);
g_signal_connect(G_OBJECT(agc_scale),"value_changed",G_CALLBACK(agcgain_value_changed_cb),NULL);
gtk_grid_attach(GTK_GRID(sliders),attenuation_label,6,0,1,1);
attenuation_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 31.0, 1.0);
- gtk_range_set_value (GTK_RANGE(attenuation_scale),attenuation);
+ gtk_range_set_value (GTK_RANGE(attenuation_scale),active_receiver->attenuation);
gtk_widget_show(attenuation_scale);
gtk_grid_attach(GTK_GRID(sliders),attenuation_scale,7,0,2,1);
g_signal_connect(G_OBJECT(attenuation_scale),"value_changed",G_CALLBACK(attenuation_value_changed_cb),NULL);
#ifndef _SLIDERS_H
#define _SLIDERS_H
-extern void linein_changed();
+extern int linein_changed(void *data);
+extern int active_receiver_changed(void *data);
extern int update_agc_gain(void *);
extern int update_af_gain(void *);
extern int update_mic_gain(void *);
extern int update_drive(void *);
-void set_agc_gain(double value);
-void set_af_gain(double value);
-void set_mic_gain(double value);
-void set_drive(double drive);
-void set_tune(double tune);
-void set_attenuation_value(double attenuation);
-GtkWidget *sliders_init(int my_width, int my_height, GtkWidget* parent);
+extern void set_agc_gain(double value);
+extern void set_af_gain(double value);
+extern void set_mic_gain(double value);
+extern void set_drive(double drive);
+extern void set_tune(double tune);
+extern void set_attenuation_value(double attenuation);
+extern GtkWidget *sliders_init(int my_width, int my_height);
#endif
--- /dev/null
+/* 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 <gtk/gtk.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <sched.h>
+#include <semaphore.h>
+
+#include <soundio/soundio.h>
+
+#include "new_protocol.h"
+#include "old_protocol.h"
+#include "radio.h"
+#include "receiver.h"
+#include "audio.h"
+
+int audio = 0;
+int audio_buffer_size = 256; // samples (both left and right)
+int mic_buffer_size = 720; // samples (both left and right)
+
+//static snd_pcm_t *playback_handle=NULL;
+static snd_pcm_t *record_handle=NULL;
+
+// 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 OUTPUT_BUFFER_SIZE (AUDIO_SAMPLE_SIZE*AUDIO_CHANNELS*audio_buffer_size)
+
+#define MIC_BUFFER_SIZE (AUDIO_SAMPLE_SIZE*AUDIO_CHANNELS*mic_buffer_size)
+
+//static unsigned char *audio_buffer=NULL;
+//static int audio_offset=0;
+
+static unsigned char *mic_buffer=NULL;
+
+static GThread *mic_read_thread_id;
+
+static int running=FALSE;
+
+static void *mic_read_thread(void *arg);
+
+char *input_devices[16];
+int n_input_devices=0;
+int n_selected_input_device=-1;
+
+char *output_devices[16];
+int n_output_devices=0;
+//int n_selected_output_device=-1;
+
+static double seconds_offset=0.0;
+static int want_pause=0;
+
+#define BUFFER_SIZE 8192
+
+static struct SoundIo *soundio;
+static struct SoundIoDevice *audio_device;
+static struct SoundIoOutStream *outstream;
+
+static short output_left_buffer[BUFFER_SIZE];
+static short output_right_buffer[BUFFER_SIZE];
+static int insert_index=0;
+static int remove_index=0;
+static int frames=0;
+
+static void write_callback(struct SoundIoOutStream *outstream, int frame_count_min, int frame_count_max) {
+//fprintf(stderr,"write_callback: min=%d max=%d frames=%d insert_index=%d remove_index=%d\n",frame_count_min, frame_count_max, frames, insert_index, remove_index);
+ double float_sample_rate = outstream->sample_rate;
+ double seconds_per_frame = 1.0 / float_sample_rate;
+ struct SoundIoChannelArea *areas;
+ int err;
+ int frame;
+ int channel;
+
+ if(frames!=0) {
+ int frames_left = frames;
+ if(frames>frame_count_max) {
+ frames_left=frame_count_max;
+ }
+ if ((err = soundio_outstream_begin_write(outstream, &areas, &frames_left))) {
+ fprintf(stderr, "unrecoverable stream error: %s\n", soundio_strerror(err));
+ exit(1);
+ }
+
+ const struct SoundIoChannelLayout *layout = &outstream->layout;
+
+ for (frame=0; frame < frames_left; frame += 1) {
+ for (channel = 0; channel < layout->channel_count; channel += 1) {
+ int16_t *s=(int16_t *)areas[channel].ptr;
+ if(channel==0) {
+ *s=output_left_buffer[remove_index];
+ } else {
+ *s=output_right_buffer[remove_index];
+ }
+ areas[channel].ptr += areas[channel].step;
+ }
+ frames--;
+ remove_index++;
+ if(remove_index==BUFFER_SIZE) {
+ remove_index=0;
+ }
+ }
+ //seconds_offset += seconds_per_frame * frame_count;
+
+ if ((err = soundio_outstream_end_write(outstream))) {
+ if (err == SoundIoErrorUnderflow)
+ return;
+ fprintf(stderr, "unrecoverable stream error: %s\n", soundio_strerror(err));
+ exit(1);
+ }
+ } else {
+ //fprintf(stderr,"audio.c: write_callback: underflow: frames=%d insert_index=%d remove_index=%d\n",frames,insert_index,remove_index);
+ }
+}
+
+static void underflow_callback(struct SoundIoOutStream *outstream) {
+ static int count = 0;
+ //fprintf(stderr, "underflow %d\n", count++);
+}
+
+int audio_open_output(RECEIVER *rx) {
+
+ int err;
+
+fprintf(stderr,"audio_open_output: id=%d device=%d\n", rx->id,rx->audio_device);
+ soundio = soundio_create();
+ if (!soundio) {
+ fprintf(stderr, "audio_open_output: soundio_create failed\n");
+ return -1;
+ }
+
+ soundio_connect(soundio);
+
+ soundio_flush_events(soundio);
+
+ audio_device = soundio_get_output_device(soundio, rx->audio_device);
+ if(!audio_device) {
+ fprintf(stderr, "audio_open_output: soundio_get_output_device failed\n");
+ return -1;
+ }
+
+ if (audio_device->probe_error) {
+ fprintf(stderr, "audio_open_output: Cannot probe audio_device: %s\n", soundio_strerror(audio_device->probe_error));
+ return -1;
+ }
+
+ outstream = soundio_outstream_create(audio_device);
+ outstream->write_callback = write_callback;
+ outstream->underflow_callback = underflow_callback;
+ outstream->name = "pihpsdr:out";
+ outstream->software_latency = 0.0;
+ outstream->sample_rate = 48000;
+
+ if (soundio_device_supports_format(audio_device, SoundIoFormatS16LE)) {
+ outstream->format = SoundIoFormatS16LE;
+ } else {
+ fprintf(stderr,"audio_open_output: audio_device does not support S16LE\n");
+ return -1;
+ }
+
+ if ((err = soundio_outstream_open(outstream))) {
+ fprintf(stderr, "audio_open_output: unable to open audio_device: %s", soundio_strerror(err));
+ return -1;
+ }
+ fprintf(stderr, "audio_open_output: Software latency: %f\n", outstream->software_latency);
+
+ if (outstream->layout_error) {
+ fprintf(stderr, "audio_open_output: unable to set channel layout: %s\n", soundio_strerror(outstream->layout_error));
+ }
+
+ if ((err = soundio_outstream_start(outstream))) {
+ fprintf(stderr, "audio_open_output: unable to start audio_device: %s\n", soundio_strerror(err));
+ return -1;
+ }
+
+ return 0;
+}
+
+int audio_open_input() {
+/*
+ int err;
+ snd_pcm_hw_params_t *hw_params;
+ int rate=48000;
+ int dir=0;
+
+fprintf(stderr,"audio_open_input: %d\n",n_selected_input_device);
+ if(n_selected_input_device<0 || n_selected_input_device>=n_input_devices) {
+ n_selected_input_device=-1;
+ return -1;
+ }
+
+ int i;
+ char hw[16];
+ char *selected=input_devices[n_selected_input_device];
+ fprintf(stderr,"audio_open_input: selected=%d:%s\n",n_selected_input_device,selected);
+
+ switch(protocol) {
+ case ORIGINAL_PROTOCOL:
+ mic_buffer_size = 720;
+ break;
+ case NEW_PROTOCOL:
+ mic_buffer_size = 64;
+ break;
+ default:
+ break;
+ }
+
+ fprintf(stderr,"audio_open_input: mic_buffer_size=%d\n",mic_buffer_size);
+ i=0;
+ while(selected[i]!=' ') {
+ hw[i]=selected[i];
+ i++;
+ }
+ hw[i]='\0';
+
+ fprintf(stderr,"audio_open_input: hw=%s\n",hw);
+
+ if ((err = snd_pcm_open (&record_handle, hw, SND_PCM_STREAM_CAPTURE, 0)) < 0) {
+ fprintf (stderr, "audio_open_input: cannot open audio device %s (%s)\n",
+ hw,
+ snd_strerror (err));
+ return -1;
+ }
+
+ if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
+ fprintf (stderr, "audio_open_input: cannot allocate hardware parameter structure (%s)\n",
+ snd_strerror (err));
+ return -1;
+ }
+
+ if ((err = snd_pcm_hw_params_any (record_handle, hw_params)) < 0) {
+ fprintf (stderr, "audio_open_input: cannot initialize hardware parameter structure (%s)\n",
+ snd_strerror (err));
+ return -1;
+ }
+
+ if ((err = snd_pcm_hw_params_set_access (record_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
+ fprintf (stderr, "audio_open_input: cannot set access type (%s)\n",
+ snd_strerror (err));
+ return -1;
+}
+
+ if ((err = snd_pcm_hw_params_set_format (record_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
+ fprintf (stderr, "audio_open_input: cannot set sample format (%s)\n",
+ snd_strerror (err));
+ return -1;
+ }
+
+ if ((err = snd_pcm_hw_params_set_rate_near (record_handle, hw_params, &rate, &dir)) < 0) {
+ fprintf (stderr, "audio_open_input: cannot set sample rate (%s)\n",
+ snd_strerror (err));
+ return -1;
+ }
+
+ if ((err = snd_pcm_hw_params_set_channels (record_handle, hw_params, 1)) < 0) {
+ fprintf (stderr, "audio_open_input: cannot set channel count (%s)\n",
+ snd_strerror (err));
+ return -1;
+ }
+
+ if ((err = snd_pcm_hw_params (record_handle, hw_params)) < 0) {
+ fprintf (stderr, "audio_open_input: cannot set parameters (%s)\n",
+ snd_strerror (err));
+ return -1;
+ }
+
+ snd_pcm_hw_params_free (hw_params);
+
+ mic_buffer=(unsigned char *)malloc(MIC_BUFFER_SIZE);
+
+ running=TRUE;
+ mic_read_thread_id = g_thread_new( "local mic", mic_read_thread, NULL);
+ if(!mic_read_thread_id )
+ {
+ fprintf(stderr,"g_thread_new failed on mic_read_thread\n");
+ }
+
+*/
+ return 0;
+}
+
+void audio_close_output(RECEIVER *rx) {
+ soundio_outstream_destroy(outstream);
+ soundio_device_unref(audio_device);
+ soundio_destroy(soundio);
+/*
+ if(rx->playback_handle!=NULL) {
+ snd_pcm_close (rx->playback_handle);
+ rx->playback_handle=NULL;
+ }
+ if(rx->playback_buffer!=NULL) {
+ free(rx->playback_buffer);
+ rx->playback_buffer=NULL;
+ }
+*/
+}
+
+void audio_close_input() {
+/*
+ running=FALSE;
+ if(record_handle!=NULL) {
+ snd_pcm_close (record_handle);
+ record_handle=NULL;
+ }
+ if(mic_buffer!=NULL) {
+ free(mic_buffer);
+ mic_buffer=NULL;
+ }
+*/
+}
+
+int audio_write(RECEIVER *rx,short left_sample,short right_sample) {
+//fprintf(stderr,"audio_write: id=%d frames=%d insert_index=%d remove_index=%d\n",rx->id, frames, insert_index,remove_index);
+ if(frames<(BUFFER_SIZE-2)) {
+ output_left_buffer[insert_index]=left_sample;
+ output_right_buffer[insert_index]=right_sample;
+ insert_index++;
+ if(insert_index==BUFFER_SIZE) {
+ insert_index=0;
+ }
+ frames++;
+ } else {
+ fprintf(stderr,"audio_write: buffer_full: frames=%d insert_index-%d remove_index=%d\n",frames,insert_index,remove_index);
+ }
+
+/*
+ snd_pcm_sframes_t delay;
+ int error;
+ long trim;
+
+ if(rx->playback_handle!=NULL && rx->playback_buffer!=NULL) {
+ rx->playback_buffer[rx->playback_offset++]=right_sample;
+ rx->playback_buffer[rx->playback_offset++]=right_sample>>8;
+ rx->playback_buffer[rx->playback_offset++]=left_sample;
+ rx->playback_buffer[rx->playback_offset++]=left_sample>>8;
+
+ if(rx->playback_offset==OUTPUT_BUFFER_SIZE) {
+
+ trim=0;
+
+ if(snd_pcm_delay(rx->playback_handle,&delay)==0) {
+ if(delay>2048) {
+ trim=delay-2048;
+//fprintf(stderr,"audio delay=%ld trim=%ld\n",delay,trim);
+ }
+ }
+
+ if ((error = snd_pcm_writei (rx->playback_handle, rx->playback_buffer, audio_buffer_size-trim)) != audio_buffer_size-trim) {
+ if(error==-EPIPE) {
+ if ((error = snd_pcm_prepare (rx->playback_handle)) < 0) {
+ fprintf (stderr, "audio_write: cannot prepare audio interface for use (%s)\n",
+ snd_strerror (error));
+ return -1;
+ }
+ if ((error = snd_pcm_writei (rx->playback_handle, rx->playback_buffer, audio_buffer_size-trim)) != audio_buffer_size) {
+ fprintf (stderr, "audio_write: write to audio interface failed (%s)\n",
+ snd_strerror (error));
+ return -1;
+ }
+ }
+ }
+ rx->playback_offset=0;
+ }
+ }
+*/
+ return 0;
+}
+
+static gpointer mic_read_thread(gpointer arg) {
+/*
+ int rc;
+ if ((rc = snd_pcm_prepare (record_handle)) < 0) {
+ fprintf (stderr, "mic_read_thread: cannot prepare audio interface for use (%s)\n",
+ snd_strerror (rc));
+ return;
+ }
+fprintf(stderr,"mic_read_thread: mic_buffer_size=%d\n",mic_buffer_size);
+ while(running) {
+ if ((rc = snd_pcm_readi (record_handle, mic_buffer, mic_buffer_size)) != mic_buffer_size) {
+ if(running) {
+ if(rc<0) {
+ fprintf (stderr, "mic_read_thread: read from audio interface failed (%s)\n",
+ snd_strerror (rc));
+ running=FALSE;
+ } else {
+ fprintf(stderr,"mic_read_thread: read %d\n",rc);
+ }
+ }
+ } else {
+ // process the mic input
+ switch(protocol) {
+ case ORIGINAL_PROTOCOL:
+ old_protocol_process_local_mic(mic_buffer,1);
+ break;
+ case NEW_PROTOCOL:
+ new_protocol_process_local_mic(mic_buffer,1);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+fprintf(stderr,"mic_read_thread: exiting\n");
+*/
+}
+
+void audio_get_cards() {
+ int i;
+
+ for(i=0;i<n_input_devices;i++) {
+ free(input_devices[i]);
+ }
+ for(i=0;i<n_output_devices;i++) {
+ free(output_devices[i]);
+ }
+
+ struct SoundIo *soundio = soundio_create();
+ if (!soundio) {
+ fprintf(stderr, "audio_get_cards: soundio_create failed\n");
+ return;
+ }
+
+ soundio_connect(soundio);
+
+ soundio_flush_events(soundio);
+
+ n_output_devices = soundio_output_device_count(soundio);
+ n_input_devices = soundio_input_device_count(soundio);
+ int default_output = soundio_default_output_device_index(soundio);
+ int default_input = soundio_default_input_device_index(soundio);
+
+
+ for(i=0;i<n_output_devices;i++) {
+ struct SoundIoDevice *device = soundio_get_output_device(soundio, i);
+fprintf(stderr,"output: %d: id=%s name=%s\n",i,device->id,device->name);
+ char *device_id=malloc(64);
+ strncpy(device_id,device->id,64);
+ output_devices[i]=device_id;
+ soundio_device_unref(device);
+ }
+
+ for(i=0;i<n_input_devices;i++) {
+ struct SoundIoDevice *device = soundio_get_input_device(soundio, i);
+fprintf(stderr,"input: %d: id=%s name=%s\n",i,device->id,device->name);
+ char *device_id=malloc(64);
+ strncpy(device_id,device->id,64);
+ input_devices[i]=device_id;
+ soundio_device_unref(device);
+ }
+
+ soundio_destroy(soundio);
+}
--- /dev/null
+/* 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.
+*
+*/
+
+#ifndef _AUDIO_H
+#define _AUDIO_H
+
+#include "receiver.h"
+
+extern char *input_devices[];
+extern int n_input_devices;
+extern int n_selected_input_device;
+
+extern char *output_devices[];
+extern int n_output_devices;
+//extern int n_selected_output_device;
+
+extern int audio_open_input();
+extern void audio_close_input();
+extern int audio_open_output(RECEIVER *rx);
+extern void audio_close_output(RECEIVER *rx);
+extern int audio_write(RECEIVER *rx,short left_sample,short right_sample);
+extern void audio_get_cards();
+#endif
#include <gtk/gtk.h>
#include "version.h"
-GtkWidget *splash_screen;
+GtkWidget *grid;
GtkWidget *status;
static cairo_surface_t *splash_surface = NULL;
+
/* Close the splash screen */
void splash_close()
{
- gtk_widget_destroy(splash_screen);
-}
-
-static gboolean splash_configure_event_cb (GtkWidget *widget,
- GdkEventConfigure *event,
- gpointer data)
-{
- if (splash_surface)
- cairo_surface_destroy (splash_surface);
-
- splash_surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget),
- CAIRO_CONTENT_COLOR,
- gtk_widget_get_allocated_width (widget),
- gtk_widget_get_allocated_height (widget));
-
- return TRUE;
+ gtk_widget_destroy(grid);
}
-
-void splash_show(char* image_name,int width,int height,int full_screen)
+GtkWidget *splash_create(char* image_name,int width,int height)
{
GtkWidget *image;
- splash_screen = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- if(full_screen) {
- gtk_window_fullscreen(GTK_WINDOW(splash_screen));
- }
- gtk_widget_set_size_request(splash_screen, width, height);
- gtk_window_set_position(GTK_WINDOW(splash_screen),GTK_WIN_POS_CENTER_ALWAYS);
- gtk_window_set_resizable(GTK_WINDOW(splash_screen), FALSE);
-
- GtkWidget *grid = gtk_grid_new();
+ grid = gtk_grid_new();
+ gtk_widget_set_size_request(grid, width, height);
gtk_grid_set_row_homogeneous(GTK_GRID(grid),FALSE);
gtk_grid_set_column_homogeneous(GTK_GRID(grid),FALSE);
image=gtk_image_new_from_file(image_name);
- //gtk_container_add(GTK_CONTAINER(splash_screen), image);
gtk_grid_attach(GTK_GRID(grid), image, 0, 0, 1, 4);
- g_signal_connect (splash_screen,"configure-event",
- G_CALLBACK (splash_configure_event_cb), NULL);
char build[64];
sprintf(build,"build: %s %s",build_date, version);
gtk_label_set_justify(GTK_LABEL(status),GTK_JUSTIFY_LEFT);
gtk_widget_override_font(status, pango_font_description_from_string("FreeMono 18"));
gtk_widget_show(status);
- //gtk_container_add(GTK_CONTAINER(splash_screen), status);
gtk_grid_attach(GTK_GRID(grid), status, 1, 3, 1, 1);
- gtk_container_add(GTK_CONTAINER(splash_screen), grid);
- gtk_widget_show_all (splash_screen);
+ return grid;
}
void splash_status(char *text) {
#ifndef _SPLASH_H
#define _SPLASH_H
-extern GtkWidget* splash_screen;
void splash_close(void);
-void splash_show(char *image_name,int time,int width,int height);
+GtkWidget *splash_create(char *image_name,int width,int height);
void splash_status(char *text);
#endif
--- /dev/null
+/* Copyright (C)
+* 2015 - John Melton, G0ORX/N6LYT
+* 2016 - Steve Wilson, KA6S
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "bandstack.h"
+#include "band.h"
+#include "filter.h"
+#include "mode.h"
+#include "alex.h"
+#include "property.h"
+#include "store.h"
+#include "store_menu.h"
+
+
+/*
+struct MEM {
+ char title[16]; // Begin BAND Struct
+ BANDSTACK *bandstack;
+ unsigned char OCrx;
+ unsigned char OCtx;
+ int preamp;
+ int alexRxAntenna;
+ int alexTxAntenna;
+ int alexAttenuation;
+ double pa_calibration;
+ long long frequencyMin;
+ long long frequencyMax;
+ long long frequencyLO;
+ int disablePA;
+ long long frequency; // Begin BANDSTACK_ENTRY
+ int mode;
+ int filter;
+ int var1Low;
+ int var1High;
+ int var2Low;
+ int var2High;
+}*/
+MEM mem[NUM_OF_MEMORYS]; // This makes it a compile time option
+
+/* */
+/* Memory uses the same format as Band Stack */
+/* Implement NUM_OF_MEMORYS memory locations for now... */
+
+void memSaveState() {
+ char name[128];
+ char value[128];
+ int current;
+ BANDSTACK_ENTRY* entry;
+ int workvar;
+ int b;
+ int stack;
+
+ for(b=0;b<NUM_OF_MEMORYS;b++) {
+ if(strlen(mem[b].title)>0) {
+ sprintf(name,"mem.%d.title",b);
+ setProperty(name,mem[b].title);
+
+ sprintf(value,"%lld",mem[b].frequency);
+ sprintf(name,"mem.%d.freqA",b);
+ setProperty(name,value);
+
+ sprintf(value,"%d",mem[b].mode);
+ sprintf(name,"mem.%d.mode",b);
+ setProperty(name,value);
+
+ sprintf(value,"%d",mem[b].filter);
+ sprintf(name,"mem.%d.filter",b);
+ setProperty(name,value);
+ }
+ }
+
+ //sprintf(value,"%d",band);
+ //setProperty("band",value);
+}
+
+void memRestoreState() {
+ char* value;
+ int b;
+ int stack;
+ char name[128];
+ BANDSTACK_ENTRY* entry;
+ int current;
+
+ // Initialize the array with default values
+ // Allows this to be a compile time option..
+ for(b=0; b<NUM_OF_MEMORYS; b++) {
+ strcpy(mem[b].title,"10");
+ mem[b].frequency = 28010000LL;
+ mem[b].mode = modeCWU;
+ mem[b].filter = filterF0;
+ }
+
+ fprintf(stderr,"memRestoreState: restore memory\n");
+
+ for(b=0;b<NUM_OF_MEMORYS;b++) {
+ sprintf(name,"mem.%d.title",b);
+ value=getProperty(name);
+ if(value) strcpy(mem[b].title,value);
+ fprintf(stderr,"RESTORE: index=%d title=%s\n",b,value);
+
+ sprintf(name,"mem.%d.freqA",b);
+ value=getProperty(name);
+ if(value) mem[b].frequency=atoll(value);
+ fprintf(stderr,"RESTORE MEM:Mem %d=FreqA %11lld\n",b,mem[b].frequency);
+
+ sprintf(name,"mem.%d.mode",b);
+ value=getProperty(name);
+ if(value) mem[b].mode=atoi(value);
+ fprintf(stderr,"RESTORE: index=%d mode=%d\n",b,mem[b].mode);
+
+ sprintf(name,"mem.%d.filter",b);
+ value=getProperty(name);
+ if(value) mem[b].filter=atoi(value);
+ fprintf(stderr,"RESTORE: index=%d filter=%d\n",b,mem[b].filter);
+ }
+
+ //value=getProperty("band");
+ //if(value) band=atoi(value);
+}
+
--- /dev/null
+/* Copyright (C)
+* 2015 - John Melton, G0ORX/N6LYT
+* 2016 - Steve Wilson, KA6S
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*/
+
+#ifndef _STORE_H
+#define _STORE_H
+
+#include <gtk/gtk.h>
+#include "bandstack.h"
+
+
+/* --------------------------------------------------------------------------*/
+/**
+* @brief Band definition
+*/
+struct _MEM_STORE {
+ char title[16]; // Begin BAND Struct
+ long long frequency; // Begin BANDSTACK_ENTRY
+ int mode;
+ int filter;
+};
+
+typedef struct _MEM_STORE MEM;
+
+extern MEM mem[];
+void memRestoreState();
+void memSaveState();
+
+#endif
--- /dev/null
+/* Copyright (C)
+* 2016 - John Melton, G0ORX/N6LYT
+* 2016 - Steve Wilson, KA6S
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*/
+
+#include <gtk/gtk.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "new_menu.h"
+#include "store_menu.h"
+#include "band.h"
+#include "bandstack.h"
+#include "filter.h"
+#include "mode.h"
+#include "radio.h"
+#include "rigctl.h"
+#include "band.h"
+#include "vfo.h"
+#include "button_text.h"
+#include "store.h"
+
+static GtkWidget *parent_window=NULL;
+
+static GtkWidget *dialog=NULL;
+
+static gboolean store_close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ if(dialog!=NULL) {
+ gtk_widget_destroy(dialog);
+ dialog=NULL;
+ sub_menu=NULL;
+ }
+ return TRUE;
+}
+
+static gboolean store_select_cb (GtkWidget *widget, gpointer data) {
+ int index = (int) data;
+ fprintf(stderr,"STORE BUTTON PUSHED=%d\n",index);
+ char workstr[16];
+
+ /* Update mem[data] with current info */
+
+ mem[index].frequency = vfo[active_receiver->id].frequency; // Store current frequency
+ mem[index].mode = vfo[active_receiver->id].mode;
+ mem[index].filter=vfo[active_receiver->id].filter;
+
+ fprintf(stderr,"store_select_cb: Index=%d\n",index);
+ fprintf(stderr,"store_select_cb: freqA=%11lld\n",mem[index].frequency);
+ fprintf(stderr,"store_select_cb: mode=%d\n",mem[index].mode);
+ fprintf(stderr,"store_select_cb: filter=%d\n",mem[index].filter);
+
+ // Save in the file now..
+ memSaveState();
+}
+
+static gboolean recall_select_cb (GtkWidget *widget, gpointer data) {
+ int index = (int) data;
+ long long new_freq;
+
+ //new_freq = mem[index].frequency;
+ strcpy(mem[index].title,"Active");
+ new_freq = mem[index].frequency;
+ fprintf(stderr,"recall_select_cb: Index=%d\n",index);
+ fprintf(stderr,"recall_select_cb: freqA=%11lld\n",new_freq);
+ fprintf(stderr,"recall_select_cb: mode=%d\n",mem[index].mode);
+ fprintf(stderr,"recall_select_cb: filter=%d\n",mem[index].filter);
+
+ //set_band(mem[index].frequency,index);
+ vfo[active_receiver->id].frequency = new_freq;
+ vfo[active_receiver->id].band = get_band_from_frequency(new_freq);
+ vfo[active_receiver->id].mode = mem[index].mode;
+ vfo[active_receiver->id].filter = mem[index].filter;
+ vfo_band_changed(vfo[active_receiver->id].band);
+}
+
+void store_menu(GtkWidget *parent) {
+ GtkWidget *b;
+ int i;
+ BAND *band;
+ char label_str[20];
+
+ parent_window=parent;
+
+ dialog=gtk_dialog_new();
+ gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window));
+ gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE);
+
+ GdkRGBA color;
+ color.red = 1.0;
+ color.green = 1.0;
+ color.blue = 1.0;
+ color.alpha = 1.0;
+ gtk_widget_override_background_color(dialog,GTK_STATE_FLAG_NORMAL,&color);
+
+ GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+
+ GtkWidget *grid=gtk_grid_new();
+
+ gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
+ gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
+ gtk_grid_set_column_spacing (GTK_GRID(grid),5);
+ gtk_grid_set_row_spacing (GTK_GRID(grid),5);
+
+ GtkWidget *close_b=gtk_button_new_with_label("Close Store");
+ g_signal_connect (close_b, "pressed", G_CALLBACK(store_close_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1);
+
+ for(i=0;i<NUM_OF_MEMORYS;i++) {
+ sprintf(label_str,"Store M%d",i);
+ b=gtk_button_new_with_label(label_str);
+ g_signal_connect(b,"pressed",G_CALLBACK(store_select_cb),(gpointer *) i);
+ gtk_grid_attach(GTK_GRID(grid),b,2,i,1,1);
+
+ sprintf(label_str,"Recall M%d",i);
+ b=gtk_button_new_with_label(label_str);
+ g_signal_connect(b,"pressed",G_CALLBACK(recall_select_cb),(gpointer *) i);
+ gtk_grid_attach(GTK_GRID(grid),b,3,i,1,1);
+ }
+
+ gtk_container_add(GTK_CONTAINER(content),grid);
+
+ sub_menu=dialog;
+
+ gtk_widget_show_all(dialog);
+}
--- /dev/null
+/* Copyright (C)
+* 2016 - Steve Wilson, KA6S
+*
+* 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.
+*
+*/
+#define NUM_OF_MEMORYS 5
+extern void store_menu(GtkWidget *parent);
#include "channel.h"
#include "wdsp.h"
#include "radio.h"
+#include "receiver.h"
#include "property.h"
#include "new_menu.h"
+#include "button_text.h"
+#define MAX_FUNCTION 3
int function=0;
static int width;
static gint rit_timer;
-static void set_button_text_color(GtkWidget *widget,char *color) {
- GtkStyleContext *style_context;
- GtkCssProvider *provider = gtk_css_provider_new ();
- gchar tmp[64];
- style_context = gtk_widget_get_style_context(widget);
- gtk_style_context_add_provider(style_context, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
- g_snprintf(tmp, sizeof tmp, "GtkButton, GtkLabel { color: %s; }", color);
- gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(provider), tmp, -1, NULL);
- g_object_unref (provider);
+static gboolean rit_timer_cb(gpointer data) {
+ int i=(int)data;
+ vfo[active_receiver->id].rit+=(i*rit_increment);
+ if(vfo[active_receiver->id].rit>1000) vfo[active_receiver->id].rit=1000;
+ if(vfo[active_receiver->id].rit<-1000) vfo[active_receiver->id].rit=-1000;
+ vfo_update(NULL);
+ return TRUE;
}
void update_toolbar_labels() {
- if(toolbar_dialog_buttons) {
- if(function) {
- gtk_button_set_label(GTK_BUTTON(sim_mox),"Tune");
- gtk_button_set_label(GTK_BUTTON(sim_s1),"RIT+");
- gtk_button_set_label(GTK_BUTTON(sim_s2),"RIT-");
- gtk_button_set_label(GTK_BUTTON(sim_s3),"CTUN");
- gtk_button_set_label(GTK_BUTTON(sim_s4),"");
- gtk_button_set_label(GTK_BUTTON(sim_s5),"");
- gtk_button_set_label(GTK_BUTTON(sim_s6),"Lock");
- } else {
- gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
- gtk_button_set_label(GTK_BUTTON(sim_s1),"Band");
- gtk_button_set_label(GTK_BUTTON(sim_s2),"BStack");
- gtk_button_set_label(GTK_BUTTON(sim_s3),"Mode");
- gtk_button_set_label(GTK_BUTTON(sim_s4),"Filter");
- gtk_button_set_label(GTK_BUTTON(sim_s5),"Noise");
- gtk_button_set_label(GTK_BUTTON(sim_s6),"AGC");
+ switch(function) {
+ case 0:
+ gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
+ gtk_button_set_label(GTK_BUTTON(sim_s1),"Band");
+ gtk_button_set_label(GTK_BUTTON(sim_s2),"BStack");
+ gtk_button_set_label(GTK_BUTTON(sim_s3),"Mode");
+ gtk_button_set_label(GTK_BUTTON(sim_s4),"Filter");
+ gtk_button_set_label(GTK_BUTTON(sim_s5),"Noise");
+ gtk_button_set_label(GTK_BUTTON(sim_s6),"AGC");
+ set_button_text_color(sim_s1,"black");
+ set_button_text_color(sim_s2,"black");
+ break;
+
+ case 1:
+ gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
+ gtk_button_set_label(GTK_BUTTON(sim_s1),"Lock");
+ gtk_button_set_label(GTK_BUTTON(sim_s2),"CTUN");
+ gtk_button_set_label(GTK_BUTTON(sim_s3),"A>B");
+ gtk_button_set_label(GTK_BUTTON(sim_s4),"A<B");
+ gtk_button_set_label(GTK_BUTTON(sim_s5),"A<>B");
+ gtk_button_set_label(GTK_BUTTON(sim_s6),"Split");
+ break;
+ case 2:
+ gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
+ gtk_button_set_label(GTK_BUTTON(sim_s1),"Freq");
+ gtk_button_set_label(GTK_BUTTON(sim_s2),"Mem");
+ gtk_button_set_label(GTK_BUTTON(sim_s3),"Vox");
+ gtk_button_set_label(GTK_BUTTON(sim_s4),"RIT+");
+ gtk_button_set_label(GTK_BUTTON(sim_s5),"RIT-");
+ gtk_button_set_label(GTK_BUTTON(sim_s6),"");
+ if(full_tune) {
+ set_button_text_color(sim_s1,"red");
}
- } else {
- if(function) {
- gtk_button_set_label(GTK_BUTTON(sim_s1),"Band v");
- gtk_button_set_label(GTK_BUTTON(sim_s2),"BStack v");
- gtk_button_set_label(GTK_BUTTON(sim_s3),"Mode v");
- gtk_button_set_label(GTK_BUTTON(sim_s4),"Filter v");
- gtk_button_set_label(GTK_BUTTON(sim_s5),"Noise v");
- gtk_button_set_label(GTK_BUTTON(sim_s6),"AGC v");
+ if(memory_tune) {
+ set_button_text_color(sim_s2,"red");
+ }
+ break;
+ case 3:
gtk_button_set_label(GTK_BUTTON(sim_mox),"Tune");
- } else {
- gtk_button_set_label(GTK_BUTTON(sim_s1),"Band ^");
- gtk_button_set_label(GTK_BUTTON(sim_s2),"BStack ^");
- gtk_button_set_label(GTK_BUTTON(sim_s3),"Mode ^");
- gtk_button_set_label(GTK_BUTTON(sim_s4),"Filter ^");
- gtk_button_set_label(GTK_BUTTON(sim_s5),"Noise ^");
- gtk_button_set_label(GTK_BUTTON(sim_s6),"AGC ^");
- gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
- }
+ if(OCtune!=0 && OCfull_tune_time!=0) {
+ gtk_button_set_label(GTK_BUTTON(sim_s1),"Full");
+ } else {
+ gtk_button_set_label(GTK_BUTTON(sim_s1),"");
+ }
+ if(OCtune!=0 && OCmemory_tune_time!=0) {
+ gtk_button_set_label(GTK_BUTTON(sim_s2),"Memory");
+ } else {
+ gtk_button_set_label(GTK_BUTTON(sim_s2),"");
+ }
+ gtk_button_set_label(GTK_BUTTON(sim_s3),"");
+ gtk_button_set_label(GTK_BUTTON(sim_s4),"");
+ gtk_button_set_label(GTK_BUTTON(sim_s5),"");
+ gtk_button_set_label(GTK_BUTTON(sim_s6),"");
+ if(full_tune) {
+ set_button_text_color(sim_s1,"red");
+ }
+ if(memory_tune) {
+ set_button_text_color(sim_s2,"red");
+ }
+ break;
}
}
last_dialog=NULL;
}
-/*
-static void band_select_cb(GtkWidget *widget, gpointer data) {
- GtkWidget *label;
- int b=(int)data;
- BANDSTACK_ENTRY *entry;
- if(b==band_get_current()) {
- entry=bandstack_entry_next();
- } else {
- BAND* band=band_set_current(b);
- entry=bandstack_entry_get_current();
- set_button_text_color(last_band,"black");
- last_band=widget;
- set_button_text_color(last_band,"orange");
- }
- setMode(entry->mode);
- FILTER* band_filters=filters[entry->mode];
- FILTER* band_filter=&band_filters[entry->filter];
- setFilter(band_filter->low,band_filter->high);
- setFrequency(entry->frequencyA);
-
- BAND *band=band_get_current_band();
- set_alex_rx_antenna(band->alexRxAntenna);
- set_alex_tx_antenna(band->alexTxAntenna);
- set_alex_attenuation(band->alexAttenuation);
-
- vfo_update(NULL);
-
- setFrequency(entry->frequencyA);
-
- calcDriveLevel();
- calcTuneDriveLevel();
-}
-*/
-
void band_cb(GtkWidget *widget, gpointer data) {
start_band();
-/*
- BAND* band;
- int show=1;
- if(last_dialog!=NULL) {
- if(strcmp(gtk_window_get_title(GTK_WINDOW(last_dialog)),"Band")==0) {
- show=0;
- }
- gtk_widget_destroy(last_dialog);
- last_dialog=NULL;
- }
- if(show) {
- GtkWidget *dialog=gtk_dialog_new_with_buttons("Band",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
- GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
- GtkWidget *grid=gtk_grid_new();
- gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
- gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
- GtkWidget *b;
- int i;
- for(i=0;i<BANDS+XVTRS;i++) {
-#ifdef LIMESDR
- if(protocol!=LIMESDR_PROTOCOL) {
- if(i>=band70 && i<=band3400) {
- continue;
- }
- }
-#endif
-
- band=(BAND*)band_get_band(i);
- if(strlen(band->title)>0) {
- GtkWidget *b=gtk_button_new_with_label(band->title);
- set_button_text_color(b,"black");
- //gtk_widget_override_font(b, pango_font_description_from_string("Arial 20"));
- if(i==band_get_current()) {
- set_button_text_color(b,"orange");
- last_band=b;
- }
- gtk_widget_show(b);
- gtk_grid_attach(GTK_GRID(grid),b,i%5,i/5,1,1);
- g_signal_connect(b,"clicked",G_CALLBACK(band_select_cb),(gpointer *)i);
- }
- }
-
- gtk_container_add(GTK_CONTAINER(content),grid);
-
- GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK);
- //gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 20"));
- g_signal_connect(close_button,"clicked",G_CALLBACK(close_cb),(gpointer *)NULL);
-
- gtk_widget_show_all(dialog);
- last_dialog=dialog;
- int result=gtk_dialog_run(GTK_DIALOG(dialog));
- }
-*/
-}
-
-/*
-static void bandstack_select_cb(GtkWidget *widget, gpointer data) {
- int b=(int)data;
- BAND *band=band_get_current_band();
- BANDSTACK *bandstack=band->bandstack;
-
- bandstack->current_entry=b;
-
- set_button_text_color(last_bandstack,"black");
- last_bandstack=widget;
- set_button_text_color(last_bandstack,"orange");
-
- BANDSTACK_ENTRY *entry;
- entry=&(bandstack->entry[b]);
-
- setMode(entry->mode);
- FILTER* band_filters=filters[entry->mode];
- FILTER* band_filter=&band_filters[entry->filter];
- setFilter(band_filter->low,band_filter->high);
- setFrequency(entry->frequencyA);
-
- set_alex_rx_antenna(band->alexRxAntenna);
- set_alex_tx_antenna(band->alexTxAntenna);
- set_alex_attenuation(band->alexAttenuation);
-
- vfo_update(NULL);
-
- setFrequency(entry->frequencyA);
}
-*/
void bandstack_cb(GtkWidget *widget, gpointer data) {
start_bandstack();
-/*
- int show=1;
- if(last_dialog!=NULL) {
- if(strcmp(gtk_window_get_title(GTK_WINDOW(last_dialog)),"Band Stack")==0) {
- show=0;
- }
- gtk_widget_destroy(last_dialog);
- last_dialog=NULL;
- }
- if(show) {
- GtkWidget *dialog=gtk_dialog_new_with_buttons("Band Stack",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
- GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
- GtkWidget *grid=gtk_grid_new();
- gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
- gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
- GtkWidget *b;
- int i;
-
- char label[16];
-
- BAND *band=band_get_current_band();
- BANDSTACK *bandstack=band->bandstack;
-
- for(i=0;i<bandstack->entries;i++) {
- BANDSTACK_ENTRY *entry=&bandstack->entry[i];
- sprintf(label,"%lld %s",entry->frequencyA,mode_string[entry->mode]);
- GtkWidget *b=gtk_button_new_with_label(label);
- set_button_text_color(b,"black");
- //gtk_widget_override_font(b, pango_font_description_from_string("Arial 20"));
- if(i==bandstack->current_entry) {
- set_button_text_color(b,"orange");
- last_bandstack=b;
- }
- gtk_widget_show(b);
- gtk_grid_attach(GTK_GRID(grid),b,i/5,i%5,1,1);
- g_signal_connect(b,"clicked",G_CALLBACK(bandstack_select_cb),(gpointer *)i);
- }
-
- gtk_container_add(GTK_CONTAINER(content),grid);
-
- GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK);
- //gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 20"));
- g_signal_connect(close_button,"clicked",G_CALLBACK(close_cb),(gpointer *)NULL);
- gtk_widget_show_all(dialog);
-
- last_dialog=dialog;
-
- int result=gtk_dialog_run(GTK_DIALOG(dialog));
- }
-*/
}
-void function_cb(GtkWidget *widget, gpointer data) {
- function=function==1?0:1;
- update_toolbar_labels();
- vfo_update(NULL);
-}
-
-/*
-static void mode_select_cb(GtkWidget *widget, gpointer data) {
- int m=(int)data;
- BANDSTACK_ENTRY *entry;
- entry=bandstack_entry_get_current();
- entry->mode=m;
- setMode(entry->mode);
- FILTER* band_filters=filters[entry->mode];
- FILTER* band_filter=&band_filters[entry->filter];
- setFilter(band_filter->low,band_filter->high);
- set_button_text_color(last_mode,"black");
- last_mode=widget;
- set_button_text_color(last_mode,"orange");
- vfo_update(NULL);
-}
-*/
-
void mode_cb(GtkWidget *widget, gpointer data) {
start_mode();
-/*
- int show=1;
- if(last_dialog!=NULL) {
- if(strcmp(gtk_window_get_title(GTK_WINDOW(last_dialog)),"Mode")==0) {
- show=0;
- }
- gtk_widget_destroy(last_dialog);
- last_dialog=NULL;
- }
- if(show) {
- BANDSTACK_ENTRY *entry=bandstack_entry_get_current();
- GtkWidget *dialog=gtk_dialog_new_with_buttons("Mode",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
- GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
- GtkWidget *grid=gtk_grid_new();
- gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
- gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
-
- GtkWidget *b;
- int i;
- for(i=0;i<MODES;i++) {
- GtkWidget *b=gtk_button_new_with_label(mode_string[i]);
- if(i==entry->mode) {
- set_button_text_color(b,"orange");
- last_mode=b;
- } else {
- set_button_text_color(b,"black");
- }
- //gtk_widget_override_font(b, pango_font_description_from_string("Arial 20"));
- gtk_widget_show(b);
- gtk_grid_attach(GTK_GRID(grid),b,i%5,i/5,1,1);
- g_signal_connect(b,"pressed",G_CALLBACK(mode_select_cb),(gpointer *)i);
- }
- gtk_container_add(GTK_CONTAINER(content),grid);
- GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK);
- //gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 20"));
- g_signal_connect(close_button,"clicked",G_CALLBACK(close_cb),(gpointer *)NULL);
- gtk_widget_show_all(dialog);
-
- last_dialog=dialog;
- int result=gtk_dialog_run(GTK_DIALOG(dialog));
-
- }
-*/
}
-/*
-static void filter_select_cb(GtkWidget *widget, gpointer data) {
- int f=(int)data;
- BANDSTACK_ENTRY *entry;
- entry=bandstack_entry_get_current();
- entry->filter=f;
- FILTER* band_filters=filters[entry->mode];
- FILTER* band_filter=&band_filters[entry->filter];
- setFilter(band_filter->low,band_filter->high);
- set_button_text_color(last_filter,"black");
- last_filter=widget;
- set_button_text_color(last_filter,"orange");
- vfo_update(NULL);
-}
-*/
void filter_cb(GtkWidget *widget, gpointer data) {
start_filter();
-/*
- int show=1;
- if(last_dialog!=NULL) {
- if(strcmp(gtk_window_get_title(GTK_WINDOW(last_dialog)),"Filter")==0) {
- show=0;
- }
- gtk_widget_destroy(last_dialog);
- last_dialog=NULL;
- }
- if(show) {
- BANDSTACK_ENTRY *entry=bandstack_entry_get_current();
- FILTER* band_filters=filters[entry->mode];
- GtkWidget *dialog=gtk_dialog_new_with_buttons("Filter",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
- GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
- GtkWidget *grid=gtk_grid_new();
- gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
- gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
-
- GtkWidget *b;
- int i;
- for(i=0;i<FILTERS;i++) {
- FILTER* band_filter=&band_filters[i];
- GtkWidget *b=gtk_button_new_with_label(band_filters[i].title);
- //gtk_widget_override_font(b, pango_font_description_from_string("Arial 20"));
- if(i==entry->filter) {
- set_button_text_color(b,"orange");
- last_filter=b;
- } else {
- set_button_text_color(b,"black");
- }
- gtk_widget_show(b);
- gtk_grid_attach(GTK_GRID(grid),b,i%5,i/5,1,1);
- g_signal_connect(b,"pressed",G_CALLBACK(filter_select_cb),(gpointer *)i);
- }
- gtk_container_add(GTK_CONTAINER(content),grid);
- GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK);
- //gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 20"));
- g_signal_connect(close_button,"clicked",G_CALLBACK(close_cb),(gpointer *)NULL);
- gtk_widget_show_all(dialog);
-
- last_dialog=dialog;
- int result=gtk_dialog_run(GTK_DIALOG(dialog));
-
- }
-*/
}
-/*
-static void agc_select_cb(GtkWidget *widget, gpointer data) {
- agc=(int)data;
- wdsp_set_agc(CHANNEL_RX0, agc);
- //SetRXAAGCMode(CHANNEL_RX0, agc);
+void agc_cb(GtkWidget *widget, gpointer data) {
+ start_agc();
}
-*/
-/*
-static void update_noise() {
- SetRXAANRRun(CHANNEL_RX0, nr);
- SetRXAEMNRRun(CHANNEL_RX0, nr2);
- SetRXAANFRun(CHANNEL_RX0, anf);
- SetRXASNBARun(CHANNEL_RX0, snb);
- vfo_update(NULL);
+void noise_cb(GtkWidget *widget, gpointer data) {
+ start_noise();
}
-static void nr_none_cb(GtkWidget *widget, gpointer data) {
- nr=0;
- nr2=0;
- nb=0;
- nb2=0;
- anf=0;
- snb=0;
- update_noise();
+void ctun_cb (GtkWidget *widget, gpointer data) {
+ int id=active_receiver->id;
+ vfo[id].ctun=vfo[id].ctun==1?0:1;
+ if(!vfo[id].ctun) {
+ vfo[id].offset=0;
+ }
+ vfo[id].ctun_frequency=vfo[id].frequency;
+ set_offset(active_receiver,vfo[id].offset);
+ vfo_update(NULL);
}
-static void nr_cb(GtkWidget *widget, gpointer data) {
- nr=1;
- nr2=0;
- nb=0;
- nb2=0;
- anf=0;
- snb=0;
- update_noise();
+static void atob_cb (GtkWidget *widget, gpointer data) {
+ vfo_a_to_b();
}
-static void nr2_cb(GtkWidget *widget, gpointer data) {
- nr=0;
- nr2=1;
- nb=0;
- nb2=0;
- anf=0;
- snb=0;
- update_noise();
+static void btoa_cb (GtkWidget *widget, gpointer data) {
+ vfo_b_to_a();
}
-static void nb_cb(GtkWidget *widget, gpointer data) {
- nr=0;
- nr2=0;
- nb=1;
- nb2=0;
- anf=0;
- snb=0;
- update_noise();
+static void aswapb_cb (GtkWidget *widget, gpointer data) {
+ vfo_a_swap_b();
}
-static void nb2_cb(GtkWidget *widget, gpointer data) {
- nr=0;
- nr2=0;
- nb=0;
- nb2=1;
- anf=0;
- snb=0;
- update_noise();
+static void split_cb (GtkWidget *widget, gpointer data) {
+ split=split==1?0:1;
+ if(split) {
+ tx_set_mode(transmitter,vfo[VFO_B].mode);
+ } else {
+ tx_set_mode(transmitter,vfo[VFO_A].mode);
+ }
+ vfo_update(NULL);
}
-static void anf_cb(GtkWidget *widget, gpointer data) {
- nr=0;
- nr2=0;
- nb=0;
- nb2=0;
- anf=1;
- snb=0;
- update_noise();
+static void rit_cb(GtkWidget *widget, gpointer data) {
+ int i=(int)data;
+ vfo[active_receiver->id].rit+=i*rit_increment;
+ if(vfo[active_receiver->id].rit>1000) vfo[active_receiver->id].rit=1000;
+ if(vfo[active_receiver->id].rit<-1000) vfo[active_receiver->id].rit=-1000;
+ vfo_update(NULL);
+ rit_timer=g_timeout_add(200,rit_timer_cb,(void *)i);
}
-static void snb_cb(GtkWidget *widget, gpointer data) {
- nr=0;
- nr2=0;
- nb=0;
- nb2=0;
- anf=0;
- snb=1;
- update_noise();
+static void freq_cb(GtkWidget *widget, gpointer data) {
+ start_vfo();
}
-*/
-void agc_cb(GtkWidget *widget, gpointer data) {
- start_agc();
-/*
- int show=1;
- if(last_dialog!=NULL) {
- if(strcmp(gtk_window_get_title(GTK_WINDOW(last_dialog)),"AGC")==0) {
- show=0;
- }
- gtk_widget_destroy(last_dialog);
- last_dialog=NULL;
- }
- if(show) {
- GtkWidget *dialog=gtk_dialog_new_with_buttons("AGC",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
-
- GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
- GtkWidget *grid=gtk_grid_new();
-
- gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
- gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
-
- GtkWidget *b_off=gtk_radio_button_new_with_label(NULL,"Off");
- //gtk_widget_override_font(b_off, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_off), agc==AGC_OFF);
- gtk_widget_show(b_off);
- gtk_grid_attach(GTK_GRID(grid),b_off,0,0,2,1);
- g_signal_connect(b_off,"pressed",G_CALLBACK(agc_select_cb),(gpointer *)AGC_OFF);
-
- GtkWidget *b_long=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_off),"Long");
- //gtk_widget_override_font(b_long, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_long), agc==AGC_LONG);
- gtk_widget_show(b_long);
- gtk_grid_attach(GTK_GRID(grid),b_long,0,1,2,1);
- g_signal_connect(b_long,"pressed",G_CALLBACK(agc_select_cb),(gpointer *)AGC_LONG);
-
- GtkWidget *b_slow=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_long),"Slow");
- //gtk_widget_override_font(b_slow, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_slow), agc==AGC_SLOW);
- gtk_widget_show(b_slow);
- gtk_grid_attach(GTK_GRID(grid),b_slow,0,2,2,1);
- g_signal_connect(b_slow,"pressed",G_CALLBACK(agc_select_cb),(gpointer *)AGC_SLOW);
-
- GtkWidget *b_medium=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_slow),"Medium");
- //gtk_widget_override_font(b_medium, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_medium), agc==AGC_MEDIUM);
- gtk_widget_show(b_medium);
- gtk_grid_attach(GTK_GRID(grid),b_medium,0,3,2,1);
- g_signal_connect(b_medium,"pressed",G_CALLBACK(agc_select_cb),(gpointer *)AGC_MEDIUM);
-
- GtkWidget *b_fast=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_medium),"Fast");
- //gtk_widget_override_font(b_fast, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_fast), agc==AGC_FAST);
- gtk_widget_show(b_fast);
- gtk_grid_attach(GTK_GRID(grid),b_fast,0,4,2,1);
- g_signal_connect(b_fast,"pressed",G_CALLBACK(agc_select_cb),(gpointer *)AGC_FAST);
-
- gtk_container_add(GTK_CONTAINER(content),grid);
-
- GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK);
- //gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 16"));
- g_signal_connect(close_button,"clicked",G_CALLBACK(close_cb),(gpointer *)NULL);
- gtk_widget_show_all(dialog);
- last_dialog=dialog;
- int result=gtk_dialog_run(GTK_DIALOG(dialog));
- }
-*/
+static void mem_cb(GtkWidget *widget, gpointer data) {
+ start_store();
}
-void noise_cb(GtkWidget *widget, gpointer data) {
- start_noise();
-/*
- int show=1;
- if(last_dialog!=NULL) {
- if(strcmp(gtk_window_get_title(GTK_WINDOW(last_dialog)),"Noise")==0) {
- show=0;
- }
- gtk_widget_destroy(last_dialog);
- last_dialog=NULL;
- }
- if(show) {
- GtkWidget *dialog=gtk_dialog_new_with_buttons("Noise",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
-
- GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
- GtkWidget *grid=gtk_grid_new();
-
- gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
- gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
-
- GtkWidget *b_nr_none=gtk_radio_button_new_with_label(NULL,"None");
- //gtk_widget_override_font(b_none, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_nr_none), nr_none==1);
- gtk_widget_show(b_nr_none);
- gtk_grid_attach(GTK_GRID(grid),b_nr_none,0,0,2,1);
- g_signal_connect(b_nr_none,"pressed",G_CALLBACK(nr_none_cb),NULL);
-
- GtkWidget *b_nr=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_nr_none),"NR");
- //gtk_widget_override_font(b_nr, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_nr), nr==1);
- gtk_widget_show(b_nr);
- gtk_grid_attach(GTK_GRID(grid),b_nr,0,1,2,1);
- g_signal_connect(b_nr,"pressed",G_CALLBACK(nr_cb),NULL);
-
- GtkWidget *b_nr2=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_nr),"NR2");
- //gtk_widget_override_font(b_nr2, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_nr2), nr2==1);
- gtk_widget_show(b_nr2);
- gtk_grid_attach(GTK_GRID(grid),b_nr2,0,2,2,1);
- g_signal_connect(b_nr2,"pressed",G_CALLBACK(nr2_cb),NULL);
-
- GtkWidget *b_anf=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_nr2),"ANF");
- //gtk_widget_override_font(b_anf, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_anf), anf==1);
- gtk_widget_show(b_anf);
- gtk_grid_attach(GTK_GRID(grid),b_anf,0,3,2,1);
- g_signal_connect(b_anf,"pressed",G_CALLBACK(anf_cb),NULL);
-
- GtkWidget *b_snb=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(b_anf),"SNB");
- //gtk_widget_override_font(b_snb, pango_font_description_from_string("Arial 16"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b_snb), snb==1);
- gtk_widget_show(b_snb);
- gtk_grid_attach(GTK_GRID(grid),b_snb,0,4,2,1);
- g_signal_connect(b_snb,"pressed",G_CALLBACK(snb_cb),NULL);
-
- gtk_container_add(GTK_CONTAINER(content),grid);
-
- GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK);
- //gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 16"));
- g_signal_connect(close_button,"clicked",G_CALLBACK(close_cb),(gpointer *)NULL);
- gtk_widget_show_all(dialog);
-
- last_dialog=dialog;
-
- int result=gtk_dialog_run(GTK_DIALOG(dialog));
-
- }
-*/
+static void vox_cb(GtkWidget *widget, gpointer data) {
+ vox=vox==1?0:1;
+ vfo_update(NULL);
}
static void stop() {
int result=gtk_dialog_run(GTK_DIALOG(dialog));
}
-/*
-static void adc_cb(GtkWidget *widget, gpointer data) {
- int adc0=adc[0];
- adc[0]=adc[1];
- adc[1]=adc0;
-
- char label[16];
- gtk_grid_remove_row(GTK_GRID(toolbar_top_1),0);
-
- sprintf(label,"RX0=%d",adc[0]);
- GtkWidget *rx0=gtk_label_new(label);
- //gtk_widget_override_font(rx0, pango_font_description_from_string("Arial 16"));
- gtk_widget_show(rx0);
- gtk_grid_attach(GTK_GRID(toolbar_top_1),rx0,0,0,1,1);
-
- sprintf(label,"RX1=%d",adc[1]);
- GtkWidget *rx1=gtk_label_new(label);
- //gtk_widget_override_font(rx1, pango_font_description_from_string("Arial 16"));
- gtk_widget_show(rx1);
- gtk_grid_attach(GTK_GRID(toolbar_top_1),rx1,1,0,1,1);
-}
-*/
-
void lock_cb(GtkWidget *widget, gpointer data) {
locked=locked==1?0:1;
vfo_update(NULL);
}
void mox_cb(GtkWidget *widget, gpointer data) {
-
-
if(getTune()==1) {
setTune(0);
}
} else if(canTransmit() || tx_out_of_band) {
setMox(1);
}
- vfo_update(NULL);
+ g_idle_add(vfo_update,NULL);
+}
+
+int mox_update(void *data) {
+ if(getTune()==1) {
+ setTune(0);
+ }
+ setMox((int)data);
+ return 0;
}
int ptt_update(void *data) {
+ int mode;
+ if(split) {
+ mode=vfo[1].mode;
+ } else {
+ mode=vfo[0].mode;
+ }
if(protocol==NEW_PROTOCOL || (mode!=modeCWU && mode!=modeCWL)) {
mox_cb(NULL,NULL);
}
return 0;
}
-static void tune_cb(GtkWidget *widget, gpointer data) {
+void tune_cb(GtkWidget *widget, gpointer data) {
if(getMox()==1) {
setMox(0);
}
vfo_update(NULL);
}
-static gboolean rit_timer_cb(gpointer data) {
- if((int)data==1) {
- rit+=rit_increment;
- } else {
- rit-=rit_increment;
- }
- if(rit>1000) rit=1000;
- if(rit<-1000) rit=-1000;
- vfo_update(NULL);
- return TRUE;
-}
-
void sim_s1_pressed_cb(GtkWidget *widget, gpointer data) {
- if(function) {
- rit+=rit_increment;
- if(rit>1000) rit=1000;
- vfo_update(NULL);
- rit_timer=g_timeout_add(200,rit_timer_cb,(gpointer)1);
- } else {
- BAND* band;
- BANDSTACK_ENTRY *entry;
- if(toolbar_dialog_buttons) {
+ switch(function) {
+ case 0:
band_cb(widget,data);
- } else {
- int b=band_get_current();
- if(function) {
- b--;
- if(b<0) {
- b=BANDS-1;
- }
-#ifdef LIMESDR
- if(protocol!=LIMESDR_PROTOCOL) {
- if(b==band3400) {
- b=band6;
- }
- }
-#endif
+ break;
+ case 1:
+ lock_cb(widget,data);
+ break;
+ case 2:
+ freq_cb(widget,data);
+ break;
+ case 3:
+ full_tune=full_tune==1?0:1;
+ if(full_tune) {
+ set_button_text_color(sim_s2,"black");
+ set_button_text_color(sim_s1,"red");
} else {
- b++;
- if(b>=BANDS) {
- b=0;
- }
-#ifdef LIMESDR
- if(protocol!=LIMESDR_PROTOCOL) {
- if(b==band70) {
- b=bandGen;
- }
- }
-#endif
+ set_button_text_color(sim_s1,"black");
}
- band=band_set_current(b);
- entry=bandstack_entry_get_current();
-
- setFrequency(entry->frequencyA);
- setMode(entry->mode);
- FILTER* band_filters=filters[entry->mode];
- FILTER* band_filter=&band_filters[entry->filter];
- setFilter(band_filter->low,band_filter->high);
-
- band=band_get_current_band();
- set_alex_rx_antenna(band->alexRxAntenna);
- set_alex_tx_antenna(band->alexTxAntenna);
- set_alex_attenuation(band->alexAttenuation);
- vfo_update(NULL);
-
- calcDriveLevel();
- calcTuneDriveLevel();
- }
+ break;
}
}
void sim_s1_released_cb(GtkWidget *widget, gpointer data) {
- if(function) {
- g_source_remove(rit_timer);
+ switch(function) {
+ case 0:
+ break;
+ case 1:
+ break;
+ case 2:
+ break;
+ case 3:
+ break;
}
}
void sim_s2_pressed_cb(GtkWidget *widget, gpointer data) {
- if(function) {
- rit-=rit_increment;
- if(rit<-1000) rit=-1000;
- vfo_update(NULL);
- rit_timer=g_timeout_add(200,rit_timer_cb,(gpointer)-1);
- } else {
- BANDSTACK_ENTRY *entry;
- if(toolbar_dialog_buttons) {
+ switch(function) {
+ case 0:
bandstack_cb(widget,data);
- } else {
- if(function) {
- entry=bandstack_entry_previous();
+ break;
+ case 1:
+ ctun_cb(widget,data);
+ break;
+ case 2:
+ mem_cb(widget,data);
+ break;
+ case 3:
+ memory_tune=memory_tune==1?0:1;
+ if(memory_tune) {
+ set_button_text_color(sim_s1,"black");
+ set_button_text_color(sim_s2,"red");
} else {
- entry=bandstack_entry_next();
+ set_button_text_color(sim_s2,"black");
}
- setFrequency(entry->frequencyA);
- setMode(entry->mode);
- FILTER* band_filters=filters[entry->mode];
- FILTER* band_filter=&band_filters[entry->filter];
- setFilter(band_filter->low,band_filter->high);
- vfo_update(NULL);
- }
+ break;
}
}
void sim_s2_released_cb(GtkWidget *widget, gpointer data) {
- if(function) {
- g_source_remove(rit_timer);
+ switch(function) {
+ case 0:
+ break;
+ case 1:
+ break;
+ case 2:
+ break;
+ case 3:
+ break;
}
}
-void sim_s3_cb(GtkWidget *widget, gpointer data) {
- if(function) {
- ctun=ctun==1?0:1;
- if(!ctun) {
- ddsOffset=0;
- wdsp_set_offset(ddsOffset);
- }
- vfo_update(NULL);
- } else {
- BAND* band;
- BANDSTACK_ENTRY *entry;
-
- if(toolbar_dialog_buttons) {
+void sim_s3_pressed_cb(GtkWidget *widget, gpointer data) {
+ switch(function) {
+ case 0:
mode_cb(widget,data);
- } else {
- band=band_get_current_band();
- entry=bandstack_entry_get_current();
- if(function) {
- entry->mode--;
- if(entry->mode<0) {
- entry->mode=MODES-1;
- }
- } else {
- entry->mode++;
- if(entry->mode>=MODES) {
- entry->mode=0;
- }
- }
- setMode(entry->mode);
-
- FILTER* band_filters=filters[entry->mode];
- FILTER* band_filter=&band_filters[entry->filter];
- setFilter(band_filter->low,band_filter->high);
-
- vfo_update(NULL);
- }
+ break;
+ case 1:
+ // A>B
+ atob_cb(widget,data);
+ break;
+ case 2:
+ vox_cb(widget,data);
+ break;
+ case 3:
+ break;
}
}
-void sim_s4_cb(GtkWidget *widget, gpointer data) {
- BAND* band;
- BANDSTACK_ENTRY *entry;
+void sim_s3_released_cb(GtkWidget *widget, gpointer data) {
+ switch(function) {
+ case 0:
+ break;
+ case 1:
+ break;
+ case 2:
+ break;
+ case 3:
+ break;
+ }
+}
- if(toolbar_dialog_buttons) {
- if(function) {
- } else {
+void sim_s4_pressed_cb(GtkWidget *widget, gpointer data) {
+ switch(function) {
+ case 0:
filter_cb(widget,data);
- }
- } else {
- band=band_get_current_band();
- entry=bandstack_entry_get_current();
- // note order of filter reversed (largest first)
- if(function) {
- entry->filter++;
- if(entry->filter>=FILTERS) {
- entry->filter=0;
- }
- } else {
- entry->filter--;
- if(entry->filter<0) {
- entry->filter=FILTERS-1;
- }
- }
-
- FILTER* band_filters=filters[entry->mode];
- FILTER* band_filter=&band_filters[entry->filter];
- setFilter(band_filter->low,band_filter->high);
-
- vfo_update(NULL);
+ break;
+ case 1:
+ // A<B
+ btoa_cb(widget,data);
+ break;
+ case 2:
+ rit_cb(widget,(void *)1);
+ break;
+ case 3:
+ break;
}
+}
+void sim_s4_released_cb(GtkWidget *widget, gpointer data) {
+ switch(function) {
+ case 0:
+ break;
+ case 1:
+ break;
+ case 2:
+ g_source_remove(rit_timer);
+ break;
+ case 3:
+ break;
+ }
}
-void sim_s5_cb(GtkWidget *widget, gpointer data) {
- if(toolbar_dialog_buttons) {
- if(function) {
- } else {
+void sim_s5_pressed_cb(GtkWidget *widget, gpointer data) {
+ switch(function) {
+ case 0:
noise_cb(widget,data);
- }
- } else {
- if(function) {
- if(nr) {
- nr=0;
- } else if(nr2) {
- nr2=0;
- nr=1;
- } else if(anf) {
- anf=0;
- nr2=1;
- } else if(snb) {
- snb=0;
- anf=1;
- } else {
- snb=1;
- }
- } else {
- if(nr) {
- nr=0;
- nr2=1;
- } else if(nr2) {
- nr2=0;
- anf=1;
- } else if(anf) {
- anf=0;
- snb=1;
- } else if(snb) {
- snb=0;
- } else {
- nr=1;
- }
- }
- SetRXAANRRun(CHANNEL_RX0, nr);
- SetRXAEMNRRun(CHANNEL_RX0, nr2);
- SetRXAANFRun(CHANNEL_RX0, anf);
- SetRXASNBARun(CHANNEL_RX0, snb);
- vfo_update(NULL);
+ break;
+ case 1:
+ // A<>B
+ aswapb_cb(widget,data);
+ break;
+ case 2:
+ rit_cb(widget,(void *)-1);
+ break;
+ case 3:
+ break;
}
}
-void sim_s6_cb(GtkWidget *widget, gpointer data) {
- if(toolbar_dialog_buttons) {
- if(function) {
- lock_cb(widget,data);
- } else {
+void sim_s5_released_cb(GtkWidget *widget, gpointer data) {
+ switch(function) {
+ case 0:
+ break;
+ case 1:
+ break;
+ case 2:
+ g_source_remove(rit_timer);
+ break;
+ case 3:
+ break;
+ }
+}
+
+void sim_s6_pressed_cb(GtkWidget *widget, gpointer data) {
+ switch(function) {
+ case 0:
agc_cb(widget,data);
- }
- } else {
- if(function) {
- agc--;
- if(agc<0) {
- agc=3;
- }
- } else {
- agc++;
- if(agc>=4) {
- agc=0;
- }
- }
- SetRXAAGCMode(CHANNEL_RX0, agc);
- vfo_update(NULL);
+ break;
+ case 1:
+ split_cb(widget,data);
+ break;
+ case 2:
+ break;
+ case 3:
+ break;
+ }
+}
+
+void sim_s6_released_cb(GtkWidget *widget, gpointer data) {
+ switch(function) {
+ case 0:
+ break;
+ case 1:
+ break;
+ case 2:
+ break;
+ case 3:
+ break;
}
}
void sim_mox_cb(GtkWidget *widget, gpointer data) {
- if(function) {
- tune_cb((GtkWidget *)NULL, (gpointer)NULL);
- } else {
- mox_cb((GtkWidget *)NULL, (gpointer)NULL);
+ switch(function) {
+ case 0:
+ case 1:
+ case 2:
+ mox_cb((GtkWidget *)NULL, (gpointer)NULL);
+ break;
+ case 3:
+ tune_cb((GtkWidget *)NULL, (gpointer)NULL);
+ break;
}
- //vfo_update(NULL);
}
void sim_function_cb(GtkWidget *widget, gpointer data) {
- function=function==1?0:1;
+ function++;
+ if(function>MAX_FUNCTION) {
+ function=0;
+ }
update_toolbar_labels();
vfo_update(NULL);
}
g_signal_connect(G_OBJECT(sim_mox),"clicked",G_CALLBACK(sim_mox_cb),NULL);
gtk_grid_attach(GTK_GRID(toolbar),sim_mox,0,0,4,1);
- sim_s1=gtk_button_new_with_label("Band ^");
+ sim_s1=gtk_button_new_with_label("Band");
gtk_widget_set_size_request (sim_s1, button_width, 0);
//gtk_widget_override_font(sim_s1, pango_font_description_from_string("Arial 16"));
g_signal_connect(G_OBJECT(sim_s1),"pressed",G_CALLBACK(sim_s1_pressed_cb),NULL);
g_signal_connect(G_OBJECT(sim_s1),"released",G_CALLBACK(sim_s1_released_cb),NULL);
gtk_grid_attach(GTK_GRID(toolbar),sim_s1,4,0,4,1);
- sim_s2=gtk_button_new_with_label("BStack ^");
+ sim_s2=gtk_button_new_with_label("BStack");
gtk_widget_set_size_request (sim_s2, button_width, 0);
//gtk_widget_override_font(sim_s2, pango_font_description_from_string("Arial 16"));
g_signal_connect(G_OBJECT(sim_s2),"pressed",G_CALLBACK(sim_s2_pressed_cb),NULL);
g_signal_connect(G_OBJECT(sim_s2),"released",G_CALLBACK(sim_s2_released_cb),NULL);
gtk_grid_attach(GTK_GRID(toolbar),sim_s2,8,0,4,1);
- sim_s3=gtk_button_new_with_label("Mode ^");
+ sim_s3=gtk_button_new_with_label("Mode");
//gtk_widget_override_font(sim_s3, pango_font_description_from_string("Arial 16"));
- g_signal_connect(G_OBJECT(sim_s3),"clicked",G_CALLBACK(sim_s3_cb),NULL);
+ g_signal_connect(G_OBJECT(sim_s3),"pressed",G_CALLBACK(sim_s3_pressed_cb),NULL);
+ g_signal_connect(G_OBJECT(sim_s3),"released",G_CALLBACK(sim_s3_released_cb),NULL);
gtk_grid_attach(GTK_GRID(toolbar),sim_s3,12,0,4,1);
- sim_s4=gtk_button_new_with_label("Filter ^");
+ sim_s4=gtk_button_new_with_label("Filter");
//gtk_widget_override_font(sim_s4, pango_font_description_from_string("Arial 16"));
- g_signal_connect(G_OBJECT(sim_s4),"clicked",G_CALLBACK(sim_s4_cb),NULL);
+ g_signal_connect(G_OBJECT(sim_s4),"pressed",G_CALLBACK(sim_s4_pressed_cb),NULL);
+ g_signal_connect(G_OBJECT(sim_s4),"released",G_CALLBACK(sim_s4_released_cb),NULL);
gtk_grid_attach(GTK_GRID(toolbar),sim_s4,16,0,4,1);
- sim_s5=gtk_button_new_with_label("Noise ^");
+ sim_s5=gtk_button_new_with_label("Noise");
//gtk_widget_override_font(sim_s5, pango_font_description_from_string("Arial 16"));
- g_signal_connect(G_OBJECT(sim_s5),"clicked",G_CALLBACK(sim_s5_cb),NULL);
+ g_signal_connect(G_OBJECT(sim_s5),"pressed",G_CALLBACK(sim_s5_pressed_cb),NULL);
+ g_signal_connect(G_OBJECT(sim_s5),"released",G_CALLBACK(sim_s5_released_cb),NULL);
gtk_grid_attach(GTK_GRID(toolbar),sim_s5,20,0,4,1);
- sim_s6=gtk_button_new_with_label("AGC ^");
+ sim_s6=gtk_button_new_with_label("AGC");
//gtk_widget_override_font(sim_s6, pango_font_description_from_string("Arial 16"));
- g_signal_connect(G_OBJECT(sim_s6),"clicked",G_CALLBACK(sim_s6_cb),NULL);
+ g_signal_connect(G_OBJECT(sim_s6),"pressed",G_CALLBACK(sim_s6_pressed_cb),NULL);
+ g_signal_connect(G_OBJECT(sim_s6),"released",G_CALLBACK(sim_s6_released_cb),NULL);
gtk_grid_attach(GTK_GRID(toolbar),sim_s6,24,0,4,1);
sim_function=gtk_button_new_with_label("Function");
//gtk_widget_override_font(sim_function, pango_font_description_from_string("Arial 16"));
- g_signal_connect(G_OBJECT(sim_function),"clicked",G_CALLBACK(function_cb),NULL);
+ g_signal_connect(G_OBJECT(sim_function),"clicked",G_CALLBACK(sim_function_cb),NULL);
gtk_grid_attach(GTK_GRID(toolbar),sim_function,28,0,4,1);
- update_toolbar_labels();
+ //update_toolbar_labels();
last_dialog=NULL;
extern int function;
+
void update_toolbar_labels();
int ptt_update(void *data);
-void lock_cb(GtkWidget *widget, gpointer data);
-
+int mox_update(void *data);
+void tune_cb(GtkWidget *widget, gpointer data);
void sim_mox_cb(GtkWidget *widget, gpointer data);
void sim_s1_pressed_cb(GtkWidget *widget, gpointer data);
void sim_s1_released_cb(GtkWidget *widget, gpointer data);
void sim_s2_pressed_cb(GtkWidget *widget, gpointer data);
void sim_s2_released_cb(GtkWidget *widget, gpointer data);
-void sim_s3_cb(GtkWidget *widget, gpointer data);
-void sim_s4_cb(GtkWidget *widget, gpointer data);
-void sim_s5_cb(GtkWidget *widget, gpointer data);
-void sim_s6_cb(GtkWidget *widget, gpointer data);
+void sim_s3_pressed_cb(GtkWidget *widget, gpointer data);
+void sim_s3_released_cb(GtkWidget *widget, gpointer data);
+void sim_s4_pressed_cb(GtkWidget *widget, gpointer data);
+void sim_s4_released_cb(GtkWidget *widget, gpointer data);
+void sim_s5_pressed_cb(GtkWidget *widget, gpointer data);
+void sim_s5_released_cb(GtkWidget *widget, gpointer data);
+void sim_s6_pressed_cb(GtkWidget *widget, gpointer data);
+void sim_s6_released_cb(GtkWidget *widget, gpointer data);
void sim_function_cb(GtkWidget *widget, gpointer data);
GtkWidget *toolbar_init(int my_width, int my_height, GtkWidget* parent);
--- /dev/null
+/* Copyright (C)
+* 2017 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*/
+
+#include <gtk/gtk.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <wdsp.h>
+
+#include "alex.h"
+#include "band.h"
+#include "bandstack.h"
+#include "channel.h"
+#include "main.h"
+#include "meter.h"
+#include "mode.h"
+#include "property.h"
+#include "radio.h"
+#include "vfo.h"
+#include "meter.h"
+#include "tx_panadapter.h"
+#include "waterfall.h"
+#include "transmitter.h"
+
+#define min(x,y) (x<y?x:y)
+#define max(x,y) (x<y?y:x)
+
+static int filterLow;
+static int filterHigh;
+
+void reconfigure_transmitter(TRANSMITTER *tx,int height) {
+ gtk_widget_set_size_request(tx->panadapter, tx->width, height);
+}
+
+void transmitter_save_state(TRANSMITTER *tx) {
+ char name[128];
+ char value[128];
+
+ sprintf(name,"transmitter.%d.fps",tx->id);
+ sprintf(value,"%d",tx->fps);
+ setProperty(name,value);
+ sprintf(name,"transmitter.%d.filter_low",tx->id);
+ sprintf(value,"%d",tx->filter_low);
+ setProperty(name,value);
+ sprintf(name,"transmitter.%d.filter_high",tx->id);
+ sprintf(value,"%d",tx->filter_high);
+ setProperty(name,value);
+ sprintf(name,"transmitter.%d.alex_antenna",tx->id);
+ sprintf(value,"%d",tx->alex_antenna);
+ setProperty(name,value);
+
+ sprintf(name,"transmitter.%d.local_microphone",tx->id);
+ sprintf(value,"%d",tx->local_microphone);
+ setProperty(name,value);
+ sprintf(name,"transmitter.%d.input_device",tx->id);
+ sprintf(value,"%d",tx->input_device);
+ setProperty(name,value);
+
+}
+
+void transmitter_restore_state(TRANSMITTER *tx) {
+ char name[128];
+ char *value;
+
+ sprintf(name,"transmitter.%d.fps",tx->id);
+ value=getProperty(name);
+ if(value) tx->fps=atoi(value);
+ sprintf(name,"transmitter.%d.filter_low",tx->id);
+ value=getProperty(name);
+ if(value) tx->filter_low=atoi(value);
+ sprintf(name,"transmitter.%d.filter_high",tx->id);
+ value=getProperty(name);
+ if(value) tx->filter_high=atoi(value);
+ sprintf(name,"transmitter.%d.alex_antenna",tx->id);
+ value=getProperty(name);
+ if(value) tx->alex_antenna=atoi(value);
+
+ sprintf(name,"transmitter.%d.local_microphone",tx->id);
+ value=getProperty(name);
+ if(value) tx->local_microphone=atoi(value);
+ sprintf(name,"transmitter.%d.input_device",tx->id);
+ value=getProperty(name);
+ if(value) tx->input_device=atoi(value);
+}
+
+static gint update_display(gpointer data) {
+ TRANSMITTER *tx=(TRANSMITTER *)data;
+ int rc;
+ double fwd;
+ double rev;
+ double exciter;
+
+ if(tx->displaying) {
+ GetPixels(tx->id,0,tx->pixel_samples,&rc);
+ if(rc) {
+ tx_panadapter_update(tx);
+ } else {
+//fprintf(stderr,"tx: update_display: GetPixels: id=%d returned %d\n",tx->id,rc);
+ }
+
+ double alc=GetTXAMeter(tx->id, alc);
+ double constant1=3.3;
+ double constant2=0.095;
+
+ if(protocol==ORIGINAL_PROTOCOL) {
+ switch(device) {
+ case DEVICE_METIS:
+ constant1=3.3;
+ constant2=0.09;
+ break;
+ case DEVICE_HERMES:
+ constant1=3.3;
+ constant2=0.095;
+ break;
+ case DEVICE_ANGELIA:
+ constant1=3.3;
+ constant2=0.095;
+ break;
+ case DEVICE_ORION:
+ constant1=5.0;
+ constant2=0.108;
+ break;
+ case DEVICE_ORION2:
+ constant1=5.0;
+ constant2=0.108;
+ break;
+ case DEVICE_HERMES_LITE:
+ break;
+ }
+
+ int power=alex_forward_power;
+ if(power==0) {
+ power=exciter_power;
+ }
+ double v1;
+ v1=((double)power/4095.0)*constant1;
+ fwd=(v1*v1)/constant2;
+
+ power=exciter_power;
+ v1=((double)power/4095.0)*constant1;
+ exciter=(v1*v1)/constant2;
+
+ rev=0.0;
+ if(alex_forward_power!=0) {
+ power=alex_reverse_power;
+ v1=((double)power/4095.0)*constant1;
+ rev=(v1*v1)/constant2;
+ }
+ } else {
+ switch(device) {
+ case NEW_DEVICE_ATLAS:
+ constant1=3.3;
+ constant2=0.09;
+ break;
+ case NEW_DEVICE_HERMES:
+ constant1=3.3;
+ constant2=0.09;
+ break;
+ case NEW_DEVICE_HERMES2:
+ constant1=3.3;
+ constant2=0.095;
+ break;
+ case NEW_DEVICE_ANGELIA:
+ constant1=3.3;
+ constant2=0.095;
+ break;
+ case NEW_DEVICE_ORION:
+ constant1=5.0;
+ constant2=0.108;
+ break;
+ case NEW_DEVICE_ORION2:
+ constant1=5.0;
+ constant2=0.108;
+ break;
+ case NEW_DEVICE_HERMES_LITE:
+ constant1=3.3;
+ constant2=0.09;
+ break;
+ }
+
+ int power=alex_forward_power;
+ if(power==0) {
+ power=exciter_power;
+ }
+ double v1;
+ v1=((double)power/4095.0)*constant1;
+ fwd=(v1*v1)/constant2;
+
+ power=exciter_power;
+ v1=((double)power/4095.0)*constant1;
+ exciter=(v1*v1)/constant2;
+
+ rev=0.0;
+ if(alex_forward_power!=0) {
+ power=alex_reverse_power;
+ v1=((double)power/4095.0)*constant1;
+ rev=(v1*v1)/constant2;
+ }
+ }
+
+ meter_update(POWER,fwd,rev,exciter,alc);
+
+ return TRUE; // keep going
+ }
+ return FALSE; // no more timer events
+}
+
+
+static void init_analyzer(TRANSMITTER *tx) {
+ int flp[] = {0};
+ double keep_time = 0.1;
+ int n_pixout=1;
+ int spur_elimination_ffts = 1;
+ int data_type = 1;
+ int fft_size = 8192;
+ int window_type = 4;
+ double kaiser_pi = 14.0;
+ int overlap = 2048;
+ int clip = 0;
+ int span_clip_l = 0;
+ int span_clip_h = 0;
+ int pixels=tx->pixels;
+ int stitches = 1;
+ int avm = 0;
+ double tau = 0.001 * 120.0;
+ int calibration_data_set = 0;
+ double span_min_freq = 0.0;
+ double span_max_freq = 0.0;
+
+ int max_w = fft_size + (int) min(keep_time * (double) tx->fps, keep_time * (double) fft_size * (double) tx->fps);
+
+ overlap = (int)max(0.0, ceil(fft_size - (double)tx->mic_sample_rate / (double)tx->fps));
+
+ fprintf(stderr,"SetAnalyzer id=%d buffer_size=%d overlap=%d\n",tx->id,tx->output_samples,overlap);
+
+
+ SetAnalyzer(tx->id,
+ n_pixout,
+ spur_elimination_ffts, //number of LO frequencies = number of ffts used in elimination
+ data_type, //0 for real input data (I only); 1 for complex input data (I & Q)
+ flp, //vector with one elt for each LO frequency, 1 if high-side LO, 0 otherwise
+ fft_size, //size of the fft, i.e., number of input samples
+ tx->output_samples, //number of samples transferred for each OpenBuffer()/CloseBuffer()
+ window_type, //integer specifying which window function to use
+ kaiser_pi, //PiAlpha parameter for Kaiser window
+ overlap, //number of samples each fft (other than the first) is to re-use from the previous
+ clip, //number of fft output bins to be clipped from EACH side of each sub-span
+ span_clip_l, //number of bins to clip from low end of entire span
+ span_clip_h, //number of bins to clip from high end of entire span
+ pixels, //number of pixel values to return. may be either <= or > number of bins
+ stitches, //number of sub-spans to concatenate to form a complete span
+ calibration_data_set, //identifier of which set of calibration data to use
+ span_min_freq, //frequency at first pixel value8192
+ span_max_freq, //frequency at last pixel value
+ max_w //max samples to hold in input ring buffers
+ );
+
+}
+
+#ifdef INCLUDED
+void transmitter_change_sample_rate(TRANSMITTER *tx,int sample_rate) {
+ SetChannelState(tx->id,0,1);
+ tx->mic_sample_rate=sample_rate;
+ tx->output_samples=tx->buffer_size/(tx->mic_sample_rate/48000);
+ free(tx->mic_input_buffer);
+ tx->mic_input_buffer=malloc(sizeof(double)*2*tx->buffer_size);
+ init_analyzer(tx);
+fprintf(stderr,"transmitter_change_sample_rate: id=%d rate=%d output_samples=%d\n",tx->id, tx->mic_sample_rate, tx->output_samples);
+ SetChannelState(tx->id,1,0);
+}
+#endif
+
+static void create_visual(TRANSMITTER *tx) {
+
+ fprintf(stderr,"transmitter: create_visual: id=%d\n",tx->id);
+
+ tx->panel=gtk_fixed_new();
+ gtk_widget_set_size_request (tx->panel, tx->width, tx->height);
+
+ if(tx->display_panadapter) {
+ tx_panadapter_init(tx,tx->width,tx->height);
+ gtk_fixed_put(GTK_FIXED(tx->panel),tx->panadapter,0,0);
+ }
+
+}
+
+TRANSMITTER *create_transmitter(int id, int buffer_size, int fft_size, int fps, int width, int height) {
+ int rc;
+
+ TRANSMITTER *tx=malloc(sizeof(TRANSMITTER));
+ tx->id=id;
+ tx->buffer_size=buffer_size;
+ tx->fft_size=fft_size;
+ tx->fps=fps;
+ if(protocol==ORIGINAL_PROTOCOL) {
+ tx->mic_sample_rate=48000;
+// tx->mic_sample_rate=receiver[0]->sample_rate;
+ tx->mic_dsp_rate=48000;
+ tx->iq_output_rate=48000;
+// tx->output_samples=tx->buffer_size/(tx->mic_sample_rate/48000);
+ tx->output_samples=tx->buffer_size;
+ tx->pixels=width;
+ } else {
+ tx->mic_sample_rate=48000;
+ tx->mic_dsp_rate=48000;
+ tx->iq_output_rate=192000;
+ tx->output_samples=tx->buffer_size*4;
+ tx->pixels=width*4; // to allow 192k to 48k conversion
+ }
+
+ tx->width=width;
+ tx->height=height;
+ tx->display_panadapter=1;
+ tx->display_waterfall=0;
+
+ tx->panadapter_high=20;
+ tx->panadapter_low=-80;
+
+ tx->displaying=0;
+
+ tx->alex_antenna=ALEX_TX_ANTENNA_1;
+
+fprintf(stderr,"create_transmitter: id=%d buffer_size=%d mic_sample_rate=%d mic_dsp_rate=%d iq_output_rate=%d output_samples=%d fps=%d\n",tx->id, tx->buffer_size, tx->mic_sample_rate, tx->mic_dsp_rate, tx->iq_output_rate, tx->output_samples,tx->fps);
+
+ tx->filter_low=tx_filter_low;
+ tx->filter_high=tx_filter_high;
+
+ transmitter_restore_state(tx);
+
+ if(split) {
+ tx->mode=vfo[VFO_B].mode;
+ } else {
+ tx->mode=vfo[VFO_A].mode;
+ }
+
+ // allocate buffers
+fprintf(stderr,"transmitter: allocate buffers: mic_input_buffer=%d iq_output_buffer=%d pixels=%d\n",tx->buffer_size,tx->output_samples,tx->pixels);
+ tx->mic_input_buffer=malloc(sizeof(double)*2*tx->buffer_size);
+ tx->iq_output_buffer=malloc(sizeof(double)*2*tx->output_samples);
+ tx->samples=0;
+ tx->pixel_samples=malloc(sizeof(float)*tx->pixels);
+
+ fprintf(stderr,"create_transmitter: OpenChannel id=%d buffer_size=%d fft_size=%d sample_rate=%d dspRate=%d outputRate=%d\n",
+ tx->id,
+ tx->buffer_size,
+ tx->fft_size,
+ tx->mic_sample_rate,
+ tx->mic_dsp_rate,
+ tx->iq_output_rate);
+
+ OpenChannel(tx->id,
+ tx->buffer_size,
+ tx->fft_size,
+ tx->mic_sample_rate,
+ tx->mic_dsp_rate,
+ tx->iq_output_rate,
+ 1, // transmit
+ 0, // run
+ 0.010, 0.025, 0.0, 0.010, 0);
+
+ SetTXAMode(tx->id, tx->mode);
+ tx_set_filter(tx,tx_filter_low,tx_filter_high);
+ SetTXABandpassWindow(tx->id, 1);
+ SetTXABandpassRun(tx->id, 1);
+
+ SetTXAFMDeviation(tx->id,(double)deviation);
+ SetTXAFMEmphPosition(tx->id,pre_emphasize);
+
+ SetTXACFIRRun(tx->id, protocol==NEW_PROTOCOL?1:0); // turned on if new protocol
+ if(enable_tx_equalizer) {
+ SetTXAGrphEQ(tx->id, tx_equalizer);
+ SetTXAEQRun(tx->id, 1);
+ } else {
+ SetTXAEQRun(tx->id, 0);
+ }
+ SetTXACTCSSRun(tx->id, 0);
+ SetTXAAMSQRun(tx->id, 0);
+ SetTXACompressorRun(tx->id, 0);
+ SetTXAosctrlRun(tx->id, 0);
+
+ SetTXAALCAttack(tx->id, 1);
+ SetTXAALCDecay(tx->id, 10);
+ SetTXAALCSt(tx->id, tx_alc);
+
+ SetTXALevelerAttack(tx->id, 1);
+ SetTXALevelerDecay(tx->id, 500);
+ SetTXALevelerTop(tx->id, 5.0);
+ SetTXALevelerSt(tx->id, tx_leveler);
+
+ SetTXAPreGenMode(tx->id, 0);
+ SetTXAPreGenToneMag(tx->id, 0.0);
+ SetTXAPreGenToneFreq(tx->id, 0.0);
+ SetTXAPreGenRun(tx->id, 0);
+
+ SetTXAPostGenMode(tx->id, 0);
+ SetTXAPostGenToneMag(tx->id, tone_level);
+ SetTXAPostGenToneFreq(tx->id, 0.0);
+ SetTXAPostGenRun(tx->id, 0);
+
+ double gain=pow(10.0, mic_gain / 20.0);
+ SetTXAPanelGain1(tx->id,gain);
+ SetTXAPanelRun(tx->id, 1);
+
+ XCreateAnalyzer(tx->id, &rc, 262144, 1, 1, "");
+ if (rc != 0) {
+ fprintf(stderr, "XCreateAnalyzer id=%d failed: %d\n",tx->id,rc);
+ } else {
+ init_analyzer(tx);
+ }
+
+ create_visual(tx);
+
+ return tx;
+}
+
+void tx_set_mode(TRANSMITTER* tx,int mode) {
+ if(tx!=NULL) {
+ tx->mode=mode;
+ SetTXAMode(tx->id, tx->mode);
+ tx_set_filter(tx,tx_filter_low,tx_filter_high);
+ }
+}
+
+void tx_set_filter(TRANSMITTER *tx,int low,int high) {
+ int mode;
+ if(split) {
+ mode=vfo[1].mode;
+ } else {
+ mode=vfo[0].mode;
+ }
+ switch(mode) {
+ case modeLSB:
+ case modeCWL:
+ case modeDIGL:
+ tx->filter_low=-high;
+ tx->filter_high=-low;
+ break;
+ case modeUSB:
+ case modeCWU:
+ case modeDIGU:
+ tx->filter_low=low;
+ tx->filter_high=high;
+ break;
+ case modeDSB:
+ case modeAM:
+ case modeSAM:
+ tx->filter_low=-high;
+ tx->filter_high=high;
+ break;
+ case modeFMN:
+ if(deviation==2500) {
+ tx->filter_low=-4000;
+ tx->filter_high=4000;
+ } else {
+ tx->filter_low=-8000;
+ tx->filter_high=8000;
+ }
+ break;
+ case modeDRM:
+ tx->filter_low=7000;
+ tx->filter_high=17000;
+ break;
+ }
+
+ double fl=tx->filter_low;
+ double fh=tx->filter_high;
+
+ if(split) {
+ fl+=vfo[VFO_B].offset;
+ fh+=vfo[VFO_B].offset;
+ } else {
+ fl+=vfo[VFO_A].offset;
+ fh+=vfo[VFO_A].offset;
+ }
+ SetTXABandpassFreqs(tx->id, fl,fh);
+}
+
+void tx_set_pre_emphasize(TRANSMITTER *tx,int state) {
+ SetTXAFMEmphPosition(tx->id,state);
+}
+
+static void full_tx_buffer(TRANSMITTER *tx) {
+ long isample;
+ long qsample;
+ double gain;
+ int j;
+ int error;
+ int mode;
+
+ switch(protocol) {
+ case ORIGINAL_PROTOCOL:
+ gain=32767.0; // 16 bit
+ break;
+ case NEW_PROTOCOL:
+ gain=8388607.0; // 24 bit
+ break;
+ }
+
+ if(vox_enabled || vox_setting) {
+ if(split) {
+ mode=vfo[1].mode;
+ } else {
+ mode=vfo[0].mode;
+ }
+ switch(mode) {
+ case modeLSB:
+ case modeUSB:
+ case modeDSB:
+ case modeFMN:
+ case modeAM:
+ case modeSAM:
+#ifdef FREEDV
+ case modeFREEDV:
+#endif
+ update_vox(tx);
+ break;
+ }
+ }
+
+ fexchange0(tx->id, tx->mic_input_buffer, tx->iq_output_buffer, &error);
+ if(error!=0) {
+ fprintf(stderr,"full_tx_buffer: id=%d fexchange0: error=%d\n",tx->id,error);
+ }
+
+ if(tx->displaying) {
+ Spectrum0(1, tx->id, 0, 0, tx->iq_output_buffer);
+ }
+
+if(isTransmitting()) {
+#ifdef FREEDV
+ int mode;
+ if(split) {
+ mode=vfo[VFO_B].mode;
+ } else {
+ mode=vfo[VFO_A].mode;
+ }
+
+ if(mode==modeFREEDV) {
+ gain=8388607.0;
+ }
+#endif
+
+ if(radio->device==NEW_DEVICE_ATLAS && atlas_penelope) {
+ if(tune) {
+ gain=gain*tune_drive;
+ } else {
+ gain=gain*(double)drive;
+ }
+ }
+
+ for(j=0;j<tx->output_samples;j++) {
+ isample=(long)(tx->iq_output_buffer[j*2]*gain);
+ qsample=(long)(tx->iq_output_buffer[(j*2)+1]*gain);
+ switch(protocol) {
+ case ORIGINAL_PROTOCOL:
+ old_protocol_iq_samples(isample,qsample);
+ break;
+ case NEW_PROTOCOL:
+ new_protocol_iq_samples(isample,qsample);
+ break;
+ }
+ }
+ }
+
+}
+
+void add_mic_sample(TRANSMITTER *tx,short mic_sample) {
+ double mic_sample_double;
+ int mode;
+ long sample;
+
+ if(split) {
+ mode=vfo[1].mode;
+ } else {
+ mode=vfo[0].mode;
+ }
+
+ switch(mode) {
+#ifdef FREEDV
+ case modeFREEDV:
+ break;
+#endif
+ default:
+ if(mode==modeCWL || mode==modeCWU || tune) {
+ mic_sample_double=0.0;
+ } else {
+ sample=mic_sample<<16;
+ mic_sample_double=(1.0 / 2147483648.0) * (double)(sample);
+ }
+//fprintf(stderr,"add_mic_sample: id=%d sample=%f (%d,%ld)\n",tx->id,mic_sample_double,mic_sample,sample);
+ tx->mic_input_buffer[tx->samples*2]=mic_sample_double;
+ tx->mic_input_buffer[(tx->samples*2)+1]=mic_sample_double;
+ tx->samples++;
+ if(tx->samples==tx->buffer_size) {
+ full_tx_buffer(tx);
+ tx->samples=0;
+ }
+ break;
+ }
+}
+
+void tx_set_displaying(TRANSMITTER *tx,int state) {
+ tx->displaying=state;
+ if(state) {
+fprintf(stderr,"start tx display update timer: %d\n", 1000/tx->fps);
+ tx->update_timer_id=gdk_threads_add_timeout_full(G_PRIORITY_HIGH_IDLE,1000/tx->fps, update_display, tx, NULL);
+ }
+}
+
--- /dev/null
+/* Copyright (C)
+* 2017 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*/
+
+#ifndef _TRANSMITTER_H
+#define _TRANSMITTER_H
+
+#include <gtk/gtk.h>
+
+#define AUDIO_BUFFER_SIZE 260
+
+typedef struct _transmitter {
+ int id;
+ int fps;
+ int displaying;
+ int mic_sample_rate;
+ int mic_dsp_rate;
+ int iq_output_rate;
+ int buffer_size;
+ int fft_size;
+ int pixels;
+ int samples;
+ int output_samples;
+ double *mic_input_buffer;
+ double *iq_output_buffer;
+
+ float *pixel_samples;
+ int display_panadapter;
+ int display_waterfall;
+ gint update_timer_id;
+
+ int mode;
+ int filter_low;
+ int filter_high;
+
+/*
+ long long frequency;
+ long long display_frequency;
+ long long dds_frequency;
+ long long dds_offset;
+*/
+ int alex_antenna;
+
+ int width;
+ int height;
+
+ GtkWidget *panel;
+ GtkWidget *panadapter;
+
+ int panadapter_low;
+ int panadapter_high;
+
+ cairo_surface_t *panadapter_surface;
+
+ int local_microphone;
+ int input_device;
+
+} TRANSMITTER;
+
+extern TRANSMITTER *create_transmitter(int id, int buffer_size, int fft_size, int fps, int width, int height);
+
+void reconfigure_transmitter(TRANSMITTER *tx,int height);
+
+extern void tx_set_mode(TRANSMITTER* tx,int m);
+extern void tx_set_filter(TRANSMITTER *tx,int low,int high);
+extern void tx_set_pre_emphasize(TRANSMITTER *tx,int state);
+
+extern void add_mic_sample(TRANSMITTER *tx,short mic_sample);
+
+extern void transmitter_save_state(TRANSMITTER *tx);
+#endif
--- /dev/null
+/*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*/
+
+#include <gtk/gtk.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "audio.h"
+#include "new_menu.h"
+#include "radio.h"
+#include "sliders.h"
+#include "transmitter.h"
+
+static GtkWidget *parent_window=NULL;
+
+static GtkWidget *dialog=NULL;
+
+static GtkWidget *last_filter;
+
+static GtkWidget *linein_b;
+static GtkWidget *micboost_b;
+
+static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ if(dialog!=NULL) {
+ gtk_widget_destroy(dialog);
+ dialog=NULL;
+ sub_menu=NULL;
+ }
+ return TRUE;
+}
+
+static void tx_spin_low_cb (GtkWidget *widget, gpointer data) {
+ tx_filter_low=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
+ tx_set_filter(transmitter,tx_filter_low,tx_filter_high);
+}
+
+static void tx_spin_high_cb (GtkWidget *widget, gpointer data) {
+ tx_filter_high=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
+ tx_set_filter(transmitter,tx_filter_low,tx_filter_high);
+}
+
+static void micboost_cb(GtkWidget *widget, gpointer data) {
+ mic_boost=gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+}
+
+static void linein_cb(GtkWidget *widget, gpointer data) {
+ mic_linein=gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+ g_idle_add(linein_changed,NULL);
+}
+
+static void local_microphone_cb(GtkWidget *widget, gpointer data) {
+ if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
+ if(audio_open_input()==0) {
+ transmitter->local_microphone=1;
+ gtk_widget_hide(linein_b);
+ gtk_widget_hide(micboost_b);
+ } else {
+ transmitter->local_microphone=0;
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
+ gtk_widget_show(linein_b);
+ gtk_widget_show(micboost_b);
+ }
+ } else {
+ if(transmitter->local_microphone) {
+ transmitter->local_microphone=0;
+ audio_close_input();
+ gtk_widget_show(linein_b);
+ gtk_widget_show(micboost_b);
+ }
+ }
+}
+
+static void local_input_changed_cb(GtkWidget *widget, gpointer data) {
+ transmitter->input_device=(int)(long)data;
+ if(transmitter->local_microphone) {
+ audio_close_input();
+ if(audio_open_input()==0) {
+ transmitter->local_microphone=1;
+ } else {
+ transmitter->local_microphone=0;
+ }
+ }
+}
+
+static gboolean emp_cb (GtkWidget *widget, gpointer data) {
+ pre_emphasize=gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+ tx_set_pre_emphasize(transmitter,pre_emphasize);
+}
+
+void tx_menu(GtkWidget *parent) {
+ GtkWidget *b;
+ int i;
+
+ parent_window=parent;
+
+ dialog=gtk_dialog_new();
+ gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window));
+ gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE);
+
+ GdkRGBA color;
+ color.red = 1.0;
+ color.green = 1.0;
+ color.blue = 1.0;
+ color.alpha = 1.0;
+ gtk_widget_override_background_color(dialog,GTK_STATE_FLAG_NORMAL,&color);
+
+ GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+
+ GtkWidget *grid=gtk_grid_new();
+
+ gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
+ gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
+ gtk_grid_set_column_spacing (GTK_GRID(grid),5);
+ gtk_grid_set_row_spacing (GTK_GRID(grid),5);
+
+ int row=0;
+ int col=0;
+
+ GtkWidget *close_b=gtk_button_new_with_label("Close");
+ g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),close_b,col,row,1,1);
+
+ col++;
+
+ GtkWidget *label=gtk_label_new("Transmit");
+ gtk_grid_attach(GTK_GRID(grid),label,col,row,1,1);
+
+ row++;
+ col=0;
+
+
+ label=gtk_label_new("Filter: ");
+ gtk_grid_attach(GTK_GRID(grid),label,col,row,1,1);
+
+ col++;
+
+ GtkWidget *tx_spin_low=gtk_spin_button_new_with_range(0.0,8000.0,1.0);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(tx_spin_low),(double)tx_filter_low);
+ gtk_grid_attach(GTK_GRID(grid),tx_spin_low,col,row,1,1);
+ g_signal_connect(tx_spin_low,"value-changed",G_CALLBACK(tx_spin_low_cb),NULL);
+
+ col++;
+
+ GtkWidget *tx_spin_high=gtk_spin_button_new_with_range(0.0,8000.0,1.0);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(tx_spin_high),(double)tx_filter_high);
+ gtk_grid_attach(GTK_GRID(grid),tx_spin_high,col,row,1,1);
+ g_signal_connect(tx_spin_high,"value-changed",G_CALLBACK(tx_spin_high_cb),NULL);
+
+ row++;
+ col=0;
+
+
+ if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL) {
+ linein_b=gtk_check_button_new_with_label("Mic Line In (ACC connector)");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linein_b), mic_linein);
+ gtk_grid_attach(GTK_GRID(grid),linein_b,col,++row,3,1);
+ g_signal_connect(linein_b,"toggled",G_CALLBACK(linein_cb),NULL);
+
+ micboost_b=gtk_check_button_new_with_label("Mic Boost (radio only)");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (micboost_b), mic_boost);
+ gtk_grid_attach(GTK_GRID(grid),micboost_b,col,++row,3,1);
+ g_signal_connect(micboost_b,"toggled",G_CALLBACK(micboost_cb),NULL);
+
+ }
+
+ if(n_input_devices>0) {
+ GtkWidget *local_microphone_b=gtk_check_button_new_with_label("Local Microphone Input");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (local_microphone_b), transmitter->local_microphone);
+ gtk_widget_show(local_microphone_b);
+ gtk_grid_attach(GTK_GRID(grid),local_microphone_b,col,++row,3,1);
+ g_signal_connect(local_microphone_b,"toggled",G_CALLBACK(local_microphone_cb),NULL);
+
+ if(transmitter->input_device==-1) transmitter->input_device=0;
+
+ for(i=0;i<n_input_devices;i++) {
+ GtkWidget *input;
+ if(i==0) {
+ input=gtk_radio_button_new_with_label(NULL,input_devices[i]);
+ } else {
+ input=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(input),input_devices[i]);
+ }
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (input), transmitter->input_device==i);
+ gtk_widget_show(input);
+ gtk_grid_attach(GTK_GRID(grid),input,col,++row,3,1);
+ g_signal_connect(input,"pressed",G_CALLBACK(local_input_changed_cb),(gpointer *)i);
+ }
+ }
+
+ row++;
+ col=0;
+
+ GtkWidget *emp_b=gtk_check_button_new_with_label("FM TX Pre-emphasize before limiting");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (emp_b), pre_emphasize);
+ gtk_widget_show(emp_b);
+ gtk_grid_attach(GTK_GRID(grid),emp_b,col,row,3,1);
+ g_signal_connect(emp_b,"toggled",G_CALLBACK(emp_cb),NULL);
+
+ gtk_container_add(GTK_CONTAINER(content),grid);
+
+ sub_menu=dialog;
+
+ gtk_widget_show_all(dialog);
+
+ if(transmitter->local_microphone && (protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL)) {
+ gtk_widget_hide(linein_b);
+ gtk_widget_hide(micboost_b);
+ }
+
+}
--- /dev/null
+/*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*/
+
+void tx_menu(GtkWidget *parent);
--- /dev/null
+/* Copyright (C)
+* 2015 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*/
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <math.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <semaphore.h>
+#include "agc.h"
+#include "band.h"
+#include "channel.h"
+#include "discovered.h"
+#include "radio.h"
+#include "receiver.h"
+#include "transmitter.h"
+#include "tx_panadapter.h"
+#include "vfo.h"
+#include "mode.h"
+#ifdef FREEDV
+#include "freedv.h"
+#endif
+#include "gpio.h"
+
+
+static gint last_x;
+static gboolean has_moved=FALSE;
+static gboolean pressed=FALSE;
+
+static gfloat hz_per_pixel;
+static gfloat filter_left;
+static gfloat filter_right;
+
+
+/* Create a new surface of the appropriate size to store our scribbles */
+static gboolean
+panadapter_configure_event_cb (GtkWidget *widget,
+ GdkEventConfigure *event,
+ gpointer data)
+{
+ TRANSMITTER *tx=(TRANSMITTER *)data;
+ int display_width=gtk_widget_get_allocated_width (tx->panadapter);
+ int display_height=gtk_widget_get_allocated_height (tx->panadapter);
+
+ if (tx->panadapter_surface)
+ cairo_surface_destroy (tx->panadapter_surface);
+
+ tx->panadapter_surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget),
+ CAIRO_CONTENT_COLOR,
+ display_width,
+ display_height);
+
+ cairo_t *cr=cairo_create(tx->panadapter_surface);
+ cairo_set_source_rgb(cr, 0, 0, 0);
+ cairo_paint(cr);
+ cairo_destroy(cr);
+ return TRUE;
+}
+
+/* Redraw the screen from the surface. Note that the ::draw
+ * signal receives a ready-to-be-used cairo_t that is already
+ * clipped to only draw the exposed areas of the widget
+ */
+static gboolean
+panadapter_draw_cb (GtkWidget *widget,
+ cairo_t *cr,
+ gpointer data)
+{
+ TRANSMITTER *tx=(TRANSMITTER *)data;
+ if(tx->panadapter_surface) {
+ cairo_set_source_surface (cr, tx->panadapter_surface, 0, 0);
+ cairo_paint (cr);
+ }
+ return TRUE;
+}
+
+static gboolean
+panadapter_button_press_event_cb (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer data)
+{
+ int x=(int)event->x;
+ if (event->button == 1) {
+ last_x=(int)event->x;
+ has_moved=FALSE;
+ pressed=TRUE;
+ }
+ return TRUE;
+}
+
+static gboolean
+panadapter_button_release_event_cb (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer data)
+{
+ TRANSMITTER *tx=(TRANSMITTER *)data;
+ int display_width=gtk_widget_get_allocated_width (tx->panadapter);
+ int display_height=gtk_widget_get_allocated_height (tx->panadapter);
+
+ if(pressed) {
+ int x=(int)event->x;
+ if (event->button == 1) {
+ if(has_moved) {
+ // drag
+ vfo_move((long long)((float)(x-last_x)*hz_per_pixel));
+ } else {
+ // move to this frequency
+ vfo_move_to((long long)((float)(x-(display_width/2))*hz_per_pixel));
+ }
+ last_x=x;
+ pressed=FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static gboolean
+panadapter_motion_notify_event_cb (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer data)
+{
+ int x, y;
+ GdkModifierType state;
+ gdk_window_get_device_position (event->window,
+ event->device,
+ &x,
+ &y,
+ &state);
+ if((state & GDK_BUTTON1_MASK == GDK_BUTTON1_MASK) || pressed) {
+ int moved=last_x-x;
+ vfo_move((long long)((float)moved*hz_per_pixel));
+ last_x=x;
+ has_moved=TRUE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+panadapter_scroll_event_cb (GtkWidget *widget,
+ GdkEventScroll *event,
+ gpointer data)
+{
+ if(event->direction==GDK_SCROLL_UP) {
+ vfo_move(step);
+ } else {
+ vfo_move(-step);
+ }
+}
+
+void tx_panadapter_update(TRANSMITTER *tx) {
+ int i;
+ int result;
+ float *samples;
+ float saved_max;
+ float saved_min;
+ gfloat saved_hz_per_pixel;
+ cairo_text_extents_t extents;
+
+ int display_width=gtk_widget_get_allocated_width (tx->panadapter);
+ int display_height=gtk_widget_get_allocated_height (tx->panadapter);
+
+ samples=tx->pixel_samples;
+ //hz_per_pixel=(double)tx->output_rate/(double)display_width;
+ hz_per_pixel=48000.0/(double)display_width;
+
+ //clear_panadater_surface();
+ cairo_t *cr;
+ cr = cairo_create (tx->panadapter_surface);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ // filter
+ cairo_set_source_rgb (cr, 0.25, 0.25, 0.25);
+ filter_left=(double)display_width/2.0+((double)tx->filter_low/hz_per_pixel);
+ filter_right=(double)display_width/2.0+((double)tx->filter_high/hz_per_pixel);
+ cairo_rectangle(cr, filter_left, 0.0, filter_right-filter_left, (double)display_height);
+ cairo_fill(cr);
+
+ // plot the levels
+ int V = (int)(tx->panadapter_high - tx->panadapter_low);
+ int numSteps = V / 20;
+ for (i = 1; i < numSteps; i++) {
+ int num = tx->panadapter_high - i * 20;
+ int y = (int)floor((tx->panadapter_high - num) * display_height / V);
+ cairo_set_source_rgb (cr, 0, 1, 1);
+ cairo_set_line_width(cr, 1.0);
+ cairo_move_to(cr,0.0,(double)y);
+ cairo_line_to(cr,(double)display_width,(double)y);
+
+ cairo_set_source_rgb (cr, 0, 1, 1);
+ cairo_select_font_face(cr, "FreeMono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+ cairo_set_font_size(cr, 12);
+ char v[32];
+ sprintf(v,"%d dBm",num);
+ cairo_move_to(cr, 1, (double)y);
+ cairo_show_text(cr, v);
+ cairo_stroke(cr);
+ }
+
+ // plot frequency markers
+ long long f;
+ long long divisor=20000;
+ long long half=24000LL; //(long long)(tx->output_rate/2);
+ long long frequency;
+ if(split) {
+ frequency=vfo[VFO_B].frequency+vfo[VFO_B].offset;
+ } else {
+ frequency=vfo[VFO_A].frequency+vfo[VFO_A].offset;
+ }
+ divisor=5000LL;
+/*
+ switch(tx->output_rate) {
+ case 48000:
+ divisor=5000L;
+ break;
+ case 96000:
+ case 100000:
+ divisor=10000L;
+ break;
+ case 192000:
+ divisor=20000L;
+ break;
+ case 384000:
+ divisor=25000L;
+ break;
+ case 768000:
+ divisor=50000L;
+ break;
+ case 1048576:
+ case 1536000:
+ case 2097152:
+ divisor=100000L;
+ break;
+ }
+*/
+//fprintf(stderr,"tx_panadapter_update: frequency=%lld divisor=%lld split=%d\n",frequency,divisor,split);
+ for(i=0;i<display_width;i++) {
+ f = frequency - half + (long) (hz_per_pixel * i);
+ if (f > 0) {
+ if ((f % divisor) < (long) hz_per_pixel) {
+ cairo_set_source_rgb (cr, 0, 1, 1);
+ cairo_set_line_width(cr, 1.0);
+ cairo_move_to(cr,(double)i,10.0);
+ cairo_line_to(cr,(double)i,(double)display_height);
+
+ cairo_set_source_rgb (cr, 0, 1, 1);
+ cairo_select_font_face(cr, "FreeMono",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_BOLD);
+ cairo_set_font_size(cr, 12);
+ char v[32];
+ sprintf(v,"%0lld.%03lld",f/1000000,(f%1000000)/1000);
+ //cairo_move_to(cr, (double)i, (double)(display_height-10));
+ cairo_text_extents(cr, v, &extents);
+ cairo_move_to(cr, (double)i-(extents.width/2.0), 10.0);
+ cairo_show_text(cr, v);
+ }
+ }
+ }
+ cairo_stroke(cr);
+
+ // band edges
+ long long min_display=frequency-half;
+ long long max_display=frequency+half;
+ int b;
+ if(split) {
+ b=vfo[1].band;
+ } else {
+ b=vfo[0].band;
+ }
+ BAND *band=band_get_band(b);
+ if(band->frequencyMin!=0LL) {
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_set_line_width(cr, 2.0);
+ if((min_display<band->frequencyMin)&&(max_display>band->frequencyMin)) {
+ i=(band->frequencyMin-min_display)/(long long)hz_per_pixel;
+ cairo_move_to(cr,(double)i,0.0);
+ cairo_line_to(cr,(double)i,(double)display_height);
+ cairo_stroke(cr);
+ }
+ if((min_display<band->frequencyMax)&&(max_display>band->frequencyMax)) {
+ i=(band->frequencyMax-min_display)/(long long)hz_per_pixel;
+ cairo_move_to(cr,(double)i,0.0);
+ cairo_line_to(cr,(double)i,(double)display_height);
+ cairo_stroke(cr);
+ }
+ }
+
+ // cursor
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_set_line_width(cr, 1.0);
+//fprintf(stderr,"cursor: x=%f\n",(double)(display_width/2.0)+(vfo[tx->id].offset/hz_per_pixel));
+ cairo_move_to(cr,(double)(display_width/2.0)+(vfo[tx->id].offset/hz_per_pixel),0.0);
+ cairo_line_to(cr,(double)(display_width/2.0)+(vfo[tx->id].offset/hz_per_pixel),(double)display_height);
+ cairo_stroke(cr);
+
+ // signal
+ double s1,s2;
+ samples[0]=-200.0;
+ samples[display_width-1]=-200.0;
+
+ int offset=0;
+
+ if(protocol==NEW_PROTOCOL) {
+ offset=1200;
+ }
+ s1=(double)samples[0+offset]+(double)get_attenuation();
+ s1 = floor((tx->panadapter_high - s1)
+ * (double) display_height
+ / (tx->panadapter_high - tx->panadapter_low));
+ cairo_move_to(cr, 0.0, s1);
+ for(i=1;i<display_width;i++) {
+ s2=(double)samples[i+offset]+(double)get_attenuation();
+ s2 = floor((tx->panadapter_high - s2)
+ * (double) display_height
+ / (tx->panadapter_high - tx->panadapter_low));
+ cairo_line_to(cr, (double)i, s2);
+ }
+
+ if(display_filled) {
+ cairo_close_path (cr);
+ cairo_set_source_rgba(cr, 1, 1, 1,0.5);
+ cairo_fill_preserve (cr);
+ }
+ cairo_set_source_rgb(cr, 1, 1, 1);
+ cairo_set_line_width(cr, 1.0);
+ cairo_stroke(cr);
+
+#ifdef FREEDV
+ int mode;
+ mode=tx->mode;
+ if(mode==modeFREEDV) {
+ cairo_set_source_rgb(cr, 1, 0, 0);
+ cairo_set_font_size(cr, 16);
+ cairo_text_extents(cr, freedv_text_data, &extents);
+ cairo_move_to(cr, (double)display_width/2.0-(extents.width/2.0),(double)display_height-2.0);
+ cairo_show_text(cr, freedv_text_data);
+ }
+#endif
+
+#ifdef GPIO
+ cairo_set_source_rgb(cr,1,1,0);
+ cairo_set_font_size(cr,12);
+ if(ENABLE_E1_ENCODER) {
+ cairo_move_to(cr, display_width-100,30);
+ cairo_show_text(cr, encoder_string[e1_encoder_action]);
+ }
+
+ if(ENABLE_E2_ENCODER) {
+ cairo_move_to(cr, display_width-100,50);
+ cairo_show_text(cr, encoder_string[e2_encoder_action]);
+ }
+
+ if(ENABLE_E3_ENCODER) {
+ cairo_move_to(cr, display_width-100,70);
+ cairo_show_text(cr, encoder_string[e3_encoder_action]);
+ }
+#endif
+
+ cairo_destroy (cr);
+ gtk_widget_queue_draw (tx->panadapter);
+
+}
+
+void tx_panadapter_init(TRANSMITTER *tx, int width,int height) {
+
+ int display_width=width;
+ int display_height=height;
+
+ tx->panadapter_surface=NULL;
+ tx->panadapter=gtk_drawing_area_new ();
+ gtk_widget_set_size_request (tx->panadapter, width, height);
+
+ /* Signals used to handle the backing surface */
+ g_signal_connect (tx->panadapter, "draw",
+ G_CALLBACK (panadapter_draw_cb), tx);
+ g_signal_connect (tx->panadapter,"configure-event",
+ G_CALLBACK (panadapter_configure_event_cb), tx);
+
+ /* Event signals */
+ g_signal_connect (tx->panadapter, "motion-notify-event",
+ G_CALLBACK (panadapter_motion_notify_event_cb), tx);
+ g_signal_connect (tx->panadapter, "button-press-event",
+ G_CALLBACK (panadapter_button_press_event_cb), tx);
+ g_signal_connect (tx->panadapter, "button-release-event",
+ G_CALLBACK (panadapter_button_release_event_cb), tx);
+ g_signal_connect(tx->panadapter,"scroll_event",
+ G_CALLBACK(panadapter_scroll_event_cb),tx);
+
+ /* Ask to receive events the drawing area doesn't normally
+ * subscribe to. In particular, we need to ask for the
+ * button press and motion notify events that want to handle.
+ */
+ gtk_widget_set_events (tx->panadapter, gtk_widget_get_events (tx->panadapter)
+ | GDK_BUTTON_PRESS_MASK
+ | GDK_BUTTON_RELEASE_MASK
+ | GDK_BUTTON1_MOTION_MASK
+ | GDK_SCROLL_MASK
+ | GDK_POINTER_MOTION_MASK
+ | GDK_POINTER_MOTION_HINT_MASK);
+
+}
--- /dev/null
+/* Copyright (C)
+* 2015 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+*/
+
+#ifndef _PANADAPTER_H
+#define _PANADAPTER_H
+
+void tx_panadapter_update(TRANSMITTER *tx);
+
+void tx_panadapter_init(TRANSMITTER *tx,int width,int height);
+
+
+#endif
-char new_version[];
+extern char new_version[];
extern int check_update();
extern int load_update();
#include "band.h"
#include "frequency.h"
#include "new_protocol.h"
+#include "property.h"
#include "radio.h"
+#include "receiver.h"
#include "vfo.h"
#include "channel.h"
#include "toolbar.h"
#include "wdsp.h"
-#include "wdsp_init.h"
#include "new_menu.h"
+#include "rigctl.h"
static GtkWidget *parent_window;
static int my_width;
static int my_height;
-static GtkWidget *vfo;
+static GtkWidget *vfo_panel;
static cairo_surface_t *vfo_surface = NULL;
int steps[]={1,10,25,50,100,250,500,1000,2500,5000,6250,9000,10000,12500,15000,20000,25000,30000,50000,100000,0};
static GtkWidget* menu=NULL;
static GtkWidget* band_menu=NULL;
+
+static void vfo_save_bandstack() {
+ BANDSTACK *bandstack=bandstack_get_bandstack(vfo[0].band);
+ BANDSTACK_ENTRY *entry=&bandstack->entry[vfo[0].bandstack];
+ entry->frequency=vfo[0].frequency;
+ entry->mode=vfo[0].mode;
+ entry->filter=vfo[0].filter;
+}
+
+void vfo_save_state() {
+ int i;
+ char name[80];
+ char value[80];
+
+ vfo_save_bandstack();
+
+ for(i=0;i<MAX_VFOS;i++) {
+ sprintf(name,"vfo.%d.band",i);
+ sprintf(value,"%d",vfo[i].band);
+ setProperty(name,value);
+ sprintf(name,"vfo.%d.frequency",i);
+ sprintf(value,"%lld",vfo[i].frequency);
+ setProperty(name,value);
+ sprintf(name,"vfo.%d.ctun",i);
+ sprintf(value,"%d",vfo[i].ctun);
+ setProperty(name,value);
+ sprintf(name,"vfo.%d.rit",i);
+ sprintf(value,"%lld",vfo[i].rit);
+ setProperty(name,value);
+ sprintf(name,"vfo.%d.lo",i);
+ sprintf(value,"%lld",vfo[i].lo);
+ setProperty(name,value);
+ sprintf(name,"vfo.%d.ctun_frequency",i);
+ sprintf(value,"%lld",vfo[i].ctun_frequency);
+ setProperty(name,value);
+ sprintf(name,"vfo.%d.offset",i);
+ sprintf(value,"%lld",vfo[i].offset);
+ setProperty(name,value);
+ sprintf(name,"vfo.%d.mode",i);
+ sprintf(value,"%d",vfo[i].mode);
+ setProperty(name,value);
+ sprintf(name,"vfo.%d.filter",i);
+ sprintf(value,"%d",vfo[i].filter);
+ setProperty(name,value);
+ }
+}
+
+void vfo_restore_state() {
+ int i;
+ char name[80];
+ char *value;
+
+ for(i=0;i<MAX_VFOS;i++) {
+
+ vfo[i].band=band20;
+ vfo[i].bandstack=0;
+ vfo[i].frequency=14010000;
+ vfo[i].mode=modeCWU;
+ vfo[i].filter=6;
+ vfo[i].lo=0;
+ vfo[i].offset=0;
+ vfo[i].rit=0;
+ vfo[i].ctun=0;
+
+ sprintf(name,"vfo.%d.band",i);
+ value=getProperty(name);
+ if(value) vfo[i].band=atoi(value);
+ sprintf(name,"vfo.%d.frequency",i);
+ value=getProperty(name);
+ if(value) vfo[i].frequency=atoll(value);
+ sprintf(name,"vfo.%d.ctun",i);
+ value=getProperty(name);
+ if(value) vfo[i].ctun=atoi(value);
+ sprintf(name,"vfo.%d.ctun_frequency",i);
+ value=getProperty(name);
+ if(value) vfo[i].ctun_frequency=atoll(value);
+ sprintf(name,"vfo.%d.rit",i);
+ value=getProperty(name);
+ if(value) vfo[i].rit=atoll(value);
+ sprintf(name,"vfo.%d.lo",i);
+ value=getProperty(name);
+ if(value) vfo[i].lo=atoll(value);
+ sprintf(name,"vfo.%d.offset",i);
+ value=getProperty(name);
+ if(value) vfo[i].offset=atoll(value);
+ sprintf(name,"vfo.%d.mode",i);
+ value=getProperty(name);
+ if(value) vfo[i].mode=atoi(value);
+ sprintf(name,"vfo.%d.filter",i);
+ value=getProperty(name);
+ if(value) vfo[i].filter=atoi(value);
+
+ }
+}
+
+void vfo_band_changed(int b) {
+ BANDSTACK *bandstack;
+
+ int id=active_receiver->id;
+
+ if(id==0) {
+ vfo_save_bandstack();
+ }
+ if(b==vfo[id].band) {
+ // same band selected - step to the next band stack
+ bandstack=bandstack_get_bandstack(b);
+ vfo[id].bandstack++;
+ if(vfo[id].bandstack>=bandstack->entries) {
+ vfo[id].bandstack=0;
+ }
+ } else {
+ // new band - get band stack entry
+ bandstack=bandstack_get_bandstack(b);
+ vfo[id].bandstack=bandstack->current_entry;
+ }
+
+ BAND *band=band_get_band(b);
+ BANDSTACK_ENTRY *entry=&bandstack->entry[vfo[id].bandstack];
+ vfo[id].band=b;
+ vfo[id].frequency=entry->frequency;
+ vfo[id].mode=entry->mode;
+ vfo[id].filter=entry->filter;
+ vfo[id].lo=band->frequencyLO;
+
+ switch(id) {
+ case 0:
+ bandstack->current_entry=vfo[id].bandstack;
+ receiver_vfo_changed(receiver[id]);
+ BAND *band=band_get_band(vfo[id].band);
+ set_alex_rx_antenna(band->alexRxAntenna);
+ set_alex_tx_antenna(band->alexTxAntenna);
+ set_alex_attenuation(band->alexAttenuation);
+ receiver_vfo_changed(receiver[0]);
+ break;
+ case 1:
+ if(receivers==2) {
+ receiver_vfo_changed(receiver[1]);
+ }
+ break;
+ }
+
+ if(split) {
+ tx_set_mode(transmitter,vfo[VFO_B].mode);
+ } else {
+ tx_set_mode(transmitter,vfo[VFO_A].mode);
+ }
+ calcDriveLevel();
+ calcTuneDriveLevel();
+ vfo_update(NULL);
+}
+
+void vfo_bandstack_changed(int b) {
+ int id=active_receiver->id;
+ if(id==0) {
+ vfo_save_bandstack();
+ }
+ vfo[id].bandstack=b;
+
+ BANDSTACK *bandstack=bandstack_get_bandstack(vfo[id].band);
+ BANDSTACK_ENTRY *entry=&bandstack->entry[vfo[id].bandstack];
+ vfo[id].frequency=entry->frequency;
+ vfo[id].mode=entry->mode;
+ vfo[id].filter=entry->filter;
+
+ switch(id) {
+ case 0:
+ bandstack->current_entry=vfo[id].bandstack;
+ receiver_vfo_changed(receiver[id]);
+ BAND *band=band_get_band(vfo[id].band);
+ set_alex_rx_antenna(band->alexRxAntenna);
+ set_alex_tx_antenna(band->alexTxAntenna);
+ set_alex_attenuation(band->alexAttenuation);
+ receiver_vfo_changed(receiver[0]);
+ break;
+ case 1:
+ if(receivers==2) {
+ receiver_vfo_changed(receiver[1]);
+ }
+ break;
+ }
+
+ if(split) {
+ tx_set_mode(transmitter,vfo[VFO_B].mode);
+ } else {
+ tx_set_mode(transmitter,vfo[VFO_A].mode);
+ }
+ calcDriveLevel();
+ calcTuneDriveLevel();
+ vfo_update(NULL);
+
+}
+
+void vfo_mode_changed(int m) {
+ int id=active_receiver->id;
+ vfo[id].mode=m;
+ switch(id) {
+ case 0:
+ receiver_mode_changed(receiver[0]);
+ receiver_filter_changed(receiver[0]);
+ break;
+ case 1:
+ if(receivers==2) {
+ receiver_mode_changed(receiver[1]);
+ receiver_filter_changed(receiver[1]);
+ }
+ break;
+ }
+ if(split) {
+ tx_set_mode(transmitter,vfo[VFO_B].mode);
+ } else {
+ tx_set_mode(transmitter,vfo[VFO_A].mode);
+ }
+
+ vfo_update(NULL);
+}
+
+void vfo_filter_changed(int f) {
+ int id=active_receiver->id;
+ vfo[id].filter=f;
+ switch(id) {
+ case 0:
+ receiver_filter_changed(receiver[0]);
+ break;
+ case 1:
+ if(receivers==2) {
+ receiver_filter_changed(receiver[1]);
+ }
+ break;
+ }
+
+ vfo_update(NULL);
+}
+
+void vfo_a_to_b() {
+ vfo[VFO_B].band=vfo[VFO_A].band;
+ vfo[VFO_B].bandstack=vfo[VFO_A].bandstack;
+ vfo[VFO_B].frequency=vfo[VFO_A].frequency;
+ vfo[VFO_B].mode=vfo[VFO_A].mode;
+ vfo[VFO_B].filter=vfo[VFO_A].filter;
+ vfo[VFO_B].filter=vfo[VFO_A].filter;
+ vfo[VFO_B].lo=vfo[VFO_A].lo;
+ vfo[VFO_B].offset=vfo[VFO_A].offset;
+ vfo[VFO_B].rit=vfo[VFO_A].rit;
+
+ if(receivers==2) {
+ receiver_vfo_changed(receiver[1]);
+ }
+ if(split) {
+ tx_set_mode(transmitter,vfo[VFO_B].mode);
+ }
+ vfo_update(NULL);
+}
+
+void vfo_b_to_a() {
+ vfo[VFO_A].band=vfo[VFO_B].band;
+ vfo[VFO_A].bandstack=vfo[VFO_B].bandstack;
+ vfo[VFO_A].frequency=vfo[VFO_B].frequency;
+ vfo[VFO_A].mode=vfo[VFO_B].mode;
+ vfo[VFO_A].filter=vfo[VFO_B].filter;
+ vfo[VFO_A].lo=vfo[VFO_B].lo;
+ vfo[VFO_A].offset=vfo[VFO_B].offset;
+ vfo[VFO_A].rit=vfo[VFO_B].rit;
+ receiver_vfo_changed(receiver[0]);
+ if(!split) {
+ tx_set_mode(transmitter,vfo[VFO_B].mode);
+ }
+ vfo_update(NULL);
+}
+
+void vfo_a_swap_b() {
+ int temp_band;
+ int temp_bandstack;
+ long long temp_frequency;
+ int temp_mode;
+ int temp_filter;
+ int temp_lo;
+ int temp_offset;
+ int temp_rit;
+
+ temp_band=vfo[VFO_A].band;
+ temp_bandstack=vfo[VFO_A].bandstack;
+ temp_frequency=vfo[VFO_A].frequency;
+ temp_mode=vfo[VFO_A].mode;
+ temp_filter=vfo[VFO_A].filter;
+ temp_lo=vfo[VFO_A].lo;
+ temp_offset=vfo[VFO_A].offset;
+ temp_rit=vfo[VFO_A].rit;
+
+ vfo[VFO_A].band=vfo[VFO_B].band;
+ vfo[VFO_A].bandstack=vfo[VFO_B].bandstack;
+ vfo[VFO_A].frequency=vfo[VFO_B].frequency;
+ vfo[VFO_A].mode=vfo[VFO_B].mode;
+ vfo[VFO_A].filter=vfo[VFO_B].filter;
+ vfo[VFO_A].lo=vfo[VFO_B].lo;
+ vfo[VFO_A].offset=vfo[VFO_B].offset;
+ vfo[VFO_A].rit=vfo[VFO_B].rit;
+
+ vfo[VFO_B].band=temp_band;
+ vfo[VFO_B].bandstack=temp_bandstack;
+ vfo[VFO_B].frequency=temp_frequency;
+ vfo[VFO_B].mode=temp_mode;
+ vfo[VFO_B].filter=temp_filter;
+ vfo[VFO_B].lo=temp_lo;
+ vfo[VFO_B].offset=temp_offset;
+ vfo[VFO_B].rit=temp_rit;
+
+ receiver_vfo_changed(receiver[0]);
+ if(receivers==2) {
+ receiver_vfo_changed(receiver[1]);
+ }
+ if(split) {
+ tx_set_mode(transmitter,vfo[VFO_B].mode);
+ } else {
+ tx_set_mode(transmitter,vfo[VFO_A].mode);
+ }
+ vfo_update(NULL);
+}
+
void vfo_step(int steps) {
+ int id=active_receiver->id;
if(!locked) {
+ if(vfo[id].ctun) {
+ vfo[id].ctun_frequency=vfo[id].ctun_frequency+(steps*step);
+ } else {
+ vfo[id].frequency=vfo[id].frequency+(steps*step);
+ }
+ receiver_frequency_changed(active_receiver);
+#ifdef INCLUDED
BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
- //entry->frequencyA=entry->frequencyA+(steps*step);
- //setFrequency(entry->frequencyA);
- setFrequency(entry->frequencyA+(steps*step));
+ setFrequency(active_receiver->frequency+(steps*step));
+#endif
vfo_update(NULL);
}
}
-void vfo_move(int hz) {
+void vfo_move(long long hz) {
+ int id=active_receiver->id;
if(!locked) {
- BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
- //entry->frequencyA=(entry->frequencyA+hz)/step*step;
- //setFrequency(entry->frequencyA);
-
+ switch(protocol) {
#ifdef LIMESDR
- if(protocol==LIMESDR_PROTOCOL)
- setFrequency((entry->frequencyA+ddsOffset-hz)/step*step);
- else
+ case LIMESDR_PROTOCOL:
+ break;
#endif
- if(ctun) {
- setFrequency((entry->frequencyA+ddsOffset-hz)/step*step);
- } else {
- setFrequency((entry->frequencyA+ddsOffset+hz)/step*step);
- }
+ default:
+ vfo[id].frequency=((vfo[id].frequency+hz)/step)*step;
+ break;
+ }
+ receiver_frequency_changed(active_receiver);
vfo_update(NULL);
}
}
-void vfo_move_to(int hz) {
+void vfo_move_to(long long hz) {
+ int id=active_receiver->id;
if(!locked) {
+ switch(protocol) {
+#ifdef LIMESDR
+ case LIMESDR_PROTOCOL:
+ break;
+#endif
+ default:
+ vfo[id].frequency=(vfo[id].frequency+hz)/step*step;
+ if(vfo[id].mode==modeCWL) {
+ vfo[id].frequency+=cw_keyer_sidetone_frequency;
+ } else if(vfo[id].mode==modeCWU) {
+ vfo[id].frequency-=cw_keyer_sidetone_frequency;
+ }
+ break;
+ }
+ receiver_vfo_changed(active_receiver);
+
+#ifdef INCLUDED
+
BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
#ifdef LIMESDR
if(protocol==LIMESDR_PROTOCOL) {
- setFrequency((entry->frequencyA+ddsOffset-hz)/step*step);
+ setFrequency((entry->frequency+active_receiver->dds_offset-hz)/step*step);
} else {
#endif
- if(ctun) {
- setFrequency((entry->frequencyA+hz)/step*step);
+ if(vfo[id].ctun) {
+ setFrequency((active_receiver->frequency+hz)/step*step);
} else {
- long f=(entry->frequencyA+ddsOffset+hz)/step*step;
- if(mode==modeCWL) {
+ long long f=(active_receiver->frequency+active_receiver->dds_offset+hz)/step*step;
+ if(vfo[active_receiver->id].mode==modeCWL) {
f+=cw_keyer_sidetone_frequency;
- } else if(mode==modeCWU) {
+ } else if(vfo[active_receiver->id].mode==modeCWU) {
f-=cw_keyer_sidetone_frequency;
}
setFrequency(f);
}
#ifdef LIMESDR
}
+#endif
#endif
vfo_update(NULL);
}
{
int i;
if(event->direction==GDK_SCROLL_UP) {
- i=1;
- } else {
- i=-1;
- }
- if(event->x>(my_width/2)) {
- if(event->x>((my_width/4)*3)) {
- // rit
- rit+=i;
- if(rit>10000) {
- rit=1000;
- }
- if(rit<-1000) {
- rit=-1000;
- }
- } else {
- // step
- }
+ vfo_move(step);
} else {
- // frequency
+ vfo_move(-step);
}
- vfo_update(NULL);
}
GdkEventConfigure *event,
gpointer data)
{
-fprintf(stderr,"vfo_configure_event_cb: width=%d height=%d\n",
- gtk_widget_get_allocated_width (widget),
- gtk_widget_get_allocated_height (widget));
if (vfo_surface)
cairo_surface_destroy (vfo_surface);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_paint (cr);
cairo_destroy(cr);
-
g_idle_add(vfo_update,NULL);
-
- /* We've handled the configure event, no need for further processing. */
return TRUE;
}
{
cairo_set_source_surface (cr, vfo_surface, 0, 0);
cairo_paint (cr);
-
- return FALSE;
+ return TRUE;
}
int vfo_update(void *data) {
- BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
- FILTER* band_filters=filters[entry->mode];
- FILTER* band_filter=&band_filters[entry->filter];
+
+ int id=active_receiver->id;
+ FILTER* band_filters=filters[vfo[id].mode];
+ FILTER* band_filter=&band_filters[vfo[id].filter];
if(vfo_surface) {
+ char temp_text[32];
cairo_t *cr;
cr = cairo_create (vfo_surface);
cairo_set_source_rgb (cr, 0, 0, 0);
char version[16];
char text[128];
if(radio->protocol==ORIGINAL_PROTOCOL) {
+ switch(radio->device) {
+#ifdef USBOZY
+ case DEVICE_OZY:
+ strcpy(version,"");
+ break;
+#endif
+ default:
+ sprintf(version,"%d.%d",
+ radio->software_version/10,
+ radio->software_version%10);
+ break;
+ }
+ } else {
sprintf(version,"%d.%d",
radio->software_version/10,
radio->software_version%10);
- } else {
- sprintf(version,"%d.%d.%d",
- radio->software_version/100,
- (radio->software_version%100)/10,
- radio->software_version%10);
}
switch(radio->protocol) {
case ORIGINAL_PROTOCOL:
+ switch(radio->device) {
+#ifdef USBOZY
+ case DEVICE_OZY:
+ sprintf(text,"%s", radio->name);
+ break;
+#endif
+ default:
+ sprintf(text,"%s %s %s",
+ radio->name,
+ version,
+ inet_ntoa(radio->info.network.address.sin_addr));
+ break;
+ }
+ break;
case NEW_PROTOCOL:
sprintf(text,"%s %s %s",
radio->name,
break;
#ifdef LIMESDR
case LIMESDR_PROTOCOL:
- sprintf(text,"%s\n",
- radio->name);
+ sprintf(text,"%s", radio->name);
break;
#endif
}
- cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
- cairo_set_font_size(cr, 10);
+ cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
+ cairo_set_font_size(cr, 12);
cairo_move_to(cr, 5, 15);
cairo_show_text(cr, text);
- long long f=entry->frequencyA+ddsOffset;
- char sf[32];
- sprintf(sf,"%0lld.%06lld MHz",f/(long long)1000000,f%(long long)1000000);
- cairo_set_font_size(cr, 28);
- if(isTransmitting()) {
+ //long long af=active_receiver->frequency+active_receiver->dds_offset;
+ long long af=vfo[0].frequency+vfo[0].offset;
+ sprintf(temp_text,"VFO A: %0lld.%06lld",af/(long long)1000000,af%(long long)1000000);
+ if(isTransmitting() && !split) {
cairo_set_source_rgb(cr, 1, 0, 0);
} else {
- cairo_set_source_rgb(cr, 0, 1, 0);
+ if(active_receiver->id==0) {
+ cairo_set_source_rgb(cr, 0, 1, 0);
+ } else {
+ cairo_set_source_rgb(cr, 0, 0.65, 0);
+ }
}
cairo_move_to(cr, 5, 38);
- cairo_show_text(cr, sf);
-
- cairo_set_font_size(cr, 12);
+ cairo_set_font_size(cr, 22);
+ cairo_show_text(cr, temp_text);
- if(rit==0) {
- cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
+ //long long bf=frequencyB;
+ long long bf=vfo[1].frequency+vfo[1].offset;
+ sprintf(temp_text,"VFO B: %0lld.%06lld",bf/(long long)1000000,bf%(long long)1000000);
+ if(isTransmitting() && split) {
+ cairo_set_source_rgb(cr, 1, 0, 0);
} else {
- cairo_set_source_rgb(cr, 0, 1, 0);
+ if(active_receiver->id==1) {
+ cairo_set_source_rgb(cr, 0, 1, 0);
+ } else {
+ cairo_set_source_rgb(cr, 0, 0.65, 0);
+ }
}
- sprintf(sf,"RIT: %d Hz",rit);
- cairo_move_to(cr, (my_width/4)*3, 38);
- cairo_show_text(cr, sf);
+ cairo_move_to(cr, 260, 38);
+ cairo_show_text(cr, temp_text);
- cairo_set_source_rgb(cr, 0, 1, 0);
+ cairo_set_font_size(cr, 12);
- int s=0;
- while(steps[s]!=step && steps[s]!=0) {
- s++;
+ if(vfo[id].rit==0) {
+ cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
+ } else {
+ cairo_set_source_rgb(cr, 1, 1, 0);
}
- sprintf(sf,"Step %s",step_labels[s]);
- cairo_move_to(cr, my_width/2, 15);
- cairo_show_text(cr, sf);
-
- cairo_move_to(cr, (my_width/4)*3, 15);
- cairo_show_text(cr, getFrequencyInfo(f));
+ sprintf(temp_text,"RIT: %d Hz",vfo[id].rit);
+ cairo_move_to(cr, 5, 50);
+ cairo_set_font_size(cr, 12);
+ cairo_show_text(cr, temp_text);
+ cairo_move_to(cr, 210, 15);
if(locked) {
- cairo_set_source_rgb(cr, 1, 0, 0);
- cairo_move_to(cr, 10, 50);
- cairo_show_text(cr, "Locked");
- }
-
- if(function) {
- cairo_set_source_rgb(cr, 1, 0.5, 0);
- cairo_move_to(cr, 70, 50);
- cairo_show_text(cr, "Function");
+ cairo_set_source_rgb(cr, 1, 0, 0);
+ } else {
+ cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
}
-
+ cairo_show_text(cr, "Locked");
+
cairo_set_source_rgb(cr, 1, 1, 0);
- cairo_move_to(cr, 130, 50);
- cairo_show_text(cr, mode_string[entry->mode]);
-
- cairo_move_to(cr, 190, 50);
- if(mode==modeFMN) {
+ cairo_move_to(cr, 100, 50);
+ if(vfo[id].mode==modeFMN) {
if(deviation==2500) {
- cairo_show_text(cr, "8k");
+ sprintf(temp_text,"%s 8k",mode_string[vfo[id].mode]);
} else {
- cairo_show_text(cr, "16k");
+ sprintf(temp_text,"%s 16k",mode_string[vfo[id].mode]);
}
} else {
- cairo_show_text(cr, band_filter->title);
+ sprintf(temp_text,"%s %s",mode_string[vfo[id].mode],band_filter->title);
}
+ cairo_show_text(cr, temp_text);
- cairo_move_to(cr, 250, 50);
- if(nr) {
- cairo_show_text(cr, "NR");
- }
- if(nr2) {
- cairo_show_text(cr, "NR2");
- }
- if(nb) {
- cairo_show_text(cr, "NB");
+ cairo_move_to(cr, 170, 50);
+ if(active_receiver->nr) {
+ cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
+ } else {
+ cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
}
- if(nb2) {
- cairo_show_text(cr, "NB2");
+ cairo_show_text(cr, "NR");
+
+ cairo_move_to(cr, 200, 50);
+ if(active_receiver->nr2) {
+ cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
+ } else {
+ cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
}
- if(anf) {
- cairo_show_text(cr, "ANF");
+ cairo_show_text(cr, "NR2");
+
+ cairo_move_to(cr, 230, 50);
+ if(active_receiver->anf) {
+ cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
+ } else {
+ cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
}
- if(snb) {
- cairo_show_text(cr, "SNB");
+ cairo_show_text(cr, "ANF");
+
+ cairo_move_to(cr, 260, 50);
+ if(active_receiver->snb) {
+ cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
+ } else {
+ cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
}
+ cairo_show_text(cr, "SNB");
- cairo_move_to(cr, 310, 50);
- switch(agc) {
+ cairo_move_to(cr, 290, 50);
+ switch(active_receiver->agc) {
case AGC_OFF:
+ cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
cairo_show_text(cr, "AGC OFF");
break;
case AGC_LONG:
+ cairo_set_source_rgb(cr, 1, 1, 0);
cairo_show_text(cr, "AGC LONG");
break;
case AGC_SLOW:
+ cairo_set_source_rgb(cr, 1, 1, 0);
cairo_show_text(cr, "AGC SLOW");
break;
case AGC_MEDIUM:
+ cairo_set_source_rgb(cr, 1, 1, 0);
cairo_show_text(cr, "AGC MEDIUM");
break;
case AGC_FAST:
+ cairo_set_source_rgb(cr, 1, 1, 0);
cairo_show_text(cr, "AGC FAST");
break;
}
+ int s=0;
+ while(steps[s]!=step && steps[s]!=0) {
+ s++;
+ }
+ sprintf(temp_text,"Step %s",step_labels[s]);
+ cairo_move_to(cr, 375, 50);
+ cairo_set_source_rgb(cr, 1, 1, 0);
+ cairo_show_text(cr, temp_text);
+
+ char *info=getFrequencyInfo(af);
+/*
+ cairo_move_to(cr, (my_width/4)*3, 50);
+ cairo_show_text(cr, getFrequencyInfo(af));
+*/
- cairo_move_to(cr, 400, 50);
- if(ctun) {
- cairo_show_text(cr, "CTUN");
+ cairo_move_to(cr, 460, 50);
+ if(vfo[id].ctun) {
+ cairo_set_source_rgb(cr, 1, 1, 0);
+ } else {
+ cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
+ }
+ cairo_show_text(cr, "CTUN");
+
+ cairo_move_to(cr, 500, 50);
+ if(cat_control>0) {
+ cairo_set_source_rgb(cr, 1, 1, 0);
+ } else {
+ cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
+ }
+ cairo_show_text(cr, "CAT");
+
+ cairo_move_to(cr, 270, 15);
+ if(split) {
+ cairo_set_source_rgb(cr, 1, 0, 0);
+ } else {
+ cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
+ }
+ cairo_show_text(cr, "Split");
+
+ cairo_move_to(cr, 310, 15);
+ if(vfo[id].mode==modeCWL || vfo[id].mode==modeCWU) {
+ cairo_set_source_rgb(cr, 1, 1, 0);
+ } else {
+ cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
}
+ sprintf(temp_text,"CW %d wpm, sidetone %d Hz",cw_keyer_speed,cw_keyer_sidetone_frequency);
+ cairo_show_text(cr, temp_text);
cairo_destroy (cr);
- gtk_widget_queue_draw (vfo);
+ gtk_widget_queue_draw (vfo_panel);
} else {
fprintf(stderr,"vfo_update: no surface!\n");
}
GdkEventButton *event,
gpointer data)
{
-
+/*
if((int)event->x < (my_width/4)) {
- lock_cb(NULL,NULL);
+ //lock_cb(NULL,NULL);
} else if((int)event->x < (my_width/2) && (int)event->x > (my_width/4)) {
start_freqent();
} else {
start_step();
-/*
- GtkWidget *dialog=gtk_dialog_new_with_buttons("Step",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
-
- GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
- GtkWidget *grid=gtk_grid_new();
-
- gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
- gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
-
- GtkWidget *step_rb=NULL;
- int i=0;
- while(steps[i]!=0) {
- if(i==0) {
- step_rb=gtk_radio_button_new_with_label(NULL,step_labels[i]);
- } else {
- step_rb=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(step_rb),step_labels[i]);
- }
- gtk_widget_override_font(step_rb, pango_font_description_from_string("FreeMono 18"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (step_rb), steps[i]==step);
- gtk_widget_show(step_rb);
- gtk_grid_attach(GTK_GRID(grid),step_rb,i%5,i/5,1,1);
- g_signal_connect(step_rb,"pressed",G_CALLBACK(vfo_step_select_cb),(gpointer *)i);
- i++;
- }
-
- gtk_container_add(GTK_CONTAINER(content),grid);
-
- GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK);
- gtk_widget_override_font(close_button, pango_font_description_from_string("FreeMono 18"));
- gtk_widget_show_all(dialog);
-
- g_signal_connect_swapped (dialog,
- "response",
- G_CALLBACK (gtk_widget_destroy),
- dialog);
-
- int result=gtk_dialog_run(GTK_DIALOG(dialog));
-*/
}
+*/
+ start_vfo();
return TRUE;
}
GtkWidget* vfo_init(int width,int height,GtkWidget *parent) {
+ int i;
fprintf(stderr,"vfo_init: width=%d height=%d\n", width, height);
+
parent_window=parent;
my_width=width;
my_height=height;
- vfo = gtk_drawing_area_new ();
- gtk_widget_set_size_request (vfo, width, height);
+ vfo_panel = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (vfo_panel, width, height);
- /* Signals used to handle the backing surface */
- g_signal_connect (vfo, "draw",
- G_CALLBACK (vfo_draw_cb), NULL);
- g_signal_connect (vfo,"configure-event",
+ g_signal_connect (vfo_panel,"configure-event",
G_CALLBACK (vfo_configure_event_cb), NULL);
+ g_signal_connect (vfo_panel, "draw",
+ G_CALLBACK (vfo_draw_cb), NULL);
/* Event signals */
- g_signal_connect (vfo, "button-press-event",
+ g_signal_connect (vfo_panel, "button-press-event",
G_CALLBACK (vfo_press_event_cb), NULL);
- g_signal_connect(vfo,"scroll_event",
+ g_signal_connect(vfo_panel,"scroll_event",
G_CALLBACK(vfo_scroll_event_cb),NULL);
- gtk_widget_set_events (vfo, gtk_widget_get_events (vfo)
+ gtk_widget_set_events (vfo_panel, gtk_widget_get_events (vfo_panel)
| GDK_BUTTON_PRESS_MASK
| GDK_SCROLL_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);
- setMode(entry->mode);
- FILTER* band_filters=filters[entry->mode];
- FILTER* band_filter=&band_filters[entry->filter];
- setFilter(band_filter->low,band_filter->high);
-
- set_alex_rx_antenna(band->alexRxAntenna);
- set_alex_tx_antenna(band->alexTxAntenna);
- set_alex_attenuation(band->alexAttenuation);
-
- return vfo;
+ return vfo_panel;
}
#ifndef _VFO_H
#define _VFO_H
+
+enum {
+ VFO_A=0,
+ VFO_B,
+ MAX_VFOS
+};
+
+struct _vfo {
+ int band;
+ int bandstack;
+ long long frequency;
+ int mode;
+ int filter;
+
+ int ctun;
+ long long ctun_frequency;
+ long long rit;
+
+ long long lo;
+ long long offset;
+
+} vfo[MAX_VFOS];
+
+
extern int steps[];
extern char *step_labels[];
extern GtkWidget* vfo_init(int width,int height,GtkWidget *parent);
extern void vfo_step(int steps);
-extern void vfo_move(int hz);
+extern void vfo_move(long long hz);
+extern void vfo_move_to(long long hz);
extern int vfo_update(void*);
+extern void set_frequency();
+
+extern void vfo_save_state();
+extern void vfo_restore_state();
+extern void vfo_band_changed(int b);
+extern void vfo_bandstack_changed(int b);
+extern void vfo_mode_changed(int m);
+extern void vfo_filter_changed(int f);
+extern void vfo_a_to_b();
+extern void vfo_b_to_a();
+extern void vfo_a_swap_b();
#endif
--- /dev/null
+/* 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 <gtk/gtk.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "new_menu.h"
+#include "band.h"
+#include "filter.h"
+#include "mode.h"
+#include "radio.h"
+#include "receiver.h"
+#include "vfo.h"
+
+static GtkWidget *parent_window=NULL;
+static GtkWidget *dialog=NULL;
+static GtkWidget *label;
+
+#define BUF_SIZE 88
+
+static char *btn_labels[] = {"1","2","3",
+ "4","5","6",
+ "7","8","9",
+ ".","0","BS",
+ "HZ","KZ","MZ"
+ ,"CL"
+ };
+
+static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ if(dialog!=NULL) {
+ gtk_widget_destroy(dialog);
+ dialog=NULL;
+ sub_menu=NULL;
+ }
+ return TRUE;
+}
+
+static gboolean freqent_select_cb (GtkWidget *widget, gpointer data) {
+ char *str = (char *) data;
+ const char *labelText;
+ char output[BUF_SIZE], buffer[BUF_SIZE];
+ int len;
+ double mult;
+ long long f;
+ static int set = 0;
+
+ if (set) {
+ set = 0;
+ strcpy (buffer, "0");
+ sprintf(output, "<big>%s</big>", buffer);
+ gtk_label_set_markup (GTK_LABEL (label), output);
+ len = 1;
+ } else {
+ labelText = gtk_label_get_text (GTK_LABEL (label));
+ strcpy (buffer, labelText);
+ len = strlen (buffer);
+ }
+
+ if (isdigit (str[0]) || str[0] == '.') {
+
+ buffer[len] = (gchar) str[0];
+ buffer[len+1] = (gchar) 0;
+
+ len = (buffer[0] == '0') ? 1 : 0;
+
+ sprintf(output, "<big>%s</big>", buffer+len);
+ gtk_label_set_markup (GTK_LABEL (label), output);
+ } else {
+
+ if (strcmp (str, "BS") == 0) {
+ /* --- Remove the last character on it. --- */
+ if (len > 0) buffer[len-1] = (gchar) 0;
+
+ /* --- Remove digit from field. --- */
+ sprintf(output, "<big>%s</big>", buffer);
+ gtk_label_set_markup (GTK_LABEL (label), output);
+
+ /* --- clear? --- */
+ } else if (strcmp (str, "CL") == 0) {
+ strcpy (buffer, "0");
+ sprintf(output, "<big>%s</big>", buffer);
+ gtk_label_set_markup (GTK_LABEL (label), output);
+ } else if (str[1] == 'Z') {
+ switch(str[0]) {
+ case 'M':
+ mult = 10000000.0;
+ break;
+ case 'K':
+ mult = 10000.0;
+ break;
+ default :
+ mult = 10.0;
+ }
+ f = ((long long)(atof(buffer)*mult)+5)/10;
+ sprintf(output, "<big>%lld</big>", f);
+ gtk_label_set_markup (GTK_LABEL (label), output);
+ int b=get_band_from_frequency(f);
+ if(b<0) {
+ fprintf(stderr,"get_band_from_frequency: failed for f=%lld\n",f);
+ b=bandGen;
+ }
+ if(b!=band_get_current()) {
+ BAND *band=band_set_current(b);
+ BANDSTACK_ENTRY *entry=bandstack_entry_get_current();
+ //setMode(entry->mode);
+ set_mode(active_receiver,entry->mode);
+ FILTER* band_filters=filters[entry->mode];
+ FILTER* band_filter=&band_filters[entry->filter];
+ //setFilter(band_filter->low,band_filter->high);
+ set_filter(active_receiver,band_filter->low,band_filter->high);
+ if(active_receiver->id==0) {
+ set_alex_rx_antenna(band->alexRxAntenna);
+ set_alex_tx_antenna(band->alexTxAntenna);
+ set_alex_attenuation(band->alexAttenuation);
+ }
+ }
+ setFrequency(f);
+ vfo_update(NULL);
+
+ set = 1;
+ }
+ }
+ vfo_update(NULL);
+}
+
+static void rit_cb(GtkComboBox *widget,gpointer data) {
+ switch(gtk_combo_box_get_active(widget)) {
+ case 0:
+ rit_increment=1;
+ break;
+ case 1:
+ rit_increment=10;
+ break;
+ case 2:
+ rit_increment=100;
+ break;
+ }
+ vfo_update(NULL);
+}
+
+static void vfo_cb(GtkComboBox *widget,gpointer data) {
+ step=steps[gtk_combo_box_get_active(widget)];
+ vfo_update(NULL);
+}
+
+static GtkWidget *last_mode;
+
+void vfo_menu(GtkWidget *parent) {
+ int i;
+
+ parent_window=parent;
+
+ dialog=gtk_dialog_new();
+ gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window));
+ gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE);
+
+ GdkRGBA color;
+ color.red = 1.0;
+ color.green = 1.0;
+ color.blue = 1.0;
+ color.alpha = 1.0;
+ gtk_widget_override_background_color(dialog,GTK_STATE_FLAG_NORMAL,&color);
+
+ GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+
+ GtkWidget *grid=gtk_grid_new();
+
+ gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
+ gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
+ gtk_grid_set_column_spacing (GTK_GRID(grid),4);
+ gtk_grid_set_row_spacing (GTK_GRID(grid),4);
+
+ GtkWidget *close_b=gtk_button_new_with_label("Close");
+ g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1);
+
+ char rx_id[32];
+ sprintf(rx_id,"RX %d VFO %s",active_receiver->id,active_receiver->id==0?"A":"B");
+ GtkWidget *rx_label=gtk_label_new(rx_id);
+ gtk_grid_attach(GTK_GRID(grid),rx_label,1,0,1,1);
+
+ label = gtk_label_new (NULL);
+ gtk_label_set_markup (GTK_LABEL (label), "<big>0</big>");
+ gtk_misc_set_alignment (GTK_MISC (label), 1, .5);
+ gtk_grid_attach(GTK_GRID(grid),label,0,1,3,1);
+
+ GtkWidget *step_rb=NULL;
+ for (i=0; i<16; i++) {
+ GtkWidget *b=gtk_button_new_with_label(btn_labels[i]);
+ set_button_text_color(b,"black");
+ gtk_widget_show(b);
+ gtk_grid_attach(GTK_GRID(grid),b,i%3,2+(i/3),1,1);
+ g_signal_connect(b,"pressed",G_CALLBACK(freqent_select_cb),(gpointer *)btn_labels[i]);
+ }
+
+ GtkWidget *rit_label=gtk_label_new("RIT step: ");
+ gtk_grid_attach(GTK_GRID(grid),rit_label,3,1,1,1);
+
+ GtkWidget *rit_b=gtk_combo_box_text_new();
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(rit_b),NULL,"1 Hz");
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(rit_b),NULL,"10 Hz");
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(rit_b),NULL,"100 Hz");
+ switch(rit_increment) {
+ case 1:
+ gtk_combo_box_set_active(GTK_COMBO_BOX(rit_b), 0);
+ break;
+ case 10:
+ gtk_combo_box_set_active(GTK_COMBO_BOX(rit_b), 1);
+ break;
+ case 100:
+ gtk_combo_box_set_active(GTK_COMBO_BOX(rit_b), 2);
+ break;
+ }
+ g_signal_connect(rit_b,"changed",G_CALLBACK(rit_cb),NULL);
+ gtk_grid_attach(GTK_GRID(grid),rit_b,3,2,1,1);
+
+ GtkWidget *vfo_label=gtk_label_new("VFO step: ");
+ gtk_grid_attach(GTK_GRID(grid),vfo_label,3,3,1,1);
+
+ GtkWidget *vfo_b=gtk_combo_box_text_new();
+ i=0;
+ while(steps[i]!=0) {
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(vfo_b),NULL,step_labels[i]);
+ if(steps[i]==step) {
+ gtk_combo_box_set_active (GTK_COMBO_BOX(vfo_b), i);
+ }
+ i++;
+ }
+ g_signal_connect(vfo_b,"changed",G_CALLBACK(vfo_cb),NULL);
+ gtk_grid_attach(GTK_GRID(grid),vfo_b,3,4,1,1);
+
+ gtk_container_add(GTK_CONTAINER(content),grid);
+
+ sub_menu=dialog;
+
+ gtk_widget_show_all(dialog);
+
+}
--- /dev/null
+/* 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 void vfo_menu(GtkWidget *parent);
#include <gtk/gtk.h>
#include "radio.h"
+#include "transmitter.h"
#include "vox.h"
#include "vfo.h"
double vox_get_peak() {
- return peak*10.0;
+ double result=peak;
+ return result;
}
-void update_vox(double *in,int length) {
+void update_vox(TRANSMITTER *tx) {
// assumes in is interleaved left and right channel with length samples
int previous_vox=vox;
int i;
double sample;
peak=0.0;
- for(i=0;i<length;i++) {
- sample=in[(i*2)+0];
+ for(i=0;i<tx->buffer_size;i++) {
+ sample=tx->mic_input_buffer[i*2];
if(sample<0.0) {
sample=-sample;
}
peak=sample;
}
}
- double threshold=vox_threshold;
- if(mic_boost && !local_microphone) {
- threshold=vox_threshold*vox_gain;
- }
-fprintf(stderr,"update_vox: peak=%f threshold=%f\n",peak,threshold);
- if(peak>threshold) {
- if(previous_vox) {
- g_source_remove(vox_timeout);
- } else {
- setVox(1);
+//fprintf(stderr,"update_vox: id=%d peak=%f\n",tx->id,peak);
+
+ if(vox_enabled) {
+ double threshold=vox_threshold;
+
+//fprintf(stderr,"update_vox: peak=%f threshold=%f\n",peak,threshold);
+
+ if(peak>threshold) {
+ if(previous_vox) {
+ g_source_remove(vox_timeout);
+ } else {
+ setVox(1);
+ }
+ vox_timeout=g_timeout_add((int)vox_hang,vox_timeout_cb,NULL);
+ }
+ if(vox!=previous_vox) {
+ g_idle_add(vfo_update,NULL);
}
- vox_timeout=g_timeout_add((int)vox_hang,vox_timeout_cb,NULL);
- }
- if(vox!=previous_vox) {
- g_idle_add(vfo_update,NULL);
}
}
*
*/
-extern void update_vox(double *in,int length);
+extern void update_vox(TRANSMITTER *tx);
extern void vox_cancel();
extern double vox_get_peak();
#include <pthread.h>
#include "new_menu.h"
+#include "radio.h"
+#include "transmitter.h"
#include "vox_menu.h"
#include "vox.h"
-#include "radio.h"
static GtkWidget *parent_window=NULL;
static GtkWidget *level;
-static pthread_t level_thread_id;
+GThread *level_thread_id;
static int run_level=0;
static double peak=0.0;
static int level_update(void *data) {
+//fprintf(stderr,"vox peak=%f\n",peak);
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(level),peak);
return 0;
}
static void start_level_thread() {
int rc;
run_level=1;
- rc=pthread_create(&level_thread_id,NULL,level_thread,NULL);
- if(rc != 0) {
- fprintf(stderr,"vox_menu: pthread_create failed on level_thread: rc=%d\n", rc);
- run_level=0;
+ level_thread_id = g_thread_new( "VOX level", level_thread, NULL);
+ if(!level_thread_id ) {
+ fprintf(stderr,"g_thread_new failed on level_thread\n");
}
+ fprintf(stderr, "level_thread: id=%p\n",level_thread_id);
}
static void destroy_cb(GtkWidget *widget, gpointer data) {
run_level=0;
-}
-
-static void vox_cb(GtkWidget *widget, gpointer data) {
- vox_enabled=vox_enabled==1?0:1;
- if(vox_enabled) {
- start_level_thread();
- } else {
- run_level=0;
- }
+ vox_setting=0;
}
static void vox_value_changed_cb(GtkWidget *widget, gpointer data) {
- vox_threshold=gtk_range_get_value(GTK_RANGE(widget))/10000.0;
+ vox_threshold=gtk_range_get_value(GTK_RANGE(widget))/1000.0;
}
static void vox_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL);
gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1);
- GtkWidget *vox_b=gtk_check_button_new_with_label("VOX Enable");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (vox_b), vox_enabled);
- gtk_widget_show(vox_b);
- gtk_grid_attach(GTK_GRID(grid),vox_b,0,1,1,1);
- g_signal_connect(vox_b,"toggled",G_CALLBACK(vox_cb),NULL);
+ GtkWidget *level_label=gtk_label_new("Mic Level:");
+ gtk_misc_set_alignment (GTK_MISC(level_label), 0, 0);
+ gtk_widget_show(level_label);
+ gtk_grid_attach(GTK_GRID(grid),level_label,0,1,1,1);
level=gtk_progress_bar_new();
+ gtk_widget_set_size_request (level, 300, 25);
gtk_widget_show(level);
gtk_grid_attach(GTK_GRID(grid),level,1,1,1,1);
-/*
- // try to set progress bar to red
- GtkStyleContext *style_context;
- GtkCssProvider *provider = gtk_css_provider_new ();
- gchar tmp[64];
- style_context = gtk_widget_get_style_context(level);
- gtk_style_context_add_provider(style_context, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
- g_snprintf(tmp, sizeof tmp, "progressbar.trough.progress { background-color: %s; }", "red");
- gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(provider), tmp, -1, NULL);
- g_object_unref (provider);
-*/
-
GtkWidget *threshold_label=gtk_label_new("VOX Threshold:");
gtk_misc_set_alignment (GTK_MISC(threshold_label), 0, 0);
gtk_widget_show(threshold_label);
GtkWidget *vox_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0,1000.0,1.0);
gtk_widget_set_size_request (vox_scale, 300, 25);
- gtk_range_set_value(GTK_RANGE(vox_scale),vox_threshold*10000.0);
+ gtk_range_set_value(GTK_RANGE(vox_scale),vox_threshold*1000.0);
gtk_widget_show(vox_scale);
gtk_grid_attach(GTK_GRID(grid),vox_scale,1,2,1,1);
g_signal_connect(G_OBJECT(vox_scale),"value_changed",G_CALLBACK(vox_value_changed_cb),NULL);
-/*
- GtkWidget *gain_label=gtk_label_new("VOX Gain:");
- gtk_misc_set_alignment (GTK_MISC(gain_label), 0, 0);
- gtk_widget_show(gain_label);
- gtk_grid_attach(GTK_GRID(grid),gain_label,0,3,1,1);
-
- GtkWidget *gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,1.0,10.0,1.0);
- gtk_range_set_value(GTK_RANGE(gain_scale),vox_gain*10000.0);
- gtk_widget_show(gain_scale);
- gtk_grid_attach(GTK_GRID(grid),gain_scale,1,3,1,1);
- g_signal_connect(G_OBJECT(gain_scale),"value_changed",G_CALLBACK(vox_gain_value_changed_cb),NULL);
-*/
GtkWidget *hang_label=gtk_label_new("VOX Hang (ms):");
gtk_misc_set_alignment (GTK_MISC(hang_label), 0, 0);
gtk_widget_show(hang_label);
gtk_widget_show_all(dialog);
- if(vox_enabled) {
- start_level_thread();
+ if(!vox_enabled) {
+ vox_setting=1;
}
+ start_level_thread();
}
*/
void vox_menu(GtkWidget *parent);
+gboolean vox_cb (GtkWidget *widget, GdkEventButton *event, gpointer data);
+
#include "vfo.h"
#include "waterfall.h"
-static GtkWidget *waterfall;
-static GdkPixbuf *pixbuf = NULL;
static int colorLowR=0; // black
static int colorLowG=0;
static gfloat hz_per_pixel;
+/*
#define BANDS 7
static long long frequency[BANDS];
static gint mode[BANDS];
static gint band=4;
+*/
static int display_width;
static int display_height;
GdkEventConfigure *event,
gpointer data)
{
+ RECEIVER *rx=(RECEIVER *)data;
display_width=gtk_widget_get_allocated_width (widget);
display_height=gtk_widget_get_allocated_height (widget);
- pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, display_width, display_height);
+ rx->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, display_width, display_height);
- char *pixels = gdk_pixbuf_get_pixels (pixbuf);
+ char *pixels = gdk_pixbuf_get_pixels (rx->pixbuf);
memset(pixels, 0, display_width*display_height*3);
cairo_t *cr,
gpointer data)
{
- gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+ RECEIVER *rx=(RECEIVER *)data;
+ gdk_cairo_set_source_pixbuf (cr, rx->pixbuf, 0, 0);
cairo_paint (cr);
return TRUE;
}
GdkEventButton *event,
gpointer data)
{
- int x=(int)event->x;
- if (event->button == 1) {
- last_x=(int)event->x;
- has_moved=FALSE;
- pressed=TRUE;
- }
- return TRUE;
+ return receiver_button_press_event(widget,event,data);
}
static gboolean
GdkEventButton *event,
gpointer data)
{
- if(pressed) {
- int x=(int)event->x;
- if (event->button == 1) {
- if(has_moved) {
- // drag
- vfo_move((int)((float)(x-last_x)*hz_per_pixel));
- } else {
- // move to this frequency
- vfo_move_to((int)((float)(x-(display_width/2))*hz_per_pixel));
- }
- last_x=x;
- pressed=FALSE;
- }
- }
- return TRUE;
+ return receiver_button_release_event(widget,event,data);
}
static gboolean waterfall_motion_notify_event_cb (GtkWidget *widget,
GdkEventMotion *event,
gpointer data)
{
- int x, y;
- GdkModifierType state;
- gdk_window_get_device_position (event->window,
- event->device,
- &x,
- &y,
- &state);
- if((state & GDK_BUTTON1_MASK == GDK_BUTTON1_MASK) || pressed) {
- int moved=last_x-x;
- vfo_move((int)((float)moved*hz_per_pixel));
- last_x=x;
- has_moved=TRUE;
- }
-
- return TRUE;
+ return receiver_motion_notify_event(widget,event,data);
}
static gboolean
GdkEventScroll *event,
gpointer data)
{
- if(event->direction==GDK_SCROLL_UP) {
- vfo_move(step);
- } else {
- vfo_move(-step);
- }
+ return receiver_scroll_event(widget,event,data);
}
-void waterfall_update(float *data) {
+void waterfall_update(RECEIVER *rx) {
int i;
- hz_per_pixel=(double)getSampleRate()/(double)display_width;
-
- if(pixbuf) {
- char *pixels = gdk_pixbuf_get_pixels (pixbuf);
+ float *samples;
+ if(rx->pixbuf) {
+ char *pixels = gdk_pixbuf_get_pixels (rx->pixbuf);
- int width=gdk_pixbuf_get_width(pixbuf);
- int height=gdk_pixbuf_get_height(pixbuf);
- int rowstride=gdk_pixbuf_get_rowstride(pixbuf);
- int channels=gdk_pixbuf_get_n_channels(pixbuf);
+ int width=gdk_pixbuf_get_width(rx->pixbuf);
+ int height=gdk_pixbuf_get_height(rx->pixbuf);
+ int rowstride=gdk_pixbuf_get_rowstride(rx->pixbuf);
+ int channels=gdk_pixbuf_get_n_channels(rx->pixbuf);
memmove(&pixels[rowstride],pixels,(height-1)*rowstride);
int average=0;
char *p;
p=pixels;
+ samples=rx->pixel_samples;
for(i=0;i<width;i++) {
- sample=data[i]+get_attenuation();
+ sample=samples[i]+get_attenuation();
average+=(int)sample;
- if(sample<(float)waterfall_low) {
+ if(sample<(float)rx->waterfall_low) {
*p++=colorLowR;
*p++=colorLowG;
*p++=colorLowB;
- } else if(sample>(float)waterfall_high) {
+ } else if(sample>(float)rx->waterfall_high) {
*p++=colorHighR;
*p++=colorHighG;
*p++=colorHighB;
} else {
- float range=(float)waterfall_high-(float)waterfall_low;
- float offset=sample-(float)waterfall_low;
+ float range=(float)rx->waterfall_high-(float)rx->waterfall_low;
+ float offset=sample-(float)rx->waterfall_low;
float percent=offset/range;
if(percent<(2.0f/9.0f)) {
float local_percent = percent / (2.0f/9.0f);
}
- if(waterfall_automatic) {
- waterfall_low=average/display_width;
- waterfall_high=waterfall_low+50;
+ if(rx->waterfall_automatic) {
+ rx->waterfall_low=average/display_width;
+ rx->waterfall_high=rx->waterfall_low+50;
}
- gtk_widget_queue_draw (waterfall);
+ gtk_widget_queue_draw (rx->waterfall);
}
}
-GtkWidget* waterfall_init(int width,int height) {
+void waterfall_init(RECEIVER *rx,int width,int height) {
display_width=width;
display_height=height;
- hz_per_pixel=(double)getSampleRate()/(double)display_width;
+ rx->pixbuf=NULL;
+ rx->waterfall_low=waterfall_low;
+ rx->waterfall_high=waterfall_high;
+ rx->waterfall_automatic=waterfall_automatic;
+
+ hz_per_pixel=(double)rx->sample_rate/(double)display_width;
//waterfall_frame = gtk_frame_new (NULL);
- waterfall = gtk_drawing_area_new ();
- gtk_widget_set_size_request (waterfall, width, height);
+ rx->waterfall = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (rx->waterfall, width, height);
/* Signals used to handle the backing surface */
- g_signal_connect (waterfall, "draw",
- G_CALLBACK (waterfall_draw_cb), NULL);
- g_signal_connect (waterfall,"configure-event",
- G_CALLBACK (waterfall_configure_event_cb), NULL);
+ g_signal_connect (rx->waterfall, "draw",
+ G_CALLBACK (waterfall_draw_cb), rx);
+ g_signal_connect (rx->waterfall,"configure-event",
+ G_CALLBACK (waterfall_configure_event_cb), rx);
/* Event signals */
- g_signal_connect (waterfall, "motion-notify-event",
- G_CALLBACK (waterfall_motion_notify_event_cb), NULL);
- g_signal_connect (waterfall, "button-press-event",
- G_CALLBACK (waterfall_button_press_event_cb), NULL);
- g_signal_connect (waterfall, "button-release-event",
- G_CALLBACK (waterfall_button_release_event_cb), NULL);
- g_signal_connect(waterfall,"scroll_event",
- G_CALLBACK(waterfall_scroll_event_cb),NULL);
+ g_signal_connect (rx->waterfall, "motion-notify-event",
+ G_CALLBACK (waterfall_motion_notify_event_cb), rx);
+ g_signal_connect (rx->waterfall, "button-press-event",
+ G_CALLBACK (waterfall_button_press_event_cb), rx);
+ g_signal_connect (rx->waterfall, "button-release-event",
+ G_CALLBACK (waterfall_button_release_event_cb), rx);
+ g_signal_connect(rx->waterfall,"scroll_event",
+ G_CALLBACK(waterfall_scroll_event_cb),rx);
/* Ask to receive events the drawing area doesn't normally
* subscribe to. In particular, we need to ask for the
* button press and motion notify events that want to handle.
*/
- gtk_widget_set_events (waterfall, gtk_widget_get_events (waterfall)
+ gtk_widget_set_events (rx->waterfall, gtk_widget_get_events (rx->waterfall)
| GDK_BUTTON_PRESS_MASK
| GDK_BUTTON_RELEASE_MASK
| GDK_BUTTON1_MOTION_MASK
| GDK_POINTER_MOTION_MASK
| GDK_POINTER_MOTION_HINT_MASK);
- return waterfall;
}
#ifndef _WATERFALL_H
#define _WATERFALL_H
-void waterfall_update(float *data);
-GtkWidget* waterfall_init(int width,int height);
+extern void waterfall_update(RECEIVER *rx);
+extern void waterfall_init(RECEIVER *rx,int width,int height);
#endif
static int receiver;
static int running=0;
-static int buffer_size=BUFFER_SIZE;
-static int tx_buffer_size=BUFFER_SIZE;
-static int fft_size=4096;
+//static int buffer_size=BUFFER_SIZE;
+//static int tx_buffer_size=BUFFER_SIZE;
+static int tx_buffer_size;
static int dspRate=48000;
static int outputRate=48000;
static int dvOutputRate=8000;
if(protocol==ORIGINAL_PROTOCOL) {
switch(sample_rate) {
case 48000:
- tx_buffer_size=BUFFER_SIZE;
+ tx_buffer_size=buffer_size;
break;
case 96000:
- tx_buffer_size=BUFFER_SIZE/2;
+ tx_buffer_size=buffer_size/2;
break;
case 192000:
- tx_buffer_size=BUFFER_SIZE/4;
+ tx_buffer_size=buffer_size/4;
break;
case 384000:
- tx_buffer_size=BUFFER_SIZE/8;
+ tx_buffer_size=buffer_size/8;
break;
}
} else {
- tx_buffer_size=BUFFER_SIZE; // input always 192K
+ tx_buffer_size=buffer_size; // input always 192K
}
}
}
// setup for diversity
- create_divEXT(0,0,2,BUFFER_SIZE);
+ create_divEXT(0,0,2,buffer_size);
SetEXTDIVRotate(0, 2, &i_rotate, &q_rotate);
SetEXTDIVRun(0,diversity_enabled);
}
int max_w = fft_size + (int) MIN(KEEP_TIME * (double) SPECTRUM_UPDATES_PER_SECOND, KEEP_TIME * (double) fft_size * (double) SPECTRUM_UPDATES_PER_SECOND);
- fprintf(stderr,"SetAnalyzer channel=%d buffer_size=%d\n",channel,buffer_size);
+ overlap = (int)max(0.0, ceil(fft_size - (double)sample_rate / (double)SPECTRUM_UPDATES_PER_SECOND));
+
+ fprintf(stderr,"SetAnalyzer channel=%d buffer_size=%d overlap=%d\n",channel,buffer_size,overlap);
+
#ifdef PSK
if(channel==CHANNEL_PSK) {
data_type=0;
+++ /dev/null
-/* Copyright (C)
-* 2015 - John Melton, G0ORX/N6LYT
-*
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-*/
-
-#ifndef _WDSP_INIT_H
-#define _WDSP_INIT_H
-
-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);
-extern int getFilterLow();
-extern int getFilterHigh();
-extern void wdsp_init(int rx,int pixels,int protocol);
-extern void wdsp_new_sample_rate(int rate);
-extern void wdsp_set_agc(int rx, int agc);
-extern void wdsp_set_deviation(double deviation);
-extern void wdsp_set_pre_emphasize(int state);
-#endif
#include <gtk/gtk.h>
#include <semaphore.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "new_menu.h"
lof=gtk_entry_get_text(GTK_ENTRY(lo_frequency[i]));
xvtr->frequencyLO=atoll(lof);
xvtr->disablePA=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(disable_pa[i]));
- entry->frequencyA=xvtr->frequencyMin;
- entry->frequencyB=xvtr->frequencyMin;
+ entry->frequency=xvtr->frequencyMin;
entry->mode=modeUSB;
entry->filter=filterF6;
+fprintf(stderr,"min=%s:%lld max=%s:%lld lo=%s:%lld\n",minf,xvtr->frequencyMin,maxf,xvtr->frequencyMax,lof,xvtr->frequencyLO);
} else {
xvtr->frequencyMin=0;
xvtr->frequencyMax=0;