Merged master 8748
This commit is contained in:
@@ -1,142 +0,0 @@
|
||||
program jt65
|
||||
|
||||
! Test the JT65 decoder for WSJT-X
|
||||
|
||||
use options
|
||||
use timer_module, only: timer
|
||||
use timer_impl, only: init_timer
|
||||
use jt65_test
|
||||
use readwav
|
||||
|
||||
character c,mode
|
||||
logical :: display_help=.false.,nrobust=.false.,single_decode=.false.
|
||||
type(wav_header) :: wav
|
||||
integer*2 id2(NZMAX)
|
||||
real*4 dd(NZMAX)
|
||||
character*80 infile
|
||||
character(len=500) optarg
|
||||
character*12 mycall,hiscall
|
||||
character*6 hisgrid
|
||||
|
||||
type (option) :: long_options(12) = [ &
|
||||
option ('aggressive',.true.,'a','aggressiveness [0-10], default AGGR=0','AGGR'), &
|
||||
option ('depth',.true.,'d','depth=5 hinted decoding, default DEPTH=0','DEPTH'), &
|
||||
option ('freq',.true.,'f','signal frequency, default FREQ=1270','FREQ'), &
|
||||
option ('help',.false.,'h','Display this help message',''), &
|
||||
option ('mode',.true.,'m','Mode A, B, C. Default is A.','MODE'), &
|
||||
option ('ntrials',.true.,'n','number of trials, default TRIALS=10000','TRIALS'), &
|
||||
option ('robust-sync',.false.,'r','robust sync',''), &
|
||||
option ('my-call',.true.,'c','my callsign',''), &
|
||||
option ('his-call',.true.,'x','his callsign',''), &
|
||||
option ('his-grid',.true.,'g','his grid locator',''), &
|
||||
option ('experience-decoding',.true.,'X' &
|
||||
,'experience decoding options (1..n), default FLAGS=0','FLAGS'), &
|
||||
option ('single-signal-mode',.false.,'s','decode at signal frequency only','') ]
|
||||
|
||||
naggressive=0
|
||||
nfqso=1500
|
||||
ntrials=10000
|
||||
nexp_decode=0
|
||||
ntol=1000
|
||||
nsubmode=0
|
||||
nlow=200
|
||||
nhigh=4000
|
||||
n2pass=2
|
||||
ndepth=3
|
||||
|
||||
do
|
||||
call getopt('a:d:f:hm:n:rc:x:g:X:s',long_options,c,optarg,narglen,nstat,noffset,nremain,.true.)
|
||||
if( nstat .ne. 0 ) then
|
||||
exit
|
||||
end if
|
||||
select case (c)
|
||||
case ('a')
|
||||
read (optarg(:narglen), *) naggressive
|
||||
case ('d')
|
||||
read (optarg(:narglen), *) ndepth
|
||||
case ('f')
|
||||
read (optarg(:narglen), *) nfqso
|
||||
case ('h')
|
||||
display_help = .true.
|
||||
case ('m')
|
||||
read (optarg(:narglen), *) mode
|
||||
if( mode .eq. 'b' .or. mode .eq. 'B' ) then
|
||||
nsubmode=1
|
||||
endif
|
||||
if( mode .eq. 'c' .or. mode .eq. 'C' ) then
|
||||
nsubmode=2
|
||||
endif
|
||||
case ('n')
|
||||
read (optarg(:narglen), *) ntrials
|
||||
case ('r')
|
||||
nrobust=.true.
|
||||
case ('c')
|
||||
read (optarg(:narglen), *) mycall
|
||||
case ('x')
|
||||
read (optarg(:narglen), *) hiscall
|
||||
case ('g')
|
||||
read (optarg(:narglen), *) hisgrid
|
||||
case ('X')
|
||||
read (optarg(:narglen), *) nexp_decode
|
||||
case ('s')
|
||||
single_decode=.true.
|
||||
ntol=100
|
||||
nlow=nfqso-ntol
|
||||
nhigh=nfqso+ntol
|
||||
n2pass=1
|
||||
end select
|
||||
end do
|
||||
|
||||
if(single_decode) nexp_decode=ior(nexp_decode,32)
|
||||
if(display_help .or. nstat.lt.0 .or. nremain.lt.1) then
|
||||
print *, ''
|
||||
print *, 'Usage: jt65 [OPTIONS] file1 [file2 ...]'
|
||||
print *, ''
|
||||
print *, ' JT65 decode pre-recorded .WAV file(s)'
|
||||
print *, ''
|
||||
print *, 'OPTIONS:'
|
||||
print *, ''
|
||||
do i = 1, size (long_options)
|
||||
call long_options(i) % print (6)
|
||||
end do
|
||||
go to 999
|
||||
endif
|
||||
|
||||
call init_timer ('timer.out')
|
||||
call timer('jt65 ',0)
|
||||
|
||||
ndecoded=0
|
||||
do ifile=noffset+1,noffset+nremain
|
||||
nfa=nlow
|
||||
nfb=nhigh
|
||||
minsync=0
|
||||
call get_command_argument(ifile,optarg,narglen)
|
||||
infile=optarg(:narglen)
|
||||
call timer('read ',0)
|
||||
call wav%read (infile)
|
||||
i1=index(infile,'.wav')
|
||||
if( i1 .eq. 0 ) i1=index(infile,'.WAV')
|
||||
read(infile(i1-4:i1-1),*,err=998) nutc
|
||||
npts=52*12000
|
||||
read(unit=wav%lun) id2(1:npts)
|
||||
close(unit=wav%lun)
|
||||
call timer('read ',1)
|
||||
dd(1:npts)=id2(1:npts)
|
||||
dd(npts+1:)=0.
|
||||
call test(dd,nutc,nfa,nfb,nfqso,ntol,nsubmode, &
|
||||
n2pass,nrobust,ntrials,naggressive,ndepth, &
|
||||
mycall,hiscall,hisgrid,nexp_decode)
|
||||
if(nft.gt.0) exit
|
||||
enddo
|
||||
|
||||
call timer('jt65 ',1)
|
||||
call timer('jt65 ',101)
|
||||
! call four2a(a,-1,1,1,1) !Free the memory used for plans
|
||||
! call filbig(a,-1,1,0.0,0,0,0,0,0) ! (ditto)
|
||||
go to 999
|
||||
|
||||
998 print*,'Cannot read from file:'
|
||||
print*,infile
|
||||
|
||||
999 continue
|
||||
end program jt65
|
||||
@@ -1,189 +0,0 @@
|
||||
=== Frequency Calibration
|
||||
|
||||
Many _WSJT-X_ capabilities depend on signal-detection bandwidths no
|
||||
more than a few Hz. Frequency accuracy and stability are therefore
|
||||
unusually important. We provide tools to enable accurate frequency
|
||||
calibration of your radio, as well as precise frequency measurement of
|
||||
on-the-air signals. The calibration procedure works by automatically
|
||||
cycling your CAT-controlled radio through a series of preset
|
||||
frequencies of carrier-based signals at reliably known frequencies,
|
||||
measuring the error in dial frequency for each signal.
|
||||
|
||||
You will probably find it convenient to define and use a special
|
||||
<<CONFIG-MENU,Configuration>> dedicated to frequency calibration.
|
||||
Then complete the following steps, as appropriate for your system.
|
||||
|
||||
- Switch to FreqCal mode
|
||||
|
||||
- In the _Working Frequencies_ box on the *Settings -> Frequencies*
|
||||
tab, delete any default frequencies for *FreqCal* mode that are not
|
||||
relevant for your location. You may want to replace some of them with
|
||||
reliably known frequencies receivable at your location.
|
||||
|
||||
TIP: We find major-city AM broadcast stations generally serve well as
|
||||
frequency calibrators at the low frequency end of the spectrum. In
|
||||
North America we also use the standard time-and-frequency broadcasts
|
||||
of WWV at 2.500, 5.000, 10.000, 15.000, and 20.000 MHz, and CHU at
|
||||
3.330, 7.850, and 14.670 MHz. Similar shortwave signals are available
|
||||
in other parts of the world.
|
||||
|
||||
- To cycle automatically through your chosen list of calibration
|
||||
frequencies, check *Execute frequency calibration cycle* on the
|
||||
*Tools* menu. _WSJT-X_ will spend 30 seconds at each frequency,
|
||||
writing its measurements to the file `fmt.all` in the directory
|
||||
where your log files are kept.
|
||||
|
||||
- During the calibration procedure, the radio's USB dial frequency is
|
||||
offset 1500 Hz below each *FreqCal* entry in the default frequencies
|
||||
list. As shown in the screen shot below, detected signal carriers
|
||||
therefore appear at about 1500 Hz in the _WSJT-X_ waterfall.
|
||||
|
||||
image::FreqCal.png[align="left",alt="FreqCal"]
|
||||
|
||||
With modern synthesized radios, small measured offsets from 1500 Hz
|
||||
will exhibit a straight-line dependence on frequency. You can
|
||||
approximate the calibration of your radio by simply dividing the
|
||||
measured frequency offset (in Hz) at the highest reliable frequency by
|
||||
the nominal frequency itself (in MHz). For example, the 20 MHz
|
||||
measurement for WWV shown above produced a measured tone offset of
|
||||
24.6 Hz, displayed in the _WSJT-X_ decoded text window. The resulting
|
||||
calibration constant is 24.6/20=1.23 parts per million. This number
|
||||
may be entered as *Slope* on the *settings -> Frequencies* tab.
|
||||
|
||||
A more precise calibration can be effected by fitting the intercept
|
||||
and slope of a straight line to the whole sequence of calibration
|
||||
measurements, as shown for these measurements in the graph plotted
|
||||
below. Software tools for completing this task are included with the
|
||||
_WSJT-X_ installation, and detailed instructions for their use are
|
||||
available at https://physics.princeton.edu/pulsar/k1jt/FMT_User.pdf.
|
||||
Using these tools and no specialized hardware beyond your
|
||||
CAT-interfaced radio, you can calibrate the radio to better than 1 Hz
|
||||
and compete very effectively in the ARRL's periodic Frequency
|
||||
Measuring Tests.
|
||||
|
||||
image::FreqCal_Graph.png[align="left",alt="FreqCal_Graph"]
|
||||
|
||||
=== Reference Spectrum
|
||||
|
||||
_WSJT-X_ provides a tool that can be used to determine the detailed
|
||||
shape of your receiver's passband. Disconnect your antenna or tune to
|
||||
a quiet frequency with no signals. With WSJT-X running in one of the
|
||||
slow modes, select *Measure reference spectrum* from the *Tools* menu.
|
||||
Wait for about a minute and then hit the *Stop* button. A file named
|
||||
`refspec.dat` will appear in your log directory.
|
||||
|
||||
[ ... TBD ... ]
|
||||
|
||||
=== Phase Response and Equalization
|
||||
|
||||
*Measure phase response* under the *Tools* menu is for advanced MSK144
|
||||
users. Phase equalization is used to compensate for group-delay
|
||||
variation across the passband of receiver filters. Careful application
|
||||
of this facility can reduce intersymbol interference, resulting in
|
||||
improved decoding sensitivity. If you use a software-defined receiver
|
||||
with linear-phase filters there is no need to apply phase
|
||||
equalization.
|
||||
|
||||
After a received frame is decoded *Measure phase response* generates
|
||||
an undistorted waveform whose Fourier transform is used as a
|
||||
frequency-dependent phase reference to compare with the phase of the
|
||||
received frame's Fourier coefficients. Phase differences between the
|
||||
reference and the received waveform include contributions from the
|
||||
originating station's transmit filter, the propagation channel, and
|
||||
filters in the receiver. If the received frame originates from a
|
||||
station known to transmit signals having little phase distortion (say,
|
||||
a station known to use a properly adjusted
|
||||
software-defined-transceiver) and if the received signal is relatively
|
||||
free from multipath distortion so that the channel phase is close to
|
||||
linear, the measured phase differences will be representative of the
|
||||
local receiver's phase response.
|
||||
|
||||
Complete the following steps to generate a phase equalization curve:
|
||||
|
||||
- Record a number of wav files that contain decodable signals from
|
||||
your chosen reference station. Best results will be obtained when the
|
||||
SNR of the reference signals is at least 9 dB.
|
||||
|
||||
- Enter the callsign of the reference station in the DX Call box.
|
||||
|
||||
- Select *Measure phase response* from the *Tools* menu, and process
|
||||
the wav files. The mode character will change from `&` to `^` while
|
||||
_WSJT-X_ is measuring the phase response and it will change back to
|
||||
`&` after the measurement is completed. The program needs to average a
|
||||
number of high-SNR frames to accurately estimate the phase, so it may
|
||||
be necessary to process several wav files. The measurement can be
|
||||
aborted at any time by selecting *Measure phase response* again to
|
||||
toggle the phase measurement off.
|
||||
|
||||
+
|
||||
|
||||
When the measurement is complete _WSJT-X_ will save the measured
|
||||
phase response in the *Log directory*, in a file with suffix
|
||||
".pcoeff". The filename will contain the callsign of the reference
|
||||
station and a timestamp. For example: K0TPP_170923_112027.pcoeff
|
||||
|
||||
- Select *Equalization tools ...* under the *Tools* menu and click the
|
||||
*Phase ...* button to view the contents of the *Log directory*. Select
|
||||
the desired pcoeff file. The measured phase values will be plotted as
|
||||
discrete circles along with a fitted curve labeled "Proposed". This is
|
||||
the proposed phase equalization curve. It's a good idea to repeat the
|
||||
phase measurement several times, using different wav files for each
|
||||
measurement, to ensure that your measurements are repeatable.
|
||||
|
||||
- Once you are satisfied with a fitted curve, push the *Apply* button
|
||||
to save the proposed response. The red curve will be replaced with a
|
||||
light green curve labeled "Current" to indicate that the phase
|
||||
equalization curve is now being applied to the received data. Another
|
||||
curve labeled "Group Delay" will appear. The "Group Delay" curve shows
|
||||
the group delay variation across the passband, in ms. Push the
|
||||
*Discard* button to remove the captured data, leaving only the applied
|
||||
phase equalization curve and corresponding group delay curve.
|
||||
|
||||
- To revert to no phase equalization, push the *Restore Defaults*
|
||||
button followed by the *Apply* button.
|
||||
|
||||
The three numbers that are printed at the end of each MSK144 decode line
|
||||
can be used to assess the improvement provided by equalization. These numbers
|
||||
`N` `H` `E` are:
|
||||
`N` - Number of frames averaged,
|
||||
`H` - Number of bit errors corrected,
|
||||
`E` - Size of MSK eye diagram opening.
|
||||
|
||||
Here is a decode of K0TPP obtained while *Measure phase response* was measuring
|
||||
the phase response:
|
||||
|
||||
103900 17 6.5 1493 ^ WA8CLT K0TPP +07 1 0 1.2
|
||||
|
||||
The "^" symbol indicates that a phase measurement is being accumulated. The
|
||||
three numbers at the end of the line indicate that one frame was
|
||||
used to obtain the decode, there were no bit errors, and the
|
||||
eye-opening was 1.2. Here's how the same decode looks after phase equalization:
|
||||
|
||||
103900 17 6.5 1493 & WA8CLT K0TPP +07 1 0 1.6
|
||||
|
||||
In this case, equalization has increased the eye opening from 1.2 to 1.6.
|
||||
Larger eye openings are associated with reduced likelihood of bit errors and
|
||||
higher likelihood that a frame will be successfully decoded.
|
||||
In this case, the larger eye-opening
|
||||
tells us that phase equalization was successful, but it is important to note
|
||||
that this test does not tell us whether the applied phase equalization curve
|
||||
is going to improve decoding of signals other than those from the reference
|
||||
station, K0TPP!
|
||||
|
||||
We strongly advise you to carry out before and after comparisons
|
||||
using a large number of saved wav files with signals from many different
|
||||
stations to decide whether or not the equalization curve improves decoding for most
|
||||
signals. When doing before and after comparisons, keep in mind that
|
||||
equalization may cause _WSJT-X_ to successfully decode a frame
|
||||
that was not decoded before equalization was applied.
|
||||
For this reason, be sure that the time "T" of
|
||||
the two decodes are the same before comparing their end-of-line quality numbers.
|
||||
|
||||
When comparing before and after decodes having the same "T", keep in mind
|
||||
that a smaller first number means that decoding has improved, even if the
|
||||
second and third numbers appear to be "worse". For example, suppose that the quality
|
||||
numbers before equalization are "2 0 0.2" and after equalization
|
||||
"1 5 -0.5". These numbers show improved decoding because
|
||||
the decode was obtained using only a single
|
||||
frame after equalization whereas a 2-frame average was needed before equalization.
|
||||
|
||||
Reference in New Issue
Block a user