static int af_encoder_changed(void *data) { int pos=*(int*)data; if(pos!=0) { if(function || isTransmitting()) { // mic gain double gain=mic_gain; //gain+=(double)pos/100.0; gain+=(double)pos; if(gain<-10.0) { gain=-10.0; } else if(gain>50.0) { gain=50.0; } set_mic_gain(gain); } else { // af gain double gain=volume; gain+=(double)pos/100.0; if(gain<0.0) { gain=0.0; } else if(gain>1.0) { gain=1.0; } set_af_gain(gain); } } free(data); return 0; }
//------------------------------------------------------------------------------ // transmit() -- send radar emissions //------------------------------------------------------------------------------ void Radar::transmit(const LCreal dt) { BaseClass::transmit(dt); // Transmitting, scanning and have an antenna? if ( !areEmissionsDisabled() && isTransmitting() ) { // Send the emission to the other player Emission* em = new Emission(); em->setFrequency(getFrequency()); em->setBandwidth(getBandwidth()); const LCreal prf1 = getPRF(); em->setPRF(prf1); int pulses = static_cast<int>(prf1 * dt + 0.5); if (pulses == 0) pulses = 1; // at least one em->setPulses(pulses); const LCreal p = getPeakPower(); em->setPower(p); em->setMaxRangeNM(getRange()); em->setPulseWidth(getPulseWidth()); em->setTransmitLoss(getRfTransmitLoss()); em->setReturnRequest( isReceiverEnabled() ); em->setTransmitter(this); getAntenna()->rfTransmit(em); em->unref(); } }
int vfo_update(void *data) { BANDSTACK_ENTRY* entry=bandstack_entry_get_current(); FILTER* band_filters=filters[entry->mode]; FILTER* band_filter=&band_filters[entry->filter]; if(vfo_surface) { cairo_t *cr; cr = cairo_create (vfo_surface); cairo_set_source_rgb (cr, 0, 0, 0); cairo_paint (cr); cairo_select_font_face(cr, "Arial", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); //cairo_set_font_size(cr, 36); cairo_set_font_size(cr, 28); if(isTransmitting()) { cairo_set_source_rgb(cr, 1, 0, 0); } else { cairo_set_source_rgb(cr, 0, 1, 0); } long long f=entry->frequencyA+ddsOffset; char sf[32]; //sprintf(sf,"%0lld.%06lld MHz",entry->frequencyA/(long long)1000000,entry->frequencyA%(long long)1000000); sprintf(sf,"%0lld.%06lld MHz",f/(long long)1000000,f%(long long)1000000); cairo_move_to(cr, 5, 30); cairo_show_text(cr, sf); cairo_set_font_size(cr, 12); cairo_move_to(cr, (my_width/2)+40, 30); //cairo_show_text(cr, getFrequencyInfo(entry->frequencyA)); cairo_show_text(cr, getFrequencyInfo(f)); sprintf(sf,"Step %dHz",step); cairo_move_to(cr, (my_width/2)+40, 15); cairo_show_text(cr, sf); if(locked) { cairo_set_source_rgb(cr, 1, 0, 0); cairo_move_to(cr, 10, 50); cairo_show_text(cr, "Locked"); } if(function) { cairo_set_source_rgb(cr, 1, 0.5, 0); cairo_move_to(cr, 70, 50); cairo_show_text(cr, "Function"); } cairo_set_source_rgb(cr, 1, 1, 0); cairo_move_to(cr, 130, 50); cairo_show_text(cr, mode_string[entry->mode]); cairo_move_to(cr, 190, 50); cairo_show_text(cr, band_filter->title); cairo_move_to(cr, 250, 50); if(nr) { cairo_show_text(cr, "NR"); } if(nr2) { cairo_show_text(cr, "NR2"); } if(nb) { cairo_show_text(cr, "NB"); } if(nb2) { cairo_show_text(cr, "NB2"); } if(anf) { cairo_show_text(cr, "ANF"); } if(snb) { cairo_show_text(cr, "SNB"); } cairo_move_to(cr, 310, 50); switch(agc) { case AGC_OFF: cairo_show_text(cr, "AGC OFF"); break; case AGC_LONG: cairo_show_text(cr, "AGC LONG"); break; case AGC_SLOW: cairo_show_text(cr, "AGC SLOW"); break; case AGC_MEDIUM: cairo_show_text(cr, "AGC MEDIUM"); break; case AGC_FAST: cairo_show_text(cr, "AGC FAST"); break; } cairo_destroy (cr); gtk_widget_queue_draw (vfo); } else { fprintf(stderr,"vfo_update: no surface!\n"); } return 0; }
gint update(gpointer data) { int result; double fwd; double rev; double exciter; int channel=CHANNEL_RX0; #ifdef PSK if(mode==modePSK) { channel=CHANNEL_PSK; } #endif if(isTransmitting()) { channel=CHANNEL_TX; } GetPixels(channel,0,samples,&result); if(result==1) { if(display_panadapter) { #ifdef PSK if(mode==modePSK) { psk_waterfall_update(samples); } else { #endif panadapter_update(samples,isTransmitting()); #ifdef PSK } #endif } if(!isTransmitting()) { #ifdef PSK if(mode!=modePSK) { #endif if(display_waterfall) { waterfall_update(samples); } #ifdef PSK } #endif } } if(!isTransmitting()) { double m; switch(mode) { #ifdef PSK case modePSK: m=(double)psk_get_signal_level(); meter_update(PSKMETER,m,0.0,0.0,0.0); break; #endif default: m=GetRXAMeter(CHANNEL_RX0, smeter); meter_update(SMETER,m,0.0,0.0,0.0); break; } } else { double alc=GetTXAMeter(CHANNEL_TX, alc); DISCOVERED *d=&discovered[selected_device]; double constant1=3.3; double constant2=0.095; if(d->protocol==ORIGINAL_PROTOCOL) { switch(d->device) { case DEVICE_METIS: constant1=3.3; constant2=0.09; break; case DEVICE_HERMES: constant1=3.3; constant2=0.095; break; case DEVICE_ANGELIA: constant1=3.3; constant2=0.095; break; case DEVICE_ORION: constant1=5.0; constant2=0.108; break; case DEVICE_HERMES_LITE: break; } int power=alex_forward_power; if(power==0) { power=exciter_power; } double v1; v1=((double)power/4095.0)*constant1; fwd=(v1*v1)/constant2; power=exciter_power; v1=((double)power/4095.0)*constant1; exciter=(v1*v1)/constant2; rev=0.0; if(alex_forward_power!=0) { power=alex_reverse_power; v1=((double)power/4095.0)*constant1; rev=(v1*v1)/constant2; } } else { switch(d->device) { case NEW_DEVICE_ATLAS: constant1=3.3; constant2=0.09; break; case NEW_DEVICE_HERMES: constant1=3.3; constant2=0.09; break; case NEW_DEVICE_HERMES2: constant1=3.3; constant2=0.095; break; case NEW_DEVICE_ANGELIA: constant1=3.3; constant2=0.095; break; case NEW_DEVICE_ORION: constant1=5.0; constant2=0.108; break; case NEW_DEVICE_ORION2: constant1=5.0; constant2=0.108; break; case NEW_DEVICE_HERMES_LITE: constant1=3.3; constant2=0.09; break; } int power=alex_forward_power; if(power==0) { power=exciter_power; } double v1; v1=((double)power/4095.0)*constant1; fwd=(v1*v1)/constant2; power=exciter_power; v1=((double)power/4095.0)*constant1; exciter=(v1*v1)/constant2; rev=0.0; if(alex_forward_power!=0) { power=alex_reverse_power; v1=((double)power/4095.0)*constant1; rev=(v1*v1)/constant2; } } /* fprintf(stderr,"alex_forward_power=%d alex_reverse_power=%d exciter_power=%d fwd=%f rev=%f exciter=%f\n", alex_forward_power, alex_reverse_power, exciter_power, fwd, rev, exciter); */ meter_update(POWER,fwd,rev,exciter,alc); } return TRUE; }
static void process_mic_data(unsigned char *buffer) { long sequence; int b; int micsample; double micsampledouble; sequence=((buffer[0]&0xFF)<<24)+((buffer[1]&0xFF)<<16)+((buffer[2]&0xFF)<<8)+(buffer[3]&0xFF); // if(isTransmitting()) { b=4; int i,j,s; for(i=0;i<MIC_SAMPLES;i++) { #ifdef FREEDV if(mode==modeFREEDV && isTransmitting()) { micsample = (int)((signed char) buffer[b++]) << 8; micsample |= (int)((unsigned char)buffer[b++] & 0xFF); if(freedv_samples==0) { // 48K to 8K int sample=(int)((double)micsample*pow(10.0, mic_gain / 20.0)); int modem_samples=mod_sample_freedv(sample); if(modem_samples!=0) { for(s=0;s<modem_samples;s++) { for(j=0;j<freedv_resample;j++) { // 8K to 48K micsample=mod_out[s]; micsampledouble=(double)micsample/32767.0; // 16 bit sample 2^16-1 micinputbuffer[micsamples*2]=micsampledouble; micinputbuffer[(micsamples*2)+1]=micsampledouble; micsamples++; if(micsamples==BUFFER_SIZE) { full_tx_buffer(); micsamples=0; } } } } } freedv_samples++; if(freedv_samples==freedv_resample) { freedv_samples=0; } } else { #endif //micsampledouble = (double)micsample/32767.0; // 16 bit sample micsampledouble = (1.0 / 2147483648.0) * (double)(buffer[b++] << 24 | buffer[b++] << 16); if(mode==modeCWL || mode==modeCWU || tune || !isTransmitting()) { micinputbuffer[micsamples*2]=0.0; micinputbuffer[(micsamples*2)+1]=0.0; } else { micinputbuffer[micsamples*2]=micsampledouble; micinputbuffer[(micsamples*2)+1]=micsampledouble; } micsamples++; if(micsamples==BUFFER_SIZE) { full_tx_buffer(); micsamples=0; } #ifdef FREEDV } #endif } // } }
static void new_protocol_high_priority(int run) { unsigned char buffer[1444]; BAND *band=band_get_current_band(); memset(buffer, 0, sizeof(buffer)); buffer[0]=high_priority_sequence>>24; buffer[1]=high_priority_sequence>>16; buffer[2]=high_priority_sequence>>8; buffer[3]=high_priority_sequence; buffer[4]=run; if(mode==modeCWU || mode==modeCWL) { if(tune) { buffer[4]|=0x02; } } else { if(isTransmitting()) { buffer[4]|=0x02; } } long rxFrequency=ddsFrequency; if(mode==modeCWU) { rxFrequency-=cw_keyer_sidetone_frequency; } else if(mode==modeCWL) { rxFrequency+=cw_keyer_sidetone_frequency; } long phase=(long)((4294967296.0*(double)rxFrequency)/122880000.0); // rx buffer[9]=phase>>24; buffer[10]=phase>>16; buffer[11]=phase>>8; buffer[12]=phase; // tx (no split yet) long long txFrequency=ddsFrequency; if(ctun) { txFrequency+=ddsOffset; } phase=(long)((4294967296.0*(double)txFrequency)/122880000.0); buffer[329]=phase>>24; buffer[330]=phase>>16; buffer[331]=phase>>8; buffer[332]=phase; int power=0; if(isTransmitting()) { if(tune) { power=tune_drive_level; } else { power=drive_level; } } buffer[345]=power&0xFF; if(isTransmitting()) { buffer[1401]=band->OCtx; if(tune) { if(OCmemory_tune_time!=0) { struct timeval te; gettimeofday(&te,NULL); long long now=te.tv_sec*1000LL+te.tv_usec/1000; if(tune_timeout>now) { buffer[1401]|=OCtune; } } else { buffer[1401]|=OCtune; } } } else { buffer[1401]=band->OCrx; } // alex HPF filters /* if (frequency < 1800000) HPF <= 6'b100000; // bypass else if (frequency < 6500000) HPF <= 6'b010000; // 1.5MHz HPF else if (frequency < 9500000) HPF <= 6'b001000; // 6.5MHz HPF else if (frequency < 13000000) HPF <= 6'b000100; // 9.5MHz HPF else if (frequency < 20000000) HPF <= 6'b000001; // 13MHz HPF else HPF <= 6'b000010; // 20MHz HPF */ long filters=0x00000000; if(isTransmitting()) { filters=0x08000000; } // set HPF if(ddsFrequency<1800000L) { filters|=ALEX_BYPASS_HPF; } else if(ddsFrequency<6500000L) { filters|=ALEX_1_5MHZ_HPF; } else if(ddsFrequency<9500000L) { filters|=ALEX_6_5MHZ_HPF; } else if(ddsFrequency<13000000L) { filters|=ALEX_9_5MHZ_HPF; } else if(ddsFrequency<20000000L) { filters|=ALEX_13MHZ_HPF; } else { filters|=ALEX_20MHZ_HPF; } // alex LPF filters /* if (frequency > 32000000) LPF <= 7'b0010000; // > 10m so use 6m LPF^M else if (frequency > 22000000) LPF <= 7'b0100000; // > 15m so use 12/10m LPF^M else if (frequency > 15000000) LPF <= 7'b1000000; // > 20m so use 17/15m LPF^M else if (frequency > 8000000) LPF <= 7'b0000001; // > 40m so use 30/20m LPF ^M else if (frequency > 4500000) LPF <= 7'b0000010; // > 80m so use 60/40m LPF^M else if (frequency > 2400000) LPF <= 7'b0000100; // > 160m so use 80m LPF ^M else LPF <= 7'b0001000; // < 2.4MHz so use 160m LPF^M */ if(ddsFrequency>32000000) { filters|=ALEX_6_BYPASS_LPF; } else if(ddsFrequency>22000000) { filters|=ALEX_12_10_LPF; } else if(ddsFrequency>15000000) { filters|=ALEX_17_15_LPF; } else if(ddsFrequency>8000000) { filters|=ALEX_30_20_LPF; } else if(ddsFrequency>4500000) { filters|=ALEX_60_40_LPF; } else if(ddsFrequency>2400000) { filters|=ALEX_80_LPF; } else { filters|=ALEX_160_LPF; } switch(band->alexRxAntenna) { case 0: // ANT 1 break; case 1: // ANT 2 break; case 2: // ANT 3 break; case 3: // EXT 1 filters|=ALEX_RX_ANTENNA_EXT2; break; case 4: // EXT 2 filters|=ALEX_RX_ANTENNA_EXT1; break; case 5: // XVTR filters|=ALEX_RX_ANTENNA_XVTR; break; default: // invalid value - set to 0 band->alexRxAntenna=0; break; } if(isTransmitting()) { switch(band->alexTxAntenna) { case 0: // ANT 1 filters|=ALEX_TX_ANTENNA_1; break; case 1: // ANT 2 filters|=ALEX_TX_ANTENNA_2; break; case 2: // ANT 3 filters|=ALEX_TX_ANTENNA_3; break; default: // invalid value - set to 0 filters|=ALEX_TX_ANTENNA_1; band->alexRxAntenna=0; break; } } else { switch(band->alexRxAntenna) { case 0: // ANT 1 filters|=ALEX_TX_ANTENNA_1; break; case 1: // ANT 2 filters|=ALEX_TX_ANTENNA_2; break; case 2: // ANT 3 filters|=ALEX_TX_ANTENNA_3; break; case 3: // EXT 1 case 4: // EXT 2 case 5: // XVTR switch(band->alexTxAntenna) { case 0: // ANT 1 filters|=ALEX_TX_ANTENNA_1; break; case 1: // ANT 2 filters|=ALEX_TX_ANTENNA_2; break; case 2: // ANT 3 filters|=ALEX_TX_ANTENNA_3; break; } break; } } buffer[1432]=(filters>>24)&0xFF; buffer[1433]=(filters>>16)&0xFF; buffer[1434]=(filters>>8)&0xFF; buffer[1435]=filters&0xFF; //buffer[1442]=attenuation; buffer[1443]=attenuation; //fprintf(stderr,"high_priority[4]=0x%02X\n", buffer[4]); //fprintf(stderr,"filters=%04X\n", filters); if(sendto(data_socket,buffer,sizeof(buffer),0,(struct sockaddr*)&high_priority_addr,high_priority_addr_length)<0) { fprintf(stderr,"sendto socket failed for high priority\n"); exit(1); } high_priority_sequence++; }
void panadapter_update(float *data,int tx) { int i; int result; float saved_max; float saved_min; gfloat saved_hz_per_pixel; cairo_text_extents_t extents; hz_per_pixel=(double)getSampleRate()/(double)display_width; samples=data; //if(result==1) { if(panadapter_surface) { if(tx) { saved_max=panadapter_high; saved_min=panadapter_low; saved_hz_per_pixel=hz_per_pixel; panadapter_high=20; panadapter_low=-80; //if(protocol==ORIGINAL_PROTOCOL) { hz_per_pixel=48000.0/(double)display_width; //} else { // hz_per_pixel=192000.0/(double)display_width; //} } //clear_panadater_surface(); cairo_t *cr; cr = cairo_create (panadapter_surface); cairo_set_source_rgb (cr, 0, 0, 0); cairo_paint (cr); // filter cairo_set_source_rgb (cr, 0.25, 0.25, 0.25); if(ctun && isTransmitting()) { filter_left=(double)display_width/2.0+((double)getFilterLow()/hz_per_pixel); filter_right=(double)display_width/2.0+((double)getFilterHigh()/hz_per_pixel); } else { filter_left=(double)display_width/2.0+(((double)getFilterLow()+ddsOffset)/hz_per_pixel); filter_right=(double)display_width/2.0+(((double)getFilterHigh()+ddsOffset)/hz_per_pixel); } cairo_rectangle(cr, filter_left, 0.0, filter_right-filter_left, (double)display_height); cairo_fill(cr); // plot the levels int V = (int)(panadapter_high - panadapter_low); int numSteps = V / 20; for (i = 1; i < numSteps; i++) { int num = panadapter_high - i * 20; int y = (int)floor((panadapter_high - num) * display_height / V); cairo_set_source_rgb (cr, 0, 1, 1); cairo_set_line_width(cr, 1.0); cairo_move_to(cr,0.0,(double)y); cairo_line_to(cr,(double)display_width,(double)y); cairo_set_source_rgb (cr, 0, 1, 1); cairo_select_font_face(cr, "FreeMono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, 12); char v[32]; sprintf(v,"%d dBm",num); cairo_move_to(cr, 1, (double)y); cairo_show_text(cr, v); } cairo_stroke(cr); // plot frequency markers long f; long divisor=20000; long half=(long)getSampleRate()/2L; long frequency=getFrequency(); if(ctun && isTransmitting()) { frequency+=ddsOffset; } switch(sample_rate) { case 48000: divisor=5000L; break; case 96000: case 100000: divisor=10000L; break; case 192000: divisor=20000L; break; case 384000: divisor=25000L; break; case 768000: divisor=50000L; break; case 1048576: case 1536000: case 2097152: divisor=100000L; break; } for(i=0;i<display_width;i++) { f = frequency - half + (long) (hz_per_pixel * i); if (f > 0) { if ((f % divisor) < (long) hz_per_pixel) { cairo_set_source_rgb (cr, 0, 1, 1); cairo_set_line_width(cr, 1.0); //cairo_move_to(cr,(double)i,0.0); cairo_move_to(cr,(double)i,10.0); cairo_line_to(cr,(double)i,(double)display_height); cairo_set_source_rgb (cr, 0, 1, 1); cairo_select_font_face(cr, "FreeMono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, 12); char v[32]; sprintf(v,"%0ld.%03ld",f/1000000,(f%1000000)/1000); //cairo_move_to(cr, (double)i, (double)(display_height-10)); cairo_text_extents(cr, v, &extents); cairo_move_to(cr, (double)i-(extents.width/2.0), 10.0); cairo_show_text(cr, v); } } } cairo_stroke(cr); // band edges long min_display=frequency-half; long max_display=frequency+half; BAND_LIMITS* bandLimits=getBandLimits(min_display,max_display); if(bandLimits!=NULL) { cairo_set_source_rgb (cr, 1, 0, 0); cairo_set_line_width(cr, 2.0); if((min_display<bandLimits->minFrequency)&&(max_display>bandLimits->minFrequency)) { i=(bandLimits->minFrequency-min_display)/(long long)hz_per_pixel; cairo_move_to(cr,(double)i,0.0); cairo_line_to(cr,(double)i,(double)display_height); } if((min_display<bandLimits->maxFrequency)&&(max_display>bandLimits->maxFrequency)) { i=(bandLimits->maxFrequency-min_display)/(long long)hz_per_pixel; cairo_move_to(cr,(double)i,0.0); cairo_line_to(cr,(double)i,(double)display_height); } } // agc if(agc!=AGC_OFF && !tx) { double hang=0.0; double thresh=0; GetRXAAGCHangLevel(CHANNEL_RX0, &hang); GetRXAAGCThresh(CHANNEL_RX0, &thresh, 4096.0, (double)sample_rate); double knee_y=thresh+(double)get_attenuation(); knee_y = floor((panadapter_high - knee_y) * (double) display_height / (panadapter_high - panadapter_low)); double hang_y=hang+(double)get_attenuation(); hang_y = floor((panadapter_high - hang_y) * (double) display_height / (panadapter_high - panadapter_low)); //fprintf(stderr,"hang=%f thresh=%f hang_y=%f knee_y=%f\n",rx1_hang,rx1_thresh,hang_y,knee_y); if(agc!=AGC_MEDIUM && agc!=AGC_FAST) { cairo_set_source_rgb (cr, 1.0, 1.0, 0.0); cairo_move_to(cr,40.0,hang_y-8.0); cairo_rectangle(cr, 40, hang_y-8.0,8.0,8.0); cairo_fill(cr); cairo_move_to(cr,40.0,hang_y); cairo_line_to(cr,(double)display_width-40.0,hang_y); cairo_stroke(cr); cairo_move_to(cr,48.0,hang_y); cairo_show_text(cr, "-H"); } cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); cairo_move_to(cr,40.0,knee_y-8.0); cairo_rectangle(cr, 40, knee_y-8.0,8.0,8.0); cairo_fill(cr); cairo_move_to(cr,40.0,knee_y); cairo_line_to(cr,(double)display_width-40.0,knee_y); cairo_stroke(cr); cairo_move_to(cr,48.0,knee_y); cairo_show_text(cr, "-G"); } // cursor cairo_set_source_rgb (cr, 1, 0, 0); cairo_set_line_width(cr, 1.0); cairo_move_to(cr,(double)(display_width/2.0)+(ddsOffset/hz_per_pixel),0.0); cairo_line_to(cr,(double)(display_width/2.0)+(ddsOffset/hz_per_pixel),(double)display_height); cairo_stroke(cr); // signal double s1,s2; samples[0]=-200.0; samples[display_width-1]=-200.0; if(tx && protocol==NEW_PROTOCOL) { int offset=1200; s1=(double)samples[0+offset]+(double)get_attenuation(); s1 = floor((panadapter_high - s1) * (double) display_height / (panadapter_high - panadapter_low)); cairo_move_to(cr, 0.0, s1); for(i=1;i<display_width;i++) { s2=(double)samples[i+offset]+(double)get_attenuation(); s2 = floor((panadapter_high - s2) * (double) display_height / (panadapter_high - panadapter_low)); cairo_line_to(cr, (double)i, s2); } } else { s1=(double)samples[0]+(double)get_attenuation(); s1 = floor((panadapter_high - s1) * (double) display_height / (panadapter_high - panadapter_low)); cairo_move_to(cr, 0.0, s1); for(i=1;i<display_width;i++) { s2=(double)samples[i]+(double)get_attenuation(); s2 = floor((panadapter_high - s2) * (double) display_height / (panadapter_high - panadapter_low)); cairo_line_to(cr, (double)i, s2); } } if(display_filled) { cairo_close_path (cr); cairo_set_source_rgba(cr, 1, 1, 1,0.5); cairo_fill_preserve (cr); } cairo_set_source_rgb(cr, 1, 1, 1); cairo_set_line_width(cr, 1.0); cairo_stroke(cr); #ifdef FREEDV if(mode==modeFREEDV) { if(tx) { cairo_set_source_rgb(cr, 1, 0, 0); } else { cairo_set_source_rgb(cr, 0, 1, 0); } cairo_set_font_size(cr, 16); cairo_text_extents(cr, freedv_text_data, &extents); cairo_move_to(cr, (double)display_width/2.0-(extents.width/2.0),(double)display_height-2.0); cairo_show_text(cr, freedv_text_data); } #endif cairo_destroy (cr); gtk_widget_queue_draw (panadapter); if(tx) { panadapter_high=saved_max; panadapter_low=saved_min; hz_per_pixel=saved_hz_per_pixel; } /* else if(mode==modeFREEDV) { panadapter_high=saved_max; panadapter_low=saved_min; hz_per_pixel=saved_hz_per_pixel; } */ } //} }
//------------------------------------------------------------------------------ // transmit() -- send radar emissions //------------------------------------------------------------------------------ void RealBeamRadar::transmit(const LCreal dt) { BaseClass::transmit(dt); // Test parameters double latitude = 0; double longitude = 0; beamWidth = 7.0; // const Simulation::Player* own = getOwnship(); if (own != nullptr) { // Get our ownship parameters altitude = static_cast<LCreal>(own->getAltitude()); latitude = own->getLatitude(); longitude = own->getLongitude(); // Locate the terrain elevation database if (terrain == nullptr) { const Simulation::Simulation* sim = own->getSimulation(); if (sim != nullptr) { setTerrain( sim->getTerrain() ); } } } // Transmitting, scanning const Simulation::Antenna* ant = getAntenna(); if (isTransmitting() && ant != nullptr && image != nullptr && terrain != nullptr && terrain->isDataLoaded()) { // Compute max range (NM) LCreal maxRngNM = getRange(); // Compute ground range LCreal groundRange[IMG_HEIGHT]; computeGroundRanges(groundRange, IMG_HEIGHT, maxRngNM); // Compute slant range LCreal slantRange2[IMG_HEIGHT]; computeSlantRanges2(slantRange2, IMG_HEIGHT, groundRange, altitude); // Compute the loss from range LCreal rangeLoss[IMG_HEIGHT]; computeRangeLoss(rangeLoss, IMG_HEIGHT, slantRange2); // Compute the earth's curvature effect LCreal curvature[IMG_HEIGHT]; computeEarthCurvature(curvature, IMG_HEIGHT, maxRngNM, static_cast<LCreal>(Basic::Nav::ERAD60)); LCreal hue = 120.0; // see Hsv LCreal saturation = 0.0; // see Hsv const Basic::Hsva* grayTable[19]; grayTable[0] = new Basic::Hsva( hue, saturation, 0.0f, 1.0f ); grayTable[1] = new Basic::Hsva( hue, saturation, 0.0872f, 1.0f ); grayTable[2] = new Basic::Hsva( hue, saturation, 0.1736f, 1.0f ); grayTable[3] = new Basic::Hsva( hue, saturation, 0.2588f, 1.0f ); grayTable[4] = new Basic::Hsva( hue, saturation, 0.3420f, 1.0f ); grayTable[5] = new Basic::Hsva( hue, saturation, 0.4226f, 1.0f ); grayTable[6] = new Basic::Hsva( hue, saturation, 0.5000f, 1.0f ); grayTable[7] = new Basic::Hsva( hue, saturation, 0.5736f, 1.0f ); grayTable[8] = new Basic::Hsva( hue, saturation, 0.6428f, 1.0f ); grayTable[9] = new Basic::Hsva( hue, saturation, 0.7071f, 1.0f ); grayTable[10] = new Basic::Hsva( hue, saturation, 0.7660f, 1.0f ); grayTable[11] = new Basic::Hsva( hue, saturation, 0.8192f, 1.0f ); grayTable[12] = new Basic::Hsva( hue, saturation, 0.8660f, 1.0f ); grayTable[13] = new Basic::Hsva( hue, saturation, 0.9063f, 1.0f ); grayTable[14] = new Basic::Hsva( hue, saturation, 0.9397f, 1.0f ); grayTable[15] = new Basic::Hsva( hue, saturation, 0.9659f, 1.0f ); grayTable[16] = new Basic::Hsva( hue, saturation, 0.9848f, 1.0f ); grayTable[17] = new Basic::Hsva( hue, saturation, 0.9962f, 1.0f ); grayTable[18] = new Basic::Hsva( hue, saturation, 1.0f, 1.0f ); // Get antenna look angles antAzAngle = static_cast<LCreal>(ant->getAzimuthD()); antElAngle = static_cast<LCreal>(ant->getElevationD()); // Which ray are we on? LCreal halfRay = static_cast<LCreal>(IMG_WIDTH/2.0f); int ray = static_cast<int>(((antAzAngle/45.0f) * halfRay) + halfRay); if (ray < 0) ray = 0; if (ray > (IMG_WIDTH-1)) ray = (IMG_WIDTH-1); if (fpass) { ray0 = ray; fpass = false; } // --- // For all rays from ray0 to our current ray // --- int icol = ray0; while (icol != ray) { for (int irow = 0; irow < IMG_HEIGHT; irow++) { elevations[irow] = 0; aacData[irow] = 1.0; validFlgs[irow] = false; maskFlgs[irow] = false; } // Direction int xx = icol - (IMG_WIDTH/2); LCreal direction = 45.0 * static_cast<LCreal>(xx) / static_cast<LCreal>(IMG_WIDTH/2); // get a strip of elevations from south to north unsigned int num = terrain->getElevations(elevations, validFlgs, IMG_HEIGHT, latitude, longitude, direction, groundRange[IMG_HEIGHT-1], interpolate); // Apply earth curvature effects to terrain elevations for (int irow = 0; irow < IMG_HEIGHT; irow++) { elevations[irow] -= curvature[irow]; } // Generate Masks Basic::Terrain::vbwShadowChecker(maskFlgs, elevations, validFlgs, IMG_HEIGHT, groundRange[IMG_HEIGHT-1], altitude, antElAngle, beamWidth); // Compute AAC data Basic::Terrain::aac(aacData, elevations, maskFlgs, IMG_HEIGHT, groundRange[IMG_HEIGHT-1], altitude); // Draw a line along the Y points (moving from south to north along the latitude lines) for (int irow = 0; irow < IMG_HEIGHT; irow++) { LCreal sn = aacData[irow]; // convert to a color (or gray) value osg::Vec3 color(0,0,0); if (validFlgs[irow] && !maskFlgs[irow]) { Basic::Terrain::getElevationColor(sn, 0.0, 1.0, grayTable, 19, color); } // store this color int idx = irow*imgWidth*PIXEL_SIZE + icol*PIXEL_SIZE; image[idx+0] = static_cast<unsigned char>( 255.0 * color[0] ); image[idx+1] = static_cast<unsigned char>( 255.0 * color[1] ); image[idx+2] = static_cast<unsigned char>( 255.0 * color[2] ); } if (icol < ray) icol++; else if (icol > ray) icol--; } ray0 = ray; } }
void* new_protocol_thread(void* arg) { DISCOVERED* d=&discovered[selected_device]; struct sockaddr_in addr; int length; unsigned char buffer[2048]; int bytesread; short sourceport; long sequence; long long timestamp; int bitspersample; int samplesperframe; int b; int leftsample; int rightsample; float leftsamplefloat; float rightsamplefloat; int previous_ptt; int previous_dot; int previous_dash; int samples; //float leftinputbuffer[BUFFER_SIZE]; //float rightinputbuffer[BUFFER_SIZE]; double iqinputbuffer[BUFFER_SIZE*2]; int outputsamples; //float leftoutputbuffer[BUFFER_SIZE]; //float rightoutputbuffer[BUFFER_SIZE]; double audiooutputbuffer[BUFFER_SIZE*2]; short leftaudiosample; short rightaudiosample; long audiosequence; unsigned char audiobuffer[1444]; int audioindex; int micsample; float micsamplefloat; int micsamples; /* float micleftinputbuffer[BUFFER_SIZE]; // 48000 float micrightinputbuffer[BUFFER_SIZE]; */ double micinputbuffer[BUFFER_SIZE*2]; int micoutputsamples; /* float micleftoutputbuffer[BUFFER_SIZE*4]; // 192000 float micrightoutputbuffer[BUFFER_SIZE*4]; */ double micoutputbuffer[BUFFER_SIZE*4*2]; double gain; int isample; int qsample; long tx_iq_sequence; unsigned char iqbuffer[1444]; int iqindex; int i, j; fprintf(stderr,"new_protocol_thread: receiver=%d\n", receiver); micsamples=0; iqindex=4; switch(sample_rate) { case 48000: outputsamples=BUFFER_SIZE; break; case 96000: outputsamples=BUFFER_SIZE/2; break; case 192000: outputsamples=BUFFER_SIZE/4; break; case 384000: outputsamples=BUFFER_SIZE/8; break; case 768000: outputsamples=BUFFER_SIZE/16; break; case 1536000: outputsamples=BUFFER_SIZE/32; break; } micoutputsamples=BUFFER_SIZE*4; // 48000 in, 192000 out fprintf(stderr,"outputsamples=%d\n", outputsamples); data_socket=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP); if(data_socket<0) { fprintf(stderr,"metis: create socket failed for data_socket: receiver=%d\n",receiver); exit(-1); } int optval = 1; setsockopt(data_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); // bind to the interface if(bind(data_socket,(struct sockaddr*)&d->interface_address,d->interface_length)<0) { fprintf(stderr,"metis: bind socket failed for data_socket: receiver=%d\n",receiver); exit(-1); } memcpy(&base_addr,&d->address,d->address_length); base_addr_length=d->address_length; base_addr.sin_port=htons(GENERAL_REGISTERS_FROM_HOST_PORT); memcpy(&receiver_addr,&d->address,d->address_length); receiver_addr_length=d->address_length; receiver_addr.sin_port=htons(RECEIVER_SPECIFIC_REGISTERS_FROM_HOST_PORT); memcpy(&transmitter_addr,&d->address,d->address_length); transmitter_addr_length=d->address_length; transmitter_addr.sin_port=htons(TRANSMITTER_SPECIFIC_REGISTERS_FROM_HOST_PORT); memcpy(&high_priority_addr,&d->address,d->address_length); high_priority_addr_length=d->address_length; high_priority_addr.sin_port=htons(HIGH_PRIORITY_FROM_HOST_PORT); memcpy(&audio_addr,&d->address,d->address_length); audio_addr_length=d->address_length; audio_addr.sin_port=htons(AUDIO_FROM_HOST_PORT); memcpy(&iq_addr,&d->address,d->address_length); iq_addr_length=d->address_length; iq_addr.sin_port=htons(TX_IQ_FROM_HOST_PORT); memcpy(&data_addr,&d->address,d->address_length); data_addr_length=d->address_length; data_addr.sin_port=htons(RX_IQ_TO_HOST_PORT+receiver); samples=0; audioindex=4; // leave space for sequence audiosequence=0L; new_protocol_general(); new_protocol_start(); new_protocol_high_priority(1,0,drive); while(running) { bytesread=recvfrom(data_socket,buffer,sizeof(buffer),0,(struct sockaddr*)&addr,&length); if(bytesread<0) { fprintf(stderr,"recvfrom socket failed for new_protocol_thread: receiver=%d", receiver); exit(1); } short sourceport=ntohs(addr.sin_port); //fprintf(stderr,"received packet length %d from port %d\n",bytesread,sourceport); if(sourceport==RX_IQ_TO_HOST_PORT) { sequence=((buffer[0]&0xFF)<<24)+((buffer[1]&0xFF)<<16)+((buffer[2]&0xFF)<<8)+(buffer[3]&0xFF); timestamp=((long long)(buffer[4]&0xFF)<<56)+((long long)(buffer[5]&0xFF)<<48)+((long long)(buffer[6]&0xFF)<<40)+((long long)(buffer[7]&0xFF)<<32); ((long long)(buffer[8]&0xFF)<<24)+((long long)(buffer[9]&0xFF)<<16)+((long long)(buffer[10]&0xFF)<<8)+(long long)(buffer[11]&0xFF); bitspersample=((buffer[12]&0xFF)<<8)+(buffer[13]&0xFF); samplesperframe=((buffer[14]&0xFF)<<8)+(buffer[15]&0xFF); //fprintf(stderr,"samples per frame %d\n",samplesperframe); if(!isTransmitting()) { b=16; for(i=0; i<samplesperframe; i++) { leftsample = (int)((signed char) buffer[b++]) << 16; leftsample += (int)((unsigned char)buffer[b++]) << 8; leftsample += (int)((unsigned char)buffer[b++]); rightsample = (int)((signed char) buffer[b++]) << 16; rightsample += (int)((unsigned char)buffer[b++]) << 8; rightsample += (int)((unsigned char)buffer[b++]); leftsamplefloat=(float)leftsample/8388607.0; // for 24 bits rightsamplefloat=(float)rightsample/8388607.0; // for 24 bits //leftinputbuffer[samples]=leftsamplefloat; //rightinputbuffer[samples]=rightsamplefloat; iqinputbuffer[samples*2]=(double)leftsamplefloat; iqinputbuffer[(samples*2)+1]=(double)rightsamplefloat; samples++; if(samples==BUFFER_SIZE) { int error; fexchange0(CHANNEL_RX0+receiver, iqinputbuffer, audiooutputbuffer, &error); if(error!=0) { fprintf(stderr,"fexchange0 returned error: %d for receiver %d\n", error,receiver); } Spectrum0(1, CHANNEL_RX0+receiver, 0, 0, iqinputbuffer); for(j=0; j<outputsamples; j++) { leftaudiosample=(short)(audiooutputbuffer[j*2]*32767.0*volume); rightaudiosample=(short)(audiooutputbuffer[(j*2)+1]*32767.0*volume); audiobuffer[audioindex++]=leftaudiosample>>8; audiobuffer[audioindex++]=leftaudiosample; audiobuffer[audioindex++]=rightaudiosample>>8; audiobuffer[audioindex++]=rightaudiosample; if(audioindex>=sizeof(audiobuffer)) { // insert the sequence audiobuffer[0]=audiosequence>>24; audiobuffer[1]=audiosequence>>16; audiobuffer[2]=audiosequence>>8; audiobuffer[3]=audiosequence; // send the buffer if(sendto(data_socket,audiobuffer,sizeof(audiobuffer),0,(struct sockaddr*)&audio_addr,audio_addr_length)<0) { fprintf(stderr,"sendto socket failed for audio\n"); exit(1); } audioindex=4; audiosequence++; } } samples=0; } }
static void new_protocol_high_priority(int run,int tx,int drive) { unsigned char buffer[1444]; BAND *band=band_get_current_band(); //fprintf(stderr,"new_protocol_high_priority: run=%d tx=%d drive=%d tx_ant=0x%08x rx_ant=0x%08x\n", run, tx, drive, alex_tx_antenna, alex_rx_antenna); memset(buffer, 0, sizeof(buffer)); buffer[0]=high_priority_sequence>>24; buffer[1]=high_priority_sequence>>16; buffer[2]=high_priority_sequence>>8; buffer[3]=high_priority_sequence; buffer[4]=run|(tx<<1); long phase=(long)((4294967296.0*(double)ddsFrequency)/122880000.0); // rx buffer[9]=phase>>24; buffer[10]=phase>>16; buffer[11]=phase>>8; buffer[12]=phase; // tx (no split yet) buffer[329]=phase>>24; buffer[330]=phase>>16; buffer[331]=phase>>8; buffer[332]=phase; buffer[345]=drive; if(isTransmitting()) { buffer[1401]=band->OCtx; if(tune) { if(OCmemory_tune_time!=0) { struct timeval te; gettimeofday(&te,NULL); long long now=te.tv_sec*1000LL+te.tv_usec/1000; if(tune_timeout>now) { buffer[1401]|=OCtune; } } else { buffer[1401]|=OCtune; } } } else { buffer[1401]=band->OCrx; } // alex HPF filters /* if (frequency < 1800000) HPF <= 6'b100000; // bypass else if (frequency < 6500000) HPF <= 6'b010000; // 1.5MHz HPF else if (frequency < 9500000) HPF <= 6'b001000; // 6.5MHz HPF else if (frequency < 13000000) HPF <= 6'b000100; // 9.5MHz HPF else if (frequency < 20000000) HPF <= 6'b000001; // 13MHz HPF else HPF <= 6'b000010; // 20MHz HPF */ long filters=0x00000000; // set HPF if(ddsFrequency<1800000L) { filters|=ALEX_BYPASS_HPF; } else if(ddsFrequency<6500000L) { filters|=ALEX_1_5MHZ_HPF; } else if(ddsFrequency<9500000L) { filters|=ALEX_6_5MHZ_HPF; } else if(ddsFrequency<13000000L) { filters|=ALEX_9_5MHZ_HPF; } else if(ddsFrequency<20000000L) { filters|=ALEX_13MHZ_HPF; } else { filters|=ALEX_20MHZ_HPF; } // alex LPF filters /* if (frequency > 32000000) LPF <= 7'b0010000; // > 10m so use 6m LPF^M else if (frequency > 22000000) LPF <= 7'b0100000; // > 15m so use 12/10m LPF^M else if (frequency > 15000000) LPF <= 7'b1000000; // > 20m so use 17/15m LPF^M else if (frequency > 8000000) LPF <= 7'b0000001; // > 40m so use 30/20m LPF ^M else if (frequency > 4500000) LPF <= 7'b0000010; // > 80m so use 60/40m LPF^M else if (frequency > 2400000) LPF <= 7'b0000100; // > 160m so use 80m LPF ^M else LPF <= 7'b0001000; // < 2.4MHz so use 160m LPF^M */ if(ddsFrequency>32000000) { filters|=ALEX_6_BYPASS_LPF; } else if(ddsFrequency>22000000) { filters|=ALEX_12_10_LPF; } else if(ddsFrequency>15000000) { filters|=ALEX_17_15_LPF; } else if(ddsFrequency>8000000) { filters|=ALEX_30_20_LPF; } else if(ddsFrequency>4500000) { filters|=ALEX_60_40_LPF; } else if(ddsFrequency>2400000) { filters|=ALEX_80_LPF; } else { filters|=ALEX_160_LPF; } switch(band->alexRxAntenna) { case 0: // ANT 1 break; case 1: // ANT 2 break; case 2: // ANT 3 break; case 3: // EXT 1 //filters|=ALEX_RX_ANTENNA_EXT1; filters|=ALEX_RX_ANTENNA_EXT2; break; case 4: // EXT 2 //filters|=ALEX_RX_ANTENNA_EXT2; filters|=ALEX_RX_ANTENNA_EXT1; break; case 5: // XVTR filters|=ALEX_RX_ANTENNA_XVTR; break; } if(isTransmitting()) { switch(band->alexTxAntenna) { case 0: // ANT 1 filters|=ALEX_TX_ANTENNA_1; break; case 1: // ANT 2 filters|=ALEX_TX_ANTENNA_2; break; case 2: // ANT 3 filters|=ALEX_TX_ANTENNA_3; break; } } else { switch(band->alexRxAntenna) { case 0: // ANT 1 filters|=ALEX_TX_ANTENNA_1; break; case 1: // ANT 2 filters|=ALEX_TX_ANTENNA_2; break; case 2: // ANT 3 filters|=ALEX_TX_ANTENNA_3; break; case 3: // EXT 1 case 4: // EXT 2 case 5: // XVTR switch(band->alexTxAntenna) { case 0: // ANT 1 filters|=ALEX_TX_ANTENNA_1; break; case 1: // ANT 2 filters|=ALEX_TX_ANTENNA_2; break; case 2: // ANT 3 filters|=ALEX_TX_ANTENNA_3; break; } break; } } //filters|=alex_attenuation; if(tx) { filters|=0x08000000; } /* buffer[1420]=filters>>24; buffer[1421]=filters>>16; buffer[1422]=filters>>8; buffer[1423]=filters; */ buffer[1432]=filters>>24; buffer[1433]=filters>>16; buffer[1434]=filters>>8; buffer[1435]=filters; //buffer[1442]=attenuation; buffer[1443]=attenuation; //fprintf(stderr,"[4]=%02X\n", buffer[4]); //fprintf(stderr,"filters=%04X\n", filters); if(sendto(data_socket,buffer,sizeof(buffer),0,(struct sockaddr*)&high_priority_addr,high_priority_addr_length)<0) { fprintf(stderr,"sendto socket failed for high priority\n"); exit(1); } high_priority_sequence++; }
int vfo_update(void *data) { BANDSTACK_ENTRY* entry=bandstack_entry_get_current(); FILTER* band_filters=filters[entry->mode]; FILTER* band_filter=&band_filters[entry->filter]; if(vfo_surface) { cairo_t *cr; cr = cairo_create (vfo_surface); cairo_set_source_rgb (cr, 0, 0, 0); cairo_paint (cr); cairo_select_font_face(cr, "FreeMono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); char version[16]; char text[128]; if(radio->protocol==ORIGINAL_PROTOCOL) { sprintf(version,"%d.%d", radio->software_version/10, radio->software_version%10); } else { sprintf(version,"%d.%d.%d", radio->software_version/100, (radio->software_version%100)/10, radio->software_version%10); } switch(radio->protocol) { case ORIGINAL_PROTOCOL: case NEW_PROTOCOL: sprintf(text,"%s %s %s", radio->name, version, inet_ntoa(radio->info.network.address.sin_addr)); break; #ifdef LIMESDR case LIMESDR_PROTOCOL: sprintf(text,"%s\n", radio->name); break; #endif } cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); cairo_set_font_size(cr, 10); cairo_move_to(cr, 5, 15); cairo_show_text(cr, text); long long f=entry->frequencyA+ddsOffset; char sf[32]; sprintf(sf,"%0lld.%06lld MHz",f/(long long)1000000,f%(long long)1000000); cairo_set_font_size(cr, 28); if(isTransmitting()) { cairo_set_source_rgb(cr, 1, 0, 0); } else { cairo_set_source_rgb(cr, 0, 1, 0); } cairo_move_to(cr, 5, 38); cairo_show_text(cr, sf); cairo_set_font_size(cr, 12); if(rit==0) { cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); } else { cairo_set_source_rgb(cr, 0, 1, 0); } sprintf(sf,"RIT: %d Hz",rit); cairo_move_to(cr, (my_width/4)*3, 38); cairo_show_text(cr, sf); cairo_set_source_rgb(cr, 0, 1, 0); int s=0; while(steps[s]!=step && steps[s]!=0) { s++; } sprintf(sf,"Step %s",step_labels[s]); cairo_move_to(cr, my_width/2, 15); cairo_show_text(cr, sf); cairo_move_to(cr, (my_width/4)*3, 15); cairo_show_text(cr, getFrequencyInfo(f)); if(locked) { cairo_set_source_rgb(cr, 1, 0, 0); cairo_move_to(cr, 10, 50); cairo_show_text(cr, "Locked"); } if(function) { cairo_set_source_rgb(cr, 1, 0.5, 0); cairo_move_to(cr, 70, 50); cairo_show_text(cr, "Function"); } cairo_set_source_rgb(cr, 1, 1, 0); cairo_move_to(cr, 130, 50); cairo_show_text(cr, mode_string[entry->mode]); cairo_move_to(cr, 190, 50); cairo_show_text(cr, band_filter->title); cairo_move_to(cr, 250, 50); if(nr) { cairo_show_text(cr, "NR"); } if(nr2) { cairo_show_text(cr, "NR2"); } if(nb) { cairo_show_text(cr, "NB"); } if(nb2) { cairo_show_text(cr, "NB2"); } if(anf) { cairo_show_text(cr, "ANF"); } if(snb) { cairo_show_text(cr, "SNB"); } cairo_move_to(cr, 310, 50); switch(agc) { case AGC_OFF: cairo_show_text(cr, "AGC OFF"); break; case AGC_LONG: cairo_show_text(cr, "AGC LONG"); break; case AGC_SLOW: cairo_show_text(cr, "AGC SLOW"); break; case AGC_MEDIUM: cairo_show_text(cr, "AGC MEDIUM"); break; case AGC_FAST: cairo_show_text(cr, "AGC FAST"); break; } cairo_destroy (cr); gtk_widget_queue_draw (vfo); } else { fprintf(stderr,"vfo_update: no surface!\n"); } return 0; }