Simplified C snippet for generating WSPR sequences:
#include <stdio.h>
void main(){
#ifndef TEXTMSG
// pack call in n1
static char c[6]=" K1JT "; //call
// all must be in uppercase
// char at position 3 must be last digit of call prefix
// left and right idented with space characters
unsigned long n1;
n1=(c[0]>='0'&&c[0]<='9'?c[0]-'0':c[0]==' '?36:c[0]-'A'+10);
n1=36*n1+(c[1]>='0'&&c[1]<='9'?c[1]-'0':c[1]==' '?36:c[1]-'A'+10);
n1=10*n1+c[2]-'0';
n1=27*n1+(c[3]==' '?26:c[3]-'A');
n1=27*n1+(c[4]==' '?26:c[4]-'A');
n1=27*n1+(c[5]==' '?26:c[5]-'A');
// pack grid, dbm in n2
static int lon = 5; //degrees longitude east -74 5
static int lat = 51; //degrees latitude north 40 51
int ng = 90*(180-lon+(lon<0?1:0) ) + lat;
static int dbm = 33; //EIRP dBm (0<=dbm<=60)
// must be in set {0,3,7,10,13,17,20,23,27,30,33,37,40,43,47,50,53,57,60}
unsigned long n2=(ng<<7)|(dbm+64);
#else
unsigned char msg[8] = "HI W0RLD";
// pack text
unsigned long long dn=0;
int y;
for(y=0;y!=8;y++){
unsigned char c = msg[y];
dn = 41*dn + (c>='0'&&c<='9'?c-'0': c>='A'&&c<='Z'?c-'A'+10:
c=='+'?37: c=='.'?38: c=='/'?39: c=='?'?40: 36);
}
unsigned int ng=dn&0x7fff;
unsigned long n1=dn>>15;
int ntype=-57; //plain text
unsigned long n2=ng<<7|(ntype+64);
#endif
// pack n1,n2 into 50 bits
char packed[11] = {n1>>20, n1>>12, n1>>4, (n1&0x0f)<<4|(n2>>18)&0x0f,
n2>>10, n2>>2, (n2&0x03)<<6, 0, 0, 0, 0};
// Convolutional encoder for a K=32, r=1/2 code.
// Layland-Lushbaugh polynomials for a K=32, r=1/2 convolutional code
int k = 0;
int i,j,p;
int nstate = 0;
unsigned char symbol[176];
for(j=0;j!=sizeof(packed);j++){
for(i=7;i>=0;i--){
unsigned long poly[2] = { 0xf2d05351L, 0xe4613c47L };
nstate = (nstate<<1) | ((packed[j]>>i)&1);
for(p=0;p!=2;p++){ //convolve
unsigned long n = nstate & poly[p];
// even := parity(n)
int even = 0;
while(n){
even = 1 - even;
n = n & (n - 1);
}
symbol[k] = even;
k++;
}
}
}
// Interleave symbols
unsigned char symbol2[162];
for(i=0;i!=162;i++){
// j0 := bit reversed_values_smaller_than_161[i]
unsigned char j0;
p=-1;
for(k=0;p!=i;k++){
for(j=0;j!=8;j++) // j0:=bit_reverse(k)
j0 = ((k>>j)&1) | (j0<<1);
if(j0<162)
p++;
}
symbol2[j0]=symbol[i]; //interleave
}
// Sync vector 162 bits
const unsigned char npr3[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 };
for(i=0;i!=162;i++){
printf("symbol[%u]=%u\n", i, symbol2[i]);
symbol2[i] = npr3[i] | symbol2[i]<<1;
}
// Modulate
FILE* pf = fopen("a.au", "wb");
fputc(0x2e,pf); //.au magic number
fputc(0x73,pf);
fputc(0x6e,pf);
fputc(0x64,pf);
fputc(0x00,pf); //offset
fputc(0x00,pf);
fputc(0x00,pf);
fputc(24,pf);
fputc(0xff,pf); //size
fputc(0xff,pf);
fputc(0xff,pf);
fputc(0xff,pf);
fputc(0x00,pf); //encoding
fputc(0x00,pf);
fputc(0x00,pf);
fputc(0x03,pf);
fputc(0x00,pf); //samplerate
fputc(0x00,pf);
fputc(0x2e,pf);
fputc(0xe0,pf);
fputc(0x00,pf); //channels
fputc(0x00,pf);
fputc(0x00,pf);
fputc(0x01,pf);
const int nmax=120*12000;
double tsymbol=8192.0/12000.0;
double dt=1.0/12000.0;
double f0=1500;
double dfgen=12000.0/8192.0;
double t=0;
double dphi;
double phi=0;
double dj0=0;
for(i=0; i!=nmax; i++){
t=t+dt;
j=(int)(t/tsymbol)+1;
if(j!=dj0){
double f=f0+dfgen*(symbol2[j]-1.5);
dj0=j;
dphi=2*3.14*dt*f;
}
phi=phi+dphi;
int wave=32767.0*sin(phi);
fputc((wave>>8)&0xff,pf);
fputc(wave&0xff,pf);
}
fclose(pf);
}
No comments:
Post a Comment