View Raw SPL
/*****************************************************************************
*                                                                            *
*   DEMODAM.SPL  Copyright (C) 2013 DSP Development Corporation              *
*                               All Rights Reserved                          *
*                                                                            *
*   Author:      Randy Race                                                  *
*                                                                            *
*   Synopsis:    AM Demodulation using low pass filtering                    *
*                                                                            *
*   Revisions:   12 Mar 2013  RRR  Creation                                  *
*                                                                            *
*****************************************************************************/

#if @HELP_DEMODAM

    DEMODAM

    Purpose: Demodulates an AM series using low pass filtering.

    Syntax:  DEMODAM(s, fc, bw)

               s - A series, the amplitude modulated input series.

              fc - Optional, a real. The carrier frequency. If not specified,
                   fc is estimated in the frequency domain.

              bw - Optional, a real. The input bandwidth. If not specified,
                   defaults to fc, the carrier frequency.

    Returns: A series or array

    Example:
             W1: gsin(1000, 1/1000, 2)^3
             W2: gcos(length(W1), deltax(W1), 200)
             W3: W1 * W2
             W4: demodam(w3, 200)

             W1 contains the source series to modulate. W2 contains the
             carrier frequency. W3 performs the amplitude modulation by
             multiplying the source series by the carrier. W4 performs
             amplitude demodulation by multiplying the AM series by
             the carrier and low pass filtering the result.

    Example:
             W1: integ(gnorm(10000, 1/10000)) * 10000
             W2: modam(w1, 1500)
             W3: demodam(w2, 1500)
             W4: demodam(w2, 1500, 200)

             W1 contains synthesized data. W2 amplitude modulates the
             data with a carrier frequency of 1500 Hz. Both W3 and W4
             demodulate the amplitude modulated series, but W4
             specifies that the input bandwidth is 200 Hz.

    Remarks:
             AM demodulation is performed by multiplying the input by
             the carrier frequency and filtering the result with a
             linear phase low pass filter.

             If the carrier frequency is not specified, DEMODAM uses
             SINFIT3 to estimate the carrier from the FFT and
             analytical rectangular window interpolation. However,
             because slight deviations of the estimated carrier from
             the actual carrier can cause large output discrepancies,
             it is best to specify the carrier if known.

             The input bandwidth parameter, bw, determines the cutoff
             frequency of the low pass filter used to demodulate the
             input.

             DEMODAM requires DADiSP/Filters to construct the FIR linear
             phase low pass filter used to demodulate the input.

             See MODAM to amplitude modulate a series.

             See DEMODFM to demodulate a frequency modulated series.

    See Also:
             Demodfm
             Modam
             Modfm
             Sinfit3
#endif


/* AM demodulation via low pass filtering */
ITERATE demodam(s, fc, bw)
{
        local f, y, fit, coef;

        if (argc < 3)
        {
                if (argc < 2)
                {
                        if (argc < 1) error("demodam - input series required");

                        /* find carrier frequency via sinfit */
                        (fit, coef) = sinfit3(s);

                        fc = coef[2];
                }

                /* bandwidth defaults to carrier frequency */
                bw = fc;
        }

        /* multiply by carrier */
        y = s * gcos(length(s), deltax(s), fc);

        /* lowpass filter */
        f = kwlpass(rate(y), bw, bw*1.01, 60);
        y = 2 * firfilterf(y, f);

        /* sample rate and offset */
        setdeltax(y, deltax(s));
        setxoffset(y, xoffset(s));

        return(y);
}