mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2025-08-03 14:42:25 -04:00
Compare commits
717 Commits
wsjtx-2.6.
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
2b9d65408d | ||
|
c5a266b5e0 | ||
|
de9dc8e3fb | ||
|
5e410a982b | ||
|
2a9d0b6998 | ||
|
75f6b9b423 | ||
|
c7a93fca4a | ||
|
08785eff56 | ||
|
40fbc208fd | ||
|
1ac2fc23c3 | ||
|
d4a5ea60e6 | ||
|
86fd50304f | ||
|
75b4e0e798 | ||
|
ee68285583 | ||
|
ae50058498 | ||
|
587a16cd21 | ||
|
45151bda3b | ||
|
34b97b53f8 | ||
|
4c0d34477d | ||
|
72651037bd | ||
|
b83c41c8de | ||
|
ae61764af3 | ||
|
ae17011aa4 | ||
|
c228b6fe18 | ||
|
ffe1d11e99 | ||
|
3882953f51 | ||
|
3611f07ad6 | ||
|
98e48e00d3 | ||
|
20c41cf45b | ||
|
200168fd37 | ||
|
b7efe4d26d | ||
|
d67a406bf0 | ||
|
41407dad9f | ||
|
f59b5a48f7 | ||
|
c251764252 | ||
|
2655e41dd6 | ||
|
d4e2c21053 | ||
|
226b17d0ea | ||
|
495170e7a1 | ||
|
90b7ff7da9 | ||
|
aac9de3e4c | ||
|
e205bf0ca6 | ||
|
b84742b1fc | ||
|
7be1c34ea0 | ||
|
0705bd329e | ||
|
6474f7e1cf | ||
|
adc0345ef3 | ||
|
69a19946df | ||
|
4ec84087c7 | ||
|
05c3389307 | ||
|
9223ae3393 | ||
|
e178df928e | ||
|
8a2051e439 | ||
|
47c64f3675 | ||
|
d155abe274 | ||
|
9babd4616b | ||
|
e81cafa2c2 | ||
|
55286b05a9 | ||
|
b3d8750949 | ||
|
3a5da4b2ac | ||
|
ae64b71498 | ||
|
74f07211c3 | ||
|
db3c7c4668 | ||
|
14b60aa146 | ||
|
153c2e4212 | ||
|
9044718e36 | ||
|
cc9c1c62c9 | ||
|
8a899d000e | ||
|
6e6caa0d82 | ||
|
447127a49f | ||
|
24bfc9f30d | ||
|
9c45e510ff | ||
|
059096534b | ||
|
2f46104140 | ||
|
4af9c58bb0 | ||
|
ae1cf334e2 | ||
|
ff39abab58 | ||
|
f7e16671ab | ||
|
8be743e0b8 | ||
|
ae14fa13e9 | ||
|
9c3cc3d685 | ||
|
13a8efd533 | ||
|
80ed717aab | ||
|
8d17c7095c | ||
|
7a0a1736a7 | ||
|
f93d846c22 | ||
|
42f322e461 | ||
|
f98009daab | ||
|
c7e13191f1 | ||
|
2584b5ef3b | ||
|
6dc971d304 | ||
|
fbfc157e79 | ||
|
12042f6ae8 | ||
|
764fcaadcb | ||
|
53db514d42 | ||
|
e6fb080071 | ||
|
32c3cb7c4a | ||
|
faae78e0e6 | ||
|
bd4edcce49 | ||
|
07e82b0c40 | ||
|
d594d14a1e | ||
|
bb4564f734 | ||
|
9e0425ef40 | ||
|
c733c0c123 | ||
|
69f98d5c5c | ||
|
7f7a5322ed | ||
|
606506f578 | ||
|
4a4225bb9c | ||
|
b5bbf4a860 | ||
|
986eaf5d40 | ||
|
232c680a41 | ||
|
69f3186b13 | ||
|
05ed9c050d | ||
|
a4e7b915de | ||
|
a7b6798c99 | ||
|
a7cef9fc89 | ||
|
0d46c8a66e | ||
|
2a4ab7e92f | ||
|
f3be4b47fa | ||
|
fd0336f234 | ||
|
7276e86e60 | ||
|
5cc82189e6 | ||
|
ac0055b303 | ||
|
0f417374c3 | ||
|
ce2a4d2fe7 | ||
|
40cba29e5f | ||
|
f3308b7ee4 | ||
|
2c2deab91a | ||
|
6cab8c3da9 | ||
|
76007c8031 | ||
|
673f74e67b | ||
|
1d21dff93f | ||
|
3ebf72076c | ||
|
5bac396d60 | ||
|
efe8f090c2 | ||
|
1f0ddb92c5 | ||
|
887bc433ec | ||
|
3546fd4ba2 | ||
|
0eaf3360d8 | ||
|
115f850cd1 | ||
|
a4395c5d08 | ||
|
e0078bf01e | ||
|
e92d5ca1f5 | ||
|
fcee51cea8 | ||
|
f086aeb95a | ||
|
c1253954f6 | ||
|
c8cbb481a0 | ||
|
826fa8ae03 | ||
|
d3e9f3fc5a | ||
|
5bacc2d763 | ||
|
6b5db9fd0c | ||
|
08d9ebaf1a | ||
|
6ec9466dc1 | ||
|
cdb7b02835 | ||
|
031f7fc1e6 | ||
|
95daa2d791 | ||
|
b13c7d8dca | ||
|
171662ba50 | ||
|
4e935e01f3 | ||
|
9545c8eaa2 | ||
|
8f8f135e02 | ||
|
50bd14937f | ||
|
e42e995c59 | ||
|
2fb711401f | ||
|
889531fda6 | ||
|
e211bae779 | ||
|
517ca61f5c | ||
|
8be6d702d2 | ||
|
6f8c326717 | ||
|
35a1d37012 | ||
|
97fac57830 | ||
|
44bd5f9ac8 | ||
|
363e301e31 | ||
|
84ec6bb457 | ||
|
50519bc282 | ||
|
1f78fe5f2c | ||
|
20c090e2bc | ||
|
2e715fa47d | ||
|
d5a8ce97e3 | ||
|
bb5e8efd52 | ||
|
6afced7335 | ||
|
90f3c59ea0 | ||
|
f42a1bb357 | ||
|
9d5f3858d4 | ||
|
1aeaec7a6d | ||
|
186abfe99e | ||
|
c45420b194 | ||
|
1b3f4315b1 | ||
|
5e8deecdb4 | ||
|
7255a7c86a | ||
|
1542b7f857 | ||
|
9c7c837dc8 | ||
|
e040c926b9 | ||
|
11f8efd2a9 | ||
|
e2ef2c7dbb | ||
|
c413ea2f14 | ||
|
b0ea3a2eb5 | ||
|
717fd42ac1 | ||
|
d9cab59537 | ||
|
61fc069443 | ||
|
2f1082e973 | ||
|
adc457214f | ||
|
5d94775c7d | ||
|
91c0e43ef6 | ||
|
0cf01f1248 | ||
|
f525f08365 | ||
|
6019101018 | ||
|
115c4c4e30 | ||
|
ac1b5d03b2 | ||
|
6e9dc42881 | ||
|
e6fad89904 | ||
|
fe19a7263d | ||
|
57aca5c222 | ||
|
0d74918634 | ||
|
43019d0cb4 | ||
|
7622915147 | ||
|
62eb8fa3e9 | ||
|
8ae939b573 | ||
|
0455cf23e6 | ||
|
7f660d62fa | ||
|
bf861d9979 | ||
|
d62cdbaf2b | ||
|
ff2f2b00b9 | ||
|
cb7395b504 | ||
|
93dba5e623 | ||
|
05931313b3 | ||
|
7348bc323e | ||
|
76e28298a3 | ||
|
c6fb86067e | ||
|
711ea392ef | ||
|
456c5de125 | ||
|
c02b977c94 | ||
|
d8570e6817 | ||
|
74c6d9eb64 | ||
|
0456b3af8c | ||
|
bfd44f178a | ||
|
4a9c4dac6f | ||
|
f6989c3e6c | ||
|
5e9b9ff2d4 | ||
|
b986c7c81c | ||
|
330db0feb4 | ||
|
933aa29451 | ||
|
f394d77be7 | ||
|
5d3e927648 | ||
|
6546846f2c | ||
|
05ae0ee9af | ||
|
6156cf0d7d | ||
|
48ae40d781 | ||
|
60bcd6291d | ||
|
18b9dbf41b | ||
|
ce7a1c26fc | ||
|
3fcb8d3deb | ||
|
84069fe9e9 | ||
|
d4d47f8323 | ||
|
dece2e9fc5 | ||
|
c5969b0434 | ||
|
d76790adc3 | ||
|
b073fa0550 | ||
|
e8162970de | ||
|
97ed4022a2 | ||
|
893565f40d | ||
|
9913111464 | ||
|
ba453131eb | ||
|
2e3c37d7b2 | ||
|
bf70fae0bf | ||
|
64f53f30ff | ||
|
f75969ffb6 | ||
|
8ecdebaeba | ||
|
a3a02a8996 | ||
|
06d1469c10 | ||
|
ea8737e9f1 | ||
|
c65ebb16d5 | ||
|
b2a1c2d977 | ||
|
2ba2a580ff | ||
|
9a863d6590 | ||
|
b04e1517a9 | ||
|
3b03c9c824 | ||
|
2d9bebddbe | ||
|
fea274ed57 | ||
|
e4dca8e241 | ||
|
cbcf0c0ecd | ||
|
28d014e634 | ||
|
4f874b6507 | ||
|
630f0c34c3 | ||
|
c2883532ed | ||
|
ce2e94de26 | ||
|
88852bebe6 | ||
|
ec9682b57b | ||
|
68aae12588 | ||
|
99876a1916 | ||
|
54e46d90f2 | ||
|
4667929d0e | ||
|
256c0c8855 | ||
|
7f09f15f17 | ||
|
9125e8bdcc | ||
|
fc135f8e03 | ||
|
46676e4715 | ||
|
b697cd8ad1 | ||
|
60bc448413 | ||
|
60dbba359b | ||
|
c52ba84a49 | ||
|
596f9ba10f | ||
|
4671b9de0b | ||
|
383ff7e91a | ||
|
ca461d8f61 | ||
|
61ac076f7d | ||
|
be4b56139f | ||
|
72990e5cd3 | ||
|
72f3075836 | ||
|
1d881fcd25 | ||
|
6a151a63cc | ||
|
bf3fd11b28 | ||
|
1280dbe93a | ||
|
f3804569f2 | ||
|
79afbec133 | ||
|
0305d52671 | ||
|
a6a9c64ab0 | ||
|
05a50fe92a | ||
|
20eaa48ded | ||
|
84ce78e361 | ||
|
df8ef88501 | ||
|
cb70a45817 | ||
|
662af6ff7e | ||
|
7bb16bb9f4 | ||
|
3ce6674762 | ||
|
102af03057 | ||
|
dc35b4983e | ||
|
f9a93443ad | ||
|
2c98a4741e | ||
|
ea0ae2b18a | ||
|
efc1ac57fa | ||
|
df04b961e9 | ||
|
635b5f1ede | ||
|
5ea28b6103 | ||
|
3a6834baee | ||
|
f1b1af6e14 | ||
|
aff4469e84 | ||
|
cdff282c5c | ||
|
a97cebff4c | ||
|
e2085b0dd5 | ||
|
8ec78120a0 | ||
|
afd97aeb68 | ||
|
51539952b7 | ||
|
a7b489f373 | ||
|
cc22bd2819 | ||
|
db54472a5a | ||
|
d307193e0a | ||
|
7aa00f33a8 | ||
|
c348791b28 | ||
|
da8e6e92b3 | ||
|
21e377d363 | ||
|
d08a056c8e | ||
|
c249d1fe7b | ||
|
69f9c1f95d | ||
|
5d61d2bf17 | ||
|
a321348dfa | ||
|
570e9ceaf7 | ||
|
9151861c6d | ||
|
491f783224 | ||
|
a7413ae627 | ||
|
88b1e46ee4 | ||
|
b812ac2786 | ||
|
b8b0b73145 | ||
|
bc9d786cca | ||
|
ce8fef82c1 | ||
|
95b0669e55 | ||
|
507f5567b8 | ||
|
8f66be4253 | ||
|
e538469f8f | ||
|
58c4749ae3 | ||
|
36ced490a3 | ||
|
ee6cd7aa0e | ||
|
290dcd0b11 | ||
|
8723fea62b | ||
|
2b7a76232f | ||
|
eebababece | ||
|
4e7aa28ed4 | ||
|
4baca1ca60 | ||
|
715e8d1b14 | ||
|
19bc663abf | ||
|
d021c62d2f | ||
|
de0a3d60e3 | ||
|
7a6dbf60a5 | ||
|
67301c8402 | ||
|
a28316212b | ||
|
40ae967fa6 | ||
|
663ed60013 | ||
|
df3e922ed8 | ||
|
898b4edcdb | ||
|
ab3c24ee30 | ||
|
aac29fd2d4 | ||
|
82ed2b5872 | ||
|
29f6d50663 | ||
|
e9f43cf0ef | ||
|
8621b62b8b | ||
|
9dac5a2ef0 | ||
|
453b1577fc | ||
|
4c3bf37294 | ||
|
f45369af8d | ||
|
a215199fd1 | ||
|
f9b5d5a865 | ||
|
77f14560ff | ||
|
f15ad2b9a2 | ||
|
0493d03485 | ||
|
3dec36b9bd | ||
|
8cec7c7e2a | ||
|
e1865d4a4d | ||
|
a4adfcc149 | ||
|
9c953d1f2d | ||
|
9fadcad322 | ||
|
b54d7f2335 | ||
|
2375e2000c | ||
|
fb9fd768f8 | ||
|
04b49c1038 | ||
|
d58bd69884 | ||
|
0a243544d4 | ||
|
664194eb0c | ||
|
80d7de8839 | ||
|
fa1b5c55d1 | ||
|
df2728efb4 | ||
|
6a6647c5f8 | ||
|
5d0b580093 | ||
|
73e1198f08 | ||
|
631e3ed1cb | ||
|
3f7888a5c7 | ||
|
969411cd39 | ||
|
06f3b36939 | ||
|
dddb542a66 | ||
|
5ccf66e6b4 | ||
|
6be56a775e | ||
|
16f9f50263 | ||
|
92c9dd7fd6 | ||
|
d870c06b8e | ||
|
910b58ace8 | ||
|
1e96c8ae85 | ||
|
68e4671e00 | ||
|
3f5cbbb147 | ||
|
ce622487ca | ||
|
39c935a882 | ||
|
56dfb99a5d | ||
|
f1dbb8d134 | ||
|
bfeab39f8c | ||
|
b6bd9072d5 | ||
|
0eaf79020f | ||
|
86965dd96b | ||
|
f98bbabd27 | ||
|
96c7d6bf36 | ||
|
b61e8aeb24 | ||
|
c73fd39d47 | ||
|
f968c74093 | ||
|
5cdc476cbc | ||
|
280dd373d3 | ||
|
cd14778f0d | ||
|
4416c21f1b | ||
|
53bf3f4de1 | ||
|
20199c33b9 | ||
|
47aeb84c05 | ||
|
da3c63e739 | ||
|
f9d2ca736d | ||
|
b5f9e0ff03 | ||
|
6877a87fe4 | ||
|
37cd5b3ede | ||
|
f79e52a655 | ||
|
9d576c1bff | ||
|
b252abb462 | ||
|
7513a63ac5 | ||
|
aef5c198bb | ||
|
cbe674bedd | ||
|
0a139e5acd | ||
|
7bf6a6123d | ||
|
df2c767488 | ||
|
871198c44f | ||
|
31bc12e3b9 | ||
|
260f867cb9 | ||
|
d1a1578bc7 | ||
|
a83649a768 | ||
|
d6dd701601 | ||
|
88798f1ca3 | ||
|
8db7c2c128 | ||
|
0c0ecd893b | ||
|
1816e80707 | ||
|
43ca0b3f9c | ||
|
1b7830825a | ||
|
54709bdcaf | ||
|
5bd1ec3c49 | ||
|
b5a045c63b | ||
|
47a899465f | ||
|
019529d293 | ||
|
29360db01a | ||
|
46fdc79881 | ||
|
2d7b76ff03 | ||
|
3c3d3ebf3a | ||
|
ad4fb2be9d | ||
|
fb573ef407 | ||
|
6979a56d5d | ||
|
a87c308823 | ||
|
935ad492e6 | ||
|
86c863f288 | ||
|
0391144683 | ||
|
61c1d8bcc5 | ||
|
652bfb8429 | ||
|
e72b39a9d9 | ||
|
dd8c01f31c | ||
|
1795619b2c | ||
|
b1c82758ee | ||
|
41a1b4cf06 | ||
|
af5193014e | ||
|
1f438e6ba1 | ||
|
e0639169a9 | ||
|
646c353e5d | ||
|
f976d32013 | ||
|
f83db225f5 | ||
|
a76239dd76 | ||
|
afcb034956 | ||
|
aec42afda7 | ||
|
1fff588991 | ||
|
73db6eb28f | ||
|
d7859062bb | ||
|
0a439019b3 | ||
|
28a48ae6fc | ||
|
18e8c89a43 | ||
|
4ea595eea1 | ||
|
920b1a9b92 | ||
|
b8d20bd4de | ||
|
31bedb8528 | ||
|
96aa4fd85c | ||
|
70988919f0 | ||
|
e15d51f275 | ||
|
824478697b | ||
|
2992a37ae1 | ||
|
a4a3f95dac | ||
|
33a836242c | ||
|
21ef0c9d30 | ||
|
548eb1906b | ||
|
af04310f93 | ||
|
6f02c86d9a | ||
|
f4475740c1 | ||
|
4dd8dd456f | ||
|
be95a0c699 | ||
|
19182d3059 | ||
|
5ea9296944 | ||
|
0bf8193601 | ||
|
cfbb2ce1fe | ||
|
848a38f1b4 | ||
|
9ec349dd26 | ||
|
66c8390c61 | ||
|
8f159db056 | ||
|
fc040d435a | ||
|
3b0e2edb75 | ||
|
c0d327b4be | ||
|
53bbf4bf23 | ||
|
dd243da82a | ||
|
029977c619 | ||
|
3958f66fd2 | ||
|
c912088107 | ||
|
d821c87238 | ||
|
64753c3f7f | ||
|
3eec292986 | ||
|
ee497eecff | ||
|
ce8bc142f6 | ||
|
bb8663dce0 | ||
|
92d7f7c7de | ||
|
954d35bd52 | ||
|
90b49ddc0a | ||
|
88cbc521bd | ||
|
e0e7ac69fa | ||
|
b0e5ff0013 | ||
|
ceb80ac810 | ||
|
a085b5e390 | ||
|
e398b6a33d | ||
|
2716b3ed8a | ||
|
4b9763b982 | ||
|
c2fdba0b6e | ||
|
4ca2b2f219 | ||
|
8b165d81b8 | ||
|
291410f3c2 | ||
|
8dcb41c47e | ||
|
7105d67e2b | ||
|
6771bd7970 | ||
|
8d0186bd2a | ||
|
042ff589fb | ||
|
2fcf6c45fe | ||
|
5f94a115f7 | ||
|
e4dd4b98a8 | ||
|
58964d1f87 | ||
|
469caa7d0c | ||
|
1773a70d79 | ||
|
6f59ddeab1 | ||
|
cbad491438 | ||
|
ca9406664e | ||
|
90c1598f1e | ||
|
31524396d2 | ||
|
a60edeb607 | ||
|
439f17c123 | ||
|
b288b20289 | ||
|
388f61b45c | ||
|
8507f6ff46 | ||
|
68d036913a | ||
|
db00402aad | ||
|
f68d4e2e6f | ||
|
9d89042d44 | ||
|
01df4a8c1e | ||
|
815200acdf | ||
|
f024605d5a | ||
|
5579c0a729 | ||
|
d1d92334bd | ||
|
00d405137a | ||
|
516c83d4f9 | ||
|
63bc2a6495 | ||
|
d3be147d35 | ||
|
bb47b65e9b | ||
|
d9211aee28 | ||
|
079927a8d8 | ||
|
173aab72e7 | ||
|
1c75702420 | ||
|
504a62bf93 | ||
|
16214c2ff1 | ||
|
d808521b0f | ||
|
a3c7b421bd | ||
|
0e12c8f3f4 | ||
|
fc2273dc67 | ||
|
b9b9fe6412 | ||
|
7d63433fe4 | ||
|
d2034e7c71 | ||
|
7b3587fcfd | ||
|
12539d3efe | ||
|
39318e9d21 | ||
|
ecaa0b8861 | ||
|
97b58a387b | ||
|
bac3198f7f | ||
|
e7b5db7b8e | ||
|
4b4a6162d6 | ||
|
6ccd2a290b | ||
|
fed64b6d9f | ||
|
994e9ca929 | ||
|
d0ea461355 | ||
|
74c3d55e7f | ||
|
6cc2a50aa0 | ||
|
dc23772f9e | ||
|
33382c1c88 | ||
|
f83a5c6cbe | ||
|
d8093cf4dc | ||
|
9f1c616487 | ||
|
d26f8c1a30 | ||
|
0e416e5d1f | ||
|
1dba0e1602 | ||
|
4b3cc34fa5 | ||
|
689d852a49 | ||
|
61d9d45be1 | ||
|
1a5815f084 | ||
|
e26b2db967 | ||
|
ff56d9fa0b | ||
|
9ff1f9ff3f | ||
|
10c70d042c | ||
|
df21127af7 | ||
|
24859b0b3a | ||
|
fcee5057f2 | ||
|
5054fb9e4e | ||
|
f4412ea7e2 | ||
|
5344fa559c | ||
|
f519ff7592 | ||
|
86e9ecb651 | ||
|
df96e8dee3 | ||
|
df388a35f0 | ||
|
3a9bb0a22e | ||
|
c4288b143d | ||
|
4d51c4e0a8 | ||
|
defb89573f | ||
|
c1972fc2dd | ||
|
3dc206dc2b | ||
|
8c2fec1212 | ||
|
a7a53dc3ba | ||
|
1099837b50 | ||
|
c98eb2019f | ||
|
58075a4443 | ||
|
f88f5ddc7a | ||
|
29abbedfe8 | ||
|
c2352bd00a | ||
|
52b946f546 | ||
|
43c3a5ec26 | ||
|
61796515af | ||
|
7f6f260dc8 | ||
|
bac63c1ea7 | ||
|
50f2ef1931 | ||
|
ce23a1897b | ||
|
fa5a63df8a | ||
|
8a70f9c131 | ||
|
2a2bc4e69b | ||
|
cd5a925208 | ||
|
2a97ba420e | ||
|
532d36dc77 | ||
|
c3d8e96c8f | ||
|
e4a7f3a22a | ||
|
27f304752a | ||
|
053ba57dc4 | ||
|
17eae05c53 | ||
|
88f542cd36 | ||
|
9ba8ae0b9b | ||
|
de841889b5 | ||
|
adc04fd71e | ||
|
8731f9e75a | ||
|
4c83311f5a | ||
|
dec65a1b7a | ||
|
dc69832745 | ||
|
f7421feb62 | ||
|
c8e64db9d4 | ||
|
f216648c05 | ||
|
44729ebe00 | ||
|
4160256747 | ||
|
5daa5f301d | ||
|
32411d1fd0 | ||
|
0055222306 | ||
|
6c018cb53f | ||
|
51eb142f4c | ||
|
ef79bed994 | ||
|
3c8a8d518a | ||
|
1069e705d2 |
@ -45,7 +45,7 @@ if (POLICY CMP0075)
|
||||
endif ()
|
||||
|
||||
project (wsjtx
|
||||
VERSION 2.6.1.0
|
||||
VERSION 2.7.0.0
|
||||
LANGUAGES C CXX Fortran
|
||||
)
|
||||
set (PROJECT_DESCRIPTION "WSJT-X: Digital Modes for Weak Signal Communications in Amateur Radio")
|
||||
@ -71,7 +71,7 @@ message (STATUS "******************************************************")
|
||||
|
||||
include (set_build_type)
|
||||
# RC 0 or omitted is a development build, GA is a General Availability release build
|
||||
set_build_type (GA)
|
||||
set_build_type (RC 4)
|
||||
set (wsjtx_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}${BUILD_TYPE_REVISION}")
|
||||
|
||||
#
|
||||
@ -161,7 +161,6 @@ endif ()
|
||||
set (WSJT_PLUGIN_DESTINATION ${PLUGIN_DESTINATION} CACHE PATH "Path for plugins")
|
||||
set (WSJT_QT_CONF_DESTINATION ${QT_CONF_DESTINATION} CACHE PATH "Path for the qt.conf file")
|
||||
|
||||
|
||||
#
|
||||
# Project sources
|
||||
#
|
||||
@ -222,6 +221,7 @@ set (wsjt_qt_CXXSRCS
|
||||
widgets/DoubleClickablePushButton.cpp
|
||||
widgets/DoubleClickableRadioButton.cpp
|
||||
Network/LotWUsers.cpp
|
||||
Network/FileDownload.cpp
|
||||
models/DecodeHighlightingModel.cpp
|
||||
widgets/DecodeHighlightingListView.cpp
|
||||
models/FoxLog.cpp
|
||||
@ -327,6 +327,7 @@ set (wsjt_FSRCS
|
||||
lib/ft8_decode.f90
|
||||
lib/ft4_decode.f90
|
||||
lib/fst4_decode.f90
|
||||
lib/get_q3list.f90
|
||||
lib/jt9_decode.f90
|
||||
lib/options.f90
|
||||
lib/packjt.f90
|
||||
@ -361,6 +362,7 @@ set (wsjt_FSRCS
|
||||
lib/bpdecode128_90.f90
|
||||
lib/ft8/bpdecode174_91.f90
|
||||
lib/baddata.f90
|
||||
lib/cablog.f90
|
||||
lib/calibrate.f90
|
||||
lib/ccf2.f90
|
||||
lib/ccf65.f90
|
||||
@ -490,6 +492,7 @@ set (wsjt_FSRCS
|
||||
lib/msk144sim.f90
|
||||
lib/mskrtd.f90
|
||||
lib/nuttal_window.f90
|
||||
lib/decode_msk144.f90
|
||||
lib/ft4/ft4sim.f90
|
||||
lib/ft4/ft4sim_mult.f90
|
||||
lib/ft4/ft4_downsample.f90
|
||||
@ -509,6 +512,7 @@ set (wsjt_FSRCS
|
||||
lib/qra/q65/q65_ap.f90
|
||||
lib/qra/q65/q65_loops.f90
|
||||
lib/qra/q65/q65_set_list.f90
|
||||
lib/qra/q65/q65_set_list2.f90
|
||||
lib/refspectrum.f90
|
||||
lib/savec2.f90
|
||||
lib/save_dxbase.f90
|
||||
@ -580,6 +584,7 @@ set (wsjt_FSRCS
|
||||
lib/fst4/fastosd240_74.f90
|
||||
lib/fst4/get_crc24.f90
|
||||
lib/fst4/fst4_baseline.f90
|
||||
lib/77bit/hash22calc.f90
|
||||
)
|
||||
|
||||
# temporary workaround for a gfortran v7.3 ICE on Fedora 27 64-bit
|
||||
@ -972,7 +977,10 @@ if (Fortran_COMPILER_NAME MATCHES "gfortran.*")
|
||||
|
||||
set (CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -fbounds-check -funroll-all-loops -fno-f2c -ffpe-summary=invalid,zero,overflow,underflow ${General_FFLAGS}")
|
||||
|
||||
set (CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -g -fbacktrace -fbounds-check -fno-f2c -ffpe-summary=invalid,zero,overflow,underflow ${General_FFLAGS}")
|
||||
### TEMPORARY: Let Fortran use RElEASE flags for DEBUG builds
|
||||
#set (CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -g -fbacktrace -fbounds-check -fno-f2c -ffpe-summary=invalid,zero,overflow,underflow ${General_FFLAGS}")
|
||||
set (CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_RELEASE} -fbounds-check -funroll-all-loops -fno-f2c -ffpe-summary=invalid,zero,overflow,underflow ${General_FFLAGS}")
|
||||
|
||||
|
||||
# FPE traps currently disabled in Debug configuration builds until
|
||||
# we decide if they are meaningful, without these FP instructions
|
||||
@ -1136,6 +1144,9 @@ target_link_libraries (jt65sim wsjt_fort wsjt_cxx)
|
||||
add_executable (sumsim lib/sumsim.f90)
|
||||
target_link_libraries (sumsim wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (cablog lib/cablog.f90)
|
||||
target_link_libraries (cablog)
|
||||
|
||||
add_executable (test_snr lib/test_snr.f90)
|
||||
target_link_libraries (test_snr wsjt_fort)
|
||||
|
||||
@ -1172,6 +1183,9 @@ target_link_libraries (wsprcode wsjt_fort wsjt_cxx)
|
||||
add_executable (encode77 lib/77bit/encode77.f90)
|
||||
target_link_libraries (encode77 wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (hash22calc lib/77bit/hash22calc.f90)
|
||||
target_link_libraries (hash22calc wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (wsprsim ${wsprsim_CSRCS})
|
||||
target_link_libraries (wsprsim ${LIBM_LIBRARIES})
|
||||
|
||||
@ -1420,10 +1434,10 @@ else (${OPENMP_FOUND} OR APPLE)
|
||||
endif (${OPENMP_FOUND} OR APPLE)
|
||||
|
||||
if (WIN32)
|
||||
# build map65
|
||||
find_package (Portaudio REQUIRED)
|
||||
add_subdirectory (map65)
|
||||
endif ()
|
||||
add_subdirectory (qmap)
|
||||
|
||||
# build the main application
|
||||
generate_version_info (wsjtx_VERSION_RESOURCES
|
||||
@ -1589,7 +1603,7 @@ install (TARGETS jt9 wsprd fmtave fcal fmeasure
|
||||
|
||||
if(WSJT_BUILD_UTILS)
|
||||
install (TARGETS ft8code jt65code jt9code jt4code msk144code
|
||||
q65code fst4sim q65sim echosim
|
||||
q65code fst4sim q65sim echosim hash22calc cablog
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
|
||||
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
|
||||
)
|
||||
@ -1631,6 +1645,7 @@ install (FILES
|
||||
cty.dat
|
||||
cty.dat_copyright.txt
|
||||
contrib/Ephemeris/JPLEPH
|
||||
eclipse.txt
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}
|
||||
#COMPONENT runtime
|
||||
)
|
||||
|
@ -173,7 +173,6 @@
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
|
||||
|
||||
#include "pimpl_impl.hpp"
|
||||
#include "Logger.hpp"
|
||||
#include "qt_helpers.hpp"
|
||||
@ -201,6 +200,7 @@
|
||||
#include "models/DecodeHighlightingModel.hpp"
|
||||
#include "logbook/logbook.h"
|
||||
#include "widgets/LazyFillComboBox.hpp"
|
||||
#include "Network/FileDownload.hpp"
|
||||
|
||||
#include "ui_Configuration.h"
|
||||
#include "moc_Configuration.cpp"
|
||||
@ -244,6 +244,9 @@ namespace
|
||||
|X85|X86|X87|X88|X89|X90|X91
|
||||
|X92|X93|X94|X95|X96|X97|X98
|
||||
|X99
|
||||
|[0][0][0][1-9] # 4-digit numbers
|
||||
|[0][0-9][1-9][0-9] # between 0001
|
||||
|[1-7][0-9][0-9][0-9] # and 7999
|
||||
)
|
||||
)", QRegularExpression::CaseInsensitiveOption | QRegularExpression::ExtendedPatternSyntaxOption};
|
||||
|
||||
@ -276,7 +279,6 @@ namespace
|
||||
constexpr quint32 qrg_version_100 {100};
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Dialog to get a new Frequency item
|
||||
//
|
||||
@ -329,9 +331,9 @@ public:
|
||||
|
||||
connect (button_box, &QDialogButtonBox::accepted, this, &FrequencyDialog::accept);
|
||||
connect (button_box, &QDialogButtonBox::rejected, this, &FrequencyDialog::reject);
|
||||
connect(start_date_time_edit_, &QDateTimeEdit::dateTimeChanged, this, &FrequencyDialog::checkSaneDates);
|
||||
connect(end_date_time_edit_, &QDateTimeEdit::dateTimeChanged, this, &FrequencyDialog::checkSaneDates);
|
||||
connect(enable_dates_checkbox_, &QCheckBox::stateChanged, this, &FrequencyDialog::toggleValidity);
|
||||
connect (start_date_time_edit_, &QDateTimeEdit::dateTimeChanged, this, &FrequencyDialog::checkSaneDates);
|
||||
connect (end_date_time_edit_, &QDateTimeEdit::dateTimeChanged, this, &FrequencyDialog::checkSaneDates);
|
||||
connect (enable_dates_checkbox_, &QCheckBox::stateChanged, this, &FrequencyDialog::toggleValidity);
|
||||
toggleValidity();
|
||||
}
|
||||
|
||||
@ -384,7 +386,6 @@ private:
|
||||
QDateTimeEdit *start_date_time_edit_;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Dialog to get a new Station item
|
||||
//
|
||||
@ -457,9 +458,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// Internal implementation of the Configuration class.
|
||||
class Configuration::impl final
|
||||
: public QDialog
|
||||
@ -564,6 +562,9 @@ private:
|
||||
Q_SLOT void on_add_macro_line_edit_editingFinished ();
|
||||
Q_SLOT void delete_macro ();
|
||||
void delete_selected_macros (QModelIndexList);
|
||||
void after_CTY_downloaded();
|
||||
void set_CTY_DAT_version(QString const& version);
|
||||
void error_during_CTY_download (QString const& reason);
|
||||
Q_SLOT void on_udp_server_line_edit_textChanged (QString const&);
|
||||
Q_SLOT void on_udp_server_line_edit_editingFinished ();
|
||||
Q_SLOT void on_save_path_select_push_button_clicked (bool);
|
||||
@ -574,7 +575,14 @@ private:
|
||||
Q_SLOT void handle_transceiver_failure (QString const& reason);
|
||||
Q_SLOT void on_reset_highlighting_to_defaults_push_button_clicked (bool);
|
||||
Q_SLOT void on_rescan_log_push_button_clicked (bool);
|
||||
Q_SLOT void on_CTY_download_button_clicked (bool);
|
||||
Q_SLOT void on_LotW_CSV_fetch_push_button_clicked (bool);
|
||||
Q_SLOT void on_hamlib_download_button_clicked (bool);
|
||||
Q_SLOT void on_revert_update_button_clicked (bool);
|
||||
void error_during_hamlib_download (QString const& reason);
|
||||
void after_hamlib_downloaded();
|
||||
void display_file_information();
|
||||
|
||||
Q_SLOT void on_cbx2ToneSpacing_clicked(bool);
|
||||
Q_SLOT void on_cbx4ToneSpacing_clicked(bool);
|
||||
Q_SLOT void on_prompt_to_log_check_box_clicked(bool);
|
||||
@ -678,6 +686,7 @@ private:
|
||||
QString FD_exchange_;
|
||||
QString RTTY_exchange_;
|
||||
QString Contest_Name_;
|
||||
QString hamlib_backed_up_;
|
||||
|
||||
qint32 id_interval_;
|
||||
qint32 ntrials_;
|
||||
@ -746,13 +755,12 @@ private:
|
||||
QAudioDeviceInfo next_audio_output_device_;
|
||||
AudioDevice::Channel audio_output_channel_;
|
||||
AudioDevice::Channel next_audio_output_channel_;
|
||||
|
||||
FileDownload cty_download;
|
||||
friend class Configuration;
|
||||
};
|
||||
|
||||
#include "Configuration.moc"
|
||||
|
||||
|
||||
// delegate to implementation class
|
||||
Configuration::Configuration (QNetworkAccessManager * network_manager, QDir const& temp_directory,
|
||||
QSettings * settings, LogBook * logbook, QWidget * parent)
|
||||
@ -859,6 +867,11 @@ bool Configuration::highlight_73 () const {return m_->highlight_73_;}
|
||||
bool Configuration::highlight_DXcall () const {return m_->highlight_DXcall_;}
|
||||
bool Configuration::highlight_DXgrid () const {return m_->highlight_DXgrid_;}
|
||||
|
||||
void Configuration::set_CTY_DAT_version(QString const& version)
|
||||
{
|
||||
m_->set_CTY_DAT_version(version);
|
||||
}
|
||||
|
||||
void Configuration::set_calibration (CalibrationParams params)
|
||||
{
|
||||
m_->calibration_ = params;
|
||||
@ -997,6 +1010,15 @@ void Configuration::set_location (QString const& grid_descriptor)
|
||||
m_->dynamic_grid_ = grid_descriptor.trimmed ();
|
||||
}
|
||||
|
||||
void Configuration::setSpecial_Q65_Pileup()
|
||||
{
|
||||
m_->bSpecialOp_=true;
|
||||
m_->ui_->gbSpecialOpActivity->setChecked(m_->bSpecialOp_);
|
||||
m_->ui_->rbQ65pileup->setChecked(true);
|
||||
m_->SelectedActivity_ = static_cast<int> (SpecialOperatingActivity::Q65_PILEUP);
|
||||
m_->write_settings();
|
||||
}
|
||||
|
||||
void Configuration::setSpecial_Hound()
|
||||
{
|
||||
m_->bSpecialOp_=true;
|
||||
@ -1019,6 +1041,7 @@ void Configuration::setSpecial_None()
|
||||
{
|
||||
m_->bSpecialOp_=false;
|
||||
m_->ui_->gbSpecialOpActivity->setChecked(m_->bSpecialOp_);
|
||||
m_->SelectedActivity_ = static_cast<int> (SpecialOperatingActivity::HOUND); // brings backward compatibility to versions without Q65_PILEUP
|
||||
m_->write_settings();
|
||||
}
|
||||
namespace
|
||||
@ -1174,8 +1197,13 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network
|
||||
|
||||
// set up LoTW users CSV file fetching
|
||||
connect (&lotw_users_, &LotWUsers::load_finished, [this] () {
|
||||
ui_->LotW_CSV_fetch_push_button->setEnabled (true);
|
||||
});
|
||||
ui_->LotW_CSV_fetch_push_button->setEnabled (true);
|
||||
});
|
||||
|
||||
connect(&lotw_users_, &LotWUsers::progress, [this] (QString const& msg) {
|
||||
ui_->LotW_CSV_status_label->setText(msg);
|
||||
});
|
||||
|
||||
lotw_users_.set_local_file_path (writeable_data_dir_.absoluteFilePath ("lotw-user-activity.csv"));
|
||||
|
||||
//
|
||||
@ -1227,6 +1255,7 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network
|
||||
ui_->special_op_activity_button_group->setId (ui_->rbARRL_Digi, static_cast<int> (SpecialOperatingActivity::ARRL_DIGI));
|
||||
ui_->special_op_activity_button_group->setId (ui_->rbFox, static_cast<int> (SpecialOperatingActivity::FOX));
|
||||
ui_->special_op_activity_button_group->setId (ui_->rbHound, static_cast<int> (SpecialOperatingActivity::HOUND));
|
||||
ui_->special_op_activity_button_group->setId (ui_->rbQ65pileup, static_cast<int> (SpecialOperatingActivity::Q65_PILEUP));
|
||||
|
||||
//
|
||||
// setup PTT port combo box drop down content
|
||||
@ -1542,6 +1571,9 @@ void Configuration::impl::read_settings ()
|
||||
Contest_Name_ = settings_->value ("Contest_Name",QString {}).toString ();
|
||||
ui_->Field_Day_Exchange->setText(FD_exchange_);
|
||||
ui_->RTTY_Exchange->setText(RTTY_exchange_);
|
||||
ui_->Contest_Name->setText(Contest_Name_);
|
||||
hamlib_backed_up_ = settings_->value ("HamlibBackedUp",QString {}).toString ();
|
||||
|
||||
if (next_font_.fromString (settings_->value ("Font", QGuiApplication::font ().toString ()).toString ())
|
||||
&& next_font_ != font_)
|
||||
{
|
||||
@ -1717,6 +1749,18 @@ void Configuration::impl::read_settings ()
|
||||
pwrBandTuneMemory_ = settings_->value("pwrBandTuneMemory",false).toBool ();
|
||||
highlight_DXcall_ = settings_->value("highlight_DXcall",false).toBool ();
|
||||
highlight_DXgrid_ = settings_->value("highlight_DXgrid",false).toBool ();
|
||||
#ifdef WIN32
|
||||
QTimer::singleShot (2500, [=] {display_file_information ();});
|
||||
#else
|
||||
ui_->hamlib_groupBox->setTitle("Hamlib Version");
|
||||
ui_->rbHamlib64->setVisible(false);
|
||||
ui_->rbHamlib32->setVisible(false);
|
||||
ui_->hamlib_download_button->setVisible(false);
|
||||
ui_->revert_update_button->setVisible(false);
|
||||
ui_->backed_up_text->setVisible(false);
|
||||
ui_->backed_up->setVisible(false);
|
||||
QTimer::singleShot (2500, [=] {display_file_information ();});
|
||||
#endif
|
||||
}
|
||||
|
||||
void Configuration::impl::find_audio_devices ()
|
||||
@ -2402,9 +2446,45 @@ void Configuration::impl::on_reset_highlighting_to_defaults_push_button_clicked
|
||||
|
||||
void Configuration::impl::on_rescan_log_push_button_clicked (bool /*clicked*/)
|
||||
{
|
||||
if (logbook_) logbook_->rescan ();
|
||||
if (logbook_) {
|
||||
logbook_->rescan ();
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::impl::on_CTY_download_button_clicked (bool /*clicked*/)
|
||||
{
|
||||
ui_->CTY_download_button->setEnabled (false); // disable button until download is complete
|
||||
QDir dataPath {QStandardPaths::writableLocation (QStandardPaths::DataLocation)};
|
||||
cty_download.configure(network_manager_,
|
||||
"http://www.country-files.com/bigcty/cty.dat",
|
||||
dataPath.absoluteFilePath("cty.dat"),
|
||||
"WSJT-X CTY Downloader");
|
||||
|
||||
// set up LoTW users CSV file fetching
|
||||
connect (&cty_download, &FileDownload::complete, this, &Configuration::impl::after_CTY_downloaded, Qt::UniqueConnection);
|
||||
connect (&cty_download, &FileDownload::error, this, &Configuration::impl::error_during_CTY_download, Qt::UniqueConnection);
|
||||
|
||||
cty_download.start_download();
|
||||
}
|
||||
void Configuration::impl::set_CTY_DAT_version(QString const& version)
|
||||
{
|
||||
ui_->CTY_file_label->setText(QString{"CTY File Version: %1"}.arg(version));
|
||||
}
|
||||
|
||||
void Configuration::impl::error_during_CTY_download (QString const& reason)
|
||||
{
|
||||
MessageBox::warning_message (this, tr ("Error Loading CTY.DAT"), reason);
|
||||
after_CTY_downloaded();
|
||||
}
|
||||
|
||||
void Configuration::impl::after_CTY_downloaded ()
|
||||
{
|
||||
ui_->CTY_download_button->setEnabled (true);
|
||||
if (logbook_) {
|
||||
logbook_->rescan ();
|
||||
ui_->CTY_file_label->setText(QString{"CTY File Version: %1"}.arg(logbook_->cty_version()));
|
||||
}
|
||||
}
|
||||
void Configuration::impl::on_LotW_CSV_fetch_push_button_clicked (bool /*checked*/)
|
||||
{
|
||||
lotw_users_.load (ui_->LotW_CSV_URL_line_edit->text (), true, true);
|
||||
@ -2419,6 +2499,113 @@ void Configuration::impl::on_decoded_text_font_push_button_clicked ()
|
||||
);
|
||||
}
|
||||
|
||||
void Configuration::impl::on_hamlib_download_button_clicked (bool /*clicked*/)
|
||||
{
|
||||
#ifdef WIN32
|
||||
extern char* hamlib_version2;
|
||||
QString hamlib = QString(QLatin1String(hamlib_version2));
|
||||
SettingsGroup g {settings_, "Configuration"};
|
||||
settings_->setValue ("HamlibBackedUp", hamlib);
|
||||
settings_->sync ();
|
||||
QDir dataPath = QCoreApplication::applicationDirPath();
|
||||
QFile f1 {dataPath.absolutePath() + "/" + "libhamlib-4_old.dll"};
|
||||
QFile f2 {dataPath.absolutePath() + "/" + "libhamlib-4_new.dll"};
|
||||
if (f1.exists()) f1.remove();
|
||||
if (f2.exists()) f2.remove();
|
||||
ui_->hamlib_download_button->setEnabled (false);
|
||||
ui_->revert_update_button->setEnabled (false);
|
||||
if (ui_->rbHamlib32->isChecked()) {
|
||||
cty_download.configure(network_manager_,
|
||||
"https://n0nb.users.sourceforge.net/dll32/libhamlib-4.dll",
|
||||
dataPath.absoluteFilePath("libhamlib-4_new.dll"),
|
||||
"Downloading latest libhamlib-4.dll");
|
||||
} else {
|
||||
cty_download.configure(network_manager_,
|
||||
"https://n0nb.users.sourceforge.net/dll64/libhamlib-4.dll",
|
||||
dataPath.absoluteFilePath("libhamlib-4_new.dll"),
|
||||
"Downloading latest libhamlib-4.dll");
|
||||
}
|
||||
connect (&cty_download, &FileDownload::complete, this, &Configuration::impl::after_hamlib_downloaded, Qt::UniqueConnection);
|
||||
connect (&cty_download, &FileDownload::error, this, &Configuration::impl::error_during_hamlib_download, Qt::UniqueConnection);
|
||||
cty_download.start_download();
|
||||
#else
|
||||
MessageBox::warning_message (this, tr ("Hamlib update only available on Windows."));
|
||||
#endif
|
||||
}
|
||||
|
||||
void Configuration::impl::error_during_hamlib_download (QString const& reason)
|
||||
{
|
||||
QDir dataPath = QCoreApplication::applicationDirPath();
|
||||
MessageBox::warning_message (this, tr ("Error Loading libhamlib-4.dll"), reason);
|
||||
ui_->hamlib_download_button->setEnabled (true);
|
||||
ui_->revert_update_button->setEnabled (true);
|
||||
}
|
||||
|
||||
void Configuration::impl::after_hamlib_downloaded ()
|
||||
{
|
||||
QDir dataPath = QCoreApplication::applicationDirPath();
|
||||
QFile::rename(dataPath.absolutePath() + "/" + "libhamlib-4.dll", dataPath.absolutePath() + "/" + "libhamlib-4_old.dll");
|
||||
QTimer::singleShot (1000, [=] {
|
||||
QFile::rename(dataPath.absolutePath() + "/" + "libhamlib-4_new.dll", dataPath.absolutePath() + "/" + "libhamlib-4.dll");
|
||||
});
|
||||
QTimer::singleShot (2000, [=] {
|
||||
MessageBox::information_message (this, tr ("Hamlib Update successful \n\nNew Hamlib will be used after restart"));
|
||||
ui_->revert_update_button->setEnabled (true);
|
||||
ui_->hamlib_download_button->setEnabled (true);
|
||||
});
|
||||
}
|
||||
|
||||
void Configuration::impl::on_revert_update_button_clicked (bool /*clicked*/)
|
||||
{
|
||||
#ifdef WIN32
|
||||
QDir dataPath = QCoreApplication::applicationDirPath();
|
||||
QFile f {dataPath.absolutePath() + "/" + "libhamlib-4_old.dll"};
|
||||
if (f.exists()) {
|
||||
ui_->revert_update_button->setEnabled (false);
|
||||
ui_->hamlib_download_button->setEnabled (false);
|
||||
QFile::rename(dataPath.absolutePath() + "/" + "libhamlib-4.dll", dataPath.absolutePath() + "/" + "libhamlib-4_new.dll");
|
||||
QTimer::singleShot (1000, [=] {
|
||||
QFile::copy(dataPath.absolutePath() + "/" + "libhamlib-4_old.dll", dataPath.absolutePath() + "/" + "libhamlib-4.dll");
|
||||
});
|
||||
QTimer::singleShot (2000, [=] {
|
||||
MessageBox::information_message (this, tr ("Hamlib successfully reverted \n\nReverted Hamlib will be used after restart"));
|
||||
ui_->revert_update_button->setEnabled (true);
|
||||
ui_->hamlib_download_button->setEnabled (true);
|
||||
});
|
||||
} else {
|
||||
MessageBox::warning_message (this, tr ("No Hamlib update found that could be reverted"));
|
||||
}
|
||||
#else
|
||||
MessageBox::warning_message (this, tr ("Hamlib update only available on Windows."));
|
||||
#endif
|
||||
}
|
||||
|
||||
void Configuration::impl::display_file_information ()
|
||||
{
|
||||
#ifdef WIN32
|
||||
QDir dataPath = QCoreApplication::applicationDirPath();
|
||||
extern char* hamlib_version2;
|
||||
QString hamlib = QString(QLatin1String(hamlib_version2));
|
||||
ui_->in_use->setText(hamlib);
|
||||
QFileInfo fi2(dataPath.absolutePath() + "/" + "libhamlib-4_old.dll");
|
||||
QString birthTime2 = fi2.birthTime().toString("yyyy-MM-dd hh:mm");
|
||||
QFile f {dataPath.absolutePath() + "/" + "libhamlib-4_old.dll"};
|
||||
if (f.exists()) {
|
||||
if (hamlib_backed_up_=="") {
|
||||
ui_->backed_up->setText(QString{"no hamlib data available, file saved %1"}.arg(birthTime2));
|
||||
} else {
|
||||
ui_->backed_up->setText(hamlib_backed_up_);
|
||||
}
|
||||
} else {
|
||||
ui_->backed_up->setText("");
|
||||
}
|
||||
#else
|
||||
extern char* hamlib_version2;
|
||||
QString hamlib = QString(QLatin1String(hamlib_version2));
|
||||
ui_->in_use->setText(hamlib);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Configuration::impl::on_PTT_port_combo_box_activated (int /* index */)
|
||||
{
|
||||
set_rig_invariants ();
|
||||
|
@ -183,6 +183,7 @@ public:
|
||||
bool highlight_only_fields () const;
|
||||
bool include_WAE_entities () const;
|
||||
bool highlight_73 () const;
|
||||
void setSpecial_Q65_Pileup();
|
||||
void setSpecial_Hound();
|
||||
void setSpecial_Fox();
|
||||
void setSpecial_None();
|
||||
@ -190,8 +191,8 @@ public:
|
||||
bool highlight_DXgrid () const;
|
||||
bool Individual_Contest_Name() const;
|
||||
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
enum class SpecialOperatingActivity {NONE, NA_VHF, EU_VHF, FIELD_DAY, RTTY, WW_DIGI, FOX, HOUND, ARRL_DIGI};
|
||||
// 0 1 2 3 4 5 6 7 8 9
|
||||
enum class SpecialOperatingActivity {NONE, NA_VHF, EU_VHF, FIELD_DAY, RTTY, WW_DIGI, FOX, HOUND, ARRL_DIGI, Q65_PILEUP};
|
||||
SpecialOperatingActivity special_op_id () const;
|
||||
|
||||
struct CalibrationParams
|
||||
@ -224,8 +225,7 @@ public:
|
||||
// This method queries if a CAT and PTT connection is operational.
|
||||
bool is_transceiver_online () const;
|
||||
|
||||
// Start the rig connection, safe and normal to call when rig is
|
||||
// already open.
|
||||
// Start the rig connection, safe and normal to call when rig is already open.
|
||||
bool transceiver_online ();
|
||||
|
||||
// check if a real rig is configured
|
||||
@ -243,6 +243,8 @@ public:
|
||||
// Close down connection to rig.
|
||||
void transceiver_offline ();
|
||||
|
||||
void set_CTY_DAT_version(QString const& version);
|
||||
|
||||
// Set transceiver frequency in Hertz.
|
||||
Q_SLOT void transceiver_frequency (Frequency);
|
||||
|
||||
|
912
Configuration.ui
912
Configuration.ui
File diff suppressed because it is too large
Load Diff
@ -6,27 +6,34 @@ you change the name in the Applications folder from WSJT-X to WSJT-X_previous
|
||||
before proceeding.
|
||||
|
||||
I recommend that you follow the installation instructions especially if you
|
||||
are moving from v2.3 to v2.4 or later, of WSJT-X or you have upgraded macOS.
|
||||
are moving from v2.5 to v2.6 or later, of WSJT-X or you have upgraded macOS.
|
||||
|
||||
Double-click on the wsjtx-...-Darwin.dmg file you have downloaded from K1JT's web-site.
|
||||
Make sure that you leave this window open for the remaining installation steps.
|
||||
|
||||
Now open a Terminal window by going to Applications->Utilities and clicking on Terminal.
|
||||
|
||||
Along with this ReadMe file there is a file: com.wsjtx.sysctl.plist which must be copied to a
|
||||
system area by typing this line in the Terminal window and then pressing the Return key.
|
||||
system area by typing these lines in the Terminal window and then pressing the Return key after
|
||||
each line.
|
||||
|
||||
sudo cp /Volumes/WSJT-X/com.wsjtx.sysctl.plist /Library/LaunchDaemons
|
||||
sudo chown root:wheel /Library/LaunchDaemons/com.wsjtx.sysctl.plist
|
||||
|
||||
you will be asked for your normal password because authorisation is needed to copy this file.
|
||||
(Your password will not be echoed but press the Return key when completed.)
|
||||
Now re-boot your Mac. This is necessary to install the changes. After the
|
||||
reboot you should re-open the Terminal window as before and you can check that the
|
||||
change has been made by typing:
|
||||
|
||||
IMPORTANT: Now re-boot your Mac otherwise these changes will not take effect.
|
||||
|
||||
After the reboot you should re-open the Terminal window as before and you can check
|
||||
that the change has been made by typing:
|
||||
|
||||
sysctl -a | grep sysv.shm
|
||||
|
||||
If shmmax is not shown as 52428800 then contact me since WSJT-X might fail to load with
|
||||
an error message: "Unable to create shared memory segment".
|
||||
If shmmax is not shown as 52428800 then contact me since WSJT-X will fail to load with
|
||||
an error message: "Unable to create shared memory segment". If the value of shmmax
|
||||
is shown as 20971520 then it is probable that you have download JTDX. WSJT-X and JTDX
|
||||
cannot both control the shmmax paramter. Contact me for advice.
|
||||
|
||||
You can now close the Terminal window. It will not be necessary to repeat this procedure
|
||||
again, even when you download an updated version of WSJT-X. It might be necessary if you
|
||||
@ -58,8 +65,17 @@ and how to access them.
|
||||
Finally, visit the Radio panel. WSJT-X is most effective when operated with CAT
|
||||
control. You will need to install the relevant Mac device driver for your rig,
|
||||
and then re-launch WSJT-X. Return to the Radio panel in Preferences and in
|
||||
the "Serial port" panel select your driver from the list that is presented. If you
|
||||
do not know where to get an appropriate driver, contact me.
|
||||
the "Serial port" panel select your driver from the list that is presented.
|
||||
|
||||
You may need a device driver for your Mac. The USB/UART Bridge chip inside the Icom,
|
||||
Yaesu and Kenwood radios is a Silicon Labs USB to UART Bridge Controller and the Mac
|
||||
drivers are available here:
|
||||
|
||||
https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers
|
||||
|
||||
Visit the SiLabs site and download v6 for a Mac. Then in WSJT-X if you use the drop-down menu
|
||||
for Serial Port you should see something like /dev/tty.SLAB_USBtoUART if the driver has been
|
||||
installed correctly. Make sure you read the release notes that come with the driver.
|
||||
|
||||
WSJT-X needs the Mac clock to be accurate. Visit System Preferences > Date & Time
|
||||
and make sure that Date and Time are set automatically. The drop-down menu will
|
||||
@ -72,9 +88,7 @@ Please email me if you have problems.
|
||||
|
||||
--- John G4KLA (g4kla@rmnjmn.co.uk)
|
||||
|
||||
Additional Notes:
|
||||
|
||||
1. Information about com.wsjtx.sysctl.plist and multiple instances of WSJT-X
|
||||
Addendum: Information about com.wsjtx.sysctl.plist and multiple instances of WSJT-X.
|
||||
|
||||
WSJT-X makes use of a block of memory which is shared between different parts of
|
||||
the code. The normal allocation of shared memory on a Mac is insufficient and this
|
||||
@ -99,15 +113,10 @@ be changed.
|
||||
If two instances of WSJT-X are running, it is likely that you might need additional
|
||||
audio devices, from two rigs for example. Visit Audio MIDI Setup and create an Aggregate Device
|
||||
which will allow you to specify more than one interface. I recommend you consult Apple's guide
|
||||
on combining multiple audio interfaces which is at https://support.apple.com/en-us/HT202000.
|
||||
on combining multiple audio interfaces which is at https://support.apple.com/en-us/HT202000.
|
||||
|
||||
2. Preventing WSJT-X from being put into 'sleep' mode (App Nap).
|
||||
|
||||
In normal circumstances an application which has not been directly accessed for a while can be
|
||||
In normal circumstances an application which has not been directly accessed for a while can be
|
||||
subject to App Nap which means it is suspended until such time as its windows are accessed. If
|
||||
it is intended that WSJT-X should be submitting continued reports to, for example, PSK Reporter
|
||||
then reporting will be interrupted. App Nap can be disabled as follows, but first quit WSJT-X:
|
||||
|
||||
Open a Terminal window and type: defaults write org.k1jt.wsjtx NSAppSleepDisable -bool YES
|
||||
If you type: defaults read org.k1jt.wsjtx then the response will be: NSAppSleepDisable = 1;
|
||||
Close the Terminal window and launch WSJT-X. (If you 'Hide' WSJT-X, this scheme will be suspended.)
|
||||
|
36
INSTALL
36
INSTALL
@ -16,8 +16,7 @@ Installing WSJT-X
|
||||
|
||||
Binary packages of WSJT-X are available from the project web site:
|
||||
|
||||
http://www.physics.princeton.edu/pulsar/K1JT/wsjtx.html
|
||||
|
||||
https://wsjt.sourceforge.io/wsjtx.html
|
||||
|
||||
Building from Source
|
||||
====================
|
||||
@ -28,7 +27,7 @@ the Boost C++ libraries. For MS Windows see the section "Building
|
||||
from Source on MS Windows" below. For Apple Mac see the section
|
||||
"Building from Source on Apple Mac".
|
||||
|
||||
Qt v5, preferably v5.9 or later is required to build WSJT-X.
|
||||
Qt v5, preferably v5.12 or later is required to build WSJT-X.
|
||||
|
||||
Qt v5 multimedia support, serial port, and Linguist is necessary as
|
||||
well as the core Qt v5 components, normally installing the Qt
|
||||
@ -51,15 +50,13 @@ normally you can choose not to install libusb-1.0-dev but if you have
|
||||
a SoftRock USB or similar SDR that uses a custom USB interface then it
|
||||
is required.
|
||||
|
||||
The Hamlib library is required. Currently WSJT-X needs to be built
|
||||
using a forked version of the Hamlib git master. This fork contains
|
||||
patches not yet accepted by the Hamlib development team which are
|
||||
essential for correct operation of WSJT-X. To build the Hamlib fork
|
||||
from sources something like the following recipe should suffice:
|
||||
The Hamlib library is required. WSJT-X can be built with any version
|
||||
of the Hamlib git master. To build Hamlib from sources something
|
||||
like the following recipe should suffice:
|
||||
|
||||
$ mkdir ~/hamlib-prefix
|
||||
$ cd ~/hamlib-prefix
|
||||
$ git clone git://git.code.sf.net/u/bsomervi/hamlib src
|
||||
$ git clone https://github.com/Hamlib/Hamlib src
|
||||
$ cd src
|
||||
$ git checkout integration
|
||||
$ ./bootstrap
|
||||
@ -114,13 +111,13 @@ Building from Source on MS Windows
|
||||
|
||||
Because building on MS Windows is quite complicated there is an
|
||||
Software Development Kit available that provides all the prerequisite
|
||||
libraries and tools for building WSJT-X. This SDK is called JT-SDK-QT
|
||||
libraries and tools for building WSJT-X. This SDK is called HAMLIB SDK
|
||||
which is documented here:
|
||||
|
||||
http://physics.princeton.edu/pulsar/K1JT/wsjtx-doc/dev-guide-main.html
|
||||
https://sourceforge.net/projects/hamlib-sdk/
|
||||
|
||||
If you need to build Hamlib rather than use the Hamlib kit included in
|
||||
the JT-SDK the following recipe should help. Reasons for building
|
||||
the HAMLIB SDK the following recipe should help. Reasons for building
|
||||
Hamlib from source might include picking up the very latest patches or
|
||||
building a different branch that you wish to contribute to.
|
||||
|
||||
@ -144,7 +141,7 @@ In an MSYS shell:-
|
||||
|
||||
$ mkdir ~/hamib-prefix
|
||||
$ cd ~/hamlib-prefix
|
||||
$ git clone git://git.code.sf.net/u/bsomervi/hamlib src
|
||||
$ git clone https://github.com/Hamlib/Hamlib src
|
||||
$ cd src
|
||||
$ git checkout integration
|
||||
$ ./bootstrap
|
||||
@ -179,10 +176,6 @@ Hamlib binary location as one of the paths in CMAKE_PREFIX_PATH.
|
||||
Building from Source on Apple Mac
|
||||
=================================
|
||||
|
||||
These instructions are adapted from my Evernote page at:
|
||||
|
||||
https://www.evernote.com/pub/bsomervi/wsjt-xmacbuilds
|
||||
|
||||
There are several ways to get the required GNU and other open source
|
||||
tools and libraries installed, my preference is MacPorts because it is
|
||||
easy to use and does everything we need.
|
||||
@ -229,12 +222,11 @@ instructions are here:
|
||||
|
||||
Hamlib
|
||||
------
|
||||
First fetch hamlib from the repository, in this case my fork of Hamlib
|
||||
3 until the official repository has all the fixes we need:
|
||||
First fetch hamlib from the git master repository:
|
||||
|
||||
$ mkdir -p ~/hamlib-prefix/build
|
||||
$ cd ~/hamlib-prefix
|
||||
$ git clone git://git.code.sf.net/u/bsomervi/hamlib src
|
||||
$ git clone https://github.com/Hamlib/Hamlib src
|
||||
$ cd src
|
||||
$ git checkout integration
|
||||
$ ./bootstrap
|
||||
@ -353,8 +345,8 @@ which installs the WSJT-X application bundle into ~/wsjtx-prefix
|
||||
Updating and Rebuilding Hamlib
|
||||
==============================
|
||||
|
||||
From time to time new fixes will be pushed to the Hamlib fork
|
||||
repository integration branch. To pick them up type:
|
||||
From time to time new fixes will be pushed to the Hamlib git
|
||||
master repository. To pick them up type:
|
||||
|
||||
$ cd ~/hamlib-prefix/src
|
||||
$ git pull
|
||||
|
203
NEWS
203
NEWS
@ -9,7 +9,208 @@
|
||||
\$$ \$$ \$$$$$$ \$$$$$$ \$$ \$$ \$$
|
||||
|
||||
|
||||
Copyright 2001 - 2023 by Joe Taylor, K1JT, and the WSJT Development Team
|
||||
Copyright 2001 - 2024 by Joe Taylor, K1JT, and the WSJT Development Team
|
||||
|
||||
Release: WSJT-X 2.7.0-rc4
|
||||
March 11, 2024
|
||||
-------------------------
|
||||
|
||||
WSJT-X 2.7.0 Release Candidate 4 brings some improvements for Fox-mode
|
||||
operators, new features for companion program QMAP, and a number of
|
||||
relatively minor enhancements and bug fixes.
|
||||
|
||||
QMAP enhancements -- of particular interest to EME operators:
|
||||
|
||||
- QMAP now decodes Q65 submodes with both 60-second and 30-second T/R
|
||||
sequence lengths. Clicking on a resulting line in the WSJT-X Active
|
||||
Stations window automatically sets dial frequency and working
|
||||
submode as needed to call that station.
|
||||
|
||||
- QMAP operates in 60-second receive sequences, and its Q65 decoder
|
||||
starts at t=19.5, 30.0, 49.5, and 58.5 s into the sequence. Most
|
||||
decoded messages are displayed well before the end of the relevant
|
||||
time slot.
|
||||
|
||||
- A new, more compact file format is now used for wideband data
|
||||
files. A "Save decoded" option has been added to the Save menu.
|
||||
|
||||
- An option has been added to allow exporting a 3 kHz portion of a
|
||||
wideband data file as a standard WSJT-X *.wav file.
|
||||
|
||||
- CTRL+click on QMAP's upper waterfall sends an integer kHz dial
|
||||
frequency request to WSJT-X.
|
||||
|
||||
- With focus on the WSJT-X main window, hit Alt+A on the keyboard to
|
||||
clear the Active Stations window.
|
||||
|
||||
- Many minor enhancements to the User Interface.
|
||||
|
||||
WSJT-X:
|
||||
|
||||
- Enable decoding of MSK144 from the jt9[.exe] executable.
|
||||
|
||||
- Several changes to reduce problems experienced when (contrary to
|
||||
our recommendations) messages with short (10-bit) callsign hashes
|
||||
are used in standard FT4/FT8 sub-bands.
|
||||
|
||||
Release: WSJT-X 2.7.0-rc3
|
||||
January 1, 2024
|
||||
-------------------------
|
||||
|
||||
WSJT-X 2.7.0 Release Candidate 3 brings some new features, as well as
|
||||
numerous detail improvements and bug fixes, such as:
|
||||
|
||||
- Added a new "Update Hamlib" function. On Windows, it allows the user to
|
||||
update Hamlib directly from the program. The previously used version is
|
||||
backed up, so the user can easily revert a hamlib update.
|
||||
|
||||
- The Hamlib version in use is now displayed (also on Linux and macOS).
|
||||
|
||||
- The FT Roundup Messages protocol has been enhanced. It now allows also
|
||||
the exchange of static 4-digit numbers instead of serial numbers. This
|
||||
extends the usability of the FT RU protocol for other contest types.
|
||||
|
||||
- Improved direct switching between modes. Submode, as well as the status
|
||||
of the "Sh" and "Fast" checkboxes are now saved and restored by mode.
|
||||
|
||||
- Some right-click events were made more intuitive and consistent.
|
||||
- Right-clicking the Q65 button enables Q65 Pileup mode, a left-click
|
||||
brings you back to the normal Q65 mode.
|
||||
- Right-click the JT65 button to switch to JT9 mode.
|
||||
|
||||
- For Q65, all messages for us are now displayed in the right window.
|
||||
|
||||
- Message averaging is now allowed only when VHF features are
|
||||
enabled, and label texts are changed to "Single Period Decodes" and
|
||||
"Average Decodes" only if averaging is enabled.
|
||||
|
||||
- Some improvements to the Hamlib Transceiver code. Behavior is now
|
||||
more stable when Rig Split has been selected.
|
||||
|
||||
- Prevented redundant network communication between WSJT-X and DX Lab
|
||||
Suite Commander.
|
||||
|
||||
- Download of the LotW file now works without OpenSSL libraries.
|
||||
|
||||
- Made the spot counter work for WSPR.
|
||||
|
||||
- Prevented insertion of an individual contest name when in Fox mode.
|
||||
|
||||
- WAE entities are now assigned to the correct DXCC when "Include
|
||||
extra WAE entities" is not selected.
|
||||
|
||||
- Added a utility program 'cablog' which can be used to convert the
|
||||
wsjtx.log file to Cabrillo format for the ARRL EME contest.
|
||||
|
||||
- Minor improvements to the Active Stations window.
|
||||
|
||||
- The Rx/Tx frequency for Echo mode has been fixed at 1500 Hz.
|
||||
|
||||
- Some corrections and updates to the INSTALL instructions for Linux.
|
||||
|
||||
- Updated CTY.DAT file.
|
||||
|
||||
Release: WSJT-X 2.7.0-rc2
|
||||
July 7, 2023
|
||||
-------------------------
|
||||
|
||||
WSJT-X 2.7.0 Release Candidate 2 introduces several minor improvements
|
||||
and bug fixes.
|
||||
|
||||
- CTRL+SHIFT+F11/F12 now changes dial frequency by 1000 Hz instead of
|
||||
2000 Hz.
|
||||
|
||||
- Improved spotting to PSK Reporter for upcoming HamSCI Festivals of
|
||||
Eclipse Ionospheric Science.
|
||||
|
||||
- Added optional Hungarian translation of the user interface.
|
||||
|
||||
- Fixed a flaw that could produce false decodes in Q65 submodes D and E.
|
||||
|
||||
- Fixed a flaw with the QSO start time. It is now reset when the DX
|
||||
Call changes.
|
||||
|
||||
- Fixed a flaw that prevented contest logging of the ARRL Digi Contest.
|
||||
|
||||
- Right-clicking the Q65 mode button to toggle the Q65 Pileup mode on/off
|
||||
now also works on macOS.
|
||||
|
||||
- Fixed a compilation error on macOS Ventura.
|
||||
|
||||
- WSPR and FST4W band hopping now works again.
|
||||
|
||||
- It is now ensured that "U.S.A." is displayed when using certain
|
||||
cty.dat files.
|
||||
|
||||
- Corrected the problem with duplicated FT8 entries in ActiveStations
|
||||
window.
|
||||
|
||||
Release: WSJT-X 2.7.0-rc1
|
||||
May 12, 2023
|
||||
-------------------------
|
||||
|
||||
WSJT-X 2.7.0 Release Candidate 1 introduces a new program called QMAP,
|
||||
a new Special Operating Activity known as Q65 Pileup, and a number of
|
||||
other enhancements and fixes.
|
||||
|
||||
- QMAP and Q65 Pileup mode are of particular interest to those
|
||||
engaged in Earth-Moon-Earth (EME) communication, but other
|
||||
applications may be found for them as well.
|
||||
|
||||
- QMAP is derived from MAP65, an older program used since 2007 for
|
||||
EME, mainly on the 2 m band. QMAP provides single-polarization
|
||||
receive-only capabilities for any one of the 60-second submodes
|
||||
of Q65. It allows you to monitor all traffic in a 90 kHz subband
|
||||
while conducting EME QSOs in the usual way with WSJT-X.
|
||||
|
||||
- Q65 Pileup mode is a new feature in WSJT-X that will assist DX
|
||||
operators using Q65 in pileup circumstances with many
|
||||
simultaneous callers and very weak signals, such as those
|
||||
experienced by 6-meter EME DXpeditions.
|
||||
|
||||
- Further details on QMAP and Q65 Pileup mode are available in a
|
||||
Quick-Start guide posted here:
|
||||
https://wsjt.sourceforge.io/Quick_Start_WSJT-X_2.7_QMAP.pdf
|
||||
|
||||
- WSJT-X now provides more efficient spotting to PSK Reporter.
|
||||
Redundant spots are omitted, and posting of spots is now spread
|
||||
more widely in time. (Temporarily, in support of the HamSCI
|
||||
Festivals of Eclipse Ionospheric Science, spots will be transmitted
|
||||
more frequently during the upcoming solar eclipses.)
|
||||
|
||||
- WSJT-X is now able to process more than 100 FT8 decodes in a single
|
||||
reception interval.
|
||||
|
||||
- Improvements to the Fox mode:
|
||||
- More convenient and efficient handling of the two queues.
|
||||
- Fox Log window now displays statistical data on the QSO rate.
|
||||
|
||||
- When the station locator is changed (e.g during portable
|
||||
operations), the new locator will be sent automatically to PSK
|
||||
Reporter.
|
||||
|
||||
- The cty.dat file can now be updated by clicking a button on the
|
||||
Settings -> Colors tab.
|
||||
|
||||
- A new status display appears when fetching a new LotW file.
|
||||
|
||||
- Multi-streamed messages transmitted by MSHV are now handled
|
||||
properly when WSJT-X is in Hound mode.
|
||||
|
||||
- Auto-sequencing now has better protection against unwanted effects
|
||||
caused by late FT8 decodes.
|
||||
|
||||
- Fixed an inconsistency in which Contest Name was not correctly
|
||||
remembered.
|
||||
|
||||
- Other minor bug fixes.
|
||||
|
||||
- Updated hyperlinks to our homepage and to our new WSJT GROUP User
|
||||
Forum (https://groups.io/g/wsjtgroup/) can now also be found in the
|
||||
User Guide.
|
||||
|
||||
- The build instructions for macOS have been clarified.
|
||||
|
||||
|
||||
Release: WSJT-X 2.6.1
|
||||
January 16, 2023
|
||||
|
229
Network/FileDownload.cpp
Normal file
229
Network/FileDownload.cpp
Normal file
@ -0,0 +1,229 @@
|
||||
|
||||
#include "FileDownload.hpp"
|
||||
#include <QCoreApplication>
|
||||
#include <QUrl>
|
||||
#include <QNetworkRequest>
|
||||
#include <QtNetwork/QNetworkAccessManager>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#include <QIODevice>
|
||||
#include "qt_helpers.hpp"
|
||||
#include "Logger.hpp"
|
||||
|
||||
FileDownload::FileDownload() : QObject(nullptr)
|
||||
{
|
||||
redirect_count_ = 0;
|
||||
url_valid_ = false;
|
||||
}
|
||||
|
||||
FileDownload::~FileDownload()
|
||||
{
|
||||
}
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||
void FileDownload::errorOccurred(QNetworkReply::NetworkError code)
|
||||
{
|
||||
LOG_INFO(QString{"FileDownload [%1]: errorOccurred %2 -> %3"}.arg(user_agent_).arg(code).arg(reply_->errorString()));
|
||||
Q_EMIT error (reply_->errorString ());
|
||||
destfile_.cancelWriting ();
|
||||
destfile_.commit ();
|
||||
}
|
||||
#else
|
||||
void FileDownload::obsoleteError()
|
||||
{
|
||||
LOG_INFO(QString{"FileDownload [%1]: error -> %3"}.arg(user_agent_).arg(reply_->errorString()));
|
||||
Q_EMIT error (reply_->errorString ());
|
||||
destfile_.cancelWriting ();
|
||||
destfile_.commit ();
|
||||
}
|
||||
#endif
|
||||
|
||||
void FileDownload::configure(QNetworkAccessManager *network_manager, const QString &source_url, const QString &destination_path, const QString &user_agent)
|
||||
{
|
||||
manager_ = network_manager;
|
||||
source_url_ = source_url;
|
||||
destination_filename_ = destination_path;
|
||||
user_agent_ = user_agent;
|
||||
}
|
||||
|
||||
void FileDownload::store()
|
||||
{
|
||||
if (destfile_.isOpen())
|
||||
destfile_.write (reply_->read (reply_->bytesAvailable ()));
|
||||
else
|
||||
LOG_INFO(QString{ "FileDownload [%1]: file is not open."}.arg(user_agent_));
|
||||
}
|
||||
|
||||
void FileDownload::replyComplete()
|
||||
{
|
||||
QFileInfo destination_file(destination_filename_);
|
||||
QDir tmpdir_(destination_file.absoluteFilePath());
|
||||
|
||||
LOG_DEBUG(QString{ "FileDownload [%1]: replyComplete"}.arg(user_agent_));
|
||||
if (!reply_)
|
||||
{
|
||||
Q_EMIT load_finished ();
|
||||
return; // we probably deleted it in an earlier call
|
||||
}
|
||||
|
||||
QUrl redirect_url {reply_->attribute (QNetworkRequest::RedirectionTargetAttribute).toUrl ()};
|
||||
|
||||
if (reply_->error () == QNetworkReply::NoError && !redirect_url.isEmpty ())
|
||||
{
|
||||
if ("https" == redirect_url.scheme () && !QSslSocket::supportsSsl ())
|
||||
{
|
||||
Q_EMIT download_error (tr ("Network Error - SSL/TLS support not installed, cannot fetch:\n\'%1\'")
|
||||
.arg (redirect_url.toDisplayString ()));
|
||||
url_valid_ = false; // reset
|
||||
Q_EMIT load_finished ();
|
||||
}
|
||||
else if (++redirect_count_ < 10) // maintain sanity
|
||||
{
|
||||
// follow redirect
|
||||
download (reply_->url ().resolved (redirect_url));
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_EMIT download_error (tr ("Network Error - Too many redirects:\n\'%1\'")
|
||||
.arg (redirect_url.toDisplayString ()));
|
||||
url_valid_ = false; // reset
|
||||
Q_EMIT load_finished ();
|
||||
}
|
||||
}
|
||||
else if (reply_->error () != QNetworkReply::NoError)
|
||||
{
|
||||
destfile_.cancelWriting();
|
||||
destfile_.commit();
|
||||
url_valid_ = false; // reset
|
||||
// report errors that are not due to abort
|
||||
if (QNetworkReply::OperationCanceledError != reply_->error ())
|
||||
{
|
||||
Q_EMIT download_error (tr ("Network Error:\n%1")
|
||||
.arg (reply_->errorString ()));
|
||||
}
|
||||
Q_EMIT load_finished ();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!url_valid_)
|
||||
{
|
||||
// now get the body content
|
||||
url_valid_ = true;
|
||||
download (reply_->url ().resolved (redirect_url));
|
||||
}
|
||||
else // the body has completed. Save it.
|
||||
{
|
||||
url_valid_ = false; // reset
|
||||
// load the database asynchronously
|
||||
// future_load_ = std::async (std::launch::async, &LotWUsers::impl::load_dictionary, this, csv_file_.fileName ());
|
||||
LOG_INFO(QString{ "FileDownload [%1]: complete. File path is %2"}.arg(user_agent_).arg(destfile_.fileName()));
|
||||
destfile_.commit();
|
||||
emit complete(destination_filename_);
|
||||
}
|
||||
}
|
||||
|
||||
if (reply_ && reply_->isFinished ())
|
||||
{
|
||||
reply_->deleteLater ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void FileDownload::downloadComplete(QNetworkReply *data)
|
||||
{
|
||||
// make a temp file in the same place as the file we're downloading. Needs to be on the same
|
||||
// filesystem as where we eventually want to 'mv' it.
|
||||
|
||||
QUrl r = request_.url();
|
||||
LOG_INFO(QString{"FileDownload [%1]: finished %2 of %3 -> %4 (%5)"}.arg(user_agent_).arg(data->operation()).arg(source_url_).arg(destination_filename_).arg(r.url()));
|
||||
|
||||
#ifdef DEBUG_FILEDOWNLOAD
|
||||
LOG_INFO("Request Headers:");
|
||||
Q_FOREACH (const QByteArray& hdr, request_.rawHeaderList()) {
|
||||
LOG_INFO(QString{ "%1 -> %2"}.arg(QString(hdr)).arg(QString(request_.rawHeader(hdr))));
|
||||
}
|
||||
|
||||
LOG_INFO("Response Headers:");
|
||||
Q_FOREACH (const QByteArray& hdr, reply_->rawHeaderList()) {
|
||||
LOG_INFO(QString{ "%1 -> %2"}.arg(QString(hdr)).arg(QString(reply_->rawHeader(hdr))));
|
||||
}
|
||||
#endif
|
||||
data->deleteLater();
|
||||
}
|
||||
|
||||
void FileDownload::start_download()
|
||||
{
|
||||
url_valid_ = false;
|
||||
download(QUrl(source_url_));
|
||||
}
|
||||
|
||||
void FileDownload::download(QUrl qurl)
|
||||
{
|
||||
request_.setUrl(qurl);
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
|
||||
if (QNetworkAccessManager::Accessible != manager_->networkAccessible ())
|
||||
{
|
||||
// try and recover network access for QNAM
|
||||
manager_->setNetworkAccessible (QNetworkAccessManager::Accessible);
|
||||
}
|
||||
#endif
|
||||
|
||||
LOG_INFO(QString{"FileDownload [%1]: Starting download of %2 to %3"}.arg(user_agent_).arg(source_url_).arg(destination_filename_));
|
||||
|
||||
request_.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||
request_.setRawHeader("Accept", "*/*");
|
||||
request_.setRawHeader ("User-Agent", user_agent_.toLocal8Bit()); // Must have a UA for some sites, like country-files
|
||||
|
||||
if (!url_valid_)
|
||||
{
|
||||
reply_ = manager_->head(request_);
|
||||
}
|
||||
else
|
||||
{
|
||||
reply_ = manager_->get (request_);
|
||||
}
|
||||
|
||||
QObject::connect(manager_, &QNetworkAccessManager::finished, this, &FileDownload::downloadComplete, Qt::UniqueConnection);
|
||||
QObject::connect(reply_, &QNetworkReply::downloadProgress, this, &FileDownload::downloadProgress, Qt::UniqueConnection);
|
||||
QObject::connect(reply_, &QNetworkReply::finished, this, &FileDownload::replyComplete, Qt::UniqueConnection);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||
QObject::connect(reply_, &QNetworkReply::errorOccurred,this, &FileDownload::errorOccurred, Qt::UniqueConnection);
|
||||
#else
|
||||
QObject::connect(reply_, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error), this, &FileDownload::obsoleteError, Qt::UniqueConnection);
|
||||
#endif
|
||||
QObject::connect(reply_, &QNetworkReply::readyRead, this, &FileDownload::store, Qt::UniqueConnection);
|
||||
|
||||
QFileInfo destination_file(destination_filename_);
|
||||
QString const tmpfile_base = destination_file.fileName();
|
||||
QString const &tmpfile_path = destination_file.absolutePath();
|
||||
QDir tmpdir{};
|
||||
if (!tmpdir.mkpath(tmpfile_path))
|
||||
{
|
||||
LOG_INFO(QString{"FileDownload [%1]: Directory %2 does not exist"}.arg(user_agent_).arg(tmpfile_path).arg(
|
||||
destfile_.errorString()));
|
||||
}
|
||||
|
||||
if (url_valid_) {
|
||||
destfile_.setFileName(destination_file.absoluteFilePath());
|
||||
if (!destfile_.open(QSaveFile::WriteOnly | QIODevice::WriteOnly)) {
|
||||
LOG_INFO(QString{"FileDownload [%1]: Unable to open %2: %3"}.arg(user_agent_).arg(destfile_.fileName()).arg(
|
||||
destfile_.errorString()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FileDownload::downloadProgress(qint64 received, qint64 total)
|
||||
{
|
||||
LOG_DEBUG(QString{"FileDownload: [%1] Progress %2 from %3, total %4, so far %5"}.arg(user_agent_).arg(destination_filename_).arg(source_url_).arg(total).arg(received));
|
||||
Q_EMIT progress(QString{"%4 bytes downloaded"}.arg(received));
|
||||
}
|
||||
|
||||
void FileDownload::abort ()
|
||||
{
|
||||
if (reply_ && reply_->isRunning ())
|
||||
{
|
||||
reply_->abort ();
|
||||
}
|
||||
}
|
54
Network/FileDownload.hpp
Normal file
54
Network/FileDownload.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
#ifndef WSJTX_FILEDOWNLOAD_H
|
||||
#define WSJTX_FILEDOWNLOAD_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QPointer>
|
||||
#include <QtNetwork/QNetworkAccessManager>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
#include <QTemporaryFile>
|
||||
#include <QSaveFile>
|
||||
|
||||
class FileDownload : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FileDownload();
|
||||
~FileDownload();
|
||||
|
||||
void configure(QNetworkAccessManager *network_manager, const QString& source_url, const QString& destination_filename, const QString& user_agent);
|
||||
|
||||
private:
|
||||
QNetworkAccessManager *manager_;
|
||||
QString source_url_;
|
||||
QString destination_filename_;
|
||||
QString user_agent_;
|
||||
QPointer<QNetworkReply> reply_;
|
||||
QNetworkRequest request_;
|
||||
QSaveFile destfile_;
|
||||
bool url_valid_;
|
||||
int redirect_count_;
|
||||
signals:
|
||||
void complete(QString filename);
|
||||
void progress(QString filename);
|
||||
void load_finished() const;
|
||||
void download_error (QString const& reason) const;
|
||||
void error(QString const& reason) const;
|
||||
|
||||
|
||||
public slots:
|
||||
void start_download();
|
||||
void download(QUrl url);
|
||||
void store();
|
||||
void abort();
|
||||
void downloadComplete(QNetworkReply* data);
|
||||
void downloadProgress(qint64 recieved, qint64 total);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||
void errorOccurred(QNetworkReply::NetworkError code);
|
||||
#else
|
||||
void obsoleteError();
|
||||
#endif
|
||||
void replyComplete();
|
||||
};
|
||||
|
||||
#endif //WSJTX_FILEDOWNLOAD_H
|
@ -16,7 +16,9 @@
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QDebug>
|
||||
|
||||
#include "qt_helpers.hpp"
|
||||
#include "Logger.hpp"
|
||||
#include "FileDownload.hpp"
|
||||
#include "pimpl_impl.hpp"
|
||||
|
||||
#include "moc_LotWUsers.cpp"
|
||||
@ -39,6 +41,7 @@ public:
|
||||
, url_valid_ {false}
|
||||
, redirect_count_ {0}
|
||||
, age_constraint_ {365}
|
||||
, connected_ {false}
|
||||
{
|
||||
}
|
||||
|
||||
@ -48,14 +51,36 @@ public:
|
||||
auto csv_file_name = csv_file_.fileName ();
|
||||
auto exists = QFileInfo::exists (csv_file_name);
|
||||
if (fetch && (!exists || forced_fetch))
|
||||
{
|
||||
current_url_.setUrl(url);
|
||||
if (current_url_.isValid() && !QSslSocket::supportsSsl())
|
||||
{
|
||||
current_url_.setUrl (url);
|
||||
if (current_url_.isValid () && !QSslSocket::supportsSsl ())
|
||||
{
|
||||
current_url_.setScheme ("http");
|
||||
}
|
||||
redirect_count_ = 0;
|
||||
download (current_url_);
|
||||
current_url_.setScheme("http");
|
||||
}
|
||||
redirect_count_ = 0;
|
||||
|
||||
Q_EMIT self_->progress (QString("Starting download from %1").arg(url));
|
||||
|
||||
lotw_downloader_.configure(network_manager_,
|
||||
url,
|
||||
csv_file_name,
|
||||
"WSJT-X LotW User Downloader");
|
||||
if (!connected_)
|
||||
{
|
||||
connect(&lotw_downloader_, &FileDownload::complete, [this, csv_file_name] {
|
||||
LOG_INFO(QString{"LotWUsers: Loading LotW file %1"}.arg(csv_file_name));
|
||||
future_load_ = std::async(std::launch::async, &LotWUsers::impl::load_dictionary, this, csv_file_name);
|
||||
});
|
||||
connect(&lotw_downloader_, &FileDownload::error, [this] (QString const& msg) {
|
||||
LOG_INFO(QString{"LotWUsers: Error downloading LotW file: %1"}.arg(msg));
|
||||
Q_EMIT self_->LotW_users_error (msg);
|
||||
});
|
||||
connect( &lotw_downloader_, &FileDownload::progress, [this] (QString const& msg) {
|
||||
Q_EMIT self_->progress (msg);
|
||||
});
|
||||
connected_ = true;
|
||||
}
|
||||
lotw_downloader_.start_download();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -67,142 +92,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void download (QUrl url)
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
|
||||
if (QNetworkAccessManager::Accessible != network_manager_->networkAccessible ())
|
||||
{
|
||||
// try and recover network access for QNAM
|
||||
network_manager_->setNetworkAccessible (QNetworkAccessManager::Accessible);
|
||||
}
|
||||
#endif
|
||||
|
||||
QNetworkRequest request {url};
|
||||
request.setRawHeader ("User-Agent", "WSJT LotW User Downloader");
|
||||
request.setOriginatingObject (this);
|
||||
|
||||
// this blocks for a second or two the first time it is used on
|
||||
// Windows - annoying
|
||||
if (!url_valid_)
|
||||
{
|
||||
reply_ = network_manager_->head (request);
|
||||
}
|
||||
else
|
||||
{
|
||||
reply_ = network_manager_->get (request);
|
||||
}
|
||||
|
||||
connect (reply_.data (), &QNetworkReply::finished, this, &LotWUsers::impl::reply_finished);
|
||||
connect (reply_.data (), &QNetworkReply::readyRead, this, &LotWUsers::impl::store);
|
||||
}
|
||||
|
||||
void reply_finished ()
|
||||
{
|
||||
if (!reply_)
|
||||
{
|
||||
Q_EMIT self_->load_finished ();
|
||||
return; // we probably deleted it in an earlier call
|
||||
}
|
||||
QUrl redirect_url {reply_->attribute (QNetworkRequest::RedirectionTargetAttribute).toUrl ()};
|
||||
if (reply_->error () == QNetworkReply::NoError && !redirect_url.isEmpty ())
|
||||
{
|
||||
if ("https" == redirect_url.scheme () && !QSslSocket::supportsSsl ())
|
||||
{
|
||||
Q_EMIT self_->LotW_users_error (tr ("Network Error - SSL/TLS support not installed, cannot fetch:\n\'%1\'")
|
||||
.arg (redirect_url.toDisplayString ()));
|
||||
url_valid_ = false; // reset
|
||||
Q_EMIT self_->load_finished ();
|
||||
}
|
||||
else if (++redirect_count_ < 10) // maintain sanity
|
||||
{
|
||||
// follow redirect
|
||||
download (reply_->url ().resolved (redirect_url));
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_EMIT self_->LotW_users_error (tr ("Network Error - Too many redirects:\n\'%1\'")
|
||||
.arg (redirect_url.toDisplayString ()));
|
||||
url_valid_ = false; // reset
|
||||
Q_EMIT self_->load_finished ();
|
||||
}
|
||||
}
|
||||
else if (reply_->error () != QNetworkReply::NoError)
|
||||
{
|
||||
csv_file_.cancelWriting ();
|
||||
csv_file_.commit ();
|
||||
url_valid_ = false; // reset
|
||||
// report errors that are not due to abort
|
||||
if (QNetworkReply::OperationCanceledError != reply_->error ())
|
||||
{
|
||||
Q_EMIT self_->LotW_users_error (tr ("Network Error:\n%1")
|
||||
.arg (reply_->errorString ()));
|
||||
}
|
||||
Q_EMIT self_->load_finished ();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (url_valid_ && !csv_file_.commit ())
|
||||
{
|
||||
Q_EMIT self_->LotW_users_error (tr ("File System Error - Cannot commit changes to:\n\"%1\"")
|
||||
.arg (csv_file_.fileName ()));
|
||||
url_valid_ = false; // reset
|
||||
Q_EMIT self_->load_finished ();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!url_valid_)
|
||||
{
|
||||
// now get the body content
|
||||
url_valid_ = true;
|
||||
download (reply_->url ().resolved (redirect_url));
|
||||
}
|
||||
else
|
||||
{
|
||||
url_valid_ = false; // reset
|
||||
// load the database asynchronously
|
||||
future_load_ = std::async (std::launch::async, &LotWUsers::impl::load_dictionary, this, csv_file_.fileName ());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (reply_ && reply_->isFinished ())
|
||||
{
|
||||
reply_->deleteLater ();
|
||||
}
|
||||
}
|
||||
|
||||
void store ()
|
||||
{
|
||||
if (url_valid_)
|
||||
{
|
||||
if (!csv_file_.isOpen ())
|
||||
{
|
||||
// create temporary file in the final location
|
||||
if (!csv_file_.open (QSaveFile::WriteOnly))
|
||||
{
|
||||
abort ();
|
||||
Q_EMIT self_->LotW_users_error (tr ("File System Error - Cannot open file:\n\"%1\"\nError(%2): %3")
|
||||
.arg (csv_file_.fileName ())
|
||||
.arg (csv_file_.error ())
|
||||
.arg (csv_file_.errorString ()));
|
||||
}
|
||||
}
|
||||
if (csv_file_.write (reply_->read (reply_->bytesAvailable ())) < 0)
|
||||
{
|
||||
abort ();
|
||||
Q_EMIT self_->LotW_users_error (tr ("File System Error - Cannot write to file:\n\"%1\"\nError(%2): %3")
|
||||
.arg (csv_file_.fileName ())
|
||||
.arg (csv_file_.error ())
|
||||
.arg (csv_file_.errorString ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void abort ()
|
||||
{
|
||||
if (reply_ && reply_->isRunning ())
|
||||
{
|
||||
reply_->abort ();
|
||||
}
|
||||
lotw_downloader_.abort();
|
||||
}
|
||||
|
||||
// Load the database from the given file name
|
||||
@ -222,12 +114,14 @@ public:
|
||||
auto pos = l.indexOf (',');
|
||||
result[l.left (pos)] = QDate::fromString (l.mid (pos + 1, l.indexOf (',', pos + 1) - pos - 1), "yyyy-MM-dd");
|
||||
}
|
||||
// qDebug () << "LotW User Data Loaded";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error {QObject::tr ("Failed to open LotW users CSV file: '%1'").arg (f.fileName ()).toStdString ()};
|
||||
}
|
||||
LOG_INFO(QString{"LotWUsers: Loaded %1 records from %2"}.arg(result.size()).arg(lotw_csv_file));
|
||||
Q_EMIT self_->progress (QString{"Loaded %1 records from LotW."}.arg(result.size()));
|
||||
Q_EMIT self_->load_finished();
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -241,6 +135,8 @@ public:
|
||||
std::future<dictionary> future_load_;
|
||||
dictionary last_uploaded_;
|
||||
qint64 age_constraint_; // days
|
||||
FileDownload lotw_downloader_;
|
||||
bool connected_;
|
||||
};
|
||||
|
||||
#include "LotWUsers.moc"
|
||||
@ -249,6 +145,7 @@ LotWUsers::LotWUsers (QNetworkAccessManager * network_manager, QObject * parent)
|
||||
: QObject {parent}
|
||||
, m_ {this, network_manager}
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
LotWUsers::~LotWUsers ()
|
||||
|
@ -31,6 +31,7 @@ public:
|
||||
bool user (QString const& call) const;
|
||||
|
||||
Q_SIGNAL void LotW_users_error (QString const& reason) const;
|
||||
Q_SIGNAL void progress (QString const& reason) const;
|
||||
Q_SIGNAL void load_finished () const;
|
||||
|
||||
private:
|
||||
|
@ -6,6 +6,8 @@
|
||||
//
|
||||
// Reports will be sent in batch mode every 5 minutes.
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
@ -18,6 +20,7 @@
|
||||
#include <QByteArray>
|
||||
#include <QDataStream>
|
||||
#include <QTimer>
|
||||
#include <QDir>
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||
#include <QRandomGenerator>
|
||||
#endif
|
||||
@ -29,19 +32,26 @@
|
||||
|
||||
#include "moc_PSKReporter.cpp"
|
||||
|
||||
#define DEBUGECLIPSE 0
|
||||
|
||||
namespace
|
||||
{
|
||||
QLatin1String HOST {"report.pskreporter.info"};
|
||||
// QLatin1String HOST {"127.0.0.1"};
|
||||
quint16 SERVICE_PORT {4739};
|
||||
// quint16 SERVICE_PORT {14739};
|
||||
int MIN_SEND_INTERVAL {15}; // in seconds
|
||||
int FLUSH_INTERVAL {4 * 5}; // in send intervals
|
||||
int MIN_SEND_INTERVAL {120}; // in seconds
|
||||
int FLUSH_INTERVAL {MIN_SEND_INTERVAL + 5}; // in send intervals
|
||||
bool ALIGNMENT_PADDING {true};
|
||||
int MIN_PAYLOAD_LENGTH {508};
|
||||
int MAX_PAYLOAD_LENGTH {1400};
|
||||
int MAX_PAYLOAD_LENGTH {10000};
|
||||
int CACHE_TIMEOUT {300}; // default to 5 minutes for repeating spots
|
||||
QMap<QString, time_t> spot_cache;
|
||||
}
|
||||
|
||||
static int added;
|
||||
static int removed;
|
||||
|
||||
class PSKReporter::impl final
|
||||
: public QObject
|
||||
{
|
||||
@ -83,6 +93,7 @@ public:
|
||||
send_receiver_data_ = 3; // three times
|
||||
}
|
||||
});
|
||||
eclipse_load(config->data_dir ().absoluteFilePath ("eclipse.txt"));
|
||||
}
|
||||
|
||||
void check_connection ()
|
||||
@ -167,7 +178,7 @@ public:
|
||||
|
||||
if (!report_timer_.isActive ())
|
||||
{
|
||||
report_timer_.start (MIN_SEND_INTERVAL * 1000);
|
||||
report_timer_.start (MIN_SEND_INTERVAL+1 * 1000); // we add 1 to give some more randomization
|
||||
}
|
||||
if (!descriptor_timer_.isActive ())
|
||||
{
|
||||
@ -188,6 +199,8 @@ public:
|
||||
|
||||
void send_report (bool send_residue = false);
|
||||
void build_preamble (QDataStream&);
|
||||
void eclipse_load(QString filename);
|
||||
bool eclipse_active(QDateTime now = QDateTime::currentDateTime());
|
||||
|
||||
bool flushing ()
|
||||
{
|
||||
@ -196,6 +209,14 @@ public:
|
||||
return flush;
|
||||
}
|
||||
|
||||
QString getStringFromQDateTime(const QString& dateTimeString, const QString& format)
|
||||
{
|
||||
QDateTime dateTime = QDateTime::fromString(dateTimeString, format);
|
||||
return dateTime.toString();
|
||||
}
|
||||
|
||||
QList<QDateTime> eclipseDates;
|
||||
|
||||
logger_type mutable logger_;
|
||||
PSKReporter * self_;
|
||||
Configuration const * config_;
|
||||
@ -272,6 +293,69 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
bool PSKReporter::impl::eclipse_active(QDateTime timeutc)
|
||||
{
|
||||
#ifdef DEBUGECLIPSE
|
||||
std::ofstream mylog("/temp/eclipse.log", std::ios_base::app);
|
||||
#endif
|
||||
QDateTime dateNow = QDateTime::currentDateTimeUtc();
|
||||
for (int i=0; i< eclipseDates.size(); ++i)
|
||||
{
|
||||
QDateTime check = eclipseDates.at(i); // already in UTC time
|
||||
// +- 6 hour window
|
||||
qint64 secondsDiff = qAbs(check.secsTo(dateNow));
|
||||
if (secondsDiff <= 3600*6) // 6 hour check
|
||||
{
|
||||
#ifdef DEBUGECLIPSE
|
||||
mylog << dateNow.toString(Qt::ISODate) << " Eclipse! " << "secondsDiff=" << secondsDiff << std::endl;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUGECLIPSE
|
||||
mylog << timeutc.toString("yyyy-MM-dd HH:mm:ss") << " no eclipse" << "\n";
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
void PSKReporter::impl::eclipse_load(QString eclipse_file)
|
||||
{
|
||||
std::ifstream fs(qPrintable(eclipse_file));
|
||||
std::string mydate,mytime,myline;
|
||||
#ifdef DEBUGECLIPSE
|
||||
std::ofstream mylog("c:/temp/eclipse.log");
|
||||
mylog << "eclipse_file=" << eclipse_file << std::endl;
|
||||
#endif
|
||||
if (fs.is_open())
|
||||
{
|
||||
while(!fs.eof())
|
||||
{
|
||||
std::getline(fs, myline);
|
||||
if (myline[0] != '#' && myline.length() > 2) // make sure to skip blank lines
|
||||
{
|
||||
//QString format = "yyyy-MM-dd hh:mm:ss";
|
||||
QDateTime qdate = QDateTime::fromString(QString::fromStdString(myline), Qt::ISODate);
|
||||
QDateTime now = QDateTime::currentDateTimeUtc();
|
||||
// only add the date if we can cover the whole 12 hours
|
||||
//if (now < qdate.toUTC().addSecs(-3600*6))
|
||||
eclipseDates.append(qdate);
|
||||
#ifdef DEBUGECLIPSE
|
||||
//else
|
||||
// mylog << "not adding " << myline << std::endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
#ifdef DEBUGECLIPSE
|
||||
mylog << myline << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifdef DEBUGECLIPSE
|
||||
if (eclipse_active(QDateTime::currentDateTime().toUTC())) mylog << "Eclipse is active" << std::endl;
|
||||
else mylog << "Eclipse is not active" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
void PSKReporter::impl::build_preamble (QDataStream& message)
|
||||
{
|
||||
// Message Header
|
||||
@ -516,6 +600,11 @@ void PSKReporter::reconnect ()
|
||||
m_->reconnect ();
|
||||
}
|
||||
|
||||
bool PSKReporter::eclipse_active(QDateTime now)
|
||||
{
|
||||
return m_->eclipse_active(now);
|
||||
}
|
||||
|
||||
void PSKReporter::setLocalStation (QString const& call, QString const& gridSquare, QString const& antenna)
|
||||
{
|
||||
LOG_LOG_LOCATION (m_->logger_, trace, "call: " << call << " grid: " << gridSquare << " ant: " << antenna);
|
||||
@ -542,7 +631,45 @@ bool PSKReporter::addRemoteStation (QString const& call, QString const& grid, Ra
|
||||
{
|
||||
reconnect ();
|
||||
}
|
||||
m_->spots_.enqueue ({call, grid, snr, freq, mode, QDateTime::currentDateTimeUtc ()});
|
||||
// remove any earlier spots of this call to reduce pskreporter load
|
||||
#ifdef DEBUGPSK
|
||||
static std::fstream fs;
|
||||
if (!fs.is_open()) fs.open("/temp/psk.log", std::fstream::in | std::fstream::out | std::fstream::app);
|
||||
#endif
|
||||
added++;
|
||||
|
||||
QDateTime qdateNow = QDateTime::currentDateTime().toUTC();
|
||||
// we allow all spots through +/- 6 hours around an eclipse for the HamSCI group
|
||||
if (!spot_cache.contains(call) || freq > 49000000 || eclipse_active(qdateNow)) // then it's a new spot
|
||||
{
|
||||
m_->spots_.enqueue ({call, grid, snr, freq, mode, QDateTime::currentDateTimeUtc ()});
|
||||
spot_cache.insert(call, time(NULL));
|
||||
#ifdef DEBUGPSK
|
||||
if (fs.is_open()) fs << "Adding " << call << " freq=" << freq << " " << spot_cache[call] << " count=" << m_->spots_.count() << std::endl;
|
||||
#endif
|
||||
}
|
||||
else if (time(NULL) - spot_cache[call] > CACHE_TIMEOUT) // then the cache has expired
|
||||
{
|
||||
m_->spots_.enqueue ({call, grid, snr, freq, mode, QDateTime::currentDateTimeUtc ()});
|
||||
#ifdef DEBUGPSK
|
||||
if (fs.is_open()) fs << "Adding # " << call << spot_cache[call] << " count=" << m_->spots_.count() << std::endl;
|
||||
#endif
|
||||
spot_cache[call] = time(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
removed++;
|
||||
#ifdef DEBUGPSK
|
||||
if (fs.is_open()) fs << "Removing " << call << " " << time(NULL) << " reduction=" << removed/(double)added*100 << "%" << std::endl;
|
||||
#endif
|
||||
}
|
||||
// remove cached items over 10 minutes old to save a little memory
|
||||
QMapIterator<QString, time_t> i(spot_cache);
|
||||
time_t tmptime = time(NULL);
|
||||
while(i.hasNext()) {
|
||||
i.next();
|
||||
if (tmptime - i.value() > 600) spot_cache.remove(i.key());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -31,6 +31,10 @@ public:
|
||||
//
|
||||
void sendReport (bool last = false);
|
||||
|
||||
//
|
||||
// True if current time falls withing a +/- window of a solar eclipse for HamSCI use
|
||||
bool eclipse_active(QDateTime now);
|
||||
|
||||
Q_SIGNAL void errorOccurred (QString const& reason);
|
||||
|
||||
private:
|
||||
|
@ -9,7 +9,208 @@
|
||||
\$$ \$$ \$$$$$$ \$$$$$$ \$$ \$$ \$$
|
||||
|
||||
|
||||
Copyright 2001 - 2023 by Joe Taylor, K1JT, and the WSJT Development Team
|
||||
Copyright 2001 - 2024 by Joe Taylor, K1JT, and the WSJT Development Team
|
||||
|
||||
Release: WSJT-X 2.7.0-rc4
|
||||
March 11, 2024
|
||||
-------------------------
|
||||
|
||||
WSJT-X 2.7.0 Release Candidate 4 brings some improvements for Fox-mode
|
||||
operators, new features for companion program QMAP, and a number of
|
||||
relatively minor enhancements and bug fixes.
|
||||
|
||||
QMAP enhancements -- of particular interest to EME operators:
|
||||
|
||||
- QMAP now decodes Q65 submodes with both 60-second and 30-second T/R
|
||||
sequence lengths. Clicking on a resulting line in the WSJT-X Active
|
||||
Stations window automatically sets dial frequency and working
|
||||
submode as needed to call that station.
|
||||
|
||||
- QMAP operates in 60-second receive sequences, and its Q65 decoder
|
||||
starts at t=19.5, 30.0, 49.5, and 58.5 s into the sequence. Most
|
||||
decoded messages are displayed well before the end of the relevant
|
||||
time slot.
|
||||
|
||||
- A new, more compact file format is now used for wideband data
|
||||
files. A "Save decoded" option has been added to the Save menu.
|
||||
|
||||
- An option has been added to allow exporting a 3 kHz portion of a
|
||||
wideband data file as a standard WSJT-X *.wav file.
|
||||
|
||||
- CTRL+click on QMAP's upper waterfall sends an integer kHz dial
|
||||
frequency request to WSJT-X.
|
||||
|
||||
- With focus on the WSJT-X main window, hit Alt+A on the keyboard to
|
||||
clear the Active Stations window.
|
||||
|
||||
- Many minor enhancements to the User Interface.
|
||||
|
||||
WSJT-X:
|
||||
|
||||
- Enable decoding of MSK144 from the jt9[.exe] executable.
|
||||
|
||||
- Several changes to reduce problems experienced when (contrary to
|
||||
our recommendations) messages with short (10-bit) callsign hashes
|
||||
are used in standard FT4/FT8 sub-bands.
|
||||
|
||||
Release: WSJT-X 2.7.0-rc3
|
||||
January 1, 2024
|
||||
-------------------------
|
||||
|
||||
WSJT-X 2.7.0 Release Candidate 3 brings some new features, as well as
|
||||
numerous detail improvements and bug fixes, such as:
|
||||
|
||||
- Added a new "Update Hamlib" function. On Windows, it allows the user to
|
||||
update Hamlib directly from the program. The previously used version is
|
||||
backed up, so the user can easily revert a hamlib update.
|
||||
|
||||
- The Hamlib version in use is now displayed (also on Linux and macOS).
|
||||
|
||||
- The FT Roundup Messages protocol has been enhanced. It now allows also
|
||||
the exchange of static 4-digit numbers instead of serial numbers. This
|
||||
extends the usability of the FT RU protocol for other contest types.
|
||||
|
||||
- Improved direct switching between modes. Submode, as well as the status
|
||||
of the "Sh" and "Fast" checkboxes are now saved and restored by mode.
|
||||
|
||||
- Some right-click events were made more intuitive and consistent.
|
||||
- Right-clicking the Q65 button enables Q65 Pileup mode, a left-click
|
||||
brings you back to the normal Q65 mode.
|
||||
- Right-click the JT65 button to switch to JT9 mode.
|
||||
|
||||
- For Q65, all messages for us are now displayed in the right window.
|
||||
|
||||
- Message averaging is now allowed only when VHF features are
|
||||
enabled, and label texts are changed to "Single Period Decodes" and
|
||||
"Average Decodes" only if averaging is enabled.
|
||||
|
||||
- Some improvements to the Hamlib Transceiver code. Behavior is now
|
||||
more stable when Rig Split has been selected.
|
||||
|
||||
- Prevented redundant network communication between WSJT-X and DX Lab
|
||||
Suite Commander.
|
||||
|
||||
- Download of the LotW file now works without OpenSSL libraries.
|
||||
|
||||
- Made the spot counter work for WSPR.
|
||||
|
||||
- Prevented insertion of an individual contest name when in Fox mode.
|
||||
|
||||
- WAE entities are now assigned to the correct DXCC when "Include
|
||||
extra WAE entities" is not selected.
|
||||
|
||||
- Added a utility program 'cablog' which can be used to convert the
|
||||
wsjtx.log file to Cabrillo format for the ARRL EME contest.
|
||||
|
||||
- Minor improvements to the Active Stations window.
|
||||
|
||||
- The Rx/Tx frequency for Echo mode has been fixed at 1500 Hz.
|
||||
|
||||
- Some corrections and updates to the INSTALL instructions for Linux.
|
||||
|
||||
- Updated CTY.DAT file.
|
||||
|
||||
Release: WSJT-X 2.7.0-rc2
|
||||
July 7, 2023
|
||||
-------------------------
|
||||
|
||||
WSJT-X 2.7.0 Release Candidate 2 introduces several minor improvements
|
||||
and bug fixes.
|
||||
|
||||
- CTRL+SHIFT+F11/F12 now changes dial frequency by 1000 Hz instead of
|
||||
2000 Hz.
|
||||
|
||||
- Improved spotting to PSK Reporter for upcoming HamSCI Festivals of
|
||||
Eclipse Ionospheric Science.
|
||||
|
||||
- Added optional Hungarian translation of the user interface.
|
||||
|
||||
- Fixed a flaw that could produce false decodes in Q65 submodes D and E.
|
||||
|
||||
- Fixed a flaw with the QSO start time. It is now reset when the DX
|
||||
Call changes.
|
||||
|
||||
- Fixed a flaw that prevented contest logging of the ARRL Digi Contest.
|
||||
|
||||
- Right-clicking the Q65 mode button to toggle the Q65 Pileup mode on/off
|
||||
now also works on macOS.
|
||||
|
||||
- Fixed a compilation error on macOS Ventura.
|
||||
|
||||
- WSPR and FST4W band hopping now works again.
|
||||
|
||||
- It is now ensured that "U.S.A." is displayed when using certain
|
||||
cty.dat files.
|
||||
|
||||
- Corrected the problem with duplicated FT8 entries in ActiveStations
|
||||
window.
|
||||
|
||||
Release: WSJT-X 2.7.0-rc1
|
||||
May 12, 2023
|
||||
-------------------------
|
||||
|
||||
WSJT-X 2.7.0 Release Candidate 1 introduces a new program called QMAP,
|
||||
a new Special Operating Activity known as Q65 Pileup, and a number of
|
||||
other enhancements and fixes.
|
||||
|
||||
- QMAP and Q65 Pileup mode are of particular interest to those
|
||||
engaged in Earth-Moon-Earth (EME) communication, but other
|
||||
applications may be found for them as well.
|
||||
|
||||
- QMAP is derived from MAP65, an older program used since 2007 for
|
||||
EME, mainly on the 2 m band. QMAP provides single-polarization
|
||||
receive-only capabilities for any one of the 60-second submodes
|
||||
of Q65. It allows you to monitor all traffic in a 90 kHz subband
|
||||
while conducting EME QSOs in the usual way with WSJT-X.
|
||||
|
||||
- Q65 Pileup mode is a new feature in WSJT-X that will assist DX
|
||||
operators using Q65 in pileup circumstances with many
|
||||
simultaneous callers and very weak signals, such as those
|
||||
experienced by 6-meter EME DXpeditions.
|
||||
|
||||
- Further details on QMAP and Q65 Pileup mode are available in a
|
||||
Quick-Start guide posted here:
|
||||
https://wsjt.sourceforge.io/Quick_Start_WSJT-X_2.7_QMAP.pdf
|
||||
|
||||
- WSJT-X now provides more efficient spotting to PSK Reporter.
|
||||
Redundant spots are omitted, and posting of spots is now spread
|
||||
more widely in time. (Temporarily, in support of the HamSCI
|
||||
Festivals of Eclipse Ionospheric Science, spots will be transmitted
|
||||
more frequently during the upcoming solar eclipses.)
|
||||
|
||||
- WSJT-X is now able to process more than 100 FT8 decodes in a single
|
||||
reception interval.
|
||||
|
||||
- Improvements to the Fox mode:
|
||||
- More convenient and efficient handling of the two queues.
|
||||
- Fox Log window now displays statistical data on the QSO rate.
|
||||
|
||||
- When the station locator is changed (e.g during portable
|
||||
operations), the new locator will be sent automatically to PSK
|
||||
Reporter.
|
||||
|
||||
- The cty.dat file can now be updated by clicking a button on the
|
||||
Settings -> Colors tab.
|
||||
|
||||
- A new status display appears when fetching a new LotW file.
|
||||
|
||||
- Multi-streamed messages transmitted by MSHV are now handled
|
||||
properly when WSJT-X is in Hound mode.
|
||||
|
||||
- Auto-sequencing now has better protection against unwanted effects
|
||||
caused by late FT8 decodes.
|
||||
|
||||
- Fixed an inconsistency in which Contest Name was not correctly
|
||||
remembered.
|
||||
|
||||
- Other minor bug fixes.
|
||||
|
||||
- Updated hyperlinks to our homepage and to our new WSJT GROUP User
|
||||
Forum (https://groups.io/g/wsjtgroup/) can now also be found in the
|
||||
User Guide.
|
||||
|
||||
- The build instructions for macOS have been clarified.
|
||||
|
||||
|
||||
Release: WSJT-X 2.6.1
|
||||
January 16, 2023
|
||||
|
@ -659,7 +659,7 @@ int HamlibTransceiver::do_start ()
|
||||
rmode_t mb;
|
||||
pbwidth_t w {RIG_PASSBAND_NORMAL};
|
||||
pbwidth_t wb;
|
||||
if (m_->freq_query_works_
|
||||
if (m_->freq_query_works_ && m_->mode_query_works_
|
||||
&& (!m_->get_vfo_works_ || !rig_get_function_ptr (m_->model_, RIG_FUNCTION_GET_VFO)))
|
||||
{
|
||||
// Icom have deficient CAT protocol with no way of reading which
|
||||
@ -760,7 +760,7 @@ int HamlibTransceiver::do_start ()
|
||||
|
||||
m_->reversed_ = RIG_VFO_B == v;
|
||||
|
||||
if (m_->mode_query_works_ && !(rig_get_caps_int (m_->model_, RIG_CAPS_TARGETABLE_VFO) & (RIG_TARGETABLE_MODE | RIG_TARGETABLE_PURE)))
|
||||
if (m_->mode_query_works_ && !(rig_get_caps_int (m_->model_, RIG_CAPS_TARGETABLE_VFO) & RIG_TARGETABLE_MODE))
|
||||
{
|
||||
if (RIG_OK == rig_get_mode (m_->rig_.data (), RIG_VFO_CURR, &m, &w))
|
||||
{
|
||||
@ -911,9 +911,9 @@ void HamlibTransceiver::do_frequency (Frequency f, MODE m, bool no_ignore)
|
||||
// to frequency such as the TS-2000 auto mode setting
|
||||
CAT_TRACE ("rig_set_mode mode=" << rig_strrmode (new_mode));
|
||||
m_->error_check (rig_set_mode (m_->rig_.data (), target_vfo, new_mode, RIG_PASSBAND_NOCHANGE), tr ("setting current VFO mode"));
|
||||
// set mode on VFOB too if we are in split
|
||||
if (state ().split()) rig_set_mode (m_->rig_.data (), RIG_VFO_B, new_mode, RIG_PASSBAND_NOCHANGE), tr ("setting VFOB mode");
|
||||
}
|
||||
// set mode on VFOB too if we are in split
|
||||
if (state ().split()) rig_set_mode (m_->rig_.data (), RIG_VFO_B, new_mode, RIG_PASSBAND_NOCHANGE), tr ("setting VFOB mode");
|
||||
update_mode (m);
|
||||
}
|
||||
}
|
||||
@ -1147,7 +1147,7 @@ void HamlibTransceiver::do_poll ()
|
||||
|
||||
if ((WSJT_RIG_NONE_CAN_SPLIT || !m_->is_dummy_)
|
||||
&& state ().split ()
|
||||
&& (rig_get_caps_int (m_->model_, RIG_CAPS_TARGETABLE_VFO) & (RIG_TARGETABLE_FREQ | RIG_TARGETABLE_PURE))
|
||||
&& (rig_get_caps_int (m_->model_, RIG_CAPS_TARGETABLE_VFO) & RIG_TARGETABLE_FREQ)
|
||||
&& !m_->one_VFO_)
|
||||
{
|
||||
// only read "other" VFO if in split, this allows rigs like
|
||||
|
@ -80,7 +80,7 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
|
||||
:jtalert: https://hamapps.com/[JTAlert]
|
||||
:launchpadki7mt: https://launchpad.net/~ki7mt[KI7MT PPA's]
|
||||
:log4om: https://www.log4om.com[Log4OM]
|
||||
:lunarEchoes: https://sourceforge.net/projects/wsjt/files/wsjtx-{VERSION}/LunarEchoes_QEX.pdf[QEX]
|
||||
:lunarEchoes: https://wsjt.sourceforge.io/LunarEchoes_QEX.pdf[QEX]
|
||||
:msk144: https://wsjt.sourceforge.io/MSK144_Protocol_QEX.pdf[QEX]
|
||||
:msvcpp_redist: https://www.microsoft.com/en-ph/download/details.aspx?id=40784[Microsoft VC++ 2013 Redistributable]
|
||||
:msys_url: https://sourceforge.net/projects/mingwbuilds/files/external-binary-packages/[MSYS Download]
|
||||
@ -94,11 +94,11 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
|
||||
:sourceforge-jtsdk: https://sourceforge.net/projects/jtsdk[SourceForge JTSDK]
|
||||
:ubuntu_sdk: https://launchpad.net/~ubuntu-sdk-team/+archive/ppa[Ubuntu SDK Notice]
|
||||
:win_openssl_packages: https://slproweb.com/products/Win32OpenSSL.html[Windows OpenSSL Packages]
|
||||
:win32_openssl: https://slproweb.com/download/Win32OpenSSL_Light-1_1_1L.msi[Win32 OpenSSL Light Package]
|
||||
:win64_openssl: https://slproweb.com/download/Win64OpenSSL_Light-1_1_1L.msi[Win64 OpenSSL Light Package]
|
||||
:win32_openssl: https://slproweb.com/download/Win32OpenSSL_Light-1_1_1s.msi[Win32 OpenSSL Light Package]
|
||||
:win64_openssl: https://slproweb.com/download/Win64OpenSSL_Light-1_1_1s.msi[Win64 OpenSSL Light Package]
|
||||
:writelog: https://writelog.com/[Writelog]
|
||||
:wsjtx_group: https://groups.io/g/WSJTX[WSJTX Group]
|
||||
:wsjtx_group2: https://groups.io/g/WSJTX[join the group]
|
||||
:wsjtx_group: https://groups.io/g/wsjtgroup[WSJT GROUP User Forum]
|
||||
:wsjtx_group2: https://groups.io/g/wsjtgroup/join[join the group]
|
||||
:wsjtx: https://sourceforge.net/projects/wsjt/files/wsjtx-{VERSION}/wsjtx.html[WSJT-X]
|
||||
:wspr0_guide: https://wsjt.sourceforge.io/WSPR0_Instructions.TXT[WSPR0 Guide]
|
||||
:wspr: https://sourceforge.net/projects/wsjt/files/wsjtx-{VERSION}/wspr.html[WSPR Home Page]
|
||||
@ -106,7 +106,7 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
|
||||
:wsprnet_activity: https://wsprnet.org/drupal/wsprnet/activity[WSPRnet Activity page]
|
||||
|
||||
// Download Links
|
||||
:cty_dat: https://www.country-files.com/cty/[Amateur Radio Country Files]
|
||||
:cty_dat: https://www.country-files.com/bigcty/cty.dat/[Amateur Radio Country Files]
|
||||
:jtbridge: https://jt-bridge.eller.nu/[JT-Bridge]
|
||||
:jtsdk_doc: https://sourceforge.net/projects/wsjt/files/wsjtx-{VERSION}/JTSDK-DOC.exe[Download]
|
||||
:jtsdk_installer: https://sourceforge.net/projects/jtsdk/files/win32/2.0.0/JTSDK-2.0.0-B2-Win32.exe/download[Download]
|
||||
@ -121,8 +121,8 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
|
||||
:svn: https://subversion.apache.org/packages.html#windows[Subversion]
|
||||
:win32: https://sourceforge.net/projects/wsjt/files/wsjtx-{VERSION}/wsjtx-{VERSION}-win32.exe[wsjtx-{VERSION}-win32.exe]
|
||||
:win64: https://sourceforge.net/projects/wsjt/files/wsjtx-{VERSION}/wsjtx-{VERSION}-win64.exe[wsjtx-{VERSION}-win64.exe]
|
||||
:wsjt-devel: https://sourceforge.net/p/wsjt/mailman/wsjt-devel/[join the group]
|
||||
:wsjt-devel2: https://sourceforge.net/p/wsjt/mailman/wsjt-devel/[subscribe to the list]
|
||||
:wsjt-devel: https://sourceforge.net/projects/wsjt/lists/wsjt-devel/[join the group]
|
||||
:wsjt-devel2: https://sourceforge.net/projects/wsjt/lists/wsjt-devel/[subscribe to the list]
|
||||
:wsjt_repo: https://sourceforge.net/p/wsjt/wsjt_orig/ci/master/tree/[WSJT Source Repository]
|
||||
:wspr_code: https://sourceforge.net/projects/wsjt/files/wsjtx-{VERSION}/WSPRcode.exe[WSPRcode.exe]
|
||||
:wspr_svn: https://sourceforge.net/p/wsjt/wspr/ci/master/tree/[WSPR Source Repository]
|
||||
@ -134,7 +134,7 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
|
||||
:dev_mail_svn: https://sourceforge.net/auth/subscriptions/[WSJT SVN Archives]
|
||||
:devmail: mailto:wsjt-devel@lists.sourceforge.net[wsjt-devel@lists.sourceforge.net]
|
||||
:devmail1: mailto:wsjt-devel@lists.sourceforge.net[Post Message]
|
||||
:wsjtgroup_mail: mailto:WSJTX@groups.io[Post Message]
|
||||
:wsjtgroup_mail: mailto:wsjtgroup@groups.io[Post Message]
|
||||
:greg_beam: mailto:ki7mt@yahoo.com[KI7MT]
|
||||
:joe_taylor: mailto:joe@princeton.edu[K1JT]
|
||||
:stuart_rackman: mailto:srackham@gmail.com[Stuart Rackham]
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
The _WSJT_ project was started by *K1JT* in 2001. Since 2005 it has
|
||||
been an Open Source project, and it has included the programs _WSJT_,
|
||||
_MAP65_, _WSPR_, _WSJT-X_, and _WSPR-X_. *G4WJS* (since 2013), *K9AN*
|
||||
(since 2015), *IV3NWV* (since 2016), *KG4IYS* (since 2021), and
|
||||
*DG2YCB* (since 2021) have made major contributions to _WSJT-X_.
|
||||
_MAP65_, _WSPR_, _WSJT-X_, and _QMAP_. *G4WJS* (since 2013), *K9AN*
|
||||
(since 2015), *IV3NWV* (since 2016), *DG2YCB* (since 2021), and
|
||||
*N9ADG* (since 2022) have made major contributions to _WSJT-X_.
|
||||
Together with K1JT they now form the core development team. *G4WJS*
|
||||
and *W9MDB* have made major contributions to the _hamlib_ library, on
|
||||
which _WSJT-X_ depends for rig control.
|
||||
@ -13,12 +13,12 @@ All code in the _WSJT_ project is licensed under the GNU Public
|
||||
License (GPL). Many users of these programs, too numerous to mention
|
||||
here individually, have contributed suggestions and advice that have
|
||||
greatly aided the development of _WSJT_ and its sister programs. For
|
||||
_WSJT-X_ in particular, we acknowledge contributions from *AC6SL,
|
||||
AE4JY, DF2ET, DJ0OT, G3WDG, G4KLA, IW3RAB, K3WYC, KA1GT, KA6MAL, KA9Q,
|
||||
KB1ZMX, KD6EKQ, KI7MT, KK1D, ND0B, PY2SDR, VE1SKY, VK3ACF, VK4BDJ,
|
||||
VK7MO, W3DJS, W3SZ, W4TI, W4TV, and W9MDB*. Each of these amateurs
|
||||
has helped to bring the program’s design, code, testing, and/or
|
||||
documentation to its present state.
|
||||
_WSJT-X_ in particular, in addition to those mentioned above we
|
||||
acknowledge contributions from *AC6SL, AE4JY, DF2ET, DJ0OT, G3WDG,
|
||||
G4KLA, IW3RAB, K3WYC, KA1GT, KA6MAL, KA9Q, KB1ZMX, KD6EKQ, KI7MT,
|
||||
KK1D, ND0B, PY2SDR, VE1SKY, VK3ACF, VK4BDJ, VK7MO, W3DJS, W3SZ, W4TI,
|
||||
and W4TV*. Each of these amateurs has helped to bring the program’s
|
||||
design, code, testing, and/or documentation to its present state.
|
||||
|
||||
Most of the color palettes for the _WSJT-X_ waterfall were copied from
|
||||
the excellent, well documented, open-source program _fldigi_, by *W1HKJ*
|
||||
|
@ -7,7 +7,9 @@ K1**JT**,`" while the suffix "`*-X*`" indicates that _WSJT-X_ started
|
||||
as an extended branch of an earlier program, _WSJT_, first released in
|
||||
2001. Bill Somerville, G4WJS, Steve Franke, K9AN, and Nico Palermo,
|
||||
IV3NWV, have been major contributors to development of _WSJT-X_ since
|
||||
2013, 2015, and 2016, respectively.
|
||||
2013, 2015, and 2016, respectively. Bill Somerville died suddenly and
|
||||
unexpectedly in December 2021; Uwe Risse, DG2YCB, joined the core
|
||||
development team soon afterward, and Brian Moran, N9ADG, in 2022.
|
||||
|
||||
_WSJT-X_ Version {VERSION_MAJOR}.{VERSION_MINOR} offers eleven
|
||||
different protocols or modes: *FST4*, *FT4*, *FT8*, *JT4*, *JT9*,
|
||||
|
@ -1,68 +1,60 @@
|
||||
[[NEW_FEATURES]]
|
||||
=== New in Version {VERSION_MAJOR}.{VERSION_MINOR}
|
||||
|
||||
- _WSJT-X 2.6_ implements new features supporting the ARRL
|
||||
International Digital Contest and its distance based scoring. The
|
||||
*Call 1st* checkbox has been replaced by a drop-down control offering
|
||||
*CQ Max Dist* as an alternative. A new window labeled *Active
|
||||
Stations* displays a list of received but unworked callsigns, sorted
|
||||
in decreasing order of potential contest points. With option *CQ Max
|
||||
Dist* selected, the program will select the reply to your CQ that
|
||||
yields the most contest points. You can click on a line in the Active
|
||||
Stations window to call that station.
|
||||
_WSJT-X 2.7_ introduces a new program called *QMAP*, a new Special
|
||||
Operating Activity *Q65 Pileup*, an option to *Update Hamlib* at the
|
||||
click of a button, and a number of other enhancements and bug fixes.
|
||||
|
||||
- Decoding performance for FT8 and Q65 has been improved in a variety
|
||||
of situations with available _a priori_ (AP) information.
|
||||
- QMAP and Q65 Pileup mode are of particular interest to those engaged
|
||||
in Earth-Moon-Earth (EME) communication, but other applications may
|
||||
be found for them as well. QMAP is currently available for Windows
|
||||
only; it is derived from MAP65, an older program used since 2007 for
|
||||
EME. QMAP provides single-polarization receive-only capabilities for
|
||||
any one of the 60-second submodes of Q65. It allows you to monitor
|
||||
all traffic in a 90 kHz sub-band while conducting EME QSOs in the
|
||||
usual way with _WSJT-X_. Q65 Pileup mode helps DX operators using
|
||||
Q65 in pileup circumstances with many simultaneous callers and very
|
||||
weak signals, such as those experienced by 6-meter EME DXpeditions.
|
||||
Further details on QMAP and Q65 Pileup mode are available in a
|
||||
Quick-Start guide posted here:
|
||||
https://wsjt.sourceforge.io/Quick_Start_WSJT-X_2.7_QMAP.pdf
|
||||
|
||||
- *Echo* mode now offers a *Clear Avg* button and produces reliable
|
||||
measurements of SNR even when Doppler spread is large. Its *Monitor*
|
||||
function can be used to measure SNR for a received unmodulated carrier
|
||||
such as a key-down test signal emitted by another station and
|
||||
reflected from the Moon, and also to measure Sun, Moon, and ground
|
||||
noise as aids for optimizing an EME station's performance.
|
||||
- A button *Update Hamlib* now appears on the *Settings -> Radio* tab.
|
||||
On Windows it allows the user to automatically download and install
|
||||
the latest version of the rig-control features in Hamlib. The
|
||||
previously used version is backed up, so you can easily revert the
|
||||
procedure if necessary. Names and dates of the active and backup
|
||||
versions are clearly displayed.
|
||||
|
||||
- New buttons on the main window allow quick changes between modes
|
||||
FT4, FT8, MSK144, Q65, and JT65, and toggling FT8 Hound mode ON/OFF.
|
||||
- Spotting to *PSK Reporter* has been made more efficient. Redundant
|
||||
spots are omitted, and all posts are spread more widely in time. If
|
||||
your station locator is changed, for example during portable
|
||||
operations, your new locator will be sent automatically to PSK
|
||||
Reporter.
|
||||
|
||||
- New convenience features allow Fox operators to react more quickly
|
||||
to particular QSO situations. A two-column table in Tab 2 provides an
|
||||
overview of the queue and of callsigns with QSOs in progress. Fox
|
||||
operator can change the ordering of callsigns in the queue, allowing
|
||||
reaction to changes in propagation. Fox now responds automatically
|
||||
for another two cycles to stations whose report has not been received,
|
||||
increasing the success rate for difficult QSOs.
|
||||
- *Fox* mode now provides more convenient handling of the two callsign
|
||||
queues, and Fox's Log window displays statistical data on recent QSO
|
||||
rate. Multi-streamed messages transmitted by _MSHV_ are now handled
|
||||
properly when _WSJT-X_ is in *Hound* mode.
|
||||
|
||||
- The Working frequency table now offers save/restore capability and
|
||||
better handling of more than one frequency per mode-band
|
||||
combination. You can set preferred frequencies, and WSJT-X will select
|
||||
these when you change band or mode. You can label a tabled frequency
|
||||
with a description, for example a DXpedition callsign, and set Start
|
||||
and End date and time so the frequencies automatically appear and
|
||||
disappear from the displayed options. You can load a publicly
|
||||
available frequency table from a file, to easily make such DXpedition
|
||||
data available to the program.
|
||||
- The cty.dat file can now be updated by clicking a button on the
|
||||
*Settings -> Colors* tab.
|
||||
|
||||
- Optional color highlighting is provided for specified DX Call and DX
|
||||
Grid, and for messages containing RR73 or 73.
|
||||
- The FT Roundup message protocol now allows the exchange of static
|
||||
4-digit numbers in place of serial numbers. This extends the
|
||||
usability of the FT RU protocol for other contest types.
|
||||
|
||||
- New options are provided for writing to file ALL.TXT. You can
|
||||
request automatic starting of a new file every month or every year,
|
||||
and you can disable writing altogether.
|
||||
- Features for main-window switching between modes have been enhanced
|
||||
so that submode and status of the *Sh* and *Fast* checkboxes are
|
||||
saved and restored by mode. Right-click events were made more
|
||||
intuitive and consistent. Right-clicking the Q65 button enables Q65
|
||||
Pileup mode, and a left-click brings you back to the normal Q65
|
||||
mode. Right-click on the JT65 button switches to JT9 mode.
|
||||
|
||||
- Settings for T/R period and Submode are remembered by mode when you
|
||||
switch directly between modes: for example, MSK144-15, Q65-60A, or
|
||||
FST4-120.
|
||||
- Message averaging is now allowed only when *VHF features* are
|
||||
enabled. Main window text box labels are changed to read "`Single
|
||||
Period Decodes`" and "`Average Decodes`" when averaging is enabled.
|
||||
|
||||
- Tx and Rx audio frequencies are remembered and restored when you
|
||||
return from a mode that sets a default frequency 1500 Hz (MSK144,
|
||||
FST4W, Echo, WSPR, FreqCal), then switching back to FT4, FT8, Q65,
|
||||
FST4, or JT65.
|
||||
Further details on minor changes can be found in the Release Notes,
|
||||
accessible from the _WSJT-X_ *Help* menu.
|
||||
|
||||
- Rig control is provided for some new radios, and bug fixes for
|
||||
controlling others.
|
||||
|
||||
- New features in _MAP65_ (available for Windows only) include an aid
|
||||
for measuring antenna pointing errors and an ability to read the file
|
||||
wsjtx.log (kept by _WSJT-X_) to recognize EME contest dupes. In
|
||||
addition, _MAP65_ now sends additional information to file azel.dat
|
||||
and offers optional digital scaling of input I/Q data.
|
||||
|
@ -31,7 +31,7 @@ image::RadioTab.png[align="center",alt="Radio Tab"]
|
||||
suitable.
|
||||
|
||||
* _CAT Control_: To have _WSJT-X_ control the radio directly rather
|
||||
than though another program, make the following settings:
|
||||
than through another program, make the following settings:
|
||||
|
||||
** Select the *Serial Port* or *Network Server* including the service
|
||||
port number used to communicate with your radio.
|
||||
|
@ -2,18 +2,17 @@
|
||||
|
||||
The best source of help in setting up your station or configuring
|
||||
_WSJT-X_ is the {wsjtx_group} at email address
|
||||
wsjtx@groups.io. The chances are good that someone with
|
||||
wsjtgroup@groups.io. The chances are good that someone with
|
||||
similar interests and equipment has already solved your problem and
|
||||
will be happy to help. To post messages here you will need to
|
||||
{wsjt-devel}.
|
||||
{wsjtx_group2}.
|
||||
|
||||
=== Bug Reports
|
||||
|
||||
One of your responsibilities as a _WSJT-X_ user is to help the
|
||||
volunteer programmers to make the program better. Bugs may be
|
||||
reported to the WSJTX forum on Groups.io {wsjtgroup_mail} or the WSJT
|
||||
Developers list (wsjt-devel@lists.sourceforge.net). Again, you will
|
||||
need to {wsjtx_group2} or {wsjt-devel2}.
|
||||
reported preferably to the WSJT Developers email list
|
||||
(wsjt-devel@lists.sourceforge.net). You will need to {wsjt-devel2}.
|
||||
|
||||
To be useful, bug reports should include at least the following
|
||||
information:
|
||||
|
@ -35,7 +35,7 @@ Rx frequency along with any decodes addressed to *My Call* (K1JT in this case).
|
||||
The red marker on the waterfall scale indicates your
|
||||
Tx frequency.
|
||||
|
||||
Twenty one FT8 signals are decoded from the example file. The number
|
||||
Twenty-one FT8 signals are decoded from the example file. The number
|
||||
of decodes is shown in a box at the bottom of the main window.
|
||||
When this file was recorded HA5WA was finishing a QSO with K1JT, and
|
||||
his 73 message is shown in red because it is addressed to *My Call* (in this case K1JT).
|
||||
|
@ -34,7 +34,7 @@ frequency control on the main window will be updated accordingly.
|
||||
frequency marker and its associated control on the main window will
|
||||
follow your frequency selections.
|
||||
|
||||
- Do the same thing with the *Ctrl* key held down. Now the both colored
|
||||
- Do the same thing with the *Ctrl* key held down. Now both colored
|
||||
markers and both spinner controls will follow your selections.
|
||||
|
||||
- Now double-click on any of the lines of decoded text in the Band
|
||||
|
@ -26,7 +26,7 @@ on bands above 1.2 GHz.
|
||||
|
||||
To activate the VHF-and-up features:
|
||||
|
||||
- On the *Settings | General* tab check *Enable VHF/UHF/Microwave
|
||||
- On the *Settings | General* tab check *Enable VHF and submode
|
||||
features* and *Single decode*.
|
||||
|
||||
- For EME, check *Decode after EME delay* to allow for extra path
|
||||
@ -291,14 +291,16 @@ communication.
|
||||
|
||||
For lunar echoes, _WSJT_ generates short fixed-frequency transmissions
|
||||
that alternate with reception intervals at the appropriate
|
||||
Doppler-shifted frequency. With *Split Operation* set to *Rig* or
|
||||
*Fake It* on the *Settings | Radio* tab, check *Doppler tracking* and
|
||||
*Own Echo* on the Astronomical Data window. Point your antenna at the
|
||||
Moon and click *Enable Tx* on the main window to start a sequence of
|
||||
echo measurements. Each cycle takes 6 seconds. If strong enough,
|
||||
echoes will be visible in the waterfall. Their average spectrum will
|
||||
be displayed in the Echo Graph window, and numerical parameters of the
|
||||
measurements appear in the main window:
|
||||
Doppler-shifted frequency. Be sure that *Enable VHF and submode
|
||||
features* has been checked on the *Settings | General* tab. With
|
||||
*Split Operation* set to *Rig* or *Fake It* on the *Settings | Radio*
|
||||
tab, check *Doppler tracking* and *Own Echo* on the Astronomical Data
|
||||
window. Point your antenna at the Moon and click *Enable Tx* on the
|
||||
main window to start a sequence of echo measurements. Each cycle
|
||||
takes 6 seconds. If strong enough, echoes will be visible in the
|
||||
waterfall. Their average spectrum will be displayed in the Echo Graph
|
||||
window, and numerical parameters of the measurements appear in the
|
||||
main window:
|
||||
|
||||
image::Echo_1296.png[align="center",alt="Echo 144 MHz"]
|
||||
|
||||
|
28
eclipse.txt
Normal file
28
eclipse.txt
Normal file
@ -0,0 +1,28 @@
|
||||
# Some test dates added for PSKReporter testing#
|
||||
2023-06-10T21:30:00Z
|
||||
2023-06-15T18:00:00Z
|
||||
2023-07-01T18:00:00Z
|
||||
2023-07-15T18:00:00Z
|
||||
2023-08-01T18:00:00Z
|
||||
2023-08-15T18:00:00Z
|
||||
2023-09-01T18:00:00Z
|
||||
2023-09-15T18:00:00Z
|
||||
2023-10-01T18:00:00Z
|
||||
# From https://eclipse.gsfc.nasa.gov/SEdecade/SEdecade2021.html
|
||||
2023-10-14T18:00:40Z
|
||||
2024-04-08T18:18:29Z
|
||||
2024-10-02T18:46:13Z
|
||||
2025-03-29T10:48:36Z
|
||||
2025-09-21T19:43:04Z
|
||||
2026-02-17T12:13:05Z
|
||||
2026-08-12T17:47:05Z
|
||||
2027-02-06T16:00:47Z
|
||||
2027-08-02T10:04:49Z
|
||||
2028-01-26T15:08:58Z
|
||||
2028-07-22T02:56:39Z
|
||||
2029-01-14T17:13:47Z
|
||||
2029-06-12T04:06:13Z
|
||||
2029-07-11T15:37:18Z
|
||||
2029-12-05T15:03:57Z
|
||||
2030-06-01T06:29:13Z
|
||||
2030-11-25T06:51:37Z
|
42
lib/77bit/hash22calc.f90
Normal file
42
lib/77bit/hash22calc.f90
Normal file
@ -0,0 +1,42 @@
|
||||
program hash22calc
|
||||
! Given a valid callsign, calculate and print its 22-bit hash.
|
||||
|
||||
use packjt77
|
||||
|
||||
character*13 callsign
|
||||
character*1 c
|
||||
character*6 basecall
|
||||
logical cok
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.ne.1) then
|
||||
print*,'Given a valid callsign, print its 22-bit hash.'
|
||||
print*,'Usage: hash22calc <callsign>'
|
||||
print*,' e.g. hash22calc W9ABC'
|
||||
go to 999
|
||||
endif
|
||||
call getarg(1,callsign)
|
||||
|
||||
! convert to upper case
|
||||
ilen=len(trim(callsign))
|
||||
do i=1, ilen
|
||||
c=callsign(i:i)
|
||||
if(c.ge.'a' .and. c.le.'z') c=char(ichar(c)-32) !Force upper case
|
||||
callsign(i:i)=c
|
||||
enddo
|
||||
|
||||
! check for a valid callsign
|
||||
call chkcall(callsign,basecall,cok)
|
||||
if(.not.cok) then
|
||||
print*,'Invalid callsign'
|
||||
print*,'Usage: hash22calc <callsign>'
|
||||
goto 999
|
||||
endif
|
||||
|
||||
! calculate the hash
|
||||
n22 = ihashcall(callsign,22)
|
||||
write(*,'(a,i7.7)') callsign,n22
|
||||
|
||||
999 end program hash22calc
|
||||
|
||||
include '../chkcall.f90'
|
@ -370,15 +370,28 @@ subroutine unpack77(c77,nrx,msg,unpk77_success)
|
||||
msg=adjustl(msg)
|
||||
|
||||
else if(i3.eq.0 .and. n3.eq.6) then
|
||||
read(c77(49:50),'(2b1)') j2a,j2b
|
||||
itype=2
|
||||
if(j2b.eq.0 .and. j2a.eq.0) itype=1
|
||||
if(j2b.eq.0 .and. j2a.eq.1) itype=3
|
||||
read(c77(48:50),'(3b1)') j48,j49,j50
|
||||
! bits 48:50
|
||||
! itype=1: x00
|
||||
! itype=2: xx1
|
||||
! itype=3: 010
|
||||
if(j50.eq.1) then
|
||||
itype=2
|
||||
else if(j49.eq.0) then
|
||||
itype=1
|
||||
else if(j48.eq.0) then
|
||||
itype=3
|
||||
else
|
||||
itype=-1
|
||||
unpk77_success=.false.
|
||||
endif
|
||||
|
||||
if(itype.eq.1) then
|
||||
! WSPR Type 1
|
||||
read(c77,2010) n28,igrid4,idbm
|
||||
2010 format(b28.28,b15.15,b5.5)
|
||||
idbm=nint(idbm*10.0/3.0)
|
||||
if(idbm.lt.0 .or. idbm.gt.60) unpk77_success=.false.
|
||||
call unpack28(n28,call_1,unpk28_success)
|
||||
if(.not.unpk28_success) unpk77_success=.false.
|
||||
call to_grid4(igrid4,grid4,unpkg4_success)
|
||||
@ -392,6 +405,7 @@ subroutine unpack77(c77,nrx,msg,unpk77_success)
|
||||
read(c77,2020) n28,npfx,idbm
|
||||
2020 format(b28.28,b16.16,b5.5)
|
||||
idbm=nint(idbm*10.0/3.0)
|
||||
if(idbm.lt.0 .or. idbm.gt.60) unpk77_success=.false.
|
||||
call unpack28(n28,call_1,unpk28_success)
|
||||
if(.not.unpk28_success) unpk77_success=.false.
|
||||
write(crpt,'(i3)') idbm
|
||||
@ -460,13 +474,17 @@ subroutine unpack77(c77,nrx,msg,unpk77_success)
|
||||
i=index(call_1,' ')
|
||||
if(i.ge.4 .and. ipa.eq.1 .and. i3.eq.1) call_1(i:i+1)='/R'
|
||||
if(i.ge.4 .and. ipa.eq.1 .and. i3.eq.2) call_1(i:i+1)='/P'
|
||||
if(i.ge.4) call add_call_to_recent_calls(call_1)
|
||||
if(i.ge.4) call add_call_to_recent_calls(call_1)
|
||||
endif
|
||||
if(index(call_2,'<').le.0) then
|
||||
i=index(call_2,' ')
|
||||
if(i.ge.4 .and. ipb.eq.1 .and. i3.eq.1) call_2(i:i+1)='/R'
|
||||
if(i.ge.4 .and. ipb.eq.1 .and. i3.eq.2) call_2(i:i+1)='/P'
|
||||
if(i.ge.4) call add_call_to_recent_calls(call_2)
|
||||
if(i.ge.4) then
|
||||
call add_call_to_recent_calls(call_2)
|
||||
! only hash the "from" call
|
||||
call save_hash_call(call_2,ndum10,ndum12,ndum22)
|
||||
endif
|
||||
endif
|
||||
if(igrid4.le.MAXGRID4) then
|
||||
call to_grid4(igrid4,grid4,unpkg4_success)
|
||||
@ -546,6 +564,7 @@ subroutine unpack77(c77,nrx,msg,unpk77_success)
|
||||
call_1=call_3
|
||||
call_2=adjustl(c11)//' '
|
||||
call add_call_to_recent_calls(call_2)
|
||||
call save_hash_call(call_2,ndum10,ndum12,ndum22)
|
||||
if(nrx.eq.1 .and. &
|
||||
dxcall13_set .and. mycall13_set .and. &
|
||||
call_2.eq.dxcall13 .and. &
|
||||
@ -1526,7 +1545,7 @@ subroutine add_call_to_recent_calls(callsign)
|
||||
endif
|
||||
|
||||
! Make sure that callsign is hashed
|
||||
call save_hash_call(callsign,n10,n12,n22)
|
||||
! call save_hash_call(callsign,n10,n12,n22) ! commented out - do this in the calling routine:
|
||||
|
||||
return
|
||||
end subroutine add_call_to_recent_calls
|
||||
|
142
lib/cablog.f90
Normal file
142
lib/cablog.f90
Normal file
@ -0,0 +1,142 @@
|
||||
program cablog
|
||||
|
||||
character*100 line,infile,outfile
|
||||
character cband*4,cmode*2,cdate*10,cutc*4,callsign*10,mycall*10
|
||||
character csent*4,crcvd*4,dsent*4,drcvd*4,g1*4
|
||||
character*3 cmo(12)
|
||||
integer icomma(20)
|
||||
logical map65
|
||||
logical isgrid,gridx
|
||||
data cmo/'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep', &
|
||||
'Oct','Nov','Dec'/
|
||||
|
||||
isgrid(g1)=g1(1:1).ge.'A' .and. g1(1:1).le.'R' .and. g1(2:2).ge.'A' .and. &
|
||||
g1(2:2).le.'R' .and. g1(3:3).ge.'0' .and. g1(3:3).le.'9' .and. &
|
||||
g1(4:4).ge.'0' .and. g1(4:4).le.'9' .and. g1(1:4).ne.'RR73'
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.ne.4) then
|
||||
print*,"Program cablog converts file 'wsjtx.log' written by WSJT-X"
|
||||
print*,"(or wsjt.log written by MAP65) to a bare-bones Cabrillo"
|
||||
print*,"log for the ARRL International EME Contest. You will"
|
||||
print*,"certainly need to edit the header information, and you may"
|
||||
print*,"edit the log elsewhere as required."
|
||||
print*,' '
|
||||
print*,'Usage: cablog <MyCall> <sent> <rcvd> <infile>'
|
||||
print*,'Examples: cablog W2ZQ -15 -16 wsjtx.log'
|
||||
print*,' cablog W2ZQ O O wsjt.log'
|
||||
go to 999
|
||||
endif
|
||||
call getarg(1,mycall)
|
||||
outfile=trim(mycall)//'.log'
|
||||
call getarg(2,dsent)
|
||||
gridx=isgrid(dsent)
|
||||
call getarg(3,drcvd)
|
||||
call getarg(4,infile)
|
||||
open(10,file=trim(infile),status='old')
|
||||
open(12,file=trim(outfile),status='unknown')
|
||||
|
||||
write(12,1000)
|
||||
1000 format('START-OF-LOG: 3.0'/ &
|
||||
'CONTEST: ARRL-EME'/ &
|
||||
'CALLSIGN: '/ &
|
||||
'CATEGORY-OPERATOR: '/ &
|
||||
'CATEGORY-BAND: '/ &
|
||||
'CATEGORY-MODE: '/ &
|
||||
'EMAIL: '/ &
|
||||
'OPERATORS: '/ &
|
||||
'CATEGORY-POWER: HIGH'/ &
|
||||
'CATEGORY-TRANSMITTER: ONE'/ &
|
||||
'CATEGORY-STATION: FIXED'/ &
|
||||
'CATEGORY-TIME: 24-HOURS'/ &
|
||||
'CATEGORY-ASSISTED: ASSISTED'/ &
|
||||
'LOCATION: SNJ'/ &
|
||||
'CLAIMED-SCORE: '/ &
|
||||
'CLUB: '/ &
|
||||
'NAME: '/ &
|
||||
'ADDRESS: '/ &
|
||||
'ADDRESS: '/ &
|
||||
'ADDRESS: '/ &
|
||||
'CREATED-BY: cablog (C) K1JT')
|
||||
|
||||
n=0
|
||||
map65=.false.
|
||||
|
||||
do nn=1,9999
|
||||
read(10,'(a100)',end=900) line
|
||||
if(len(trim(line)).eq.0) cycle
|
||||
if(line(6:6).ge.'A' .and. line(6:6).le.'Z') map65=.true.
|
||||
n=n+1
|
||||
k=0
|
||||
do j=1,100
|
||||
if(line(j:j).eq.',') then
|
||||
k=k+1
|
||||
icomma(k)=j
|
||||
endif
|
||||
enddo
|
||||
cmode='DG'
|
||||
if(index(line,',CW,').gt.10) cmode='CW'
|
||||
|
||||
if(map65) then
|
||||
do i=1,12
|
||||
if(cmo(i).eq.line(6:8)) write(cdate(6:7),'(i2.2)') i
|
||||
enddo
|
||||
cdate(1:5)=line(1:5)
|
||||
cdate(8:10)=line(9:11)
|
||||
cutc=line(13:14)//line(16:17)
|
||||
i0=index(line(19:),',')
|
||||
callsign=line(19:17+i0)
|
||||
cband='144 '
|
||||
csent=dsent
|
||||
crcvd=drcvd
|
||||
else
|
||||
cdate=line(1:10)
|
||||
cutc=line(32:33)//line(35:36)
|
||||
i0=index(line(41:),',')
|
||||
callsign=line(41:39+i0)
|
||||
read(line(icomma(6)+1:icomma(7)-1),*,err=10,end=10) freq
|
||||
go to 20
|
||||
10 print*,'***Error at line ',n
|
||||
print*,trim(line)
|
||||
20 if(freq.ge.50.0 .and. freq.le.54.0) cband='50 '
|
||||
if(freq.ge.144.0 .and. freq.le.148.0) cband='144 '
|
||||
if(freq.ge.28.0 .and. freq.le.29.0) cband='144 '
|
||||
if(freq.ge.222.0 .and. freq.le.225.0) cband='222 '
|
||||
if(freq.ge.420.0 .and. freq.le.450.0) cband='432 '
|
||||
if(freq.ge.902.0 .and. freq.le.928.0) cband='902 '
|
||||
if(freq.ge.1240.0 .and. freq.le.1300.0) cband='1.2G'
|
||||
if(freq.ge.2300.0 .and. freq.le.2450.0) cband='2.3G'
|
||||
if(freq.ge.3300.0 .and. freq.le.3500.0) cband='3.4G'
|
||||
if(freq.ge.5650.0 .and. freq.le.5925.0) cband='5.7G'
|
||||
if(freq.ge.10000.0 .and. freq.le.10500.0) cband='10G '
|
||||
if(freq.ge.24000.0 .and. freq.le.24250.0) cband='24G '
|
||||
if(icomma(8).eq.icomma(9)-1) then
|
||||
csent=dsent
|
||||
else
|
||||
csent=line(icomma(8)+1:icomma(9)-1)
|
||||
endif
|
||||
if(icomma(9).eq.icomma(10)-1) then
|
||||
crcvd=drcvd
|
||||
else
|
||||
crcvd=line(icomma(9)+1:icomma(10)-1)
|
||||
endif
|
||||
endif
|
||||
if(gridx) then
|
||||
csent=dsent
|
||||
crcvd=line(icomma(5)+1:icomma(6)-1)
|
||||
endif
|
||||
|
||||
write(12,1030) cband,cmode,cdate,cutc,mycall,csent,callsign,crcvd
|
||||
1030 format('QSO: ',a4,1x,a2,1x,a10,1x,a4,1x,a6,1x,a4,4x,a10,1x,a4)
|
||||
enddo
|
||||
|
||||
900 write(12,1900)
|
||||
1900 format('END-OF-LOG:')
|
||||
write(*,1910) n,trim(outfile)
|
||||
1910 format('Processed',i5,' QSOs.'/'Output file: ',a)
|
||||
|
||||
999 end program cablog
|
||||
|
||||
!2023-10-28,00:17:00,2023-10-28,00:21:00,G7TZZ,IO92,1296.083100,Q65,-17,-17,,,,
|
||||
!2023-Nov-30,20:31,W8WN,EM77,0,Q65A
|
||||
|
57
lib/decode_msk144.f90
Normal file
57
lib/decode_msk144.f90
Normal file
@ -0,0 +1,57 @@
|
||||
subroutine decode_msk144(audio_samples, params, data_dir)
|
||||
include 'jt9com.f90'
|
||||
|
||||
! constants
|
||||
integer, parameter :: SAMPLING_RATE = 12000
|
||||
integer, parameter :: BLOCK_SIZE = 7168
|
||||
integer, parameter :: STEP_SIZE = BLOCK_SIZE / 2
|
||||
integer, parameter :: CALL_LENGTH = 12
|
||||
|
||||
! aguments
|
||||
integer*2 audio_samples(NMAX)
|
||||
type(params_block) :: params
|
||||
character(len = 500) :: data_dir
|
||||
|
||||
! parameters of mskrtd
|
||||
integer*2 :: buffer(BLOCK_SIZE)
|
||||
real :: tsec
|
||||
logical :: bshmsg = .false. ! enables shorthand messages
|
||||
logical :: btrain = .false. ! turns on training in MSK144 mode
|
||||
real*8 :: pcoeffs(5) = (/ 0.0, 0.0, 0.0, 0.0, 0.0 /); ! phase equalization
|
||||
logical :: bswl = .false.
|
||||
character(len = 80) :: line
|
||||
character(len = CALL_LENGTH) :: mycall
|
||||
character(len = CALL_LENGTH) :: hiscall
|
||||
|
||||
! local variables
|
||||
integer :: sample_count
|
||||
integer :: position
|
||||
integer :: message_count = 0
|
||||
|
||||
|
||||
! decode in 0.3s blocks
|
||||
sample_count = params%ntr * SAMPLING_RATE
|
||||
mycall = transfer(params%mycall, mycall) ! string to char[]
|
||||
hiscall = transfer(params%hiscall, hiscall)
|
||||
|
||||
do position = 1, sample_count - BLOCK_SIZE + 1, STEP_SIZE
|
||||
buffer = audio_samples(position : position + BLOCK_SIZE - 1)
|
||||
tsec = position / REAL(SAMPLING_RATE)
|
||||
|
||||
call mskrtd(buffer, params%nutc, tsec, params%ntol, params%nfqso, params%ndepth, &
|
||||
mycall, hiscall, bshmsg, btrain, pcoeffs, bswl, data_dir, line)
|
||||
|
||||
if (line(1:1) .ne. char(0)) then
|
||||
line = line(1:index(line, char(0))-1)
|
||||
write(*, 1001) line
|
||||
1001 format(a80)
|
||||
message_count = message_count + 1;
|
||||
end if
|
||||
end do
|
||||
|
||||
if (.not. params%ndiskdat) then
|
||||
write(*, 1002) 0, message_count, 0
|
||||
1002 format('<DecodeFinished>', 2i4, i9)
|
||||
end if
|
||||
|
||||
end subroutine decode_msk144
|
@ -44,7 +44,9 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
|
||||
|
||||
real ss(184,NSMAX)
|
||||
logical baddata,newdat65,newdat9,single_decode,bVHF,bad0,newdat,ex
|
||||
logical lprinthash22
|
||||
integer*2 id2(NTMAX*12000)
|
||||
integer nqf(20)
|
||||
type(params_block) :: params
|
||||
real*4 dd(NTMAX*12000)
|
||||
character(len=20) :: datetime
|
||||
@ -211,7 +213,28 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
|
||||
params%nfa,params%nfb,logical(params%nclearave), &
|
||||
single_decode,logical(params%nagain),params%max_drift, &
|
||||
logical(params%newdat),params%emedelay,mycall,hiscall,hisgrid, &
|
||||
params%nQSOProgress,ncontest,logical(params%lapcqonly),navg0)
|
||||
params%nQSOProgress,ncontest,logical(params%lapcqonly),navg0,nqf)
|
||||
params%nclearave=.false.
|
||||
|
||||
if(.not.params%nagain) then
|
||||
! Go through identified candidates again, treating each as if it had been
|
||||
! double-clicked on the waterfall.
|
||||
do k=1,20
|
||||
if(nqf(k).eq.0) exit
|
||||
if(params%nagain .and. abs(nqf(k)-params%nfqso).gt.params%ntol) cycle
|
||||
nqd=1
|
||||
navg0=0
|
||||
ntol=5
|
||||
call my_q65%decode(q65_decoded,id2,nqd,params%nutc,params%ntr, &
|
||||
params%nsubmode,nqf(k),ntol,params%ndepth, &
|
||||
params%nfa,params%nfb,logical(params%nclearave), &
|
||||
.true.,.true.,params%max_drift, &
|
||||
.false.,params%emedelay,mycall,hiscall,hisgrid, &
|
||||
params%nQSOProgress,ncontest,logical(params%lapcqonly), &
|
||||
navg0,nqf)
|
||||
enddo
|
||||
endif
|
||||
|
||||
call timer('dec_q65 ',1)
|
||||
close(17)
|
||||
go to 800
|
||||
@ -221,27 +244,30 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
|
||||
! We're in FST4 mode
|
||||
ndepth=iand(params%ndepth,3)
|
||||
iwspr=0
|
||||
lprinthash22=.false.
|
||||
params%nsubmode=0
|
||||
call timer('dec_fst4',0)
|
||||
call my_fst4%decode(fst4_decoded,id2,params%nutc, &
|
||||
params%nQSOProgress,params%nfa,params%nfb, &
|
||||
params%nfqso,ndepth,params%ntr,params%nexp_decode, &
|
||||
params%ntol,params%emedelay,logical(params%nagain), &
|
||||
logical(params%lapcqonly),mycall,hiscall,iwspr)
|
||||
logical(params%lapcqonly),mycall,hiscall,iwspr,lprinthash22)
|
||||
call timer('dec_fst4',1)
|
||||
go to 800
|
||||
endif
|
||||
|
||||
if(params%nmode.eq.241) then
|
||||
if(params%nmode.eq.241 .or. params%nmode.eq.242) then
|
||||
! We're in FST4W mode
|
||||
ndepth=iand(params%ndepth,3)
|
||||
iwspr=1
|
||||
lprinthash22=.false.
|
||||
if(params%nmode.eq.242) lprinthash22=.true.
|
||||
call timer('dec_fst4',0)
|
||||
call my_fst4%decode(fst4_decoded,id2,params%nutc, &
|
||||
params%nQSOProgress,params%nfa,params%nfb, &
|
||||
params%nfqso,ndepth,params%ntr,params%nexp_decode, &
|
||||
params%ntol,params%emedelay,logical(params%nagain), &
|
||||
logical(params%lapcqonly),mycall,hiscall,iwspr)
|
||||
logical(params%lapcqonly),mycall,hiscall,iwspr,lprinthash22)
|
||||
call timer('dec_fst4',1)
|
||||
go to 800
|
||||
endif
|
||||
@ -705,7 +731,7 @@ contains
|
||||
end subroutine ft4_decoded
|
||||
|
||||
subroutine fst4_decoded (this,nutc,sync,nsnr,dt,freq,decoded,nap, &
|
||||
qual,ntrperiod,lwspr,fmid,w50)
|
||||
qual,ntrperiod,fmid,w50)
|
||||
|
||||
use fst4_decode
|
||||
implicit none
|
||||
@ -720,7 +746,6 @@ contains
|
||||
integer, intent(in) :: nap
|
||||
real, intent(in) :: qual
|
||||
integer, intent(in) :: ntrperiod
|
||||
logical, intent(in) :: lwspr
|
||||
real, intent(in) :: fmid
|
||||
real, intent(in) :: w50
|
||||
|
||||
|
@ -20,7 +20,7 @@ subroutine four2a(a,nfft,ndim,isign,iform)
|
||||
! actual computations.
|
||||
|
||||
use fftw3
|
||||
parameter (NPMAX=2100) !Max numberf of stored plans
|
||||
parameter (NPMAX=2100) !Max number of stored plans
|
||||
parameter (NSMALL=16385) !Max half complex size of "small" FFTs
|
||||
complex a(nfft) !Array to be transformed
|
||||
complex aa(NSMALL) !Local copy of "small" a()
|
||||
|
@ -171,15 +171,15 @@ subroutine fastosd240_74(llr,k,apmask,ndeep,message74,cw,nhardmin,dmin)
|
||||
if( ndeep.eq. 1) then
|
||||
nord=1
|
||||
xlambda=0.0
|
||||
nsyncmax=np
|
||||
nsyndmax=np
|
||||
elseif(ndeep.eq.2) then
|
||||
nord=2
|
||||
xlambda=0.0
|
||||
nsyncmax=np
|
||||
nsyndmax=np
|
||||
elseif(ndeep.eq.3) then
|
||||
nord=3
|
||||
xlambda=4.0
|
||||
nsyncmax=11
|
||||
nsyndmax=11
|
||||
elseif(ndeep.eq.4) then
|
||||
nord=4
|
||||
xlambda=3.4
|
||||
@ -190,7 +190,6 @@ subroutine fastosd240_74(llr,k,apmask,ndeep,message74,cw,nhardmin,dmin)
|
||||
s2=sum(absrx(k+1:N))
|
||||
rho=s1/(s1+xlambda*s2)
|
||||
rhodmin=rho*dmin
|
||||
nerr64=-1
|
||||
do iorder=1,nord
|
||||
!beta=0.0
|
||||
!if(iorder.ge.3) beta=0.4
|
||||
@ -216,7 +215,6 @@ subroutine fastosd240_74(llr,k,apmask,ndeep,message74,cw,nhardmin,dmin)
|
||||
cw=ce
|
||||
nhardmin=sum(nxor)
|
||||
nwhspmin=nwhsp
|
||||
nerr64=sum(nxor(1:K))
|
||||
endif
|
||||
endif
|
||||
! Get the next test error pattern, iflag will go negative
|
||||
@ -224,7 +222,6 @@ subroutine fastosd240_74(llr,k,apmask,ndeep,message74,cw,nhardmin,dmin)
|
||||
call nextpat74(mi,k,iorder,iflag)
|
||||
enddo
|
||||
enddo
|
||||
|
||||
998 continue
|
||||
! Re-order the codeword to [message bits][parity bits] format.
|
||||
cw(indices)=cw
|
||||
|
@ -93,6 +93,10 @@ program fst4sim
|
||||
if(i3.eq.1) then
|
||||
write(*,*) ' mycall hiscall hisgrid'
|
||||
write(*,'(28i1,1x,i1,1x,28i1,1x,i1,1x,i1,1x,15i1,1x,3i1)') msgbits(1:77)
|
||||
elseif(i3.eq.0 .and. n3.eq.6) then
|
||||
write(*,'(a15,37x,a5)') '50-bit message','CRC24'
|
||||
write(*,'(50i1,1x,24i1)') msgbits(1:50),msgbits(51:74)
|
||||
write(*,'(a50)') '01234567890123456789012345678901234567890123456789'
|
||||
else
|
||||
write(*,'(a14)') 'Message bits: '
|
||||
write(*,'(77i1,1x,24i1)') msgbits
|
||||
|
@ -4,33 +4,47 @@ program ldpcsim240_74
|
||||
|
||||
use packjt77
|
||||
|
||||
parameter(N=240, K=74, M=N-K)
|
||||
parameter(N=240, NN=120)
|
||||
character*8 arg
|
||||
character*37 msg0
|
||||
character*37 msg0,msgsent,msg
|
||||
character*77 c77
|
||||
character*24 c24
|
||||
integer*1 msgbits(74)
|
||||
integer*1 msgbits(101)
|
||||
integer*1 apmask(240)
|
||||
integer*1 cw(240)
|
||||
integer*1 codeword(N),message74(74)
|
||||
integer ncrc24
|
||||
real rxdata(N),llr(N)
|
||||
integer modtype, graymap(0:3)
|
||||
integer*4 itone(120)
|
||||
integer channeltype
|
||||
integer lmax(1)
|
||||
real rxdata(N)
|
||||
real llr(240)
|
||||
real bitmetrics(2*NN,4)
|
||||
complex c1(4,8),c2(16,4),c4(256,2),cs(0:3,NN)
|
||||
real s2(0:65535)
|
||||
logical one(0:65535,0:15) ! 65536 8-symbol sequences, 16 bits
|
||||
logical first
|
||||
data first/.true./
|
||||
data graymap/0,1,3,2/
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.ne.5 .and. nargs.ne.6) then
|
||||
print*,'Usage: ldpcsim niter ndeep #trials s K [msg]'
|
||||
print*,'e.g. ldpcsim240_74 20 5 1000 0.85 64 "K9AN K1JT FN20"'
|
||||
if(nargs.ne.7 .and. nargs.ne.8) then
|
||||
print*,'Usage: ldpcsim maxosd norder #trials s Keff modtype channel '
|
||||
print*,'e.g. ldpcsim240_74 2 4 1000 0.85 50 1 0'
|
||||
print*,'s : if negative, then value is ignored and sigma is calculated from SNR.'
|
||||
print*,'niter: is the number of BP iterations.'
|
||||
print*,'ndeep: -1 is BP only, ndeep>=0 is OSD order'
|
||||
print*,'K :is the number of message+CRC bits and must be in the range [50,74]'
|
||||
print*,'maxosd<0: do bp only'
|
||||
print*,'maxosd=0: do bp and then call osd once with channel llrs.'
|
||||
print*,'maxosd>0: do bp and then call osc maxosd times with saved bp outputs.'
|
||||
print*,'norder : osd decoding depth'
|
||||
print*,'Keff : # of message bits, Keff must be in the range 50:74'
|
||||
print*,'modtype : 0 coherent BPSK, 1 4FSK'
|
||||
print*,'channel : 0 AWGN, 1 Rayleigh (4FSK only)'
|
||||
print*,'WSPR-format message is optional'
|
||||
return
|
||||
endif
|
||||
call getarg(1,arg)
|
||||
read(arg,*) max_iterations
|
||||
read(arg,*) maxosd
|
||||
call getarg(2,arg)
|
||||
read(arg,*) norder
|
||||
call getarg(3,arg)
|
||||
@ -39,17 +53,26 @@ program ldpcsim240_74
|
||||
read(arg,*) s
|
||||
call getarg(5,arg)
|
||||
read(arg,*) Keff
|
||||
msg0='K9AN K1JT FN20 '
|
||||
if(nargs.eq.6) call getarg(6,msg0)
|
||||
call getarg(6,arg)
|
||||
read(arg,*) modtype
|
||||
call getarg(7,arg)
|
||||
read(arg,*) channeltype
|
||||
call getarg(8,arg)
|
||||
|
||||
msg0='K9AN EN50 20 '
|
||||
call pack77(msg0,i3,n3,c77)
|
||||
|
||||
rate=real(Keff)/real(N)
|
||||
|
||||
write(*,*) "code rate: ",rate
|
||||
write(*,*) "niter : ",max_iterations
|
||||
write(*,*) "maxosd : ",maxosd
|
||||
write(*,*) "norder : ",norder
|
||||
write(*,*) "s : ",s
|
||||
write(*,*) "K : ",Keff
|
||||
if(modtype.eq.0) write(*,*) "modtype : coherent BPSK"
|
||||
if(modtype.eq.1) write(*,*) "modtype : noncoherent 4FSK"
|
||||
if(channeltype.eq.0) write(*,*) "channel : AWGN"
|
||||
if(channeltype.eq.1) write(*,*) "channel : Rayleigh"
|
||||
|
||||
msgbits=0
|
||||
read(c77,'(50i1)') msgbits(1:50)
|
||||
@ -59,49 +82,170 @@ program ldpcsim240_74
|
||||
call get_crc24(msgbits,74,ncrc24)
|
||||
write(c24,'(b24.24)') ncrc24
|
||||
read(c24,'(24i1)') msgbits(51:74)
|
||||
write(*,'(24i1)') msgbits(51:74)
|
||||
write(*,'(24i1)') msgbits(51:74)
|
||||
write(*,*) 'message with crc24'
|
||||
write(*,'(74i1)') msgbits(1:74)
|
||||
call encode240_74(msgbits,codeword)
|
||||
call init_random_seed()
|
||||
call sgran()
|
||||
|
||||
call encode240_74(msgbits(1:74),codeword)
|
||||
do i=1,120
|
||||
is=codeword(2*i)+2*codeword(2*i-1)
|
||||
itone(i)=graymap(is)
|
||||
enddo
|
||||
|
||||
write(*,*) 'codeword'
|
||||
write(*,'(77i1,1x,24i1,1x,73i1)') codeword
|
||||
|
||||
write(*,*) "Eb/N0 Es/N0 ngood nundetected sigma symbol error rate"
|
||||
do idb = 8,-3,-1
|
||||
! call init_random_seed()
|
||||
! call sgran()
|
||||
|
||||
one=.false.
|
||||
do i=0,65535
|
||||
do j=0,15
|
||||
if(iand(i,2**j).ne.0) one(i,j)=.true.
|
||||
enddo
|
||||
enddo
|
||||
|
||||
write(*,*) "Eb/N0 Es/N0 ngood nundetected symbol error rate"
|
||||
do idb = 24,-8,-1
|
||||
db=idb/2.0-1.0
|
||||
sigma=1/sqrt( 2*rate*(10**(db/10.0)) ) ! to make db represent Eb/No
|
||||
sigma=1/sqrt( 2*rate*iq*(10**(db/10.0)) ) ! to make db represent Eb/No
|
||||
! sigma=1/sqrt( 2*(10**(db/10.0)) ) ! db represents Es/No
|
||||
ngood=0
|
||||
nue=0
|
||||
nberr=0
|
||||
nsymerr=0
|
||||
|
||||
do itrial=1, ntrials
|
||||
! Create a realization of a noisy received word
|
||||
do i=1,N
|
||||
rxdata(i) = 2.0*codeword(i)-1.0 + sigma*gran()
|
||||
enddo
|
||||
nerr=0
|
||||
do i=1,N
|
||||
if( rxdata(i)*(2*codeword(i)-1.0) .lt. 0 ) nerr=nerr+1
|
||||
enddo
|
||||
nberr=nberr+nerr
|
||||
if(modtype.eq.0) then
|
||||
iq = 1 ! bits per symbol
|
||||
sigma=1/sqrt( 2*rate*iq*(10**(db/10.0)) ) ! to make db represent Eb/No
|
||||
do i=1,N
|
||||
rxdata(i) = 2.0*codeword(i)-1.0 + sigma*gran()
|
||||
enddo
|
||||
nerr=0
|
||||
do i=1,N
|
||||
if( rxdata(i)*(2*codeword(i)-1.0) .lt. 0 ) nerr=nerr+1
|
||||
enddo
|
||||
nberr=nberr+nerr
|
||||
|
||||
rxav=sum(rxdata)/N
|
||||
rx2av=sum(rxdata*rxdata)/N
|
||||
rxsig=sqrt(rx2av-rxav*rxav)
|
||||
rxdata=rxdata/rxsig
|
||||
if( s .lt. 0 ) then
|
||||
ss=sigma
|
||||
rxav=sum(rxdata)/N
|
||||
rx2av=sum(rxdata*rxdata)/N
|
||||
rxsig=sqrt(rx2av-rxav*rxav)
|
||||
rxdata=rxdata/rxsig
|
||||
if( s .lt. 0 ) then
|
||||
ss=sigma
|
||||
else
|
||||
ss=s
|
||||
endif
|
||||
|
||||
llr=2.0*rxdata/(ss*ss)
|
||||
else
|
||||
ss=s
|
||||
! noncoherent MFSK
|
||||
iq = 2 ! bits per symbol
|
||||
sigma=1/sqrt( 2*rate*iq*(10**(db/10.0)) ) ! to make db represent Eb/No
|
||||
A=1
|
||||
do i=1,120
|
||||
do j=0,3
|
||||
if(j.eq.itone(i)) then
|
||||
if(channeltype.eq.0) then
|
||||
A=1.0
|
||||
elseif(channeltype.eq.1) then
|
||||
xI=gran()**2+gran()**2
|
||||
A=sqrt(xI/2)
|
||||
endif
|
||||
cs(j,i)= A + sigma*gran() + cmplx(0,1)*sigma*gran()
|
||||
elseif(j.ne.itone(i)) then
|
||||
cs(j,i)= sigma*gran() + cmplx(0,1)*sigma*gran()
|
||||
endif
|
||||
enddo
|
||||
lmax=maxloc(abs(cs(:,i)))
|
||||
if(lmax(1)-1.ne.itone(i) ) nsymerr=nsymerr+1
|
||||
enddo
|
||||
|
||||
do k=1,NN,8
|
||||
|
||||
do m=1,8 ! do 4 1-symbol correlations for each of 8 symbs
|
||||
s2=0
|
||||
do is=1,4
|
||||
c1(is,m)=cs(graymap(is-1),k+m-1)
|
||||
s2(is-1)=abs(c1(is,m))
|
||||
enddo
|
||||
ipt=(k-1)*2+2*(m-1)+1
|
||||
do ib=0,1
|
||||
bm=maxval(s2(0:3),one(0:3,1-ib)) - &
|
||||
maxval(s2(0:3),.not.one(0:3,1-ib))
|
||||
if(ipt+ib.gt.2*NN) cycle
|
||||
bitmetrics(ipt+ib,1)=bm
|
||||
enddo
|
||||
enddo
|
||||
|
||||
do m=1,4 ! do 16 2-symbol correlations for each of 4 2-symbol groups
|
||||
s2=0
|
||||
do i=1,4
|
||||
do j=1,4
|
||||
is=(i-1)*4+j
|
||||
c2(is,m)=c1(i,2*m-1)+c1(j,2*m)
|
||||
s2(is-1)=abs(c2(is,m))**2
|
||||
enddo
|
||||
enddo
|
||||
ipt=(k-1)*2+4*(m-1)+1
|
||||
do ib=0,3
|
||||
bm=maxval(s2(0:15),one(0:15,3-ib)) - &
|
||||
maxval(s2(0:15),.not.one(0:15,3-ib))
|
||||
if(ipt+ib.gt.2*NN) cycle
|
||||
bitmetrics(ipt+ib,2)=bm
|
||||
enddo
|
||||
enddo
|
||||
|
||||
do m=1,2 ! do 256 4-symbol corrs for each of 2 4-symbol groups
|
||||
s2=0
|
||||
do i=1,16
|
||||
do j=1,16
|
||||
is=(i-1)*16+j
|
||||
c4(is,m)=c2(i,2*m-1)+c2(j,2*m)
|
||||
s2(is-1)=abs(c4(is,m))
|
||||
enddo
|
||||
enddo
|
||||
ipt=(k-1)*2+8*(m-1)+1
|
||||
do ib=0,7
|
||||
bm=maxval(s2(0:255),one(0:255,7-ib)) - &
|
||||
maxval(s2(0:255),.not.one(0:255,7-ib))
|
||||
if(ipt+ib.gt.2*NN) cycle
|
||||
bitmetrics(ipt+ib,3)=bm
|
||||
enddo
|
||||
enddo
|
||||
|
||||
s2=0 ! do 65536 8-symbol correlations for the entire group
|
||||
do i=1,256
|
||||
do j=1,256
|
||||
is=(i-1)*256+j
|
||||
s2(is-1)=abs(c4(i,1)+c4(j,2))
|
||||
enddo
|
||||
enddo
|
||||
ipt=(k-1)*2+1
|
||||
do ib=0,15
|
||||
bm=maxval(s2(0:65535),one(0:65535,15-ib)) - &
|
||||
maxval(s2(0:65535),.not.one(0:65535,15-ib))
|
||||
if(ipt+ib.gt.2*NN) cycle
|
||||
bitmetrics(ipt+ib,4)=bm
|
||||
enddo
|
||||
|
||||
enddo
|
||||
|
||||
call normalizebmet(bitmetrics(:,1),2*NN)
|
||||
call normalizebmet(bitmetrics(:,2),2*NN)
|
||||
call normalizebmet(bitmetrics(:,3),2*NN)
|
||||
call normalizebmet(bitmetrics(:,4),2*NN)
|
||||
|
||||
scalefac=2.83
|
||||
bitmetrics=scalefac*bitmetrics
|
||||
|
||||
llr=bitmetrics(:,1)
|
||||
endif
|
||||
|
||||
llr=2.0*rxdata/(ss*ss)
|
||||
apmask=0
|
||||
dmin=0.0
|
||||
maxosd=2
|
||||
call decode240_74(llr, Keff, maxosd, norder, apmask, message74, cw, ntype, nharderror, dmin)
|
||||
if(nharderror.ge.0) then
|
||||
n2err=0
|
||||
@ -116,9 +260,10 @@ write(*,'(24i1)') msgbits(51:74)
|
||||
endif
|
||||
enddo
|
||||
! snr2500=db+10*log10(200.0/116.0/2500.0)
|
||||
esn0=db+10*log10(rate)
|
||||
pberr=real(nberr)/(real(ntrials*N))
|
||||
write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,8x,e10.3)") db,esn0,ngood,nue,pberr
|
||||
esn0=db+10*log10(rate*iq)
|
||||
pberr=real(nberr)/real(ntrials*N)
|
||||
pserr=real(nsymerr)/real(ntrials*120)
|
||||
write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,8x,e10.3)") db,esn0,ngood,nue,pserr
|
||||
|
||||
enddo
|
||||
|
||||
|
@ -8,7 +8,7 @@ module fst4_decode
|
||||
|
||||
abstract interface
|
||||
subroutine fst4_decode_callback (this,nutc,sync,nsnr,dt,freq, &
|
||||
decoded,nap,qual,ntrperiod,lwspr,fmid,w50)
|
||||
decoded,nap,qual,ntrperiod,fmid,w50)
|
||||
import fst4_decoder
|
||||
implicit none
|
||||
class(fst4_decoder), intent(inout) :: this
|
||||
@ -21,7 +21,6 @@ module fst4_decode
|
||||
integer, intent(in) :: nap
|
||||
real, intent(in) :: qual
|
||||
integer, intent(in) :: ntrperiod
|
||||
logical, intent(in) :: lwspr
|
||||
real, intent(in) :: fmid
|
||||
real, intent(in) :: w50
|
||||
end subroutine fst4_decode_callback
|
||||
@ -31,7 +30,7 @@ contains
|
||||
|
||||
subroutine decode(this,callback,iwave,nutc,nQSOProgress,nfa,nfb,nfqso, &
|
||||
ndepth,ntrperiod,nexp_decode,ntol,emedelay,lagain,lapcqonly,mycall, &
|
||||
hiscall,iwspr)
|
||||
hiscall,iwspr,lprinthash22)
|
||||
|
||||
use prog_args
|
||||
use timer_module, only: timer
|
||||
@ -67,9 +66,10 @@ contains
|
||||
integer mcq(29),mrrr(19),m73(19),mrr73(19)
|
||||
|
||||
logical badsync,unpk77_success,single_decode
|
||||
logical first,nohiscall,lwspr
|
||||
logical first,nohiscall
|
||||
logical new_callsign,plotspec_exists,wcalls_exists,do_k50_decode
|
||||
logical decdata_exists
|
||||
logical lprinthash22
|
||||
|
||||
integer*2 iwave(30*60*12000)
|
||||
|
||||
@ -88,7 +88,8 @@ contains
|
||||
dxcall13=hiscall ! initialize for use in packjt77
|
||||
mycall13=mycall
|
||||
|
||||
if(iwspr.ne.0.and.iwspr.ne.1) return
|
||||
if(iwspr.ne.0 .and. iwspr.ne.1) return
|
||||
|
||||
if(lagain) continue ! use lagain to keep compiler happy
|
||||
|
||||
if(first) then
|
||||
@ -503,6 +504,13 @@ contains
|
||||
write(c77,'(50i1)') message74(1:50)
|
||||
c77(51:77)='000000000000000000000110000'
|
||||
call unpack77(c77,1,msg,unpk77_success)
|
||||
if(lprinthash22 .and. unpk77_success .and. index(msg,'<...>').gt.0) then
|
||||
read(c77,'(b22.22)') n22tmp
|
||||
i1=index(msg,' ')
|
||||
wpart=trim(msg(i1+1:))
|
||||
write(msg,'(a1,i7.7,a1)') '<',n22tmp,'>'
|
||||
msg=trim(msg)//' '//trim(wpart)
|
||||
endif
|
||||
if(unpk77_success .and. do_k50_decode) then
|
||||
! If decode was obtained with Keff=66, save call/grid in fst4w_calls.txt if not there already.
|
||||
i1=index(msg,' ')
|
||||
@ -602,6 +610,7 @@ contains
|
||||
case(1800)
|
||||
snr_calfac=320.0
|
||||
case default
|
||||
snr_calfac=430.0
|
||||
end select
|
||||
arg=snr_calfac*xsig/base - 1.0
|
||||
if(arg.gt.0.0) then
|
||||
@ -626,8 +635,7 @@ contains
|
||||
close(21)
|
||||
endif
|
||||
call this%callback(nutc,smax1,nsnr,xdt,fsig,msg, &
|
||||
iaptype,qual,ntrperiod,lwspr,fmid,w50)
|
||||
! if(iwspr.eq.0 .and. nb.lt.0) go to 900
|
||||
iaptype,qual,ntrperiod,fmid,w50)
|
||||
goto 800
|
||||
endif
|
||||
enddo ! metrics
|
||||
@ -988,7 +996,7 @@ contains
|
||||
do i=-ia,ia !Find freq range that has 50% of signal power
|
||||
sum2=sum2 + ss(i)-avg
|
||||
if(sum2.ge.0.25*sum1 .and. xi1.eq.-999.0) then
|
||||
xi1=i - 1 + (sum2-0.25*sum1)/(sum2-sum2z)
|
||||
xi1=i - 1 + (0.25*sum1-sum2)/(sum2-sum2z)
|
||||
endif
|
||||
if(sum2.ge.0.50*sum1 .and. xi2.eq.-999.0) then
|
||||
xi2=i - 1 + (sum2-0.50*sum1)/(sum2-sum2z)
|
||||
|
@ -15,7 +15,7 @@ subroutine foxgen()
|
||||
! common block.
|
||||
|
||||
parameter (NN=79,ND=58,NSPS=4*1920)
|
||||
parameter (NWAVE=(160+2)*134400*4) !the biggest waveform we generate (FST4-1800 at 48kHz)
|
||||
parameter (NWAVE=(160+2)*134400*4) ! the biggest waveform we generate (FST4-1800 at 48kHz)
|
||||
parameter (NFFT=614400,NH=NFFT/2)
|
||||
character*40 cmsg
|
||||
character*37 msg,msgsent
|
||||
|
@ -2,38 +2,50 @@ program ldpcsim174_91
|
||||
! End to end test of the (174,91)/crc14 encoder and decoder.
|
||||
use packjt77
|
||||
|
||||
integer, parameter:: N=174, K=91, M=N-K
|
||||
character*37 msg,msgsent,msgreceived
|
||||
integer, parameter:: N=174, K=91, M=N-K, NN=58
|
||||
character*37 msg,msgsent
|
||||
character*77 c77
|
||||
character*8 arg
|
||||
character*6 grid
|
||||
character*96 tmpchar
|
||||
integer*1, allocatable :: codeword(:), decoded(:), message(:)
|
||||
integer*1 msgbits(77)
|
||||
integer*1 message77(77),message91(91)
|
||||
integer*1 message91(91)
|
||||
integer*1 apmask(N), cw(N)
|
||||
integer lmax(1)
|
||||
integer modtype, itone(79), itonecw(58), graymap(0:7)
|
||||
integer nerrtot(0:N),nerrdec(0:N)
|
||||
integer channeltype
|
||||
logical unpk77_success
|
||||
logical one(0:511,0:8)
|
||||
real*8, allocatable :: rxdata(:)
|
||||
real, allocatable :: llr(:)
|
||||
real llr(174),llra(174),llrb(174),llrc(174),llrd(174)
|
||||
real bmeta(174),bmetb(174),bmetc(174),bmetd(174)
|
||||
complex cs(0:7,NN)
|
||||
real s2(0:511)
|
||||
data graymap/0,1,3,2,5,6,4,7/
|
||||
|
||||
nerrtot=0
|
||||
nerrdec=0
|
||||
|
||||
!
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.ne.6) then
|
||||
print*,'Usage: ldpcsim niter ndepth #trials s Keff nbposd'
|
||||
print*,'eg: ldpcsim 10 2 1000 0.84 91 1'
|
||||
print*,'niter: max BP iterations'
|
||||
print*,'ndepth: OSD order'
|
||||
print*,'s: noise sigma; if negative value is ignored and sigma is calculated from SNR.'
|
||||
print*,'nbposd=0, no coupling. nbposd>0, maxsuper=nbposd; nbposd<0, no OSD'
|
||||
if(nargs.ne.7) then
|
||||
print*,'Usage: ldpcsim maxosd norder #trials s Keff modtype channel'
|
||||
print*,'eg: ldpcsim 10 2 1000 0.84 91 1 0'
|
||||
print*,' maxosd<0: do bp only'
|
||||
print*,' maxosd=0: do bp and then call osd once with channel llrs'
|
||||
print*,' maxosd>1: do bp and then call osd maxosd times with saved bp outputs'
|
||||
print*,' norder : osd decoding depth'
|
||||
print*,' s : BPSK only, noise sigma, if s<0 value is ignored and sigma is calculated from SNR.'
|
||||
print*,' Keff : Keff must be in the range [77,91]; Keff-77 is the # of bits to use as CRC.'
|
||||
print*,' modtype : 0, coherent BPSK; 1 noncoherent 8FSK'
|
||||
print*,' channel : 0, AWGN; 1, block Rayleigh (Rayleigh only works with 8FSK!)'
|
||||
return
|
||||
endif
|
||||
call getarg(1,arg)
|
||||
read(arg,*) max_iterations
|
||||
read(arg,*) maxosd
|
||||
call getarg(2,arg)
|
||||
read(arg,*) ndepth
|
||||
read(arg,*) norder
|
||||
call getarg(3,arg)
|
||||
read(arg,*) ntrials
|
||||
call getarg(4,arg)
|
||||
@ -41,16 +53,24 @@ program ldpcsim174_91
|
||||
call getarg(5,arg)
|
||||
read(arg,*) Keff
|
||||
call getarg(6,arg)
|
||||
read(arg,*) nbposd
|
||||
read(arg,*) modtype
|
||||
call getarg(7,arg)
|
||||
read(arg,*) channeltype
|
||||
|
||||
! scale Eb/No for a (174,91) code
|
||||
rate=real(K)/real(N)
|
||||
|
||||
write(*,*) "rate: ",rate
|
||||
write(*,*) "niter= ",max_iterations," s= ",s
|
||||
|
||||
allocate ( codeword(N), decoded(K), message(K) )
|
||||
allocate ( rxdata(N), llr(N) )
|
||||
allocate ( rxdata(N) )
|
||||
|
||||
one=.false.
|
||||
do i=0,511
|
||||
do j=0,8
|
||||
if(iand(i,2**j).ne.0) one(i,j)=.true.
|
||||
enddo
|
||||
enddo
|
||||
|
||||
msg="K9ABC K1ABC FN20"
|
||||
i3=0
|
||||
@ -65,47 +85,144 @@ program ldpcsim174_91
|
||||
|
||||
call init_random_seed()
|
||||
|
||||
iq=1
|
||||
if(modtype.gt.0) then ! MFSK - get tones
|
||||
i3=-1
|
||||
n3=-1
|
||||
call genft8(msg,i3,n3,msgsent,msgbits,itone)
|
||||
write(*,*) 'message tones'
|
||||
write(*,'(79(i1,1x))') itone
|
||||
itonecw(1:29)=itone(8:36)
|
||||
itonecw(30:58)=itone(44:72)
|
||||
iq=3 ! bits per symbol
|
||||
endif
|
||||
call encode174_91(msgbits,codeword)
|
||||
write(*,*) 'crc14'
|
||||
write(*,'(14i1)') codeword(78:91)
|
||||
write(*,*) 'codeword'
|
||||
write(*,'(22(8i1,1x))') codeword
|
||||
|
||||
write(*,*) "Eb/N0 Es/N0 ngood nundetected sigma psymerr"
|
||||
do idb = 10,-4,-1
|
||||
write(*,*) 'Eb/N0 Es/N0 SNR2500 ngood nundetected sigma psymerr pbiterr'
|
||||
do idb = 20,-4,-1
|
||||
nsymerr=0
|
||||
nbiterr=0
|
||||
db=idb/2.0-1.0
|
||||
sigma=1/sqrt( 2*rate*(10**(db/10.0)) )
|
||||
sigma=1/sqrt( 2*rate*iq*(10**(db/10.0)) )
|
||||
ngood=0
|
||||
nue=0
|
||||
nsumerr=0
|
||||
|
||||
do itrial=1, ntrials
|
||||
! Create a realization of a noisy received word
|
||||
do i=1,N
|
||||
rxdata(i) = 2.0*codeword(i)-1.0 + sigma*gran()
|
||||
enddo
|
||||
nerr=0
|
||||
do i=1,N
|
||||
if( rxdata(i)*(2*codeword(i)-1.0) .lt. 0 ) nerr=nerr+1
|
||||
enddo
|
||||
if(nerr.ge.1) nerrtot(nerr)=nerrtot(nerr)+1
|
||||
if(modtype.eq.0) then
|
||||
do i=1,N
|
||||
rxdata(i) = 2.0*codeword(i)-1.0 + sigma*gran()
|
||||
enddo
|
||||
nerr=0
|
||||
do i=1,N
|
||||
if( rxdata(i)*(2*codeword(i)-1.0) .lt. 0 ) nerr=nerr+1
|
||||
enddo
|
||||
if(nerr.ge.1) nerrtot(nerr)=nerrtot(nerr)+1
|
||||
|
||||
rxav=sum(rxdata)/N
|
||||
rx2av=sum(rxdata*rxdata)/N
|
||||
rxsig=sqrt(rx2av-rxav*rxav)
|
||||
rxdata=rxdata/rxsig
|
||||
if( s .lt. 0 ) then
|
||||
ss=sigma
|
||||
rxav=sum(rxdata)/N
|
||||
rx2av=sum(rxdata*rxdata)/N
|
||||
rxsig=sqrt(rx2av-rxav*rxav)
|
||||
rxdata=rxdata/rxsig
|
||||
if( s .lt. 0 ) then
|
||||
ss=sigma
|
||||
else
|
||||
ss=s
|
||||
endif
|
||||
llr=2.0*rxdata/(ss*ss)
|
||||
else
|
||||
ss=s
|
||||
! noncoherent MFSK
|
||||
do i=1,58
|
||||
do j=0,7
|
||||
if(j.eq.itonecw(i)) then
|
||||
if(channeltype.eq.0) then
|
||||
A=1.0
|
||||
elseif(channeltype.eq.1) then
|
||||
xI=gran()**2 + gran()**2
|
||||
A=sqrt(xI/2)
|
||||
endif
|
||||
cs(j,i)= A + sigma*gran() + cmplx(0,1)*sigma*gran()
|
||||
elseif(j.ne.itonecw(i)) then
|
||||
cs(j,i)= sigma*gran() + cmplx(0,1)*sigma*gran()
|
||||
endif
|
||||
enddo
|
||||
lmax=maxloc(abs(cs(:,i)))
|
||||
if(lmax(1)-1.ne.itonecw(i) ) nsymerr=nsymerr+1
|
||||
enddo
|
||||
do nsym=1,3
|
||||
nt=2**(3*nsym)
|
||||
do ks=1,58,nsym
|
||||
amax=-1.0
|
||||
do i=0,nt-1
|
||||
i1=i/64
|
||||
i2=iand(i,63)/8
|
||||
i3=iand(i,7)
|
||||
if(nsym.eq.1) then
|
||||
s2(i)=abs(cs(graymap(i3),ks))
|
||||
elseif(nsym.eq.2) then
|
||||
s2(i)=abs(cs(graymap(i2),ks)+cs(graymap(i3),ks+1))
|
||||
elseif(nsym.eq.3) then
|
||||
if(ks.ne.58) then
|
||||
s2(i)=abs(cs(graymap(i1),ks)+cs(graymap(i2),ks+1)+cs(graymap(i3),ks+2))
|
||||
else
|
||||
s2(i)=abs(cs(graymap(i1),ks))
|
||||
endif
|
||||
else
|
||||
print*,"Error - nsym must be 1, 2, or 3."
|
||||
endif
|
||||
enddo
|
||||
|
||||
i32=1+(ks-1)*3
|
||||
if(nsym.eq.1) ibmax=2
|
||||
if(nsym.eq.2) ibmax=5
|
||||
if(nsym.eq.3) ibmax=8
|
||||
do ib=0,ibmax
|
||||
bm=maxval(s2(0:nt-1),one(0:nt-1,ibmax-ib)) - &
|
||||
maxval(s2(0:nt-1),.not.one(0:nt-1,ibmax-ib))
|
||||
if(i32+ib .gt.174) cycle
|
||||
if(nsym.eq.1) then
|
||||
bmeta(i32+ib)=bm
|
||||
den=max(maxval(s2(0:nt-1),one(0:nt-1,ibmax-ib)), &
|
||||
maxval(s2(0:nt-1),.not.one(0:nt-1,ibmax-ib)))
|
||||
if(den.gt.0.0) then
|
||||
cm=bm/den
|
||||
else ! erase it
|
||||
cm=0.0
|
||||
endif
|
||||
bmetd(i32+ib)=cm
|
||||
elseif(nsym.eq.2) then
|
||||
bmetb(i32+ib)=bm
|
||||
elseif(nsym.eq.3) then
|
||||
bmetc(i32+ib)=bm
|
||||
endif
|
||||
enddo
|
||||
enddo
|
||||
enddo
|
||||
call normalizebmet(bmeta,174)
|
||||
call normalizebmet(bmetb,174)
|
||||
call normalizebmet(bmetc,174)
|
||||
call normalizebmet(bmetd,174)
|
||||
|
||||
scalefac=2.83
|
||||
llra=scalefac*bmeta
|
||||
llrb=scalefac*bmetb
|
||||
llrc=scalefac*bmetc
|
||||
llrd=scalefac*bmetd
|
||||
|
||||
llr=llrc
|
||||
endif
|
||||
|
||||
llr=2.0*rxdata/(ss*ss)
|
||||
do i=1, 174
|
||||
if(llr(i)*(codeword(i)-0.5).lt.0) nbiterr=nbiterr+1
|
||||
enddo
|
||||
|
||||
nap=0 ! number of AP bits
|
||||
llr(1:nap)=5*(2.0*msgbits(1:nap)-1.0)
|
||||
apmask=0
|
||||
apmask(1:nap)=1
|
||||
call decode174_91(llr,Keff,nbposd,ndepth,apmask,message91,cw,ntype,nharderrors,dmin)
|
||||
call decode174_91(llr,Keff,maxosd,norder,apmask,message91,cw,ntype,nharderrors,dmin)
|
||||
! If the decoder finds a valid codeword, nharderrors will be .ge. 0.
|
||||
if( nharderrors.ge.0 ) then
|
||||
nhw=count(cw.ne.codeword)
|
||||
@ -119,9 +236,12 @@ program ldpcsim174_91
|
||||
nsumerr=nsumerr+nerr
|
||||
enddo
|
||||
|
||||
esn0=db+10.0*log10(rate)
|
||||
pberr=real(nsumerr)/(real(ntrials*N))
|
||||
write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,8x,f5.2,8x,e10.3)") db,esn0,ngood,nue,ss,pberr
|
||||
esn0=db+10.0*log10(iq*rate) ! iq=3 bits per symbol for 8FSK
|
||||
snr2500=esn0-10.0*log10(2500/6.25)
|
||||
! pberr=real(nsumerr)/(real(ntrials*N))
|
||||
psymerr=real(nsymerr)/(ntrials*174.0/iq)
|
||||
pbiterr=real(nbiterr)/(ntrials*174.0)
|
||||
write(*,"(f4.1,4x,f5.1,4x,f5.1,1x,i8,1x,i8,8x,f5.2,8x,e10.3,8x,e10.3)") db,esn0,snr2500,ngood,nue,ss,psymerr,pbiterr
|
||||
|
||||
enddo
|
||||
|
||||
@ -132,3 +252,18 @@ program ldpcsim174_91
|
||||
close(23)
|
||||
|
||||
end program ldpcsim174_91
|
||||
|
||||
subroutine normalizebmet(bmet,n)
|
||||
real bmet(n)
|
||||
|
||||
bmetav=sum(bmet)/real(n)
|
||||
bmet2av=sum(bmet*bmet)/real(n)
|
||||
var=bmet2av-bmetav*bmetav
|
||||
if( var .gt. 0.0 ) then
|
||||
bmetsig=sqrt(var)
|
||||
else
|
||||
bmetsig=sqrt(bmet2av)
|
||||
endif
|
||||
bmet=bmet/bmetsig
|
||||
return
|
||||
end subroutine normalizebmet
|
||||
|
@ -1,5 +1,4 @@
|
||||
subroutine sync8(dd,nfa,nfb,syncmin,nfqso,maxcand,nzhsym,candidate, &
|
||||
ncand,sbase)
|
||||
subroutine sync8(dd,nfa,nfb,syncmin,nfqso,maxcand,candidate,ncand,sbase)
|
||||
|
||||
include 'ft8_params.f90'
|
||||
parameter (MAXPRECAND=1000)
|
||||
|
@ -46,7 +46,6 @@ contains
|
||||
procedure(ft8_decode_callback) :: callback
|
||||
parameter (MAXCAND=600,MAX_EARLY=100)
|
||||
real*8 tsec,tseq
|
||||
real s(NH1,NHSYM)
|
||||
real sbase(NH1)
|
||||
real candidate(3,MAXCAND)
|
||||
real dd(15*12000),dd1(15*12000)
|
||||
@ -61,14 +60,14 @@ contains
|
||||
character datetime*13,msg37*37
|
||||
character*37 allmessages(200)
|
||||
character*12 ctime
|
||||
integer allsnrs(100)
|
||||
integer allsnrs(200)
|
||||
integer itone(NN)
|
||||
integer itone_save(NN,MAX_EARLY)
|
||||
real f1_save(MAX_EARLY)
|
||||
real xdt_save(MAX_EARLY)
|
||||
data nutc0/-1/
|
||||
|
||||
save s,dd,dd1,nutc0,ndec_early,itone_save,f1_save,xdt_save,lsubtracted,&
|
||||
save dd,dd1,nutc0,ndec_early,itone_save,f1_save,xdt_save,lsubtracted, &
|
||||
allmessages
|
||||
|
||||
this%callback => callback
|
||||
@ -193,8 +192,7 @@ contains
|
||||
endif
|
||||
call timer('sync8 ',0)
|
||||
maxc=MAXCAND
|
||||
call sync8(dd,ifa,ifb,syncmin,nfqso,maxc,nzhsym,candidate, &
|
||||
ncand,sbase)
|
||||
call sync8(dd,ifa,ifb,syncmin,nfqso,maxc,candidate,ncand,sbase)
|
||||
call timer('sync8 ',1)
|
||||
do icand=1,ncand
|
||||
sync=candidate(3,icand)
|
||||
|
132
lib/get_q3list.f90
Normal file
132
lib/get_q3list.f90
Normal file
@ -0,0 +1,132 @@
|
||||
subroutine get_q3list(fname,bDiskData,nlist,list)
|
||||
|
||||
type q3list
|
||||
character*6 call
|
||||
character*4 grid
|
||||
integer nsec
|
||||
integer nfreq
|
||||
integer moonel
|
||||
end type q3list
|
||||
|
||||
parameter (MAX_CALLERS=40)
|
||||
character*(*) fname
|
||||
character*36 list(40)
|
||||
character*8 grid6
|
||||
logical*1 bDiskData
|
||||
integer time
|
||||
integer nt(8)
|
||||
integer indx(MAX_CALLERS)
|
||||
type(q3list) ctmp(MAX_CALLERS),callers(MAX_CALLERS)
|
||||
character*256 jpleph_file_name,file24name
|
||||
common/jplcom/jpleph_file_name
|
||||
common/lu24com/file24name
|
||||
|
||||
nhist2=0
|
||||
open(24,file=fname,status='unknown',form='unformatted')
|
||||
read(24,end=1) nhist2
|
||||
if(nhist2.ge.1 .and. nhist2.le.40) then
|
||||
read(24,end=1) ctmp(1:nhist2)
|
||||
else
|
||||
nhist2=0
|
||||
endif
|
||||
1 rewind 24
|
||||
if(nhist2.eq.0) go to 900
|
||||
|
||||
now=time()
|
||||
call date_and_time(values=nt)
|
||||
uth=nt(5) + (nt(6)-nt(4))/60.0 + nt(7)/3600.0
|
||||
j=0
|
||||
|
||||
do i=1,nhist2
|
||||
age=(now - ctmp(i)%nsec)/3600.0
|
||||
if(age.gt.24.0) cycle
|
||||
grid6=ctmp(i)%grid//'mm'
|
||||
call grid2deg(grid6,xlon,xlat)
|
||||
call sun(nt(1),nt(2),nt(3),uth,-xlon,xlat,RASun,DecSun,xLST, &
|
||||
AzSun,ElSun,mjd,day)
|
||||
call moondopjpl(nt(1),nt(2),nt(3),uth,-xlon,xlat,RAMoon,DecMoon, &
|
||||
xLST,HA,AzMoon,ElMoon,vr,techo)
|
||||
if(ElMoon.lt.-5.0 .and. (.not.bDiskData)) cycle
|
||||
j=j+1 !Keep this one...
|
||||
callers(j)=ctmp(i)
|
||||
callers(j)%moonel=nint(ElMoon) !... and save its current moonel
|
||||
enddo
|
||||
|
||||
nhist2=j
|
||||
write(24) nhist2
|
||||
write(24) callers(1:nhist2)
|
||||
|
||||
call indexx(callers(1:nhist2)%nfreq,nhist2,indx)
|
||||
do i=1,nhist2
|
||||
j=indx(i)
|
||||
moon_el=nint(ElMoon)
|
||||
age=(now - callers(j)%nsec)/3600.0
|
||||
write(list(i),1000) i,callers(j)%nfreq,callers(j)%call, &
|
||||
callers(j)%grid,callers(j)%moonel,age,char(0)
|
||||
1000 format(i2,'.',i6,2x,a6,2x,a4,i5,f7.1,a1)
|
||||
|
||||
! h1=mod(now,86400)/3600.0
|
||||
! h2=mod(callers(i)%nsec,86400)/3600.0
|
||||
! hd=h1-h2
|
||||
! if(hd.lt.0.0) hd=hd+24.0
|
||||
! write(*,3301) i,callers(i)%call,now,callers(i)%nsec,h1,h2,hd
|
||||
!3301 format(i3,2x,a6,2i12,3f10.6)
|
||||
|
||||
enddo
|
||||
|
||||
900 close(24)
|
||||
nlist=nhist2
|
||||
file24name=fname
|
||||
|
||||
return
|
||||
end subroutine get_q3list
|
||||
|
||||
subroutine rm_q3list(dxcall0)
|
||||
|
||||
parameter (MAX_CALLERS=40)
|
||||
type q3list
|
||||
character*6 call
|
||||
character*4 grid
|
||||
integer nsec
|
||||
integer nfreq
|
||||
integer moonel
|
||||
end type q3list
|
||||
character*(*) dxcall0
|
||||
character*6 dxcall
|
||||
character*256 file24name
|
||||
type(q3list) callers(MAX_CALLERS)
|
||||
common/lu24com/file24name
|
||||
|
||||
dxcall=dxcall0
|
||||
open(24,file=trim(file24name),status='unknown',form='unformatted')
|
||||
read(24) nhist2
|
||||
read(24) callers(1:nhist2)
|
||||
|
||||
if(nhist2.eq.MAX_CALLERS .and. dxcall.eq.callers(nhist2)%call) then
|
||||
nhist2=MAX_CALLERS - 1
|
||||
go to 10
|
||||
endif
|
||||
|
||||
iz=nhist2
|
||||
do i=1,iz
|
||||
if(callers(i)%call .eq. dxcall) then
|
||||
nhist2=nhist2-1
|
||||
callers(i:nhist2)=callers(i+1:nhist2+1) !Remove dxcall from q3list
|
||||
exit
|
||||
endif
|
||||
enddo
|
||||
|
||||
10 rewind 24
|
||||
write(24) nhist2
|
||||
write(24) callers(1:nhist2)
|
||||
close(24)
|
||||
|
||||
return
|
||||
end subroutine rm_q3list
|
||||
|
||||
subroutine jpl_setup(fname)
|
||||
character*256 fname,jpleph_file_name
|
||||
common/jplcom/jpleph_file_name
|
||||
jpleph_file_name=fname
|
||||
return
|
||||
end subroutine jpl_setup
|
@ -1 +1 @@
|
||||
gfortran -o chkfft chkfft3.f90 four2a.f90 gran.c /jtsdk/fftw3f/libfftw3f-3.dll
|
||||
gfortran -o chkfft3 chkfft3.f90 four2a.f90 gran.c libfftw3f-3.dll
|
||||
|
28
lib/jt9.f90
28
lib/jt9.f90
@ -27,7 +27,7 @@ program jt9
|
||||
logical :: read_files = .true., tx9 = .false., display_help = .false., &
|
||||
bLowSidelobes = .false., nexp_decode_set = .false., &
|
||||
have_ntol = .false.
|
||||
type (option) :: long_options(31) = [ &
|
||||
type (option) :: long_options(33) = [ &
|
||||
option ('help', .false., 'h', 'Display this help message', ''), &
|
||||
option ('shmem',.true.,'s','Use shared memory for sample data','KEY'), &
|
||||
option ('tr-period', .true., 'p', 'Tx/Rx period, default SECONDS=60', &
|
||||
@ -60,9 +60,11 @@ program jt9
|
||||
option ('jt65', .false.,'6', 'JT65 mode', ''), &
|
||||
option ('fst4', .false., '7', 'FST4 mode', ''), &
|
||||
option ('fst4w', .false., 'W', 'FST4W mode', ''), &
|
||||
option ('fst4w', .false., 'Y', 'FST4W mode, print hash22 values', ''), &
|
||||
option ('ft8', .false., '8', 'FT8 mode', ''), &
|
||||
option ('jt9', .false., '9', 'JT9 mode', ''), &
|
||||
option ('qra64', .false., 'q', 'QRA64 mode', ''), &
|
||||
option ('msk144', .false., 'k', 'MSK144 mode', ''), &
|
||||
option ('QSOprog', .true., 'Q', 'QSO progress (0-5), default PROGRESS=1',&
|
||||
'QSOprogress'), &
|
||||
option ('sub-mode', .true., 'b', 'Sub mode, default SUBMODE=A', 'A'), &
|
||||
@ -85,13 +87,12 @@ program jt9
|
||||
common/decstats/ntry65a,ntry65b,n65a,n65b,num9,numfano
|
||||
data npatience/1/,nthreads/1/,wisfile/' '/
|
||||
|
||||
iwspr=0
|
||||
nsubmode = 0
|
||||
ntol = 20
|
||||
TRperiod=60.d0
|
||||
|
||||
do
|
||||
call getopt('hs:e:a:b:r:m:p:d:f:F:w:t:9876543WqTL:S:H:c:G:x:g:X:Q:', &
|
||||
call getopt('hs:e:a:b:r:m:p:d:f:F:w:t:9876543WYqkTL:S:H:c:G:x:g:X:Q:', &
|
||||
long_options,c,optarg,arglen,stat,offset,remain,.true.)
|
||||
if (stat .ne. 0) then
|
||||
exit
|
||||
@ -129,7 +130,9 @@ program jt9
|
||||
read (optarg(:arglen), *) fhigh
|
||||
case ('q')
|
||||
mode = 164
|
||||
case ('Q')
|
||||
case ('k')
|
||||
mode = 144
|
||||
case ('Q')
|
||||
read (optarg(:arglen), *) nQSOProg
|
||||
case ('3')
|
||||
mode = 66
|
||||
@ -141,7 +144,6 @@ program jt9
|
||||
if (mode.lt.65) mode = mode + 65
|
||||
case ('7')
|
||||
mode = 240
|
||||
iwspr=0
|
||||
case ('8')
|
||||
mode = 8
|
||||
case ('9')
|
||||
@ -152,7 +154,8 @@ program jt9
|
||||
read (optarg(:arglen), *) npatience
|
||||
case ('W')
|
||||
mode = 241
|
||||
iwspr=1
|
||||
case ('Y')
|
||||
mode = 242
|
||||
case ('c')
|
||||
read (optarg(:arglen), *) mycall
|
||||
case ('G')
|
||||
@ -212,7 +215,7 @@ program jt9
|
||||
hisgrid=' '
|
||||
endif
|
||||
|
||||
if (mode .eq. 241) then
|
||||
if (mode .eq. 241 .or. mode .eq. 242) then
|
||||
ntol = min (ntol, 100)
|
||||
else if (mode .eq. 65 + 9 .and. .not. have_ntol) then
|
||||
ntol = 20
|
||||
@ -222,7 +225,7 @@ program jt9
|
||||
ntol = min (ntol, 1000)
|
||||
end if
|
||||
if (.not. nexp_decode_set) then
|
||||
if (mode .eq. 240 .or. mode .eq. 241) then
|
||||
if (mode .eq. 240 .or. mode .eq. 241 .or. mode .eq. 242) then
|
||||
nexp_decode = 3 * 256 ! single decode off and nb=0
|
||||
end if
|
||||
end if
|
||||
@ -277,7 +280,8 @@ program jt9
|
||||
call timer('symspec ',1)
|
||||
endif
|
||||
nhsym0=nhsym
|
||||
if(nhsym.ge.181 .and. mode.ne.240 .and. mode.ne.241 .and. mode.ne.66) exit
|
||||
if(nhsym.ge.181 .and. mode.ne.240 .and. mode.ne.241 .and. &
|
||||
mode.ne.242 .and. mode.ne.66) exit
|
||||
endif
|
||||
enddo
|
||||
close(unit=wav%lun)
|
||||
@ -294,7 +298,6 @@ program jt9
|
||||
shared_data%params%kin=64800
|
||||
if(mode.eq.240) shared_data%params%kin=720000 !### 60 s periods ###
|
||||
shared_data%params%nzhsym=nhsym
|
||||
if(mode.eq.240 .and. iwspr.eq.1) ndepth=ior(ndepth,128)
|
||||
shared_data%params%ndepth=ndepth
|
||||
shared_data%params%lft8apon=.true.
|
||||
shared_data%params%ljt65apon=.true.
|
||||
@ -352,7 +355,12 @@ program jt9
|
||||
call multimode_decoder(shared_data%ss,id2a, &
|
||||
shared_data%params,nfsample)
|
||||
cycle
|
||||
|
||||
! MSK144
|
||||
else if (mode .eq. 144) then
|
||||
call decode_msk144(shared_data%id2, shared_data%params, data_dir)
|
||||
endif
|
||||
|
||||
! Normal decoding pass
|
||||
call multimode_decoder(shared_data%ss,shared_data%id2, &
|
||||
shared_data%params,nfsample)
|
||||
|
11
lib/jt9a.f90
11
lib/jt9a.f90
@ -70,8 +70,15 @@ subroutine jt9a()
|
||||
call multimode_decoder(shared_data%ss,id2a,local_params,12000)
|
||||
local_params%nzhsym=50
|
||||
endif
|
||||
! Normal decoding pass
|
||||
call multimode_decoder(shared_data%ss,shared_data%id2,local_params,12000)
|
||||
|
||||
if(local_params%nmode .eq. 144) then
|
||||
! MSK144
|
||||
call decode_msk144(shared_data%id2, shared_data%params, data_dir)
|
||||
else
|
||||
! Normal decoding pass
|
||||
call multimode_decoder(shared_data%ss,shared_data%id2,local_params,12000)
|
||||
endif
|
||||
|
||||
call timer('decoder ',1)
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
subroutine map65_mmdec(nutc,id2,nqd,nsubmode,nfa,nfb,nfqso,ntol,newdat, &
|
||||
nagain,max_drift,mycall,hiscall,hisgrid)
|
||||
subroutine map65_mmdec(nutc,id2,nqd,ntrperiod, nsubmode,nfa,nfb,nfqso, &
|
||||
ntol,newdat,nagain,max_drift,ndepth,mycall,hiscall,hisgrid)
|
||||
|
||||
use prog_args
|
||||
use timer_module, only: timer
|
||||
@ -14,8 +14,8 @@ subroutine map65_mmdec(nutc,id2,nqd,nsubmode,nfa,nfb,nfqso,ntol,newdat, &
|
||||
|
||||
logical single_decode,bVHF,lnewdat,lagain,lclearave,lapcqonly
|
||||
integer*2 id2(300*12000)
|
||||
integer nqf(20)
|
||||
! type(params_block) :: params
|
||||
character(len=20) :: datetime
|
||||
character(len=12) :: mycall, hiscall
|
||||
character(len=6) :: hisgrid
|
||||
data ntr0/-1/
|
||||
@ -28,8 +28,7 @@ subroutine map65_mmdec(nutc,id2,nqd,nsubmode,nfa,nfb,nfqso,ntol,newdat, &
|
||||
! hiscall=transfer(params%hiscall,hiscall)
|
||||
! mygrid=transfer(params%mygrid,mygrid)
|
||||
! hisgrid=transfer(params%hisgrid,hisgrid)
|
||||
datetime=' '
|
||||
|
||||
|
||||
my_q65%decoded = 0
|
||||
ncontest=0
|
||||
nQSOprogress=0
|
||||
@ -40,16 +39,12 @@ subroutine map65_mmdec(nutc,id2,nqd,nsubmode,nfa,nfb,nfqso,ntol,newdat, &
|
||||
lagain=(nagain.ne.0)
|
||||
bVHF=.true.
|
||||
emedelay=2.5
|
||||
ndepth=1
|
||||
ntrperiod=60
|
||||
|
||||
open(17,file=trim(temp_dir)//'/red.dat',status='unknown')
|
||||
open(14,file=trim(temp_dir)//'/avemsg.txt',status='unknown')
|
||||
! ntrperiod=60
|
||||
|
||||
call timer('dec_q65 ',0)
|
||||
call my_q65%decode(q65_decoded,id2,nqd,nutc,ntrperiod,nsubmode,nfqso, &
|
||||
ntol,ndepth,nfa,nfb,lclearave,single_decode,lagain,max_drift,lnewdat, &
|
||||
emedelay,mycall,hiscall,hisgrid,nQSOProgress,ncontest,lapcqonly,navg0)
|
||||
emedelay,mycall,hiscall,hisgrid,nQSOProgress,ncontest,lapcqonly,navg0,nqf)
|
||||
call timer('dec_q65 ',1)
|
||||
|
||||
return
|
||||
|
@ -3,6 +3,10 @@ subroutine pctile(x,npts,npct,xpct)
|
||||
real x(npts)
|
||||
real,allocatable :: tmp(:)
|
||||
|
||||
if(npts.lt.0 .or. npct.lt.0 .or. npct.gt.100) then
|
||||
xpct=1.0
|
||||
go to 900
|
||||
endif
|
||||
allocate(tmp(npts))
|
||||
|
||||
tmp=x
|
||||
@ -11,6 +15,7 @@ subroutine pctile(x,npts,npct,xpct)
|
||||
if(j.lt.1) j=1
|
||||
if(j.gt.npts) j=npts
|
||||
xpct=tmp(j)
|
||||
deallocate(tmp)
|
||||
|
||||
return
|
||||
900 return
|
||||
end subroutine pctile
|
||||
|
@ -33,7 +33,7 @@ contains
|
||||
subroutine decode(this,callback,iwave,nqd0,nutc,ntrperiod,nsubmode,nfqso, &
|
||||
ntol,ndepth,nfa0,nfb0,lclearave,single_decode,lagain,max_drift0, &
|
||||
lnewdat0,emedelay,mycall,hiscall,hisgrid,nQSOprogress,ncontest, &
|
||||
lapcqonly,navg0)
|
||||
lapcqonly,navg0,nqf)
|
||||
|
||||
! Top-level routine that organizes the decoding of Q65 signals
|
||||
! Input: iwave Raw data, i*2
|
||||
@ -55,9 +55,13 @@ contains
|
||||
use, intrinsic :: iso_c_binding
|
||||
use q65 !Shared variables
|
||||
use prog_args
|
||||
use types
|
||||
|
||||
parameter (NMAX=300*12000) !Max TRperiod is 300 s
|
||||
parameter (NMAX=300*12000) !Max TRperiod is 300 s
|
||||
parameter (MAX_CALLERS=40) !For multiple q3 decodes in NA VHf Contest mode
|
||||
|
||||
class(q65_decoder), intent(inout) :: this
|
||||
|
||||
procedure(q65_decode_callback) :: callback
|
||||
character(len=12) :: mycall, hiscall !Used for AP decoding
|
||||
character(len=6) :: hisgrid
|
||||
@ -70,19 +74,26 @@ contains
|
||||
character*80 fmt
|
||||
integer*2 iwave(NMAX) !Raw data
|
||||
real, allocatable :: dd(:) !Raw data
|
||||
real xdtdecodes(100)
|
||||
real f0decodes(100)
|
||||
integer dat4(13) !Decoded message as 12 6-bit integers
|
||||
integer dgen(13)
|
||||
integer nqf(20)
|
||||
integer stageno !Added by W3SZ
|
||||
integer time
|
||||
logical lclearave,lnewdat0,lapcqonly,unpk77_success
|
||||
logical single_decode,lagain
|
||||
complex, allocatable :: c00(:) !Analytic signal, 6000 Sa/s
|
||||
complex, allocatable :: c0(:) !Analytic signal, 6000 Sa/s
|
||||
integer stageno !Added by W3SZ
|
||||
stageno=0
|
||||
type(q3list) callers(MAX_CALLERS)
|
||||
|
||||
! Start by setting some parameters and allocating storage for large arrays
|
||||
call sec0(0,tdecode)
|
||||
stageno=0
|
||||
ndecodes=0
|
||||
decodes=' '
|
||||
f0decodes=0.
|
||||
xdtdecodes=0.
|
||||
nfa=nfa0
|
||||
nfb=nfb0
|
||||
nqd=nqd0
|
||||
@ -97,9 +108,30 @@ contains
|
||||
nfft1=ntrperiod*12000
|
||||
nfft2=ntrperiod*6000
|
||||
npasses=1
|
||||
nhist2=0
|
||||
if(lagain) ndepth=ior(ndepth,3) !Use 'Deep' for manual Q65 decodes
|
||||
dxcall13=hiscall ! initialize for use in packjt77
|
||||
mycall13=mycall
|
||||
if(ncontest.eq.1) then
|
||||
! NA VHF, WW-Digi, or ARRL Digi Contest
|
||||
open(24,file=trim(data_dir)//'/tsil.3q',status='unknown', &
|
||||
form='unformatted')
|
||||
read(24,end=2) nhist2
|
||||
if(nhist2.ge.1 .and. nhist2.le.40) then
|
||||
read(24,end=2) callers(1:nhist2)
|
||||
now=time()
|
||||
do i=1,nhist2
|
||||
hours=(now - callers(i)%nsec)/3600.0
|
||||
if(hours.gt.24.0) then
|
||||
callers(i:nhist2-1)=callers(i+1:nhist2)
|
||||
nhist2=nhist2-1
|
||||
endif
|
||||
enddo
|
||||
else
|
||||
nhist2=0
|
||||
endif
|
||||
2 close(24)
|
||||
endif
|
||||
|
||||
! Determine the T/R sequence: iseq=0 (even), or iseq=1 (odd)
|
||||
n=nutc
|
||||
@ -132,25 +164,37 @@ contains
|
||||
baud=12000.0/nsps
|
||||
this%callback => callback
|
||||
nFadingModel=1
|
||||
maxiters=33
|
||||
ibwa=max(1,int(1.8*log(baud*mode_q65)) + 1)
|
||||
ibwb=min(10,ibwa+2)
|
||||
if(iand(ndepth,3).ge.2) then
|
||||
ibwa=max(1,int(1.8*log(baud*mode_q65)) + 1)
|
||||
ibwb=min(10,ibwa+5)
|
||||
maxiters=67
|
||||
endif
|
||||
|
||||
! ibwa=max(1,int(1.8*log(baud*mode_q65)) + 5)
|
||||
!### This needs work!
|
||||
ibwa=1 !Q65-60A
|
||||
if(mode_q65.eq.2) ibwa=3 !Q65-60B
|
||||
if(mode_q65.eq.4) ibwa=8 !Q65-60C
|
||||
if(mode_q65.eq.8) ibwa=8 !Q65-60D
|
||||
if(mode_q65.eq.16) ibwa=8 !Q65-60E
|
||||
!###
|
||||
|
||||
! ibwb=min(15,ibwa+4)
|
||||
ibwb=min(15,ibwa+6)
|
||||
maxiters=40
|
||||
if(iand(ndepth,3).eq.2) maxiters=60
|
||||
if(iand(ndepth,3).eq.3) then
|
||||
ibwa=max(1,ibwa-1)
|
||||
ibwb=min(10,ibwb+1)
|
||||
ibwa=max(1,ibwa-2)
|
||||
ibwb=min(15,ibwb+2)
|
||||
maxiters=100
|
||||
endif
|
||||
|
||||
! Generate codewords for full-AP list decoding
|
||||
if(ichar(hiscall(1:1)).eq.0) hiscall=' '
|
||||
if(ichar(hisgrid(1:1)).eq.0) hisgrid=' '
|
||||
ncw=0
|
||||
if(nqd.eq.1 .or. lagain) then
|
||||
call q65_set_list(mycall,hiscall,hisgrid,codewords,ncw)
|
||||
if(nqd.eq.1 .or. lagain .or. ncontest.eq.1) then
|
||||
if(ncontest.eq.1) then
|
||||
call q65_set_list2(mycall,hiscall,hisgrid,callers,nhist2, &
|
||||
codewords,ncw)
|
||||
else
|
||||
call q65_set_list(mycall,hiscall,hisgrid,codewords,ncw)
|
||||
endif
|
||||
endif
|
||||
dgen=0
|
||||
call q65_enc(dgen,codewords) !Initialize the Q65 codec
|
||||
@ -166,11 +210,9 @@ contains
|
||||
call timer('q65_dec0',0)
|
||||
! Call top-level routine in q65 module: establish sync and try for a
|
||||
! q3 or q0 decode.
|
||||
call q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
call q65_dec0(iavg,iwave,ntrperiod,nfqso,ntol,lclearave, &
|
||||
emedelay,xdt,f0,snr1,width,dat4,snr2,idec,stageno)
|
||||
call timer('q65_dec0',1)
|
||||
! write(*,3001) '=a',nfqso,ntol,ndepth,xdt,f0,idec
|
||||
!3001 format(a2,3i5,f7.2,f7.1,i5)
|
||||
|
||||
if(idec.ge.0) then
|
||||
dtdec=xdt !We have a q3 or q0 decode at nfqso
|
||||
@ -178,6 +220,9 @@ contains
|
||||
go to 100
|
||||
endif
|
||||
|
||||
if(ncontest.eq.1 .and. lagain .and. iand(ndepth,16).eq.16) go to 50
|
||||
if(ncontest.eq.1 .and. lagain .and. iand(ndepth,16).eq.0) go to 100
|
||||
|
||||
! Prepare for a single-period decode with iaptype = 0, 1, 2, or 4
|
||||
jpk0=(xdt+1.0)*6000 !Index of nominal start of signal
|
||||
if(ntrperiod.le.30) jpk0=(xdt+0.5)*6000 !For shortest sequences
|
||||
@ -200,11 +245,10 @@ contains
|
||||
read(c78,1060) apsymbols
|
||||
endif
|
||||
|
||||
call timer('q65loops',0)
|
||||
call timer('q65loop1',0)
|
||||
call q65_loops(c00,npts/2,nsps/2,nsubmode,ndepth,jpk0, &
|
||||
xdt,f0,iaptype,xdt1,f1,snr2,dat4,idec)
|
||||
call timer('q65loops',1)
|
||||
! write(*,3001) '=b',nfqso,ntol,ndepth,xdt,f0,idec
|
||||
call timer('q65loop1',1)
|
||||
if(idec.ge.0) then
|
||||
dtdec=xdt1
|
||||
f0dec=f1
|
||||
@ -215,11 +259,11 @@ contains
|
||||
if(iand(ndepth,16).eq.0 .or. navg(iseq).lt.2) go to 100
|
||||
|
||||
! There was no single-transmission decode. Try for an average 'q3n' decode.
|
||||
50 call timer('list_avg',0)
|
||||
50 iavg=1
|
||||
call timer('list_avg',0)
|
||||
! Call top-level routine in q65 module: establish sync and try for a q3
|
||||
! decode, this time using the cumulative 's1a' symbol spectra.
|
||||
iavg=1
|
||||
call q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
call q65_dec0(iavg,iwave,ntrperiod,nfqso,ntol,lclearave, &
|
||||
emedelay,xdt,f0,snr1,width,dat4,snr2,idec,stageno)
|
||||
call timer('list_avg',1)
|
||||
|
||||
@ -236,7 +280,7 @@ contains
|
||||
|
||||
call timer('q65_avg ',0)
|
||||
iavg=2
|
||||
call q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
call q65_dec0(iavg,iwave,ntrperiod,nfqso,ntol,lclearave, &
|
||||
emedelay,xdt,f0,snr1,width,dat4,snr2,idec,stageno)
|
||||
call timer('q65_avg ',1)
|
||||
if(idec.ge.0) then
|
||||
@ -250,7 +294,7 @@ contains
|
||||
call timer('q65_dec0',0)
|
||||
! Call top-level routine in q65 module: establish sync and try for a
|
||||
! q3 or q0 decode.
|
||||
call q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
call q65_dec0(iavg,iwave,ntrperiod,nfqso,ntol,lclearave, &
|
||||
emedelay,xdt,f0,snr1,width,dat4,snr2,idec,stageno)
|
||||
call timer('q65_dec0',1)
|
||||
if(idec.ge.0) then
|
||||
@ -280,15 +324,21 @@ contains
|
||||
if(idupe.eq.0) then
|
||||
ndecodes=min(ndecodes+1,100)
|
||||
decodes(ndecodes)=decoded
|
||||
call q65_snr(dat4,dtdec,f0dec,mode_q65,nused,snr2)
|
||||
f0decodes(ndecodes)=f0dec
|
||||
xdtdecodes(ndecodes)=dtdec
|
||||
call q65_snr(dat4,dtdec,f0dec,mode_q65,snr2)
|
||||
nsnr=nint(snr2)
|
||||
call this%callback(nutc,snr1,nsnr,dtdec,f0dec,decoded, &
|
||||
idec,nused,ntrperiod)
|
||||
call q65_hist(nint(f0dec),msg0=decoded)
|
||||
if(ncontest.eq.1) then
|
||||
call q65_hist2(nint(f0dec),decoded,callers,nhist2)
|
||||
else
|
||||
call q65_hist(nint(f0dec),msg0=decoded)
|
||||
endif
|
||||
if(iand(ndepth,128).ne.0 .and. .not.lagain .and. &
|
||||
int(abs(f0dec-nfqso)).le.ntol ) call q65_clravg !AutoClrAvg
|
||||
call sec0(1,tdecode)
|
||||
open(22,file=trim(data_dir)//'/q65_decodes.dat',status='unknown', &
|
||||
open(22,file=trim(data_dir)//'/q65_decodes.txt',status='unknown', &
|
||||
position='append',iostat=ios)
|
||||
if(ios.eq.0) then
|
||||
! Save decoding parameters to q65_decoded.dat, for later analysis.
|
||||
@ -298,13 +348,13 @@ contains
|
||||
if(c6.eq.' ') c6='<b> '
|
||||
c4=hisgrid(1:4)
|
||||
if(c4.eq.' ') c4='<b> '
|
||||
fmt='(i6.4,1x,a4,i5,4i2,6i3,i4,f6.2,f7.1,f6.1,f7.1,f6.2,'// &
|
||||
fmt='(i6.4,1x,a4,i5,4i2,8i3,i4,f6.2,f7.1,f6.1,f7.1,f6.2,'// &
|
||||
'1x,a6,1x,a6,1x,a4,1x,a)'
|
||||
if(ntrperiod.le.30) fmt(5:5)='6'
|
||||
if(idec.eq.3) nrc=0
|
||||
write(22,fmt) nutc,cmode,nfqso,nQSOprogress,idec,idfbest,idtbest, &
|
||||
ibw,ndistbest,nused,icand,ncand,nrc,ndepth,xdt,f0,snr2,plog, &
|
||||
tdecode,mycall(1:6),c6,c4,trim(decoded)
|
||||
ibwa,ibwb,ibw,ndistbest,nused,icand,ncand,nrc,ndepth,xdt, &
|
||||
f0,snr2,plog,tdecode,mycall(1:6),c6,c4,trim(decoded)
|
||||
close(22)
|
||||
endif
|
||||
endif
|
||||
@ -317,6 +367,26 @@ contains
|
||||
snr1=candidates(icand,1)
|
||||
xdt= candidates(icand,2)
|
||||
f0 = candidates(icand,3)
|
||||
do i=1,ndecodes
|
||||
fdiff=f0-f0decodes(i)
|
||||
if(fdiff.gt.-baud*mode_q65 .and. fdiff.lt.65*baud*mode_q65) go to 800
|
||||
enddo
|
||||
|
||||
!### TEST REGION
|
||||
if(ncontest.eq.-1) then
|
||||
call timer('q65_dec0',0)
|
||||
! Call top-level routine in q65 module: establish sync and try for a
|
||||
! q3 or q0 decode.
|
||||
call q65_dec0(iavg,iwave,ntrperiod,nint(f0),ntol,lclearave, &
|
||||
emedelay,xdt,f0,snr1,width,dat4,snr2,idec,stageno)
|
||||
call timer('q65_dec0',1)
|
||||
if(idec.ge.0) then
|
||||
dtdec=xdt !We have a q3 or q0 decode at f0
|
||||
f0dec=f0
|
||||
go to 200
|
||||
endif
|
||||
endif
|
||||
!###
|
||||
jpk0=(xdt+1.0)*6000 !Index of nominal start of signal
|
||||
if(ntrperiod.le.30) jpk0=(xdt+0.5)*6000 !For shortest sequences
|
||||
if(jpk0.lt.0) jpk0=0
|
||||
@ -329,6 +399,8 @@ contains
|
||||
if(lapcqonly) npasses=1
|
||||
iaptype=0
|
||||
do ipass=0,npasses !Loop over AP passes
|
||||
! write(*,3001) nutc,icand,ipass,f0,xdt,snr1
|
||||
!3001 format('a',i5.4,2i3,3f7.1)
|
||||
apmask=0 !Try first with no AP information
|
||||
apsymbols=0
|
||||
if(ipass.ge.1) then
|
||||
@ -341,10 +413,10 @@ contains
|
||||
read(c78,1060) apsymbols
|
||||
endif
|
||||
|
||||
call timer('q65loops',0)
|
||||
call timer('q65loop2',0)
|
||||
call q65_loops(c00,npts/2,nsps/2,nsubmode,ndepth,jpk0, &
|
||||
xdt,f0,iaptype,xdt1,f1,snr2,dat4,idec)
|
||||
call timer('q65loops',1)
|
||||
call timer('q65loop2',1)
|
||||
! write(*,3001) '=e',nfqso,ntol,ndepth,xdt,f0,idec
|
||||
if(idec.ge.0) then
|
||||
dtdec=xdt1
|
||||
@ -365,15 +437,21 @@ contains
|
||||
if(idupe.eq.0) then
|
||||
ndecodes=min(ndecodes+1,100)
|
||||
decodes(ndecodes)=decoded
|
||||
call q65_snr(dat4,dtdec,f0dec,mode_q65,nused,snr2)
|
||||
f0decodes(ndecodes)=f0dec
|
||||
call q65_snr(dat4,dtdec,f0dec,mode_q65,snr2)
|
||||
nsnr=nint(snr2)
|
||||
call this%callback(nutc,snr1,nsnr,dtdec,f0dec,decoded, &
|
||||
idec,nused,ntrperiod)
|
||||
call q65_hist(nint(f0dec),msg0=decoded)
|
||||
if(ncontest.eq.1) then
|
||||
call q65_hist2(nint(f0dec),decoded,callers,nhist2)
|
||||
else
|
||||
call q65_hist(nint(f0dec),msg0=decoded)
|
||||
endif
|
||||
if(iand(ndepth,128).ne.0 .and. .not.lagain .and. &
|
||||
int(abs(f0dec-nfqso)).le.ntol ) call q65_clravg !AutoClrAvg
|
||||
call sec0(1,tdecode)
|
||||
open(22,file=trim(data_dir)//'/q65_decodes.dat',status='unknown', &
|
||||
ios=1
|
||||
open(22,file=trim(data_dir)//'/q65_decodes.txt',status='unknown',&
|
||||
position='append',iostat=ios)
|
||||
if(ios.eq.0) then
|
||||
! Save decoding parameters to q65_decoded.dat, for later analysis.
|
||||
@ -383,20 +461,45 @@ contains
|
||||
if(c6.eq.' ') c6='<b> '
|
||||
c4=hisgrid(1:4)
|
||||
if(c4.eq.' ') c4='<b> '
|
||||
fmt='(i6.4,1x,a4,i5,4i2,6i3,i4,f6.2,f7.1,f6.1,f7.1,f6.2,'// &
|
||||
fmt='(i6.4,1x,a4,i5,4i2,8i3,i4,f6.2,f7.1,f6.1,f7.1,f6.2,'// &
|
||||
'1x,a6,1x,a6,1x,a4,1x,a)'
|
||||
if(ntrperiod.le.30) fmt(5:5)='6'
|
||||
if(idec.eq.3) nrc=0
|
||||
write(22,fmt) nutc,cmode,nfqso,nQSOprogress,idec,idfbest,idtbest, &
|
||||
ibw,ndistbest,nused,icand,ncand,nrc,ndepth,xdt,f0,snr2,plog, &
|
||||
tdecode,mycall(1:6),c6,c4,trim(decoded)
|
||||
write(22,fmt) nutc,cmode,nfqso,nQSOprogress,idec,idfbest, &
|
||||
idtbest,ibwa,ibwb,ibw,ndistbest,nused,icand,ncand,nrc, &
|
||||
ndepth,xdt,f0,snr2,plog,tdecode,mycall(1:6),c6,c4, &
|
||||
trim(decoded)
|
||||
close(22)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
800 continue
|
||||
enddo ! icand
|
||||
if(iavg.eq.0 .and.navg(iseq).ge.2 .and. iand(ndepth,16).ne.0) go to 50
|
||||
900 return
|
||||
|
||||
900 if(ncontest.ne.1 .or. lagain) go to 999
|
||||
if(ntrperiod.ne.60 .or. nsubmode.ne.0) go to 999
|
||||
|
||||
! This is first time here, and we're running Q65-60A in NA VHF Contest mode.
|
||||
! Return a list of potential sync frequencies at which to try q3 decoding.
|
||||
|
||||
k=0
|
||||
nqf=0
|
||||
bw=baud*mode_q65*65
|
||||
do i=1,ncand
|
||||
! snr1=candidates(i,1)
|
||||
! xdt= candidates(i,2)
|
||||
f0 = candidates(i,3)
|
||||
do j=1,ndecodes ! Already decoded one at or near this frequency?
|
||||
fj=f0decodes(j)
|
||||
if(f0.gt.fj-5.0 .and. f0.lt.fj+bw+5.0) go to 990
|
||||
enddo
|
||||
k=k+1
|
||||
nqf(k)=nint(f0)
|
||||
990 continue
|
||||
enddo
|
||||
|
||||
999 return
|
||||
end subroutine decode
|
||||
|
||||
end module q65_decode
|
||||
|
@ -2,8 +2,8 @@ module q65
|
||||
|
||||
parameter (NSTEP=8) !Number of time bins per symbol in s1, s1a, s1b
|
||||
parameter (PLOG_MIN=-242.0) !List decoding threshold
|
||||
integer nsave,nlist,LL0,iz0,jz0
|
||||
integer listutc(10)
|
||||
integer iz0,jz0
|
||||
! integer listutc(10)
|
||||
integer apsym0(58),aph10(10)
|
||||
integer apmask1(78),apsymbols1(78)
|
||||
integer apmask(13),apsymbols(13)
|
||||
@ -12,23 +12,22 @@ module q65
|
||||
integer codewords(63,206)
|
||||
integer ibwa,ibwb,ncw,nsps,mode_q65,nfa,nfb,nqd
|
||||
integer idfbest,idtbest,ibw,ndistbest,maxiters,max_drift
|
||||
integer istep,nsmo,lag1,lag2,npasses,nused,iseq,ncand,nrc
|
||||
integer istep,nsmo,lag1,lag2,npasses,iseq,ncand,nrc
|
||||
integer i0,j0
|
||||
integer navg(0:1)
|
||||
logical lnewdat
|
||||
real candidates(20,3) !snr, xdt, and f0 of top candidates
|
||||
real, allocatable :: s1raw(:,:) !Symbol spectra, 1/8-symbol steps
|
||||
real, allocatable :: s1(:,:) !Symbol spectra w/suppressed peaks
|
||||
real, allocatable :: s1w(:,:) !Symbol spectra w/suppressed peaks !w3sz added
|
||||
real, allocatable :: s1w(:,:) !Symbol spectra w/suppressed peaks (W3SZ)
|
||||
real, allocatable,save :: s1a(:,:,:) !Cumulative symbol spectra
|
||||
real, allocatable,save :: ccf2(:) !Max CCF(freq) at any lag, single seq
|
||||
real, allocatable,save :: ccf2_avg(:) !Like ccf2, but for accumulated average
|
||||
real, allocatable,save :: ccf2(:) !Max CCF(freq) at any lag (orange curve)
|
||||
real, allocatable,save :: ccf2_avg(:) !Like ccf2, but for avg (red curve)
|
||||
real sync(85) !sync vector
|
||||
real df,dtstep,dtdec,f0dec,ftol,plog,drift
|
||||
|
||||
contains
|
||||
|
||||
subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
subroutine q65_dec0(iavg,iwave,ntrperiod,nfqso,ntol,lclearave, &
|
||||
emedelay,xdt,f0,snr1,width,dat4,snr2,idec,stageno)
|
||||
|
||||
! Top-level routine in q65 module
|
||||
@ -41,7 +40,6 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
! ntrperiod T/R sequence length (s)
|
||||
! nfqso Target frequency (Hz)
|
||||
! ntol Search range around nfqso (Hz)
|
||||
! ndepth Requested decoding depth
|
||||
! lclearave Flag to clear the accumulating array
|
||||
! emedelay Extra delay for EME signals
|
||||
! Output: xdt Time offset from nominal (s)
|
||||
@ -68,7 +66,7 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
real, allocatable :: s3(:,:) !Data-symbol energies s3(LL,63)
|
||||
real, allocatable :: ccf1(:) !CCF(freq) at fixed lag (red)
|
||||
data first/.true./
|
||||
save first
|
||||
save first,LL0
|
||||
|
||||
integer w3t
|
||||
integer w3f
|
||||
@ -76,7 +74,6 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
integer stageno
|
||||
|
||||
NN=63
|
||||
if(nutc+ndepth.eq.-999) stop !Silence compiler warnings
|
||||
|
||||
! Set some parameters and allocate storage for large arrays
|
||||
irc=-2
|
||||
@ -95,7 +92,8 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
ftol=ntol
|
||||
ia=ntol/df
|
||||
ia2=max(ia,10*mode_q65,nint(100.0/df))
|
||||
nsmo=int(0.7*mode_q65*mode_q65)
|
||||
! nsmo=int(0.7*mode_q65*mode_q65)
|
||||
nsmo=int(0.5*mode_q65*mode_q65)
|
||||
if(nsmo.lt.1) nsmo=1
|
||||
if(first) then !Generate the sync vector
|
||||
sync=-22.0/63.0 !Sync tone OFF
|
||||
@ -107,8 +105,6 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
allocate(s3(-64:LL-65,63))
|
||||
allocate(ccf1(-ia2:ia2))
|
||||
if(LL.ne.LL0 .or. iz.ne.iz0 .or. jz.ne.jz0 .or. lclearave) then
|
||||
if(allocated(s1raw)) deallocate(s1raw)
|
||||
allocate(s1raw(iz,jz))
|
||||
if(allocated(s1)) deallocate(s1)
|
||||
allocate(s1(iz,jz))
|
||||
if(allocated(s1a)) deallocate(s1a)
|
||||
@ -126,7 +122,7 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
lclearave=.false.
|
||||
endif
|
||||
ccf1=0.
|
||||
if(iavg.eq.0) ccf2_avg=0.
|
||||
if(iavg.eq.0) ccf2=0.
|
||||
dtstep=nsps/(NSTEP*12000.0) !Step size in seconds
|
||||
lag1=-1.0/dtstep
|
||||
lag2=1.0/dtstep + 0.9999
|
||||
@ -135,29 +131,18 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
if(nsps.ge.7200) j0=1.0/dtstep !Nominal start-signal index
|
||||
|
||||
s3=0.
|
||||
! if(iavg.eq.0 .and. lnewdat) then
|
||||
if(iavg.eq.0) then
|
||||
call timer('q65_syms',0)
|
||||
! Compute symbol spectra with NSTEP time bins per symbol
|
||||
call q65_symspec(iwave,ntrperiod*12000,iz,jz,s1)
|
||||
call timer('q65_syms',1)
|
||||
! lnewdat=.false.
|
||||
else
|
||||
s1=s1a(:,:,iseq)
|
||||
endif
|
||||
|
||||
i0=nint(nfqso/df) !Target QSO frequency
|
||||
ii1=max(1,i0-64)
|
||||
ii2=i0-65+LL
|
||||
call pctile(s1(ii1:ii2,1:jz),ii2-ii1+1*jz,45,base)
|
||||
s1=s1/base
|
||||
s1raw=s1
|
||||
|
||||
! Apply fast AGC to the symbol spectra
|
||||
s1max=20.0 !Empirical choice
|
||||
do j=1,jz !### Maybe wrong way? ###
|
||||
smax=maxval(s1(ii1:ii2,j))
|
||||
if(smax.gt.s1max) s1(ii1:ii2,j)=s1(ii1:ii2,j)*s1max/smax
|
||||
enddo
|
||||
|
||||
dat4=0
|
||||
if(ncw.gt.0 .and. iavg.le.1) then
|
||||
! Try list decoding via "Deep Likelihood".
|
||||
@ -178,7 +163,7 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
! Get 2d CCF and ccf2 using sync symbols only
|
||||
if(iavg.eq.0) then
|
||||
call timer('ccf_22a ',0)
|
||||
call q65_ccf_22(s1,iz,jz,nfqso,ntol,ndepth,ntrperiod,iavg,ipk,jpk, &
|
||||
call q65_ccf_22(s1,iz,jz,nfqso,ntol,iavg,ipk,jpk, &
|
||||
f0a,xdta,ccf2)
|
||||
call timer('ccf_22a ',1)
|
||||
endif
|
||||
@ -186,7 +171,7 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
! Get 2d CCF and ccf2_avg using sync symbols only
|
||||
if(iavg.ge.1) then
|
||||
call timer('ccf_22b ',0)
|
||||
call q65_ccf_22(s1,iz,jz,nfqso,ntol,ndepth,ntrperiod,iavg,ipk,jpk, &
|
||||
call q65_ccf_22(s1,iz,jz,nfqso,ntol,iavg,ipk,jpk, &
|
||||
f0a,xdta,ccf2_avg)
|
||||
call timer('ccf_22b ',1)
|
||||
endif
|
||||
@ -217,10 +202,8 @@ subroutine q65_dec0(iavg,nutc,iwave,ntrperiod,nfqso,ntol,ndepth,lclearave, &
|
||||
if(i2.eq.-9999 .and. ccf1(-i).ge.0.5*smax) i2=-i
|
||||
enddo
|
||||
width=df*(i2-i1)
|
||||
|
||||
if(ncw.eq.0) ccf1=0.
|
||||
|
||||
call q65_write_red(iz,xdt,ccf2_avg,ccf2)
|
||||
call q65_write_red(iz,xdt,ccf2_avg,ccf2) !### Need this call for WSJT-X
|
||||
|
||||
if(idec.lt.0 .and. (iavg.eq.0 .or. iavg.eq.2)) then
|
||||
call q65_dec_q012(s3,LL,snr2,dat4,idec,decoded)
|
||||
@ -291,7 +274,7 @@ subroutine q65_symspec(iwave,nmax,iz,jz,s1)
|
||||
allocate(c0(0:nsps-1))
|
||||
nfft=nsps
|
||||
fac=1/32767.0
|
||||
do j=1,jz !Compute symbol spectra at step size
|
||||
do j=1,jz,2 !Compute symbol spectra at 2*step size
|
||||
i1=(j-1)*istep
|
||||
i2=i1+nsps-1
|
||||
k=-1
|
||||
@ -311,6 +294,8 @@ subroutine q65_symspec(iwave,nmax,iz,jz,s1)
|
||||
do i=1,nsmo
|
||||
call smo121(s1(1:iz,j),iz)
|
||||
enddo
|
||||
! Interpolate to fill in the skipped-over spectra.
|
||||
if(j.ge.3) s1(1:iz,j-1)=0.5*(s1(1:iz,j-2)+s1(1:iz,j))
|
||||
enddo
|
||||
if(lnewdat) then
|
||||
navg(iseq)=navg(iseq) + 1
|
||||
@ -481,7 +466,7 @@ subroutine q65_ccf_85(s1,iz,jz,nfqso,ia,ia2,ipk,jpk,f0,xdt,imsg_best, &
|
||||
return
|
||||
end subroutine q65_ccf_85
|
||||
|
||||
subroutine q65_ccf_22(s1,iz,jz,nfqso,ntol,ndepth,ntrperiod,iavg,ipk,jpk, &
|
||||
subroutine q65_ccf_22(s1,iz,jz,nfqso,ntol,iavg,ipk,jpk, &
|
||||
f0,xdt,ccf2)
|
||||
|
||||
! Attempt synchronization using only the 22 sync symbols. Return ccf2
|
||||
@ -489,6 +474,7 @@ subroutine q65_ccf_22(s1,iz,jz,nfqso,ntol,ndepth,ntrperiod,iavg,ipk,jpk, &
|
||||
|
||||
real s1(iz,jz)
|
||||
real ccf2(iz) !Orange sync curve
|
||||
real tmp(20,3)
|
||||
real, allocatable :: xdt2(:)
|
||||
real, allocatable :: s1avg(:)
|
||||
integer, allocatable :: indx(:)
|
||||
@ -499,11 +485,12 @@ subroutine q65_ccf_22(s1,iz,jz,nfqso,ntol,ndepth,ntrperiod,iavg,ipk,jpk, &
|
||||
|
||||
ia=max(nfa,100)/df
|
||||
ib=min(nfb,4900)/df
|
||||
if(nqd.ne.1 .or. iavg.ne.0) max_drift=0
|
||||
! if(nqd.ne.1 .or. iavg.ne.0) max_drift=0 !### Disabled March 22, 2023
|
||||
if(max_drift.ne.0) then
|
||||
ia=max(nint(100/df),nint((nfqso-ntol)/df))
|
||||
ib=min(nint(4900/df),nint((nfqso+ntol)/df))
|
||||
endif
|
||||
if(ia.ge.ib) ia=ib-ntol/df !Protect against wacky settings
|
||||
|
||||
do i=ia,ib
|
||||
s1avg(i)=sum(s1(i,1:jz))
|
||||
@ -513,7 +500,9 @@ subroutine q65_ccf_22(s1,iz,jz,nfqso,ntol,ndepth,ntrperiod,iavg,ipk,jpk, &
|
||||
ibest=0
|
||||
lagpk=0
|
||||
lagbest=0
|
||||
idrift_max=0
|
||||
idrift_best=0
|
||||
|
||||
do i=ia,ib
|
||||
ccfmax=0.
|
||||
do lag=lag1,lag2
|
||||
@ -535,10 +524,13 @@ subroutine q65_ccf_22(s1,iz,jz,nfqso,ntol,ndepth,ntrperiod,iavg,ipk,jpk, &
|
||||
endif
|
||||
enddo ! idrift
|
||||
enddo ! lag
|
||||
|
||||
ccf2(i)=ccfmax
|
||||
xdt2(i)=lagpk*dtstep
|
||||
|
||||
if(ccfmax.gt.ccfbest .and. abs(i*df-nfqso).le.ftol) then
|
||||
ccfbest=ccfmax
|
||||
snrbest=snr
|
||||
ibest=i
|
||||
lagbest=lagpk
|
||||
idrift_best=idrift_max
|
||||
@ -556,28 +548,39 @@ subroutine q65_ccf_22(s1,iz,jz,nfqso,ntol,ndepth,ntrperiod,iavg,ipk,jpk, &
|
||||
|
||||
! Save parameters for best candidates
|
||||
jzz=ib-ia+1
|
||||
call pctile(ccf2(ia:ib),jzz,40,base)
|
||||
ccf2=ccf2/base
|
||||
call indexx(ccf2(ia:ib),jzz,indx)
|
||||
|
||||
call pctile(ccf2(ia:ib),jzz,50,ave)
|
||||
call pctile(ccf2(ia:ib),jzz,84,base)
|
||||
rms=base-ave
|
||||
ncand=0
|
||||
maxcand=20
|
||||
do j=1,20
|
||||
k=jzz-j+1
|
||||
if(k.lt.1 .or. k.gt.iz) cycle
|
||||
i=indx(k)+ia-1
|
||||
if(ccf2(i).lt.3.3) exit !Candidate limit
|
||||
f=i*df
|
||||
i3=max(1, i-mode_q65)
|
||||
i4=min(iz,i+mode_q65)
|
||||
biggest=maxval(ccf2(i3:i4))
|
||||
if(ccf2(i).ne.biggest) cycle
|
||||
snr=(ccf2(i)-ave)/rms
|
||||
if(snr.lt.6.0) exit
|
||||
ncand=ncand+1
|
||||
candidates(ncand,1)=ccf2(i)
|
||||
candidates(ncand,1)=snr
|
||||
candidates(ncand,2)=xdt2(i)
|
||||
candidates(ncand,3)=f
|
||||
if(ncand.ge.maxcand) exit
|
||||
enddo
|
||||
|
||||
! Resort the candidates back into frequency order
|
||||
tmp(1:ncand,1:3)=candidates(1:ncand,1:3)
|
||||
candidates=0.
|
||||
call indexx(tmp(1:ncand,3),ncand,indx)
|
||||
do i=1,ncand
|
||||
candidates(i,1:3)=tmp(indx(i),1:3)
|
||||
enddo
|
||||
|
||||
return
|
||||
end subroutine q65_ccf_22
|
||||
|
||||
@ -591,7 +594,7 @@ subroutine q65_dec1(s3,nsubmode,b90ts,esnodb,irc,dat4,decoded)
|
||||
integer dat4(13)
|
||||
character c77*77,decoded*37
|
||||
logical unpk77_success
|
||||
|
||||
|
||||
nFadingModel=1
|
||||
decoded=' '
|
||||
call q65_intrinsics_ff(s3,nsubmode,b90ts,nFadingModel,s3prob)
|
||||
@ -605,7 +608,7 @@ subroutine q65_dec1(s3,nsubmode,b90ts,esnodb,irc,dat4,decoded)
|
||||
irc=-1
|
||||
endif
|
||||
nrc=irc
|
||||
|
||||
|
||||
return
|
||||
end subroutine q65_dec1
|
||||
|
||||
@ -672,16 +675,21 @@ subroutine q65_write_red(iz,xdt,ccf2_avg,ccf2)
|
||||
call q65_sync_curve(ccf2_avg,1,iz,rms1)
|
||||
call q65_sync_curve(ccf2,1,iz,rms2)
|
||||
|
||||
i1=max(1,nint(nfa/df))
|
||||
i2=min(iz,int(nfb/df))
|
||||
y0=minval(ccf2(i1:i2))
|
||||
y0_avg=minval(ccf2_avg(i1:i2))
|
||||
g=0.4
|
||||
g_avg=0.
|
||||
if(navg(iseq).ge.2) g_avg=g
|
||||
rewind 17
|
||||
write(17,1000) xdt,minval(ccf2_avg),maxval(ccf2_avg)
|
||||
do i=max(1,nint(nfa/df)),min(iz,int(nfb/df))
|
||||
write(17,1000) xdt,g_avg*minval(ccf2_avg),g_avg*maxval(ccf2_avg)
|
||||
do i=i1,i2
|
||||
freq=i*df
|
||||
y1=ccf2_avg(i)
|
||||
if(y1.gt.10.0) y1=10.0 + 2.0*log10(y1/10.0)
|
||||
y2=ccf2(i)
|
||||
if(y2.gt.10.0) y2=10.0 + 2.0*log10(y2/10.0)
|
||||
y1=g_avg*(ccf2_avg(i)-y0_avg)
|
||||
y2=g*(ccf2(i)-y0)
|
||||
write(17,1000) freq,y1,y2
|
||||
1000 format(3f10.3)
|
||||
1000 format(f10.3,2f15.6)
|
||||
enddo
|
||||
flush(17)
|
||||
|
||||
@ -733,7 +741,7 @@ subroutine q65_bzap(s3,LL)
|
||||
return
|
||||
end subroutine q65_bzap
|
||||
|
||||
subroutine q65_snr(dat4,dtdec,f0dec,mode_q65,nused,snr2)
|
||||
subroutine q65_snr(dat4,dtdec,f0dec,mode_q65,snr2)
|
||||
|
||||
! Estimate SNR of a decoded transmission by aligning the spectra of
|
||||
! all 85 symbols.
|
||||
@ -764,7 +772,7 @@ subroutine q65_snr(dat4,dtdec,f0dec,mode_q65,nused,snr2)
|
||||
if(j.ge.1 .and. j.le.jz0) then
|
||||
do i=1,iz0
|
||||
ii=i+mode_q65*itone(k)
|
||||
if(ii.ge.1 .and. ii.le.iz0) spec(i)=spec(i) + s1raw(ii,j)
|
||||
if(ii.ge.1 .and. ii.le.iz0) spec(i)=spec(i) + s1(ii,j)
|
||||
enddo
|
||||
endif
|
||||
enddo
|
||||
@ -781,8 +789,6 @@ subroutine q65_snr(dat4,dtdec,f0dec,mode_q65,nused,snr2)
|
||||
sig_area=sum(spec(ia+nsum:ib-nsum)-1.0)
|
||||
w_equiv=sig_area/(smax-1.0)
|
||||
snr2=db(max(1.0,sig_area)) - db(2500.0/df)
|
||||
! NB: No adjustment to SNR is now made for nused>1, because that process did
|
||||
! not seem to work as expected.
|
||||
|
||||
return
|
||||
end subroutine q65_snr
|
||||
@ -841,4 +847,66 @@ subroutine q65_hist(if0,msg0,dxcall,dxgrid)
|
||||
900 return
|
||||
end subroutine q65_hist
|
||||
|
||||
subroutine q65_hist2(nfreq,msg0,callers,nhist2)
|
||||
|
||||
use types
|
||||
use prog_args
|
||||
parameter (MAX_CALLERS=40) !For multiple q3 decodes in NA VHf Contest mode
|
||||
character*37 msg0,msg
|
||||
type(q3list) callers(MAX_CALLERS)
|
||||
character*6 c6
|
||||
character*4 g4
|
||||
logical newcall,isgrid
|
||||
|
||||
isgrid(g4)=g4(1:1).ge.'A' .and. g4(1:1).le.'R' .and. g4(2:2).ge.'A' .and. &
|
||||
g4(2:2).le.'R' .and. g4(3:3).ge.'0' .and. g4(3:3).le.'9' .and. &
|
||||
g4(4:4).ge.'0' .and. g4(4:4).le.'9' .and. g4(1:4).ne.'RR73'
|
||||
|
||||
msg=msg0
|
||||
if(index(msg,'/').gt.0) goto 900 !Ignore messages with compound calls
|
||||
i0=index(msg,' R ')
|
||||
if(i0.ge.7) msg=msg(1:i0)//msg(i0+3:)
|
||||
i1=index(msg,' ')
|
||||
c6=' '
|
||||
g4=' '
|
||||
if(i1.ge.4 .and. i1.le.13) then
|
||||
i2=index(msg(i1+1:),' ') + i1
|
||||
c6=msg(i1+1:i2-1) !Extract DX call
|
||||
g4=msg(i2+1:i2+4) !Extract DX grid
|
||||
endif
|
||||
|
||||
newcall=.true.
|
||||
do i=1,nhist2
|
||||
if(callers(i)%call .eq. c6) then
|
||||
newcall=.false.
|
||||
callers(i)%nsec=time()
|
||||
callers(i)%nfreq=nfreq
|
||||
exit
|
||||
endif
|
||||
enddo
|
||||
|
||||
if(newcall .and. isgrid(g4)) then
|
||||
if(nhist2.eq.MAX_CALLERS) then
|
||||
! Purge the oldest caller
|
||||
callers(1:MAX_CALLERS-1)=callers(2:MAX_CALLERS)
|
||||
nhist2=nhist2-1
|
||||
endif
|
||||
nhist2=nhist2+1
|
||||
callers(nhist2)%call=c6
|
||||
callers(nhist2)%grid=g4
|
||||
callers(nhist2)%nsec=time()
|
||||
callers(nhist2)%nfreq=nfreq
|
||||
endif
|
||||
|
||||
if(nhist2.ge.1 .and. nhist2.le.40) then
|
||||
open(24,file=trim(data_dir)//'/tsil.3q',status='unknown', &
|
||||
form='unformatted')
|
||||
write(24) nhist2
|
||||
write(24) callers(1:nhist2)
|
||||
close(24)
|
||||
endif
|
||||
|
||||
900 return
|
||||
end subroutine q65_hist2
|
||||
|
||||
end module q65
|
||||
|
@ -135,10 +135,9 @@ end
|
||||
|
||||
subroutine get_q65crc12(mc2,ncrc1,ncrc2)
|
||||
!
|
||||
character c12*12,c6*6
|
||||
character c6*6
|
||||
integer*1 mc(90),mc2(90),tmp(6)
|
||||
integer*1 r(13),p(13)
|
||||
integer ncrc
|
||||
! polynomial for 12-bit CRC 0xF01
|
||||
data p/1,1,0,0,0,0,0,0,0,1,1,1,1/
|
||||
|
||||
@ -170,7 +169,6 @@ subroutine get_q65_tones(msg37,codeword,itone)
|
||||
implicit none
|
||||
character*37 msg37
|
||||
character*77 c77
|
||||
character*12 c12
|
||||
character*6 c6
|
||||
integer codeword(65)
|
||||
integer sync(22)
|
||||
|
@ -37,7 +37,7 @@ subroutine q65_loops(c00,npts2,nsps2,nsubmode,ndepth,jpk0, &
|
||||
if(iand(ndepth,3).eq.3) then
|
||||
idfmax=5
|
||||
idtmax=5
|
||||
maxdist=15
|
||||
maxdist=5
|
||||
endif
|
||||
|
||||
napmin=99
|
||||
|
@ -3,7 +3,7 @@ subroutine q65_set_list(mycall,hiscall,hisgrid,codewords,ncw)
|
||||
parameter (MAX_NCW=206)
|
||||
character*12 mycall,hiscall
|
||||
character*6 hisgrid
|
||||
character*37 msg0,msg,msgsent
|
||||
character*37 msg,msgsent
|
||||
logical my_std,his_std
|
||||
integer codewords(63,MAX_NCW)
|
||||
integer itone(85)
|
||||
@ -45,7 +45,7 @@ subroutine q65_set_list(mycall,hiscall,hisgrid,codewords,ncw)
|
||||
endif
|
||||
endif
|
||||
|
||||
10 call genq65(msg,0,msgsent,itone,i3,n3)
|
||||
call genq65(msg,0,msgsent,itone,i3,n3)
|
||||
i0=1
|
||||
j=0
|
||||
do k=1,85
|
||||
|
70
lib/qra/q65/q65_set_list2.f90
Normal file
70
lib/qra/q65/q65_set_list2.f90
Normal file
@ -0,0 +1,70 @@
|
||||
subroutine q65_set_list2(mycall,hiscall,hisgrid,callers,nhist2,codewords,ncw)
|
||||
|
||||
use types
|
||||
parameter (MAX_NCW=206)
|
||||
parameter (MAX_CALLERS=40) !For multiple q3 decodes in NA VHf Contest mode
|
||||
character*12 mycall,hiscall
|
||||
character*6 hisgrid,c6
|
||||
character*4 g4
|
||||
character*37 msg,msgsent
|
||||
logical std,isgrid
|
||||
integer codewords(63,MAX_NCW)
|
||||
integer itone(85)
|
||||
integer isync(22)
|
||||
type(q3list) callers(MAX_CALLERS)
|
||||
|
||||
data isync/1,9,12,13,15,22,23,26,27,33,35,38,46,50,55,60,62,66,69,74,76,85/
|
||||
|
||||
isgrid(g4)=g4(1:1).ge.'A' .and. g4(1:1).le.'R' .and. g4(2:2).ge.'A' .and. &
|
||||
g4(2:2).le.'R' .and. g4(3:3).ge.'0' .and. g4(3:3).le.'9' .and. &
|
||||
g4(4:4).ge.'0' .and. g4(4:4).le.'9' .and. g4(1:4).ne.'RR73'
|
||||
|
||||
call stdcall(hiscall,std)
|
||||
jmax=nhist2
|
||||
if(std .and. isgrid(hisgrid(1:4))) then
|
||||
jmax=min(MAX_CALLERS,nhist2+1)
|
||||
do j=1,nhist2
|
||||
if(callers(j)%call .eq. hiscall(1:6)) then
|
||||
jmax=nhist2
|
||||
exit
|
||||
endif
|
||||
enddo
|
||||
endif
|
||||
|
||||
codewords(:,1)=0
|
||||
i=1
|
||||
do j=1,jmax
|
||||
c6=callers(j)%call
|
||||
g4=callers(j)%grid
|
||||
if(j.eq.nhist2+1) then
|
||||
c6=hiscall(1:6)
|
||||
g4=hisgrid(1:4)
|
||||
endif
|
||||
do k=1,5
|
||||
i=i+1
|
||||
msg=trim(mycall)//' '//trim(c6)
|
||||
j0=len(trim(msg))+1
|
||||
if(k.eq.1) msg=msg(1:j0)//g4
|
||||
if(k.eq.2) msg=msg(1:j0)//'R '//g4
|
||||
if(k.eq.3) msg(j0:j0+3)=' RRR'
|
||||
if(k.eq.4) msg(j0:j0+4)=' RR73'
|
||||
if(k.eq.5) msg(j0:j0+2)=' 73'
|
||||
call genq65(msg,0,msgsent,itone,i3,n3)
|
||||
i0=1
|
||||
jj=0
|
||||
do kk=1,85
|
||||
if(kk.eq.isync(i0)) then
|
||||
i0=i0+1
|
||||
cycle
|
||||
endif
|
||||
jj=jj+1
|
||||
codewords(jj,i)=itone(kk) - 1
|
||||
enddo
|
||||
! write(71,3001) i,j,k,codewords(1:13,i),trim(msg)
|
||||
!3001 format(3i3,2x,13i3,2x,a)
|
||||
enddo
|
||||
enddo
|
||||
ncw=i
|
||||
|
||||
return
|
||||
end subroutine q65_set_list2
|
@ -8,6 +8,7 @@ program q65sim
|
||||
type(hdr) h !Header for .wav file
|
||||
integer*2 iwave(NMAX) !Generated waveform
|
||||
integer itone(85) !Channel symbols (values 0-65)
|
||||
integer ntone(85,10) !Channel symbols for up to 10 messages
|
||||
integer y(63) !Codeword
|
||||
integer istart !averaging compatible start seconds
|
||||
integer imins !minutes for 15s period timestamp
|
||||
@ -17,19 +18,20 @@ program q65sim
|
||||
complex cdat(NMAX) !Generated complex waveform
|
||||
complex cspread(0:NMAX-1) !Complex amplitude for Rayleigh fading
|
||||
complex z
|
||||
real*8 f0,dt,twopi,phi,dphi,baud,fsample,freq
|
||||
character msg*37,fname*17,csubmode*1,arg*12
|
||||
character msgsent*37
|
||||
real*8 f00,f0,dt,twopi,phi,dphi,baud,fsample,freq
|
||||
character fname*17,csubmode*1,arg*12,c2*2
|
||||
character*37 msg,msgsent,imsg(10)
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.ne.10) then
|
||||
print*,'Usage: q65sim "msg" A-E freq fDop DT f1 Stp TRp Nfile SNR'
|
||||
print*,'Example: q65sim "K1ABC W9XYZ EN37" A 1500 0.0 0.0 0.0 1 60 1 -26'
|
||||
if(nargs.ne.11) then
|
||||
print*,'Usage: q65sim "msg" A-E freq fDop DT f1 Stp TRp Nsig Nfile SNR'
|
||||
print*,'Example: q65sim "K1ABC W9XYZ EN37" A 1500 0.0 0.0 0.0 1 60 1 1 -26'
|
||||
print*,'Example: q65sim "ST" A 1500 0.0 0.0 0.0 1 60 1 -26'
|
||||
print*,' fDop = Doppler spread'
|
||||
print*,' f1 = Drift or Doppler rate (Hz/min)'
|
||||
print*,' Stp = Step size (Hz)'
|
||||
print*,' Stp = 0 implies no Doppler tracking'
|
||||
print*,' Nsig = number of generated signals, 1 - 10'
|
||||
print*,' Creates filenames which increment to permit averaging in first period'
|
||||
print*,' If msg = ST program produces a single tone at freq'
|
||||
go to 999
|
||||
@ -38,7 +40,7 @@ program q65sim
|
||||
call getarg(2,csubmode)
|
||||
mode65=2**(ichar(csubmode)-ichar('A'))
|
||||
call getarg(3,arg)
|
||||
read(arg,*) f0
|
||||
read(arg,*) f00
|
||||
call getarg(4,arg)
|
||||
read(arg,*) fspread
|
||||
call getarg(5,arg)
|
||||
@ -50,8 +52,10 @@ program q65sim
|
||||
call getarg(8,arg)
|
||||
read(arg,*) ntrperiod
|
||||
call getarg(9,arg)
|
||||
read(arg,*) nfiles
|
||||
read(arg,*) nsig
|
||||
call getarg(10,arg)
|
||||
read(arg,*) nfiles
|
||||
call getarg(11,arg)
|
||||
read(arg,*) snrdb
|
||||
|
||||
if(ntrperiod.eq.15) then
|
||||
@ -79,22 +83,39 @@ program q65sim
|
||||
nsym=85 !Number of channel symbols
|
||||
mode65=2**(ichar(csubmode) - ichar('A'))
|
||||
|
||||
ichk=0
|
||||
call genq65(msg,ichk,msgsent,itone,i3,n3)
|
||||
|
||||
imsg(1)=msg
|
||||
if(nsig.ge.2) then
|
||||
i0=index(msg,' ')
|
||||
i0=i0 + index(msg(i0+1:),' ')-2
|
||||
do i=1,nsig
|
||||
c2=char(ichar('A')+i-1)//char(ichar('A')+i-1)
|
||||
imsg(i)=msg(1:i0-1)//c2//msg(i0+2:)
|
||||
enddo
|
||||
endif
|
||||
|
||||
j=0
|
||||
do i=1,85
|
||||
if(itone(i).gt.0) then
|
||||
j=j+1
|
||||
y(j)=itone(i)-1
|
||||
endif
|
||||
ichk=0
|
||||
do i=1,nsig
|
||||
msg=imsg(i)
|
||||
call genq65(msg,ichk,msgsent,itone,i3,n3)
|
||||
ntone(:,i)=itone
|
||||
enddo
|
||||
write(*,1001) y(1:13),y(1:13)
|
||||
|
||||
if(nsig.eq.1) then
|
||||
j=0
|
||||
do i=1,85
|
||||
if(itone(i).gt.0) then
|
||||
j=j+1
|
||||
y(j)=itone(i)-1
|
||||
endif
|
||||
enddo
|
||||
write(*,1001) y(1:13),y(1:13)
|
||||
1001 format('Generated message'/'6-bit: ',13i3/'binary: ',13b6.6)
|
||||
write(*,1002) y
|
||||
write(*,1002) y
|
||||
1002 format(/'Codeword:'/(20i3))
|
||||
write(*,1003) itone
|
||||
write(*,1003) itone
|
||||
1003 format(/'Channel symbols:'/(20i3))
|
||||
endif
|
||||
|
||||
baud=12000.d0/nsps !Keying rate (6.67 baud fot 15-s sequences)
|
||||
h=default_header(12000,npts)
|
||||
@ -116,43 +137,54 @@ program q65sim
|
||||
|
||||
open(10,file=trim(fname),access='stream',status='unknown')
|
||||
xnoise=0.
|
||||
cdat=0.
|
||||
if(snrdb.lt.90) then
|
||||
do i=1,npts
|
||||
xnoise(i)=gran() !Generate gaussian noise
|
||||
enddo
|
||||
endif
|
||||
cdat=0.
|
||||
|
||||
bandwidth_ratio=2500.0/6000.0
|
||||
sig=sqrt(2*bandwidth_ratio)*10.0**(0.05*snrdb)
|
||||
if(snrdb.gt.90.0) sig=1.0
|
||||
write(*,1020) ifile,ntrperiod,f0,csubmode,snrdb,fspread,xdt,f1,nstp,trim(msgsent)
|
||||
1020 format(i4,i6,f7.1,2x,a1,2x,f5.1,1x,f6.2,2f6.1,i4,2x,a)
|
||||
phi=0.d0
|
||||
dphi=0.d0
|
||||
k=(xdt+0.5)*12000 !Start audio at t=xdt+0.5 s (TR=15 and 30 s)
|
||||
if(ntrperiod.ge.60) k=(xdt+1.0)*12000 !TR 60+ at t = xdt + 1.0 s
|
||||
isym0=-99
|
||||
do i=1,npts !Add this signal into cdat()
|
||||
isym=i/nsps + 1
|
||||
if(isym.gt.nsym) exit
|
||||
if(isym.ne.isym0) then
|
||||
freq_drift=f1*i*dt/60.0
|
||||
if(nstp.ne.0) freq_drift=freq_drift - nstp*nint(freq_drift/nstp)
|
||||
if (msg(1:2).eq.'ST') then
|
||||
freq = f0 + freq_drift
|
||||
else
|
||||
freq = f0 + freq_drift + itone(isym)*baud*mode65
|
||||
endif
|
||||
dphi=twopi*freq*dt
|
||||
isym0=isym
|
||||
write(*,1020) ifile,ntrperiod,f00,csubmode,snrdb,fspread,xdt,f1,nstp,trim(msgsent)
|
||||
1020 format(i4,i6,f7.1,2x,a1,2x,f5.1,1x,f6.2,2f6.1,i4,2x,a)
|
||||
|
||||
n=65.0*baud*mode65/100.0 + 0.9999
|
||||
nfstep=100*n
|
||||
nf1=1500 - nfstep*(nsig-1)/2
|
||||
do n=1,nsig
|
||||
f0=f00
|
||||
if(nsig.ge.2) then
|
||||
f0=nf1 + (n-1)*nfstep
|
||||
itone=ntone(:,n)
|
||||
endif
|
||||
phi=phi + dphi
|
||||
if(phi.gt.twopi) phi=phi-twopi
|
||||
xphi=phi
|
||||
z=cmplx(cos(xphi),sin(xphi))
|
||||
k=k+1
|
||||
if(k.ge.1) cdat(k)=cdat(k) + sig*z
|
||||
phi=0.d0
|
||||
dphi=0.d0
|
||||
k=(xdt+0.5)*12000 !Start audio at t=xdt+0.5 s (TR=15 and 30 s)
|
||||
if(ntrperiod.ge.60) k=(xdt+1.0)*12000 !TR 60+ at t = xdt + 1.0 s
|
||||
isym0=-99
|
||||
do i=1,npts !Add this signal into cdat()
|
||||
isym=i/nsps + 1
|
||||
if(isym.gt.nsym) exit
|
||||
if(isym.ne.isym0) then
|
||||
freq_drift=f1*i*dt/60.0
|
||||
if(nstp.ne.0) freq_drift=freq_drift - nstp*nint(freq_drift/nstp)
|
||||
if (msg(1:2).eq.'ST') then
|
||||
freq = f0 + freq_drift
|
||||
else
|
||||
freq = f0 + freq_drift + itone(isym)*baud*mode65
|
||||
endif
|
||||
dphi=twopi*freq*dt
|
||||
isym0=isym
|
||||
endif
|
||||
phi=phi + dphi
|
||||
if(phi.gt.twopi) phi=phi-twopi
|
||||
xphi=phi
|
||||
z=cmplx(cos(xphi),sin(xphi))
|
||||
k=k+1
|
||||
if(k.ge.1) cdat(k)=cdat(k) + sig*z
|
||||
enddo
|
||||
enddo
|
||||
|
||||
if(fspread.ne.0) then !Apply specified Doppler spread
|
||||
|
@ -35,7 +35,7 @@ program sumsim
|
||||
fac=1.0/nargs
|
||||
iwave(1:npts)=nint(fac*wave(1:npts))
|
||||
|
||||
open(12,file='000000_0000.wav',access='stream',status='unknown')
|
||||
open(12,file='000001_0000.wav',access='stream',status='unknown')
|
||||
write(12) h,iwave(1:npts)
|
||||
close(12)
|
||||
|
||||
|
@ -50,7 +50,7 @@ subroutine sun(y,m,DD,UT,lon,lat,RA,Dec,LST,Az,El,mjd,day)
|
||||
MM = mod(356.0470d0 + 0.9856002585d0 * d + 360000.d0,360.d0)
|
||||
Ls = mod(w+MM+720.0,360.0)
|
||||
|
||||
EE = MM + e*rad*sin(MM/rad) * (1.0 + e*cos(M/rad))
|
||||
EE = MM + e*rad*sin(MM/rad) * (1.0 + e*cos(MM/rad))
|
||||
EE = EE - (EE - e*rad*sin(EE/rad)-MM) / (1.0 - e*cos(EE/rad))
|
||||
|
||||
xv = cos(EE/rad) - e
|
||||
|
@ -1,129 +0,0 @@
|
||||
program test_qra64
|
||||
|
||||
character*71 cmd1,cmd2,line
|
||||
character*22 msg
|
||||
character*8 arg
|
||||
character*1 csubmode
|
||||
integer nretcode(0:11)
|
||||
logical decok
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.ne.9) then
|
||||
print*,'Usage: test_qra64 "msg" A-D depth freq DT fDop TRp nfiles SNR'
|
||||
print*,'Example: test_qra64 "K1ABC W9XYZ EN37" A 3 1000 0.0 5.0 60 100 -20'
|
||||
print*,' SNR = 0 to loop over all relevant SNRs'
|
||||
go to 999
|
||||
endif
|
||||
call getarg(1,msg)
|
||||
call getarg(2,csubmode)
|
||||
call getarg(3,arg)
|
||||
read(arg,*) ndepth
|
||||
call getarg(4,arg)
|
||||
read(arg,*) nf0
|
||||
call getarg(5,arg)
|
||||
read(arg,*) dt
|
||||
call getarg(6,arg)
|
||||
read(arg,*) fDop
|
||||
call getarg(7,arg)
|
||||
read(arg,*) ntrperiod
|
||||
call getarg(8,arg)
|
||||
read(arg,*) nfiles
|
||||
call getarg(9,arg)
|
||||
read(arg,*) nsnr
|
||||
|
||||
nsps=6192
|
||||
i50=-28
|
||||
ia=-20
|
||||
ib=-33
|
||||
if(nsnr.ne.0) then
|
||||
ia=nsnr
|
||||
ib=nsnr
|
||||
endif
|
||||
|
||||
baud=12000.0/nsps
|
||||
tsym=1.0/baud
|
||||
|
||||
! 1 2 3 4 5 6 7
|
||||
! 12345678901234567890123456789012345678901234567890123456789012345678901'
|
||||
cmd1='qra64sim "K1ABC W9XYZ EN37 " A 1 0.2 0.00 100 F -20 > junk0'
|
||||
|
||||
cmd2='jt9 -q -L 300 -H 3000 -f 1000 -d 3 -b A *.wav > junk'
|
||||
|
||||
write(cmd1(10:33),'(a)') '"'//msg//'"'
|
||||
cmd1(35:35)=csubmode
|
||||
write(cmd1(40:43),'(f4.1)') fDop
|
||||
write(cmd1(44:48),'(f5.2)') dt
|
||||
write(cmd1(49:53),'(i5)') nfiles
|
||||
|
||||
write(cmd2(26:29),'(i4)') nf0
|
||||
write(cmd2(34:34),'(i1)') ndepth
|
||||
cmd2(39:39)=csubmode
|
||||
|
||||
call system('rm -f *.wav')
|
||||
|
||||
write(*,1000) (j,j=0,11)
|
||||
write(12,1000) (j,j=0,11)
|
||||
1000 format(/'SNR d Dop Sync Dec Bad',i6,11i4,' tdec'/80('-'))
|
||||
|
||||
dterr=tsym/4.0
|
||||
nferr=max(1,nint(0.5*baud),nint(fdop/3.0))
|
||||
ndecodes0=nfiles
|
||||
|
||||
do nsnr=ia,ib,-1
|
||||
nsync=0
|
||||
ndecodes=0
|
||||
nfalse=0
|
||||
nretcode=0
|
||||
write(cmd1(57:59),'(i3)') nsnr
|
||||
call system(cmd1)
|
||||
call sec0(0,tdec)
|
||||
call system(cmd2)
|
||||
call sec0(1,tdec)
|
||||
open(10,file='junk',status='unknown')
|
||||
n=0
|
||||
do iline=1,9999
|
||||
read(10,'(a71)',end=10) line
|
||||
if(index(line,'<Decode').eq.1) cycle
|
||||
read(line(11:20),*) xdt,nf
|
||||
irc=-1
|
||||
if(line(23:23).ne.' ') read(line(45:46),*) irc
|
||||
decok=index(line,'W9XYZ').gt.0
|
||||
if((abs(xdt-dt).le.dterr .and. abs(nf-nf0).le.nferr) .or. decok) then
|
||||
nsync=nsync+1
|
||||
endif
|
||||
if(irc.lt.0) cycle
|
||||
if(decok) then
|
||||
i=irc
|
||||
if(i.le.11) then
|
||||
ndecodes=ndecodes + 1
|
||||
else
|
||||
i=mod(i,10)
|
||||
endif
|
||||
nretcode(i)=nretcode(i) + 1
|
||||
else
|
||||
nfalse=nfalse + 1
|
||||
print*,'False: ',line
|
||||
endif
|
||||
enddo ! iline
|
||||
10 close(10)
|
||||
write(*,1100) nsnr,ndepth,fDop,nsync,ndecodes,nfalse,nretcode, &
|
||||
tdec/nfiles
|
||||
write(12,1100) nsnr,ndepth,fDop,nsync,ndecodes,nfalse,nretcode, &
|
||||
tdec/nfiles
|
||||
1100 format(i3,i2,f5.1,2i5,i4,i6,11i4,f6.2)
|
||||
if(ndecodes.lt.nfiles/2 .and. ndecodes0.ge.nfiles/2) then
|
||||
snr_thresh=nsnr + float(nfiles/2 - ndecodes)/(ndecodes0-ndecodes)
|
||||
write(13,1200) ndepth,fdop,csubmode,snr_thresh
|
||||
1200 format(i1,f6.1,2x,a1,f7.1)
|
||||
flush(13)
|
||||
endif
|
||||
flush(6)
|
||||
flush(12)
|
||||
if(ndecodes.eq.0) exit !Bail out if no decodes at this SNR
|
||||
ndecodes0=ndecodes
|
||||
enddo ! nsnr
|
||||
|
||||
999 end program test_qra64
|
||||
|
||||
include 'sec0.f90'
|
||||
|
@ -7,4 +7,12 @@ module types
|
||||
integer, parameter :: dp = REAL64
|
||||
integer, parameter :: qp = REAL128
|
||||
|
||||
type q3list
|
||||
character*6 call
|
||||
character*4 grid
|
||||
integer nsec
|
||||
integer nfreq
|
||||
integer moonel
|
||||
end type q3list
|
||||
|
||||
end module types
|
||||
|
@ -146,6 +146,7 @@ unsigned long readwavfile(char *ptr_to_infile, int ntrmin, float *idat, float *q
|
||||
nr=fread(buf2,2,npoints,fp); //Read raw data
|
||||
fclose(fp);
|
||||
if( nr == 0 ) {
|
||||
free(buf2);
|
||||
fprintf(stderr, "No data in file '%s'\n", ptr_to_infile);
|
||||
return 1;
|
||||
}
|
||||
@ -1165,7 +1166,7 @@ int main(int argc, char *argv[])
|
||||
for (k=0; k<162; k++) { //Sum over symbols
|
||||
ifd=ifr+((float)k-81.0)/81.0*( (float)idrift )/(2.0*df);
|
||||
kindex=k0+2*k;
|
||||
if( kindex < nffts ) {
|
||||
if( kindex >= 0 && kindex < nffts ) {
|
||||
p0=ps[ifd-3][kindex];
|
||||
p1=ps[ifd-1][kindex];
|
||||
p2=ps[ifd+1][kindex];
|
||||
|
@ -16,9 +16,11 @@
|
||||
#include <QTextStream>
|
||||
#include <QDebug>
|
||||
#include <QDebugStateSaver>
|
||||
#include <QRegularExpression>
|
||||
#include "Configuration.hpp"
|
||||
#include "Radio.hpp"
|
||||
#include "pimpl_impl.hpp"
|
||||
#include "Logger.hpp"
|
||||
|
||||
#include "moc_AD1CCty.cpp"
|
||||
|
||||
@ -163,6 +165,9 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
QString get_cty_path(const Configuration *configuration);
|
||||
void load_cty(QFile &file);
|
||||
|
||||
entity_by_id::iterator lookup_entity (QString call, prefix const& p) const
|
||||
{
|
||||
call = call.toUpper ();
|
||||
@ -228,6 +233,9 @@ public:
|
||||
|
||||
Configuration const * configuration_;
|
||||
QString path_;
|
||||
QString cty_version_;
|
||||
QString cty_version_date_;
|
||||
|
||||
entities_type entities_;
|
||||
prefixes_type prefixes_;
|
||||
};
|
||||
@ -314,6 +322,80 @@ char const * AD1CCty::continent (Continent c)
|
||||
}
|
||||
}
|
||||
|
||||
QString AD1CCty::impl::get_cty_path(Configuration const * configuration)
|
||||
{
|
||||
QDir dataPath {QStandardPaths::writableLocation (QStandardPaths::DataLocation)};
|
||||
auto path = dataPath.exists (file_name)
|
||||
? dataPath.absoluteFilePath (file_name) // user override
|
||||
: configuration->data_dir ().absoluteFilePath (file_name); // or original
|
||||
return path;
|
||||
}
|
||||
|
||||
void AD1CCty::impl::load_cty(QFile &file)
|
||||
{
|
||||
QRegularExpression version_pattern{R"(VER\d{8})"};
|
||||
int entity_id = 0;
|
||||
int line_number{0};
|
||||
|
||||
entities_.clear();
|
||||
prefixes_.clear();
|
||||
cty_version_ = QString{};
|
||||
cty_version_date_ = QString{};
|
||||
|
||||
QTextStream in{&file};
|
||||
while (!in.atEnd())
|
||||
{
|
||||
auto const &entity_line = in.readLine();
|
||||
++line_number;
|
||||
if (!in.atEnd())
|
||||
{
|
||||
auto const &entity_parts = entity_line.split(':');
|
||||
if (entity_parts.size() >= 8)
|
||||
{
|
||||
auto primary_prefix = entity_parts[7].trimmed();
|
||||
bool WAE_only{false};
|
||||
if (primary_prefix.startsWith('*'))
|
||||
{
|
||||
primary_prefix = primary_prefix.mid(1);
|
||||
WAE_only = true;
|
||||
}
|
||||
bool ok1, ok2, ok3, ok4, ok5;
|
||||
entities_.emplace(++entity_id, entity_parts[0].trimmed(), WAE_only, entity_parts[1].trimmed().toInt(&ok1),
|
||||
entity_parts[2].trimmed().toInt(&ok2), continent(entity_parts[3].trimmed()),
|
||||
entity_parts[4].trimmed().toFloat(&ok3), entity_parts[5].trimmed().toFloat(&ok4),
|
||||
static_cast<int> (entity_parts[6].trimmed().toFloat(&ok5) * 60 * 60), primary_prefix);
|
||||
if (!(ok1 && ok2 && ok3 && ok4 && ok5))
|
||||
{
|
||||
throw std::domain_error{"Invalid number in cty.dat line " + boost::lexical_cast<std::string>(line_number)};
|
||||
}
|
||||
QString line;
|
||||
QString detail;
|
||||
do
|
||||
{
|
||||
in.readLineInto(&line);
|
||||
++line_number;
|
||||
} while (detail += line, !detail.endsWith(';'));
|
||||
for (auto prefix: detail.left(detail.size() - 1).split(','))
|
||||
{
|
||||
prefix = prefix.trimmed();
|
||||
bool exact{false};
|
||||
if (prefix.startsWith('='))
|
||||
{
|
||||
prefix = prefix.mid(1);
|
||||
exact = true;
|
||||
// match version pattern to prefix
|
||||
if (version_pattern.match(prefix).hasMatch())
|
||||
{
|
||||
cty_version_date_ = prefix;
|
||||
}
|
||||
}
|
||||
prefixes_.emplace(prefix, exact, entity_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AD1CCty::AD1CCty (Configuration const * configuration)
|
||||
: m_ {configuration}
|
||||
{
|
||||
@ -321,69 +403,23 @@ AD1CCty::AD1CCty (Configuration const * configuration)
|
||||
// TODO: G4WJS - consider doing the following asynchronously to
|
||||
// speed up startup. Not urgent as it takes less than 0.5s on a Core
|
||||
// i7 reading BIG CTY.DAT.
|
||||
QDir dataPath {QStandardPaths::writableLocation (QStandardPaths::DataLocation)};
|
||||
m_->path_ = dataPath.exists (file_name)
|
||||
? dataPath.absoluteFilePath (file_name) // user override
|
||||
: configuration->data_dir ().absoluteFilePath (file_name); // or original
|
||||
AD1CCty::reload (configuration);
|
||||
}
|
||||
|
||||
void AD1CCty::reload(Configuration const * configuration)
|
||||
{
|
||||
m_->path_ = m_->impl::get_cty_path(configuration);
|
||||
QFile file {m_->path_};
|
||||
|
||||
LOG_INFO(QString{"Loading CTY.DAT from %1"}.arg (m_->path_));
|
||||
|
||||
if (file.open (QFile::ReadOnly))
|
||||
{
|
||||
int entity_id = 0;
|
||||
int line_number {0};
|
||||
QTextStream in {&file};
|
||||
while (!in.atEnd ())
|
||||
{
|
||||
auto const& entity_line = in.readLine ();
|
||||
++line_number;
|
||||
if (!in.atEnd ())
|
||||
{
|
||||
auto const& entity_parts = entity_line.split (':');
|
||||
if (entity_parts.size () >= 8)
|
||||
{
|
||||
auto primary_prefix = entity_parts[7].trimmed ();
|
||||
bool WAE_only {false};
|
||||
if (primary_prefix.startsWith ('*'))
|
||||
{
|
||||
primary_prefix = primary_prefix.mid (1);
|
||||
WAE_only = true;
|
||||
}
|
||||
bool ok1, ok2, ok3, ok4, ok5;
|
||||
m_->entities_.emplace (++entity_id
|
||||
, entity_parts[0].trimmed ()
|
||||
, WAE_only
|
||||
, entity_parts[1].trimmed ().toInt (&ok1)
|
||||
, entity_parts[2].trimmed ().toInt (&ok2)
|
||||
, continent (entity_parts[3].trimmed ())
|
||||
, entity_parts[4].trimmed ().toFloat (&ok3)
|
||||
, entity_parts[5].trimmed ().toFloat (&ok4)
|
||||
, static_cast<int> (entity_parts[6].trimmed ().toFloat (&ok5) * 60 * 60)
|
||||
, primary_prefix);
|
||||
if (!(ok1 && ok2 && ok3 && ok4 && ok5))
|
||||
{
|
||||
throw std::domain_error {"Invalid number in cty.dat line " + boost::lexical_cast<std::string> (line_number)};
|
||||
}
|
||||
QString line;
|
||||
QString detail;
|
||||
do
|
||||
{
|
||||
in.readLineInto (&line);
|
||||
++line_number;
|
||||
} while (detail += line, !detail.endsWith (';'));
|
||||
for (auto prefix : detail.left (detail.size () - 1).split (','))
|
||||
{
|
||||
prefix = prefix.trimmed ();
|
||||
bool exact {false};
|
||||
if (prefix.startsWith ('='))
|
||||
{
|
||||
prefix = prefix.mid (1);
|
||||
exact = true;
|
||||
}
|
||||
m_->prefixes_.emplace (prefix, exact, entity_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
m_->impl::load_cty(file);
|
||||
m_->cty_version_ = AD1CCty::lookup("VERSION").entity_name;
|
||||
Q_EMIT cty_loaded(m_->cty_version_);
|
||||
LOG_INFO(QString{"Loaded CTY.DAT version %1, %2"}.arg (m_->cty_version_date_).arg (m_->cty_version_));
|
||||
}
|
||||
}
|
||||
|
||||
AD1CCty::~AD1CCty ()
|
||||
@ -410,8 +446,8 @@ auto AD1CCty::lookup (QString const& call) const -> Record
|
||||
if (p != m_->prefixes_.end ())
|
||||
{
|
||||
impl::entity_by_id::iterator e = m_->lookup_entity (call, *p);
|
||||
if ((m_->configuration_->include_WAE_entities () || !e->WAE_only_)
|
||||
&& (!p->exact_ || call.size () == search_prefix.size ()))
|
||||
// always lookup WAE entities, we substitute them later in displaytext.cpp if "Include extra WAE entites" is not selected
|
||||
if (!p->exact_ || call.size () == search_prefix.size ())
|
||||
{
|
||||
return m_->fixup (*p, *e);
|
||||
}
|
||||
@ -421,3 +457,7 @@ auto AD1CCty::lookup (QString const& call) const -> Record
|
||||
}
|
||||
return Record {};
|
||||
}
|
||||
auto AD1CCty::version () const -> QString
|
||||
{
|
||||
return m_->cty_version_date_;
|
||||
}
|
||||
|
@ -42,8 +42,11 @@ public:
|
||||
};
|
||||
|
||||
explicit AD1CCty (Configuration const *);
|
||||
void reload(Configuration const * configuration);
|
||||
~AD1CCty ();
|
||||
Record lookup (QString const& call) const;
|
||||
QString version () const;
|
||||
Q_SIGNAL void cty_loaded (QString const& version) const;
|
||||
|
||||
private:
|
||||
class impl;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <QDateTime>
|
||||
#include "Configuration.hpp"
|
||||
#include "revision_utils.hpp"
|
||||
#include "Logger.hpp"
|
||||
#include "qt_helpers.hpp"
|
||||
#include "pimpl_impl.hpp"
|
||||
|
||||
@ -225,7 +226,7 @@ namespace
|
||||
{
|
||||
auto const logFileName = "wsjtx_log.adi";
|
||||
|
||||
// Expception class suitable for using with QtConcurrent across
|
||||
// Exception class suitable for using with QtConcurrent across
|
||||
// thread boundaries
|
||||
class LoaderException final
|
||||
: public QException
|
||||
@ -374,6 +375,7 @@ public:
|
||||
|
||||
void reload ()
|
||||
{
|
||||
prefixes_.reload (configuration_);
|
||||
async_loader_ = QtConcurrent::run (loader, path_, &prefixes_);
|
||||
loader_watcher_.setFuture (async_loader_);
|
||||
}
|
||||
@ -402,11 +404,18 @@ WorkedBefore::WorkedBefore (Configuration const * configuration)
|
||||
{
|
||||
error = e.error ();
|
||||
}
|
||||
Q_EMIT finished_loading (n, error);
|
||||
QString cty_ver = m_->prefixes_.version();
|
||||
LOG_DEBUG(QString{"WorkedBefore::reload: CTY.DAT version %1"}.arg (cty_ver));
|
||||
Q_EMIT finished_loading (n, cty_ver, error);
|
||||
});
|
||||
reload ();
|
||||
}
|
||||
|
||||
QString WorkedBefore::cty_version () const
|
||||
{
|
||||
return m_->prefixes_.version ();
|
||||
}
|
||||
|
||||
void WorkedBefore::reload ()
|
||||
{
|
||||
m_->reload ();
|
||||
@ -668,6 +677,7 @@ bool WorkedBefore::CQ_zone_worked (int CQ_zone, QString const& mode, QString con
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool WorkedBefore::ITU_zone_worked (int ITU_zone, QString const& mode, QString const& band) const
|
||||
{
|
||||
if (mode.size ())
|
||||
@ -699,3 +709,5 @@ bool WorkedBefore::ITU_zone_worked (int ITU_zone, QString const& mode, QString c
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,8 +36,9 @@ public:
|
||||
bool continent_worked (Continent continent, QString const& mode, QString const& band) const;
|
||||
bool CQ_zone_worked (int CQ_zone, QString const& mode, QString const& band) const;
|
||||
bool ITU_zone_worked (int ITU_zone, QString const& mode, QString const& band) const;
|
||||
QString cty_version () const;
|
||||
|
||||
Q_SIGNAL void finished_loading (int worked_before_record_count, QString const& error) const;
|
||||
Q_SIGNAL void finished_loading (int worked_before_record_count, QString const, QString const& error) const;
|
||||
|
||||
private:
|
||||
class impl;
|
||||
|
@ -69,6 +69,11 @@ void LogBook::rescan ()
|
||||
worked_before_.reload ();
|
||||
}
|
||||
|
||||
QString const LogBook::cty_version() const
|
||||
{
|
||||
return worked_before_.cty_version();
|
||||
}
|
||||
|
||||
QByteArray LogBook::QSOToADIF (QString const& hisCall, QString const& hisGrid, QString const& mode,
|
||||
QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn,
|
||||
QDateTime const& dateTimeOff, QString const& band, QString const& comments,
|
||||
@ -96,7 +101,7 @@ QByteArray LogBook::QSOToADIF (QString const& hisCall, QString const& hisGrid, Q
|
||||
t += " <band:" + QString::number(band.size()) + ">" + band;
|
||||
t += " <freq:" + QString::number(strDialFreq.size()) + ">" + strDialFreq;
|
||||
t += " <station_callsign:" + QString::number(myCall.size()) + ">" + myCall;
|
||||
t += " <my_gridsquare:" + QString::number(myGrid.size()) + ">" + myGrid;
|
||||
if(myGrid!="") t += " <my_gridsquare:" + QString::number(myGrid.size()) + ">" + myGrid;
|
||||
if(txPower!="") t += " <tx_pwr:" + QString::number(txPower.size()) + ">" + txPower;
|
||||
if(comments!="") t += " <comment:" + QString::number(comments.size()) + ">" + comments;
|
||||
if(name!="") t += " <name:" + QString::number(name.size()) + ">" + name;
|
||||
|
@ -46,7 +46,9 @@ public:
|
||||
QString const& m_myGrid, QString const& m_txPower, QString const& operator_call,
|
||||
QString const& xSent, QString const& xRcvd, QString const& propmode);
|
||||
|
||||
Q_SIGNAL void finished_loading (int worked_before_record_count, QString const& error) const;
|
||||
QString const cty_version() const;
|
||||
|
||||
Q_SIGNAL void finished_loading (int worked_before_record_count, QString const cty_version, QString const& error) const;
|
||||
|
||||
CabrilloLog * contest_log ();
|
||||
Multiplier const * multiplier () const;
|
||||
|
@ -63,13 +63,14 @@ void Astro::astroUpdate(QDateTime t, QString mygrid, QString hisgrid,
|
||||
int isec=sec;
|
||||
double uth=nhr + nmin/60.0 + sec/3600.0;
|
||||
int nfreq=(int)datcom_.fcenter;
|
||||
if(nfreq<10 or nfreq > 50000) nfreq=144;
|
||||
// if(nfreq<10 or nfreq > 50000) nfreq=144;
|
||||
|
||||
astrosub_(&nyear, &month, &nday, &uth, &nfreq, mygrid.toLatin1(),
|
||||
hisgrid.toLatin1(), &azsun, &elsun, &azmoon, &elmoon,
|
||||
&azmoondx, &elmoondx, &ntsky, &ndop, &ndop00,&ramoon, &decmoon,
|
||||
&dgrd, &poloffset, &xnr, 6, 6);
|
||||
|
||||
datcom_.nfast=ndop00; //Send self Doppler to decoder, via datcom
|
||||
sprintf(cc,
|
||||
"Az: %6.1f\n"
|
||||
"El: %6.1f\n"
|
||||
|
381
map65/astro.ui
381
map65/astro.ui
@ -7,242 +7,177 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>441</width>
|
||||
<height>483</height>
|
||||
<height>503</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<widget class="QGroupBox" name="gbPointing">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>269</x>
|
||||
<y>19</y>
|
||||
<width>151</width>
|
||||
<height>431</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string/>
|
||||
</property>
|
||||
<widget class="QRadioButton" name="rb1">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>100</y>
|
||||
<width>30</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="rb2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>60</x>
|
||||
<y>100</y>
|
||||
<width>40</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>2, 5</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="rb3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>110</x>
|
||||
<y>100</y>
|
||||
<width>30</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>3</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="rb4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>60</x>
|
||||
<y>150</y>
|
||||
<width>30</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>4</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="rb6">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>60</x>
|
||||
<y>50</y>
|
||||
<width>30</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>6</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QDoubleSpinBox" name="sbOffset">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>230</y>
|
||||
<width>130</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Offset </string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> deg</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.500000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>20.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.500000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>2.500000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="cbAutoCycle">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>330</y>
|
||||
<width>91</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Auto Cycle</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="cbOnOff">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>380</y>
|
||||
<width>70</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>On Off</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QSpinBox" name="sbDwell">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>280</y>
|
||||
<width>130</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> s</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Dwell </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>300</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>10</y>
|
||||
<width>258</width>
|
||||
<height>471</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="astroTextBrowser">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Courier New</family>
|
||||
<pointsize>20</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbPointingTests">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="astroTextBrowser">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Courier New</family>
|
||||
<pointsize>20</pointsize>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbPointingTests">
|
||||
<property name="text">
|
||||
<string>Pointing Tests</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QGroupBox" name="gbPointing">
|
||||
<property name="title">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="QRadioButton" name="rb6">
|
||||
<property name="text">
|
||||
<string>Pointing Tests</string>
|
||||
<string>6</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<item row="1" column="0">
|
||||
<widget class="QRadioButton" name="rb1">
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QRadioButton" name="rb2">
|
||||
<property name="text">
|
||||
<string>2, 5</string>
|
||||
</property>
|
||||
</spacer>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QRadioButton" name="rb3">
|
||||
<property name="text">
|
||||
<string>3</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QRadioButton" name="rb4">
|
||||
<property name="text">
|
||||
<string>4</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="3">
|
||||
<widget class="QDoubleSpinBox" name="sbOffset">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Offset </string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> deg</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.500000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>20.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.500000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>2.500000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="3">
|
||||
<widget class="QSpinBox" name="sbDwell">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> s</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Dwell </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>300</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="3">
|
||||
<widget class="QCheckBox" name="cbAutoCycle">
|
||||
<property name="text">
|
||||
<string>Auto Cycle</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="cbOnOff">
|
||||
<property name="text">
|
||||
<string>On Off</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
3229
map65/devsetup.ui
3229
map65/devsetup.ui
File diff suppressed because it is too large
Load Diff
@ -12,3 +12,15 @@ subroutine astrosub(nyear,month,nday,uth8,nfreq,mygrid,hisgrid, &
|
||||
|
||||
return
|
||||
end subroutine astrosub
|
||||
|
||||
subroutine astrosub00(nyear,month,nday,uth8,nfreq,mygrid,ndop00)
|
||||
|
||||
implicit real*8 (a-h,o-z)
|
||||
character*6 mygrid
|
||||
|
||||
call astrosub(nyear,month,nday,uth8,nfreq,mygrid,mygrid, &
|
||||
AzSun8,ElSun8,AzMoon8,ElMoon8,AzMoonB8,ElMoonB8,ntsky,ndop,ndop00, &
|
||||
RAMoon8,DecMoon8,Dgrd8,poloffset8,xnr8)
|
||||
|
||||
return
|
||||
end subroutine astrosub00
|
||||
|
@ -12,7 +12,7 @@ subroutine decode0(dd,ss,savg,nstandalone)
|
||||
common/npar/fcenter,nutc,idphi,mousedf,mousefqso,nagain, &
|
||||
ndepth,ndiskdat,neme,newdat,nfa,nfb,nfcal,nfshift, &
|
||||
mcall3,nkeep,ntol,nxant,nrxlog,nfsample,nxpol,nmode, &
|
||||
nfast,nsave,max_drift,nhsym,mycall,mygrid,hiscall,hisgrid,datetime
|
||||
ndop00,nsave,max_drift,nhsym,mycall,mygrid,hiscall,hisgrid,datetime
|
||||
common/early/nhsym1,nhsym2,ldecoded(32768)
|
||||
common/decodes/ndecodes
|
||||
data neme0/-99/,mcall3b/1/
|
||||
@ -56,7 +56,7 @@ subroutine decode0(dd,ss,savg,nstandalone)
|
||||
mousedf,mousefqso,nagain,ndecdone,nfshift,ndphi,max_drift, &
|
||||
nfcal,nkeep,mcall3b,nsum,nsave,nxant,mycall,mygrid, &
|
||||
neme,ndepth,nstandalone,hiscall,hisgrid,nhsym,nfsample, &
|
||||
ndiskdat,nxpol,nmode)
|
||||
ndiskdat,nxpol,nmode,ndop00)
|
||||
call timer('map65a ',1)
|
||||
call timer('decode0 ',1)
|
||||
|
||||
|
@ -10,6 +10,7 @@ subroutine ftninit(appd)
|
||||
|
||||
addpfx=' '
|
||||
call pfxdump(appd//'/prefixes.txt')
|
||||
open(12,file=appd//'/wb_q65.txt',status='unknown')
|
||||
open(13,file=appd//'/map65.log',status='unknown')
|
||||
open(19,file=appd//'/livecq.txt',status='unknown')
|
||||
open(21,file=appd//'/map65_rx.log',status='unknown',access='append',err=950)
|
||||
|
@ -7,9 +7,9 @@ program m65
|
||||
!
|
||||
! 10 binary input data, *.tf2 files
|
||||
! 11 prefixes.txt
|
||||
! 12
|
||||
! 12 wb_w65.txt
|
||||
! 13 map65.log
|
||||
! 14
|
||||
! 14
|
||||
! 15
|
||||
! 16 tquick log
|
||||
! 17 saved *.tf2 files
|
||||
@ -41,7 +41,7 @@ program m65
|
||||
common/npar/fcenter,nutc,idphi,mousedf,mousefqso,nagain, &
|
||||
ndepth,ndiskdat,neme,newdat,nfa,nfb,nfcal,nfshift, &
|
||||
mcall3,nkeep,ntol,nxant,nrxlog,nfsample,nxpol,nmode, &
|
||||
nfast,nsave,max_drift,nhsym,mycall,mygrid,hiscall,hisgrid,datetime
|
||||
ndop00,nsave,max_drift,nhsym,mycall,mygrid,hiscall,hisgrid,datetime
|
||||
common/early/nhsym1,nhsym2,ldecoded(32768)
|
||||
|
||||
nargs=iargc()
|
||||
|
@ -82,7 +82,7 @@ subroutine m65c(dd,ss,savg,nparams0)
|
||||
common/npar/fcenter,nutc,idphi,mousedf,mousefqso,nagain, &
|
||||
ndepth,ndiskdat,neme,newdat,nfa,nfb,nfcal,nfshift, &
|
||||
mcall3,nkeep,ntol,nxant,nrxlog,nfsample,nxpol,nmode, &
|
||||
nfast,nsave,max_drift,nhsym,mycall,mygrid,hiscall,hisgrid, &
|
||||
ndop00,nsave,max_drift,nhsym,mycall,mygrid,hiscall,hisgrid, &
|
||||
datetime,junk1,junk2
|
||||
common/early/nhsym1,nhsym2,ldecoded(32768)
|
||||
equivalence (nparams,fcenter)
|
||||
|
@ -2,7 +2,7 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
mousedf,mousefqso,nagain,ndecdone,nfshift,ndphi,max_drift, &
|
||||
nfcal,nkeep,mcall3b,nsum,nsave,nxant,mycall,mygrid, &
|
||||
neme,ndepth,nstandalone,hiscall,hisgrid,nhsym,nfsample, &
|
||||
ndiskdat,nxpol,nmode)
|
||||
ndiskdat,nxpol,nmode,ndop00)
|
||||
|
||||
! Processes timf2 data from Linrad to find and decode JT65 signals.
|
||||
|
||||
@ -41,6 +41,7 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
data nfile/0/,nutc0/-999/,nid/0/,ip000/1/,ip001/1/,mousefqso0/-999/
|
||||
save
|
||||
|
||||
rewind 12
|
||||
ndecodes=0
|
||||
|
||||
! Clean start for Q65 at early decode
|
||||
@ -68,11 +69,11 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
endif
|
||||
!###
|
||||
! do k=1,ncand
|
||||
! freq=cand(k)%f+nkhz_center-48.0-1.27046
|
||||
! freq=cand(k)%f+nkhz_center-48.0
|
||||
! ipk=cand(k)%indx
|
||||
! write(*,3010) nutc,k,db(cand(k)%snr),freq,cand(k)%xdt, &
|
||||
! write(71,3071) k,db(cand(k)%snr),freq,cand(k)%xdt, &
|
||||
! cand(k)%ipol,cand(k)%iflip,ipk,ldecoded(ipk)
|
||||
!3010 format('=a',i5.4,i5,f8.2,f10.3,f8.2,2i3,i6,L4)
|
||||
!3071 format(i3,f8.2,f10.3,f8.2,2i3,i6,L4)
|
||||
! enddo
|
||||
!###
|
||||
|
||||
@ -365,7 +366,7 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
call timer('q65b ',0)
|
||||
call q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf, &
|
||||
ntol,xpol,mycall,mygrid, hiscall,hisgrid,mode_q65,f0,fqso, &
|
||||
newdat,nagain,max_drift,nhsym,idec)
|
||||
newdat,nagain,max_drift,nhsym,ndop00,idec)
|
||||
call timer('q65b ',1)
|
||||
if(idec.ge.0) candec(icand)=.true.
|
||||
enddo
|
||||
@ -376,7 +377,7 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
call timer('q65b ',0)
|
||||
call q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf, &
|
||||
ntol,xpol,mycall,mygrid,hiscall,hisgrid,mode_q65,f0,fqso, &
|
||||
newdat,nagain,max_drift,nhsym,idec)
|
||||
newdat,nagain,max_drift,nhsym,ndop00,idec)
|
||||
call timer('q65b ',1)
|
||||
endif
|
||||
endif
|
||||
@ -420,7 +421,7 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
call timer('q65b ',0)
|
||||
call q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf,ntol, &
|
||||
xpol,mycall,mygrid,hiscall,hisgrid,mode_q65,f0,fqso,newdat, &
|
||||
nagain,max_drift,nhsym,idec)
|
||||
nagain,max_drift,nhsym,ndop00,idec)
|
||||
call timer('q65b ',1)
|
||||
if(idec.ge.0) candec(icand)=.true.
|
||||
enddo ! icand
|
||||
@ -520,6 +521,7 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, &
|
||||
ndecdone=2
|
||||
|
||||
900 close(23)
|
||||
call flush(12)
|
||||
ndphi=0
|
||||
mcall3b=mcall3a
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
subroutine q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, &
|
||||
mycall0,mygrid,hiscall0,hisgrid,mode_q65,f0,fqso,newdat,nagain, &
|
||||
max_drift,nhsym,idec)
|
||||
max_drift,nhsym,ndop00,idec)
|
||||
|
||||
! This routine provides an interface between MAP65 and the Q65 decoder
|
||||
! in WSJT-X. All arguments are input data obtained from the MAP65 GUI.
|
||||
@ -137,10 +137,11 @@ subroutine q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, &
|
||||
nfb=min(2500,1000+ntol)
|
||||
endif
|
||||
nsnr0=-99 !Default snr for no decode
|
||||
ndpth=3
|
||||
|
||||
! NB: Frequency of ipk is now shifted to 1000 Hz.
|
||||
call map65_mmdec(nutc,iwave,nqd,nsubmode,nfa,nfb,1000,ntol, &
|
||||
newdat,nagain,max_drift,mycall,hiscall,hisgrid)
|
||||
call map65_mmdec(nutc,iwave,nqd,60,nsubmode,nfa,nfb,1000,ntol, &
|
||||
newdat,nagain,max_drift,ndepth,mycall,hiscall0,hisgrid)
|
||||
|
||||
MHz=fcenter
|
||||
freq0=MHz + 0.001d0*ikhz
|
||||
@ -181,11 +182,16 @@ subroutine q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, &
|
||||
if(nutc.ne.nutc00 .or. msg0(1:28).ne.msg00 .or. freq1.ne.freq1_00) then
|
||||
! Write to file map65_rx.log:
|
||||
ndecodes=ndecodes+1
|
||||
write(21,1110) freq1,ndf,xdt0,npol,nsnr0,nutc,msg0(1:28),cq0
|
||||
1110 format(f8.3,i5,f5.1,2i4,i5.4,2x,a28,': A',2x,a3)
|
||||
write(21,1110) freq1,ndf,xdt0,npol,nsnr0,nutc,msg0(1:28), &
|
||||
cmode(2:2),cq0
|
||||
1110 format(f8.3,i5,f5.1,2i4,i5.4,2x,a28,': ',a1,2x,a3)
|
||||
nutc00=nutc
|
||||
msg00=msg0(1:28)
|
||||
freq1_00=freq1
|
||||
frx=0.001*k0*df+nkhz_center-48.0+1.0 - 0.001*nfcal
|
||||
fsked=frx - 0.001*ndop00/2.0 - 1.5
|
||||
write(12,1120) nutc,fsked,xdt0,nsnr0,trim(msg0)
|
||||
1120 format(i4.4,f9.3,f7.2,i5,2x,a,i6)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -41,7 +41,7 @@ subroutine get_candidates(ss,savg,xpol,jz,nfa,nfb,nts_jt65,nts_q65,cand,ncand)
|
||||
type(candidate) :: cand(MAX_CANDIDATES)
|
||||
common/early/nhsym1,nhsym2,ldecoded(32768)
|
||||
|
||||
call wb_sync(ss,savg,xpol,jz,nfa,nfb)
|
||||
call wb_sync(ss,savg,xpol,jz,nfa,nfb) !Output to sync() array
|
||||
|
||||
tstep=2048.0/11025.0 !0.185760 s: 0.5*tsym_jt65, 0.3096*tsym_q65
|
||||
df3=96000.0/NFFT
|
||||
@ -89,8 +89,6 @@ subroutine get_candidates(ss,savg,xpol,jz,nfa,nfb,nts_jt65,nts_q65,cand,ncand)
|
||||
if(diffhz.gt.-0.03*bw .and. diffhz.lt.1.03*bw) skip=.true.
|
||||
enddo
|
||||
if(skip) cycle
|
||||
! write(*,3301) i,k,m,f0,diffhz,bw,db(snr1)
|
||||
!3301 format('=A',3i5,f8.3,2f8.0,f8.2)
|
||||
k=k+1
|
||||
cand(k)%snr=snr1
|
||||
cand(k)%f=f0
|
||||
@ -99,6 +97,8 @@ subroutine get_candidates(ss,savg,xpol,jz,nfa,nfb,nts_jt65,nts_q65,cand,ncand)
|
||||
cand(k)%ipol=sync(n)%ipol
|
||||
cand(k)%iflip=nint(flip)
|
||||
cand(k)%indx=n
|
||||
! write(50,3050) i,k,m,f0+32.0,diffhz,bw,snr1,db(snr1)
|
||||
!3050 format(3i5,f8.3,2f8.0,2f8.2)
|
||||
if(k.ge.MAX_CANDIDATES) exit
|
||||
enddo
|
||||
ncand=k
|
||||
@ -251,15 +251,30 @@ subroutine wb_sync(ss,savg,xpol,jz,nfa,nfb)
|
||||
|
||||
enddo ! i (frequency bin)
|
||||
|
||||
! do i=ia,ib
|
||||
! write(15,3015) 0.001*(i-1)*df3,sync(i)%ccfmax,sync(i)%xdt,sync(i)%ipol, &
|
||||
! sync(i)%iflip,sync(i)%birdie
|
||||
!3015 format(3f10.3,2i6,L5)
|
||||
! enddo
|
||||
|
||||
call pctile(sync(ia:ib)%ccfmax,ib-ia+1,50,base)
|
||||
sync(ia:ib)%ccfmax=sync(ia:ib)%ccfmax/base
|
||||
|
||||
bw=65*4*1.66666667 !Q65-60C bandwidth
|
||||
nbw=bw/df3 + 1 !Number of bins to blank
|
||||
syncmin=2.0
|
||||
nguard=10
|
||||
do i=ia,ib
|
||||
if(sync(i)%ccfmax.lt.syncmin) cycle
|
||||
spk=maxval(sync(i:i+nbw)%ccfmax)
|
||||
ip =maxloc(sync(i:i+nbw)%ccfmax)
|
||||
i0=ip(1)+i-1
|
||||
ja=min(i,i0-nguard)
|
||||
jb=i0+nbw+nguard
|
||||
sync(ja:jb)%ccfmax=0.
|
||||
sync(i0)%ccfmax=spk
|
||||
enddo
|
||||
|
||||
! do i=ia,ib
|
||||
! write(15,3015) 0.001*(i-1)*df3+32.0,sync(i)%ccfmax,sync(i)%xdt, &
|
||||
! sync(i)%ipol,sync(i)%iflip,sync(i)%birdie
|
||||
!3015 format(3f10.3,2i6,L5)
|
||||
! enddo
|
||||
|
||||
return
|
||||
end subroutine wb_sync
|
||||
|
||||
|
@ -1293,7 +1293,25 @@ void MainWindow::decode() //decode()
|
||||
datcom_.mousefqso=m_wide_graph_window->QSOfreq();
|
||||
datcom_.ndepth=m_ndepth;
|
||||
datcom_.ndiskdat=0;
|
||||
if(m_diskData) datcom_.ndiskdat=1;
|
||||
if(m_diskData) {
|
||||
datcom_.ndiskdat=1;
|
||||
int i0=m_path.indexOf(".tf2");
|
||||
if(i0<0) i0=m_path.indexOf(".iq");
|
||||
if(i0>0) {
|
||||
// Compute self Doppler using the filename for Date and Time
|
||||
int nyear=m_path.mid(i0-11,2).toInt()+2000;
|
||||
int month=m_path.mid(i0-9,2).toInt();
|
||||
int nday=m_path.mid(i0-7,2).toInt();
|
||||
int nhr=m_path.mid(i0-4,2).toInt();
|
||||
int nmin=m_path.mid(i0-2,2).toInt();
|
||||
double uth=nhr + nmin/60.0;
|
||||
int nfreq=(int)datcom_.fcenter;
|
||||
int ndop00;
|
||||
|
||||
astrosub00_(&nyear, &month, &nday, &uth, &nfreq, m_myGrid.toLatin1(),&ndop00,6);
|
||||
datcom_.nfast=ndop00; //Send self Doppler to decoder, via datcom
|
||||
}
|
||||
}
|
||||
datcom_.neme=0;
|
||||
if(ui->actionOnly_EME_calls->isChecked()) datcom_.neme=1;
|
||||
|
||||
@ -1322,7 +1340,7 @@ void MainWindow::decode() //decode()
|
||||
datcom_.nxpol=0;
|
||||
if(m_xpol) datcom_.nxpol=1;
|
||||
datcom_.nmode=10*m_modeQ65 + m_modeJT65;
|
||||
datcom_.nfast=1; //No longer used
|
||||
// datcom_.nfast=1; //No longer used
|
||||
datcom_.nsave=m_nsave;
|
||||
datcom_.max_drift=ui->sbMaxDrift->value();
|
||||
|
||||
|
@ -322,6 +322,9 @@ extern "C" {
|
||||
int len1, int len2);
|
||||
|
||||
int ptt_(int* nport, int* itx, int* iptt);
|
||||
|
||||
void astrosub00_ (int* nyear, int* month, int* nday, double* uth, int* nfreq,
|
||||
const char* mygrid, int* ndop00, int len1);
|
||||
}
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>635</width>
|
||||
<height>523</height>
|
||||
<width>902</width>
|
||||
<height>560</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@ -54,7 +54,7 @@
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>620</width>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -65,7 +65,7 @@
|
||||
<item>
|
||||
<widget class="DisplayText" name="decodedTextBrowser">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Expanding">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@ -78,8 +78,8 @@
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>610</width>
|
||||
<height>400</height>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
@ -229,9 +229,27 @@ p, li { white-space: pre-wrap; }
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5" stretch="0,0,1,0,0,1">
|
||||
<item>
|
||||
<widget class="QFrame" name="xMeterFrame">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>65</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
@ -242,6 +260,18 @@ p, li { white-space: pre-wrap; }
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="yMeterFrame">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>65</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
@ -262,13 +292,13 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>164</width>
|
||||
<height>40</height>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>290</width>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -276,181 +306,252 @@ p, li { white-space: pre-wrap; }
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string> DX Call DX Grid </string>
|
||||
<string/>
|
||||
</property>
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>231</x>
|
||||
<y>13</y>
|
||||
<width>50</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>SetMsgs</string>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QWidget" name="layoutWidget_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>7</x>
|
||||
<y>13</y>
|
||||
<width>150</width>
|
||||
<height>64</height>
|
||||
</rect>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="dxCallEntry">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>23</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="dxGridEntry">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>23</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QPushButton" name="lookupButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Lookup</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="addButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="genStdMsgsPushButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>80</y>
|
||||
<width>90</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>90</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&GenStdMsgs</string>
|
||||
</property>
|
||||
</widget>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="dxCallEntry">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>23</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="dxGridEntry">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>23</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="lookupButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Lookup</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="addButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="genStdMsgsPushButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&GenStdMsgs</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="DX_Grid_label">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">border-width: 0;</string>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="midLineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><html><head/><body><p align="center">DX Grid</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="DX_Call_label">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">border-width: 0;</string>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="midLineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>DX Call</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item alignment="Qt::AlignHCenter">
|
||||
<widget class="QLabel" name="labUTC">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
@ -735,20 +836,20 @@ p, li { white-space: pre-wrap; }
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9" stretch="1,0,0">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="tx1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>160</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>180</width>
|
||||
<width>100</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -765,14 +866,14 @@ p, li { white-space: pre-wrap; }
|
||||
<item>
|
||||
<widget class="QLineEdit" name="tx2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>160</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>180</width>
|
||||
<width>100</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -781,14 +882,14 @@ p, li { white-space: pre-wrap; }
|
||||
<item>
|
||||
<widget class="QLineEdit" name="tx3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>160</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>180</width>
|
||||
<width>100</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -797,14 +898,14 @@ p, li { white-space: pre-wrap; }
|
||||
<item>
|
||||
<widget class="QLineEdit" name="tx4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>160</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>180</width>
|
||||
<width>100</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -813,14 +914,14 @@ p, li { white-space: pre-wrap; }
|
||||
<item>
|
||||
<widget class="QLineEdit" name="tx5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>160</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>180</width>
|
||||
<width>100</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -829,14 +930,14 @@ p, li { white-space: pre-wrap; }
|
||||
<item>
|
||||
<widget class="QLineEdit" name="tx6">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>160</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>180</width>
|
||||
<width>100</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -849,7 +950,7 @@ p, li { white-space: pre-wrap; }
|
||||
<item>
|
||||
<widget class="QRadioButton" name="txrb1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>16</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@ -862,7 +963,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<width>30</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -880,7 +981,7 @@ p, li { white-space: pre-wrap; }
|
||||
<item>
|
||||
<widget class="QRadioButton" name="txrb2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>16</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@ -893,7 +994,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<width>30</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -908,7 +1009,7 @@ p, li { white-space: pre-wrap; }
|
||||
<item>
|
||||
<widget class="QRadioButton" name="txrb3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>16</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@ -921,7 +1022,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<width>30</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -936,7 +1037,7 @@ p, li { white-space: pre-wrap; }
|
||||
<item>
|
||||
<widget class="QRadioButton" name="txrb4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>16</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@ -949,7 +1050,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<width>30</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -964,7 +1065,7 @@ p, li { white-space: pre-wrap; }
|
||||
<item>
|
||||
<widget class="QRadioButton" name="txrb5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>16</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@ -977,7 +1078,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<width>30</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -992,7 +1093,7 @@ p, li { white-space: pre-wrap; }
|
||||
<item>
|
||||
<widget class="QRadioButton" name="txrb6">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>16</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@ -1005,7 +1106,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<width>30</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -1037,7 +1138,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>29</width>
|
||||
<width>35</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -1056,7 +1157,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>29</width>
|
||||
<width>35</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -1075,7 +1176,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>29</width>
|
||||
<width>35</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -1094,7 +1195,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>29</width>
|
||||
<width>35</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -1113,7 +1214,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>29</width>
|
||||
<width>35</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -1132,7 +1233,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>29</width>
|
||||
<width>35</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -1156,8 +1257,8 @@ p, li { white-space: pre-wrap; }
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>635</width>
|
||||
<height>21</height>
|
||||
<width>902</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
@ -1291,7 +1392,7 @@ p, li { white-space: pre-wrap; }
|
||||
</action>
|
||||
<action name="actionAbout">
|
||||
<property name="text">
|
||||
<string> About MAP65</string>
|
||||
<string>About MAP65</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+F1</string>
|
||||
|
@ -776,7 +776,7 @@ void CPlotter::mouseMoveEvent (QMouseEvent * event)
|
||||
if(lower) {
|
||||
QToolTip::showText(event->globalPos(),QString::number(ndf));
|
||||
} else {
|
||||
QToolTip::showText(event->globalPos(),QString::number(freq));
|
||||
QToolTip::showText(event->globalPos(),QString::number(freq,'f',3));
|
||||
}
|
||||
QWidget::mouseMoveEvent(event);
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <QSqlQuery>
|
||||
#include <QTextStream>
|
||||
#include <QDebug>
|
||||
#include "Logger.hpp"
|
||||
#include "Configuration.hpp"
|
||||
#include "qt_db_helpers.hpp"
|
||||
#include "pimpl_impl.hpp"
|
||||
@ -37,6 +38,10 @@ public:
|
||||
Configuration const * configuration_;
|
||||
QSqlQuery mutable dupe_query_;
|
||||
QSqlQuery mutable export_query_;
|
||||
// queries for rates
|
||||
QSqlQuery mutable rate_n_query_;
|
||||
QSqlQuery mutable rate60m_query_;
|
||||
QString rate();
|
||||
};
|
||||
|
||||
#include "FoxLog.moc"
|
||||
@ -118,6 +123,25 @@ FoxLog::impl::impl (Configuration const * configuration)
|
||||
" ORDER BY "
|
||||
" \"when\"");
|
||||
|
||||
SQL_error_check (rate_n_query_, &QSqlQuery::prepare,
|
||||
"SELECT "
|
||||
" \"when\""
|
||||
" FROM "
|
||||
" fox_log "
|
||||
" ORDER BY "
|
||||
" \"when\" DESC"
|
||||
" LIMIT :limitn"
|
||||
);
|
||||
|
||||
SQL_error_check (rate60m_query_, &QSqlQuery::prepare,
|
||||
"SELECT "
|
||||
" COUNT() "
|
||||
" FROM "
|
||||
" fox_log "
|
||||
" where \"when\" > :one_hour_ago"
|
||||
" ORDER BY "
|
||||
" \"when\" DESC"
|
||||
);
|
||||
setEditStrategy (QSqlTableModel::OnFieldChange);
|
||||
setTable ("fox_log");
|
||||
setHeaderData (fieldIndex ("when"), Qt::Horizontal, tr ("Date & Time(UTC)"));
|
||||
@ -135,6 +159,13 @@ FoxLog::impl::impl (Configuration const * configuration)
|
||||
SQL_error_check (*this, &QSqlTableModel::select);
|
||||
}
|
||||
|
||||
QString FoxLog::rate()
|
||||
{
|
||||
return QString("Last 10: %1, Last 100: %2, Last 60m: %3").arg(QString::number(this->rate_last_n(10),'f',0),
|
||||
QString::number(this->rate_last_n(100),'f',0),
|
||||
QString::number(this->rate_60m()));
|
||||
}
|
||||
|
||||
FoxLog::FoxLog (Configuration const * configuration)
|
||||
: m_ {configuration}
|
||||
{
|
||||
@ -221,6 +252,47 @@ void FoxLog::reset ()
|
||||
}
|
||||
}
|
||||
|
||||
int FoxLog::rate_60m()
|
||||
{
|
||||
int rate60m = 0;
|
||||
qlonglong const& one_hour_ago = QDateTime::currentDateTime().addSecs(-3600).toMSecsSinceEpoch () / 1000;
|
||||
|
||||
// query the 60m rate
|
||||
m_->rate60m_query_.bindValue (":one_hour_ago", one_hour_ago);
|
||||
SQL_error_check (m_->rate60m_query_, static_cast<bool (QSqlQuery::*) ()> (&QSqlQuery::exec));
|
||||
m_->rate60m_query_.next ();
|
||||
rate60m = m_->rate60m_query_.value (0).toLongLong();
|
||||
return rate60m;
|
||||
//
|
||||
}
|
||||
|
||||
double FoxLog::rate_last_n(int n)
|
||||
{
|
||||
double rate_interval = 0;
|
||||
|
||||
qlonglong const& secs_now = QDateTime::currentDateTime().toMSecsSinceEpoch () / 1000;
|
||||
|
||||
// get last n or up to n
|
||||
m_->rate_n_query_.bindValue (":limitn", n);
|
||||
SQL_error_check (m_->rate_n_query_, static_cast<bool (QSqlQuery::*) ()> (&QSqlQuery::exec));
|
||||
|
||||
m_->rate_n_query_.next();
|
||||
if (!m_->rate_n_query_.isValid()) {
|
||||
LOG_ERROR(QString("rate_n result is not valid. Last error %1").arg(m_->rate_n_query_.lastError().text()));
|
||||
return 0.0;
|
||||
}
|
||||
// size / (time_now - time_of_first)
|
||||
m_->rate_n_query_.last();
|
||||
rate_interval = secs_now - m_->rate_n_query_.value (0).toLongLong ();
|
||||
if (rate_interval == 0) return 0.0;
|
||||
|
||||
m_->rate_n_query_.first(); // count the records
|
||||
|
||||
int size = 1;
|
||||
while (m_->rate_n_query_.next() && m_->rate_n_query_.isValid()) size++;
|
||||
return (size/rate_interval) * 3600;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
struct ADIF_field
|
||||
|
@ -26,6 +26,9 @@ public:
|
||||
QSqlTableModel * model ();
|
||||
void reset ();
|
||||
void export_qsos (QTextStream&) const;
|
||||
QString rate();
|
||||
double rate_last_n(int n); // get the rate for the last n
|
||||
int rate_60m();
|
||||
|
||||
private:
|
||||
class impl;
|
||||
|
@ -659,7 +659,7 @@ QModelIndex FrequencyList_v2_101::impl::add (Item f)
|
||||
endInsertRows ();
|
||||
|
||||
// if we added one that had a preferred frequency, unprefer everything else
|
||||
unprefer_all_but(f, row, {Qt::DisplayRole, Qt::CheckStateRole});
|
||||
if (f.preferred_) unprefer_all_but(f, row, {Qt::DisplayRole, Qt::CheckStateRole});
|
||||
|
||||
return index (row, 0);
|
||||
}
|
||||
@ -1335,8 +1335,10 @@ FrequencyList_v2_101::FrequencyItems FrequencyList_v2_101::from_json_file(QFile
|
||||
{
|
||||
throw ReadFileException{tr ("No Frequencies were found")};
|
||||
}
|
||||
#ifdef DUMP_ENTRY_COUNTS
|
||||
int valid_entry_count = 0;
|
||||
int skipped_entry_count = 0;
|
||||
#endif
|
||||
for (auto const &item: arr)
|
||||
{
|
||||
QString mode_s, region_s;
|
||||
@ -1359,13 +1361,21 @@ FrequencyList_v2_101::FrequencyItems FrequencyList_v2_101::from_json_file(QFile
|
||||
freq.isSane())
|
||||
{
|
||||
list.push_back(freq);
|
||||
#ifdef DUMP_ENTRY_COUNTS
|
||||
valid_entry_count++;
|
||||
} else
|
||||
#endif
|
||||
} else {
|
||||
#ifdef DUMP_ENTRY_COUNTS
|
||||
skipped_entry_count++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
//MessageBox::information_message(this, tr("Loaded Frequencies from %1").arg(file_name),
|
||||
// tr("Entries Valid/Skipped %1").arg(QString::number(valid_entry_count) + "/" +
|
||||
// QString::number(skipped_entry_count)));
|
||||
|
||||
#ifdef DUMP_ENTRY_COUNTS
|
||||
MessageBox::information_message(this, tr("Loaded Frequencies from %1").arg(file_name),
|
||||
tr("Entries Valid/Skipped %1").arg(QString::number(valid_entry_count) + "/" +
|
||||
QString::number(skipped_entry_count)));
|
||||
#endif
|
||||
return list;
|
||||
}
|
||||
// write JSON format to a file
|
||||
|
1
qmap/.gitignore
vendored
Normal file
1
qmap/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
~*
|
65
qmap/CMakeLists.txt
Normal file
65
qmap/CMakeLists.txt
Normal file
@ -0,0 +1,65 @@
|
||||
set (qmap_CXXSRCS
|
||||
about.cpp
|
||||
astro.cpp
|
||||
devsetup.cpp
|
||||
displaytext.cpp
|
||||
getfile.cpp
|
||||
main.cpp
|
||||
mainwindow.cpp
|
||||
meterwidget.cpp
|
||||
plotter.cpp
|
||||
signalmeter.cpp
|
||||
soundin.cpp
|
||||
widegraph.cpp
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
set (qmap_CXXSRCS ${qmap_CXXSRCS})
|
||||
endif (WIN32)
|
||||
|
||||
set (qmap_UISRCS
|
||||
about.ui
|
||||
astro.ui
|
||||
devsetup.ui
|
||||
mainwindow.ui
|
||||
widegraph.ui
|
||||
)
|
||||
|
||||
set (qmap_C_and_CXXSRCS
|
||||
${qmap_CSRCS}
|
||||
${qmap_CXXSRCS}
|
||||
)
|
||||
set_property (SOURCE ${qmap_C_and_CXXSRCS} APPEND_STRING PROPERTY COMPILE_FLAGS " -include wsjtx_config.h")
|
||||
set_property (SOURCE ${qmap_C_and_CXXSRCS} APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_BINARY_DIR}/wsjtx_config.h)
|
||||
|
||||
# build the subdirectories
|
||||
add_subdirectory (libqmap)
|
||||
|
||||
# UI generation
|
||||
qt5_wrap_ui (qmap_GENUISRCS ${qmap_UISRCS})
|
||||
|
||||
add_executable (qmap ${qmap_CXXSRCS} ${qmap_CSRCS} ${qmap_GENUISRCS} qmap.rc)
|
||||
target_include_directories (qmap PRIVATE ${CMAKE_SOURCE_DIR} ${FFTW3_INCLUDE_DIRS})
|
||||
target_link_libraries (qmap wsjt_qt qmap_impl ${FFTW3_LIBRARIES} Qt5::Widgets Qt5::Network Usb::Usb)
|
||||
|
||||
if (WSJT_CREATE_WINMAIN)
|
||||
set_target_properties (qmap PROPERTIES WIN32_EXECUTABLE ON)
|
||||
endif (WSJT_CREATE_WINMAIN)
|
||||
|
||||
if (WIN32)
|
||||
install (
|
||||
CODE "get_filename_component (_path \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/wsjtx_dir.txt\" REALPATH)
|
||||
if (WIN32)
|
||||
set (_separator \"\\\\\")
|
||||
else ()
|
||||
set (_separator \"/\")
|
||||
endif ()
|
||||
file (WRITE \"\${_path}\" \".\${_separator}\\n\")"
|
||||
)
|
||||
|
||||
install (
|
||||
TARGETS qmap
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
|
||||
BUNDLE DESTINATION . COMPONENT runtime
|
||||
)
|
||||
endif ()
|
30
qmap/LICENSE_WHEATLEY.TXT
Normal file
30
qmap/LICENSE_WHEATLEY.TXT
Normal file
@ -0,0 +1,30 @@
|
||||
+ + + This Software is released under the "Simplified BSD License" + + +
|
||||
Copyright 2010 Moe Wheatley. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY Moe Wheatley ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL Moe Wheatley OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation
|
||||
are those of the authors and should not be interpreted as representing
|
||||
official policies, either expressed or implied, of Moe Wheatley.
|
BIN
qmap/MAP65_Beta_Release.docx
Normal file
BIN
qmap/MAP65_Beta_Release.docx
Normal file
Binary file not shown.
23
qmap/about.cpp
Normal file
23
qmap/about.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
#include "about.h"
|
||||
#include "revision_utils.hpp"
|
||||
#include "ui_about.h"
|
||||
|
||||
CAboutDlg::CAboutDlg(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::CAboutDlg)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->labelTxt->setText("<html><h2>" + QString {"QMAP v"
|
||||
+ QCoreApplication::applicationVersion ()
|
||||
+ " " + revision ()}.simplified () + "</h2><br />"
|
||||
"QMAP is a wideband receiver for the Q65 protocol, intnded<br />"
|
||||
"primarily for amateur radio EME communication. It works <br />"
|
||||
"in close cooperation with WSJT-X, versions 2.7 and later. <br /><br />"
|
||||
"Copyright 2001-2024 by Joe Taylor, K1JT. Additional <br />"
|
||||
"acknowledgments are contained in the source code.");
|
||||
}
|
||||
|
||||
CAboutDlg::~CAboutDlg()
|
||||
{
|
||||
delete ui;
|
||||
}
|
23
qmap/about.h
Normal file
23
qmap/about.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef ABOUTDLG_H
|
||||
#define ABOUTDLG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class CAboutDlg;
|
||||
}
|
||||
|
||||
class CAboutDlg : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CAboutDlg(QWidget *parent = nullptr);
|
||||
~CAboutDlg();
|
||||
|
||||
private:
|
||||
Ui::CAboutDlg *ui;
|
||||
QString m_Str;
|
||||
};
|
||||
|
||||
#endif // ABOUTDLG_H
|
37
qmap/about.ui
Normal file
37
qmap/about.ui
Normal file
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CAboutDlg</class>
|
||||
<widget class="QDialog" name="CAboutDlg">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::NonModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>374</width>
|
||||
<height>164</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>About QMAP</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelTxt">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
257
qmap/afmhot.dat
Normal file
257
qmap/afmhot.dat
Normal file
@ -0,0 +1,257 @@
|
||||
0 0.0000 0.0000 0.0000
|
||||
1 0.0000 0.0000 0.0000
|
||||
2 0.0078 0.0000 0.0000
|
||||
3 0.0157 0.0000 0.0000
|
||||
4 0.0235 0.0000 0.0000
|
||||
5 0.0314 0.0000 0.0000
|
||||
6 0.0392 0.0000 0.0000
|
||||
7 0.0471 0.0000 0.0000
|
||||
8 0.0549 0.0000 0.0000
|
||||
9 0.0627 0.0000 0.0000
|
||||
10 0.0706 0.0000 0.0000
|
||||
11 0.0784 0.0000 0.0000
|
||||
12 0.0863 0.0000 0.0000
|
||||
13 0.0941 0.0000 0.0000
|
||||
14 0.1020 0.0000 0.0000
|
||||
15 0.1098 0.0000 0.0000
|
||||
16 0.1176 0.0000 0.0000
|
||||
17 0.1255 0.0000 0.0000
|
||||
18 0.1333 0.0000 0.0000
|
||||
19 0.1412 0.0000 0.0000
|
||||
20 0.1490 0.0000 0.0000
|
||||
21 0.1569 0.0000 0.0000
|
||||
22 0.1647 0.0000 0.0000
|
||||
23 0.1725 0.0000 0.0000
|
||||
24 0.1804 0.0000 0.0000
|
||||
25 0.1882 0.0000 0.0000
|
||||
26 0.1961 0.0000 0.0000
|
||||
27 0.2039 0.0000 0.0000
|
||||
28 0.2118 0.0000 0.0000
|
||||
29 0.2196 0.0000 0.0000
|
||||
30 0.2275 0.0000 0.0000
|
||||
31 0.2353 0.0000 0.0000
|
||||
32 0.2431 0.0000 0.0000
|
||||
33 0.2510 0.0000 0.0000
|
||||
34 0.2588 0.0000 0.0000
|
||||
35 0.2667 0.0000 0.0000
|
||||
36 0.2745 0.0000 0.0000
|
||||
37 0.2824 0.0000 0.0000
|
||||
38 0.2902 0.0000 0.0000
|
||||
39 0.2980 0.0000 0.0000
|
||||
40 0.3059 0.0000 0.0000
|
||||
41 0.3137 0.0000 0.0000
|
||||
42 0.3216 0.0000 0.0000
|
||||
43 0.3294 0.0000 0.0000
|
||||
44 0.3373 0.0000 0.0000
|
||||
45 0.3451 0.0000 0.0000
|
||||
46 0.3529 0.0000 0.0000
|
||||
47 0.3608 0.0000 0.0000
|
||||
48 0.3686 0.0000 0.0000
|
||||
49 0.3765 0.0000 0.0000
|
||||
50 0.3843 0.0000 0.0000
|
||||
51 0.3922 0.0000 0.0000
|
||||
52 0.4000 0.0000 0.0000
|
||||
53 0.4078 0.0000 0.0000
|
||||
54 0.4157 0.0000 0.0000
|
||||
55 0.4235 0.0000 0.0000
|
||||
56 0.4314 0.0000 0.0000
|
||||
57 0.4392 0.0000 0.0000
|
||||
58 0.4471 0.0000 0.0000
|
||||
59 0.4549 0.0000 0.0000
|
||||
60 0.4627 0.0000 0.0000
|
||||
61 0.4706 0.0000 0.0000
|
||||
62 0.4784 0.0000 0.0000
|
||||
63 0.4863 0.0000 0.0000
|
||||
64 0.4941 0.0000 0.0000
|
||||
65 0.5020 0.0000 0.0000
|
||||
66 0.5098 0.0098 0.0000
|
||||
67 0.5176 0.0176 0.0000
|
||||
68 0.5255 0.0255 0.0000
|
||||
69 0.5333 0.0333 0.0000
|
||||
70 0.5412 0.0412 0.0000
|
||||
71 0.5490 0.0490 0.0000
|
||||
72 0.5569 0.0569 0.0000
|
||||
73 0.5647 0.0647 0.0000
|
||||
74 0.5725 0.0725 0.0000
|
||||
75 0.5804 0.0804 0.0000
|
||||
76 0.5882 0.0882 0.0000
|
||||
77 0.5961 0.0961 0.0000
|
||||
78 0.6039 0.1039 0.0000
|
||||
79 0.6118 0.1118 0.0000
|
||||
80 0.6196 0.1196 0.0000
|
||||
81 0.6275 0.1275 0.0000
|
||||
82 0.6353 0.1353 0.0000
|
||||
83 0.6431 0.1431 0.0000
|
||||
84 0.6510 0.1510 0.0000
|
||||
85 0.6588 0.1588 0.0000
|
||||
86 0.6667 0.1667 0.0000
|
||||
87 0.6745 0.1745 0.0000
|
||||
88 0.6824 0.1824 0.0000
|
||||
89 0.6902 0.1902 0.0000
|
||||
90 0.6980 0.1980 0.0000
|
||||
91 0.7059 0.2059 0.0000
|
||||
92 0.7137 0.2137 0.0000
|
||||
93 0.7216 0.2216 0.0000
|
||||
94 0.7294 0.2294 0.0000
|
||||
95 0.7373 0.2373 0.0000
|
||||
96 0.7451 0.2451 0.0000
|
||||
97 0.7529 0.2529 0.0000
|
||||
98 0.7608 0.2608 0.0000
|
||||
99 0.7686 0.2686 0.0000
|
||||
100 0.7765 0.2765 0.0000
|
||||
101 0.7843 0.2843 0.0000
|
||||
102 0.7922 0.2922 0.0000
|
||||
103 0.8000 0.3000 0.0000
|
||||
104 0.8078 0.3078 0.0000
|
||||
105 0.8157 0.3157 0.0000
|
||||
106 0.8235 0.3235 0.0000
|
||||
107 0.8314 0.3314 0.0000
|
||||
108 0.8392 0.3392 0.0000
|
||||
109 0.8471 0.3471 0.0000
|
||||
110 0.8549 0.3549 0.0000
|
||||
111 0.8627 0.3627 0.0000
|
||||
112 0.8706 0.3706 0.0000
|
||||
113 0.8784 0.3784 0.0000
|
||||
114 0.8863 0.3863 0.0000
|
||||
115 0.8941 0.3941 0.0000
|
||||
116 0.9020 0.4020 0.0000
|
||||
117 0.9098 0.4098 0.0000
|
||||
118 0.9176 0.4176 0.0000
|
||||
119 0.9255 0.4255 0.0000
|
||||
120 0.9333 0.4333 0.0000
|
||||
121 0.9412 0.4412 0.0000
|
||||
122 0.9490 0.4490 0.0000
|
||||
123 0.9569 0.4569 0.0000
|
||||
124 0.9647 0.4647 0.0000
|
||||
125 0.9725 0.4725 0.0000
|
||||
126 0.9804 0.4804 0.0000
|
||||
127 0.9882 0.4882 0.0000
|
||||
128 0.9961 0.4961 0.0000
|
||||
129 1.0000 0.5039 0.0000
|
||||
130 1.0000 0.5118 0.0118
|
||||
131 1.0000 0.5196 0.0196
|
||||
132 1.0000 0.5275 0.0275
|
||||
133 1.0000 0.5353 0.0353
|
||||
134 1.0000 0.5431 0.0431
|
||||
135 1.0000 0.5510 0.0510
|
||||
136 1.0000 0.5588 0.0588
|
||||
137 1.0000 0.5667 0.0667
|
||||
138 1.0000 0.5745 0.0745
|
||||
139 1.0000 0.5824 0.0824
|
||||
140 1.0000 0.5902 0.0902
|
||||
141 1.0000 0.5980 0.0980
|
||||
142 1.0000 0.6059 0.1059
|
||||
143 1.0000 0.6137 0.1137
|
||||
144 1.0000 0.6216 0.1216
|
||||
145 1.0000 0.6294 0.1294
|
||||
146 1.0000 0.6373 0.1373
|
||||
147 1.0000 0.6451 0.1451
|
||||
148 1.0000 0.6529 0.1529
|
||||
149 1.0000 0.6608 0.1608
|
||||
150 1.0000 0.6686 0.1686
|
||||
151 1.0000 0.6765 0.1765
|
||||
152 1.0000 0.6843 0.1843
|
||||
153 1.0000 0.6922 0.1922
|
||||
154 1.0000 0.7000 0.2000
|
||||
155 1.0000 0.7078 0.2078
|
||||
156 1.0000 0.7157 0.2157
|
||||
157 1.0000 0.7235 0.2235
|
||||
158 1.0000 0.7314 0.2314
|
||||
159 1.0000 0.7392 0.2392
|
||||
160 1.0000 0.7471 0.2471
|
||||
161 1.0000 0.7549 0.2549
|
||||
162 1.0000 0.7627 0.2627
|
||||
163 1.0000 0.7706 0.2706
|
||||
164 1.0000 0.7784 0.2784
|
||||
165 1.0000 0.7863 0.2863
|
||||
166 1.0000 0.7941 0.2941
|
||||
167 1.0000 0.8020 0.3020
|
||||
168 1.0000 0.8098 0.3098
|
||||
169 1.0000 0.8176 0.3176
|
||||
170 1.0000 0.8255 0.3255
|
||||
171 1.0000 0.8333 0.3333
|
||||
172 1.0000 0.8412 0.3412
|
||||
173 1.0000 0.8490 0.3490
|
||||
174 1.0000 0.8569 0.3569
|
||||
175 1.0000 0.8647 0.3647
|
||||
176 1.0000 0.8725 0.3725
|
||||
177 1.0000 0.8804 0.3804
|
||||
178 1.0000 0.8882 0.3882
|
||||
179 1.0000 0.8961 0.3961
|
||||
180 1.0000 0.9039 0.4039
|
||||
181 1.0000 0.9118 0.4118
|
||||
182 1.0000 0.9196 0.4196
|
||||
183 1.0000 0.9275 0.4275
|
||||
184 1.0000 0.9353 0.4353
|
||||
185 1.0000 0.9431 0.4431
|
||||
186 1.0000 0.9510 0.4510
|
||||
187 1.0000 0.9588 0.4588
|
||||
188 1.0000 0.9667 0.4667
|
||||
189 1.0000 0.9745 0.4745
|
||||
190 1.0000 0.9824 0.4824
|
||||
191 1.0000 0.9902 0.4902
|
||||
192 1.0000 0.9980 0.4980
|
||||
193 1.0000 1.0000 0.5059
|
||||
194 1.0000 1.0000 0.5137
|
||||
195 1.0000 1.0000 0.5216
|
||||
196 1.0000 1.0000 0.5294
|
||||
197 1.0000 1.0000 0.5373
|
||||
198 1.0000 1.0000 0.5451
|
||||
199 1.0000 1.0000 0.5529
|
||||
200 1.0000 1.0000 0.5608
|
||||
201 1.0000 1.0000 0.5686
|
||||
202 1.0000 1.0000 0.5765
|
||||
203 1.0000 1.0000 0.5843
|
||||
204 1.0000 1.0000 0.5922
|
||||
205 1.0000 1.0000 0.6000
|
||||
206 1.0000 1.0000 0.6078
|
||||
207 1.0000 1.0000 0.6157
|
||||
208 1.0000 1.0000 0.6235
|
||||
209 1.0000 1.0000 0.6314
|
||||
210 1.0000 1.0000 0.6392
|
||||
211 1.0000 1.0000 0.6471
|
||||
212 1.0000 1.0000 0.6549
|
||||
213 1.0000 1.0000 0.6627
|
||||
214 1.0000 1.0000 0.6706
|
||||
215 1.0000 1.0000 0.6784
|
||||
216 1.0000 1.0000 0.6863
|
||||
217 1.0000 1.0000 0.6941
|
||||
218 1.0000 1.0000 0.7020
|
||||
219 1.0000 1.0000 0.7098
|
||||
220 1.0000 1.0000 0.7176
|
||||
221 1.0000 1.0000 0.7255
|
||||
222 1.0000 1.0000 0.7333
|
||||
223 1.0000 1.0000 0.7412
|
||||
224 1.0000 1.0000 0.7490
|
||||
225 1.0000 1.0000 0.7569
|
||||
226 1.0000 1.0000 0.7647
|
||||
227 1.0000 1.0000 0.7725
|
||||
228 1.0000 1.0000 0.7804
|
||||
229 1.0000 1.0000 0.7882
|
||||
230 1.0000 1.0000 0.7961
|
||||
231 1.0000 1.0000 0.8039
|
||||
232 1.0000 1.0000 0.8118
|
||||
233 1.0000 1.0000 0.8196
|
||||
234 1.0000 1.0000 0.8275
|
||||
235 1.0000 1.0000 0.8353
|
||||
236 1.0000 1.0000 0.8431
|
||||
237 1.0000 1.0000 0.8510
|
||||
238 1.0000 1.0000 0.8588
|
||||
239 1.0000 1.0000 0.8667
|
||||
240 1.0000 1.0000 0.8745
|
||||
241 1.0000 1.0000 0.8824
|
||||
242 1.0000 1.0000 0.8902
|
||||
243 1.0000 1.0000 0.8980
|
||||
244 1.0000 1.0000 0.9059
|
||||
245 1.0000 1.0000 0.9137
|
||||
246 1.0000 1.0000 0.9216
|
||||
247 1.0000 1.0000 0.9294
|
||||
248 1.0000 1.0000 0.9373
|
||||
249 1.0000 1.0000 0.9451
|
||||
250 1.0000 1.0000 0.9529
|
||||
251 1.0000 1.0000 0.9608
|
||||
252 1.0000 1.0000 0.9686
|
||||
253 1.0000 1.0000 0.9765
|
||||
254 1.0 0.0 0.0
|
||||
255 1.0 1.0 0.0
|
||||
256 0.0 1.000 0.0
|
195
qmap/astro.cpp
Normal file
195
qmap/astro.cpp
Normal file
@ -0,0 +1,195 @@
|
||||
#include "astro.h"
|
||||
#include <QSettings>
|
||||
#include "ui_astro.h"
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
#include <stdio.h>
|
||||
#include "SettingsGroup.hpp"
|
||||
#include "commons.h"
|
||||
#include <math.h>
|
||||
|
||||
extern "C" {
|
||||
void astrosub_ (int* nyear, int* month, int* nday, double* uth, int* nfreq,
|
||||
const char* mygrid, const char* hisgrid, double* azsun,
|
||||
double* elsun, double* azmoon, double* elmoon, double* azmoondx,
|
||||
double* elmoondx, int* ntsky, int* ndop, int* ndop00,
|
||||
double* ramoon, double* decmoon, double* dgrd, double* poloffset,
|
||||
double* xnr, int len1, int len2);
|
||||
}
|
||||
|
||||
Astro::Astro (QString const& settings_filename, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::Astro),
|
||||
m_settings_filename {settings_filename}
|
||||
{
|
||||
ui->setupUi (this);
|
||||
setWindowTitle ("Astronomical Data");
|
||||
setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint | Qt::WindowMinimizeButtonHint);
|
||||
QSettings settings {m_settings_filename, QSettings::IniFormat};
|
||||
SettingsGroup g {&settings, "MainWindow"}; // MainWindow group for
|
||||
// historical reasons
|
||||
setGeometry (settings.value ("AstroGeom", QRect {71, 390, 227, 403}).toRect ());
|
||||
ui->astroTextBrowser->setStyleSheet(
|
||||
"QTextBrowser { background-color : cyan; color : black; }");
|
||||
ui->astroTextBrowser->clear();
|
||||
m_AzElDir0="";
|
||||
}
|
||||
|
||||
Astro::~Astro()
|
||||
{
|
||||
QSettings settings {m_settings_filename, QSettings::IniFormat};
|
||||
SettingsGroup g {&settings, "MainWindow"};
|
||||
settings.setValue ("AstroGeom", geometry ());
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void Astro::astroUpdate(QDateTime t, QString mygrid, QString azelDir, double xavg)
|
||||
{
|
||||
char cc[300];
|
||||
double azsun,elsun,azmoon,elmoon,azmoondx,elmoondx;
|
||||
double ramoon,decmoon,dgrd,poloffset,xnr;
|
||||
int ntsky,ndop,ndop00;
|
||||
QString date = t.date().toString("yyyy MMM dd");
|
||||
QString utc = t.time().toString();
|
||||
int nyear=t.date().year();
|
||||
int month=t.date().month();
|
||||
int nday=t.date().day();
|
||||
int nhr=t.time().hour();
|
||||
int nmin=t.time().minute();
|
||||
double sec=t.time().second() + 0.001*t.time().msec();
|
||||
int isec=sec;
|
||||
double uth=nhr + nmin/60.0 + sec/3600.0;
|
||||
int nfreq=(int)datcom_.fcenter;
|
||||
|
||||
astrosub_(&nyear, &month, &nday, &uth, &nfreq, mygrid.toLatin1(),
|
||||
mygrid.toLatin1(), &azsun, &elsun, &azmoon, &elmoon,
|
||||
&azmoondx, &elmoondx, &ntsky, &ndop, &ndop00,&ramoon, &decmoon,
|
||||
&dgrd, &poloffset, &xnr, 6, 6);
|
||||
|
||||
datcom_.ndop00=ndop00; //Send self Doppler to decoder, via datcom
|
||||
m_ndop00=ndop00;
|
||||
|
||||
snprintf(cc, sizeof(cc),
|
||||
"Az: %6.1f\n"
|
||||
"El: %6.1f\n"
|
||||
"SelfDop:%6d\n"
|
||||
"MoonDec:%6.1f\n"
|
||||
"SunAz: %6.1f\n"
|
||||
"SunEl: %6.1f\n"
|
||||
"Freq: %6d\n"
|
||||
"Tsky: %6d\n"
|
||||
"MNR: %6.1f\n"
|
||||
"Dgrd: %6.1f",
|
||||
azmoon,elmoon,ndop00,decmoon,azsun,elsun,
|
||||
nfreq,ntsky,xnr,dgrd);
|
||||
ui->astroTextBrowser->setText(" "+ date + "\nUTC: " + utc + "\n" + cc);
|
||||
|
||||
double azOffset=0.0;
|
||||
double elOffset=0.0;
|
||||
double rad=57.2957795131;
|
||||
int iCycle=2;
|
||||
// Are we doing pointing tests?
|
||||
bool bPointing=ui->cbPointingTests->isChecked();
|
||||
ui->gbPointing->setVisible(bPointing);
|
||||
if(bPointing) {
|
||||
int nDwell=int(ui->sbDwell->value());
|
||||
if(ui->cbAutoCycle->isChecked()) {
|
||||
iCycle=(t.currentSecsSinceEpoch()%(6*nDwell))/nDwell + 1;
|
||||
if(iCycle==1) {
|
||||
azOffset = -ui->sbOffset->value()/cos(elsun/rad);
|
||||
ui->rb1->setChecked(true);
|
||||
}
|
||||
if(iCycle==2 or iCycle==5) {
|
||||
ui->rb2->setChecked(true);
|
||||
}
|
||||
if(iCycle==3) {
|
||||
azOffset = +ui->sbOffset->value()/cos(elsun/rad);
|
||||
ui->rb3->setChecked(true);
|
||||
}
|
||||
if(iCycle==4) {
|
||||
elOffset = -ui->sbOffset->value();
|
||||
ui->rb4->setChecked(true);
|
||||
}
|
||||
if(iCycle==6) {
|
||||
elOffset = +ui->sbOffset->value();
|
||||
ui->rb6->setChecked(true);
|
||||
}
|
||||
} else if(ui->cbOnOff->isChecked()) {
|
||||
iCycle=(t.currentSecsSinceEpoch()%(2*nDwell))/nDwell + 1;
|
||||
if(iCycle==1) {
|
||||
azOffset = -ui->sbOffset->value()/cos(elsun/rad);
|
||||
ui->rb1->setChecked(true);
|
||||
}
|
||||
if(iCycle==2) {
|
||||
ui->rb2->setChecked(true);
|
||||
}
|
||||
} else {
|
||||
if(ui->rb1->isChecked()) azOffset = -ui->sbOffset->value()/cos(elsun/rad);
|
||||
if(ui->rb3->isChecked()) azOffset = ui->sbOffset->value()/cos(elsun/rad);
|
||||
if(ui->rb4->isChecked()) elOffset = -ui->sbOffset->value();
|
||||
if(ui->rb6->isChecked()) elOffset = ui->sbOffset->value();
|
||||
}
|
||||
if(ui->cbAutoCycle->isChecked() or ui->cbOnOff->isChecked()) {
|
||||
QFile f("pointing.out");
|
||||
if(f.open(QIODevice::WriteOnly | QIODevice::Append)) {
|
||||
QTextStream out(&f);
|
||||
out << t.toString("yyyy-MMM-dd hh:mm:ss");
|
||||
snprintf(cc,sizeof(cc),"%7.1f %7.1f %d %7.1f %7.1f %10.1f %7.2f\n",
|
||||
azsun,elsun,iCycle,azOffset,elOffset,xavg,10.0*log10(xavg));
|
||||
out << cc;
|
||||
f.close();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ui->rb2->setChecked(true);
|
||||
ui->cbAutoCycle->setChecked(false);
|
||||
ui->cbOnOff->setChecked(false);
|
||||
}
|
||||
|
||||
// Write pointing data to azel.dat
|
||||
QString fname=azelDir+"/azel.dat";
|
||||
QFile f(fname);
|
||||
if(!f.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
if(azelDir==m_AzElDir0) return;
|
||||
m_AzElDir0=azelDir;
|
||||
QMessageBox mb;
|
||||
mb.setText("Cannot open " + fname + "\nCorrect the setting of AzEl Directory in Setup?");
|
||||
mb.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
QTextStream out(&f);
|
||||
snprintf(cc,sizeof(cc),"%2.2d:%2.2d:%2.2d,%5.1f,%5.1f,Moon\n"
|
||||
"%2.2d:%2.2d:%2.2d,%5.1f,%5.1f,Sun\n"
|
||||
"%2.2d:%2.2d:%2.2d,%5.1f,%5.1f,Source\n"
|
||||
"%4d,%6d,%6d,Doppler\n"
|
||||
"%3d,%1d,fQSO\n",
|
||||
nhr,nmin,isec,azmoon,elmoon,
|
||||
nhr,nmin,isec,azsun+azOffset,elsun+elOffset,
|
||||
nhr,nmin,isec,0.0,0.0,
|
||||
nfreq,ndop,ndop00,
|
||||
datcom_.mousefqso,0);
|
||||
out << cc;
|
||||
f.close();
|
||||
}
|
||||
|
||||
void Astro::setFontSize(int n)
|
||||
{
|
||||
ui->astroTextBrowser->setFontPointSize(n);
|
||||
}
|
||||
|
||||
void Astro::on_cbAutoCycle_clicked(bool checked)
|
||||
{
|
||||
if(checked) ui->cbOnOff->setChecked(false);
|
||||
}
|
||||
|
||||
void Astro::on_cbOnOff_clicked(bool checked)
|
||||
{
|
||||
if(checked) ui->cbAutoCycle->setChecked(false);
|
||||
}
|
||||
|
||||
int Astro::getSelfDop()
|
||||
{
|
||||
return m_ndop00;
|
||||
}
|
35
qmap/astro.h
Normal file
35
qmap/astro.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef ASTRO_H
|
||||
#define ASTRO_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDateTime>
|
||||
|
||||
namespace Ui {
|
||||
class Astro;
|
||||
}
|
||||
|
||||
class Astro : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Astro (QString const& settings_filename, QWidget *parent = 0);
|
||||
void astroUpdate(QDateTime t, QString mygrid, QString azelDir, double xavg);
|
||||
void setFontSize(int n);
|
||||
int getSelfDop();
|
||||
|
||||
~Astro ();
|
||||
|
||||
private slots:
|
||||
void on_cbOnOff_clicked(bool checked);
|
||||
void on_cbAutoCycle_clicked(bool checked);
|
||||
|
||||
private:
|
||||
Ui::Astro *ui;
|
||||
QString m_settings_filename;
|
||||
QString m_AzElDir0;
|
||||
|
||||
qint32 m_ndop00=0;
|
||||
};
|
||||
|
||||
#endif
|
283
qmap/astro.ui
Normal file
283
qmap/astro.ui
Normal file
@ -0,0 +1,283 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Astro</class>
|
||||
<widget class="QWidget" name="Astro">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>431</width>
|
||||
<height>393</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<widget class="QGroupBox" name="gbPointing">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>269</x>
|
||||
<y>19</y>
|
||||
<width>151</width>
|
||||
<height>361</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string/>
|
||||
</property>
|
||||
<widget class="QRadioButton" name="rb1">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>70</y>
|
||||
<width>30</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="rb2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>60</x>
|
||||
<y>70</y>
|
||||
<width>40</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>2, 5</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="rb3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>110</x>
|
||||
<y>70</y>
|
||||
<width>30</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>3</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="rb4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>60</x>
|
||||
<y>120</y>
|
||||
<width>30</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>4</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="rb6">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>60</x>
|
||||
<y>20</y>
|
||||
<width>30</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>6</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QDoubleSpinBox" name="sbOffset">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>180</y>
|
||||
<width>130</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Offset </string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> deg</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.500000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>20.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.500000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>2.500000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="cbAutoCycle">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>260</y>
|
||||
<width>91</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Auto Cycle</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="cbOnOff">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>300</y>
|
||||
<width>70</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>On Off</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QSpinBox" name="sbDwell">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>220</y>
|
||||
<width>130</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> s</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Dwell </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>300</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>10</y>
|
||||
<width>258</width>
|
||||
<height>371</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="astroTextBrowser">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>325</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Courier New</family>
|
||||
<pointsize>20</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbPointingTests">
|
||||
<property name="text">
|
||||
<string>Pointing Tests</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
256
qmap/blue.dat
Normal file
256
qmap/blue.dat
Normal file
@ -0,0 +1,256 @@
|
||||
0 0.0000 0.0000 0.0000
|
||||
1 0.0902 0.0902 0.2558
|
||||
2 0.1176 0.1176 0.2694
|
||||
3 0.1412 0.1412 0.2820
|
||||
4 0.1569 0.1569 0.2938
|
||||
5 0.1725 0.1725 0.3049
|
||||
6 0.1843 0.1843 0.3154
|
||||
7 0.1961 0.1961 0.3254
|
||||
8 0.2039 0.2039 0.3349
|
||||
9 0.2157 0.2157 0.3440
|
||||
10 0.2235 0.2235 0.3528
|
||||
11 0.2314 0.2314 0.3612
|
||||
12 0.2392 0.2392 0.3693
|
||||
13 0.2471 0.2471 0.3772
|
||||
14 0.2549 0.2549 0.3848
|
||||
15 0.2588 0.2588 0.3921
|
||||
16 0.2667 0.2667 0.3992
|
||||
17 0.2706 0.2706 0.4061
|
||||
18 0.2784 0.2784 0.4129
|
||||
19 0.2824 0.2824 0.4194
|
||||
20 0.2902 0.2902 0.4258
|
||||
21 0.2941 0.2941 0.4319
|
||||
22 0.2980 0.2980 0.4380
|
||||
23 0.3059 0.3059 0.4439
|
||||
24 0.3098 0.3098 0.4496
|
||||
25 0.3137 0.3137 0.4553
|
||||
26 0.3176 0.3176 0.4608
|
||||
27 0.3216 0.3216 0.4661
|
||||
28 0.3294 0.3294 0.4714
|
||||
29 0.3333 0.3333 0.4765
|
||||
30 0.3373 0.3373 0.4815
|
||||
31 0.3412 0.3412 0.4865
|
||||
32 0.3451 0.3451 0.4913
|
||||
33 0.3490 0.3490 0.4960
|
||||
34 0.3529 0.3529 0.5006
|
||||
35 0.3569 0.3569 0.5052
|
||||
36 0.3608 0.3608 0.5096
|
||||
37 0.3647 0.3647 0.5140
|
||||
38 0.3686 0.3686 0.5183
|
||||
39 0.3725 0.3725 0.5225
|
||||
40 0.3765 0.3765 0.5266
|
||||
41 0.3804 0.3804 0.5306
|
||||
42 0.3843 0.3843 0.5346
|
||||
43 0.3843 0.3843 0.5385
|
||||
44 0.3882 0.3882 0.5423
|
||||
45 0.3922 0.3922 0.5460
|
||||
46 0.3961 0.3961 0.5497
|
||||
47 0.4000 0.4000 0.5533
|
||||
48 0.4039 0.4039 0.5569
|
||||
49 0.4078 0.4078 0.5603
|
||||
50 0.4118 0.4118 0.5638
|
||||
51 0.4118 0.4118 0.5671
|
||||
52 0.4157 0.4157 0.5704
|
||||
53 0.4196 0.4196 0.5736
|
||||
54 0.4235 0.4235 0.5768
|
||||
55 0.4275 0.4275 0.5799
|
||||
56 0.4314 0.4314 0.5829
|
||||
57 0.4314 0.4314 0.5859
|
||||
58 0.4353 0.4353 0.5889
|
||||
59 0.4392 0.4392 0.5917
|
||||
60 0.4431 0.4431 0.5946
|
||||
61 0.4471 0.4471 0.5973
|
||||
62 0.4471 0.4471 0.6001
|
||||
63 0.4510 0.4510 0.6027
|
||||
64 0.4549 0.4549 0.6053
|
||||
65 0.4588 0.4588 0.6079
|
||||
66 0.4627 0.4627 0.6104
|
||||
67 0.4627 0.4627 0.6129
|
||||
68 0.4667 0.4667 0.6153
|
||||
69 0.4706 0.4706 0.6176
|
||||
70 0.4745 0.4745 0.6199
|
||||
71 0.4745 0.4745 0.6222
|
||||
72 0.4784 0.4784 0.6244
|
||||
73 0.4824 0.4824 0.6266
|
||||
74 0.4863 0.4863 0.6287
|
||||
75 0.4863 0.4863 0.6308
|
||||
76 0.4902 0.4902 0.6328
|
||||
77 0.4941 0.4941 0.6348
|
||||
78 0.4980 0.4980 0.6367
|
||||
79 0.5020 0.5020 0.6386
|
||||
80 0.5020 0.5020 0.6404
|
||||
81 0.5059 0.5059 0.6422
|
||||
82 0.5098 0.5098 0.6440
|
||||
83 0.5098 0.5098 0.6457
|
||||
84 0.5137 0.5137 0.6474
|
||||
85 0.5176 0.5176 0.6490
|
||||
86 0.5216 0.5216 0.6506
|
||||
87 0.5216 0.5216 0.6521
|
||||
88 0.5255 0.5255 0.6536
|
||||
89 0.5294 0.5294 0.6551
|
||||
90 0.5333 0.5333 0.6565
|
||||
91 0.5333 0.5333 0.6578
|
||||
92 0.5373 0.5373 0.6591
|
||||
93 0.5412 0.5412 0.6604
|
||||
94 0.5451 0.5451 0.6617
|
||||
95 0.5451 0.5451 0.6629
|
||||
96 0.5490 0.5490 0.6640
|
||||
97 0.5529 0.5529 0.6651
|
||||
98 0.5569 0.5569 0.6662
|
||||
99 0.5569 0.5569 0.6672
|
||||
100 0.5608 0.5608 0.6682
|
||||
101 0.5647 0.5647 0.6692
|
||||
102 0.5647 0.5647 0.6701
|
||||
103 0.5686 0.5686 0.6710
|
||||
104 0.5725 0.5725 0.6718
|
||||
105 0.5765 0.5765 0.6726
|
||||
106 0.5765 0.5765 0.6733
|
||||
107 0.5804 0.5804 0.6740
|
||||
108 0.5843 0.5843 0.6747
|
||||
109 0.5843 0.5843 0.6753
|
||||
110 0.5882 0.5882 0.6759
|
||||
111 0.5922 0.5922 0.6765
|
||||
112 0.5961 0.5961 0.6770
|
||||
113 0.5961 0.5961 0.6774
|
||||
114 0.6000 0.6000 0.6779
|
||||
115 0.6039 0.6039 0.6783
|
||||
116 0.6039 0.6039 0.6786
|
||||
117 0.6078 0.6078 0.6789
|
||||
118 0.6118 0.6118 0.6792
|
||||
119 0.6157 0.6157 0.6794
|
||||
120 0.6157 0.6157 0.6796
|
||||
121 0.6196 0.6196 0.6798
|
||||
122 0.6235 0.6235 0.6799
|
||||
123 0.6235 0.6235 0.6800
|
||||
124 0.6275 0.6275 0.6800
|
||||
125 0.6314 0.6314 0.6800
|
||||
126 0.6353 0.6353 0.6799
|
||||
127 0.6353 0.6353 0.6799
|
||||
128 0.6392 0.6392 0.6797
|
||||
129 0.6431 0.6431 0.6796
|
||||
130 0.6431 0.6431 0.6794
|
||||
131 0.6471 0.6471 0.6791
|
||||
132 0.6510 0.6510 0.6789
|
||||
133 0.6549 0.6549 0.6785
|
||||
134 0.6549 0.6549 0.6782
|
||||
135 0.6588 0.6588 0.6778
|
||||
136 0.6627 0.6627 0.6773
|
||||
137 0.6627 0.6627 0.6769
|
||||
138 0.6667 0.6667 0.6763
|
||||
139 0.6706 0.6706 0.6758
|
||||
140 0.6745 0.6745 0.6752
|
||||
141 0.6745 0.6745 0.6746
|
||||
142 0.6784 0.6784 0.6739
|
||||
143 0.6824 0.6824 0.6732
|
||||
144 0.6824 0.6824 0.6724
|
||||
145 0.6863 0.6863 0.6716
|
||||
146 0.6902 0.6902 0.6708
|
||||
147 0.6941 0.6941 0.6699
|
||||
148 0.6941 0.6941 0.6690
|
||||
149 0.6980 0.6980 0.6680
|
||||
150 0.7020 0.7020 0.6670
|
||||
151 0.7020 0.7020 0.6660
|
||||
152 0.7059 0.7059 0.6649
|
||||
153 0.7098 0.7098 0.6638
|
||||
154 0.7098 0.7098 0.6626
|
||||
155 0.7137 0.7137 0.6614
|
||||
156 0.7176 0.7176 0.6601
|
||||
157 0.7216 0.7216 0.6589
|
||||
158 0.7216 0.7216 0.6575
|
||||
159 0.7255 0.7255 0.6561
|
||||
160 0.7294 0.7294 0.6547
|
||||
161 0.7294 0.7294 0.6533
|
||||
162 0.7333 0.7333 0.6518
|
||||
163 0.7373 0.7373 0.6502
|
||||
164 0.7412 0.7412 0.6486
|
||||
165 0.7412 0.7412 0.6470
|
||||
166 0.7451 0.7451 0.6453
|
||||
167 0.7490 0.7490 0.6436
|
||||
168 0.7490 0.7490 0.6418
|
||||
169 0.7529 0.7529 0.6400
|
||||
170 0.7569 0.7569 0.6382
|
||||
171 0.7608 0.7608 0.6363
|
||||
172 0.7608 0.7608 0.6343
|
||||
173 0.7647 0.7647 0.6324
|
||||
174 0.7686 0.7686 0.6303
|
||||
175 0.7686 0.7686 0.6282
|
||||
176 0.7725 0.7725 0.6261
|
||||
177 0.7765 0.7765 0.6239
|
||||
178 0.7804 0.7804 0.6217
|
||||
179 0.7804 0.7804 0.6194
|
||||
180 0.7843 0.7843 0.6171
|
||||
181 0.7882 0.7882 0.6147
|
||||
182 0.7882 0.7882 0.6123
|
||||
183 0.7922 0.7922 0.6098
|
||||
184 0.7961 0.7961 0.6073
|
||||
185 0.8000 0.8000 0.6047
|
||||
186 0.8000 0.8000 0.6021
|
||||
187 0.8039 0.8039 0.5994
|
||||
188 0.8078 0.8078 0.5967
|
||||
189 0.8078 0.8078 0.5939
|
||||
190 0.8118 0.8118 0.5911
|
||||
191 0.8157 0.8157 0.5882
|
||||
192 0.8196 0.8196 0.5853
|
||||
193 0.8196 0.8196 0.5823
|
||||
194 0.8235 0.8235 0.5792
|
||||
195 0.8275 0.8275 0.5761
|
||||
196 0.8275 0.8275 0.5729
|
||||
197 0.8314 0.8314 0.5697
|
||||
198 0.8353 0.8353 0.5664
|
||||
199 0.8392 0.8392 0.5630
|
||||
200 0.8392 0.8392 0.5596
|
||||
201 0.8431 0.8431 0.5561
|
||||
202 0.8471 0.8471 0.5525
|
||||
203 0.8471 0.8471 0.5489
|
||||
204 0.8510 0.8510 0.5452
|
||||
205 0.8549 0.8549 0.5414
|
||||
206 0.8588 0.8588 0.5376
|
||||
207 0.8588 0.8588 0.5337
|
||||
208 0.8627 0.8627 0.5297
|
||||
209 0.8667 0.8667 0.5257
|
||||
210 0.8667 0.8667 0.5215
|
||||
211 0.8706 0.8706 0.5173
|
||||
212 0.8745 0.8745 0.5130
|
||||
213 0.8784 0.8784 0.5086
|
||||
214 0.8784 0.8784 0.5042
|
||||
215 0.8824 0.8824 0.4996
|
||||
216 0.8863 0.8863 0.4950
|
||||
217 0.8863 0.8863 0.4902
|
||||
218 0.8902 0.8902 0.4854
|
||||
219 0.8941 0.8941 0.4804
|
||||
220 0.8980 0.8980 0.4754
|
||||
221 0.8980 0.8980 0.4702
|
||||
222 0.9020 0.9020 0.4649
|
||||
223 0.9059 0.9059 0.4595
|
||||
224 0.9098 0.9098 0.4540
|
||||
225 0.9098 0.9098 0.4484
|
||||
226 0.9137 0.9137 0.4426
|
||||
227 0.9176 0.9176 0.4366
|
||||
228 0.9176 0.9176 0.4306
|
||||
229 0.9216 0.9216 0.4243
|
||||
230 0.9255 0.9255 0.4179
|
||||
231 0.9294 0.9294 0.4114
|
||||
232 0.9294 0.9294 0.4046
|
||||
233 0.9333 0.9333 0.3977
|
||||
234 0.9373 0.9373 0.3905
|
||||
235 0.9373 0.9373 0.3831
|
||||
236 0.9412 0.9412 0.3754
|
||||
237 0.9451 0.9451 0.3675
|
||||
238 0.9490 0.9490 0.3594
|
||||
239 0.9490 0.9490 0.3509
|
||||
240 0.9529 0.9529 0.3420
|
||||
241 0.9569 0.9569 0.3328
|
||||
242 0.9608 0.9608 0.3232
|
||||
243 0.9608 0.9608 0.3131
|
||||
244 0.9647 0.9647 0.3024
|
||||
245 0.9686 0.9686 0.2912
|
||||
246 0.9686 0.9686 0.2792
|
||||
247 0.9725 0.9725 0.2664
|
||||
248 0.9765 0.9765 0.2526
|
||||
249 0.9804 0.9804 0.2375
|
||||
250 0.9804 0.9804 0.2208
|
||||
251 0.9843 0.9843 0.2020
|
||||
252 0.9882 0.9882 0.1800
|
||||
253 1.0 0.0 0.0
|
||||
254 1.0 1.0 0.0
|
||||
255 0.0 1.000 0.0
|
107
qmap/commons.h
Normal file
107
qmap/commons.h
Normal file
@ -0,0 +1,107 @@
|
||||
#ifndef COMMONS_H
|
||||
#define COMMONS_H
|
||||
|
||||
#define NFFT 32768
|
||||
|
||||
extern "C" {
|
||||
|
||||
extern struct { //This is "common/datcom/..." in Fortran
|
||||
float d4[2*5760000]; //Raw I/Q data from Linrad
|
||||
float ss[400*NFFT]; //Half-symbol spectra at 0,45,90,135 deg pol
|
||||
float savg[NFFT]; //Avg spectra at 0,45,90,135 deg pol
|
||||
double fcenter; //Center freq from Linrad (MHz)
|
||||
int nutc; //UTC as integer, HHMM
|
||||
float fselected; //Selected frequency for nagain decodes
|
||||
int mousedf; //User-selected DF
|
||||
int mousefqso; //User-selected QSO freq (kHz)
|
||||
int nagain; //1 ==> decode only at fQSO +/- Tol
|
||||
int ndepth; //How much hinted decoding to do?
|
||||
int ndiskdat; //1 ==> data read from *.iq file
|
||||
int ntx60; //Number of seconds transmitted in Q65-60x
|
||||
int newdat; //1 ==> new data, must do long FFT
|
||||
int nfa; //Low decode limit (kHz)
|
||||
int nfb; //High decode limit (kHz)
|
||||
int nfcal; //Frequency correction, for calibration (Hz)
|
||||
int nfshift; //Shift of displayed center freq (kHz)
|
||||
int ntx30a; //Number of seconds transmitted in first half minute , Q65-30x
|
||||
int ntx30b; //Number of seconds transmitted in second half minute, Q65-30x
|
||||
int ntol; //+/- decoding range around fQSO (Hz)
|
||||
int n60; //nsecs%60
|
||||
int junk4; //
|
||||
int nfsample; //Input sample rate
|
||||
int ndop58; //EME Self Doppler at t=58
|
||||
int nBaseSubmode; //Base submode for Q65-60x (aka m_modeQ65)
|
||||
int ndop00; //EME Self Doppler at t=0
|
||||
int nsave; //0=None, 1=SaveDecoded, 2=SaveAll
|
||||
int max_drift; //Maximum Q65 drift: units symbol_rate/TxT
|
||||
int offset; //Offset in Hz
|
||||
int nhsym; //Number of available JT65 half-symbols
|
||||
char mycall[12];
|
||||
char mygrid[6];
|
||||
char hiscall[12];
|
||||
char hisgrid[6];
|
||||
char datetime[20];
|
||||
int junk1; //Used to test extent of copy to shared memory
|
||||
int junk2;
|
||||
bool bAlso30; //Process for 30-second submode as well as 60-second
|
||||
} datcom_;
|
||||
|
||||
extern struct { //This is "common/datcom/..." in Fortran
|
||||
float d4[2*5760000]; //Raw I/Q data from Linrad
|
||||
float ss[400*NFFT]; //Half-symbol spectra at 0,45,90,135 deg pol
|
||||
float savg[NFFT]; //Avg spectra at 0,45,90,135 deg pol
|
||||
double fcenter; //Center freq from Linrad (MHz)
|
||||
int nutc; //UTC as integer, HHMM
|
||||
float fselected; //Selected frequency for nagain decodes
|
||||
int mousedf; //User-selected DF
|
||||
int mousefqso; //User-selected QSO freq (kHz)
|
||||
int nagain; //1 ==> decode only at fQSO +/- Tol
|
||||
int ndepth; //How much hinted decoding to do?
|
||||
int ndiskdat; //1 ==> data read from *.iq file
|
||||
int ntx60; //Number of seconds transmitted in Q65-60x
|
||||
int newdat; //1 ==> new data, must do long FFT
|
||||
int nfa; //Low decode limit (kHz)
|
||||
int nfb; //High decode limit (kHz)
|
||||
int nfcal; //Frequency correction, for calibration (Hz)
|
||||
int nfshift; //Shift of displayed center freq (kHz)
|
||||
int ntx30a; //Number of seconds transmitted in first half minute , Q65-30x
|
||||
int ntx30b; //Number of seconds transmitted in second half minute, Q65-30x
|
||||
int ntol; //+/- decoding range around fQSO (Hz)
|
||||
int n60; //nsecs%60
|
||||
int junk4; //
|
||||
int nfsample; //Input sample rate
|
||||
int ndop58; //EME Self Doppler at t=58
|
||||
int nBaseSubmode; //Base submode for Q65-60x (aka m_modeQ65)
|
||||
int ndop00; //EME Self Doppler at t=0
|
||||
int nsave; //0=None, 1=SaveDecoded, 2=SaveAll
|
||||
int max_drift; //Maximum Q65 drift: units symbol_rate/TxT
|
||||
int offset; //Offset in Hz
|
||||
int nhsym; //Number of available JT65 half-symbols
|
||||
char mycall[12];
|
||||
char mygrid[6];
|
||||
char hiscall[12];
|
||||
char hisgrid[6];
|
||||
char datetime[20];
|
||||
int junk1; //Used to test extent of copy to shared memory
|
||||
int junk2;
|
||||
bool bAlso30; //Process for 30-second submode as well as 60-second
|
||||
} datcom2_;
|
||||
|
||||
extern struct {
|
||||
int ndecodes; //These are flags for inter-process communication
|
||||
int ncand; //between QMAP and WSJT-X
|
||||
int nQDecoderDone; //1 for real-time decodes, 2 for data from disk
|
||||
int nWDecoderBusy; //Set to 1 when WSJT-X decoder is busy
|
||||
int nWTransmitting; //Set to TRperiod when WSJT-X is transmitting
|
||||
int kHzRequested; //Integer kHz dial frequency request to WSJT-X
|
||||
char result[50][64]; //Staging area for QMAP decodes
|
||||
} decodes_;
|
||||
|
||||
extern struct {
|
||||
char revision[22];
|
||||
char saveFileName[120];
|
||||
} savecom_;
|
||||
|
||||
}
|
||||
|
||||
#endif // COMMONS_H
|
51
qmap/devsetup.cpp
Normal file
51
qmap/devsetup.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
#include "devsetup.h"
|
||||
#include "mainwindow.h"
|
||||
#include <QTextStream>
|
||||
#include <QDebug>
|
||||
#include <cstdio>
|
||||
|
||||
//----------------------------------------------------------- DevSetup()
|
||||
DevSetup::DevSetup(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
ui.setupUi(this); //setup the dialog form
|
||||
m_restartSoundIn=false;
|
||||
}
|
||||
|
||||
DevSetup::~DevSetup()
|
||||
{
|
||||
}
|
||||
|
||||
void DevSetup::initDlg()
|
||||
{
|
||||
ui.myCallEntry->setText(m_myCall);
|
||||
ui.myGridEntry->setText(m_myGrid);
|
||||
ui.astroFont->setValue(m_astroFont);
|
||||
ui.myCallColor->addItems({"","red","green","cyan"});
|
||||
ui.myCallColor->setCurrentIndex(m_myCallColor);
|
||||
ui.saveDirEntry->setText(m_saveDir);
|
||||
ui.azelDirEntry->setText(m_azelDir);
|
||||
ui.fCalSpinBox->setValue(m_fCal);
|
||||
ui.faddEntry->setText(QString::number(m_fAdd,'f',3));
|
||||
ui.sbPort->setValue(m_udpPort);
|
||||
ui.sb_dB->setValue(m_dB);
|
||||
}
|
||||
|
||||
//------------------------------------------------------- accept()
|
||||
void DevSetup::accept()
|
||||
{
|
||||
// Called when OK button is clicked.
|
||||
// Check to see whether SoundInThread must be restarted,
|
||||
// and save user parameters.
|
||||
|
||||
m_myCall=ui.myCallEntry->text();
|
||||
m_myGrid=ui.myGridEntry->text();
|
||||
m_astroFont=ui.astroFont->value();
|
||||
m_myCallColor=ui.myCallColor->currentIndex();
|
||||
m_saveDir=ui.saveDirEntry->text();
|
||||
m_azelDir=ui.azelDirEntry->text();
|
||||
m_fCal=ui.fCalSpinBox->value();
|
||||
m_fAdd=ui.faddEntry->text().toDouble();
|
||||
m_udpPort=ui.sbPort->value();
|
||||
m_dB=ui.sb_dB->value();
|
||||
QDialog::accept();
|
||||
}
|
41
qmap/devsetup.h
Normal file
41
qmap/devsetup.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef DEVSETUP_H
|
||||
#define DEVSETUP_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "ui_devsetup.h"
|
||||
|
||||
class DevSetup : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DevSetup(QWidget *parent=0);
|
||||
~DevSetup();
|
||||
|
||||
void initDlg();
|
||||
qint32 m_fCal;
|
||||
qint32 m_udpPort;
|
||||
qint32 m_astroFont;
|
||||
qint32 m_dB;
|
||||
|
||||
double m_fAdd;
|
||||
double m_TxOffset;
|
||||
|
||||
bool m_network;
|
||||
bool m_restartSoundIn;
|
||||
|
||||
int m_myCallColor;
|
||||
|
||||
QString m_myCall;
|
||||
QString m_myGrid;
|
||||
QString m_saveDir;
|
||||
QString m_azelDir;
|
||||
|
||||
public slots:
|
||||
void accept();
|
||||
|
||||
private:
|
||||
int r,g,b,r0,g0,b0,r1,g1,b1,r2,g2,b2,r3,g3,b3;
|
||||
Ui::DialogSndCard ui;
|
||||
};
|
||||
|
||||
#endif // DEVSETUP_H
|
448
qmap/devsetup.ui
Normal file
448
qmap/devsetup.ui
Normal file
@ -0,0 +1,448 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DialogSndCard</class>
|
||||
<widget class="QDialog" name="DialogSndCard">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>268</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTabWidget" name="ioTabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Station</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>My Call:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>My Grid:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Astro Font Size:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Highlight My Call:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="myCallEntry">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>K1JT</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="myGridEntry">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>FN20qi</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="astroFont">
|
||||
<property name="minimum">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>32</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="myCallColor"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Fcal (Hz):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Fadd (MHz)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="fCalSpinBox">
|
||||
<property name="minimum">
|
||||
<number>-50000</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="faddEntry">
|
||||
<property name="text">
|
||||
<string>0.0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save Directory:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="saveDirEntry">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>AzEl Directory:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="azelDirEntry">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="title">
|
||||
<string>I/O Devices</string>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="layoutWidget_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>10</y>
|
||||
<width>255</width>
|
||||
<height>64</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Input from Linrad or SDR Console</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="sb_dB">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Adjust to scale digital I/Q data.</p></body></html></string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> dB</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Gain </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-50</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_11">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="sbPort">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>57</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>20000</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>51000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50004</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_Port">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>26</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>DialogSndCard</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>257</x>
|
||||
<y>380</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>DialogSndCard</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>325</x>
|
||||
<y>380</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
15
qmap/displaytext.cpp
Normal file
15
qmap/displaytext.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include "displaytext.h"
|
||||
#include <QDebug>
|
||||
#include <QMouseEvent>
|
||||
|
||||
DisplayText::DisplayText(QWidget *parent) :
|
||||
QTextBrowser(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void DisplayText::mouseDoubleClickEvent(QMouseEvent *e)
|
||||
{
|
||||
bool ctrl = (e->modifiers() & 0x4000000);
|
||||
emit(selectCallsign(ctrl));
|
||||
QTextBrowser::mouseDoubleClickEvent(e);
|
||||
}
|
22
qmap/displaytext.h
Normal file
22
qmap/displaytext.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef DISPLAYTEXT_H
|
||||
#define DISPLAYTEXT_H
|
||||
|
||||
#include <QTextBrowser>
|
||||
|
||||
class DisplayText : public QTextBrowser
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DisplayText(QWidget *parent = 0);
|
||||
|
||||
signals:
|
||||
void selectCallsign(bool ctrl);
|
||||
|
||||
public slots:
|
||||
|
||||
protected:
|
||||
void mouseDoubleClickEvent(QMouseEvent *e);
|
||||
|
||||
};
|
||||
|
||||
#endif // DISPLAYTEXT_H
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user