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