/************************************************************************
 *                                                                      *
 * Copyright (c) 2005 Synfora, Inc.  All rights reserved.               *
 *                                                                      *
 * This file contains Confidential Information of Synfora, Inc.         *
 * In addition, certain inventions disclosed in this file may be        *
 * claimed within patents owned or patent applications filed by         *
 * Synfora or third parties.  Any use of Synfora's copyrighted works,   *
 * confidential information, patented inventions, or patent-pending     *
 * inventions is subject to the terms and conditions of your written    *
 * license agreement with Synfora, Inc.                                 *
 * All other use and disclosure is strictly prohibited.                 *
 *                                                                      *
 ************************************************************************/

// Fir filter driver code

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "pico.h"
#include "fir.h" 
#include "fixed_point.h"


FILE *pfile2, *pfile3;

// Compute the weights for filtering.  For simplicity, I will use a rectangular
// window. 
void compute_weights(short w[], int num_weights, int cutoff_freq) {
  double srate = 1.0/SFREQ;
  double value;
  const float pi = 4*atan(1);

  double temp1, temp2;
  int halfway = (num_weights-1)/2;
  int k;

  for (k=0; k <= num_weights-1; k++) {
    if (k == halfway) {
      value = 2.0*cutoff_freq*srate;
    }
    else {
      temp1 = sin(2*pi*cutoff_freq*srate*(k-halfway));
      temp2 = pi*(k-halfway);
      value = temp1/temp2;
    }

    w[k] = d2w(value,BITSIZEW, EXPW, SIGNW);
  }
}

void pico_stream_output_y2(short val) {
  static int i = 0;
  fprintf(pfile2, "%f\n", w2d(val,BITSIZEY,EXPY,SIGNY));
  i++;
  if (i == (M2-N)) {
    i = 0;
  }
}

void pico_stream_output_y3(short val) {
  static int i = 0;
  fprintf(pfile3, "%f\n", w2d(val,BITSIZEY,EXPY,SIGNY));
  i++;
  if (i == (M2-N)) {
    i = 0;
  }
}

int
main() 
{
  int npaid;
  int h,i,j,k;
  FILE *pfile;
  int input_freq;

  double srate = 1.0/SFREQ;
  double value;
  const float pi = 4*atan(1);

  for (h=0; h < L; h++) {
    // For each task, create a different waveform as input for filtering
    input_freq = BASE_INPUT_FREQ + 10*h;

    for (i=0; i < M; i++) {
      // Make the input a sum of frequencies in multiples of
      // input_freq hz, all the way to the max frequency, SFREQ/2.
      // Then, all frequencies below FREQ should be filtered away.
      value = 0;
      for (j=input_freq; j < SFREQ/2; j+=input_freq) {
        value += cos(2*pi*j*srate*i);  // sample a cosine wave
      }

      // Convert the double "value" into fixed point
      x[h][i] = d2w(value,BITSIZEX,EXPX,SIGNX);
    }
  }

  compute_weights(w,  N, FREQ1);
  compute_weights(w2, N, FREQ2);

  // init all values
  for (h=0; h < L; h++) {
    for (i=0; i < M2-N; i++)
      y2[h][i] = 0;

    for (i=0; i < M2-N; i++)
      y3[h][i] = 0;
  }
  
  pfile = fopen("x.dat", "w");
  pfile2 = fopen("y2.dat", "w");
  pfile3 = fopen("y3.dat", "w");

  npaid = PICO_initialize_NPA (fir);
  PICO_set_task_overlap(npaid,2);

  for (h=0; h < L; h++) {
    task_num = h;
    fir();
  }

  PICO_sync_task(npaid, 0);
  PICO_finalize_NPA (npaid);
    
  for (h=0; h < L; h++) {
    for (i=0; i < M2-N; i++) {
      fprintf(pfile, "%3f %f\n", (h*(M2-N) + i)*srate, w2d(x[h][i],BITSIZEX,EXPX,SIGNX));
    }
  }

  fclose(pfile);
  fclose(pfile2);
  fclose(pfile3);

  return 0;
}
