Added I decoder and reorganized the E selection code
This commit is contained in:
parent
f706685cc9
commit
5215fd324d
@ -304,6 +304,8 @@ set (wsjt_FSRCS
|
|||||||
lib/js8c_decode.f90
|
lib/js8c_decode.f90
|
||||||
lib/js8e_module.f90
|
lib/js8e_module.f90
|
||||||
lib/js8e_decode.f90
|
lib/js8e_decode.f90
|
||||||
|
lib/js8i_module.f90
|
||||||
|
lib/js8i_decode.f90
|
||||||
|
|
||||||
# remaining non-module sources
|
# remaining non-module sources
|
||||||
lib/addit.f90
|
lib/addit.f90
|
||||||
@ -420,6 +422,7 @@ set (wsjt_FSRCS
|
|||||||
lib/js8/ldpcsim174js8b.f90
|
lib/js8/ldpcsim174js8b.f90
|
||||||
lib/js8/ldpcsim174js8c.f90
|
lib/js8/ldpcsim174js8c.f90
|
||||||
lib/js8/ldpcsim174js8e.f90
|
lib/js8/ldpcsim174js8e.f90
|
||||||
|
lib/js8/ldpcsim174js8i.f90
|
||||||
lib/ldpcsim40.f90
|
lib/ldpcsim40.f90
|
||||||
lib/libration.f90
|
lib/libration.f90
|
||||||
lib/lorentzian.f90
|
lib/lorentzian.f90
|
||||||
@ -1006,6 +1009,9 @@ target_link_libraries (ldpcsim174js8c wsjt_fort wsjt_cxx)
|
|||||||
add_executable (ldpcsim174js8e lib/js8/ldpcsim174js8e.f90 wsjtx.rc)
|
add_executable (ldpcsim174js8e lib/js8/ldpcsim174js8e.f90 wsjtx.rc)
|
||||||
target_link_libraries (ldpcsim174js8e wsjt_fort wsjt_cxx)
|
target_link_libraries (ldpcsim174js8e wsjt_fort wsjt_cxx)
|
||||||
|
|
||||||
|
add_executable (ldpcsim174js8i lib/js8/ldpcsim174js8i.f90 wsjtx.rc)
|
||||||
|
target_link_libraries (ldpcsim174js8i wsjt_fort wsjt_cxx)
|
||||||
|
|
||||||
add_executable (js8 ${js8_FSRCS} ${js8_CXXSRCS} wsjtx.rc)
|
add_executable (js8 ${js8_FSRCS} ${js8_CXXSRCS} wsjtx.rc)
|
||||||
if (${OPENMP_FOUND} OR APPLE)
|
if (${OPENMP_FOUND} OR APPLE)
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
|
@ -84,6 +84,9 @@ void Modulator::start (unsigned symbolsLength, double framesPerSymbol,
|
|||||||
else if(m_TRperiod == JS8E_TX_SECONDS){
|
else if(m_TRperiod == JS8E_TX_SECONDS){
|
||||||
delay_ms = JS8E_START_DELAY_MS;
|
delay_ms = JS8E_START_DELAY_MS;
|
||||||
}
|
}
|
||||||
|
else if(m_TRperiod == JS8I_TX_SECONDS){
|
||||||
|
delay_ms = JS8I_START_DELAY_MS;
|
||||||
|
}
|
||||||
|
|
||||||
// noise generator parameters
|
// noise generator parameters
|
||||||
if (m_addNoise) {
|
if (m_addNoise) {
|
||||||
|
14
commons.h
14
commons.h
@ -24,6 +24,7 @@
|
|||||||
#define JS8_ENABLE_JS8B 1
|
#define JS8_ENABLE_JS8B 1
|
||||||
#define JS8_ENABLE_JS8C 1
|
#define JS8_ENABLE_JS8C 1
|
||||||
#define JS8_ENABLE_JS8E 1
|
#define JS8_ENABLE_JS8E 1
|
||||||
|
#define JS8_ENABLE_JS8I 0
|
||||||
|
|
||||||
#define JS8A_SYMBOL_SAMPLES 1920
|
#define JS8A_SYMBOL_SAMPLES 1920
|
||||||
#define JS8A_TX_SECONDS 15
|
#define JS8A_TX_SECONDS 15
|
||||||
@ -37,16 +38,13 @@
|
|||||||
#define JS8C_TX_SECONDS 6
|
#define JS8C_TX_SECONDS 6
|
||||||
#define JS8C_START_DELAY_MS 100
|
#define JS8C_START_DELAY_MS 100
|
||||||
|
|
||||||
#define JS8E_IS_ULTRA 0
|
|
||||||
#if JS8E_IS_ULTRA
|
|
||||||
#define JS8E_SYMBOL_SAMPLES 384
|
|
||||||
#define JS8E_TX_SECONDS 4
|
|
||||||
#define JS8E_START_DELAY_MS 100
|
|
||||||
#else
|
|
||||||
#define JS8E_SYMBOL_SAMPLES 4000
|
#define JS8E_SYMBOL_SAMPLES 4000
|
||||||
#define JS8E_TX_SECONDS 30
|
#define JS8E_TX_SECONDS 30
|
||||||
#define JS8E_START_DELAY_MS 500
|
#define JS8E_START_DELAY_MS 500
|
||||||
#endif
|
|
||||||
|
#define JS8I_SYMBOL_SAMPLES 384
|
||||||
|
#define JS8I_TX_SECONDS 4
|
||||||
|
#define JS8I_START_DELAY_MS 100
|
||||||
|
|
||||||
#ifndef TEST_FOX_WAVE_GEN
|
#ifndef TEST_FOX_WAVE_GEN
|
||||||
#define TEST_FOX_WAVE_GEN 0
|
#define TEST_FOX_WAVE_GEN 0
|
||||||
@ -104,10 +102,12 @@ extern struct dec_data {
|
|||||||
int kposB; // starting position of decode for submode B
|
int kposB; // starting position of decode for submode B
|
||||||
int kposC; // starting position of decode for submode C
|
int kposC; // starting position of decode for submode C
|
||||||
int kposE; // starting position of decode for submode E
|
int kposE; // starting position of decode for submode E
|
||||||
|
int kposI; // starting position of decode for submode I
|
||||||
int kszA; // number of frames for decode for submode A
|
int kszA; // number of frames for decode for submode A
|
||||||
int kszB; // number of frames for decode for submode B
|
int kszB; // number of frames for decode for submode B
|
||||||
int kszC; // number of frames for decode for submode C
|
int kszC; // number of frames for decode for submode C
|
||||||
int kszE; // number of frames for decode for submode E
|
int kszE; // number of frames for decode for submode E
|
||||||
|
int kszI; // number of frames for decode for submode I
|
||||||
int nzhsym; // half symbol stop index
|
int nzhsym; // half symbol stop index
|
||||||
int nsubmode;
|
int nsubmode;
|
||||||
int nsubmodes;
|
int nsubmodes;
|
||||||
|
@ -259,7 +259,12 @@ bool DecodedText::tryUnpackFastData(){
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(submode_ != Varicode::JS8CallFast && submode_ != Varicode::JS8CallTurbo && submode_ != Varicode::JS8CallUltraSlow){
|
if(
|
||||||
|
submode_ != Varicode::JS8CallFast &&
|
||||||
|
submode_ != Varicode::JS8CallTurbo &&
|
||||||
|
submode_ != Varicode::JS8CallSlow &&
|
||||||
|
submode_ != Varicode::JS8CallUltra
|
||||||
|
){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
|
|||||||
use js8b_decode
|
use js8b_decode
|
||||||
use js8c_decode
|
use js8c_decode
|
||||||
use js8e_decode
|
use js8e_decode
|
||||||
|
use js8i_decode
|
||||||
|
|
||||||
include 'jt9com.f90'
|
include 'jt9com.f90'
|
||||||
include 'timer_common.inc'
|
include 'timer_common.inc'
|
||||||
@ -27,6 +28,10 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
|
|||||||
integer :: decoded
|
integer :: decoded
|
||||||
end type counting_js8e_decoder
|
end type counting_js8e_decoder
|
||||||
|
|
||||||
|
type, extends(js8i_decoder) :: counting_js8i_decoder
|
||||||
|
integer :: decoded
|
||||||
|
end type counting_js8i_decoder
|
||||||
|
|
||||||
real ss(184,NSMAX)
|
real ss(184,NSMAX)
|
||||||
logical baddata,newdat65,newdat9,single_decode,bVHF,bad0,newdat,trydecode
|
logical baddata,newdat65,newdat9,single_decode,bVHF,bad0,newdat,trydecode
|
||||||
integer*2 id0(NTMAX*12000)
|
integer*2 id0(NTMAX*12000)
|
||||||
@ -40,6 +45,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
|
|||||||
type(counting_js8b_decoder) :: my_js8b
|
type(counting_js8b_decoder) :: my_js8b
|
||||||
type(counting_js8c_decoder) :: my_js8c
|
type(counting_js8c_decoder) :: my_js8c
|
||||||
type(counting_js8e_decoder) :: my_js8e
|
type(counting_js8e_decoder) :: my_js8e
|
||||||
|
type(counting_js8i_decoder) :: my_js8i
|
||||||
|
|
||||||
!cast C character arrays to Fortran character strings
|
!cast C character arrays to Fortran character strings
|
||||||
datetime=transfer(params%datetime, datetime)
|
datetime=transfer(params%datetime, datetime)
|
||||||
@ -53,6 +59,7 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
|
|||||||
my_js8b%decoded = 0
|
my_js8b%decoded = 0
|
||||||
my_js8c%decoded = 0
|
my_js8c%decoded = 0
|
||||||
my_js8e%decoded = 0
|
my_js8e%decoded = 0
|
||||||
|
my_js8i%decoded = 0
|
||||||
|
|
||||||
single_decode=iand(params%nexp_decode,32).ne.0
|
single_decode=iand(params%nexp_decode,32).ne.0
|
||||||
bVHF=iand(params%nexp_decode,64).ne.0
|
bVHF=iand(params%nexp_decode,64).ne.0
|
||||||
@ -74,6 +81,29 @@ subroutine multimode_decoder(ss,id2,params,nfsample)
|
|||||||
write(*,1012) params%nsubmode, params%nsubmodes
|
write(*,1012) params%nsubmode, params%nsubmodes
|
||||||
1012 format('<DecodeStarted>',2i4)
|
1012 format('<DecodeStarted>',2i4)
|
||||||
|
|
||||||
|
if(params%nmode.eq.8 .and. (params%nsubmode.eq.8 .or. iand(params%nsubmodes, 16).eq.16)) then
|
||||||
|
! We're in JS8 mode I
|
||||||
|
call timer('decjs8i ',0)
|
||||||
|
newdat=params%newdat
|
||||||
|
write(*,*) '<DecodeDebug> mode I decode started'
|
||||||
|
|
||||||
|
! copy the relevant frames for decoding
|
||||||
|
pos = max(0,params%kposI)
|
||||||
|
sz = max(0,params%kszI)
|
||||||
|
id0=0
|
||||||
|
id0(1:sz+1)=id2(pos+1:pos+sz+1)
|
||||||
|
|
||||||
|
call my_js8i%decode(js8i_decoded,id0,params%nQSOProgress,params%nfqso, &
|
||||||
|
params%nftx,newdat,params%nutc,params%nfa,params%nfb, &
|
||||||
|
params%nexp_decode,params%ndepth,logical(params%nagain), &
|
||||||
|
logical(params%lft8apon),logical(params%lapcqonly),params%napwid, &
|
||||||
|
mycall,mygrid,hiscall,hisgrid)
|
||||||
|
|
||||||
|
write(*,*) '<DecodeDebug> mode I decode finished'
|
||||||
|
|
||||||
|
call timer('decjs8i ',1)
|
||||||
|
endif
|
||||||
|
|
||||||
if(params%nmode.eq.8 .and. (params%nsubmode.eq.4 .or. iand(params%nsubmodes, 8).eq.8)) then
|
if(params%nmode.eq.8 .and. (params%nsubmode.eq.4 .or. iand(params%nsubmodes, 8).eq.8)) then
|
||||||
! We're in JS8 mode E
|
! We're in JS8 mode E
|
||||||
call timer('decjs8e ',0)
|
call timer('decjs8e ',0)
|
||||||
@ -229,6 +259,7 @@ contains
|
|||||||
if(submode.eq.1) m=' B '
|
if(submode.eq.1) m=' B '
|
||||||
if(submode.eq.2) m=' C '
|
if(submode.eq.2) m=' C '
|
||||||
if(submode.eq.4) m=' E '
|
if(submode.eq.4) m=' E '
|
||||||
|
if(submode.eq.8) m=' I '
|
||||||
|
|
||||||
|
|
||||||
i0=index(decoded0,';')
|
i0=index(decoded0,';')
|
||||||
@ -377,4 +408,30 @@ contains
|
|||||||
return
|
return
|
||||||
end subroutine js8e_decoded
|
end subroutine js8e_decoded
|
||||||
|
|
||||||
|
subroutine js8i_decoded (this,sync,snr,dt,freq,decoded,nap,qual)
|
||||||
|
use js8i_decode
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
class(js8i_decoder), intent(inout) :: this
|
||||||
|
real, intent(in) :: sync
|
||||||
|
integer, intent(in) :: snr
|
||||||
|
real, intent(in) :: dt
|
||||||
|
real, intent(in) :: freq
|
||||||
|
character(len=37), intent(in) :: decoded
|
||||||
|
integer, intent(in) :: nap
|
||||||
|
real, intent(in) :: qual
|
||||||
|
integer :: submode
|
||||||
|
save
|
||||||
|
|
||||||
|
submode=8
|
||||||
|
call js8_decoded(sync, snr, dt, freq, decoded, nap, qual, submode)
|
||||||
|
|
||||||
|
select type(this)
|
||||||
|
type is (counting_js8i_decoder)
|
||||||
|
this%decoded = this%decoded + 1
|
||||||
|
end select
|
||||||
|
|
||||||
|
return
|
||||||
|
end subroutine js8i_decoded
|
||||||
|
|
||||||
end subroutine multimode_decoder
|
end subroutine multimode_decoder
|
||||||
|
37
lib/js8/js8i_params.f90
Normal file
37
lib/js8/js8i_params.f90
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
!parameter (NSPS=480) !Samples per symbol at 12000 S/s
|
||||||
|
!parameter (NTXDUR=5) !TX Duration in Seconds
|
||||||
|
!parameter (NDOWNSPS=16) !Downsampled samples per symbol
|
||||||
|
!parameter (AZ=6.0) !Near dupe sync spacing
|
||||||
|
!parameter (NDD=136) !Downconverted FFT Bins - 100 Bins
|
||||||
|
!parameter (JZ=62) !Sync Search Space over +/- 2.5s relative to 0.5s TX start time. 2.48 = 62/4/(12000/1920) ?
|
||||||
|
|
||||||
|
|
||||||
|
parameter (NSPS=384, NTXDUR=4, NDOWNSPS=12, NDD=125, JZ=250) ! 250 Hz 31.25 baud 60 wpm -18.0dB (1.0Eb/N0) 2.52s
|
||||||
|
! parameter (NSPS=384, NTXDUR=5, NDOWNSPS=12, NDD=125, JZ=116) ! 250 Hz 31.25 baud 48 wpm -18.0dB (1.0Eb/N0) 2.52s
|
||||||
|
! parameter (NSPS=480, NTXDUR=5, NDOWNSPS=12, NDD=125, JZ=116) ! 200 Hz 25 baud 48 wpm -19.0dB (1.0Eb/N0) 3.16s
|
||||||
|
! parameter (NSPS=480, NTXDUR=6, NDOWNSPS=20, NDD=150, JZ=116) ! 200 Hz 25 baud 40 wpm -19.0dB (1.0Eb/N0) 3.16s
|
||||||
|
! parameter (NSPS=500, NTXDUR=6, NDOWNSPS=20, NDD=144, JZ=116) ! 192 Hz 24 baud 40 wpm -19.4dB (1.0Eb/N0) 3.29s
|
||||||
|
! parameter (NSPS=600, NTXDUR=6, NDOWNSPS=24, NDD=120, JZ=172) ! 160 Hz 20 baud 40 wpm -20.0dB (1.0Eb/N0) 3.95s
|
||||||
|
! parameter (NSPS=768, NTXDUR=8, NDOWNSPS=24, NDD=125, JZ=116) ! 125 Hz 15.625 baud 32 wpm -21.0dB (1.0Eb/N0) 5.05s
|
||||||
|
! parameter (NSPS=800, NTXDUR=8, NDOWNSPS=24, NDD=100, JZ=116) ! 120 Hz 15 baud 32 wpm -21.2dB (1.0Eb/N0) 5.26s
|
||||||
|
! parameter (NSPS=960, NTXDUR=8, NDOWNSPS=24, NDD=100, JZ=116) ! 100 Hz 12.50 baud 32 wpm -22.0dB (1.0Eb/N0) 5.92s
|
||||||
|
! parameter (NSPS=1200, NTXDUR=10, NDOWNSPS=20, NDD=100, JZ=116) ! 80 Hz 10 baud 24 wpm -23.0dB (1.0Eb/N0) 7.90s
|
||||||
|
! parameter (NSPS=1920, NTXDUR=15, NDOWNSPS=32, NDD=100, JZ=116) ! 50 Hz 6.250 baud 16 wpm -25.0dB (1.0Eb/N0) 12.64s
|
||||||
|
! parameter (NSPS=3840, NTXDUR=30, NDOWNSPS=32, NDD=94, JZ=116) ! 24 Hz 3.125 baud 8 wpm -28.0dB (1.0Eb/N0) 25.28s
|
||||||
|
! parameter (NSPS=4000, NTXDUR=28, NDOWNSPS=20, NDD=90, JZ=32) ! 24 Hz 3 baud 8 wpm -28.2dB (1.0Eb/N0) 26.33s
|
||||||
|
|
||||||
|
parameter (AZ=12000.0/(1.0*NSPS)*0.8d0) !Dedupe overlap in Hz
|
||||||
|
parameter (ASTART=0.1) !Start delay in seconds
|
||||||
|
parameter (ASYNCMIN=1.5) !Minimum Sync
|
||||||
|
|
||||||
|
parameter (KK=87) !Information bits (75 + CRC12)
|
||||||
|
parameter (ND=58) !Data symbols
|
||||||
|
parameter (NS=21) !Sync symbols (3 @ Costas 7x7)
|
||||||
|
parameter (NN=NS+ND) !Total channel symbols (79)
|
||||||
|
parameter (NZ=NSPS*NN) !Samples in full 15 s waveform (151,680)
|
||||||
|
parameter (NMAX=NTXDUR*12000) !Samples in iwave (180,000)
|
||||||
|
parameter (NFFT1=2*NSPS, NH1=NFFT1/2) !Length of FFTs for symbol spectra
|
||||||
|
parameter (NSTEP=NSPS/4) !Rough time-sync step size
|
||||||
|
parameter (NHSYM=NMAX/NSTEP-3) !Number of symbol spectra (1/4-sym steps)
|
||||||
|
parameter (NDOWN=NSPS/NDOWNSPS) !Downsample factor to 32 samples per symbol
|
||||||
|
parameter (NQSYMBOL=NDOWNSPS/4) !Downsample factor of a quarter symbol
|
238
lib/js8/ldpcsim174js8i.f90
Normal file
238
lib/js8/ldpcsim174js8i.f90
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
program ldpcsim174js8
|
||||||
|
! End to end test of the (174,75)/crc12 encoder and decoder.
|
||||||
|
use crc
|
||||||
|
use packjt
|
||||||
|
|
||||||
|
include 'js8_params.f90'
|
||||||
|
include 'js8i_params.f90'
|
||||||
|
|
||||||
|
character*22 msg,msgsent,msgreceived
|
||||||
|
character*8 arg
|
||||||
|
character*6 grid
|
||||||
|
integer*1, allocatable :: codeword(:), decoded(:), message(:)
|
||||||
|
integer*1, target:: i1Msg8BitBytes(11)
|
||||||
|
integer*1 msgbits(87)
|
||||||
|
integer*1 apmask(174), cw(174)
|
||||||
|
integer*2 checksum
|
||||||
|
integer*4 i4Msg6BitWords(13)
|
||||||
|
integer colorder(174)
|
||||||
|
integer nerrtot(174),nerrdec(174),nmpcbad(87)
|
||||||
|
logical checksumok,fsk,bpsk
|
||||||
|
real*8, allocatable :: rxdata(:)
|
||||||
|
real, allocatable :: llr(:)
|
||||||
|
|
||||||
|
data colorder/ &
|
||||||
|
0, 1, 2, 3, 30, 4, 5, 6, 7, 8, 9, 10, 11, 32, 12, 40, 13, 14, 15, 16,&
|
||||||
|
17, 18, 37, 45, 29, 19, 20, 21, 41, 22, 42, 31, 33, 34, 44, 35, 47, 51, 50, 43,&
|
||||||
|
36, 52, 63, 46, 25, 55, 27, 24, 23, 53, 39, 49, 59, 38, 48, 61, 60, 57, 28, 62,&
|
||||||
|
56, 58, 65, 66, 26, 70, 64, 69, 68, 67, 74, 71, 54, 76, 72, 75, 78, 77, 80, 79,&
|
||||||
|
73, 83, 84, 81, 82, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,&
|
||||||
|
100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,&
|
||||||
|
120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,&
|
||||||
|
140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,&
|
||||||
|
160,161,162,163,164,165,166,167,168,169,170,171,172,173/
|
||||||
|
|
||||||
|
nerrtot=0
|
||||||
|
nerrdec=0
|
||||||
|
nmpcbad=0 ! Used to collect the number of errors in the message+crc part of the codeword
|
||||||
|
|
||||||
|
nargs=iargc()
|
||||||
|
if(nargs.ne.4) then
|
||||||
|
print*,'Usage: ldpcsim niter ndepth #trials s '
|
||||||
|
print*,'eg: ldpcsim 10 2 1000 0.84'
|
||||||
|
print*,'belief propagation iterations: niter, ordered-statistics depth: ndepth'
|
||||||
|
print*,'If s is negative, then value is ignored and sigma is calculated from SNR.'
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
call getarg(1,arg)
|
||||||
|
read(arg,*) max_iterations
|
||||||
|
call getarg(2,arg)
|
||||||
|
read(arg,*) ndepth
|
||||||
|
call getarg(3,arg)
|
||||||
|
read(arg,*) ntrials
|
||||||
|
call getarg(4,arg)
|
||||||
|
read(arg,*) s
|
||||||
|
|
||||||
|
fsk=.false.
|
||||||
|
bpsk=.true.
|
||||||
|
|
||||||
|
! don't count crc bits as data bits
|
||||||
|
N=174
|
||||||
|
K=87
|
||||||
|
! scale Eb/No for a (174,87) code
|
||||||
|
rate=real(K)/real(N)
|
||||||
|
|
||||||
|
write(*,*) "rate: ",rate
|
||||||
|
write(*,*) "niter= ",max_iterations," s= ",s
|
||||||
|
|
||||||
|
allocate ( codeword(N), decoded(K), message(K) )
|
||||||
|
allocate ( rxdata(N), llr(N) )
|
||||||
|
|
||||||
|
msg="0123456789012"
|
||||||
|
! msg="G4WJS K9AN EN50"
|
||||||
|
call packmsg(msg,i4Msg6BitWords,itype,.false.) !Pack into 12 6-bit bytes
|
||||||
|
call unpackmsg(i4Msg6BitWords,msgsent,.false.,grid) !Unpack to get msgsent
|
||||||
|
write(*,*) "message sent ",msgsent
|
||||||
|
|
||||||
|
i4=0
|
||||||
|
ik=0
|
||||||
|
im=0
|
||||||
|
do i=1,12
|
||||||
|
nna=i4Msg6BitWords(i)
|
||||||
|
do j=1, 6
|
||||||
|
ik=ik+1
|
||||||
|
i4=i4+i4+iand(1,ishft(nna,j-6))
|
||||||
|
i4=iand(i4,255)
|
||||||
|
if(ik.eq.8) then
|
||||||
|
im=im+1
|
||||||
|
! if(i4.gt.127) i4=i4-256
|
||||||
|
i1Msg8BitBytes(im)=i4
|
||||||
|
ik=0
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
i1Msg8BitBytes(10:11)=0
|
||||||
|
checksum = crc12 (c_loc (i1Msg8BitBytes), 11)
|
||||||
|
checksum = xor(checksum, 42) ! TODO: jsherer - could change the crc here
|
||||||
|
! For reference, the next 3 lines show how to check the CRC
|
||||||
|
i1Msg8BitBytes(10)=checksum/256
|
||||||
|
i1Msg8BitBytes(11)=iand(checksum,transfer(255,0_2))
|
||||||
|
checksumok = crc12_check(c_loc (i1Msg8BitBytes), 11)
|
||||||
|
if( checksumok ) write(*,*) 'Good checksum'
|
||||||
|
|
||||||
|
! K=87, For now:
|
||||||
|
! msgbits(1:72) JT message bits
|
||||||
|
! msgbits(73:75) 3 free message bits (set to 0)
|
||||||
|
! msgbits(76:87) CRC12
|
||||||
|
mbit=0
|
||||||
|
do i=1, 9
|
||||||
|
i1=i1Msg8BitBytes(i)
|
||||||
|
do ibit=1,8
|
||||||
|
mbit=mbit+1
|
||||||
|
msgbits(mbit)=iand(1,ishft(i1,ibit-8))
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
msgbits(73:75)=0 ! the three extra message bits go here
|
||||||
|
i1=i1Msg8BitBytes(10) ! First 4 bits of crc12 are LSB of this byte
|
||||||
|
do ibit=1,4
|
||||||
|
msgbits(75+ibit)=iand(1,ishft(i1,ibit-4))
|
||||||
|
enddo
|
||||||
|
i1=i1Msg8BitBytes(11) ! Now shift in last 8 bits of the CRC
|
||||||
|
do ibit=1,8
|
||||||
|
msgbits(79+ibit)=iand(1,ishft(i1,ibit-8))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
write(*,*) 'message'
|
||||||
|
write(*,'(11(8i1,1x))') msgbits
|
||||||
|
|
||||||
|
call encode174(msgbits,codeword)
|
||||||
|
call init_random_seed()
|
||||||
|
! call sgran()
|
||||||
|
|
||||||
|
write(*,*) 'codeword'
|
||||||
|
write(*,'(22(8i1,1x))') codeword
|
||||||
|
|
||||||
|
write(*,*) "Es/N0 SNR2500 ngood nundetected nbadcrc sigma"
|
||||||
|
do idb = 20,-10,-1
|
||||||
|
!do idb = -3,-3,-1
|
||||||
|
db=idb/2.0-1.0
|
||||||
|
sigma=1/sqrt( 2*(10**(db/10.0)) )
|
||||||
|
ngood=0
|
||||||
|
nue=0
|
||||||
|
nbadcrc=0
|
||||||
|
nberr=0
|
||||||
|
do itrial=1, ntrials
|
||||||
|
! Create a realization of a noisy received word
|
||||||
|
do i=1,N
|
||||||
|
if( bpsk ) then
|
||||||
|
rxdata(i) = 2.0*codeword(i)-1.0 + sigma*gran()
|
||||||
|
elseif( fsk ) then
|
||||||
|
if( codeword(i) .eq. 1 ) then
|
||||||
|
r1=(1.0 + sigma*gran())**2 + (sigma*gran())**2
|
||||||
|
r2=(sigma*gran())**2 + (sigma*gran())**2
|
||||||
|
elseif( codeword(i) .eq. 0 ) then
|
||||||
|
r2=(1.0 + sigma*gran())**2 + (sigma*gran())**2
|
||||||
|
r1=(sigma*gran())**2 + (sigma*gran())**2
|
||||||
|
endif
|
||||||
|
! rxdata(i)=0.35*(sqrt(r1)-sqrt(r2))
|
||||||
|
! rxdata(i)=0.35*(exp(r1)-exp(r2))
|
||||||
|
rxdata(i)=0.12*(log(r1)-log(r2))
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
nerr=0
|
||||||
|
do i=1,N
|
||||||
|
if( rxdata(i)*(2*codeword(i)-1.0) .lt. 0 ) nerr=nerr+1
|
||||||
|
enddo
|
||||||
|
if(nerr.ge.1) nerrtot(nerr)=nerrtot(nerr)+1
|
||||||
|
nberr=nberr+nerr
|
||||||
|
|
||||||
|
! Correct signal normalization is important for this decoder.
|
||||||
|
rxav=sum(rxdata)/N
|
||||||
|
rx2av=sum(rxdata*rxdata)/N
|
||||||
|
rxsig=sqrt(rx2av-rxav*rxav)
|
||||||
|
rxdata=rxdata/rxsig
|
||||||
|
! To match the metric to the channel, s should be set to the noise standard deviation.
|
||||||
|
! For now, set s to the value that optimizes decode probability near threshold.
|
||||||
|
! The s parameter can be tuned to trade a few tenth's dB of threshold for an order of
|
||||||
|
! magnitude in UER
|
||||||
|
if( s .lt. 0 ) then
|
||||||
|
ss=sigma
|
||||||
|
else
|
||||||
|
ss=s
|
||||||
|
endif
|
||||||
|
|
||||||
|
llr=2.0*rxdata/(ss*ss)
|
||||||
|
nap=0 ! number of AP bits
|
||||||
|
llr(colorder(174-87+1:174-87+nap)+1)=5*(2.0*msgbits(1:nap)-1.0)
|
||||||
|
apmask=0
|
||||||
|
apmask(colorder(174-87+1:174-87+nap)+1)=1
|
||||||
|
|
||||||
|
! max_iterations is max number of belief propagation iterations
|
||||||
|
call bpdecode174(llr, apmask, max_iterations, decoded, cw, nharderrors,niterations)
|
||||||
|
if( ndepth .ge. 0 .and. nharderrors .lt. 0 ) call osd174(llr, apmask, ndepth, decoded, cw, nharderrors, dmin)
|
||||||
|
! If the decoder finds a valid codeword, nharderrors will be .ge. 0.
|
||||||
|
if( nharderrors .ge. 0 ) then
|
||||||
|
call extractmessage174(decoded,msgreceived,ncrcflag)
|
||||||
|
if( ncrcflag .ne. 1 ) then
|
||||||
|
nbadcrc=nbadcrc+1
|
||||||
|
endif
|
||||||
|
|
||||||
|
nueflag=0
|
||||||
|
nerrmpc=0
|
||||||
|
do i=1,K ! find number of errors in message+crc part of codeword
|
||||||
|
if( msgbits(i) .ne. decoded(i) ) then
|
||||||
|
nueflag=1
|
||||||
|
nerrmpc=nerrmpc+1
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
if(nerrmpc.ge.1) nmpcbad(nerrmpc)=nmpcbad(nerrmpc)+1
|
||||||
|
if( ncrcflag .eq. 1 ) then
|
||||||
|
if( nueflag .eq. 0 ) then
|
||||||
|
ngood=ngood+1
|
||||||
|
if(nerr.ge.1) nerrdec(nerr)=nerrdec(nerr)+1
|
||||||
|
else if( nueflag .eq. 1 ) then
|
||||||
|
nue=nue+1;
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
baud=12000.0/NSPS
|
||||||
|
snr2500=db+10.0*log10((baud/2500.0))
|
||||||
|
pberr=real(nberr)/(real(ntrials*N))
|
||||||
|
write(*,"(f4.1,4x,f5.1,1x,i8,1x,i8,1x,i8,8x,f5.2,8x,e10.3)") db,snr2500,ngood,nue,nbadcrc,ss,pberr
|
||||||
|
|
||||||
|
enddo
|
||||||
|
|
||||||
|
open(unit=23,file='nerrhisto.dat',status='unknown')
|
||||||
|
do i=1,174
|
||||||
|
write(23,'(i4,2x,i10,i10,f10.2)') i,nerrdec(i),nerrtot(i),real(nerrdec(i))/real(nerrtot(i)+1e-10)
|
||||||
|
enddo
|
||||||
|
close(23)
|
||||||
|
open(unit=25,file='nmpcbad.dat',status='unknown')
|
||||||
|
do i=1,87
|
||||||
|
write(25,'(i4,2x,i10)') i,nmpcbad(i)
|
||||||
|
enddo
|
||||||
|
close(25)
|
||||||
|
|
||||||
|
end program ldpcsim174js8
|
152
lib/js8i_decode.f90
Normal file
152
lib/js8i_decode.f90
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
module js8i_decode
|
||||||
|
|
||||||
|
type :: js8i_decoder
|
||||||
|
procedure(js8i_decode_callback), pointer :: callback
|
||||||
|
contains
|
||||||
|
procedure :: decode
|
||||||
|
end type js8i_decoder
|
||||||
|
|
||||||
|
abstract interface
|
||||||
|
subroutine js8i_decode_callback (this,sync,snr,dt,freq,decoded,nap,qual)
|
||||||
|
import js8i_decoder
|
||||||
|
implicit none
|
||||||
|
class(js8i_decoder), intent(inout) :: this
|
||||||
|
real, intent(in) :: sync
|
||||||
|
integer, intent(in) :: snr
|
||||||
|
real, intent(in) :: dt
|
||||||
|
real, intent(in) :: freq
|
||||||
|
character(len=37), intent(in) :: decoded
|
||||||
|
integer, intent(in) :: nap
|
||||||
|
real, intent(in) :: qual
|
||||||
|
end subroutine js8i_decode_callback
|
||||||
|
end interface
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
subroutine decode(this,callback,iwave,nQSOProgress,nfqso,nftx,newdat, &
|
||||||
|
nutc,nfa,nfb,nexp_decode,ndepth,nagain,lft8apon,lapcqonly,napwid, &
|
||||||
|
mycall12,mygrid6,hiscall12,hisgrid6)
|
||||||
|
! use wavhdr
|
||||||
|
use timer_module, only: timer
|
||||||
|
! type(hdr) h
|
||||||
|
use js8i_module
|
||||||
|
|
||||||
|
class(js8i_decoder), intent(inout) :: this
|
||||||
|
procedure(js8i_decode_callback) :: callback
|
||||||
|
real s(NH1,NHSYM)
|
||||||
|
real sbase(NH1)
|
||||||
|
real candidate(3,200)
|
||||||
|
real dd(NMAX)
|
||||||
|
logical, intent(in) :: lft8apon,lapcqonly,nagain
|
||||||
|
logical newdat,lsubtract,ldupe,bcontest
|
||||||
|
character*12 mycall12, hiscall12
|
||||||
|
character*6 mygrid6,hisgrid6
|
||||||
|
integer*2 iwave(NMAX)
|
||||||
|
integer apsym(KK)
|
||||||
|
character datetime*13,message*22,msg37*37
|
||||||
|
character*22 allmessages(100)
|
||||||
|
integer allsnrs(100)
|
||||||
|
save s,dd
|
||||||
|
|
||||||
|
bcontest=iand(nexp_decode,128).ne.0
|
||||||
|
this%callback => callback
|
||||||
|
write(datetime,1001) nutc !### TEMPORARY ###
|
||||||
|
1001 format("000000_",i6.6)
|
||||||
|
|
||||||
|
call ft8apset(mycall12,mygrid6,hiscall12,hisgrid6,bcontest,apsym,iaptype)
|
||||||
|
|
||||||
|
dd=iwave
|
||||||
|
ndecodes=0
|
||||||
|
allmessages=' '
|
||||||
|
allsnrs=0
|
||||||
|
ifa=nfa
|
||||||
|
ifb=nfb
|
||||||
|
if(nagain) then
|
||||||
|
ifa=nfqso-10
|
||||||
|
ifb=nfqso+10
|
||||||
|
endif
|
||||||
|
|
||||||
|
! For now:
|
||||||
|
! ndepth=1: no subtraction, 1 pass, belief propagation only
|
||||||
|
! ndepth=2: subtraction, 3 passes, belief propagation only
|
||||||
|
! ndepth=3: subtraction, 3 passes, bp+osd
|
||||||
|
if(ndepth.eq.1) npass=1
|
||||||
|
if(ndepth.ge.2) npass=3
|
||||||
|
do ipass=1,npass
|
||||||
|
newdat=.true. ! Is this a problem? I hijacked newdat.
|
||||||
|
syncmin=ASYNCMIN
|
||||||
|
if(ipass.eq.1) then
|
||||||
|
lsubtract=.true.
|
||||||
|
if(ndepth.eq.1) lsubtract=.false.
|
||||||
|
elseif(ipass.eq.2) then
|
||||||
|
n2=ndecodes
|
||||||
|
if(ndecodes.eq.0) cycle
|
||||||
|
lsubtract=.true.
|
||||||
|
elseif(ipass.eq.3) then
|
||||||
|
if((ndecodes-n2).eq.0) cycle
|
||||||
|
lsubtract=.false.
|
||||||
|
endif
|
||||||
|
|
||||||
|
call timer('syncjs8 ',0)
|
||||||
|
call syncjs8(dd,ifa,ifb,syncmin,nfqso,s,candidate,ncand,sbase)
|
||||||
|
call timer('syncjs8 ',1)
|
||||||
|
|
||||||
|
if(NWRITELOG.eq.1) then
|
||||||
|
write(*,*) '<DecodeDebug>', ncand, "candidates"
|
||||||
|
flush(6)
|
||||||
|
endif
|
||||||
|
|
||||||
|
do icand=1,ncand
|
||||||
|
sync=candidate(3,icand)
|
||||||
|
f1=candidate(1,icand)
|
||||||
|
xdt=candidate(2,icand)
|
||||||
|
xbase=10.0**(0.1*(sbase(nint(f1/(12000.0/NFFT1)))-40.0)) ! 3.125Hz
|
||||||
|
nsnr0=min(99,nint(10.0*log10(sync) - 25.5)) !### empirical ###
|
||||||
|
|
||||||
|
if(NWRITELOG.eq.1) then
|
||||||
|
write(*,*) '<DecodeDebug> candidate', icand, 'f1', f1, 'sync', sync, 'xdt', xdt, 'xbase', xbase
|
||||||
|
flush(6)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call timer('js8dec ',0)
|
||||||
|
call js8dec(dd,newdat,nQSOProgress,nfqso,nftx,ndepth,lft8apon, &
|
||||||
|
lapcqonly,napwid,lsubtract,nagain,iaptype,mycall12,mygrid6, &
|
||||||
|
hiscall12,bcontest,sync,f1,xdt,xbase,apsym,nharderrors,dmin, &
|
||||||
|
nbadcrc,iappass,iera,msg37,xsnr)
|
||||||
|
message=msg37(1:22) !###
|
||||||
|
nsnr=nint(xsnr)
|
||||||
|
xdt=xdt-ASTART
|
||||||
|
hd=nharderrors+dmin
|
||||||
|
|
||||||
|
if(NWRITELOG.eq.1) then
|
||||||
|
write(*,*) '<DecodeDebug> candidate', icand, 'hard', hd, 'nbadcrc', nbadcrc
|
||||||
|
flush(6)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call timer('js8dec ',1)
|
||||||
|
if(nbadcrc.eq.0) then
|
||||||
|
ldupe=.false.
|
||||||
|
do id=1,ndecodes
|
||||||
|
if(message.eq.allmessages(id).and.nsnr.le.allsnrs(id)) ldupe=.true.
|
||||||
|
enddo
|
||||||
|
if(.not.ldupe) then
|
||||||
|
ndecodes=ndecodes+1
|
||||||
|
allmessages(ndecodes)=message
|
||||||
|
allsnrs(ndecodes)=nsnr
|
||||||
|
endif
|
||||||
|
if(.not.ldupe .and. associated(this%callback)) then
|
||||||
|
qual=1.0-(nharderrors+dmin)/60.0 ! scale qual to [0.0,1.0]
|
||||||
|
call this%callback(sync,nsnr,xdt,f1,msg37,iaptype,qual)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if(NWRITELOG.eq.1) then
|
||||||
|
write(*,*) '<DecodeDebug> ---'
|
||||||
|
flush(6)
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
return
|
||||||
|
end subroutine decode
|
||||||
|
|
||||||
|
end module js8i_decode
|
13
lib/js8i_module.f90
Normal file
13
lib/js8i_module.f90
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
module js8i_module
|
||||||
|
include 'js8/js8_params.f90'
|
||||||
|
include 'js8/js8i_params.f90'
|
||||||
|
|
||||||
|
contains
|
||||||
|
include 'js8/baselinejs8.f90'
|
||||||
|
include 'js8/syncjs8.f90'
|
||||||
|
include 'js8/js8_downsample.f90'
|
||||||
|
include 'js8/syncjs8d.f90'
|
||||||
|
include 'js8/genjs8refsig.f90'
|
||||||
|
include 'js8/subtractjs8.f90'
|
||||||
|
include 'js8/js8dec.f90'
|
||||||
|
end module js8i_module
|
@ -23,10 +23,12 @@
|
|||||||
integer(c_int) :: kposB
|
integer(c_int) :: kposB
|
||||||
integer(c_int) :: kposC
|
integer(c_int) :: kposC
|
||||||
integer(c_int) :: kposE
|
integer(c_int) :: kposE
|
||||||
|
integer(c_int) :: kposI
|
||||||
integer(c_int) :: kszA
|
integer(c_int) :: kszA
|
||||||
integer(c_int) :: kszB
|
integer(c_int) :: kszB
|
||||||
integer(c_int) :: kszC
|
integer(c_int) :: kszC
|
||||||
integer(c_int) :: kszE
|
integer(c_int) :: kszE
|
||||||
|
integer(c_int) :: kszI
|
||||||
integer(c_int) :: nzhsym
|
integer(c_int) :: nzhsym
|
||||||
integer(c_int) :: nsubmode
|
integer(c_int) :: nsubmode
|
||||||
integer(c_int) :: nsubmodes
|
integer(c_int) :: nsubmodes
|
||||||
|
161
mainwindow.cpp
161
mainwindow.cpp
@ -961,7 +961,8 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
|||||||
ui->actionModeJS8Normal->setActionGroup(modeActionGroup);
|
ui->actionModeJS8Normal->setActionGroup(modeActionGroup);
|
||||||
ui->actionModeJS8Fast->setActionGroup(modeActionGroup);
|
ui->actionModeJS8Fast->setActionGroup(modeActionGroup);
|
||||||
ui->actionModeJS8Turbo->setActionGroup(modeActionGroup);
|
ui->actionModeJS8Turbo->setActionGroup(modeActionGroup);
|
||||||
ui->actionModeJS8UltraSlow->setActionGroup(modeActionGroup);
|
ui->actionModeJS8Slow->setActionGroup(modeActionGroup);
|
||||||
|
ui->actionModeJS8Ultra->setActionGroup(modeActionGroup);
|
||||||
|
|
||||||
auto mbmp = new MousePressEater();
|
auto mbmp = new MousePressEater();
|
||||||
connect(mbmp, &MousePressEater::mousePressed, this, [this](QObject *, QMouseEvent * e, bool *pProcessed){
|
connect(mbmp, &MousePressEater::mousePressed, this, [this](QObject *, QMouseEvent * e, bool *pProcessed){
|
||||||
@ -979,13 +980,10 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
|||||||
ui->actionModeJS8Turbo->setVisible(false);
|
ui->actionModeJS8Turbo->setVisible(false);
|
||||||
}
|
}
|
||||||
if(!JS8_ENABLE_JS8E){
|
if(!JS8_ENABLE_JS8E){
|
||||||
ui->actionModeJS8UltraSlow->setVisible(false);
|
ui->actionModeJS8Slow->setVisible(false);
|
||||||
}
|
}
|
||||||
if(JS8_ENABLE_JS8E && !JS8E_IS_ULTRA){
|
if(!JS8_ENABLE_JS8I){
|
||||||
// reorder so slow is at the top
|
ui->actionModeJS8Ultra->setVisible(false);
|
||||||
ui->menuModeJS8->removeAction(ui->actionModeJS8UltraSlow);
|
|
||||||
ui->menuModeJS8->insertAction(ui->actionModeJS8Normal, ui->actionModeJS8UltraSlow);
|
|
||||||
ui->actionModeJS8UltraSlow->setText("JS8 (&Slow, 30s, 24Hz, ~8WPM)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// prep
|
// prep
|
||||||
@ -2514,10 +2512,11 @@ void MainWindow::setDecodedTextFont (QFont const& font)
|
|||||||
|
|
||||||
int MainWindow::computePeriodForSubmode(int submode){
|
int MainWindow::computePeriodForSubmode(int submode){
|
||||||
switch(submode){
|
switch(submode){
|
||||||
case Varicode::JS8CallNormal: return JS8A_TX_SECONDS;
|
case Varicode::JS8CallNormal: return JS8A_TX_SECONDS;
|
||||||
case Varicode::JS8CallFast: return JS8B_TX_SECONDS;
|
case Varicode::JS8CallFast: return JS8B_TX_SECONDS;
|
||||||
case Varicode::JS8CallTurbo: return JS8C_TX_SECONDS;
|
case Varicode::JS8CallTurbo: return JS8C_TX_SECONDS;
|
||||||
case Varicode::JS8CallUltraSlow: return JS8E_TX_SECONDS;
|
case Varicode::JS8CallSlow: return JS8E_TX_SECONDS;
|
||||||
|
case Varicode::JS8CallUltra: return JS8I_TX_SECONDS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -2542,21 +2541,13 @@ int MainWindow::computeStop(int submode, int period){
|
|||||||
stop = int(period/0.288);
|
stop = int(period/0.288);
|
||||||
#else
|
#else
|
||||||
int symbolSamples = 0;
|
int symbolSamples = 0;
|
||||||
float threshold = 1.0;
|
float threshold = 0.0;
|
||||||
switch(submode){
|
switch(submode){
|
||||||
case Varicode::JS8CallNormal: symbolSamples = JS8A_SYMBOL_SAMPLES; /* threshold = 1.00 */ ; break;
|
case Varicode::JS8CallNormal: symbolSamples = JS8A_SYMBOL_SAMPLES; threshold = 1.00; break;
|
||||||
case Varicode::JS8CallFast: symbolSamples = JS8B_SYMBOL_SAMPLES; /* threshold = 1.08 */ ; break;
|
case Varicode::JS8CallFast: symbolSamples = JS8B_SYMBOL_SAMPLES; threshold = 1.00; break;
|
||||||
case Varicode::JS8CallTurbo: symbolSamples = JS8C_SYMBOL_SAMPLES; /* threshold = 0.50 */ ; break;
|
case Varicode::JS8CallTurbo: symbolSamples = JS8C_SYMBOL_SAMPLES; threshold = 1.00; break;
|
||||||
case Varicode::JS8CallUltraSlow:
|
case Varicode::JS8CallSlow: symbolSamples = JS8E_SYMBOL_SAMPLES; threshold = 1.25; break;
|
||||||
{
|
case Varicode::JS8CallUltra: symbolSamples = JS8I_SYMBOL_SAMPLES; threshold = 0.50; break;
|
||||||
symbolSamples = JS8E_SYMBOL_SAMPLES;
|
|
||||||
#if JS8E_IS_ULTRA
|
|
||||||
threshold = 0.0;
|
|
||||||
#else
|
|
||||||
threshold = 1.25;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
stop = qFloor(float(symbolSamples*JS8_NUM_SYMBOLS + threshold*RX_SAMPLE_RATE)/(float)m_nsps*2.0);
|
stop = qFloor(float(symbolSamples*JS8_NUM_SYMBOLS + threshold*RX_SAMPLE_RATE)/(float)m_nsps*2.0);
|
||||||
#endif
|
#endif
|
||||||
@ -2591,7 +2582,8 @@ int MainWindow::computeFramesNeededForDecode(int submode){
|
|||||||
case Varicode::JS8CallNormal: symbolSamples = JS8A_SYMBOL_SAMPLES; threshold = JS8A_START_DELAY_MS/1000.0 + 0.5; break;
|
case Varicode::JS8CallNormal: symbolSamples = JS8A_SYMBOL_SAMPLES; threshold = JS8A_START_DELAY_MS/1000.0 + 0.5; break;
|
||||||
case Varicode::JS8CallFast: symbolSamples = JS8B_SYMBOL_SAMPLES; threshold = JS8B_START_DELAY_MS/1000.0 + 0.5; break;
|
case Varicode::JS8CallFast: symbolSamples = JS8B_SYMBOL_SAMPLES; threshold = JS8B_START_DELAY_MS/1000.0 + 0.5; break;
|
||||||
case Varicode::JS8CallTurbo: symbolSamples = JS8C_SYMBOL_SAMPLES; threshold = JS8C_START_DELAY_MS/1000.0 + 0.5; break;
|
case Varicode::JS8CallTurbo: symbolSamples = JS8C_SYMBOL_SAMPLES; threshold = JS8C_START_DELAY_MS/1000.0 + 0.5; break;
|
||||||
case Varicode::JS8CallUltraSlow: symbolSamples = JS8E_SYMBOL_SAMPLES; threshold = JS8E_START_DELAY_MS/1000.0 + 0.5; break;
|
case Varicode::JS8CallSlow: symbolSamples = JS8E_SYMBOL_SAMPLES; threshold = JS8E_START_DELAY_MS/1000.0 + 0.5; break;
|
||||||
|
case Varicode::JS8CallUltra: symbolSamples = JS8I_SYMBOL_SAMPLES; threshold = JS8I_START_DELAY_MS/1000.0 + 0.5; break;
|
||||||
}
|
}
|
||||||
return int(qFloor(float(symbolSamples*JS8_NUM_SYMBOLS + threshold*RX_SAMPLE_RATE)));
|
return int(qFloor(float(symbolSamples*JS8_NUM_SYMBOLS + threshold*RX_SAMPLE_RATE)));
|
||||||
}
|
}
|
||||||
@ -2774,7 +2766,8 @@ void MainWindow::on_menuModeJS8_aboutToShow(){
|
|||||||
ui->actionModeJS8Normal->setEnabled(canChangeMode);
|
ui->actionModeJS8Normal->setEnabled(canChangeMode);
|
||||||
ui->actionModeJS8Fast->setEnabled(canChangeMode);
|
ui->actionModeJS8Fast->setEnabled(canChangeMode);
|
||||||
ui->actionModeJS8Turbo->setEnabled(canChangeMode);
|
ui->actionModeJS8Turbo->setEnabled(canChangeMode);
|
||||||
ui->actionModeJS8UltraSlow->setEnabled(canChangeMode);
|
ui->actionModeJS8Slow->setEnabled(canChangeMode);
|
||||||
|
ui->actionModeJS8Ultra->setEnabled(canChangeMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_menuControl_aboutToShow(){
|
void MainWindow::on_menuControl_aboutToShow(){
|
||||||
@ -3272,7 +3265,8 @@ void MainWindow::setSubmode(int submode){
|
|||||||
ui->actionModeJS8Normal->setChecked(submode == Varicode::JS8CallNormal);
|
ui->actionModeJS8Normal->setChecked(submode == Varicode::JS8CallNormal);
|
||||||
ui->actionModeJS8Fast->setChecked(submode == Varicode::JS8CallFast);
|
ui->actionModeJS8Fast->setChecked(submode == Varicode::JS8CallFast);
|
||||||
ui->actionModeJS8Turbo->setChecked(submode == Varicode::JS8CallTurbo);
|
ui->actionModeJS8Turbo->setChecked(submode == Varicode::JS8CallTurbo);
|
||||||
ui->actionModeJS8UltraSlow->setChecked(submode == Varicode::JS8CallUltraSlow);
|
ui->actionModeJS8Slow->setChecked(submode == Varicode::JS8CallSlow);
|
||||||
|
ui->actionModeJS8Ultra->setChecked(submode == Varicode::JS8CallUltra);
|
||||||
on_actionJS8_triggered();
|
on_actionJS8_triggered();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3288,8 +3282,11 @@ int MainWindow::submodeNameToSubmode(QString speedName){
|
|||||||
if(speed == submodeName(Varicode::JS8CallTurbo)){
|
if(speed == submodeName(Varicode::JS8CallTurbo)){
|
||||||
return Varicode::JS8CallTurbo;
|
return Varicode::JS8CallTurbo;
|
||||||
}
|
}
|
||||||
if(speed == submodeName(Varicode::JS8CallUltraSlow)){
|
if(speed == submodeName(Varicode::JS8CallSlow)){
|
||||||
return Varicode::JS8CallUltraSlow;
|
return Varicode::JS8CallSlow;
|
||||||
|
}
|
||||||
|
if(speed == submodeName(Varicode::JS8CallUltra)){
|
||||||
|
return Varicode::JS8CallUltra;
|
||||||
}
|
}
|
||||||
// default to the current submode
|
// default to the current submode
|
||||||
return m_nSubMode;
|
return m_nSubMode;
|
||||||
@ -3306,12 +3303,11 @@ QString MainWindow::submodeName(int submode){
|
|||||||
else if(submode == Varicode::JS8CallTurbo){
|
else if(submode == Varicode::JS8CallTurbo){
|
||||||
return "TURBO";
|
return "TURBO";
|
||||||
}
|
}
|
||||||
else if(submode == Varicode::JS8CallUltraSlow){
|
else if(submode == Varicode::JS8CallSlow){
|
||||||
#if JS8E_IS_ULTRA
|
|
||||||
return "ULTRA";
|
|
||||||
#else
|
|
||||||
return "SLOW";
|
return "SLOW";
|
||||||
#endif
|
}
|
||||||
|
else if(submode == Varicode::JS8CallUltra){
|
||||||
|
return "ULTRA";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "?";
|
return "?";
|
||||||
@ -4161,8 +4157,8 @@ bool MainWindow::decodeEnqueueReady(qint32 k, qint32 k0){
|
|||||||
qint32 startE = -1;
|
qint32 startE = -1;
|
||||||
qint32 szE = -1;
|
qint32 szE = -1;
|
||||||
qint32 cycleE = -1;
|
qint32 cycleE = -1;
|
||||||
if(JS8_DEBUG_DECODE) qDebug() << "? ULTRASLOW" << currentDecodeStartE << nextDecodeStartE;
|
if(JS8_DEBUG_DECODE) qDebug() << "? SLOW" << currentDecodeStartE << nextDecodeStartE;
|
||||||
bool couldDecodeE = isDecodeReady(Varicode::JS8CallUltraSlow, k, k0, ¤tDecodeStartE, &nextDecodeStartE, &startE, &szE, &cycleE);
|
bool couldDecodeE = isDecodeReady(Varicode::JS8CallSlow, k, k0, ¤tDecodeStartE, &nextDecodeStartE, &startE, &szE, &cycleE);
|
||||||
if(m_diskData){
|
if(m_diskData){
|
||||||
startE = 0;
|
startE = 0;
|
||||||
szE = NTMAX*RX_SAMPLE_RATE-1;
|
szE = NTMAX*RX_SAMPLE_RATE-1;
|
||||||
@ -4170,6 +4166,21 @@ bool MainWindow::decodeEnqueueReady(qint32 k, qint32 k0){
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if JS8_ENABLE_JS8I
|
||||||
|
static qint32 currentDecodeStartI = -1;
|
||||||
|
static qint32 nextDecodeStartI = -1;
|
||||||
|
qint32 startI = -1;
|
||||||
|
qint32 szI = -1;
|
||||||
|
qint32 cycleI = -1;
|
||||||
|
if(JS8_DEBUG_DECODE) qDebug() << "? ULTRA" << currentDecodeStartI << nextDecodeStartI;
|
||||||
|
bool couldDecodeI = isDecodeReady(Varicode::JS8CallUltra, k, k0, ¤tDecodeStartI, &nextDecodeStartI, &startI, &szI, &cycleI);
|
||||||
|
if(m_diskData){
|
||||||
|
startI = 0;
|
||||||
|
szI = NTMAX*RX_SAMPLE_RATE-1;
|
||||||
|
couldDecodeI = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int decodes = 0;
|
int decodes = 0;
|
||||||
|
|
||||||
if(couldDecodeA){
|
if(couldDecodeA){
|
||||||
@ -4205,7 +4216,7 @@ bool MainWindow::decodeEnqueueReady(qint32 k, qint32 k0){
|
|||||||
#if JS8_ENABLE_JS8E
|
#if JS8_ENABLE_JS8E
|
||||||
if(couldDecodeE){
|
if(couldDecodeE){
|
||||||
DecodeParams d;
|
DecodeParams d;
|
||||||
d.submode = Varicode::JS8CallUltraSlow;
|
d.submode = Varicode::JS8CallSlow;
|
||||||
d.cycle = cycleE;
|
d.cycle = cycleE;
|
||||||
d.start = startE;
|
d.start = startE;
|
||||||
d.sz = szE;
|
d.sz = szE;
|
||||||
@ -4214,6 +4225,18 @@ bool MainWindow::decodeEnqueueReady(qint32 k, qint32 k0){
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if JS8_ENABLE_JS8E
|
||||||
|
if(couldDecodeI){
|
||||||
|
DecodeParams d;
|
||||||
|
d.submode = Varicode::JS8CallUltra;
|
||||||
|
d.cycle = cycleI;
|
||||||
|
d.start = startI;
|
||||||
|
d.sz = szI;
|
||||||
|
m_decoderQueue.append(d);
|
||||||
|
decodes++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return decodes > 0;
|
return decodes > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4291,11 +4314,18 @@ bool MainWindow::decodeProcessQueue(qint32 *pSubmode){
|
|||||||
dec_data.params.nsubmodes |= (params.submode << 1);
|
dec_data.params.nsubmodes |= (params.submode << 1);
|
||||||
break;
|
break;
|
||||||
#if JS8_ENABLE_JS8E
|
#if JS8_ENABLE_JS8E
|
||||||
case Varicode::JS8CallUltraSlow:
|
case Varicode::JS8CallSlow:
|
||||||
dec_data.params.kposE = params.start;
|
dec_data.params.kposE = params.start;
|
||||||
dec_data.params.kszE = params.sz;
|
dec_data.params.kszE = params.sz;
|
||||||
dec_data.params.nsubmodes |= (params.submode << 1);
|
dec_data.params.nsubmodes |= (params.submode << 1);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#if JS8_ENABLE_JS8I
|
||||||
|
case Varicode::JS8CallUltra:
|
||||||
|
dec_data.params.kposI = params.start;
|
||||||
|
dec_data.params.kszI = params.sz;
|
||||||
|
dec_data.params.nsubmodes |= (params.submode << 1);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#if JS8_SINGLE_DECODE
|
#if JS8_SINGLE_DECODE
|
||||||
@ -5249,8 +5279,10 @@ void MainWindow::guiUpdate()
|
|||||||
txDuration=JS8B_START_DELAY_MS/1000.0 + JS8_NUM_SYMBOLS * (double)JS8B_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE;
|
txDuration=JS8B_START_DELAY_MS/1000.0 + JS8_NUM_SYMBOLS * (double)JS8B_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE;
|
||||||
} else if(m_nSubMode == Varicode::JS8CallTurbo){
|
} else if(m_nSubMode == Varicode::JS8CallTurbo){
|
||||||
txDuration=JS8C_START_DELAY_MS/1000.0 + JS8_NUM_SYMBOLS * (double)JS8C_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE;
|
txDuration=JS8C_START_DELAY_MS/1000.0 + JS8_NUM_SYMBOLS * (double)JS8C_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE;
|
||||||
} else if(m_nSubMode == Varicode::JS8CallUltraSlow){
|
} else if(m_nSubMode == Varicode::JS8CallSlow){
|
||||||
txDuration=JS8E_START_DELAY_MS/1000.0 + JS8_NUM_SYMBOLS * (double)JS8E_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE;
|
txDuration=JS8E_START_DELAY_MS/1000.0 + JS8_NUM_SYMBOLS * (double)JS8E_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE;
|
||||||
|
} else if(m_nSubMode == Varicode::JS8CallUltra){
|
||||||
|
txDuration=JS8I_START_DELAY_MS/1000.0 + JS8_NUM_SYMBOLS * (double)JS8I_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5336,9 +5368,12 @@ void MainWindow::guiUpdate()
|
|||||||
else if(m_nSubMode == Varicode::JS8CallTurbo){
|
else if(m_nSubMode == Varicode::JS8CallTurbo){
|
||||||
ratio = (((double)m_TRperiod - (JS8_NUM_SYMBOLS*(double)JS8C_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE))/(double)m_TRperiod);
|
ratio = (((double)m_TRperiod - (JS8_NUM_SYMBOLS*(double)JS8C_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE))/(double)m_TRperiod);
|
||||||
}
|
}
|
||||||
else if(m_nSubMode == Varicode::JS8CallUltraSlow){
|
else if(m_nSubMode == Varicode::JS8CallSlow){
|
||||||
ratio = (((double)m_TRperiod - (JS8_NUM_SYMBOLS*(double)JS8E_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE))/(double)m_TRperiod);
|
ratio = (((double)m_TRperiod - (JS8_NUM_SYMBOLS*(double)JS8E_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE))/(double)m_TRperiod);
|
||||||
}
|
}
|
||||||
|
else if(m_nSubMode == Varicode::JS8CallUltra){
|
||||||
|
ratio = (((double)m_TRperiod - (JS8_NUM_SYMBOLS*(double)JS8I_SYMBOL_SAMPLES/(double)RX_SAMPLE_RATE))/(double)m_TRperiod);
|
||||||
|
}
|
||||||
|
|
||||||
if(fTR > 1.0-ratio && fTR < 1.0){
|
if(fTR > 1.0-ratio && fTR < 1.0){
|
||||||
if(!m_deadAirTone){
|
if(!m_deadAirTone){
|
||||||
@ -5362,6 +5397,10 @@ void MainWindow::guiUpdate()
|
|||||||
// for the turbo mode, only allow 1/2 late threshold
|
// for the turbo mode, only allow 1/2 late threshold
|
||||||
lateThreshold *= 0.5;
|
lateThreshold *= 0.5;
|
||||||
}
|
}
|
||||||
|
else if(m_nSubMode == Varicode::JS8CallUltra){
|
||||||
|
// for the ultra mode, only allow 1/2 late threshold
|
||||||
|
lateThreshold *= 0.5;
|
||||||
|
}
|
||||||
if(g_iptt==0 and ((m_bTxTime and fTR<lateThreshold and msgLength>0) or m_tune)) {
|
if(g_iptt==0 and ((m_bTxTime and fTR<lateThreshold and msgLength>0) or m_tune)) {
|
||||||
//### Allow late starts
|
//### Allow late starts
|
||||||
icw[0]=m_ncw;
|
icw[0]=m_ncw;
|
||||||
@ -5424,7 +5463,7 @@ void MainWindow::guiUpdate()
|
|||||||
qDebug() << "gen ft8";
|
qDebug() << "gen ft8";
|
||||||
genft8_(message, MyGrid, &bcontest, &m_i3bit, msgsent, const_cast<char *> (ft8msgbits),
|
genft8_(message, MyGrid, &bcontest, &m_i3bit, msgsent, const_cast<char *> (ft8msgbits),
|
||||||
const_cast<int *> (itone), 22, 6, 22);
|
const_cast<int *> (itone), 22, 6, 22);
|
||||||
} else if (m_nSubMode == Varicode::JS8CallFast || m_nSubMode == Varicode::JS8CallTurbo || m_nSubMode == Varicode::JS8CallUltraSlow){
|
} else if (m_nSubMode == Varicode::JS8CallFast || m_nSubMode == Varicode::JS8CallTurbo || m_nSubMode == Varicode::JS8CallSlow || m_nSubMode == Varicode::JS8CallUltra){
|
||||||
qDebug() << "gen js8";
|
qDebug() << "gen js8";
|
||||||
genjs8_(message, MyGrid, &bcontest, &m_i3bit, msgsent, const_cast<char *> (ft8msgbits),
|
genjs8_(message, MyGrid, &bcontest, &m_i3bit, msgsent, const_cast<char *> (ft8msgbits),
|
||||||
const_cast<int *> (itone), 22, 6, 22);
|
const_cast<int *> (itone), 22, 6, 22);
|
||||||
@ -7399,7 +7438,11 @@ void MainWindow::on_actionModeJS8Turbo_triggered(){
|
|||||||
on_actionJS8_triggered();
|
on_actionJS8_triggered();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionModeJS8UltraSlow_triggered(){
|
void MainWindow::on_actionModeJS8Slow_triggered(){
|
||||||
|
on_actionJS8_triggered();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_actionModeJS8Ultra_triggered(){
|
||||||
on_actionJS8_triggered();
|
on_actionJS8_triggered();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7418,7 +7461,7 @@ void MainWindow::prepareHeartbeatMode(bool enabled){
|
|||||||
ui->hbMacroButton->setChecked(false);
|
ui->hbMacroButton->setChecked(false);
|
||||||
}
|
}
|
||||||
ui->actionHeartbeat->setEnabled(enabled);
|
ui->actionHeartbeat->setEnabled(enabled);
|
||||||
ui->actionModeJS8HB->setEnabled(m_nSubMode == Varicode::JS8CallNormal || (!JS8E_IS_ULTRA && m_nSubMode == Varicode::JS8CallUltraSlow));
|
ui->actionModeJS8HB->setEnabled(m_nSubMode == Varicode::JS8CallNormal || m_nSubMode == Varicode::JS8CallSlow);
|
||||||
ui->actionHeartbeatAcknowledgements->setEnabled(ui->actionModeAutoreply->isChecked() && enabled);
|
ui->actionHeartbeatAcknowledgements->setEnabled(ui->actionModeAutoreply->isChecked() && enabled);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -7461,12 +7504,15 @@ void MainWindow::on_actionJS8_triggered()
|
|||||||
else if(ui->actionModeJS8Turbo->isChecked()){
|
else if(ui->actionModeJS8Turbo->isChecked()){
|
||||||
m_nSubMode=Varicode::JS8CallTurbo;
|
m_nSubMode=Varicode::JS8CallTurbo;
|
||||||
}
|
}
|
||||||
else if(ui->actionModeJS8UltraSlow->isChecked()){
|
else if(ui->actionModeJS8Slow->isChecked()){
|
||||||
m_nSubMode=Varicode::JS8CallUltraSlow;
|
m_nSubMode=Varicode::JS8CallSlow;
|
||||||
|
}
|
||||||
|
else if(ui->actionModeJS8Ultra->isChecked()){
|
||||||
|
m_nSubMode=Varicode::JS8CallUltra;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only enable heartbeat for normal mode
|
// Only enable heartbeat for normal mode
|
||||||
ui->actionModeJS8HB->setEnabled(m_nSubMode == Varicode::JS8CallNormal || (!JS8E_IS_ULTRA && m_nSubMode == Varicode::JS8CallUltraSlow));
|
ui->actionModeJS8HB->setEnabled(m_nSubMode == Varicode::JS8CallNormal || m_nSubMode == Varicode::JS8CallSlow);
|
||||||
prepareHeartbeatMode(ui->actionModeJS8HB->isEnabled() && ui->actionModeJS8HB->isChecked());
|
prepareHeartbeatMode(ui->actionModeJS8HB->isEnabled() && ui->actionModeJS8HB->isChecked());
|
||||||
|
|
||||||
//if(m_nSubMode != Varicode::JS8CallNormal){
|
//if(m_nSubMode != Varicode::JS8CallNormal){
|
||||||
@ -9559,10 +9605,14 @@ void MainWindow::transmit (double snr)
|
|||||||
symbolSamples=(double)JS8C_SYMBOL_SAMPLES;
|
symbolSamples=(double)JS8C_SYMBOL_SAMPLES;
|
||||||
toneSpacing=(double)RX_SAMPLE_RATE/(double)JS8C_SYMBOL_SAMPLES;
|
toneSpacing=(double)RX_SAMPLE_RATE/(double)JS8C_SYMBOL_SAMPLES;
|
||||||
}
|
}
|
||||||
else if(m_nSubMode == Varicode::JS8CallUltraSlow){
|
else if(m_nSubMode == Varicode::JS8CallSlow){
|
||||||
symbolSamples=(double)JS8E_SYMBOL_SAMPLES;
|
symbolSamples=(double)JS8E_SYMBOL_SAMPLES;
|
||||||
toneSpacing=(double)RX_SAMPLE_RATE/(double)JS8E_SYMBOL_SAMPLES;
|
toneSpacing=(double)RX_SAMPLE_RATE/(double)JS8E_SYMBOL_SAMPLES;
|
||||||
}
|
}
|
||||||
|
else if(m_nSubMode == Varicode::JS8CallUltra){
|
||||||
|
symbolSamples=(double)JS8I_SYMBOL_SAMPLES;
|
||||||
|
toneSpacing=(double)RX_SAMPLE_RATE/(double)JS8I_SYMBOL_SAMPLES;
|
||||||
|
}
|
||||||
if(m_config.x2ToneSpacing()) toneSpacing*=2.0;
|
if(m_config.x2ToneSpacing()) toneSpacing*=2.0;
|
||||||
if(m_config.x4ToneSpacing()) toneSpacing*=4.0;
|
if(m_config.x4ToneSpacing()) toneSpacing*=4.0;
|
||||||
if(m_config.bFox() and !m_tune) toneSpacing=-1;
|
if(m_config.bFox() and !m_tune) toneSpacing=-1;
|
||||||
@ -9816,9 +9866,7 @@ int MainWindow::rxThreshold(int submode){
|
|||||||
int threshold = 10;
|
int threshold = 10;
|
||||||
if(submode == Varicode::JS8CallFast){ threshold = 16; }
|
if(submode == Varicode::JS8CallFast){ threshold = 16; }
|
||||||
if(submode == Varicode::JS8CallTurbo){ threshold = 32; }
|
if(submode == Varicode::JS8CallTurbo){ threshold = 32; }
|
||||||
#if JS8E_IS_ULTRA
|
if(submode == Varicode::JS8CallUltra){ threshold = 50; }
|
||||||
if(submode == Varicode::JS8CallUltraSlow){ threshold = 50; }
|
|
||||||
#endif
|
|
||||||
return threshold;
|
return threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9831,10 +9879,8 @@ int MainWindow::rxSnrThreshold(int submode){
|
|||||||
return -22;
|
return -22;
|
||||||
case Varicode::JS8CallTurbo:
|
case Varicode::JS8CallTurbo:
|
||||||
return -20;
|
return -20;
|
||||||
#if JS8E_IS_ULTRA
|
case Varicode::JS8CallUltra:
|
||||||
case Varicode::JS8CallUltraSlow:
|
|
||||||
return -18;
|
return -18;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return -28;
|
return -28;
|
||||||
@ -12632,8 +12678,11 @@ void MainWindow::networkMessage(Message const &message)
|
|||||||
if(speed == Varicode::JS8CallTurbo){
|
if(speed == Varicode::JS8CallTurbo){
|
||||||
ui->actionModeJS8Turbo->setChecked(true);
|
ui->actionModeJS8Turbo->setChecked(true);
|
||||||
}
|
}
|
||||||
if(speed == Varicode::JS8CallUltraSlow){
|
if(speed == Varicode::JS8CallSlow){
|
||||||
ui->actionModeJS8UltraSlow->setChecked(true);
|
ui->actionModeJS8Slow->setChecked(true);
|
||||||
|
}
|
||||||
|
if(speed == Varicode::JS8CallUltra){
|
||||||
|
ui->actionModeJS8Ultra->setChecked(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sendNetworkMessage("MODE.SPEED", "", {
|
sendNetworkMessage("MODE.SPEED", "", {
|
||||||
|
@ -275,7 +275,8 @@ private slots:
|
|||||||
void on_actionModeJS8Normal_triggered();
|
void on_actionModeJS8Normal_triggered();
|
||||||
void on_actionModeJS8Fast_triggered();
|
void on_actionModeJS8Fast_triggered();
|
||||||
void on_actionModeJS8Turbo_triggered();
|
void on_actionModeJS8Turbo_triggered();
|
||||||
void on_actionModeJS8UltraSlow_triggered();
|
void on_actionModeJS8Slow_triggered();
|
||||||
|
void on_actionModeJS8Ultra_triggered();
|
||||||
void on_actionHeartbeatAcknowledgements_toggled(bool checked);
|
void on_actionHeartbeatAcknowledgements_toggled(bool checked);
|
||||||
void on_actionModeMultiDecoder_toggled(bool checked);
|
void on_actionModeMultiDecoder_toggled(bool checked);
|
||||||
void on_actionModeAutoreply_toggled(bool checked);
|
void on_actionModeAutoreply_toggled(bool checked);
|
||||||
|
@ -4778,10 +4778,11 @@ list. The list can be maintained in Settings (F2).</string>
|
|||||||
<addaction name="actionDeepDecode"/>
|
<addaction name="actionDeepDecode"/>
|
||||||
<addaction name="actionDeepestDecode"/>
|
<addaction name="actionDeepestDecode"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
<addaction name="actionModeJS8Slow"/>
|
||||||
<addaction name="actionModeJS8Normal"/>
|
<addaction name="actionModeJS8Normal"/>
|
||||||
<addaction name="actionModeJS8Fast"/>
|
<addaction name="actionModeJS8Fast"/>
|
||||||
<addaction name="actionModeJS8Turbo"/>
|
<addaction name="actionModeJS8Turbo"/>
|
||||||
<addaction name="actionModeJS8UltraSlow"/>
|
<addaction name="actionModeJS8Ultra"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="menu_Decode_Passes"/>
|
<addaction name="menu_Decode_Passes"/>
|
||||||
<addaction name="actionModeMultiDecoder"/>
|
<addaction name="actionModeMultiDecoder"/>
|
||||||
@ -5712,7 +5713,7 @@ list. The list can be maintained in Settings (F2).</string>
|
|||||||
<string>JS8 (&Turbo, 6s, 160Hz, ~40 WPM)</string>
|
<string>JS8 (&Turbo, 6s, 160Hz, ~40 WPM)</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionModeJS8UltraSlow">
|
<action name="actionModeJS8Ultra">
|
||||||
<property name="checkable">
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
@ -5763,6 +5764,14 @@ list. The list can be maintained in Settings (F2).</string>
|
|||||||
<string>Enable Autoreply (&AUTO)</string>
|
<string>Enable Autoreply (&AUTO)</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionModeJS8Slow">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>JS8 (&Slow, 30s, 24Hz, ~8 WPM)</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
@ -422,9 +422,12 @@ void CPlotter::DrawOverlay() //DrawOverlay()
|
|||||||
else if(m_nSubMode == Varicode::JS8CallTurbo){
|
else if(m_nSubMode == Varicode::JS8CallTurbo){
|
||||||
bw = 8.0*(double)RX_SAMPLE_RATE/(double)JS8C_SYMBOL_SAMPLES;
|
bw = 8.0*(double)RX_SAMPLE_RATE/(double)JS8C_SYMBOL_SAMPLES;
|
||||||
}
|
}
|
||||||
else if(m_nSubMode == Varicode::JS8CallUltraSlow){
|
else if(m_nSubMode == Varicode::JS8CallSlow){
|
||||||
bw = 8.0*(double)RX_SAMPLE_RATE/(double)JS8E_SYMBOL_SAMPLES;
|
bw = 8.0*(double)RX_SAMPLE_RATE/(double)JS8E_SYMBOL_SAMPLES;
|
||||||
}
|
}
|
||||||
|
else if(m_nSubMode == Varicode::JS8CallUltra){
|
||||||
|
bw = 8.0*(double)RX_SAMPLE_RATE/(double)JS8I_SYMBOL_SAMPLES;
|
||||||
|
}
|
||||||
|
|
||||||
painter0.setPen(penGreen);
|
painter0.setPen(penGreen);
|
||||||
|
|
||||||
|
@ -28,7 +28,8 @@ public:
|
|||||||
JS8CallNormal = 0,
|
JS8CallNormal = 0,
|
||||||
JS8CallFast = 1,
|
JS8CallFast = 1,
|
||||||
JS8CallTurbo = 2,
|
JS8CallTurbo = 2,
|
||||||
JS8CallUltraSlow = 4
|
JS8CallSlow = 4,
|
||||||
|
JS8CallUltra = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
// frame type transmitted via itype and decoded by the ft8 decoded
|
// frame type transmitted via itype and decoded by the ft8 decoded
|
||||||
|
Loading…
Reference in New Issue
Block a user