Subversion Repositories DIN Is Noise

Rev

Rev 1807 | Rev 1809 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
* modulator.cc
* DIN Is Noise is copyright (c) 2006-2021 Jagannathan Sampath
* DIN Is Noise is released under GNU Public License 2.0
* For more information, please visit https://dinisnoise.org/
*/


#include "multi_curve.h"
#include "modulator.h"
#include "audio.h"
#include "chrono.h"
#include "drone.h"
#include "ui_list.h"

extern float TWO_PI;
extern const char spc;

mod_params::mod_params (multi_curve* c, int i, point<float>& p, const std::string& n) {

  setdir (i, &p.x, &p.y);

  bv.name = n;
  bv.crv = c;
  bv.setup ();
  depth = result = initial = 0;

}

void mod_params::clear () {
  depth = 0;
  result = 0;
  initial = 0;
  bv.set_bpm (bv.bpm);
}

void mod_params::calc (double dt) {
  bv.delta = dt * bv.bps;
  result = depth * bv.sol (bv.now, bv.delta);
}

void mod_params::calcdir (drone& dd) {
  float* px [] = {&vertical.x, &horizontal.x, &dd.vx, &dd.ax};
  float* py [] = {&vertical.y, &horizontal.y, &dd.vy, &dd.ay};
  dirx = px[id];
  diry = py[id];
}

autorotator::autorotator (defvelaccel& d) : autoflip(d) {

  yes = d.autos.rot.yes;

  int i = 0;
  if (d.autos.rot.dir == RANDOM) i = get_rand_bit (); else i = d.autos.rot.dir;
  static const int dirs [] = {-1, 1};
  dir = dirs[i];

  if (d.autos.rot.mov == RANDOM)
    mov = get_rand_bit ();
  else
    mov = d.autos.rot.mov;

  if (mov == SMOOTH)
    set_rpm (d.autos.rot.rpm);
  else {
    setdeg (d.autos.rot.dps);
    settps (d.autos.rot.tps);
  }
}

void autorotator::set_rpm (float r) {
  if (r > 0) {
    rpm = r;
    angle.persec = TWO_PI * r / 60.0f;
  } else {
    rpm = 0;
    angle.persec = 0.0f;
  }
}

void autorotator::chgdeg (float d) {
  setdeg (deg + d);
}

void autorotator::chgtps (float t) {
  settps (tps + t);
  setdeg (deg);
}

void autorotator::calc (double dt) {
  if (mov == SMOOTH)
    angle.theta = dt * angle.persec;
  else {
    if (tik (ui_clk())) angle.theta = tik.triggert * angle.persec; else angle.theta = 0.0f;
  }

  if (autoflip.yes) autoflip.calc (angle.theta, dir);
  angle.theta *= dir;

}

void autoflipt::calc (float theta, int& dir) {
  total += theta;
  if (total > angle.rad) {
    dir = -dir;
    total = 0.0f;
  }
}

void autoflipt::set (float d) {
  angle = d;
}

autoflipt::autoflipt (defvelaccel& d) {
  yes = d.autos.flip.yes;
  angle = d.autos.flip.deg;
  total = 0.0f;
}

using namespace std;
istream& operator>> (istream& file, autorotator& ar) {
  file >> ar.yes >> ar.dir >> ar.rpm >> ar.mov >> ar.deg >> ar.tps >> ar.autoflip;
  if (ar.mov == autorotator::SMOOTH)
    ar.set_rpm (ar.rpm);
  else {
    ar.setdeg (ar.deg);
    ar.settps (ar.tps);
  }
  return file;
}

ostream& operator<< (ostream& file, autorotator& ar) {
  file << ar.yes << spc << ar.dir << spc << ar.rpm << spc << ar.mov << spc << ar.deg << spc << ar.tps << spc << ar.autoflip;
  return file;
}

istream& operator>> (istream& file, autoflipt& af) {
  float d;
  file >> af.yes >> d >> af.total;
  af.angle = d;
  return file;
}


ostream& operator<< (ostream& file, autoflipt& af) {
  file << af.yes << spc << af.angle.deg << spc << af.total;
  return file;
}