Compare commits

..

217 Commits

Author SHA1 Message Date
Jordan Sherer 8f8772f1bd Version bump 2018-07-27 16:52:25 -04:00
Jordan Sherer f09132f6b4 Fix beacon for compound calls 2018-07-27 16:52:16 -04:00
Jordan Sherer bf57a67c43 Encoding of beacon messages that consist of compound call + (grid or arbitrary 15 bit number) + a flag (isCQ) 2018-07-27 16:11:11 -04:00
Jordan Sherer 091b3b3ee8 Disabled global keyboard shortcuts... 2018-07-27 14:40:37 -04:00
Jordan Sherer 17033f1044 Automatic reply to AGN queries. Restore last message in the text area menu 2018-07-27 13:53:07 -04:00
Jordan Sherer 7c656fac71 Updated compound callsign parsing in directed messages (use base callsign instead) 2018-07-27 11:28:31 -04:00
Jordan Sherer a6771b81c3 Fixed leading whitespace issue for buffered commands 2018-07-27 10:57:51 -04:00
Jordan Sherer eca184bac6 Version bump 2018-07-27 02:27:50 -04:00
Jordan Sherer 6ad2417804 Remove station from heard list 2018-07-27 02:22:48 -04:00
Jordan Sherer 21e87d8b6f QSY on right click of heard list 2018-07-27 01:43:25 -04:00
Jordan Sherer 52a5650a74 Restore original functionality regarding stations heard 2018-07-27 01:36:55 -04:00
Jordan Sherer 2158722ebc Fixed bug in checksuming of buffered messages 2018-07-27 01:24:38 -04:00
Jordan Sherer bf11d66f60 Dont reset the beacon at a 1 minute interval 2018-07-26 20:51:02 -04:00
Jordan Sherer 371aa1e20c Fixed callsign parsing expression 2018-07-26 20:46:08 -04:00
Jordan Sherer 8348f61a94 Bump date 2018-07-26 17:31:21 -04:00
Jordan Sherer bf28918096 Write current messages to ALL.TXT 2018-07-26 16:30:19 -04:00
Jordan Sherer 571aa6446d Added message alerts 2018-07-26 15:57:19 -04:00
Jordan Sherer 4290dd6e2f Extended charset via escapes. DE added to retransmits 2018-07-26 14:31:28 -04:00
Jordan Sherer de66664635 Added extended alphabet for special characters 2018-07-26 12:47:03 -04:00
Jordan Sherer 9e9c996813 Refactor message buffering for relay 2018-07-25 22:49:19 -04:00
Jordan Sherer f67ea3803d Changed to a better callsign validator expression 2018-07-25 20:24:22 -04:00
Jordan Sherer fa00e0dfd6 Added callsign label to main window 2018-07-25 20:13:23 -04:00
Jordan Sherer ceaa76c497 Experimental single-hop relay working 2018-07-25 17:15:59 -04:00
Jordan Sherer 9c9a5c2d8b Added power reply. Added ack reply 2018-07-25 16:51:47 -04:00
Jordan Sherer d611d83bb9 Fixed J1Y callsign bug. Added power reporting command 2018-07-25 14:46:21 -04:00
Jordan Sherer 253b60217f Added station power to configuration 2018-07-25 11:30:44 -04:00
Jordan Sherer 39a536bb91 Experimental foundation of all or nothing checksummed messages 2018-07-25 09:06:47 -04:00
Jordan Sherer 115a9d65f7 Send data frames after directed. Fix bug with enter key double sending 2018-07-24 23:10:47 -04:00
Jordan Sherer 796920cb6b Better EOT. Fixed bug in enter key press 2018-07-24 22:32:24 -04:00
Jordan Sherer c1c7d85195 UI Tweaks. Remove frequency restriction (causing problems). And keep track of the last message sent for later. 2018-07-24 21:04:04 -04:00
Jordan Sherer c5a6f76b1e Bump version to v0.3.0 2018-07-24 20:42:55 -04:00
Jordan Sherer 5b198351be Send message on enter key press 2018-07-24 17:45:23 -04:00
Jordan Sherer 246d53201c Updated compound call parsing and aliasing 2018-07-24 17:31:06 -04:00
Jordan Sherer 999a239e67 Remove reference to FT8Free 2018-07-24 16:47:14 -04:00
Jordan Sherer f091cb28ef Make sure log window is large enough 2018-07-24 16:47:05 -04:00
Jordan Sherer f415b0c94f Added autoreply button in conjuntion with beacon button 2018-07-24 16:46:04 -04:00
Jordan Sherer 0bf2afa5f8 Proper handling of directed messages for compound calls using an alias scheme 2018-07-24 15:19:02 -04:00
Jordan Sherer 706a9b1ebd Allow stations heard query 2018-07-24 11:11:04 -04:00
Jordan Sherer 4cec8b80a3 Check offsets above and below 5Hz 2018-07-24 09:42:07 -04:00
Jordan Sherer 9e68b8c402 Clear compound call cache on activity clear 2018-07-24 09:23:44 -04:00
Jordan Sherer 478ba82df7 Removed split rig check ignore for split operation 2018-07-24 09:08:53 -04:00
Jordan Sherer 7aef92dd68 Updated call activity once receiving compound callsign 2018-07-24 03:07:36 -04:00
Jordan Sherer 01249bd115 Support compound callsigns 2018-07-24 02:53:01 -04:00
Jordan Sherer 9bee00c5dd Remove directed buttons and put them in the menu 2018-07-24 02:52:12 -04:00
Jordan Sherer b9b274f2d6 Disallow callsigns with both prefixes and suffixes 2018-07-24 02:51:44 -04:00
Jordan Sherer 4a17062487 Added packing of compound callsigns into a dedicated message 2018-07-24 02:47:14 -04:00
Jordan Sherer 1c73ce2c90 Removed extra non-ft8 binaries 2018-07-23 23:56:51 -04:00
Jordan Sherer 07a29c7f1d Refactoring directed frame packing 2018-07-23 17:20:03 -04:00
Jordan Sherer f7a941406c Typing in a callsign not in your heard list recognizes it as a callsign selected 2018-07-23 17:19:26 -04:00
Jordan Sherer adecb88c29 Added callsign prefix packing 2018-07-23 15:28:36 -04:00
Jordan Sherer 857e19ed94 Updated callsign handling
Reducing compound callsigns to their basecall for most commands except CQ and DE (beacon)
2018-07-23 11:45:41 -04:00
Jordan Sherer f47224979e Refactor store freq. Rename to bacon. 2018-07-23 09:09:55 -04:00
Jordan Sherer c0833aa753 Added checksum generation and ACK 2018-07-23 08:51:29 -04:00
Jordan Sherer 20d931a9ca Moved macro button...again. 2018-07-23 08:49:58 -04:00
Jordan Sherer 1b2f8a1c6c Restore audio frequency after responding to allcall or transmitting beacon 2018-07-21 17:50:33 -04:00
Jordan Sherer 95e75741ed Fix bug in scrolling of the main window 2018-07-21 17:32:35 -04:00
Jordan Sherer dc75c08081 Configuration and MainWindow UI tweaks 2018-07-21 17:18:35 -04:00
Jordan Sherer 8c204e317b Fixed beacon postponement 2018-07-21 17:06:17 -04:00
Jordan Sherer a672668c3a Only respond to allcalls once per beacon interval 2018-07-21 16:57:42 -04:00
Jordan Sherer 8638b53e45 Added band activity age in the table 2018-07-21 16:55:04 -04:00
Jordan Sherer 394a6d045f Beacon interval default to 15 min 2018-07-21 16:10:13 -04:00
Jordan Sherer 29bbedcc8f Make sure standard messages are displayed with a space between them. 2018-07-21 15:57:01 -04:00
Jordan Sherer d66b4ffb37 Disable QTC QTH buttons if those messages are empty 2018-07-21 12:37:11 -04:00
Jordan Sherer c0c4693782 Widened the log qso dialog 2018-07-21 03:55:45 -04:00
Jordan Sherer 9223d3da40 Version bump to 0.2.0 2018-07-21 03:52:48 -04:00
Jordan Sherer 83e3f5ddbc SNR button sends a directed SNR message 2018-07-21 03:52:13 -04:00
Jordan Sherer 0f4057aa97 Make sure to clear seen beacon cache when changing bands 2018-07-21 03:45:56 -04:00
Jordan Sherer 591629e369 Disable heard list beaconing for now 2018-07-21 03:33:00 -04:00
Jordan Sherer 4a96ab3b13 Beaconing of heard list 2018-07-21 03:32:07 -04:00
Jordan Sherer e955cff24f Make sure selected call exists before using it 2018-07-21 02:31:30 -04:00
Jordan Sherer fe405cfba8 Added ability to encode power into dbm 2018-07-21 02:18:15 -04:00
Jordan Sherer 92117aa791 Added SNR directed command 2018-07-20 23:17:49 -04:00
Jordan Sherer d4c2d9a871 Log directed FT8Call messages to PSKReporter 2018-07-20 23:09:17 -04:00
Jordan Sherer b2e2b91d31 Refactored get current frequency 2018-07-20 22:17:41 -04:00
Jordan Sherer fa864c50cd Removed CQ DX from allcall 2018-07-20 16:23:48 -04:00
Jordan Sherer 1c6d1babe6 Set the QTH button to drop in the station location if provided 2018-07-20 16:11:21 -04:00
Jordan Sherer ac27d1a9b6 Brighter green for slider 2018-07-20 16:10:59 -04:00
Jordan Sherer 28eb082655 Further fix format of SNR 2018-07-20 16:04:14 -04:00
Jordan Sherer 9a945c156d Proper SNR formatting +00 +30 -09 2018-07-20 11:40:55 -04:00
Jordan Sherer 83c742f7ec Double click band activity now transfers the received message into the directed activity window and further transmissions on the offset will be added to the window automatically 2018-07-20 10:54:00 -04:00
Jordan Sherer 7a788c05c8 Added configuration options for controlling aging of the callsign and band activity windows 2018-07-20 10:13:12 -04:00
Jordan Sherer 7b409a6ff4 Fix varicode bug with empty messages 2018-07-20 09:38:34 -04:00
Jordan Sherer 87a631f5f0 Reorder directed and macro buttons 2018-07-20 09:38:10 -04:00
Jordan Sherer efd6b54ba7 Updated slider handle color 2018-07-20 09:00:36 -04:00
Jordan Sherer 553f2400e5 Updated text decoding to support more commands as well as numerical options for those commands 2018-07-19 23:14:11 -04:00
Jordan Sherer 5c84e79e5b Updated label text for qth message 2018-07-19 10:36:43 -04:00
Jordan Sherer 052b81ec8f Added 73 action and more appropriate all call responses. Added better handling of end of transmissions. 2018-07-19 10:35:00 -04:00
Jordan Sherer 7ecc550bc2 Added station qth to configuration options 2018-07-19 10:34:19 -04:00
Jordan Sherer b8267372e4 Added varicode encoding of messages
What this does is allow us to pack more than 13 characters in a single
transmission frame. Optimized using a Huffman encoding using weights of
alphabetical frequency, this will often allow us to send less than 5 bits
per character.
2018-07-19 03:44:08 -04:00
Jordan Sherer 512dffabf4 Added station message command processing 2018-07-19 02:09:19 -04:00
Jordan Sherer 50a3a56d2d Added station message to configuration 2018-07-19 00:39:31 -04:00
Jordan Sherer deb228948d Added ability to display when we receive the final transmission frame of a message 2018-07-18 16:45:27 -04:00
Jordan Sherer 58032b6ae4 Restrict low offset when not in split mode 2018-07-18 14:26:45 -04:00
Jordan Sherer 7845736c05 Smarter beacon scheduling for when editing a message or have recently transmitted 2018-07-18 09:04:58 -04:00
Jordan Sherer 77eb65d6b3 Display callsign prefix for transmitted directed messages 2018-07-16 09:14:28 -04:00
Jordan Sherer 252c21b818 Bump version to 0.1.1 2018-07-16 12:07:39 +00:00
Jordan Sherer 82c3b23e44 Merge branch 'ft8call-reorg' of https://bitbucket.org/widefido/wsjtx into ft8call-reorg 2018-07-16 11:59:06 +00:00
Jordan Sherer 5764170975 Disabled contest mode message packing which causes crashes when typing R 2018-07-16 11:58:41 +00:00
Jordan Sherer a2c85256e8 Only throttle ALLCALLs 2018-07-15 21:00:12 -04:00
Jordan Sherer 9419383ab0 Fixes for windows 2018-07-15 17:58:16 -04:00
Jordan Sherer 4c63129876 Fixed bug in beacon bumping 2018-07-15 16:48:27 -04:00
Jordan Sherer f2b876df49 Bump version to July 30 2018-07-15 16:12:57 -04:00
Jordan Sherer f229019ef5 Updated buttons while frame count is queued and is transmitting 2018-07-15 15:58:07 -04:00
Jordan Sherer 3260bb7b89 Use standard FT8 packing for standard FT8 messages, but apply a directed header for those messages that _can_ be directed 2018-07-15 15:43:29 -04:00
Jordan Sherer 2832572741 Process directed free text messages. Bump beacon on transmit. 2018-07-15 13:03:16 -04:00
Jordan Sherer 28df33b218 Better parsing of selected callsign. Blur edit box while transmitting 2018-07-15 11:00:57 -04:00
Jordan Sherer 6ee0820659 Disabled colors that are not displayed 2018-07-15 10:22:21 -04:00
Jordan Sherer 2c73ccde9b Huffman frame packing 2018-07-15 09:40:46 -04:00
Jordan Sherer 90ce372081 Added CRC-5 to directed messages to confirm message is valid 2018-07-14 22:05:08 -04:00
Jordan Sherer 15d75f7397 Try not to allocate every time... 2018-07-14 18:10:07 -04:00
Jordan Sherer f47c1a5024 Updated comment 2018-07-14 17:10:59 -04:00
Jordan Sherer c74ed5135b Parse callsigns from standard messages 2018-07-14 17:09:12 -04:00
Jordan Sherer b08ecd21e6 PSKReporter shouldnt include the rigname in the name. Added a cache to prevent allcall overrun 2018-07-14 09:26:39 -04:00
Jordan Sherer 1c98d47718 Bump EOL 2018-07-13 22:26:51 -04:00
Jordan Sherer 46e11f8d00 Complete rename to ft8call executable 2018-07-13 22:22:16 -04:00
Jordan Sherer 1e0a93e076 Update Help menu and Copyrights 2018-07-13 22:13:36 -04:00
Jordan Sherer f77f139abb Fix typo 2018-07-13 22:13:18 -04:00
Jordan Sherer 2ae74d8cde Added grid packing to varicode 2018-07-13 21:59:54 -04:00
Jordan Sherer 369b5fd73a Better beacon scheduling when receiving a directed message 2018-07-13 21:59:44 -04:00
Jordan Sherer 4de968d2f0 Try to prevent false directed decodes 2018-07-13 21:58:43 -04:00
Jordan Sherer 09b12701b5 Updated table call view. Added ALLCALL 2018-07-13 15:45:00 -04:00
Jordan Sherer d00eee440c Fixed accesses of invalid memory 2018-07-13 15:44:48 -04:00
Jordan Sherer c1df21f940 Better QSlider to match systems 2018-07-13 15:09:29 -04:00
Jordan Sherer 9117ad5381 New slider style 2018-07-13 14:43:57 -04:00
Jordan Sherer a96216e2f8 Refactored directed code into decoded text so the rest of the app can use it as is. 2018-07-13 10:32:58 -04:00
Jordan Sherer 4140114d8d Remove revision from PSKReporter report 2018-07-13 09:01:01 -04:00
Jordan Sherer bd34bf104f Bump version 2018-07-13 04:46:02 -04:00
Jordan Sherer 6a265efe48 Added command processing, code cleanup, new parsing of messages to be sent, etc. 2018-07-13 04:44:41 -04:00
Jordan Sherer 983790a3ff Added query toolbar button 2018-07-13 04:43:22 -04:00
Jordan Sherer 43b65d5ca9 Pack and unpack directed message commands naively 2018-07-13 04:42:23 -04:00
Jordan Sherer 8bc61902ac Added a priority queue 2018-07-13 02:44:31 -04:00
Jordan Sherer 4e0326ad6d Added callsign packing 2018-07-13 00:55:48 -04:00
Jordan Sherer 808782b965 Working through huffman interface 2018-07-12 20:31:45 -04:00
Jordan Sherer 707f577f31 Added huffman encoding utility 2018-07-12 18:02:54 -04:00
Jordan Sherer 705244786e Add bits accessor for decodedtext 2018-07-12 16:35:00 -04:00
Jordan Sherer 4e66e92671 Remove debug statement 2018-07-12 16:25:06 -04:00
Jordan Sherer 283e7fae77 Beacon every hour or less 2018-07-12 16:24:42 -04:00
Jordan Sherer 441936111a Output i3bits in FT8 decoder from JT9 2018-07-12 16:19:33 -04:00
Jordan Sherer f81a954d1d Ensure 10Hz offset for FT8 reception 2018-07-12 16:18:54 -04:00
Jordan Sherer 23c1730148 Disabled callsign parsing until we are ready 2018-07-12 15:23:12 -04:00
Jordan Sherer 05257d287f Parse callsigns in QSO and add to call panel 2018-07-12 15:14:41 -04:00
Jordan Sherer 64b5ebbdd2 Updated to refresh rx activity at least once per cycle 2018-07-12 14:15:18 -04:00
Jordan Sherer 91d6836fa5 Updated call activity detail 2018-07-12 10:35:41 -04:00
Jordan Sherer dd3613b214 Added bit packing to varicode 2018-07-12 09:54:56 -04:00
Jordan Sherer c96522c11b Added the start of varicode 2018-07-11 23:09:22 -04:00
Jordan Sherer 564b93f307 Removed unused count function 2018-07-11 22:53:21 -04:00
Jordan Sherer 04eaf61c13 Fixed the size of the top toolbar 2018-07-11 22:31:55 -04:00
Jordan Sherer b800dac9ce Contest should be false 2018-07-11 22:13:53 -04:00
Jordan Sherer 2cb78f5414 Extracted isMyCallIncluded 2018-07-11 10:40:29 -04:00
Jordan Sherer 494459ee11 Extracted isRecentlyDirected 2018-07-11 10:30:20 -04:00
Jordan Sherer 1cddbdf91e Experimenting with age in the band activity window 2018-07-10 22:32:35 -04:00
Jordan Sherer 74ea603801 Added clearAll action 2018-07-10 15:35:05 -04:00
Jordan Sherer 16854627d9 Updated PSKReporter spots to use FT8Call instead of WSJT-X for the application name 2018-07-10 15:23:52 -04:00
Jordan Sherer 495c16892f Bump 2018-07-10 00:56:17 -04:00
Jordan Sherer c596f23a05 Added wsjtx-ft8call as output target 2018-07-09 23:07:31 -04:00
Jordan Sherer b69e042f21 Bump version 2018-07-09 22:02:39 -04:00
Jordan Sherer ec568966c8 Fixed macros menu 2018-07-09 21:49:38 -04:00
Jordan Sherer eb062fb0b8 Macros should be updated more frequently 2018-07-09 20:55:54 -04:00
Jordan Sherer 9907a80136 Activity gui should update every 15 seconds 2018-07-09 20:51:42 -04:00
Jordan Sherer cd9079e7ff Updated directed call cache to be better represent recent directed calls 2018-07-09 17:29:43 -04:00
Jordan Sherer 42a8338d1c Allow transmit within 2 seconds of cycle start 2018-07-09 16:36:56 -04:00
Jordan Sherer f44b1154b7 Added SPOT button to UI 2018-07-09 16:31:37 -04:00
Jordan Sherer 722f2f10ae Fixed spec percent bug. Reduced default controls to nil 2018-07-09 15:34:44 -04:00
Jordan Sherer 2a7f38b187 Better breaking apart messages with newlines. Macros behavior 2018-07-09 15:17:53 -04:00
Jordan Sherer f9ab37530c Only clear activity on actual band change, not freq change 2018-07-09 10:10:04 -04:00
Jordan Sherer 442ff4b21d Fix bug on band change 2018-07-09 10:02:45 -04:00
Jordan Sherer ecacddb165 Updated makefile configs 2018-07-08 12:17:10 -04:00
Jordan Sherer 6aab2276ed Updated QAction for old versions of Qt 2018-07-08 09:29:31 -04:00
Jordan Sherer 5c9f9e8141 Version bump. 2018-07-08 09:25:35 -04:00
Jordan Sherer 60563a7dc3 Fix QAction constructor for old compilers 2018-07-07 22:04:27 -04:00
Jordan Sherer 7255728049 Added distance to the calls list 2018-07-07 22:02:11 -04:00
Jordan Sherer 50094fd8a9 Five minutes is too long. Down to two for activity 2018-07-07 17:15:17 -04:00
Jordan Sherer c45f4c137a Keep band activity around for 5 min 2018-07-07 16:58:09 -04:00
Jordan Sherer 16b46176a6 Only QSY your beacon if the frequency isn't free. Don't break lines in the rx window 2018-07-07 16:56:33 -04:00
Jordan Sherer 0df4bbcd29 Added QTH button 2018-07-07 00:47:17 -04:00
Jordan Sherer 3bbea95955 Add warning and eol message 2018-07-06 22:37:25 -04:00
Jordan Sherer fa0baad9a0 Pin calling activity to the top of the activity window 2018-07-06 22:21:04 -04:00
Jordan Sherer 7b7493d560 Fixed beacon tx display 2018-07-06 22:07:30 -04:00
Jordan Sherer dc6de6d819 Bump version 2018-07-06 20:14:09 -04:00
Jordan Sherer b7a51a5764 Disable a bunch of configuration settings that do not make sense for FT8Call 2018-07-06 20:06:41 -04:00
Jordan Sherer 145bc8d292 Updated configuration for beacon interval 2018-07-06 20:01:38 -04:00
Jordan Sherer f58ce3aec0 Propertly clear the edit widget. Properly space messages in the rx window 2018-07-06 18:25:27 -04:00
Jordan Sherer 27b45a26d9 Clear activity on band change. Scroll rx window 2018-07-06 16:54:26 -04:00
Jordan Sherer 0653f81a0d Smarter beaconing with band space 2018-07-06 16:40:09 -04:00
Jordan Sherer 1134cd5782 Disable activity word wrapping 2018-07-06 16:39:51 -04:00
Jordan Sherer aa1871dc66 Fixed beacon scheduling 2018-07-06 16:19:22 -04:00
Jordan Sherer 56869d16a9 Updated since computation to be accurate 2018-07-06 15:27:26 -04:00
Jordan Sherer ccf00dc460 Simple build script to help deploy linux app images 2018-07-06 15:27:06 -04:00
Jordan Sherer 57ad5fd0bc Compat for older Qt 2018-07-06 07:15:11 +00:00
Jordan Sherer 7d9553dd7c Added make app script 2018-07-06 03:03:02 -04:00
Jordan Sherer cad3f43752 Added version 2018-07-06 02:53:31 -04:00
Jordan Sherer 2605fb1a8f UI Customizations 2018-07-06 02:36:40 -04:00
Jordan Sherer 130b749dfe Disabled splashscreen. Updated application name and window title 2018-07-06 00:10:30 -04:00
Jordan Sherer 04bdf8574a Cache calls for easier display 2018-07-05 15:21:47 -04:00
Jordan Sherer 0dfc805a49 Highlight send button on transmit 2018-07-05 04:56:46 -04:00
Jordan Sherer 022866b52b Complete UI functionality 2018-07-05 04:45:55 -04:00
Jordan Sherer 9ed0fe80d2 UI: TableView customizations, including clear context menu 2018-07-03 18:57:49 -04:00
Jordan Sherer 7837ff5d74 UI: Updated tableview behavior 2018-07-03 15:34:03 -04:00
Jordan Sherer bee42d1762 UI Updates, Text Eliding, CallDetail Grid 2018-07-03 11:38:16 -04:00
Jordan Sherer 26c76662ac Read only edit box while transmitting 2018-07-03 03:29:26 -04:00
Jordan Sherer e3a9762179 Beaconing 2018-07-03 03:21:01 -04:00
Jordan Sherer d048f5a2ab Selection tracking 2018-07-03 02:02:19 -04:00
Jordan Sherer 0a95c79f3a Correct stop behavior when clicking send 2018-07-03 01:17:15 -04:00
Jordan Sherer 762f0fb3e1 Added proper send countdown 2018-07-02 23:03:07 -04:00
Jordan Sherer 812b11a53d Disable tx button 2018-07-02 22:56:51 -04:00
Jordan Sherer c517b555d8 Reorganized message transmission semantics 2018-07-02 22:54:26 -04:00
Jordan Sherer f610e946fc Reorganized the window, added beacon watch, macro buttons, etc 2018-07-02 15:08:26 -04:00
Jordan Sherer cb71c3dcf4 Adding messages to band activity 2018-06-15 10:11:44 -04:00
Jordan Sherer 5c8ff568c3 Updated main ui 2018-03-19 00:05:12 -04:00
Jordan Sherer 87cdc7f7e7 Reorganize main window and style meter 2018-03-10 16:59:09 -05:00
Jordan Sherer e694d862aa Modifying mainwindow to display waterfall and minimal ui 2018-03-09 13:10:19 -05:00
Jordan Sherer 4df7aae11a Merged in the extended free text experiment patch 2018-03-08 17:01:33 -05:00
Jordan Sherer 55261b6149 Working copy 2018-03-08 16:09:27 -05:00
Jordan Sherer e3bea34342 SVN r8544 2018-03-07 18:28:00 -05:00
Jordan Sherer 79dd112598 SVN r8543 2018-03-07 01:57:18 -05:00
Jordan Sherer bc073fee9a Turn off rig split freq mode because there's an undefined function here.. 2018-03-05 14:56:43 -05:00
Jordan Sherer a32fe6a4dc Updated to r8541 2018-03-05 14:49:51 -05:00
216 changed files with 29276 additions and 5424 deletions
+1
View File
@@ -1,2 +1,3 @@
TAGS
tags
.svn
BIN
View File
Binary file not shown.
+10 -7
View File
@@ -2,13 +2,15 @@
# To pass variables to cpack from cmake, they must be configured
# in this file.
set (CPACK_SET_DESTDIR true)
set (CPACK_PACKAGE_VENDOR "@PROJECT_VENDOR@")
set (CPACK_PACKAGE_CONTACT "@PROJECT_CONTACT@")
set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "@PROJECT_SUMMARY_DESCRIPTION@")
set (CPACK_RESOURCE_FILE_LICENSE "@PROJECT_SOURCE_DIR@/COPYING")
set (CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
set (CPACK_PACKAGE_EXECUTABLES wsjtx "@PROJECT_NAME@")
set (CPACK_CREATE_DESKTOP_LINKS wsjtx)
set (CPACK_PACKAGE_EXECUTABLES ft8call "@PROJECT_NAME@")
set (CPACK_CREATE_DESKTOP_LINKS ft8call)
set (CPACK_STRIP_FILES TRUE)
#
@@ -19,9 +21,10 @@ set (CPACK_STRIP_FILES TRUE)
#set (CPACK_COMPONENT_RUNTIME_DESCRIPTION "@WSJTX_DESCRIPTION_SUMMARY@")
if (CPACK_GENERATOR MATCHES "NSIS")
set (CPACK_SET_DESTDIR FALSE)
set (CPACK_STRIP_FILES FALSE) # breaks Qt packaging on Windows
set (CPACK_NSIS_INSTALL_ROOT "C:\\WSJT")
set (CPACK_NSIS_INSTALL_ROOT "C:\\FT8Call")
# set the install/unistall icon used for the installer itself
# There is a bug in NSI that does not handle full unix paths properly.
@@ -35,13 +38,13 @@ if (CPACK_GENERATOR MATCHES "NSIS")
"@PROJECT_HOMEPAGE@" "@PROJECT_NAME@ Web Site"
)
# Use the icon from wsjtx for add-remove programs
set (CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\wsjtx.exe")
set (CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\ft8call.exe")
set (CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}")
set (CPACK_NSIS_HELP_LINK "@PROJECT_MANUAL_DIRECTORY_URL@/@PROJECT_MANUAL@")
set (CPACK_NSIS_URL_INFO_ABOUT "@PROJECT_HOMEPAGE@")
set (CPACK_NSIS_CONTACT "${CPACK_PACKAGE_CONTACT}")
set (CPACK_NSIS_MUI_FINISHPAGE_RUN "wsjtx.exe")
set (CPACK_NSIS_MUI_FINISHPAGE_RUN "ft8call.exe")
set (CPACK_NSIS_MODIFY_PATH ON)
endif ()
@@ -65,9 +68,9 @@ if ("${CPACK_GENERATOR}" STREQUAL "WIX")
# Reset CPACK_PACKAGE_VERSION to deal with WiX restriction.
# But the file names still use the full CMake_VERSION value:
set (CPACK_PACKAGE_FILE_NAME
"${CPACK_PACKAGE_NAME}-@wsjtx_VERSION@-${CPACK_SYSTEM_NAME}")
"${CPACK_PACKAGE_NAME}-@ft8call_VERSION@-${CPACK_SYSTEM_NAME}")
set (CPACK_SOURCE_PACKAGE_FILE_NAME
"${CPACK_PACKAGE_NAME}-@wsjtx_VERSION@-Source")
"${CPACK_PACKAGE_NAME}-@ft8call_VERSION@-Source")
if (NOT CPACK_WIX_SIZEOF_VOID_P)
set (CPACK_WIX_SIZEOF_VOID_P "@CMAKE_SIZEOF_VOID_P@")
+64 -48
View File
@@ -22,7 +22,7 @@ Change this to the newest SDK available that you can install on your system (10.
Do not override this if you intend to build an official deployable installer.")
endif (APPLE)
project (wsjtx C CXX Fortran)
project (ft8call C CXX Fortran)
#
# CMake policies
@@ -45,10 +45,10 @@ message (STATUS "Building ${CMAKE_PROJECT_NAME}-${wsjtx_VERSION}")
#
# project information
#
set (PROJECT_NAME "WSJT-X")
set (PROJECT_VENDOR "Joe Taylor, K1JT")
set (PROJECT_CONTACT "Joe Taylor <k1jt@arrl.net>")
set (PROJECT_COPYRIGHT "Copyright (C) 2001-2017 by Joe Taylor, K1JT")
set (PROJECT_NAME "FT8Call")
set (PROJECT_VENDOR "Jordan Sherer, KN4CRD")
set (PROJECT_CONTACT "Jordan Sherer <kn4crd@gmail.com>")
set (PROJECT_COPYRIGHT "Copyright (C) 2001-2018 by Joe Taylor, K1JT, (C) 2018 by Jordan Sherer, KN4CRD")
set (PROJECT_HOMEPAGE http://www.physics.princeton.edu/pulsar/K1JT/wsjtx.html)
set (PROJECT_MANUAL wsjtx-main)
set (PROJECT_MANUAL_DIRECTORY_URL http://www.physics.princeton.edu/pulsar/K1JT/wsjtx-doc/)
@@ -303,6 +303,7 @@ set (wsjtx_CXXSRCS
astro.cpp
messageaveraging.cpp
WsprTxScheduler.cpp
varicode.cpp
mainwindow.cpp
Configuration.cpp
main.cpp
@@ -366,12 +367,12 @@ set (wsjt_FSRCS
lib/averms.f90
lib/azdist.f90
lib/badmsg.f90
lib/fsk4hf/baseline.f90
lib/ft8/baseline.f90
lib/bpdecode40.f90
lib/bpdecode144.f90
lib/fsk4hf/bpdecode120.f90
lib/fsk4hf/bpdecode168.f90
lib/fsk4hf/bpdecode174.f90
lib/ft8/bpdecode174.f90
lib/fsk4hf/bpdecode300.f90
lib/baddata.f90
lib/calibrate.f90
@@ -379,11 +380,12 @@ set (wsjt_FSRCS
lib/ccf65.f90
lib/fsk4hf/chkcrc10.f90
lib/fsk4hf/chkcrc12.f90
lib/fsk4hf/chkcrc12a.f90
lib/ft8/chkcrc12a.f90
lib/chkcall.f90
lib/chkhist.f90
lib/chkmsg.f90
lib/chkss2.f90
lib/ft8/compress.f90
lib/coord.f90
lib/fsk4hf/cpolyfit.f90
lib/fsk4hf/cpolyfitw.f90
@@ -405,7 +407,7 @@ set (wsjt_FSRCS
lib/encode_msk144.f90
lib/fsk4hf/encode120.f90
lib/fsk4hf/encode168.f90
lib/fsk4hf/encode174.f90
lib/ft8/encode174.f90
lib/fsk4hf/encode300.f90
lib/entail.f90
lib/ephem.f90
@@ -413,7 +415,7 @@ set (wsjt_FSRCS
lib/extract4.f90
lib/extractmessage144.f90
lib/fsk4hf/extractmessage168.f90
lib/fsk4hf/extractmessage174.f90
lib/ft8/extractmessage174.f90
lib/fano232.f90
lib/fast9.f90
lib/fast_decode.f90
@@ -425,6 +427,7 @@ set (wsjt_FSRCS
lib/fil4.f90
lib/fil6521.f90
lib/filbig.f90
lib/ft8/filt8.f90
lib/fitcal.f90
lib/fix_contest_msg.f90
lib/flat1.f90
@@ -436,19 +439,23 @@ set (wsjt_FSRCS
lib/fmtmsg.f90
lib/foldspec9f.f90
lib/four2a.f90
lib/ft8/foxfilt.f90
lib/ft8/foxgen.f90
lib/ft8/foxgen_wrap.f90
lib/fqso_first.f90
lib/freqcal.f90
lib/fsk4hf/fsk4hf.f90
lib/fsk4hf/ft8apset.f90
lib/fsk4hf/ft8b.f90
lib/fsk4hf/ft8_downsample.f90
lib/fsk4hf/ft8sim.f90
lib/ft8/ft8apset.f90
lib/ft8/ft8b.f90
lib/ft8/ft8code.f90
lib/ft8/ft8_downsample.f90
lib/ft8/ft8sim.f90
lib/gen4.f90
lib/gen65.f90
lib/gen9.f90
lib/geniscat.f90
lib/fsk4hf/genfsk4hf.f90
lib/fsk4hf/genft8.f90
lib/ft8/genft8.f90
lib/genmsk144.f90
lib/genmsk40.f90
lib/fsk4hf/genmskhf.f90
@@ -459,7 +466,7 @@ set (wsjt_FSRCS
lib/fsk4hf/getfc1w.f90
lib/fsk4hf/getfc2w.f90
lib/genqra64.f90
lib/fsk4hf/genft8refsig.f90
lib/ft8/genft8refsig.f90
lib/genwspr.f90
lib/geodist.f90
lib/getlags.f90
@@ -468,6 +475,7 @@ set (wsjt_FSRCS
lib/graycode65.f90
lib/grayline.f90
lib/grid2deg.f90
lib/ft8/h1.f90
lib/hash.f90
lib/hint65.f90
lib/hspec.f90
@@ -484,7 +492,7 @@ set (wsjt_FSRCS
lib/ldpcsim144.f90
lib/fsk4hf/ldpcsim120.f90
lib/fsk4hf/ldpcsim168.f90
lib/fsk4hf/ldpcsim174.f90
lib/ft8/ldpcsim174.f90
lib/fsk4hf/ldpcsim300.f90
lib/ldpcsim40.f90
lib/libration.f90
@@ -512,11 +520,12 @@ set (wsjt_FSRCS
lib/mskrtd.f90
lib/fsk4hf/msksoftsym.f90
lib/fsk4hf/msksoftsymw.f90
lib/fsk4hf/osd174.f90
lib/ft8/osd174.f90
lib/fsk4hf/osd300.f90
lib/pctile.f90
lib/peakdt9.f90
lib/peakup.f90
lib/plotsave.f90
lib/polyfit.f90
lib/fsk4hf/polyfit4.f90
lib/prog_args.f90
@@ -543,7 +552,7 @@ set (wsjt_FSRCS
lib/spec9f.f90
lib/stdmsg.f90
lib/subtract65.f90
lib/fsk4hf/subtractft8.f90
lib/ft8/subtractft8.f90
lib/sun.f90
lib/symspec.f90
lib/symspec2.f90
@@ -551,8 +560,8 @@ set (wsjt_FSRCS
lib/sync4.f90
lib/sync64.f90
lib/sync65.f90
lib/fsk4hf/sync8.f90
lib/fsk4hf/sync8d.f90
lib/ft8/sync8.f90
lib/ft8/sync8d.f90
lib/sync9.f90
lib/sync9f.f90
lib/sync9w.f90
@@ -561,12 +570,12 @@ set (wsjt_FSRCS
lib/to_contest_msg.f90
lib/tweak1.f90
lib/twkfreq.f90
lib/fsk4hf/twkfreq1.f90
lib/ft8/twkfreq1.f90
lib/twkfreq65.f90
lib/unpackmsg144.f90
lib/update_recent_calls.f90
lib/update_hasharray.f90
lib/fsk4hf/watterson.f90
lib/ft8/watterson.f90
lib/wav11.f90
lib/wav12.f90
lib/xcor.f90
@@ -582,6 +591,9 @@ set (wsjt_FSRCS
lib/zplot9.f90
)
# temporary workaround for a gfortran v7.3 ICE on Fedora 27 64-bit
set_source_files_properties (lib/slasubs.f PROPERTIES COMPILE_FLAGS -O2)
set (ka9q_CSRCS
lib/ftrsd/decode_rs.c
lib/ftrsd/encode_rs.c
@@ -602,7 +614,7 @@ set (qra_CSRCS
set (wsjt_CSRCS
${ka9q_CSRCS}
lib/ftrsd/ftrsd2.c
lib/ftrsd/ftrsdap.c
lib/sgran.c
lib/golay24_table.c
lib/gran.c
@@ -675,6 +687,7 @@ set (message_aggregator_CXXSRCS
UDPExamples/DecodesModel.cpp
UDPExamples/BeaconsModel.cpp
UDPExamples/ClientWidget.cpp
MaidenheadLocatorValidator.cpp
)
set (message_aggregator_STYLESHEETS
@@ -943,7 +956,7 @@ if (Fortran_COMPILER_NAME MATCHES "gfortran.*")
set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -isysroot ${CMAKE_OSX_SYSROOT}")
endif (CMAKE_OSX_SYSROOT)
set (CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -funroll-all-loops -fno-f2c ${General_FFLAGS}")
set (CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -fbounds-check -funroll-all-loops -fno-f2c ${General_FFLAGS}")
set (CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -fbounds-check -fno-f2c ${General_FFLAGS}")
elseif (Fortran_COMPILER_NAME MATCHES "ifort.*")
# ifort (untested)
@@ -1202,8 +1215,8 @@ target_link_libraries (ldpcsim40 wsjt_fort wsjt_cxx)
add_executable (ldpcsim120 lib/fsk4hf/ldpcsim120.f90 wsjtx.rc)
target_link_libraries (ldpcsim120 wsjt_fort wsjt_cxx)
add_executable (ldpcsim300 lib/fsk4hf/ldpcsim300.f90 wsjtx.rc)
target_link_libraries (ldpcsim300 wsjt_fort wsjt_cxx)
add_executable (ldpcsim174 lib/ft8/ldpcsim174.f90 wsjtx.rc)
target_link_libraries (ldpcsim174 wsjt_fort wsjt_cxx)
add_executable (ldpcsim144 lib/ldpcsim144.f90 wsjtx.rc)
target_link_libraries (ldpcsim144 wsjt_fort wsjt_cxx)
@@ -1214,7 +1227,10 @@ target_link_libraries (ldpcsim168 wsjt_fort wsjt_cxx)
add_executable (fsk4hf lib/fsk4hf/fsk4hf.f90 wsjtx.rc)
target_link_libraries (fsk4hf wsjt_fort wsjt_cxx)
add_executable (ft8sim lib/fsk4hf/ft8sim.f90 wsjtx.rc)
add_executable (ft8code lib/ft8/ft8code.f90 wsjtx.rc)
target_link_libraries (ft8code wsjt_fort wsjt_cxx)
add_executable (ft8sim lib/ft8/ft8sim.f90 wsjtx.rc)
target_link_libraries (ft8sim wsjt_fort wsjt_cxx)
add_executable (wsprlfsim lib/fsk4hf/wsprlfsim.f90 wsjtx.rc)
@@ -1283,7 +1299,7 @@ else (${OPENMP_FOUND} OR APPLE)
endif (${OPENMP_FOUND} OR APPLE)
# build the main application
add_executable (wsjtx MACOSX_BUNDLE
add_executable (ft8call MACOSX_BUNDLE
${wsjtx_CXXSRCS}
${wsjtx_GENUISRCS}
wsjtx.rc
@@ -1292,10 +1308,10 @@ add_executable (wsjtx MACOSX_BUNDLE
)
if (WSJT_CREATE_WINMAIN)
set_target_properties (wsjtx PROPERTIES WIN32_EXECUTABLE ON)
set_target_properties (ft8call PROPERTIES WIN32_EXECUTABLE ON)
endif (WSJT_CREATE_WINMAIN)
set_target_properties (wsjtx PROPERTIES
set_target_properties (ft8call PROPERTIES
MACOSX_BUNDLE_INFO_STRING "${WSJTX_DESCRIPTION_SUMMARY}"
MACOSX_BUNDLE_ICON_FILE "${WSJTX_ICON_FILE}"
MACOSX_BUNDLE_BUNDLE_VERSION ${wsjtx_VERSION}
@@ -1306,27 +1322,27 @@ set_target_properties (wsjtx PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER "org.k1jt.wsjtx"
)
target_include_directories (wsjtx PRIVATE ${FFTW3_INCLUDE_DIRS})
target_include_directories (ft8call PRIVATE ${FFTW3_INCLUDE_DIRS})
if (APPLE)
target_link_libraries (wsjtx wsjt_fort wsjt_cxx wsjt_qt wsjt_qtmm ${hamlib_LIBRARIES} ${FFTW3_LIBRARIES})
target_link_libraries (ft8call wsjt_fort wsjt_cxx wsjt_qt wsjt_qtmm ${hamlib_LIBRARIES} ${FFTW3_LIBRARIES})
else ()
target_link_libraries (wsjtx wsjt_fort_omp wsjt_cxx wsjt_qt wsjt_qtmm ${hamlib_LIBRARIES} ${FFTW3_LIBRARIES})
target_link_libraries (ft8call wsjt_fort_omp wsjt_cxx wsjt_qt wsjt_qtmm ${hamlib_LIBRARIES} ${FFTW3_LIBRARIES})
if (OpenMP_C_FLAGS)
set_target_properties (wsjtx PROPERTIES
set_target_properties (ft8call PROPERTIES
COMPILE_FLAGS "${OpenMP_C_FLAGS}"
LINK_FLAGS "${OpenMP_C_FLAGS}"
)
endif ()
set_target_properties (wsjtx PROPERTIES
set_target_properties (ft8call PROPERTIES
Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/fortran_modules_omp
)
if (WIN32)
set_target_properties (wsjtx PROPERTIES
set_target_properties (ft8call PROPERTIES
LINK_FLAGS -Wl,--stack,16777216
)
endif ()
endif ()
qt5_use_modules (wsjtx SerialPort) # not sure why the interface link library syntax above doesn't work
qt5_use_modules (ft8call SerialPort) # not sure why the interface link library syntax above doesn't work
# make a library for WSJT-X UDP servers
# add_library (wsjtx_udp SHARED ${UDP_library_CXXSRCS})
@@ -1371,18 +1387,18 @@ endif (WSJT_CREATE_WINMAIN)
if (UNIX)
if (NOT WSJT_SKIP_MANPAGES)
add_subdirectory (manpages)
add_dependencies (wsjtx manpages)
add_dependencies (ft8call manpages)
endif (NOT WSJT_SKIP_MANPAGES)
if (NOT APPLE)
add_subdirectory (debian)
add_dependencies (wsjtx debian)
add_dependencies (ft8call debian)
endif (NOT APPLE)
endif (UNIX)
#
# installation
#
install (TARGETS wsjtx
install (TARGETS ft8call
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
BUNDLE DESTINATION . COMPONENT runtime
)
@@ -1409,7 +1425,7 @@ install (TARGETS udp_daemon message_aggregator
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
)
install (TARGETS jt9 jt65code qra64code qra64sim jt9code jt4code
install (TARGETS jt9 ft8code jt65code qra64code qra64sim jt9code jt4code
msk144code wsprd wspr_fsk8d fmtave fcal fmeasure
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
@@ -1472,11 +1488,11 @@ add_custom_target (uninstall
# creates svnversion.h using cmake script
add_custom_target (revisiontag
COMMAND ${CMAKE_COMMAND} -D SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR} -D OUTPUT_DIR=${PROJECT_BINARY_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/CMake/getsvn.cmake
COMMENT "Generating Subversion revision information"
VERBATIM
)
# add_custom_target (revisiontag
# COMMAND ${CMAKE_COMMAND} -D SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR} -D OUTPUT_DIR=${PROJECT_BINARY_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/CMake/getsvn.cmake
# COMMENT "Generating Subversion revision information"
# VERBATIM
# )
# explicitly say that the wsjt_qt depends on custom target, this is
# done indirectly so that the revisiontag target gets built exactly
# once per build
@@ -1496,7 +1512,7 @@ if (NOT WIN32 AND NOT APPLE)
# install a desktop file so wsjtx appears in the application start
# menu with an icon
install (
FILES wsjtx.desktop message_aggregator.desktop
FILES ft8call.desktop message_aggregator.desktop
DESTINATION share/applications
#COMPONENT runtime
)
+1
View File
@@ -10,6 +10,7 @@ auto CallsignValidator::validate (QString& input, int& pos) const -> State
{
auto match = re_.match (input, 0, QRegularExpression::PartialPreferCompleteMatch);
input = input.toUpper ();
if (input.count(QLatin1Char('/')) > 1) return Invalid;
if (match.hasMatch ()) return Acceptable;
if (!input.size () || match.hasPartialMatch ()) return Intermediate;
pos = input.size ();
+250 -12
View File
@@ -140,6 +140,7 @@
#include <QSettings>
#include <QAudioDeviceInfo>
#include <QAudioInput>
#include <QDebug>
#include <QDialog>
#include <QAction>
#include <QFileDialog>
@@ -160,7 +161,6 @@
#include <QColorDialog>
#include <QSerialPortInfo>
#include <QScopedPointer>
#include <QDebug>
#include "pimpl_impl.hpp"
#include "qt_helpers.hpp"
@@ -181,6 +181,8 @@
#include "MaidenheadLocatorValidator.hpp"
#include "CallsignValidator.hpp"
#include "varicode.h"
#include "ui_Configuration.h"
#include "moc_Configuration.cpp"
@@ -430,6 +432,8 @@ private:
Q_SLOT void on_add_macro_push_button_clicked (bool = false);
Q_SLOT void on_delete_macro_push_button_clicked (bool = false);
Q_SLOT void on_PTT_method_button_group_buttonClicked (int);
Q_SLOT void on_station_message_line_edit_textChanged(QString const&);
Q_SLOT void on_qth_message_line_edit_textChanged(QString const&);
Q_SLOT void on_add_macro_line_edit_editingFinished ();
Q_SLOT void delete_macro ();
void delete_selected_macros (QModelIndexList);
@@ -444,6 +448,10 @@ private:
Q_SLOT void on_pbTxMsg_clicked();
Q_SLOT void on_pbNewDXCC_clicked();
Q_SLOT void on_pbNewCall_clicked();
Q_SLOT void on_cbFox_clicked (bool);
Q_SLOT void on_cbHound_clicked (bool);
Q_SLOT void on_cbx2ToneSpacing_clicked(bool);
Q_SLOT void on_cbx4ToneSpacing_clicked(bool);
// typenames used as arguments must match registered type names :(
Q_SIGNAL void start_transceiver (unsigned seqeunce_number) const;
@@ -520,10 +528,16 @@ private:
CalibrationParams calibration_;
bool frequency_calibration_disabled_; // not persistent
unsigned transceiver_command_number_;
QString dynamic_grid_;
// configuration fields that we publish
QString my_callsign_;
QString my_grid_;
QString my_station_;
int my_dBm_;
QString my_qth_;
int callsign_aging_;
int activity_aging_;
QColor color_CQ_;
QColor next_color_CQ_;
QColor color_MyCall_;
@@ -543,6 +557,7 @@ private:
bool id_after_73_;
bool tx_QSY_allowed_;
bool spot_to_psk_reporter_;
bool autoreply_off_at_startup_;
bool monitor_off_at_startup_;
bool monitor_last_used_;
bool log_as_RTTY_;
@@ -550,20 +565,33 @@ private:
bool prompt_to_log_;
bool insert_blank_;
bool DXCC_;
bool ppfx_;
bool clear_DX_;
bool miles_;
bool quick_call_;
bool disable_TX_on_73_;
int beacon_;
int watchdog_;
bool TX_messages_;
bool enable_VHF_features_;
bool decode_at_52s_;
bool single_decode_;
bool twoPass_;
bool bFox_;
bool bHound_;
bool x2ToneSpacing_;
bool realTimeDecode_;
bool x4ToneSpacing_;
bool use_dynamic_grid_;
QString opCall_;
QString udp_server_name_;
port_type udp_server_port_;
// QString n1mm_server_name () const;
QString n1mm_server_name_;
port_type n1mm_server_port_;
bool broadcast_to_n1mm_;
// port_type n1mm_server_port () const;
// bool valid_n1mm_info () const;
// bool broadcast_to_n1mm() const;
bool accept_udp_requests_;
bool udpWindowToFront_;
bool udpWindowRestore_;
@@ -612,7 +640,6 @@ bool Configuration::restart_audio_input () const {return m_->restart_sound_input
bool Configuration::restart_audio_output () const {return m_->restart_sound_output_device_;}
auto Configuration::type_2_msg_gen () const -> Type2MsgGen {return m_->type_2_msg_gen_;}
QString Configuration::my_callsign () const {return m_->my_callsign_;}
QString Configuration::my_grid () const {return m_->my_grid_;}
QColor Configuration::color_CQ () const {return m_->color_CQ_;}
QColor Configuration::color_MyCall () const {return m_->color_MyCall_;}
QColor Configuration::color_TxMsg () const {return m_->color_TxMsg_;}
@@ -633,6 +660,15 @@ bool Configuration::spot_to_psk_reporter () const
// rig must be open and working to spot externally
return is_transceiver_online () && m_->spot_to_psk_reporter_;
}
void Configuration::set_spot_to_psk_reporter (bool spot)
{
if(m_->spot_to_psk_reporter_ != spot){
m_->spot_to_psk_reporter_ = spot;
m_->write_settings();
}
}
bool Configuration::autoreply_off_at_startup () const {return m_->autoreply_off_at_startup_;}
bool Configuration::monitor_off_at_startup () const {return m_->monitor_off_at_startup_;}
bool Configuration::monitor_last_used () const {return m_->rig_is_dummy_ || m_->monitor_last_used_;}
bool Configuration::log_as_RTTY () const {return m_->log_as_RTTY_;}
@@ -640,22 +676,30 @@ bool Configuration::report_in_comments () const {return m_->report_in_comments_;
bool Configuration::prompt_to_log () const {return m_->prompt_to_log_;}
bool Configuration::insert_blank () const {return m_->insert_blank_;}
bool Configuration::DXCC () const {return m_->DXCC_;}
bool Configuration::ppfx() const {return m_->ppfx_;}
bool Configuration::clear_DX () const {return m_->clear_DX_;}
bool Configuration::miles () const {return m_->miles_;}
bool Configuration::quick_call () const {return m_->quick_call_;}
bool Configuration::disable_TX_on_73 () const {return m_->disable_TX_on_73_;}
int Configuration::beacon () const {return m_->beacon_;}
int Configuration::watchdog () const {return m_->watchdog_;}
bool Configuration::TX_messages () const {return m_->TX_messages_;}
bool Configuration::enable_VHF_features () const {return m_->enable_VHF_features_;}
bool Configuration::decode_at_52s () const {return m_->decode_at_52s_;}
bool Configuration::single_decode () const {return m_->single_decode_;}
bool Configuration::twoPass() const {return m_->twoPass_;}
bool Configuration::bFox() const {return m_->bFox_;}
bool Configuration::bHound() const {return m_->bHound_;}
bool Configuration::x2ToneSpacing() const {return m_->x2ToneSpacing_;}
bool Configuration::realTimeDecode() const {return m_->realTimeDecode_;}
bool Configuration::x4ToneSpacing() const {return m_->x4ToneSpacing_;}
bool Configuration::split_mode () const {return m_->split_mode ();}
QString Configuration::opCall() const {return m_->opCall_;}
QString Configuration::udp_server_name () const {return m_->udp_server_name_;}
auto Configuration::udp_server_port () const -> port_type {return m_->udp_server_port_;}
bool Configuration::accept_udp_requests () const {return m_->accept_udp_requests_;}
QString Configuration::n1mm_server_name () const {return m_->n1mm_server_name_;}
auto Configuration::n1mm_server_port () const -> port_type {return m_->n1mm_server_port_;}
bool Configuration::broadcast_to_n1mm () const {return m_->broadcast_to_n1mm_;}
bool Configuration::udpWindowToFront () const {return m_->udpWindowToFront_;}
bool Configuration::udpWindowRestore () const {return m_->udpWindowRestore_;}
Bands * Configuration::bands () {return &m_->bands_;}
@@ -766,6 +810,55 @@ void Configuration::sync_transceiver (bool force_signal, bool enforce_mode_and_s
}
}
bool Configuration::valid_n1mm_info () const
{
// do very rudimentary checking on the n1mm server name and port number.
//
auto server_name = m_->n1mm_server_name_;
auto port_number = m_->n1mm_server_port_;
return(!(server_name.trimmed().isEmpty() || port_number == 0));
}
QString Configuration::my_grid() const
{
auto the_grid = m_->my_grid_;
if (m_->use_dynamic_grid_ && m_->dynamic_grid_.size () >= 4) {
the_grid = m_->dynamic_grid_;
}
return the_grid;
}
QString Configuration::my_station() const
{
return m_->my_station_;
}
int Configuration::my_dBm() const {
return m_->my_dBm_;
}
QString Configuration::my_qth() const
{
return m_->my_qth_;
}
int Configuration::callsign_aging() const
{
return m_->callsign_aging_;
}
int Configuration::activity_aging() const
{
return m_->activity_aging_;
}
void Configuration::set_location (QString const& grid_descriptor)
{
// change the dynamic grid
qDebug () << "Configuration::set_location - location:" << grid_descriptor;
m_->dynamic_grid_ = grid_descriptor.trimmed ();
}
namespace
{
#if defined (Q_OS_MAC)
@@ -897,10 +990,15 @@ Configuration::impl::impl (Configuration * self, QDir const& temp_directory,
ui_->callsign_line_edit->setValidator (new CallsignValidator {this});
ui_->grid_line_edit->setValidator (new MaidenheadLocatorValidator {this});
ui_->add_macro_line_edit->setValidator (new QRegExpValidator {message_alphabet, this});
ui_->station_message_line_edit->setValidator (new QRegExpValidator {message_alphabet, this});
ui_->qth_message_line_edit->setValidator (new QRegExpValidator {message_alphabet, this});
ui_->udp_server_port_spin_box->setMinimum (1);
ui_->udp_server_port_spin_box->setMaximum (std::numeric_limits<port_type>::max ());
ui_->n1mm_server_port_spin_box->setMinimum (1);
ui_->n1mm_server_port_spin_box->setMaximum (std::numeric_limits<port_type>::max ());
//
// assign ids to radio buttons
//
@@ -1064,10 +1162,50 @@ void Configuration::impl::initialize_models ()
{
pal.setColor (QPalette::Base, Qt::white);
}
QMap<int, int> dbm2mw = {
{0 , 1},
{3 , 2},
{7 , 5},
{10 , 10},
{13 , 20},
{17 , 50},
{20 , 100},
{23 , 200},
{27 , 500},
{30 , 1000}, // 1W
{33 , 2000}, // 2W
{37 , 5000}, // 5W
{40 , 10000}, // 10W
{43 , 20000}, // 20W
{47 , 50000}, // 50W
{50 , 100000}, // 100W
{53 , 200000}, // 200W
{57 , 500000}, // 500W
{60 , 1000000}, // 1000W
};
ui_->station_power_combo_box->clear();
ui_->station_power_combo_box->addItem(QString(""), -1);
foreach(auto dbm, dbm2mw.keys()){
ui_->station_power_combo_box->addItem(QString("%1 (%2 dBm)").arg(Varicode::formatPWR(dbm)).arg(dbm), dbm);
if(dbm == my_dBm_){
ui_->station_power_combo_box->setCurrentIndex(ui_->station_power_combo_box->count()-1);
}
}
ui_->callsign_line_edit->setPalette (pal);
ui_->grid_line_edit->setPalette (pal);
ui_->callsign_line_edit->setText (my_callsign_);
ui_->grid_line_edit->setText (my_grid_);
ui_->callsign_aging_spin_box->setValue(callsign_aging_);
ui_->activity_aging_spin_box->setValue(activity_aging_);
ui_->station_message_line_edit->setText (my_station_.toUpper());
ui_->qth_message_line_edit->setText (my_qth_.toUpper());
ui_->use_dynamic_grid->setChecked(use_dynamic_grid_);
ui_->labCQ->setStyleSheet(QString("background: %1").arg(color_CQ_.name()));
ui_->labMyCall->setStyleSheet(QString("background: %1").arg(color_MyCall_.name()));
ui_->labTx->setStyleSheet(QString("background: %1").arg(color_TxMsg_.name()));
@@ -1085,6 +1223,7 @@ void Configuration::impl::initialize_models ()
ui_->CW_id_after_73_check_box->setChecked (id_after_73_);
ui_->tx_QSY_check_box->setChecked (tx_QSY_allowed_);
ui_->psk_reporter_check_box->setChecked (spot_to_psk_reporter_);
ui_->autoreply_off_check_box->setChecked (autoreply_off_at_startup_);
ui_->monitor_off_check_box->setChecked (monitor_off_at_startup_);
ui_->monitor_last_used_check_box->setChecked (monitor_last_used_);
ui_->log_as_RTTY_check_box->setChecked (log_as_RTTY_);
@@ -1092,19 +1231,22 @@ void Configuration::impl::initialize_models ()
ui_->prompt_to_log_check_box->setChecked (prompt_to_log_);
ui_->insert_blank_check_box->setChecked (insert_blank_);
ui_->DXCC_check_box->setChecked (DXCC_);
ui_->ppfx_check_box->setChecked (ppfx_);
ui_->clear_DX_check_box->setChecked (clear_DX_);
ui_->miles_check_box->setChecked (miles_);
ui_->quick_call_check_box->setChecked (quick_call_);
ui_->disable_TX_on_73_check_box->setChecked (disable_TX_on_73_);
ui_->beacon_spin_box->setValue (beacon_);
ui_->tx_watchdog_spin_box->setValue (watchdog_);
ui_->TX_messages_check_box->setChecked (TX_messages_);
ui_->enable_VHF_features_check_box->setChecked(enable_VHF_features_);
ui_->decode_at_52s_check_box->setChecked(decode_at_52s_);
ui_->single_decode_check_box->setChecked(single_decode_);
ui_->cbTwoPass->setChecked(twoPass_);
ui_->cbFox->setChecked(bFox_);
ui_->cbHound->setChecked(bHound_);
ui_->cbx2ToneSpacing->setChecked(x2ToneSpacing_);
ui_->cbRealTime->setChecked(realTimeDecode_);
ui_->cbRealTime->setVisible(false); //Tempoary -- probably will remove this control
ui_->cbx4ToneSpacing->setChecked(x4ToneSpacing_);
ui_->type_2_msg_gen_combo_box->setCurrentIndex (type_2_msg_gen_);
ui_->rig_combo_box->setCurrentText (rig_params_.rig_name);
ui_->TX_mode_button_group->button (data_mode_)->setChecked (true);
@@ -1133,9 +1275,13 @@ void Configuration::impl::initialize_models ()
}
ui_->TX_audio_source_button_group->button (rig_params_.audio_source)->setChecked (true);
ui_->CAT_poll_interval_spin_box->setValue (rig_params_.poll_interval);
ui_->opCallEntry->setText (opCall_);
ui_->udp_server_line_edit->setText (udp_server_name_);
ui_->udp_server_port_spin_box->setValue (udp_server_port_);
ui_->accept_udp_requests_check_box->setChecked (accept_udp_requests_);
ui_->n1mm_server_name_line_edit->setText (n1mm_server_name_);
ui_->n1mm_server_port_spin_box->setValue (n1mm_server_port_);
ui_->enable_n1mm_broadcast_check_box->setChecked (broadcast_to_n1mm_);
ui_->udpWindowToFront->setChecked(udpWindowToFront_);
ui_->udpWindowRestore->setChecked(udpWindowRestore_);
ui_->calibration_intercept_spin_box->setValue (calibration_.intercept);
@@ -1178,6 +1324,11 @@ void Configuration::impl::read_settings ()
my_callsign_ = settings_->value ("MyCall", QString {}).toString ();
my_grid_ = settings_->value ("MyGrid", QString {}).toString ();
my_station_ = settings_->value("MyStation", QString {}).toString();
my_dBm_ = settings_->value("MyPower", -1).toInt();
callsign_aging_ = settings_->value ("CallsignAging", 0).toInt ();
activity_aging_ = settings_->value ("ActivityAging", 2).toInt ();
my_qth_ = settings_->value("MyQTH", QString {}).toString();
next_color_CQ_ = color_CQ_ = settings_->value("colorCQ","#66ff66").toString();
next_color_MyCall_ = color_MyCall_ = settings_->value("colorMyCall","#ff6666").toString();
next_color_TxMsg_ = color_TxMsg_ = settings_->value("colorTxMsg","#ffff00").toString();
@@ -1271,13 +1422,17 @@ void Configuration::impl::read_settings ()
type_2_msg_gen_ = settings_->value ("Type2MsgGen", QVariant::fromValue (Configuration::type_2_msg_3_full)).value<Configuration::Type2MsgGen> ();
autoreply_off_at_startup_ = settings_->value ("AutoreplyOFF", false).toBool ();
monitor_off_at_startup_ = settings_->value ("MonitorOFF", false).toBool ();
monitor_last_used_ = settings_->value ("MonitorLastUsed", false).toBool ();
spot_to_psk_reporter_ = settings_->value ("PSKReporter", false).toBool ();
id_after_73_ = settings_->value ("After73", false).toBool ();
tx_QSY_allowed_ = settings_->value ("TxQSYAllowed", false).toBool ();
use_dynamic_grid_ = settings_->value ("AutoGrid", false).toBool ();
macros_.setStringList (settings_->value ("Macros", QStringList {"TNX 73 GL"}).toStringList ());
auto loadedMacros = settings_->value ("Macros", QStringList {"TNX 73 GL"}).toStringList();
macros_.setStringList (loadedMacros);
region_ = settings_->value ("Region", QVariant::fromValue (IARURegions::ALL)).value<IARURegions::Region> ();
@@ -1322,22 +1477,30 @@ void Configuration::impl::read_settings ()
prompt_to_log_ = settings_->value ("PromptToLog", false).toBool ();
insert_blank_ = settings_->value ("InsertBlank", false).toBool ();
DXCC_ = settings_->value ("DXCCEntity", false).toBool ();
ppfx_ = settings_->value ("PrincipalPrefix", false).toBool ();
clear_DX_ = settings_->value ("ClearCallGrid", false).toBool ();
miles_ = settings_->value ("Miles", false).toBool ();
quick_call_ = settings_->value ("QuickCall", false).toBool ();
disable_TX_on_73_ = settings_->value ("73TxDisable", false).toBool ();
watchdog_ = settings_->value ("TxWatchdog", 6).toInt ();
beacon_ = settings_->value ("TxBeacon", 15).toInt ();
watchdog_ = settings_->value ("TxWatchdog", 0).toInt ();
TX_messages_ = settings_->value ("Tx2QSO", true).toBool ();
enable_VHF_features_ = settings_->value("VHFUHF",false).toBool ();
decode_at_52s_ = settings_->value("Decode52",false).toBool ();
single_decode_ = settings_->value("SingleDecode",false).toBool ();
twoPass_ = settings_->value("TwoPass",true).toBool ();
bFox_ = settings_->value("Fox",false).toBool ();
bHound_ = settings_->value("Hound",false).toBool ();
x2ToneSpacing_ = settings_->value("x2ToneSpacing",false).toBool ();
realTimeDecode_ = settings_->value("RealTimeDecode",false).toBool ();
x4ToneSpacing_ = settings_->value("x4ToneSpacing",false).toBool ();
rig_params_.poll_interval = settings_->value ("Polling", 0).toInt ();
rig_params_.split_mode = settings_->value ("SplitMode", QVariant::fromValue (TransceiverFactory::split_mode_none)).value<TransceiverFactory::SplitMode> ();
opCall_ = settings_->value ("OpCall", "").toString ();
udp_server_name_ = settings_->value ("UDPServer", "127.0.0.1").toString ();
udp_server_port_ = settings_->value ("UDPServerPort", 2237).toUInt ();
n1mm_server_name_ = settings_->value ("N1MMServer", "127.0.0.1").toString ();
n1mm_server_port_ = settings_->value ("N1MMServerPort", 2333).toUInt ();
broadcast_to_n1mm_ = settings_->value ("BroadcastToN1MM", false).toBool ();
accept_udp_requests_ = settings_->value ("AcceptUDPRequests", false).toBool ();
udpWindowToFront_ = settings_->value ("udpWindowToFront",false).toBool ();
udpWindowRestore_ = settings_->value ("udpWindowRestore",false).toBool ();
@@ -1353,6 +1516,11 @@ void Configuration::impl::write_settings ()
settings_->setValue ("MyCall", my_callsign_);
settings_->setValue ("MyGrid", my_grid_);
settings_->setValue ("MyStation", my_station_);
settings_->setValue ("MyPower", my_dBm_);
settings_->setValue ("MyQTH", my_qth_);
settings_->setValue ("CallsignAging", callsign_aging_);
settings_->setValue ("ActivityAging", activity_aging_);
settings_->setValue("colorCQ",color_CQ_);
settings_->setValue("colorMyCall",color_MyCall_);
settings_->setValue("colorTxMsg",color_TxMsg_);
@@ -1391,6 +1559,7 @@ void Configuration::impl::write_settings ()
settings_->setValue ("AudioInputChannel", AudioDevice::toString (audio_input_channel_));
settings_->setValue ("AudioOutputChannel", AudioDevice::toString (audio_output_channel_));
settings_->setValue ("Type2MsgGen", QVariant::fromValue (type_2_msg_gen_));
settings_->setValue ("AutoreplyOFF", autoreply_off_at_startup_);
settings_->setValue ("MonitorOFF", monitor_off_at_startup_);
settings_->setValue ("MonitorLastUsed", monitor_last_used_);
settings_->setValue ("PSKReporter", spot_to_psk_reporter_);
@@ -1413,10 +1582,12 @@ void Configuration::impl::write_settings ()
settings_->setValue ("PromptToLog", prompt_to_log_);
settings_->setValue ("InsertBlank", insert_blank_);
settings_->setValue ("DXCCEntity", DXCC_);
settings_->setValue ("PrincipalPrefix", ppfx_);
settings_->setValue ("ClearCallGrid", clear_DX_);
settings_->setValue ("Miles", miles_);
settings_->setValue ("QuickCall", quick_call_);
settings_->setValue ("73TxDisable", disable_TX_on_73_);
settings_->setValue ("TxBeacon", beacon_);
settings_->setValue ("TxWatchdog", watchdog_);
settings_->setValue ("Tx2QSO", TX_messages_);
settings_->setValue ("CATForceDTR", rig_params_.force_dtr);
@@ -1430,10 +1601,16 @@ void Configuration::impl::write_settings ()
settings_->setValue ("Decode52", decode_at_52s_);
settings_->setValue ("SingleDecode", single_decode_);
settings_->setValue ("TwoPass", twoPass_);
settings_->setValue ("Fox", bFox_);
settings_->setValue ("Hound", bHound_);
settings_->setValue ("x2ToneSpacing", x2ToneSpacing_);
settings_->setValue ("RealTimeDecode", realTimeDecode_);
settings_->setValue ("x4ToneSpacing", x4ToneSpacing_);
settings_->setValue ("OpCall", opCall_);
settings_->setValue ("UDPServer", udp_server_name_);
settings_->setValue ("UDPServerPort", udp_server_port_);
settings_->setValue ("N1MMServer", n1mm_server_name_);
settings_->setValue ("N1MMServerPort", n1mm_server_port_);
settings_->setValue ("BroadcastToN1MM", broadcast_to_n1mm_);
settings_->setValue ("AcceptUDPRequests", accept_udp_requests_);
settings_->setValue ("udpWindowToFront", udpWindowToFront_);
settings_->setValue ("udpWindowRestore", udpWindowRestore_);
@@ -1442,6 +1619,7 @@ void Configuration::impl::write_settings ()
settings_->setValue ("pwrBandTxMemory", pwrBandTxMemory_);
settings_->setValue ("pwrBandTuneMemory", pwrBandTuneMemory_);
settings_->setValue ("Region", QVariant::fromValue (region_));
settings_->setValue ("AutoGrid", use_dynamic_grid_);
}
void Configuration::impl::set_rig_invariants ()
@@ -1795,6 +1973,11 @@ void Configuration::impl::accept ()
my_callsign_ = ui_->callsign_line_edit->text ();
my_grid_ = ui_->grid_line_edit->text ();
my_station_ = ui_->station_message_line_edit->text().toUpper();
my_dBm_ = ui_->station_power_combo_box->currentData().toInt();
my_qth_ = ui_->qth_message_line_edit->text().toUpper();
callsign_aging_ = ui_->callsign_aging_spin_box->value();
activity_aging_ = ui_->activity_aging_spin_box->value();
spot_to_psk_reporter_ = ui_->psk_reporter_check_box->isChecked ();
id_interval_ = ui_->CW_id_interval_spin_box->value ();
ntrials_ = ui_->sbNtrials->value ();
@@ -1804,6 +1987,7 @@ void Configuration::impl::accept ()
RxBandwidth_ = ui_->sbBandwidth->value ();
id_after_73_ = ui_->CW_id_after_73_check_box->isChecked ();
tx_QSY_allowed_ = ui_->tx_QSY_check_box->isChecked ();
autoreply_off_at_startup_ = ui_->autoreply_off_check_box->isChecked ();
monitor_off_at_startup_ = ui_->monitor_off_check_box->isChecked ();
monitor_last_used_ = ui_->monitor_last_used_check_box->isChecked ();
type_2_msg_gen_ = static_cast<Type2MsgGen> (ui_->type_2_msg_gen_combo_box->currentIndex ());
@@ -1812,10 +1996,12 @@ void Configuration::impl::accept ()
prompt_to_log_ = ui_->prompt_to_log_check_box->isChecked ();
insert_blank_ = ui_->insert_blank_check_box->isChecked ();
DXCC_ = ui_->DXCC_check_box->isChecked ();
ppfx_ = ui_->ppfx_check_box->isChecked ();
clear_DX_ = ui_->clear_DX_check_box->isChecked ();
miles_ = ui_->miles_check_box->isChecked ();
quick_call_ = ui_->quick_call_check_box->isChecked ();
disable_TX_on_73_ = ui_->disable_TX_on_73_check_box->isChecked ();
beacon_ = ui_->beacon_spin_box->value ();
watchdog_ = ui_->tx_watchdog_spin_box->value ();
TX_messages_ = ui_->TX_messages_check_box->isChecked ();
data_mode_ = static_cast<DataMode> (ui_->TX_mode_button_group->checkedId ());
@@ -1825,12 +2011,15 @@ void Configuration::impl::accept ()
decode_at_52s_ = ui_->decode_at_52s_check_box->isChecked ();
single_decode_ = ui_->single_decode_check_box->isChecked ();
twoPass_ = ui_->cbTwoPass->isChecked ();
bFox_ = ui_->cbFox->isChecked ();
bHound_ = ui_->cbHound->isChecked ();
x2ToneSpacing_ = ui_->cbx2ToneSpacing->isChecked ();
realTimeDecode_ = ui_->cbRealTime->isChecked ();
x4ToneSpacing_ = ui_->cbx4ToneSpacing->isChecked ();
calibration_.intercept = ui_->calibration_intercept_spin_box->value ();
calibration_.slope_ppm = ui_->calibration_slope_ppm_spin_box->value ();
pwrBandTxMemory_ = ui_->checkBoxPwrBandTxMemory->isChecked ();
pwrBandTuneMemory_ = ui_->checkBoxPwrBandTuneMemory->isChecked ();
opCall_=ui_->opCallEntry->text();
auto new_server = ui_->udp_server_line_edit->text ();
if (new_server != udp_server_name_)
{
@@ -1846,6 +2035,12 @@ void Configuration::impl::accept ()
}
accept_udp_requests_ = ui_->accept_udp_requests_check_box->isChecked ();
auto new_n1mm_server = ui_->n1mm_server_name_line_edit->text ();
n1mm_server_name_ = new_n1mm_server;
auto new_n1mm_port = ui_->n1mm_server_port_spin_box->value ();
n1mm_server_port_ = new_n1mm_port;
broadcast_to_n1mm_ = ui_->enable_n1mm_broadcast_check_box->isChecked ();
udpWindowToFront_ = ui_->udpWindowToFront->isChecked ();
udpWindowRestore_ = ui_->udpWindowRestore->isChecked ();
@@ -1867,7 +2062,14 @@ void Configuration::impl::accept ()
stations_.station_list(next_stations_.station_list ());
stations_.sort (StationList::band_column);
}
if (ui_->use_dynamic_grid->isChecked() && !use_dynamic_grid_ )
{
// turning on so clear it so only the next location update gets used
dynamic_grid_.clear ();
}
use_dynamic_grid_ = ui_->use_dynamic_grid->isChecked();
write_settings (); // make visible to all
}
@@ -2060,6 +2262,22 @@ void Configuration::impl::on_sound_output_combo_box_currentTextChanged (QString
default_audio_output_device_selected_ = QAudioDeviceInfo::defaultOutputDevice ().deviceName () == text;
}
void Configuration::impl::on_station_message_line_edit_textChanged(QString const &text)
{
QString upper = text.toUpper();
if(text != upper){
ui_->station_message_line_edit->setText (upper);
}
}
void Configuration::impl::on_qth_message_line_edit_textChanged(QString const &text)
{
QString upper = text.toUpper();
if(text != upper){
ui_->qth_message_line_edit->setText (upper);
}
}
void Configuration::impl::on_add_macro_line_edit_editingFinished ()
{
ui_->add_macro_line_edit->setText (ui_->add_macro_line_edit->text ().toUpper ());
@@ -2295,6 +2513,26 @@ void Configuration::impl::on_calibration_slope_ppm_spin_box_valueChanged (double
rig_active_ = false; // force reset
}
void Configuration::impl::on_cbFox_clicked (bool checked)
{
if (checked) ui_->cbHound->setChecked (false);
}
void Configuration::impl::on_cbHound_clicked (bool checked)
{
if (checked) ui_->cbFox->setChecked (false);
}
void Configuration::impl::on_cbx2ToneSpacing_clicked(bool b)
{
if(b) ui_->cbx4ToneSpacing->setChecked(false);
}
void Configuration::impl::on_cbx4ToneSpacing_clicked(bool b)
{
if(b) ui_->cbx2ToneSpacing->setChecked(false);
}
bool Configuration::impl::have_rig ()
{
if (!open_rig ())
+20 -1
View File
@@ -96,6 +96,11 @@ public:
QString my_callsign () const;
QString my_grid () const;
QString my_station () const;
int my_dBm() const;
int activity_aging() const;
int callsign_aging() const;
QString my_qth () const;
QFont text_font () const;
QFont decoded_text_font () const;
qint32 id_interval () const;
@@ -107,6 +112,8 @@ public:
bool id_after_73 () const;
bool tx_QSY_allowed () const;
bool spot_to_psk_reporter () const;
void set_spot_to_psk_reporter (bool);
bool autoreply_off_at_startup () const;
bool monitor_off_at_startup () const;
bool monitor_last_used () const;
bool log_as_RTTY () const;
@@ -114,10 +121,12 @@ public:
bool prompt_to_log () const;
bool insert_blank () const;
bool DXCC () const;
bool ppfx() const;
bool clear_DX () const;
bool miles () const;
bool quick_call () const;
bool disable_TX_on_73 () const;
int beacon () const;
int watchdog () const;
bool TX_messages () const;
bool split_mode () const;
@@ -125,17 +134,24 @@ public:
bool decode_at_52s () const;
bool single_decode () const;
bool twoPass() const;
bool bFox() const;
bool bHound() const;
bool x2ToneSpacing() const;
bool x4ToneSpacing() const;
bool contestMode() const;
bool realTimeDecode() const;
bool MyDx() const;
bool CQMyN() const;
bool NDxG() const;
bool NN() const;
bool EMEonly() const;
bool post_decodes () const;
QString opCall() const;
QString udp_server_name () const;
port_type udp_server_port () const;
QString n1mm_server_name () const;
port_type n1mm_server_port () const;
bool valid_n1mm_info () const;
bool broadcast_to_n1mm() const;
bool accept_udp_requests () const;
bool udpWindowToFront () const;
bool udpWindowRestore () const;
@@ -184,6 +200,9 @@ public:
// Set the calibration parameters and enable calibration corrections.
void set_calibration (CalibrationParams);
// Set the dynamic grid which is only used if configuration setting is enabled.
void set_location (QString const&);
// This method queries if a CAT and PTT connection is operational.
bool is_transceiver_online () const;
+893 -450
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -24,7 +24,7 @@ public:
//
Detector (unsigned frameRate, unsigned periodLengthInSeconds, unsigned downSampleFactor = 4u, QObject * parent = 0);
void setPeriod(unsigned p) {m_period=p;}
void setTRPeriod(unsigned p) {m_period=p;}
bool reset () override;
Q_SIGNAL void framesWritten (qint64) const;
+6 -4
View File
@@ -666,14 +666,16 @@ void HRDTransceiver::do_tx_frequency (Frequency tx, MODE mode, bool /*no_ignore*
set_data_mode (mode);
set_dropdown (receiver_dropdown_, (reversed_ ? rx_B_selection_ : rx_A_selection_).front ());
}
else if (vfo_count_ > 1)
else if (vfo_count_ > 1 && ((vfo_A_button_ >=0 && vfo_B_button_ >=0) || vfo_toggle_button_ >= 0))
{
set_button (vfo_A_button_ >= 0 ? (reversed_ ? vfo_A_button_ : vfo_B_button_) : vfo_toggle_button_);
set_dropdown (mode_A_dropdown_, lookup_mode (mode, mode_A_map_));
set_data_mode (mode);
set_button (vfo_A_button_ >= 0 ? (reversed_ ? vfo_B_button_ : vfo_A_button_) : vfo_toggle_button_);
}
// else Tx VFO mode gets set with frequency below
// else Tx VFO mode gets set with frequency below or we
// don't have a way of setting it so we assume it is
// always the same as the Rx VFO mode
}
}
@@ -809,7 +811,7 @@ void HRDTransceiver::do_mode (MODE mode)
set_dropdown (mode_A_dropdown_, lookup_mode (mode, mode_A_map_));
set_dropdown (receiver_dropdown_, rx_B_selection_.front ());
}
else if (vfo_count_ > 1)
else if (vfo_count_ > 1 && ((vfo_A_button_ >=0 && vfo_B_button_ >=0) || vfo_toggle_button_ >= 0))
{
set_button (vfo_A_button_ >= 0 ? vfo_A_button_ : vfo_toggle_button_);
set_dropdown (mode_A_dropdown_, lookup_mode (mode, mode_A_map_));
@@ -847,7 +849,7 @@ void HRDTransceiver::do_mode (MODE mode)
set_dropdown (mode_A_dropdown_, lookup_mode (mode, mode_A_map_));
set_dropdown (receiver_dropdown_, rx_A_selection_.front ());
}
else if (vfo_count_ > 1)
else if (vfo_count_ > 1 && ((vfo_A_button_ >=0 && vfo_B_button_ >=0) || vfo_toggle_button_ >= 0))
{
set_button (vfo_B_button_ >= 0 ? vfo_B_button_ : vfo_toggle_button_);
set_dropdown (mode_A_dropdown_, lookup_mode (mode, mode_A_map_));
+3 -3
View File
@@ -804,9 +804,9 @@ void HamlibTransceiver::do_tx_frequency (Frequency tx, MODE mode, bool no_ignore
if (UNK != mode)
{
auto new_mode = map_mode (mode);
// TRACE_CAT ("HamlibTransceiver", "rig_set_split_freq_mode freq = " << tx
// << " mode = " << rig_strrmode (new_mode));
// error_check (rig_set_split_freq_mode (rig_.data (), RIG_VFO_CURR, tx, new_mode, RIG_PASSBAND_NOCHANGE), tr ("setting split TX frequency and mode"));
TRACE_CAT ("HamlibTransceiver", "rig_set_split_freq_mode freq = " << tx
<< " mode = " << rig_strrmode (new_mode));
error_check (rig_set_split_freq_mode (rig_.data (), RIG_VFO_CURR, tx, new_mode, RIG_PASSBAND_NOCHANGE), tr ("setting split TX frequency and mode"));
}
else
{
+2 -1
View File
@@ -2,6 +2,7 @@
#include <QDialogButtonBox>
#include <QPushButton>
#include <QCoreApplication>
#include "revision_utils.hpp"
@@ -13,7 +14,7 @@ MessageBox::MessageBox (QWidget * parent)
MessageBox::MessageBox (Icon icon, QString const& text, StandardButtons buttons
, QWidget * parent, Qt::WindowFlags flags)
: QMessageBox {icon, program_title (), text, buttons, parent, flags}
: QMessageBox {icon, QCoreApplication::applicationName (), text, buttons, parent, flags}
{
}
+58 -10
View File
@@ -1,6 +1,8 @@
#include "MessageClient.hpp"
#include <stdexcept>
#include <vector>
#include <algorithm>
#include <QUdpSocket>
#include <QHostInfo>
@@ -76,6 +78,7 @@ public:
QHostAddress server_;
quint32 schema_;
QTimer * heartbeat_timer_;
std::vector<QHostAddress> blocked_addresses_;
// hold messages sent before host lookup completes asynchronously
QQueue<QByteArray> pending_messages_;
@@ -93,15 +96,24 @@ void MessageClient::impl::host_info_results (QHostInfo host_info)
}
else if (host_info.addresses ().size ())
{
server_ = host_info.addresses ()[0];
// send initial heartbeat which allows schema negotiation
heartbeat ();
// clear any backlog
while (pending_messages_.size ())
auto server = host_info.addresses ()[0];
if (blocked_addresses_.end () == std::find (blocked_addresses_.begin (), blocked_addresses_.end (), server))
{
send_message (pending_messages_.dequeue ());
server_ = server;
// send initial heartbeat which allows schema negotiation
heartbeat ();
// clear any backlog
while (pending_messages_.size ())
{
send_message (pending_messages_.dequeue ());
}
}
else
{
Q_EMIT self_->error ("UDP server blocked, please try another");
pending_messages_.clear (); // discard
}
}
}
@@ -195,6 +207,17 @@ void MessageClient::impl::parse_message (QByteArray const& msg)
}
break;
case NetworkMessage::Location:
{
QByteArray location;
in >> location;
if (check_status (in) != Fail)
{
Q_EMIT self_->location (QString::fromUtf8 (location));
}
}
break;
default:
// Ignore
//
@@ -349,6 +372,17 @@ void MessageClient::send_raw_datagram (QByteArray const& message, QHostAddress c
}
}
void MessageClient::add_blocked_destination (QHostAddress const& a)
{
m_->blocked_addresses_.push_back (a);
if (a == m_->server_)
{
m_->server_.clear ();
Q_EMIT error ("UDP server blocked, please try another");
m_->pending_messages_.clear (); // discard
}
}
void MessageClient::status_update (Frequency f, QString const& mode, QString const& dx_call
, QString const& report, QString const& tx_mode
, bool tx_enabled, bool transmitting, bool decoding
@@ -410,7 +444,9 @@ void MessageClient::clear_decodes ()
void MessageClient::qso_logged (QDateTime time_off, QString const& dx_call, QString const& dx_grid
, Frequency dial_frequency, QString const& mode, QString const& report_sent
, QString const& report_received, QString const& tx_power
, QString const& comments, QString const& name, QDateTime time_on)
, QString const& comments, QString const& name, QDateTime time_on
, QString const& operator_call, QString const& my_call
, QString const& my_grid)
{
if (m_->server_port_ && !m_->server_string_.isEmpty ())
{
@@ -418,7 +454,19 @@ void MessageClient::qso_logged (QDateTime time_off, QString const& dx_call, QStr
NetworkMessage::Builder out {&message, NetworkMessage::QSOLogged, m_->id_, m_->schema_};
out << time_off << dx_call.toUtf8 () << dx_grid.toUtf8 () << dial_frequency << mode.toUtf8 ()
<< report_sent.toUtf8 () << report_received.toUtf8 () << tx_power.toUtf8 () << comments.toUtf8 ()
<< name.toUtf8 () << time_on;
<< name.toUtf8 () << time_on << operator_call.toUtf8 () << my_call.toUtf8 () << my_grid.toUtf8 ();
m_->send_message (out, message);
}
}
void MessageClient::logged_ADIF (QByteArray const& ADIF_record)
{
if (m_->server_port_ && !m_->server_string_.isEmpty ())
{
QByteArray message;
NetworkMessage::Builder out {&message, NetworkMessage::LoggedADIF, m_->id_, m_->schema_};
QByteArray ADIF {"\n<adif_ver:5>3.0.7\n<programid:6>WSJT-X\n<EOH>\n" + ADIF_record + " <EOR>"};
out << ADIF;
m_->send_message (out, message);
}
}
+15 -1
View File
@@ -62,13 +62,22 @@ public:
Q_SLOT void qso_logged (QDateTime time_off, QString const& dx_call, QString const& dx_grid
, Frequency dial_frequency, QString const& mode, QString const& report_sent
, QString const& report_received, QString const& tx_power, QString const& comments
, QString const& name, QDateTime time_on);
, QString const& name, QDateTime time_on, QString const& operator_call
, QString const& my_call, QString const& my_grid);
// ADIF_record argument should be valid ADIF excluding any <EOR> end
// of record marker
Q_SLOT void logged_ADIF (QByteArray const& ADIF_record);
// this slot may be used to send arbitrary UDP datagrams to and
// destination allowing the underlying socket to be used for general
// UDP messaging if desired
Q_SLOT void send_raw_datagram (QByteArray const&, QHostAddress const& dest_address, port_type dest_port);
// disallowed message destination (does not block datagrams sent
// with send_raw_datagram() above)
Q_SLOT void add_blocked_destination (QHostAddress const&);
// this signal is emitted if the server sends us a reply, the only
// reply supported is reply to a prior CQ or QRZ message
Q_SIGNAL void reply (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode
@@ -90,6 +99,11 @@ public:
// lookup fails
Q_SIGNAL void error (QString const&) const;
// this signal is emitted if the message obtains a location from a
// server. (It doesn't have to be new, could be a periodic location
// update)
Q_SIGNAL void location (QString const&);
private:
class impl;
pimpl<impl> m_;
+30 -2
View File
@@ -291,14 +291,19 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s
QByteArray comments;
QByteArray name;
QDateTime time_on; // Note: LOTW uses TIME_ON for their +/- 30-minute time window
QByteArray operator_call;
QByteArray my_call;
QByteArray my_grid;
in >> time_off >> dx_call >> dx_grid >> dial_frequency >> mode >> report_sent >> report_received
>> tx_power >> comments >> name >> time_on;
>> tx_power >> comments >> name >> time_on >> operator_call >> my_call >> my_grid;
if (check_status (in) != Fail)
{
Q_EMIT self_->qso_logged (id, time_off, QString::fromUtf8 (dx_call), QString::fromUtf8 (dx_grid)
, dial_frequency, QString::fromUtf8 (mode), QString::fromUtf8 (report_sent)
, QString::fromUtf8 (report_received), QString::fromUtf8 (tx_power)
, QString::fromUtf8 (comments), QString::fromUtf8 (name), time_on);
, QString::fromUtf8 (comments), QString::fromUtf8 (name), time_on
, QString::fromUtf8 (operator_call), QString::fromUtf8 (my_call)
, QString::fromUtf8 (my_grid));
}
}
break;
@@ -308,6 +313,17 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s
clients_.remove (id);
break;
case NetworkMessage::LoggedADIF:
{
QByteArray ADIF;
in >> ADIF;
if (check_status (in) != Fail)
{
Q_EMIT self_->logged_ADIF (id, ADIF);
}
}
break;
default:
// Ignore
break;
@@ -452,3 +468,15 @@ void MessageServer::free_text (QString const& id, QString const& text, bool send
m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_);
}
}
void MessageServer::location (QString const& id, QString const& loc)
{
auto iter = m_->clients_.find (id);
if (iter != std::end (m_->clients_))
{
QByteArray message;
NetworkMessage::Builder out {&message, NetworkMessage::Location, id, (*iter).negotiated_schema_number_};
out << loc.toUtf8 ();
m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_);
}
}
+6 -1
View File
@@ -59,6 +59,9 @@ public:
// message and optionally send it ASAP
Q_SLOT void free_text (QString const& id, QString const& text, bool send);
// ask the client with identification 'id' to set the location provided
Q_SLOT void location (QString const& id, QString const& location);
// the following signals are emitted when a client broadcasts the
// matching message
Q_SIGNAL void client_opened (QString const& id, QString const& version, QString const& revision);
@@ -77,8 +80,10 @@ public:
Q_SIGNAL void qso_logged (QString const& id, QDateTime time_off, QString const& dx_call, QString const& dx_grid
, Frequency dial_frequency, QString const& mode, QString const& report_sent
, QString const& report_received, QString const& tx_power, QString const& comments
, QString const& name, QDateTime time_on);
, QString const& name, QDateTime time_on, QString const& operator_call
, QString const& my_call, QString const& my_grid);
Q_SIGNAL void clear_decodes (QString const& id);
Q_SIGNAL void logged_ADIF (QString const& id, QByteArray const& ADIF);
// this signal is emitted when a network error occurs
Q_SIGNAL void error (QString const&) const;
-1
View File
@@ -24,7 +24,6 @@ namespace
"QRA64",
"FreqCal",
"FT8",
"FT8Free"
};
std::size_t constexpr mode_names_size = sizeof (mode_names) / sizeof (mode_names[0]);
}
-1
View File
@@ -50,7 +50,6 @@ public:
QRA64,
FreqCal,
FT8,
FT8Free,
MODES_END_SENTINAL_AND_COUNT // this must be last
};
Q_ENUM (Mode)
+12 -4
View File
@@ -5,6 +5,7 @@
#include <QDebug>
#include "mainwindow.h"
#include "soundout.h"
#include "commons.h"
#include "moc_Modulator.cpp"
@@ -86,7 +87,8 @@ void Modulator::start (unsigned symbolsLength, double framesPerSymbol,
if(m_bFastMode) m_ic=0;
m_silentFrames = 0;
// calculate number of silent frames to send
// calculate number of silent frames to send, so that audio will start at
// the nominal time "delay_ms" into the Tx sequence.
if (synchronize && !m_tuning && !m_bFastMode) {
m_silentFrames = m_ic + m_frameRate / (1000 / delay_ms) - (mstr * (m_frameRate / 1000));
}
@@ -168,6 +170,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
case Active:
{
unsigned int isym=0;
// qDebug() << "Mod A" << m_toneSpacing << m_ic;
if(!m_tuning) isym=m_ic/(4.0*m_nsps); // Actual fsample=48000
bool slowCwId=((isym >= m_symbolsLength) && (icw[0] > 0)) && (!m_bFastMode);
if(m_TRperiod==3) slowCwId=false;
@@ -248,7 +251,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
i0=i1-816;
}
qint16 sample;
for (unsigned i = 0; i < numFrames && m_ic <= i1; ++i) {
isym=0;
if(!m_tuning and m_TRperiod!=3) isym=m_ic / (4.0 * m_nsps); //Actual
@@ -264,7 +267,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
m_toneFrequency0=m_frequency + itone[isym]*m_toneSpacing;
}
}
// qDebug() << "B" << m_bFastMode << m_ic << numFrames << isym << itone[isym]
// qDebug() << "Mod B" << m_bFastMode << m_ic << numFrames << isym << itone[isym]
// << m_toneFrequency0 << m_nsps;
m_dphi = m_twoPi * m_toneFrequency0 / m_frameRate;
m_isym0 = isym;
@@ -285,7 +288,12 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
if (m_ic > i0) m_amp = 0.98 * m_amp;
if (m_ic > i1) m_amp = 0.0;
samples = load (postProcessSample (m_amp * qSin (m_phi)), samples);
sample=qRound(m_amp*qSin(m_phi));
if(m_toneSpacing < 0) sample=qRound(m_amp*foxcom_.wave[m_ic]);
// if(m_ic < 100) qDebug() << "Mod C" << m_ic << m_amp << foxcom_.wave[m_ic] << sample;
samples = load(postProcessSample(sample), samples);
++framesGenerated;
++m_ic;
}
+1 -1
View File
@@ -31,7 +31,7 @@ public:
double frequency () const {return m_frequency;}
bool isActive () const {return m_state != Idle;}
void setSpread(double s) {m_fSpread=s;}
void setPeriod(unsigned p) {m_period=p;}
void setTRPeriod(unsigned p) {m_period=p;}
void set_nsym(int n) {m_symbolsLength=n;}
Q_SLOT void start (unsigned symbolsLength, double framesPerSymbol, double frequency,
+44 -1
View File
@@ -229,7 +229,7 @@
* Date & Time Off QDateTime
* DX call utf8
* DX grid utf8
* Dial frequency (Hz) quint64
* Tx frequency (Hz) quint64
* Mode utf8
* Report send utf8
* Report received utf8
@@ -237,6 +237,9 @@
* Comments utf8
* Name utf8
* Date & Time On QDateTime
* Operator call utf8
* My call utf8
* My grid utf8
*
* The QSO logged message is sent to the server(s) when the
* WSJT-X user accepts the "Log QSO" dialog by clicking the "OK"
@@ -304,6 +307,7 @@
* command to determine the contents of the current free text
* message.
*
*
* WSPRDecode Out 10 quint32
* Id (unique key) utf8
* New bool
@@ -327,6 +331,43 @@
* from a played back recording.
*
*
* Location In 11
* Id (unique key) utf8
* Location utf8
*
* This message allows the server to set the current current
* geographical location of operation. The supplied location is
* not persistent but is used as a session lifetime replacement
* loction that overrides the Maidenhead grid locater set in the
* application settings. The intent is to allow an external
* application to update the operating location dynamically
* during a mobile period of operation.
*
* Currently only Maidenhead grid squares or sub-squares are
* accepted, i.e. 4- or 6-digit locators. Other formats may be
* accepted in future.
*
*
* Logged ADIF Out 12 quint32
* Id (unique key) utf8
* ADIF text ASCII (serialized like utf8)
*
* The logged ADIF message is sent to the server(s) when the
* WSJT-X user accepts the "Log QSO" dialog by clicking the "OK"
* button. The "ADIF text" field consists of a valid ADIF file
* such that the WSJT-X UDP header information is encapsulated
* into a valid ADIF header. E.g.:
*
* <magic-number><schema-number><type><id><32-bit-count> # binary encoded fields
* # the remainder is the contents of the ADIF text field
* <adif_ver:5>3.0.7
* <programid:6>WSJT-X
* <EOH>
* ADIF log data fields ...<EOR>
*
* Note that receiving applications can treat the whole message
* as a valid ADIF file with one record without special parsing.
*
*/
#include <QDataStream>
@@ -353,6 +394,8 @@ namespace NetworkMessage
HaltTx,
FreeText,
WSPRDecode,
Location,
LoggedADIF,
maximum_message_type_ // ONLY add new message types
// immediately before here
};
+61 -5
View File
@@ -1,9 +1,65 @@
0; 0; 0
0; 0; 87
0; 79;114
0;141; 61
96;158; 0
0; 0; 9
0; 0; 21
0; 0; 34
0; 0; 45
0; 0; 57
0; 0; 67
0; 0; 77
0; 0; 86
0; 0; 94
0; 12;101
0; 23;106
0; 35;110
0; 46;113
0; 57;115
0; 68;115
0; 78;114
0; 88;112
0; 97;108
0;106;103
0;114; 97
0;122; 90
0;129; 81
0;136; 72
0;141; 62
0;146; 51
0;151; 39
11;154; 27
29;157; 15
46;158; 2
63;159; 0
79;159; 0
96;159; 0
111;157; 0
127;155; 0
142;152; 0
156;148; 0
169;143; 0
182;138; 0
193;131; 0
204;124; 0
253; 50; 17
214;117; 0
223;109; 0
231;100; 0
238; 91; 0
244; 81; 0
248; 71; 0
252; 60; 5
254; 50; 19
255; 38; 33
255; 47; 47
255; 61; 61
255; 75; 75
255; 90; 90
255;105;105
255;121;121
255;138;138
255;156;156
255;175;175
255;196;196
255;218;218
255;243;243
255;255;255
255;255;255
255;255;255
+301
View File
@@ -0,0 +1,301 @@
__ __ ______ _____ ________ __ __
| \ _ | \ / \ | \| \ | \ | \
| $$ / \ | $$| $$$$$$\ \$$$$$ \$$$$$$$$ | $$ | $$
| $$/ $\| $$| $$___\$$ | $$ | $$ ______ \$$\/ $$
| $$ $$$\ $$ \$$ \ __ | $$ | $$| \ >$$ $$
| $$ $$\$$\$$ _\$$$$$$\| \ | $$ | $$ \$$$$$$/ $$$$\
| $$$$ \$$$$| \__| $$| $$__| $$ | $$ | $$ \$$\
| $$$ \$$$ \$$ $$ \$$ $$ | $$ | $$ | $$
\$$ \$$ \$$$$$$ \$$$$$$ \$$ \$$ \$$
Copyright 2001 - 2018 by Joe Taylor, K1JT.
Release: WSJT-X Version 1.9.0-rc2
February 26, 2018
---------------------------------
Changes from WSJT-X Version 1.8.0 include the following:
- New FT8 DXpedition Mode to facilitate high QSO rates in pileup
situations
- Decoding improvements for JT65 mode, including a priori (AP)
decoding when VHF/UHF/Microwave features are enabled
- Optional Auto-Sequencing in JT4, JT9, and JT65 when
VHF/UHF/Microwave features are enabled
- Better suppression of low-confidence false decodes generated by AP
decoding in FT8 mode
- Improved decoding performance for WSPR mode, especially effective at
LF and MF
- Minor adjustments to auto-sequencing behavior
- More flexible Doppler control features for EME
- Improved waterfall sensitivity for very weak signals
- Automatic real-time forwarding of logged information to N1MM Logger+
- Expanded and improved UDP messages sent to companion programs
- Bug fixes and other minor tweaks to user interface
A primary purpose of this beta release is to allow field testing of
FT8 DXpedition Mode. Instructions for this mode are posted here:
http://physics.princeton.edu/pulsar/k1jt/FT8_DXpedition_Mode.pdf
Contacts in FT8 DXpedition Mode must use WSJT-X v1.9.0 at both ends of
the QSO. Please report any anomalous behavior to email list
wsjt-devel@lists.sourceforge.net. You must be a subscriber in order
to post there.
Release: WSJT-X Version 1.8.0
October 27, 2017
-----------------------------
This is the full General Availability release of WSJT-X Version 1.8.0.
Changes from WSJT-X Version 1.8.0-rc3 are very minor:
- Right-click on the Wide Graph now pops up a Context Menu. Select
the item *Set Rx & Tx Offset* to complete a one-handed setting of
both red and green frequency markers.
- Several clarifications and additions to Tool Tips and the User Guide.
We recommend that all users should upgrade to WSJT-X Version 1.8.0.
If you upgrade from v1.8.0-rc1 it may be necessary to do a one-time
reset of the default list of suggested operating frequencies. Go to
*File->Settings->Frequencies*, right click on the table and select
*Reset*.
Release: WSJT-X Version 1.8.0-rc3
October 16, 2017
---------------------------------
Most (but not all) changes since Version 1.8.0-rc2 involve user
control of the increasingly popular FT8 mode. The "RC3" release also
includes minor bug fixes and updates to the WSJT-X User Guide.
The following list includes all of the more important changes:
- New optimization of GUI for simplex and split behavior in FT8 mode.
1. Checkbox "Lock Tx Freq" on main window is relabeled "Hold Tx Freq".
2. Double-clicking on decoded messages that do not contain your own
call moves both Rx and Tx frequencies. If the first callsign is
your own call, only Rx freq moves.
3. Double-clicking on decoded messages moves the Rx frequency. If
"Hold Tx Freq" is checked, Tx frequency is moved only if CTRL was
held down.
4. Clicking on the waterfall moves Rx and Tx frequencies as
before: Rx only on a simple click, Tx only on SHIFT-click, and
both on CTRL-click. This happens even if "Hold Tx Freq" is
checked.
- Add a semi-automated "FreqCal" procedure: see *Solve for calibration
parameters* on the Tools menu.
- Improv auto-sequencing behavior: stop and on-frequency
transmission if a called station comes back to someone else.
- Improve S/N estimation in some situations involving QRM.
- Fix an initialization issue with user-modified application fonts.
- Fix an issue with Tx5 message generation with Type 2 compound calls.
- Enhance and improve the ADIF parser of logbook records. Update
the band limits as per ADIF 3.0.6 specification.
- Increase the FT8 DT range to +/- 2.5 s.
- Do not allow window manager events to close the astronomical data
window.
- Add an "Erase" item to the context (right-click) menu for decoded
text.
- Extend UDP messages with an "off air" boolean field indicating that
the decode was derived from a .WAV file playback rather than an on air
reception.
- Extend reference applications to use the new off air decode message
field.
- Improve performance of FT8 decoder, especially for overlapping
signals.
- Allow specialized use of "x2 Tone Spacing" in FT8 and slow JT9
modes.
- Move "NA VHF Contest Mode" checkbox to main screen. Query the
operator if d > 10000 km.
- Adjust UI to improve portability with font size changes and between
platforms.
- Extend UDP Reply message to support keyboard modifiers. This allows
UDP servers to emulate keyboard modified double-clicks on decoded
messages, e.g. ALT+double-click for replying to a CQ or QRZ call
without changing ones Tx frequency offset.
- Update the cty.dat file (21st Sept 2017).
- Ensure that Fast Graph is properly initialized.
- Better handling of worked before and country name display. Appended
text is added at a fixed column unless the message overlaps in which
case the appended information floats to the right.
- Restore printing of MSK144 decode quality information.
- Display Echo Graph automatically when Echo mode is started.
- Fix a bug that prevented double-click on a JT65 EME-style "OOO"
message from populating the Tx message boxes.
- Fixed behavior with double-click on 'CQ <AA-ZZ> <call> <grid>.'
- Update the "blank line" divider with band ID at 4*TRperiod/5.
- Fix cty.dat lookups that were not honouring exact match flags
- Add some further Copyright protections.
- Fix a bug involving "firstcall contains mycall" but not equal to mycall.
- Fix an issue with editing IARU regions in the working frequencies table.
Release: WSJT-X Version 1.8.0-rc2
September 2, 2017
---------------------------------
Implementation of FT8 and its auto-sequencing feature is now more
capable and more polished. The decoder is faster and better: it now
includes signal subtraction, multi-pass decoding, and the use of
accumulated "a priori" information as a QSO progresses. Sensitivity
extends downward as far as -24 dB in some circumstances. Overlapping
signals 2 and 3 deep are frequently decoded at essentially the same
frequency. On a crowded band we sometimes see more than 30 decodes in
a single 15-second interval, over a 2 kHz window. The North American
VHF Contesting Mode has been extended to include both FT8 and MSK144
modes.
The "RC2" release also includes many minor bug fixes and an
extensively updated WSJT-X User Guide.
Depending on what code revision you upgrade from, it may be necessary
to do a one-time reset of the default list of suggested operating
frequencies. Go to *File->Settings->Frequencies*, right click on
the table and select *Reset*.
Release: WSJT-X Version 1.8.0
-----------------------------
NEW FEATURES IN WSJT-X Version 1.8.0
------------------------------------
1. New mode called FT8: sensitivity down to -20 dB on the AWGN
channel; QSOs 4 times faster than JT65 or JT9; auto-sequencing
includes an option to respond automatically to first decoded
reply to your CQ.
2. New mode for accurate Frequency Calibration of your radio.
3. Improved performance of decoders for JT65, QRA64, and MSK144.
MSK144 includes facilities for amplitide and phase equalization
and an "SWL" mode for short-format messages.
4. Options to minimize screen space used by Main and Wide Graph
windows.
5. Enhanced management scheme for table of operating frequencies, and
a new set of default frequencies specific to the three IARU
Regions.
6. Improved CAT control for many rigs, including those controlled
through Commander or OmniRig.
7. New keyboard shortcuts to set "Tx even/1st" ON or OFF.
8. A number of (mostly minor) bug fixes and tweaks to the user
interface. For example: new behavior for the audio level slider;
correctly logged QSO start times in certain situations; correct
control of FT-891/991 and some other radios via rigctld.
At the time of the v1.8.0-rc1 release the following tasks are yet to
be completed:
1. Updates to WSJT-X User Guide.
2. Sample files for FT8.
3. Enhanced decoding using AP ("a priori") information.
4. Signal subtraction and multi-pass decoding.
5. Option to Auto-respond to the weakest responder to your CQ.
Installation packages for Windows, Linux, OS X, and Raspbian can be
downloaded from the WSJT web site:
http://physics.princeton.edu/pulsar/K1JT/wsjtx.html
Please send bug reports to either wsjtgroup@yahoogroups.com or
wsjt-devel@lists.sourceforge.net. Such reports should include a full
prescription of steps to reproduce the undesired behavior. You must
be a subscriber to post to either of these lists.
Brief Description of the FT8 Protocol
-------------------------------------
WSJT-X Version 1.8.0 includes a new mode called FT8, developed by K9AN
and K1JT. The mode name "FT8" stands for "Franke and Taylor, 8-FSK
modulation". FT8 uses 15-second T/R sequences and provides 50% or
better decoding probability down to -20 dB on an AWGN channel. An
auto-sequencing facility includes an option to respond automatically
to the first decoded reply to your CQ. FT8 QSOs are 4 times faster
than those made with JT65 or JT9. FT8 is an excellent mode for HF
DXing and for situations like multi-hop E_s on 6 meters, where deep
QSB may make fast and reliable completion of QSOs desirable.
Some important characteristics of FT8:
- T/R sequence length: 15 s
- Message length: 75 bits + 12-bit CRC
- FEC code: LDPC(174,87)
- Modulation: 8-FSK, tone spacing 6.25 Hz
- Constant-envelope waveform
- Occupied bandwidth: 50 Hz
- Synchronization: 7x7 Costas arrays at start, middle, and end
- Transmission duration: 79*1920/12000 = 12.64 s
- Decoding threshold: -20 dB; several dB lower with AP decoding
- Multi-decoder finds and decodes all FT8 signals in passband
- Optional auto-sequencing and auto-reply to a CQ response
- Operational behavior similar to JT9, JT65
We plan to implement signal subtraction, two-pass decoding, and use of
a priori (AP) information in the decoder. These features are not yet
activated in v1.8.0.
We haven't yet finalized what the three extra bits in the message
payload will be used for. Suggestions are welcome!
-- Joe, K1JT, for the WSJT Development Team
+13 -1
View File
@@ -3,6 +3,8 @@
#include <QRegExp>
#include <QColor>
#include "MaidenheadLocatorValidator.hpp"
namespace
{
//QRegExp message_alphabet {"[- A-Za-z0-9+./?]*"};
@@ -120,9 +122,11 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
, decodes_table_view_ {new QTableView}
, beacons_table_view_ {new QTableView}
, message_line_edit_ {new QLineEdit}
, grid_line_edit_ {new QLineEdit}
, decodes_stack_ {new QStackedLayout}
, auto_off_button_ {new QPushButton {tr ("&Auto Off")}}
, halt_tx_button_ {new QPushButton {tr ("&Halt Tx")}}
, de_label_ {new QLabel}
, mode_label_ {new QLabel}
, fast_mode_ {false}
, frequency_label_ {new QLabel}
@@ -141,13 +145,18 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
auto form_layout = new QFormLayout;
form_layout->addRow (tr ("Free text:"), message_line_edit_);
form_layout->addRow (tr ("Temporary grid:"), grid_line_edit_);
message_line_edit_->setValidator (new QRegExpValidator {message_alphabet, this});
grid_line_edit_->setValidator (new MaidenheadLocatorValidator {this});
connect (message_line_edit_, &QLineEdit::textEdited, [this] (QString const& text) {
Q_EMIT do_free_text (id_, text, false);
});
connect (message_line_edit_, &QLineEdit::editingFinished, [this] () {
Q_EMIT do_free_text (id_, message_line_edit_->text (), true);
});
connect (grid_line_edit_, &QLineEdit::editingFinished, [this] () {
Q_EMIT location (id_, grid_line_edit_->text ());
});
auto decodes_page = new QWidget;
auto decodes_layout = new QVBoxLayout {decodes_page};
@@ -189,6 +198,7 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
// set up status area
auto status_bar = new QStatusBar;
status_bar->addPermanentWidget (de_label_);
status_bar->addPermanentWidget (mode_label_);
status_bar->addPermanentWidget (frequency_label_);
status_bar->addPermanentWidget (dx_label_);
@@ -216,7 +226,7 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod
void ClientWidget::update_status (QString const& id, Frequency f, QString const& mode, QString const& dx_call
, QString const& report, QString const& tx_mode, bool tx_enabled
, bool transmitting, bool decoding, qint32 rx_df, qint32 tx_df
, QString const& de_call, QString const& /*de_grid*/, QString const& dx_grid
, QString const& de_call, QString const& de_grid, QString const& dx_grid
, bool watchdog_timeout, QString const& sub_mode, bool fast_mode)
{
if (id == id_)
@@ -224,6 +234,8 @@ void ClientWidget::update_status (QString const& id, Frequency f, QString const&
fast_mode_ = fast_mode;
decodes_proxy_model_.de_call (de_call);
decodes_proxy_model_.rx_df (rx_df);
de_label_->setText (de_call.size () >= 0 ? QString {"DE: %1%2"}.arg (de_call)
.arg (de_grid.size () ? '(' + de_grid + ')' : QString {}) : QString {});
mode_label_->setText (QString {"Mode: %1%2%3%4"}
.arg (mode)
.arg (sub_mode)
+3
View File
@@ -43,6 +43,7 @@ public:
Q_SIGNAL void do_reply (QModelIndex const&, quint8 modifier);
Q_SIGNAL void do_halt_tx (QString const& id, bool auto_only);
Q_SIGNAL void do_free_text (QString const& id, QString const& text, bool);
Q_SIGNAL void location (QString const &id, QString const &text);
private:
QString id_;
@@ -69,9 +70,11 @@ private:
QTableView * decodes_table_view_;
QTableView * beacons_table_view_;
QLineEdit * message_line_edit_;
QLineEdit * grid_line_edit_;
QStackedLayout * decodes_stack_;
QAbstractButton * auto_off_button_;
QAbstractButton * halt_tx_button_;
QLabel * de_label_;
QLabel * mode_label_;
bool fast_mode_;
QLabel * frequency_label_;
+14 -5
View File
@@ -22,12 +22,15 @@ namespace
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Sent"),
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Rec'd"),
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Power"),
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Operator"),
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "My Call"),
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "My Grid"),
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Comments"),
};
}
MessageAggregatorMainWindow::MessageAggregatorMainWindow ()
: log_ {new QStandardItemModel {0, 11, this}}
: log_ {new QStandardItemModel {0, 14, this}}
, decodes_model_ {new DecodesModel {this}}
, beacons_model_ {new BeaconsModel {this}}
, server_ {new MessageServer {this}}
@@ -111,10 +114,12 @@ MessageAggregatorMainWindow::MessageAggregatorMainWindow ()
show ();
}
void MessageAggregatorMainWindow::log_qso (QString const& /*id*/, QDateTime time_off, QString const& dx_call, QString const& dx_grid
, Frequency dial_frequency, QString const& mode, QString const& report_sent
, QString const& report_received, QString const& tx_power, QString const& comments
, QString const& name, QDateTime time_on)
void MessageAggregatorMainWindow::log_qso (QString const& /*id*/, QDateTime time_off, QString const& dx_call
, QString const& dx_grid, Frequency dial_frequency, QString const& mode
, QString const& report_sent, QString const& report_received
, QString const& tx_power, QString const& comments
, QString const& name, QDateTime time_on, QString const& operator_call
, QString const& my_call, QString const& my_grid)
{
QList<QStandardItem *> row;
row << new QStandardItem {time_on.toString ("dd-MMM-yyyy hh:mm:ss")}
@@ -127,6 +132,9 @@ void MessageAggregatorMainWindow::log_qso (QString const& /*id*/, QDateTime time
<< new QStandardItem {report_sent}
<< new QStandardItem {report_received}
<< new QStandardItem {tx_power}
<< new QStandardItem {operator_call}
<< new QStandardItem {my_call}
<< new QStandardItem {my_grid}
<< new QStandardItem {comments};
log_->appendRow (row);
log_table_view_->resizeColumnsToContents ();
@@ -149,6 +157,7 @@ void MessageAggregatorMainWindow::add_client (QString const& id, QString const&
connect (dock, &ClientWidget::do_reply, decodes_model_, &DecodesModel::do_reply);
connect (dock, &ClientWidget::do_halt_tx, server_, &MessageServer::halt_tx);
connect (dock, &ClientWidget::do_free_text, server_, &MessageServer::free_text);
connect (dock, &ClientWidget::location, server_, &MessageServer::location);
connect (view_action, &QAction::toggled, dock, &ClientWidget::setVisible);
dock_widgets_[id] = dock;
server_->replay (id);
+2 -1
View File
@@ -29,7 +29,8 @@ public:
Q_SLOT void log_qso (QString const& /*id*/, QDateTime time_off, QString const& dx_call, QString const& dx_grid
, Frequency dial_frequency, QString const& mode, QString const& report_sent
, QString const& report_received, QString const& tx_power, QString const& comments
, QString const& name, QDateTime time_on);
, QString const& name, QDateTime time_on, QString const& operator_call
, QString const& my_call, QString const& my_grid);
private:
void add_client (QString const& id, QString const& version, QString const& revision);
+34
View File
@@ -95,6 +95,38 @@ public:
}
}
Q_SLOT void qso_logged (QString const&client_id, QDateTime time_off, QString const& dx_call, QString const& dx_grid
, Frequency dial_frequency, QString const& mode, QString const& report_sent
, QString const& report_received, QString const& tx_power
, QString const& comments, QString const& name, QDateTime time_on
, QString const& operator_call, QString const& my_call, QString const& my_grid)
{
if (client_id == id_)
{
qDebug () << "time_on:" << time_on << "time_off:" << time_off << "dx_call:" << dx_call << "grid:" << dx_grid
<< "freq:" << dial_frequency << "mode:" << mode << "rpt_sent:" << report_sent
<< "rpt_rcvd:" << report_received << "Tx_pwr:" << tx_power << "comments:" << comments
<< "name:" << name << "operator_call:" << operator_call << "my_call:" << my_call
<< "my_grid:" << my_grid;
std::cout << QByteArray {80, '-'}.data () << '\n';
std::cout << tr ("%1: Logged %2 grid: %3 power: %4 sent: %5 recd: %6 freq: %7 time_off: %8 op: %9 my_call: %10 my_grid: %11")
.arg (id_).arg (dx_call).arg (dx_grid).arg (tx_power).arg (report_sent).arg (report_received)
.arg (dial_frequency).arg (time_off.toString("yyyy-MM-dd hh:mm:ss.z")).arg (operator_call)
.arg (my_call).arg (my_grid).toStdString ()
<< std::endl;
}
}
Q_SLOT void logged_ADIF (QString const&client_id, QByteArray const& ADIF)
{
if (client_id == id_)
{
qDebug () << "ADIF:" << ADIF;
std::cout << QByteArray {80, '-'}.data () << '\n';
std::cout << ADIF.data () << std::endl;
}
}
private:
QString id_;
Frequency dial_frequency_;
@@ -127,6 +159,8 @@ private:
connect (server_, &MessageServer::status_update, client, &Client::update_status);
connect (server_, &MessageServer::decode, client, &Client::decode_added);
connect (server_, &MessageServer::WSPR_decode, client, &Client::beacon_spot_added);
connect (server_, &MessageServer::qso_logged, client, &Client::qso_logged);
connect (server_, &MessageServer::logged_ADIF, client, &Client::logged_ADIF);
clients_[id] = client;
server_->replay (id);
std::cout << "Discovered WSJT-X instance: " << id.toStdString ();
+3 -3
View File
@@ -1,6 +1,6 @@
# Version number components
set (WSJTX_VERSION_MAJOR 1)
set (WSJTX_VERSION_MINOR 7)
set (WSJTX_VERSION_PATCH 1)
set (WSJTX_VERSION_MAJOR 0)
set (WSJTX_VERSION_MINOR 3)
set (WSJTX_VERSION_PATCH 2)
set (WSJTX_RC 0) # release candidate number, comment out or zero for development versions
set (WSJTX_VERSION_IS_RELEASE 0) # set to 1 for final release build
+1 -1
View File
@@ -18,7 +18,7 @@ CAboutDlg::CAboutDlg(QWidget *parent) :
+ " " + revision ()}.simplified () + "</h2><br />"
"WSJT-X implements a number of digital modes designed for <br />"
"weak-signal Amateur Radio communication. <br /><br />"
"&copy; 2001-2017 by Joe Taylor, K1JT, with grateful <br />"
"&copy; 2001-2018 by Joe Taylor, K1JT, with grateful <br />"
"acknowledgment for contributions from AC6SL, AE4JY, <br />"
"DJ0OT, G3WDG, G4KLA, G4WJS, IV3NWV, IW3RAB, K3WYC, K9AN, <br />"
"KA6MAL, KA9Q, KB1ZMX, KD6EKQ, KI7MT, KK1D, ND0B, PY2SDR, <br />"
+81 -21
View File
@@ -29,7 +29,7 @@ extern "C" {
double* ramoon, double* decmoon, double* dgrd, double* poloffset,
double* xnr, double* techo, double* width1, double* width2,
bool* bTx, const char* AzElFileName, const char* jpleph,
int len1, int len2, int len3, int len4);
fortran_charlen_t, fortran_charlen_t, fortran_charlen_t, fortran_charlen_t);
}
Astro::Astro(QSettings * settings, Configuration const * configuration, QWidget * parent)
@@ -38,6 +38,9 @@ Astro::Astro(QSettings * settings, Configuration const * configuration, QWidget
, configuration_ {configuration}
, ui_ {new Ui::Astro}
, m_DopplerMethod {0}
, m_dop {0}
, m_dop00 {0}
, m_dx_two_way_dop {0}
{
ui_->setupUi (this);
setWindowTitle (QApplication::applicationName () + " - " + tr ("Astronomical Data"));
@@ -70,7 +73,9 @@ void Astro::read_settings ()
case 0: ui_->rbNoDoppler->setChecked (true); break;
case 1: ui_->rbFullTrack->setChecked (true); break;
case 2: ui_->rbConstFreqOnMoon->setChecked (true); break;
case 3: ui_->rbRxOnly->setChecked (true); break;
case 3: ui_->rbOwnEcho->setChecked (true); break;
case 4: ui_->rbOnDxEcho->setChecked (true); break;
case 5: ui_->rbCallDx->setChecked (true); break;
}
move (settings_->value ("window/pos", pos ()).toPoint ());
}
@@ -104,14 +109,15 @@ auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const
double freq8 {static_cast<double> (freq_moon)};
auto const& AzElFileName = QDir::toNativeSeparators (configuration_->azel_directory ().absoluteFilePath ("azel.dat"));
auto const& jpleph = configuration_->data_dir ().absoluteFilePath ("JPLEPH");
int ndop;
int ndop00;
QString mygrid_padded {(mygrid + " ").left (6)};
QString hisgrid_padded {(hisgrid + " ").left (6)};
astrosub_(&nyear, &month, &nday, &uth, &freq8, mygrid_padded.toLatin1().constData(),
hisgrid_padded.toLatin1().constData(), &azsun, &elsun, &azmoon, &elmoon,
&azmoondx, &elmoondx, &ntsky, &ndop, &ndop00, &ramoon, &decmoon,
&azmoondx, &elmoondx, &ntsky, &m_dop, &m_dop00, &ramoon, &decmoon,
&dgrd, &poloffset, &xnr, &techo, &width1, &width2, &bTx,
AzElFileName.toLatin1().constData(), jpleph.toLatin1().constData(), 6, 6,
AzElFileName.length(), jpleph.length());
@@ -119,7 +125,7 @@ auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const
if(hisgrid_padded==" ") {
azmoondx=0.0;
elmoondx=0.0;
ndop=0;
m_dop=0;
width2=0.0;
}
QString message;
@@ -132,14 +138,14 @@ auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const
<< qSetRealNumberPrecision (1)
<< "Az: " << azmoon << "\n"
"El: " << elmoon << "\n"
"SelfDop:" << ndop00 << "\n"
"SelfDop:" << m_dop00 << "\n"
"Width: " << int(width1) << "\n"
<< qSetRealNumberPrecision (2)
<< "Delay: " << techo << "\n"
<< qSetRealNumberPrecision (1)
<< "DxAz: " << azmoondx << "\n"
"DxEl: " << elmoondx << "\n"
"DxDop: " << ndop << "\n"
"DxDop: " << m_dop << "\n"
"DxWid: " << int(width2) << "\n"
"Dec: " << decmoon << "\n"
"SunAz: " << azsun << "\n"
@@ -159,24 +165,48 @@ auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const
switch (m_DopplerMethod)
{
case 1: // All Doppler correction done here; DX station stays at nominal dial frequency.
correction.rx = m_dop;
break;
case 4: // All Doppler correction done here; DX station stays at nominal dial frequency. (Trial for OnDxEcho)
correction.rx = m_dop;
break;
//case 5: // All Doppler correction done here; DX station stays at nominal dial frequency.
case 3: // Both stations do full correction on Rx and none on Tx
correction.rx = dx_is_self ? ndop00 : ndop;
//correction.rx = dx_is_self ? m_dop00 : m_dop;
correction.rx = m_dop00; // Now always sets RX to *own* echo freq
break;
case 2:
case 2:
// Doppler correction to constant frequency on Moon
correction.rx = ndop00 / 2;
correction.rx = m_dop00 / 2;
break;
}
if (3 != m_DopplerMethod) correction.tx = -correction.rx;
switch (m_DopplerMethod)
{
case 1: correction.tx = -correction.rx;
break;
case 2: correction.tx = -correction.rx;
break;
case 3: correction.tx = 0;
break;
case 4: // correction.tx = m_dop - m_dop00;
correction.tx = m_dx_two_way_dop - m_dop;
qDebug () << "correction.tx:" << correction.tx;
break;
case 5: correction.tx = - m_dop00;
break;
}
//if (3 != m_DopplerMethod || 4 != m_DopplerMethod) correction.tx = -correction.rx;
if(dx_is_self && m_DopplerMethod == 1) correction.rx = 0;
if (no_tx_QSY && 3 != m_DopplerMethod && 0 != m_DopplerMethod)
{
// calculate a single correction for transmit half way through
// the period as a compromise for rigs that can't CAT QSY
// while transmitting
// calculate a single correction for transmit half way through
// the period as a compromise for rigs that can't CAT QSY
// while transmitting
//
// use a base time of (secs-since-epoch + 2) so as to be sure
// we do the next period if we calculate just before it starts
@@ -194,7 +224,7 @@ auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const
double uth {nhr + nmin/60.0 + sec/3600.0};
astrosub_(&nyear, &month, &nday, &uth, &freq8, mygrid_padded.toLatin1().constData(),
hisgrid_padded.toLatin1().constData(), &azsun, &elsun, &azmoon, &elmoon,
&azmoondx, &elmoondx, &ntsky, &ndop, &ndop00, &ramoon, &decmoon,
&azmoondx, &elmoondx, &ntsky, &m_dop, &m_dop00, &ramoon, &decmoon,
&dgrd, &poloffset, &xnr, &techo, &width1, &width2, &bTx,
"", jpleph.toLatin1().constData(), 6, 6,
0, jpleph.length());
@@ -203,15 +233,27 @@ auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const
{
case 1:
// All Doppler correction done here; DX station stays at nominal dial frequency.
offset = dx_is_self ? ndop00 : ndop;
offset = dx_is_self ? m_dop00 : m_dop;
break;
case 2:
// Doppler correction to constant frequency on Moon
offset = ndop00 / 2;
offset = m_dop00 / 2;
break;
case 4:
// Doppler correction for OnDxEcho
offset = m_dop - m_dx_two_way_dop;
break;
//case 5: correction.tx = - m_dop00;
case 5: offset = m_dop00;// version for _7
break;
}
correction.tx = -offset;
qDebug () << "correction.tx (no tx qsy):" << correction.tx;
}
}
return correction;
@@ -235,13 +277,31 @@ void Astro::on_rbFullTrack_clicked()
Q_EMIT tracking_update ();
}
void Astro::on_rbRxOnly_clicked()
void Astro::on_rbOnDxEcho_clicked(bool checked)
{
m_DopplerMethod = 4;
check_split ();
if (checked) {
m_dx_two_way_dop = 2 * (m_dop - (m_dop00/2));
qDebug () << "Starting Doppler:" << m_dx_two_way_dop;
}
Q_EMIT tracking_update ();
}
void Astro::on_rbOwnEcho_clicked()
{
m_DopplerMethod = 3;
check_split ();
Q_EMIT tracking_update ();
}
void Astro::on_rbCallDx_clicked()
{
m_DopplerMethod = 5;
check_split ();
Q_EMIT tracking_update ();
}
void Astro::on_rbConstFreqOnMoon_clicked()
{
m_DopplerMethod = 2;
+6 -1
View File
@@ -57,8 +57,10 @@ protected:
private slots:
void on_rbConstFreqOnMoon_clicked();
void on_rbFullTrack_clicked();
void on_rbRxOnly_clicked();
void on_rbOwnEcho_clicked();
void on_rbNoDoppler_clicked();
void on_rbOnDxEcho_clicked(bool);
void on_rbCallDx_clicked();
void on_cbDopplerTracking_toggled(bool);
private:
@@ -71,6 +73,9 @@ private:
QScopedPointer<Ui::Astro> ui_;
qint32 m_DopplerMethod;
int m_dop;
int m_dop00;
int m_dx_two_way_dop;
};
inline
+30 -4
View File
@@ -48,12 +48,12 @@
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbRxOnly">
<widget class="QRadioButton" name="rbOwnEcho">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Both stations do full correction to their QSO partner's grid square during receive, no correction is applied on transmit.&lt;/p&gt;&lt;p&gt;This mode facilitates accurate Doppler shift correction when one or both stations have a rig that does not accept CAT QSY commands while transmitting.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Transmit takes place on sked frequency and receive frequency is corrected for own echoes. &lt;/p&gt;&lt;p&gt;This mode can be used for calling CQ, or when using Echo mode.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Receive only</string>
<string>Own Echo</string>
</property>
</widget>
</item>
@@ -70,6 +70,32 @@
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbOnDxEcho">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;DX station announces their TX Freq, which is entered as the Sked Freq. Correction applied to RX and TX so you appear on the DX's station's own echo Freq.&lt;/p&gt;&lt;p&gt;If the rig does not accept CAT QSY commands while transmitting a single correction is applied for the whole transmit period.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>On DX Echo</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbCallDx">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Tune radio manually and select this mode to put your echo on the same frequency.&lt;/p&gt;&lt;p&gt;If the rig does not accept CAT QSY commands while transmitting a single correction is applied for the whole transmit period.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Call DX</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbNoDoppler">
<property name="toolTip">
@@ -83,7 +109,7 @@
</property>
</widget>
</item>
</layout>
</layout>
</widget>
</item>
<item>
+8
View File
@@ -0,0 +1,8 @@
See ./index.html for information about this release. The "Getting Started"
section is a useful starting place.
---------------------------
Copyright Beman Dawes, 2008
Distributed under the Boost Software License, Version 1.0.
See ./LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt
+312
View File
@@ -0,0 +1,312 @@
# Copyright Vladimir Prus 2002-2006.
# Copyright Dave Abrahams 2005-2006.
# Copyright Rene Rivera 2005-2007.
# Copyright Douglas Gregor 2005.
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
# Usage:
#
# b2 [options] [properties] [install|stage]
#
# Builds and installs Boost.
#
# Targets and Related Options:
#
# install Install headers and compiled library files to the
# ======= configured locations (below).
#
# --prefix=<PREFIX> Install architecture independent files here.
# Default; C:\Boost on Win32
# Default; /usr/local on Unix. Linux, etc.
#
# --exec-prefix=<EPREFIX> Install architecture dependent files here.
# Default; <PREFIX>
#
# --libdir=<DIR> Install library files here.
# Default; <EPREFIX>/lib
#
# --includedir=<HDRDIR> Install header files here.
# Default; <PREFIX>/include
#
# stage Build and install only compiled library files to the
# ===== stage directory.
#
# --stagedir=<STAGEDIR> Install library files here
# Default; ./stage
#
# Other Options:
#
# --build-type=<type> Build the specified pre-defined set of variations of
# the libraries. Note, that which variants get built
# depends on what each library supports.
#
# -- minimal -- (default) Builds a minimal set of
# variants. On Windows, these are static
# multithreaded libraries in debug and release
# modes, using shared runtime. On Linux, these are
# static and shared multithreaded libraries in
# release mode.
#
# -- complete -- Build all possible variations.
#
# --build-dir=DIR Build in this location instead of building within
# the distribution tree. Recommended!
#
# --show-libraries Display the list of Boost libraries that require
# build and installation steps, and then exit.
#
# --layout=<layout> Determine whether to choose library names and header
# locations such that multiple versions of Boost or
# multiple compilers can be used on the same system.
#
# -- versioned -- Names of boost binaries include
# the Boost version number, name and version of
# the compiler and encoded build properties. Boost
# headers are installed in a subdirectory of
# <HDRDIR> whose name contains the Boost version
# number.
#
# -- tagged -- Names of boost binaries include the
# encoded build properties such as variant and
# threading, but do not including compiler name
# and version, or Boost version. This option is
# useful if you build several variants of Boost,
# using the same compiler.
#
# -- system -- Binaries names do not include the
# Boost version number or the name and version
# number of the compiler. Boost headers are
# installed directly into <HDRDIR>. This option is
# intended for system integrators building
# distribution packages.
#
# The default value is 'versioned' on Windows, and
# 'system' on Unix.
#
# --buildid=ID Add the specified ID to the name of built libraries.
# The default is to not add anything.
#
# --python-buildid=ID Add the specified ID to the name of built libraries
# that depend on Python. The default is to not add
# anything. This ID is added in addition to --buildid.
#
# --help This message.
#
# --with-<library> Build and install the specified <library>. If this
# option is used, only libraries specified using this
# option will be built.
#
# --without-<library> Do not build, stage, or install the specified
# <library>. By default, all libraries are built.
#
# Properties:
#
# toolset=toolset Indicate the toolset to build with.
#
# variant=debug|release Select the build variant
#
# link=static|shared Whether to build static or shared libraries
#
# threading=single|multi Whether to build single or multithreaded binaries
#
# runtime-link=static|shared
# Whether to link to static or shared C and C++
# runtime.
#
# TODO:
# - handle boost version
# - handle python options such as pydebug
import boostcpp ;
import package ;
import sequence ;
import xsltproc ;
import set ;
import path ;
import link ;
path-constant BOOST_ROOT : . ;
constant BOOST_VERSION : 1.63.0 ;
constant BOOST_JAMROOT_MODULE : $(__name__) ;
boostcpp.set-version $(BOOST_VERSION) ;
use-project /boost/architecture : libs/config/checks/architecture ;
local all-headers =
[ MATCH .*libs/(.*)/include/boost : [ glob libs/*/include/boost libs/*/*/include/boost ] ] ;
for dir in $(all-headers)
{
link-directory $(dir)-headers : libs/$(dir)/include/boost : <location>. ;
explicit $(dir)-headers ;
}
if $(all-headers)
{
constant BOOST_MODULARLAYOUT : $(all-headers) ;
}
project boost
: requirements <include>.
[ boostcpp.architecture ]
[ boostcpp.address-model ]
# Disable auto-linking for all targets here, primarily because it caused
# troubles with V2.
<define>BOOST_ALL_NO_LIB=1
# Used to encode variant in target name. See the 'tag' rule below.
<tag>@$(__name__).tag
<conditional>@handle-static-runtime
# Comeau does not support shared lib
<toolset>como:<link>static
<toolset>como-linux:<define>_GNU_SOURCE=1
# When building docs within Boost, we want the standard Boost style
<xsl:param>boost.defaults=Boost
: usage-requirements <include>.
: build-dir bin.v2
;
# This rule is called by Boost.Build to determine the name of target. We use it
# to encode the build variant, compiler name and boost version in the target
# name.
#
rule tag ( name : type ? : property-set )
{
return [ boostcpp.tag $(name) : $(type) : $(property-set) ] ;
}
rule python-tag ( name : type ? : property-set )
{
return [ boostcpp.python-tag $(name) : $(type) : $(property-set) ] ;
}
rule handle-static-runtime ( properties * )
{
# Using static runtime with shared libraries is impossible on Linux, and
# dangerous on Windows. Therefore, we disallow it. This might be drastic,
# but it was disabled for a while without anybody complaining.
# For CW, static runtime is needed so that std::locale works.
if <link>shared in $(properties) && <runtime-link>static in $(properties) &&
! ( <toolset>cw in $(properties) )
{
ECHO "error: link=shared together with runtime-link=static is not allowed" ;
ECHO "error: such property combination is either impossible " ;
ECHO "error: or too dangerious to be of any use" ;
EXIT ;
}
}
all-libraries = [ MATCH .*libs/(.*)/build/.* : [ glob libs/*/build/Jamfile.v2 ]
[ glob libs/*/build/Jamfile ] ] ;
all-libraries = [ sequence.unique $(all-libraries) ] ;
# The function_types library has a Jamfile, but it's used for maintenance
# purposes, there's no library to build and install.
all-libraries = [ set.difference $(all-libraries) : function_types ] ;
# Setup convenient aliases for all libraries.
local rule explicit-alias ( id : targets + )
{
alias $(id) : $(targets) ;
explicit $(id) ;
}
# First, the complicated libraries: where the target name in Jamfile is
# different from its directory name.
explicit-alias prg_exec_monitor : libs/test/build//boost_prg_exec_monitor ;
explicit-alias test_exec_monitor : libs/test/build//boost_test_exec_monitor ;
explicit-alias unit_test_framework : libs/test/build//boost_unit_test_framework ;
explicit-alias bgl-vis : libs/graps/build//bgl-vis ;
explicit-alias serialization : libs/serialization/build//boost_serialization ;
explicit-alias wserialization : libs/serialization/build//boost_wserialization ;
for local l in $(all-libraries)
{
if ! $(l) in test graph serialization
{
explicit-alias $(l) : libs/$(l)/build//boost_$(l) ;
}
}
# Log has an additional target
explicit-alias log_setup : libs/log/build//boost_log_setup ;
alias headers : $(all-headers)-headers : : : <include>. ;
explicit headers ;
# Make project ids of all libraries known.
for local l in $(all-libraries)
{
use-project /boost/$(l) : libs/$(l)/build ;
}
if [ path.exists $(BOOST_ROOT)/tools/inspect ]
{
use-project /boost/tools/inspect : tools/inspect/build ;
}
if [ path.exists $(BOOST_ROOT)/libs/wave/tool ]
{
use-project /boost/libs/wave/tool : libs/wave/tool/build ;
}
# This rule should be called from libraries' Jamfiles and will create two
# targets, "install" and "stage", that will install or stage that library. The
# --prefix option is respected, but --with and --without options, naturally, are
# ignored.
#
# - libraries -- list of library targets to install.
#
rule boost-install ( libraries * )
{
package.install install
: <dependency>/boost//install-proper-headers $(install-requirements)
: # No binaries
: $(libraries)
: # No headers, it is handled by the dependency.
;
install stage : $(libraries) : <location>$(BOOST_STAGE_LOCATE) ;
module [ CALLER_MODULE ]
{
explicit stage ;
explicit install ;
}
}
# Creates a library target, adding autolink support and also creates
# stage and install targets via boost-install, above.
rule boost-lib ( name : sources * : requirements * : default-build * : usage-requirements * )
{
name = boost_$(name) ;
autolink = <link>shared:<define>BOOST_$(name:U)_DYN_LINK=1 ;
lib $(name)
: $(sources)
: $(requirements) $(autolink)
: $(default-build)
: $(usage-requirements) $(autolink)
;
boost-install $(name) ;
}
headers =
# The .SUNWCCh files are present in tr1 include directory and have to be
# installed (see http://lists.boost.org/Archives/boost/2007/05/121430.php).
[ path.glob-tree $(BOOST_ROOT)/boost : *.hpp *.ipp *.h *.inc *.SUNWCCh : CVS .svn ]
[ path.glob-tree $(BOOST_ROOT)/boost/compatibility/cpp_c_headers : c* : CVS .svn ]
[ path.glob boost/tr1/tr1 : * : bcc32 sun CVS .svn ]
;
# Declare special top-level targets that build and install the desired variants
# of the libraries.
boostcpp.declare-targets $(all-libraries) : $(headers) ;
+23
View File
@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
+11
View File
@@ -0,0 +1,11 @@
This boost tree is a cut down version of the 1.63.0 source tree built
using the boost bcp utility, invoked thus:
cd <clean-boost-source-tree>
<path-where-bcp-was-built>/bcp iterator range math numeric crc circular_buffer build bootstrap.bat bootstrap.sh boostcpp.jam boost-build.jam <this-directory>
Note that bcp is built from a separate boost source tree to avoid
polluting the clean tree used to extract components from above.
Add other boost libraries as necessary. See the Subversion book for
details on how to maintain 3rd-party vendor content used in a project.
+17
View File
@@ -0,0 +1,17 @@
# Copyright (C) 2002-2003 David Abrahams.
# Copyright (C) 2002-2003 Vladimir Prus.
# Copyright (C) 2003,2007 Rene Rivera.
# Use, modification and distribution are subject to the
# Boost Software License, Version 1.0. (See accompanying file
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# This is the initial file loaded by Boost Jam when run from any Boost library
# folder. It allows us to choose which Boost Build installation to use for
# building Boost libraries. Unless explicitly selected using a command-line
# option, the version included with the Boost library distribution is used (as
# opposed to any other Boost Build version installed on the user's sytem).
BOOST_ROOT = $(.boost-build-file:D) ;
BOOST_BUILD = [ MATCH --boost-build=(.*) : $(ARGV) ] ;
BOOST_BUILD ?= tools/build/src ;
boost-build $(BOOST_BUILD) ;
+66
View File
@@ -0,0 +1,66 @@
/*=============================================================================
Copyright 2002 William E. Kempf
Distributed under the Boost Software License, Version 1.0. (See accompany-
ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
H1
{
FONT-SIZE: 200%;
COLOR: #00008B;
}
H2
{
FONT-SIZE: 150%;
}
H3
{
FONT-SIZE: 125%;
}
H4
{
FONT-SIZE: 108%;
}
BODY
{
FONT-SIZE: 100%;
BACKGROUND-COLOR: #ffffff;
COLOR: #000000;
}
PRE
{
MARGIN-LEFT: 2em;
FONT-FAMILY: Courier,
monospace;
}
CODE
{
FONT-FAMILY: Courier,
monospace;
}
CODE.as_pre
{
white-space: pre;
}
.index
{
TEXT-ALIGN: left;
}
.page-index
{
TEXT-ALIGN: left;
}
.definition
{
TEXT-ALIGN: left;
}
.footnote
{
FONT-SIZE: 66%;
VERTICAL-ALIGN: super;
TEXT-DECORATION: none;
}
.function-semantics
{
CLEAR: left;
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

+62
View File
@@ -0,0 +1,62 @@
// Circular buffer library header file.
// Copyright (c) 2003-2008 Jan Gaspar
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See www.boost.org/libs/circular_buffer for documentation.
#if !defined(BOOST_CIRCULAR_BUFFER_HPP)
#define BOOST_CIRCULAR_BUFFER_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/circular_buffer_fwd.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/static_assert.hpp>
// BOOST_CB_ENABLE_DEBUG: Debug support control.
#if !defined(BOOST_CB_ENABLE_DEBUG)
#define BOOST_CB_ENABLE_DEBUG 0
#endif
// BOOST_CB_ASSERT: Runtime assertion.
#if BOOST_CB_ENABLE_DEBUG
#include <boost/assert.hpp>
#define BOOST_CB_ASSERT(Expr) BOOST_ASSERT(Expr)
#else
#define BOOST_CB_ASSERT(Expr) ((void)0)
#endif
// BOOST_CB_IS_CONVERTIBLE: Check if Iterator::value_type is convertible to Type.
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0550) || BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
#define BOOST_CB_IS_CONVERTIBLE(Iterator, Type) ((void)0)
#else
#include <boost/detail/iterator.hpp>
#include <boost/type_traits/is_convertible.hpp>
#define BOOST_CB_IS_CONVERTIBLE(Iterator, Type) \
BOOST_STATIC_ASSERT((is_convertible<typename detail::iterator_traits<Iterator>::value_type, Type>::value))
#endif
// BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS:
// Check if the STL provides templated iterator constructors for its containers.
#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
#define BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS BOOST_STATIC_ASSERT(false);
#else
#define BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS ((void)0);
#endif
#include <boost/circular_buffer/debug.hpp>
#include <boost/circular_buffer/details.hpp>
#include <boost/circular_buffer/base.hpp>
#include <boost/circular_buffer/space_optimized.hpp>
#undef BOOST_CB_ASSERT_TEMPLATED_ITERATOR_CONSTRUCTORS
#undef BOOST_CB_IS_CONVERTIBLE
#undef BOOST_CB_ASSERT
#endif // #if !defined(BOOST_CIRCULAR_BUFFER_HPP)
File diff suppressed because it is too large Load Diff
+248
View File
@@ -0,0 +1,248 @@
// Debug support for the circular buffer library.
// Copyright (c) 2003-2008 Jan Gaspar
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#if !defined(BOOST_CIRCULAR_BUFFER_DEBUG_HPP)
#define BOOST_CIRCULAR_BUFFER_DEBUG_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#if BOOST_CB_ENABLE_DEBUG
#include <cstring>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std {
using ::memset;
}
#endif
#endif // BOOST_CB_ENABLE_DEBUG
namespace boost {
namespace cb_details {
#if BOOST_CB_ENABLE_DEBUG
// The value the uninitialized memory is filled with.
const int UNINITIALIZED = 0xcc;
template <class T>
inline void do_fill_uninitialized_memory(T* data, std::size_t size_in_bytes) BOOST_NOEXCEPT {
std::memset(static_cast<void*>(data), UNINITIALIZED, size_in_bytes);
}
template <class T>
inline void do_fill_uninitialized_memory(T& /*data*/, std::size_t /*size_in_bytes*/) BOOST_NOEXCEPT {
// Do nothing
}
class debug_iterator_registry;
/*!
\class debug_iterator_base
\brief Registers/unregisters iterators into the registry of valid iterators.
This class is intended to be a base class of an iterator.
*/
class debug_iterator_base {
private:
// Members
//! Iterator registry.
mutable const debug_iterator_registry* m_registry;
//! Next iterator in the iterator chain.
mutable const debug_iterator_base* m_next;
public:
// Construction/destruction
//! Default constructor.
debug_iterator_base();
//! Constructor taking the iterator registry as a parameter.
debug_iterator_base(const debug_iterator_registry* registry);
//! Copy constructor.
debug_iterator_base(const debug_iterator_base& rhs);
//! Destructor.
~debug_iterator_base();
// Methods
//! Assign operator.
debug_iterator_base& operator = (const debug_iterator_base& rhs);
//! Is the iterator valid?
bool is_valid(const debug_iterator_registry* registry) const;
//! Invalidate the iterator.
/*!
\note The method is const in order to invalidate const iterators, too.
*/
void invalidate() const;
//! Return the next iterator in the iterator chain.
const debug_iterator_base* next() const;
//! Set the next iterator in the iterator chain.
/*!
\note The method is const in order to set a next iterator to a const iterator, too.
*/
void set_next(const debug_iterator_base* it) const;
private:
// Helpers
//! Register self as a valid iterator.
void register_self();
//! Unregister self from valid iterators.
void unregister_self();
};
/*!
\class debug_iterator_registry
\brief Registry of valid iterators.
This class is intended to be a base class of a container.
*/
class debug_iterator_registry {
//! Pointer to the chain of valid iterators.
mutable const debug_iterator_base* m_iterators;
public:
// Methods
//! Default constructor.
debug_iterator_registry() : m_iterators(0) {}
//! Register an iterator into the list of valid iterators.
/*!
\note The method is const in order to register iterators into const containers, too.
*/
void register_iterator(const debug_iterator_base* it) const {
it->set_next(m_iterators);
m_iterators = it;
}
//! Unregister an iterator from the list of valid iterators.
/*!
\note The method is const in order to unregister iterators from const containers, too.
*/
void unregister_iterator(const debug_iterator_base* it) const {
const debug_iterator_base* previous = 0;
for (const debug_iterator_base* p = m_iterators; p != it; previous = p, p = p->next()) {}
remove(it, previous);
}
//! Invalidate every iterator pointing to the same element as the iterator passed as a parameter.
template <class Iterator>
void invalidate_iterators(const Iterator& it) {
const debug_iterator_base* previous = 0;
for (const debug_iterator_base* p = m_iterators; p != 0; p = p->next()) {
if (((Iterator*)p)->m_it == it.m_it) {
p->invalidate();
remove(p, previous);
continue;
}
previous = p;
}
}
//! Invalidate all iterators except an iterator poining to the same element as the iterator passed as a parameter.
template <class Iterator>
void invalidate_iterators_except(const Iterator& it) {
const debug_iterator_base* previous = 0;
for (const debug_iterator_base* p = m_iterators; p != 0; p = p->next()) {
if (((Iterator*)p)->m_it != it.m_it) {
p->invalidate();
remove(p, previous);
continue;
}
previous = p;
}
}
//! Invalidate all iterators.
void invalidate_all_iterators() {
for (const debug_iterator_base* p = m_iterators; p != 0; p = p->next())
p->invalidate();
m_iterators = 0;
}
private:
// Helpers
//! Remove the current iterator from the iterator chain.
void remove(const debug_iterator_base* current,
const debug_iterator_base* previous) const {
if (previous == 0)
m_iterators = m_iterators->next();
else
previous->set_next(current->next());
}
};
// Implementation of the debug_iterator_base methods.
inline debug_iterator_base::debug_iterator_base() : m_registry(0), m_next(0) {}
inline debug_iterator_base::debug_iterator_base(const debug_iterator_registry* registry)
: m_registry(registry), m_next(0) {
register_self();
}
inline debug_iterator_base::debug_iterator_base(const debug_iterator_base& rhs)
: m_registry(rhs.m_registry), m_next(0) {
register_self();
}
inline debug_iterator_base::~debug_iterator_base() { unregister_self(); }
inline debug_iterator_base& debug_iterator_base::operator = (const debug_iterator_base& rhs) {
if (m_registry == rhs.m_registry)
return *this;
unregister_self();
m_registry = rhs.m_registry;
register_self();
return *this;
}
inline bool debug_iterator_base::is_valid(const debug_iterator_registry* registry) const {
return m_registry == registry;
}
inline void debug_iterator_base::invalidate() const { m_registry = 0; }
inline const debug_iterator_base* debug_iterator_base::next() const { return m_next; }
inline void debug_iterator_base::set_next(const debug_iterator_base* it) const { m_next = it; }
inline void debug_iterator_base::register_self() {
if (m_registry != 0)
m_registry->register_iterator(this);
}
inline void debug_iterator_base::unregister_self() {
if (m_registry != 0)
m_registry->unregister_iterator(this);
}
#endif // #if BOOST_CB_ENABLE_DEBUG
} // namespace cb_details
} // namespace boost
#endif // #if !defined(BOOST_CIRCULAR_BUFFER_DEBUG_HPP)
+498
View File
@@ -0,0 +1,498 @@
// Helper classes and functions for the circular buffer.
// Copyright (c) 2003-2008 Jan Gaspar
// Copyright (c) 2014 Glen Fernandes // C++11 allocator model support.
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#if !defined(BOOST_CIRCULAR_BUFFER_DETAILS_HPP)
#define BOOST_CIRCULAR_BUFFER_DETAILS_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/throw_exception.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/move/move.hpp>
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
#include <boost/utility/addressof.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <iterator>
// Silence MS /W4 warnings like C4913:
// "user defined binary operator ',' exists but no overload could convert all operands, default built-in binary operator ',' used"
// This might happen when previously including some boost headers that overload the coma operator.
#if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable:4913)
#endif
namespace boost {
namespace cb_details {
template <class Traits> struct nonconst_traits;
template<class ForwardIterator, class Diff, class T, class Alloc>
void uninitialized_fill_n_with_alloc(
ForwardIterator first, Diff n, const T& item, Alloc& alloc);
template<class InputIterator, class ForwardIterator, class Alloc>
ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a);
template<class InputIterator, class ForwardIterator, class Alloc>
ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a);
/*!
\struct const_traits
\brief Defines the data types for a const iterator.
*/
template <class Traits>
struct const_traits {
// Basic types
typedef typename Traits::value_type value_type;
typedef typename Traits::const_pointer pointer;
typedef typename Traits::const_reference reference;
typedef typename Traits::size_type size_type;
typedef typename Traits::difference_type difference_type;
// Non-const traits
typedef nonconst_traits<Traits> nonconst_self;
};
/*!
\struct nonconst_traits
\brief Defines the data types for a non-const iterator.
*/
template <class Traits>
struct nonconst_traits {
// Basic types
typedef typename Traits::value_type value_type;
typedef typename Traits::pointer pointer;
typedef typename Traits::reference reference;
typedef typename Traits::size_type size_type;
typedef typename Traits::difference_type difference_type;
// Non-const traits
typedef nonconst_traits<Traits> nonconst_self;
};
/*!
\struct iterator_wrapper
\brief Helper iterator dereference wrapper.
*/
template <class Iterator>
struct iterator_wrapper {
mutable Iterator m_it;
explicit iterator_wrapper(Iterator it) : m_it(it) {}
Iterator operator () () const { return m_it++; }
private:
iterator_wrapper<Iterator>& operator = (const iterator_wrapper<Iterator>&); // do not generate
};
/*!
\struct item_wrapper
\brief Helper item dereference wrapper.
*/
template <class Pointer, class Value>
struct item_wrapper {
Value m_item;
explicit item_wrapper(Value item) : m_item(item) {}
Pointer operator () () const { return &m_item; }
private:
item_wrapper<Pointer, Value>& operator = (const item_wrapper<Pointer, Value>&); // do not generate
};
/*!
\struct assign_n
\brief Helper functor for assigning n items.
*/
template <class Value, class Alloc>
struct assign_n {
typedef typename boost::container::allocator_traits<Alloc>::size_type size_type;
size_type m_n;
Value m_item;
Alloc& m_alloc;
assign_n(size_type n, Value item, Alloc& alloc) : m_n(n), m_item(item), m_alloc(alloc) {}
template <class Pointer>
void operator () (Pointer p) const {
uninitialized_fill_n_with_alloc(p, m_n, m_item, m_alloc);
}
private:
assign_n<Value, Alloc>& operator = (const assign_n<Value, Alloc>&); // do not generate
};
/*!
\struct assign_range
\brief Helper functor for assigning range of items.
*/
template <class Iterator, class Alloc>
struct assign_range {
Iterator m_first;
Iterator m_last;
Alloc& m_alloc;
assign_range(const Iterator& first, const Iterator& last, Alloc& alloc)
: m_first(first), m_last(last), m_alloc(alloc) {}
template <class Pointer>
void operator () (Pointer p) const {
boost::cb_details::uninitialized_copy(m_first, m_last, p, m_alloc);
}
};
template <class Iterator, class Alloc>
inline assign_range<Iterator, Alloc> make_assign_range(const Iterator& first, const Iterator& last, Alloc& a) {
return assign_range<Iterator, Alloc>(first, last, a);
}
/*!
\class capacity_control
\brief Capacity controller of the space optimized circular buffer.
*/
template <class Size>
class capacity_control {
//! The capacity of the space-optimized circular buffer.
Size m_capacity;
//! The lowest guaranteed or minimum capacity of the adapted space-optimized circular buffer.
Size m_min_capacity;
public:
//! Constructor.
capacity_control(Size buffer_capacity, Size min_buffer_capacity = 0)
: m_capacity(buffer_capacity), m_min_capacity(min_buffer_capacity)
{ // Check for capacity lower than min_capacity.
BOOST_CB_ASSERT(buffer_capacity >= min_buffer_capacity);
}
// Default copy constructor.
// Default assign operator.
//! Get the capacity of the space optimized circular buffer.
Size capacity() const { return m_capacity; }
//! Get the minimal capacity of the space optimized circular buffer.
Size min_capacity() const { return m_min_capacity; }
//! Size operator - returns the capacity of the space optimized circular buffer.
operator Size() const { return m_capacity; }
};
/*!
\struct iterator
\brief Random access iterator for the circular buffer.
\param Buff The type of the underlying circular buffer.
\param Traits Basic iterator types.
\note This iterator is not circular. It was designed
for iterating from begin() to end() of the circular buffer.
*/
template <class Buff, class Traits>
struct iterator :
public std::iterator<
std::random_access_iterator_tag,
typename Traits::value_type,
typename Traits::difference_type,
typename Traits::pointer,
typename Traits::reference>
#if BOOST_CB_ENABLE_DEBUG
, public debug_iterator_base
#endif // #if BOOST_CB_ENABLE_DEBUG
{
// Helper types
//! Base iterator.
typedef std::iterator<
std::random_access_iterator_tag,
typename Traits::value_type,
typename Traits::difference_type,
typename Traits::pointer,
typename Traits::reference> base_iterator;
//! Non-const iterator.
typedef iterator<Buff, typename Traits::nonconst_self> nonconst_self;
// Basic types
//! The type of the elements stored in the circular buffer.
typedef typename base_iterator::value_type value_type;
//! Pointer to the element.
typedef typename base_iterator::pointer pointer;
//! Reference to the element.
typedef typename base_iterator::reference reference;
//! Size type.
typedef typename Traits::size_type size_type;
//! Difference type.
typedef typename base_iterator::difference_type difference_type;
// Member variables
//! The circular buffer where the iterator points to.
const Buff* m_buff;
//! An internal iterator.
pointer m_it;
// Construction & assignment
// Default copy constructor.
//! Default constructor.
iterator() : m_buff(0), m_it(0) {}
#if BOOST_CB_ENABLE_DEBUG
//! Copy constructor (used for converting from a non-const to a const iterator).
iterator(const nonconst_self& it) : debug_iterator_base(it), m_buff(it.m_buff), m_it(it.m_it) {}
//! Internal constructor.
/*!
\note This constructor is not intended to be used directly by the user.
*/
iterator(const Buff* cb, const pointer p) : debug_iterator_base(cb), m_buff(cb), m_it(p) {}
#else
iterator(const nonconst_self& it) : m_buff(it.m_buff), m_it(it.m_it) {}
iterator(const Buff* cb, const pointer p) : m_buff(cb), m_it(p) {}
#endif // #if BOOST_CB_ENABLE_DEBUG
//! Assign operator.
iterator& operator = (const iterator& it) {
if (this == &it)
return *this;
#if BOOST_CB_ENABLE_DEBUG
debug_iterator_base::operator =(it);
#endif // #if BOOST_CB_ENABLE_DEBUG
m_buff = it.m_buff;
m_it = it.m_it;
return *this;
}
// Random access iterator methods
//! Dereferencing operator.
reference operator * () const {
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
BOOST_CB_ASSERT(m_it != 0); // check for iterator pointing to end()
return *m_it;
}
//! Dereferencing operator.
pointer operator -> () const { return &(operator*()); }
//! Difference operator.
template <class Traits0>
difference_type operator - (const iterator<Buff, Traits0>& it) const {
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator
return linearize_pointer(*this) - linearize_pointer(it);
}
//! Increment operator (prefix).
iterator& operator ++ () {
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
BOOST_CB_ASSERT(m_it != 0); // check for iterator pointing to end()
m_buff->increment(m_it);
if (m_it == m_buff->m_last)
m_it = 0;
return *this;
}
//! Increment operator (postfix).
iterator operator ++ (int) {
iterator<Buff, Traits> tmp = *this;
++*this;
return tmp;
}
//! Decrement operator (prefix).
iterator& operator -- () {
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
BOOST_CB_ASSERT(m_it != m_buff->m_first); // check for iterator pointing to begin()
if (m_it == 0)
m_it = m_buff->m_last;
m_buff->decrement(m_it);
return *this;
}
//! Decrement operator (postfix).
iterator operator -- (int) {
iterator<Buff, Traits> tmp = *this;
--*this;
return tmp;
}
//! Iterator addition.
iterator& operator += (difference_type n) {
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
if (n > 0) {
BOOST_CB_ASSERT(m_buff->end() - *this >= n); // check for too large n
m_it = m_buff->add(m_it, n);
if (m_it == m_buff->m_last)
m_it = 0;
} else if (n < 0) {
*this -= -n;
}
return *this;
}
//! Iterator addition.
iterator operator + (difference_type n) const { return iterator<Buff, Traits>(*this) += n; }
//! Iterator subtraction.
iterator& operator -= (difference_type n) {
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
if (n > 0) {
BOOST_CB_ASSERT(*this - m_buff->begin() >= n); // check for too large n
m_it = m_buff->sub(m_it == 0 ? m_buff->m_last : m_it, n);
} else if (n < 0) {
*this += -n;
}
return *this;
}
//! Iterator subtraction.
iterator operator - (difference_type n) const { return iterator<Buff, Traits>(*this) -= n; }
//! Element access operator.
reference operator [] (difference_type n) const { return *(*this + n); }
// Equality & comparison
//! Equality.
template <class Traits0>
bool operator == (const iterator<Buff, Traits0>& it) const {
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator
return m_it == it.m_it;
}
//! Inequality.
template <class Traits0>
bool operator != (const iterator<Buff, Traits0>& it) const {
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator
return m_it != it.m_it;
}
//! Less.
template <class Traits0>
bool operator < (const iterator<Buff, Traits0>& it) const {
BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator
BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator
return linearize_pointer(*this) < linearize_pointer(it);
}
//! Greater.
template <class Traits0>
bool operator > (const iterator<Buff, Traits0>& it) const { return it < *this; }
//! Less or equal.
template <class Traits0>
bool operator <= (const iterator<Buff, Traits0>& it) const { return !(it < *this); }
//! Greater or equal.
template <class Traits0>
bool operator >= (const iterator<Buff, Traits0>& it) const { return !(*this < it); }
// Helpers
//! Get a pointer which would point to the same element as the iterator in case the circular buffer is linearized.
template <class Traits0>
typename Traits0::pointer linearize_pointer(const iterator<Buff, Traits0>& it) const {
return it.m_it == 0 ? m_buff->m_buff + m_buff->size() :
(it.m_it < m_buff->m_first ? it.m_it + (m_buff->m_end - m_buff->m_first)
: m_buff->m_buff + (it.m_it - m_buff->m_first));
}
};
//! Iterator addition.
template <class Buff, class Traits>
inline iterator<Buff, Traits>
operator + (typename Traits::difference_type n, const iterator<Buff, Traits>& it) {
return it + n;
}
/*!
\fn ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest)
\brief Equivalent of <code>std::uninitialized_copy</code> but with explicit specification of value type.
*/
template<class InputIterator, class ForwardIterator, class Alloc>
inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a) {
ForwardIterator next = dest;
BOOST_TRY {
for (; first != last; ++first, ++dest)
boost::container::allocator_traits<Alloc>::construct(a, boost::addressof(*dest), *first);
} BOOST_CATCH(...) {
for (; next != dest; ++next)
boost::container::allocator_traits<Alloc>::destroy(a, boost::addressof(*next));
BOOST_RETHROW
}
BOOST_CATCH_END
return dest;
}
template<class InputIterator, class ForwardIterator, class Alloc>
ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a,
true_type) {
for (; first != last; ++first, ++dest)
boost::container::allocator_traits<Alloc>::construct(a, boost::addressof(*dest), boost::move(*first));
return dest;
}
template<class InputIterator, class ForwardIterator, class Alloc>
ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a,
false_type) {
return uninitialized_copy(first, last, dest, a);
}
/*!
\fn ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest)
\brief Equivalent of <code>std::uninitialized_copy</code> but with explicit specification of value type and moves elements if they have noexcept move constructors.
*/
template<class InputIterator, class ForwardIterator, class Alloc>
ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest, Alloc& a) {
typedef typename boost::is_nothrow_move_constructible<typename boost::container::allocator_traits<Alloc>::value_type>::type tag_t;
return uninitialized_move_if_noexcept_impl(first, last, dest, a, tag_t());
}
/*!
\fn void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const T& item, Alloc& alloc)
\brief Equivalent of <code>std::uninitialized_fill_n</code> with allocator.
*/
template<class ForwardIterator, class Diff, class T, class Alloc>
inline void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const T& item, Alloc& alloc) {
ForwardIterator next = first;
BOOST_TRY {
for (; n > 0; ++first, --n)
boost::container::allocator_traits<Alloc>::construct(alloc, boost::addressof(*first), item);
} BOOST_CATCH(...) {
for (; next != first; ++next)
boost::container::allocator_traits<Alloc>::destroy(alloc, boost::addressof(*next));
BOOST_RETHROW
}
BOOST_CATCH_END
}
} // namespace cb_details
} // namespace boost
#if defined(_MSC_VER)
# pragma warning(pop)
#endif
#endif // #if !defined(BOOST_CIRCULAR_BUFFER_DETAILS_HPP)
File diff suppressed because it is too large Load Diff
+43
View File
@@ -0,0 +1,43 @@
// Forward declaration of the circular buffer and its adaptor.
// Copyright (c) 2003-2008 Jan Gaspar
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See www.boost.org/libs/circular_buffer for documentation.
#if !defined(BOOST_CIRCULAR_BUFFER_FWD_HPP)
#define BOOST_CIRCULAR_BUFFER_FWD_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp>
#if !defined(BOOST_NO_STD_ALLOCATOR)
#include <memory>
#else
#include <vector>
#endif
namespace boost {
#if !defined(BOOST_NO_STD_ALLOCATOR)
#define BOOST_CB_DEFAULT_ALLOCATOR(T) std::allocator<T>
#else
#define BOOST_CB_DEFAULT_ALLOCATOR(T) BOOST_DEDUCED_TYPENAME std::vector<T>::allocator_type
#endif
template <class T, class Alloc = BOOST_CB_DEFAULT_ALLOCATOR(T)>
class circular_buffer;
template <class T, class Alloc = BOOST_CB_DEFAULT_ALLOCATOR(T)>
class circular_buffer_space_optimized;
#undef BOOST_CB_DEFAULT_ALLOCATOR
} // namespace boost
#endif // #if !defined(BOOST_CIRCULAR_BUFFER_FWD_HPP)
+36
View File
@@ -0,0 +1,36 @@
// boost/detail/lightweight_main.hpp -------------------------------------------------//
// Copyright Beman Dawes 2010
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
#include <iostream>
#include <exception>
//--------------------------------------------------------------------------------------//
// //
// exception reporting main() that calls cpp_main() //
// //
//--------------------------------------------------------------------------------------//
int cpp_main(int argc, char* argv[]);
int main(int argc, char* argv[])
{
try
{
return cpp_main(argc, argv);
}
catch (const std::exception& ex)
{
std::cout
<< "\nERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR\n"
<< "\n****************************** std::exception *****************************\n"
<< ex.what()
<< "\n***************************************************************************\n"
<< std::endl;
}
return 1;
}
+142
View File
@@ -0,0 +1,142 @@
// boost progress.hpp header file ------------------------------------------//
// Copyright Beman Dawes 1994-99. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/timer for documentation.
// Revision History
// 1 Dec 01 Add leading progress display strings (suggested by Toon Knapen)
// 20 May 01 Introduce several static_casts<> to eliminate warning messages
// (Fixed by Beman, reported by Herve Bronnimann)
// 12 Jan 01 Change to inline implementation to allow use without library
// builds. See docs for more rationale. (Beman Dawes)
// 22 Jul 99 Name changed to .hpp
// 16 Jul 99 Second beta
// 6 Jul 99 Initial boost version
#ifndef BOOST_PROGRESS_HPP
#define BOOST_PROGRESS_HPP
#include <boost/timer.hpp>
#include <boost/noncopyable.hpp>
#include <boost/cstdint.hpp> // for uintmax_t
#include <iostream> // for ostream, cout, etc
#include <string> // for string
namespace boost {
// progress_timer ----------------------------------------------------------//
// A progress_timer behaves like a timer except that the destructor displays
// an elapsed time message at an appropriate place in an appropriate form.
class progress_timer : public timer, private noncopyable
{
public:
explicit progress_timer( std::ostream & os = std::cout )
// os is hint; implementation may ignore, particularly in embedded systems
: timer(), noncopyable(), m_os(os) {}
~progress_timer()
{
// A) Throwing an exception from a destructor is a Bad Thing.
// B) The progress_timer destructor does output which may throw.
// C) A progress_timer is usually not critical to the application.
// Therefore, wrap the I/O in a try block, catch and ignore all exceptions.
try
{
// use istream instead of ios_base to workaround GNU problem (Greg Chicares)
std::istream::fmtflags old_flags = m_os.setf( std::istream::fixed,
std::istream::floatfield );
std::streamsize old_prec = m_os.precision( 2 );
m_os << elapsed() << " s\n" // "s" is System International d'Unites std
<< std::endl;
m_os.flags( old_flags );
m_os.precision( old_prec );
}
catch (...) {} // eat any exceptions
} // ~progress_timer
private:
std::ostream & m_os;
};
// progress_display --------------------------------------------------------//
// progress_display displays an appropriate indication of
// progress at an appropriate place in an appropriate form.
// NOTE: (Jan 12, 2001) Tried to change unsigned long to boost::uintmax_t, but
// found some compilers couldn't handle the required conversion to double.
// Reverted to unsigned long until the compilers catch up.
class progress_display : private noncopyable
{
public:
explicit progress_display( unsigned long expected_count_,
std::ostream & os = std::cout,
const std::string & s1 = "\n", //leading strings
const std::string & s2 = "",
const std::string & s3 = "" )
// os is hint; implementation may ignore, particularly in embedded systems
: noncopyable(), m_os(os), m_s1(s1), m_s2(s2), m_s3(s3) { restart(expected_count_); }
void restart( unsigned long expected_count_ )
// Effects: display appropriate scale
// Postconditions: count()==0, expected_count()==expected_count_
{
_count = _next_tic_count = _tic = 0;
_expected_count = expected_count_;
m_os << m_s1 << "0% 10 20 30 40 50 60 70 80 90 100%\n"
<< m_s2 << "|----|----|----|----|----|----|----|----|----|----|"
<< std::endl // endl implies flush, which ensures display
<< m_s3;
if ( !_expected_count ) _expected_count = 1; // prevent divide by zero
} // restart
unsigned long operator+=( unsigned long increment )
// Effects: Display appropriate progress tic if needed.
// Postconditions: count()== original count() + increment
// Returns: count().
{
if ( (_count += increment) >= _next_tic_count ) { display_tic(); }
return _count;
}
unsigned long operator++() { return operator+=( 1 ); }
unsigned long count() const { return _count; }
unsigned long expected_count() const { return _expected_count; }
private:
std::ostream & m_os; // may not be present in all imps
const std::string m_s1; // string is more general, safer than
const std::string m_s2; // const char *, and efficiency or size are
const std::string m_s3; // not issues
unsigned long _count, _expected_count, _next_tic_count;
unsigned int _tic;
void display_tic()
{
// use of floating point ensures that both large and small counts
// work correctly. static_cast<>() is also used several places
// to suppress spurious compiler warnings.
unsigned int tics_needed = static_cast<unsigned int>((static_cast<double>(_count)
/ static_cast<double>(_expected_count)) * 50.0);
do { m_os << '*' << std::flush; } while ( ++_tic < tics_needed );
_next_tic_count =
static_cast<unsigned long>((_tic/50.0) * static_cast<double>(_expected_count));
if ( _count == _expected_count ) {
if ( _tic < 51 ) m_os << '*';
m_os << std::endl;
}
} // display_tic
};
} // namespace boost
#endif // BOOST_PROGRESS_HPP
+21
View File
@@ -0,0 +1,21 @@
#ifndef BOOST_THREAD_CONDITION_HPP
#define BOOST_THREAD_CONDITION_HPP
// (C) Copyright 2007 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/detail/config.hpp>
#if defined BOOST_THREAD_PROVIDES_CONDITION
#include <boost/thread/condition_variable.hpp>
namespace boost
{
typedef condition_variable_any condition;
}
#endif
#endif
+155
View File
@@ -0,0 +1,155 @@
#ifndef BOOST_THREAD_DETAIL_THREAD_GROUP_HPP
#define BOOST_THREAD_DETAIL_THREAD_GROUP_HPP
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2007-9 Anthony Williams
#include <list>
#include <boost/thread/csbl/memory/unique_ptr.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/lock_guard.hpp>
#include <boost/config/abi_prefix.hpp>
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4251)
#endif
namespace boost
{
class thread_group
{
private:
thread_group(thread_group const&);
thread_group& operator=(thread_group const&);
public:
thread_group() {}
~thread_group()
{
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
it!=end;
++it)
{
delete *it;
}
}
bool is_this_thread_in()
{
thread::id id = this_thread::get_id();
boost::shared_lock<shared_mutex> guard(m);
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
it!=end;
++it)
{
if ((*it)->get_id() == id)
return true;
}
return false;
}
bool is_thread_in(thread* thrd)
{
if(thrd)
{
thread::id id = thrd->get_id();
boost::shared_lock<shared_mutex> guard(m);
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
it!=end;
++it)
{
if ((*it)->get_id() == id)
return true;
}
return false;
}
else
{
return false;
}
}
template<typename F>
thread* create_thread(F threadfunc)
{
boost::lock_guard<shared_mutex> guard(m);
boost::csbl::unique_ptr<thread> new_thread(new thread(threadfunc));
threads.push_back(new_thread.get());
return new_thread.release();
}
void add_thread(thread* thrd)
{
if(thrd)
{
BOOST_THREAD_ASSERT_PRECONDITION( ! is_thread_in(thrd) ,
thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost::thread_group: trying to add a duplicated thread")
);
boost::lock_guard<shared_mutex> guard(m);
threads.push_back(thrd);
}
}
void remove_thread(thread* thrd)
{
boost::lock_guard<shared_mutex> guard(m);
std::list<thread*>::iterator const it=std::find(threads.begin(),threads.end(),thrd);
if(it!=threads.end())
{
threads.erase(it);
}
}
void join_all()
{
BOOST_THREAD_ASSERT_PRECONDITION( ! is_this_thread_in() ,
thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost::thread_group: trying joining itself")
);
boost::shared_lock<shared_mutex> guard(m);
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
it!=end;
++it)
{
if ((*it)->joinable())
(*it)->join();
}
}
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
void interrupt_all()
{
boost::shared_lock<shared_mutex> guard(m);
for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
it!=end;
++it)
{
(*it)->interrupt();
}
}
#endif
size_t size() const
{
boost::shared_lock<shared_mutex> guard(m);
return threads.size();
}
private:
std::list<thread*> threads;
mutable shared_mutex m;
};
}
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
#include <boost/config/abi_suffix.hpp>
#endif
+716
View File
@@ -0,0 +1,716 @@
#ifndef BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
#define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
// (C) Copyright 2006-8 Anthony Williams
// (C) Copyright 2012 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
#include <boost/thread/detail/thread_interruption.hpp>
#endif
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/ceil.hpp>
#endif
#include <boost/thread/detail/delete.hpp>
#include <boost/assert.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
class shared_mutex
{
private:
class state_data
{
public:
state_data () :
shared_count(0),
exclusive(false),
upgrade(false),
exclusive_waiting_blocked(false)
{}
void assert_free() const
{
BOOST_ASSERT( ! exclusive );
BOOST_ASSERT( ! upgrade );
BOOST_ASSERT( shared_count==0 );
}
void assert_locked() const
{
BOOST_ASSERT( exclusive );
BOOST_ASSERT( shared_count==0 );
BOOST_ASSERT( ! upgrade );
}
void assert_lock_shared () const
{
BOOST_ASSERT( ! exclusive );
BOOST_ASSERT( shared_count>0 );
//BOOST_ASSERT( (! upgrade) || (shared_count>1));
// if upgraded there are at least 2 threads sharing the mutex,
// except when unlock_upgrade_and_lock has decreased the number of readers but has not taken yet exclusive ownership.
}
void assert_lock_upgraded () const
{
BOOST_ASSERT( ! exclusive );
BOOST_ASSERT( upgrade );
BOOST_ASSERT( shared_count>0 );
}
void assert_lock_not_upgraded () const
{
BOOST_ASSERT( ! upgrade );
}
bool can_lock () const
{
return ! (shared_count || exclusive);
}
void exclusive_blocked (bool blocked)
{
exclusive_waiting_blocked = blocked;
}
void lock ()
{
exclusive = true;
}
void unlock ()
{
exclusive = false;
exclusive_waiting_blocked = false;
}
bool can_lock_shared () const
{
return ! (exclusive || exclusive_waiting_blocked);
}
bool more_shared () const
{
return shared_count > 0 ;
}
unsigned get_shared_count () const
{
return shared_count ;
}
unsigned lock_shared ()
{
return ++shared_count;
}
void unlock_shared ()
{
--shared_count;
}
bool unlock_shared_downgrades()
{
if (upgrade) {
upgrade=false;
exclusive=true;
return true;
} else {
exclusive_waiting_blocked=false;
return false;
}
}
void lock_upgrade ()
{
++shared_count;
upgrade=true;
}
bool can_lock_upgrade () const
{
return ! (exclusive || exclusive_waiting_blocked || upgrade);
}
void unlock_upgrade ()
{
upgrade=false;
--shared_count;
}
//private:
unsigned shared_count;
bool exclusive;
bool upgrade;
bool exclusive_waiting_blocked;
};
state_data state;
boost::mutex state_change;
boost::condition_variable shared_cond;
boost::condition_variable exclusive_cond;
boost::condition_variable upgrade_cond;
void release_waiters()
{
exclusive_cond.notify_one();
shared_cond.notify_all();
}
public:
BOOST_THREAD_NO_COPYABLE(shared_mutex)
shared_mutex()
{
}
~shared_mutex()
{
}
void lock_shared()
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
while(!state.can_lock_shared())
{
shared_cond.wait(lk);
}
state.lock_shared();
}
bool try_lock_shared()
{
boost::unique_lock<boost::mutex> lk(state_change);
if(!state.can_lock_shared())
{
return false;
}
state.lock_shared();
return true;
}
#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock_shared(system_time const& timeout)
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
while(!state.can_lock_shared())
{
if(!shared_cond.timed_wait(lk,timeout))
{
return false;
}
}
state.lock_shared();
return true;
}
template<typename TimeDuration>
bool timed_lock_shared(TimeDuration const & relative_time)
{
return timed_lock_shared(get_system_time()+relative_time);
}
#endif
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
{
return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time)
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
while(!state.can_lock_shared())
//while(state.exclusive || state.exclusive_waiting_blocked)
{
if(cv_status::timeout==shared_cond.wait_until(lk,abs_time))
{
return false;
}
}
state.lock_shared();
return true;
}
#endif
void unlock_shared()
{
boost::unique_lock<boost::mutex> lk(state_change);
state.assert_lock_shared();
state.unlock_shared();
if (! state.more_shared())
{
if (state.upgrade)
{
// As there is a thread doing a unlock_upgrade_and_lock that is waiting for ! state.more_shared()
// avoid other threads to lock, lock_upgrade or lock_shared, so only this thread is notified.
state.upgrade=false;
state.exclusive=true;
//lk.unlock();
upgrade_cond.notify_one();
}
else
{
state.exclusive_waiting_blocked=false;
//lk.unlock();
}
release_waiters();
}
}
void lock()
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
while (state.shared_count || state.exclusive)
{
state.exclusive_waiting_blocked=true;
exclusive_cond.wait(lk);
}
state.exclusive=true;
}
#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock(system_time const& timeout)
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
while(state.shared_count || state.exclusive)
{
state.exclusive_waiting_blocked=true;
if(!exclusive_cond.timed_wait(lk,timeout))
{
if(state.shared_count || state.exclusive)
{
state.exclusive_waiting_blocked=false;
release_waiters();
return false;
}
break;
}
}
state.exclusive=true;
return true;
}
template<typename TimeDuration>
bool timed_lock(TimeDuration const & relative_time)
{
return timed_lock(get_system_time()+relative_time);
}
#endif
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
{
return try_lock_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
while(state.shared_count || state.exclusive)
{
state.exclusive_waiting_blocked=true;
if(cv_status::timeout == exclusive_cond.wait_until(lk,abs_time))
{
if(state.shared_count || state.exclusive)
{
state.exclusive_waiting_blocked=false;
release_waiters();
return false;
}
break;
}
}
state.exclusive=true;
return true;
}
#endif
bool try_lock()
{
boost::unique_lock<boost::mutex> lk(state_change);
if(state.shared_count || state.exclusive)
{
return false;
}
else
{
state.exclusive=true;
return true;
}
}
void unlock()
{
boost::unique_lock<boost::mutex> lk(state_change);
state.assert_locked();
state.exclusive=false;
state.exclusive_waiting_blocked=false;
state.assert_free();
release_waiters();
}
void lock_upgrade()
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
{
shared_cond.wait(lk);
}
state.lock_shared();
state.upgrade=true;
}
#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock_upgrade(system_time const& timeout)
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
{
if(!shared_cond.timed_wait(lk,timeout))
{
if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
{
return false;
}
break;
}
}
state.lock_shared();
state.upgrade=true;
return true;
}
template<typename TimeDuration>
bool timed_lock_upgrade(TimeDuration const & relative_time)
{
return timed_lock_upgrade(get_system_time()+relative_time);
}
#endif
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time)
{
return try_lock_upgrade_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool try_lock_upgrade_until(const chrono::time_point<Clock, Duration>& abs_time)
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
{
if(cv_status::timeout == shared_cond.wait_until(lk,abs_time))
{
if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
{
return false;
}
break;
}
}
state.lock_shared();
state.upgrade=true;
return true;
}
#endif
bool try_lock_upgrade()
{
boost::unique_lock<boost::mutex> lk(state_change);
if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
{
return false;
}
else
{
state.lock_shared();
state.upgrade=true;
state.assert_lock_upgraded();
return true;
}
}
void unlock_upgrade()
{
boost::unique_lock<boost::mutex> lk(state_change);
//state.upgrade=false;
state.unlock_upgrade();
if(! state.more_shared() )
{
state.exclusive_waiting_blocked=false;
release_waiters();
} else {
shared_cond.notify_all();
}
}
// Upgrade <-> Exclusive
void unlock_upgrade_and_lock()
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
state.assert_lock_upgraded();
state.unlock_shared();
while (state.more_shared())
{
upgrade_cond.wait(lk);
}
state.upgrade=false;
state.exclusive=true;
state.assert_locked();
}
void unlock_and_lock_upgrade()
{
boost::unique_lock<boost::mutex> lk(state_change);
state.assert_locked();
state.exclusive=false;
state.upgrade=true;
state.lock_shared();
state.exclusive_waiting_blocked=false;
state.assert_lock_upgraded();
release_waiters();
}
bool try_unlock_upgrade_and_lock()
{
boost::unique_lock<boost::mutex> lk(state_change);
state.assert_lock_upgraded();
if( !state.exclusive
&& !state.exclusive_waiting_blocked
&& state.upgrade
&& state.shared_count==1)
{
state.shared_count=0;
state.exclusive=true;
state.upgrade=false;
state.assert_locked();
return true;
}
return false;
}
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool
try_unlock_upgrade_and_lock_for(
const chrono::duration<Rep, Period>& rel_time)
{
return try_unlock_upgrade_and_lock_until(
chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool
try_unlock_upgrade_and_lock_until(
const chrono::time_point<Clock, Duration>& abs_time)
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
state.assert_lock_upgraded();
if (state.shared_count != 1)
{
for (;;)
{
cv_status status = shared_cond.wait_until(lk,abs_time);
if (state.shared_count == 1)
break;
if(status == cv_status::timeout)
return false;
}
}
state.upgrade=false;
state.exclusive=true;
state.exclusive_waiting_blocked=false;
state.shared_count=0;
return true;
}
#endif
// Shared <-> Exclusive
void unlock_and_lock_shared()
{
boost::unique_lock<boost::mutex> lk(state_change);
state.assert_locked();
state.exclusive=false;
state.lock_shared();
state.exclusive_waiting_blocked=false;
release_waiters();
}
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
bool try_unlock_shared_and_lock()
{
boost::unique_lock<boost::mutex> lk(state_change);
state.assert_lock_shared();
if( !state.exclusive
&& !state.exclusive_waiting_blocked
&& !state.upgrade
&& state.shared_count==1)
{
state.shared_count=0;
state.exclusive=true;
return true;
}
return false;
}
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool
try_unlock_shared_and_lock_for(
const chrono::duration<Rep, Period>& rel_time)
{
return try_unlock_shared_and_lock_until(
chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool
try_unlock_shared_and_lock_until(
const chrono::time_point<Clock, Duration>& abs_time)
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
state.assert_lock_shared();
if (state.shared_count != 1)
{
for (;;)
{
cv_status status = shared_cond.wait_until(lk,abs_time);
if (state.shared_count == 1)
break;
if(status == cv_status::timeout)
return false;
}
}
state.upgrade=false;
state.exclusive=true;
state.exclusive_waiting_blocked=false;
state.shared_count=0;
return true;
}
#endif
#endif
// Shared <-> Upgrade
void unlock_upgrade_and_lock_shared()
{
boost::unique_lock<boost::mutex> lk(state_change);
state.assert_lock_upgraded();
state.upgrade=false;
state.exclusive_waiting_blocked=false;
release_waiters();
}
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
bool try_unlock_shared_and_lock_upgrade()
{
boost::unique_lock<boost::mutex> lk(state_change);
state.assert_lock_shared();
if( !state.exclusive
&& !state.exclusive_waiting_blocked
&& !state.upgrade
)
{
state.upgrade=true;
return true;
}
return false;
}
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool
try_unlock_shared_and_lock_upgrade_for(
const chrono::duration<Rep, Period>& rel_time)
{
return try_unlock_shared_and_lock_upgrade_until(
chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool
try_unlock_shared_and_lock_upgrade_until(
const chrono::time_point<Clock, Duration>& abs_time)
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
state.assert_lock_shared();
if( state.exclusive
|| state.exclusive_waiting_blocked
|| state.upgrade
)
{
for (;;)
{
cv_status status = exclusive_cond.wait_until(lk,abs_time);
if( ! state.exclusive
&& ! state.exclusive_waiting_blocked
&& ! state.upgrade
)
break;
if(status == cv_status::timeout)
return false;
}
}
state.upgrade=true;
return true;
}
#endif
#endif
};
typedef shared_mutex upgrade_mutex;
}
#include <boost/config/abi_suffix.hpp>
#endif
+50
View File
@@ -0,0 +1,50 @@
#ifndef BOOST_THREAD_SHARED_MUTEX_HPP
#define BOOST_THREAD_SHARED_MUTEX_HPP
// shared_mutex.hpp
//
// (C) Copyright 2007 Anthony Williams
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/detail/config.hpp>
#if defined(BOOST_THREAD_PLATFORM_WIN32)
#if defined(BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN)
#include <boost/thread/pthread/shared_mutex.hpp>
#else
#include <boost/thread/win32/shared_mutex.hpp>
#endif
#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
//#include <boost/thread/v2/shared_mutex.hpp>
#include <boost/thread/pthread/shared_mutex.hpp>
#else
#error "Boost threads unavailable on this platform"
#endif
#include <boost/thread/lockable_traits.hpp>
namespace boost
{
typedef shared_mutex shared_timed_mutex;
namespace sync
{
#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
template<>
struct is_basic_lockable<shared_mutex>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
template<>
struct is_lockable<shared_mutex>
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
#endif
}
}
#endif
+16
View File
@@ -0,0 +1,16 @@
#ifndef BOOST_THREAD_THREAD_HPP
#define BOOST_THREAD_THREAD_HPP
// thread.hpp
//
// (C) Copyright 2007-8 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/thread_only.hpp>
#include <boost/thread/detail/thread_group.hpp>
#endif
+903
View File
@@ -0,0 +1,903 @@
#ifndef BOOST_THREAD_WIN32_SHARED_MUTEX_HPP
#define BOOST_THREAD_WIN32_SHARED_MUTEX_HPP
// (C) Copyright 2006-8 Anthony Williams
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/assert.hpp>
#include <boost/detail/interlocked.hpp>
#include <boost/thread/win32/thread_primitives.hpp>
#include <boost/static_assert.hpp>
#include <limits.h>
#include <boost/thread/thread_time.hpp>
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/ceil.hpp>
#endif
#include <boost/thread/detail/delete.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
class shared_mutex
{
private:
struct state_data
{
unsigned shared_count:11,
shared_waiting:11,
exclusive:1,
upgrade:1,
exclusive_waiting:7,
exclusive_waiting_blocked:1;
friend bool operator==(state_data const& lhs,state_data const& rhs)
{
return *reinterpret_cast<unsigned const*>(&lhs)==*reinterpret_cast<unsigned const*>(&rhs);
}
};
template<typename T>
T interlocked_compare_exchange(T* target,T new_value,T comparand)
{
BOOST_STATIC_ASSERT(sizeof(T)==sizeof(long));
long const res=BOOST_INTERLOCKED_COMPARE_EXCHANGE(reinterpret_cast<long*>(target),
*reinterpret_cast<long*>(&new_value),
*reinterpret_cast<long*>(&comparand));
return *reinterpret_cast<T const*>(&res);
}
enum
{
unlock_sem = 0,
exclusive_sem = 1
};
state_data state;
detail::win32::handle semaphores[2];
detail::win32::handle upgrade_sem;
void release_waiters(state_data old_state)
{
if(old_state.exclusive_waiting)
{
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[exclusive_sem],1,0)!=0);
}
if(old_state.shared_waiting || old_state.exclusive_waiting)
{
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
}
}
void release_shared_waiters(state_data old_state)
{
if(old_state.shared_waiting || old_state.exclusive_waiting)
{
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
}
}
public:
BOOST_THREAD_NO_COPYABLE(shared_mutex)
shared_mutex()
{
semaphores[unlock_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
semaphores[exclusive_sem]=detail::win32::create_anonymous_semaphore_nothrow(0,LONG_MAX);
if (!semaphores[exclusive_sem])
{
detail::win32::release_semaphore(semaphores[unlock_sem],LONG_MAX);
boost::throw_exception(thread_resource_error());
}
upgrade_sem=detail::win32::create_anonymous_semaphore_nothrow(0,LONG_MAX);
if (!upgrade_sem)
{
detail::win32::release_semaphore(semaphores[unlock_sem],LONG_MAX);
detail::win32::release_semaphore(semaphores[exclusive_sem],LONG_MAX);
boost::throw_exception(thread_resource_error());
}
state_data state_={0,0,0,0,0,0};
state=state_;
}
~shared_mutex()
{
detail::win32::CloseHandle(upgrade_sem);
detail::win32::CloseHandle(semaphores[unlock_sem]);
detail::win32::CloseHandle(semaphores[exclusive_sem]);
}
bool try_lock_shared()
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
if(!new_state.exclusive && !new_state.exclusive_waiting_blocked)
{
++new_state.shared_count;
if(!new_state.shared_count)
{
return false;
}
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
return !(old_state.exclusive| old_state.exclusive_waiting_blocked);
}
void lock_shared()
{
#if defined BOOST_THREAD_USES_DATETIME
BOOST_VERIFY(timed_lock_shared(::boost::detail::get_system_time_sentinel()));
#else
BOOST_VERIFY(try_lock_shared_until(chrono::steady_clock::now()));
#endif
}
#if defined BOOST_THREAD_USES_DATETIME
template<typename TimeDuration>
bool timed_lock_shared(TimeDuration const & relative_time)
{
return timed_lock_shared(get_system_time()+relative_time);
}
bool timed_lock_shared(boost::system_time const& wait_until)
{
for(;;)
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
{
++new_state.shared_waiting;
if(!new_state.shared_waiting)
{
boost::throw_exception(boost::lock_error());
}
}
else
{
++new_state.shared_count;
if(!new_state.shared_count)
{
boost::throw_exception(boost::lock_error());
}
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
{
return true;
}
unsigned long const res=detail::win32::WaitForSingleObjectEx(semaphores[unlock_sem],::boost::detail::get_milliseconds_until(wait_until), 0);
if(res==detail::win32::timeout)
{
for(;;)
{
state_data new_state=old_state;
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
{
if(new_state.shared_waiting)
{
--new_state.shared_waiting;
}
}
else
{
++new_state.shared_count;
if(!new_state.shared_count)
{
return false;
}
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
{
return true;
}
return false;
}
BOOST_ASSERT(res==0);
}
}
#endif
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
{
return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
system_clock::time_point s_now = system_clock::now();
typename Clock::time_point c_now = Clock::now();
return try_lock_shared_until(s_now + ceil<system_clock::duration>(t - c_now));
}
template <class Duration>
bool try_lock_shared_until(const chrono::time_point<chrono::system_clock, Duration>& t)
{
using namespace chrono;
typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt;
return try_lock_shared_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch())));
}
bool try_lock_shared_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp)
{
for(;;)
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
{
++new_state.shared_waiting;
if(!new_state.shared_waiting)
{
boost::throw_exception(boost::lock_error());
}
}
else
{
++new_state.shared_count;
if(!new_state.shared_count)
{
boost::throw_exception(boost::lock_error());
}
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
{
return true;
}
chrono::system_clock::time_point n = chrono::system_clock::now();
unsigned long res;
if (tp>n) {
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-n);
res=detail::win32::WaitForSingleObjectEx(semaphores[unlock_sem],
static_cast<unsigned long>(rel_time.count()), 0);
} else {
res=detail::win32::timeout;
}
if(res==detail::win32::timeout)
{
for(;;)
{
state_data new_state=old_state;
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
{
if(new_state.shared_waiting)
{
--new_state.shared_waiting;
}
}
else
{
++new_state.shared_count;
if(!new_state.shared_count)
{
return false;
}
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
{
return true;
}
return false;
}
BOOST_ASSERT(res==0);
}
}
#endif
void unlock_shared()
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
bool const last_reader=!--new_state.shared_count;
if(last_reader)
{
if(new_state.upgrade)
{
new_state.upgrade=false;
new_state.exclusive=true;
}
else
{
if(new_state.exclusive_waiting)
{
--new_state.exclusive_waiting;
new_state.exclusive_waiting_blocked=false;
}
new_state.shared_waiting=0;
}
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
if(last_reader)
{
if(old_state.upgrade)
{
BOOST_VERIFY(detail::win32::ReleaseSemaphore(upgrade_sem,1,0)!=0);
}
else
{
release_waiters(old_state);
}
}
break;
}
old_state=current_state;
}
}
void lock()
{
#if defined BOOST_THREAD_USES_DATETIME
BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel()));
#else
BOOST_VERIFY(try_lock_until(chrono::steady_clock::now()));
#endif
}
#if defined BOOST_THREAD_USES_DATETIME
template<typename TimeDuration>
bool timed_lock(TimeDuration const & relative_time)
{
return timed_lock(get_system_time()+relative_time);
}
#endif
bool try_lock()
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
if(new_state.shared_count || new_state.exclusive)
{
return false;
}
else
{
new_state.exclusive=true;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
return true;
}
#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock(boost::system_time const& wait_until)
{
for(;;)
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
if(new_state.shared_count || new_state.exclusive)
{
++new_state.exclusive_waiting;
if(!new_state.exclusive_waiting)
{
boost::throw_exception(boost::lock_error());
}
new_state.exclusive_waiting_blocked=true;
}
else
{
new_state.exclusive=true;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
if(!old_state.shared_count && !old_state.exclusive)
{
return true;
}
#ifndef UNDER_CE
const bool wait_all = true;
#else
const bool wait_all = false;
#endif
unsigned long const wait_res=detail::win32::WaitForMultipleObjectsEx(2,semaphores,wait_all,::boost::detail::get_milliseconds_until(wait_until), 0);
if(wait_res==detail::win32::timeout)
{
for(;;)
{
bool must_notify = false;
state_data new_state=old_state;
if(new_state.shared_count || new_state.exclusive)
{
if(new_state.exclusive_waiting)
{
if(!--new_state.exclusive_waiting)
{
new_state.exclusive_waiting_blocked=false;
must_notify = true;
}
}
}
else
{
new_state.exclusive=true;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if (must_notify)
{
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0);
}
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
if(!old_state.shared_count && !old_state.exclusive)
{
return true;
}
return false;
}
BOOST_ASSERT(wait_res<2);
}
}
#endif
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
{
return try_lock_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
system_clock::time_point s_now = system_clock::now();
typename Clock::time_point c_now = Clock::now();
return try_lock_until(s_now + ceil<system_clock::duration>(t - c_now));
}
template <class Duration>
bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t)
{
using namespace chrono;
typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt;
return try_lock_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch())));
}
bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp)
{
for(;;)
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
if(new_state.shared_count || new_state.exclusive)
{
++new_state.exclusive_waiting;
if(!new_state.exclusive_waiting)
{
boost::throw_exception(boost::lock_error());
}
new_state.exclusive_waiting_blocked=true;
}
else
{
new_state.exclusive=true;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
if(!old_state.shared_count && !old_state.exclusive)
{
return true;
}
#ifndef UNDER_CE
const bool wait_all = true;
#else
const bool wait_all = false;
#endif
chrono::system_clock::time_point n = chrono::system_clock::now();
unsigned long wait_res;
if (tp>n) {
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
wait_res=detail::win32::WaitForMultipleObjectsEx(2,semaphores,wait_all,
static_cast<unsigned long>(rel_time.count()), 0);
} else {
wait_res=detail::win32::timeout;
}
if(wait_res==detail::win32::timeout)
{
for(;;)
{
bool must_notify = false;
state_data new_state=old_state;
if(new_state.shared_count || new_state.exclusive)
{
if(new_state.exclusive_waiting)
{
if(!--new_state.exclusive_waiting)
{
new_state.exclusive_waiting_blocked=false;
must_notify = true;
}
}
}
else
{
new_state.exclusive=true;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if (must_notify)
{
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0);
}
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
if(!old_state.shared_count && !old_state.exclusive)
{
return true;
}
return false;
}
BOOST_ASSERT(wait_res<2);
}
}
#endif
void unlock()
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
new_state.exclusive=false;
if(new_state.exclusive_waiting)
{
--new_state.exclusive_waiting;
new_state.exclusive_waiting_blocked=false;
}
new_state.shared_waiting=0;
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
release_waiters(old_state);
}
void lock_upgrade()
{
for(;;)
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade)
{
++new_state.shared_waiting;
if(!new_state.shared_waiting)
{
boost::throw_exception(boost::lock_error());
}
}
else
{
++new_state.shared_count;
if(!new_state.shared_count)
{
boost::throw_exception(boost::lock_error());
}
new_state.upgrade=true;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
if(!(old_state.exclusive|| old_state.exclusive_waiting_blocked|| old_state.upgrade))
{
return;
}
BOOST_VERIFY(!detail::win32::WaitForSingleObjectEx(semaphores[unlock_sem],detail::win32::infinite, 0));
}
}
bool try_lock_upgrade()
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade)
{
return false;
}
else
{
++new_state.shared_count;
if(!new_state.shared_count)
{
return false;
}
new_state.upgrade=true;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
return true;
}
void unlock_upgrade()
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
new_state.upgrade=false;
bool const last_reader=!--new_state.shared_count;
new_state.shared_waiting=0;
if(last_reader)
{
if(new_state.exclusive_waiting)
{
--new_state.exclusive_waiting;
new_state.exclusive_waiting_blocked=false;
}
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
if(last_reader)
{
release_waiters(old_state);
}
else {
release_shared_waiters(old_state);
}
// #7720
//else {
// release_waiters(old_state);
//}
break;
}
old_state=current_state;
}
}
void unlock_upgrade_and_lock()
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
bool const last_reader=!--new_state.shared_count;
if(last_reader)
{
new_state.upgrade=false;
new_state.exclusive=true;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
if(!last_reader)
{
BOOST_VERIFY(!detail::win32::WaitForSingleObjectEx(upgrade_sem,detail::win32::infinite, 0));
}
break;
}
old_state=current_state;
}
}
void unlock_and_lock_upgrade()
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
new_state.exclusive=false;
new_state.upgrade=true;
++new_state.shared_count;
if(new_state.exclusive_waiting)
{
--new_state.exclusive_waiting;
new_state.exclusive_waiting_blocked=false;
}
new_state.shared_waiting=0;
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
release_waiters(old_state);
}
// bool try_unlock_upgrade_and_lock()
// {
// return false;
// }
//#ifdef BOOST_THREAD_USES_CHRONO
// template <class Rep, class Period>
// bool
// try_unlock_upgrade_and_lock_for(
// const chrono::duration<Rep, Period>& rel_time)
// {
// return try_unlock_upgrade_and_lock_until(
// chrono::steady_clock::now() + rel_time);
// }
// template <class Clock, class Duration>
// bool
// try_unlock_upgrade_and_lock_until(
// const chrono::time_point<Clock, Duration>& abs_time)
// {
// return false;
// }
//#endif
void unlock_and_lock_shared()
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
new_state.exclusive=false;
++new_state.shared_count;
if(new_state.exclusive_waiting)
{
--new_state.exclusive_waiting;
new_state.exclusive_waiting_blocked=false;
}
new_state.shared_waiting=0;
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
release_waiters(old_state);
}
void unlock_upgrade_and_lock_shared()
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
new_state.upgrade=false;
if(new_state.exclusive_waiting)
{
--new_state.exclusive_waiting;
new_state.exclusive_waiting_blocked=false;
}
new_state.shared_waiting=0;
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
release_waiters(old_state);
}
};
typedef shared_mutex upgrade_mutex;
}
#include <boost/config/abi_suffix.hpp>
#endif
+173
View File
@@ -0,0 +1,173 @@
// (C) Copyright John Maddock 2005-7.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED
# define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED
#include <cstddef>
#if (defined(__GNUC__) && !(defined(linux) || defined(__linux) || defined(__linux__))) \
|| (!defined(__FreeBSD__) && defined(__GNUC__)) \
|| (!defined(_AIX) && defined(__IBMCPP__) && (__IBMCPP__ >= 800))
// Disable use of #include_next on Linux as typically we are installed in a
// directory that is searched *after* the std lib include path.
#if !defined(BOOST_HAS_INCLUDE_NEXT)
# define BOOST_HAS_INCLUDE_NEXT
#endif
// Need to find out if we're using GLIBC:
#ifdef BOOST_TR1_UTILITY_INCLUDED
// Oops we're in a recursive include path!!
// Need to include utility, or some std lib header,
// but *not* via <utility> or <boost/config/no_tr1/utility.hpp>
# ifndef BOOST_TR1_NO_RECURSION
# define BOOST_TR1_NO_RECURSION
# define BOOST_TR1_NO_CONFIG_RECURSION
# endif
# if defined(BOOST_HAS_INCLUDE_NEXT) && !defined(BOOST_TR1_DISABLE_INCLUDE_NEXT)
# include_next <utility>
# else
# include BOOST_TR1_STD_HEADER(utility)
# endif
# ifdef BOOST_TR1_NO_CONFIG_RECURSION
# undef BOOST_TR1_NO_CONFIG_RECURSION
# undef BOOST_TR1_NO_RECURSION
# endif
#else
#include <boost/config/no_tr1/utility.hpp>
#endif
#endif
#if defined(__GLIBCXX__) && !defined(BOOST_TR1_PATH)
# define BOOST_TR1_PATH(name) tr1/name
#endif
#if !defined(BOOST_TR1_PATH)
# define BOOST_TR1_PATH(name) name
#endif
#define BOOST_TR1_HEADER(name) <BOOST_TR1_PATH(name)>
// Can't use BOOST_WORKAROUND here, it leads to recursive includes:
#if (defined(__BORLANDC__) && (__BORLANDC__ <= 0x600))
# define BOOST_TR1_USE_OLD_TUPLE
#endif
#ifdef __IBMCPP_TR1__
// turn on support for everything:
# define BOOST_HAS_TR1
#endif
#ifdef __GXX_EXPERIMENTAL_CXX0X__
# define BOOST_HAS_TR1_COMPLEX_OVERLOADS
# define BOOST_HAS_TR1_COMPLEX_INVERSE_TRIG
#endif
#ifdef BOOST_HAS_TR1
// turn on support for everything:
# define BOOST_HAS_TR1_ARRAY
# define BOOST_HAS_TR1_COMPLEX_OVERLOADS
# define BOOST_HAS_TR1_COMPLEX_INVERSE_TRIG
# define BOOST_HAS_TR1_REFERENCE_WRAPPER
# define BOOST_HAS_TR1_RESULT_OF
# define BOOST_HAS_TR1_MEM_FN
# define BOOST_HAS_TR1_BIND
# define BOOST_HAS_TR1_FUNCTION
# define BOOST_HAS_TR1_HASH
# define BOOST_HAS_TR1_SHARED_PTR
# define BOOST_HAS_TR1_RANDOM
# define BOOST_HAS_TR1_REGEX
# define BOOST_HAS_TR1_TUPLE
# define BOOST_HAS_TR1_TYPE_TRAITS
# define BOOST_HAS_TR1_UTILITY
# define BOOST_HAS_TR1_UNORDERED_MAP
# define BOOST_HAS_TR1_UNORDERED_SET
# define BOOST_HAS_TR1_CMATH
#endif
#if defined(__MWERKS__) && (__MWERKS__ >= 0x3205)
//
// Very preliminary MWCW support, may not be right:
//
# define BOOST_HAS_TR1_SHARED_PTR
# define BOOST_HAS_TR1_REFERENCE_WRAPPER
# define BOOST_HAS_TR1_FUNCTION
# define BOOST_HAS_TR1_TUPLE
# define BOOST_HAS_TR1_RESULT_OF
#endif
#ifdef BOOST_HAS_GCC_TR1
// turn on support for everything in gcc 4.0.x:
# define BOOST_HAS_TR1_ARRAY
#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
//# define BOOST_HAS_TR1_COMPLEX_OVERLOADS
# define BOOST_HAS_TR1_COMPLEX_INVERSE_TRIG
#endif
# define BOOST_HAS_TR1_REFERENCE_WRAPPER
# define BOOST_HAS_TR1_RESULT_OF
# define BOOST_HAS_TR1_MEM_FN
# define BOOST_HAS_TR1_BIND
# define BOOST_HAS_TR1_FUNCTION
# define BOOST_HAS_TR1_HASH
# define BOOST_HAS_TR1_SHARED_PTR
#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
# define BOOST_HAS_TR1_RANDOM
//# define BOOST_HAS_TR1_REGEX
#ifdef _GLIBCXX_USE_C99_MATH_TR1
# define BOOST_HAS_TR1_CMATH
#endif
#endif
# define BOOST_HAS_TR1_TUPLE
# define BOOST_HAS_TR1_TYPE_TRAITS
# define BOOST_HAS_TR1_UTILITY
# define BOOST_HAS_TR1_UNORDERED_MAP
# define BOOST_HAS_TR1_UNORDERED_SET
#endif
#if defined(_MSC_VER) && (_MSC_VER >= 1500) \
&& defined(_MSC_FULL_VER) && \
!defined(__SGI_STL_PORT) && \
!defined(_STLPORT_VERSION) && \
!defined(_RWSTD_VER_STR) && \
!defined(_RWSTD_VER)
//
// MSVC-9.0 defines a not-quite TR1 conforming hash
// function object in <functional>, so we must define
// this here, in addition the feature pack for VC9
// provides a more or less full TR1 implementation:
//
# if (defined(_HAS_TR1) && (_HAS_TR1 + 0)) || (_CPPLIB_VER >= 540)
# define BOOST_HAS_TR1_ARRAY
# define BOOST_HAS_TR1_REFERENCE_WRAPPER
# define BOOST_HAS_TR1_RESULT_OF
# define BOOST_HAS_TR1_MEM_FN
# define BOOST_HAS_TR1_BIND
# define BOOST_HAS_TR1_FUNCTION
# define BOOST_HAS_TR1_HASH
# define BOOST_HAS_TR1_SHARED_PTR
# define BOOST_HAS_TR1_RANDOM
# define BOOST_HAS_TR1_REGEX
# define BOOST_HAS_TR1_TUPLE
# define BOOST_HAS_TR1_TYPE_TRAITS
# define BOOST_HAS_TR1_UTILITY
# define BOOST_HAS_TR1_UNORDERED_MAP
# define BOOST_HAS_TR1_UNORDERED_SET
# else
# define BOOST_HAS_TR1_HASH
# endif
# if _MSC_VER >= 1600
# define BOOST_HAS_CPP_0X
# endif
# if _MSC_VER >= 1700
# define BOOST_HAS_TR1_COMPLEX_OVERLOADS
# endif
#endif
#include <boost/config.hpp>
#endif
+705
View File
@@ -0,0 +1,705 @@
# Boost.Build support specific for the Boost C++ Libraries.
# Copyright Vladimir Prus 2002-2010.
# Copyright Dave Abrahams 2005-2006.
# Copyright Rene Rivera 2005-2007.
# Copyright Douglas Gregor 2005.
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
import "class" : new ;
import common ;
import configure ;
import build-system ;
import generate ;
import modules ;
import option ;
import os ;
import package ;
import path ;
import project ;
import regex ;
import set ;
import targets ;
import feature ;
import property ;
##############################################################################
#
# 0. General setup. Parse options, check them.
#
##############################################################################
BOOST_ROOT = [ modules.binding $(__name__) ] ;
BOOST_ROOT = $(BOOST_ROOT:D) ;
rule set-version ( version )
{
BOOST_VERSION = $(version) ;
local version-tag = [ MATCH ^([^.]+)[.]([^.]+)[.]([^.]+) : $(BOOST_VERSION)
] ;
if $(version-tag[3]) = 0
{
version-tag = $(version-tag[1-2]) ;
}
BOOST_VERSION_TAG = $(version-tag:J=_) ;
}
# Option to choose how many variants to build. The default is "minimal".
build-type = [ option.get build-type ] ;
build-type ?= minimal ;
if ! ( $(build-type) in complete minimal )
{
EXIT The value of the --build-type option should be either 'complete' or
'minimal' ;
}
# What kind of layout are we doing?
layout = [ option.get layout : "" ] ;
# On Windows, we used versioned layout by default in order to be compatible with
# autolink. On other systems, we use system layout which is what every other
# program uses. Note that the Windows check is static, and will not be affected
# by specific build properties used.
if ! $(layout)
{
if [ os.name ] = NT
{
layout = versioned ;
}
else
{
layout = system ;
}
}
layout-$(layout) = true ;
if $(layout) = system && $(build-type) = complete
{
ECHO error: Cannot use --layout=system with --build-type complete. ;
ECHO error: Please use either --layout=versioned or --layout=tagged ;
ECHO error: if you wish to build multiple variants. ;
if [ os.name ] != NT
{
ECHO error: Note that --layout=system is used by default on Unix
starting with Boost 1.40. ;
}
EXIT ;
}
# Possible stage only location.
stage-locate = [ option.get stagedir ] ;
stage-locate ?= stage ;
BOOST_STAGE_LOCATE = $(stage-locate) ;
# Custom build ID.
build-id = [ option.get buildid ] ;
if $(build-id)
{
BUILD_ID = [ regex.replace $(build-id) "[*\\/:.\"\' ]" _ ] ;
}
# Python build id (for Python libraries only).
python-id = [ option.get "python-buildid" ] ;
if $(python-id)
{
PYTHON_ID = [ regex.replace $(python-id) [*\\/:.\"\'] _ ] ;
}
################################################################################
#
# 1. 'tag' function adding decorations suitable to the properties if versioned
# or tagged layout is requested. Called from Jamroot.
#
################################################################################
rule tag ( name : type ? : property-set )
{
if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB
{
local result ;
if $(layout) = versioned
{
result = [ common.format-name
<base> <toolset> <threading> <runtime> -$(BOOST_VERSION_TAG)
-$(BUILD_ID)
: $(name) : $(type) : $(property-set) ] ;
}
else if $(layout) = tagged
{
result = [ common.format-name
<base> <threading> <runtime>
-$(BUILD_ID)
: $(name) : $(type) : $(property-set) ] ;
}
else if $(layout) = system
{
result = [ common.format-name
<base>
-$(BUILD_ID)
: $(name) : $(type) : $(property-set) ] ;
}
else
{
EXIT error: invalid layout '$(layout:E=)' ;
}
# Optionally add version suffix. On NT, library with version suffix will
# not be recognized by linkers. On CYGWIN, we get strage duplicate
# symbol errors when library is generated with version suffix. On OSX,
# version suffix is not needed -- the linker expects the
# libFoo.1.2.3.dylib format. AIX linkers do not accept version suffixes
# either. Pgi compilers can not accept a library with version suffix.
if $(type) = SHARED_LIB &&
! [ $(property-set).get <target-os> ] in windows cygwin darwin aix &&
! [ $(property-set).get <toolset> ] in pgi
{
result = $(result).$(BOOST_VERSION) ;
}
return $(result) ;
}
}
# Specialized tag function to use for libraries linking to Python.
# Appends value of --python-buildid if provided.
rule python-tag ( name : type ? : property-set )
{
local result = $(name) ;
if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB && $(PYTHON_ID)
{
result = $(result)-$(PYTHON_ID) ;
}
# forward to the boost tagging rule
return [ tag $(result) : $(type) : $(property-set) ] ;
}
################################################################################
#
# 2. Declare targets that build and install all libraries. Specifically:
#
# - 'stage-proper' that puts all libraries in stage/lib
# - 'install-proper' that install libraries and headers to system location
# - 'stage-unversioned' that creates links to libraries without boost version
# in name
# - 'install-unversioned' which creates unversioned linked to installed
# libraries.
#
################################################################################
# Worker function suitable to the 'generate' metatarget. Creates a link to
# 'source', striping any version number information from the name.
rule make-unversioned-links ( project name ? : property-set : sources * )
{
local filter ;
if [ modules.peek : NT ]
{
filter = (.*[.]lib) ;
}
else
{
filter =
(.*[.]so)[.0-9]*
(.*[.]dylib)
(.*[.]a) ;
}
local result ;
for local s in $(sources)
{
local m = [ MATCH ^(.*)-[0-9_]+$(filter)$ : [ $(s).name ] ] ;
if $(m)
{
local ea = [ $(s).action ] ;
local ep = [ $(ea).properties ] ;
local a = [ new non-scanning-action $(s) : symlink.ln : $(ep) ] ;
result += [ new file-target $(m:J=) exact : [ $(s).type ] :
$(project) : $(a) ] ;
}
}
return $(result) ;
}
rule filtered-target ( name : message + : sources + : requirements * )
{
message $(name)-message : warning: $(message) ;
alias $(name) : $(sources) : $(requirements) ;
alias $(name) : $(name)-message ;
local p = [ project.current ] ;
$(p).mark-target-as-explicit $(name) ;
$(p).mark-target-as-explicit $(name)-message ;
}
rule declare_install_and_stage_proper_targets ( libraries * : headers * )
{
local p = [ project.current ] ;
for local l in $(libraries)
{
if $(l) = locale
{
filtered-target $(l)-for-install :
Skipping Boost.Locale library with threading=single. :
libs/$(l)/build : <threading>multi ;
}
else if $(l) = wave
{
filtered-target $(l)-for-install :
Skipping Boost.Wave library with threading=single. :
libs/$(l)/build : <threading>multi ;
}
else if $(l) = thread
{
filtered-target $(l)-for-install :
Skipping Boost.Thread library with threading=single. :
libs/$(l)/build : <threading>multi ;
}
else
{
alias $(l)-for-install : libs/$(l)/build ;
$(p).mark-target-as-explicit $(l)-for-install ;
}
}
local library-targets = $(libraries)-for-install ;
install-requirements = <install-source-root>$(BOOST_ROOT)/boost ;
if $(layout-versioned)
{
install-requirements +=
<install-header-subdir>boost-$(BOOST_VERSION_TAG)/boost ;
}
else
{
install-requirements += <install-header-subdir>boost ;
}
if [ os.name ] = NT
{
install-requirements += <install-default-prefix>C:/Boost ;
}
else
{
install-requirements += <install-default-prefix>/usr/local ;
}
p = [ project.current ] ;
# Complete install.
package.install install-proper
: $(install-requirements) <install-no-version-symlinks>on
:
: $(libraries)-for-install
: $(headers)
;
$(p).mark-target-as-explicit install-proper ;
# Install just library.
install stage-proper
: $(libraries)-for-install
: <location>$(stage-locate)/lib
<install-dependencies>on <install-type>LIB
<install-no-version-symlinks>on
;
$(p).mark-target-as-explicit stage-proper ;
# Commented out as it does not seem to work. Whoever wrote this originally,
# left some typos in the code, but when that got corrected and the code got
# enabled - it started reporting ambiguous/duplicate target Boost Build
# errors. Anyone requiring unversioned staged libraries needs to correct
# those errors before reenabling this code. For more detailed information
# see the related Boost library development mailing list thread at
# 'http://lists.boost.org/Archives/boost/2012/06/194312.php'.
# (06.07.2012.) (Jurko)
#~ if $(layout-versioned) && ( [ modules.peek : NT ] || [ modules.peek : UNIX ] )
#~ {
#~ generate stage-unversioned : stage-proper :
#~ <generating-rule>@boostcpp.make-unversioned-links ;
#~ $(p).mark-target-as-explicit stage-unversioned ;
#~
#~ generate install-unversioned : install-proper :
#~ <generating-rule>@boostcpp.make-unversioned-links ;
#~ $(p).mark-target-as-explicit install-unversioned ;
#~ }
#~ else
{
# Create do-nothing aliases.
alias stage-unversioned ;
$(p).mark-target-as-explicit stage-unversioned ;
alias install-unversioned ;
$(p).mark-target-as-explicit install-unversioned ;
}
}
################################################################################
#
# 3. Declare top-level targets 'stage' and 'install'. These examine the
# --build-type option and, in case it is 'complete', build the 'install-proper'
# and 'stage-proper' targets with a number of property sets.
#
################################################################################
class top-level-target : alias-target-class
{
import modules ;
rule __init__ ( name : project : sources * : requirements *
: default-build * : usage-requirements * )
{
alias-target-class.__init__ $(name) : $(project) : $(sources) :
$(requirements) : $(default-build) : $(usage-requirements) ;
self.build-type = [ modules.peek boostcpp : build-type ] ;
# On Linux, we build the release variant by default, since few users
# will ever want to debug C++ Boost libraries, and there is no ABI
# incompatibility between debug and release variants. We build shared
# and static libraries since that is what most packages seem to provide
# (.so in libfoo and .a in libfoo-dev).
self.minimal-properties = [ property-set.create <variant>release
<threading>multi <link>shared <link>static <runtime-link>shared ] ;
# On Windows, new IDE projects use:
#
# runtime-link=dynamic, threading=multi, variant=(debug|release)
#
# and in addition, C++ Boost's autolink defaults to static linking.
self.minimal-properties-win = [ property-set.create <variant>debug
<variant>release <threading>multi <link>static <runtime-link>shared
] ;
self.complete-properties = [ property-set.create
<variant>debug <variant>release
<threading>single <threading>multi
<link>shared <link>static
<runtime-link>shared <runtime-link>static ] ;
}
rule generate ( property-set )
{
modules.poke : top-level-targets : [ modules.peek : top-level-targets ]
$(self.name) ;
if $(self.build-type) = minimal
{
local expanded ;
local os = [ $(property-set).get <target-os> ] ;
# Because we completely override the parent's 'generate' we need to
# check for default feature values ourselves.
if ! $(os)
{
os = [ feature.defaults <target-os> ] ;
os = $(os:G=) ;
}
if $(os) = windows
{
expanded = [ targets.apply-default-build $(property-set)
: $(self.minimal-properties-win) ] ;
}
else
{
expanded = [ targets.apply-default-build $(property-set)
: $(self.minimal-properties) ] ;
}
return [ build-multiple $(expanded) ] ;
}
else if $(self.build-type) = complete
{
local expanded = [ targets.apply-default-build $(property-set)
: $(self.complete-properties) ] ;
# Filter inappopriate combinations.
local filtered ;
for local p in $(expanded)
{
# See comment in handle-static-runtime regarding this logic.
if [ $(p).get <link> ] = shared
&& [ $(p).get <runtime-link> ] = static
&& [ $(p).get <toolset> ] != cw
{
# Skip this.
}
else
{
filtered += $(p) ;
}
}
return [ build-multiple $(filtered) ] ;
}
else
{
import errors ;
errors.error "Unknown build type" ;
}
}
rule build-multiple ( property-sets * )
{
local usage-requirements = [ property-set.empty ] ;
local result ;
for local p in $(property-sets)
{
local r = [ alias-target-class.generate $(p) ] ;
if $(r)
{
usage-requirements = [ $(usage-requirements).add $(r[1]) ] ;
result += $(r[2-]) ;
}
}
return $(usage-requirements) [ sequence.unique $(result) ] ;
}
}
rule declare_top_level_targets ( libraries * : headers * )
{
declare_install_and_stage_proper_targets $(libraries) : $(headers) ;
targets.create-metatarget top-level-target : [ project.current ]
: install
: install-proper install-unversioned
;
targets.create-metatarget top-level-target : [ project.current ]
: stage
: stage-proper stage-unversioned
;
p = [ project.current ] ;
$(p).mark-target-as-explicit install stage ;
# This target is built by default, and will forward to 'stage' after
# producing some explanations.
targets.create-metatarget top-level-target : [ project.current ]
: forward
: explain stage
;
}
stage-abs = [ path.native [ path.root $(stage-locate)/lib [ path.pwd ] ] ] ;
################################################################################
#
# 4. Add hook to report configuration before the build, and confirmation with
# setup instructions after the build.
#
################################################################################
message explain : "\nBuilding the Boost C++ Libraries.\n\n" ;
local p = [ project.current ] ;
$(p).mark-target-as-explicit explain ;
rule pre-build ( )
{
local tl = [ modules.peek : top-level-targets ] ;
if stage in $(tl) || install in $(tl)
{
# FIXME: Remove 'if' when Boost regression tests start using trunk bjam.
if PAD in [ RULENAMES ]
{
configure.print-component-configuration ;
}
}
}
IMPORT $(__name__) : pre-build : : $(__name__).pre-build ;
build-system.set-pre-build-hook $(__name__).pre-build ;
# FIXME: Revise stage_abs.
rule post-build ( ok ? )
{
if forward in [ modules.peek : top-level-targets ]
{
if $(ok)
{
local include-path = [ path.native $(BOOST_ROOT) ] ;
ECHO "
The Boost C++ Libraries were successfully built!
The following directory should be added to compiler include paths:
$(include-path)
The following directory should be added to linker library paths:
$(stage-abs)
" ;
}
}
}
IMPORT $(__name__) : post-build : : $(__name__).post-build ;
build-system.set-post-build-hook $(__name__).post-build ;
################################################################################
#
# 5. Top-level setup.
#
################################################################################
# Decides which libraries are to be installed by looking at --with-<library>
# --without-<library> arguments. Returns the list of directories under "libs"
# which must be built and installed.
#
rule libraries-to-install ( existing-libs * )
{
local argv = [ modules.peek : ARGV ] ;
local with-parameter = [ MATCH ^--with-(.*) : $(argv) ] ;
local without-parameter = [ MATCH ^--without-(.*) : $(argv) ] ;
if ! $(with-parameter) && ! $(without-parameter)
{
# Nothing is specified on command line. See if maybe project-config.jam
# has some choices.
local libs = [ modules.peek project-config : libraries ] ;
with-parameter = [ MATCH ^--with-(.*) : $(libs) ] ;
without-parameter = [ MATCH ^--without-(.*) : $(libs) ] ;
}
# Do some checks.
if $(with-parameter) && $(without-parameter)
{
EXIT error: both --with-<library> and --without-<library> specified ;
}
local wrong = [ set.difference $(with-parameter) : $(existing-libs) ] ;
if $(wrong)
{
EXIT error: wrong library name '$(wrong[1])' in the --with-<library>
option. ;
}
local wrong = [ set.difference $(without-parameter) : $(existing-libs) ] ;
if $(wrong)
{
EXIT error: wrong library name '$(wrong[1])' in the --without-<library>
option. ;
}
if $(with-parameter)
{
return [ set.intersection $(existing-libs) : $(with-parameter) ] ;
}
else
{
return [ set.difference $(existing-libs) : $(without-parameter) ] ;
}
}
rule declare-targets ( all-libraries * : headers * )
{
configure.register-components $(all-libraries) ;
# Select the libraries to install.
libraries = [ libraries-to-install $(all-libraries) ] ;
configure.components-building $(libraries) ;
if [ option.get "show-libraries" : : true ]
{
ECHO The following libraries require building: ;
for local l in $(libraries)
{
ECHO " - $(l)" ;
}
EXIT ;
}
declare_top_level_targets $(libraries) : $(headers) ;
}
# Returns the properties identifying the toolset. We'll use them
# below to configure checks. These are essentially same as in
# configure.builds, except we don't use address-model and
# architecture - as we're trying to detect them here.
#
rule toolset-properties ( properties * )
{
local toolset = [ property.select <toolset> : $(properties) ] ;
local toolset-version-property = "<toolset-$(toolset:G=):version>" ;
return [ property.select <target-os> <toolset> $(toolset-version-property) : $(properties) ] ;
}
feature.feature deduced-address-model : 32 64 : propagated optional composite hidden ;
feature.compose <deduced-address-model>32 : <address-model>32 ;
feature.compose <deduced-address-model>64 : <address-model>64 ;
rule deduce-address-model ( properties * )
{
local result ;
local filtered = [ toolset-properties $(properties) ] ;
if [ configure.builds /boost/architecture//32 : $(filtered) : 32-bit ]
{
result = 32 ;
}
else if [ configure.builds /boost/architecture//64 : $(filtered) : 64-bit ]
{
result = 64 ;
}
if $(result)
{
# Normally, returning composite feature here is equivalent to forcing
# consituent properties as well. But we only want to indicate toolset
# deduced default, so also pick whatever address-model is explicitly
# specified, if any.
result = <deduced-address-model>$(result) [ property.select <address-model> : $(properties) ] ;
}
return $(result) ;
}
rule address-model ( )
{
return <conditional>@boostcpp.deduce-address-model ;
}
local deducable-architectures = arm mips1 power sparc x86 combined ;
feature.feature deduced-architecture : $(deducable-architectures) : propagated optional composite hidden ;
for a in $(deducable-architectures)
{
feature.compose <deduced-architecture>$(a) : <architecture>$(a) ;
}
rule deduce-architecture ( properties * )
{
local result ;
local filtered = [ toolset-properties $(properties) ] ;
if [ configure.builds /boost/architecture//arm : $(filtered) : arm ]
{
result = arm ;
}
else if [ configure.builds /boost/architecture//mips1 : $(filtered) : mips1 ]
{
result = mips1 ;
}
else if [ configure.builds /boost/architecture//power : $(filtered) : power ]
{
result = power ;
}
else if [ configure.builds /boost/architecture//sparc : $(filtered) : sparc ]
{
result = sparc ;
}
else if [ configure.builds /boost/architecture//x86 : $(filtered) : x86 ]
{
result = x86 ;
}
else if [ configure.builds /boost/architecture//combined : $(filtered) : combined ]
{
result = combined ;
}
if $(result)
{
# See comment in deduce-address-model.
result = <deduced-architecture>$(result) [ property.select <architecture> : $(properties) ] ;
}
return $(result) ;
}
rule architecture ( )
{
return <conditional>@boostcpp.deduce-architecture ;
}
+81
View File
@@ -0,0 +1,81 @@
@ECHO OFF
REM Copyright (C) 2009 Vladimir Prus
REM
REM Distributed under the Boost Software License, Version 1.0.
REM (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
ECHO Building Boost.Build engine
if exist ".\tools\build\src\engine\bin.ntx86\b2.exe" del tools\build\src\engine\bin.ntx86\b2.exe
if exist ".\tools\build\src\engine\bin.ntx86\bjam.exe" del tools\build\src\engine\bin.ntx86\bjam.exe
if exist ".\tools\build\src\engine\bin.ntx86_64\b2.exe" del tools\build\src\engine\bin.ntx86_64\b2.exe
if exist ".\tools\build\src\engine\bin.ntx86_64\bjam.exe" del tools\build\src\engine\bin.ntx86_64\bjam.exe
pushd tools\build\src\engine
call .\build.bat %* > ..\..\..\..\bootstrap.log
@ECHO OFF
popd
if exist ".\tools\build\src\engine\bin.ntx86\bjam.exe" (
copy .\tools\build\src\engine\bin.ntx86\b2.exe . > nul
copy .\tools\build\src\engine\bin.ntx86\bjam.exe . > nul
goto :bjam_built)
if exist ".\tools\build\src\engine\bin.ntx86_64\bjam.exe" (
copy .\tools\build\src\engine\bin.ntx86_64\b2.exe . > nul
copy .\tools\build\src\engine\bin.ntx86_64\bjam.exe . > nul
goto :bjam_built)
goto :bjam_failure
:bjam_built
REM Ideally, we should obtain the toolset that build.bat has
REM guessed. However, it uses setlocal at the start and does not
REM export BOOST_JAM_TOOLSET, and I don't know how to do that
REM properly. Default to msvc for now.
set toolset=msvc
ECHO import option ; > project-config.jam
ECHO. >> project-config.jam
ECHO using %toolset% ; >> project-config.jam
ECHO. >> project-config.jam
ECHO option.set keep-going : false ; >> project-config.jam
ECHO. >> project-config.jam
ECHO.
ECHO Bootstrapping is done. To build, run:
ECHO.
ECHO .\b2
ECHO.
ECHO To adjust configuration, edit 'project-config.jam'.
ECHO Further information:
ECHO.
ECHO - Command line help:
ECHO .\b2 --help
ECHO.
ECHO - Getting started guide:
ECHO http://boost.org/more/getting_started/windows.html
ECHO.
ECHO - Boost.Build documentation:
ECHO http://www.boost.org/build/doc/html/index.html
goto :end
:bjam_failure
ECHO.
ECHO Failed to build Boost.Build engine.
ECHO Please consult bootstrap.log for further diagnostics.
ECHO.
ECHO You can try to obtain a prebuilt binary from
ECHO.
ECHO http://sf.net/project/showfiles.php?group_id=7586^&package_id=72941
ECHO.
ECHO Also, you can file an issue at http://svn.boost.org
ECHO Please attach bootstrap.log in that case.
goto :end
:end
+409
View File
@@ -0,0 +1,409 @@
#!/bin/sh
# Copyright (C) 2005, 2006 Douglas Gregor.
# Copyright (C) 2006 The Trustees of Indiana University
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
# boostinspect:notab - Tabs are required for the Makefile.
BJAM=""
TOOLSET=""
BJAM_CONFIG=""
BUILD=""
PREFIX=/usr/local
EPREFIX=
LIBDIR=
INCLUDEDIR=
LIBS=""
PYTHON=python
PYTHON_VERSION=
PYTHON_ROOT=
ICU_ROOT=
# Handle case where builtin shell version of echo command doesn't
# support -n. Use the installed echo executable if there is one
# rather than builtin version to ensure -n is supported.
ECHO=`which echo`
if test "x$ECHO" = x; then
ECHO=echo
fi
# Internal flags
flag_no_python=
flag_icu=
flag_show_libraries=
for option
do
case $option in
-help | --help | -h)
want_help=yes ;;
-prefix=* | --prefix=*)
PREFIX=`expr "x$option" : "x-*prefix=\(.*\)"`
;;
-exec-prefix=* | --exec-prefix=*)
EPREFIX=`expr "x$option" : "x-*exec-prefix=\(.*\)"`
;;
-libdir=* | --libdir=*)
LIBDIR=`expr "x$option" : "x-*libdir=\(.*\)"`
;;
-includedir=* | --includedir=*)
INCLUDEDIR=`expr "x$option" : "x-*includedir=\(.*\)"`
;;
-show-libraries | --show-libraries )
flag_show_libraries=yes
;;
-with-bjam=* | --with-bjam=* )
BJAM=`expr "x$option" : "x-*with-bjam=\(.*\)"`
;;
-with-icu | --with-icu )
flag_icu=yes
;;
-with-icu=* | --with-icu=* )
flag_icu=yes
ICU_ROOT=`expr "x$option" : "x-*with-icu=\(.*\)"`
;;
-without-icu | --without-icu )
flag_icu=no
;;
-with-libraries=* | --with-libraries=* )
library_list=`expr "x$option" : "x-*with-libraries=\(.*\)"`
if test "$library_list" != "all"; then
old_IFS=$IFS
IFS=,
for library in $library_list
do
LIBS="$LIBS --with-$library"
if test $library = python; then
requested_python=yes
fi
done
IFS=$old_IFS
if test "x$requested_python" != xyes; then
flag_no_python=yes
fi
fi
;;
-without-libraries=* | --without-libraries=* )
library_list=`expr "x$option" : "x-*without-libraries=\(.*\)"`
old_IFS=$IFS
IFS=,
for library in $library_list
do
LIBS="$LIBS --without-$library"
if test $library = python; then
flag_no_python=yes
fi
done
IFS=$old_IFS
;;
-with-python=* | --with-python=* )
PYTHON=`expr "x$option" : "x-*with-python=\(.*\)"`
;;
-with-python-root=* | --with-python-root=* )
PYTHON_ROOT=`expr "x$option" : "x-*with-python-root=\(.*\)"`
;;
-with-python-version=* | --with-python-version=* )
PYTHON_VERSION=`expr "x$option" : "x-*with-python-version=\(.*\)"`
;;
-with-toolset=* | --with-toolset=* )
TOOLSET=`expr "x$option" : "x-*with-toolset=\(.*\)"`
;;
-*)
{ echo "error: unrecognized option: $option
Try \`$0 --help' for more information." >&2
{ (exit 1); exit 1; }; }
;;
esac
done
if test "x$want_help" = xyes; then
cat <<EOF
\`./bootstrap.sh' prepares Boost for building on a few kinds of systems.
Usage: $0 [OPTION]...
Defaults for the options are specified in brackets.
Configuration:
-h, --help display this help and exit
--with-bjam=BJAM use existing Boost.Jam executable (bjam)
[automatically built]
--with-toolset=TOOLSET use specific Boost.Build toolset
[automatically detected]
--show-libraries show the set of libraries that require build
and installation steps (i.e., those libraries
that can be used with --with-libraries or
--without-libraries), then exit
--with-libraries=list build only a particular set of libraries,
describing using either a comma-separated list of
library names or "all"
[all]
--without-libraries=list build all libraries except the ones listed []
--with-icu enable Unicode/ICU support in Regex
[automatically detected]
--without-icu disable Unicode/ICU support in Regex
--with-icu=DIR specify the root of the ICU library installation
and enable Unicode/ICU support in Regex
[automatically detected]
--with-python=PYTHON specify the Python executable [python]
--with-python-root=DIR specify the root of the Python installation
[automatically detected]
--with-python-version=X.Y specify the Python version as X.Y
[automatically detected]
Installation directories:
--prefix=PREFIX install Boost into the given PREFIX
[/usr/local]
--exec-prefix=EPREFIX install Boost binaries into the given EPREFIX
[PREFIX]
More precise control over installation directories:
--libdir=DIR install libraries here [EPREFIX/lib]
--includedir=DIR install headers here [PREFIX/include]
EOF
fi
test -n "$want_help" && exit 0
# TBD: Determine where the script is located
my_dir="."
# Determine the toolset, if not already decided
if test "x$TOOLSET" = x; then
guessed_toolset=`$my_dir/tools/build/src/engine/build.sh --guess-toolset`
case $guessed_toolset in
acc | darwin | gcc | como | mipspro | pathscale | pgi | qcc | vacpp )
TOOLSET=$guessed_toolset
;;
intel-* )
TOOLSET=intel
;;
mingw )
TOOLSET=gcc
;;
sun* )
TOOLSET=sun
;;
* )
# Not supported by Boost.Build
;;
esac
fi
rm -f config.log
# Build bjam
if test "x$BJAM" = x; then
$ECHO -n "Building Boost.Build engine with toolset $TOOLSET... "
pwd=`pwd`
(cd "$my_dir/tools/build/src/engine" && ./build.sh "$TOOLSET") > bootstrap.log 2>&1
if [ $? -ne 0 ]; then
echo
echo "Failed to build Boost.Build build engine"
echo "Consult 'bootstrap.log' for more details"
exit 1
fi
cd "$pwd"
arch=`cd $my_dir/tools/build/src/engine && ./bootstrap/jam0 -d0 -f build.jam --toolset=$TOOLSET --toolset-root= --show-locate-target && cd ..`
BJAM="$my_dir/tools/build/src/engine/$arch/b2"
echo "tools/build/src/engine/$arch/b2"
cp "$BJAM" .
cp "$my_dir/tools/build/src/engine/$arch/bjam" .
fi
# TBD: Turn BJAM into an absolute path
# If there is a list of libraries
if test "x$flag_show_libraries" = xyes; then
cat <<EOF
The following Boost libraries have portions that require a separate build
and installation step. Any library not listed here can be used by including
the headers only.
The Boost libraries requiring separate building and installation are:
EOF
$BJAM -d0 --show-libraries | grep '^[[:space:]]*-'
exit 0
fi
# Setup paths
if test "x$EPREFIX" = x; then
EPREFIX="$PREFIX"
fi
if test "x$LIBDIR" = x; then
LIBDIR="$EPREFIX/lib"
fi
if test "x$INCLUDEDIR" = x; then
INCLUDEDIR="$PREFIX/include"
fi
# Find Python
if test "x$flag_no_python" = x; then
result=`$PYTHON -c "exit" > /dev/null 2>&1`
if [ "$?" -ne "0" ]; then
flag_no_python=yes
fi
fi
if test "x$flag_no_python" = x; then
if test "x$PYTHON_VERSION" = x; then
$ECHO -n "Detecting Python version... "
PYTHON_VERSION=`$PYTHON -c "import sys; print (\"%d.%d\" % (sys.version_info[0], sys.version_info[1]))"`
echo $PYTHON_VERSION
fi
if test "x$PYTHON_ROOT" = x; then
$ECHO -n "Detecting Python root... "
PYTHON_ROOT=`$PYTHON -c "import sys; print(sys.prefix)"`
echo $PYTHON_ROOT
fi
fi
# Configure ICU
$ECHO -n "Unicode/ICU support for Boost.Regex?... "
if test "x$flag_icu" != xno; then
if test "x$ICU_ROOT" = x; then
COMMON_ICU_PATHS="/usr /usr/local /sw"
for p in $COMMON_ICU_PATHS; do
if test -r $p/include/unicode/utypes.h; then
ICU_ROOT=$p
fi
done
if test "x$ICU_ROOT" = x; then
echo "not found."
else
BJAM_CONFIG="$BJAM_CONFIG -sICU_PATH=$ICU_ROOT"
echo "$ICU_ROOT"
fi
else
BJAM_CONFIG="$BJAM_CONFIG -sICU_PATH=$ICU_ROOT"
echo "$ICU_ROOT"
fi
else
echo "disabled."
fi
# Backup the user's existing project-config.jam
JAM_CONFIG_OUT="project-config.jam"
if test -r "project-config.jam"; then
counter=1
while test -r "project-config.jam.$counter"; do
counter=`expr $counter + 1`
done
echo "Backing up existing Boost.Build configuration in project-config.jam.$counter"
mv "project-config.jam" "project-config.jam.$counter"
fi
# Generate user-config.jam
echo "Generating Boost.Build configuration in project-config.jam..."
cat > project-config.jam <<EOF
# Boost.Build Configuration
# Automatically generated by bootstrap.sh
import option ;
import feature ;
# Compiler configuration. This definition will be used unless
# you already have defined some toolsets in your user-config.jam
# file.
if ! $TOOLSET in [ feature.values <toolset> ]
{
using $TOOLSET ;
}
project : default-build <toolset>$TOOLSET ;
EOF
# - Python configuration
if test "x$flag_no_python" = x; then
cat >> project-config.jam <<EOF
# Python configuration
import python ;
if ! [ python.configured ]
{
using python : $PYTHON_VERSION : $PYTHON_ROOT ;
}
EOF
fi
if test "x$ICU_ROOT" != x; then
cat >> project-config.jam << EOF
path-constant ICU_PATH : $ICU_ROOT ;
EOF
fi
cat >> project-config.jam << EOF
# List of --with-<library> and --without-<library>
# options. If left empty, all libraries will be built.
# Options specified on the command line completely
# override this variable.
libraries = $LIBS ;
# These settings are equivivalent to corresponding command-line
# options.
option.set prefix : $PREFIX ;
option.set exec-prefix : $EPREFIX ;
option.set libdir : $LIBDIR ;
option.set includedir : $INCLUDEDIR ;
# Stop on first error
option.set keep-going : false ;
EOF
cat << EOF
Bootstrapping is done. To build, run:
./b2
To adjust configuration, edit 'project-config.jam'.
Further information:
- Command line help:
./b2 --help
- Getting started guide:
http://www.boost.org/more/getting_started/unix-variants.html
- Boost.Build documentation:
http://www.boost.org/build/doc/html/index.html
EOF
+149
View File
@@ -0,0 +1,149 @@
@import url("doc/src/boostbook.css");
@import url("doc/src/docutils.css");
/* Copyright David Abrahams 2006. Distributed under the Boost
Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
dl.docutils dt {
font-weight: bold }
img.boost-logo {
border: none;
vertical-align: middle
}
pre.literal-block span.concept {
font-style: italic;
}
.nav {
display: inline;
list-style-type: none;
}
.prevpage {
padding-top: -5px;
text-align: left;
float: left;
}
.nextpage {
padding-top: -20px;
text-align: right;
float: right;
}
div.small {
font-size: smaller }
h2 a {
font-size: 90%;
}
h3 a {
font-size: 80%;
}
h4 a {
font-size: 70%;
}
h5 a {
font-size: 60%;
}
dl,table
{
text-align: left;
font-size: 10pt;
line-height: 1.15;
}
/*=============================================================================
Tables
=============================================================================*/
/* The only clue docutils gives us that tables are logically tables,
and not, e.g., footnotes, is that they have border="1". Therefore
we're keying off of that. We used to manually patch docutils to
add a "table" class to all logical tables, but that proved much too
fragile.
*/
table[border="1"]
{
width: 92%;
margin-left: 4%;
margin-right: 4%;
}
table[border="1"]
{
padding: 4px;
}
/* Table Cells */
table[border="1"] tr td
{
padding: 0.5em;
text-align: left;
font-size: 9pt;
}
table[border="1"] tr th
{
padding: 0.5em 0.5em 0.5em 0.5em;
border: 1pt solid white;
font-size: 80%;
}
@media screen
{
/* Tables */
table[border="1"] tr td
{
border: 1px solid #DCDCDC;
}
table[border="1"] tr th
{
background-color: #F0F0F0;
border: 1px solid #DCDCDC;
}
pre,
.screen
{
border: 1px solid #DCDCDC;
}
td pre
td .screen
{
border: 0px
}
.sidebar pre
{
border: 0px
}
}
pre,
.screen
{
font-size: 9pt;
display: block;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
/* Program listings in tables don't get borders */
td pre,
td .screen
{
margin: 0pc 0pc 0pc 0pc;
padding: 0pc 0pc 0pc 0pc;
}
+12 -1
View File
@@ -41,7 +41,9 @@ extern struct dec_data {
int nsubmode;
bool nagain;
int ndepth;
bool lapon;
bool lft8apon;
bool lapcqonly;
bool ljt65apon;
int napwid;
int ntxmode;
int nmode;
@@ -78,6 +80,15 @@ extern struct {
float red[4096];
} echocom_;
extern struct {
float wave[606720];
int nslots;
int nfreq;
int i3bit[5];
char cmsg[5][40];
char mycall[12];
} foxcom_;
#ifdef __cplusplus
}
#endif
+1699
View File
File diff suppressed because it is too large Load Diff
+940 -880
View File
File diff suppressed because it is too large Load Diff
+105 -2
View File
@@ -4,8 +4,10 @@
#include <QRegularExpression>
#include <QDebug>
#include <varicode.h>
extern "C" {
bool stdmsg_(char const * msg, bool contest_mode, char const * mygrid, int len_msg, int len_grid);
bool stdmsg_(char const * msg, bool contest_mode, char const * mygrid, fortran_charlen_t, fortran_charlen_t);
}
namespace
@@ -50,8 +52,109 @@ DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString
, contest_mode_
, grid_c_string.constData ()
, 22, 6);
// We're only going to unpack standard messages for CQs && beacons...
// TODO: jsherer - this is a hack for now...
if(is_standard_){
is_standard_ = QRegularExpression("^(CQ|DE|QRZ)\\s").match(message_).hasMatch();
}
}
};
tryUnpack();
}
DecodedText::DecodedText (QString const& ft8callmessage){
message_ = ft8callmessage;
is_standard_ = false;
tryUnpack();
}
bool DecodedText::tryUnpack(){
if(is_standard_){
return false;
}
bool unpacked = false;
if(!unpacked){
unpacked = tryUnpackCompound();
}
if(!unpacked){
unpacked = tryUnpackDirected();
}
if(!unpacked){
unpacked = tryUnpackData();
}
return unpacked;
}
bool DecodedText::tryUnpackCompound(){
QString m = message().trimmed();
// directed calls will always be 12+ chars and contain no spaces.
if(m.length() < 12 || m.contains(' ')){
return false;
}
QStringList parts = Varicode::unpackCompoundMessage(m, nullptr);
if(parts.isEmpty() || parts.length() < 2){
return false;
}
compound_ = QString("%1/%2").arg(parts.at(0), parts.at(1));
message_ = QString("%1: ").arg(compound_);
return true;
}
bool DecodedText::tryUnpackDirected(){
QString m = message().trimmed();
// directed calls will always be 12+ chars and contain no spaces.
if(m.length() < 12 || m.contains(' ')){
return false;
}
QStringList parts = Varicode::unpackDirectedMessage(m);
if(parts.isEmpty()){
return false;
}
if(parts.length() == 3){
// replace it with the correct unpacked (directed)
message_ = QString("%1: %2%3 ").arg(parts.at(0), parts.at(1), parts.at(2));
} else if(parts.length() == 4){
// replace it with the correct unpacked (directed numeric)
message_ = QString("%1: %2%3 %4 ").arg(parts.at(0), parts.at(1), parts.at(2), parts.at(3));
} else {
// replace it with the correct unpacked (freetext)
message_ = QString(parts.join(""));
}
directed_ = parts;
return true;
}
bool DecodedText::tryUnpackData(){
QString m = message().trimmed();
// data frames calls will always be 12+ chars and contain no spaces.
if(m.length() < 12 || m.contains(' ')){
return false;
}
QString data = Varicode::unpackDataMessage(m);
if(data.isEmpty()){
return false;
}
message_ = data;
return true;
}
QStringList DecodedText::messageWords () const
{
+24 -6
View File
@@ -10,6 +10,7 @@
#define DECODEDTEXT_H
#include <QString>
#include <QStringList>
@@ -30,15 +31,28 @@ class DecodedText
{
public:
explicit DecodedText (QString const& message, bool, QString const& my_grid);
explicit DecodedText (QString const& ft8callmessage);
QString string() const { return string_; };
bool tryUnpack();
bool tryUnpackCompound();
bool tryUnpackDirected();
bool tryUnpackData();
QString compoundCall() const { return compound_; }
bool isCompoundMessage() const { return !compound_.isEmpty(); }
QStringList directedMessage() const { return directed_; }
bool isDirectedMessage() const { return !directed_.isEmpty() && directed_.length() > 2; }
QString string() const { return string_; }
QString message() const { return message_; }
QStringList messageWords () const;
int indexOf(QString s) const { return string_.indexOf(s); };
int indexOf(QString s, int i) const { return string_.indexOf(s,i); };
QString mid(int f, int t) const { return string_.mid(f,t); };
QString left(int i) const { return string_.left(i); };
int indexOf(QString s) const { return string_.indexOf(s); }
int indexOf(QString s, int i) const { return string_.indexOf(s,i); }
QString mid(int f, int t) const { return string_.mid(f,t); }
QString left(int i) const { return string_.left(i); }
void clear() { string_.clear(); };
void clear() { string_.clear(); }
QString CQersCall() const;
@@ -49,6 +63,8 @@ public:
bool isLowConfidence () const;
int frequencyOffset() const; // hertz offset from the tuned dial or rx frequency, aka audio frequency
int snr() const;
bool hasBits() const { return !string_.right(5).trimmed().isEmpty(); }
int bits() const { return string_.right(5).trimmed().toShort(); }
float dt() const;
// find and extract any report. Returns true if this is a standard message
@@ -75,6 +91,8 @@ private:
column_mode = 19,
column_qsoText = 22 };
QString compound_;
QStringList directed_;
QString string_;
int padding_;
bool contest_mode_;
+62
View File
@@ -0,0 +1,62 @@
Here are the "displayWidgets()" strings for WSJT-X modes
1 2 3
012345678901234567890123456789012
----------------------------------------------
JT4 111010000000111000110000000000000
JT4/VHF 111110010010111110111100000000000
JT9 111010000000111000010000000000001
JT9/VHF 111110101000111110010000000000000
JT9+JT65 111010000001111000010000000000001
JT65 111010000000111000010000000000001
JT65/VHF 111110010000111110101100010000000
QRA64 111110010110111110000000001000000
ISCAT 100111000000000110000000000000000
MSK144 101111110100000000010001000010000
WSPR 000000000000000001010000000000000
Echo 000000000000000000000010000000000
FCal 001101000000000000000000000001000
FT8 111010000100111000010000100100001
FT8/VHF 111010000100111000010000100110001
FT8/Fox 111010000100111000010000000000100
FT8/Hound 111010000100111000010000000000110
----------------------------------------------
1 2 3
012345678901234567890123456789012
----------------------------------------------
Mapping of column numbers to widgets
----------------------------------------------
0. txFirstCheckbox
1. TxFreqSpinBox
2. RxFreqSpinBox
3. sbFtol
4. rptSpinBox
5. sbTR
6. sbCQTxFreq, cbCQTx
7. cbShMsgs
8. cbFast9
9. cbAutoSeq
10. cbTx6
11. pbTxMode
12. pbR2T
13. pbT2R
14. cbHoldTxFreq
15. sbSubmode
16. syncSpinBox
17. WSPR_Controls_Widget
18. ClrAvgButton
19. Fast/Normal/Deep
20. Include Avg
21. Include Deep Search
22. Echo Graph
23. cbSWL
24. AP FT8
25. AP JT65
26. AP DX Call
27. cbFirst
28. cbVHFcontest
29. measure_check_box
30. labDXped
31. cbRxAll
32. cbCQonly
+39 -22
View File
@@ -1,5 +1,5 @@
#include "displaytext.h"
#include "mainwindow.h"
#include <QMouseEvent>
#include <QDateTime>
#include <QTextCharFormat>
@@ -121,7 +121,6 @@ QString DisplayText::appendDXCCWorkedB4(QString message, QString const& callsign
if(!call.contains(QRegExp("[0-9]|[A-Z]"))) return message;
logBook.match(/*in*/call,/*out*/countryName,callWorkedBefore,countryWorkedBefore);
message = message.trimmed ();
QString appendage;
if (!countryWorkedBefore) // therefore not worked call either
@@ -143,25 +142,32 @@ QString DisplayText::appendDXCCWorkedB4(QString message, QString const& callsign
}
}
int i1=countryName.indexOf(";");
if(m_bPrincipalPrefix) {
int i2=countryName.lastIndexOf(";");
if(i1>0) countryName=countryName.mid(i1+2,i2-i1-2);
} else {
if(i1>0) countryName=countryName.mid(0,i1);
// do some obvious abbreviations
countryName.replace ("Islands", "Is.");
countryName.replace ("Island", "Is.");
countryName.replace ("North ", "N. ");
countryName.replace ("Northern ", "N. ");
countryName.replace ("South ", "S. ");
countryName.replace ("East ", "E. ");
countryName.replace ("Eastern ", "E. ");
countryName.replace ("West ", "W. ");
countryName.replace ("Western ", "W. ");
countryName.replace ("Central ", "C. ");
countryName.replace (" and ", " & ");
countryName.replace ("Republic", "Rep.");
countryName.replace ("United States", "U.S.A.");
countryName.replace ("Fed. Rep. of ", "");
countryName.replace ("French ", "Fr.");
countryName.replace ("Asiatic", "AS");
countryName.replace ("European", "EU");
countryName.replace ("African", "AF");
countryName.replace ("Islands", "Is.");
countryName.replace ("Island", "Is.");
countryName.replace ("North ", "N. ");
countryName.replace ("Northern ", "N. ");
countryName.replace ("South ", "S. ");
countryName.replace ("East ", "E. ");
countryName.replace ("Eastern ", "E. ");
countryName.replace ("West ", "W. ");
countryName.replace ("Western ", "W. ");
countryName.replace ("Central ", "C. ");
countryName.replace (" and ", " & ");
countryName.replace ("Republic", "Rep.");
countryName.replace ("United States", "U.S.A.");
countryName.replace ("Fed. Rep. of ", "");
countryName.replace ("French ", "Fr.");
countryName.replace ("Asiatic", "AS");
countryName.replace ("European", "EU");
countryName.replace ("African", "AF");
}
appendage += countryName;
@@ -181,9 +187,11 @@ QString DisplayText::appendDXCCWorkedB4(QString message, QString const& callsign
void DisplayText::displayDecodedText(DecodedText const& decodedText, QString const& myCall,
bool displayDXCCEntity, LogBook const& logBook,
QColor color_CQ, QColor color_MyCall,
QColor color_DXCC, QColor color_NewCall)
QColor color_DXCC, QColor color_NewCall, bool ppfx,
bool bCQonly)
{
QColor bg {Qt::white};
m_bPrincipalPrefix=ppfx;
QColor bg {Qt::transparent};
bool CQcall = false;
if (decodedText.string ().contains (" CQ ")
|| decodedText.string ().contains (" CQDX ")
@@ -192,6 +200,7 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con
CQcall = true;
bg = color_CQ;
}
if(bCQonly and !CQcall) return;
if (myCall != "" and (
decodedText.indexOf (" " + myCall + " ") >= 0
or decodedText.indexOf (" " + myCall + "/") >= 0
@@ -225,6 +234,9 @@ void DisplayText::displayTransmittedText(QString text, QString modeTx, qint32 tx
if(bFastMode or modeTx=="FT8") {
t = QDateTime::currentDateTimeUtc().toString("hhmmss") + \
" Tx " + t2 + t1 + text;
} else if(modeTx.mid(0,6)=="FT8fox") {
t = QDateTime::currentDateTimeUtc().toString("hhmmss") + \
" Tx" + modeTx.mid(7) + " " + text;
} else {
t = QDateTime::currentDateTimeUtc().toString("hhmm") + \
" Tx " + t2 + t1 + text;
@@ -237,3 +249,8 @@ void DisplayText::displayQSY(QString text)
QString t = QDateTime::currentDateTimeUtc().toString("hhmmss") + " " + text;
appendText (t, "hotpink");
}
void DisplayText::displayFoxToBeCalled(QString t, QColor bg)
{
appendText(t,bg);
}
+4 -2
View File
@@ -20,11 +20,12 @@ public:
void setContentFont (QFont const&);
void insertLineSpacer(QString const&);
void displayDecodedText(DecodedText const& decodedText, QString const& myCall, bool displayDXCCEntity,
LogBook const& logBook, QColor color_CQ, QColor color_MyCall,
QColor color_DXCC, QColor color_NewCall);
LogBook const& logBook, QColor color_CQ, QColor color_MyCall,
QColor color_DXCC, QColor color_NewCall, bool ppfx, bool bCQonly=false);
void displayTransmittedText(QString text, QString modeTx, qint32 txFreq,
QColor color_TxMsg, bool bFastMode);
void displayQSY(QString text);
void displayFoxToBeCalled(QString t, QColor bg);
Q_SIGNAL void selectCallsign (Qt::KeyboardModifiers);
Q_SIGNAL void erased ();
@@ -36,6 +37,7 @@ protected:
void mouseDoubleClickEvent(QMouseEvent *e);
private:
bool m_bPrincipalPrefix;
QString appendDXCCWorkedB4(QString message, QString const& callsign, QColor * bg, LogBook const& logBook,
QColor color_CQ, QColor color_DXCC, QColor color_NewCall);
+1
View File
@@ -72,6 +72,7 @@ set (UG_IMGS
images/decode-menu.png
images/decodes.png
images/download_samples.png
images/echo_144.png
images/file-menu.png
images/FreqCal.png
images/FreqCal_Graph.png
+1 -1
View File
@@ -23,7 +23,7 @@ the following copyright notice prominently:
*The algorithms, source code, look-and-feel of _{prog}_ and related
programs, and protocol specifications for the modes FSK441, FT8, JT4,
JT6M, JT9, JT65, JTMS, QRA64, ISCAT, and MSK144 are Copyright (C)
2001-2017 by one or more of the following authors: Joseph Taylor,
2001-2018 by one or more of the following authors: Joseph Taylor,
K1JT; Bill Somerville, G4WJS; Steven Franke, K9AN; Nico Palermo,
IV3NWV; Greg Beam, KI7MT; Michael Black, W9MDB; Edson Pereira, PY2SDR;
Philip Karn, KA9Q; and other members of the WSJT Development Group.*
+2 -1
View File
@@ -68,6 +68,7 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
:fmt_k5cm: http://www.k5cm.com/[FMT Event Info]
:fmt_wspr: http://www.physics.princeton.edu/pulsar/K1JT/FMT_User.pdf[Accurate Frequency Measurements with your WSPR Setup]
:ft8_tips: http://www.physics.princeton.edu/pulsar/K1JT/FT8_Operating_Tips.pdf[here]
:ft8_DXped: http://physics.princeton.edu/pulsar/k1jt/FT8_DXpedition_Mode.pdf[FT8 DXpedition Mode]
:gnu_gpl: http://www.gnu.org/licenses/gpl-3.0.txt[GNU General Public License]
:homepage: http://physics.princeton.edu/pulsar/K1JT/[WSJT Home Page]
:hrd: http://www.hrdsoftwarellc.com/[Ham Radio Deluxe]
@@ -104,7 +105,7 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
:jtsdk_qt: http://physics.princeton.edu/pulsar/K1JT/JTSDK-QT.exe[Download]
:jtsdk_vcredist: http://sourceforge.net/projects/jtsdk/files/win32/2.0.0/base/contrib/vcredist_x86.exe/download[Download]
:nh6z: http://www.nh6z.net/Amatuer_Radio_Station_NH6Z/Other_Peoples_Software.html[here]
:omnirig: http://www.dxatlas.com/OmniRig/Files/OmniRig.zip[Download]
:omnirig: http://www.dxatlas.com/OmniRig/Files/OmniRig.zip[Omni-Rig]
:osx: http://physics.princeton.edu/pulsar/K1JT/wsjtx-{VERSION}-Darwin.dmg[wsjtx-{VERSION}-Darwin.dmg]
:QRA64_EME: http://physics.princeton.edu/pulsar/K1JT/QRA64_EME.pdf[QRA64 for microwave EME]
:svn: http://subversion.apache.org/packages.html#windows[Subversion]
@@ -56,7 +56,8 @@ and reception in ISCAT, MSK144, and the fast JT9 modes.
MSK144 and the fast JT9 submodes you can activate the spinner control
*Tx CQ nnn* by checking the box to its right. The program will then
generate something like `CQ nnn K1ABC FN42` for your CQ message, where
`nnn` is the kHz portion of your current operating frequency. Your CQ
`nnn` is the kHz portion of your current operating frequency,
in the range 010 to 999. Your CQ
message *Tx6* will then be transmitted at the calling frequency
selected in the *Tx CQ nnn* spinner control. All other messages will
be transmitted at your current operating frequency. On reception,
@@ -67,7 +68,7 @@ specified response frequency.
* Checkboxes at bottom center of the main window control special
features for particular operating modes:
** *Sh* enables shorthand messages in JT4, JT65, and MSK144 modes
** *Sh* enables shorthand messages in JT4, JT65, QRA64 and MSK144 modes
** *Fast* enables fast JT9 submodes
@@ -1,9 +1,12 @@
// Status=review
The following buttons appear just under the decoded text windows on
The following controls appear just under the decoded text windows on
the main screen:
//.Main UI
image::main-ui-controls.png[align="left",width=650,alt="Main UI Controls"]
image::main-ui-controls.png[align="center",width=650,alt="Main UI Controls"]
* When *CQ only* is checked, only messages from stations calling CQ will
be displayed in the left text panel.
* *Log QSO* raises a dialog window pre-filled with known information
about a QSO you have nearly completed. You can edit or add to this
@@ -62,3 +65,5 @@ Toggle the button a second time or click *Halt Tx* to terminate the
*Tune* process. Note that activating *Tune* interrupts a receive
sequence and will prevent decoding during that sequence.
* Uncheck the box *Menus* to make the top-of-window menus disappear,
leaving more vertical space for decoded messages.
+5 -4
View File
@@ -1,9 +1,10 @@
=== AP Decoding
The _WSJT-X_ decoders for QRA64 and FT8 include optional procedures
that use naturally accumulating information during a minimal QSO.
This _a priori_ (AP) information increases sensitivity of the decoder
by up to 4 dB, at the cost of a slightly higher rate of false decodes.
The _WSJT-X_ decoders for JT65, QRA64, and FT8 include optional
procedures that use naturally accumulating information during a
minimal QSO. This _a priori_ (AP) information increases sensitivity
of the decoder by up to 4 dB, at the cost of a slightly higher rate of
false decodes.
For example: when you decide to answer a CQ, you already know your own
callsign and that of your potential QSO partner. The software
+5 -5
View File
@@ -1,6 +1,6 @@
////
Questions:
Should be short one liners ending with ?::
Should be short one liners (in the .adoc file) ending with ?::
If your question is too long for one line, consider multiple questions or rephrase
Answers:
@@ -47,11 +47,11 @@ location for each instance of _WSJT-X_.
wsjtx --rig-name=TS2000
wsjtx --rig-name=FT847
When setting up rig control through _OmniRig_, something goes wrong when I click *Test CAT*. What can I do about it?::
Rig control through _OmniRig_ seems to fail when I click *Test CAT*. What can I do about it?::
_OmniRig_ apparently has a bug that appears when you click *Test CAT*.
Forget using *Test CAT* and just click *OK*. _OmniRig_ then behaves
normally.
_Omni-Rig_ apparently has a bug that appears when you click *Test
CAT*. Forget using *Test CAT* and just click *OK*. _Omni-Rig_ then
behaves normally.
I am using _WSJT-X_ with _Ham Radio Deluxe_. All seems well until I start HRD Logbook or DM780 running in parallel; then CAT control becomes unreliable.::
Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 11 KiB

+7 -2
View File
@@ -1,4 +1,4 @@
// These instructions are up-to-date for WSJT-X v1.8
// These instructions are up-to-date for WSJT-X v1.9
*OS X 10.9* and later: Download the file {osx} to your desktop,
double-click on it and consult its `ReadMe` file for important
@@ -6,13 +6,18 @@ installation notes.
If you have already installed a previous version, you can retain it by
changing its name in the *Applications* folder (say, from _WSJT-X_ to
_WSJT-X_1.7_). You can then proceed to the installation phase.
_WSJT-X_1.8_). You can then proceed to the installation phase.
Take note also of the following:
* Use the Mac's *Audio MIDI Setup* utility to configure your sound
card for 48000 Hz, two-channel, 16-bit format.
NOTE: If you are using macOS with an external audio device and find
that Tx audio spontaneously switches to the motherboard sound device
after a few transmissions, try setting the sample rate to 44100 Hz
rather than the otherwise recommended 48000 Hz.
* Use *System Preferences* to select an external time source to keep
your system clock synchronized to UTC.
+11 -1
View File
@@ -7,7 +7,7 @@ K1**JT**,`" while the suffix "`-X`" indicates that _WSJT-X_ started as
an extended and experimental branch of the program
_WSJT_.
_WSJT-X_ Version 1.8 offers nine different protocols or modes: *FT8*,
_WSJT-X_ Version 1.9 offers nine different protocols or modes: *FT8*,
*JT4*, *JT9*, *JT65*, *QRA64*, *ISCAT*, *MSK144*, *WSPR*, and *Echo*.
The first five are designed for making reliable QSOs under extreme
weak-signal conditions. They use nearly identical message structure
@@ -62,3 +62,13 @@ tracking for EME QSOs and Echo testing. The program runs equally well
on Windows, Macintosh, and Linux systems, and installation packages
are available for all three platforms.
*Version Numbers:* _WSJT-X_ release numbers have major, minor, and
patch numbers separated by periods: for example, _WSJT-X_ Version
1.9.0. Temporary "`beta`" release candidates are sometimes made in
advance of a new general-availability release, in order to obtain user
feedback. For example, version 1.9.0-rc1, 1.9.0-rc2, etc., would
be beta releases leading up to the final release of v1.9.0.
Release candidates should be used _only_ during a short testing
period. They carry an implied obligation to provide feedback to the
program development group. Candidate releases should not be used on
the air after a full release with the same number has been made.
+9 -7
View File
@@ -41,7 +41,7 @@ are desirable. Double-click the *Tx1* control under _Now_ or _Next_
to toggle use of the Tx2 message rather than Tx1 to start a QSO.
Similarly, double-click the *Tx4* control to toggle between sending
`RRR` and `RR73` in that message. The `RR73` message should be used
only if you are reasonably confident that no repititions will be
only if you are reasonably confident that no repetitions will be
required.
=== Free-Text Messages
@@ -57,12 +57,14 @@ or rag-chewing.
=== Auto-Sequencing
The slow modes JT4, JT9, JT65, and QRA64 allow nearly 10 seconds at
the end of each one-minute receiving sequence -- enough time for you
to inspect decoded messages and decide how to reply. The 15-second
T/R cycles of FT8 allow only about two seconds for this task, which is
often not enough. For this reason a basic auto-sequencing feature is
offered. Check *Auto Seq* on the main window to enable this feature:
The 15-second T/R cycles of FT8 allow only about two seconds to inspect
decoded messages and decide how to reply, which is often not enough.
The slow modes JT4, JT9, JT65, and QRA64 allow nearly 10 seconds
for this task, but operators may find that this is still insufficient
when workload is high, especially on EME. For these reasons a basic
auto-sequencing feature is offered.
Check *Auto Seq* on the main window to enable this feature:
image::auto-seq.png[align="center",alt="AutoSeq"]
+19 -18
View File
@@ -1,31 +1,32 @@
=== New in Version 1.8
=== New in Version 1.9
For quick reference, here's a short list of features and capabilities
added to _WSJT-X_ since Version 1.7.0:
added to _WSJT-X_ since Version 1.8.0:
- New mode *FT8* designed for fast QSOs
- New *FT8 DXpedition Mode* to facilitate high QSO rates in pileup
situations
- New tool *FreqCal* for accurate frequency calibration of your radio
- Decoding improvements for JT65 mode, including _a priori_ (AP)
decoding when VHF/UHF/Microwave features are enabled
- Improved decoding performance for JT65, QRA64, and MSK144
- Optional Auto-Sequencing in JT4, JT9, and JT65 when VHF/UHF/Microwave features are enabled
- *SWL* option for third-party decoding short-format MSK144 messages
- Better suppression of low-confidence false decodes generated by AP
decoding in FT8 mode
- Experimental phase equalization for MSK144
- Options to minimize screen space used by *Main* and *Wide Graph*
windows
- New set of suggested default frequencies specific to the three IARU
regions
- Improved decoding performance for WSPR mode, especially effective at LF and MF
- Enhanced scheme for managing table of suggested default operating
frequencies
- Minor adjustments to auto-sequencing behavior
- Improved CAT control for many radios, including those controlled
through Commander or OmniRig
- More flexible Doppler control features for EME
- Bug fixes and minor tweaks to user interface
- Improved waterfall sensitivity for very weak signals
- Automatic real-time forwarding of logged information to _N1MM Logger+_
- Expanded and improved UDP messages sent to companion programs
- Bug fixes and other minor tweaks to user interface
=== Documentation Conventions
+50 -3
View File
@@ -9,9 +9,11 @@ additional bit flags a message containing arbitrary alphanumeric text,
up to 13 characters. Special cases allow other information such as
add-on callsign prefixes (e.g., ZA/K1ABC) or suffixes (e.g., K1ABC/P)
to be encoded. The basic aim is to compress the most common messages
used for minimally valid QSOs into a fixed 72-bit length. Information
payloads in FT8 include 3 additional bits (75 bits total), with
definitions yet to be defined.
used for minimally valid QSOs into a fixed 72-bit length. The
information payload in FT8 includes 3 additional bits (75 bits total).
One of the added bits is used to flag special messages used by the
DXpedition station in FT8 DXpedition Mode. Uses for the remaining two
bits are yet to be defined.
A standard amateur callsign consists of a one- or two-character
prefix, at least one of which must be a letter, followed by a digit
@@ -166,6 +168,51 @@ QRA64 presently offers no message averaging capability, though that
feature may be added. In early tests, many EME QSOs were made using
submodes QRA64A-E on bands from 144 MHz to 24 GHz.
[[WSPR_PROTOCOL]]
==== WSPR
WSPR is designed for probing potential radio propagation paths using
low power beacon-like transmissions. WSPR signals convey a callsign,
Maidenhead grid locator, and power level using a compressed data
format with strong forward error correction and narrow-band 4-FSK
modulation. The protocol is effective at signal-to-noise ratios as low
as 31 dB in a 2500 Hz bandwidth.
WSPR messages can have one of three possible formats illustrated by
the following examples:
- Type 1: K1ABC FN42 37
- Type 2: PJ4/K1ABC 37
- Type 3: <PJ4/K1ABC> FK52UD 37
Type 1 messages contain a standard callsign, a 4-character Maidenhead
grid locator, and power level in dBm. Type 2 messages omit the grid
locator but include a compound callsign, while type 3 messages replace
the callsign with a 15-bit hash code and include a 6-character locator
as well as the power level. Lossless compression techniques squeeze
all three message types into exactly 50 bits of user
information. Standard callsigns require 28 bits and 4-character grid
locators 15 bits. In Type 1 messages, the remaining 7 bits convey the
power level. In message types 2 and 3 these 7 bits convey power level
along with an extension or re-definition of fields normally used for
callsign and locator. Together, these compression techniques amount to
“source encoding” the user message into the smallest possible number
of bits.
WSPR uses a convolutional code with constraint length K=32 and rate
r=1/2. Convolution extends the 50 user bits into a total of (50 + K
1) × 2 = 162 one-bit symbols. Interleaving is applied to scramble the
order of these symbols, thereby minimizing the effect of short bursts
of errors in reception that might be caused by fading or interference.
The data symbols are combined with an equal number of synchronizing
symbols, a pseudo-random pattern of 0s and 1s. The 2-bit
combination for each symbol is the quantity that determines which of
four possible tones to transmit in any particular symbol
interval. Data information is taken as the most significant bit, sync
information the least significant. Thus, on a 0 3 scale, the tone
for a given symbol is twice the value (0 or 1) of the data bit, plus
the sync bit.
[[SLOW_SUMMARY]]
==== Summary
+10 -8
View File
@@ -31,12 +31,14 @@ IMPORTANT: For the health of your T/R relays and external
preamplifier, we strongly recommend using a hardware sequencer and
testing to make sure that sequencing is correct.
- Check *FT8 and MSK144: NA VHF Contest Mode* to enable generation and
auto-sequencing of messages using four-character grid locators in
place of signal reports, as required for most North American VHF
contests.
- Check *x 2 Tone spacing* or *x 4 Tone spacing* to generate Tx audio
with twice or four times the normal tone spacing. This feature is
intended for use with specialized LF/MF transmitters that divide
generated frequencies by 2 or 4 as part of the transmission process.
_FT8 DXpedition Mode_
- Check *Fox* if you are a DXpedition station operating in FT8
DXpedition Mode. Check *Hound* if you wish to make QSOs with such a
Fox. Be sure to read the operating instructions for {ft8_DXped}.
- Check *x 2 Tone spacing* to generate Tx audio with twice the normal
tone spacing. This feature is intended for use with specialized LF/MF
transmitters that divide the audio waveform by 2 before further
processing.
+4 -4
View File
@@ -11,7 +11,7 @@ your radio, select the *Radio* tab.
- Alternatively, if you have configured your station for control by
*DX Lab Suite Commander*, *Ham Radio Deluxe*, *Hamlib NET rigctl*, or
*OmniRig*, you may select one of those program names from the *Rig*
*Omni-Rig*, you may select one of those program names from the *Rig*
list. In these cases the entry field immediately under _CAT Control_
will be relabeled as *Network Server*. Leave this field blank to
access the default instance of your control program, running on the
@@ -19,9 +19,9 @@ same computer. If the control program runs on a different computer
and/or port, specify it here. Hover the mouse pointer over the entry
field to see the required formatting details.
- Select *OmniRig Rig 1* or *OmniRig Rig 2* to connect to an _OmniRig_
server running on the same computer. Note that _OmniRig_ is available
only under Windows.
- Select *Omni-Rig Rig 1* or *Omni-Rig Rig 2* to connect to an
_Omni-Rig_ server running on the same computer. Note that _Omni-Rig_
is available only under Windows.
- Set *Poll Interval* to the desired interval for _WSJT-X_ to query
your radio. For most radios a small number (say, 1 3 s) is
+7 -1
View File
@@ -2,7 +2,9 @@
[[FIG_CONFIG_RPT]]
image::reporting.png[align="center",alt="Reporting Screen"]
- _Logging_: Choose any desired options from this group.
- _Logging_: Choose any desired options from this group. Operators in
a multi-operator station may wish to enter their home callsign as *Op
Call*.
- _Network Services_: Check *Enable PSK Reporter Spotting* to send
reception reports to the {pskreporter} mapping facility.
@@ -13,3 +15,7 @@ updates from _WSJT-X_. Cooperating applications like _JTAlert_ use
this feature to obtain information about a running _WSJT-X_ instance.
If you are using _JTAlert_, be sure to check the three boxes at lower
right.
- _N1MM Logger+ Broadcasts_: To send information on logged QSOs
directly to _N1MM Logger+_, check the box and enter the IP address and
port number for _N1MM_.
+7 -12
View File
@@ -40,8 +40,8 @@ try clicking with the mouse on the decoded text lines and on the
waterfall spectral display. You should be able to confirm the
following behavior:
- Double-click on either of the decoded lines highlighted in
green. This action produces the following results:
- Click or double-click on either of the decoded lines highlighted in
green. These actions produce the following results:
** Callsign and locator of a station calling CQ are copied to the *DX
Call* and *DX Grid* entry fields.
@@ -57,14 +57,16 @@ station.
** The *Gen Msg* ("`generated message`") radio button at bottom right
of the main window is selected.
** If you had checked *Double-click on call sets Tx Enable* on the
*Setup* menu, *Enable Tx* would be activated and a transmission would
start automatically at the proper time.
** *Double-click* does all of the above and also activates *Enable Tx*
so that a transmission will start automatically at the proper time.
** You can modify the double-click behavior by holding down the
*Shift* key to move only the Tx frequency or the *Ctrl* key to move
both Rx and Tx frequencies.
NOTE: You can prevent your Tx frequency from being changed by checking the
box *Hold Tx Freq*.
- Double-click on the decoded message `K1JT N5KDV EM41`, highlighted
in red. Results will be similar to those in the previous step. The Tx
frequency (red marker) is not moved unless *Shift* or *Ctrl* is held
@@ -72,13 +74,6 @@ down. Messages highlighted in red are usually in response to your own
CQ or from a tail-ender, and you probably want your Tx frequency to
stay where it was.
NOTE: Double-clicking on decoded messages can be defaulted to simplex
operation by checking *Double click on call sets Tx and Rx freqs* on
the *Settings -> General* tab.
NOTE: You can prevent your Tx frequency from being changed by checking the
box *Lock Tx Freq*.
- Click somewhere on the waterfall to set Rx frequency (green marker
on waterfall scale).
+18 -6
View File
@@ -45,16 +45,28 @@ when double-clicking.
NOTE: To avoid QRM from competing callers, it is frequently desirable
to answer a CQ on a different frequency from that of the CQing
station. Choose a Tx frequency that appears to be not in use. The
same is true when you tail-end another QSO.
station. The same is true when you tail-end another QSO. Choose a Tx
frequency that appears to be not in use.
NOTE: The FT8 decoder can often copy several overlapping signals at
nearly the same frequency. Keyboard shortcuts *Shift+F11* and
*Shift+F12* provide an easy way to move your Tx frequency down or up
in 60 Hz steps.
NOTE: Keyboard shortcuts *Shift+F11* and *Shift+F12* provide an easy
way to move your Tx frequency down or up in 60 Hz steps.
NOTE: Further helpful tips on FT8 operating procedures are available
{ft8_tips}. Thanks to ZL2IFB!
.FT8 DXpedition Mode:
- This special operating mode enables DXpeditions to make FT8 QSOs at
very high rates. Both stations must use _WSJT-X_ Version 1.9 or
later. Detailed operating instructions for {ft8_DXped} are available
online. Do not try to use DXpedition mode without reading these
instructions carefully!
IMPORTANT: FT8 DXpedition mode is suitable for use only by legitimate
DXpeditions and those attempting to work them. Do not try to use
DXpedition mode for normal FT8 operation. Do not use it in the
conventional FT8 subbands. And especially, do not use the
multi-signal capability unless you are a DXpedition.
IMPORTANT: When finished with this Tutorial, don't forget to re-enter
your own callsign as *My Call* on the *Settings | General* tab.
+35 -8
View File
@@ -1,4 +1,4 @@
_WSJT-X_ v1.8 suppports a number of features designed for use
_WSJT-X_ v1.9 suppports a number of features designed for use
on the VHF and higher bands. These features include:
- *FT8*, a mode designed for making fast QSOs with weak, fading
@@ -8,6 +8,8 @@ signals
- *JT9* fast modes, useful for scatter propagation on VHF bands
- *JT65*, widely used for EME on VHF and higher bands
- *QRA64*, a mode for EME using a "`Q-ary Repeat Accumulate`" code,
a low-density parity-check (LDPC) code using a 64-character symbol
alphabet
@@ -24,6 +26,8 @@ propagation
- *Doppler tracking*, which becomes increasingly important for EME
on bands above 1.2 GHz.
- Optional *Auto-Sequencing* in JT4, JT9, and JT65 as well as FT8 and QRA64.
[[VHF_SETUP]]
=== VHF Setup
@@ -32,8 +36,8 @@ To activate the VHF-and-up features:
- On the *Settings | General* tab check *Enable VHF/UHF/Microwave
features* and *Single decode*.
- For EME, check *Decode at t = 52 s* to allow for extra path delay on
received signals.
- For EME, check *Decode after EME delay* to allow for extra path
delay on received signals.
- If you will use automatic Doppler tracking and your radio accepts
frequency-setting commands while transmitting, check *Allow Tx
@@ -77,13 +81,16 @@ becomes visible when you check *Doppler tracking*.
image::Astronomical_data.png[align="center",alt="Astronomical data"]
Three different types of Doppler tracking are provided:
Five different types of Doppler tracking are provided:
- Select *Full Doppler to DX Grid* if you know your QSO partner's locator
and he/she will not be using any Doppler control.
- Select *Receive only* to enable EME Doppler tracking of your receive
frequency to a specific locator. Your Tx frequency will remain fixed.
- Select *Own Echo* to enable EME Doppler tracking of your receive
frequency to your own echo frequency. Your Tx frequency will remain fixed
and is set to the Sked frequency. This mode can be used when announcing
your CQ call on a specific frequency and listening on your own echo
frequency. It can also be used for echo testing with Echo mode.
- Select *Constant frequency on Moon* to correct for your own one-way
Doppler shift to or from the Moon. If your QSO partner does the same
@@ -91,6 +98,25 @@ thing, both stations will have the required Doppler compensation.
Moreover, anyone else using this option will hear both of you
without the need for manual frequency changes.
- Select *On Dx Echo* when your QSO partner is not using automated
Doppler tracking, and announces his/her transmit frequency and listening
on their own echo frequency. When clicked, this Doppler method will
set your rig frequency on receive to correct for the mutual Doppler
shift. On transmit, your rig frequency will be set so that your
QSO partner will receive you on the same frequency as their own echo
at the start of the QSO. As the QSO proceeds, your QSO partner will
receive you on this starting frequency so that they do not have to
retune their receiver as the Doppler changes. Sked frequency in this
case is set to that announced by your QSO partner.
- Select *Call DX* after tuning the radio manually to find a station,
with the Doppler mode initally set to *None*. You may be tuning the band
looking for random stations, or to a frequency where a station has been
seen on an SDR display. It is usually necessary to hold down the Ctrl key
while tuning the radio. From the moment *Call DX* is pressed, your
transmit frequency is set so that your echo will fall on the same
frequency you (and the DX station) are listening.
- See <<ASTRODATA,Astronomical Data>> for details on the quantities
displayed in this window.
@@ -142,8 +168,9 @@ shorthand messages for RO, RRR, and 73. These messages are always
enabled for reception; they will be automatically generated for
transmission if you check the shorthand message box *Sh*.
Be sure to check *Deep* on the *Decode* menu; you may optionally
include *Enable averaging* and *Deep search*.
*Deep* on the *Decode* menu will be automatically selected. You may
optionally include *Enable averaging*, *Enable Deep search*, and
*Enable AP*.
The following screen shot shows three transmissions from a 144 MHz EME
QSO using submode JT65B and shorthand messages. Take note of the
-1
View File
@@ -29,7 +29,6 @@ private slots:
void on_gainSlider_valueChanged(int value);
void on_zeroSlider_valueChanged(int value);
void on_binsPerPixelSpinBox_valueChanged(int n);
void on_pbColors_clicked();
private:
+1 -1
View File
@@ -85,7 +85,7 @@ void FastGraph::on_greenZeroSlider_valueChanged(int value)
ui->fastPlot->draw();
}
void FastGraph::setTRperiod(int n)
void FastGraph::setTRPeriod(int n)
{
m_TRperiod=n;
ui->fastPlot->setTRperiod(m_TRperiod);
+1 -1
View File
@@ -20,7 +20,7 @@ public:
void plotSpec(bool diskData, int UTCdisk);
void saveSettings();
void setTRperiod(int n);
void setTRPeriod(int n);
void setMode(QString mode);
signals:
+11
View File
@@ -0,0 +1,11 @@
[Desktop Entry]
Version=1.0
Name=ft8call
Comment=Amateur Radio Weak Signal Operating
Exec=ft8call
Icon=wsjtx_icon
Terminal=false
X-MultipleArgs=false
Type=Application
Categories=AudioVideo;Audio;HamRadio;
StartupNotify=true
+4 -4
View File
@@ -38,15 +38,15 @@ his locator AJ10:
2. KH1DX K1ABC FN42, KH1DX W9XYZ EN37, ...
3. K1ABC KH1DX -13
4. KH1DX K1ABC R-11
5. K1ABC R 73; W9XYZ <KH1DX> -17
5. K1ABC RR73; W9XYZ <KH1DX> -17
6. ... no copy from W9XYZ ...
7. W9XYZ KH1DX -17
8. ... no copy from W9XYZ ...
9. G4AAA KH1DX -11
10. KH1DX G4AAA R-03
11. G4AAA R 73; DL3BBB <KH1DX> -12
11. G4AAA RR73; DL3BBB <KH1DX> -12
12. KH1DX DL3BBB R-09
13. DL3BBB R 73; DE <KH1DX>
13. DL3BBB RR73; DE <KH1DX>
14. ...
------------------------------------------------------------------------
@@ -144,7 +144,7 @@ hoping to find a clear slot, by using Shift+F11 and Shift+F12.
sent automatically.
- After you send the "R+rpt" message, AutoSeq will watch for a
message that starts with "MyCall R 73; ...". When that is
message that starts with "MyCall RR73; ...". When that is
received, you're in his log, and you'll be prompted to log the QSO.
Random thoughts
+4 -4
View File
@@ -12,10 +12,10 @@ subroutine azdist(grid1,grid2,utch,nAz,nEl,nDmiles,nDkm,nHotAz,nHotABetter)
data mygrid0/" "/,hisgrid0/" "/,utch0/-999.d0/
save
MyGrid=grid1
HisGrid=grid2
if(ichar(grid1(5:5)).eq.0) MyGrid(5:6)=' '
if(ichar(grid2(5:5)).eq.0) HisGrid(5:6)=' '
MyGrid=grid1//' '
HisGrid=grid2//' '
if(ichar(MyGrid(5:5)).eq.0) MyGrid(5:6)=' '
if(ichar(HisGrid(5:5)).eq.0) HisGrid(5:6)=' '
if(MyGrid.eq.HisGrid) then
naz=0
+2 -1
View File
@@ -1,6 +1,7 @@
subroutine ccf2(ss,nz,nflip,ccfbest,xlagpk)
parameter (LAGMIN=-86,LAGMAX=258)
! parameter (LAGMIN=-86,LAGMAX=258)
parameter (LAGMIN=-112,LAGMAX=258) ! Look for DT from -3.6s to +5.0s
real ss(nz)
real ccf(-LAGMAX:LAGMAX)
integer npr(126)
+6 -4
View File
@@ -1,5 +1,6 @@
subroutine decode65a(dd,npts,newdat,nqd,f0,nflip,mode65,ntrials, &
naggressive,ndepth,ntol,mycall,hiscall,hisgrid,nexp_decode, &
naggressive,ndepth,ntol,mycall,hiscall,hisgrid,nQSOProgress, &
ljt65apon, nexp_decode, &
bVHF,sync2,a,dt,nft,nspecial,qual,nhist,nsmo,decoded)
! Apply AFC corrections to a candidate JT65 signal, then decode it.
@@ -15,7 +16,7 @@ subroutine decode65a(dd,npts,newdat,nqd,f0,nflip,mode65,ntrials, &
complex c5a(512)
real s2(66,126)
real a(5)
logical bVHF,first
logical bVHF,first,ljt65apon
character decoded*22,decoded_best*22
character mycall*12,hiscall*12,hisgrid*6
character*27 cr
@@ -122,10 +123,11 @@ subroutine decode65a(dd,npts,newdat,nqd,f0,nflip,mode65,ntrials, &
endif
s2(i,1:126)=s1(jj,1:126)
enddo
nadd=ismo !### ??? ###
call decode65b(s2,nflip,nadd,mode65,ntrials,naggressive,ndepth, &
mycall,hiscall,hisgrid,nexp_decode,nqd,nft,qual,nhist,decoded)
mycall,hiscall,hisgrid,nQSOProgress,ljt65apon,nexp_decode, &
nqd,nft,qual, &
nhist,decoded)
if(nft.eq.1) then
nsmo=ismo
+6 -3
View File
@@ -1,10 +1,12 @@
subroutine decode65b(s2,nflip,nadd,mode65,ntrials,naggressive,ndepth, &
mycall,hiscall,hisgrid,nexp_decode,nqd,nft,qual,nhist,decoded)
mycall,hiscall,hisgrid,nQSOProgress,ljt65apon,nexp_decode,nqd, &
nft,qual, &
nhist,decoded)
use jt65_mod
real s2(66,126)
real s3(64,63)
logical ltext
logical ltext,ljt65apon
character decoded*22
character mycall*12,hiscall*12,hisgrid*6
save
@@ -19,7 +21,8 @@ subroutine decode65b(s2,nflip,nadd,mode65,ntrials,naggressive,ndepth, &
enddo
call extract(s3,nadd,mode65,ntrials,naggressive,ndepth,nflip,mycall, &
hiscall,hisgrid,nexp_decode,ncount,nhist,decoded,ltext,nft,qual)
hiscall,hisgrid,nQSOProgress,ljt65apon,nexp_decode,ncount, &
nhist,decoded,ltext,nft,qual)
! Suppress "birdie messages" and other garbage decodes:
if(decoded(1:7).eq.'000AAA ') ncount=-1
+114 -17
View File
@@ -54,10 +54,13 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
10 if (params%nagain) then
open(13,file=trim(temp_dir)//'/decoded.txt',status='unknown', &
position='append',iostat=ios)
if(params%nmode.eq.8) open(19,file=trim(temp_dir)//'/houndcallers.txt', &
status='unknown',position='append',iostat=ios)
else
open(13,file=trim(temp_dir)//'/decoded.txt',status='unknown', &
iostat=ios)
end if
open(13,file=trim(temp_dir)//'/decoded.txt',status='unknown',iostat=ios)
if(params%nmode.eq.8) open(19,file=trim(temp_dir)//'/houndcallers.txt', &
status='unknown',iostat=ios)
endif
if(ios.ne.0) then
nfail=nfail+1
if(nfail.le.3) then
@@ -73,9 +76,38 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
call my_ft8%decode(ft8_decoded,id2,params%nQSOProgress,params%nfqso, &
params%nftx,newdat,params%nutc,params%nfa,params%nfb, &
params%nexp_decode,params%ndepth,logical(params%nagain), &
logical(params%lapon),params%napwid,params%mycall, &
params%mygrid,params%hiscall,params%hisgrid)
logical(params%lft8apon),logical(params%lapcqonly),params%napwid, &
params%mycall,params%mygrid,params%hiscall,params%hisgrid)
call timer('decft8 ',1)
if(nfox.gt.0) then
n30min=minval(n30fox(1:nfox))
n30max=maxval(n30fox(1:nfox))
endif
j=0
rewind 19
if(nfox.eq.0) then
endfile 19
rewind 19
else
do i=1,nfox
n=n30fox(i)
if(n30max-n30fox(i).le.4) then
j=j+1
c2fox(j)=c2fox(i)
g2fox(j)=g2fox(i)
nsnrfox(j)=nsnrfox(i)
nfreqfox(j)=nfreqfox(i)
n30fox(j)=n
m=n30max-n
call azdist(params%mygrid,g2fox(j),0.d0,nAz,nEl,nDmiles,nDkm, &
nHotAz,nHotABetter)
write(19,1004) c2fox(j),g2fox(j),nsnrfox(j),nfreqfox(j),nDkm,m
1004 format(a12,1x,a4,i5,i6,i7,i3)
endif
enddo
nfox=j
flush(19)
endif
go to 800
endif
@@ -153,7 +185,8 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
logical(params%nagain),params%n2pass,logical(params%nrobust), &
ntrials,params%naggressive,params%ndepth,params%emedelay, &
logical(params%nclearave),params%mycall,params%hiscall, &
params%hisgrid,params%nexp_decode)
params%hisgrid,params%nexp_decode,params%nQSOProgress, &
logical(params%ljt65apon))
call timer('jt65a ',1)
else if(params%nmode.eq.9 .or. (params%nmode.eq.(65+9) .and. params%ntxmode.eq.9)) then
@@ -178,7 +211,8 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
logical(params%nagain),params%n2pass,logical(params%nrobust), &
ntrials,params%naggressive,params%ndepth,params%emedelay, &
logical(params%nclearave),params%mycall,params%hiscall, &
params%hisgrid,params%nexp_decode)
params%hisgrid,params%nexp_decode,params%nQSOProgress, &
logical(params%ljt65apon))
call timer('jt65a ',1)
else
call timer('decjt9 ',0)
@@ -197,7 +231,8 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
write(*,1010) nsynced,ndecoded
1010 format('<DecodeFinished>',2i4)
call flush(6)
close(13)
close(13)
close(19)
if(params%nmode.eq.4 .or. params%nmode.eq.65) close(14)
return
@@ -290,7 +325,7 @@ contains
integer, intent(in) :: nsum
integer, intent(in) :: minsync
integer i,nft
integer i,nap,nft
logical is_deep,is_average
character decoded*22,csync*2,cflags*3
@@ -332,6 +367,10 @@ contains
write(cflags(2:2),'(i1)') min(nsum,9)
if(nsum.ge.10) cflags(2:2)='*'
endif
nap=ishft(ft,-2)
if(nap.ne.0) then
write(cflags(1:3),'(a1,i1)') 'a',nap
endif
endif
csync='# '
i=0
@@ -399,22 +438,80 @@ contains
integer, intent(in) :: snr
real, intent(in) :: dt
real, intent(in) :: freq
character(len=22), intent(in) :: decoded
character(len=37), intent(in) :: decoded
character c1*12,c2*6,g2*4,w*4
integer i0,i1,i2,i3,i4,i5,n30,nwrap
integer, intent(in) :: nap
real, intent(in) :: qual
character*2 annot
character*22 decoded0
decoded0=decoded
character*37 decoded0
logical isgrid4,first,b0,b1,b2
data first/.true./
save
isgrid4(w)=(len_trim(w).eq.4 .and. &
ichar(w(1:1)).ge.ichar('A') .and. ichar(w(1:1)).le.ichar('R') .and. &
ichar(w(2:2)).ge.ichar('A') .and. ichar(w(2:2)).le.ichar('R') .and. &
ichar(w(3:3)).ge.ichar('0') .and. ichar(w(3:3)).le.ichar('9') .and. &
ichar(w(4:4)).ge.ichar('0') .and. ichar(w(4:4)).le.ichar('9'))
if(first) then
c2fox=' '
g2fox=' '
nsnrfox=-99
nfreqfox=-99
n30z=0
nwrap=0
nfox=0
first=.false.
endif
decoded0=decoded
annot=' '
if(nap.ne.0) then
write(annot,'(a1,i1)') 'a',nap
if(qual.lt.0.17) decoded0(22:22)='?'
write(annot,'(a1,i1)') 'a',nap
if(qual.lt.0.17) decoded0(22:22)='?'
endif
write(*,1000) params%nutc,snr,dt,nint(freq),decoded0,annot
i0=index(decoded0,';')
if(i0.le.0) write(*,1000) params%nutc,snr,dt,nint(freq),decoded0(1:22),annot
1000 format(i6.6,i4,f5.1,i5,' ~ ',1x,a22,1x,a2)
if(i0.gt.0) write(*,1001) params%nutc,snr,dt,nint(freq),decoded0
1001 format(i6.6,i4,f5.1,i5,' ~ ',1x,a37)
write(13,1002) params%nutc,nint(sync),snr,dt,freq,0,decoded0
1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a22,' FT8')
1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a37,' FT8')
i1=index(decoded0,' ')
i2=i1 + index(decoded0(i1+1:),' ')
i3=i2 + index(decoded0(i2+1:),' ')
if(i1.ge.3 .and. i2.ge.7 .and. i3.ge.10) then
c1=decoded0(1:i1-1)//' '
c2=decoded0(i1+1:i2-1)
g2=decoded0(i2+1:i3-1)
b0=c1.eq.params%mycall
if(len(trim(c1)).ne.len(trim(params%mycall))) then
i4=index(trim(c1),trim(params%mycall))
i5=index(trim(params%mycall),trim(c1))
if(i4.ge.1 .or. i5.ge.1) b0=.true.
endif
b1=i3-i2.eq.5 .and. isgrid4(g2)
b2=i3-i2.eq.1
if(b0 .and. (b1.or.b2) .and. nint(freq).ge.1000) then
n=params%nutc
n30=(3600*(n/10000) + 60*mod((n/100),100) + mod(n,100))/30
if(n30.lt.n30z) nwrap=nwrap+5760 !New UTC day, handle the wrap
n30z=n30
n30=n30+nwrap
nfox=nfox+1
c2fox(nfox)=c2
g2fox(nfox)=g2
nsnrfox(nfox)=snr
nfreqfox(nfox)=nint(freq)
n30fox(nfox)=n30
endif
endif
call flush(6)
call flush(13)

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