mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-12-24 11:40:31 -05:00
Add code for QRA64 with fast fading.
git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@7295 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
5152778813
commit
8390bcd798
@ -494,6 +494,7 @@ set (qra_CSRCS
|
||||
lib/qra/qracodes/qra12_63_64_irr_b.c
|
||||
lib/qra/qracodes/qra13_64_64_irr_e.c
|
||||
lib/qra/qracodes/qracodes.c
|
||||
lib/qra/qracodes/normrnd.c
|
||||
)
|
||||
|
||||
set (wsjt_CSRCS
|
||||
|
327
lib/qra/qra64/fadampgauss.c
Normal file
327
lib/qra/qra64/fadampgauss.c
Normal file
@ -0,0 +1,327 @@
|
||||
/*
|
||||
fadampgauss.c
|
||||
Gaussian fading tables for QRA64 modes
|
||||
|
||||
(c) 2016 - Nico Palermo, IV3NWV
|
||||
|
||||
This file is part of the qracodes project, a Forward Error Control
|
||||
encoding/decoding package based on Q-ary RA (Repeat and Accumulate) LDPC codes.
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
qracodes is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
qracodes is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with qracodes source distribution.
|
||||
If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
*/
|
||||
static const int hlen_tab_gauss[64] = {
|
||||
2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 3, 3, 3, 3,
|
||||
4, 4, 4, 4, 5, 5, 5, 6,
|
||||
6, 6, 7, 7, 8, 8, 9, 10,
|
||||
10, 11, 12, 13, 14, 15, 17, 18,
|
||||
19, 21, 23, 25, 27, 29, 32, 34,
|
||||
37, 41, 44, 48, 52, 57, 62, 65
|
||||
};
|
||||
static const float hgauss1[2] = {
|
||||
0.1722f, 0.9540f
|
||||
};
|
||||
static const float hgauss2[2] = {
|
||||
0.1870f, 0.9463f
|
||||
};
|
||||
static const float hgauss3[2] = {
|
||||
0.2028f, 0.9374f
|
||||
};
|
||||
static const float hgauss4[2] = {
|
||||
0.2198f, 0.9273f
|
||||
};
|
||||
static const float hgauss5[2] = {
|
||||
0.2378f, 0.9158f
|
||||
};
|
||||
static const float hgauss6[2] = {
|
||||
0.2569f, 0.9030f
|
||||
};
|
||||
static const float hgauss7[2] = {
|
||||
0.2769f, 0.8887f
|
||||
};
|
||||
static const float hgauss8[2] = {
|
||||
0.2977f, 0.8730f
|
||||
};
|
||||
static const float hgauss9[2] = {
|
||||
0.3190f, 0.8559f
|
||||
};
|
||||
static const float hgauss10[2] = {
|
||||
0.3405f, 0.8374f
|
||||
};
|
||||
static const float hgauss11[2] = {
|
||||
0.3619f, 0.8177f
|
||||
};
|
||||
static const float hgauss12[2] = {
|
||||
0.3828f, 0.7970f
|
||||
};
|
||||
static const float hgauss13[2] = {
|
||||
0.4026f, 0.7755f
|
||||
};
|
||||
static const float hgauss14[2] = {
|
||||
0.4208f, 0.7533f
|
||||
};
|
||||
static const float hgauss15[2] = {
|
||||
0.4371f, 0.7307f
|
||||
};
|
||||
static const float hgauss16[2] = {
|
||||
0.4510f, 0.7078f
|
||||
};
|
||||
static const float hgauss17[3] = {
|
||||
0.1729f, 0.4621f, 0.6849f
|
||||
};
|
||||
static const float hgauss18[3] = {
|
||||
0.1920f, 0.4704f, 0.6620f
|
||||
};
|
||||
static const float hgauss19[3] = {
|
||||
0.2131f, 0.4757f, 0.6393f
|
||||
};
|
||||
static const float hgauss20[3] = {
|
||||
0.2350f, 0.4782f, 0.6170f
|
||||
};
|
||||
static const float hgauss21[3] = {
|
||||
0.2565f, 0.4779f, 0.5949f
|
||||
};
|
||||
static const float hgauss22[3] = {
|
||||
0.2767f, 0.4752f, 0.5733f
|
||||
};
|
||||
static const float hgauss23[3] = {
|
||||
0.2948f, 0.4703f, 0.5522f
|
||||
};
|
||||
static const float hgauss24[3] = {
|
||||
0.3102f, 0.4635f, 0.5316f
|
||||
};
|
||||
static const float hgauss25[4] = {
|
||||
0.1874f, 0.3226f, 0.4551f, 0.5115f
|
||||
};
|
||||
static const float hgauss26[4] = {
|
||||
0.2071f, 0.3319f, 0.4454f, 0.4919f
|
||||
};
|
||||
static const float hgauss27[4] = {
|
||||
0.2253f, 0.3383f, 0.4347f, 0.4730f
|
||||
};
|
||||
static const float hgauss28[4] = {
|
||||
0.2413f, 0.3419f, 0.4232f, 0.4546f
|
||||
};
|
||||
static const float hgauss29[5] = {
|
||||
0.1701f, 0.2546f, 0.3429f, 0.4110f, 0.4368f
|
||||
};
|
||||
static const float hgauss30[5] = {
|
||||
0.1874f, 0.2652f, 0.3417f, 0.3985f, 0.4196f
|
||||
};
|
||||
static const float hgauss31[5] = {
|
||||
0.2028f, 0.2729f, 0.3386f, 0.3857f, 0.4029f
|
||||
};
|
||||
static const float hgauss32[6] = {
|
||||
0.1569f, 0.2158f, 0.2780f, 0.3338f, 0.3728f, 0.3868f
|
||||
};
|
||||
static const float hgauss33[6] = {
|
||||
0.1723f, 0.2263f, 0.2807f, 0.3278f, 0.3599f, 0.3713f
|
||||
};
|
||||
static const float hgauss34[6] = {
|
||||
0.1857f, 0.2343f, 0.2812f, 0.3207f, 0.3471f, 0.3564f
|
||||
};
|
||||
static const float hgauss35[7] = {
|
||||
0.1550f, 0.1968f, 0.2398f, 0.2799f, 0.3128f, 0.3344f, 0.3420f
|
||||
};
|
||||
static const float hgauss36[7] = {
|
||||
0.1677f, 0.2055f, 0.2430f, 0.2770f, 0.3043f, 0.3220f, 0.3281f
|
||||
};
|
||||
static const float hgauss37[8] = {
|
||||
0.1456f, 0.1783f, 0.2118f, 0.2442f, 0.2728f, 0.2953f, 0.3098f, 0.3147f
|
||||
};
|
||||
static const float hgauss38[8] = {
|
||||
0.1572f, 0.1866f, 0.2160f, 0.2436f, 0.2675f, 0.2861f, 0.2979f, 0.3019f
|
||||
};
|
||||
static const float hgauss39[9] = {
|
||||
0.1410f, 0.1667f, 0.1928f, 0.2182f, 0.2416f, 0.2615f, 0.2767f, 0.2863f,
|
||||
0.2895f
|
||||
};
|
||||
static const float hgauss40[10] = {
|
||||
0.1288f, 0.1511f, 0.1741f, 0.1970f, 0.2187f, 0.2383f, 0.2547f, 0.2672f,
|
||||
0.2750f, 0.2776f
|
||||
};
|
||||
static const float hgauss41[10] = {
|
||||
0.1391f, 0.1592f, 0.1795f, 0.1992f, 0.2176f, 0.2340f, 0.2476f, 0.2578f,
|
||||
0.2641f, 0.2662f
|
||||
};
|
||||
static const float hgauss42[11] = {
|
||||
0.1298f, 0.1475f, 0.1654f, 0.1830f, 0.1999f, 0.2153f, 0.2289f, 0.2401f,
|
||||
0.2484f, 0.2535f, 0.2552f
|
||||
};
|
||||
static const float hgauss43[12] = {
|
||||
0.1227f, 0.1382f, 0.1540f, 0.1696f, 0.1848f, 0.1991f, 0.2120f, 0.2232f,
|
||||
0.2324f, 0.2391f, 0.2433f, 0.2447f
|
||||
};
|
||||
static const float hgauss44[13] = {
|
||||
0.1173f, 0.1309f, 0.1448f, 0.1587f, 0.1722f, 0.1851f, 0.1971f, 0.2078f,
|
||||
0.2171f, 0.2246f, 0.2301f, 0.2334f, 0.2346f
|
||||
};
|
||||
static const float hgauss45[14] = {
|
||||
0.1132f, 0.1253f, 0.1375f, 0.1497f, 0.1617f, 0.1732f, 0.1841f, 0.1941f,
|
||||
0.2030f, 0.2106f, 0.2167f, 0.2212f, 0.2239f, 0.2248f
|
||||
};
|
||||
static const float hgauss46[15] = {
|
||||
0.1102f, 0.1208f, 0.1315f, 0.1423f, 0.1529f, 0.1632f, 0.1730f, 0.1821f,
|
||||
0.1904f, 0.1978f, 0.2040f, 0.2089f, 0.2126f, 0.2148f, 0.2155f
|
||||
};
|
||||
static const float hgauss47[17] = {
|
||||
0.0987f, 0.1079f, 0.1173f, 0.1267f, 0.1362f, 0.1455f, 0.1546f, 0.1634f,
|
||||
0.1716f, 0.1792f, 0.1861f, 0.1921f, 0.1972f, 0.2012f, 0.2042f, 0.2059f,
|
||||
0.2065f
|
||||
};
|
||||
static const float hgauss48[18] = {
|
||||
0.0980f, 0.1062f, 0.1145f, 0.1228f, 0.1311f, 0.1393f, 0.1474f, 0.1551f,
|
||||
0.1624f, 0.1693f, 0.1756f, 0.1813f, 0.1862f, 0.1904f, 0.1936f, 0.1960f,
|
||||
0.1975f, 0.1979f
|
||||
};
|
||||
static const float hgauss49[19] = {
|
||||
0.0976f, 0.1049f, 0.1122f, 0.1195f, 0.1268f, 0.1341f, 0.1411f, 0.1479f,
|
||||
0.1544f, 0.1606f, 0.1663f, 0.1715f, 0.1762f, 0.1802f, 0.1836f, 0.1862f,
|
||||
0.1881f, 0.1893f, 0.1897f
|
||||
};
|
||||
static const float hgauss50[21] = {
|
||||
0.0911f, 0.0974f, 0.1038f, 0.1103f, 0.1167f, 0.1232f, 0.1295f, 0.1357f,
|
||||
0.1417f, 0.1474f, 0.1529f, 0.1580f, 0.1627f, 0.1670f, 0.1708f, 0.1741f,
|
||||
0.1768f, 0.1790f, 0.1805f, 0.1815f, 0.1818f
|
||||
};
|
||||
static const float hgauss51[23] = {
|
||||
0.0861f, 0.0916f, 0.0973f, 0.1029f, 0.1086f, 0.1143f, 0.1199f, 0.1255f,
|
||||
0.1309f, 0.1361f, 0.1412f, 0.1460f, 0.1505f, 0.1548f, 0.1587f, 0.1622f,
|
||||
0.1653f, 0.1679f, 0.1702f, 0.1719f, 0.1732f, 0.1739f, 0.1742f
|
||||
};
|
||||
static const float hgauss52[25] = {
|
||||
0.0823f, 0.0872f, 0.0922f, 0.0971f, 0.1021f, 0.1071f, 0.1121f, 0.1170f,
|
||||
0.1219f, 0.1266f, 0.1312f, 0.1356f, 0.1398f, 0.1438f, 0.1476f, 0.1511f,
|
||||
0.1543f, 0.1572f, 0.1597f, 0.1619f, 0.1637f, 0.1651f, 0.1661f, 0.1667f,
|
||||
0.1669f
|
||||
};
|
||||
static const float hgauss53[27] = {
|
||||
0.0795f, 0.0838f, 0.0882f, 0.0925f, 0.0969f, 0.1013f, 0.1057f, 0.1101f,
|
||||
0.1144f, 0.1186f, 0.1227f, 0.1267f, 0.1306f, 0.1343f, 0.1378f, 0.1411f,
|
||||
0.1442f, 0.1471f, 0.1497f, 0.1520f, 0.1541f, 0.1558f, 0.1573f, 0.1585f,
|
||||
0.1593f, 0.1598f, 0.1599f
|
||||
};
|
||||
static const float hgauss54[29] = {
|
||||
0.0774f, 0.0812f, 0.0850f, 0.0889f, 0.0928f, 0.0966f, 0.1005f, 0.1043f,
|
||||
0.1081f, 0.1119f, 0.1155f, 0.1191f, 0.1226f, 0.1259f, 0.1292f, 0.1322f,
|
||||
0.1351f, 0.1379f, 0.1404f, 0.1428f, 0.1449f, 0.1468f, 0.1485f, 0.1499f,
|
||||
0.1511f, 0.1520f, 0.1527f, 0.1531f, 0.1532f
|
||||
};
|
||||
static const float hgauss55[32] = {
|
||||
0.0726f, 0.0759f, 0.0792f, 0.0826f, 0.0860f, 0.0894f, 0.0928f, 0.0962f,
|
||||
0.0996f, 0.1029f, 0.1062f, 0.1094f, 0.1126f, 0.1157f, 0.1187f, 0.1217f,
|
||||
0.1245f, 0.1271f, 0.1297f, 0.1321f, 0.1343f, 0.1364f, 0.1383f, 0.1401f,
|
||||
0.1416f, 0.1430f, 0.1442f, 0.1451f, 0.1459f, 0.1464f, 0.1467f, 0.1468f
|
||||
};
|
||||
static const float hgauss56[34] = {
|
||||
0.0718f, 0.0747f, 0.0777f, 0.0807f, 0.0836f, 0.0866f, 0.0896f, 0.0926f,
|
||||
0.0956f, 0.0985f, 0.1014f, 0.1043f, 0.1071f, 0.1098f, 0.1125f, 0.1151f,
|
||||
0.1176f, 0.1201f, 0.1224f, 0.1246f, 0.1267f, 0.1287f, 0.1305f, 0.1322f,
|
||||
0.1338f, 0.1352f, 0.1365f, 0.1376f, 0.1385f, 0.1393f, 0.1399f, 0.1403f,
|
||||
0.1406f, 0.1407f
|
||||
};
|
||||
static const float hgauss57[37] = {
|
||||
0.0687f, 0.0712f, 0.0738f, 0.0765f, 0.0791f, 0.0817f, 0.0843f, 0.0870f,
|
||||
0.0896f, 0.0922f, 0.0948f, 0.0973f, 0.0998f, 0.1023f, 0.1047f, 0.1071f,
|
||||
0.1094f, 0.1117f, 0.1138f, 0.1159f, 0.1179f, 0.1199f, 0.1217f, 0.1234f,
|
||||
0.1250f, 0.1265f, 0.1279f, 0.1292f, 0.1304f, 0.1314f, 0.1323f, 0.1330f,
|
||||
0.1337f, 0.1341f, 0.1345f, 0.1347f, 0.1348f
|
||||
};
|
||||
static const float hgauss58[41] = {
|
||||
0.0640f, 0.0663f, 0.0686f, 0.0709f, 0.0732f, 0.0755f, 0.0778f, 0.0801f,
|
||||
0.0824f, 0.0847f, 0.0870f, 0.0893f, 0.0915f, 0.0938f, 0.0960f, 0.0982f,
|
||||
0.1003f, 0.1024f, 0.1044f, 0.1064f, 0.1083f, 0.1102f, 0.1120f, 0.1137f,
|
||||
0.1154f, 0.1170f, 0.1185f, 0.1199f, 0.1212f, 0.1224f, 0.1236f, 0.1246f,
|
||||
0.1255f, 0.1264f, 0.1271f, 0.1277f, 0.1282f, 0.1286f, 0.1289f, 0.1291f,
|
||||
0.1291f
|
||||
};
|
||||
static const float hgauss59[44] = {
|
||||
0.0625f, 0.0645f, 0.0665f, 0.0685f, 0.0705f, 0.0726f, 0.0746f, 0.0767f,
|
||||
0.0787f, 0.0807f, 0.0827f, 0.0847f, 0.0867f, 0.0887f, 0.0907f, 0.0926f,
|
||||
0.0945f, 0.0964f, 0.0982f, 0.1000f, 0.1017f, 0.1034f, 0.1051f, 0.1067f,
|
||||
0.1083f, 0.1097f, 0.1112f, 0.1125f, 0.1138f, 0.1151f, 0.1162f, 0.1173f,
|
||||
0.1183f, 0.1192f, 0.1201f, 0.1208f, 0.1215f, 0.1221f, 0.1226f, 0.1230f,
|
||||
0.1233f, 0.1235f, 0.1237f, 0.1237f
|
||||
};
|
||||
static const float hgauss60[48] = {
|
||||
0.0596f, 0.0614f, 0.0631f, 0.0649f, 0.0667f, 0.0685f, 0.0703f, 0.0721f,
|
||||
0.0738f, 0.0756f, 0.0774f, 0.0792f, 0.0810f, 0.0827f, 0.0845f, 0.0862f,
|
||||
0.0879f, 0.0896f, 0.0912f, 0.0929f, 0.0945f, 0.0960f, 0.0976f, 0.0991f,
|
||||
0.1005f, 0.1019f, 0.1033f, 0.1046f, 0.1059f, 0.1071f, 0.1083f, 0.1094f,
|
||||
0.1105f, 0.1115f, 0.1124f, 0.1133f, 0.1141f, 0.1149f, 0.1156f, 0.1162f,
|
||||
0.1167f, 0.1172f, 0.1176f, 0.1179f, 0.1182f, 0.1184f, 0.1185f, 0.1185f
|
||||
};
|
||||
static const float hgauss61[52] = {
|
||||
0.0575f, 0.0590f, 0.0606f, 0.0621f, 0.0637f, 0.0652f, 0.0668f, 0.0684f,
|
||||
0.0700f, 0.0715f, 0.0731f, 0.0747f, 0.0762f, 0.0778f, 0.0793f, 0.0809f,
|
||||
0.0824f, 0.0839f, 0.0854f, 0.0868f, 0.0883f, 0.0897f, 0.0911f, 0.0925f,
|
||||
0.0938f, 0.0951f, 0.0964f, 0.0976f, 0.0988f, 0.1000f, 0.1011f, 0.1022f,
|
||||
0.1033f, 0.1043f, 0.1053f, 0.1062f, 0.1070f, 0.1079f, 0.1086f, 0.1093f,
|
||||
0.1100f, 0.1106f, 0.1112f, 0.1116f, 0.1121f, 0.1125f, 0.1128f, 0.1131f,
|
||||
0.1133f, 0.1134f, 0.1135f, 0.1135f
|
||||
};
|
||||
static const float hgauss62[57] = {
|
||||
0.0545f, 0.0558f, 0.0572f, 0.0586f, 0.0599f, 0.0613f, 0.0627f, 0.0641f,
|
||||
0.0654f, 0.0668f, 0.0682f, 0.0696f, 0.0710f, 0.0723f, 0.0737f, 0.0751f,
|
||||
0.0764f, 0.0778f, 0.0791f, 0.0804f, 0.0817f, 0.0830f, 0.0843f, 0.0855f,
|
||||
0.0868f, 0.0880f, 0.0892f, 0.0903f, 0.0915f, 0.0926f, 0.0937f, 0.0948f,
|
||||
0.0958f, 0.0968f, 0.0977f, 0.0987f, 0.0996f, 0.1004f, 0.1013f, 0.1020f,
|
||||
0.1028f, 0.1035f, 0.1042f, 0.1048f, 0.1054f, 0.1059f, 0.1064f, 0.1068f,
|
||||
0.1072f, 0.1076f, 0.1079f, 0.1082f, 0.1084f, 0.1085f, 0.1087f, 0.1087f,
|
||||
0.1088f
|
||||
};
|
||||
static const float hgauss63[62] = {
|
||||
0.0522f, 0.0534f, 0.0546f, 0.0558f, 0.0570f, 0.0582f, 0.0594f, 0.0606f,
|
||||
0.0619f, 0.0631f, 0.0643f, 0.0655f, 0.0667f, 0.0679f, 0.0691f, 0.0703f,
|
||||
0.0715f, 0.0727f, 0.0739f, 0.0751f, 0.0763f, 0.0774f, 0.0786f, 0.0797f,
|
||||
0.0808f, 0.0819f, 0.0830f, 0.0841f, 0.0851f, 0.0861f, 0.0872f, 0.0882f,
|
||||
0.0891f, 0.0901f, 0.0910f, 0.0919f, 0.0928f, 0.0936f, 0.0944f, 0.0952f,
|
||||
0.0960f, 0.0967f, 0.0974f, 0.0981f, 0.0987f, 0.0994f, 0.0999f, 0.1005f,
|
||||
0.1010f, 0.1014f, 0.1019f, 0.1023f, 0.1026f, 0.1030f, 0.1033f, 0.1035f,
|
||||
0.1037f, 0.1039f, 0.1040f, 0.1041f, 0.1042f, 0.1042f
|
||||
};
|
||||
static const float hgauss64[65] = {
|
||||
0.0526f, 0.0537f, 0.0547f, 0.0558f, 0.0569f, 0.0579f, 0.0590f, 0.0601f,
|
||||
0.0611f, 0.0622f, 0.0633f, 0.0643f, 0.0654f, 0.0665f, 0.0675f, 0.0686f,
|
||||
0.0696f, 0.0707f, 0.0717f, 0.0727f, 0.0737f, 0.0748f, 0.0758f, 0.0767f,
|
||||
0.0777f, 0.0787f, 0.0796f, 0.0806f, 0.0815f, 0.0824f, 0.0833f, 0.0842f,
|
||||
0.0850f, 0.0859f, 0.0867f, 0.0875f, 0.0883f, 0.0891f, 0.0898f, 0.0905f,
|
||||
0.0912f, 0.0919f, 0.0925f, 0.0932f, 0.0938f, 0.0943f, 0.0949f, 0.0954f,
|
||||
0.0959f, 0.0964f, 0.0968f, 0.0972f, 0.0976f, 0.0979f, 0.0983f, 0.0986f,
|
||||
0.0988f, 0.0991f, 0.0993f, 0.0994f, 0.0996f, 0.0997f, 0.0998f, 0.0998f,
|
||||
0.0998f
|
||||
};
|
||||
static const float *hptr_tab_gauss[64] = {
|
||||
hgauss1, hgauss2, hgauss3, hgauss4,
|
||||
hgauss5, hgauss6, hgauss7, hgauss8,
|
||||
hgauss9, hgauss10, hgauss11, hgauss12,
|
||||
hgauss13, hgauss14, hgauss15, hgauss16,
|
||||
hgauss17, hgauss18, hgauss19, hgauss20,
|
||||
hgauss21, hgauss22, hgauss23, hgauss24,
|
||||
hgauss25, hgauss26, hgauss27, hgauss28,
|
||||
hgauss29, hgauss30, hgauss31, hgauss32,
|
||||
hgauss33, hgauss34, hgauss35, hgauss36,
|
||||
hgauss37, hgauss38, hgauss39, hgauss40,
|
||||
hgauss41, hgauss42, hgauss43, hgauss44,
|
||||
hgauss45, hgauss46, hgauss47, hgauss48,
|
||||
hgauss49, hgauss50, hgauss51, hgauss52,
|
||||
hgauss53, hgauss54, hgauss55, hgauss56,
|
||||
hgauss57, hgauss58, hgauss59, hgauss60,
|
||||
hgauss61, hgauss62, hgauss63, hgauss64
|
||||
};
|
329
lib/qra/qra64/fadamplorentz.c
Normal file
329
lib/qra/qra64/fadamplorentz.c
Normal file
@ -0,0 +1,329 @@
|
||||
/*
|
||||
fadamplorentz.c
|
||||
Lorentz fading tables for QRA64 modes
|
||||
|
||||
(c) 2016 - Nico Palermo, IV3NWV
|
||||
|
||||
This file is part of the qracodes project, a Forward Error Control
|
||||
encoding/decoding package based on Q-ary RA (Repeat and Accumulate) LDPC codes.
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
qracodes is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
qracodes is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with qracodes source distribution.
|
||||
If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static const int hlen_tab_lorentz[64] = {
|
||||
2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 3, 3,
|
||||
3, 3, 3, 3, 3, 4, 4, 4,
|
||||
4, 4, 5, 5, 5, 5, 6, 6,
|
||||
7, 7, 7, 8, 8, 9, 10, 10,
|
||||
11, 12, 13, 14, 15, 16, 17, 19,
|
||||
20, 22, 23, 25, 27, 30, 32, 35,
|
||||
38, 41, 45, 49, 53, 57, 62, 65
|
||||
};
|
||||
static const float hlorentz1[2] = {
|
||||
0.1464f, 0.9543f
|
||||
};
|
||||
static const float hlorentz2[2] = {
|
||||
0.1563f, 0.9503f
|
||||
};
|
||||
static const float hlorentz3[2] = {
|
||||
0.1672f, 0.9461f
|
||||
};
|
||||
static const float hlorentz4[2] = {
|
||||
0.1773f, 0.9415f
|
||||
};
|
||||
static const float hlorentz5[2] = {
|
||||
0.1868f, 0.9367f
|
||||
};
|
||||
static const float hlorentz6[2] = {
|
||||
0.1970f, 0.9314f
|
||||
};
|
||||
static const float hlorentz7[2] = {
|
||||
0.2063f, 0.9258f
|
||||
};
|
||||
static const float hlorentz8[2] = {
|
||||
0.2151f, 0.9197f
|
||||
};
|
||||
static const float hlorentz9[2] = {
|
||||
0.2236f, 0.9132f
|
||||
};
|
||||
static const float hlorentz10[2] = {
|
||||
0.2320f, 0.9061f
|
||||
};
|
||||
static const float hlorentz11[2] = {
|
||||
0.2406f, 0.8986f
|
||||
};
|
||||
static const float hlorentz12[2] = {
|
||||
0.2494f, 0.8905f
|
||||
};
|
||||
static const float hlorentz13[2] = {
|
||||
0.2584f, 0.8819f
|
||||
};
|
||||
static const float hlorentz14[2] = {
|
||||
0.2674f, 0.8727f
|
||||
};
|
||||
static const float hlorentz15[3] = {
|
||||
0.1400f, 0.2765f, 0.8629f
|
||||
};
|
||||
static const float hlorentz16[3] = {
|
||||
0.1451f, 0.2857f, 0.8525f
|
||||
};
|
||||
static const float hlorentz17[3] = {
|
||||
0.1504f, 0.2949f, 0.8414f
|
||||
};
|
||||
static const float hlorentz18[3] = {
|
||||
0.1557f, 0.3041f, 0.8298f
|
||||
};
|
||||
static const float hlorentz19[3] = {
|
||||
0.1611f, 0.3133f, 0.8174f
|
||||
};
|
||||
static const float hlorentz20[3] = {
|
||||
0.1666f, 0.3223f, 0.8045f
|
||||
};
|
||||
static const float hlorentz21[3] = {
|
||||
0.1721f, 0.3312f, 0.7909f
|
||||
};
|
||||
static const float hlorentz22[4] = {
|
||||
0.1195f, 0.1778f, 0.3399f, 0.7766f
|
||||
};
|
||||
static const float hlorentz23[4] = {
|
||||
0.1235f, 0.1835f, 0.3483f, 0.7618f
|
||||
};
|
||||
static const float hlorentz24[4] = {
|
||||
0.1277f, 0.1893f, 0.3564f, 0.7463f
|
||||
};
|
||||
static const float hlorentz25[4] = {
|
||||
0.1319f, 0.1952f, 0.3641f, 0.7303f
|
||||
};
|
||||
static const float hlorentz26[4] = {
|
||||
0.1362f, 0.2011f, 0.3712f, 0.7138f
|
||||
};
|
||||
static const float hlorentz27[5] = {
|
||||
0.1062f, 0.1407f, 0.2071f, 0.3779f, 0.6967f
|
||||
};
|
||||
static const float hlorentz28[5] = {
|
||||
0.1097f, 0.1452f, 0.2132f, 0.3839f, 0.6793f
|
||||
};
|
||||
static const float hlorentz29[5] = {
|
||||
0.1134f, 0.1499f, 0.2193f, 0.3891f, 0.6615f
|
||||
};
|
||||
static const float hlorentz30[5] = {
|
||||
0.1172f, 0.1546f, 0.2254f, 0.3936f, 0.6434f
|
||||
};
|
||||
static const float hlorentz31[6] = {
|
||||
0.0974f, 0.1211f, 0.1595f, 0.2314f, 0.3973f, 0.6251f
|
||||
};
|
||||
static const float hlorentz32[6] = {
|
||||
0.1007f, 0.1251f, 0.1645f, 0.2374f, 0.4000f, 0.6066f
|
||||
};
|
||||
static const float hlorentz33[7] = {
|
||||
0.0872f, 0.1042f, 0.1292f, 0.1695f, 0.2434f, 0.4017f, 0.5880f
|
||||
};
|
||||
static const float hlorentz34[7] = {
|
||||
0.0902f, 0.1077f, 0.1335f, 0.1747f, 0.2491f, 0.4025f, 0.5694f
|
||||
};
|
||||
static const float hlorentz35[7] = {
|
||||
0.0934f, 0.1114f, 0.1379f, 0.1799f, 0.2547f, 0.4022f, 0.5509f
|
||||
};
|
||||
static const float hlorentz36[8] = {
|
||||
0.0832f, 0.0967f, 0.1152f, 0.1423f, 0.1851f, 0.2600f, 0.4008f, 0.5325f
|
||||
};
|
||||
static const float hlorentz37[8] = {
|
||||
0.0862f, 0.1001f, 0.1192f, 0.1469f, 0.1903f, 0.2649f, 0.3985f, 0.5143f
|
||||
};
|
||||
static const float hlorentz38[9] = {
|
||||
0.0784f, 0.0893f, 0.1036f, 0.1232f, 0.1515f, 0.1955f, 0.2694f, 0.3950f,
|
||||
0.4964f
|
||||
};
|
||||
static const float hlorentz39[10] = {
|
||||
0.0724f, 0.0813f, 0.0925f, 0.1072f, 0.1273f, 0.1562f, 0.2005f, 0.2733f,
|
||||
0.3906f, 0.4787f
|
||||
};
|
||||
static const float hlorentz40[10] = {
|
||||
0.0751f, 0.0842f, 0.0958f, 0.1109f, 0.1315f, 0.1609f, 0.2054f, 0.2767f,
|
||||
0.3853f, 0.4614f
|
||||
};
|
||||
static const float hlorentz41[11] = {
|
||||
0.0703f, 0.0779f, 0.0873f, 0.0992f, 0.1148f, 0.1358f, 0.1656f, 0.2101f,
|
||||
0.2794f, 0.3790f, 0.4444f
|
||||
};
|
||||
static const float hlorentz42[12] = {
|
||||
0.0665f, 0.0730f, 0.0808f, 0.0905f, 0.1027f, 0.1187f, 0.1401f, 0.1702f,
|
||||
0.2145f, 0.2813f, 0.3720f, 0.4278f
|
||||
};
|
||||
static const float hlorentz43[13] = {
|
||||
0.0634f, 0.0690f, 0.0757f, 0.0838f, 0.0938f, 0.1063f, 0.1226f, 0.1444f,
|
||||
0.1747f, 0.2185f, 0.2824f, 0.3643f, 0.4117f
|
||||
};
|
||||
static const float hlorentz44[14] = {
|
||||
0.0609f, 0.0658f, 0.0716f, 0.0785f, 0.0869f, 0.0971f, 0.1100f, 0.1266f,
|
||||
0.1487f, 0.1791f, 0.2220f, 0.2826f, 0.3559f, 0.3960f
|
||||
};
|
||||
static const float hlorentz45[15] = {
|
||||
0.0588f, 0.0632f, 0.0683f, 0.0743f, 0.0814f, 0.0900f, 0.1005f, 0.1137f,
|
||||
0.1306f, 0.1529f, 0.1831f, 0.2250f, 0.2820f, 0.3470f, 0.3808f
|
||||
};
|
||||
static const float hlorentz46[16] = {
|
||||
0.0571f, 0.0611f, 0.0657f, 0.0709f, 0.0771f, 0.0844f, 0.0932f, 0.1040f,
|
||||
0.1175f, 0.1346f, 0.1570f, 0.1869f, 0.2274f, 0.2804f, 0.3377f, 0.3660f
|
||||
};
|
||||
static const float hlorentz47[17] = {
|
||||
0.0557f, 0.0594f, 0.0635f, 0.0682f, 0.0736f, 0.0800f, 0.0875f, 0.0965f,
|
||||
0.1076f, 0.1212f, 0.1385f, 0.1609f, 0.1903f, 0.2292f, 0.2781f, 0.3281f,
|
||||
0.3517f
|
||||
};
|
||||
static const float hlorentz48[19] = {
|
||||
0.0516f, 0.0546f, 0.0579f, 0.0617f, 0.0659f, 0.0708f, 0.0764f, 0.0829f,
|
||||
0.0906f, 0.0999f, 0.1111f, 0.1249f, 0.1423f, 0.1645f, 0.1933f, 0.2302f,
|
||||
0.2748f, 0.3182f, 0.3379f
|
||||
};
|
||||
static const float hlorentz49[20] = {
|
||||
0.0509f, 0.0537f, 0.0567f, 0.0602f, 0.0640f, 0.0684f, 0.0734f, 0.0792f,
|
||||
0.0859f, 0.0938f, 0.1032f, 0.1146f, 0.1286f, 0.1460f, 0.1679f, 0.1957f,
|
||||
0.2305f, 0.2709f, 0.3082f, 0.3245f
|
||||
};
|
||||
static const float hlorentz50[22] = {
|
||||
0.0480f, 0.0504f, 0.0529f, 0.0558f, 0.0589f, 0.0625f, 0.0665f, 0.0710f,
|
||||
0.0761f, 0.0821f, 0.0889f, 0.0970f, 0.1066f, 0.1181f, 0.1321f, 0.1494f,
|
||||
0.1709f, 0.1976f, 0.2300f, 0.2662f, 0.2981f, 0.3115f
|
||||
};
|
||||
static const float hlorentz51[23] = {
|
||||
0.0477f, 0.0499f, 0.0523f, 0.0550f, 0.0580f, 0.0612f, 0.0649f, 0.0690f,
|
||||
0.0736f, 0.0789f, 0.0850f, 0.0920f, 0.1002f, 0.1099f, 0.1215f, 0.1355f,
|
||||
0.1526f, 0.1735f, 0.1989f, 0.2288f, 0.2609f, 0.2880f, 0.2991f
|
||||
};
|
||||
static const float hlorentz52[25] = {
|
||||
0.0456f, 0.0475f, 0.0496f, 0.0519f, 0.0544f, 0.0572f, 0.0602f, 0.0636f,
|
||||
0.0673f, 0.0715f, 0.0763f, 0.0817f, 0.0879f, 0.0951f, 0.1034f, 0.1132f,
|
||||
0.1248f, 0.1387f, 0.1554f, 0.1755f, 0.1995f, 0.2268f, 0.2550f, 0.2779f,
|
||||
0.2870f
|
||||
};
|
||||
static const float hlorentz53[27] = {
|
||||
0.0438f, 0.0456f, 0.0474f, 0.0494f, 0.0516f, 0.0539f, 0.0565f, 0.0594f,
|
||||
0.0625f, 0.0660f, 0.0698f, 0.0742f, 0.0790f, 0.0846f, 0.0909f, 0.0981f,
|
||||
0.1065f, 0.1164f, 0.1279f, 0.1416f, 0.1579f, 0.1771f, 0.1994f, 0.2242f,
|
||||
0.2487f, 0.2680f, 0.2754f
|
||||
};
|
||||
static const float hlorentz54[30] = {
|
||||
0.0410f, 0.0424f, 0.0440f, 0.0456f, 0.0474f, 0.0493f, 0.0513f, 0.0536f,
|
||||
0.0560f, 0.0587f, 0.0616f, 0.0648f, 0.0684f, 0.0724f, 0.0768f, 0.0818f,
|
||||
0.0874f, 0.0938f, 0.1011f, 0.1096f, 0.1194f, 0.1308f, 0.1442f, 0.1599f,
|
||||
0.1781f, 0.1987f, 0.2208f, 0.2421f, 0.2582f, 0.2643f
|
||||
};
|
||||
static const float hlorentz55[32] = {
|
||||
0.0400f, 0.0413f, 0.0427f, 0.0441f, 0.0457f, 0.0474f, 0.0492f, 0.0512f,
|
||||
0.0533f, 0.0557f, 0.0582f, 0.0609f, 0.0639f, 0.0672f, 0.0709f, 0.0749f,
|
||||
0.0795f, 0.0845f, 0.0902f, 0.0967f, 0.1041f, 0.1125f, 0.1222f, 0.1334f,
|
||||
0.1464f, 0.1614f, 0.1785f, 0.1973f, 0.2169f, 0.2351f, 0.2485f, 0.2535f
|
||||
};
|
||||
static const float hlorentz56[35] = {
|
||||
0.0380f, 0.0391f, 0.0403f, 0.0416f, 0.0429f, 0.0444f, 0.0459f, 0.0475f,
|
||||
0.0493f, 0.0512f, 0.0532f, 0.0554f, 0.0578f, 0.0604f, 0.0632f, 0.0663f,
|
||||
0.0697f, 0.0734f, 0.0775f, 0.0821f, 0.0873f, 0.0930f, 0.0995f, 0.1069f,
|
||||
0.1153f, 0.1248f, 0.1358f, 0.1483f, 0.1624f, 0.1782f, 0.1952f, 0.2125f,
|
||||
0.2280f, 0.2391f, 0.2432f
|
||||
};
|
||||
static const float hlorentz57[38] = {
|
||||
0.0364f, 0.0374f, 0.0384f, 0.0395f, 0.0407f, 0.0419f, 0.0432f, 0.0446f,
|
||||
0.0461f, 0.0477f, 0.0494f, 0.0512f, 0.0531f, 0.0552f, 0.0575f, 0.0599f,
|
||||
0.0626f, 0.0655f, 0.0686f, 0.0721f, 0.0759f, 0.0801f, 0.0848f, 0.0899f,
|
||||
0.0957f, 0.1022f, 0.1095f, 0.1178f, 0.1271f, 0.1377f, 0.1496f, 0.1629f,
|
||||
0.1774f, 0.1926f, 0.2076f, 0.2207f, 0.2299f, 0.2332f
|
||||
};
|
||||
static const float hlorentz58[41] = {
|
||||
0.0351f, 0.0360f, 0.0369f, 0.0379f, 0.0389f, 0.0400f, 0.0411f, 0.0423f,
|
||||
0.0436f, 0.0450f, 0.0464f, 0.0479f, 0.0496f, 0.0513f, 0.0532f, 0.0552f,
|
||||
0.0573f, 0.0596f, 0.0621f, 0.0648f, 0.0678f, 0.0710f, 0.0745f, 0.0784f,
|
||||
0.0826f, 0.0873f, 0.0925f, 0.0983f, 0.1048f, 0.1120f, 0.1201f, 0.1291f,
|
||||
0.1392f, 0.1505f, 0.1628f, 0.1759f, 0.1894f, 0.2023f, 0.2134f, 0.2209f,
|
||||
0.2237f
|
||||
};
|
||||
static const float hlorentz59[45] = {
|
||||
0.0333f, 0.0341f, 0.0349f, 0.0357f, 0.0366f, 0.0375f, 0.0384f, 0.0394f,
|
||||
0.0405f, 0.0416f, 0.0428f, 0.0440f, 0.0453f, 0.0467f, 0.0482f, 0.0498f,
|
||||
0.0515f, 0.0532f, 0.0552f, 0.0572f, 0.0594f, 0.0618f, 0.0643f, 0.0671f,
|
||||
0.0701f, 0.0734f, 0.0770f, 0.0809f, 0.0851f, 0.0898f, 0.0950f, 0.1008f,
|
||||
0.1071f, 0.1142f, 0.1221f, 0.1307f, 0.1403f, 0.1508f, 0.1621f, 0.1739f,
|
||||
0.1857f, 0.1968f, 0.2060f, 0.2123f, 0.2145f
|
||||
};
|
||||
static const float hlorentz60[49] = {
|
||||
0.0319f, 0.0325f, 0.0332f, 0.0339f, 0.0347f, 0.0355f, 0.0363f, 0.0371f,
|
||||
0.0380f, 0.0390f, 0.0400f, 0.0410f, 0.0421f, 0.0432f, 0.0444f, 0.0457f,
|
||||
0.0471f, 0.0485f, 0.0500f, 0.0517f, 0.0534f, 0.0552f, 0.0572f, 0.0593f,
|
||||
0.0615f, 0.0640f, 0.0666f, 0.0694f, 0.0724f, 0.0757f, 0.0793f, 0.0833f,
|
||||
0.0875f, 0.0922f, 0.0974f, 0.1030f, 0.1093f, 0.1161f, 0.1237f, 0.1319f,
|
||||
0.1409f, 0.1506f, 0.1608f, 0.1713f, 0.1816f, 0.1910f, 0.1987f, 0.2038f,
|
||||
0.2056f
|
||||
};
|
||||
static const float hlorentz61[53] = {
|
||||
0.0307f, 0.0313f, 0.0319f, 0.0325f, 0.0332f, 0.0338f, 0.0346f, 0.0353f,
|
||||
0.0361f, 0.0369f, 0.0377f, 0.0386f, 0.0395f, 0.0405f, 0.0415f, 0.0426f,
|
||||
0.0437f, 0.0449f, 0.0462f, 0.0475f, 0.0489f, 0.0504f, 0.0519f, 0.0536f,
|
||||
0.0553f, 0.0572f, 0.0592f, 0.0614f, 0.0637f, 0.0661f, 0.0688f, 0.0716f,
|
||||
0.0747f, 0.0780f, 0.0816f, 0.0856f, 0.0898f, 0.0945f, 0.0996f, 0.1051f,
|
||||
0.1111f, 0.1177f, 0.1249f, 0.1327f, 0.1410f, 0.1499f, 0.1590f, 0.1683f,
|
||||
0.1771f, 0.1851f, 0.1915f, 0.1957f, 0.1971f
|
||||
};
|
||||
static const float hlorentz62[57] = {
|
||||
0.0297f, 0.0302f, 0.0308f, 0.0313f, 0.0319f, 0.0325f, 0.0332f, 0.0338f,
|
||||
0.0345f, 0.0352f, 0.0359f, 0.0367f, 0.0375f, 0.0384f, 0.0392f, 0.0401f,
|
||||
0.0411f, 0.0421f, 0.0432f, 0.0443f, 0.0454f, 0.0466f, 0.0479f, 0.0493f,
|
||||
0.0507f, 0.0522f, 0.0538f, 0.0555f, 0.0573f, 0.0592f, 0.0613f, 0.0635f,
|
||||
0.0658f, 0.0683f, 0.0710f, 0.0738f, 0.0769f, 0.0803f, 0.0839f, 0.0878f,
|
||||
0.0920f, 0.0965f, 0.1015f, 0.1069f, 0.1127f, 0.1190f, 0.1258f, 0.1330f,
|
||||
0.1406f, 0.1486f, 0.1568f, 0.1648f, 0.1724f, 0.1791f, 0.1844f, 0.1878f,
|
||||
0.1890f
|
||||
};
|
||||
static const float hlorentz63[62] = {
|
||||
0.0284f, 0.0289f, 0.0294f, 0.0299f, 0.0304f, 0.0309f, 0.0315f, 0.0320f,
|
||||
0.0326f, 0.0332f, 0.0338f, 0.0345f, 0.0352f, 0.0359f, 0.0366f, 0.0374f,
|
||||
0.0382f, 0.0390f, 0.0399f, 0.0408f, 0.0417f, 0.0427f, 0.0437f, 0.0448f,
|
||||
0.0459f, 0.0471f, 0.0484f, 0.0497f, 0.0511f, 0.0525f, 0.0541f, 0.0557f,
|
||||
0.0575f, 0.0593f, 0.0612f, 0.0633f, 0.0655f, 0.0679f, 0.0704f, 0.0731f,
|
||||
0.0760f, 0.0791f, 0.0824f, 0.0859f, 0.0898f, 0.0939f, 0.0984f, 0.1032f,
|
||||
0.1083f, 0.1139f, 0.1198f, 0.1261f, 0.1328f, 0.1398f, 0.1469f, 0.1541f,
|
||||
0.1610f, 0.1675f, 0.1731f, 0.1774f, 0.1802f, 0.1811f
|
||||
};
|
||||
static const float hlorentz64[65] = {
|
||||
0.0283f, 0.0287f, 0.0291f, 0.0296f, 0.0301f, 0.0306f, 0.0311f, 0.0316f,
|
||||
0.0322f, 0.0327f, 0.0333f, 0.0339f, 0.0345f, 0.0352f, 0.0359f, 0.0366f,
|
||||
0.0373f, 0.0381f, 0.0388f, 0.0397f, 0.0405f, 0.0414f, 0.0423f, 0.0433f,
|
||||
0.0443f, 0.0454f, 0.0465f, 0.0476f, 0.0489f, 0.0501f, 0.0515f, 0.0529f,
|
||||
0.0544f, 0.0560f, 0.0576f, 0.0594f, 0.0613f, 0.0632f, 0.0653f, 0.0676f,
|
||||
0.0699f, 0.0724f, 0.0751f, 0.0780f, 0.0811f, 0.0843f, 0.0879f, 0.0916f,
|
||||
0.0956f, 0.0999f, 0.1046f, 0.1095f, 0.1147f, 0.1202f, 0.1261f, 0.1321f,
|
||||
0.1384f, 0.1447f, 0.1510f, 0.1569f, 0.1624f, 0.1670f, 0.1706f, 0.1728f,
|
||||
0.1736f
|
||||
};
|
||||
static const float *hptr_tab_lorentz[64] = {
|
||||
hlorentz1, hlorentz2, hlorentz3, hlorentz4,
|
||||
hlorentz5, hlorentz6, hlorentz7, hlorentz8,
|
||||
hlorentz9, hlorentz10, hlorentz11, hlorentz12,
|
||||
hlorentz13, hlorentz14, hlorentz15, hlorentz16,
|
||||
hlorentz17, hlorentz18, hlorentz19, hlorentz20,
|
||||
hlorentz21, hlorentz22, hlorentz23, hlorentz24,
|
||||
hlorentz25, hlorentz26, hlorentz27, hlorentz28,
|
||||
hlorentz29, hlorentz30, hlorentz31, hlorentz32,
|
||||
hlorentz33, hlorentz34, hlorentz35, hlorentz36,
|
||||
hlorentz37, hlorentz38, hlorentz39, hlorentz40,
|
||||
hlorentz41, hlorentz42, hlorentz43, hlorentz44,
|
||||
hlorentz45, hlorentz46, hlorentz47, hlorentz48,
|
||||
hlorentz49, hlorentz50, hlorentz51, hlorentz52,
|
||||
hlorentz53, hlorentz54, hlorentz55, hlorentz56,
|
||||
hlorentz57, hlorentz58, hlorentz59, hlorentz60,
|
||||
hlorentz61, hlorentz62, hlorentz63, hlorentz64
|
||||
};
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
main.c
|
||||
QRA64 mode encode/decode test
|
||||
QRA64 mode encode/decode tests
|
||||
|
||||
(c) 2016 - Nico Palermo, IV3NWV
|
||||
|
||||
@ -145,21 +145,22 @@ symbol.
|
||||
normrnd_s(rp,NSAMPLES,0,sigma);
|
||||
normrnd_s(rq,NSAMPLES,0,sigma);
|
||||
|
||||
if (channel_type == CHANNEL_AWGN)
|
||||
for (k=0;k<QRA64_N;k++)
|
||||
rp[k*QRA64_M+x[k]]+=A;
|
||||
else
|
||||
if (channel_type == CHANNEL_RAYLEIGH) {
|
||||
normrnd_s(chp,QRA64_N,0,sigmach);
|
||||
normrnd_s(chq,QRA64_N,0,sigmach);
|
||||
for (k=0;k<QRA64_N;k++) {
|
||||
rp[k*QRA64_M+x[k]]+=A*chp[k];
|
||||
rq[k*QRA64_M+x[k]]+=A*chq[k];
|
||||
}
|
||||
}
|
||||
else {
|
||||
return 0; // unknown channel type
|
||||
}
|
||||
if(EbNodB>-15)
|
||||
if (channel_type == CHANNEL_AWGN)
|
||||
for (k=0;k<QRA64_N;k++)
|
||||
rp[k*QRA64_M+x[k]]+=A;
|
||||
else
|
||||
if (channel_type == CHANNEL_RAYLEIGH) {
|
||||
normrnd_s(chp,QRA64_N,0,sigmach);
|
||||
normrnd_s(chq,QRA64_N,0,sigmach);
|
||||
for (k=0;k<QRA64_N;k++) {
|
||||
rp[k*QRA64_M+x[k]]+=A*chp[k];
|
||||
rq[k*QRA64_M+x[k]]+=A*chq[k];
|
||||
}
|
||||
}
|
||||
else {
|
||||
return 0; // unknown channel type
|
||||
}
|
||||
|
||||
// compute the squares of the amplitudes of the received samples
|
||||
for (k=0;k<NSAMPLES;k++)
|
||||
@ -342,7 +343,7 @@ a particular type decode among the above 6 cases succeded.
|
||||
|
||||
int ndecok[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int nundet = 0;
|
||||
int ntx = 100,ndec=0;
|
||||
int ntx = 200,ndec=0;
|
||||
|
||||
qra64codec *codec_iv3nwv = qra64_init(mode); // codec for IV3NWV
|
||||
qra64codec *codec_k1jt = qra64_init(mode); // codec for K1JT
|
||||
@ -351,16 +352,16 @@ a particular type decode among the above 6 cases succeded.
|
||||
QRA64_SNR_EBNO_OFFSET);
|
||||
|
||||
// This will enable K1JT's decoder to look for calls directed to him [K1JT ? ?/b]
|
||||
printf("K1JT decoder enabled for [K1JT ? ?/blank]\n");
|
||||
qra64_apset(codec_k1jt, CALL_K1JT,0,0,APTYPE_MYCALL);
|
||||
// printf("K1JT decoder enabled for [K1JT ? ?/blank]\n");
|
||||
// qra64_apset(codec_k1jt, CALL_K1JT,0,0,APTYPE_MYCALL);
|
||||
|
||||
// This will enable K1JT's decoder to look for IV3NWV calls directed to him [K1JT IV3NWV ?/b]
|
||||
printf("K1JT decoder enabled for [K1JT IV3NWV ?]\n");
|
||||
qra64_apset(codec_k1jt, CALL_K1JT,CALL_IV3NWV,0,APTYPE_BOTHCALLS);
|
||||
// printf("K1JT decoder enabled for [K1JT IV3NWV ?]\n");
|
||||
// qra64_apset(codec_k1jt, CALL_CQ,CALL_IV3NWV,0,APTYPE_BOTHCALLS);
|
||||
|
||||
// This will enable K1JT's decoder to look for msges sent by IV3NWV [? IV3NWV ?]
|
||||
printf("K1JT decoder enabled for [? IV3NWV ?/blank]\n");
|
||||
qra64_apset(codec_k1jt, 0,CALL_IV3NWV,GRID_BLANK,APTYPE_HISCALL);
|
||||
// printf("K1JT decoder enabled for [? IV3NWV ?/blank]\n");
|
||||
// qra64_apset(codec_k1jt, 0,CALL_IV3NWV,GRID_BLANK,APTYPE_HISCALL);
|
||||
|
||||
// This will enable K1JT's decoder to look for full-knowledge [K1JT IV3NWV JN66] msgs
|
||||
printf("K1JT decoder enabled for [K1JT IV3NWV JN66]\n");
|
||||
@ -372,8 +373,12 @@ a particular type decode among the above 6 cases succeded.
|
||||
|
||||
|
||||
// Dx station IV3NWV calls
|
||||
printf("\nIV3NWV encoder sends msg: [CQ IV3NWV JN66]\n\n");
|
||||
printf("\nIV3NWV encoder sends msg: [K1JT IV3NWV JN66]\n\n");
|
||||
encodemsg_jt65(x,CALL_CQ,CALL_IV3NWV,GRID_JN66);
|
||||
|
||||
// printf("\nIV3NWV encoder sends msg: [CQ IV3NWV JN66]\n\n");
|
||||
// encodemsg_jt65(x,CALL_CQ,CALL_IV3NWV,GRID_JN66);
|
||||
|
||||
// printf("\nIV3NWV encoder sends msg: [CQ IV3NWV]\n\n");
|
||||
// encodemsg_jt65(x,CALL_CQ,CALL_IV3NWV,GRID_BLANK);
|
||||
qra64_encode(codec_iv3nwv, y, x);
|
||||
@ -409,6 +414,88 @@ a particular type decode among the above 6 cases succeded.
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_fastfading(float EbNodB, float B90, int fadingModel, int submode, int apmode)
|
||||
{
|
||||
int x[QRA64_K], xdec[QRA64_K];
|
||||
int y[QRA64_N];
|
||||
float *rx;
|
||||
float ebnodbest, ebnodbavg=0;
|
||||
int rc,k;
|
||||
|
||||
int ndecok[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int nundet = 0;
|
||||
int ntx = 100,ndec=0;
|
||||
|
||||
qra64codec *codec_iv3nwv;
|
||||
qra64codec *codec_k1jt;
|
||||
|
||||
codec_iv3nwv=qra64_init(QRA_NOAP);
|
||||
codec_k1jt =qra64_init(apmode);
|
||||
|
||||
printf("\nSimulating the QRA64 decoder with fast-fading metric\n");
|
||||
printf("B90=%.2f Hz - Fading Model=%s - Submode=QRA64%c\n\n",B90,fadingModel?"Lorentz":"Gauss",submode+'A');
|
||||
|
||||
if (apmode==QRA_USERAP) {
|
||||
// This will enable K1JT's decoder to look for calls directed to him [K1JT ? ?/b]
|
||||
printf("K1JT decoder enabled for [K1JT ? ?/blank]\n");
|
||||
qra64_apset(codec_k1jt, CALL_K1JT,0,0,APTYPE_MYCALL);
|
||||
|
||||
// This will enable K1JT's decoder to look for IV3NWV calls directed to him [K1JT IV3NWV ?/b]
|
||||
printf("K1JT decoder enabled for [K1JT IV3NWV ?]\n");
|
||||
qra64_apset(codec_k1jt, CALL_CQ,CALL_IV3NWV,0,APTYPE_BOTHCALLS);
|
||||
|
||||
// This will enable K1JT's decoder to look for msges sent by IV3NWV [? IV3NWV ?]
|
||||
printf("K1JT decoder enabled for [? IV3NWV ?/blank]\n");
|
||||
qra64_apset(codec_k1jt, 0,CALL_IV3NWV,GRID_BLANK,APTYPE_HISCALL);
|
||||
|
||||
// This will enable K1JT's decoder to look for full-knowledge [K1JT IV3NWV JN66] msgs
|
||||
printf("K1JT decoder enabled for [K1JT IV3NWV JN66]\n");
|
||||
qra64_apset(codec_k1jt, CALL_K1JT,CALL_IV3NWV,GRID_JN66,APTYPE_FULL);
|
||||
|
||||
// This will enable K1JT's decoder to look for calls from IV3NWV [CQ IV3NWV ?/b] msgs
|
||||
printf("K1JT decoder enabled for [CQ IV3NWV ?/b/JN66]\n");
|
||||
qra64_apset(codec_k1jt, 0,CALL_IV3NWV,GRID_JN66,APTYPE_CQHISCALL);
|
||||
|
||||
}
|
||||
printf("\nEncoding msg: [K1JT IV3NWV JN66]\n");
|
||||
encodemsg_jt65(x,CALL_K1JT,CALL_IV3NWV,GRID_JN66);
|
||||
qra64_encode(codec_iv3nwv, y, x);
|
||||
|
||||
printf("Decoding with K1JT's decoder\n");
|
||||
for (k=0;k<ntx;k++) {
|
||||
printf(".");
|
||||
rc = qra64_fastfading_channel(&rx,y,submode,EbNodB,B90,fadingModel);
|
||||
if (rc<0) {
|
||||
printf("qra64_fastfading_channel error. rc=%d\n",rc);
|
||||
return -1;
|
||||
}
|
||||
rc = qra64_decode_fastfading(codec_k1jt,&ebnodbest,xdec,rx,submode,B90,fadingModel);
|
||||
if (rc>=0) {
|
||||
ebnodbavg +=ebnodbest;
|
||||
if (memcmp(xdec,x,12*sizeof(int))==0)
|
||||
ndecok[rc]++;
|
||||
else
|
||||
nundet++;
|
||||
}
|
||||
}
|
||||
printf("\n\n");
|
||||
|
||||
printf("Transimtted msgs:%d\nDecoded msgs:\n\n",ntx);
|
||||
for (k=0;k<12;k++) {
|
||||
printf("%3d with %s\n",ndecok[k],decode_type[k]);
|
||||
ndec += ndecok[k];
|
||||
}
|
||||
printf("\nTotal: %d/%d (%d undetected errors)\n\n",ndec,ntx,nundet);
|
||||
printf("");
|
||||
|
||||
ebnodbavg/=(ndec+nundet);
|
||||
printf("Estimated SNR (average in dB) = %.2f dB\n\n",ebnodbavg-QRA64_SNR_EBNO_OFFSET);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void syntax(void)
|
||||
{
|
||||
printf("\nQRA64 Mode Tests\n");
|
||||
@ -421,6 +508,11 @@ void syntax(void)
|
||||
printf(" -a<ap-type> : set decode type 0=NOAP 1=AUTOAP (default) 2=USERAP\n");
|
||||
printf(" -t<testtype>: 0=simulate seq of msgs between IV3NWV and K1JT (default)\n");
|
||||
printf(" 1=simulate K1JT receiving K1JT IV3NWV JN66\n");
|
||||
printf(" 2=simulate fast-fading routines (option -c ignored)\n");
|
||||
printf("Options used only for fast-fading simulations:\n");
|
||||
printf(" -b : 90%% fading bandwidth in Hz [1..230 Hz] (default = 2.5 Hz)\n");
|
||||
printf(" -m : fading model. 0=Gauss, 1=Lorentz (default = Lorentz)\n");
|
||||
printf(" -q : qra64 submode. 0=QRA64A,... 4=QRA64E (default = QRA64A)\n");
|
||||
printf(" -h: this help\n");
|
||||
}
|
||||
|
||||
@ -433,55 +525,88 @@ int main(int argc, char* argv[])
|
||||
unsigned int testtype=0;
|
||||
int nqso = 100;
|
||||
float EbNodB;
|
||||
float B90 = 2.5;
|
||||
int fadingModel = 1;
|
||||
int submode = 0;
|
||||
|
||||
// Parse the command line
|
||||
while(--argc) {
|
||||
argv++;
|
||||
|
||||
if (strncmp(*argv,"-h",2)==0) {
|
||||
syntax();
|
||||
return 0;
|
||||
} else {
|
||||
if (strncmp(*argv,"-a",2)==0) {
|
||||
mode = ( int)atoi((*argv)+2);
|
||||
if (mode>2) {
|
||||
printf("Invalid decoding mode\n");
|
||||
syntax();
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
if (strncmp(*argv,"-a",2)==0) {
|
||||
mode = ( int)atoi((*argv)+2);
|
||||
if (mode>2) {
|
||||
printf("Invalid decoding mode\n");
|
||||
syntax();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (strncmp(*argv,"-s",2)==0) {
|
||||
SNRdB = (float)atof((*argv)+2);
|
||||
if (SNRdB>20 || SNRdB<-40) {
|
||||
printf("SNR should be in the range [-40..20]\n");
|
||||
SNRdB = (float)atof((*argv)+2);
|
||||
if (SNRdB>20 || SNRdB<-50) {
|
||||
printf("SNR should be in the range [-50..20]\n");
|
||||
syntax();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (strncmp(*argv,"-t",2)==0) {
|
||||
testtype = ( int)atoi((*argv)+2);
|
||||
if (testtype>2) {
|
||||
printf("Invalid test type\n");
|
||||
syntax();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (strncmp(*argv,"-c",2)==0) {
|
||||
channel = ( int)atoi((*argv)+2);
|
||||
if (channel>CHANNEL_RAYLEIGH) {
|
||||
printf("Invalid channel type\n");
|
||||
syntax();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (strncmp(*argv,"-b",2)==0) {
|
||||
B90 = (float)atof((*argv)+2);
|
||||
if (B90<1 || B90>230) {
|
||||
printf("Invalid B90\n");
|
||||
syntax();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (strncmp(*argv,"-m",2)==0) {
|
||||
fadingModel = (int)atoi((*argv)+2);
|
||||
if (fadingModel<0 || fadingModel>1) {
|
||||
printf("Invalid fading model\n");
|
||||
syntax();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (strncmp(*argv,"-q",2)==0) {
|
||||
submode = (int)atoi((*argv)+2);
|
||||
if (submode<0 || submode>4) {
|
||||
printf("Invalid submode\n");
|
||||
syntax();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("Invalid option\n");
|
||||
syntax();
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (strncmp(*argv,"-t",2)==0) {
|
||||
testtype = ( int)atoi((*argv)+2);
|
||||
if (testtype>1) {
|
||||
printf("Invalid test type\n");
|
||||
syntax();
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (strncmp(*argv,"-c",2)==0) {
|
||||
channel = ( int)atoi((*argv)+2);
|
||||
if (channel>CHANNEL_RAYLEIGH) {
|
||||
printf("Invalid channel type\n");
|
||||
syntax();
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
printf("Invalid option\n");
|
||||
syntax();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EbNodB = SNRdB+QRA64_SNR_EBNO_OFFSET;
|
||||
|
||||
@ -490,21 +615,33 @@ int main(int argc, char* argv[])
|
||||
#endif
|
||||
|
||||
if (testtype==0) {
|
||||
for (k=0;k<nqso;k++) {
|
||||
printf("\n\n------------------------\n");
|
||||
rc = test_proc_1(channel, EbNodB, mode);
|
||||
if (rc==0)
|
||||
nok++;
|
||||
}
|
||||
printf("\n\n%d/%d QSOs to end without repetitions\n",nok,nqso);
|
||||
} else {
|
||||
test_proc_2(channel, EbNodB, mode);
|
||||
}
|
||||
|
||||
printf("Input SNR = %.1fdB channel=%s ap-mode=%s\n\n",
|
||||
for (k=0;k<nqso;k++) {
|
||||
printf("\n\n------------------------\n");
|
||||
rc = test_proc_1(channel, EbNodB, mode);
|
||||
if (rc==0)
|
||||
nok++;
|
||||
}
|
||||
printf("\n\n%d/%d QSOs to end without repetitions\n",nok,nqso);
|
||||
printf("Input SNR = %.1fdB channel=%s ap-mode=%s\n\n",
|
||||
SNRdB,
|
||||
channel==CHANNEL_AWGN?"AWGN":"RAYLEIGH",
|
||||
apmode_type[mode]
|
||||
);
|
||||
}
|
||||
else if (testtype==1) {
|
||||
test_proc_2(channel, EbNodB, mode);
|
||||
printf("Input SNR = %.1fdB channel=%s ap-mode=%s\n\n",
|
||||
SNRdB,
|
||||
channel==CHANNEL_AWGN?"AWGN":"RAYLEIGH",
|
||||
apmode_type[mode]
|
||||
);
|
||||
}
|
||||
else {
|
||||
test_fastfading(EbNodB,B90,fadingModel,submode,mode);
|
||||
printf("Input SNR = %.1fdB ap-mode=%s\n\n",
|
||||
SNRdB,
|
||||
channel==CHANNEL_AWGN?"AWGN":"RAYLEIGH",
|
||||
apmode_type[mode]
|
||||
);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ Encoding/decoding functions for the QRA64 mode
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Code used in this sowftware release:
|
||||
QRA code used in this sowftware release:
|
||||
|
||||
QRA13_64_64_IRR_E: K=13 N=64 Q=64 irregular QRA code (defined in
|
||||
qra13_64_64_irr_e.h /.c)
|
||||
@ -34,13 +34,13 @@ resulting code is a (12,63) code
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "qra64.h"
|
||||
#include "../qracodes/qracodes.h"
|
||||
#include "../qracodes/qra13_64_64_irr_e.h"
|
||||
#include "../qracodes/pdmath.h"
|
||||
#include "../qracodes/normrnd.h"
|
||||
|
||||
// Code parameters of the QRA64 mode
|
||||
#define QRA64_CODE qra_13_64_64_irr_e
|
||||
@ -54,8 +54,28 @@ resulting code is a (12,63) code
|
||||
static int calc_crc6(const int *x, int sz);
|
||||
static void ix_mask(float *dst, const float *src, const int *mask,
|
||||
const int *x);
|
||||
static int qra64_do_decode(int *x, const float *pix, const int *ap_mask,
|
||||
static int qra64_decode_attempts(qra64codec *pcodec, int *xdec, const float *ix);
|
||||
static int qra64_do_decode(int *x, const float *pix, const int *ap_mask,
|
||||
const int *ap_x);
|
||||
static float qra64_fastfading_estim_noise_std(
|
||||
float *rxen,
|
||||
const float esnometric,
|
||||
const int submode);
|
||||
static void qra64_fastfading_intrinsics(
|
||||
float *pix,
|
||||
const float *rxamp,
|
||||
const float *hptr,
|
||||
const int hlen,
|
||||
const float cmetric,
|
||||
const int submode);
|
||||
static float qra64_fastfading_msg_esno(
|
||||
const int *ydec,
|
||||
const float *rxamp,
|
||||
const float sigma,
|
||||
const float EsNoMetric,
|
||||
const int hlen,
|
||||
const int submode);
|
||||
|
||||
|
||||
// a-priori information masks for fields in JT65-like msgs --------------------
|
||||
#define MASK_CQQRZ 0xFFFFFFC // CQ/QRZ calls common bits
|
||||
@ -259,101 +279,13 @@ int qra64_decode(qra64codec *pcodec, float *ebno, int *x, const float *rxen)
|
||||
// Initialize crc prob to a uniform distribution
|
||||
pd_init(dsttmp,pd_uniform(QRA64_m),QRA64_M);
|
||||
|
||||
// Attempt to decode without a-priori info --------------------------------
|
||||
rc = qra64_do_decode(xdec, ix, NULL, NULL);
|
||||
if (rc>=0) {
|
||||
rc = 0; // successfull decode with AP0
|
||||
goto decode_end;
|
||||
}
|
||||
else
|
||||
if (pcodec->apflags==QRA_NOAP)
|
||||
// nothing more to do
|
||||
return rc; // rc<0 = unsuccessful decode
|
||||
// Try to decode using all AP cases if required
|
||||
rc = qra64_decode_attempts(pcodec, xdec, ix);
|
||||
|
||||
// Here we handle decoding with AP knowledge
|
||||
if (rc<0)
|
||||
return rc; // no success
|
||||
|
||||
// Attempt to decode CQ calls
|
||||
rc = qra64_do_decode(xdec,ix,pcodec->apmask_cqqrz, pcodec->apmsg_cqqrz);
|
||||
if (rc>=0) { rc = 1; goto decode_end; }; // decoded [cq/qrz ? ?]
|
||||
rc = qra64_do_decode(xdec, ix, pcodec->apmask_cqqrz_ooo,
|
||||
pcodec->apmsg_cqqrz);
|
||||
if (rc>=0) { rc = 2; goto decode_end; }; // decoded [cq ? ooo]
|
||||
|
||||
// attempt to decode calls directed to us
|
||||
if (pcodec->apmsg_set[APTYPE_MYCALL]) {
|
||||
rc = qra64_do_decode(xdec, ix, pcodec->apmask_call1,
|
||||
pcodec->apmsg_call1);
|
||||
if (rc>=0) { rc = 3; goto decode_end; }; // decoded [mycall ? ?]
|
||||
rc = qra64_do_decode(xdec, ix, pcodec->apmask_call1_ooo,
|
||||
pcodec->apmsg_call1);
|
||||
if (rc>=0) { rc = 4; goto decode_end; }; // decoded [mycall ? ooo]
|
||||
}
|
||||
|
||||
// attempt to decode [mycall srccall ?] msgs
|
||||
if (pcodec->apmsg_set[APTYPE_BOTHCALLS]) {
|
||||
rc = qra64_do_decode(xdec, ix, pcodec->apmask_call1_call2,
|
||||
pcodec->apmsg_call1_call2);
|
||||
if (rc>=0) { rc = 5; goto decode_end; }; // decoded [mycall srccall ?]
|
||||
}
|
||||
|
||||
// attempt to decode [? hiscall ?/b] msgs
|
||||
if (pcodec->apmsg_set[APTYPE_HISCALL]) {
|
||||
rc = qra64_do_decode(xdec, ix, pcodec->apmask_call2,
|
||||
pcodec->apmsg_call2);
|
||||
if (rc>=0) { rc = 6; goto decode_end; }; // decoded [? hiscall ?]
|
||||
rc = qra64_do_decode(xdec, ix, pcodec->apmask_call2_ooo,
|
||||
pcodec->apmsg_call2);
|
||||
if (rc>=0) { rc = 7; goto decode_end; }; // decoded [? hiscall ooo]
|
||||
}
|
||||
|
||||
// attempt to decode [cq/qrz hiscall ?/b/grid] msgs
|
||||
if (pcodec->apmsg_set[APTYPE_CQHISCALL]) {
|
||||
|
||||
rc = qra64_do_decode(xdec, ix, pcodec->apmask_cq_call2,
|
||||
pcodec->apmsg_cq_call2);
|
||||
if (rc>=0) { rc = 9; goto decode_end; }; // decoded [cq/qrz hiscall ?]
|
||||
|
||||
rc = qra64_do_decode(xdec, ix, pcodec->apmask_cq_call2_ooo,
|
||||
pcodec->apmsg_cq_call2_grid);
|
||||
if (rc>=0) {
|
||||
// Full AP mask need special handling
|
||||
// To minimize false decodes we check the decoded message
|
||||
// with what passed in the ap_set call
|
||||
if (memcmp(pcodec->apmsg_cq_call2_grid,xdec, QRA64_K*sizeof(int))!=0)
|
||||
return -1;
|
||||
rc = 11; goto decode_end;
|
||||
}; // decoded [cq/qrz hiscall grid]
|
||||
|
||||
rc = qra64_do_decode(xdec, ix, pcodec->apmask_cq_call2_ooo,
|
||||
pcodec->apmsg_cq_call2);
|
||||
if (rc>=0) {
|
||||
// Full AP mask need special handling
|
||||
// To minimize false decodes we check the decoded message
|
||||
// with what passed in the ap_set call
|
||||
if (memcmp(pcodec->apmsg_cq_call2,xdec, QRA64_K*sizeof(int))!=0)
|
||||
return -1;
|
||||
rc = 10; goto decode_end; }; // decoded [cq/qrz hiscall ]
|
||||
}
|
||||
|
||||
// attempt to decode [mycall hiscall grid]
|
||||
if (pcodec->apmsg_set[APTYPE_FULL]) {
|
||||
rc = qra64_do_decode(xdec, ix, pcodec->apmask_call1_call2_grid,
|
||||
pcodec->apmsg_call1_call2_grid);
|
||||
if (rc>=0) {
|
||||
// Full AP mask need special handling
|
||||
// All the three msg fields were given.
|
||||
// To minimize false decodes we check the decoded message
|
||||
// with what passed in the ap_set call
|
||||
if (memcmp(pcodec->apmsg_call1_call2_grid,xdec, QRA64_K*sizeof(int))!=0)
|
||||
return -1;
|
||||
rc = 8; goto decode_end;
|
||||
}; // decoded [mycall hiscall grid]
|
||||
}
|
||||
|
||||
// all decoding attempts failed
|
||||
return rc;
|
||||
|
||||
decode_end: // successfull decode
|
||||
// successfull decode --------------------------------
|
||||
|
||||
// copy decoded message (without crc) to output buffer
|
||||
memcpy(x,xdec,QRA64_K*sizeof(int));
|
||||
@ -404,8 +336,585 @@ decode_end: // successfull decode
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Tables of fading amplitudes coefficients for QRA64 (Ts=6912/12000)
|
||||
// As the fading is assumed to be symmetric around the nominal frequency
|
||||
// only the leftmost and the central coefficient are stored in the tables.
|
||||
// (files have been generated with the Matlab code efgengauss.m and efgenlorentz.m)
|
||||
#include "fadampgauss.c"
|
||||
#include "fadamplorentz.c"
|
||||
|
||||
int qra64_decode_fastfading(
|
||||
qra64codec *pcodec, // ptr to the codec structure
|
||||
float *ebno, // ptr to where the estimated Eb/No value will be saved
|
||||
int *x, // ptr to decoded message
|
||||
float *rxen, // ptr to received symbol energies array
|
||||
const int submode, // submode idx (0=QRA64A ... 4=QRA64E)
|
||||
const float B90, // spread bandwidth (90% fractional energy)
|
||||
const int fadingModel) // 0=Gaussian 1=Lorentzian fade model
|
||||
|
||||
// Decode a QRA64 msg using a fast-fading metric
|
||||
//
|
||||
// rxen: The array of the received bin energies
|
||||
// Bins must be spaced by integer multiples of the symbol rate (1/Ts Hz)
|
||||
// The array must be an array of total length U = L x N where:
|
||||
// L: is the number of frequency bins per message symbol (see after)
|
||||
// N: is the number of symbols in a QRA64 msg (63)
|
||||
|
||||
// The number of bins/symbol L depends on the selected submode accordingly to
|
||||
// the following rule:
|
||||
// L = (64+64*2^submode+64) = 64*(2+2^submode)
|
||||
// Tone 0 is always supposed to be at offset 64 in the array.
|
||||
// The m-th tone nominal frequency is located at offset 64 + m*2^submode (m=0..63)
|
||||
//
|
||||
// Submode A: (2^submode = 1)
|
||||
// L = 64*3 = 196 bins/symbol
|
||||
// Total length of the energies array: U = 192*63 = 12096 floats
|
||||
//
|
||||
// Submode B: (2^submode = 2)
|
||||
// L = 64*4 = 256 bins/symbol
|
||||
// Total length of the energies array: U = 256*63 = 16128 floats
|
||||
//
|
||||
// Submode C: (2^submode = 4)
|
||||
// L = 64*6 = 384 bins/symbol
|
||||
// Total length of the energies array: U = 384*63 = 24192 floats
|
||||
//
|
||||
// Submode D: (2^submode = 8)
|
||||
// L = 64*10 = 640 bins/symbol
|
||||
// Total length of the energies array: U = 640*63 = 40320 floats
|
||||
//
|
||||
// Submode E: (2^submode = 16)
|
||||
// L = 64*18 = 1152 bins/symbol
|
||||
// Total length of the energies array: U = 1152*63 = 72576 floats
|
||||
//
|
||||
// Note: The rxen array is modified and reused for internal calculations.
|
||||
//
|
||||
//
|
||||
// B90: spread fading bandwidth in Hz (90% fractional average energy)
|
||||
//
|
||||
// B90 should be in the range 1 Hz ... 238 Hz
|
||||
// The value passed to the call is rounded to the closest value among the
|
||||
// 64 available values:
|
||||
// B = 1.09^k Hz, with k=0,1,...,63
|
||||
//
|
||||
// I.e. B90=27 Hz will be approximated in this way:
|
||||
// k = rnd(log(27)/log(1.09)) = 38
|
||||
// B90 = 1.09^k = 1.09^38 = 26.4 Hz
|
||||
//
|
||||
// For any input value the maximum rounding error is not larger than +/- 5%
|
||||
//
|
||||
|
||||
{
|
||||
|
||||
int k;
|
||||
float *srctmp, *dsttmp;
|
||||
float ix[QRA64_NC*QRA64_M]; // (depunctured) intrisic information
|
||||
int xdec[QRA64_KC]; // decoded message (with crc)
|
||||
int ydec[QRA64_NC]; // re-encoded message (for snr calculations)
|
||||
float noisestd; // estimated noise std
|
||||
float esno,ebnoval; // estimated Eb/No
|
||||
float tempf;
|
||||
float EsNoMetric, cmetric;
|
||||
int rc;
|
||||
int hidx, hlen;
|
||||
const float *hptr;
|
||||
|
||||
if (QRA64_NMSG!=QRA64_CODE.NMSG)
|
||||
return -16; // QRA64_NMSG define is wrong
|
||||
|
||||
if (submode<0 || submode>4)
|
||||
return -17; // invalid submode
|
||||
|
||||
if (B90<1.0f || B90>238.0f)
|
||||
return -18; // B90 out of range
|
||||
|
||||
// compute index to most appropriate amplitude weighting function coefficients
|
||||
hidx = (int)(log((float)B90)/log(1.09f) - 0.499f);
|
||||
|
||||
if (hidx<0 || hidx > 64)
|
||||
return -19; // index of weighting function out of range
|
||||
|
||||
if (fadingModel==0) { // gaussian fading model
|
||||
// point to gaussian weighting taps
|
||||
hlen = hlen_tab_gauss[hidx]; // hlen = (L+1)/2 (where L=(odd) number of taps of w fun)
|
||||
hptr = hptr_tab_gauss[hidx]; // pointer to the first (L+1)/2 coefficients of w fun
|
||||
}
|
||||
else if (fadingModel==1) {
|
||||
// point to lorentzian weighting taps
|
||||
hlen = hlen_tab_lorentz[hidx]; // hlen = (L+1)/2 (where L=(odd) number of taps of w fun)
|
||||
hptr = hptr_tab_lorentz[hidx]; // pointer to the first (L+1)/2 coefficients of w fun
|
||||
}
|
||||
else
|
||||
return -20; // invalid fading model index
|
||||
|
||||
|
||||
// compute (euristically) the optimal decoder metric accordingly the given spread amount
|
||||
// We assume that the decoder threshold is:
|
||||
// Es/No(dB) = Es/No(AWGN)(dB) + 8*log(B90)/log(240)(dB)
|
||||
// that's to say, at the maximum Doppler spread bandwidth (240 Hz) there's a ~8 dB Es/No degradation
|
||||
// over the AWGN case
|
||||
tempf = 8.0f*(float)log((float)B90)/(float)log(240.0f);
|
||||
EsNoMetric = pcodec->decEsNoMetric*(float)pow(10.0f,tempf/10.0f);
|
||||
|
||||
// Step 1 -----------------------------------------------------------------------------------
|
||||
// Evaluate the noise stdev from the received energies at nominal tone frequencies
|
||||
// and transform energies to amplitudes
|
||||
tempf = hptr[hlen-1]; // amplitude weigth at nominal freq;
|
||||
tempf = tempf*tempf; // fractional energy at nominal freq. bin
|
||||
|
||||
noisestd = qra64_fastfading_estim_noise_std(rxen, EsNoMetric, submode);
|
||||
cmetric = (float)sqrt(M_PI_2*EsNoMetric)/noisestd;
|
||||
|
||||
// Step 2 -----------------------------------------------------------------------------------
|
||||
// Compute message symbols probability distributions
|
||||
qra64_fastfading_intrinsics(ix, rxen, hptr, hlen, cmetric, submode);
|
||||
|
||||
// Step 3 ---------------------------------------------------------------------------
|
||||
// De-puncture observations adding a uniform distribution for the crc symbol
|
||||
// Move check symbols distributions one symbol towards the end
|
||||
dsttmp = PD_ROWADDR(ix,QRA64_M, QRA64_NC-1); //Point to last symbol prob dist
|
||||
srctmp = dsttmp-QRA64_M; // source is the previous pd
|
||||
for (k=0;k<QRA64_C;k++) {
|
||||
pd_init(dsttmp,srctmp,QRA64_M);
|
||||
dsttmp -=QRA64_M;
|
||||
srctmp -=QRA64_M;
|
||||
}
|
||||
// Initialize crc prob to a uniform distribution
|
||||
pd_init(dsttmp,pd_uniform(QRA64_m),QRA64_M);
|
||||
|
||||
// Step 4 ---------------------------------------------------------------------------
|
||||
// Attempt to decode
|
||||
rc = qra64_decode_attempts(pcodec, xdec, ix);
|
||||
if (rc<0)
|
||||
return rc; // no success
|
||||
|
||||
// copy decoded message (without crc) to output buffer
|
||||
memcpy(x,xdec,QRA64_K*sizeof(int));
|
||||
|
||||
// Step 5 ----------------------------------------------------------------------------
|
||||
// Estimate the message Eb/No
|
||||
|
||||
if (ebno==0) // null pointer indicates we are not interested in the Eb/No estimate
|
||||
return rc;
|
||||
|
||||
// reencode message to estimate Eb/No
|
||||
qra_encode(&QRA64_CODE, ydec, xdec);
|
||||
// puncture crc
|
||||
memmove(ydec+QRA64_K,ydec+QRA64_KC,QRA64_C*sizeof(int));
|
||||
|
||||
// compute Es/N0 of decoded message
|
||||
esno = qra64_fastfading_msg_esno(ydec,rxen,noisestd, EsNoMetric, hlen,submode);
|
||||
|
||||
// as the weigthing function include about 90% of the energy
|
||||
// we could compute the unbiased esno with:
|
||||
// esno = esno/0.9;
|
||||
|
||||
// this would be the exact value if the noisestd were not overestimated at high Eb/No
|
||||
ebnoval = 1.0f/(1.0f*QRA64_K/QRA64_N*QRA64_m)*esno;
|
||||
|
||||
// compute value in dB
|
||||
if (ebnoval<=0)
|
||||
ebnoval = EBNO_MIN; // assume a minimum, positive value
|
||||
else
|
||||
ebnoval = 10.0f*(float)log10(ebnoval);
|
||||
if (ebnoval<EBNO_MIN)
|
||||
ebnoval = EBNO_MIN;
|
||||
|
||||
*ebno = ebnoval;
|
||||
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int qra64_fastfading_channel(float **rxen, const int *xmsg, const int submode, const float EbN0dB, const float B90, const int fadingModel)
|
||||
{
|
||||
// Simulate transmission over a fading channel and non coherent detection
|
||||
|
||||
// Set rxen to point to an array of bin energies formatted as required
|
||||
// by the (fast-fading) decoding routine
|
||||
|
||||
// returns 0 on success or negative values on error conditions
|
||||
|
||||
static float *channel_out = NULL;
|
||||
static int channel_submode = -1;
|
||||
|
||||
int bpt = (1<<submode); // bins per tone
|
||||
int bps = QRA64_M*(2+bpt); // total number of bins per symbols
|
||||
int bpm = bps*QRA64_N; // total number of bins in a message
|
||||
int n,j,hidx, hlen;
|
||||
const float *hptr;
|
||||
float *cursym,*curtone;
|
||||
|
||||
float iq[2];
|
||||
float *curi, *curq;
|
||||
|
||||
// float tote=0; // debug
|
||||
|
||||
float N0, EsN0, Es, A, sigmanoise, sigmasig;
|
||||
|
||||
if (rxen==NULL)
|
||||
return -1; // rxen must be a non-null ptr
|
||||
|
||||
// allocate output buffer if not yet done or if submode changed
|
||||
if (channel_out==NULL || submode!=channel_submode) {
|
||||
|
||||
// unallocate previous buffer
|
||||
if (channel_out)
|
||||
free(channel_out);
|
||||
|
||||
// allocate new buffer
|
||||
// we allocate twice the mem so that we can store/compute complex amplitudes
|
||||
channel_out = (float*)malloc(bpm*sizeof(float)*2);
|
||||
if (channel_out==NULL)
|
||||
return -2; // error allocating memory
|
||||
|
||||
channel_submode = submode;
|
||||
}
|
||||
|
||||
if (B90<1.0f || B90>238.0f)
|
||||
return -18; // B90 out of range
|
||||
|
||||
// compute index to most appropriate amplitude weighting function coefficients
|
||||
hidx = (int)(log((float)B90)/log(1.09f) - 0.499f);
|
||||
|
||||
if (hidx<0 || hidx > 64)
|
||||
return -19; // index of weighting function out of range
|
||||
|
||||
if (fadingModel==0) { // gaussian fading model
|
||||
// point to gaussian weighting taps
|
||||
hlen = hlen_tab_gauss[hidx]; // hlen = (L+1)/2 (where L=(odd) number of taps of w fun)
|
||||
hptr = hptr_tab_gauss[hidx]; // pointer to the first (L+1)/2 coefficients of w fun
|
||||
}
|
||||
else if (fadingModel==1) {
|
||||
// point to lorentzian weighting taps
|
||||
hlen = hlen_tab_lorentz[hidx]; // hlen = (L+1)/2 (where L=(odd) number of taps of w fun)
|
||||
hptr = hptr_tab_lorentz[hidx]; // pointer to the first (L+1)/2 coefficients of w fun
|
||||
}
|
||||
else
|
||||
return -20; // invalid fading model index
|
||||
|
||||
|
||||
// Compute the unfaded tone amplitudes from the Eb/No value passed to the call
|
||||
N0 = 1.0f; // assume unitary noise PSD
|
||||
sigmanoise = (float)sqrt(N0/2);
|
||||
EsN0 = (float)pow(10.0f,EbN0dB/10.0f)*QRA64_m*QRA64_K/QRA64_N; // Es/No = m*R*Eb/No
|
||||
Es = EsN0*N0;
|
||||
A = (float)sqrt(Es/2.0f); // unfaded tone amplitude (i^2+q^2 = Es/2+Es/2 = Es)
|
||||
|
||||
|
||||
// Generate gaussian noise iq components
|
||||
normrnd_s(channel_out, bpm*2, 0 , sigmanoise);
|
||||
|
||||
// Add message symbols energies
|
||||
for (n=0;n<QRA64_N;n++) {
|
||||
|
||||
cursym = channel_out+n*bps + QRA64_M; // point to n-th symbol
|
||||
curtone = cursym+xmsg[n]*bpt; // point to encoded tone
|
||||
curi = curtone-hlen+1; // point to real part of first bin
|
||||
curq = curtone-hlen+1+bpm; // point to imag part of first bin
|
||||
|
||||
// generate Rayleigh faded bins with given average energy and add to noise
|
||||
for (j=0;j<hlen;j++) {
|
||||
sigmasig = A*hptr[j];
|
||||
normrnd_s(iq, 2, 0 , sigmasig);
|
||||
// iq[0]=sigmasig*sqrt(2); iq[1]=0; debug: used to verify Eb/No
|
||||
*curi++ += iq[0];
|
||||
*curq++ += iq[1];
|
||||
// tote +=iq[0]*iq[0]+iq[1]*iq[1]; // debug
|
||||
}
|
||||
for (j=hlen-2;j>=0;j--) {
|
||||
sigmasig = A*hptr[j];
|
||||
normrnd_s(iq, 2, 0 , sigmasig);
|
||||
// iq[0]=sigmasig*sqrt(2); iq[1]=0; debug: used to verify Eb/No
|
||||
*curi++ += iq[0];
|
||||
*curq++ += iq[1];
|
||||
// tote +=iq[0]*iq[0]+iq[1]*iq[1]; // debug
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// tote = tote/QRA64_N; // debug
|
||||
|
||||
// compute total bin energies (S+N) and store in first half of buffer
|
||||
curi = channel_out;
|
||||
curq = channel_out+bpm;
|
||||
for (n=0;n<bpm;n++)
|
||||
channel_out[n] = curi[n]*curi[n] + curq[n]*curq[n];
|
||||
|
||||
// set rxen to point to the channel output energies
|
||||
*rxen = channel_out;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Static functions definitions ----------------------------------------------
|
||||
|
||||
// fast-fading static functions --------------------------------------------------------------
|
||||
|
||||
static float qra64_fastfading_estim_noise_std(float *rxen, const float esnometric, const int submode)
|
||||
{
|
||||
// estimate the noise standard deviation from nominal frequency symbol bins
|
||||
// transform energies to amplitudes
|
||||
|
||||
// rxen = message symbols energies (overwritten with symbols amplitudes)
|
||||
// esnometric = Es/No at nominal frequency bin for which we compute the decoder metric
|
||||
// submode = submode used (0=A...4=E)
|
||||
|
||||
int bpt = (1<<submode); // bins per tone
|
||||
int bps = QRA64_M*(2+bpt); // total number of bins per symbols
|
||||
int bpm = bps*QRA64_N; // total number of bins in a message
|
||||
int k;
|
||||
float sigmaest;
|
||||
|
||||
// estimate noise std
|
||||
sigmaest = 0;
|
||||
for (k=0;k<bpm;k++) {
|
||||
sigmaest += rxen[k];
|
||||
// convert energies to amplitudes for later use
|
||||
rxen[k] = (float)sqrt(rxen[k]); // we do it in place to avoid memory allocations
|
||||
}
|
||||
sigmaest = sigmaest/bpm;
|
||||
sigmaest = (float)sqrt(sigmaest/(1.0f+esnometric/bps)/2.0f);
|
||||
|
||||
// Note: sigma is overestimated by the (unknown) factor sqrt((1+esno(true)/bps)/(1+esnometric/bps))
|
||||
|
||||
return sigmaest;
|
||||
}
|
||||
|
||||
static void qra64_fastfading_intrinsics(
|
||||
float *pix,
|
||||
const float *rxamp,
|
||||
const float *hptr,
|
||||
const int hlen,
|
||||
const float cmetric,
|
||||
const int submode)
|
||||
{
|
||||
|
||||
// For each symbol in a message:
|
||||
// a) Compute tones loglikelihoods as a sum of products between of the expected
|
||||
// amplitude fading coefficient and received amplitudes.
|
||||
// Each product is computed as log(I0(hk*xk*cmetric)) where hk is the average fading amplitude,
|
||||
// xk is the received amplitude at bin offset k, and cmetric is a constant dependend on the
|
||||
// Eb/N0 value for which the metric is optimized
|
||||
// The function y = log(I0(x)) is approximated as y = x^2/(x+e)
|
||||
// b) Compute intrinsic symbols probability distributions from symbols loglikelihoods
|
||||
|
||||
int n,k,j, bps, bpt;
|
||||
const float *cursym, *curbin;
|
||||
float *curix;
|
||||
float u, maxloglh, loglh, sumix;
|
||||
|
||||
bpt = 1<<submode; // bins per tone
|
||||
bps = QRA64_M*(2+bpt); // bins per symbol
|
||||
|
||||
for (n=0;n<QRA64_N;n++) { // for each symbol in the message
|
||||
cursym = rxamp+n*bps + QRA64_M; // point to current symbol nominal bin
|
||||
maxloglh = 0;
|
||||
curix = pix+n*QRA64_M;
|
||||
for (k=0;k<QRA64_M;k++) { // for each tone in the current symbol
|
||||
curbin = cursym + k*bpt -hlen+1; // ptr to lowest bin of the current tone
|
||||
// compute tone loglikelihood as a weighted sum of bins loglikelihoods
|
||||
loglh = 0.f;
|
||||
for (j=0;j<hlen;j++) {
|
||||
u = *curbin++ * hptr[j]*cmetric;
|
||||
u = u*u/(u+(float)M_E); // log(I0(u)) approx.
|
||||
loglh = loglh + u;
|
||||
}
|
||||
for (j=hlen-2;j>=0;j--) {
|
||||
u = *curbin++ * hptr[j]*cmetric;
|
||||
u = u*u/(u+(float)M_E); // log(I0(u)) approx.
|
||||
loglh = loglh + u;
|
||||
}
|
||||
if (loglh>maxloglh) // keep track of the max loglikelihood
|
||||
maxloglh = loglh;
|
||||
curix[k]=loglh;
|
||||
}
|
||||
// scale to likelihoods
|
||||
sumix = 0.f;
|
||||
for (k=0;k<QRA64_M;k++) {
|
||||
u = (float)exp(curix[k]-maxloglh);
|
||||
curix[k]=u;
|
||||
sumix +=u;
|
||||
}
|
||||
// scale to probabilities
|
||||
sumix = 1.0f/sumix;
|
||||
for (k=0;k<QRA64_M;k++)
|
||||
curix[k] = curix[k]*sumix;
|
||||
}
|
||||
}
|
||||
|
||||
static float qra64_fastfading_msg_esno(
|
||||
const int *ydec,
|
||||
const float *rxamp,
|
||||
const float sigma,
|
||||
const float EsNoMetric,
|
||||
const int hlen,
|
||||
const int submode)
|
||||
{
|
||||
// Estimate msg Es/N0
|
||||
|
||||
int n,j, bps, bpt;
|
||||
const float *cursym, *curtone, *curbin;
|
||||
float u, msgsn,esno;
|
||||
int tothlen = 2*hlen-1;
|
||||
|
||||
bpt = 1<<submode; // bins per tone
|
||||
bps = QRA64_M*(2+bpt); // bins per symbol
|
||||
|
||||
msgsn = 0;
|
||||
for (n=0;n<QRA64_N;n++) {
|
||||
cursym = rxamp+n*bps + QRA64_M; // point to n-th symbol amplitudes
|
||||
curtone = cursym+ydec[n]*bpt; // point to decoded tone amplitudes
|
||||
curbin = curtone-hlen+1; // point to first bin amplitude
|
||||
|
||||
// sum bin energies
|
||||
for (j=0;j<hlen;j++) {
|
||||
u = *curbin++;
|
||||
msgsn += u*u;
|
||||
}
|
||||
for (j=hlen-2;j>=0;j--) {
|
||||
u = *curbin++;
|
||||
msgsn += u*u;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
msgsn = msgsn/(QRA64_N*tothlen); // avg msg energy per bin (noise included)
|
||||
|
||||
// as sigma is overestimated (sigmatrue = sigma*sqrt((1+EsNoMetric/bps)/(1+EsNo/bps))
|
||||
// we have: msgsn = (1+x/hlen)/(1+x/bps)*2*sigma^2*(1+EsnoMetric/bps), where x = Es/N0(true)
|
||||
//
|
||||
// we can then write:
|
||||
// u = msgsn/2.0f/(sigma*sigma)/(1.0f+EsNoMetric/bps);
|
||||
// (1+x/hlen)/(1+x/bps) = u
|
||||
|
||||
u = msgsn/(2.0f*sigma*sigma)/(1.0f+EsNoMetric/bps);
|
||||
|
||||
// check u>1
|
||||
if (u<1)
|
||||
return 0.f;
|
||||
|
||||
// check u<bps/tot hlen
|
||||
if (u>(bps/tothlen))
|
||||
return 10000.f;
|
||||
|
||||
// solve for Es/No
|
||||
esno = (u-1.0f)/(1.0f/tothlen-u/bps);
|
||||
|
||||
return esno;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Attempt to decode given intrisic information
|
||||
static int qra64_decode_attempts(qra64codec *pcodec, int *xdec, const float *ix)
|
||||
{
|
||||
int rc;
|
||||
|
||||
// Attempt to decode without a-priori info --------------------------------
|
||||
rc = qra64_do_decode(xdec, ix, NULL, NULL);
|
||||
if (rc>=0)
|
||||
return 0; // successfull decode with AP0
|
||||
else
|
||||
if (pcodec->apflags==QRA_NOAP)
|
||||
// nothing more to do
|
||||
return rc; // rc<0 = unsuccessful decode
|
||||
|
||||
// Here we handle decoding with AP knowledge
|
||||
|
||||
// Attempt to decode CQ calls
|
||||
rc = qra64_do_decode(xdec,ix,pcodec->apmask_cqqrz, pcodec->apmsg_cqqrz);
|
||||
if (rc>=0) return 1; // decoded [cq/qrz ? ?]
|
||||
|
||||
rc = qra64_do_decode(xdec, ix, pcodec->apmask_cqqrz_ooo,
|
||||
pcodec->apmsg_cqqrz);
|
||||
if (rc>=0) return 2; // decoded [cq ? ooo]
|
||||
|
||||
// attempt to decode calls directed to us
|
||||
if (pcodec->apmsg_set[APTYPE_MYCALL]) {
|
||||
rc = qra64_do_decode(xdec, ix, pcodec->apmask_call1,
|
||||
pcodec->apmsg_call1);
|
||||
if (rc>=0) return 3; // decoded [mycall ? ?]
|
||||
rc = qra64_do_decode(xdec, ix, pcodec->apmask_call1_ooo,
|
||||
pcodec->apmsg_call1);
|
||||
if (rc>=0) return 4; // decoded [mycall ? ooo]
|
||||
}
|
||||
|
||||
// attempt to decode [mycall srccall ?] msgs
|
||||
if (pcodec->apmsg_set[APTYPE_BOTHCALLS]) {
|
||||
rc = qra64_do_decode(xdec, ix, pcodec->apmask_call1_call2,
|
||||
pcodec->apmsg_call1_call2);
|
||||
if (rc>=0) return 5; // decoded [mycall srccall ?]
|
||||
}
|
||||
|
||||
// attempt to decode [? hiscall ?/b] msgs
|
||||
if (pcodec->apmsg_set[APTYPE_HISCALL]) {
|
||||
rc = qra64_do_decode(xdec, ix, pcodec->apmask_call2,
|
||||
pcodec->apmsg_call2);
|
||||
if (rc>=0) return 6; // decoded [? hiscall ?]
|
||||
rc = qra64_do_decode(xdec, ix, pcodec->apmask_call2_ooo,
|
||||
pcodec->apmsg_call2);
|
||||
if (rc>=0) return 7; // decoded [? hiscall ooo]
|
||||
}
|
||||
|
||||
// attempt to decode [cq/qrz hiscall ?/b/grid] msgs
|
||||
if (pcodec->apmsg_set[APTYPE_CQHISCALL]) {
|
||||
|
||||
rc = qra64_do_decode(xdec, ix, pcodec->apmask_cq_call2,
|
||||
pcodec->apmsg_cq_call2);
|
||||
if (rc>=0) return 9; // decoded [cq/qrz hiscall ?]
|
||||
|
||||
rc = qra64_do_decode(xdec, ix, pcodec->apmask_cq_call2_ooo,
|
||||
pcodec->apmsg_cq_call2_grid);
|
||||
if (rc>=0) {
|
||||
// Full AP mask need special handling
|
||||
// To minimize false decodes we check the decoded message
|
||||
// with what passed in the ap_set call
|
||||
if (memcmp(pcodec->apmsg_cq_call2_grid,xdec, QRA64_K*sizeof(int))!=0)
|
||||
return -1;
|
||||
else
|
||||
return 11; // decoded [cq/qrz hiscall grid]
|
||||
};
|
||||
|
||||
rc = qra64_do_decode(xdec, ix, pcodec->apmask_cq_call2_ooo,
|
||||
pcodec->apmsg_cq_call2);
|
||||
if (rc>=0) {
|
||||
// Full AP mask need special handling
|
||||
// To minimize false decodes we check the decoded message
|
||||
// with what passed in the ap_set call
|
||||
if (memcmp(pcodec->apmsg_cq_call2,xdec, QRA64_K*sizeof(int))!=0)
|
||||
return -1;
|
||||
else
|
||||
return 10; // decoded [cq/qrz hiscall ]
|
||||
}
|
||||
}
|
||||
|
||||
// attempt to decode [mycall hiscall grid]
|
||||
if (pcodec->apmsg_set[APTYPE_FULL]) {
|
||||
rc = qra64_do_decode(xdec, ix, pcodec->apmask_call1_call2_grid,
|
||||
pcodec->apmsg_call1_call2_grid);
|
||||
if (rc>=0) {
|
||||
// Full AP mask need special handling
|
||||
// All the three msg fields were given.
|
||||
// To minimize false decodes we check the decoded message
|
||||
// with what passed in the ap_set call
|
||||
if (memcmp(pcodec->apmsg_call1_call2_grid,xdec, QRA64_K*sizeof(int))!=0)
|
||||
return -1;
|
||||
else
|
||||
return 8; // decoded [mycall hiscall grid]
|
||||
}
|
||||
}
|
||||
|
||||
// all decoding attempts failed
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Decode with given a-priori information
|
||||
static int qra64_do_decode(int *xdec, const float *pix, const int *ap_mask,
|
||||
const int *ap_x)
|
||||
@ -441,6 +950,8 @@ static int qra64_do_decode(int *xdec, const float *pix, const int *ap_mask,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// crc functions --------------------------------------------------------------
|
||||
// crc-6 generator polynomial
|
||||
// g(x) = x^6 + a5*x^5 + ... + a1*x + a0
|
||||
|
@ -140,6 +140,83 @@ int qra64_decode(qra64codec *pcodec, float *ebno, int *x, const float *r);
|
||||
// return codes in the range 1-10 indicate the amount and the type of a-priori
|
||||
// information was required to decode the received message.
|
||||
|
||||
|
||||
// Decode a QRA64 msg using a fast-fading metric
|
||||
int qra64_decode_fastfading(
|
||||
qra64codec *pcodec, // ptr to the codec structure
|
||||
float *ebno, // ptr to where the estimated Eb/No value will be saved
|
||||
int *x, // ptr to decoded message
|
||||
float *rxen, // ptr to received symbol energies array
|
||||
const int submode, // submode idx (0=QRA64A ... 4=QRA64E)
|
||||
const float B90, // spread bandwidth (90% fractional energy)
|
||||
const int fadingModel); // 0=Gaussian 1=Lorentzian fade model
|
||||
//
|
||||
// rxen: The array of the received bin energies
|
||||
// Bins must be spaced by integer multiples of the symbol rate (1/Ts Hz)
|
||||
// The array must be an array of total length U = L x N where:
|
||||
// L: is the number of frequency bins per message symbol (see after)
|
||||
// N: is the number of symbols in a QRA64 msg (63)
|
||||
//
|
||||
// The number of bins/symbol L depends on the selected submode accordingly to
|
||||
// the following rule:
|
||||
// L = (64+64*2^submode+64) = 64*(2+2^submode)
|
||||
// Tone 0 is always supposed to be at offset 64 in the array.
|
||||
// The m-th tone nominal frequency is located at offset 64 + m*2^submode (m=0..63)
|
||||
//
|
||||
// Submode A: (2^submode = 1)
|
||||
// L = 64*3 = 196 bins/symbol
|
||||
// Total length of the energies array: U = 192*63 = 12096 floats
|
||||
//
|
||||
// Submode B: (2^submode = 2)
|
||||
// L = 64*4 = 256 bins/symbol
|
||||
// Total length of the energies array: U = 256*63 = 16128 floats
|
||||
//
|
||||
// Submode C: (2^submode = 4)
|
||||
// L = 64*6 = 384 bins/symbol
|
||||
// Total length of the energies array: U = 384*63 = 24192 floats
|
||||
//
|
||||
// Submode D: (2^submode = 8)
|
||||
// L = 64*10 = 640 bins/symbol
|
||||
// Total length of the energies array: U = 640*63 = 40320 floats
|
||||
//
|
||||
// Submode E: (2^submode = 16)
|
||||
// L = 64*18 = 1152 bins/symbol
|
||||
// Total length of the energies array: U = 1152*63 = 72576 floats
|
||||
//
|
||||
// Note: The rxen array is modified and reused for internal calculations.
|
||||
//
|
||||
//
|
||||
// B90: spread fading bandwidth in Hz (90% fractional average energy)
|
||||
//
|
||||
// B90 should be in the range 1 Hz ... 238 Hz
|
||||
// The value passed to the call is rounded to the closest value among the
|
||||
// 64 available values:
|
||||
// B = 1.09^k Hz, with k=0,1,...,63
|
||||
//
|
||||
// I.e. B90=27 Hz will be approximated in this way:
|
||||
// k = rnd(log(27)/log(1.09)) = 38
|
||||
// B90 = 1.09^k = 1.09^38 = 26.4 Hz
|
||||
//
|
||||
// For any input value the maximum rounding error is not larger than +/- 5%
|
||||
//
|
||||
// return codes: same return codes of qra64_decode (+some additional error codes)
|
||||
|
||||
|
||||
// Simulate the fast-fading channel (to be used with qra64_decode_fastfading)
|
||||
int qra64_fastfading_channel(
|
||||
float **rxen,
|
||||
const int *xmsg,
|
||||
const int submode,
|
||||
const float EbN0dB,
|
||||
const float B90,
|
||||
const int fadingModel);
|
||||
// Simulate transmission over a fading channel with given B90, fading model and submode
|
||||
// and non coherent detection.
|
||||
// Sets rxen to point to an array of bin energies formatted as required
|
||||
// by the (fast-fading) decoding routine.
|
||||
// returns 0 on success or negative values on error conditions
|
||||
|
||||
|
||||
int qra64_apset(qra64codec *pcodec, const int mycall, const int hiscall, const int grid, const int aptype);
|
||||
// Set decoder a-priori knowledge accordingly to the type of the message to
|
||||
// look up for
|
||||
|
50
lib/qra/qra64/qra64example.txt
Normal file
50
lib/qra/qra64/qra64example.txt
Normal file
@ -0,0 +1,50 @@
|
||||
Example:
|
||||
|
||||
qra64 -a2 -t2 -b10.0 -m1 -q2 -s-28.0
|
||||
|
||||
Simulate fast-fading decoding (-t2) with
|
||||
USER_AP (-a2)
|
||||
B90 = 10.0 Hz (-b10.0)
|
||||
Lorentz model (-m1)
|
||||
submode QRA64C (-q2)
|
||||
Input SNR = -28.0 dB (-s-28.0)
|
||||
|
||||
(type qra64 -h for command syntax)
|
||||
|
||||
Command Output:
|
||||
|
||||
Simulating the QRA64 decoder with fast-fading metric
|
||||
B90=10.00 Hz - Fading Model=Lorentz - Submode=QRA64C
|
||||
|
||||
K1JT decoder enabled for [K1JT ? ?/blank]
|
||||
K1JT decoder enabled for [K1JT IV3NWV ?]
|
||||
K1JT decoder enabled for [? IV3NWV ?/blank]
|
||||
K1JT decoder enabled for [K1JT IV3NWV JN66]
|
||||
K1JT decoder enabled for [CQ IV3NWV ?/b/JN66]
|
||||
|
||||
Encoding msg: [K1JT IV3NWV JN66]
|
||||
Decoding with K1JT's decoder
|
||||
....................................................................................................
|
||||
|
||||
Transimtted msgs:100
|
||||
Decoded msgs:
|
||||
|
||||
0 with [? ? ?] AP0
|
||||
0 with [CQ ? ?] AP27
|
||||
0 with [CQ ? ] AP42
|
||||
4 with [CALL ? ?] AP29
|
||||
0 with [CALL ? ] AP44
|
||||
0 with [CALL CALL ?] AP57
|
||||
2 with [? CALL ?] AP29
|
||||
0 with [? CALL ] AP44
|
||||
91 with [CALL CALL G] AP72
|
||||
0 with [CQ CALL ?] AP55
|
||||
0 with [CQ CALL ] AP70
|
||||
0 with [CQ CALL G] AP70
|
||||
|
||||
Total: 97/100 (0 undetected errors)
|
||||
|
||||
Estimated SNR (average in dB) = -28.39 dB
|
||||
|
||||
Input SNR = -28.0dB ap-mode=USER AP
|
||||
|
Loading…
Reference in New Issue
Block a user