Subversion Repositories DIN Is Noise

Rev

Rev 2304 | Blame | Compare with Previous | Last modification | View Log | RSS feed

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


#ifndef __drone__
#define __drone__

#include "fader.h"
#include "solver.h"
#include "play.h"
#include "trail.h"
#include "alarm.h"
#include "modulator.h"
#include "noiser.h"
#include "container.h"
#include "vector2d.h"
#include "angle.h"
#include "autorotator.h"
#include "tokenizer.h"

#include <string>
#include <map>
#include <ostream>

CURVE_LISTENER (modv_lis)

#define RESETCHUCKTRAILS(d) if (drone::chuckt::autoresettrails) resetchucktrails(d);

extern int TRAILSIZE;
extern int BOTTOM;
extern float DELTA_VOLUME;
extern float ARROW_U, ARROW_V;

struct din;
struct drone;

typedef std::list<drone*>::iterator drone_iterator;

struct attractee {
  int id;
  drone* d;
  attractee (int _id = -1, drone* _d = 0) {id = _id; d = _d;}
  bool operator== (const attractee& ae) {return (d == ae.d);}
};

struct nnmaxt {
  int n;
  int max;
  nnmaxt () : n(0), max(1) {}
};
std::ostream& operator<< (std::ostream&, nnmaxt&);
std::istream& operator>> (std::istream&, nnmaxt&);
#define MAKE_NNMAXER(name,var) struct name : nnmaxt { name (); } var;

struct drone {

  static float MASTERVOLUME;

  static float anchoropacity;

  static int UID; // unique id
  int id; // this drone id

  // type
  enum {DRONE, NOISE, RANDOM};
  static int IS;
  int is;
  void setis ();

  float step; // sample step that determines pitch (see note.h)

  // for binaural
  //

  int binaural; // binaural?

  float sep; // pitch separation in sample step units if drone is binaural

  enum {LEFT, RIGHT};
  int just;

  float vol; // actual volume
 
  int range; // range number on microtonal-keyboard
  float pos; // position in range (0 - left, 1 - right, can go < 0 & > 1 too)

  int sel; // selected?

  float cx, cy; // unmodulated position
  float x, y; // current position

  int snap; // snap to range edge?
  float sx; // snapped x (used for note snap)
  int note_num; // 0 = left note, 1 = right note of range

  float dy; // height from microtonal-keyboard bottom

  // wip din60
  // sol, player -> L, sol2, player2 -> R for binaural drones
  //

  solver sol; // solve bezier curve waveform of drone into samples
  play player; // render the drone using solver into samples

  // for binaural drone
  solver sol2;
  play player2;

  // visuals
  //

  float r, g, b; // color
  void setcolor ();
  void setcolor (drone& d, float r);

  trail_t trail; // trail points

  // handle
  static int HANDLESIZE; // default size
  int handle_size;
  box<float> handle; // for picking
  void calc_handle ();

  // arrow used for drawing velocity and accel vectors
  struct arrowt {
    static float U, V, K, CAP;
    float u, v, t;
    int cap;
    arrowt () {reset ();}
    void reset ();
  } arrow;

  struct posafxvelt {
    int yes; // drone position affects velocity vector?
    point<float> pt;
    static double minmag;
    posafxvelt() : yes(0), pt (0.0f,0.0f) {}
  } posafxvel;

  // connections
  //
  static float STIFFNESS;
  static std::map<drone*,bool> proc_conn;
  int nconn;
  std::list<drone*> connections;
  std::list<double> mags;
  enum {LINK=0, CHAIN=1};
  int type;
  drone* eval_conns ();
  void remagconns ();

  // states
  enum {DEAD=0, RISING, FALLING, ACTIVE};
  int state; // current
  fader fdr; // for rising/falling -> fade in/out

  int frozen; // frozen?
  double froze_at; // time when frozen
  int freeze ();
  int thaw ();
  void handle_time_pass ();

  //
  // mute/unmute ; drone <> noise
  fader gab;
  float tovol;
  static double gabt;

  // modulation
  modulator mod;

  // orbitals & rocketry
  //
  int orbiting; // orbiting?
  int attractor; // attractor?
  std::list<attractee> attractees; // list of drones attracted by this drone

  float V; // speed
  struct modvt { // speed modulation
    drone* d;
    solver sol;
    float val;
    double _1life;
    modvt (drone* dd) : d (dd), sol (&crv), val (1.0f), _1life (0.0f) {}
    float operator()() {
      float x = (ui_clk () - d->birth) * _1life;
      val = sol(x) * d->V;
      return val;
    }
    static multi_curve crv;
    static curve_editor ed;
    static modv_lis lis;
    static void init ();
  } modv;

  float vx, vy; // current velocity vector
  float xv, yv; // position of velocity vector tip
  int vrev;

  float A; // acceleration
  float ax, ay; // acceleration unit vector
  float xi, yi; // interim position
  float xa, ya; // position of acceleration vector tip

  // auto rotation
  static defvelaccel v0, a0;
  struct autorotva {
    autorotator v, a;
    autorotator* arr[2];
    autorotva () : v (v0), a (a0) {
      arr[0] = &v;
      arr[1] = &a;
    }
    void calc (double dt) {
      v.calc (dt);
      a.calc (dt);
    }
  } autorot;

  static int anchored;

  int gravity; // accelerated by gravity?

  int launcher; // launches drones?
  alarm_t launch_every; // alarm time in seconds
  float lpm; // launches per minute
  int dpl; // drones per launch
  drone* launched_by;

  MAKE_NNMAXER (bouncet, bounces)
  MAKE_NNMAXER (genn, gen)

  // targets for launchers to launch drones to
  std::vector<drone*> targets;
  int cur_target;
  int num_targets;
  void clear_targets ();
  drone* target;

  static double LIFETIME;
  double birth; // time at birth
  double life; // lifetime
  void setlife (float l);
  int reincarnate;

  static double INSERTTIME; // time for insert into orbit
  double insert; // time to insert into orbit

  enum {NONE, POINT, USE};
  int tracking;
  drone* tracked_drone; // the tracked drone

  // wanding
  static struct wandt {
    int dist;
    int dist2;
    wandt (int d) {set (d);}
    void set (int d) {
      dist = d;
      dist2 = d * d;
    }
  } wand;

  enum {UNSET=0, INTERPOLATE, EMPLACE};
  int update_pv;
  void update_pitch_volume ();

  drone (float bottom = 0.0f);

  static int ref;
  ~drone();

  void set_pos (float x, float y);
  void set_center (float _cx, float _cy, int e = 1);
  void move_center ();

  void change_modpos (int i, int what, float delta);
  void change_depth (int i, int what, float delta);
  void change_bpm (int i, int what, float delta);
  void change_bpm (mod_params& mp, float delta);

  noiser nsr;
  void setnoise ();

  enum {IMMORTAL, MORTAL, REINCARNATE};
  static int ARE;

  // for drone <> noise conversions
  struct fin {
    virtual void finished (din& d, drone* pd) = 0;
  } *finl;

  static struct drone2noise : fin {
    void finished (din& mkb, drone* pd);
  } dnl;

  static struct noise2drone : fin {
    void finished (din& mkb, drone* pd);
  } ndl;

  static fin* fins [3]; // 0 = null, 1 = drone2noise, 2 = noise2drone, init @ main.cc

  struct chuckt { // virtual geometric chuck

    static anglet apt; // angle per turn
    static int outline; // draw outline?
    static int autoresettrails; // auto reset trails when chuck params changed?

    int yes;
    drone* sun; // this drone aka planet orbits around sun
    drone* sat; // planet's satellite
    float ux, uy; // unit vector of sun -> planet vector
    float len; // length of sun -> planet vector
    float speed; // angular speed, scales apt
    float speed0; // for toggling speed, 0
    int dir; // -1 = clockwise; +1 = clockwise
    float cx, cy; // center b4 chucked

    chuckt () {
      yes = 0;
      sun = sat = 0;
      ux = uy = 0.0f;
      len = 0.0f;
      speed = 1.0f;
      speed0 = 0.0f;
      dir = 1;
      cx = cy = 0.0f;
    }

    void set (int y, drone* n) {
      yes = y;
      sun = n;
    }

    void calc (drone* planet) {
      len = unit_vector (ux, uy, sun->cx, sun->cy, planet->cx, planet->cy);
      if (sat) sat->chuck.calc (sat);
    }

    void de () {
      if (sat) {
        sat->chuck.sun = sun;
        if (sun) {
          sun->chuck.sat = sat;
          sat->chuck.calc (sat);
        }
      } else {
        if (sun) sun->chuck.sat = 0;
      }
      yes = 0;
    }

    void re (drone& p);

    void print ();

    void resettrail (drone* p);

  } chuck;

};

std::ostream& operator<< (std::ostream& f, drone::arrowt& aw);
std::istream& operator>> (std::istream&, drone::arrowt& aw);
std::ostream& operator<< (std::ostream&, drone::chuckt& ch);
std::istream& operator>> (std::istream&, drone::chuckt& ch);

struct group {
  int n;
  std::vector<drone*> drones;
  group () {n = 0;}
  group (std::vector<drone*> mem, int n);
  int member (drone* d) {
    std::vector<drone*>::iterator db = drones.begin (), de = drones.end();
    if (find (db, de, d) == de) return 0; else return 1;
  }
  int remove (drone* d) {
    if (erase (drones, d)) {
      --n;
      return 1;
    }
    return 0;
  }
};

struct drone_pendulum_group : group {
  int orient;
  int depth;
  drone_pendulum_group (int o = 0, int d = 0) { orient = o; depth = d;}
  drone_pendulum_group (int o, int d, std::vector<drone*> mem, int n) : group (mem, n), orient(o), depth(d)  {}
};


//void copyis (drone& t, drone& s);

#endif