kopia lustrzana https://gitlab.com/eliggett/wfview
Merge branch 'master' into shuttle
commit
eb81196238
287
CHANGELOG
287
CHANGELOG
|
@ -1,5 +1,292 @@
|
|||
# CHANGELOG
|
||||
|
||||
|
||||
- 20210611
|
||||
|
||||
Update udpserver.cpp
|
||||
|
||||
Use global watchdog rather than per-connection
|
||||
|
||||
Report when users are disconnected by the watchdog
|
||||
|
||||
Use watchdog to cleanup lost server connections
|
||||
|
||||
Fix crash on disconnect
|
||||
|
||||
Make status update after disconnection
|
||||
|
||||
More server disconnection cleanup
|
||||
|
||||
Improve server disconnection/cleanup
|
||||
|
||||
- 20210610
|
||||
|
||||
remove spaces when adding extra server users
|
||||
|
||||
Update udpserver.cpp
|
||||
|
||||
Allow both encoded and plain text passwords
|
||||
|
||||
Lots of fixes to server setup table
|
||||
|
||||
Hopefully fix the occasional 0xe1 packet from hitting the pty
|
||||
|
||||
Add more info for server connections
|
||||
|
||||
Make sure that user is authenticated before allowing CIV/Audio
|
||||
|
||||
Use correct location for statusupdate!
|
||||
|
||||
Indicate when TX is not available
|
||||
|
||||
Show server connection status in taskbar (only for USB connected rigs)
|
||||
|
||||
- 20210609
|
||||
|
||||
Allow sender or receiver to be 0xe1 in server
|
||||
|
||||
Always forward wfview traffic to wfview clients
|
||||
|
||||
- 20210608
|
||||
|
||||
Truncate wfview.log on open
|
||||
|
||||
Detect radio baudrate in server mode
|
||||
|
||||
Comment out rtaudio if not being used
|
||||
|
||||
Baud rate calculations are now only happening when baud rate is received
|
||||
and reasonable.
|
||||
|
||||
- 20210607
|
||||
|
||||
Check that we have at least 1 audio channel available.
|
||||
|
||||
Improve audio cleanup
|
||||
|
||||
Add extra debugging for UDP server CIV
|
||||
|
||||
Make only MacOS use buffered audio
|
||||
|
||||
Improve mac audio
|
||||
|
||||
- 20210606
|
||||
|
||||
Fix TX Audio on Linux
|
||||
|
||||
Various fixes to udpserver
|
||||
|
||||
Make QTMultimedia default
|
||||
|
||||
Fix to allow rtaudio to compile again
|
||||
|
||||
- 20210605
|
||||
|
||||
Add latency check to TX audio
|
||||
|
||||
Fix incorrect use of latency setting
|
||||
|
||||
- 20210604
|
||||
|
||||
Stop silly compile warning
|
||||
|
||||
Change udpserver to use new audiosetup struct properly.
|
||||
|
||||
Fix audio device selection
|
||||
|
||||
Fix for txaudio
|
||||
|
||||
Add QtMultimedia as default audio
|
||||
|
||||
- 20210603
|
||||
|
||||
Hopefully fix hang on exit when trying to close audio thread.
|
||||
|
||||
- 20210602
|
||||
|
||||
Use heap based rtaudio for enumeration
|
||||
|
||||
Catch possible exception when closing non-existent stream
|
||||
|
||||
Fix mac audio
|
||||
|
||||
Fix mac crash on closing audio
|
||||
|
||||
Make sure audio is deleted in destructor
|
||||
|
||||
Force specific rtaudio API depending on platform.
|
||||
|
||||
Linux now uses librtuadio-dev where available
|
||||
|
||||
Removing local rtaudio code and using library instead.
|
||||
|
||||
revert to ALSA for now
|
||||
|
||||
Tell rtaudio not to hog device
|
||||
|
||||
Update audiohandler.cpp
|
||||
|
||||
Select chunksize based on native sample rate
|
||||
|
||||
Force 48K sample rate when 44100 is detected.
|
||||
|
||||
change linux compiler directive to allow new-aligned
|
||||
|
||||
Tidy up server mutexes
|
||||
|
||||
Fix server high CPU on disconnect
|
||||
|
||||
- 20210601
|
||||
|
||||
Stop deleting audio after last client disconects
|
||||
|
||||
Change udpserver packet handling to be similar to udphandler
|
||||
|
||||
Update udpserver.cpp
|
||||
|
||||
Let buffer keep filling.
|
||||
|
||||
Change to 10ms poll time for server rx audio
|
||||
|
||||
Mutex work in udpserver
|
||||
|
||||
Fix for crash when remote requests tone.
|
||||
|
||||
- 20210531
|
||||
|
||||
IC-7700 support
|
||||
|
||||
Open pty non-blocking
|
||||
|
||||
Fix for crashing pty on mac
|
||||
|
||||
Fix compile issue after merge
|
||||
|
||||
- 20210530
|
||||
|
||||
Keep the theme during resize. TODO: preference for wf theme
|
||||
|
||||
Removing my own uninformed sidenote.
|
||||
|
||||
Waterfal length may now be adjusted. Let's see what range of length
|
||||
seems good and limit the control accordingly. Also there may be a memory
|
||||
leak in the prepareWf() function where the colormap is created when the
|
||||
image is resized.
|
||||
|
||||
CIV may now be changed as-needed while running.
|
||||
|
||||
Remove various compiler warnings and tidy up.
|
||||
|
||||
add silence if audio has stopped
|
||||
|
||||
- 20210529
|
||||
|
||||
fix for mac/linux compiler
|
||||
|
||||
Detect number of device channels and convert accordingly
|
||||
|
||||
Lots more changes for rtaudio compatibility
|
||||
|
||||
Small change to show default audio devices
|
||||
|
||||
- 20210528
|
||||
|
||||
More chair movements.
|
||||
|
||||
More arranging of the chairs. Also fixed a minor bug that prevented the
|
||||
"Manual" serial device entry on my system.
|
||||
|
||||
Cleaning up the main constructor for wfmain.
|
||||
|
||||
Add some startup logging
|
||||
|
||||
Update audiohandler.cpp
|
||||
|
||||
Update udphandler.cpp
|
||||
|
||||
Change toolbar display formatting
|
||||
|
||||
Use preferred sample rate rather than force 48000
|
||||
|
||||
- 20210527
|
||||
|
||||
Allow higher latency
|
||||
|
||||
udpserver fixes
|
||||
|
||||
Update udpserver.cpp
|
||||
|
||||
Fix for tx audio channels
|
||||
|
||||
Add tx audio
|
||||
|
||||
add asound lib to linux build
|
||||
|
||||
fix qmake file
|
||||
|
||||
Use ring buffer with rtaudio to eliminate mutexes
|
||||
|
||||
- 20210525
|
||||
|
||||
Update INSTALL_PREBUILT_BINARY.md
|
||||
|
||||
move ulaw to dedicated header
|
||||
|
||||
add rtaudio as submodule
|
||||
|
||||
add opus-tools as submodule
|
||||
|
||||
Add mutex for audio buffer
|
||||
|
||||
- 20210523
|
||||
|
||||
Fixes for linux build
|
||||
|
||||
First working rtaudio (output only)
|
||||
|
||||
Link can now be clicked.
|
||||
|
||||
Added helpful text to settings tab.
|
||||
|
||||
Allow entry to Server Setup for either radio connection type.
|
||||
|
||||
Minor change to clarify roll of Server Setup
|
||||
|
||||
- 20210522
|
||||
|
||||
Add debugging and fix silly error in audiooutput combobox
|
||||
|
||||
reenable audio buffers
|
||||
|
||||
Attempt to fix crash
|
||||
|
||||
Make only first client have TX audio
|
||||
|
||||
Stop audiohandler re-enumerating devices on connect.
|
||||
|
||||
Stop preamps/attenuators lists growing every time we reconnect.
|
||||
|
||||
Try increasing audio device buffer size
|
||||
|
||||
- 20210521
|
||||
|
||||
Changed method for adding modes to rigs and populating the rig menu.
|
||||
This should be easier to maintain and better in the long run.
|
||||
|
||||
"Hopefully" fix annoying UDP server crash on client disconnect!
|
||||
|
||||
Fix for TX audio in udp server
|
||||
|
||||
Fix for stuttering audio on mac
|
||||
|
||||
Fixed missing break in switchs.
|
||||
|
||||
Typo in message about CI-V
|
||||
|
||||
Dynamic timing update for all baud rates and connection types.
|
||||
|
||||
Fixed support for 9600 baud and lower speeds.
|
||||
|
||||
- 20210521
|
||||
|
||||
Add baud rate detection for remote rigs
|
||||
|
|
|
@ -21,11 +21,11 @@ redhat7 -- no qt support
|
|||
Debian 11 (Debian 10 is outdated)
|
||||
Fedora 33
|
||||
Fedora 34
|
||||
mint 20.1
|
||||
mint 20.1 (and up?)
|
||||
openSUSE 15.x
|
||||
openSUSE Tumbleweed
|
||||
SLES 15.x
|
||||
Ubuntu 20.04.2
|
||||
Ubuntu 20.04.2 and up (?)
|
||||
~~~
|
||||
|
||||
|
||||
|
@ -63,6 +63,10 @@ wfview
|
|||
sudo apt install libqcustomplot2.0 libqt5multimedia5 libqt5serialport5
|
||||
sudo ln -s /usr/lib64/libqcustomplot-qt5.so.2 /usr/lib64/libqcustomplot.so.2
|
||||
wfview
|
||||
|
||||
note: if the above symlink fails, use the following line to fix the library link:
|
||||
|
||||
sudo ln -s /lib/x86_64-linux-gnu/libqcustomplot.so.2.0.1 /lib/x86_64-linux-gnu/libqcustomplot.so.2
|
||||
~~~
|
||||
|
||||
### openSUSE/Tumbleweed/SLES:
|
||||
|
@ -76,6 +80,11 @@ wfview
|
|||
sudo apt install libqcustomplot2.0 libqt5multimedia5 libqt5serialport5
|
||||
sudo ln -s /usr/lib/x86_64-linux-gnu/libqcustomplot.so.2.0.1 /usr/lib/x86_64-linux-gnu/libqcustomplot.so.2
|
||||
wfview
|
||||
|
||||
|
||||
note: if the above symlink fails, use the following line to fix the library link:
|
||||
|
||||
sudo ln -s /lib/x86_64-linux-gnu/libqcustomplot.so.2.0.1 /lib/x86_64-linux-gnu/libqcustomplot.so.2
|
||||
~~~
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
The following highlights are in this dot-release:
|
||||
|
||||
added IC7700
|
||||
fixes and improvements to audio
|
||||
ability to choose between rtaudio and qtmultimedia (default) as compile time option
|
||||
fixes and lots of improvements at the usb-server end
|
||||
waterfall length can be adjusted now
|
||||
no need to restart to change CIV address
|
||||
seamless changing rigs without restart
|
||||
started support for older rigs like the 718
|
||||
wf display disappears when there is no wf capable rig
|
||||
IC R8600 support improved
|
||||
for older rigs added a polling timing box to keep stuff keeping smooth
|
|
@ -118,8 +118,16 @@ void commHandler::receiveDataIn()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if(inPortData.startsWith("\xFE\xFE"))
|
||||
{
|
||||
if(inPortData.contains("\xFC"))
|
||||
{
|
||||
//qInfo(logSerial()) << "Transaction contains collision data. Dumping.";
|
||||
//printHex(inPortData, false, true);
|
||||
port->commitTransaction();
|
||||
return;
|
||||
}
|
||||
if(inPortData.endsWith("\xFD"))
|
||||
{
|
||||
// good!
|
||||
|
|
1745
resampler/resample.c
1745
resampler/resample.c
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,339 @@
|
|||
/* Copyright (C) 2007-2008 Jean-Marc Valin
|
||||
* Copyright (C) 2008 Thorvald Natvig
|
||||
* Copyright (C) 2011 Texas Instruments
|
||||
* author Jyri Sarha
|
||||
*/
|
||||
/**
|
||||
@file resample_neon.h
|
||||
@brief Resampler functions (NEON version)
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
#if defined(__aarch64__)
|
||||
static inline int32_t saturate_32bit_to_16bit(int32_t a) {
|
||||
int32_t ret;
|
||||
asm ("fmov s0, %w[a]\n"
|
||||
"sqxtn h0, s0\n"
|
||||
"sxtl v0.4s, v0.4h\n"
|
||||
"fmov %w[ret], s0\n"
|
||||
: [ret] "=r" (ret)
|
||||
: [a] "r" (a)
|
||||
: "v0" );
|
||||
return ret;
|
||||
}
|
||||
#elif defined(__thumb2__)
|
||||
static inline int32_t saturate_32bit_to_16bit(int32_t a) {
|
||||
int32_t ret;
|
||||
asm ("ssat %[ret], #16, %[a]"
|
||||
: [ret] "=r" (ret)
|
||||
: [a] "r" (a)
|
||||
: );
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static inline int32_t saturate_32bit_to_16bit(int32_t a) {
|
||||
int32_t ret;
|
||||
asm ("vmov.s32 d0[0], %[a]\n"
|
||||
"vqmovn.s32 d0, q0\n"
|
||||
"vmov.s16 %[ret], d0[0]\n"
|
||||
: [ret] "=r" (ret)
|
||||
: [a] "r" (a)
|
||||
: "q0");
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#undef WORD2INT
|
||||
#define WORD2INT(x) (saturate_32bit_to_16bit(x))
|
||||
|
||||
#define OVERRIDE_INNER_PRODUCT_SINGLE
|
||||
/* Only works when len % 4 == 0 and len >= 4 */
|
||||
#if defined(__aarch64__)
|
||||
static inline int32_t inner_product_single(const int16_t *a, const int16_t *b, unsigned int len)
|
||||
{
|
||||
int32_t ret;
|
||||
uint32_t remainder = len % 16;
|
||||
len = len - remainder;
|
||||
|
||||
asm volatile (" cmp %w[len], #0\n"
|
||||
" b.ne 1f\n"
|
||||
" ld1 {v16.4h}, [%[b]], #8\n"
|
||||
" ld1 {v20.4h}, [%[a]], #8\n"
|
||||
" subs %w[remainder], %w[remainder], #4\n"
|
||||
" smull v0.4s, v16.4h, v20.4h\n"
|
||||
" b.ne 4f\n"
|
||||
" b 5f\n"
|
||||
"1:"
|
||||
" ld1 {v16.4h, v17.4h, v18.4h, v19.4h}, [%[b]], #32\n"
|
||||
" ld1 {v20.4h, v21.4h, v22.4h, v23.4h}, [%[a]], #32\n"
|
||||
" subs %w[len], %w[len], #16\n"
|
||||
" smull v0.4s, v16.4h, v20.4h\n"
|
||||
" smlal v0.4s, v17.4h, v21.4h\n"
|
||||
" smlal v0.4s, v18.4h, v22.4h\n"
|
||||
" smlal v0.4s, v19.4h, v23.4h\n"
|
||||
" b.eq 3f\n"
|
||||
"2:"
|
||||
" ld1 {v16.4h, v17.4h, v18.4h, v19.4h}, [%[b]], #32\n"
|
||||
" ld1 {v20.4h, v21.4h, v22.4h, v23.4h}, [%[a]], #32\n"
|
||||
" subs %w[len], %w[len], #16\n"
|
||||
" smlal v0.4s, v16.4h, v20.4h\n"
|
||||
" smlal v0.4s, v17.4h, v21.4h\n"
|
||||
" smlal v0.4s, v18.4h, v22.4h\n"
|
||||
" smlal v0.4s, v19.4h, v23.4h\n"
|
||||
" b.ne 2b\n"
|
||||
"3:"
|
||||
" cmp %w[remainder], #0\n"
|
||||
" b.eq 5f\n"
|
||||
"4:"
|
||||
" ld1 {v18.4h}, [%[b]], #8\n"
|
||||
" ld1 {v22.4h}, [%[a]], #8\n"
|
||||
" subs %w[remainder], %w[remainder], #4\n"
|
||||
" smlal v0.4s, v18.4h, v22.4h\n"
|
||||
" b.ne 4b\n"
|
||||
"5:"
|
||||
" saddlv d0, v0.4s\n"
|
||||
" sqxtn s0, d0\n"
|
||||
" sqrshrn h0, s0, #15\n"
|
||||
" sxtl v0.4s, v0.4h\n"
|
||||
" fmov %w[ret], s0\n"
|
||||
: [ret] "=r" (ret), [a] "+r" (a), [b] "+r" (b),
|
||||
[len] "+r" (len), [remainder] "+r" (remainder)
|
||||
:
|
||||
: "cc", "v0",
|
||||
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23");
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static inline int32_t inner_product_single(const int16_t *a, const int16_t *b, unsigned int len)
|
||||
{
|
||||
int32_t ret;
|
||||
uint32_t remainder = len % 16;
|
||||
len = len - remainder;
|
||||
|
||||
asm volatile (" cmp %[len], #0\n"
|
||||
" bne 1f\n"
|
||||
" vld1.16 {d16}, [%[b]]!\n"
|
||||
" vld1.16 {d20}, [%[a]]!\n"
|
||||
" subs %[remainder], %[remainder], #4\n"
|
||||
" vmull.s16 q0, d16, d20\n"
|
||||
" beq 5f\n"
|
||||
" b 4f\n"
|
||||
"1:"
|
||||
" vld1.16 {d16, d17, d18, d19}, [%[b]]!\n"
|
||||
" vld1.16 {d20, d21, d22, d23}, [%[a]]!\n"
|
||||
" subs %[len], %[len], #16\n"
|
||||
" vmull.s16 q0, d16, d20\n"
|
||||
" vmlal.s16 q0, d17, d21\n"
|
||||
" vmlal.s16 q0, d18, d22\n"
|
||||
" vmlal.s16 q0, d19, d23\n"
|
||||
" beq 3f\n"
|
||||
"2:"
|
||||
" vld1.16 {d16, d17, d18, d19}, [%[b]]!\n"
|
||||
" vld1.16 {d20, d21, d22, d23}, [%[a]]!\n"
|
||||
" subs %[len], %[len], #16\n"
|
||||
" vmlal.s16 q0, d16, d20\n"
|
||||
" vmlal.s16 q0, d17, d21\n"
|
||||
" vmlal.s16 q0, d18, d22\n"
|
||||
" vmlal.s16 q0, d19, d23\n"
|
||||
" bne 2b\n"
|
||||
"3:"
|
||||
" cmp %[remainder], #0\n"
|
||||
" beq 5f\n"
|
||||
"4:"
|
||||
" vld1.16 {d16}, [%[b]]!\n"
|
||||
" vld1.16 {d20}, [%[a]]!\n"
|
||||
" subs %[remainder], %[remainder], #4\n"
|
||||
" vmlal.s16 q0, d16, d20\n"
|
||||
" bne 4b\n"
|
||||
"5:"
|
||||
" vaddl.s32 q0, d0, d1\n"
|
||||
" vadd.s64 d0, d0, d1\n"
|
||||
" vqmovn.s64 d0, q0\n"
|
||||
" vqrshrn.s32 d0, q0, #15\n"
|
||||
" vmov.s16 %[ret], d0[0]\n"
|
||||
: [ret] "=r" (ret), [a] "+r" (a), [b] "+r" (b),
|
||||
[len] "+r" (len), [remainder] "+r" (remainder)
|
||||
:
|
||||
: "cc", "q0",
|
||||
"d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23");
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif // !defined(__aarch64__)
|
||||
|
||||
#elif defined(FLOATING_POINT)
|
||||
#if defined(__aarch64__)
|
||||
static inline int32_t saturate_float_to_16bit(float a) {
|
||||
int32_t ret;
|
||||
asm ("fcvtas s1, %s[a]\n"
|
||||
"sqxtn h1, s1\n"
|
||||
"sxtl v1.4s, v1.4h\n"
|
||||
"fmov %w[ret], s1\n"
|
||||
: [ret] "=r" (ret)
|
||||
: [a] "w" (a)
|
||||
: "v1");
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static inline int32_t saturate_float_to_16bit(float a) {
|
||||
int32_t ret;
|
||||
asm ("vmov.f32 d0[0], %[a]\n"
|
||||
"vcvt.s32.f32 d0, d0, #15\n"
|
||||
"vqrshrn.s32 d0, q0, #15\n"
|
||||
"vmov.s16 %[ret], d0[0]\n"
|
||||
: [ret] "=r" (ret)
|
||||
: [a] "r" (a)
|
||||
: "q0");
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef WORD2INT
|
||||
#define WORD2INT(x) (saturate_float_to_16bit(x))
|
||||
|
||||
#define OVERRIDE_INNER_PRODUCT_SINGLE
|
||||
/* Only works when len % 4 == 0 and len >= 4 */
|
||||
#if defined(__aarch64__)
|
||||
static inline float inner_product_single(const float *a, const float *b, unsigned int len)
|
||||
{
|
||||
float ret;
|
||||
uint32_t remainder = len % 16;
|
||||
len = len - remainder;
|
||||
|
||||
asm volatile (" cmp %w[len], #0\n"
|
||||
" b.ne 1f\n"
|
||||
" ld1 {v16.4s}, [%[b]], #16\n"
|
||||
" ld1 {v20.4s}, [%[a]], #16\n"
|
||||
" subs %w[remainder], %w[remainder], #4\n"
|
||||
" fmul v1.4s, v16.4s, v20.4s\n"
|
||||
" b.ne 4f\n"
|
||||
" b 5f\n"
|
||||
"1:"
|
||||
" ld1 {v16.4s, v17.4s, v18.4s, v19.4s}, [%[b]], #64\n"
|
||||
" ld1 {v20.4s, v21.4s, v22.4s, v23.4s}, [%[a]], #64\n"
|
||||
" subs %w[len], %w[len], #16\n"
|
||||
" fmul v1.4s, v16.4s, v20.4s\n"
|
||||
" fmul v2.4s, v17.4s, v21.4s\n"
|
||||
" fmul v3.4s, v18.4s, v22.4s\n"
|
||||
" fmul v4.4s, v19.4s, v23.4s\n"
|
||||
" b.eq 3f\n"
|
||||
"2:"
|
||||
" ld1 {v16.4s, v17.4s, v18.4s, v19.4s}, [%[b]], #64\n"
|
||||
" ld1 {v20.4s, v21.4s, v22.4s, v23.4s}, [%[a]], #64\n"
|
||||
" subs %w[len], %w[len], #16\n"
|
||||
" fmla v1.4s, v16.4s, v20.4s\n"
|
||||
" fmla v2.4s, v17.4s, v21.4s\n"
|
||||
" fmla v3.4s, v18.4s, v22.4s\n"
|
||||
" fmla v4.4s, v19.4s, v23.4s\n"
|
||||
" b.ne 2b\n"
|
||||
"3:"
|
||||
" fadd v16.4s, v1.4s, v2.4s\n"
|
||||
" fadd v17.4s, v3.4s, v4.4s\n"
|
||||
" cmp %w[remainder], #0\n"
|
||||
" fadd v1.4s, v16.4s, v17.4s\n"
|
||||
" b.eq 5f\n"
|
||||
"4:"
|
||||
" ld1 {v18.4s}, [%[b]], #16\n"
|
||||
" ld1 {v22.4s}, [%[a]], #16\n"
|
||||
" subs %w[remainder], %w[remainder], #4\n"
|
||||
" fmla v1.4s, v18.4s, v22.4s\n"
|
||||
" b.ne 4b\n"
|
||||
"5:"
|
||||
" faddp v1.4s, v1.4s, v1.4s\n"
|
||||
" faddp %[ret].4s, v1.4s, v1.4s\n"
|
||||
: [ret] "=w" (ret), [a] "+r" (a), [b] "+r" (b),
|
||||
[len] "+r" (len), [remainder] "+r" (remainder)
|
||||
:
|
||||
: "cc", "v1", "v2", "v3", "v4",
|
||||
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23");
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static inline float inner_product_single(const float *a, const float *b, unsigned int len)
|
||||
{
|
||||
float ret;
|
||||
uint32_t remainder = len % 16;
|
||||
len = len - remainder;
|
||||
|
||||
asm volatile (" cmp %[len], #0\n"
|
||||
" bne 1f\n"
|
||||
" vld1.32 {q4}, [%[b]]!\n"
|
||||
" vld1.32 {q8}, [%[a]]!\n"
|
||||
" subs %[remainder], %[remainder], #4\n"
|
||||
" vmul.f32 q0, q4, q8\n"
|
||||
" bne 4f\n"
|
||||
" b 5f\n"
|
||||
"1:"
|
||||
" vld1.32 {q4, q5}, [%[b]]!\n"
|
||||
" vld1.32 {q8, q9}, [%[a]]!\n"
|
||||
" vld1.32 {q6, q7}, [%[b]]!\n"
|
||||
" vld1.32 {q10, q11}, [%[a]]!\n"
|
||||
" subs %[len], %[len], #16\n"
|
||||
" vmul.f32 q0, q4, q8\n"
|
||||
" vmul.f32 q1, q5, q9\n"
|
||||
" vmul.f32 q2, q6, q10\n"
|
||||
" vmul.f32 q3, q7, q11\n"
|
||||
" beq 3f\n"
|
||||
"2:"
|
||||
" vld1.32 {q4, q5}, [%[b]]!\n"
|
||||
" vld1.32 {q8, q9}, [%[a]]!\n"
|
||||
" vld1.32 {q6, q7}, [%[b]]!\n"
|
||||
" vld1.32 {q10, q11}, [%[a]]!\n"
|
||||
" subs %[len], %[len], #16\n"
|
||||
" vmla.f32 q0, q4, q8\n"
|
||||
" vmla.f32 q1, q5, q9\n"
|
||||
" vmla.f32 q2, q6, q10\n"
|
||||
" vmla.f32 q3, q7, q11\n"
|
||||
" bne 2b\n"
|
||||
"3:"
|
||||
" vadd.f32 q4, q0, q1\n"
|
||||
" vadd.f32 q5, q2, q3\n"
|
||||
" cmp %[remainder], #0\n"
|
||||
" vadd.f32 q0, q4, q5\n"
|
||||
" beq 5f\n"
|
||||
"4:"
|
||||
" vld1.32 {q6}, [%[b]]!\n"
|
||||
" vld1.32 {q10}, [%[a]]!\n"
|
||||
" subs %[remainder], %[remainder], #4\n"
|
||||
" vmla.f32 q0, q6, q10\n"
|
||||
" bne 4b\n"
|
||||
"5:"
|
||||
" vadd.f32 d0, d0, d1\n"
|
||||
" vpadd.f32 d0, d0, d0\n"
|
||||
" vmov.f32 %[ret], d0[0]\n"
|
||||
: [ret] "=r" (ret), [a] "+r" (a), [b] "+r" (b),
|
||||
[len] "+l" (len), [remainder] "+l" (remainder)
|
||||
:
|
||||
: "cc", "q0", "q1", "q2", "q3",
|
||||
"q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11");
|
||||
return ret;
|
||||
}
|
||||
#endif // defined(__aarch64__)
|
||||
#endif
|
|
@ -2,127 +2,127 @@
|
|||
* Copyright (C) 2008 Thorvald Natvig
|
||||
*/
|
||||
/**
|
||||
@file resample_sse.h
|
||||
@brief Resampler functions (SSE version)
|
||||
@file resample_sse.h
|
||||
@brief Resampler functions (SSE version)
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
- Neither the name of the Xiph.org Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <xmmintrin.h>
|
||||
|
||||
#define OVERRIDE_INNER_PRODUCT_SINGLE
|
||||
static inline float inner_product_single(const float *a, const float *b, unsigned int len)
|
||||
static inline float inner_product_single(const float* a, const float* b, unsigned int len)
|
||||
{
|
||||
unsigned int i;
|
||||
float ret;
|
||||
__m128 sum = _mm_setzero_ps();
|
||||
for (i=0;i<len;i+=8)
|
||||
{
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i)));
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4)));
|
||||
}
|
||||
sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
|
||||
sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
|
||||
_mm_store_ss(&ret, sum);
|
||||
return ret;
|
||||
int i;
|
||||
float ret;
|
||||
__m128 sum = _mm_setzero_ps();
|
||||
for (i = 0; i < len; i += 8)
|
||||
{
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a + i), _mm_loadu_ps(b + i)));
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a + i + 4), _mm_loadu_ps(b + i + 4)));
|
||||
}
|
||||
sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
|
||||
sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
|
||||
_mm_store_ss(&ret, sum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define OVERRIDE_INTERPOLATE_PRODUCT_SINGLE
|
||||
static inline float interpolate_product_single(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) {
|
||||
unsigned int i;
|
||||
float ret;
|
||||
__m128 sum = _mm_setzero_ps();
|
||||
__m128 f = _mm_loadu_ps(frac);
|
||||
for(i=0;i<len;i+=2)
|
||||
{
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample)));
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample)));
|
||||
}
|
||||
sum = _mm_mul_ps(f, sum);
|
||||
sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
|
||||
sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
|
||||
_mm_store_ss(&ret, sum);
|
||||
return ret;
|
||||
static inline float interpolate_product_single(const float* a, const float* b, unsigned int len, const spx_uint32_t oversample, float* frac) {
|
||||
int i;
|
||||
float ret;
|
||||
__m128 sum = _mm_setzero_ps();
|
||||
__m128 f = _mm_loadu_ps(frac);
|
||||
for (i = 0; i < len; i += 2)
|
||||
{
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a + i), _mm_loadu_ps(b + i * oversample)));
|
||||
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a + i + 1), _mm_loadu_ps(b + (i + 1) * oversample)));
|
||||
}
|
||||
sum = _mm_mul_ps(f, sum);
|
||||
sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
|
||||
sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
|
||||
_mm_store_ss(&ret, sum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef __SSE2__
|
||||
#ifdef USE_SSE2
|
||||
#include <emmintrin.h>
|
||||
#define OVERRIDE_INNER_PRODUCT_DOUBLE
|
||||
|
||||
static inline double inner_product_double(const float *a, const float *b, unsigned int len)
|
||||
static inline double inner_product_double(const float* a, const float* b, unsigned int len)
|
||||
{
|
||||
unsigned int i;
|
||||
double ret;
|
||||
__m128d sum = _mm_setzero_pd();
|
||||
__m128 t;
|
||||
for (i=0;i<len;i+=8)
|
||||
{
|
||||
t = _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i));
|
||||
sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
|
||||
sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
|
||||
int i;
|
||||
double ret;
|
||||
__m128d sum = _mm_setzero_pd();
|
||||
__m128 t;
|
||||
for (i = 0; i < len; i += 8)
|
||||
{
|
||||
t = _mm_mul_ps(_mm_loadu_ps(a + i), _mm_loadu_ps(b + i));
|
||||
sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
|
||||
sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
|
||||
|
||||
t = _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4));
|
||||
sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
|
||||
sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
|
||||
}
|
||||
sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum));
|
||||
_mm_store_sd(&ret, sum);
|
||||
return ret;
|
||||
t = _mm_mul_ps(_mm_loadu_ps(a + i + 4), _mm_loadu_ps(b + i + 4));
|
||||
sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
|
||||
sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
|
||||
}
|
||||
sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum));
|
||||
_mm_store_sd(&ret, sum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE
|
||||
static inline double interpolate_product_double(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) {
|
||||
unsigned int i;
|
||||
double ret;
|
||||
__m128d sum;
|
||||
__m128d sum1 = _mm_setzero_pd();
|
||||
__m128d sum2 = _mm_setzero_pd();
|
||||
__m128 f = _mm_loadu_ps(frac);
|
||||
__m128d f1 = _mm_cvtps_pd(f);
|
||||
__m128d f2 = _mm_cvtps_pd(_mm_movehl_ps(f,f));
|
||||
__m128 t;
|
||||
for(i=0;i<len;i+=2)
|
||||
{
|
||||
t = _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample));
|
||||
sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));
|
||||
sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
|
||||
static inline double interpolate_product_double(const float* a, const float* b, unsigned int len, const spx_uint32_t oversample, float* frac) {
|
||||
int i;
|
||||
double ret;
|
||||
__m128d sum;
|
||||
__m128d sum1 = _mm_setzero_pd();
|
||||
__m128d sum2 = _mm_setzero_pd();
|
||||
__m128 f = _mm_loadu_ps(frac);
|
||||
__m128d f1 = _mm_cvtps_pd(f);
|
||||
__m128d f2 = _mm_cvtps_pd(_mm_movehl_ps(f, f));
|
||||
__m128 t;
|
||||
for (i = 0; i < len; i += 2)
|
||||
{
|
||||
t = _mm_mul_ps(_mm_load1_ps(a + i), _mm_loadu_ps(b + i * oversample));
|
||||
sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));
|
||||
sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
|
||||
|
||||
t = _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample));
|
||||
sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));
|
||||
sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
|
||||
}
|
||||
sum1 = _mm_mul_pd(f1, sum1);
|
||||
sum2 = _mm_mul_pd(f2, sum2);
|
||||
sum = _mm_add_pd(sum1, sum2);
|
||||
sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum));
|
||||
_mm_store_sd(&ret, sum);
|
||||
return ret;
|
||||
t = _mm_mul_ps(_mm_load1_ps(a + i + 1), _mm_loadu_ps(b + (i + 1) * oversample));
|
||||
sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));
|
||||
sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
|
||||
}
|
||||
sum1 = _mm_mul_pd(f1, sum1);
|
||||
sum2 = _mm_mul_pd(f2, sum2);
|
||||
sum = _mm_add_pd(sum1, sum2);
|
||||
sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum));
|
||||
_mm_store_sd(&ret, sum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -362,6 +362,10 @@ void rigCommander::setSpectrumBounds(double startFreq, double endFreq, unsigned
|
|||
if(startFreq > 400.0)
|
||||
freqRange++;
|
||||
break;
|
||||
case modelR8600:
|
||||
freqRange = 1;
|
||||
edgeNumber = 1;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
|
@ -429,7 +433,7 @@ void rigCommander::setScopeSpan(char span)
|
|||
// See ICD, page 165, "19-12".
|
||||
// 2.5k = 0
|
||||
// 5k = 2, etc.
|
||||
if((span <0 ) || (span >7))
|
||||
if((span <0 ) || (span >9))
|
||||
return;
|
||||
|
||||
QByteArray payload;
|
||||
|
@ -464,6 +468,12 @@ void rigCommander::setScopeSpan(char span)
|
|||
case 7:
|
||||
freq = 500.0E-3;
|
||||
break;
|
||||
case 8:
|
||||
freq = 1000.0E-3;
|
||||
break;
|
||||
case 9:
|
||||
freq = 2500.0E-3;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
|
@ -1090,6 +1100,12 @@ void rigCommander::parseData(QByteArray dataInput)
|
|||
// payload = getpayload(data); // or something
|
||||
// parse (payload); // recursive ok?
|
||||
payloadIn = data.right(data.length() - 4);
|
||||
if(payloadIn.contains("\xFE"))
|
||||
{
|
||||
//qDebug(logRig()) << "Corrupted data contains FE within message body: ";
|
||||
//printHex(payloadIn);
|
||||
break;
|
||||
}
|
||||
parseCommand();
|
||||
break;
|
||||
case '\x00':
|
||||
|
@ -1100,9 +1116,15 @@ void rigCommander::parseData(QByteArray dataInput)
|
|||
// This is an echo of our own broadcast request.
|
||||
// The data are "to 00" and "from E1"
|
||||
// Don't use it!
|
||||
qDebug(logRig()) << "Caught it! Found the echo'd broadcast request from us!";
|
||||
qDebug(logRig()) << "Caught it! Found the echo'd broadcast request from us! Rig has not responded to broadcast query yet.";
|
||||
} else {
|
||||
payloadIn = data.right(data.length() - 4);
|
||||
payloadIn = data.right(data.length() - 4); // Removes FE FE E0 94 part
|
||||
if(payloadIn.contains("\xFE"))
|
||||
{
|
||||
//qDebug(logRig()) << "Corrupted data contains FE within message body: ";
|
||||
//printHex(payloadIn);
|
||||
break;
|
||||
}
|
||||
parseCommand();
|
||||
}
|
||||
break;
|
||||
|
@ -1320,9 +1342,9 @@ void rigCommander::parseLevels()
|
|||
break;
|
||||
|
||||
default:
|
||||
qInfo(logRig()) << "Unknown control level (0x14) received at register " << payloadIn[1] << " with level " << level;
|
||||
qInfo(logRig()) << "Unknown control level (0x14) received at register " << QString("0x%1").arg((int)payloadIn[1],2,16) << " with level " << QString("0x%1").arg((int)level,2,16) << ", int=" << (int)level;
|
||||
printHex(payloadIn);
|
||||
break;
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -2474,7 +2496,6 @@ void rigCommander::parseDetailedRegisters1A05()
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void rigCommander::parseWFData()
|
||||
|
@ -2549,6 +2570,14 @@ mode_info rigCommander::createMode(mode_kind m, unsigned char reg, QString name)
|
|||
return mode;
|
||||
}
|
||||
|
||||
centerSpanData rigCommander::createScopeCenter(centerSpansType s, QString name)
|
||||
{
|
||||
centerSpanData csd;
|
||||
csd.cstype = s;
|
||||
csd.name = name;
|
||||
return csd;
|
||||
}
|
||||
|
||||
void rigCommander::determineRigCaps()
|
||||
{
|
||||
//TODO: Determine available bands (low priority, rig will reject out of band requests anyway)
|
||||
|
@ -2577,6 +2606,7 @@ void rigCommander::determineRigCaps()
|
|||
|
||||
rigCaps.hasDD = false;
|
||||
rigCaps.hasDV = false;
|
||||
rigCaps.hasDataModes = true; // USB-D, LSB-D, etc
|
||||
rigCaps.hasATU = false;
|
||||
|
||||
rigCaps.hasCTCSS = false;
|
||||
|
@ -2585,7 +2615,14 @@ void rigCommander::determineRigCaps()
|
|||
rigCaps.spectSeqMax = 0;
|
||||
rigCaps.spectAmpMax = 0;
|
||||
rigCaps.spectLenMax = 0;
|
||||
rigCaps.scopeCenterSpans = { createScopeCenter(cs2p5k, "±2.5k"), createScopeCenter(cs5k, "±5k"),
|
||||
createScopeCenter(cs10k, "±10k"), createScopeCenter(cs25k, "±25k"),
|
||||
createScopeCenter(cs50k, "±50k"), createScopeCenter(cs100k, "±100k"),
|
||||
createScopeCenter(cs250k, "±250k"), createScopeCenter(cs500k, "±500k")
|
||||
};
|
||||
|
||||
|
||||
rigCaps.hasFDcomms = true; // false for older radios
|
||||
|
||||
// Clear inputs/preamps/attenuators lists in case we have re-connected.
|
||||
rigCaps.preamps.clear();
|
||||
|
@ -2601,6 +2638,7 @@ void rigCommander::determineRigCaps()
|
|||
rigCaps.hasAntennaSel = false;
|
||||
|
||||
rigCaps.hasTransmit = true;
|
||||
rigCaps.hasPTTCommand = true;
|
||||
|
||||
// Common, reasonable defaults for most supported HF rigs:
|
||||
rigCaps.bsr[band160m] = 0x01;
|
||||
|
@ -2663,6 +2701,7 @@ void rigCommander::determineRigCaps()
|
|||
rigCaps.hasEthernet = true;
|
||||
rigCaps.hasWiFi = false;
|
||||
rigCaps.hasTransmit = false;
|
||||
rigCaps.hasPTTCommand = false;
|
||||
rigCaps.hasCTCSS = true;
|
||||
rigCaps.hasDTCS = true;
|
||||
rigCaps.hasDV = true;
|
||||
|
@ -2683,6 +2722,7 @@ void rigCommander::determineRigCaps()
|
|||
createMode(modeP25, 0x16, "P25"), createMode(modedPMR, 0x18, "dPMR"),
|
||||
createMode(modeNXDN_VN, 0x19, "NXDN-VN"), createMode(modeNXDN_N, 0x20, "NXDN-N"),
|
||||
createMode(modeDCR, 0x21, "DCR")});
|
||||
rigCaps.scopeCenterSpans.insert(rigCaps.scopeCenterSpans.end(), {createScopeCenter(cs1M, "±1M"), createScopeCenter(cs2p5M, "±2.5M")});
|
||||
break;
|
||||
case model9700:
|
||||
rigCaps.modelName = QString("IC-9700");
|
||||
|
@ -2717,6 +2757,7 @@ void rigCommander::determineRigCaps()
|
|||
rigCaps.hasLan = false;
|
||||
rigCaps.hasEthernet = false;
|
||||
rigCaps.hasWiFi = false;
|
||||
rigCaps.hasFDcomms = false;
|
||||
rigCaps.hasDD = false;
|
||||
rigCaps.hasDV = false;
|
||||
rigCaps.hasCTCSS = true;
|
||||
|
@ -2832,6 +2873,7 @@ void rigCommander::determineRigCaps()
|
|||
rigCaps.hasLan = false;
|
||||
rigCaps.hasEthernet = false;
|
||||
rigCaps.hasWiFi = false;
|
||||
rigCaps.hasFDcomms = false;
|
||||
rigCaps.hasATU = true;
|
||||
rigCaps.hasCTCSS = true;
|
||||
rigCaps.hasDTCS = true;
|
||||
|
@ -2852,6 +2894,7 @@ void rigCommander::determineRigCaps()
|
|||
rigCaps.hasLan = false;
|
||||
rigCaps.hasEthernet = false;
|
||||
rigCaps.hasWiFi = false;
|
||||
rigCaps.hasFDcomms = true;
|
||||
rigCaps.hasATU = true;
|
||||
rigCaps.hasCTCSS = true;
|
||||
rigCaps.hasDTCS = true;
|
||||
|
@ -2872,6 +2915,7 @@ void rigCommander::determineRigCaps()
|
|||
rigCaps.hasLan = false;
|
||||
rigCaps.hasEthernet = false;
|
||||
rigCaps.hasWiFi = false;
|
||||
rigCaps.hasFDcomms = false;
|
||||
rigCaps.hasATU = true;
|
||||
rigCaps.hasCTCSS = true;
|
||||
rigCaps.hasDTCS = true;
|
||||
|
@ -2897,6 +2941,7 @@ void rigCommander::determineRigCaps()
|
|||
rigCaps.hasLan = false;
|
||||
rigCaps.hasEthernet = false;
|
||||
rigCaps.hasWiFi = false;
|
||||
rigCaps.hasFDcomms = false;
|
||||
rigCaps.hasATU = true;
|
||||
rigCaps.hasCTCSS = true;
|
||||
rigCaps.hasDTCS = true;
|
||||
|
@ -2939,7 +2984,10 @@ void rigCommander::determineRigCaps()
|
|||
rigCaps.hasLan = false;
|
||||
rigCaps.hasEthernet = false;
|
||||
rigCaps.hasWiFi = false;
|
||||
rigCaps.hasFDcomms = false;
|
||||
rigCaps.hasATU = true;
|
||||
rigCaps.hasPTTCommand = false;
|
||||
rigCaps.hasDataModes = false;
|
||||
rigCaps.attenuators.push_back('\x20');
|
||||
rigCaps.bands = standardHF;
|
||||
rigCaps.bands.insert(rigCaps.bands.end(), standardVU.begin(), standardVU.end());
|
||||
|
@ -2947,6 +2995,28 @@ void rigCommander::determineRigCaps()
|
|||
rigCaps.modes = commonModes;
|
||||
rigCaps.modes.insert(rigCaps.modes.end(), createMode(modeWFM, 0x06, "WFM"));
|
||||
break;
|
||||
case model718:
|
||||
rigCaps.modelName = QString("IC-718");
|
||||
rigCaps.hasSpectrum = false;
|
||||
rigCaps.inputs.clear();
|
||||
rigCaps.hasLan = false;
|
||||
rigCaps.hasEthernet = false;
|
||||
rigCaps.hasWiFi = false;
|
||||
rigCaps.hasFDcomms = false;
|
||||
rigCaps.hasATU = false;
|
||||
rigCaps.hasPTTCommand = false;
|
||||
rigCaps.hasDataModes = false;
|
||||
rigCaps.attenuators.push_back('\x20');
|
||||
rigCaps.preamps.push_back('\x01');
|
||||
rigCaps.bands = {band10m, band10m, band12m,
|
||||
band15m, band17m, band20m, band30m,
|
||||
band40m, band60m, band80m, band160m, bandGen};
|
||||
rigCaps.modes = { createMode(modeLSB, 0x00, "LSB"), createMode(modeUSB, 0x01, "USB"),
|
||||
createMode(modeAM, 0x02, "AM"),
|
||||
createMode(modeCW, 0x03, "CW"), createMode(modeCW_R, 0x07, "CW-R"),
|
||||
createMode(modeRTTY, 0x04, "RTTY"), createMode(modeRTTY_R, 0x08, "RTTY-R")
|
||||
};
|
||||
break;
|
||||
case model756pro:
|
||||
rigCaps.modelName = QString("IC-756 Pro");
|
||||
rigCaps.hasSpectrum = false;
|
||||
|
@ -2954,6 +3024,7 @@ void rigCommander::determineRigCaps()
|
|||
rigCaps.hasLan = false;
|
||||
rigCaps.hasEthernet = false;
|
||||
rigCaps.hasWiFi = false;
|
||||
rigCaps.hasFDcomms = false;
|
||||
rigCaps.hasATU = true;
|
||||
rigCaps.preamps.push_back('\x01');
|
||||
rigCaps.preamps.push_back('\x02');
|
||||
|
@ -2971,6 +3042,7 @@ void rigCommander::determineRigCaps()
|
|||
rigCaps.hasLan = false;
|
||||
rigCaps.hasEthernet = false;
|
||||
rigCaps.hasWiFi = false;
|
||||
rigCaps.hasFDcomms = false;
|
||||
rigCaps.hasATU = true;
|
||||
rigCaps.preamps.push_back('\x01');
|
||||
rigCaps.preamps.push_back('\x02');
|
||||
|
@ -2988,6 +3060,7 @@ void rigCommander::determineRigCaps()
|
|||
rigCaps.hasLan = false;
|
||||
rigCaps.hasEthernet = false;
|
||||
rigCaps.hasWiFi = false;
|
||||
rigCaps.hasFDcomms = false;
|
||||
rigCaps.hasATU = true;
|
||||
rigCaps.preamps.push_back('\x01');
|
||||
rigCaps.preamps.push_back('\x02');
|
||||
|
@ -3008,6 +3081,7 @@ void rigCommander::determineRigCaps()
|
|||
rigCaps.hasLan = false;
|
||||
rigCaps.hasEthernet = false;
|
||||
rigCaps.hasWiFi = false;
|
||||
rigCaps.hasFDcomms = false;
|
||||
rigCaps.hasPreamp = false;
|
||||
rigCaps.hasAntennaSel = false;
|
||||
rigCaps.attenuators.push_back('\x10');
|
||||
|
|
|
@ -377,6 +377,7 @@ private:
|
|||
void printHex(const QByteArray &pdata);
|
||||
void printHex(const QByteArray &pdata, bool printVert, bool printHoriz);
|
||||
mode_info createMode(mode_kind m, unsigned char reg, QString name);
|
||||
centerSpanData createScopeCenter(centerSpansType s, QString name);
|
||||
|
||||
commHandler* comm = Q_NULLPTR;
|
||||
pttyHandler* ptty = Q_NULLPTR;
|
||||
|
|
|
@ -52,8 +52,11 @@ model_kind determineRadioModel(unsigned char rigID)
|
|||
case model705:
|
||||
rig = model705;
|
||||
break;
|
||||
case model756proiii:
|
||||
rig = model756proiii;
|
||||
case model718:
|
||||
rig = model718;
|
||||
break;
|
||||
case model910h:
|
||||
rig = model910h;
|
||||
break;
|
||||
case model756pro:
|
||||
rig = model756pro;
|
||||
|
@ -61,6 +64,9 @@ model_kind determineRadioModel(unsigned char rigID)
|
|||
case model756proii:
|
||||
rig = model756proii;
|
||||
break;
|
||||
case model756proiii:
|
||||
rig = model756proiii;
|
||||
break;
|
||||
default:
|
||||
rig = modelUnknown;
|
||||
break;
|
||||
|
|
|
@ -28,6 +28,7 @@ enum model_kind {
|
|||
model9700 = 0xA2,
|
||||
model705 = 0xA4,
|
||||
model706 = 0x58,
|
||||
model718 = 0x5E,
|
||||
model756pro = 0x5C,
|
||||
model756proii = 0x64,
|
||||
model756proiii = 0x6E,
|
||||
|
@ -67,6 +68,24 @@ enum bandType { band23cm=0,
|
|||
bandGen
|
||||
};
|
||||
|
||||
enum centerSpansType {
|
||||
cs2p5k = 0,
|
||||
cs5k = 1,
|
||||
cs10k = 2,
|
||||
cs25k = 3,
|
||||
cs50k = 4,
|
||||
cs100k = 5,
|
||||
cs250k = 6,
|
||||
cs500k = 7,
|
||||
cs1M = 8,
|
||||
cs2p5M = 9
|
||||
};
|
||||
|
||||
struct centerSpanData {
|
||||
centerSpansType cstype;
|
||||
QString name;
|
||||
};
|
||||
|
||||
model_kind determineRadioModel(unsigned char rigID);
|
||||
|
||||
struct rigCapabilities {
|
||||
|
@ -80,6 +99,7 @@ struct rigCapabilities {
|
|||
bool hasLan; // OEM ethernet or wifi connection
|
||||
bool hasEthernet;
|
||||
bool hasWiFi;
|
||||
bool hasFDcomms;
|
||||
|
||||
QVector<rigInput> inputs;
|
||||
|
||||
|
@ -96,13 +116,16 @@ struct rigCapabilities {
|
|||
bool hasDTCS;
|
||||
|
||||
bool hasTransmit;
|
||||
bool hasPTTCommand;
|
||||
bool hasAttenuator;
|
||||
bool hasPreamp;
|
||||
bool hasAntennaSel;
|
||||
bool hasDataModes;
|
||||
|
||||
std::vector <unsigned char> attenuators;
|
||||
std::vector <unsigned char> preamps;
|
||||
std::vector <unsigned char> antennas;
|
||||
std::vector <centerSpanData> scopeCenterSpans;
|
||||
std::vector <bandType> bands;
|
||||
unsigned char bsr[20] = {0};
|
||||
|
||||
|
|
167
udpserver.cpp
167
udpserver.cpp
|
@ -57,6 +57,10 @@ void udpServer::init()
|
|||
udpAudio = new QUdpSocket(this);
|
||||
udpAudio->bind(config.audioPort);
|
||||
QUdpSocket::connect(udpAudio, &QUdpSocket::readyRead, this, &udpServer::audioReceived);
|
||||
|
||||
wdTimer = new QTimer();
|
||||
connect(wdTimer, &QTimer::timeout, this, &udpServer::watchdog);
|
||||
wdTimer->start(500);
|
||||
}
|
||||
|
||||
udpServer::~udpServer()
|
||||
|
@ -76,10 +80,6 @@ udpServer::~udpServer()
|
|||
client->pingTimer->stop();
|
||||
delete client->pingTimer;
|
||||
}
|
||||
if (client->wdTimer != Q_NULLPTR) {
|
||||
client->wdTimer->stop();
|
||||
delete client->wdTimer;
|
||||
}
|
||||
|
||||
if (client->retransmitTimer != Q_NULLPTR) {
|
||||
client->retransmitTimer->stop();
|
||||
|
@ -213,10 +213,6 @@ void udpServer::controlReceived()
|
|||
connect(current->idleTimer, &QTimer::timeout, this, std::bind(&udpServer::sendControl, this, current, (quint8)0x00, (quint16)0x00));
|
||||
current->idleTimer->start(100);
|
||||
|
||||
current->wdTimer = new QTimer();
|
||||
connect(current->wdTimer, &QTimer::timeout, this, std::bind(&udpServer::watchdog, this, current));
|
||||
//current->wdTimer->start(1000);
|
||||
|
||||
current->retransmitTimer = new QTimer();
|
||||
connect(current->retransmitTimer, &QTimer::timeout, this, std::bind(&udpServer::sendRetransmitRequest, this, current));
|
||||
current->retransmitTimer->start(RETRANSMIT_PERIOD);
|
||||
|
@ -242,8 +238,15 @@ void udpServer::controlReceived()
|
|||
{
|
||||
qInfo(logUdpServer()) << current->ipAddress.toString() << ": Received 'disconnect' request";
|
||||
sendControl(current, 0x00, in->seq);
|
||||
//current->wdTimer->stop(); // Keep watchdog running to delete stale connection.
|
||||
|
||||
if (current->audioClient != Q_NULLPTR) {
|
||||
deleteConnection(&audioClients, current->audioClient);
|
||||
}
|
||||
if (current->civClient != Q_NULLPTR) {
|
||||
deleteConnection(&civClients, current->civClient);
|
||||
}
|
||||
deleteConnection(&controlClients, current);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -315,14 +318,12 @@ void udpServer::controlReceived()
|
|||
passcode(user.username, usercomp);
|
||||
QByteArray passcomp;
|
||||
passcode(user.password, passcomp);
|
||||
if (!strcmp(in->username, usercomp.constData()) && !strcmp(in->password, passcomp.constData()))
|
||||
if (!strcmp(in->username, usercomp.constData()) && (!strcmp(in->password, user.password.toUtf8()) || !strcmp(in->password, passcomp.constData())))
|
||||
{
|
||||
current->isAuthenticated = true;
|
||||
current->user = user;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// Generate login response
|
||||
current->rxSeq = in->seq;
|
||||
|
@ -423,11 +424,11 @@ void udpServer::controlReceived()
|
|||
break;
|
||||
}
|
||||
}
|
||||
// Report current connections:
|
||||
emit haveNetworkStatus(QString("<pre>Server connections: Control:%1 CI-V:%2 Audio:%3</pre>").arg(controlClients.size()).arg(civClients.size()).arg(audioClients.size()));
|
||||
|
||||
commonReceived(&controlClients, current, r);
|
||||
|
||||
// Connection "may" have been deleted so check before calling common function.
|
||||
if (current != Q_NULLPTR) {
|
||||
commonReceived(&controlClients, current, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -445,22 +446,6 @@ void udpServer::civReceived()
|
|||
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
|
||||
bool userOK = false;
|
||||
foreach(CLIENT * client, controlClients)
|
||||
{
|
||||
if (client != Q_NULLPTR)
|
||||
{
|
||||
if (client->ipAddress == datagram.senderAddress() && client->isAuthenticated)
|
||||
{
|
||||
userOK = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!userOK)
|
||||
{
|
||||
qDebug(logUdpServer()) << "user is NOT authenticated but attempted CI-V connection!";
|
||||
}
|
||||
|
||||
foreach(CLIENT * client, civClients)
|
||||
{
|
||||
if (client != Q_NULLPTR)
|
||||
|
@ -469,13 +454,25 @@ void udpServer::civReceived()
|
|||
{
|
||||
current = client;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (current == Q_NULLPTR)
|
||||
{
|
||||
current = new CLIENT();
|
||||
|
||||
foreach(CLIENT* client, controlClients)
|
||||
{
|
||||
if (client != Q_NULLPTR)
|
||||
{
|
||||
if (client->ipAddress == datagram.senderAddress() && client->isAuthenticated && client->civClient == Q_NULLPTR)
|
||||
{
|
||||
current->controlClient = client;
|
||||
client->civClient = current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
current->type = "CIV";
|
||||
current->civId = 0;
|
||||
current->connected = true;
|
||||
|
@ -495,10 +492,6 @@ void udpServer::civReceived()
|
|||
connect(current->idleTimer, &QTimer::timeout, this, std::bind(&udpServer::sendControl, this, current, 0x00, (quint16)0x00));
|
||||
//current->idleTimer->start(100); // Start idleTimer after receiving iamready.
|
||||
|
||||
current->wdTimer = new QTimer();
|
||||
connect(current->wdTimer, &QTimer::timeout, this, std::bind(&udpServer::watchdog, this, current));
|
||||
//current->wdTimer->start(1000);
|
||||
|
||||
current->retransmitTimer = new QTimer();
|
||||
connect(current->retransmitTimer, &QTimer::timeout, this, std::bind(&udpServer::sendRetransmitRequest, this, current));
|
||||
current->retransmitTimer->start(RETRANSMIT_PERIOD);
|
||||
|
@ -510,6 +503,11 @@ void udpServer::civReceived()
|
|||
|
||||
}
|
||||
|
||||
if (current->controlClient == Q_NULLPTR || !current->controlClient->isAuthenticated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (r.length())
|
||||
{
|
||||
/* case (CONTROL_SIZE):
|
||||
|
@ -598,22 +596,6 @@ void udpServer::audioReceived()
|
|||
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
|
||||
bool userOK = false;
|
||||
foreach(CLIENT * client, controlClients)
|
||||
{
|
||||
if (client != Q_NULLPTR)
|
||||
{
|
||||
if (client->ipAddress == datagram.senderAddress() && client->isAuthenticated)
|
||||
{
|
||||
userOK = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!userOK)
|
||||
{
|
||||
qDebug(logUdpServer()) << "user is NOT authenticated but attempted CI-V connection!";
|
||||
}
|
||||
|
||||
foreach(CLIENT * client, audioClients)
|
||||
{
|
||||
if (client != Q_NULLPTR)
|
||||
|
@ -627,6 +609,17 @@ void udpServer::audioReceived()
|
|||
if (current == Q_NULLPTR)
|
||||
{
|
||||
current = new CLIENT();
|
||||
foreach(CLIENT* client, controlClients)
|
||||
{
|
||||
if (client != Q_NULLPTR)
|
||||
{
|
||||
if (client->ipAddress == datagram.senderAddress() && client->isAuthenticated && client->audioClient == Q_NULLPTR)
|
||||
{
|
||||
current->controlClient = client;
|
||||
client->audioClient = current;
|
||||
}
|
||||
}
|
||||
}
|
||||
current->type = "Audio";
|
||||
current->connected = true;
|
||||
current->timeConnected = QDateTime::currentDateTime();
|
||||
|
@ -641,10 +634,6 @@ void udpServer::audioReceived()
|
|||
connect(current->pingTimer, &QTimer::timeout, this, std::bind(&udpServer::sendPing, this, &audioClients, current, (quint16)0x00, false));
|
||||
current->pingTimer->start(100);
|
||||
|
||||
current->wdTimer = new QTimer();
|
||||
connect(current->wdTimer, &QTimer::timeout, this, std::bind(&udpServer::watchdog, this, current));
|
||||
//current->wdTimer->start(1000);
|
||||
|
||||
current->retransmitTimer = new QTimer();
|
||||
connect(current->retransmitTimer, &QTimer::timeout, this, std::bind(&udpServer::sendRetransmitRequest, this, current));
|
||||
current->retransmitTimer->start(RETRANSMIT_PERIOD);
|
||||
|
@ -913,7 +902,8 @@ void udpServer::sendControl(CLIENT* c, quint8 type, quint16 seq)
|
|||
|
||||
void udpServer::sendPing(QList<CLIENT*>* l, CLIENT* c, quint16 seq, bool reply)
|
||||
{
|
||||
// Also use to detect "stale" connections
|
||||
Q_UNUSED(l);
|
||||
/*
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
|
||||
if (c->lastHeard.secsTo(now) > STALE_CONNECTION)
|
||||
|
@ -923,6 +913,7 @@ void udpServer::sendPing(QList<CLIENT*>* l, CLIENT* c, quint16 seq, bool reply)
|
|||
return;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
//qInfo(logUdpServer()) << c->ipAddress.toString() << ": Sending Ping";
|
||||
|
||||
|
@ -981,8 +972,6 @@ void udpServer::sendLoginResponse(CLIENT* c, bool allowed)
|
|||
c->pingTimer->stop();
|
||||
if (c->retransmitTimer != Q_NULLPTR)
|
||||
c->retransmitTimer->stop();
|
||||
if (c->wdTimer != Q_NULLPTR)
|
||||
c->wdTimer->stop();
|
||||
}
|
||||
else {
|
||||
strcpy(p.connection, "WFVIEW");
|
||||
|
@ -1226,10 +1215,56 @@ void udpServer::sendTokenResponse(CLIENT* c, quint8 type)
|
|||
|
||||
#define PURGE_SECONDS 60
|
||||
|
||||
void udpServer::watchdog(CLIENT* c)
|
||||
void udpServer::watchdog()
|
||||
{
|
||||
Q_UNUSED(c);
|
||||
// Do something!
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
|
||||
foreach(CLIENT * client, audioClients)
|
||||
{
|
||||
if (client != Q_NULLPTR)
|
||||
{
|
||||
if (client->lastHeard.secsTo(now) > STALE_CONNECTION)
|
||||
{
|
||||
qInfo(logUdpServer()) << client->ipAddress.toString() << "(" << client->type << "): Deleting stale connection ";
|
||||
deleteConnection(&audioClients, client);
|
||||
}
|
||||
}
|
||||
else {
|
||||
qInfo(logUdpServer()) << "Current client is NULL!";
|
||||
}
|
||||
}
|
||||
|
||||
foreach(CLIENT* client, civClients)
|
||||
{
|
||||
if (client != Q_NULLPTR)
|
||||
{
|
||||
if (client->lastHeard.secsTo(now) > STALE_CONNECTION)
|
||||
{
|
||||
qInfo(logUdpServer()) << client->ipAddress.toString() << "(" << client->type << "): Deleting stale connection ";
|
||||
deleteConnection(&civClients, client);
|
||||
}
|
||||
}
|
||||
else {
|
||||
qInfo(logUdpServer()) << "Current client is NULL!";
|
||||
}
|
||||
}
|
||||
|
||||
foreach(CLIENT* client, controlClients)
|
||||
{
|
||||
if (client != Q_NULLPTR)
|
||||
{
|
||||
if (client->lastHeard.secsTo(now) > STALE_CONNECTION)
|
||||
{
|
||||
qInfo(logUdpServer()) << client->ipAddress.toString() << "(" << client->type << "): Deleting stale connection ";
|
||||
deleteConnection(&controlClients, client);
|
||||
}
|
||||
}
|
||||
else {
|
||||
qInfo(logUdpServer()) << "Current client is NULL!";
|
||||
}
|
||||
}
|
||||
|
||||
emit haveNetworkStatus(QString("<pre>Server connections: Control:%1 CI-V:%2 Audio:%3</pre>").arg(controlClients.size()).arg(civClients.size()).arg(audioClients.size()));
|
||||
}
|
||||
|
||||
void udpServer::sendStatus(CLIENT* c)
|
||||
|
@ -1511,7 +1546,7 @@ void udpServer::sendRetransmitRequest(CLIENT* c)
|
|||
void udpServer::deleteConnection(QList<CLIENT*>* l, CLIENT* c)
|
||||
{
|
||||
|
||||
qInfo(logUdpServer()) << "Deleting connection to: " << c->ipAddress.toString() << ":" << QString::number(c->port);
|
||||
qInfo(logUdpServer()) << "Deleting" << c->type << "connection to: " << c->ipAddress.toString() << ":" << QString::number(c->port);
|
||||
if (c->idleTimer != Q_NULLPTR) {
|
||||
c->idleTimer->stop();
|
||||
delete c->idleTimer;
|
||||
|
@ -1520,10 +1555,6 @@ void udpServer::deleteConnection(QList<CLIENT*>* l, CLIENT* c)
|
|||
c->pingTimer->stop();
|
||||
delete c->pingTimer;
|
||||
}
|
||||
if (c->wdTimer != Q_NULLPTR) {
|
||||
c->wdTimer->stop();
|
||||
delete c->wdTimer;
|
||||
}
|
||||
|
||||
if (c->retransmitTimer != Q_NULLPTR) {
|
||||
c->retransmitTimer->stop();
|
||||
|
|
|
@ -94,7 +94,6 @@ private:
|
|||
|
||||
QTimer* pingTimer;
|
||||
QTimer* idleTimer;
|
||||
QTimer* wdTimer;
|
||||
QTimer* retransmitTimer;
|
||||
|
||||
// Only used for audio.
|
||||
|
@ -117,6 +116,9 @@ private:
|
|||
|
||||
quint8 civId;
|
||||
bool isAuthenticated;
|
||||
CLIENT* controlClient = Q_NULLPTR;
|
||||
CLIENT* civClient = Q_NULLPTR;
|
||||
CLIENT* audioClient = Q_NULLPTR;
|
||||
};
|
||||
|
||||
void controlReceived();
|
||||
|
@ -132,7 +134,7 @@ private:
|
|||
void sendTokenResponse(CLIENT* c,quint8 type);
|
||||
void sendStatus(CLIENT* c);
|
||||
void sendRetransmitRequest(CLIENT* c);
|
||||
void watchdog(CLIENT* c);
|
||||
void watchdog();
|
||||
void sendRxAudio();
|
||||
void deleteConnection(QList<CLIENT*> *l, CLIENT* c);
|
||||
|
||||
|
@ -175,6 +177,7 @@ private:
|
|||
quint8 txCodec = 0;
|
||||
|
||||
QHostAddress hasTxAudio;
|
||||
QTimer* wdTimer;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2,11 +2,15 @@
|
|||
#include "ui_udpserversetup.h"
|
||||
#include "logcategories.h"
|
||||
|
||||
extern void passcode(QString in,QByteArray& out);
|
||||
|
||||
udpServerSetup::udpServerSetup(QWidget* parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::udpServerSetup)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
addUserLine("", "", 0); // Create a blank row if we never receive config.
|
||||
|
||||
// Get any stored config information from the main form.
|
||||
SERVERCONFIG config;
|
||||
emit serverConfig(config,false); // Just send blank server config.
|
||||
|
@ -29,43 +33,22 @@ void udpServerSetup::receiveServerConfig(SERVERCONFIG conf)
|
|||
|
||||
int row = 0;
|
||||
|
||||
for (int i = 0; i < ui->usersTable->rowCount(); i++)
|
||||
{
|
||||
ui->usersTable->removeRow(i);
|
||||
}
|
||||
|
||||
foreach (SERVERUSER user, conf.users)
|
||||
{
|
||||
if (user.username != "" && user.password != "")
|
||||
{
|
||||
if (ui->usersTable->rowCount() <= row) {
|
||||
ui->usersTable->insertRow(ui->usersTable->rowCount());
|
||||
}
|
||||
ui->usersTable->setItem(row, 0, new QTableWidgetItem(user.username));
|
||||
ui->usersTable->setItem(row, 1, new QTableWidgetItem(user.password));
|
||||
QComboBox* comboBox = new QComboBox();
|
||||
comboBox->insertItems(0, { "Full User","Full with no TX","Monitor only" });
|
||||
comboBox->setCurrentIndex(user.userType);
|
||||
ui->usersTable->setCellWidget(row, 2, comboBox);
|
||||
addUserLine(user.username, user.password, user.userType);
|
||||
row++;
|
||||
}
|
||||
}
|
||||
// Delete any rows no longer needed
|
||||
int count=0;
|
||||
|
||||
for (count = row; count <= ui->usersTable->rowCount(); count++)
|
||||
{
|
||||
if (count == conf.users.count()) {
|
||||
ui->usersTable->insertRow(ui->usersTable->rowCount());
|
||||
QComboBox* comboBox = new QComboBox();
|
||||
comboBox->insertItems(0, { "Full User","Full with no TX","Monitor only" });
|
||||
ui->usersTable->setCellWidget(count, 2, comboBox);
|
||||
}
|
||||
else if (count > conf.users.count()) {
|
||||
ui->usersTable->removeRow(count);
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
ui->usersTable->insertRow(ui->usersTable->rowCount());
|
||||
QComboBox* comboBox = new QComboBox();
|
||||
comboBox->insertItems(0, { "Full User","Full with no TX","Monitor only" });
|
||||
ui->usersTable->setCellWidget(count, 2, comboBox);
|
||||
if (row == 0) {
|
||||
addUserLine("", "", 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -83,11 +66,12 @@ void udpServerSetup::accept()
|
|||
|
||||
for (int row = 0; row < ui->usersTable->model()->rowCount(); row++)
|
||||
{
|
||||
if (ui->usersTable->item(row, 0) != NULL && ui->usersTable->item(row, 1) != NULL)
|
||||
if (ui->usersTable->item(row, 0) != NULL)
|
||||
{
|
||||
SERVERUSER user;
|
||||
user.username = ui->usersTable->item(row, 0)->text();
|
||||
user.password = ui->usersTable->item(row, 1)->text();
|
||||
QLineEdit* password = (QLineEdit*)ui->usersTable->cellWidget(row, 1);
|
||||
user.password = password->text();
|
||||
QComboBox* comboBox = (QComboBox*)ui->usersTable->cellWidget(row, 2);
|
||||
user.userType = comboBox->currentIndex();
|
||||
config.users.append(user);
|
||||
|
@ -106,13 +90,38 @@ void udpServerSetup::accept()
|
|||
void udpServerSetup::on_usersTable_cellClicked(int row, int col)
|
||||
{
|
||||
qInfo() << "Clicked on " << row << "," << col;
|
||||
if (row == ui->usersTable->model()->rowCount() - 1 && ui->usersTable->item(row, 0) != NULL && ui->usersTable->item(row, 1) != NULL) {
|
||||
ui->usersTable->insertRow(ui->usersTable->rowCount());
|
||||
QComboBox* comboBox = new QComboBox();
|
||||
comboBox->insertItems(0, { "Full User","Full with no TX","Monitor only" });
|
||||
userTypes.append(comboBox);
|
||||
ui->usersTable->setCellWidget(ui->usersTable->rowCount() - 1, 2, comboBox);
|
||||
|
||||
if (row == ui->usersTable->model()->rowCount() - 1 && ui->usersTable->item(row, 0) != NULL) {
|
||||
addUserLine("", "", 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void udpServerSetup::onPasswordChanged()
|
||||
{
|
||||
int row = sender()->property("row").toInt();
|
||||
QLineEdit* password = (QLineEdit*)ui->usersTable->cellWidget(row, 1);
|
||||
QByteArray pass;
|
||||
passcode(password->text(), pass);
|
||||
password->setText(pass);
|
||||
qInfo() << "password row" << row << "changed";
|
||||
}
|
||||
|
||||
void udpServerSetup::addUserLine(const QString& user, const QString& pass, const int& type)
|
||||
{
|
||||
ui->usersTable->insertRow(ui->usersTable->rowCount());
|
||||
ui->usersTable->setItem(ui->usersTable->rowCount() - 1, 0, new QTableWidgetItem(user));
|
||||
ui->usersTable->setItem(ui->usersTable->rowCount() - 1, 1, new QTableWidgetItem());
|
||||
ui->usersTable->setItem(ui->usersTable->rowCount() - 1, 2, new QTableWidgetItem());
|
||||
|
||||
QLineEdit* password = new QLineEdit();
|
||||
password->setProperty("row", (int)ui->usersTable->rowCount() - 1);
|
||||
password->setEchoMode(QLineEdit::PasswordEchoOnEdit);
|
||||
password->setText(pass);
|
||||
connect(password, SIGNAL(editingFinished()), this, SLOT(onPasswordChanged()));
|
||||
ui->usersTable->setCellWidget(ui->usersTable->rowCount() - 1, 1, password);
|
||||
|
||||
QComboBox* comboBox = new QComboBox();
|
||||
comboBox->insertItems(0, { "Full User","Full with no TX","Monitor only" });
|
||||
comboBox->setCurrentIndex(type);
|
||||
ui->usersTable->setCellWidget(ui->usersTable->rowCount() - 1, 2, comboBox);
|
||||
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ public:
|
|||
|
||||
private slots:
|
||||
void on_usersTable_cellClicked(int row, int col);
|
||||
void onPasswordChanged();
|
||||
|
||||
public slots:
|
||||
void receiveServerConfig(SERVERCONFIG conf);
|
||||
|
@ -53,6 +54,7 @@ private:
|
|||
Ui::udpServerSetup* ui;
|
||||
void accept();
|
||||
QList<QComboBox*> userTypes;
|
||||
void addUserLine(const QString &user, const QString &pass, const int &type);
|
||||
};
|
||||
|
||||
#endif // UDPSERVER_H
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>440</width>
|
||||
<height>351</height>
|
||||
<height>361</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
|
|
916
wfmain.cpp
916
wfmain.cpp
Plik diff jest za duży
Load Diff
28
wfmain.h
28
wfmain.h
|
@ -31,6 +31,8 @@
|
|||
#include <qserialportinfo.h>
|
||||
#include "shuttle.h"
|
||||
|
||||
#include <deque>
|
||||
|
||||
namespace Ui {
|
||||
class wfmain;
|
||||
}
|
||||
|
@ -147,6 +149,7 @@ signals:
|
|||
void openShuttle();
|
||||
|
||||
private slots:
|
||||
void updateSizes(int tabIndex);
|
||||
void shortcutF1();
|
||||
void shortcutF2();
|
||||
void shortcutF3();
|
||||
|
@ -240,8 +243,7 @@ private slots:
|
|||
void handleWFDoubleClick(QMouseEvent *);
|
||||
void handleWFScroll(QWheelEvent *);
|
||||
void handlePlotScroll(QWheelEvent *);
|
||||
void runDelayedCommand();
|
||||
void runPeriodicCommands();
|
||||
void sendRadioCommandLoop();
|
||||
void showStatusBarText(QString text);
|
||||
void serverConfigRequested(SERVERCONFIG conf, bool store);
|
||||
void receiveBaudRate(quint32 baudrate);
|
||||
|
@ -458,6 +460,8 @@ private slots:
|
|||
|
||||
void on_wfLengthSlider_valueChanged(int value);
|
||||
|
||||
void on_pollingBtn_clicked();
|
||||
|
||||
private:
|
||||
Ui::wfmain *ui;
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
@ -472,6 +476,7 @@ private:
|
|||
void setPlotTheme(QCustomPlot *plot, bool isDark);
|
||||
void prepareWf();
|
||||
void prepareWf(unsigned int wfLength);
|
||||
void showHideSpectrum(bool show);
|
||||
void getInitialRigState();
|
||||
void setBandButtons();
|
||||
void showButton(QPushButton *btn);
|
||||
|
@ -519,6 +524,8 @@ private:
|
|||
QShortcut *keyF;
|
||||
QShortcut *keyM;
|
||||
|
||||
QShortcut *keyDebug;
|
||||
|
||||
|
||||
rigCommander * rig=Q_NULLPTR;
|
||||
QThread* rigThread = Q_NULLPTR;
|
||||
|
@ -526,8 +533,9 @@ private:
|
|||
QCPColorMapData * colorMapData;
|
||||
QCPColorScale * colorScale;
|
||||
QTimer * delayedCommand;
|
||||
QTimer * periodicPollingTimer;
|
||||
QTimer * pttTimer;
|
||||
uint16_t loopTickCounter;
|
||||
uint16_t slowCmdNum;
|
||||
|
||||
void setupPlots();
|
||||
void makeRig();
|
||||
|
@ -568,6 +576,7 @@ private:
|
|||
int smeterPos=0;
|
||||
|
||||
QVector <QByteArray> wfimage;
|
||||
unsigned int wfLengthMax;
|
||||
|
||||
bool onFullscreen;
|
||||
bool drawPeaks;
|
||||
|
@ -588,16 +597,18 @@ private:
|
|||
cmdGetSql, cmdGetATUStatus, cmdGetSpectrumMode, cmdGetSpectrumSpan, cmdScopeCenterMode, cmdScopeFixedMode, cmdGetPTT,
|
||||
cmdGetTxPower, cmdGetMicGain, cmdGetSpectrumRefLevel, cmdGetDuplexMode, cmdGetModInput, cmdGetModDataInput,
|
||||
cmdGetCurrentModLevel, cmdStartRegularPolling, cmdStopRegularPolling, cmdQueNormalSpeed,
|
||||
cmdGetVdMeter, cmdGetIdMeter, cmdGetSMeter, cmdGetPowerMeter, cmdGetALCMeter, cmdGetCompMeter,
|
||||
cmdGetVdMeter, cmdGetIdMeter, cmdGetSMeter, cmdGetPowerMeter, cmdGetALCMeter, cmdGetCompMeter, cmdGetTxRxMeter,
|
||||
cmdGetTone, cmdGetTSQL, cmdGetDTCS, cmdGetRptAccessMode, cmdGetPreamp, cmdGetAttenuator, cmdGetAntenna};
|
||||
|
||||
cmds cmdOut;
|
||||
QVector <cmds> cmdOutQue;
|
||||
QVector <cmds> periodicCmdQueue;
|
||||
std::deque <cmds> delayedCmdQue;
|
||||
std::deque <cmds> periodicCmdQueue;
|
||||
std::deque <cmds> slowPollCmdQueue;
|
||||
void doCmd(cmds cmd);
|
||||
int pCmdNum = 0;
|
||||
int delayedCmdIntervalLAN_ms = 100;
|
||||
int delayedCmdIntervalSerial_ms = 100;
|
||||
int delayedCmdStartupInterval_ms = 100;
|
||||
bool runPeriodicCommands;
|
||||
bool usingLAN = false;
|
||||
|
||||
freqMemory mem;
|
||||
|
@ -671,6 +682,8 @@ private:
|
|||
void issueDelayedCommandPriority(cmds cmd);
|
||||
void issueDelayedCommandUnique(cmds cmd);
|
||||
void changeSliderQuietly(QSlider *slider, int value);
|
||||
void statusFromSliderPercent(QString name, int percentValue);
|
||||
void statusFromSliderRaw(QString name, int rawValue);
|
||||
|
||||
void processModLevel(rigInput source, unsigned char level);
|
||||
|
||||
|
@ -683,6 +696,7 @@ private:
|
|||
|
||||
void initPeriodicCommands();
|
||||
void insertPeriodicCommand(cmds cmd, unsigned char priority);
|
||||
void insertSlowPeriodicCommand(cmds cmd, unsigned char priority);
|
||||
void calculateTimingParameters();
|
||||
|
||||
void changeMode(mode_kind mode);
|
||||
|
|
32
wfmain.ui
32
wfmain.ui
|
@ -18,7 +18,7 @@
|
|||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>3</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="mainTab">
|
||||
<attribute name="title">
|
||||
|
@ -26,7 +26,7 @@
|
|||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<widget class="QGroupBox" name="spectrumGroupBox">
|
||||
<property name="title">
|
||||
<string>Spectrum</string>
|
||||
</property>
|
||||
|
@ -44,12 +44,12 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_13">
|
||||
<layout class="QHBoxLayout" name="specControlsHorizLayout">
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_26">
|
||||
<widget class="QLabel" name="specModeLabel">
|
||||
<property name="text">
|
||||
<string>Spectrum Mode: </string>
|
||||
</property>
|
||||
|
@ -66,7 +66,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<widget class="QLabel" name="specSpanLabel">
|
||||
<property name="text">
|
||||
<string>Span:</string>
|
||||
</property>
|
||||
|
@ -86,7 +86,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<widget class="QLabel" name="specEdgeLabel">
|
||||
<property name="text">
|
||||
<string>Edge</string>
|
||||
</property>
|
||||
|
@ -133,7 +133,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_31">
|
||||
<widget class="QLabel" name="specThemeLabel">
|
||||
<property name="text">
|
||||
<string>Theme:</string>
|
||||
</property>
|
||||
|
@ -150,7 +150,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<spacer name="specHorizSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
|
@ -2612,6 +2612,22 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pollingBtn">
|
||||
<property name="toolTip">
|
||||
<string>Set up radio polling. The radio's meter is polled every-other interval.</string>
|
||||
</property>
|
||||
<property name="accessibleName">
|
||||
<string>Polling</string>
|
||||
</property>
|
||||
<property name="accessibleDescription">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Polling</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
|
|
13
wfview.pro
13
wfview.pro
|
@ -31,7 +31,10 @@ linux:QMAKE_LFLAGS += -O2 -s
|
|||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
DEFINES += QCUSTOMPLOT_COMPILE_LIBRARY
|
||||
|
||||
|
||||
# These defines are used for the resampler
|
||||
equals(QT_ARCH, i386): DEFINES += USE_SSE
|
||||
equals(QT_ARCH, arm): DEFINES += USE_NEON
|
||||
DEFINES += OUTSIDE_SPEEX
|
||||
DEFINES += RANDOM_PREFIX=wf
|
||||
|
||||
|
@ -107,7 +110,7 @@ win32:INCLUDEPATH += ../hidapi/hidapi
|
|||
|
||||
!linux:INCLUDEPATH += ../qcustomplot
|
||||
|
||||
INCLUDEPATH += opus-tools/src
|
||||
INCLUDEPATH += resampler
|
||||
!linux:INCLUDEPATH += rtaudio
|
||||
|
||||
SOURCES += main.cpp\
|
||||
|
@ -126,7 +129,7 @@ SOURCES += main.cpp\
|
|||
meter.cpp \
|
||||
qledlabel.cpp \
|
||||
pttyhandler.cpp \
|
||||
opus-tools/src/resample.c \
|
||||
resampler/resample.c \
|
||||
repeatersetup.cpp \
|
||||
rigctld.cpp \
|
||||
ring/ring.cpp \
|
||||
|
@ -148,9 +151,9 @@ HEADERS += wfmain.h \
|
|||
meter.h \
|
||||
qledlabel.h \
|
||||
pttyhandler.h \
|
||||
opus-tools/src/speex_resampler.h \
|
||||
opus-tools/src/arch.h \
|
||||
opus-tools/src/resample_sse.h \
|
||||
resampler/speex_resampler.h \
|
||||
resampler/arch.h \
|
||||
resampler/resample_sse.h \
|
||||
repeatersetup.h \
|
||||
repeaterattributes.h \
|
||||
rigctld.h \
|
||||
|
|
Ładowanie…
Reference in New Issue