Listing 1

/************************
Description: This function implements a continuous loop for a 
             Phase Modulation Receiver.
Parameters:  frequency -- the center frequency of the IF (in Hz)
 	     bandwidth  the IF bandwidth (in Hz)
Inputs:      one sample per loop from the input sampling process
Outputs:     one sample per loop to the output process
Returns:     nothing
Notes:	     this function assumes that a multi-tasking kernel allows
	     this function to operate as a task that cooperates with the
	     input sampling task and the output presentation task. This function waits
	     for the sampling process to give it a single sample at the beginning 
             of each sample period.  This function processes the samples and decodes 
             them into a baseband signal that is sent out one sample per sample period.
************************/
void PM_receiver(int frequency, int bandwidth)
{
int input_sample, output_sample;
int phase_detector_sample;

  // set up the IF bandpass filter for the center frequency, bandwidth, and 27 filter taps
  setup_IF_bandpass_filter(frequency, bandwidth, 27);
  // set up the baseband bandpass filter for 300 Hz low frequency, 3000 Hz high frequency, 
  // and 27 filter taps
  setup_baseband_filter(300, 3000, 27);
  // initialize the peak detector moving average
  last_peak = 0;
  average_index = 0;
  // the main loop for the demodulator
  do
  {
    input_sample = wait_for_sample();
    // we re-use the input sample variable because it is already in a register
    input_sample = IF_filter(input_sample);
    // perform the function to adjust the phase detector reference
    phase_detector_sample = PM_lock_phase();
    // Clip the IF signal
    input_sample = angle_modulation_clipper(input_sample);
    // do the demodulation
    output_sample = input_sample * phase_detector_sample;
    // filter the baseband
    output_sample = baseband_filter(output_sample);
    // send the output sample to the consuming task
    send_output_sample(output_sample);
  } while (PM_active());
}


Listing 2
/************************
Description:	This function implements a continuous loop for a 
Phase Modulation Receiver.
Parameters:	frequency -- the center frequency of the IF (in Hz)
 		Bandwidth  the IF bandwidth (in Hz)
Inputs: 	one sample per loop from the input sampling process
Outputs: 	one sample per loop to the output process
Returns: nothing
Notes:		this function assumes that a multi-tasking kernel allows
		this function to operate as a task that cooperates with the
		input sampling task and the output presentation task. This function waits
		for the sampling process to give it a single sample at the beginning of each sample
		period.  This function processes the samples and decodes them into a baseband
		signal that is sent out one sample per sample period.
************************/
Void FM_demodulator(int frequency, int bandwidth)
{
int input_sample, output_sample;
int n_minus_2, n_minus_1;

  // set up the IF bandpass filter for the center frequency, bandwidth, and 27 filter taps
  setup_IF_bandpass_filter(frequency, bandwidth, 27);
  // set up the baseband bandpass filter for 300 Hz low frequency, 3000 Hz high frequency, 
  // and 27 filter taps
  setup_baseband_filter(300, 3000, 27);
  // the main loop for the demodulator
  do
  {
    input_sample = wait_for_sample();
    // we re-use the input sample variable because it is already in a register
    input_sample = IF_filter(input_sample);
    // Clip the IF signal
    input_sample = angle_modulation_clipper(input_sample);
    // do the demodulation
    output_sample = input_sample * n_minus_2;
    n_minus_2 = n_minus_1;
    n_minus_1 = input_sample;
    // filter the baseband
    output_sample = baseband_filter(output_sample);
    // send the output sample to the consuming task
    send_output_sample(output_sample);
  } while (FM_active());
}

Listing 3
/************************
Description:	This function implements the limiter function that is 
                common to PM and FM demodulation
Parameters:	input_sample -- the current IF signal sample
Inputs: 	running average of previous peak samples
Outputs: 	Updated running average of peak samples
Returns:        clipped IF sample
Notes:		this function is different from most in that the variables
		have static allocation. This is necessary to hold the 
		history of the incoming samples.

************************/
int angle_modulation_clipper(int input_sample)
{
static int last_peak, moving_average[8], average_index, this_peak_candidate, average_peak;

    average_index &= 7; // this is never initialized so this keeps it in range
    this_peak_candidate = abs(input_sample);
    if (this_peak_candidate < last_peak)
    {
      // store this peak in the moving average
      moving_average[average_index] = this_peak_candidate;
      average_index++;
      // Reset the peak detector
      last_peak = 0;
      // wrap the average array index
      average_index &= 7;
      average_peak = moving_average[0] + moving_average[1] + moving_average[2] +
                     moving_average[3] + moving_average[4] + moving_average[5] +
                     moving_average[6] + moving_average[7];
      // divide the accumulated value by 8
      average_peak >>= 3;  
    }
    else
    {
      last_peak = this_peak_candidate;
    }
    // apply the gain
    if (average_peak > 1024)
    {
       input_sample *= 4;
    }
    if (average_peak > 512)
    {
       input_sample *= 8;
    }
    // clip the waveform
    if (input_sample > 250)
    {
       input_sample = 250;
    }
    if (input_sample < -250)
    {
       input_sample = -250;
    }
    return (input_sample);
}