1 /* balance -- LV2 stereo balance control
2 *
3 * Copyright (C) 2013 Robin Gareus <robin@gareus.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <math.h>
23 #include <assert.h>
24
25 #include "lv2/lv2plug.in/ns/lv2core/lv2.h"
26 #include "lv2/lv2plug.in/ns/ext/state/state.h"
27 #include "uris.h"
28
29 #define MAXDELAY (2001)
30 #define CHANNELS (2)
31
32 #define C_LEFT (0)
33 #define C_RIGHT (1)
34
35 #define FADE_LEN (64)
36 #define METER_FALLOFF (13.3) // dB/sec
37 #define UPDATE_FREQ (30.0) // Hz
38 #define PEAK_HOLD_TIME (2.0) // seconds
39
40 #define PEAK_INTEGRATION_MAX (0.05) // seconds -- used for buffer size limit
41 #define PEAK_INTEGRATION_TIME (0.005) // seconds -- must be >=0; should be <= PEAK_INTEGRATION_MAX
42 #define PHASE_INTEGRATION_TIME (.5) // seconds -- must be > 0
43
44 #define SIGNUM(a) ( (a) < 0 ? -1 : 1)
45 #define SQUARE(a) ( (a) * (a) )
46
47 #define VALTODB(V) (20.0f * log10f(V))
48
49 #define MIN(a,b) ( (a) < (b) ? (a) : (b) )
50 #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
51 #define RAIL(v, min, max) (MIN((max), MAX((min), (v))))
52
53 typedef enum {
54 BLC_TRIM = 0,
55 BLC_PHASEL,
56 BLC_PHASER,
57 BLC_BALANCE,
58 BLC_UNIYGAIN,
59 BLC_DLYL,
60 BLC_DLYR,
61 BLC_MONOIZE,
62 BLC_INL,
63 BLC_INR,
64 BLC_OUTL,
65 BLC_OUTR,
66 BLC_UICONTROL,
67 BLC_UINOTIFY
68 } PortIndex;
69
70 typedef struct {
71 LV2_URID_Map* map;
72 balanceURIs uris;
73
74 LV2_Atom_Forge forge;
75 LV2_Atom_Forge_Frame frame;
76 const LV2_Atom_Sequence* control;
77 LV2_Atom_Sequence* notify;
78
79 /* control ports */
80 float* trim;
81 float* phase[CHANNELS];
82 float* balance;
83 float* unitygain;
84 float* monomode;
85 float* delay[CHANNELS];
86 float* input[CHANNELS];
87 float* output[CHANNELS];
88
89 /* delay buffers */
90 float buffer[CHANNELS][MAXDELAY];
91
92 /* buffer offsets */
93 int w_ptr[CHANNELS];
94 int r_ptr[CHANNELS];
95
96 /* current settings */
97 float c_amp[CHANNELS];
98 int c_dly[CHANNELS];
99 int c_monomode;
100
101 float samplerate;
102 float p_bal[CHANNELS];
103 int p_dly[CHANNELS];
104
105 int uicom_active;
106
107 float meter_falloff;
108 float peak_hold;
109
110 /* peak hold */
111 int p_peakcnt;
112 int peak_integrate_pos, peak_integrate_pref, peak_integrate_max;
113 float p_peak_in[CHANNELS], p_peak_out[CHANNELS]; // [abs max signal] peak hold
114 double *p_peak_inPi[CHANNELS], *p_peak_outPi[CHANNELS]; // [sqaread signal] integration data buffer
115 double p_peak_inP[CHANNELS], p_peak_outP[CHANNELS]; // [squared signal] current
116 double p_peak_inM[CHANNELS], p_peak_outM[CHANNELS]; // [squared signal] max
117
118 /* visible peak w/ falloff */
119 float p_vpeak_in[CHANNELS]; // [dBFS]
120 float p_vpeak_out[CHANNELS]; // [dbFS]
121
122 int phase_integrate_pos, phase_integrate_max;
123 double *p_phase_outPi, *p_phase_outNi;
124 double p_phase_outP, p_phase_outN;
125
126 /* peak hold */
127 float p_tme_in[CHANNELS]; // [samples]
128 float p_tme_out[CHANNELS]; // [samples
129 float p_max_in[CHANNELS]; // [dbFS]
130 float p_max_out[CHANNELS]; // [dbFS]
131
132 int queue_stateswitch;
133 float state[3];
134 } BalanceControl;
135
136 #define DLYWITHGAIN(GAIN) \
137 buffer[ self->w_ptr[chn] ] = input[pos]; \
138 output[pos] = buffer[ self->r_ptr[chn] ] * (GAIN);
139
140 #define INCREMENT_PTRS(CHN) \
141 self->r_ptr[CHN] = (self->r_ptr[CHN] + 1) % MAXDELAY; \
142 self->w_ptr[CHN] = (self->w_ptr[CHN] + 1) % MAXDELAY;
143
144 #define SMOOTHGAIN (amp + (target_amp - amp) * (float) MIN(pos, fade_len) / (float)fade_len)
145
146 static void
process_channel(BalanceControl * self,const float target_amp,const uint32_t chn,const uint32_t n_samples)147 process_channel(BalanceControl *self,
148 const float target_amp, const uint32_t chn,
149 const uint32_t n_samples)
150 {
151 uint32_t pos = 0;
152 const float delay = *(self->delay[chn]);
153 const float* const input = self->input[chn];
154 float* const output = self->output[chn];
155 float* const buffer = self->buffer[chn];
156 const float amp = self->c_amp[chn];
157
158 // TODO bridge cycles if smoothing is longer than n_samples
159 const uint32_t fade_len = (n_samples >= FADE_LEN) ? FADE_LEN : n_samples;
160
161 if (self->c_dly[chn] != rint(delay)) {
162 /* delay length changed */
163 const int r_ptr = self->r_ptr[chn];
164 const int w_ptr = self->w_ptr[chn];
165
166 /* fade out */
167 for (; pos < fade_len; pos++) {
168 const float gain = (float)(fade_len - pos) / (float)fade_len;
169 DLYWITHGAIN(gain * SMOOTHGAIN)
170 INCREMENT_PTRS(chn);
171 }
172
173 /* restore pointers to beginning of fade. */
174 self->r_ptr[chn] = r_ptr;
175 self->w_ptr[chn] = w_ptr;
176 INCREMENT_PTRS(chn);
177 pos = 1;
178
179 /* update read pointer */
180 self->r_ptr[chn] += self->c_dly[chn] - rintf(delay);
181 if (self->r_ptr[chn] < 0) {
182 self->r_ptr[chn] -= MAXDELAY * floor(self->r_ptr[chn] / (float)MAXDELAY);
183 }
184 self->r_ptr[chn] = self->r_ptr[chn] % MAXDELAY;
185 self->c_dly[chn] = rint(delay);
186
187 /* fade in, x-fade */
188 for (; pos < fade_len; pos++) {
189 const float gain = (float)pos / (float)fade_len;
190 buffer[ self->w_ptr[chn] ] = input[pos]; \
191 output[pos] += buffer[ self->r_ptr[chn] ] * (gain * SMOOTHGAIN);
192 INCREMENT_PTRS(chn);
193 }
194 }
195
196 if (target_amp != self->c_amp[chn]) {
197 for (; pos < n_samples; pos++) {
198 DLYWITHGAIN(SMOOTHGAIN)
199 INCREMENT_PTRS(chn);
200 }
201 } else {
202 for (; pos < n_samples; pos++) {
203 DLYWITHGAIN(amp)
204 INCREMENT_PTRS(chn);
205 }
206 }
207 self->c_amp[chn] = target_amp;
208 }
209
210 static void
channel_map(BalanceControl * self,int mode,const uint32_t start,const uint32_t end)211 channel_map(BalanceControl *self, int mode,
212 const uint32_t start, const uint32_t end)
213 {
214 uint32_t i;
215 switch (mode) {
216 case 1:
217 for (i=start; i < end; ++i) {
218 self->output[C_RIGHT][i] = self->output[C_LEFT][i];
219 }
220 break;
221 case 2:
222 for (i=start; i < end; ++i) {
223 self->output[C_LEFT][i] = self->output[C_RIGHT][i];
224 }
225 break;
226 case 3:
227 for (i=start; i < end; ++i) {
228 const float mem = self->output[C_LEFT][i];
229 self->output[C_LEFT][i] = self->output[C_RIGHT][i];
230 self->output[C_RIGHT][i] = mem;
231 }
232 break;
233 case 4:
234 for (i=start; i < end; ++i) {
235 const float mono = (self->output[C_LEFT][i] + self->output[C_RIGHT][i]) / 2.0;
236 self->output[C_LEFT][i] = self->output[C_RIGHT][i] = mono;
237 }
238 break;
239 default:
240 case 0:
241 break;
242 }
243 }
244
245 static void
channel_map_change(BalanceControl * self,int mode,const uint32_t pos,float * out)246 channel_map_change(BalanceControl *self, int mode,
247 const uint32_t pos, float *out)
248 {
249 switch (mode) {
250 case 1:
251 out[C_LEFT] = self->output[C_LEFT][pos];
252 out[C_RIGHT] = self->output[C_LEFT][pos];
253 break;
254 case 2:
255 out[C_LEFT] = self->output[C_RIGHT][pos];
256 out[C_RIGHT] = self->output[C_RIGHT][pos];
257 break;
258 case 3:
259 out[C_LEFT] = self->output[C_RIGHT][pos];
260 out[C_RIGHT] = self->output[C_LEFT][pos];
261 break;
262 case 4:
263 {
264 const float mono = (self->output[C_LEFT][pos] + self->output[C_RIGHT][pos]) / 2.0;
265 out[C_LEFT] = out[C_RIGHT] = mono;
266 }
267 break;
268 default:
269 case 0:
270 out[C_LEFT] = self->output[C_LEFT][pos];
271 out[C_RIGHT] = self->output[C_RIGHT][pos];
272 break;
273 }
274 }
275
gain_to_db(const float g)276 static inline float gain_to_db(const float g) {
277 if (g <= 0) return -INFINITY;
278 return VALTODB(g);
279 }
280
db_to_gain(const float d)281 static inline float db_to_gain(const float d) {
282 return pow(10, d/20.0);
283 }
284
reset_uicom(BalanceControl * self)285 static void reset_uicom(BalanceControl* self) {
286 int i;
287 for (i=0; i < CHANNELS; ++i) {
288 self->p_peak_in[i] = -INFINITY;
289 self->p_peak_out[i] = -INFINITY;
290 self->p_vpeak_in[i] = -INFINITY;
291 self->p_vpeak_out[i] = -INFINITY;
292
293 self->p_tme_in[i] = 0;
294 self->p_tme_out[i] = 0;
295 self->p_max_in[i] = -INFINITY;
296 self->p_max_out[i] = -INFINITY;
297
298 self->p_bal[i] = INFINITY;
299 self->p_dly[i] = -1;
300
301 self->p_phase_outP = 0;
302 self->p_phase_outN = 0;
303
304 memset(self->p_peak_inPi[i], 0, self->peak_integrate_max * sizeof(double));
305 memset(self->p_peak_outPi[i], 0, self->peak_integrate_max * sizeof(double));
306
307 self->p_peak_outP[i] = self->p_peak_inP[i] = 0;
308 self->p_peak_outM[i] = self->p_peak_inM[i] = 0;
309 }
310
311 memset(self->p_phase_outPi, 0, self->phase_integrate_max * sizeof(double));
312 memset(self->p_phase_outNi, 0, self->phase_integrate_max * sizeof(double));
313 self->peak_integrate_pos = self->phase_integrate_pos = 0;
314
315 self->p_peakcnt = 0;
316 }
317
send_cfg_to_ui(BalanceControl * self)318 static void send_cfg_to_ui(BalanceControl* self) {
319 forge_kvcontrolmessage(&self->forge, &self->uris, CFG_INTEGRATE, self->peak_integrate_pref / self->samplerate);
320 forge_kvcontrolmessage(&self->forge, &self->uris, CFG_FALLOFF, self->meter_falloff * (float) UPDATE_FREQ);
321 forge_kvcontrolmessage(&self->forge, &self->uris, CFG_HOLDTIME, self->peak_hold / (float) UPDATE_FREQ);
322 }
323
update_meter_cfg(BalanceControl * self,int key,float val)324 static void update_meter_cfg(BalanceControl* self, int key, float val) {
325 switch (key) {
326 case 0:
327 if (val >=0 && val <= self->peak_integrate_max) {
328 self->peak_integrate_pref = val * self->samplerate;
329 }
330 reset_uicom(self);
331 break;
332 case 1:
333 self->meter_falloff = MAX(0, val / UPDATE_FREQ);
334 self->meter_falloff = MIN(self->meter_falloff, 1000);
335 break;
336 case 2:
337 self->peak_hold = MAX(0, val * UPDATE_FREQ);
338 self->peak_hold = MIN(self->peak_hold, 60 * UPDATE_FREQ);
339 break;
340 case 3:
341 for (int i=0; i < CHANNELS; ++i) {
342 if ( ((int)val)&1) {
343 self->p_max_in[i] = -INFINITY;
344 }
345 if ( ((int)val)&2) {
346 self->p_max_out[i] = -INFINITY;
347 }
348 }
349 forge_kvcontrolmessage(&self->forge, &self->uris, PEAK_IN_LEFT, self->p_max_in[C_LEFT]);
350 forge_kvcontrolmessage(&self->forge, &self->uris, PEAK_IN_RIGHT, self->p_max_in[C_RIGHT]);
351 forge_kvcontrolmessage(&self->forge, &self->uris, PEAK_OUT_LEFT, self->p_max_out[C_LEFT]);
352 forge_kvcontrolmessage(&self->forge, &self->uris, PEAK_OUT_RIGHT, self->p_max_out[C_RIGHT]);
353 break;
354
355 default:
356 break;
357 }
358 }
359
360 static void
run(LV2_Handle instance,uint32_t n_samples)361 run(LV2_Handle instance, uint32_t n_samples)
362 {
363 uint32_t i,c;
364 BalanceControl* self = (BalanceControl*)instance;
365 const float balance = *self->balance;
366 const float trim = db_to_gain(*self->trim);
367 float gain_left = 1.0;
368 float gain_right = 1.0;
369
370 const int ascnt = self->samplerate / UPDATE_FREQ;
371
372 const uint32_t capacity = self->notify->atom.size;
373 lv2_atom_forge_set_buffer(&self->forge, (uint8_t*)self->notify, capacity);
374 lv2_atom_forge_sequence_head(&self->forge, &self->frame, 0);
375
376 /* reset after state restore */
377 if (self->queue_stateswitch) {
378 self->queue_stateswitch = 0;
379 self->peak_integrate_pref = self->state[0] * self->samplerate;
380 self->meter_falloff = self->state[1] / UPDATE_FREQ;
381 self->peak_hold = self->state[2] * UPDATE_FREQ;
382
383 self->peak_integrate_pref = MAX(0, self->peak_integrate_pref);
384 self->peak_integrate_pref = MIN(self->peak_integrate_pref, self->peak_integrate_max);
385
386 self->meter_falloff = MAX(0, self->meter_falloff);
387 self->meter_falloff = MIN(self->meter_falloff, 1000);
388
389 self->peak_hold = MAX(0, self->peak_hold);
390 self->peak_hold = MIN(self->peak_hold, 60 * UPDATE_FREQ);
391 reset_uicom(self);
392 send_cfg_to_ui(self);
393 }
394
395 /* Process incoming events from GUI */
396 if (self->control) {
397 LV2_Atom_Event* ev = lv2_atom_sequence_begin(&(self->control)->body);
398 while(!lv2_atom_sequence_is_end(&(self->control)->body, (self->control)->atom.size, ev)) {
399 if (ev->body.type == self->uris.atom_Blank || ev->body.type == self->uris.atom_Object) {
400 const LV2_Atom_Object* obj = (LV2_Atom_Object*)&ev->body;
401 if (obj->body.otype == self->uris.blc_meters_on) {
402 if (self->uicom_active == 0) {
403 reset_uicom(self);
404 send_cfg_to_ui(self);
405 self->uicom_active = 1;
406 }
407 }
408 if (obj->body.otype == self->uris.blc_meters_off) {
409 self->uicom_active = 0;
410 }
411 if (obj->body.otype == self->uris.blc_meters_cfg) {
412 const LV2_Atom* key = NULL;
413 const LV2_Atom* value = NULL;
414 lv2_atom_object_get(obj, self->uris.blc_cckey, &key, self->uris.blc_ccval, &value, 0);
415 if (value && key) {
416 update_meter_cfg(self, ((LV2_Atom_Int*)key)->body, ((LV2_Atom_Float*)value)->body);
417 }
418 }
419 }
420 ev = lv2_atom_sequence_next(ev);
421 }
422 }
423
424 /* pre-calculate parameters */
425 if (balance < 0) {
426 gain_right = 1.0 + RAIL(balance, -1.0, 0.0);
427 } else if (balance > 0) {
428 gain_left = 1.0 - RAIL(balance, 0.0, 1.0);
429 }
430
431 switch ((int) *self->unitygain) {
432 case 1:
433 {
434 /* maintain amplitude sum */
435 const double gaindiff = (gain_left - gain_right);
436 gain_left = 1.0 + gaindiff;
437 gain_right = 1.0 - gaindiff;
438 }
439 break;
440 case 2:
441 {
442 /* equal power*/
443 if (balance < 0) {
444 gain_right = MAX(.5, gain_right);
445 gain_left = db_to_gain(-gain_to_db(gain_right));
446 } else {
447 gain_left = MAX(.5, gain_left);
448 gain_right = db_to_gain(-gain_to_db(gain_left));
449 }
450 }
451 case 0:
452 /* 'tradidional' balance */
453 break;
454 }
455
456 if (*(self->phase[C_LEFT])) gain_left *=-1;
457 if (*(self->phase[C_RIGHT])) gain_right *=-1;
458
459 /* keep track of input levels -- only if GUI is visiable */
460 if (self->uicom_active) {
461 for (c=0; c < CHANNELS; ++c) {
462 for (i=0; i < n_samples; ++i) {
463 /* input peak meter */
464 const float ps = fabsf(self->input[c][i]);
465 if (ps > self->p_peak_in[c]) self->p_peak_in[c] = ps;
466
467 if (self->peak_integrate_pref < 1) {
468 const float psm = ps * ps;
469 if (psm > self->p_peak_inM[c]) self->p_peak_inM[c] = psm;
470 continue;
471 }
472
473 /* integrated level, peak */
474 const int pip = (self->peak_integrate_pos + i ) % self->peak_integrate_pref;
475 const double p_sig = SQUARE(self->input[c][i]);
476 self->p_peak_inP[c] += p_sig - self->p_peak_inPi[c][pip];
477 self->p_peak_inPi[c][pip] = p_sig;
478 /* peak of integrated signal */
479 const float psm = self->p_peak_inP[c] / (double) self->peak_integrate_pref;
480 if (psm > self->p_peak_inM[c]) self->p_peak_inM[c] = psm;
481 }
482 }
483 }
484
485 /* process audio -- delayline + balance & gain */
486 process_channel(self, gain_left * trim, C_LEFT, n_samples);
487 process_channel(self, gain_right * trim, C_RIGHT, n_samples);
488
489 /* swap/assign channels */
490 uint32_t pos = 0;
491
492 if (self->c_monomode != (int) *self->monomode) {
493 /* smooth change */
494 const uint32_t fade_len = (n_samples >= FADE_LEN) ? FADE_LEN : n_samples;
495 for (; pos < fade_len; pos++) {
496 const float gain = (float)pos / (float)fade_len;
497 float x1[CHANNELS], x2[CHANNELS];
498 channel_map_change(self, self->c_monomode, pos, x1);
499 channel_map_change(self, (int) *self->monomode, pos, x2);
500 self->output[C_LEFT][pos] = x1[C_LEFT] * (1.0 - gain) + x2[C_LEFT] * gain;
501 self->output[C_RIGHT][pos] = x1[C_RIGHT] * (1.0 - gain) + x2[C_RIGHT] * gain;
502 }
503 }
504
505 channel_map(self, (int) *self->monomode, pos, n_samples);
506 self->c_monomode = (int) *self->monomode;
507
508 /* audio processing done */
509
510 if (!self->uicom_active) {
511 return;
512 }
513
514 /* output peak meter */
515 for (c=0; c < CHANNELS; ++c) {
516 for (i=0; i < n_samples; ++i) {
517 /* peak */
518 const float ps = fabsf(self->output[c][i]);
519 if (ps > self->p_peak_out[c]) self->p_peak_out[c] = ps;
520
521 if (self->peak_integrate_pref < 1) {
522 const float psm = ps * ps;
523 if (psm > self->p_peak_outM[c]) self->p_peak_outM[c] = psm;
524 continue;
525 }
526
527 /* integrated level, peak */
528 const int pip = (self->peak_integrate_pos + i ) % self->peak_integrate_pref;
529 const double p_sig = SQUARE(self->output[c][i]);
530 self->p_peak_outP[c] += p_sig - self->p_peak_outPi[c][pip];
531 self->p_peak_outPi[c][pip] = p_sig;
532 /* peak of integrated signal */
533 const float psm = self->p_peak_outP[c] / (double) self->peak_integrate_pref;
534 if (psm > self->p_peak_outM[c]) self->p_peak_outM[c] = psm;
535 }
536 }
537 if (self->peak_integrate_pref > 0) {
538 self->peak_integrate_pos = (self->peak_integrate_pos + n_samples ) % self->peak_integrate_pref;
539 }
540
541 /* simple output phase correlation */
542 for (i=0; i < n_samples; ++i) {
543 const double p_pos = SQUARE(self->output[C_LEFT][i] + self->output[C_RIGHT][i]);
544 const double p_neg = SQUARE(self->output[C_LEFT][i] - self->output[C_RIGHT][i]);
545
546 /* integrate over 500ms */
547 self->p_phase_outP += p_pos - self->p_phase_outPi[self->phase_integrate_pos];
548 self->p_phase_outN += p_neg - self->p_phase_outNi[self->phase_integrate_pos];
549 self->p_phase_outPi[self->phase_integrate_pos] = p_pos;
550 self->p_phase_outNi[self->phase_integrate_pos] = p_neg;
551 self->phase_integrate_pos = (self->phase_integrate_pos + 1) % self->phase_integrate_max;
552 }
553
554 /* abs peak hold */
555 #define PKM(A,CHN,ID) \
556 { \
557 const float peak = VALTODB(self->p_peak_##A[CHN]); \
558 if (peak > self->p_max_##A[CHN]) { \
559 self->p_max_##A[CHN] = peak; \
560 self->p_tme_##A[CHN] = 0; \
561 forge_kvcontrolmessage(&self->forge, &self->uris, ID, self->p_max_##A[CHN]); \
562 } else if (self->peak_hold <= 0) { \
563 (self->p_tme_##A[CHN])=0; /* infinite hold */ \
564 } else if (self->p_tme_##A[CHN] <= self->peak_hold) { \
565 (self->p_tme_##A[CHN])++; \
566 } else if (self->meter_falloff == 0) { \
567 self->p_max_##A[CHN] = peak; \
568 forge_kvcontrolmessage(&self->forge, &self->uris, ID, self->p_max_##A[CHN]); \
569 } else { \
570 self->p_max_##A[CHN] -= self->meter_falloff; \
571 self->p_max_##A[CHN] = MAX(peak, self->p_max_##A[CHN]); \
572 forge_kvcontrolmessage(&self->forge, &self->uris, ID, self->p_max_##A[CHN]); \
573 } \
574 }
575
576 /* RMS meter */
577 #define PKF(A,CHN,ID) \
578 { \
579 float dbp = VALTODB(sqrt(2.0 * self->p_peak_##A##M[CHN])); \
580 if (dbp > self->p_vpeak_##A[CHN]) { \
581 self->p_vpeak_##A[CHN] = dbp; \
582 } else if (self->meter_falloff == 0) { \
583 self->p_vpeak_##A[CHN] = dbp; \
584 } else { \
585 self->p_vpeak_##A[CHN] -= self->meter_falloff; \
586 self->p_vpeak_##A[CHN] = MAX(dbp, self->p_vpeak_##A[CHN]); \
587 } \
588 forge_kvcontrolmessage(&self->forge, &self->uris, ID, (self->p_vpeak_##A [CHN])); \
589 }
590
591 /* report peaks to UI */
592 self->p_peakcnt += n_samples;
593 if (self->p_peakcnt > ascnt) {
594
595 PKF(in, C_LEFT, METER_IN_LEFT)
596 PKF(in, C_RIGHT, METER_IN_RIGHT);
597 PKF(out, C_LEFT, METER_OUT_LEFT);
598 PKF(out, C_RIGHT, METER_OUT_RIGHT);
599
600 PKM(in, C_LEFT, PEAK_IN_LEFT);
601 PKM(in, C_RIGHT, PEAK_IN_RIGHT);
602 PKM(out, C_LEFT, PEAK_OUT_LEFT);
603 PKM(out, C_RIGHT, PEAK_OUT_RIGHT);
604
605 #define RMSF(A) sqrt( ( (A) / (double)self->phase_integrate_max ) + 1.0e-12 )
606 double phase = 0.0;
607 const double phasdiv = self->p_phase_outP + self->p_phase_outN;
608 if (phasdiv >= 1.0e-6) {
609 phase = (RMSF(self->p_phase_outP) - RMSF(self->p_phase_outN)) / RMSF(phasdiv);
610 } else if (self->p_phase_outP > .001 && self->p_phase_outN > .001) {
611 phase = 1.0;
612 }
613
614 forge_kvcontrolmessage(&self->forge, &self->uris, PHASE_OUT, phase);
615
616 self->p_peakcnt -= ascnt;
617 for (c=0; c < CHANNELS; ++c) {
618 self->p_peak_in[c] = -INFINITY;
619 self->p_peak_out[c] = -INFINITY;
620 self->p_peak_inM[c] = -INFINITY;
621 self->p_peak_outM[c] = -INFINITY;
622 }
623 }
624
625 /* report values to UI - if changed*/
626 float bal = gain_to_db(fabsf(gain_left));
627 if (bal != self->p_bal[C_LEFT]) {
628 forge_kvcontrolmessage(&self->forge, &self->uris, GAIN_LEFT, bal);
629 }
630 self->p_bal[C_LEFT] = bal;
631
632 bal = gain_to_db(fabsf(gain_right));
633 if (bal != self->p_bal[C_RIGHT]) {
634 forge_kvcontrolmessage(&self->forge, &self->uris, GAIN_RIGHT, bal);
635 }
636 self->p_bal[C_RIGHT] = bal;
637
638 if (self->p_dly[C_LEFT] != self->c_dly[C_LEFT]) {
639 forge_kvcontrolmessage(&self->forge, &self->uris, DELAY_LEFT, (float) self->c_dly[C_LEFT] / self->samplerate);
640 }
641 self->p_dly[C_LEFT] = self->c_dly[C_LEFT];
642
643 if (self->p_dly[C_RIGHT] != self->c_dly[C_RIGHT]) {
644 forge_kvcontrolmessage(&self->forge, &self->uris, DELAY_RIGHT, (float) self->c_dly[C_RIGHT] / self->samplerate);
645 }
646 self->p_dly[C_RIGHT] = self->c_dly[C_RIGHT];
647
648 }
649
650 static LV2_Handle
instantiate(const LV2_Descriptor * descriptor,double rate,const char * bundle_path,const LV2_Feature * const * features)651 instantiate(const LV2_Descriptor* descriptor,
652 double rate,
653 const char* bundle_path,
654 const LV2_Feature* const* features)
655 {
656 int i;
657 BalanceControl* self = (BalanceControl*) calloc(1, sizeof(BalanceControl));
658 if (!self) return NULL;
659
660 for (int i=0; features[i]; ++i) {
661 if (!strcmp(features[i]->URI, LV2_URID__map)) {
662 self->map = (LV2_URID_Map*)features[i]->data;
663 }
664 }
665
666 if (!self->map) {
667 fprintf(stderr, "BLClv2 error: Host does not support urid:map\n");
668 free(self);
669 return NULL;
670 }
671
672 map_balance_uris(self->map, &self->uris);
673 lv2_atom_forge_init(&self->forge, self->map);
674
675 self->peak_integrate_max = PEAK_INTEGRATION_MAX * rate;
676 self->peak_integrate_pref = PEAK_INTEGRATION_TIME * rate;
677 self->phase_integrate_max = PHASE_INTEGRATION_TIME * rate;
678 self->meter_falloff = METER_FALLOFF / UPDATE_FREQ;
679 self->peak_hold = PEAK_HOLD_TIME * UPDATE_FREQ;
680
681 assert(self->peak_integrate_max >= 0);
682 assert(self->phase_integrate_max > 0);
683 assert(self->peak_integrate_max <= self->phase_integrate_max);
684
685 for (i=0; i < CHANNELS; ++i) {
686 self->c_amp[i] = 1.0;
687 self->c_dly[i] = 0;
688 self->r_ptr[i] = self->w_ptr[i] = 0;
689 memset(self->buffer[i], 0, sizeof(float) * MAXDELAY);
690 self->p_peak_inPi[i] = (double*) malloc(self->peak_integrate_max * sizeof(double));
691 self->p_peak_outPi[i] = (double*) malloc(self->peak_integrate_max * sizeof(double));
692 }
693 self->p_phase_outPi = (double*) malloc(self->phase_integrate_max * sizeof(double));
694 self->p_phase_outNi = (double*) malloc(self->phase_integrate_max * sizeof(double));
695
696 self->uicom_active = 0;
697 self->c_monomode = 0;
698 self->samplerate = rate;
699 self->queue_stateswitch = 0;
700
701 reset_uicom(self);
702
703 return (LV2_Handle)self;
704 }
705
706 static void
connect_port(LV2_Handle instance,uint32_t port,void * data)707 connect_port(LV2_Handle instance,
708 uint32_t port,
709 void* data)
710 {
711 BalanceControl* self = (BalanceControl*)instance;
712
713 switch ((PortIndex)port) {
714 case BLC_TRIM:
715 self->trim = (float*) data;
716 break;
717 case BLC_PHASEL:
718 self->phase[C_LEFT] = (float*) data;
719 break;
720 case BLC_PHASER:
721 self->phase[C_RIGHT] = (float*) data;
722 break;
723 case BLC_BALANCE:
724 self->balance = (float*) data;
725 break;
726 case BLC_UNIYGAIN:
727 self->unitygain = (float*) data;
728 break;
729 case BLC_MONOIZE:
730 self->monomode = (float*) data;
731 break;
732 case BLC_DLYL:
733 self->delay[C_LEFT] = (float*) data;
734 break;
735 case BLC_DLYR:
736 self->delay[C_RIGHT] = (float*) data;
737 break;
738 case BLC_INL:
739 self->input[C_LEFT] = (float*) data;
740 break;
741 case BLC_INR:
742 self->input[C_RIGHT] = (float*) data;
743 break;
744 case BLC_OUTL:
745 self->output[C_LEFT] = (float*) data;
746 break;
747 case BLC_OUTR:
748 self->output[C_RIGHT] = (float*) data;
749 break;
750 case BLC_UINOTIFY:
751 self->notify = (LV2_Atom_Sequence*)data;
752 break;
753 case BLC_UICONTROL:
754 self->control = (const LV2_Atom_Sequence*)data;
755 break;
756 }
757 }
758
759 static LV2_State_Status
save(LV2_Handle instance,LV2_State_Store_Function store,LV2_State_Handle handle,uint32_t flags,const LV2_Feature * const * features)760 save(LV2_Handle instance,
761 LV2_State_Store_Function store,
762 LV2_State_Handle handle,
763 uint32_t flags,
764 const LV2_Feature* const* features)
765 {
766 BalanceControl* self = (BalanceControl*)instance;
767
768 char cfg[1024];
769 int off = 0;
770
771 off += sprintf(cfg + off, "peak_integrate=%f\n", self->peak_integrate_pref / self->samplerate);
772 off += sprintf(cfg + off, "meter_falloff=%f\n", self->meter_falloff * (float) UPDATE_FREQ);
773 off += sprintf(cfg + off, "peak_hold=%f\n", self->peak_hold / (float) UPDATE_FREQ);
774
775 store(handle, self->uris.blc_state,
776 cfg, strlen(cfg) + 1,
777 self->uris.atom_String,
778 LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
779 return LV2_STATE_SUCCESS;
780 }
781
782 static LV2_State_Status
restore(LV2_Handle instance,LV2_State_Retrieve_Function retrieve,LV2_State_Handle handle,uint32_t flags,const LV2_Feature * const * features)783 restore(LV2_Handle instance,
784 LV2_State_Retrieve_Function retrieve,
785 LV2_State_Handle handle,
786 uint32_t flags,
787 const LV2_Feature* const* features)
788 {
789 BalanceControl* self = (BalanceControl*)instance;
790 size_t size;
791 uint32_t type;
792 uint32_t valflags;
793 const void* value = retrieve(handle, self->uris.blc_state, &size, &type, &valflags);
794
795 if (!value) {
796 return LV2_STATE_ERR_UNKNOWN;
797 }
798
799 const char* cfg = (const char*)value;
800 const char *te, *ts = cfg;
801
802 while (ts && *ts && (te=strchr(ts, '\n'))) {
803 char *val;
804 char kv[1024];
805 memcpy(kv, ts, te-ts);
806 kv[te-ts]=0;
807 if((val=strchr(kv,'='))) {
808 *val=0;
809 if (!strcmp(kv, "peak_integrate")) {
810 self->state[0] = atof(val+1);
811 } else if (!strcmp(kv, "meter_falloff")) {
812 self->state[1] = atof(val+1);
813 } else if (!strcmp(kv, "peak_hold")) {
814 self->state[2] = atof(val+1);
815 }
816 }
817 ts=te+1;
818 }
819 self->queue_stateswitch = 1;
820 return LV2_STATE_SUCCESS;
821 }
822
823 static void
cleanup(LV2_Handle instance)824 cleanup(LV2_Handle instance)
825 {
826 BalanceControl* self = (BalanceControl*)instance;
827 for (int i=0; i < CHANNELS; ++i) {
828 free(self->p_peak_inPi[i]);
829 free(self->p_peak_outPi[i]);
830 }
831 free(self->p_phase_outPi);
832 free(self->p_phase_outNi);
833 free(instance);
834 }
835
836 const void*
extension_data(const char * uri)837 extension_data(const char* uri)
838 {
839 static const LV2_State_Interface state = { save, restore };
840 if (!strcmp(uri, LV2_STATE__interface)) {
841 return &state;
842 }
843 return NULL;
844 }
845
846 static const LV2_Descriptor descriptor = {
847 BLC_URI,
848 instantiate,
849 connect_port,
850 NULL,
851 run,
852 NULL,
853 cleanup,
854 extension_data
855 };
856
857 #undef LV2_SYMBOL_EXPORT
858 #ifdef _WIN32
859 # define LV2_SYMBOL_EXPORT __declspec(dllexport)
860 #else
861 # define LV2_SYMBOL_EXPORT __attribute__ ((visibility ("default")))
862 #endif
863 LV2_SYMBOL_EXPORT
864 const LV2_Descriptor*
lv2_descriptor(uint32_t index)865 lv2_descriptor(uint32_t index)
866 {
867 switch (index) {
868 case 0:
869 return &descriptor;
870 default:
871 return NULL;
872 }
873 }
874