1 // samplv1.cpp
2 //
3 /****************************************************************************
4    Copyright (C) 2012-2021, rncbc aka Rui Nuno Capela. All rights reserved.
5 
6    This program is free software; you can redistribute it and/or
7    modify it under the terms of the GNU General Public License
8    as published by the Free Software Foundation; either version 2
9    of the License, or (at your option) 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 along
17    with this program; if not, write to the Free Software Foundation, Inc.,
18    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 
20 *****************************************************************************/
21 
22 #include "samplv1.h"
23 
24 #include "samplv1_sample.h"
25 
26 #include "samplv1_wave.h"
27 #include "samplv1_ramp.h"
28 
29 #include "samplv1_list.h"
30 
31 #include "samplv1_filter.h"
32 #include "samplv1_formant.h"
33 
34 #include "samplv1_fx.h"
35 #include "samplv1_reverb.h"
36 
37 #include "samplv1_pshifter.h"
38 
39 #include "samplv1_config.h"
40 #include "samplv1_controls.h"
41 #include "samplv1_programs.h"
42 #include "samplv1_tuning.h"
43 
44 #include "samplv1_sched.h"
45 
46 
47 #ifdef CONFIG_DEBUG_0
48 #include <cstdio>
49 #endif
50 
51 #include <cstring>
52 
53 
54 //-------------------------------------------------------------------------
55 // samplv1_impl
56 //
57 // -- borrowed and revamped from synth.h of synth4
58 //    Copyright (C) 2007 jorgen, linux-vst.com
59 //
60 
61 const uint8_t MAX_VOICES  = 64;			// max polyphony
62 const uint8_t MAX_NOTES   = 128;
63 
64 const float MIN_ENV_MSECS = 0.5f;		// min 500 usec per stage
65 const float MAX_ENV_MSECS = 5000.0f;	// max 5 sec per stage (default)
66 
67 const float OCTAVE_SCALE  = 12.0f;
68 const float TUNING_SCALE  = 1.0f;
69 const float SWEEP_SCALE   = 0.5f;
70 const float PITCH_SCALE   = 0.5f;
71 
72 const uint8_t MAX_DIRECT_NOTES = (MAX_VOICES >> 2);
73 
74 
75 // maximum helper
76 
samplv1_max(float a,float b)77 inline float samplv1_max ( float a, float b )
78 {
79 	return (a > b ? a : b);
80 }
81 
82 
83 // hyperbolic-tangent fast approximation
84 
samplv1_tanhf(const float x)85 inline float samplv1_tanhf ( const float x )
86 {
87 	const float x2 = x * x;
88 	return x * (27.0f + x2) / (27.0f + 9.0f * x2);
89 }
90 
91 
92 // sigmoids
93 
samplv1_sigmoid(const float x)94 inline float samplv1_sigmoid ( const float x )
95 {
96 //	return 2.0f / (1.0f + ::expf(-5.0f * x)) - 1.0f;
97 	return samplv1_tanhf(2.0f * x);
98 }
99 
samplv1_sigmoid_0(const float x,const float t0)100 inline float samplv1_sigmoid_0 ( const float x, const float t0 )
101 {
102 	const float t1 = 1.0f - t0;
103 #if 0
104 	if (x > +t1)
105 		return +t1 + t0 * samplv1_tanhf(+(x - t1) / t0);
106 	else
107 	if (x < -t1)
108 		return -t1 - t0 * samplv1_tanhf(-(x + t1) / t0);
109 	else
110 		return x;
111 #else
112 	return (x < -1.0f ? -t1 : (x > +1.0f ? t1 : t1 * x * (1.5f - 0.5f * x * x)));
113 #endif
114 }
115 
samplv1_sigmoid_1(const float x,const float t0=0.01f)116 inline float samplv1_sigmoid_1 ( const float x, const float t0 = 0.01f )
117 {
118 	return 0.5f * (1.0f + samplv1_sigmoid_0(2.0f * x - 1.0f, t0));
119 }
120 
121 
122 // velocity hard-split curve
123 
samplv1_velocity(const float x,const float p=0.2f)124 inline float samplv1_velocity ( const float x, const float p = 0.2f )
125 {
126 	return ::powf(x, (1.0f - p));
127 }
128 
129 
130 // pitchbend curve
131 
samplv1_pow2f(const float x)132 inline float samplv1_pow2f ( const float x )
133 {
134 // simplest power-of-2 straight linearization
135 // -- x argument valid in [-1, 1] interval
136 //	return 1.0f + (x < 0.0f ? 0.5f : 1.0f) * x;
137 	return ::powf(2.0f, x);
138 }
139 
140 
141 // convert note to frequency (hertz)
142 
samplv1_freq2(float delta)143 inline float samplv1_freq2 ( float delta )
144 {
145 	return ::powf(2.0f, delta / 12.0f);
146 }
147 
samplv1_freq(int note)148 inline float samplv1_freq ( int note )
149 {
150 	return (440.0f / 32.0f) * samplv1_freq2(float(note - 9));
151 }
152 
153 
154 // parameter port (basic)
155 
156 class samplv1_port
157 {
158 public:
159 
samplv1_port()160 	samplv1_port() : m_port(nullptr), m_value(0.0f), m_vport(0.0f) {}
161 
~samplv1_port()162 	virtual ~samplv1_port() {}
163 
set_port(float * port)164 	void set_port(float *port)
165 		{ m_port = port; }
port() const166 	float *port() const
167 		{ return m_port; }
168 
set_value(float value)169 	virtual void set_value(float value)
170 		{ m_value = value; if (m_port) m_vport = *m_port; }
171 
value() const172 	float value() const
173 		{ return m_value; }
value_ptr()174 	float *value_ptr()
175 		{ tick(1); return &m_value; }
176 
tick(uint32_t)177 	virtual float tick(uint32_t /*nstep*/)
178 	{
179 		if (m_port && ::fabsf(*m_port - m_vport) > 0.001f)
180 			set_value(*m_port);
181 
182 		return m_value;
183 	}
184 
operator *()185 	float operator *()
186 		{ return tick(1); }
187 
188 private:
189 
190 	float *m_port;
191 	float  m_value;
192 	float  m_vport;
193 };
194 
195 
196 // parameter port (smoothed)
197 
198 class samplv1_port2 : public samplv1_port
199 {
200 public:
201 
samplv1_port2()202 	samplv1_port2() : m_vtick(0.0f), m_vstep(0.0f), m_nstep(0) {}
203 
204 	static const uint32_t NSTEP = 32;
205 
set_value(float value)206 	void set_value(float value)
207 	{
208 		m_vtick = samplv1_port::value();
209 
210 		m_nstep = NSTEP;
211 		m_vstep = (value - m_vtick) / float(m_nstep);
212 
213 		samplv1_port::set_value(value);
214 	}
215 
tick(uint32_t nstep)216 	float tick(uint32_t nstep)
217 	{
218 		if (m_nstep == 0)
219 			return samplv1_port::tick(nstep);
220 
221 		if (m_nstep >= nstep) {
222 			m_vtick += m_vstep * float(nstep);
223 			m_nstep -= nstep;
224 		} else {
225 			m_vtick += m_vstep * float(m_nstep);
226 			m_nstep  = 0;
227 		}
228 
229 		return m_vtick;
230 	}
231 
232 private:
233 
234 	float    m_vtick;
235 	float    m_vstep;
236 	uint32_t m_nstep;
237 };
238 
239 
240 // parameter port (scheduled/detached)
241 
242 class samplv1_port3_sched : public samplv1_sched
243 {
244 public:
245 
246 	// ctor.
samplv1_port3_sched(samplv1 * pSampl)247 	samplv1_port3_sched(samplv1 *pSampl)
248 		: samplv1_sched(pSampl, samplv1_sched::Controller) {}
249 
250 	// (pure) virtual prober.
251 	virtual float probe(int sid) const = 0;
252 };
253 
254 
255 class samplv1_port3 : public samplv1_port
256 {
257 public:
258 
samplv1_port3(samplv1_port3_sched * sched,samplv1::ParamIndex index)259 	samplv1_port3(samplv1_port3_sched *sched, samplv1::ParamIndex index)
260 		: m_sched(sched), m_index(index) {}
261 
set_value(float value)262 	void set_value(float value)
263 	{
264 		const float v0 = m_sched->probe(m_index);
265 		const float d0 = ::fabsf(value - v0);
266 
267 		samplv1_port::set_value(value);
268 
269 		if (d0 > 0.001f)
270 			m_sched->schedule(m_index);
271 	}
272 
set_value_sync(float value)273 	void set_value_sync(float value)
274 	{
275 		samplv1_port::set_value(value);
276 	}
277 
278 private:
279 
280 	samplv1_port3_sched *m_sched;
281 	samplv1::ParamIndex  m_index;
282 };
283 
284 
285 // envelope
286 
287 struct samplv1_env
288 {
289 	// envelope stages
290 
291 	enum Stage { Idle = 0, Attack, Decay, Sustain, Release, End };
292 
293 	// per voice
294 
295 	struct State
296 	{
297 		// ctor.
Statesamplv1_env::State298 		State() : running(false), stage(Idle),
299 			phase(0.0f), delta(0.0f), value(0.0f),
300 			c1(1.0f), c0(0.0f), frames(0) {}
301 
302 		// process
ticksamplv1_env::State303 		float tick()
304 		{
305 			if (running && frames > 0) {
306 				phase += delta;
307 				value = c1 * phase * (2.0f - phase) + c0;
308 				--frames;
309 			}
310 			return value;
311 		}
312 
313 		// state
314 		bool running;
315 		Stage stage;
316 		float phase;
317 		float delta;
318 		float value;
319 		float c1, c0;
320 		uint32_t frames;
321 	};
322 
startsamplv1_env323 	void start(State *p)
324 	{
325 		p->running = true;
326 		p->stage = Attack;
327 		p->frames = uint32_t(*attack * *attack * max_frames);
328 		if (p->frames < min_frames1) // prevent click on too fast attack
329 			p->frames = min_frames1;
330 		p->phase = 0.0f;
331 		p->delta = 1.0f / float(p->frames);
332 		p->value = 0.0f;
333 		p->c1 = 1.0f;
334 		p->c0 = 0.0f;
335 	}
336 
nextsamplv1_env337 	void next(State *p)
338 	{
339 		if (p->stage == Attack) {
340 			p->stage = Decay;
341 			p->frames = uint32_t(*decay * *decay * max_frames);
342 			if (p->frames < min_frames2) // prevent click on too fast decay
343 				p->frames = min_frames2;
344 			p->phase = 0.0f;
345 			p->delta = 1.0f / float(p->frames);
346 			p->c1 = *sustain - 1.0f;
347 			p->c0 = p->value;
348 		}
349 		else if (p->stage == Decay) {
350 			p->running = false; // stay at this stage until note_off received
351 			p->stage = Sustain;
352 			p->frames = 0;
353 			p->phase = 0.0f;
354 			p->delta = 0.0f;
355 			p->c1 = 0.0f;
356 			p->c0 = p->value;
357 		}
358 		else if (p->stage == Release) {
359 			p->running = false;
360 			p->stage = End;
361 			p->frames = 0;
362 			p->phase = 0.0f;
363 			p->delta = 0.0f;
364 			p->value = 0.0f;
365 			p->c1 = 0.0f;
366 			p->c0 = 0.0f;
367 		}
368 	}
369 
note_offsamplv1_env370 	void note_off(State *p)
371 	{
372 		p->running = true;
373 		p->stage = Release;
374 		p->frames = uint32_t(*release * *release * max_frames);
375 		if (p->frames < min_frames2) // prevent click on too fast release
376 			p->frames = min_frames2;
377 		p->phase = 0.0f;
378 		p->delta = 1.0f / float(p->frames);
379 		p->c1 = -(p->value);
380 		p->c0 = p->value;
381 	}
382 
note_off_fastsamplv1_env383 	void note_off_fast(State *p)
384 	{
385 		p->running = true;
386 		p->stage = Release;
387 		p->frames = min_frames2;
388 		p->phase = 0.0f;
389 		p->delta = 1.0f / float(p->frames);
390 		p->c1 = -(p->value);
391 		p->c0 = p->value;
392 	}
393 
restartsamplv1_env394 	void restart(State *p, bool legato)
395 	{
396 		p->running = true;
397 		if (legato) {
398 			p->stage = Decay;
399 			p->frames = min_frames2;
400 			p->phase = 0.0f;
401 			p->delta = 1.0f / float(p->frames);
402 			p->c1 = *sustain - p->value;
403 			p->c0 = 0.0f;
404 		} else {
405 			p->stage = Attack;
406 			p->frames = uint32_t(*attack * *attack * max_frames);
407 			if (p->frames < min_frames1)
408 				p->frames = min_frames1;
409 			p->phase = 0.0f;
410 			p->delta = 1.0f / float(p->frames);
411 			p->c1 = 1.0f;
412 			p->c0 = 0.0f;
413 		}
414 	}
415 
idlesamplv1_env416 	void idle(State *p)
417 	{
418 		p->running = false;
419 		p->stage = Idle;
420 		p->frames = 0;
421 		p->phase = 0.0f;
422 		p->delta = 0.0f;
423 		p->value = 1.0f;
424 		p->c1 = 0.0f;
425 		p->c0 = 0.0f;
426 	}
427 
428 	// parameters
429 
430 	samplv1_port attack;
431 	samplv1_port decay;
432 	samplv1_port sustain;
433 	samplv1_port release;
434 
435 	uint32_t min_frames1;
436 	uint32_t min_frames2;
437 	uint32_t max_frames;
438 };
439 
440 
441 // midi control
442 
443 struct samplv1_ctl
444 {
samplv1_ctlsamplv1_ctl445 	samplv1_ctl() { reset(); }
446 
resetsamplv1_ctl447 	void reset()
448 	{
449 		pressure = 0.0f;
450 		pitchbend = 1.0f;
451 		modwheel = 0.0f;
452 		panning = 0.0f;
453 		volume = 1.0f;
454 		sustain = false;
455 	}
456 
457 	float pressure;
458 	float pitchbend;
459 	float modwheel;
460 	float panning;
461 	float volume;
462 	bool  sustain;
463 };
464 
465 
466 // dco
467 
468 class samplv1_gen : samplv1_port3_sched
469 {
470 public:
471 
samplv1_gen(samplv1 * pSampl)472 	samplv1_gen(samplv1 *pSampl)
473 		: samplv1_port3_sched(pSampl),
474 			reverse(this, samplv1::GEN1_REVERSE),
475 			offset(this, samplv1::GEN1_OFFSET),
476 			offset_1(this, samplv1::GEN1_OFFSET_1),
477 			offset_2(this, samplv1::GEN1_OFFSET_2),
478 			loop(this, samplv1::GEN1_LOOP),
479 			loop_1(this, samplv1::GEN1_LOOP_1),
480 			loop_2(this, samplv1::GEN1_LOOP_2) {}
481 
482 	samplv1_port  sample;
483 	samplv1_port3 reverse;
484 	samplv1_port3 offset;
485 	samplv1_port3 offset_1;
486 	samplv1_port3 offset_2;
487 	samplv1_port3 loop;
488 	samplv1_port3 loop_1;
489 	samplv1_port3 loop_2;
490 	samplv1_port  octave;
491 	samplv1_port  tuning;
492 	samplv1_port  glide;
493 	samplv1_port  envtime;
494 
495 	float sample0, envtime0;
496 
497 protected:
498 
probe(int sid) const499 	float probe(int sid) const
500 	{
501 		float ret = 0.0f;
502 		samplv1 *pSampl = samplv1_port3_sched::instance();
503 
504 		switch (samplv1::ParamIndex(sid)) {
505 		case samplv1::GEN1_REVERSE:
506 			ret = (pSampl->isReverse() ? 1.0f : 0.0f);
507 			break;
508 		case samplv1::GEN1_OFFSET:
509 			ret = (pSampl->isOffset() ? 1.0f : 0.0f);
510 			break;
511 		case samplv1::GEN1_OFFSET_1: {
512 			const uint32_t iSampleLength
513 				= pSampl->sample()->length();
514 			const uint32_t iOffsetStart
515 				= pSampl->offsetStart();
516 			ret = (iSampleLength > 0
517 				? float(iOffsetStart) / float(iSampleLength)
518 				: 0.0f);
519 			break;
520 		}
521 		case samplv1::GEN1_OFFSET_2: {
522 			const uint32_t iSampleLength
523 				= pSampl->sample()->length();
524 			const uint32_t iOffsetEnd
525 				= pSampl->offsetEnd();
526 			ret = (iSampleLength > 0
527 				? float(iOffsetEnd) / float(iSampleLength)
528 				: 1.0f);
529 			break;
530 		}
531 		case samplv1::GEN1_LOOP:
532 			ret = (pSampl->isLoop() ? 1.0f : 0.0f);
533 			break;
534 		case samplv1::GEN1_LOOP_1: {
535 			const uint32_t iSampleLength
536 				= pSampl->sample()->length();
537 			const uint32_t iLoopStart
538 				= pSampl->loopStart();
539 			ret = (iSampleLength > 0
540 				? float(iLoopStart) / float(iSampleLength)
541 				: 0.0f);
542 			break;
543 		}
544 		case samplv1::GEN1_LOOP_2: {
545 			const uint32_t iSampleLength
546 				= pSampl->sample()->length();
547 			const uint32_t iLoopEnd
548 				= pSampl->loopEnd();
549 			ret = (iSampleLength > 0
550 				? float(iLoopEnd) / float(iSampleLength)
551 				: 1.0f);
552 			break;
553 		}
554 		default:
555 			break;
556 		}
557 
558 		return ret;
559 	}
560 
process(int sid)561 	void process(int sid)
562 	{
563 		samplv1 *pSampl = samplv1_port3_sched::instance();
564 
565 		switch (samplv1::ParamIndex(sid)) {
566 		case samplv1::GEN1_REVERSE:
567 			pSampl->setReverse(reverse.value() > 0.5f, true);
568 			break;
569 		case samplv1::GEN1_OFFSET:
570 			pSampl->setOffset(offset.value() > 0.5f, true);
571 			break;
572 		case samplv1::GEN1_OFFSET_1:
573 			if (pSampl->isOffset()) {
574 				const uint32_t iSampleLength
575 					= pSampl->sample()->length();
576 				const uint32_t iOffsetEnd
577 					= pSampl->offsetEnd();
578 				uint32_t iOffsetStart
579 					= uint32_t(offset_1.value() * float(iSampleLength));
580 				if (pSampl->isLoop()) {
581 					const uint32_t iLoopStart
582 						= pSampl->loopStart();
583 					if (iOffsetStart >= iLoopStart)
584 						iOffsetStart = iLoopStart - 1;
585 				}
586 				if (iOffsetStart >= iOffsetEnd)
587 					iOffsetStart  = iOffsetEnd - 1;
588 				pSampl->setOffsetRange(iOffsetStart, iOffsetEnd, true);
589 			}
590 			break;
591 		case samplv1::GEN1_OFFSET_2:
592 			if (pSampl->isOffset()) {
593 				const uint32_t iSampleLength
594 					= pSampl->sample()->length();
595 				const uint32_t iOffsetStart
596 					= pSampl->offsetStart();
597 				uint32_t iOffsetEnd
598 					= uint32_t(offset_2.value() * float(iSampleLength));
599 				if (pSampl->isLoop()) {
600 					const uint32_t iLoopEnd
601 						= pSampl->loopEnd();
602 					if (iLoopEnd >= iOffsetEnd)
603 						iOffsetEnd = iLoopEnd + 1;
604 				}
605 				if (iOffsetStart >= iOffsetEnd)
606 					iOffsetEnd = iOffsetStart + 1;
607 				pSampl->setOffsetRange(iOffsetStart, iOffsetEnd, true);
608 			}
609 			break;
610 		case samplv1::GEN1_LOOP:
611 			pSampl->setLoop(loop.value() > 0.5f, true);
612 			break;
613 		case samplv1::GEN1_LOOP_1:
614 			if (pSampl->isLoop()) {
615 				const uint32_t iSampleLength
616 					= pSampl->sample()->length();
617 				const uint32_t iLoopEnd
618 					= pSampl->loopEnd();
619 				uint32_t iLoopStart
620 					= uint32_t(loop_1.value() * float(iSampleLength));
621 				if (pSampl->isOffset()) {
622 					const uint32_t iOffsetStart
623 						= pSampl->offsetStart();
624 					if (iLoopStart < iOffsetStart)
625 						iLoopStart = iOffsetStart;
626 				}
627 				if (iLoopStart >= iLoopEnd)
628 					iLoopStart  = iLoopEnd - 1;
629 				pSampl->setLoopRange(iLoopStart, iLoopEnd, true);
630 			}
631 			break;
632 		case samplv1::GEN1_LOOP_2:
633 			if (pSampl->isLoop()) {
634 				const uint32_t iSampleLength
635 					= pSampl->sample()->length();
636 				const uint32_t iLoopStart
637 					= pSampl->loopStart();
638 				uint32_t iLoopEnd
639 					= uint32_t(loop_2.value() * float(iSampleLength));
640 				if (pSampl->isOffset()) {
641 					const uint32_t iOffsetEnd
642 						= pSampl->offsetEnd();
643 					if (iLoopEnd > iOffsetEnd)
644 						iLoopEnd = iOffsetEnd;
645 				}
646 				if (iLoopStart >= iLoopEnd)
647 					iLoopEnd = iLoopStart + 1;
648 				pSampl->setLoopRange(iLoopStart, iLoopEnd, true);
649 			}
650 			break;
651 		default:
652 			break;
653 		}
654 	}
655 };
656 
657 
658 // dcf
659 
660 struct samplv1_dcf
661 {
662 	samplv1_port  enabled;
663 	samplv1_port2 cutoff;
664 	samplv1_port2 reso;
665 	samplv1_port  type;
666 	samplv1_port  slope;
667 	samplv1_port2 envelope;
668 
669 	samplv1_env   env;
670 };
671 
672 
673 // lfo
674 struct samplv1_voice;
675 
676 struct samplv1_lfo
677 {
678 	samplv1_port  enabled;
679 	samplv1_port  shape;
680 	samplv1_port  width;
681 	samplv1_port2 bpm;
682 	samplv1_port2 rate;
683 	samplv1_port  sync;
684 	samplv1_port2 sweep;
685 	samplv1_port2 pitch;
686 	samplv1_port2 cutoff;
687 	samplv1_port2 reso;
688 	samplv1_port2 panning;
689 	samplv1_port2 volume;
690 
691 	samplv1_env   env;
692 
693 	samplv1_voice *psync;
694 };
695 
696 
697 // dca
698 
699 struct samplv1_dca
700 {
701 	samplv1_port enabled;
702 	samplv1_port volume;
703 
704 	samplv1_env  env;
705 };
706 
707 
708 
709 // def (ranges)
710 
711 struct samplv1_def
712 {
713 	samplv1_port pitchbend;
714 	samplv1_port modwheel;
715 	samplv1_port pressure;
716 	samplv1_port velocity;
717 	samplv1_port channel;
718 	samplv1_port mono;
719 };
720 
721 
722 // out (mix)
723 
724 struct samplv1_out
725 {
726 	samplv1_port width;
727 	samplv1_port panning;
728 	samplv1_port fxsend;
729 	samplv1_port volume;
730 };
731 
732 
733 // chorus (fx)
734 
735 struct samplv1_cho
736 {
737 	samplv1_port wet;
738 	samplv1_port delay;
739 	samplv1_port feedb;
740 	samplv1_port rate;
741 	samplv1_port mod;
742 };
743 
744 
745 // flanger (fx)
746 
747 struct samplv1_fla
748 {
749 	samplv1_port wet;
750 	samplv1_port delay;
751 	samplv1_port feedb;
752 	samplv1_port daft;
753 };
754 
755 
756 // phaser (fx)
757 
758 struct samplv1_pha
759 {
760 	samplv1_port wet;
761 	samplv1_port rate;
762 	samplv1_port feedb;
763 	samplv1_port depth;
764 	samplv1_port daft;
765 };
766 
767 
768 // delay (fx)
769 
770 struct samplv1_del
771 {
772 	samplv1_port wet;
773 	samplv1_port delay;
774 	samplv1_port feedb;
775 	samplv1_port bpm;
776 };
777 
778 
779 // reverb
780 
781 struct samplv1_rev
782 {
783 	samplv1_port wet;
784 	samplv1_port room;
785 	samplv1_port damp;
786 	samplv1_port feedb;
787 	samplv1_port width;
788 };
789 
790 
791 // dynamic(compressor/limiter)
792 
793 struct samplv1_dyn
794 {
795 	samplv1_port compress;
796 	samplv1_port limiter;
797 };
798 
799 
800 // keyboard/note range
801 
802 struct samplv1_key
803 {
804 	samplv1_port low;
805 	samplv1_port high;
806 
is_notesamplv1_key807 	bool is_note(int key)
808 	{
809 		return (key >= int(*low) && int(*high) >= key);
810 	}
811 };
812 
813 
814 // glide (portamento)
815 
816 struct samplv1_glide
817 {
samplv1_glidesamplv1_glide818 	samplv1_glide(float& last) : m_last(last) { reset(); }
819 
resetsamplv1_glide820 	void reset( uint32_t frames = 0, float freq = 0.0f )
821 	{
822 		m_frames = frames;
823 
824 		if (m_frames > 0) {
825 			m_freq = m_last;
826 			m_step = (m_last - freq) / float(m_frames);
827 		} else {
828 			m_freq = freq;
829 			m_step = 0.0f;
830 		}
831 
832 		m_last = freq;
833 	}
834 
ticksamplv1_glide835 	float tick()
836 	{
837 		if (m_frames > 0) {
838 			m_freq -= m_step;
839 			--m_frames;
840 		}
841 
842 		return m_freq;
843 	}
844 
845 private:
846 
847 	uint32_t m_frames;
848 
849 	float  m_step;
850 	float  m_freq;
851 
852 	float& m_last;
853 };
854 
855 
856 // balance smoother (1 parameters)
857 
858 class samplv1_bal1 : public samplv1_ramp1
859 {
860 public:
861 
samplv1_bal1()862 	samplv1_bal1() : samplv1_ramp1(2) {}
863 
864 protected:
865 
evaluate(uint16_t i)866 	float evaluate(uint16_t i)
867 	{
868 		samplv1_ramp1::update();
869 
870 		const float wbal = 0.25f * M_PI
871 			* (1.0f + m_param1_v);
872 
873 		return M_SQRT2 * (i & 1 ? ::sinf(wbal) : ::cosf(wbal));
874 	}
875 };
876 
877 
878 // balance smoother (2 parameters)
879 
880 class samplv1_bal2 : public samplv1_ramp2
881 {
882 public:
883 
samplv1_bal2()884 	samplv1_bal2() : samplv1_ramp2(2) {}
885 
886 protected:
887 
evaluate(uint16_t i)888 	float evaluate(uint16_t i)
889 	{
890 		samplv1_ramp2::update();
891 
892 		const float wbal = 0.25f * M_PI
893 			* (1.0f + m_param1_v)
894 			* (1.0f + m_param2_v);
895 
896 		return M_SQRT2 * (i & 1 ? ::sinf(wbal) : ::cosf(wbal));
897 	}
898 };
899 
900 
901 // pressure smoother (3 parameters)
902 
903 class samplv1_pre : public samplv1_ramp3
904 {
905 public:
906 
samplv1_pre()907 	samplv1_pre() : samplv1_ramp3() {}
908 
909 protected:
910 
evaluate(uint16_t)911 	float evaluate(uint16_t)
912 	{
913 		samplv1_ramp3::update();
914 
915 		return m_param1_v * samplv1_max(m_param2_v, m_param3_v);
916 	}
917 };
918 
919 
920 // common phasor (LFO sync)
921 
922 class samplv1_phasor
923 {
924 public:
925 
samplv1_phasor(uint32_t nsize=1024)926 	samplv1_phasor(uint32_t nsize = 1024)
927 		: m_nsize(nsize), m_nframes(0) {}
928 
process(uint32_t nframes)929 	void process(uint32_t nframes)
930 	{
931 		m_nframes += nframes;
932 		while (m_nframes >= m_nsize)
933 			m_nframes -= m_nsize;
934 	}
935 
pshift() const936 	float pshift() const
937 		{ return float(m_nframes) / float(m_nsize); }
938 
939 private:
940 
941 	uint32_t m_nsize;
942 	uint32_t m_nframes;
943 };
944 
945 
946 // forward decl.
947 
948 class samplv1_impl;
949 
950 
951 // voice
952 
953 struct samplv1_voice : public samplv1_list<samplv1_voice>
954 {
955 	samplv1_voice(samplv1_impl *pImpl);
956 
957 	int note;									// voice note
958 
959 	float vel;									// key velocity
960 	float pre;									// key pressure/after-touch
961 
962 	samplv1_generator  gen1;					// generator
963 	samplv1_oscillator lfo1;					// low frequency oscilattor
964 
965 	float gen1_freq;							// frequency and phase
966 
967 	float lfo1_sample;
968 
969 	samplv1_filter1 dcf11, dcf12;				// filters
970 	samplv1_filter2 dcf13, dcf14;
971 	samplv1_filter3 dcf15, dcf16;
972 	samplv1_formant dcf17, dcf18;
973 
974 	samplv1_env::State dca1_env;				// envelope states
975 	samplv1_env::State dcf1_env;
976 	samplv1_env::State lfo1_env;
977 
978 	samplv1_glide gen1_glide;					// glides (portamento)
979 
980 	samplv1_pre dca1_pre;
981 
982 	float out1_panning;
983 	float out1_volume;
984 
985 	samplv1_bal1  out1_pan;						// output panning
986 	samplv1_ramp1 out1_vol;						// output volume
987 
988 	bool sustain;
989 };
990 
991 
992 // MIDI input asynchronous status notification
993 
994 class samplv1_midi_in : public samplv1_sched
995 {
996 public:
997 
samplv1_midi_in(samplv1 * pSampl)998 	samplv1_midi_in (samplv1 *pSampl)
999 		: samplv1_sched(pSampl, MidiIn),
1000 			m_enabled(false), m_count(0) {}
1001 
schedule_event()1002 	void schedule_event()
1003 		{ if (m_enabled && ++m_count < 2) schedule(-1); }
schedule_note(int key,int vel)1004 	void schedule_note(int key, int vel)
1005 		{ if (m_enabled) schedule((vel << 7) | key); }
1006 
process(int)1007 	void process(int) {}
1008 
enabled(bool on)1009 	void enabled(bool on)
1010 		{ m_enabled = on; m_count = 0; }
1011 
count()1012 	uint32_t count()
1013 	{
1014 		const uint32_t ret = m_count;
1015 		m_count = 0;
1016 		return ret;
1017 	}
1018 
1019 private:
1020 
1021 	bool     m_enabled;
1022 	uint32_t m_count;
1023 };
1024 
1025 
1026 // micro-tuning/instance implementation
1027 
1028 class samplv1_tun
1029 {
1030 public:
1031 
samplv1_tun()1032 	samplv1_tun() : enabled(false), refPitch(440.0f), refNote(69) {}
1033 
1034 	bool    enabled;
1035 	float   refPitch;
1036 	int     refNote;
1037 	QString scaleFile;
1038 	QString keyMapFile;
1039 };
1040 
1041 
1042 // polyphonic sampler implementation
1043 
1044 class samplv1_impl
1045 {
1046 public:
1047 
1048 	samplv1_impl(samplv1 *pSampl, uint16_t nchannels, float srate);
1049 
1050 	~samplv1_impl();
1051 
1052 	void setChannels(uint16_t nchannels);
1053 	uint16_t channels() const;
1054 
1055 	void setSampleRate(float srate);
1056 	float sampleRate() const;
1057 
1058 	void setSampleFile(const char *pszSampleFile, uint16_t otabs);
1059 	const char *sampleFile() const;
1060 	uint16_t octaves() const;
1061 
1062 	void setBufferSize(uint32_t nsize);
1063 	uint32_t bufferSize() const;
1064 
1065 	void setTempo(float bpm);
1066 	float tempo() const;
1067 
1068 	void setParamPort(samplv1::ParamIndex index, float *pfParam);
1069 	samplv1_port *paramPort(samplv1::ParamIndex index);
1070 
1071 	void setParamValue(samplv1::ParamIndex index, float fValue);
1072 	float paramValue(samplv1::ParamIndex index);
1073 
1074 	void updateEnvTimes();
1075 
1076 	samplv1_controls *controls();
1077 	samplv1_programs *programs();
1078 
1079 	void setTuningEnabled(bool enabled);
1080 	bool isTuningEnabled() const;
1081 
1082 	void setTuningRefPitch(float refPitch);
1083 	float tuningRefPitch() const;
1084 
1085 	void setTuningRefNote(int refNote);
1086 	int tuningRefNote() const;
1087 
1088 	void setTuningScaleFile(const char *pszScaleFile);
1089 	const char *tuningScaleFile() const;
1090 
1091 	void setTuningKeyMapFile(const char *pszKeyMapFile);
1092 	const char *tuningKeyMapFile() const;
1093 
1094 	void resetTuning();
1095 
1096 	void process_midi(uint8_t *data, uint32_t size);
1097 	void process(float **ins, float **outs, uint32_t nframes);
1098 
1099 	void stabilize();
1100 	void reset();
1101 
1102 	void sampleReverseTest();
1103 	void sampleReverseSync();
1104 
1105 	void sampleOffsetTest();
1106 	void sampleOffsetSync();
1107 	void sampleOffsetRangeSync();
1108 
1109 	void sampleLoopTest();
1110 	void sampleLoopSync();
1111 	void sampleLoopRangeSync();
1112 
1113 	void midiInEnabled(bool on);
1114 	uint32_t midiInCount();
1115 
1116 	void directNoteOn(int note, int vel);
1117 
1118 	bool running(bool on);
1119 
1120 	samplv1_sample  gen1_sample;
1121 	samplv1_wave_lf lfo1_wave;
1122 
1123 	float gen1_last;
1124 
1125 	samplv1_formant::Impl dcf1_formant;
1126 
1127 protected:
1128 
1129 	void allSoundOff();
1130 	void allControllersOff();
1131 	void allNotesOff();
1132 	void allSustainOff();
1133 	void allSustainOn();
1134 
get_bpm(float bpm) const1135 	float get_bpm ( float bpm ) const
1136 		{ return (bpm > 0.0f ? bpm : m_bpm); }
1137 
alloc_voice()1138 	samplv1_voice *alloc_voice ()
1139 	{
1140 		samplv1_voice *pv = m_free_list.next();
1141 		if (pv) {
1142 			m_free_list.remove(pv);
1143 			m_play_list.append(pv);
1144 			++m_nvoices;
1145 		}
1146 		return pv;
1147 	}
1148 
free_voice(samplv1_voice * pv)1149 	void free_voice ( samplv1_voice *pv )
1150 	{
1151 		if (m_lfo1.psync == pv)
1152 			m_lfo1.psync = nullptr;
1153 
1154 		m_play_list.remove(pv);
1155 		m_free_list.append(pv);
1156 		--m_nvoices;
1157 	}
1158 
1159 	void alloc_sfxs(uint32_t nsize);
1160 
1161 private:
1162 
1163 	samplv1_config   m_config;
1164 	samplv1_controls m_controls;
1165 	samplv1_programs m_programs;
1166 	samplv1_midi_in  m_midi_in;
1167 	samplv1_tun      m_tun;
1168 
1169 	uint16_t m_nchannels;
1170 	float    m_srate;
1171 	float    m_bpm;
1172 
1173 	float    m_freqs[MAX_NOTES];
1174 
1175 	samplv1_ctl m_ctl1;
1176 
1177 	samplv1_gen m_gen1;
1178 	samplv1_dcf m_dcf1;
1179 	samplv1_lfo m_lfo1;
1180 	samplv1_dca m_dca1;
1181 	samplv1_out m_out1;
1182 
1183 	samplv1_def m_def;
1184 
1185 	samplv1_cho m_cho;
1186 	samplv1_fla m_fla;
1187 	samplv1_pha m_pha;
1188 	samplv1_del m_del;
1189 	samplv1_rev m_rev;
1190 	samplv1_dyn m_dyn;
1191 
1192 	samplv1_key m_key;
1193 
1194 	samplv1_voice **m_voices;
1195 	samplv1_voice  *m_notes[MAX_NOTES];
1196 
1197 	samplv1_list<samplv1_voice> m_free_list;
1198 	samplv1_list<samplv1_voice> m_play_list;
1199 
1200 	samplv1_ramp1 m_wid1;
1201 	samplv1_bal2  m_pan1;
1202 	samplv1_ramp3 m_vol1;
1203 
1204 	float  **m_sfxs;
1205 	uint32_t m_nsize;
1206 
1207 	samplv1_fx_chorus   m_chorus;
1208 	samplv1_fx_flanger *m_flanger;
1209 	samplv1_fx_phaser  *m_phaser;
1210 	samplv1_fx_delay   *m_delay;
1211 	samplv1_fx_comp    *m_comp;
1212 
1213 	samplv1_reverb m_reverb;
1214 
1215 	// process direct note on/off...
1216 	volatile uint16_t m_direct_note;
1217 
1218 	struct direct_note {
1219 		uint8_t status, note, vel;
1220 	} m_direct_notes[MAX_DIRECT_NOTES];
1221 
1222 	volatile int  m_nvoices;
1223 
1224 	volatile bool m_running;
1225 };
1226 
1227 
1228 // voice constructor
1229 
samplv1_voice(samplv1_impl * pImpl)1230 samplv1_voice::samplv1_voice ( samplv1_impl *pImpl ) :
1231 	note(-1),
1232 	vel(0.0f),
1233 	pre(0.0f),
1234 	gen1(&pImpl->gen1_sample),
1235 	lfo1(&pImpl->lfo1_wave),
1236 	gen1_freq(0.0f),
1237 	lfo1_sample(0.0f),
1238 	dcf17(&pImpl->dcf1_formant),
1239 	dcf18(&pImpl->dcf1_formant),
1240 	gen1_glide(pImpl->gen1_last),
1241 	out1_volume(1.0f),
1242 	out1_panning(0.0f),
1243 	sustain(false)
1244 {
1245 }
1246 
1247 
1248 // engine constructor
1249 
samplv1_impl(samplv1 * pSampl,uint16_t nchannels,float srate)1250 samplv1_impl::samplv1_impl (
1251 	samplv1 *pSampl, uint16_t nchannels, float srate )
1252 		: gen1_sample(srate), m_controls(pSampl), m_programs(pSampl),
1253 			m_midi_in(pSampl), m_bpm(180.0f), m_gen1(pSampl),
1254 			m_nvoices(0), m_running(false)
1255 {
1256 	// null sample.
1257 	m_gen1.sample0 = 0.0f;
1258 
1259 	// max env. stage length (default)
1260 	m_gen1.envtime0 = 0.0001f * MAX_ENV_MSECS;
1261 
1262 	// glide note.
1263 	gen1_last = 0.0f;
1264 
1265 	// allocate voice pool.
1266 	m_voices = new samplv1_voice * [MAX_VOICES];
1267 
1268 	for (int i = 0; i < MAX_VOICES; ++i) {
1269 		m_voices[i] = new samplv1_voice(this);
1270 		m_free_list.append(m_voices[i]);
1271 	}
1272 
1273 	for (int note = 0; note < MAX_NOTES; ++note)
1274 		m_notes[note] = nullptr;
1275 
1276 	// local buffers none yet
1277 	m_sfxs = nullptr;
1278 	m_nsize = 0;
1279 
1280 	// flangers none yet
1281 	m_flanger = nullptr;
1282 
1283 	// phasers none yet
1284 	m_phaser = nullptr;
1285 
1286 	// delays none yet
1287 	m_delay = nullptr;
1288 
1289 	// compressors none yet
1290 	m_comp = nullptr;
1291 
1292 	// Pitch-shifting support...
1293 	samplv1_pshifter::setDefaultType(
1294 		samplv1_pshifter::Type(m_config.iPitchShiftType));
1295 
1296 	// Micro-tuning support, if any...
1297 	resetTuning();
1298 
1299 	// load controllers & programs database...
1300 	m_config.loadControls(&m_controls);
1301 	m_config.loadPrograms(&m_programs);
1302 
1303 	// number of channels
1304 	setChannels(nchannels);
1305 
1306 	// set default sample rate
1307 	setSampleRate(srate);
1308 
1309 	// reset all voices
1310 	allControllersOff();
1311 	allNotesOff();
1312 
1313 	running(true);
1314 }
1315 
1316 
1317 // destructor
1318 
~samplv1_impl(void)1319 samplv1_impl::~samplv1_impl (void)
1320 {
1321 #if 0
1322 	// DO NOT save programs database here:
1323 	// prevent multi-instance clash...
1324 	m_config.savePrograms(&m_programs);
1325 #endif
1326 
1327 	// deallocate sample filenames
1328 	setSampleFile(nullptr, 0);
1329 
1330 	// deallocate voice pool.
1331 	for (int i = 0; i < MAX_VOICES; ++i)
1332 		delete m_voices[i];
1333 
1334 	delete [] m_voices;
1335 
1336 	// deallocate local buffers
1337 	alloc_sfxs(0);
1338 
1339 	// deallocate channels
1340 	setChannels(0);
1341 }
1342 
1343 
setChannels(uint16_t nchannels)1344 void samplv1_impl::setChannels ( uint16_t nchannels )
1345 {
1346 	m_nchannels = nchannels;
1347 
1348 	// deallocate flangers
1349 	if (m_flanger) {
1350 		delete [] m_flanger;
1351 		m_flanger = nullptr;
1352 	}
1353 
1354 	// deallocate phasers
1355 	if (m_phaser) {
1356 		delete [] m_phaser;
1357 		m_phaser = nullptr;
1358 	}
1359 
1360 	// deallocate delays
1361 	if (m_delay) {
1362 		delete [] m_delay;
1363 		m_delay = nullptr;
1364 	}
1365 
1366 	// deallocate compressors
1367 	if (m_comp) {
1368 		delete [] m_comp;
1369 		m_comp = nullptr;
1370 	}
1371 }
1372 
1373 
channels(void) const1374 uint16_t samplv1_impl::channels (void) const
1375 {
1376 	return m_nchannels;
1377 }
1378 
1379 
setSampleRate(float srate)1380 void samplv1_impl::setSampleRate ( float srate )
1381 {
1382 	// set internal sample rate
1383 	m_srate = srate;
1384 
1385 	// update waves sample rate
1386 	gen1_sample.setSampleRate(m_srate);
1387 	lfo1_wave.setSampleRate(m_srate);
1388 
1389 	updateEnvTimes();
1390 
1391 	dcf1_formant.setSampleRate(m_srate);
1392 }
1393 
1394 
sampleRate(void) const1395 float samplv1_impl::sampleRate (void) const
1396 {
1397 	return m_srate;
1398 }
1399 
1400 
setBufferSize(uint32_t nsize)1401 void samplv1_impl::setBufferSize ( uint32_t nsize )
1402 {
1403 	// set nominal buffer size
1404 	if (m_nsize < nsize) alloc_sfxs(nsize);
1405 }
1406 
1407 
bufferSize(void) const1408 uint32_t samplv1_impl::bufferSize (void) const
1409 {
1410 	return m_nsize;
1411 }
1412 
1413 
setTempo(float bpm)1414 void samplv1_impl::setTempo ( float bpm )
1415 {
1416 	// set nominal tempo (BPM)
1417 	m_bpm = bpm;
1418 }
1419 
1420 
tempo(void) const1421 float samplv1_impl::tempo (void) const
1422 {
1423 	return m_bpm;
1424 }
1425 
1426 
1427 // allocate local buffers
alloc_sfxs(uint32_t nsize)1428 void samplv1_impl::alloc_sfxs ( uint32_t nsize )
1429 {
1430 	if (m_sfxs) {
1431 		for (uint16_t k = 0; k < m_nchannels; ++k)
1432 			delete [] m_sfxs[k];
1433 		delete [] m_sfxs;
1434 		m_sfxs = nullptr;
1435 		m_nsize = 0;
1436 	}
1437 
1438 	if (m_nsize < nsize) {
1439 		m_nsize = nsize;
1440 		m_sfxs = new float * [m_nchannels];
1441 		for (uint16_t k = 0; k < m_nchannels; ++k)
1442 			m_sfxs[k] = new float [m_nsize];
1443 	}
1444 }
1445 
1446 
updateEnvTimes(void)1447 void samplv1_impl::updateEnvTimes (void)
1448 {
1449 	// update envelope range times in frames
1450 	const float srate_ms = 0.001f * m_srate;
1451 
1452 	float envtime_msecs = 10000.0f * m_gen1.envtime0;
1453 	if (envtime_msecs < MIN_ENV_MSECS) {
1454 		const uint32_t envtime_frames
1455 			= (gen1_sample.offsetEnd() - gen1_sample.offsetStart()) >> 1;
1456 		envtime_msecs = envtime_frames / srate_ms;
1457 	}
1458 	if (envtime_msecs < MIN_ENV_MSECS)
1459 		envtime_msecs = MIN_ENV_MSECS * 4.0f;
1460 
1461 	const uint32_t min_frames1 = uint32_t(srate_ms * MIN_ENV_MSECS);
1462 	const uint32_t min_frames2 = (min_frames1 << 2);
1463 	const uint32_t max_frames  = uint32_t(srate_ms * envtime_msecs);
1464 
1465 	m_dcf1.env.min_frames1 = min_frames1;
1466 	m_dcf1.env.min_frames2 = min_frames2;
1467 	m_dcf1.env.max_frames  = max_frames;
1468 
1469 	m_lfo1.env.min_frames1 = min_frames1;
1470 	m_lfo1.env.min_frames2 = min_frames2;
1471 	m_lfo1.env.max_frames  = max_frames;
1472 
1473 	m_dca1.env.min_frames1 = min_frames1;
1474 	m_dca1.env.min_frames2 = min_frames2;
1475 	m_dca1.env.max_frames  = max_frames;
1476 }
1477 
1478 
setSampleFile(const char * pszSampleFile,uint16_t otabs)1479 void samplv1_impl::setSampleFile ( const char *pszSampleFile, uint16_t otabs )
1480 {
1481 	reset();
1482 
1483 	if (pszSampleFile) {
1484 		m_gen1.sample0 = *m_gen1.sample;
1485 		gen1_sample.open(pszSampleFile, samplv1_freq(m_gen1.sample0), otabs);
1486 	} else {
1487 		gen1_sample.close();
1488 	}
1489 
1490 	updateEnvTimes();
1491 }
1492 
1493 
sampleFile(void) const1494 const char *samplv1_impl::sampleFile (void) const
1495 {
1496 	return gen1_sample.filename();
1497 }
1498 
1499 
octaves(void) const1500 uint16_t samplv1_impl::octaves (void) const
1501 {
1502 	return gen1_sample.otabs();
1503 }
1504 
1505 
setParamPort(samplv1::ParamIndex index,float * pfParam)1506 void samplv1_impl::setParamPort ( samplv1::ParamIndex index, float *pfParam )
1507 {
1508 	static float s_fDummy = 0.0f;
1509 
1510 	if (pfParam == nullptr)
1511 		pfParam = &s_fDummy;
1512 
1513 	samplv1_port *pParamPort = paramPort(index);
1514 	if (pParamPort)
1515 		pParamPort->set_port(pfParam);
1516 
1517 	// check null connections.
1518 	if (pfParam == &s_fDummy)
1519 		return;
1520 
1521 	// reset ramps after port (re)connection.
1522 	switch (index) {
1523 	case samplv1::OUT1_VOLUME:
1524 	case samplv1::DCA1_VOLUME:
1525 		m_vol1.reset(
1526 			m_out1.volume.value_ptr(),
1527 			m_dca1.volume.value_ptr(),
1528 			&m_ctl1.volume);
1529 		break;
1530 	case samplv1::OUT1_WIDTH:
1531 		m_wid1.reset(
1532 			m_out1.width.value_ptr());
1533 		break;
1534 	case samplv1::OUT1_PANNING:
1535 		m_pan1.reset(
1536 			m_out1.panning.value_ptr(),
1537 			&m_ctl1.panning);
1538 		break;
1539 	default:
1540 		break;
1541 	}
1542 }
1543 
1544 
paramPort(samplv1::ParamIndex index)1545 samplv1_port *samplv1_impl::paramPort ( samplv1::ParamIndex index )
1546 {
1547 	samplv1_port *pParamPort = nullptr;
1548 
1549 	switch (index) {
1550 	case samplv1::GEN1_SAMPLE:    pParamPort = &m_gen1.sample;      break;
1551 	case samplv1::GEN1_REVERSE:   pParamPort = &m_gen1.reverse;     break;
1552 	case samplv1::GEN1_OFFSET:    pParamPort = &m_gen1.offset;      break;
1553 	case samplv1::GEN1_OFFSET_1:  pParamPort = &m_gen1.offset_1;    break;
1554 	case samplv1::GEN1_OFFSET_2:  pParamPort = &m_gen1.offset_2;    break;
1555 	case samplv1::GEN1_LOOP:      pParamPort = &m_gen1.loop;        break;
1556 	case samplv1::GEN1_LOOP_1:    pParamPort = &m_gen1.loop_1;      break;
1557 	case samplv1::GEN1_LOOP_2:    pParamPort = &m_gen1.loop_2;      break;
1558 	case samplv1::GEN1_OCTAVE:    pParamPort = &m_gen1.octave;      break;
1559 	case samplv1::GEN1_TUNING:    pParamPort = &m_gen1.tuning;      break;
1560 	case samplv1::GEN1_GLIDE:     pParamPort = &m_gen1.glide;       break;
1561 	case samplv1::GEN1_ENVTIME:   pParamPort = &m_gen1.envtime;     break;
1562 	case samplv1::DCF1_ENABLED:   pParamPort = &m_dcf1.enabled;     break;
1563 	case samplv1::DCF1_CUTOFF:    pParamPort = &m_dcf1.cutoff;      break;
1564 	case samplv1::DCF1_RESO:      pParamPort = &m_dcf1.reso;        break;
1565 	case samplv1::DCF1_TYPE:      pParamPort = &m_dcf1.type;        break;
1566 	case samplv1::DCF1_SLOPE:     pParamPort = &m_dcf1.slope;       break;
1567 	case samplv1::DCF1_ENVELOPE:  pParamPort = &m_dcf1.envelope;    break;
1568 	case samplv1::DCF1_ATTACK:    pParamPort = &m_dcf1.env.attack;  break;
1569 	case samplv1::DCF1_DECAY:     pParamPort = &m_dcf1.env.decay;   break;
1570 	case samplv1::DCF1_SUSTAIN:   pParamPort = &m_dcf1.env.sustain; break;
1571 	case samplv1::DCF1_RELEASE:   pParamPort = &m_dcf1.env.release; break;
1572 	case samplv1::LFO1_ENABLED:   pParamPort = &m_lfo1.enabled;     break;
1573 	case samplv1::LFO1_SHAPE:     pParamPort = &m_lfo1.shape;       break;
1574 	case samplv1::LFO1_WIDTH:     pParamPort = &m_lfo1.width;       break;
1575 	case samplv1::LFO1_BPM:       pParamPort = &m_lfo1.bpm;         break;
1576 	case samplv1::LFO1_RATE:      pParamPort = &m_lfo1.rate;        break;
1577 	case samplv1::LFO1_SYNC:      pParamPort = &m_lfo1.sync;        break;
1578 	case samplv1::LFO1_SWEEP:     pParamPort = &m_lfo1.sweep;       break;
1579 	case samplv1::LFO1_PITCH:     pParamPort = &m_lfo1.pitch;       break;
1580 	case samplv1::LFO1_CUTOFF:    pParamPort = &m_lfo1.cutoff;      break;
1581 	case samplv1::LFO1_RESO:      pParamPort = &m_lfo1.reso;        break;
1582 	case samplv1::LFO1_PANNING:   pParamPort = &m_lfo1.panning;     break;
1583 	case samplv1::LFO1_VOLUME:    pParamPort = &m_lfo1.volume;      break;
1584 	case samplv1::LFO1_ATTACK:    pParamPort = &m_lfo1.env.attack;  break;
1585 	case samplv1::LFO1_DECAY:     pParamPort = &m_lfo1.env.decay;   break;
1586 	case samplv1::LFO1_SUSTAIN:   pParamPort = &m_lfo1.env.sustain; break;
1587 	case samplv1::LFO1_RELEASE:   pParamPort = &m_lfo1.env.release; break;
1588 	case samplv1::DCA1_ENABLED:   pParamPort = &m_dca1.enabled;     break;
1589 	case samplv1::DCA1_VOLUME:    pParamPort = &m_dca1.volume;      break;
1590 	case samplv1::DCA1_ATTACK:    pParamPort = &m_dca1.env.attack;  break;
1591 	case samplv1::DCA1_DECAY:     pParamPort = &m_dca1.env.decay;   break;
1592 	case samplv1::DCA1_SUSTAIN:   pParamPort = &m_dca1.env.sustain; break;
1593 	case samplv1::DCA1_RELEASE:   pParamPort = &m_dca1.env.release; break;
1594 	case samplv1::OUT1_WIDTH:     pParamPort = &m_out1.width;       break;
1595 	case samplv1::OUT1_PANNING:   pParamPort = &m_out1.panning;     break;
1596 	case samplv1::OUT1_FXSEND:    pParamPort = &m_out1.fxsend;      break;
1597 	case samplv1::OUT1_VOLUME:    pParamPort = &m_out1.volume;      break;
1598 	case samplv1::DEF1_PITCHBEND: pParamPort = &m_def.pitchbend;    break;
1599 	case samplv1::DEF1_MODWHEEL:  pParamPort = &m_def.modwheel;     break;
1600 	case samplv1::DEF1_PRESSURE:  pParamPort = &m_def.pressure;     break;
1601 	case samplv1::DEF1_VELOCITY:  pParamPort = &m_def.velocity;     break;
1602 	case samplv1::DEF1_CHANNEL:   pParamPort = &m_def.channel;      break;
1603 	case samplv1::DEF1_MONO:      pParamPort = &m_def.mono;         break;
1604 	case samplv1::CHO1_WET:       pParamPort = &m_cho.wet;          break;
1605 	case samplv1::CHO1_DELAY:     pParamPort = &m_cho.delay;        break;
1606 	case samplv1::CHO1_FEEDB:     pParamPort = &m_cho.feedb;        break;
1607 	case samplv1::CHO1_RATE:      pParamPort = &m_cho.rate;         break;
1608 	case samplv1::CHO1_MOD:       pParamPort = &m_cho.mod;          break;
1609 	case samplv1::FLA1_WET:       pParamPort = &m_fla.wet;          break;
1610 	case samplv1::FLA1_DELAY:     pParamPort = &m_fla.delay;        break;
1611 	case samplv1::FLA1_FEEDB:     pParamPort = &m_fla.feedb;        break;
1612 	case samplv1::FLA1_DAFT:      pParamPort = &m_fla.daft;         break;
1613 	case samplv1::PHA1_WET:       pParamPort = &m_pha.wet;          break;
1614 	case samplv1::PHA1_RATE:      pParamPort = &m_pha.rate;         break;
1615 	case samplv1::PHA1_FEEDB:     pParamPort = &m_pha.feedb;        break;
1616 	case samplv1::PHA1_DEPTH:     pParamPort = &m_pha.depth;        break;
1617 	case samplv1::PHA1_DAFT:      pParamPort = &m_pha.daft;         break;
1618 	case samplv1::DEL1_WET:       pParamPort = &m_del.wet;          break;
1619 	case samplv1::DEL1_DELAY:     pParamPort = &m_del.delay;        break;
1620 	case samplv1::DEL1_FEEDB:     pParamPort = &m_del.feedb;        break;
1621 	case samplv1::DEL1_BPM:       pParamPort = &m_del.bpm;          break;
1622 	case samplv1::REV1_WET:       pParamPort = &m_rev.wet;          break;
1623 	case samplv1::REV1_ROOM:      pParamPort = &m_rev.room;         break;
1624 	case samplv1::REV1_DAMP:      pParamPort = &m_rev.damp;         break;
1625 	case samplv1::REV1_FEEDB:     pParamPort = &m_rev.feedb;        break;
1626 	case samplv1::REV1_WIDTH:     pParamPort = &m_rev.width;        break;
1627 	case samplv1::DYN1_COMPRESS:  pParamPort = &m_dyn.compress;     break;
1628 	case samplv1::DYN1_LIMITER:   pParamPort = &m_dyn.limiter;      break;
1629 	case samplv1::KEY1_LOW:       pParamPort = &m_key.low;          break;
1630 	case samplv1::KEY1_HIGH:      pParamPort = &m_key.high;         break;
1631 	default: break;
1632 	}
1633 
1634 	return pParamPort;
1635 }
1636 
1637 
setParamValue(samplv1::ParamIndex index,float fValue)1638 void samplv1_impl::setParamValue ( samplv1::ParamIndex index, float fValue )
1639 {
1640 	samplv1_port *pParamPort = paramPort(index);
1641 	if (pParamPort)
1642 		pParamPort->set_value(fValue);
1643 }
1644 
1645 
paramValue(samplv1::ParamIndex index)1646 float samplv1_impl::paramValue ( samplv1::ParamIndex index )
1647 {
1648 	samplv1_port *pParamPort = paramPort(index);
1649 	return (pParamPort ? pParamPort->value() : 0.0f);
1650 }
1651 
1652 
1653 // handle midi input
1654 
process_midi(uint8_t * data,uint32_t size)1655 void samplv1_impl::process_midi ( uint8_t *data, uint32_t size )
1656 {
1657 	for (uint32_t i = 0; i < size; ++i) {
1658 
1659 		// channel status
1660 		const int channel = (data[i] & 0x0f) + 1;
1661 		const int status  = (data[i] & 0xf0);
1662 
1663 		// channel filter
1664 		const int ch = int(*m_def.channel);
1665 		const int on = (ch == 0 || ch == channel);
1666 
1667 		// all system common/real-time ignored
1668 		if (status == 0xf0)
1669 			continue;
1670 
1671 		// check data size (#1)
1672 		if (++i >= size)
1673 			break;
1674 
1675 		const int key = (data[i] & 0x7f);
1676 
1677 		// program change
1678 		if (status == 0xc0) {
1679 			if (on) m_programs.prog_change(key);
1680 			continue;
1681 		}
1682 
1683 		// channel aftertouch
1684 		if (status == 0xd0) {
1685 			if (on) m_ctl1.pressure = float(key) / 127.0f;
1686 			continue;
1687 		}
1688 
1689 		// check data size (#2)
1690 		if (++i >= size)
1691 			break;
1692 
1693 		// channel value
1694 		const int value = (data[i] & 0x7f);
1695 
1696 		// channel/controller filter
1697 		if (!on) {
1698 			if (status == 0xb0)
1699 				m_controls.process_enqueue(channel, key, value);
1700 			continue;
1701 		}
1702 
1703 		// note on
1704 		if (status == 0x90 && value > 0) {
1705 			if (!m_key.is_note(key))
1706 				continue;
1707 			samplv1_voice *pv;
1708 			// mono voice modes
1709 			if (*m_def.mono > 0.0f) {
1710 				int n = 0;
1711 				for (pv = m_play_list.next(); pv; pv = pv->next()) {
1712 					if (pv->note >= 0
1713 						&& pv->dca1_env.stage != samplv1_env::Release) {
1714 						m_dcf1.env.note_off_fast(&pv->dcf1_env);
1715 						m_lfo1.env.note_off_fast(&pv->lfo1_env);
1716 						m_dca1.env.note_off_fast(&pv->dca1_env);
1717 						if (++n > 1) { // there shall be only one
1718 							m_notes[pv->note] = nullptr;
1719 							pv->note = -1;
1720 						}
1721 					}
1722 				}
1723 			}
1724 			pv = m_notes[key];
1725 			if (pv && pv->note >= 0/* && !m_ctl1.sustain*/) {
1726 				// retrigger fast release
1727 				m_dcf1.env.note_off_fast(&pv->dcf1_env);
1728 				m_lfo1.env.note_off_fast(&pv->lfo1_env);
1729 				m_dca1.env.note_off_fast(&pv->dca1_env);
1730 				m_notes[pv->note] = nullptr;
1731 				pv->note = -1;
1732 			}
1733 			// find free voice
1734 			pv = alloc_voice();
1735 			if (pv) {
1736 				// waveform
1737 				pv->note = key;
1738 				// velocity
1739 				const float vel = float(value) / 127.0f;
1740 				// quadratic velocity law
1741 				pv->vel = samplv1_velocity(vel * vel, *m_def.velocity);
1742 				// pressure/after-touch
1743 				pv->pre = 0.0f;
1744 				pv->dca1_pre.reset(
1745 					m_def.pressure.value_ptr(),
1746 					&m_ctl1.pressure, &pv->pre);
1747 				// frequencies
1748 				const float gen1_tuning
1749 					= *m_gen1.octave * OCTAVE_SCALE
1750 					+ *m_gen1.tuning * TUNING_SCALE;
1751 				pv->gen1_freq = m_freqs[key] * samplv1_freq2(gen1_tuning);
1752 				// generator
1753 				pv->gen1.start(pv->gen1_freq);
1754 				// filters
1755 				const int dcf1_type = int(*m_dcf1.type);
1756 				pv->dcf11.reset(samplv1_filter1::Type(dcf1_type));
1757 				pv->dcf12.reset(samplv1_filter1::Type(dcf1_type));
1758 				pv->dcf13.reset(samplv1_filter2::Type(dcf1_type));
1759 				pv->dcf14.reset(samplv1_filter2::Type(dcf1_type));
1760 				pv->dcf15.reset(samplv1_filter3::Type(dcf1_type));
1761 				pv->dcf16.reset(samplv1_filter3::Type(dcf1_type));
1762 				// formant filters
1763 				const float dcf1_cutoff = *m_dcf1.cutoff;
1764 				const float dcf1_reso = *m_dcf1.reso;
1765 				pv->dcf17.reset_filters(dcf1_cutoff, dcf1_reso);
1766 				pv->dcf18.reset_filters(dcf1_cutoff, dcf1_reso);
1767 				// envelopes
1768 				if (*m_dcf1.enabled > 0.0f)
1769 					m_dcf1.env.start(&pv->dcf1_env);
1770 				else
1771 					m_dcf1.env.idle(&pv->dcf1_env);
1772 				if (*m_lfo1.enabled > 0.0f)
1773 					m_lfo1.env.start(&pv->lfo1_env);
1774 				else
1775 					m_lfo1.env.idle(&pv->lfo1_env);
1776 				if (*m_dca1.enabled > 0.0f)
1777 					m_dca1.env.start(&pv->dca1_env);
1778 				else
1779 					m_dca1.env.idle(&pv->dca1_env);
1780 				// something about the loop
1781 				pv->gen1.setLoop(gen1_sample.isLoop());
1782 				// lfos
1783 				const float lfo1_pshift
1784 					= (m_lfo1.psync ? m_lfo1.psync->lfo1.pshift() : 0.0f);
1785 				pv->lfo1_sample = pv->lfo1.start(lfo1_pshift);
1786 				if (*m_lfo1.sync > 0.0f && m_lfo1.psync == nullptr)
1787 					m_lfo1.psync = pv;
1788 				// glides (portamentoa)
1789 				const float gen1_frames
1790 					= uint32_t(*m_gen1.glide * *m_gen1.glide * m_srate);
1791 				pv->gen1_glide.reset(gen1_frames, pv->gen1_freq);
1792 				// panning
1793 				pv->out1_panning = 0.0f;
1794 				pv->out1_pan.reset(&pv->out1_panning);
1795 				// volume
1796 				pv->out1_volume = 1.0f;
1797 				pv->out1_vol.reset(&pv->out1_volume);
1798 				// sustain
1799 				pv->sustain = false;
1800 				// allocated
1801 				m_notes[key] = pv;
1802 			}
1803 			m_midi_in.schedule_note(key, value);
1804 		}
1805 		// note off
1806 		else if (status == 0x80 || (status == 0x90 && value == 0)) {
1807 			if (!m_key.is_note(key))
1808 				continue;
1809 			samplv1_voice *pv = m_notes[key];
1810 			if (pv && pv->note >= 0) {
1811 				if (m_ctl1.sustain)
1812 					pv->sustain = true;
1813 				else
1814 				if (!pv->sustain) {
1815 					if (pv->dca1_env.stage != samplv1_env::Release) {
1816 						m_dca1.env.note_off(&pv->dca1_env);
1817 						m_dcf1.env.note_off(&pv->dcf1_env);
1818 						m_lfo1.env.note_off(&pv->lfo1_env);
1819 					//	pv->gen1.setLoop(false);
1820 					}
1821 					m_notes[pv->note] = nullptr;
1822 					pv->note = -1;
1823 					// mono legato?
1824 					if (*m_def.mono > 0.0f) {
1825 						do pv = pv->prev();	while (pv && pv->note < 0);
1826 						if (pv && pv->note >= 0) {
1827 							const bool legato = (*m_def.mono > 1.0f);
1828 							m_dcf1.env.restart(&pv->dcf1_env, legato);
1829 							m_lfo1.env.restart(&pv->lfo1_env, legato);
1830 							m_dca1.env.restart(&pv->dca1_env, legato);
1831 							pv->gen1.setLoop(*m_gen1.loop > 0.0f);
1832 							if (!legato) pv->gen1.start(pv->gen1_freq);
1833 							m_notes[pv->note] = pv;
1834 						}
1835 					}
1836 				}
1837 			}
1838 			m_midi_in.schedule_note(key, 0);
1839 		}
1840 		// key pressure/poly.aftertouch
1841 		else if (status == 0xa0) {
1842 			if (!m_key.is_note(key))
1843 				continue;
1844 			samplv1_voice *pv = m_notes[key];
1845 			if (pv && pv->note >= 0)
1846 				pv->pre = *m_def.pressure * float(value) / 127.0f;
1847 		}
1848 		// control change
1849 		else if (status == 0xb0) {
1850 		switch (key) {
1851 			case 0x00:
1852 				// bank-select MSB (cc#0)
1853 				m_programs.bank_select_msb(value);
1854 				break;
1855 			case 0x01:
1856 				// modulation wheel (cc#1)
1857 				m_ctl1.modwheel = *m_def.modwheel * float(value) / 127.0f;
1858 				break;
1859 			case 0x07:
1860 				// channel volume (cc#7)
1861 				m_ctl1.volume = float(value) / 127.0f;
1862 				break;
1863 			case 0x0a:
1864 				// channel panning (cc#10)
1865 				m_ctl1.panning = float(value - 64) / 64.0f;
1866 				break;
1867 			case 0x20:
1868 				// bank-select LSB (cc#32)
1869 				m_programs.bank_select_lsb(value);
1870 				break;
1871 			case 0x40:
1872 				// sustain/damper pedal (cc#64)
1873 				if (m_ctl1.sustain && value <  64)
1874 					allSustainOff();
1875 				m_ctl1.sustain = bool(value >= 64);
1876 				break;
1877 			case 0x42:
1878 				// sustenuto pedal (cc#66)
1879 				if (value < 64)
1880 					allSustainOff();
1881 				else
1882 					allSustainOn();
1883 				break;
1884 			case 0x78:
1885 				// all sound off (cc#120)
1886 				allSoundOff();
1887 				break;
1888 			case 0x79:
1889 				// all controllers off (cc#121)
1890 				allControllersOff();
1891 				break;
1892 			case 0x7b:
1893 				// all notes off (cc#123)
1894 				allNotesOff();
1895 				break;
1896 			}
1897 			// process controllers...
1898 			m_controls.process_enqueue(channel, key, value);
1899 		}
1900 		// pitch bend
1901 		else if (status == 0xe0) {
1902 			const float pitchbend = float(key + (value << 7) - 0x2000) / 8192.0f;
1903 			m_ctl1.pitchbend = samplv1_pow2f(*m_def.pitchbend * pitchbend);
1904 		}
1905 	}
1906 
1907 	// process pending controllers...
1908 	m_controls.process_dequeue();
1909 
1910 	// asynchronous event notification...
1911 	m_midi_in.schedule_event();
1912 }
1913 
1914 
1915 // all controllers off
1916 
allControllersOff(void)1917 void samplv1_impl::allControllersOff (void)
1918 {
1919 	m_ctl1.reset();
1920 }
1921 
1922 
1923 // all sound off
1924 
allSoundOff(void)1925 void samplv1_impl::allSoundOff (void)
1926 {
1927 	m_chorus.setSampleRate(m_srate);
1928 	m_chorus.reset();
1929 
1930 	for (uint16_t k = 0; k < m_nchannels; ++k) {
1931 		m_phaser[k].setSampleRate(m_srate);
1932 		m_delay[k].setSampleRate(m_srate);
1933 		m_comp[k].setSampleRate(m_srate);
1934 		m_flanger[k].reset();
1935 		m_phaser[k].reset();
1936 		m_delay[k].reset();
1937 		m_comp[k].reset();
1938 	}
1939 
1940 	m_reverb.setSampleRate(m_srate);
1941 	m_reverb.reset();
1942 }
1943 
1944 
1945 // all notes off
1946 
allNotesOff(void)1947 void samplv1_impl::allNotesOff (void)
1948 {
1949 	samplv1_voice *pv = m_play_list.next();
1950 	while (pv) {
1951 		if (pv->note >= 0)
1952 			m_notes[pv->note] = nullptr;
1953 		free_voice(pv);
1954 		pv = m_play_list.next();
1955 	}
1956 
1957 	gen1_last = 0.0f;
1958 
1959 	m_lfo1.psync = nullptr;
1960 
1961 	m_direct_note = 0;
1962 }
1963 
1964 
1965 // all sustained notes off
1966 
allSustainOff(void)1967 void samplv1_impl::allSustainOff (void)
1968 {
1969 	samplv1_voice *pv = m_play_list.next();
1970 	while (pv) {
1971 		if (pv->note >= 0 && pv->sustain) {
1972 			pv->sustain = false;
1973 			if (pv->dca1_env.stage != samplv1_env::Release) {
1974 				m_dca1.env.note_off(&pv->dca1_env);
1975 				m_dcf1.env.note_off(&pv->dcf1_env);
1976 				m_lfo1.env.note_off(&pv->lfo1_env);
1977 				pv->gen1.setLoop(false);
1978 				m_notes[pv->note] = nullptr;
1979 				pv->note = -1;
1980 			}
1981 		}
1982 		pv = pv->next();
1983 	}
1984 }
1985 
1986 
1987 // sustain all notes on (sustenuto)
1988 
allSustainOn(void)1989 void samplv1_impl::allSustainOn (void)
1990 {
1991 	samplv1_voice *pv = m_play_list.next();
1992 	while (pv) {
1993 		if (pv->note >= 0 && !pv->sustain)
1994 			pv->sustain = true;
1995 		pv = pv->next();
1996 	}
1997 }
1998 
1999 
2000 // direct note-on triggered on next cycle...
directNoteOn(int note,int vel)2001 void samplv1_impl::directNoteOn ( int note, int vel )
2002 {
2003 	if (vel > 0 && m_nvoices >= MAX_DIRECT_NOTES)
2004 		return;
2005 
2006 	const uint32_t i = m_direct_note;
2007 	if (i < MAX_DIRECT_NOTES) {
2008 		const int ch1 = int(*m_def.channel);
2009 		const int chan = (ch1 > 0 ? ch1 - 1 : 0) & 0x0f;
2010 		direct_note& data = m_direct_notes[i];
2011 		data.status = (vel > 0 ? 0x90 : 0x80) | chan;
2012 		data.note = note;
2013 		data.vel = vel;
2014 		++m_direct_note;
2015 	}
2016 }
2017 
2018 
2019 // controllers accessor
2020 
controls(void)2021 samplv1_controls *samplv1_impl::controls (void)
2022 {
2023 	return &m_controls;
2024 }
2025 
2026 
2027 // programs accessor
2028 
programs(void)2029 samplv1_programs *samplv1_impl::programs (void)
2030 {
2031 	return &m_programs;
2032 }
2033 
2034 
2035 // Micro-tuning support
2036 
setTuningEnabled(bool enabled)2037 void samplv1_impl::setTuningEnabled ( bool enabled )
2038 {
2039 	m_tun.enabled = enabled;
2040 }
2041 
isTuningEnabled(void) const2042 bool samplv1_impl::isTuningEnabled (void) const
2043 {
2044 	return m_tun.enabled;
2045 }
2046 
2047 
setTuningRefPitch(float refPitch)2048 void samplv1_impl::setTuningRefPitch ( float refPitch )
2049 {
2050 	m_tun.refPitch = refPitch;
2051 }
2052 
tuningRefPitch(void) const2053 float samplv1_impl::tuningRefPitch (void) const
2054 {
2055 	return m_tun.refPitch;
2056 }
2057 
2058 
setTuningRefNote(int refNote)2059 void samplv1_impl::setTuningRefNote ( int refNote )
2060 {
2061 	m_tun.refNote = refNote;
2062 }
2063 
tuningRefNote(void) const2064 int samplv1_impl::tuningRefNote (void) const
2065 {
2066 	return m_tun.refNote;
2067 }
2068 
2069 
setTuningScaleFile(const char * pszScaleFile)2070 void samplv1_impl::setTuningScaleFile ( const char *pszScaleFile )
2071 {
2072 	m_tun.scaleFile = QString::fromUtf8(pszScaleFile);
2073 }
2074 
tuningScaleFile(void) const2075 const char *samplv1_impl::tuningScaleFile (void) const
2076 {
2077 	return m_tun.scaleFile.toUtf8().constData();
2078 }
2079 
2080 
setTuningKeyMapFile(const char * pszKeyMapFile)2081 void samplv1_impl::setTuningKeyMapFile ( const char *pszKeyMapFile )
2082 {
2083 	m_tun.keyMapFile = QString::fromUtf8(pszKeyMapFile);
2084 }
2085 
tuningKeyMapFile(void) const2086 const char *samplv1_impl::tuningKeyMapFile (void) const
2087 {
2088 	return m_tun.keyMapFile.toUtf8().constData();
2089 }
2090 
2091 
resetTuning(void)2092 void samplv1_impl::resetTuning (void)
2093 {
2094 	if (m_tun.enabled) {
2095 		// Instance micro-tuning, possibly from Scala keymap and scale files...
2096 		samplv1_tuning tuning(
2097 			m_tun.refPitch,
2098 			m_tun.refNote);
2099 		if (m_tun.keyMapFile.isEmpty())
2100 		if (!m_tun.keyMapFile.isEmpty())
2101 			tuning.loadKeyMapFile(m_tun.keyMapFile);
2102 		if (!m_tun.scaleFile.isEmpty())
2103 			tuning.loadScaleFile(m_tun.scaleFile);
2104 		for (int note = 0; note < MAX_NOTES; ++note)
2105 			m_freqs[note] = tuning.noteToPitch(note);
2106 		// Done instance tuning.
2107 	}
2108 	else
2109 	if (m_config.bTuningEnabled) {
2110 		// Global/config micro-tuning, possibly from Scala keymap and scale files...
2111 		samplv1_tuning tuning(
2112 			m_config.fTuningRefPitch,
2113 			m_config.iTuningRefNote);
2114 		if (!m_config.sTuningKeyMapFile.isEmpty())
2115 			tuning.loadKeyMapFile(m_config.sTuningKeyMapFile);
2116 		if (!m_config.sTuningScaleFile.isEmpty())
2117 			tuning.loadScaleFile(m_config.sTuningScaleFile);
2118 		for (int note = 0; note < MAX_NOTES; ++note)
2119 			m_freqs[note] = tuning.noteToPitch(note);
2120 		// Done global/config tuning.
2121 	} else {
2122 		// Native/default tuning, 12-tone equal temperament western standard...
2123 		for (int note = 0; note < MAX_NOTES; ++note)
2124 			m_freqs[note] = samplv1_freq(note);
2125 		// Done native/default tuning.
2126 	}
2127 }
2128 
2129 
2130 // all stabilize
2131 
stabilize(void)2132 void samplv1_impl::stabilize (void)
2133 {
2134 	for (int i = 0; i < samplv1::NUM_PARAMS; ++i) {
2135 		samplv1_port *pParamPort = paramPort(samplv1::ParamIndex(i));
2136 		if (pParamPort)
2137 			pParamPort->tick(samplv1_port2::NSTEP);
2138 	}
2139 }
2140 
2141 
2142 // all reset clear
2143 
reset(void)2144 void samplv1_impl::reset (void)
2145 {
2146 	m_vol1.reset(
2147 		m_out1.volume.value_ptr(),
2148 		m_dca1.volume.value_ptr(),
2149 		&m_ctl1.volume);
2150 	m_pan1.reset(
2151 		m_out1.panning.value_ptr(),
2152 		&m_ctl1.panning);
2153 	m_wid1.reset(
2154 		m_out1.width.value_ptr());
2155 
2156 	// flangers
2157 	if (m_flanger == nullptr)
2158 		m_flanger = new samplv1_fx_flanger [m_nchannels];
2159 
2160 	// phasers
2161 	if (m_phaser == nullptr)
2162 		m_phaser = new samplv1_fx_phaser [m_nchannels];
2163 
2164 	// delays
2165 	if (m_delay == nullptr)
2166 		m_delay = new samplv1_fx_delay [m_nchannels];
2167 
2168 	// compressors
2169 	if (m_comp == nullptr)
2170 		m_comp = new samplv1_fx_comp [m_nchannels];
2171 
2172 	// reverbs
2173 	m_reverb.reset();
2174 
2175 	// controllers reset.
2176 	m_controls.reset();
2177 
2178 	allSoundOff();
2179 //	allControllersOff();
2180 	allNotesOff();
2181 }
2182 
2183 
2184 // MIDI input asynchronous status notification accessors
2185 
midiInEnabled(bool on)2186 void samplv1_impl::midiInEnabled ( bool on )
2187 {
2188 	m_midi_in.enabled(on);
2189 }
2190 
2191 
midiInCount(void)2192 uint32_t samplv1_impl::midiInCount (void)
2193 {
2194 	return m_midi_in.count();
2195 }
2196 
2197 
2198 // synthesize
2199 
process(float ** ins,float ** outs,uint32_t nframes)2200 void samplv1_impl::process ( float **ins, float **outs, uint32_t nframes )
2201 {
2202 	if (!m_running) return;
2203 
2204 	float *v_outs[m_nchannels];
2205 	float *v_sfxs[m_nchannels];
2206 
2207 	// FIXME: fx-send buffer reallocation... seriously?
2208 	if (m_nsize < nframes) alloc_sfxs(nframes);
2209 
2210 	uint16_t k;
2211 
2212 	for (k = 0; k < m_nchannels; ++k) {
2213 		::memset(m_sfxs[k], 0, nframes * sizeof(float));
2214 		::memcpy(outs[k], ins[k], nframes * sizeof(float));
2215 	}
2216 
2217 	// process direct note on/off...
2218 	while (m_direct_note > 0) {
2219 		const direct_note& data
2220 			= m_direct_notes[--m_direct_note];
2221 		process_midi((uint8_t *) &data, sizeof(data));
2222 	}
2223 
2224 	// channel indexes
2225 
2226 	const uint16_t k11 = 0;
2227 	const uint16_t k12 = (gen1_sample.channels() > 1 ? 1 : 0);
2228 
2229 	// controls
2230 
2231 	const bool lfo1_enabled = (*m_lfo1.enabled > 0.0f);
2232 
2233 	const float lfo1_freq = (lfo1_enabled
2234 		? get_bpm(*m_lfo1.bpm) / (60.01f - *m_lfo1.rate * 60.0f) : 0.0f);
2235 
2236 	const float modwheel1 = (lfo1_enabled
2237 		? m_ctl1.modwheel + PITCH_SCALE * *m_lfo1.pitch : 0.0f);
2238 
2239 	const bool dcf1_enabled = (*m_dcf1.enabled > 0.0f);
2240 
2241 	const float fxsend1 = *m_out1.fxsend * *m_out1.fxsend;
2242 
2243 	if (m_gen1.sample0 != *m_gen1.sample) {
2244 		m_gen1.sample0  = *m_gen1.sample;
2245 		gen1_sample.reset(samplv1_freq(m_gen1.sample0));
2246 	}
2247 
2248 	if (m_gen1.envtime0 != *m_gen1.envtime) {
2249 		m_gen1.envtime0  = *m_gen1.envtime;
2250 		updateEnvTimes();
2251 	}
2252 
2253 	if (lfo1_enabled) {
2254 		lfo1_wave.reset_test(
2255 			samplv1_wave::Shape(*m_lfo1.shape), *m_lfo1.width);
2256 	}
2257 
2258 	// per voice
2259 
2260 	samplv1_voice *pv = m_play_list.next();
2261 
2262 	while (pv) {
2263 
2264 		samplv1_voice *pv_next = pv->next();
2265 
2266 		// output buffers
2267 
2268 		for (k = 0; k < m_nchannels; ++k) {
2269 			v_outs[k] = outs[k];
2270 			v_sfxs[k] = m_sfxs[k];
2271 		}
2272 
2273 		uint32_t nblock = nframes;
2274 
2275 		while (nblock > 0) {
2276 
2277 			uint32_t ngen = nblock;
2278 
2279 			// process envelope stages
2280 
2281 			if (pv->dca1_env.running && pv->dca1_env.frames < ngen)
2282 				ngen = pv->dca1_env.frames;
2283 			if (pv->dcf1_env.running && pv->dcf1_env.frames < ngen)
2284 				ngen = pv->dcf1_env.frames;
2285 			if (pv->lfo1_env.running && pv->lfo1_env.frames < ngen)
2286 				ngen = pv->lfo1_env.frames;
2287 
2288 			for (uint32_t j = 0; j < ngen; ++j) {
2289 
2290 				// velocities
2291 
2292 				const float vel1
2293 					= (pv->vel + (1.0f - pv->vel) * pv->dca1_pre.value(j));
2294 
2295 				// generators
2296 
2297 				const float lfo1_env
2298 					= (lfo1_enabled ? pv->lfo1_env.tick() : 0.0f);
2299 				const float lfo1
2300 					= (lfo1_enabled ? pv->lfo1_sample * lfo1_env : 0.0f);
2301 
2302 				pv->gen1.next(pv->gen1_freq
2303 					* (m_ctl1.pitchbend + modwheel1 * lfo1)
2304 					+ pv->gen1_glide.tick());
2305 
2306 				float gen1 = pv->gen1.value(k11);
2307 				float gen2 = pv->gen1.value(k12);
2308 
2309 				if (lfo1_enabled) {
2310 					pv->lfo1_sample = pv->lfo1.sample(lfo1_freq
2311 						* (1.0f + SWEEP_SCALE * *m_lfo1.sweep * lfo1_env));
2312 				}
2313 
2314 				// filters
2315 
2316 				if (dcf1_enabled) {
2317 					const float env1 = 0.5f
2318 						* (1.0f + *m_dcf1.envelope * pv->dcf1_env.tick());
2319 					const float cutoff1 = samplv1_sigmoid_1(*m_dcf1.cutoff
2320 						* env1 * (1.0f + *m_lfo1.cutoff * lfo1));
2321 					const float reso1 = samplv1_sigmoid_1(*m_dcf1.reso
2322 						* env1 * (1.0f + *m_lfo1.reso * lfo1));
2323 					switch (int(*m_dcf1.slope)) {
2324 					case 3: // Formant
2325 						gen1 = pv->dcf17.output(gen1, cutoff1, reso1);
2326 						gen2 = pv->dcf18.output(gen2, cutoff1, reso1);
2327 						break;
2328 					case 2: // Biquad
2329 						gen1 = pv->dcf15.output(gen1, cutoff1, reso1);
2330 						gen2 = pv->dcf16.output(gen2, cutoff1, reso1);
2331 						break;
2332 					case 1: // 24db/octave
2333 						gen1 = pv->dcf13.output(gen1, cutoff1, reso1);
2334 						gen2 = pv->dcf14.output(gen2, cutoff1, reso1);
2335 						break;
2336 					case 0: // 12db/octave
2337 					default:
2338 						gen1 = pv->dcf11.output(gen1, cutoff1, reso1);
2339 						gen2 = pv->dcf12.output(gen2, cutoff1, reso1);
2340 						break;
2341 					}
2342 				}
2343 
2344 				// volumes
2345 
2346 				const float wid1 = m_wid1.value(j);
2347 				const float mid1 = 0.5f * (gen1 + gen2);
2348 				const float sid1 = 0.5f * (gen1 - gen2);
2349 				const float vol1 = vel1 * m_vol1.value(j)
2350 					* pv->dca1_env.tick()
2351 					* pv->out1_vol.value(j);
2352 
2353 				// outputs
2354 
2355 				const float out1 = vol1 * (mid1 + sid1 * wid1)
2356 					* pv->out1_pan.value(j, 0)
2357 					* m_pan1.value(j, 0);
2358 				const float out2 = vol1 * (mid1 - sid1 * wid1)
2359 					* pv->out1_pan.value(j, 1)
2360 					* m_pan1.value(j, 1);
2361 
2362 				for (k = 0; k < m_nchannels; ++k) {
2363 					const float dry = (k & 1 ? out2 : out1);
2364 					const float wet = fxsend1 * dry;
2365 					*v_outs[k]++ += dry - wet;
2366 					*v_sfxs[k]++ += wet;
2367 				}
2368 
2369 				if (j == 0) {
2370 					pv->out1_panning = lfo1 * *m_lfo1.panning;
2371 					pv->out1_volume  = lfo1 * *m_lfo1.volume + 1.0f;
2372 				}
2373 			}
2374 
2375 			nblock -= ngen;
2376 
2377 			// voice ramps countdown
2378 
2379 			pv->dca1_pre.process(ngen);
2380 			pv->out1_pan.process(ngen);
2381 			pv->out1_vol.process(ngen);
2382 
2383 			// envelope countdowns
2384 
2385 			if (pv->dca1_env.running && pv->dca1_env.frames == 0)
2386 				m_dca1.env.next(&pv->dca1_env);
2387 
2388 			if (pv->gen1.isOver() ||
2389 				pv->dca1_env.stage == samplv1_env::End) {
2390 				if (pv->note < 0)
2391 					free_voice(pv);
2392 				nblock = 0;
2393 			} else {
2394 				if (pv->dcf1_env.running && pv->dcf1_env.frames == 0)
2395 					m_dcf1.env.next(&pv->dcf1_env);
2396 				if (pv->lfo1_env.running && pv->lfo1_env.frames == 0)
2397 					m_lfo1.env.next(&pv->lfo1_env);
2398 			}
2399 		}
2400 
2401 		// next playing voice
2402 
2403 		pv = pv_next;
2404 	}
2405 
2406 	// chorus
2407 	if (m_nchannels > 1) {
2408 		m_chorus.process(m_sfxs[0], m_sfxs[1], nframes, *m_cho.wet,
2409 			*m_cho.delay, *m_cho.feedb, *m_cho.rate, *m_cho.mod);
2410 	}
2411 
2412 	// effects
2413 	for (k = 0; k < m_nchannels; ++k) {
2414 		float *in = m_sfxs[k];
2415 		// flanger
2416 		m_flanger[k].process(in, nframes, *m_fla.wet,
2417 			*m_fla.delay, *m_fla.feedb, *m_fla.daft * float(k));
2418 		// phaser
2419 		m_phaser[k].process(in, nframes, *m_pha.wet,
2420 			*m_pha.rate, *m_pha.feedb, *m_pha.depth, *m_pha.daft * float(k));
2421 		// delay
2422 		m_delay[k].process(in, nframes, *m_del.wet,
2423 			*m_del.delay, *m_del.feedb, get_bpm(*m_del.bpm));
2424 	}
2425 
2426 	// reverb
2427 	if (m_nchannels > 1) {
2428 		m_reverb.process(m_sfxs[0], m_sfxs[1], nframes, *m_rev.wet,
2429 			*m_rev.feedb, *m_rev.room, *m_rev.damp, *m_rev.width);
2430 	}
2431 
2432 	// output mix-down
2433 	for (k = 0; k < m_nchannels; ++k) {
2434 		uint32_t n;
2435 		float *sfx = m_sfxs[k];
2436 		// compressor
2437 		if (int(*m_dyn.compress) > 0)
2438 			m_comp[k].process(sfx, nframes);
2439 		// limiter
2440 		if (int(*m_dyn.limiter) > 0) {
2441 			float *p = sfx;
2442 			float *q = sfx;
2443 			for (n = 0; n < nframes; ++n)
2444 				*q++ = samplv1_sigmoid(*p++);
2445 		}
2446 		// mix-down
2447 		float *out = outs[k];
2448 		for (n = 0; n < nframes; ++n)
2449 			*out++ += *sfx++;
2450 	}
2451 
2452 	// post-processing
2453 	m_dca1.volume.tick(nframes);
2454 	m_out1.width.tick(nframes);
2455 	m_out1.panning.tick(nframes);
2456 	m_out1.volume.tick(nframes);
2457 
2458 	m_wid1.process(nframes);
2459 	m_pan1.process(nframes);
2460 	m_vol1.process(nframes);
2461 
2462 	m_controls.process(nframes);
2463 }
2464 
2465 
sampleReverseTest(void)2466 void samplv1_impl::sampleReverseTest (void)
2467 {
2468 	if (m_running)
2469 		m_gen1.reverse.tick(1);
2470 }
2471 
2472 
sampleReverseSync(void)2473 void samplv1_impl::sampleReverseSync (void)
2474 {
2475 	const bool bReverse
2476 		= gen1_sample.isReverse();
2477 
2478 	m_gen1.reverse.set_value_sync(bReverse ? 1.0f : 0.0f);
2479 }
2480 
2481 
sampleOffsetTest(void)2482 void samplv1_impl::sampleOffsetTest (void)
2483 {
2484 	if (m_running) {
2485 		m_gen1.offset.tick(1);
2486 		m_gen1.offset_1.tick(1);
2487 		m_gen1.offset_2.tick(1);
2488 	}
2489 }
2490 
2491 
sampleOffsetSync(void)2492 void samplv1_impl::sampleOffsetSync (void)
2493 {
2494 	const bool bOffset
2495 		= gen1_sample.isOffset();
2496 
2497 	m_gen1.offset.set_value_sync(bOffset ? 1.0f : 0.0f);
2498 }
2499 
2500 
sampleOffsetRangeSync(void)2501 void samplv1_impl::sampleOffsetRangeSync (void)
2502 {
2503 	const uint32_t iSampleLength
2504 		= gen1_sample.length();
2505 	const uint32_t iOffsetStart
2506 		= gen1_sample.offsetStart();
2507 	const uint32_t iOffsetEnd
2508 		= gen1_sample.offsetEnd();
2509 
2510 	const float offset_1 = (iSampleLength > 0
2511 		? float(iOffsetStart) / float(iSampleLength)
2512 		: 0.0f);
2513 	const float offset_2 = (iSampleLength > 0
2514 		? float(iOffsetEnd) / float(iSampleLength)
2515 		: 1.0f);
2516 
2517 	m_gen1.offset_1.set_value_sync(offset_1);
2518 	m_gen1.offset_2.set_value_sync(offset_2);
2519 }
2520 
2521 
sampleLoopTest(void)2522 void samplv1_impl::sampleLoopTest (void)
2523 {
2524 	if (m_running) {
2525 		m_gen1.loop.tick(1);
2526 		m_gen1.loop_1.tick(1);
2527 		m_gen1.loop_2.tick(1);
2528 	}
2529 }
2530 
2531 
sampleLoopSync(void)2532 void samplv1_impl::sampleLoopSync (void)
2533 {
2534 	const bool bLoop
2535 		= gen1_sample.isLoop();
2536 
2537 	m_gen1.loop.set_value_sync(bLoop ? 1.0f : 0.0f);
2538 }
2539 
2540 
sampleLoopRangeSync(void)2541 void samplv1_impl::sampleLoopRangeSync (void)
2542 {
2543 	const uint32_t iSampleLength
2544 		= gen1_sample.length();
2545 	const uint32_t iLoopStart
2546 		= gen1_sample.loopStart();
2547 	const uint32_t iLoopEnd
2548 		= gen1_sample.loopEnd();
2549 
2550 	const float loop_1 = (iSampleLength > 0
2551 		? float(iLoopStart) / float(iSampleLength)
2552 		: 0.0f);
2553 	const float loop_2 = (iSampleLength > 0
2554 		? float(iLoopEnd) / float(iSampleLength)
2555 		: 1.0f);
2556 
2557 	m_gen1.loop_1.set_value_sync(loop_1);
2558 	m_gen1.loop_2.set_value_sync(loop_2);
2559 }
2560 
2561 
2562 // process running state...
running(bool on)2563 bool samplv1_impl::running ( bool on )
2564 {
2565 	const bool running = m_running;
2566 	m_running = on;
2567 	return running;
2568 }
2569 
2570 
2571 //-------------------------------------------------------------------------
2572 // samplv1 - decl.
2573 //
2574 
samplv1(uint16_t nchannels,float srate)2575 samplv1::samplv1 ( uint16_t nchannels, float srate )
2576 {
2577 	m_pImpl = new samplv1_impl(this, nchannels, srate);
2578 }
2579 
2580 
~samplv1(void)2581 samplv1::~samplv1 (void)
2582 {
2583 	delete m_pImpl;
2584 }
2585 
2586 
setChannels(uint16_t nchannels)2587 void samplv1::setChannels ( uint16_t nchannels )
2588 {
2589 	m_pImpl->setChannels(nchannels);
2590 }
2591 
2592 
channels(void) const2593 uint16_t samplv1::channels (void) const
2594 {
2595 	return m_pImpl->channels();
2596 }
2597 
2598 
setSampleRate(float srate)2599 void samplv1::setSampleRate ( float srate )
2600 {
2601 	m_pImpl->setSampleRate(srate);
2602 }
2603 
2604 
sampleRate(void) const2605 float samplv1::sampleRate (void) const
2606 {
2607 	return m_pImpl->sampleRate();
2608 }
2609 
2610 
setSampleFile(const char * pszSampleFile,uint16_t iOctaves,bool bSync)2611 void samplv1::setSampleFile ( const char *pszSampleFile, uint16_t iOctaves, bool bSync )
2612 {
2613 	m_pImpl->setSampleFile(pszSampleFile, iOctaves);
2614 
2615 	if (bSync) updateSample();
2616 }
2617 
2618 
sampleFile(void) const2619 const char *samplv1::sampleFile (void) const
2620 {
2621 	return m_pImpl->sampleFile();
2622 }
2623 
2624 
octaves(void) const2625 uint16_t samplv1::octaves (void) const
2626 {
2627 	return m_pImpl->octaves();
2628 }
2629 
2630 
sample(void) const2631 samplv1_sample *samplv1::sample (void) const
2632 {
2633 	return &(m_pImpl->gen1_sample);
2634 }
2635 
2636 
setReverse(bool bReverse,bool bSync)2637 void samplv1::setReverse ( bool bReverse, bool bSync )
2638 {
2639 	m_pImpl->gen1_sample.setReverse(bReverse);
2640 	m_pImpl->sampleReverseSync();
2641 
2642 	if (bSync) updateSample();
2643 }
2644 
isReverse(void) const2645 bool samplv1::isReverse (void) const
2646 {
2647 	return m_pImpl->gen1_sample.isReverse();
2648 }
2649 
2650 
setOffset(bool bOffset,bool bSync)2651 void samplv1::setOffset ( bool bOffset, bool bSync )
2652 {
2653 	m_pImpl->gen1_sample.setOffset(bOffset);
2654 	m_pImpl->sampleOffsetSync();
2655 
2656 	if (bSync) updateOffsetRange();
2657 }
2658 
isOffset(void) const2659 bool samplv1::isOffset (void) const
2660 {
2661 	return m_pImpl->gen1_sample.isOffset();
2662 }
2663 
2664 
setOffsetRange(uint32_t iOffsetStart,uint32_t iOffsetEnd,bool bSync)2665 void samplv1::setOffsetRange ( uint32_t iOffsetStart, uint32_t iOffsetEnd, bool bSync )
2666 {
2667 	m_pImpl->gen1_sample.setOffsetRange(iOffsetStart, iOffsetEnd);
2668 	m_pImpl->sampleOffsetRangeSync();
2669 	m_pImpl->updateEnvTimes();
2670 
2671 	if (bSync) updateOffsetRange();
2672 }
2673 
offsetStart(void) const2674 uint32_t samplv1::offsetStart (void) const
2675 {
2676 	return m_pImpl->gen1_sample.offsetStart();
2677 }
2678 
offsetEnd(void) const2679 uint32_t samplv1::offsetEnd (void) const
2680 {
2681 	return m_pImpl->gen1_sample.offsetEnd();
2682 }
2683 
2684 
setLoop(bool bLoop,bool bSync)2685 void samplv1::setLoop ( bool bLoop, bool bSync )
2686 {
2687 	m_pImpl->gen1_sample.setLoop(bLoop);
2688 	m_pImpl->sampleLoopSync();
2689 
2690 	if (bSync) updateLoopRange();
2691 }
2692 
isLoop(void) const2693 bool samplv1::isLoop (void) const
2694 {
2695 	return m_pImpl->gen1_sample.isLoop();
2696 }
2697 
2698 
setLoopRange(uint32_t iLoopStart,uint32_t iLoopEnd,bool bSync)2699 void samplv1::setLoopRange ( uint32_t iLoopStart, uint32_t iLoopEnd, bool bSync )
2700 {
2701 	m_pImpl->gen1_sample.setLoopRange(iLoopStart, iLoopEnd);
2702 	m_pImpl->sampleLoopRangeSync();
2703 
2704 	if (bSync) updateLoopRange();
2705 }
2706 
loopStart(void) const2707 uint32_t samplv1::loopStart (void) const
2708 {
2709 	return m_pImpl->gen1_sample.loopStart();
2710 }
2711 
loopEnd(void) const2712 uint32_t samplv1::loopEnd (void) const
2713 {
2714 	return m_pImpl->gen1_sample.loopEnd();
2715 }
2716 
2717 
setLoopFade(uint32_t iLoopFade,bool bSync)2718 void samplv1::setLoopFade ( uint32_t iLoopFade, bool bSync )
2719 {
2720 	m_pImpl->gen1_sample.setLoopCrossFade(iLoopFade);
2721 
2722 	if (bSync) updateLoopFade();
2723 }
2724 
loopFade(void) const2725 uint32_t samplv1::loopFade (void) const
2726 {
2727 	return uint32_t(m_pImpl->gen1_sample.loopCrossFade());
2728 }
2729 
2730 
setLoopZero(bool bLoopZero,bool bSync)2731 void samplv1::setLoopZero ( bool bLoopZero, bool bSync )
2732 {
2733 	m_pImpl->gen1_sample.setLoopZeroCrossing(bLoopZero);
2734 
2735 	if (bSync) updateLoopZero();
2736 }
2737 
isLoopZero(void) const2738 bool samplv1::isLoopZero (void) const
2739 {
2740 	return m_pImpl->gen1_sample.isLoopZeroCrossing();
2741 }
2742 
2743 
setBufferSize(uint32_t nsize)2744 void samplv1::setBufferSize ( uint32_t nsize )
2745 {
2746 	m_pImpl->setBufferSize(nsize);
2747 }
2748 
bufferSize(void) const2749 uint32_t samplv1::bufferSize (void) const
2750 {
2751 	return m_pImpl->bufferSize();
2752 }
2753 
2754 
setTempo(float bpm)2755 void samplv1::setTempo ( float bpm )
2756 {
2757 	m_pImpl->setTempo(bpm);
2758 }
2759 
tempo(void) const2760 float samplv1::tempo (void) const
2761 {
2762 	return m_pImpl->tempo();
2763 }
2764 
2765 
setParamPort(ParamIndex index,float * pfParam)2766 void samplv1::setParamPort ( ParamIndex index, float *pfParam )
2767 {
2768 	m_pImpl->setParamPort(index, pfParam);
2769 }
2770 
paramPort(ParamIndex index) const2771 samplv1_port *samplv1::paramPort ( ParamIndex index ) const
2772 {
2773 	return m_pImpl->paramPort(index);
2774 }
2775 
2776 
setParamValue(ParamIndex index,float fValue)2777 void samplv1::setParamValue ( ParamIndex index, float fValue )
2778 {
2779 	m_pImpl->setParamValue(index, fValue);
2780 }
2781 
paramValue(ParamIndex index) const2782 float samplv1::paramValue ( ParamIndex index ) const
2783 {
2784 	return m_pImpl->paramValue(index);
2785 }
2786 
2787 
process_midi(uint8_t * data,uint32_t size)2788 void samplv1::process_midi ( uint8_t *data, uint32_t size )
2789 {
2790 #ifdef CONFIG_DEBUG_0
2791 	fprintf(stderr, "samplv1[%p]::process_midi(%u)", this, size);
2792 	for (uint32_t i = 0; i < size; ++i)
2793 		fprintf(stderr, " %02x", data[i]);
2794 	fprintf(stderr, "\n");
2795 #endif
2796 
2797 	m_pImpl->process_midi(data, size);
2798 }
2799 
2800 
process(float ** ins,float ** outs,uint32_t nframes)2801 void samplv1::process ( float **ins, float **outs, uint32_t nframes )
2802 {
2803 	m_pImpl->process(ins, outs, nframes);
2804 
2805 	m_pImpl->sampleReverseTest();
2806 }
2807 
2808 
2809 // controllers accessor
2810 
controls(void) const2811 samplv1_controls *samplv1::controls (void) const
2812 {
2813 	return m_pImpl->controls();
2814 }
2815 
2816 
2817 // programs accessor
2818 
programs(void) const2819 samplv1_programs *samplv1::programs (void) const
2820 {
2821 	return m_pImpl->programs();
2822 }
2823 
2824 
2825 // process state
2826 
running(bool on)2827 bool samplv1::running ( bool on )
2828 {
2829 	return m_pImpl->running(on);
2830 }
2831 
2832 
2833 // all stabilize
2834 
stabilize(void)2835 void samplv1::stabilize (void)
2836 {
2837 	m_pImpl->stabilize();
2838 }
2839 
2840 
2841 // all reset clear
2842 
reset(void)2843 void samplv1::reset (void)
2844 {
2845 	m_pImpl->reset();
2846 }
2847 
2848 
sampleOffsetLoopTest(void)2849 void samplv1::sampleOffsetLoopTest (void)
2850 {
2851 	m_pImpl->sampleOffsetTest();
2852 	m_pImpl->sampleLoopTest();
2853 }
2854 
2855 
2856 // MIDI input asynchronous status notification accessors
2857 
midiInEnabled(bool on)2858 void samplv1::midiInEnabled ( bool on )
2859 {
2860 	m_pImpl->midiInEnabled(on);
2861 }
2862 
2863 
midiInCount(void)2864 uint32_t samplv1::midiInCount (void)
2865 {
2866 	return m_pImpl->midiInCount();
2867 }
2868 
2869 
2870 // MIDI direct note on/off triggering
2871 
directNoteOn(int note,int vel)2872 void samplv1::directNoteOn ( int note, int vel )
2873 {
2874 	m_pImpl->directNoteOn(note, vel);
2875 }
2876 
2877 
2878 // Micro-tuning support
setTuningEnabled(bool enabled)2879 void samplv1::setTuningEnabled ( bool enabled )
2880 {
2881 	m_pImpl->setTuningEnabled(enabled);
2882 }
2883 
isTuningEnabled(void) const2884 bool samplv1::isTuningEnabled (void) const
2885 {
2886 	return m_pImpl->isTuningEnabled();
2887 }
2888 
2889 
setTuningRefPitch(float refPitch)2890 void samplv1::setTuningRefPitch ( float refPitch )
2891 {
2892 	m_pImpl->setTuningRefPitch(refPitch);
2893 }
2894 
tuningRefPitch(void) const2895 float samplv1::tuningRefPitch (void) const
2896 {
2897 	return m_pImpl->tuningRefPitch();
2898 }
2899 
2900 
setTuningRefNote(int refNote)2901 void samplv1::setTuningRefNote ( int refNote )
2902 {
2903 	m_pImpl->setTuningRefNote(refNote);
2904 }
2905 
tuningRefNote(void) const2906 int samplv1::tuningRefNote (void) const
2907 {
2908 	return m_pImpl->tuningRefNote();
2909 }
2910 
2911 
setTuningScaleFile(const char * pszScaleFile)2912 void samplv1::setTuningScaleFile ( const char *pszScaleFile )
2913 {
2914 	m_pImpl->setTuningScaleFile(pszScaleFile);
2915 }
2916 
tuningScaleFile(void) const2917 const char *samplv1::tuningScaleFile (void) const
2918 {
2919 	return m_pImpl->tuningScaleFile();
2920 }
2921 
2922 
setTuningKeyMapFile(const char * pszKeyMapFile)2923 void samplv1::setTuningKeyMapFile ( const char *pszKeyMapFile )
2924 {
2925 	m_pImpl->setTuningKeyMapFile(pszKeyMapFile);
2926 }
2927 
tuningKeyMapFile(void) const2928 const char *samplv1::tuningKeyMapFile (void) const
2929 {
2930 	return m_pImpl->tuningKeyMapFile();
2931 }
2932 
2933 
resetTuning(void)2934 void samplv1::resetTuning (void)
2935 {
2936 	m_pImpl->resetTuning();
2937 }
2938 
2939 
2940 // end of samplv1.cpp
2941