/* * binaural_drone.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 "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, "%0.3fHz+%0.3fHz=%0.3fHz @ %0.2f%% vol", 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, "%0.3fHz+%0.3fHz=%0.3fHz @ %0.2f%% vol", hzl, (hzr - hzl), hzr, vol * 100); name = BUFFER; } void binaural_drone::make_name (float v) { sprintf (BUFFER, "%0.3fHz+%0.3fHz=%0.3fHz @ %0.2f%% vol", 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]; }