#include <math.h>
#include <stdio.h>
#include <sys/soundcard.h>
#include "OscBank.h"
#include "miditabl.h"
#include "MIDIInpt.h"
#include "RTWvOut.h"

// set this to 1 to have volume and amplitude
// control side by side.
#define ADJACENT 0

main(int argc, char** argv)
{
  int i, DELTA=1, j, oneOn=0;
  int INHARM=1;			// A flag determininig whether we are controlling
				// frequencies or inharmonic factor.
  int N = 1, over = 1;
  double freq=400, temp, temp2, out;
  RTWvOut output;
  OscBank *o;
  MIDIInpt controller;
  DataWindow *data;

  double INH_range = 1.1;	// For controlling inharmonicity
  //double INH_mult = log(INH_range)/128;
  double INH_mult = (INH_range-1)/127;
  
  if (argc>1) 
    N = atoi(argv[1]);

  if (argc>2)
    INHARM = atoi(argv[2]);

  if (N>MAXOSC) N = MAXOSC;
  o = new OscBank(N, freq);

  data = new DataWindow(N*2+1, "Additive synthesis", 200, 200);
  char st[20];
  data->SetName(0, "Fundamental");
  data->SetValue(0, &o->f0);
  for(i=1; i<=N; i++)
  {
    if (INHARM) {
      sprintf(st, "deviation(%d)", i);
      data->SetName(i, st);
      data->SetValue(i, &o->inhCoeff[i-1]);
    }
    else
    {
      sprintf(st, "f%d", i);
      data->SetName(i, st);
      data->SetValue(i, &o->o[i-1]->f);
    }
    sprintf(st, "A%d", i);
    data->SetName(i+N, st);
    data->SetValue(i+N, &o->o[i-1]->A);     
  }

  data->Update();

  //  printf("o->f0 is %f\n", o->f0);
  while(1)
  {
    if (controller.nextMessage() > 0) {
      temp2 = controller.getByteThree();
      temp = controller.getByteTwo();	

      if ((controller.getType()==MIDI_NOTEON) && (temp2>=1.0))
      {
	  j = (int) temp;
	  temp = __MIDI_To_Pitch[j];
	  //          printf("NoteOn    %4.2fHz %f\n",temp,temp2);
       	  oneOn += 1;
	  o->setFreq(temp);
	  data->Update();
	  //	  printf("o->f0 is %f\n", float(o->f0));
      }
      else if (controller.getType()==MIDI_NOTEOFF)	{
	if (temp2 < 2.0) temp2 = 64.0;
	if (oneOn ==1) {
	  //	  printf("NoteOff         0.0 1 %f %f\n",temp,temp2);
	}
	oneOn -= 1;
      }

      else if (controller.getType() == MIDI_CTL_CHANGE)
      {
	j = (int) temp;

	if (j<N*2) {
	  if (ADJACENT) {	// Adjacent control of freq and amp
	    if (j%2)
	      o->setAmp(j/2, temp2/128);
	    else
	      if (INHARM)
		o->setInharm(j/2, 1+temp2*INH_mult);
	      else
		o->setFreq(j/2, (temp2+5)*20);
	  }
	  else {	        // Non-adjacent cotrol
	    if (j<N)	
	      if (INHARM)
		o->setInharm(j, 1+temp2*INH_mult);
	      else
		o->setFreq(j, (temp2+5)*20);
	    else
	      o->setAmp(j-N, temp2/128);
	  }
	   data->Update();
	}
      }
    }

    for (i=0;i<DELTA;i++)
    {
      output.tick(o->tick()/N);
    }
  }
}













