*------------- Telecommunications & Signal Processing Lab --------------
*                          McGill University
*
*
* Module:
*     REAL FUNCTION GDLSEC (B2, B1, B0, COSW, SINW)
*
*
* Purpose:
*     Find the group delay for a quadratic function
*
*
* Description:
*     This function calculates the group delay for a quadratic function
*     of the form,
*
*       B(z) = b2*z**2 + b1*z + b0 .
*
*     If the function is evaluated on the unit circle with z=exp(jw),
*
*       B(w) = exp(jw) [ (b2+b0)*cosw + b1 + j(b2-b0)*sinw ] .
*
*     The group delay is the negative derivative with respect to w of
*     the phase angle of this function.  If the polynomial has zero
*     coefficients, the group delay is set to zero.  Note that since
*     the polynomial is a function of positive powers of z, where z
*     can be interpreted to be a time advance of -1 samples, the group
*     delay is generally a negative value.
*
*
* Parameters:
* R <-  GDLSEC - Group delay in samples
*
* R ->  B2     - First polynomial coefficient
* R ->  B1     - Second polynomial coefficient
* R ->  B0     - Third polynomial coefficient
* R ->  COSW   - Cosine of the normalized angular frequency
* R ->  SINW   - Sine of the normalized angular frequency
*
*
* Author / revision:
*     P. Kabal
*     $Revision: 1.3 $  $Date: 1995/03/08 15:22:29 $
*
*
*-----------------------------------------------------------------------

      REAL FUNCTION GDLSEC (B2, B1, B0, COSW, SINW)


      REAL B2,B1,B0,COSW,SINW
      REAL RW,RPW,XW,XPW


* The polynomial is
*   B(z) = b2*z**2 + b1*z + b0
* On the unit circle, z=exp(jw), express the function as
*   B(w) = R(w) + jX(w),
* where
*
*       B(w) = exp(jw) [ (b2+b0)cosw + b1 + j (b2-b0)sinw ]
*
* The exponential term adds a delay of -1 sample.  Neglecting this
* exponential term,
*       R(w)  = b1 + (b2+b0)cosw
*       X(w)  = (b2-b0)sinw
* The group delay 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),
*       R'(w) = -(b2+b0)sinw
*       X'(w) = (b2-b0)cosw

* Roots on the unit circle present computational problems.  It can be
* verified that the group delay is continuous through the roots.  For
* that reason, the following code detects roots on the unit circle and
* handles them as special cases.  For instance conjugate roots give
* rise to a symmetrical polynomial, which has a constant group delay.
* For values near but not on the roots, numerical problems can still
* occur.

* The behaviour of the group delay for roots near the unit circle, but
* not on it is very different.  In this case the group delay can be
* very large.  Consider B(z) = (1+e) z**2 + 1.  The group delay for
* w=pi, works out to be -1 - (2+e)/e .

* Symmetric polynomial
* - includes the case with conjugate roots on the unit circle
      IF (B2.EQ.B0) THEN
        IF (B2.EQ.0.0 .AND. B1.EQ.0.0) THEN
          GDLSEC=0.0
        ELSE
          GDLSEC=-1.0
        END IF

* Root at z=1 (delay -0.5)
* - also handles the case of roots at both z=1 and z=-1 (b1=0)
* - the remaining polynomial is b2*z + b0
      ELSE IF (B2+B0.EQ.B1) THEN
        IF (B1.EQ.0.0) THEN
          GDLSEC=-1.0
        ELSE
          RW=B2+B0*COSW
          RPW=-B0*SINW
          XW=-B0*SINW
          XPW=-B0*COSW
          GDLSEC=-1.5-(XPW*RW - RPW*XW)/(RW**2 + XW**2)
        END IF

* Root at z=-1 (delay -0.5)
* - remaining polynomial is b2*z - b0
      ELSE IF (B2+B0.EQ.-B1) THEN
        RW=B2-B0*COSW
        RPW=B0*SINW
        XW=B0*SINW
        XPW=B0*COSW
        GDLSEC=-1.5-(XPW*RW - RPW*XW)/(RW**2 + XW**2)

* General case (no unit circle zeros)
      ELSE
        RW=B1+(B2+B0)*COSW
        RPW=-(B2+B0)*SINW
        XW=(B2-B0)*SINW
        XPW=(B2-B0)*COSW
        GDLSEC=-1.0-(XPW*RW - RPW*XW)/(RW**2 + XW**2)

      END IF

      RETURN

      END
