Subversion Repositories DIN Is Noise

Rev

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

/*
* sounding_board.cc
* DIN Is Noise is copyright (c) 2006-2017 Jagannathan Sampath
* For more information, please visit http://dinisnoise.org/
*/


#include "sounding_board.h"
#include "console.h"
#include "curve_listener.h"
#include "audio.h"
#include "input.h"
#include "viewwin.h"
#include "fft.h"
#include <fstream>
using namespace std;

extern ofstream dlog;

extern string user_data_dir;

extern int mousex, mousey;

extern curve_library wav_lib;

extern int find_nearest_note (string&, float&, float&);

void waveform_listener::edited (curve_editor* ed, int i) {
  if (fft0.folded () == 0) fft0.go (ed->curveinfo[i].curve);
  sb->update_players (ed->mix);
  curve_listener::edited (ed, i);
}

sounding_board::sounding_board () : wav ("swav.crv"), waved ("swav.ed"), fdrcrv ("fader.crv"), hlp ("binaural-drones.hlp") {
#ifdef __EVALUATION__
    name = "binaural-drones [Evaluation Version]";
#else
    name = "binaural-drones";
#endif
  wavlis.sb = this;
  waved.add (&wav, &wavlis);
  waved.attach_library (&wav_lib);
  close_octave = 1;
  num_sounders = 0;
  prev_mousex = prev_mousey = 0;
  xt = dxt = 0.0f;
  fading = 0;
  after_fade = 0;
  fdrsol (&fdrcrv);
}

void sounding_board::load () {
  ifstream file ((user_data_dir + "binaural_drones").c_str (), ios::in);
  string ignore;
  int n; file >> ignore >> n;
  if (n) {
    for (int i = 0; i < n; ++i) {
      string name;
      float hz, l, r;
      int bias;
      file >> name >> hz >> l >> r >> bias;
      add (name, hz, l, r, bias);
    }
    dlog << "+++ loaded " << n << " binaurals +++" << endl;
  }
}

void sounding_board::save () {
  ofstream file ((user_data_dir + "binaural_drones").c_str (), ios::out);
  file << "num_binaural_drones " << num_sounders << endl; // we call sounder a binaural drone
  for (int i = 0; i < num_sounders; ++i) {
    sounder* si = sounders[i];
    file << si->name << ' ' << si->hz << ' ' << si->l << ' ' << si->r << ' ' << si->bias << endl;
  }
  dlog << "+++ saved all binaurals +++" << endl;
}

sounding_board::~sounding_board () {
  for (int i = 0; i < num_sounders; ++i) delete sounders[i];
  wav.save ("swav.crv");
  dlog << "--- destroyed sounding_board ---" << endl;
}

void sounding_board::add (const string& name, float hz, float l, float r, int bias) {
  sounder* snd = new sounder (&wav, name, hz, l, r, bias, fadet);
  sounders.push_back (snd);
  ++num_sounders;
  start_fading ();
}

void sounding_board::sync () { // sync the players
  for (int i = 0; i < num_sounders; ++i) {
    sounder* ps = sounders[i];
    ps->playl.x = -ps->playl.dx;
    ps->playr.x = -ps->playr.dx;
  }
}

void sounding_board::maximise (int mult) { // maximise volume
  float v = mult * 1./num_sounders;
  for (int i = 0; i < num_sounders; ++i) {
    sounder* ps = sounders[i];
    ps->l = ps->r = v;
  }
}

void sounding_board::list () { // list sounders
  static char BUFFER[1024];
  cons << console::green;
  for (int i = 0; i < num_sounders; ++i) {
    sounder* ps = sounders[i];
    string note; float freq = ps->hz; float dist; find_nearest_note (note, freq, dist);
    sprintf (BUFFER, "@%sHz, Nearest note = %s, L = %.3f, R = %.3f", ps->name.c_str(), note.c_str(), ps->l, ps->r);
    cons << BUFFER << eol;
    dlog << BUFFER << endl;
  }
}

void sounding_board::set_fade_time (float ft) {
  fadet = ft;
  if (fadet <= 0.0f) fadet = 0.001f;
  extern int SAMPLE_RATE;
  dxt = 1.0 / (fadet * SAMPLE_RATE);
}

void sounding_board::start_fading () {
  fading = 1;
  after_fade = 0;
  xt = 0;
}

void sounding_board::clear_fading () {
  fading = 0;
  for (int i = 0; i < num_sounders; ++i) sounders[i]->clear_fading ();
  after_fade = 1;
}

int sounding_board::render_audio (float* L0, float* R0) {

  if (fading) {
    extern atmin _atmin; extern atmax _atmax;
    fdrsol (xt, dxt, aout.samples_per_channel, aout.vol, _atmin, _atmax);
    if (xt >= 1.0f) clear_fading ();
  }

  for (int i = 0; i < num_sounders; ++i) {
    sounder* ps = sounders[i];
    float* L = L0, *R = R0;
    ps->render (L, R, aout.vol);
  }

  if (after_fade) {
    cons ("after-fade");
    after_fade = 0;
  }

  return 1;

}

void sounding_board::update_players (multi_curve& mx) {
  int canmix = mx.num_vertices;
  for (int i = 0; i < num_sounders; ++i) {
    sounder* s = sounders[i];
    s->soll.update ();
    s->solr.update ();
    if (canmix) {
      s->playl.set_mix (mx);
      s->playr.set_mix (mx);
    }
  }
}

int sounding_board::handle_input () {
  prev_mousex = mousex;
  prev_mousey = mousey;
  if (keypressed (SDLK_F1)) hlp();
  return 1;
}

void sounding_board::enter () {
  extern void show_menu ();
  show_menu ();
}

int sounding_board::change_justification (int d) {
  just += d;
  if (just < LEFT) just = CENTER;
  else if (just > CENTER) just = LEFT;
  return just;
}

int sounding_board::change_key_note (int d) {
  keynote += d;
  if (keynote < START_PITCH) keynote = FROM_SCALE;
  else if (keynote > FROM_SCALE) keynote = START_PITCH;
  return keynote;
}