Many renames: QRA65 --> QRA64, QRA02 --> QRA64.

git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@6848 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Joe Taylor 2016-07-02 12:15:41 +00:00
parent 23e4f34612
commit 3016ccee01
17 changed files with 224 additions and 224 deletions

View File

@ -359,7 +359,7 @@ set (wsjt_FSRCS
lib/genmsk.f90 lib/genmsk.f90
lib/genmsk144.f90 lib/genmsk144.f90
lib/genmsk_short.f90 lib/genmsk_short.f90
lib/genqra65.f90 lib/genqra64.f90
lib/genwspr.f90 lib/genwspr.f90
lib/geodist.f90 lib/geodist.f90
lib/getlags.f90 lib/getlags.f90
@ -411,7 +411,7 @@ set (wsjt_FSRCS
lib/polyfit.f90 lib/polyfit.f90
lib/prog_args.f90 lib/prog_args.f90
lib/ps4.f90 lib/ps4.f90
lib/qra02.f90 lib/qra64a.f90
lib/readwav.f90 lib/readwav.f90
lib/rectify_msk.f90 lib/rectify_msk.f90
lib/refspectrum.f90 lib/refspectrum.f90
@ -484,8 +484,8 @@ set (ldpc_CSRCS
) )
set (qra_CSRCS set (qra_CSRCS
lib/qra/qra65/qra65.c lib/qra/qra64/qra64.c
lib/qra/qra65/qra65_subs.c lib/qra/qra64/qra64_subs.c
lib/qra/qracodes/npfwht.c lib/qra/qracodes/npfwht.c
lib/qra/qracodes/pdmath.c lib/qra/qracodes/pdmath.c
lib/qra/qracodes/qra12_63_64_irr_b.c lib/qra/qracodes/qra12_63_64_irr_b.c
@ -1017,8 +1017,8 @@ target_link_libraries (jt4sim wsjt_fort wsjt_cxx)
add_executable (jt65sim lib/jt65sim.f90 wsjtx.rc) add_executable (jt65sim lib/jt65sim.f90 wsjtx.rc)
target_link_libraries (jt65sim wsjt_fort wsjt_cxx) target_link_libraries (jt65sim wsjt_fort wsjt_cxx)
add_executable (qra65sim lib/qra/qra65/qra65sim.f90 wsjtx.rc) add_executable (qra64sim lib/qra/qra64/qra64sim.f90 wsjtx.rc)
target_link_libraries (qra65sim wsjt_fort wsjt_cxx) target_link_libraries (qra64sim wsjt_fort wsjt_cxx)
add_executable (jt9sim lib/jt9sim.f90 wsjtx.rc) add_executable (jt9sim lib/jt9sim.f90 wsjtx.rc)
target_link_libraries (jt9sim wsjt_fort wsjt_cxx) target_link_libraries (jt9sim wsjt_fort wsjt_cxx)
@ -1026,8 +1026,8 @@ target_link_libraries (jt9sim wsjt_fort wsjt_cxx)
add_executable (jt65code lib/jt65code.f90 wsjtx.rc) add_executable (jt65code lib/jt65code.f90 wsjtx.rc)
target_link_libraries (jt65code wsjt_fort wsjt_cxx) target_link_libraries (jt65code wsjt_fort wsjt_cxx)
add_executable (qra65code lib/qra65code.f90 wsjtx.rc) add_executable (qra64code lib/qra64code.f90 wsjtx.rc)
target_link_libraries (qra65code wsjt_fort wsjt_cxx) target_link_libraries (qra64code wsjt_fort wsjt_cxx)
add_executable (jt9code lib/jt9code.f90 wsjtx.rc) add_executable (jt9code lib/jt9code.f90 wsjtx.rc)
target_link_libraries (jt9code wsjt_fort wsjt_cxx) target_link_libraries (jt9code wsjt_fort wsjt_cxx)
@ -1193,7 +1193,7 @@ install (TARGETS udp_daemon message_aggregator
BUNDLE DESTINATION ${WSJT_BIN_DESTINATION} COMPONENT runtime BUNDLE DESTINATION ${WSJT_BIN_DESTINATION} COMPONENT runtime
) )
install (TARGETS jt9 jt65code qra65code jt9code jt4code wsprd install (TARGETS jt9 jt65code qra64code qra64sim jt9code jt4code wsprd
RUNTIME DESTINATION ${WSJT_BIN_DESTINATION} COMPONENT runtime RUNTIME DESTINATION ${WSJT_BIN_DESTINATION} COMPONENT runtime
BUNDLE DESTINATION ${WSJT_BIN_DESTINATION} COMPONENT runtime BUNDLE DESTINATION ${WSJT_BIN_DESTINATION} COMPONENT runtime
) )

View File

@ -48,7 +48,7 @@ public:
ISCAT, ISCAT,
JTMSK, JTMSK,
MSK144, MSK144,
QRA65, QRA64,
MODES_END_SENTINAL_AND_COUNT // this must be last MODES_END_SENTINAL_AND_COUNT // this must be last
}; };
Q_ENUM (Mode) Q_ENUM (Mode)

View File

@ -1,6 +1,6 @@
subroutine genqra65(msg0,ichk,msgsent,itone,itype) subroutine genqra64(msg0,ichk,msgsent,itone,itype)
! Encodes a QRA65 message to yield itone(1:84) ! Encodes a QRA64 message to yield itone(1:84)
use packjt use packjt
character*22 msg0 character*22 msg0
@ -37,7 +37,7 @@ subroutine genqra65(msg0,ichk,msgsent,itone,itype)
call packmsg(message,dgen,itype) !Pack message into 72 bits call packmsg(message,dgen,itype) !Pack message into 72 bits
call unpackmsg(dgen,msgsent) !Unpack to get message sent call unpackmsg(dgen,msgsent) !Unpack to get message sent
if(ichk.ne.0) go to 999 !Return if checking only if(ichk.ne.0) go to 999 !Return if checking only
call qra65_enc(dgen,sent) !Encode using QRA65 call qra64_enc(dgen,sent) !Encode using QRA64
itone(1:7)=icos7 !Insert 7x7 Costas array in 3 places itone(1:7)=icos7 !Insert 7x7 Costas array in 3 places
itone(8:39)=sent(1:32) itone(8:39)=sent(1:32)
@ -47,4 +47,4 @@ subroutine genqra65(msg0,ichk,msgsent,itone,itype)
endif endif
999 return 999 return
end subroutine genqra65 end subroutine genqra64

View File

@ -99,7 +99,7 @@ contains
if(nsubmode.ge.100) then if(nsubmode.ge.100) then
! This is QRA65 mode ! This is QRA65 mode
call qra02(dd,nf1,nf2,nfqso,ntol,mycall,sync,nsnr,dtx,nfreq,decoded,nft) call qra64a(dd,nf1,nf2,nfqso,ntol,mycall,sync,nsnr,dtx,nfreq,decoded,nft)
! if(sync.lt.12.8) go to 900 !### Temporary ### ! if(sync.lt.12.8) go to 900 !### Temporary ###
if (associated(this%callback)) then if (associated(this%callback)) then
ndrift=0 ndrift=0

View File

@ -0,0 +1,30 @@
FC = gfortran
CC = gcc
CFLAGS = -O2 -Wall -I. -D_WIN32
# Default rules
%.o: %.c
${CC} ${CFLAGS} -c $<
%.o: %.f
${FC} ${FFLAGS} -c $<
%.o: %.F
${FC} ${FFLAGS} -c $<
%.o: %.f90
${FC} ${FFLAGS} -c $<
%.o: %.F90
${FC} ${FFLAGS} -c $<
all: qra64.exe
OBJS1 = main.o qra64.o
qra64.exe: $(OBJS1)
${CC} -o qra64.exe $(OBJS1) ../qracodes/libqra64.a -lm
OBJS2 = qra64sim.o options.o wavhdr.o
qra64sim.exe: $(OBJS2)
${FC} -o qra64sim.exe $(OBJS2) ../qracodes/libqra64.a -lm
.PHONY : clean
clean:
$(RM) *.o qra64.exe qra64sim.exe

View File

@ -1,6 +1,6 @@
/* /*
main.c main.c
QRA65 mode encode/decode test QRA64 mode encode/decode test
(c) 2016 - Nico Palermo, IV3NWV (c) 2016 - Nico Palermo, IV3NWV
@ -13,7 +13,7 @@ encoding/decoding package based on Q-ary RA (Repeat and Accumulate) LDPC codes.
Files in this package: Files in this package:
main.c - this file main.c - this file
qra65.c/.h - qra65 mode encode/decoding functions qra64.c/.h - qra64 mode encode/decoding functions
../qracodes/normrnd.{c,h} - random gaussian number generator ../qracodes/normrnd.{c,h} - random gaussian number generator
../qracodes/npfwht.{c,h} - Fast Walsh-Hadamard Transforms ../qracodes/npfwht.{c,h} - Fast Walsh-Hadamard Transforms
@ -41,7 +41,7 @@ Files in this package:
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
The code used by the QRA65 mode is the code: QRA13_64_64_IRR_E: K=13 The code used by the QRA64 mode is the code: QRA13_64_64_IRR_E: K=13
N=64 Q=64 irregular QRA code (defined in qra13_64_64_irr_e.{h,c}). N=64 Q=64 irregular QRA code (defined in qra13_64_64_irr_e.{h,c}).
This code has been designed to include a CRC as the 13th information This code has been designed to include a CRC as the 13th information
@ -80,7 +80,7 @@ unsigned GetTickCount(void) {
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "qra65.h" #include "qra64.h"
#include "../qracodes/normrnd.h" // gaussian numbers generator #include "../qracodes/normrnd.h" // gaussian numbers generator
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -106,7 +106,7 @@ void printwordh(char *msg, int *x, int size)
printf("\n"); printf("\n");
} }
#define NSAMPLES (QRA65_N*QRA65_M) #define NSAMPLES (QRA64_N*QRA64_M)
static float rp[NSAMPLES]; static float rp[NSAMPLES];
static float rq[NSAMPLES]; static float rq[NSAMPLES];
@ -119,22 +119,22 @@ float *mfskchannel(int *x, int channel_type, float EbNodB)
/* /*
Simulate an MFSK channel, either AWGN or Rayleigh. Simulate an MFSK channel, either AWGN or Rayleigh.
x is a pointer to the transmitted codeword, an array of QRA65_N x is a pointer to the transmitted codeword, an array of QRA64_N
integers in the range 0..63. integers in the range 0..63.
Returns the received symbol energies (squared amplitudes) as an array of Returns the received symbol energies (squared amplitudes) as an array of
(QRA65_M*QRA65_N) floats. The first QRA65_M entries of this array are (QRA64_M*QRA64_N) floats. The first QRA64_M entries of this array are
the energies of the first symbol in the codeword. The second QRA65_M the energies of the first symbol in the codeword. The second QRA64_M
entries are those of the second symbol, and so on up to the last codeword entries are those of the second symbol, and so on up to the last codeword
symbol. symbol.
*/ */
const float No = 1.0f; // noise spectral density const float No = 1.0f; // noise spectral density
const float sigma = (float)sqrt(No/2.0f); // std dev of noise I/Q components const float sigma = (float)sqrt(No/2.0f); // std dev of noise I/Q components
const float sigmach = (float)sqrt(1/2.0f); // std dev of channel I/Q gains const float sigmach = (float)sqrt(1/2.0f); // std dev of channel I/Q gains
const float R = 1.0f*QRA65_K/QRA65_N; const float R = 1.0f*QRA64_K/QRA64_N;
float EbNo = (float)pow(10,EbNodB/10); float EbNo = (float)pow(10,EbNodB/10);
float EsNo = 1.0f*QRA65_m*R*EbNo; float EsNo = 1.0f*QRA64_m*R*EbNo;
float Es = EsNo*No; float Es = EsNo*No;
float A = (float)sqrt(Es); float A = (float)sqrt(Es);
int k; int k;
@ -143,15 +143,15 @@ symbol.
normrnd_s(rq,NSAMPLES,0,sigma); normrnd_s(rq,NSAMPLES,0,sigma);
if (channel_type == CHANNEL_AWGN) if (channel_type == CHANNEL_AWGN)
for (k=0;k<QRA65_N;k++) for (k=0;k<QRA64_N;k++)
rp[k*QRA65_M+x[k]]+=A; rp[k*QRA64_M+x[k]]+=A;
else else
if (channel_type == CHANNEL_RAYLEIGH) { if (channel_type == CHANNEL_RAYLEIGH) {
normrnd_s(chp,QRA65_N,0,sigmach); normrnd_s(chp,QRA64_N,0,sigmach);
normrnd_s(chq,QRA65_N,0,sigmach); normrnd_s(chq,QRA64_N,0,sigmach);
for (k=0;k<QRA65_N;k++) { for (k=0;k<QRA64_N;k++) {
rp[k*QRA65_M+x[k]]+=A*chp[k]; rp[k*QRA64_M+x[k]]+=A*chp[k];
rq[k*QRA65_M+x[k]]+=A*chq[k]; rq[k*QRA64_M+x[k]]+=A*chq[k];
} }
} }
else { else {
@ -224,57 +224,57 @@ by their recipients (with no retries) and -1 if any of them could not
be decoded be decoded
*/ */
int x[QRA65_K], xdec[QRA65_K]; int x[QRA64_K], xdec[QRA64_K];
int y[QRA65_N]; int y[QRA64_N];
float *rx; float *rx;
int rc; int rc;
// Each simulated station must use its own codec, since it might work with // Each simulated station must use its own codec, since it might work with
// different a-priori information. // different a-priori information.
qra65codec *codec_iv3nwv = qra65_init(mode,CALL_IV3NWV); // codec for IV3NWV qra64codec *codec_iv3nwv = qra64_init(mode,CALL_IV3NWV); // codec for IV3NWV
qra65codec *codec_k1jt = qra65_init(mode,CALL_K1JT); // codec for K1JT qra64codec *codec_k1jt = qra64_init(mode,CALL_K1JT); // codec for K1JT
// Step 1a: IV3NWV makes a CQ call (with no grid) // Step 1a: IV3NWV makes a CQ call (with no grid)
printf("IV3NWV tx: CQ IV3NWV\n"); printf("IV3NWV tx: CQ IV3NWV\n");
encodemsg_jt65(x,CALL_CQ,CALL_IV3NWV,GRID_BLANK); encodemsg_jt65(x,CALL_CQ,CALL_IV3NWV,GRID_BLANK);
qra65_encode(codec_iv3nwv, y, x); qra64_encode(codec_iv3nwv, y, x);
rx = mfskchannel(y,channel_type,EbNodB); rx = mfskchannel(y,channel_type,EbNodB);
// Step 1b: K1JT attempts to decode [? ? ?], [CQ/QRZ ? ?] or [CQ/QRZ ?] // Step 1b: K1JT attempts to decode [? ? ?], [CQ/QRZ ? ?] or [CQ/QRZ ?]
rc = qra65_decode(codec_k1jt, xdec,rx); rc = qra64_decode(codec_k1jt, xdec,rx);
if (rc>=0) { // decoded if (rc>=0) { // decoded
printf("K1JT rx: received with apcode=%d %s\n",rc, decode_type[rc]); printf("K1JT rx: received with apcode=%d %s\n",rc, decode_type[rc]);
// Step 2a: K1JT replies to IV3NWV (with no grid) // Step 2a: K1JT replies to IV3NWV (with no grid)
printf("K1JT tx: IV3NWV K1JT\n"); printf("K1JT tx: IV3NWV K1JT\n");
encodemsg_jt65(x,CALL_IV3NWV,CALL_K1JT, GRID_BLANK); encodemsg_jt65(x,CALL_IV3NWV,CALL_K1JT, GRID_BLANK);
qra65_encode(codec_k1jt, y, x); qra64_encode(codec_k1jt, y, x);
rx = mfskchannel(y,channel_type,EbNodB); rx = mfskchannel(y,channel_type,EbNodB);
// Step 2b: IV3NWV attempts to decode [? ? ?], [IV3NWV ? ?] or [IV3NWV ?] // Step 2b: IV3NWV attempts to decode [? ? ?], [IV3NWV ? ?] or [IV3NWV ?]
rc = qra65_decode(codec_iv3nwv, xdec,rx); rc = qra64_decode(codec_iv3nwv, xdec,rx);
if (rc>=0) { // decoded if (rc>=0) { // decoded
printf("IV3NWV rx: received with apcode=%d %s\n",rc, decode_type[rc]); printf("IV3NWV rx: received with apcode=%d %s\n",rc, decode_type[rc]);
// Step 3a: IV3NWV replies to K1JT with a 73 // Step 3a: IV3NWV replies to K1JT with a 73
printf("IV3NWV tx: K1JT IV3NWV 73\n"); printf("IV3NWV tx: K1JT IV3NWV 73\n");
encodemsg_jt65(x,CALL_K1JT,CALL_IV3NWV, GRID_73); encodemsg_jt65(x,CALL_K1JT,CALL_IV3NWV, GRID_73);
qra65_encode(codec_iv3nwv, y, x); qra64_encode(codec_iv3nwv, y, x);
rx = mfskchannel(y,channel_type,EbNodB); rx = mfskchannel(y,channel_type,EbNodB);
// Step 3b: K1JT attempts to decode [? ? ?] or [K1JT IV3NWV ?] // Step 3b: K1JT attempts to decode [? ? ?] or [K1JT IV3NWV ?]
rc = qra65_decode(codec_k1jt, xdec,rx); rc = qra64_decode(codec_k1jt, xdec,rx);
if (rc>=0) { // decoded if (rc>=0) { // decoded
printf("K1JT rx: received with apcode=%d %s\n",rc, decode_type[rc]); printf("K1JT rx: received with apcode=%d %s\n",rc, decode_type[rc]);
// Step 4a: K1JT replies to IV3NWV with a 73 // Step 4a: K1JT replies to IV3NWV with a 73
printf("K1JT tx: IV3NWV K1JT 73\n"); printf("K1JT tx: IV3NWV K1JT 73\n");
encodemsg_jt65(x,CALL_IV3NWV,CALL_K1JT, GRID_73); encodemsg_jt65(x,CALL_IV3NWV,CALL_K1JT, GRID_73);
qra65_encode(codec_k1jt, y, x); qra64_encode(codec_k1jt, y, x);
rx = mfskchannel(y,channel_type,EbNodB); rx = mfskchannel(y,channel_type,EbNodB);
// Step 4b: IV3NWV attempts to decode [? ? ?], [IV3NWV ? ?], or [IV3NWV ?] // Step 4b: IV3NWV attempts to decode [? ? ?], [IV3NWV ? ?], or [IV3NWV ?]
rc = qra65_decode(codec_iv3nwv, xdec,rx); rc = qra64_decode(codec_iv3nwv, xdec,rx);
if (rc>=0) { // decoded if (rc>=0) { // decoded
printf("IV3NWV rx: received with apcode=%d %s\n",rc, decode_type[rc]); printf("IV3NWV rx: received with apcode=%d %s\n",rc, decode_type[rc]);
return 0; return 0;
@ -297,7 +297,7 @@ If mode=QRA_NOAP, K1JT decoder attempts to decode only msgs of type [? ? ?].
If mode=QRA_AUTOP, K1JT decoder will attempt to decode also the msgs If mode=QRA_AUTOP, K1JT decoder will attempt to decode also the msgs
[K1JT IV3NWV] and [K1JT IV3NWV ?]. [K1JT IV3NWV] and [K1JT IV3NWV ?].
In the case a decode is successful the return code of the qra65_decode function In the case a decode is successful the return code of the qra64_decode function
indicates the amount of a-priori information required to decode the received indicates the amount of a-priori information required to decode the received
message according to this table: message according to this table:
@ -314,33 +314,33 @@ This test simulates the situation ntx times and reports how many times
a particular type decode among the above 6 cases succeded. a particular type decode among the above 6 cases succeded.
*/ */
int x[QRA65_K], xdec[QRA65_K]; int x[QRA64_K], xdec[QRA64_K];
int y[QRA65_N]; int y[QRA64_N];
float *rx; float *rx;
int rc,k; int rc,k;
int ndecok[6] = { 0, 0, 0, 0, 0, 0}; int ndecok[6] = { 0, 0, 0, 0, 0, 0};
int ntx = 100,ndec=0; int ntx = 100,ndec=0;
qra65codec *codec_iv3nwv = qra65_init(mode,CALL_IV3NWV); // codec for IV3NWV qra64codec *codec_iv3nwv = qra64_init(mode,CALL_IV3NWV); // codec for IV3NWV
qra65codec *codec_k1jt = qra65_init(mode,CALL_K1JT); // codec for K1JT qra64codec *codec_k1jt = qra64_init(mode,CALL_K1JT); // codec for K1JT
// This will enable K1JT's decoder to look for IV3NWV calls // This will enable K1JT's decoder to look for IV3NWV calls
encodemsg_jt65(x,CALL_IV3NWV,CALL_K1JT,GRID_BLANK); encodemsg_jt65(x,CALL_IV3NWV,CALL_K1JT,GRID_BLANK);
qra65_encode(codec_k1jt, y, x); qra64_encode(codec_k1jt, y, x);
printf("K1JT tx: IV3NWV K1JT\n"); printf("K1JT tx: IV3NWV K1JT\n");
// IV3NWV reply to K1JT // IV3NWV reply to K1JT
printf("IV3NWV tx: K1JT IV3NWV JN66\n"); printf("IV3NWV tx: K1JT IV3NWV JN66\n");
encodemsg_jt65(x,CALL_K1JT,CALL_IV3NWV,GRID_JN66); encodemsg_jt65(x,CALL_K1JT,CALL_IV3NWV,GRID_JN66);
qra65_encode(codec_iv3nwv, y, x); qra64_encode(codec_iv3nwv, y, x);
printf("Simulating decodes by K1JT up to AP56 ..."); printf("Simulating decodes by K1JT up to AP56 ...");
for (k=0;k<ntx;k++) { for (k=0;k<ntx;k++) {
printf("."); printf(".");
rx = mfskchannel(y,channel_type,EbNodB); rx = mfskchannel(y,channel_type,EbNodB);
rc = qra65_decode(codec_k1jt, xdec,rx); rc = qra64_decode(codec_k1jt, xdec,rx);
if (rc>=0) if (rc>=0)
ndecok[rc]++; ndecok[rc]++;
} }
@ -359,10 +359,10 @@ a particular type decode among the above 6 cases succeded.
void syntax(void) void syntax(void)
{ {
printf("\nQRA65 Mode Tests\n"); printf("\nQRA64 Mode Tests\n");
printf("2016, Nico Palermo - IV3NWV\n\n"); printf("2016, Nico Palermo - IV3NWV\n\n");
printf("---------------------------\n\n"); printf("---------------------------\n\n");
printf("Syntax: qra65 [-s<snrdb>] [-c<channel>] [-a<ap-type>] [-t<testtype>] [-h]\n"); printf("Syntax: qra64 [-s<snrdb>] [-c<channel>] [-a<ap-type>] [-t<testtype>] [-h]\n");
printf("Options: \n"); printf("Options: \n");
printf(" -s<snrdb> : set simulation SNR in 2500 Hz BW (default:-27.5 dB)\n"); printf(" -s<snrdb> : set simulation SNR in 2500 Hz BW (default:-27.5 dB)\n");
printf(" -c<channel> : set channel type 0=AWGN (default) 1=Rayleigh\n"); printf(" -c<channel> : set channel type 0=AWGN (default) 1=Rayleigh\n");

View File

@ -1,6 +1,6 @@
/* /*
qra65.c qra64.c
Encoding/decoding functions for the QRA65 mode Encoding/decoding functions for the QRA64 mode
(c) 2016 - Nico Palermo, IV3NWV (c) 2016 - Nico Palermo, IV3NWV
@ -36,24 +36,24 @@ resulting code is a (12,63) code
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
#include "qra65.h" #include "qra64.h"
#include "../qracodes/qracodes.h" #include "../qracodes/qracodes.h"
#include "../qracodes/qra13_64_64_irr_e.h" #include "../qracodes/qra13_64_64_irr_e.h"
#include "../qracodes/pdmath.h" #include "../qracodes/pdmath.h"
// Code parameters of the QRA65 mode // Code parameters of the QRA64 mode
#define QRA65_CODE qra_13_64_64_irr_e #define QRA64_CODE qra_13_64_64_irr_e
#define QRA65_NMSG 218 // Must much value indicated in QRA65_CODE.NMSG #define QRA64_NMSG 218 // Must much value indicated in QRA64_CODE.NMSG
#define QRA65_KC (QRA65_K+1) // Information symbols (crc included) #define QRA64_KC (QRA64_K+1) // Information symbols (crc included)
#define QRA65_NC (QRA65_N+1) // Codeword length (as defined in the code) #define QRA64_NC (QRA64_N+1) // Codeword length (as defined in the code)
#define QRA65_NITER 100 // max number of iterations per decode #define QRA64_NITER 100 // max number of iterations per decode
// static functions declarations ---------------------------------------------- // static functions declarations ----------------------------------------------
static int calc_crc6(const int *x, int sz); static int calc_crc6(const int *x, int sz);
static void ix_mask(float *dst, const float *src, const int *mask, static void ix_mask(float *dst, const float *src, const int *mask,
const int *x); const int *x);
static int qra65_do_decode(int *x, const float *pix, const int *ap_mask, static int qra64_do_decode(int *x, const float *pix, const int *ap_mask,
const int *ap_x); const int *ap_x);
// a-priori information masks for fields in JT65-like msgs -------------------- // a-priori information masks for fields in JT65-like msgs --------------------
@ -64,20 +64,20 @@ static int qra65_do_decode(int *x, const float *pix, const int *ap_mask,
#define MASK_GRIDBIT 0x8000 // b[15] is 1 for free text, 0 otherwise #define MASK_GRIDBIT 0x8000 // b[15] is 1 for free text, 0 otherwise
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
qra65codec *qra65_init(int flags, const int mycall) qra64codec *qra64_init(int flags, const int mycall)
{ {
// Eb/No value for which we optimize the decoder metric // Eb/No value for which we optimize the decoder metric
const float EbNodBMetric = 2.8f; const float EbNodBMetric = 2.8f;
const float EbNoMetric = (float)pow(10,EbNodBMetric/10); const float EbNoMetric = (float)pow(10,EbNodBMetric/10);
const float R = 1.0f*(QRA65_KC)/(QRA65_NC); const float R = 1.0f*(QRA64_KC)/(QRA64_NC);
qra65codec *pcodec = (qra65codec*)malloc(sizeof(qra65codec)); qra64codec *pcodec = (qra64codec*)malloc(sizeof(qra64codec));
if (!pcodec) if (!pcodec)
return 0; // can't allocate memory return 0; // can't allocate memory
pcodec->decEsNoMetric = 1.0f*QRA65_m*R*EbNoMetric; pcodec->decEsNoMetric = 1.0f*QRA64_m*R*EbNoMetric;
pcodec->apflags = flags; pcodec->apflags = flags;
if (flags!=QRA_AUTOAP) if (flags!=QRA_AUTOAP)
@ -107,20 +107,20 @@ qra65codec *qra65_init(int flags, const int mycall)
return pcodec; return pcodec;
} }
void qra65_encode(qra65codec *pcodec, int *y, const int *x) void qra64_encode(qra64codec *pcodec, int *y, const int *x)
{ {
int encx[QRA65_KC]; // encoder input buffer int encx[QRA64_KC]; // encoder input buffer
int ency[QRA65_NC]; // encoder output buffer int ency[QRA64_NC]; // encoder output buffer
int call1,call2,grid; int call1,call2,grid;
memcpy(encx,x,QRA65_K*sizeof(int)); // Copy input to encoder buffer memcpy(encx,x,QRA64_K*sizeof(int)); // Copy input to encoder buffer
encx[QRA65_K]=calc_crc6(encx,QRA65_K); // Compute and add crc symbol encx[QRA64_K]=calc_crc6(encx,QRA64_K); // Compute and add crc symbol
qra_encode(&QRA65_CODE, ency, encx); // encode msg+crc using given QRA code qra_encode(&QRA64_CODE, ency, encx); // encode msg+crc using given QRA code
// copy codeword to output puncturing the crc symbol // copy codeword to output puncturing the crc symbol
memcpy(y,ency,QRA65_K*sizeof(int)); // copy information symbols memcpy(y,ency,QRA64_K*sizeof(int)); // copy information symbols
memcpy(y+QRA65_K,ency+QRA65_KC,QRA65_C*sizeof(int)); // copy parity symbols memcpy(y+QRA64_K,ency+QRA64_KC,QRA64_C*sizeof(int)); // copy parity symbols
if (pcodec->apflags!=QRA_AUTOAP) if (pcodec->apflags!=QRA_AUTOAP)
return; return;
@ -149,59 +149,59 @@ void qra65_encode(qra65codec *pcodec, int *y, const int *x)
} }
} }
int qra65_decode(qra65codec *pcodec, int *x, const float *rxen) int qra64_decode(qra64codec *pcodec, int *x, const float *rxen)
{ {
int k; int k;
float *srctmp, *dsttmp; float *srctmp, *dsttmp;
float ix[QRA65_NC*QRA65_M]; // (depunctured) intrisic information float ix[QRA64_NC*QRA64_M]; // (depunctured) intrisic information
int rc; int rc;
if (QRA65_NMSG!=QRA65_CODE.NMSG) // sanity check if (QRA64_NMSG!=QRA64_CODE.NMSG) // sanity check
return -16; // QRA65_NMSG define is wrong return -16; // QRA64_NMSG define is wrong
// compute symbols intrinsic probabilities from received energy observations // compute symbols intrinsic probabilities from received energy observations
qra_mfskbesselmetric(ix, rxen, QRA65_m, QRA65_N,pcodec->decEsNoMetric); qra_mfskbesselmetric(ix, rxen, QRA64_m, QRA64_N,pcodec->decEsNoMetric);
// de-puncture observations adding a uniform distribution for the crc symbol // de-puncture observations adding a uniform distribution for the crc symbol
// move check symbols distributions one symbol towards the end // move check symbols distributions one symbol towards the end
dsttmp = PD_ROWADDR(ix,QRA65_M, QRA65_NC-1); //Point to last symbol prob dist dsttmp = PD_ROWADDR(ix,QRA64_M, QRA64_NC-1); //Point to last symbol prob dist
srctmp = dsttmp-QRA65_M; // source is the previous pd srctmp = dsttmp-QRA64_M; // source is the previous pd
for (k=0;k<QRA65_C;k++) { for (k=0;k<QRA64_C;k++) {
pd_init(dsttmp,srctmp,QRA65_M); pd_init(dsttmp,srctmp,QRA64_M);
dsttmp -=QRA65_M; dsttmp -=QRA64_M;
srctmp -=QRA65_M; srctmp -=QRA64_M;
} }
// Initialize crc prob to a uniform distribution // Initialize crc prob to a uniform distribution
pd_init(dsttmp,pd_uniform(QRA65_m),QRA65_M); pd_init(dsttmp,pd_uniform(QRA64_m),QRA64_M);
// Attempt to decode without a-priori info -------------------------------- // Attempt to decode without a-priori info --------------------------------
rc = qra65_do_decode(x, ix, NULL, NULL); rc = qra64_do_decode(x, ix, NULL, NULL);
if (rc>=0) return 0; // successfull decode with AP0 if (rc>=0) return 0; // successfull decode with AP0
if (pcodec->apflags!=QRA_AUTOAP) return rc; // rc<0 = unsuccessful decode if (pcodec->apflags!=QRA_AUTOAP) return rc; // rc<0 = unsuccessful decode
// Attempt to decode CQ calls // Attempt to decode CQ calls
rc = qra65_do_decode(x,ix,pcodec->apmask_cqqrz, pcodec->apmsg_cqqrz); // AP27 rc = qra64_do_decode(x,ix,pcodec->apmask_cqqrz, pcodec->apmsg_cqqrz); // AP27
if (rc>=0) return 1; // decoded [cq/qrz ? ?] if (rc>=0) return 1; // decoded [cq/qrz ? ?]
rc = qra65_do_decode(x, ix, pcodec->apmask_cqqrz_ooo, rc = qra64_do_decode(x, ix, pcodec->apmask_cqqrz_ooo,
pcodec->apmsg_cqqrz); // AP42 pcodec->apmsg_cqqrz); // AP42
if (rc>=0) return 2; // decoded [cq ? ooo] if (rc>=0) return 2; // decoded [cq ? ooo]
// attempt to decode calls directed to us (mycall) // attempt to decode calls directed to us (mycall)
rc = qra65_do_decode(x, ix, pcodec->apmask_call1, rc = qra64_do_decode(x, ix, pcodec->apmask_call1,
pcodec->apmsg_call1); // AP29 pcodec->apmsg_call1); // AP29
if (rc>=0) return 3; // decoded [mycall ? ?] if (rc>=0) return 3; // decoded [mycall ? ?]
rc = qra65_do_decode(x, ix, pcodec->apmask_call1_ooo, rc = qra64_do_decode(x, ix, pcodec->apmask_call1_ooo,
pcodec->apmsg_call1); // AP44 pcodec->apmsg_call1); // AP44
if (rc>=0) return 4; // decoded [mycall ? ooo] if (rc>=0) return 4; // decoded [mycall ? ooo]
// if apsrccall is set attempt to decode [mycall srccall ?] msgs // if apsrccall is set attempt to decode [mycall srccall ?] msgs
if (pcodec->apsrccall==0) return rc; // nothing more to do if (pcodec->apsrccall==0) return rc; // nothing more to do
rc = qra65_do_decode(x, ix, pcodec->apmask_call1_call2, rc = qra64_do_decode(x, ix, pcodec->apmask_call1_call2,
pcodec->apmsg_call1_call2); // AP57 pcodec->apmsg_call1_call2); // AP57
if (rc>=0) return 5; // decoded [mycall srccall ?] if (rc>=0) return 5; // decoded [mycall srccall ?]
@ -211,17 +211,17 @@ int qra65_decode(qra65codec *pcodec, int *x, const float *rxen)
// Static functions definitions ---------------------------------------------- // Static functions definitions ----------------------------------------------
// Decode with given a-priori information // Decode with given a-priori information
static int qra65_do_decode(int *x, const float *pix, const int *ap_mask, static int qra64_do_decode(int *x, const float *pix, const int *ap_mask,
const int *ap_x) const int *ap_x)
{ {
int rc; int rc;
const float *ixsrc; const float *ixsrc;
float ix_masked[QRA65_NC*QRA65_M]; // Masked intrinsic information float ix_masked[QRA64_NC*QRA64_M]; // Masked intrinsic information
float ex[QRA65_NC*QRA65_M]; // Extrinsic information from the decoder float ex[QRA64_NC*QRA64_M]; // Extrinsic information from the decoder
float v2cmsg[QRA65_NMSG*QRA65_M]; // buffers for the decoder messages float v2cmsg[QRA64_NMSG*QRA64_M]; // buffers for the decoder messages
float c2vmsg[QRA65_NMSG*QRA65_M]; float c2vmsg[QRA64_NMSG*QRA64_M];
int xdec[QRA65_KC]; int xdec[QRA64_KC];
if (ap_mask==NULL) { // no a-priori information if (ap_mask==NULL) { // no a-priori information
ixsrc = pix; // intrinsic source is what passed as argument ixsrc = pix; // intrinsic source is what passed as argument
@ -233,19 +233,19 @@ static int qra65_do_decode(int *x, const float *pix, const int *ap_mask,
} }
// run the decoding algorithm // run the decoding algorithm
rc = qra_extrinsic(&QRA65_CODE,ex,ixsrc,QRA65_NITER,v2cmsg,c2vmsg); rc = qra_extrinsic(&QRA64_CODE,ex,ixsrc,QRA64_NITER,v2cmsg,c2vmsg);
if (rc<0) if (rc<0)
return -1; // no convergence in given iterations return -1; // no convergence in given iterations
// decode // decode
qra_mapdecode(&QRA65_CODE,xdec,ex,ixsrc); qra_mapdecode(&QRA64_CODE,xdec,ex,ixsrc);
// verify crc // verify crc
if (calc_crc6(xdec,QRA65_K)!=xdec[QRA65_K]) // crc doesn't match (detected error) if (calc_crc6(xdec,QRA64_K)!=xdec[QRA64_K]) // crc doesn't match (detected error)
return -2; // decoding was succesfull but crc doesn't match return -2; // decoding was succesfull but crc doesn't match
// success. copy decoded message to output buffer // success. copy decoded message to output buffer
memcpy(x,xdec,QRA65_K*sizeof(int)); memcpy(x,xdec,QRA64_K*sizeof(int));
return 0; return 0;
} }
@ -284,17 +284,17 @@ static void ix_mask(float *dst, const float *src, const int *mask,
int k,kk, smask; int k,kk, smask;
float *row; float *row;
memcpy(dst,src,(QRA65_NC*QRA65_M)*sizeof(float)); memcpy(dst,src,(QRA64_NC*QRA64_M)*sizeof(float));
for (k=0;k<QRA65_K;k++) { // we can mask only information symbols distrib for (k=0;k<QRA64_K;k++) { // we can mask only information symbols distrib
smask = mask[k]; smask = mask[k];
row = PD_ROWADDR(dst,QRA65_M,k); row = PD_ROWADDR(dst,QRA64_M,k);
if (smask) { if (smask) {
for (kk=0;kk<QRA65_M;kk++) for (kk=0;kk<QRA64_M;kk++)
if (((kk^x[k])&smask)!=0) if (((kk^x[k])&smask)!=0)
*(row+kk) = 0.f; *(row+kk) = 0.f;
pd_norm(row,QRA65_m); pd_norm(row,QRA64_m);
} }
} }
} }

View File

@ -1,5 +1,5 @@
// qra65.h // qra64.h
// Encoding/decoding functions for the QRA65 mode // Encoding/decoding functions for the QRA64 mode
// //
// (c) 2016 - Nico Palermo, IV3NWV // (c) 2016 - Nico Palermo, IV3NWV
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
@ -19,19 +19,19 @@
// along with qracodes source distribution. // along with qracodes source distribution.
// If not, see <http://www.gnu.org/licenses/>. // If not, see <http://www.gnu.org/licenses/>.
#ifndef _qra65_h_ #ifndef _qra64_h_
#define _qra65_h_ #define _qra64_h_
// qra65_init(...) initialization flags // qra64_init(...) initialization flags
#define QRA_NOAP 0 // don't use a-priori knowledge #define QRA_NOAP 0 // don't use a-priori knowledge
#define QRA_AUTOAP 1 // use auto a-priori knowledge #define QRA_AUTOAP 1 // use auto a-priori knowledge
// QRA code parameters // QRA code parameters
#define QRA65_K 12 // information symbols #define QRA64_K 12 // information symbols
#define QRA65_N 63 // codeword length #define QRA64_N 63 // codeword length
#define QRA65_C 51 // (number of parity checks C=(N-K)) #define QRA64_C 51 // (number of parity checks C=(N-K))
#define QRA65_M 64 // code alphabet size #define QRA64_M 64 // code alphabet size
#define QRA65_m 6 // bits per symbol #define QRA64_m 6 // bits per symbol
// packed predefined callsigns and fields as defined in JT65 // packed predefined callsigns and fields as defined in JT65
#define CALL_CQ 0xFA08319 #define CALL_CQ 0xFA08319
@ -55,14 +55,14 @@ typedef struct {
int apmask_call1[12]; int apmask_call1[12];
int apmask_call1_ooo[12]; int apmask_call1_ooo[12];
int apmask_call1_call2[12]; int apmask_call1_call2[12];
} qra65codec; } qra64codec;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
qra65codec *qra65_init(int flags, const int mycall); qra64codec *qra64_init(int flags, const int mycall);
// QRA65 mode initialization function // QRA64 mode initialization function
// arguments: // arguments:
// flags: set the decoder mode // flags: set the decoder mode
// When flags = QRA_NOAP no a-priori information will be used by the decoder // When flags = QRA_NOAP no a-priori information will be used by the decoder
@ -70,37 +70,37 @@ qra65codec *qra65_init(int flags, const int mycall);
// of available a-priori information // of available a-priori information
// mycall: 28-bit packed callsign of the user (as computed by JT65) // mycall: 28-bit packed callsign of the user (as computed by JT65)
// returns: // returns:
// Pointer to the qra65codec data structure allocated and inizialized by the function // Pointer to the qra64codec data structure allocated and inizialized by the function
// this handle should be passed to the encoding/decoding functions // this handle should be passed to the encoding/decoding functions
// //
// 0 if unsuccessful (can't allocate memory) // 0 if unsuccessful (can't allocate memory)
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
void qra65_encode(qra65codec *pcodec, int *y, const int *x); void qra64_encode(qra64codec *pcodec, int *y, const int *x);
// QRA65 mode encoder // QRA64 mode encoder
// arguments: // arguments:
// pcodec = pointer to a qra65codec data structure as returned by qra65_init // pcodec = pointer to a qra64codec data structure as returned by qra64_init
// x = pointer to the message to encode // x = pointer to the message to encode
// x must point to an array of integers (i.e. defined as int x[12]) // x must point to an array of integers (i.e. defined as int x[12])
// y = pointer to the encoded message // y = pointer to the encoded message
// y must point to an array of integers of lenght 63 (i.e. defined as int y[63]) // y must point to an array of integers of lenght 63 (i.e. defined as int y[63])
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
int qra65_decode(qra65codec *pcodec, int *x, const float *r); int qra64_decode(qra64codec *pcodec, int *x, const float *r);
// QRA65 mode decoder // QRA64 mode decoder
// arguments: // arguments:
// pcodec = pointer to a qra65codec data structure as returned by qra65_init // pcodec = pointer to a qra64codec data structure as returned by qra64_init
// x = pointer to the array of integers where the decoded message will be stored // x = pointer to the array of integers where the decoded message will be stored
// x must point to an array of integers (i.e. defined as int x[12]) // x must point to an array of integers (i.e. defined as int x[12])
// r = pointer to the received symbols energies (squared amplitudes) // r = pointer to the received symbols energies (squared amplitudes)
// r must point to an array of QRA65_M*QRA65_N (=64*63=4032) float numbers. // r must point to an array of QRA64_M*QRA64_N (=64*63=4032) float numbers.
// The first QRA_M entries should be the energies of the first symbol in the codeword // The first QRA_M entries should be the energies of the first symbol in the codeword
// The last QRA_M entries should be the energies of the last symbol in the codeword // The last QRA_M entries should be the energies of the last symbol in the codeword
// //
// return code: // return code:
// //
// The return code is <0 when decoding is unsuccessful // The return code is <0 when decoding is unsuccessful
// -16 indicates that the definition of QRA65_NMSG does not match what required by the code // -16 indicates that the definition of QRA64_NMSG does not match what required by the code
// If the decoding process is successfull the return code is accordingly to the following table // If the decoding process is successfull the return code is accordingly to the following table
// rc=0 [? ? ?] AP0 (decoding with no a-priori) // rc=0 [? ? ?] AP0 (decoding with no a-priori)
// rc=1 [CQ ? ?] AP27 // rc=1 [CQ ? ?] AP27
@ -120,4 +120,4 @@ void decodemsg_jt65(int *call1, int *call2, int *grid, const int *x);
} }
#endif #endif
#endif // _qra65_h_ #endif // _qra64_h_

View File

@ -1,17 +1,17 @@
// qra65_subs.c // qra64_subs.c
// Fortran interface routines for QRA65 // Fortran interface routines for QRA64
#include "qra65.h" #include "qra64.h"
#include <stdio.h> #include <stdio.h>
void qra65_enc_(int x[], int y[]) void qra64_enc_(int x[], int y[])
{ {
int ncall=0xf70c238; //K1ABC int ncall=0xf70c238; //K1ABC
qra65codec *codec = qra65_init(0,ncall); //codec for ncall qra64codec *codec = qra64_init(0,ncall); //codec for ncall
qra65_encode(codec, y, x); qra64_encode(codec, y, x);
} }
void qra65_dec_(float r[], int* nmycall, int xdec[], int* rc) void qra64_dec_(float r[], int* nmycall, int xdec[], int* rc)
{ {
// Return codes: // Return codes:
// rc=-16 failed sanity check // rc=-16 failed sanity check
@ -26,11 +26,11 @@ void qra65_dec_(float r[], int* nmycall, int xdec[], int* rc)
static ncall0=-1; static ncall0=-1;
int ncall=*nmycall; int ncall=*nmycall;
static qra65codec *codec; static qra64codec *codec;
if(ncall!=ncall0) { if(ncall!=ncall0) {
codec = qra65_init(1,ncall); //codec for ncall codec = qra64_init(1,ncall); //codec for ncall
ncall0=ncall; ncall0=ncall;
} }
*rc = qra65_decode(codec,xdec,r); *rc = qra64_decode(codec,xdec,r);
} }

View File

@ -1,6 +1,6 @@
program qra65sim program qra64sim
! Generate simulated QRA65 data for testing the decoder. ! Generate simulated QRA64 data for testing the decoder.
use wavhdr use wavhdr
use packjt use packjt
@ -141,11 +141,11 @@ program qra65sim
xsnr=xsnr+5 !### TEMPORARY ### xsnr=xsnr+5 !### TEMPORARY ###
call genqra65(msg,ichk,msgsent,itone,itype) call genqra64(msg,ichk,msgsent,itone,itype)
! call packmsg(msg,dgen,itype) !Pack message into 12 six-bit bytes ! call packmsg(msg,dgen,itype) !Pack message into 12 six-bit bytes
! call qra65_enc(dgen,sent) !Encode using QRA65 ! call qra64_enc(dgen,sent) !Encode using QRA64
!! call qra65_dec(sent,dgen,ierr) !Decode (### for test only ###) !! call qra64_dec(sent,dgen,ierr) !Decode (### for test only ###)
!! write(*,3001) sent !! write(*,3001) sent
!!3001 format(21i3) !!3001 format(21i3)
@ -249,4 +249,4 @@ program qra65sim
close(10) close(10)
enddo enddo
999 end program qra65sim 999 end program qra64sim

View File

@ -1,30 +0,0 @@
FC = gfortran
CC = gcc
CFLAGS = -O2 -Wall -I. -D_WIN32
# Default rules
%.o: %.c
${CC} ${CFLAGS} -c $<
%.o: %.f
${FC} ${FFLAGS} -c $<
%.o: %.F
${FC} ${FFLAGS} -c $<
%.o: %.f90
${FC} ${FFLAGS} -c $<
%.o: %.F90
${FC} ${FFLAGS} -c $<
all: qra65.exe
OBJS1 = main.o qra65.o
qra65.exe: $(OBJS1)
${CC} -o qra65.exe $(OBJS1) ../qracodes/libqra65.a -lm
OBJS2 = qra65sim.o options.o wavhdr.o
qra65sim.exe: $(OBJS2)
${FC} -o qra65sim.exe $(OBJS2) ../qracodes/libqra65.a -lm
.PHONY : clean
clean:
$(RM) *.o qra65.exe qra65sim.exe

View File

@ -1,4 +1,4 @@
subroutine qra02(dd,nf1,nf2,nfqso,ntol,mycall_12,sync,nsnr,dtx,nfreq, & subroutine qra64a(dd,nf1,nf2,nfqso,ntol,mycall_12,sync,nsnr,dtx,nfreq, &
decoded,nft) decoded,nft)
use packjt use packjt
@ -20,7 +20,7 @@ subroutine qra02(dd,nf1,nf2,nfqso,ntol,mycall_12,sync,nsnr,dtx,nfreq, &
equivalence (x,cx) equivalence (x,cx)
data icos7/2,5,6,0,4,1,3/ !Costas 7x7 pattern data icos7/2,5,6,0,4,1,3/ !Costas 7x7 pattern
data mark/' ','.','-','+','X','$'/ data mark/' ','.','-','+','X','$'/
common/qra65com/ss(NZ,194),s3(0:63,1:63),ccf(NZ,0:25) common/qra64com/ss(NZ,194),s3(0:63,1:63),ccf(NZ,0:25)
save save
! rewind 73 ! rewind 73
@ -123,7 +123,7 @@ subroutine qra02(dd,nf1,nf2,nfqso,ntol,mycall_12,sync,nsnr,dtx,nfreq, &
mycall=mycall_12(1:6) !### May need fixing ### mycall=mycall_12(1:6) !### May need fixing ###
call packcall(mycall,nmycall,ltext) call packcall(mycall,nmycall,ltext)
call qra65_dec(s3,nmycall,dat4,irc) !Attempt decoding call qra64_dec(s3,nmycall,dat4,irc) !Attempt decoding
if(irc.ge.0) then if(irc.ge.0) then
call unpackmsg(dat4,decoded) !Unpack the user message call unpackmsg(dat4,decoded) !Unpack the user message
call fmtmsg(decoded,iz) call fmtmsg(decoded,iz)
@ -131,4 +131,4 @@ subroutine qra02(dd,nf1,nf2,nfqso,ntol,mycall_12,sync,nsnr,dtx,nfreq, &
endif endif
900 return 900 return
end subroutine qra02 end subroutine qra64a

View File

@ -1,11 +1,11 @@
program QRA65code program QRA64code
! Provides examples of message packing, bit and symbol ordering, ! Provides examples of message packing, bit and symbol ordering,
! QRA (63,12) encoding, and other necessary details of the QRA65 ! QRA (63,12) encoding, and other necessary details of the QRA64
! protocol. Also permits simple simulations to measure performance ! protocol. Also permits simple simulations to measure performance
! on an AWGN channel with secure time and frequency synchronization. ! on an AWGN channel with secure time and frequency synchronization.
! Return codes from qra65_dec: ! Return codes from qra64_dec:
! irc=0 [? ? ?] AP0 (decoding with no a-priori information) ! irc=0 [? ? ?] AP0 (decoding with no a-priori information)
! irc=1 [CQ ? ?] AP27 ! irc=1 [CQ ? ?] AP27
! irc=2 [CQ ? ] AP42 ! irc=2 [CQ ? ] AP42
@ -23,8 +23,8 @@ program QRA65code
nargs=iargc() nargs=iargc()
if(nargs.lt.1) then if(nargs.lt.1) then
print*,'Usage: qra65code "message" [snr2500] [Nrpt]' print*,'Usage: qra64code "message" [snr2500] [Nrpt]'
print*,' qra65code -t [snr2500]' print*,' qra64code -t [snr2500]'
go to 999 go to 999
endif endif
@ -67,7 +67,7 @@ program QRA65code
if(itype.eq.5) msgtype="Type 2 sfx" if(itype.eq.5) msgtype="Type 2 sfx"
if(itype.eq.6) msgtype="Free text" if(itype.eq.6) msgtype="Free text"
call qra65_enc(dgen,sent) !Encode using QRA65 call qra64_enc(dgen,sent) !Encode using QRA64
! Generate a simulated s3() array with moderately high S/N ! Generate a simulated s3() array with moderately high S/N
do j=1,63 do j=1,63
@ -86,7 +86,7 @@ program QRA65code
mycall=' ' mycall=' '
if(i1.ge.4) mycall=msg(1:i1-1) if(i1.ge.4) mycall=msg(1:i1-1)
call packcall(mycall,nmycall,ltext) call packcall(mycall,nmycall,ltext)
call qra65_dec(s3,nmycall,dec,irc) !Decode call qra64_dec(s3,nmycall,dec,irc) !Decode
decoded=" " decoded=" "
if(irc.ge.0) then if(irc.ge.0) then
@ -124,4 +124,4 @@ program QRA65code
1060 format('Decoded messages:',i5,'/',i4,' Undetected errors:',i5) 1060 format('Decoded messages:',i5,'/',i4,' Undetected errors:',i5)
endif endif
999 end program QRA65code 999 end program QRA64code

View File

@ -81,7 +81,7 @@ extern "C" {
void gen65_(char* msg, int* ichk, char* msgsent, int itone[], void gen65_(char* msg, int* ichk, char* msgsent, int itone[],
int* itext, int len1, int len2); int* itext, int len1, int len2);
void genqra65_(char* msg, int* ichk, char* msgsent, int itone[], void genqra64_(char* msg, int* ichk, char* msgsent, int itone[],
int* itext, int len1, int len2); int* itext, int len1, int len2);
void genwspr_(char* msg, char* msgsent, int itone[], int len1, int len2); void genwspr_(char* msg, char* msgsent, int itone[], int len1, int len2);
@ -466,7 +466,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
ui->actionISCAT->setActionGroup(modeGroup); ui->actionISCAT->setActionGroup(modeGroup);
ui->actionJTMSK->setActionGroup(modeGroup); ui->actionJTMSK->setActionGroup(modeGroup);
ui->actionMSK144->setActionGroup(modeGroup); ui->actionMSK144->setActionGroup(modeGroup);
ui->actionQRA65->setActionGroup(modeGroup); ui->actionQRA64->setActionGroup(modeGroup);
QActionGroup* saveGroup = new QActionGroup(this); QActionGroup* saveGroup = new QActionGroup(this);
ui->actionNone->setActionGroup(saveGroup); ui->actionNone->setActionGroup(saveGroup);
@ -743,7 +743,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
bool b = vhf and (m_mode=="JT4" or m_mode=="JT65" or bool b = vhf and (m_mode=="JT4" or m_mode=="JT65" or
m_mode=="ISCAT" or m_mode=="JT9" or m_mode=="ISCAT" or m_mode=="JT9" or
m_mode=="JTMSK" or m_mode=="MSK144" or m_mode=="JTMSK" or m_mode=="MSK144" or
m_mode=="QRA65"); m_mode=="QRA64");
VHF_controls_visible(b); VHF_controls_visible(b);
ui->txFirstCheckBox->setChecked(m_txFirst); ui->txFirstCheckBox->setChecked(m_txFirst);
@ -768,7 +768,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
if(m_mode=="ISCAT") on_actionISCAT_triggered(); if(m_mode=="ISCAT") on_actionISCAT_triggered();
if(m_mode=="JTMSK") on_actionJTMSK_triggered(); if(m_mode=="JTMSK") on_actionJTMSK_triggered();
if(m_mode=="MSK144") on_actionMSK144_triggered(); if(m_mode=="MSK144") on_actionMSK144_triggered();
if(m_mode=="QRA65") on_actionQRA65_triggered(); if(m_mode=="QRA64") on_actionQRA64_triggered();
if(m_mode=="Echo") monitor(false); //Don't auto-start Monitor in Echo mode. if(m_mode=="Echo") monitor(false); //Don't auto-start Monitor in Echo mode.
ui->sbSubmode->setValue (vhf ? m_nSubMode : 0); ui->sbSubmode->setValue (vhf ? m_nSubMode : 0);
@ -829,8 +829,8 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
QString t=m_config.my_callsign(); QString t=m_config.my_callsign();
if(t!="IV3NWV" and t!="K1JT" and t!="K9AN" and t!="G4WJS" if(t!="IV3NWV" and t!="K1JT" and t!="K9AN" and t!="G4WJS"
and t!="IW0HDV" and t!="VE1SKY" and t!="KI7MT") { and t!="IW0HDV" and t!="VE1SKY" and t!="KI7MT") {
ui->actionQRA65->setChecked(false); ui->actionQRA64->setChecked(false);
ui->actionQRA65->setEnabled(false); ui->actionQRA64->setEnabled(false);
ui->actionMSK144->setChecked(false); ui->actionMSK144->setChecked(false);
ui->actionMSK144->setEnabled(false); } ui->actionMSK144->setEnabled(false); }
} }
@ -1339,7 +1339,7 @@ void MainWindow::on_actionSettings_triggered() //Setup Dialog
setup_status_bar (vhf); setup_status_bar (vhf);
bool b = vhf && (m_mode=="JT4" or m_mode=="JT65" or bool b = vhf && (m_mode=="JT4" or m_mode=="JT65" or
m_mode=="ISCAT" or m_mode=="JT9" or m_mode=="JTMSK" or m_mode=="ISCAT" or m_mode=="JT9" or m_mode=="JTMSK" or
m_mode=="MSK144" or m_mode=="QRA65"); m_mode=="MSK144" or m_mode=="QRA64");
VHF_features_enabled(b); VHF_features_enabled(b);
VHF_controls_visible(b); VHF_controls_visible(b);
} }
@ -1654,8 +1654,8 @@ void MainWindow::createStatusBar() //createStatusBar
void MainWindow::setup_status_bar (bool vhf) void MainWindow::setup_status_bar (bool vhf)
{ {
mode_label.setText ("QRA65" == m_mode ? QString {"QRA02"} : m_mode); mode_label.setText ("QRA64" == m_mode ? QString {"QRA02"} : m_mode);
if (m_mode.contains (QRegularExpression {R"(^(JT65|JT9|JT4|ISCAT|QRA65)$)"})) if (m_mode.contains (QRegularExpression {R"(^(JT65|JT9|JT4|ISCAT|QRA64)$)"}))
{ {
if (vhf || "JT4" == m_mode || "ISCAT" == m_mode) if (vhf || "JT4" == m_mode || "ISCAT" == m_mode)
{ {
@ -1682,7 +1682,7 @@ void MainWindow::setup_status_bar (bool vhf)
{ {
mode_label.setStyleSheet ("QLabel{background-color: #66ff66}"); mode_label.setStyleSheet ("QLabel{background-color: #66ff66}");
} }
else if ("QRA65" == m_mode) else if ("QRA64" == m_mode)
{ {
mode_label.setStyleSheet ("QLabel{background-color: #99ff33}"); mode_label.setStyleSheet ("QLabel{background-color: #99ff33}");
} }
@ -2116,8 +2116,8 @@ void MainWindow::decode() //decode()
if(m_modeTx=="JT65") dec_data.params.ntxmode=65; if(m_modeTx=="JT65") dec_data.params.ntxmode=65;
dec_data.params.nmode=9; dec_data.params.nmode=9;
if(m_mode=="JT65") dec_data.params.nmode=65; if(m_mode=="JT65") dec_data.params.nmode=65;
if(m_mode=="QRA65") dec_data.params.nmode=165; if(m_mode=="QRA64") dec_data.params.nmode=165;
if(m_mode=="QRA65") dec_data.params.ntxmode=165; if(m_mode=="QRA64") dec_data.params.ntxmode=165;
if(m_mode=="JT9+JT65") dec_data.params.nmode=9+65; // = 74 if(m_mode=="JT9+JT65") dec_data.params.nmode=9+65; // = 74
if(m_mode=="JT4") { if(m_mode=="JT4") {
dec_data.params.nmode=4; dec_data.params.nmode=4;
@ -2125,7 +2125,7 @@ void MainWindow::decode() //decode()
} }
dec_data.params.ntrperiod=m_TRperiod; dec_data.params.ntrperiod=m_TRperiod;
dec_data.params.nsubmode=m_nSubMode; dec_data.params.nsubmode=m_nSubMode;
if(m_mode=="QRA65") dec_data.params.nsubmode=101; if(m_mode=="QRA64") dec_data.params.nsubmode=101;
dec_data.params.minw=0; dec_data.params.minw=0;
dec_data.params.nclearave=m_nclearave; dec_data.params.nclearave=m_nclearave;
if(m_nclearave!=0) { if(m_nclearave!=0) {
@ -2309,7 +2309,7 @@ void MainWindow::readFromStdout() //readFromStdout
QByteArray t=proc_jt9.readLine(); QByteArray t=proc_jt9.readLine();
bool bAvgMsg=false; bool bAvgMsg=false;
int navg=0; int navg=0;
if(m_mode=="JT4" or m_mode=="JT65" or m_mode=="QRA65") { if(m_mode=="JT4" or m_mode=="JT65" or m_mode=="QRA64") {
int n=t.indexOf("f"); int n=t.indexOf("f");
if(n<0) n=t.indexOf("d"); if(n<0) n=t.indexOf("d");
if(n>0) { if(n>0) {
@ -2421,7 +2421,7 @@ void MainWindow::readFromStdout() //readFromStdout
} }
} }
if((m_mode=="JT4" or m_mode=="JT65" or m_mode=="QRA65") and m_msgAvgWidget!=NULL) { if((m_mode=="JT4" or m_mode=="JT65" or m_mode=="QRA64") and m_msgAvgWidget!=NULL) {
if(m_msgAvgWidget->isVisible()) { if(m_msgAvgWidget->isVisible()) {
QFile f(m_config.temp_dir ().absoluteFilePath ("avemsg.txt")); QFile f(m_config.temp_dir ().absoluteFilePath ("avemsg.txt"));
if(f.open(QIODevice::ReadOnly | QIODevice::Text)) { if(f.open(QIODevice::ReadOnly | QIODevice::Text)) {
@ -2518,7 +2518,7 @@ void MainWindow::guiUpdate()
if(m_modeTx=="JT4") txDuration=1.0 + 207.0*2520/11025.0; // JT4 if(m_modeTx=="JT4") txDuration=1.0 + 207.0*2520/11025.0; // JT4
if(m_modeTx=="JT9") txDuration=1.0 + 85.0*m_nsps/12000.0; // JT9 if(m_modeTx=="JT9") txDuration=1.0 + 85.0*m_nsps/12000.0; // JT9
if(m_modeTx=="JT65") txDuration=1.0 + 126*4096/11025.0; // JT65 if(m_modeTx=="JT65") txDuration=1.0 + 126*4096/11025.0; // JT65
if(m_mode=="QRA65") txDuration=1.0 + 84*6912/12000.0; // QRA65 if(m_mode=="QRA64") txDuration=1.0 + 84*6912/12000.0; // QRA64
if(m_mode=="WSPR-2") txDuration=2.0 + 162*8192/12000.0; // WSPR if(m_mode=="WSPR-2") txDuration=2.0 + 162*8192/12000.0; // WSPR
if(m_mode=="ISCAT" or m_mode=="JTMSK" or m_mode=="MSK144" or m_bFast9) { if(m_mode=="ISCAT" or m_mode=="JTMSK" or m_mode=="MSK144" or m_bFast9) {
txDuration=m_TRperiod-0.25; // ISCAT, JT9-fast, JTMSK, MSK144 txDuration=m_TRperiod-0.25; // ISCAT, JT9-fast, JTMSK, MSK144
@ -2710,7 +2710,7 @@ void MainWindow::guiUpdate()
&m_currentMessageType, len1, len1); &m_currentMessageType, len1, len1);
if(m_modeTx=="JT65") gen65_(message, &ichk, msgsent, const_cast<int *> (itone), if(m_modeTx=="JT65") gen65_(message, &ichk, msgsent, const_cast<int *> (itone),
&m_currentMessageType, len1, len1); &m_currentMessageType, len1, len1);
if(m_mode=="QRA65") genqra65_(message, &ichk, msgsent, const_cast<int *> (itone), if(m_mode=="QRA64") genqra64_(message, &ichk, msgsent, const_cast<int *> (itone),
&m_currentMessageType, len1, len1); &m_currentMessageType, len1, len1);
if(m_mode.startsWith ("WSPR")) genwspr_(message, msgsent, const_cast<int *> (itone), if(m_mode.startsWith ("WSPR")) genwspr_(message, msgsent, const_cast<int *> (itone),
len1, len1); len1, len1);
@ -3231,7 +3231,7 @@ void MainWindow::processMessage(QString const& messages, int position, bool ctrl
if (ui->TxFreqSpinBox->isEnabled ()) { if (ui->TxFreqSpinBox->isEnabled ()) {
if(!m_bFastMode) ui->TxFreqSpinBox->setValue(frequency); if(!m_bFastMode) ui->TxFreqSpinBox->setValue(frequency);
} else if(m_mode != "JT4" && m_mode != "JT65" && !m_mode.startsWith ("JT9") && } else if(m_mode != "JT4" && m_mode != "JT65" && !m_mode.startsWith ("JT9") &&
m_mode != "QRA65") { m_mode != "QRA64") {
return; return;
} }
} }
@ -3933,13 +3933,13 @@ void MainWindow::on_actionMSK144_triggered()
ui->actionMSK144->setChecked(true); ui->actionMSK144->setChecked(true);
} }
void MainWindow::on_actionQRA65_triggered() void MainWindow::on_actionQRA64_triggered()
{ {
on_actionJT65_triggered(); on_actionJT65_triggered();
m_mode="QRA65"; m_mode="QRA64";
m_modeTx="QRA65"; m_modeTx="QRA64";
ui->actionQRA65->setChecked(true); ui->actionQRA64->setChecked(true);
switch_mode (Modes::QRA65); switch_mode (Modes::QRA64);
statusChanged(); statusChanged();
setup_status_bar (m_config.enable_VHF_features ()); setup_status_bar (m_config.enable_VHF_features ());
m_wideGraph->setMode(m_mode); m_wideGraph->setMode(m_mode);
@ -4819,11 +4819,11 @@ void MainWindow::transmit (double snr)
true, false, snr, m_TRperiod); true, false, snr, m_TRperiod);
} }
if (m_modeTx == "QRA65") { if (m_modeTx == "QRA64") {
if(m_nSubMode==0) toneSpacing=12000.0/6912.0; if(m_nSubMode==0) toneSpacing=12000.0/6912.0;
if(m_nSubMode==1) toneSpacing=2*12000.0/6912.0; if(m_nSubMode==1) toneSpacing=2*12000.0/6912.0;
if(m_nSubMode==2) toneSpacing=4*12000.0/6912.0; if(m_nSubMode==2) toneSpacing=4*12000.0/6912.0;
Q_EMIT sendMessage (NUM_QRA65_SYMBOLS, Q_EMIT sendMessage (NUM_QRA64_SYMBOLS,
6912.0, ui->TxFreqSpinBox->value () - m_XIT, 6912.0, ui->TxFreqSpinBox->value () - m_XIT,
toneSpacing, m_soundOutput, m_config.audio_output_channel (), toneSpacing, m_soundOutput, m_config.audio_output_channel (),
true, false, snr, m_TRperiod); true, false, snr, m_TRperiod);

View File

@ -42,7 +42,7 @@
#define NUM_ISCAT_SYMBOLS 1291 //30*11025/256 #define NUM_ISCAT_SYMBOLS 1291 //30*11025/256
#define NUM_JTMSK_SYMBOLS 234 //(72+15+12)*2 + 3*11 sync + 3 f0-parity #define NUM_JTMSK_SYMBOLS 234 //(72+15+12)*2 + 3*11 sync + 3 f0-parity
#define NUM_MSK144_SYMBOLS 144 //s8 + d48 + s8 + d80 #define NUM_MSK144_SYMBOLS 144 //s8 + d48 + s8 + d80
#define NUM_QRA65_SYMBOLS 84 //63 data + 21 sync #define NUM_QRA64_SYMBOLS 84 //63 data + 21 sync
#define NUM_CW_SYMBOLS 250 #define NUM_CW_SYMBOLS 250
#define TX_SAMPLE_RATE 48000 #define TX_SAMPLE_RATE 48000
@ -249,7 +249,7 @@ private slots:
void on_sbCQRxFreq_valueChanged(int n); void on_sbCQRxFreq_valueChanged(int n);
void on_cbCQRx_toggled(bool b); void on_cbCQRx_toggled(bool b);
void on_actionMSK144_triggered(); void on_actionMSK144_triggered();
void on_actionQRA65_triggered(); void on_actionQRA64_triggered();
private: private:
Q_SIGNAL void initializeAudioOutputStream (QAudioDeviceInfo, Q_SIGNAL void initializeAudioOutputStream (QAudioDeviceInfo,

View File

@ -2353,7 +2353,7 @@ QPushButton[state=&quot;ok&quot;] {
<addaction name="actionISCAT"/> <addaction name="actionISCAT"/>
<addaction name="actionJTMSK"/> <addaction name="actionJTMSK"/>
<addaction name="actionMSK144"/> <addaction name="actionMSK144"/>
<addaction name="actionQRA65"/> <addaction name="actionQRA64"/>
</widget> </widget>
<widget class="QMenu" name="menuConfig"> <widget class="QMenu" name="menuConfig">
<property name="title"> <property name="title">
@ -2823,12 +2823,12 @@ QPushButton[state=&quot;ok&quot;] {
<string>MSK144</string> <string>MSK144</string>
</property> </property>
</action> </action>
<action name="actionQRA65"> <action name="actionQRA64">
<property name="checkable"> <property name="checkable">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="text"> <property name="text">
<string>QRA02</string> <string>QRA64</string>
</property> </property>
</action> </action>
</widget> </widget>

View File

@ -355,7 +355,7 @@ void CPlotter::DrawOverlay() //DrawOverlay()
if(m_nSubMode==7) bw=128*bw; //H if(m_nSubMode==7) bw=128*bw; //H
} }
if(m_mode=="QRA65") { //QRA65 if(m_mode=="QRA64") { //QRA64
bw=63.0*12000.0/m_nsps; bw=63.0*12000.0/m_nsps;
if(m_nSubMode==1) bw=2*bw; //B if(m_nSubMode==1) bw=2*bw; //B
if(m_nSubMode==2) bw=4*bw; //C if(m_nSubMode==2) bw=4*bw; //C
@ -375,9 +375,9 @@ void CPlotter::DrawOverlay() //DrawOverlay()
x2=XfromFreq(1600); x2=XfromFreq(1600);
painter0.drawLine(x1,29,x2,29); painter0.drawLine(x1,29,x2,29);
} }
if(m_mode=="JT9" or m_mode=="JT65" or m_mode=="JT9+JT65" or m_mode=="QRA65") { if(m_mode=="JT9" or m_mode=="JT65" or m_mode=="JT9+JT65" or m_mode=="QRA64") {
if(m_mode=="QRA65" or (g_single_decode and m_mode=="JT65")) { if(m_mode=="QRA64" or (g_single_decode and m_mode=="JT65")) {
painter0.setPen(penGreen); painter0.setPen(penGreen);
x1=XfromFreq(m_rxFreq-m_tol); x1=XfromFreq(m_rxFreq-m_tol);
x2=XfromFreq(m_rxFreq+m_tol); x2=XfromFreq(m_rxFreq+m_tol);
@ -409,7 +409,7 @@ void CPlotter::DrawOverlay() //DrawOverlay()
} }
if(m_mode=="JT9" or m_mode=="JT65" or m_mode=="JT9+JT65" or if(m_mode=="JT9" or m_mode=="JT65" or m_mode=="JT9+JT65" or
m_mode.mid(0,4)=="WSPR" or m_mode=="QRA65") { m_mode.mid(0,4)=="WSPR" or m_mode=="QRA64") {
painter0.setPen(penRed); painter0.setPen(penRed);
x1=XfromFreq(m_txFreq); x1=XfromFreq(m_txFreq);
x2=XfromFreq(m_txFreq+bw); x2=XfromFreq(m_txFreq+bw);