/*
  ZynAddSubFX - a software synthesizer

  metronome.C - Stereo LFO used by some effects
  Copyright (C) 2002-2005 Nasca Octavian Paul
  Author: Nasca Octavian Paul

  Modified for rakarrack by Josep Andreu 6 Ryan Billing


  This program is free software; you can redistribute it and/or modify
  it under the terms of version 2 of the GNU General Public License
  as published by the Free Software Foundation.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License (version 2) for more details.

  You should have received a copy of the GNU General Public License (version 2)
  along with this program; if not, write to the Free Software Foundation,
  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA

*/

#include "Metronome.h"

#ifdef SHR3D_SFX_CORE_RAKARRACK

Metronome::Metronome()
  : dulltick(4, 1600.0f, 80.0f, 1)   //BPF
  , sharptick(4, 2800.0f, 80.0f, 1)  //BPF
  , hpf(3, 850.0f, 60.0f, 1)  //HPF  
{
  tick_interval = SAMPLE_RATE;
  tickctr = 0;
  markctr = 0;
  ticktype = 4;
  meter = 3;
  tickper = lrintf(0.012f * fSAMPLE_RATE);
}

void Metronome::cleanup()
{
  tickctr = 0;
  markctr = 0;
  dulltick.cleanup();
  sharptick.cleanup();
  hpf.cleanup();
}

void Metronome::set_tempo(i32 bpm)
{
  const f32 tickperiod = 60.0f / ((f32)bpm);
  tick_interval = lrintf(fSAMPLE_RATE * tickperiod);
}

void Metronome::set_meter(i32 counts)  //how many counts to hear the "mark"
{
  ticktype = counts; //always dull if 0, always sharp if 1, mark on interval if more
  if (counts < 1) counts = 1;
  meter = counts - 1;
}

void Metronome::metronomeout(f32* tickout, const i32 blockSize)
{
  f32 ticker = 0.0f;

  for (i32 i = 0; i < blockSize; i++)
  {
    tickctr++;

    if (tickctr > tick_interval)
    {
      tickctr = 0;
      markctr++;
      if (markctr > meter) markctr = 0;
    }
    if (tickctr < tickper)
      ticker = 1.0f;
    else
      ticker = 0.0f;

    f32 hipass = hpf.filterout_s(ticker);

    if (hipass > 0.5f)
      hipass = 0.5f;
    if (hipass < -0.5f)
      hipass = -0.5f;
    const f32 outdull = dulltick.filterout_s(hipass);
    const f32 outsharp = sharptick.filterout_s(hipass);

    switch (ticktype)
    {
    case 0:
      tickout[i] = 1.25f * outdull;
      break;
    case 1:
      tickout[i] = 0.65f * outsharp;
      break;
    default:
      if (markctr == 0)
      {
        tickout[i] = 0.65f * outsharp;
      }
      else
      {
        tickout[i] = 1.25f * outdull;
      }
      break;
    }
  }
}

#endif // SHR3D_SFX_CORE_RAKARRACK
