790 Commits

Author SHA1 Message Date
a37aec3bdf reduce sample rate on 2m 2020-10-11 18:55:03 +02:00
1cec386c18 release version 0.20.0 2020-10-11 15:03:39 +02:00
ce39de14e8 display squelch on mouseover, too 2020-10-11 00:46:41 +02:00
3975073efd defer demodulator startup until center_freq is set 2020-10-11 00:25:13 +02:00
f31685e4e7 fix some exceptions due to None values 2020-10-11 00:15:09 +02:00
a856c27fe4 cache requirements, not features, for even better results 2020-10-10 23:00:05 +02:00
0435225a29 add feature detection cache to improve client load times 2020-10-10 22:08:35 +02:00
be757c7968 change default rtlsdr gain to 29 to avoid e4000 problems 2020-10-10 13:38:26 +02:00
9b977ac878 combine docker operations into docker.sh 2020-10-05 17:03:34 +02:00
37344c0cb8 don't pull result 2020-10-05 16:25:09 +02:00
ff25fa25dd fix missing pkg-config for plutosdr 2020-10-04 23:48:42 +02:00
ac0e44857c rtltcp docker image 2020-10-04 22:57:03 +02:00
9f17f1bc17 make wfm deemphasis tau configurable 2020-10-04 21:56:35 +02:00
1faa61ad50 allow wfm deemphasis tau to be set from the outside 2020-10-04 21:46:58 +02:00
815831b1ed update dependencies in docker 2020-10-04 21:02:46 +02:00
6c70e19c63 separate metric for direct aprs messages 2020-10-02 17:45:48 +02:00
4a8e9472ab create metric dynamically 2020-10-02 17:16:16 +02:00
5d4f3b8d90 update owrx_connector in docker 2020-09-26 01:46:25 +02:00
f37c7baefb update connectors 2020-09-21 18:31:49 +02:00
efca3520ab update connectors 2020-09-21 14:54:59 +02:00
cc385f851f remove unused import 2020-09-20 19:55:08 +02:00
349604ac50 fix some javascript errors 2020-09-20 19:53:13 +02:00
eaaa214dc9 add more details about dream; prevent X11 windows during feature
detection
2020-09-20 12:41:11 +02:00
e3e94ad14e update changelog with the respective type 2020-09-20 12:26:57 +02:00
c1347de1f0 optimize waterfall color generation 2020-09-19 21:53:29 +02:00
71a2352d2b let the client initiate the dsp again 2020-09-19 21:35:14 +02:00
34414de4e5 only re-start dsp if dsp has been started before 2020-09-19 21:17:00 +02:00
ff34e793a0 handle failure of sdr devices asynchronously 2020-09-19 20:45:23 +02:00
31295efbff restore linear interpolation to improve performance 2020-09-19 15:51:54 +02:00
a3285d5943 make the secondary fft run faster again 2020-09-17 22:57:40 +02:00
b9e19421c1 activate fft averaging on the secondary fft 2020-09-17 22:43:39 +02:00
6a6d4a3c9b secondary fft is now complex, better display for digimodes based on FM 2020-09-17 22:21:49 +02:00
82825fee41 fix sequence according to dependencies 2020-09-17 21:33:11 +02:00
2018dd444f start off with black & white to avoid javascript errors 2020-09-17 21:13:42 +02:00
35243fb62e anticipate problems with old color schemes; counter with new config
version
2020-09-17 20:59:16 +02:00
fa08f1e2cf use chroma.js to calculate waterfall colors 2020-09-17 20:10:01 +02:00
e10a52b39e handle full queue better by draining 2020-09-15 22:04:53 +02:00
c947204356 adopt the frontend regex (matches better), closes #170 2020-09-13 22:30:57 +02:00
994bf7439b update changelog 2020-09-13 20:22:26 +02:00
97f3642262 fix mouse wheel tuning for frequencies < 1MHz 2020-09-13 15:35:32 +02:00
0e8aece991 display current waterfall values on mouse over 2020-09-13 13:57:12 +02:00
39a473c8c2 disable waterfall sliders in auto mode 2020-09-13 13:38:44 +02:00
b9e6ffe03d first attempt at an automatically calibrating waterfall 2020-09-12 22:06:12 +02:00
9f9a5ceaa3 implement minimum waterfall range 2020-09-12 20:36:10 +02:00
36cf6097b3 fine-tune colors 2020-09-12 19:54:25 +02:00
45c0d05fec include turbo color map (by google ai) 2020-09-12 19:49:22 +02:00
3cd6af9ef9 add fonts in newer, better compressed formats 2020-09-12 19:01:51 +02:00
d12af6d203 strip non-essential parts from direwolf in docker 2020-09-12 00:21:46 +02:00
5f5cafe5ca optimizes uhd build further 2020-09-11 23:34:52 +02:00
d45cc207ad use sprites scaled to specific resolution (better performance, less
scaling headaches)
2020-09-11 22:12:01 +02:00
6e3a13e0d2 slim down uhd build; enable usb devices 2020-09-11 01:31:00 +02:00
0d6e9a5b9f missed file during sprite commits 2020-09-11 00:19:46 +02:00
7d509eeb48 explicitly fill buffer with 0s to avoid noise on newer chrome versions 2020-09-11 00:19:04 +02:00
87ba4ea524 fix audioworklet callbacks 2020-09-11 00:09:07 +02:00
42f975a926 use sprites for bookmark button, too 2020-09-11 00:02:45 +02:00
63c31eba22 use sprites to reduce the number of requests 2020-09-10 22:29:01 +02:00
626fa7681b improvise compiler flags for arm cpus 2020-09-10 21:07:49 +02:00
d412d482b2 add build instructions for new images 2020-09-10 20:55:12 +02:00
cf2f7377ab remove obsolete image 2020-09-10 20:54:16 +02:00
6c8cadace6 add docker builds for uhd and red pitaya 2020-09-10 18:25:18 +02:00
320f64a611 fix copy target 2020-09-06 23:35:00 +02:00
bfc3684d75 actually uncouple base and owrx layer 2020-09-06 23:33:45 +02:00
19a4a37144 update csdr with bugfix 2020-09-06 21:07:55 +02:00
f2d284989b add exceptional bandwidth for drm 2020-09-05 22:10:23 +02:00
3f01fc6d67 update changelog 2020-09-05 19:50:14 +02:00
d4396cc61a Merge branch 'develop' into drm 2020-09-05 01:10:50 +02:00
298da694ca compress background image with webp 2020-09-05 01:10:08 +02:00
a5bc7850a0 update csdr 2020-09-05 00:41:06 +02:00
f6e0cf2b71 patch dream to avoid hamlib and link with faad2 correctly 2020-09-05 00:40:36 +02:00
9a5286ca24 use complex fractional decimator 2020-09-04 22:02:23 +02:00
e10143b6db add dream to docker builds 2020-09-04 21:20:27 +02:00
6fe41f8e02 add compilation instructions 2020-09-04 20:27:12 +02:00
e8068a8795 fix dream audio output 2020-09-04 19:14:16 +02:00
e8ee94d13b fix detection 2020-09-04 18:11:36 +02:00
2411929455 implement DRM mode with dream 2020-09-04 18:09:02 +02:00
bec02795b8 implement gzip compression for assets 2020-09-04 15:44:25 +02:00
b5bc63e76b fix cache-control header 2020-09-04 14:46:27 +02:00
1aa487ff1a update owrx_connector in docker 2020-09-01 23:33:14 +02:00
f47ebb2adb docker optimization
* move openwebrx project tools to a separate layer for lower download
  volume and faster builds
* use COPY instead of ADD
* COPY multiple files at once to reduce number of layers
2020-09-01 23:30:48 +02:00
f90670f477 erase waterfall calibration memory 2020-08-31 21:48:02 +02:00
95ac5aeb7d detect device failure 2020-08-30 23:48:05 +02:00
9be0664e14 explicit typing of the source event interface 2020-08-30 23:47:04 +02:00
805039ec02 Merge branch 'develop' of github.com:jketterl/openwebrx into develop 2020-08-30 23:26:45 +02:00
322ebb1baa Merge pull request #171 from jwt27/jwt27/bpsk
s/psk/bpsk/g in bands.json
2020-08-30 23:20:51 +02:00
32105538c5 lock on the spectrum thread to avoid double start 2020-08-30 17:35:53 +02:00
820ca16cd9 update codec2 in docker 2020-08-30 14:43:05 +02:00
45e3c910da s/psk/bpsk/g in bands.json 2020-08-30 04:56:48 +02:00
d609acc6aa freedv agc fine-tuning 2020-08-29 21:32:21 +02:00
02b4822be8 update csdr in docker 2020-08-28 22:35:23 +02:00
c16a1b4726 fine-tune dsd agc; remove limiter (included in agc now) 2020-08-28 22:05:00 +02:00
d1cea95eb4 use 16bit agc for freedv and dsd modes, refs #126 2020-08-27 22:35:49 +02:00
53eefa7c80 fix last_decimation 2020-08-27 22:35:12 +02:00
b06732dbf5 fine-tuning of dsd audio agc 2020-08-27 19:41:46 +02:00
22feb8dd1c moderate agc for NFM 2020-08-27 19:28:20 +02:00
56f976e495 let's try without the minor version 2020-08-27 00:12:18 +02:00
f830c7efa6 update csdr dependency to 0.17.0 2020-08-27 00:08:50 +02:00
04d6515337 let's try this way 2020-08-26 23:17:40 +02:00
f78a68d53f update dependency versions 2020-08-26 23:13:50 +02:00
c8687f2f8d update wording on github 2020-08-26 21:08:50 +02:00
1884b89a6e update changelog 2020-08-26 21:07:50 +02:00
008787a938 update csdr in docker 2020-08-26 21:05:29 +02:00
f41814c6ca add csdr version requirement 2020-08-26 20:07:58 +02:00
055269504b use the new agc parameters 2020-08-26 19:45:21 +02:00
dea5b15656 new gain parameters for digital modes 2020-08-26 00:43:49 +02:00
6650438d2f slow agc parameters for AM 2020-08-25 21:28:18 +02:00
4204e4d9e2 Merge branch 'develop' into agc_work 2020-08-24 00:03:55 +02:00
9e41d49d46 refactor audio startup so it will autostart on firefox, if allowed 2020-08-23 17:56:13 +02:00
6aa25760c5 update the issues page wordings 2020-08-22 18:07:54 +02:00
1bff6d1289 update connectors to latest version 2020-08-20 11:50:56 +02:00
23c69fb5a3 add "remote" mapping 2020-08-16 23:22:46 +02:00
b158e0d17d add the ability to add literal command-line arguments 2020-08-16 23:19:37 +02:00
c9dd33ba57 add a new source for rtl_tcp and rtl_tcp_connector 2020-08-16 21:49:52 +02:00
bc000451cc update make call 2020-08-15 17:39:13 +02:00
47da9a9d70 use unix dir separators 2020-08-15 17:01:32 +02:00
66703cb5e1 include radioberry in full build 2020-08-15 16:53:10 +02:00
0066b4dbfd make script executable 2020-08-15 16:52:55 +02:00
18d8b81f70 add git revision 2020-08-15 16:46:16 +02:00
8d52bde6b0 Merge pull request #165 from pa3gsb/develop
radioberry added to docker setup
2020-08-15 16:43:28 +02:00
dd3bf121c1 fix start_freq not working on neighboring profiles 2020-08-15 16:05:50 +02:00
cfc3f926fe clone added 2020-08-15 14:24:48 +02:00
6f8c8a3b66 radioberry added to docker setup 2020-08-15 14:02:20 +02:00
1c2125f969 prevent direwolf from using hamlib, refs #164 2020-08-14 21:08:35 +02:00
0030c6d656 thread names to aid debugging 2020-08-14 20:22:25 +02:00
7e5ea6e065 improve read pipe opening 2020-08-14 20:20:07 +02:00
49383e757f extract pipes to separate file 2020-08-14 19:54:07 +02:00
0cd0a1085a uncouple reading pipes, too, and select makes the threads time out 2020-08-14 00:17:09 +02:00
5bc69b6fa4 use id of pipe to avoid file system collisions 2020-08-13 23:51:11 +02:00
ddb5fe51b3 open pipes in non-blocking loops, preventing thread leaks 2020-08-13 23:35:49 +02:00
56debcd08a provide a fallback for browsers not supporting css gaps 2020-08-13 19:39:56 +02:00
de34856d57 let's stick with flexbox, but use native wrapping 2020-08-12 22:14:02 +02:00
80c25f459c use the space, modes! 2020-08-12 21:41:06 +02:00
ccb322016e re-arrange demodulator buttons in a dynamic grid 2020-08-12 19:44:33 +02:00
08ba0c7b02 shut down multiprocessing queue explicitly using a poison pill 2020-08-11 22:14:36 +02:00
7f57e4f45c compensate oversampling with the prefilter of csdr 2020-08-08 22:51:03 +02:00
f0b3a50c23 increase maximum audio speed indication (uncompressed hd is about
700kbps)
2020-08-08 22:23:34 +02:00
e51dbac2c5 update changelog 2020-08-08 22:06:33 +02:00
f4c43ffab6 fine-tune 2020-08-08 22:04:28 +02:00
69a12650d2 permit increased bandwidth for WFM 2020-08-08 22:04:10 +02:00
8c5a7a087f compensate WFM frequency deviation, at least preliminary 2020-08-08 21:56:35 +02:00
5a938b8c0b simplify 2020-08-08 21:35:15 +02:00
448e266097 implement wfm demodulator chain 2020-08-08 21:29:25 +02:00
da3f59fb9b determine hd audio rate and send it to the server 2020-08-08 20:45:03 +02:00
ef2ec1e1c5 catch exception on closed inputs 2020-08-08 20:43:29 +02:00
031c937c0c actually build fcdpp image 2020-08-08 00:11:44 +02:00
c6ec21747b add log to issue template 2020-08-08 00:11:11 +02:00
b54be3384d add docker build for funcube 2020-08-07 23:28:36 +02:00
62ee2ca445 add documentation about freedv_rx 2020-08-07 22:58:24 +02:00
03b2f83981 add groups.io link 2020-08-07 19:43:04 +02:00
20f0a5cd6c Update issue templates 2020-08-07 19:23:35 +02:00
640f438c4c Merge pull request #161 from jketterl/openwebrx-bug-template
Update issue templates
2020-08-07 19:15:21 +02:00
b068fb5756 Update issue templates 2020-08-07 17:07:09 +02:00
645ace75c3 protect against erroneous reads 2020-08-06 20:06:04 +02:00
0518ff9358 provide information to the queue which entries are done 2020-08-05 20:04:41 +02:00
a65fd7916e drain connections, close wave files refs #146 2020-08-05 20:03:38 +02:00
a77108dd0c drain subprocess pipes to free up file descriptors, refs #146 2020-08-05 20:01:57 +02:00
7234ff4309 use normal queue since we're not even multiprocessing 2020-08-05 19:07:55 +02:00
7ea8c8f7c6 use better locking for the service startup/shutdown 2020-07-30 21:35:31 +02:00
c8e5b4f822 let's try this again with a more recent version... 2020-07-30 18:05:56 +02:00
780d51286a update changelog 2020-07-29 21:45:24 +02:00
2252547fc1 add freedv to docker container 2020-07-29 21:44:10 +02:00
7e5409160e initial work on freedv / codec2 support, refs #126 2020-07-28 00:28:20 +02:00
9b187140ff catch exception and replace with a debug message, refs #22 2020-07-27 21:18:24 +02:00
77ae13723d remove link to outdated instructions, closes #157 2020-07-27 20:27:25 +02:00
9efc839128 update to js8call 2.2.0 2020-07-22 18:45:13 +02:00
660301a43b update to wsjt-x 2.2.2 2020-07-21 22:51:12 +02:00
11fd918d62 handle more errors the right way, refs #144 2020-07-21 20:33:48 +02:00
de67d36cd6 update changelog 2020-07-21 20:03:33 +02:00
1f8b2f7909 always send busy state event, even when always-on, closes #147 2020-07-21 19:57:23 +02:00
d9bc03d1fc clear the multiprocessing queue to get rid of more file descriptors,
refs #146
2020-07-20 23:09:38 +02:00
369a61ec59 shut down pipes correctly, refs #146 2020-07-19 19:42:18 +02:00
c54f19282a improved error handling, refs #146 #22 2020-07-19 19:00:26 +02:00
174e9afa7b correctly close iqtee / iqtee2 pipes 2020-07-18 20:00:49 +02:00
e53f1f60eb multi-key signing implementation 2020-07-09 21:32:57 +02:00
7eb0a8cf7e add fcdpp support 2020-07-09 15:39:33 +02:00
0e6518915d * refactor receiverid into a separate controller base
* allow multiple headers to prepare for checking multiple claims
2020-07-04 21:47:56 +02:00
e0129fd0f7 move timezone to initialization instead of implicit localization 2020-07-01 19:10:46 +02:00
929cf5e230 makefiles use tabs... weird 2020-06-23 19:48:00 +02:00
d6512e0a86 prevent debian packaging from modifying png files 2020-06-23 19:39:26 +02:00
480b728c06 move metrics initialization to have initial metrics 2020-06-23 00:08:59 +02:00
9e323a08ff remove duplicate css declaration 2020-06-22 00:07:16 +02:00
75f4f0bfe0 fix timezones in all places 2020-06-21 22:35:40 +02:00
2eece08d27 correct timezone for last-modified header 2020-06-21 21:42:32 +02:00
b930bb432d add -dev flag to clearly distinguish development versions 2020-06-14 21:58:35 +02:00
83ff417f4d post-release cleanup 2020-06-13 19:25:15 +02:00
bead51db69 fix the date 2020-06-13 18:51:01 +02:00
bf171bbfda add release targets 2020-06-13 18:48:18 +02:00
8ca068c98f update changelogs to reflect release 2020-06-13 18:47:17 +02:00
a696cc4ed8 next release version 2020-06-13 18:31:49 +02:00
0a2a28cb34 remove debugging 2020-06-13 18:26:27 +02:00
0f20f1fcdc update changelog 2020-06-13 18:21:22 +02:00
9a61f90fec parse hex string for hmac 2020-06-11 20:55:05 +02:00
5a88856825 fix array syntax 2020-06-11 00:01:47 +02:00
0e4f772c69 perform actual hmac signature 2020-06-11 00:00:16 +02:00
8278ece803 add receiver keys to configuration 2020-06-10 23:34:09 +02:00
eebe33f896 implement signature algorithm 2020-06-10 22:50:16 +02:00
61d03b38b9 receiver receiverid challenge and find corresponding key 2020-06-10 20:09:40 +02:00
c0f447ca20 fix rockprog integration 2020-06-07 22:53:31 +02:00
81465d69cc introduce next version to develop branch 2020-06-02 21:18:05 +02:00
1e84ced9a9 resture "under construction" notice 2020-06-02 21:12:25 +02:00
3479148b86 more tuning of the default configuration 2020-06-01 22:52:35 +02:00
017ad818ef fix up default configuration 2020-06-01 22:43:58 +02:00
09caae2fcc update changelog 2020-06-01 21:44:02 +02:00
ae295d72ae remove "under construction" notice 2020-06-01 19:41:38 +02:00
16c59c3245 release versions 2020-06-01 19:05:09 +02:00
ea65ef0100 update changelog 2020-06-01 18:34:54 +02:00
379e39aa3e Merge branch 'develop' into radioberry 2020-06-01 18:27:44 +02:00
835501a5f4 update changelog 2020-06-01 18:15:03 +02:00
c87cfed525 remove old status urls 2020-06-01 16:03:22 +02:00
ebd1e04414 remove sdr.hu parts 2020-06-01 15:58:15 +02:00
1019ed5793 fill gain input with values 2020-05-31 21:24:07 +02:00
adcac7b54a hackrf gain settings 2020-05-31 20:52:45 +02:00
d3a3078504 soapy gain input box for airspyhf 2020-05-31 20:43:12 +02:00
ac18a76c14 split stuff into separate files 2020-05-31 20:25:41 +02:00
66b5f17d38 implement soapy gain input 2020-05-31 19:57:20 +02:00
9763f302f3 switch to csdr and owrx_connector development versions 2020-05-31 15:04:09 +02:00
1359da5b14 limit SIMD flags to x86 only 2020-05-31 01:04:57 +02:00
063d22f88c build with lime SIMD limited to SSE3 for better portability, refs #38 2020-05-31 00:55:21 +02:00
7681830256 add soapy module for hackrf 2020-05-30 23:41:30 +02:00
3371697e18 add bias_tee mapping 2020-05-30 23:03:43 +02:00
bfe6c00f90 add debian changelog entry, too 2020-05-30 22:59:45 +02:00
e90973bcd4 switch hackrf to soapy 2020-05-30 22:58:31 +02:00
e0648d63ad reduce image size by excluding wsjt-x and js8call frontend binaries 2020-05-28 00:45:27 +02:00
564c1e26b6 let's try auto-apt-proxy to cut down build times 2020-05-25 20:38:42 +02:00
27d6802dfc include wsjt-x patches 2020-05-25 20:31:42 +02:00
d2a4f2bc46 patch wsjt-x to use packaged hamlib, too 2020-05-25 20:30:53 +02:00
d24abd436e install s6 overlay during normal dependency setup 2020-05-25 20:10:03 +02:00
305adc94fa install s6 overlay for the right platform 2020-05-24 21:45:08 +02:00
d9db693aec add changelog 2020-05-24 18:02:45 +02:00
d64f08490a use the old syntax 2020-05-24 18:00:14 +02:00
a982c86794 update sdrplay patches; fix sdrplay service 2020-05-24 17:28:48 +02:00
6c307d885f integrate s6 service layer for sdrplay 2020-05-24 16:00:36 +02:00
048210d7da update to latest versions from the homepage 2020-05-24 14:59:11 +02:00
d2be712de8 include sdrplay lib from sdrplay repo 2020-05-24 14:46:17 +02:00
3a8256e3bc update to the sdrplay repository version 2020-05-24 14:43:25 +02:00
385c241858 Merge branch 'develop' into sdrplay_v3 2020-05-24 14:05:36 +02:00
a1da591218 rtl_connector optimization 2020-05-24 13:50:28 +02:00
f1d9a4a28c switch to shift_addfast_cc for better performance 2020-05-24 03:04:20 +02:00
29b3f530d2 update again, latest fixes for aarch64 2020-05-24 02:44:55 +02:00
e1f83727b7 update csdr to latest 2020-05-24 00:42:47 +02:00
17f4f671a6 add a changelog entry about docker debian rebuild 2020-05-24 00:41:18 +02:00
4b8ef29775 add the fmv-optimized owrx_connector in docker, too, refs #38 2020-05-23 22:55:00 +02:00
5377087848 don't install unnecessary dependencies 2020-05-23 22:53:12 +02:00
1fedd0e50f limesdr requires libatomic 2020-05-23 22:52:22 +02:00
6cac3b4d39 restore startup 2020-05-23 22:51:46 +02:00
d9292587ec part 2: all the image builds 2020-05-23 19:59:31 +02:00
cf4f1dce32 rebuild docker containers with debian, stage 1: base 2020-05-23 18:06:46 +02:00
1299f5e9cc update csdr in docker to the latest version 2020-05-22 21:25:22 +02:00
48b177defa provision for a custom gain control 2020-05-17 21:21:37 +02:00
63475dda78 implement field sorting 2020-05-17 20:25:49 +02:00
9dd7a7e653 remove the remnants of the templating configuration 2020-05-17 18:51:36 +02:00
b624bef345 add broadcast bands 2020-05-17 18:45:01 +02:00
a03176223a add a bit more dynamic content 2020-05-17 18:44:26 +02:00
98cb1a8389 use the new version without FMV 2020-05-17 11:19:22 +02:00
ddbc844954 update csdr 2020-05-17 01:38:08 +02:00
d22ab23771 set package build flag to disable optimizations 2020-05-16 21:29:16 +02:00
0a60b505b8 update dependencies, refs #38 2020-05-16 19:03:48 +02:00
2b4799591f initialize logging early since there may be messages happening in
imports
2020-05-14 22:57:09 +02:00
048aab682f include changed wsjt keys in config migration 2020-05-14 22:56:49 +02:00
e557d46c0d apply darkly theme 2020-05-14 22:31:54 +02:00
10d6309608 add rockprog as a dependency 2020-05-14 21:40:28 +02:00
7d41fc8b06 pass temporary directory to services, too 2020-05-11 23:45:44 +02:00
2483398b0f clean up .wav files on exception, refs #107 2020-05-11 23:20:03 +02:00
a94209a2bc apply some alt tags to images 2020-05-11 20:31:21 +02:00
db7b4f195e fix for offset_freq when demodulator is exactly on center_freq 2020-05-11 15:04:24 +02:00
b0f7fd5d00 ability to add more config keys 2020-05-10 22:42:09 +02:00
96b1de1856 register different input types 2020-05-10 20:34:34 +02:00
9366d67218 dynamic sdr device settings 2020-05-10 20:18:42 +02:00
8df885b727 download receiver details via rest api 2020-05-10 17:27:46 +02:00
11cf2a96e2 create a receiver details route for use in the header 2020-05-10 17:12:42 +02:00
f62bd8be36 Merge branch 'develop' into radioberry 2020-05-10 17:03:58 +02:00
813474b5d6 make the header work on all pages 2020-05-10 17:03:30 +02:00
508ea2cf96 create a javascript profile for the map, too 2020-05-10 17:03:30 +02:00
a37e5ac93f header is now collapsed by default; simpler javascript 2020-05-10 17:03:30 +02:00
2c1ec7df74 make the header work on all pages 2020-05-10 16:23:05 +02:00
4971bee67c create a javascript profile for the map, too 2020-05-10 16:12:37 +02:00
eaa41c3256 header is now collapsed by default; simpler javascript 2020-05-10 16:07:14 +02:00
5606646064 implement basic support for radioberry 2020-05-10 00:03:14 +02:00
59a7842c6d fix map info window popping up after close 2020-05-09 01:18:51 +02:00
149ad8dcc6 move rx_photo code to header 2020-05-09 01:03:43 +02:00
3a5e227ab5 integrate feature report 2020-05-09 00:27:42 +02:00
3202f48f8e header details on map, too 2020-05-09 00:20:38 +02:00
3a455a0452 start collecting header routines 2020-05-09 00:11:20 +02:00
f2288ceb49 let's work with frame targets 2020-05-08 23:53:50 +02:00
dba4f91c77 include homepage 2020-05-08 23:49:02 +02:00
1f565355ec change available mode highlighting, refs #95 2020-05-08 23:34:34 +02:00
af1cfee754 allow switching underlying modulation (if available) refs #95 2020-05-08 22:56:02 +02:00
9563adacf7 more jquery magic for progressbars 2020-05-08 21:35:45 +02:00
fc7188145b use jquery to store progressbar objects 2020-05-08 21:18:03 +02:00
ceafcbf850 fix secondary demod being false 2020-05-06 23:00:57 +02:00
7fbd024ed5 fix sql=0 parameter 2020-05-06 22:52:48 +02:00
66a4f29911 let's try pre-loading the pipes to improve dsp initialization 2020-05-06 19:54:55 +02:00
eab3bf780e fix problems with sdr device failover detection 2020-05-04 20:36:17 +02:00
efa9771ad7 let's move some logic to the dialog 2020-05-04 00:20:01 +02:00
e2cacc1fa0 only available ones 2020-05-03 23:58:12 +02:00
93b8f75cc3 automatically load modes into bookmark dialog 2020-05-03 23:56:22 +02:00
a6a29b7032 actually, it's better to catch the exception inside 2020-05-03 21:50:40 +02:00
981d3b6673 ignore keyerrors in this case 2020-05-03 21:28:37 +02:00
8e313517d1 initialize frequeny correctly 2020-05-03 21:26:11 +02:00
beed0c1a70 improve squelch handling
squelch is now included in the URL hash
some modes now have the squelch visually disabled, refs #65
2020-05-03 19:55:48 +02:00
d98abe42bc fix configurable_keys exception 2020-05-03 17:50:37 +02:00
52367e53f5 remove the debugging 2020-05-03 17:46:32 +02:00
acb392e56c reset & stabilize modes 2020-05-03 13:10:54 +02:00
ac136313cb keep back changes until start command is given 2020-05-03 13:10:25 +02:00
e92a91663d restart demodulator based on modes 2020-05-03 12:48:25 +02:00
26ba8ca999 update bandpass for secondary modes 2020-05-03 12:23:23 +02:00
e409c37158 add remark about js8 binary location 2020-05-03 12:09:36 +02:00
2f2d52df85 re-wire digital voice meta panels 2020-05-03 12:09:18 +02:00
0868e643c9 return after sending 404 2020-05-02 16:59:27 +02:00
1bfe768601 hash handling fits better into here now 2020-05-02 15:17:09 +02:00
3405bc485b fix profile switching 2020-05-02 15:07:47 +02:00
6ff1b7d20a fix reconnection behavior 2020-05-02 14:51:00 +02:00
3504c8b54e update changelog 2020-05-02 14:40:01 +02:00
e01a12a945 just a comma 2020-05-02 13:57:19 +02:00
8c8445eb3b improve receiver load times by concating javascript 2020-05-02 13:35:42 +02:00
7a3043559f initialize mouseover display 2020-05-02 02:35:55 +02:00
54812f0de1 fix band changes 2020-05-02 02:32:49 +02:00
28c1425a8f fix digimode init from hash 2020-05-02 02:13:16 +02:00
a96690c8bd fft_fps isn't even used in the frontend 2020-05-02 01:36:12 +02:00
e5196c6af9 prevent starting demodulator if already started 2020-05-02 01:35:38 +02:00
19518da2e2 fix filter setup 2020-05-02 01:25:23 +02:00
b956a0dcd6 resolve todos 2020-05-02 01:16:36 +02:00
20023e3989 update bookmarks 2020-05-02 01:10:41 +02:00
d9a818525d refactor demodulator classes, part 2 2020-05-02 01:07:44 +02:00
b8f7686a6d refactor demodulator classes, part 1 2020-05-02 00:05:20 +02:00
5013af2117 combine methods 2020-04-30 23:31:52 +02:00
02a6326605 fix method names in comments 2020-04-30 23:20:56 +02:00
1441b9610c refactor into the classes, too 2020-04-30 23:16:49 +02:00
56f3f089a1 fix debugging; synchronize startup 2020-04-30 22:54:44 +02:00
1764abe65f update secondary parameters 2020-04-30 22:31:18 +02:00
33762574c3 improve demodulator initalization, part 2: refactor js classes 2020-04-30 22:07:19 +02:00
f1dc9af651 use synchronized setup; start dsp later 2020-04-27 22:49:24 +02:00
25a7bbd86a reset secondary demodulator, too 2020-04-26 23:14:34 +02:00
6a8168025d improve demodulator initialization 2020-04-26 22:46:30 +02:00
26321ab68b keep more parameters on the server side 2020-04-26 18:45:41 +02:00
449b3b3986 features no longer used on this level 2020-04-26 17:19:05 +02:00
39f9d4c273 streamline button generation 2020-04-26 17:18:48 +02:00
bb1b561c47 fully-automatic mode panel generation 2020-04-26 16:58:31 +02:00
907787cfdc implement first stages of active mode communication 2020-04-26 15:17:03 +02:00
e61d3a22a3 add if_mode mapping for sdrplay, refs #105 2020-04-26 13:49:03 +02:00
fb90a4e54b display sdr devices 2020-04-26 02:15:19 +02:00
5282b5f8df implement redirect on login 2020-04-26 01:54:48 +02:00
9942b3baf2 separate page for sdr settings 2020-04-25 21:55:52 +02:00
b874583931 setup for multiple settings sections 2020-04-25 21:42:00 +02:00
2f011ea249 add remark about web admin 2020-04-25 20:57:12 +02:00
a4ebf87263 check for key 2020-04-25 20:55:33 +02:00
dd492fa63c hide "settings" link if features is disabled 2020-04-25 20:52:41 +02:00
4dc10fb6a3 lose the logo 2020-04-25 20:36:08 +02:00
4a2b81c793 use autogain on airspyhf 2020-04-25 20:32:11 +02:00
e064352621 finally, remove debugging 2020-04-25 19:18:30 +02:00
b58357741a separate modes in here, too 2020-04-25 19:05:24 +02:00
2198c00d00 add js8 settings to web configuration 2020-04-25 17:33:30 +02:00
978eea400d clean up wsjt remainders in absctract code 2020-04-25 16:22:40 +02:00
a828f61c72 use right message delay for mode 2020-04-24 23:47:05 +02:00
4e67be8a3c dynamic profiles 2020-04-23 23:30:56 +02:00
623f21f769 fast and turbo modes 2020-04-23 22:27:03 +02:00
34838abfa9 profiles 2020-04-23 22:21:26 +02:00
280e39d9c4 js8 slow mode 2020-04-23 22:19:07 +02:00
2df56ad8b9 js8 slow mode (attempt?) 2020-04-23 00:34:49 +02:00
5ab2f02f63 multi-profile decoding 2020-04-23 00:21:59 +02:00
0120b33a25 refactor chopper out of wsjt 2020-04-22 23:53:19 +02:00
9622cd6a2a Merge branch 'develop' into js8call 2020-04-22 18:34:10 +02:00
78ccaa7d65 access regex groups in python 3.5 compatible way, closes #109 2020-04-22 18:28:45 +02:00
4f07c62cc9 use the latest available thread 2020-04-21 21:00:16 +02:00
520ddbb034 Merge branch 'develop' into js8call 2020-04-21 19:27:13 +02:00
0a16500133 get avatar path from pkg_resources, refs #108 2020-04-21 19:24:57 +02:00
681a583711 always begin a new message if the flag says so 2020-04-21 18:11:07 +02:00
aa4362fe9f add js8 to the changelog 2020-04-20 22:12:33 +02:00
0c12d07a26 finalize visual message representation 2020-04-20 22:07:21 +02:00
f474ab94d2 close threads when ending message has been received 2020-04-20 18:31:45 +02:00
5ba77012a7 update js8py library 2020-04-19 23:42:36 +02:00
a573fa0b93 Merge branch 'develop' into js8call 2020-04-19 23:38:51 +02:00
9a86bc23be make hackrf sleep for 1 second on restarts (device is not released
immediately)
2020-04-19 23:36:35 +02:00
c90b415c8b add scroll-to-bottom and cleanup intervals 2020-04-19 23:35:06 +02:00
4287387a5e threading frontend implementation 2020-04-19 22:10:32 +02:00
32bd1bb4aa install js8py 2020-04-18 00:41:16 +02:00
1023087c8a get locator from compound frame, too 2020-04-17 23:50:23 +02:00
5843aec342 fix js8call in the docker build 2020-04-16 22:01:51 +02:00
f52bf560ec add hamlib and js8 to docker (not working yet) 2020-04-15 23:20:17 +02:00
05a4139f94 add js8call dependency 2020-04-15 22:26:45 +02:00
116e20335e Merge branch 'develop' into js8call 2020-04-15 22:25:14 +02:00
5e6b45eaec Merge branch 'develop' of github.com:jketterl/openwebrx into develop 2020-04-15 21:40:38 +02:00
aa38340415 Merge pull request #104 from moepman/fix-hackrf-ppm
hackrf: properly use ppm setting as parameter
2020-04-15 21:40:29 +02:00
4d157d275a hackrf: properly use ppm setting as parameter 2020-04-15 21:22:06 +02:00
70818836de switch to recommended dependencies 2020-04-15 20:40:03 +02:00
1f70b93310 seems like we're in upper case 2020-04-14 23:16:45 +02:00
4c604bf400 Merge branch 'develop' into js8call 2020-04-14 22:37:22 +02:00
7fe694ba0a add urls to debian packaging 2020-04-14 22:36:59 +02:00
eb9059a711 switch to homepage url 2020-04-14 22:36:59 +02:00
da4917998d js8 metrics 2020-04-14 22:31:30 +02:00
99b4a25de7 js8 service 2020-04-14 21:27:50 +02:00
899445d586 display messages on the web 2020-04-14 21:12:25 +02:00
2de0cbc6c0 send messages to frontend, spots to pskreporter 2020-04-14 21:10:35 +02:00
7948d1f27a move dmr_filter property to the right list 2020-04-14 13:43:26 +02:00
bcb8a2315c use new library for js8 decoding 2020-04-13 16:35:31 +02:00
ddfd85c586 add js8 decoding if available 2020-04-12 13:10:23 +02:00
0e8715b5a1 the space has been introduced at some point, make it optional 2020-04-12 00:53:58 +02:00
1b2e237816 increment connector dependency 2020-04-12 00:32:01 +02:00
6d43126fa5 remove unused import 2020-04-10 20:05:06 +02:00
3c0146b1c4 add patches for armv7l and aarch64 2020-04-10 18:37:09 +02:00
893a56aa83 update install script patch 2020-04-10 18:03:19 +02:00
f7c9fbcc22 factory name has been changed in v3 2020-04-10 17:25:32 +02:00
aa29836039 remove debugging output 2020-04-10 17:21:53 +02:00
c30740c4e3 add uhd and redpitaya device modules; switch driver detection to
factories
2020-04-10 16:33:04 +02:00
d07cbb2b10 more abc 2020-04-05 21:48:05 +02:00
8fdf263e4b explicitly cast frequency 2020-04-05 21:47:40 +02:00
4d67b684e4 refactor 2020-04-05 19:08:58 +02:00
d06e9151b9 pass the frequency along with the job, refs #22 #61 2020-04-05 16:35:46 +02:00
366def0235 use abc 2020-04-05 15:22:23 +02:00
2301141b44 add missing keys() method 2020-04-02 18:21:45 +02:00
112eda2021 use the command mapper to generate event keys 2020-04-02 00:10:28 +02:00
d9e15357f3 update connector for docker 2020-04-01 23:50:00 +02:00
70ba0cd618 add direct_sampling mapping for rtl_sdr 2020-04-01 23:37:40 +02:00
78704885d7 drop another todo 2020-04-01 22:39:32 +02:00
513b477fac add user.json provisioning 2020-04-01 22:31:14 +02:00
6c3bb0b520 add first user storage implementation 2020-04-01 22:29:42 +02:00
c2e85ce9a6 web admin is disabled by default for now 2020-04-01 21:40:33 +02:00
3f742c7b1a webadmin feature flag 2020-04-01 21:39:53 +02:00
b7831b824a update dependencies 2020-03-29 22:48:10 +02:00
f0ef5bb371 add location picker so set receiver location 2020-03-29 21:40:29 +02:00
29566430a6 add location input fields 2020-03-29 20:49:37 +02:00
a3126b060d add forms to setup 2020-03-29 20:15:13 +02:00
2ef80eee1d refactor and format 2020-03-29 20:14:34 +02:00
65a0320cea refactor 2020-03-29 19:52:56 +02:00
199dfe106a add a new multi-checkbox to select background detection services 2020-03-29 19:50:37 +02:00
056a8a3289 migrate waterfall settings away from tuples 2020-03-29 18:49:13 +02:00
1d5f450f74 config file brush-up 2020-03-29 18:35:48 +02:00
7914202df3 move over to fork 2020-03-29 18:33:14 +02:00
a6b5984dce migrate to version 2 2020-03-29 18:28:18 +02:00
fd9e913a49 config migration for receiver_gps 2020-03-29 18:08:26 +02:00
2b7d6738f1 switch to json to avoid external dependency 2020-03-29 17:14:37 +02:00
f81e53e455 fix typo 2020-03-28 00:40:36 +01:00
3011e62fad add first steps towards a storage implementation 2020-03-27 23:44:03 +01:00
54dc412c4a add number types 2020-03-27 22:00:10 +01:00
0e9bb45d89 add more fields 2020-03-27 21:11:33 +01:00
6493fb86c1 add sdr.hu settings 2020-03-27 01:14:38 +01:00
df21a1eed6 send initial settings 2020-03-27 00:35:05 +01:00
c5a5d25320 update config settings directly in the frontend 2020-03-26 23:34:25 +01:00
7efe254a66 apply new values to config 2020-03-26 23:04:02 +01:00
d71dc35239 fill the form with data 2020-03-26 22:08:24 +01:00
ab9df41a21 render inputs in code, not in html 2020-03-26 21:52:34 +01:00
16639c0b5b add autofocus 2020-03-26 20:19:05 +01:00
2d86483907 no more debugging for the map 2020-03-26 20:13:36 +01:00
24a4d03eff note about agc in changelog 2020-03-26 17:28:37 +01:00
0d93186066 drop the passed modulation if the frequency is invalid 2020-03-26 15:36:49 +01:00
69b43b40b5 update changelog 2020-03-26 13:38:14 +01:00
16d5db00af send bias tee configs for rtl_sdr 2020-03-26 13:33:32 +01:00
b87f7017d1 remove unused detector 2020-03-26 13:14:25 +01:00
8a053f47d4 update changelog 2020-03-26 12:53:58 +01:00
895d8019e3 switch to raw mode to avoid arecord file size limit 2020-03-26 09:45:41 +01:00
25755d09dd improve waterfall auto-adjust for SDRs with oversampling 2020-03-25 21:50:22 +01:00
a7345bb16f propagate measurement reset to reporters, closes #88 2020-03-25 20:49:34 +01:00
0bffc2b3dd this doesn't do anything useful any more 2020-03-25 20:35:42 +01:00
14382e012f don't send event when value doesn't change 2020-03-25 17:59:00 +01:00
0e19a40968 fix import 2020-03-25 15:48:27 +01:00
4aac5c9584 use the interface 2020-03-25 15:47:15 +01:00
8a2356580a rename 2020-03-24 22:52:17 +01:00
4e4266f1c4 fix wording 2020-03-24 22:50:43 +01:00
cfea251d60 clean up 2020-03-24 22:50:18 +01:00
d1ef1810bf update changelog 2020-03-24 22:35:44 +01:00
25b287344f rename collect -> filter 2020-03-24 22:16:11 +01:00
f30cf3fecd fix up properties in the application 2020-03-24 22:13:42 +01:00
236f3d2058 more layer replacement 2020-03-24 22:11:54 +01:00
14634af83c add layer add / remove events + tests 2020-03-24 20:36:26 +01:00
4b7ac0e299 remove unused specials 2020-03-24 00:29:59 +01:00
cc5c130f49 fix secondary demod; add same-value handling 2020-03-24 00:18:10 +01:00
d5c2f8414e add stack event handling 2020-03-24 00:08:48 +01:00
c83d8580ba rewrite property engine
Property class is gone; logic is now done with Layers, Stack and Filter
2020-03-23 23:56:05 +01:00
7562dc8ecb use dictionary api 2020-03-23 22:09:41 +01:00
37e74f9027 use dictionary api 2020-03-23 22:09:26 +01:00
7cae383127 include defaults 2020-03-23 22:09:05 +01:00
b25e61ae9a rename 2020-03-22 21:59:22 +01:00
885d02ceca start implementing property layering 2020-03-22 21:51:49 +01:00
b3a5a36d9c more tests 2020-03-22 19:42:59 +01:00
5076f79aaa add owrx.property to the setup 2020-03-22 15:39:59 +01:00
9768fa7c50 add docker build for perseus 2020-03-22 15:32:39 +01:00
92cd65b66f remove installation leftovers 2020-03-22 11:56:43 +01:00
541c38151f split config and property code, first test 2020-03-21 22:40:39 +01:00
7948b7bfa1 move openwebrx installation to the end to profit from docker build cache 2020-03-21 21:44:09 +01:00
05485ba8e3 add perseus basic build (not enabled for now) 2020-03-21 18:58:03 +01:00
2505e95d1c reduce layers 2020-03-21 15:54:17 +01:00
135e9ae7b9 compile the connector into soapy for faster builds 2020-03-21 15:49:22 +01:00
8ed6dbe5d1 update changelog 2020-03-21 15:45:50 +01:00
752cd42ad7 Merge pull request #86 from amontefusco/iw0hdv
Perseus HF Receiver integration
2020-03-21 15:40:54 +01:00
fbf74a1286 add bitpack flag for airspy 2020-03-21 15:18:45 +01:00
55e1a97d43 update changelogs 2020-03-21 15:13:11 +01:00
8a03951713 re-align main buttons 2020-03-16 22:48:42 +01:00
1a1ad670ee fix background 2020-03-16 22:32:07 +01:00
5273131b25 apply new image background 2020-03-16 22:16:56 +01:00
d74b79f585 references to Perseus HF receiver removed from main config file 2020-03-16 18:05:49 +01:00
e1af089658 Merge branch 'develop' into iw0hdv 2020-03-16 17:39:53 +01:00
34ee5d8e3b More info on Perseus integration. 2020-03-16 00:21:49 +01:00
68e8a77b1d more refinements as per Jakob Ketterl suggestions 2020-03-16 00:13:51 +01:00
edded220b5 add the mailing list links 2020-03-15 23:39:38 +01:00
1581c659af add version to startup messages 2020-03-15 23:34:44 +01:00
ca5889f925 introduce config checking infrastructure 2020-03-15 23:32:19 +01:00
6e6861479d fix bugs with negative lat / long; update formatting
ref: #81
2020-03-15 18:46:37 +01:00
8e87aa0342 Merge branch 'develop' into iw0hdv 2020-03-15 17:25:56 +01:00
97cb51d990 Perseus SDR HF receiver first support 2020-03-15 17:24:36 +01:00
d2ce27eeab convert boolean values into something that soapy understands 2020-03-14 23:07:23 +01:00
00a7b7877c update parameter to match latest dev code 2020-03-14 23:06:52 +01:00
c387fe0fe9 add fictional bias_tee mapping for rtl_sdr_soapy
needs to be implemented in SoapyRTLSDR first
2020-03-14 01:56:17 +01:00
fea2cd1cc5 add new settings mappings for rf_notch and dab_notch 2020-03-14 01:21:43 +01:00
7742d7a048 don't include None values 2020-03-14 01:21:30 +01:00
e37e2f4540 add biastee setting for sdrplay, too 2020-03-14 01:15:25 +01:00
4deb4c781e use new mechanism for airspy bias-tee, too 2020-03-14 01:13:23 +01:00
5da2047935 introduce a generic mapping from sdr properties to soapy settings 2020-03-14 01:04:52 +01:00
fb82daf936 add to changelog 2020-03-13 23:55:45 +01:00
ede40e4a68 always add OSM source, switch when no google maps key is present. 2020-03-13 23:53:14 +01:00
3852f28fd4 Merge pull request #72 from jquagga/develop
Add fallback to use OpenStreetMap/Wikipedia Maps
2020-03-13 23:52:47 +01:00
c385fd635b Add fallback to use OpenStreetMap/Wikipedia Maps 2020-03-11 10:27:46 -04:00
b9ac887eed add the first form elements 2020-03-08 23:23:36 +01:00
a2dc2b3085 align the icons 2020-03-08 22:33:41 +01:00
6ab77f958c add settings button, start with the admin template 2020-03-08 21:28:15 +01:00
4928f80929 let's try to close that bracket 2020-03-07 21:23:08 +01:00
687e504af4 replace links 2020-03-07 20:53:17 +01:00
14b293e0cb add note about groups.io 2020-03-05 22:03:19 +01:00
beb59da6a6 remove incomplete setup instructions and link to the wiki 2020-03-05 20:53:47 +01:00
c2702e02a9 use the recommended way to generate google maps urls 2020-03-05 17:52:40 +01:00
6b4509fca5 update owrx_connector 2020-03-02 21:55:21 +01:00
8abfe059b7 now the sequence doesn't matter any more 2020-02-28 16:55:50 +01:00
10523dbbd7 use threading to uncouble the queues 2020-02-28 16:13:53 +01:00
b8c71109b8 initialize dmr filter, too 2020-02-28 00:30:41 +01:00
9cc850e578 introduce new pipe classes to improve sequencing 2020-02-28 00:20:37 +01:00
0e47f2d92a update changelog 2020-02-27 23:23:22 +01:00
fbcfb550a2 pass direct sampling mode changes to owrx_connector 2020-02-27 23:21:00 +01:00
a388acdf03 update changelog 2020-02-27 22:54:42 +01:00
d36be799d0 improve lock handling 2020-02-27 19:48:22 +01:00
c325368be8 improve variable handling 2020-02-27 18:50:53 +01:00
388218f9df implement a reconnection loop for direwolf, ref #60 2020-02-27 18:43:58 +01:00
6b2656efae fix constructor 2020-02-27 18:43:44 +01:00
278fab268f use dicts for the pipes 2020-02-25 20:55:42 +01:00
bd8b8ca410 session cookie handling 2020-02-23 21:52:13 +01:00
fb7422e5a8 generate session cookie 2020-02-23 21:39:12 +01:00
a70c51193b parse login data 2020-02-23 20:52:32 +01:00
fa75cac7f5 post login data 2020-02-23 20:25:36 +01:00
de3694248a restore audioworklets 2020-02-23 20:14:07 +01:00
9f06149ae3 add shadow 2020-02-23 20:13:36 +01:00
437e28c3a9 add templating 2020-02-23 20:13:11 +01:00
cad6175db0 login form 2020-02-23 20:04:19 +01:00
af053b9ac4 no more abstract methods 2020-02-23 19:29:17 +01:00
0a20cb5e41 prepare route protection 2020-02-23 19:23:18 +01:00
aa9737498a add controller options to allow multiple routes per controller 2020-02-23 18:32:37 +01:00
42191f4e77 rewrite routing logic 2020-02-23 17:53:02 +01:00
451eb99f8a split the controllers into separate files 2020-02-23 17:22:13 +01:00
b110705f45 fix this in develop, at least 2020-02-21 22:37:10 +01:00
36e94d4e3c fix typo 2020-02-20 22:30:56 +01:00
4e98bbc1c9 continue development as version 0.19 2020-02-20 22:01:21 +01:00
c3b13b224c add back under construction panel 2020-02-20 21:58:08 +01:00
5f388fd38d add dependency to soapysdr-tool to make SoapySDRUtil available 2020-02-19 20:06:27 +01:00
9bc161c140 split the manifest step into a separate skript 2020-02-18 22:47:51 +01:00
dbb7c0cde3 remove the "under construction" banner 2020-02-18 22:26:44 +01:00
52e517dfc3 make tags overridable from the outside 2020-02-18 21:52:52 +01:00
37ffb2a02c break lines at 80 chars 2020-02-18 21:19:00 +01:00
91b3713dad fix date 2020-02-18 21:09:22 +01:00
c53ac1aa4f pin the dependency release commits 2020-02-18 20:58:01 +01:00
c4166997be release version 0.18 2020-02-18 20:55:24 +01:00
f0f9455c6e add the changelog to the debian package 2020-02-18 20:53:53 +01:00
7bc78425cd add user to plugdev group, fix some lintian issues 2020-02-17 17:05:31 +01:00
d1dc14d9e5 don't put debian files in docker builds 2020-02-17 15:03:39 +01:00
521755b9f2 create and use custom user on debian install 2020-02-17 15:03:20 +01:00
ad565c5a2b re-wire the audio output to "null" - thanks to @dl9rdz 2020-02-17 12:06:13 +01:00
ebba6e1ada use more cpu cores 2020-02-16 12:19:49 +01:00
0b7b5d985f update copyright date 2020-02-16 11:49:20 +01:00
b948e06a4f use urllib to update sdr.hu, no wget dependency
ref: #52
2020-02-15 00:16:04 +01:00
eaa98b0d64 new status controller as json 2020-02-09 21:46:03 +01:00
16b3c11678 add soapy remote to docker build, too 2020-02-09 15:23:17 +01:00
c92929a32d add soapyremote source 2020-02-09 13:59:37 +01:00
46c3e5077d fix typo 2020-02-08 21:43:47 +01:00
dc12c54ae6 fix libiio installation 2020-02-08 21:05:12 +01:00
bdc43455a5 add dependencies 2020-02-08 19:53:23 +01:00
42eeb00a0f add limesdr build 2020-02-08 19:47:16 +01:00
5951d2a874 add docker build for pluto 2020-02-08 19:01:50 +01:00
9a5aba7313 disable config interface unless explicitly enables in the config 2020-02-08 18:29:48 +01:00
d94914629f update changelog to reflect new image 2020-02-08 17:55:59 +01:00
216ede189c style the input 2020-02-01 22:25:16 +01:00
0191ed7ad6 abort frequency input on ESC key 2020-02-01 21:48:46 +01:00
8036758857 improve error handling on band and bookmark loading 2020-02-01 21:37:43 +01:00
41bc168a38 Merge pull request #51 from ofadam/patch-1
Fixed typo
2020-01-29 21:44:31 +01:00
14ea326f43 Fixed typo
2019 reference should have been 2020.
2020-01-29 14:35:52 -06:00
fcc907d488 add to changelog 2020-01-29 20:14:03 +01:00
2869fc3642 Merge branch 'develop' into daylight-scheduler 2020-01-29 20:12:35 +01:00
dc1fb3b607 more readme updates 2020-01-29 20:11:26 +01:00
1258180805 update the readme 2020-01-29 20:05:06 +01:00
b35958c6eb update changelog, closes #47 2020-01-29 19:58:36 +01:00
152737e8f6 split out the changelog into a separate file 2020-01-29 19:19:57 +01:00
840f624b21 Merge branch 'develop' into daylight-scheduler 2020-01-25 23:53:10 +01:00
cd1f8a7cb1 update dependencies in docker 2020-01-25 23:52:20 +01:00
49c333b88a include digital demods in hash 2020-01-25 23:47:32 +01:00
8fc981c8a0 use static elements 2020-01-25 22:47:47 +01:00
4b60b7e046 frequency editor on click 2020-01-25 22:35:44 +01:00
92254c8c4d update hash when demodulator params change 2020-01-25 21:15:05 +01:00
34312dd402 fix url hash parsing 2020-01-25 20:53:55 +01:00
b63a991008 redo the scheduling so it works close to the dateline, too 2020-01-24 23:29:25 +01:00
4f36df6324 some work on the agc (doesn't work for all stations) 2020-01-24 11:42:20 +01:00
05af69f7b2 Merge branch 'develop' into daylight-scheduler 2020-01-23 11:15:18 +01:00
641907893c Merge pull request #48 from dh5ym/develop
Fix PlutoSDR support
2020-01-22 22:23:12 +01:00
7e2c2ad323 Fix PlutoSDR support 2020-01-22 21:55:22 +01:00
4e3d6527dd Merge pull request #2 from jketterl/develop
update
2020-01-22 21:51:19 +01:00
5b9344dee9 fix evening greyline 2020-01-20 17:29:32 +01:00
6157aba1ec Merge branch 'develop' into daylight-scheduler 2020-01-19 19:08:59 +01:00
f06f1265d8 just calculate today's schedule, makes things much easiear 2020-01-19 18:54:53 +01:00
1f68ecd9f4 add greyline calculation 2020-01-19 18:34:37 +01:00
877f0e4c28 allow schedule entries with datetime 2020-01-19 17:04:14 +01:00
af7437ab04 switch to monospaced font for better mousewheel tuning 2020-01-19 16:09:56 +01:00
f1e5e9a765 Merge branch 'develop' into daylight-scheduler 2020-01-19 10:52:43 +01:00
136b668f8f fix bookmark tuning 2020-01-19 10:50:40 +01:00
24032f4f5a Merge branch 'develop' into daylight-scheduler 2020-01-19 01:01:26 +01:00
18a63a6e7b mousewheel tuning 2020-01-19 00:00:51 +01:00
ae98e6bc56 refactor frequency display 2020-01-18 21:33:10 +01:00
b142180f94 optimize 2020-01-18 17:35:33 +01:00
f826002ea8 enable solar calculations 2020-01-18 00:43:37 +01:00
12be082523 refactor service / schedule code in preparation for alternate schedulers 2020-01-17 22:46:01 +01:00
470fc43646 avoid using preexec_fn in the other places, too 2020-01-17 21:18:02 +01:00
c12a4ecb80 Merge pull request #1 from jketterl/develop
merge changes to my fork
2020-01-17 15:06:30 +01:00
ea5b5dc8fb avoid preexec_fn (something's leaky there) 2020-01-17 12:17:15 +00:00
79ab37e6a0 add rtlsdr via soapy to the docker builds; clean up 2020-01-17 12:58:26 +01:00
0f1d219002 Merge pull request #44 from dh5ym/develop
Adding PlutoSDR support via SoapySDR, closes #27
2020-01-17 12:43:19 +01:00
7bf4c48733 Adding support for PlutoSDR (Adalm Pluto) via SoapySDR 2020-01-15 22:44:11 +01:00
d7aaf0d00e Adding support for PlutoSDR (Adalm Pluto) via SoapySDR 2020-01-15 22:42:08 +01:00
758b15e887 set parameters for psk63 mode 2020-01-13 20:10:14 +01:00
c3d89bd4bf fix device mixup 2020-01-10 23:31:51 +01:00
ad5683279e allow wider filter for pocsag; fix filter display; 2020-01-10 23:26:29 +01:00
14198aaa17 fix table alignment for long messages 2020-01-10 23:25:49 +01:00
976c15d29a parse address as a numeric field 2020-01-10 22:11:57 +01:00
ba9a9096bf use the nice error overlay, closes #28 2020-01-10 21:43:21 +01:00
cbd87abc3d add automatic backoff when server is at capacity 2020-01-10 21:38:46 +01:00
5a57648eec add direct sampling option, ref #37 2020-01-10 20:50:56 +01:00
b7538dcdd0 add alternate soapy driver for rtl-sdr sticks 2020-01-10 20:43:28 +01:00
aee1642ef6 add limesdr soapy driver module 2020-01-10 19:54:53 +01:00
ac92df2149 close pocsag message window on profile change 2020-01-09 23:48:48 +01:00
44c1edb2dd update legal information
remove andras from contacts since he discontinued openwebrx
2020-01-09 22:24:39 +01:00
2ea8812fda remove 3d view aka mathbox since it consumes more than 1MB data per
visit
2020-01-09 21:52:47 +01:00
922a5ed607 fix gain introduced by filtering 2020-01-09 21:44:36 +01:00
98e227c102 update digiham dependency 2020-01-09 19:33:17 +01:00
5a0398ceb5 require new digiham version 2020-01-09 19:26:41 +01:00
ebb7398446 update to latest digiham 2020-01-09 19:23:40 +01:00
e0501cff0f add owrx message passing and frontend 2020-01-09 15:12:51 +01:00
0e528c9267 refactor parsers; introduce new pocsag parser 2020-01-09 15:11:53 +01:00
0f8c86a26c 20 was too wide 2020-01-09 14:00:32 +01:00
f05ac31dc4 don't choke on invalid characters 2020-01-09 13:49:38 +01:00
2bb877a84b let's go for 20kHz for now 2020-01-09 13:49:15 +01:00
887cc3a88a sample pocsag data in 48kHz, too, allowing for wider filters 2020-01-09 13:47:47 +01:00
52199dd800 some preliminary styles 2020-01-08 22:40:44 +01:00
94b486cf2e wider filter for pocsag (as wide as possible) 2020-01-08 22:36:22 +01:00
db508fc4f7 inversion mode 2020-01-07 07:30:19 +01:00
12e5d2f6f3 add scaffolding for pocsag decoding 2020-01-06 22:08:17 +01:00
4859cb5db8 update to latest 2020-01-06 21:02:04 +01:00
83ad9d616f remove sdr.js 2020-01-06 19:52:31 +01:00
2a0ee83c12 implement lowpass 2020-01-06 19:48:54 +01:00
5379d8cc3d step one: implement upsampling 2020-01-06 16:29:23 +01:00
9187bb4371 use local codec for fft, too 2020-01-05 23:33:07 +01:00
c8c5ce8105 use local implementation of ima adpcm instead of sdr.js 2020-01-05 23:26:27 +01:00
15d351258f implement fallback for older setuptools 2020-01-05 21:08:17 +01:00
5fdc5489a1 losen dependency to python 3.5 2020-01-05 20:49:29 +01:00
a30841cdf6 add some debugging here 2020-01-05 18:41:46 +01:00
aad904f1a1 add owrs.source to the list of includes 2020-01-05 00:19:20 +01:00
8eb067b810 update csdr 2020-01-04 21:12:51 +01:00
108402a281 let's try this trick 2020-01-04 01:57:14 +01:00
de958ca091 seems like this fixes the starvation of workers 2020-01-02 19:35:58 +01:00
42828dbf65 add always-on feature 2019-12-31 19:14:05 +01:00
036442aa69 allow services to be disabled on individual sdrs 2019-12-31 18:44:47 +01:00
e60c332c24 arm 2019-12-31 16:24:45 +01:00
406d06fef2 add rockprog interface 2019-12-31 16:20:36 +01:00
9aa6f72152 fix the resampler 2019-12-31 15:27:33 +01:00
70347d1ef9 use automatic ports unless explicitly configured 2019-12-31 15:24:11 +01:00
42789ed561 clean up obsolete files 2019-12-31 09:43:04 +01:00
092a2e5ca0 handle soapy not being installed at all, references #42 2019-12-30 16:38:16 +01:00
9c82a80273 update csdr links 2019-12-30 16:23:22 +01:00
57dab75832 re-enable build cache 2019-12-30 00:12:03 +01:00
6297b8f277 use explicit revisions so i can use the docker build cache 2019-12-30 00:11:27 +01:00
6bcdd4007a fix dh_python3, hopefully 2019-12-29 21:46:26 +01:00
d0d0ba6ba7 initialize dict in code to avoid wrong references 2019-12-29 17:34:58 +01:00
550637ddef update raspi url 2019-12-29 10:06:10 +01:00
2bb2f65776 fix ppm parameter 2019-12-28 23:05:59 +01:00
420e21b078 add a pull to be up to date locally 2019-12-28 17:26:54 +01:00
71b8d72da3 push first, ask questions later 2019-12-28 17:17:10 +01:00
86ceb7a274 use lists for all command stuff 2019-12-28 16:44:45 +01:00
489d2390c8 fix name 2019-12-28 15:56:36 +01:00
1a3a5b43a0 reformat with black 2019-12-28 01:24:07 +01:00
e5724620a8 pass the tag the right way 2019-12-28 01:14:27 +01:00
2c4c88e30d move this over so a normal soapy sdr source 2019-12-28 00:38:36 +01:00
f92c49cee6 fix overlooked bias tee in airspy 2019-12-28 00:33:27 +01:00
8371d3b67a refactor sources to be more flexible 2019-12-28 00:26:45 +01:00
ca4d9771cc soapy driver detection; clean up docs 2019-12-27 11:37:12 +01:00
15a2e63866 combine arch and latest 2019-12-27 11:36:45 +01:00
eec35f07c3 add error message to log panel, too 2019-12-23 21:21:45 +01:00
11cfca5211 send a log message to the client when a device fails 2019-12-23 21:18:40 +01:00
46b5e9034f attempt to select new sdr on failure 2019-12-23 21:18:40 +01:00
7793609fa4 alpine is available for all archs now, but 3.11 produces segfaults :( 2019-12-23 19:11:47 +00:00
6f9ba6c290 improve sdr failure message display, closes #19 2019-12-21 23:46:05 +01:00
4d0d316fdd improve sdr failure detection 2019-12-21 23:29:56 +01:00
b5c5bcb9f1 fix readline problem 2019-12-21 21:17:19 +01:00
8fe9bf6292 attempt better wsjt decoder handling 2019-12-21 21:08:44 +01:00
9923f5b18e checkout the right branch 2019-12-21 21:00:43 +01:00
292fe80acf break apart the ever-growing owrx/source.py 2019-12-21 20:58:28 +01:00
5b08dae28d rx_sdr is not needed any more 2019-12-21 19:43:21 +01:00
33dd6937b4 change default config 2019-12-21 19:31:54 +01:00
a34cb3db8a reflect changes in the config, too 2019-12-21 19:30:46 +01:00
10de50d251 remove old sources, make the connector-based ones default 2019-12-21 19:24:14 +01:00
3bbcaa1329 use shallow cloning everywhere to speed up the build 2019-12-19 22:14:32 +01:00
e1d2ed8867 add fifisdr support (no frequency tuning) 2019-12-19 21:37:19 +01:00
8ee0d7c0e8 add sdrplay patch 2019-12-15 17:31:23 +00:00
721ac5e2a3 additional files for docker 2019-12-15 18:28:35 +01:00
88a410a9c0 the cache is evil, it has betrayed us 2019-12-15 18:28:10 +01:00
0e8116b743 handle errors in json files 2019-12-15 17:44:31 +01:00
ef1435cef7 rtltcp_compat is now a flag; expose through config 2019-12-15 16:33:07 +01:00
f7ff798238 add aarch64 build 2019-12-15 02:18:30 +00:00
f012c1180c update wsjt-x to 2.1.2 2019-12-14 21:04:23 +01:00
5a2e8d8f80 move config to /etc/openwebrx 2019-12-14 19:05:22 +01:00
364d3473a2 add airspyhf sample config 2019-12-10 23:02:22 +01:00
1a092a1e24 remove debug message 2019-12-08 22:13:57 +01:00
8248c60aa0 add direwolf and wsjtx packages 2019-12-08 21:56:50 +01:00
f4106ee427 strip path from glob 2019-12-08 21:46:08 +01:00
4e99a3ad07 explicitly glob over the htdocs 2019-12-08 21:37:14 +01:00
57a61f0c40 close connection when queue overflows 2019-12-08 21:11:36 +01:00
61988e3297 add sox dependency 2019-12-08 21:06:16 +01:00
5c8da76d9a move bands and bookmarks to the config, too 2019-12-08 21:00:01 +01:00
3b32dc37c8 git pull everytime 2019-12-08 20:45:30 +01:00
7a6d021e18 switch file loading to pkg_resources 2019-12-08 20:27:58 +01:00
21cb0e8feb docker-based debian package build 2019-12-08 19:00:34 +01:00
527eccd3c6 add systemd; add dependencies 2019-12-08 17:35:37 +01:00
57ec4e09ad move to package location 2019-12-08 17:16:28 +01:00
9164a3ed3a restructure project for packaging 2019-12-08 17:15:48 +01:00
37086bc6c7 debian build (first take) 2019-12-08 14:02:09 +01:00
1d1851dc76 add airspyhf support 2019-12-06 11:39:23 +01:00
ac841221b6 always pull before building 2019-12-06 11:38:15 +01:00
c8ddb121d0 simplify command execution 2019-12-05 21:07:56 +01:00
ba5613cf62 fix quoting 2019-12-05 20:57:03 +01:00
af4acd5623 parse device queries manually, since they are not x-www-urlencoded 2019-12-05 20:53:27 +01:00
19eb5c73e7 pre-filter soapy devices by driver 2019-12-05 19:51:55 +01:00
94ff6cc800 switch to my csdr master branch 2019-12-05 18:30:40 +01:00
adf4f5a738 explicit favicon link 2019-12-04 00:47:50 +01:00
1e6088ca1d relative map urls 2019-12-03 19:06:00 +01:00
9d01b2306c improve https detection 2019-12-03 18:57:32 +01:00
fc8d3d8f11 improve websocket url determination 2019-12-03 18:53:57 +01:00
15b860af36 add soapy connectivity for airspy 2019-12-03 14:32:10 +01:00
90d990bdfb add depencency for sox 2019-12-01 15:42:50 +01:00
2cfeb6b6d6 more safari fixes 2019-11-26 22:06:13 +01:00
42f9fb52ed safari compatibility 2019-11-26 21:35:22 +01:00
11c2c8afe3 limit multiprocessing queue to avoid memory leak on failing connections 2019-11-26 20:13:04 +01:00
fe39c2712d keep the output_rate on sdr change 2019-11-26 20:13:04 +01:00
b774e75f2c fix urls for when we aren't running on the root 2019-11-25 20:17:11 +01:00
147c108570 update with latest image link 2019-11-24 21:47:16 +01:00
53de54120e only specify device strings when configured 2019-11-24 20:34:51 +01:00
fa097bf57e update readme 2019-11-24 19:36:07 +01:00
917eb4fdf1 update readme 2019-11-24 18:23:45 +01:00
a8df774e50 dual authors 2019-11-24 18:08:54 +01:00
0b98ce1ef2 restructure docker image; add separate temp dir that can be placed in a
tmpfs
2019-11-24 15:30:53 +01:00
c6bbdffea0 update ignore files 2019-11-23 18:21:55 +01:00
481918ab5b better profile switching for the gui 2019-11-23 17:22:20 +01:00
b27caf2405 allow initial_squelch_level to be set per profile 2019-11-23 16:56:29 +01:00
d5b7338531 run black 2019-11-23 01:13:16 +01:00
9246500c95 run black 2019-11-23 01:12:21 +01:00
91669a7fda no agc necessary for wsjt-x decoding 2019-11-23 00:35:33 +01:00
c7eb67129a add information about connectors 2019-11-22 23:34:27 +01:00
98901ac668 add pskreporter dupe check and stats 2019-11-22 17:16:40 +01:00
7dde793f9e let's switch to the connectors per default for now 2019-11-22 15:18:29 +01:00
07de82ae82 secondary chain as array, too 2019-11-22 15:00:36 +01:00
9f710cb70e fix for lfo_offset = None 2019-11-21 17:19:51 +01:00
dab62a04df fix offset switching 2019-11-21 16:07:20 +01:00
de51e266f6 add airspy source; fix offset tuning 2019-11-21 15:31:37 +01:00
5375580104 add device handling for rtl 2019-11-20 11:37:06 +01:00
964d9e873d add iq swapping capability 2019-11-19 14:03:32 +01:00
7e8e644e6c purge manifests after use (won't work as expected otherwise) 2019-11-18 21:26:11 +00:00
6bde623698 add manifest stuff 2019-11-18 14:42:05 +01:00
5ba89035b4 add connectors to docker 2019-11-18 14:15:59 +01:00
a9b99fa0ff introduce connector source for sdrplay 2019-11-17 20:52:16 +01:00
6619a1b4a6 the ServiceHandler is fully passive 2019-11-16 15:40:12 +01:00
a36f106c72 add source "busy state" to improve background scheduling 2019-11-15 23:05:52 +01:00
097f8a2b82 refactor event system 2019-11-15 22:13:00 +01:00
bcbb911b24 restore airspy feature test 2019-11-15 19:36:07 +01:00
f18efb2344 use Popen for feature detection to be able to take control of the
working directory
2019-11-14 22:13:02 +01:00
497d98363f fix bookmark edit / delete flyout 2019-11-14 15:31:44 +01:00
367bf666fc listen for frequency changes in the scheduler, too 2019-11-13 19:50:00 +01:00
7489a3bb9d try to improve memory footprint by rebuilding map dictionary in
intervals
2019-11-13 18:01:01 +01:00
2a6c7863b1 improve control socket handling 2019-11-12 15:57:10 +01:00
bf27f51049 let's leave some footsteps 2019-11-12 13:43:39 +01:00
6ba74a0c30 add ppm 2019-11-11 20:35:50 +01:00
ada94f69c3 new modificitions for owrx_connector support 2019-11-11 18:07:14 +01:00
dc5ac081ce fix some javascript code style issues 2019-11-07 10:56:39 +01:00
8a46922e77 panels disappear behind the header 2019-11-01 22:22:46 +01:00
5fdffb5e0c fix scrolling for canvas background and bookmarks. i hope that's all
now.
2019-11-01 19:48:08 +01:00
9f6a4891ed fix styles (broken by debugging) 2019-11-01 18:53:16 +01:00
41d23c66a4 prevent events from being blocked by the panels 2019-11-01 18:47:33 +01:00
9163f3d30e improve autoplay interface 2019-11-01 16:58:36 +01:00
d49fff65e4 switch to different csdr branch 2019-11-01 15:18:39 +01:00
95253e40bd organize timers and threads to get proper shutdown 2019-10-31 22:24:31 +01:00
af1a99c130 prevent deadlocks by shutting down services in correct order 2019-10-31 19:13:33 +01:00
1638fde181 fix gradient (without gradient) 2019-10-28 20:54:31 +01:00
52ea2e88e9 update readme 2019-10-27 17:45:17 +01:00
204 changed files with 10768 additions and 16717 deletions

7
.dockerignore Normal file
View File

@ -0,0 +1,7 @@
.git
.gitignore
.idea
**/*.pyc
**/*.swp
black-env
debian

29
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,29 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Installation method**
How did you install OpenWebRX? (Raspberry Pi SD card image, Debian / Ubuntu packages, Docker image, manually?)
**Versions**
What version of OpenWebRX are you running? (Check on startup, or see `owrx/version.py`. If a `-dev` version is used, ideally state the commit the issue is appearing on)
**Log messages**
Are there any relevant messages relating to the bug in the output / log of OpenWebRX? (On most installations, the log should be available using the command `sudo journalctl -u openwebrx`)
**Additional context**
Add any other context about the problem here.

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: General support request or other project-relasted question
url: https://groups.io/g/openwebrx
about: Request help on the community mailing list

View File

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: feature
assignees: ''
---
Before posting a new feature request, please check if a similar idea has already been listed
* on the issue tracker
* on the [OpenWebRX github project](https://github.com/users/jketterl/projects/1).
In the latter case, please only proceed if you have additional information about the feature, and please let us know that there's already a card there.
**Feature description**
Please describe in plain words what functionality you'd like to see in OpenWebRX, and why you think it's useful.
**Target audience**
Please let us know if you think that this feature is of particular interest for a particular group of users (e.g. hams, SWLs, DXers, ...)

5
.gitignore vendored
View File

@ -1,4 +1,5 @@
*.pyc **/*.pyc
*.swp **/*.swp
tags tags
.idea .idea
packages

164
CHANGELOG.md Normal file
View File

@ -0,0 +1,164 @@
**unreleased**
- Added the ability to sign multiple keys in a single request, thus enabling multiple users to claim a single receiver
on receiverbook.de
- Fixed file descriptor leaks to prevent "too many open files" errors
- Add new demodulator chain for FreeDV
- Added new HD audio streaming mode along with a new WFM demodulator
- Reworked AGC code for better results in AM, SSB and digital modes
- Added support for demodulation of "Digital Radio Mondiale" (DRM) broadcast using the "dream" decoder.
- New default waterfall color scheme
- Prototype of a continuous automatic waterfall calibration mode
- New devices supported:
- FunCube Dongle Pro+ (`"type": "fcdpp"`)
- Support for connections to rtl_tcp (`"type": "rtl_tcp"`)
**0.19.1**
- Added ability to authenticate receivers with listing sites using "receiver id" tokens
**0.19.0**
- Fix direwolf connection setup by implementing a retry loop
- Pass direct sampling mode changes for rtl_sdr_soapy to owrx_connector
- OSM maps instead of Google when google_maps_api_key is not set (thanks @jquagga)
- Improved logic to pass parameters to soapy devices.
- `rtl_sdr_soapy`: added support for `bias_tee`
- `sdrplay`: added support for `bias_tee`, `rf_notch` and `dab_notch`
- `airspy`: added support for `bitpack`
- Added support for Perseus-SDR devices, (thanks @amontefusco)
- Property System has been rewritten so that defaults on sdr behave as expected
- Waterfall range auto-adjustment now only takes the center 80% of the spectrum into account, which should work better
with SDRs that oversample or have rather flat filter curves towards the spectrum edges
- Bugfix for negative network usage
- FiFi SDR: prevent arecord from shutting down after 2GB of data has been sent
- Added support for bias tee control on rtl_sdr devices
- All connector driven SDRs now support `"rf_gain": "auto"` to enable AGC
- `rtl_sdr` type now also supports the `direct_sampling` option
- Added decoding implementation for for digimode "JS8Call"
(requires an installation of [js8call](http://js8call.com/) and
[the js8py library](https://github.com/jketterl/js8py))
- Reorganization of the frontend demodulator code
- Improve receiver load time by concatenating javascript assets
- Docker images migrated to Debian slim images; This was necessary to allow the use of function multiversioning in
csdr and owrx_connector to allow the images to run on a wider range of CPUs
- Docker containers have been updated to include the SDRplay driver version 3
- HackRF support is now based on SoapyHackRF
- Removed sdr.hu server listing support since the site has been shut down
- Added support for Radioberry 2 Rasbperry Pi SDR Cape
**0.18.0**
- Support for SoapyRemote
**2020-02-08**
- Compression, resampling and filtering in the frontend have been rewritten in javascript, sdr.js has been removed
- Decoding of Pocsag modulation is now possible
- Removed the 3D waterfall since it had no real application and required ~1MB of javascript code to be downloaded
- Improved the frontend handling of the "too many users" scenario
- PSK63 digimode is now available (same decoding pipeline as PSK31, but with adopted parameters)
- The frequency can now be manipulated with the mousewheel, which should allow the user to tune more precise. The tuning
step size is determined by the digit the mouse cursor is hovering over.
- Clicking on the frequency now opens an input for direct frequency selection
- URL hashes have been fixed and improved: They are now updated automatically, so a shared URL will include frequency
and demodulator, which allows for improved sharing and linking.
- New daylight scheduler for background decoding, allows profiles to be selected by local sunrise / sunset times
- New devices supported:
- LimeSDR (`"type": "lime_sdr"`)
- PlutoSDR (`"type": "pluto_sdr"`)
- RTL_SDR via Soapy (`"type": "rtl_sdr_soapy"`) on special request to allow use of the direct sampling mode
**2020-01-04**
- The [owrx_connector](https://github.com/jketterl/owrx_connector) is now the default way of communicating with sdr
devices. The old sdr types have been replaced, all `_connector` suffixes on the type must be removed!
- The sources have been refactored, making it a lot easier to add support for other devices
- SDR device failure handling has been improved, including user feedback
- New devices supported:
- FiFiSDR (`"type": "fifi_sdr"`)
**2019-12-15**
- wsjt-x updated to 2.1.2
- The rtl_tcp compatibility mode of the owrx_connector is now configurable using the `rtltcp_compat` flag
**2019-12-10**
- added support for airspyhf devices (Airspy HF+ / Discovery)
**2019-12-05**
- explicit device filter for soapy devices for multi-device setups
**2019-12-03**
- compatibility fixes for safari browsers (ios and mac)
**2019-11-24**
- There is now a new way to interface with SDR hardware, .
They talk directly to the hardware (no rtl_sdr / rx_sdr necessary) and offer I/Q data on a socket, just like nmux
did before. They additionally offer a control socket that allows openwebrx to control the SDR parameters directly,
without the need for repeated restarts. This allows for quicker profile changes, and also reduces the risk of your
SDR hardware from failing during the switchover. See `config_webrx.py` for further information and instructions.
- Offset tuning using the `lfo_offset` has been reworked in a way that `center_freq` has to be set to the frequency you
actually want to listen to. If you're using an `lfo_offset` already, you will probably need to change its sign.
- `initial_squelch_level` can now be set on each profile.
- As usual, plenty of fixes and improvements.
**2019-10-27**
- Part of the frontend code has been reworked
- Audio buffer minimums have been completely stripped. As a result, you should get better latency. Unfortunately,
this also means there will be some skipping when audio starts.
- Now also supports AudioWorklets (for those browser that have it). The Raspberry Pi image has been updated to include
https due to the SecureContext requirement.
- Mousewheel controls for the receiver sliders
- Error handling for failed SDR devices
**2019-09-29**
- One of the most-requested features is finally coming to OpenWebRX: Bookmarks (sometimes also referred to as labels).
There's two kinds of bookmarks available:
- Serverside bookmarks that are set up by the receiver administrator. Check the file `bookmarks.json` for examples!
- Clientside bookmarks which every user can store for themselves. They are stored in the browser's localStorage.
- Some more bugs in the websocket handling have been fixed.
**2019-09-25**
- Automatic reporting of spots to [pskreporter](https://pskreporter.info/) is now possible. Please have a look at the
configuration on how to set it up.
- Websocket communication has been overhauled in large parts. It should now be more reliable, and failing connections
should now have no impact on other users.
- Profile scheduling allows to set up band-hopping if you are running background services.
- APRS now has the ability to show symbols on the map, if a corresponding symbol set has been installed. Check the
config!
- Debug logging has been disabled in a handful of modules, expect vastly reduced output on the shell.
**2019-09-13**
- New set of APRS-related features
- Decode Packet transmissions using [direwolf](https://github.com/wb2osz/direwolf) (1k2 only for now)
- APRS packets are mostly decoded and shown both in a new panel and on the map
- APRS is also available as a background service
- direwolfs I-gate functionality can be enabled, which allows your receiver to work as a receive-only I-gate for the
APRS network in the background
- Demodulation for background services has been optimized to use less total bandwidth, saving CPU
- More metrics have been added; they can be used together with collectd and its curl_json plugin for now, with some
limitations.
**2019-07-21**
- Latest Features:
- More WSJT-X modes have been added, including the new FT4 mode
- I started adding a bandplan feature, the first thing visible is the "dial" indicator that brings you right to the
dial frequency for digital modes
- fixed some bugs in the websocket communication which broke the map
**2019-07-13**
- Latest Features:
- FT8 Integration (using wsjt-x demodulators)
- New Map Feature that shows both decoded grid squares from FT8 and Locations decoded from YSF digital voice
- New Feature report that will show what functionality is available
- There's a new Raspbian SD Card image available (see below)
**2019-06-30**
- I have done some major rework on the openwebrx core, and I am planning to continue adding more features in the near
future. Please check this place for updates.
- My work has not been accepted into the upstream repository, so you will need to chose between my fork and the official
version.
- I have enabled the issue tracker on this project, so feel free to file bugs or suggest enhancements there!
- This version sports the following new and amazing features:
- Support of multiple SDR devices simultaneously
- Support for multiple profiles per SDR that allow the user to listen to different frequencies
- Support for digital voice decoding
- Feature detection that will disable functionality when dependencies are not available (if you're missing the digital
buttons, this is probably why)
- Raspbian SD Card Images and Docker builds available (see below)
- I am currently working on the feature set for a stable release, but you are more than welcome to test development
versions!

View File

@ -1,15 +0,0 @@
First of all, thank you for taking the time to contribute to this project!
Before I can accept your contributions, I need a signed copy of the Individual Contributor License Agreement (ICLA) from you, which is available <a href="ICLA.txt">here</a>.
The ICLA is needed because it will allow me to dual license the OpenWebRX project under AGPL and a commercial license.
I will also apply dual licensing to csdr, but only those parts that are original work (e.g. without the parts enabled by `-DUSE_IMA_ADPCM`; code taken from other projects is clearly separable).
However, even if there is commercial interest in the projects, I promise to keep them as open as possible, keeping my original intention to provide an open-source web-based SDR receiver software to the amateur radio operators and SDR enthusiasts.
This contributor agreement is based on the one of Apache Software Foundation, with some modifications. (You can review differences <a href="https://gist.github.com/ha7ilm/9e981006d24659e336c7/revisions">here</a>).
When you contribute for the first time, I will send you the ICLA. Replying with only the information requested and the text "I Agree" is sufficient.
Thanks,
Andras, HA7ILM

View File

@ -1,5 +0,0 @@
This is a list of the great people who contributed code to the OpenWebRX repository. (Names are sorted alphabetically.)
Gnoxter <gnoxter@linuxlounge.net>
John Seamons, ZL/KF6VO <jks@jks.com>

128
ICLA.txt
View File

@ -1,128 +0,0 @@
Individual Contributor License Agreement ("Agreement")
In order to clarify the intellectual property license granted
with Contributions from any person or entity, Retzler András
(hereinafter referred to as "Project Owner") must have a
Contributor License Agreement ("CLA") on file that has
been signed by each Contributor, indicating agreement to the license
terms below. This license is for your protection as a Contributor as
well as the protection of the Project Owner; it does not change your
rights to use your own Contributions for any other purpose.
Please read this document carefully before signing and keep a copy
for your records.
Full name: ______________________________________________________
(optional) Public name: _________________________________________
Mailing Address: ________________________________________________
________________________________________________
Country: ______________________________________________________
(optional) Telephone: ___________________________________________
E-Mail: ______________________________________________________
You accept and agree to the following terms and conditions for Your
present and future Contributions submitted to the Project Owner.
Except for the license granted herein to the Project Owner and recipients
of software distributed by the Project Owner, You reserve all right, title,
and interest in and to Your Contributions.
1. Definitions.
"You" (or "Your") shall mean the copyright owner or legal entity
authorized by the copyright owner that is making this Agreement
with the Project Owner. For legal entities, the entity making a
Contribution and all other entities that control, are controlled
by, or are under common control with that entity are considered to
be a single Contributor. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"Contribution" shall mean any original work of authorship,
including any modifications or additions to an existing work, that
is intentionally submitted by You to the Project Owner for inclusion
in, or documentation of, any of the products owned or managed by
the Project Owner (the "Work"). For the purposes of this definition,
"submitted" means any form of electronic, verbal, or written
communication sent to the Project Owner or its representatives,
including but not limited to communication on electronic mailing
lists, source code control systems, and issue tracking systems that
are managed by, or on behalf of, the Project Owner for the purpose of
discussing and improving the Work, but excluding communication that
is conspicuously marked or otherwise designated in writing by You
as "Not a Contribution."
2. Grant of Copyright License. Subject to the terms and conditions of
this Agreement, You hereby grant to the Project Owner and to
recipients of software distributed by the Project Owner a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare derivative works of,
publicly display, publicly perform, sublicense, and distribute Your
Contributions and such derivative works.
3. Grant of Patent License. Subject to the terms and conditions of
this Agreement, You hereby grant to the Project Owner and to
recipients of software distributed by the Project Owner a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the
Work, where such license applies only to those patent claims
licensable by You that are necessarily infringed by Your
Contribution(s) alone or by combination of Your Contribution(s)
with the Work to which such Contribution(s) was submitted. If any
entity institutes patent litigation against You or any other entity
(including a cross-claim or counterclaim in a lawsuit) alleging
that your Contribution, or the Work to which you have contributed,
constitutes direct or contributory patent infringement, then any
patent licenses granted to that entity under this Agreement for
that Contribution or Work shall terminate as of the date such
litigation is filed.
4. You represent that you are legally entitled to grant the above
license. If your employer(s) has rights to intellectual property
that you create that includes your Contributions, you represent
that you have received permission to make Contributions on behalf
of that employer, that your employer has waived such rights for
your Contributions to the Project Owner, or that your employer has
executed a separate Corporate CLA with the Project Owner.
5. You represent that each of Your Contributions is Your original
creation (see section 7 for submissions on behalf of others). You
represent that Your Contribution submissions include complete
details of any third-party license or other restriction (including,
but not limited to, related patents and trademarks) of which you
are personally aware and which are associated with any part of Your
Contributions.
6. You are not expected to provide support for Your Contributions,
except to the extent You desire to provide support. You may provide
support for free, for a fee, or not at all. Unless required by
applicable law or agreed to in writing, You provide Your
Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
OF ANY KIND, either express or implied, including, without
limitation, any warranties or conditions of TITLE, NON-
INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
7. Should You wish to submit work that is not Your original creation,
You may submit it to the Project Owner separately from any
Contribution, identifying the complete details of its source and of
any license or other restriction (including, but not limited to,
related patents, trademarks, and license agreements) of which you
are personally aware, and conspicuously marking the work as
"Submitted on behalf of a third-party: [named here]".
8. You agree to notify the Project Owner of any facts or circumstances of
which you become aware that would make these representations
inaccurate in any respect.
Please sign: __________________________________ Date: ________________
Text derived from the Apache Individual Contributor License Agreement
("Agreement") V2.0, available at http://apache.org/licenses/icla.txt

134
README.md
View File

@ -1,129 +1,39 @@
OpenWebRX OpenWebRX
========= =========
[:floppy_disk: Setup guide for Ubuntu](http://blog.sdr.hu/2015/06/30/quick-setup-openwebrx.html) | [:blue_book: Knowledge base on the Wiki](https://github.com/simonyiszk/openwebrx/wiki/) | [:earth_americas: Receivers on SDR.hu](http://sdr.hu/)
OpenWebRX is a multi-user SDR receiver software with a web interface. OpenWebRX is a multi-user SDR receiver software with a web interface.
![OpenWebRX](http://blog.sdr.hu/images/openwebrx/screenshot.png) ![OpenWebRX](https://www.openwebrx.de/gfx/openwebrx-screenshot.png)
It has the following features: It has the following features:
- [csdr](https://github.com/simonyiszk/csdr) based demodulators (AM/FM/SSB/CW/BPSK31), - [csdr](https://github.com/jketterl/csdr) based demodulators (AM/FM/SSB/CW/BPSK31/BPSK63)
- filter passband can be set from GUI, - filter passband can be set from GUI
- it extensively uses HTML5 features like WebSocket, Web Audio API, and Canvas - it extensively uses HTML5 features like WebSocket, Web Audio API, and Canvas
- it works in Google Chrome, Chromium and Mozilla Firefox - it works in Google Chrome, Chromium and Mozilla Firefox
- currently supports RTL-SDR, HackRF, SDRplay, AirSpy - currently supports RTL-SDR, HackRF, SDRplay, AirSpy, LimeSDR, PlutoSDR
- Multiple SDR devices can be used simultaneously - Multiple SDR devices can be used simultaneously
- [digiham](https://github.com/jketterl/digiham) based demodularors (DMR, YSF) - [digiham](https://github.com/jketterl/digiham) based demodularors (DMR, YSF, Pocsag)
- [dsd](https://github.com/f4exb/dsdcc) based demodulators (D-Star, NXDN) - [dsd](https://github.com/f4exb/dsdcc) based demodulators (D-Star, NXDN)
- [wsjt-x](https://physics.princeton.edu/pulsar/k1jt/wsjtx.html) based demodulators (FT8, FT4, WSPR, JT65, JT9) - [wsjt-x](https://physics.princeton.edu/pulsar/k1jt/wsjtx.html) based demodulators (FT8, FT4, WSPR, JT65, JT9)
**News (2019-09-29 by DD5FJK)**
- One of the most-requested features is finally coming to OpenWebRX: Bookmarks (sometimes also referred to as labels). There's two kinds of bookmarks available:
- Serverside bookmarks that are set up by the receiver administrator. Check the file `bookmarks.json` for examples!
- Clientside bookmarks which every user can store for themselves. They are stored in the browser's localStorage.
- Some more bugs in the websocket handling have been fixed.
**News (2019-09-25 by DD5JFK)**
- Automatic reporting of spots to [pskreporter](https://pskreporter.info/) is now possible. Please have a look at the configuration on how to set it up.
- Websocket communication has been overhauled in large parts. It should now be more reliable, and failing connections should now have no impact on other users.
- Profile scheduling allows to set up band-hopping if you are running background services.
- APRS now has the ability to show symbols on the map, if a corresponding symbol set has been installed. Check the config!
- Debug logging has been disabled in a handful of modules, expect vastly reduced output on the shell.
**News (2019-09-13 by DD5JFK)**
- New set of APRS-related features
- Decode Packet transmissions using [direwolf](https://github.com/wb2osz/direwolf) (1k2 only for now)
- APRS packets are mostly decoded and shown both in a new panel and on the map
- APRS is also available as a background service
- direwolfs I-gate functionality can be enabled, which allows your receiver to work as a receive-only I-gate for the APRS network in the background
- Demodulation for background services has been optimized to use less total bandwidth, saving CPU
- More metrics have been added; they can be used together with collectd and its curl_json plugin for now, with some limitations.
**News (2019-07-21 by DD5JFK)**
- Latest Features:
- More WSJT-X modes have been added, including the new FT4 mode
- I started adding a bandplan feature, the first thing visible is the "dial" indicator that brings you right to the dial frequency for digital modes
- fixed some bugs in the websocket communication which broke the map
**News (2019-07-13 by DD5JFK)**
- Latest Features:
- FT8 Integration (using wsjt-x demodulators)
- New Map Feature that shows both decoded grid squares from FT8 and Locations decoded from YSF digital voice
- New Feature report that will show what functionality is available
- There's a new Raspbian SD Card image available (see below)
**News (2019-06-30 by DD5JFK)**
- I have done some major rework on the openwebrx core, and I am planning to continue adding more features in the near future. Please check this place for updates.
- My work has not been accepted into the upstream repository, so you will need to chose between my fork and the official version.
- I have enabled the issue tracker on this project, so feel free to file bugs or suggest enhancements there!
- This version sports the following new and amazing features:
- Support of multiple SDR devices simultaneously
- Support for multiple profiles per SDR that allow the user to listen to different frequencies
- Support for digital voice decoding
- Feature detection that will disable functionality when dependencies are not available (if you're missing the digital buttons, this is probably why)
- Raspbian SD Card Images and Docker builds available (see below)
- I am currently working on the feature set for a stable release, but you are more than welcome to test development versions!
> When upgrading OpenWebRX, please make sure that you also upgrade *csdr* and *digiham*!
## OpenWebRX servers on SDR.hu
[SDR.hu](http://sdr.hu) is a site which lists the active, public OpenWebRX servers. Your receiver [can also be part of it](http://sdr.hu/openwebrx), if you want.
![sdr.hu](http://blog.sdr.hu/images/openwebrx/screenshot-sdrhu.png)
## Setup ## Setup
### Raspberry Pi SD Card Images The following methods of setting up a receiver are currently available:
Probably the quickest way to get started is to download the [latest Raspberry Pi SD Card Image](https://s3.eu-central-1.amazonaws.com/de.dd5jfk.openwebrx/2019-09-29-OpenWebRX-full.zip). It contains all the depencencies out of the box, and should work on all Raspberries up to the 3B+. - Raspberry Pi SD card images
- Debian repository
- Docker images
- Manual installation
This is based off the Raspbian Lite distribution, so [their installation instructions](https://www.raspberrypi.org/documentation/installation/installing-images/) apply. Please checkout the [setup guide on the wiki](https://github.com/jketterl/openwebrx/wiki/Setup-Guide) for more details
on the respective methods.
Please note: I have not updated this to include the Raspberry Pi 4 yet. (It seems to be impossible to build Rasbpian Buster images on x86 hardware right now. Stay tuned!) ## Community
Once you have booted a Raspberry with the SD Card, it will appear in your network with the hostname "openwebrx", which should make it available as http://openwebrx:8073/ on most networks. This may vary depending on your specific setup. If you have trouble setting up or configuring your receiver, you have some great idea you want to see implemented, or
you just generally want to have some OpenWebRX-related chat, come visit us over on
For Digital voice, the minimum requirement right now seems to be a Rasbperry Pi 3B+. I would like to work on optimizing this for lower specs, but at this point I am not sure how much can be done. [our groups.io group](https://groups.io/g/openwebrx).
### Docker Images
For those familiar with docker, I am providing [recent builds and Releases for both x86 and arm processors on the Docker hub](https://hub.docker.com/r/jketterl/openwebrx). You can find a short introduction there.
### Manual Installation
OpenWebRX currently requires Linux and python 3 to run.
First you will need to install the dependencies:
- [csdr](https://github.com/simonyiszk/csdr)
- [rtl-sdr](http://sdr.osmocom.org/trac/wiki/rtl-sdr)
Optional Dependencies if you want to be able to listen do digital voice:
- [digiham](https://github.com/jketterl/digiham)
- [dsd](https://github.com/f4exb/dsdcc)
Optional Dependency if you want to decode WSJT-X modes:
- [wsjt-x](https://physics.princeton.edu/pulsar/k1jt/wsjtx.html)
After cloning this repository and connecting an RTL-SDR dongle to your computer, you can run the server:
./openwebrx.py
You can now open the GUI at <a href="http://localhost:8073">http://localhost:8073</a>.
Please note that the server is also listening on the following ports (on localhost only):
- ports 4950 to 4960 for the multi-user I/Q servers.
Now the next step is to customize the parameters of your server in `config_webrx.py`.
Actually, if you do something cool with OpenWebRX, please drop me a mail:
*Andras Retzler, HA7ILM &lt;randras@sdr.hu&gt;*
## Usage tips ## Usage tips
@ -133,14 +43,10 @@ The filter envelope can be dragged at its ends and moved around to set the passb
However, if you hold down the shift key, you can drag the center line (BFO) or the whole passband (PBS). However, if you hold down the shift key, you can drag the center line (BFO) or the whole passband (PBS).
## Setup tips
If you have any problems installing OpenWebRX, you should check out the <a href="https://github.com/simonyiszk/openwebrx/wiki">Wiki</a> about it, which has a page on the <a href="https://github.com/simonyiszk/openwebrx/wiki/Common-problems-and-their-solutions">common problems and their solutions</a>.
Sometimes the actual error message is not at the end of the terminal output, you may have to look at the whole output to find it.
## Licensing ## Licensing
OpenWebRX is available under Affero GPL v3 license (<a href="https://tldrlegal.com/license/gnu-affero-general-public-license-v3-(agpl-3.0)">summary</a>). OpenWebRX is available under Affero GPL v3 license
([summary](https://tldrlegal.com/license/gnu-affero-general-public-license-v3-(agpl-3.0))).
OpenWebRX is also available under a commercial license on request. Please contact me at the address *&lt;randras@sdr.hu&gt;* for licensing options. OpenWebRX is also available under a commercial license on request. Please contact me at the address
*&lt;randras@sdr.hu&gt;* for licensing options.

View File

@ -4,11 +4,12 @@
"lower_bound": 1810000, "lower_bound": 1810000,
"upper_bound": 2000000, "upper_bound": 2000000,
"frequencies": { "frequencies": {
"psk31": 1838000, "bpsk31": 1838000,
"ft8": 1840000, "ft8": 1840000,
"wspr": 1836600, "wspr": 1836600,
"jt65": 1838000, "jt65": 1838000,
"jt9": 1839000 "jt9": 1839000,
"js8": 1842000
} }
}, },
{ {
@ -16,12 +17,13 @@
"lower_bound": 3500000, "lower_bound": 3500000,
"upper_bound": 3800000, "upper_bound": 3800000,
"frequencies": { "frequencies": {
"psk31": 3580000, "bpsk31": 3580000,
"ft8": 3573000, "ft8": 3573000,
"wspr": 3592600, "wspr": 3592600,
"jt65": 3570000, "jt65": 3570000,
"jt9": 3572000, "jt9": 3572000,
"ft4": [3568000, 3575000] "ft4": [3568000, 3575000],
"js8": 3578000
} }
}, },
{ {
@ -38,12 +40,13 @@
"lower_bound": 7000000, "lower_bound": 7000000,
"upper_bound": 7200000, "upper_bound": 7200000,
"frequencies": { "frequencies": {
"psk31": 7040000, "bpsk31": 7040000,
"ft8": 7074000, "ft8": 7074000,
"wspr": 7038600, "wspr": 7038600,
"jt65": 7076000, "jt65": 7076000,
"jt9": 7078000, "jt9": 7078000,
"ft4": 7047500 "ft4": 7047500,
"js8": 7078000
} }
}, },
{ {
@ -51,12 +54,13 @@
"lower_bound": 10100000, "lower_bound": 10100000,
"upper_bound": 10150000, "upper_bound": 10150000,
"frequencies": { "frequencies": {
"psk31": 10141000, "bpsk31": 10141000,
"ft8": 10136000, "ft8": 10136000,
"wspr": 10138700, "wspr": 10138700,
"jt65": 10138000, "jt65": 10138000,
"jt9": 10140000, "jt9": 10140000,
"ft4": 10140000 "ft4": 10140000,
"js8": 10130000
} }
}, },
{ {
@ -64,12 +68,13 @@
"lower_bound": 14000000, "lower_bound": 14000000,
"upper_bound": 14350000, "upper_bound": 14350000,
"frequencies": { "frequencies": {
"psk31": 14070000, "bpsk31": 14070000,
"ft8": 14074000, "ft8": 14074000,
"wspr": 14095600, "wspr": 14095600,
"jt65": 14076000, "jt65": 14076000,
"jt9": 14078000, "jt9": 14078000,
"ft4": 14080000 "ft4": 14080000,
"js8": 14078000
} }
}, },
{ {
@ -77,12 +82,13 @@
"lower_bound": 18068000, "lower_bound": 18068000,
"upper_bound": 18168000, "upper_bound": 18168000,
"frequencies": { "frequencies": {
"psk31": 18098000, "bpsk31": 18098000,
"ft8": 18100000, "ft8": 18100000,
"wspr": 18104600, "wspr": 18104600,
"jt65": 18102000, "jt65": 18102000,
"jt9": 18104000, "jt9": 18104000,
"ft4": 18104000 "ft4": 18104000,
"js8": 18104000
} }
}, },
{ {
@ -90,12 +96,13 @@
"lower_bound": 21000000, "lower_bound": 21000000,
"upper_bound": 21450000, "upper_bound": 21450000,
"frequencies": { "frequencies": {
"psk31": 21070000, "bpsk31": 21070000,
"ft8": 21074000, "ft8": 21074000,
"wspr": 21094600, "wspr": 21094600,
"jt65": 21076000, "jt65": 21076000,
"jt9": 21078000, "jt9": 21078000,
"ft4": 21140000 "ft4": 21140000,
"js8": 21078000
} }
}, },
{ {
@ -103,12 +110,13 @@
"lower_bound": 24890000, "lower_bound": 24890000,
"upper_bound": 24990000, "upper_bound": 24990000,
"frequencies": { "frequencies": {
"psk31": 24920000, "bpsk31": 24920000,
"ft8": 24915000, "ft8": 24915000,
"wspr": 24924600, "wspr": 24924600,
"jt65": 24917000, "jt65": 24917000,
"jt9": 24919000, "jt9": 24919000,
"ft4": 24919000 "ft4": 24919000,
"js8": 24922000
} }
}, },
{ {
@ -116,12 +124,13 @@
"lower_bound": 28000000, "lower_bound": 28000000,
"upper_bound": 29700000, "upper_bound": 29700000,
"frequencies": { "frequencies": {
"psk31": [28070000, 28120000], "bpsk31": [28070000, 28120000],
"ft8": 28074000, "ft8": 28074000,
"wspr": 28124600, "wspr": 28124600,
"jt65": 28076000, "jt65": 28076000,
"jt9": 28078000, "jt9": 28078000,
"ft4": 28180000 "ft4": 28180000,
"js8": 28078000
} }
}, },
{ {
@ -129,12 +138,13 @@
"lower_bound": 50030000, "lower_bound": 50030000,
"upper_bound": 51000000, "upper_bound": 51000000,
"frequencies": { "frequencies": {
"psk31": 50305000, "bpsk31": 50305000,
"ft8": 50313000, "ft8": 50313000,
"wspr": 50293000, "wspr": 50293000,
"jt65": 50310000, "jt65": 50310000,
"jt9": 50312000, "jt9": 50312000,
"ft4": 50318000 "ft4": 50318000,
"js8": 50318000
} }
}, },
{ {
@ -160,7 +170,10 @@
{ {
"name": "70cm", "name": "70cm",
"lower_bound": 430000000, "lower_bound": 430000000,
"upper_bound": 440000000 "upper_bound": 440000000,
"frequencies": {
"pocsag": 439987500
}
}, },
{ {
"name": "23cm", "name": "23cm",
@ -186,5 +199,75 @@
"name": "3cm", "name": "3cm",
"lower_bound": 10000000000, "lower_bound": 10000000000,
"upper_bound": 10500000000 "upper_bound": 10500000000
},
{
"name": "120m Broadcast",
"lower_bound": 2300000,
"upper_bound": 2495000
},
{
"name": "90m Broadcast",
"lower_bound": 3200000,
"upper_bound": 3400000
},
{
"name": "75m Broadcast",
"lower_bound": 3900000,
"upper_bound": 4000000
},
{
"name": "60m Broadcast",
"lower_bound": 4750000,
"upper_bound": 4995000
},
{
"name": "49m Broadcast",
"lower_bound": 5900000,
"upper_bound": 6200000
},
{
"name": "41m Broadcast",
"lower_bound": 7200000,
"upper_bound": 7450000
},
{
"name": "31m Broadcast",
"lower_bound": 9400000,
"upper_bound": 9900000
},
{
"name": "25m Broadcast",
"lower_bound": 11600000,
"upper_bound": 12100000
},
{
"name": "22m Broadcast",
"lower_bound": 13570000,
"upper_bound": 13870000
},
{
"name": "19m Broadcast",
"lower_bound": 15100000,
"upper_bound": 15830000
},
{
"name": "16m Broadcast",
"lower_bound": 17480000,
"upper_bound": 17900000
},
{
"name": "15m Broadcast",
"lower_bound": 18900000,
"upper_bound": 19020000
},
{
"name": "13m Broadcast",
"lower_bound": 21450000,
"upper_bound": 21850000
},
{
"name": "11m Broadcast",
"lower_bound": 25670000,
"upper_bound": 26100000
} }
] ]

View File

@ -129,11 +129,6 @@
"frequency": 439937500, "frequency": 439937500,
"modulation": "dmr" "modulation": "dmr"
}, },
{
"name": "Pocsag",
"frequency": 439987500,
"modulation": "nfm"
},
{ {
"name": "DB0ULR", "name": "DB0ULR",
"frequency": 145575000, "frequency": 145575000,

View File

@ -1,22 +0,0 @@
#!/bin/bash
set -euxo pipefail
ARCH=$(uname -m)
case $ARCH in
x86_64)
BASE_IMAGE=alpine
;;
armv*)
BASE_IMAGE=arm32v6/alpine
esac
TAGS=$ARCH
docker build --build-arg BASE_IMAGE=$BASE_IMAGE -t openwebrx-base:$ARCH -f docker/Dockerfiles/Dockerfile-base .
docker build --build-arg ARCH=$ARCH -t jketterl/openwebrx-rtlsdr:$ARCH -f docker/Dockerfiles/Dockerfile-rtlsdr .
docker build --build-arg ARCH=$ARCH -t openwebrx-soapysdr-base:$ARCH -f docker/Dockerfiles/Dockerfile-soapysdr .
docker build --build-arg ARCH=$ARCH -t jketterl/openwebrx-sdrplay:$ARCH -f docker/Dockerfiles/Dockerfile-sdrplay .
docker build --build-arg ARCH=$ARCH -t jketterl/openwebrx-hackrf:$ARCH -f docker/Dockerfiles/Dockerfile-hackrf .
docker build --build-arg ARCH=$ARCH -t jketterl/openwebrx-airspy:$ARCH -f docker/Dockerfiles/Dockerfile-airspy .
docker build --build-arg ARCH=$ARCH -t jketterl/openwebrx-full:$ARCH -t jketterl/openwebrx:$ARCH -f docker/Dockerfiles/Dockerfile-full .

View File

@ -6,6 +6,7 @@ config_webrx: configuration options for OpenWebRX
This file is part of OpenWebRX, This file is part of OpenWebRX,
an open-source SDR receiver software with a web UI. an open-source SDR receiver software with a web UI.
Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu> Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu>
Copyright (c) 2019-2020 by Jakob Ketterl <dd5jfk@darc.de>
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as it under the terms of the GNU Affero General Public License as
@ -31,8 +32,11 @@ config_webrx: configuration options for OpenWebRX
and use them for running your web service with OpenWebRX.) and use them for running your web service with OpenWebRX.)
""" """
# configuration version. please only modify if you're able to perform the associated migration steps.
version = 3
# NOTE: you can find additional information about configuring OpenWebRX in the Wiki: # NOTE: you can find additional information about configuring OpenWebRX in the Wiki:
# https://github.com/simonyiszk/openwebrx/wiki # https://github.com/jketterl/openwebrx/wiki/Configuration-guide
# ==== Server settings ==== # ==== Server settings ====
web_port = 8073 web_port = 8073
@ -43,37 +47,50 @@ receiver_name = "[Callsign]"
receiver_location = "Budapest, Hungary" receiver_location = "Budapest, Hungary"
receiver_asl = 200 receiver_asl = 200
receiver_admin = "example@example.com" receiver_admin = "example@example.com"
receiver_gps = (47.000000, 19.000000) receiver_gps = {"lat": 47.000000, "lon": 19.000000}
photo_title = "Panorama of Budapest from Schönherz Zoltán Dormitory" photo_title = "Panorama of Budapest from Schönherz Zoltán Dormitory"
# photo_desc allows you to put pretty much any HTML you like into the receiver description.
# The lines below should give you some examples of what's possible.
photo_desc = """ photo_desc = """
You can add your own background photo and receiver information.<br /> You can add your own background photo and receiver information.<br />
Receiver is operated by: <a href="mailto:%[RX_ADMIN]">%[RX_ADMIN]</a><br/> Receiver is operated by: <a href="mailto:openwebrx@localhost" target="_blank">Receiver Operator</a><br/>
Device: %[RX_DEVICE]<br /> Device: Receiver Device<br />
Antenna: %[RX_ANT]<br /> Antenna: Receiver Antenna<br />
Website: <a href="http://localhost" target="_blank">http://localhost</a> Website: <a href="http://localhost" target="_blank">http://localhost</a>
""" """
# ==== sdr.hu listing ==== # ==== Public receiver listings ====
# If you want your ham receiver to be listed publicly on sdr.hu, then take the following steps: # You can publish your receiver on online receiver directories, like https://www.receiverbook.de
# 1. Register at: http://sdr.hu/register # You will receive a receiver key from the directory that will authenticate you as the operator of this receiver.
# 2. You will get an unique key by email. Copy it and paste here: # Please note that you not share your receiver keys publicly since anyone that obtains your receiver key can take over
sdrhu_key = "" # your public listing.
# 3. Set this setting to True to enable listing: # Your receiver keys should be placed into this array:
sdrhu_public_listing = False receiver_keys = []
server_hostname = "localhost" # If you list your receiver on multiple sites, you can place all your keys into the array above, or you can append
# keys to the arraylike this:
# receiver_keys += ["my-receiver-key"]
# If you're not sure, simply copy & paste the code you received from your listing site below this line:
# ==== DSP/RX settings ==== # ==== DSP/RX settings ====
fft_fps = 9 fft_fps = 9
fft_size = 4096 # Should be power of 2 fft_size = 4096 # Should be power of 2
fft_voverlap_factor = ( fft_voverlap_factor = (
0.3 0.3 # If fft_voverlap_factor is above 0, multiple FFTs will be used for creating a line on the diagram.
) # If fft_voverlap_factor is above 0, multiple FFTs will be used for creating a line on the diagram. )
audio_compression = "adpcm" # valid values: "adpcm", "none" audio_compression = "adpcm" # valid values: "adpcm", "none"
fft_compression = "adpcm" # valid values: "adpcm", "none" fft_compression = "adpcm" # valid values: "adpcm", "none"
# Tau setting for WFM (broadcast FM) deemphasis\
# Quote from wikipedia https://en.wikipedia.org/wiki/FM_broadcasting#Pre-emphasis_and_de-emphasis
# "In most of the world a 50 µs time constant is used. In the Americas and South Korea, 75 µs is used"
# Enable one of the following lines, depending on your location:
# wfm_deemphasis_tau = 75e-6 # for US and South Korea
wfm_deemphasis_tau = 50e-6 # for the rest of the world
digimodes_enable = True # Decoding digimodes come with higher CPU usage. digimodes_enable = True # Decoding digimodes come with higher CPU usage.
digimodes_fft_size = 1024 digimodes_fft_size = 2048
# determines the quality, and thus the cpu usage, for the ambe codec used by digital voice modes # determines the quality, and thus the cpu usage, for the ambe codec used by digital voice modes
# if you're running on a Raspi (up to 3B+) you'll want to leave this on 1 # if you're running on a Raspi (up to 3B+) you'll want to leave this on 1
@ -92,12 +109,28 @@ Note: if you experience audio underruns while CPU usage is 100%, you can:
# ==== I/Q sources ==== # ==== I/Q sources ====
# (Uncomment the appropriate by removing # characters at the beginning of the corresponding lines.) # (Uncomment the appropriate by removing # characters at the beginning of the corresponding lines.)
################################################################################################# ###############################################################################
# Is my SDR hardware supported? # # Is my SDR hardware supported? #
# Check here: https://github.com/simonyiszk/openwebrx/wiki#guides-for-receiver-hardware-support # # Check here: https://github.com/jketterl/openwebrx/wiki/Supported-Hardware #
################################################################################################# ###############################################################################
# Currently supported types of sdr receivers: "rtl_sdr", "sdrplay", "hackrf", "airspy" # Currently supported types of sdr receivers:
# "rtl_sdr", "rtl_sdr_soapy", "sdrplay", "hackrf", "airspy", "airspyhf", "fifi_sdr",
# "perseussdr", "lime_sdr", "pluto_sdr", "soapy_remote"
#
# In order to use rtl_sdr, you will need to install librtlsdr-dev and the connector.
# In order to use sdrplay, airspy or airspyhf, you will need to install soapysdr, the corresponding driver, and the
# connector.
#
# https://github.com/jketterl/owrx_connector
#
# In order to use Perseus HF you need to install the libperseus-sdr
#
# https://github.com/Microtelecom/libperseus-sdr
#
# and do the proper changes to the sdrs object below
# (see also Wiki in https://github.com/jketterl/openwebrx/wiki/Sample-configuration-for-Perseus-HF-receiver).
#
sdrs = { sdrs = {
"rtlsdr": { "rtlsdr": {
@ -105,13 +138,13 @@ sdrs = {
"type": "rtl_sdr", "type": "rtl_sdr",
"ppm": 0, "ppm": 0,
# you can change this if you use an upconverter. formula is: # you can change this if you use an upconverter. formula is:
# shown_center_freq = center_freq + lfo_offset # center_freq + lfo_offset = actual frequency on the sdr
# "lfo_offset": 0, # "lfo_offset": 0,
"profiles": { "profiles": {
"70cm": { "70cm": {
"name": "70cm Relais", "name": "70cm Relais",
"center_freq": 438800000, "center_freq": 438800000,
"rf_gain": 30, "rf_gain": 29,
"samp_rate": 2400000, "samp_rate": 2400000,
"start_freq": 439275000, "start_freq": 439275000,
"start_mod": "nfm", "start_mod": "nfm",
@ -119,17 +152,61 @@ sdrs = {
"2m": { "2m": {
"name": "2m komplett", "name": "2m komplett",
"center_freq": 145000000, "center_freq": 145000000,
"rf_gain": 30, "rf_gain": 29,
"samp_rate": 2400000, "samp_rate": 2048000,
"start_freq": 145725000, "start_freq": 145725000,
"start_mod": "nfm", "start_mod": "nfm",
}, },
}, },
}, },
"airspy": {
"name": "Airspy HF+",
"type": "airspyhf",
"ppm": 0,
"rf_gain": "auto",
"profiles": {
"20m": {
"name": "20m",
"center_freq": 14150000,
"samp_rate": 384000,
"start_freq": 14070000,
"start_mod": "usb",
},
"30m": {
"name": "30m",
"center_freq": 10125000,
"samp_rate": 192000,
"start_freq": 10142000,
"start_mod": "usb",
},
"40m": {
"name": "40m",
"center_freq": 7100000,
"samp_rate": 256000,
"start_freq": 7070000,
"start_mod": "lsb",
},
"80m": {
"name": "80m",
"center_freq": 3650000,
"samp_rate": 384000,
"start_freq": 3570000,
"start_mod": "lsb",
},
"49m": {
"name": "49m Broadcast",
"center_freq": 6050000,
"samp_rate": 384000,
"start_freq": 6070000,
"start_mod": "am",
},
},
},
"sdrplay": { "sdrplay": {
"name": "SDRPlay RSP2", "name": "SDRPlay RSP2",
"type": "sdrplay", "type": "sdrplay",
"ppm": 0, "ppm": 0,
"antenna": "Antenna A",
"profiles": { "profiles": {
"20m": { "20m": {
"name": "20m", "name": "20m",
@ -138,7 +215,6 @@ sdrs = {
"samp_rate": 500000, "samp_rate": 500000,
"start_freq": 14070000, "start_freq": 14070000,
"start_mod": "usb", "start_mod": "usb",
"antenna": "Antenna A",
}, },
"30m": { "30m": {
"name": "30m", "name": "30m",
@ -154,8 +230,7 @@ sdrs = {
"rf_gain": 0, "rf_gain": 0,
"samp_rate": 500000, "samp_rate": 500000,
"start_freq": 7070000, "start_freq": 7070000,
"start_mod": "usb", "start_mod": "lsb",
"antenna": "Antenna A",
}, },
"80m": { "80m": {
"name": "80m", "name": "80m",
@ -163,8 +238,7 @@ sdrs = {
"rf_gain": 0, "rf_gain": 0,
"samp_rate": 500000, "samp_rate": 500000,
"start_freq": 3570000, "start_freq": 3570000,
"start_mod": "usb", "start_mod": "lsb",
"antenna": "Antenna A",
}, },
"49m": { "49m": {
"name": "49m Broadcast", "name": "49m Broadcast",
@ -173,56 +247,37 @@ sdrs = {
"samp_rate": 500000, "samp_rate": 500000,
"start_freq": 6070000, "start_freq": 6070000,
"start_mod": "am", "start_mod": "am",
"antenna": "Antenna A",
}, },
}, },
}, },
} }
# ==== Misc settings ====
iq_port_range = [
4950,
4960,
] # TCP port for range ncat to listen on. It will send I/Q data over its connections, for internal use in OpenWebRX. It is only accessible from the localhost by default.
# ==== Color themes ==== # ==== Color themes ====
# A guide is available to help you set these values: https://github.com/simonyiszk/openwebrx/wiki/Calibrating-waterfall-display-levels ### google turbo colormap (see: https://ai.googleblog.com/2019/08/turbo-improved-rainbow-colormap-for.html)
waterfall_colors = [0x30123b, 0x311542, 0x33184a, 0x341b51, 0x351e58, 0x36215f, 0x372466, 0x38266c, 0x392973, 0x3a2c79, 0x3b2f80, 0x3c3286, 0x3d358b, 0x3e3891, 0x3e3a97, 0x3f3d9c, 0x4040a2, 0x4043a7, 0x4146ac, 0x4248b1, 0x424bb6, 0x434eba, 0x4351bf, 0x4453c3, 0x4456c7, 0x4559cb, 0x455bcf, 0x455ed3, 0x4561d7, 0x4663da, 0x4666dd, 0x4669e1, 0x466be4, 0x466ee7, 0x4671e9, 0x4673ec, 0x4676ee, 0x4678f1, 0x467bf3, 0x467df5, 0x4680f7, 0x4682f9, 0x4685fa, 0x4587fc, 0x458afd, 0x448cfe, 0x448ffe, 0x4391ff, 0x4294ff, 0x4196ff, 0x3f99ff, 0x3e9bff, 0x3d9efe, 0x3ba1fd, 0x3aa3fd, 0x38a6fb, 0x36a8fa, 0x35abf9, 0x33adf7, 0x31b0f6, 0x2fb2f4, 0x2db5f2, 0x2cb7f0, 0x2ab9ee, 0x28bcec, 0x26beea, 0x25c0e7, 0x23c3e5, 0x21c5e2, 0x20c7e0, 0x1fc9dd, 0x1dccdb, 0x1cced8, 0x1bd0d5, 0x1ad2d3, 0x19d4d0, 0x18d6cd, 0x18d8cb, 0x18dac8, 0x17dbc5, 0x17ddc3, 0x17dfc0, 0x18e0be, 0x18e2bb, 0x19e3b9, 0x1ae5b7, 0x1be6b4, 0x1de8b2, 0x1ee9af, 0x20eaad, 0x22ecaa, 0x24eda7, 0x27eea4, 0x29efa1, 0x2cf09e, 0x2ff19b, 0x32f298, 0x35f394, 0x38f491, 0x3cf58e, 0x3ff68b, 0x43f787, 0x46f884, 0x4af980, 0x4efa7d, 0x51fa79, 0x55fb76, 0x59fc73, 0x5dfc6f, 0x61fd6c, 0x65fd69, 0x69fe65, 0x6dfe62, 0x71fe5f, 0x75ff5c, 0x79ff59, 0x7dff56, 0x80ff53, 0x84ff50, 0x88ff4e, 0x8bff4b, 0x8fff49, 0x92ff46, 0x96ff44, 0x99ff42, 0x9cfe40, 0x9ffe3e, 0xa2fd3d, 0xa4fd3b, 0xa7fc3a, 0xaafc39, 0xacfb38, 0xaffa37, 0xb1f936, 0xb4f835, 0xb7f835, 0xb9f634, 0xbcf534, 0xbff434, 0xc1f334, 0xc4f233, 0xc6f033, 0xc9ef34, 0xcbee34, 0xceec34, 0xd0eb34, 0xd2e934, 0xd5e835, 0xd7e635, 0xd9e435, 0xdbe236, 0xdde136, 0xe0df37, 0xe2dd37, 0xe4db38, 0xe6d938, 0xe7d738, 0xe9d539, 0xebd339, 0xedd139, 0xeecf3a, 0xf0cd3a, 0xf1cb3a, 0xf3c93a, 0xf4c73a, 0xf5c53a, 0xf7c33a, 0xf8c13a, 0xf9bf39, 0xfabd39, 0xfaba38, 0xfbb838, 0xfcb637, 0xfcb436, 0xfdb135, 0xfdaf35, 0xfeac34, 0xfea933, 0xfea732, 0xfea431, 0xffa12f, 0xff9e2e, 0xff9c2d, 0xff992c, 0xfe962b, 0xfe932a, 0xfe9028, 0xfe8d27, 0xfd8a26, 0xfd8724, 0xfc8423, 0xfc8122, 0xfb7e20, 0xfb7b1f, 0xfa781e, 0xf9751c, 0xf8721b, 0xf86f1a, 0xf76c19, 0xf66917, 0xf56616, 0xf46315, 0xf36014, 0xf25d13, 0xf05b11, 0xef5810, 0xee550f, 0xed530e, 0xeb500e, 0xea4e0d, 0xe94b0c, 0xe7490b, 0xe6470a, 0xe4450a, 0xe34209, 0xe14009, 0xdf3e08, 0xde3c07, 0xdc3a07, 0xda3806, 0xd83606, 0xd63405, 0xd43205, 0xd23105, 0xd02f04, 0xce2d04, 0xcc2b03, 0xca2903, 0xc82803, 0xc62602, 0xc32402, 0xc12302, 0xbf2102, 0xbc1f01, 0xba1e01, 0xb71c01, 0xb41b01, 0xb21901, 0xaf1801, 0xac1601, 0xaa1501, 0xa71401, 0xa41201, 0xa11101, 0x9e1001, 0x9b0f01, 0x980d01, 0x950c01, 0x920b01, 0x8e0a01, 0x8b0901, 0x880801, 0x850701, 0x810602, 0x7e0502, 0x7a0402]
### original theme by teejez:
#waterfall_colors = [0x000000, 0x0000FF, 0x00FFFF, 0x00FF00, 0xFFFF00, 0xFF0000, 0xFF00FF, 0xFFFFFF]
### default theme by teejez:
waterfall_colors = [0x000000FF, 0x0000FFFF, 0x00FFFFFF, 0x00FF00FF, 0xFFFF00FF, 0xFF0000FF, 0xFF00FFFF, 0xFFFFFFFF]
waterfall_min_level = -88 # in dB
waterfall_max_level = -20
waterfall_auto_level_margin = (5, 40)
### old theme by HA7ILM: ### old theme by HA7ILM:
# waterfall_colors = "[0x000000ff,0x2e6893ff, 0x69a5d0ff, 0x214b69ff, 0x9dc4e0ff, 0xfff775ff, 0xff8a8aff, 0xb20000ff]" #waterfall_colors = [0x000000, 0x2e6893, 0x69a5d0, 0x214b69, 0x9dc4e0, 0xfff775, 0xff8a8a, 0xb20000]
# waterfall_min_level = -115 #in dB # waterfall_min_level = -115 #in dB
# waterfall_max_level = 0 # waterfall_max_level = 0
# waterfall_auto_level_margin = (20, 30) # waterfall_auto_level_margin = {"min": 20, "max": 30}
##For the old colors, you might also want to set [fft_voverlap_factor] to 0. ##For the old colors, you might also want to set [fft_voverlap_factor] to 0.
# Note: When the auto waterfall level button is clicked, the following happens: waterfall_min_level = -88 # in dB
# [waterfall_min_level] = [current_min_power_level] - [waterfall_auto_level_margin[0]] waterfall_max_level = -20
# [waterfall_max_level] = [current_max_power_level] + [waterfall_auto_level_margin[1]] waterfall_auto_level_margin = {"min": 3, "max": 10, "min_range": 50}
#
# ___|____________________________________|____________________________________|____________________________________|___> signal power
# \_waterfall_auto_level_margin[0]_/ |__ current_min_power_level | \_waterfall_auto_level_margin[1]_/
# current_max_power_level __|
# 3D view settings # Note: When the auto waterfall level button is clicked, the following happens:
mathbox_waterfall_frequency_resolution = 128 # bins # [waterfall_min_level] = [current_min_power_level] - [waterfall_auto_level_margin["min"]]
mathbox_waterfall_history_length = 10 # seconds # [waterfall_max_level] = [current_max_power_level] + [waterfall_auto_level_margin["max"]]
mathbox_waterfall_colors = [ #
0x000000FF, # ___|________________________________________|____________________________________|________________________________________|___> signal power
0x2E6893FF, # \_waterfall_auto_level_margin["min"]_/ |__ current_min_power_level | \_waterfall_auto_level_margin["max"]_/
0x69A5D0FF, # current_max_power_level __|
0x214B69FF,
0x9DC4E0FF,
0xFFF775FF,
0xFF8A8AFF,
0xB20000FF,
]
# === Experimental settings === # === Experimental settings ===
# Warning! The settings below are very experimental. # Warning! The settings below are very experimental.
@ -239,22 +294,28 @@ google_maps_api_key = ""
# in seconds; default: 2 hours # in seconds; default: 2 hours
map_position_retention_time = 2 * 60 * 60 map_position_retention_time = 2 * 60 * 60
# wsjt decoder queue configuration # decoder queue configuration
# due to the nature of the wsjt operating modes (ft8, ft8, jt9, jt65 and wspr), the data is recorded for a given amount # due to the nature of some operating modes (ft8, ft8, jt9, jt65, wspr and js8), the data is recorded for a given amount
# of time (6.5 seconds up to 2 minutes) and decoded at the end. this can lead to very high peak loads. # of time (6 seconds up to 2 minutes) and decoded at the end. this can lead to very high peak loads.
# to mitigate this, the recordings will be queued and processed in sequence. # to mitigate this, the recordings will be queued and processed in sequence.
# the number of workers will limit the total amount of work (one worker will losely occupy one cpu / thread) # the number of workers will limit the total amount of work (one worker will losely occupy one cpu / thread)
wsjt_queue_workers = 2 decoding_queue_workers = 2
# the maximum queue length will cause decodes to be dumped if the workers cannot keep up # the maximum queue length will cause decodes to be dumped if the workers cannot keep up
# if you are running background services, make sure this number is high enough to accept the task influx during peaks # if you are running background services, make sure this number is high enough to accept the task influx during peaks
# i.e. this should be higher than the number of wsjt services running at the same time # i.e. this should be higher than the number of decoding services running at the same time
wsjt_queue_length = 10 decoding_queue_length = 10
# wsjt decoding depth will allow more results, but will also consume more cpu # wsjt decoding depth will allow more results, but will also consume more cpu
wsjt_decoding_depth = 3 wsjt_decoding_depth = 3
# can also be set for each mode separately # can also be set for each mode separately
# jt65 seems to be somewhat prone to erroneous decodes, this setting handles that to some extent # jt65 seems to be somewhat prone to erroneous decodes, this setting handles that to some extent
wsjt_decoding_depths = {"jt65": 1} wsjt_decoding_depths = {"jt65": 1}
# JS8 comes in different speeds: normal, slow, fast, turbo. This setting controls which ones are enabled.
js8_enabled_profiles = ["normal", "slow"]
# JS8 decoding depth; higher value will get more results, but will also consume more cpu
js8_decoding_depth = 3
temporary_directory = "/tmp" temporary_directory = "/tmp"
services_enabled = False services_enabled = False
@ -277,3 +338,8 @@ aprs_symbols_path = "/opt/aprs-symbols/png"
# this also uses the receiver_gps setting from above, so make sure it contains a correct locator # this also uses the receiver_gps setting from above, so make sure it contains a correct locator
pskreporter_enabled = False pskreporter_enabled = False
pskreporter_callsign = "N0CALL" pskreporter_callsign = "N0CALL"
# === Web admin settings ===
# this feature is experimental at the moment. it should not be enabled on shared receivers since it allows remote
# changes to the receiver settings. enable for testing in controlled environment only.
# webadmin_enabled = False

View File

@ -4,6 +4,7 @@ OpenWebRX csdr plugin: do the signal processing with csdr
This file is part of OpenWebRX, This file is part of OpenWebRX,
an open-source SDR receiver software with a web UI. an open-source SDR receiver software with a web UI.
Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu> Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu>
Copyright (c) 2019-2020 by Jakob Ketterl <dd5jfk@darc.de>
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as it under the terms of the GNU Affero General Public License as
@ -24,10 +25,15 @@ import subprocess
import os import os
import signal import signal
import threading import threading
import math
from functools import partial from functools import partial
from owrx.kiss import KissClient, DirewolfConfig from owrx.kiss import KissClient, DirewolfConfig
from owrx.wsjt import Ft8Chopper, WsprChopper, Jt9Chopper, Jt65Chopper, Ft4Chopper from owrx.wsjt import Ft8Profile, WsprProfile, Jt9Profile, Jt65Profile, Ft4Profile
from owrx.js8 import Js8Profiles
from owrx.audio import AudioChopper
from csdr.pipe import Pipe
import logging import logging
@ -39,7 +45,7 @@ class output(object):
if not self.supports_type(t): if not self.supports_type(t):
# TODO rewrite the output mechanism in a way that avoids producing unnecessary data # TODO rewrite the output mechanism in a way that avoids producing unnecessary data
logger.warning("dumping output of type %s since it is not supported.", t) logger.warning("dumping output of type %s since it is not supported.", t)
threading.Thread(target=self.pump(read_fn, lambda x: None)).start() threading.Thread(target=self.pump(read_fn, lambda x: None), name="csdr_pump_thread").start()
return return
self.receive_output(t, read_fn) self.receive_output(t, read_fn)
@ -50,7 +56,11 @@ class output(object):
def copy(): def copy():
run = True run = True
while run: while run:
data = None
try:
data = read() data = read()
except ValueError:
pass
if data is None or (isinstance(data, bytes) and len(data) == 0): if data is None or (isinstance(data, bytes) and len(data) == 0):
run = False run = False
else: else:
@ -66,8 +76,10 @@ class dsp(object):
def __init__(self, output): def __init__(self, output):
self.samp_rate = 250000 self.samp_rate = 250000
self.output_rate = 11025 self.output_rate = 11025
self.hd_output_rate = 44100
self.fft_size = 1024 self.fft_size = 1024
self.fft_fps = 5 self.fft_fps = 5
self.center_freq = 0
self.offset_freq = 0 self.offset_freq = 0
self.low_cut = -4000 self.low_cut = -4000
self.high_cut = 4000 self.high_cut = 4000
@ -80,43 +92,53 @@ class dsp(object):
self.demodulator = "nfm" self.demodulator = "nfm"
self.name = "csdr" self.name = "csdr"
self.base_bufsize = 512 self.base_bufsize = 512
self.decimation = None
self.last_decimation = None
self.nc_port = None self.nc_port = None
self.csdr_dynamic_bufsize = False self.csdr_dynamic_bufsize = False
self.csdr_print_bufsizes = False self.csdr_print_bufsizes = False
self.csdr_through = False self.csdr_through = False
self.squelch_level = 0 self.squelch_level = -150
self.fft_averages = 50 self.fft_averages = 50
self.wfm_deemphasis_tau = 50e-6
self.iqtee = False self.iqtee = False
self.iqtee2 = False self.iqtee2 = False
self.secondary_demodulator = None self.secondary_demodulator = None
self.secondary_fft_size = 1024 self.secondary_fft_size = 1024
self.secondary_process_fft = None self.secondary_process_fft = None
self.secondary_process_demod = None self.secondary_process_demod = None
self.pipe_names = [ self.pipe_names = {
"bpf_pipe", "bpf_pipe": Pipe.WRITE,
"shift_pipe", "shift_pipe": Pipe.WRITE,
"squelch_pipe", "squelch_pipe": Pipe.WRITE,
"smeter_pipe", "smeter_pipe": Pipe.READ,
"meta_pipe", "meta_pipe": Pipe.READ,
"iqtee_pipe", "iqtee_pipe": Pipe.NONE,
"iqtee2_pipe", "iqtee2_pipe": Pipe.NONE,
"dmr_control_pipe", "dmr_control_pipe": Pipe.WRITE,
] }
self.secondary_pipe_names = ["secondary_shift_pipe"] self.pipes = {}
self.secondary_pipe_names = {"secondary_shift_pipe": Pipe.WRITE}
self.secondary_offset_freq = 1000 self.secondary_offset_freq = 1000
self.unvoiced_quality = 1 self.unvoiced_quality = 1
self.modification_lock = threading.Lock() self.modification_lock = threading.Lock()
self.output = output self.output = output
self.temporary_directory = "/tmp"
self.temporary_directory = None
self.pipe_base_path = None
self.set_temporary_directory("/tmp")
self.is_service = False self.is_service = False
self.direwolf_config = None self.direwolf_config = None
self.direwolf_port = None self.direwolf_port = None
self.process = None
def set_service(self, flag=True): def set_service(self, flag=True):
self.is_service = flag self.is_service = flag
def set_temporary_directory(self, what): def set_temporary_directory(self, what):
self.temporary_directory = what self.temporary_directory = what
self.pipe_base_path = "{tmp_dir}/openwebrx_pipe_".format(tmp_dir=self.temporary_directory)
def chain(self, which): def chain(self, which):
chain = ["nc -v 127.0.0.1 {nc_port}"] chain = ["nc -v 127.0.0.1 {nc_port}"]
@ -135,7 +157,7 @@ class dsp(object):
if self.fft_compression == "adpcm": if self.fft_compression == "adpcm":
chain += ["csdr compress_fft_adpcm_f_u8 {fft_size}"] chain += ["csdr compress_fft_adpcm_f_u8 {fft_size}"]
return chain return chain
chain += ["csdr shift_addition_cc --fifo {shift_pipe}"] chain += ["csdr shift_addfast_cc --fifo {shift_pipe}"]
if self.decimation > 1: if self.decimation > 1:
chain += ["csdr fir_decimate_cc {decimation} {ddc_transition_bw} HAMMING"] chain += ["csdr fir_decimate_cc {decimation} {ddc_transition_bw} HAMMING"]
chain += ["csdr bandpass_fir_fft_cc --fifo {bpf_pipe} {bpf_transition_bw} HAMMING"] chain += ["csdr bandpass_fir_fft_cc --fifo {bpf_pipe} {bpf_transition_bw} HAMMING"]
@ -151,19 +173,35 @@ class dsp(object):
if not self.output.supports_type("audio"): if not self.output.supports_type("audio"):
return chain return chain
# safe some cpu cycles... no need to decimate if decimation factor is 1 # safe some cpu cycles... no need to decimate if decimation factor is 1
last_decimation_block = ( last_decimation_block = []
["csdr fractional_decimator_ff {last_decimation}"] if self.last_decimation != 1.0 else [] if self.last_decimation >= 2.0:
) # activate prefilter if signal has been oversampled, e.g. WFM
last_decimation_block = ["csdr fractional_decimator_ff {last_decimation} 12 --prefilter"]
elif self.last_decimation != 1.0:
last_decimation_block = ["csdr fractional_decimator_ff {last_decimation}"]
if which == "nfm": if which == "nfm":
chain += ["csdr fmdemod_quadri_cf", "csdr limit_ff"] chain += ["csdr fmdemod_quadri_cf", "csdr limit_ff"]
chain += last_decimation_block chain += last_decimation_block
chain += ["csdr deemphasis_nfm_ff {audio_rate}"] chain += [
"csdr deemphasis_nfm_ff {audio_rate}",
"csdr agc_ff --profile slow --max 3",
]
if self.get_audio_rate() != self.get_output_rate(): if self.get_audio_rate() != self.get_output_rate():
chain += [ chain += [
"sox -t raw -r {audio_rate} -e floating-point -b 32 -c 1 --buffer 32 - -t raw -r {output_rate} -e signed-integer -b 16 -c 1 - " "sox -t raw -r {audio_rate} -e floating-point -b 32 -c 1 --buffer 32 - -t raw -r {output_rate} -e signed-integer -b 16 -c 1 - "
] ]
else: else:
chain += ["csdr convert_f_s16"] chain += ["csdr convert_f_s16"]
elif which == "wfm":
chain += [
"csdr fmdemod_quadri_cf",
"csdr limit_ff",
]
chain += last_decimation_block
chain += [
"csdr deemphasis_wfm_ff {audio_rate} {wfm_deemphasis_tau}",
"csdr convert_f_s16"
]
elif self.isDigitalVoice(which): elif self.isDigitalVoice(which):
chain += ["csdr fmdemod_quadri_cf", "dc_block "] chain += ["csdr fmdemod_quadri_cf", "dc_block "]
chain += last_decimation_block chain += last_decimation_block
@ -174,8 +212,11 @@ class dsp(object):
chain += ["dsd -fd -i - -o - -u {unvoiced_quality} -g -1 "] chain += ["dsd -fd -i - -o - -u {unvoiced_quality} -g -1 "]
elif which == "nxdn": elif which == "nxdn":
chain += ["dsd -fi -i - -o - -u {unvoiced_quality} -g -1 "] chain += ["dsd -fi -i - -o - -u {unvoiced_quality} -g -1 "]
chain += ["CSDR_FIXED_BUFSIZE=32 csdr convert_s16_f"] chain += [
max_gain = 5 "digitalvoice_filter",
"CSDR_FIXED_BUFSIZE=32 csdr agc_s16 --max 30 --initial 3",
"sox -t raw -r 8000 -e signed-integer -b 16 -c 1 --buffer 32 - -t raw -r {output_rate} -e signed-integer -b 16 -c 1 - ",
]
# digiham modes # digiham modes
else: else:
chain += ["rrc_filter", "gfsk_demodulator"] chain += ["rrc_filter", "gfsk_demodulator"]
@ -186,20 +227,42 @@ class dsp(object):
] ]
elif which == "ysf": elif which == "ysf":
chain += ["ysf_decoder --fifo {meta_pipe}", "mbe_synthesizer -y -f -u {unvoiced_quality}"] chain += ["ysf_decoder --fifo {meta_pipe}", "mbe_synthesizer -y -f -u {unvoiced_quality}"]
max_gain = 0.0005 max_gain = 0.005
chain += [ chain += [
"digitalvoice_filter -f", "digitalvoice_filter -f",
"CSDR_FIXED_BUFSIZE=32 csdr agc_ff 160000 0.8 1 0.0000001 {max_gain}".format(max_gain=max_gain), "CSDR_FIXED_BUFSIZE=32 csdr agc_ff --max 0.005 --initial 0.0005",
"sox -t raw -r 8000 -e floating-point -b 32 -c 1 --buffer 32 - -t raw -r {output_rate} -e signed-integer -b 16 -c 1 - ", "sox -t raw -r 8000 -e floating-point -b 32 -c 1 --buffer 32 - -t raw -r {output_rate} -e signed-integer -b 16 -c 1 - ",
] ]
elif which == "am": elif which == "am":
chain += ["csdr amdemod_cf", "csdr fastdcblock_ff"] chain += ["csdr amdemod_cf", "csdr fastdcblock_ff"]
chain += last_decimation_block chain += last_decimation_block
chain += ["csdr agc_ff", "csdr limit_ff", "csdr convert_f_s16"] chain += [
"csdr agc_ff --profile slow --initial 200",
"csdr convert_f_s16",
]
elif self.isFreeDV(which):
chain += ["csdr realpart_cf"]
chain += last_decimation_block
chain += [
"csdr agc_ff",
"csdr convert_f_s16",
"freedv_rx 1600 - -",
"csdr agc_s16 --max 30 --initial 3",
"sox -t raw -r 8000 -e signed-integer -b 16 -c 1 --buffer 32 - -t raw -r {output_rate} -e signed-integer -b 16 -c 1 - ",
]
elif self.isDrm(which):
if self.last_decimation != 1.0:
# we are still dealing with complex samples here, so the regular last_decimation_block doesn't fit
chain += ["csdr fractional_decimator_cc {last_decimation}"]
chain += [
"csdr convert_f_s16",
"dream -c 6 --sigsrate 48000 --audsrate 48000 -I - -O -",
"sox -t raw -r 48000 -e signed-integer -b 16 -c 2 - -t raw -r {output_rate} -e signed-integer -b 16 -c 1 - ",
]
elif which == "ssb": elif which == "ssb":
chain += ["csdr realpart_cf"] chain += ["csdr realpart_cf"]
chain += last_decimation_block chain += last_decimation_block
chain += ["csdr agc_ff", "csdr limit_ff"] chain += ["csdr agc_ff"]
# fixed sample rate necessary for the wsjt-x tools. fix with sox... # fixed sample rate necessary for the wsjt-x tools. fix with sox...
if self.get_audio_rate() != self.get_output_rate(): if self.get_audio_rate() != self.get_output_rate():
chain += [ chain += [
@ -213,35 +276,42 @@ class dsp(object):
return chain return chain
def secondary_chain(self, which): def secondary_chain(self, which):
secondary_chain_base = "cat {input_pipe} | " chain = ["cat {input_pipe}"]
if which == "fft": if which == "fft":
return ( chain += [
secondary_chain_base "csdr fft_cc {secondary_fft_input_size} {secondary_fft_block_size}",
+ "csdr realpart_cf | csdr fft_fc {secondary_fft_input_size} {secondary_fft_block_size} | csdr logpower_cf -70 " "csdr logpower_cf -70"
+ (" | csdr compress_fft_adpcm_f_u8 {secondary_fft_size}" if self.fft_compression == "adpcm" else "") if self.fft_averages == 0
) else "csdr logaveragepower_cf -70 {secondary_fft_size} {fft_averages}",
elif which == "bpsk31": "csdr fft_exchange_sides_ff {secondary_fft_input_size}",
return ( ]
secondary_chain_base if self.fft_compression == "adpcm":
+ "csdr shift_addition_cc --fifo {secondary_shift_pipe} | " chain += ["csdr compress_fft_adpcm_f_u8 {secondary_fft_size}"]
+ "csdr bandpass_fir_fft_cc -{secondary_bpf_cutoff} {secondary_bpf_cutoff} {secondary_bpf_cutoff} | "
+ "csdr simple_agc_cc 0.001 0.5 | "
+ "csdr timing_recovery_cc GARDNER {secondary_samples_per_bits} 0.5 2 --add_q | "
+ "CSDR_FIXED_BUFSIZE=1 csdr dbpsk_decoder_c_u8 | "
+ "CSDR_FIXED_BUFSIZE=1 csdr psk31_varicode_decoder_u8_u8"
)
elif self.isWsjtMode(which):
chain = secondary_chain_base + "csdr realpart_cf | "
if self.last_decimation != 1.0:
chain += "csdr fractional_decimator_ff {last_decimation} | "
chain += "csdr agc_ff | csdr limit_ff | csdr convert_f_s16"
return chain return chain
elif which == "bpsk31" or which == "bpsk63":
return chain + [
"csdr shift_addfast_cc --fifo {secondary_shift_pipe}",
"csdr bandpass_fir_fft_cc -{secondary_bpf_cutoff} {secondary_bpf_cutoff} {secondary_bpf_cutoff}",
"csdr simple_agc_cc 0.001 0.5",
"csdr timing_recovery_cc GARDNER {secondary_samples_per_bits} 0.5 2 --add_q",
"CSDR_FIXED_BUFSIZE=1 csdr dbpsk_decoder_c_u8",
"CSDR_FIXED_BUFSIZE=1 csdr psk31_varicode_decoder_u8_u8",
]
elif self.isWsjtMode(which) or self.isJs8(which):
chain += ["csdr realpart_cf"]
if self.last_decimation != 1.0:
chain += ["csdr fractional_decimator_ff {last_decimation}"]
return chain + ["csdr limit_ff", "csdr convert_f_s16"]
elif which == "packet": elif which == "packet":
chain = secondary_chain_base + "csdr fmdemod_quadri_cf | " chain += ["csdr fmdemod_quadri_cf"]
if self.last_decimation != 1.0: if self.last_decimation != 1.0:
chain += "csdr fractional_decimator_ff {last_decimation} | " chain += ["csdr fractional_decimator_ff {last_decimation}"]
chain += "csdr convert_f_s16 | direwolf -c {direwolf_config} -r {audio_rate} -t 0 -q d -q h - 1>&2" return chain + ["csdr convert_f_s16", "direwolf -c {direwolf_config} -r {audio_rate} -t 0 -q d -q h 1>&2"]
return chain elif which == "pocsag":
chain += ["csdr fmdemod_quadri_cf"]
if self.last_decimation != 1.0:
chain += ["csdr fractional_decimator_ff {last_decimation}"]
return chain + ["fsk_demodulator -i", "pocsag_decoder"]
def set_secondary_demodulator(self, what): def set_secondary_demodulator(self, what):
if self.get_secondary_demodulator() == what: if self.get_secondary_demodulator() == what:
@ -251,9 +321,10 @@ class dsp(object):
self.restart() self.restart()
def secondary_fft_block_size(self): def secondary_fft_block_size(self):
return (self.samp_rate / self.decimation) / ( base = (self.samp_rate / self.decimation) / (self.fft_fps * 2)
self.fft_fps * 2 if self.fft_averages == 0:
) # *2 is there because we do FFT on real signal here return base
return base / self.fft_averages
def secondary_decimation(self): def secondary_decimation(self):
return 1 # currently unused return 1 # currently unused
@ -261,33 +332,41 @@ class dsp(object):
def secondary_bpf_cutoff(self): def secondary_bpf_cutoff(self):
if self.secondary_demodulator == "bpsk31": if self.secondary_demodulator == "bpsk31":
return 31.25 / self.if_samp_rate() return 31.25 / self.if_samp_rate()
elif self.secondary_demodulator == "bpsk63":
return 62.5 / self.if_samp_rate()
return 0 return 0
def secondary_bpf_transition_bw(self): def secondary_bpf_transition_bw(self):
if self.secondary_demodulator == "bpsk31": if self.secondary_demodulator == "bpsk31":
return 31.25 / self.if_samp_rate() return 31.25 / self.if_samp_rate()
elif self.secondary_demodulator == "bpsk63":
return 62.5 / self.if_samp_rate()
return 0 return 0
def secondary_samples_per_bits(self): def secondary_samples_per_bits(self):
if self.secondary_demodulator == "bpsk31": if self.secondary_demodulator == "bpsk31":
return int(round(self.if_samp_rate() / 31.25)) & ~3 return int(round(self.if_samp_rate() / 31.25)) & ~3
elif self.secondary_demodulator == "bpsk63":
return int(round(self.if_samp_rate() / 62.5)) & ~3
return 0 return 0
def secondary_bw(self): def secondary_bw(self):
if self.secondary_demodulator == "bpsk31": if self.secondary_demodulator == "bpsk31":
return 31.25 return 31.25
elif self.secondary_demodulator == "bpsk63":
return 62.5
def start_secondary_demodulator(self): def start_secondary_demodulator(self):
if not self.secondary_demodulator: if not self.secondary_demodulator:
return return
logger.debug("starting secondary demodulator from IF input sampled at %d" % self.if_samp_rate()) logger.debug("starting secondary demodulator from IF input sampled at %d" % self.if_samp_rate())
secondary_command_demod = self.secondary_chain(self.secondary_demodulator) secondary_command_demod = " | ".join(self.secondary_chain(self.secondary_demodulator))
self.try_create_pipes(self.secondary_pipe_names, secondary_command_demod) self.try_create_pipes(self.secondary_pipe_names, secondary_command_demod)
self.try_create_configs(secondary_command_demod) self.try_create_configs(secondary_command_demod)
secondary_command_demod = secondary_command_demod.format( secondary_command_demod = secondary_command_demod.format(
input_pipe=self.iqtee2_pipe, input_pipe=self.pipes["iqtee2_pipe"],
secondary_shift_pipe=self.secondary_shift_pipe, secondary_shift_pipe=self.pipes["secondary_shift_pipe"],
secondary_decimation=self.secondary_decimation(), secondary_decimation=self.secondary_decimation(),
secondary_samples_per_bits=self.secondary_samples_per_bits(), secondary_samples_per_bits=self.secondary_samples_per_bits(),
secondary_bpf_cutoff=self.secondary_bpf_cutoff(), secondary_bpf_cutoff=self.secondary_bpf_cutoff(),
@ -304,17 +383,18 @@ class dsp(object):
if self.csdr_print_bufsizes: if self.csdr_print_bufsizes:
my_env["CSDR_PRINT_BUFSIZES"] = "1" my_env["CSDR_PRINT_BUFSIZES"] = "1"
if self.output.supports_type("secondary_fft"): if self.output.supports_type("secondary_fft"):
secondary_command_fft = self.secondary_chain("fft") secondary_command_fft = " | ".join(self.secondary_chain("fft"))
secondary_command_fft = secondary_command_fft.format( secondary_command_fft = secondary_command_fft.format(
input_pipe=self.iqtee_pipe, input_pipe=self.pipes["iqtee_pipe"],
secondary_fft_input_size=self.secondary_fft_size, secondary_fft_input_size=self.secondary_fft_size,
secondary_fft_size=self.secondary_fft_size, secondary_fft_size=self.secondary_fft_size,
secondary_fft_block_size=self.secondary_fft_block_size(), secondary_fft_block_size=self.secondary_fft_block_size(),
fft_averages=self.fft_averages,
) )
logger.debug("secondary command (fft) = %s", secondary_command_fft) logger.debug("secondary command (fft) = %s", secondary_command_fft)
self.secondary_process_fft = subprocess.Popen( self.secondary_process_fft = subprocess.Popen(
secondary_command_fft, stdout=subprocess.PIPE, shell=True, preexec_fn=os.setpgrp, env=my_env secondary_command_fft, stdout=subprocess.PIPE, shell=True, start_new_session=True, env=my_env
) )
self.output.send_output( self.output.send_output(
"secondary_fft", "secondary_fft",
@ -326,56 +406,69 @@ class dsp(object):
# it would block if not read. by piping it to devnull, we avoid a potential pitfall here. # it would block if not read. by piping it to devnull, we avoid a potential pitfall here.
secondary_output = subprocess.DEVNULL if self.isPacket() else subprocess.PIPE secondary_output = subprocess.DEVNULL if self.isPacket() else subprocess.PIPE
self.secondary_process_demod = subprocess.Popen( self.secondary_process_demod = subprocess.Popen(
secondary_command_demod, stdout=secondary_output, shell=True, preexec_fn=os.setpgrp, env=my_env secondary_command_demod, stdout=secondary_output, shell=True, start_new_session=True, env=my_env
) )
self.secondary_processes_running = True self.secondary_processes_running = True
if self.isWsjtMode(): if self.isWsjtMode():
smd = self.get_secondary_demodulator() smd = self.get_secondary_demodulator()
chopper_profile = None
if smd == "ft8": if smd == "ft8":
chopper = Ft8Chopper(self.secondary_process_demod.stdout) chopper_profile = Ft8Profile()
elif smd == "wspr": elif smd == "wspr":
chopper = WsprChopper(self.secondary_process_demod.stdout) chopper_profile = WsprProfile()
elif smd == "jt65": elif smd == "jt65":
chopper = Jt65Chopper(self.secondary_process_demod.stdout) chopper_profile = Jt65Profile()
elif smd == "jt9": elif smd == "jt9":
chopper = Jt9Chopper(self.secondary_process_demod.stdout) chopper_profile = Jt9Profile()
elif smd == "ft4": elif smd == "ft4":
chopper = Ft4Chopper(self.secondary_process_demod.stdout) chopper_profile = Ft4Profile()
if chopper_profile is not None:
chopper = AudioChopper(self, self.secondary_process_demod.stdout, chopper_profile)
chopper.start() chopper.start()
self.output.send_output("wsjt_demod", chopper.read) self.output.send_output("wsjt_demod", chopper.read)
elif self.isJs8():
chopper = AudioChopper(self, self.secondary_process_demod.stdout, *Js8Profiles.getEnabledProfiles())
chopper.start()
self.output.send_output("js8_demod", chopper.read)
elif self.isPacket(): elif self.isPacket():
# we best get the ax25 packets from the kiss socket # we best get the ax25 packets from the kiss socket
kiss = KissClient(self.direwolf_port) kiss = KissClient(self.direwolf_port)
self.output.send_output("packet_demod", kiss.read) self.output.send_output("packet_demod", kiss.read)
elif self.isPocsag():
self.output.send_output("pocsag_demod", self.secondary_process_demod.stdout.readline)
else: else:
self.output.send_output("secondary_demod", partial(self.secondary_process_demod.stdout.read, 1)) self.output.send_output("secondary_demod", partial(self.secondary_process_demod.stdout.read, 1))
# open control pipes for csdr and send initialization data # open control pipes for csdr and send initialization data
if self.secondary_shift_pipe != None: # TODO digimodes if self.has_pipe("secondary_shift_pipe"): # TODO digimodes
self.secondary_shift_pipe_file = open(self.secondary_shift_pipe, "w") # TODO digimodes
self.set_secondary_offset_freq(self.secondary_offset_freq) # TODO digimodes self.set_secondary_offset_freq(self.secondary_offset_freq) # TODO digimodes
def set_secondary_offset_freq(self, value): def set_secondary_offset_freq(self, value):
self.secondary_offset_freq = value self.secondary_offset_freq = value
if self.secondary_processes_running and hasattr(self, "secondary_shift_pipe_file"): if self.secondary_processes_running and self.has_pipe("secondary_shift_pipe"):
self.secondary_shift_pipe_file.write("%g\n" % (-float(self.secondary_offset_freq) / self.if_samp_rate())) self.pipes["secondary_shift_pipe"].write("%g\n" % (-float(self.secondary_offset_freq) / self.if_samp_rate()))
self.secondary_shift_pipe_file.flush()
def stop_secondary_demodulator(self): def stop_secondary_demodulator(self):
if self.secondary_processes_running == False: if not self.secondary_processes_running:
return return
self.try_delete_pipes(self.secondary_pipe_names) self.try_delete_pipes(self.secondary_pipe_names)
self.try_delete_configs() self.try_delete_configs()
if self.secondary_process_fft: if self.secondary_process_fft:
try: try:
os.killpg(os.getpgid(self.secondary_process_fft.pid), signal.SIGTERM) os.killpg(os.getpgid(self.secondary_process_fft.pid), signal.SIGTERM)
# drain any leftover data to free file descriptors
self.secondary_process_fft.communicate()
self.secondary_process_fft = None
except ProcessLookupError: except ProcessLookupError:
# been killed by something else, ignore # been killed by something else, ignore
pass pass
if self.secondary_process_demod: if self.secondary_process_demod:
try: try:
os.killpg(os.getpgid(self.secondary_process_demod.pid), signal.SIGTERM) os.killpg(os.getpgid(self.secondary_process_demod.pid), signal.SIGTERM)
# drain any leftover data to free file descriptors
self.secondary_process_demod.communicate()
self.secondary_process_demod = None
except ProcessLookupError: except ProcessLookupError:
# been killed by something else, ignore # been killed by something else, ignore
pass pass
@ -426,11 +519,21 @@ class dsp(object):
def get_decimation(self, input_rate, output_rate): def get_decimation(self, input_rate, output_rate):
decimation = 1 decimation = 1
while input_rate / (decimation + 1) >= output_rate: correction = 1
# wideband fm has a much higher frequency deviation (75kHz).
# we cannot cover this if we immediately decimate to the sample rate the audio will have later on, so we need
# to compensate here.
# the factor of 5 is by experimentation only, with a minimum audio rate of 36kHz (enforced by the client)
# this allows us to cover at least +/- 80kHz of frequency spectrum (may be higher, but that's the worst case).
# the correction factor is automatically compensated for by the secondary decimation stage, which comes
# after the demodulator.
if self.get_demodulator() == "wfm":
correction = 5
while input_rate / (decimation + 1) >= output_rate * correction:
decimation += 1 decimation += 1
fraction = float(input_rate / decimation) / output_rate fraction = float(input_rate / decimation) / output_rate
intermediate_rate = input_rate / decimation intermediate_rate = input_rate / decimation
return (decimation, fraction, intermediate_rate) return decimation, fraction, intermediate_rate
def if_samp_rate(self): def if_samp_rate(self):
return self.samp_rate / self.decimation return self.samp_rate / self.decimation
@ -441,11 +544,18 @@ class dsp(object):
def get_output_rate(self): def get_output_rate(self):
return self.output_rate return self.output_rate
def get_hd_output_rate(self):
return self.hd_output_rate
def get_audio_rate(self): def get_audio_rate(self):
if self.isDigitalVoice() or self.isPacket(): if self.isDigitalVoice() or self.isPacket() or self.isPocsag() or self.isDrm():
return 48000 return 48000
elif self.isWsjtMode(): elif self.isWsjtMode() or self.isJs8():
return 12000 return 12000
elif self.isFreeDV():
return 8000
elif self.isHdAudio():
return self.get_hd_output_rate()
return self.get_output_rate() return self.get_output_rate()
def isDigitalVoice(self, demodulator=None): def isDigitalVoice(self, demodulator=None):
@ -458,11 +568,36 @@ class dsp(object):
demodulator = self.get_secondary_demodulator() demodulator = self.get_secondary_demodulator()
return demodulator in ["ft8", "wspr", "jt65", "jt9", "ft4"] return demodulator in ["ft8", "wspr", "jt65", "jt9", "ft4"]
def isJs8(self, demodulator = None):
if demodulator is None:
demodulator = self.get_secondary_demodulator()
return demodulator == "js8"
def isPacket(self, demodulator=None): def isPacket(self, demodulator=None):
if demodulator is None: if demodulator is None:
demodulator = self.get_secondary_demodulator() demodulator = self.get_secondary_demodulator()
return demodulator == "packet" return demodulator == "packet"
def isPocsag(self, demodulator=None):
if demodulator is None:
demodulator = self.get_secondary_demodulator()
return demodulator == "pocsag"
def isFreeDV(self, demodulator=None):
if demodulator is None:
demodulator = self.get_demodulator()
return demodulator == "freedv"
def isHdAudio(self, demodulator=None):
if demodulator is None:
demodulator = self.get_demodulator()
return demodulator == "wfm"
def isDrm(self, demodulator=None):
if demodulator is None:
demodulator = self.get_demodulator()
return demodulator == "drm"
def set_output_rate(self, output_rate): def set_output_rate(self, output_rate):
if self.output_rate == output_rate: if self.output_rate == output_rate:
return return
@ -470,7 +605,16 @@ class dsp(object):
self.calculate_decimation() self.calculate_decimation()
self.restart() self.restart()
def set_hd_output_rate(self, hd_output_rate):
if self.hd_output_rate == hd_output_rate:
return
self.hd_output_rate = hd_output_rate
self.calculate_decimation()
self.restart()
def set_demodulator(self, demodulator): def set_demodulator(self, demodulator):
if demodulator in ["usb", "lsb", "cw"]:
demodulator = "ssb"
if self.demodulator == demodulator: if self.demodulator == demodulator:
return return
self.demodulator = demodulator self.demodulator = demodulator
@ -499,36 +643,39 @@ class dsp(object):
return self.samp_rate / self.fft_fps / self.fft_averages return self.samp_rate / self.fft_fps / self.fft_averages
def set_offset_freq(self, offset_freq): def set_offset_freq(self, offset_freq):
if offset_freq is None:
return
self.offset_freq = offset_freq self.offset_freq = offset_freq
if self.running: if self.running:
self.modification_lock.acquire() self.pipes["shift_pipe"].write("%g\n" % (-float(self.offset_freq) / self.samp_rate))
self.shift_pipe_file.write("%g\n" % (-float(self.offset_freq) / self.samp_rate))
self.shift_pipe_file.flush() def set_center_freq(self, center_freq):
self.modification_lock.release() # dsp only needs to know this to be able to pass it to decoders in the form of get_operating_freq()
self.center_freq = center_freq
def get_operating_freq(self):
return self.center_freq + self.offset_freq
def set_bpf(self, low_cut, high_cut): def set_bpf(self, low_cut, high_cut):
self.low_cut = low_cut self.low_cut = low_cut
self.high_cut = high_cut self.high_cut = high_cut
if self.running: if self.running:
self.modification_lock.acquire() self.pipes["bpf_pipe"].write(
self.bpf_pipe_file.write(
"%g %g\n" % (float(self.low_cut) / self.if_samp_rate(), float(self.high_cut) / self.if_samp_rate()) "%g %g\n" % (float(self.low_cut) / self.if_samp_rate(), float(self.high_cut) / self.if_samp_rate())
) )
self.bpf_pipe_file.flush()
self.modification_lock.release()
def get_bpf(self): def get_bpf(self):
return [self.low_cut, self.high_cut] return [self.low_cut, self.high_cut]
def convertToLinear(self, db):
return float(math.pow(10, db / 10))
def set_squelch_level(self, squelch_level): def set_squelch_level(self, squelch_level):
self.squelch_level = squelch_level self.squelch_level = squelch_level
# no squelch required on digital voice modes # no squelch required on digital voice modes
actual_squelch = 0 if self.isDigitalVoice() or self.isPacket() else self.squelch_level actual_squelch = -150 if self.isDigitalVoice() or self.isPacket() or self.isPocsag() or self.isFreeDV() else self.squelch_level
if self.running: if self.running:
self.modification_lock.acquire() self.pipes["squelch_pipe"].write("%g\n" % (self.convertToLinear(actual_squelch)))
self.squelch_pipe_file.write("%g\n" % (float(actual_squelch)))
self.squelch_pipe_file.flush()
self.modification_lock.release()
def set_unvoiced_quality(self, q): def set_unvoiced_quality(self, q):
self.unvoiced_quality = q self.unvoiced_quality = q
@ -538,39 +685,42 @@ class dsp(object):
return self.unvoiced_quality return self.unvoiced_quality
def set_dmr_filter(self, filter): def set_dmr_filter(self, filter):
if self.dmr_control_pipe_file: if self.has_pipe("dmr_control_pipe"):
self.dmr_control_pipe_file.write("{0}\n".format(filter)) self.pipes["dmr_control_pipe"].write("{0}\n".format(filter))
self.dmr_control_pipe_file.flush()
def mkfifo(self, path): def set_wfm_deemphasis_tau(self, tau):
try: if self.wfm_deemphasis_tau == tau:
os.unlink(path) return
except: self.wfm_deemphasis_tau = tau
pass self.restart()
os.mkfifo(path)
def ddc_transition_bw(self): def ddc_transition_bw(self):
return self.ddc_transition_bw_rate * (self.if_samp_rate() / float(self.samp_rate)) return self.ddc_transition_bw_rate * (self.if_samp_rate() / float(self.samp_rate))
def try_create_pipes(self, pipe_names, command_base): def try_create_pipes(self, pipe_names, command_base):
for pipe_name in pipe_names: for pipe_name, pipe_type in pipe_names.items():
if self.has_pipe(pipe_name):
logger.warning("{pipe_name} is still in use", pipe_name=pipe_name)
self.pipes[pipe_name].close()
if "{" + pipe_name + "}" in command_base: if "{" + pipe_name + "}" in command_base:
setattr(self, pipe_name, self.pipe_base_path + pipe_name) p = self.pipe_base_path + pipe_name
self.mkfifo(getattr(self, pipe_name)) encoding = None
# TODO make digiham output unicode and then change this here
# the whole pipe enoding feature onlye exists because of this
if pipe_name == "meta_pipe":
encoding = "cp437"
self.pipes[pipe_name] = Pipe.create(p, pipe_type, encoding=encoding)
else: else:
setattr(self, pipe_name, None) self.pipes[pipe_name] = None
def has_pipe(self, name):
return name in self.pipes and self.pipes[name] is not None
def try_delete_pipes(self, pipe_names): def try_delete_pipes(self, pipe_names):
for pipe_name in pipe_names: for pipe_name in pipe_names:
pipe_path = getattr(self, pipe_name, None) if self.has_pipe(pipe_name):
if pipe_path: self.pipes[pipe_name].close()
try: self.pipes[pipe_name] = None
os.unlink(pipe_path)
except FileNotFoundError:
# it seems like we keep calling this twice. no idea why, but we don't need the resulting error.
pass
except Exception:
logger.exception("try_delete_pipes()")
def try_create_configs(self, command): def try_create_configs(self, command):
if "{direwolf_config}" in command: if "{direwolf_config}" in command:
@ -597,23 +747,36 @@ class dsp(object):
self.direwolf_config = None self.direwolf_config = None
def start(self): def start(self):
self.modification_lock.acquire() with self.modification_lock:
if self.running: if self.running:
self.modification_lock.release()
return return
self.running = True self.running = True
command_base = " | ".join(self.chain(self.demodulator)) command_base = " | ".join(self.chain(self.demodulator))
# create control pipes for csdr # create control pipes for csdr
self.pipe_base_path = "{tmp_dir}/openwebrx_pipe_{myid}_".format(tmp_dir=self.temporary_directory, myid=id(self))
self.try_create_pipes(self.pipe_names, command_base) self.try_create_pipes(self.pipe_names, command_base)
# send initial config through the pipes
if self.has_pipe("bpf_pipe"):
self.set_bpf(self.low_cut, self.high_cut)
if self.has_pipe("shift_pipe"):
self.set_offset_freq(self.offset_freq)
if self.has_pipe("squelch_pipe"):
self.set_squelch_level(self.squelch_level)
if self.has_pipe("dmr_control_pipe"):
self.set_dmr_filter(3)
# run the command # run the command
command = command_base.format( command = command_base.format(
bpf_pipe=self.bpf_pipe, bpf_pipe=self.pipes["bpf_pipe"],
shift_pipe=self.shift_pipe, shift_pipe=self.pipes["shift_pipe"],
squelch_pipe=self.pipes["squelch_pipe"],
smeter_pipe=self.pipes["smeter_pipe"],
meta_pipe=self.pipes["meta_pipe"],
iqtee_pipe=self.pipes["iqtee_pipe"],
iqtee2_pipe=self.pipes["iqtee2_pipe"],
dmr_control_pipe=self.pipes["dmr_control_pipe"],
decimation=self.decimation, decimation=self.decimation,
last_decimation=self.last_decimation, last_decimation=self.last_decimation,
fft_size=self.fft_size, fft_size=self.fft_size,
@ -624,16 +787,11 @@ class dsp(object):
flowcontrol=int(self.samp_rate * 2), flowcontrol=int(self.samp_rate * 2),
start_bufsize=self.base_bufsize * self.decimation, start_bufsize=self.base_bufsize * self.decimation,
nc_port=self.nc_port, nc_port=self.nc_port,
squelch_pipe=self.squelch_pipe,
smeter_pipe=self.smeter_pipe,
meta_pipe=self.meta_pipe,
iqtee_pipe=self.iqtee_pipe,
iqtee2_pipe=self.iqtee2_pipe,
output_rate=self.get_output_rate(), output_rate=self.get_output_rate(),
smeter_report_every=int(self.if_samp_rate() / 6000), smeter_report_every=int(self.if_samp_rate() / 6000),
unvoiced_quality=self.get_unvoiced_quality(), unvoiced_quality=self.get_unvoiced_quality(),
dmr_control_pipe=self.dmr_control_pipe,
audio_rate=self.get_audio_rate(), audio_rate=self.get_audio_rate(),
wfm_deemphasis_tau=self.wfm_deemphasis_tau,
) )
logger.debug("Command = %s", command) logger.debug("Command = %s", command)
@ -644,7 +802,7 @@ class dsp(object):
my_env["CSDR_PRINT_BUFSIZES"] = "1" my_env["CSDR_PRINT_BUFSIZES"] = "1"
out = subprocess.PIPE if self.output.supports_type("audio") else subprocess.DEVNULL out = subprocess.PIPE if self.output.supports_type("audio") else subprocess.DEVNULL
self.process = subprocess.Popen(command, stdout=out, shell=True, preexec_fn=os.setpgrp, env=my_env) self.process = subprocess.Popen(command, stdout=out, shell=True, start_new_session=True, env=my_env)
def watch_thread(): def watch_thread():
rc = self.process.wait() rc = self.process.wait()
@ -653,52 +811,32 @@ class dsp(object):
logger.debug("restarting since rc = 0, self.running = true, and no modification") logger.debug("restarting since rc = 0, self.running = true, and no modification")
self.restart() self.restart()
threading.Thread(target=watch_thread).start() threading.Thread(target=watch_thread, name="csdr_watch_thread").start()
if self.output.supports_type("audio"): audio_type = "hd_audio" if self.isHdAudio() else "audio"
if self.output.supports_type(audio_type):
self.output.send_output( self.output.send_output(
"audio", audio_type,
partial( partial(
self.process.stdout.read, self.process.stdout.read,
self.get_fft_bytes_to_read() if self.demodulator == "fft" else self.get_audio_bytes_to_read(), self.get_fft_bytes_to_read() if self.demodulator == "fft" else self.get_audio_bytes_to_read(),
), ),
) )
# open control pipes for csdr
if self.bpf_pipe:
self.bpf_pipe_file = open(self.bpf_pipe, "w")
if self.shift_pipe:
self.shift_pipe_file = open(self.shift_pipe, "w")
if self.squelch_pipe:
self.squelch_pipe_file = open(self.squelch_pipe, "w")
self.start_secondary_demodulator() self.start_secondary_demodulator()
self.modification_lock.release() if self.has_pipe("smeter_pipe"):
# send initial config through the pipes
if self.squelch_pipe:
self.set_squelch_level(self.squelch_level)
if self.shift_pipe:
self.set_offset_freq(self.offset_freq)
if self.bpf_pipe:
self.set_bpf(self.low_cut, self.high_cut)
if self.smeter_pipe:
self.smeter_pipe_file = open(self.smeter_pipe, "r")
def read_smeter(): def read_smeter():
raw = self.smeter_pipe_file.readline() raw = self.pipes["smeter_pipe"].readline()
if len(raw) == 0: if len(raw) == 0:
return None return None
else: else:
return float(raw.rstrip("\n")) return float(raw.rstrip("\n"))
self.output.send_output("smeter", read_smeter) self.output.send_output("smeter", read_smeter)
if self.meta_pipe != None: if self.has_pipe("meta_pipe"):
# TODO make digiham output unicode and then change this here
self.meta_pipe_file = open(self.meta_pipe, "r", encoding="cp437")
def read_meta(): def read_meta():
raw = self.meta_pipe_file.readline() raw = self.pipes["meta_pipe"].readline()
if len(raw) == 0: if len(raw) == 0:
return None return None
else: else:
@ -706,15 +844,19 @@ class dsp(object):
self.output.send_output("meta", read_meta) self.output.send_output("meta", read_meta)
if self.dmr_control_pipe: if self.csdr_dynamic_bufsize:
self.dmr_control_pipe_file = open(self.dmr_control_pipe, "w") self.process.stdout.read(8) # dummy read to skip bufsize & preamble
logger.debug("Note: CSDR_DYNAMIC_BUFSIZE_ON = 1")
def stop(self): def stop(self):
self.modification_lock.acquire() with self.modification_lock:
self.running = False self.running = False
if hasattr(self, "process"): if self.process is not None:
try: try:
os.killpg(os.getpgid(self.process.pid), signal.SIGTERM) os.killpg(os.getpgid(self.process.pid), signal.SIGTERM)
# drain any leftover data to free file descriptors
self.process.communicate()
self.process = None
except ProcessLookupError: except ProcessLookupError:
# been killed by something else, ignore # been killed by something else, ignore
pass pass
@ -722,8 +864,6 @@ class dsp(object):
self.try_delete_pipes(self.pipe_names) self.try_delete_pipes(self.pipe_names)
self.modification_lock.release()
def restart(self): def restart(self):
if not self.running: if not self.running:
return return
@ -732,4 +872,3 @@ class dsp(object):
def __del__(self): def __del__(self):
self.stop() self.stop()
del self.process

155
csdr/pipe.py Normal file
View File

@ -0,0 +1,155 @@
import os
import select
import time
import threading
import logging
logger = logging.getLogger(__name__)
class Pipe(object):
READ = "r"
WRITE = "w"
NONE = None
@staticmethod
def create(path, t, encoding=None):
if t == Pipe.READ:
return ReadingPipe(path, encoding=encoding)
elif t == Pipe.WRITE:
return WritingPipe(path, encoding=encoding)
elif t == Pipe.NONE:
return Pipe(path, None, encoding=encoding)
def __init__(self, path, direction, encoding=None):
self.doOpen = True
self.path = "{base}_{myid}".format(base=path, myid=id(self))
self.direction = direction
self.encoding = encoding
self.file = None
os.mkfifo(self.path)
def open(self):
"""
this method opens the file descriptor with an added O_NONBLOCK flag. This gives us a special behaviour for
FIFOS, when they are not opened by the opposing side:
- opening a pipe for writing will throw an OSError with errno = 6 (ENXIO). This is handled specially in the
WritingPipe class.
- opening a pipe for reading will pass through this method instantly, even if the opposing end has not been
opened yet, but the resulting file descriptor will behave as if O_NONBLOCK is set (even if we remove it
immediately here), resulting in empty reads until data is available. This is handled specially in the
ReadingPipe class.
"""
def opener(path, flags):
fd = os.open(path, flags | os.O_NONBLOCK)
os.set_blocking(fd, True)
return fd
self.file = open(self.path, self.direction, encoding=self.encoding, opener=opener)
def close(self):
self.doOpen = False
try:
if self.file is not None:
self.file.close()
os.unlink(self.path)
except FileNotFoundError:
# it seems like we keep calling this twice. no idea why, but we don't need the resulting error.
pass
except Exception:
logger.exception("Pipe.close()")
def __str__(self):
return self.path
class WritingPipe(Pipe):
def __init__(self, path, encoding=None):
self.queue = []
self.queueLock = threading.Lock()
super().__init__(path, "w", encoding=encoding)
self.open()
def open_and_dequeue(self):
"""
This method implements a retry loop that can be interrupted in case the Pipe gets shutdown before actually
being connected.
After the pipe is opened successfully, all data that has been queued is sent in the order it was passed into
write().
"""
retries = 0
while self.file is None and self.doOpen and retries < 10:
try:
super().open()
except OSError as error:
# ENXIO = FIFO has not been opened for reading
if error.errno == 6:
time.sleep(.1)
retries += 1
else:
raise
# if doOpen is false, opening has been canceled, so no warning in that case.
if self.file is None:
if self.doOpen:
logger.warning("could not open FIFO %s", self.path)
return
with self.queueLock:
for i in self.queue:
self.file.write(i)
self.file.flush()
self.queue = None
def open(self):
"""
This sends the opening operation off to a background thread. If we were to block the thread here, another pipe
may be waiting in the queue to be opened on the opposing side, resulting in a deadlock
"""
threading.Thread(target=self.open_and_dequeue, name="csdr_pipe_thread").start()
def write(self, data):
"""
This method queues all data to be written until the file is actually opened. As soon as a file is available,
it becomes a passthrough.
"""
if self.file is None:
with self.queueLock:
self.queue.append(data)
return
r = self.file.write(data)
self.file.flush()
return r
class ReadingPipe(Pipe):
def __init__(self, path, encoding=None):
super().__init__(path, "r", encoding=encoding)
def open(self):
"""
This method implements an interruptible loop that waits for the file descriptor to be opened and the first
batch of data coming in using repeated select() calls.
:return:
"""
if not self.doOpen:
return
super().open()
while self.doOpen:
(read, _, _) = select.select([self.file], [], [], 1)
if self.file in read:
break
def read(self):
if self.file is None:
self.open()
return self.file.read()
def readline(self):
if self.file is None:
self.open()
return self.file.readline()

153
debian/changelog vendored Normal file
View File

@ -0,0 +1,153 @@
openwebrx (0.20.0) buster focal; urgency=low
* Added the ability to sign multiple keys in a single request, thus enabling
multiple users to claim a single receiver on receiverbook.de
* Fixed file descriptor leaks to prevent "too many open files" errors
* Add new demodulator chain for FreeDV
* Added new HD audio streaming mode along with a new WFM demodulator
* Reworked AGC code for better results in AM, SSB and digital modes
* Added support for demodulation of "Digital Radio Mondiale" (DRM) broadcast
using the "dream" decoder.
* New default waterfall color scheme
* Prototype of a continuous automatic waterfall calibration mode
* New devices supported:
- FunCube Dongle Pro+ (`"type": "fcdpp"`)
- Support for connections to rtl_tcp (`"type": "rtl_tcp"`)
-- Jakob Ketterl <jakob.ketterl@gmx.de> Sun, 11 Oct 2020 13:02:00 +0000
openwebrx (0.19.1) buster focal; urgency=low
* Added ability to authenticate receivers with listing sites using
"receiver id" tokens
-- Jakob Ketterl <jakob.ketterl@gmx.de> Sat, 13 Jun 2020 16:46:00 +0000
openwebrx (0.19.0) buster focal; urgency=low
* Fix direwolf connection setup by implementing a retry loop
* Pass direct sampling mode changes for rtl_sdr_soapy to owrx_connector
* OSM maps instead of Google when google_maps_api_key is not set (thanks
@jquagga)
* Improved logic to pass parameters to soapy devices.
- `rtl_sdr_soapy`: added support for `bias_tee`
- `sdrplay`: added support for `bias_tee`, `rf_notch` and `dab_notch`
- `airspy`: added support for `bitpack`
* Added support for Perseus-SDR devices, (thanks @amontefusco)
* Property System has been rewritten so that defaults on sdr behave as
expected
* Waterfall range auto-adjustment now only takes the center 80% of the
spectrum into account, which should work better with SDRs that oversample
or have rather flat filter curves towards the spectrum edges
* Bugfix for negative network usage
* FiFi SDR: prevent arecord from shutting down after 2GB of data has been
sent
* Added support for bias tee control on rtl_sdr devices
* All connector driven SDRs now support `"rf_gain": "auto"` to enable AGC
* `rtl_sdr` type now also supports the `direct_sampling` option
* Added decoding implementation for for digimode "JS8Call" (requires an
installation of js8call and the js8py library)
* Reorganization of the frontend demodulator code
* Improve receiver load time by concatenating javascript assets
* HackRF support is now based on SoapyHackRF
* Removed sdr.hu server listing support since the site has been shut down
* Added support for Radioberry 2 Rasbperry Pi SDR Cape
-- Jakob Ketterl <jakob.ketterl@gmx.de> Mon, 01 Jun 2020 17:02:00 +0000
openwebrx (0.18.0) buster; urgency=low
* Compression, resampling and filtering in the frontend have been rewritten
in javascript, sdr.js has been removed
* Decoding of Pocsag modulation is now possible
* Removed the 3D waterfall since it had no real application and required ~1MB
of javascript code to be downloaded
* Improved the frontend handling of the "too many users" scenario
* PSK63 digimode is now available (same decoding pipeline as PSK31, but with
adopted parameters)
* The frequency can now be manipulated with the mousewheel, which should
allow the user to tune more precise. The tuning step size is determined by
the digit the mouse cursor is hovering over.
* Clicking on the frequency now opens an input for direct frequency selection
* URL hashes have been fixed and improved: They are now updated
automatically, so a shared URL will include frequency and demodulator,
which allows for improved sharing and linking.
* New daylight scheduler for background decoding, allows profiles to be
selected by local sunrise / sunset times
* The owrx_connector is now the default way of communicating with sdr
devices. The old sdr types have been replaced, all `_connector` suffixes on
the type must be removed!
* The sources have been refactored, making it a lot easier to add support for
other devices
* SDR device failure handling has been improved, including user feedback
* New devices supported:
* wsjt-x updated to 2.1.2
* The rtl_tcp compatibility mode of the owrx_connector is now configurable
using the `rtltcp_compat` flag
* explicit device filter for soapy devices for multi-device setups
* compatibility fixes for safari browsers (ios and mac)
* Offset tuning using the `lfo_offset` has been reworked in a way that
`center_freq` has to be set to the frequency you actually want to listen
to. If you're using an `lfo_offset` already, you will probably need to
change its sign.
* `initial_squelch_level` can now be set on each profile.
* Part of the frontend code has been reworked
- Audio buffer minimums have been completely stripped. As a result, you
should get better latency. Unfortunately, this also means there will be
some skipping when audio starts.
- Now also supports AudioWorklets (for those browser that have it).
- Mousewheel controls for the receiver sliders
* Error handling for failed SDR devices
* One of the most-requested features is finally coming to OpenWebRX:
Bookmarks (sometimes also referred to as labels).
There's two kinds of bookmarks available:
- Serverside bookmarks that are set up by the receiver administrator.
Check the file `bookmarks.json` for examples!
- Clientside bookmarks which every user can store for themselves. They are
stored in the browser's localStorage.
* Automatic reporting of spots to [pskreporter](https://pskreporter.info/) is
now possible. Please have a look at the configuration on how to set it up.
* Websocket communication has been overhauled in large parts. It should now
be more reliable, and failing connections should now have no impact on
other users.
* Profile scheduling allows to set up band-hopping if you are running
background services.
* APRS now has the ability to show symbols on the map, if a corresponding
symbol set has been installed. Check the config!
* Debug logging has been disabled in a handful of modules, expect vastly
reduced output on the shell.
* New set of APRS-related features
- Decode Packet transmissions using direwolf (1k2 only for now)
- APRS packets are mostly decoded and shown both in a new panel and on the
map
- APRS is also available as a background service
- direwolfs I-gate functionality can be enabled, which allows your receiver
to work as a receive-only I-gate for the APRS network in the background
* Demodulation for background services has been optimized to use less total
bandwidth, saving CPU
* More metrics have been added; they can be used together with collectd and
its curl_json plugin for now, with some limitations.
* New bandplan feature, the first thing visible is the "dial" indicator that
brings you right to the dial frequency for digital modes
* fixed some bugs in the websocket communication which broke the map
* WSJT-X integration (FT8, FT4, WSPR, JT65, JT9 using wsjt-x demodulators)
* New Map Feature that shows both decoded grid squares from FT8 and Locations
decoded from YSF digital voice
* New Feature report that will show what functionality is available
* major rework on the openwebrx core
* Support of multiple SDR devices simultaneously
* Support for multiple profiles per SDR that allow the user to listen to
different frequencies
* Support for digital voice decoding
* Feature detection that will disable functionality when dependencies are not
available (if you're missing the digital
buttons, this is probably why)
* Support added for the following SDR sources:
- LimeSDR (`"type": "lime_sdr"`)
- PlutoSDR (`"type": "pluto_sdr"`)
- RTL_SDR via Soapy (`"type": "rtl_sdr_soapy"`) on special request to allow
use of the direct sampling mode
- SoapyRemote (`"type": "soapy_remote"`)
- FiFiSDR (`"type": "fifi_sdr"`)
- airspyhf devices (Airspy HF+ / Discovery) (`"type": "airspyhf"`)
-- Jakob Ketterl <jakob.ketterl@gmx.de> Tue, 18 Feb 2020 20:09:00 +0000

1
debian/compat vendored Normal file
View File

@ -0,0 +1 @@
10

16
debian/control vendored Normal file
View File

@ -0,0 +1,16 @@
Source: openwebrx
Maintainer: Jakob Ketterl <jakob.ketterl@gmx.de>
Section: hamradio
Priority: optional
Standards-Version: 4.2.0
Build-Depends: debhelper (>= 11), dh-python, python3-all (>= 3.5), python3-setuptools
Homepage: https://www.openwebrx.de/
Vcs-Browser: https://github.com/jketterl/openwebrx
Vcs-Git: https://github.com/jketterl/openwebrx.git
Package: openwebrx
Architecture: all
Depends: adduser, python3 (>= 3.5), python3-pkg-resources, csdr (>= 0.17), netcat, owrx-connector (>= 0.3), python3-js8py (>= 0.1), ${python3:Depends}, ${misc:Depends}
Recommends: digiham (>= 0.3), dsd (>= 1.7), sox, direwolf (>= 1.4), wsjtx, soapysdr-tools
Description: multi-user web sdr
Open source, multi-user SDR receiver with a web interface

5
debian/openwebrx.install vendored Normal file
View File

@ -0,0 +1,5 @@
config_webrx.py etc/openwebrx/
bands.json etc/openwebrx/
bookmarks.json etc/openwebrx/
users.json etc/openwebrx/
systemd/openwebrx.service lib/systemd/system/

7
debian/postinst vendored Executable file
View File

@ -0,0 +1,7 @@
#!/bin/bash
set -euxo pipefail
adduser --system --group --no-create-home --home /nonexistant openwebrx
usermod -aG plugdev openwebrx
#DEBHELPER#

8
debian/rules vendored Executable file
View File

@ -0,0 +1,8 @@
#!/usr/bin/make -f
export PYBUILD_NAME=openwebrx
%:
dh $@ --with python3 --buildsystem=pybuild --with systemd
override_dh_strip_nondeterminism:
dh_strip_nondeterminism -X.png

1
debian/source/format vendored Normal file
View File

@ -0,0 +1 @@
3.0 (native)

97
docker.sh Executable file
View File

@ -0,0 +1,97 @@
#!/usr/bin/env bash
set -euo pipefail
ARCH=$(uname -m)
IMAGES="openwebrx-rtlsdr openwebrx-sdrplay openwebrx-hackrf openwebrx-airspy openwebrx-rtlsdr-soapy openwebrx-plutosdr openwebrx-limesdr openwebrx-soapyremote openwebrx-perseus openwebrx-fcdpp openwebrx-radioberry openwebrx-uhd openwebrx-redpitaya openwebrx-rtltcp openwebrx-full openwebrx"
ALL_ARCHS="x86_64 armv7l aarch64"
TAG=${TAG:-"latest"}
ARCHTAG="$TAG-$ARCH"
usage () {
echo "Usage: ${0} [command]"
echo "Available commands:"
echo " help Show this usage information"
echo " build Build all docker images"
echo " push Push built docker images to the docker hub"
echo " manifest Compile the docker hub manifest (combines arm and x86 tags into one)"
echo " tag Tag a release"
}
build () {
# build the base images
docker build --pull -t openwebrx-base:${ARCHTAG} -f docker/Dockerfiles/Dockerfile-base .
docker build --build-arg ARCHTAG=${ARCHTAG} -t openwebrx-soapysdr-base:${ARCHTAG} -f docker/Dockerfiles/Dockerfile-soapysdr .
for image in ${IMAGES}; do
i=${image:10}
# "openwebrx" is a special image that gets tag-aliased later on
if [[ ! -z "${i}" ]] ; then
docker build --build-arg ARCHTAG=$ARCHTAG -t jketterl/${image}:${ARCHTAG} -f docker/Dockerfiles/Dockerfile-${i} .
fi
done
# tag openwebrx alias image
docker tag jketterl/openwebrx-full:${ARCHTAG} jketterl/openwebrx:${ARCHTAG}
}
push () {
for image in ${IMAGES}; do
docker push jketterl/$image:$ARCHTAG
done
}
manifest () {
for image in ${IMAGES}; do
# there's no docker manifest rm command, and the create --amend does not work, so we have to clean up manually
rm -rf "${HOME}/.docker/manifests/docker.io_jketterl_${image}-${TAG}"
IMAGE_LIST=""
for a in $ALL_ARCHS; do
IMAGE_LIST="$IMAGE_LIST jketterl/$image:$TAG-$a"
done
docker manifest create jketterl/$image:$TAG $IMAGE_LIST
docker manifest push --purge jketterl/$image:$TAG
done
}
tag () {
if [[ -x ${1:-} || -z ${2:-} ]] ; then
echo "Usage: ${0} tag [SRC_TAG] [TARGET_TAG]"
return
fi
local SRC_TAG=${1}
local TARGET_TAG=${2}
for image in ${IMAGES}; do
# there's no docker manifest rm command, and the create --amend does not work, so we have to clean up manually
rm -rf "${HOME}/.docker/manifests/docker.io_jketterl_${image}-${TARGET_TAG}"
IMAGE_LIST=""
for a in ${ALL_ARCHS}; do
docker pull jketterl/${image}:${SRC_TAG}-${a}
docker tag jketterl/${image}:${SRC_TAG}-${a} jketterl/${image}:${TARGET_TAG}-${a}
docker push jketterl/${image}:${TARGET_TAG}-${a}
IMAGE_LIST="${IMAGE_LIST} jketterl/${image}:${TARGET_TAG}-${a}"
done
docker manifest create jketterl/${image}:${TARGET_TAG} ${IMAGE_LIST}
docker manifest push --purge jketterl/${image}:${TARGET_TAG}
docker pull jketterl/${image}:${TARGET_TAG}
done
}
case ${1:-} in
build)
build
;;
push)
push
;;
manifest)
manifest
;;
tag)
tag ${@:2}
;;
*)
usage
;;
esac

View File

@ -1,6 +1,8 @@
ARG ARCH ARG ARCHTAG
FROM openwebrx-base:$ARCH FROM openwebrx-soapysdr-base:$ARCHTAG
ADD docker/scripts/install-dependencies-airspy.sh / COPY docker/scripts/install-dependencies-airspy.sh /
RUN /install-dependencies-airspy.sh RUN /install-dependencies-airspy.sh &&\
rm /install-dependencies-airspy.sh
ADD . /opt/openwebrx

View File

@ -1,17 +1,23 @@
ARG BASE_IMAGE FROM debian:buster-slim
FROM $BASE_IMAGE
RUN apk add --no-cache bash COPY docker/files/js8call/js8call-hamlib.patch \
docker/files/wsjtx/wsjtx.patch \
docker/files/wsjtx/wsjtx-hamlib.patch \
docker/files/dream/dream.patch \
docker/scripts/install-dependencies.sh /
RUN /install-dependencies.sh && \
rm /install-dependencies.sh && \
rm /*.patch
COPY docker/scripts/install-owrx-tools.sh /
RUN /install-owrx-tools.sh && \
rm /install-owrx-tools.sh
ADD docker/scripts/direwolf-1.5.patch / ENTRYPOINT ["/init"]
ADD docker/scripts/install-dependencies.sh /
RUN /install-dependencies.sh
ADD . /openwebrx WORKDIR /opt/openwebrx
WORKDIR /openwebrx VOLUME /etc/openwebrx
VOLUME /config CMD [ "/opt/openwebrx/docker/scripts/run.sh" ]
ENTRYPOINT [ "/openwebrx/docker/scripts/run.sh" ]
EXPOSE 8073 EXPOSE 8073

View File

@ -0,0 +1,8 @@
ARG ARCHTAG
FROM openwebrx-soapysdr-base:$ARCHTAG
COPY docker/scripts/install-dependencies-fcdpp.sh /
RUN /install-dependencies-fcdpp.sh &&\
rm /install-dependencies-fcdpp.sh
COPY . /opt/openwebrx

View File

@ -1,11 +1,29 @@
ARG ARCH ARG ARCHTAG
FROM openwebrx-base:$ARCH FROM openwebrx-base:$ARCHTAG
ADD docker/scripts/install-dependencies-*.sh / COPY docker/scripts/install-dependencies-*.sh \
ADD docker/scripts/install-lib.*.patch / docker/files/sdrplay/install-lib.*.patch \
docker/scripts/install-connectors.sh /
RUN /install-dependencies-rtlsdr.sh RUN /install-dependencies-rtlsdr.sh &&\
RUN /install-dependencies-hackrf.sh /install-dependencies-soapysdr.sh &&\
RUN /install-dependencies-soapysdr.sh /install-dependencies-hackrf.sh &&\
RUN /install-dependencies-sdrplay.sh /install-dependencies-sdrplay.sh &&\
RUN /install-dependencies-airspy.sh /install-dependencies-airspy.sh &&\
/install-dependencies-rtlsdr-soapy.sh &&\
/install-dependencies-plutosdr.sh &&\
/install-dependencies-limesdr.sh &&\
/install-dependencies-soapyremote.sh &&\
/install-dependencies-perseus.sh &&\
/install-dependencies-fcdpp.sh &&\
/install-dependencies-radioberry.sh &&\
/install-dependencies-uhd.sh &&\
/install-dependencies-redpitaya.sh &&\
/install-connectors.sh &&\
rm /install-dependencies-*.sh &&\
rm /install-lib.*.patch && \
rm /install-connectors.sh
COPY docker/files/services/sdrplay /etc/services.d/sdrplay
ADD . /opt/openwebrx

View File

@ -1,6 +1,8 @@
ARG ARCH ARG ARCHTAG
FROM openwebrx-base:$ARCH FROM openwebrx-soapysdr-base:$ARCHTAG
ADD docker/scripts/install-dependencies-hackrf.sh / COPY docker/scripts/install-dependencies-hackrf.sh /
RUN /install-dependencies-hackrf.sh RUN /install-dependencies-hackrf.sh &&\
rm /install-dependencies-hackrf.sh
COPY . /opt/openwebrx

View File

@ -0,0 +1,8 @@
ARG ARCHTAG
FROM openwebrx-soapysdr-base:$ARCHTAG
COPY docker/scripts/install-dependencies-limesdr.sh /
RUN /install-dependencies-limesdr.sh &&\
rm /install-dependencies-limesdr.sh
COPY . /opt/openwebrx

View File

@ -0,0 +1,8 @@
ARG ARCHTAG
FROM openwebrx-base:$ARCHTAG
COPY docker/scripts/install-dependencies-perseus.sh /
RUN /install-dependencies-perseus.sh &&\
rm /install-dependencies-perseus.sh
COPY . /opt/openwebrx

View File

@ -0,0 +1,8 @@
ARG ARCHTAG
FROM openwebrx-soapysdr-base:$ARCHTAG
COPY docker/scripts/install-dependencies-plutosdr.sh /
RUN /install-dependencies-plutosdr.sh &&\
rm /install-dependencies-plutosdr.sh
COPY . /opt/openwebrx

View File

@ -0,0 +1,8 @@
ARG ARCHTAG
FROM openwebrx-soapysdr-base:$ARCHTAG
COPY docker/scripts/install-dependencies-radioberry.sh /
RUN /install-dependencies-radioberry.sh &&\
rm /install-dependencies-radioberry.sh
COPY . /opt/openwebrx

View File

@ -0,0 +1,8 @@
ARG ARCHTAG
FROM openwebrx-soapysdr-base:$ARCHTAG
COPY docker/scripts/install-dependencies-redpitaya.sh /
RUN /install-dependencies-redpitaya.sh &&\
rm /install-dependencies-redpitaya.sh
COPY . /opt/openwebrx

View File

@ -1,6 +1,12 @@
ARG ARCH ARG ARCHTAG
FROM openwebrx-base:$ARCH FROM openwebrx-base:$ARCHTAG
ADD docker/scripts/install-dependencies-rtlsdr.sh / COPY docker/scripts/install-dependencies-rtlsdr.sh \
RUN /install-dependencies-rtlsdr.sh docker/scripts/install-connectors.sh /
RUN /install-dependencies-rtlsdr.sh &&\
rm /install-dependencies-rtlsdr.sh &&\
/install-connectors.sh &&\
rm /install-connectors.sh
COPY . /opt/openwebrx

View File

@ -0,0 +1,8 @@
ARG ARCHTAG
FROM openwebrx-soapysdr-base:$ARCHTAG
COPY docker/scripts/install-dependencies-rtlsdr-soapy.sh /
RUN /install-dependencies-rtlsdr-soapy.sh &&\
rm /install-dependencies-rtlsdr-soapy.sh
COPY . /opt/openwebrx

View File

@ -0,0 +1,9 @@
ARG ARCHTAG
FROM openwebrx-base:$ARCHTAG
COPY docker/scripts/install-connectors.sh /
RUN /install-connectors.sh &&\
rm /install-connectors.sh
COPY . /opt/openwebrx

View File

@ -1,7 +1,12 @@
ARG ARCH ARG ARCHTAG
FROM openwebrx-soapysdr-base:$ARCH FROM openwebrx-soapysdr-base:$ARCHTAG
ADD docker/scripts/install-dependencies-sdrplay.sh / COPY docker/scripts/install-dependencies-sdrplay.sh \
ADD docker/scripts/install-lib.*.patch / docker/files/sdrplay/install-lib.*.patch /
RUN /install-dependencies-sdrplay.sh RUN /install-dependencies-sdrplay.sh &&\
rm /install-dependencies-sdrplay.sh &&\
rm /install-lib.*.patch
COPY docker/files/services/sdrplay /etc/services.d/sdrplay
COPY . /opt/openwebrx

View File

@ -0,0 +1,8 @@
ARG ARCHTAG
FROM openwebrx-soapysdr-base:$ARCHTAG
COPY docker/scripts/install-dependencies-soapyremote.sh /
RUN /install-dependencies-soapyremote.sh &&\
rm /install-dependencies-soapyremote.sh
COPY . /opt/openwebrx

View File

@ -1,6 +1,9 @@
ARG ARCH ARG ARCHTAG
FROM openwebrx-base:$ARCH FROM openwebrx-base:$ARCHTAG
ADD docker/scripts/install-dependencies-soapysdr.sh /
RUN /install-dependencies-soapysdr.sh
COPY docker/scripts/install-dependencies-soapysdr.sh \
docker/scripts/install-connectors.sh /
RUN /install-dependencies-soapysdr.sh &&\
rm /install-dependencies-soapysdr.sh &&\
/install-connectors.sh &&\
rm /install-connectors.sh

View File

@ -0,0 +1,8 @@
ARG ARCHTAG
FROM openwebrx-soapysdr-base:$ARCHTAG
COPY docker/scripts/install-dependencies-uhd.sh /
RUN /install-dependencies-uhd.sh &&\
rm /install-dependencies-uhd.sh
COPY . /opt/openwebrx

5
docker/env Normal file
View File

@ -0,0 +1,5 @@
ARCH=$(uname -m)
IMAGES="openwebrx-rtlsdr openwebrx-sdrplay openwebrx-hackrf openwebrx-airspy openwebrx-rtlsdr-soapy openwebrx-plutosdr openwebrx-limesdr openwebrx-soapyremote openwebrx-perseus openwebrx-fcdpp openwebrx-radioberry openwebrx-uhd openwebrx-redpitaya openwebrx-rtltcp openwebrx-full openwebrx"
ALL_ARCHS="x86_64 armv7l aarch64"
TAG=${TAG:-"latest"}
ARCHTAG="$TAG-$ARCH"

View File

@ -0,0 +1,96 @@
--- dream.pro.org 2020-09-04 22:51:51.579926191 +0200
+++ dream.pro 2020-09-04 22:52:57.609434707 +0200
@@ -70,9 +70,6 @@
exists(/opt/local/include/speex/speex_preprocess.h) {
CONFIG += speexdsp
}
- exists(/opt/local/include/hamlib/rig.h) {
- CONFIG += hamlib
- }
contains(QT_VERSION, ^4\\.7.*) {
QT += phonon opengl svg
DEFINES -= QWT_NO_SVG
@@ -138,12 +135,6 @@
packagesExist(sndfile) {
CONFIG += sndfile
}
- packagesExist(hamlib) {
- CONFIG += hamlib
- }
- packagesExist(gpsd) {
- CONFIG += gps
- }
packagesExist(pcap) {
CONFIG += pcap
}
@@ -159,14 +150,6 @@
exists(/usr/local/include/sndfile.h) {
CONFIG += sndfile
}
- exists(/usr/include/hamlib/rig.h) | \
- exists(/usr/local/include/hamlib/rig.h) {
- CONFIG += hamlib
- }
- exists(/usr/include/gps.h) | \
- exists(/usr/local/include/gps.h) {
- CONFIG += gps
- }
exists(/usr/include/pcap.h) | \
exists(/usr/local/include/pcap.h) {
CONFIG += pcap
@@ -194,9 +177,6 @@
exists($$OUT_PWD/include/speex/speex_preprocess.h) {
CONFIG += speexdsp
}
- exists($$OUT_PWD/include/hamlib/rig.h) {
- CONFIG += hamlib
- }
exists($$OUT_PWD/include/pcap.h) {
CONFIG += pcap
}
@@ -225,7 +205,7 @@
LIBS += -lz
}
}
-exists($$OUT_PWD/include/neaacdec.h) {
+exists(/usr/include/neaacdec.h) {
DEFINES += HAVE_LIBFAAD \
USE_FAAD2_LIBRARY
LIBS += -lfaad_drm
@@ -257,11 +237,6 @@
win32:LIBS += libspeexdsp.lib
message("with libspeexdsp")
}
-gps {
- DEFINES += HAVE_LIBGPS
- unix:LIBS += -lgps
- message("with gps")
-}
pcap {
DEFINES += HAVE_LIBPCAP
unix:LIBS += -lpcap
@@ -269,24 +244,6 @@
win32-g++:LIBS += -lwpcap -lpacket
message("with pcap")
}
-hamlib {
- DEFINES += HAVE_LIBHAMLIB
- macx:LIBS += -framework IOKit
- unix:LIBS += -lhamlib
- win32:LIBS += libhamlib-2.lib
- HEADERS += src/util/Hamlib.h
- SOURCES += src/util/Hamlib.cpp
- qt {
- HEADERS += src/util-QT/Rig.h
- SOURCES += src/util-QT/Rig.cpp
- }
- gui {
- HEADERS += src/GUI-QT/RigDlg.h
- SOURCES += src/GUI-QT/RigDlg.cpp
- FORMS += RigDlg.ui
- }
- message("with hamlib")
-}
qwt {
DEFINES += QWT_NO_SVG
macx {

View File

@ -0,0 +1,151 @@
diff -ur js8call-orig/CMake/Modules/Findhamlib.cmake js8call/CMake/Modules/Findhamlib.cmake
--- js8call-orig/CMake/Modules/Findhamlib.cmake 2020-07-22 18:14:18.014499840 +0200
+++ js8call/CMake/Modules/Findhamlib.cmake 2020-07-22 18:16:07.200375473 +0200
@@ -78,4 +78,4 @@
# Handle the QUIETLY and REQUIRED arguments and set HAMLIB_FOUND to
# TRUE if all listed variables are TRUE
include (FindPackageHandleStandardArgs)
-find_package_handle_standard_args (hamlib DEFAULT_MSG hamlib_INCLUDE_DIRS hamlib_LIBRARIES hamlib_LIBRARY_DIRS)
+find_package_handle_standard_args (hamlib DEFAULT_MSG hamlib_INCLUDE_DIRS hamlib_LIBRARIES)
diff -ur js8call-orig/CMakeLists.txt js8call/CMakeLists.txt
--- js8call-orig/CMakeLists.txt 2020-07-22 18:14:18.014499840 +0200
+++ js8call/CMakeLists.txt 2020-07-22 18:17:55.629633825 +0200
@@ -558,7 +558,7 @@
#
# libhamlib setup
#
-set (hamlib_STATIC 1)
+set (hamlib_STATIC 0)
find_package (hamlib 3 REQUIRED)
find_program (RIGCTL_EXE rigctl)
find_program (RIGCTLD_EXE rigctld)
@@ -911,56 +911,6 @@
target_link_libraries (js8 wsjt_fort wsjt_cxx Qt5::Core)
endif (${OPENMP_FOUND} OR APPLE)
-# build the main application
-add_executable (js8call MACOSX_BUNDLE
- ${sqlite3_CSRCS}
- ${wsjtx_CXXSRCS}
- ${wsjtx_GENUISRCS}
- wsjtx.rc
- ${WSJTX_ICON_FILE}
- ${wsjtx_RESOURCES_RCC}
- images.qrc
- )
-
-if (WSJT_CREATE_WINMAIN)
- set_target_properties (js8call PROPERTIES WIN32_EXECUTABLE ON)
-endif (WSJT_CREATE_WINMAIN)
-
-set_target_properties (js8call PROPERTIES
- MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Darwin/Info.plist.in"
- MACOSX_BUNDLE_INFO_STRING "${WSJTX_DESCRIPTION_SUMMARY}"
- MACOSX_BUNDLE_ICON_FILE "${WSJTX_ICON_FILE}"
- MACOSX_BUNDLE_BUNDLE_VERSION ${wsjtx_VERSION}
- MACOSX_BUNDLE_SHORT_VERSION_STRING "v${wsjtx_VERSION}"
- MACOSX_BUNDLE_LONG_VERSION_STRING "Version ${wsjtx_VERSION}"
- MACOSX_BUNDLE_BUNDLE_NAME "${PROJECT_NAME}"
- MACOSX_BUNDLE_BUNDLE_EXECUTABLE_NAME "${PROJECT_NAME}"
- MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT}"
- MACOSX_BUNDLE_GUI_IDENTIFIER "org.kn4crd.js8call"
- )
-
-target_include_directories (js8call PRIVATE ${FFTW3_INCLUDE_DIRS})
-if (APPLE)
- target_link_libraries (js8call wsjt_fort wsjt_cxx wsjt_qt wsjt_qtmm ${hamlib_LIBRARIES} ${FFTW3_LIBRARIES})
-else ()
- target_link_libraries (js8call wsjt_fort_omp wsjt_cxx wsjt_qt wsjt_qtmm ${hamlib_LIBRARIES} ${FFTW3_LIBRARIES})
- if (OpenMP_C_FLAGS)
- set_target_properties (js8call PROPERTIES
- COMPILE_FLAGS "${OpenMP_C_FLAGS}"
- LINK_FLAGS "${OpenMP_C_FLAGS}"
- )
- endif ()
- set_target_properties (js8call PROPERTIES
- Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/fortran_modules_omp
- )
- if (WIN32)
- set_target_properties (js8call PROPERTIES
- LINK_FLAGS -Wl,--stack,16777216
- )
- endif ()
-endif ()
-qt5_use_modules (js8call SerialPort) # not sure why the interface link library syntax above doesn't work
-
# if (UNIX)
# if (NOT WSJT_SKIP_MANPAGES)
# add_subdirectory (manpages)
@@ -976,38 +926,10 @@
#
# installation
#
-install (TARGETS js8call
- RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
- BUNDLE DESTINATION . COMPONENT runtime
- )
-
install (TARGETS js8 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
)
-install (PROGRAMS
- ${RIGCTL_EXE}
- DESTINATION ${CMAKE_INSTALL_BINDIR}
- #COMPONENT runtime
- RENAME rigctl-local${CMAKE_EXECUTABLE_SUFFIX}
- )
-
-install (PROGRAMS
- ${RIGCTLD_EXE}
- DESTINATION ${CMAKE_INSTALL_BINDIR}
- #COMPONENT runtime
- RENAME rigctld-local${CMAKE_EXECUTABLE_SUFFIX}
- )
-
-install (FILES
- README
- COPYING
- INSTALL
- INSTALL-WSJTX
- DESTINATION ${CMAKE_INSTALL_DOCDIR}
- #COMPONENT runtime
- )
-
install (FILES
contrib/Ephemeris/JPLEPH
DESTINATION ${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}
@@ -1061,32 +983,6 @@
"${CMAKE_CURRENT_BINARY_DIR}/wsjtx_config.h"
)
-
-if (NOT WIN32 AND NOT APPLE)
- # install a desktop file so js8call appears in the application start
- # menu with an icon
- install (
- FILES js8call.desktop
- DESTINATION /usr/share/applications
- #COMPONENT runtime
- )
- install (
- FILES icons/Unix/js8call_icon.png
- DESTINATION /usr/share/pixmaps
- #COMPONENT runtime
- )
-
- IF("${CMAKE_INSTALL_PREFIX}" STREQUAL "/opt/js8call")
- execute_process(COMMAND ln -s /opt/js8call/bin/js8call ljs8call)
-
- install(FILES
- ${CMAKE_BINARY_DIR}/ljs8call DESTINATION /usr/bin/ RENAME js8call
- #COMPONENT runtime
- )
- endif()
-endif (NOT WIN32 AND NOT APPLE)
-
-
#
# bundle fixup only done in Release or MinSizeRel configurations
#
Only in js8call/: .idea

View File

@ -0,0 +1,23 @@
diff -ur sdrplay-orig/install_lib.sh sdrplay/install_lib.sh
--- sdrplay-orig/install_lib.sh 2020-05-24 14:30:06.022483867 +0000
+++ sdrplay/install_lib.sh 2020-05-24 14:30:49.093435726 +0000
@@ -4,19 +4,6 @@
export MAJVERS="3"
echo "Installing SDRplay RSP API library ${VERS}..."
-read -p "Press RETURN to view the license agreement" ret
-
-more sdrplay_license.txt
-
-while true; do
- echo "Press y and RETURN to accept the license agreement and continue with"
- read -p "the installation, or press n and RETURN to exit the installer [y/n] " yn
- case $yn in
- [Yy]* ) break;;
- [Nn]* ) exit;;
- * ) echo "Please answer y or n";;
- esac
-done
export ARCH=`uname -m`

View File

@ -0,0 +1,40 @@
diff -ur sdrplay-orig/install_lib.sh sdrplay/install_lib.sh
--- sdrplay-orig/install_lib.sh 2020-05-24 14:13:04.561271707 +0000
+++ sdrplay/install_lib.sh 2020-05-24 14:16:20.068329040 +0000
@@ -4,19 +4,6 @@
MAJVERS="3"
echo "Installing SDRplay RSP API library ${VERS}..."
-read -p "Press RETURN to view the license agreement" ret
-
-more sdrplay_license.txt
-
-while true; do
- echo "Press y and RETURN to accept the license agreement and continue with"
- read -p "the installation, or press n and RETURN to exit the installer [y/n] " yn
- case $yn in
- [Yy]* ) break;;
- [Nn]* ) exit;;
- * ) echo "Please answer y or n";;
- esac
-done
ARCH=`uname -m`
@@ -141,16 +128,6 @@
echo "SDRplay API ${VERS} Installation Finished"
echo " "
-while true; do
- echo "Would you like to add SDRplay USB IDs to the local database for easier
-"
- read -p "identification in applications such as lsusb? [y/n] " yn
- case $yn in
- [Yy]* ) break;;
- [Nn]* ) exit;;
- * ) echo "Please answer y or n";;
- esac
-done
sudo cp scripts/sdrplay_usbids.sh ${INSTALLBINDIR}/.
sudo chmod 755 ${INSTALLBINDIR}/sdrplay_usbids.sh
sudo cp scripts/sdrplay_ids.txt ${INSTALLBINDIR}/.

View File

@ -0,0 +1,39 @@
diff -ur sdrplay-orig/install_lib.sh sdrplay/install_lib.sh
--- sdrplay-orig/install_lib.sh 2020-05-24 13:56:56.622000041 +0000
+++ sdrplay/install_lib.sh 2020-05-24 13:58:51.837801559 +0000
@@ -4,19 +4,6 @@
MAJVERS="3"
echo "Installing SDRplay RSP API library ${VERS}..."
-read -p "Press RETURN to view the license agreement" ret
-
-more sdrplay_license.txt
-
-while true; do
- echo "Press y and RETURN to accept the license agreement and continue with"
- read -p "the installation, or press n and RETURN to exit the installer [y/n] " yn
- case $yn in
- [Yy]* ) break;;
- [Nn]* ) exit;;
- * ) echo "Please answer y or n";;
- esac
-done
ARCH=`uname -m`
OSDIST="Unknown"
@@ -157,15 +144,6 @@
echo " "
echo "SDRplay API ${VERS} Installation Finished"
echo " "
-while true; do
- echo "Would you like to add SDRplay USB IDs to the local database for easier"
- read -p "identification in applications such as lsusb? [y/n] " yn
- case $yn in
- [Yy]* ) break;;
- [Nn]* ) exit;;
- * ) echo "Please answer y or n";;
- esac
-done
sudo cp scripts/sdrplay_usbids.sh ${INSTALLBINDIR}/.
sudo chmod 755 ${INSTALLBINDIR}/sdrplay_usbids.sh
sudo cp scripts/sdrplay_ids.txt ${INSTALLBINDIR}/.

View File

@ -0,0 +1,2 @@
#!/usr/bin/execlineb -P
/usr/local/bin/sdrplay_apiService

View File

@ -0,0 +1,43 @@
--- CMakeLists.txt.orig 2020-07-21 20:59:55.982026645 +0200
+++ CMakeLists.txt 2020-07-21 21:01:25.444836112 +0200
@@ -80,24 +80,6 @@
include (ExternalProject)
-
-#
-# build and install hamlib locally so it can be referenced by the
-# WSJT-X build
-#
-ExternalProject_Add (hamlib
- GIT_REPOSITORY ${hamlib_repo}
- GIT_TAG ${hamlib_TAG}
- URL ${CMAKE_CURRENT_SOURCE_DIR}/src/${__hamlib_upstream}
- URL_HASH MD5=${hamlib_md5sum}
- #UPDATE_COMMAND ${CMAKE_COMMAND} -E env "[ -f ./bootstrap ] && ./bootstrap"
- PATCH_COMMAND ${PATCH_EXECUTABLE} -p1 -N < ${CMAKE_CURRENT_SOURCE_DIR}/hamlib.patch
- CONFIGURE_COMMAND <SOURCE_DIR>/configure --prefix=<INSTALL_DIR> --disable-shared --enable-static --without-cxx-binding ${EXTRA_FLAGS} # LIBUSB_LIBS=${USB_LIBRARY}
- BUILD_COMMAND $(MAKE) all V=1 # $(MAKE) is ExternalProject_Add() magic to do recursive make
- INSTALL_COMMAND $(MAKE) install-strip V=1 DESTDIR=""
- STEP_TARGETS update install
- )
-
#
# custom target to make a hamlib source tarball
#
@@ -136,7 +118,6 @@
# build and optionally install WSJT-X using the hamlib package built
# above
#
-ExternalProject_Get_Property (hamlib INSTALL_DIR)
ExternalProject_Add (wsjtx
GIT_REPOSITORY ${wsjtx_repo}
GIT_TAG ${WSJTX_TAG}
@@ -160,7 +141,6 @@
DEPENDEES build
)
-set_target_properties (hamlib PROPERTIES EXCLUDE_FROM_ALL 1)
set_target_properties (wsjtx PROPERTIES EXCLUDE_FROM_ALL 1)
add_dependencies (wsjtx-configure hamlib-install)

View File

@ -0,0 +1,155 @@
diff -ur wsjtx-orig/CMake/Modules/Findhamlib.cmake wsjtx/CMake/Modules/Findhamlib.cmake
--- wsjtx-orig/CMake/Modules/Findhamlib.cmake 2020-07-21 21:10:43.124810140 +0200
+++ wsjtx/CMake/Modules/Findhamlib.cmake 2020-07-21 21:11:03.368019114 +0200
@@ -85,4 +85,4 @@
# Handle the QUIETLY and REQUIRED arguments and set HAMLIB_FOUND to
# TRUE if all listed variables are TRUE
include (FindPackageHandleStandardArgs)
-find_package_handle_standard_args (hamlib DEFAULT_MSG hamlib_INCLUDE_DIRS hamlib_LIBRARIES hamlib_LIBRARY_DIRS)
+find_package_handle_standard_args (hamlib DEFAULT_MSG hamlib_INCLUDE_DIRS hamlib_LIBRARIES)
diff -ur wsjtx-orig/CMakeLists.txt wsjtx/CMakeLists.txt
--- wsjtx-orig/CMakeLists.txt 2020-07-21 21:10:43.124810140 +0200
+++ wsjtx/CMakeLists.txt 2020-07-21 22:14:04.454639589 +0200
@@ -871,7 +871,7 @@
#
# libhamlib setup
#
-set (hamlib_STATIC 1)
+set (hamlib_STATIC 0)
find_package (hamlib 3 REQUIRED)
find_program (RIGCTL_EXE rigctl)
find_program (RIGCTLD_EXE rigctld)
@@ -1348,53 +1348,10 @@
endif(WSJT_BUILD_UTILS)
-# build the main application
-add_executable (wsjtx MACOSX_BUNDLE
- ${wsjtx_CXXSRCS}
- ${wsjtx_GENUISRCS}
- wsjtx.rc
- ${WSJTX_ICON_FILE}
- ${wsjtx_RESOURCES_RCC}
- )
-
if (WSJT_CREATE_WINMAIN)
set_target_properties (wsjtx PROPERTIES WIN32_EXECUTABLE ON)
endif (WSJT_CREATE_WINMAIN)
-set_target_properties (wsjtx PROPERTIES
- MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Darwin/Info.plist.in"
- MACOSX_BUNDLE_INFO_STRING "${WSJTX_DESCRIPTION_SUMMARY}"
- MACOSX_BUNDLE_ICON_FILE "${WSJTX_ICON_FILE}"
- MACOSX_BUNDLE_BUNDLE_VERSION ${wsjtx_VERSION}
- MACOSX_BUNDLE_SHORT_VERSION_STRING "v${wsjtx_VERSION}"
- MACOSX_BUNDLE_LONG_VERSION_STRING "Version ${wsjtx_VERSION}"
- MACOSX_BUNDLE_BUNDLE_NAME "${PROJECT_NAME}"
- MACOSX_BUNDLE_BUNDLE_EXECUTABLE_NAME "${PROJECT_NAME}"
- MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT}"
- MACOSX_BUNDLE_GUI_IDENTIFIER "org.k1jt.wsjtx"
- )
-
-target_include_directories (wsjtx PRIVATE ${FFTW3_INCLUDE_DIRS})
-if (APPLE)
- target_link_libraries (wsjtx Qt5::SerialPort wsjt_fort wsjt_cxx wsjt_qt wsjt_qtmm ${hamlib_LIBRARIES} ${FFTW3_LIBRARIES})
-else ()
- target_link_libraries (wsjtx Qt5::SerialPort wsjt_fort_omp wsjt_cxx wsjt_qt wsjt_qtmm ${hamlib_LIBRARIES} ${FFTW3_LIBRARIES})
- if (OpenMP_C_FLAGS)
- set_target_properties (wsjtx PROPERTIES
- COMPILE_FLAGS "${OpenMP_C_FLAGS}"
- LINK_FLAGS "${OpenMP_C_FLAGS}"
- )
- endif ()
- set_target_properties (wsjtx PROPERTIES
- Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/fortran_modules_omp
- )
- if (WIN32)
- set_target_properties (wsjtx PROPERTIES
- LINK_FLAGS -Wl,--stack,16777216
- )
- endif ()
-endif ()
-
# make a library for WSJT-X UDP servers
# add_library (wsjtx_udp SHARED ${UDP_library_CXXSRCS})
add_library (wsjtx_udp-static STATIC ${UDP_library_CXXSRCS})
@@ -1437,24 +1394,9 @@
set_target_properties (message_aggregator PROPERTIES WIN32_EXECUTABLE ON)
endif (WSJT_CREATE_WINMAIN)
-if (UNIX)
- if (NOT WSJT_SKIP_MANPAGES)
- add_subdirectory (manpages)
- add_dependencies (wsjtx manpages)
- endif (NOT WSJT_SKIP_MANPAGES)
- if (NOT APPLE)
- add_subdirectory (debian)
- add_dependencies (wsjtx debian)
- endif (NOT APPLE)
-endif (UNIX)
-
#
# installation
#
-install (TARGETS wsjtx
- RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
- BUNDLE DESTINATION . COMPONENT runtime
- )
# install (TARGETS wsjtx_udp EXPORT udp
# RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
@@ -1473,12 +1415,7 @@
# DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/wsjtx
# )
-install (TARGETS udp_daemon message_aggregator
- RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
- BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
- )
-
-install (TARGETS jt9 wsprd fmtave fcal fmeasure
+install (TARGETS jt9 wsprd
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
)
@@ -1491,39 +1428,6 @@
)
endif(WSJT_BUILD_UTILS)
-install (PROGRAMS
- ${RIGCTL_EXE}
- DESTINATION ${CMAKE_INSTALL_BINDIR}
- #COMPONENT runtime
- RENAME rigctl-wsjtx${CMAKE_EXECUTABLE_SUFFIX}
- )
-
-install (PROGRAMS
- ${RIGCTLD_EXE}
- DESTINATION ${CMAKE_INSTALL_BINDIR}
- #COMPONENT runtime
- RENAME rigctld-wsjtx${CMAKE_EXECUTABLE_SUFFIX}
- )
-
-install (PROGRAMS
- ${RIGCTLCOM_EXE}
- DESTINATION ${CMAKE_INSTALL_BINDIR}
- #COMPONENT runtime
- RENAME rigctlcom-wsjtx${CMAKE_EXECUTABLE_SUFFIX}
- )
-
-install (FILES
- README
- COPYING
- AUTHORS
- THANKS
- NEWS
- INSTALL
- BUGS
- DESTINATION ${CMAKE_INSTALL_DOCDIR}
- #COMPONENT runtime
- )
-
install (FILES
contrib/Ephemeris/JPLEPH
DESTINATION ${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}
Only in wsjtx: .idea

View File

@ -1,241 +0,0 @@
diff --git a/Makefile.linux b/Makefile.linux
index 5010833..3f61de9 100644
--- a/Makefile.linux
+++ b/Makefile.linux
@@ -585,102 +585,102 @@ install : $(APPS) direwolf.conf tocalls.txt symbols-new.txt symbolsX.txt dw-icon
# Applications, not installed with package manager, normally go in /usr/local/bin.
# /usr/bin is used instead when installing from .DEB or .RPM package.
#
- $(INSTALL) -D --mode=755 direwolf $(DESTDIR)/bin/direwolf
- $(INSTALL) -D --mode=755 decode_aprs $(DESTDIR)/bin/decode_aprs
- $(INSTALL) -D --mode=755 text2tt $(DESTDIR)/bin/text2tt
- $(INSTALL) -D --mode=755 tt2text $(DESTDIR)/bin/tt2text
- $(INSTALL) -D --mode=755 ll2utm $(DESTDIR)/bin/ll2utm
- $(INSTALL) -D --mode=755 utm2ll $(DESTDIR)/bin/utm2ll
- $(INSTALL) -D --mode=755 aclients $(DESTDIR)/bin/aclients
- $(INSTALL) -D --mode=755 log2gpx $(DESTDIR)/bin/log2gpx
- $(INSTALL) -D --mode=755 gen_packets $(DESTDIR)/bin/gen_packets
- $(INSTALL) -D --mode=755 atest $(DESTDIR)/bin/atest
- $(INSTALL) -D --mode=755 ttcalc $(DESTDIR)/bin/ttcalc
- $(INSTALL) -D --mode=755 kissutil $(DESTDIR)/bin/kissutil
- $(INSTALL) -D --mode=755 cm108 $(DESTDIR)/bin/cm108
- $(INSTALL) -D --mode=755 dwespeak.sh $(DESTDIR)/bin/dwspeak.sh
+ $(INSTALL) -D -m=755 direwolf $(DESTDIR)/bin/direwolf
+ $(INSTALL) -D -m=755 decode_aprs $(DESTDIR)/bin/decode_aprs
+ $(INSTALL) -D -m=755 text2tt $(DESTDIR)/bin/text2tt
+ $(INSTALL) -D -m=755 tt2text $(DESTDIR)/bin/tt2text
+ $(INSTALL) -D -m=755 ll2utm $(DESTDIR)/bin/ll2utm
+ $(INSTALL) -D -m=755 utm2ll $(DESTDIR)/bin/utm2ll
+ $(INSTALL) -D -m=755 aclients $(DESTDIR)/bin/aclients
+ $(INSTALL) -D -m=755 log2gpx $(DESTDIR)/bin/log2gpx
+ $(INSTALL) -D -m=755 gen_packets $(DESTDIR)/bin/gen_packets
+ $(INSTALL) -D -m=755 atest $(DESTDIR)/bin/atest
+ $(INSTALL) -D -m=755 ttcalc $(DESTDIR)/bin/ttcalc
+ $(INSTALL) -D -m=755 kissutil $(DESTDIR)/bin/kissutil
+ $(INSTALL) -D -m=755 cm108 $(DESTDIR)/bin/cm108
+ $(INSTALL) -D -m=755 dwespeak.sh $(DESTDIR)/bin/dwspeak.sh
#
# Telemetry Toolkit executables. Other .conf and .txt files will go into doc directory.
#
- $(INSTALL) -D --mode=755 telemetry-toolkit/telem-balloon.pl $(DESTDIR)/bin/telem-balloon.pl
- $(INSTALL) -D --mode=755 telemetry-toolkit/telem-bits.pl $(DESTDIR)/bin/telem-bits.pl
- $(INSTALL) -D --mode=755 telemetry-toolkit/telem-data.pl $(DESTDIR)/bin/telem-data.pl
- $(INSTALL) -D --mode=755 telemetry-toolkit/telem-data91.pl $(DESTDIR)/bin/telem-data91.pl
- $(INSTALL) -D --mode=755 telemetry-toolkit/telem-eqns.pl $(DESTDIR)/bin/telem-eqns.pl
- $(INSTALL) -D --mode=755 telemetry-toolkit/telem-parm.pl $(DESTDIR)/bin/telem-parm.pl
- $(INSTALL) -D --mode=755 telemetry-toolkit/telem-seq.sh $(DESTDIR)/bin/telem-seq.sh
- $(INSTALL) -D --mode=755 telemetry-toolkit/telem-unit.pl $(DESTDIR)/bin/telem-unit.pl
- $(INSTALL) -D --mode=755 telemetry-toolkit/telem-volts.py $(DESTDIR)/bin/telem-volts.py
+ $(INSTALL) -D -m=755 telemetry-toolkit/telem-balloon.pl $(DESTDIR)/bin/telem-balloon.pl
+ $(INSTALL) -D -m=755 telemetry-toolkit/telem-bits.pl $(DESTDIR)/bin/telem-bits.pl
+ $(INSTALL) -D -m=755 telemetry-toolkit/telem-data.pl $(DESTDIR)/bin/telem-data.pl
+ $(INSTALL) -D -m=755 telemetry-toolkit/telem-data91.pl $(DESTDIR)/bin/telem-data91.pl
+ $(INSTALL) -D -m=755 telemetry-toolkit/telem-eqns.pl $(DESTDIR)/bin/telem-eqns.pl
+ $(INSTALL) -D -m=755 telemetry-toolkit/telem-parm.pl $(DESTDIR)/bin/telem-parm.pl
+ $(INSTALL) -D -m=755 telemetry-toolkit/telem-seq.sh $(DESTDIR)/bin/telem-seq.sh
+ $(INSTALL) -D -m=755 telemetry-toolkit/telem-unit.pl $(DESTDIR)/bin/telem-unit.pl
+ $(INSTALL) -D -m=755 telemetry-toolkit/telem-volts.py $(DESTDIR)/bin/telem-volts.py
#
# Misc. data such as "tocall" to system mapping.
#
- $(INSTALL) -D --mode=644 tocalls.txt $(DESTDIR)/share/direwolf/tocalls.txt
- $(INSTALL) -D --mode=644 symbols-new.txt $(DESTDIR)/share/direwolf/symbols-new.txt
- $(INSTALL) -D --mode=644 symbolsX.txt $(DESTDIR)/share/direwolf/symbolsX.txt
+ $(INSTALL) -D -m=644 tocalls.txt $(DESTDIR)/share/direwolf/tocalls.txt
+ $(INSTALL) -D -m=644 symbols-new.txt $(DESTDIR)/share/direwolf/symbols-new.txt
+ $(INSTALL) -D -m=644 symbolsX.txt $(DESTDIR)/share/direwolf/symbolsX.txt
#
# For desktop icon.
#
- $(INSTALL) -D --mode=644 dw-icon.png $(DESTDIR)/share/direwolf/pixmaps/dw-icon.png
- $(INSTALL) -D --mode=644 direwolf.desktop $(DESTDIR)/share/applications/direwolf.desktop
+ $(INSTALL) -D -m=644 dw-icon.png $(DESTDIR)/share/direwolf/pixmaps/dw-icon.png
+ $(INSTALL) -D -m=644 direwolf.desktop $(DESTDIR)/share/applications/direwolf.desktop
#
# Documentation. Various plain text files and PDF.
#
- $(INSTALL) -D --mode=644 CHANGES.md $(DESTDIR)/share/doc/direwolf/CHANGES.md
- $(INSTALL) -D --mode=644 LICENSE-dire-wolf.txt $(DESTDIR)/share/doc/direwolf/LICENSE-dire-wolf.txt
- $(INSTALL) -D --mode=644 LICENSE-other.txt $(DESTDIR)/share/doc/direwolf/LICENSE-other.txt
+ $(INSTALL) -D -m=644 CHANGES.md $(DESTDIR)/share/doc/direwolf/CHANGES.md
+ $(INSTALL) -D -m=644 LICENSE-dire-wolf.txt $(DESTDIR)/share/doc/direwolf/LICENSE-dire-wolf.txt
+ $(INSTALL) -D -m=644 LICENSE-other.txt $(DESTDIR)/share/doc/direwolf/LICENSE-other.txt
#
# ./README.md is an overview for the project main page.
# Maybe we could stick it in some other place.
# doc/README.md contains an overview of the PDF file contents and is more useful here.
#
- $(INSTALL) -D --mode=644 doc/README.md $(DESTDIR)/share/doc/direwolf/README.md
- $(INSTALL) -D --mode=644 doc/2400-4800-PSK-for-APRS-Packet-Radio.pdf $(DESTDIR)/share/doc/direwolf/2400-4800-PSK-for-APRS-Packet-Radio.pdf
- $(INSTALL) -D --mode=644 doc/A-Better-APRS-Packet-Demodulator-Part-1-1200-baud.pdf $(DESTDIR)/share/doc/direwolf/A-Better-APRS-Packet-Demodulator-Part-1-1200-baud.pdf
- $(INSTALL) -D --mode=644 doc/A-Better-APRS-Packet-Demodulator-Part-2-9600-baud.pdf $(DESTDIR)/share/doc/direwolf/A-Better-APRS-Packet-Demodulator-Part-2-9600-baud.pdf
- $(INSTALL) -D --mode=644 doc/A-Closer-Look-at-the-WA8LMF-TNC-Test-CD.pdf $(DESTDIR)/share/doc/direwolf/A-Closer-Look-at-the-WA8LMF-TNC-Test-CD.pdf
- $(INSTALL) -D --mode=644 doc/APRS-Telemetry-Toolkit.pdf $(DESTDIR)/share/doc/direwolf/APRS-Telemetry-Toolkit.pdf
- $(INSTALL) -D --mode=644 doc/APRStt-Implementation-Notes.pdf $(DESTDIR)/share/doc/direwolf/APRStt-Implementation-Notes.pdf
- $(INSTALL) -D --mode=644 doc/APRStt-interface-for-SARTrack.pdf $(DESTDIR)/share/doc/direwolf/APRStt-interface-for-SARTrack.pdf
- $(INSTALL) -D --mode=644 doc/APRStt-Listening-Example.pdf $(DESTDIR)/share/doc/direwolf/APRStt-Listening-Example.pdf
- $(INSTALL) -D --mode=644 doc/Bluetooth-KISS-TNC.pdf $(DESTDIR)/share/doc/direwolf/Bluetooth-KISS-TNC.pdf
- $(INSTALL) -D --mode=644 doc/Going-beyond-9600-baud.pdf $(DESTDIR)/share/doc/direwolf/Going-beyond-9600-baud.pdf
- $(INSTALL) -D --mode=644 doc/Raspberry-Pi-APRS.pdf $(DESTDIR)/share/doc/direwolf/Raspberry-Pi-APRS.pdf
- $(INSTALL) -D --mode=644 doc/Raspberry-Pi-APRS-Tracker.pdf $(DESTDIR)/share/doc/direwolf/Raspberry-Pi-APRS-Tracker.pdf
- $(INSTALL) -D --mode=644 doc/Raspberry-Pi-SDR-IGate.pdf $(DESTDIR)/share/doc/direwolf/Raspberry-Pi-SDR-IGate.pdf
- $(INSTALL) -D --mode=644 doc/Successful-APRS-IGate-Operation.pdf $(DESTDIR)/share/doc/direwolf/Successful-APRS-IGate-Operation.pdf
- $(INSTALL) -D --mode=644 doc/User-Guide.pdf $(DESTDIR)/share/doc/direwolf/User-Guide.pdf
- $(INSTALL) -D --mode=644 doc/WA8LMF-TNC-Test-CD-Results.pdf $(DESTDIR)/share/doc/direwolf/WA8LMF-TNC-Test-CD-Results.pdf
+ $(INSTALL) -D -m=644 doc/README.md $(DESTDIR)/share/doc/direwolf/README.md
+ $(INSTALL) -D -m=644 doc/2400-4800-PSK-for-APRS-Packet-Radio.pdf $(DESTDIR)/share/doc/direwolf/2400-4800-PSK-for-APRS-Packet-Radio.pdf
+ $(INSTALL) -D -m=644 doc/A-Better-APRS-Packet-Demodulator-Part-1-1200-baud.pdf $(DESTDIR)/share/doc/direwolf/A-Better-APRS-Packet-Demodulator-Part-1-1200-baud.pdf
+ $(INSTALL) -D -m=644 doc/A-Better-APRS-Packet-Demodulator-Part-2-9600-baud.pdf $(DESTDIR)/share/doc/direwolf/A-Better-APRS-Packet-Demodulator-Part-2-9600-baud.pdf
+ $(INSTALL) -D -m=644 doc/A-Closer-Look-at-the-WA8LMF-TNC-Test-CD.pdf $(DESTDIR)/share/doc/direwolf/A-Closer-Look-at-the-WA8LMF-TNC-Test-CD.pdf
+ $(INSTALL) -D -m=644 doc/APRS-Telemetry-Toolkit.pdf $(DESTDIR)/share/doc/direwolf/APRS-Telemetry-Toolkit.pdf
+ $(INSTALL) -D -m=644 doc/APRStt-Implementation-Notes.pdf $(DESTDIR)/share/doc/direwolf/APRStt-Implementation-Notes.pdf
+ $(INSTALL) -D -m=644 doc/APRStt-interface-for-SARTrack.pdf $(DESTDIR)/share/doc/direwolf/APRStt-interface-for-SARTrack.pdf
+ $(INSTALL) -D -m=644 doc/APRStt-Listening-Example.pdf $(DESTDIR)/share/doc/direwolf/APRStt-Listening-Example.pdf
+ $(INSTALL) -D -m=644 doc/Bluetooth-KISS-TNC.pdf $(DESTDIR)/share/doc/direwolf/Bluetooth-KISS-TNC.pdf
+ $(INSTALL) -D -m=644 doc/Going-beyond-9600-baud.pdf $(DESTDIR)/share/doc/direwolf/Going-beyond-9600-baud.pdf
+ $(INSTALL) -D -m=644 doc/Raspberry-Pi-APRS.pdf $(DESTDIR)/share/doc/direwolf/Raspberry-Pi-APRS.pdf
+ $(INSTALL) -D -m=644 doc/Raspberry-Pi-APRS-Tracker.pdf $(DESTDIR)/share/doc/direwolf/Raspberry-Pi-APRS-Tracker.pdf
+ $(INSTALL) -D -m=644 doc/Raspberry-Pi-SDR-IGate.pdf $(DESTDIR)/share/doc/direwolf/Raspberry-Pi-SDR-IGate.pdf
+ $(INSTALL) -D -m=644 doc/Successful-APRS-IGate-Operation.pdf $(DESTDIR)/share/doc/direwolf/Successful-APRS-IGate-Operation.pdf
+ $(INSTALL) -D -m=644 doc/User-Guide.pdf $(DESTDIR)/share/doc/direwolf/User-Guide.pdf
+ $(INSTALL) -D -m=644 doc/WA8LMF-TNC-Test-CD-Results.pdf $(DESTDIR)/share/doc/direwolf/WA8LMF-TNC-Test-CD-Results.pdf
#
# Various sample config and other files go into examples under the doc directory.
# When building from source, these can be put in home directory with "make install-conf".
# When installed from .DEB or .RPM package, the user will need to copy these to
# the home directory or other desired location.
#
- $(INSTALL) -D --mode=644 direwolf.conf $(DESTDIR)/share/doc/direwolf/examples/direwolf.conf
- $(INSTALL) -D --mode=755 dw-start.sh $(DESTDIR)/share/doc/direwolf/examples/dw-start.sh
- $(INSTALL) -D --mode=644 sdr.conf $(DESTDIR)/share/doc/direwolf/examples/sdr.conf
- $(INSTALL) -D --mode=644 telemetry-toolkit/telem-m0xer-3.txt $(DESTDIR)/share/doc/direwolf/examples/telem-m0xer-3.txt
- $(INSTALL) -D --mode=644 telemetry-toolkit/telem-balloon.conf $(DESTDIR)/share/doc/direwolf/examples/telem-balloon.conf
- $(INSTALL) -D --mode=644 telemetry-toolkit/telem-volts.conf $(DESTDIR)/share/doc/direwolf/examples/telem-volts.conf
+ $(INSTALL) -D -m=644 direwolf.conf $(DESTDIR)/share/doc/direwolf/examples/direwolf.conf
+ $(INSTALL) -D -m=755 dw-start.sh $(DESTDIR)/share/doc/direwolf/examples/dw-start.sh
+ $(INSTALL) -D -m=644 sdr.conf $(DESTDIR)/share/doc/direwolf/examples/sdr.conf
+ $(INSTALL) -D -m=644 telemetry-toolkit/telem-m0xer-3.txt $(DESTDIR)/share/doc/direwolf/examples/telem-m0xer-3.txt
+ $(INSTALL) -D -m=644 telemetry-toolkit/telem-balloon.conf $(DESTDIR)/share/doc/direwolf/examples/telem-balloon.conf
+ $(INSTALL) -D -m=644 telemetry-toolkit/telem-volts.conf $(DESTDIR)/share/doc/direwolf/examples/telem-volts.conf
#
# "man" pages
#
- $(INSTALL) -D --mode=644 man1/aclients.1 $(DESTDIR)/share/man/man1/aclients.1
- $(INSTALL) -D --mode=644 man1/atest.1 $(DESTDIR)/share/man/man1/atest.1
- $(INSTALL) -D --mode=644 man1/decode_aprs.1 $(DESTDIR)/share/man/man1/decode_aprs.1
- $(INSTALL) -D --mode=644 man1/direwolf.1 $(DESTDIR)/share/man/man1/direwolf.1
- $(INSTALL) -D --mode=644 man1/gen_packets.1 $(DESTDIR)/share/man/man1/gen_packets.1
- $(INSTALL) -D --mode=644 man1/kissutil.1 $(DESTDIR)/share/man/man1/kissutil.1
- $(INSTALL) -D --mode=644 man1/ll2utm.1 $(DESTDIR)/share/man/man1/ll2utm.1
- $(INSTALL) -D --mode=644 man1/log2gpx.1 $(DESTDIR)/share/man/man1/log2gpx.1
- $(INSTALL) -D --mode=644 man1/text2tt.1 $(DESTDIR)/share/man/man1/text2tt.1
- $(INSTALL) -D --mode=644 man1/tt2text.1 $(DESTDIR)/share/man/man1/tt2text.1
- $(INSTALL) -D --mode=644 man1/utm2ll.1 $(DESTDIR)/share/man/man1/utm2ll.1
+ $(INSTALL) -D -m=644 man1/aclients.1 $(DESTDIR)/share/man/man1/aclients.1
+ $(INSTALL) -D -m=644 man1/atest.1 $(DESTDIR)/share/man/man1/atest.1
+ $(INSTALL) -D -m=644 man1/decode_aprs.1 $(DESTDIR)/share/man/man1/decode_aprs.1
+ $(INSTALL) -D -m=644 man1/direwolf.1 $(DESTDIR)/share/man/man1/direwolf.1
+ $(INSTALL) -D -m=644 man1/gen_packets.1 $(DESTDIR)/share/man/man1/gen_packets.1
+ $(INSTALL) -D -m=644 man1/kissutil.1 $(DESTDIR)/share/man/man1/kissutil.1
+ $(INSTALL) -D -m=644 man1/ll2utm.1 $(DESTDIR)/share/man/man1/ll2utm.1
+ $(INSTALL) -D -m=644 man1/log2gpx.1 $(DESTDIR)/share/man/man1/log2gpx.1
+ $(INSTALL) -D -m=644 man1/text2tt.1 $(DESTDIR)/share/man/man1/text2tt.1
+ $(INSTALL) -D -m=644 man1/tt2text.1 $(DESTDIR)/share/man/man1/tt2text.1
+ $(INSTALL) -D -m=644 man1/utm2ll.1 $(DESTDIR)/share/man/man1/utm2ll.1
#
# Set group and mode of HID devices corresponding to C-Media USB Audio adapters.
# This will allow us to use the CM108/CM119 GPIO pins for PTT.
#
- $(INSTALL) -D --mode=644 99-direwolf-cmedia.rules /etc/udev/rules.d/99-direwolf-cmedia.rules
+ $(INSTALL) -D -m=644 99-direwolf-cmedia.rules /etc/udev/rules.d/99-direwolf-cmedia.rules
#
@echo " "
@echo "If this is your first install, not an upgrade, type this to put a copy"
diff --git a/cdigipeater.c b/cdigipeater.c
index 9c40d95..94112e9 100644
--- a/cdigipeater.c
+++ b/cdigipeater.c
@@ -49,7 +49,7 @@
#include <stdio.h>
#include <ctype.h> /* for isdigit, isupper */
#include "regex.h"
-#include <sys/unistd.h>
+#include <unistd.h>
#include "ax25_pad.h"
#include "cdigipeater.h"
diff --git a/decode_aprs.c b/decode_aprs.c
index 35c186b..a620cb3 100644
--- a/decode_aprs.c
+++ b/decode_aprs.c
@@ -3872,11 +3872,7 @@ static void decode_tocall (decode_aprs_t *A, char *dest)
* models before getting to the more generic APY.
*/
-#if defined(__WIN32__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__APPLE__)
qsort (tocalls, num_tocalls, sizeof(struct tocalls_s), tocall_cmp);
-#else
- qsort (tocalls, num_tocalls, sizeof(struct tocalls_s), (__compar_fn_t)tocall_cmp);
-#endif
}
else {
if ( ! A->g_quiet) {
diff --git a/digipeater.c b/digipeater.c
index 36970d7..5195582 100644
--- a/digipeater.c
+++ b/digipeater.c
@@ -62,7 +62,7 @@
#include <stdio.h>
#include <ctype.h> /* for isdigit, isupper */
#include "regex.h"
-#include <sys/unistd.h>
+#include <unistd.h>
#include "ax25_pad.h"
#include "digipeater.h"
diff --git a/direwolf.h b/direwolf.h
index 514bcc5..52f5ae9 100644
--- a/direwolf.h
+++ b/direwolf.h
@@ -274,7 +274,7 @@ char *strtok_r(char *str, const char *delim, char **saveptr);
char *strcasestr(const char *S, const char *FIND);
-#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__APPLE__)
+#if 1
// strlcpy and strlcat should be in string.h and the C library.
diff --git a/multi_modem.c b/multi_modem.c
index 5d96c79..24261b9 100644
--- a/multi_modem.c
+++ b/multi_modem.c
@@ -80,7 +80,7 @@
#include <string.h>
#include <assert.h>
#include <stdio.h>
-#include <sys/unistd.h>
+#include <unistd.h>
#include "ax25_pad.h"
#include "textcolor.h"

View File

@ -0,0 +1,31 @@
#!/usr/bin/env bash
set -euxo pipefail
export MAKEFLAGS="-j4"
function cmakebuild() {
cd $1
if [[ ! -z "${2:-}" ]]; then
git checkout $2
fi
mkdir build
cd build
cmake ..
make
make install
cd ../..
rm -rf $1
}
cd /tmp
BUILD_PACKAGES="git cmake make gcc g++"
apt-get update
apt-get -y install --no-install-recommends $BUILD_PACKAGES
git clone https://github.com/jketterl/owrx_connector.git
cmakebuild owrx_connector 0.3.0
apt-get -y purge --autoremove $BUILD_PACKAGES
apt-get clean
rm -rf /var/lib/apt/lists/*

View File

@ -1,8 +1,12 @@
#!/bin/bash #!/bin/bash
set -euxo pipefail set -euxo pipefail
export MAKEFLAGS="-j4"
function cmakebuild() { function cmakebuild() {
cd $1 cd $1
if [[ ! -z "${2:-}" ]]; then
git checkout $2
fi
mkdir build mkdir build
cd build cd build
cmake .. cmake ..
@ -14,13 +18,27 @@ function cmakebuild() {
cd /tmp cd /tmp
STATIC_PACKAGES="libusb" STATIC_PACKAGES="libusb-1.0-0"
BUILD_PACKAGES="git libusb-dev cmake make gcc musl-dev g++ linux-headers" BUILD_PACKAGES="git libusb-1.0-0-dev cmake make gcc g++ pkg-config"
apk add --no-cache $STATIC_PACKAGES apt-get update
apk add --no-cache --virtual .build-deps $BUILD_PACKAGES apt-get -y install --no-install-recommends $STATIC_PACKAGES $BUILD_PACKAGES
git clone https://github.com/airspy/airspyone_host.git git clone https://github.com/airspy/airspyone_host.git
cmakebuild airspyone_host # latest from master as of 2020-09-04
cmakebuild airspyone_host 652fd7f1a8f85687641e0bd91f739694d7258ecc
apk del .build-deps git clone https://github.com/pothosware/SoapyAirspy.git
cmakebuild SoapyAirspy 10d697b209e7f1acc8b2c8d24851d46170ef77e3
git clone https://github.com/airspy/airspyhf.git
# latest from master as of 2020-09-04
cmakebuild airspyhf 8891387edddcd185e2949e9814e9ef35f46f0722
git clone https://github.com/pothosware/SoapyAirspyHF.git
# latest from master as of 2020-09-04
cmakebuild SoapyAirspyHF 5488dac5b44f1432ce67b40b915f7e61d3bd4853
apt-get -y purge --autoremove $BUILD_PACKAGES
apt-get clean
rm -rf /var/lib/apt/lists/*

View File

@ -0,0 +1,32 @@
#!/bin/bash
set -euxo pipefail
export MAKEFLAGS="-j4"
function cmakebuild() {
cd $1
if [[ ! -z "${2:-}" ]]; then
git checkout $2
fi
mkdir build
cd build
cmake ..
make
make install
cd ../..
rm -rf $1
}
cd /tmp
STATIC_PACKAGES="libhidapi-hidraw0 libhidapi-libusb0 libasound2"
BUILD_PACKAGES="git cmake make gcc g++ libhidapi-dev libasound2-dev"
apt-get update
apt-get -y install --no-install-recommends $STATIC_PACKAGES $BUILD_PACKAGES
git clone https://github.com/pothosware/SoapyFCDPP.git
cmakebuild SoapyFCDPP soapy-fcdpp-0.1.1
apt-get -y purge --autoremove $BUILD_PACKAGES
apt-get clean
rm -rf /var/lib/apt/lists/*

View File

@ -1,8 +1,12 @@
#!/bin/bash #!/bin/bash
set -euxo pipefail set -euxo pipefail
export MAKEFLAGS="-j4"
function cmakebuild() { function cmakebuild() {
cd $1 cd $1
if [[ ! -z "${2:-}" ]]; then
git checkout $2
fi
mkdir build mkdir build
cd build cd build
cmake .. cmake ..
@ -14,16 +18,24 @@ function cmakebuild() {
cd /tmp cd /tmp
STATIC_PACKAGES="libusb fftw udev" STATIC_PACKAGES="libusb-1.0-0 libfftw3-3 udev"
BUILD_PACKAGES="git cmake make patch wget sudo gcc g++ libusb-dev fftw-dev" BUILD_PACKAGES="git cmake make patch wget sudo gcc g++ libusb-1.0-0-dev libfftw3-dev pkg-config"
apk add --no-cache $STATIC_PACKAGES apt-get update
apk add --no-cache --virtual .build-deps $BUILD_PACKAGES apt-get -y install --no-install-recommends $STATIC_PACKAGES $BUILD_PACKAGES
git clone https://github.com/mossmann/hackrf.git git clone https://github.com/mossmann/hackrf.git
cd hackrf cd hackrf
# latest from master as of 2020-09-04
git checkout 6e5cbda2945c3bab0e6e1510eae418eda60c358e
cmakebuild host cmakebuild host
cd .. cd ..
rm -rf hackrf rm -rf hackrf
apk del .build-deps git clone https://github.com/pothosware/SoapyHackRF.git
# latest from master as of 2020-09-04
cmakebuild SoapyHackRF 7d530872f96c1cbe0ed62617c32c48ce7e103e1d
SUDO_FORCE_REMOVE=yes apt-get -y purge --autoremove $BUILD_PACKAGES
apt-get clean
rm -rf /var/lib/apt/lists/*

View File

@ -0,0 +1,32 @@
#!/usr/bin/env bash
set -euo pipefail
export MAKEFLAGS="-j4"
cd /tmp
STATIC_PACKAGES="libusb-1.0-0 libatomic1"
BUILD_PACKAGES="git libusb-1.0-0-dev cmake make gcc g++"
apt-get update
apt-get -y install --no-install-recommends $STATIC_PACKAGES $BUILD_PACKAGES
SIMD_FLAGS=""
if [[ 'x86_64' == `uname -m` ]] ; then
SIMD_FLAGS="-DDEFAULT_SIMD_FLAGS=SSE3"
fi
git clone https://github.com/myriadrf/LimeSuite.git
cd LimeSuite
# latest from master as of 2020-09-04
git checkout 9526621f8b4c9e2a7f638b5ef50c45560dcad22a
mkdir builddir
cd builddir
cmake .. -DENABLE_EXAMPLES=OFF -DENABLE_DESKTOP=OFF -DENABLE_LIME_UTIL=OFF -DENABLE_QUICKTEST=OFF -DENABLE_OCTAVE=OFF -DENABLE_GUI=OFF -DCMAKE_CXX_STANDARD_LIBRARIES="-latomic" ${SIMD_FLAGS}
make
make install
cd ../..
rm -rf LimeSuite
apt-get -y purge --autoremove $BUILD_PACKAGES
apt-get clean
rm -rf /var/lib/apt/lists/*

View File

@ -0,0 +1,27 @@
#!/usr/bin/env bash
set -euxo pipefail
export MAKEFLAGS="-j4"
cd /tmp
STATIC_PACKAGES="libusb-1.0-0 libudev1"
BUILD_PACKAGES="git make gcc autoconf automake libtool libusb-1.0-0-dev xxd"
apt-get update
apt-get -y install --no-install-recommends $STATIC_PACKAGES $BUILD_PACKAGES
git clone https://github.com/Microtelecom/libperseus-sdr.git
cd libperseus-sdr
# latest from master as of 2020-09-04
git checkout c2c95daeaa08bf0daed0e8ada970ab17cc264e1b
./bootstrap.sh
./configure
make
make install
ldconfig /etc/ld.so.conf.d
cd ..
rm -rf libperseus-sdr
apt-get -y purge --autoremove $BUILD_PACKAGES
apt-get clean
rm -rf /var/lib/apt/lists/*

View File

@ -0,0 +1,39 @@
#!/usr/bin/env bash
set -euo pipefail
export MAKEFLAGS="-j4"
function cmakebuild() {
cd $1
if [[ ! -z "${2:-}" ]]; then
git checkout $2
fi
mkdir build
cd build
cmake .. ${3:-}
make
make install
cd ../..
rm -rf $1
}
cd /tmp
STATIC_PACKAGES="libusb-1.0-0 libxml2"
BUILD_PACKAGES="git libusb-1.0-0-dev cmake make gcc g++ libxml2-dev flex bison pkg-config"
apt-get update
apt-get -y install --no-install-recommends $STATIC_PACKAGES $BUILD_PACKAGES
git clone https://github.com/analogdevicesinc/libiio.git
cmakebuild libiio v0.21 -DCMAKE_INSTALL_PREFIX=/usr/local
git clone https://github.com/analogdevicesinc/libad9361-iio.git
cmakebuild libad9361-iio v0.2
git clone https://github.com/pothosware/SoapyPlutoSDR.git
# latest from master as of 2020-09-04
cmakebuild SoapyPlutoSDR 93717b32ef052e0dfa717aa2c1a4eb27af16111f
apt-get -y purge --autoremove $BUILD_PACKAGES
apt-get clean
rm -rf /var/lib/apt/lists/*

View File

@ -0,0 +1,37 @@
#!/bin/bash
set -euxo pipefail
export MAKEFLAGS="-j4"
function cmakebuild() {
cd $1
if [[ ! -z "${2:-}" ]]; then
git checkout $2
fi
mkdir build
cd build
cmake ..
make
make install
cd ../..
rm -rf $1
}
cd /tmp
STATIC_PACKAGES="libusb-1.0-0 libfftw3-3 udev"
BUILD_PACKAGES="git cmake make patch wget sudo gcc g++ libusb-1.0-0-dev libfftw3-dev pkg-config"
apt-get update
apt-get -y install --no-install-recommends $STATIC_PACKAGES $BUILD_PACKAGES
git clone https://github.com/pa3gsb/Radioberry-2.x
cd Radioberry-2.x/SBC/rpi-4
# latest from master as of 2020-09-04
cmakebuild SoapyRadioberrySDR 8d17de6b4dc076e628900a82f05c7cf0b16cbe24
cd ../../..
rm -rf Radioberry-2.x
SUDO_FORCE_REMOVE=yes apt-get -y purge --autoremove $BUILD_PACKAGES
apt-get clean
rm -rf /var/lib/apt/lists/*

View File

@ -0,0 +1,32 @@
#!/bin/bash
set -euo pipefail
export MAKEFLAGS="-j4"
function cmakebuild() {
cd $1
if [[ ! -z "${2:-}" ]]; then
git checkout $2
fi
mkdir build
cd build
cmake ..
make
make install
cd ../..
rm -rf $1
}
cd /tmp
STATIC_PACKAGES=""
BUILD_PACKAGES="git cmake make gcc g++"
apt-get update
apt-get -y install --no-install-recommends $STATIC_PACKAGES $BUILD_PACKAGES
git clone https://github.com/pothosware/SoapyRedPitaya.git
cmakebuild SoapyRedPitaya soapy-redpitaya-0.1.1
SUDO_FORCE_REMOVE=yes apt-get -y purge --autoremove $BUILD_PACKAGES
apt-get clean
rm -rf /var/lib/apt/lists/*

View File

@ -0,0 +1,36 @@
#!/usr/bin/env bash
set -euo pipefail
export MAKEFLAGS="-j4"
function cmakebuild() {
cd $1
if [[ ! -z "${2:-}" ]]; then
git checkout $2
fi
mkdir build
cd build
cmake ..
make
make install
cd ../..
rm -rf $1
}
cd /tmp
STATIC_PACKAGES="libusb-1.0-0"
BUILD_PACKAGES="git libusb-1.0-0-dev cmake make gcc g++ pkg-config"
apt-get update
apt-get -y install --no-install-recommends $STATIC_PACKAGES $BUILD_PACKAGES
git clone https://github.com/osmocom/rtl-sdr.git
# latest from master as of 2020-09-04
cmakebuild rtl-sdr ed0317e6a58c098874ac58b769cf2e609c18d9a5
git clone https://github.com/pothosware/SoapyRTLSDR.git
cmakebuild SoapyRTLSDR soapy-rtl-sdr-0.3.1
apt-get -y purge --autoremove $BUILD_PACKAGES
apt-get clean
rm -rf /var/lib/apt/lists/*

View File

@ -1,8 +1,12 @@
#!/bin/bash #!/bin/bash
set -euxo pipefail set -euxo pipefail
export MAKEFLAGS="-j4"
function cmakebuild() { function cmakebuild() {
cd $1 cd $1
if [[ ! -z "${2:-}" ]]; then
git checkout $2
fi
mkdir build mkdir build
cd build cd build
cmake .. cmake ..
@ -14,13 +18,16 @@ function cmakebuild() {
cd /tmp cd /tmp
STATIC_PACKAGES="libusb" STATIC_PACKAGES="libusb-1.0.0"
BUILD_PACKAGES="git libusb-dev cmake make gcc musl-dev g++ linux-headers" BUILD_PACKAGES="git libusb-1.0.0-dev cmake make gcc g++ pkg-config"
apk add --no-cache $STATIC_PACKAGES apt-get update
apk add --no-cache --virtual .build-deps $BUILD_PACKAGES apt-get -y install --no-install-recommends $STATIC_PACKAGES $BUILD_PACKAGES
git clone https://github.com/osmocom/rtl-sdr.git git clone https://github.com/osmocom/rtl-sdr.git
cmakebuild rtl-sdr # latest from master as of 2020-09-04
cmakebuild rtl-sdr ed0317e6a58c098874ac58b769cf2e609c18d9a5
apk del .build-deps apt-get -y purge --autoremove $BUILD_PACKAGES
apt-get clean
rm -rf /var/lib/apt/lists/*

View File

@ -1,8 +1,12 @@
#!/bin/bash #!/bin/bash
set -euxo pipefail set -euxo pipefail
export MAKEFLAGS="-j4"
function cmakebuild() { function cmakebuild() {
cd $1 cd $1
if [[ ! -z "${2:-}" ]]; then
git checkout $2
fi
mkdir build mkdir build
cd build cd build
cmake .. cmake ..
@ -14,24 +18,27 @@ function cmakebuild() {
cd /tmp cd /tmp
STATIC_PACKAGES="libusb udev" STATIC_PACKAGES="libusb-1.0.0 udev"
BUILD_PACKAGES="git cmake make patch wget sudo gcc g++ libusb-dev" BUILD_PACKAGES="git cmake make patch wget sudo gcc g++ libusb-1.0-0-dev"
apk add --no-cache $STATIC_PACKAGES apt-get update
apk add --no-cache --virtual .build-deps $BUILD_PACKAGES apt-get -y install --no-install-recommends $STATIC_PACKAGES $BUILD_PACKAGES
ARCH=$(uname -m) ARCH=$(uname -m)
case $ARCH in case $ARCH in
x86_64) x86_64)
BINARY=SDRplay_RSP_API-Linux-2.13.1.run BINARY=SDRplay_RSP_API-Linux-3.07.1.run
;; ;;
armv*) armv*)
BINARY=SDRplay_RSP_API-RPi-2.13.1.run BINARY=SDRplay_RSP_API-ARM32-3.07.2.run
;;
aarch64)
BINARY=SDRplay_RSP_API-ARM64-3.07.1.run
;; ;;
esac esac
wget http://www.sdrplay.com/software/$BINARY wget https://www.sdrplay.com/software/$BINARY
sh $BINARY --noexec --target sdrplay sh $BINARY --noexec --target sdrplay
patch --verbose -Np0 < /install-lib.$ARCH.patch patch --verbose -Np0 < /install-lib.$ARCH.patch
@ -41,7 +48,10 @@ cd ..
rm -rf sdrplay rm -rf sdrplay
rm $BINARY rm $BINARY
git clone https://github.com/pothosware/SoapySDRPlay.git git clone https://github.com/SDRplay/SoapySDRPlay.git
cmakebuild SoapySDRPlay # latest from master as of 2020-09-04
cmakebuild SoapySDRPlay 105f8a6b3d449982d7ef860790c201aa066b8fa9
apk del .build-deps SUDO_FORCE_REMOVE=yes apt-get -y purge --autoremove $BUILD_PACKAGES
apt-get clean
rm -rf /var/lib/apt/lists/*

View File

@ -0,0 +1,32 @@
#!/usr/bin/env bash
set -euo pipefail
export MAKEFLAGS="-j4"
function cmakebuild() {
cd $1
if [[ ! -z "${2:-}" ]]; then
git checkout $2
fi
mkdir build
cd build
cmake ..
make
make install
cd ../..
rm -rf $1
}
cd /tmp
STATIC_PACKAGES="avahi-daemon libavahi-client3"
BUILD_PACKAGES="git cmake make gcc g++ libavahi-client-dev"
apt-get update
apt-get -y install --no-install-recommends $STATIC_PACKAGES $BUILD_PACKAGES
git clone https://github.com/pothosware/SoapyRemote.git
cmakebuild SoapyRemote soapy-remote-0.5.2
apt-get -y purge --autoremove $BUILD_PACKAGES
apt-get clean
rm -rf /var/lib/apt/lists/*

View File

@ -1,8 +1,12 @@
#!/bin/bash #!/bin/bash
set -euxo pipefail set -euxo pipefail
export MAKEFLAGS="-j4"
function cmakebuild() { function cmakebuild() {
cd $1 cd $1
if [[ ! -z "${2:-}" ]]; then
git checkout $2
fi
mkdir build mkdir build
cd build cd build
cmake .. cmake ..
@ -14,16 +18,16 @@ function cmakebuild() {
cd /tmp cd /tmp
STATIC_PACKAGES="udev" STATIC_PACKAGES="libudev1"
BUILD_PACKAGES="git cmake make patch wget sudo gcc g++" BUILD_PACKAGES="git cmake make patch wget sudo gcc g++"
apk add --no-cache $STATIC_PACKAGES apt-get update
apk add --no-cache --virtual .build-deps $BUILD_PACKAGES apt-get -y install --no-install-recommends $STATIC_PACKAGES $BUILD_PACKAGES
git clone https://github.com/pothosware/SoapySDR git clone https://github.com/pothosware/SoapySDR
cmakebuild SoapySDR # latest from master as of 2020-09-04
cmakebuild SoapySDR 580b94f3dad46899f34ec0a060dbb4534e844e57
git clone https://github.com/rxseger/rx_tools SUDO_FORCE_REMOVE=yes apt-get -y purge --autoremove $BUILD_PACKAGES
cmakebuild rx_tools apt-get clean
rm -rf /var/lib/apt/lists/*
apk del .build-deps

View File

@ -0,0 +1,60 @@
#!/bin/bash
set -euo pipefail
export MAKEFLAGS="-j4"
function cmakebuild() {
cd $1
if [[ ! -z "${2:-}" ]]; then
git checkout $2
fi
mkdir build
cd build
cmake ..
make
make install
cd ../..
rm -rf $1
}
cd /tmp
STATIC_PACKAGES="libusb-1.0.0 libboost-chrono1.67.0 libboost-date-time1.67.0 libboost-filesystem1.67.0 libboost-program-options1.67.0 libboost-regex1.67.0 libboost-test1.67.0 libboost-serialization1.67.0 libboost-thread1.67.0 libboost-system1.67.0 python3-numpy python3-mako"
BUILD_PACKAGES="git cmake make gcc g++ libusb-1.0-0-dev libboost-dev libboost-chrono-dev libboost-date-time-dev libboost-filesystem-dev libboost-program-options-dev libboost-regex-dev libboost-test-dev libboost-serialization-dev libboost-thread-dev libboost-system-dev"
apt-get update
apt-get -y install --no-install-recommends $STATIC_PACKAGES $BUILD_PACKAGES
git clone https://github.com/EttusResearch/uhd.git
# 3.15.0.0 Release
mkdir -p uhd/host/build
cd uhd/host/build
git checkout v3.15.0.0
# see https://github.com/EttusResearch/uhd/issues/350
case `uname -m` in
arm*)
cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_UTILS=OFF -DENABLE_PYTHON_API=OFF -DENABLE_EXAMPLES=OFF -DENABLE_TESTS=OFF -DENABLE_OCTOCLOCK=OFF -DENABLE_MAN_PAGES=OFF -DSTRIP_BINARIES=ON \
-DCMAKE_CXX_FLAGS:STRING="-march=armv7-a -mfloat-abi=hard -mfpu=neon -mtune=cortex-a8 -Wno-psabi" \
-DCMAKE_C_FLAGS:STRING="-march=armv7-a -mfloat-abi=hard -mfpu=neon -mtune=cortex-a8 -Wno-psabi" \
-DCMAKE_ASM_FLAGS:STRING="-march=armv7-a -mfloat-abi=hard -mfpu=neon -mtune=cortex-a8 -g" ..
;;
aarch64*)
cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_UTILS=OFF -DENABLE_PYTHON_API=OFF -DENABLE_EXAMPLES=OFF -DENABLE_TESTS=OFF -DENABLE_OCTOCLOCK=OFF -DENABLE_MAN_PAGES=OFF -DSTRIP_BINARIES=ON \
-DCMAKE_CXX_FLAGS:STRING="-march=armv8-a -mtune=cortex-a72 -Wno-psabi" \
-DCMAKE_C_FLAGS:STRING="-march=armv8-a -mtune=cortex-a72 -Wno-psabi" \
-DCMAKE_ASM_FLAGS:STRING="-march=armv8-a -mtune=cortex-a72 -g" ..
;;
x86_64)
cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_UTILS=OFF -DENABLE_PYTHON_API=OFF -DENABLE_EXAMPLES=OFF -DENABLE_TESTS=OFF -DENABLE_OCTOCLOCK=OFF -DENABLE_MAN_PAGES=OFF -DSTRIP_BINARIES=ON ..
;;
esac
make
make install
cd ../../..
rm -rf uhd
git clone https://github.com/pothosware/SoapyUHD.git
cmakebuild SoapyUHD soapy-uhd-0.4.1
SUDO_FORCE_REMOVE=yes apt-get -y purge --autoremove $BUILD_PACKAGES
apt-get clean
rm -rf /var/lib/apt/lists/*

View File

@ -1,11 +1,15 @@
#!/bin/bash #!/bin/bash
set -euxo pipefail set -euxo pipefail
export MAKEFLAGS="-j4"
function cmakebuild() { function cmakebuild() {
cd $1 cd $1
if [[ ! -z "${2:-}" ]]; then
git checkout $2
fi
mkdir build mkdir build
cd build cd build
cmake .. cmake ${CMAKE_ARGS:-} ..
make make
make install make install
cd ../.. cd ../..
@ -14,50 +18,99 @@ function cmakebuild() {
cd /tmp cd /tmp
STATIC_PACKAGES="sox fftw python3 netcat-openbsd libsndfile lapack libusb qt5-qtbase qt5-qtmultimedia qt5-qtserialport qt5-qttools alsa-lib" STATIC_PACKAGES="sox libfftw3-bin python3 python3-setuptools netcat-openbsd libsndfile1 liblapack3 libusb-1.0-0 libqt5core5a libreadline7 libgfortran4 libgomp1 libasound2 libudev1 ca-certificates libqt5gui5 libqt5sql5 libqt5printsupport5 libpulse0 libfaad2 libopus0"
BUILD_PACKAGES="git libsndfile-dev fftw-dev cmake ca-certificates make gcc musl-dev g++ lapack-dev linux-headers autoconf automake libtool texinfo gfortran libusb-dev qt5-qtbase-dev qt5-qtmultimedia-dev qt5-qtserialport-dev qt5-qttools-dev asciidoctor asciidoc alsa-lib-dev linux-headers" BUILD_PACKAGES="wget git libsndfile1-dev libfftw3-dev cmake make gcc g++ liblapack-dev texinfo gfortran libusb-1.0-0-dev qtbase5-dev qtmultimedia5-dev qttools5-dev libqt5serialport5-dev qttools5-dev-tools asciidoctor asciidoc libasound2-dev libudev-dev libhamlib-dev patch xsltproc qt5-default libfaad-dev libopus-dev"
apt-get update
apt-get -y install auto-apt-proxy
apt-get -y install --no-install-recommends $STATIC_PACKAGES $BUILD_PACKAGES
apk add --no-cache $STATIC_PACKAGES case `uname -m` in
apk add --no-cache --virtual .build-deps $BUILD_PACKAGES arm*)
PLATFORM=armhf
;;
aarch64*)
PLATFORM=aarch64
;;
x86_64*)
PLATFORM=amd64
;;
esac
wget https://github.com/just-containers/s6-overlay/releases/download/v1.21.8.0/s6-overlay-${PLATFORM}.tar.gz
tar xzf s6-overlay-${PLATFORM}.tar.gz -C /
rm s6-overlay-${PLATFORM}.tar.gz
git clone https://git.code.sf.net/p/itpp/git itpp git clone https://git.code.sf.net/p/itpp/git itpp
cmakebuild itpp cmakebuild itpp bb5c7e95f40e8fdb5c3f3d01a84bcbaf76f3676d
git clone https://github.com/jketterl/csdr.git -b 48khz_filter
cd csdr
make
make install
cd ..
rm -rf csdr
git clone https://github.com/szechyjs/mbelib.git git clone https://github.com/szechyjs/mbelib.git
cmakebuild mbelib cmakebuild mbelib 9a04ed5c78176a9965f3d43f7aa1b1f5330e771f
if [ -d "/usr/local/lib64" ]; then
# no idea why it's put into there now. alpine does not handle it correctly, so move it.
mv /usr/local/lib64/libmbe* /usr/local/lib
fi
git clone https://github.com/jketterl/digiham.git
cmakebuild digiham
git clone https://github.com/f4exb/dsd.git git clone https://github.com/f4exb/dsd.git
cmakebuild dsd cmakebuild dsd f6939f9edbbc6f66261833616391a4e59cb2b3d7
WSJT_DIR=wsjtx-2.1.0 JS8CALL_VERSION=2.2.0
JS8CALL_DIR=js8call
JS8CALL_TGZ=js8call-${JS8CALL_VERSION}.tgz
wget http://files.js8call.com/${JS8CALL_VERSION}/${JS8CALL_TGZ}
tar xfz ${JS8CALL_TGZ}
# patch allows us to build against the packaged hamlib
patch -Np1 -d ${JS8CALL_DIR} < /js8call-hamlib.patch
rm /js8call-hamlib.patch
CMAKE_ARGS="-D CMAKE_CXX_FLAGS=-DJS8_USE_HAMLIB_THREE" cmakebuild ${JS8CALL_DIR}
rm ${JS8CALL_TGZ}
WSJT_DIR=wsjtx-2.2.2
WSJT_TGZ=${WSJT_DIR}.tgz WSJT_TGZ=${WSJT_DIR}.tgz
wget http://physics.princeton.edu/pulsar/k1jt/$WSJT_TGZ wget http://physics.princeton.edu/pulsar/k1jt/${WSJT_TGZ}
tar xvfz $WSJT_TGZ tar xfz ${WSJT_TGZ}
cmakebuild $WSJT_DIR patch -Np0 -d ${WSJT_DIR} < /wsjtx-hamlib.patch
mv /wsjtx.patch ${WSJT_DIR}
cmakebuild ${WSJT_DIR}
rm ${WSJT_TGZ}
git clone https://github.com/wb2osz/direwolf.git git clone --depth 1 -b 1.5 https://github.com/wb2osz/direwolf.git
cd direwolf cd direwolf
git checkout 1.5 # hamlib is present (necessary for the wsjt-x and js8call builds) and would be used, but there's no real need.
patch -Np1 < /direwolf-1.5.patch # by setting enable_hamlib we prevent direwolf from linking to it, and it can be stripped at the end of the script.
make make enable_hamlib=
make install make install
cd .. cd ..
rm -rf direwolf rm -rf direwolf
# strip lots of generic documentation that will never be read inside a docker container
rm /usr/local/share/doc/direwolf/*.pdf
# examples are pointless, too
rm -rf /usr/local/share/doc/direwolf/examples/
git clone https://github.com/drowe67/codec2.git
cd codec2
# latest commit from master as of 2020-10-04
git checkout 55d7bb8d1bddf881bdbfcb971a718b83e6344598
mkdir build
cd build
cmake ..
make
make install
install -m 0755 src/freedv_rx /usr/local/bin
cd ../..
rm -rf codec2
wget https://downloads.sourceforge.net/project/drm/dream/2.1.1/dream-2.1.1-svn808.tar.gz
tar xvfz dream-2.1.1-svn808.tar.gz
pushd dream
patch -Np0 < /dream.patch
qmake CONFIG+=console
make
make install
popd
rm -rf dream
rm dream-2.1.1-svn808.tar.gz
git clone https://github.com/hessu/aprs-symbols /opt/aprs-symbols git clone https://github.com/hessu/aprs-symbols /opt/aprs-symbols
pushd /opt/aprs-symbols
git checkout 5c2abe2658ee4d2563f3c73b90c6f59124839802
popd
apk del .build-deps apt-get -y purge --autoremove $BUILD_PACKAGES
apt-get clean
rm -rf /var/lib/apt/lists/*

View File

@ -1,40 +0,0 @@
--- sdrplay/install_lib.sh
+++ sdrplay/install_lib_patched.sh
@@ -3,19 +3,7 @@
echo "Installing SDRplay RSP API library 2.13..."
-more sdrplay_license.txt
-
-while true; do
- echo "Press y and RETURN to accept the license agreement and continue with"
- read -p "the installation, or press n and RETURN to exit the installer [y/n] " yn
- case $yn in
- [Yy]* ) break;;
- [Nn]* ) exit;;
- * ) echo "Please answer y or n";;
- esac
-done
-
-export ARCH=`arch`
+export ARCH=`uname -m`
export VERS="2.13"
echo "Architecture: ${ARCH}"
@@ -60,16 +48,6 @@
echo "ERROR: udev rules directory not found, add udev support and run the"
echo "installer again. udev support can be added by running..."
echo "sudo apt-get install libudev-dev"
- echo " "
- exit 1
-fi
-
-if /sbin/ldconfig -p | /bin/fgrep -q libusb-1.0; then
- echo "Libusb found, continuing..."
-else
- echo " "
- echo "ERROR: Libusb cannot be found. Please install libusb and then run"
- echo "the installer again. Libusb can be installed from http://libusb.info"
echo " "
exit 1
fi

View File

@ -1,40 +0,0 @@
--- sdrplay/install_lib.sh 2018-06-21 01:57:02.000000000 +0200
+++ sdrplay/install_lib_patched.sh 2019-01-22 17:21:06.445804136 +0100
@@ -2,19 +2,7 @@
echo "Installing SDRplay RSP API library 2.13..."
-more sdrplay_license.txt
-
-while true; do
- echo "Press y and RETURN to accept the license agreement and continue with"
- read -p "the installation, or press n and RETURN to exit the installer [y/n] " yn
- case $yn in
- [Yy]* ) break;;
- [Nn]* ) exit;;
- * ) echo "Please answer y or n";;
- esac
-done
-
-export ARCH=`arch`
+export ARCH=`uname -m`
export VERS="2.13"
echo "Architecture: ${ARCH}"
@@ -60,16 +48,6 @@
echo " "
exit 1
fi
-
-if /sbin/ldconfig -p | /bin/fgrep -q libusb-1.0; then
- echo "Libusb found, continuing..."
-else
- echo " "
- echo "ERROR: Libusb cannot be found. Please install libusb and then run"
- echo "the installer again. Libusb can be installed from http://libusb.info"
- echo " "
- exit 1
-fi
#echo "Installing SoapySDRPlay..."

View File

@ -0,0 +1,48 @@
#!/bin/bash
set -euxo pipefail
export MAKEFLAGS="-j4"
function cmakebuild() {
cd $1
if [[ ! -z "${2:-}" ]]; then
git checkout $2
fi
mkdir build
cd build
cmake ${CMAKE_ARGS:-} ..
make
make install
cd ../..
rm -rf $1
}
cd /tmp
STATIC_PACKAGES="libfftw3-bin"
BUILD_PACKAGES="git autoconf automake libtool libfftw3-dev pkg-config cmake make gcc g++"
apt-get update
apt-get -y install --no-install-recommends $STATIC_PACKAGES $BUILD_PACKAGES
git clone https://github.com/jketterl/js8py.git
pushd js8py
git checkout 0.1.0
python3 setup.py install
popd
rm -rf js8py
git clone https://github.com/jketterl/csdr.git
cd csdr
git checkout 0.17.0
autoreconf -i
./configure
make
make install
cd ..
rm -rf csdr
git clone https://github.com/jketterl/digiham.git
cmakebuild digiham 0.3.0
apt-get -y purge --autoremove $BUILD_PACKAGES
apt-get clean
rm -rf /var/lib/apt/lists/*

View File

@ -1,12 +1,20 @@
#!/bin/bash #!/bin/bash
set -euo pipefail set -euo pipefail
if [[ ! -f /config/config_webrx.py ]] ; then mkdir -p /etc/openwebrx/
cp config_webrx.py /config mkdir -p /tmp/openwebrx/
if [[ ! -f /etc/openwebrx/config_webrx.py ]] ; then
sed 's/temporary_directory = "\/tmp"/temporary_directory = "\/tmp\/openwebrx"/' < "/opt/openwebrx/config_webrx.py" > "/etc/openwebrx/config_webrx.py"
fi
if [[ ! -f /etc/openwebrx/bands.json ]] ; then
cp bands.json /etc/openwebrx/
fi
if [[ ! -f /etc/openwebrx/bookmarks.json ]] ; then
cp bookmarks.json /etc/openwebrx/
fi
if [[ ! -f /etc/openwebrx/users.json ]] ; then
cp users.json /etc/openwebrx/
fi fi
rm config_webrx.py
ln -s /config/config_webrx.py .
_term() { _term() {

0
htdocs/__init__.py Normal file
View File

14
htdocs/css/admin.css Normal file
View File

@ -0,0 +1,14 @@
@import url("openwebrx-header.css");
@import url("openwebrx-globals.css");
.buttons {
text-align: right;
}
.row .map-input {
margin: 15px 15px 0;
}
.device {
margin-top: 20px;
}

12
htdocs/css/bootstrap.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,11 +1,6 @@
@import url("openwebrx-header.css"); @import url("openwebrx-header.css");
@import url("openwebrx-globals.css"); @import url("openwebrx-globals.css");
/* expandable photo not implemented on features page */
#webrx-top-photo-clip {
max-height: 67px;
}
h1 { h1 {
text-align: center; text-align: center;
margin: 50px 0; margin: 50px 0;

24
htdocs/css/login.css Normal file
View File

@ -0,0 +1,24 @@
@import url("openwebrx-header.css");
@import url("openwebrx-globals.css");
.login {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 500px;
padding: 20px;
border-radius: 10px;
border: 1px solid #575757;
box-shadow: 0 0 20px #000;
}
.login .btn {
width: 100%;
}
.btn-login {
height: 50px;
}

View File

@ -1,11 +1,6 @@
@import url("openwebrx-header.css"); @import url("openwebrx-header.css");
@import url("openwebrx-globals.css"); @import url("openwebrx-globals.css");
/* expandable photo not implemented on map page */
#webrx-top-photo-clip {
max-height: 67px;
}
body { body {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@ -6,3 +6,20 @@ html, body
font-family: "DejaVu Sans", Verdana, Geneva, sans-serif; font-family: "DejaVu Sans", Verdana, Geneva, sans-serif;
} }
.sprite {
background-image: url(../gfx/openwebrx-sprites.png);
display: inline-block;
}
.openwebrx-button.highlighted .sprite {
background-image: linear-gradient(rgba(255,127,0,0.5), rgba(255,127,0,0.5)), url(../gfx/openwebrx-sprites.png);
background-blend-mode: overlay;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and (min-device-pixel-ratio: 2) {
.sprite {
background-image: url(../gfx/openwebrx-sprites-2x.png);
background-size: 198px 77px;
}
}

View File

@ -2,6 +2,7 @@
{ {
position: relative; position: relative;
z-index:1000; z-index:1000;
background-color: #575757;
} }
#webrx-top-photo #webrx-top-photo
@ -13,7 +14,8 @@
#webrx-top-photo-clip #webrx-top-photo-clip
{ {
min-height: 67px; min-height: 67px;
max-height: 350px; max-height: 67px;
height: 350px;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
} }
@ -41,22 +43,24 @@
right: 0; right: 0;
} }
#webrx-tob-container, #webrx-top-container * {
line-height: initial;
box-sizing: initial;
}
#webrx-top-container img {
vertical-align: initial;
}
#webrx-top-logo #webrx-top-logo
{ {
padding: 12px; padding: 12px;
float: left; float: left;
} }
#webrx-ha5kfu-top-logo
{
float: right;
padding: 15px;
}
#webrx-rx-avatar #webrx-rx-avatar
{ {
background-color: rgba(154, 154, 154, .5); background-color: rgba(154, 154, 154, .5);
border-radius: 7px;
float: left; float: left;
margin: 7px; margin: 7px;
@ -107,46 +111,38 @@
cursor:pointer; cursor:pointer;
position: absolute; position: absolute;
left: 470px; left: 470px;
top: 51px; top: 55px;
} }
#openwebrx-rx-details-arrow a #openwebrx-rx-details-arrow a
{ {
margin: 0; margin: 0;
padding: 0; padding: 0;
line-height: 0;
display: block;
} }
#openwebrx-rx-details-arrow-down #openwebrx-main-buttons .button {
{ display: block;
display:none; width: 55px;
}
#openwebrx-main-buttons ul
{
display: table;
margin:0;
}
#openwebrx-main-buttons ul li
{
display: table-cell;
padding-left: 5px;
padding-right: 5px;
cursor:pointer; cursor:pointer;
} }
#openwebrx-main-buttons .button img {
height: 38px;
}
#openwebrx-main-buttons a { #openwebrx-main-buttons a {
color: inherit; color: inherit;
text-decoration: inherit; text-decoration: inherit;
} }
#openwebrx-main-buttons li:hover #openwebrx-main-buttons .button:hover
{ {
background-color: rgba(255, 255, 255, 0.3); background-color: rgba(255, 255, 255, 0.3);
} }
#openwebrx-main-buttons li:active #openwebrx-main-buttons .button:active
{ {
background-color: rgba(255, 255, 255, 0.55); background-color: rgba(255, 255, 255, 0.55);
} }
@ -154,6 +150,9 @@
#openwebrx-main-buttons #openwebrx-main-buttons
{ {
padding: 5px 15px;
display: flex;
list-style: none;
float: right; float: right;
margin:0; margin:0;
color: white; color: white;
@ -193,3 +192,44 @@
text-shadow: none; text-shadow: none;
} }
.sprite-panel-status {
background-position: 0 0;
width: 44px;
height: 38px;
}
.sprite-panel-log {
background-position: -44px 0;
width: 38px;
height: 38px;
}
.sprite-panel-receiver {
background-position: -82px 0;
width: 40px;
height: 38px;
}
.sprite-panel-map {
background-position: -122px 0;
width: 38px;
height: 38px;
}
.sprite-panel-settings {
background-position: -160px 0;
width: 38px;
height: 38px;
}
.sprite-rx-details-arrow-down {
background-position: 0 -65px;
width: 43px;
height: 12px;
}
.sprite-rx-details-arrow-up {
background-position: -43px -65px;
width: 43px;
height: 12px;
}

View File

@ -3,6 +3,7 @@
This file is part of OpenWebRX, This file is part of OpenWebRX,
an open-source SDR receiver software with a web UI. an open-source SDR receiver software with a web UI.
Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu> Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu>
Copyright (c) 2019-2020 by Jakob Ketterl <dd5jfk@darc.de>
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as it under the terms of the GNU Affero General Public License as
@ -149,6 +150,10 @@ input[type=range]:focus::-ms-fill-upper
background: #B6B6B6; background: #B6B6B6;
} }
input[type=range]:disabled {
opacity: 0.5;
}
#webrx-page-container #webrx-page-container
{ {
height: 100%; height: 100%;
@ -170,6 +175,7 @@ input[type=range]:focus::-ms-fill-upper
background-repeat: repeat-x; background-repeat: repeat-x;
background-size: cover; background-size: cover;
background-color: #444; background-color: #444;
z-index: 1001;
} }
#openwebrx-bookmarks-container #openwebrx-bookmarks-container
@ -258,16 +264,34 @@ input[type=range]:focus::-ms-fill-upper
border-top-color: #0F0; border-top-color: #0F0;
} }
#webrx-canvas-container #webrx-canvas-background {
{
flex-grow: 1; flex-grow: 1;
position: relative;
overflow: hidden;
background-image: url('../gfx/openwebrx-background-cool-blue.png'); background-image: url('../gfx/openwebrx-background-cool-blue.png');
background-repeat: no-repeat; background-repeat: no-repeat;
background-color: #1e5f7f; background-color: #1e5f7f;
background-size: cover; background-size: cover;
display: flex;
flex-direction: column;
}
@supports(background-image: -webkit-image-set(url('../gfx/openwebrx-background-cool-blue.webp') 1x)) {
#webrx-canvas-background {
background-image: -webkit-image-set(url('../gfx/openwebrx-background-cool-blue.webp') 1x);
}
}
@supports(background-image: image-set(url('../gfx/openwebrx-background-cool-blue.webp') 1x)) {
#webrx-canvas-background {
background-image: image-set(url('../gfx/openwebrx-background-cool-blue.webp') 1x);
}
}
#webrx-canvas-container
{
position: relative;
overflow: visible;
cursor: crosshair; cursor: crosshair;
flex-grow: 1;
} }
#webrx-canvas-container canvas #webrx-canvas-container canvas
@ -276,14 +300,8 @@ input[type=range]:focus::-ms-fill-upper
border-style: none; border-style: none;
image-rendering: crisp-edges; image-rendering: crisp-edges;
image-rendering: -webkit-optimize-contrast; image-rendering: -webkit-optimize-contrast;
/*transition: left 200ms, width 200ms;*/ width: 100%;
} height: 200px;
#openwebrx-mathbox-container
{
flex-grow: 1;
overflow: none;
display: none;
} }
#openwebrx-log-scroll #openwebrx-log-scroll
@ -302,57 +320,50 @@ input[type=range]:focus::-ms-fill-upper
color: #ff6262; color: #ff6262;
} }
/*#webrx-freq-show
{
visibility: hidden;
position: absolute;
top: 0px;
left: 0px;
padding: 5px;
font-weight: bold;
border-radius: 10px;
-moz-border-radius: 10px;
background-color: #999999;
color: White;
z-index:9999; /*should be higher?
}*/
/* removed non-free fonts like that: */
/*@font-face {
font-family: 'unibody_8_pro_regregular';
src: url('../gfx/unibody8pro-regular-webfont.eot');
src: url('../gfx/unibody8pro-regular-webfont.ttf');
font-weight: normal;
font-style: normal;
}*/
@font-face { @font-face {
font-family: 'expletus-sans-medium'; font-family: 'roboto-mono';
src: url('../gfx/font-expletus-sans/ExpletusSans-Medium.ttf'); src: url('../fonts/RobotoMono-Regular.woff2') format('woff2'),
url('../fonts/RobotoMono-Regular.woff') format('woff'),
url('../fonts/RobotoMono-Regular.ttf') format('truetype');
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
} }
#webrx-actual-freq .webrx-actual-freq {
{
width: 100%; width: 100%;
text-align: left; text-align: left;
font-size: 16pt;
font-family: 'expletus-sans-medium';
padding: 0; padding: 0;
margin: 0; margin: 0;
line-height:22px; display: flex;
flex-direction: row;
} }
#webrx-mouse-freq .webrx-actual-freq > * {
{ flex: 1;
}
.webrx-actual-freq input {
font-family: 'roboto-mono';
width: 0;
box-sizing: border-box;
border: 0;
padding: 0;
background-color: inherit;
color: inherit;
}
.webrx-actual-freq, .webrx-actual-freq input {
font-size: 16pt;
font-family: 'roboto-mono';
line-height: 22px;
}
.webrx-mouse-freq {
width: 100%; width: 100%;
text-align: left; text-align: left;
font-size: 10pt; font-size: 10pt;
color: #AAA; color: #AAA;
font-family: 'expletus-sans-medium'; font-family: 'roboto-mono';
margin-bottom: 5px; margin-bottom: 5px;
} }
@ -363,6 +374,8 @@ input[type=range]:focus::-ms-fill-upper
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: flex-end; justify-content: flex-end;
height: 0;
overflow: visible;
} }
#openwebrx-panels-container-left { #openwebrx-panels-container-left {
@ -385,6 +398,7 @@ input[type=range]:focus::-ms-fill-upper
border-radius: 15px; border-radius: 15px;
-moz-border-radius: 15px; -moz-border-radius: 15px;
margin: 5.9px; margin: 5.9px;
box-sizing: content-box;
} }
.openwebrx-panel a .openwebrx-panel a
@ -421,7 +435,7 @@ input[type=range]:focus::-ms-fill-upper
display: inline-block; display: inline-block;
} }
.openwebrx-button:hover, .openwebrx-demodulator-button.highlighted .openwebrx-button:hover, .openwebrx-demodulator-button.highlighted, .openwebrx-button.highlighted
{ {
/*background:-webkit-gradient( linear, left top, left bottom, color-stop(0.0 , #3F3F3F), color-stop(1, #777777) ); /*background:-webkit-gradient( linear, left top, left bottom, color-stop(0.0 , #3F3F3F), color-stop(1, #777777) );
background:-moz-linear-gradient( center top, #373737 5%, #4F4F4F 100% );*/ background:-moz-linear-gradient( center top, #373737 5%, #4F4F4F 100% );*/
@ -439,9 +453,12 @@ input[type=range]:focus::-ms-fill-upper
margin-right: 0; margin-right: 0;
} }
.openwebrx-button.disabled {
opacity: 0.5;
}
.openwebrx-demodulator-button .openwebrx-demodulator-button
{ {
width: 38px;
height: 19px; height: 19px;
font-size: 12pt; font-size: 12pt;
text-align: center; text-align: center;
@ -449,6 +466,10 @@ input[type=range]:focus::-ms-fill-upper
margin-right: 5px; margin-right: 5px;
} }
.openwebrx-demodulator-button.same-mod {
color: #FFC;
}
.openwebrx-square-button img .openwebrx-square-button img
{ {
height: 27px; height: 27px;
@ -612,6 +633,31 @@ img.openwebrx-mirror-img
padding-top: 0; padding-top: 0;
} }
.openwebrx-modes-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: -5px -5px 0 0;
}
.openwebrx-modes-grid .openwebrx-demodulator-button {
margin: 0;
white-space: nowrap;
flex: 1 0 38px;
margin: 5px 5px 0 0;
}
@supports(gap: 5px) {
.openwebrx-modes-grid {
margin: 0;
gap: 5px;
}
.openwebrx-modes-grid .openwebrx-demodulator-button {
margin: 0;
}
}
#openwebrx-smeter-outer #openwebrx-smeter-outer
{ {
border-color: #888; border-color: #888;
@ -642,11 +688,10 @@ img.openwebrx-mirror-img
float: right; float: right;
margin-right: 5px; margin-right: 5px;
margin-top: 24px; margin-top: 24px;
font-family: 'expletus-sans-medium'; font-family: 'roboto-mono';
} }
#openwebrx-big-grey .openwebrx-overlay {
{
position: fixed; position: fixed;
width: 100%; width: 100%;
height: 100%; height: 100%;
@ -657,21 +702,36 @@ img.openwebrx-mirror-img
left: 0; left: 0;
top: 0; top: 0;
z-index: 1001; z-index: 1001;
display: none;
vertical-align: middle;
text-align: center;
color: white; color: white;
font-weight: bold; font-weight: bold;
font-size: 20pt; font-size: 20pt;
}
#openwebrx-autoplay-overlay
{
cursor: pointer; cursor: pointer;
transition: opacity 0.3s linear; transition: opacity 0.3s linear;
} }
#openwebrx-big-grey img #openwebrx-autoplay-overlay img
{ {
width: 150px; width: 150px;
} }
.openwebrx-overlay .overlay-content {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
text-align: center;
}
#openwebrx-error-overlay .overlay-content {
background-color: #000;
padding: 50px;
border-radius: 20px;
}
#openwebrx-digimode-canvas-container #openwebrx-digimode-canvas-container
{ {
/*margin: -10px -10px 10px -10px;*/ /*margin: -10px -10px 10px -10px;*/
@ -713,8 +773,7 @@ img.openwebrx-mirror-img
color: White; color: White;
} }
#openwebrx-secondary-demod-listbox .openwebrx-secondary-demod-listbox {
{
width: 173px; width: 173px;
height: 27px; height: 27px;
padding-left:3px; padding-left:3px;
@ -913,32 +972,23 @@ img.openwebrx-mirror-img
display: inline-block; display: inline-block;
} }
#openwebrx-panel-wsjt-message, .openwebrx-message-panel {
#openwebrx-panel-packet-message
{
height: 180px; height: 180px;
} }
#openwebrx-panel-wsjt-message tbody, .openwebrx-message-panel tbody {
#openwebrx-panel-packet-message tbody
{
display: block; display: block;
overflow: auto; overflow: auto;
height: 150px; height: 150px;
width: 100%; width: 100%;
} }
#openwebrx-panel-wsjt-message thead tr, .openwebrx-message-panel thead tr {
#openwebrx-panel-packet-message thead tr
{
display: block; display: block;
} }
#openwebrx-panel-wsjt-message th, .openwebrx-message-panel th,
#openwebrx-panel-wsjt-message td, .openwebrx-message-panel td {
#openwebrx-panel-packet-message th,
#openwebrx-panel-packet-message td
{
width: 50px; width: 50px;
text-align: left; text-align: left;
padding: 1px 3px; padding: 1px 3px;
@ -957,8 +1007,34 @@ img.openwebrx-mirror-img
width: 70px; width: 70px;
} }
#openwebrx-panel-js8-message .message {
width: 465px;
max-width: 465px;
}
#openwebrx-panel-js8-message td.message {
white-space: nowrap;
overflow: hidden;
display: flex;
flex-direction: row-reverse;
}
#openwebrx-panel-js8-message .message div {
flex: 1;
}
#openwebrx-panel-js8-message .decimal {
text-align: right;
width: 35px;
}
#openwebrx-panel-js8-message .decimal.freq {
width: 70px;
}
#openwebrx-panel-packet-message .message { #openwebrx-panel-packet-message .message {
width: 410px; width: 410px;
max-width: 410px;
} }
#openwebrx-panel-packet-message .callsign { #openwebrx-panel-packet-message .callsign {
@ -970,6 +1046,16 @@ img.openwebrx-mirror-img
text-align: center; text-align: center;
} }
#openwebrx-panel-pocsag-message .address {
width: 100px;
}
#openwebrx-panel-pocsag-message .message {
width: 486px;
max-width: 486px;
white-space: pre;
}
.aprs-symbol { .aprs-symbol {
display: inline-block; display: inline-block;
width: 15px; width: 15px;
@ -1051,12 +1137,16 @@ img.openwebrx-mirror-img
#openwebrx-panel-digimodes[data-mode="jt9"] #openwebrx-digimode-content-container, #openwebrx-panel-digimodes[data-mode="jt9"] #openwebrx-digimode-content-container,
#openwebrx-panel-digimodes[data-mode="ft4"] #openwebrx-digimode-content-container, #openwebrx-panel-digimodes[data-mode="ft4"] #openwebrx-digimode-content-container,
#openwebrx-panel-digimodes[data-mode="packet"] #openwebrx-digimode-content-container, #openwebrx-panel-digimodes[data-mode="packet"] #openwebrx-digimode-content-container,
#openwebrx-panel-digimodes[data-mode="pocsag"] #openwebrx-digimode-content-container,
#openwebrx-panel-digimodes[data-mode="js8"] #openwebrx-digimode-content-container,
#openwebrx-panel-digimodes[data-mode="ft8"] #openwebrx-digimode-select-channel, #openwebrx-panel-digimodes[data-mode="ft8"] #openwebrx-digimode-select-channel,
#openwebrx-panel-digimodes[data-mode="wspr"] #openwebrx-digimode-select-channel, #openwebrx-panel-digimodes[data-mode="wspr"] #openwebrx-digimode-select-channel,
#openwebrx-panel-digimodes[data-mode="jt65"] #openwebrx-digimode-select-channel, #openwebrx-panel-digimodes[data-mode="jt65"] #openwebrx-digimode-select-channel,
#openwebrx-panel-digimodes[data-mode="jt9"] #openwebrx-digimode-select-channel, #openwebrx-panel-digimodes[data-mode="jt9"] #openwebrx-digimode-select-channel,
#openwebrx-panel-digimodes[data-mode="ft4"] #openwebrx-digimode-select-channel, #openwebrx-panel-digimodes[data-mode="ft4"] #openwebrx-digimode-select-channel,
#openwebrx-panel-digimodes[data-mode="packet"] #openwebrx-digimode-select-channel #openwebrx-panel-digimodes[data-mode="packet"] #openwebrx-digimode-select-channel,
#openwebrx-panel-digimodes[data-mode="pocsag"] #openwebrx-digimode-select-channel,
#openwebrx-panel-digimodes[data-mode="js8"] #openwebrx-digimode-select-channel
{ {
display: none; display: none;
} }
@ -1066,8 +1156,83 @@ img.openwebrx-mirror-img
#openwebrx-panel-digimodes[data-mode="jt65"] #openwebrx-digimode-canvas-container, #openwebrx-panel-digimodes[data-mode="jt65"] #openwebrx-digimode-canvas-container,
#openwebrx-panel-digimodes[data-mode="jt9"] #openwebrx-digimode-canvas-container, #openwebrx-panel-digimodes[data-mode="jt9"] #openwebrx-digimode-canvas-container,
#openwebrx-panel-digimodes[data-mode="ft4"] #openwebrx-digimode-canvas-container, #openwebrx-panel-digimodes[data-mode="ft4"] #openwebrx-digimode-canvas-container,
#openwebrx-panel-digimodes[data-mode="packet"] #openwebrx-digimode-canvas-container #openwebrx-panel-digimodes[data-mode="packet"] #openwebrx-digimode-canvas-container,
#openwebrx-panel-digimodes[data-mode="pocsag"] #openwebrx-digimode-canvas-container,
#openwebrx-panel-digimodes[data-mode="js8"] #openwebrx-digimode-canvas-container
{ {
height: 200px; height: 200px;
margin: -10px; margin: -10px;
} }
.sprite-zoom-in {
background-position: 0 -38px;
width: 27px;
height: 27px;
}
.sprite-zoom-out {
background-position: -27px -38px;
width: 27px;
height: 27px;
}
.sprite-zoom-in-total {
background-position: -54px -38px;
width: 24px;
height: 27px;
}
.sprite-zoom-out-total {
background-position: -78px -38px;
width: 25px;
height: 27px;
}
.sprite-edit {
background-position: -131px -51px;
width: 14px;
height: 14px;
}
.sprite-trashcan {
background-position: -145px -38px;
width: 14px;
height: 14px;
}
.sprite-speaker {
width: 14px;
height: 15px;
}
#openwebrx-mute-on .sprite-speaker {
background-position: -117px -38px;
}
#openwebrx-mute-off .sprite-speaker {
background-position: -103px -38px;
}
.sprite-squelch {
background-position: -131px -38px;
width: 14px;
height: 13px;
}
.sprite-waterfall-auto {
background-position: -103px -53px;
width: 14px;
height: 11px;
}
.sprite-waterfall-default {
background-position: -117px -53px;
width: 14px;
height: 12px;
}
.sprite-bookmark {
background-position: -159px -38px;
width: 21px;
height: 27px;
}

View File

@ -1,9 +1,12 @@
<HTML><HEAD> <HTML><HEAD>
<TITLE>OpenWebRX Feature report</TITLE> <TITLE>OpenWebRX Feature report</TITLE>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <link rel="shortcut icon" type="image/x-icon" href="static/favicon.ico" />
<link rel="stylesheet" href="static/css/bootstrap.min.css" />
<link rel="stylesheet" type="text/css" href="static/css/admin.css" />
<link rel="stylesheet" href="static/css/features.css"> <link rel="stylesheet" href="static/css/features.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/1.9.0/showdown.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/1.9.0/showdown.min.js"></script>
<script src="static/lib/jquery-3.2.1.min.js"></script> <script src="static/lib/jquery-3.2.1.min.js"></script>
<script src="static/lib/Header.js"></script>
<script src="static/features.js"></script> <script src="static/features.js"></script>
</HEAD><BODY> </HEAD><BODY>
${header} ${header}

View File

@ -1,6 +1,6 @@
$(function(){ $(function(){
var converter = new showdown.Converter(); var converter = new showdown.Converter();
$.ajax('/api/features').done(function(data){ $.ajax('api/features').done(function(data){
var $table = $('table.features'); var $table = $('table.features');
$.each(data, function(name, details) { $.each(data, function(name, details) {
var requirements = $.map(details.requirements, function(r, name){ var requirements = $.map(details.requirements, function(r, name){

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,20 @@
<!DOCTYPE HTML>
<html>
<head>
<title>OpenWebRX Settings</title>
<link rel="shortcut icon" type="image/x-icon" href="static/favicon.ico" />
<link rel="stylesheet" href="static/css/bootstrap.min.css" />
<link rel="stylesheet" type="text/css" href="static/css/admin.css" />
<script src="https://unpkg.com/location-picker/dist/location-picker.min.js"></script>
<script src="compiled/settings.js"></script>
<meta charset="utf-8">
</head>
<body>
${header}
<div class="container">
<div class="col-12">
<h1>General settings</h1>
</div>
${sections}
</div>
</body>

View File

@ -1,93 +0,0 @@
Copyright (c) 2011, Jasper de Waard (jasper@designtown.nl),
with Reserved Font Name "Expletus Sans".
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@ -1,25 +1,23 @@
<div id="webrx-top-container"> <div id="webrx-top-container">
<div id="webrx-top-photo-clip"> <div id="webrx-top-photo-clip">
<img src="static/gfx/openwebrx-top-photo.jpg" id="webrx-top-photo"/> <img src="static/gfx/openwebrx-top-photo.jpg" id="webrx-top-photo" alt="Receiver panorama"/>
<div id="webrx-top-bar" class="webrx-top-bar-parts"> <div id="webrx-top-bar" class="webrx-top-bar-parts">
<a href="https://sdr.hu/openwebrx" target="_blank"><img src="static/gfx/openwebrx-top-logo.png" id="webrx-top-logo" /></a> <a href="https://www.openwebrx.de/" target="_blank"><img src="static/gfx/openwebrx-top-logo.png" id="webrx-top-logo" alt="OpenWebRX Logo"/></a>
<a href="http://ha5kfu.sch.bme.hu/" target="_blank"><img src="static/gfx/openwebrx-ha5kfu-top-logo.png" id="webrx-ha5kfu-top-logo" /></a> <img id="webrx-rx-avatar" class="openwebrx-photo-trigger" src="static/gfx/openwebrx-avatar.png" alt="Receiver avatar"/>
<img id="webrx-rx-avatar" class="openwebrx-photo-trigger" src="static/gfx/openwebrx-avatar.png"/>
<div id="webrx-rx-texts"> <div id="webrx-rx-texts">
<div id="webrx-rx-title" class="openwebrx-photo-trigger"></div> <div id="webrx-rx-title" class="openwebrx-photo-trigger"></div>
<div id="webrx-rx-desc" class="openwebrx-photo-trigger"></div> <div id="webrx-rx-desc" class="openwebrx-photo-trigger"></div>
</div> </div>
<div id="openwebrx-rx-details-arrow"> <div id="openwebrx-rx-details-arrow">
<a id="openwebrx-rx-details-arrow-up" class="openwebrx-photo-trigger"><img src="static/gfx/openwebrx-rx-details-arrow-up.png" /></a> <a id="openwebrx-rx-details-arrow-up" class="openwebrx-photo-trigger" style="display: none;"><span class="sprite sprite-rx-details-arrow-up"></span></a>
<a id="openwebrx-rx-details-arrow-down" class="openwebrx-photo-trigger"><img src="static/gfx/openwebrx-rx-details-arrow.png" /></a> <a id="openwebrx-rx-details-arrow-down" class="openwebrx-photo-trigger"><span class="sprite sprite-rx-details-arrow-down"></span></a>
</div> </div>
<section id="openwebrx-main-buttons"> <section id="openwebrx-main-buttons">
<ul> <div class="button" data-toggle-panel="openwebrx-panel-status"><span class="sprite sprite-panel-status"></span><br/>Status</div>
<li data-toggle-panel="openwebrx-panel-status"><img src="static/gfx/openwebrx-panel-status.png" /><br/>Status</li> <div class="button" data-toggle-panel="openwebrx-panel-log"><span class="sprite sprite-panel-log"></span><br/>Log</div>
<li data-toggle-panel="openwebrx-panel-log"><img src="static/gfx/openwebrx-panel-log.png" /><br/>Log</li> <div class="button" data-toggle-panel="openwebrx-panel-receiver"><span class="sprite sprite-panel-receiver"></span><br/>Receiver</div>
<li data-toggle-panel="openwebrx-panel-receiver"><img src="static/gfx/openwebrx-panel-receiver.png" /><br/>Receiver</li> <a class="button" href="map" target="openwebrx-map"><span class="sprite sprite-panel-map"></span><br/>Map</a>
<li><a href="/map" target="_blank"><img src="static/gfx/openwebrx-panel-map.png" /><br/>Map</a></li> ${settingslink}
</ul>
</section> </section>
</div> </div>
<div id="webrx-rx-photo-title"></div> <div id="webrx-rx-photo-title"></div>

View File

@ -4,6 +4,7 @@
This file is part of OpenWebRX, This file is part of OpenWebRX,
an open-source SDR receiver software with a web UI. an open-source SDR receiver software with a web UI.
Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu> Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu>
Copyright (c) 2019-2020 by Jakob Ketterl <dd5jfk@darc.de>
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as it under the terms of the GNU Affero General Public License as
@ -22,15 +23,8 @@
<html> <html>
<head> <head>
<title>OpenWebRX | Open Source SDR Web App for Everyone!</title> <title>OpenWebRX | Open Source SDR Web App for Everyone!</title>
<script src="static/sdr.js"></script> <link rel="shortcut icon" type="image/x-icon" href="static/favicon.ico" />
<script src="static/mathbox-bundle.min.js"></script> <script src="compiled/receiver.js"></script>
<script src="static/openwebrx.js"></script>
<script src="static/lib/jquery-3.2.1.min.js"></script>
<script src="static/lib/jquery.nanoscroller.js"></script>
<script src="static/lib/BookmarkBar.js"></script>
<script src="static/lib/AudioEngine.js"></script>
<script src="static/lib/ProgressBar.js"></script>
<script src="static/lib/Measurement.js"></script>
<link rel="stylesheet" type="text/css" href="static/lib/nanoscroller.css" /> <link rel="stylesheet" type="text/css" href="static/lib/nanoscroller.css" />
<link rel="stylesheet" type="text/css" href="static/css/openwebrx.css" /> <link rel="stylesheet" type="text/css" href="static/css/openwebrx.css" />
<meta charset="utf-8"> <meta charset="utf-8">
@ -44,16 +38,13 @@
<canvas id="openwebrx-scale-canvas" width="0" height="0"></canvas> <canvas id="openwebrx-scale-canvas" width="0" height="0"></canvas>
</div> </div>
</div> </div>
<div id="openwebrx-mathbox-container"> </div> <div id="webrx-canvas-background">
<div id="webrx-canvas-container"> <div id="webrx-canvas-container">
<!-- add canvas here by javascript --> <!-- add canvas here by javascript -->
</div> </div>
</div>
<div id="openwebrx-panels-container"> <div id="openwebrx-panels-container">
<div id="openwebrx-panels-container-left"> <div id="openwebrx-panels-container-left">
<div class="openwebrx-panel" data-panel-name="client-under-devel" style="width: 245px; background-color: Red;">
<span style="font-size: 15pt; font-weight: bold;">Under construction</span>
<br />We're working on the code right now, so the application might fail.
</div>
<div class="openwebrx-panel" id="openwebrx-panel-digimodes" style="display: none; width: 619px;" data-panel-name="digimodes"> <div class="openwebrx-panel" id="openwebrx-panel-digimodes" style="display: none; width: 619px;" data-panel-name="digimodes">
<div id="openwebrx-digimode-canvas-container"> <div id="openwebrx-digimode-canvas-container">
<div id="openwebrx-digimode-select-channel"></div> <div id="openwebrx-digimode-select-channel"></div>
@ -65,7 +56,7 @@
</div> </div>
</div> </div>
</div> </div>
<table class="openwebrx-panel" id="openwebrx-panel-wsjt-message" style="display: none; width: 619px;" data-panel-name="wsjt-message"> <table class="openwebrx-panel openwebrx-message-panel" id="openwebrx-panel-wsjt-message" style="display: none; width: 619px;" data-panel-name="wsjt-message">
<thead><tr> <thead><tr>
<th>UTC</th> <th>UTC</th>
<th class="decimal">dB</th> <th class="decimal">dB</th>
@ -75,7 +66,15 @@
</tr></thead> </tr></thead>
<tbody></tbody> <tbody></tbody>
</table> </table>
<table class="openwebrx-panel" id="openwebrx-panel-packet-message" style="display: none; width: 619px;" data-panel-name="aprs-message"> <table class="openwebrx-panel openwebrx-message-panel" id="openwebrx-panel-js8-message" style="display:none; width: 619px;" data-panel-name="js8-message">
<thead><tr>
<th>UTC</th>
<th class="decimal freq">Freq</th>
<th class="message">Message</th>
</tr></thead>
<tbody></tbody>
</table>
<table class="openwebrx-panel openwebrx-message-panel" id="openwebrx-panel-packet-message" style="display: none; width: 619px;" data-panel-name="aprs-message">
<thead><tr> <thead><tr>
<th>UTC</th> <th>UTC</th>
<th class="callsign">Callsign</th> <th class="callsign">Callsign</th>
@ -84,6 +83,13 @@
</tr></thead> </tr></thead>
<tbody></tbody> <tbody></tbody>
</table> </table>
<table class="openwebrx-panel openwebrx-message-panel" id="openwebrx-panel-pocsag-message" style="display: none; width: 619px;" data-panel-name="pocsag-message">
<thead><tr>
<th class="address">Address</th>
<th class="message">Message</th>
</tr></thead>
<tbody></tbody>
</table>
<div class="openwebrx-panel openwebrx-meta-panel" id="openwebrx-panel-metadata-ysf" style="display: none;" data-panel-name="metadata-ysf"> <div class="openwebrx-panel openwebrx-meta-panel" id="openwebrx-panel-metadata-ysf" style="display: none;" data-panel-name="metadata-ysf">
<div class="openwebrx-meta-frame"> <div class="openwebrx-meta-frame">
<div class="openwebrx-meta-slot"> <div class="openwebrx-meta-slot">
@ -116,93 +122,58 @@
<div class="openwebrx-panel" id="openwebrx-panel-log" data-panel-name="debug" style="width: 619px;"> <div class="openwebrx-panel" id="openwebrx-panel-log" data-panel-name="debug" style="width: 619px;">
<div class="openwebrx-panel-inner nano" id="openwebrx-log-scroll"> <div class="openwebrx-panel-inner nano" id="openwebrx-log-scroll">
<div class="nano-content"> <div class="nano-content">
<div id="openwebrx-client-log-title">OpenWebRX client log</strong></div> <div id="openwebrx-client-log-title">OpenWebRX client log</div>
<span id="openwebrx-client-1">Author: </span><a href="http://blog.sdr.hu/about" target="_blank">András Retzler, HA7ILM</a><br />You can support OpenWebRX development via <a href="http://blog.sdr.hu/support" target="_blank">PayPal!</a><br/> <div>
Author contact: <a href="http://www.justjakob.de/" target="_blank">Jakob Ketterl, DD5JFK</a> |
<a href="https://www.openwebrx.de" target="_blank">OpenWebRX homepage</a>
</div>
<div>Support and information: <a href="https://groups.io/g/openwebrx" target="_blank">Groups.io Mailinglist</a></div>
<div id="openwebrx-debugdiv"></div> <div id="openwebrx-debugdiv"></div>
</div> </div>
</div> </div>
</div> </div>
<div class="openwebrx-panel" id="openwebrx-panel-status" data-panel-name="status" style="width: 615px;" data-panel-transparent="true"> <div class="openwebrx-panel" id="openwebrx-panel-status" data-panel-name="status" style="width: 615px;" data-panel-transparent="true">
<div class="openwebrx-progressbar" id="openwebrx-bar-audio-buffer"> <span class="openwebrx-progressbar-text">Audio buffer [0 ms]</span><div class="openwebrx-progressbar-bar"></div></div> <div class="openwebrx-progressbar" id="openwebrx-bar-audio-buffer" data-type="audiobuffer"></div>
<div class="openwebrx-progressbar" id="openwebrx-bar-audio-output"> <span class="openwebrx-progressbar-text">Audio output [0 sps]</span><div class="openwebrx-progressbar-bar"></div></div> <div class="openwebrx-progressbar" id="openwebrx-bar-audio-output" data-type="audiooutput"></div>
<div class="openwebrx-progressbar" id="openwebrx-bar-audio-speed"> <span class="openwebrx-progressbar-text">Audio stream [0 kbps]</span><div class="openwebrx-progressbar-bar"></div></div> <div class="openwebrx-progressbar" id="openwebrx-bar-audio-speed" data-type="audiospeed"></div>
<div class="openwebrx-progressbar" id="openwebrx-bar-network-speed"> <span class="openwebrx-progressbar-text">Network usage [0 kbps]</span><div class="openwebrx-progressbar-bar"></div></div> <div class="openwebrx-progressbar" id="openwebrx-bar-network-speed" data-type="networkspeed"></div>
<div class="openwebrx-progressbar" id="openwebrx-bar-server-cpu"> <span class="openwebrx-progressbar-text">Server CPU [0%]</span><div class="openwebrx-progressbar-bar"></div></div> <div class="openwebrx-progressbar" id="openwebrx-bar-server-cpu" data-type="cpu"></div>
<div class="openwebrx-progressbar" id="openwebrx-bar-clients"> <span class="openwebrx-progressbar-text">Clients [1]</span><div class="openwebrx-progressbar-bar"></div></div> <div class="openwebrx-progressbar" id="openwebrx-bar-clients" data-type="clients"></div>
</div> </div>
</div> </div>
<div id="openwebrx-panels-container-right"> <div id="openwebrx-panels-container-right">
<div class="openwebrx-panel" id="openwebrx-panel-receiver" data-panel-name="client-params" style="width: 259px;"> <div class="openwebrx-panel" id="openwebrx-panel-receiver" data-panel-name="client-params" style="width: 259px;">
<div class="openwebrx-panel-line frequencies-container"> <div class="openwebrx-panel-line frequencies-container">
<div class="frequencies"> <div class="frequencies">
<div id="webrx-actual-freq">---.--- MHz</div> <div class="webrx-actual-freq"></div>
<div id="webrx-mouse-freq">---.--- MHz</div> <div class="webrx-mouse-freq"></div>
</div> </div>
<div class="openwebrx-button openwebrx-square-button openwebrx-bookmark-button" style="display:none;" title="Add bookmark..."> <div class="openwebrx-button openwebrx-square-button openwebrx-bookmark-button" style="display:none;" title="Add bookmark...">
<img src="static/gfx/openwebrx-bookmark.png"> <span class="sprite sprite-bookmark"></span>
</div> </div>
</div> </div>
<div class="openwebrx-panel-line"> <div class="openwebrx-panel-line">
<select id="openwebrx-sdr-profiles-listbox" onchange="sdr_profile_changed();"> <select id="openwebrx-sdr-profiles-listbox" onchange="sdr_profile_changed();">
</select> </select>
</div> </div>
<div class="openwebrx-panel-line openwebrx-panel-flex-line"> <div class="openwebrx-modes openwebrx-panel-line"></div>
<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-nfm"
onclick="demodulator_analog_replace('nfm');">FM</div>
<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-am"
onclick="demodulator_analog_replace('am');">AM</div>
<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-lsb"
onclick="demodulator_analog_replace('lsb');">LSB</div>
<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-usb"
onclick="demodulator_analog_replace('usb');">USB</div>
<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-cw"
onclick="demodulator_analog_replace('cw');">CW</div>
</div>
<div class="openwebrx-panel-line openwebrx-panel-flex-line">
<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-dmr"
style="display:none;" data-feature="digital_voice_digiham"
onclick="demodulator_analog_replace('dmr');">DMR</div>
<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-dstar"
style="display:none;" data-feature="digital_voice_dsd"
onclick="demodulator_analog_replace('dstar');">DStar</div>
<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-nxdn"
style="display:none;" data-feature="digital_voice_dsd"
onclick="demodulator_analog_replace('nxdn');">NXDN</div>
<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-ysf"
style="display:none;" data-feature="digital_voice_digiham"
onclick="demodulator_analog_replace('ysf');">YSF</div>
</div>
<div class="openwebrx-panel-line openwebrx-panel-flex-line">
<div class="openwebrx-button openwebrx-demodulator-button" id="openwebrx-button-dig" onclick="demodulator_digital_replace_last();">DIG</div>
<select id="openwebrx-secondary-demod-listbox" onchange="secondary_demod_listbox_changed();">
<option value="none"></option>
<option value="bpsk31">BPSK31</option>
<option value="ft8" data-feature="wsjt-x">FT8</option>
<option value="wspr" data-feature="wsjt-x">WSPR</option>
<option value="jt65" data-feature="wsjt-x">JT65</option>
<option value="jt9" data-feature="wsjt-x">JT9</option>
<option value="ft4" data-feature="wsjt-x">FT4</option>
<option value="packet" data-feature="packet">Packet</option>
</select>
</div>
<div class="openwebrx-panel-line"> <div class="openwebrx-panel-line">
<div title="Mute on/off" id="openwebrx-mute-off" class="openwebrx-button" onclick="toggleMute();"><img src="static/gfx/openwebrx-speaker.png" class="openwebrx-sliderbtn-img" id="openwebrx-mute-img"></div> <div title="Mute on/off" id="openwebrx-mute-off" class="openwebrx-button" onclick="toggleMute();"><span class="sprite sprite-speaker openwebrx-sliderbtn-img"></span></div>
<input title="Volume" id="openwebrx-panel-volume" class="openwebrx-panel-slider" type="range" min="0" max="150" value="50" step="1" onchange="updateVolume()" oninput="updateVolume()"> <input title="Volume" id="openwebrx-panel-volume" class="openwebrx-panel-slider" type="range" min="0" max="150" value="50" step="1" onchange="updateVolume()" oninput="updateVolume()">
<div title="Auto-adjust waterfall colors" id="openwebrx-waterfall-colors-auto" class="openwebrx-button" onclick="waterfall_measure_minmax_now=true;"><img src="static/gfx/openwebrx-waterfall-auto.png" class="openwebrx-sliderbtn-img"></div> <div title="Auto-adjust waterfall colors (right-click for continuous)" id="openwebrx-waterfall-colors-auto" class="openwebrx-button"><span class="sprite sprite-waterfall-auto openwebrx-sliderbtn-img"></span></div>
<input title="Waterfall minimum level" id="openwebrx-waterfall-color-min" class="openwebrx-panel-slider" type="range" min="-200" max="100" value="50" step="1" onchange="updateWaterfallColors(0);" oninput="updateVolume()"> <input title="Waterfall minimum level" id="openwebrx-waterfall-color-min" class="openwebrx-panel-slider" type="range" min="-200" max="100" value="50" step="1" onchange="updateWaterfallColors(0);" oninput="updateVolume()">
</div> </div>
<div class="openwebrx-panel-line"> <div class="openwebrx-panel-line">
<div title="Auto-set squelch level" id="openwebrx-squelch-default" class="openwebrx-button" onclick="setSquelchToAuto()"><img src="static/gfx/openwebrx-squelch-button.png" class="openwebrx-sliderbtn-img"></div> <div title="Auto-set squelch level" class="openwebrx-squelch-default openwebrx-button"><span class="sprite sprite-squelch openwebrx-sliderbtn-img"></span></div>
<input title="Squelch" id="openwebrx-panel-squelch" class="openwebrx-panel-slider" type="range" min="-150" max="0" value="-150" step="1" onchange="updateSquelch()" oninput="updateSquelch()"> <input title="Squelch" class="openwebrx-squelch-slider openwebrx-panel-slider" type="range" min="-150" max="0" value="-150" step="1">
<div title="Set waterfall colors to default" id="openwebrx-waterfall-colors-default" class="openwebrx-button" onclick="waterfallColorsDefault()"><img src="static/gfx/openwebrx-waterfall-default.png" class="openwebrx-sliderbtn-img"></div> <div title="Set waterfall colors to default" id="openwebrx-waterfall-colors-default" class="openwebrx-button" onclick="waterfallColorsDefault()"><span class="sprite sprite-waterfall-default openwebrx-sliderbtn-img"></span></div>
<input title="Waterfall maximum level" id="openwebrx-waterfall-color-max" class="openwebrx-panel-slider" type="range" min="-200" max="100" value="50" step="1" onchange="updateWaterfallColors(1);" oninput="updateVolume()"> <input title="Waterfall maximum level" id="openwebrx-waterfall-color-max" class="openwebrx-panel-slider" type="range" min="-200" max="100" value="50" step="1" onchange="updateWaterfallColors(1);" oninput="updateVolume()">
</div> </div>
<div class="openwebrx-panel-line"> <div class="openwebrx-panel-line">
<div class="openwebrx-button openwebrx-square-button" onclick="zoomInOneStep();" title="Zoom in one step"> <img src="static/gfx/openwebrx-zoom-in.png" /></div> <div class="openwebrx-button openwebrx-square-button" onclick="zoomInOneStep();" title="Zoom in one step"><span class="sprite sprite-zoom-in"></span></div>
<div class="openwebrx-button openwebrx-square-button" onclick="zoomOutOneStep();" title="Zoom out one step"> <img src="static/gfx/openwebrx-zoom-out.png" /></div> <div class="openwebrx-button openwebrx-square-button" onclick="zoomOutOneStep();" title="Zoom out one step"><span class="sprite sprite-zoom-out"></span></div>
<div class="openwebrx-button openwebrx-square-button" onclick="zoomInTotal();" title="Zoom in totally"><img src="static/gfx/openwebrx-zoom-in-total.png" /></div> <div class="openwebrx-button openwebrx-square-button" onclick="zoomInTotal();" title="Zoom in totally"><span class="sprite sprite-zoom-in-total"></span></div>
<div class="openwebrx-button openwebrx-square-button" onclick="zoomOutTotal();" title="Zoom out totally"><img src="static/gfx/openwebrx-zoom-out-total.png" /></div> <div class="openwebrx-button openwebrx-square-button" onclick="zoomOutTotal();" title="Zoom out totally"><span class="sprite sprite-zoom-out-total"></span></div>
<div class="openwebrx-button openwebrx-square-button" onclick="mathbox_toggle();" title="Toggle 3D view"><img src="static/gfx/openwebrx-3d-spectrum.png" /></div>
<div id="openwebrx-smeter-db">0 dB</div> <div id="openwebrx-smeter-db">0 dB</div>
</div> </div>
<div class="openwebrx-panel-line"> <div class="openwebrx-panel-line">
@ -214,10 +185,17 @@
</div> </div>
</div> </div>
</div> </div>
<div id="openwebrx-big-grey" onclick="playButtonClick();"> <div id="openwebrx-autoplay-overlay" class="openwebrx-overlay" style="display:none;">
<div id="openwebrx-play-button-text"> <div class="overlay-content">
<img id="openwebrx-play-button" src="static/gfx/openwebrx-play-button.png" /> <img id="openwebrx-play-button" src="static/gfx/openwebrx-play-button.png" />
<br /><br />Start OpenWebRX <div>Start OpenWebRX</div>
</div>
</div>
<div id="openwebrx-error-overlay" class="openwebrx-overlay" style="display:none;">
<div class="overlay-content">
<div>This receiver is currently unavailable due to technical issues.</div>
<div>Error Message:</div>
<div class="errormessage"></div>
</div> </div>
</div> </div>
<div id="openwebrx-dialog-bookmark" class="openwebrx-dialog" style="display:none;"> <div id="openwebrx-dialog-bookmark" class="openwebrx-dialog" style="display:none;">
@ -232,17 +210,7 @@
</div> </div>
<div class="form-field"> <div class="form-field">
<label for="modulation">Modulation:</label> <label for="modulation">Modulation:</label>
<select name="modulation" id="modulation"> <select name="modulation" id="modulation"></select>
<option value="nfm">FM</option>
<option value="am">AM</option>
<option value="usb">USB</option>
<option value="lsb">LSB</option>
<option value="cw">CW</option>
<option value="dmr">DMR</option>
<option value="dstar">D-Star</option>
<option value="nxdn">NXDN</option>
<option value="ysf">YSF</option>
</select>
</div> </div>
<div class="buttons"> <div class="buttons">
<div class="openwebrx-button" data-action="cancel">Cancel</div> <div class="openwebrx-button" data-action="cancel">Cancel</div>

View File

@ -9,7 +9,7 @@ AprsMarker.prototype.draw = function() {
if (this.symbol) { if (this.symbol) {
var tableId = this.symbol.table === '/' ? 0 : 1; var tableId = this.symbol.table === '/' ? 0 : 1;
div.style.background = 'url(/aprs-symbols/aprs-symbols-24-' + tableId + '@2x.png)'; div.style.background = 'url(aprs-symbols/aprs-symbols-24-' + tableId + '@2x.png)';
div.style['background-size'] = '384px 144px'; div.style['background-size'] = '384px 144px';
div.style['background-position-x'] = -(this.symbol.index % 16) * 24 + 'px'; div.style['background-position-x'] = -(this.symbol.index % 16) * 24 + 'px';
div.style['background-position-y'] = -Math.floor(this.symbol.index / 16) * 24 + 'px'; div.style['background-position-y'] = -Math.floor(this.symbol.index / 16) * 24 + 'px';
@ -63,7 +63,7 @@ AprsMarker.prototype.onAdd = function() {
var overlay = this.overlay = document.createElement('div'); var overlay = this.overlay = document.createElement('div');
overlay.style.width = '24px'; overlay.style.width = '24px';
overlay.style.height = '24px'; overlay.style.height = '24px';
overlay.style.background = 'url(/aprs-symbols/aprs-symbols-24-2@2x.png)'; overlay.style.background = 'url(aprs-symbols/aprs-symbols-24-2@2x.png)';
overlay.style['background-size'] = '384px 144px'; overlay.style['background-size'] = '384px 144px';
overlay.style.display = 'none'; overlay.style.display = 'none';

View File

@ -10,35 +10,56 @@ function AudioEngine(maxBufferLength, audioReporter) {
if (!ctx) { if (!ctx) {
return; return;
} }
this.audioContext = new ctx();
this.allowed = this.audioContext.state === 'running';
this.started = false;
this.audioCodec = new sdrjs.ImaAdpcm(); this.onStartCallbacks = [];
this.started = false;
this.audioContext = new ctx();
var me = this;
this.audioContext.onstatechange = function() {
if (me.audioContext.state !== 'running') return;
me._start();
}
this.audioCodec = new ImaAdpcmCodec();
this.compression = 'none'; this.compression = 'none';
this.setupResampling(); this.setupResampling();
this.resampler = new sdrjs.RationalResamplerFF(this.resamplingFactor, 1); this.resampler = new Interpolator(this.resamplingFactor);
this.hdResampler = new Interpolator(this.hdResamplingFactor);
this.maxBufferSize = maxBufferLength * this.getSampleRate(); this.maxBufferSize = maxBufferLength * this.getSampleRate();
} }
AudioEngine.prototype.start = function(callback) { AudioEngine.prototype.resume = function(){
this.audioContext.resume();
}
AudioEngine.prototype._start = function() {
var me = this; var me = this;
if (me.resamplingFactor === 0) return; //if failed to find a valid resampling factor...
if (me.started) { // if failed to find a valid resampling factor...
if (callback) callback(false); if (me.resamplingFactor === 0) {
return; return;
} }
me.audioContext.resume().then(function(){ // been started before?
me.allowed = me.audioContext.state === 'running'; if (me.started) {
if (!me.allowed) { return;
if (callback) callback(false); }
// are we allowed to play audio?
if (!me.isAllowed()) {
return; return;
} }
me.started = true; me.started = true;
var runCallbacks = function(workletType) {
var callbacks = me.onStartCallbacks;
me.onStartCallbacks = false;
callbacks.forEach(function(c) { c(workletType); });
};
me.gainNode = me.audioContext.createGain(); me.gainNode = me.audioContext.createGain();
me.gainNode.connect(me.audioContext.destination); me.gainNode.connect(me.audioContext.destination);
@ -65,7 +86,7 @@ AudioEngine.prototype.start = function(callback) {
} }
}); });
me.audioNode.port.start(); me.audioNode.port.start();
if (callback) callback(true, 'AudioWorklet'); runCallbacks('AudioWorklet');
}); });
} else { } else {
me.audioBuffers = []; me.audioBuffers = [];
@ -120,15 +141,22 @@ AudioEngine.prototype.start = function(callback) {
me.audioNode = me.audioContext[method](bufferSize, 0, 1); me.audioNode = me.audioContext[method](bufferSize, 0, 1);
me.audioNode.onaudioprocess = audio_onprocess; me.audioNode.onaudioprocess = audio_onprocess;
me.audioNode.connect(me.gainNode); me.audioNode.connect(me.gainNode);
if (callback) callback(true, 'ScriptProcessorNode'); runCallbacks('ScriptProcessorNode')
} }
setInterval(me.reportStats.bind(me), 1000); setInterval(me.reportStats.bind(me), 1000);
}); };
AudioEngine.prototype.onStart = function(callback) {
if (this.onStartCallbacks) {
this.onStartCallbacks.push(callback);
} else {
callback();
}
}; };
AudioEngine.prototype.isAllowed = function() { AudioEngine.prototype.isAllowed = function() {
return this.allowed; return this.audioContext.state === 'running';
}; };
AudioEngine.prototype.reportStats = function() { AudioEngine.prototype.reportStats = function() {
@ -165,35 +193,57 @@ AudioEngine.prototype.resetStats = function() {
}; };
AudioEngine.prototype.setupResampling = function() { //both at the server and the client AudioEngine.prototype.setupResampling = function() { //both at the server and the client
var output_range_max = 12000; var audio_params = this.findRate(8000, 12000);
var output_range_min = 8000; if (!audio_params) {
this.resamplingFactor = 0;
this.outputRate = 0;
divlog('Your audio card sampling rate (' + targetRate + ') is not supported.<br />Please change your operating system default settings in order to fix this.', 1);
} else {
this.resamplingFactor = audio_params.resamplingFactor;
this.outputRate = audio_params.outputRate;
}
var hd_audio_params = this.findRate(36000, 48000);
if (!hd_audio_params) {
this.hdResamplingFactor = 0;
this.hdOutputRate = 0;
divlog('Your audio card sampling rate (' + targetRate + ') is not supported for HD audio<br />Please change your operating system default settings in order to fix this.', 1);
} else {
this.hdResamplingFactor = hd_audio_params.resamplingFactor;
this.hdOutputRate = hd_audio_params.outputRate;
}
};
AudioEngine.prototype.findRate = function(low, high) {
var targetRate = this.audioContext.sampleRate; var targetRate = this.audioContext.sampleRate;
var i = 1; var i = 1;
while (true) { while (true) {
var audio_server_output_rate = Math.floor(targetRate / i); var audio_server_output_rate = Math.floor(targetRate / i);
if (audio_server_output_rate < output_range_min) { if (audio_server_output_rate < low) {
this.resamplingFactor = 0; return;
this.outputRate = 0; } else if (audio_server_output_rate >= low && audio_server_output_rate <= high) {
divlog('Your audio card sampling rate (' + targetRate + ') is not supported.<br />Please change your operating system default settings in order to fix this.', 1); return {
break; resamplingFactor: i,
} else if (audio_server_output_rate >= output_range_min && audio_server_output_rate <= output_range_max) { outputRate: audio_server_output_rate
this.resamplingFactor = i; }
this.outputRate = audio_server_output_rate;
break; //okay, we're done
} }
i++; i++;
}
}; };
}
AudioEngine.prototype.getOutputRate = function() { AudioEngine.prototype.getOutputRate = function() {
return this.outputRate; return this.outputRate;
}; };
AudioEngine.prototype.getHdOutputRate = function() {
return this.hdOutputRate;
}
AudioEngine.prototype.getSampleRate = function() { AudioEngine.prototype.getSampleRate = function() {
return this.audioContext.sampleRate; return this.audioContext.sampleRate;
}; };
AudioEngine.prototype.pushAudio = function(data) { AudioEngine.prototype.processAudio = function(data, resampler) {
if (!this.audioNode) return; if (!this.audioNode) return;
this.audioBytes.add(data.byteLength); this.audioBytes.add(data.byteLength);
var buffer; var buffer;
@ -203,7 +253,7 @@ AudioEngine.prototype.pushAudio = function(data) {
} else { } else {
buffer = new Int16Array(data); buffer = new Int16Array(data);
} }
buffer = this.resampler.process(sdrjs.ConvertI16_F(buffer)); buffer = resampler.process(buffer);
if (this.audioNode.port) { if (this.audioNode.port) {
// AudioWorklets supported // AudioWorklets supported
this.audioNode.port.postMessage(buffer); this.audioNode.port.postMessage(buffer);
@ -213,8 +263,16 @@ AudioEngine.prototype.pushAudio = function(data) {
this.audioBuffers.push(buffer); this.audioBuffers.push(buffer);
} }
} }
}
AudioEngine.prototype.pushAudio = function(data) {
this.processAudio(data, this.resampler);
}; };
AudioEngine.prototype.pushHdAudio = function(data) {
this.processAudio(data, this.hdResampler);
}
AudioEngine.prototype.setCompression = function(compression) { AudioEngine.prototype.setCompression = function(compression) {
this.compression = compression; this.compression = compression;
}; };
@ -228,3 +286,129 @@ AudioEngine.prototype.getBuffersize = function() {
if (!this.audioBuffers) return 0; if (!this.audioBuffers) return 0;
return this.audioBuffers.map(function(b){ return b.length; }).reduce(function(a, b){ return a + b; }, 0); return this.audioBuffers.map(function(b){ return b.length; }).reduce(function(a, b){ return a + b; }, 0);
}; };
function ImaAdpcmCodec() {
this.reset();
}
ImaAdpcmCodec.prototype.reset = function() {
this.stepIndex = 0;
this.predictor = 0;
this.step = 0;
};
ImaAdpcmCodec.imaIndexTable = [ -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8 ];
ImaAdpcmCodec.imaStepTable = [
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
];
ImaAdpcmCodec.prototype.decode = function(data) {
var output = new Int16Array(data.length * 2);
for (var i = 0; i < data.length; i++) {
output[i * 2] = this.decodeNibble(data[i] & 0x0F);
output[i * 2 + 1] = this.decodeNibble((data[i] >> 4) & 0x0F);
}
return output;
};
ImaAdpcmCodec.prototype.decodeNibble = function(nibble) {
this.stepIndex += ImaAdpcmCodec.imaIndexTable[nibble];
this.stepIndex = Math.min(Math.max(this.stepIndex, 0), 88);
var diff = this.step >> 3;
if (nibble & 1) diff += this.step >> 2;
if (nibble & 2) diff += this.step >> 1;
if (nibble & 4) diff += this.step;
if (nibble & 8) diff = -diff;
this.predictor += diff;
this.predictor = Math.min(Math.max(this.predictor, -32768), 32767);
this.step = ImaAdpcmCodec.imaStepTable[this.stepIndex];
return this.predictor;
};
function Interpolator(factor) {
this.factor = factor;
this.lowpass = new Lowpass(factor)
}
Interpolator.prototype.process = function(data) {
var output = new Float32Array(data.length * this.factor);
for (var i = 0; i < data.length; i++) {
output[i * this.factor] = (data[i] + 0.5) / 32768;
}
return this.lowpass.process(output);
};
function Lowpass(interpolation) {
this.interpolation = interpolation;
var transitionBandwidth = 0.05;
this.numtaps = Math.round(4 / transitionBandwidth);
if (this.numtaps % 2 == 0) this.numtaps += 1;
var cutoff = 1 / interpolation;
this.coefficients = this.getCoefficients(cutoff / 2);
this.delay = new Float32Array(this.numtaps);
for (var i = 0; i < this.numtaps; i++){
this.delay[i] = 0;
}
this.delayIndex = 0;
}
Lowpass.prototype.getCoefficients = function(cutoffRate) {
var middle = Math.floor(this.numtaps / 2);
// hamming window
var window_function = function(r){
var rate = 0.5 + r / 2;
return 0.54 - 0.46 * Math.cos(2 * Math.PI * rate);
}
var output = [];
output[middle] = 2 * Math.PI * cutoffRate * window_function(0);
for (var i = 1; i <= middle; i++) {
output[middle - i] = output[middle + i] = (Math.sin(2 * Math.PI * cutoffRate * i) / i) * window_function(i / middle);
}
return this.normalizeCoefficients(output);
};
Lowpass.prototype.normalizeCoefficients = function(input) {
var sum = 0;
var output = [];
for (var i = 0; i < input.length; i++) {
sum += input[i];
}
for (var i = 0; i < input.length; i++) {
output[i] = input[i] / sum;
}
return output;
};
Lowpass.prototype.process = function(input) {
output = new Float32Array(input.length);
for (var oi = 0; oi < input.length; oi++) {
this.delay[this.delayIndex] = input[oi];
this.delayIndex = (this.delayIndex + 1) % this.numtaps;
var acc = 0;
var index = this.delayIndex;
for (var i = 0; i < this.numtaps; ++i) {
var index = index != 0 ? index - 1 : this.numtaps - 1;
acc += this.delay[index] * this.coefficients[i];
if (isNaN(acc)) debugger;
}
// gain by interpolation
output[oi] = this.interpolation * acc;
}
return output;
};

View File

@ -33,7 +33,10 @@ class OwrxAudioProcessor extends AudioWorkletProcessor {
this.port.start(); this.port.start();
} }
process(inputs, outputs) { process(inputs, outputs) {
if (this.remaining() < 128) return true; if (this.remaining() < 128) {
outputs[0].forEach(output => output.fill(0));
return true;
}
outputs[0].forEach((output) => { outputs[0].forEach((output) => {
output.set(this.audioBuffer.subarray(this.outPos, this.outPos + 128)); output.set(this.audioBuffer.subarray(this.outPos, this.outPos + 128));
}); });

View File

@ -8,12 +8,10 @@ function BookmarkBar() {
var $bookmark = $(e.target).closest('.bookmark'); var $bookmark = $(e.target).closest('.bookmark');
me.$container.find('.bookmark').removeClass('selected'); me.$container.find('.bookmark').removeClass('selected');
var b = $bookmark.data(); var b = $bookmark.data();
if (!b || !b.frequency || (!b.modulation && !b.digital_modulation)) return; if (!b || !b.frequency || !b.modulation) return;
demodulator_set_offset_frequency(0, b.frequency - center_freq); me.getDemodulator().set_offset_frequency(b.frequency - center_freq);
if (b.modulation) { if (b.modulation) {
demodulator_analog_replace(b.modulation); me.getDemodulatorPanel().setMode(b.modulation);
} else if (b.digital_modulation) {
demodulator_digital_replace(b.digital_modulation);
} }
$bookmark.addClass('selected'); $bookmark.addClass('selected');
}); });
@ -89,8 +87,8 @@ BookmarkBar.prototype.render = function(){
var $bookmark = $( var $bookmark = $(
'<div class="bookmark" data-source="' + b.source + '"' + (b.editable?' editable="editable"':'') + '>' + '<div class="bookmark" data-source="' + b.source + '"' + (b.editable?' editable="editable"':'') + '>' +
'<div class="bookmark-actions">' + '<div class="bookmark-actions">' +
'<div class="openwebrx-button action" data-action="edit"><img src="static/gfx/openwebrx-edit.png"></div>' + '<div class="openwebrx-button action" data-action="edit"><span class="sprite sprite-edit"></span></div>' +
'<div class="openwebrx-button action" data-action="delete"><img src="static/gfx/openwebrx-trashcan.png"></div>' + '<div class="openwebrx-button action" data-action="delete"><span class="sprite sprite-trashcan"><span></div>' +
'</div>' + '</div>' +
'<div class="bookmark-content">' + b.name + '</div>' + '<div class="bookmark-content">' + b.name + '</div>' +
'</div>' '</div>'
@ -104,40 +102,26 @@ BookmarkBar.prototype.render = function(){
}; };
BookmarkBar.prototype.showEditDialog = function(bookmark) { BookmarkBar.prototype.showEditDialog = function(bookmark) {
var $form = this.$dialog.find("form");
if (!bookmark) { if (!bookmark) {
bookmark = { bookmark = {
name: "", name: "",
frequency: center_freq + demodulators[0].offset_frequency, frequency: center_freq + this.getDemodulator().get_offset_frequency(),
modulation: demodulators[0].subtype modulation: this.getDemodulator().get_secondary_demod() || this.getDemodulator().get_modulation()
} }
} }
['name', 'frequency', 'modulation'].forEach(function(key){ this.$dialog.bookmarkDialog().setValues(bookmark);
$form.find('#' + key).val(bookmark[key]);
});
this.$dialog.data('id', bookmark.id);
this.$dialog.show(); this.$dialog.show();
this.$dialog.find('#name').focus(); this.$dialog.find('#name').focus();
}; };
BookmarkBar.prototype.storeBookmark = function() { BookmarkBar.prototype.storeBookmark = function() {
var me = this; var me = this;
var bookmark = {}; var bookmark = this.$dialog.bookmarkDialog().getValues();
var valid = true; if (!bookmark) return;
['name', 'frequency', 'modulation'].forEach(function(key){
var $input = me.$dialog.find('#' + key);
valid = valid && $input[0].checkValidity();
bookmark[key] = $input.val();
});
if (!valid) {
me.$dialog.find("form :submit").click();
return;
}
bookmark.frequency = Number(bookmark.frequency); bookmark.frequency = Number(bookmark.frequency);
var bookmarks = me.localBookmarks.getBookmarks(); var bookmarks = me.localBookmarks.getBookmarks();
bookmark.id = me.$dialog.data('id');
if (!bookmark.id) { if (!bookmark.id) {
if (bookmarks.length) { if (bookmarks.length) {
bookmark.id = 1 + Math.max.apply(Math, bookmarks.map(function(b){ return b.id || 0; })); bookmark.id = 1 + Math.max.apply(Math, bookmarks.map(function(b){ return b.id || 0; }));
@ -154,6 +138,14 @@ BookmarkBar.prototype.storeBookmark = function() {
me.$dialog.hide(); me.$dialog.hide();
}; };
BookmarkBar.prototype.getDemodulatorPanel = function() {
return $('#openwebrx-panel-receiver').demodulatorPanel();
};
BookmarkBar.prototype.getDemodulator = function() {
return this.getDemodulatorPanel().getDemodulator();
};
BookmarkLocalStorage = function(){ BookmarkLocalStorage = function(){
}; };
@ -171,7 +163,3 @@ BookmarkLocalStorage.prototype.deleteBookmark = function(data) {
bookmarks = bookmarks.filter(function(b) { return b.id !== data; }); bookmarks = bookmarks.filter(function(b) { return b.id !== data; });
this.setBookmarks(bookmarks); this.setBookmarks(bookmarks);
}; };

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