Removed many files not needed for map65, and fixed Makefile accordingly.

git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/map65@327 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Joe Taylor 2007-01-09 15:15:26 +00:00
parent 659b430fbf
commit 4470e5ebe5
33 changed files with 19 additions and 5079 deletions

View File

@ -1,91 +0,0 @@
To: Users of WSJT
From: Joe Taylor, K1JT
Subject: WSJT 5.9.0
Date: November 14, 2005
I am pleased to announce that WSJT 5.9.0 is available for free
download from the WSJT Home Page,
http://pulsar.princeton.edu/~joe/K1JT. It should appear soon
on the European mirror site, http://www.dk5ya.de, as well.
I believe that all reported bugs found in beta-release version 5.8.6
have been fixed. In addition, new enhancements have taken the program
well beyond the capabilities of the baseline comparison versions,
4.9.8 and 5.8.6.
The new WSJT 5.9.0 is faster and better than previous versions in a
number of ways. A brief description of the enhancements since version
5.8.6 can be found at
http://pulsar.princeton.edu/~joe/K1JT/UpdateHistory.txt. There are
many program changes, so be sure to read this information carefully
before trying to use WSJT 5.9.0!
Of course there may be some new bugs, and perhaps I have overlooked an
existing problem that you already know about. Please let me know if
you find shortcomings in version 5.9.0, or if you have suggestions for
further improvements.
Sorry, I have not yet found time to implement EME Echo mode. When
that is done, and when I have finished some further enhancements to
the decoders, WSJT 6.0 will be born. With some luck, there may also
be a new User's Guide at about that time.
With best wishes,
-- 73, Joe, K1JT
Additional Information for Programmers
-----------------------------------------------------------------------
WSJT versions 5.8+ are the result of a complete re-write of the user
interface, timing control, and audio I/O portions of WSJT 4.9.8. My
principal motivation was to make the program multi-threaded, both for
real-time operational convenience and for performance reasons.
Another strong motivation was a desire to move the program away from
its dependence on a proprietary compiler (Microsoft Visual Basic) and
a single computer platform (Windows).
The user interface of WSJT 5.8+ is written in Python -- an elegant,
open, cross-platform language that has been a pleasure for me to
learn. The remainder of the program is written mostly in Fortran,
with some routines coded in C; much of that code has been carried over
directly from WSJT 4.9.8.
I hope soon to release the source code for WSJT under the GNU General
Public License (GPL). To this end, I have separated out the one piece
of proprietary code formerly in the program -- the soft-decision Reed
Solomon decoder licensed from CodeVector Technologies (CVT). A driver
for this decoder, optimized for JT65, has been compiled into a
stand-alone executable that is now distributed as part of the WSJT
installation package, but not part of the program itself. With this
approach I can honor all provisions of the CVT license, and at the
same time release everything else as an open source program under the
GPL.
WSJT 5.9.0 now includes an open source hard-decision Reed Solomon
decoder based on code written by Phil Karn, KA9Q . WSJT uses this
decoder automatically if the proprietary CVT decoder is unavailable.
In such instances the "deep search" decodes retain their full
sensitivity, but fully general decoding independent of the callsign
database will be less sensitive by 2 or more dB, depending on signal
fading characteristics. Separation of the program into two executable
units is transparent to the user.
WSJT 5.9.0 uses the following open source libraries, which are also
available under the GPL:
1. FFTW, by Matteo Frigo and Steven Johnson, for computing Fourier
transforms
2. "Secret Rabbit Code" or "libsamplerate", by Erik de Castro, for
accomplishing band-limited resampling of data
3. RS, by Phil Karn, KA9Q, for Reed Solomon encoding and
hard-decision decoding.
I hope that the open release of WSJT source code will encourage others
to read and understand the code, get involved in improving WSJT, and
perhaps porting it to other platforms. Versions of the CVT
soft-decision decoder for Linux or Macintosh will be easy to compile
and distribute, if there is demand for them.

View File

@ -1,185 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
<TITLE></TITLE>
<META NAME="GENERATOR" CONTENT="OpenOffice.org 2.0-pre (Linux)">
<META NAME="CREATED" CONTENT="20060311;19474000">
<META NAME="CHANGED" CONTENT="20060311;20035200">
<STYLE>
<!--
PRE { font-family: "Thorndale AMT" }
-->
</STYLE>
</HEAD>
<BODY LANG="de-DE" DIR="LTR">
<PRE>HowTo for Linux SuSE 10.0 ( DL3LST)
Use Yast to install the following packages from the Linux Distribution DVD
Compiler
cpp
gcc
gcc-c++
liggcc
Tcl/tk
tcl-devel
tk-devel
alsa-devel
Python
python
python-devel
python-imaging
python-numeric
python-tk
--------------------------------------------------------------------------------------------------
// Fortran compiler
Page: <A HREF="http://www.g95.org/"> http://www.g95.org/</A>
Downloadpage: <A HREF="http://ftp.g95.org/"> http://ftp.g95.org/</A>
Page: <A HREF="http://ftp.g95.org/g95-x86-linux.tgz"> http://ftp.g95.org/g95-x86-linux.tgz</A>
install: g95
follow instruction File: Install
How to install g95:
File Install:
1) Unpack the downloaded tarball (e.g. g95-x86-linux.tgz) in a directory
of your choice:
tar -zxvf g95-x86-linux.tgz
2) For your convenience, you can create another symbolic link from a
directory in your $PATH (e.g. ~/bin) to the executable
ln -s $PWD/g95-install/bin/*g95* ~/bin/g95
You should now be able to run g95 and create executables.
To get a list of environment variables that control the library, run a
compiled binary with the --help option, ie:
./a.out <20>help
From console try the g95 command .
The system should answer
g95: no input files
I changed the SymLink to /usr/bin where i installed the g77 packages too
ln -s $PWD/g95-install/bin/*g95* /usr/bin/g95
gcc-g77 compiler
Page: <A HREF="http://sourceforge.net/project/showfiles.php?group_id=2435&amp;package_id=82721&amp;release_id=15880">http://sourceforge.net/project/showfiles.php?group_id=2435&amp;package_id=82721&amp;release_id=15880</A>
Download: <A HREF="http://prdownloads.sourceforge.net/mingw/gcc-g77-3.4.2-20040916-1.tar.gz?download">http://prdownloads.sourceforge.net/mingw/gcc-g77-3.4.2-20040916-1.tar.gz?download</A>
From gcc-g77-3.4.2-20040916-1.tar.gz we need the /libexec folder for l2g
copy from the archive the folder
/libexec to /usr/libexec
------------------------------------------------------------------------------
other packages
------------------------------------------------------------------------------
Install: PortaudioV1.19
Page: <A HREF="http://www.portaudio.com/usingsvn.html">http://www.portaudio.com/usingsvn.html</A>
Download: <A HREF="http://www.portaudio.com/archives/pa_previous_snapshot_v19.tar.gz">http://www.portaudio.com/archives/pa_previous_snapshot_v19.tar.gz</A>
./configure
make all
make install
------------------------------------------------------------------------------
FFT3
Page : <A HREF="http://www.fftw.org/">http://www.fftw.org/ </A>
Download : <A HREF="http://www.fftw.org/fftw-3.1.1.tar.g">http://www.fftw.org/fftw-3.1.1.tar.g</A>z
./configure
./make all
./ make install
------------------------------------------------------------------------------
libsamplerate
libsamplerate-0.1.2.
Download: <A HREF="http://www.mega-nerd.com/SRC/download.html">http://www.mega-nerd.com/SRC/download.html</A>
./configure
./make all
./ make install
------------------------------------------------------------------------------
reed-solomon-4.0
.Page: <A HREF="http://www.ka9q.net/code/fec/">http://www.ka9q.net/code/fec/</A>
Download: <A HREF="http://www.ka9q.net/code/fec/reed-solomon-4.0.tar.gz">http://www.ka9q.net/code/fec/reed-solomon-4.0.tar.gz</A>
/configure
./make
./ make install
------------------------------------------------------------------------------
F2PY ( Fortran to Python )
Download: <A HREF="http://cens.ioc.ee/projects/f2py2e/2.x/F2PY-2-latest.tar.gz">http://cens.ioc.ee/projects/f2py2e/2.x/F2PY-2-latest.tar.gz</A>
python setup.py install
Scipy_Distutils
Page: <A HREF="http://cens.ioc.ee/projects/f2py2e/2.x/">http://cens.ioc.ee/projects/f2py2e/2.x/</A>
Download: <A HREF="http://cens.ioc.ee/projects/f2py2e/2.x/scipy_distutils-latest.tar.gz"> http://cens.ioc.ee/projects/f2py2e/2.x/scipy_distutils-latest.tar.gz</A>
python setup.py install
WSJT source code
K1JT Page: <A HREF="http://pulsar.princeton.edu/~joe/K1JT/">http://pulsar.princeton.edu/~joe/K1JT/</A>
Download page: <A HREF="http://developer.berlios.de/projects/wsjt/">http://developer.berlios.de/projects/wsjt/</A>
./configure
make
python wsjt.py
that<EFBFBD>s all - have fun
------------------------------------------------------------------------------
If you need the packages for other Linux distributions see linkpages below
------------------------------------------------------------------------------
Python:
Page. <A HREF="http://www.python.org/download/releases/2.4.3">http://www.python.org/download/releases/2.4.3</A>
Download: <A HREF="http://www.python.org/ftp/python/2.4.3/Python-2.4.3.tgz">http://www.python.org/ftp/python/2.4.3/Python-2.4.3.tgz</A>
/configure
./make
./ make install
than run
python setup.py install
Numeric
Page: <A HREF="http://numeric.scipy.org/"> http://numeric.scipy.org</A>/
Download: <A HREF="http://prdownloads.sourceforge.net/numpy/Numeric-24.2.tar.gz?download">http://prdownloads.sourceforge.net/numpy/Numeric-24.2.tar.gz?download</A>
install
Iimaging (be sure Tcl/Ck Lib was installed before)
Page: <A HREF="http://www.pythonware.com/products/pil/">http://www.pythonware.com/products/pil/</A>
Download: <A HREF="http://effbot.org/downloads/Imaging-1.1.5.tar.gz">http://effbot.org/downloads/Imaging-1.1.5.tar.gz</A>
python setup.py install
------------------------------------------------------------------------------
other sites
------------------------------------------------------------------------------
for gcc compiler try
<A HREF="http://gcc.gnu.org/mirrors.html">http://gcc.gnu.org/mirrors.html</A>
Example German server
<A HREF="ftp://ftp.fu-berlin.de/unix/languages/gcc/releases/gcc-4.1.0/">ftp://ftp.fu-berlin.de/unix/languages/gcc/releases/gcc-4.1.0/</A>
<A HREF="ftp://ftp.gwdg.de/pub/misc/gcc/releases/gcc-4.1.1/">ftp://ftp.gwdg.de/pub/misc/gcc/releases/gcc-4.1.1/</A>
the full program ( !!! filesize is 21 MB )
<A HREF="ftp://ftp.fu-berlin.de/unix/languages/gcc/releases/gcc-4.1.0/gcc-core-4.1.0.tar.gz">ftp://ftp.fu-berlin.de/unix/languages/gcc/releases/gcc-4.1.0/gcc-core-4.1.0.tar.gz</A>
./configure
make
make install
</PRE>
</BODY>
</HTML>

View File

@ -1,46 +0,0 @@
program JT65karn
C Provides examples of message packing, bit and symbol ordering,
C Reed Solomon encoding, and other necessary details of the JT65
C protocol.
character*22 msg0,msg,decoded,cok*3
integer dgen(12),sent(63),recd(12),era(51)
nargs=iargc()
if(nargs.ne.1) then
print*,'Usage: JT65code "message"'
go to 999
endif
call getarg(1,msg0) !Get message from command line
msg=msg0
call chkmsg(msg,cok,nspecial,flip) !See if it includes "OOO" report
if(nspecial.gt.0) then !or is a shorthand message
write(*,1010)
1010 format('Shorthand message.')
go to 999
endif
call packmsg(msg,dgen) !Pack message into 72 bits
write(*,1020) msg0
1020 format('Message: ',a22) !Echo input message
if(iand(dgen(10),8).ne.0) write(*,1030) !Is the plain text bit set?
1030 format('Plain text.')
write(*,1040) dgen
1040 format('Packed message, 6-bit symbols: ',12i3) !Display packed symbols
call rs_encode(dgen,sent) !RS encode
call interleave63(sent,1) !Interleave channel symbols
call graycode(sent,63,1) !Apply Gray code
write(*,1050) sent
1050 format('Channel symbols, including FEC:'/(i5,20i3))
call graycode(sent,63,-1)
call interleave63(sent,-1)
call rs_decode(sent,era,0,recd,nerr)
call unpackmsg(recd,decoded) !Unpack the user message
write(*,1060) decoded,cok
1060 format('Decoded message: ',a22,2x,a3)
999 end

View File

@ -1,20 +0,0 @@
include 'JT65code.f'
include 'nchar.f'
include 'grid2deg.f'
include 'packmsg.f'
include 'packtext.f'
include 'packcall.f'
include 'packgrid.f'
include 'unpackmsg.f'
include 'unpacktext.f'
include 'unpackcall.f'
include 'unpackgrid.f'
include 'deg2grid.f'
include 'chkmsg.f'
include 'getpfx1.f'
include 'getpfx2.f'
include 'k2grid.f'
include 'grid2k.f'
include 'interleave63.f'
include 'graycode.f'
include 'set.f'

View File

@ -1,126 +0,0 @@
CC ?= @CC@
FFLAGS = @FFLAGS@
LDFLAGS = @LDFLAGS@
CPPFLAGS = @CPPFLAGS@
CFLAGS = @CFLAGS@
CFLAGS += -DBIGSYM
# WSJT specific Fortran flags
#FFLAGS += -Wall -fbounds-check -cpp -fno-second-underscore
FFLAGS = -O2 -cpp -w -fno-second-underscore
OS=@OS@
G95=@G95@
COMPILER=@G95_LIB_PATH@
FC=@G95@
LDFLAGS += -L${COMPILER}
LDFLAGS += -lg2c
PYTHON ?= @PYTHON@
RM ?= @RM@
F2PY = @F2PY@
F2PY_PY = "f2py.py"
%.o : %.f90
$(FC) -c $(FFLAGS) $< -o $@
OBJS1 = JT65code.o nchar.o grid2deg.o packmsg.o packtext.o \
packcall.o packgrid.o unpackmsg.o unpacktext.o unpackcall.o \
unpackgrid.o deg2grid.o packdxcc.o chkmsg.o getpfx1.o \
getpfx2.o k2grid.o grid2k.o interleave63.o graycode.o set.o \
igray.o init_rs.o encode_rs.o decode_rs.o \
wrapkarn.o
F2PYONLY = ftn_init ftn_quit audio_init spec getfile azdist0 astro0
SRCS2F90 = a2d.f90 abc441.f90 astro0.f90 audio_init.f90 azdist0.f90 \
blanker.f90 decode1.f90 decode2.f90 decode3.f90 ftn_init.f90 \
ftn_quit.f90 get_fname.f90 getfile.f90 horizspec.f90 hscroll.f90 \
i1tor4.f90 pix2d.f90 pix2d65.f90 rfile.f90 savedata.f90 spec.f90 \
wsjtgen.f90 runqqq.f90 fivehz.f90
OBJS2F90 = a2d.o abc441.o astro0.o audio_init.o azdist0.o \
blanker.o decode1.o decode2.o decode3.o ftn_init.o \
ftn_quit.o get_fname.o getfile.o horizspec.o hscroll.o \
i1tor4.o pix2d.o pix2d65.o rfile.o savedata.o spec.o \
wsjtgen.o runqqq.o fivehz.o
SRCS2F77 = wsjt1.f astro.f astropak.f \
avesp2.f bzap.f spec441.f spec2d.f mtdecode.f stdecode.f \
indexx.f s2shape.f flat2.f gen65.f chkmsg.f gen6m.f gentone.f \
syncf0.f syncf1.f synct.f decode6m.f avemsg6m.f \
set.f flatten.f db.f pctile.f sort.f ssort.f ps.f smooth.f \
ping.f longx.f peakup.f sync.f detect.f avemsg65.f decode65.f \
demod64a.f encode65.f extract.f flat1.f four2.f rfile2.f \
gencw.f getpfx1.f getpfx2.f getsnr.f graycode.f grid2k.f \
interleave63.f k2grid.f limit.f lpf1.f deep65.f morse.f \
nchar.f packcall.f packgrid.f packmsg.f packtext.f setup65.f \
short65.f slope.f spec2d65.f sync65.f unpackcall.f \
unpackgrid.f unpackmsg.f unpacktext.f xcor.f xfft.f wsjt65.f
OBJS2F77 = wsjt1.o astro.o astropak.o \
avesp2.o bzap.o spec441.o spec2d.o mtdecode.o stdecode.o \
indexx.o s2shape.o flat2.o gen65.o chkmsg.o gen6m.o gentone.o \
syncf0.o syncf1.o synct.o decode6m.o avemsg6m.o \
set.o flatten.o db.o pctile.o sort.o ssort.o ps.o smooth.o \
ping.o longx.o peakup.o sync.o detect.o avemsg65.o decode65.o \
demod64a.o encode65.o extract.o flat1.o four2.o rfile2.o \
gencw.o getpfx1.o getpfx2.o getsnr.o graycode.o grid2k.o \
interleave63.o k2grid.o limit.o lpf1.o deep65.o morse.o \
nchar.o packcall.o packgrid.o packmsg.o packtext.o setup65.o \
short65.o slope.o spec2d65.o sync65.o unpackcall.o \
unpackgrid.o unpackmsg.o unpacktext.o xcor.o xfft.o wsjt65.o
#OBJS2F90 = a2d.o abc441.o astro0.o audio_init.o azdist0.o \
# blanker.o decode1.o decode2.o decode3.o ftn_init.o \
# ftn_quit.o get_fname.o getfile.o horizspec.o hscroll.o \
# i1tor4.o pix2d.o pix2d65.o rfile.o savedata.o spec.o \
# wsjtgen.o runqqq.o fivehz.o
#
# ok, so far for now
# Windows @AUDIO@ will be jtaudio.c since it uses portaudio
# for *nix @AUDIO@ will also be jtaudio.c and start_threads.c
# for portaudio
# for *nix @AUDIO@ will be start_threads.c for alsa
# for *nix @AUDIO@ will be ?? for oss
#
# ptt_unix.c vs. ptt.c I'll sort out later.
# ditto for cutil.c (only used on *nix)
# --db
# jtaudio.c/start_threads.c mess will have to be sorted out later
# to minimise #ifdef's
# --db
#
OBJS2C = init_rs.o encode_rs.o decode_rs.o
SRCS3C = ptt_unix.c igray.c wrapkarn.c cutil.c
SRCS3C += @AUDIO@
all: JT65code wsjt6
JT65code: $(OBJS1)
$(FC) -o JT65code $(OBJS1)
wsjt6: Audio.so #wsjt.spec
# ${PYTHON} c:\python23\installer\Build.py wsjt.spec
# ${RM} wsjt6
Audio.so: $(OBJS2C) $(OBJS2F77) $(SRCS2F90) ${SRCS3C}
${PYTHON} ${F2PY_PY} -c --quiet --opt="-O -cpp -D${CFLAGS} \
-fno-second-underscore" $(OBJS2C) $(OBJS2F77) -m Audio \
--f77exec=${G95} --f90exec=${G95} ${CPPFLAGS} ${LDFLAGS} \
only: $(F2PYONLY) : \
$(SRCS2F90) \
${SRCS3C}
wsjt.spec: wsjt.py astro.py g.py options.py palettes.py smeter.py specjt.py
# ${PYTHON} c:\python23\installer\makespec.py --icon wsjt.ico \
# --tk --onefile wsjt.py
four2.o: four2.f
$(FC) -c -O2 four2.f
.PHONY : clean
clean:
${RM} -f *.o *.so JT65code wsjt6

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +0,0 @@
[Setup]
AppName=WSJT
AppVerName=WSJT Version 5.9.2 r77
AppCopyright=Copyright (C) 2001-2005 by Joe Taylor, K1JT
DefaultDirName={pf}\WSJT6
DefaultGroupName=WSJT6
[Files]
Source: "c:\k1jt\svn\wsjt\release-5.9.2\WSJT6.EXE"; DestDir: "{app}"
Source: "c:\k1jt\svn\wsjt\release-5.9.2\README_592.TXT"; DestDir: "{app}"
Source: "c:\k1jt\svn\wsjt\release-5.9.2\CALL3.TXT"; DestDir: "{app}"; Flags: onlyifdoesntexist
Source: "c:\k1jt\svn\wsjt\release-5.9.2\wsjt.ico"; DestDir: "{app}"; Flags: onlyifdoesntexist
Source: "c:\k1jt\svn\wsjt\release-5.9.2\TSKY.DAT"; DestDir: "{app}"; Flags: onlyifdoesntexist
Source: "c:\k1jt\svn\wsjt\release-5.9.2\libsamplerate.dll"; DestDir: "{app}"; Flags: onlyifdoesntexist
Source: "c:\k1jt\svn\wsjt\release-5.9.2\kvasd.exe"; DestDir: "{app}";
Source: "c:\k1jt\svn\wsjt\release-5.9.2\wsjtrc.win"; DestDir: "{app}";
Source: "c:\k1jt\svn\wsjt\release-5.9.2\Tutorial_592.txt"; DestDir: "{app}";
Source: "c:\k1jt\python\wsjt\rxwav\samples\W8WN_010809_110400.WAV"; DestDir: "{app}\RxWav\Samples\"; Flags: onlyifdoesntexist
[Icons]
Name: "{group}\WSJT6"; Filename: "{app}\WSJT6.EXE"; WorkingDir: {app}
Name: "{userdesktop}\WSJT6"; Filename: "{app}\WSJT6.EXE"; WorkingDir: {app}

View File

@ -1,283 +0,0 @@
WSJT DEVELOPMENT OVERVIEW
-------------------------
1 Introduction
----------------------------------------------------------------------
WSJT is a computer program designed to facilitate Amateur Radio
communication under extreme weak-signal conditions. Three very
different coding and modulation methods are provided: one for
communication by "meteor scatter" techniques on the VHF bands; one for
meteor and ionospheric scatter, primarily on the 6 meter band; and one
for the very challenging EME (Earth-Moon-Earth) path.
2 Program Overview
----------------------------------------------------------------------
WSJT's user interface is written in Python. The major Python
source-code files include:
1. wsjt.py Defines the main-screen GUI for user interactions;
acts as "traffic cop" for orchestrating all
event-driven and time-shared activities.
2. specjt.py Provides real-time display of received signals as
two-dimensional "waterfall" spectra.
3. options.py Provides entry fields for user-defined parameters.
4. astro.py Displays astronomical data for sun, moon, sky
temperature, etc.
Smaller Python files serve various utility purposes.
Both wsjt.py and specjt.py make calls to external procedures compiled
from Fortran and C. A variety of global data is shared among modules
through common blocks defined in Fortran. The Python code runs in a
single thread, although timers make the functions of the several main
modules appear concurrent. Fortran routines create additional threads
to be used for soundcard I/O and the decoding of received messages.
As a small part of its overall task, the decoder for JT65 invokes an
external program named KVASD.EXE or KVASD, located in the main
WSJT directory. If this program is present it uses information on
received 64-FSK symbols and attempts to decipher it according to a
Reed Solomon (63,12) code, using the algebraic soft-decision algorithm
of Koetter and Vardy. If KVASD is not present, WSJT uses its own
internal hard-decision Reed Solomon decoder instead. Interprocess
communication between WSJT and KVASD takes place through a shared disk
file. KVASD is not an integral part of WSJT. Its algorithm is
patented, and the source code is the property of CodeVector
Technologies, LLC. However, compiled versions of KVASD may be freely
used in conjunction with WSJT for the purposes of amateur radio
weak-signal communication.
3 Some Functional Details
----------------------------------------------------------------------
WSJT execution starts at the top of Python file wsjt.py. The
other Python modules are loaded and executed as needed. Fortran
routines are called to start a high-priority thread to handle
continuous A/D and D/A streams, and a background thread to decode
received or previously recorded signals. The top-level Python
code determines the overall state of program operation, e.g.,
Idle, Monitoring, or Transmitting. In normal usage the operator
puts the program into Auto mode, resulting in a timed sequence of
alternating transmission and reception intervals.
4 Other Open-Source Software used in WSJT
----------------------------------------------------------------------
WSJT 5.9 uses the following open source libraries:
1. FFTW, by Matteo Frigo and Steven Johnson, for computing Fourier
transforms
2. PortAudio, by Ross Bencina and Phil Burk, for audio I/O
3. "Secret Rabbit Code" or "libsamplerate", by Erik de Castro, for
accomplishing band-limited resampling of data
4. RS, by Phil Karn, KA9Q, for Reed Solomon encoding and
hard-decision decoding.
5 Platform-Dependent Notes
----------------------------------------------------------------------
The Python code should run on any supported Python platform. Most of
the remaining code can be compiled for Linux, FreeBSD, unix, or OS/X,
as well as Windows. Platform-dependent versions of FFTW, PortAudio,
and libsamplerate may need to be installed.
Methods are provided for creating additional threads and setting their
runtime priorities in Windows, Linux, and FreeBSD.
6 Partial List of Functions and Subroutines, and their purposes
----------------------------------------------------------------------
Routines for audio startup, decoding, display computations
blanker.f90 Noise blanker
fivehz.f90 Called by PortAudio callback
flat2.f Flatten the spectrum for waterfall display
pix2d65.f90 Computes pixels for waterfall display
pix2d.f90 Computes pixels for waterfall display
runqqq.f90 Executes another process
wsjtgen.f90 Generates Tx waveforms
abc441.f90 Part of FSK441 generator
gen65.f Generate JT65 waveform
chkmsg.f Check a JT65 message for presence of 'OOO'
encode65.f Encode a JT65 message
getpfx1.f Handle extra DXCC prefixes
getpfx2.f ...
graycode.f Convert binary to/from Gray code
nchar.f Convert number, letter, space to 0-36
packcall.f Routines for JT65 source encoding
packdxcc.f ...
packgrid.f ...
packmsg.f ...
packtext.f ...
pfx.f ...
gen6m.f Generate JT6M waveform
gentone.f Generate tone for JT6M message
gencw.f Generate CW waveform
morse.f Convert ascii to morse dits
gencwid.f Generate a CW ID message
grid2k.f Convert grid locator to integer
interleave63.f Interleave JT65 symbols
gcom1.f90 Global commons for sharing data among Fortran routines
gcom2.f90 and between Fortran and Python
gcom3.f90
gcom4.f90
makedate.f90 Gererates makedate_sub.f90
Astronomical calculations:
astro.f Computes Az, El, Doppler for Sun, Moon, etc.
astropak.f "Includes" for astro supoport routines
azdist.f Computes azimuth, distance, etc., between two locators
coord.f Spherical trig utility
dcoord.f Spherical trig utility in double precision
deg2grid.f Convert lat/long (degrees) to grid locator
dot.f Compute dot product
ftsky.f Get sky temperature from data file
geocentric.f Convert geodetic to geocentric coords
GeoDist.f Compute azimuth and distance between two locators
grid2deg.f Convert grid locator to lat/long
moon2.f Compute moon location at specified date and time
MoonDop.f Compute lunar doppler shift and related quantities
sun.f Compure sun location at specified date and time
toxyz.f Convert between polar and cartesian coords
Utilities:
db.f Compute decibels from ratio
gasdev.f Generate Gaussian random numbers
igray.f Gray code
indexx.f Sort routine
set.f Move, add, zero, ...
pctile.f Sort an array and get specified percentile
ran1.f Uniform random numbers
rfile2.f Read a binary file (Linux)
sort.f Sort an array
FFTs:
fftw3.f Fortran definitions for FFTW
four2a.f Wrapper to make FFTW look like four2
four2.f FFT in Fortran (a;ternative to using FFTW)
ps.f Compute power spectrum
xfft.f Real to complex FFT wrapper
Routines for Decoding:
wsjt1.f Top-level decoding routine; handles FSK441 especially
avesp2.f Computes average spectrum
bzap.f Find and remove birdies
detect.f Measure power in FSK441 tones
flatten.f Flatten the spectrum
longx.f Decode normal FSK441 messages
lpf1.f Quick-and-dirty lowpass filter
mtdecode.f Multi-tone decoding
ping.f Find pings
s2shape.f Flatten the 2d spectrum
smooth.f Smooth by boxcar averaging
spec2d.f Compute 2d spectrum for FSK441
stdecode.f Decode FSK441 shorthand messages
sync.f Synchronize FSK441 data
wsjt65.f JT65 decoder
afc65.f AFC for JT65
avemsg65.f Decode average message
decode65.f Decode JT65 message
deep65.f Deep search decoder
demod64a.f Compute probabilities of transmitted symbols
extract.f Extract message from JT65 symbol probabilities
flat1.f Flatten the passband
getsnr.f Compute snr or shorthand message
k2grid.f Convert integer to 4-digit grid locator
limit.f Clipper for JT65
peakup.f Interpolate to find fractional-bin peak
setup65.f Initialize pseudorandom sync vector
short65.f Detect JT65 shorthand messages
slope.f Remove a straight-line slope
spec2d65.f Compute 2d spectrum for JT65
spec441.f Compute spectra for FSK441 decoding
sync65.f Synchronize a JT65 signal
unpackcall.f Unpack JT65 message parts ...
unpackgrid.f ...
unpackmsg.f ...
unpacktext.f ...
xcor.f Compute cross-correlation for JT65 sync
decode6m.f Decode JT65 signal
syncf0.f First frequency sync
syncf1.f Second freq sync
synct.f First time sync
avemsg6m.f Get average JT65 message
JT65code.f Program to illustrate and test JT65 coding
Hard-Decision Reed Solomon Codec
decode_rs.c Decoder
encode_rs.c Encoder
init_rs.c Initialization routine
wrapkarn.c Wapper for Fortran
cutil.c Fortran wrappers for some basic C functions
jtaudio.c Audio I/O, calls PortAudio routines
padevsub.c Select desired audio device
ptt.c PTT via serial port DTR/RTS
ptt_linux.c Ditto for Linux (dummy at present)
resample.c Wrapper for resample routine
start_threads.c Start audio and decoder threads
7 Compiling Instructions
----------------------------------------------------------------------
Scripts are provided for compiling WSJT in both Windows and Linux.
They are presently set up to use Compaq Visual Fortran (v6.6) and
Microsoft C (v6.0) in Windows, and g95 and gcc in Linux. My
installation has Python 2.3. Additional tools include f2py, which
compiles Fortran and C to make Python extensions; the Python Imaging
Library; Numeric Python; and the SciPy distribution utilities.
Linux Windows Function
-------------------------------------------------------------------
g0 g0.bat Compiles the hard-decision Reed Solomon Decoder
Needs to be done only once.
g1 g1.bat Compiles the remaining Fortran and C to produce Python
extension module audio.pyd (Windows) or audio.so
(Linux).
g2 g2.bat Uses McMillan Installer to create an f2py specification
file, wsjt.spec
g3 g3.bat Uses Installer to produce a distributable file WSJT6.EXE
(Windows).
g99 g99.bat Runs all of the g[0-3] scripts.
These steps produce a distributable file WSJT6.EXE (Windows) or wsjt6
(Linux) that contains all necessary software components, so that the
end user does not need to install Python or any of its other
extensions, or the compilers.
A configuration script and Makefile facility is also provided.
Assuming that all of the pre-requisites are properly installed, WSJT
can now be compiled in Windows as follows:
C> copy Makefile.win Makefile
C> nmake
In Linux or FreeBSD, do the following:
$ ./configure --enable-portaudio (or --enable-alsa or --enable-oss)
$ make
8 Present status (January 17, 2006)
----------------------------------------------------------------------
WSJT version 5.9.2 (built from SVN revision 115) has been released for
Windows. It is is fully functional in Linux and BSD, as well, but
presently need to be compiled locally. In due course we plan to
provide distributions for standard *nix distributions.

Binary file not shown.

View File

@ -1,30 +0,0 @@
subroutine abc441(msg,nmsg,itone,ndits)
character msg*28
integer itone(84)
integer lookup(0:91)
character cc*43
data cc/' 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ.,?/#$'/
data lookup/13, 15, 17, 46, 47, 45, 44, 12, 11, 14, &
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, &
16, 48, 18, 19, 20, 21, 22, 23, 24, 25, &
26, 27, 15, 29, 30, 14, 16, 42, 46, 35, &
36, 37, 21, 0, 11, 41, 10, 13, 43, 1, &
2, 3, 4, 5, 6, 7, 8, 9, 49, 56, &
52, 55, 54, 12, 63, 17, 18, 19, 20, 44, &
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, &
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, &
45, 63/
save
do i=1,nmsg
n=ichar(msg(i:i))
if(n.lt.0 .or. n.gt.91) n=32 !Replace illegal char with blank
n=lookup(n)
itone(3*i-2)=n/16 + 1
itone(3*i-1)=mod(n/4,4) + 1
itone(3*i)=mod(n,4) + 1
enddo
ndits=3*nmsg
return
end subroutine abc441

View File

@ -1,110 +0,0 @@
subroutine avemsg6m(s2db,nz,nslim,NFixLen,cfile6,lcum,
+ f0,lumsg,npkept)
C Attempts to find message length and then decodes an average message.
real s2db(0:43,nz)
real s2dc(0:43,22)
real wgt(22)
real acf(0:430)
logical lcum
character*43 pua
character*6 cfile6
character*22 avemsg,blanks
data pua/'0123456789., /#?$ABCDEFGHIJKLMNOPQRSTUVWXYZ'/
data blanks/' '/
data twopi/6.283185307/
data offset/20.6/
C Adjustable sig limit, depending on length of data to average.
nslim2=nslim - 9 + 4.0*log10(624.0/nz) !### +10 was here
k=0
sum=0.
nsum=0
do j=1,nz
if(mod(j,3).eq.1) then
sum=sum+s2db(0,j) !Measure avg sig strength for sync tone
nsum=nsum+1
else
k=k+1
call move(s2db(0,j),s2db(0,k),44) !Save data spectra
endif
enddo
sig=sum/nsum !Signal strength estimate
nsig=nint(db(sig)-offset)
C Most of the time in this routine is in this loop.
kz=k
do lag=0,kz-1
sum=0.
do j=1,kz-lag
do i=0,43
sum=sum+s2db(i,j)*s2db(i,j+lag)
enddo
enddo
acf(lag)=sum
enddo
acf0=acf(0)
do lag=0,kz-1
acf(lag)=acf(lag)/acf0
enddo
lmsg1=NFixLen/256
lmsg2=NFixLen-256*lmsg1
if(mod(lmsg1,2).eq.1) lmsg1=lmsg1+1
if(mod(lmsg2,2).eq.1) lmsg2=lmsg2+1
smax=-1.e9
do ip=4,22,2 !Compute periodogram for allowed msg periods
if(NFixLen.ne.0 .and. ip.ne.4 .and. ip.ne.lmsg1
+ .and. ip.ne.lmsg2) go to 5
f=1.0/ip
s=0.
do lag=0,kz-1
s=s+acf(lag)*cos(twopi*f*lag)
enddo
if(s.gt.smax) then
smax=s
msglen=ip !Save best message length
endif
5 enddo
C Average the symbols from s2db into s2dc.
call zero(s2dc,44*22)
call zero(wgt,22)
do j=1,kz
k=mod(j-1,msglen)+1
call add(s2db(0,j),s2dc(0,k),s2dc(0,k),44)
wgt(k)=wgt(k)+1.0
enddo
do j=1,msglen !Hard-decode the avg msg,
smax=-1.e9 !picking max bin for each char
do i=1,43
s2dc(i,j)=s2dc(i,j)/wgt(j)
if(s2dc(i,j).gt.smax) then
smax=s2dc(i,j)
ipk=i
endif
enddo
k=mod(ipk,3)
i=ipk
avemsg(j:j)=pua(i:i)
enddo
ndf0=nint(f0-1076.66)
do i=1,msglen
if(avemsg(i:i).eq.' ') goto 10
enddo
go to 20
10 avemsg=avemsg(i+1:msglen)//avemsg(1:i)
20 if(nsig.gt.nslim2) then
npkept=npkept+1
avemsg=avemsg(1:msglen)//blanks
write(lumsg,1020) cfile6,nsig,ndf0,avemsg,msglen
if(lcum) write(21,1020) cfile6,nsig,ndf0,avemsg,msglen
1020 format(a6,8x,i6,i5,7x,a22,19x,'*',i4)
endif
return
end

View File

@ -1,18 +0,0 @@
subroutine blanker(d2d,jz)
integer*2 d2d(jz)
avg=700.
threshold=5.0
do i=1,jz
xmag=abs(d2d(i))
xmed=0.75*xmed + 0.25*d2d(i)
avg=0.999*avg + 0.001*xmag
if(xmag.gt.threshold*avg) then
! d2d(i)=nint(xmed)
d2d(i)=0
endif
enddo
return
end subroutine blanker

View File

@ -37,8 +37,6 @@ subroutine decode3(d2,jz,istart,filename)
d2d(i)=d2(i) d2d(i)=d2(i)
enddo enddo
if(nblank.ne.0) call blanker(d2d,jz)
nseg=1 nseg=1
if(mode(1:4).eq.'JT65') then if(mode(1:4).eq.'JT65') then
i=index(FileID,'.')-3 i=index(FileID,'.')-3
@ -78,23 +76,7 @@ subroutine decode3(d2,jz,istart,filename)
nclearave=0 nclearave=0
nagain=0 nagain=0
if(mode(1:4).eq.'JT65') then
call pix2d65(d2d,jz) call pix2d65(d2d,jz)
else if(mode.eq.'FSK441') then
nz=s2(1,1)
call pix2d(d2d,jz,mousebutton,MouseDF,NFreeze,mode,s2,64,nz,b)
else if(mode(1:4).eq.'JT6M' .and. mousebutton.eq.0) then
nz=s2(1,1)
call pix2d(d2d,jz,mousebutton,MouseDF,NFreeze,mode,s2,64,nz,b)
endif
! Compute red and magenta cutves for small plot area, FSK441/JT6M only
if(mode.eq.'FSK441' .or. mode.eq.'JT6M') then
do i=1,128
if(mode.eq.'FSK441' .and. ps0(i).gt.0.0) ps0(i)=10.0*log10(ps0(i))
if(psavg(i).gt.0.0) psavg(i)=10.0*log10(psavg(i))
enddo
endif
999 return 999 return
end subroutine decode3 end subroutine decode3

View File

@ -1,159 +0,0 @@
subroutine decode6m(data,jz,cfile6,MinSigdB,istart,
+ NFixLen,lcum,f0,lumsg,npkept,yellow)
C Decode a JT6M message. Data must start at the beginning of a
C sync symbol; sync frequency is assumed to be f0.
parameter (NMAX=30*11025)
real data(jz) !Raw data
real s2db(0:43,646) !Spectra of symbols
c real s2(128,646)
real syncsig(646)
real yellow(216)
real ref(0:43)
logical lcum
character*43 pua
character*48 msg
character*6 cfile6
real*8 dpha,twopi
complex*16 z,dz
complex zz
complex ct(0:511)
complex c
common/hcom/c(NMAX)
data pua/'0123456789., /#?$ABCDEFGHIJKLMNOPQRSTUVWXYZ'/
data offset/20.6/
ps(zz)=real(zz)**2 + aimag(zz)**2 !Power spectrum function
C Convert data to baseband (complex result) using quadrature LO.
twopi=8*atan(1.d0)
dpha=twopi*f0/11025.d0
dz=cmplx(cos(dpha),-sin(dpha))
z=1.d0/dz
do i=1,jz
z=z*dz
c(i)=data(i)*z
enddo
C Get spectrum for each symbol.
C NB: for decoding pings, could do FFTs first for sync intervals only,
C and then for data symbols only where the sync amplitude is above
C threshold. However, for the average message we want all FFTs computed.
call zero(ref,44)
nz=jz/512 - 1
fac=1.0/512.0
do j=1,nz
i0=512*(j-1) + 1
do i=0,511
ct(i)=fac*c(i0+i)
enddo
call four2a(ct,512,1,-1,1)
C Save PS for each symbol
do i=0,127
xps=ps(ct(i))
if(i.le.43) s2db(i,j)=xps
c s2(i+1,j)=xps
enddo
if(mod(j,3).eq.1) call add(ref,s2db(0,j),ref,44) !Accumulate ref spec
enddo
C Return sync-tone amplitudes for plotting.
iz=nz/3 -1
do i=1,iz
j=3*i-2
yellow(i)=s2db(0,j)-0.5*(s2db(0,j+1)+s2db(0,j+2))
enddo
yellow(216)=iz
fac=3.0/nz
do i=0,43 !Normalize the ref spectrum
ref(i)=fac*ref(i)
enddo
ref(0)=ref(2) !Sync bin uses bin 2 as ref
do j=1,nz !Compute strength of sync
m=mod(j-1,3) !signal at each j.
ja=j-m-3
jb=ja+3
if(ja.lt.1) ja=ja+3
if(jb.gt.nz) jb=jb-3
syncsig(j)=0.5*(s2db(0,ja)+s2db(0,jb))/ref(0)
syncsig(j)=db(syncsig(j)) - offset
do i=0,43 !Normalize s2db
s2db(i,j)=s2db(i,j)/ref(i)
enddo
enddo
C Decode any message of 2 or more consecutive characters bracketed by
C sync-tones above a threshold.
C Use hard-decoding (i.e., pick max bin).
nslim=MinSigdB !Signal limit for decoding
ndf0=nint(f0-1076.77) !Freq offset DF, in Hz
n=0 !Number of decoded characters
j0=0
sbest=-1.e9
do j=2,nz-1,3
if(syncsig(j).ge.float(nslim)) then
C Is it time to write out the results?
if((n.eq.48) .or. (j.ne.j0+3 .and. j0.ne.0)) then
nsig=nint(sbest)
width=(512./11025.)*(1.5*n+1.0)
if(nsig.ge.nslim) then
npkept=npkept+1
write(lumsg,1010) cfile6,tping,width,
+ nsig,ndf0,(msg(k:k),k=1,n)
if(lcum) write(21,1010) cfile6,tping,width,
+ nsig,ndf0,(msg(k:k),k=1,n)
1010 format(a6,2f5.1,i4,i5,6x,48a1) !### 6x was 7x ###
endif
n=0
sbest=-1.e9
endif
j0=j
smax1=-1.e9
do i=1,43 !Pick max bin for 1st char
if(s2db(i,j).gt.smax1) then
smax1=s2db(i,j)
ipk=i
endif
enddo
n=n+1
if(n.eq.1) tping=j*512./11025. + (istart-1)/11025.0 !Start of ping
msg(n:n)=pua(ipk:ipk) !Decoded character
smax2=-1.e9
do i=1,43
if(s2db(i,j+1).gt.smax2) then
smax2=s2db(i,j+1)
ipk=i
endif
enddo
n=n+1
msg(n:n)=pua(ipk:ipk)
sig0=10.0**(0.1*(syncsig(j)+offset))
sig=db(0.5*sig0 + 0.25*(smax1+smax2))-offset
sbest=max(sbest,sig)
endif
enddo
nsig=nint(sbest)
width=(512./11025.)*(1.5*n+1.0)
if(n.ne.0 .and. nsig.ge.nslim) then
npkept=npkept+1
write(lumsg,1010) cfile6,tping,
+ width,nsig,ndf0,(msg(k:k),k=1,n)
if(lcum) write(21,1010) cfile6,tping,
+ width,nsig,ndf0,(msg(k:k),k=1,n)
endif
C Decode average message for the whole record.
call avemsg6m(s2db,nz,nslim,NFixLen,cfile6,lcum,f0,lumsg,npkept)
return
end

3
g0
View File

@ -1,3 +0,0 @@
gcc -c -DBIGSYM=1 init_rs.c
gcc -c -DBIGSYM=1 encode_rs.c
gcc -c -DBIGSYM=1 decode_rs.c

5
g1
View File

@ -1,5 +0,0 @@
G95=/usr/local/bin/g95
COMPILER=//usr/local/lib/gcc-lib/i386-unknown-freebsd5.4/4.0.1/
python f2py.py -c --quiet --opt="-O -cpp -DFreeBSD -fno-second-underscore" init_rs.o encode_rs.o decode_rs.o -m Audio --f77exec=$G95 --f90exec=$G95 -L$COMPILER -lpthread -lg2c only: ftn_init ftn_quit audio_init spec getfile azdist0 astro0 : a2d.f90 abc441.f90 astro0.f90 audio_init.f90 azdist0.f90 blanker.f90 decode1.f90 decode2.f90 decode3.f90 ftn_init.f90 ftn_quit.f90 get_fname.f90 getfile.f90 horizspec.f90 hscroll.f90 i1tor4.f90 pix2d.f90 pix2d65.f90 rfile.f90 savedata.f90 spec.f90 wsjtgen.f90 runqqq.f90 wsjt1.f fsubs1.f fsubs.f astro.f astropak.f jtaudio.c ptt_bsd.c igray.c wrapkarn.c start_threads.c cutil.c fivehz.f90

4
g99
View File

@ -1,4 +0,0 @@
g0
g1
g2
g3

49
gen6m.f
View File

@ -1,49 +0,0 @@
subroutine gen6m(msg,samfac,iwave,nwave)
C Encodes a message into a wavefile for transmitting JT6M signals.
parameter (NMAX=21504) !NMAX=28*512*3/2: number of waveform samples
character*28 msg !Message to be generated
real*8 samfac
real*4 x(NMAX) !Data for wavefile
integer*2 iwave(NMAX) !Generated wave file
integer*4 imsg(28)
do i=27,1,-1 !Get message length
if(msg(i:i).ne.' ') go to 10
enddo
i=1
10 nmsg=i+1
if(mod(nmsg,2).eq.1) nmsg=nmsg+1 !Make it even
nwave=nmsg*512*3/2
do m=1,nmsg !Get character code numbers
ic=m
n=ichar(msg(ic:ic))
C Calculate i in range 0-42:
if(n.ge.ichar('0') .and. n.le.ichar('9')) i=n-ichar('0')
if(msg(ic:ic).eq.'.') i=10
if(msg(ic:ic).eq.',') i=11
if(msg(ic:ic).eq.' ') i=12
if(msg(ic:ic).eq.'/') i=13
if(msg(ic:ic).eq.'#') i=14
if(msg(ic:ic).eq.'?') i=15
if(msg(ic:ic).eq.'$') i=16
if(n.ge.ichar('a') .and. n.le.ichar('z')) i=n-ichar('a')+17
if(n.ge.ichar('A') .and. n.le.ichar('Z')) i=n-ichar('A')+17
imsg(m)=i
enddo
k=1
do i=1,nmsg,2
call gentone(x(k),-1,k) !Generate a sync tone
call gentone(x(k),imsg(i),k) !First character
call gentone(x(k),imsg(i+1),k) !Second character
enddo
do i=1,nwave
iwave(i)=nint(32767.0*x(i))
enddo
return
end

92
glpr
View File

@ -1,92 +0,0 @@
lpr astro.f
lpr Audio.f90
lpr avemsg65.f
lpr avemsg6m.f
lpr avesp2.f
lpr azdist.f
lpr bzap.f
lpr chkmsg.f
lpr coord.f
lpr db.f
lpr dcoord.f
lpr decode65.f
lpr decode6m.f
lpr deep65.f
lpr deg2grid.f
lpr demod64a.f
lpr detect.f
lpr dot.f
lpr encode65.f
lpr extract.f
lpr fivehz.f90
lpr flat1.f
lpr flat2.f
lpr flatten.f
lpr four2a.f
lpr fsubs1.f
lpr fsubs.f
lpr ftsky.f
lpr gasdev.f
lpr gen65.f
lpr gen6m.f
lpr gencw.f
lpr gentone.f
lpr geocentric.f
lpr geodist.f
lpr getpfx1.f
lpr getpfx2.f
lpr getsnr.f
lpr graycode.f
lpr grid2deg.f
lpr grid2k.f
lpr igray.f
lpr indexx.f
lpr interleave63.f
lpr jtaudio.c
lpr k2grid.f
lpr limit.f
lpr longx.f
lpr lpf1.f
lpr moon2.f
lpr MoonDop.f
lpr morse.f
lpr mtdecode.f
lpr nchar.f
lpr packcall.f
lpr packgrid.f
lpr packmsg.f
lpr packtext.f
lpr pctile.f
lpr peakup.f
lpr ping.f
lpr ps.f
lpr ptt.c
lpr ran1.f
lpr resample.c
lpr s2shape.f
lpr set.f
lpr setup65.f
lpr short65.f
lpr slope.f
lpr smooth.f
lpr sort.f
lpr spec2d65.f
lpr spec2d.f
lpr spec441.f
lpr stdecode.f
lpr sun.f
lpr sync65.f
lpr sync.f
lpr syncf0.f
lpr syncf1.f
lpr synct.f
lpr toxyz.f
lpr unpackcall.f
lpr unpackgrid.f
lpr unpackmsg.f
lpr unpacktext.f
lpr wrapkarn.c
lpr wsjt1.f
lpr wsjt65.f
lpr xcor.f
lpr xfft.f

3
go
View File

@ -1,3 +0,0 @@
gcc -c wrapkarn.c
gcc -c igray.c
f77 -o JT65code -fno-second-underscore JT65code_all.f igray.o wrapkarn.o init_rs.o encode_rs.o decode_rs.o

View File

@ -1,88 +0,0 @@
!------------------------------------------------------ horizspec
subroutine horizspec(x,brightness,contrast,a)
real x(4096)
integer brightness,contrast
integer*2 a(750,300)
real y(512),ss(128)
complex c(0:256)
equivalence (y,c)
include 'gcom1.f90'
include 'gcom2.f90'
save
nfft=512
nq=nfft/4
gain=50.0 * 3.0**(0.36+0.01*contrast)
offset=0.5*(brightness+30.0)
df=11025.0/512.0
if(ntr.ne.ntr0) then
if(lauto.eq.0 .or. ntr.eq.TxFirst) then
call hscroll(a,nx)
nx=0
endif
ntr0=ntr
endif
i0=0
do iter=1,5
if(nx.lt.750) nx=nx+1
do i=1,nfft
y(i)=1.4*x(i+i0)
enddo
call xfft2(y,nfft)
nq=nfft/4
do i=1,nq
ss(i)=real(c(i))**2 + aimag(c(i))**2
enddo
p=0.
do i=21,120
p=p+ss(i)
n=0
if(ss(i).gt.0.) n=gain*log10(0.05*ss(i)) + offset
n=min(252,max(0,n))
j=121-i
a(nx,j)=n
enddo
if(nx.eq.7 .or. nx.eq.378 .or. nx.eq.750) then
! Put in yellow ticks at the standard tone frequencies for FSK441, or
! at the sync-tone frequency for JT65, JT6M.
do i=nx-4,nx
if(mode.eq.'FSK441') then
do n=2,5
j=121-nint(n*441/df)
a(i,j)=254
enddo
else if(mode(1:4).eq.'JT65') then
j=121-nint(1270.46/df)
a(i,j)=254
else if(mode.eq.'JT6M') then
j=121-nint(1076.66/df)
a(i,j)=254
endif
enddo
endif
ng=140 - 30*log10(0.00033*p+0.001)
ng=min(ng,150)
if(nx.eq.1) ng0=ng
if(abs(ng-ng0).le.1) then
a(nx,ng)=255
else
ist=1
if(ng.lt.ng0) ist=-1
jmid=(ng+ng0)/2
i=max(1,nx-1)
do j=ng0+ist,ng,ist
a(i,j)=255
if(j.eq.jmid) i=i+1
enddo
ng0=ng
endif
i0=i0+441
enddo
return
end subroutine horizspec

View File

@ -1,14 +0,0 @@
!------------------------------------------------- hscroll
subroutine hscroll(a,nx)
integer*2 a(750,300)
do j=1,150
do i=1,750
if(nx.gt.50) a(i,150+j)=a(i,j)
a(i,j)=0
enddo
enddo
return
end subroutine hscroll

128
longx.f
View File

@ -1,128 +0,0 @@
subroutine longx(dat,npts0,ps,DFTolerance,noffset,
+ msg,msglen,bauderr)
C Look for 441-baud modulation, synchronize to it, and decode message.
C Longest allowed data analysis is 1 second.
parameter (NMAX=11025)
parameter (NDMAX=NMAX/25)
real dat(npts0)
real ps(128),psmo(20)
integer DFTolerance
real y1(NMAX)
real y2(NMAX)
real y3(NMAX)
real y4(NMAX)
real wgt(-2:2)
integer dit(NDMAX)
integer n4(0:2)
character msg*40
character c*48
common/acom/a1,a2,a3,a4
data c/' 123456789.,?/# $ABCD FGHIJKLMNOPQRSTUVWXY 0EZ '/
data wgt/1.0,4.0,6.0,4.0,1.0/
NSPD=25 !Change if FSK110 is implemented
LTone=2
NBaud=11025/NSPD
npts=min(NMAX,npts0)
df=11025.0/256.0
smax=0.
C Find the frequency offset of this ping.
C NB: this might be improved by including a bandpass correction to ps.
ia=nint((LTone*NBaud-DFTolerance)/df)
ib=nint((LTone*NBaud+DFTolerance)/df)
do i=ia,ib !Search for correct DF
sum=0.
do j=1,4 !Sum over the 4 tones
m=nint((i*df+(j-1)*NBaud)/df)
do k=-2,2 !Weighted averages over 5 bins
sum=sum+wgt(k)*ps(m+k)
enddo
enddo
k=i-ia+1
psmo(k)=sum
kpk=0
if(sum.gt.smax) then
smax=sum
noffset=nint(i*df-LTone*NBaud)
kpk=k
endif
enddo
if(kpk.gt.1 .and. kpk.lt.20) then
call peakup(psmo(kpk-1),psmo(kpk),psmo(kpk+1),dx)
noffset=nint(noffset+dx*df)
endif
C Do square-law detection in each of four filters.
f1=LTone*NBaud+noffset
f2=(LTone+1)*NBaud+noffset
f3=(LTone+2)*NBaud+noffset
f4=(LTone+3)*NBaud+noffset
call detect(dat,npts,f1,y1)
call detect(dat,npts,f2,y2)
call detect(dat,npts,f3,y3)
call detect(dat,npts,f4,y4)
C Bandpass correction:
npts=npts-(NSPD-1)
do i=1,npts
y1(i)=y1(i)*a1
y2(i)=y2(i)*a2
y3(i)=y3(i)*a3
y4(i)=y4(i)*a4
enddo
call sync(y1,y2,y3,y4,npts,jpk,baud,bauderr)
C Decimate y arrays by NSPD
ndits=npts/NSPD - 1
do i=1,ndits
y1(i)=y1(jpk+(i-1)*NSPD)
y2(i)=y2(jpk+(i-1)*NSPD)
y3(i)=y3(jpk+(i-1)*NSPD)
y4(i)=y4(jpk+(i-1)*NSPD)
enddo
C Now find the mod3 phase that has no tone 3's
n4(0)=0
n4(1)=0
n4(2)=0
do i=1,ndits
ymax=max(y1(i),y2(i),y3(i),y4(i))
if(y1(i).eq.ymax) dit(i)=0
if(y2(i).eq.ymax) dit(i)=1
if(y3(i).eq.ymax) dit(i)=2
if(y4(i).eq.ymax) then
dit(i)=3
k=mod(i,3)
n4(k)=n4(k)+1
endif
enddo
n4min=min(n4(0),n4(1),n4(2))
if(n4min.eq.n4(0)) jsync=3
if(n4min.eq.n4(1)) jsync=1
if(n4min.eq.n4(2)) jsync=2
C Might want to notify if n4min>0 or if one of the others is equal
C to n4min. In both cases, could then decode 2 or 3 times, using
C other starting phases.
C Finally, decode the message.
msg=' '
msglen=ndits/3
msglen=min(msglen,40)
do i=1,msglen
j=(i-1)*3+jsync
nc=16*dit(j) + 4*dit(j+1) +dit(j+2)
msg(i:i)=' '
if(nc.le.47) msg(i:i)=c(nc+1:nc+1)
enddo
return
end

View File

@ -1,144 +0,0 @@
subroutine mtdecode(dat,jz,nz,MinSigdB,MinWidth,
+ NQRN,DFTolerance,istart,pick,cfile6,ps0)
C Decode Multi-Tone FSK441 mesages.
real dat(jz) !Raw audio data
integer NQRN
integer DFTolerance
logical pick
character*6 cfile6,cf*1
real sigdb(3100) !Detected signal in dB, sampled at 20 ms
real work(3100)
integer indx(3100)
real pingdat(3,100)
real ps(128)
real ps0(128)
character msg*40,msg3*3
character*90 line
common/ccom/nline,tping(100),line(100)
slim=MinSigdB
wmin=0.001*MinWidth * (19.95/20.0)
nf1=-DFTolerance
nf2=DFTolerance
msg3=' '
dt=1.0/11025.0
C Find signal power at suitable intervals to search for pings.
istep=221
dtbuf=istep/11025.
do n=1,nz
s=0.
ib=n*istep
ia=ib-istep+1
do i=ia,ib
s=s+dat(i)**2
enddo
sigdb(n)=s/istep
enddo
!#####################################################################
if(.not.pick) then
! Remove initial transient from sigdb
call indexx(nz,sigdb,indx)
imax=0
do i=1,50
if(indx(i).gt.50) go to 10
imax=max(imax,indx(i))
enddo
10 do i=1,50
if(indx(nz+1-i).gt.50) go to 20
imax=max(imax,indx(nz+1-i))
enddo
20 imax=imax+6 !Safety margin
base1=sigdb(indx(nz/2))
do i=1,imax
sigdb(i)=base1
enddo
endif
!##################################################################
call smooth(sigdb,nz)
C Remove baseline and one dB for good measure.
call pctile (sigdb,work,nz,50,base1)
do i=1,nz
sigdb(i)=dB(sigdb(i)/base1) - 1.0
enddo
call ping(sigdb,nz,dtbuf,slim,wmin,pingdat,nping)
C If this is a "mouse pick" and no ping was found, force a pseudo-ping
C at center of data.
if(pick.and.nping.eq.0) then
if(nping.le.99) nping=nping+1
pingdat(1,nping)=0.5*jz*dt
pingdat(2,nping)=0.16
pingdat(3,nping)=1.0
endif
bigpeak=0.
do iping=1,nping
C Find starting place and length of data to be analyzed:
tstart=pingdat(1,iping)
width=pingdat(2,iping)
peak=pingdat(3,iping)
mswidth=10*nint(100.0*width)
jj=(tstart-0.02)/dt
if(jj.lt.1) jj=1
jjz=nint((width+0.02)/dt)+1
jjz=min(jjz,jz+1-jj)
C Compute average spectrum of this ping.
call spec441(dat(jj),jjz,ps,f0)
C Decode the message.
msg=' '
call longx(dat(jj),jjz,ps,DFTolerance,noffset,msg,
+ msglen,bauderr)
qrnlimit=4.4*1.5**(5.0-NQRN)
if(NQRN.eq.0) qrnlimit=99.
if(msglen.eq.0) go to 100
C Assemble a signal report:
nwidth=0
if(width.ge.0.04) nwidth=1 !These might depend on NSPD
if(width.ge.0.12) nwidth=2
if(width.gt.1.00) nwidth=3
nstrength=6
if(peak.ge.11.0) nstrength=7
if(peak.ge.17.0) nstrength=8
if(peak.ge.23.0) nstrength=9
! if(peak.gt.5.0 .and.mswidth.ge.100) then
! call specsq(dat(jj),jjz,DFTolerance,0,noffset2)
! noffset=noffset2
! endif
C Discard this ping if DF outside tolerance limits or bauderr too big.
C (However, if the ping was mouse-picked, proceed anyway.)
if(.not.pick .and. ((noffset.lt.nf1 .or. noffset.gt.nf2) .or.
+ (abs(bauderr).gt.qrnlimit))) goto 100
C If it's the best ping yet, save the spectrum:
if(peak.gt.bigpeak) then
bigpeak=peak
do i=1,128
ps0(i)=ps(i)
enddo
endif
tstart=tstart + dt*(istart-1)
cf=' '
if(nline.le.99) nline=nline+1
tping(nline)=tstart
write(line(nline),1050) cfile6,tstart,mswidth,int(peak),
+ nwidth,nstrength,noffset,msg3,msg,cf
1050 format(a6,f5.1,i5,i3,1x,2i1,i5,1x,a3,1x,a40,1x,a1)
100 enddo
return
end

136
pix2d.f90
View File

@ -1,136 +0,0 @@
subroutine pix2d(d2,jz,mousebutton,mousedf,nfreeze,mode,s2,nchan,nz,b)
! Compute pixels to represent the 2-d spectrum s2(nchan,nz), and the
! green line.
integer*2 d2(jz) !Raw input data
character*6 mode
real s2(nchan,nz) !2-d spectrum
integer*2 b(60000) !Pixels corresponding to 2-d spectrum
data nx0/0/
save
tbest=s2(2,1)
s2(1,1)=s2(3,1)
s2(2,1)=s2(3,1)
gain=100.
offset=0.0
if(mousebutton.eq.0) then
k=0
do i=54,7,-1
do j=1,nz
k=k+1
n=0
if(s2(i,j).gt.0) n=gain*log10(s2(i,j)) + offset
n=min(252,max(0,n))
b(k)=n
enddo
k=k+500-nz
enddo
do i=k+1,60000
b(i)=0
enddo
else
! This is a mouse-picked decode, so we compute the "zoomed" region.
k=50*500
do i=54,7,-1
do j=1,nz
k=k+1
n=0
if(s2(i,j).gt.0) n=gain*log10(s2(i,j)) + offset
n=min(252,max(0,n))
b(k)=n
enddo
k=k+500-nz
enddo
endif
if(mousebutton.eq.0) then
! Compute the green curve
sum=0.
do i=1,jz
sum=sum+d2(i)
enddo
nave=nint(sum/jz)
nadd=661
ngreen=min(jz/nadd,500)
k=0
j=0
do i=1,ngreen
sq=0.
do n=1,nadd
k=k+1
d2(k)=d2(k)-nave
x=d2(k)
sq=sq + x*x
enddo
x=0.0001*sq/nadd
j=j+1
x=120.0-40.0*log10(0.01*x)
if(x.lt.1.0) x=1.0
if(x.gt.119.) x=119.
ng=nint(x)
ng=min(ng,120)
nx=i
if(nx.eq.1) ng0=ng
if(abs(ng-ng0).le.1) then
b((ng-1)*500+nx)=255
else
ist=1
if(ng.lt.ng0) ist=-1
jmid=(ng+ng0)/2
ii=max(1,nx-1)
do j=ng0+ist,ng,ist
b((j-1)*500+ii)=255
if(j.eq.jmid) ii=ii+1
enddo
ng0=ng
endif
enddo
if(mode.eq.'FSK441') then
! Insert yellow tick marks at frequencies of the FSK441 tones
do i=2,5
f=441*i
ich=58-nint(f/43.066)
do j=1,5
b((ich-1)*500+j+2)=254
b((ich-1)*500+j+248)=254
b((ich-1)*500+j+495)=254
enddo
enddo
else if(mode.eq.'JT6M') then
! Insert yellow tick marks at frequencies of the JT6M sync tone
f=1076.66
ich=60-nint(f/43.066) !Why 58 for FSK441, above?
do j=1,5
b((ich-1)*500+j+2)=254
b((ich-1)*500+j+248)=254
b((ich-1)*500+j+495)=254
enddo
! Insert green tick at frequency indicated by MouseDF
if(NFreeze.gt.0) then
f=1076.66+mousedf
ich=60-nint(f/43.066) !Why 58 for FSK441, above?
do j=1,7
b((ich-1)*500+j+2)=255
enddo
endif
endif
! Mark the best ping with a red tick
if(tbest.gt.0.0) then
nx=tbest/0.060 + 1
do j=110,120
b((j-1)*500+nx0)=0
b((j-1)*500+nx)=253
enddo
nx0=nx
endif
endif
return
end subroutine pix2d

View File

@ -63,10 +63,6 @@ subroutine spec(brightness,contrast,logmap,ngain,nspeed,a)
npts=jzc/2048 npts=jzc/2048
npts=2048*npts npts=2048*npts
kread=0 kread=0
if(nspeed.ge.6) then
call hscroll(a,nx)
nx=0
endif
endif endif
if(npts.lt.0) npts=npts+nmax if(npts.lt.0) npts=npts+nmax
if(npts.lt.nfft) go to 900 !Not enough data available if(npts.lt.nfft) go to 900 !Not enough data available
@ -118,20 +114,6 @@ subroutine spec(brightness,contrast,logmap,ngain,nspeed,a)
endif endif
endif endif
if(nspeed.ge.6) then
call horizspec(x,brightness,contrast,a)
ncall=Mod(ncall+1,5)
if(ncall.eq.1 .or. nspeed.eq.7) newdat=1
if(ndiskdat.eq.1) then
npts=jzc-kread
else
npts=iwrite-iread
if(npts.lt.0) npts=npts+nmax
endif
if(npts.ge.4096) go to 10
go to 900
endif
call xfft2(x,nfft) call xfft2(x,nfft)
do i=1,nh !Accumulate power spectrum do i=1,nh !Accumulate power spectrum

128
spec2d.f
View File

@ -1,128 +0,0 @@
subroutine spec2d(data,jz,nstep,s2,nchan,nz,psavg0,sigma)
C Computes 2d spectrogram for FSK441 single-tone search and waterfall
C display.
parameter (NFFT=256)
parameter (NR=NFFT+2)
parameter (NH=NFFT/2)
parameter (NQ=NFFT/4)
real data(jz)
real s2(nchan,nz)
real x(NR)
real w1(7),w2(7)
real psavg(128)
real psavg0(128)
real ps2(128)
complex c(0:NH)
common/acom/a1,a2,a3,a4
common/fcom/s(3100),indx(3100)
equivalence (x,c)
save
df=11025.0/NFFT
C Compute the 2d spectrogram s2(nchan,nz). Note that in s2 the frequency
C bins are shifted down 5 bins from their natural positions.
call set(0.0,psavg,NH)
do n=1,nz
j=1 + (n-1)*nstep
call move(data(j),x,NFFT)
call xfft(x,NFFT)
sum=0.
do i=1,NQ
s2(i,n)=real(c(5+i))**2 + aimag(c(5+i))**2
sum=sum+s2(i,n)
enddo
s(n)=sum/NQ
C Accumulate average spectrum for the whole file.
do i=1,nh
psavg0(i) = psavg0(i)+ real(c(i))**2 + aimag(c(i))**2
enddo
enddo
C Normalize and save a copy of psavg0 for plotting. Roll off the
C spectrum at 300 and 3000 Hz.
do i=1,nh
psavg0(i)=3.e-5*psavg0(i)/nz
f=df*i
fac=1.0
if(f.lt.300.0) fac=f/300.0
if(f.gt.3000.0) fac=max(0.00333,(3300.0-f)/300.0)
psavg0(i)=(fac**2)*psavg0(i)
enddo
C Compute an average spectrum from the weakest 25% of time slices.
call indexx(nz,s,indx)
call zero(ps2,NQ)
do j=1,nz/4
k=indx(j)
do i=1,NQ
ps2(i+5)=ps2(i+5)+s2(i,k)
enddo
enddo
ps2(1)=ps2(5)
ps2(2)=ps2(5)
ps2(3)=ps2(5)
ps2(4)=ps2(5)
sum=0.
do i=6,59
sum=sum+ps2(i)
enddo
if(sum.eq.0.0) then
sigma=-999.
go to 999
endif
C Compute a smoothed spectrum without local peaks, and find its max.
smaxx=0.
do i=4,NQ
sum=0.
do k=1,7
w1(k)=ps2(i+k-4)
sum=sum+w1(k)
enddo
ave=sum/7.0
if(i.ge.14 .and. i.le.58) then
call pctile(w1,w2,7,50,base)
ave=0.25*(w2(1)+w2(2)+w2(3)+w2(4))
endif
psavg(i)=ave
smaxx=max(psavg(i),smaxx)
enddo
C Save scale factors for flattening spectra of pings.
a1=1.0
a2=psavg(nint(2*441/df))/psavg(nint(3*441/df))
a3=psavg(nint(2*441/df))/psavg(nint(4*441/df))
a4=psavg(nint(2*441/df))/psavg(nint(5*441/df))
afac=4.0/(a1+a2+a3+a4)
a1=afac*a1
a2=afac*a2
a3=afac*a3
a4=afac*a4
C Normalize 2D spectrum by the average based on weakest 25% of time
C slices, smoothed, and with local peaks removed.
do i=1,NQ
do j=1,nz
s2(i,j)=s2(i,j)/max(psavg(i+5),0.01*smaxx)
enddo
enddo
C Find average of active spectral region, over the whole file.
sum=0.
do i=9,52
do j=1,nz
sum=sum+s2(i,j)
enddo
enddo
sigma=sum/(44*nz)
999 return
end

View File

@ -1,37 +0,0 @@
subroutine spec441(dat,jz,s,f0)
C Computes average spectrum over a range of dat, e.g. for a ping.
C Returns spectral array and frequency of peak value.
parameter (NFFT=256)
parameter (NR=NFFT+2)
parameter (NH=NFFT/2)
real*4 dat(jz)
real*4 x(NR),s(NH)
complex c(0:NH)
equivalence (x,c)
call zero(s,NH)
nz=jz/NFFT
do n=1,nz
j=1 + (n-1)*NFFT
call move(dat(j),x,NFFT)
call xfft(x,NFFT)
do i=1,NH
s(i)=s(i)+real(c(i))**2 + aimag(c(i))**2
enddo
enddo
smax=0.
df=11025.0/NFFT
fac=1.0/(100.0*nfft*nz)
do i=1,nh
s(i)=fac*s(i)
if(s(i).gt.smax) then
smax=s(i)
f0=i*df
endif
enddo
return
end

View File

@ -1,56 +0,0 @@
subroutine syncf0(data,jz,NFreeze,NTol,jstart,f0,smax)
C Does 512-pt FFTs of data with 256-pt step size.
C Finds sync tone and determines aproximate values for jstart and f0.
real data(jz) !Raw data
real s2(128,6) !Average spectra at half-symbol spacings
real x(512)
complex cx(0:511)
complex z
equivalence (x,cx)
ps(z)=real(z)**2 + aimag(z)**2 !Power spectrum function
call zero(s2,6*128) !Clear average
df=11025./512.
ia=(f0-400)/df
ib=(f0+400)/df + 0.999
if(NFreeze.eq.1) then
ia=(f0-NTol)/df
ib=(f0+Ntol)/df + 0.999
endif
C Most of the time in this routine is in this loop.
nblk=jz/256 - 6
do n=1,nblk !Accumulate avg spectrum for
j=256*(n-1)+1 !512-pt blocks, stepping by 256
call move(data(j),x,512)
call xfft(x,512)
do i=ia,ib
x(i)=ps(cx(i))
enddo
k=mod(n-1,6)+1
call add(s2(ia,k),x(ia),s2(ia,k),ib-ia+1) !Average at each step
enddo
C Look for best spectral peak, using the "sync off" phases as reference.
smax=0.
do i=ia,ib
do k=1,6
k1=mod(k+1,6)+1
k2=mod(k+3,6)+1
r=0.5*(s2(i,k1)+s2(i,k2))
s=s2(i,k)/r
if(s.gt.smax) then
smax=s
jstart=(k-1)*256 + 1 !Best starting place for sync
f0=i*df !Best sync frequency
endif
enddo
enddo
return
end

117
syncf1.f
View File

@ -1,117 +0,0 @@
subroutine syncf1(data,jz,jstart,f0,NFreeze,DFTolerance,smax,red)
C Does 16k FFTs of data with stepsize 15360, using only "sync on" intervals.
C Returns a refined value of f0, the sync-tone frequency.
parameter (NFFT=16384)
parameter (NH=NFFT/2)
parameter (NQ=NFFT/4)
parameter (NB3=3*512)
real data(jz) !Raw data
integer DFTolerance
real x(NFFT)
real red(512)
real s(NQ) !Ref spectrum for flattening and birdie-zapping
complex c(0:NH)
complex z
equivalence (x,c)
ps(z)=real(z)**2 + aimag(z)**2 !Power spectrum ASF
C Accumulate a high-resolution average spectrum
df=11025.0/NFFT
jstep=10*NB3
nz=(jz-jstart)/jstep -1
call zero(s,NQ)
do n=1,nz
call zero(x,NFFT)
k=(n-1)*jstep
do i=1,10
j=(i-1)*NB3 + 1
call move(data(jstart+k+j),x(j),512)
enddo
call xfft(x,NFFT)
do i=1,NQ
x(i)=ps(c(i))
enddo
call add(s,x,s,NQ)
enddo
fac=(1.0/NFFT)**2
do i=1,NQ !Normalize
s(i)=fac*s(i)
enddo
call smooth(s,NQ)
C NB: could also compute a "blue" spectrum, using the sync-off intervals.
n8=NQ/8
do i=1,n8
red(i)=0.
do k=8*i-7,8*i
red(i)=red(i)+s(k)
enddo
red(i)=10.0*red(i)/(8.0*nz)
enddo
dftol=min(DFTolerance,25)
if(nfreeze.eq.1) dftol=DFTolerance
C Find improved value for f0
smax=0.
ia=(f0-dftol)/df
ib=(f0+dftol)/df + 0.999
! if(NFreeze.eq.1) then
! ia=(f0-5.)/df
! ib=(f0+5.)/df
! endif
do i=ia,ib
if(s(i).gt.smax) then
smax=s(i)
ipk=i
endif
enddo
f0=ipk*df
C Remove line at f0 from spectrum -- if it's strong enough.
ia=(f0-150)/df
ib=(f0+150)/df
a1=0.
a2=0.
nsum=50
do i=1,nsum
a1=a1+s(ia-i)
a2=a2+s(ib+i)
enddo
a1=a1/nsum
a2=a2/nsum
smax=2.0*smax/(a1+a2)
if(smax.gt.3.0) then
b=(a2-a1)/(ib-ia)
do i=ia,ib
s(i)=a1 + (i-ia)*b
enddo
endif
C Make a smoothed version of the spectrum.
nsum=50
fac=1./(2*nsum+1)
call zero(x,nsum)
call zero(s,50)
call zero(s(NQ-nsum),nsum)
sum=0.
do i=nsum+1,NQ-nsum
sum=sum+s(i+nsum)-s(i-nsum)
x(i)=fac*sum
enddo
call zero(x(NQ-nsum),nsum+1)
C To zap birdies, compare s(i) and x(i). If s(i) is larger by more
C than some limit, replace x(i) by s(i). That will put narrow birdies
C on top of the smoothed spectrum.
call move(x,s,NQ) !Copy smoothed spectrum into s
return
end

69
synct.f
View File

@ -1,69 +0,0 @@
subroutine synct(data,jz,jstart,f0,smax)
C Gets a refined value of jstart.
parameter (NMAX=30*11025)
parameter (NB3=3*512)
real data(jz)
real*8 dpha,twopi
complex*16 z,dz
complex c,c1,zz
common/hcom/c(NMAX)
ps(zz)=real(zz)**2 + aimag(zz)**2 !Power spectrum function
C Convert data to baseband (complex result) using quadrature LO.
twopi=8*atan(1.d0)
dpha=twopi*f0/11025.d0
dz=cmplx(cos(dpha),-sin(dpha))
z=1.d0/dz
do i=1,jz
z=z*dz
c(i)=data(i)*z
enddo
C Detect zero-beat sync tone in 512-sample chunks, stepped by 1.
C Sums replace original values in c(i).
zz=0
do i=1,512 !Compute first sum
zz=zz+c(i)
enddo
c1=c(1)
c(1)=zz
do i=2,jz-512 !Compute the rest recursively
zz=c(i-1)+c(i+511)-c1
c1=c(i) !Save original value
c(i)=zz !Save the sum
enddo
C Iterate to find the best jstart.
jstart=jstart+NB3
nz=(jz-jstart)/NB3 -1
smax=0.
jstep=256
jbest=jstart
10 jstep=jstep/2
jstart=jbest
do j=jstart-jstep,jstart+jstep,jstep
s=0.
r=0.
do n=1,nz
k=(n-1)*NB3 + j
s=s + ps(c(k))
r=r + ps(c(k+512)) + ps(c(k+1024))
enddo
s=2*s/r !Better to use s/r or s-r?
if(s.gt.smax) then
smax=s
jbest=j
endif
enddo
if(jstep.gt.1) go to 10
jstart=jbest
if(jstart.gt.NB3) jstart=jstart-NB3
return
end

110
wsjt1.F
View File

@ -197,116 +197,6 @@ C Intentionally degrade SNR by -nclip dB.
goto 900 goto 900
endif endif
! If we're in JT6M mode, call the 6M decoding routines.
if(mode.eq.4) then
do i=1,jz !### Why is it level-sensitive?
dat(i)=dat(i)/25.0
enddo
! For waterfall plot
call spec2d(dat,jz,nstep,s2,nchan,nz,psavg,sigma)
if(sigma.lt.0.0) basevb=-99.0
if(jz/11025.0.lt.3.9 .or. sigma.lt.0.0) go to 900
f0=1076.66
if(NFreeze.eq.1) f0=1076.66 + MouseDF
f00=f0
call syncf0(dat,jz,NFreeze,DFTolerance,jstart,f0,smax)
call synct(dat,jz,jstart,f0,smax)
call syncf1(dat,jz,jstart,f0,NFreeze,DFTolerance,smax,red)
do i=1,512
ccf(i-6)=dB(red(i))
enddo
df=11025./256.
do i=1,64
sum=0.
do k=8*i-7,8*i
sum=sum+red(k)
enddo
psavg(i)=5.0*sum
fac=1.0
freq=i*df
if(freq.gt.2500.0) fac=((freq-2500.)/20.0)**(-1.0)
psavg(i)=fac*psavg(i)
psavg(i+64)=0.001
enddo
jz=jz-jstart+1
nslim=MinSigdB
NFixLen=0
C Call the decoder if DF is in range or Freeze is off.
if(NFreeze.eq.0 .or.
+ abs(f0-f00).lt.float(DFTolerance)) then
call decode6m(dat(jstart),jz,cfile6,nslim,istart,
+ NFixLen,lcum,f0,lumsg,npkept,yellow)
endif
if(pick) then
do i=1,216
ps0(i)=yellow0(i)
enddo
else
ps0(216)=yellow(216)
yellow0(216)=yellow(216)
do i=1,215
ps0(i)=2*yellow(i)
yellow0(i)=ps0(i)
enddo
endif
goto 800
endif
! We're in FSK441 mode. Compute the 2D spectrum.
df=11025.0/256.0 !FFT resolution ~43 Hz
dtbuf=nstep/11025.0
stlim=nslim2 !Single-tone threshold
call spec2d(dat,jz,nstep,s2,nchan,nz,psavg,sigma)
if(sigma.lt.0.0) basevb=-99.0
if(sigma.lt.0.0) go to 900
nline0=nline
STfound=.false.
npkept=0
C Look for single-tone messages
if((.not.pick) .or. MouseButton.eq.1) then
call stdecode(s2,nchan,nz,sigma,dtbuf,df,stlim,
+ DFTolerance,cfile6,pick,istart)
endif
if(nline.gt.nline0) STfound=.true. !ST message(s) found
C Now the multi-tone decoding
call mtdecode(dat,jz,nz,MinSigdB,MinWidth,
+ NQRN,DFTolerance,istart,pick,cfile6,ps0)
npkept=nline !Number of pings that were kept
smax=0.
stbest=.false.
if(npkept.gt.0) then
call indexx(npkept,tping,indx) !Merge the ST and MT decodes
do i=1,npkept
j=indx(i)
if(pick .and. STFound .and.
+ line(j)(29:31).eq.' ') goto 10
write(lumsg,1050) line(j) !Write to decoded.txt
1050 format(a79)
if(lcum) write(21,1050) line(j) !Write to ALL.TXT
read(line(j),1060) sig,msg3
1060 format(16x,f3.0,9x,a3)
if(sig.gt.smax) then
smax=sig
tbest=tping(j)
stbest = (msg3.ne.' ')
endif
10 enddo
endif
dt=1.0/11025.0 !Compute spectrum for pink curve
if(stbest) then
jj=nint(tbest/dt)
call spec441(dat(jj),1102,ps0,f0)
endif
800 continue 800 continue
call s2shape(s2,nchan,nz,tbest) call s2shape(s2,nchan,nz,tbest)

View File

@ -117,7 +117,6 @@ subroutine wsjtgen
dt=1.d0/fsample_out dt=1.d0/fsample_out
LTone=2 LTone=2
if(mode(1:4).eq.'JT65') then
! We're in JT65 mode. ! We're in JT65 mode.
if(mode(5:5).eq.'A') mode65=1 if(mode(5:5).eq.'A') mode65=1
if(mode(5:5).eq.'B') mode65=2 if(mode(5:5).eq.'B') mode65=2
@ -142,96 +141,10 @@ subroutine wsjtgen
nwave=k nwave=k
endif endif
goto 900
endif
if(mode(1:4).eq.'Echo') then
! We're in Echo mode.
! dither=AmpA
! call echogen(dither,wavefile,nbytes,f1)
! AmpB=f1
goto 900
endif
if(mode(1:4).eq.'JT6M') then
! We're in JT6M mode.
call gen6m(msg,samfacout,iwave,nwave)
goto 900
endif
if(mode(1:2).eq.'CW') then
! We're in CW mode
wpm=15.
freqcw=800.
call gencw(msg,wpm,freqcw,samfacout,TRPeriod,iwave,nwave)
goto 900
endif
! We're in FSK441 mode.
if(nmsg.lt.28) nmsg=nmsg+1 !Add trailing blank if nmsg < 28
! Check for shorthand messages
sendingsh = 0
if(shok.eq.1 .and. nmsg.le.4) then
if (msg(1:3).eq.'R26') then
msg='++'
nmsg=2
sendingsh = 1
else if (msg(1:3).eq.'R27') then
msg='**'
nmsg=2
sendingsh = 1
else if (msg(1:3).eq.'RRR') then
msg='%%'
nmsg=2
sendingsh = 1
else if (msg(1:2).eq.'73') then
msg='@@'
nmsg=2
sendingsh = 1
endif
endif
! Encode the message
call abc441(msg,nmsg,itone,ndits)
ndata=ndits*nspd
! Generate iwave
k=0
df=11025.0/NSPD
do m=1,ndits
freq=(LTone-1+itone(m))*df
dpha=twopi*freq*dt
do i=1,NSPD
k=k+1
pha=pha+dpha
iwave(k)=nint(32767.0*sin(pha))
enddo
enddo
nwave=k
900 sending=txmsg 900 sending=txmsg
if(mode(1:4).eq.'JT65' .and. sendingsh.ne.1) sending=msgsent if(sendingsh.ne.1) sending=msgsent
nmsg=nmsg0 nmsg=nmsg0
if(lcwid .and. (mode.eq.'FSK441' .or. mode(1:4).eq.'JT6M')) then
! Generate and insert the CW ID.
wpm=25.
freqcw=440.
idmsg=MyCall//' '
call gencwid(idmsg,wpm,freqcw,samfacout,icwid,ncwid)
k=0
do i=ncwid+1,int(trperiod*fsample_out)
k=k+1
if(k.gt.nwave) k=k-nwave
iwave(i)=iwave(k)
enddo
do i=1,ncwid
iwave(i)=icwid(i)
enddo
nwave=trperiod*fsample_out
endif
999 return 999 return
end subroutine wsjtgen end subroutine wsjtgen