#include "OscBank.h"
#include <stdio.h>
#include <math.h>

OscBank :: OscBank(int N, double aF)
{
  f0 = aF;
  if (N<1) N=1;
  if (N>MAXOSC) N=MAXOSC;

  Nosc = N;
  o = new (Osc*)[Nosc];
  inhCoeff = new double[Nosc];

  A=1; R=0;
  for (int i=0; i<Nosc; i++)
  {
    inhCoeff[i] = 1;
    o[i] = new Osc(f0*(i+1), exp(-i));
  }
}

OscBank :: ~OscBank()
{
}

void OscBank :: setFreq(double aF)
{
  f0 = aF;
  for (int i=0; i<Nosc; i++)
  {
    o[i]->setFreq(f0*(i+1)*inhCoeff[i]);
  }
}

void OscBank :: setFreq(int i, double aF)
{
  if ((i<Nosc) && (i>=0)) {    
    o[i]->setFreq(aF);
    inhCoeff[i] = aF/(f0*(i+1));
  }
}

void OscBank :: setInharm(int i, double inh)
{
  if ((i<Nosc) && (i>=0)) {    
    inhCoeff[i] = inh;
    o[i]->setFreq(f0*(i+1)*inh);
  }
}

#ifndef log2
#define log2(x) (log(double(x))/0.69314718)
#endif
/*
#ifndef pow
#define pow(x,y) (exp((y)*ln(x)))
#endif
*/
void OscBank :: setStretch(double h)
{
  double inh;
  
  for (int i=1; i<Nosc; i++)
  {
    inh = pow(h, log2(i));
    inhCoeff[i] = inh/(i+1);
    o[i]->setFreq(inh*f0);
  }
}

void OscBank :: setAmp(int i, double aA)
{
  if ((i<Nosc) && (i>=0)) {    
    o[i]->setAmp(aA);
  }
}

void OscBank :: setAmp(double aA)
{
  A = aA;
  for (int i=0; i<Nosc; i++) {
    o[i]->setAmp(aA*exp(double(-R*i)));
  }
}

void OscBank :: setRolloff(double aR)
{
  R = aR;
  this->setAmp(A);
}

double OscBank :: tick()
{
  double out;

  out = 0;
  for (int i=0; i<Nosc; i++)
  {
    out += o[i]->tick();
  }
  return out;
}





