diff --git a/lib/ft8/foxgen.f90 b/lib/ft8/foxgen.f90 index 5a78b8f78..38c17285c 100644 --- a/lib/ft8/foxgen.f90 +++ b/lib/ft8/foxgen.f90 @@ -1,4 +1,4 @@ -subroutine foxgen(bSuperFox,data_dir) +subroutine foxgen(bSuperFox,fname) ! Called from MainWindow::foxTxSequencer() to generate the Tx waveform in ! FT8 Fox mode. The Tx message can contain up to 5 "slots", each carrying @@ -18,7 +18,7 @@ subroutine foxgen(bSuperFox,data_dir) parameter (NWAVE=(160+2)*134400*4) !the biggest waveform we generate (FST4-1800 at 48kHz) parameter (NFFT=614400,NH=NFFT/2) logical*1 bSuperFox - character*(*) data_dir + character*(*) fname character*40 cmsg character*37 msg,msgsent integer itone(79) @@ -33,12 +33,13 @@ subroutine foxgen(bSuperFox,data_dir) if(bSuperFox) then ! call foxgen2(nslots,cmsg,cmnd) - open(25,file=data_dir,status='unknown') + open(25,file=fname,status='unknown') + rewind(25) write(25,'(a40)') cmsg(1:nslots) close(25) return endif - + fstep=60.d0 dfreq=6.25d0 dt=1.d0/48000.d0 diff --git a/lib/superfox/Makefile b/lib/superfox/Makefile index 9a25fcda1..6727f9a4b 100644 --- a/lib/superfox/Makefile +++ b/lib/superfox/Makefile @@ -15,31 +15,13 @@ CFLAGS= -O9 -Wall %.o: %.F90 ${FC} ${FFLAGS} -c $< -all: rs_sf.a rstest +all: sfox_tx -OBJS1 = rstest.o ran1.o rs_sf.a -rstest: $(OBJS1) - $(FC) -o rstest $(OBJS1) rs_sf.a +OBJS1 = sfox_tx.o foxgen2.o sfox_assemble.o -OBJS2 = rs_125_49.o ran1.o get_crc14.o rs_sf.a -rs_125_49: $(OBJS2) - $(FC) -o rs_125_49 $(OBJS2) rs_sf.a - -rs_sf.a: init_rs_sf.o encode_rs_sf.o decode_rs_sf.o rs_sf.o - ar -crs rs_sf.a init_rs_sf.o encode_rs_sf.o decode_rs_sf.o rs_sf.o - -init_rs_sf.o: init_rs.c - gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^ -encode_rs_sf.o: encode_rs.c - gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^ -decode_rs_sf.o: decode_rs.c - gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^ - -encode_rs_8.o: encode_rs.c - gcc -DFIXED=1 $(CFLAGS) -c -o $@ $^ -decode_rs_8.o: decode_rs.c - gcc -DFIXED=1 $(CFLAGS) -c -o $@ $^ +sfox_tx: $(OBJS1) + $(FC) -o sfox_tx $(OBJS1) libwsjt_fort.a .PHONY : clean clean: - -rm -f *.o *.a *.exe + -rm -f *.o *.exe diff --git a/lib/superfox/foxgen2.f90 b/lib/superfox/foxgen2.f90 index 68bb28357..6878b2c59 100644 --- a/lib/superfox/foxgen2.f90 +++ b/lib/superfox/foxgen2.f90 @@ -4,7 +4,7 @@ subroutine foxgen2(nslots,cmsg,line) ! generate the waveform to be transmitted. We need to parse the old-style ! Fox messages and extract the necessary pieces. - use packjt77 +! use packjt77 character*120 line character*40 cmsg(5) !Old-style Fox messages are here character*37 msg @@ -76,3 +76,53 @@ subroutine foxgen2(nslots,cmsg,line) return end subroutine foxgen2 + +subroutine split77(msg,nwords,nw,w) + +! Convert msg to upper case; collapse multiple blanks; parse into words. + + character*37 msg + character*13 w(19) + character*1 c,c0 + character*6 bcall_1 + logical ok1 + integer nw(19) + + iz=len(trim(msg)) + j=0 + k=0 + n=0 + c0=' ' + w=' ' + do i=1,iz + if(ichar(msg(i:i)).eq.0) msg(i:i)=' ' + c=msg(i:i) !Single character + if(c.eq.' ' .and. c0.eq.' ') cycle !Skip leading/repeated blanks + if(c.ne.' ' .and. c0.eq.' ') then + k=k+1 !New word + n=0 + endif + j=j+1 !Index in msg + n=n+1 !Index in word + if(c.ge.'a' .and. c.le.'z') c=char(ichar(c)-32) !Force upper case + msg(j:j)=c + if(n.le.13) w(k)(n:n)=c !Copy character c into word + c0=c + enddo + iz=j !Message length + nwords=k !Number of words in msg + if(nwords.le.0) go to 900 + do i=1,nwords + nw(i)=len(trim(w(i))) + enddo + msg(iz+1:)=' ' + if(nwords.lt.3) go to 900 + call chkcall(w(3),bcall_1,ok1) + if(ok1 .and. w(1)(1:3).eq.'CQ ') then + w(1)='CQ_'//w(2)(1:10) !Make "CQ " into "CQ_" + w(2:12)=w(3:13) !Move all remaining words down by one + nwords=nwords-1 + endif + +900 return +end subroutine split77 diff --git a/lib/superfox/sfox_tx.f90 b/lib/superfox/sfox_tx.f90 index e5017dcf6..4f7c0ed90 100644 --- a/lib/superfox/sfox_tx.f90 +++ b/lib/superfox/sfox_tx.f90 @@ -1,23 +1,47 @@ program sfox_tx - character*120 fname - character*40 cmsg(5) - integer itone(151) +! Functioins of this program are required in order to create a SuperFox +! transmission. +! The present version goes through the following steps: +! 1. Read old-style Fox messages from file 'sfox_1.dat' in the WSJT-X +! writable data directory. +! 2. Parse up to NSlots=5 messages to extract MyCall, up to 10 Hound +! calls, and the report or RR73 to be sent to each Hound. +! 3. Assemble and encode a single SuperFox message to produce itone(1:151), +! the array of channel symbol values. +! 4. Write the contents of itone to file 'sfox_2.dat'. + + character*120 fname !Full path for sfox.dat + character*120 line !List of SuperFox message pieces + character*40 cmsg(5) !Old-style Fox messages + integer itone(151) !SuperFox channel-symbol values + + open(70,file='fort.70',status='unknown',position='append') call getarg(1,fname) open(25,file=trim(fname),status='unknown') do i=1,5 read(25,1000,end=10) cmsg(i) 1000 format(a40) -! write(*,1000) cmsg(i) + write(70,*) 'AAA',i,cmsg(i) enddo + i=6 -10 rewind(25) - do i=1,151 +10 close(25) + nslots=i-1 + write(70,*) 'BBB',nslots + call foxgen2(nslots,cmsg,line) + write(70,*) 'CCC ',trim(line) + + do i=1,151 !Dummy loop to populate itone during tests itone(i)=i-1 enddo + + i1=index(fname,'sfox_1.dat') + fname(i1:i1+9)='sfox_2.dat' + open(25,file=trim(fname),status='unknown') write(25,1100) itone -1100 format(20i4) +1100 format(20i4) close(25) end program sfox_tx diff --git a/lib/superfox/sfox_wave.f90 b/lib/superfox/sfox_wave.f90 index 2358ee113..e94d1efa0 100644 --- a/lib/superfox/sfox_wave.f90 +++ b/lib/superfox/sfox_wave.f90 @@ -1,5 +1,8 @@ subroutine sfox_wave(fname) - + +! Called by WSJT-X when it's time for SuperFox to transmit. Reads array +! itone(1:151) from disk file 'sfox_2.dat' in the writable data directory. + parameter (NWAVE=(160+2)*134400*4) !Max WSJT-X waveform (FST4-1800 at 48kHz) parameter (NN=151,NSPS=1024) character*(*) fname @@ -8,8 +11,8 @@ subroutine sfox_wave(fname) common/foxcom/wave(NWAVE) - open(25,file=trim(fname),status='unknown') - read(25,'(20i4)') itone + open(25,file=trim(fname),status='unknown',err=900) + read(25,'(20i4)',err=900,end=900) itone close(25) ! Generate the SuperFox waveform. @@ -22,7 +25,6 @@ subroutine sfox_wave(fname) k=0 do j=1,NN f=f0 + baud*mod(itone(j),128) - print*,'A',j,itone(j),f dphi=twopi*f*dt do ii=1,4*NSPS k=k+1 @@ -32,5 +34,7 @@ subroutine sfox_wave(fname) enddo enddo +900 continue + return end subroutine sfox_wave diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index b0afade69..c62d0dd93 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -4826,7 +4826,7 @@ void MainWindow::guiUpdate() QString foxCall=m_config.my_callsign() + " "; ::memcpy(foxcom_.mycall, foxCall.toLatin1(), sizeof foxcom_.mycall); //Copy Fox callsign into foxcom_ bool bSuperFox=m_config.superFox(); - auto fname {QDir::toNativeSeparators(m_config.writeable_data_dir().absoluteFilePath("sfox.dat")).toLocal8Bit()}; + auto fname {QDir::toNativeSeparators(m_config.writeable_data_dir().absoluteFilePath("sfox_1.dat")).toLocal8Bit()}; foxgen_(&bSuperFox, fname.constData(), (FCL)fname.size()); if(bSuperFox) sfox_tx(); } @@ -10303,7 +10303,7 @@ Transmit: QString foxCall=m_config.my_callsign() + " "; ::memcpy(foxcom_.mycall, foxCall.toLatin1(),sizeof foxcom_.mycall); //Copy Fox callsign into foxcom_ bool bSuperFox=m_config.superFox(); - auto fname {QDir::toNativeSeparators(m_config.writeable_data_dir().absoluteFilePath("sfox.dat")).toLocal8Bit()}; + auto fname {QDir::toNativeSeparators(m_config.writeable_data_dir().absoluteFilePath("sfox_1.dat")).toLocal8Bit()}; foxgen_(&bSuperFox, fname.constData(), (FCL)fname.size()); if(bSuperFox) sfox_tx(); m_tFoxTxSinceCQ++; @@ -10884,7 +10884,7 @@ void MainWindow::on_jt65Button_clicked() void MainWindow::sfox_tx() { // qint64 ms0 = QDateTime::currentMSecsSinceEpoch(); - auto fname {QDir::toNativeSeparators(m_config.writeable_data_dir().absoluteFilePath("sfox.dat")).toLocal8Bit()}; + auto fname {QDir::toNativeSeparators(m_config.writeable_data_dir().absoluteFilePath("sfox_1.dat")).toLocal8Bit()}; p2.start("sfox_tx", QStringList {fname}); p2.waitForFinished(); sfox_wave_(fname.constData(), (FCL)fname.size());