View Raw SPL
/*****************************************************************************
*                                                                            *
*   CAS2SOS.SPL  Copyright (C) 2015 DSP Development Corporation              *
*                               All Rights Reserved                          *
*                                                                            *
*   Author:      Randy Race                                                  *
*                                                                            *
*   Synopsis:    Converts cascade coefficients to second order section form  *
*                                                                            *
*   Revisions:   30 Jun 2015  RRR  Creation                                  *
*                                                                            *
*****************************************************************************/


#if @HELP_CAS2SOS

    CAS2SOS  

    Purpose: 
             Converts cascade coefficients to second order section form.
                                                                        
    Format:  
             CAS2SOS(c)

             (sos, g) = CAS2SOS(c)

                c - A series, the filter coefficients in cascade form.

    Returns: 
             A Nx6 column series, where the first 3 columns contain the
             numerator coefficients and the last three columns contain
             the denominator coefficients. Each row represents a 2nd order
             stage.

             (sos, g) = CAS2SOS(c) returns the Nx6 second order stages and
             gain in two separate variables.

    Example:
             c = {1, 1, 0, 0, -0.5, 0.2};
             (sos, g) = cas2sos(c);

             sos == {{1, 0, 0, 1, -0.5, 0.2}
             g == 1.0

             The 2nd order cascade filter coefficients represent the
             following Z transform:

                                -1       -2
                        1 + 0.0z   + 0.0z 
             H(z) = 1 * -------------------
                                -1       -2
                        1 - 0.5z   + 0.2z


             The resulting SOS form filter coefficients represent the
             same Z transform.

    Example:
             c = {1, 1, 0, 0, -0.754856, 0.392379, 1, 0, 0, 0.254856, 0};
             (sos, g) = cas2dir(c);

             sos == {{1, 0, 0, 1, -0.754856, 0.292379},
                     {1, 0, 0, 1,  0.254856, 0}}

             g == 1.0

             The 2nd order cascade filter coefficients represent the
             following 2 stage cascaded Z transform:

                                     -1       -2
                             1 + 0.0z   + 0.0z 
             H(z) = 1 * ----------------------------
                                     -1            -2
                        1 - 0.754856z   + 0.392379z


                                     -1       -2
                             1 + 0.0z   + 0.0z 
                      * ------------------------
                                     -1       -2
                        1 - 0.254856z   + 0.0z


             The resulting SOS form coefficients represent the same Z
             transform.

    Remarks:
             CAS2SOS converts cascade form filter coefficients to second
             order section form. Both forms represent the following
             Z transform: 
  

                               -1       -2                -1       -2
                    b10 + b11 z  + b12 z       b20 + b21 z  + b22 z
         H(z) = G * ________________________ *  ________________________ ...
                               -1       -2                -1       -2
                      1 + a11 z  + a12 z         1 + a21 z  + a22 z


             where the cascade coefficients are represented as a single
             column series with the coefficients in the following order:

             G, b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...

             and the SOS form is an Nx6 array:

             {{b10, b11, b12, 1, a11, a12},
              {b20, b21, b22, 1, a21, a22}, 

                            ...

              {bN0, bN1, bN2, 1, aN1, aN2}} 

             Each row of the SOS coefficients represents a second order stage.

             See SOS2CAS to convert SOS form coefficients to cascade form.

    See Also:
             Cas2tf
             Cascade
             Sos2cas
             Sos2zp
#endif


/* converts cascade coefficients into a Nx6 array */
cas2sos(c)
{
        local m, gain, bn, an;

        if (argc < 1)
        {
                c = {};
        }

        /* force series */
        c = {c};

        if ((length(c) - 1) % 5 != 0)
        {
                error("cas2sos - improper cascade series");
        }

        /* gain */
        gain = c[1];

        /* coefficients (no gain term) */
        m = extract(c, 2, -1);

        /* each column a stage */
        m = ravel(m, 5);

        /* numerator */
        bn = extract(m, 1, 3)';

        setcomment(bn, "Num", -1);
        setdeltax(bn, deltax(c));

        /* denominator */
        an = {ones(1, numcols(m)), extract(m, 4, 2)}';

        setcomment(an, "Den", -1);
        setdeltax(an, deltax(c));

        if (outargc == 3)
        {
                /* return separate Nx3 arrays */
                return(bn, an, gain);
        }
        else if (outargc == 2)
        {
                return(ravel(bn, an), gain);
        }
        else
        {
                bn[1, ..] *= gain;
                return(ravel(bn, an));
        }
}