1 /* fat1 -- LV2 autotuner
2  *
3  * Copyright (C) 2016 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 <math.h>
20 #include <stdint.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #include <lv2/lv2plug.in/ns/ext/atom/atom.h>
26 #include <lv2/lv2plug.in/ns/ext/atom/forge.h>
27 #include <lv2/lv2plug.in/ns/ext/log/logger.h>
28 #include <lv2/lv2plug.in/ns/ext/midi/midi.h>
29 #include <lv2/lv2plug.in/ns/lv2core/lv2.h>
30 
31 #include "fat1.h"
32 #include "retuner.h"
33 
34 static pthread_mutex_t fftw_planner_lock = PTHREAD_MUTEX_INITIALIZER;
35 static unsigned int    instance_count    = 0;
36 
37 typedef struct {
38 	const LV2_Atom_Sequence* midiin;
39 
40 	/* URI mapping */
41 	LV2_URID midi_MidiEvent;
42 	LV2_URID atom_Object;
43 	LV2_URID fat_panic;
44 	LV2_URID atom_eventTransfer;
45 
46 	/* LV2 Output */
47 	LV2_Log_Log*   log;
48 	LV2_Log_Logger logger;
49 
50 	/* I/O Ports */
51 	float* port[FAT_LAST];
52 
53 	/* internal state */
54 	LV2AT::Retuner* retuner;
55 
56 	int   notes[12];
57 	int   notemask;
58 	int   midimask;
59 	int   midichan;
60 	float pitchbend;
61 	float latency;
62 
63 	bool panic_btn;
64 	bool microtonal;
65 	bool scales;
66 
67 	uint32_t noteset_update_interval;
68 	uint32_t noteset_update_counter;
69 	int      noteset;
70 } Fat1;
71 
72 /* *****************************************************************************
73  * helper functions
74  */
75 
76 static void
77 clear_midimask (Fat1* self)
78 {
79 	for (int i = 0; i < 12; ++i) {
80 		self->notes[i] = 0;
81 	}
82 	self->midimask  = 0;
83 	self->pitchbend = 0;
84 }
85 
86 static void
87 update_midimask (Fat1* self)
88 {
89 	self->midimask = 0;
90 	int b, i;
91 	for (i = 0, b = 1; i < 12; i++, b <<= 1) {
92 		if (self->notes[i])
93 			self->midimask |= b;
94 	}
95 }
96 
97 static int
98 midi_14bit (const uint8_t* const b)
99 {
100 	return (b[1]) | (b[2] << 7);
101 }
102 
103 static int
104 parse_midi (Fat1*                self,
105             uint32_t             tme,
106             const uint8_t* const msg,
107             const uint32_t       size)
108 {
109 	if (size != 3) {
110 		return 0;
111 	}
112 
113 	if ((self->midichan < 0) || ((msg[0] & 0x0f) == self->midichan)) {
114 		const uint32_t n = msg[1];
115 		switch (msg[0] & 0xf0) {
116 			case 0xe0:
117 				self->pitchbend = (midi_14bit (msg) - 8192) / 8192.f;
118 				break;
119 			case 0xb0:
120 				if ((n == 123 || n == 120) && msg[2] == 0) { // midi-panic
121 					clear_midimask (self);
122 				}
123 				break;
124 			case 0x90:
125 				if (msg[2] > 0) {
126 					self->notes[n % 12] += 1;
127 					return 1;
128 				}
129 				// no break -- fallthrough, note-on velocity 0
130 			case 0x80:
131 				if (self->notes[n % 12]) {
132 					self->notes[n % 12] -= 1;
133 					return 1;
134 				}
135 			default:
136 				break;
137 		}
138 	}
139 	return 0;
140 }
141 
142 static int
143 set_scale (int scale_id) {
144 	if (scale_id <= 0 || scale_id > 24) {
145 		/* chromatic */
146 		return 4095;
147 	}
148 
149 	static const bool western[12] = {
150 		1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1
151 	};
152 
153 	if (scale_id > 12) {
154 		scale_id = 1 + (scale_id + 2) % 12;
155 	}
156 
157 	int b, i;
158 	int notemask = 0;
159 	for (i = 0, b = 1; i < 12; i++, b <<= 1) {
160 		int s = (i + 13 - scale_id) % 12;
161 		if (western[s]) {
162 			notemask |= b;
163 		}
164 	}
165 
166 	return notemask;
167 }
168 
169 /* *****************************************************************************
170  * LV2 Plugin
171  */
172 
173 static LV2_Handle
174 instantiate (const LV2_Descriptor*     descriptor,
175              double                    rate,
176              const char*               bundle_path,
177              const LV2_Feature* const* features)
178 {
179 	Fat1*         self = (Fat1*)calloc (1, sizeof (Fat1));
180 	LV2_URID_Map* map  = NULL;
181 
182 	if (0 == strcmp (descriptor->URI, FAT1_URI)) {
183 		self->microtonal = false;
184 		self->scales     = false;
185 	} else if (0 == strcmp (descriptor->URI, FAT1_URI "#microtonal")) {
186 		self->microtonal = true;
187 		self->scales     = false;
188 	} else if (0 == strcmp (descriptor->URI, FAT1_URI "#scales")) {
189 		self->microtonal = false;
190 		self->scales     = true;
191 	} else {
192 		free (self);
193 		return 0;
194 	}
195 
196 	int i;
197 	for (i = 0; features[i]; ++i) {
198 		if (!strcmp (features[i]->URI, LV2_URID__map)) {
199 			map = (LV2_URID_Map*)features[i]->data;
200 		} else if (!strcmp (features[i]->URI, LV2_LOG__log)) {
201 			self->log = (LV2_Log_Log*)features[i]->data;
202 		}
203 	}
204 
205 	lv2_log_logger_init (&self->logger, map, self->log);
206 
207 	if (!map) {
208 		lv2_log_error (&self->logger, "Fat1.lv2 error: Host does not support urid:map\n");
209 		free (self);
210 		return NULL;
211 	}
212 
213 	pthread_mutex_lock (&fftw_planner_lock);
214 	self->retuner = new LV2AT::Retuner (rate);
215 	++instance_count;
216 	pthread_mutex_unlock (&fftw_planner_lock);
217 
218 	self->notemask = 0xfff;
219 	self->midichan = -1;
220 	clear_midimask (self);
221 
222 	self->midi_MidiEvent     = map->map (map->handle, LV2_MIDI__MidiEvent);
223 	self->atom_Object        = map->map (map->handle, LV2_ATOM__Object);
224 	self->fat_panic          = map->map (map->handle, FAT1_URI "#panic");
225 	self->atom_eventTransfer = map->map (map->handle, LV2_ATOM__eventTransfer);
226 
227 	// compare Retuner c'tor
228 	if (rate < 64000) {
229 		self->latency = 1024;
230 	} else if (rate < 128000) {
231 		self->latency = 2048;
232 	} else {
233 		self->latency = 4096;
234 	}
235 	self->noteset_update_interval = rate / 20;
236 	self->noteset_update_counter  = self->noteset_update_interval;
237 	return (LV2_Handle)self;
238 }
239 
240 static void
241 connect_port (LV2_Handle instance,
242               uint32_t   port,
243               void*      data)
244 {
245 	Fat1* self = (Fat1*)instance;
246 
247 	if (port == FAT_MIDI_IN) {
248 		self->midiin = (const LV2_Atom_Sequence*)data;
249 	} else if (port < FAT_LAST) {
250 		self->port[port] = (float*)data;
251 	}
252 }
253 
254 static void
255 connect_port_scales (LV2_Handle instance,
256                      uint32_t   port,
257                      void*      data)
258 {
259 	Fat1* self = (Fat1*)instance;
260 
261 	if (port == FAT_MIDI_IN) {
262 		self->midiin = (const LV2_Atom_Sequence*)data;
263 	} else if (port <= FAT_NOTE) {
264 		self->port[port] = (float*)data;
265 	} else {
266 		switch (port) {
267 			case 13:
268 				self->port[FAT_MASK] = (float*)data;
269 				break;
270 			case 14:
271 				self->port[FAT_NSET] = (float*)data;
272 				break;
273 			case 15:
274 				self->port[FAT_BEND] = (float*)data;
275 				break;
276 			case 16:
277 				self->port[FAT_ERRR] = (float*)data;
278 				break;
279 			case 17:
280 				self->port[FAT_LTNC] = (float*)data;
281 				break;
282 			default:
283 				break;
284 		}
285 	}
286 }
287 
288 static void
289 run (LV2_Handle instance, uint32_t n_samples)
290 {
291 	Fat1* self = (Fat1*)instance;
292 
293 	self->retuner->set_fastmode (*self->port[FAT_FAST]);
294 
295 	if (*self->port[FAT_FAST]) {
296 		*self->port[FAT_LTNC] = self->latency / 4;
297 	} else {
298 		*self->port[FAT_LTNC] = self->latency;
299 	}
300 
301 	if (!self->midiin || n_samples == 0) {
302 		return;
303 	}
304 
305 	/* set mode and midi-channel */
306 	const int mchn = rint (*self->port[FAT_MCHN]);
307 	if (mchn <= 0 || mchn > 16) {
308 		self->midichan = -1;
309 	} else {
310 		self->midichan = mchn - 1;
311 	}
312 
313 	int mode = rint (*self->port[FAT_MODE]);
314 	if (mode < 0)
315 		mode = 0;
316 	if (mode > 2)
317 		mode = 2;
318 
319 	if (mode == 2) {
320 		clear_midimask (self);
321 	}
322 
323 	/* Process incoming midi events */
324 	bool            update_midi = false;
325 	LV2_Atom_Event* ev          = lv2_atom_sequence_begin (&(self->midiin)->body);
326 	while (!lv2_atom_sequence_is_end (&(self->midiin)->body, (self->midiin)->atom.size, ev)) {
327 		if (ev->body.type == self->midi_MidiEvent) {
328 			update_midi |= parse_midi (self, ev->time.frames, (uint8_t*)(ev + 1), ev->body.size);
329 
330 		} else if (ev->body.type == self->atom_Object) {
331 			const LV2_Atom_Object* obj = (LV2_Atom_Object*)&ev->body;
332 			if (obj->body.otype == self->fat_panic) {
333 				clear_midimask (self);
334 			}
335 		}
336 		ev = lv2_atom_sequence_next (ev);
337 	}
338 	if (update_midi) {
339 		update_midimask (self);
340 	}
341 
342 	/* prepare key-range midi/fixed */
343 	if (mode != 1) {
344 		if (self->scales) {
345 			self->notemask = set_scale (rint (*self->port[FAT_NOTE]));
346 		} else {
347 			self->notemask = 0;
348 			for (int i = 0; i < 12; ++i) {
349 				if (*self->port[FAT_NOTE + i] > 0) {
350 					self->notemask |= 1 << i;
351 				}
352 			}
353 		}
354 	}
355 
356 	int notes;
357 	switch (mode) {
358 		case 1:
359 			notes = self->midimask;
360 			break;
361 		case 2:
362 			notes           = self->notemask;
363 			self->pitchbend = 0.f;
364 			break;
365 		default:
366 			notes = self->midimask ? self->midimask : self->notemask;
367 	}
368 
369 	/* push config to retuner */
370 	self->retuner->set_refpitch (*self->port[FAT_TUNE]);
371 	self->retuner->set_notebias (*self->port[FAT_BIAS]);
372 	self->retuner->set_corrfilt (*self->port[FAT_FILT]);
373 	self->retuner->set_corrgain (*self->port[FAT_CORR]);
374 	self->retuner->set_corroffs (*self->port[FAT_OFFS] + *self->port[FAT_PBST] * self->pitchbend);
375 	self->retuner->set_notemask (notes);
376 
377 	if (self->microtonal) {
378 		for (int i = 0; i < 12; ++i) {
379 			self->retuner->set_notescale (i, *self->port[FAT_SCALE + i]);
380 		}
381 	}
382 
383 	/* process */
384 	self->retuner->process (n_samples, self->port[FAT_INPUT], self->port[FAT_OUTPUT]);
385 
386 	self->noteset_update_counter += n_samples;
387 
388 	if (self->noteset_update_counter > self->noteset_update_interval) {
389 		self->noteset                = self->retuner->get_noteset ();
390 		self->noteset_update_counter = 0;
391 	}
392 
393 	/* report */
394 	*self->port[FAT_MASK] = notes;
395 	*self->port[FAT_NSET] = self->noteset;
396 	*self->port[FAT_ERRR] = self->retuner->get_error ();
397 	*self->port[FAT_BEND] = self->pitchbend;
398 }
399 
400 static void
401 cleanup (LV2_Handle instance)
402 {
403 	Fat1* self = (Fat1*)instance;
404 	pthread_mutex_lock (&fftw_planner_lock);
405 	delete self->retuner;
406 	if (instance_count > 0) {
407 		--instance_count;
408 	}
409 #ifdef WITH_STATIC_FFTW_CLEANUP
410 	/* use this only when statically linking to a local fftw!
411 	 *
412 	 * "After calling fftw_cleanup, all existing plans become undefined,
413 	 *  and you should not attempt to execute them nor to destroy them."
414 	 * [http://www.fftw.org/fftw3_doc/Using-Plans.html]
415 	 *
416 	 * If libfftwf is shared with other plugins or the host this can
417 	 * cause undefined behavior.
418 	 */
419 	if (instance_count == 0) {
420 		fftwf_cleanup ();
421 	}
422 #endif
423 	pthread_mutex_unlock (&fftw_planner_lock);
424 	free (instance);
425 }
426 
427 static void
428 activate (LV2_Handle instance)
429 {
430 	Fat1* self = (Fat1*)instance;
431 	clear_midimask (self);
432 }
433 
434 const void*
435 extension_data (const char* uri)
436 {
437 	return NULL;
438 }
439 
440 static const LV2_Descriptor descriptor = {
441 	FAT1_URI,
442 	instantiate,
443 	connect_port,
444 	activate,
445 	run,
446 	NULL,
447 	cleanup,
448 	extension_data
449 };
450 
451 static const LV2_Descriptor descriptor_microtonal = {
452 	FAT1_URI "#microtonal",
453 	instantiate,
454 	connect_port,
455 	activate,
456 	run,
457 	NULL,
458 	cleanup,
459 	extension_data
460 };
461 
462 static const LV2_Descriptor descriptor_scales = {
463 	FAT1_URI "#scales",
464 	instantiate,
465 	connect_port_scales,
466 	activate,
467 	run,
468 	NULL,
469 	cleanup,
470 	extension_data
471 };
472 
473 #undef LV2_SYMBOL_EXPORT
474 #ifdef _WIN32
475 #  define LV2_SYMBOL_EXPORT __declspec(dllexport)
476 #else
477 #  define LV2_SYMBOL_EXPORT __attribute__ ((visibility ("default")))
478 #endif
479 LV2_SYMBOL_EXPORT
480 const LV2_Descriptor*
481 lv2_descriptor (uint32_t index)
482 {
483 	switch (index) {
484 		case 0:
485 			return &descriptor;
486 		case 1:
487 			return &descriptor_microtonal;
488 		case 2:
489 			return &descriptor_scales;
490 		default:
491 			return NULL;
492 	}
493 }
494