kopia lustrzana https://github.com/Guenael/rtlsdr-wsprd
feat(reformat): using Google c++ style everywhere
rodzic
2524ddb6f6
commit
d140fd524f
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
BasedOnStyle: Google
|
||||
ColumnLimit: 0
|
||||
UseTab: Never
|
||||
---
|
||||
Language: Cpp
|
||||
SortIncludes: false
|
||||
IndentWidth: 4
|
||||
---
|
388
rtlsdr_wsprd.c
388
rtlsdr_wsprd.c
|
@ -34,7 +34,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
|
@ -45,6 +44,7 @@
|
|||
#include <curl/curl.h>
|
||||
#include <rtl-sdr.h>
|
||||
|
||||
|
||||
#include "./rtlsdr_wsprd.h"
|
||||
#include "wsprd/wsprd.h"
|
||||
|
||||
|
@ -85,7 +85,7 @@ struct decoder_state dec;
|
|||
|
||||
/* Thread stuff for separate RX (blocking function) */
|
||||
struct dongle_state {
|
||||
pthread_t thread;
|
||||
pthread_t thread;
|
||||
};
|
||||
struct dongle_state dongle;
|
||||
|
||||
|
@ -110,14 +110,14 @@ static void rtlsdr_callback(unsigned char *samples,
|
|||
-0.0034059318, 0.0049745750, -0.0005058826, -0.0027772683
|
||||
};
|
||||
|
||||
int8_t *sigIn = (int8_t*)samples;
|
||||
int8_t *sigIn = (int8_t *)samples;
|
||||
uint32_t sigLenght = samples_count;
|
||||
static uint32_t decimationIndex = 0;
|
||||
|
||||
/* CIC buffers */
|
||||
static int32_t Ix1, Ix2, Qx1, Qx2;
|
||||
static int32_t Iy1, It1y, It1z, Qy1, Qt1y, Qt1z;
|
||||
static int32_t Iy2, It2y, It2z, Qy2, Qt2y, Qt2z;
|
||||
static int32_t Ix1, Ix2, Qx1, Qx2;
|
||||
static int32_t Iy1, It1y, It1z, Qy1, Qt1y, Qt1z;
|
||||
static int32_t Iy2, It2y, It2z, Qy2, Qt2y, Qt2z;
|
||||
|
||||
/* FIR compensation filter buffers */
|
||||
static float firI[32], firQ[32];
|
||||
|
@ -141,17 +141,17 @@ static void rtlsdr_callback(unsigned char *samples,
|
|||
(Weaver technique, keep the upper band, IQ inverted on RTL devices)
|
||||
*/
|
||||
int8_t tmp;
|
||||
for (uint32_t i = 0; i < sigLenght; i+=8) {
|
||||
tmp = -sigIn[i+3];
|
||||
sigIn[i+3] = sigIn[i+2];
|
||||
sigIn[i+2] = tmp;
|
||||
for (uint32_t i = 0; i < sigLenght; i += 8) {
|
||||
tmp = -sigIn[i + 3];
|
||||
sigIn[i + 3] = sigIn[i + 2];
|
||||
sigIn[i + 2] = tmp;
|
||||
|
||||
sigIn[i+4] = -sigIn[i+4];
|
||||
sigIn[i+5] = -sigIn[i+5];
|
||||
sigIn[i + 4] = -sigIn[i + 4];
|
||||
sigIn[i + 5] = -sigIn[i + 5];
|
||||
|
||||
tmp = -sigIn[i+6];
|
||||
sigIn[i+6] = sigIn[i+7];
|
||||
sigIn[i+7] = tmp;
|
||||
tmp = -sigIn[i + 6];
|
||||
sigIn[i + 6] = sigIn[i + 7];
|
||||
sigIn[i + 7] = tmp;
|
||||
}
|
||||
|
||||
/* CIC decimator (N=2)
|
||||
|
@ -160,10 +160,10 @@ static void rtlsdr_callback(unsigned char *samples,
|
|||
* Understanding cascaded integrator-comb filters
|
||||
http://www.embedded.com/design/configurable-systems/4006446/Understanding-cascaded-integrator-comb-filters
|
||||
*/
|
||||
for (int32_t i = 0; i < sigLenght/2; i++) {
|
||||
for (int32_t i = 0; i < sigLenght / 2; i++) {
|
||||
/* Integrator stages (N=2) */
|
||||
Ix1 += (int32_t)sigIn[i*2];
|
||||
Qx1 += (int32_t)sigIn[i*2+1];
|
||||
Ix1 += (int32_t)sigIn[i * 2];
|
||||
Qx1 += (int32_t)sigIn[i * 2 + 1];
|
||||
Ix2 += Ix1;
|
||||
Qx2 += Qx1;
|
||||
|
||||
|
@ -197,14 +197,14 @@ static void rtlsdr_callback(unsigned char *samples,
|
|||
Isum += firI[j] * zCoef[j];
|
||||
Qsum += firQ[j] * zCoef[j];
|
||||
if (j < 31) {
|
||||
firI[j] = firI[j+1];
|
||||
firQ[j] = firQ[j+1];
|
||||
firI[j] = firI[j + 1];
|
||||
firQ[j] = firQ[j + 1];
|
||||
}
|
||||
}
|
||||
firI[31] = (float)Iy2;
|
||||
firQ[31] = (float)Qy2;
|
||||
Isum += firI[31]*zCoef[32];
|
||||
Qsum += firQ[31]*zCoef[32];
|
||||
Isum += firI[31] * zCoef[32];
|
||||
Qsum += firQ[31] * zCoef[32];
|
||||
|
||||
/* Save the result in the buffer */
|
||||
if (rx_state.iqIndex < (SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE)) {
|
||||
|
@ -246,34 +246,34 @@ void postSpots(uint32_t n_results) {
|
|||
time(&rawtime);
|
||||
struct tm *gtm = gmtime(&rawtime);
|
||||
|
||||
for (uint32_t i=0; i < n_results; i++) {
|
||||
snprintf(url, sizeof(url)-1, "http://wsprnet.org/post?function=wspr&rcall=%s&rgrid=%s&rqrg=%.6f&date=%s&time=%s&sig=%.0f&dt=%.1f&tqrg=%.6f&tcall=%s&tgrid=%s&dbm=%s&version=0.2r_wsprd&mode=2",
|
||||
dec_options.rcall,
|
||||
dec_options.rloc,
|
||||
dec_results[i].freq,
|
||||
dec_options.date,
|
||||
dec_options.uttime,
|
||||
dec_results[i].snr,
|
||||
dec_results[i].dt,
|
||||
dec_results[i].freq,
|
||||
dec_results[i].call,
|
||||
dec_results[i].loc,
|
||||
dec_results[i].pwr);
|
||||
for (uint32_t i = 0; i < n_results; i++) {
|
||||
snprintf(url, sizeof(url) - 1, "http://wsprnet.org/post?function=wspr&rcall=%s&rgrid=%s&rqrg=%.6f&date=%s&time=%s&sig=%.0f&dt=%.1f&tqrg=%.6f&tcall=%s&tgrid=%s&dbm=%s&version=0.2r_wsprd&mode=2",
|
||||
dec_options.rcall,
|
||||
dec_options.rloc,
|
||||
dec_results[i].freq,
|
||||
dec_options.date,
|
||||
dec_options.uttime,
|
||||
dec_results[i].snr,
|
||||
dec_results[i].dt,
|
||||
dec_results[i].freq,
|
||||
dec_results[i].call,
|
||||
dec_results[i].loc,
|
||||
dec_results[i].pwr);
|
||||
|
||||
printf("Spot : %04d-%02d-%02d %02d:%02d:%02d %6.2f %6.2f %10.6f %2d %7s %6s %2s\n",
|
||||
gtm->tm_year + 1900,
|
||||
gtm->tm_mon + 1,
|
||||
gtm->tm_mday,
|
||||
gtm->tm_hour,
|
||||
gtm->tm_min,
|
||||
gtm->tm_sec,
|
||||
dec_results[i].snr,
|
||||
dec_results[i].dt,
|
||||
dec_results[i].freq,
|
||||
(int)dec_results[i].drift,
|
||||
dec_results[i].call,
|
||||
dec_results[i].loc,
|
||||
dec_results[i].pwr);
|
||||
gtm->tm_year + 1900,
|
||||
gtm->tm_mon + 1,
|
||||
gtm->tm_mday,
|
||||
gtm->tm_hour,
|
||||
gtm->tm_min,
|
||||
gtm->tm_sec,
|
||||
dec_results[i].snr,
|
||||
dec_results[i].dt,
|
||||
dec_results[i].freq,
|
||||
(int)dec_results[i].drift,
|
||||
dec_results[i].call,
|
||||
dec_results[i].loc,
|
||||
dec_results[i].pwr);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if (curl) {
|
||||
|
@ -290,11 +290,11 @@ void postSpots(uint32_t n_results) {
|
|||
|
||||
if (n_results == 0) {
|
||||
printf("No spot %04d-%02d-%02d %02d:%02dz\n",
|
||||
gtm->tm_year + 1900,
|
||||
gtm->tm_mon + 1,
|
||||
gtm->tm_mday,
|
||||
gtm->tm_hour,
|
||||
gtm->tm_min);
|
||||
gtm->tm_year + 1900,
|
||||
gtm->tm_mon + 1,
|
||||
gtm->tm_mday,
|
||||
gtm->tm_hour,
|
||||
gtm->tm_min);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,8 +305,8 @@ static void *wsprDecoder(void *arg) {
|
|||
Real = 375 * 116 = 43500
|
||||
FIXME with SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE ??
|
||||
*/
|
||||
static float iSamples[45000]= {0};
|
||||
static float qSamples[45000]= {0};
|
||||
static float iSamples[45000] = {0};
|
||||
static float qSamples[45000] = {0};
|
||||
static uint32_t samples_len;
|
||||
int32_t n_results = 0;
|
||||
|
||||
|
@ -348,8 +348,8 @@ double atofs(char *s) {
|
|||
uint32_t len;
|
||||
double suff = 1.0;
|
||||
len = strlen(s);
|
||||
last = s[len-1];
|
||||
s[len-1] = '\0';
|
||||
last = s[len - 1];
|
||||
s[len - 1] = '\0';
|
||||
|
||||
switch (last) {
|
||||
case 'g':
|
||||
|
@ -362,25 +362,25 @@ double atofs(char *s) {
|
|||
case 'K':
|
||||
suff *= 1e3;
|
||||
suff *= atof(s);
|
||||
s[len-1] = last;
|
||||
s[len - 1] = last;
|
||||
return suff;
|
||||
}
|
||||
s[len-1] = last;
|
||||
s[len - 1] = last;
|
||||
return atof(s);
|
||||
}
|
||||
|
||||
|
||||
int32_t parse_u64(char* s, uint64_t* const value) {
|
||||
int32_t parse_u64(char *s, uint64_t *const value) {
|
||||
uint_fast8_t base = 10;
|
||||
char* s_end;
|
||||
char *s_end;
|
||||
uint64_t u64_value;
|
||||
|
||||
if (strlen(s) > 2) {
|
||||
if (s[0] == '0') {
|
||||
if ( (s[1] == 'x') || (s[1] == 'X') ) {
|
||||
if ((s[1] == 'x') || (s[1] == 'X')) {
|
||||
base = 16;
|
||||
s += 2;
|
||||
} else if ( (s[1] == 'b') || (s[1] == 'B') ) {
|
||||
} else if ((s[1] == 'b') || (s[1] == 'B')) {
|
||||
base = 2;
|
||||
s += 2;
|
||||
}
|
||||
|
@ -389,7 +389,7 @@ int32_t parse_u64(char* s, uint64_t* const value) {
|
|||
|
||||
s_end = s;
|
||||
u64_value = strtoull(s, &s_end, base);
|
||||
if ( (s != s_end) && (*s_end == 0) ) {
|
||||
if ((s != s_end) && (*s_end == 0)) {
|
||||
*value = u64_value;
|
||||
return 1;
|
||||
} else {
|
||||
|
@ -433,8 +433,8 @@ void sigint_callback_handler(int signum) {
|
|||
|
||||
|
||||
int32_t readfile(float *iSamples, float *qSamples, char *filename) {
|
||||
FILE* fd = NULL;
|
||||
float filebuffer[2*SIGNAL_LENGHT*SIGNAL_SAMPLE_RATE];
|
||||
FILE *fd = NULL;
|
||||
float filebuffer[2 * SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE];
|
||||
|
||||
fd = fopen(filename, "rb");
|
||||
if (fd == NULL) {
|
||||
|
@ -449,16 +449,16 @@ int32_t readfile(float *iSamples, float *qSamples, char *filename) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int32_t nread = fread(filebuffer, sizeof(float), 2*SIGNAL_LENGHT*SIGNAL_SAMPLE_RATE, fd);
|
||||
if (nread != 2*SIGNAL_LENGHT*SIGNAL_SAMPLE_RATE) {
|
||||
int32_t nread = fread(filebuffer, sizeof(float), 2 * SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE, fd);
|
||||
if (nread != 2 * SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE) {
|
||||
fprintf(stderr, "Cannot read all the data!\n");
|
||||
fclose(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (int32_t i=0; i < SIGNAL_LENGHT*SIGNAL_SAMPLE_RATE; i++) {
|
||||
iSamples[i] = filebuffer[2*i];
|
||||
qSamples[i] = -filebuffer[2*i+1];
|
||||
for (int32_t i = 0; i < SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE; i++) {
|
||||
iSamples[i] = filebuffer[2 * i];
|
||||
qSamples[i] = -filebuffer[2 * i + 1];
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
|
@ -468,13 +468,13 @@ int32_t readfile(float *iSamples, float *qSamples, char *filename) {
|
|||
|
||||
|
||||
int32_t writefile(float *iSamples, float *qSamples, char *filename, uint32_t type, double freq) {
|
||||
FILE* fd = NULL;
|
||||
FILE *fd = NULL;
|
||||
char info[15] = {}; // Info descriptor, not used for now
|
||||
|
||||
float filebuffer[2*SIGNAL_LENGHT*SIGNAL_SAMPLE_RATE];
|
||||
for (int32_t i=0; i < SIGNAL_LENGHT*SIGNAL_SAMPLE_RATE; i++) {
|
||||
filebuffer[2*i] = iSamples[i];
|
||||
filebuffer[2*i+1] = -qSamples[i];
|
||||
float filebuffer[2 * SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE];
|
||||
for (int32_t i = 0; i < SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE; i++) {
|
||||
filebuffer[2 * i] = iSamples[i];
|
||||
filebuffer[2 * i + 1] = -qSamples[i];
|
||||
}
|
||||
|
||||
fd = fopen(filename, "wb");
|
||||
|
@ -488,8 +488,8 @@ int32_t writefile(float *iSamples, float *qSamples, char *filename, uint32_t typ
|
|||
fwrite(&type, sizeof(uint32_t), 1, fd);
|
||||
fwrite(&freq, sizeof(double), 1, fd);
|
||||
|
||||
int32_t nwrite = fwrite(filebuffer, sizeof(float), 2*SIGNAL_LENGHT*SIGNAL_SAMPLE_RATE, fd);
|
||||
if (nwrite != 2*SIGNAL_LENGHT*SIGNAL_SAMPLE_RATE) {
|
||||
int32_t nwrite = fwrite(filebuffer, sizeof(float), 2 * SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE, fd);
|
||||
if (nwrite != 2 * SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE) {
|
||||
fprintf(stderr, "Cannot write all the data!\n");
|
||||
return 1;
|
||||
}
|
||||
|
@ -529,22 +529,22 @@ void usage(void) {
|
|||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int main(int argc, char **argv) {
|
||||
uint32_t opt;
|
||||
|
||||
int32_t rtl_result;
|
||||
int32_t rtl_count;
|
||||
char rtl_vendor[256], rtl_product[256], rtl_serial[256];
|
||||
int32_t rtl_result;
|
||||
int32_t rtl_count;
|
||||
char rtl_vendor[256], rtl_product[256], rtl_serial[256];
|
||||
|
||||
initrx_options();
|
||||
initDecoder_options();
|
||||
|
||||
/* RX buffer allocation */
|
||||
rx_state.iSamples = malloc(sizeof(float)*SIGNAL_LENGHT*SIGNAL_SAMPLE_RATE);
|
||||
rx_state.qSamples = malloc(sizeof(float)*SIGNAL_LENGHT*SIGNAL_SAMPLE_RATE);
|
||||
rx_state.iSamples = malloc(sizeof(float) * SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE);
|
||||
rx_state.qSamples = malloc(sizeof(float) * SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE);
|
||||
|
||||
/* Stop condition setup */
|
||||
rx_state.exit_flag = false;
|
||||
rx_state.exit_flag = false;
|
||||
rx_state.decode_flag = false;
|
||||
uint32_t nLoop = 0;
|
||||
|
||||
|
@ -553,101 +553,101 @@ int main(int argc, char** argv) {
|
|||
|
||||
while ((opt = getopt(argc, argv, "f:c:l:g:a:o:p:u:d:n:i:H:Q:S")) != -1) {
|
||||
switch (opt) {
|
||||
case 'f': // Frequency
|
||||
if (!strcasecmp(optarg, "LF")) {
|
||||
rx_options.dialfreq = 136000;
|
||||
} else if (!strcasecmp(optarg, "LF-15")) {
|
||||
rx_options.dialfreq = 136112;
|
||||
} else if (!strcasecmp(optarg, "MF")) {
|
||||
rx_options.dialfreq = 474200;
|
||||
} else if (!strcasecmp(optarg, "MF-15")) {
|
||||
rx_options.dialfreq = 474312;
|
||||
} else if (!strcasecmp(optarg, "160m")) {
|
||||
rx_options.dialfreq = 1836600;
|
||||
} else if (!strcasecmp(optarg, "160m-15")) {
|
||||
rx_options.dialfreq = 1838212;
|
||||
} else if (!strcasecmp(optarg, "80m")) {
|
||||
rx_options.dialfreq = 3592600;
|
||||
} else if (!strcasecmp(optarg, "60m")) {
|
||||
rx_options.dialfreq = 5287200;
|
||||
} else if (!strcasecmp(optarg, "40m")) {
|
||||
rx_options.dialfreq = 7038600;
|
||||
} else if (!strcasecmp(optarg, "30m")) {
|
||||
rx_options.dialfreq = 10138700;
|
||||
} else if (!strcasecmp(optarg, "20m")) {
|
||||
rx_options.dialfreq = 14095600;
|
||||
} else if (!strcasecmp(optarg, "17m")) {
|
||||
rx_options.dialfreq = 18104600;
|
||||
} else if (!strcasecmp(optarg, "15m")) {
|
||||
rx_options.dialfreq = 21094600;
|
||||
} else if (!strcasecmp(optarg, "12m")) {
|
||||
rx_options.dialfreq = 24924600;
|
||||
} else if (!strcasecmp(optarg, "10m")) {
|
||||
rx_options.dialfreq = 28124600;
|
||||
} else if (!strcasecmp(optarg, "6m")) {
|
||||
rx_options.dialfreq = 50293000;
|
||||
} else if (!strcasecmp(optarg, "4m")) {
|
||||
rx_options.dialfreq = 70091000;
|
||||
} else if (!strcasecmp(optarg, "2m")) {
|
||||
rx_options.dialfreq = 144489000;
|
||||
} else if (!strcasecmp(optarg, "1m25")) {
|
||||
rx_options.dialfreq = 222280000;
|
||||
} else if (!strcasecmp(optarg, "70cm")) {
|
||||
rx_options.dialfreq = 432300000;
|
||||
} else if (!strcasecmp(optarg, "23cm")) {
|
||||
rx_options.dialfreq = 1296500000;
|
||||
} else {
|
||||
rx_options.dialfreq = (uint32_t)atofs(optarg);
|
||||
}
|
||||
break;
|
||||
case 'c': // Callsign
|
||||
snprintf(dec_options.rcall, sizeof(dec_options.rcall), "%.12s", optarg);
|
||||
break;
|
||||
case 'l': // Locator / Grid
|
||||
snprintf(dec_options.rloc, sizeof(dec_options.rloc), "%.6s", optarg);
|
||||
break;
|
||||
case 'g': // Small signal amplifier gain
|
||||
rx_options.gain = atoi(optarg);
|
||||
if (rx_options.gain < 0) rx_options.gain = 0;
|
||||
if (rx_options.gain > 49) rx_options.gain = 49;
|
||||
rx_options.gain *= 10;
|
||||
break;
|
||||
case 'a': // Auto gain
|
||||
rx_options.autogain = atoi(optarg);
|
||||
if (rx_options.autogain < 0) rx_options.autogain = 0;
|
||||
if (rx_options.autogain > 1) rx_options.autogain = 1;
|
||||
break;
|
||||
case 'o': // Fine frequency correction
|
||||
rx_options.shift = atoi(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
rx_options.ppm = atoi(optarg);
|
||||
break;
|
||||
case 'u': // Upconverter frequency
|
||||
rx_options.upconverter = (uint32_t)atofs(optarg);
|
||||
break;
|
||||
case 'd': // Direct Sampling
|
||||
rx_options.directsampling = (uint32_t)atofs(optarg);
|
||||
break;
|
||||
case 'n': // Stop after n iterations
|
||||
rx_options.maxloop = (uint32_t)atofs(optarg);
|
||||
break;
|
||||
case 'i': // Select the device to use
|
||||
rx_options.device = (uint32_t)atofs(optarg);
|
||||
break;
|
||||
case 'H': // Decoder option, use a hastable
|
||||
dec_options.usehashtable = 1;
|
||||
break;
|
||||
case 'Q': // Decoder option, faster
|
||||
dec_options.quickmode = 1;
|
||||
break;
|
||||
case 'S': // Decoder option, single pass mode (same as original wsprd)
|
||||
dec_options.subtraction = 0;
|
||||
dec_options.npasses = 1;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
case 'f': // Frequency
|
||||
if (!strcasecmp(optarg, "LF")) {
|
||||
rx_options.dialfreq = 136000;
|
||||
} else if (!strcasecmp(optarg, "LF-15")) {
|
||||
rx_options.dialfreq = 136112;
|
||||
} else if (!strcasecmp(optarg, "MF")) {
|
||||
rx_options.dialfreq = 474200;
|
||||
} else if (!strcasecmp(optarg, "MF-15")) {
|
||||
rx_options.dialfreq = 474312;
|
||||
} else if (!strcasecmp(optarg, "160m")) {
|
||||
rx_options.dialfreq = 1836600;
|
||||
} else if (!strcasecmp(optarg, "160m-15")) {
|
||||
rx_options.dialfreq = 1838212;
|
||||
} else if (!strcasecmp(optarg, "80m")) {
|
||||
rx_options.dialfreq = 3592600;
|
||||
} else if (!strcasecmp(optarg, "60m")) {
|
||||
rx_options.dialfreq = 5287200;
|
||||
} else if (!strcasecmp(optarg, "40m")) {
|
||||
rx_options.dialfreq = 7038600;
|
||||
} else if (!strcasecmp(optarg, "30m")) {
|
||||
rx_options.dialfreq = 10138700;
|
||||
} else if (!strcasecmp(optarg, "20m")) {
|
||||
rx_options.dialfreq = 14095600;
|
||||
} else if (!strcasecmp(optarg, "17m")) {
|
||||
rx_options.dialfreq = 18104600;
|
||||
} else if (!strcasecmp(optarg, "15m")) {
|
||||
rx_options.dialfreq = 21094600;
|
||||
} else if (!strcasecmp(optarg, "12m")) {
|
||||
rx_options.dialfreq = 24924600;
|
||||
} else if (!strcasecmp(optarg, "10m")) {
|
||||
rx_options.dialfreq = 28124600;
|
||||
} else if (!strcasecmp(optarg, "6m")) {
|
||||
rx_options.dialfreq = 50293000;
|
||||
} else if (!strcasecmp(optarg, "4m")) {
|
||||
rx_options.dialfreq = 70091000;
|
||||
} else if (!strcasecmp(optarg, "2m")) {
|
||||
rx_options.dialfreq = 144489000;
|
||||
} else if (!strcasecmp(optarg, "1m25")) {
|
||||
rx_options.dialfreq = 222280000;
|
||||
} else if (!strcasecmp(optarg, "70cm")) {
|
||||
rx_options.dialfreq = 432300000;
|
||||
} else if (!strcasecmp(optarg, "23cm")) {
|
||||
rx_options.dialfreq = 1296500000;
|
||||
} else {
|
||||
rx_options.dialfreq = (uint32_t)atofs(optarg);
|
||||
}
|
||||
break;
|
||||
case 'c': // Callsign
|
||||
snprintf(dec_options.rcall, sizeof(dec_options.rcall), "%.12s", optarg);
|
||||
break;
|
||||
case 'l': // Locator / Grid
|
||||
snprintf(dec_options.rloc, sizeof(dec_options.rloc), "%.6s", optarg);
|
||||
break;
|
||||
case 'g': // Small signal amplifier gain
|
||||
rx_options.gain = atoi(optarg);
|
||||
if (rx_options.gain < 0) rx_options.gain = 0;
|
||||
if (rx_options.gain > 49) rx_options.gain = 49;
|
||||
rx_options.gain *= 10;
|
||||
break;
|
||||
case 'a': // Auto gain
|
||||
rx_options.autogain = atoi(optarg);
|
||||
if (rx_options.autogain < 0) rx_options.autogain = 0;
|
||||
if (rx_options.autogain > 1) rx_options.autogain = 1;
|
||||
break;
|
||||
case 'o': // Fine frequency correction
|
||||
rx_options.shift = atoi(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
rx_options.ppm = atoi(optarg);
|
||||
break;
|
||||
case 'u': // Upconverter frequency
|
||||
rx_options.upconverter = (uint32_t)atofs(optarg);
|
||||
break;
|
||||
case 'd': // Direct Sampling
|
||||
rx_options.directsampling = (uint32_t)atofs(optarg);
|
||||
break;
|
||||
case 'n': // Stop after n iterations
|
||||
rx_options.maxloop = (uint32_t)atofs(optarg);
|
||||
break;
|
||||
case 'i': // Select the device to use
|
||||
rx_options.device = (uint32_t)atofs(optarg);
|
||||
break;
|
||||
case 'H': // Decoder option, use a hastable
|
||||
dec_options.usehashtable = 1;
|
||||
break;
|
||||
case 'Q': // Decoder option, faster
|
||||
dec_options.quickmode = 1;
|
||||
break;
|
||||
case 'S': // Decoder option, single pass mode (same as original wsprd)
|
||||
dec_options.subtraction = 0;
|
||||
dec_options.npasses = 1;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -690,15 +690,13 @@ int main(int argc, char** argv) {
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
fprintf(stderr, "Found %d device(s):\n", rtl_count);
|
||||
for (uint32_t i=0; i < rtl_count; i++) {
|
||||
for (uint32_t i = 0; i < rtl_count; i++) {
|
||||
rtlsdr_get_device_usb_strings(i, rtl_vendor, rtl_product, rtl_serial);
|
||||
fprintf(stderr, " %d: %s, %s, SN: %s\n", i, rtl_vendor, rtl_product, rtl_serial);
|
||||
}
|
||||
fprintf(stderr, "\nUsing device %d: %s\n", rx_options.device, rtlsdr_get_device_name(rx_options.device));
|
||||
|
||||
|
||||
rtl_result = rtlsdr_open(&rtl_device, rx_options.device);
|
||||
if (rtl_result < 0) {
|
||||
fprintf(stderr, "ERROR: Failed to open rtlsdr device #%d.\n", rx_options.device);
|
||||
|
@ -721,7 +719,6 @@ int main(int argc, char** argv) {
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
rtl_result = rtlsdr_set_tuner_gain_mode(rtl_device, 1);
|
||||
if (rtl_result < 0) {
|
||||
fprintf(stderr, "ERROR: Failed to enable manual gain\n");
|
||||
|
@ -729,7 +726,6 @@ int main(int argc, char** argv) {
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
if (rx_options.autogain) {
|
||||
rtl_result = rtlsdr_set_tuner_gain_mode(rtl_device, 0);
|
||||
if (rtl_result != 0) {
|
||||
|
@ -746,7 +742,6 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (rx_options.ppm != 0) {
|
||||
rtl_result = rtlsdr_set_freq_correction(rtl_device, rx_options.ppm);
|
||||
if (rtl_result < 0) {
|
||||
|
@ -756,7 +751,6 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
rtl_result = rtlsdr_set_center_freq(rtl_device, rx_options.realfreq + FS4_RATE + 1500);
|
||||
if (rtl_result < 0) {
|
||||
fprintf(stderr, "ERROR: Failed to set frequency\n");
|
||||
|
@ -764,7 +758,6 @@ int main(int argc, char** argv) {
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
rtl_result = rtlsdr_reset_buffer(rtl_device);
|
||||
if (rtl_result < 0) {
|
||||
fprintf(stderr, "ERROR: Failed to reset buffers.\n");
|
||||
|
@ -772,7 +765,6 @@ int main(int argc, char** argv) {
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
/* Print used parameter */
|
||||
time_t rawtime;
|
||||
time(&rawtime);
|
||||
|
@ -788,16 +780,15 @@ int main(int argc, char** argv) {
|
|||
if (rx_options.autogain)
|
||||
printf(" Auto gain : enable\n");
|
||||
else
|
||||
printf(" Gain : %d dB\n", rx_options.gain/10);
|
||||
|
||||
printf(" Gain : %d dB\n", rx_options.gain / 10);
|
||||
|
||||
/* Time alignment stuff */
|
||||
struct timeval lTime;
|
||||
gettimeofday(&lTime, NULL);
|
||||
uint32_t sec = lTime.tv_sec % 120;
|
||||
uint32_t usec = sec * 1000000 + lTime.tv_usec;
|
||||
uint32_t sec = lTime.tv_sec % 120;
|
||||
uint32_t usec = sec * 1000000 + lTime.tv_usec;
|
||||
uint32_t uwait = 120000000 - usec;
|
||||
printf("Wait for time sync (start in %d sec)\n\n", uwait/1000000);
|
||||
printf("Wait for time sync (start in %d sec)\n\n", uwait / 1000000);
|
||||
printf(" Date Time(z) SNR DT Freq Dr Call Loc Pwr\n");
|
||||
|
||||
/* Prepare a low priority param for the decoder thread */
|
||||
|
@ -817,13 +808,12 @@ int main(int argc, char** argv) {
|
|||
pthread_create(&dongle.thread, NULL, rtlsdr_rx, NULL);
|
||||
pthread_create(&dec.thread, &dec.tattr, wsprDecoder, NULL);
|
||||
|
||||
|
||||
/* Main loop : Wait, read, decode */
|
||||
while (!rx_state.exit_flag && !(rx_options.maxloop && (nLoop >= rx_options.maxloop))) {
|
||||
/* Wait for time Sync on 2 mins */
|
||||
gettimeofday(&lTime, NULL);
|
||||
sec = lTime.tv_sec % 120;
|
||||
usec = sec * 1000000 + lTime.tv_usec;
|
||||
sec = lTime.tv_sec % 120;
|
||||
usec = sec * 1000000 + lTime.tv_usec;
|
||||
uwait = 120000000 - usec + 10000; // Adding 10ms, to be sure to reach this next minute
|
||||
usleep(uwait);
|
||||
|
||||
|
@ -837,8 +827,8 @@ int main(int argc, char** argv) {
|
|||
/* Start to store the samples */
|
||||
initSampleStorage();
|
||||
|
||||
while ( (rx_state.exit_flag == false) &&
|
||||
(rx_state.iqIndex < (SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE) ) ) {
|
||||
while ((rx_state.exit_flag == false) &&
|
||||
(rx_state.iqIndex < (SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE))) {
|
||||
usleep(250000);
|
||||
}
|
||||
nLoop++;
|
||||
|
|
|
@ -25,16 +25,13 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
#ifndef bool
|
||||
typedef uint32_t bool;
|
||||
#define true 1
|
||||
#define true 1
|
||||
#define false 0
|
||||
#endif
|
||||
|
||||
|
@ -69,12 +66,13 @@ struct receiver_options {
|
|||
char uttime[5];
|
||||
};
|
||||
|
||||
|
||||
static void rtlsdr_callback(unsigned char *samples, uint32_t samples_count, void *ctx);
|
||||
static void *rtlsdr_rx(void *arg);
|
||||
void postSpots(uint32_t n_results);
|
||||
static void *wsprDecoder(void *arg);
|
||||
double atofs(char *s);
|
||||
int32_t parse_u64(char* s, uint64_t* const value);
|
||||
int32_t parse_u64(char *s, uint64_t *const value);
|
||||
void initSampleStorage();
|
||||
void initDecoder_options();
|
||||
void initrx_options();
|
||||
|
|
68
wsprd/fano.c
68
wsprd/fano.c
|
@ -26,30 +26,30 @@ struct node {
|
|||
};
|
||||
|
||||
// Convolutional coding polynomials. All are rate 1/2, K=32
|
||||
#ifdef NASA_STANDARD
|
||||
#ifdef NASA_STANDARD
|
||||
/* "NASA standard" code by Massey & Costello
|
||||
* Nonsystematic, quick look-in, dmin=11, dfree=23
|
||||
* used on Pioneer 10-12, Helios A,B
|
||||
*/
|
||||
#define POLY1 0xbbef6bb7
|
||||
#define POLY2 0xbbef6bb5
|
||||
#define POLY1 0xbbef6bb7
|
||||
#define POLY2 0xbbef6bb5
|
||||
#endif
|
||||
|
||||
#ifdef MJ
|
||||
#ifdef MJ
|
||||
/* Massey-Johannesson code
|
||||
* Nonsystematic, quick look-in, dmin=13, dfree>=23
|
||||
* Purported to be more computationally efficient than Massey-Costello
|
||||
*/
|
||||
#define POLY1 0xb840a20f
|
||||
#define POLY2 0xb840a20d
|
||||
#define POLY1 0xb840a20f
|
||||
#define POLY2 0xb840a20d
|
||||
#endif
|
||||
|
||||
#ifdef LL
|
||||
#ifdef LL
|
||||
/* Layland-Lushbaugh code
|
||||
* Nonsystematic, non-quick look-in, dmin=?, dfree=?
|
||||
*/
|
||||
#define POLY1 0xf2d05351
|
||||
#define POLY2 0xe4613c47
|
||||
#define POLY1 0xf2d05351
|
||||
#define POLY2 0xe4613c47
|
||||
#endif
|
||||
|
||||
/* Convolutionally encode a packet. The input data bytes are read
|
||||
|
@ -70,7 +70,7 @@ int encode(unsigned char *symbols, // Output buffer, 2*8*nbytes
|
|||
|
||||
encstate = 0;
|
||||
while (nbytes-- != 0) {
|
||||
for (i=7; i >= 0; i--) {
|
||||
for (i = 7; i >= 0; i--) {
|
||||
encstate = (encstate << 1) | ((*data >> i) & 1);
|
||||
ENCODE(sym, encstate);
|
||||
*symbols++ = sym >> 1;
|
||||
|
@ -84,9 +84,9 @@ int encode(unsigned char *symbols, // Output buffer, 2*8*nbytes
|
|||
/* Decode packet with the Fano algorithm.
|
||||
* Return 0 on success, -1 on timeout
|
||||
*/
|
||||
int fano(unsigned int *metric, // Final path metric (returned value)
|
||||
unsigned int *cycles, // Cycle count (returned value)
|
||||
unsigned int *maxnp, // Progress before timeout (returned value)
|
||||
int fano(unsigned int *metric, // Final path metric (returned value)
|
||||
unsigned int *cycles, // Cycle count (returned value)
|
||||
unsigned int *maxnp, // Progress before timeout (returned value)
|
||||
unsigned char *data, // Decoded output data
|
||||
unsigned char *symbols, // Raw deinterleaved input symbols
|
||||
unsigned int nbits, // Number of output bits
|
||||
|
@ -94,28 +94,28 @@ int fano(unsigned int *metric, // Final path metric (returned value)
|
|||
int delta, // Threshold adjust parameter
|
||||
unsigned int maxcycles) { // Decoding timeout in cycles per bit
|
||||
|
||||
struct node *nodes; // First node
|
||||
struct node *np; // Current node
|
||||
struct node *lastnode; // Last node
|
||||
struct node *tail; // First node of tail
|
||||
int t; // Threshold
|
||||
struct node *nodes; // First node
|
||||
struct node *np; // Current node
|
||||
struct node *lastnode; // Last node
|
||||
struct node *tail; // First node of tail
|
||||
int t; // Threshold
|
||||
int m0, m1;
|
||||
int ngamma;
|
||||
unsigned int lsym;
|
||||
unsigned int i;
|
||||
|
||||
if ((nodes = (struct node *)malloc((nbits+1)*sizeof(struct node))) == NULL) {
|
||||
if ((nodes = (struct node *)malloc((nbits + 1) * sizeof(struct node))) == NULL) {
|
||||
printf("malloc failed\n");
|
||||
return 0;
|
||||
}
|
||||
lastnode = &nodes[nbits-1];
|
||||
tail = &nodes[nbits-31];
|
||||
lastnode = &nodes[nbits - 1];
|
||||
tail = &nodes[nbits - 31];
|
||||
*maxnp = 0;
|
||||
|
||||
/* Compute all possible branch metrics for each symbol pair
|
||||
* This is the only place we actually look at the raw input symbols
|
||||
*/
|
||||
for (np=nodes; np <= lastnode; np++) {
|
||||
for (np = nodes; np <= lastnode; np++) {
|
||||
np->metrics[0] = mettab[0][symbols[0]] + mettab[0][symbols[1]];
|
||||
np->metrics[1] = mettab[0][symbols[0]] + mettab[1][symbols[1]];
|
||||
np->metrics[2] = mettab[1][symbols[0]] + mettab[0][symbols[1]];
|
||||
|
@ -136,7 +136,7 @@ int fano(unsigned int *metric, // Final path metric (returned value)
|
|||
* This code should be modified if a systematic code were used.
|
||||
*/
|
||||
|
||||
m1 = np->metrics[3^lsym];
|
||||
m1 = np->metrics[3 ^ lsym];
|
||||
if (m0 > m1) {
|
||||
np->tm[0] = m0; // 0-branch has better metric
|
||||
np->tm[1] = m1;
|
||||
|
@ -145,13 +145,13 @@ int fano(unsigned int *metric, // Final path metric (returned value)
|
|||
np->tm[1] = m0;
|
||||
np->encstate++; // Set low bit
|
||||
}
|
||||
np->i = 0; // Start with best branch
|
||||
np->i = 0; // Start with best branch
|
||||
maxcycles *= nbits;
|
||||
np->gamma = t = 0;
|
||||
|
||||
// Start the Fano decoder
|
||||
for (i=1; i <= maxcycles; i++) {
|
||||
if ((int)(np-nodes) > (int)*maxnp) *maxnp = (int)(np-nodes);
|
||||
for (i = 1; i <= maxcycles; i++) {
|
||||
if ((int)(np - nodes) > (int)*maxnp) *maxnp = (int)(np - nodes);
|
||||
|
||||
// Look forward */
|
||||
ngamma = np->gamma + np->tm[np->i];
|
||||
|
@ -169,7 +169,7 @@ int fano(unsigned int *metric, // Final path metric (returned value)
|
|||
// Move forward
|
||||
np[1].gamma = ngamma;
|
||||
np[1].encstate = np->encstate << 1;
|
||||
if ( ++np == (lastnode+1) ) {
|
||||
if (++np == (lastnode + 1)) {
|
||||
break; // Done!
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ int fano(unsigned int *metric, // Final path metric (returned value)
|
|||
np->tm[0] = np->metrics[lsym];
|
||||
} else {
|
||||
m0 = np->metrics[lsym];
|
||||
m1 = np->metrics[3^lsym];
|
||||
m1 = np->metrics[3 ^ lsym];
|
||||
if (m0 > m1) {
|
||||
np->tm[0] = m0; // 0-branch is better
|
||||
np->tm[1] = m1;
|
||||
|
@ -217,13 +217,13 @@ int fano(unsigned int *metric, // Final path metric (returned value)
|
|||
|
||||
// Back up
|
||||
if (--np < tail && np->i != 1) {
|
||||
np->i++; // Search next best branch
|
||||
np->i++; // Search next best branch
|
||||
np->encstate ^= 1;
|
||||
break;
|
||||
} // else keep looking back
|
||||
} // else keep looking back
|
||||
}
|
||||
}
|
||||
*metric = np->gamma; // Return the final path metric
|
||||
*metric = np->gamma; // Return the final path metric
|
||||
|
||||
// Copy decoded data to user's buffer
|
||||
nbits >>= 3;
|
||||
|
@ -233,11 +233,11 @@ int fano(unsigned int *metric, // Final path metric (returned value)
|
|||
*data++ = np->encstate;
|
||||
np += 8;
|
||||
}
|
||||
*cycles = i+1;
|
||||
*cycles = i + 1;
|
||||
|
||||
free(nodes);
|
||||
if (i >= maxcycles)
|
||||
return -1; // Decoder timed out
|
||||
return -1; // Decoder timed out
|
||||
|
||||
return 0; // Successful completion
|
||||
return 0; // Successful completion
|
||||
}
|
||||
|
|
19
wsprd/fano.h
19
wsprd/fano.h
|
@ -32,12 +32,13 @@ extern unsigned char Partab[];
|
|||
* POLY1 goes into the 2-bit of sym, and the symbol generated from POLY2
|
||||
* goes into the 1-bit.
|
||||
*/
|
||||
#define ENCODE(sym, encstate) {\
|
||||
unsigned long _tmp;\
|
||||
_tmp = (encstate) & POLY1;\
|
||||
_tmp ^= _tmp >> 16;\
|
||||
(sym) = Partab[(_tmp ^ (_tmp >> 8)) & 0xff] << 1;\
|
||||
_tmp = (encstate) & POLY2;\
|
||||
_tmp ^= _tmp >> 16;\
|
||||
(sym) |= Partab[(_tmp ^ (_tmp >> 8)) & 0xff];\
|
||||
}
|
||||
#define ENCODE(sym, encstate) \
|
||||
{ \
|
||||
unsigned long _tmp; \
|
||||
_tmp = (encstate)&POLY1; \
|
||||
_tmp ^= _tmp >> 16; \
|
||||
(sym) = Partab[(_tmp ^ (_tmp >> 8)) & 0xff] << 1; \
|
||||
_tmp = (encstate)&POLY2; \
|
||||
_tmp ^= _tmp >> 16; \
|
||||
(sym) |= Partab[(_tmp ^ (_tmp >> 8)) & 0xff]; \
|
||||
}
|
||||
|
|
|
@ -1,118 +1,117 @@
|
|||
/*******************************************************************************
|
||||
* 4 metric tables calculated via simulation for 2-FSK with Es/No=0,3,6,9 dB
|
||||
* tables were calculated for constant rms noise level of 50. The symbol vector
|
||||
* should be normalized to have rms amplitude equal to "symbol_scale".
|
||||
********************************************************************************/
|
||||
* 4 metric tables calculated via simulation for 2-FSK with Es/No=0,3,6,9 dB
|
||||
* tables were calculated for constant rms noise level of 50. The symbol vector
|
||||
* should be normalized to have rms amplitude equal to "symbol_scale".
|
||||
********************************************************************************/
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmissing-braces"
|
||||
|
||||
//float symbol_scale[4]={42.6, 53.3, 72.7, 100.2};
|
||||
static const float metric_tables[4][256]= {
|
||||
0.9782, 0.9695, 0.9689, 0.9669, 0.9666, 0.9653, 0.9638, 0.9618, 0.9599, 0.9601,
|
||||
0.9592, 0.9570, 0.9556, 0.9540, 0.9525, 0.9527, 0.9486, 0.9477, 0.9450, 0.9436,
|
||||
0.9424, 0.9400, 0.9381, 0.9360, 0.9340, 0.9316, 0.9301, 0.9272, 0.9254, 0.9224,
|
||||
0.9196, 0.9171, 0.9154, 0.9123, 0.9076, 0.9061, 0.9030, 0.9000, 0.8965, 0.8934,
|
||||
0.8903, 0.8874, 0.8834, 0.8792, 0.8760, 0.8726, 0.8685, 0.8639, 0.8599, 0.8550,
|
||||
0.8504, 0.8459, 0.8422, 0.8364, 0.8320, 0.8262, 0.8215, 0.8159, 0.8111, 0.8052,
|
||||
0.7996, 0.7932, 0.7878, 0.7812, 0.7745, 0.7685, 0.7616, 0.7550, 0.7479, 0.7405,
|
||||
0.7336, 0.7255, 0.7184, 0.7102, 0.7016, 0.6946, 0.6860, 0.6769, 0.6687, 0.6598,
|
||||
0.6503, 0.6416, 0.6325, 0.6219, 0.6122, 0.6016, 0.5920, 0.5818, 0.5711, 0.5606,
|
||||
0.5487, 0.5374, 0.5266, 0.5142, 0.5020, 0.4908, 0.4784, 0.4663, 0.4532, 0.4405,
|
||||
0.4271, 0.4144, 0.4006, 0.3865, 0.3731, 0.3594, 0.3455, 0.3304, 0.3158, 0.3009,
|
||||
0.2858, 0.2708, 0.2560, 0.2399, 0.2233, 0.2074, 0.1919, 0.1756, 0.1590, 0.1427,
|
||||
0.1251, 0.1074, 0.0905, 0.0722, 0.0550, 0.0381, 0.0183, 0.0000, -0.0185, -0.0391,
|
||||
-0.0571, -0.0760, -0.0966, -0.1160, -0.1370, -0.1584, -0.1787, -0.1999, -0.2214, -0.2423,
|
||||
-0.2643, -0.2879, -0.3114, -0.3336, -0.3568, -0.3806, -0.4050, -0.4293, -0.4552, -0.4798,
|
||||
-0.5046, -0.5296, -0.5564, -0.5836, -0.6093, -0.6372, -0.6645, -0.6933, -0.7208, -0.7495,
|
||||
-0.7763, -0.8065, -0.8378, -0.8660, -0.8964, -0.9293, -0.9592, -0.9907, -1.0214, -1.0509,
|
||||
-1.0850, -1.1168, -1.1528, -1.1847, -1.2157, -1.2511, -1.2850, -1.3174, -1.3540, -1.3900,
|
||||
-1.4201, -1.4580, -1.4956, -1.5292, -1.5683, -1.6030, -1.6411, -1.6789, -1.7147, -1.7539,
|
||||
-1.7887, -1.8289, -1.8699, -1.9043, -1.9469, -1.9849, -2.0267, -2.0610, -2.1028, -2.1391,
|
||||
-2.1855, -2.2215, -2.2712, -2.3033, -2.3440, -2.3870, -2.4342, -2.4738, -2.5209, -2.5646,
|
||||
-2.6016, -2.6385, -2.6868, -2.7356, -2.7723, -2.8111, -2.8524, -2.9009, -2.9428, -2.9879,
|
||||
-3.0103, -3.0832, -3.1340, -3.1628, -3.2049, -3.2557, -3.3101, -3.3453, -3.4025, -3.4317,
|
||||
-3.4828, -3.5270, -3.5745, -3.6181, -3.6765, -3.7044, -3.7410, -3.8118, -3.8368, -3.9549,
|
||||
-3.9488, -3.9941, -4.0428, -4.0892, -4.1648, -4.1965, -4.1892, -4.2565, -4.3356, -4.3948,
|
||||
-4.4481, -4.4607, -4.5533, -4.5809, -4.5927, -5.1047,
|
||||
0.9978, 0.9962, 0.9961, 0.9959, 0.9958, 0.9954, 0.9949, 0.9950, 0.9947, 0.9942,
|
||||
0.9940, 0.9939, 0.9933, 0.9931, 0.9928, 0.9924, 0.9921, 0.9916, 0.9911, 0.9909,
|
||||
0.9903, 0.9900, 0.9892, 0.9887, 0.9883, 0.9877, 0.9869, 0.9863, 0.9857, 0.9848,
|
||||
0.9842, 0.9835, 0.9825, 0.9817, 0.9808, 0.9799, 0.9791, 0.9777, 0.9767, 0.9757,
|
||||
0.9744, 0.9729, 0.9716, 0.9704, 0.9690, 0.9674, 0.9656, 0.9641, 0.9625, 0.9609,
|
||||
0.9587, 0.9567, 0.9548, 0.9524, 0.9501, 0.9478, 0.9453, 0.9426, 0.9398, 0.9371,
|
||||
0.9339, 0.9311, 0.9277, 0.9242, 0.9206, 0.9168, 0.9131, 0.9087, 0.9043, 0.8999,
|
||||
0.8953, 0.8907, 0.8857, 0.8803, 0.8747, 0.8690, 0.8632, 0.8572, 0.8507, 0.8439,
|
||||
0.8368, 0.8295, 0.8217, 0.8138, 0.8058, 0.7972, 0.7883, 0.7784, 0.7694, 0.7597,
|
||||
0.7489, 0.7378, 0.7269, 0.7152, 0.7030, 0.6911, 0.6782, 0.6643, 0.6506, 0.6371,
|
||||
0.6211, 0.6054, 0.5897, 0.5740, 0.5565, 0.5393, 0.5214, 0.5027, 0.4838, 0.4643,
|
||||
0.4436, 0.4225, 0.4004, 0.3787, 0.3562, 0.3324, 0.3089, 0.2839, 0.2584, 0.2321,
|
||||
0.2047, 0.1784, 0.1499, 0.1213, 0.0915, 0.0628, 0.0314, 0.0000, -0.0321, -0.0657,
|
||||
-0.0977, -0.1324, -0.1673, -0.2036, -0.2387, -0.2768, -0.3150, -0.3538, -0.3936, -0.4327,
|
||||
-0.4739, -0.5148, -0.5561, -0.6000, -0.6438, -0.6889, -0.7331, -0.7781, -0.8247, -0.8712,
|
||||
-0.9177, -0.9677, -1.0142, -1.0631, -1.1143, -1.1686, -1.2169, -1.2680, -1.3223, -1.3752,
|
||||
-1.4261, -1.4806, -1.5356, -1.5890, -1.6462, -1.7041, -1.7591, -1.8124, -1.8735, -1.9311,
|
||||
-1.9891, -2.0459, -2.1048, -2.1653, -2.2248, -2.2855, -2.3466, -2.4079, -2.4668, -2.5263,
|
||||
-2.5876, -2.6507, -2.7142, -2.7761, -2.8366, -2.8995, -2.9620, -3.0279, -3.0973, -3.1576,
|
||||
-3.2238, -3.2890, -3.3554, -3.4215, -3.4805, -3.5518, -3.6133, -3.6812, -3.7473, -3.8140,
|
||||
-3.8781, -3.9450, -4.0184, -4.0794, -4.1478, -4.2241, -4.2853, -4.3473, -4.4062, -4.4839,
|
||||
-4.5539, -4.6202, -4.6794, -4.7478, -4.8309, -4.9048, -4.9669, -5.0294, -5.1194, -5.1732,
|
||||
-5.2378, -5.3094, -5.3742, -5.4573, -5.5190, -5.5728, -5.6637, -5.7259, -5.7843, -5.8854,
|
||||
-5.9553, -6.0054, -6.0656, -6.1707, -6.2241, -6.3139, -6.3393, -6.4356, -6.5153, -6.5758,
|
||||
-6.6506, -6.7193, -6.7542, -6.8942, -6.9219, -6.9605, -7.1013, -7.1895, -7.1549, -7.2799,
|
||||
-7.4119, -7.4608, -7.5256, -7.5879, -7.7598, -8.4120,
|
||||
0.9999, 0.9998, 0.9998, 0.9998, 0.9998, 0.9998, 0.9997, 0.9997, 0.9997, 0.9997,
|
||||
0.9997, 0.9996, 0.9996, 0.9996, 0.9995, 0.9995, 0.9994, 0.9994, 0.9994, 0.9993,
|
||||
0.9993, 0.9992, 0.9991, 0.9991, 0.9990, 0.9989, 0.9988, 0.9988, 0.9988, 0.9986,
|
||||
0.9985, 0.9984, 0.9983, 0.9982, 0.9980, 0.9979, 0.9977, 0.9976, 0.9974, 0.9971,
|
||||
0.9969, 0.9968, 0.9965, 0.9962, 0.9960, 0.9957, 0.9953, 0.9950, 0.9947, 0.9941,
|
||||
0.9937, 0.9933, 0.9928, 0.9922, 0.9917, 0.9911, 0.9904, 0.9897, 0.9890, 0.9882,
|
||||
0.9874, 0.9863, 0.9855, 0.9843, 0.9832, 0.9819, 0.9806, 0.9792, 0.9777, 0.9760,
|
||||
0.9743, 0.9724, 0.9704, 0.9683, 0.9659, 0.9634, 0.9609, 0.9581, 0.9550, 0.9516,
|
||||
0.9481, 0.9446, 0.9406, 0.9363, 0.9317, 0.9270, 0.9218, 0.9160, 0.9103, 0.9038,
|
||||
0.8972, 0.8898, 0.8822, 0.8739, 0.8647, 0.8554, 0.8457, 0.8357, 0.8231, 0.8115,
|
||||
0.7984, 0.7854, 0.7704, 0.7556, 0.7391, 0.7210, 0.7038, 0.6840, 0.6633, 0.6408,
|
||||
0.6174, 0.5939, 0.5678, 0.5410, 0.5137, 0.4836, 0.4524, 0.4193, 0.3850, 0.3482,
|
||||
0.3132, 0.2733, 0.2315, 0.1891, 0.1435, 0.0980, 0.0493, 0.0000, -0.0510, -0.1052,
|
||||
-0.1593, -0.2177, -0.2759, -0.3374, -0.4005, -0.4599, -0.5266, -0.5935, -0.6626, -0.7328,
|
||||
-0.8051, -0.8757, -0.9498, -1.0271, -1.1019, -1.1816, -1.2642, -1.3459, -1.4295, -1.5077,
|
||||
-1.5958, -1.6818, -1.7647, -1.8548, -1.9387, -2.0295, -2.1152, -2.2154, -2.3011, -2.3904,
|
||||
-2.4820, -2.5786, -2.6730, -2.7652, -2.8616, -2.9546, -3.0526, -3.1445, -3.2445, -3.3416,
|
||||
-3.4357, -3.5325, -3.6324, -3.7313, -3.8225, -3.9209, -4.0248, -4.1278, -4.2261, -4.3193,
|
||||
-4.4220, -4.5262, -4.6214, -4.7242, -4.8234, -4.9245, -5.0298, -5.1250, -5.2232, -5.3267,
|
||||
-5.4332, -5.5342, -5.6431, -5.7270, -5.8401, -5.9350, -6.0407, -6.1418, -6.2363, -6.3384,
|
||||
-6.4536, -6.5429, -6.6582, -6.7433, -6.8438, -6.9478, -7.0789, -7.1894, -7.2714, -7.3815,
|
||||
-7.4810, -7.5575, -7.6852, -7.8071, -7.8580, -7.9724, -8.1000, -8.2207, -8.2867, -8.4017,
|
||||
-8.5287, -8.6347, -8.7082, -8.8319, -8.9448, -9.0355, -9.1885, -9.2095, -9.2863, -9.4186,
|
||||
-9.5064, -9.6386, -9.7207, -9.8286, -9.9453, -10.0701, -10.1735, -10.3001, -10.2858, -10.5427,
|
||||
-10.5982, -10.7361, -10.7042, -10.9212, -11.0097, -11.0469, -11.1155, -11.2812, -11.3472, -11.4988,
|
||||
-11.5327, -11.6692, -11.9376, -11.8606, -12.1372, -13.2539,
|
||||
1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
|
||||
1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
|
||||
1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
|
||||
0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999,
|
||||
0.9999, 0.9998, 0.9998, 0.9998, 0.9998, 0.9997, 0.9997, 0.9997, 0.9997, 0.9996,
|
||||
0.9996, 0.9995, 0.9995, 0.9994, 0.9994, 0.9993, 0.9992, 0.9991, 0.9991, 0.9989,
|
||||
0.9988, 0.9986, 0.9985, 0.9983, 0.9981, 0.9980, 0.9977, 0.9974, 0.9971, 0.9968,
|
||||
0.9965, 0.9962, 0.9956, 0.9950, 0.9948, 0.9941, 0.9933, 0.9926, 0.9919, 0.9910,
|
||||
0.9899, 0.9889, 0.9877, 0.9863, 0.9845, 0.9829, 0.9811, 0.9791, 0.9769, 0.9741,
|
||||
0.9716, 0.9684, 0.9645, 0.9611, 0.9563, 0.9519, 0.9463, 0.9406, 0.9344, 0.9272,
|
||||
0.9197, 0.9107, 0.9016, 0.8903, 0.8791, 0.8653, 0.8523, 0.8357, 0.8179, 0.7988,
|
||||
0.7779, 0.7562, 0.7318, 0.7024, 0.6753, 0.6435, 0.6089, 0.5700, 0.5296, 0.4860,
|
||||
0.4366, 0.3855, 0.3301, 0.2735, 0.2114, 0.1443, 0.0682, 0.0000, -0.0715, -0.1604,
|
||||
-0.2478, -0.3377, -0.4287, -0.5277, -0.6291, -0.7384, -0.8457, -0.9559, -1.0742, -1.1913,
|
||||
-1.3110, -1.4238, -1.5594, -1.6854, -1.8093, -1.9414, -2.0763, -2.2160, -2.3611, -2.4876,
|
||||
-2.6374, -2.7710, -2.9225, -3.0591, -3.2077, -3.3452, -3.4916, -3.6316, -3.7735, -3.9296,
|
||||
-4.0682, -4.2334, -4.3607, -4.5270, -4.6807, -4.8108, -4.9753, -5.1212, -5.2631, -5.4042,
|
||||
-5.5510, -5.7227, -5.8794, -6.0244, -6.1677, -6.3271, -6.4862, -6.6130, -6.7449, -6.9250,
|
||||
-7.1232, -7.1736, -7.3628, -7.5596, -7.6906, -7.8129, -7.9817, -8.1440, -8.3016, -8.4797,
|
||||
-8.5734, -8.7692, -8.9198, -9.0610, -9.1746, -9.3536, -9.5939, -9.6957, -9.8475, -9.9639,
|
||||
-10.1730, -10.2427, -10.4573, -10.5413, -10.7303, -10.9339, -11.0215, -11.2047, -11.2894, -11.4572,
|
||||
-11.6256, -11.7794, -11.8801, -12.1717, -12.2354, -12.3686, -12.6195, -12.6527, -12.8247, -12.9560,
|
||||
-13.3265, -13.1667, -13.4274, -13.6064, -13.5515, -13.9501, -13.9926, -14.4049, -14.1653, -14.4348,
|
||||
-14.7983, -14.7807, -15.2349, -15.3536, -15.3026, -15.2739, -15.7170, -16.2161, -15.9185, -15.9490,
|
||||
-16.6258, -16.5568, -16.4318, -16.7999, -16.4101, -17.6393, -17.7643, -17.2644, -17.5973, -17.0403,
|
||||
-17.7039, -18.0073, -18.1840, -18.3848, -18.6286, -20.7063
|
||||
};
|
||||
// float symbol_scale[4]={42.6, 53.3, 72.7, 100.2};
|
||||
static const float metric_tables[4][256] = {
|
||||
0.9782, 0.9695, 0.9689, 0.9669, 0.9666, 0.9653, 0.9638, 0.9618, 0.9599, 0.9601,
|
||||
0.9592, 0.9570, 0.9556, 0.9540, 0.9525, 0.9527, 0.9486, 0.9477, 0.9450, 0.9436,
|
||||
0.9424, 0.9400, 0.9381, 0.9360, 0.9340, 0.9316, 0.9301, 0.9272, 0.9254, 0.9224,
|
||||
0.9196, 0.9171, 0.9154, 0.9123, 0.9076, 0.9061, 0.9030, 0.9000, 0.8965, 0.8934,
|
||||
0.8903, 0.8874, 0.8834, 0.8792, 0.8760, 0.8726, 0.8685, 0.8639, 0.8599, 0.8550,
|
||||
0.8504, 0.8459, 0.8422, 0.8364, 0.8320, 0.8262, 0.8215, 0.8159, 0.8111, 0.8052,
|
||||
0.7996, 0.7932, 0.7878, 0.7812, 0.7745, 0.7685, 0.7616, 0.7550, 0.7479, 0.7405,
|
||||
0.7336, 0.7255, 0.7184, 0.7102, 0.7016, 0.6946, 0.6860, 0.6769, 0.6687, 0.6598,
|
||||
0.6503, 0.6416, 0.6325, 0.6219, 0.6122, 0.6016, 0.5920, 0.5818, 0.5711, 0.5606,
|
||||
0.5487, 0.5374, 0.5266, 0.5142, 0.5020, 0.4908, 0.4784, 0.4663, 0.4532, 0.4405,
|
||||
0.4271, 0.4144, 0.4006, 0.3865, 0.3731, 0.3594, 0.3455, 0.3304, 0.3158, 0.3009,
|
||||
0.2858, 0.2708, 0.2560, 0.2399, 0.2233, 0.2074, 0.1919, 0.1756, 0.1590, 0.1427,
|
||||
0.1251, 0.1074, 0.0905, 0.0722, 0.0550, 0.0381, 0.0183, 0.0000, -0.0185, -0.0391,
|
||||
-0.0571, -0.0760, -0.0966, -0.1160, -0.1370, -0.1584, -0.1787, -0.1999, -0.2214, -0.2423,
|
||||
-0.2643, -0.2879, -0.3114, -0.3336, -0.3568, -0.3806, -0.4050, -0.4293, -0.4552, -0.4798,
|
||||
-0.5046, -0.5296, -0.5564, -0.5836, -0.6093, -0.6372, -0.6645, -0.6933, -0.7208, -0.7495,
|
||||
-0.7763, -0.8065, -0.8378, -0.8660, -0.8964, -0.9293, -0.9592, -0.9907, -1.0214, -1.0509,
|
||||
-1.0850, -1.1168, -1.1528, -1.1847, -1.2157, -1.2511, -1.2850, -1.3174, -1.3540, -1.3900,
|
||||
-1.4201, -1.4580, -1.4956, -1.5292, -1.5683, -1.6030, -1.6411, -1.6789, -1.7147, -1.7539,
|
||||
-1.7887, -1.8289, -1.8699, -1.9043, -1.9469, -1.9849, -2.0267, -2.0610, -2.1028, -2.1391,
|
||||
-2.1855, -2.2215, -2.2712, -2.3033, -2.3440, -2.3870, -2.4342, -2.4738, -2.5209, -2.5646,
|
||||
-2.6016, -2.6385, -2.6868, -2.7356, -2.7723, -2.8111, -2.8524, -2.9009, -2.9428, -2.9879,
|
||||
-3.0103, -3.0832, -3.1340, -3.1628, -3.2049, -3.2557, -3.3101, -3.3453, -3.4025, -3.4317,
|
||||
-3.4828, -3.5270, -3.5745, -3.6181, -3.6765, -3.7044, -3.7410, -3.8118, -3.8368, -3.9549,
|
||||
-3.9488, -3.9941, -4.0428, -4.0892, -4.1648, -4.1965, -4.1892, -4.2565, -4.3356, -4.3948,
|
||||
-4.4481, -4.4607, -4.5533, -4.5809, -4.5927, -5.1047,
|
||||
0.9978, 0.9962, 0.9961, 0.9959, 0.9958, 0.9954, 0.9949, 0.9950, 0.9947, 0.9942,
|
||||
0.9940, 0.9939, 0.9933, 0.9931, 0.9928, 0.9924, 0.9921, 0.9916, 0.9911, 0.9909,
|
||||
0.9903, 0.9900, 0.9892, 0.9887, 0.9883, 0.9877, 0.9869, 0.9863, 0.9857, 0.9848,
|
||||
0.9842, 0.9835, 0.9825, 0.9817, 0.9808, 0.9799, 0.9791, 0.9777, 0.9767, 0.9757,
|
||||
0.9744, 0.9729, 0.9716, 0.9704, 0.9690, 0.9674, 0.9656, 0.9641, 0.9625, 0.9609,
|
||||
0.9587, 0.9567, 0.9548, 0.9524, 0.9501, 0.9478, 0.9453, 0.9426, 0.9398, 0.9371,
|
||||
0.9339, 0.9311, 0.9277, 0.9242, 0.9206, 0.9168, 0.9131, 0.9087, 0.9043, 0.8999,
|
||||
0.8953, 0.8907, 0.8857, 0.8803, 0.8747, 0.8690, 0.8632, 0.8572, 0.8507, 0.8439,
|
||||
0.8368, 0.8295, 0.8217, 0.8138, 0.8058, 0.7972, 0.7883, 0.7784, 0.7694, 0.7597,
|
||||
0.7489, 0.7378, 0.7269, 0.7152, 0.7030, 0.6911, 0.6782, 0.6643, 0.6506, 0.6371,
|
||||
0.6211, 0.6054, 0.5897, 0.5740, 0.5565, 0.5393, 0.5214, 0.5027, 0.4838, 0.4643,
|
||||
0.4436, 0.4225, 0.4004, 0.3787, 0.3562, 0.3324, 0.3089, 0.2839, 0.2584, 0.2321,
|
||||
0.2047, 0.1784, 0.1499, 0.1213, 0.0915, 0.0628, 0.0314, 0.0000, -0.0321, -0.0657,
|
||||
-0.0977, -0.1324, -0.1673, -0.2036, -0.2387, -0.2768, -0.3150, -0.3538, -0.3936, -0.4327,
|
||||
-0.4739, -0.5148, -0.5561, -0.6000, -0.6438, -0.6889, -0.7331, -0.7781, -0.8247, -0.8712,
|
||||
-0.9177, -0.9677, -1.0142, -1.0631, -1.1143, -1.1686, -1.2169, -1.2680, -1.3223, -1.3752,
|
||||
-1.4261, -1.4806, -1.5356, -1.5890, -1.6462, -1.7041, -1.7591, -1.8124, -1.8735, -1.9311,
|
||||
-1.9891, -2.0459, -2.1048, -2.1653, -2.2248, -2.2855, -2.3466, -2.4079, -2.4668, -2.5263,
|
||||
-2.5876, -2.6507, -2.7142, -2.7761, -2.8366, -2.8995, -2.9620, -3.0279, -3.0973, -3.1576,
|
||||
-3.2238, -3.2890, -3.3554, -3.4215, -3.4805, -3.5518, -3.6133, -3.6812, -3.7473, -3.8140,
|
||||
-3.8781, -3.9450, -4.0184, -4.0794, -4.1478, -4.2241, -4.2853, -4.3473, -4.4062, -4.4839,
|
||||
-4.5539, -4.6202, -4.6794, -4.7478, -4.8309, -4.9048, -4.9669, -5.0294, -5.1194, -5.1732,
|
||||
-5.2378, -5.3094, -5.3742, -5.4573, -5.5190, -5.5728, -5.6637, -5.7259, -5.7843, -5.8854,
|
||||
-5.9553, -6.0054, -6.0656, -6.1707, -6.2241, -6.3139, -6.3393, -6.4356, -6.5153, -6.5758,
|
||||
-6.6506, -6.7193, -6.7542, -6.8942, -6.9219, -6.9605, -7.1013, -7.1895, -7.1549, -7.2799,
|
||||
-7.4119, -7.4608, -7.5256, -7.5879, -7.7598, -8.4120,
|
||||
0.9999, 0.9998, 0.9998, 0.9998, 0.9998, 0.9998, 0.9997, 0.9997, 0.9997, 0.9997,
|
||||
0.9997, 0.9996, 0.9996, 0.9996, 0.9995, 0.9995, 0.9994, 0.9994, 0.9994, 0.9993,
|
||||
0.9993, 0.9992, 0.9991, 0.9991, 0.9990, 0.9989, 0.9988, 0.9988, 0.9988, 0.9986,
|
||||
0.9985, 0.9984, 0.9983, 0.9982, 0.9980, 0.9979, 0.9977, 0.9976, 0.9974, 0.9971,
|
||||
0.9969, 0.9968, 0.9965, 0.9962, 0.9960, 0.9957, 0.9953, 0.9950, 0.9947, 0.9941,
|
||||
0.9937, 0.9933, 0.9928, 0.9922, 0.9917, 0.9911, 0.9904, 0.9897, 0.9890, 0.9882,
|
||||
0.9874, 0.9863, 0.9855, 0.9843, 0.9832, 0.9819, 0.9806, 0.9792, 0.9777, 0.9760,
|
||||
0.9743, 0.9724, 0.9704, 0.9683, 0.9659, 0.9634, 0.9609, 0.9581, 0.9550, 0.9516,
|
||||
0.9481, 0.9446, 0.9406, 0.9363, 0.9317, 0.9270, 0.9218, 0.9160, 0.9103, 0.9038,
|
||||
0.8972, 0.8898, 0.8822, 0.8739, 0.8647, 0.8554, 0.8457, 0.8357, 0.8231, 0.8115,
|
||||
0.7984, 0.7854, 0.7704, 0.7556, 0.7391, 0.7210, 0.7038, 0.6840, 0.6633, 0.6408,
|
||||
0.6174, 0.5939, 0.5678, 0.5410, 0.5137, 0.4836, 0.4524, 0.4193, 0.3850, 0.3482,
|
||||
0.3132, 0.2733, 0.2315, 0.1891, 0.1435, 0.0980, 0.0493, 0.0000, -0.0510, -0.1052,
|
||||
-0.1593, -0.2177, -0.2759, -0.3374, -0.4005, -0.4599, -0.5266, -0.5935, -0.6626, -0.7328,
|
||||
-0.8051, -0.8757, -0.9498, -1.0271, -1.1019, -1.1816, -1.2642, -1.3459, -1.4295, -1.5077,
|
||||
-1.5958, -1.6818, -1.7647, -1.8548, -1.9387, -2.0295, -2.1152, -2.2154, -2.3011, -2.3904,
|
||||
-2.4820, -2.5786, -2.6730, -2.7652, -2.8616, -2.9546, -3.0526, -3.1445, -3.2445, -3.3416,
|
||||
-3.4357, -3.5325, -3.6324, -3.7313, -3.8225, -3.9209, -4.0248, -4.1278, -4.2261, -4.3193,
|
||||
-4.4220, -4.5262, -4.6214, -4.7242, -4.8234, -4.9245, -5.0298, -5.1250, -5.2232, -5.3267,
|
||||
-5.4332, -5.5342, -5.6431, -5.7270, -5.8401, -5.9350, -6.0407, -6.1418, -6.2363, -6.3384,
|
||||
-6.4536, -6.5429, -6.6582, -6.7433, -6.8438, -6.9478, -7.0789, -7.1894, -7.2714, -7.3815,
|
||||
-7.4810, -7.5575, -7.6852, -7.8071, -7.8580, -7.9724, -8.1000, -8.2207, -8.2867, -8.4017,
|
||||
-8.5287, -8.6347, -8.7082, -8.8319, -8.9448, -9.0355, -9.1885, -9.2095, -9.2863, -9.4186,
|
||||
-9.5064, -9.6386, -9.7207, -9.8286, -9.9453, -10.0701, -10.1735, -10.3001, -10.2858, -10.5427,
|
||||
-10.5982, -10.7361, -10.7042, -10.9212, -11.0097, -11.0469, -11.1155, -11.2812, -11.3472, -11.4988,
|
||||
-11.5327, -11.6692, -11.9376, -11.8606, -12.1372, -13.2539,
|
||||
1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
|
||||
1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
|
||||
1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
|
||||
0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999,
|
||||
0.9999, 0.9998, 0.9998, 0.9998, 0.9998, 0.9997, 0.9997, 0.9997, 0.9997, 0.9996,
|
||||
0.9996, 0.9995, 0.9995, 0.9994, 0.9994, 0.9993, 0.9992, 0.9991, 0.9991, 0.9989,
|
||||
0.9988, 0.9986, 0.9985, 0.9983, 0.9981, 0.9980, 0.9977, 0.9974, 0.9971, 0.9968,
|
||||
0.9965, 0.9962, 0.9956, 0.9950, 0.9948, 0.9941, 0.9933, 0.9926, 0.9919, 0.9910,
|
||||
0.9899, 0.9889, 0.9877, 0.9863, 0.9845, 0.9829, 0.9811, 0.9791, 0.9769, 0.9741,
|
||||
0.9716, 0.9684, 0.9645, 0.9611, 0.9563, 0.9519, 0.9463, 0.9406, 0.9344, 0.9272,
|
||||
0.9197, 0.9107, 0.9016, 0.8903, 0.8791, 0.8653, 0.8523, 0.8357, 0.8179, 0.7988,
|
||||
0.7779, 0.7562, 0.7318, 0.7024, 0.6753, 0.6435, 0.6089, 0.5700, 0.5296, 0.4860,
|
||||
0.4366, 0.3855, 0.3301, 0.2735, 0.2114, 0.1443, 0.0682, 0.0000, -0.0715, -0.1604,
|
||||
-0.2478, -0.3377, -0.4287, -0.5277, -0.6291, -0.7384, -0.8457, -0.9559, -1.0742, -1.1913,
|
||||
-1.3110, -1.4238, -1.5594, -1.6854, -1.8093, -1.9414, -2.0763, -2.2160, -2.3611, -2.4876,
|
||||
-2.6374, -2.7710, -2.9225, -3.0591, -3.2077, -3.3452, -3.4916, -3.6316, -3.7735, -3.9296,
|
||||
-4.0682, -4.2334, -4.3607, -4.5270, -4.6807, -4.8108, -4.9753, -5.1212, -5.2631, -5.4042,
|
||||
-5.5510, -5.7227, -5.8794, -6.0244, -6.1677, -6.3271, -6.4862, -6.6130, -6.7449, -6.9250,
|
||||
-7.1232, -7.1736, -7.3628, -7.5596, -7.6906, -7.8129, -7.9817, -8.1440, -8.3016, -8.4797,
|
||||
-8.5734, -8.7692, -8.9198, -9.0610, -9.1746, -9.3536, -9.5939, -9.6957, -9.8475, -9.9639,
|
||||
-10.1730, -10.2427, -10.4573, -10.5413, -10.7303, -10.9339, -11.0215, -11.2047, -11.2894, -11.4572,
|
||||
-11.6256, -11.7794, -11.8801, -12.1717, -12.2354, -12.3686, -12.6195, -12.6527, -12.8247, -12.9560,
|
||||
-13.3265, -13.1667, -13.4274, -13.6064, -13.5515, -13.9501, -13.9926, -14.4049, -14.1653, -14.4348,
|
||||
-14.7983, -14.7807, -15.2349, -15.3536, -15.3026, -15.2739, -15.7170, -16.2161, -15.9185, -15.9490,
|
||||
-16.6258, -16.5568, -16.4318, -16.7999, -16.4101, -17.6393, -17.7643, -17.2644, -17.5973, -17.0403,
|
||||
-17.7039, -18.0073, -18.1840, -18.3848, -18.6286, -20.7063};
|
||||
|
||||
#pragma GCC diagnostic pop
|
402
wsprd/nhash.c
402
wsprd/nhash.c
|
@ -81,9 +81,9 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy.
|
|||
|
||||
#define HASH_LITTLE_ENDIAN 1
|
||||
|
||||
#define hashsize(n) ((uint32_t)1<<(n))
|
||||
#define hashmask(n) (hashsize(n)-1)
|
||||
#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
|
||||
#define hashsize(n) ((uint32_t)1 << (n))
|
||||
#define hashmask(n) (hashsize(n) - 1)
|
||||
#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
|
||||
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
|
@ -129,15 +129,15 @@ on, and rotates are much kinder to the top and bottom bits, so I used
|
|||
rotates.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
#define mix(a,b,c) \
|
||||
{ \
|
||||
a -= c; a ^= rot(c, 4); c += b; \
|
||||
b -= a; b ^= rot(a, 6); a += c; \
|
||||
c -= b; c ^= rot(b, 8); b += a; \
|
||||
a -= c; a ^= rot(c,16); c += b; \
|
||||
b -= a; b ^= rot(a,19); a += c; \
|
||||
c -= b; c ^= rot(b, 4); b += a; \
|
||||
}
|
||||
#define mix(a, b, c) \
|
||||
{ \
|
||||
a -= c; a ^= rot(c, 4); c += b; \
|
||||
b -= a; b ^= rot(a, 6); a += c; \
|
||||
c -= b; c ^= rot(b, 8); b += a; \
|
||||
a -= c; a ^= rot(c,16); c += b; \
|
||||
b -= a; b ^= rot(a,19); a += c; \
|
||||
c -= b; c ^= rot(b, 4); b += a; \
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
|
@ -164,16 +164,16 @@ and these came close:
|
|||
11 8 15 26 3 22 24
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
#define final(a,b,c) \
|
||||
{ \
|
||||
c ^= b; c -= rot(b,14); \
|
||||
a ^= c; a -= rot(c,11); \
|
||||
b ^= a; b -= rot(a,25); \
|
||||
c ^= b; c -= rot(b,16); \
|
||||
a ^= c; a -= rot(c,4); \
|
||||
b ^= a; b -= rot(a,14); \
|
||||
c ^= b; c -= rot(b,24); \
|
||||
}
|
||||
#define final(a, b, c) \
|
||||
{ \
|
||||
c ^= b; c -= rot(b,14); \
|
||||
a ^= c; a -= rot(c,11); \
|
||||
b ^= a; b -= rot(a,25); \
|
||||
c ^= b; c -= rot(b,16); \
|
||||
a ^= c; a -= rot(c,4); \
|
||||
b ^= a; b -= rot(a,14); \
|
||||
c ^= b; c -= rot(b,24); \
|
||||
}
|
||||
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
|
@ -202,26 +202,26 @@ acceptable. Do NOT use for cryptographic purposes.
|
|||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
uint32_t nhash( const void *key, size_t length, uint32_t initval) {
|
||||
uint32_t a,b,c; /* internal state */
|
||||
uint32_t nhash(const void *key, size_t length, uint32_t initval) {
|
||||
uint32_t a, b, c; /* internal state */
|
||||
union {
|
||||
const void *ptr;
|
||||
size_t i;
|
||||
} u; /* needed for Mac Powerbook G4 */
|
||||
} u; /* needed for Mac Powerbook G4 */
|
||||
|
||||
/* Set up the internal state */
|
||||
a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
|
||||
|
||||
u.ptr = key;
|
||||
if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
|
||||
const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
|
||||
const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
|
||||
|
||||
/*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
|
||||
while (length > 12) {
|
||||
a += k[0];
|
||||
b += k[1];
|
||||
c += k[2];
|
||||
mix(a,b,c);
|
||||
mix(a, b, c);
|
||||
length -= 12;
|
||||
k += 3;
|
||||
}
|
||||
|
@ -238,214 +238,214 @@ uint32_t nhash( const void *key, size_t length, uint32_t initval) {
|
|||
*/
|
||||
#ifndef VALGRIND
|
||||
|
||||
switch(length) {
|
||||
case 12:
|
||||
c+=k[2];
|
||||
b+=k[1];
|
||||
a+=k[0];
|
||||
break;
|
||||
case 11:
|
||||
c+=k[2]&0xffffff;
|
||||
b+=k[1];
|
||||
a+=k[0];
|
||||
break;
|
||||
case 10:
|
||||
c+=k[2]&0xffff;
|
||||
b+=k[1];
|
||||
a+=k[0];
|
||||
break;
|
||||
case 9 :
|
||||
c+=k[2]&0xff;
|
||||
b+=k[1];
|
||||
a+=k[0];
|
||||
break;
|
||||
case 8 :
|
||||
b+=k[1];
|
||||
a+=k[0];
|
||||
break;
|
||||
case 7 :
|
||||
b+=k[1]&0xffffff;
|
||||
a+=k[0];
|
||||
break;
|
||||
case 6 :
|
||||
b+=k[1]&0xffff;
|
||||
a+=k[0];
|
||||
break;
|
||||
case 5 :
|
||||
b+=k[1]&0xff;
|
||||
a+=k[0];
|
||||
break;
|
||||
case 4 :
|
||||
a+=k[0];
|
||||
break;
|
||||
case 3 :
|
||||
a+=k[0]&0xffffff;
|
||||
break;
|
||||
case 2 :
|
||||
a+=k[0]&0xffff;
|
||||
break;
|
||||
case 1 :
|
||||
a+=k[0]&0xff;
|
||||
break;
|
||||
case 0 :
|
||||
return c; /* zero length strings require no mixing */
|
||||
switch (length) {
|
||||
case 12:
|
||||
c += k[2];
|
||||
b += k[1];
|
||||
a += k[0];
|
||||
break;
|
||||
case 11:
|
||||
c += k[2] & 0xffffff;
|
||||
b += k[1];
|
||||
a += k[0];
|
||||
break;
|
||||
case 10:
|
||||
c += k[2] & 0xffff;
|
||||
b += k[1];
|
||||
a += k[0];
|
||||
break;
|
||||
case 9:
|
||||
c += k[2] & 0xff;
|
||||
b += k[1];
|
||||
a += k[0];
|
||||
break;
|
||||
case 8:
|
||||
b += k[1];
|
||||
a += k[0];
|
||||
break;
|
||||
case 7:
|
||||
b += k[1] & 0xffffff;
|
||||
a += k[0];
|
||||
break;
|
||||
case 6:
|
||||
b += k[1] & 0xffff;
|
||||
a += k[0];
|
||||
break;
|
||||
case 5:
|
||||
b += k[1] & 0xff;
|
||||
a += k[0];
|
||||
break;
|
||||
case 4:
|
||||
a += k[0];
|
||||
break;
|
||||
case 3:
|
||||
a += k[0] & 0xffffff;
|
||||
break;
|
||||
case 2:
|
||||
a += k[0] & 0xffff;
|
||||
break;
|
||||
case 1:
|
||||
a += k[0] & 0xff;
|
||||
break;
|
||||
case 0:
|
||||
return c; /* zero length strings require no mixing */
|
||||
}
|
||||
|
||||
#else /* make valgrind happy */
|
||||
|
||||
k8 = (const uint8_t *)k;
|
||||
switch(length) {
|
||||
case 12:
|
||||
c+=k[2];
|
||||
b+=k[1];
|
||||
a+=k[0];
|
||||
break;
|
||||
case 11:
|
||||
c+=((uint32_t)k8[10])<<16; /* fall through */
|
||||
case 10:
|
||||
c+=((uint32_t)k8[9])<<8; /* fall through */
|
||||
case 9 :
|
||||
c+=k8[8]; /* fall through */
|
||||
case 8 :
|
||||
b+=k[1];
|
||||
a+=k[0];
|
||||
break;
|
||||
case 7 :
|
||||
b+=((uint32_t)k8[6])<<16; /* fall through */
|
||||
case 6 :
|
||||
b+=((uint32_t)k8[5])<<8; /* fall through */
|
||||
case 5 :
|
||||
b+=k8[4]; /* fall through */
|
||||
case 4 :
|
||||
a+=k[0];
|
||||
break;
|
||||
case 3 :
|
||||
a+=((uint32_t)k8[2])<<16; /* fall through */
|
||||
case 2 :
|
||||
a+=((uint32_t)k8[1])<<8; /* fall through */
|
||||
case 1 :
|
||||
a+=k8[0];
|
||||
break;
|
||||
case 0 :
|
||||
return c;
|
||||
switch (length) {
|
||||
case 12:
|
||||
c += k[2];
|
||||
b += k[1];
|
||||
a += k[0];
|
||||
break;
|
||||
case 11:
|
||||
c += ((uint32_t)k8[10]) << 16; /* fall through */
|
||||
case 10:
|
||||
c += ((uint32_t)k8[9]) << 8; /* fall through */
|
||||
case 9:
|
||||
c += k8[8]; /* fall through */
|
||||
case 8:
|
||||
b += k[1];
|
||||
a += k[0];
|
||||
break;
|
||||
case 7:
|
||||
b += ((uint32_t)k8[6]) << 16; /* fall through */
|
||||
case 6:
|
||||
b += ((uint32_t)k8[5]) << 8; /* fall through */
|
||||
case 5:
|
||||
b += k8[4]; /* fall through */
|
||||
case 4:
|
||||
a += k[0];
|
||||
break;
|
||||
case 3:
|
||||
a += ((uint32_t)k8[2]) << 16; /* fall through */
|
||||
case 2:
|
||||
a += ((uint32_t)k8[1]) << 8; /* fall through */
|
||||
case 1:
|
||||
a += k8[0];
|
||||
break;
|
||||
case 0:
|
||||
return c;
|
||||
}
|
||||
|
||||
#endif /* !valgrind */
|
||||
|
||||
} else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
|
||||
const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
|
||||
const uint8_t *k8;
|
||||
const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
|
||||
const uint8_t *k8;
|
||||
|
||||
/*--------------- all but last block: aligned reads and different mixing */
|
||||
while (length > 12) {
|
||||
a += k[0] + (((uint32_t)k[1])<<16);
|
||||
b += k[2] + (((uint32_t)k[3])<<16);
|
||||
c += k[4] + (((uint32_t)k[5])<<16);
|
||||
mix(a,b,c);
|
||||
a += k[0] + (((uint32_t)k[1]) << 16);
|
||||
b += k[2] + (((uint32_t)k[3]) << 16);
|
||||
c += k[4] + (((uint32_t)k[5]) << 16);
|
||||
mix(a, b, c);
|
||||
length -= 12;
|
||||
k += 6;
|
||||
}
|
||||
|
||||
/*----------------------------- handle the last (probably partial) block */
|
||||
k8 = (const uint8_t *)k;
|
||||
switch(length) {
|
||||
case 12:
|
||||
c+=k[4]+(((uint32_t)k[5])<<16);
|
||||
b+=k[2]+(((uint32_t)k[3])<<16);
|
||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||
break;
|
||||
case 11:
|
||||
c+=((uint32_t)k8[10])<<16; /* fall through */
|
||||
case 10:
|
||||
c+=k[4];
|
||||
b+=k[2]+(((uint32_t)k[3])<<16);
|
||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||
break;
|
||||
case 9 :
|
||||
c+=k8[8]; /* fall through */
|
||||
case 8 :
|
||||
b+=k[2]+(((uint32_t)k[3])<<16);
|
||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||
break;
|
||||
case 7 :
|
||||
b+=((uint32_t)k8[6])<<16; /* fall through */
|
||||
case 6 :
|
||||
b+=k[2];
|
||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||
break;
|
||||
case 5 :
|
||||
b+=k8[4]; /* fall through */
|
||||
case 4 :
|
||||
a+=k[0]+(((uint32_t)k[1])<<16);
|
||||
break;
|
||||
case 3 :
|
||||
a+=((uint32_t)k8[2])<<16; /* fall through */
|
||||
case 2 :
|
||||
a+=k[0];
|
||||
break;
|
||||
case 1 :
|
||||
a+=k8[0];
|
||||
break;
|
||||
case 0 :
|
||||
return c; /* zero length requires no mixing */
|
||||
switch (length) {
|
||||
case 12:
|
||||
c += k[4] + (((uint32_t)k[5]) << 16);
|
||||
b += k[2] + (((uint32_t)k[3]) << 16);
|
||||
a += k[0] + (((uint32_t)k[1]) << 16);
|
||||
break;
|
||||
case 11:
|
||||
c += ((uint32_t)k8[10]) << 16; /* fall through */
|
||||
case 10:
|
||||
c += k[4];
|
||||
b += k[2] + (((uint32_t)k[3]) << 16);
|
||||
a += k[0] + (((uint32_t)k[1]) << 16);
|
||||
break;
|
||||
case 9:
|
||||
c += k8[8]; /* fall through */
|
||||
case 8:
|
||||
b += k[2] + (((uint32_t)k[3]) << 16);
|
||||
a += k[0] + (((uint32_t)k[1]) << 16);
|
||||
break;
|
||||
case 7:
|
||||
b += ((uint32_t)k8[6]) << 16; /* fall through */
|
||||
case 6:
|
||||
b += k[2];
|
||||
a += k[0] + (((uint32_t)k[1]) << 16);
|
||||
break;
|
||||
case 5:
|
||||
b += k8[4]; /* fall through */
|
||||
case 4:
|
||||
a += k[0] + (((uint32_t)k[1]) << 16);
|
||||
break;
|
||||
case 3:
|
||||
a += ((uint32_t)k8[2]) << 16; /* fall through */
|
||||
case 2:
|
||||
a += k[0];
|
||||
break;
|
||||
case 1:
|
||||
a += k8[0];
|
||||
break;
|
||||
case 0:
|
||||
return c; /* zero length requires no mixing */
|
||||
}
|
||||
|
||||
} else { /* need to read the key one byte at a time */
|
||||
} else { /* need to read the key one byte at a time */
|
||||
const uint8_t *k = (const uint8_t *)key;
|
||||
|
||||
/*--------------- all but the last block: affect some 32 bits of (a,b,c) */
|
||||
while (length > 12) {
|
||||
a += k[0];
|
||||
a += ((uint32_t)k[1])<<8;
|
||||
a += ((uint32_t)k[2])<<16;
|
||||
a += ((uint32_t)k[3])<<24;
|
||||
a += ((uint32_t)k[1]) << 8;
|
||||
a += ((uint32_t)k[2]) << 16;
|
||||
a += ((uint32_t)k[3]) << 24;
|
||||
b += k[4];
|
||||
b += ((uint32_t)k[5])<<8;
|
||||
b += ((uint32_t)k[6])<<16;
|
||||
b += ((uint32_t)k[7])<<24;
|
||||
b += ((uint32_t)k[5]) << 8;
|
||||
b += ((uint32_t)k[6]) << 16;
|
||||
b += ((uint32_t)k[7]) << 24;
|
||||
c += k[8];
|
||||
c += ((uint32_t)k[9])<<8;
|
||||
c += ((uint32_t)k[10])<<16;
|
||||
c += ((uint32_t)k[11])<<24;
|
||||
mix(a,b,c);
|
||||
c += ((uint32_t)k[9]) << 8;
|
||||
c += ((uint32_t)k[10]) << 16;
|
||||
c += ((uint32_t)k[11]) << 24;
|
||||
mix(a, b, c);
|
||||
length -= 12;
|
||||
k += 12;
|
||||
}
|
||||
|
||||
/*-------------------------------- last block: affect all 32 bits of (c) */
|
||||
switch(length) { /* all the case statements fall through */
|
||||
case 12:
|
||||
c+=((uint32_t)k[11])<<24;
|
||||
case 11:
|
||||
c+=((uint32_t)k[10])<<16;
|
||||
case 10:
|
||||
c+=((uint32_t)k[9])<<8;
|
||||
case 9 :
|
||||
c+=k[8];
|
||||
case 8 :
|
||||
b+=((uint32_t)k[7])<<24;
|
||||
case 7 :
|
||||
b+=((uint32_t)k[6])<<16;
|
||||
case 6 :
|
||||
b+=((uint32_t)k[5])<<8;
|
||||
case 5 :
|
||||
b+=k[4];
|
||||
case 4 :
|
||||
a+=((uint32_t)k[3])<<24;
|
||||
case 3 :
|
||||
a+=((uint32_t)k[2])<<16;
|
||||
case 2 :
|
||||
a+=((uint32_t)k[1])<<8;
|
||||
case 1 :
|
||||
a+=k[0];
|
||||
break;
|
||||
case 0 :
|
||||
return c;
|
||||
switch (length) { /* all the case statements fall through */
|
||||
case 12:
|
||||
c += ((uint32_t)k[11]) << 24;
|
||||
case 11:
|
||||
c += ((uint32_t)k[10]) << 16;
|
||||
case 10:
|
||||
c += ((uint32_t)k[9]) << 8;
|
||||
case 9:
|
||||
c += k[8];
|
||||
case 8:
|
||||
b += ((uint32_t)k[7]) << 24;
|
||||
case 7:
|
||||
b += ((uint32_t)k[6]) << 16;
|
||||
case 6:
|
||||
b += ((uint32_t)k[5]) << 8;
|
||||
case 5:
|
||||
b += k[4];
|
||||
case 4:
|
||||
a += ((uint32_t)k[3]) << 24;
|
||||
case 3:
|
||||
a += ((uint32_t)k[2]) << 16;
|
||||
case 2:
|
||||
a += ((uint32_t)k[1]) << 8;
|
||||
case 1:
|
||||
a += k[0];
|
||||
break;
|
||||
case 0:
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
final(a,b,c);
|
||||
c=(32767&c);
|
||||
final(a, b, c);
|
||||
c = (32767 & c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -453,6 +453,6 @@ uint32_t nhash( const void *key, size_t length, uint32_t initval) {
|
|||
/*
|
||||
* Fortran argument compatible wrapper
|
||||
*/
|
||||
uint32_t nhash_( const void * key, size_t const * length, uint32_t const * initval) {
|
||||
return nhash (key, *length, *initval);
|
||||
uint32_t nhash_(const void *key, size_t const *length, uint32_t const *initval) {
|
||||
return nhash(key, *length, *initval);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
uint32_t nhash( const void * key, size_t length, uint32_t initval);
|
||||
uint32_t nhash_( void const * key, size_t const * length, uint32_t const * initval);
|
||||
uint32_t nhash(const void* key, size_t length, uint32_t initval);
|
||||
uint32_t nhash_(void const* key, size_t const* length, uint32_t const* initval);
|
||||
|
|
803
wsprd/wsprd.c
803
wsprd/wsprd.c
Plik diff jest za duży
Load Diff
|
@ -35,41 +35,39 @@
|
|||
|
||||
/* Option & config of decoder (Shared with the wsprd code) */
|
||||
struct decoder_options {
|
||||
uint32_t freq; // Dial frequency
|
||||
char rcall[13]; // Callsign of the RX station
|
||||
char rloc[7]; // Locator of the RX station
|
||||
char date[7]; // Date & time of the processes samples
|
||||
char uttime[5]; // ''
|
||||
uint32_t quickmode; // Decoder option & tweak
|
||||
uint32_t usehashtable; // ''
|
||||
uint32_t npasses; // ''
|
||||
uint32_t subtraction; // ''
|
||||
uint32_t freq; // Dial frequency
|
||||
char rcall[13]; // Callsign of the RX station
|
||||
char rloc[7]; // Locator of the RX station
|
||||
char date[7]; // Date & time of the processes samples
|
||||
char uttime[5]; // ''
|
||||
uint32_t quickmode; // Decoder option & tweak
|
||||
uint32_t usehashtable; // ''
|
||||
uint32_t npasses; // ''
|
||||
uint32_t subtraction; // ''
|
||||
};
|
||||
|
||||
|
||||
struct decoder_results {
|
||||
double freq;
|
||||
float sync;
|
||||
float snr;
|
||||
float dt;
|
||||
float drift;
|
||||
int32_t jitter;
|
||||
char message[23];
|
||||
char call[13];
|
||||
char loc[7];
|
||||
char pwr[3];
|
||||
double freq;
|
||||
float sync;
|
||||
float snr;
|
||||
float dt;
|
||||
float drift;
|
||||
int32_t jitter;
|
||||
char message[23];
|
||||
char call[13];
|
||||
char loc[7];
|
||||
char pwr[3];
|
||||
uint32_t cycles;
|
||||
};
|
||||
|
||||
|
||||
void sync_and_demodulate(float *id, float *qd, long np,
|
||||
uint8_t *symbols, float *freq1, float fstep,
|
||||
int32_t *shift1, int32_t lagmin, int32_t lagmax, int32_t lagstep,
|
||||
float *drift1, int32_t symfac, float *sync, int32_t mode);
|
||||
void subtract_signal(float *id, float *qd, long np,
|
||||
float f0, int32_t shift0, float drift0, uint8_t* channel_symbols);
|
||||
float f0, int32_t shift0, float drift0, uint8_t *channel_symbols);
|
||||
void subtract_signal2(float *id, float *qd, long np,
|
||||
float f0, int32_t shift0, float drift0, uint8_t* channel_symbols);
|
||||
float f0, int32_t shift0, float drift0, uint8_t *channel_symbols);
|
||||
int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints,
|
||||
struct decoder_options options, struct decoder_results *decodes,
|
||||
int32_t *n_results);
|
||||
|
|
|
@ -39,44 +39,43 @@
|
|||
//#pragma GCC diagnostic ignored "-Wstringop-overflow"
|
||||
//#pragma GCC diagnostic ignored "-Wstringop-truncation"
|
||||
|
||||
|
||||
void unpack50(signed char *dat, int32_t *n1, int32_t *n2) {
|
||||
int32_t i, i4;
|
||||
|
||||
i = dat[0];
|
||||
i4 = i&255;
|
||||
*n1 = i4<<20;
|
||||
i4 = i & 255;
|
||||
*n1 = i4 << 20;
|
||||
|
||||
i = dat[1];
|
||||
i4 = i&255;
|
||||
*n1 = *n1+(i4<<12);
|
||||
i4 = i & 255;
|
||||
*n1 = *n1 + (i4 << 12);
|
||||
|
||||
i = dat[2];
|
||||
i4 = i&255;
|
||||
*n1 = *n1+(i4<<4);
|
||||
i4 = i & 255;
|
||||
*n1 = *n1 + (i4 << 4);
|
||||
|
||||
i = dat[3];
|
||||
i4 = i&255;
|
||||
*n1 = *n1+((i4>>4)&15);
|
||||
*n2 = (i4&15)<<18;
|
||||
i4 = i & 255;
|
||||
*n1 = *n1 + ((i4 >> 4) & 15);
|
||||
*n2 = (i4 & 15) << 18;
|
||||
|
||||
i = dat[4];
|
||||
i4 = i&255;
|
||||
*n2 = *n2+(i4<<10);
|
||||
i4 = i & 255;
|
||||
*n2 = *n2 + (i4 << 10);
|
||||
|
||||
i = dat[5];
|
||||
i4 = i&255;
|
||||
*n2 = *n2+(i4<<2);
|
||||
i4 = i & 255;
|
||||
*n2 = *n2 + (i4 << 2);
|
||||
|
||||
i = dat[6];
|
||||
i4 = i&255;
|
||||
*n2 = *n2+((i4>>6)&3);
|
||||
i4 = i & 255;
|
||||
*n2 = *n2 + ((i4 >> 6) & 3);
|
||||
}
|
||||
|
||||
int unpackcall(int32_t ncall, char *call) {
|
||||
char c[]= {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
|
||||
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
|
||||
'U', 'V', 'W', 'X', 'Y', 'Z', ' '};
|
||||
char c[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
|
||||
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
|
||||
'U', 'V', 'W', 'X', 'Y', 'Z', ' '};
|
||||
int32_t n;
|
||||
int i;
|
||||
char tmp[7];
|
||||
|
@ -84,34 +83,34 @@ int unpackcall(int32_t ncall, char *call) {
|
|||
n = ncall;
|
||||
strcpy(call, "......");
|
||||
if (n < 262177560) {
|
||||
i = n%27+10;
|
||||
i = n % 27 + 10;
|
||||
tmp[5] = c[i];
|
||||
n = n/27;
|
||||
i = n%27+10;
|
||||
n = n / 27;
|
||||
i = n % 27 + 10;
|
||||
tmp[4] = c[i];
|
||||
n = n/27;
|
||||
i = n%27+10;
|
||||
n = n / 27;
|
||||
i = n % 27 + 10;
|
||||
tmp[3] = c[i];
|
||||
n = n/27;
|
||||
i = n%10;
|
||||
n = n / 27;
|
||||
i = n % 10;
|
||||
tmp[2] = c[i];
|
||||
n = n/10;
|
||||
i = n%36;
|
||||
n = n / 10;
|
||||
i = n % 36;
|
||||
tmp[1] = c[i];
|
||||
n = n/36;
|
||||
n = n / 36;
|
||||
i = n;
|
||||
tmp[0] = c[i];
|
||||
tmp[6] = '\0';
|
||||
// remove leading whitespace
|
||||
for (i=0; i < 5; i++) {
|
||||
if ( tmp[i] != c[36] )
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (tmp[i] != c[36])
|
||||
break;
|
||||
}
|
||||
sprintf(call, "%-6s", &tmp[i]);
|
||||
// remove trailing whitespace
|
||||
for (i=0; i < 6; i++) {
|
||||
if ( call[i] == c[36] ) {
|
||||
call[i]='\0';
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (call[i] == c[36]) {
|
||||
call[i] = '\0';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -121,29 +120,29 @@ int unpackcall(int32_t ncall, char *call) {
|
|||
}
|
||||
|
||||
int unpackgrid(int32_t ngrid, char *grid) {
|
||||
char c[]= {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
|
||||
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
|
||||
'U', 'V', 'W', 'X', 'Y', 'Z', ' '};
|
||||
char c[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
|
||||
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
|
||||
'U', 'V', 'W', 'X', 'Y', 'Z', ' '};
|
||||
int dlat, dlong;
|
||||
|
||||
ngrid = ngrid>>7;
|
||||
if ( ngrid < 32400 ) {
|
||||
dlat = (ngrid%180)-90;
|
||||
dlong = (ngrid/180)*2 - 180 + 2;
|
||||
if ( dlong < -180 )
|
||||
dlong = dlong+360;
|
||||
if ( dlong > 180 )
|
||||
dlong = dlong+360;
|
||||
int nlong = 60.0*(180.0-dlong)/5.0;
|
||||
int n1 = nlong/240;
|
||||
int n2 = (nlong - 240*n1)/24;
|
||||
grid[0] = c[10+n1];
|
||||
ngrid = ngrid >> 7;
|
||||
if (ngrid < 32400) {
|
||||
dlat = (ngrid % 180) - 90;
|
||||
dlong = (ngrid / 180) * 2 - 180 + 2;
|
||||
if (dlong < -180)
|
||||
dlong = dlong + 360;
|
||||
if (dlong > 180)
|
||||
dlong = dlong + 360;
|
||||
int nlong = 60.0 * (180.0 - dlong) / 5.0;
|
||||
int n1 = nlong / 240;
|
||||
int n2 = (nlong - 240 * n1) / 24;
|
||||
grid[0] = c[10 + n1];
|
||||
grid[2] = c[n2];
|
||||
|
||||
int nlat = 60.0*(dlat+90)/2.5;
|
||||
n1 = nlat/240;
|
||||
n2 = (nlat-240*n1)/24;
|
||||
grid[1] = c[10+n1];
|
||||
int nlat = 60.0 * (dlat + 90) / 2.5;
|
||||
n1 = nlat / 240;
|
||||
n2 = (nlat - 240 * n1) / 24;
|
||||
grid[1] = c[10 + n1];
|
||||
grid[3] = c[n2];
|
||||
} else {
|
||||
strcpy(grid, "XXXX");
|
||||
|
@ -153,24 +152,24 @@ int unpackgrid(int32_t ngrid, char *grid) {
|
|||
}
|
||||
|
||||
int unpackpfx(int32_t nprefix, char *call) {
|
||||
char nc, pfx[4]="", tmpcall[7]="";
|
||||
char nc, pfx[4] = "", tmpcall[7] = "";
|
||||
int i;
|
||||
int32_t n;
|
||||
|
||||
strcpy(tmpcall, call);
|
||||
if ( nprefix < 60000 ) {
|
||||
if (nprefix < 60000) {
|
||||
// add a prefix of 1 to 3 characters
|
||||
n = nprefix;
|
||||
for (i=2; i >= 0; i--) {
|
||||
nc = n%37;
|
||||
if ( (nc >= 0) & (nc <= 9) ) {
|
||||
pfx[i] = nc+48;
|
||||
} else if ( (nc >= 10) & (nc <= 35) ) {
|
||||
pfx[i] = nc+55;
|
||||
for (i = 2; i >= 0; i--) {
|
||||
nc = n % 37;
|
||||
if ((nc >= 0) & (nc <= 9)) {
|
||||
pfx[i] = nc + 48;
|
||||
} else if ((nc >= 10) & (nc <= 35)) {
|
||||
pfx[i] = nc + 55;
|
||||
} else {
|
||||
pfx[i] = ' ';
|
||||
}
|
||||
n = n/37;
|
||||
n = n / 37;
|
||||
}
|
||||
|
||||
strcpy(call, pfx);
|
||||
|
@ -179,20 +178,20 @@ int unpackpfx(int32_t nprefix, char *call) {
|
|||
|
||||
} else {
|
||||
// add a suffix of 1 or 2 characters
|
||||
nc = nprefix-60000;
|
||||
if ( (nc >= 0) & (nc <= 9) ) {
|
||||
pfx[0] = nc+48;
|
||||
nc = nprefix - 60000;
|
||||
if ((nc >= 0) & (nc <= 9)) {
|
||||
pfx[0] = nc + 48;
|
||||
strcpy(call, tmpcall);
|
||||
strncat(call, "/", 1);
|
||||
strncat(call, pfx, 1);
|
||||
} else if ( (nc >= 10) & (nc <= 35) ) {
|
||||
pfx[0] = nc+55;
|
||||
} else if ((nc >= 10) & (nc <= 35)) {
|
||||
pfx[0] = nc + 55;
|
||||
strcpy(call, tmpcall);
|
||||
strncat(call, "/", 1);
|
||||
strncat(call, pfx, 1);
|
||||
} else if ( (nc >= 36) & (nc <= 125) ) {
|
||||
pfx[0] = (nc-26)/10+48;
|
||||
pfx[1] = (nc-26)%10+48;
|
||||
} else if ((nc >= 36) & (nc <= 125)) {
|
||||
pfx[0] = (nc - 26) / 10 + 48;
|
||||
pfx[1] = (nc - 26) % 10 + 48;
|
||||
strcpy(call, tmpcall);
|
||||
strncat(call, "/", 1);
|
||||
strncat(call, pfx, 2);
|
||||
|
@ -213,26 +212,26 @@ void deinterleave(unsigned char *sym) {
|
|||
j = ((i * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32;
|
||||
if (j < 162) {
|
||||
tmp[p] = sym[j];
|
||||
p = p+1;
|
||||
p = p + 1;
|
||||
}
|
||||
i = i+1;
|
||||
i = i + 1;
|
||||
}
|
||||
for (i=0; i < 162; i++) {
|
||||
for (i = 0; i < 162; i++) {
|
||||
sym[i] = tmp[i];
|
||||
}
|
||||
}
|
||||
|
||||
// used by qsort
|
||||
int doublecomp(const void* elem1, const void* elem2) {
|
||||
if (*(const double*)elem1 < *(const double*)elem2)
|
||||
int doublecomp(const void *elem1, const void *elem2) {
|
||||
if (*(const double *)elem1 < *(const double *)elem2)
|
||||
return -1;
|
||||
return *(const double*)elem1 > *(const double*)elem2;
|
||||
return *(const double *)elem1 > *(const double *)elem2;
|
||||
}
|
||||
|
||||
int floatcomp(const void* elem1, const void* elem2) {
|
||||
if (*(const float*)elem1 < *(const float*)elem2)
|
||||
int floatcomp(const void *elem1, const void *elem2) {
|
||||
if (*(const float *)elem1 < *(const float *)elem2)
|
||||
return -1;
|
||||
return *(const float*)elem1 > *(const float*)elem2;
|
||||
return *(const float *)elem1 > *(const float *)elem2;
|
||||
}
|
||||
|
||||
int unpk_(signed char *message, char *hashtab, char *call_loc_pow, char *call, char *loc, char *pwr, char *callsign) {
|
||||
|
@ -240,11 +239,11 @@ int unpk_(signed char *message, char *hashtab, char *call_loc_pow, char *call, c
|
|||
char grid[5], grid6[7], cdbm[3];
|
||||
|
||||
unpack50(message, &n1, &n2);
|
||||
if ( !unpackcall(n1, callsign) )
|
||||
if (!unpackcall(n1, callsign))
|
||||
return 1;
|
||||
if ( !unpackgrid(n2, grid) )
|
||||
if (!unpackgrid(n2, grid))
|
||||
return 1;
|
||||
int ntype = (n2&127) - 64;
|
||||
int ntype = (n2 & 127) - 64;
|
||||
callsign[12] = 0;
|
||||
grid[4] = 0;
|
||||
|
||||
|
@ -261,11 +260,11 @@ int unpk_(signed char *message, char *hashtab, char *call_loc_pow, char *call, c
|
|||
* 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 ) {
|
||||
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);
|
||||
memset(call_loc_pow, 0, sizeof(char) * 23);
|
||||
sprintf(cdbm, "%2d", ndbm);
|
||||
strncat(call_loc_pow, callsign, strlen(callsign));
|
||||
strncat(call_loc_pow, " ", 1);
|
||||
|
@ -274,11 +273,11 @@ int unpk_(signed char *message, char *hashtab, char *call_loc_pow, char *call, c
|
|||
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);
|
||||
strcpy(hashtab + ihash * 13, callsign);
|
||||
|
||||
memset(call, 0, strlen(callsign)+1);
|
||||
memset(loc, 0, strlen(grid)+1);
|
||||
memset(pwr, 0, 2+1);
|
||||
memset(call, 0, strlen(callsign) + 1);
|
||||
memset(loc, 0, strlen(grid) + 1);
|
||||
memset(pwr, 0, 2 + 1);
|
||||
strncat(call, callsign, strlen(callsign));
|
||||
strncat(call, "\0", 1);
|
||||
strncat(loc, grid, strlen(grid));
|
||||
|
@ -288,62 +287,62 @@ int unpk_(signed char *message, char *hashtab, char *call_loc_pow, char *call, c
|
|||
|
||||
} else {
|
||||
nadd = nu;
|
||||
if ( nu > 3 )
|
||||
nadd = nu-3;
|
||||
if ( nu > 7 )
|
||||
nadd = nu-7;
|
||||
n3 = n2/128+32768*(nadd-1);
|
||||
if ( !unpackpfx(n3, callsign) )
|
||||
if (nu > 3)
|
||||
nadd = nu - 3;
|
||||
if (nu > 7)
|
||||
nadd = nu - 7;
|
||||
n3 = n2 / 128 + 32768 * (nadd - 1);
|
||||
if (!unpackpfx(n3, callsign))
|
||||
return 1;
|
||||
ndbm = ntype - nadd;
|
||||
memset(call_loc_pow, 0, sizeof(char)*23);
|
||||
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);
|
||||
int nu = ndbm%10;
|
||||
if ( nu == 0 || nu == 3 || nu == 7 || nu == 10 ) { // make sure power is OK
|
||||
int nu = ndbm % 10;
|
||||
if (nu == 0 || nu == 3 || nu == 7 || nu == 10) { // make sure power is OK
|
||||
ihash = nhash(callsign, strlen(callsign), (uint32_t)146);
|
||||
strcpy(hashtab+ihash*13, callsign);
|
||||
strcpy(hashtab + ihash * 13, callsign);
|
||||
} else {
|
||||
noprint = 1;
|
||||
}
|
||||
|
||||
memset(call, 0, strlen(callsign)+1);
|
||||
memset(call, 0, strlen(callsign) + 1);
|
||||
memset(loc, 0, 1);
|
||||
memset(pwr, 0, 2+1);
|
||||
memset(pwr, 0, 2 + 1);
|
||||
strncat(call, callsign, strlen(callsign));
|
||||
strncat(call, "\0", 1);
|
||||
strncat(loc, "\0", 1);
|
||||
strncat(pwr, cdbm, 2);
|
||||
strncat(pwr, "\0", 1);
|
||||
}
|
||||
} else if ( ntype < 0 ) {
|
||||
ndbm = -(ntype+1);
|
||||
memset(grid6, 0, sizeof(char)*7);
|
||||
strncat(grid6, callsign+5, 1);
|
||||
} else if (ntype < 0) {
|
||||
ndbm = -(ntype + 1);
|
||||
memset(grid6, 0, sizeof(char) * 7);
|
||||
strncat(grid6, callsign + 5, 1);
|
||||
strncat(grid6, callsign, 5);
|
||||
int nu = ndbm%10;
|
||||
if ( (nu == 0 || nu == 3 || nu == 7 || nu == 10) &&
|
||||
(isalpha(grid6[0]) && isalpha(grid6[1]) && isdigit(grid6[2]) && isdigit(grid6[3]) ) ) {
|
||||
int nu = ndbm % 10;
|
||||
if ((nu == 0 || nu == 3 || nu == 7 || nu == 10) &&
|
||||
(isalpha(grid6[0]) && isalpha(grid6[1]) && isdigit(grid6[2]) && isdigit(grid6[3]))) {
|
||||
// not testing 4'th and 5'th chars because of this case: <PA0SKT/2> JO33 40
|
||||
// grid is only 4 chars even though this is a hashed callsign...
|
||||
// isalpha(grid6[4]) && isalpha(grid6[5]) ) ) {
|
||||
ihash = nhash(callsign, strlen(callsign), (uint32_t)146);
|
||||
strcpy(hashtab+ihash*13, callsign);
|
||||
strcpy(hashtab + ihash * 13, callsign);
|
||||
} else {
|
||||
noprint = 1;
|
||||
}
|
||||
|
||||
ihash = (n2-ntype-64)/128;
|
||||
if ( strncmp(hashtab+ihash*13, "\0", 1) != 0 ) {
|
||||
sprintf(callsign, "<%s>", hashtab+ihash*13);
|
||||
ihash = (n2 - ntype - 64) / 128;
|
||||
if (strncmp(hashtab + ihash * 13, "\0", 1) != 0) {
|
||||
sprintf(callsign, "<%s>", hashtab + ihash * 13);
|
||||
} else {
|
||||
sprintf(callsign, "%5s", "<...>");
|
||||
}
|
||||
|
||||
memset(call_loc_pow, 0, sizeof(char)*23);
|
||||
memset(call_loc_pow, 0, sizeof(char) * 23);
|
||||
sprintf(cdbm, "%2d", ndbm);
|
||||
strncat(call_loc_pow, callsign, strlen(callsign));
|
||||
strncat(call_loc_pow, " ", 1);
|
||||
|
@ -352,9 +351,9 @@ int unpk_(signed char *message, char *hashtab, char *call_loc_pow, char *call, c
|
|||
strncat(call_loc_pow, cdbm, 2);
|
||||
strncat(call_loc_pow, "\0", 1);
|
||||
|
||||
memset(call, 0, strlen(callsign)+1);
|
||||
memset(loc, 0, strlen(grid6)+1);
|
||||
memset(pwr, 0, 2+1);
|
||||
memset(call, 0, strlen(callsign) + 1);
|
||||
memset(loc, 0, strlen(grid6) + 1);
|
||||
memset(pwr, 0, 2 + 1);
|
||||
strncat(call, callsign, strlen(callsign));
|
||||
strncat(call, "\0", 1);
|
||||
strncat(loc, grid6, strlen(grid6));
|
||||
|
@ -363,7 +362,7 @@ int unpk_(signed char *message, char *hashtab, char *call_loc_pow, char *call, c
|
|||
strncat(pwr, "\0", 1);
|
||||
|
||||
// I don't know what to do with these... They show up as "A000AA" grids.
|
||||
if ( ntype == -64 )
|
||||
if (ntype == -64)
|
||||
noprint = 1;
|
||||
}
|
||||
return noprint;
|
||||
|
|
|
@ -36,7 +36,7 @@ int unpackpfx(int32_t nprefix, char *call);
|
|||
void deinterleave(unsigned char *sym);
|
||||
|
||||
// used by qsort
|
||||
int doublecomp(const void* elem1, const void* elem2);
|
||||
int floatcomp(const void* elem1, const void* elem2);
|
||||
int doublecomp(const void *elem1, const void *elem2);
|
||||
int floatcomp(const void *elem1, const void *elem2);
|
||||
|
||||
int unpk_(signed char *message, char *hashtab, char *call_loc_pow, char *call, char *loc, char *pwr, char *callsign);
|
||||
|
|
|
@ -12,29 +12,28 @@
|
|||
#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 >= 48 && ch <= 57) { // 0-9
|
||||
return ch - 48;
|
||||
}
|
||||
if( ch == 32 ) { //space
|
||||
if (ch == 32) { // space
|
||||
return 36;
|
||||
}
|
||||
if( ch >= 65 && ch <= 82 ) { //A-Z
|
||||
return ch-65;
|
||||
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 >= 48 && ch <= 57) { // 0-9
|
||||
return ch - 48;
|
||||
}
|
||||
if( ch == 32 ) { //space
|
||||
if (ch == 32) { // space
|
||||
return 36;
|
||||
}
|
||||
if( ch >= 65 && ch <= 90 ) { //A-Z
|
||||
return ch-55;
|
||||
if (ch >= 65 && ch <= 90) { // A-Z
|
||||
return ch - 55;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -42,8 +41,8 @@ char get_callsign_character_code(char ch) {
|
|||
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;
|
||||
m = (179 - 10 * grid4[0] - grid4[2]) * 180 + 10 * grid4[1] + grid4[3];
|
||||
m = m * 128 + power + 64;
|
||||
return m;
|
||||
}
|
||||
|
||||
|
@ -51,101 +50,101 @@ long unsigned int pack_call(char *callsign) {
|
|||
int i;
|
||||
long unsigned int n;
|
||||
char call6[6];
|
||||
memset(call6,32,sizeof(char)*6);
|
||||
memset(call6, 32, sizeof(char) * 6);
|
||||
// callsign is 6 characters in length. Exactly.
|
||||
int call_len = strlen(callsign);
|
||||
if( call_len > 6 ) {
|
||||
if (call_len > 6) {
|
||||
return 0;
|
||||
}
|
||||
if( isdigit(*(callsign+2)) ) {
|
||||
for (i=0; i<6; i++) {
|
||||
if( callsign[i] == 0 ) {
|
||||
call6[i]=32;
|
||||
if (isdigit(*(callsign + 2))) {
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (callsign[i] == 0) {
|
||||
call6[i] = 32;
|
||||
} else {
|
||||
call6[i]=*(callsign+i);
|
||||
call6[i] = *(callsign + i);
|
||||
}
|
||||
}
|
||||
} else if( isdigit(*(callsign+1)) ) {
|
||||
for (i=0; i<6; i++) {
|
||||
if( i==0 || callsign[i-1]==0 ) {
|
||||
call6[i]=32;
|
||||
} else if (isdigit(*(callsign + 1))) {
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (i == 0 || callsign[i - 1] == 0) {
|
||||
call6[i] = 32;
|
||||
} else {
|
||||
call6[i]=*(callsign+i-1);
|
||||
call6[i] = *(callsign + i - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i=0; i<6; i++) {
|
||||
call6[i]=get_callsign_character_code(call6[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;
|
||||
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 ) {
|
||||
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,"/");
|
||||
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];
|
||||
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;
|
||||
*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 = 38;
|
||||
}
|
||||
*m=60000-32768+*m;
|
||||
} else if( callsign[i1+3]==0 ) {
|
||||
//two char suffix
|
||||
for (i=0; i<i1; i++) {
|
||||
call6[i]=callsign[i];
|
||||
*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;
|
||||
*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(pfx," "); // FIXME-CHECK
|
||||
*n=pack_call(call6);
|
||||
int plen=strlen(pfx);
|
||||
if( plen ==1 ) {
|
||||
*m=36;
|
||||
*m=37*(*m)+36;
|
||||
} else if( plen == 2 ) {
|
||||
*m=36;
|
||||
char *pfx = strtok(callsign, "/");
|
||||
call6 = strtok(pfx, " "); // FIXME-CHECK
|
||||
*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;
|
||||
*m = 0;
|
||||
}
|
||||
for (i=0; i<plen; i++) {
|
||||
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;
|
||||
if (nc >= 48 && nc <= 57) {
|
||||
nc = nc - 48;
|
||||
} else if (nc >= 65 && nc <= 90) {
|
||||
nc = nc - 65 + 10;
|
||||
} else {
|
||||
nc=36;
|
||||
nc = 36;
|
||||
}
|
||||
*m=37*(*m)+nc;
|
||||
*m = 37 * (*m) + nc;
|
||||
}
|
||||
*nadd=0;
|
||||
if( *m > 32768 ) {
|
||||
*m=*m-32768;
|
||||
*nadd=1;
|
||||
*nadd = 0;
|
||||
if (*m > 32768) {
|
||||
*m = *m - 32768;
|
||||
*nadd = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -154,162 +153,160 @@ 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;
|
||||
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;
|
||||
i = i + 1;
|
||||
}
|
||||
for (i=0; i<162; i++) {
|
||||
sym[i]=tmp[i];
|
||||
for (i = 0; i < 162; i++) {
|
||||
sym[i] = tmp[i];
|
||||
}
|
||||
}
|
||||
|
||||
int get_wspr_channel_symbols(char* rawmessage, char* hashtab, unsigned char* symbols) {
|
||||
int m=0, n=0, ntype=0;
|
||||
int get_wspr_channel_symbols(char *rawmessage, char *hashtab, 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};
|
||||
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], message[23];
|
||||
|
||||
memset(message,0,sizeof(char)*23);
|
||||
i=0;
|
||||
while ( rawmessage[i] != 0 && i<23 ) {
|
||||
message[i]=rawmessage[i];
|
||||
memset(message, 0, sizeof(char) * 23);
|
||||
i = 0;
|
||||
while (rawmessage[i] != 0 && i < 23) {
|
||||
message[i] = rawmessage[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
int i1=strcspn(message," ");
|
||||
int i2=strcspn(message,"/");
|
||||
int i3=strcspn(message,"<");
|
||||
int i4=strcspn(message,">");
|
||||
int mlen=strlen(message);
|
||||
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<7) & (i2==mlen) & (i3==mlen) ) {
|
||||
if ((i1 > 3) & (i1 < 7) & (i2 == mlen) & (i3 == mlen)) {
|
||||
// Type 1 message: K9AN EN50 33
|
||||
// xxnxxxx xxnn nn
|
||||
callsign = strtok(message," ");
|
||||
grid = strtok(NULL," ");
|
||||
powstr = strtok(NULL," ");
|
||||
callsign = strtok(message, " ");
|
||||
grid = strtok(NULL, " ");
|
||||
powstr = strtok(NULL, " ");
|
||||
int power = atoi(powstr);
|
||||
n = pack_call(callsign);
|
||||
|
||||
for (i=0; i<4; i++) {
|
||||
grid4[i]=get_locator_character_code(*(grid+i));
|
||||
for (i = 0; i < 4; i++) {
|
||||
grid4[i] = get_locator_character_code(*(grid + i));
|
||||
}
|
||||
m = pack_grid4_power(grid4,power);
|
||||
m = pack_grid4_power(grid4, power);
|
||||
|
||||
} else if ( i3 == 0 && i4 < mlen ) {
|
||||
} 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," ");
|
||||
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;
|
||||
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];
|
||||
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);
|
||||
} else if ( i2 < mlen ) { // just looks for a right slash
|
||||
grid6[5] = grid[0];
|
||||
n = pack_call(grid6);
|
||||
} else if (i2 < mlen) { // just looks for a right slash
|
||||
// Type 2: PJ4/K1ABC 37
|
||||
callsign=strtok(message," ");
|
||||
if( strlen(callsign) < i2 ) return 0; //guards against pathological case
|
||||
powstr=strtok(NULL," ");
|
||||
callsign = strtok(message, " ");
|
||||
if (strlen(callsign) < i2) return 0; // guards against pathological case
|
||||
powstr = strtok(NULL, " ");
|
||||
int power = atoi(powstr);
|
||||
if( power < 0 ) power=0;
|
||||
if( power > 60 ) power=60;
|
||||
power=power+nu[power%10];
|
||||
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;
|
||||
ntype = power + 1 + nadd;
|
||||
m = 128 * ng + ntype + 64;
|
||||
n = n1;
|
||||
} else {
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
// 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 hashtab[32768][13];
|
||||
// memset(hashtab,0,sizeof(char)*32768*13);
|
||||
|
||||
char *check_call_loc_pow, *check_callsign, *call, *loc, *pwr;
|
||||
check_call_loc_pow=malloc(sizeof(char)*23);
|
||||
check_callsign=malloc(sizeof(char)*13);
|
||||
call=malloc(sizeof(char)*13);
|
||||
loc=malloc(sizeof(char)*7);
|
||||
pwr=malloc(sizeof(char)*3);
|
||||
check_call_loc_pow = malloc(sizeof(char) * 23);
|
||||
check_callsign = malloc(sizeof(char) * 13);
|
||||
call = malloc(sizeof(char) * 13);
|
||||
loc = malloc(sizeof(char) * 7);
|
||||
pwr = malloc(sizeof(char) * 3);
|
||||
signed char check_data[11];
|
||||
memcpy(check_data,data,sizeof(char)*11);
|
||||
unpk_(check_data,hashtab,check_call_loc_pow,call,loc,pwr,check_callsign);
|
||||
// printf("Will decode as: %s\n",check_call_loc_pow);
|
||||
memcpy(check_data, data, sizeof(char) * 11);
|
||||
unpk_(check_data, hashtab, check_call_loc_pow, call, loc, pwr, 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=(nbytes * 2 * 8); // This is how much encode() writes
|
||||
unsigned int nbytes = 11; // The message with tail is packed into 11 bytes.
|
||||
unsigned int nencoded = (nbytes * 2 * 8); // This is how much encode() writes
|
||||
unsigned char channelbits[nencoded];
|
||||
memset(channelbits,0,sizeof(char)*nencoded);
|
||||
memset(channelbits, 0, sizeof(char) * nencoded);
|
||||
|
||||
encode(channelbits,data,nbytes);
|
||||
encode(channelbits, data, nbytes);
|
||||
|
||||
interleave(channelbits);
|
||||
|
||||
for (i=0; i<162; i++) {
|
||||
symbols[i]=2*channelbits[i]+pr3[i];
|
||||
for (i = 0; i < 162; i++) {
|
||||
symbols[i] = 2 * channelbits[i] + pr3[i];
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -4,6 +4,6 @@ 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 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, char* hashtab, unsigned char* symbols);
|
||||
int get_wspr_channel_symbols(char *message, char *hashtab, unsigned char *symbols);
|
||||
|
|
Ładowanie…
Reference in New Issue