schedule_high_priority();
#ifdef SOAPYSDR
} else if(radio->device==SOAPYSDR_USB_DEVICE) {
- soapy_protocol_set_tx_antenna(transmitter,dac[0].antenna);
+ soapy_protocol_set_tx_antenna(transmitter,dac->antenna);
#endif
}
}
//static unsigned char *audio_buffer=NULL;
//static int audio_offset=0;
-static unsigned char *mic_buffer=NULL;
+static float *mic_buffer=NULL;
static GThread *mic_read_thread_id;
static void *mic_read_thread(void *arg);
-char *input_devices[32];
-int n_input_devices=0;
-//int n_selected_input_device=-1;
-char *output_devices[32];
-int n_output_devices=0;
-//int n_selected_output_device=-1;
+int n_input_devices;
+AUDIO_DEVICE input_devices[MAX_AUDIO_DEVICES];
+int n_output_devices;
+AUDIO_DEVICE output_devices[MAX_AUDIO_DEVICES];
int audio_open_output(RECEIVER *rx) {
int err;
int rate=48000;
int dir=0;
-
-fprintf(stderr,"audio_open_output: rx=%d audio_device=%d\n",rx->id,rx->audio_device);
- if(rx->audio_device<0 || rx->audio_device>=n_output_devices) {
- rx->audio_device=-1;
+ if(rx->audio_name==NULL) {
+ rx->local_audio=0;
return -1;
}
+fprintf(stderr,"audio_open_output: rx=%d %s\n",rx->id,rx->audio_name);
+
int i;
- char hw[64];
- char *selected=output_devices[rx->audio_device];
+ char hw[128];
-fprintf(stderr,"audio_open_output: selected=%d:%s\n",rx->audio_device,selected);
+fprintf(stderr,"audio_open_output: selected=%s\n",rx->audio_name);
i=0;
- while(selected[i]!=' ') {
- hw[i]=selected[i];
+ while(rx->audio_name[i]!=' ') {
+ hw[i]=rx->audio_name[i];
i++;
}
hw[i]='\0';
int rate=48000;
int dir=0;
-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;
+ if(transmitter->microphone_name==NULL) {
+ transmitter->local_microphone=0;
return -1;
}
+fprintf(stderr,"audio_open_input: %s\n",transmitter->microphone_name);
int i;
char hw[64];
- 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:
fprintf(stderr,"audio_open_input: mic_buffer_size=%d\n",mic_buffer_size);
i=0;
- while(selected[i]!=' ') {
- hw[i]=selected[i];
+ while(transmitter->microphone_name[i]!=' ') {
+ hw[i]=transmitter->microphone_name[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) {
return -1;
}
- if ((err = snd_pcm_hw_params_set_format (record_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
+ if ((err = snd_pcm_hw_params_set_format (record_handle, hw_params, SND_PCM_FORMAT_FLOAT_LE)) < 0) {
fprintf (stderr, "audio_open_input: cannot set sample format (%s)\n",
snd_strerror (err));
audio_close_input();
snd_pcm_hw_params_free (hw_params);
- mic_buffer=(unsigned char *)malloc(MIC_BUFFER_SIZE);
+ mic_buffer=g_new0(float,mic_buffer_size);
+
running=TRUE;
mic_read_thread_id = g_thread_new( "local mic", mic_read_thread, NULL);
// process the mic input
switch(protocol) {
case ORIGINAL_PROTOCOL:
- old_protocol_process_local_mic(mic_buffer,1);
+ old_protocol_process_local_mic(mic_buffer);
break;
case NEW_PROTOCOL:
- new_protocol_process_local_mic(mic_buffer,1);
+ new_protocol_process_local_mic(mic_buffer);
break;
#ifdef SOAPYSDR
case SOAPYSDR_PROTOCOL:
- soapy_protocol_process_local_mic(mic_buffer,1);
+ soapy_protocol_process_local_mic(mic_buffer);
break;
#endif
default:
fprintf(stderr,"audio_get_cards\n");
- for(i=0;i<n_input_devices;i++) {
- free(input_devices[i]);
- }
n_input_devices=0;
-
- for(i=0;i<n_output_devices;i++) {
- free(output_devices[i]);
- }
n_output_devices=0;
+ snd_ctl_card_info_alloca(&info);
+ snd_pcm_info_alloca(&pcminfo);
while (snd_card_next(&card) >= 0 && card >= 0) {
int err = 0;
snd_ctl_t *handle;
// input devices
snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE);
if ((err = snd_ctl_pcm_info(handle, pcminfo)) == 0) {
- device_id=malloc(64);
- snprintf(device_id, 64, "plughw:%d,%d %s", card, dev, snd_ctl_card_info_get_name(info));
- input_devices[n_input_devices++]=device_id;
+ device_id=malloc(128);
+ snprintf(device_id, 128, "plughw:%d,%d %s", card, dev, snd_ctl_card_info_get_name(info));
+ if(n_input_devices<MAX_AUDIO_DEVICES) {
+ input_devices[n_input_devices].name=g_new0(char,strlen(device_id)+1);
+ strcpy(input_devices[n_input_devices].name,device_id);
+ input_devices[n_input_devices].description=g_new0(char,strlen(device_id)+1);
+ strcpy(input_devices[n_input_devices].description,device_id);
+ input_devices[n_input_devices].index=i;
+ n_input_devices++;
+ }
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) {
- device_id=malloc(64);
- snprintf(device_id, 64, "plughw:%d,%d %s", card, dev, snd_ctl_card_info_get_name(info));
- output_devices[n_output_devices++]=device_id;
+ device_id=malloc(128);
+ snprintf(device_id, 128, "plughw:%d,%d %s", card, dev, snd_ctl_card_info_get_name(info));
+ if(n_output_devices<MAX_AUDIO_DEVICES) {
+ output_devices[n_output_devices].name=g_new0(char,strlen(device_id)+1);
+ strcpy(output_devices[n_output_devices].name,device_id);
+ output_devices[n_output_devices].description=g_new0(char,strlen(device_id)+1);
+ strcpy(output_devices[n_output_devices].description,device_id);
+ input_devices[n_output_devices].index=i;
+ n_output_devices++;
+ }
fprintf(stderr,"output_device: %s\n",device_id);
}
}
-
snd_ctl_close(handle);
-
}
// look for dmix
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);
- device_id=malloc(64);
-
- snprintf(device_id, 64, "%s", name);
- output_devices[n_output_devices++]=device_id;
+ device_id=malloc(128);
+
+ snprintf(device_id, 128, "%s", name);
+ if(n_output_devices<MAX_AUDIO_DEVICES) {
+ output_devices[n_output_devices].name=g_new0(char,strlen(device_id)+1);
+ strcpy(output_devices[n_output_devices].name,device_id);
+ output_devices[n_output_devices].description=g_new0(char,strlen(device_id)+1);
+ strcpy(output_devices[n_output_devices].description,device_id);
+ input_devices[n_output_devices].index=i;
+ n_output_devices++;
+ }
fprintf(stderr,"output_device: %s\n",device_id);
}
#include "receiver.h"
-extern char *input_devices[];
-extern int n_input_devices;
-//extern int n_selected_input_device;
+#define MAX_AUDIO_DEVICES 64
+
+typedef struct _audio_devices {
+ char *name;
+ int index;
+ char *description;
+} AUDIO_DEVICE;
-extern char *output_devices[];
+extern int n_input_devices;
+extern AUDIO_DEVICE input_devices[MAX_AUDIO_DEVICES];
extern int n_output_devices;
-//extern int n_selected_output_device;
+extern AUDIO_DEVICE output_devices[MAX_AUDIO_DEVICES];
extern int audio_open_input();
extern void audio_close_input();
case ENCODER_RIT_RX2:
button=b_rit_rx2;
break;
+ case ENCODER_XIT:
+ button=b_xit;
+ break;
case ENCODER_CW_SPEED:
button=b_cw_speed;
break;
case ENCODER_RIT_RX2:
button=b_top_rit_rx2;
break;
+ case ENCODER_XIT:
+ button=b_top_xit;
+ break;
case ENCODER_CW_SPEED:
button=b_top_cw_speed;
break;
g_signal_connect(enc5,"button_press_event",G_CALLBACK(enc_cb),GINT_TO_POINTER(ENC5));
col++;
-#ifdef CONTROLLER2
+#if defined (CONTROLLER2_V2)
GtkWidget *enc5_top=gtk_button_new_with_label(encoder_string[e5_top_encoder_action]);
gtk_grid_attach(GTK_GRID(grid),enc5_top,col,row,1,1);
g_signal_connect(enc5_top,"button_press_event",G_CALLBACK(enc_cb),GINT_TO_POINTER(ENC5_TOP));
#include <stdio.h>
#include <string.h>
+#include "main.h"
#include "new_menu.h"
#include "exit_menu.h"
+#include "discovery.h"
#include "radio.h"
#include "new_protocol.h"
#include "old_protocol.h"
}
}
+static gboolean discovery_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ cleanup();
+#ifdef GPIO
+ gpio_close();
+#endif
+ switch(protocol) {
+ case ORIGINAL_PROTOCOL:
+ old_protocol_stop();
+ break;
+ case NEW_PROTOCOL:
+ new_protocol_stop();
+ break;
+#ifdef SOAPYSDR
+ case SOAPYSDR_PROTOCOL:
+ soapy_protocol_stop();
+ break;
+#endif
+ }
+ radioSaveState();
+ radio_stop();
+ gtk_container_remove(GTK_CONTAINER(top_window), fixed);
+ gtk_widget_destroy(fixed);
+ gtk_container_add(GTK_CONTAINER(top_window), grid);
+ discovery();
+ return TRUE;
+}
+
static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
cleanup();
return TRUE;
#endif
}
radioSaveState();
+
_exit(0);
}
g_signal_connect (close_b, "pressed", G_CALLBACK(close_cb), NULL);
gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1);
+ GtkWidget *discovery_b=gtk_button_new_with_label("Discovery");
+ g_signal_connect (discovery_b, "pressed", G_CALLBACK(discovery_cb), NULL);
+ gtk_grid_attach(GTK_GRID(grid),discovery_b,0,1,1,1);
+
GtkWidget *exit_b=gtk_button_new_with_label("Exit");
g_signal_connect (exit_b, "pressed", G_CALLBACK(exit_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),exit_b,0,1,1,1);
+ gtk_grid_attach(GTK_GRID(grid),exit_b,1,1,1,1);
GtkWidget *reboot_b=gtk_button_new_with_label("Reboot");
g_signal_connect (reboot_b, "pressed", G_CALLBACK(reboot_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),reboot_b,1,1,1,1);
+ gtk_grid_attach(GTK_GRID(grid),reboot_b,2,1,1,1);
GtkWidget *shutdown_b=gtk_button_new_with_label("Shutdown");
g_signal_connect (shutdown_b, "pressed", G_CALLBACK(shutdown_cb), NULL);
- gtk_grid_attach(GTK_GRID(grid),shutdown_b,2,1,1,1);
+ gtk_grid_attach(GTK_GRID(grid),shutdown_b,3,1,1,1);
gtk_container_add(GTK_CONTAINER(content),grid);
}
int ext_xit_update(void *data) {
+ if(can_transmit) {
+ transmitter->xit_enabled=transmitter->xit_enabled==1?0:1;
+ if(protocol==NEW_PROTOCOL) {
+ schedule_high_priority();
+ }
+ }
+ vfo_update();
return 0;
}
int ext_xit_clear(void *data) {
+ if(can_transmit) {
+ transmitter->xit=0;
+ vfo_update();
+ }
return 0;
}
return 0;
}
+int ext_sat_update(void *data) {
+ int mode=GPOINTER_TO_INT(data);
+ if(sat_mode==mode) {
+ sat_mode=SAT_NONE;
+ } else {
+ sat_mode=mode;
+ }
+ vfo_update();
+ return 0;
+}
+
int ext_function_update(void *data) {
function++;
if(function>MAX_FUNCTION) {
int ext_start_rx(void *data);
int ext_diversity_update(void *data);
+int ext_sat_update(void *data);
"AGC",
"SPLIT",
"DIVERSITY",
+ "SAT",
+ "RSAT",
"BAND MENU",
"BANDSTACK MENU",
"MODE MENU",
fprintf(stderr,"e_function_pressed: %d\n",action);
switch(action) {
case TUNE:
- g_idle_add(ext_tune_update,NULL);
+ if(can_transmit) g_idle_add(ext_tune_update,NULL);
break;
case MOX:
- g_idle_add(ext_mox_update,NULL);
+ if(can_transmit) g_idle_add(ext_mox_update,NULL);
break;
case PS:
#ifdef PURESIGNAL
- g_idle_add(ext_ps_update,NULL);
+ if(can_transmit) g_idle_add(ext_ps_update,NULL);
#endif
break;
case TWO_TONE:
- g_idle_add(ext_two_tone,NULL);
+ if(can_transmit) g_idle_add(ext_two_tone,NULL);
break;
case NR:
g_idle_add(ext_nr_update,NULL);
g_idle_add(ext_rit_clear,NULL);
break;
case XIT:
- g_idle_add(ext_xit_update,NULL);
+ if(can_transmit) g_idle_add(ext_xit_update,NULL);
break;
case XIT_CLEAR:
- g_idle_add(ext_xit_clear,NULL);
+ if(can_transmit) g_idle_add(ext_xit_clear,NULL);
break;
case BAND_PLUS:
g_idle_add(ext_band_plus,NULL);
g_idle_add(ext_agc_update,NULL);
break;
case SPLIT:
- g_idle_add(ext_split_update,NULL);
+ if(can_transmit) g_idle_add(ext_split_update,NULL);
break;
case DIVERSITY:
g_idle_add(ext_diversity_update,GINT_TO_POINTER(0));
break;
+ case SAT:
+ if(can_transmit) g_idle_add(ext_sat_update,GINT_TO_POINTER(SAT_MODE));
+ break;
+ case RSAT:
+ if(can_transmit) g_idle_add(ext_sat_update,GINT_TO_POINTER(RSAT_MODE));
+ break;
case MENU_BAND:
g_idle_add(ext_band_update,NULL);
break;
}
set_af_gain(1,value);
break;
+ case ENCODER_RF_GAIN_RX1:
+ value=receiver[0]->rf_gain;
+ value+=(double)pos;
+ if(value<0.0) {
+ value=0.0;
+ } else if(value>100.0) {
+ value=100.0;
+ }
+ set_rf_gain(0,value);
+ break;
+ case ENCODER_RF_GAIN_RX2:
+ value=receiver[1]->rf_gain;
+ value+=(double)pos;
+ if(value<0.0) {
+ value=0.0;
+ } else if(value>71.0) {
+ value=71.0;
+ }
+ set_rf_gain(1,value);
+ break;
case ENCODER_AGC_GAIN_RX1:
value=receiver[0]->agc_gain;
value+=(double)pos;
case ENCODER_MIC_GAIN:
value=mic_gain;
value+=(double)pos;
- if(value<-10.0) {
- value=-10.0;
+ if(value<-12.0) {
+ value=-12.0;
} else if(value>50.0) {
value=50.0;
}
case ENCODER_RIT_RX1:
value=(double)vfo[receiver[0]->id].rit;
value+=(double)(pos*rit_increment);
- if(value<-1000.0) {
- value=-1000.0;
- } else if(value>1000.0) {
- value=1000.0;
+ if(value<-10000.0) {
+ value=-10000.0;
+ } else if(value>10000.0) {
+ value=10000.0;
}
vfo[receiver[0]->id].rit=(int)value;
if(protocol==NEW_PROTOCOL) {
case ENCODER_RIT_RX2:
value=(double)vfo[receiver[1]->id].rit;
value+=(double)(pos*rit_increment);
- if(value<-1000.0) {
- value=-1000.0;
- } else if(value>1000.0) {
- value=1000.0;
+ if(value<-10000.0) {
+ value=-10000.0;
+ } else if(value>10000.0) {
+ value=10000.0;
}
vfo[receiver[1]->id].rit=(int)value;
if(protocol==NEW_PROTOCOL) {
}
g_idle_add(ext_vfo_update,NULL);
break;
+ case ENCODER_XIT:
+ value=(double)transmitter->xit;
+ value+=(double)(pos*rit_increment);
+ if(value<-10000.0) {
+ value=-10000.0;
+ } else if(value>10000.0) {
+ value=10000.0;
+ }
+ transmitter->xit=(int)value;
+ if(protocol==NEW_PROTOCOL) {
+ schedule_high_priority();
+ }
+ g_idle_add(ext_vfo_update,NULL);
+ break;
case ENCODER_CW_SPEED:
value=(double)cw_keyer_speed;
value+=(double)pos;
AGC,
SPLIT,
DIVERSITY,
+ SAT,
+ RSAT,
MENU_BAND,
MENU_BANDSTACK,
MENU_MODE,
//g_print("i1c_interrupt: sw=%d action=%d\n",i,sw_action[i]);
switch(sw_action[i]) {
case TUNE:
- {
- int tune=getTune();
- if(tune==0) tune=1; else tune=0;
- g_idle_add(ext_tune_update,GINT_TO_POINTER(tune));
+ if(can_transmit) {
+ int tune=getTune();
+ if(tune==0) tune=1; else tune=0;
+ g_idle_add(ext_tune_update,GINT_TO_POINTER(tune));
}
break;
case MOX:
- {
- int mox=getMox();
- if(mox==0) mox=1; else mox=0;
- g_idle_add(ext_mox_update,GINT_TO_POINTER(mox));
+ if(can_transmit) {
+ int mox=getMox();
+ if(mox==0) mox=1; else mox=0;
+ g_idle_add(ext_mox_update,GINT_TO_POINTER(mox));
}
break;
case PS:
#ifdef PURESIGNAL
- g_idle_add(ext_ps_update,NULL);
+ if(can_transmit) g_idle_add(ext_ps_update,NULL);
#endif
break;
case TWO_TONE:
- g_idle_add(ext_two_tone,NULL);
+ if(can_transmit) g_idle_add(ext_two_tone,NULL);
break;
case NR:
g_idle_add(ext_nr_update,NULL);
g_idle_add(ext_rit_clear,NULL);
break;
case XIT:
- g_idle_add(ext_xit_update,NULL);
+ if(can_transmit) g_idle_add(ext_xit_update,NULL);
break;
case XIT_CLEAR:
- g_idle_add(ext_xit_clear,NULL);
+ if(can_transmit) g_idle_add(ext_xit_clear,NULL);
break;
case BAND_PLUS:
g_idle_add(ext_band_plus,NULL);
g_idle_add(ext_agc_update,NULL);
break;
case SPLIT:
- g_idle_add(ext_split_update,NULL);
+ if(can_transmit) g_idle_add(ext_split_update,NULL);
+ break;
+ case DIVERSITY:
+ g_idle_add(ext_diversity_update,GINT_TO_POINTER(0));
+ break;
+ case SAT:
+ if(can_transmit) g_idle_add(ext_sat_update,GINT_TO_POINTER(SAT_MODE));
+ break;
+ case RSAT:
+ if(can_transmit) g_idle_add(ext_sat_update,GINT_TO_POINTER(RSAT_MODE));
+ break;
+ case MENU_BAND:
+ g_idle_add(ext_band_update,NULL);
+ break;
+ case MENU_BANDSTACK:
+ g_idle_add(ext_bandstack_update,NULL);
+ break;
+ case MENU_MODE:
+ g_idle_add(ext_mode_update,NULL);
+ break;
+ case MENU_FILTER:
+ g_idle_add(ext_filter_update,NULL);
+ break;
+ case MENU_FREQUENCY:
+ g_idle_add(ext_frequency_update,NULL);
+ break;
+ case MENU_MEMORY:
+ g_idle_add(ext_memory_update,NULL);
+ break;
+ case MENU_DIVERSITY:
+ g_idle_add(ext_diversity_update,GINT_TO_POINTER(1));
break;
}
}
break;
case COMPRESS:
// Use values in the range 0 ... 20
- if (type == MIDI_WHEEL) {
- dnew=transmitter->compressor_level + val;
- if (dnew > 20.0) dnew=20.0;
- if (dnew < 0 ) dnew=0;
- } else if (type == MIDI_KNOB){
+ if(can_transmit) {
+ if (type == MIDI_WHEEL) {
+ dnew=transmitter->compressor_level + val;
+ if (dnew > 20.0) dnew=20.0;
+ if (dnew < 0 ) dnew=0;
+ } else if (type == MIDI_KNOB){
dnew=(20.0*val)/100.0;
- } else {
+ } else {
break;
- }
- transmitter->compressor_level=dnew;
- if (dnew < 0.5) transmitter->compressor=0;
- if (dnew > 0.5) transmitter->compressor=1;
- g_idle_add(ext_set_compression, NULL);
+ }
+ transmitter->compressor_level=dnew;
+ if (dnew < 0.5) transmitter->compressor=0;
+ if (dnew > 0.5) transmitter->compressor=1;
+ g_idle_add(ext_set_compression, NULL);
+ }
break;
case MIDI_NB:
// cycle through NoiseBlanker settings
break;
case VOX:
// toggle VOX
- vox_enabled = !vox_enabled;
- g_idle_add(ext_vfo_update, NULL);
+ if(can_transmit) {
+ vox_enabled = !vox_enabled;
+ g_idle_add(ext_vfo_update, NULL);
+ }
break;
case MIDI_CTUN:
// toggle CTUN
case MIDI_PS:
#ifdef PURESIGNAL
// toggle PURESIGNAL
- new=!(transmitter->puresignal);
- g_idle_add(ext_tx_set_ps,GINT_TO_POINTER(new));
+ if(can_transmit) {
+ new=!(transmitter->puresignal);
+ g_idle_add(ext_tx_set_ps,GINT_TO_POINTER(new));
+ }
#endif
break;
case MIDI_SPLIT:
// toggle split mode
- if(!split) {
+ if(can_transmit) {
+ if(!split) {
split=1;
tx_set_mode(transmitter,vfo[VFO_B].mode);
- } else {
+ } else {
split=0;
tx_set_mode(transmitter,vfo[VFO_A].mode);
- }
- g_idle_add(ext_vfo_update, NULL);
+ }
+ g_idle_add(ext_vfo_update, NULL);
+ }
break;
case VFO_A2B:
g_idle_add(ext_vfo_a_to_b, NULL);
//
txFrequency=vfo[txvfo].frequency-vfo[txvfo].lo+vfo[txvfo].offset;
+ if(transmitter->xit_enabled) {
+ txFrequency+=transmitter->xit;
+ }
if (!cw_is_on_vfo_freq) {
if(txmode==modeCWU) {
}
}
-void new_protocol_process_local_mic(unsigned char *buffer,int le) {
- int b;
+void new_protocol_process_local_mic(float *buffer) {
int i;
short sample;
- b=0;
for(i=0;i<MIC_SAMPLES;i++) {
- if(le) {
- sample = (short)(buffer[b++]&0xFF);
- sample |= (short) (buffer[b++]<<8);
- } else {
- sample = (short)(buffer[b++]<<8);
- sample |= (short) (buffer[b++]&0xFF);
- }
+ sample = (short)(buffer[i]*32767.0);
#ifdef FREEDV
if(active_receiver->freedv) {
add_freedv_mic_sample(transmitter,sample);
extern void setTune(int state);
extern int getTune();
-extern void new_protocol_process_local_mic(unsigned char *buffer,int le);
+extern void new_protocol_process_local_mic(float *buffer);
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);
extern void new_protocol_flush_iq_samples();
}
}
freq=vfo[vfonum].frequency-vfo[vfonum].lo+vfo[vfonum].offset;
+ if(transmitter->xit_enabled) {
+ freq+=transmitter->xit;
+ }
if (!cw_is_on_vfo_freq) {
if(vfo[vfonum].mode==modeCWU) {
freq+=(long long)cw_keyer_sidetone_frequency;
}
-void old_protocol_process_local_mic(unsigned char *buffer,int le) {
- int b;
+void old_protocol_process_local_mic(float *buffer) {
int i;
short sample;
// always 48000 samples per second
- b=0;
for(i=0;i<720;i++) {
// avoid pointer increments in logical-or constructs, as the sequence
// is undefined
- if(le) {
- sample = (short) (buffer[b++]&0xFF);
- sample |= (short) (buffer[b++]<<8);
- } else {
- sample = (short)(buffer[b++]<<8);
- sample |= (short) (buffer[b++]&0xFF);
- }
+ sample = (short) (buffer[i]*32767.0);
#ifdef FREEDV
if(active_receiver->freedv) {
add_freedv_mic_sample(transmitter,sample);
extern void old_protocol_init(int rx,int pixels,int rate);
extern void old_protocol_set_mic_sample_rate(int rate);
-extern void old_protocol_process_local_mic(unsigned char *buffer,int le);
+extern void old_protocol_process_local_mic(float *buffer);
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);
extern void old_protocol_iq_samples_with_sidetone(int isample,int qsample,int side);
#define FREEDV_WATERFALL_HEIGHT (105)
#endif
-static GtkWidget *fixed;
+GtkWidget *fixed;
static GtkWidget *vfo_panel;
static GtkWidget *meter;
static GtkWidget *menu;
static cairo_surface_t *encoders_surface = NULL;
#endif
+gint sat_mode;
+
int region=REGION_OTHER;
int echo=0;
int can_transmit=0;
+gboolean duplex=FALSE;
+
+void radio_stop() {
+ if(can_transmit) {
+g_print("radio_stop: TX: CloseChannel: %d\n",transmitter->id);
+ CloseChannel(transmitter->id);
+ }
+ set_displaying(receiver[0],0);
+g_print("radio_stop: RX0: CloseChannel: %d\n",receiver[0]->id);
+ CloseChannel(receiver[0]->id);
+ set_displaying(receiver[1],0);
+g_print("radio_stop: RX1: CloseChannel: %d\n",receiver[1]->id);
+ CloseChannel(receiver[1]->id);
+}
+
void reconfigure_radio() {
int i;
int y;
y=0;
fixed=gtk_fixed_new();
+ g_object_ref(grid); // so it does not get deleted
gtk_container_remove(GTK_CONTAINER(top_window),grid);
gtk_container_add(GTK_CONTAINER(top_window), fixed);
int tx_height=rx_height;
rx_height=rx_height/RECEIVERS;
-
//
// To be on the safe side, we create ALL receiver panels here
// If upon startup, we only should display one panel, we do the switch below
//fprintf(stderr,"Create transmitter\n");
if(can_transmit) {
- transmitter=create_transmitter(CHANNEL_TX, buffer_size, fft_size, updates_per_second, display_width, tx_height);
+ transmitter=create_transmitter(CHANNEL_TX, buffer_size, fft_size, updates_per_second, display_width/2, tx_height/2);
transmitter->x=0;
transmitter->y=VFO_HEIGHT;
receiver[PS_RX_FEEDBACK]=create_pure_signal_receiver(PS_RX_FEEDBACK, buffer_size,protocol==ORIGINAL_PROTOCOL?active_receiver->sample_rate:192000,display_width);
SetPSHWPeak(transmitter->id, protocol==ORIGINAL_PROTOCOL? 0.4067 : 0.2899);
#endif
+
}
#ifdef AUDIO_WATERFALL
if(can_transmit) {
soapy_protocol_create_transmitter(transmitter);
soapy_protocol_set_tx_antenna(transmitter,dac[0].antenna);
+/*
for(int i=0;i<radio->info.soapy.tx_gains;i++) {
- soapy_protocol_set_tx_gain(transmitter,radio->info.soapy.tx_gain[i],dac[0].tx_gain[i]);
+ soapy_protocol_set_tx_gain_element(transmitter,radio->info.soapy.tx_gain[i],dac[0].tx_gain[i]);
}
+*/
+ soapy_protocol_set_tx_gain(transmitter,transmitter->drive);
soapy_protocol_set_tx_frequency(transmitter);
+ soapy_protocol_start_transmitter(transmitter);
}
soapy_protocol_set_rx_antenna(rx,adc[0].antenna);
+/*
for(int i=0;i<radio->info.soapy.rx_gains;i++) {
- soapy_protocol_set_gain(rx,radio->info.soapy.rx_gain[i],adc[0].rx_gain[i]);
+ soapy_protocol_set_gain_element(rx,radio->info.soapy.rx_gain[i],adc[0].rx_gain[i]);
}
+*/
+
soapy_protocol_set_rx_frequency(rx,VFO_A);
soapy_protocol_set_automatic_gain(rx,adc[0].agc);
for(int i=0;i<radio->info.soapy.rx_gains;i++) {
- soapy_protocol_set_gain(rx,radio->info.soapy.rx_gain[i],adc[0].rx_gain[i]);
+ soapy_protocol_set_gain_element(rx,radio->info.soapy.rx_gain[i],adc[0].rx_gain[i]);
}
if(vfo[0].ctun) {
}
soapy_protocol_start_receiver(rx);
+//g_print("radio: set rf_gain=%f\n",rx->rf_gain);
+ soapy_protocol_set_gain(rx,rx->rf_gain);
+
}
#endif
static void rxtx(int state) {
int i;
+ g_print("rxtx: state=%d duplex=%d\n",state,duplex);
if(state) {
// switch to tx
#ifdef FREEDV
tx_feedback->samples=0;
#endif
- for(i=0;i<receivers;i++) {
- // Delivery of RX samples
- // to WDSP via fexchange0() may come to an abrupt stop
- // (especially with PURESIGNAL or DIVERSITY).
- // Therefore, wait for *all* receivers to complete
- // their slew-down before going TX.
- SetChannelState(receiver[i]->id,0,1);
- set_displaying(receiver[i],0);
- g_object_ref((gpointer)receiver[i]->panel);
- g_object_ref((gpointer)receiver[i]->panadapter);
- if(receiver[i]->waterfall!=NULL) {
- g_object_ref((gpointer)receiver[i]->waterfall);
+ if(!duplex) {
+ for(i=0;i<receivers;i++) {
+ // Delivery of RX samples
+ // to WDSP via fexchange0() may come to an abrupt stop
+ // (especially with PURESIGNAL or DIVERSITY).
+ // Therefore, wait for *all* receivers to complete
+ // their slew-down before going TX.
+ SetChannelState(receiver[i]->id,0,1);
+ set_displaying(receiver[i],0);
+ g_object_ref((gpointer)receiver[i]->panel);
+ g_object_ref((gpointer)receiver[i]->panadapter);
+ if(receiver[i]->waterfall!=NULL) {
+ g_object_ref((gpointer)receiver[i]->waterfall);
+ }
+ gtk_container_remove(GTK_CONTAINER(fixed),receiver[i]->panel);
}
- gtk_container_remove(GTK_CONTAINER(fixed),receiver[i]->panel);
}
//#ifdef FREEDV
// if(active_receiver->freedv) {
// }
//#endif
gtk_fixed_put(GTK_FIXED(fixed),transmitter->panel,transmitter->x,transmitter->y);
+
SetChannelState(transmitter->id,1,0);
tx_set_displaying(transmitter,1);
+ switch(protocol) {
+#ifdef SOAPYSDR
+ case SOAPYSDR_PROTOCOL:
+ soapy_protocol_set_tx_frequency(transmitter);
+ //soapy_protocol_start_transmitter(transmitter);
+ break;
+#endif
+ }
} else {
// switch to rx
+ switch(protocol) {
+#ifdef SOAPYSDR
+ case SOAPYSDR_PROTOCOL:
+ //soapy_protocol_stop_transmitter(transmitter);
+ break;
+#endif
+ }
SetChannelState(transmitter->id,0,1);
tx_set_displaying(transmitter,0);
g_object_ref((gpointer)transmitter->panel);
// gtk_widget_hide(audio_waterfall);
// }
//#endif
- for(i=0;i<receivers;i++) {
- gtk_fixed_put(GTK_FIXED(fixed),receiver[i]->panel,receiver[i]->x,receiver[i]->y);
- SetChannelState(receiver[i]->id,1,0);
- set_displaying(receiver[i],1);
+ if(!duplex) {
+ for(i=0;i<receivers;i++) {
+ gtk_fixed_put(GTK_FIXED(fixed),receiver[i]->panel,receiver[i]->x,receiver[i]->y);
+ SetChannelState(receiver[i]->id,1,0);
+ set_displaying(receiver[i],1);
+ }
}
//#ifdef FREEDV
// if(active_receiver->freedv) {
}
void setMox(int state) {
+g_print("setMox: %d\n",state);
if(!can_transmit) return;
vox_cancel(); // remove time-out
if(mox!=state) {
schedule_high_priority();
schedule_receive_specific();
break;
-#ifdef SOAPYSDR
- case SOAPYSDR_PROTOCOL:
- if(transmitter!=NULL) {
- if(mox) {
- soapy_protocol_set_tx_frequency(transmitter);
- soapy_protocol_start_transmitter(transmitter);
- } else {
- soapy_protocol_stop_transmitter(transmitter);
- }
- }
- break;
-#endif
default:
break;
}
//schedule_general();
}
if(state) {
- for(i=0;i<receivers;i++) {
- // Delivery of RX samples
- // to WDSP via fexchange0() may come to an abrupt stop
- // (especially with PURESIGNAL or DIVERSITY)
- // Therefore, wait for *all* receivers to complete
- // their slew-down before going TX.
- SetChannelState(receiver[i]->id,0,1);
- set_displaying(receiver[i],0);
- if(protocol==NEW_PROTOCOL) {
- schedule_high_priority();
+ if(!duplex) {
+ for(i=0;i<receivers;i++) {
+ // Delivery of RX samples
+ // to WDSP via fexchange0() may come to an abrupt stop
+ // (especially with PURESIGNAL or DIVERSITY)
+ // Therefore, wait for *all* receivers to complete
+ // their slew-down before going TX.
+ SetChannelState(receiver[i]->id,0,1);
+ set_displaying(receiver[i],0);
+ if(protocol==NEW_PROTOCOL) {
+ schedule_high_priority();
+ }
}
}
void setDrive(double value) {
transmitter->drive=value;
- calcDriveLevel();
+ switch(protocol) {
+ case ORIGINAL_PROTOCOL:
+ case NEW_PROTOCOL:
+ calcDriveLevel();
+ break;
+#ifdef SOAPYSDR
+ case SOAPYSDR_PROTOCOL:
+ soapy_protocol_set_tx_gain(transmitter,transmitter->drive);
+
+ break;
+#endif
+ }
}
double getTuneDrive() {
value=getProperty("rx2_gain_slider");
if(value) rx_gain_slider[1]=atoi(value);
+ value=getProperty("split");
+ if(value) split=atoi(value);
+ value=getProperty("duplex");
+ if(value) duplex=atoi(value);
+ value=getProperty("sat_mode");
+ if(value) sat_mode=atoi(value);
+
#ifdef SOAPYSDR
if(radio->device==SOAPYSDR_USB_DEVICE) {
for(int i=0;i<radio->info.soapy.rx_gains;i++) {
value=getProperty("radio.adc[0].antenna");
if(value!=NULL) adc[0].antenna=atoi(value);
+ value=getProperty("radio.dac[0].antenna");
+ if(value!=NULL) dac[0].antenna=atoi(value);
for(int i=0;i<radio->info.soapy.tx_gains;i++) {
sprintf(name,"radio.dac[0].tx_gain.%s",radio->info.soapy.tx_gain[i]);
value=getProperty(name);
sprintf(value,"%d", adc[0].antenna);
setProperty(name,value);
+ sprintf(name,"radio.dac[0].antenna");
+ sprintf(value,"%d", dac[0].antenna);
+ setProperty(name,value);
+
for(int i=0;i<radio->info.soapy.tx_gains;i++) {
sprintf(name,"radio.dac[0].tx_gain.%s",radio->info.soapy.tx_gain[i]);
sprintf(value,"%d", dac[0].tx_gain[i]);
sprintf(value,"%d", adc[1].antenna);
setProperty(name,value);
+ sprintf(name,"radio.dac[1].antenna");
+ sprintf(value,"%d", dac[1].antenna);
+ setProperty(name,value);
+
for(int i=0;i<radio->info.soapy.tx_gains;i++) {
sprintf(name,"radio.dac[1].tx_gain.%s",radio->info.soapy.tx_gain[i]);
sprintf(value,"%d", dac[1].tx_gain[i]);
if(can_transmit) {
transmitter_save_state(transmitter);
}
+
+ sprintf(value,"%d",duplex);
+ setProperty("duplex",value);
+ sprintf(value,"%d",split);
+ setProperty("split",value);
+ sprintf(value,"%d",sat_mode);
+ setProperty("sat_mode",value);
+
#ifdef FREEDV
freedv_save_state();
#endif
extern DISCOVERED *radio;
+extern GtkWidget *fixed;
+
extern char property_path[];
#define NONE 0
#define KEYER_MODE_A 1
#define KEYER_MODE_B 2
+enum {
+ SAT_NONE,
+ SAT_MODE,
+ RSAT_MODE
+};
+
+extern gint sat_mode;
+
extern int echo;
extern int radio_sample_rate;
int locked;
extern long long step;
-//extern int rit;
extern int rit_increment;
+extern gboolean duplex;
+
extern int lt2208Dither;
extern int lt2208Random;
extern int attenuation;
extern int can_transmit;
+extern void radio_stop();
extern void reconfigure_radio();
extern void start_radio();
//extern void init_radio();
#include "soapy_protocol.h"
#endif
#include "gpio.h"
+#include "vfo.h"
static GtkWidget *parent_window=NULL;
-
static GtkWidget *menu_b=NULL;
-
static GtkWidget *dialog=NULL;
+static GtkWidget *rx_gains[3];
+static GtkWidget *tx_gains[2];
+static GtkWidget *sat_b;
+static GtkWidget *rsat_b;
static void cleanup() {
if(dialog!=NULL) {
}
#ifdef SOAPYSDR
+static void rf_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
+ ADC *adc=(ADC *)data;
+ active_receiver->rf_gain=gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget));
+
+ if(radio->device==SOAPYSDR_USB_DEVICE) {
+ soapy_protocol_set_gain(receiver[0],active_receiver->rf_gain);
+ }
+
+ for(int i=0;i<radio->info.soapy.rx_gains;i++) {
+ int value=soapy_protocol_get_gain_element(active_receiver,radio->info.soapy.rx_gain[i]);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(rx_gains[i]),(double)value);
+ }
+}
+
static void rx_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
ADC *adc=(ADC *)data;
int gain;
if(radio->device==SOAPYSDR_USB_DEVICE) {
gain=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
- soapy_protocol_set_gain(receiver[0],(char *)gtk_widget_get_name(widget),gain);
+ soapy_protocol_set_gain_element(receiver[0],(char *)gtk_widget_get_name(widget),gain);
+
for(int i=0;i<radio->info.soapy.rx_gains;i++) {
if(strcmp(radio->info.soapy.rx_gain[i],(char *)gtk_widget_get_name(widget))==0) {
adc[0].rx_gain[i]=gain;
break;
}
}
+
+ }
+}
+
+static void drive_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
+ DAC *dac=(DAC *)data;
+ int gain;
+ if(radio->device==SOAPYSDR_USB_DEVICE) {
+ gain=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
+ soapy_protocol_set_tx_gain(transmitter,(double)gain);
+ for(int i=0;i<radio->info.soapy.tx_gains;i++) {
+ int value=soapy_protocol_get_tx_gain_element(transmitter,radio->info.soapy.tx_gain[i]);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(tx_gains[i]),(double)value);
+ }
}
}
int gain;
if(radio->device==SOAPYSDR_USB_DEVICE) {
gain=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
- soapy_protocol_set_tx_gain(transmitter,(char *)gtk_widget_get_name(widget),gain);
+ soapy_protocol_set_tx_gain_element(transmitter,(char *)gtk_widget_get_name(widget),gain);
for(int i=0;i<radio->info.soapy.tx_gains;i++) {
if(strcmp(radio->info.soapy.tx_gain[i],(char *)gtk_widget_get_name(widget))==0) {
dac[0].tx_gain[i]=gain;
int gain;
if(radio->device==SOAPYSDR_USB_DEVICE) {
gain=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
- soapy_protocol_set_tx_gain(radio->transmitter,(char *)gtk_widget_get_name(widget),gain);
+ soapy_protocol_set_tx_gain_element(radio->transmitter,(char *)gtk_widget_get_name(widget),gain);
for(int i=0;i<radio->discovered->info.soapy.tx_gains;i++) {
if(strcmp(radio->discovered->info.soapy.tx_gain[i],(char *)gtk_widget_get_name(widget))==0) {
radio->dac[0].tx_gain[i]=gain;
iqswap=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
}
+static void split_cb(GtkWidget *widget, gpointer data) {
+ split=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+ vfo_update();
+}
+
+static void duplex_cb(GtkWidget *widget, gpointer data) {
+ duplex=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+ vfo_update();
+}
+
+static void sat_cb(GtkWidget *widget, gpointer data) {
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rsat_b), FALSE);
+ sat_mode=SAT_MODE;
+ } else {
+ sat_mode=SAT_NONE;
+ }
+ vfo_update();
+}
+
+static void rsat_cb(GtkWidget *widget, gpointer data) {
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sat_b), FALSE);
+ sat_mode=RSAT_MODE;
+ } else {
+ sat_mode=SAT_NONE;
+ }
+ vfo_update();
+}
static void load_filters(void) {
if(protocol==NEW_PROTOCOL) {
gtk_grid_attach(GTK_GRID(grid),region_combo,col,row,1,1);
g_signal_connect(region_combo,"changed",G_CALLBACK(region_cb),NULL);
+ col++;
+
row++;
col=0;
row=1;
- GtkWidget *rit_label=gtk_label_new("RIT step (Hz): ");
+ GtkWidget *rit_label=gtk_label_new("R/XIT step (Hz): ");
gtk_grid_attach(GTK_GRID(grid),rit_label,col,row,1,1);
row++;
if(row>temp_row) temp_row=row;
}
-#ifdef SOAPYSDR
row=temp_row;
col=0;
+
+ GtkWidget *split_b=gtk_check_button_new_with_label("Split");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (split_b), split);
+ gtk_grid_attach(GTK_GRID(grid),split_b,col,row,1,1);
+ g_signal_connect(split_b,"toggled",G_CALLBACK(split_cb),NULL);
+
+ col++;
+
+ GtkWidget *duplex_b=gtk_check_button_new_with_label("Duplex");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (duplex_b), duplex);
+ gtk_grid_attach(GTK_GRID(grid),duplex_b,col,row,1,1);
+ g_signal_connect(duplex_b,"toggled",G_CALLBACK(duplex_cb),NULL);
+
+ col++;
+
+ sat_b=gtk_check_button_new_with_label("SAT");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sat_b), sat_mode==SAT_MODE);
+ gtk_grid_attach(GTK_GRID(grid),sat_b,col,row,1,1);
+ g_signal_connect(sat_b,"toggled",G_CALLBACK(sat_cb),NULL);
+
+ col++;
+
+ rsat_b=gtk_check_button_new_with_label("RSAT");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rsat_b), sat_mode==RSAT_MODE);
+ gtk_grid_attach(GTK_GRID(grid),rsat_b,col,row,1,1);
+ g_signal_connect(rsat_b,"toggled",G_CALLBACK(rsat_cb),NULL);
+
+ row++;
+ if(row>temp_row) temp_row=row;
+
+#ifdef SOAPYSDR
+ col=0;
if(radio->device==SOAPYSDR_USB_DEVICE) {
int i;
if(radio->info.soapy.rx_gains>0) {
}
+ //rx_gains=g_new(GtkWidget*,radio->info.soapy.rx_gains);
for(i=0;i<radio->info.soapy.rx_gains;i++) {
col=0;
GtkWidget *rx_gain_label=gtk_label_new(radio->info.soapy.rx_gain[i]);
if(range.step==0.0) {
range.step=1.0;
}
- GtkWidget *rx_gain_b=gtk_spin_button_new_with_range(range.minimum,range.maximum,range.step);
- gtk_widget_set_name (rx_gain_b, radio->info.soapy.rx_gain[i]);
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(rx_gain_b),(double)adc[0].rx_gain[i]);
- gtk_grid_attach(GTK_GRID(grid),rx_gain_b,col,row,1,1);
- g_signal_connect(rx_gain_b,"value_changed",G_CALLBACK(rx_gain_value_changed_cb),&adc[0]);
- col++;
+ rx_gains[i]=gtk_spin_button_new_with_range(range.minimum,range.maximum,range.step);
+ gtk_widget_set_name (rx_gains[i], radio->info.soapy.rx_gain[i]);
+ int value=soapy_protocol_get_gain_element(active_receiver,radio->info.soapy.rx_gain[i]);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(rx_gains[i]),(double)value);
+ //gtk_spin_button_set_value(GTK_SPIN_BUTTON(rx_gains[i]),(double)adc[0].rx_gain[i]);
+ gtk_grid_attach(GTK_GRID(grid),rx_gains[i],col,row,1,1);
+ g_signal_connect(rx_gains[i],"value_changed",G_CALLBACK(rx_gain_value_changed_cb),&adc[0]);
+
+ gtk_widget_set_sensitive(rx_gains[i], FALSE);
+
row++;
}
+ // used single gain control - LimeSDR works out best setting for the 3 rx gains
+ col=0;
+ GtkWidget *rf_gain_label=gtk_label_new("RF Gain");
+ gtk_grid_attach(GTK_GRID(grid),rf_gain_label,col,row,1,1);
+ col++;
+ GtkWidget *rf_gain_b=gtk_spin_button_new_with_range(0.0,60.0,1.0);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(rf_gain_b),active_receiver->rf_gain);
+ gtk_grid_attach(GTK_GRID(grid),rf_gain_b,col,row,1,1);
+ g_signal_connect(rf_gain_b,"value_changed",G_CALLBACK(rf_gain_value_changed_cb),&adc[0]);
+ col++;
+ row++;
+
row=temp_row;
if(can_transmit) {
+ //tx_gains=g_new(GtkWidget*,radio->info.soapy.tx_gains);
for(i=0;i<radio->info.soapy.tx_gains;i++) {
col=2;
GtkWidget *tx_gain_label=gtk_label_new(radio->info.soapy.tx_gain[i]);
if(range.step==0.0) {
range.step=1.0;
}
- GtkWidget *tx_gain_b=gtk_spin_button_new_with_range(range.minimum,range.maximum,range.step);
- gtk_widget_set_name (tx_gain_b, radio->info.soapy.tx_gain[i]);
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(tx_gain_b),(double)dac[0].tx_gain[i]);
- gtk_grid_attach(GTK_GRID(grid),tx_gain_b,col,row,1,1);
- g_signal_connect(tx_gain_b,"value_changed",G_CALLBACK(tx_gain_value_changed_cb),&dac[0]);
+ tx_gains[i]=gtk_spin_button_new_with_range(range.minimum,range.maximum,range.step);
+ gtk_widget_set_name (tx_gains[i], radio->info.soapy.tx_gain[i]);
+ int value=soapy_protocol_get_tx_gain_element(transmitter,radio->info.soapy.tx_gain[i]);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(tx_gains[i]),(double)value);
+ //gtk_spin_button_set_value(GTK_SPIN_BUTTON(tx_gains[i]),(double)dac[0].tx_gain[i]);
+ gtk_grid_attach(GTK_GRID(grid),tx_gains[i],col,row,1,1);
+ g_signal_connect(tx_gains[i],"value_changed",G_CALLBACK(tx_gain_value_changed_cb),&dac[0]);
+
+ gtk_widget_set_sensitive(tx_gains[i], FALSE);
+
row++;
}
- }
+ // used single gain control - LimeSDR works out best setting for the 3 rx gains
+ col=2;
+ GtkWidget *tx_gain_label=gtk_label_new("TX Gain");
+ gtk_grid_attach(GTK_GRID(grid),tx_gain_label,col,row,1,1);
+ col++;
+ tx_gains[i]=gtk_spin_button_new_with_range(0.0,100.0,1.0);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(tx_gains[i]),transmitter->drive);
+ gtk_grid_attach(GTK_GRID(grid),tx_gains[i],col,row,1,1);
+ g_signal_connect(tx_gains[i],"value_changed",G_CALLBACK(drive_gain_value_changed_cb),&adc[0]);
+ }
}
#endif
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));
+ vfo_move_to((long long)((float)x*rx->hz_per_pixel));
}
last_x=x;
pressed=FALSE;
&state);
// G0ORX: removed test as with it unable to drag screen
//if(state & GDK_BUTTON1_MASK) {
- int moved=last_x-x;
+ //int moved=last_x-x;
+ int moved=x-last_x;
vfo_move((long long)((float)moved*rx->hz_per_pixel));
last_x=x;
has_moved=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);
- }
+ vfo_move(step);
} else {
- if(vfo[active_receiver->id].ctun) {
- vfo_move(step);
- } else {
- vfo_move(-step);
- }
+ vfo_move(-step);
}
return TRUE;
}
sprintf(name,"receiver.%d.volume",rx->id);
sprintf(value,"%f",rx->volume);
setProperty(name,value);
+ sprintf(name,"receiver.%d.rf_gain",rx->id);
+ sprintf(value,"%f",rx->rf_gain);
+ setProperty(name,value);
sprintf(name,"receiver.%d.agc",rx->id);
sprintf(value,"%d",rx->agc);
setProperty(name,value);
sprintf(name,"receiver.%d.local_audio",rx->id);
sprintf(value,"%d",rx->local_audio);
setProperty(name,value);
+ if(rx->audio_name!=NULL) {
+ sprintf(name,"receiver.%d.audio_name",rx->id);
+ sprintf(value,"%s",rx->audio_name);
+ setProperty(name,value);
+ }
sprintf(name,"receiver.%d.mute_when_not_active",rx->id);
sprintf(value,"%d",rx->mute_when_not_active);
setProperty(name,value);
sprintf(name,"receiver.%d.volume",rx->id);
value=getProperty(name);
if(value) rx->volume=atof(value);
+ sprintf(name,"receiver.%d.rf_gain",rx->id);
+ value=getProperty(name);
+ if(value) rx->rf_gain=atof(value);
sprintf(name,"receiver.%d.agc",rx->id);
value=getProperty(name);
if(value) rx->agc=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_name",rx->id);
+ value=getProperty(name);
+ if(value) {
+ rx->audio_name=g_new(gchar,strlen(value)+1);
+ strcpy(rx->audio_name,value);
+ }
sprintf(name,"receiver.%d.mute_when_not_active",rx->id);
value=getProperty(name);
if(value) rx->mute_when_not_active=atoi(value);
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);
+ } else {
+ if(rx->update_timer_id!=-1) {
+ rx->update_timer_id=-1;
+ }
}
}
rx->panadapter_low=-140;
rx->panadapter_step=20;
- rx->volume=0.0;
+ rx->volume=5.0;
+ rx->rf_gain=50.0;
rx->squelch_enable=0;
rx->squelch=0;
rx->playback_handle=NULL;
rx->playback_buffer=NULL;
rx->local_audio=0;
+ rx->audio_name=NULL;
rx->mute_when_not_active=0;
rx->audio_channel=STEREO;
rx->audio_device=-1;
rx->fft_size=fft_size;
rx->pixels=pixels;
rx->fps=fps;
+ rx->update_timer_id=-1;
// rx->dds_offset=0;
rx->playback_handle=NULL;
rx->local_audio=0;
+ rx->audio_name=NULL;
rx->mute_when_not_active=0;
rx->audio_channel=STEREO;
rx->audio_device=-1;
short right_audio_sample;
int i;
for(i=0;i<rx->output_samples;i++) {
- if(isTransmitting()) {
+ if(isTransmitting() && !duplex) {
left_audio_sample=0;
right_audio_sample=0;
} else {
gint adc;
gdouble volume;
+ gdouble rf_gain;
+
gint agc;
gdouble agc_gain;
gdouble agc_slope;
gint local_audio;
gint mute_when_not_active;
gint audio_device;
+ gchar *audio_name;
#ifdef PORTAUDIO
PaStream *playback_handle;
gfloat *playback_buffer;
#include "new_protocol.h"
static GtkWidget *parent_window=NULL;
-
static GtkWidget *menu_b=NULL;
-
static GtkWidget *dialog=NULL;
+static GtkWidget *local_audio_b=NULL;
+static GtkWidget *output=NULL;
static void cleanup() {
if(dialog!=NULL) {
static void local_audio_cb(GtkWidget *widget, gpointer data) {
fprintf(stderr,"local_audio_cb: rx=%d\n",active_receiver->id);
+
+ if(active_receiver->audio_name==NULL) {
+ int i=gtk_combo_box_get_active(GTK_COMBO_BOX(output));
+ active_receiver->audio_name=g_new(gchar,strlen(output_devices[i].name)+1);
+ strcpy(active_receiver->audio_name,output_devices[i].name);
+ }
if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
if(audio_open_output(active_receiver)==0) {
active_receiver->local_audio=1;
// call audo_close_output with old device, audio_open_output with new one
//
static void local_output_changed_cb(GtkWidget *widget, gpointer data) {
- int newdev = (int)(long)data;
- fprintf(stderr,"local_output_changed rx=%d from %d to %d\n",active_receiver->id,active_receiver->audio_device,newdev);
+ int i = GPOINTER_TO_INT(data);
+ fprintf(stderr,"local_output_changed rx=%d %s\n",active_receiver->id,output_devices[i].name);
if(active_receiver->local_audio) {
audio_close_output(active_receiver); // audio_close with OLD device
- active_receiver->audio_device=newdev; // update rx to NEW device
- if(audio_open_output(active_receiver)==0) { // audio_open with NEW device
- active_receiver->local_audio=1;
- } else {
+ }
+
+ if(active_receiver->audio_name!=NULL) {
+ g_free(active_receiver->audio_name);
+ active_receiver->audio_name=NULL;
+ }
+
+ if(i>=0) {
+ active_receiver->audio_name=g_new(gchar,strlen(output_devices[i].name)+1);
+ strcpy(active_receiver->audio_name,output_devices[i].name);
+ //active_receiver->audio_device=output_devices[i].index; // update rx to NEW device
+ }
+
+ if(active_receiver->local_audio) {
+ if(audio_open_output(active_receiver)<0) { // audio_open with NEW device
active_receiver->local_audio=0;
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (local_audio_b),FALSE);
}
- fprintf(stderr,"local_output_changed rx=%d local_audio=%d\n",active_receiver->id,active_receiver->local_audio);
- } else {
- // If not (currently) using local audio, just change dev num
- active_receiver->audio_device=newdev;
}
+ fprintf(stderr,"local_output_changed rx=%d local_audio=%d\n",active_receiver->id,active_receiver->local_audio);
}
static void audio_channel_cb(GtkWidget *widget, gpointer data) {
int row=0;
if(n_output_devices>0) {
- GtkWidget *local_audio_b=gtk_check_button_new_with_label("Local Audio Output");
+ 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);
if(active_receiver->audio_device==-1) active_receiver->audio_device=0;
- GtkWidget *output=NULL;
+ output=NULL;
for(i=0;i<n_output_devices;i++) {
- 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);
+ output=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(output),output_devices[i].description);
+ if(active_receiver->audio_name!=NULL) {
+ if(strcmp(active_receiver->audio_name,output_devices[i].description)==0) {
+ gtk_combo_box_set_active(GTK_COMBO_BOX(output),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)(long)i);
+ g_signal_connect(output,"pressed",G_CALLBACK(local_output_changed_cb),GINT_TO_POINTER(i));
}
row=0;
samples[display_width-1]=-200.0;
s1=(double)samples[0]+(double)adc_attenuation[rx->adc];
if (filter_board == ALEX && rx->adc == 0) s1 += (double)(10*rx->alex_attenuation);
+#ifdef SOAPYSDR
+ if(protocol==SOAPYSDR_PROTOCOL) {
+ s1-=rx->rf_gain;
+ }
+#endif
s1 = floor((rx->panadapter_high - s1)
* (double) display_height
for(i=1;i<display_width;i++) {
s2=(double)samples[i]+(double)adc_attenuation[rx->adc];
if (filter_board == ALEX && rx->adc == 0) s2 += (double)(10*rx->alex_attenuation);
+#ifdef SOAPYSDR
+ if(protocol==SOAPYSDR_PROTOCOL) {
+ s2-=rx->rf_gain;
+ }
+#endif
s2 = floor((rx->panadapter_high - s2)
* (double) display_height
/ (rx->panadapter_high - rx->panadapter_low));
#include "band.h"
#include "discovered.h"
#include "new_protocol.h"
+#ifdef SOAPYSDR
+#include "soapy_protocol.h"
+#endif
#include "vfo.h"
#include "alex.h"
#include "agc.h"
#define NONE 0
#define AF_GAIN 1
-#define MIC_GAIN 2
-#define LINEIN_GAIN 3
-#define AGC_GAIN 4
-#define DRIVE 5
-#define ATTENUATION 6
-#define SQUELCH 7
-#define COMP 8
-#define FILTER_WIDTH 9
-#define DIVERSITY_GAIN 10
-#define DIVERSITY_PHASE 11
+#define RF_GAIN 2
+#define MIC_GAIN 3
+#define LINEIN_GAIN 4
+#define AGC_GAIN 5
+#define DRIVE 6
+#define ATTENUATION 7
+#define SQUELCH 8
+#define COMP 9
+#define FILTER_WIDTH 10
+#define DIVERSITY_GAIN 11
+#define DIVERSITY_PHASE 12
static gint scale_timer;
static int scale_status=NONE;
static GtkWidget *scale_dialog;
static GtkWidget *af_gain_label;
static GtkWidget *af_gain_scale;
+static GtkWidget *rf_gain_label;
+static GtkWidget *rf_gain_scale;
static GtkWidget *agc_gain_label;
static GtkWidget *agc_scale;
static GtkWidget *attenuation_label;
gtk_range_set_range(GTK_RANGE(mic_gain_scale),0.0,31.0);
gtk_range_set_value (GTK_RANGE(mic_gain_scale),linein_gain);
} else {
- gtk_label_set_text(GTK_LABEL(mic_gain_label),"Mic (dB):");
- gtk_range_set_range(GTK_RANGE(mic_gain_scale),-10.0,50.0);
+ gtk_label_set_text(GTK_LABEL(mic_gain_label),"Mic:");
+ gtk_range_set_range(GTK_RANGE(mic_gain_scale),-12.0,50.0);
gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_gain);
}
}
}
}
+static void rf_gain_value_changed_cb(GtkWidget *widget, gpointer data) {
+ active_receiver->rf_gain=gtk_range_get_value(GTK_RANGE(af_gain_scale));
+#ifdef SOAPYSDR
+ if(protocol=SOAPYSDR_PROTOCOL) {
+ soapy_protocol_set_gain(active_receiver,active_receiver->rf_gain);
+ }
+#endif
+}
+
+void update_rf_gain() {
+ set_rf_gain(active_receiver->id,active_receiver->rf_gain);
+}
+
+void set_rf_gain(int rx,double value) {
+ receiver[rx]->rf_gain=value;
+#ifdef SOAPYSDR
+ if(protocol==SOAPYSDR_PROTOCOL) {
+ soapy_protocol_set_gain(active_receiver,active_receiver->rf_gain);
+ }
+#endif
+ if(display_sliders) {
+ gtk_range_set_value (GTK_RANGE(rf_gain_scale),receiver[rx]->rf_gain);
+ } else {
+ if(scale_status!=RF_GAIN) {
+ if(scale_status!=NONE) {
+ g_source_remove(scale_timer);
+ gtk_widget_destroy(scale_dialog);
+ scale_status=NONE;
+ }
+ }
+ if(scale_status==NONE) {
+ scale_status=RF_GAIN;
+ scale_dialog=gtk_dialog_new_with_buttons("RF Gain",GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
+ GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog));
+ rf_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 100.0, 1.00);
+ gtk_widget_set_size_request (rf_gain_scale, 400, 30);
+ gtk_range_set_value (GTK_RANGE(rf_gain_scale),receiver[rx]->rf_gain);
+ gtk_widget_show(rf_gain_scale);
+ gtk_container_add(GTK_CONTAINER(content),rf_gain_scale);
+ scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL);
+ //gtk_widget_show_all(scale_dialog);
+ int result=gtk_dialog_run(GTK_DIALOG(scale_dialog));
+ } else {
+ g_source_remove(scale_timer);
+ gtk_range_set_value (GTK_RANGE(rf_gain_scale),receiver[rx]->rf_gain);
+ scale_timer=g_timeout_add(2000,scale_timeout_cb,NULL);
+ }
+ }
+}
+
void set_filter_width(int rx,int width) {
if(scale_status!=FILTER_WIDTH) {
if(scale_status!=NONE) {
linein_gain=(int)gtk_range_get_value(GTK_RANGE(widget));
} else {
mic_gain=gtk_range_get_value(GTK_RANGE(widget));
- double gain=pow(10.0, mic_gain / 20.0);
- SetTXAPanelGain1(transmitter->id,gain);
+ SetTXAPanelGain1(transmitter->id,pow(10.0, mic_gain/20.0));
}
}
void set_mic_gain(double value) {
if(can_transmit) {
mic_gain=value;
- double gain=pow(10.0, mic_gain / 20.0);
- SetTXAPanelGain1(transmitter->id,gain);
+ SetTXAPanelGain1(transmitter->id,pow(10.0, mic_gain/20.0));
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(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
+ scale_dialog=gtk_dialog_new_with_buttons("Mic Gain",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);
+ mic_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,-12.0, 50.0, 1.00);
gtk_widget_set_size_request (mic_gain_scale, 400, 30);
gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_gain);
gtk_widget_show(mic_gain_scale);
if(can_transmit) {
- mic_gain_label=gtk_label_new(mic_linein?"Linein:":"Mic (dB):");
+ mic_gain_label=gtk_label_new(mic_linein?"Linein:":"Mic:");
gtk_widget_override_font(mic_gain_label, pango_font_description_from_string("Sans 10"));
gtk_grid_attach(GTK_GRID(sliders),mic_gain_label,0,1,1,1);
- mic_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,mic_linein?0.0:-10.0,mic_linein?31.0:50.0, 1.0);
+ mic_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,mic_linein?0.0:1.0,mic_linein?31.0:100.0, 1.0);
gtk_widget_override_font(mic_gain_scale, pango_font_description_from_string("Sans 10"));
gtk_range_set_value (GTK_RANGE(mic_gain_scale),mic_linein?linein_gain:mic_gain);
gtk_grid_attach(GTK_GRID(sliders),mic_gain_scale,1,1,2,1);
extern void set_agc_gain(int rx,double value);
extern void set_af_gain(int rx,double value);
+extern void set_rf_gain(int rx,double value);
extern void set_mic_gain(double value);
extern void set_drive(double drive);
//extern void set_tune(double tune);
static SoapySDRStream *rx_stream;
static SoapySDRStream *tx_stream;
static int soapy_rx_sample_rate;
-static int soapy_tx_sample_rate;
static int max_samples;
static int samples=0;
void soapy_protocol_create_transmitter(TRANSMITTER *tx) {
int rc;
- soapy_tx_sample_rate=tx->iq_output_rate;
-fprintf(stderr,"soapy_protocol_create_transmitter: setting samplerate=%f\n",(double)soapy_tx_sample_rate);
- rc=SoapySDRDevice_setSampleRate(soapy_device,SOAPY_SDR_TX,tx->dac,(double)soapy_tx_sample_rate);
+fprintf(stderr,"soapy_protocol_create_transmitter: setting samplerate=%f\n",(double)tx->iq_output_rate);
+ rc=SoapySDRDevice_setSampleRate(soapy_device,SOAPY_SDR_TX,tx->dac,(double)tx->iq_output_rate);
if(rc!=0) {
- fprintf(stderr,"soapy_protocol_configure_transmitter: SoapySDRDevice_setSampleRate(%f) failed: %s\n",(double)soapy_tx_sample_rate,SoapySDR_errToStr(rc));
+ fprintf(stderr,"soapy_protocol_configure_transmitter: SoapySDRDevice_setSampleRate(%f) failed: %s\n",(double)tx->iq_output_rate,SoapySDR_errToStr(rc));
}
size_t channel=tx->dac;
//_exit(0);
}
-void soapy_protocol_process_local_mic(unsigned char *buffer,int le) {
- int b;
+void soapy_protocol_process_local_mic(float *buffer) {
int i;
short sample;
// always 48000 samples per second
- b=0;
for(i=0;i<720;i++) {
- if(le) {
- sample = (short) (buffer[b++]&0xFF);
- sample |= (short) (buffer[b++]<<8);
- } else {
- sample = (short)(buffer[b++]<<8);
- sample |= (short) (buffer[b++]&0xFF);
- }
+ sample=(short)(buffer[i]*32767.0);
#ifdef FREEDV
if(active_receiver->freedv) {
add_freedv_mic_sample(transmitter,sample);
int flags=0;
long long timeNs=0;
long timeoutUs=100000L;
- if(isTransmitting(radio)) {
+ if(isTransmitting()) {
output_buffer[output_buffer_index++]=isample;
output_buffer[output_buffer_index++]=qsample;
if(output_buffer_index>=max_tx_samples) {
// write the buffer
+//g_print("soapy_protocol_iq_samples: writeStream\n");
int elements=SoapySDRDevice_writeStream(soapy_device,tx_stream,tx_buffs,max_tx_samples,&flags,timeNs,timeoutUs);
if(elements!=max_tx_samples) {
g_print("soapy_protocol_iq_samples: writeStream returned %d for %d elements\n",elements,max_tx_samples);
}
void soapy_protocol_set_tx_frequency(TRANSMITTER *tx) {
- int v=active_receiver->id;
+ int v;
int rc;
double f;
+ v=active_receiver->id;
+ if(split) {
+ v=active_receiver->id==0?1:0;
+ }
if(soapy_device!=NULL) {
//f=(double)(vfo[v].frequency+vfo[v].ctun_frequency-vfo[v].lo_tx);
if(vfo[v].ctun) {
} else {
f=(double)(vfo[v].frequency-vfo[v].lo_tx);
}
+
+ if(transmitter->xit_enabled) {
+ f+=(double)(transmitter->xit);
+ }
+
+
g_print("soapy_protocol_set_tx_frequency: %f\n",f);
rc=SoapySDRDevice_setFrequency(soapy_device,SOAPY_SDR_TX,tx->dac,f,NULL);
if(rc!=0) {
}
}
-void soapy_protocol_set_gain(RECEIVER *rx,char *name,int gain) {
+void soapy_protocol_set_gain(RECEIVER *rx,double gain) {
+ int rc;
+//fprintf(stderr,"soapy_protocol_set_gain: adc=%d gain=%f\n",gain);
+ rc=SoapySDRDevice_setGain(soapy_device,SOAPY_SDR_RX,rx->adc,gain);
+ if(rc!=0) {
+ fprintf(stderr,"soapy_protocol: SoapySDRDevice_setGain failed: %s\n",SoapySDR_errToStr(rc));
+ }
+}
+
+void soapy_protocol_set_gain_element(RECEIVER *rx,char *name,int gain) {
int rc;
//fprintf(stderr,"soapy_protocol_set_gain: adc=%d %s=%d\n",rx->adc,name,gain);
rc=SoapySDRDevice_setGainElement(soapy_device,SOAPY_SDR_RX,rx->adc,name,(double)gain);
if(rc!=0) {
- fprintf(stderr,"soapy_protocol: SoapySDRDevice_setGain %s failed: %s\n",name,SoapySDR_errToStr(rc));
+ fprintf(stderr,"soapy_protocol: SoapySDRDevice_setGainElement %s failed: %s\n",name,SoapySDR_errToStr(rc));
+ }
+}
+
+void soapy_protocol_set_tx_gain(TRANSMITTER *tx,int gain) {
+ int rc;
+ rc=SoapySDRDevice_setGain(soapy_device,SOAPY_SDR_TX,tx->dac,(double)gain);
+ if(rc!=0) {
+ fprintf(stderr,"soapy_protocol: SoapySDRDevice_setGain failed: %s\n",SoapySDR_errToStr(rc));
}
}
-void soapy_protocol_set_tx_gain(TRANSMITTER *tx,char *name,int gain) {
+void soapy_protocol_set_tx_gain_element(TRANSMITTER *tx,char *name,int gain) {
int rc;
rc=SoapySDRDevice_setGainElement(soapy_device,SOAPY_SDR_TX,tx->dac,name,(double)gain);
if(rc!=0) {
- fprintf(stderr,"soapy_protocol: SoapySDRDevice_setGain %s failed: %s\n",name,SoapySDR_errToStr(rc));
+ fprintf(stderr,"soapy_protocol: SoapySDRDevice_setGainElement %s failed: %s\n",name,SoapySDR_errToStr(rc));
}
}
-int soapy_protocol_get_gain(RECEIVER *rx,char *name) {
+int soapy_protocol_get_gain_element(RECEIVER *rx,char *name) {
double gain;
gain=SoapySDRDevice_getGainElement(soapy_device,SOAPY_SDR_RX,rx->adc,name);
return (int)gain;
}
+int soapy_protocol_get_tx_gain_element(TRANSMITTER *tx,char *name) {
+ double gain;
+ gain=SoapySDRDevice_getGainElement(soapy_device,SOAPY_SDR_TX,tx->dac,name);
+ return (int)gain;
+}
+
gboolean soapy_protocol_get_automatic_gain(RECEIVER *rx) {
gboolean mode=SoapySDRDevice_getGainMode(soapy_device, SOAPY_SDR_RX, rx->adc);
return mode;
void soapy_protocol_set_rx_frequency(RECEIVER *rx,int v);
void soapy_protocol_set_rx_antenna(RECEIVER *rx,int ant);
void soapy_protocol_set_lna_gain(RECEIVER *rx,int gain);
-void soapy_protocol_set_gain(RECEIVER *rx,char *name,int gain);
-int soapy_protocol_get_gain(RECEIVER *rx,char *name);
+void soapy_protocol_set_gain(RECEIVER *rx,double gain);
+void soapy_protocol_set_gain_element(RECEIVER *rx,char *name,int gain);
+int soapy_protocol_get_gain_element(RECEIVER *rx,char *name);
void soapy_protocol_change_sample_rate(RECEIVER *rx,int rate);
gboolean soapy_protocol_get_automatic_gain(RECEIVER *rx);
void soapy_protocol_set_automatic_gain(RECEIVER *rx,gboolean mode);
void soapy_protocol_stop_transmitter(TRANSMITTER *tx);
void soapy_protocol_set_tx_frequency(TRANSMITTER *tx);
void soapy_protocol_set_tx_antenna(TRANSMITTER *tx,int ant);
-void soapy_protocol_set_tx_gain(TRANSMITTER *tx,char *name,int gain);
-void soapy_protocol_process_local_mic(unsigned char *buffer,int le);
+void soapy_protocol_set_tx_gain(TRANSMITTER *tx,int gain);
+void soapy_protocol_set_tx_gain_element(TRANSMITTER *tx,char *name,int gain);
+int soapy_protocol_get_tx_gain_element(TRANSMITTER *tx,char *name);
+void soapy_protocol_process_local_mic(float *buffer);
void soapy_protocol_iq_samples(float isample,float qsample);
void soapy_protocol_set_mic_sample_rate(int rate);
#endif
static gint rit_plus_timer=-1;
static gint rit_minus_timer=-1;
+static gint xit_plus_timer=-1;
+static gint xit_minus_timer=-1;
static gboolean rit_timer_cb(gpointer data) {
int i=GPOINTER_TO_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;
+ if(vfo[active_receiver->id].rit>10000) vfo[active_receiver->id].rit=10000;
+ if(vfo[active_receiver->id].rit<-10000) vfo[active_receiver->id].rit=-10000;
+ if(protocol==NEW_PROTOCOL) {
+ schedule_high_priority();
+ }
+ g_idle_add(ext_vfo_update,NULL);
+ return TRUE;
+}
+
+static gboolean xit_timer_cb(gpointer data) {
+ int i=GPOINTER_TO_INT(data);
+ transmitter->xit+=(i*rit_increment);
+ if(transmitter->xit>10000) transmitter->xit=10000;
+ if(transmitter->xit<-10000) transmitter->xit=-10000;
if(protocol==NEW_PROTOCOL) {
schedule_high_priority();
}
void update_toolbar_labels() {
switch(function) {
case 0:
- gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
+ if(can_transmit) {
+ gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
+ } else {
+ gtk_button_set_label(GTK_BUTTON(sim_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");
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");
+ if(can_transmit) {
+ gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
+ } else {
+ gtk_button_set_label(GTK_BUTTON(sim_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");
+ if(can_transmit) {
+ gtk_button_set_label(GTK_BUTTON(sim_s6),"Split");
+ } else {
+ gtk_button_set_label(GTK_BUTTON(sim_s6),"");
+ }
break;
case 2:
- gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
+ if(can_transmit) {
+ gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
+ } else {
+ gtk_button_set_label(GTK_BUTTON(sim_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_s3),"RIT");
-
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),"RIT CL");
- if(full_tune) {
- set_button_text_color(sim_s1,"red");
+ break;
+ case 3:
+ if(can_transmit) {
+ gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
+ } else {
+ gtk_button_set_label(GTK_BUTTON(sim_mox),"");
}
- if(memory_tune) {
- set_button_text_color(sim_s2,"red");
+ gtk_button_set_label(GTK_BUTTON(sim_s1),"Freq");
+ gtk_button_set_label(GTK_BUTTON(sim_s2),"Mem");
+ if(can_transmit) {
+ gtk_button_set_label(GTK_BUTTON(sim_s3),"XIT");
+ gtk_button_set_label(GTK_BUTTON(sim_s4),"XIT+");
+ gtk_button_set_label(GTK_BUTTON(sim_s5),"XIT-");
+ gtk_button_set_label(GTK_BUTTON(sim_s6),"XIT CL");
+ } else {
+ 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),"");
}
break;
- case 3:
- gtk_button_set_label(GTK_BUTTON(sim_mox),"Tune");
- if(OCtune!=0 && OCfull_tune_time!=0) {
- gtk_button_set_label(GTK_BUTTON(sim_s1),"Full");
+ case 4:
+ if(can_transmit) {
+ gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
} else {
+ gtk_button_set_label(GTK_BUTTON(sim_mox),"");
+ }
+ gtk_button_set_label(GTK_BUTTON(sim_s1),"Freq");
+ if(can_transmit) {
+ gtk_button_set_label(GTK_BUTTON(sim_s2),"Split");
+ gtk_button_set_label(GTK_BUTTON(sim_s3),"Duplex");
+ gtk_button_set_label(GTK_BUTTON(sim_s4),"SAT");
+ gtk_button_set_label(GTK_BUTTON(sim_s5),"RSAT");
+ } 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),"");
+ break;
+ case 5:
+ if(can_transmit) {
+ gtk_button_set_label(GTK_BUTTON(sim_mox),"Tune");
+ 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),"");
+ }
+ } else {
+ gtk_button_set_label(GTK_BUTTON(sim_mox),"");
gtk_button_set_label(GTK_BUTTON(sim_s1),"");
}
if(OCtune!=0 && OCmemory_tune_time!=0) {
gtk_button_set_label(GTK_BUTTON(sim_s3),"Band");
gtk_button_set_label(GTK_BUTTON(sim_s4),"Mode");
gtk_button_set_label(GTK_BUTTON(sim_s5),"Filter");
- gtk_button_set_label(GTK_BUTTON(sim_s6),"Mox");
+ if(can_transmit) {
+ gtk_button_set_label(GTK_BUTTON(sim_s6),"Mox");
+ } else {
+ gtk_button_set_label(GTK_BUTTON(sim_s6),"");
+ }
if(full_tune) {
set_button_text_color(sim_s1,"red");
}
}
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);
+ if(can_transmit) {
+ split=split==1?0:1;
+ if(split) {
+ tx_set_mode(transmitter,vfo[VFO_B].mode);
+ } else {
+ tx_set_mode(transmitter,vfo[VFO_A].mode);
+ }
+ g_idle_add(ext_vfo_update,NULL);
+ }
+}
+
+static void duplex_cb (GtkWidget *widget, gpointer data) {
+ if(can_transmit) {
+ duplex=duplex==1?0:1;
+ g_idle_add(ext_vfo_update,NULL);
+ }
+}
+
+static void sat_cb (GtkWidget *widget, gpointer data) {
+ if(can_transmit) {
+ if(sat_mode==SAT_MODE) {
+ sat_mode=SAT_NONE;
+ } else {
+ sat_mode=SAT_MODE;
+ }
+ g_idle_add(ext_vfo_update,NULL);
+ }
+}
+
+static void rsat_cb (GtkWidget *widget, gpointer data) {
+ if(can_transmit) {
+ if(sat_mode==RSAT_MODE) {
+ sat_mode=SAT_NONE;
+ } else {
+ sat_mode=RSAT_MODE;
+ }
+ g_idle_add(ext_vfo_update,NULL);
}
- g_idle_add(ext_vfo_update,NULL);
}
static void rit_enable_cb(GtkWidget *widget, gpointer data) {
static void rit_cb(GtkWidget *widget, gpointer data) {
int i=GPOINTER_TO_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;
+ if(vfo[active_receiver->id].rit>10000) vfo[active_receiver->id].rit=10000;
+ if(vfo[active_receiver->id].rit<-10000) vfo[active_receiver->id].rit=-10000;
if(protocol==NEW_PROTOCOL) {
schedule_high_priority();
}
g_idle_add(ext_vfo_update,NULL);
}
+static void xit_enable_cb(GtkWidget *widget, gpointer data) {
+ if(can_transmit) {
+ transmitter->xit_enabled=transmitter->xit_enabled==1?0:1;
+ if(protocol==NEW_PROTOCOL) {
+ schedule_high_priority();
+ }
+ g_idle_add(ext_vfo_update,NULL);
+ }
+}
+
+static void xit_cb(GtkWidget *widget, gpointer data) {
+ if(can_transmit) {
+ int i=GPOINTER_TO_INT(data);
+ transmitter->xit+=i*rit_increment;
+ if(transmitter->xit>10000) transmitter->xit=10000;
+ if(transmitter->xit<-10000) transmitter->xit=-10000;
+ if(protocol==NEW_PROTOCOL) {
+ schedule_high_priority();
+ }
+ g_idle_add(ext_vfo_update,NULL);
+ if(i<0) {
+ xit_minus_timer=g_timeout_add(200,xit_timer_cb,(gpointer)(long)i);
+ } else {
+ xit_plus_timer=g_timeout_add(200,xit_timer_cb,(gpointer)(long)i);
+ }
+ }
+}
+
+static void xit_clear_cb(GtkWidget *widget, gpointer data) {
+ if(can_transmit) {
+ transmitter->xit=0;
+ g_idle_add(ext_vfo_update,NULL);
+ }
+}
+
static void freq_cb(GtkWidget *widget, gpointer data) {
start_vfo();
}
freq_cb(widget,data);
break;
case 3:
+ freq_cb(widget,data);
+ break;
+ case 4:
+ freq_cb(widget,data);
+ break;
+ case 5:
full_tune=full_tune==1?0:1;
if(full_tune) {
set_button_text_color(sim_s2,"black");
break;
case 3:
break;
+ case 4:
+ break;
+ case 5:
+ break;
}
}
mem_cb(widget,data);
break;
case 3:
+ mem_cb(widget,data);
+ break;
+ case 4:
+ split_cb(widget,data);
+ break;
+ case 5:
memory_tune=memory_tune==1?0:1;
if(memory_tune) {
set_button_text_color(sim_s1,"black");
break;
case 3:
break;
+ case 4:
+ break;
+ case 5:
+ break;
}
}
atob_cb(widget,data);
break;
case 2:
- //vox_cb(widget,data);
rit_enable_cb(widget,data);
break;
case 3:
+ xit_enable_cb(widget,data);
+ break;
+ case 4:
+ duplex_cb(widget,data);
+ break;
+ case 5:
band_cb(widget,data);
break;
}
break;
case 3:
break;
+ case 4:
+ break;
+ case 5:
+ break;
}
}
}
break;
case 3:
+ if(xit_minus_timer==-1 && xit_plus_timer==-1) {
+ xit_cb(widget,(void *)1);
+ }
+ break;
+ case 4:
+ sat_cb(widget,data);
+ break;
+ case 5:
mode_cb(widget,data);
break;
}
}
break;
case 3:
+ if(xit_plus_timer!=-1) {
+ g_source_remove(xit_plus_timer);
+ xit_plus_timer=-1;
+ }
+ break;
+ case 4:
+ break;
+ case 5:
break;
}
}
}
break;
case 3:
+ if(xit_minus_timer==-1 && xit_plus_timer==-1) {
+ xit_cb(widget,(void *)-1);
+ }
+ break;
+ case 4:
+ rsat_cb(widget,data);
+ break;
+ case 5:
filter_cb(widget,data);
break;
}
}
break;
case 3:
+ if(xit_minus_timer!=-1) {
+ g_source_remove(xit_minus_timer);
+ xit_minus_timer=-1;
+ }
+ break;
+ case 4:
+ break;
+ case 5:
break;
}
}
rit_clear_cb(widget,NULL);
break;
case 3:
+ xit_clear_cb(widget,NULL);
+ break;
+ case 4:
+ break;
+ case 5:
break;
}
}
case 2:
break;
case 3:
- mox_cb((GtkWidget *)NULL, (gpointer)NULL);
+ break;
+ case 4:
+ break;
+ case 5:
break;
}
}
case 0:
case 1:
case 2:
+ case 3:
+ case 4:
mox_cb((GtkWidget *)NULL, (gpointer)NULL);
break;
- case 3:
+ case 5:
tune_cb((GtkWidget *)NULL, (gpointer)NULL);
break;
}
#ifndef _TOOLBAR_H
#define _TOOLBAR_H
-#define MAX_FUNCTION 3
+#define MAX_FUNCTION 5
extern int function;
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);
-
+ if(tx->microphone_name!=NULL) {
+ sprintf(name,"transmitter.%d.microphone_name",tx->id);
+ sprintf(value,"%s",tx->microphone_name);
+ setProperty(name,value);
+ }
sprintf(name,"transmitter.%d.low_latency",tx->id);
sprintf(value,"%d",tx->low_latency);
setProperty(name,value);
sprintf(name,"transmitter.%d.compressor_level",tx->id);
sprintf(value,"%f",tx->compressor_level);
setProperty(name,value);
+ sprintf(name,"transmitter.%d.xit_enabled",tx->id);
+ sprintf(value,"%d",tx->xit_enabled);
+ setProperty(name,value);
+ sprintf(name,"transmitter.%d.xit",tx->id);
+ sprintf(value,"%lld",tx->xit);
+ setProperty(name,value);
}
void transmitter_restore_state(TRANSMITTER *tx) {
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);
+ sprintf(name,"transmitter.%d.microphone_name",tx->id);
value=getProperty(name);
- if(value) tx->input_device=atoi(value);
+ if(value) {
+ tx->microphone_name=g_new(gchar,strlen(value)+1);
+ strcpy(tx->microphone_name,value);
+ }
sprintf(name,"transmitter.%d.low_latency",tx->id);
value=getProperty(name);
if(value) tx->low_latency=atoi(value);
sprintf(name,"transmitter.%d.compressor_level",tx->id);
value=getProperty(name);
if(value) tx->compressor_level=atof(value);
+ sprintf(name,"transmitter.%d.xit_enabled",tx->id);
+ value=getProperty(name);
+ if(value) tx->xit_enabled=atoi(value);
+ sprintf(name,"transmitter.%d.xit",tx->id);
+ value=getProperty(name);
+ if(value) tx->xit=atoll(value);
}
static gboolean update_display(gpointer data) {
tx->mic_sample_rate=48000;
tx->mic_dsp_rate=96000;
tx->iq_output_rate=radio_sample_rate;
- tx->buffer_size=1024;
- tx->output_samples=1024*(tx->iq_output_rate/tx->mic_sample_rate);
- tx->pixels=width*8; // to allow 384k to 24k conversion
+ tx->output_samples=tx->buffer_size*(tx->iq_output_rate/tx->mic_sample_rate);
+ tx->pixels=width*(tx->iq_output_rate/tx->mic_sample_rate);
+/*
+ tx->mic_sample_rate=48000;
+ tx->mic_dsp_rate=48000;
+ tx->iq_output_rate=48000;
+ tx->output_samples=tx->buffer_size;
+ tx->pixels=width; // to allow 48k to 24k conversion
+*/
break;
#endif
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);
+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 width=%d height=%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->width,tx->height);
tx->filter_low=tx_filter_low;
tx->filter_high=tx_filter_high;
tx->compressor_level=0.0;
tx->local_microphone=0;
+ tx->microphone_name=NULL;
+
+ tx->xit_enabled=FALSE;
+ tx->xit=0LL;
transmitter_restore_state(tx);
SetTXAPostGenToneFreq(tx->id, 0.0);
SetTXAPostGenRun(tx->id, 0);
- double gain=pow(10.0, mic_gain / 20.0);
- SetTXAPanelGain1(tx->id,gain);
+ SetTXAPanelGain1(tx->id,pow(10.0, mic_gain/20.0));
SetTXAPanelRun(tx->id, 1);
SetTXAFMDeviation(tx->id, (double)tx->deviation);
} else {
mode=vfo[0].mode;
}
-//fprintf(stderr,"tx_set_filter: tx=%p mode=%d low=%d high=%d\n",tx,mode,low,high);
+
+fprintf(stderr,"tx_set_filter: tx=%p mode=%s low=%d high=%d\n",tx,mode_string[mode],low,high);
+
switch(mode) {
case modeLSB:
case modeCWL:
double fl=tx->filter_low;
double fh=tx->filter_high;
+/*
if(split) {
fl+=vfo[VFO_B].offset;
fh+=vfo[VFO_B].offset;
fl+=vfo[VFO_A].offset;
fh+=vfo[VFO_A].offset;
}
+*/
SetTXABandpassFreqs(tx->id, fl,fh);
}
// Original code without pulse shaping and without side tone
//
for(j=0;j<tx->output_samples;j++) {
- double is=tx->iq_output_buffer[j*2];
- double qs=tx->iq_output_buffer[(j*2)+1];
+ double is,qs;
+ if(iqswap) {
+ qs=tx->iq_output_buffer[j*2];
+ qs=tx->iq_output_buffer[(j*2)+1];
+ } else {
+ is=tx->iq_output_buffer[j*2];
+ qs=tx->iq_output_buffer[(j*2)+1];
+ }
isample=is>=0.0?(long)floor(is*gain+0.5):(long)ceil(is*gain-0.5);
qsample=qs>=0.0?(long)floor(qs*gain+0.5):(long)ceil(qs*gain-0.5);
switch(protocol) {
break;
#ifdef SOAPYSDR
case SOAPYSDR_PROTOCOL:
- soapy_protocol_iq_samples((float)tx->iq_output_buffer[j*2],(float)tx->iq_output_buffer[(j*2)+1]);
+ soapy_protocol_iq_samples((float)isample,(float)qsample);
break;
#endif
}
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;
cairo_surface_t *panadapter_surface;
int local_microphone;
- int input_device;
+ gchar *microphone_name;
int out_of_band;
gint out_of_band_timer_id;
double rev;
double alc;
+ gint xit_enabled;
+ long long xit;
+
int x;
int y;
#include "ext.h"
static GtkWidget *parent_window=NULL;
-
static GtkWidget *dialog=NULL;
-
static GtkWidget *last_filter;
-
+static GtkWidget *input;
static GtkWidget *micin_b=NULL;
static GtkWidget *linein_b=NULL;
static GtkWidget *micboost_b=NULL;
static void local_microphone_cb(GtkWidget *widget, gpointer data) {
if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
+ if(transmitter->microphone_name==NULL) {
+ int i=gtk_combo_box_get_active(GTK_COMBO_BOX(input));
+ transmitter->microphone_name=g_new(gchar,strlen(input_devices[i].name)+1);
+ strcpy(transmitter->microphone_name,input_devices[i].name);
+ }
if(audio_open_input()==0) {
transmitter->local_microphone=1;
if(micin_b!=NULL) gtk_widget_hide(micin_b);
}
static void local_input_changed_cb(GtkWidget *widget, gpointer data) {
- transmitter->input_device=(int)(long)data;
+ int i=GPOINTER_TO_INT(data);
if(transmitter->local_microphone) {
audio_close_input();
- if(audio_open_input()==0) {
- transmitter->local_microphone=1;
- } else {
+ }
+
+ if(transmitter->microphone_name!=NULL) {
+ g_free(transmitter->microphone_name);
+ }
+
+ transmitter->microphone_name=g_new(gchar,strlen(input_devices[i].name)+1);
+ strcpy(transmitter->microphone_name,input_devices[i].name);
+
+ if(transmitter->local_microphone) {
+ if(audio_open_input()<0) {
transmitter->local_microphone=0;
}
}
row++;
col=0;
- GtkWidget *comp_enable=gtk_check_button_new_with_label("Compression (dB):");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (comp_enable), transmitter->compressor);
- gtk_grid_attach(GTK_GRID(grid),comp_enable,col,row,1,1);
- g_signal_connect(comp_enable,"toggled",G_CALLBACK(comp_enable_cb),NULL);
+ }
- col++;
- GtkWidget *comp=gtk_spin_button_new_with_range(0.0,20.0,1.0);
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(comp),(double)transmitter->compressor_level);
- gtk_grid_attach(GTK_GRID(grid),comp,col,row,1,1);
- g_signal_connect(comp,"value-changed",G_CALLBACK(comp_cb),NULL);
+ GtkWidget *comp_enable=gtk_check_button_new_with_label("Compression (dB):");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (comp_enable), transmitter->compressor);
+ gtk_grid_attach(GTK_GRID(grid),comp_enable,col,row,1,1);
+ g_signal_connect(comp_enable,"toggled",G_CALLBACK(comp_enable_cb),NULL);
- row++;
- col=0;
+ col++;
+
+ GtkWidget *comp=gtk_spin_button_new_with_range(0.0,20.0,1.0);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(comp),(double)transmitter->compressor_level);
+ gtk_grid_attach(GTK_GRID(grid),comp,col,row,1,1);
+ g_signal_connect(comp,"value-changed",G_CALLBACK(comp_cb),NULL);
+
+ row++;
+ col=0;
- }
if(n_input_devices>0) {
GtkWidget *local_microphone_b=gtk_check_button_new_with_label("Local Microphone Input");
gtk_grid_attach(GTK_GRID(grid),local_microphone_b,col,row++,2,1);
g_signal_connect(local_microphone_b,"toggled",G_CALLBACK(local_microphone_cb),NULL);
- if(transmitter->input_device==-1) {
- transmitter->input_device=0;
- }
-
- GtkWidget *input=NULL;
+ input=NULL;
for(i=0;i<n_input_devices;i++) {
- 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);
+ input=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(input),input_devices[i].description);
+ if(transmitter->microphone_name!=NULL) {
+ if(strcmp(transmitter->microphone_name,input_devices[i].description)==0) {
+ gtk_combo_box_set_active(GTK_COMBO_BOX(input),i);
+ }
+ }
gtk_widget_show(input);
gtk_grid_attach(GTK_GRID(grid),input,col,row++,2,1);
g_signal_connect(input,"pressed",G_CALLBACK(local_input_changed_cb),(gpointer)(long)i);
col++;
- GtkWidget *panadapter_low_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0);
+ GtkWidget *panadapter_low_r=gtk_spin_button_new_with_range(-400.0,100.0,1.0);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(panadapter_low_r),(double)transmitter->panadapter_low);
gtk_widget_show(panadapter_low_r);
gtk_grid_attach(GTK_GRID(grid),panadapter_low_r,col,row,1,1);
int display_width=gtk_widget_get_allocated_width (tx->panadapter);
int display_height=gtk_widget_get_allocated_height (tx->panadapter);
+g_print("tx_panadapter_configure_event_cb: width=%d height=%d\n",display_width,display_height);
if (tx->panadapter_surface)
cairo_surface_destroy (tx->panadapter_surface);
//long long half=12000LL; //(long long)(tx->output_rate/2);
long long half=24000LL; //(long long)(tx->output_rate/2);
long long frequency;
- frequency=vfo[id].frequency+vfo[id].offset;
+ //frequency=vfo[id].frequency+vfo[id].offset;
+ if(vfo[id].ctun) {
+ frequency=vfo[id].ctun_frequency-vfo[id].lo_tx;
+ } else {
+ frequency=vfo[id].frequency-vfo[id].lo_tx;
+ }
double vfofreq=(double)display_width * 0.5;
if (!cw_is_on_vfo_freq) {
if(vfo[id].mode==modeCWU) {
cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
cairo_set_line_width(cr, 1.0);
//fprintf(stderr,"cursor: x=%f\n",(double)(display_width/2.0)+(vfo[tx->id].offset/hz_per_pixel));
- cairo_move_to(cr,vfofreq+(vfo[id].offset/hz_per_pixel),0.0);
- cairo_line_to(cr,vfofreq+(vfo[id].offset/hz_per_pixel),(double)display_height);
+ //cairo_move_to(cr,vfofreq+(vfo[id].offset/hz_per_pixel),0.0);
+ //cairo_line_to(cr,vfofreq+(vfo[id].offset/hz_per_pixel),(double)display_height);
+ cairo_move_to(cr,vfofreq,0.0);
+ cairo_line_to(cr,vfofreq,(double)display_height);
cairo_stroke(cr);
// signal
switch(protocol) {
case ORIGINAL_PROTOCOL:
- //offset=(tx->pixels/4)*1;
offset=0;
break;
case NEW_PROTOCOL:
- //offset=(tx->pixels/16)*7;
offset=(tx->pixels/8)*3;
break;
+#ifdef SOAPYSDR
+ case SOAPYSDR_PROTOCOL:
+ offset=(tx->pixels/16)*7;
+ break;
+#endif
}
s1=(double)samples[0+offset];
char build_version[]=GIT_VERSION;
#if defined (CONTROLLER2_V1)
-char version[]="2.0.0 (Controller2 V1)";
+char version[]="2.0.1 (Controller2 V1)";
#elif defined (CONTROLLER2_V2)
-char version[]="2.0.0 (Controller2 V2)";
+char version[]="2.0.1 (Controller2 V2)";
#elif defined (GPIO)
-char version[]="2.0.0 (Controller1)";
+char version[]="2.0.1 (Controller1)";
#else
-char version[]="2.0.0";
+char version[]="2.0.1";
#endif
vfo[id].lo=band->frequencyLO+band->errorLO;
vfo[id].lo_tx=band->txFrequencyLO+band->txErrorLO;
+ // turn off ctun
+ vfo[id].ctun=0;
switch(id) {
case 0:
} else {
vfo[id].frequency=vfo[id].frequency+(steps*step);
}
+
+ int sid=id==0?1:0;
+ switch(sat_mode) {
+ case SAT_NONE:
+ break;
+ case SAT_MODE:
+ // A and B increment and decrement together
+ if(vfo[sid].ctun) {
+ vfo[sid].ctun_frequency=vfo[sid].ctun_frequency+(steps*step);
+ } else {
+ vfo[sid].frequency=vfo[sid].frequency+(steps*step);
+ }
+ break;
+ case RSAT_MODE:
+ // A increments and B decrements or A decrments and B increments
+ if(vfo[sid].ctun) {
+ vfo[sid].ctun_frequency=vfo[sid].ctun_frequency-(steps*step);
+ } else {
+ vfo[sid].frequency=vfo[sid].frequency-(steps*step);
+ }
+ break;
+ }
+
receiver_frequency_changed(active_receiver);
#ifdef INCLUDED
BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
void vfo_move(long long hz) {
int id=active_receiver->id;
+g_print("vfo_move: id=%d hz=%lld\n",id,hz);
if(!locked) {
- switch(protocol) {
-/*
-#ifdef SOAPYSDR
- case SOAPYSDR_PROTOCOL:
- vfo[id].ctun_frequency=((vfo[id].ctun_frequency-hz)/step)*step;
+ if(vfo[id].ctun) {
+ vfo[id].ctun_frequency=((vfo[id].ctun_frequency+hz)/step)*step;
+ } else {
+ vfo[id].frequency=((vfo[id].frequency+hz)/step)*step;
+ }
+ int sid=id==0?1:0;
+ switch(sat_mode) {
+ case SAT_NONE:
break;
-#endif
-*/
- default:
- if(vfo[id].ctun) {
- vfo[id].ctun_frequency=((vfo[id].ctun_frequency-hz)/step)*step;
+ case SAT_MODE:
+ // A and B increment and decrement together
+ if(vfo[sid].ctun) {
+ vfo[sid].ctun_frequency=((vfo[sid].ctun_frequency+hz)/step)*step;
} else {
- vfo[id].frequency=((vfo[id].frequency+hz)/step)*step;
+ vfo[sid].frequency=((vfo[sid].frequency+hz)/step)*step;
+ }
+ break;
+ case RSAT_MODE:
+ // A increments and B decrements or A decrments and B increments
+ if(vfo[sid].ctun) {
+ vfo[sid].ctun_frequency=((vfo[sid].ctun_frequency-hz)/step)*step;
+ } else {
+ vfo[sid].frequency=((vfo[sid].frequency-hz)/step)*step;
}
break;
}
}
void vfo_move_to(long long hz) {
+ // hz is the offset from the min frequency
int id=active_receiver->id;
+ long long offset=(hz/step)*step;
+ long long half=(long long)(active_receiver->sample_rate/2);
+ long long f=vfo[id].frequency-half+offset;
+ long long diff;
+
+g_print("vfo_move_to: id=%d hz=%lld f=%lld\n",id,hz,f);
+
if(!locked) {
- switch(protocol) {
- default:
- if(vfo[id].ctun) {
- vfo[id].ctun_frequency=(vfo[id].frequency+hz)/step*step;
- if(vfo[id].mode==modeCWL) {
- vfo[id].ctun_frequency+=cw_keyer_sidetone_frequency;
- } else if(vfo[id].mode==modeCWU) {
- vfo[id].ctun_frequency-=cw_keyer_sidetone_frequency;
- }
+ if(vfo[id].ctun) {
+ diff=f-vfo[id].ctun_frequency;
+ vfo[id].ctun_frequency=f;
+ if(vfo[id].mode==modeCWL) {
+ vfo[id].ctun_frequency+=cw_keyer_sidetone_frequency;
+ } else if(vfo[id].mode==modeCWU) {
+ vfo[id].ctun_frequency-=cw_keyer_sidetone_frequency;
+ }
+g_print("vfo_move_to: vfo=%d ctun_frequency=%lld diff=%lld\n",id,vfo[id].ctun_frequency,diff);
+ } else {
+ diff=f-vfo[id].frequency;
+ vfo[id].frequency=f;
+ 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;
+ }
+g_print("vfo_move_to: vfo=%d frequency=%lld diff==%%ld\n",id,vfo[id].frequency,diff);
+ }
+
+ int sid=id==0?1:0;
+ switch(sat_mode) {
+ case SAT_NONE:
+ break;
+ case SAT_MODE:
+ f=vfo[sid].frequency-half+offset;
+ // A and B increment and decrement together
+ if(vfo[sid].ctun) {
+ vfo[sid].ctun_frequency+=diff;
+g_print("vfo_move_to: SAT vfo=%d ctun_frequency=%lld\n",sid,vfo[sid].ctun_frequency);
} else {
- 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;
- }
+ vfo[sid].frequency+=diff;
+g_print("vfo_move_to: SAT vfo=%d frequency=%lld\n",sid,vfo[sid].frequency);
+ }
+ break;
+ case RSAT_MODE:
+ f=vfo[sid].frequency+half-offset;
+ // A increments and B decrements or A decrements and B increments
+ if(vfo[sid].ctun) {
+ vfo[sid].ctun_frequency-=diff;
+g_print("vfo_move_to: RSAT vfo=%d ctun_frequency=%lld\n",sid,vfo[sid].ctun_frequency);
+ } else {
+ vfo[sid].frequency-=diff;
+g_print("vfo_move_to: RSAT vfo=%d frequency=%lld\n",sid,vfo[sid].frequency);
}
break;
}
+
receiver_vfo_changed(active_receiver);
#ifdef INCLUDED
// id == 1, split == 1 : TX freq = VFO_A
- long long af=vfo[0].frequency+vfo[0].offset;
+ long long af;
+ if(isTransmitting() && !split) {
+ if(vfo[0].ctun) {
+ af=(double)(vfo[0].ctun_frequency-vfo[0].lo_tx);
+ } else {
+ af=(double)(vfo[0].frequency-vfo[0].lo_tx);
+ }
+ } else {
+ if(vfo[0].ctun) {
+ af=(double)(vfo[0].ctun_frequency);
+ } else {
+ af=(double)(vfo[0].frequency);
+ }
+ }
+
sprintf(temp_text,"VFO A: %0lld.%06lld",af/(long long)1000000,af%(long long)1000000);
if(isTransmitting() && ((id == 0 && !split) || (id == 1 && split))) {
if (transmitter->out_of_band) sprintf(temp_text,"VFO A: Out of band");
cairo_show_text(cr, temp_text);
- long long bf=vfo[1].frequency+vfo[1].offset;
+ long long bf;
+ if(isTransmitting() && split) {
+ if(vfo[1].ctun) {
+ bf=(double)(vfo[1].ctun_frequency-vfo[1].lo_tx);
+ } else {
+ bf=(double)(vfo[1].frequency-vfo[1].lo_tx);
+ }
+ } else {
+ if(vfo[1].ctun) {
+ bf=(double)(vfo[1].ctun_frequency);
+ } else {
+ bf=(double)(vfo[1].frequency);
+ }
+ }
sprintf(temp_text,"VFO B: %0lld.%06lld",bf/(long long)1000000,bf%(long long)1000000);
if(isTransmitting() && ((id == 0 && split) || (id == 1 && !split))) {
if (transmitter->out_of_band) sprintf(temp_text,"VFO B: Out of band");
cairo_set_source_rgb(cr, 0.0, 0.65, 0.0);
}
}
- cairo_move_to(cr, 260, 38);
+ cairo_move_to(cr, 270, 38);
cairo_show_text(cr, temp_text);
+#ifdef PURESIGNAL
+ if(can_transmit) {
+ cairo_move_to(cr, 180, 15);
+ if(transmitter->puresignal) {
+ cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
+ } else {
+ cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
+ }
+ cairo_set_font_size(cr, 12);
+ cairo_show_text(cr, "PS");
+ }
+#endif
+
+
if(vfo[id].rit_enabled==0) {
cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
} else {
- cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
+ cairo_set_source_rgb(cr, 0.0, 1.0, 0.0);
}
- sprintf(temp_text,"RIT: %lld Hz",vfo[id].rit);
+ sprintf(temp_text,"RIT: %lldHz",vfo[id].rit);
cairo_move_to(cr, 210, 15);
cairo_set_font_size(cr, 12);
cairo_show_text(cr, temp_text);
+
+ if(can_transmit) {
+ if(transmitter->xit_enabled==0) {
+ cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
+ } else {
+ cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
+ }
+ sprintf(temp_text,"XIT: %lldHz",transmitter->xit);
+ cairo_move_to(cr, 310, 15);
+ cairo_set_font_size(cr, 12);
+ cairo_show_text(cr, temp_text);
+ }
+
// NB and NB2 are mutually exclusive, therefore
// they are put to the same place in order to save
// some space
- cairo_move_to(cr, 150, 50);
+ cairo_move_to(cr, 155, 50);
if(active_receiver->nb) {
cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
cairo_show_text(cr, "NB");
}
cairo_show_text(cr, "SNB");
- cairo_move_to(cr, 300, 50);
+ //cairo_move_to(cr, 300, 50);
+ cairo_move_to(cr, 270, 50);
switch(active_receiver->agc) {
case AGC_OFF:
cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
// we should display the compressor (level)
//
if(can_transmit) {
- cairo_move_to(cr, 400, 50);
+ //cairo_move_to(cr, 400, 50);
+ cairo_move_to(cr, 330, 50);
if (transmitter->compressor) {
sprintf(temp_text,"CMPR %d dB",(int) transmitter->compressor_level);
cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
s++;
}
sprintf(temp_text,"Step %s",step_labels[s]);
- cairo_move_to(cr, 300, 15);
+ //cairo_move_to(cr, 300, 15);
+ cairo_move_to(cr, 400, 15);
cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
cairo_show_text(cr, temp_text);
cairo_show_text(cr, getFrequencyInfo(af));
*/
- cairo_move_to(cr, 400, 15);
+ //cairo_move_to(cr, 400, 15);
+ cairo_move_to(cr, 430, 50);
if(vfo[id].ctun) {
cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
} else {
}
cairo_show_text(cr, "CTUN");
- cairo_move_to(cr, 450, 15);
+ //cairo_move_to(cr, 450, 15);
+ cairo_move_to(cr, 470, 50);
if(cat_control>0) {
cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
} else {
}
cairo_show_text(cr, "Split");
-#ifdef PURESIGNAL
- if(can_transmit) {
- cairo_move_to(cr, 105, 50);
- if(transmitter->puresignal) {
- cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
- } else {
- cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
- }
- cairo_show_text(cr, "PS");
+ cairo_move_to(cr, 95, 50);
+ if(sat_mode!=SAT_NONE) {
+ cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
+ } else {
+ cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
+ }
+ if(sat_mode==SAT_NONE || sat_mode==SAT_MODE) {
+ cairo_show_text(cr, "SAT");
+ } else {
+ cairo_show_text(cr, "RSAT");
}
-#endif
+ if(duplex) {
+ cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
+ } else {
+ cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
+ }
+ sprintf(temp_text,"DUP");
+ cairo_move_to(cr, 130, 50);
+ cairo_set_font_size(cr, 12);
+ cairo_show_text(cr, temp_text);
cairo_destroy (cr);
gtk_widget_queue_draw (vfo_panel);
int ctun;
long long ctun_frequency;
+
int rit_enabled;
long long rit;
#endif
#ifdef PURESIGNAL
- GtkWidget *enable_ps=gtk_check_button_new_with_label("Enable Pure Signal");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (enable_ps), transmitter->puresignal);
- gtk_grid_attach(GTK_GRID(grid),enable_ps,3,7,1,1);
- g_signal_connect(enable_ps,"toggled",G_CALLBACK(enable_ps_cb),NULL);
+ if(can_transmit) {
+ GtkWidget *enable_ps=gtk_check_button_new_with_label("Enable Pure Signal");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (enable_ps), transmitter->puresignal);
+ gtk_grid_attach(GTK_GRID(grid),enable_ps,3,7,1,1);
+ g_signal_connect(enable_ps,"toggled",G_CALLBACK(enable_ps_cb),NULL);
+ }
#endif
gtk_container_add(GTK_CONTAINER(content),grid);
int i;
RECEIVER *rx=active_receiver;
gboolean saved_ctun;
-g_print("update_receiver: band=%d error=%d\n",band,error);
+//g_print("update_receiver: band=%d error=%d\n",band,error);
if(vfo[0].band==band) {
BAND *xvtr=band_get_band(band);
-g_print("update_receiver: found band: %s\n",xvtr->title);
+//g_print("update_receiver: found band: %s\n",xvtr->title);
vfo[0].lo=xvtr->frequencyLO+xvtr->errorLO;
vfo[0].lo_tx=xvtr->txFrequencyLO+xvtr->txErrorLO;
saved_ctun=vfo[0].ctun;