1 /*
2 * binaural_drone.cc
3 * DIN Is Noise is copyright (c) 2006-2021 Jagannathan Sampath
4 * DIN Is Noise is released under GNU Public License 2.0
5 * For more information, please visit https://dinisnoise.org/
6 */
7
8 #include "binaural_drone.h"
9 #include "audio.h"
10 #include "console.h"
11
12 extern void hz2step (float& hz, float& step);
13 extern void step2hz (float& step, float& hz);
14
15 extern char BUFFER[];
16
binaural_drone(multi_curve * wav,float _lhz,float _rhz,float _vol,int _just,float _sep,float lx,float rx)17 binaural_drone::binaural_drone (multi_curve* wav, float _lhz, float _rhz, float _vol, int _just, float _sep, float lx, float rx) {
18
19 soll (wav);
20 solr (wav);
21 playl.set_wave (&soll);
22 playr.set_wave (&solr);
23
24 l_step = r_step = 0.0f;
25 set_hz (_lhz, _rhz);
26 if (lx == INVALID) // normal lx is in [0,1]
27 sync ();
28 else {
29 playl.x = lx;
30 playr.x = rx;
31 }
32
33 vol = 0.0f;
34 set_vol (_vol);
35
36 just = _just;
37 sep = _sep;
38
39 sel = 0;
40
41 }
42
make_name()43 void binaural_drone::make_name () {
44 sprintf (BUFFER, "%0.3fHz+%0.3fHz=%0.3fHz @ %0.2f%% vol", l_hz, sep, r_hz, vol * 100);
45 name = BUFFER;
46 }
47
make_name(float stepl,float stepr)48 void binaural_drone::make_name (float stepl, float stepr) {
49 float hzl, hzr; step2hz (stepl, hzl); step2hz (stepr, hzr);
50 sprintf (BUFFER, "%0.3fHz+%0.3fHz=%0.3fHz @ %0.2f%% vol", hzl, (hzr - hzl), hzr, vol * 100);
51 name = BUFFER;
52 }
53
make_name(float v)54 void binaural_drone::make_name (float v) {
55 sprintf (BUFFER, "%0.3fHz+%0.3fHz=%0.3fHz @ %0.2f%% vol", l_hz, sep, r_hz, v * 100);
56 name = BUFFER;
57 }
58
set_hz(int i,float v)59 void binaural_drone::set_hz (int i, float v) {
60
61 float* step_prev [] = {&l_step_prev, &r_step_prev};
62 float* hz [] = {&l_hz, &r_hz};
63 float* step [] = {&l_step, &r_step};
64 int flags [] = {fade_flags::L, fade_flags::R};
65 float* step_cur [] = {&fading.l_step_cur, &fading.r_step_cur};
66
67 float& step_prev_i = *step_prev[i];
68 float& hz_i = *hz[i];
69 float& step_i = *step[i];
70
71 int j = !i;
72 *step_cur[j] = *step[j];
73
74 step_prev_i = step_i;
75 hz_i = v;
76 hz2step (hz_i, step_i);
77 sep = r_hz - l_hz;
78
79 int fi = flags[i];
80 if (fading.hz) {
81 if (fading.hz != fi) fading.hz = fade_flags::BOTH;
82 } else fading.hz = fi;
83
84 }
85
set_hz(float _lhz,float _rhz)86 void binaural_drone::set_hz (float _lhz, float _rhz) {
87 l_step_prev = l_step;
88 r_step_prev = r_step;
89 l_hz = _lhz;
90 r_hz = _rhz;
91 sep = r_hz - l_hz;
92 hz2step (l_hz, l_step);
93 hz2step (r_hz, r_step);
94 fill_hz ();
95 make_name ();
96 }
97
fill_hz()98 void binaural_drone::fill_hz () {
99 playl.fill_pitch (l_step);
100 playr.fill_pitch (r_step);
101 }
102
set_vol(float v)103 void binaural_drone::set_vol (float v) {
104 vol_prev = vol;
105 vol = v;
106 fading.vol = 1;
107 }
108
set_sep(float s)109 void binaural_drone::set_sep (float s) {
110 switch (just) {
111 case LEFT:
112 set_hz (RIGHT, l_hz + s);
113 break;
114 case RIGHT:
115 set_hz (LEFT, r_hz - s);
116 break;
117 case CENTER:
118 float mid = (l_hz + r_hz) / 2.0, s2 = s / 2.0;
119 set_hz (LEFT, mid - s2);
120 set_hz (RIGHT, mid + s2);
121 break;
122 }
123 }
124
set_just(int j)125 void binaural_drone::set_just (int j) {
126 just = j;
127 }
128
render(float * L,float * R,float * vfdr,float * pfdr,int uv,int uh,int abort)129 void binaural_drone::render (float* L, float* R, float* vfdr, float* pfdr, int uv, int uh, int abort) {
130
131 play* pl [] = {&playl, &playr};
132 float* outf [] = {L, R};
133 float* outi [] = {aout.bufL, aout.bufR};
134
135 if (fading.vol) {
136 calc_fader (aout.fdr1, vfdr, aout.samples_per_channel, vol_prev, vol, &fading.vol_cur);
137 if (uv) {
138 make_name (fading.vol_cur);
139 if (abort) {
140 vol = fading.vol_cur;
141 fading.vol = fade_flags::NONE;
142 }
143 }
144 }
145
146 if (fading.hz) {
147 if (fading.hz == fade_flags::L || fading.hz == fade_flags::BOTH)
148 calc_fader (playl.pdx, pfdr, aout.samples_per_channel, l_step_prev, l_step, &fading.l_step_cur);
149 if (fading.hz == fade_flags::R || fading.hz == fade_flags::BOTH)
150 calc_fader (playr.pdx, pfdr, aout.samples_per_channel, r_step_prev, r_step, &fading.r_step_cur);
151 if (uh) {
152 make_name (fading.l_step_cur, fading.r_step_cur);
153 if (abort) {
154 l_step = fading.l_step_cur;
155 r_step = fading.r_step_cur;
156 step2hz (fading.l_step_cur, l_hz);
157 step2hz (fading.r_step_cur, r_hz);
158 sep = r_hz - l_hz;
159 fill_hz ();
160 fading.hz = fade_flags::NONE;
161 }
162 }
163 }
164
165
166 for (int i = 0; i < 2; ++i) {
167 float* outfi = outf [i];
168 float* outii = outi [i];
169 memset (outii, 0, aout.samples_channel_size);
170 play* pli = pl [i];
171 if (fading.vol)
172 pli->gen_wav_mix (outii, aout.fdr1, aout.samples_per_channel);
173 else
174 pli->gen_wav_mix (outii, vol, aout.samples_per_channel);
175 for (int j = 0, k = aout.samples_per_channel; j < k; ++j) outfi[j] += outii[j];
176 }
177
178 }
179
calc_fader(float * out,float * alpha,int n,float v1,float v2,float * cur)180 void binaural_drone::calc_fader (float* out, float* alpha, int n, float v1, float v2, float* cur) {
181 float dv = v2 - v1;
182 for (int i = 0; i < n; ++i) {
183 float ai = alpha[i];
184 out[i] = v1 + ai * dv;
185 }
186 *cur = out[n-1];
187 }
188
sync()189 void binaural_drone::sync () {
190 // so first += solves to y=0 [depends on waveform shape]
191 playl.x = -playl.pdx[0];
192 playr.x = -playr.pdx[0];
193 }
194