WIP chore: wsprd lib update partial

pull/111/head
Guenael 2021-12-22 00:43:49 -05:00
rodzic e54f2c865c
commit b248ceb121
11 zmienionych plików z 639 dodań i 419 usunięć

Wyświetl plik

@ -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!)

Wyświetl plik

@ -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

Wyświetl plik

@ -7,111 +7,138 @@
#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[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}};
#pragma GCC diagnostic pop

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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);

Wyświetl plik

@ -44,22 +44,26 @@
#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
#define NFILT 256
#define NSIG NSYM * NSPERSYM
/* Possible PATIENCE options: FFTW_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,82 +77,83 @@ 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;
unsigned char *symbols, float *f1, int ifmin, int ifmax, float fstep,
int *shift1, int lagmin, int lagmax, int lagstep,
float *drift1, int symfac, float *sync, int mode) {
/***********************************************************************
* 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. *
************************************************************************/
static float fplast = -10000.0;
float i0[NSYM], q0[NSYM],
i1[NSYM], q1[NSYM],
i2[NSYM], q2[NSYM],
float f0 = 0.0, fp, ss,
fbest = 0.0,
fsum = 0.0,
f2sum = 0.0,
fsymb[NSYM];
int best_shift = 0;
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],
float c0[NSPERSYM], s0[NSPERSYM],
c1[NSPERSYM], s1[NSPERSYM],
c2[NSPERSYM], s2[NSPERSYM],
c3[NSPERSYM], s3[NSPERSYM];
float dphi0, cdphi0, sdphi0,
dphi1, cdphi1, sdphi1,
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;
syncmax = -1e30;
if (mode == 0) {
ifmin = 0;
ifmax = 0;
fstep = 0.0;
f0 = *freq1;
f0 = *f1;
}
if (mode == 1) {
lagmin = *shift1;
lagmax = *shift1;
ifmin = -5;
ifmax = 5;
f0 = *freq1;
f0 = *f1;
}
if (mode == 2) {
lagmin = *shift1;
lagmax = *shift1;
ifmin = 0;
ifmax = 0;
f0 = *freq1;
f0 = *f1;
}
for (int32_t ifreq = ifmin; ifreq <= ifmax; ifreq++) {
f0 = *freq1 + ifreq * fstep;
for (lag = lagmin; lag <= lagmax; lag = lag + lagstep) {
for (int ifreq = ifmin; ifreq <= ifmax; ifreq++) {
f0 = *f1 + ifreq * fstep;
for (int 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 i = 0; i < NSYM; i++) {
fp = f0 + (*drift1 / 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);
dphi0 = TWOPIDT * (fp - DF15);
cdphi0 = cos(dphi0);
sdphi0 = sin(dphi0);
dphi1 = TWOPIDT * (fp - 0.5 * DF);
cdphi1 = cosf(dphi1);
sdphi1 = sinf(dphi1);
dphi1 = TWOPIDT * (fp - DF05);
cdphi1 = cos(dphi1);
sdphi1 = sin(dphi1);
dphi2 = TWOPIDT * (fp + 0.5 * DF);
cdphi2 = cosf(dphi2);
sdphi2 = sinf(dphi2);
dphi2 = TWOPIDT * (fp + DF05);
cdphi2 = cos(dphi2);
sdphi2 = sin(dphi2);
dphi3 = TWOPIDT * (fp + 1.5 * DF);
cdphi3 = cosf(dphi3);
sdphi3 = sinf(dphi3);
dphi3 = TWOPIDT * (fp + DF15);
cdphi3 = cos(dphi3);
sdphi3 = sin(dphi3);
c0[0] = 1;
s0[0] = 0;
@ -159,7 +164,7 @@ void sync_and_demodulate(float *id, float *qd, long np,
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;
@ -181,9 +186,9 @@ void sync_and_demodulate(float *id, float *qd, long np,
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];
@ -199,25 +204,25 @@ void sync_and_demodulate(float *id, float *qd, long np,
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);
p0 = sqrt(p0);
p1 = sqrt(p1);
p2 = sqrt(p2);
p3 = sqrt(p3);
totp = totp + p0 + p1 + p2 + p3;
cmet = (p1 + p3) - (p0 + p2);
ss = ss + cmet * (2 * pr3vector[i] - 1);
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;
}
@ -227,18 +232,18 @@ void sync_and_demodulate(float *id, float *qd, long np,
if (mode <= 1) { // Send best params back to caller
*sync = syncmax;
*shift1 = best_shift;
*freq1 = fbest;
*f1 = 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 = fsum + fsymb[i] / NSYM;
f2sum = f2sum + fsymb[i] * fsymb[i] / NSYM;
}
fac = sqrtf(f2sum - fsum * fsum);
for (int32_t i = 0; i < NSYM; i++) {
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 +254,196 @@ void sync_and_demodulate(float *id, float *qd, long np,
return;
}
void noncoherent_sequence_detection(float *id, float *qd, long np,
unsigned char *symbols, float *f1, int *shift1,
float *drift1, int symfac, int *nblocksize, int *bitmetric) {
/************************************************************************
* Noncoherent sequence detection for wspr. *
* Allowed block lengths are nblock=1,2,3,6, or 9 symbols. *
* Longer block lengths require longer channel coherence time. *
* The whole block is estimated at once. *
* nblock=1 corresponds to noncoherent detection of individual symbols *
* like the original wsprd symbol demodulator. *
************************************************************************/
static float fplast = -10000.0;
int i, j, k, lag, itone, ib, b, nblock, nseq, imask;
float xi[512], xq[512];
float is[4][NSYM], qs[4][NSYM],
cf[4][NSYM], sf[4][NSYM],
cm, sm, cmp, smp;
float p[512], fac, xm1, xm0;
float c0[NSPERSYM+1], s0[NSPERSYM+1],
c1[NSPERSYM+1], s1[NSPERSYM+1],
c2[NSPERSYM+1], s2[NSPERSYM+1],
c3[NSPERSYM+1], s3[NSPERSYM+1];
float dphi0, cdphi0, sdphi0,
dphi1, cdphi1, sdphi1,
dphi2, cdphi2, sdphi2,
dphi3, cdphi3, sdphi3;
float f0, fp, fsum = 0.0, f2sum = 0.0, fsymb[NSYM];
f0 = *f1;
lag = *shift1;
nblock = *nblocksize;
nseq = 1 << nblock;
int bitbybit = *bitmetric;
for (i = 0; i < NSYM; i++) {
fp = f0 + (*drift1 / 2.0) * ((float)i - (float)NBITS) / (float)NBITS;
if (i == 0 || (fp != fplast)) { // only calculate sin/cos if necessary
dphi0 = TWOPIDT * (fp - DF15);
cdphi0 = cos(dphi0);
sdphi0 = sin(dphi0);
dphi1 = TWOPIDT * (fp - DF05);
cdphi1 = cos(dphi1);
sdphi1 = sin(dphi1);
dphi2 = TWOPIDT * (fp + DF05);
cdphi2 = cos(dphi2);
sdphi2 = sin(dphi2);
dphi3 = TWOPIDT * (fp + DF15);
cdphi3 = cos(dphi3);
sdphi3 = sin(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;
for (j = 1; j < (NSPERSYM+1); 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;
s1[j] = c1[j - 1] * sdphi1 + s1[j - 1] * cdphi1;
c2[j] = c2[j - 1] * cdphi2 - s2[j - 1] * sdphi2;
s2[j] = c2[j - 1] * sdphi2 + s2[j - 1] * cdphi2;
c3[j] = c3[j - 1] * cdphi3 - s3[j - 1] * sdphi3;
s3[j] = c3[j - 1] * sdphi3 + s3[j - 1] * cdphi3;
}
fplast = fp;
}
cf[0][i] = c0[NSPERSYM];
sf[0][i] = s0[NSPERSYM];
cf[1][i] = c1[NSPERSYM];
sf[1][i] = s1[NSPERSYM];
cf[2][i] = c2[NSPERSYM];
sf[2][i] = s2[NSPERSYM];
cf[3][i] = c3[NSPERSYM];
sf[3][i] = s3[NSPERSYM];
is[0][i] = 0.0;
qs[0][i] = 0.0;
is[1][i] = 0.0;
qs[1][i] = 0.0;
is[2][i] = 0.0;
qs[2][i] = 0.0;
is[3][i] = 0.0;
qs[3][i] = 0.0;
for (j = 0; j < NSPERSYM; j++) {
k = lag + i * NSPERSYM + j;
if ((k > 0) && (k < np)) {
is[0][i] = is[0][i] + id[k] * c0[j] + qd[k] * s0[j];
qs[0][i] = qs[0][i] - id[k] * s0[j] + qd[k] * c0[j];
is[1][i] = is[1][i] + id[k] * c1[j] + qd[k] * s1[j];
qs[1][i] = qs[1][i] - id[k] * s1[j] + qd[k] * c1[j];
is[2][i] = is[2][i] + id[k] * c2[j] + qd[k] * s2[j];
qs[2][i] = qs[2][i] - id[k] * s2[j] + qd[k] * c2[j];
is[3][i] = is[3][i] + id[k] * c3[j] + qd[k] * s3[j];
qs[3][i] = qs[3][i] - id[k] * s3[j] + qd[k] * c3[j];
}
}
}
for (i = 0; i < NSYM; i = i + nblock) {
for (j = 0; j < nseq; j++) {
xi[j] = 0.0;
xq[j] = 0.0;
cm = 1;
sm = 0;
for (ib = 0; ib < nblock; ib++) {
b = (j & (1 << (nblock - 1 - ib))) >> (nblock - 1 - ib);
itone = pr3vector[i + ib] + 2 * b;
xi[j] = xi[j] + is[itone][i + ib] * cm + qs[itone][i + ib] * sm;
xq[j] = xq[j] + qs[itone][i + ib] * cm - is[itone][i + ib] * sm;
cmp = cf[itone][i + ib] * cm - sf[itone][i + ib] * sm;
smp = sf[itone][i + ib] * cm + cf[itone][i + ib] * sm;
cm = cmp;
sm = smp;
}
p[j] = xi[j] * xi[j] + xq[j] * xq[j];
p[j] = sqrt(p[j]);
}
for (ib = 0; ib < nblock; ib++) {
imask = 1 << (nblock - 1 - ib);
xm1 = 0.0;
xm0 = 0.0;
for (j = 0; j < nseq; j++) {
if ((j & imask) != 0) {
if (p[j] > xm1) xm1 = p[j];
}
if ((j & imask) == 0) {
if (p[j] > xm0) xm0 = p[j];
}
}
fsymb[i + ib] = xm1 - xm0;
if (bitbybit == 1) {
fsymb[i + ib] = fsymb[i + ib] / (xm1 > xm0 ? xm1 : xm0);
}
}
}
for (i = 0; i < NSYM; i++) { // Normalize the soft symbols
fsum = fsum + fsymb[i] / NSYM;
f2sum = f2sum + fsymb[i] * fsymb[i] / NSYM;
}
fac = sqrt(f2sum - fsum * fsum);
for (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;
symbols[i] = fsymb[i] + 128;
}
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;
float f0, int shift0, float drift0, unsigned char *channel_symbols) {
float c0[NSPERSYM], s0[NSPERSYM];
float dphi, cdphi, sdphi;
for (int32_t i = 0; i < NSYM; i++) {
for (int i = 0; i < NSYM; i++) {
float fp = f0 + ((float)drift0 / 2.0) * ((float)i - (float)NBITS) / (float)NBITS;
dphi = TWOPIDT * (fp + ((float)channel_symbols[i] - 1.5) * DF);
cdphi = cosf(dphi);
sdphi = sinf(dphi);
dphi = TWOPIDT * (fp + ((float)channel_symbols[i] - 1.5) * DF);
cdphi = cos(dphi);
sdphi = sin(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 = shift0 + 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];
@ -285,11 +451,12 @@ void subtract_signal(float *id, float *qd, long np,
}
// subtract the signal here.
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 = shift0 + 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 +466,24 @@ void subtract_signal(float *id, float *qd, long np,
return;
}
/******************************************************************************
Fully coherent signal subtraction
Subtract the coherent component of a signal
*******************************************************************************/
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};
void subtract_signal2(float *id,
float *qd,
long np,
float f0,
int shift0,
float drift0,
unsigned char *channel_symbols) {
float phi = 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) )
@ -319,72 +495,74 @@ void subtract_signal2(float *id, float *qd, long np,
// create reference wspr signal vector, centered on f0.
//
for (int32_t i = 0; i < NSYM; i++) {
cs = (float)channel_symbols[i];
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 + (drift0 / 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] = cos(phi); // cannot precompute sin/cos because dphi is changing
refq[ii] = sin(phi);
phi = phi + dphi;
}
}
float w[nfilt], norm = 0, partialsum[nfilt];
// 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] = sin(M_PI * (float)i / (float)(nfilt - 1));
norm = norm + w[i];
}
for (int i = 0; i < nfilt; i++) {
w[i] = w[i] / norm;
}
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 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];
for (int i = 0; i < NSYM * NSPERSYM; i++) {
int 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];
}
}
// 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));
norm = norm + w[i];
}
for (int32_t i = 0; i < NFILT; i++) {
w[i] = w[i] / norm;
}
for (int32_t i = 1; i < NFILT; i++) {
partialsum[i] = partialsum[i - 1] + w[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
// (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];
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 = shift0 + 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,6 +570,24 @@ void subtract_signal2(float *id, float *qd, long np,
return;
}
unsigned int count_hard_errors(unsigned char *symbols, unsigned char *channel_symbols) {
int i, is;
unsigned char cw[162];
unsigned int nerrors;
for (i = 0; i < 162; i++) {
cw[i] = channel_symbols[i] >= 2 ? 1 : 0;
}
deinterleave(cw);
nerrors = 0;
for (i = 0; i < 162; i++) {
is = symbols[i] > 127 ? 1 : 0;
nerrors = nerrors + (is == cw[i] ? 0 : 1);
}
return nerrors;
}
int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints,
struct decoder_options options, struct decoder_results *decodes,
int32_t *n_results) {
@ -405,6 +601,7 @@ int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints,
float sync0[200], sync1 = 0.0;
float snr0[200];
int32_t shift0[200], shift1 = 0;
int32_t ifmin, ifmax;
char callsign[13] = {0};
char call_loc_pow[23] = {0};
@ -420,6 +617,7 @@ int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints,
// Hash table
char hashtab[32768 * 13] = {0};
char loctab[32768 * 5] = {0};
int32_t nh;
// Parameters used for performance-tuning:
@ -441,7 +639,7 @@ int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints,
// 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));
}
@ -459,11 +657,11 @@ int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints,
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);
PLAN = fftwf_plan_dft_1d(512, fftin, fftout, FFTW_FORWARD, PATIENCE);
float ps[512][nffts];
float w[512];
for (i = 0; i < 512; i++) {
for (int i = 0; i < 512; i++) {
w[i] = sinf(0.006147931 * i);
}
@ -479,23 +677,23 @@ int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints,
}
// Main loop starts here
for (int32_t ipass = 0; ipass < options.npasses; ipass++) {
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;
memset(ps, 0.0, sizeof(float) * 512 * nffts);
for (i = 0; i < nffts; i++) {
for (int 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];
}
fftwf_execute(PLAN3);
fftwf_execute(PLAN);
for (j = 0; j < 512; j++) {
for (int j = 0; j < 512; j++) {
k = j + 256;
if (k > 511)
k = k - 512;
@ -505,7 +703,7 @@ 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 (int i = 0; i < nffts; i++) {
for (j = 0; j < 512; j++) {
psavg[j] = psavg[j] + ps[j][i];
}
@ -514,7 +712,7 @@ int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints,
// 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;
@ -524,7 +722,7 @@ int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints,
// 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,14 +738,14 @@ 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++) {
for (int i = 0; i < 200; i++) {
freq0[i] = 0.0;
snr0[i] = 0.0;
drift0[i] = 0.0;
@ -556,7 +754,7 @@ int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints,
}
int32_t npk = 0;
for (j = 1; j < 410; j++) {
for (int 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;
@ -572,7 +770,7 @@ int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints,
// Don't waste time on signals outside of the range [fmin,fmax].
i = 0;
for (j = 0; j < npk; j++) {
for (int j = 0; j < npk; j++) {
if (freq0[j] >= fmin && freq0[j] <= fmax) {
freq0[i] = freq0[j];
snr0[i] = snr0[j];
@ -582,9 +780,8 @@ int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints,
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 (int pass = 1; pass <= npk - 1; pass++) {
for (k = 0; k < npk - pass; k++) {
if (snr0[k] < snr0[k + 1]) {
tmp = snr0[k];
@ -610,31 +807,22 @@ 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 (int j = 0; j < npk; j++) { // For each candidate...
float smax = -1e30;
int if0 = freq0[j] / (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 (k = 0; k < NSYM; k++) { // Sum over symbols
ifd = ifr + ((float)k - (float)NBITS) / (float)NBITS * ((float)idrift) / DF;
kindex = k0 + 2 * k;
int ifd = ifr + ((float)k - (float)NBITS) / (float)NBITS * ((float)idrift) / DF;
int 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);
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;
@ -670,7 +858,7 @@ 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++) {
for (int j = 0; j < npk; j++) {
memset(symbols, 0, sizeof(char) * NBITS * 2);
memset(callsign, 0, sizeof(char) * 13);
memset(call_loc_pow, 0, sizeof(char) * 23);
@ -678,26 +866,31 @@ int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints,
memset(loc, 0, sizeof(char) * 7);
memset(pwr, 0, sizeof(char) * 3);
freq1 = freq0[j];
freq1 = freq0[j];
drift1 = drift0[j];
shift1 = shift0[j];
sync1 = sync0[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;
ifmin = 0;
ifmax = 0;
if (options.quickmode)
lagstep = 16;
sync_and_demodulate(idat, qdat, npoints, symbols, &freq1, fstep, &shift1,
sync_and_demodulate(idat, qdat, npoints, symbols, &freq1, ifmin, ifmax, fstep, &shift1,
lagmin, lagmax, lagstep, &drift1, symfac, &sync1, 0);
// Fine search for frequency peak (mode 1)
fstep = 0.1;
sync_and_demodulate(idat, qdat, npoints, symbols, &freq1, fstep, &shift1,
ifmin = 0;
ifmin = -2;
ifmax = 2;
sync_and_demodulate(idat, qdat, npoints, symbols, &freq1, ifmin, ifmax, fstep, &shift1,
lagmin, lagmax, lagstep, &drift1, symfac, &sync1, 1);
if (sync1 > minsync1) {
@ -717,7 +910,7 @@ int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints,
jiggered_shift = shift1 + ii;
// Use mode 2 to get soft-decision symbols
sync_and_demodulate(idat, qdat, npoints, symbols, &freq1, fstep,
sync_and_demodulate(idat, qdat, npoints, symbols, &freq1, ifmin, ifmax, fstep,
&jiggered_shift, lagmin, lagmax, lagstep, &drift1, symfac,
&sync1, 2);
sq = 0.0;
@ -748,12 +941,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)) {
//if (get_wspr_channel_symbols(call_loc_pow, hashtab, channel_symbols)) {
if (get_wspr_channel_symbols(call_loc_pow, hashtab, loctab, channel_symbols)) {
subtract_signal2(idat, qdat, npoints, freq1, shift1, drift1, channel_symbols);
} else {
break;
@ -816,9 +1009,7 @@ 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");

Wyświetl plik

@ -44,6 +44,14 @@ struct decoder_options {
uint32_t subtraction; // ''
};
struct cand {
float freq;
float snr;
int shift;
float drift;
float sync;
};
struct decoder_results {
double freq;
float sync;
@ -58,14 +66,44 @@ struct decoder_results {
uint32_t cycles;
};
// struct result {
// char date[7];
// char time[5];
// float sync;
// float snr;
// float dt;
// double freq;
// char message[23];
// float drift;
// unsigned int cycles;
// int jitter;
// int blocksize;
// unsigned int metric;
// int nhardmin;
// int ipass;
// int decodetype;
// };
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);
unsigned char *symbols, float *f1, int ifmin, int ifmax, float fstep,
int *shift1, int lagmin, int lagmax, int lagstep,
float *drift1, int symfac, float *sync, int mode);
void noncoherent_sequence_detection(float *id, float *qd, long np,
unsigned char *symbols, float *f1, int *shift1,
float *drift1, int symfac, int *nblocksize, int *bitmetric);
void subtract_signal(float *id, float *qd, long np,
float f0, int32_t shift0, float drift0, uint8_t *channel_symbols);
float f0, int shift0, float drift0, unsigned char *channel_symbols);
void subtract_signal2(float *id, float *qd, long np,
float f0, int32_t shift0, float drift0, uint8_t *channel_symbols);
float f0, int shift0, float drift0, unsigned char *channel_symbols);
unsigned int count_hard_errors(unsigned char *symbols, unsigned char *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);

Wyświetl plik

@ -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);
@ -302,36 +297,26 @@ 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);
int nu = ndbm % 10;
if (nu == 0 || nu == 3 || nu == 7) { // make sure power is OK
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);
} 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 && 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);
} 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;

Wyświetl plik

@ -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);

Wyświetl plik

@ -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,19 +160,20 @@ 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] = {
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};
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];
@ -193,16 +185,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 +224,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 +235,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 +275,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,13 +284,13 @@ 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);
@ -309,6 +299,8 @@ int get_wspr_channel_symbols(char *rawmessage, char *hashtab, unsigned char *sym
for (i = 0; i < 162; i++) {
symbols[i] = 2 * channelbits[i] + pr3[i];
}
free(check_call_loc_pow);
free(check_callsign);
return 1;
}

Wyświetl plik

@ -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);