subroutine refspectrum(id2,bclear,brefspec,buseref,fname)

! Input:
!  id2       i*2        Raw 16-bit integer data, 12000 Hz sample rate
!  brefspec  logical    True when accumulating a reference spectrum

  parameter (NFFT=6912,NH=NFFT/2,NPOLYLOW=400,NPOLYHIGH=2600)
  integer*2 id2(NFFT)
  logical*1 bclear,brefspec,buseref,blastuse
  
  real xs(0:NH-1)                         !Saved upper half of input chunk convolved with h(t) 
  real x(0:NFFT-1)                        !Work array
  real*4 w(0:NFFT-1)                      !Window function
  real*4 s(0:NH)                          !Average spectrum
  real*4 fil(0:NH)
  real*8 xfit(1500),yfit(1500),sigmay(1500),a(5),chisqr !Polyfit arrays
  logical first
  complex cx(0:NH)                        !Complex frequency-domain work array
  complex cfil(0:NH)
  character*(*) fname
  common/spectra/syellow(6827),ref(0:NH),filter(0:NH)
  equivalence(x,cx)
  data first/.true./,blastuse/.false./
  save

  if(first) then
     pi=4.0*atan(1.0)
     do i=0,NFFT-1
        ww=sin(i*pi/NFFT)
        w(i)=ww*ww/NFFT
     enddo
     nsave=0
     s=0.0
     filter=1.0
     xs=0.
     first=.false.
  endif
  if(bclear) s=0.

  if(brefspec) then
     x(0:NH-1)=0.001*id2(1:NH)
     x(NH:NFFT-1)=0.0
     call four2a(cx,NFFT,1,-1,0)                 !r2c FFT

     do i=1,NH
        s(i)=s(i) + real(cx(i))**2 + aimag(cx(i))**2
     enddo
     nsave=nsave+1

     fac0=0.9
     if(mod(nsave,4).eq.0) then
        df=12000.0/NFFT
        ia=nint(1000.0/df)
        ib=nint(2000.0/df)
        avemid=sum(s(ia:ib))/(ib-ia+1)
        do i=0,NH
           fil(i)=0.
           if(s(i).gt.0.0) then
              fil(i)=sqrt(avemid/s(i))
           endif
        enddo

! Default range is 240 - 4000 Hz.  For narrower filters, use frequencies
! at which gain is -20 dB relative to 1500 Hz.
        ia=nint(240.0/df)
        ib=nint(4000.0/df)
        i0=nint(1500.0/df)
        do i=i0,ia,-1
           if(s(i)/s(i0).lt.0.01) exit
        enddo
        ia=i
        do i=i0,ib,1
           if(s(i)/s(i0).lt.0.01) exit
        enddo
        ib=i

        fac=fac0
        do i=ia,1,-1
           fac=fac*fac0
           fil(i)=fac*fil(i)
        enddo

        fac=fac0
        do i=ib,NH
           fac=fac*fac0
           fil(i)=fac*fil(i)
        enddo

        do iter=1,100                        !### ??? ###
           call smo121(fil,NH)
        enddo

        do i=0,NH 
           filter(i)=-60.0
           if(s(i).gt.0.0) filter(i)=20.0*log10(fil(i))
        enddo

        il=nint(NPOLYLOW/df)
        ih=nint(NPOLYHIGH/df)
        nfit=ih-il+1
        mode=0
        nterms=5
        do i=1,nfit
          xfit(i)=((i+il-1)*df-1500.0)/1000.0
          yfit(i)=fil(i+il-1)
          sigmay(i)=1.0
        enddo
        call polyfit(xfit,yfit,sigmay,nfit,nterms,mode,a,chisqr)

        open(16,file=fname,status='unknown')
        write(16,1003) NPOLYLOW,NPOLYHIGH,nterms,a
1003    format(3i5,5e25.16)
        do i=1,NH
           freq=i*df
           ref(i)=db(s(i)/avemid)
           write(16,1005) freq,s(i),ref(i),fil(i),filter(i)
1005       format(f10.3,e12.3,f12.6,e12.3,f12.6)
        enddo
        close(16)
     endif
     return
  endif

  if(buseref) then
     if(blastuse.neqv.buseref) then !just enabled so read filter
        fil=1.0
        open(16,file=fname,status='old',err=999)
        read(16,1003,err=20,end=999) ndummy,ndummy,nterms,a
        goto 30
20      rewind(16)              !allow for old style refspec.dat with no header
30      do i=1,NH
           read(16,1005,err=999,end=999) freq,s(i),ref(i),fil(i),filter(i)
        enddo
! Make the filter causal for overlap and add.
        cx(0)=0.0
        cx(1:NH)=fil(1:NH)/NFFT
        call four2a(cx,NFFT,1,1,-1)
        x=cshift(x,-400)
        x(800:NH)=0.0
        call four2a(cx,NFFT,1,-1,0)
        cfil=cx
        close(16)
     endif
! Use overlap and add method to apply causal reference filter.
     x(0:NH-1)=id2(1:NH)
     x(NH:NFFT-1)=0.0
     x=x/NFFT
     call four2a(cx,NFFT,1,-1,0)
     cx=cfil*cx
     call four2a(cx,NFFT,1,1,-1)
     x(0:NH-1)=x(0:NH-1)+xs    
     xs=x(NH:NFFT-1)
     id2(1:NH)=nint(x(0:NH-1))
  endif
  blastuse=buseref

999 return
end subroutine refspectrum
