1 /*
2     Copyright (C) 2011 Tom Szilagyi
3 
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18 
19 #include <inttypes.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <stdio.h>
23 #include <math.h>
24 #include <time.h>
25 
26 #include <glib.h>
27 #include <gtk/gtk.h>
28 #include <sndfile.h>
29 #include <samplerate.h>
30 #include <zita-convolver.h>
31 #include <lv2.h>
32 
33 #include "ir.h"
34 #include "ir_utils.h"
35 
36 #define ZITA_CONVOLVER_VERSION  0
37 #if ZITA_CONVOLVER_MAJOR_VERSION == 3
38 #undef ZITA_CONVOLVER_VERSION
39 #define ZITA_CONVOLVER_VERSION  3
40 #elif ZITA_CONVOLVER_MAJOR_VERSION == 4
41 #undef ZITA_CONVOLVER_VERSION
42 #define ZITA_CONVOLVER_VERSION  4
43 #else
44 #error "This version of IR requires zita-convolver 3.x.x or 4.x.x"
45 #endif
46 
47 /* You may need to change these to match your JACK server setup!
48  *
49  * Priority should match -P parameter passed to jackd.
50  * Sched.class: either SCHED_FIFO or SCHED_RR (I think Jack uses SCHED_FIFO).
51  *
52  * THREAD_SYNC_MODE must be true if you want to use the plugin in Jack
53  * freewheeling mode (eg. while exporting in Ardour). You may only use
54  * false if you *only* run the plugin realtime.
55  */
56 #define CONVPROC_SCHEDULER_PRIORITY 0
57 #define CONVPROC_SCHEDULER_CLASS SCHED_FIFO
58 #define THREAD_SYNC_MODE true
59 
60 
61 static LV2_Descriptor * IR_Descriptor = NULL;
62 static GKeyFile * keyfile = NULL;
63 static GtkListStore * store_bookmarks = NULL;
64 G_LOCK_DEFINE_STATIC(conv_configure_lock);
65 
connectPortIR(LV2_Handle instance,uint32_t port,void * data)66 static void connectPortIR(LV2_Handle instance,
67 			  uint32_t port,
68 			  void * data) {
69 
70 	IR * ir = (IR *)instance;
71 
72 	switch (port) {
73 	/* Audio I/O */
74 	case IR_PORT_INPUT_L:
75 		ir->in_L = (const float*)data;
76 		break;
77 	case IR_PORT_INPUT_R:
78 		ir->in_R = (const float*)data;
79 		break;
80 	case IR_PORT_OUTPUT_L:
81 		ir->out_L = (float*)data;
82 		break;
83 	case IR_PORT_OUTPUT_R:
84 		ir->out_R = (float*)data;
85 		break;
86 
87 	/* Control */
88 	case IR_PORT_REVERSE:
89 		ir->port_reverse = (float*)data;
90 		break;
91 	case IR_PORT_PREDELAY:
92 		ir->port_predelay = (float*)data;
93 		break;
94 	case IR_PORT_ATTACK:
95 		ir->port_attack = (float*)data;
96 		break;
97 	case IR_PORT_ATTACKTIME:
98 		ir->port_attacktime = (float*)data;
99 		break;
100 	case IR_PORT_ENVELOPE:
101 		ir->port_envelope = (float*)data;
102 		break;
103 	case IR_PORT_LENGTH:
104 		ir->port_length = (float*)data;
105 		break;
106 	case IR_PORT_STRETCH:
107 		ir->port_stretch = (float*)data;
108 		break;
109 	case IR_PORT_STEREO_IN:
110 		ir->port_stereo_in = (float*)data;
111 		break;
112 	case IR_PORT_STEREO_IR:
113 		ir->port_stereo_ir = (float*)data;
114 		break;
115 	case IR_PORT_AGC_SW:
116 		ir->port_agc_sw = (float*)data;
117 		break;
118 	case IR_PORT_DRY_SW:
119 		ir->port_dry_sw = (float*)data;
120 		break;
121 	case IR_PORT_DRY_GAIN:
122 		ir->port_dry_gain = (float*)data;
123 		break;
124 	case IR_PORT_WET_SW:
125 		ir->port_wet_sw = (float*)data;
126 		break;
127 	case IR_PORT_WET_GAIN:
128 		ir->port_wet_gain = (float*)data;
129 		break;
130 
131 	/* Save/Restore */
132 	case IR_PORT_FHASH_0:
133 		ir->port_fhash_0 = (float*)data;
134 		break;
135 	case IR_PORT_FHASH_1:
136 		ir->port_fhash_1 = (float*)data;
137 		break;
138 	case IR_PORT_FHASH_2:
139 		ir->port_fhash_2 = (float*)data;
140 		break;
141 
142 	/* Meter ports */
143 	case IR_PORT_METER_DRY_L:
144 		ir->port_meter_dry_L = (float*)data;
145 		break;
146 	case IR_PORT_METER_DRY_R:
147 		ir->port_meter_dry_R = (float*)data;
148 		break;
149 	case IR_PORT_METER_WET_L:
150 		ir->port_meter_wet_L = (float*)data;
151 		break;
152 	case IR_PORT_METER_WET_R:
153 		ir->port_meter_wet_R = (float*)data;
154 		break;
155 
156 	/* Latency port */
157 	case IR_PORT_LATENCY:
158 		ir->port_latency = (float*)data;
159 		break;
160 	}
161 }
162 
free_ir_samples(IR * ir)163 static void free_ir_samples(IR * ir) {
164 	if (ir->ir_samples != 0) {
165 		float **p = ir->ir_samples;
166 		while (*p) {
167 			free(*p++);
168 		}
169 		free(ir->ir_samples);
170 		ir->ir_samples = 0;
171 	}
172 }
173 
free_conv_safely(Convproc * conv)174 static void free_conv_safely(Convproc * conv) {
175 	unsigned int state;
176 
177 	if (!conv) {
178 		return;
179 	}
180 	state = conv->state();
181 	if (state != Convproc::ST_STOP) {
182 		conv->stop_process();
183 	}
184 	conv->cleanup();
185 	delete conv;
186 }
187 
free_convproc(IR * ir)188 static void free_convproc(IR * ir) {
189 	free_conv_safely(ir->conv_0);
190 	ir->conv_0 = 0;
191 	free_conv_safely(ir->conv_1);
192 	ir->conv_1 = 0;
193 }
194 
cleanupIR(LV2_Handle instance)195 static void cleanupIR(LV2_Handle instance) {
196 	IR * ir = (IR*)instance;
197 
198 	if (!ir->first_conf_done) {
199 		ir->conf_thread_exit = 1;
200 		g_thread_join(ir->conf_thread);
201 	}
202 
203 	free_convproc(ir);
204 	if (ir->source_samples != NULL) {
205 		free(ir->source_samples);
206 		ir->source_samples = NULL;
207 	}
208 	if (ir->resampled_samples != NULL) {
209 		free(ir->resampled_samples);
210 		ir->resampled_samples = NULL;
211 	}
212 	free_ir_samples(ir);
213 
214 	if (ir->source_path && (strlen(ir->source_path) > 0)) {
215 		save_path(keyfile, ir->source_path);
216 		free(ir->source_path);
217 	}
218 
219 	free(instance);
220 }
221 
222 /* Read IR audio file
223  *   input data: source_path
224  *  output data: nchan, source_samples
225  * return value: 0 OK, < 0 error
226  */
load_sndfile(IR * ir)227 static int load_sndfile(IR * ir) {
228 
229 	int length = 0;
230 	int offset = 0;
231 	float * buff;
232 
233 	if (!(ir->source_path) || *ir->source_path != '/') {
234 		fprintf(stderr, "IR: load_sndfile error: %s is not an absolute path\n",
235 			ir->source_path);
236 		return -1;
237 	}
238 
239 	ir->Finp = sf_open(ir->source_path, SFM_READ, &ir->Sinp);
240 	if (!ir->Finp) {
241 		fprintf(stderr, "IR: unable to read IR input file '%s'\n",
242 			ir->source_path);
243 		return -1;
244 	}
245 
246 	ir->source_samplerate = ir->Sinp.samplerate;
247 	ir->nchan = ir->Sinp.channels;
248 	ir->source_nfram = ir->Sinp.frames;
249 
250 	if ((ir->nchan != 1) && (ir->nchan != 2) && (ir->nchan != 4)) {
251 		fprintf(stderr, "IR: channel count %d of '%s' not supported.\n",
252 			ir->nchan, ir->source_path);
253 		sf_close(ir->Finp);
254 		return -1;
255 	}
256 
257 	length = ir->source_nfram;
258 	if (ir->source_samples != NULL) {
259 		free(ir->source_samples);
260 	}
261 	ir->source_samples = (float*)malloc(ir->nchan * length * sizeof(float));
262         buff = new float[BSIZE * ir->nchan];
263 
264 	while (length) {
265 		int n = (length > BSIZE) ? BSIZE : length;
266 		n = sf_readf_float(ir->Finp, buff, n);
267 		if (n < 0) {
268 			fprintf(stderr, "IR: error reading file %s\n", ir->source_path);
269 			sf_close(ir->Finp);
270 			delete[] buff;
271 			return -1;
272 		}
273 		if (n) {
274 			for (int i = 0; i < n * ir->nchan; i++) {
275 				ir->source_samples[offset + i] = buff[i];
276 			}
277 			offset += n * ir->nchan;
278 			length -= n;
279 		}
280 	}
281 
282 	delete[] buff;
283 	sf_close(ir->Finp);
284 
285 	return 0;
286 }
287 
288 /* Resample the IR samples, taking stretch into account
289  *    input: source_nfram, source_samples
290  *   output: ir_nfram, resampled_samples
291  * This function sets up the resampling operation
292  * return: 0: OK, 1: OK, no SRC needed, -1: error
293  */
resample_init(IR * ir)294 static int resample_init(IR * ir) {
295 
296 	float stretch = *ir->port_stretch / 100.0;
297 	float fs_out = ir->sample_rate * stretch;
298 
299 	if (!ir->source_samples || !ir->source_nfram || !ir->nchan) {
300 		return -1;
301 	}
302 
303 	if (ir->source_samplerate == (unsigned int)fs_out) {
304 		ir->ir_nfram = ir->source_nfram;
305 		if (ir->resampled_samples != NULL) {
306 		        free(ir->resampled_samples);
307 		}
308 		ir->resampled_samples =
309 		        (float*)calloc(ir->nchan * ir->ir_nfram, sizeof(float));
310 		for (int i = 0; i < ir->nchan * ir->ir_nfram; i++) {
311 		        ir->resampled_samples[i] = ir->source_samples[i];
312 		}
313 		return 1;
314 	}
315 
316 	ir->ir_nfram = ir->source_nfram * fs_out / ir->source_samplerate + 1;
317 
318 	//printf("IR Resampler: fs_in=%d fs_out=%f\n", ir->source_samplerate, fs_out);
319 	//printf("              samples_in=%d samples_out=%d\n", ir->source_nfram, ir->ir_nfram);
320 
321 	if (ir->resampled_samples != NULL) {
322 		free(ir->resampled_samples);
323 	}
324 	ir->resampled_samples = (float*)calloc(ir->nchan * ir->ir_nfram, sizeof(float));
325 
326 	int src_error;
327 	ir->src_state = src_new(SRC_SINC_BEST_QUALITY, ir->nchan, &src_error);
328 	if (ir->src_state == NULL) {
329 		fprintf(stderr, "IR: src_new() error: %s\n", src_strerror(src_error));
330 		return -1;
331 	}
332 	src_error = src_set_ratio(ir->src_state, fs_out / ir->source_samplerate);
333 	if (src_error) {
334 		fprintf(stderr, "IR: src_set_ratio() error: %s, new_ratio = %g\n",
335 			src_strerror(src_error), fs_out / ir->source_samplerate);
336 		src_delete(ir->src_state);
337 		return -1;
338 	}
339 
340 	ir->src_progress = 0.0;
341 	ir->src_in_frames = ir->source_nfram;
342 	ir->src_out_frames = 0;
343 	ir->src_data.data_in = ir->source_samples;
344 	ir->src_data.data_out = ir->resampled_samples;
345 	ir->src_data.input_frames_used = 0;
346 	ir->src_data.output_frames_gen = 0;
347 	ir->src_data.src_ratio = fs_out / ir->source_samplerate; /* really needed? */
348 	ir->src_data.end_of_input = 0;
349 	return 0;
350 }
351 
352 /* Do a chunk of resample processing
353  * return: 0: OK, not ready (call it again); 1: ready; -1: error
354  * ir->src_progress can be used to track progress of resampling
355  */
resample_do(IR * ir)356 static int resample_do(IR * ir) {
357 	if (!ir->src_in_frames) {
358 		return 1;
359 	}
360 
361 	ir->src_data.input_frames = (ir->src_in_frames > BSIZE_SR) ? BSIZE_SR : ir->src_in_frames;
362 	ir->src_data.output_frames = ir->ir_nfram - ir->src_out_frames;
363 
364 	//printf("src_progress %f\n", ir->src_progress);
365 	int src_error = src_process(ir->src_state, &ir->src_data);
366 	if (src_error != 0) {
367 		fprintf(stderr, "IR: src_process() error: %s\n", src_strerror(src_error));
368 		src_delete(ir->src_state);
369 		return -1;
370 	}
371 
372 	ir->src_data.data_in += ir->nchan * ir->src_data.input_frames_used;
373 	ir->src_data.data_out += ir->nchan * ir->src_data.output_frames_gen;
374 	ir->src_in_frames -= ir->src_data.input_frames_used;
375 	ir->src_out_frames += ir->src_data.output_frames_gen;
376 	ir->src_progress = (float)ir->src_out_frames / ir->ir_nfram;
377 
378 	return ir->src_in_frames ? 0 : 1;
379 }
380 
381 /* Finish resampling; call this after resample_do returned 1 */
resample_cleanup(IR * ir)382 static void resample_cleanup(IR * ir) {
383 	if (ir->src_out_frames < ir->ir_nfram) {
384 		ir->ir_nfram = ir->src_out_frames;
385 	}
386 	ir->src_progress = 1.0;
387 	src_delete(ir->src_state);
388 }
389 
390 /* In place processing on ir_samples[] */
process_envelopes(IR * ir)391 static void process_envelopes(IR * ir) {
392 
393 	int attack_time_s = (int)*ir->port_attacktime * ir->sample_rate / 1000;
394 	float attack_pc = *ir->port_attack;
395 	float length_pc = *ir->port_length;
396 	float env_pc = *ir->port_envelope;
397 
398 	compute_envelope(ir->ir_samples, ir->nchan, ir->ir_nfram,
399 			 attack_time_s, attack_pc,
400 			 env_pc, length_pc);
401 }
402 
403 /* Mid-Side based Stereo width effect */
ms_stereo(float width,float * lp,float * rp,int length)404 static void ms_stereo(float width, float * lp, float * rp, int length) {
405 
406 	float w = width / 100.0f;
407 	float x = (1.0 - w) / (1.0 + w); /* M-S coeff.; L_out = L + x*R; R_out = x*L + R */
408 	float L, R;
409 
410 	for (int i = 0; i < length; i++) {
411 		L = *lp;
412 		R = *rp;
413 		*lp++ = L + x * R;
414 		*rp++ = R + x * L;
415 	}
416 }
417 
418 /* Prepare samples to be loaded into convolution engine
419  *    input: ir_nfram, resampled_samples
420  *   output: ir_samples
421  *   parameters: all plugin parameters except stretch,
422  *               stereo_in, dry_*, wet_*
423  */
prepare_convdata(IR * ir)424 static void prepare_convdata(IR * ir) {
425 
426 	if (!ir->resampled_samples || !ir->ir_nfram || !ir->nchan) {
427 		return;
428 	}
429 
430 	free_ir_samples(ir);
431 	ir->ir_samples = (float**)malloc((1 + ir->nchan) * sizeof(float*));
432 	for (int i = 0; i < ir->nchan; i++) {
433 		ir->ir_samples[i] = (float*)malloc(ir->ir_nfram * sizeof(float));
434 	}
435 	ir->ir_samples[ir->nchan] = NULL;
436 
437 	/* de-interleave resampled_samples to ir_samples */
438 	for (int ch = 0; ch < ir->nchan; ch++) {
439 		float * p = ir->resampled_samples + ch;
440 		float * q = ir->ir_samples[ch];
441 		int nch = ir->nchan;
442 		int nfram = ir->ir_nfram;
443 		for (int i = 0; i < nfram; i++) {
444 			q[i] = p[i * nch];
445 		}
446 	}
447 
448 	/* Autogain calculation */
449 	float pow = 0;
450 	for (int ch = 0; ch < ir->nchan; ch++) {
451 		float * p = ir->ir_samples[ch];
452 		for (int i = 0; i < ir->ir_nfram; i++) {
453 			pow += p[i] * p[i];
454 		}
455 	}
456 	pow /= ir->nchan;
457 	ir->autogain_new = -10.0 * log10f(pow / 6.0);
458 
459 	/* IR stereo width */
460 	if (ir->nchan == 2) {
461 		ms_stereo(*ir->port_stereo_ir, ir->ir_samples[0], ir->ir_samples[1], ir->ir_nfram);
462 	} else if (ir->nchan == 4) {
463 		ms_stereo(*ir->port_stereo_ir, ir->ir_samples[0], ir->ir_samples[1], ir->ir_nfram);
464 		ms_stereo(*ir->port_stereo_ir, ir->ir_samples[2], ir->ir_samples[3], ir->ir_nfram);
465 	}
466 	process_envelopes(ir);
467 
468 	/* reverse ir vector if needed */
469 	int reverse = (*ir->port_reverse > 0.0f) ? 1 : 0;
470 	if (reverse) {
471 		float tmp;
472 		int nfram = ir->ir_nfram;
473 		for (int ch = 0; ch < ir->nchan; ch++) {
474 			float * p = ir->ir_samples[ch];
475 			for (int i = 0, j = nfram-1; i < nfram/2; i++, j--) {
476 				tmp = p[i];
477 				p[i] = p[j];
478 				p[j] = tmp;
479 			}
480 		}
481 	}
482 }
483 
484 /* Initialise (the next) convolution engine to use */
init_conv(IR * ir)485 static void init_conv(IR * ir) {
486 
487 	Convproc * conv;
488 	int req_to_use;
489 
490 	if (!ir->ir_samples || !ir->ir_nfram || !ir->nchan) {
491 		return;
492 	}
493 
494 	if (ir->conv_in_use != ir->conv_req_to_use) {
495 		fprintf(stderr, "IR init_conv: error, engine still in use!\n");
496 		return;
497 	}
498 
499 	if (ir->conv_in_use == 1) { /* new one will be 0th */
500 		free_conv_safely(ir->conv_0);
501 		ir->conv_0 = new Convproc;
502 		conv = ir->conv_0;
503 		req_to_use = 0;
504 	} else { /* new one will be 1st */
505 		free_conv_safely(ir->conv_1);
506 		ir->conv_1 = new Convproc;
507 		conv = ir->conv_1;
508 		req_to_use = 1;
509 	}
510 
511 	uint32_t predelay_samples = (int)*ir->port_predelay * ir->sample_rate / 1000;
512 	uint32_t length = ir->maxsize;
513 	int nfram;
514 
515 	if (predelay_samples + ir->ir_nfram > length) {
516 		fprintf(stderr, "IR: warning: truncated IR to %d samples\n", length);
517 		nfram = length - predelay_samples;
518 	} else {
519 		nfram = ir->ir_nfram;
520 		length = predelay_samples + ir->ir_nfram;
521 	}
522 
523 	if (length < ir->block_length) {
524 		length = ir->block_length;
525 	}
526 
527 	G_LOCK(conv_configure_lock);
528 	//printf("configure length=%d ir->block_length=%d\n", length, ir->block_length);
529 #if ZITA_CONVOLVER_VERSION == 3
530 	if (ir->nchan == 4) {
531 		conv->set_density(1);
532 	}
533 	int ret = conv->configure(2, // n_inputs
534 				  2, // n_outputs
535 				  length,
536 				  ir->block_length,
537 				  ir->block_length,
538 				  Convproc::MAXPART);
539 #elif ZITA_CONVOLVER_VERSION == 4
540 	float density = 0.0f;
541 	if (ir->nchan == 4) {
542 		density = 1.0f;
543 	}
544 	int ret = conv->configure(2, // n_inputs
545 				  2, // n_outputs
546 				  length,
547 				  ir->block_length,
548 				  ir->block_length,
549 				  Convproc::MAXPART,
550 				  density);
551 #endif
552 	G_UNLOCK(conv_configure_lock);
553 	if (ret != 0) {
554 		fprintf(stderr, "IR: can't initialise zita-convolver engine, Convproc::configure returned %d\n", ret);
555 		free_conv_safely(conv);
556 		if (req_to_use == 0) {
557 			ir->conv_0 = NULL;
558 		} else {
559 			ir->conv_1 = NULL;
560 		}
561 		return;
562 	}
563 
564 	switch (ir->nchan) {
565 	case 1: /* both input channels are convolved with the same IR */
566 		conv->impdata_create(0, 0, 1, ir->ir_samples[0],
567 				     predelay_samples, nfram + predelay_samples);
568 		conv->impdata_copy(0, 0, 1, 1);
569 		break;
570 	case 2: /* left channel convolved with left IR channel yields left output
571 		   same for the right channel */
572 		conv->impdata_create(0, 0, 1, ir->ir_samples[0],
573 				     predelay_samples, nfram + predelay_samples);
574 		conv->impdata_create(1, 1, 1, ir->ir_samples[1],
575 				     predelay_samples, nfram + predelay_samples);
576 		break;
577 	case 4: /* IR is a full matrix:  / in_L -> out_L   in_L -> out_R \
578 		                         \ in_R -> out_L   in_R -> out_R /  */
579 		conv->impdata_create(0, 0, 1, ir->ir_samples[0],
580 				     predelay_samples, nfram + predelay_samples);
581 		conv->impdata_create(0, 1, 1, ir->ir_samples[1],
582 				     predelay_samples, nfram + predelay_samples);
583 		conv->impdata_create(1, 0, 1, ir->ir_samples[2],
584 				     predelay_samples, nfram + predelay_samples);
585 		conv->impdata_create(1, 1, 1, ir->ir_samples[3],
586 				     predelay_samples, nfram + predelay_samples);
587 		break;
588 	default: printf("IR init_conv: error, impossible value: ir->nchan = %d\n",
589 			ir->nchan);
590 	}
591 
592 	conv->start_process(CONVPROC_SCHEDULER_PRIORITY, CONVPROC_SCHEDULER_CLASS);
593 	ir->conv_req_to_use = req_to_use;
594 }
595 
IR_configurator_thread(gpointer data)596 static gpointer IR_configurator_thread(gpointer data) {
597 
598 	IR * ir = (IR *)data;
599 
600 	struct timespec treq;
601 	struct timespec trem;
602 
603 	while (!ir->conf_thread_exit) {
604 		if ((ir->run > 0) && !ir->first_conf_done) {
605 			uint64_t fhash = fhash_from_ports(ir->port_fhash_0,
606 							  ir->port_fhash_1,
607 							  ir->port_fhash_2);
608 			//printf("IR confthread: fhash = %016" PRIx64 "\n", fhash);
609 			if (fhash) {
610 				char * filename = get_path_from_key(keyfile, fhash);
611 				if (filename) {
612 					//printf("  load filename=%s\n", filename);
613 					ir->source_path = filename;
614 					if (load_sndfile(ir) == 0) {
615 						int r = resample_init(ir);
616 						if (r == 0) {
617 							while ((r == 0) && (!ir->conf_thread_exit)) {
618 								r = resample_do(ir);
619 							}
620 							resample_cleanup(ir);
621 						}
622 						if (r >= 0) {
623 							prepare_convdata(ir);
624 							init_conv(ir);
625 						}
626 					} else {
627 						free(ir->source_path);
628 						ir->source_path = NULL;
629 					}
630 				} else {
631 					fprintf(stderr, "IR: fhash=%016" PRIx64
632 						" was not found in DB\n", fhash);
633 				}
634 			}
635 			ir->first_conf_done = 1;
636 			return NULL;
637 		}
638 
639 		/* sleep 100 ms before checking again */
640 		treq.tv_sec = 0;
641 		treq.tv_nsec = 100000000;
642 		nanosleep(&treq, &trem);
643 	}
644 	return NULL;
645 }
646 
instantiateIR(const LV2_Descriptor * descriptor,double sample_rate,const char * path,const LV2_Feature * const * features)647 static LV2_Handle instantiateIR(const LV2_Descriptor *descriptor,
648 				double sample_rate,
649 				const char *path,
650 				const LV2_Feature *const *features) {
651 
652 	IR * ir = (IR *)calloc(1, sizeof(IR));
653 
654 	ir->sample_rate = sample_rate;
655 	ir->reinit_pending = 0;
656 	ir->maxsize = MAXSIZE;
657 	ir->block_length = IR_DEFAULT_JACK_BUFLEN;
658 	ir->bufconv_pos = 0;
659 	ir->run = -5; /* do nothing for the first 5 run() calls */
660 
661 	ir->load_sndfile = load_sndfile;
662 	ir->resample_init = resample_init;
663 	ir->resample_do = resample_do;
664 	ir->resample_cleanup = resample_cleanup;
665 	ir->prepare_convdata = prepare_convdata;
666 	ir->init_conv = init_conv;
667 
668 	ir->keyfile = keyfile;
669 	ir->store_bookmarks = store_bookmarks;
670 
671 	ir->conf_thread = g_thread_new("IR_configurator_thread",
672                                        IR_configurator_thread, (gpointer)ir);
673 	return (LV2_Handle)ir;
674 }
675 
676 #define ACC_MAX(m,v) (((fabs(v))>(m))?fabs(v):(m))
runIR(LV2_Handle instance,uint32_t n)677 static void runIR(LV2_Handle instance, uint32_t n) {
678 
679 	IR * ir = (IR *)instance;
680 	Convproc * conv;
681 
682 	const float * const in_L = ir->in_L;
683 	const float * const in_R = ir->in_R;
684 	float * const out_L = ir->out_L;
685 	float * const out_R = ir->out_R;
686 
687 	float dry_L_meter = 0.0;
688 	float dry_R_meter = 0.0;
689 	float wet_L_meter = 0.0;
690 	float wet_R_meter = 0.0;
691 
692 	float width = ir->width;
693 	float dry_gain = ir->dry_gain;
694 	float wet_gain = ir->wet_gain;
695 
696 	if (ir->run < 0) { /* XXX safety measure: wait until buffer size stabilizes, bypass until then */
697 		if ((in_L != out_L) || (in_R != out_R)) {
698 			for (unsigned int j = 0; j < n; j++) {
699 				out_L[j] = in_L[j];
700 				out_R[j] = in_R[j];
701 			}
702 		}
703 		ir->run++;
704 		*ir->port_latency = ir->block_length;
705 		return;
706 	}
707 
708 	if (ir->conv_in_use != ir->conv_req_to_use) {
709 		/* call stop_process() on the conv being switched away from
710 		 * so it can be deallocated next time it is needed */
711 		Convproc * conv_from;
712 		if (ir->conv_in_use == 0) {
713 			conv_from = ir->conv_0;
714 		} else {
715 			conv_from = ir->conv_1;
716 		}
717 		if (conv_from) {
718 			conv_from->stop_process();
719 		}
720 
721 		ir->conv_in_use = ir->conv_req_to_use;
722 		ir->autogain = ir->autogain_new;
723 		//printf("IR engine switching to conv_%d  autogain = %f\n", ir->conv_in_use, ir->autogain);
724 
725 		/* fade it up */
726 		wet_gain = 0.0;
727 	}
728 	if (ir->conv_in_use == 0) {
729 		conv = ir->conv_0;
730 	} else {
731 		conv = ir->conv_1;
732 	}
733 
734 	if (n > ir->block_length) {
735 		/* MUST range from IR_DEFAULT_JACK_BUFLEN<<1 to IR_MAXIMUM_JACK_BUFLEN */
736 		if ((n == 2048) || (n == 4096) || (n = 8192) || (n = 16384)) {
737 			/* block size seems to be a valid JACK buffer size */
738 			ir->block_length = n;
739 			ir->reinit_pending = 1;
740 			ir->bufconv_pos = 0;
741 			conv = 0;
742 			//printf("IR block_length = %d\n", n);
743 		}
744 	}
745 
746 	if (n > IR_MAXIMUM_JACK_BUFLEN) {
747 		fprintf(stderr, "IR: being run() with buffer length %d greater than largest supported length %d, bypassing...\n",
748 			n, IR_MAXIMUM_JACK_BUFLEN);
749 		if ((in_L != out_L) || (in_R != out_R)) {
750 			for (unsigned int j = 0; j < n; j++) {
751 				out_L[j] = in_L[j];
752 				out_R[j] = in_R[j];
753 			}
754 		}
755 		return;
756 	}
757 
758 	float agc_gain_raw = (*ir->port_agc_sw > 0.0f) ? DB_CO(ir->autogain) : 1.0f;
759 
760 	float width_raw = *ir->port_stereo_in / 100.0f; /* stereo width */
761 	float dry_sw = (*ir->port_dry_sw > 0.0f) ? 1.0f : 0.0f;
762 	float wet_sw = (*ir->port_wet_sw > 0.0f) ? 1.0f : 0.0f;
763 	float dry_gain_raw = DB_CO(*ir->port_dry_gain) * dry_sw;
764 	float wet_gain_raw = DB_CO(*ir->port_wet_gain) * wet_sw * agc_gain_raw;
765 
766 	float * pi, * qi, * po, * qo, * dL, * dR;
767 	float dry_L, dry_R, wet_L, wet_R;
768 	unsigned int bcp = ir->bufconv_pos;
769 
770 	if (conv != 0) {
771 		pi = conv->inpdata(0);
772 		qi = conv->inpdata(1);
773 		po = conv->outdata(0);
774 		qo = conv->outdata(1);
775 		dL = ir->drybuf_L;
776 		dR = ir->drybuf_R;
777 		float x;
778 		for (unsigned int j = 0; j < n; j++) {
779 			width = width * SMOOTH_CO_1 + width_raw * SMOOTH_CO_0;
780 			x = (1.0 - width) / (1.0 + width); /* M-S coeff. */
781 			pi[bcp] = in_L[j] + x * in_R[j];
782 			qi[bcp] = in_R[j] + x * in_L[j];
783 
784 			dry_gain = SMOOTH_CO_1 * dry_gain + SMOOTH_CO_0 * dry_gain_raw;
785 			wet_gain = SMOOTH_CO_1 * wet_gain + SMOOTH_CO_0 * wet_gain_raw;
786 			dry_L = dL[bcp];
787 			dry_R = dR[bcp];
788 			dL[bcp] = in_L[j] * dry_gain;
789 			dR[bcp] = in_R[j] * dry_gain;
790 			wet_L = po[bcp] * wet_gain;
791 			wet_R = qo[bcp] * wet_gain;
792 			dry_L_meter = ACC_MAX(dry_L_meter, dry_L);
793 			dry_R_meter = ACC_MAX(dry_R_meter, dry_R);
794 			wet_L_meter = ACC_MAX(wet_L_meter, wet_L);
795 			wet_R_meter = ACC_MAX(wet_R_meter, wet_R);
796 			out_L[j] = dry_L + wet_L;
797 			out_R[j] = dry_R + wet_R;
798 
799 			if (++bcp == ir->block_length) {
800 				bcp = 0;
801 				conv->process(THREAD_SYNC_MODE);
802 			}
803 		}
804 	} else { /* convolution engine not available */
805 		dL = ir->drybuf_L;
806 		dR = ir->drybuf_R;
807 		for (unsigned int j = 0; j < n; j++) {
808 			dry_gain = SMOOTH_CO_1 * dry_gain + SMOOTH_CO_0 * dry_gain_raw;
809 			dry_L = dL[bcp];
810 			dry_R = dR[bcp];
811 			dL[bcp] = in_L[j] * dry_gain;
812 			dR[bcp] = in_R[j] * dry_gain;
813 			dry_L_meter = ACC_MAX(dry_L_meter, dry_L);
814 			dry_R_meter = ACC_MAX(dry_R_meter, dry_R);
815 			out_L[j] = dry_L;
816 			out_R[j] = dry_R;
817 
818 			if (++bcp == ir->block_length) {
819 				bcp = 0;
820 			}
821 		}
822 	}
823 
824 	ir->width = width;
825 	ir->dry_gain = dry_gain;
826 	ir->wet_gain = wet_gain;
827 	ir->bufconv_pos = bcp;
828 
829 	*ir->port_meter_dry_L = dry_L_meter;
830 	*ir->port_meter_dry_R = dry_R_meter;
831 	*ir->port_meter_wet_L = wet_L_meter;
832 	*ir->port_meter_wet_R = wet_R_meter;
833 
834 	*ir->port_latency = ir->block_length;
835 	ir->run = 1;
836 }
837 
extdata_IR(const char * uri)838 const void * extdata_IR(const char * uri) {
839 	return NULL;
840 }
841 
init()842 void __attribute__ ((constructor)) init() {
843 
844 	if (zita_convolver_major_version () != ZITA_CONVOLVER_MAJOR_VERSION) {
845 		fprintf(stderr, "IR: compile-time & runtime library versions of zita-convolver do not match!\n");
846 		IR_Descriptor = NULL;
847 		return;
848 	}
849 
850 	if (!g_thread_supported()) {
851 		fprintf(stderr, "IR: This plugin requires a working GLib with GThread.\n");
852 		IR_Descriptor = NULL;
853 		return;
854 	}
855 
856 	IR_Descriptor = (LV2_Descriptor *)malloc(sizeof(LV2_Descriptor));
857 
858 	IR_Descriptor->URI = IR_URI;
859 	IR_Descriptor->instantiate = instantiateIR;
860 	IR_Descriptor->cleanup = cleanupIR;
861 	IR_Descriptor->activate = NULL;
862 	IR_Descriptor->deactivate = NULL;
863 	IR_Descriptor->connect_port = connectPortIR;
864 	IR_Descriptor->run = runIR;
865 	IR_Descriptor->extension_data = extdata_IR;
866 
867 	keyfile = load_keyfile();
868 	store_bookmarks = gtk_list_store_new(2,
869 					     G_TYPE_STRING,  /* visible name (key) */
870 					     G_TYPE_STRING); /* full pathname (value) */
871 	load_bookmarks(keyfile, store_bookmarks);
872 }
873 
fini()874 void __attribute__ ((destructor)) fini() {
875 	save_keyfile(keyfile);
876 	g_key_file_free(keyfile);
877 	g_object_unref(store_bookmarks);
878 	free(IR_Descriptor);
879 }
880 
881 LV2_SYMBOL_EXPORT
lv2_descriptor(uint32_t index)882 const LV2_Descriptor * lv2_descriptor(uint32_t index) {
883 
884 	switch (index) {
885 	case 0:
886 		return IR_Descriptor;
887 	default:
888 		return NULL;
889 	}
890 }
891