mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-30 12:30:23 -04:00 
			
		
		
		
	Actually add the new wsprsim files this time.
git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@5608 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
		
							parent
							
								
									8cf80a851d
								
							
						
					
					
						commit
						3723b66ddb
					
				
							
								
								
									
										124
									
								
								lib/wsprd/unpk.c.obsolete
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								lib/wsprd/unpk.c.obsolete
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,124 @@ | |||||||
|  | /* the routine unpk() is not in wsprd_utils.c */ | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <math.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <time.h> | ||||||
|  | 
 | ||||||
|  | #include "wsprd_utils.h" | ||||||
|  | 
 | ||||||
|  | unsigned int nhash_( const void *key, size_t length, uint32_t initval); | ||||||
|  | 
 | ||||||
|  | void unpk_(signed char message[], int *nhashtab, char call_loc_pow[]) | ||||||
|  | { | ||||||
|  |   int i,n1,n2,n3,ndbm,ihash,nadd,noprint,nh; | ||||||
|  |   char callsign[13],grid[5],grid6[7],cdbm[3]; | ||||||
|  |   static char hashtab[32768][13]; | ||||||
|  |   FILE *fhash; | ||||||
|  | 
 | ||||||
|  |   if(*nhashtab==1) { | ||||||
|  |     char line[80], hcall[12]; | ||||||
|  |     if( (fhash=fopen("hashtable.txt","r+")) ) { | ||||||
|  |       while (fgets(line, sizeof(line), fhash) != NULL) { | ||||||
|  | 	sscanf(line,"%d %s",&nh,hcall); | ||||||
|  | 	strcpy(*hashtab+nh*13,hcall); | ||||||
|  |       } | ||||||
|  |     } else { | ||||||
|  |       fhash=fopen("hashtable.txt","w+"); | ||||||
|  |     } | ||||||
|  |     fclose(fhash); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if(*nhashtab==2) { | ||||||
|  |     fhash=fopen("hashtable.txt","w"); | ||||||
|  |     for (i=0; i<32768; i++) { | ||||||
|  |       if( strncmp(hashtab[i],"\0",1) != 0 ) { | ||||||
|  | 	fprintf(fhash,"%5d %s\n",i,*hashtab+i*13); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     fclose(fhash); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   unpack50(message,&n1,&n2); | ||||||
|  |   unpackcall(n1,callsign); | ||||||
|  |   unpackgrid(n2, grid); | ||||||
|  |   int ntype = (n2&127) - 64; | ||||||
|  |   callsign[12]=0; | ||||||
|  |   grid[4]=0; | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  Based on the value of ntype, decide whether this is a Type 1, 2, or  | ||||||
|  |  3 message. | ||||||
|  | 
 | ||||||
|  |  * Type 1: 6 digit call, grid, power - ntype is positive and is a member  | ||||||
|  |          of the set {0,3,7,10,13,17,20...60} | ||||||
|  | 
 | ||||||
|  |  * Type 2: extended callsign, power - ntype is positive but not | ||||||
|  |          a member of the set of allowed powers | ||||||
|  | 
 | ||||||
|  |  * Type 3: hash, 6 digit grid, power - ntype is negative. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  |   if( (ntype >= 0) && (ntype <= 62) ) { | ||||||
|  |     int nu=ntype%10; | ||||||
|  |     if( nu == 0 || nu == 3 || nu == 7 ) { | ||||||
|  |       ndbm=ntype; | ||||||
|  |       memset(call_loc_pow,0,sizeof(char)*23); | ||||||
|  |       sprintf(cdbm,"%2d",ndbm); | ||||||
|  |       strncat(call_loc_pow,callsign,strlen(callsign)); | ||||||
|  |       strncat(call_loc_pow," ",1); | ||||||
|  |       strncat(call_loc_pow,grid,4); | ||||||
|  |       strncat(call_loc_pow," ",1); | ||||||
|  |       strncat(call_loc_pow,cdbm,2); | ||||||
|  |       strncat(call_loc_pow,"\0",1); | ||||||
|  |       ihash=nhash_(callsign,strlen(callsign),(uint32_t)146); | ||||||
|  |       strcpy(*hashtab+ihash*13,callsign); | ||||||
|  |     } else { | ||||||
|  |       nadd=nu; | ||||||
|  |       if( nu > 3 ) nadd=nu-3; | ||||||
|  |       if( nu > 7 ) nadd=nu-7; | ||||||
|  |       n3=n2/128+32768*(nadd-1); | ||||||
|  |       unpackpfx(n3,callsign); | ||||||
|  |       ndbm=ntype-nadd; | ||||||
|  |       memset(call_loc_pow,0,sizeof(char)*23); | ||||||
|  |       sprintf(cdbm,"%2d",ndbm); | ||||||
|  |       strncat(call_loc_pow,callsign,strlen(callsign)); | ||||||
|  |       strncat(call_loc_pow," ",1); | ||||||
|  |       strncat(call_loc_pow,cdbm,2); | ||||||
|  |       strncat(call_loc_pow,"\0",1); | ||||||
|  |       ihash=nhash_(callsign,strlen(callsign),(uint32_t)146); | ||||||
|  |       strcpy(*hashtab+ihash*13,callsign); | ||||||
|  |       noprint=0; | ||||||
|  |     } | ||||||
|  |   } else if ( ntype < 0 ) { | ||||||
|  |     ndbm=-(ntype+1); | ||||||
|  |     memset(grid6,0,sizeof(char)*7); | ||||||
|  |     strncat(grid6,callsign+5,1); | ||||||
|  |     strncat(grid6,callsign,5); | ||||||
|  |     ihash=(n2-ntype-64)/128; | ||||||
|  |     if( strncmp(hashtab[ihash],"\0",1) != 0 ) { | ||||||
|  |       sprintf(callsign,"<%s>",hashtab[ihash]); | ||||||
|  |     } else { | ||||||
|  |       sprintf(callsign,"%5s","<...>"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     memset(call_loc_pow,0,sizeof(char)*23); | ||||||
|  |     sprintf(cdbm,"%2d",ndbm); | ||||||
|  |     strncat(call_loc_pow,callsign,strlen(callsign)); | ||||||
|  |     strncat(call_loc_pow," ",1); | ||||||
|  |     strncat(call_loc_pow,grid6,strlen(grid6)); | ||||||
|  |     strncat(call_loc_pow," ",1); | ||||||
|  |     strncat(call_loc_pow,cdbm,2); | ||||||
|  |     strncat(call_loc_pow,"\0",1); | ||||||
|  |                  | ||||||
|  |     noprint=0; | ||||||
|  |                  | ||||||
|  | // I don't know what to do with these... They show up as "A000AA" grids. | ||||||
|  |     if( ntype == -64 ) noprint=1;   | ||||||
|  |   } | ||||||
|  |   //  printf("\nUnpacked in C:    %s\n",call_loc_pow); | ||||||
|  | } | ||||||
							
								
								
									
										202
									
								
								lib/wsprd/wsprsim.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								lib/wsprd/wsprsim.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,202 @@ | |||||||
|  | /*
 | ||||||
|  |  File name: wsprsim.c (first committed to wsjtx June 13, 2015) | ||||||
|  |  */ | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <math.h> | ||||||
|  | #include <string.h> | ||||||
|  | 
 | ||||||
|  | #include "wsprsim_utils.h" | ||||||
|  | #include "wsprd_utils.h" | ||||||
|  | #include "fano.h" | ||||||
|  | 
 | ||||||
|  | int printdata=0; | ||||||
|  | 
 | ||||||
|  | void usage() { | ||||||
|  |     printf("Usage: wsprsim [options] message\n"); | ||||||
|  |     printf("       message format:   \"K1ABC FN42 33\"\n"); | ||||||
|  |     printf("                         \"PJ4/K1ABC 33\"\n"); | ||||||
|  |     printf("                         \"<PJ4/K1ABC> FK52UD 33\"\n"); | ||||||
|  |     printf("Options:\n"); | ||||||
|  |     printf("       -c   (print channel symbols)\n"); | ||||||
|  |     printf("       -d   (print packed data with zero tail - 11 bytes)\n"); | ||||||
|  |     printf("       -o filename (write a c2 file with this name)\n"); | ||||||
|  |     printf("       -s x (x is snr of signal that is written to .c2 file)\n"); | ||||||
|  |     printf("\n"); | ||||||
|  |     printf(" e.g. ./wsprsim -cds -28 -o 150613_1920.c2 \"K1ABC FN42 33\"\n"); | ||||||
|  |     printf(" then ./wsprd 150613_1920.c2\n"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int add_signal_vector(float f0, float t0, float amp, unsigned char* symbols | ||||||
|  |                       , double* isig, double* qsig) | ||||||
|  | { | ||||||
|  |     int i, j, ii, idelay; | ||||||
|  |     double phi=0.0, twopidt, df, dt, dphi; | ||||||
|  |     twopidt=8.0*atan(1.0)/375.0; | ||||||
|  |     df=375.0/256.0; | ||||||
|  |     dt=1/375.0; | ||||||
|  |     idelay=t0/dt; | ||||||
|  |      | ||||||
|  |     for (i=0; i<162; i++) { | ||||||
|  |         dphi=twopidt*(f0 + ( (double)symbols[i]-1.5)*df ); | ||||||
|  |         for ( j=0; j<256; j++ ) { | ||||||
|  |             ii=idelay+256*i+j; | ||||||
|  |             isig[ii]=isig[ii]+amp*cos(phi); | ||||||
|  |             qsig[ii]=qsig[ii]+amp*sin(phi); | ||||||
|  |             phi=phi+dphi; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char* tobinary(int x) | ||||||
|  | { | ||||||
|  |     static char b[33]; | ||||||
|  |     b[0] = '\0'; | ||||||
|  |      | ||||||
|  |     long unsigned int z; | ||||||
|  |     for (z = 0x80000000; z > 0; z >>= 1) | ||||||
|  |     { | ||||||
|  |         strcat(b, ((x & z) == z) ? "1" : "0"); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     return b; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | double gaussrand() | ||||||
|  | { | ||||||
|  |     static double V1, V2, S; | ||||||
|  |     static int phase = 0; | ||||||
|  |     double X; | ||||||
|  |      | ||||||
|  |     if(phase == 0) { | ||||||
|  |         do { | ||||||
|  |             double U1 = (double)rand() / RAND_MAX; | ||||||
|  |             double U2 = (double)rand() / RAND_MAX; | ||||||
|  |              | ||||||
|  |             V1 = 2 * U1 - 1; | ||||||
|  |             V2 = 2 * U2 - 1; | ||||||
|  |             S = V1 * V1 + V2 * V2; | ||||||
|  |         } while(S >= 1 || S == 0); | ||||||
|  |          | ||||||
|  |         X = V1 * sqrt(-2 * log(S) / S); | ||||||
|  |     } else | ||||||
|  |         X = V2 * sqrt(-2 * log(S) / S); | ||||||
|  |      | ||||||
|  |     phase = 1 - phase; | ||||||
|  |      | ||||||
|  |     return X; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | unsigned long writec2file(char *c2filename, int trmin, double freq | ||||||
|  |                           , double *idat, double *qdat) | ||||||
|  | { | ||||||
|  |     int i; | ||||||
|  |     float buffer[2*45000]; | ||||||
|  |     memset(buffer,0,sizeof(float)*2*45000); | ||||||
|  |     FILE *fp; | ||||||
|  |      | ||||||
|  |     fp = fopen(c2filename,"wb"); | ||||||
|  |     if( fp == NULL ) { | ||||||
|  |         fprintf(stderr, "Could not open c2 file '%s'\n", c2filename); | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  |     unsigned long nwrite = fwrite(c2filename,sizeof(char),14,fp); | ||||||
|  |     nwrite = fwrite(&trmin, sizeof(int), 1, fp); | ||||||
|  |     nwrite = fwrite(&freq, sizeof(double), 1, fp); | ||||||
|  |      | ||||||
|  |     for(i=0; i<45000; i++) { | ||||||
|  |         buffer[2*i]=idat[i]; | ||||||
|  |         buffer[2*i+1]=-qdat[i]; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     nwrite = fwrite(buffer, sizeof(float), 2*45000, fp); | ||||||
|  |     if( nwrite == 2*45000 ) { | ||||||
|  |         return nwrite; | ||||||
|  |     } else { | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //********************************************************************
 | ||||||
|  | int main(int argc, char *argv[]) | ||||||
|  | { | ||||||
|  |     extern char *optarg; | ||||||
|  |     extern int optind; | ||||||
|  |     int i, c, printchannel=0; | ||||||
|  |     float snr=50.0; | ||||||
|  |     char *message, *c2filename; | ||||||
|  |     // message length is 22 characters
 | ||||||
|  |     message=malloc(sizeof(char)*23); | ||||||
|  |     c2filename=malloc(sizeof(char)*15); | ||||||
|  |     memset(c2filename,0,sizeof(char)*15); | ||||||
|  |      | ||||||
|  |     while ( (c = getopt(argc, argv, "cdo:s:")) !=-1 ) { | ||||||
|  |         switch (c) { | ||||||
|  |             case 'c': | ||||||
|  |                 printchannel=1; | ||||||
|  |             case 'd': | ||||||
|  |                 printdata=1; | ||||||
|  |             case 'o': | ||||||
|  |                 c2filename = optarg; | ||||||
|  |                 break; | ||||||
|  |             case 's': | ||||||
|  |                 snr = (float)atoi(optarg); | ||||||
|  |                 break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     if( optind+1 > argc ) { | ||||||
|  |         usage(); | ||||||
|  |         return 0; | ||||||
|  |     } else { | ||||||
|  |         message=argv[optind]; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     unsigned char channel_symbols[162]; | ||||||
|  |     get_wspr_channel_symbols(message, channel_symbols); | ||||||
|  |      | ||||||
|  |     if( printchannel ) { | ||||||
|  |         printf("Channel symbols:\n"); | ||||||
|  |         for (i=0; i<162; i++) { | ||||||
|  |             printf("%d ",channel_symbols[i]); | ||||||
|  |         } | ||||||
|  |         printf("\n"); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // add noise, then signal
 | ||||||
|  |     double isig[45000], qsig[45000]; | ||||||
|  |     memset(isig,0,sizeof(double)*45000); | ||||||
|  |     memset(qsig,0,sizeof(double)*45000); | ||||||
|  |      | ||||||
|  |     if( snr < 40 ) { | ||||||
|  |         // snr in 375Hz is 8.2 dB higher than in 2500 Hz.
 | ||||||
|  |         snr=snr+8.2; | ||||||
|  |         snr=pow(10,snr/20.0)*pow(2,0.5); | ||||||
|  | 
 | ||||||
|  |         for (i = 0; i<45000; i++) { | ||||||
|  |             isig[i]=isig[i]+gaussrand(); | ||||||
|  |             qsig[i]=qsig[i]+gaussrand(); | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         snr=1.0; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     float f0, t0; | ||||||
|  |     f0=0.0; | ||||||
|  |     t0=1.0; | ||||||
|  |     add_signal_vector(f0, t0, snr, channel_symbols, isig, qsig); | ||||||
|  |      | ||||||
|  |     if( strlen(c2filename) >0 ) { | ||||||
|  |         // write a .c2 file
 | ||||||
|  |         double carrierfreq=10.1387; | ||||||
|  |         int wsprtype=2; | ||||||
|  |         if( strlen(c2filename) != 14 ) { | ||||||
|  |             strcpy(c2filename,"000000_0001.c2"); | ||||||
|  |         } | ||||||
|  |         printf("Writing %s\n",c2filename); | ||||||
|  |         writec2file(c2filename, wsprtype, carrierfreq, isig, qsig); | ||||||
|  |     } | ||||||
|  |     return 1; | ||||||
|  | } | ||||||
							
								
								
									
										304
									
								
								lib/wsprd/wsprsim_utils.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										304
									
								
								lib/wsprd/wsprsim_utils.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,304 @@ | |||||||
|  | /*
 | ||||||
|  |  Functions used by wsprsim | ||||||
|  |  */ | ||||||
|  | #include "wsprsim_utils.h" | ||||||
|  | #include "wsprd_utils.h" | ||||||
|  | #include "nhash.h" | ||||||
|  | #include "fano.h" | ||||||
|  | 
 | ||||||
|  | char get_locator_character_code(char ch) { | ||||||
|  |     if( ch >=48 && ch <=57 ) { //0-9
 | ||||||
|  |         return ch-48; | ||||||
|  |     } | ||||||
|  |     if( ch == 32 ) {  //space
 | ||||||
|  |         return 36; | ||||||
|  |     } | ||||||
|  |     if( ch >= 65 && ch <= 82 ) { //A-Z
 | ||||||
|  |         return ch-65; | ||||||
|  |     } | ||||||
|  |     return -1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char get_callsign_character_code(char ch) { | ||||||
|  |     if( ch >=48 && ch <=57 ) { //0-9
 | ||||||
|  |         return ch-48; | ||||||
|  |     } | ||||||
|  |     if( ch == 32 ) {  //space
 | ||||||
|  |         return 36; | ||||||
|  |     } | ||||||
|  |     if( ch >= 65 && ch <= 90 ) { //A-Z
 | ||||||
|  |         return ch-55; | ||||||
|  |     } | ||||||
|  |     return -1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | long unsigned int pack_grid4_power(char *grid4, int power) { | ||||||
|  |     long unsigned int m; | ||||||
|  |      | ||||||
|  |     m=(179-10*grid4[0]-grid4[2])*180+10*grid4[1]+grid4[3]; | ||||||
|  |     m=m*128+power+64; | ||||||
|  |     return m; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | long unsigned int pack_call(char *callsign) { | ||||||
|  |     int i; | ||||||
|  |     long unsigned int n; | ||||||
|  |     char call6[6]; | ||||||
|  |     memset(call6,32,sizeof(char)*6); | ||||||
|  |     // callsign is 6 characters in length. Exactly.
 | ||||||
|  |     int call_len = strlen(callsign); | ||||||
|  |     if( call_len > 6 ) { | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  |     if( isdigit(*(callsign+2)) ) { | ||||||
|  |         for (i=0; i<6; i++) { | ||||||
|  |             call6[i]=*(callsign+i); | ||||||
|  |         } | ||||||
|  |     } else if( isdigit(*(callsign+1)) ) { | ||||||
|  |         for (i=0; i<5; i++) { | ||||||
|  |             if( callsign[i] != 0 ) { | ||||||
|  |                 call6[i+1]=*(callsign+i); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     for (i=0; i<6; i++) { | ||||||
|  |         call6[i]=get_callsign_character_code(call6[i]); | ||||||
|  |     } | ||||||
|  |     n = call6[0]; | ||||||
|  |     n = n*36+call6[1]; | ||||||
|  |     n = n*10+call6[2]; | ||||||
|  |     n = n*27+call6[3]-10; | ||||||
|  |     n = n*27+call6[4]-10; | ||||||
|  |     n = n*27+call6[5]-10; | ||||||
|  |     return n; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void pack_prefix(char *callsign, int32_t *n, int32_t *m, int32_t *nadd ) { | ||||||
|  |     int i; | ||||||
|  |     char *call6; | ||||||
|  |     call6=malloc(sizeof(char)*6); | ||||||
|  |     memset(call6,32,sizeof(char)*6); | ||||||
|  |      | ||||||
|  |     int i1=strcspn(callsign,"/"); | ||||||
|  |      | ||||||
|  |     if( callsign[i1+2] == 0 ) {  | ||||||
|  |         //single char suffix
 | ||||||
|  |         for (i=0; i<i1; i++) { | ||||||
|  |             call6[i]=callsign[i]; | ||||||
|  |         } | ||||||
|  |         *n=pack_call(call6); | ||||||
|  |         *nadd=1; | ||||||
|  |         int nc = callsign[i1+1]; | ||||||
|  |         if( nc >= 48 && nc <= 57 ) { | ||||||
|  |             *m=nc-48; | ||||||
|  |         } else if ( nc >= 65 && nc <= 90 ) { | ||||||
|  |             *m=nc-65+10; | ||||||
|  |         } else { | ||||||
|  |             *m=38; | ||||||
|  |         } | ||||||
|  |         *m=60000-32768+*m; | ||||||
|  |     } else if( callsign[i1+3]==0 ) { | ||||||
|  |         //two char suffix
 | ||||||
|  |         for (i=0; i<i1; i++) { | ||||||
|  |             call6[i]=callsign[i]; | ||||||
|  |         } | ||||||
|  |         *n=pack_call(call6); | ||||||
|  |         *nadd=1; | ||||||
|  |         *m=10*(callsign[i1+1]-48)+(callsign[i1+2]-48); | ||||||
|  |         *m=60000 + 26 + *m; | ||||||
|  |     } else { | ||||||
|  |         char* pfx=strtok(callsign,"/"); | ||||||
|  |         call6=strtok(NULL," "); | ||||||
|  |         *n=pack_call(call6); | ||||||
|  |         int plen=strlen(pfx); | ||||||
|  |         if( plen ==1 ) { | ||||||
|  |             *m=36; | ||||||
|  |             *m=37*(*m)+36; | ||||||
|  |         } else if( plen == 2 ) { | ||||||
|  |             *m=36; | ||||||
|  |         } else { | ||||||
|  |             *m=0; | ||||||
|  |         } | ||||||
|  |         for (i=0; i<plen; i++) { | ||||||
|  |             int nc = callsign[i]; | ||||||
|  |             if( nc >= 48 && nc <= 57 ) { | ||||||
|  |                 nc=nc-48; | ||||||
|  |             } else if ( nc >= 65 && nc <= 90 ) { | ||||||
|  |                 nc=nc-65+10; | ||||||
|  |             } else { | ||||||
|  |                 nc=36; | ||||||
|  |             } | ||||||
|  |             *m=37*(*m)+nc; | ||||||
|  |         } | ||||||
|  |         *nadd=0; | ||||||
|  |         if( *m > 32768 ) { | ||||||
|  |             *m=*m-32768; | ||||||
|  |             *nadd=1; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void interleave(unsigned char *sym) | ||||||
|  | { | ||||||
|  |     unsigned char tmp[162]; | ||||||
|  |     unsigned char p, i, j; | ||||||
|  |      | ||||||
|  |     p=0; | ||||||
|  |     i=0; | ||||||
|  |     while (p<162) { | ||||||
|  |         j=((i * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32; | ||||||
|  |         if (j < 162 ) { | ||||||
|  |             tmp[j]=sym[p]; | ||||||
|  |             p=p+1; | ||||||
|  |         } | ||||||
|  |         i=i+1; | ||||||
|  |     } | ||||||
|  |     for (i=0; i<162; i++) { | ||||||
|  |         sym[i]=tmp[i]; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int get_wspr_channel_symbols(char* message, unsigned char* symbols) { | ||||||
|  |     int m=0, n=0, ntype=0; | ||||||
|  |     int i, j, ihash; | ||||||
|  |     unsigned char pr3[162]= | ||||||
|  |     {1,1,0,0,0,0,0,0,1,0,0,0,1,1,1,0,0,0,1,0, | ||||||
|  |         0,1,0,1,1,1,1,0,0,0,0,0,0,0,1,0,0,1,0,1, | ||||||
|  |         0,0,0,0,0,0,1,0,1,1,0,0,1,1,0,1,0,0,0,1, | ||||||
|  |         1,0,1,0,0,0,0,1,1,0,1,0,1,0,1,0,1,0,0,1, | ||||||
|  |         0,0,1,0,1,1,0,0,0,1,1,0,1,0,1,0,0,0,1,0, | ||||||
|  |         0,0,0,0,1,0,0,1,0,0,1,1,1,0,1,1,0,0,1,1, | ||||||
|  |         0,1,0,0,0,1,1,1,0,0,0,0,0,1,0,1,0,0,1,1, | ||||||
|  |         0,0,0,0,0,0,0,1,1,0,1,0,1,1,0,0,0,1,1,0, | ||||||
|  |         0,0}; | ||||||
|  |     int nu[10]={0,-1,1,0,-1,2,1,0,-1,1}; | ||||||
|  |     char *callsign, *grid, *powstr; | ||||||
|  |     char grid4[5]; | ||||||
|  |      | ||||||
|  |     int i1=strcspn(message," "); | ||||||
|  |     int i2=strcspn(message,"/"); | ||||||
|  |     int i3=strcspn(message,"<"); | ||||||
|  |     int i4=strcspn(message,">"); | ||||||
|  |     int mlen=strlen(message); | ||||||
|  |      | ||||||
|  |     // Use the presence and/or absence of "<" and "/" to decide what
 | ||||||
|  |     // type of message. No sanity checks! Beware!
 | ||||||
|  |      | ||||||
|  |     if( (i1>3) & (i1<6) & (i2==mlen) & (i3==mlen) ) { | ||||||
|  |         // Type 1 message: K9AN EN50 33
 | ||||||
|  |         //                 xxnxxxx xxnn nn
 | ||||||
|  |         const char s[2]=" "; | ||||||
|  |         callsign = strtok(message,s); | ||||||
|  |         grid = strtok(NULL,s); | ||||||
|  |         powstr = strtok(NULL,s); | ||||||
|  |         int power = atoi(powstr); | ||||||
|  |          | ||||||
|  |         n = pack_call(callsign); | ||||||
|  |          | ||||||
|  |         for (i=0; i<4; i++) { | ||||||
|  |             grid4[i]=get_locator_character_code(*(grid+i)); | ||||||
|  |         } | ||||||
|  |         m = pack_grid4_power(grid4,power); | ||||||
|  |          | ||||||
|  |     } else if ( i3 == 0 && i4 < mlen ) { | ||||||
|  |         // Type 3:      <K1ABC> EN50WC 33
 | ||||||
|  |         //          <PJ4/K1ABC> FK52UD 37
 | ||||||
|  |         // send hash instead of callsign to make room for 6 char grid.
 | ||||||
|  |         // if 4-digit locator is specified, 2 spaces are added to the end.
 | ||||||
|  |         callsign=strtok(message,"<> "); | ||||||
|  |         grid=strtok(NULL," "); | ||||||
|  |         powstr=strtok(NULL," "); | ||||||
|  |         int power = atoi(powstr); | ||||||
|  |         if( power < 0 ) power=0; | ||||||
|  |         if( power > 60 ) power=60; | ||||||
|  |         power=power+nu[power%10]; | ||||||
|  |         ntype=-(power+1); | ||||||
|  |         ihash=nhash(callsign,strlen(callsign),(uint32_t)146); | ||||||
|  |         m=128*ihash + ntype + 64; | ||||||
|  |          | ||||||
|  |         char grid6[6]; | ||||||
|  |         memset(grid6,32,sizeof(char)*6); | ||||||
|  |         j=strlen(grid); | ||||||
|  |         for(i=0; i<j-1; i++) { | ||||||
|  |             grid6[i]=grid[i+1]; | ||||||
|  |         } | ||||||
|  |         grid6[5]=grid[0]; | ||||||
|  |         n=pack_call(grid6); | ||||||
|  |         printf("Callsign %s hash %d\n",callsign,ihash); | ||||||
|  |     } else if ( i2 < mlen ) {  // just looks for a right slash
 | ||||||
|  |         // Type 2: PJ4/K1ABC 37
 | ||||||
|  |         callsign=strtok(message," "); | ||||||
|  |         powstr=strtok(NULL," "); | ||||||
|  |         int power = atoi(powstr); | ||||||
|  |         if( power < 0 ) power=0; | ||||||
|  |         if( power > 60 ) power=60; | ||||||
|  |         power=power+nu[power%10]; | ||||||
|  |         int n1, ng, nadd; | ||||||
|  |         pack_prefix(callsign, &n1, &ng, &nadd); | ||||||
|  |         ntype=power + 1 + nadd; | ||||||
|  |         m=128*ng+ntype+64; | ||||||
|  |         n=n1; | ||||||
|  |     } else { | ||||||
|  |         printf("Error: bad message format\n"); | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // pack 50 bits + 31 (0) tail bits into 11 bytes
 | ||||||
|  |     unsigned char it, data[11]; | ||||||
|  |     memset(data,0,sizeof(char)*11); | ||||||
|  |     it=0xFF & (n>>20); | ||||||
|  |     data[0]=it; | ||||||
|  |     it=0xFF & (n>>12); | ||||||
|  |     data[1]=it; | ||||||
|  |     it=0xFF & (n>>4); | ||||||
|  |     data[2]=it; | ||||||
|  |     it= ((n&(0x0F))<<4) + ((m>>18)&(0x0F)); | ||||||
|  |     data[3]=it; | ||||||
|  |     it=0xFF & (m>>10); | ||||||
|  |     data[4]=it; | ||||||
|  |     it=0xFF & (m>>2); | ||||||
|  |     data[5]=it; | ||||||
|  |     it=(m & 0x03)<<6 ; | ||||||
|  |     data[6]=it; | ||||||
|  |     data[7]=0; | ||||||
|  |     data[8]=0; | ||||||
|  |     data[9]=0; | ||||||
|  |     data[10]=0; | ||||||
|  |      | ||||||
|  |     if( printdata ) { | ||||||
|  |         printf("Data is :"); | ||||||
|  |         for (i=0; i<11; i++) { | ||||||
|  |             printf("%02X ",data[i]); | ||||||
|  |         } | ||||||
|  |         printf("\n"); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // make sure that the 11-byte data vector is unpackable
 | ||||||
|  |     // unpack it with the routine that the decoder will use and display
 | ||||||
|  |     // the result. let the operator decide whether it worked.
 | ||||||
|  |     char hashtab[32768][13]; | ||||||
|  |     memset(hashtab,0,sizeof(char)*32768*13); | ||||||
|  |      | ||||||
|  |     char *check_call_loc_pow, *check_callsign; | ||||||
|  |     check_call_loc_pow=malloc(sizeof(char)*23); | ||||||
|  |     check_callsign=malloc(sizeof(char)*13); | ||||||
|  |     signed char check_data[11]; | ||||||
|  |     memcpy(check_data,data,sizeof(char)*11); | ||||||
|  |     unpk_(check_data,hashtab,check_call_loc_pow,check_callsign); | ||||||
|  |     printf("Will decode as: %s\n",check_call_loc_pow); | ||||||
|  |      | ||||||
|  |     unsigned int nbytes=11; // The message with tail is packed into 11 bytes.
 | ||||||
|  |     unsigned int nencoded=162; | ||||||
|  |     unsigned char channelbits[nencoded]; | ||||||
|  |     memset(channelbits,0,sizeof(char)*nencoded); | ||||||
|  |      | ||||||
|  |     encode(channelbits,data,nbytes); | ||||||
|  |      | ||||||
|  |     interleave(channelbits); | ||||||
|  |      | ||||||
|  |     for (i=0; i<162; i++) { | ||||||
|  |         symbols[i]=2*channelbits[i]+pr3[i]; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     return 1; | ||||||
|  | } | ||||||
							
								
								
									
										28
									
								
								lib/wsprd/wsprsim_utils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								lib/wsprd/wsprsim_utils.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | #ifndef WSPRSIM_UTILS_H | ||||||
|  | #define WSPRSIM_UTILS_H | ||||||
|  | 
 | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <ctype.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <time.h> | ||||||
|  | 
 | ||||||
|  | extern int printdata; | ||||||
|  | 
 | ||||||
|  | char get_locator_character_code(char ch); | ||||||
|  | 
 | ||||||
|  | char get_callsign_character_code(char ch); | ||||||
|  | 
 | ||||||
|  | long unsigned int pack_grid4_power(char *grid4, int power); | ||||||
|  | 
 | ||||||
|  | long unsigned int pack_call(char *callsign); | ||||||
|  | 
 | ||||||
|  | void pack_prefix(char *callsign, int32_t *n, int32_t *m, int32_t *nadd ); | ||||||
|  | 
 | ||||||
|  | void interleave(unsigned char *sym); | ||||||
|  | 
 | ||||||
|  | int get_wspr_channel_symbols(char* message, unsigned char* symbols); | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user