From f8c1b6ed23f80ecc1ef51b2eb6fdd1c77dc5f638 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Tue, 3 Jul 2012 19:43:26 +0000 Subject: [PATCH] Soundout is now working (or at least making noise) with JTMS3 waveforms. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/jtms3@2479 ab8295b8-cf94-4d9e-aec4-7959e3be5d79 --- jtms3.pro | 2 +- libm65/conv232.f90 | 38 ++++++++++++++++++++++++ libm65/encode232.f90 | 33 +++++++++++++++++++++ libm65/entail.f90 | 30 +++++++++++++++++++ libm65/four2a.f90 | 3 +- libm65/genjtms3.f90 | 26 ++++++++++++++++ libm65/genjtms3a.f90 | 70 ++++++++++++++++++++++++++++++++++++++++++++ libm65/scr258.f90 | 51 ++++++++++++++++++++++++++++++++ mainwindow.cpp | 9 ++++-- mainwindow.h | 3 ++ soundout.cpp | 8 ++--- 11 files changed, 264 insertions(+), 9 deletions(-) create mode 100644 libm65/conv232.f90 create mode 100644 libm65/encode232.f90 create mode 100644 libm65/entail.f90 create mode 100644 libm65/genjtms3.f90 create mode 100644 libm65/genjtms3a.f90 create mode 100644 libm65/scr258.f90 diff --git a/jtms3.pro b/jtms3.pro index e5712718e..93c322e60 100644 --- a/jtms3.pro +++ b/jtms3.pro @@ -6,7 +6,7 @@ QT += core gui network CONFIG += qwt thread -#CONFIG += console +CONFIG += console TARGET = jtms3 VERSION = 0.1 diff --git a/libm65/conv232.f90 b/libm65/conv232.f90 new file mode 100644 index 000000000..3a347e1d9 --- /dev/null +++ b/libm65/conv232.f90 @@ -0,0 +1,38 @@ +! Layland-Lushbaugh polynomials for a K=32, r=1/2 convolutional code, +! and 8-bit parity lookup table. + + data npoly1/-221228207/,npoly2/-463389625/ + integer*1 partab(0:255) + data partab/ & + 0, 1, 1, 0, 1, 0, 0, 1, & + 1, 0, 0, 1, 0, 1, 1, 0, & + 1, 0, 0, 1, 0, 1, 1, 0, & + 0, 1, 1, 0, 1, 0, 0, 1, & + 1, 0, 0, 1, 0, 1, 1, 0, & + 0, 1, 1, 0, 1, 0, 0, 1, & + 0, 1, 1, 0, 1, 0, 0, 1, & + 1, 0, 0, 1, 0, 1, 1, 0, & + 1, 0, 0, 1, 0, 1, 1, 0, & + 0, 1, 1, 0, 1, 0, 0, 1, & + 0, 1, 1, 0, 1, 0, 0, 1, & + 1, 0, 0, 1, 0, 1, 1, 0, & + 0, 1, 1, 0, 1, 0, 0, 1, & + 1, 0, 0, 1, 0, 1, 1, 0, & + 1, 0, 0, 1, 0, 1, 1, 0, & + 0, 1, 1, 0, 1, 0, 0, 1, & + 1, 0, 0, 1, 0, 1, 1, 0, & + 0, 1, 1, 0, 1, 0, 0, 1, & + 0, 1, 1, 0, 1, 0, 0, 1, & + 1, 0, 0, 1, 0, 1, 1, 0, & + 0, 1, 1, 0, 1, 0, 0, 1, & + 1, 0, 0, 1, 0, 1, 1, 0, & + 1, 0, 0, 1, 0, 1, 1, 0, & + 0, 1, 1, 0, 1, 0, 0, 1, & + 0, 1, 1, 0, 1, 0, 0, 1, & + 1, 0, 0, 1, 0, 1, 1, 0, & + 1, 0, 0, 1, 0, 1, 1, 0, & + 0, 1, 1, 0, 1, 0, 0, 1, & + 1, 0, 0, 1, 0, 1, 1, 0, & + 0, 1, 1, 0, 1, 0, 0, 1, & + 0, 1, 1, 0, 1, 0, 0, 1, & + 1, 0, 0, 1, 0, 1, 1, 0/ diff --git a/libm65/encode232.f90 b/libm65/encode232.f90 new file mode 100644 index 000000000..bc904b488 --- /dev/null +++ b/libm65/encode232.f90 @@ -0,0 +1,33 @@ +subroutine encode232(dat,nsym,symbol) + +! Convolutional encoder for a K=32, r=1/2 code. + + integer*1 dat(13) !User data, packed 8 bits per byte + integer*1 symbol(500) !Channel symbols, one bit per byte + integer*1 i1 + include 'conv232.f90' + + nstate=0 + k=0 + do j=1,nsym + do i=7,0,-1 + i1=dat(j) + i4=i1 + if (i4.lt.0) i4=i4+256 + nstate=ior(ishft(nstate,1),iand(ishft(i4,-i),1)) + n=iand(nstate,npoly1) + n=ieor(n,ishft(n,-16)) + k=k+1 + symbol(k)=partab(iand(ieor(n,ishft(n,-8)),255)) + n=iand(nstate,npoly2) + n=ieor(n,ishft(n,-16)) + k=k+1 + symbol(k)=partab(iand(ieor(n,ishft(n,-8)),255)) + if(k.ge.nsym) go to 100 + enddo + enddo + +100 continue + + return +end subroutine encode232 diff --git a/libm65/entail.f90 b/libm65/entail.f90 new file mode 100644 index 000000000..1228a75c6 --- /dev/null +++ b/libm65/entail.f90 @@ -0,0 +1,30 @@ +subroutine entail(dgen,data0) + +! Move 72-bit packed data from 6-bit to 8-bit symbols and add a zero tail. + integer dgen(13) + integer*1 data0(13) + + i4=0 + k=0 + m=0 + do i=1,12 + n=dgen(i) + do j=1,6 + k=k+1 + i4=i4+i4+iand(1,ishft(n,j-6)) + i4=iand(i4,255) + if(k.eq.8) then + m=m+1 + if(i4.gt.127) i4=i4-256 + data0(m)=i4 + k=0 + endif + enddo + enddo + do m=10,13 + data0(m)=0 + enddo + + return +end subroutine entail + diff --git a/libm65/four2a.f90 b/libm65/four2a.f90 index 01a4605f9..d334f5d60 100644 --- a/libm65/four2a.f90 +++ b/libm65/four2a.f90 @@ -22,7 +22,8 @@ subroutine four2a(a,nfft,ndim,isign,iform) complex aa(NSMALL) integer nn(NPMAX),ns(NPMAX),nf(NPMAX),nl(NPMAX) integer*8 plan(NPMAX) !Actually should be i*8, but no matter - data nplan/0/,npatience/1/ +! data nplan/0/,npatience/1/ + data nplan/0/,npatience/0/ include 'fftw3.f' save plan,nplan,nn,ns,nf,nl diff --git a/libm65/genjtms3.f90 b/libm65/genjtms3.f90 new file mode 100644 index 000000000..9b1e70bc7 --- /dev/null +++ b/libm65/genjtms3.f90 @@ -0,0 +1,26 @@ +subroutine genjtms3(msg,msgsent,iwave,nwave) + + character*22 msg,msgsent + integer*1 chansym(258) + integer*2 iwave(30*48000) + integer dgen(13) + integer*1 data0(13) + integer*1 datsym(215) + integer indx0(9) !Indices of duplicated data symbols + data indx0 /16,38,60,82,104,126,148,170,192/ + + call packmsg(msg,dgen) !Pack message into 12 six-bit symbols + call entail(dgen,data0) !Move from 6-bit to 8-bit symbols, add tail + ndat=(72+31)*2 + call encode232(data0,ndat,datsym) !Convolutional encoding + + do i=1,9 !Duplicate 9 symbols at end of datsym + datsym(206+i)=datsym(indx0(i)) + enddo + + call scr258(isync,datsym,1,chansym) !Insert sync and data into chansym(258) + call genjtms3a(chansym,258,iwave,nwave) + msgsent=msg + + return +end subroutine genjtms3 diff --git a/libm65/genjtms3a.f90 b/libm65/genjtms3a.f90 new file mode 100644 index 000000000..f51194bb4 --- /dev/null +++ b/libm65/genjtms3a.f90 @@ -0,0 +1,70 @@ +subroutine genjtms3a(chansym,nsym,iwave,nwave) + + integer*1 chansym(nsym) + integer*2 iwave(30*48000) + real x(0:6191),x2(0:6191) + complex c(0:3096),c2(0:6191) !Could be 0:3096 ??? + equivalence (x,c),(x2,c2) + + do j=1,nsym !Define the baseband signal + i0=24*(j-1) !24 samples per symbol + x(i0:i0+23)=2*chansym(j)-1 + enddo + + nfft=24*nsym + fac=1.0/nfft + x(0:nfft-1)=fac*x(0:nfft-1) + call four2a(x,nfft,1,-1,0) !Forward r2c FFT + +! Apply lowpass filter + fc=1200.0 + bw=200.0 + df=48000.0/nfft + nh=nfft/2 + c2=0. + ib=2000.0/df + + do i=0,ib + f=i*df + g=1.0 + if(f.gt.fc) then + xx=(f-fc)/bw + g=exp(-xx*xx) + endif + c2(i)=g*c(i) + enddo + + call four2a(c2,nfft,1,1,-1) !Inverse c2r FFT + + nf0=nint(1500.0/df) + f0=nf0*df + twopi=8.0*atan(1.0) + dphi=twopi*f0/48000.0 + phi=0. + peak=0. + sq=0. + do i=0,nfft-1 + phi=phi+dphi + if(phi.gt.twopi) phi=phi-twopi + y=cos(phi) + x2(i)=y*x2(i) + sq=sq + x2(i)**2 + if(abs(x2(i)).gt.peak) peak=abs(x2(i)) + enddo + rms=sqrt(sq/nfft) +! print*,rms,peak,peak/rms + + fac=32767.0/peak + do i=0,nfft-1 + iwave(i+1)=fac*x2(i) + enddo + nwave=30*48000 + nrpt=nwave/nfft + do n=2,nrpt + ib=n*nfft + ia=ib-nfft+1 + iwave(ia:ib)=iwave(1:nfft) + enddo + + return +end subroutine genjtms3a diff --git a/libm65/scr258.f90 b/libm65/scr258.f90 new file mode 100644 index 000000000..46c75df76 --- /dev/null +++ b/libm65/scr258.f90 @@ -0,0 +1,51 @@ +subroutine scr258(isync,idat,ndir,ichan) + + integer*1 isync(43) + integer*1 idat(215) + integer*1 ichan(258) + + integer indx(258) + data indx/ & + -1, 1, 129, 65, 193, 33, -2, 161, 97, 17, & ! 10 + 145, 81, -3, 209, 49, 177, 113, 9, -4, 137, & ! 20 + 73, 201, 41, 169, -5, 105, 25, 153, 89, 57, & ! 30 + -6, 185, 121, 5, 133, 69, -7, 197, 37, 165, & ! 40 + 101, 21, -8, 149, 85, 213, 53, 181, -9, 117, & ! 50 + 13, 141, 77, 205, -10, 45, 173, 109, 29, 157, & ! 60 + -11, 93, 61, 189, 125, 3, -12, 131, 67, 195, & ! 70 + 35, 163, -13, 99, 19, 147, 83, 211, -14, 51, & ! 80 + 179, 115, 11, 139, -15, 75, 203, 43, 171, 107, & ! 90 + -16, 27, 155, 91, 59, 187, -17, 123, 7, 135, & !100 + 71, 199, -18, 39, 167, 103, 23, 151, -19, 87, & !110 + 215, 55, 183, 119, -20, 15, 143, 79, 207, 47, & !120 + -21, 175, 111, 31, 159, 95, -22, 63, 191, 127, & !130 + 2, 130, -23, 66, 194, 34, 162, 98, -24, 18, & !140 + 146, 82, 210, 50, -25, 178, 114, 10, 138, 74, & !150 + -26, 202, 42, 170, 106, 26, -27, 154, 90, 58, & !160 + 186, 122, -28, 6, 134, 70, 198, 38, -29, 166, & !170 + 102, 22, 150, 86, -30, 214, 54, 182, 118, 14, & !180 + -31, 142, 78, 206, 46, 174, -32, 110, 30, 158, & !190 + 94, 62, -33, 190, 126, 4, 132, 68, -34, 196, & !200 + 36, 164, 100, 20, -35, 148, 84, 212, 52, 180, & !210 + -36, 116, 12, 140, 76, 204, -37, 44, 172, 108, & !220 + 28, 156, -38, 92, 60, 188, 124, 8, -39, 136, & !230 + 72, 200, 40, 168, -40, 104, 24, 152, 88, 56, & !240 + -41, 184, 120, 16, 144, 80, -42, 208, 48, 176, & !250 + 112, 32, -43, 160, 96, 64, 192, 128/ + save + + if(ndir.gt.0) then + do i=1,258 + j=indx(i) + if(j.lt.0) ichan(i)=isync(-j) + if(j.gt.0) ichan(i)=idat(j) + enddo + else + do i=1,258 + j=indx(i) +! if(j.lt.0) isync(-j)=ichan(i) + if(j.gt.0) idat(j)=ichan(i) + enddo + endif + +end subroutine scr258 diff --git a/mainwindow.cpp b/mainwindow.cpp index 7725a2fe6..429a49f15 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -10,7 +10,7 @@ #define NFFT 32768 -short int iwave[60*11025]; //Wave file for Tx audio +short int iwave[30*48000]; //Wave file for Tx audio int nwave; //Length of Tx waveform bool btxok; //True if OK to transmit double outputLatency; //Latency in seconds @@ -1236,12 +1236,15 @@ void MainWindow::guiUpdate() ba2msg(ba,message); int len1=22; - -//### Wrong mode! +/* + //### Wrong mode! int mode65=m_mode65; double samfac=1.0; gen65_(message,&mode65,&samfac,&nsendingsh,msgsent,iwave,&nwave,len1,len1); +*/ + genjtms3_(message,msgsent,iwave,&nwave,len1,len1); msgsent[22]=0; + qDebug() << msgsent << nwave; if(m_restart) { QFile f("jtms3_tx.log"); diff --git a/mainwindow.h b/mainwindow.h index dea576588..c26c5f1e6 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -254,6 +254,9 @@ extern "C" { float* py, float s[], int* nkhz, int* nhsym, int* nzap, float* slimit, uchar lstrong[]); + void genjtms3_(char* message, char* msgsent, short iwave[], + int* nwave, int len1, int len2); + void gen65_(char* msg, int* mode65, double* samfac, int* nsendingsh, char* msgsent, short iwave[], int* nwave, int len1, int len2); diff --git a/soundout.cpp b/soundout.cpp index 41570f2bf..5c6c79bd8 100644 --- a/soundout.cpp +++ b/soundout.cpp @@ -8,7 +8,7 @@ extern "C" { extern float gran(); //Noise generator (for tests only) -extern short int iwave[60*11025]; //Wave file for Tx audio +extern short int iwave[30*48000]; //Wave file for Tx audio extern int nwave; extern bool btxok; extern double outputLatency; @@ -54,7 +54,7 @@ extern "C" int d2aCallback(const void *inputBuffer, void *outputBuffer, // t0=timeInfo->currentTime; } else { if(n != nminStart) { //Late start in new minute: compute starting index - ic=(int)(tstart*11025.0); + ic=(int)(tstart*48000.0); // ic0=ic; // t0=timeInfo->currentTime; // qDebug() << "B" << t0 << ic0; @@ -122,7 +122,7 @@ void SoundOutThread::run() outParam.suggestedLatency=0.05; outParam.hostApiSpecificStreamInfo=NULL; - paerr=Pa_IsFormatSupported(NULL,&outParam,11025.0); + paerr=Pa_IsFormatSupported(NULL,&outParam,48000.0); if(paerr<0) { qDebug() << "PortAudio says requested output format not supported."; qDebug() << paerr << m_nDevOut; @@ -135,7 +135,7 @@ void SoundOutThread::run() paerr=Pa_OpenStream(&outStream, //Output stream NULL, //No input parameters &outParam, //Output parameters - 12000.0, //Sample rate + 48000.0, //Sample rate FRAMES_PER_BUFFER, //Frames per buffer paClipOff, //No clipping d2aCallback, //output callbeck routine