#include #include #include #include "globdef.h" #include "uidef.h" #include "fft1def.h" #include "fft2def.h" #include "fft3def.h" #include "seldef.h" #include "sigdef.h" #include "screendef.h" #include "vernr.h" #include "thrdef.h" #include "conf.h" #include "keyboard_def.h" #include "blnkdef.h" #include "caldef.h" #include "sdrdef.h" #include "txdef.h" #include "options.h" #if (USERS_EXTRA_PRESENT == 1) extern float users_extra_update_interval; extern double users_extra_time; void users_extra(void); #endif #define MAX_FILES 256 #define MAX_NAMLEN 36 #define DISKSAVE_X_SIZE 48*text_width #define DISKSAVE_Y_SIZE 6*text_height #define DISKSAVE_SCREEN_SIZE (DISKSAVE_X_SIZE*DISKSAVE_Y_SIZE) #define DEBMEM 64 void write_wav_header(int totbytes); fpos_t wav_wrpos; int sel_parm; int sel_line; void init_os_independent_globals(void) { int i; int *net_fds; net_fds=(void*)(&netfd); allow_parport=0; keyboard_buffer_ptr=0; keyboard_buffer_used=0; mouse_flag=0; lbutton_state=0; rbutton_state=0; new_lbutton_state=0; new_rbutton_state=0; // Make sure we know that no memory space is reserved yet. wg_waterf=NULL; bg_waterf=NULL; fft3_handle=NULL; hires_handle=NULL; fft1_handle=NULL; blanker_handle=NULL; baseband_handle=NULL; afc_handle=NULL; calmem_handle=NULL; rx_da_wrbuf=NULL; tx_da_wrbuf=NULL; vga_font=NULL; dx=NULL; // and that analog io is closed rx_audio_in=-1; rx_audio_out=-1; sdr=-1; rx_daout_block=0; tx_daout_block=0; tx_audio_in=-1; tx_audio_out=-1; tx_flag=0; // Clear flags workload_reset_flag=0; kill_all_flag=0; lir_errcod=0; for(i=0; i= 4095)goto txt_err; wgi=(void*)(graphtype_parptr[type]); k=0; max_intpar = graphtype_max_intpar[type]; max_floatpar = graphtype_max_floatpar[type]; for(i=0; i=4095)goto txt_err; sscanf(&parinfo[k],"[%d]",&wgi[i]); while(parinfo[k]!='\n' && k<4095)k++; if(k>=4095)goto txt_err; } if(max_floatpar < 0) { wgd=(void*)(&wgi[max_intpar]); for(i=0; i<-max_floatpar; i++) { while(parinfo[k]==' ' || parinfo[k]== '\n' )k++; j=0; while(parinfo[k]== graphtype_partexts_float[type][i][j]&&k<4095) { k++; j++; } if(graphtype_partexts_float[type][i][j] != 0)goto txt_err; while(parinfo[k]!='[' && k<4095)k++; if(k>=4095)goto txt_err; sscanf(&parinfo[k],"[%lf]",&wgd[i]); if(k>=4095)goto txt_err; while(parinfo[k]!='\n' && k<4095)k++; } } else { wgf=(void*)(&wgi[max_intpar]); for(i=0; i3) { lir_text(col,line,s); while(k==1 && ch != 10 ) { k=fread(&ch,1,1,file); if(ch==13)ch=10; } num++; line++; } if(line>screen_last_line) { line=2; col+=MAX_NAMLEN +5; if( col+MAX_NAMLEN+5 > screen_last_col)goto listfull; } if(k == 1 && num < MAX_FILES)goto get_name; listfull:; if(sel_line == -1)sel_line=lir_get_integer(42, 0, 3, 0,num-1); if(kill_all_flag) return; if(fsetpos(file, &fileptr[sel_line]))lirerr(1119); clear_screen(); } void get_parfile_name(char *s) { int i, ptr, eq; ptr=0; while(s[ptr]!=0 && s[ptr]!=' ') { if(s[ptr]==10 || s[ptr]==13 ) { savefile_parname[0]=0; s[ptr]=0; return; } ptr++; } s[ptr]=0; ptr++; while(s[ptr] == ' ')ptr++; i=0; eq=1; while(s[ptr]!=0 && s[ptr]!=' ' && s[ptr] != 10 && s[ptr] != 13 && i<40) { savefile_parname[i]=s[ptr]; if(s[i] != s[ptr])eq=0; i++; ptr++; } if(i!=0 && eq==1)lirerr(1120); if(i>= 40)lirerr(1115); savefile_parname[i]=0; } int init_wavread(int sel_file) { char s[80]; FILE *file; int i, k, chunk_size; short int ishort; int errnr; clear_screen(); file = fopen("adwav", "rb"); if (file == NULL) { file = fopen("adwav.txt", "rb"); if (file == NULL) { help_message(313); return 1; } } if(sel_file != 0) { select_namlin(s,file); if(kill_all_flag) return 1; } for(i=0; i<80; i++)s[i]=0; fread(&s , 1, 70, file); fclose(file); get_parfile_name(s); if(lir_errcod != 0)return 1; save_file = fopen(s, "rb"); if (save_file == NULL) { lir_text(5,4,"Can not open file"); lir_text(5,5,s); rdfile_x:; await_keyboard(); return 1; } // Read the WAV file header. // First 4 bytes should be "RIFF" k=fread(&i,sizeof(int),1,save_file); errnr=0; if(k !=1 || i != 0x46464952) { errnr=1; headerr:; lir_text(5,5,s); sprintf(s,"Error in .wav file header [%d]",errnr); lir_text(5,4,s); goto rdfile_x; } // Read file size (we do not need it) fread(&i,sizeof(int),1,save_file); // Now we should read "WAVE" k=fread(&i,sizeof(int),1,save_file); errnr=2; if(k !=1 || i != 0x45564157)goto headerr; // Now we should read "fmt " k=fread(&i,sizeof(int),1,save_file); errnr=3; if(k !=1 || i != 0x20746d66)goto headerr; // read the size of the format chunk. k=fread(&chunk_size,sizeof(int),1,save_file); errnr=4; if(k !=1 )goto headerr; // read the type of data (Format Tag). We only recognize PCM data! k=fread(&ishort,sizeof(short int),1,save_file); errnr=5; if(k !=1 || ishort != 1) { lir_text(5,3,"Unknown WAVE format. (PCM only accepted)"); goto headerr; } // Read no of channels k=fread(&ishort,sizeof(short int),1,save_file); errnr=6; if(k !=1 || ishort < 1 || ishort > 2)goto headerr; ui.rx_ad_channels=ishort; ui.rx_rf_channels=ishort; ui.rx_input_mode=0; // Read the sampling speed. k=fread(&ui.rx_ad_speed,sizeof(int),1,save_file); errnr=7; if(k !=1 )goto headerr; // Read average bytes per second (do not care what it is) errnr=8; k=fread(&i,sizeof(int),1,save_file); if(k !=1 )goto headerr; // Read block align to get 8 or 16 bit format. k=fread(&ishort,sizeof(short int),1,save_file); errnr=9; if(k !=1 )goto headerr; errnr=10; ishort/=ui.rx_rf_channels; switch (ishort) { case 1: ui.rx_input_mode+=BYTE_INPUT; break; case 2: break; case 3: ui.rx_input_mode+=BYTE_INPUT; ui.rx_input_mode+=DWORD_INPUT; break; default: goto headerr; } // Skip extra bytes if present. chunk_size-=14; skip_chunk:; errnr=11; while(chunk_size != 0) { k=fread(&i,1,1,save_file); if(k !=1 )goto headerr; chunk_size--; } // Read chunks until we encounter the "data" string. k=fread(&i,sizeof(int),1,save_file); errnr=12; if(k !=1 || i != 0x61746164) { k=fread(&chunk_size,sizeof(int),1,save_file); if(k !=1 )goto headerr; goto skip_chunk; } // Read how much data we have ( do not care) fread(&i,sizeof(int),1,save_file); disksave_flag=2; save_init_flag=0; diskread_time=0; fg.passband_center=0; fg.passband_direction=0; fft1_direction=fg.passband_direction; return 0; } void parfile_end(FILE *file) { fprintf(file,"\nChange only between brackets."); fprintf(file,"\nIf file has errors, Linrad will ignore file and prompt"); fprintf(file,"\nfor a complete set of new parameters\n"); fprintf(file,"\n%s",PROGRAM_NAME); fclose(file); } int init_diskread(int sel_file) { char s[80]; FILE *file; int i,kk; if(sel_file != -1) { sel_parm=sel_file; sel_line=-1; } kk=sel_parm; if( wav_read_flag != 0) { return init_wavread(kk); } clear_screen(); file = fopen("adfile", "rb"); if (file == NULL) { file = fopen("adfile.txt", "rb"); if (file == NULL) { help_message(314); return 1; } } if(kk != 0) { select_namlin(s,file); if(kill_all_flag) return 1; } for(i=0; i<80; i++)s[i]=0; fread(&s , 1, 70, file); fclose(file); get_parfile_name(s); if(lir_errcod != 0)return 1; for(i=0;i<80;i++)if(s[i]==10)s[i]=0; save_file = fopen(s, "rb"); if (save_file == NULL) { errfile:; lir_text(5,4,"Can not open file"); lir_text(5,5,s); await_keyboard(); return 1; } disksave_flag=2; fread(&ui.rx_input_mode,sizeof(int),1,save_file); // In case ui.rx_input_mode is negative the file contains more data. if(ui.rx_input_mode < 0) { fread(&diskread_time,sizeof(double),1,save_file); fread(&fg.passband_center,sizeof(double),1,save_file); fread(&fg.passband_direction,sizeof(int),1,save_file); if(abs(fg.passband_direction) != 1)goto errfile; fft1_direction=fg.passband_direction; fread(&ui.rx_input_mode,sizeof(int),1,save_file); } else { diskread_time=0; fg.passband_center=0; fg.passband_direction=1; fft1_direction=fg.passband_direction; } fread(&ui.rx_rf_channels,sizeof(int),1,save_file); if(ui.rx_input_mode >= MODEPARM_MAX)goto errfile; fread(&ui.rx_ad_channels,sizeof(int),1,save_file); if(ui.rx_ad_channels > 4 || ui.rx_ad_channels < 1)goto errfile; fread(&ui.rx_ad_speed,sizeof(int),1,save_file); save_init_flag=0; fread(&save_init_flag,1,1,save_file); return 0; } void disksave_start_stop(void) { FILE *fc_file, *iq_file; int i; double dt1; char raw_filename[160]; char s[160]; char indicator[2]; char *disksave_screencopy; char *raw={".raw"}; indicator[0]=' '; if( (disksave_flag & 0xfffe) == 0) { if(disksave_flag == 0) { pause_thread(THREAD_SCREEN); indicator[0]='S'; disksave_screencopy=malloc(DISKSAVE_SCREEN_SIZE); if(disksave_screencopy == NULL) { lirerr(1047); return; } lir_getbox(0,0,DISKSAVE_X_SIZE,DISKSAVE_Y_SIZE,disksave_screencopy); lir_fillbox(0,0,DISKSAVE_X_SIZE,DISKSAVE_Y_SIZE,10); lir_text(0,1,"Enter file name for raw data."); lir_text(0,2,"ENTER to skip."); lir_text(0,3,"=>"); i=lir_get_filename(2,3,s); if(kill_all_flag) return; if(i==0) { indicator[0]=' '; disksave_flag = 0; } else { if( i<4 || (i > 4 && strcmp(&s[i-4],raw) !=0)) { strcpy(&s[i],raw); } if(s[0] != '/' && s[0]!= '.') { sprintf(raw_filename,"%s%s",RAWDIR,s); } else { strcpy(raw_filename,s); } save_file = fopen( raw_filename, "wb"); if(save_file == NULL) { could_not_create(raw_filename); if(kill_all_flag) return; disksave_flag = 0; } else { // Write -1 as a flag telling what version number of Linrad raw data file // we are writing. i=-1; fwrite(&i,sizeof(int),1,save_file); dt1=current_time(); fwrite(&dt1,sizeof(double),1,save_file); fwrite(&fg.passband_center,sizeof(double),1,save_file); fwrite(&fg.passband_direction,sizeof(int),1,save_file); // Write mode info so we know how to process data when reading fwrite(&ui.rx_input_mode,sizeof(int),1,save_file); fwrite(&ui.rx_rf_channels,sizeof(int),1,save_file); fwrite(&ui.rx_ad_channels,sizeof(int),1,save_file); fwrite(&ui.rx_ad_speed,sizeof(int),1,save_file); save_init_flag=0; iq_file=NULL; fc_file=NULL; if( (fft1_calibrate_flag&CALAMP) == CALAMP) { make_filfunc_filename(s); fc_file = fopen(s, "rb"); if(fc_file != NULL) { save_init_flag=1; } else { lirerr(1062); return; } } if( (ui.rx_input_mode&IQ_DATA) != 0 && (fft1_calibrate_flag&CALIQ) == CALIQ) { make_iqcorr_filename(s); iq_file = fopen(s, "rb"); if(iq_file != NULL) { save_init_flag+=2; } else { lirerr(1062); return; } } fwrite(&save_init_flag,1,1,save_file); if( (save_init_flag & 1) == 1) { rd1:; i=fread(&s,1,1,fc_file); if(i != 0) { fwrite(&s,1,1,save_file); goto rd1; } fclose(fc_file); fc_file=NULL; } if( (save_init_flag & 2) == 2) { rd2:; i=fread(&s,1,1,iq_file); if(i != 0) { fwrite(&s,1,1,save_file); goto rd2; } fclose(iq_file); iq_file=NULL; } } } lir_putbox(0,0,DISKSAVE_X_SIZE,DISKSAVE_Y_SIZE,disksave_screencopy); free(disksave_screencopy); resume_thread(THREAD_SCREEN); disksave_flag=1; } else { disksave_flag=0; lir_sleep(200000); fclose(save_file); save_file=NULL; } } indicator[1]=0; settextcolor(14); i=wg.xright-text_width-2; if(i<2)i=2; lir_pixwrite(i,wg.yborder+2,indicator); settextcolor(7); } void wavsave_start_stop(void) { int i; char s[160],wav_filename[160]; char *wav_write_screencopy; char indicator[2]; char *wav={".wav"}; indicator[0]=' '; if( wav_write_flag == 0) { pause_thread(THREAD_SCREEN); indicator[0]='W'; wav_write_screencopy=malloc(DISKSAVE_SCREEN_SIZE); if(wav_write_screencopy == NULL) { lirerr(1047); return; } lir_getbox(0,0,DISKSAVE_X_SIZE,DISKSAVE_Y_SIZE,wav_write_screencopy); lir_fillbox(0,0,DISKSAVE_X_SIZE,DISKSAVE_Y_SIZE,10); lir_text(0,1,"Enter name for audio output file"); lir_text(0,2,"ENTER to skip."); lir_text(0,3,"=>"); i=lir_get_filename(2,3,s); if(kill_all_flag) return; if(i==0) { indicator[0]=' '; wav_write_flag = 0; } else { if( i<4 || (i > 4 && strcmp(&s[i-4],wav) !=0)) { strcpy(&s[i],wav); } if(s[0] != '/' && s[0]!= '.') { sprintf(wav_filename,"%s%s",RAWDIR,s); } else { strcpy(wav_filename,s); } wav_file = fopen( wav_filename, "wb"); if(wav_file == NULL) { could_not_create(wav_filename); await_keyboard(); } else { // Write the .wav header, but make the file size gigantic // We will write the correct size when closing, but if // system crashes we can fix the header and recover data. // Speed, channels and bits will be ok. Size will indicate loss of data. write_wav_header(0x7fffffff); wavfile_bytes=0; fflush(wav_file); lir_sync(); wav_write_flag=1; } } lir_putbox(0,0,DISKSAVE_X_SIZE,DISKSAVE_Y_SIZE,wav_write_screencopy); free(wav_write_screencopy); resume_thread(THREAD_SCREEN); } else { wav_write_flag = 0; lir_sleep(200000); write_wav_header(wavfile_bytes); fclose(wav_file); lir_sync(); } indicator[1]=0; settextcolor(14); i=wg.xright-2*text_width-2; if(i<2)i=2; lir_pixwrite(i,wg.yborder+2,indicator); settextcolor(7); } void write_wav_header(int totbytes) { int i; // Write the header for a .wav file using the current output // settings. // First point to start of file. if(totbytes == 0x7fffffff) { if(fgetpos(wav_file, &wav_wrpos)) { lirerr(1114); return; } } else { if(fsetpos(wav_file, &wav_wrpos) != 0) { lirerr(1111); return; } } // First 4 bytes should be "RIFF" if(fwrite("RIFF",sizeof(int),1,wav_file)!= 1) { headerr:; lirerr(1112); return; } // Now file size in bytes -8 // The format chunk uses 16 bytes. i=totbytes+16; if(fwrite(&i,sizeof(int),1,wav_file)!= 1)goto headerr; // The next code word pair is "WAVEfmt " if(fwrite("WAVEfmt ",sizeof(int),2,wav_file)!= 2)goto headerr; // Write the size of the format chunk = 16 i=16; if(fwrite(&i,sizeof(int),1,wav_file)!= 1)goto headerr; // Write the type of data (Format Tag = 1 for PCM data) i=1; if(fwrite(&i,sizeof(short int),1,wav_file)!=1)goto headerr; // Write no of channels if(fwrite(&rx_daout_channels,sizeof(short int),1,wav_file)!=1)goto headerr; // Write the output speed. if(fwrite(&genparm[DA_OUTPUT_SPEED],sizeof(int),1,wav_file)!=1)goto headerr; i=genparm[DA_OUTPUT_SPEED]*rx_daout_bytes; // Write average bytes per second. if(fwrite(&i,sizeof(int),1,wav_file)!=1)goto headerr; i=rx_daout_channels*rx_daout_bytes; // Write block align. if(fwrite(&i,sizeof(short int),1,wav_file)!=1)goto headerr; // Write bits per sample i=8*rx_daout_bytes; if(fwrite(&i,sizeof(short int),1,wav_file)!=1)goto headerr; // Now write the code word "data" if(fwrite("data",sizeof(int),1,wav_file)!=1)goto headerr; // And finally the size of the data block if(fwrite(&totbytes,sizeof(int),1,wav_file)!=1)goto headerr; } void init_memalloc(MEM_INF *mm, int max) { memalloc_no=0; memalloc_max=max; memalloc_mem=mm; } void mem(int num, void *pointer, int size, int scratch_size) { if(lir_errcod !=0)return; // Skip if outside array. Error code will come on return from memalloc. if(memalloc_no<0 || memalloc_no>=memalloc_max)goto skip; memalloc_mem[memalloc_no].pointer=pointer; if(size<0) { lirerr(1125); return; } memalloc_mem[memalloc_no].size=(size+15)&0xfffffff0; memalloc_mem[memalloc_no].scratch_size=(scratch_size+15)&0xfffffff0; memalloc_mem[memalloc_no].num=num; skip:; memalloc_no++; } int memalloc( int *handle, char *s) { int i,j,k,totbytes; char *x; int *ptr; if(memalloc_no<0 || memalloc_no >= memalloc_max)lirerr(1136); if(lir_errcod != 0)return 0; memalloc_mem[memalloc_no].pointer=s; memalloc_mem[memalloc_no].size=-1; totbytes=16+DEBMEM; for(i=0; i 120)imax=120; i=0; while(s[i]!=0 && i