From ad65044ed48265e5d67a75dbfe4b9d86a85b4b33 Mon Sep 17 00:00:00 2001 From: c vw Date: Thu, 9 Jan 2020 17:21:33 +0100 Subject: [PATCH] several fixes --- agc_menu.c | 3 +- alsa_midi.c | 1 + audio.c | 8 +-- cw_menu.c | 3 +- ext.c | 43 ++++++------ ext.h | 2 +- gpio.c | 2 +- i2c.c | 2 +- iambic.c | 7 +- midi3.c | 9 +-- new_protocol.c | 58 +++------------- old_protocol.c | 36 ++-------- pa_menu.c | 5 +- radio.c | 14 ++-- radio_menu.c | 11 +-- soapy_protocol.c | 5 +- toolbar.c | 10 +-- transmitter.c | 17 ++--- tx_panadapter.c | 22 +++--- vfo.c | 172 ++++++++++++++++++++++------------------------- vfo.h | 4 ++ 21 files changed, 169 insertions(+), 265 deletions(-) diff --git a/agc_menu.c b/agc_menu.c index fd807ac..bf8ec11 100644 --- a/agc_menu.c +++ b/agc_menu.c @@ -32,6 +32,7 @@ #include "receiver.h" #include "vfo.h" #include "button_text.h" +#include "ext.h" static GtkWidget *parent_window=NULL; @@ -59,7 +60,7 @@ static void agc_select_cb (GtkToggleButton *widget, gpointer data) { if(gtk_toggle_button_get_active(widget)) { active_receiver->agc=GPOINTER_TO_INT(data); set_agc(active_receiver, active_receiver->agc); - vfo_update(); + g_idle_add(ext_vfo_update, NULL); } } diff --git a/alsa_midi.c b/alsa_midi.c index 4c183a5..89dc8e5 100644 --- a/alsa_midi.c +++ b/alsa_midi.c @@ -233,6 +233,7 @@ void register_midi_device(char *myname) { } if (!found) { fprintf(stderr,"MIDI device %s NOT FOUND!\n", myname); + return; } // Found our MIDI input device. Spawn off a thread reading data ret = pthread_create(&midi_thread_id, NULL, midi_thread, NULL); diff --git a/audio.c b/audio.c index 30ad173..0a3664e 100644 --- a/audio.c +++ b/audio.c @@ -398,15 +398,11 @@ int audio_write(RECEIVER *rx,float left_sample,float right_sample) { snd_pcm_sframes_t delay; long rc; long trim; - int mode=modeUSB; + int txmode=get_tx_mode(); float *float_buffer; gint32 *long_buffer; gint16 *short_buffer; - if(can_transmit) { - mode=transmitter->mode; - } - // // We have to stop the stream here if a CW side tone may occur. // This might cause underflows, but we cannot use audio_write @@ -416,7 +412,7 @@ int audio_write(RECEIVER *rx,float left_sample,float right_sample) { // to listen to this rx while transmitting. // - if (rx == active_receiver && isTransmitting() && (mode==modeCWU || mode==modeCWL)) { + if (rx == active_receiver && isTransmitting() && (txmode==modeCWU || txmode==modeCWL)) { return 0; } diff --git a/cw_menu.c b/cw_menu.c index 2f6e076..07ce115 100644 --- a/cw_menu.c +++ b/cw_menu.c @@ -124,7 +124,8 @@ static void cw_keyer_sidetone_level_value_changed_cb(GtkWidget *widget, gpointer 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(transmitter->mode==modeCWL || transmitter->mode==modeCWU) { + int txmode=get_tx_mode(); + if(txmode==modeCWL || txmode==modeCWU) { BANDSTACK_ENTRY *entry=bandstack_entry_get_current(); FILTER* band_filters=filters[entry->mode]; FILTER* band_filter=&band_filters[entry->filter]; diff --git a/ext.c b/ext.c index 57a3e25..7c8a5cb 100644 --- a/ext.c +++ b/ext.c @@ -82,6 +82,10 @@ static int vfo_timeout_cb(void * data) { return 0; } +// +// ALL calls to vfo_update should go through g_idle_add(ext_vfo_update) +// such that they can be filtered out if they come at high rate +// int ext_vfo_update(void *data) { if (vfo_timeout ==0) { vfo_timeout=g_timeout_add(100, vfo_timeout_cb, NULL); @@ -207,16 +211,15 @@ int ext_update_vfo_step(void *data) { i++; if(steps[i]!=0) { step=steps[i]; - vfo_update(); } } else { i--; if(i>=0) { step=steps[i]; - vfo_update(); } } } + g_idle_add(ext_vfo_update, NULL); return 0; } @@ -337,7 +340,7 @@ int ext_nr_update(void *data) { } SetRXAANRRun(active_receiver->id, active_receiver->nr); SetRXAEMNRRun(active_receiver->id, active_receiver->nr2); - vfo_update(); + g_idle_add(ext_vfo_update, NULL); return 0; } @@ -360,7 +363,7 @@ int ext_nb_update(void *data) { } SetEXTANBRun(active_receiver->id, active_receiver->nb); SetEXTNOBRun(active_receiver->id, active_receiver->nb2); - vfo_update(); + g_idle_add(ext_vfo_update, NULL); return 0; } @@ -373,7 +376,7 @@ int ext_snb_update(void *data) { mode_settings[vfo[active_receiver->id].mode].snb=0; } SetRXASNBARun(active_receiver->id, active_receiver->snb); - vfo_update(); + g_idle_add(ext_vfo_update, NULL); return 0; } @@ -448,21 +451,21 @@ int ext_bandstack_minus(void *data) { int ext_lock_update(void *data) { locked=locked==1?0:1; - vfo_update(); + g_idle_add(ext_vfo_update, NULL); return 0; } int ext_rit_update(void *data) { vfo[active_receiver->id].rit_enabled=vfo[active_receiver->id].rit_enabled==1?0:1; receiver_frequency_changed(active_receiver); - vfo_update(); + g_idle_add(ext_vfo_update, NULL); return 0; } int ext_rit_clear(void *data) { vfo[active_receiver->id].rit=0; receiver_frequency_changed(active_receiver); - vfo_update(); + g_idle_add(ext_vfo_update, NULL); return 0; } @@ -473,14 +476,14 @@ int ext_xit_update(void *data) { schedule_high_priority(); } } - vfo_update(); + g_idle_add(ext_vfo_update, NULL); return 0; } int ext_xit_clear(void *data) { if(can_transmit) { transmitter->xit=0; - vfo_update(); + g_idle_add(ext_vfo_update, NULL); } return 0; } @@ -523,7 +526,7 @@ int ext_ctun_update(void *data) { } vfo[id].ctun_frequency=vfo[id].frequency; set_offset(active_receiver,vfo[id].offset); - vfo_update(); + g_idle_add(ext_vfo_update, NULL); return 0; } @@ -533,19 +536,15 @@ int ext_agc_update(void *data) { active_receiver->agc=0; } set_agc(active_receiver, active_receiver->agc); - vfo_update(); + g_idle_add(ext_vfo_update, NULL); return 0; } -int ext_split_update(void *data) { +int ext_split_toggle(void *data) { 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); - } - vfo_update(); + tx_set_mode(transmitter,get_tx_mode()); + g_idle_add(ext_vfo_update, NULL); } return 0; } @@ -570,7 +569,7 @@ int ext_diversity_update(void *data) { schedule_high_priority(); schedule_receive_specific(); } - vfo_update(); + g_idle_add(ext_vfo_update, NULL); } return 0; } @@ -587,7 +586,7 @@ int ext_sat_update(void *data) { sat_mode=SAT_NONE; break; } - vfo_update(); + g_idle_add(ext_vfo_update, NULL); return 0; } @@ -597,7 +596,7 @@ int ext_function_update(void *data) { function=0; } update_toolbar_labels(); - vfo_update(); + g_idle_add(ext_vfo_update, NULL); return 0; } diff --git a/ext.h b/ext.h index f70c958..5a365f5 100644 --- a/ext.h +++ b/ext.h @@ -63,7 +63,7 @@ extern int ext_b_to_a(void *data); extern int ext_a_swap_b(void *data); extern int ext_ctun_update(void *data); extern int ext_agc_update(void *data); -extern int ext_split_update(void *data); +extern int ext_split_toggle(void *data); extern int ext_cw_setup(); diff --git a/gpio.c b/gpio.c index 9c1b76a..1b21c1e 100644 --- a/gpio.c +++ b/gpio.c @@ -526,7 +526,7 @@ static int e_function_pressed(void *data) { g_idle_add(ext_agc_update,NULL); break; case SPLIT: - if(can_transmit) g_idle_add(ext_split_update,NULL); + if(can_transmit) g_idle_add(ext_split_toggle,NULL); break; case DIVERSITY: g_idle_add(ext_diversity_update,GINT_TO_POINTER(0)); diff --git a/i2c.c b/i2c.c index 7478c57..67f52ee 100644 --- a/i2c.c +++ b/i2c.c @@ -271,7 +271,7 @@ void i2c_interrupt() { g_idle_add(ext_agc_update,NULL); break; case SPLIT: - if(can_transmit) g_idle_add(ext_split_update,NULL); + if(can_transmit) g_idle_add(ext_split_toggle,NULL); break; case DIVERSITY: g_idle_add(ext_diversity_update,GINT_TO_POINTER(0)); diff --git a/iambic.c b/iambic.c index 7e6f341..9a405b9 100644 --- a/iambic.c +++ b/iambic.c @@ -215,6 +215,8 @@ #include "iambic.h" #include "transmitter.h" #include "ext.h" +#include "mode.h" +#include "vfo.h" static void* keyer_thread(void *arg); static pthread_t keyer_thread_id; @@ -352,6 +354,7 @@ static void* keyer_thread(void *arg) { int i; int kdelay; int old_volume; + int txmode; #ifdef __APPLE__ struct timespec now; #endif @@ -376,7 +379,9 @@ static void* keyer_thread(void *arg) { // swallow any cw_events posted during the last "cw hang" time. if (!kcwl && !kcwr) continue; - if (!mox && cw_breakin) { + // check mode: to not induce RX/TX transition if not in CW mode + txmode=get_tx_mode(); + if (!mox && cw_breakin && (txmode == modeCWU || txmode == modeCWL)) { g_idle_add(ext_mox_update, (gpointer)(long) 1); // Wait for mox, that is, wait for WDSP shutting down the RX and // firing up the TX. This induces a small delay when hitting the key for diff --git a/midi3.c b/midi3.c index 898c8ec..56a1333 100644 --- a/midi3.c +++ b/midi3.c @@ -582,14 +582,7 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) { case MIDI_SPLIT: // only key supported // toggle split mode if (type == MIDI_KEY) { - if(!split) { - split=1; - tx_set_mode(transmitter,vfo[VFO_B].mode); - } else { - split=0; - tx_set_mode(transmitter,vfo[VFO_A].mode); - } - g_idle_add(ext_vfo_update, NULL); + g_idle_add(ext_split_toggle, NULL); } break; /////////////////////////////////////////////////////////// "SWAPRX" diff --git a/new_protocol.c b/new_protocol.c index 4483d1b..6be450c 100644 --- a/new_protocol.c +++ b/new_protocol.c @@ -573,13 +573,10 @@ g_print("iq_addr=%s\n",inet_ntoa(radio->info.network.address.sin_addr)); static void new_protocol_general() { BAND *band; int rc; + int txvfo=get_tx_vfo(); pthread_mutex_lock(&general_mutex); - if(split) { - band=band_get_band(vfo[VFO_B].band); - } else { - band=band_get_band(vfo[VFO_A].band); - } + band=band_get_band(vfo[txvfo].band); memset(general_buffer, 0, sizeof(general_buffer)); general_buffer[0]=general_sequence>>24; @@ -633,9 +630,9 @@ static void new_protocol_high_priority() { long long rxFrequency; long long txFrequency; long phase; - int txmode; int ddc; - int txvfo; + int txvfo=get_tx_vfo(); + int txmode=get_tx_mode(); if(data_socket==-1) { return; @@ -649,25 +646,6 @@ static void new_protocol_high_priority() { high_priority_buffer_to_radio[2]=high_priority_sequence>>8; high_priority_buffer_to_radio[3]=high_priority_sequence; - // - // Determine VFO controlling the TX frequency - // and the associated mode - // - if(active_receiver->id==VFO_A) { - if(split) { - txvfo=VFO_B; - } else { - txvfo=VFO_A; - } - } else { - if(split) { - txvfo=VFO_A; - } else { - txvfo=VFO_B; - } - } - txmode=vfo[txvfo].mode; - high_priority_buffer_to_radio[4]=running; // // We need not set PTT of doing internal CW with break-in @@ -794,12 +772,7 @@ static void new_protocol_high_priority() { high_priority_buffer_to_radio[345]=power&0xFF; if(isTransmitting()) { - - if(split) { - band=band_get_band(vfo[VFO_B].band); - } else { - band=band_get_band(vfo[VFO_A].band); - } + band=band_get_band(vfo[txvfo].band); high_priority_buffer_to_radio[1401]=band->OCtx<<1; if(tune) { if(OCmemory_tune_time!=0) { @@ -1142,7 +1115,7 @@ static void new_protocol_high_priority() { static unsigned char last_50=0; static void new_protocol_transmit_specific() { - int mode; + int txmode=get_tx_mode(); int rc; pthread_mutex_lock(&tx_spec_mutex); @@ -1153,15 +1126,10 @@ static void new_protocol_transmit_specific() { transmit_specific_buffer[2]=tx_specific_sequence>>8; transmit_specific_buffer[3]=tx_specific_sequence; - if(split) { - mode=vfo[1].mode; - } else { - mode=vfo[0].mode; - } transmit_specific_buffer[4]=1; // 1 DAC transmit_specific_buffer[5]=0; // default no CW - if ((mode==modeCWU || mode==modeCWL) && cw_keyer_internal) { + if ((txmode==modeCWU || txmode==modeCWL) && cw_keyer_internal) { // // Set this byte only if in CW, and if using the "internal" keyer // @@ -1789,10 +1757,6 @@ static void process_high_priority(unsigned char *buffer) { #endif } - //int tx_vfo=split?VFO_B:VFO_A; - //if(vfo[tx_vfo].mode==modeCWL || vfo[tx_vfo].mode==modeCWU) { - // local_ptt=local_ptt|dot|dash; - //} if(previous_ptt!=local_ptt) { g_idle_add(ext_mox_update,(gpointer)(long)(local_ptt)); } @@ -1830,10 +1794,10 @@ static void process_mic_data(int bytes) { void new_protocol_cw_audio_samples(short left_audio_sample,short right_audio_sample) { int rc; - int mode=transmitter->mode; + int txmode=get_tx_mode(); // // Only process samples if transmitting in CW - if (isTransmitting() && (mode==modeCWU || mode==modeCWL)) { + if (isTransmitting() && (txmode==modeCWU || txmode==modeCWL)) { // insert the samples audiobuffer[audioindex++]=left_audio_sample>>8; @@ -1864,10 +1828,10 @@ void new_protocol_cw_audio_samples(short left_audio_sample,short right_audio_sam void new_protocol_audio_samples(RECEIVER *rx,short left_audio_sample,short right_audio_sample) { int rc; - int mode=transmitter->mode; + int txmode=get_tx_mode(); // // Only process samples if NOT transmitting in CW - if (isTransmitting() && (mode==modeCWU || mode==modeCWL)) return; + if (isTransmitting() && (txmode==modeCWU || txmode==modeCWL)) return; // insert the samples audiobuffer[audioindex++]=left_audio_sample>>8; diff --git a/old_protocol.c b/old_protocol.c index f138735..b5b0fdb 100644 --- a/old_protocol.c +++ b/old_protocol.c @@ -710,11 +710,7 @@ static long long channel_freq(int chan) { // indicates that we should use the TX frequency. // We have to adjust by the offset for CTUN mode // - if(active_receiver->id==VFO_A) { - vfonum = split ? VFO_B : VFO_A; - } else { - vfonum = split ? VFO_A : VFO_B; - } + vfonum=get_tx_vfo(); freq=vfo[vfonum].frequency-vfo[vfonum].lo; if (vfo[vfonum].ctun) freq += vfo[vfonum].offset; if(transmitter->xit_enabled) { @@ -806,8 +802,6 @@ static void process_ozy_input_buffer(unsigned char *buffer) { int id=active_receiver->id; - int tx_vfo=split?VFO_B:VFO_A; - int num_hpsdr_receivers=how_many_receivers(); int rxfdbk = rx_feedback_channel(); int txfdbk = tx_feedback_channel(); @@ -1048,7 +1042,8 @@ static void process_bandscope_buffer(char *buffer) { void ozy_send_buffer() { - int mode; + int txmode=get_tx_mode(); + int txvfo=get_tx_vfo(); int i; BAND *band; int num_hpsdr_receivers=how_many_receivers(); @@ -1102,9 +1097,7 @@ void ozy_send_buffer() { } band=band_get_band(vfo[VFO_A].band); if(isTransmitting()) { - if(split) { - band=band_get_band(vfo[VFO_B].band); - } + band=band_get_band(vfo[txvfo].band); output_buffer[C2]|=band->OCtx<<1; if(tune) { if(OCmemory_tune_time!=0) { @@ -1294,12 +1287,7 @@ void ozy_send_buffer() { // Therefore, when in CW mode, send the TX drive level also when receiving. // (it would be sufficient to do so only with internal CW). // - if(split) { - mode=vfo[1].mode; - } else { - mode=vfo[0].mode; - } - if(isTransmitting() || (mode == modeCWU) || (mode == modeCWL)) { + if(isTransmitting() || (txmode == modeCWU) || (txmode == modeCWL)) { if(tune && !transmitter->tune_use_drive) { double fac=sqrt((double)transmitter->tune_percent * 0.01); power=(int)((double)transmitter->drive_level*fac); @@ -1474,13 +1462,8 @@ void ozy_send_buffer() { break; case 7: output_buffer[C0]=0x1E; - if(split) { - mode=vfo[1].mode; - } else { - mode=vfo[0].mode; - } output_buffer[C1]=0x00; - if((mode==modeCWU || mode==modeCWL) && !tune && cw_keyer_internal && !transmitter->twotone) { + if((txmode==modeCWU || txmode==modeCWL) && !tune && cw_keyer_internal && !transmitter->twotone) { output_buffer[C1]|=0x01; } output_buffer[C2]=cw_keyer_sidetone_volume; @@ -1530,13 +1513,8 @@ void ozy_send_buffer() { } // set mox - if(split) { - mode=vfo[1].mode; - } else { - mode=vfo[0].mode; - } if (isTransmitting()) { - if(mode==modeCWU || mode==modeCWL) { + if(txmode==modeCWU || txmode==modeCWL) { // // For "internal" CW, we should not set // the MOX bit, everything is done in the FPGA. diff --git a/pa_menu.c b/pa_menu.c index aee51f6..f9601ed 100644 --- a/pa_menu.c +++ b/pa_menu.c @@ -55,9 +55,8 @@ static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_d 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)); - int v=VFO_A; - if(split) v=VFO_B; - int b=vfo[v].band; + int txvfo=get_tx_vfo(); + int b=vfo[txvfo].band; BAND *current=band_get_band(b); if(band==current) { calcDriveLevel(); diff --git a/radio.c b/radio.c index 66e3c58..852b11d 100644 --- a/radio.c +++ b/radio.c @@ -1350,11 +1350,8 @@ void setTune(int state) { } } - int mode=vfo[VFO_A].mode; - if(split) { - mode=vfo[VFO_B].mode; - } - pre_tune_mode=mode; + int txmode=get_tx_mode(); + pre_tune_mode=txmode; pre_tune_cw_internal=cw_keyer_internal; // @@ -1362,7 +1359,7 @@ void setTune(int state) { // in LSB/DIGL, tune 1000 Hz below carrier // all other (CW, AM, FM): tune on carrier freq. // - switch(mode) { + switch(txmode) { case modeLSB: case modeDIGL: SetTXAPostGenToneFreq(transmitter->id,-(double)1000.0); @@ -1381,7 +1378,7 @@ void setTune(int state) { SetTXAPostGenMode(transmitter->id,0); SetTXAPostGenRun(transmitter->id,1); - switch(mode) { + switch(txmode) { case modeCWL: cw_keyer_internal=0; tx_set_mode(transmitter,modeLSB); @@ -1471,8 +1468,7 @@ double getDrive() { static int calcLevel(double d) { int level=0; - int v=VFO_A; - if(split) v=VFO_B; + int v=get_tx_vfo(); BAND *band=band_get_band(vfo[v].band); double target_dbm = 10.0 * log10(d * 1000.0); diff --git a/radio_menu.c b/radio_menu.c index 9e4b7c5..1c73ce0 100644 --- a/radio_menu.c +++ b/radio_menu.c @@ -40,6 +40,7 @@ #endif #include "gpio.h" #include "vfo.h" +#include "ext.h" static GtkWidget *parent_window=NULL; static GtkWidget *menu_b=NULL; @@ -196,12 +197,12 @@ static void iqswap_cb(GtkWidget *widget, gpointer data) { } static void split_cb(GtkWidget *widget, gpointer data) { - split=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); - vfo_update(); + int new=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); + if (new != split) g_idle_add(ext_split_toggle, NULL); } // -// call-able from outside, e.g. toolbar or MIDI +// call-able from outside, e.g. toolbar or MIDI, through g_idle_add // void setDuplex() { if(duplex) { @@ -214,7 +215,7 @@ void setDuplex() { gtk_widget_destroy(transmitter->dialog); reconfigure_transmitter(transmitter,display_width,rx_height*receivers); } - vfo_update(); + g_idle_add(ext_vfo_update, NULL); } static void duplex_cb(GtkWidget *widget, gpointer data) { @@ -228,7 +229,7 @@ static void duplex_cb(GtkWidget *widget, gpointer data) { static void sat_cb(GtkWidget *widget, gpointer data) { sat_mode=gtk_combo_box_get_active(GTK_COMBO_BOX(widget)); - vfo_update(); + g_idle_add(ext_vfo_update, NULL); } static void load_filters(void) { diff --git a/soapy_protocol.c b/soapy_protocol.c index 56e30c1..c392273 100644 --- a/soapy_protocol.c +++ b/soapy_protocol.c @@ -369,10 +369,7 @@ void soapy_protocol_set_tx_frequency(TRANSMITTER *tx) { int rc; double f; - v=active_receiver->id; - if(split) { - v=active_receiver->id==0?1:0; - } + v=get_tx_vfo(); if(soapy_device!=NULL) { //f=(double)(vfo[v].frequency+vfo[v].ctun_frequency-vfo[v].lo_tx); if(vfo[v].ctun) { diff --git a/toolbar.c b/toolbar.c index e05648b..409a094 100644 --- a/toolbar.c +++ b/toolbar.c @@ -276,15 +276,7 @@ static void aswapb_cb (GtkWidget *widget, gpointer data) { } static void split_cb (GtkWidget *widget, gpointer data) { - 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); - } + g_idle_add(ext_split_toggle, NULL); } static void duplex_cb (GtkWidget *widget, gpointer data) { diff --git a/transmitter.c b/transmitter.c index b98d98c..604ed8d 100644 --- a/transmitter.c +++ b/transmitter.c @@ -113,6 +113,7 @@ static gint update_out_of_band(gpointer data) { void transmitter_set_out_of_band(TRANSMITTER *tx) { tx->out_of_band=1; + g_idle_add(ext_vfo_update,NULL); tx->out_of_band_timer_id=gdk_threads_add_timeout_full(G_PRIORITY_HIGH_IDLE,1000,update_out_of_band, tx, NULL); } @@ -755,11 +756,6 @@ fprintf(stderr,"transmitter: allocate buffers: mic_input_buffer=%p iq_output_buf TXASetMP(tx->id, tx->low_latency); - int mode=vfo[VFO_A].mode; - if(split) { - mode=vfo[VFO_B].mode; - } - SetTXABandpassWindow(tx->id, 1); SetTXABandpassRun(tx->id, 1); @@ -806,7 +802,7 @@ fprintf(stderr,"transmitter: allocate buffers: mic_input_buffer=%p iq_output_buf SetTXACompressorGain(tx->id, tx->compressor_level); SetTXACompressorRun(tx->id, tx->compressor); - tx_set_mode(tx,mode); + tx_set_mode(tx,get_tx_mode()); XCreateAnalyzer(tx->id, &rc, 262144, 1, 1, ""); if (rc != 0) { @@ -850,14 +846,9 @@ void tx_set_mode(TRANSMITTER* tx,int mode) { } void tx_set_filter(TRANSMITTER *tx,int low,int high) { - int mode; - if(split) { - mode=vfo[1].mode; - } else { - mode=vfo[0].mode; - } + int txmode=get_tx_mode(); - switch(mode) { + switch(txmode) { case modeLSB: case modeCWL: case modeDIGL: diff --git a/tx_panadapter.c b/tx_panadapter.c index 4de9f04..b7dae99 100644 --- a/tx_panadapter.c +++ b/tx_panadapter.c @@ -186,11 +186,9 @@ void tx_panadapter_update(TRANSMITTER *tx) { int display_width=gtk_widget_get_allocated_width (tx->panadapter); int display_height=gtk_widget_get_allocated_height (tx->panadapter); - // id = VFO which contains the TX frequency - int id = active_receiver->id; - if (split) { - id = 1-id; - } + int txvfo = get_tx_vfo(); + int txmode = get_tx_mode(); + samples=tx->pixel_samples; hz_per_pixel=(double)tx->iq_output_rate/(double)tx->pixels; @@ -203,7 +201,7 @@ void tx_panadapter_update(TRANSMITTER *tx) { // filter - if (vfo[id].mode != modeCWU && vfo[id].mode != modeCWL) { + if (txmode != modeCWU && txmode != modeCWL) { 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); @@ -246,17 +244,17 @@ void tx_panadapter_update(TRANSMITTER *tx) { //long long half=24000LL; //(long long)(tx->output_rate/2); long long half=6000LL; //(long long)(tx->output_rate/2); long long frequency; - if(vfo[id].ctun) { - frequency=vfo[id].ctun_frequency-vfo[id].lo_tx; + if(vfo[txvfo].ctun) { + frequency=vfo[txvfo].ctun_frequency-vfo[txvfo].lo_tx; } else { - frequency=vfo[id].frequency-vfo[id].lo_tx; + frequency=vfo[txvfo].frequency-vfo[txvfo].lo_tx; } double vfofreq=(double)display_width * 0.5; if (!cw_is_on_vfo_freq) { - if(vfo[id].mode==modeCWU) { + if(txmode==modeCWU) { frequency+=(long long)cw_keyer_sidetone_frequency; vfofreq -= (double) cw_keyer_sidetone_frequency/hz_per_pixel; - } else if(vfo[id].mode==modeCWL) { + } else if(txmode==modeCWL) { frequency-=(long long)cw_keyer_sidetone_frequency; vfofreq += (double) cw_keyer_sidetone_frequency/hz_per_pixel; } @@ -295,7 +293,7 @@ void tx_panadapter_update(TRANSMITTER *tx) { // band edges long long min_display=frequency-half; long long max_display=frequency+half; - int b=vfo[id].band; + int b=vfo[txvfo].band; BAND *band=band_get_band(b); if(band->frequencyMin!=0LL) { cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); diff --git a/vfo.c b/vfo.c index 9a897b1..25cceac 100644 --- a/vfo.c +++ b/vfo.c @@ -318,11 +318,7 @@ void vfo_band_changed(int b) { } if(can_transmit) { - if(split) { - tx_set_mode(transmitter,vfo[VFO_B].mode); - } else { - tx_set_mode(transmitter,vfo[VFO_A].mode); - } + tx_set_mode(transmitter,get_tx_mode()); // // If the band has changed, it is necessary to re-calculate // the drive level. Furthermore, possibly the "PA disable" @@ -367,11 +363,7 @@ void vfo_bandstack_changed(int b) { } if(can_transmit) { - if(split) { - tx_set_mode(transmitter,vfo[VFO_B].mode); - } else { - tx_set_mode(transmitter,vfo[VFO_A].mode); - } + tx_set_mode(transmitter,get_tx_mode()); } // // I do not think the band can change within this function. @@ -414,11 +406,7 @@ void vfo_mode_changed(int m) { break; } if(can_transmit) { - if(split) { - tx_set_mode(transmitter,vfo[VFO_B].mode); - } else { - tx_set_mode(transmitter,vfo[VFO_A].mode); - } + tx_set_mode(transmitter,get_tx_mode()); } // // changing modes may change BFO frequency @@ -467,9 +455,7 @@ void vfo_a_to_b() { receiver_vfo_changed(receiver[1]); } if(can_transmit) { - if(split) { - tx_set_mode(transmitter,vfo[VFO_B].mode); - } + tx_set_mode(transmitter,get_tx_mode()); } g_idle_add(ext_vfo_update,NULL); } @@ -486,9 +472,7 @@ void vfo_b_to_a() { vfo[VFO_A].rit=vfo[VFO_B].rit; receiver_vfo_changed(receiver[0]); if(can_transmit) { - if(!split) { - tx_set_mode(transmitter,vfo[VFO_B].mode); - } + tx_set_mode(transmitter,get_tx_mode()); } g_idle_add(ext_vfo_update,NULL); } @@ -539,11 +523,7 @@ void vfo_a_swap_b() { receiver_vfo_changed(receiver[1]); } if(can_transmit) { - if(split) { - tx_set_mode(transmitter,vfo[VFO_B].mode); - } else { - tx_set_mode(transmitter,vfo[VFO_A].mode); - } + tx_set_mode(transmitter,get_tx_mode()); } g_idle_add(ext_vfo_update,NULL); } @@ -832,6 +812,8 @@ static gboolean vfo_draw_cb (GtkWidget *widget, void vfo_update() { int id=active_receiver->id; + int txvfo=get_tx_vfo(); + FILTER* band_filters=filters[vfo[id].mode]; FILTER* band_filter=&band_filters[vfo[id].filter]; if(vfo_surface) { @@ -885,32 +867,19 @@ void vfo_update() { // If it is out-of-band, we display "Out of band" in red. // Frequencies we are not transmitting on are displayed in green // (dimmed if the freq. does not belong to the active receiver). - // Depending on which receiver is the active one, and if we use split, - // the following frequencies are used for transmitting (see old_protocol.c): - // id == 0, split == 0 : TX freq = VFO_A - // id == 0, split == 1 : TX freq = VFO_B - // id == 1, split == 0 : TX freq = VFO_B - // id == 1, split == 1 : TX freq = VFO_A - - - 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); - } - } + + // Frequencies of VFO A and B + + long long af = vfo[0].ctun ? vfo[0].ctun_frequency : vfo[0].frequency; + long long bf = vfo[1].ctun ? vfo[1].ctun_frequency : vfo[1].frequency; + + int oob=0; + if (can_transmit) oob=transmitter->out_of_band; 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"); + + if(txvfo == 0 && (isTransmitting() || oob)) { + if (oob) sprintf(temp_text,"VFO A: Out of band"); cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); } else { if(id==0) { @@ -923,24 +892,9 @@ void vfo_update() { cairo_set_font_size(cr, 22); cairo_show_text(cr, temp_text); - - 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"); + if(txvfo == 1 && (isTransmitting() || oob)) { + if (oob) sprintf(temp_text,"VFO B: Out of band"); cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); } else { if(id==1) { @@ -1095,35 +1049,37 @@ void vfo_update() { cairo_set_source_rgb(cr, 1.0, 1.0, 0.0); cairo_show_text(cr, temp_text); - // - // af: Frequency of VFO_A, bf: Frequency of VFO_B, without xit/rit etc. - // + long long txfreq; int txlow, txhigh; - if ((id == 0 && ! split) || (id == 1 && split)) { - // txfreq derived from VFO A - txfreq=af; - } else { - txfreq=bf; - } - if (transmitter->xit_enabled) txfreq += transmitter->xit; - // - // In CW modes, the signal is generated explicitly (without WDSP), - // so we can assume a zero-width filter. Note that the CW signal - // can be on the VFO frequency or offset by the side tone freq. - // - switch (transmitter->mode) { - case modeCWU: - txlow = txhigh = cw_is_on_vfo_freq ? 0 : cw_keyer_sidetone_frequency; - break; - case modeCWL: - txlow = txhigh = cw_is_on_vfo_freq ? 0 : -cw_keyer_sidetone_frequency; - break; - default: - txlow =transmitter->filter_low; - txhigh=transmitter->filter_high; + if (can_transmit) { + txfreq = (txvfo == 0) ? af : bf; + if (transmitter->xit_enabled) txfreq += transmitter->xit; + // + // In CW modes, the signal is generated explicitly (without WDSP), + // so we can assume a zero-width filter. Note that the CW signal + // can be on the VFO frequency or offset by the side tone freq. + // + switch (transmitter->mode) { + case modeCWU: + txlow = txhigh = cw_is_on_vfo_freq ? 0 : cw_keyer_sidetone_frequency; + break; + case modeCWL: + txlow = txhigh = cw_is_on_vfo_freq ? 0 : -cw_keyer_sidetone_frequency; + break; + default: + txlow =transmitter->filter_low; + txhigh=transmitter->filter_high; break; + } + } else { + // + // If there is no transmitter, use VFO frequency of active receiver + // + txfreq = (id == 0) ? af : bf; + txlow = 0; + txhigh =0; } getFrequencyInfo(txfreq, txlow, txhigh); /* @@ -1254,3 +1210,35 @@ fprintf(stderr,"vfo_init: width=%d height=%d\n", width, height); return vfo_panel; } + +// +// Some utility functions to get characteristics of the current +// transmitter. These functions can be used even if there is no +// transmitter (transmitter->mode may segfault). +// + +int get_tx_vfo() { + int txvfo=active_receiver->id; + if (split) txvfo = 1 - txvfo; + return txvfo; +} + +int get_tx_mode() { + int txvfo=active_receiver->id; + if (split) txvfo = 1 - txvfo; + if (can_transmit) { + return vfo[txvfo].mode; + } else { + return modeUSB; + } +} + +long long get_tx_freq() { + int txvfo=active_receiver->id; + if (split) txvfo = 1 - txvfo; + if (vfo[txvfo].ctun) { + return vfo[txvfo].ctun_frequency; + } else { + return vfo[txvfo].frequency; + } +} diff --git a/vfo.h b/vfo.h index 101a9b5..bd08e57 100644 --- a/vfo.h +++ b/vfo.h @@ -85,5 +85,9 @@ extern void vfo_a_to_b(); extern void vfo_b_to_a(); extern void vfo_a_swap_b(); +extern int get_tx_vfo(); +extern int get_tx_mode(); +extern long long get_tx_freq(); + extern void vfo_xvtr_changed(); #endif -- 2.45.2