diff --git a/rtlsdr_wsprd.c b/rtlsdr_wsprd.c index 5b1f763..1bc60c7 100644 --- a/rtlsdr_wsprd.c +++ b/rtlsdr_wsprd.c @@ -324,7 +324,7 @@ void postSpots(uint32_t n_results) { // "Table 'wsprnet_db.activity' doesn't exist" reported on web site... // Anyone has doc about this? if (n_results == 0) { - snprintf(url, sizeof(url) - 1, "http://wsprnet.org/post?function=wsprstat&rcall=%s&rgrid=%s&rqrg=%.6f&tpct=%.2f&tqrg=%.6f&dbm=%d&version=rtlsdr-wsprd_v0.4.2&mode=2", + snprintf(url, sizeof(url) - 1, "http://wsprnet.org/post?function=wsprstat&rcall=%s&rgrid=%s&rqrg=%.6f&tpct=%.2f&tqrg=%.6f&dbm=%d&version=rtlsdr-050&mode=2", dec_options.rcall, dec_options.rloc, rx_options.realfreq / 1e6, @@ -347,7 +347,7 @@ void postSpots(uint32_t n_results) { } 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=%02d%02d%02d&time=%02d%02d&sig=%.0f&dt=%.1f&tqrg=%.6f&tcall=%s&tgrid=%s&dbm=%s&version=rtlsdr-wsprd_v0.4.2&mode=2", + snprintf(url, sizeof(url) - 1, "http://wsprnet.org/post?function=wspr&rcall=%s&rgrid=%s&rqrg=%.6f&date=%02d%02d%02d&time=%02d%02d&sig=%.0f&dt=%.1f&tqrg=%.6f&tcall=%s&tgrid=%s&dbm=%s&version=rtlsdr-050&mode=2", dec_options.rcall, dec_options.rloc, dec_results[i].freq, @@ -612,10 +612,10 @@ int32_t decoderSelfTest() { unsigned char symbols[162]; char message[] = "K1JT FN20QI 20"; char hashtab[32768*13] = {0}; - //char loctab[32768*5] = {0}; // EVAL: code update from wsprd + char loctab[32768*5] = {0}; // EVAL: code update from wsprd // Compute sympbols from the message - get_wspr_channel_symbols(message, hashtab, symbols); + get_wspr_channel_symbols(message, hashtab, loctab, symbols); float f0 = 50.0; float t0 = 2.0; // Caution!! Possible buffer overflow with the index calculation (no user input here!) @@ -721,28 +721,53 @@ int main(int argc, char **argv) { case 'f': // Frequency if (!strcasecmp(optarg, "LF")) { rx_options.dialfreq = 136000; + // Implicit direct sampling for HF bands & lower + if (!rx_options.directsampling) + rx_options.directsampling = 2; } else if (!strcasecmp(optarg, "MF")) { rx_options.dialfreq = 474200; + if (!rx_options.directsampling) + rx_options.directsampling = 2; } else if (!strcasecmp(optarg, "160m")) { rx_options.dialfreq = 1836600; + if (!rx_options.directsampling) + rx_options.directsampling = 2; } else if (!strcasecmp(optarg, "80m")) { rx_options.dialfreq = 3592600; + if (!rx_options.directsampling) + rx_options.directsampling = 2; } else if (!strcasecmp(optarg, "60m")) { rx_options.dialfreq = 5287200; + if (!rx_options.directsampling) + rx_options.directsampling = 2; } else if (!strcasecmp(optarg, "40m")) { rx_options.dialfreq = 7038600; + if (!rx_options.directsampling) + rx_options.directsampling = 2; } else if (!strcasecmp(optarg, "30m")) { rx_options.dialfreq = 10138700; + if (!rx_options.directsampling) + rx_options.directsampling = 2; } else if (!strcasecmp(optarg, "20m")) { rx_options.dialfreq = 14095600; + if (!rx_options.directsampling) + rx_options.directsampling = 2; } else if (!strcasecmp(optarg, "17m")) { rx_options.dialfreq = 18104600; + if (!rx_options.directsampling) + rx_options.directsampling = 2; } else if (!strcasecmp(optarg, "15m")) { rx_options.dialfreq = 21094600; + if (!rx_options.directsampling) + rx_options.directsampling = 2; } else if (!strcasecmp(optarg, "12m")) { rx_options.dialfreq = 24924600; + if (!rx_options.directsampling) + rx_options.directsampling = 2; } else if (!strcasecmp(optarg, "10m")) { rx_options.dialfreq = 28124600; + if (!rx_options.directsampling) + rx_options.directsampling = 2; } else if (!strcasecmp(optarg, "6m")) { rx_options.dialfreq = 50293000; } else if (!strcasecmp(optarg, "4m")) { @@ -822,18 +847,18 @@ int main(int argc, char **argv) { if (rx_options.selftest == true) { if (decoderSelfTest()) { fprintf(stdout, "Self-test SUCCESS!\n"); - exit(0); + return EXIT_SUCCESS; } else { fprintf(stderr, "Self-test FAILED!\n"); - exit(1); + return EXIT_FAILURE; } } if (rx_options.readfile == true) { fprintf(stdout, "Reading IQ file: %s\n", rx_options.filename); decodeRecordedFile(rx_options.filename); - exit(0); + return EXIT_SUCCESS; } if (rx_options.writefile == true) { @@ -843,19 +868,19 @@ int main(int argc, char **argv) { if (rx_options.dialfreq == 0) { fprintf(stderr, "Please specify a dial frequency.\n"); fprintf(stderr, " --help for usage...\n"); - exit(1); + return EXIT_FAILURE; } if (dec_options.rcall[0] == 0) { fprintf(stderr, "Please specify your callsign.\n"); fprintf(stderr, " --help for usage...\n"); - exit(1); + return EXIT_FAILURE; } if (dec_options.rloc[0] == 0) { fprintf(stderr, "Please specify your locator.\n"); fprintf(stderr, " --help for usage...\n"); - exit(1); + return EXIT_FAILURE; } /* Calcule shift offset */ @@ -961,7 +986,7 @@ int main(int argc, char **argv) { struct tm *gtm = gmtime(&rawtime); /* Print used parameter */ - printf("\nStarting rtlsdr-wsprd (%04d-%02d-%02d, %02d:%02dz) -- Version 0.4.2\n", + printf("\nStarting rtlsdr-wsprd (%04d-%02d-%02d, %02d:%02dz) -- Version 0.5.0\n", gtm->tm_year + 1900, gtm->tm_mon + 1, gtm->tm_mday, gtm->tm_hour, gtm->tm_min); printf(" Callsign : %s\n", dec_options.rcall); printf(" Locator : %s\n", dec_options.rloc); diff --git a/wsprd/fano.c b/wsprd/fano.c index 1a7a546..2a124d2 100644 --- a/wsprd/fano.c +++ b/wsprd/fano.c @@ -166,8 +166,7 @@ int fano(unsigned int *metric, // Final path metric (returned value) */ while (ngamma >= t + delta) t += delta; } - // Move forward - np[1].gamma = ngamma; + np[1].gamma = ngamma; // Move forward np[1].encstate = np->encstate << 1; if (++np == (lastnode + 1)) { break; // Done! @@ -194,14 +193,11 @@ int fano(unsigned int *metric, // Final path metric (returned value) np->encstate++; // Set low bit } } - np->i = 0; - // Start with best branch + np->i = 0; // Start with best branch continue; } - // Threshold violated, can't go forward - for (;;) { - // Look backward + for (;;) { // Look backward if (np == nodes || np[-1].gamma < t) { /* Can't back up either. * Relax threshold and and look @@ -214,7 +210,6 @@ int fano(unsigned int *metric, // Final path metric (returned value) } break; } - // Back up if (--np < tail && np->i != 1) { np->i++; // Search next best branch diff --git a/wsprd/metric_tables.h b/wsprd/metric_tables.h index d51d156..7db6e27 100644 --- a/wsprd/metric_tables.h +++ b/wsprd/metric_tables.h @@ -4,114 +4,136 @@ * 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}; - -#pragma GCC diagnostic pop \ No newline at end of file +//float symbol_scale[5]={42.6, 53.3, 72.7, 100.2, 125.4}; +float metric_tables[5][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}, + {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, -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, 1.43370769e-019, + 2.64031087e-006, 6.6908396e+031, 1.77537994e+028, 2.79322819e+020, 1.94326e-019, + 0.00019371575, 2.80722121e-041}}; diff --git a/wsprd/nhash.c b/wsprd/nhash.c index 18125fa..b5f8677 100644 --- a/wsprd/nhash.c +++ b/wsprd/nhash.c @@ -449,10 +449,3 @@ uint32_t nhash(const void *key, size_t length, uint32_t initval) { return c; } - -/* - * Fortran argument compatible wrapper - */ -uint32_t nhash_(const void *key, size_t const *length, uint32_t const *initval) { - return nhash(key, *length, *initval); -} diff --git a/wsprd/nhash.h b/wsprd/nhash.h index a5bab49..cbe8b41 100644 --- a/wsprd/nhash.h +++ b/wsprd/nhash.h @@ -1,4 +1,3 @@ #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); diff --git a/wsprd/wsprd.c b/wsprd/wsprd.c index d509741..2a3fdd8 100644 --- a/wsprd/wsprd.c +++ b/wsprd/wsprd.c @@ -44,22 +44,29 @@ #include "./wsprsim_utils.h" #include "./metric_tables.h" -#define DF 375.0 / 256.0 -#define DT 1.0 / 375.0 -#define TWOPIDT 2.0 * M_PI * DT -#define NIQ 45000 -#define NBITS 81 -#define NSYM 162 -#define NSPERSYM 256 -#define NFILT 256 -#define NSIG NSYM * NSPERSYM +#define SIGNAL_LENGHT 120 +#define SIGNAL_SAMPLE_RATE 375 +#define SIGNAL_SAMPLES SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE +#define NBITS 81 +#define NSYM 162 +#define NSPERSYM 256 +#define DF 375.0 / 256.0 +#define DT 1.0 / 375.0 +#define DF05 DF * 0.5 +#define DF15 DF * 1.5 +#define TWOPIDT 2.0 * M_PI * DT -/* Possible PATIENCE options: FFTW_ESTIMATE, FFTW_ESTIMATE_PATIENT, FFTW_MEASURE, FFTW_PATIENT, FFTW_EXHAUSTIVE */ + +/* Possible PATIENCE options: F + FTW_ESTIMATE, + FFTW_ESTIMATE_PATIENT, + FFTW_MEASURE, + FFTW_PATIENT, + FFTW_EXHAUSTIVE +*/ #define PATIENCE FFTW_ESTIMATE -fftwf_plan PLAN1, - PLAN2, - PLAN3; +fftwf_plan PLAN; int32_t printdata = 0; uint8_t pr3vector[NSYM] = { @@ -73,93 +80,91 @@ uint8_t pr3vector[NSYM] = { 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0}; -/*********************************************************************** - * mode = 0: no frequency or drift search. find best time lag. * - * 1: no time lag or drift search. find best frequency. * - * 2: no frequency or time lag search. calculate soft-decision * - * symbols using passed frequency and shift. * - ************************************************************************/ -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) { - float fbest = 0.0; - float f0 = 0.0, fp, ss; - int32_t lag; - static float fplast = -10000.0; - float i0[NSYM], q0[NSYM], + +/* mode = 0: no frequency or drift search. find best time lag. + * 1: no time lag or drift search. find best frequency. + * 2: no frequency or time lag search. calculate soft-decision + * symbols using passed frequency and shift. + */ +void sync_and_demodulate(float *id, + float *qd, + long np, + unsigned char *symbols, + float *freq, + int ifmin, + int ifmax, + float fstep, + int *shift, + int lagmin, + int lagmax, + int lagstep, + float *drift, + int symfac, + float *sync, + int mode) { + + float i0[NSYM], q0[NSYM], i1[NSYM], q1[NSYM], i2[NSYM], q2[NSYM], i3[NSYM], q3[NSYM]; - float p0, p1, p2, p3, cmet, totp, syncmax, fac; float c0[NSPERSYM], s0[NSPERSYM], c1[NSPERSYM], s1[NSPERSYM], c2[NSPERSYM], s2[NSPERSYM], c3[NSPERSYM], s3[NSPERSYM]; - float dphi0, cdphi0, sdphi0, - dphi1, cdphi1, sdphi1, - dphi2, cdphi2, sdphi2, - dphi3, cdphi3, sdphi3; - float fsum = 0.0, f2sum = 0.0, fsymb[NSYM]; - int32_t best_shift = 0; - int32_t ifmin = 0, ifmax = 0; + float fsymb[NSYM]; + + float fbest = 0.0, + fsum = 0.0, + f2sum = 0.0; + + int best_shift = 0; + static float fplast = -10000.0; + float syncmax = -1e30; - syncmax = -1e30; if (mode == 0) { ifmin = 0; ifmax = 0; fstep = 0.0; - f0 = *freq1; - } - if (mode == 1) { - lagmin = *shift1; - lagmax = *shift1; - ifmin = -5; - ifmax = 5; - f0 = *freq1; - } - if (mode == 2) { - lagmin = *shift1; - lagmax = *shift1; - ifmin = 0; - ifmax = 0; - f0 = *freq1; + } else if (mode == 1) { + lagmin = *shift; + lagmax = *shift; + } else if (mode == 2) { + lagmin = *shift; + lagmax = *shift; + ifmin = 0; + ifmax = 0; } - for (int32_t ifreq = ifmin; ifreq <= ifmax; ifreq++) { - f0 = *freq1 + ifreq * fstep; - for (lag = lagmin; lag <= lagmax; lag = lag + lagstep) { - ss = 0.0; - totp = 0.0; - for (int32_t i = 0; i < NSYM; i++) { - fp = f0 + ((float)*drift1 / 2.0) * ((float)i - (float)NBITS) / (float)NBITS; + for (int ifreq = ifmin; ifreq <= ifmax; ifreq++) { + float f0 = *freq + ifreq * fstep; + for (int lag = lagmin; lag <= lagmax; lag = lag + lagstep) { + float ss = 0.0; + float totp = 0.0; + for (int i = 0; i < NSYM; i++) { + float fp = f0 + (*drift / 2.0) * ((float)i - (float)NBITS) / (float)NBITS; if (i == 0 || (fp != fplast)) { // only calculate sin/cos if necessary - dphi0 = TWOPIDT * (fp - 1.5 * DF); - cdphi0 = cosf(dphi0); - sdphi0 = sinf(dphi0); + float dphi0 = TWOPIDT * (fp - DF15); + float cdphi0 = cosf(dphi0); + float sdphi0 = sinf(dphi0); - dphi1 = TWOPIDT * (fp - 0.5 * DF); - cdphi1 = cosf(dphi1); - sdphi1 = sinf(dphi1); + float dphi1 = TWOPIDT * (fp - DF05); + float cdphi1 = cosf(dphi1); + float sdphi1 = sinf(dphi1); - dphi2 = TWOPIDT * (fp + 0.5 * DF); - cdphi2 = cosf(dphi2); - sdphi2 = sinf(dphi2); + float dphi2 = TWOPIDT * (fp + DF05); + float cdphi2 = cosf(dphi2); + float sdphi2 = sinf(dphi2); - dphi3 = TWOPIDT * (fp + 1.5 * DF); - cdphi3 = cosf(dphi3); - sdphi3 = sinf(dphi3); + float dphi3 = TWOPIDT * (fp + DF15); + float cdphi3 = cosf(dphi3); + float sdphi3 = sinf(dphi3); - c0[0] = 1; - s0[0] = 0; - c1[0] = 1; - s1[0] = 0; - c2[0] = 1; - s2[0] = 0; - c3[0] = 1; - s3[0] = 0; + c0[0] = 1; s0[0] = 0; + c1[0] = 1; s1[0] = 0; + c2[0] = 1; s2[0] = 0; + c3[0] = 1; s3[0] = 0; - for (int32_t j = 1; j < NSPERSYM; j++) { + for (int j = 1; j < NSPERSYM; j++) { c0[j] = c0[j - 1] * cdphi0 - s0[j - 1] * sdphi0; s0[j] = c0[j - 1] * sdphi0 + s0[j - 1] * cdphi0; c1[j] = c1[j - 1] * cdphi1 - s1[j - 1] * sdphi1; @@ -172,18 +177,14 @@ void sync_and_demodulate(float *id, float *qd, long np, fplast = fp; } - i0[i] = 0.0; - q0[i] = 0.0; - i1[i] = 0.0; - q1[i] = 0.0; - i2[i] = 0.0; - q2[i] = 0.0; - i3[i] = 0.0; - q3[i] = 0.0; + i0[i] = 0.0; q0[i] = 0.0; + i1[i] = 0.0; q1[i] = 0.0; + i2[i] = 0.0; q2[i] = 0.0; + i3[i] = 0.0; q3[i] = 0.0; - for (int32_t j = 0; j < NSPERSYM; j++) { - int32_t k = lag + i * NSPERSYM + j; - if ((k > 0) & (k < np)) { + for (int j = 0; j < NSPERSYM; j++) { + int k = lag + i * NSPERSYM + j; + if ((k > 0) && (k < np)) { i0[i] = i0[i] + id[k] * c0[j] + qd[k] * s0[j]; q0[i] = q0[i] - id[k] * s0[j] + qd[k] * c0[j]; i1[i] = i1[i] + id[k] * c1[j] + qd[k] * s1[j]; @@ -194,51 +195,47 @@ void sync_and_demodulate(float *id, float *qd, long np, q3[i] = q3[i] - id[k] * s3[j] + qd[k] * c3[j]; } } - p0 = i0[i] * i0[i] + q0[i] * q0[i]; - p1 = i1[i] * i1[i] + q1[i] * q1[i]; - p2 = i2[i] * i2[i] + q2[i] * q2[i]; - p3 = i3[i] * i3[i] + q3[i] * q3[i]; - p0 = sqrtf(p0); - p1 = sqrtf(p1); - p2 = sqrtf(p2); - p3 = sqrtf(p3); + float p0 = sqrt(i0[i] * i0[i] + q0[i] * q0[i]); + float p1 = sqrt(i1[i] * i1[i] + q1[i] * q1[i]); + float p2 = sqrt(i2[i] * i2[i] + q2[i] * q2[i]); + float p3 = sqrt(i3[i] * i3[i] + q3[i] * q3[i]); totp = totp + p0 + p1 + p2 + p3; - cmet = (p1 + p3) - (p0 + p2); - ss = ss + cmet * (2 * pr3vector[i] - 1); + float cmet = (p1 + p3) - (p0 + p2); + ss = (pr3vector[i] == 1) ? ss + cmet : ss - cmet; if (mode == 2) { // Compute soft symbols - if (pr3vector[i]) { + if (pr3vector[i] == 1) { fsymb[i] = p3 - p1; } else { fsymb[i] = p2 - p0; } } } - - if (ss / totp > syncmax) { // Save best parameters - syncmax = ss / totp; + ss = ss / totp; + if (ss > syncmax) { // Save best parameters + syncmax = ss; best_shift = lag; fbest = f0; } } // lag loop - } // freq loop + } // freq loop if (mode <= 1) { // Send best params back to caller *sync = syncmax; - *shift1 = best_shift; - *freq1 = fbest; + *shift = best_shift; + *freq = fbest; return; } if (mode == 2) { *sync = syncmax; - for (int32_t i = 0; i < NSYM; i++) { // Normalize the soft symbols - fsum = fsum + fsymb[i] / (float)NSYM; - f2sum = f2sum + fsymb[i] * fsymb[i] / (float)NSYM; + for (int i = 0; i < NSYM; i++) { // Normalize the soft symbols + fsum += fsymb[i] / NSYM; + f2sum += fsymb[i] * fsymb[i] / NSYM; } - fac = sqrtf(f2sum - fsum * fsum); - for (int32_t i = 0; i < NSYM; i++) { + float fac = sqrt(f2sum - fsum * fsum); + for (int i = 0; i < NSYM; i++) { fsymb[i] = symfac * fsymb[i] / fac; if (fsymb[i] > 127) fsymb[i] = 127.0; if (fsymb[i] < -128) fsymb[i] = -128.0; @@ -249,35 +246,38 @@ void sync_and_demodulate(float *id, float *qd, long np, return; } -/*************************************************************************** - symbol-by-symbol signal subtraction - ****************************************************************************/ -void subtract_signal(float *id, float *qd, long np, - float f0, int32_t shift0, float drift0, uint8_t *channel_symbols) { - float i0, q0; + +/* symbol-by-symbol signal subtraction */ +void subtract_signal(float *id, + float *qd, + long np, + float f0, + int shift, + float drift, + unsigned char *channel_symbols) { + float c0[NSPERSYM], s0[NSPERSYM]; - float dphi, cdphi, sdphi; - for (int32_t i = 0; i < NSYM; i++) { - float fp = f0 + ((float)drift0 / 2.0) * ((float)i - (float)NBITS) / (float)NBITS; + for (int i = 0; i < NSYM; i++) { + float fp = f0 + ((float)drift / 2.0) * ((float)i - (float)NBITS) / (float)NBITS; - dphi = TWOPIDT * (fp + ((float)channel_symbols[i] - 1.5) * DF); - cdphi = cosf(dphi); - sdphi = sinf(dphi); + float dphi = TWOPIDT * (fp + ((float)channel_symbols[i] - 1.5) * DF); + float cdphi = cosf(dphi); + float sdphi = sinf(dphi); c0[0] = 1; s0[0] = 0; - for (int32_t j = 1; j < NSPERSYM; j++) { + for (int j = 1; j < NSPERSYM; j++) { c0[j] = c0[j - 1] * cdphi - s0[j - 1] * sdphi; s0[j] = c0[j - 1] * sdphi + s0[j - 1] * cdphi; } - i0 = 0.0; - q0 = 0.0; + float i0 = 0.0; + float q0 = 0.0; - for (int32_t j = 0; j < NSPERSYM; j++) { - int32_t k = shift0 + i * NSPERSYM + j; + for (int j = 0; j < NSPERSYM; j++) { + int k = shift + i * NSPERSYM + j; if ((k > 0) & (k < np)) { i0 = i0 + id[k] * c0[j] + qd[k] * s0[j]; q0 = q0 - id[k] * s0[j] + qd[k] * c0[j]; @@ -288,8 +288,8 @@ void subtract_signal(float *id, float *qd, long np, i0 = i0 / (float)NSPERSYM; // will be wrong for partial symbols at the edges... q0 = q0 / (float)NSPERSYM; - for (int32_t j = 0; j < NSPERSYM; j++) { - int32_t k = shift0 + i * NSPERSYM + j; + for (int j = 0; j < NSPERSYM; j++) { + int k = shift + i * NSPERSYM + j; if ((k > 0) & (k < np)) { id[k] = id[k] - (i0 * c0[j] - q0 * s0[j]); qd[k] = qd[k] - (q0 * c0[j] + i0 * s0[j]); @@ -299,15 +299,22 @@ void subtract_signal(float *id, float *qd, long np, return; } -/****************************************************************************** - Fully coherent signal subtraction - *******************************************************************************/ -void subtract_signal2(float *id, float *qd, long np, - float f0, int32_t shift0, float drift0, uint8_t *channel_symbols) { - float phi = 0, dphi, cs; - float refi[NIQ] = {0}, refq[NIQ] = {0}, - ci[NIQ] = {0}, cq[NIQ] = {0}, - cfi[NIQ] = {0}, cfq[NIQ] = {0}; + +/* Subtract the coherent component of a signal */ +void subtract_signal2(float *id, + float *qd, + long np, + float f0, + int shift, + float drift, + unsigned char *channel_symbols) { + + float phi = 0.0; + const int nfilt = 360; // nfilt must be even number. + + float refi[SIGNAL_SAMPLES] = {0}, refq[SIGNAL_SAMPLES] = {0}, + ci[SIGNAL_SAMPLES] = {0}, cq[SIGNAL_SAMPLES] = {0}, + cfi[SIGNAL_SAMPLES] = {0}, cfq[SIGNAL_SAMPLES] = {0}; /****************************************************************************** Measured signal: s(t)=a(t)*exp( j*theta(t) ) @@ -317,74 +324,75 @@ void subtract_signal2(float *id, float *qd, long np, Multiply r(t) by c(t) and subtract from s(t), i.e. s'(t)=s(t)-c(t)r(t) *******************************************************************************/ - // create reference wspr signal vector, centered on f0. - // - for (int32_t i = 0; i < NSYM; i++) { - cs = (float)channel_symbols[i]; + /* create reference wspr signal vector, centered on f0. */ + for (int i = 0; i < NSYM; i++) { + float cs = (float)channel_symbols[i]; - dphi = TWOPIDT * (f0 + - ((float)drift0 / 2.0) * ((float)i - (float)NSYM / 2.0) / ((float)NSYM / 2.0) + - (cs - 1.5) * DF); + float dphi = TWOPIDT * (f0 + (drift / 2.0) * ((float)i - (float)NSYM / 2.0) / ((float)NSYM / 2.0) + (cs - 1.5) * DF); - for (int32_t j = 0; j < NSPERSYM; j++) { - int32_t ii = NSPERSYM * i + j; - refi[ii] = refi[ii] + cosf(phi); // cannot precompute sin/cos because dphi is changing - refq[ii] = refq[ii] + sinf(phi); + for (int j = 0; j < NSPERSYM; j++) { + int ii = NSPERSYM * i + j; + refi[ii] = cosf(phi); // cannot precompute sin/cos because dphi is changing + refq[ii] = sinf(phi); phi = phi + dphi; } } - // s(t) * conjugate(r(t)) - // beginning of first symbol in reference signal is at i=0 - // beginning of first symbol in received data is at shift0. - // filter transient lasts nfilt samples - // leave nfilt zeros as a pad at the beginning of the unfiltered reference signal - for (int32_t i = 0; i < NSYM * NSPERSYM; i++) { - int32_t k = shift0 + i; - if ((k > 0) & (k < np)) { - ci[i + NFILT] = id[k] * refi[i] + qd[k] * refq[i]; - cq[i + NFILT] = qd[k] * refi[i] - id[k] * refq[i]; - } - } + float w[nfilt], norm = 0, partialsum[nfilt]; - // quick and dirty filter - may want to do better - float w[NFILT] = {0}, norm = 0, partialsum[NFILT] = {0}; - for (int32_t i = 0; i < NFILT; i++) { - w[i] = sinf(M_PI * (float)i / (float)(NFILT - 1)); + /* lowpass filter and remove startup transient */ + for (int i = 0; i < nfilt; i++) { + partialsum[i] = 0.0; + } + for (int i = 0; i < nfilt; i++) { + w[i] = sinf(M_PI * (float)i / (float)(nfilt - 1)); norm = norm + w[i]; } - for (int32_t i = 0; i < NFILT; i++) { + for (int i = 0; i < nfilt; i++) { w[i] = w[i] / norm; } - for (int32_t i = 1; i < NFILT; i++) { + for (int i = 1; i < nfilt; i++) { partialsum[i] = partialsum[i - 1] + w[i]; } + // s(t) * conjugate(r(t)) + // beginning of first symbol in reference signal is at i=0 + // beginning of first symbol in received data is at shift value. + // filter transient lasts nfilt samples + // leave nfilt zeros as a pad at the beginning of the unfiltered reference signal + for (int i = 0; i < NSYM * NSPERSYM; i++) { + int k = shift + i; + if ((k > 0) && (k < np)) { + ci[i + nfilt] = id[k] * refi[i] + qd[k] * refq[i]; + cq[i + nfilt] = qd[k] * refi[i] - id[k] * refq[i]; + } + } + // LPF - for (int32_t i = NFILT / 2; i < NIQ - NFILT / 2; i++) { + for (int i = nfilt / 2; i < SIGNAL_SAMPLES - nfilt / 2; i++) { cfi[i] = 0.0; cfq[i] = 0.0; - for (int32_t j = 0; j < NFILT; j++) { - cfi[i] = cfi[i] + w[j] * ci[i - NFILT / 2 + j]; - cfq[i] = cfq[i] + w[j] * cq[i - NFILT / 2 + j]; + for (int j = 0; j < nfilt; j++) { + cfi[i] = cfi[i] + w[j] * ci[i - nfilt / 2 + j]; + cfq[i] = cfq[i] + w[j] * cq[i - nfilt / 2 + j]; } } // subtract c(t)*r(t) here - // (ci+j*cq)(refi+j*refq)=(ci*refi-cq*refq)+j(ci*refq)+cq*refi) - // beginning of first symbol in reference signal is at i=NFILT - // beginning of first symbol in received data is at shift0. - for (int32_t i = 0; i < NSIG; i++) { - if (i < NFILT / 2) { // take care of the end effect (LPF step response) here - norm = partialsum[NFILT / 2 + i]; - } else if (i > (NSIG - 1 - NFILT / 2)) { - norm = partialsum[NFILT / 2 + NSIG - 1 - i]; + // (ci+j*cq)(refi+j*refq)=(ci*refi-cq*refq)+j(ci*refq+cq*refi) + // beginning of first symbol in reference signal is at i=nfilt + // beginning of first symbol in received data is at shift value. + for (int i = 0; i < NSYM * NSPERSYM; i++) { + if (i < nfilt / 2) { // take care of the end effect (LPF step response) here + norm = partialsum[nfilt / 2 + i]; + } else if (i > (NSYM * NSPERSYM - 1 - nfilt / 2)) { + norm = partialsum[nfilt / 2 + NSYM * NSPERSYM - 1 - i]; } else { norm = 1.0; } - int32_t k = shift0 + i; - int32_t j = i + NFILT; - if ((k > 0) & (k < np)) { + int k = shift + i; + int j = i + nfilt; + if ((k > 0) && (k < np)) { id[k] = id[k] - (cfi[j] * refi[i] - cfq[j] * refq[i]) / norm; qd[k] = qd[k] - (cfi[j] * refq[i] + cfq[j] * refi[i]) / norm; } @@ -392,111 +400,138 @@ void subtract_signal2(float *id, float *qd, long np, return; } -int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints, - struct decoder_options options, struct decoder_results *decodes, - int32_t *n_results) { - int32_t i, j, k; + +int wspr_decode(float *idat, + float *qdat, + int samples, + struct decoder_options options, + struct decoder_results *decodes, + int *n_results) { + + /* Parameters used for performance-tuning */ + float minsync1 = 0.10; // First sync limit + float minsync2 = 0.12; // Second sync limit + int iifac = 3; // Step size in final DT peakup + int symfac = 50; // Soft-symbol normalizing factor + int maxdrift = 4; // Maximum (+/-) drift + float minrms = 52.0 * (symfac / 64.0); // Final test for plausible decoding + int delta = 60; // Fano threshold step + int maxcycles = 10000; // Fano timeout limit + float fmin = -110.0; + float fmax = 110.0; + + /* Search live parameters */ + float fstep; + int lagmin; + int lagmax; + int lagstep; + int ifmin; + int ifmax; + + /* Decoder flags */ + int worth_a_try; + int uniques = 0; + + /* CPU usage stats */ + uint32_t metric, cycles, maxnp; + + /* Candidates properties */ + struct cand candidates[200]; + + /* Decoded candidate */ uint8_t symbols[NBITS * 2] = {0}; uint8_t decdata[(NBITS + 7) / 8] = {0}; - int8_t message[12] = {0}; + int8_t message[12] = {0}; - float freq0[200], freq1 = 0.0; - float drift0[200], drift1 = 0.0; - float sync0[200], sync1 = 0.0; - float snr0[200]; - int32_t shift0[200], shift1 = 0; + /* Results */ + char callsign[13] = {0}; + char call_loc_pow[23] = {0}; + char call[13] = {0}; + char loc[7] = {0}; + char pwr[3] = {0}; + float allfreqs[100] = {0}; + char allcalls[100][13] = {0}; - char callsign[13] = {0}; - char call_loc_pow[23] = {0}; - char call[13] = {0}; - char loc[7] = {0}; - char pwr[3] = {0}; - - uint32_t metric, cycles, maxnp; - int32_t worth_a_try; - int32_t uniques = 0; - float fmin = -110.0; - float fmax = 110.0; - - // Hash table - char hashtab[32768 * 13] = {0}; - int32_t nh; - - // Parameters used for performance-tuning: - uint32_t maxcycles = 10000; // Fano timeout limit - double minsync1 = 0.10; // First sync limit - double minsync2 = 0.12; // Second sync limit - int32_t iifac = 3; // Step size in final DT peakup - int32_t symfac = 50; // Soft-symbol normalizing factor - int32_t maxdrift = 4; // Maximum (+/-) drift - double minrms = 52.0 * (symfac / 64.0); // Final test for plausible decoding - int32_t delta = 60; // Fano threshold step - - // Results - float allfreqs[100]; - char allcalls[100][13]; - memset(allfreqs, 0, sizeof(float) * 100); - memset(allcalls, 0, sizeof(char) * 100 * 13); - - // Setup metric table + /* Setup metric table */ int32_t mettab[2][256]; float bias = 0.42; - for (i = 0; i < 256; i++) { + for (int i = 0; i < 256; i++) { mettab[0][i] = round(10 * (metric_tables[2][i] - bias)); mettab[1][i] = round(10 * (metric_tables[2][255 - i] - bias)); } - // FFT buffer - fftwf_complex *fftin, *fftout; - - FILE *fp_fftw_wisdom_file, *fhash; - if ((fp_fftw_wisdom_file = fopen("fftw_wisdom.dat", "r"))) { // Open FFTW wisdom - fftwf_import_wisdom_from_file(fp_fftw_wisdom_file); - fclose(fp_fftw_wisdom_file); - } - - // Do windowed ffts over 2 symbols, stepped by half symbols - int32_t nffts = 4 * floor(npoints / 512) - 1; - fftin = (fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex) * 512); - fftout = (fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex) * 512); - PLAN3 = fftwf_plan_dft_1d(512, fftin, fftout, FFTW_FORWARD, PATIENCE); - - float ps[512][nffts]; - float w[512]; - for (i = 0; i < 512; i++) { - w[i] = sinf(0.006147931 * i); - } + /* Setup/Load hash tables */ + FILE *fhash; + int nh; + char hashtab[32768 * 13] = {0}; + char loctab[32768 * 5] = {0}; if (options.usehashtable) { - char line[80], hcall[12]; + char line[80], hcall[12], hgrid[5];; if ((fhash = fopen("hashtable.txt", "r+"))) { while (fgets(line, sizeof(line), fhash) != NULL) { - sscanf(line, "%d %s", &nh, hcall); + hgrid[0] = '\0'; + sscanf(line, "%d %s %s", &nh, hcall, hgrid); strcpy(hashtab + nh * 13, hcall); + if (strlen(hgrid) > 0) strcpy(loctab + nh * 5, hgrid); } fclose(fhash); } } - // Main loop starts here - for (int32_t ipass = 0; ipass < options.npasses; ipass++) { + /* FFT buffer (512 bins) */ + fftwf_complex *fftin, *fftout; + fftin = (fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex) * 512); + fftout = (fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex) * 512); + PLAN = fftwf_plan_dft_1d(512, fftin, fftout, FFTW_FORWARD, PATIENCE); + + /* Recover FFTW optimization settings */ + FILE *fp_fftw_wisdom_file; + if ((fp_fftw_wisdom_file = fopen("fftw_wisdom.dat", "r"))) { // Open FFTW wisdom + fftwf_import_wisdom_from_file(fp_fftw_wisdom_file); + fclose(fp_fftw_wisdom_file); + } + + /* Hann function */ + float hann[512]; + for (int i = 0; i < 512; i++) { + hann[i] = sinf(0.006147931 * i); + } + + /* FFT output alloc */ + const int blocks = 4 * floor(samples / 512) - 1; + float ps[512][blocks]; + memset(ps, 0.0, sizeof(float) * 512 * blocks); + + /* Main loop starts here */ + for (int ipass = 0; ipass < options.npasses; ipass++) { if (ipass == 1 && uniques == 0) break; - if (ipass == 1) // otherwise we bog down on the second pass - options.quickmode = 1; + if (ipass < 2) { + maxdrift = 4; + minsync2 = 0.12; + } + if (ipass == 2) { + maxdrift = 0; // no drift for smaller frequency estimator variance + minsync2 = 0.10; + } - memset(ps, 0.0, sizeof(float) * 512 * nffts); - for (i = 0; i < nffts; i++) { - for (j = 0; j < 512; j++) { - k = i * 128 + j; - fftin[j][0] = idat[k] * w[j]; - fftin[j][1] = qdat[k] * w[j]; + /* Compute FFT + * FFT over 2 symbols, stepped by half symbols + */ + for (int i = 0; i < blocks; i++) { + /* Load samples */ + for (int j = 0; j < 512; j++) { + int k = i * 128 + j; + fftin[j][0] = idat[k] * hann[j]; + fftin[j][1] = qdat[k] * hann[j]; } - fftwf_execute(PLAN3); + fftwf_execute(PLAN); - for (j = 0; j < 512; j++) { - k = j + 256; + /* Recover frequencies */ + for (int j = 0; j < 512; j++) { + int k = j + 256; if (k > 511) k = k - 512; ps[j][i] = fftout[k][0] * fftout[k][0] + fftout[k][1] * fftout[k][1]; @@ -505,26 +540,27 @@ int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints, // Compute average spectrum float psavg[512] = {0}; - for (i = 0; i < nffts; i++) { - for (j = 0; j < 512; j++) { - psavg[j] = psavg[j] + ps[j][i]; + for (int i = 0; i < blocks; i++) { + for (int j = 0; j < 512; j++) { + psavg[j] += ps[j][i]; } } + // Already restricted by previous FIR // Smooth with 7-point window and limit spectrum to +/-150 Hz int32_t window[7] = {1, 1, 1, 1, 1, 1, 1}; float smspec[411]; - for (i = 0; i < 411; i++) { + for (int i = 0; i < 411; i++) { smspec[i] = 0.0; - for (j = -3; j <= 3; j++) { - k = 256 - 205 + i + j; - smspec[i] = smspec[i] + window[j + 3] * psavg[k]; + for (int j = -3; j <= 3; j++) { + int k = 256 - 205 + i + j; + smspec[i] += window[j + 3] * psavg[k]; } } // Sort spectrum values, then pick off noise level as a percentile float tmpsort[411]; - for (j = 0; j < 411; j++) { + for (int j = 0; j < 411; j++) { tmpsort[j] = smspec[j]; } qsort(tmpsort, 411, sizeof(float), floatcomp); @@ -540,59 +576,52 @@ int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints, float min_snr = powf(10.0, -7.0 / 10.0); // this is min snr in wspr bw float snr_scaling_factor = 26.3; - for (j = 0; j < 411; j++) { + for (int j = 0; j < 411; j++) { smspec[j] = smspec[j] / noise_level - 1.0; if (smspec[j] < min_snr) smspec[j] = 0.1; continue; } // Find all local maxima in smoothed spectrum. - for (i = 0; i < 200; i++) { - freq0[i] = 0.0; - snr0[i] = 0.0; - drift0[i] = 0.0; - shift0[i] = 0; - sync0[i] = 0.0; + for (int i = 0; i < 200; i++) { + candidates[i].freq = 0.0; + candidates[i].snr = 0.0; + candidates[i].drift = 0.0; + candidates[i].shift = 0; + candidates[i].sync = 0.0; } - int32_t npk = 0; - for (j = 1; j < 410; j++) { - if ((smspec[j] > smspec[j - 1]) && (smspec[j] > smspec[j + 1]) && (npk < 200)) { - freq0[npk] = (j - 205) * (DF / 2.0); - snr0[npk] = 10.0 * log10f(smspec[j]) - snr_scaling_factor; + int npk = 0; + unsigned char candidate; + for (int j = 1; j < 410; j++) { + candidate = (smspec[j] > smspec[j - 1]) && + (smspec[j] > smspec[j + 1]) && + (npk < 200); + if (candidate) { + candidates[npk].freq = (j - 205) * (DF / 2.0); + candidates[npk].snr = 10.0 * log10f(smspec[j]) - snr_scaling_factor; npk++; } } - /* Compute corrected fmin, fmax, accounting for dial frequency error - float dialfreq_error = 0.0; // dialfreq_error is in units of Hz - fmin += dialfreq_error; - fmax += dialfreq_error; - */ - // Don't waste time on signals outside of the range [fmin,fmax]. - i = 0; - for (j = 0; j < npk; j++) { - if (freq0[j] >= fmin && freq0[j] <= fmax) { - freq0[i] = freq0[j]; - snr0[i] = snr0[j]; + int i = 0; + for (int j = 0; j < npk; j++) { + if (candidates[j].freq >= fmin && candidates[j].freq <= fmax) { + candidates[i] = candidates[j]; i++; } } npk = i; // bubble sort on snr, bringing freq along for the ride - int32_t pass; - float tmp; - for (pass = 1; pass <= npk - 1; pass++) { - for (k = 0; k < npk - pass; k++) { - if (snr0[k] < snr0[k + 1]) { - tmp = snr0[k]; - snr0[k] = snr0[k + 1]; - snr0[k + 1] = tmp; - tmp = freq0[k]; - freq0[k] = freq0[k + 1]; - freq0[k + 1] = tmp; + struct cand tmp; + for (int pass = 1; pass <= npk - 1; pass++) { + for (int k = 0; k < npk - pass; k++) { + if (candidates[k].snr < candidates[k + 1].snr) { + tmp = candidates[k]; + candidates[k] = candidates[k + 1]; + candidates[k + 1] = tmp; } } } @@ -610,43 +639,34 @@ int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints, span of 162 symbols, with deviation equal to 0 at the center of the signal vector. */ - - int32_t idrift, ifr, if0, ifd, k0; - int32_t kindex; - float smax, ss, pow, p0, p1, p2, p3; - for (j = 0; j < npk; j++) { // For each candidate... - smax = -1e30; - if0 = freq0[j] / (DF / 2.0) + NSPERSYM; - for (ifr = if0 - 1; ifr <= if0 + 1; ifr++) { // Freq search - for (k0 = -10; k0 < 22; k0++) { // Time search - for (idrift = -maxdrift; idrift <= maxdrift; idrift++) { // Drift search - ss = 0.0; - pow = 0.0; - for (k = 0; k < NSYM; k++) { // Sum over symbols - ifd = ifr + ((float)k - (float)NBITS) / (float)NBITS * ((float)idrift) / DF; - kindex = k0 + 2 * k; - if (kindex < nffts) { - p0 = ps[ifd - 3][kindex]; - p1 = ps[ifd - 1][kindex]; - p2 = ps[ifd + 1][kindex]; - p3 = ps[ifd + 3][kindex]; - - p0 = sqrtf(p0); - p1 = sqrtf(p1); - p2 = sqrtf(p2); - p3 = sqrtf(p3); + for (int j = 0; j < npk; j++) { // For each candidate... + float sync, sync_max = -1e30; + int if0 = candidates[j].freq / (DF / 2.0) + NSPERSYM; + for (int ifr = if0 - 1; ifr <= if0 + 1; ifr++) { // Freq search + for (int k0 = -10; k0 < 22; k0++) { // Time search + for (int idrift = -maxdrift; idrift <= maxdrift; idrift++) { // Drift search + float ss = 0.0; + float pow = 0.0; + for (int k = 0; k < NSYM; k++) { // Sum over symbols + int ifd = ifr + ((float)k - (float)NBITS) / (float)NBITS * ((float)idrift) / DF; + int kindex = k0 + 2 * k; + if (kindex < blocks) { + float p0 = sqrtf(ps[ifd - 3][kindex]); + float p1 = sqrtf(ps[ifd - 1][kindex]); + float p2 = sqrtf(ps[ifd + 1][kindex]); + float p3 = sqrtf(ps[ifd + 3][kindex]); ss = ss + (2 * pr3vector[k] - 1) * ((p1 + p3) - (p0 + p2)); pow = pow + p0 + p1 + p2 + p3; - sync1 = ss / pow; + sync = ss / pow; } } - if (sync1 > smax) { // Save coarse parameters - smax = sync1; - shift0[j] = 128 * (k0 + 1); - drift0[j] = idrift; - freq0[j] = (ifr - NSPERSYM) * (DF / 2.0); - sync0[j] = sync1; + if (sync > sync_max) { // Save coarse parameters + sync_max = sync; + candidates[j].shift = 128 * (k0 + 1); + candidates[j].drift = idrift; + candidates[j].freq = (ifr - NSPERSYM) * (DF / 2.0); + candidates[j].sync = sync; } } } @@ -670,70 +690,75 @@ int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints, could each work on one candidate at a time. */ - for (j = 0; j < npk; j++) { - memset(symbols, 0, sizeof(char) * NBITS * 2); + for (int j = 0; j < npk; j++) { memset(callsign, 0, sizeof(char) * 13); memset(call_loc_pow, 0, sizeof(char) * 23); memset(call, 0, sizeof(char) * 13); memset(loc, 0, sizeof(char) * 7); memset(pwr, 0, sizeof(char) * 3); - freq1 = freq0[j]; - drift1 = drift0[j]; - shift1 = shift0[j]; - sync1 = sync0[j]; - - // Fine search for best sync lag (mode 0) - float fstep = 0.0; - int32_t lagmin = shift1 - 144; - int32_t lagmax = shift1 + 144; - int32_t lagstep = 8; + float freq = candidates[j].freq; + float drift = candidates[j].drift; + float sync = candidates[j].sync; + int shift = candidates[j].shift; + // Search for best sync lag (mode 0) + fstep = 0.0; + ifmin = 0; + ifmax = 0; + lagmin = shift - 128; + lagmax = shift + 128; + lagstep = 8; if (options.quickmode) lagstep = 16; + sync_and_demodulate(idat, qdat, samples, symbols, &freq, ifmin, ifmax, fstep, &shift, + lagmin, lagmax, lagstep, &drift, symfac, &sync, 0); - sync_and_demodulate(idat, qdat, npoints, symbols, &freq1, fstep, &shift1, - lagmin, lagmax, lagstep, &drift1, symfac, &sync1, 0); - - // Fine search for frequency peak (mode 1) + // Search for frequency peak (mode 1) fstep = 0.1; - sync_and_demodulate(idat, qdat, npoints, symbols, &freq1, fstep, &shift1, - lagmin, lagmax, lagstep, &drift1, symfac, &sync1, 1); + ifmin = -2; + ifmax = 2; + sync_and_demodulate(idat, qdat, samples, symbols, &freq, ifmin, ifmax, fstep, &shift, + lagmin, lagmax, lagstep, &drift, symfac, &sync, 1); - if (sync1 > minsync1) { + candidates[j].freq = freq; + candidates[j].shift = shift; + candidates[j].drift = drift; + candidates[j].sync = sync; + + if (sync > minsync1) { worth_a_try = 1; } else { worth_a_try = 0; } - int32_t idt = 0, ii = 0, jiggered_shift; - float y, sq, rms; - int32_t not_decoded = 1; - + int idt = 0, ii = 0; + int not_decoded = 1; while (worth_a_try && not_decoded && idt <= (128 / iifac)) { ii = (idt + 1) / 2; if (idt % 2 == 1) ii = -ii; ii = iifac * ii; - jiggered_shift = shift1 + ii; + int jiggered_shift = shift + ii; // Use mode 2 to get soft-decision symbols - sync_and_demodulate(idat, qdat, npoints, symbols, &freq1, fstep, - &jiggered_shift, lagmin, lagmax, lagstep, &drift1, symfac, - &sync1, 2); - sq = 0.0; + sync_and_demodulate(idat, qdat, samples, symbols, &freq, ifmin, ifmax, fstep, + &jiggered_shift, lagmin, lagmax, lagstep, &drift, symfac, + &sync, 2); + float sq = 0.0; for (i = 0; i < NSYM; i++) { - y = (float)symbols[i] - 128.0; + float y = (float)symbols[i] - 128.0; sq += y * y; } - rms = sqrtf(sq / (float)NSYM); + float rms = sqrtf(sq / (float)NSYM); - if ((sync1 > minsync2) && (rms > minrms)) { + if ((sync > minsync2) && (rms > minrms)) { deinterleave(symbols); not_decoded = fano(&metric, &cycles, &maxnp, decdata, symbols, NBITS, mettab, delta, maxcycles); } idt++; - if (options.quickmode) break; + if (options.quickmode) + break; } if (worth_a_try && !not_decoded) { @@ -748,13 +773,12 @@ int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints, // Unpack the decoded message, update the hashtable, apply // sanity checks on grid and power, and return // call_loc_pow string and also callsign (for de-duping). - int32_t noprint = unpk_(message, hashtab, call_loc_pow, call, loc, pwr, callsign); - + int32_t noprint = unpk_(message, hashtab, loctab, call_loc_pow, call, loc, pwr, callsign); if (options.subtraction && (ipass == 0) && !noprint) { unsigned char channel_symbols[NSYM]; - if (get_wspr_channel_symbols(call_loc_pow, hashtab, channel_symbols)) { - subtract_signal2(idat, qdat, npoints, freq1, shift1, drift1, channel_symbols); + if (get_wspr_channel_symbols(call_loc_pow, hashtab, loctab, channel_symbols)) { + subtract_signal2(idat, qdat, samples, freq, shift, drift, channel_symbols); } else { break; } @@ -763,24 +787,23 @@ int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints, // Remove dupes (same callsign and freq within 3 Hz) int32_t dupe = 0; for (i = 0; i < uniques; i++) { - if (!strcmp(callsign, allcalls[i]) && (fabs(freq1 - allfreqs[i]) < 3.0)) + if (!strcmp(callsign, allcalls[i]) && (fabs(freq - allfreqs[i]) < 3.0)) dupe = 1; } if (!dupe) { strcpy(allcalls[uniques], callsign); - allfreqs[uniques] = freq1; + allfreqs[uniques] = freq; uniques++; double dialfreq = (double)options.freq / 1e6; - double freq_print = dialfreq + (1500 + freq1) / 1e6; - float dt_print = shift1 * DT - 2.0; + double freq_print = dialfreq + (1500.0 + freq) / 1e6; - decodes[uniques - 1].sync = sync1; - decodes[uniques - 1].snr = snr0[j]; - decodes[uniques - 1].dt = dt_print; - decodes[uniques - 1].freq = freq_print; - decodes[uniques - 1].drift = drift1; + decodes[uniques - 1].sync = candidates[j].sync; + decodes[uniques - 1].snr = candidates[j].snr; + decodes[uniques - 1].dt = shift * DT - 2.0; + decodes[uniques - 1].freq = freq_print; + decodes[uniques - 1].drift = drift; decodes[uniques - 1].cycles = cycles; decodes[uniques - 1].jitter = ii; strcpy(decodes[uniques - 1].message, call_loc_pow); @@ -792,20 +815,19 @@ int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints, } } - // sort the result + /* Sort the result */ struct decoder_results temp; - for (j = 1; j <= uniques - 1; j++) { - for (k = 0; k < uniques - j; k++) { + for (int j = 1; j <= uniques - 1; j++) { + for (int k = 0; k < uniques - j; k++) { if (decodes[k].snr < decodes[k + 1].snr) { temp = decodes[k]; decodes[k] = decodes[k + 1]; - ; decodes[k + 1] = temp; } } } - // Return number of spots to the calling fct + /* Return number of spots to the calling fct */ *n_results = uniques; fftwf_free(fftin); @@ -816,18 +838,17 @@ int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints, fclose(fp_fftw_wisdom_file); } - fftwf_destroy_plan(PLAN1); - fftwf_destroy_plan(PLAN2); - fftwf_destroy_plan(PLAN3); + fftwf_destroy_plan(PLAN); if (options.usehashtable) { fhash = fopen("hashtable.txt", "w"); - for (i = 0; i < 32768; i++) { + for (int i = 0; i < 32768; i++) { if (strncmp(hashtab + i * 13, "\0", 1) != 0) { - fprintf(fhash, "%5d %s\n", i, hashtab + i * 13); + fprintf(fhash, "%5d %s %s\n", i, hashtab + i * 13, loctab + i * 5); } } fclose(fhash); } + return 0; } diff --git a/wsprd/wsprd.h b/wsprd/wsprd.h index 386452b..088c470 100644 --- a/wsprd/wsprd.h +++ b/wsprd/wsprd.h @@ -35,37 +35,71 @@ /* 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 - uint32_t quickmode; // Decoder option & tweak - uint32_t usehashtable; // '' - uint32_t npasses; // '' - uint32_t subtraction; // '' + int freq; // Dial frequency + char rcall[13]; // Callsign of the RX station + char rloc[7]; // Locator of the RX station + int quickmode; // Decoder option & tweak + int usehashtable; // '' + int npasses; // '' + int subtraction; // '' +}; + +struct cand { + float freq; + float snr; + int shift; + float drift; + float sync; }; 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]; - uint32_t cycles; + double freq; + float sync; + float snr; + float dt; + float drift; + int jitter; + char message[23]; + char call[13]; + char loc[7]; + char pwr[3]; + int 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); -void subtract_signal2(float *id, float *qd, long np, - 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); +void sync_and_demodulate(float *id, + float *qd, + long np, + unsigned char *symbols, + float *freq, + int ifmin, + int ifmax, + float fstep, + int *shift, + int lagmin, + int lagmax, + int lagstep, + float *drift, + int symfac, + float *sync, + int mode); +void subtract_signal(float *id, + float *qd, + long np, + float f0, + int shift, + float drift, + unsigned char *channel_symbols); +void subtract_signal2(float *id, + float *qd, + long np, + float f0, + int shift, + float drift, + unsigned char *channel_symbols); +int wspr_decode(float *idat, + float *qdat, + int samples, + struct decoder_options options, + struct decoder_results *decodes, + int *n_results); + diff --git a/wsprd/wsprd_utils.c b/wsprd/wsprd_utils.c index 65fb572..9a63009 100644 --- a/wsprd/wsprd_utils.c +++ b/wsprd/wsprd_utils.c @@ -152,7 +152,7 @@ int unpackgrid(int32_t ngrid, char *grid) { } int unpackpfx(int32_t nprefix, char *call) { - char nc, pfx[4] = "", tmpcall[7] = ""; + char nc, pfx[4] = {'\0'}, tmpcall[7]; int i; int32_t n; @@ -172,7 +172,8 @@ int unpackpfx(int32_t nprefix, char *call) { n = n / 37; } - strcpy(call, pfx); + char *p = strrchr(pfx, ' '); + strcpy(call, p ? p + 1 : pfx); strncat(call, "/", 1); strncat(call, tmpcall, strlen(tmpcall)); @@ -234,9 +235,9 @@ int floatcomp(const void *elem1, const void *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) { +int unpk_(signed char *message, char *hashtab, char *loctab, char *call_loc_pow, char *call, char *loc, char *pwr, char *callsign) { int n1, n2, n3, ndbm, ihash, nadd, noprint = 0; - char grid[5], grid6[7], cdbm[3]; + char grid[5], grid6[7], cdbm[4]; unpack50(message, &n1, &n2); if (!unpackcall(n1, callsign)) @@ -250,13 +251,10 @@ int unpk_(signed char *message, char *hashtab, char *call_loc_pow, char *call, c /* Based on the value of ntype, decide whether this is a Type 1, 2, or 3 message. - * Type 1: 6 digit call, grid, power - ntype is positive and is a member of the set {0,3,7,10,13,17,20...60} - * Type 2: extended callsign, power - ntype is positive but not a member of the set of allowed powers - * Type 3: hash, 6 digit grid, power - ntype is negative. */ @@ -274,26 +272,23 @@ int unpk_(signed char *message, char *hashtab, char *call_loc_pow, char *call, c strncat(call_loc_pow, "\0", 1); ihash = nhash(callsign, strlen(callsign), (uint32_t)146); strcpy(hashtab + ihash * 13, callsign); + strcpy(loctab + ihash * 5, grid); - memset(call, 0, strlen(callsign) + 1); - memset(loc, 0, strlen(grid) + 1); - memset(pwr, 0, 2 + 1); + memset(call, 0, sizeof(char) * strlen(callsign) + 1); + memset(loc, 0, sizeof(char) * strlen(grid) + 1); + memset(pwr, 0, sizeof(char) * 2 + 1); strncat(call, callsign, strlen(callsign)); strncat(call, "\0", 1); strncat(loc, grid, strlen(grid)); strncat(loc, "\0", 1); strncat(pwr, cdbm, 2); strncat(pwr, "\0", 1); - } else { nadd = nu; - if (nu > 3) - nadd = nu - 3; - if (nu > 7) - nadd = nu - 7; + if (nu > 3) nadd = nu - 3; + if (nu > 7) nadd = nu - 7; n3 = n2 / 128 + 32768 * (nadd - 1); - if (!unpackpfx(n3, callsign)) - return 1; + if (!unpackpfx(n3, callsign)) return 1; ndbm = ntype - nadd; memset(call_loc_pow, 0, sizeof(char) * 23); sprintf(cdbm, "%2d", ndbm); @@ -305,33 +300,23 @@ int unpk_(signed char *message, char *hashtab, char *call_loc_pow, char *call, c if (nu == 0 || nu == 3 || nu == 7) { // make sure power is OK ihash = nhash(callsign, strlen(callsign), (uint32_t)146); strcpy(hashtab + ihash * 13, callsign); - } else { + } else noprint = 1; - } - - memset(call, 0, strlen(callsign) + 1); - memset(loc, 0, 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); - strncat(grid6, callsign, 5); + // size_t len=strlen(callsign); + size_t len = 6; + strncat(grid6, callsign + len - 1, 1); + strncat(grid6, callsign, len - 1); int nu = ndbm % 10; - if ((nu == 0 || nu == 3 || nu == 7) && - (isalpha(grid6[0]) && isalpha(grid6[1]) && isdigit(grid6[2]) && isdigit(grid6[3]))) { + if ((nu != 0 && nu != 3 && nu != 7) || + !isalpha(grid6[0]) || !isalpha(grid6[1]) || + !isdigit(grid6[2]) || !isdigit(grid6[3])) { // not testing 4'th and 5'th chars because of this case: 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); - } else { noprint = 1; } @@ -351,9 +336,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, sizeof(char) * strlen(callsign) + 1); + memset(loc, 0, sizeof(char) * strlen(grid6) + 1); + memset(pwr, 0, sizeof(char) * 2 + 1); strncat(call, callsign, strlen(callsign)); strncat(call, "\0", 1); strncat(loc, grid6, strlen(grid6)); @@ -362,7 +347,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; diff --git a/wsprd/wsprd_utils.h b/wsprd/wsprd_utils.h index f28726e..31e9422 100644 --- a/wsprd/wsprd_utils.h +++ b/wsprd/wsprd_utils.h @@ -39,4 +39,4 @@ void deinterleave(unsigned char *sym); 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); +int unpk_(signed char *message, char *hashtab, char *loctab, char *call_loc_pow, char *call, char *loc, char *pwr, char *callsign); diff --git a/wsprd/wsprsim_utils.c b/wsprd/wsprsim_utils.c index 5f21520..b64118f 100644 --- a/wsprd/wsprsim_utils.c +++ b/wsprd/wsprsim_utils.c @@ -38,7 +38,7 @@ char get_callsign_character_code(char ch) { return -1; } -long unsigned int pack_grid4_power(char *grid4, int power) { +long unsigned int pack_grid4_power(char const *grid4, int power) { long unsigned int m; m = (179 - 10 * grid4[0] - grid4[2]) * 180 + 10 * grid4[1] + grid4[3]; @@ -46,31 +46,23 @@ long unsigned int pack_grid4_power(char *grid4, int power) { return m; } -long unsigned int pack_call(char *callsign) { - int i; +long unsigned int pack_call(char const *callsign) { + unsigned int i; long unsigned int n; char call6[6]; - memset(call6, 32, sizeof(char) * 6); + memset(call6, ' ', sizeof(call6)); // callsign is 6 characters in length. Exactly. - int call_len = strlen(callsign); + size_t call_len = strlen(callsign); if (call_len > 6) { return 0; } - if (isdigit(*(callsign + 2))) { - for (i = 0; i < 6; i++) { - if (callsign[i] == 0) { - call6[i] = 32; - } else { - call6[i] = *(callsign + i); - } + if (isdigit(callsign[2])) { + for (i = 0; i < call_len; 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 { - call6[i] = *(callsign + i - 1); - } + } else if (isdigit(callsign[1])) { + for (i = 1; i < call_len + 1; i++) { + call6[i] = callsign[i - 1]; } } for (i = 0; i < 6; i++) { @@ -86,17 +78,16 @@ long unsigned int pack_call(char *callsign) { } 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, "/"); + size_t i; + char *call6 = calloc(7, sizeof(char)); + size_t i1 = strcspn(callsign, "/"); if (callsign[i1 + 2] == 0) { // single char suffix for (i = 0; i < i1; i++) { call6[i] = callsign[i]; } + call6[i] = '\0'; *n = pack_call(call6); *nadd = 1; int nc = callsign[i1 + 1]; @@ -118,11 +109,10 @@ void pack_prefix(char *callsign, int32_t *n, int32_t *m, int32_t *nadd) { *m = 10 * (callsign[i1 + 1] - 48) + (callsign[i1 + 2] - 48); *m = 60000 + 26 + *m; } else { - char *pfx = strtok(callsign, "/"); - *n = pack_call(strtok(NULL, " ")); - //call6 = strtok(NULL, " "); - //*n = pack_call(call6); - int plen = strlen(pfx); + char const *pfx = strtok(callsign, "/"); + char const *call = strtok(NULL, " "); + *n = pack_call(call); + size_t plen = strlen(pfx); if (plen == 1) { *m = 36; *m = 37 * (*m) + 36; @@ -148,6 +138,7 @@ void pack_prefix(char *callsign, int32_t *n, int32_t *m, int32_t *nadd) { *nadd = 1; } } + free(call6); } void interleave(unsigned char *sym) { @@ -169,10 +160,11 @@ void interleave(unsigned char *sym) { } } -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, char *loctab, unsigned char *symbols) { + int m = 0, ntype = 0; + long unsigned int n = 0; int i, j, ihash; - unsigned char pr3[162] = { + unsigned char pr3vector[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, @@ -181,7 +173,8 @@ int get_wspr_channel_symbols(char *rawmessage, char *hashtab, unsigned char *sym 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}; + 0, 0 }; + int nu[10] = {0, -1, 1, 0, -1, 2, 1, 0, -1, 1}; char *callsign, *grid, *powstr; char grid4[5], message[23]; @@ -193,16 +186,16 @@ int get_wspr_channel_symbols(char *rawmessage, char *hashtab, unsigned char *sym i++; } - int i1 = strcspn(message, " "); - int i2 = strcspn(message, "/"); - int i3 = strcspn(message, "<"); - int i4 = strcspn(message, ">"); - int mlen = strlen(message); + size_t i1 = strcspn(message, " "); + size_t i2 = strcspn(message, "/"); + size_t i3 = strcspn(message, "<"); + size_t i4 = strcspn(message, ">"); + size_t 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, " "); @@ -232,8 +225,8 @@ int get_wspr_channel_symbols(char *rawmessage, char *hashtab, unsigned char *sym ihash = nhash(callsign, strlen(callsign), (uint32_t)146); m = 128 * ihash + ntype + 64; - char grid6[6]; - memset(grid6, 32, sizeof(char) * 6); + char grid6[7]; + memset(grid6, 0, sizeof(char) * 7); j = strlen(grid); for (i = 0; i < j - 1; i++) { grid6[i] = grid[i + 1]; @@ -243,7 +236,7 @@ int get_wspr_channel_symbols(char *rawmessage, char *hashtab, unsigned char *sym } 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 + if (i2 == 0 || i2 > strlen(callsign)) return 0; // guards against pathological case powstr = strtok(NULL, " "); int power = atoi(powstr); if (power < 0) power = 0; @@ -283,8 +276,6 @@ int get_wspr_channel_symbols(char *rawmessage, char *hashtab, unsigned char *sym // make sure that the 11-byte data vector is unpackable // unpack it with the routine that the decoder will use and display // the result. let the operator decide whether it worked. - // char hashtab[32768][13]; - // memset(hashtab,0,sizeof(char)*32768*13); char *check_call_loc_pow, *check_callsign, *call, *loc, *pwr; check_call_loc_pow = malloc(sizeof(char) * 23); @@ -294,21 +285,23 @@ int get_wspr_channel_symbols(char *rawmessage, char *hashtab, unsigned char *sym 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); + + unpk_(check_data, hashtab, loctab, 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 char channelbits[nencoded]; - memset(channelbits, 0, sizeof(char) * nencoded); + unsigned int nbytes = 11; // The message with tail is packed into almost 11 bytes. + unsigned char channelbits[nbytes * 8 * 2]; /* 162 rounded up */ + memset(channelbits, 0, sizeof(char) * nbytes * 8 * 2); encode(channelbits, data, nbytes); interleave(channelbits); for (i = 0; i < 162; i++) { - symbols[i] = 2 * channelbits[i] + pr3[i]; + symbols[i] = 2 * channelbits[i] + pr3vector[i]; } - + free(check_call_loc_pow); + free(check_callsign); return 1; } + diff --git a/wsprd/wsprsim_utils.h b/wsprd/wsprsim_utils.h index e74be73..a6d208f 100644 --- a/wsprd/wsprsim_utils.h +++ b/wsprd/wsprsim_utils.h @@ -2,8 +2,8 @@ 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); +long unsigned int pack_grid4_power(char const *grid4, int power); +long unsigned int pack_call(char const *callsign); void pack_prefix(char *callsign, int32_t *n, int32_t *m, int32_t *nadd); void interleave(unsigned char *sym); -int get_wspr_channel_symbols(char *message, char *hashtab, unsigned char *symbols); +int get_wspr_channel_symbols(char *rawmessage, char *hashtab, char *loctab, unsigned char *symbols);