| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  | program mskber
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ! Generate an MSK waveform, pass it through an AWGN channel, apply coherent 
 | 
					
						
							|  |  |  | ! MSK receiver, and count number of errors at each Eb/No.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  |   parameter (MAXSYM=1000*1000)
 | 
					
						
							|  |  |  |   parameter (NSPS=5)                        !Samples per symbol
 | 
					
						
							|  |  |  |   real ct(-NSPS:NSPS*MAXSYM-1)              !cos(pi*t/2T)
 | 
					
						
							|  |  |  |   real st(-NSPS:NSPS*MAXSYM-1)              !sin(pi*t/2T)
 | 
					
						
							|  |  |  |   real r(0:MAXSYM-1)                        !Random numbers to set test bits
 | 
					
						
							|  |  |  |   real xsym(0:MAXSYM-1)                     !Soft Rx symbols
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   complex xt(-NSPS:NSPS*MAXSYM-1)           !Complex baseband Tx waveform
 | 
					
						
							|  |  |  |   complex nt(-NSPS:NSPS*MAXSYM-1)           !Generated AWGN channel noise
 | 
					
						
							|  |  |  |   complex yt(-NSPS:NSPS*MAXSYM-1)           !Received signal, yt = xt + fac*nt
 | 
					
						
							|  |  |  |   complex cwave(-NSPS:NSPS*MAXSYM-1)        !Audio waveform, Tx real part
 | 
					
						
							|  |  |  |   complex z
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   integer sym0(0:MAXSYM-1)                  !Generated test bits
 | 
					
						
							|  |  |  |   integer sym(0:MAXSYM-1)                   !Hard-copy received bits
 | 
					
						
							|  |  |  |   integer sym1(0:7)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   character*12 arg
 | 
					
						
							|  |  |  |   data sym1/1,1,0,0,0,1,1,1/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   nargs=iargc()
 | 
					
						
							|  |  |  |   if(nargs.ne.2) then
 | 
					
						
							|  |  |  |      print*,'Usage:  mskber nsym EbNo'
 | 
					
						
							|  |  |  |      go to 999
 | 
					
						
							|  |  |  |   endif
 | 
					
						
							|  |  |  |   call getarg(1,arg)
 | 
					
						
							|  |  |  |   read(arg,*) nsym
 | 
					
						
							|  |  |  |   call getarg(2,arg)
 | 
					
						
							|  |  |  |   read(arg,*) EbNo
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   pi=4.0*atan(1.0)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  |   do i=-NSPS,NSPS*nsym-1                  !Define ct, st arrays
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  |      t=i*pi/(2.0*NSPS)
 | 
					
						
							|  |  |  |      ct(i)=cos(t)
 | 
					
						
							|  |  |  |      st(i)=sin(t)
 | 
					
						
							|  |  |  |   enddo
 | 
					
						
							|  |  |  |   fac=1.0/sqrt(float(NSPS))
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  |   do iEbNo=0,10                                  !Loop over a range of Eb/No
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  |      sym0=0
 | 
					
						
							|  |  |  |      call random_number(r)
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  |      where(r(0:nsym-1).gt.0.5) sym0(0:nsym-1)=1  !Generate random data bits
 | 
					
						
							|  |  |  |      if(nsym.eq.8) sym0(0:nsym-1)=sym1
 | 
					
						
							|  |  |  |      call mskmod(sym0,nsym,NSPS,ct,st,xt,cwave)  !Generate Tx waveform
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  |      do i=-NSPS,NSPS*nsym-1                      !Generate Gaussian noise
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  |         xx=0.707*gran()
 | 
					
						
							|  |  |  |         yy=0.707*gran()
 | 
					
						
							|  |  |  |         nt(i)=cmplx(xx,yy)
 | 
					
						
							|  |  |  |      enddo
 | 
					
						
							|  |  |  |      fac_noise=10.0**(-iEbNo/20.0)
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  |      if(EbNo.ne.0.0) fac_noise=10.0**(-EbNo/20.0)
 | 
					
						
							|  |  |  |      yt=xt + fac_noise*nt                        !Rx signal, with noise
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  |      call mskdemod(yt,nsym,NSPS,ct,st,xsym)      !MSK demodulator
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |      sym=0
 | 
					
						
							|  |  |  |      where(xsym.gt.0.0) sym=1
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  |      if(nsym.le.160 .and. EbNo.ne.0.0) then
 | 
					
						
							|  |  |  |         write(*,1012) sym0(0:nsym-1)
 | 
					
						
							|  |  |  |         if(nsym.gt.50) write(*,1012) 
 | 
					
						
							|  |  |  |         write(*,1012) sym(0:nsym-1)
 | 
					
						
							|  |  |  | 1012    format(50i1)
 | 
					
						
							|  |  |  |         do i=-nsps,nsps*nsym-1
 | 
					
						
							|  |  |  |            phi=i*2.0*pi*1500/12000.0
 | 
					
						
							|  |  |  |            z=cwave(i)*cmplx(cos(phi),sin(phi))    !Mix back to baseband
 | 
					
						
							|  |  |  |            write(51,1014) float(i)/nsps,xt(i),abs(xt(i)),cwave(i),z
 | 
					
						
							|  |  |  | 1014       format(8f8.4)
 | 
					
						
							|  |  |  |         enddo
 | 
					
						
							|  |  |  |      endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  | ! Count the hard errors
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  |      nerr=count(sym(0:nsym-1).ne.sym0(0:nsym-1))
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  |      thber=0.5*erfc(10.0**(iEbNo/20.0))
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  |      xEbNo=iEbNo
 | 
					
						
							|  |  |  |      if(EbNo.ne.0.0) xEbNo=EbNo
 | 
					
						
							|  |  |  |      write(*,1000) xEbNo,thber,float(nerr)/nsym
 | 
					
						
							|  |  |  | 1000 format(f6.1,2f10.6)
 | 
					
						
							|  |  |  |      if(EbNo.ne.0.0) exit
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  |   enddo
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  | 999 end program mskber
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  | subroutine mskmod(sym,nsym,nsps,ct,st,xt,cwave)
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ! Generate MSK Tx waveform at baseband.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   integer sym(0:nsym-1)                   !Hard-copy received bits
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  |   complex xt(-nsps:nsps*nsym-1)           !Complex baseband Tx waveform
 | 
					
						
							|  |  |  |   complex cwave(-nsps:nsps*nsym-1)        !Audio waveform, fc=1500 Hz.
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  |   real ct(-nsps:nsps*nsym-1)              !cos(pi*t/2T)
 | 
					
						
							|  |  |  |   real st(-nsps:nsps*nsym-1)              !sin(pi*t/2T)
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  |   real ai(-nsps:nsps*nsym-1)              !Rectangular pulses for even symbols
 | 
					
						
							|  |  |  |   real aq(-nsps:nsps*nsym-1)              !Rectangular pulses for odd symbols
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  |   ai=0.
 | 
					
						
							|  |  |  |   aq=0.
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  |   fac=1.0/sqrt(float(nsps))
 | 
					
						
							|  |  |  |   do j=0,nsym-1,2
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  |      ia=(j-1)*nsps
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  |      ib=ia+2*nsps-1
 | 
					
						
							|  |  |  |      ai(ia:ib)=2*sym(j)-1                !Even bits as rectangular pulses
 | 
					
						
							|  |  |  |      aq(ia+nsps:ib+nsps)=2*sym(j+1)-1    !Odd bits as rectangular pulses
 | 
					
						
							|  |  |  |   enddo
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  |   xt=fac*cmplx(ai*ct,aq*st)                  !Baseband Tx waveform
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   twopi=8.0*atan(1.0)
 | 
					
						
							|  |  |  |   do i=-nsps,nsps*nsym-1
 | 
					
						
							|  |  |  |      phi=i*twopi*1500/12000.0
 | 
					
						
							|  |  |  |      cwave(i)=xt(i)*cmplx(cos(phi),-sin(phi))
 | 
					
						
							|  |  |  |   enddo
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return
 | 
					
						
							|  |  |  | end subroutine mskmod
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | subroutine mskdemod(yt,nsym,nsps,ct,st,xsym) 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ! MSK demodulator
 | 
					
						
							|  |  |  | ! Rx phase must be known and stable; symbol sync must be established.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  |   complex yt(-nsps:nsps*nsym-1)           !Received signal
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  |   real ct(-nsps:nsps*nsym-1)              !cos(pi*t/2T)
 | 
					
						
							|  |  |  |   real st(-nsps:nsps*nsym-1)              !sin(pi*t/2T)
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  |   real xe(-nsps:nsps*nsym-1)              !Temp array for received even symbols
 | 
					
						
							|  |  |  |   real xo(-nsps:nsps*nsym-1)              !Temp array for received odd symbols
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  |   real xsym(0:nsym-1)                     !Soft Rx symbols
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:57:17 +00:00
										 |  |  |   iz=nsps*(nsym+1)
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  |   xe(-nsps:nsps*nsym-1)=real(yt)*ct       !Apply matched filters
 | 
					
						
							|  |  |  |   xo(-nsps:nsps*nsym-1)=aimag(yt)*st
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  |   do j=0,nsym-1,2
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  |      ia=(j-1)*nsps
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  |      ib=ia+2*nsps-1
 | 
					
						
							| 
									
										
										
										
											2016-02-23 15:48:03 +00:00
										 |  |  |      xsym(j)=sum(xe(ia:ib))               !Integrate over 2 symbol lengths
 | 
					
						
							|  |  |  |      xsym(j+1)=sum(xo(ia+nsps:ib+nsps))
 | 
					
						
							| 
									
										
										
										
											2016-02-22 18:32:39 +00:00
										 |  |  |   enddo
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return
 | 
					
						
							|  |  |  | end subroutine mskdemod
 |