Merged master 8748
This commit is contained in:
@@ -1,222 +0,0 @@
|
||||
subroutine ft8b(dd0,nfqso,f1,xdt,nharderrors,dmin,nbadcrc,message,xsnr)
|
||||
|
||||
use timer_module, only: timer
|
||||
include 'ft8_params.f90'
|
||||
parameter(NRECENT=10,NP2=2812)
|
||||
character message*22,msgsent*22
|
||||
character*12 recent_calls(NRECENT)
|
||||
real a(5)
|
||||
real s1(0:7,ND),s2(0:7,NN)
|
||||
real ps(0:7)
|
||||
real rxdata(3*ND),llr(3*ND) !Soft symbols
|
||||
real dd0(15*12000)
|
||||
integer*1 decoded(KK),apmask(3*ND),cw(3*ND)
|
||||
integer itone(NN)
|
||||
integer icos7(0:6)
|
||||
complex cd0(NP2)
|
||||
complex csync(0:6,32)
|
||||
complex ctwk(32)
|
||||
complex csymb(32)
|
||||
logical first
|
||||
data icos7/2,5,6,0,4,1,3/
|
||||
data first/.true./
|
||||
save first,twopi,fs2,dt2,taus,baud,csync
|
||||
|
||||
if( first ) then
|
||||
twopi=8.0*atan(1.0)
|
||||
fs2=12000.0/64.0
|
||||
dt2=1/fs2
|
||||
taus=32*dt2
|
||||
baud=1/taus
|
||||
do i=0,6
|
||||
phi=0.0
|
||||
dphi=twopi*icos7(i)*baud*dt2
|
||||
do j=1,32
|
||||
csync(i,j)=cmplx(cos(phi),sin(phi))
|
||||
phi=mod(phi+dphi,twopi)
|
||||
enddo
|
||||
enddo
|
||||
first=.false.
|
||||
endif
|
||||
|
||||
max_iterations=40
|
||||
norder=2
|
||||
! if(abs(nfqso-f1).lt.10.0) norder=3
|
||||
call timer('ft8_down',0)
|
||||
call ft8_downsample(dd0,f1,cd0)
|
||||
call timer('ft8_down',1)
|
||||
|
||||
i0=xdt*fs2
|
||||
smax=0.0
|
||||
do idt=i0-16,i0+16
|
||||
sync=0
|
||||
do i=0,6
|
||||
i1=idt+i*32
|
||||
i2=i1+36*32
|
||||
i3=i1+72*32
|
||||
term1=0.0 ! this needs to be fixed...
|
||||
term2=0.0
|
||||
term3=0.0
|
||||
if( i1.ge.1 .and. i1+31.le.NP2 ) &
|
||||
term1=abs(sum(cd0(i1:i1+31)*conjg(csync(i,1:32))))
|
||||
if( i2.ge.1 .and. i2+31.le.NP2 ) &
|
||||
term2=abs(sum(cd0(i2:i2+31)*conjg(csync(i,1:32))))
|
||||
if( i3.ge.1 .and. i3+31.le.NP2 ) &
|
||||
term3=abs(sum(cd0(i3:i3+31)*conjg(csync(i,1:32))))
|
||||
sync=sync+term1+term2+term3
|
||||
enddo
|
||||
if( sync .gt. smax ) then
|
||||
smax=sync
|
||||
ibest=idt
|
||||
endif
|
||||
enddo
|
||||
xdt2=ibest*dt2
|
||||
|
||||
! peak up the frequency
|
||||
i0=xdt2*fs2
|
||||
smax=0.0
|
||||
do ifr=-5,5
|
||||
delf=ifr*0.5
|
||||
dphi=twopi*delf*dt2
|
||||
phi=0.0
|
||||
do i=1,32
|
||||
ctwk(i)=cmplx(cos(phi),sin(phi))
|
||||
phi=mod(phi+dphi,twopi)
|
||||
enddo
|
||||
sync=0.0
|
||||
do i=0,6
|
||||
i1=i0+i*32
|
||||
i2=i1+36*32
|
||||
i3=i1+72*32
|
||||
term1=0.0 ! this needs to be fixed...
|
||||
term2=0.0
|
||||
term3=0.0
|
||||
if( i1.ge.1 .and. i1+31.le.NP2 ) &
|
||||
term1=abs(sum(cd0(i1:i1+31)*conjg(ctwk*csync(i,1:32))))
|
||||
if( i2.ge.1 .and. i2+31.le.NP2 ) &
|
||||
term2=abs(sum(cd0(i2:i2+31)*conjg(ctwk*csync(i,1:32))))
|
||||
if( i3.ge.1 .and. i3+31.le.NP2 ) &
|
||||
term3=abs(sum(cd0(i3:i3+31)*conjg(ctwk*csync(i,1:32))))
|
||||
sync=sync+term1+term2+term3
|
||||
enddo
|
||||
if( sync .gt. smax ) then
|
||||
smax=sync
|
||||
delfbest=delf
|
||||
endif
|
||||
enddo
|
||||
a=0.0
|
||||
a(1)=-delfbest
|
||||
call twkfreq1(cd0,NP2,fs2,a,cd0)
|
||||
xdt=xdt2
|
||||
f1=f1+delfbest
|
||||
|
||||
j=0
|
||||
do k=1,NN
|
||||
i1=ibest+(k-1)*32
|
||||
csymb=cmplx(0.0,0.0)
|
||||
if( i1.ge.1 .and. i1+31 .le. NP2 ) csymb=cd0(i1:i1+31)
|
||||
call four2a(csymb,32,1,-1,1)
|
||||
s2(0:7,k)=abs(csymb(1:8))
|
||||
enddo
|
||||
j=0
|
||||
do k=1,NN
|
||||
if(k.le.7) cycle
|
||||
if(k.ge.37 .and. k.le.43) cycle
|
||||
if(k.gt.72) cycle
|
||||
j=j+1
|
||||
s1(0:7,j)=s2(0:7,k)
|
||||
enddo
|
||||
|
||||
do j=1,ND
|
||||
ps=s1(0:7,j)
|
||||
where (ps.gt.0.0) ps=log(ps)
|
||||
r1=max(ps(1),ps(3),ps(5),ps(7))-max(ps(0),ps(2),ps(4),ps(6))
|
||||
r2=max(ps(2),ps(3),ps(6),ps(7))-max(ps(0),ps(1),ps(4),ps(5))
|
||||
r4=max(ps(4),ps(5),ps(6),ps(7))-max(ps(0),ps(1),ps(2),ps(3))
|
||||
rxdata(3*j-2)=r4
|
||||
rxdata(3*j-1)=r2
|
||||
rxdata(3*j)=r1
|
||||
enddo
|
||||
|
||||
rxav=sum(rxdata)/(3.0*ND)
|
||||
rx2av=sum(rxdata*rxdata)/(3.0*ND)
|
||||
var=rx2av-rxav*rxav
|
||||
if( var .gt. 0.0 ) then
|
||||
rxsig=sqrt(var)
|
||||
else
|
||||
rxsig=sqrt(rx2av)
|
||||
endif
|
||||
rxdata=rxdata/rxsig
|
||||
ss=0.84
|
||||
llr=2.0*rxdata/(ss*ss)
|
||||
apmask=0
|
||||
cw=0
|
||||
call timer('bpd174 ',0)
|
||||
call bpdecode174(llr,apmask,max_iterations,decoded,cw,nharderrors)
|
||||
call timer('bpd174 ',1)
|
||||
dmin=0.0
|
||||
if(nharderrors.lt.0) then
|
||||
call timer('osd174 ',0)
|
||||
call osd174(llr,norder,decoded,cw,nharderrors,dmin)
|
||||
call timer('osd174 ',1)
|
||||
endif
|
||||
nbadcrc=1
|
||||
message=' '
|
||||
xsnr=-99.0
|
||||
if(count(cw.eq.0).eq.174) go to 900 !Reject the all-zero codeword
|
||||
if( nharderrors.ge.0 .and. dmin.le.30.0 .and. nharderrors .lt. 30) then
|
||||
call chkcrc12a(decoded,nbadcrc)
|
||||
else
|
||||
nharderrors=-1
|
||||
go to 900
|
||||
endif
|
||||
if(nbadcrc.eq.0) then
|
||||
call extractmessage174(decoded,message,ncrcflag,recent_calls,nrecent)
|
||||
call genft8(message,msgsent,itone)
|
||||
xsig=0.0
|
||||
xnoi=0.0
|
||||
do i=1,79
|
||||
xsig=xsig+s2(itone(i),i)**2
|
||||
ios=mod(itone(i)+4,7)
|
||||
xnoi=xnoi+s2(ios,i)**2
|
||||
enddo
|
||||
xsnr=0.001
|
||||
if( xnoi.gt.0 .and. xnoi.lt.xsig ) xsnr=xsig/xnoi-1.0
|
||||
xsnr=10.0*log10(xsnr)-27.0
|
||||
if( xsnr .lt. -24.0 ) xsnr=-24.0
|
||||
endif
|
||||
900 continue
|
||||
return
|
||||
end subroutine ft8b
|
||||
|
||||
subroutine ft8_downsample(dd,f0,c1)
|
||||
|
||||
! Downconvert to complex data sampled at 187.5 Hz, 32 samples/symbol
|
||||
|
||||
parameter (NMAX=15*12000,NFFT2=2812)
|
||||
complex c1(0:NFFT2-1)
|
||||
complex cx(0:NMAX/2)
|
||||
real dd(NMAX),x(NMAX)
|
||||
equivalence (x,cx)
|
||||
save x
|
||||
|
||||
df=12000.0/NMAX
|
||||
x=dd
|
||||
call four2a(cx,NMAX,1,-1,0) !r2c FFT to freq domain
|
||||
baud=12000.0/(32.0*64.0)
|
||||
i0=nint(f0/df)
|
||||
ft=f0+8.0*baud
|
||||
it=min(nint(ft/df),NMAX/2-1)
|
||||
fb=f0-1.0*baud
|
||||
ib=max(1,nint(fb/df))
|
||||
k=0
|
||||
c1=cmplx(0.0,0.0)
|
||||
do i=ib,it
|
||||
c1(k)=cx(i)
|
||||
k=k+1
|
||||
enddo
|
||||
c1=cshift(c1,i0-ib)
|
||||
call four2a(c1,NFFT2,1,1,1) !c2c FFT back to time domain
|
||||
c1=c1/(NMAX*NFFT2)
|
||||
return
|
||||
end subroutine ft8_downsample
|
||||
@@ -1,107 +0,0 @@
|
||||
subroutine genwspr5(msg,msgsent,itone)
|
||||
|
||||
! Encode a WSPR-LF message, producing array itone().
|
||||
|
||||
use crc
|
||||
include 'wsprlf_params.f90'
|
||||
|
||||
character*22 msg,msgsent
|
||||
character*60 cbits
|
||||
integer*1,target :: idat(9)
|
||||
integer*1 msgbits(KK),codeword(ND)
|
||||
logical first
|
||||
integer icw(ND)
|
||||
integer id(NS+ND)
|
||||
integer jd(NS+ND)
|
||||
integer isync(48) !Long sync vector
|
||||
integer ib13(13) !Barker 13 code
|
||||
integer itone(NN)
|
||||
integer*8 n8
|
||||
data ib13/1,1,1,1,1,-1,-1,1,1,-1,1,-1,1/
|
||||
data first/.true./
|
||||
save first,isync
|
||||
|
||||
if(first) then
|
||||
n8=z'cbf089223a51'
|
||||
do i=1,48
|
||||
isync(i)=-1
|
||||
if(iand(n8,1).eq.1) isync(i)=1
|
||||
n8=n8/2
|
||||
enddo
|
||||
first=.false.
|
||||
endif
|
||||
|
||||
idat=0
|
||||
call wqencode(msg,ntype0,idat) !Source encoding
|
||||
id7=idat(7)
|
||||
if(id7.lt.0) id7=id7+256
|
||||
id7=id7/64
|
||||
icrc=crc10(c_loc(idat),9) !Compute the 10-bit CRC
|
||||
idat(8)=icrc/256 !Insert CRC into idat(8:9)
|
||||
idat(9)=iand(icrc,255)
|
||||
call wqdecode(idat,msgsent,itype)
|
||||
|
||||
write(cbits,1004) idat(1:6),id7,icrc
|
||||
1004 format(6b8.8,b2.2,b10.10)
|
||||
read(cbits,1006) msgbits
|
||||
1006 format(60i1)
|
||||
|
||||
! call chkcrc10(msgbits,nbadcrc)
|
||||
! print*,msgsent,itype,crc10_check(c_loc(idat),9),nbadcrc
|
||||
|
||||
call encode300(msgbits,codeword) !Encode the test message
|
||||
icw=2*codeword - 1 !NRZ codeword
|
||||
|
||||
! Message structure:
|
||||
! I channel: R1 48*(S1+D1) S13 48*(D1+S1) R1
|
||||
! Q channel: R1 D109 R1
|
||||
! Generate QPSK with no offset, then shift the y array to get OQPSK.
|
||||
|
||||
! I channel:
|
||||
n=0
|
||||
k=0
|
||||
do j=1,48 !Insert group of 48*(S1+D1)
|
||||
n=n+1
|
||||
id(n)=2*isync(j)
|
||||
k=k+1
|
||||
n=n+1
|
||||
id(n)=icw(k)
|
||||
enddo
|
||||
|
||||
do j=1,13 !Insert Barker 13 code
|
||||
n=n+1
|
||||
id(n)=2*ib13(j)
|
||||
enddo
|
||||
|
||||
do j=1,48 !Insert group of 48*(S1+D1)
|
||||
k=k+1
|
||||
n=n+1
|
||||
id(n)=icw(k)
|
||||
n=n+1
|
||||
id(n)=2*isync(j)
|
||||
enddo
|
||||
|
||||
! Q channel
|
||||
do j=1,204
|
||||
k=k+1
|
||||
n=n+1
|
||||
id(n)=icw(k)
|
||||
enddo
|
||||
|
||||
! Map I and Q to tones.
|
||||
n=0
|
||||
jz=(NS+ND+1)/2
|
||||
do j=1,jz-1
|
||||
jd(2*j-1)=id(j)/abs(id(j))
|
||||
jd(2*j)=id(j+jz)/abs(id(j+jz))
|
||||
enddo
|
||||
jd(NS+ND)=id(jz)/abs(id(jz))
|
||||
itone=0
|
||||
do j=1,jz-1
|
||||
itone(2*j+1)=(jd(2*j)*jd(2*j-1)+1)/2;
|
||||
itone(2*j+2)=-(jd(2*j)*jd(2*j+1)-1)/2;
|
||||
enddo
|
||||
itone(NS+ND+2)=jd(NS+ND) !### Is this correct ??? ###
|
||||
|
||||
return
|
||||
end subroutine genwspr5
|
||||
@@ -1,54 +0,0 @@
|
||||
=== New in Version 1.8
|
||||
|
||||
For quick reference, here's a short list of features and capabilities
|
||||
added to _WSJT-X_ since Version 1.7.0:
|
||||
|
||||
- New mode *FT8* designed for fast QSOs
|
||||
|
||||
- New tool *FreqCal* for accurate frequency calibration of your radio
|
||||
|
||||
- Improved decoding performance for JT65, QRA64, and MSK144
|
||||
|
||||
- *SWL* option for third-party decoding short-format MSK144 messages
|
||||
|
||||
- Experimental amplitude and phase equalization for MSK144
|
||||
|
||||
- Options to minimize screen space used by *Main* and *Wide Graph*
|
||||
windows
|
||||
|
||||
- New set of suggested default frequencies specific to the three IARU
|
||||
regions
|
||||
|
||||
- Enhanced scheme for managing table of suggested default operating
|
||||
frequencies
|
||||
|
||||
- Improved CAT control for many radios, including those controlled
|
||||
through Commander or OmniRig
|
||||
|
||||
- Bug fixes and minor tweaks to user interface
|
||||
|
||||
=== Documentation Conventions
|
||||
|
||||
In this manual the following icons call attention to particular types
|
||||
of information:
|
||||
|
||||
NOTE: *Notes* containing information that may be of interest to
|
||||
particuar classes of users.
|
||||
|
||||
TIP: *Tips* on program features or capabilities that might otherwise be
|
||||
overlooked.
|
||||
|
||||
IMPORTANT: *Warnings* about usage that could lead to undesired
|
||||
consequences.
|
||||
|
||||
=== How You Can Contribute
|
||||
|
||||
_WSJT-X_ is part of an open-source project released under the
|
||||
{gnu_gpl} (GPL). If you have programming or documentation skills or
|
||||
would like to contribute to the project in other ways, please make
|
||||
your interests known to the development team. The project's
|
||||
source-code repository can be found at {devsvn}, and most
|
||||
communication among the developers takes place on the email reflector
|
||||
{devmail}. Bug reports and suggestions for new features, improvements
|
||||
to the _WSJT-X_ User Guide, etc., may also be sent to the
|
||||
{wsjt_yahoo_group} email reflector.
|
||||
@@ -0,0 +1,40 @@
|
||||
subroutine extractmessage174(decoded,msgreceived,ncrcflag)
|
||||
use iso_c_binding, only: c_loc,c_size_t
|
||||
use crc
|
||||
use packjt
|
||||
|
||||
character*22 msgreceived
|
||||
character*87 cbits
|
||||
integer*1 decoded(87)
|
||||
integer*1, target:: i1Dec8BitBytes(11)
|
||||
integer*4 i4Dec6BitWords(12)
|
||||
|
||||
! Write decoded bits into cbits: 75-bit message plus 12-bit CRC
|
||||
write(cbits,1000) decoded
|
||||
1000 format(87i1)
|
||||
read(cbits,1001) i1Dec8BitBytes
|
||||
1001 format(11b8)
|
||||
read(cbits,1002) ncrc12 !Received CRC12
|
||||
1002 format(75x,b12)
|
||||
|
||||
i1Dec8BitBytes(10)=iand(i1Dec8BitBytes(10),128+64+32)
|
||||
i1Dec8BitBytes(11)=0
|
||||
icrc12=crc12(c_loc(i1Dec8BitBytes),11) !CRC12 computed from 75 msg bits
|
||||
|
||||
if(ncrc12.eq.icrc12 .or. sum(decoded(57:87)).eq.0) then !### Kludge ###
|
||||
! CRC12 checks out --- unpack 72-bit message
|
||||
do ibyte=1,12
|
||||
itmp=0
|
||||
do ibit=1,6
|
||||
itmp=ishft(itmp,1)+iand(1,decoded((ibyte-1)*6+ibit))
|
||||
enddo
|
||||
i4Dec6BitWords(ibyte)=itmp
|
||||
enddo
|
||||
call unpackmsg(i4Dec6BitWords,msgreceived,.false.,' ')
|
||||
ncrcflag=1
|
||||
else
|
||||
msgreceived=' '
|
||||
ncrcflag=-1
|
||||
endif
|
||||
return
|
||||
end subroutine extractmessage174
|
||||
@@ -1,74 +0,0 @@
|
||||
////
|
||||
Questions:
|
||||
Should be short one liners ending with ?::
|
||||
If your question is too long for one line, consider multiple questions or rephrase
|
||||
|
||||
Answers:
|
||||
Can be bullet or paragraphs. Bullets make for easier reading.
|
||||
|
||||
Bullet Usage:
|
||||
* = a circle bullet single intent
|
||||
** = circle bullet double indent
|
||||
. = should be avoided as the questions are numbered
|
||||
.. = bullet a, b, c, and so on, double indent
|
||||
|
||||
Alternatives: Use a * Bullet, followed by .. for example, then have
|
||||
a multi-section answer using the * as the section header
|
||||
|
||||
* Section Header 1
|
||||
.. Possible Answer a
|
||||
.. Possible Answer b
|
||||
* Section Header 2
|
||||
.. Possible Answer a
|
||||
.. Possible Answer b
|
||||
|
||||
Link Usage:
|
||||
Use the common/links.adoc for href links to maintain consistency. Try to avoid
|
||||
apostrophes ` or ' as it breaks AsciiDoc syntax without special escaping
|
||||
and they do not translate into other languages well.
|
||||
|
||||
////
|
||||
[qanda]
|
||||
My displayed spectrum is flatter when I do not check the *Flatten* box. What's wrong?::
|
||||
|
||||
_WSJT-X_ does not expect a steep filter edge within the displayed
|
||||
passband. Use a wider IF filter or reduce the displayed passband by
|
||||
decreasing *Bins/Pixel*, increasing *Start*, or reducing the width of
|
||||
the *Wide Graph*. You might also choose to re-center the filter
|
||||
passband, if such control is available.
|
||||
|
||||
How should I configure _WSJT-X_ to run multiple instances?::
|
||||
|
||||
Start _WSJT-X_ from a command-prompt window, assigning each instance a
|
||||
unique identifier as in the following two-instance example. This
|
||||
procedure will isolate the *Settings* file and the writable file
|
||||
location for each instance of _WSJT-X_.
|
||||
|
||||
wsjtx --rig-name=TS2000
|
||||
wsjtx --rig-name=FT847
|
||||
|
||||
When setting up rig control through _OmniRig_, something goes wrong when I click *Test CAT*. What can I do about it?::
|
||||
|
||||
_OmniRig_ apparently has a bug that appears when you click *Test CAT*.
|
||||
Forget using *Test CAT* and just click *OK*. _OmniRig_ then behaves
|
||||
normally.
|
||||
|
||||
I am using _WSJT-X_ with _Ham Radio Deluxe_. All seems well until I start HRD Logbook or DM780 running in parallel; then CAT control becomes unreliable.::
|
||||
|
||||
You may see delays up to 20 seconds or so in frequency changes or
|
||||
other radio commands, due to a bug in HRD. HRD folks are aware of the
|
||||
problem, and are working to resolve it.
|
||||
|
||||
I am running _WSJT-X_ under Ubuntu. The program starts, but menu bar is missing from the top of the main window and the hot-keys don't work.::
|
||||
|
||||
Ubuntu's new "`Unity`" desktop puts the menu for the currently active
|
||||
window at the top of the primary display screen. You can restore menu
|
||||
bars to their traditional locations by typing the following in a
|
||||
command-prompt window:
|
||||
|
||||
sudo apt remove appmenu-qt5
|
||||
|
||||
+
|
||||
Alternatively, you can disable the common menu bar for just WSJT-X by starting the application with the environment variable QT_QPA_PLATFORMTHEME set to empty (the space after the '=' character is necessary):
|
||||
|
||||
QT_QPA_PLATFORMTHEME= wsjtx
|
||||
@@ -0,0 +1,164 @@
|
||||
program chkfft
|
||||
|
||||
! Tests and times one-dimensional FFTs computed by four2a().
|
||||
! An all-Fortran version of four2a() is available, but the preferred
|
||||
! version uses calls to the FFTW library.
|
||||
|
||||
parameter (NMAX=8*1024*1024) !Maximum FFT length
|
||||
complex a(NMAX),b(NMAX)
|
||||
real ar(NMAX),br(NMAX)
|
||||
real mflops
|
||||
character infile*12,arg*8
|
||||
logical list
|
||||
common/patience/npatience
|
||||
equivalence (a,ar),(b,br)
|
||||
|
||||
nargs=iargc()
|
||||
if(nargs.ne.5) then
|
||||
print*,'Usage: chkfft <nfft | infile> nr nw nc np'
|
||||
print*,' nfft: length of FFT'
|
||||
print*,' nfft=0: do lengths 2^n, n=2^4 to 2^23'
|
||||
print*,' infile: name of file with nfft values, one per line'
|
||||
print*,' nr: 0/1 to not read (or read) wisdom'
|
||||
print*,' nw: 0/1 to not write (or write) wisdom'
|
||||
print*,' nc: 0/1 for real or complex data'
|
||||
print*,' np: 0-4 patience for finding best algorithm'
|
||||
go to 999
|
||||
endif
|
||||
|
||||
list=.false.
|
||||
nfft=-1
|
||||
call getarg(1,infile)
|
||||
open(10,file=infile,status='old',err=1)
|
||||
list=.true. !A valid file name was provided
|
||||
go to 2
|
||||
1 read(infile,*) nfft !Takje first argument to be nfft
|
||||
2 call getarg(2,arg)
|
||||
read(arg,*) nr
|
||||
call getarg(3,arg)
|
||||
read(arg,*) nw
|
||||
call getarg(4,arg)
|
||||
read(arg,*) ncomplex
|
||||
call getarg(5,arg)
|
||||
read(arg,*) npatience
|
||||
|
||||
call sgran()
|
||||
|
||||
if(list) write(*,1000) infile,nr,nw,ncomplex,npatience
|
||||
1000 format(/'infile: ',a12,' nr:',i2,' nw',i2,' nc:',i2,' np:',i2/)
|
||||
if(.not.list) write(*,1002) nfft,nr,nw,ncomplex,npatience
|
||||
1002 format(/'nfft: ',i10,' nr:',i2,' nw',i2,' nc:',i2,' np:',i2/)
|
||||
|
||||
open(12,file='chkfft.out',status='unknown')
|
||||
open(13,file='fftwf_wisdom.dat',status='unknown')
|
||||
|
||||
if(nr.ne.0) then
|
||||
call import_wisdom_from_file(isuccess,13)
|
||||
if(isuccess.eq.0) then
|
||||
write(*,1010)
|
||||
1010 format('Failed to import FFTW wisdom.')
|
||||
go to 999
|
||||
endif
|
||||
endif
|
||||
|
||||
idum=-1 !Set random seed
|
||||
ndim=1 !One-dimensional transforms
|
||||
do i=1,NMAX !Set random data
|
||||
x=gran()
|
||||
y=gran()
|
||||
b(i)=cmplx(x,y) !Generate random data
|
||||
enddo
|
||||
|
||||
iters=1000000
|
||||
if(list .or. (nfft.gt.0)) then
|
||||
n1=1
|
||||
n2=1
|
||||
if(nfft.eq.-1) n2=999999
|
||||
write(*,1020)
|
||||
1020 format(' NFFT Time rms MHz MFlops iters', &
|
||||
' tplan'/61('-'))
|
||||
else
|
||||
n1=4
|
||||
n2=23
|
||||
write(*,1030)
|
||||
1030 format(' n N=2^n Time rms MHz MFlops iters', &
|
||||
' tplan'/63('-'))
|
||||
endif
|
||||
|
||||
do ii=n1,n2 !Test one or more FFT lengths
|
||||
if(list) then
|
||||
read(10,*,end=900) nfft !Read nfft from file
|
||||
else if(n2.gt.n1) then
|
||||
nfft=2**ii !Do powers of 2
|
||||
endif
|
||||
|
||||
iformf=1
|
||||
iformb=1
|
||||
if(ncomplex.eq.0) then
|
||||
iformf=0 !Real-to-complex transform
|
||||
iformb=-1 !Complex-to-real (inverse) transform
|
||||
endif
|
||||
|
||||
if(nfft.gt.NMAX) go to 900
|
||||
a(1:nfft)=b(1:nfft) !Copy test data into a()
|
||||
t0=second()
|
||||
call four2a(a,nfft,ndim,-1,iformf) !Get planning time for forward FFT
|
||||
call four2a(a,nfft,ndim,+1,iformb) !Get planning time for backward FFT
|
||||
t2=second()
|
||||
tplan=t2-t0 !Total planning time for this length
|
||||
|
||||
total=0.
|
||||
do iter=1,iters !Now do many iterations
|
||||
a(1:nfft)=b(1:nfft) !Copy test data into a()
|
||||
|
||||
t0=second()
|
||||
call four2a(a,nfft,ndim,-1,iformf) !Forward FFT
|
||||
call four2a(a,nfft,ndim,+1,iformb) !Backward FFT on same data
|
||||
t1=second()
|
||||
total=total+t1-t0
|
||||
if(total.ge.1.0) go to 40 !Cut iterations short if t>1 s
|
||||
enddo
|
||||
iter=iters
|
||||
|
||||
40 time=0.5*total/iter !Time for one FFT of current length
|
||||
tplan=0.5*tplan-time !Planning time for one FFT
|
||||
if(tplan.lt.0) tplan=0.
|
||||
a(1:nfft)=a(1:nfft)/nfft
|
||||
|
||||
! Compute RMS difference between original array and back-transformed array.
|
||||
sq=0.
|
||||
if(ncomplex.eq.1) then
|
||||
do i=1,nfft
|
||||
sq=sq + real(a(i)-b(i))**2 + imag(a(i)-b(i))**2
|
||||
enddo
|
||||
else
|
||||
do i=1,nfft
|
||||
sq=sq + (ar(i)-br(i))**2
|
||||
enddo
|
||||
endif
|
||||
rms=sqrt(sq/nfft)
|
||||
|
||||
freq=1.e-6*nfft/time
|
||||
mflops=5.0/(1.e6*time/(nfft*log(float(nfft))/log(2.0)))
|
||||
if(n2.eq.1 .or. n2.eq.999999) then
|
||||
write(*,1050) nfft,time,rms,freq,mflops,iter,tplan
|
||||
write(12,1050) nfft,time,rms,freq,mflops,iter,tplan
|
||||
1050 format(i8,f11.7,f12.8,f7.2,f8.1,i8,f6.1)
|
||||
else
|
||||
write(*,1060) ii,nfft,time,rms,freq,mflops,iter,tplan
|
||||
write(12,1060) ii,nfft,time,rms,freq,mflops,iter,tplan
|
||||
1060 format(i2,i8,f11.7,f12.8,f7.2,f8.1,i8,f6.1)
|
||||
endif
|
||||
if(mod(ii,50).eq.0) call four2a(0,-1,0,0,0)
|
||||
enddo
|
||||
|
||||
900 continue
|
||||
if(nw.eq.1) then
|
||||
rewind 13
|
||||
call export_wisdom_to_file(13)
|
||||
! write(*,1070)
|
||||
!1070 format(/'Exported FFTW wisdom')
|
||||
endif
|
||||
|
||||
999 call four2a(0,-1,0,0,0)
|
||||
end program chkfft
|
||||
@@ -1,85 +0,0 @@
|
||||
#ifndef COMMONS_H
|
||||
#define COMMONS_H
|
||||
|
||||
#define NSMAX 6827
|
||||
#define NTMAX 300
|
||||
#define RX_SAMPLE_RATE 12000
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdbool>
|
||||
extern "C" {
|
||||
#else
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This structure is shared with Fortran code, it MUST be kept in
|
||||
* sync with lib/jt9com.f90
|
||||
*/
|
||||
extern struct dec_data {
|
||||
float ss[184*NSMAX];
|
||||
float savg[NSMAX];
|
||||
float sred[5760];
|
||||
short int d2[NTMAX*RX_SAMPLE_RATE];
|
||||
struct
|
||||
{
|
||||
int nutc; //UTC as integer, HHMM
|
||||
bool ndiskdat; //true ==> data read from *.wav file
|
||||
int ntrperiod; //TR period (seconds)
|
||||
int nQSOProgress; /* QSO state machine state */
|
||||
int nfqso; //User-selected QSO freq (kHz)
|
||||
int nftx; /* Transmit audio offset where
|
||||
replies might be expected */
|
||||
bool newdat; //true ==> new data, must do long FFT
|
||||
int npts8; //npts for c0() array
|
||||
int nfa; //Low decode limit (Hz)
|
||||
int nfSplit; //JT65 | JT9 split frequency
|
||||
int nfb; //High decode limit (Hz)
|
||||
int ntol; //+/- decoding range around fQSO (Hz)
|
||||
int kin;
|
||||
int nzhsym;
|
||||
int nsubmode;
|
||||
bool nagain;
|
||||
int ndepth;
|
||||
bool lapon;
|
||||
int napwid;
|
||||
int ntxmode;
|
||||
int nmode;
|
||||
int minw;
|
||||
bool nclearave;
|
||||
int minSync;
|
||||
float emedelay;
|
||||
float dttol;
|
||||
int nlist;
|
||||
int listutc[10];
|
||||
int n2pass;
|
||||
int nranera;
|
||||
int naggressive;
|
||||
bool nrobust;
|
||||
int nexp_decode;
|
||||
char datetime[20];
|
||||
char mycall[12];
|
||||
char mygrid[6];
|
||||
char hiscall[12];
|
||||
char hisgrid[6];
|
||||
} params;
|
||||
} dec_data;
|
||||
|
||||
extern struct {
|
||||
float syellow[NSMAX];
|
||||
float ref[3457];
|
||||
float filter[3457];
|
||||
} spectra_;
|
||||
|
||||
extern struct {
|
||||
int nclearave;
|
||||
int nsum;
|
||||
float blue[4096];
|
||||
float red[4096];
|
||||
} echocom_;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // COMMONS_H
|
||||
@@ -1,502 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>WideGraph</class>
|
||||
<widget class="QDialog" name="WideGraph">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>799</width>
|
||||
<height>395</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="CPlotter" name="widePlot">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QCheckBox" name="cbControls">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>9</x>
|
||||
<y>10</y>
|
||||
<width>60</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>65</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Controls</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="controls_widget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="horizontalSpacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="1" column="8">
|
||||
<widget class="QSlider" name="gain2dSlider">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Spectrum gain</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-50</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksAbove</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="labPalette">
|
||||
<property name="text">
|
||||
<string> Palette </string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="adjust_palette_push_button">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Enter definition for a new color palette.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Adjust...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="8">
|
||||
<widget class="QSlider" name="gainSlider">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Waterfall gain</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-50</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksAbove</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="11">
|
||||
<widget class="QSpinBox" name="sbPercent2dPlot">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Set fractional size of spectrum in this window.</p></body></html></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> %</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Spec </string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>30</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="6">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbFlatten">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Flatten spectral baseline over the full displayed interval.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Flatten</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbRef">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Compute and save a reference spectrum. (Not yet fully implemented.)</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Ref Spec</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="11">
|
||||
<widget class="QSpinBox" name="smoSpinBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Smoothing of Linear Average spectrum</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Smooth </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>7</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="bppSpinBox">
|
||||
<property name="toolTip">
|
||||
<string>Compression factor for frequency scale</string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Bins/Pixel </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QComboBox" name="paletteComboBox">
|
||||
<property name="toolTip">
|
||||
<string>Select waterfall palette</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="6">
|
||||
<widget class="QComboBox" name="spec2dComboBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Select data for spectral display</p></body></html></string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Current</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Cumulative</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Linear Avg</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Reference</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QSpinBox" name="fStartSpinBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Frequency at left edge of waterfall</p></body></html></string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> Hz</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Start </string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>5000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="fSplitSpinBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Decode JT9 only above this frequency</p></body></html></string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> JT9</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>JT65 </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>5000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>3000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QSpinBox" name="waterfallAvgSpinBox">
|
||||
<property name="toolTip">
|
||||
<string>Number of FFTs averaged (controls waterfall scrolling rate)</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>N Avg </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="10">
|
||||
<widget class="QSlider" name="zeroSlider">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Waterfall zero</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-50</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksAbove</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="10">
|
||||
<widget class="QSlider" name="zero2dSlider">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Spectrum zero</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-50</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksAbove</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" rowspan="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="12" rowspan="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="3" rowspan="2">
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="5" rowspan="2">
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>CPlotter</class>
|
||||
<extends>QFrame</extends>
|
||||
<header>plotter.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
Reference in New Issue
Block a user