1 /* B.Harvestr
2  * LV2 Plugin
3  *
4  * Copyright (C) 2018 by Sven Jähnichen
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3, or (at your option)
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20 
21 #include "BHarvestr.hpp"
22 #include <ctime>
23 #include <stdexcept>
24 #include "BUtilities/stof.hpp"
25 #include "lv2/core/lv2_util.h"
26 
27 #define LCG_RAND_MAX 0x7fff
28 static unsigned int g_seed;
lcg_srand(int seed)29 inline void lcg_srand (int seed) {g_seed = seed;}
lcg_rand()30 inline int lcg_rand ()
31 {
32     g_seed = (1103515245 * g_seed + 12345);
33     return (g_seed >> 16) & LCG_RAND_MAX;
34 }
35 
framesToSeconds(const uint64_t frame,const double rate)36 inline double framesToSeconds (const uint64_t frame, const double rate) {return (double (frame)) / rate;}
framesToMilliseconds(const uint64_t frame,const double rate)37 inline double framesToMilliseconds (const uint64_t frame, const double rate) {return 1000.0 * (double (frame)) / rate;}
secondsToFrames(const double s,const double rate)38 inline uint64_t secondsToFrames (const double s, const double rate) {return rate * s;}
millisecondsToFrames(const double ms,const double rate)39 inline uint64_t millisecondsToFrames (const double ms, const double rate) {return rate * ms / 1000.0;}
noteToFrequency(const double note)40 inline double noteToFrequency (const double note) {return pow (2.0, (note - 69.0) / 12.0) * 440.0;}
modulatef(const float min,const float max,const float mod)41 inline float modulatef (const float min, const float max, const float mod) {return (min == max ? min : min + mod * (max - min));}
fracf(const float value)42 inline float fracf (const float value) {return value - floor (value);}
43 
BHarvestr(double samplerate,const LV2_Feature * const * features)44 BHarvestr::BHarvestr (double samplerate, const LV2_Feature* const* features) :
45 	map (NULL), unmap (NULL), workerSchedule (NULL),
46 	controlPort (nullptr), notifyPort (nullptr),
47 	audioOutput1 (nullptr), audioOutput2 (nullptr),
48 	notifyForge (), notifyFrame (),
49 	new_controllers {nullptr}, controllers {0},
50 	pattern (), sample (nullptr), voices (),
51 	lfo {Lfo()},
52 	seq {Sequencer<NR_SEQ_STEPS>()},
53 	shape {Shape<MAXNODES>()},
54 	presetInfo {"", "", 0, "", "", "", ""},
55 	rate (samplerate),
56 	frame (0),
57 	sampleFrame (0xFFFFFFFFFFFFFFFF), sampleSelectionFrame (0xFFFFFFFFFFFFFFFF),
58 	ui_on (false),
59         activated (false),
60 	notify {false, false, false, false, false, false, {false}, false, false},
61 	message ("")
62 
63 {
64 	//Scan host features for URID map
65 	LV2_URID_Map* m = NULL;
66 	LV2_URID_Unmap* u = NULL;
67 	for (int i = 0; features[i]; ++i)
68 	{
69 		if (strcmp (features[i]->URI, LV2_URID__map) == 0)
70 		{
71 			m = (LV2_URID_Map*) features[i]->data;
72 		}
73 
74 		else if (strcmp (features[i]->URI, LV2_URID__unmap) == 0)
75 		{
76 			u = (LV2_URID_Unmap*) features[i]->data;
77 		}
78 
79 		else if (!strcmp(features[i]->URI, LV2_WORKER__schedule))
80 		{
81                         workerSchedule = (LV2_Worker_Schedule*)features[i]->data;
82 		}
83 	}
84 
85 	if (!m) throw std::invalid_argument ("BHarvestr.lv2: Host does not support urid:map.");
86 	if (!workerSchedule) throw std::invalid_argument ("BHarvestr.lv2: Host does not support work:schedule.");
87 
88 	//Map URIS
89 	map = m;
90 	unmap = u;
91 	getURIs (m, &uris);
92 
93 	// Initialize notify
94 	lv2_atom_forge_init (&notifyForge, map);
95 
96 	// Init presetInfo
97 	memset (&presetInfo, 0, sizeof (presetInfo));
98 
99 	// Init shapes
100 	for (int i = 0; i < USER_SHAPES + NR_USER_SHAPES; ++i) shape[i].setDefaultShape ();
101 	shape[SINE_SHAPE].insertNode ({CORNER_NODE, {0.001, 0.0}, {0.0, 0.0}, {0.1821, 0.0}});
102 	shape[SINE_SHAPE].insertNode ({CORNER_NODE, {0.5, 1.0}, {-0.1821, 0.0}, {0.1821, 0.0}});
103 	shape[SINE_SHAPE].insertNode ({CORNER_NODE, {0.999, 0.0}, {-0.1821, 0.0}, {0.0, 0.0}});
104 	shape[HALF_SINE_SHAPE].insertNode ({CORNER_NODE, {0.001, 0.0}, {0.0, 0.0}, {0.1821, 0.5}});
105 	shape[HALF_SINE_SHAPE].insertNode ({CORNER_NODE, {0.5, 1.0}, {-0.1821, 0.0}, {0.1821, 0.0}});
106 	shape[HALF_SINE_SHAPE].insertNode ({CORNER_NODE, {0.999, 0.0}, {-0.1821, 0.5}, {0.0, 0.0}});
107 	shape[TRIANGLE_SHAPE].insertNode ({POINT_NODE, {0.5, 1.0}, {0.0, 0.0}, {0.0, 0.0}});
108 	shape[TRAPEZ_SHAPE].insertNode ({POINT_NODE, {0.25, 1.0}, {0.0, 0.0}, {0.0, 0.0}});
109 	shape[TRAPEZ_SHAPE].insertNode ({POINT_NODE, {0.75, 1.0}, {0.0, 0.0}, {0.0, 0.0}});
110 
111 	// Init random engine
112 	lcg_srand (time (0));
113 
114 	ui_on = false;
115 }
116 
connect_port(uint32_t port,void * data)117 void BHarvestr::connect_port (uint32_t port, void *data)
118 {
119 	switch (port)
120 	{
121 		case CONTROL:
122 			controlPort = (LV2_Atom_Sequence*) data;
123 			break;
124 		case NOTIFY:
125 			notifyPort = (LV2_Atom_Sequence*) data;
126 			break;
127 		case AUDIO_OUT_1:
128 			audioOutput1 = (float*) data;
129 			break;
130 		case AUDIO_OUT_2:
131 			audioOutput2 = (float*) data;
132 			break;
133 		default:
134 			// Connect controllers
135 			if ((port >= CONTROLLERS) && (port < CONTROLLERS + MAXCONTROLLERS)) new_controllers[port - CONTROLLERS] = (float*) data;
136 	}
137 }
138 
activate()139 void BHarvestr::activate() {activated = true;}
140 
deactivate()141 void BHarvestr::deactivate() {activated = false;}
142 
run(uint32_t n_samples)143 void BHarvestr::run (uint32_t n_samples)
144 {
145 	uint32_t last_t = 0;
146 
147 	if ((!controlPort) || (!notifyPort) || (!audioOutput1) || (!audioOutput2)) return;
148 
149 	// Init notify port
150 	uint32_t space = notifyPort->atom.size;
151 	lv2_atom_forge_set_buffer(&notifyForge, (uint8_t*) notifyPort, space);
152 	lv2_atom_forge_sequence_head(&notifyForge, &notifyFrame, 0);
153 
154 	// Validate controllers
155 	for (int i = 0; i < MAXCONTROLLERS; ++i)
156 	{
157 		if (new_controllers[i])
158 		{
159 			float val = controllerLimits[i].validate (*(new_controllers[i]));
160 			if (val != *(new_controllers[i]))
161 			{
162 				fprintf (stderr, "BHarvestr.lv2: Value out of range in run (): Controller#%i\n", i);
163 				*(new_controllers[i]) = val;
164 				// TODO update GUI controller
165 			}
166 
167 			if (controllers[i] != val)
168 			{
169 				controllers[i] = val;
170 
171 				if (i == SAMPLE_START)
172 				{
173 					if (controllers[SAMPLE_END] < val) controllers[SAMPLE_END] = val;
174 					notify.selectionDisplay = true;
175 				}
176 
177 				else if (i == SAMPLE_END)
178 				{
179 					if (controllers[SAMPLE_START] > val) controllers[SAMPLE_START] = val;
180 					notify.selectionDisplay = true;
181 				}
182 
183 				else if (i == PATTERN_TYPE) pattern.setPattern (PatternIndex (int (val)));
184 
185 				else if (i == PATTERN_SIZE) pattern.setSteps (pattern.getRows() * val);
186 
187 				else if ((i >= LFOS) && (i < LFOS + LFO_SIZE * NR_LFOS))
188 				{
189 					int nr = (i - LFOS) / LFO_SIZE;
190 					int param = (i - LFOS) % LFO_SIZE;
191 
192 					switch (param)
193 					{
194 						case LFO_TYPE:	lfo[nr].setType (LfoIndex (int (val)));
195 								break;
196 
197 						case LFO_FREQ:	lfo[nr].setFrequency (val, framesToSeconds (frame, rate));
198 								break;
199 
200 						case LFO_PHASE:	lfo[nr].setPhase (val);
201 								break;
202 
203 						default:	break;
204 					}
205 				}
206 
207 				else if ((i >= SEQS) && (i < SEQS + SEQ_SIZE * NR_SEQS))
208 				{
209 					int nr = (i - SEQS) / SEQ_SIZE;
210 					int param = (i - SEQS) % SEQ_SIZE;
211 
212 					switch (param)
213 					{
214 						case SEQ_CHS:	seq[nr].setSize (val);
215 								break;
216 
217 						case SEQ_FREQ:	seq[nr].setFrequency (val, framesToSeconds (frame, rate));
218 								break;
219 
220 						case SEQ_PHASE:	seq[nr].setPhase (val);
221 								break;
222 
223 						default:	seq[nr].setStep (param - SEQ_STEPS, val);
224 					}
225 				}
226 
227 				// Recalculate pattern.rows_
228 				if
229 				(
230 					(i == SAMPLE_START) ||
231 					(i == SAMPLE_END) ||
232 					(i == PROPERTIES + GRAIN_SIZE * PROPERTIES_SIZE + PROPERTY_VALUE_START) ||
233 					(i == PROPERTIES + GRAIN_SIZE * PROPERTIES_SIZE + PROPERTY_VALUE_END)
234 				)
235 				{
236 					if (!sample) pattern.setRows (1);
237 					else
238 					{
239 						float grainSize =
240 						(
241 							controllers[PROPERTIES + GRAIN_SIZE * PROPERTIES_SIZE + PROPERTY_VALUE_START] +
242 							controllers[PROPERTIES + GRAIN_SIZE * PROPERTIES_SIZE + PROPERTY_VALUE_END]
243 						) / 2.0f;
244 
245 						if (grainSize != 0.0f)
246 						{
247 							float selectionSize = (controllers[SAMPLE_END] - controllers[SAMPLE_START]) *
248 									      framesToSeconds(sample->info.frames, rate) * 1000.0f;
249 							int grainsPerSelection = ceil (selectionSize / grainSize);
250 							pattern.setRows (grainsPerSelection);
251 						}
252 						else pattern.setRows (1);
253 					}
254 				}
255 			}
256 		}
257 	}
258 
259 	// Read CONTROL port (notifications from GUI and host)
260 	LV2_ATOM_SEQUENCE_FOREACH (controlPort, ev)
261 	{
262 		if ((ev->body.type == uris.atom_Object) || (ev->body.type == uris.atom_Blank))
263 		{
264 			const LV2_Atom_Object* obj = (const LV2_Atom_Object*)&ev->body;
265 
266 			// GUI on
267 			if (obj->body.otype == uris.bharvestr_uiOn)
268 			{
269 				ui_on = true;
270 				notify.pattern = true;
271 				notify.sampleDisplay = true;
272 				notify.selectionDisplay = true;
273 				notify.samplePath = true;
274 				for (int i = 0; i < USER_SHAPES + NR_USER_SHAPES; ++i) notify.shape[i] = true;
275 				notify.presetInfo = true;
276 			}
277 
278 			// GUI off
279 			else if (obj->body.otype == uris.bharvestr_uiOff) ui_on = false;
280 
281 			// Sample/Selection playback started/stopped
282 			else if (obj->body.otype == uris.bharvestr_samplePlay) sampleFrame = 0;
283 			else if (obj->body.otype == uris.bharvestr_sampleStop) sampleFrame = 0xFFFFFFFFFFFFFFFF;
284 			else if (obj->body.otype == uris.bharvestr_selectionPlay) sampleSelectionFrame = 0;
285 			else if (obj->body.otype == uris.bharvestr_selectionStop) sampleSelectionFrame = 0xFFFFFFFFFFFFFFFF;
286 
287 			// Pattern changed notifications
288 			else if (obj->body.otype == uris.bharvestr_patternEvent)
289 			{
290 				LV2_Atom *oPr = NULL, *oPs = NULL, *oPat = NULL;
291 				lv2_atom_object_get
292 				(
293 					obj,
294 					uris.bharvestr_patternRows, &oPr,
295 					uris.bharvestr_patternSteps, &oPs,
296 					uris.bharvestr_pattern, &oPat,
297 					NULL
298 				);
299 
300 				if (oPr && (oPr->type == uris.atom_Int))
301 				{
302 					const int rows = ((const LV2_Atom_Int*)oPr)->body;
303 					pattern.setRows (rows);
304 				}
305 
306 				// Pattern notification
307 				if (oPat && (oPat->type == uris.atom_Vector))
308 				{
309 					const LV2_Atom_Vector* vec = (const LV2_Atom_Vector*) oPat;
310 					if (vec->body.child_type == uris.atom_Int)
311 					{
312 						const uint32_t size = (uint32_t) ((oPat->size - sizeof(LV2_Atom_Vector_Body)) / sizeof (int));
313 						int* new_pattern = (int*) (&vec->body + 1);
314 						pattern.setValues (new_pattern, size);
315 						controllers[PATTERN_TYPE] = USER_PATTERN;
316 						notify.pattern = true;
317 					}
318 				}
319 
320 				if (oPs && (oPs->type == uris.atom_Int))
321 				{
322 					const int steps = ((const LV2_Atom_Int*)oPs)->body;
323 					pattern.setSteps (steps);
324 				}
325 			}
326 
327 			// Sample path notification -> forward to worker
328 			else if (obj->body.otype == uris.bharvestr_sampleEvent)
329 			{
330 				LV2_Atom* oPath = NULL;
331 				lv2_atom_object_get (obj, uris.bharvestr_samplePath, &oPath, NULL);
332 
333 				if (oPath && (oPath->type == uris.atom_Path))
334 				{
335 					workerSchedule->schedule_work (workerSchedule->handle, lv2_atom_total_size(&ev->body), &ev->body);
336 				}
337 			}
338 
339 			// Shape changed notifications
340 			else if (obj->body.otype == uris.bharvestr_shapeEvent)
341 			{
342 				LV2_Atom *oId = NULL, *oData = NULL;
343 				lv2_atom_object_get (obj,
344 						     uris.bharvestr_shapeIndex, &oId,
345 						     uris.bharvestr_shapeData, &oData,
346 						     NULL);
347 
348 				if (oId && (oId->type == uris.atom_Int) && oData && (oData->type == uris.atom_Vector))
349 				{
350 					const int index = ((const LV2_Atom_Int*)oId)->body;
351 					if ((index >= USER_SHAPES) && (index < USER_SHAPES + NR_USER_SHAPES))
352 					{
353 						const LV2_Atom_Vector* vec = (const LV2_Atom_Vector*) oData;
354 						if (vec->body.child_type == uris.atom_Float)
355 						{
356 							shape[index].clearShape ();
357 							const uint32_t vecSize = (uint32_t) ((oData->size - sizeof(LV2_Atom_Vector_Body)) / (7 * sizeof (float)));
358 							float* data = (float*) (&vec->body + 1);
359 							for (unsigned int i = 0; (i < vecSize) && (i < MAXNODES); ++i)
360 							{
361 								Node node;
362 								node.nodeType = NodeType (int (data[i * 7]));
363 								node.point.x = data[i * 7 + 1];
364 								node.point.y = data[i * 7 + 2];
365 								node.handle1.x = data[i * 7 + 3];
366 								node.handle1.y = data[i * 7 + 4];
367 								node.handle2.x = data[i * 7 + 5];
368 								node.handle2.y = data[i * 7 + 6];
369 								shape[index].appendRawNode (node);
370 							}
371 							shape[index].validateShape();
372 						}
373 					}
374 				}
375 			}
376 
377 			// Preset info notification
378 			else if (obj->body.otype ==uris.bharvestr_presetInfoEvent)
379 			{
380 				const LV2_Atom *oName = NULL, *oType = NULL, *oDate = NULL, *oCreator = NULL, *oUri = NULL, *oLicense = NULL, *oDescription = NULL ;
381 				lv2_atom_object_get
382 				(
383 					obj,
384 					uris.bharvestr_presetInfoName, &oName,
385 					uris.bharvestr_presetInfoType, &oType,
386 					uris.bharvestr_presetInfoDate, &oDate,
387 					uris.bharvestr_presetInfoCreator, &oCreator,
388 					uris.bharvestr_presetInfoURI, &oUri,
389 					uris.bharvestr_presetInfoLicense, &oLicense,
390 					uris.bharvestr_presetInfoDescription, &oDescription,
391 					NULL
392 				);
393 
394 				if (oName && (oName->type == uris.atom_String)) strncpy (presetInfo.name, (const char*)LV2_ATOM_BODY_CONST (oName), PRESETINFO_MAX_TXT_SIZE - 1);
395 				if (oType && (oType->type == uris.atom_String)) strncpy (presetInfo.type, (const char*)LV2_ATOM_BODY_CONST (oType), PRESETINFO_MAX_TXT_SIZE - 1);
396 				if (oDate && (oDate->type == uris.atom_Int)) presetInfo.date = ((const LV2_Atom_Int*)oDate)->body;
397 				if (oCreator && (oCreator->type == uris.atom_String)) strncpy (presetInfo.creator, (const char*)LV2_ATOM_BODY_CONST (oCreator), PRESETINFO_MAX_TXT_SIZE - 1);
398 				if (oUri && (oUri->type == uris.atom_String)) strncpy (presetInfo.uri, (const char*)LV2_ATOM_BODY_CONST (oUri), PRESETINFO_MAX_TXT_SIZE - 1);
399 				if (oLicense && (oLicense->type == uris.atom_String)) strncpy (presetInfo.license, (const char*)LV2_ATOM_BODY_CONST (oLicense), PRESETINFO_MAX_TXT_SIZE - 1);
400 				if (oDescription && (oDescription->type == uris.atom_String)) strncpy (presetInfo.description, (const char*)LV2_ATOM_BODY_CONST (oDescription), PRESETINFO_MAX_TXT_SIZE - 1);
401 			}
402 
403 			// Keyboard
404 			else if (obj->body.otype ==uris.bharvestr_keyboardEvent)
405 			{
406 				LV2_Atom *okOn = NULL, *okOff = NULL;
407 				lv2_atom_object_get (obj,
408 						     uris.bharvestr_keyOn, &okOn,
409 						     uris.bharvestr_keyOff, &okOff,
410 						     NULL);
411 
412 				if (okOn && (okOn->type == uris.atom_Int))
413 				{
414 					const int note = ((const LV2_Atom_Int*)okOn)->body;
415 					noteOn (note, 64, frame + ev->time.frames);
416 				}
417 
418 				if (okOff && (okOff->type == uris.atom_Int))
419 				{
420 					const int note = ((const LV2_Atom_Int*)okOff)->body;
421 					noteOff (note, frame + ev->time.frames);
422 				}
423 			}
424 		}
425 
426 		// Read incoming MIDI_IN events
427 		else if (ev->body.type == uris.midi_Event)
428 		{
429 			const uint8_t* const msg = (const uint8_t*)(ev + 1);
430 			const uint8_t typ = lv2_midi_message_type(msg);
431 			//uint8_t chn = msg[0] & 0x0F;
432 
433 			switch (typ)
434 			{
435 
436 				case LV2_MIDI_MSG_NOTE_ON:
437 				{
438 					const uint8_t note = msg[1];
439 					const uint8_t velocity = msg[2];
440 					if (velocity != 0)
441 					{
442 						noteOn (note, velocity, frame + ev->time.frames);
443 						break;
444 					}
445 					// Otherwise continue with note off
446 				}
447 				// No break here!
448 
449 				case LV2_MIDI_MSG_NOTE_OFF:
450 				{
451 					const uint8_t note = msg[1];
452 					noteOff (note, frame + ev->time.frames);
453 				}
454 				break;
455 
456 				case LV2_MIDI_MSG_CONTROLLER:
457 				{
458 					const uint8_t cc = msg[1];
459 
460 					switch (cc)
461 					{
462 
463 						// LV2_MIDI_CTL_SUSTAIN: Forward to all outputs
464 						case LV2_MIDI_CTL_SUSTAIN:
465 						break;
466 
467 						// LV2_MIDI_CTL_ALL_SOUNDS_OFF: Stop all outputs
468 						case LV2_MIDI_CTL_ALL_SOUNDS_OFF:
469 						allSoundsOff (frame + ev->time.frames);
470 						break;
471 
472 						// LV2_MIDI_CTL_ALL_NOTES_OFF: Stop all voices
473 						case LV2_MIDI_CTL_ALL_NOTES_OFF:
474 						allNotesOff (frame + ev->time.frames);
475 						break;
476 
477 						// All other MIDI signals
478 						default: break;
479 					}
480 				}
481 
482 				default: break;
483 			}
484 		}
485 
486 		else fprintf (stderr, "BHarvestr.lv2: Ignored event in Control port (otype = %i, %s)\n", ev->body.type,
487 					  (unmap ? unmap->unmap (unmap->handle, ev->body.type) : NULL));
488 
489 		// Update for this iteration
490 		uint32_t next_t = (ev->time.frames < n_samples ? ev->time.frames : n_samples);
491 		play (last_t, next_t);
492 		last_t = next_t;
493 	}
494 
495 	// Update for the remainder of the cycle
496 	if (last_t < n_samples) play (last_t, n_samples);
497 
498 	// Update position in case of no new barBeat submitted on next call
499 	frame += n_samples;
500 
501 	if (ui_on)
502 	{
503 		notifyStatusToGui ();
504 		if (notify.sampleStop) notifySampleStopToGui();
505 		if (notify.selectionStop) notifySelectionStopToGui();
506 		if (notify.pattern) notifyPatternToGui();
507 		if (notify.sampleDisplay || notify.selectionDisplay) notifyDisplayToGui();
508 		if (notify.samplePath) notifySamplePathToGui();
509 		for (int i = 0; i < USER_SHAPES + NR_USER_SHAPES; ++i)
510 		{
511 			if (notify.shape[i]) notifyShapeToGui (ShapeIndex (i));
512 		}
513 		if (notify.presetInfo) notifyPresetInfoToGui();
514 		if (notify.message) notifyMessageToGui();
515 	}
516 	lv2_atom_forge_pop(&notifyForge, &notifyFrame);
517 }
518 
state_save(LV2_State_Store_Function store,LV2_State_Handle handle,uint32_t flags,const LV2_Feature * const * features)519 LV2_State_Status BHarvestr::state_save (LV2_State_Store_Function store, LV2_State_Handle handle, uint32_t flags,
520 			const LV2_Feature* const* features)
521 {
522 	LV2_State_Map_Path* map_path = NULL;
523 	for (int i = 0; features[i]; ++i)
524 	{
525 		if (!strcmp(features[i]->URI, LV2_STATE__mapPath))
526 		{
527 			map_path = (LV2_State_Map_Path*)features[i]->data;
528 			break;
529 		}
530 	}
531 
532 	if (!map_path)
533 	{
534 		fprintf (stderr, "BHarvestr.lv2: Feature map_path not available! Can't save plugin status!\n" );
535 		return LV2_STATE_ERR_NO_FEATURE;
536 	}
537 
538 	// Save sample path
539 	if (sample && sample->path)
540 	{
541 		char* abstrPath = map_path->abstract_path(map_path->handle, sample->path);
542 		store(handle, uris.bharvestr_samplePath, abstrPath, strlen (sample->path) + 1, uris.atom_Path, LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
543 		free (abstrPath);
544 	}
545 
546 	// Save preset data
547 	if (presetInfo.name[0] != '\0') store (handle, uris.bharvestr_presetInfoName, presetInfo.name, strlen (presetInfo.name) + 1, uris.atom_String, LV2_STATE_IS_POD);
548 	if (presetInfo.type[0] != '\0') store (handle, uris.bharvestr_presetInfoType, presetInfo.type, strlen (presetInfo.type) + 1, uris.atom_String, LV2_STATE_IS_POD);
549 	if (presetInfo.date != 0) store (handle, uris.bharvestr_presetInfoDate, &presetInfo.date, sizeof(presetInfo.date), uris.atom_Int, LV2_STATE_IS_POD);
550 	if (presetInfo.creator[0] != '\0') store (handle, uris.bharvestr_presetInfoCreator, presetInfo.creator, strlen (presetInfo.creator) + 1, uris.atom_String, LV2_STATE_IS_POD);
551 	if (presetInfo.uri[0] != '\0') store (handle, uris.bharvestr_presetInfoURI,  presetInfo.uri, strlen (presetInfo.uri) + 1, uris.atom_String, LV2_STATE_IS_POD | LV2_STATE_IS_POD);
552 	if (presetInfo.license[0] != '\0') store (handle, uris.bharvestr_presetInfoLicense, presetInfo.license, strlen (presetInfo.license) + 1, uris.atom_String, LV2_STATE_IS_POD);
553 	if (presetInfo.description[0] != '\0') store (handle, uris.bharvestr_presetInfoDescription, presetInfo.description, strlen (presetInfo.description) + 1, uris.atom_String, LV2_STATE_IS_POD);
554 
555 
556 	// Store pattern
557 	if (controllers[PATTERN_TYPE] == USER_PATTERN)
558 	{
559 		char patternDataString[0x4010] = "\nPattern data:\n";
560 		const int patternSteps = pattern.getSteps();
561 		const int patternRows = pattern.getRows();
562 
563 		for (int s = 0; s < MAXPATTERNSTEPS; ++s)
564 		{
565 			char valueString[16];
566 			int val = pattern.getValue (s);
567 			snprintf (valueString, 14, "val:%d;", val);
568 			if (s % 8 == 7) strcat (valueString, "\n");
569 			else strcat (valueString, " ");
570 			strcat (patternDataString, valueString);
571 		}
572 		store (handle, uris.bharvestr_patternRows, &patternRows, sizeof(patternRows), uris.atom_Int, LV2_STATE_IS_POD);
573 		store (handle, uris.bharvestr_patternSteps, &patternSteps, sizeof(patternSteps), uris.atom_Int, LV2_STATE_IS_POD);
574 		store (handle, uris.bharvestr_pattern, patternDataString, strlen (patternDataString) + 1, uris.atom_String, LV2_STATE_IS_POD);
575 	}
576 
577 	// Store shapes
578 	{
579 		char shapesDataString[0x8010] = "Shape data:\n";
580 
581 		for (int sh = USER_SHAPES; sh < USER_SHAPES + NR_USER_SHAPES; ++sh)
582 		{
583 			for (unsigned int nd = 0; nd < shape[sh].size (); ++nd)
584 			{
585 				char valueString[160];
586 				Node node = shape[sh].getNode (nd);
587 				snprintf
588 				(
589 					valueString,
590 					126,
591 					"shp:%d; typ:%d; ptx:%f; pty:%f; h1x:%f; h1y:%f; h2x:%f; h2y:%f",
592 					sh,
593 					int (node.nodeType),
594 					node.point.x,
595 					node.point.y,
596 					node.handle1.x,
597 					node.handle1.y,
598 					node.handle2.x,
599 					node.handle2.y
600 				);
601 				if ((sh < USER_SHAPES + NR_USER_SHAPES - 1) || (nd < shape[sh].size ())) strcat (valueString, ";\n");
602 				else strcat(valueString, "\n");
603 				strcat (shapesDataString, valueString);
604 			}
605 		}
606 		store (handle, uris.bharvestr_shapeData, shapesDataString, strlen (shapesDataString) + 1, uris.atom_String, LV2_STATE_IS_POD);
607 	}
608 
609 	return LV2_STATE_SUCCESS;
610 }
611 
state_restore(LV2_State_Retrieve_Function retrieve,LV2_State_Handle handle,uint32_t flags,const LV2_Feature * const * features)612 LV2_State_Status BHarvestr::state_restore (LV2_State_Retrieve_Function retrieve, LV2_State_Handle handle, uint32_t flags,
613 			const LV2_Feature* const* features)
614 {
615         // Get host features
616 	LV2_Worker_Schedule* schedule = nullptr;
617 	LV2_State_Map_Path* mapPath = nullptr;
618 	const char* missing  = lv2_features_query
619 	(
620 		features,
621 		LV2_STATE__mapPath, &mapPath, true,
622 		LV2_WORKER__schedule, &schedule, false,
623 		nullptr
624 	);
625 
626 	if (missing)
627 	{
628 		fprintf (stderr, "BJumblr.lv2: Host doesn't support required features.\n");
629 		return LV2_STATE_ERR_NO_FEATURE;
630 	}
631 
632 	size_t   size;
633 	uint32_t type;
634 	uint32_t valflags;
635 
636         // Retireve sample data
637 	{
638 		char samplePath[PATH_MAX] = {0};
639 
640 		const void* pathData = retrieve (handle, uris.bharvestr_samplePath, &size, &type, &valflags);
641 		if (pathData)
642 		{
643 			const char* absPath  = mapPath->absolute_path (mapPath->handle, (char*)pathData);
644 		        if (absPath)
645 			{
646 				if (strlen (absPath) < PATH_MAX) strcpy (samplePath, absPath);
647 				else fprintf (stderr, "BHarvestr.lv2: Sample path too long.\n");
648 		        }
649 		}
650 
651 		if (activated && schedule)
652 		{
653 			LV2_Atom_Forge forge;
654 			lv2_atom_forge_init(&forge, map);
655 			uint8_t buf[1200];
656 			lv2_atom_forge_set_buffer(&forge, buf, sizeof(buf));
657 			LV2_Atom_Forge_Frame frame;
658 			LV2_Atom* msg = (LV2_Atom*)forgeSamplePath (&forge, &frame, samplePath);
659 			lv2_atom_forge_pop(&forge, &frame);
660 			if (msg) schedule->schedule_work(schedule->handle, lv2_atom_total_size(msg), msg);
661 		}
662 
663 		else
664 		{
665                         Sample* s = loadSample (samplePath);
666         		if (s)
667         		{
668         			if (sample) delete sample;
669         			installSample (s);
670         		}
671 		}
672 	}
673 
674 	// Retrieve preset data
675 	const void* presetNameData = retrieve (handle, uris.bharvestr_presetInfoName, &size, &type, &valflags);
676         if (presetNameData)
677 	{
678 		const char* str = (const char*)presetNameData;
679 		strncpy (presetInfo.name, str, LIMIT (strlen (str) + 1, 0, PRESETINFO_MAX_TXT_SIZE - 1));
680 		notify.presetInfo = true;
681         }
682 
683 	const void* presetTypeData = retrieve (handle, uris.bharvestr_presetInfoType, &size, &type, &valflags);
684         if (presetTypeData)
685 	{
686 		const char* str = (const char*)presetTypeData;
687 		strncpy (presetInfo.type, str, LIMIT (strlen (str) + 1, 0, PRESETINFO_MAX_TXT_SIZE - 1));
688 		notify.presetInfo = true;
689         }
690 
691 	const void* presetDateData = retrieve (handle, uris.bharvestr_presetInfoDate, &size, &type, &valflags);
692         if (presetDateData)
693 	{
694 		presetInfo.date = *(int*)presetDateData;
695 		notify.presetInfo = true;
696         }
697 
698 	const void* presetCreatorData = retrieve (handle, uris.bharvestr_presetInfoCreator, &size, &type, &valflags);
699         if (presetNameData)
700 	{
701 		const char* str = (const char*)presetCreatorData;
702 		strncpy (presetInfo.creator, str, LIMIT (strlen (str) + 1, 0, PRESETINFO_MAX_TXT_SIZE - 1));
703 		notify.presetInfo = true;
704         }
705 
706 	const void* presetUriData = retrieve (handle, uris.bharvestr_presetInfoURI, &size, &type, &valflags);
707         if (presetUriData)
708 	{
709 		const char* str = (const char*)presetUriData;
710 		strncpy (presetInfo.uri, str, LIMIT (strlen (str) + 1, 0, PRESETINFO_MAX_TXT_SIZE - 1));
711 		notify.presetInfo = true;
712         }
713 
714 	const void* presetLicenseData = retrieve (handle, uris.bharvestr_presetInfoLicense, &size, &type, &valflags);
715         if (presetLicenseData)
716 	{
717 		const char* str = (const char*)presetLicenseData;
718 		strncpy (presetInfo.license, str, LIMIT (strlen (str) + 1, 0, PRESETINFO_MAX_TXT_SIZE - 1));
719 		notify.presetInfo = true;
720         }
721 
722 	const void* presetDescriptionData = retrieve (handle, uris.bharvestr_presetInfoDescription, &size, &type, &valflags);
723         if (presetDescriptionData)
724 	{
725 		const char* str = (const char*)presetDescriptionData;
726 		strncpy (presetInfo.description, str, LIMIT (strlen (str) + 1, 0, PRESETINFO_MAX_TXT_SIZE - 1));
727 		notify.presetInfo = true;
728         }
729 
730 	// Retrieve pattern data
731 	const void* patternRowsData = retrieve (handle, uris.bharvestr_patternRows, &size, &type, &valflags);
732         if (patternRowsData)
733 	{
734 		const int rows = *(int*)patternRowsData;
735 		pattern.setRows (rows);
736         }
737 
738 	const void* patternStepsData = retrieve (handle, uris.bharvestr_patternSteps, &size, &type, &valflags);
739         if (patternStepsData)
740 	{
741 		const int steps = *(int*)patternStepsData;
742 		pattern.setSteps (steps);
743         }
744 
745 	const void* patternData = retrieve (handle, uris.bharvestr_pattern, &size, &type, &valflags);
746         if (patternData)
747 	{
748 		std::string str = (char*)patternData;
749 
750 		// Parse retrieved data
751 		int step = 1;
752 		std::vector<int> data = {};
753 		while (!str.empty())
754 		{
755 			// Look for next "val:"
756 			size_t strPos = str.find ("val:");
757 			size_t nextPos = 0;
758 			if (strPos == std::string::npos) break;	// No "val:" found => end
759 			if (strPos + 4 > str.length()) break;	// Nothing more after "val:" => end
760 			str.erase (0, strPos + 4);
761 			if (step > MAXPATTERNSTEPS)
762 			{
763 				fprintf (stderr, "BHarvestr.lv2: Max. pattern size exceeded. Pattern data truncated at step %i.\n", step);
764 				break;
765 			}
766 			int val;
767 			try {val = BUtilities::stof (str, &nextPos);}
768 			catch  (const std::exception& e)
769 			{
770 				fprintf (stderr, "BHarvestr.lv2: Restore pattern incomplete. Can't parse step %i from \"%s...\"", step, str.substr (0, 63).c_str());
771 				break;
772 			}
773 
774 			if (nextPos > 0) str.erase (0, nextPos);
775 			if ((val < 0) || (val >= MAXPATTERNSTEPS))
776 			{
777 				fprintf (stderr, "BHarvestr.lv2: Restore pattern incomplete. Invalid matrix data loaded for step %i.\n", step);
778 				break;
779 			}
780 			data.push_back (val);
781 			++step;
782 		}
783 
784 		// Set pattern
785 		pattern.setPattern (USER_PATTERN);
786 		pattern.setValues (data);
787 		controllers[PATTERN_TYPE] = USER_PATTERN;
788 		notify.pattern = true;
789         }
790 
791 	// Retrieve shapes
792 	const void* shapesData = retrieve(handle, uris.bharvestr_shapeData, &size, &type, &valflags);
793 	if (shapesData && (type == uris.atom_String))
794 	{
795 		// Clear old shapes first
796 		for (int sh = USER_SHAPES; sh < USER_SHAPES + NR_USER_SHAPES; ++sh) shape[sh].clearShape();
797 
798 		// Parse retrieved data
799 		std::string shapesDataString = (char*) shapesData;
800 		const std::string keywords[8] = {"shp:", "typ:", "ptx:", "pty:", "h1x:", "h1y:", "h2x:", "h2y:"};
801 		while (!shapesDataString.empty())
802 		{
803 			// Look for next "shp:"
804 			size_t strPos = shapesDataString.find ("shp:");
805 			size_t nextPos = 0;
806 			if (strPos == std::string::npos) break;	// No "shp:" found => end
807 			if (strPos + 4 > shapesDataString.length()) break;	// Nothing more after id => end
808 			shapesDataString.erase (0, strPos + 4);
809 
810 			int sh;
811 			try {sh = BUtilities::stof (shapesDataString, &nextPos);}
812 			catch  (const std::exception& e)
813 			{
814 				fprintf (stderr, "BHarvestr.lv2: Restore shape state incomplete. Can't parse shape number from \"%s...\"", shapesDataString.substr (0, 63).c_str());
815 				break;
816 			}
817 
818 			if (nextPos > 0) shapesDataString.erase (0, nextPos);
819 			if ((sh < 0) || (sh >= USER_SHAPES + NR_USER_SHAPES))
820 			{
821 				fprintf (stderr, "BHarvestr.lv2: Restore shape state incomplete. Invalid matrix data block loaded for shape %i.\n", sh);
822 				break;
823 			}
824 
825 			// Look for shape data
826 			Node node = {NodeType::POINT_NODE, {0, 0}, {0, 0}, {0, 0}};
827 			bool isTypeDef = false;
828 			for (int i = 1; i < 9; ++i)
829 			{
830 				strPos = shapesDataString.find (keywords[i]);
831 				if (strPos == std::string::npos) continue;	// Keyword not found => next keyword
832 				if (strPos + 4 >= shapesDataString.length())	// Nothing more after keyword => end
833 				{
834 					shapesDataString ="";
835 					break;
836 				}
837 				if (strPos > 0) shapesDataString.erase (0, strPos + 4);
838 				float val;
839 				try {val = BUtilities::stof (shapesDataString, &nextPos);}
840 				catch  (const std::exception& e)
841 				{
842 					fprintf (stderr, "Harvestr.lv2: Restore shape state incomplete. Can't parse %s from \"%s...\"",
843 							 keywords[i].substr(0,3).c_str(), shapesDataString.substr (0, 63).c_str());
844 					break;
845 				}
846 
847 				if (nextPos > 0) shapesDataString.erase (0, nextPos);
848 				switch (i)
849 				{
850 					case 1: node.nodeType = (NodeType)((int)val);
851 						isTypeDef = true;
852 						break;
853 					case 2: node.point.x = val;
854 						break;
855 					case 3:	node.point.y = val;
856 						break;
857 					case 4:	node.handle1.x = val;
858 						break;
859 					case 5:	node.handle1.y = val;
860 						break;
861 					case 6:	node.handle2.x = val;
862 						break;
863 					case 7:	node.handle2.y = val;
864 						break;
865 					default:break;
866 				}
867 			}
868 
869 			// Set data
870 			if (isTypeDef) shape[sh].appendNode (node);
871 		}
872 
873 		// Validate all shapes
874 		for (int sh = USER_SHAPES; sh < USER_SHAPES + NR_USER_SHAPES; ++sh)
875 		{
876 			if (shape[sh].size () < 2) shape[sh].setDefaultShape ();
877 			else if (!shape[sh].validateShape ()) shape[sh].setDefaultShape ();
878 		}
879 
880 		// Force GUI notification
881 		for (int sh = USER_SHAPES; sh < USER_SHAPES + NR_USER_SHAPES; ++sh) notify.shape[sh] = true;
882 	}
883 
884 	return LV2_STATE_SUCCESS;
885 }
886 
work(LV2_Worker_Respond_Function respond,LV2_Worker_Respond_Handle handle,uint32_t size,const void * data)887 LV2_Worker_Status BHarvestr::work (LV2_Worker_Respond_Function respond, LV2_Worker_Respond_Handle handle, uint32_t size, const void* data)
888 {
889 	const LV2_Atom* atom = (const LV2_Atom*)data;
890 
891 	// Free old sample
892         if (atom->type == uris.bharvestr_sampleFreeEvent)
893 	{
894 		const LV2_Atom_Ptr* workerMessage = (LV2_Atom_Ptr*) atom;
895 		if (workerMessage && workerMessage->data) delete (Sample*)workerMessage->data;
896         }
897 
898 	// Load sample
899 	else
900 	{
901                 const LV2_Atom_Object* obj = (const LV2_Atom_Object*)data;
902 
903 
904 		// Sample path event
905 		if (obj->body.otype == uris.bharvestr_sampleEvent)
906 		{
907 			const LV2_Atom* path = NULL;
908 			lv2_atom_object_get(obj, uris.bharvestr_samplePath, &path, 0);
909 
910 			if (path && (path->type == uris.atom_Path))
911 			{
912 				Sample* s = loadSample ((const char*)LV2_ATOM_BODY_CONST(path));
913 
914 				if (s)
915 				{
916 					LV2_Atom_Ptr responseMessage = LV2_Atom_Ptr {{sizeof (Sample*), uris.bharvestr_sampleSetEvent}, s};
917 					respond (handle, sizeof(responseMessage), &responseMessage);
918 				}
919 			}
920 
921 			else return LV2_WORKER_ERR_UNKNOWN;
922 		}
923         }
924 
925         return LV2_WORKER_SUCCESS;
926 }
927 
work_response(uint32_t size,const void * data)928 LV2_Worker_Status BHarvestr::work_response (uint32_t size, const void* data)
929 {
930 	const LV2_Atom* atom = (const LV2_Atom*)data;
931 
932 	// Set sample
933 	if (atom->type == uris.bharvestr_sampleSetEvent)
934 	{
935 		// Schedule free old sample
936 		LV2_Atom_Ptr workerMessage = LV2_Atom_Ptr {{sizeof (Sample*), uris.bharvestr_sampleFreeEvent}, sample};
937 		workerSchedule->schedule_work (workerSchedule->handle, sizeof (workerMessage), &workerMessage);
938 
939 		// Install new sample from data
940 		const LV2_Atom_Ptr* atom_ptr = (const LV2_Atom_Ptr*) atom;
941 		installSample ((Sample*) atom_ptr->data);
942 	}
943 
944 	else fprintf(stderr, "B.Harvestr.lv2: Worker response unknown.\n");
945 	return LV2_WORKER_SUCCESS;
946 }
947 
loadSample(const char * path)948 Sample* BHarvestr::loadSample (const char* path)
949 {
950 	Sample* s = nullptr;
951 	try {s = new Sample (path);}
952 	catch (std::bad_alloc &ba)
953 	{
954 		fprintf (stderr, "BHarvestr.lv2: Can't allocate enough memory to open sample file.\n");
955 		strcpy (message, "BHarvestr.lv2: Can't allocate enough memory to open sample file.");
956 		notify.message = true;
957 	}
958 	catch (std::invalid_argument &ia)
959 	{
960 		fprintf (stderr, "%s\n", ia.what());
961 		strcpy (message, ia.what());
962 		notify.message = true;
963 	}
964 	return s;
965 }
966 
installSample(Sample * s)967 void BHarvestr::installSample (Sample* s)
968 {
969 	sample = s;
970 	sampleFrame = 0xFFFFFFFFFFFFFFFF;
971 	sampleSelectionFrame = 0xFFFFFFFFFFFFFFFF;
972 	notify.sampleDisplay = true;
973 	notify.selectionDisplay = true;
974 	notify.sampleStop = true;
975 	notify.selectionStop = true;
976 
977 	// Recalculate pattern.rows_
978 	if (sample)
979 		{
980 		float grainSize =
981 		(
982 			controllers[PROPERTIES + GRAIN_SIZE * PROPERTIES_SIZE + PROPERTY_VALUE_START] +
983 			controllers[PROPERTIES + GRAIN_SIZE * PROPERTIES_SIZE + PROPERTY_VALUE_END]
984 		) / 2.0f;
985 
986 		if (grainSize != 0.0f)
987 		{
988 			float selectionSize = (controllers[SAMPLE_END] - controllers[SAMPLE_START]) *
989 					      framesToSeconds(sample->info.frames, rate) * 1000.0f;
990 			int grainsPerSelection = ceil (selectionSize / grainSize);
991 			pattern.setRows (grainsPerSelection);
992 		}
993 		else pattern.setRows (1);
994 	}
995 	else pattern.setRows (1);
996 }
997 
noteOn(const uint8_t note,const uint8_t velocity,const uint64_t frame)998 void BHarvestr::noteOn (const uint8_t note, const uint8_t velocity, const uint64_t frame)
999 {
1000 	bool newNote = true;
1001 
1002 	// Scan if this is an additional midi message
1003 	// (e.g., double note on, velocity changed)
1004 	for (Voice** it = voices.begin(); it < voices.end(); ++it)
1005 	{
1006 		if (((**it).note == note) && (frame < (**it).endFrame))
1007 		{
1008 			(**it).velocity = velocity;
1009 			newNote = false;
1010 			break;
1011 		}
1012 	}
1013 
1014 	// New voice
1015 	if (newNote && (voices.size < controllers[MAX_VOICES]))
1016 	{
1017 		// Copy envelope data from controllers
1018 		Envelope env[NR_ENVS];
1019 		for (int i = 0; i < NR_ENVS; ++i)
1020 		{
1021 			env[i] = Envelope
1022 			(
1023 				controllers[ENVS + i * ENV_SIZE + ENV_ATTACK],
1024 				controllers[ENVS + i * ENV_SIZE + ENV_DECAY],
1025 				controllers[ENVS + i * ENV_SIZE + ENV_SUSTAIN],
1026 				controllers[ENVS + i * ENV_SIZE + ENV_RELEASE]
1027 			);
1028 		}
1029 
1030 		// Calculate release frames for each voice
1031 		uint64_t releaseFrames = secondsToFrames (4.0, rate);
1032 		for (int i = 0; i < NR_PROPERTY_MODULATORS; ++i)
1033 		{
1034 			int modNr = controllers[SYNTH + SYNTH_LEVEL * PROPERTIES_SIZE + PROPERTY_MODULATORS + i];
1035 			if (modNr == MODULATOR_NONE) break;
1036 			if ((modNr >= MODULATOR_ENV1) && (modNr <= MODULATOR_ENV4))
1037 			{
1038 				int envNr = modNr - MODULATOR_ENV1;
1039 				double iReleaseSeconds = env[envNr].getRelease();
1040 				uint64_t iReleaseFrames = secondsToFrames (iReleaseSeconds, rate);
1041 				if (iReleaseFrames < releaseFrames) releaseFrames = iReleaseFrames;
1042 			}
1043 		}
1044 
1045 		// Add new voice
1046 		Voice voice = Voice (note, velocity, frame, 0xFFFFFFFF00000000, releaseFrames, env);
1047 		voice.grains.push_back (Grain {frame, 0xFFFFFFFF00000000, 0ul, 0l, 0.0, 0.0, 0.0});
1048 		voices.push_back (voice);
1049 	}
1050 }
1051 
noteOff(const uint8_t note,const uint64_t frame)1052 void BHarvestr::noteOff (const uint8_t note, const uint64_t frame)
1053 {
1054 	for (Voice** it = voices.begin(); it < voices.end(); ++it)
1055 	{
1056 		if (((**it).note == note) && (frame < (**it).endFrame))
1057 		{
1058 			(**it).endFrame = frame;
1059 			const double pos = framesToSeconds (frame - (**it).startFrame, rate);
1060 			for (int i = 0; i < NR_ENVS; ++i) (**it).envelope[i].releaseAt (pos);
1061 		}
1062 	}
1063 }
1064 
allSoundsOff(const uint64_t frame)1065 void BHarvestr::allSoundsOff (const uint64_t frame)
1066 {
1067 	// TODO
1068 	voices.clear();
1069 }
1070 
allNotesOff(const uint64_t frame)1071 void BHarvestr::allNotesOff (const uint64_t frame)
1072 {
1073 	for (Voice** it = voices.begin(); it < voices.end(); ++it)
1074 	{
1075 		if (frame < (**it).endFrame)
1076 		{
1077 			(**it).endFrame = frame;
1078 			const double pos = framesToSeconds (frame - (**it).startFrame, rate);
1079 			for (int i = 0; i < NR_ENVS; ++i) (**it).envelope[i].releaseAt (pos);
1080 		}
1081 	}
1082 }
1083 
play(const int start,const int end)1084 void BHarvestr::play (const int start, const int end)
1085 {
1086 	if (end < start) return;
1087 	if ((!sample) || (!sample->data))
1088 	{
1089 		memset (&audioOutput1[start], 0, (end - start) * sizeof (float));
1090 		memset (&audioOutput2[start], 0, (end - start) * sizeof (float));
1091 		return;
1092 	}
1093 
1094 	for (int i = start; i < end; ++i)
1095 	{
1096 		uint64_t iframe = frame + i;
1097 		float isample1 = 0.0f;
1098 		float isample2 = 0.0f;
1099 
1100 		// Sample playback?
1101 		if (sampleFrame != 0xFFFFFFFFFFFFFFFF)
1102 		{
1103 			if (sampleFrame >= uint64_t (sample->info.frames))
1104 			{
1105 				sampleFrame = 0xFFFFFFFFFFFFFFFF;
1106 				notify.sampleStop = true;
1107 			}
1108 			else
1109 			{
1110 				isample1 += sample->data[sampleFrame * sample->info.channels];
1111 				isample2 += sample->data[sampleFrame * sample->info.channels];
1112 				++sampleFrame;
1113 			}
1114 		}
1115 
1116 		// Selection playback?
1117 		if (sampleSelectionFrame != 0xFFFFFFFFFFFFFFFF)
1118 		{
1119 			uint64_t start = controllers[SAMPLE_START] * sample->info.frames;
1120 			uint64_t size = (controllers[SAMPLE_END] - controllers[SAMPLE_START]) * sample->info.frames;
1121 			if ((sampleSelectionFrame >= size) || (start + sampleSelectionFrame >= uint64_t (sample->info.frames)))
1122 			{
1123 				sampleSelectionFrame = 0xFFFFFFFFFFFFFFFF;
1124 				notify.selectionStop = true;
1125 			}
1126 			else
1127 			{
1128 				isample1 += sample->data[(start + sampleSelectionFrame) * sample->info.channels];
1129 				isample2 += sample->data[(start + sampleSelectionFrame) * sample->info.channels];
1130 				++sampleSelectionFrame;
1131 			}
1132 		}
1133 
1134 		for (size_t v = 0; v < voices.size; ++v)
1135 		{
1136 			Voice& voice = voices[v];
1137 
1138 			// Play only active voices
1139 			if ((iframe >= voice.startFrame) && (iframe <= voice.endFrame + voice.releaseFrames))
1140 			{
1141 
1142 				float vsample1 = 0.0f;
1143 				float vsample2 = 0.0f;
1144 
1145 				// Remove outtimed grains
1146 				bool done;
1147 				do
1148 				{
1149 					done = true;
1150 					for (Grain** git = voice.grains.begin (); git < voice.grains.end(); ++git)
1151 					{
1152 						if ((**git).endFrame < iframe)
1153 						{
1154 							voice.grains.erase (git);
1155 							done = false;
1156 							break;
1157 						}
1158 					}
1159 				} while (!done);
1160 
1161 
1162 				// Seed new grains
1163 				if ((voice.grains.size > 0) && (voice.grains.back().startFrame <= iframe))
1164 				{
1165 					Grain& grain = voice.grains.back();
1166 
1167 					// Calculate pattern position first
1168 					uint64_t grainStartFrame;
1169 					uint64_t selectionFrames = (controllers[SAMPLE_END] - controllers[SAMPLE_START]) * sample->info.frames;
1170 					uint64_t patternFrames = double (selectionFrames) * controllers[PATTERN_SIZE];
1171 					double grainMs = controllers[PROPERTIES + GRAIN_SIZE * PROPERTIES_SIZE + PROPERTY_VALUE_START];
1172 					int64_t grainFrames = millisecondsToFrames (grainMs, rate);
1173 
1174 					if (iframe - voice.patternStartFrame > patternFrames) voice.patternStartFrame = iframe;
1175 					if (grainFrames <= 0) grainStartFrame = controllers[SAMPLE_START] * sample->info.frames;
1176 					else
1177 					{
1178 						int patternStep = double (iframe - voice.patternStartFrame) / double (grainFrames);
1179 						patternStep = LIMIT (patternStep, 0, MAXPATTERNSTEPS - 1);
1180 						int grainStep = pattern.getValue (patternStep);
1181 						grainStartFrame = controllers[SAMPLE_START] * sample->info.frames + grainStep * grainFrames;
1182 					}
1183 
1184 
1185 					// Set modulated grain properties
1186 					float graintune = getModulation (&voice, PROPERTIES + GRAIN_TUNE * PROPERTIES_SIZE, iframe);
1187 					float grainfine = getModulation (&voice, PROPERTIES + GRAIN_FINE * PROPERTIES_SIZE, iframe);
1188 					grain.speed = noteToFrequency(float (voice.note) + graintune + 0.01 * grainfine) / controllers[SAMPLE_FREQ];
1189 
1190 					float grainsize = getModulation (&voice, PROPERTIES + GRAIN_SIZE * PROPERTIES_SIZE, iframe);
1191 					grain.endFrame = grain.startFrame + millisecondsToFrames (grainsize, rate) * grain.speed;
1192 
1193 					float phase = getModulation (&voice, PROPERTIES + GRAIN_PHASE * PROPERTIES_SIZE, iframe);
1194 					grain.sampleStartFrame = grainStartFrame + grain.driveFrames - grainsize * phase;
1195 
1196 					grain.level = getModulation (&voice, PROPERTIES + GRAIN_LEVEL * PROPERTIES_SIZE, iframe);
1197 					grain.pan = getModulation (&voice, PROPERTIES + GRAIN_PAN * PROPERTIES_SIZE, iframe);
1198 
1199 
1200 					// Reserve next grain
1201 					float grainrate = getModulation (&voice, PROPERTIES + GRAIN_RATE * PROPERTIES_SIZE, iframe);
1202 					double diffframes = double (grain.endFrame - grain.startFrame) / grainrate;
1203 					uint64_t nextframe = iframe + diffframes;
1204 
1205 					float graindrive = getModulation (&voice, PROPERTIES + GRAIN_DRIVE * PROPERTIES_SIZE, iframe);
1206 					int64_t nextdriveframes = int64_t (grain.driveFrames + graindrive * diffframes) % grainFrames ;
1207 
1208 					voice.grains.push_back(Grain {nextframe , 0xFFFFFFFF00000000, 0ul, nextdriveframes, 0.0, 0.0, 0.0});
1209 
1210 					// Kick out first grain if grains full
1211 					while (voice.grains.size > controllers[MAX_GRAINS_PER_VOICE]) voice.grains.pop_front();
1212 				}
1213 
1214 
1215 				// Render
1216 				for (int g = 0; g < int (voice.grains.size); ++g)
1217 				{
1218 					Grain& grain = voice.grains[g];
1219 
1220 					if ((iframe >= grain.startFrame) && (iframe <= grain.endFrame))
1221 					{
1222 						double pos = grain.sampleStartFrame + double (iframe - grain.startFrame) * grain.speed;
1223 						uint64_t p0 = pos;
1224 						double pfrac = pos - p0;
1225 
1226 						if (int64_t (p0 + 1) < sample->info.frames)
1227 						{
1228 							double relpos =
1229 							(
1230 								grain.endFrame > grain.startFrame ?
1231 								double (iframe - grain.startFrame) / double (grain.endFrame - grain.startFrame) :
1232 								0
1233 							);
1234 							// Get raw sample
1235 							float s0 = sample->data[p0 * sample->info.channels];
1236 							float s1 = sample->data[(p0 + 1) * sample->info.channels];
1237 							float psample = s0 + (s1 - s0) * pfrac;
1238 							// Apply shape
1239 							psample *= shape[int (controllers[GRAIN_SHAPE])].getMapRawValue (relpos);
1240 							// Set level
1241 							psample *= grain.level;
1242 							// Set panning
1243 							float psample1 = psample * (grain.pan < 0 ? grain.pan + 1 : 1);
1244 							float psample2 = psample * (grain.pan < 0 ? 1 : 1 - grain.pan);
1245 
1246 							// Add to vsample
1247 							vsample1 += psample1;
1248 							vsample2 += psample2;
1249 						}
1250 					}
1251 				}
1252 
1253 				// Apply envelope and add to isample
1254 				float f = getModulation (&voice, SYNTH + SYNTH_LEVEL * PROPERTIES_SIZE, iframe);
1255 				isample1 += vsample1 * f;
1256 				isample2 += vsample2 * f;
1257 			}
1258 		}
1259 
1260 		// Write to audio out
1261 		audioOutput1[i] = isample1;
1262 		audioOutput2[i] = isample2;
1263 	}
1264 
1265 	// Cleanup release-ended voices
1266 	bool done;
1267 	do
1268 	{
1269 		done = true;
1270 		for (Voice** vit = voices.begin (); vit < voices.end(); ++vit)
1271 		{
1272 			if ((**vit).endFrame + (**vit).releaseFrames < frame + end)
1273 			{
1274 				voices.erase (vit);
1275 				done = false;
1276 				break;
1277 			}
1278 		}
1279 	} while (!done);
1280 }
1281 
getModulation(const Voice * voiceptr,const int property,const uint64_t frame) const1282 double BHarvestr::getModulation (const Voice* voiceptr, const int property, const uint64_t frame) const
1283 {
1284 	float start = controllers[property + PROPERTY_VALUE_START];
1285 	float end = controllers[property + PROPERTY_VALUE_END];
1286 	float factor = (controllers[property + PROPERTY_MODULATORS] == 0.0f ? 0.0f : 1.0f);
1287 
1288 	for (int i = 0; i < NR_PROPERTY_MODULATORS; ++i)
1289 	{
1290 		int mod = controllers[property + PROPERTY_MODULATORS + i];
1291 		if (mod == 0) break;
1292 
1293 		// Envelope
1294 		if (mod <= MODULATOR_ENV4)
1295 		{
1296 			if (voiceptr)
1297 			{
1298 				const int nr = mod - MODULATOR_ENV1;
1299 				if (frame < voiceptr->startFrame) factor = 0.0f;
1300 				else factor *= voiceptr->envelope[nr].getValue (framesToSeconds (frame - voiceptr->startFrame, rate));
1301 			}
1302 		}
1303 
1304 		// LFO
1305 		else if (mod <= MODULATOR_LFO4)
1306 		{
1307 			const int nr = mod - MODULATOR_LFO1;
1308 			factor *= controllers[LFOS + nr * LFO_SIZE + LFO_AMP] * lfo[nr].getValue (framesToSeconds (frame, rate));
1309 		}
1310 
1311 		// Sequencer
1312 		else if (mod <= MODULATOR_SEQ4)
1313 		{
1314 			const int nr = mod - MODULATOR_SEQ1;
1315 			factor *= seq[nr].getValue (framesToSeconds (frame, rate));
1316 		}
1317 
1318 		// Random
1319 		else
1320 		{
1321 			const int nr = mod - MODULATOR_RANDOM1;
1322 			const double rnd = double (lcg_rand()) / double (LCG_RAND_MAX);
1323 			factor *= controllers[RNDS + nr * RND_SIZE + RND_MIN] + rnd * (controllers[RNDS + nr * RND_SIZE + RND_MAX] - controllers[RNDS + nr * RND_SIZE + RND_MIN]);
1324 		}
1325 	}
1326 
1327 	return modulatef (start, end, factor);
1328 }
1329 
notifyStatusToGui()1330 void BHarvestr::notifyStatusToGui ()
1331 {
1332 	LV2_Atom_Forge_Frame forgeframe;
1333 	lv2_atom_forge_frame_time(&notifyForge, 0);
1334 	lv2_atom_forge_object(&notifyForge, &forgeframe, 0, uris.bharvestr_statusEvent);
1335 
1336 	// Time
1337 	lv2_atom_forge_key(&notifyForge, uris.bharvestr_statusTime);
1338 	lv2_atom_forge_double(&notifyForge, double (frame) / rate);
1339 
1340 	// LFO positions
1341 	float lfoPositions[NR_LFOS];
1342 	for (int i = 0; i < NR_LFOS; ++i) lfoPositions[i] = fracf (lfo[i].getPosition(double (frame) / rate) + lfo[i].getPhase());
1343 	lv2_atom_forge_key(&notifyForge, uris.bharvestr_statusLfoPositions);
1344 	lv2_atom_forge_vector(&notifyForge, sizeof(float), uris.atom_Float, NR_LFOS, (void*) lfoPositions);
1345 
1346 	// Seq positions
1347 	float seqPositions[NR_SEQS];
1348 	for (int i = 0; i < NR_SEQS; ++i) seqPositions[i] = fracf (seq[i].getPosition(double (frame) / rate) + seq[i].getPhase());
1349 	lv2_atom_forge_key(&notifyForge, uris.bharvestr_statusSeqPositions);
1350 	lv2_atom_forge_vector(&notifyForge, sizeof(float), uris.atom_Float, NR_LFOS, (void*) seqPositions);
1351 
1352 	// Env positions
1353 	float envPositions[2 * MAXVOICES];
1354 	int count = 0;
1355 	for (unsigned int v = 0; v < voices.size; ++v)
1356 	{
1357 		if (frame >= voices[v].startFrame)
1358 		{
1359 			if (frame < voices[v].endFrame)
1360 			{
1361 				envPositions[count] = 0.0f;
1362 				envPositions[count + 1] = framesToSeconds (frame - voices[v].startFrame, rate);
1363 			}
1364 			else
1365 			{
1366 				envPositions[count] = 1.0f;
1367 				envPositions[count + 1] = framesToSeconds (frame - voices[v].endFrame, rate);
1368 			}
1369 
1370 			count += 2;
1371 		}
1372 	}
1373 	lv2_atom_forge_key(&notifyForge, uris.bharvestr_statusEnvPositions);
1374 	lv2_atom_forge_vector(&notifyForge, sizeof(float), uris.atom_Float, count, (void*) envPositions);
1375 
1376 	// Grain properties
1377 	float grainProperties[NR_GRAIN_PROPERTIES];
1378 	for (int i = 0; i < NR_GRAIN_PROPERTIES; ++i)
1379 	{
1380 		grainProperties[i] = getModulation (nullptr, PROPERTIES + i * PROPERTIES_SIZE, frame);
1381 	}
1382 
1383 	lv2_atom_forge_key(&notifyForge, uris.bharvestr_statusGrainProperties);
1384 	lv2_atom_forge_vector(&notifyForge, sizeof(float), uris.atom_Float, NR_GRAIN_PROPERTIES, (void*) grainProperties);
1385 
1386 	// Pattern positions
1387 	int patternPos[MAXVOICES] = {0};
1388 	double grainMs = controllers[PROPERTIES + GRAIN_SIZE * PROPERTIES_SIZE + PROPERTY_VALUE_START];
1389 	int64_t grainFrames = millisecondsToFrames (grainMs, rate);
1390 	for (unsigned int v = 0; v < voices.size; ++v)
1391 	{
1392 		Voice& voice = voices[v];
1393 		int patternStep = double (frame - voice.patternStartFrame) / double (grainFrames);
1394 		patternPos[v] = LIMIT (patternStep, 0, MAXPATTERNSTEPS - 1);
1395 	}
1396 
1397 	lv2_atom_forge_key(&notifyForge, uris.bharvestr_statusPatternPositions);
1398 	lv2_atom_forge_vector(&notifyForge, sizeof(int), uris.atom_Int, voices.size, (void*) patternPos);
1399 
1400 	lv2_atom_forge_pop(&notifyForge, &forgeframe);
1401 }
1402 
forgeSamplePath(LV2_Atom_Forge * forge,LV2_Atom_Forge_Frame * frame,const char * path)1403 LV2_Atom_Forge_Ref BHarvestr::forgeSamplePath (LV2_Atom_Forge* forge, LV2_Atom_Forge_Frame* frame, const char* path)
1404 {
1405 	const LV2_Atom_Forge_Ref msg = lv2_atom_forge_object (forge, frame, 0, uris.bharvestr_sampleEvent);
1406 	if (msg)
1407 	{
1408 		lv2_atom_forge_key (forge, uris.bharvestr_samplePath);
1409 		lv2_atom_forge_path (forge, path, strlen (path) + 1);
1410 	}
1411 	return msg;
1412 }
1413 
notifySampleStopToGui()1414 void BHarvestr::notifySampleStopToGui ()
1415 {
1416 	LV2_Atom_Forge_Frame forgeframe;
1417 	lv2_atom_forge_frame_time(&notifyForge, 0);
1418 	lv2_atom_forge_object(&notifyForge, &forgeframe, 0, uris.bharvestr_sampleStop);
1419 	lv2_atom_forge_pop(&notifyForge, &forgeframe);
1420 
1421 	notify.sampleStop = false;
1422 }
1423 
notifySelectionStopToGui()1424 void BHarvestr::notifySelectionStopToGui ()
1425 {
1426 	LV2_Atom_Forge_Frame forgeframe;
1427 	lv2_atom_forge_frame_time(&notifyForge, 0);
1428 	lv2_atom_forge_object(&notifyForge, &forgeframe, 0, uris.bharvestr_selectionStop);
1429 	lv2_atom_forge_pop(&notifyForge, &forgeframe);
1430 
1431 	notify.selectionStop = false;
1432 }
1433 
notifyPatternToGui()1434 void BHarvestr::notifyPatternToGui ()
1435 {
1436 	if (pattern.getPattern() == USER_PATTERN)
1437 	{
1438 		LV2_Atom_Forge_Frame frame;
1439 		lv2_atom_forge_frame_time(&notifyForge, 0);
1440 		lv2_atom_forge_object(&notifyForge, &frame, 0, uris.bharvestr_patternEvent);
1441 		lv2_atom_forge_key(&notifyForge, uris.bharvestr_patternRows);
1442 		lv2_atom_forge_int(&notifyForge, pattern.getRows());
1443 		lv2_atom_forge_key(&notifyForge, uris.bharvestr_patternSteps);
1444 		lv2_atom_forge_int(&notifyForge, pattern.getSteps());
1445 		lv2_atom_forge_key(&notifyForge, uris.bharvestr_pattern);
1446 		lv2_atom_forge_vector(&notifyForge, sizeof(int), uris.atom_Int, MAXPATTERNSTEPS, (void*) pattern.getValues());
1447 		lv2_atom_forge_pop(&notifyForge, &frame);
1448 	}
1449 	notify.pattern = false;
1450 }
1451 
notifySamplePathToGui()1452 void BHarvestr::notifySamplePathToGui ()
1453 {
1454 	if (sample && sample->path)
1455 	{
1456 		LV2_Atom_Forge_Frame frame;
1457 		lv2_atom_forge_frame_time(&notifyForge, 0);
1458 		forgeSamplePath(&notifyForge, &frame, sample->path);
1459 		lv2_atom_forge_pop(&notifyForge, &frame);
1460 	}
1461 
1462 	notify.samplePath = false;
1463 }
1464 
notifyDisplayToGui()1465 void BHarvestr::notifyDisplayToGui ()
1466 {
1467 	LV2_Atom_Forge_Frame frame;
1468 	lv2_atom_forge_frame_time(&notifyForge, 0);
1469 	lv2_atom_forge_object(&notifyForge, &frame, 0, uris.bharvestr_displayEvent);
1470 
1471 	if (notify.sampleDisplay)
1472 	{
1473 		float sampleSize = 0.0f;
1474 		float sampleDisplay[DISPLAYDATASIZE] {0.0f};
1475 		if (sample && sample->info.frames)
1476 		{
1477 			sampleSize = double (sample->info.frames) / rate;
1478 			for (int i = 0; i < DISPLAYDATASIZE; ++i)
1479 			{
1480 				sampleDisplay[i] = sample->data[size_t (i * sample->info.frames / DISPLAYDATASIZE) * sample->info.channels];
1481 			}
1482 		}
1483 
1484 		else memset (sampleDisplay, 0, DISPLAYDATASIZE * sizeof (float));
1485 
1486 		lv2_atom_forge_key(&notifyForge, uris.bharvestr_sampleSize);
1487 		lv2_atom_forge_float(&notifyForge, sampleSize);
1488 		lv2_atom_forge_key(&notifyForge, uris.bharvestr_sampleDisplayData);
1489 		lv2_atom_forge_vector(&notifyForge, sizeof(float), uris.atom_Float, DISPLAYDATASIZE, (void*) sampleDisplay);
1490 		notify.sampleDisplay = false;
1491 	}
1492 
1493 	if (notify.selectionDisplay)
1494 	{
1495 		float selectionDisplay[DISPLAYDATASIZE] {0.0f};
1496 		if (sample && sample->info.frames)
1497 		{
1498 			size_t s = controllers[SAMPLE_START] * sample->info.frames;
1499 			size_t e = controllers[SAMPLE_END] * sample->info.frames;
1500 
1501 			for (int i = 0; i < DISPLAYDATASIZE; ++i)
1502 			{
1503 				selectionDisplay[i] = sample->data[(s + size_t (i * (e - s) / DISPLAYDATASIZE)) * sample->info.channels];
1504 			}
1505 		}
1506 
1507 		else memset (selectionDisplay, 0, DISPLAYDATASIZE * sizeof (float));
1508 
1509 		lv2_atom_forge_key(&notifyForge, uris.bharvestr_selectionDisplayData);
1510 		lv2_atom_forge_vector(&notifyForge, sizeof(float), uris.atom_Float, DISPLAYDATASIZE, (void*) selectionDisplay);
1511 		notify.selectionDisplay = false;
1512 	}
1513 
1514 	lv2_atom_forge_pop(&notifyForge, &frame);
1515 }
1516 
notifyShapeToGui(ShapeIndex index)1517 void BHarvestr::notifyShapeToGui (ShapeIndex index)
1518 {
1519 	unsigned int shapeNr = index;
1520 	size_t size = shape[shapeNr].size ();
1521 
1522 	// Load shapeBuffer
1523 	float shapeBuffer[MAXNODES * 7];
1524 	for (unsigned int i = 0; i < size; ++i)
1525 	{
1526 		Node node = shape[shapeNr].getRawNode (i);
1527 		shapeBuffer[i * 7] = (float)node.nodeType;
1528 		shapeBuffer[i * 7 + 1] = (float)node.point.x;
1529 		shapeBuffer[i * 7 + 2] = (float)node.point.y;
1530 		shapeBuffer[i * 7 + 3] = (float)node.handle1.x;
1531 		shapeBuffer[i * 7 + 4] = (float)node.handle1.y;
1532 		shapeBuffer[i * 7 + 5] = (float)node.handle2.x;
1533 		shapeBuffer[i * 7 + 6] = (float)node.handle2.y;
1534 	}
1535 
1536 	// Notify shapeBuffer
1537 	LV2_Atom_Forge_Frame frame;
1538 	lv2_atom_forge_frame_time(&notifyForge, 0);
1539 	lv2_atom_forge_object(&notifyForge, &frame, 0, uris.bharvestr_shapeEvent);
1540 	lv2_atom_forge_key(&notifyForge, uris.bharvestr_shapeIndex);
1541 	lv2_atom_forge_int(&notifyForge, shapeNr);
1542 	lv2_atom_forge_key(&notifyForge, uris.bharvestr_shapeData);
1543 	lv2_atom_forge_vector(&notifyForge, sizeof(float), uris.atom_Float, (uint32_t) (7 * size), &shapeBuffer);
1544 	lv2_atom_forge_pop(&notifyForge, &frame);
1545 
1546 	notify.shape[shapeNr] = false;
1547 }
1548 
notifyPresetInfoToGui()1549 void BHarvestr::notifyPresetInfoToGui()
1550 {
1551 	LV2_Atom_Forge_Frame frame;
1552 	lv2_atom_forge_frame_time(&notifyForge, 0);
1553 	lv2_atom_forge_object(&notifyForge, &frame, 0, uris.bharvestr_presetInfoEvent);
1554 	lv2_atom_forge_key(&notifyForge, uris.bharvestr_presetInfoName);
1555 	lv2_atom_forge_string(&notifyForge, presetInfo.name, strlen (presetInfo.name) + 1);
1556 	lv2_atom_forge_key(&notifyForge, uris.bharvestr_presetInfoType);
1557 	lv2_atom_forge_string(&notifyForge, presetInfo.type, strlen (presetInfo.type) + 1);
1558 	lv2_atom_forge_key(&notifyForge, uris.bharvestr_presetInfoDate);
1559 	lv2_atom_forge_int(&notifyForge, presetInfo.date);
1560 	lv2_atom_forge_key(&notifyForge, uris.bharvestr_presetInfoCreator);
1561 	lv2_atom_forge_string(&notifyForge, presetInfo.creator, strlen (presetInfo.creator) + 1);
1562 	lv2_atom_forge_key(&notifyForge, uris.bharvestr_presetInfoURI);
1563 	lv2_atom_forge_string(&notifyForge, presetInfo.uri, strlen (presetInfo.uri) + 1);
1564 	lv2_atom_forge_key(&notifyForge, uris.bharvestr_presetInfoLicense);
1565 	lv2_atom_forge_string(&notifyForge, presetInfo.license, strlen (presetInfo.license) + 1);
1566 	lv2_atom_forge_key(&notifyForge, uris.bharvestr_presetInfoDescription);
1567 	lv2_atom_forge_string(&notifyForge, presetInfo.description, strlen (presetInfo.description) + 1);
1568 	lv2_atom_forge_pop(&notifyForge, &frame);
1569 
1570 	notify.presetInfo = false;
1571 }
1572 
notifyMessageToGui()1573 void BHarvestr::notifyMessageToGui()
1574 {
1575 	LV2_Atom_Forge_Frame frame;
1576 	lv2_atom_forge_frame_time(&notifyForge, 0);
1577 	lv2_atom_forge_object(&notifyForge, &frame, 0, uris.bharvestr_messageEvent);
1578 	lv2_atom_forge_key(&notifyForge, uris.bharvestr_message);
1579 	lv2_atom_forge_string(&notifyForge, message, strlen (message) + 1);
1580 	lv2_atom_forge_pop(&notifyForge, &frame);
1581 
1582 	notify.message = false;
1583 }
1584 
1585 /*
1586  *
1587  *
1588  ******************************************************************************
1589  *  LV2 specific declarations
1590  */
1591 
instantiate(const LV2_Descriptor * descriptor,double samplerate,const char * bundle_path,const LV2_Feature * const * features)1592 static LV2_Handle instantiate (const LV2_Descriptor* descriptor, double samplerate, const char* bundle_path, const LV2_Feature* const* features)
1593 {
1594 	// New instance
1595 	BHarvestr* instance;
1596 	try {instance = new BHarvestr(samplerate, features);}
1597 	catch (std::exception& exc)
1598 	{
1599 		fprintf (stderr, "BHarvestr.lv2: Plugin instantiation failed. %s\n", exc.what ());
1600 		return NULL;
1601 	}
1602 
1603 	return (LV2_Handle)instance;
1604 }
1605 
connect_port(LV2_Handle instance,uint32_t port,void * data)1606 static void connect_port (LV2_Handle instance, uint32_t port, void *data)
1607 {
1608 	BHarvestr* inst = (BHarvestr*) instance;
1609 	inst->connect_port (port, data);
1610 }
1611 
activate(LV2_Handle instance)1612 void activate (LV2_Handle instance)
1613 {
1614 	BHarvestr* inst = (BHarvestr*) instance;
1615 	if (inst) inst->activate();
1616 }
1617 
run(LV2_Handle instance,uint32_t n_samples)1618 static void run (LV2_Handle instance, uint32_t n_samples)
1619 {
1620 	BHarvestr* inst = (BHarvestr*) instance;
1621 	if (inst) inst->run (n_samples);
1622 }
1623 
deactivate(LV2_Handle instance)1624 void deactivate (LV2_Handle instance)
1625 {
1626 	BHarvestr* inst = (BHarvestr*) instance;
1627 	if (inst) inst->deactivate();
1628 }
1629 
state_save(LV2_Handle instance,LV2_State_Store_Function store,LV2_State_Handle handle,uint32_t flags,const LV2_Feature * const * features)1630 static LV2_State_Status state_save(LV2_Handle instance, LV2_State_Store_Function store, LV2_State_Handle handle, uint32_t flags,
1631            const LV2_Feature* const* features)
1632 {
1633 	BHarvestr* inst = (BHarvestr*)instance;
1634 	if (!inst) return LV2_STATE_SUCCESS;
1635 
1636 	return inst->state_save (store, handle, flags, features);
1637 }
1638 
state_restore(LV2_Handle instance,LV2_State_Retrieve_Function retrieve,LV2_State_Handle handle,uint32_t flags,const LV2_Feature * const * features)1639 static LV2_State_Status state_restore(LV2_Handle instance, LV2_State_Retrieve_Function retrieve, LV2_State_Handle handle, uint32_t flags,
1640            const LV2_Feature* const* features)
1641 {
1642 	BHarvestr* inst = (BHarvestr*)instance;
1643 	if (!inst) return LV2_STATE_SUCCESS;
1644 
1645 	return inst->state_restore (retrieve, handle, flags, features);
1646 }
1647 
work(LV2_Handle instance,LV2_Worker_Respond_Function respond,LV2_Worker_Respond_Handle handle,uint32_t size,const void * data)1648 static LV2_Worker_Status work (LV2_Handle instance, LV2_Worker_Respond_Function respond, LV2_Worker_Respond_Handle handle,
1649 	uint32_t size, const void* data)
1650 {
1651 	BHarvestr* inst = (BHarvestr*)instance;
1652 	if (!inst) return LV2_WORKER_SUCCESS;
1653 
1654 	return inst->work (respond, handle, size, data);
1655 }
1656 
work_response(LV2_Handle instance,uint32_t size,const void * data)1657 static LV2_Worker_Status work_response (LV2_Handle instance, uint32_t size,  const void* data)
1658 {
1659 	BHarvestr* inst = (BHarvestr*)instance;
1660 	if (!inst) return LV2_WORKER_SUCCESS;
1661 
1662 	return inst->work_response (size, data);
1663 }
1664 
cleanup(LV2_Handle instance)1665 static void cleanup (LV2_Handle instance)
1666 {
1667 	BHarvestr* inst = (BHarvestr*) instance;
1668 	if (inst) delete inst;
1669 }
1670 
1671 
extension_data(const char * uri)1672 static const void* extension_data(const char* uri)
1673 {
1674   static const LV2_State_Interface  state  = {state_save, state_restore};
1675   static const LV2_Worker_Interface worker = {work, work_response, NULL};
1676   if (!strcmp(uri, LV2_STATE__interface)) return &state;
1677   if (!strcmp(uri, LV2_WORKER__interface)) return &worker;
1678   return NULL;
1679 }
1680 
1681 
1682 static const LV2_Descriptor descriptor =
1683 {
1684 		BHARVESTR_URI,
1685 		instantiate,
1686 		connect_port,
1687 		activate,
1688 		run,
1689 		deactivate,
1690 		cleanup,
1691 		extension_data
1692 };
1693 
1694 // LV2 Symbol Export
lv2_descriptor(uint32_t index)1695 LV2_SYMBOL_EXPORT const LV2_Descriptor* lv2_descriptor (uint32_t index)
1696 {
1697 	switch (index)
1698 	{
1699 	case 0: return &descriptor;
1700 	default: return NULL;
1701 	}
1702 }
1703 
1704 /* End of LV2 specific declarations
1705  *
1706  * *****************************************************************************
1707  *
1708  *
1709  */
1710