*------------- Telecommunications & Signal Processing Lab --------------
*                          McGill University
*
*
* Module:
*     REAL FUNCTION GDLCAS (F, H, NSECT)
*
*
* Purpose:
*     Find the group delay for an analog cascade filter
*
*
* Description:
*     This function calculates the group delay of a cascade analog
*     filter specified by its coefficients.  The filter is a cascade
*     of second order sections, with the Laplace transform of the i'th
*     filter section given as
*
*                h(1,i)*s**2 + h(2,i)*s + h(3,i)
*       H(i,s) = ------------------------------- .
*                   s**2 + h(4,i)*s + h(5,i)
*
*     The group delay in seconds at frequency f for the filter is
*     calculated as
*
*       T = GDLCAS(f,H,NSECT) .
*
*     If the given frequency corresponds to an uncancelled pole or zero
*     of the response, a warning message is printed and the group delay
*     is set to 1E20 for zeros and -1E20 for poles.
*
*
* Parameters:
* R <-  GDLCAS - Group delay in seconds
*
* R ->  F      - Frequency
* R ->  H      - Array of groups of 5 filter coefficients, each
*                defining a biquadratic filter section
* I ->  NSECT  - Number of filter sections
*
*
* Author / revision:
*     P. Kabal
*     $Revision: 1.5 $  $Date: 1995/03/08 15:21:08 $
*
*
*-----------------------------------------------------------------------

      REAL FUNCTION GDLCAS (F, H, NSECT)


      REAL PI2
      PARAMETER (PI2=6.283 185 307)

      INTEGER NSECT
      INTEGER NZ,K

      REAL F
      REAL W,B2,B1,B0,C2,C1,C0,RW,RPW,XW,XPW,
     -     ANUM,ADEN
      REAL H(5,*)


* Add the group delay of each second order section
      W = PI2*F
      NZ = 0
      GDLCAS = 0.0

      DO 100 K=1,NSECT

* The transfer function is
*
*                b2*s**2 + b1*s + b0   B(s)
*         H(s) = ------------------- = ----
*                  s**2 + c1*s + c0    C(s)
*

* If the constant terms are zero, cancel an s term between numerator
* and denominator
        IF (H(3,K).EQ.0.0 .AND. H(5,K).EQ.0.0) THEN
          B2 = 0.0
          B1 = H(1,K)
          B0 = H(2,K)
          C2 = 0.0
          C1 = 1.0
          C0 = H(4,K)
        ELSE
          B2 = H(1,K)
          B1 = H(2,K)
          B0 = H(3,K)
          C2 = 1.
          C1 = H(4,K)
          C0 = H(5,K)
        END IF

* The group delay for H(jw) is the group delay for the numerator
* term less the group delay for the denominator term.  On the
* imaginary axis express the numerator term as B(jw) = R(w) + jX(w).
* The group delay for the numerator term for w=2Pi f is
*
*               d arctan(X(w)/R(w))      X'(w)R(w)-R'(w)X(w)
*     Td(w) = - -------------------  = - ------------------- ,
*                d w                      R(w)**2 + X(w)**2
*
* where X'(w) is the derivative of X(w) and R'(w) is the
* derivative of R(w).
* In the sequel, the numerator (and denominator) are expressed as
*
*       B(jw) =  b0  - b2 w**2 + j b1 w
*
*  Then
*
*       R(w)  = b0 - b2 w**2
*       R'(w) = -2 b2 w
*       X(w)  = b1 w
*       X'(w) = b1

* Delay due to numerator
        RW =B0-B2*W**2
        RPW=-2.*B2*W
        XW =B1*W
        XPW=B1
        ANUM = XPW*RW - RPW*XW
        ADEN = RW**2 + XW**2
        IF (ADEN.LE.0.0) THEN
          NZ = NZ+1
        ELSE
          GDLCAS = GDLCAS - ANUM/ADEN
        END IF

* Delay due to denominator
        RW =C0-C2*W**2
        RPW=-2.*C2*W
        XW =C1*W
        XPW=C1
        ANUM = XPW*RW - RPW*XW
        ADEN = RW**2 + XW**2
        IF (ADEN.LE.0.0) THEN
          NZ = NZ-1
        ELSE
          GDLCAS = GDLCAS + ANUM/ADEN
        END IF

 100  CONTINUE

      IF (NZ.NE.0) THEN
        CALL WARN('GDLCAS - Undefined delay')
        IF (NZ.GT.0) THEN
          GDLCAS = 1E20
        ELSE
          GDLCAS = -1E20
        END IF
      END IF


      RETURN

      END
