Subversion Repositories DIN Is Noise

Rev

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

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


#include "binaural_drone.h"
#include "audio.h"
#include "console.h"

extern void hz2step (float& hz, float& step);
extern void step2hz (float& step, float& hz);

extern char BUFFER[];

binaural_drone::binaural_drone (multi_curve* wav, float _lhz, float _rhz, float _vol, int _just, float _sep, float lx, float rx) {

  soll (wav);
  solr (wav);
  playl.set_wave (&soll);
  playr.set_wave (&solr);

  l_step = r_step = 0.0f;
  set_hz (_lhz, _rhz);
  if (lx == INVALID) // normal lx is in [0,1]
    sync ();
  else {
    playl.x = lx;
    playr.x = rx;
  }

  vol = 0.0f;
  set_vol (_vol);

  just = _just;
  sep = _sep;

  sel = 0;

}

void binaural_drone::make_name () {
  sprintf (BUFFER, BD_NAME, l_hz, sep, r_hz, vol * 100);
  name = BUFFER;
}

void binaural_drone::make_name (float stepl, float stepr) {
  float hzl, hzr; step2hz (stepl, hzl); step2hz (stepr, hzr);
  sprintf (BUFFER, BD_NAME, hzl, (hzr - hzl), hzr, vol * 100);
  name = BUFFER;
}

void binaural_drone::make_name (float v) {
  sprintf (BUFFER, BD_NAME, l_hz, sep, r_hz, v * 100);
  name = BUFFER;
}

void binaural_drone::set_hz (int i, float v) {

  float* step_prev [] = {&l_step_prev, &r_step_prev};
  float* hz [] = {&l_hz, &r_hz};
  float* step [] = {&l_step, &r_step};
  int flags [] = {fade_flags::L, fade_flags::R};
  float* step_cur [] = {&fading.l_step_cur, &fading.r_step_cur};
 
  float& step_prev_i = *step_prev[i];
  float& hz_i = *hz[i];
  float& step_i = *step[i];

  int j = !i;
  *step_cur[j] = *step[j];

  step_prev_i = step_i;
  hz_i = v;
  hz2step (hz_i, step_i);
  sep = r_hz - l_hz;

  int fi = flags[i];
  if (fading.hz) {
    if (fading.hz != fi) fading.hz = fade_flags::BOTH;
  } else fading.hz = fi;

}

void binaural_drone::set_hz (float _lhz, float _rhz) {
  l_step_prev = l_step;
  r_step_prev = r_step;
  l_hz = _lhz;
  r_hz = _rhz;
  sep = r_hz - l_hz;
  hz2step (l_hz, l_step);
  hz2step (r_hz, r_step);
  fill_hz ();
  make_name ();
}

void binaural_drone::fill_hz () {
  playl.fill_pitch (l_step);
  playr.fill_pitch (r_step);
}

void binaural_drone::set_vol (float v) {
  vol_prev = vol;
  vol = v;
  fading.vol = 1;
}

void binaural_drone::set_sep (float s) {
  switch (just) {
    case LEFT:
      set_hz (RIGHT, l_hz + s);
      break;
    case RIGHT:
      set_hz (LEFT, r_hz - s);
      break;
    case CENTER:
      float mid = (l_hz + r_hz) / 2.0, s2 = s / 2.0;
      set_hz (LEFT, mid - s2);
      set_hz (RIGHT, mid + s2);
      break;
  }
}

void binaural_drone::set_just (int j) {
  just = j;
}

void binaural_drone::render (float* L, float* R, float* vfdr, float* pfdr, int uv, int uh, int abort) {

  play* pl [] = {&playl, &playr};
  float* outf [] = {L, R};
  float* outi [] = {aout.bufL, aout.bufR};

  if (fading.vol) {
    calc_fader (aout.fdr1, vfdr, aout.samples_per_channel, vol_prev, vol, &fading.vol_cur);
    if (uv) {
      make_name (fading.vol_cur);
      if (abort) {
        vol = fading.vol_cur;
        fading.vol = fade_flags::NONE;
      }
    }
  }

  if (fading.hz) {
    if (fading.hz == fade_flags::L || fading.hz == fade_flags::BOTH)
      calc_fader (playl.pdx, pfdr, aout.samples_per_channel, l_step_prev, l_step, &fading.l_step_cur);
    if (fading.hz == fade_flags::R || fading.hz == fade_flags::BOTH)
      calc_fader (playr.pdx, pfdr, aout.samples_per_channel, r_step_prev, r_step, &fading.r_step_cur);
    if (uh) {
      make_name (fading.l_step_cur, fading.r_step_cur);
      if (abort) {
        l_step = fading.l_step_cur;
        r_step = fading.r_step_cur;
        step2hz (fading.l_step_cur, l_hz);
        step2hz (fading.r_step_cur, r_hz);
        sep = r_hz - l_hz;
        fill_hz ();
        fading.hz = fade_flags::NONE;
      }
    }
  }


  for (int i = 0; i < 2; ++i) {
    float* outfi = outf [i];
    float* outii = outi [i];
    memset (outii, 0, aout.samples_channel_size);
    play* pli = pl [i];
    if (fading.vol)
      pli->gen_wav_mix (outii, aout.fdr1, aout.samples_per_channel);
    else
      pli->gen_wav_mix (outii, vol, aout.samples_per_channel);
    for (int j = 0, k = aout.samples_per_channel; j < k; ++j) outfi[j] += outii[j];
  }

}

void binaural_drone::calc_fader (float* out, float* alpha, int n, float v1, float v2, float* cur) {
  float dv = v2 - v1;
  for (int i = 0; i < n; ++i) {
    float ai = alpha[i];
    out[i] = v1 + ai * dv;
  }
  *cur = out[n-1];
}

void binaural_drone::sync () {
  // so first += solves to y=0 [depends on waveform shape]
  playl.x = -playl.pdx[0];
  playr.x = -playr.pdx[0];
}