1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-07-29 20:22:26 -04:00

Compare commits

...

351 Commits

Author SHA1 Message Date
Edouard Griffiths
7f51f794fd
Merge pull request #2484 from srcejon/fix_140
Fix type forward declaration
2025-07-08 14:55:47 +02:00
Jon Beniston
f76bfcb8f4 Revert Qt to 6.7.3 on Windows. 2025-07-08 08:25:49 +01:00
Jon Beniston
88e52f362a Fix type forward declaration. 2025-07-07 12:54:19 +01:00
Edouard Griffiths
8a4b8e3731
Merge pull request #2482 from srcejon/fix_2481
Update Qt version to 6.9.1 on Windows and Mac.
2025-07-05 21:31:26 +02:00
Jon Beniston
3966480fea Update Qt version to 6.9.1 on Windows and Mac. For #2481 2025-07-05 13:31:44 +01:00
f4exb
115922c385 Updated version and changelogs 2025-07-02 19:02:52 +02:00
f4exb
32dbf0f325 Audio: added 160 kHz sample rate for Malahit DSP 2025-07-02 14:57:39 +02:00
Edouard Griffiths
03bc7e3d08
Merge pull request #2479 from f4exb/fix-2478
Fix 2478
2025-07-02 09:25:00 +02:00
f4exb
49f2527fcd AudioCATSISO: fix audio sample rate handling and device enumeration 2025-07-02 00:07:31 +02:00
f4exb
2dbc61a92e AudioInput: set the correct sample rate after device sample rates refresh 2025-07-02 00:06:44 +02:00
f4exb
4dade2a709 Try to find the correct available audio sample rates in Qt5 2025-07-02 00:05:22 +02:00
Edouard Griffiths
7c738b161c
Merge pull request #2475 from srcejon/fix_2435
Radio Astronomy: Add option to auto save data to .csv.
2025-06-24 16:38:46 +02:00
Jon Beniston
4afde2a399 Radio Astronomy: Add option to auto save data to .csv. For #2435 2025-06-24 12:32:42 +01:00
Edouard Griffiths
7f5f59e510
Merge pull request #2474 from srcejon/freq_scanner
FreqScanner: Fix crash if row is selected when remove is pressed.
2025-06-24 08:10:07 +02:00
Edouard Griffiths
61608067f4
Merge pull request #2473 from srcejon/fix_2470
RemoteTCP: Add support for SDR_RX_SAMPLE_24BIT=OFF
2025-06-24 00:53:30 +02:00
srcejon
deac6017e3 FreqScanner: Fix crash if row is selected when remove is pressed. For #2391 2025-06-23 22:52:32 +01:00
Jon Beniston
d67798da56 RemoteTCP: Add support for SDR_RX_SAMPLE_24BIT=OFF 2025-06-23 22:36:09 +01:00
Edouard Griffiths
ca5898bc57
Merge pull request #2472 from srcejon/fix_2470
Fix --remote-tcp.
2025-06-23 18:18:05 +02:00
Edouard Griffiths
694c3a334d
Merge pull request #2467 from srcejon/android_fixes
A few small fixes
2025-06-23 18:17:50 +02:00
Jon Beniston
99fca7c09e Fix --remote-tcp. For #2470 2025-06-20 15:43:01 +01:00
Jon Beniston
d2470a5379 Remove obsolete GOES TLE. Remove NOAA18 as no longer active. For #2372 2025-06-17 12:20:29 +01:00
Jon Beniston
638898d3a4 Fix crash if route database not downloaded 2025-06-17 11:53:56 +01:00
Jon Beniston
e16772c154 Hide 3D only buttons if no 3D map 2025-06-17 11:53:36 +01:00
Jon Beniston
914a3af96f Fix Android compilation 2025-06-17 11:53:00 +01:00
Edouard Griffiths
e5fc6fbd81
Merge pull request #2465 from srcejon/freq_scanner
Map and ADS-B updates
2025-06-13 14:38:33 +02:00
srcejon
83bff3e847 FramelessWindowResizer: Enable child tracking for QWebEngineView. 2025-06-12 15:11:33 +01:00
srcejon
b340b92a04 Fix 2D map tracks. 2025-06-12 09:46:00 +01:00
srcejon
89a25c8a7f Fix QML warning 2025-06-12 09:21:33 +01:00
srcejon
0e93251349 Fix update of current position after filtering. 2025-06-11 10:37:45 +01:00
srcejon
65e6f89214 Restore position of 2D map after changing settings. #2458 2025-06-10 18:03:57 +01:00
srcejon
e287ac60d5 Remove debug 2025-06-10 18:03:00 +01:00
srcejon
5985a0d2e0 Fix gcc warning. 2025-06-10 15:52:30 +01:00
srcejon
9864650d9a Fix parameter injection warning. #2203 2025-06-10 15:52:09 +01:00
srcejon
0a3a455937 Fix reg exp for lat,long string. 2025-06-10 15:31:36 +01:00
srcejon
e564ac2f39 Update Kiki public URL. Add proxy support. 2025-06-10 15:30:52 +01:00
srcejon
7948561cdc Update docs. 2025-06-10 14:37:14 +01:00
srcejon
43e1e9c095 Update map docmentation. 2025-06-10 13:13:41 +01:00
srcejon
811f320536 Fix typos. 2025-06-10 11:46:58 +01:00
srcejon
290ba12c93
Merge branch 'f4exb:master' into freq_scanner 2025-06-10 11:37:54 +01:00
srcejon
6dba1f6813 Update ADS-B documentation. 2025-06-10 11:30:48 +01:00
Edouard Griffiths
05f88acf02
Merge pull request #2461 from srcejon/fix_2456
Add 384000 and maximum supported audio sample rates for Qt 6
2025-06-10 11:23:41 +02:00
srcejon
3e0375f6d5 Update docs 2025-06-09 20:07:35 +01:00
srcejon
d441dad344 Add debug 2025-06-09 20:07:22 +01:00
srcejon
55de2c724f Wait until connected before sending initial CZML 2025-06-09 20:06:58 +01:00
srcejon
cca47bbb50 Use Ellipsoid as default terrain, to minimize quota usage. 2025-06-09 16:12:13 +01:00
srcejon
8a3a246888 Add maptiler API key setting for satellite maps. Rotate default key.
Use OSM map tiles, as wikimedia tiles are no longer available.
Fix gcc warnings.
2025-06-09 15:36:01 +01:00
srcejon
b7619e1c57 Add missing return values. 2025-06-09 12:46:01 +01:00
Jon Beniston
9b714aed45 Add 384000 and maximum supported sample rates for Qt 6 AudioDeviceInfo. For #2456. 2025-06-09 11:29:16 +01:00
srcejon
c791067ea8 Fix gcc error. 2025-06-09 11:12:46 +01:00
srcejon
bc235856a8 Add Whittaker Eilers smoothing. 2025-06-09 11:01:25 +01:00
srcejon
ff3b3f4ef5 Map: Add PFD, first person view and path smoothing. Only send changes via CZML. 2025-06-09 10:44:17 +01:00
srcejon
29f7d534e5 Support wasm files in web server. 2025-06-09 10:38:53 +01:00
srcejon
395e9e0821 Use settings keys 2025-06-09 10:36:46 +01:00
srcejon
1e5257b851 Update Cesium resources 2025-06-09 10:34:57 +01:00
srcejon
d26aa35969 Map: Add support for latest Cesium graphics settings: MSAA, Terrain Lighting, Water effects, Fog and HDR, display FPS.
Add setting to select default imagery. Use Sentinel 2 as default to avoid hitting Bing Maps quota.
Add directional light strength setting.
Add ArcGIS API Key setting.
2025-06-09 10:34:41 +01:00
srcejon
24b1807a07 Map: Rotate default API keys. 2025-06-09 10:25:50 +01:00
srcejon
6c9dd36f8b Map: Add Aurora prediction and Maidenhead grid 2025-06-09 10:23:12 +01:00
srcejon
1aeac6e268 Map: Add World Magnetic Model data and show magnetic declination on map. 2025-06-09 10:18:05 +01:00
srcejon
d834c363b3 Add Cesium workaround for #1640 2025-06-09 10:14:12 +01:00
srcejon
d988aab950 Use Mode S roll data rather than estimated for map. 2025-06-09 10:13:15 +01:00
srcejon
c50097e420 Fix for Qt 5 2025-06-05 13:54:12 +01:00
srcejon
1baca797f6 Use aircraftPath 2025-06-05 13:53:34 +01:00
srcejon
6a9bba0656 Add CORS proxy for Emscripten. 2025-06-04 20:24:58 +01:00
srcejon
aa28bc700d Fix init order. 2025-06-04 20:22:43 +01:00
srcejon
96cc7a550f Remove unused variables. 2025-06-04 20:22:32 +01:00
srcejon
4678abf091 Use combined aircraft database.
Use png rather than bmp.
Add sideview images.
2025-06-04 20:22:09 +01:00
srcejon
276083d3e8 Fix for Qt5. 2025-06-04 19:28:47 +01:00
srcejon
13ecf0124e Add checklist widget 2025-06-04 18:23:53 +01:00
srcejon
db9ccd9ca8 Azel: Mark methods as const. 2025-06-04 18:15:59 +01:00
srcejon
1304926162 Add colour tracks to map. 2025-06-04 18:11:52 +01:00
srcejon
2aa2ad27da Add addtional map aircraft icons. 2025-06-04 18:11:20 +01:00
srcejon
1975c1748c Add additional demod stats.
Add analysis of Mode S frames in order to help filter out false positives.
Remove Boost. Use Profiler instead.
Fix crash if interrrupted before run.
Decode full preamble for Mode S frames.
Add support for additional Mode S downlink formats.
Allow demod stats to be reset.
Add timestamps for buffers, to ensure ordering of frames.
Add additional data columns (Aircraft Type, Sideview, Track,  Interrogator Code, TCAS, ACAS, RA, Max speed, Version, Length, Width, ADS-B/Mode S frame counts, radius, NACp, NACv, GVA, NIC, SIL, Stops).
Add PCE (Preamble Chip Errors) settings for Mode S demod.
Remove correlate full preamable setting.
Send aircraft state to Map feature for display on PFD.
Add support for airline route database.
Use combined aircraft database from sdrangel.org rather than OSN database.
Add stats table, with demod stats and breakdown of frame types received..
Add button to delete all aircraft from table.
Add display of interrogator code coverage.
Remove airport elevation setting as now calculated dynamically.
Add QNH setting.
Add coverage map.
Add chart of frame rate and aircraft count.
Add table/map orientation setting.
Add display of aircraft position uncertainty.
Add coloured flight paths with several palettes.
Add setting to favour airline livery over aircraft type in 3D model matching.
Only use 4 engine map icon for aircraft with 4 engines.
Add specialised aircraft map icons (Eurofighter, Spitfire, F35, A400M, Apache, Chinook, Glider)
Display aircraft route in labels.
Better validate local/global aircraft positions.
Add support for tc==31, aircraft operational status frames.
Add decoding of Mode S df 0, 11, 16 frames.
Add decoding of BDS 0,5 0,8, 0,9.
2025-06-04 18:05:10 +01:00
srcejon
f882747e97 Remove boost dependency and add charts and sideviews. 2025-06-04 17:01:41 +01:00
srcejon
f1aab5c97e Add additional ADS-B toolbar icons 2025-06-04 17:00:46 +01:00
srcejon
d453e164fa Add additional ADS-B map aircraft icons to better reflect aircraft categories. 2025-06-04 17:00:04 +01:00
srcejon
3b22d436ee Update flags 2025-06-04 16:59:06 +01:00
srcejon
4c1f99a7d2 Add aircraft sideviews. 2025-06-04 16:58:22 +01:00
srcejon
cd38c0d6a3 Convert airline logos from BMP to PNG to reduce size. 2025-06-04 16:56:58 +01:00
srcejon
91b83cff3b
Merge branch 'f4exb:master' into freq_scanner 2025-06-03 16:16:38 +01:00
f4exb
c333fb505c SSB Demod: clamp audio to 16 bit samples boundaries for better audio overdrive robustness. Fixes #2452 2025-06-02 22:01:21 +02:00
srcejon
b897b2176d Merge master 2025-06-02 12:10:21 +01:00
Edouard Griffiths
f7b9727ef9
Merge pull request #2450 from f4exb/fix-swagger
Fix swagger
2025-05-29 18:50:53 +02:00
f4exb
76b4623375 Upgrade Swagger UI to 5.22.0 and added WDSPRx.yaml to resources 2025-05-29 15:10:16 +02:00
f4exb
28077752a9 Swagger schema fixes 2025-05-29 12:48:11 +02:00
f4exb
3d3195489a Added Swagger schema validation container in the compose stack 2025-05-29 12:47:57 +02:00
f4exb
89d7fe736f Updated versions and changelogs 2025-05-04 20:01:51 +02:00
f4exb
2f47258605 Added Python script to control PlutoDVB2 2025-05-04 19:57:24 +02:00
f4exb
de4147b853 DATV demod: pass symbol rate in report 2025-05-04 01:44:51 +02:00
f4exb
002f5e8af3 Demod DATV: improve UDP TS output detection 2025-05-03 17:16:19 +02:00
f4exb
ce007419e8 DATV demod server plugin 2025-05-03 04:29:19 +02:00
f4exb
fc82606e6e DATV demod: completely remove LDPC external command references 2025-05-03 02:38:48 +02:00
f4exb
ab54ac7a63 DATV demod: prepare for server version 2025-05-03 01:43:35 +02:00
f4exb
379c802d39 Move datvideorender.h outside datvdemodsink.h 2025-05-02 23:57:25 +02:00
Edouard Griffiths
e6eb23d8a0
Merge pull request #2442 from srcejon/fix_2441
Try to fix Windows CI build
2025-04-23 11:43:39 +02:00
Jon Beniston
0111ce247b Try Python 3.12 for CI build as well. 2025-04-23 09:20:55 +01:00
Jon Beniston
c108f5be40 Try using Python 3.12 instead 2025-04-23 09:10:24 +01:00
Jon Beniston
1074bd0105 Try earlier versions to work around #2441 2025-04-23 08:40:40 +01:00
Jon Beniston
a5d1f48580 Try setup-python: true to fix #2441 2025-04-23 08:25:47 +01:00
f4exb
1c8d7bdaf1 AudioCATSISO: accept ttyS* serial ports for CAT. Fixes #2420 2025-04-21 14:34:53 +02:00
f4exb
77b2b815b8 Replace sprintf by snprintf wherever possible 2025-04-21 14:34:53 +02:00
Edouard Griffiths
2e1411311b
Merge pull request #2439 from srcejon/fix_qt_6_9
Fix build with Qt 6.9.0.
2025-04-21 14:34:01 +02:00
Edouard Griffiths
c8fed979d4
Merge pull request #2438 from mattsoftware/gs232_fixes
Also accept +0179+0001 as an acceptable gs232 format for reporting po…
2025-04-21 13:28:57 +02:00
Jon Beniston
60869b74f9 Fix build with Qt 6.9.0. 2025-04-21 10:59:54 +01:00
Matt Paine
88b2f29894 Comment out the debug statements 2025-04-21 19:22:21 +10:00
Matt Paine
fa6a801411 Also accept +0179+0001 as an acceptable gs232 format for reporting position 2025-04-21 10:59:09 +10:00
Edouard Griffiths
1c6b167527
Merge pull request #2433 from srcejon/fix_sat_tracker_doppler_crash
Fix sat tracker doppler crash
2025-04-17 17:38:28 +02:00
Jon Beniston
bafcb75313 Fix doppler correction. 2025-04-16 14:43:47 +01:00
Jon Beniston
e33d6e9b64 Satellite Tracker: Fix crash when doppler enabled. 2025-04-16 11:23:38 +01:00
Edouard Griffiths
7e6342624c
Merge pull request #2432 from srcejon/fix_2428
ChannelWebAPIUtils: Add double version of patchDeviceSetting.
2025-04-14 16:56:53 +02:00
Jon Beniston
90ddb54371 ChannelWebAPIUtils: Add double version of patchDeviceSetting. Fix #2428 2025-04-14 09:13:44 +01:00
f4exb
356e5e42be Use -DCMAKE_POLICY_VERSION_MINIMUM=3.5 for external packages Windows build 2025-04-05 21:59:21 +02:00
f4exb
c7e2a78903 Use SerialDV 1.1.5 2025-04-05 09:39:09 +02:00
Edouard Griffiths
8ff41d60fd
Merge pull request #2425 from lukolszewski/feature/adding-split-button
Split button added, swagger changed manually, but should be the same …
2025-04-05 01:03:37 +02:00
Łukasz Olszewski
5f74620406 Split button added, swagger changed manually, but should be the same when regenerated 2025-03-27 01:20:53 +01:00
srcejon
7a97bbfea0
Merge branch 'f4exb:master' into freq_scanner 2025-03-10 09:33:04 +00:00
Edouard Griffiths
81bae39a22
Merge pull request #2417 from srcejon/fix_2002
Update HackRF to v2024.02.1.
2025-03-09 11:41:36 +01:00
Jon Beniston
596544ade7 Update HackRF to v2024.02.1. For #2002 2025-03-08 09:33:18 +00:00
Edouard Griffiths
fed8856e1e
Merge pull request #2416 from srcejon/fix_2415
Update LimeSuite to latest version to fix Windows build
2025-03-08 00:51:48 +01:00
Jon Beniston
825c1d0759 Update LimeSuite to latest version, to fix #2415 2025-03-07 16:37:31 +00:00
srcejon
190b8c6aeb
Merge branch 'f4exb:master' into freq_scanner 2025-03-07 16:25:34 +00:00
Edouard Griffiths
0c502c59f8
Merge pull request #2414 from srcejon/fix_2283
Fix HackRF support
2025-03-07 09:33:44 +01:00
Jon Beniston
ad46defda9 Merge branch 'fix_2283' of https://github.com/srcejon/sdrangel into fix_2283 2025-03-06 17:12:01 +00:00
Jon Beniston
42a674037f HackRfInput: Call applySettings before starting thread, otherwise HackRF will not start correctly. Handle not all settingsKeys being set, when adjusting centre frequency. 2025-03-06 17:11:35 +00:00
Jon Beniston
3c9931bc59 LoadConfigurationFSM::loadDeviceSets: Wait 250ms to allow devices to initialise, as DeviceGUI::sendSettings has 100ms delay. 2025-03-06 17:09:16 +00:00
srcejon
cb5d921e68 Add altitudeDateTime to MapItem 2025-03-06 13:55:38 +00:00
srcejon
5ae5641f99
Merge branch 'f4exb:master' into freq_scanner 2025-03-06 13:46:24 +00:00
Edouard Griffiths
b3f83c33fa
Merge pull request #2410 from srcejon/fix_2324
wdsp: Remove redundant code that causes stack overflow on Mac.
2025-03-05 07:21:32 +01:00
Jon Beniston
c40da37faf wdsp: Remove redundant code that causes stack overflow on Mac. For #2324. 2025-02-27 13:20:44 +00:00
Edouard Griffiths
ba673bf3a2
Merge pull request #2402 from srcejon/fix_2401
Fix -DBUILD_SHARED_LIBS=ON for FLAC
2025-02-16 21:05:19 +01:00
Jon Beniston
082a07d39b Fix -DBUILD_SHARED_LIBS=ON for FLAC 2025-02-16 18:11:37 +00:00
Edouard Griffiths
d24c552d24
Merge pull request #2397 from srcejon/mac_ci
Mac x64 build for Mac OS 12
2025-02-10 03:29:44 +01:00
Edouard Griffiths
31ab1480d0
Merge pull request #2394 from srcejon/fix_2242
Radiosonde: Fix pressure calculation.
2025-02-09 10:14:27 +01:00
srcejon
08537b5a5a Add callsign to aircraft state 2025-02-04 16:00:04 +00:00
srcejon
4627be2e50 Add labelDateTime to MapItem 2025-02-04 13:51:52 +00:00
Jon Beniston
7f20ca0a6d Fix indent 2025-02-04 12:04:51 +00:00
Jon Beniston
310df0046c Try setting MACOSX_DEPLOYMENT_TARGET to see if it can run on older MacOSes. 2025-02-04 12:03:13 +00:00
srcejon
3c5ce69846
Merge branch 'f4exb:master' into freq_scanner 2025-02-04 11:02:29 +00:00
Jon Beniston
b653117360 Fix lint warnings. 2025-02-03 14:04:43 +00:00
Jon Beniston
a2f8428352 Radiosonde: Fix pressure calculation. #2242 2025-02-03 13:58:46 +00:00
f4exb
e6b3e50fd2 Updated version and changelog 2025-02-02 19:09:22 +01:00
Edouard Griffiths
504684c609
Merge pull request #2389 from srcejon/fix_2364
Update snap to use UHD 4.7.
2025-01-26 09:56:52 +01:00
Jon Beniston
fc64424377 Update snap to use UHD 4.7. 2025-01-25 15:57:43 +00:00
Edouard Griffiths
89e392e91f
Merge pull request #2386 from srcejon/fix_2384
Fix gcc warnings about warning options
2025-01-25 10:21:50 +01:00
srcejon
23279d2f46 Fix gcc warnings about warning options 2025-01-23 22:57:16 +00:00
Edouard Griffiths
d7863b25c6
Merge pull request #2385 from srcejon/mac_ci
Update Mac Github actions
2025-01-23 21:53:11 +01:00
Edouard Griffiths
6ded8f079b
Merge pull request #2383 from srcejon/fix_file_sink_ui
FileSink: Add minimum width constraint so widgets don't move around a…
2025-01-23 20:47:12 +01:00
srcejon
d524bf2057
Merge branch 'f4exb:master' into mac_ci 2025-01-23 14:31:04 +00:00
Jon Beniston
6df8b94637 Try to fix arm build as well. 2025-01-23 11:02:37 +00:00
Edouard Griffiths
19d8a1da0f
Merge pull request #2382 from srcejon/fix_2378
Radiosonde: Add option to display predicted paths.
2025-01-23 10:26:24 +01:00
Jon Beniston
2ea5ef220b Add set +e to allow script to continue on error 2025-01-23 08:53:01 +00:00
Jon Beniston
9ea7ade57f Try continue-on-error: true to allow make to be retried 2025-01-22 21:38:22 +00:00
Jon Beniston
c9c9febe41 Use version 4.1 of x265 as master is broken on Mac. 2025-01-22 21:38:00 +00:00
Jon Beniston
4519e512c6 Retry make package in case hdituil fails 2025-01-22 20:45:22 +00:00
srcejon
2248b42a06
Merge branch 'f4exb:master' into mac_ci 2025-01-22 20:35:49 +00:00
Jon Beniston
7af58538b6 FileSink: Add minimum width constraint so widgets don't move around as dials are changed. 2025-01-21 13:47:47 +00:00
Jon Beniston
9f61152d37 Merge branch 'fix_2378' of https://github.com/srcejon/sdrangel into fix_2378 2025-01-21 13:33:17 +00:00
Jon Beniston
52d59b8609 Radiosonde: Add option to display predicted paths. 2025-01-21 13:33:11 +00:00
Edouard Griffiths
6b30f17361
Merge pull request #2381 from srcejon/fix_2359
Add --start command line option to start all devices and features.
2025-01-21 14:33:07 +01:00
Jon Beniston
2f280ec06a Radiosonde: Fix radio type sent to SondeHub 2025-01-21 10:41:01 +00:00
Edouard Griffiths
3c7fd19f59
Merge pull request #2380 from srcejon/fix_2375
Fix SSB Mod Morse keyer
2025-01-20 22:28:59 +01:00
Edouard Griffiths
e38e2e773f
Merge pull request #2379 from srcejon/fix_2378
Radiosonde: Rate limit position updates to SondeHub.
2025-01-20 21:06:42 +01:00
Jon Beniston
f841eecab9 Add --start option to start all devices and features. For #2359. 2025-01-20 10:54:21 +00:00
Jon Beniston
b2a1dc3569 Fix SSB Mod Morse keyer 2025-01-20 09:25:33 +00:00
Jon Beniston
9c64424cec Display errors from SondeHub as warnings rather than debug. 2025-01-19 13:09:55 +00:00
Jon Beniston
a3692309c0 Radiosonde: Rate limit position updates to SondeHub. Fixes #2378. 2025-01-19 13:09:16 +00:00
Edouard Griffiths
83b36c6aab
Merge pull request #2377 from srcejon/sid_fix_read_csv
SID: Fix crash when loading data from .csv.
2025-01-19 10:43:18 +01:00
Jon Beniston
c62a25f40a Undo auto-format. 2025-01-17 13:33:53 +00:00
Jon Beniston
86ac92e63e SID: Fix crash when loading data from .csv. 2025-01-17 13:31:19 +00:00
Edouard Griffiths
aa65bd5b39
Merge pull request #2371 from das-Iro/colormap-acab
Added "All Colors Are Beautiful" colormap
2025-01-11 00:18:46 +01:00
Arne Jünemann
4203e72e12 Added All Colors Are Beautiful colormap 2025-01-10 15:53:30 +01:00
srcejon
73f345792d Add date and time for interpolatable properties 2025-01-05 20:47:19 +00:00
srcejon
5eeae7c231 Add type and onSurface fields 2025-01-05 10:24:33 +00:00
srcejon
67dec1dd83 Fix spelling 2025-01-03 11:43:18 +00:00
srcejon
4e3545cf0e Add aircraft state to MapItem 2025-01-03 11:30:35 +00:00
Edouard Griffiths
3f7e1193fa
Merge pull request #2369 from tyrylu/right_click_using_keyboard
right-click-enabler: Allow activation of the right click action by keyboard
2025-01-02 18:10:47 +01:00
Lukáš Tyrychtr
c2652d3ee5 right-click-enabler: Allow activation of the right click action by keyboard
This allows for example, selecting the audio output device for visually
impaired.
2024-12-28 18:19:54 +01:00
Edouard Griffiths
51b540cf72
Merge pull request #2365 from srcejon/usrp_gpio
Add GPIO support for USRP devices
2024-12-25 21:02:23 +01:00
Edouard Griffiths
70d090101a
Merge pull request #2363 from srcejon/freq_scanner
ADS-B: Fix OpenSky authentication to enable 4000 API calls per day.
2024-12-25 20:11:19 +01:00
Jon Beniston
d3584f6af2 RemoteTCPSink: Handle client disconnecting immediately. 2024-12-24 13:25:14 +00:00
Jon Beniston
c5efd73f6b Document GPIOs. 2024-12-24 12:56:36 +00:00
Jon Beniston
4510f40729 ChannelWebAPIUtils::patchDeviceSetting: Add support for sinks and MIMO. 2024-12-24 12:49:10 +00:00
Jon Beniston
56bd20d59b USRP: Implement GPIO settings. 2024-12-24 12:48:43 +00:00
srcejon
a4269dcd78 Add GPIO pins to USRP and regen swagger 2024-12-24 10:59:35 +00:00
srcejon
9f661aee30 ADS-B: Fix OpenSky authentication to enable 4000 API calls per day. 2024-12-20 16:34:11 +00:00
Edouard Griffiths
35088962fe
Merge pull request #2362 from srcejon/freq_scanner
Fix Win32 plugin directory for Qt6 build
2024-12-18 15:50:07 +01:00
srcejon
930e4d7e50 Fix Win32 plugin directory for Qt6 build 2024-12-18 09:33:15 +00:00
Edouard Griffiths
f4e2d10055
Merge pull request #2357 from srcejon/fix_2336
Fix audio modulators when channel sample rate is greater than audio sample rate
2024-12-10 21:46:39 +01:00
Jon Beniston
68126592ad Fix naming of Kazakhstan flag 2024-12-10 14:05:19 +00:00
Jon Beniston
5ea872fe30 Add additional DSC coast stations. 2024-12-10 14:04:47 +00:00
Jon Beniston
7dec953ade DSC: Use coast stations of rmessage source as well. 2024-12-10 10:46:12 +00:00
Jon Beniston
1462890a77 Fix modulators when channel sample rate is greater than audio sample rate. 2024-12-10 10:45:48 +00:00
Edouard Griffiths
d696dd66a0
Merge pull request #2355 from srcejon/dsc_coast_station_names
DSC Demod: Add coast station names.
2024-12-09 21:03:04 +01:00
Jon Beniston
107d1ee6c8 Fix lint warnings. 2024-12-09 12:03:34 +00:00
Jon Beniston
4a8adc4a42 DSC: Add coast station names. 2024-12-09 11:58:17 +00:00
Jon Beniston
a9385cb91c macos-14 is arm only 2024-12-05 14:40:08 +00:00
Jon Beniston
ec0ffa005a Try macos-14, as 13 fails due to https://github.com/actions/runner-images/issues/7522 2024-12-05 13:11:08 +00:00
Jon Beniston
405073d198 Install svn needed to build lame 2024-12-05 10:15:18 +00:00
Jon Beniston
88c5554970 Update mac_x64 build to macos-13, as github no longer supports 12. 2024-12-05 09:08:02 +00:00
f4exb
c4e57a1696 Updated versions and changelogs 2024-12-05 02:10:24 +01:00
Edouard Griffiths
99011d8bbc
Merge pull request #2347 from srcejon/win_code_sign
Upload signed releases rather than unsigned releases to Github
2024-12-03 15:11:01 +01:00
Jon Beniston
d86dbbade9 Upload signed releases rather than unsigned releases to Github releases page.
Only sign releases, not all pull requests.
2024-12-02 22:41:18 +00:00
Edouard Griffiths
87a3d9dea7
Merge pull request #2344 from srcejon/win_code_sign
Windows code signing update
2024-12-02 20:11:39 +01:00
Jon Beniston
c0b8620baa Increase timeout to 1 hour 2024-12-02 13:50:24 +00:00
Jon Beniston
4b714dfaa5 Remove unzip step, as it appears we get a .exe 2024-12-02 13:46:56 +00:00
f4exb
ec4d14be3f FT8 Demod: limit upper bandwidth to 5.8 kHz 2024-12-02 13:01:22 +01:00
Edouard Griffiths
1f0a8e3690
Merge pull request #2342 from srcejon/fix_2332
Stop device while loading device set.
2024-11-26 23:09:14 +01:00
Edouard Griffiths
5ba42f1866
Merge pull request #2341 from srcejon/fix_aircraft_db
ADSB: Update URL of OpenSkyNetwork Aircraft database.
2024-11-26 17:57:57 +01:00
Jon Beniston
3c3e5cf3df Stop device while changing channel set. Fixes #2332 2024-11-26 11:52:30 +00:00
Jon Beniston
943a1fb56c ADSB: Update URL of OpenSkyNetwork Aircraft database. 2024-11-26 10:41:48 +00:00
Edouard Griffiths
460ebfbeb2
Merge pull request #2340 from srcejon/fix_2315
Fix crash and audio mod
2024-11-26 09:47:11 +01:00
srcejon
a91fa3b760 Don't stop source if being deleted. For #2315. Send DSPSignalNotification in audio mods for #2336. 2024-11-25 17:16:08 +00:00
Edouard Griffiths
d0cae88ba8
Merge pull request #2338 from srcejon/fix_2337
RadioSonde: Limit precision of floating point numbers sent to SondeHub.
2024-11-19 16:27:50 +01:00
Edouard Griffiths
30a0198862
Merge pull request #2335 from srcejon/win_code_sign
Code Signing: Use relative path. Increase approval timeout to 30 minutes.
2024-11-19 10:11:14 +01:00
Jon Beniston
7b7f9e2c06 Limit precision of floating point numbers sent to SondeHub. 2024-11-18 09:48:50 +00:00
Jon Beniston
a12d664055 Use relative path. Increase timeout to 30 minutes. 2024-11-16 10:48:26 +00:00
Edouard Griffiths
5cc7b3ac33
Merge pull request #2334 from srcejon/fix_2333
ADSB: Include adsbdemodsettings.h
2024-11-16 10:38:53 +01:00
Jon Beniston
4465e1e8b8 ADSB: Include adsbdemodsettings.h 2024-11-15 13:00:39 +00:00
Edouard Griffiths
4da9a34c87
Merge pull request #2331 from srcejon/win_code_sign
Use release signing certificate for Windows installer.
2024-11-14 15:18:19 +01:00
Edouard Griffiths
7bc6210b64
Merge pull request #2330 from srcejon/fix_2315
Fix a few memory leaks and race conditions
2024-11-14 14:31:09 +01:00
Jon Beniston
f8a991e4a3 Use release signing certificate for Windows installer. 2024-11-14 12:40:01 +00:00
srcejon
6dcc342c10 Fix memory leak and race condition relating to DSP*Engines. Part of #2159 2024-11-14 11:42:53 +00:00
srcejon
7c7a7d7c1e FreeDV: Fix memory allocation/free issues. Part of #2315. 2024-11-14 11:40:46 +00:00
Edouard Griffiths
0a94970a70
Merge pull request #2328 from srcejon/freq_scanner
DemodAnalyzer: Ensure sample rate is set in worker.
2024-11-12 23:16:04 +01:00
srcejon
875f16f12a Wav Files: Add support for meta-data. 2024-11-12 20:36:33 +00:00
srcejon
c4733a3645 DemodAnalyzer: Ensure sample rate is set in worker. Fixes #2309. 2024-11-12 20:36:10 +00:00
Edouard Griffiths
585841e787
Merge pull request #2327 from srcejon/fix_2322
SDRplayv3: Patch path to libsdrplay_api.so.3
2024-11-12 21:16:46 +01:00
Edouard Griffiths
bba9d0b421
Merge pull request #2326 from srcejon/fix_1734
ADS-B: Fix memory use after delete.
2024-11-12 20:23:35 +01:00
Jon Beniston
600e338bab SDRplayv3: Mac now appears to link with libsdrplay_api.so.3 rather than libsdrplay_api.so.3.15. 2024-11-12 15:38:34 +00:00
srcejon
f03499a9a3 ADS-B: Fix memory use after delete. For #1734 and part of #2315 2024-11-12 12:39:14 +00:00
f4exb
73533231a5 Fixed Appveyor Docker image build 2024-11-12 11:01:48 +01:00
Edouard Griffiths
d52179dbe2
Merge pull request #2323 from srcejon/win_code_sign
Windows Signing: Fix output-artifact-directory and unzip file.
2024-11-12 10:58:44 +01:00
Jon Beniston
a7c67a8540 Fix output-artifact-directory and unzip file. 2024-11-11 16:53:52 +00:00
f4exb
cb4651af0b Fixed Appveyor Docker image build 2024-11-11 17:15:20 +01:00
f4exb
ba6a3cc665 Updated versions and changelogs 2024-11-11 09:46:29 +01:00
Edouard Griffiths
9f95769608
Merge pull request #2321 from srcejon/mac_ci
Use macos-12 for Mac x86 build
2024-11-10 20:58:31 +01:00
Edouard Griffiths
ca76d5fbae
Merge pull request #2320 from srcejon/fix_2319
Pager: Add Add notifications based on alpha and numeric columns.
2024-11-10 18:05:51 +01:00
Jon Beniston
d7547e2d25 Pager: Add alpha and numeric columns. Implements #2319 2024-11-10 15:48:36 +00:00
Jon Beniston
d53aa60112 Merge branch 'mac_ci' of https://github.com/srcejon/sdrangel into mac_ci 2024-11-10 14:09:53 +00:00
Jon Beniston
8284388862 nasm and subversion already installed in brew - and upgrade fails. 2024-11-10 14:09:47 +00:00
srcejon
d69ca4d1f6
Merge branch 'f4exb:master' into mac_ci 2024-11-10 12:53:53 +00:00
Jon Beniston
43077fc549 Add mac into dmg filename 2024-11-10 10:13:03 +00:00
Jon Beniston
1ca63912b6 Try macos-12 2024-11-10 10:04:51 +00:00
Edouard Griffiths
86f4a5bc69
Merge pull request #2316 from srcejon/win_qt6
Fix missing 3D map and Sky Map from latest Windows release.
2024-11-10 09:47:02 +01:00
Jon Beniston
b96b4b60b4 Workaround for "hdiutil: create failed - Resource busy" 2024-11-09 22:32:18 +00:00
Jon Beniston
3da2074d9d Add qtwebchannel needed by qtwebengine. 2024-11-09 21:50:13 +00:00
f4exb
ae5dc866c7 Updated versions and changelogs 2024-11-09 18:46:38 +01:00
Edouard Griffiths
bf837e0e02
Merge pull request #2314 from gl-bars/AddDebDependencies
Add deb dependencies
2024-11-08 20:12:36 +01:00
Gleb Baryshev
b6816fe886 Add deb dependencies 2024-11-08 14:04:58 +02:00
Edouard Griffiths
f09a1259e4
Merge pull request #2313 from srcejon/freq_scanner
Support more Qt configurations
2024-11-07 08:31:05 +01:00
srcejon
5bffac3eaa Merge branch 'freq_scanner' of https://github.com/srcejon/sdrangel into freq_scanner 2024-11-06 13:14:55 +00:00
srcejon
197ac366e2 Support compilation when QT_NO_NETWORKINTERFACE is defined (E.g. WebAssembly) 2024-11-06 12:27:06 +00:00
srcejon
14063a80e9 Support compilation without SSL support. 2024-11-06 12:12:46 +00:00
srcejon
8ed7972dce Support compilation on Qt platforms that don't support processes (i.e. WebAssembly). 2024-11-06 12:11:49 +00:00
srcejon
2abe88368b Use ENABLE_METIS option 2024-11-06 11:58:44 +00:00
Edouard Griffiths
06678a5978
Merge pull request #2311 from srcejon/win_code_sign
Windows code signing: Use test certificate
2024-11-05 23:13:45 +01:00
Edouard Griffiths
29bac274d6
Merge pull request #2310 from srcejon/freq_scanner
Frequency scanner: Add multiplex mode
2024-11-05 13:34:32 +01:00
Jon Beniston
eceedd5db8 Windows code signing: Use test certificate until release certificate is available. 2024-11-05 11:12:14 +00:00
srcejon
98481a96e9 Fix path to resources. 2024-11-05 10:38:13 +00:00
srcejon
28faddea1d ADS-B: Use settings keys. 2024-11-05 10:31:32 +00:00
srcejon
a9f25b3642 AIS Demod: Remove spacing around messages, to make better use of available space. 2024-11-05 10:09:34 +00:00
srcejon
1235f71388 Freuqency Scanner: Add multiplex mode. 2024-11-05 10:09:09 +00:00
f4exb
e277e4fc1f Github actions: use upload-artifact v4 to comply with nodejs requirements 2024-11-03 19:57:55 +01:00
Edouard Griffiths
fcc1bca5a0
Merge pull request #2307 from srcejon/win_code_sign
Add github action to test code signing on Windows using SignPath.
2024-11-03 09:16:19 +01:00
Jon Beniston
b8fc311997 Add github action to test code signing on windows using SignPath. 2024-11-02 16:16:09 +00:00
Edouard Griffiths
9161fc1c05
Merge pull request #2306 from srcejon/snap
Don't build Snaps on pull requests
2024-11-02 16:44:20 +01:00
Edouard Griffiths
fd168e881a
Merge pull request #2305 from srcejon/linux_github_release
github action to build ubuntu 22.04 and 24.04 release .debs
2024-11-02 15:31:07 +01:00
Jon Beniston
df6cefbd69 Merge branch 'snap' of https://github.com/srcejon/sdrangel into snap 2024-11-02 10:07:52 +00:00
Jon Beniston
23a8fdeb86 Don't build snap on pull requests. 2024-11-02 10:07:41 +00:00
Jon Beniston
feabcef336 libgl1-mesa-glx replaced by libgl1 and libglx-mesa0, 2024-11-02 08:56:21 +00:00
Edouard Griffiths
b122d40bce
Merge pull request #2304 from srcejon/freq_scanner
Server: Use Sink/MIMO signals rather than Source.
2024-11-02 08:53:11 +01:00
Edouard Griffiths
8346cc4988
Merge pull request #2303 from srcejon/mac_ci
Add github action to build releases for Mac
2024-11-02 05:18:58 +01:00
Edouard Griffiths
067324edd9
Merge pull request #2302 from srcejon/snap
Add github action to build and publish Snap
2024-11-01 23:16:02 +01:00
Jon Beniston
c72a72b3f8 ubuntu-20.04 doesn't support required version of cmake 2024-11-01 22:01:42 +00:00
Jon Beniston
763438c7e5 Use short sha 2024-11-01 21:33:38 +00:00
Jon Beniston
00df25ff63 Try ubuntu-20.04 2024-11-01 21:31:45 +00:00
Jon Beniston
8f030d9ea5 Upload artifact doesn't like relative paths. 2024-11-01 19:57:29 +00:00
Jon Beniston
bd8853f2e9 Build for both ubuntu-22.04 and ubuntu-24.04 2024-11-01 18:58:26 +00:00
Jon Beniston
8c7e650f8f Update limesuite to v23.11.0 to see if it builds on ubuntu-24.04 2024-11-01 18:57:37 +00:00
Jon Beniston
e6e6084e1c Try ubuntu-22.04 2024-11-01 18:01:19 +00:00
Jon Beniston
dc330b7d5b Remove libclang1-11 2024-11-01 17:47:33 +00:00
Jon Beniston
1ecaa22721 Trial .deb build 2024-11-01 17:42:11 +00:00
srcejon
d516e9529d
Merge branch 'f4exb:master' into freq_scanner 2024-11-01 16:32:59 +00:00
srcejon
9afab2af89 Server: Use Sink/MIMO signals rather than Source. 2024-11-01 16:32:39 +00:00
Jon Beniston
4f36b21d2e Use macos-14 image to build on ARM which is twice as fast. 2024-11-01 16:28:23 +00:00
Edouard Griffiths
e8041308b1
Merge pull request #2301 from srcejon/freq_scanner
RemoteTCPSink: Disable IQ compression for RTL0 protocol.
2024-11-01 17:24:55 +01:00
srcejon
b04d7eb10a RemoteTCPSink: Does use IQ only setting for RTL0. 2024-11-01 13:42:23 +00:00
Jon Beniston
441c47c35f Install python manually. 2024-11-01 13:30:36 +00:00
Jon Beniston
9bd001c9ed Update to github releases 2024-11-01 12:49:39 +00:00
Jon Beniston
4ba1340e8e Merge branch 'mac_ci' of https://github.com/srcejon/sdrangel into mac_ci 2024-11-01 12:47:02 +00:00
Jon Beniston
1094874321 Remove test code. 2024-11-01 12:46:53 +00:00
srcejon
84251abda7
Merge branch 'f4exb:master' into mac_ci 2024-11-01 12:46:23 +00:00
Jon Beniston
fa4f9c2d82 Update snap to github releases and snap store. 2024-11-01 12:21:59 +00:00
srcejon
7f275f2a3e
Merge branch 'f4exb:master' into snap 2024-11-01 12:05:46 +00:00
Jon Beniston
ff56523865 Try Python3_FIND_FRAMEWORK=NEVER 2024-11-01 11:43:28 +00:00
Jon Beniston
1653698f99 Try -DPYTHON_EXECUTABLE again 2024-11-01 11:37:55 +00:00
Jon Beniston
a9dbfea8d1 Try bin 2024-11-01 11:16:00 +00:00
Jon Beniston
7a9b5ee068 Try Python3_ROOT_DIR 2024-11-01 10:48:36 +00:00
Jon Beniston
8e81d3825a Update boost to latest release. 1.78 fails to build using c++17
Update UHD to 4.7 and set -DENABLE_PYTHON_API=OFF to try to remove runtime python requirement.
2024-11-01 10:10:31 +00:00
f4exb
bd67d553ea Main server: wait for set sample source/sink/MIMO to complete before loading the device settings. For #2294 2024-11-01 10:32:39 +01:00
Jon Beniston
03f4dfe2e1 Add target option 2024-11-01 09:11:32 +00:00
Jon Beniston
28d0b73bc5 Install SDRplay API 2024-11-01 09:08:25 +00:00
Jon Beniston
0bfef9de14 Add x64 build. Try to build DATV. 2024-11-01 08:08:19 +00:00
Jon Beniston
622958bdb5 Use hash for ci builds 2024-10-31 21:16:19 +00:00
Jon Beniston
5c41fe8342 Build in one step, as faster 2024-10-31 21:12:36 +00:00
Jon Beniston
32a9144f55 Don't use absolute path, as build directory may be somewhere else. 2024-10-31 21:12:15 +00:00
Jon Beniston
e707d75624 Update OpenCV as fails to compile with c++17 2024-10-31 18:57:08 +00:00
Jon Beniston
868bfea65e Disble USRP for now. 2024-10-31 18:10:27 +00:00
Jon Beniston
9d3fe6e86e Try DPYTHON_EXECUTABLE 2024-10-31 17:13:19 +00:00
Jon Beniston
d9f36dc508 Try venv 2024-10-31 16:41:05 +00:00
Jon Beniston
e35133b741 Try pipx 2024-10-31 16:28:29 +00:00
Jon Beniston
3df03768d2 Is pip3 already installed? 2024-10-31 16:22:50 +00:00
Jon Beniston
4d6d97538c Fix syntax 2024-10-31 16:07:48 +00:00
Jon Beniston
ede06e2ca8 Fix version name. 2024-10-31 16:05:50 +00:00
Jon Beniston
f124186366 Add python packages for UHD 2024-10-31 15:33:00 +00:00
Edouard Griffiths
618e234d6c
Merge pull request #2299 from srcejon/fix_2282
Fix spectrum peak measurement for SSB spectra.
2024-10-31 16:25:14 +01:00
Jon Beniston
7bab142af1 usrpoutput: add_dependencies needs to follow add_library 2024-10-31 15:16:08 +00:00
Jon Beniston
11614b417b Add brew subversion and nasm.
Add qtwebchannel as appears to be needed by qtwebengine.
2024-10-31 14:50:06 +00:00
Jon Beniston
729d663832 Add id to try to fix "Input required and not supplied: path" in upload-artifact 2024-10-31 14:38:52 +00:00
Jon Beniston
e5fa27ba96 Try removing setup-python 2024-10-31 14:34:48 +00:00
Edouard Griffiths
4b37779e9e
Merge pull request #2298 from srcejon/fix_2297
Update some example scripts to python3
2024-10-31 15:14:00 +01:00
Jon Beniston
46e8688de2 Install Qt 6 2024-10-31 14:03:21 +00:00
Jon Beniston
fceee07486 Remove nehalem for arm build 2024-10-31 13:56:29 +00:00
Jon Beniston
a108d0b986 Merge branch 'mac_ci' of https://github.com/srcejon/sdrangel into mac_ci 2024-10-31 13:53:56 +00:00
Jon Beniston
362e23bea0 Add github action to build Mac release 2024-10-31 13:53:45 +00:00
Jon Beniston
5ac77fca98 Try snapcore/action-build instead 2024-10-31 13:31:05 +00:00
Jon Beniston
ab13f94cf0 Add github action to build snap. 2024-10-31 13:21:34 +00:00
Jon Beniston
764bce52fe Fix spectrum peak measurement for SSB spectra. Fixes #2282. 2024-10-31 12:42:46 +00:00
srcejon
b37c7f6cb9 Update some example scripts to python3 2024-10-31 11:50:40 +00:00
f4exb
35aa393f11 Upgrade C++ standard to c++17 2024-10-23 21:32:13 +02:00
Edouard Griffiths
ed89eea72c
Merge pull request #2288 from srcejon/android_fixes
Fix Android build
2024-10-22 17:01:58 +02:00
Edouard Griffiths
f6f2d9bee7
Merge pull request #2287 from srcejon/win_qt6
Use Qt 6 for Windows github build
2024-10-22 01:45:01 +02:00
Jon Beniston
66247ec6fd Fix for Qt5 2024-10-21 18:28:21 +01:00
Jon Beniston
dbbf1918ab Fix Android build 2024-10-21 17:15:27 +01:00
Jon Beniston
77895090dc Fix Android build 2024-10-21 17:13:11 +01:00
Jon Beniston
2538662c9b Fixes for Android 2024-10-21 17:11:55 +01:00
Jon Beniston
89134729cc Don't build aaroniartsainput on Android 2024-10-21 17:10:51 +01:00
Jon Beniston
2132ac8ed2 Fix Qt5 Android build 2024-10-21 17:10:22 +01:00
Jon Beniston
7ed543ec35 Initialise m_displayRailways 2024-10-21 17:10:03 +01:00
Jon Beniston
907fe25d3c Fix plugin names for Qt6 Android 2024-10-21 17:09:32 +01:00
Jon Beniston
427d17351d Remove use of obsolete QRegExp 2024-10-21 17:08:41 +01:00
Jon Beniston
b6146caf36 Fix for Android Qt6 2024-10-21 17:05:19 +01:00
Jon Beniston
de37c031b5 Remove unused obsolete header 2024-10-21 17:03:54 +01:00
Jon Beniston
ac49a480f4 Remove test code 2024-10-20 13:05:29 +01:00
Jon Beniston
31cbe96b4c Add qtshadertools 2024-10-20 12:09:11 +01:00
Jon Beniston
5b9e61d839 WebEngine install not supported for 6.8 yet. 2024-10-20 11:19:29 +01:00
Jon Beniston
e3af72febb Add qtwebview - Is this the only way to include web engine? 2024-10-20 10:51:07 +01:00
Jon Beniston
aaf9f53571 Add qtwebsockets 2024-10-20 10:41:48 +01:00
Jon Beniston
9171ae9cd7 Add more Qt modules and set ENABLE_QT6=ON 2024-10-20 10:35:24 +01:00
Jon Beniston
0b84a572d6 Update Qt optional packages for 6.8 2024-10-20 10:23:56 +01:00
Jon Beniston
ec2f62fa5c Allow build test. Remove later. 2024-10-20 09:58:24 +01:00
Jon Beniston
a47c0913b5 Use Qt 6.8 for Windows build 2024-10-20 09:53:25 +01:00
13139 changed files with 71779 additions and 7631 deletions

View File

@ -20,118 +20,118 @@ environment:
# -DBUILD_SERVER=OFF \
# -DCMAKE_PREFIX_PATH=C:\\Qt\\5.15.2\\msvc2019_64;C:\\Libraries\\boost_1_73_0"
# CMAKE_GENERATOR: Ninja
- TARGET: ubuntu2204prod
APPVEYOR_BUILD_WORKER_CLOUD: nasrock Docker
APPVEYOR_BUILD_WORKER_IMAGE: Linux
CC: "gcc-11"
CXX: "g++-11"
CMAKE_CUSTOM_OPTIONS: "-DCMAKE_BUILD_TYPE=Release \
-DARCH_OPT=nehalem \
-DDEBUG_OUTPUT=ON \
-DENABLE_EXTERNAL_LIBRARIES=AUTO \
-DBUILD_SERVER=OFF"
# - TARGET: ubuntu2204prod
# APPVEYOR_BUILD_WORKER_CLOUD: nasrock Docker
# APPVEYOR_BUILD_WORKER_IMAGE: Linux
# CC: "gcc-11"
# CXX: "g++-11"
# CMAKE_CUSTOM_OPTIONS: "-DCMAKE_BUILD_TYPE=Release \
# -DARCH_OPT=nehalem \
# -DDEBUG_OUTPUT=ON \
# -DENABLE_EXTERNAL_LIBRARIES=AUTO \
# -DBUILD_SERVER=OFF"
- TARGET: ubuntu2204docker
APPVEYOR_BUILD_WORKER_CLOUD: nasrock
APPVEYOR_BUILD_WORKER_IMAGE: Linux
APPVEYOR_CONSOLE_DISABLE_PTY: true
for:
# - matrix:
# only:
# - TARGET: 'vs2019gui'
# cache:
# - C:\ProgramData\chocolatey\bin
# - C:\ProgramData\chocolatey\lib
# build_script:
# - call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
# # Install GNU patch as applying patches with git fails in BladeRF tree
# - choco install patch
# - git submodule update --init --recursive
# - mkdir build && cd build
# - cmake .. -G "%CMAKE_GENERATOR%" %CMAKE_CUSTOM_OPTIONS%
# - cmake --build . --config Release --target package
# artifacts: # push installer executable
# path: build\*.exe
# name: installer
# deploy:
# release: sdrangel-v$(appveyor_build_version)
# description: 'SDRangel Windows'
# provider: GitHub
# auth_token:
# secure: kyU5TaXRoily6q/QLRLqal2xCFGWEdnb8AJIu7FknsUQyj1wjRGmqC2My+Wfszod
# artifact: installer, portable
# draft: false
# prerelease: false
# tag: $(APPVEYOR_REPO_TAG_NAME) # will not work until tag is pushed
# on:
# APPVEYOR_REPO_TAG: true # deploy on tag push only
# branch: master # release from master branch only
- matrix:
only:
- TARGET: ubuntu2204prod
clone_folder: /home/appveyor/projects
cache:
- $HOME/external/
install:
- sh: sudo apt-get update
- sh: echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections
# not sdrplay with soapysdr; libairspyhf-dev is too old (no lna)
- sh: |
sudo apt-get -y install build-essential cmake git xxd \
devscripts fakeroot debhelper libfftw3-dev qtbase5-dev libopengl-dev libqt5opengl5-dev \
qttools5-dev qttools5-dev-tools qtmultimedia5-dev libqt5multimedia5-plugins libqt5websockets5-dev \
libqt5quick5 qtwebengine5-dev qtbase5-private-dev \
qml-module-qtlocation qml-module-qtpositioning qml-module-qtquick-window2 qml-module-qtquick-dialogs \
qml-module-qtquick-controls qml-module-qtquick-controls2 qml-module-qtquick-layouts qml-module-qtgraphicaleffects \
libqt5serialport5-dev qtdeclarative5-dev qtpositioning5-dev qtlocation5-dev \
libqt5charts5-dev libqt5texttospeech5-dev libqt5gamepad5-dev libqt5svg5-dev libfaad-dev libflac-dev zlib1g-dev \
libusb-1.0-0-dev libhidapi-dev libboost-all-dev libasound2-dev libopencv-dev libopencv-imgcodecs-dev \
libxml2-dev bison flex ffmpeg libpostproc-dev libavcodec-dev libavformat-dev \
libopus-dev libcodec2-dev libairspy-dev libhackrf-dev \
libbladerf-dev libsoapysdr-dev libiio-dev libuhd-dev libhamlib-dev \
python3-mako python3-cheetah python3-numpy \
autoconf automake libtool ninja-build libclang1-11
- sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_cm256cc.sh; fi
- sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_mbelib.sh; fi
- sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_serialdv.sh; fi
- sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_dsdcc.sh; fi
- sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_perseus-sdr.sh; fi
- sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_xtrx-sdr.sh; fi
- sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_airspyhf.sh; fi
- sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_rtlsdr.sh; fi
- sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_limesuite.sh; fi
- sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_ggmorse.sh; fi
- sh: bash cmake/ci/build_sdrplay.sh
before_build:
- sh: bash -c export
- sh: bash -c pwd
build_script:
- sh: ./cmake/ci/build_sdrangel.sh
test_script:
# debian build path
- sh: ./obj-x86_64-linux-gnu/sdrangelbench
after_build:
- sh: mkdir sdrangel-${APPVEYOR_BUILD_VERSION}
- sh: cp ../*.deb ../*.build ../*.buildinfo ../*.changes sdrangel-${APPVEYOR_BUILD_VERSION}
- sh: tar -czf sdrangel-${APPVEYOR_BUILD_VERSION}.tar.gz sdrangel-${APPVEYOR_BUILD_VERSION}
artifacts:
- path: sdrangel-${APPVEYOR_BUILD_VERSION}.tar.gz
name: package2204
# deploy:
# release: sdrangel-v$(appveyor_build_version)
# description: 'SDRangel Ubuntu 22.04'
# provider: GitHub
# auth_token:
# secure: kyU5TaXRoily6q/QLRLqal2xCFGWEdnb8AJIu7FknsUQyj1wjRGmqC2My+Wfszod
# artifact: archive
# draft: false
# prerelease: false
# on:
# APPVEYOR_REPO_TAG: true # deploy on tag push only
# branch: master # release from master branch only
deploy:
provider: Environment
name: f4exb
# # - matrix:
# # only:
# # - TARGET: 'vs2019gui'
# # cache:
# # - C:\ProgramData\chocolatey\bin
# # - C:\ProgramData\chocolatey\lib
# # build_script:
# # - call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
# # # Install GNU patch as applying patches with git fails in BladeRF tree
# # - choco install patch
# # - git submodule update --init --recursive
# # - mkdir build && cd build
# # - cmake .. -G "%CMAKE_GENERATOR%" %CMAKE_CUSTOM_OPTIONS%
# # - cmake --build . --config Release --target package
# # artifacts: # push installer executable
# # path: build\*.exe
# # name: installer
# # deploy:
# # release: sdrangel-v$(appveyor_build_version)
# # description: 'SDRangel Windows'
# # provider: GitHub
# # auth_token:
# # secure: kyU5TaXRoily6q/QLRLqal2xCFGWEdnb8AJIu7FknsUQyj1wjRGmqC2My+Wfszod
# # artifact: installer, portable
# # draft: false
# # prerelease: false
# # tag: $(APPVEYOR_REPO_TAG_NAME) # will not work until tag is pushed
# # on:
# # APPVEYOR_REPO_TAG: true # deploy on tag push only
# # branch: master # release from master branch only
# - matrix:
# only:
# - TARGET: ubuntu2204prod
# clone_folder: /home/appveyor/projects
# cache:
# - $HOME/external/
# install:
# - sh: sudo apt-get update
# - sh: echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections
# # not sdrplay with soapysdr; libairspyhf-dev is too old (no lna)
# - sh: |
# sudo apt-get -y install build-essential cmake git xxd \
# devscripts fakeroot debhelper libfftw3-dev qtbase5-dev libopengl-dev libqt5opengl5-dev \
# qttools5-dev qttools5-dev-tools qtmultimedia5-dev libqt5multimedia5-plugins libqt5websockets5-dev \
# libqt5quick5 qtwebengine5-dev qtbase5-private-dev \
# qml-module-qtlocation qml-module-qtpositioning qml-module-qtquick-window2 qml-module-qtquick-dialogs \
# qml-module-qtquick-controls qml-module-qtquick-controls2 qml-module-qtquick-layouts qml-module-qtgraphicaleffects \
# libqt5serialport5-dev qtdeclarative5-dev qtpositioning5-dev qtlocation5-dev \
# libqt5charts5-dev libqt5texttospeech5-dev libqt5gamepad5-dev libqt5svg5-dev libfaad-dev libflac-dev zlib1g-dev \
# libusb-1.0-0-dev libhidapi-dev libboost-all-dev libasound2-dev libopencv-dev libopencv-imgcodecs-dev \
# libxml2-dev bison flex ffmpeg libpostproc-dev libavcodec-dev libavformat-dev \
# libopus-dev libcodec2-dev libairspy-dev libhackrf-dev \
# libbladerf-dev libsoapysdr-dev libiio-dev libuhd-dev libhamlib-dev \
# python3-mako python3-cheetah python3-numpy \
# autoconf automake libtool ninja-build libclang1-11
# - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_cm256cc.sh; fi
# - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_mbelib.sh; fi
# - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_serialdv.sh; fi
# - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_dsdcc.sh; fi
# - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_perseus-sdr.sh; fi
# - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_xtrx-sdr.sh; fi
# - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_airspyhf.sh; fi
# - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_rtlsdr.sh; fi
# - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_limesuite.sh; fi
# - sh: if [[ ! "${CMAKE_CUSTOM_OPTIONS}" =~ "ENABLE_EXTERNAL_LIBRARIES" ]]; then bash cmake/ci/build_ggmorse.sh; fi
# - sh: bash cmake/ci/build_sdrplay.sh
# before_build:
# - sh: bash -c export
# - sh: bash -c pwd
# build_script:
# - sh: ./cmake/ci/build_sdrangel.sh
# test_script:
# # debian build path
# - sh: ./obj-x86_64-linux-gnu/sdrangelbench
# after_build:
# - sh: mkdir sdrangel-${APPVEYOR_BUILD_VERSION}
# - sh: cp ../*.deb ../*.build ../*.buildinfo ../*.changes sdrangel-${APPVEYOR_BUILD_VERSION}
# - sh: tar -czf sdrangel-${APPVEYOR_BUILD_VERSION}.tar.gz sdrangel-${APPVEYOR_BUILD_VERSION}
# artifacts:
# - path: sdrangel-${APPVEYOR_BUILD_VERSION}.tar.gz
# name: package2204
# # deploy:
# # release: sdrangel-v$(appveyor_build_version)
# # description: 'SDRangel Ubuntu 22.04'
# # provider: GitHub
# # auth_token:
# # secure: kyU5TaXRoily6q/QLRLqal2xCFGWEdnb8AJIu7FknsUQyj1wjRGmqC2My+Wfszod
# # artifact: archive
# # draft: false
# # prerelease: false
# # on:
# # APPVEYOR_REPO_TAG: true # deploy on tag push only
# # branch: master # release from master branch only
# deploy:
# provider: Environment
# name: f4exb
- matrix:
only:
- TARGET: ubuntu2204docker

62
.github/workflows/linux.yml vendored Normal file
View File

@ -0,0 +1,62 @@
name: SDRangel Linux release build
on:
push:
branches:
- linux_github_release
tags:
- 'v*'
jobs:
build_deb:
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, ubuntu-24.04]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get -y install build-essential cmake git xxd \
devscripts fakeroot debhelper libfftw3-dev qtbase5-dev libopengl-dev libqt5opengl5-dev \
qttools5-dev qttools5-dev-tools qtmultimedia5-dev libqt5multimedia5-plugins libqt5websockets5-dev \
libqt5quick5 qtwebengine5-dev qtbase5-private-dev \
qml-module-qtlocation qml-module-qtpositioning qml-module-qtquick-window2 qml-module-qtquick-dialogs \
qml-module-qtquick-controls qml-module-qtquick-controls2 qml-module-qtquick-layouts qml-module-qtgraphicaleffects \
libqt5serialport5-dev qtdeclarative5-dev qtpositioning5-dev qtlocation5-dev \
libqt5charts5-dev libqt5texttospeech5-dev libqt5gamepad5-dev libqt5svg5-dev libfaad-dev libflac-dev zlib1g-dev \
libusb-1.0-0-dev libhidapi-dev libboost-all-dev libasound2-dev libopencv-dev libopencv-imgcodecs-dev \
libxml2-dev bison flex ffmpeg libpostproc-dev libavcodec-dev libavformat-dev \
libopus-dev libcodec2-dev libairspy-dev libhackrf-dev \
libbladerf-dev libsoapysdr-dev libiio-dev libuhd-dev libhamlib-dev \
python3-mako python3-cheetah python3-numpy \
autoconf automake libtool ninja-build
bash cmake/ci/build_sdrplay.sh
- name: Build SDRangel
run: |
debuild -i -us -uc -b
- name: Get version
id: get_version
run: |
if [[ "${{github.ref_name}}" == "linux_github_release" ]]; then
echo "version=$(echo ${{github.sha}} | cut -c1-7)" >> $GITHUB_OUTPUT
else
echo "version=$(echo ${{github.ref_name}} | cut -c2-)" >> $GITHUB_OUTPUT
fi
- name: Rename
run: mv ../sdrangel_*_amd64.deb sdrangel_${{ steps.get_version.outputs.version }}_${{ matrix.os }}_amd64.deb
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: sdrangel_${{ steps.get_version.outputs.version }}_${{ matrix.os }}_amd64.deb
path: sdrangel_${{ steps.get_version.outputs.version }}_${{ matrix.os }}_amd64.deb
- name: Upload release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
files: sdrangel_${{ steps.get_version.outputs.version }}_${{ matrix.os }}_amd64.deb

161
.github/workflows/mac.yml vendored Normal file
View File

@ -0,0 +1,161 @@
name: SDRangel Mac release build
on:
push:
branches:
- mac_ci
tags:
- 'v*'
jobs:
build_mac_x64:
runs-on: macos-13
env:
MACOSX_DEPLOYMENT_TARGET: 12.0
steps:
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
- name: Update brew
run: brew update
- name: Install brew packages
run: brew install nasm subversion
- name: Install SDRplay API
run: |
wget https://www.sdrplay.com/software/SDRplayAPI-macos-installer-universal-3.15.0.pkg
sudo installer -pkg SDRplayAPI-macos-installer-universal-3.15.0.pkg -target /
- name: Install python
run: |
wget https://www.python.org/ftp/python/3.12.7/python-3.12.7-macos11.pkg
sudo installer -pkg python-3.12.7-macos11.pkg -target /
- name: Install python packages for UHD
run: |
/usr/local/bin/python3.12 -m pip install numpy mako requests Cheetah3 setuptools
- name: Install Qt
uses: jurplel/install-qt-action@v4
with:
version: '6.9.1'
host: 'mac'
arch: 'clang_64'
modules: 'qtcharts qtscxml qt5compat qtlocation qtmultimedia qtpositioning qtserialport qtspeech qtwebsockets qtwebengine qtshadertools qtwebchannel'
- name: Configure SDRangel
run: |
mkdir build && cd build
cmake .. -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_QT6=ON -DCMAKE_BUILD_TYPE=Release -DARCH_OPT=nehalem -DDEBUG_OUTPUT=ON -DENABLE_USRP=ON -DENABLE_MIRISDR=OFF -DBUILD_SERVER=OFF -DENABLE_EXTERNAL_LIBRARIES=ON -DBUNDLE=ON -DPKG_CONFIG_USE_CMAKE_PREFIX_PATH=TRUE -DPYTHON_EXECUTABLE=/usr/local/bin/python3.12
- name: Build SDRangel on Mac
run: |
cd build
make -j4
- name: Create dmg
run: |
cd build
RETRIES=5
COUNT=1
set +e
while [ $COUNT -lt $RETRIES ]; do
make package
if [ $? -eq 0 ]; then
RETRIES=0
break
fi
let COUNT=$COUNT+1
done
shell: bash
continue-on-error: true
- name: Get version
id: get_version
run: |
if [[ "${{github.ref_name}}" == "mac_ci" ]]; then
echo "version=$(echo ${{github.sha}} | cut -c1-7)" >> $GITHUB_OUTPUT
else
echo "version=$(echo ${{github.ref_name}} | cut -c2-)" >> $GITHUB_OUTPUT
fi
- name: Get filename
id: get_filename
run: echo "filename=$(grep CPACK_PACKAGE_FILE_NAME build/CMakeCache.txt | cut -d "=" -f2)" >> $GITHUB_OUTPUT
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: sdrangel-${{ steps.get_version.outputs.version }}-macx64.dmg
path: ${{ github.workspace }}/build/${{ steps.get_filename.outputs.filename }}.dmg
- name: Upload release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
files: ${{ github.workspace }}/build/${{ steps.get_filename.outputs.filename }}.dmg
build_mac_arm64:
runs-on: macos-14
steps:
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
- name: Update brew
run: brew update
- name: Install brew packages
run: brew install nasm subversion
- name: Install SDRplay API
run: |
wget https://www.sdrplay.com/software/SDRplayAPI-macos-installer-universal-3.15.0.pkg
sudo installer -pkg SDRplayAPI-macos-installer-universal-3.15.0.pkg -target /
- name: Install python
run: |
wget https://www.python.org/ftp/python/3.12.7/python-3.12.7-macos11.pkg
sudo installer -pkg python-3.12.7-macos11.pkg -target /
- name: Install python packages for UHD
run: |
/usr/local/bin/python3.12 -m pip install numpy mako requests Cheetah3 setuptools
- name: Install Qt
uses: jurplel/install-qt-action@v4
with:
version: '6.9.1'
host: 'mac'
arch: 'clang_64'
modules: 'qtcharts qtscxml qt5compat qtlocation qtmultimedia qtpositioning qtserialport qtspeech qtwebsockets qtwebengine qtshadertools qtwebchannel'
- name: Configure SDRangel
run: |
mkdir build && cd build
cmake .. -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_QT6=ON -DCMAKE_BUILD_TYPE=Release -DDEBUG_OUTPUT=ON -DENABLE_USRP=ON -DENABLE_MIRISDR=OFF -DBUILD_SERVER=OFF -DENABLE_EXTERNAL_LIBRARIES=ON -DBUNDLE=ON -DPKG_CONFIG_USE_CMAKE_PREFIX_PATH=TRUE -DPYTHON_EXECUTABLE=/usr/local/bin/python3.12
- name: Build SDRangel on Mac
run: |
cd build
make -j3
- name: Create dmg
run: |
cd build
RETRIES=5
COUNT=1
set +e
while [ $COUNT -lt $RETRIES ]; do
make package
if [ $? -eq 0 ]; then
RETRIES=0
break
fi
let COUNT=$COUNT+1
done
shell: bash
continue-on-error: true
- name: Get version
id: get_version
run: |
if [[ "${{github.ref_name}}" == "mac_ci" ]]; then
echo "version=$(echo ${{github.sha}} | cut -c1-7)" >> $GITHUB_OUTPUT
else
echo "version=$(echo ${{github.ref_name}} | cut -c2-)" >> $GITHUB_OUTPUT
fi
- name: Get filename
id: get_filename
run: echo "filename=$(grep CPACK_PACKAGE_FILE_NAME build/CMakeCache.txt | cut -d "=" -f2)" >> $GITHUB_OUTPUT
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: sdrangel-${{ steps.get_version.outputs.version }}-macarm64.dmg
path: ${{ github.workspace }}/build/${{ steps.get_filename.outputs.filename }}.dmg
- name: Upload release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
files: ${{ github.workspace }}/build/${{ steps.get_filename.outputs.filename }}.dmg

View File

@ -24,7 +24,7 @@ jobs:
WIN_ARCH: "x64",
os: windows-latest,
QT_INST_DIR: "C:/",
QTDIR: "C:/Qt/5.15.2/msvc2019_64",
QTDIR: "C:/Qt/6.7.3/msvc2019_64",
QT_ARCH: win64_msvc2019_64,
boost_dl: "${{ github.workspace }}\\downloads\\boost",
lib_dir: "C:\\Libraries",
@ -41,6 +41,9 @@ jobs:
echo github.event_name: ${{ github.event_name }}
echo github.ref: ${{ github.ref }}
echo github.workspace: ${{ github.workspace }}
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install basic dependencies on Windows
if: startsWith(matrix.config.os, 'windows')
run: |
@ -69,19 +72,20 @@ jobs:
rm -rf boost_*/* download.tar.bz2 download.tar
shell: bash
- name: Install Qt
uses: jurplel/install-qt-action@v3
uses: jurplel/install-qt-action@v4
with:
version: '6.7.3'
dir: ${{matrix.config.QT_INST_DIR}}
arch: ${{matrix.config.QT_ARCH}}
setup-python: false
modules: 'qtcharts qtwebengine'
modules: 'qtcharts qtscxml qt5compat qtlocation qtmultimedia qtpositioning qtserialport qtspeech qtwebsockets qtwebengine qtshadertools qtwebchannel'
- name: build sdrangel on Windows
if: startsWith(matrix.config.os, 'windows')
run: |
cmd "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
cmd "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
choco install patch
mkdir build && cd build
cmake .. -G "${{ matrix.config.generators }}" -DCMAKE_BUILD_TYPE=Release -DARCH_OPT=SSE4_2 -DDEBUG_OUTPUT=ON -DENABLE_MIRISDR=OFF -DBUILD_SERVER=OFF -DCMAKE_PREFIX_PATH="C:\Qt\5.15.2\msvc2019_64;C:\Libraries\boost_1_73_0"
cmake .. -G "${{ matrix.config.generators }}" -DCMAKE_BUILD_TYPE=Release -DENABLE_QT6=ON -DARCH_OPT=SSE4_2 -DDEBUG_OUTPUT=ON -DENABLE_MIRISDR=OFF -DBUILD_SERVER=OFF -DCMAKE_PREFIX_PATH="C:\Qt\6.7.3\msvc2019_64;C:\Libraries\boost_1_73_0"
cmake --build . --config Release --target package
- name: Check disk space
run: Get-PSDrive
@ -89,18 +93,13 @@ jobs:
id: get_version
run: echo "version=$(grep sdrangel_VERSION build/CMakeCache.txt | cut -d "=" -f2)" >> $env:GITHUB_OUTPUT
- name: Upload artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: sdrangel-${{ steps.get_version.outputs.version }}-win64.exe
path: ${{ github.workspace }}/build/sdrangel-${{ steps.get_version.outputs.version }}-win64.exe
- name: Upload release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v0.1.13
with:
files: ${{ github.workspace }}/build/sdrangel-${{ steps.get_version.outputs.version }}-win64.exe
build_mac:
runs-on: macos-13
runs-on: macos-14
steps:
- uses: actions/checkout@v4
with:
@ -125,10 +124,7 @@ jobs:
- name: Configure SDRangel
run: |
mkdir build && cd build
cmake .. -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_QT6=ON -DCMAKE_BUILD_TYPE=Release -DARCH_OPT=nehalem -DDEBUG_OUTPUT=ON -DENABLE_CHANNELRX_DEMODDATV=OFF -DENABLE_CHANNELTX_MODDATV=OFF -DENABLE_MIRISDR=OFF -DBUILD_SERVER=OFF -DENABLE_EXTERNAL_LIBRARIES=AUTO -DBUNDLE=ON -DPKG_CONFIG_USE_CMAKE_PREFIX_PATH=TRUE -DCMAKE_PREFIX_PATH="/usr/local/opt/ffmpeg@5/"
- name: Get filename
id: get_filename
run: echo "filename=$(grep CPACK_PACKAGE_FILE_NAME build/CMakeCache.txt | cut -d "=" -f2)" >> $GITHUB_OUTPUT
cmake .. -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_QT6=ON -DCMAKE_BUILD_TYPE=Release -DDEBUG_OUTPUT=ON -DENABLE_CHANNELRX_DEMODDATV=OFF -DENABLE_CHANNELTX_MODDATV=OFF -DENABLE_MIRISDR=OFF -DBUILD_SERVER=OFF -DENABLE_EXTERNAL_LIBRARIES=AUTO -DBUNDLE=ON -DPKG_CONFIG_USE_CMAKE_PREFIX_PATH=TRUE -DCMAKE_PREFIX_PATH="/usr/local/opt/ffmpeg@5/"
- name: Build SDRangel on Mac
run: |
cd build

44
.github/workflows/snap.yml vendored Normal file
View File

@ -0,0 +1,44 @@
# See: https://github.com/snapcore/action-build
name: SDRangel snap release build
on:
push:
branches:
- snap
tags:
- 'v*'
jobs:
build_snap:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
- name: Get version
id: get_version
run: |
if [[ "${{github.ref_name}}" == "snap" ]]; then
echo "version=${{github.sha}}" >> $GITHUB_OUTPUT
else
echo "version=$(echo ${{github.ref_name}} | cut -c2-)" >> $GITHUB_OUTPUT
fi
- uses: snapcore/action-build@v1
id: build
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: sdrangel-${{ steps.get_version.outputs.version }}-amd64.snap
path: ${{ steps.build.outputs.snap }}
- name: Upload release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
files: ${{ steps.build.outputs.snap }}
- uses: snapcore/action-publish@v1
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_STORE_LOGIN }}
with:
snap: ${{ steps.build.outputs.snap }}
release: stable

119
.github/workflows/windows.yml vendored Normal file
View File

@ -0,0 +1,119 @@
name: SDRangel Windows release build and signing
on:
push:
branches:
- master
tags:
- 'v*'
jobs:
build:
name: ${{ matrix.config.name }}
runs-on: ${{ matrix.config.os }}
strategy:
fail-fast: false
matrix:
config:
- {
name: "Windows-x64",
WIN_ARCH: "x64",
os: windows-latest,
QT_INST_DIR: "C:/",
QTDIR: "C:/Qt/6.7.3/msvc2019_64",
QT_ARCH: win64_msvc2019_64,
boost_dl: "${{ github.workspace }}\\downloads\\boost",
lib_dir: "C:\\Libraries",
generators: Ninja
}
steps:
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
- name: Print env
run: |
echo github.event.action: ${{ github.event.action }}
echo github.event_name: ${{ github.event_name }}
echo github.ref: ${{ github.ref }}
echo github.workspace: ${{ github.workspace }}
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install basic dependencies on Windows
if: startsWith(matrix.config.os, 'windows')
run: |
choco install ninja cmake
ninja --version
cmake --version
- name: Install MSVC on Windows
if: startsWith(matrix.config.os, 'windows')
uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64
- name: Install Boost
env:
BOOST_ROOT: ${{ matrix.config.boost_dl }}
BOOST_DEST: ${{ matrix.config.lib_dir }}
BOOST_URL: https://archives.boost.io/release/1.73.0/source/boost_1_73_0.tar.bz2
run: |
mkdir -p $BOOST_ROOT
mkdir -p $BOOST_DEST
curl --progress-bar --location --output $BOOST_ROOT/download.tar.bz2 $BOOST_URL
7z -o$BOOST_ROOT x $BOOST_ROOT/download.tar.bz2 -y -bd
7z -o$BOOST_ROOT x $BOOST_ROOT/download.tar -y -bd
cd $BOOST_ROOT && cp -r boost_* $BOOST_DEST
ls -l $BOOST_DEST
ls -l "C:\\"
rm -rf boost_*/* download.tar.bz2 download.tar
shell: bash
- name: Install Qt
uses: jurplel/install-qt-action@v4
with:
version: '6.7.3'
dir: ${{matrix.config.QT_INST_DIR}}
arch: ${{matrix.config.QT_ARCH}}
setup-python: 'false'
modules: 'qtcharts qtscxml qt5compat qtlocation qtmultimedia qtpositioning qtserialport qtspeech qtwebsockets qtwebengine qtshadertools qtwebchannel'
- name: build sdrangel on Windows
if: startsWith(matrix.config.os, 'windows')
run: |
cmd "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
choco install patch
mkdir build && cd build
cmake .. -G "${{ matrix.config.generators }}" -DCMAKE_BUILD_TYPE=Release -DENABLE_QT6=ON -DARCH_OPT=SSE4_2 -DDEBUG_OUTPUT=ON -DENABLE_MIRISDR=OFF -DBUILD_SERVER=OFF -DCMAKE_PREFIX_PATH="C:\Qt\6.7.3\msvc2019_64;C:\Libraries\boost_1_73_0"
cmake --build . --config Release --target package
- name: Check disk space
run: Get-PSDrive
- name: Get version
id: get_version
run: echo "version=$(grep sdrangel_VERSION build/CMakeCache.txt | cut -d "=" -f2)" >> $env:GITHUB_OUTPUT
- name: Upload unsigned artifact
id: upload-unsigned-artifact
uses: actions/upload-artifact@v4
with:
name: sdrangel-${{ steps.get_version.outputs.version }}-win64.exe
path: ${{ github.workspace }}/build/sdrangel-${{ steps.get_version.outputs.version }}-win64.exe
- name: Sign Code
id: sign_code
uses: signpath/github-action-submit-signing-request@v1
with:
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: '553b8f53-adf0-4fe5-be3d-283504a21a51'
project-slug: 'sdrangel'
signing-policy-slug: 'release-signing'
github-artifact-id: '${{ steps.upload-unsigned-artifact.outputs.artifact-id }}'
wait-for-completion: true
output-artifact-directory: 'build\signed'
wait-for-completion-timeout-in-seconds: 3600
- name: Upload signed artifact
id: upload-signed-artifact
uses: actions/upload-artifact@v4
with:
name: sdrangel-${{ steps.get_version.outputs.version }}-win64-signed.exe
path: ${{ github.workspace }}/build/signed/sdrangel-${{ steps.get_version.outputs.version }}-win64.exe
- name: Upload release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
files: ${{ github.workspace }}/build/signed/sdrangel-${{ steps.get_version.outputs.version }}-win64.exe

View File

@ -1,3 +1,77 @@
sdrangel (7.22.8-1) unstable; urgency=medium
* See Github release
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Wed, 02 Jul 2025 17:00:39 +0200
sdrangel (7.22.7-1) unstable; urgency=medium
* See Github release
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 04 May 2025 17:58:14 +0200
sdrangel (7.22.6-1) unstable; urgency=medium
* See Github release
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 02 Feb 2025 18:08:11 +0100
sdrangel (7.22.5-1) unstable; urgency=medium
* Windows: upload signed releases rather than unsigned releases to Github releases page. PR #2347
* Windows: fixed signed releases. PR #2344
* FT8 Demod: limit upper bandwidth to 5.8 kHz. Fixes #2339
* Stop device while changing channel set. Fixes #2332. PR #2342
* ADSB: Update URL of OpenSkyNetwork Aircraft database. PR #2341
* Don't stop source if being deleted. For #2315. PR #2340
* Send DSPSignalNotification in audio mods for #2336. PR #2340
* Radiosonde: limit precision of floating point numbers sent to SondeHub. PR #2338
* Windows signed releases: use relative path. Increase timeout to 30 minutes. PR #2335
* ADSB: Include adsbdemodsettings.h PR #2334
* Use release signing certificate for Windows installer. PR #2331
* Fix memory leak and race condition relating to DSP*Engines. Part of #2159 PR #2330
* FreeDV: Fix memory allocation/free issues. Part of #2315. PR #2330
* Wav Files: Add support for meta-data. PR #2328
* DemodAnalyzer: Ensure sample rate is set in worker. Fixes #2309. PR #2328
^ SDRplayv3: Mac: link with libsdrplay_api.so.3 rather than libsdrplay_api.so.3.15. PR #2327
* ADS-B: Fix memory use after delete. For #1734 and part of #2315 PR #2326
* Fixed Appveyor Docker image build
* Fix output-artifact-directory and unzip file. PR #2323
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Thu, 05 Dec 2024 01:07:27 +0100
sdrangel (7.22.4-1) unstable; urgency=medium
* Use macos-12 for Mac x86 build. PR #2321
* Workaround for "hdiutil: create failed - Resource busy"
* Pager: Add alpha and numeric columns. Implements #2319. PR #2320
* Added qtwebchannel dependecy to fix missing 3d Map and Sky Map from Windows release. PR #2316
* Removed .deb package build from Appveyor
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Mom, 11 Nov 2024 08:42:03 +0100
sdrangel (7.22.3-1) unstable; urgency=medium
* Add deb dependencies for pipewire. PR #2314
* Added compilation options for WebAssembly. PR #2313
* ADS-B: Use settings keys. PR #2310
* AIS Demod: Remove spacing around messages. PR #2310
* Freuqency Scanner: Add multiplex mode. PR #2310
* Build snap, MAC, Windows and Ubuntu .deb with Github actions. Various PRs
* Server: Use Sink/MIMO signals rather than Source. Part of #2294. PR #2304
* Updated some Python scripts to Python3. PR #2298
* RemoteTCPSink: Does use IQ only setting for RTL0. PR #2301
* Server: wait for set sample source/sink/MIMO to complete before loading the device settings. Fixes #2294
* Fix spectrum peak measurement for SSB spectra. Fixes #2282. PR #2299
* Upgrade C++ standard to c++17
* Fixes for Android . PR #2288
* Add qtshadertools. PR #2287
* Add more Qt modules and set ENABLE_QT6=ON. PR #2287
* Update Qt optional packages for 6.8 , PR #2287
* Use Qt 6.8 for Windows build. PR #2287
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sat, 09 Nov 2024 17:30:44 +0100
sdrangel (7.22.2-1) unstable; urgency=medium
* ChirpChat: increased preamble symbols limit from 20 to 32. Fixes #2284
@ -19,7 +93,7 @@ sdrangel (7.22.2-1) unstable; urgency=medium
* RemoteTCPInput: Add wss protocol support. PR #2270
* Fix DeviceAPI::deserialize. Fixes #2266. PR #2267
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 20 Oct 2024 08:26:38 +0200
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 20 Oct 2024 08:26:38 +0200
sdrangel (7.22.1-1) unstable; urgency=medium

View File

@ -11,7 +11,7 @@ endif()
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
# disable only when needed
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
@ -20,7 +20,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# configure version
set(sdrangel_VERSION_MAJOR "7")
set(sdrangel_VERSION_MINOR "22")
set(sdrangel_VERSION_PATCH "2")
set(sdrangel_VERSION_PATCH "8")
set(sdrangel_VERSION_SUFFIX "")
# SDRAngel cmake options
@ -277,6 +277,7 @@ set(INSTALL_PLUGINSSRV_DIR "${INSTALL_LIB_DIR}/pluginssrv")
if(ANDROID)
set(PLUGINS_PREFIX "sdrangel_plugins_")
set(PLUGINSSRV_PREFIX "sdrangel_pluginssrv_")
set(ANDROID_PACKAGE_SOURCE_DIR ${PROJECT_SOURCE_DIR}/android/qt6 CACHE INTERNAL "")
else()
set(PLUGINS_PREFIX "")
set(PLUGINSSRV_PREFIX "")
@ -428,7 +429,7 @@ elseif (WIN32)
elseif(ANDROID)
set(EXTERNAL_LIBRARY_FOLDER "${CMAKE_SOURCE_DIR}/external/android")
set(Boost_INCLUDE_DIR "${EXTERNAL_LIBRARY_FOLDER}/ndk_21_boost_1.72.0/include" CACHE INTERNAL "")
set(Boost_INCLUDE_DIR "${EXTERNAL_LIBRARY_FOLDER}/ndk_26b_boost_1.83.0/include" CACHE INTERNAL "")
set(FFTW3F_FOUND ON CACHE INTERNAL "")
set(FFTW3F_INCLUDE_DIRS "${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/fftw-3/include" CACHE INTERNAL "")
@ -485,6 +486,14 @@ elseif(ANDROID)
set(SWSCALE_INCLUDE_DIRS "${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/ffmpeg/include" CACHE INTERNAL "")
set(SWSCALE_LIBRARIES "${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/ffmpeg/lib/libswscale.so" CACHE INTERNAL "")
set(GGMORSE_FOUND ON CACHE INTERNAL "")
set(GGMORSE_INCLUDE_DIR "${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/ggmorse/include/" CACHE INTERNAL "")
set(GGMORSE_LIBRARIES "${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/ggmorse/lib/static/libggmorse.a" CACHE INTERNAL "")
set(FLAC_FOUND ON CACHE INTERNAL "")
set(FLAC_INCLUDE_DIR "${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/flac/include/" CACHE INTERNAL "")
set(FLAC_LIBRARIES "${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/flac/lib/libFLAC.so" CACHE INTERNAL "")
set(LIBUSB_FOUND ON CACHE INTERNAL "")
set(LIBUSB_INCLUDE_DIR "${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/libusb/include/" CACHE INTERNAL "")
set(LIBUSB_LIBRARIES "${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/libusb/lib/libusb1.0.so" CACHE INTERNAL "")
@ -507,11 +516,6 @@ elseif(ANDROID)
if (ENABLE_QT6)
set(ANDROID_EXTRA_LIBS
${Qt6_DIR}/../../../android_arm64_v8a/lib/libQt6Charts_arm64-v8a.so
${Qt6_DIR}/../../../android_arm64_v8a/lib/libQt6Concurrent_arm64-v8a.so
${Qt6_DIR}/../../../android_arm64_v8a/lib/libQt6MultimediaWidgets_arm64-v8a.so
${Qt6_DIR}/../../../android_arm64_v8a/lib/libQt6SerialPort_arm64-v8a.so
${Qt6_DIR}/../../../android_arm64_v8a/lib/libQt6TextToSpeech_arm64-v8a.so
${EXTERNAL_LIBRARY_FOLDER}/android_openssl/latest/arm64/libssl_1_1.so
${EXTERNAL_LIBRARY_FOLDER}/android_openssl/latest/arm64/libcrypto_1_1.so
${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/ffmpeg/lib/libavcodec.so
@ -526,6 +530,7 @@ elseif(ANDROID)
${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/dsdcc/lib/libdsdcc.so
${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/libusb/lib/libunrooted_android.so
${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/libusb/lib/libusb1.0.so
${EXTERNAL_LIBRARY_FOLDER}/${ANDROID_ABI}/flac/lib/libFLAC.so
CACHE INTERNAL ""
)
else()
@ -576,6 +581,7 @@ elseif(ANDROID)
${EXTERNAL_LIBRARY_FOLDER}/arm64-v8a/dsdcc/lib/libdsdcc.so
${EXTERNAL_LIBRARY_FOLDER}/arm64-v8a/libusb/lib/libunrooted_android.so
${EXTERNAL_LIBRARY_FOLDER}/arm64-v8a/libusb/lib/libusb1.0.so
${EXTERNAL_LIBRARY_FOLDER}/arm64-v8a/flac/lib/libFLAC.so
${EXTERNAL_LIBRARY_FOLDER}/armeabi-v7a/ffmpeg/lib/libavcodec.so
${EXTERNAL_LIBRARY_FOLDER}/armeabi-v7a/ffmpeg/lib/libavdevice.so
${EXTERNAL_LIBRARY_FOLDER}/armeabi-v7a/ffmpeg/lib/libavfilter.so
@ -588,6 +594,7 @@ elseif(ANDROID)
${EXTERNAL_LIBRARY_FOLDER}/armeabi-v7a/dsdcc/lib/libdsdcc.so
${EXTERNAL_LIBRARY_FOLDER}/armeabi-v7a/libusb/lib/libunrooted_android.so
${EXTERNAL_LIBRARY_FOLDER}/armeabi-v7a/libusb/lib/libusb1.0.so
${EXTERNAL_LIBRARY_FOLDER}/armeabi-v7a/flac/lib/libFLAC.so
CACHE INTERNAL ""
)
endif()
@ -650,8 +657,7 @@ if(ENABLE_QT6)
MultimediaWidgets
Positioning
Charts
SerialPort
Core5Compat)
SerialPort)
else()
find_package(Qt5 5.15
REQUIRED COMPONENTS
@ -679,7 +685,8 @@ if (BUILD_GUI)
QuickWidgets
TextToSpeech
Svg
SvgWidgets)
SvgWidgets
StateMachine)
else()
find_package(Qt5
REQUIRED COMPONENTS

View File

@ -22,7 +22,6 @@
///////////////////////////////////////////////////////////////////////////////////
#include <QApplication>
#include <QTextCodec>
#include <QProxyStyle>
#include <QStyleFactory>
#include <QFontDatabase>
@ -48,10 +47,6 @@
static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *logger)
{
/*
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
*/
QCoreApplication::setOrganizationName(COMPANY);
QCoreApplication::setApplicationName(APPLICATION_NAME);
QCoreApplication::setApplicationVersion(SDRANGEL_VERSION);
@ -193,7 +188,9 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo
logger = nullptr;
}
MainWindow w(logger, parser);
MainWindow w(logger, parser);
w.show();
if (parser.getListDevices())
{
@ -202,12 +199,6 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo
return EXIT_SUCCESS;
}
if (parser.getRemoteTCPSink()) {
RemoteTCPSinkStarter::start(parser);
}
w.show();
return a.exec();
}

View File

@ -19,7 +19,11 @@ if(WIN32)
endif()
if(NOT MSVC)
add_compile_options(-Wall -Wextra -Wvla -Woverloaded-virtual -Wno-inconsistent-missing-override -ffast-math -fno-finite-math-only -ftree-vectorize)
add_compile_options(-Wall -Wextra -Wvla -ffast-math -fno-finite-math-only -ftree-vectorize)
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Woverloaded-virtual>)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_compile_options(-Wno-inconsistent-missing-override)
endif()
else()
# Disable some warnings, so more useful warnings aren't hidden in the noise
# 4996 'fopen': This function or variable may be unsafe. Consider using fopen_s instead.

View File

@ -36,7 +36,7 @@ if(APPLE AND BUNDLE AND BUILD_GUI)
set(CPACK_BUNDLE_ICON "${CMAKE_SOURCE_DIR}/cmake/cpack/sdrangel_icon.icns")
set(CPACK_BUNDLE_PLIST "${CMAKE_BINARY_DIR}/Info.plist")
set(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/cmake/cpack/sdrangel_icon.icns")
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION}_${CPACK_MACOS_PACKAGE_ARCHITECTURE}_${CMAKE_SYSTEM_PROCESSOR}" CACHE INTERNAL "")
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION}_mac-${CPACK_MACOS_PACKAGE_ARCHITECTURE}_${CMAKE_SYSTEM_PROCESSOR}" CACHE INTERNAL "")
set(CPACK_PRE_BUILD_SCRIPTS "${PROJECT_BINARY_DIR}/deploy_mac.cmake")
# copy SoapySDR Modules
@ -175,7 +175,7 @@ elseif(WIN32 OR MINGW)
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${fftw3f_dll}" "${SDRANGEL_BINARY_BIN_DIR}/"
)
endforeach(fftw3f_dll)
file(GLOB LIBUSB_DLLS "${LIBUSB_DLL_DIR}/*${CMAKE_SHARED_LIBRARY_SUFFIX}")
foreach(libusb_dll ${LIBUSB_DLLS})
get_filename_component(libusb_dll_name "${libusb_dll}" NAME)

View File

@ -1,14 +1,15 @@
# This CPACK_PRE_BUILD_SCRIPTS script is used to copy all required Qt and other 3rd party libraries (SDR drivers and codecs) in to the .app bundle
# It is run in a staging area (${CPACK_TEMPORARY_INSTALL_DIRECTORY}/SDRangel.app) after all targets have been installed (E.g. sdrangel exe and plugins)
# The copying of frameworks and libraries is mostly done by 'macdeployqt', however, in order for 'macdeployqt' to copy libraries built by external/CMakeLists.txt,
# we first need to add RPATHs into the libraries giving the locations of any libraries they might depend on.
# we first need to add RPATHs into the libraries giving the locations of any libraries they might depend on.
# These paths are in the variable MACOS_EXTERNAL_LIBS_FIXUP set in externals/CMakeLists.txt
# Is there an easier way to this?
# Copy executable that will be run when icon in /Applications is clicked
message ("Copying default executable to SDRangel.app/Contents/MacOS/SDRangel")
execute_process (COMMAND mkdir ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/SDRangel.app/Contents/MacOS/)
execute_process (COMMAND cp /opt/build/sdrangel/build/sdrangel ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/SDRangel.app/Contents/MacOS/SDRangel)
execute_process (COMMAND pwd)
execute_process (COMMAND cp sdrangel ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/SDRangel.app/Contents/MacOS/SDRangel)
# Add RPATHS to libraries so macdeployqt can find out and copy all dependencies

76
debian/changelog vendored
View File

@ -1,3 +1,77 @@
sdrangel (7.22.8-1) unstable; urgency=medium
* See Github release
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Wed, 02 Jul 2025 17:00:39 +0200
sdrangel (7.22.7-1) unstable; urgency=medium
* See Github release
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 04 May 2025 17:58:14 +0200
sdrangel (7.22.6-1) unstable; urgency=medium
* See Github release
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 02 Feb 2025 18:08:11 +0100
sdrangel (7.22.5-1) unstable; urgency=medium
* Windows: upload signed releases rather than unsigned releases to Github releases page. PR #2347
* Windows: fixed signed releases. PR #2344
* FT8 Demod: limit upper bandwidth to 5.8 kHz. Fixes #2339
* Stop device while changing channel set. Fixes #2332. PR #2342
* ADSB: Update URL of OpenSkyNetwork Aircraft database. PR #2341
* Don't stop source if being deleted. For #2315. PR #2340
* Send DSPSignalNotification in audio mods for #2336. PR #2340
* Radiosonde: limit precision of floating point numbers sent to SondeHub. PR #2338
* Windows signed releases: use relative path. Increase timeout to 30 minutes. PR #2335
* ADSB: Include adsbdemodsettings.h PR #2334
* Use release signing certificate for Windows installer. PR #2331
* Fix memory leak and race condition relating to DSP*Engines. Part of #2159 PR #2330
* FreeDV: Fix memory allocation/free issues. Part of #2315. PR #2330
* Wav Files: Add support for meta-data. PR #2328
* DemodAnalyzer: Ensure sample rate is set in worker. Fixes #2309. PR #2328
^ SDRplayv3: Mac: link with libsdrplay_api.so.3 rather than libsdrplay_api.so.3.15. PR #2327
* ADS-B: Fix memory use after delete. For #1734 and part of #2315 PR #2326
* Fixed Appveyor Docker image build
* Fix output-artifact-directory and unzip file. PR #2323
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Thu, 05 Dec 2024 01:07:27 +0100
sdrangel (7.22.4-1) unstable; urgency=medium
* Use macos-12 for Mac x86 build. PR #2321
* Workaround for "hdiutil: create failed - Resource busy"
* Pager: Add alpha and numeric columns. Implements #2319. PR #2320
* Added qtwebchannel dependecy to fix missing 3d Map and Sky Map from Windows release. PR #2316
* Removed .deb package build from Appveyor
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Mom, 11 Nov 2024 08:42:03 +0100
sdrangel (7.22.3-1) unstable; urgency=medium
* Add deb dependencies for pipewire. PR #2314
* Added compilation options for WebAssembly. PR #2313
* ADS-B: Use settings keys. PR #2310
* AIS Demod: Remove spacing around messages. PR #2310
* Freuqency Scanner: Add multiplex mode. PR #2310
* Build snap, MAC, Windows and Ubuntu .deb with Github actions. Various PRs
* Server: Use Sink/MIMO signals rather than Source. Part of #2294. PR #2304
* Updated some Python scripts to Python3. PR #2298
* RemoteTCPSink: Does use IQ only setting for RTL0. PR #2301
* Server: wait for set sample source/sink/MIMO to complete before loading the device settings. Fixes #2294
* Fix spectrum peak measurement for SSB spectra. Fixes #2282. PR #2299
* Upgrade C++ standard to c++17
* Fixes for Android . PR #2288
* Add qtshadertools. PR #2287
* Add more Qt modules and set ENABLE_QT6=ON. PR #2287
* Update Qt optional packages for 6.8 , PR #2287
* Use Qt 6.8 for Windows build. PR #2287
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sat, 09 Nov 2024 17:30:44 +0100
sdrangel (7.22.2-1) unstable; urgency=medium
* ChirpChat: increased preamble symbols limit from 20 to 32. Fixes #2284
@ -19,7 +93,7 @@ sdrangel (7.22.2-1) unstable; urgency=medium
* RemoteTCPInput: Add wss protocol support. PR #2270
* Fix DeviceAPI::deserialize. Fixes #2266. PR #2267
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 20 Oct 2024 08:26:38 +0200
-- Edouard Griffiths, F4EXB <f4exb06@gmail.com> Sun, 20 Oct 2024 08:26:38 +0200
sdrangel (7.22.1-1) unstable; urgency=medium

7
debian/control vendored
View File

@ -42,8 +42,10 @@ Build-Depends: debhelper (>= 9),
libopencv-imgcodecs-dev,
libxml2-dev,
bison,
cmake,
flex,
ffmpeg,
ninja-build,
libfaad-dev,
libflac-dev,
libavcodec-dev,
@ -63,12 +65,13 @@ Architecture: any
Depends: ${shlibs:Depends},
${misc:Depends},
libasound2,
libgl1-mesa-glx,
libgl1,
libglx-mesa0,
libqt5multimedia5-plugins,
libqt5gamepad5,
libqt5svg5,
qtspeech5-speechd-plugin,
pulseaudio,
pulseaudio | pipewire-pulse,
ffmpeg,
gstreamer1.0-libav,
qml-module-qtlocation,

View File

@ -40,4 +40,6 @@ if(ENABLE_USRP AND UHD_FOUND)
add_subdirectory(usrp)
endif()
add_subdirectory(metis)
if(ENABLE_METIS)
add_subdirectory(metis)
endif()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 640 KiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 490 KiB

After

Width:  |  Height:  |  Size: 844 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 570 KiB

After

Width:  |  Height:  |  Size: 819 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 372 KiB

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 351 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 603 KiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 859 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 547 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 KiB

BIN
doc/img/Map_plugin_pfd.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 KiB

View File

@ -11,9 +11,9 @@
set(CODEC2_TAG "v1.0.3")
set(CM256CC_TAG c0e92b92aca3d1d36c990b642b937c64d363c559)
set(MBELIB_TAG fe83b32c6a60cdd7bce8cecf3c7a0b9ec87a7667)
set(SERIALDV_TAG "v1.1.4")
set(SERIALDV_TAG "v1.1.5")
set(DSDCC_TAG "v1.9.5")
set(LIMESUITE_TAG 70e3859a55d8d5353963a5318013c8454594769f)
set(LIMESUITE_TAG b39cb61ed03d74c35a2de757d495e901acbb6404)
set(BLADERF_TAG "2021.02")
set(LIBIIO_TAG 826563e41b5ce9890b75506f672017de8d76d52d)
set(AIRSPYHF_TAG "1af81c0ca18944b8c9897c3c98dc0a991815b686")
@ -29,17 +29,11 @@ set(SOAPYSDR_SDRPLAY_TAG "soapy-sdrplay-0.2.0")
set(SOAPYSDR_AUDIO_TAG "soapy-audio-0.1.1")
set(SOAPYSDR_REMOTE_TAG "soapy-remote-0.5.1")
set(AIRSPY_TAG "37c768ce9997b32e7328eb48972a7fda0a1f8554")
set(HACKRF_TAG "v2022.09.1")
set(HACKRF_TAG "v2024.02.1")
set(LIBXML2_TAG "v2.10.4")
set(UHD_TAG "v4.6.0.0")
if (APPLE AND (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL x86_64))
# UHD fails to load with 1.80+
set(BOOST_TAG "1.78.0")
set(BOOST_TAG2 "1_78_0")
else()
set(BOOST_TAG "1.83.0")
set(BOOST_TAG2 "1_83_0")
endif()
set(UHD_TAG "v4.7.0.0")
set(BOOST_TAG "1.86.0")
set(BOOST_TAG2 "1_86_0")
# For some external project macros
include(ExternalProject)
@ -60,6 +54,7 @@ if (WIN32)
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG=${SDRANGEL_BINARY_LIB_DIR}
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE=${SDRANGEL_BINARY_LIB_DIR}
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO=${SDRANGEL_BINARY_LIB_DIR}
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
)
elseif (LINUX)
set(COMMON_CMAKE_ARGS
@ -426,6 +421,7 @@ if (NOT FFMPEG_FOUND AND NOT USE_PRECOMPILED_LIBS)
if (NOT X265_FOUND OR X265_EXTERNAL)
ExternalProject_Add(x265
GIT_REPOSITORY https://bitbucket.org/multicoreware/x265_git.git
GIT_TAG 4.1
PREFIX "${EXTERNAL_BUILD_LIBRARIES}/x265"
SOURCE_SUBDIR "source"
CMAKE_ARGS ${COMMON_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
@ -546,7 +542,7 @@ endif (NOT FFMPEG_FOUND AND NOT USE_PRECOMPILED_LIBS)
if (NOT OpenCV_FOUND AND NOT USE_PRECOMPILED_LIBS AND ENABLE_CHANNELTX_MODATV)
ExternalProject_Add(opencv
GIT_REPOSITORY https://github.com/opencv/opencv.git
GIT_TAG 4.5.5
GIT_TAG 4.10.0
DEPENDS "${FFMPEG_DEPENDS}"
PREFIX "${EXTERNAL_BUILD_LIBRARIES}/opencv"
CMAKE_ARGS ${COMMON_CMAKE_ARGS} -DWITH_FFMPEG=ON -DCMAKE_PREFIX_PATH=${FFMPEG_INSTALL_DIR}
@ -864,7 +860,7 @@ if(ENABLE_CHANNELRX_REMOTETCPSINK)
ExternalProject_Add(flac
GIT_REPOSITORY https://github.com/xiph/flac.git
PREFIX "${EXTERNAL_BUILD_LIBRARIES}/flac"
CMAKE_ARGS ${COMMON_CMAKE_ARGS} -DINSTALL_MANPAGES=OFF -D=BUILD_SHARED_LIBS=ON -DWITH_FORTIFY_SOURCE=OFF -DWITH_STACK_PROTECTOR=PFF -DBUILD_PROGRAMS=OFF -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF -DWITH_OGG=OFF -DBUILD_DOCS=OFF
CMAKE_ARGS ${COMMON_CMAKE_ARGS} -DINSTALL_MANPAGES=OFF -DBUILD_SHARED_LIBS=ON -DWITH_FORTIFY_SOURCE=OFF -DWITH_STACK_PROTECTOR=PFF -DBUILD_PROGRAMS=OFF -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF -DWITH_OGG=OFF -DBUILD_DOCS=OFF
BUILD_BYPRODUCTS "${FLAC_LIBRARIES}"
INSTALL_COMMAND ""
TEST_COMMAND ""
@ -1578,6 +1574,8 @@ if (WIN32 OR APPLE)
-DLIBUSB_LIBRARIES=${LIBUSB_LIBRARIES}
-DLIBUSB_INCLUDE_DIR=${LIBUSB_INCLUDE_DIR}
${UHD_PYTHON_ARGS}
-DPython3_FIND_FRAMEWORK=NEVER
-DENABLE_PYTHON_API=OFF
-DCMAKE_INSTALL_NAME_DIR=<INSTALL_DIR>/lib
TEST_COMMAND ""
)

View File

@ -82,7 +82,7 @@ std::string Packing::unpackcall(int x)
if (x <= 1002)
{
sprintf(tmp, "CQ %d", x - 3);
snprintf(tmp, sizeof(tmp), "CQ %d", x - 3);
return std::string(tmp);
}
@ -96,7 +96,7 @@ std::string Packing::unpackcall(int x)
int ci3 = x / 27;
x %= 27;
int ci4 = x;
sprintf(tmp, "CQ %c%c%c%c", c4[ci1], c4[ci2], c4[ci3], c4[ci4]);
snprintf(tmp, sizeof(tmp), "CQ %c%c%c%c", c4[ci1], c4[ci2], c4[ci3], c4[ci4]);
return std::string(tmp);
}
@ -193,9 +193,9 @@ std::string Packing::unpackgrid15(int ng, int ir)
char tmp[16];
if (db >= 0) {
sprintf(tmp, "%s+%02d", ir ? "R" : "", db);
snprintf(tmp, sizeof(tmp), "%s+%02d", ir ? "R" : "", db);
} else {
sprintf(tmp, "%s-%02d", ir ? "R" : "", 0 - db);
snprintf(tmp, sizeof(tmp), "%s-%02d", ir ? "R" : "", 0 - db);
}
return std::string(tmp);
@ -396,7 +396,7 @@ std::string Packing::unpack_5(int a77[], std::string& call1str, std::string& cal
i += 3;
int qsonb = un64(a77, i, 11);
char report[16];
sprintf(report, "%d%04d", rst, qsonb);
snprintf(report, sizeof(report), "%d%04d", rst, qsonb);
i += 11;
// g25
int ng = un64(a77, i, 25);
@ -467,9 +467,9 @@ std::string Packing::unpack_0_1(int a77[], std::string& call1str, std::string& c
char tmp[32];
if (r >= 0) {
sprintf(tmp, "+%02d", r);
snprintf(tmp, sizeof(tmp), "+%02d", r);
} else {
sprintf(tmp, "-%02d", -r);
snprintf(tmp, sizeof(tmp), "-%02d", -r);
}
locstr = std::string(tmp);
@ -553,7 +553,7 @@ std::string Packing::unpack_3(int a77[], std::string& call1str, std::string& cal
else
{
char tmp[32];
sprintf(tmp, "%04d", serial);
snprintf(tmp, sizeof(tmp), "%04d", serial);
serialstr = std::string(tmp);
}
@ -571,7 +571,7 @@ std::string Packing::unpack_3(int a77[], std::string& call1str, std::string& cal
}
{
char tmp[16];
sprintf(tmp, "%d ", rst);
snprintf(tmp, sizeof(tmp), "%d ", rst);
msg += std::string(tmp);
}
@ -634,7 +634,7 @@ std::string Packing::unpack_0_3(int a77[], int n3, std::string& call1str, std::s
{
char tmp[16];
sprintf(tmp, "%d%c ", n_transmitters + 1, clss + 'A');
snprintf(tmp, sizeof(tmp), "%d%c ", n_transmitters + 1, clss + 'A');
msg += std::string(tmp);
}
@ -658,9 +658,9 @@ std::string Packing::unpack(int a77[], std::string& call1, std::string& call2, s
char tmp[64];
if (i3 == 0) {
sprintf(tmp, "%d.%d", i3, n3);
snprintf(tmp, sizeof(tmp), "%d.%d", i3, n3);
} else {
sprintf(tmp, "%d", i3);
snprintf(tmp, sizeof(tmp), "%d", i3);
}
type = std::string(tmp);
@ -714,7 +714,7 @@ std::string Packing::unpack(int a77[], std::string& call1, std::string& call2, s
}
call1 = "UNK";
sprintf(tmp, "UNK i3=%d n3=%d", i3, n3);
snprintf(tmp, sizeof(tmp), "UNK i3=%d n3=%d", i3, n3);
return std::string(tmp);
}

View File

@ -4,6 +4,6 @@ PLUGINS=$(git diff --name-only ${1}..${2} | grep plugins/ | cut -d'/' -f2,3 | so
for plugin in $PLUGINS
do
FILE=$(find $BASEDIR/plugins/$plugin -name "*plugin.cpp")
sed -i -E "s/QStringLiteral\(\"7\.(.*)\"\)/QStringLiteral\(\"7\.22\.2\"\)/" $FILE
echo $FILE
sed -i -E "s/QStringLiteral\(\"7\.(.*)\"\)/QStringLiteral\(\"7\.22\.7\"\)/" $FILE
done

View File

@ -17,10 +17,18 @@ if (NOT SERVER_MODE)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINS_DIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINS_DIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINS_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINS_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINS_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINS_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINS_DIR}")
if(WIN32 AND Qt6_FOUND)
# https://bugreports.qt.io/browse/QTBUG-124589
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINS_RUNTIME_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINS_RUNTIME_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINS_RUNTIME_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINS_RUNTIME_DIR}")
else()
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINS_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINS_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINS_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINS_DIR}")
endif()
else()
if(WIN32)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${BUILD_PLUGINSSRV_RUNTIME_DIR}")
@ -32,10 +40,17 @@ else()
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINSSRV_DIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINSSRV_DIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINSSRV_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINSSRV_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINSSRV_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINSSRV_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINSSRV_DIR}")
if(WIN32 AND Qt6_FOUND)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINSSRV_RUNTIME_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINSSRV_RUNTIME_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINSSRV_RUNTIME_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINSSRV_RUNTIME_DIR}")
else()
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINSSRV_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINSSRV_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINSSRV_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINSSRV_DIR}")
endif()
endif()
if (ENABLE_CHANNELMIMO)

View File

@ -211,6 +211,26 @@ else()
message(STATUS "Not building wdsprx (ENABLE_CHANNELRX_WDSPRX=${ENABLE_CHANNELRX_WDSPRX} WDSP_SUPPORT=${WDSP_SUPPORT})")
endif()
# need ffmpeg 3.1 that correstonds to
# libavutil 55.27.100
# libavcodec 57.48.101
# libavformat 57.40.101
find_package(FFmpeg COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE)
if (ENABLE_CHANNELRX_DEMODDATV AND FFMPEG_FOUND)
if(WIN32)
add_subdirectory(demoddatv)
else()
if(((AVUTIL_VERSION VERSION_GREATER "55.27.99") AND (AVCODEC_VERSION VERSION_GREATER "57.48.101")) OR FFMPEG_EXTERNAL OR FFMPEG_SKIP_CHECK)
message(STATUS "Include demoddatv")
add_subdirectory(demoddatv)
else()
message(STATUS "FFmpeg too old to compile demoddatv; needs at least avutil: 55.27.100, avcodec/avformat: 57.48.101")
endif()
endif()
else()
message(STATUS "Not building demoddatv (ENABLE_CHANNELRX_DEMODDATV=${ENABLE_CHANNELRX_DEMODDATV} FFMPEG_FOUND=${FFMPEG_FOUND})")
endif()
if(NOT SERVER_MODE)
if (ENABLE_CHANNELRX_HEATMAP)
@ -230,25 +250,4 @@ if(NOT SERVER_MODE)
else()
message(STATUS "Not building demodatv (ENABLE_CHANNELRX_DEMODATV=${ENABLE_CHANNELRX_DEMODATV})")
endif()
# need ffmpeg 3.1 that correstonds to
# libavutil 55.27.100
# libavcodec 57.48.101
# libavformat 57.40.101
find_package(FFmpeg COMPONENTS AVCODEC AVFORMAT AVUTIL SWSCALE)
if (ENABLE_CHANNELRX_DEMODDATV AND FFMPEG_FOUND)
if(WIN32)
add_subdirectory(demoddatv)
else()
if(((AVUTIL_VERSION VERSION_GREATER "55.27.99") AND (AVCODEC_VERSION VERSION_GREATER "57.48.101")) OR FFMPEG_EXTERNAL OR FFMPEG_SKIP_CHECK)
message(STATUS "Include demoddatv")
add_subdirectory(demoddatv)
else()
message(STATUS "FFmpeg too old to compile demoddatv; needs at least avutil: 55.27.100, avcodec/avformat: 57.48.101")
endif()
endif()
else()
message(STATUS "Not building demoddatv (ENABLE_CHANNELRX_DEMODDATV=${ENABLE_CHANNELRX_DEMODDATV} FFMPEG_FOUND=${FFMPEG_FOUND})")
endif()
endif()

View File

@ -88,7 +88,7 @@ ChannelAnalyzer::~ChannelAnalyzer()
delete m_networkManager;
m_deviceAPI->removeChannelSinkAPI(this);
m_deviceAPI->removeChannelSink(this);
m_deviceAPI->removeChannelSink(this, true);
if (m_basebandSink->isRunning()) {
stop();
@ -103,7 +103,7 @@ void ChannelAnalyzer::setDeviceAPI(DeviceAPI *deviceAPI)
if (deviceAPI != m_deviceAPI)
{
m_deviceAPI->removeChannelSinkAPI(this);
m_deviceAPI->removeChannelSink(this);
m_deviceAPI->removeChannelSink(this, false);
m_deviceAPI = deviceAPI;
m_deviceAPI->addChannelSink(this);
m_deviceAPI->addChannelSinkAPI(this);

View File

@ -27,7 +27,7 @@
const PluginDescriptor ChannelAnalyzerPlugin::m_pluginDescriptor = {
ChannelAnalyzer::m_channelId,
QStringLiteral("Channel Analyzer"),
QStringLiteral("7.22.1"),
QStringLiteral("7.22.5"),
QStringLiteral("(c) Edouard Griffiths, F4EXB"),
QStringLiteral("https://github.com/f4exb/sdrangel"),
true,

View File

@ -84,7 +84,7 @@ ChannelPower::~ChannelPower()
);
delete m_networkManager;
m_deviceAPI->removeChannelSinkAPI(this);
m_deviceAPI->removeChannelSink(this);
m_deviceAPI->removeChannelSink(this, true);
if (m_basebandSink->isRunning()) {
stop();
@ -98,7 +98,7 @@ void ChannelPower::setDeviceAPI(DeviceAPI *deviceAPI)
if (deviceAPI != m_deviceAPI)
{
m_deviceAPI->removeChannelSinkAPI(this);
m_deviceAPI->removeChannelSink(this);
m_deviceAPI->removeChannelSink(this, false);
m_deviceAPI = deviceAPI;
m_deviceAPI->addChannelSink(this);
m_deviceAPI->addChannelSinkAPI(this);

View File

@ -29,7 +29,7 @@
const PluginDescriptor ChannelPowerPlugin::m_pluginDescriptor = {
ChannelPower::m_channelId,
QStringLiteral("Channel Power"),
QStringLiteral("7.22.1"),
QStringLiteral("7.22.5"),
QStringLiteral("(c) Jon Beniston, M7RCE"),
QStringLiteral("https://github.com/f4exb/sdrangel"),
true,

View File

@ -28,7 +28,6 @@ set(adsb_HEADERS
include_directories(
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
${Boost_INCLUDE_DIRS}
)
if(NOT SERVER_MODE)
@ -47,6 +46,7 @@ if(NOT SERVER_MODE)
adsbdemodicons.qrc
airlinelogos.qrc
flags.qrc
sideviews.qrc
)
set(adsb_HEADERS
${adsb_HEADERS}
@ -60,7 +60,7 @@ if(NOT SERVER_MODE)
)
set(TARGET_NAME ${PLUGINS_PREFIX}demodadsb)
set(TARGET_LIB Qt::Widgets Qt::Quick Qt::QuickWidgets Qt::Positioning)
set(TARGET_LIB Qt::Widgets Qt::Quick Qt::QuickWidgets Qt::Positioning Qt::Charts)
if(Qt${QT_DEFAULT_MAJOR_VERSION}Location_FOUND)
list(APPEND TARGET_LIB Qt::Location)
endif()
@ -86,12 +86,7 @@ if(NOT BUILD_SHARED_LIBS)
set_property(GLOBAL APPEND PROPERTY STATIC_PLUGINS_PROPERTY ${TARGET_NAME})
endif()
if (NOT WIN32)
link_directories(${Boost_LIBRARY_DIRS})
endif()
target_link_libraries(${TARGET_NAME} PRIVATE
Boost::disable_autolinking
Qt::Core
${TARGET_LIB}
sdrbase

View File

@ -17,10 +17,6 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#define BOOST_CHRONO_HEADER_ONLY
#include <boost/chrono/chrono.hpp>
#include <stdio.h>
#include <complex.h>
#include <QTime>
@ -49,6 +45,7 @@
MESSAGE_CLASS_DEFINITION(ADSBDemod::MsgConfigureADSBDemod, Message)
MESSAGE_CLASS_DEFINITION(ADSBDemod::MsgAircraftReport, Message)
MESSAGE_CLASS_DEFINITION(ADSBDemod::MsgResetStats, Message)
const char* const ADSBDemod::m_channelIdURI = "sdrangel.channel.adsbdemod";
const char* const ADSBDemod::m_channelId = "ADSBDemod";
@ -71,7 +68,7 @@ ADSBDemod::ADSBDemod(DeviceAPI *devieAPI) :
m_worker = new ADSBDemodWorker();
m_basebandSink->setMessageQueueToWorker(m_worker->getInputMessageQueue());
applySettings(m_settings, true);
applySettings(m_settings, QStringList(), true);
m_deviceAPI->addChannelSink(this);
m_deviceAPI->addChannelSinkAPI(this);
@ -104,9 +101,9 @@ ADSBDemod::~ADSBDemod()
);
delete m_networkManager;
m_deviceAPI->removeChannelSinkAPI(this);
m_deviceAPI->removeChannelSink(this);
m_deviceAPI->removeChannelSink(this, true);
delete m_basebandSink; // This results in a call to ADSBDemod::stop(), so need to delete before worker and thread
delete m_worker;
delete m_basebandSink;
delete m_thread;
}
@ -115,7 +112,7 @@ void ADSBDemod::setDeviceAPI(DeviceAPI *deviceAPI)
if (deviceAPI != m_deviceAPI)
{
m_deviceAPI->removeChannelSinkAPI(this);
m_deviceAPI->removeChannelSink(this);
m_deviceAPI->removeChannelSink(this, false);
m_deviceAPI = deviceAPI;
m_deviceAPI->addChannelSink(this);
m_deviceAPI->addChannelSinkAPI(this);
@ -147,7 +144,7 @@ void ADSBDemod::start()
m_basebandSink->startWork();
m_thread->start();
ADSBDemodWorker::MsgConfigureADSBDemodWorker *msg = ADSBDemodWorker::MsgConfigureADSBDemodWorker::create(m_settings, true);
ADSBDemodWorker::MsgConfigureADSBDemodWorker *msg = ADSBDemodWorker::MsgConfigureADSBDemodWorker::create(m_settings, QStringList(), true);
m_worker->getInputMessageQueue()->push(msg);
}
@ -169,7 +166,7 @@ bool ADSBDemod::handleMessage(const Message& cmd)
MsgConfigureADSBDemod& cfg = (MsgConfigureADSBDemod&) cmd;
qDebug() << "ADSBDemod::handleMessage: MsgConfigureADSBDemod";
applySettings(cfg.getSettings(), cfg.getForce());
applySettings(cfg.getSettings(), cfg.getSettingsKeys(), cfg.getForce());
return true;
}
@ -194,118 +191,25 @@ bool ADSBDemod::handleMessage(const Message& cmd)
m_aircraftReport = msg.getReport();
return true;
}
else if (MsgResetStats::match(cmd))
{
MsgResetStats& msg = (MsgResetStats&) cmd;
MsgResetStats* rep = new MsgResetStats(msg);
m_basebandSink->getInputMessageQueue()->push(rep);
return true;
}
else
{
return false;
}
}
void ADSBDemod::applySettings(const ADSBDemodSettings& settings, bool force)
void ADSBDemod::applySettings(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force)
{
qDebug() << "ADSBDemod::applySettings:"
<< " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset
<< " m_rfBandwidth: " << settings.m_rfBandwidth
<< " m_streamIndex: " << settings.m_streamIndex
<< " m_useReverseAPI: " << settings.m_useReverseAPI
<< " m_reverseAPIAddress: " << settings.m_reverseAPIAddress
<< " m_reverseAPIPort: " << settings.m_reverseAPIPort
<< " m_reverseAPIDeviceIndex: " << settings.m_reverseAPIDeviceIndex
<< " m_reverseAPIChannelIndex: " << settings.m_reverseAPIChannelIndex
<< settings.getDebugString(settingsKeys, force)
<< " force: " << force;
QList<QString> reverseAPIKeys;
if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force) {
reverseAPIKeys.append("inputFrequencyOffset");
}
if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force) {
reverseAPIKeys.append("rfBandwidth");
}
if ((settings.m_correlationThreshold != m_settings.m_correlationThreshold) || force) {
reverseAPIKeys.append("correlationThreshold");
}
if ((settings.m_samplesPerBit != m_settings.m_samplesPerBit) || force) {
reverseAPIKeys.append("samplesPerBit");
}
if ((settings.m_correlateFullPreamble != m_settings.m_correlateFullPreamble) || force) {
reverseAPIKeys.append("correlateFullPreamble");
}
if ((settings.m_demodModeS != m_settings.m_demodModeS) || force) {
reverseAPIKeys.append("demodModeS");
}
if ((settings.m_interpolatorPhaseSteps != m_settings.m_interpolatorPhaseSteps) || force) {
reverseAPIKeys.append("interpolatorPhaseSteps");
}
if ((settings.m_interpolatorTapsPerPhase != m_settings.m_interpolatorTapsPerPhase) || force) {
reverseAPIKeys.append("interpolatorTapsPerPhase");
}
if ((settings.m_removeTimeout != m_settings.m_removeTimeout) || force) {
reverseAPIKeys.append("removeTimeout");
}
if ((settings.m_feedEnabled != m_settings.m_feedEnabled) || force) {
reverseAPIKeys.append("feedEnabled");
}
if ((settings.m_exportClientEnabled != m_settings.m_exportClientEnabled) || force) {
reverseAPIKeys.append("exportClientEnabled");
}
if ((settings.m_exportClientHost != m_settings.m_exportClientHost) || force) {
reverseAPIKeys.append("exportClientHost");
}
if ((settings.m_exportClientPort != m_settings.m_exportClientPort) || force) {
reverseAPIKeys.append("exportClientPort");
}
if ((settings.m_exportClientFormat != m_settings.m_exportClientFormat) || force) {
reverseAPIKeys.append("exportClientFormat");
}
if ((settings.m_exportServerEnabled != m_settings.m_exportServerEnabled) || force) {
reverseAPIKeys.append("exportServerEnabled");
}
if ((settings.m_exportServerPort != m_settings.m_exportServerPort) || force) {
reverseAPIKeys.append("exportServerPort");
}
if ((settings.m_importEnabled != m_settings.m_importEnabled) || force) {
reverseAPIKeys.append("importEnabled");
}
if ((settings.m_importHost != m_settings.m_importHost) || force) {
reverseAPIKeys.append("importHost");
}
if ((settings.m_importUsername != m_settings.m_importUsername) || force) {
reverseAPIKeys.append("importUsername");
}
if ((settings.m_importPassword != m_settings.m_importPassword) || force) {
reverseAPIKeys.append("importPassword");
}
if ((settings.m_importParameters != m_settings.m_importParameters) || force) {
reverseAPIKeys.append("importParameters");
}
if ((settings.m_importPeriod != m_settings.m_importPeriod) || force) {
reverseAPIKeys.append("importPeriod");
}
if ((settings.m_importMinLatitude != m_settings.m_importMinLatitude) || force) {
reverseAPIKeys.append("importMinLatitude");
}
if ((settings.m_importMaxLatitude != m_settings.m_importMaxLatitude) || force) {
reverseAPIKeys.append("importMaxLatitude");
}
if ((settings.m_importMinLongitude != m_settings.m_importMinLongitude) || force) {
reverseAPIKeys.append("importMinLongitude");
}
if ((settings.m_importMaxLongitude != m_settings.m_importMaxLongitude) || force) {
reverseAPIKeys.append("importMaxLongitude");
}
if ((settings.m_logFilename != m_settings.m_logFilename) || force) {
reverseAPIKeys.append("logFilename");
}
if ((settings.m_logEnabled != m_settings.m_logEnabled) || force) {
reverseAPIKeys.append("logEnabled");
}
if ((settings.m_title != m_settings.m_title) || force) {
reverseAPIKeys.append("title");
}
if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force) {
reverseAPIKeys.append("rfBandwidth");
}
if (m_settings.m_streamIndex != settings.m_streamIndex)
{
if (m_deviceAPI->getSampleMIMO()) // change of stream is possible for MIMO devices only
@ -317,38 +221,40 @@ void ADSBDemod::applySettings(const ADSBDemodSettings& settings, bool force)
m_settings.m_streamIndex = settings.m_streamIndex; // make sure ChannelAPI::getStreamIndex() is consistent
emit streamIndexChanged(settings.m_streamIndex);
}
reverseAPIKeys.append("streamIndex");
}
ADSBDemodBaseband::MsgConfigureADSBDemodBaseband *msg = ADSBDemodBaseband::MsgConfigureADSBDemodBaseband::create(settings, force);
ADSBDemodBaseband::MsgConfigureADSBDemodBaseband *msg = ADSBDemodBaseband::MsgConfigureADSBDemodBaseband::create(settings, settingsKeys, force);
m_basebandSink->getInputMessageQueue()->push(msg);
ADSBDemodWorker::MsgConfigureADSBDemodWorker *workerMsg = ADSBDemodWorker::MsgConfigureADSBDemodWorker::create(settings, force);
ADSBDemodWorker::MsgConfigureADSBDemodWorker *workerMsg = ADSBDemodWorker::MsgConfigureADSBDemodWorker::create(settings, settingsKeys, force);
m_worker->getInputMessageQueue()->push(workerMsg);
if (settings.m_useReverseAPI)
{
bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) ||
(m_settings.m_reverseAPIAddress != settings.m_reverseAPIAddress) ||
(m_settings.m_reverseAPIPort != settings.m_reverseAPIPort) ||
(m_settings.m_reverseAPIDeviceIndex != settings.m_reverseAPIDeviceIndex) ||
(m_settings.m_reverseAPIChannelIndex != settings.m_reverseAPIChannelIndex);
webapiReverseSendSettings(reverseAPIKeys, settings, fullUpdate || force);
bool fullUpdate = (settingsKeys.contains("useReverseAPI") && settings.m_useReverseAPI) ||
settingsKeys.contains("reverseAPIAddress") ||
settingsKeys.contains("reverseAPIPort") ||
settingsKeys.contains("reverseAPIDeviceIndex") ||
settingsKeys.contains("reverseAPIChannelIndex");
webapiReverseSendSettings(settingsKeys, settings, fullUpdate || force);
}
m_settings = settings;
if (force) {
m_settings = settings;
} else {
m_settings.applySettings(settingsKeys, settings);
}
}
void ADSBDemod::setCenterFrequency(qint64 frequency)
{
ADSBDemodSettings settings = m_settings;
settings.m_inputFrequencyOffset = frequency;
applySettings(settings);
applySettings(settings, {"inputFrequencyOffset"}, false);
if (m_guiMessageQueue) // forward to GUI if any
{
MsgConfigureADSBDemod *msgToGUI = MsgConfigureADSBDemod::create(settings, false);
MsgConfigureADSBDemod *msgToGUI = MsgConfigureADSBDemod::create(settings, {"inputFrequencyOffset"}, false);
m_guiMessageQueue->push(msgToGUI);
}
}
@ -368,7 +274,7 @@ bool ADSBDemod::deserialize(const QByteArray& data)
success = false;
}
MsgConfigureADSBDemod *msg = MsgConfigureADSBDemod::create(m_settings, true);
MsgConfigureADSBDemod *msg = MsgConfigureADSBDemod::create(m_settings, QStringList(), true);
m_inputMessageQueue.push(msg);
return success;
@ -404,12 +310,12 @@ int ADSBDemod::webapiSettingsPutPatch(
ADSBDemodSettings settings = m_settings;
webapiUpdateChannelSettings(settings, channelSettingsKeys, response);
MsgConfigureADSBDemod *msg = MsgConfigureADSBDemod::create(settings, force);
MsgConfigureADSBDemod *msg = MsgConfigureADSBDemod::create(settings, channelSettingsKeys, force);
m_inputMessageQueue.push(msg);
if (m_guiMessageQueue) // forward to GUI if any
{
MsgConfigureADSBDemod *msgToGUI = MsgConfigureADSBDemod::create(settings, force);
MsgConfigureADSBDemod *msgToGUI = MsgConfigureADSBDemod::create(settings, channelSettingsKeys, force);
m_guiMessageQueue->push(msgToGUI);
}
@ -435,9 +341,6 @@ void ADSBDemod::webapiUpdateChannelSettings(
if (channelSettingsKeys.contains("samplesPerBit")) {
settings.m_samplesPerBit = response.getAdsbDemodSettings()->getSamplesPerBit();
}
if (channelSettingsKeys.contains("correlateFullPreamble")) {
settings.m_correlateFullPreamble = response.getAdsbDemodSettings()->getCorrelateFullPreamble() != 0;
}
if (channelSettingsKeys.contains("demodModeS")) {
settings.m_demodModeS = response.getAdsbDemodSettings()->getDemodModeS() != 0;
}
@ -556,7 +459,6 @@ void ADSBDemod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& res
response.getAdsbDemodSettings()->setRfBandwidth(settings.m_rfBandwidth);
response.getAdsbDemodSettings()->setCorrelationThreshold(settings.m_correlationThreshold);
response.getAdsbDemodSettings()->setSamplesPerBit(settings.m_samplesPerBit);
response.getAdsbDemodSettings()->setCorrelateFullPreamble(settings.m_correlateFullPreamble ? 1 : 0);
response.getAdsbDemodSettings()->setDemodModeS(settings.m_demodModeS ? 1 : 0);
response.getAdsbDemodSettings()->setInterpolatorPhaseSteps(settings.m_interpolatorPhaseSteps);
response.getAdsbDemodSettings()->setInterpolatorTapsPerPhase(settings.m_interpolatorTapsPerPhase);
@ -661,7 +563,7 @@ void ADSBDemod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& respons
}
}
void ADSBDemod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const ADSBDemodSettings& settings, bool force)
void ADSBDemod::webapiReverseSendSettings(const QList<QString>& channelSettingsKeys, const ADSBDemodSettings& settings, bool force)
{
SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
swgChannelSettings->setDirection(0); // single sink (Rx)
@ -685,9 +587,6 @@ void ADSBDemod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, c
if (channelSettingsKeys.contains("samplesPerBit") || force) {
swgADSBDemodSettings->setSamplesPerBit(settings.m_samplesPerBit);
}
if (channelSettingsKeys.contains("correlateFullPreamble") || force) {
swgADSBDemodSettings->setCorrelateFullPreamble(settings.m_correlateFullPreamble ? 1 : 0);
}
if (channelSettingsKeys.contains("demodModeS") || force) {
swgADSBDemodSettings->setDemodModeS(settings.m_demodModeS ? 1 : 0);
}

View File

@ -20,8 +20,6 @@
#ifndef INCLUDE_ADSBDEMOD_H
#define INCLUDE_ADSBDEMOD_H
#include <vector>
#include <QNetworkRequest>
#include "dsp/basebandsamplesink.h"
@ -44,20 +42,23 @@ public:
public:
const ADSBDemodSettings& getSettings() const { return m_settings; }
const QStringList& getSettingsKeys() const { return m_settingsKeys; }
bool getForce() const { return m_force; }
static MsgConfigureADSBDemod* create(const ADSBDemodSettings& settings, bool force)
static MsgConfigureADSBDemod* create(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force)
{
return new MsgConfigureADSBDemod(settings, force);
return new MsgConfigureADSBDemod(settings, settingsKeys, force);
}
private:
ADSBDemodSettings m_settings;
QStringList m_settingsKeys;
bool m_force;
MsgConfigureADSBDemod(const ADSBDemodSettings& settings, bool force) :
MsgConfigureADSBDemod(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force) :
Message(),
m_settings(settings),
m_settingsKeys(settingsKeys),
m_force(force)
{ }
};
@ -91,6 +92,21 @@ public:
{ }
};
class MsgResetStats : public Message {
MESSAGE_CLASS_DECLARATION
public:
static MsgResetStats* create()
{
return new MsgResetStats();
}
private:
MsgResetStats() :
Message()
{ }
};
ADSBDemod(DeviceAPI *deviceAPI);
virtual ~ADSBDemod();
virtual void destroy() { delete this; }
@ -184,9 +200,9 @@ private:
QNetworkRequest m_networkRequest;
virtual bool handleMessage(const Message& cmd); //!< Processing of a message. Returns true if message has actually been processed
void applySettings(const ADSBDemodSettings& settings, bool force = false);
void applySettings(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force = false);
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response);
void webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const ADSBDemodSettings& settings, bool force);
void webapiReverseSendSettings(const QList<QString>& channelSettingsKeys, const ADSBDemodSettings& settings, bool force);
private slots:
void networkManagerFinished(QNetworkReply *reply);

View File

@ -23,6 +23,7 @@
#include "dsp/downchannelizer.h"
#include "adsbdemodbaseband.h"
#include "adsbdemod.h"
#include "adsb.h"
MESSAGE_CLASS_DEFINITION(ADSBDemodBaseband::MsgConfigureADSBDemodBaseband, Message)
@ -117,7 +118,7 @@ bool ADSBDemodBaseband::handleMessage(const Message& cmd)
MsgConfigureADSBDemodBaseband& cfg = (MsgConfigureADSBDemodBaseband&) cmd;
qDebug() << "ADSBDemodBaseband::handleMessage: MsgConfigureADSBDemodBaseband";
applySettings(cfg.getSettings(), cfg.getForce());
applySettings(cfg.getSettings(), cfg.getSettingsKeys(), cfg.getForce());
return true;
}
@ -132,25 +133,35 @@ bool ADSBDemodBaseband::handleMessage(const Message& cmd)
return true;
}
else if (ADSBDemod::MsgResetStats::match(cmd))
{
m_sink.resetStats();
return true;
}
else
{
return false;
}
}
void ADSBDemodBaseband::applySettings(const ADSBDemodSettings& settings, bool force)
void ADSBDemodBaseband::applySettings(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force)
{
if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset)
|| (settings.m_samplesPerBit != m_settings.m_samplesPerBit) || force)
if ( (settingsKeys.contains("inputFrequencyOffset") && (settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset))
|| (settingsKeys.contains("samplesPerBit") && (settings.m_samplesPerBit != m_settings.m_samplesPerBit))
|| force)
{
int requestedRate = ADS_B_BITS_PER_SECOND * settings.m_samplesPerBit;
m_channelizer->setChannelization(requestedRate, settings.m_inputFrequencyOffset);
m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
}
m_sink.applySettings(settings, force);
m_sink.applySettings(settings, settingsKeys, force);
m_settings = settings;
if (force) {
m_settings = settings;
} else {
m_settings.applySettings(settingsKeys, settings);
}
}
int ADSBDemodBaseband::getChannelSampleRate() const

View File

@ -39,20 +39,23 @@ public:
public:
const ADSBDemodSettings& getSettings() const { return m_settings; }
const QStringList& getSettingsKeys() const { return m_settingsKeys; }
bool getForce() const { return m_force; }
static MsgConfigureADSBDemodBaseband* create(const ADSBDemodSettings& settings, bool force)
static MsgConfigureADSBDemodBaseband* create(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force)
{
return new MsgConfigureADSBDemodBaseband(settings, force);
return new MsgConfigureADSBDemodBaseband(settings, settingsKeys, force);
}
private:
ADSBDemodSettings m_settings;
QStringList m_settingsKeys;
bool m_force;
MsgConfigureADSBDemodBaseband(const ADSBDemodSettings& settings, bool force) :
MsgConfigureADSBDemodBaseband(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force) :
Message(),
m_settings(settings),
m_settingsKeys(settingsKeys),
m_force(force)
{ }
};
@ -80,7 +83,7 @@ private:
QRecursiveMutex m_mutex;
bool handleMessage(const Message& cmd);
void applySettings(const ADSBDemodSettings& settings, bool force = false);
void applySettings(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force = false);
private slots:
void handleInputMessages();

View File

@ -50,7 +50,6 @@ ADSBDemodDisplayDialog::ADSBDemodDisplayDialog(ADSBDemodSettings *settings, QWid
ui->airportSize->setCurrentIndex((int)settings->m_airportMinimumSize);
ui->heliports->setChecked(settings->m_displayHeliports);
ui->units->setCurrentIndex((int)settings->m_siUnits);
ui->displayStats->setChecked(settings->m_displayDemodStats);
ui->autoResizeTableColumns->setChecked(settings->m_autoResizeTableColumns);
ui->aviationstackAPIKey->setText(settings->m_aviationstackAPIKey);
ui->checkWXAPIKey->setText(settings->m_checkWXAPIKey);
@ -67,12 +66,17 @@ ADSBDemodDisplayDialog::ADSBDemodDisplayDialog(ADSBDemodSettings *settings, QWid
ui->mapProvider->setCurrentText(settings->m_mapProvider);
}
ui->mapType->setCurrentIndex((int)settings->m_mapType);
ui->maptilerAPIKey->setText(m_settings->m_maptilerAPIKey);
ui->navAids->setChecked(settings->m_displayNavAids);
ui->atcCallsigns->setChecked(settings->m_atcCallsigns);
ui->photos->setChecked(settings->m_displayPhotos);
ui->verboseModelMatching->setChecked(settings->m_verboseModelMatching);
ui->airfieldElevation->setValue(settings->m_airfieldElevation);
ui->favourLivery->setChecked(settings->m_favourLivery);
ui->transitionAltitude->setValue(settings->m_transitionAlt);
for (auto i = ADSBDemodSettings::m_palettes.cbegin(), end = ADSBDemodSettings::m_palettes.cend(); i != end; ++i) {
ui->flightPathPalette->addItem(i.key());
}
ui->flightPathPalette->setCurrentText(settings->m_flightPathPaletteName);
}
ADSBDemodDisplayDialog::~ADSBDemodDisplayDialog()
@ -82,35 +86,130 @@ ADSBDemodDisplayDialog::~ADSBDemodDisplayDialog()
void ADSBDemodDisplayDialog::accept()
{
m_settings->m_removeTimeout = ui->timeout->value();
m_settings->m_aircraftMinZoom = ui->aircraftMinZoom->value();
m_settings->m_airportRange = ui->airportRange->value();
m_settings->m_airportMinimumSize = (ADSBDemodSettings::AirportType)ui->airportSize->currentIndex();
m_settings->m_displayHeliports = ui->heliports->isChecked();
m_settings->m_siUnits = ui->units->currentIndex() == 0 ? false : true;
m_settings->m_displayDemodStats = ui->displayStats->isChecked();
m_settings->m_autoResizeTableColumns = ui->autoResizeTableColumns->isChecked();
m_settings->m_aviationstackAPIKey = ui->aviationstackAPIKey->text();
m_settings->m_checkWXAPIKey = ui->checkWXAPIKey->text();
m_settings->m_airspaces = QStringList();
if (m_settings->m_removeTimeout != ui->timeout->value())
{
m_settings->m_removeTimeout = ui->timeout->value();
m_settingsKeys.append("removeTimeout");
}
if (m_settings->m_aircraftMinZoom != ui->aircraftMinZoom->value())
{
m_settings->m_aircraftMinZoom = ui->aircraftMinZoom->value();
m_settingsKeys.append("aircraftMinZoom");
}
if (m_settings->m_airportRange != ui->airportRange->value())
{
m_settings->m_airportRange = ui->airportRange->value();
m_settingsKeys.append("airportRange");
}
if (m_settings->m_airportMinimumSize != (ADSBDemodSettings::AirportType)ui->airportSize->currentIndex())
{
m_settings->m_airportMinimumSize = (ADSBDemodSettings::AirportType)ui->airportSize->currentIndex();
m_settingsKeys.append("airportMinimumSize");
}
if (m_settings->m_displayHeliports != ui->heliports->isChecked())
{
m_settings->m_displayHeliports = ui->heliports->isChecked();
m_settingsKeys.append("displayHeliports");
}
if (m_settings->m_siUnits != (ui->units->currentIndex() == 0 ? false : true))
{
m_settings->m_siUnits = ui->units->currentIndex() == 0 ? false : true;
m_settingsKeys.append("siUnits");
}
if (m_settings->m_autoResizeTableColumns != ui->autoResizeTableColumns->isChecked())
{
m_settings->m_autoResizeTableColumns = ui->autoResizeTableColumns->isChecked();
m_settingsKeys.append("autoResizeTableColumns");
}
if (m_settings->m_aviationstackAPIKey != ui->aviationstackAPIKey->text())
{
m_settings->m_aviationstackAPIKey = ui->aviationstackAPIKey->text();
m_settingsKeys.append("aviationstackAPIKey");
}
if (m_settings->m_checkWXAPIKey != ui->checkWXAPIKey->text())
{
m_settings->m_checkWXAPIKey = ui->checkWXAPIKey->text();
m_settingsKeys.append("checkWXAPIKey");
}
QStringList airspaces;
for (int i = 0; i < ui->airspaces->count(); i++)
{
QListWidgetItem *item = ui->airspaces->item(i);
if (item->checkState() == Qt::Checked) {
m_settings->m_airspaces.append(item->text());
airspaces.append(item->text());
}
}
m_settings->m_airspaceRange = ui->airspaceRange->value();
m_settings->m_mapProvider = ui->mapProvider->currentText();
m_settings->m_mapType = (ADSBDemodSettings::MapType)ui->mapType->currentIndex();
m_settings->m_displayNavAids = ui->navAids->isChecked();
m_settings->m_atcCallsigns = ui->atcCallsigns->isChecked();
m_settings->m_displayPhotos = ui->photos->isChecked();
m_settings->m_verboseModelMatching = ui->verboseModelMatching->isChecked();
m_settings->m_airfieldElevation = ui->airfieldElevation->value();
m_settings->m_transitionAlt = ui->transitionAltitude->value();
m_settings->m_tableFontName = m_fontName;
m_settings->m_tableFontSize = m_fontSize;
if (m_settings->m_airspaces != airspaces)
{
m_settings->m_airspaces = airspaces;
m_settingsKeys.append("airspaces");
}
if (m_settings->m_airspaceRange != ui->airspaceRange->value())
{
m_settings->m_airspaceRange = ui->airspaceRange->value();
m_settingsKeys.append("airspaceRange");
}
if (m_settings->m_mapProvider != ui->mapProvider->currentText())
{
m_settings->m_mapProvider = ui->mapProvider->currentText();
m_settingsKeys.append("mapProvider");
}
if (m_settings->m_mapType != (ADSBDemodSettings::MapType)ui->mapType->currentIndex())
{
m_settings->m_mapType = (ADSBDemodSettings::MapType)ui->mapType->currentIndex();
m_settingsKeys.append("mapType");
}
if (m_settings->m_maptilerAPIKey != ui->maptilerAPIKey->text())
{
m_settings->m_maptilerAPIKey = ui->maptilerAPIKey->text();
m_settingsKeys.append("maptilerAPIKey");
}
if (m_settings->m_displayNavAids != ui->navAids->isChecked())
{
m_settings->m_displayNavAids = ui->navAids->isChecked();
m_settingsKeys.append("displayNavAids");
}
if (m_settings->m_atcCallsigns != ui->atcCallsigns->isChecked())
{
m_settings->m_atcCallsigns = ui->atcCallsigns->isChecked();
m_settingsKeys.append("atcCallsigns");
}
if (m_settings->m_displayPhotos != ui->photos->isChecked())
{
m_settings->m_displayPhotos = ui->photos->isChecked();
m_settingsKeys.append("displayPhotos");
}
if (m_settings->m_verboseModelMatching != ui->verboseModelMatching->isChecked())
{
m_settings->m_verboseModelMatching = ui->verboseModelMatching->isChecked();
m_settingsKeys.append("verboseModelMatching");
}
if (m_settings->m_favourLivery != ui->favourLivery->isChecked())
{
m_settings->m_favourLivery = ui->favourLivery->isChecked();
m_settingsKeys.append("favourLivery");
}
if (m_settings->m_transitionAlt != ui->transitionAltitude->value())
{
m_settings->m_transitionAlt = ui->transitionAltitude->value();
m_settingsKeys.append("transitionAlt");
}
if (m_settings->m_tableFontName != m_fontName)
{
m_settings->m_tableFontName = m_fontName;
m_settingsKeys.append("tableFontName");
}
if (m_settings->m_tableFontSize != m_fontSize)
{
m_settings->m_tableFontSize = m_fontSize;
m_settingsKeys.append("tableFontSize");
}
if (m_settings->m_flightPathPaletteName != ui->flightPathPalette->currentText())
{
m_settings->m_flightPathPaletteName = ui->flightPathPalette->currentText();
m_settingsKeys.append("flightPathPaletteName");
m_settings->applyPalette();
}
QDialog::accept();
}

View File

@ -28,6 +28,8 @@ public:
explicit ADSBDemodDisplayDialog(ADSBDemodSettings *settings, QWidget* parent = 0);
~ADSBDemodDisplayDialog();
const QStringList& getSettingsKeys() const { return m_settingsKeys; };
private slots:
void accept();
void on_font_clicked();
@ -35,6 +37,7 @@ private slots:
private:
Ui::ADSBDemodDisplayDialog* ui;
ADSBDemodSettings *m_settings;
QStringList m_settingsKeys;
QString m_fontName;
int m_fontSize;
};

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>417</width>
<height>467</height>
<height>505</height>
</rect>
</property>
<property name="font">
@ -124,22 +124,16 @@
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="displayStatsLabel">
<widget class="QLabel" name="verboseModelMatchingLabel">
<property name="text">
<string>Display demodulator statistics</string>
<string>Log 3D model matching information</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="displayStats">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<widget class="QCheckBox" name="verboseModelMatching">
<property name="toolTip">
<string>Display demodulator statistics</string>
<string>Log information about how aircraft are matched to 3D models</string>
</property>
<property name="text">
<string/>
@ -147,16 +141,16 @@
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="verboseModelMatchingLabel">
<widget class="QLabel" name="favourLiveryLabel">
<property name="text">
<string>Log 3D model matching information</string>
<string>Favour airline livery over aircraft type</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="verboseModelMatching">
<widget class="QCheckBox" name="favourLivery">
<property name="toolTip">
<string>Log information about how aircraft are matched to 3D models</string>
<string>Favour airline livery over aircraft type for 3D models</string>
</property>
<property name="text">
<string/>
@ -192,36 +186,13 @@
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="airfieldElevationLabel">
<property name="text">
<string>Airfield barometric altitude (ft)</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QSpinBox" name="airfieldElevation">
<property name="toolTip">
<string>Barometric altitude reported by aircraft when on airfield surface</string>
</property>
<property name="minimum">
<number>-10000</number>
</property>
<property name="maximum">
<number>30000</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="transitionAltitudeLabel">
<property name="text">
<string>Transition altitude (ft)</string>
</property>
</widget>
</item>
<item row="10" column="1">
<item row="9" column="1">
<widget class="QSpinBox" name="transitionAltitude">
<property name="toolTip">
<string>Transition altitude in feet</string>
@ -232,6 +203,9 @@
<property name="maximum">
<number>20000</number>
</property>
<property name="value">
<number>6000</number>
</property>
</widget>
</item>
</layout>
@ -303,14 +277,14 @@
</item>
</widget>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QLabel" name="aircraftMinZoomLabel">
<property name="text">
<string>Zoom level for aircraft scaling</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="QSpinBox" name="aircraftMinZoom">
<property name="toolTip">
<string>When map zoom (0 min zoom - 15 max zoom) is higher than this value, aircraft icon size will be scaled</string>
@ -320,14 +294,14 @@
</property>
</widget>
</item>
<item row="3" column="0">
<item row="4" column="0">
<widget class="QLabel" name="airportSizeLabel">
<property name="text">
<string>Display airports with size</string>
</property>
</widget>
</item>
<item row="3" column="1">
<item row="4" column="1">
<widget class="QComboBox" name="airportSize">
<property name="toolTip">
<string>Sets the minimum airport size that will be displayed on the map</string>
@ -349,14 +323,14 @@
</item>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QLabel" name="heliportsLabel">
<property name="text">
<string>Display heliports</string>
</property>
</widget>
</item>
<item row="4" column="1">
<item row="5" column="1">
<widget class="QCheckBox" name="heliports">
<property name="toolTip">
<string>When checked, heliports are displayed on the map</string>
@ -366,14 +340,14 @@
</property>
</widget>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QLabel" name="airportRangeLabel">
<property name="text">
<string>Airport display distance (km)</string>
</property>
</widget>
</item>
<item row="5" column="1">
<item row="6" column="1">
<widget class="QSpinBox" name="airportRange">
<property name="toolTip">
<string>Displays airports within the specified distance in kilometres from My Position</string>
@ -383,14 +357,14 @@
</property>
</widget>
</item>
<item row="6" column="0">
<item row="7" column="0">
<widget class="QLabel" name="airspacesLabel">
<property name="text">
<string>Airspaces to display</string>
</property>
</widget>
</item>
<item row="6" column="1">
<item row="7" column="1">
<widget class="QListWidget" name="airspaces">
<property name="toolTip">
<string>Airspace categories to display</string>
@ -547,14 +521,14 @@
</item>
</widget>
</item>
<item row="7" column="0">
<item row="8" column="0">
<widget class="QLabel" name="airspaceRangeLabel">
<property name="text">
<string>Airspace display distance (km)</string>
</property>
</widget>
</item>
<item row="7" column="1">
<item row="8" column="1">
<widget class="QSpinBox" name="airspaceRange">
<property name="toolTip">
<string>Displays airspace within the specified distance in kilometres from My Position</string>
@ -564,14 +538,14 @@
</property>
</widget>
</item>
<item row="8" column="0">
<item row="9" column="0">
<widget class="QLabel" name="displayNavAids">
<property name="text">
<string>Display NAVAIDs</string>
</property>
</widget>
</item>
<item row="8" column="1">
<item row="9" column="1">
<widget class="QCheckBox" name="navAids">
<property name="toolTip">
<string>Display NAVAIDs such as VORs and NDBs</string>
@ -581,7 +555,7 @@
</property>
</widget>
</item>
<item row="9" column="1">
<item row="10" column="1">
<widget class="QCheckBox" name="atcCallsigns">
<property name="toolTip">
<string>Use ATC callsigns (SPEEDBIRD) rather than ICAO (BAW) for aircraft labels on map</string>
@ -591,13 +565,44 @@
</property>
</widget>
</item>
<item row="9" column="0">
<item row="10" column="0">
<widget class="QLabel" name="atcCallsignsLabel">
<property name="text">
<string>Use ATC callsigns on map</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QComboBox" name="flightPathPalette">
<property name="toolTip">
<string>Colour palette to use for aircraft flight paths</string>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="flightPathPaletteLabel">
<property name="text">
<string>Flight path palette</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>Maptiler API key</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="maptilerAPIKey">
<property name="toolTip">
<string>API key for Maptiler (https://maptiler.com) for satellite map</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
@ -607,10 +612,10 @@
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
</property>
</widget>
</item>

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,7 @@
#include <QTextToSpeech>
#include <QRandomGenerator>
#include <QNetworkAccessManager>
#include <QtCharts>
#include "channel/channelgui.h"
#include "dsp/dsptypes.h"
@ -56,11 +57,17 @@ class WebAPIAdapterInterface;
class HttpDownloadManager;
class ADSBDemodGUI;
class ADSBOSMTemplateServer;
class CheckList;
class AircraftModel;
namespace Ui {
class ADSBDemodGUI;
}
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
using namespace QtCharts;
#endif
// Custom widget to allow formatted decimal numbers to be sorted numerically
class CustomDoubleTableWidgetItem : public QTableWidgetItem
{
@ -89,12 +96,16 @@ struct Aircraft {
QString m_icaoHex;
QString m_callsign; // Flight callsign
QString m_flight; // Guess at flight number
bool m_globalPosition; // Position has been determined from global decode
Real m_latitude; // Latitude in decimal degrees
Real m_longitude; // Longitude in decimal degrees
int m_altitude; // Altitude in feet
float m_radius; // Horizontal containment radius limit (Rc) in metres
int m_altitude; // Altitude in feet (will be 0 if on surface)
int m_pressureAltitude; // Pressure altitude in feet for Map PFD altimeter (can be negative on surface)
bool m_onSurface; // Indicates if on surface or airborne
bool m_altitudeGNSS; // Altitude is GNSS HAE (Height above WGS-84 ellipsoid) rather than barometric alitute (relative to 29.92 Hg)
float m_heading; // Heading or track in degrees
float m_heading; // Heading in degrees magnetic
float m_track; // Track in degrees true?
int m_verticalRate; // Vertical climb rate in ft/min
QString m_emitterCategory; // Aircraft type
QString m_status; // Aircraft status
@ -102,23 +113,37 @@ struct Aircraft {
Real m_range; // Distance from station to aircraft
Real m_azimuth; // Azimuth from station to aircraft
Real m_elevation; // Elevation from station to aircraft
QDateTime m_time; // When last updated
QDateTime m_rxTime; // When last frame received (can be long ago if reading from log file)
QDateTime m_updateTime; // Last time we updated data for this aircraft (used for determining when to remove an aircraft)
int m_selAltitude; // Selected altitude in MCP/FCU or FMS in feet
int m_selHeading; // Selected heading in MCP/FCU in degrees
int m_baro; // Aircraft baro setting in mb (Mode-S)
float m_baro; // Aircraft baro setting in mb (Mode-S)
float m_roll; // In degrees
int m_groundspeed; // In knots
float m_turnRate; // In degrees per second
int m_trueAirspeed; // In knots
int m_indicatedAirspeed; // In knots
float m_mach; // Mach number
bool m_autopilot;
bool m_vnavMode;
bool m_altHoldMode;
bool m_approachMode;
bool m_lnavMode;
bool m_tcasOperational; // Appears only to be true if TA/RA, false if TA ONLY
bool m_bdsCapabilities[16][16]; // BDS capabilities are indicaited by BDS 1.7
int m_adsbVersion;
bool m_nicSupplementA;
bool m_nicSupplementB;
bool m_nicSupplementC;
bool m_positionValid; // Indicates if we have valid data for the above fields
bool m_altitudeValid;
bool m_pressureAltitudeValid;
bool m_onSurfaceValid;
bool m_headingValid;
bool m_trackValid;
bool m_verticalRateValid;
bool m_selAltitudeValid;
bool m_selHeadingValid;
@ -129,16 +154,30 @@ struct Aircraft {
bool m_trueAirspeedValid;
bool m_indicatedAirspeedValid;
bool m_machValid;
bool m_autopilotValid;
bool m_vnavModeValid;
bool m_altHoldModeValid;
bool m_approachModeValid;
bool m_lnavModeValid;
bool m_tcasOperationalValid;
bool m_bdsCapabilitiesValid;
bool m_adsbVersionValid;
bool m_nicSupplementAValid;
bool m_nicSupplementBValid;
bool m_nicSupplementCValid;
// State for calculating position using two CPR frames
bool m_cprValid[2];
Real m_cprLat[2];
Real m_cprLong[2];
double m_cprLat[2];
double m_cprLong[2];
QDateTime m_cprTime[2];
int m_adsbFrameCount; // Number of ADS-B frames for this aircraft
int m_modesFrameCount; // Number of Mode-S frames for this aircraft
int m_nonTransponderFrameCount;
int m_tisBFrameCount;
int m_adsrFrameCount;
float m_minCorrelation;
float m_maxCorrelation;
float m_correlation;
@ -148,8 +187,12 @@ struct Aircraft {
bool m_isHighlighted; // Are we highlighting this aircraft in the table and map
bool m_showAll;
QVariantList m_coordinates; // Coordinates we've recorded the aircraft at
QList<QVariantList> m_coordinates; // Coordinates we've recorded the aircraft at, split up in to altitude ranges
QList<QVariantList> m_recentCoordinates; // Last 20 seconds of coordinates for ATC mode
QList<QDateTime> m_coordinateDateTimes;
QList<int> m_coordinateColors; // 0-7 index to 8 color palette according to altitude
QList<int> m_recentCoordinateColors;
int m_lastColor;
AircraftInformation *m_aircraftInfo; // Info about the aircraft from the database
QString m_aircraft3DModel; // 3D model for map based on aircraft type
@ -159,6 +202,7 @@ struct Aircraft {
ADSBDemodGUI *m_gui;
QString m_flagIconURL;
QString m_airlineIconURL;
QString m_sideviewIconURL;
// For animation on 3D map
float m_runwayAltitude;
@ -168,10 +212,14 @@ struct Aircraft {
bool m_rotorStarted; // Rotors started on 'Rotorcraft'
bool m_engineStarted; // Engines started (typically propellors)
QDateTime m_positionDateTime;
QDateTime m_orientationDateTime;
QDateTime m_orientationDateTime; // FIXME
QDateTime m_headingDateTime;
QDateTime m_prevHeadingDateTime;
int m_prevHeading;
QDateTime m_trackDateTime;
QDateTime m_altitudeDateTime;
QDateTime m_indicatedAirspeedDateTime;
QDateTime m_prevTrackDateTime;
int m_prevTrack;
float m_trackWhenHeadingSet;
float m_pitchEst; // Estimated pitch based on vertical rate
float m_rollEst; // Estimated roll based on rate of change in heading
@ -182,30 +230,48 @@ struct Aircraft {
QTableWidgetItem *m_callsignItem;
QTableWidgetItem* m_atcCallsignItem;
QTableWidgetItem *m_modelItem;
QTableWidgetItem *m_typeItem;
QTableWidgetItem *m_sideviewItem;
QTableWidgetItem *m_airlineItem;
QTableWidgetItem *m_latitudeItem;
QTableWidgetItem *m_longitudeItem;
QTableWidgetItem *m_altitudeItem;
QTableWidgetItem *m_headingItem;
QTableWidgetItem *m_trackItem;
QTableWidgetItem *m_verticalRateItem;
CustomDoubleTableWidgetItem *m_rangeItem;
QTableWidgetItem *m_azElItem;
QTableWidgetItem *m_emitterCategoryItem;
QTableWidgetItem *m_statusItem;
QTableWidgetItem *m_squawkItem;
QTableWidgetItem *m_identItem;
QTableWidgetItem *m_registrationItem;
QTableWidgetItem *m_countryItem;
QTableWidgetItem *m_registeredItem;
QTableWidgetItem *m_manufacturerNameItem;
QTableWidgetItem *m_ownerItem;
QTableWidgetItem *m_operatorICAOItem;
QTableWidgetItem *m_interogatorCodeItem;
QTableWidgetItem *m_timeItem;
QTableWidgetItem *m_totalFrameCountItem;
QTableWidgetItem *m_adsbFrameCountItem;
QTableWidgetItem *m_modesFrameCountItem;
QTableWidgetItem *m_nonTransponderItem;
QTableWidgetItem *m_tisBFrameCountItem;
QTableWidgetItem *m_adsrFrameCountItem;
QTableWidgetItem *m_radiusItem;
QTableWidgetItem *m_nacpItem;
QTableWidgetItem *m_nacvItem;
QTableWidgetItem *m_gvaItem;
QTableWidgetItem *m_nicItem;
QTableWidgetItem *m_nicBaroItem;
QTableWidgetItem *m_silItem;
QTableWidgetItem *m_correlationItem;
QTableWidgetItem *m_rssiItem;
QTableWidgetItem *m_flightStatusItem;
QTableWidgetItem *m_depItem;
QTableWidgetItem *m_arrItem;
QTableWidgetItem *m_stopsItem;
QTableWidgetItem *m_stdItem;
QTableWidgetItem *m_etdItem;
QTableWidgetItem *m_atdItem;
@ -218,6 +284,13 @@ struct Aircraft {
QTableWidgetItem *m_apItem;
QTableWidgetItem *m_vModeItem;
QTableWidgetItem *m_lModeItem;
QTableWidgetItem *m_tcasItem;
QTableWidgetItem *m_acasItem;
QTableWidgetItem *m_raItem;
QTableWidgetItem *m_maxSpeedItem;
QTableWidgetItem *m_versionItem;
QTableWidgetItem *m_lengthItem;
QTableWidgetItem *m_widthItem;
QTableWidgetItem *m_rollItem;
QTableWidgetItem *m_groundspeedItem;
QTableWidgetItem *m_turnRateItem;
@ -231,16 +304,18 @@ struct Aircraft {
QTableWidgetItem *m_staticPressureItem;
QTableWidgetItem *m_staticAirTempItem;
QTableWidgetItem *m_humidityItem;
QTableWidgetItem *m_tisBItem;
Aircraft(ADSBDemodGUI *gui) :
m_icao(0),
m_globalPosition(false),
m_latitude(0),
m_longitude(0),
m_radius(0.0f),
m_altitude(0),
m_onSurface(false),
m_altitudeGNSS(false),
m_heading(0),
m_track(0),
m_verticalRate(0),
m_azimuth(0),
m_elevation(0),
@ -253,9 +328,22 @@ struct Aircraft {
m_trueAirspeed(0),
m_indicatedAirspeed(0),
m_mach(0.0f),
m_autopilot(false),
m_vnavMode(false),
m_altHoldMode(false),
m_approachMode(false),
m_lnavMode(false),
m_tcasOperational(false),
m_adsbVersion(0),
m_nicSupplementA(false),
m_nicSupplementB(false),
m_nicSupplementC(false),
m_positionValid(false),
m_altitudeValid(false),
m_pressureAltitudeValid(false),
m_onSurfaceValid(false),
m_headingValid(false),
m_trackValid(false),
m_verticalRateValid(false),
m_selAltitudeValid(false),
m_selHeadingValid(false),
@ -266,9 +354,22 @@ struct Aircraft {
m_trueAirspeedValid(false),
m_indicatedAirspeedValid(false),
m_machValid(false),
m_autopilotValid(false),
m_vnavModeValid(false),
m_altHoldModeValid(false),
m_approachModeValid(false),
m_lnavModeValid(false),
m_tcasOperationalValid(false),
m_bdsCapabilitiesValid(false),
m_adsbVersionValid(false),
m_nicSupplementAValid(false),
m_nicSupplementBValid(false),
m_nicSupplementCValid(false),
m_adsbFrameCount(0),
m_modesFrameCount(0),
m_nonTransponderFrameCount(0),
m_tisBFrameCount(0),
m_adsrFrameCount(0),
m_minCorrelation(INFINITY),
m_maxCorrelation(-INFINITY),
m_correlation(0.0f),
@ -302,9 +403,12 @@ struct Aircraft {
m_callsignItem = new QTableWidgetItem();
m_atcCallsignItem = new QTableWidgetItem();
m_modelItem = new QTableWidgetItem();
m_typeItem = new QTableWidgetItem();
m_sideviewItem = new QTableWidgetItem();
m_airlineItem = new QTableWidgetItem();
m_altitudeItem = new QTableWidgetItem();
m_headingItem = new QTableWidgetItem();
m_trackItem = new QTableWidgetItem();
m_verticalRateItem = new QTableWidgetItem();
m_rangeItem = new CustomDoubleTableWidgetItem();
m_azElItem = new QTableWidgetItem();
@ -313,19 +417,34 @@ struct Aircraft {
m_emitterCategoryItem = new QTableWidgetItem();
m_statusItem = new QTableWidgetItem();
m_squawkItem = new QTableWidgetItem();
m_identItem = new QTableWidgetItem();
m_registrationItem = new QTableWidgetItem();
m_countryItem = new QTableWidgetItem();
m_registeredItem = new QTableWidgetItem();
m_manufacturerNameItem = new QTableWidgetItem();
m_ownerItem = new QTableWidgetItem();
m_operatorICAOItem = new QTableWidgetItem();
m_interogatorCodeItem = new QTableWidgetItem();
m_timeItem = new QTableWidgetItem();
m_totalFrameCountItem = new QTableWidgetItem();
m_adsbFrameCountItem = new QTableWidgetItem();
m_modesFrameCountItem = new QTableWidgetItem();
m_nonTransponderItem = new QTableWidgetItem();
m_tisBFrameCountItem = new QTableWidgetItem();
m_adsrFrameCountItem = new QTableWidgetItem();
m_radiusItem = new QTableWidgetItem();
m_nacpItem = new QTableWidgetItem();
m_nacvItem = new QTableWidgetItem();
m_gvaItem = new QTableWidgetItem();
m_nicItem = new QTableWidgetItem();
m_nicBaroItem = new QTableWidgetItem();
m_silItem = new QTableWidgetItem();
m_correlationItem = new QTableWidgetItem();
m_rssiItem = new QTableWidgetItem();
m_flightStatusItem = new QTableWidgetItem();
m_depItem = new QTableWidgetItem();
m_arrItem = new QTableWidgetItem();
m_stopsItem = new QTableWidgetItem();
m_stdItem = new QTableWidgetItem();
m_etdItem = new QTableWidgetItem();
m_atdItem = new QTableWidgetItem();
@ -338,6 +457,13 @@ struct Aircraft {
m_apItem = new QTableWidgetItem();
m_vModeItem = new QTableWidgetItem();
m_lModeItem = new QTableWidgetItem();
m_tcasItem = new QTableWidgetItem();
m_acasItem = new QTableWidgetItem();
m_raItem = new QTableWidgetItem();
m_maxSpeedItem = new QTableWidgetItem();
m_versionItem = new QTableWidgetItem();
m_lengthItem = new QTableWidgetItem();
m_widthItem = new QTableWidgetItem();
m_rollItem = new QTableWidgetItem();
m_groundspeedItem = new QTableWidgetItem();
m_turnRateItem = new QTableWidgetItem();
@ -351,16 +477,15 @@ struct Aircraft {
m_staticPressureItem = new QTableWidgetItem();
m_staticAirTempItem = new QTableWidgetItem();
m_humidityItem = new QTableWidgetItem();
m_tisBItem = new QTableWidgetItem();
}
QString getImage() const;
QString getText(const ADSBDemodSettings *settings, bool all=false) const;
// Label to use for aircraft on map
QString getLabel(const ADSBDemodSettings *settings) const;
QString getLabel(const ADSBDemodSettings *settings, QDateTime& dateTime) const;
// Name to use when selected as a target (E.g. for use as target name in Rotator Controller)
QString targetName()
QString targetName() const
{
if (!m_callsign.isEmpty())
return QString("Callsign: %1").arg(m_callsign);
@ -368,6 +493,71 @@ struct Aircraft {
return QString("ICAO: %1").arg(m_icao, 0, 16);
}
void setOnSurface(const QDateTime& dateTime);
void setAltitude(int altitudeFt, bool gnss, const QDateTime& dateTime, const ADSBDemodSettings& settings);
void setVerticalRate(int verticalRate, const ADSBDemodSettings& settings);
void setGroundspeed(float groundspeed, const ADSBDemodSettings& settings);
void setTrueAirspeed(int airspeed, const ADSBDemodSettings& settings);
void setIndicatedAirspeed(int airspeed, const QDateTime& dateTime, const ADSBDemodSettings& settings);
void setTrack(float track, const QDateTime& dateTime);
void setHeading(float heading, const QDateTime& dateTime);
void addCoordinate(const QDateTime& dateTime, AircraftModel *model);
void clearCoordinates(AircraftModel *model);
};
class AircraftPathModel : public QAbstractListModel {
Q_OBJECT
public:
using QAbstractListModel::QAbstractListModel;
enum MarkerRoles{
coordinatesRole = Qt::UserRole + 1,
colorRole = Qt::UserRole + 2,
};
AircraftPathModel(AircraftModel *aircraftModel, Aircraft *aircraft) :
m_aircraftModel(aircraftModel),
m_aircraft(aircraft),
m_paths(0),
m_showFullPath(false),
m_showATCPath(false)
{
settingsUpdated();
}
int rowCount(const QModelIndex &parent = QModelIndex()) const override {
(void) parent;
return m_paths;
}
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
void add();
void updateLast();
void removed();
void clear();
void settingsUpdated();
Qt::ItemFlags flags(const QModelIndex &index) const override
{
(void) index;
return Qt::ItemIsEnabled;
}
QHash<int, QByteArray> roleNames() const {
QHash<int, QByteArray> roles;
roles[coordinatesRole] = "coordinates";
roles[colorRole] = "color";
return roles;
}
private:
AircraftModel *m_aircraftModel;
Aircraft *m_aircraft;
int m_paths; // Should match m_aircraft->m_coordinates.count()
bool m_showFullPath;
bool m_showATCPath;
};
// Aircraft data model used by QML map item
@ -385,12 +575,16 @@ public:
aircraftPathRole = Qt::UserRole + 6,
showAllRole = Qt::UserRole + 7,
highlightedRole = Qt::UserRole + 8,
targetRole = Qt::UserRole + 9
targetRole = Qt::UserRole + 9,
radiusRole = Qt::UserRole + 10,
showRadiusRole = Qt::UserRole + 11,
aircraftPathModelRole = Qt::UserRole + 12,
};
Q_INVOKABLE void addAircraft(Aircraft *aircraft) {
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_aircrafts.append(aircraft);
m_pathModels.append(new AircraftPathModel(this, aircraft));
endInsertRows();
}
@ -409,7 +603,8 @@ public:
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
}
void aircraftUpdated(Aircraft *aircraft) {
void aircraftUpdated(Aircraft *aircraft)
{
int row = m_aircrafts.indexOf(aircraft);
if (row >= 0)
{
@ -418,30 +613,72 @@ public:
}
}
void allAircraftUpdated() {
/*
// Not sure why this doesn't work - it should be more efficient
// than the following code
emit dataChanged(index(0), index(rowCount()));
*/
for (int i = 0; i < m_aircrafts.count(); i++)
void highlightChanged(Aircraft *aircraft)
{
int row = m_aircrafts.indexOf(aircraft);
if (row >= 0)
{
QModelIndex idx = index(i);
m_pathModels[row]->settingsUpdated();
QModelIndex idx = index(row);
emit dataChanged(idx, idx);
}
}
void removeAircraft(Aircraft *aircraft) {
void clearCoords(Aircraft *aircraft)
{
int row = m_aircrafts.indexOf(aircraft);
if (row >= 0) {
m_pathModels[row]->clear();
}
}
void aircraftCoordsUpdated(Aircraft *aircraft)
{
int row = m_aircrafts.indexOf(aircraft);
if (row >= 0) {
m_pathModels[row]->updateLast();
}
}
void aircraftCoordsAdded(Aircraft *aircraft)
{
int row = m_aircrafts.indexOf(aircraft);
if (row >= 0) {
m_pathModels[row]->add();
}
}
void aircraftCoordsRemoved(Aircraft *aircraft)
{
int row = m_aircrafts.indexOf(aircraft);
if (row >= 0) {
m_pathModels[row]->removed();
}
}
void allAircraftUpdated()
{
emit dataChanged(index(0), index(rowCount()-1));
for (int i = 0; i < m_aircrafts.count(); i++) {
m_pathModels[i]->settingsUpdated();
}
}
void removeAircraft(Aircraft *aircraft)
{
int row = m_aircrafts.indexOf(aircraft);
if (row >= 0)
{
beginRemoveRows(QModelIndex(), row, row);
m_aircrafts.removeAt(row);
delete m_pathModels.takeAt(row);
endRemoveRows();
}
}
QHash<int, QByteArray> roleNames() const {
QHash<int, QByteArray> roleNames() const
{
QHash<int, QByteArray> roles;
roles[positionRole] = "position";
roles[headingRole] = "heading";
@ -452,22 +689,12 @@ public:
roles[showAllRole] = "showAll";
roles[highlightedRole] = "highlighted";
roles[targetRole] = "target";
roles[radiusRole] = "containmentRadius";
roles[aircraftPathModelRole] = "aircraftPathModel";
return roles;
}
void setFlightPaths(bool flightPaths)
{
m_flightPaths = flightPaths;
allAircraftUpdated();
}
void setAllFlightPaths(bool allFlightPaths)
{
m_allFlightPaths = allFlightPaths;
allAircraftUpdated();
}
void setSettings(const ADSBDemodSettings *settings)
void setSettings(const ADSBDemodSettings *settings)
{
m_settings = settings;
allAircraftUpdated();
@ -487,11 +714,11 @@ public:
}
}
const ADSBDemodSettings *m_settings;
private:
QList<Aircraft *> m_aircrafts;
bool m_flightPaths;
bool m_allFlightPaths;
const ADSBDemodSettings *m_settings;
QList<AircraftPathModel *> m_pathModels;
};
// Airport data model used by QML map item
@ -667,26 +894,34 @@ public:
airspacePolygonRole = Qt::UserRole + 6
};
Q_INVOKABLE void addAirspace(Airspace *airspace) {
Q_INVOKABLE void addAirspace(Airspace *airspace)
{
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_airspaces.append(airspace);
// Convert QPointF to QVariantList of QGeoCoordinates
QVariantList polygon;
for (const auto p : airspace->m_polygon)
{
QGeoCoordinate coord(p.y(), p.x(), airspace->topHeightInMetres());
polygon.push_back(QVariant::fromValue(coord));
}
m_polygons.append(polygon);
updatePolygon(airspace, -1);
endInsertRows();
}
int rowCount(const QModelIndex &parent = QModelIndex()) const override {
int rowCount(const QModelIndex &parent = QModelIndex()) const override
{
Q_UNUSED(parent)
return m_airspaces.count();
}
void removeAllAirspaces() {
void removeAirspace(Airspace *airspace)
{
int idx = m_airspaces.indexOf(airspace);
if (idx >= 0)
{
beginRemoveRows(QModelIndex(), idx, idx);
m_airspaces.removeAt(idx);
m_polygons.removeAt(idx);
endRemoveRows();
}
}
void removeAllAirspaces()
{
if (m_airspaces.count() > 0)
{
beginRemoveRows(QModelIndex(), 0, m_airspaces.count() - 1);
@ -696,6 +931,23 @@ public:
}
}
void airspaceUpdated(const Airspace *airspace)
{
int row = m_airspaces.indexOf(airspace);
if (row >= 0)
{
updatePolygon(airspace, row);
QModelIndex idx = index(row);
emit dataChanged(idx, idx);
}
}
bool contains(const Airspace *airspace)
{
return m_airspaces.contains(airspace);
}
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant& value, int role = Qt::EditRole) override;
@ -706,7 +958,8 @@ public:
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
}
QHash<int, QByteArray> roleNames() const {
QHash<int, QByteArray> roleNames() const
{
QHash<int, QByteArray> roles;
roles[nameRole] = "name";
roles[detailsRole] = "details";
@ -718,8 +971,25 @@ public:
}
private:
QList<Airspace *> m_airspaces;
QList<const Airspace *> m_airspaces;
QList<QVariantList> m_polygons;
void updatePolygon(const Airspace *airspace, int row)
{
// Convert QPointF to QVariantList of QGeoCoordinates
QVariantList polygon;
for (const auto p : airspace->m_polygon)
{
QGeoCoordinate coord(p.y(), p.x(), airspace->topHeightInMetres());
polygon.push_back(QVariant::fromValue(coord));
}
if (row == -1) {
m_polygons.append(polygon);
} else {
m_polygons.replace(row, polygon);
}
}
};
// NavAid model used for each NavAid on the map
@ -811,7 +1081,7 @@ public:
{
m_aircraftRegExp.optimize();
}
virtual ~ModelMatch() = default;
virtual bool match(const QString &aircraft, const QString &manufacturer, QString &model)
@ -867,6 +1137,23 @@ protected:
class ADSBDemodGUI : public ChannelGUI {
Q_OBJECT
struct Interogator {
Real m_minLatitude;
Real m_maxLatitude;
Real m_minLongitude;
Real m_maxLongitude;
bool m_valid;
Airspace m_airspace;
Interogator() :
m_valid(false)
{
}
void update(int ic, Aircraft *aircraft, AirspaceModel *airspaceModel, CheckList *checkList, bool display);
void calcPoly();
};
public:
static ADSBDemodGUI* create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel);
virtual void destroy();
@ -911,6 +1198,7 @@ private:
ChannelMarker m_channelMarker;
RollupState m_rollupState;
ADSBDemodSettings m_settings;
QStringList m_settingsKeys;
qint64 m_deviceCenterFrequency;
int m_basebandSampleRate;
bool m_basicSettingsShown;
@ -922,6 +1210,7 @@ private:
QHash<int, Aircraft *> m_aircraft; // Hashed on ICAO
QSharedPointer<const QHash<int, AircraftInformation *>> m_aircraftInfo;
QSharedPointer<const QHash<QString, AircraftRouteInformation *>> m_routeInfo; // Hashed on callsign
QSharedPointer<const QHash<int, AirportInformation *>> m_airportInfo; // Hashed on id
AircraftModel m_aircraftModel;
AirportModel m_airportModel;
@ -935,12 +1224,85 @@ private:
Aircraft *m_trackAircraft; // Aircraft we want to track in Channel Report
MovingAverageUtil<float, double, 10> m_correlationAvg;
MovingAverageUtil<float, double, 10> m_correlationOnesAvg;
MovingAverageUtil<float, double, 100> m_qnhAvg;
Aircraft *m_highlightAircraft; // Aircraft we want to highlight, when selected in table
float m_currentAirportRange; // Current settings, so we only update if changed
ADSBDemodSettings::AirportType m_currentAirportMinimumSize;
bool m_currentDisplayHeliports;
static const int m_maxRangeDeg = 5;
QList<float> m_maxRange[2];
Airspace m_coverageAirspace[2];
Interogator m_interogators[ADSB_IC_MAX];
enum StatsRow {
ADSB_FRAMES,
MODE_S_FRAMES,
TOTAL_FRAMES,
ADSB_RATE,
MODE_S_RATE,
TOTAL_RATE,
DATA_RATE,
CORRELATOR_MATCHES,
PERCENT_VALID,
PREAMBLE_FAILS,
CRC_FAILS,
TYPE_FAILS,
INVALID_FAILS,
ICAO_FAILS,
RANGE_FAILS,
ALT_FAILS,
AVERAGE_CORRELATION,
TC_0,
TC_1_4,
TC_5_8,
TC_9_18,
TC_19,
TC_20_22,
TC_24,
TC_28,
TC_29,
TC_31,
TC_UNUSED,
DF0,
DF4,
DF5,
DF11,
DF16,
DF17,
DF18,
DF19,
DF20_21,
DF22,
DF24,
MAX_RANGE,
MAX_ALTITUDE,
MAX_RATE
};
qint64 m_rangeFails;
qint64 m_altFails;
QDateTime m_frameRateTime;
qint64 m_adsbFrameRateCount;
qint64 m_modesFrameRateCount;
qint64 m_totalBytes;
float m_maxRangeStat;
float m_maxAltitudeStat;
float m_maxRateState;
qint64 m_dfStats[32];
qint64 m_tcStats[32];
QChart *m_chart;
QLineSeries *m_adsbFrameRateSeries;
QLineSeries *m_modesFrameRateSeries;
QLineSeries *m_aircraftSeries;
QDateTimeAxis *m_xAxis;
QValueAxis *m_fpsYAxis;
QValueAxis *m_aircraftYAxis;
QDateTime m_averageTime;
#ifdef QT_TEXTTOSPEECH_FOUND
QTextToSpeech *m_speech;
#endif
@ -976,19 +1338,22 @@ private:
static const QString m_flightStatuses[];
static const QString m_hazardSeverity[];
static const QString m_fomSources[];
static const QString m_nacvStrings[];
explicit ADSBDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent = 0);
virtual ~ADSBDemodGUI();
QString maptilerAPIKey() const;
void blockApplySettings(bool block);
void applySettings(bool force = false);
void displaySettings();
void applySetting(const QString& settingsKey);
void applySettings(const QStringList& settingsKeys, bool force = false);
void applyAllSettings();
void displaySettings(const QStringList& settingsKeys, bool force);
bool handleMessage(const Message& message);
void makeUIConnections();
void updateAbsoluteCenterFrequency();
void updatePosition(Aircraft *aircraft);
bool updateLocalPosition(Aircraft *aircraft, double latitude, double longitude, bool surfacePosition);
void clearFromMap(const QString& name);
void sendToMap(Aircraft *aircraft, QList<SWGSDRangel::SWGMapAnimation *> *animations);
Aircraft *getAircraft(int icao, bool &newAircraft);
@ -1003,10 +1368,24 @@ private:
float correlationOnes,
unsigned crc,
bool updateModel);
void decodeModeS(const QByteArray data, int df, Aircraft *aircraft);
void decodeID(const QByteArray& data, QString& emitterCategory, QString& callsign);
void decodeGroundspeed(const QByteArray& data, float& v, float& h);
void decodeAirspeed(const QByteArray& data, bool& tas, int& as, bool& hdgValid, float& hdg);
void decodeVerticalRate(const QByteArray& data, int& verticalRate);
void updateAircraftPosition(Aircraft *aircraft, double latitude, double longitude, const QDateTime& dateTime);
bool validateGlobalPosition(double latitude, double longitude, bool countFailure);
bool validateLocalPosition(double latitude, double longitude, bool surfacePosition, bool countFailure);
bool decodeGlobalPosition(int f, const double cprLat[2], const double cprLong[2], const QDateTime cprTime[2], double& latitude, double& longitude, bool countFailure);
bool decodeLocalPosition(int f, double cprLat, double cprLong, bool onSurface, const Aircraft *aircraft, double& latitude, double& longitude, bool countFailure);
void decodeCpr(const QByteArray& data, int& f, double& latCpr, double& lonCpr) const;
bool decodeAltitude(const QByteArray& data, int& altFt) const;
void decodeModeSAltitude(const QByteArray& data, const QDateTime dateTime, Aircraft *aircraft);
void decodeModeS(const QByteArray data, const QDateTime dateTime, int df, Aircraft *aircraft);
void decodeCommB(const QByteArray data, const QDateTime dateTime, int df, Aircraft *aircraft, bool &updatedCallsign);
QList<SWGSDRangel::SWGMapAnimation *> *animate(QDateTime dateTime, Aircraft *aircraft);
SWGSDRangel::SWGMapAnimation *gearAnimation(QDateTime startDateTime, bool up);
SWGSDRangel::SWGMapAnimation *gearAngle(QDateTime startDateTime, bool flat);
SWGSDRangel::SWGMapAnimation *flapsAnimation(QDateTime startDateTime, float currentFlaps, float flaps);
SWGSDRangel::SWGMapAnimation *slatsAnimation(QDateTime startDateTime, bool retract);
SWGSDRangel::SWGMapAnimation *rotorAnimation(QDateTime startDateTime, bool stop);
@ -1019,18 +1398,18 @@ private:
QString subAircraftString(Aircraft *aircraft, const QString &string);
void resizeTable();
QString getDataDir();
void readAirportDB(const QString& filename);
void readAirportFrequenciesDB(const QString& filename);
void update3DModels();
void updateAirports();
void updateAirspaces();
void updateNavAids();
void updateChannelList();
void removeAircraft(QHash<int, Aircraft *>::iterator& i, Aircraft *aircraft);
QAction *createCheckableItem(QString& text, int idx, bool checked);
Aircraft* findAircraftByFlight(const QString& flight);
QString dataTimeToShortString(QDateTime dt);
void initFlightInformation();
void initAviationWeather();
void setShowContainmentRadius(bool show);
void applyMapSettings();
void updatePhotoText(Aircraft *aircraft);
void updatePhotoFlightInformation(Aircraft *aircraft);
@ -1042,16 +1421,33 @@ private:
void applyImportSettings();
void sendAircraftReport();
void updatePosition(float latitude, float longitude, float altitude);
void clearOldHeading(Aircraft *aircraft, const QDateTime& dateTime, float newTrack);
void updateQNH(const Aircraft *aircraft, float qnh);
void setCallsign(Aircraft *aircraft, const QString& callsign);
void initCoverageMap();
void clearCoverageMap();
void updateCoverageMap(float azimuth, float elevation, float distance, float altitude);
void leaveEvent(QEvent*);
void enterEvent(EnterEventType*);
void updateDFStats(int df);
bool updateTCStats(int tc, int row, int low, int high);
void resetStats();
void plotChart();
int countActiveAircraft();
void averageSeries(QLineSeries *series, const QDateTime& startTime, const QDateTime& endTime);
void legendMarkerClicked();
private slots:
void on_deltaFrequency_changed(qint64 value);
void on_rfBW_valueChanged(int value);
void on_threshold_valueChanged(int value);
void on_chipsThreshold_valueChanged(int value);
void on_phaseSteps_valueChanged(int value);
void on_tapsPerPhase_valueChanged(int value);
void statsTable_customContextMenuRequested(QPoint pos);
void adsbData_customContextMenuRequested(QPoint point);
void on_adsbData_cellClicked(int row, int column);
void on_adsbData_cellDoubleClicked(int row, int column);
@ -1060,18 +1456,24 @@ private slots:
void columnSelectMenu(QPoint pos);
void columnSelectMenuChecked(bool checked = false);
void on_spb_currentIndexChanged(int value);
void on_correlateFullPreamble_clicked(bool checked);
void on_demodModeS_clicked(bool checked);
void on_feed_clicked(bool checked);
void on_notifications_clicked();
void on_flightInfo_clicked();
void on_findOnMapFeature_clicked();
void on_getOSNDB_clicked();
void on_deleteAircraft_clicked();
void on_getAircraftDB_clicked();
void on_getAirportDB_clicked();
void on_getAirspacesDB_clicked();
void on_coverage_clicked(bool checked);
void on_displayChart_clicked(bool checked);
void on_stats_clicked(bool checked);
void on_flightPaths_clicked(bool checked);
void on_allFlightPaths_clicked(bool checked);
void on_atcLabels_clicked(bool checked);
void on_displayOrientation_clicked(bool checked);
void on_displayRadius_clicked(bool checked);
void on_ic_globalCheckStateChanged(int state);
void onWidgetRolled(QWidget* widget, bool rollDown);
void onMenuDialogCalled(const QPoint& p);
void handleInputMessages();
@ -1098,6 +1500,12 @@ private slots:
void devicePositionChanged(float latitude, float longitude, float altitude);
void requestMetar(const QString& icao);
void weatherUpdated(const AviationWeather::METAR &metar);
void on_manualQNH_clicked(bool checked);
void on_qnh_valueChanged(int value);
void clearCoverage(const QPoint& p);
void clearStats(const QPoint& p);
void clearChart(const QPoint& p);
void resetChartAxes();
signals:
void homePositionChanged();

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,13 @@
<file>icons/aircraft.png</file>
<file>icons/airport.png</file>
<file>icons/controltower.png</file>
<file>icons/coverage.png</file>
<file>icons/allflightpaths.png</file>
<file>icons/vor.png</file>
<file>icons/stats.png</file>
<file>icons/chart.png</file>
<file>icons/horizontal.png</file>
<file>icons/vertical.png</file>
<file>icons/radius.png</file>
</qresource>
</RCC>

View File

@ -5,14 +5,22 @@
<file>map/map_6_strict.qml</file>
<file>map/ModifiedMapView.qml</file>
<file>map/MapStation.qml</file>
<file>map/aircraft_2engine.png</file>
<file>map/aircraft_2enginesmall.png</file>
<file>map/aircraft_4engine.png</file>
<file>map/aircraft_small.png</file>
<file>map/aircraft_large.png</file>
<file>map/aircraft_heavy_2engine.png</file>
<file>map/aircraft_heavy_4engine.png</file>
<file>map/aircraft_helicopter.png</file>
<file>map/aircraft_light.png</file>
<file>map/aircraft_space.png</file>
<file>map/aircraft_drone.png</file>
<file>map/aircraft_fighter.png</file>
<file>map/aircraft_glider.png</file>
<file>map/spitfire.png</file>
<file>map/a400m.png</file>
<file>map/f35.png</file>
<file>map/apache.png</file>
<file>map/chinook.png</file>
<file>map/eurofighter.png</file>
<file>map/airport_large.png</file>
<file>map/airport_medium.png</file>
<file>map/airport_small.png</file>

View File

@ -25,7 +25,7 @@
// Map main ADS-B table column numbers to combo box indices
std::vector<int> ADSBDemodNotificationDialog::m_columnMap = {
ADSB_COL_ICAO, ADSB_COL_CALLSIGN, ADSB_COL_MODEL,
ADSB_COL_ICAO, ADSB_COL_CALLSIGN, ADSB_COL_MODEL, ADSB_COL_TYPE,
ADSB_COL_ALTITUDE, ADSB_COL_GROUND_SPEED, ADSB_COL_RANGE,
ADSB_COL_CATEGORY, ADSB_COL_STATUS, ADSB_COL_SQUAWK,
ADSB_COL_REGISTRATION, ADSB_COL_MANUFACTURER, ADSB_COL_OWNER, ADSB_COL_OPERATOR_ICAO
@ -117,6 +117,7 @@ void ADSBDemodNotificationDialog::addRow(ADSBDemodSettings::NotificationSettings
match->addItem("ICAO ID");
match->addItem("Callsign");
match->addItem("Aircraft");
match->addItem("Type");
match->addItem("Alt (ft)");
match->addItem("GS (kn)");
match->addItem("D (km)");

View File

@ -36,7 +36,8 @@ void ADSBDemodSettings::resetToDefaults()
{
m_inputFrequencyOffset = 0;
m_rfBandwidth = 2*1300000;
m_correlationThreshold = 10.0f; //<! ones/zero powers correlation threshold in dB
m_correlationThreshold = 7.0f; //<! ones/zero powers correlation threshold in dB
m_chipsThreshold = 0;
m_samplesPerBit = 4;
m_removeTimeout = 60;
m_feedEnabled = false;
@ -73,13 +74,13 @@ void ADSBDemodSettings::resetToDefaults()
m_tableFontName = "Liberation Sans";
m_tableFontSize = 9;
m_displayDemodStats = false;
m_correlateFullPreamble = true;
m_demodModeS = true;
m_autoResizeTableColumns = false;
m_interpolatorPhaseSteps = 4; // Higher than these two values will struggle to run in real-time
m_interpolatorTapsPerPhase = 3.5f; // without gaining much improvement in PER
m_aviationstackAPIKey = "";
m_checkWXAPIKey = "";
m_maptilerAPIKey = "";
for (int i = 0; i < ADSBDEMOD_COLUMNS; i++)
{
m_columnIndexes[i] = i;
@ -98,13 +99,24 @@ void ADSBDemodSettings::resetToDefaults()
m_displayNavAids = true;
m_displayPhotos = true;
m_verboseModelMatching = false;
m_airfieldElevation = 0;
m_aircraftMinZoom = 11;
m_workspaceIndex = 0;
m_hidden = false;
m_atcLabels = true;
m_atcCallsigns = true;
m_transitionAlt = 6000; // Depends on airport. 18,000 in USA
m_qnh = 1013.25;
m_manualQNH = false;
m_displayCoverage = false;
m_displayChart = false;
m_displayOrientation = false;
m_displayRadius = false;
for (int i = 0; i < ADSB_IC_MAX; i++) {
m_displayIC[i] = false;
}
m_flightPathPaletteName = "Spectral";
applyPalette();
m_favourLivery = true;
}
QByteArray ADSBDemodSettings::serialize() const
@ -141,7 +153,6 @@ QByteArray ADSBDemodSettings::serialize() const
s.writeString(25, m_tableFontName);
s.writeS32(26, m_tableFontSize);
s.writeBool(27, m_displayDemodStats);
s.writeBool(28, m_correlateFullPreamble);
s.writeBool(29, m_demodModeS);
s.writeBool(30, m_autoResizeTableColumns);
s.writeS32(31, m_interpolatorPhaseSteps);
@ -165,7 +176,6 @@ QByteArray ADSBDemodSettings::serialize() const
}
s.writeBool(44, m_verboseModelMatching);
s.writeS32(45, m_airfieldElevation);
s.writeBool(46, m_exportClientEnabled);
s.writeBool(47, m_exportServerEnabled);
@ -192,6 +202,19 @@ QByteArray ADSBDemodSettings::serialize() const
s.writeS32(67, m_transitionAlt);
s.writeString(68, m_amDemod);
s.writeFloat(69, m_qnh);
s.writeBool(70, m_manualQNH);
s.writeBool(71, m_displayCoverage);
s.writeBool(72, m_displayChart);
s.writeBool(73, m_displayOrientation);
s.writeBool(74, m_displayRadius);
s.writeString(75, m_flightPathPaletteName);
s.writeS32(76, m_chipsThreshold);
s.writeBool(77, m_favourLivery);
s.writeString(78, m_maptilerAPIKey);
for (int i = 0; i < ADSBDEMOD_COLUMNS; i++) {
s.writeS32(100 + i, m_columnIndexes[i]);
}
@ -229,7 +252,7 @@ bool ADSBDemodSettings::deserialize(const QByteArray& data)
d.readS32(1, &tmp, 0);
m_inputFrequencyOffset = tmp;
d.readReal(2, &m_rfBandwidth, 2*1300000);
d.readReal(3, &m_correlationThreshold, 0.0f);
d.readReal(3, &m_correlationThreshold, 7.0f);
d.readS32(4, &m_samplesPerBit, 4);
d.readS32(5, &m_removeTimeout, 60);
d.readBool(6, &m_feedEnabled, false);
@ -268,7 +291,6 @@ bool ADSBDemodSettings::deserialize(const QByteArray& data)
d.readString(25, &m_tableFontName, "Liberation Sans");
d.readS32(26, &m_tableFontSize, 9);
d.readBool(27, &m_displayDemodStats, false);
d.readBool(28, &m_correlateFullPreamble, true);
d.readBool(29, &m_demodModeS, true);
d.readBool(30, &m_autoResizeTableColumns, false);
d.readS32(31, &m_interpolatorPhaseSteps, 4);
@ -296,7 +318,6 @@ bool ADSBDemodSettings::deserialize(const QByteArray& data)
}
d.readBool(44, &m_verboseModelMatching, false);
d.readS32(45, &m_airfieldElevation, 0);
d.readBool(46, &m_exportClientEnabled, true);
d.readBool(47, &m_exportServerEnabled, true);
@ -328,6 +349,21 @@ bool ADSBDemodSettings::deserialize(const QByteArray& data)
d.readS32(67, &m_transitionAlt, 6000);
d.readString(68, &m_amDemod);
d.readFloat(69, &m_qnh, 1013.25);
d.readBool(70, &m_manualQNH, false);
d.readBool(71, &m_displayCoverage, false);
d.readBool(72, &m_displayChart, false);
d.readBool(73, &m_displayOrientation, false);
d.readBool(74, &m_displayRadius, false);
d.readString(75, &m_flightPathPaletteName, "Spectral");
d.readS32(76, &m_chipsThreshold, 0);
d.readBool(77, &m_favourLivery, true);
d.readString(78, &m_maptilerAPIKey, "");
applyPalette();
#ifdef LINUX
if (m_mapProvider == "osm") {
m_mapProvider = "mapboxgl";
@ -401,3 +437,509 @@ void ADSBDemodSettings::NotificationSettings::updateRegularExpression()
qDebug() << "ADSBDemod: Regular expression is not valid: " << m_regExp;
}
}
void ADSBDemodSettings::applySettings(const QStringList& settingsKeys, const ADSBDemodSettings& settings)
{
if (settingsKeys.contains("inputFrequencyOffset")) {
m_inputFrequencyOffset = settings.m_inputFrequencyOffset;
}
if (settingsKeys.contains("rfBandwidth")) {
m_rfBandwidth = settings.m_rfBandwidth;
}
if (settingsKeys.contains("correlationThreshold")) {
m_correlationThreshold = settings.m_correlationThreshold;
}
if (settingsKeys.contains("chipsThreshold")) {
m_chipsThreshold = settings.m_chipsThreshold;
}
if (settingsKeys.contains("samplesPerBit")) {
m_samplesPerBit = settings.m_samplesPerBit;
}
if (settingsKeys.contains("removeTimeout")) {
m_removeTimeout = settings.m_removeTimeout;
}
if (settingsKeys.contains("feedEnabled")) {
m_feedEnabled = settings.m_feedEnabled;
}
if (settingsKeys.contains("exportClientEnabled")) {
m_exportClientEnabled = settings.m_exportClientEnabled;
}
if (settingsKeys.contains("exportClientHost")) {
m_exportClientHost = settings.m_exportClientHost;
}
if (settingsKeys.contains("exportClientPort")) {
m_exportClientPort = settings.m_exportClientPort;
}
if (settingsKeys.contains("exportClientFormat")) {
m_exportClientFormat = settings.m_exportClientFormat;
}
if (settingsKeys.contains("exportServerEnabled")) {
m_exportServerEnabled = settings.m_exportServerEnabled;
}
if (settingsKeys.contains("exportServerPort")) {
m_exportServerPort = settings.m_exportServerPort;
}
if (settingsKeys.contains("importEnabled")) {
m_importEnabled = settings.m_importEnabled;
}
if (settingsKeys.contains("importHost")) {
m_importHost = settings.m_importHost;
}
if (settingsKeys.contains("importUsername")) {
m_importUsername = settings.m_importUsername;
}
if (settingsKeys.contains("importPassword")) {
m_importPassword = settings.m_importPassword;
}
if (settingsKeys.contains("importParameters")) {
m_importParameters = settings.m_importParameters;
}
if (settingsKeys.contains("importPeriod")) {
m_importPeriod = settings.m_importPeriod;
}
if (settingsKeys.contains("importMinLatitude")) {
m_importMinLatitude = settings.m_importMinLatitude;
}
if (settingsKeys.contains("importMaxLatitude")) {
m_importMaxLatitude = settings.m_importMaxLatitude;
}
if (settingsKeys.contains("importMinLongitude")) {
m_importMinLongitude = settings.m_importMinLongitude;
}
if (settingsKeys.contains("importMaxLongitude")) {
m_importMaxLongitude = settings.m_importMaxLongitude;
}
if (settingsKeys.contains("rgbColor")) {
m_rgbColor = settings.m_rgbColor;
}
if (settingsKeys.contains("title")) {
m_title = settings.m_title;
}
if (settingsKeys.contains("useReverseAPI")) {
m_useReverseAPI = settings.m_useReverseAPI;
}
if (settingsKeys.contains("reverseAPIAddress")) {
m_reverseAPIAddress = settings.m_reverseAPIAddress;
}
if (settingsKeys.contains("reverseAPIPort")) {
m_reverseAPIPort = settings.m_reverseAPIPort;
}
if (settingsKeys.contains("reverseAPIDeviceIndex")) {
m_reverseAPIDeviceIndex = settings.m_reverseAPIDeviceIndex;
}
if (settingsKeys.contains("columnIndexes")) {
std::copy(std::begin(settings.m_columnIndexes), std::end(settings.m_columnIndexes), std::begin(m_columnIndexes));
}
if (settingsKeys.contains("columnSizes")) {
std::copy(std::begin(settings.m_columnSizes), std::end(settings.m_columnIndexes), std::begin(m_columnSizes));
}
if (settingsKeys.contains("airportRange")) {
m_airportRange = settings.m_airportRange;
}
if (settingsKeys.contains("airportMinimumSize")) {
m_airportMinimumSize = settings.m_airportMinimumSize;
}
if (settingsKeys.contains("displayHeliports")) {
m_displayHeliports = settings.m_displayHeliports;
}
if (settingsKeys.contains("flightPaths")) {
m_flightPaths = settings.m_flightPaths;
}
if (settingsKeys.contains("allFlightPaths")) {
m_allFlightPaths = settings.m_allFlightPaths;
}
if (settingsKeys.contains("siUnits")) {
m_siUnits = settings.m_siUnits;
}
if (settingsKeys.contains("tableFontName")) {
m_tableFontName = settings.m_tableFontName;
}
if (settingsKeys.contains("tableFontSize")) {
m_tableFontSize = settings.m_tableFontSize;
}
if (settingsKeys.contains("displayDemodStats")) {
m_displayDemodStats = settings.m_displayDemodStats;
}
if (settingsKeys.contains("demodModeS")) {
m_demodModeS = settings.m_demodModeS;
}
if (settingsKeys.contains("amDemod")) {
m_amDemod = settings.m_amDemod;
}
if (settingsKeys.contains("autoResizeTableColumns")) {
m_autoResizeTableColumns = settings.m_autoResizeTableColumns;
}
if (settingsKeys.contains("interpolatorPhaseSteps")) {
m_interpolatorPhaseSteps = settings.m_interpolatorPhaseSteps;
}
if (settingsKeys.contains("interpolatorTapsPerPhase")) {
m_interpolatorTapsPerPhase = settings.m_interpolatorTapsPerPhase;
}
if (settingsKeys.contains("notificationSettings")) {
m_notificationSettings = settings.m_notificationSettings;
}
if (settingsKeys.contains("aviationstackAPIKey")) {
m_aviationstackAPIKey = settings.m_aviationstackAPIKey;
}
if (settingsKeys.contains("checkWXAPIKey")) {
m_checkWXAPIKey = settings.m_checkWXAPIKey;
}
if (settingsKeys.contains("maptilerAPIKey")) {
m_maptilerAPIKey = settings.m_maptilerAPIKey;
}
if (settingsKeys.contains("logFilename")) {
m_logFilename = settings.m_logFilename;
}
if (settingsKeys.contains("logEnabled")) {
m_logEnabled = settings.m_logEnabled;
}
if (settingsKeys.contains("airspaces")) {
m_airspaces = settings.m_airspaces;
}
if (settingsKeys.contains("airspaceRange")) {
m_airspaceRange = settings.m_airspaceRange;
}
if (settingsKeys.contains("mapProvider")) {
m_mapProvider = settings.m_mapProvider;
}
if (settingsKeys.contains("mapType")) {
m_mapType = settings.m_mapType;
}
if (settingsKeys.contains("displayNavAids")) {
m_displayNavAids = settings.m_displayNavAids;
}
if (settingsKeys.contains("displayPhotos")) {
m_displayPhotos = settings.m_displayPhotos;
}
if (settingsKeys.contains("verboseModelMatching")) {
m_verboseModelMatching = settings.m_verboseModelMatching;
}
if (settingsKeys.contains("aircraftMinZoom")) {
m_aircraftMinZoom = settings.m_aircraftMinZoom;
}
if (settingsKeys.contains("atcLabels")) {
m_atcLabels = settings.m_atcLabels;
}
if (settingsKeys.contains("atcCallsigns")) {
m_atcCallsigns = settings.m_atcCallsigns;
}
if (settingsKeys.contains("transitionAlt")) {
m_transitionAlt = settings.m_transitionAlt;
}
if (settingsKeys.contains("qnh")) {
m_qnh = settings.m_qnh;
}
if (settingsKeys.contains("manualQNH")) {
m_manualQNH = settings.m_manualQNH;
}
if (settingsKeys.contains("displayCoverage")) {
m_displayCoverage = settings.m_displayCoverage;
}
if (settingsKeys.contains("displayChart")) {
m_displayChart = settings.m_displayChart;
}
if (settingsKeys.contains("displayOrientation")) {
m_displayOrientation = settings.m_displayOrientation;
}
if (settingsKeys.contains("displayRadius")) {
m_displayRadius = settings.m_displayRadius;
}
if (settingsKeys.contains("flightPathPaletteName"))
{
m_flightPathPaletteName = settings.m_flightPathPaletteName;
applyPalette();
}
if (settingsKeys.contains("favourLivery")) {
m_favourLivery = settings.m_favourLivery;
}
}
QString ADSBDemodSettings::getDebugString(const QStringList& settingsKeys, bool force) const
{
std::ostringstream ostr;
if (settingsKeys.contains("inputFrequencyOffset") || force) {
ostr << " m_inputFrequencyOffset: " << m_inputFrequencyOffset;
}
if (settingsKeys.contains("rfBandwidth") || force) {
ostr << " m_rfBandwidth: " << m_rfBandwidth;
}
if (settingsKeys.contains("correlationThreshold") || force) {
ostr << " m_correlationThreshold: " << m_correlationThreshold;
}
if (settingsKeys.contains("chipsThreshold") || force) {
ostr << " m_chipsThreshold: " << m_chipsThreshold;
}
if (settingsKeys.contains("samplesPerBit") || force) {
ostr << " m_samplesPerBit: " << m_samplesPerBit;
}
if (settingsKeys.contains("removeTimeout") || force) {
ostr << " m_removeTimeout: " << m_removeTimeout;
}
if (settingsKeys.contains("feedEnabled") || force) {
ostr << " m_feedEnabled: " << m_feedEnabled;
}
if (settingsKeys.contains("exportClientEnabled") || force) {
ostr << " m_exportClientEnabled: " << m_exportClientEnabled;
}
if (settingsKeys.contains("exportClientHost") || force) {
ostr << " m_exportClientHost: " << m_exportClientHost.toStdString();
}
if (settingsKeys.contains("exportClientPort") || force) {
ostr << " m_exportClientPort: " << m_exportClientPort;
}
if (settingsKeys.contains("exportClientFormat") || force) {
ostr << " m_exportClientFormat: " << m_exportClientFormat;
}
if (settingsKeys.contains("exportServerEnabled") || force) {
ostr << " m_exportServerEnabled: " << m_exportServerEnabled;
}
if (settingsKeys.contains("exportServerPort") || force) {
ostr << " m_exportServerPort: " << m_exportServerPort;
}
if (settingsKeys.contains("importEnabled") || force) {
ostr << " m_importEnabled: " << m_importEnabled;
}
if (settingsKeys.contains("importHost") || force) {
ostr << " m_importHost: " << m_importHost.toStdString();
}
if (settingsKeys.contains("importUsername") || force) {
ostr << " m_importUsername: " << m_importUsername.toStdString();
}
if (settingsKeys.contains("importPassword") || force) {
ostr << " m_importPassword: " << m_importPassword.toStdString();
}
if (settingsKeys.contains("importParameters") || force) {
ostr << " m_importParameters: " << m_importParameters.toStdString();
}
if (settingsKeys.contains("importPeriod") || force) {
ostr << " m_importPeriod: " << m_importPeriod;
}
if (settingsKeys.contains("importMinLatitude") || force) {
ostr << " m_importMinLatitude: " << m_importMinLatitude.toStdString();
}
if (settingsKeys.contains("importMaxLatitude") || force) {
ostr << " m_importMaxLatitude: " << m_importMaxLatitude.toStdString();
}
if (settingsKeys.contains("importMinLongitude") || force) {
ostr << " m_importMinLongitude: " << m_importMinLongitude.toStdString();
}
if (settingsKeys.contains("importMaxLongitude") || force) {
ostr << " m_importMaxLongitude: " << m_importMaxLongitude.toStdString();
}
if (settingsKeys.contains("title") || force) {
ostr << " m_title: " << m_title.toStdString();
}
if (settingsKeys.contains("useReverseAPI") || force) {
ostr << " m_useReverseAPI: " << m_useReverseAPI;
}
if (settingsKeys.contains("reverseAPIAddress") || force) {
ostr << " m_reverseAPIAddress: " << m_reverseAPIAddress.toStdString();
}
if (settingsKeys.contains("reverseAPIPort") || force) {
ostr << " m_reverseAPIPort: " << m_reverseAPIPort;
}
if (settingsKeys.contains("reverseAPIDeviceIndex") || force) {
ostr << " m_reverseAPIDeviceIndex: " << m_reverseAPIDeviceIndex;
}
if (settingsKeys.contains("airportRange") || force) {
ostr << " m_airportRange: " << m_airportRange;
}
if (settingsKeys.contains("airportMinimumSize") || force) {
ostr << " m_airportMinimumSize: " << m_airportMinimumSize;
}
if (settingsKeys.contains("displayHeliports") || force) {
ostr << " m_displayHeliports: " << m_displayHeliports;
}
if (settingsKeys.contains("flightPaths") || force) {
ostr << " m_flightPaths: " << m_flightPaths;
}
if (settingsKeys.contains("allFlightPaths") || force) {
ostr << " m_allFlightPaths: " << m_allFlightPaths;
}
if (settingsKeys.contains("siUnits") || force) {
ostr << " m_siUnits: " << m_siUnits;
}
if (settingsKeys.contains("tableFontName") || force) {
ostr << " m_tableFontName: " << m_tableFontName.toStdString();
}
if (settingsKeys.contains("tableFontSize") || force) {
ostr << " m_tableFontSize: " << m_tableFontSize;
}
if (settingsKeys.contains("displayDemodStats") || force) {
ostr << " m_displayDemodStats: " << m_displayDemodStats;
}
if (settingsKeys.contains("demodModeS") || force) {
ostr << " m_demodModeS: " << m_demodModeS;
}
if (settingsKeys.contains("amDemod") || force) {
ostr << " m_amDemod: " << m_amDemod.toStdString();
}
if (settingsKeys.contains("autoResizeTableColumns") || force) {
ostr << " m_autoResizeTableColumns: " << m_autoResizeTableColumns;
}
if (settingsKeys.contains("interpolatorPhaseSteps") || force) {
ostr << " m_interpolatorPhaseSteps: " << m_interpolatorPhaseSteps;
}
if (settingsKeys.contains("notificationSettings") || force) {
//ostr << " m_notificationSettings: " << m_notificationSettings.join(",").toStdString();
}
if (settingsKeys.contains("aviationstackAPIKey") || force) {
ostr << " m_aviationstackAPIKey: " << m_aviationstackAPIKey.toStdString();
}
if (settingsKeys.contains("checkWXAPIKey") || force) {
ostr << " m_checkWXAPIKey: " << m_checkWXAPIKey.toStdString();
}
if (settingsKeys.contains("maptilerAPIKey") || force) {
ostr << " m_maptilerAPIKey: " << m_maptilerAPIKey.toStdString();
}
if (settingsKeys.contains("logFilename") || force) {
ostr << " m_logFilename: " << m_logFilename.toStdString();
}
if (settingsKeys.contains("logEnabled") || force) {
ostr << " m_logEnabled: " << m_logEnabled;
}
if (settingsKeys.contains("airspaces") || force) {
ostr << " m_airspaces: " << m_airspaces.join(",").toStdString();
}
if (settingsKeys.contains("airspaceRange") || force) {
ostr << " m_airspaceRange: " << m_airspaceRange;
}
if (settingsKeys.contains("mapProvider") || force) {
ostr << " m_mapProvider: " << m_mapProvider.toStdString();
}
if (settingsKeys.contains("mapType") || force) {
ostr << " m_mapType: " << m_mapType;
}
if (settingsKeys.contains("displayNavAids") || force) {
ostr << " m_displayNavAids: " << m_displayNavAids;
}
if (settingsKeys.contains("displayPhotos") || force) {
ostr << " m_displayPhotos: " << m_displayPhotos;
}
if (settingsKeys.contains("verboseModelMatching") || force) {
ostr << " m_verboseModelMatching: " << m_verboseModelMatching;
}
if (settingsKeys.contains("aircraftMinZoom") || force) {
ostr << " m_aircraftMinZoom: " << m_aircraftMinZoom;
}
if (settingsKeys.contains("atcLabels") || force) {
ostr << " m_atcLabels: " << m_atcLabels;
}
if (settingsKeys.contains("atcCallsigns") || force) {
ostr << " m_atcCallsigns: " << m_atcCallsigns;
}
if (settingsKeys.contains("transitionAlt") || force) {
ostr << " m_transitionAlt: " << m_transitionAlt;
}
if (settingsKeys.contains("qnh") || force) {
ostr << " m_qnh: " << m_qnh;
}
if (settingsKeys.contains("manualQNH") || force) {
ostr << " m_manualQNH: " << m_manualQNH;
}
if (settingsKeys.contains("displayCoverage") || force) {
ostr << " m_displayCoverage: " << m_displayCoverage;
}
if (settingsKeys.contains("displayChart") || force) {
ostr << " m_displayChart: " << m_displayChart;
}
if (settingsKeys.contains("displayOrientation") || force) {
ostr << " m_displayOrientation: " << m_displayOrientation;
}
if (settingsKeys.contains("displayRadius") || force) {
ostr << " m_displayRadius: " << m_displayRadius;
}
if (settingsKeys.contains("flightPathPaletteName") || force) {
ostr << " m_flightPathPaletteName: " << m_flightPathPaletteName.toStdString();
}
if (settingsKeys.contains("favourLivery") || force) {
ostr << " m_favourLivery: " << m_favourLivery;
}
return QString(ostr.str().c_str());
}
void ADSBDemodSettings::applyPalette()
{
if (m_palettes.contains(m_flightPathPaletteName)) {
m_flightPathPalette = m_palettes.value(m_flightPathPaletteName);
} else {
m_flightPathPalette = m_rainbowPalette;
}
}
const QVariant ADSBDemodSettings::m_rainbowPalette[8] = {
QVariant(QColor(0xff, 0x00, 0x00)),
QVariant(QColor(0xff, 0x7f, 0x00)),
QVariant(QColor(0xff, 0xff, 0x00)),
QVariant(QColor(0xf7, 0xff, 0x00)),
QVariant(QColor(0x00, 0xff, 0x00)),
QVariant(QColor(0x00, 0xff, 0x7f)),
QVariant(QColor(0x00, 0xff, 0xff)),
QVariant(QColor(0x00, 0x7f, 0xff)),
};
const QVariant ADSBDemodSettings::m_pastelPalette[8] = {
QVariant(QColor(0xff, 0xad, 0xad)),
QVariant(QColor(0xff, 0xd6, 0xa5)),
QVariant(QColor(0xfd, 0xff, 0xb6)),
QVariant(QColor(0xca, 0xff, 0xbf)),
QVariant(QColor(0x9b, 0xf6, 0xff)),
QVariant(QColor(0xa0, 0xc4, 0xff)),
QVariant(QColor(0xbd, 0xb2, 0xff)),
QVariant(QColor(0xff, 0xc6, 0xff)),
};
const QVariant ADSBDemodSettings::m_spectralPalette[8] = {
QVariant(QColor(0xd5, 0x3e, 0x4f)),
QVariant(QColor(0xf4, 0x6d, 0x43)),
QVariant(QColor(0xfd, 0xae, 0x61)),
QVariant(QColor(0xfe, 0xe0, 0x8b)),
QVariant(QColor(0xe6, 0xf5, 0x98)),
QVariant(QColor(0xab, 0xdd, 0xa4)),
QVariant(QColor(0x66, 0xc2, 0xa5)),
QVariant(QColor(0x32, 0x88, 0xbd)),
};
const QVariant ADSBDemodSettings::m_bluePalette[8] = {
QVariant(QColor(0xde, 0xeb, 0xf7)),
QVariant(QColor(0xc6, 0xdb, 0xef)),
QVariant(QColor(0x9e, 0xca, 0xe1)),
QVariant(QColor(0x6b, 0xae, 0xd6)),
QVariant(QColor(0x42, 0x92, 0xc6)),
QVariant(QColor(0x21, 0x71, 0xb5)),
QVariant(QColor(0x08, 0x51, 0x9c)),
QVariant(QColor(0x08, 0x30, 0x6b)),
};
const QVariant ADSBDemodSettings::m_purplePalette[8] = {
QVariant(QColor(0xcc, 0xaf, 0xf2)),
QVariant(QColor(0xb6, 0x99, 0xe0)),
QVariant(QColor(0xa0, 0x84, 0xcf)),
QVariant(QColor(0x8a, 0x6f, 0xbd)),
QVariant(QColor(0x76, 0x5a, 0xac)),
QVariant(QColor(0x62, 0x45, 0x9a)),
QVariant(QColor(0x4f, 0x30, 0x89)),
QVariant(QColor(0x3e, 0x18, 0x78)),
};
const QVariant ADSBDemodSettings::m_greyPalette[8] = {
QVariant(QColor(0x80, 0x80, 0x80)),
QVariant(QColor(0x80, 0x80, 0x80)),
QVariant(QColor(0x80, 0x80, 0x80)),
QVariant(QColor(0x80, 0x80, 0x80)),
QVariant(QColor(0x80, 0x80, 0x80)),
QVariant(QColor(0x80, 0x80, 0x80)),
QVariant(QColor(0x80, 0x80, 0x80)),
QVariant(QColor(0x80, 0x80, 0x80)),
};
const QHash<QString, const QVariant *> ADSBDemodSettings::m_palettes = {
{"Rainbow", &ADSBDemodSettings::m_rainbowPalette[0]},
{"Pastel", &ADSBDemodSettings::m_pastelPalette[0]},
{"Spectral", &ADSBDemodSettings::m_spectralPalette[0]},
{"Blues", &ADSBDemodSettings::m_bluePalette[0]},
{"Purples", &ADSBDemodSettings::m_purplePalette[0]},
{"Grey", &ADSBDemodSettings::m_greyPalette[0]},
};

View File

@ -29,63 +29,89 @@
class Serializable;
// Number of columns in the table
#define ADSBDEMOD_COLUMNS 54
#define ADSBDEMOD_COLUMNS 78
// ADS-B table columns
#define ADSB_COL_ICAO 0
#define ADSB_COL_CALLSIGN 1
#define ADSB_COL_ATC_CALLSIGN 2
#define ADSB_COL_MODEL 3
#define ADSB_COL_AIRLINE 4
#define ADSB_COL_COUNTRY 5
#define ADSB_COL_GROUND_SPEED 6
#define ADSB_COL_TRUE_AIRSPEED 7
#define ADSB_COL_INDICATED_AIRSPEED 8
#define ADSB_COL_MACH 9
#define ADSB_COL_SEL_ALTITUDE 10
#define ADSB_COL_ALTITUDE 11
#define ADSB_COL_VERTICALRATE 12
#define ADSB_COL_SEL_HEADING 13
#define ADSB_COL_HEADING 14
#define ADSB_COL_TURNRATE 15
#define ADSB_COL_ROLL 16
#define ADSB_COL_RANGE 17
#define ADSB_COL_AZEL 18
#define ADSB_COL_CATEGORY 19
#define ADSB_COL_STATUS 20
#define ADSB_COL_SQUAWK 21
#define ADSB_COL_REGISTRATION 22
#define ADSB_COL_REGISTERED 23
#define ADSB_COL_MANUFACTURER 24
#define ADSB_COL_OWNER 25
#define ADSB_COL_OPERATOR_ICAO 26
#define ADSB_COL_AP 27
#define ADSB_COL_V_MODE 28
#define ADSB_COL_L_MODE 29
#define ADSB_COL_BARO 30
#define ADSB_COL_HEADWIND 31
#define ADSB_COL_EST_AIR_TEMP 32
#define ADSB_COL_WIND_SPEED 33
#define ADSB_COL_WIND_DIR 34
#define ADSB_COL_STATIC_PRESSURE 35
#define ADSB_COL_STATIC_AIR_TEMP 36
#define ADSB_COL_HUMIDITY 37
#define ADSB_COL_LATITUDE 38
#define ADSB_COL_LONGITUDE 39
#define ADSB_COL_TIME 40
#define ADSB_COL_FRAMECOUNT 41
#define ADSB_COL_TIS_B 42
#define ADSB_COL_CORRELATION 43
#define ADSB_COL_RSSI 44
#define ADSB_COL_FLIGHT_STATUS 45
#define ADSB_COL_DEP 46
#define ADSB_COL_ARR 47
#define ADSB_COL_STD 48
#define ADSB_COL_ETD 49
#define ADSB_COL_ATD 50
#define ADSB_COL_STA 51
#define ADSB_COL_ETA 52
#define ADSB_COL_ATA 53
#define ADSB_COL_TYPE 4
#define ADSB_COL_SIDEVIEW 5
#define ADSB_COL_AIRLINE 6
#define ADSB_COL_COUNTRY 7
#define ADSB_COL_GROUND_SPEED 8
#define ADSB_COL_TRUE_AIRSPEED 9
#define ADSB_COL_INDICATED_AIRSPEED 10
#define ADSB_COL_MACH 11
#define ADSB_COL_SEL_ALTITUDE 12
#define ADSB_COL_ALTITUDE 13
#define ADSB_COL_VERTICALRATE 14
#define ADSB_COL_SEL_HEADING 15
#define ADSB_COL_HEADING 16
#define ADSB_COL_TRACK 17
#define ADSB_COL_TURNRATE 18
#define ADSB_COL_ROLL 19
#define ADSB_COL_RANGE 20
#define ADSB_COL_AZEL 21
#define ADSB_COL_CATEGORY 22
#define ADSB_COL_STATUS 23
#define ADSB_COL_SQUAWK 24
#define ADSB_COL_IDENT 25
#define ADSB_COL_REGISTRATION 26
#define ADSB_COL_REGISTERED 27
#define ADSB_COL_MANUFACTURER 28
#define ADSB_COL_OWNER 29
#define ADSB_COL_OPERATOR_ICAO 30
#define ADSB_COL_AP 31
#define ADSB_COL_V_MODE 32
#define ADSB_COL_L_MODE 33
#define ADSB_COL_TCAS 34
#define ADSB_COL_ACAS 35
#define ADSB_COL_RA 36
#define ADSB_COL_MAX_SPEED 37
#define ADSB_COL_VERSION 38
#define ADSB_COL_LENGTH 39
#define ADSB_COL_WIDTH 40
#define ADSB_COL_BARO 41
#define ADSB_COL_HEADWIND 42
#define ADSB_COL_EST_AIR_TEMP 43
#define ADSB_COL_WIND_SPEED 44
#define ADSB_COL_WIND_DIR 45
#define ADSB_COL_STATIC_PRESSURE 46
#define ADSB_COL_STATIC_AIR_TEMP 47
#define ADSB_COL_HUMIDITY 48
#define ADSB_COL_LATITUDE 49
#define ADSB_COL_LONGITUDE 50
#define ADSB_COL_IC 51
#define ADSB_COL_TIME 52
#define ADSB_COL_FRAMECOUNT 53
#define ADSB_COL_ADSB_FRAMECOUNT 54
#define ADSB_COL_MODES_FRAMECOUNT 55
#define ADSB_COL_NON_TRANSPONDER 56
#define ADSB_COL_TIS_B_FRAMECOUNT 57
#define ADSB_COL_ADSR_FRAMECOUNT 58
#define ADSB_COL_RADIUS 59
#define ADSB_COL_NACP 60
#define ADSB_COL_NACV 61
#define ADSB_COL_GVA 62
#define ADSB_COL_NIC 63
#define ADSB_COL_NIC_BARO 64
#define ADSB_COL_SIL 65
#define ADSB_COL_CORRELATION 66
#define ADSB_COL_RSSI 67
#define ADSB_COL_FLIGHT_STATUS 68
#define ADSB_COL_DEP 69
#define ADSB_COL_ARR 70
#define ADSB_COL_STOPS 71
#define ADSB_COL_STD 72
#define ADSB_COL_ETD 73
#define ADSB_COL_ATD 74
#define ADSB_COL_STA 75
#define ADSB_COL_ETA 76
#define ADSB_COL_ATA 77
#define ADSB_IC_MAX 63
struct ADSBDemodSettings
{
@ -104,6 +130,7 @@ struct ADSBDemodSettings
int32_t m_inputFrequencyOffset;
Real m_rfBandwidth;
Real m_correlationThreshold; //!< Correlation power threshold in dB
int m_chipsThreshold; //!< How many chips in preamble can be incorrect for Mode S
int m_samplesPerBit;
int m_removeTimeout; //!< Time in seconds before removing an aircraft, unless a new frame is received
@ -159,7 +186,6 @@ struct ADSBDemodSettings
QString m_tableFontName; //!< Font to use for table
int m_tableFontSize;
bool m_displayDemodStats;
bool m_correlateFullPreamble;
bool m_demodModeS; //!< Demodulate all Mode-S frames, not just ADS-B
QString m_amDemod; //!< AM Demod to tune to selected ATC frequency
bool m_autoResizeTableColumns;
@ -169,6 +195,7 @@ struct ADSBDemodSettings
QList<NotificationSettings *> m_notificationSettings;
QString m_aviationstackAPIKey; //!< aviationstack.com API key
QString m_checkWXAPIKey; //!< checkwxapi.com API key
QString m_maptilerAPIKey; //!< maptiler.com API key (for osm/satellite map)
QString m_logFilename;
bool m_logEnabled;
@ -186,13 +213,24 @@ struct ADSBDemodSettings
bool m_displayPhotos;
Serializable *m_rollupState;
bool m_verboseModelMatching;
int m_airfieldElevation; //!< QFE in ft so aircraft takeoff/land from correct position
int m_aircraftMinZoom;
bool m_atcLabels;
bool m_atcCallsigns;
int m_transitionAlt;
float m_qnh;
bool m_manualQNH;
bool m_displayCoverage;
bool m_displayChart;
bool m_displayOrientation;
bool m_displayRadius;
bool m_displayIC[ADSB_IC_MAX];
QString m_flightPathPaletteName;
bool m_favourLivery; //!< Favour airline livery over aircraft type when exact 3D model isn't available
const QVariant *m_flightPathPalette;
ADSBDemodSettings();
void resetToDefaults();
void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; }
@ -201,6 +239,18 @@ struct ADSBDemodSettings
bool deserialize(const QByteArray& data);
QByteArray serializeNotificationSettings(QList<NotificationSettings *> notificationSettings) const;
void deserializeNotificationSettings(const QByteArray& data, QList<NotificationSettings *>& notificationSettings);
void applySettings(const QStringList& settingsKeys, const ADSBDemodSettings& settings);
QString getDebugString(const QStringList& settingsKeys, bool force = false) const;
void applyPalette();
static const QVariant m_rainbowPalette[8];
static const QVariant m_pastelPalette[8];
static const QVariant m_spectralPalette[8];
static const QVariant m_bluePalette[8];
static const QVariant m_purplePalette[8];
static const QVariant m_greyPalette[8];
static const QHash<QString, const QVariant *> m_palettes;
};
#endif /* PLUGINS_CHANNELRX_DEMODADSB_ADSBDEMODSETTINGS_H_ */

View File

@ -19,14 +19,16 @@
#include <QTime>
#include <QDebug>
#include "util/profiler.h"
#include "adsbdemodsink.h"
#include "adsbdemodsinkworker.h"
#include "adsbdemod.h"
#include "adsb.h"
ADSBDemodSink::ADSBDemodSink() :
m_channelSampleRate(6000000),
m_channelFrequencyOffset(0),
m_feedTime(0.0),
m_sampleBuffer{nullptr, nullptr, nullptr},
m_worker(this),
m_writeBuffer(0),
@ -37,7 +39,7 @@ ADSBDemodSink::ADSBDemodSink() :
m_magsqCount(0),
m_messageQueueToGUI(nullptr)
{
applySettings(m_settings, true);
applySettings(m_settings, QStringList(), true);
applyChannelSettings(m_channelSampleRate, m_channelFrequencyOffset, true);
for (int i = 0; i < m_buffers; i++)
m_bufferWrite[i].release(1);
@ -53,7 +55,7 @@ ADSBDemodSink::~ADSBDemodSink()
void ADSBDemodSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end)
{
// Start timing how long we are in this function
m_startPoint = boost::chrono::steady_clock::now();
PROFILER_START();
// Optimise for common case, where no resampling or frequency offset
if ((m_interpolatorDistance == 1.0f) && (m_channelFrequencyOffset == 0))
@ -113,8 +115,7 @@ void ADSBDemodSink::feed(const SampleVector::const_iterator& begin, const Sample
}
// Calculate number of seconds in this function
boost::chrono::duration<double> sec = boost::chrono::steady_clock::now() - m_startPoint;
m_feedTime += sec.count();
PROFILER_STOP("ADSB feed");
}
void ADSBDemodSink::processOneSample(Real magsq)
@ -127,8 +128,17 @@ void ADSBDemodSink::processOneSample(Real magsq)
m_writeIdx++;
if (!m_bufferDateTimeValid[m_writeBuffer])
{
m_bufferFirstSampleDateTime[m_writeBuffer] = QDateTime::currentDateTime();
QDateTime dateTime = QDateTime::currentDateTime();
if (m_minFirstSampleDateTime.isValid() && (dateTime < m_minFirstSampleDateTime)) {
dateTime = m_minFirstSampleDateTime;
}
m_bufferFirstSampleDateTime[m_writeBuffer] = dateTime;
m_bufferDateTimeValid[m_writeBuffer] = true;
// Make sure timestamps from different buffers are in order, even if we receive samples faster than real time
const qint64 samplesPerSecondMSec = ADS_B_BITS_PER_SECOND * m_settings.m_samplesPerBit / 1000;
const qint64 offsetMSec = m_bufferSize / samplesPerSecondMSec;
m_minFirstSampleDateTime = dateTime.addMSecs(offsetMSec);
}
if (m_writeIdx >= m_bufferSize)
{
@ -138,15 +148,9 @@ void ADSBDemodSink::processOneSample(Real magsq)
if (m_writeBuffer >= m_buffers)
m_writeBuffer = 0;
// Don't include time spent waiting for a buffer
boost::chrono::duration<double> sec = boost::chrono::steady_clock::now() - m_startPoint;
m_feedTime += sec.count();
if (m_worker.isRunning())
m_bufferWrite[m_writeBuffer].acquire();
m_startPoint = boost::chrono::steady_clock::now();
m_writeIdx = m_samplesPerFrame - 1; // Leave space for copying samples from previous buffer
m_bufferDateTimeValid[m_writeBuffer] = false;
@ -247,37 +251,46 @@ void ADSBDemodSink::applyChannelSettings(int channelSampleRate, int channelFrequ
m_channelFrequencyOffset = channelFrequencyOffset;
}
void ADSBDemodSink::applySettings(const ADSBDemodSettings& settings, bool force)
void ADSBDemodSink::applySettings(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force)
{
qDebug() << "ADSBDemodSink::applySettings:"
<< " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset
<< " m_rfBandwidth: " << settings.m_rfBandwidth
<< " m_correlationThreshold: " << settings.m_correlationThreshold
<< " m_correlateFullPreamble: " << settings.m_correlateFullPreamble
<< " m_demodModeS: " << settings.m_demodModeS
<< " m_samplesPerBit: " << settings.m_samplesPerBit
<< " force: " << force;
if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth)
|| (settings.m_samplesPerBit != m_settings.m_samplesPerBit)
|| (settings.m_interpolatorPhaseSteps != m_settings.m_interpolatorPhaseSteps)
|| (settings.m_interpolatorTapsPerPhase != m_settings.m_interpolatorTapsPerPhase)
if ((settingsKeys.contains("rfBandwidth") && (settings.m_rfBandwidth != m_settings.m_rfBandwidth))
|| (settingsKeys.contains("samplesPerBit") && (settings.m_samplesPerBit != m_settings.m_samplesPerBit))
|| (settingsKeys.contains("interpolatorPhaseSteps") && (settings.m_interpolatorPhaseSteps != m_settings.m_interpolatorPhaseSteps))
|| (settingsKeys.contains("interpolatorTapsPerPhase") && (settings.m_interpolatorTapsPerPhase != m_settings.m_interpolatorTapsPerPhase))
|| force)
{
m_interpolator.create(m_settings.m_interpolatorPhaseSteps, m_channelSampleRate, settings.m_rfBandwidth / 2.2, m_settings.m_interpolatorTapsPerPhase);
m_interpolatorDistanceRemain = 0;
m_interpolatorDistance = (Real) m_channelSampleRate / (Real) (ADS_B_BITS_PER_SECOND * settings.m_samplesPerBit);
m_interpolatorDistance = (Real) m_channelSampleRate / (Real) (ADS_B_BITS_PER_SECOND * settings.m_samplesPerBit);
}
if ((settings.m_samplesPerBit != m_settings.m_samplesPerBit) || force)
if ((settingsKeys.contains("samplesPerBit") && (settings.m_samplesPerBit != m_settings.m_samplesPerBit)) || force)
{
init(settings.m_samplesPerBit);
}
// Forward to worker
ADSBDemodSinkWorker::MsgConfigureADSBDemodSinkWorker *msg = ADSBDemodSinkWorker::MsgConfigureADSBDemodSinkWorker::create(
settings, force);
settings, settingsKeys, force);
m_worker.getInputMessageQueue()->push(msg);
m_settings = settings;
if (force) {
m_settings = settings;
} else {
m_settings.applySettings(settingsKeys, settings);
}
}
void ADSBDemodSink::resetStats()
{
ADSBDemod::MsgResetStats* msg = ADSBDemod::MsgResetStats::create();
m_worker.getInputMessageQueue()->push(msg);
}

View File

@ -19,9 +19,6 @@
#ifndef INCLUDE_ADSBDEMODSINK_H
#define INCLUDE_ADSBDEMODSINK_H
#define BOOST_CHRONO_HEADER_ONLY
#include <boost/chrono/chrono.hpp>
#include "dsp/channelsamplesink.h"
#include "dsp/nco.h"
#include "dsp/interpolator.h"
@ -55,11 +52,12 @@ public:
}
void applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force = false);
void applySettings(const ADSBDemodSettings& settings, bool force = false);
void applySettings(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force = false);
void setMessageQueueToGUI(MessageQueue *messageQueue) { m_messageQueueToGUI = messageQueue; }
void setMessageQueueToWorker(MessageQueue *messageQueue) { m_messageQueueToWorker = messageQueue; }
void startWorker();
void stopWorker();
void resetStats();
private:
friend ADSBDemodSinkWorker;
@ -83,9 +81,6 @@ private:
Real m_interpolatorDistance;
Real m_interpolatorDistanceRemain;
boost::chrono::steady_clock::time_point m_startPoint;
double m_feedTime; //!< Time spent in feed()
// Triple buffering for sharing sample data between two threads
// Top area of each buffer is not used by writer, as it's used by the reader
// for copying the last few samples of the previous buffer, so it can
@ -96,6 +91,7 @@ private:
QSemaphore m_bufferWrite[3]; //!< Semaphore to control write access to the buffers
QSemaphore m_bufferRead[3]; //!< Semaphore to control read access from the buffers
QDateTime m_bufferFirstSampleDateTime[3]; //!< Time for first sample in the buffer
QDateTime m_minFirstSampleDateTime;
bool m_bufferDateTimeValid[3];
ADSBDemodSinkWorker m_worker; //!< Worker thread that does the actual demodulation
int m_writeBuffer; //!< Which of the 3 buffers we're writing in to

View File

@ -15,30 +15,288 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#define BOOST_CHRONO_HEADER_ONLY
#include <boost/chrono/chrono.hpp>
#include <QDebug>
#include "util/db.h"
#include "util/profiler.h"
#include "util/units.h"
#include "util/osndb.h"
#include "util/popcount.h"
#include "adsbdemodreport.h"
#include "adsbdemodsink.h"
#include "adsbdemodsinkworker.h"
#include "adsbdemodsettings.h"
#include "adsbdemod.h"
#include "adsb.h"
MESSAGE_CLASS_DEFINITION(ADSBDemodSinkWorker::MsgConfigureADSBDemodSinkWorker, Message)
const Real ADSBDemodSinkWorker::m_correlationScale = 3.0f;
static int grayToBinary(int gray, int bits)
{
int binary = 0;
for (int i = bits - 1; i >= 0; i--) {
binary = binary | ((((1 << (i+1)) & binary) >> 1) ^ ((1 << i) & gray));
}
return binary;
}
static int gillhamToFeet(int n)
{
int c1 = (n >> 10) & 1;
int a1 = (n >> 9) & 1;
int c2 = (n >> 8) & 1;
int a2 = (n >> 7) & 1;
int c4 = (n >> 6) & 1;
int a4 = (n >> 5) & 1;
int b1 = (n >> 4) & 1;
int b2 = (n >> 3) & 1;
int d2 = (n >> 2) & 1;
int b4 = (n >> 1) & 1;
int d4 = n & 1;
int n500 = grayToBinary((d2 << 7) | (d4 << 6) | (a1 << 5) | (a2 << 4) | (a4 << 3) | (b1 << 2) | (b2 << 1) | b4, 4);
int n100 = grayToBinary((c1 << 2) | (c2 << 1) | c4, 3) - 1;
if (n100 == 6) {
n100 = 4;
}
if (n500 %2 != 0) {
n100 = 4 - n100;
}
return -1200 + n500*500 + n100*100;
}
static int decodeModeSAltitude(const QByteArray& data)
{
int altitude = 0; // Altitude in feet
int altitudeCode = ((data[2] & 0x1f) << 8) | (data[3] & 0xff);
if (altitudeCode & 0x40) // M bit indicates metres
{
int altitudeMetres = ((altitudeCode & 0x1f80) >> 1) | (altitudeCode & 0x3f);
altitude = Units::metresToFeet(altitudeMetres);
}
else
{
// Remove M and Q bits
int altitudeFix = ((altitudeCode & 0x1f80) >> 2) | ((altitudeCode & 0x20) >> 1) | (altitudeCode & 0xf);
// Convert to feet
if (altitudeCode & 0x10) {
altitude = altitudeFix * 25 - 1000;
} else {
altitude = gillhamToFeet(altitudeFix);
}
}
return altitude;
}
void ADSBDemodSinkWorker::handleModeS(unsigned char *data, int bytes, unsigned icao, int df, int firstIndex, unsigned short preamble, Real preambleCorrelation, Real correlationOnes, const QDateTime& dateTime, unsigned crc)
{
// Ignore downlink formats we can't decode / unlikely
if ((df != 19) && (df != 22) && (df < 24))
{
QList<RXRecord> l;
if (m_modeSOnlyIcaos.contains(icao))
{
l = m_modeSOnlyIcaos.value(icao);
if (abs(l.last().m_firstIndex - firstIndex) < 4) {
return; // Duplicate
}
}
else
{
// Stop hash table from getting too big - clear every 10 seconds or so
QDateTime currentDateTime = QDateTime::currentDateTime();
if (m_lastClear.secsTo(currentDateTime) >= 10)
{
//qDebug() << "Clearing ModeS only hash. size=" << m_modeSOnlyIcaos.size();
m_modeSOnlyIcaos.clear();
m_lastClear = currentDateTime;
}
}
RXRecord rx;
rx.m_data = QByteArray((char*)data, bytes);
rx.m_firstIndex = firstIndex;
rx.m_preamble = preamble;
rx.m_preambleCorrelation = preambleCorrelation;
rx.m_correlationOnes = correlationOnes;
rx.m_dateTime = dateTime;
rx.m_crc = crc;
l.append(rx);
m_modeSOnlyIcaos.insert(icao, l);
// Have we heard from the same address several times in the last 10 seconds?
if (l.size() >= 5)
{
// Check all frames have consistent altitudes and identifiers
bool idConsistent = true;
bool altitudeConsistent = true;
int altitude = -1;
int id = -1;
for (int i = 0; i < l.size(); i++)
{
int df2 = ((l[i].m_data[0] >> 3) & ADS_B_DF_MASK);
if ((df2 == 0) || (df2 == 4) || (df2 == 16) || (df2 == 20))
{
int curAltitude = decodeModeSAltitude(l[i].m_data);
if (altitude == -1)
{
altitude = curAltitude;
}
else
{
if (abs(curAltitude - altitude) > 1000) {
altitudeConsistent = false;
}
}
}
else if ((df2 == 5) || (df2 == 21))
{
int curId = ((data[2] & 0x1f) << 8) | (data[3] & 0xff); // No decode - we just want to know if it changes
if (id == -1)
{
id = curId;
}
else
{
if (id != curId) {
idConsistent = false;
}
}
}
}
// FIXME: We could optionally check to see if aircraft ICAO is in db, but the db isn't complete
if (altitudeConsistent && idConsistent)
{
// Forward all frames
for (int i = 0; i < l.size(); i++) {
forwardFrame((const unsigned char *) l[i].m_data.data(), l[i].m_data.size(), l[i].m_preambleCorrelation, l[i].m_correlationOnes, l[i].m_dateTime, l[i].m_crc);
}
m_icaos.insert(icao, l.back().m_dateTime.toMSecsSinceEpoch());
}
else
{
m_modeSOnlyIcaos.remove(icao);
}
}
}
}
// Check if a Mode S frame has reserved bits set or reserved field values
// Refer: Annex 10 Volume IV
bool ADSBDemodSinkWorker::modeSValid(unsigned char *data, unsigned df)
{
bool invalid = false;
if (df == 0)
{
invalid = ((data[0] & 0x1) | (data[1] & 0x18) | (data[2] & 0x60)) != 0;
}
else if ((df == 4) || (df == 20))
{
unsigned fs = data[0] & 0x3;
unsigned dr = (data[1] >> 3) & 0x1f;
invalid = (fs == 6) || (fs == 7) || ((dr >= 8) && (dr <= 15));
}
else if ((df == 5) || (df == 21))
{
unsigned fs = data[0] & 0x3;
unsigned dr = (data[1] >> 3) & 0x1f;
invalid = (fs == 6) || (fs == 7) || ((dr >= 8) && (dr <= 15)) || ((data[3] & 0x40) != 0);
}
else if (df == 11)
{
unsigned ca = data[0] & 0x7;
invalid = ((ca >= 1) && (ca <= 3));
}
else if (df == 16)
{
invalid = ((data[0] & 0x3) | (data[1] & 0x18) | (data[2] & 0x60)) != 0;
}
return invalid;
}
// Check if valid ICAO address - i.e. not a reserved address - see Table 9-1 in Annex X Volume III
bool ADSBDemodSinkWorker::icaoValid(unsigned icao)
{
unsigned msn = (icao >> 20) & 0xf;
return (icao != 0) && (msn != 0xf) && (msn != 0xb) && (msn != 0xd);
}
// Is it less than a minute since the last received frame for this ICAO
bool ADSBDemodSinkWorker::icaoHeardRecently(unsigned icao, const QDateTime &dateTime)
{
const int timeLimitMSec = 60*1000;
if (m_icaos.contains(icao))
{
if ((dateTime.toMSecsSinceEpoch() - m_icaos.value(icao)) < timeLimitMSec) {
return true;
} else {
m_icaos.remove(icao);
}
}
return false;
}
void ADSBDemodSinkWorker::forwardFrame(const unsigned char *data, int size, float preambleCorrelation, float correlationOnes, const QDateTime& dateTime, unsigned crc)
{
// Pass to GUI
if (m_sink->getMessageQueueToGUI())
{
ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create(
QByteArray((char*)data, size),
preambleCorrelation,
correlationOnes,
dateTime,
crc);
m_sink->getMessageQueueToGUI()->push(msg);
}
// Pass to worker to feed to other servers
if (m_sink->getMessageQueueToWorker())
{
ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create(
QByteArray((char*)data, size),
preambleCorrelation,
correlationOnes,
dateTime,
crc);
m_sink->getMessageQueueToWorker()->push(msg);
}
}
void ADSBDemodSinkWorker::run()
{
int readBuffer = 0;
m_lastClear = QDateTime::currentDateTime();
// Acquire first buffer
m_sink->m_bufferRead[readBuffer].acquire();
if (isInterruptionRequested()) {
return;
}
// Start recording how much time is spent processing in this method
boost::chrono::steady_clock::time_point startPoint = boost::chrono::steady_clock::now();
PROFILER_START();
// Check for updated settings
handleInputMessages();
@ -52,8 +310,6 @@ void ADSBDemodSinkWorker::run()
<< " samplesPerFrame: " << samplesPerFrame
<< " samplesPerChip: " << samplesPerChip
<< " samplesPerBit: " << samplesPerBit
<< " correlateFullPreamble: " << m_settings.m_correlateFullPreamble
<< " correlationScale: " << m_correlationScale
<< " correlationThreshold: " << m_settings.m_correlationThreshold;
int readIdx = m_sink->m_samplesPerFrame - 1;
@ -64,61 +320,33 @@ void ADSBDemodSinkWorker::run()
// Correlate received signal with expected preamble
// chip+ indexes are 0, 2, 7, 9
// correlating over first 6 bits gives a reduction in per-sample
// processing, but more than doubles the number of false matches
Real preambleCorrelationOnes = 0.0;
Real preambleCorrelationZeros = 0.0;
if (m_settings.m_correlateFullPreamble)
for (int i = 0; i < samplesPerChip; i++)
{
for (int i = 0; i < samplesPerChip; i++)
{
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 0*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 1*samplesPerChip + i];
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 0*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 1*samplesPerChip + i];
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 2*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 3*samplesPerChip + i];
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 2*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 3*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 4*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 5*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 4*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 5*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 6*samplesPerChip + i];
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 7*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 6*samplesPerChip + i];
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 7*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 8*samplesPerChip + i];
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 9*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 8*samplesPerChip + i];
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 9*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 10*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 11*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 10*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 11*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 12*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 13*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 12*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 13*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 14*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 15*samplesPerChip + i];
}
}
else
{
for (int i = 0; i < samplesPerChip; i++)
{
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 0*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 1*samplesPerChip + i];
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 2*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 3*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 4*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 5*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 6*samplesPerChip + i];
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 7*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 8*samplesPerChip + i];
preambleCorrelationOnes += m_sink->m_sampleBuffer[readBuffer][startIdx + 9*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 10*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 11*samplesPerChip + i];
}
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 14*samplesPerChip + i];
preambleCorrelationZeros += m_sink->m_sampleBuffer[readBuffer][startIdx + 15*samplesPerChip + i];
}
// Use the ratio of ones power over zeros power, as we don't care how powerful the signal
@ -139,6 +367,7 @@ void ADSBDemodSinkWorker::run()
int firstIdx = startIdx;
m_demodStats.m_correlatorMatches++;
// Skip over preamble
startIdx += samplesPerBit*ADS_B_PREAMBLE_BITS;
@ -148,6 +377,7 @@ void ADSBDemodSinkWorker::run()
int currentBit;
unsigned char currentByte = 0;
int df;
int firstIndex = 0;
for (int bit = 0; bit < ADS_B_ES_BITS; bit++)
{
@ -166,6 +396,9 @@ void ADSBDemodSinkWorker::run()
currentByte |= currentBit << (7-(bit & 0x7));
if ((bit & 0x7) == 0x7)
{
if (byteIdx == 0) {
firstIndex = startIdx;
}
data[byteIdx++] = currentByte;
currentByte = 0;
// Don't try to demodulate any further, if this isn't an ADS-B frame
@ -179,6 +412,10 @@ void ADSBDemodSinkWorker::run()
}
}
Real preambleCorrelationScaled = preambleCorrelation * m_correlationScale;
Real correlationOnes = preambleCorrelationOnes / samplesPerChip;
QDateTime dateTime = rxDateTime(firstIdx, readBuffer);
// Is ADS-B?
df = ((data[0] >> 3) & ADS_B_DF_MASK);
if ((df == 17) || (df == 18))
@ -189,109 +426,177 @@ void ADSBDemodSinkWorker::run()
m_crc.calculate(data, ADS_B_ES_BYTES-3);
if (parity == m_crc.get())
{
// Got a valid frame
m_demodStats.m_adsbFrames++;
// Get 24-bit ICAO and save in hash of ICAOs that have been seen
// Get 24-bit ICAO
unsigned icao = ((data[1] & 0xff) << 16) | ((data[2] & 0xff) << 8) | (data[3] & 0xff);
m_icaos.insert(icao, true);
// Don't try to re-demodulate the same frame
// We could possibly allow a partial overlap here
readIdx += (ADS_B_ES_BITS+ADS_B_PREAMBLE_BITS)*ADS_B_CHIPS_PER_BIT*samplesPerChip - 1;
// Pass to GUI
if (m_sink->getMessageQueueToGUI())
if (icaoValid(icao))
{
ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create(
QByteArray((char*)data, sizeof(data)),
preambleCorrelation * m_correlationScale,
preambleCorrelationOnes / samplesPerChip,
rxDateTime(firstIdx, readBuffer),
m_crc.get());
m_sink->getMessageQueueToGUI()->push(msg);
// Got a valid frame
m_demodStats.m_adsbFrames++;
// Save in hash of ICAOs that have been seen
m_icaos.insert(icao, dateTime.toMSecsSinceEpoch());
// Don't try to re-demodulate the same frame
// We could possibly allow a partial overlap here
readIdx += (ADS_B_ES_BITS+ADS_B_PREAMBLE_BITS)*ADS_B_CHIPS_PER_BIT*samplesPerChip - 1;
forwardFrame(data, sizeof(data), preambleCorrelationScaled, correlationOnes, dateTime, m_crc.get());
}
// Pass to worker to feed to other servers
if (m_sink->getMessageQueueToWorker())
else
{
ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create(
QByteArray((char*)data, sizeof(data)),
preambleCorrelation * m_correlationScale,
preambleCorrelationOnes / samplesPerChip,
rxDateTime(firstIdx, readBuffer),
m_crc.get());
m_sink->getMessageQueueToWorker()->push(msg);
m_demodStats.m_icaoFails++;
}
}
else
{
m_demodStats.m_crcFails++;
}
}
else if (m_settings.m_demodModeS)
{
int bytes;
// Decode premable, as correlation alone results in too many false positives for Mode S frames
startIdx = readIdx;
unsigned short preamble = 0;
QVector<float> preambleChips(16);
// Determine number of bytes in frame depending on downlink format
if ((df == 0) || (df == 4) || (df == 5) || (df == 11)) {
bytes = 56/8;
} else if ((df == 16) || (df == 20) || (df == 21) || (df >= 24)) {
bytes = 112/8;
} else {
bytes = 0;
}
if (bytes > 0)
for (int bit = 0; bit < ADS_B_PREAMBLE_BITS; bit++)
{
// Extract received parity
int parity = (data[bytes-3] << 16) | (data[bytes-2] << 8) | data[bytes-1];
// Calculate CRC on received frame
m_crc.init();
m_crc.calculate(data, bytes-3);
int crc = m_crc.get();
// DF4 / DF5 / DF20 / DF21 have ICAO address XORed in to parity.
// Extract ICAO from parity and see if it matches an aircraft we've already
// received an ADS-B frame from
if ((df == 4) || (df == 5) || (df == 20) || (df == 21))
preambleChips[bit*2] = 0.0f;
preambleChips[bit*2+1] = 0.0f;
for (int i = 0; i < samplesPerChip; i++)
{
unsigned icao = (parity ^ crc) & 0xffffff;
if (m_icaos.contains(icao)) {
crc ^= icao;
}
preambleChips[bit*2] += m_sink->m_sampleBuffer[readBuffer][startIdx+i];
preambleChips[bit*2+1] += m_sink->m_sampleBuffer[readBuffer][startIdx+samplesPerChip+i];
}
// For DF11, the last 7 bits may have an address/interogration identifier (II)
// XORed in, so we ignore those bits
if ((parity == crc) || ((df == 11) && ((parity & 0xffff80) == (crc & 0xffff80))))
startIdx += samplesPerBit;
}
startIdx = firstIdx;
float onesAvg = (preambleChips[0] + preambleChips[2] + preambleChips[7] + preambleChips[9]) / 4.0f;
float zerosAvg = (preambleChips[1] + preambleChips[3] + preambleChips[4] + preambleChips[5] + preambleChips[6] + preambleChips[8]
+ preambleChips[10] + + preambleChips[11] + preambleChips[12] + preambleChips[13] + preambleChips[14] + preambleChips[15]) / 12.0f;
float midPoint = zerosAvg + (onesAvg - zerosAvg) / 2.0f;
for (int i = 0; i < 16; i++)
{
unsigned chip = preambleChips[i] > midPoint;
preamble |= chip << (15-i);
}
// qDebug() << "Preamble" << preambleChips << "zerosAvg" << zerosAvg << "onesAvg" << onesAvg << "midPoint" << midPoint << "chips" << Qt::hex << preamble;
const unsigned short expectedPreamble = 0xa140;
int preambleDifferences = popcount(expectedPreamble ^ preamble);
if (preambleDifferences <= m_settings.m_chipsThreshold)
{
int bytes;
// Determine number of bytes in frame depending on downlink format
if ((df == 0) || (df == 4) || (df == 5) || (df == 11)) {
bytes = 56/8;
} else if ((df == 16) || (df == 19) || (df == 20) || (df == 21) || (df == 22) || ((df >= 24) && (df <= 27))) {
bytes = 112/8;
} else {
bytes = 0;
}
if (bytes > 0)
{
m_demodStats.m_modesFrames++;
// Pass to GUI (only pass formats it can decode)
if (m_sink->getMessageQueueToGUI() && ((df == 4) || (df == 5) || (df == 20) || (df == 21)))
bool invalid = modeSValid(data, df);
if (!invalid)
{
ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create(
QByteArray((char*)data, bytes),
preambleCorrelation * m_correlationScale,
preambleCorrelationOnes / samplesPerChip,
rxDateTime(firstIdx, readBuffer),
m_crc.get());
m_sink->getMessageQueueToGUI()->push(msg);
// Extract received parity
int parity = (data[bytes-3] << 16) | (data[bytes-2] << 8) | data[bytes-1];
// Calculate CRC on received frame
m_crc.init();
m_crc.calculate(data, bytes-3);
int crc = m_crc.get();
bool forward = false;
// ICAO address XORed in to parity, apart from DF11
// Extract ICAO from parity and see if it matches an aircraft we've already
// received an ADS-B or Mode S frame from
// For DF11, the last 7 bits may have an iterogration code (II/SI)
// XORed in, so we ignore those bits. This does sometimes lead to false-positives
if (df != 11)
{
unsigned icao = (parity ^ crc) & 0xffffff;
if (icaoValid(icao))
{
if (icaoHeardRecently(icao, dateTime)) {
forward = true;
} else {
handleModeS(data, bytes, icao, df, firstIndex, preamble, preambleCorrelationScaled, correlationOnes, dateTime, m_crc.get());
}
}
else
{
m_demodStats.m_icaoFails++;
}
}
else
{
// Ignore IC bits
parity &= 0xffff80;
crc &= 0xffff80;
if (parity == crc)
{
// Get 24-bit ICAO
unsigned icao = ((data[1] & 0xff) << 16) | ((data[2] & 0xff) << 8) | (data[3] & 0xff);
if (icaoValid(icao))
{
if (icaoHeardRecently(icao, dateTime)) {
forward = true;
} else {
handleModeS(data, bytes, icao, df, firstIndex, preamble, preambleCorrelationScaled, correlationOnes, dateTime, m_crc.get());
}
}
else
{
m_demodStats.m_icaoFails++;
}
}
else
{
m_demodStats.m_crcFails++;
}
}
if (forward)
{
m_demodStats.m_modesFrames++;
// Don't try to re-demodulate the same frame
// We could possibly allow a partial overlap here
readIdx += ((bytes*8)+ADS_B_PREAMBLE_BITS)*ADS_B_CHIPS_PER_BIT*samplesPerChip - 1;
forwardFrame(data, bytes, preambleCorrelationScaled, correlationOnes, dateTime, m_crc.get());
}
else
{
m_demodStats.m_crcFails++;
}
}
// Pass to worker to feed to other servers
if (m_sink->getMessageQueueToWorker())
else
{
ADSBDemodReport::MsgReportADSB *msg = ADSBDemodReport::MsgReportADSB::create(
QByteArray((char*)data, bytes),
preambleCorrelation * m_correlationScale,
preambleCorrelationOnes / samplesPerChip,
rxDateTime(firstIdx, readBuffer),
m_crc.get());
m_sink->getMessageQueueToWorker()->push(msg);
m_demodStats.m_invalidFails++;
}
}
else
{
m_demodStats.m_crcFails++;
m_demodStats.m_typeFails++;
}
}
else
m_demodStats.m_typeFails++;
{
m_demodStats.m_preambleFails++;
}
}
else
{
m_demodStats.m_typeFails++;
}
}
readIdx++;
if (readIdx > m_sink->m_bufferSize - samplesPerFrame)
{
@ -300,9 +605,7 @@ void ADSBDemodSinkWorker::run()
nextBuffer = 0;
// Update amount of time spent processing (don't include time spend in acquire)
boost::chrono::duration<double> sec = boost::chrono::steady_clock::now() - startPoint;
m_demodStats.m_demodTime += sec.count();
m_demodStats.m_feedTime = m_sink->m_feedTime;
PROFILER_STOP("ADS-B demod");
// Send stats to GUI
if (m_sink->getMessageQueueToGUI())
@ -320,7 +623,7 @@ void ADSBDemodSinkWorker::run()
handleInputMessages();
// Resume timing how long we are processing
startPoint = boost::chrono::steady_clock::now();
PROFILER_RESTART();
int samplesRemaining = m_sink->m_bufferSize - readIdx;
if (samplesRemaining > 0)
@ -357,24 +660,27 @@ void ADSBDemodSinkWorker::handleInputMessages()
MsgConfigureADSBDemodSinkWorker* cfg = (MsgConfigureADSBDemodSinkWorker*)message;
ADSBDemodSettings settings = cfg->getSettings();
QStringList settingsKeys = cfg->getSettingsKeys();
bool force = cfg->getForce();
if (settings.m_correlateFullPreamble) {
m_correlationScale = 3.0;
} else {
m_correlationScale = 2.0;
}
if ((m_settings.m_correlationThreshold != settings.m_correlationThreshold) || force)
if ((settingsKeys.contains("correlationThreshold") && (m_settings.m_correlationThreshold != settings.m_correlationThreshold)) || force)
{
m_correlationThresholdLinear = CalcDb::powerFromdB(settings.m_correlationThreshold);
m_correlationThresholdLinear /= m_correlationScale;
qDebug() << "m_correlationThresholdLinear: " << m_correlationThresholdLinear;
}
m_settings = settings;
if (force) {
m_settings = settings;
} else {
m_settings.applySettings(settingsKeys, settings);
}
delete message;
}
else if (ADSBDemod::MsgResetStats::match(*message))
{
m_demodStats.reset();
}
}
}

View File

@ -26,10 +26,9 @@
#include "util/message.h"
#include "util/messagequeue.h"
#include "adsbdemodstats.h"
#include "adsbdemodsettings.h"
class ADSBDemodSink;
struct ADSBDemodSettings;
struct ADSBDemodStats;
class ADSBDemodSinkWorker : public QThread {
Q_OBJECT
@ -40,20 +39,23 @@ public:
public:
const ADSBDemodSettings& getSettings() const { return m_settings; }
const QStringList& getSettingsKeys() const { return m_settingsKeys; }
bool getForce() const { return m_force; }
static MsgConfigureADSBDemodSinkWorker* create(const ADSBDemodSettings& settings, bool force)
static MsgConfigureADSBDemodSinkWorker* create(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force)
{
return new MsgConfigureADSBDemodSinkWorker(settings, force);
return new MsgConfigureADSBDemodSinkWorker(settings, settingsKeys, force);
}
private:
ADSBDemodSettings m_settings;
QStringList m_settingsKeys;
bool m_force;
MsgConfigureADSBDemodSinkWorker(const ADSBDemodSettings& settings, bool force) :
MsgConfigureADSBDemodSinkWorker(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force) :
Message(),
m_settings(settings),
m_settingsKeys(settingsKeys),
m_force(force)
{ }
};
@ -75,11 +77,29 @@ private:
ADSBDemodSink *m_sink;
ADSBDemodStats m_demodStats;
Real m_correlationThresholdLinear;
Real m_correlationScale;
static const Real m_correlationScale;
crcadsb m_crc; //!< Have as member to avoid recomputing LUT
QHash<int, bool> m_icaos; //!< ICAO addresses that have been received
QHash<unsigned, qint64> m_icaos; //!< ICAO addresses that have been received and msecsSinceEpoch last heard
QDateTime m_lastClear;
struct RXRecord {
QByteArray m_data;
int m_firstIndex;
unsigned short m_preamble;
Real m_preambleCorrelation;
Real m_correlationOnes;
QDateTime m_dateTime;
unsigned m_crc;
};
QHash<int, QList<RXRecord>> m_modeSOnlyIcaos;
QDateTime rxDateTime(int firstIdx, int readBuffer) const;
void handleModeS(unsigned char *data, int bytes, unsigned icao, int df, int firstIndex, unsigned short preamble, Real preambleCorrelation, Real correlationOnes, const QDateTime& dateTime, unsigned crc);
void forwardFrame(const unsigned char *data, int size, float preambleCorrelation, float correlationOnes, const QDateTime& dateTime, unsigned crc);
bool icaoHeardRecently(unsigned icao, const QDateTime &dateTime);
static bool icaoValid(unsigned icao);
static bool modeSValid(unsigned char *data, unsigned df);
};

View File

@ -25,20 +25,27 @@ struct ADSBDemodStats {
qint64 m_correlatorMatches; //!< Total number of correlator matches
qint64 m_adsbFrames; //!< How many ADS-B frames with correct CRCs
qint64 m_modesFrames; //!< How many non-ADS-B Mode-S frames with correct CRCs
qint64 m_preambleFails; //!< How many non-ADS-B Mode S frames with errors in preamble
qint64 m_crcFails; //!< How many frames we've demoded with incorrect CRCs
qint64 m_typeFails; //!< How many frames we've demoded with unknown type (DF) so we can't check CRC
double m_demodTime; //!< How long we've spent in run()
double m_feedTime; //!< How long we've spent in feed()
qint64 m_invalidFails; //!< How many frames we've demoded with reserved bits set
qint64 m_icaoFails; //!< How many frames we've demoded with reserved ICAO
ADSBDemodStats() :
m_correlatorMatches(0),
m_adsbFrames(0),
m_modesFrames(0),
m_crcFails(0),
m_typeFails(0),
m_demodTime(0.0),
m_feedTime(0.0)
ADSBDemodStats()
{
reset();
}
void reset()
{
m_correlatorMatches = 0;
m_adsbFrames = 0;
m_modesFrames = 0;
m_preambleFails = 0;
m_crcFails = 0;
m_typeFails = 0;
m_invalidFails = 0;
m_icaoFails = 0;
}
};

View File

@ -150,7 +150,7 @@ bool ADSBDemodWorker::handleMessage(const Message& message)
QMutexLocker mutexLocker(&m_mutex);
MsgConfigureADSBDemodWorker& cfg = (MsgConfigureADSBDemodWorker&) message;
applySettings(cfg.getSettings(), cfg.getForce());
applySettings(cfg.getSettings(), cfg.getSettingsKeys(), cfg.getForce());
return true;
}
else if (ADSBDemodReport::MsgReportADSB::match(message))
@ -165,7 +165,7 @@ bool ADSBDemodWorker::handleMessage(const Message& message)
}
}
void ADSBDemodWorker::applySettings(const ADSBDemodSettings& settings, bool force)
void ADSBDemodWorker::applySettings(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force)
{
qDebug() << "ADSBDemodWorker::applySettings:"
<< " m_feedEnabled: " << settings.m_feedEnabled
@ -179,10 +179,10 @@ void ADSBDemodWorker::applySettings(const ADSBDemodSettings& settings, bool forc
<< " m_logFilename: " << settings.m_logFilename
<< " force: " << force;
if ((settings.m_feedEnabled != m_settings.m_feedEnabled)
|| (settings.m_exportClientEnabled != m_settings.m_exportClientEnabled)
|| (settings.m_exportClientHost != m_settings.m_exportClientHost)
|| (settings.m_exportClientPort != m_settings.m_exportClientPort)
if ((settingsKeys.contains("feedEnabled") && (settings.m_feedEnabled != m_settings.m_feedEnabled))
|| (settingsKeys.contains("exportClientEnabled") && (settings.m_exportClientEnabled != m_settings.m_exportClientEnabled))
|| (settingsKeys.contains("exportClientHost") && (settings.m_exportClientHost != m_settings.m_exportClientHost))
|| (settingsKeys.contains("exportClientPort") && (settings.m_exportClientPort != m_settings.m_exportClientPort))
|| force)
{
// Close any existing connection
@ -195,9 +195,9 @@ void ADSBDemodWorker::applySettings(const ADSBDemodSettings& settings, bool forc
}
}
if ((settings.m_feedEnabled != m_settings.m_feedEnabled)
|| (settings.m_exportServerEnabled != m_settings.m_exportServerEnabled)
|| (settings.m_exportServerPort != m_settings.m_exportServerPort)
if ((settingsKeys.contains("feedEnabled") && (settings.m_feedEnabled != m_settings.m_feedEnabled))
|| (settingsKeys.contains("exportServerEnabled") && (settings.m_exportServerEnabled != m_settings.m_exportServerEnabled))
|| (settingsKeys.contains("exportServerPort") && (settings.m_exportServerPort != m_settings.m_exportServerPort))
|| force)
{
if (m_beastServer.isListening()) {
@ -208,8 +208,8 @@ void ADSBDemodWorker::applySettings(const ADSBDemodSettings& settings, bool forc
}
}
if ((settings.m_logEnabled != m_settings.m_logEnabled)
|| (settings.m_logFilename != m_settings.m_logFilename)
if ((settingsKeys.contains("logEnabled") && (settings.m_logEnabled != m_settings.m_logEnabled))
|| (settingsKeys.contains("logFilename") && (settings.m_logFilename != m_settings.m_logFilename))
|| force)
{
if (m_logFile.isOpen())
@ -238,7 +238,11 @@ void ADSBDemodWorker::applySettings(const ADSBDemodSettings& settings, bool forc
}
}
m_settings = settings;
if (force) {
m_settings = settings;
} else {
m_settings.applySettings(settingsKeys, settings);
}
}
void ADSBDemodWorker::connected()

View File

@ -61,20 +61,23 @@ public:
public:
const ADSBDemodSettings& getSettings() const { return m_settings; }
const QStringList& getSettingsKeys() const { return m_settingsKeys; }
bool getForce() const { return m_force; }
static MsgConfigureADSBDemodWorker* create(const ADSBDemodSettings& settings, bool force)
static MsgConfigureADSBDemodWorker* create(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force)
{
return new MsgConfigureADSBDemodWorker(settings, force);
return new MsgConfigureADSBDemodWorker(settings, settingsKeys, force);
}
private:
ADSBDemodSettings m_settings;
QStringList m_settingsKeys;
bool m_force;
MsgConfigureADSBDemodWorker(const ADSBDemodSettings& settings, bool force) :
MsgConfigureADSBDemodWorker(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force) :
Message(),
m_settings(settings),
m_settingsKeys(settingsKeys),
m_force(force)
{ }
};
@ -101,7 +104,7 @@ private:
ADSBBeastServer m_beastServer;
bool handleMessage(const Message& cmd);
void applySettings(const ADSBDemodSettings& settings, bool force = false);
void applySettings(const ADSBDemodSettings& settings, const QStringList& settingsKeys, bool force = false);
void send(const char *data, int length);
char *escape(char *p, char c);
void handleADSB(QByteArray data, const QDateTime dateTime, float correlation);

View File

@ -67,14 +67,14 @@ private slots:
{
xml = QString("\
{\
\"UrlTemplate\" : \"https://maps.wikimedia.org/osm-intl/%z/%x/%y%1.png\",\
\"UrlTemplate\" : \"https://tile.openstreetmap.org/%z/%x/%y.png\",\
\"ImageFormat\" : \"png\",\
\"QImageFormat\" : \"Indexed8\",\
\"ID\" : \"wmf-intl-%2x\",\
\"ID\" : \"osm-%1x\",\
\"MaximumZoomLevel\" : 18,\
\"MapCopyRight\" : \"<a href='https://wikimediafoundation.org/wiki/Terms_of_Use'>WikiMedia Foundation</a>\",\
\"DataCopyRight\" : \"<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors\"\
}").arg(hiresURL).arg(hires ? 1 : 2);
}").arg(hires ? 1 : 2);
}
else if (tokens[1] == "/satellite")
{

View File

@ -30,7 +30,7 @@
const PluginDescriptor ADSBPlugin::m_pluginDescriptor = {
ADSBDemod::m_channelId,
QStringLiteral("ADS-B Demodulator"),
QStringLiteral("7.22.1"),
QStringLiteral("7.22.7"),
QStringLiteral("(c) Jon Beniston, M7RCE"),
QStringLiteral("https://github.com/f4exb/sdrangel"),
true,

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Some files were not shown because too many files have changed in this diff Show More