Klang C++
Language Reference (draft)
Loading...
Searching...
No Matches
klang.h
1#pragma once
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <cmath>
6#include <limits>
7#include <assert.h>
8#include <array>
9#include <memory>
10#include <vector>
11#include <string>
12#include <cstdarg>
13#include <algorithm>
14#include <type_traits>
15#include <mutex>
16#include <functional>
17
18#include <float.h>
19
20#ifdef __wasm__
21#define THREAD_LOCAL
22static inline float _sqrt(float x) { return __builtin_sqrtf(x); }
23static inline float _abs(float x) { return __builtin_fabsf(x); }
24#define SQRT _sqrt
25#define SQRTF _sqrt
26#define ABS _abs
27#define FABS _abs
28#endif
29#ifdef __APPLE__
30#define THREAD_LOCAL
31#define SQRT ::sqrt
32#define SQRTF ::sqrtf
33#define ABS ::abs
34#define FABS ::fabsf
35#endif
36#if defined(__WIN32__) || defined(WIN32)
37#define THREAD_LOCAL thread_local
38#define SQRT ::sqrt
39#define SQRTF ::sqrtf
40#define ABS ::abs
41#define FABS ::fabsf
42#endif
43
44#if defined(DEBUG) || defined(_DEBUG)
45 #define KLANG_DEBUG 1
46#else
47 #define KLANG_DEBUG 0
48#endif
49
50#ifndef GRAPH_SIZE
51#define GRAPH_SIZE 44100
52#endif
53
54#define GRAPH_SERIES 4
55
56// provide access to original math functions through std:: prefix
57namespace std {
58 namespace klang {
59 template<typename TYPE> TYPE sqrt(TYPE x) { return SQRT(x); }
60 template<typename TYPE> TYPE abs(TYPE x) { return ABS(x); }
61 }
62};
63
64#define IS_SIMPLE_TYPE(type)
65 static_assert(!std::is_polymorphic_v<type>, "signal has virtual table");
66 static_assert(!std::has_virtual_destructor_v<type>, "signal has virtual destructor");
67 static_assert(std::is_trivially_copyable_v<type>, "signal is not trivially copyable");
68 static_assert(std::is_trivially_copy_assignable_v<type>, "signal is not trivially copy assignable");
69 static_assert(std::is_trivially_copy_constructible_v<type>, "signal is not trivially copy assignable");
70 static_assert(std::is_trivially_destructible_v<type>, "signal is not trivially copy assignable");
71 static_assert(std::is_trivially_move_assignable_v<type>, "signal is not trivially copy assignable");
72 static_assert(std::is_trivially_move_constructible_v<type>, "signal is not trivially copy assignable");
73
74namespace klang {
75
76 /// Klang language version (major.minor.build.debug)
77 struct Version {
78 unsigned char major, minor, build, extra;
79 bool isDebug() const { return extra & 1; } }
80 static constexpr version = { 0, 7, 0, KLANG_DEBUG };
81
82 /// Klang mode identifiers (e.g. averages, level following)
83 enum Mode { Peak, RMS, Mean };
84
85 #define DENORMALISE 1.175494e-38f
86
87 /// Constant scalar (pre-converted to double, float and int).
88 struct constant {
89
90 /// Create a constant from the given value.
91 constexpr constant(double value) noexcept
92 : d(value), f(static_cast<float>(value)), i(static_cast<int>(value)), inv(value == 0.0f ? 0.0f : static_cast<float>(1.0 / value)) { }
93
94 const double d; //!< Constant as double
95 const float f; //!< Constant as float
96 const int i; //!< Constant as integer
97 const float inv; //!< Inverse of constant
98
99 constexpr operator float() const noexcept { return f; }
100
101 /// Constant raised to the power, x.
102 float operator^(float x) const { return std::pow(f, x); }
103 float operator^(int x) const { return static_cast<float>(std::pow(d, x)); }
104 float operator^(double x) const { return static_cast<float>(std::pow(d, x)); }
105 };
106
107 #define CONSTANT constexpr constant
108
109#if __cplusplus == 201703L
110 #pragma warning(disable:4996) // disable deprecated warning
111 /// @internal
112 template <typename T>
113 inline constexpr bool is_literal = std::is_literal_type_v<T>;
114#else
115 /// @internal
116 template <typename T>
118#endif
119 /// @internal
120 template<typename Base, typename Derived>
121 constexpr bool is_derived_from() {
122 return std::is_base_of_v<Base, Derived>;
123 }
124 /// @internal
125 template<typename Head, typename... Tail>
126 constexpr bool are_scalars(Head&& head, Tail&&... tail) {
127 using T = std::decay_t<decltype(head)>;
128 return std::is_scalar_v<T> && ((sizeof... (Tail)) == 0 || are_scalars(std::forward<decltype(tail)>(tail)...));
129 }
130 /// @internal
131 template <typename BASE, int EXP>
132 inline constexpr BASE poweri(BASE base) {
133 BASE result = 1;
134 constexpr bool negative = EXP < 0;
135 int exp = negative ? -EXP : EXP;
136 while (exp > 0) {
137 if (exp % 2 == 1)
138 result *= base;
139 base *= base;
140 exp >>= 1;
141 }
142 return negative ? 1 / result : result;
143 }
144 /// @internal
145 template <typename BASE, typename EXP>
146 using power_t = typename std::conditional_t<std::is_integral_v<BASE>, float, BASE>;
147
148 /// Raise @a base to the power @a exp.
149 template <typename BASE, typename EXP, std::enable_if_t < is_literal<EXP>, bool>>
150 inline constexpr power_t<BASE, EXP> power(BASE base, EXP exp) {
151 if constexpr (std::is_integral_v<EXP>) {
152 switch (exp) {
153 case 0: return (BASE)1;
154 case 1: return base;
155 case 2: return base * base;
156 case 3: return base * base * base;
157 case 4: return base * base * base * base;
158 case -1: return (BASE)1 / base;
159 case -2: return (BASE)1 / (base * base);
160 case -3: return (BASE)1 / (base * base * base);
161 case -4: return (BASE)1 / (base * base * base * base);
162 default:
163 return poweri<BASE, exp>(base);
164 }
165 } else if constexpr (std::is_floating_point_v<EXP>) {
166 if constexpr (exp == (EXP)0) return 1;
167 else if constexpr (exp == (EXP)1) return base;
168 else if constexpr (exp == (EXP)2) return base * base;
169 else if constexpr (exp == (EXP)3) return base * base * base;
170 else if constexpr (exp == (EXP)4) return base * base * base * base;
171 else if constexpr (exp == (EXP)-1) return 1 / base;
172 else if constexpr (exp == (EXP)-2) return 1 / (base * base);
173 else if constexpr (exp == (EXP)-3) return 1 / (base * base * base);
174 else if constexpr (exp == (EXP)-4) return 1 / (base * base * base * base);
175 }
176 return (BASE)std::pow(base, exp);;
177 }
178
179 /// Raise @a base to the power @a exp.
180 template <typename BASE, typename EXP>
181 inline constexpr power_t<BASE, EXP> power(BASE base, EXP exp) {
182 if constexpr (std::is_integral_v<BASE>) {
183 return power(float(base), exp);
184 } else if constexpr (std::is_integral_v<EXP>) {
185 switch (exp) {
186 case 0: return (BASE)1;
187 case 1: return base;
188 case 2: return base * base;
189 case 3: return base * base * base;
190 case 4: return base * base * base * base;
191 case -1: return (BASE)1 / base;
192 case -2: return (BASE)1 / (base * base);
193 case -3: return (BASE)1 / (base * base * base);
194 case -4: return (BASE)1 / (base * base * base * base);
195 }
196 } else if constexpr (std::is_floating_point_v<EXP>) {
197 if (base == (BASE)10) return (power_t<BASE, EXP>)::exp(exp * (EXP)2.3025850929940456840179914546843642076011014886287729760333279009);
198 else if (exp == (EXP)0) return (power_t<BASE, EXP>)1;
199 else if (exp == (EXP)1) return base;
200 else if (exp == (EXP)2) return base * base;
201 else if (exp == (EXP)3) return base * base * base;
202 else if (exp == (EXP)4) return base * base * base * base;
203 else if (exp == (EXP)-1) return (power_t<BASE, EXP>)1 / base;
204 else if (exp == (EXP)-2) return (power_t<BASE, EXP>)1 / (base * base);
205 else if (exp == (EXP)-3) return (power_t<BASE, EXP>)1 / (base * base * base);
206 else if (exp == (EXP)-4) return (power_t<BASE, EXP>)1 / (base * base * base * base);
207 }
208 return power_t<BASE, EXP>(std::pow(base, exp));
209 }
210
211 /// Return the minimum of two values.
212 template<typename TYPE1, typename TYPE2> inline TYPE1 min(TYPE1 a, TYPE2 b) { return a < b ? a : (TYPE1)b; };
213
214 /// Return the minimum of two values.
215 template<typename TYPE1, typename TYPE2> inline TYPE1 max(TYPE1 a, TYPE2 b) { return a > b ? a : (TYPE1)b; };
216
217 /// The mathematical constant, pi (and it's inverse).
218 constexpr constant pi = { 3.1415926535897932384626433832795 };
219
220 /// The natural logorithm of 2 (and it's inverse).
221 constexpr constant ln2 = { 0.6931471805599453094172321214581 };
222
223 /// The square root of 2 (and it's inverse).
224 constexpr constant root2 = { 1.4142135623730950488016887242097 };
225
226 /// Generates a random number between min and max. Use an integer types for whole numbers.
227 template<typename TYPE>
228 inline static TYPE random(const TYPE min, const TYPE max) { return rand() * ((max - min) / (TYPE)RAND_MAX) + min; }
229
230 /// Set the random seed (to allow repeatable random generation).
231 inline static void random(const unsigned int seed) { srand(seed); }
232
233 /// A function that handles an event.
234 typedef void event;
235
236 /// Variable-sized array, pre-allocated to a max. capacity.
237 template<typename TYPE, int CAPACITY>
238 struct Array {
239 TYPE items[CAPACITY];
240 unsigned int count = 0;
241
242 /// The maximum capacity of the array.
243 static int capacity() { return CAPACITY; }
244
245 /// The current number of items in the array.
246 unsigned int size() const { return count; }
247
248 /// Add the specified item to the end of the array.
249 void add(const TYPE& item) {
250 if(count < CAPACITY)
251 items[count++] = item;
252 }
253
254 /// Add a blank item to the end of the array, returning a pointer that allows the item to be modified.
255 TYPE* add() {
256 if (count < CAPACITY)
257 return &items[count++];
258 return nullptr;
259 }
260
261 /// Clear the array contents. Only resets the item count, without wiping memory.
262 void clear() { count = 0; }
263
264 /// Find the maximum value in the array.
265 float max() const {
266 float max = 0.f;
267 for (unsigned int i = 0; i < count; i++)
268 if (abs(items[i]) > max)
269 max = items[i];
270 return max;
271 }
272
273 /// Find the mean average of values in the array.
274 float mean() const {
275 float sum = 0.f;
276 for (unsigned int i = 0; i < count; i++)
277 sum += abs(items[i]);
278 return sum / count;
279 }
280
281 /// Find the root mean squared (RMS) average of values in the array.
282 float rms() const {
283 float sum = 0.f;
284 for (unsigned int i = 0; i < count; i++)
285 sum += items[i] * items[i];
286 return sqrt(sum / count);
287 }
288
289 /// Normalises values in the array to the specified @a target, based on peak, mean, or RMS value;
290 void normalise(float target = 1.f, int mode = Peak) {
291 if (!count) return;
292
293 const float current = (mode == Peak) ? max() : (mode == Mean) ? mean() : rms();
294 const float scale = current == 0.f ? 0.f : target / current;
295 for (int i = 0; i < count; i++)
296 items[i] *= scale;
297 }
298
299 /// Returns a reference to the array item at the given index.
300 TYPE& operator[](int index) { return items[index]; }
301
302 /// Returns a read-only reference to the array item at the given index.
303 const TYPE& operator[](int index) const { return items[index]; }
304
305 /// Construct an array given the specified values.
306 Array(std::initializer_list<TYPE> init_list) {
307 count = std::min(static_cast<unsigned int>(init_list.size()), static_cast<unsigned int>(CAPACITY));
309 }
310
311 /// Construct an empty array.
312 Array() = default; // Default constructor to allow empty initialization
313 };
314
315 /// String of characters representing text.
316 template<int SIZE>
317 struct Text {
318 /// The character buffer.
319 char string[SIZE + 1] = { 0 };
320
321 /// Maximum size of the string.
322 int capacity() const { return SIZE; }
323
324 /// Automatic cast to constant C-string.
325 operator const char* () const { return string; }
326
327 /// Return constant C-string.
328 const char* c_str() const { return string; }
329
330 /// Create a new Text object from a C-string.
331 static Text from(const char* in) {
332 Text text;
333 text = in;
334 return text;
335 }
336
337 /// Assign C-String to Text object.
338 void operator=(const char* in) {
339 memcpy(string, in, SIZE);
340 string[SIZE] = 0;
341 }
342
343 /// Returns true if Text matches the given C-string.
344 bool operator==(const char* in) const {
345 return strcmp(string, in) == 0;
346 }
347
348 /// Returns true if Text does not matches the given C-string.
349 bool operator!=(const char* in) const {
350 return !operator==(in);
351 }
352 };
353
354 /// A short Text object used to label controls.
355 typedef Text<32> Caption;
356
357 struct Output;
358
359 struct relative;
360
361 /// A mono audio signal (equivalent to a float).
362 struct signal {
363 float value;
364
365 /// Create signal from a constant.
366 signal(constant initial) : value(initial.f) { }
367
368 /// Create signal from a 32-bit float..
369 signal(const float initial = 0.f) : value(initial) { }
370
371 /// Create signal from a 64-bit double.
372 signal(const double initial) : value((const float)initial) { }
373
374 /// Create signal from an 32-bit signed integer.
375 signal(const int value) : value((const float)value) { }
376
377 /// Feedback operator (prevents further processing of returned value).
378 const signal& operator<<(const signal& input) {
379 value = input;
380 return *this;
381 }
382
383 /// Stream operator (feedforward; allows further processing)
384 signal& operator>>(signal& destination) const {
385 destination.value = value;
386 return destination;
387 }
388
389 /// Assign processed output of \a in to signal.
390 signal& operator=(Output& in);
391 /// Adds processed output of \a in to signal.
392 signal& operator+=(Output& in);
393
394 /// Add (mix) another signal to the signal.
395 signal& operator+=(const signal& x) { value += x.value; return *this; }
396 /// Subtract another signal from the signal.
397 signal& operator-=(const signal& x) { value -= x.value; return *this; }
398 /// Multiply (modulate) signal by another signal.
399 signal& operator*=(const signal& x) { value *= x.value; return *this; }
400 /// Divide signal by another signal.
401 signal& operator/=(const signal& x) { value /= x.value; return *this; }
402
403 /// Add the specified amount to the signal.
404 signal& operator+=(float x) { value += x; return *this; }
405 /// Subtract the specified amount from the signal.
406 signal& operator-=(float x) { value -= x; return *this; }
407 /// Multiply signal by the specified amount.
408 signal& operator*=(float x) { value *= x; return *this; }
409 /// Divide signal by the specified amount.
410 signal& operator/=(float x) { value /= x; return *this; }
411
412 /// Add the specified amount to the signal.
413 signal& operator+=(double x) { value += (float)x; return *this; }
414 /// Subtract the specified amount from the signal.
415 signal& operator-=(double x) { value -= (float)x; return *this; }
416 /// Multiply signal by the specified amount.
417 signal& operator*=(double x) { value *= (float)x; return *this; }
418 /// Divide signal by the specified amount.
419 signal& operator/=(double x) { value /= (float)x; return *this; }
420
421 /// Add the specified amount to the signal.
422 signal& operator+=(int x) { value += (float)x; return *this; }
423 /// Subtract the specified amount from the signal.
424 signal& operator-=(int x) { value -= (float)x; return *this; }
425 /// Multiply signal by the specified amount.
426 signal& operator*=(int x) { value *= (float)x; return *this; }
427 /// Divide signal by the specified amount.
428 signal& operator/=(int x) { value /= (float)x; return *this; }
429
430 /// Add two signals together.
431 signal operator+(float x) const { return value + x; }
432 /// Subtract one signal from another.
433 signal operator-(float x) const { return value - x; }
434 /// Multiply (modulate) two signals.
435 signal operator*(float x) const { return value * x; }
436 /// Divide one signal by another.
437 signal operator/(float x) const { return value / x; }
438
439 /// Return a copy of the signal offset by x.
440 signal operator+(double x) const { return value + (float)x; }
441 /// Return a copy of the signal offset by -x.
442 signal operator-(double x) const { return value - (float)x; }
443 /// Return a copy of the signal scaled by x.
444 signal operator*(double x) const { return value * (float)x; }
445 /// Return a copy of the signal divided by.
446 signal operator/(double x) const { return value / (float)x; }
447
448 /// Return a copy of the signal offset by x.
449 signal operator+(int x) const { return value + (float)x; }
450 /// Return a copy of the signal offset by -x.
451 signal operator-(int x) const { return value - (float)x; }
452 /// Return a copy of the signal scaled by x.
453 signal operator*(int x) const { return value * (float)x; }
454 /// Return a copy of the signal divided by x.
455 signal operator/(int x) const { return value / (float)x; }
456
457 /// Return a copy of the signal raised to the power of x.
458 signal operator^(float x) const { return power(value, x); }
459 /// Return a copy of the signal raised to the power of x.
460 signal operator^(double x) const { return power(value, x); }
461 /// Return a copy of the signal raised to the power of x.
462 signal operator^(int x) const { return power(value, x); }
463
464 operator const float() const { return value; }
465 operator float&() { return value; }
466
467 /// Check if the signal contains a denormal value.
468 bool isDenormal() const {
469 const unsigned int bits = *(const unsigned int*)&value;
470 return !(bits & 0x7F800000) && (bits & 0x007FFFFF);
471 }
472
473 /// Returns the number of channels (1 = mono).
474 int channels() const { return 1; }
475
476 /// Returns a copy of the signal to treat as a relative offset (e.g. for phase modulation).
477 relative operator+() const; // unary + operator produces relative signal
478 /// Returns a copy of the signal to treat as a relative offset (e.g. for phase modulation).
479 relative relative() const; //
480 };
481
482 /// @internal signal MUST compile as a float
483 static_assert(sizeof(signal) == sizeof(float), "signal != float");
485
486 /// A signal used as an offset relative to another signal.
487 struct relative : public signal { };
488
489 /// Returns a copy of the signal to treat as a relative offset (e.g. for phase modulation).
490 inline relative signal::operator+() const { return { value }; }
491 /// Returns a copy of the signal to treat as a relative offset (e.g. for phase modulation).
492 inline relative signal::relative() const { return { value }; }
493
494 /// Stream a literal / constant / scalar type into a signal.
495 inline static signal& operator>>(float input, signal& destination) { // CHECK: should this be signal, rather than float?
496 destination << signal(input);
497 return destination;
498 }
499
500 /// A multi-channel audio signal (e.g. stereo).
501 template<int CHANNELS = 2>
502 struct signals {
503 /// @cond
504 union {
505 signal value[CHANNELS]; ///< Array of channel values.
506 struct {
507 signal l; ///< Left channel
508 signal r; ///< Right channel
509 };
510 };
511 /// @endcond
512
513 /// Return the mono mix of a stereo channel.
514 signal mono() const { return (l + r) * 0.5f; }
515
516 /// Return a reference to the signal at the specified index (0 = left, 1 = right).
517 signal& operator[](int index) { return value[index]; }
518 /// Return a read-only reference to the signal at the specified index (0 = left, 1 = right).
519 const signal& operator[](int index) const { return value[index]; }
520
521 /// Create a stereo signal with the given value.
522 signals(float initial = 0.f) : l(initial), r(initial) { }
523 /// Create a stereo signal with the given value.
524 signals(double initial) : l((float)initial), r((float)initial) { }
525 /// Create a stereo signal with the given value.
526 signals(int initial) : l((float)initial), r((float)initial) { }
527
528 /// Create a stereo signal with the given left and right value.
529 signals(float left, float right) : l(left), r(right) { }
530 /// Create a stereo signal with the given left and right value.
531 signals(double left, double right) : l((float)left), r((float)right) { }
532 /// Create a stereo signal with the given left and right value.
533 signals(int left, int right) : l((float)left), r((float)right) { }
534
535 /// Create a multi-channel signal with the given channel values.
536 template <typename... Args, typename = std::enable_if_t<(std::is_convertible_v<Args, signal> && ...)>>
537 signals(Args&... initial) : value{ initial... } { }
538 /// Create a multi-channel signal with the given channel values.
539 template <typename... Args, typename = std::enable_if_t<(std::is_scalar_v<Args> && ...)>>
540 signals(Args... initial) : value { initial... } { }
541
542 /// Returns the number of channels in the signal.
543 int channels() const { return CHANNELS; }
544
545 /// Feedback operator (prevents further processing of returned value).
546 const signals& operator<<(const signals& input) {
547 return this->operator=(input);
548 }
549
550 /// Stream operator (feedforward; allows further processing).
551 signals& operator>>(signals& destination) const {
552 destination = *this;
553 return destination;
554 }
555
556 /// Add (mix) another signal to the signal.
557 signals& operator+=(const signals x) { for (int v = 0; v < CHANNELS; v++) value[v] += x[v]; return *this; }
558 /// Subtract another signal from the signal.
559 signals& operator-=(const signals x) { for (int v = 0; v < CHANNELS; v++) value[v] -= x[v]; return *this; }
560 /// Multiply (modulate) signal by another signal.
561 signals& operator*=(const signals x) { for (int v = 0; v < CHANNELS; v++) value[v] *= x[v]; return *this; }
562 /// Divide signal by another signal.
563 signals& operator/=(const signals x) { for (int v = 0; v < CHANNELS; v++) value[v] /= x[v]; return *this; }
564
565 /// Add two multi-channel signals together.
566 signals operator+(const signals x) const { signals s = *this; for (int v = 0; v < CHANNELS; v++) s[v] += x[v]; return s; }
567 /// Subtract one multi-channel signal from another.
568 signals operator-(const signals x) const { signals s = *this; for (int v = 0; v < CHANNELS; v++) s[v] -= x[v]; return s; }
569 /// Multiply (modulate) two multi-channel signals.
570 signals operator*(const signals x) const { signals s = *this; for (int v = 0; v < CHANNELS; v++) s[v] *= x[v]; return s; }
571 /// Divide one multi-channel signal by another.
572 signals operator/(const signals x) const { signals s = *this; for (int v = 0; v < CHANNELS; v++) s[v] /= x[v]; return s; }
573
574 //signals& operator+=(const signal x) { for (int v = 0; v < CHANNELS; v++) value[v] += x; return *this; }
575 //signals& operator-=(const signal x) { for (int v = 0; v < CHANNELS; v++) value[v] -= x; return *this; }
576 //signals& operator*=(const signal x) { for (int v = 0; v < CHANNELS; v++) value[v] *= x; return *this; }
577 //signals& operator/=(const signal x) { for (int v = 0; v < CHANNELS; v++) value[v] /= x; return *this; }
578
579 /// Return a copy of the multi-channel signal, adding a mono signal to each channel.
580 signals operator+(const signal x) const { signals s = *this; for (int v = 0; v < CHANNELS; v++) s[v] += x; return s; }
581 /// Return a copy of the multi-channel signal, subtracting a mono signal from each channel.
582 signals operator-(const signal x) const { signals s = *this; for (int v = 0; v < CHANNELS; v++) s[v] -= x; return s; }
583 /// Return a copy of the multi-channel signal, multiplying (modulating) each channel by a mono signal.
584 signals operator*(const signal x) const { signals s = *this; for (int v = 0; v < CHANNELS; v++) s[v] *= x; return s; }
585 /// Return a copy of the multi-channel signal, dividing each channel by a mono signal.
586 signals operator/(const signal x) const { signals s = *this; for (int v = 0; v < CHANNELS; v++) s[v] /= x; return s; }
587
588 /// Return a copy of the signal with each channel offset by x.
589 signals operator+(float x) const { signals s = *this; for(int v = 0; v < CHANNELS; v++) s[v] += x; return s; }
590 /// Return a copy of the signal with each channel offset by -x.
591 signals operator-(float x) const { signals s = *this; for(int v = 0; v < CHANNELS; v++) s[v] -= x; return s; }
592 /// Return a copy of the signal with each channel scaled by x.
593 signals operator*(float x) const { signals s = *this; for(int v = 0; v < CHANNELS; v++) s[v] *= x; return s; }
594 /// Return a copy of the signal with each channel divided by x.
595 signals operator/(float x) const { signals s = *this; for(int v = 0; v < CHANNELS; v++) s[v] /= x; return s; }
596
597 /// Return a copy of the signal with each channel offset by x.
598 signals operator+(double x) const { signals s = *this; for (int v = 0; v < CHANNELS; v++) s[v] += x; return s; }
599 /// Return a copy of the signal with each channel offset by -x.
600 signals operator-(double x) const { signals s = *this; for (int v = 0; v < CHANNELS; v++) s[v] -= x; return s; }
601 /// Return a copy of the signal with each channel scaled by x.
602 signals operator*(double x) const { signals s = *this; for (int v = 0; v < CHANNELS; v++) s[v] *= x; return s; }
603 /// Return a copy of the signal with each channel divided by x.
604 signals operator/(double x) const { signals s = *this; for (int v = 0; v < CHANNELS; v++) s[v] /= x; return s; }
605
606 /// Return a copy of the signal with each channel offset by x.
607 signals operator+(int x) const { signals s = *this; for (int v = 0; v < CHANNELS; v++) s[v] += x; return s; }
608 /// Return a copy of the signal with each channel offset by -x.
609 signals operator-(int x) const { signals s = *this; for (int v = 0; v < CHANNELS; v++) s[v] -= x; return s; }
610 /// Return a copy of the signal with each channel scaled by x.
611 signals operator*(int x) const { signals s = *this; for (int v = 0; v < CHANNELS; v++) s[v] *= x; return s; }
612 /// Return a copy of the signal with each channel divided by x.
613 signals operator/(int x) const { signals s = *this; for (int v = 0; v < CHANNELS; v++) s[v] /= x; return s; }
614 };
615
616 /// Return a copy of the signal with each channel offset by x.
617 template<int CHANNELS = 2> inline signals<CHANNELS> operator+(float x, const signals<CHANNELS>& y) { return y + x; }
618 /// Return a copy of the signal with each channel subtracted from x.
619 template<int CHANNELS = 2> inline signals<CHANNELS> operator-(float x, const signals<CHANNELS>& y) { return -y + x; }
620 /// Return a copy of the signal with each channel scaled by x.
621 template<int CHANNELS = 2> inline signals<CHANNELS> operator*(float x, const signals<CHANNELS>& y) { return y * x; }
622 /// Return a copy of the signal with each channel divided into x.
623 template<int CHANNELS = 2> inline signals<CHANNELS> operator/(float x, const signals<CHANNELS>& y) {
624 signals<CHANNELS> s = { 0.f };
625 for(int c=0; c<CHANNELS; c++)
626 s[c] = x / y[c];
627 return std::move(s);
628 }
629
630 /// @cond
631 /// Helper class for converting units / quantities
632 struct Conversion : public signal {
633 using signal::signal;
634 // operator klang::signal& () { return signal; };
635 };
636 /// @endcond
637
638 /// A phase or wavetable increment.
639 struct increment {
640 float amount; ///< The current phase.
641 const float size; ///< The length of a a full cycle (e.g. 2 pi or wavetable size)
642
643 /// Create a phase increment (default to radians).
644 increment(float amount, const float size = 2 * pi) : amount(amount), size(size) { }
645 /// Create a phase increment (wavetable size).
646 increment(float amount, int size) : amount(amount), size((float)size) { }
647 /// Create a phase increment.
648 increment(float amount, double size) : amount(amount), size((float)size) { }
649
650 /// Set current phase.
651 increment& operator=(float in) { amount = in; return *this; }
652 };
653
654 struct Control;
655
656 /// A signal used as a control parameter.
657 struct param : public signal {
659 param(const float initial = 0.f) : signal(initial) { }
660 param(const signal& in) : signal(in) { }
661 param(signal& in) : signal(in) { }
662 param(Control& in); // see Control declaration
663
664 param& operator+=(const increment& increment) {
665 value += increment.amount;
666 if (value >= increment.size)
667 value -= increment.size;
668 return *this;
669 }
670 };
671
672 // param should also be binary compatible with float / signal
673 static_assert(sizeof(param) == sizeof(float), "param != float");
674
675 // support left-to-right and right-to-left signal flow
676 inline static param& operator>>(param& from, param& to) {
677 to << from;
678 return to;
679 }
680
681 /// @cond
682 struct params {
683 param* parameters;
684 const int size;
685
686 params(param p) : parameters(new param[1]), size(1) { parameters[0] = p; }
687 params(std::initializer_list<param> params) : parameters(new param[params.size()]), size((int)params.size()) {
688 int index = 0;
689 for(param p : params)
690 parameters[index++] = p;
691 }
692
693 param& operator[](int index) { return parameters[index]; }
694 };
695 /// @endcond
696
697 inline float fast_mod(float x, float y) {
698 const unsigned int i = (((unsigned int)(x * (float(UINT_MAX) + 1.f) / y)) >> 9) | 0x3f800000;
699 return (*(const float*)&i - 1.f) * y;
700 }
701
702 inline double fast_mod(double x, double y) {
703 const unsigned long long i = (((unsigned long long)(x * (double(ULLONG_MAX) + 1.0) / y)) >> 12ULL) | 0x7FF0000000000000ULL;
704 return (*(const double*)&i - 1.0) * y;
705 }
706
707 inline float fast_mod1(float x) {
708 const unsigned int i = ((unsigned int)(x * (float(UINT_MAX) + 1.f)) >> 9) | 0x3f800000;
709 return *(const float*)&i - 1.f;
710 }
711
712 inline double fast_mod1(double x) {
713 const unsigned long long i = (((unsigned long long)(x * (double(ULLONG_MAX) + 1.0))) >> 12ULL) | 0x7FF0000000000000ULL;
714 return (*(const double*)&i - 1.0);
715 }
716
717 inline float fast_mod2pi(float x) {
718 constexpr float twoPi = float(2.0 * 3.1415926535897932384626433832795);
719 const unsigned int i = (((unsigned int)(x * (float(UINT_MAX) + 1.f) / twoPi)) >> 9) | 0x3f800000;
720 return (*(const float*)&i - 1.f) * twoPi;
721 }
722
723 inline float fast_modp(unsigned int x) {
724 constexpr float twoPi = float(2.0 * 3.1415926535897932384626433832795);
725 const unsigned int i = (x >> 9) | 0x3f800000;
726 return (*(const float*)&i - 1.f) * twoPi;
727 }
728
729 inline double fast_mod2pi(double x) {
730 constexpr double twoPi = (2.0 * 3.1415926535897932384626433832795);
731 const unsigned long long i = (((unsigned long long)(x * (double(ULLONG_MAX) + 1.0) / twoPi)) >> 12ULL) | 0x7FF0000000000000ULL;
732 return (*(const double*)&i - 1.0) * twoPi;
733 }
734
735 template<int SIZE>
736 inline double fast_modi(double x) {
737 constexpr double size = double(SIZE);
738 constexpr double sizeInv = 1.0 / double(SIZE);
739 const unsigned long long i = (((unsigned long long)(x * (double(ULLONG_MAX) + 1.0) * sizeInv)) >> 12ULL) | 0x7FF0000000000000ULL;
740 return (*(const double*)&i - 1.0) * size;
741 }
742
743 /// Matrix processor
744 //template<int X, int Y = X>
745 struct Matrix {
746 float v[4][4] = { 0 };
747
748 float* operator[](int col) { return v[col]; }
749 const float* operator[](int col) const { return v[col]; }
750
751 float& operator()(int col, int row) { return v[col][row]; }
752 float operator()(int col, int row) const { return v[col][row]; }
753
754 signals<4> operator<<(const signals<4>& in) const {
755 return { v[0][0] * in[0] + v[0][1] * in[1] + v[0][2] * in[2] + v[0][3] * in[3],
756 v[1][0] * in[0] + v[1][1] * in[1] + v[1][2] * in[2] + v[1][3] * in[3],
757 v[2][0] * in[0] + v[2][1] * in[1] + v[2][2] * in[2] + v[2][3] * in[3],
758 v[3][0] * in[0] + v[3][1] * in[1] + v[3][2] * in[2] + v[3][3] * in[3] };
759 }
760 };
761
762 inline signals<4> operator*(const signals<4>& in, const Matrix& m) {
763 return { m[0][0] * in[0] + m[0][1] * in[1] + m[0][2] * in[2] + m[0][3] * in[3],
764 m[1][0] * in[0] + m[1][1] * in[1] + m[1][2] * in[2] + m[1][3] * in[3],
765 m[2][0] * in[0] + m[2][1] * in[1] + m[2][2] * in[2] + m[2][3] * in[3],
766 m[3][0] * in[0] + m[3][1] * in[1] + m[3][2] * in[2] + m[3][3] * in[3] };
767 }
768
769 inline signals<4> operator>>(const signals<4>& in, const Matrix& m) { return operator*(in, m); }
770
771 /// @cond
772 template<typename TYPE, typename _TYPE>
773 struct phase {
774 static constexpr TYPE twoPi = TYPE(2.0 * 3.1415926535897932384626433832795);
775
776 // represent phase using full range of uint32
777 // (integer math, no conditionals, free oversampling)
778 _TYPE i = 0;
779
780 // convert float [0, 2pi) to uint32
781 phase(TYPE phase = 0) {
782 if constexpr (std::is_same<TYPE, double>()) {
783 constexpr TYPE FUINTMAX = TYPE(ULLONG_MAX + 1.0) / twoPi; // (float)INT_MAX + 1.f;
784 phase *= FUINTMAX;
785 i = (_TYPE)phase;
786 } else if constexpr (std::is_same<TYPE, float>()) {
787 constexpr TYPE FUINTMAX = TYPE(UINT_MAX + 1.0) / twoPi; // (float)INT_MAX + 1.f;
788 phase *= FUINTMAX;
789 i = (_TYPE)phase;
790 }
791 }
792
793 // convert uint32 to float [0, 1)
794 operator TYPE() const {
795 const _TYPE phase = (i >> 12ULL) | 0x3FF0000000000000ULL;
796 return (*(const TYPE*)&phase - TYPE(1.0)) * twoPi;
797 }
798
799 //static void test() {
800 // phase p;
801 // assert((float)(p = 0.f).radians() == 0.f);
802 // assert((float)(p = pi / 2).radians() == pi / 2);
803 // assert((float)(p = pi).radians() == pi);
804 // assert((float)(p = 3 * pi / 2).radians() == 3 * pi / 2);
805 // assert((float)(p = 2 * pi).radians() == 0.f);
806 //}
807 };
808 /// @endcond
809
810 /// Control parameter (phase)
811 struct Phase : public param {
812 //INFO("Phase", 0.f, 0.f, 1.0f)
813 using param::param;
814 /*Phase(const float p = 0.f) : param(p) { };*/
815
816 param& operator+=(float increment) {
817 if (increment >= (2 * pi))
818 return *this;
819 value += increment;
820 if (value > (2 * pi))
821 value -= (2 * pi);
822 return *this;
823 }
824
825 param& operator+=(const increment& increment) {
826 if (increment.amount >= increment.size)
827 return *this;
828 value += increment.amount;
829 if (value > increment.size)
830 value -= increment.size;
831 return *this;
832 }
833
834 Phase operator+(const increment& increment) const {
835 if (increment.amount >= increment.size)
836 return value;
837 Phase value = Phase::value + increment.amount;
838 if (value > increment.size)
839 value -= increment.size;
840 return value;
841 }
842
843 Phase operator%(float modulus) {
844 return fast_mod(value, modulus);
845 }
846 };
847
848 struct Frequency;
849
850 /// Control parameter (pitch)
851 struct Pitch : public param {
852 //INFO("Pitch", 60.f, 0.f, 127.f)
853 using param::param;
854
855 //Pitch(float p = 60.f) : param(p) { };
856 //Pitch(int p) : param((float)p) { };
857
858 // convert note number to pitch class and octave (e.g. C#5)
859 const char* text() const {
860 THREAD_LOCAL static char buffer[32] = { 0 };
861 const char* const notes[12] = { "C", "C#/Db", "D", "D#/Eb", "E", "F", "F#/Gb", "G", "G#/Ab", "A", "A#/Bb", "B" };
862 snprintf(buffer, 32, "%s%d", notes[(int)value % 12], (int)value / 12);
863 return buffer;
864 }
865
866 const Pitch* operator->() {
867 Frequency = 440.f * power(2.f, (value - 69.f) / 12.f);
868 return this;
869 }
870
871 THREAD_LOCAL static Conversion Frequency;
872
873 template<typename TYPE> Pitch operator+(TYPE in) { return value + in; }
874 template<typename TYPE> Pitch operator-(TYPE in) { return value - in; }
875 template<typename TYPE> Pitch operator*(TYPE in) { return value * in; }
876 template<typename TYPE> Pitch operator/(TYPE in) { return value / in; }
877 };
878
879 THREAD_LOCAL inline Conversion Pitch::Frequency;
880
881// inline THREAD_LOCAL Pitch::Convert Pitch::Frequency;
882
883 /// Control parameter (frequency)
884 struct Frequency : public param {
885 //INFO("Frequency", 1000.f, -FLT_MAX, FLT_MAX)
886 using param::param;
887 Frequency(float f = 1000.f) : param(f) { };
888 };
889
890 /// Sample rate constants
891 static struct SampleRate {
892 float f; ///< sample rate (float)
893 int i; ///< sample rate (integer)
894 double d; ///< sample rate (double)
895 float inv; ///< 1 / sample rate (inverse)
896 float w; ///< angular frequency (omega)
897 float nyquist; ///< nyquist frequency (f / 2)
898
899 SampleRate(float sr) : f(sr), i(int(sr+0.001f)), d((double)sr), inv(1.f / sr), w(2.0f * pi * inv), nyquist(sr / 2.f) { }
900
901 operator float() { return f; }
902 } fs(44100); // sample rate
903
904 struct Amplitude;
905
906 /// Control parameter (idecibels)
907 struct dB : public param {
908 //INFO("dB", 0.f, -FLT_MAX, FLT_MAX)
909 using param::param;
910
911 dB(float gain = 0.f) : param(gain) { };
912
913 const dB* operator->() {
914 Amplitude = power(10, value * 0.05f);
915 return this;
916 }
917
918 THREAD_LOCAL static Conversion Amplitude;
919 };
920
921 /// Control parameter (linear amplitude)
922 struct Amplitude : public param {
923 //INFO("Gain", 1.f, -FLT_MAX, FLT_MAX)
924 using param::param;
925
926 Amplitude(float a = 1.f) : param(a) { };
927 Amplitude(const dB& db) {
928 value = power(10, db.value * 0.05f); // 10 ^ (db * 0.05f);
929 };
930
931 //dB operator >> (dB) const {
932 // return 20.f * log10f(value);
933 //}
934 //operator dB() const {
935 // return 20.f * log10f(value);
936 //}
937
938 const Amplitude* operator->() const {
939 dB = 20.f * log10f(value);
940 return this;
941 }
942
943 THREAD_LOCAL static Conversion dB;
944 };
945
946 THREAD_LOCAL inline Conversion dB::Amplitude;
947 THREAD_LOCAL inline Conversion Amplitude::dB;
948
949 /// Control parameter (velocity)
951
952 /// UI control / parameter
953 struct Control
954 {
955 enum Type
956 {
957 NONE, // no control (list terminator)
958 ROTARY, // rotary knob (dial/pot)
959 BUTTON, // push button (trigger)
960 TOGGLE, // on/off switch (toggle)
961 SLIDER, // linear slider (fader)
962 MENU, // drop-down list (menu; up to 128 items)
963 METER, // level meter (read-only: use setParameter() to set value)
964 WHEEL, // MIDI control (Pitch Bend / Mod Wheel only)
965 };
966
967 /// Control size
968 struct Size
969 {
970 Size(int x = -1, int y = -1, int width = -1, int height = -1)
971 : x(x), y(y), width(width), height(height) { }
972
973 int x;
974 int y;
975 int width;
977
978 bool isAuto() const { return x == -1 && y == -1 && width == -1 && height == -1; }
979 };
980
981 typedef Array<Caption, 128> Options;
982
983 Caption name; // name for control label / saved parameter
984 Type type = NONE; // control type (see above)
985
986 float min; // minimum control value (e.g. 0.0)
987 float max; // maximum control value (e.g. 1.0)
988 float initial; // initial value for control (e.g. 0.0)
989
990 Size size; // position (x,y) and size (height, width) of the control (use AUTO_SIZE for automatic layout)
991 Options options; // text options for menus and group buttons
992
993 signal value; // current control value
994 signal smoothed; // smoothed control value (filtered)
995
996 operator signal& () { return value; }
997 operator const signal&() const { return value; }
998 operator param() const { return value; }
999 operator float() const { return value.value; }
1000
1001 static constexpr float smoothing = 0.999f;
1003
1004 operator Control*() { return this; }
1005
1006 Control& set(float x) {
1007 value = std::clamp(x, min, max);
1008 return *this;
1009 }
1010
1011 Control& operator+=(float x) { value += x; return *this; }
1012 Control& operator*=(float x) { value *= x; return *this; }
1013 Control& operator-=(float x) { value -= x; return *this; }
1014 Control& operator/=(float x) { value /= x; return *this; }
1015
1016 //float operator+(float x) const { return value + x; }
1017 //float operator*(float x) const { return value * x; }
1018 //float operator-(float x) const { return value - x; }
1019 //float operator/(float x) const { return value / x; }
1020
1021 template<typename TYPE> signal operator+(const Control& x) const { return value + x; }
1022 template<typename TYPE> signal operator*(const Control& x) const { return value * x; }
1023 template<typename TYPE> signal operator-(const Control& x) const { return value - x; }
1024 template<typename TYPE> signal operator/(const Control& x) const { return value / x; }
1025
1026 template<typename TYPE> float operator+(TYPE x) const { return value + x; }
1027 template<typename TYPE> float operator*(TYPE x) const { return value * x; }
1028 template<typename TYPE> float operator-(TYPE x) const { return value - x; }
1029 template<typename TYPE> float operator/(TYPE x) const { return value / x; }
1030
1031 template<typename TYPE> Control& operator<<(TYPE& in) { value = in; return *this; } // assign to control with processing
1032 template<typename TYPE> Control& operator<<(const TYPE& in) { value = in; return *this; } // assign to control without/after processing
1033
1034 template<typename TYPE> TYPE& operator>>(TYPE& in) { return value >> in; } // stream control to signal/object (allows processing)
1035 template<typename TYPE> const TYPE& operator>>(const TYPE& in) { return value >> in; } // stream control to signal/object (no processing)
1036 };
1037
1038 const Control::Size Automatic = { -1, -1, -1, -1 };
1040
1041 /// Mapped UI control
1042 struct ControlMap {
1044
1045 ControlMap() : control(nullptr) { };
1046 ControlMap(Control& control) : control(&control) { };
1047
1048 operator Control&() { return *control; }
1050 operator const signal&() const { return control->value; }
1051 operator param() const { return control->value; }
1052 operator float() const { return control->value; }
1054
1055 template<typename TYPE> Control& operator<<(TYPE& in) { control->value = in; return *control; } // assign to control with processing
1056 template<typename TYPE> Control& operator<<(const TYPE& in) { control->value = in; return *control; } // assign to control without/after processing
1057 };
1058
1060
1061 inline param::param(Control& in) : signal(in.value) { }
1062
1063 inline static Control Dial(const char* name, float min = 0.f, float max = 1.f, float initial = 0.f)
1064 { return { Caption::from(name), Control::ROTARY, min, max, initial, Automatic, NoOptions, initial }; }
1065
1066 inline static Control Button(const char* name)
1067 { return { Caption::from(name), Control::BUTTON, 0, 1, 0.f, Automatic, NoOptions, 0.f }; }
1068
1069 inline static Control Toggle(const char* name, bool initial = false)
1070 { return { Caption::from(name), Control::TOGGLE, 0, 1, initial ? 1.f : 0.f, Automatic, NoOptions, initial ? 1.f : 0.f}; }
1071
1072 inline static Control Slider(const char* name, float min = 0.f, float max = 1.f, float initial = 0.f)
1073 { return { Caption::from(name), Control::SLIDER, min, max, initial, Automatic, NoOptions, initial }; }
1074
1075 template<typename... Options>
1076 static Control Menu(const char* name, const Options... options)
1077 { Control::Options menu;
1078 const char* strings[] = { options... };
1079 int nbValues = sizeof...(options);
1080 for(int p=0; p<nbValues; p++)
1082 return { Caption::from(name), Control::MENU, 0, menu.size() - 1.f, 0, Automatic, menu, 0 };
1083 }
1084
1085 inline static Control Meter(const char* name, float min = 0.f, float max = 1.f, float initial = 0.f)
1086 { return { Caption::from(name), Control::METER, min, max, initial, Automatic, NoOptions, initial }; }
1087
1088 inline static Control PitchBend()
1089 { return { { "PITCH\nBEND" }, Control::WHEEL, 0.f, 16384.f, 8192.f, Automatic, NoOptions, 8192.f }; }
1090
1091 inline static Control ModWheel()
1092 { return { { "MOD\nWHEEL" }, Control::WHEEL, 0.f, 127.f, 0.f, Automatic, NoOptions, 0.f }; }
1093
1094 /// Plugin UI controls
1095 struct Controls : Array<Control, 128>
1096 {
1097 float value[128] = { 0 };
1098
1099 void operator+= (const Control& control) {
1100 items[count++] = control;
1101 }
1102
1103 void operator= (const Controls& controls) {
1104 for (int c = 0; c < 128 && controls[c].type != Control::NONE; c++)
1105 operator+=(controls[c]);
1106 }
1107
1108 void operator=(std::initializer_list<Control> controls) {
1109 for(auto control : controls)
1110 operator+=(control);
1111 }
1112
1113 void add(const char* name, Control::Type type = Control::ROTARY, float min = 0.f, float max = 1.f, float initial = 0.f, Control::Size size = Automatic) {
1114 items[count].name = name;
1115 items[count].type = type;
1116 items[count].min = min;
1117 items[count].max = max;
1118 items[count].initial = initial;
1119 items[count].size = size;
1120 items[count++].value = initial;
1121 }
1122
1123 bool changed() {
1124 bool changed = false;
1125 for (unsigned int c = 0; c < count; c++) {
1126 if (items[c].value != value[c]) {
1127 value[c] = items[c].value;
1128 changed = true;
1129 }
1130 }
1131 return changed;
1132 }
1133
1134 //float& operator[](int index) { return items[index].value; }
1135 //signal operator[](int index) const { return items[index].value; }
1136
1137 //Control& operator()(int index) { return items[index]; }
1138 //Control operator()(int index) const { return items[index]; }
1139 };
1140
1141 typedef Array<float, 128> Values;
1142
1143 /// Factory preset
1144 struct Preset {
1145 Caption name = { 0 };
1147 };
1148
1149 //template<typename... Settings>
1150 //static Program Preset(const char* name, const Settings... settings)
1151 //{ Values values;
1152 // float preset[] = { (float)settings... };
1153 // int nbSettings = sizeof...(settings);
1154 // for(int s=0; s<nbSettings; s++)
1155 // values.add(preset[s]);
1156 // return { Caption::from(name), values };
1157 //}
1158
1159 /// Factory presets
1160 struct Presets : Array<Preset, 128> {
1161 void operator += (const Preset& preset) {
1162 items[count++] = preset;
1163 }
1164
1165 void operator= (const Presets& presets) {
1166 for (int p = 0; p < 128 && presets[p].name[0]; p++)
1167 operator+=(presets[p]);
1168 }
1169
1170 void operator=(std::initializer_list<Preset> presets) {
1171 for(auto preset : presets)
1172 operator+=(preset);
1173 }
1174
1175 template<typename... Values>
1176 void add(const char* name, const Values... values) {
1177 items[count].name = name;
1178
1179 const float preset[] = { values... };
1180 int nbValues = sizeof...(values);
1181 for(int p=0; p<nbValues; p++)
1183 count++;
1184 }
1185 };
1186
1187 /// Audio buffer (mono)
1188 class buffer {
1189 protected:
1190 constexpr unsigned int capacity(unsigned int n) {
1191 // Decrement n to handle the case where n is already a power of 2
1192 n--;
1193 n |= n >> 1;
1194 n |= n >> 2;
1195 n |= n >> 4;
1196 n |= n >> 8;
1197 n |= n >> 16;
1198 // Increment n to get the next power of 2
1199 n++;
1200 return n;
1201 }
1202 const unsigned int mask = 0xFFFFFFFF;
1203 const bool owned = false;
1204 float* samples;
1207 public:
1208 typedef signal signal;
1209 const int size;
1210
1211 buffer(float* buffer, int size)
1212 : owned(false), samples(buffer), size(size) {
1213 rewind();
1214 }
1215
1216 buffer(float* buffer, int size, float initial)
1217 : owned(false), samples(buffer), size(size) {
1218 rewind();
1219 set(initial);
1220 }
1221
1222 buffer(int size, float initial = 0)
1223 : mask(capacity(size) - 1), owned(true), samples(new float[capacity(size)]), size(size) {
1224 rewind();
1225 set(initial);
1226 }
1227
1228 virtual ~buffer() {
1229 if (owned)
1230 delete[] samples;
1231 }
1232
1233 void rewind(int offset = 0) {
1234#ifdef _MSC_VER
1235 _controlfp_s(nullptr, _DN_FLUSH, _MCW_DN);
1236#endif
1237 ptr = (signal*)&samples[offset];
1238 end = (signal*)&samples[size];
1239 }
1240
1241 void clear() {
1242 memset(samples, 0, sizeof(float) * size);
1243 }
1244
1245 void clear(int size) {
1246 memset(samples, 0, sizeof(float) * (size < buffer::size ? size : buffer::size));
1247 }
1248
1249 int offset() const {
1250 return int((signal*)&samples[0] - ptr);
1251 }
1252
1253 void set(float value = 0) {
1254 if (value == 0)
1255 clear();
1256 else for (int s = 0; s < size; s++)
1257 samples[s] = value;
1258 }
1259
1260 signal& operator[](int offset) {
1261 return *(signal*)&samples[offset & mask]; // owned array can't write beyond allocation
1262 }
1263
1264 signal operator[](float offset) {
1265 return ((const buffer*)this)->operator[](offset);
1266 }
1267
1268 signal operator[](float offset) const {
1269 const float f = floorf(offset);
1270 const float frac = offset - f;
1271
1272 const int i = (int)offset;
1273 const int j = (i == (size - 1)) ? 0 : (i + 1);
1274
1275 return samples[i] * (1.f - frac) + samples[j] * frac;
1276 }
1277
1278 const signal& operator[](int index) const {
1279 return *(const signal*)&samples[index];
1280 }
1281
1282 operator signal& () {
1283 return *ptr;
1284 }
1285
1286 operator const signal& () const {
1287 return *ptr;
1288 }
1289
1290 explicit operator double() const {
1291 return *ptr;
1292 }
1293
1294 bool finished() const {
1295 return ptr == end;
1296 }
1297
1298 signal& operator++(int) {
1299 return *ptr++;
1300 }
1301
1302 signal& operator=(const signal& in) {
1303 return *ptr = in;
1304 }
1305
1306 signal& operator+=(const signal& in) {
1307 *ptr += in;
1308 return *this;
1309 }
1310
1311 signal& operator*=(const signal& in) {
1312 *ptr *= in;
1313 return *this;
1314 }
1315
1316 buffer& operator=(const buffer& in) {
1317 //assert(size == in.size);
1318 memcpy(samples, in.samples, size * sizeof(float));
1319 return *this;
1320 }
1321
1322 buffer& operator<<(const signal& in) {
1323 *ptr = in;
1324 return *this;
1325 }
1326
1327 const float* data() const { return samples; }
1328 };
1329
1330 struct Graph;
1331 struct GraphPtr;
1332
1333 /// Templates supporting common audio functionality
1334 namespace Generic {
1335
1336 /// Audio input object
1337 template<typename SIGNAL>
1338 struct Input {
1339 virtual ~Input() { }
1340 SIGNAL in = { 0.f };
1341
1342 // retrieve current input
1343 virtual const SIGNAL& input() const { return in; }
1344
1345 // feedback input (include pre-processing, if any)
1346 virtual void operator<<(const SIGNAL& source) { in = source; input(); }
1347 virtual void input(const SIGNAL& source) { in = source; input(); }
1348
1349 protected:
1350 // preprocess input (default: none)
1351 virtual void input() { }
1352 };
1353
1354 /// Audio output object
1355 template<typename SIGNAL>
1356 struct Output {
1357 SIGNAL out = { 0.f };
1358
1359 // returns previous output (without processing)
1360 virtual const SIGNAL& output() const { return out; }
1361
1362 // pass output to destination (with processing)
1363 template<typename TYPE>
1364 TYPE& operator>>(TYPE& destination) { process(); return destination = out; }
1365
1366 // returns output (with processing)
1367 virtual operator const SIGNAL&() { process(); return out; } // return processed output
1368 virtual operator const SIGNAL&() const { return out; } // return last output
1369
1370 // arithmetic operations produce copies
1371 template<typename TYPE> SIGNAL operator+(TYPE& other) { process(); return out + (other); }
1372 template<typename TYPE> SIGNAL operator*(TYPE& other) { process(); return out * (other); }
1373 template<typename TYPE> SIGNAL operator-(TYPE& other) { process(); return out - (other); }
1374 template<typename TYPE> SIGNAL operator/(TYPE& other) { process(); return out / (other); }
1375
1376 protected:
1377 // signal processing
1378 virtual void process() = 0;
1379 };
1380
1381 //template<typename TYPE> inline signal operator+(TYPE other, Output& output) { return signal(output) + other; }
1382 //template<typename TYPE> inline signal operator*(TYPE other, Output& output) { return signal(output) * other; }
1383 //template<typename TYPE> inline signal operator-(TYPE other, Output& output) { return signal(other) - signal(output); }
1384 //template<typename TYPE> inline signal operator/(TYPE other, Output& output) { return signal(other) / signal(output); }
1385
1386 // in-place arithmetic operations (CHECK: can these just be SIGNAL?)
1387 template<typename SIGNAL> inline SIGNAL operator+(float other, Output<SIGNAL>& output) { return SIGNAL(output) + other; }
1388 template<typename SIGNAL> inline SIGNAL operator*(float other, Output<SIGNAL>& output) { return SIGNAL(output) * other; }
1389 template<typename SIGNAL> inline SIGNAL operator-(float other, Output<SIGNAL>& output) { return SIGNAL(other) - SIGNAL(output); }
1390 template<typename SIGNAL> inline SIGNAL operator/(float other, Output<SIGNAL>& output) { return SIGNAL(other) / SIGNAL(output); }
1391
1392 template<typename SIGNAL> inline SIGNAL operator+(Output<SIGNAL>& output, float other) { return SIGNAL(output) + other; }
1393 template<typename SIGNAL> inline SIGNAL operator*(Output<SIGNAL>& output, float other) { return SIGNAL(output) * other; }
1394 template<typename SIGNAL> inline SIGNAL operator-(Output<SIGNAL>& output, float other) { return SIGNAL(output) - other; }
1395 template<typename SIGNAL> inline SIGNAL operator/(Output<SIGNAL>& output, float other) { return SIGNAL(output) / other; }
1396
1397 //inline signal operator+(Output& other, Output& output) { return signal(output) + signal(other); }
1398 //inline signal operator*(Output& other, Output& output) { return signal(output) * signal(other); }
1399 //inline signal operator-(Output& other, Output& output) { return signal(other) - signal(output); }
1400 //inline signal operator/(Output& other, Output& output) { return signal(other) / signal(output); }
1401
1402 /// Signal generator object (output only)
1403 template<typename SIGNAL>
1404 struct Generator : public Output<SIGNAL> {
1405 using Output<SIGNAL>::out;
1406
1407 // inline parameter(s) support
1408 template<typename... params>
1409 Output<SIGNAL>& operator()(params... p) {
1410 set(p...); return *this;
1411 }
1412
1413 using Output<SIGNAL>::operator>>;
1414 using Output<SIGNAL>::process;
1415 operator const SIGNAL& () override { process(); return out; } // return processed output
1416 operator const SIGNAL& () const override { return out; } // return last output
1417
1418 protected:
1419 // overrideable parameter setting (up to 8 parameters)
1420 /// @cond
1421 virtual void set(param) { };
1422 virtual void set(relative) { }; // relative alternative
1423 virtual void set(param, param) { };
1424 virtual void set(param, relative) { }; // relative alternative
1425 virtual void set(param, param, param) { };
1426 virtual void set(param, param, relative) { }; // relative alternative
1427 virtual void set(param, param, param, param) { };
1428 virtual void set(param, param, param, relative) { }; // relative alternative
1429 virtual void set(param, param, param, param, param) { };
1430 virtual void set(param, param, param, param, relative) { }; // relative alternative
1431 virtual void set(param, param, param, param, param, param) { };
1432 virtual void set(param, param, param, param, param, relative) { }; // relative alternative
1433 virtual void set(param, param, param, param, param, param, param) { };
1434 virtual void set(param, param, param, param, param, param, relative) { }; // relative alternative
1435 virtual void set(param, param, param, param, param, param, param, param) { };
1436 virtual void set(param, param, param, param, param, param, param, relative) { }; // relative alternative
1437 /// @endcond
1438 };
1439
1440 /// Signal modifier object (input-output)
1441 template<typename SIGNAL>
1442 struct Modifier : public Input<SIGNAL>, public Output<SIGNAL> {
1443 using Input<SIGNAL>::in;
1444 using Output<SIGNAL>::out;
1445
1446 virtual ~Modifier() { }
1447
1448 // signal processing (input-output)
1449 operator const SIGNAL&() override { process(); return out; } // return processed output
1450 operator const SIGNAL&() const override { return out; } // return last output
1451
1452 using Input<SIGNAL>::input;
1453 virtual void process() override { out = in; } // default to pass-through
1454
1455 // inline parameter(s) support
1456 template<typename... params>
1457 Modifier<SIGNAL>& operator()(params... p) {
1458 set(p...); return *this;
1459 }
1460 protected:
1461 // overrideable parameter setting (up to 8 parameters)
1462 /// @cond
1463 virtual void set(param) { };
1464 virtual void set(param, param) { };
1465 virtual void set(param, param, param) { };
1466 virtual void set(param, param, param, param) { };
1467 virtual void set(param, param, param, param, param) { };
1468 virtual void set(param, param, param, param, param, param) { };
1469 virtual void set(param, param, param, param, param, param, param) { };
1470 virtual void set(param, param, param, param, param, param, param, param) { };
1471 /// @endcond
1472 };
1473
1474 /// Applies a function to a signal (input-output)
1475 template<typename SIGNAL, typename... Args>
1476 struct Function : public Generic::Modifier<SIGNAL> {
1477 virtual ~Function() { }
1478
1479 using Modifier<SIGNAL>::in;
1480 using Modifier<SIGNAL>::out;
1481
1482 operator SIGNAL() {
1483 if (function)
1484 return evaluate();
1485 process();
1486 return out;
1487 };
1489 if(function)
1490 return evaluate();
1491 return 2.f;
1492 }
1493
1494 /// @cond
1495 // Helper to combine hash values
1496 template <typename T>
1497 inline void hash_combine(std::size_t& seed, const T& value) const {
1498 std::hash<T> hasher;
1499 seed ^= hasher(value) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
1500 }
1501
1502 // Recursive function to hash each element of a tuple
1503 template <typename Tuple, std::size_t Index = 0>
1504 std::size_t hash_tuple(const Tuple& tuple) const {
1505 if constexpr (Index < std::tuple_size<Tuple>::value) {
1508 return seed;
1509 } else {
1510 return 0;
1511 }
1512 }
1513
1514 operator void*() { return this; }
1515 uint64_t hash() const { return hash_tuple(tail(inputs)); }
1516 /// @endcond
1517
1518 std::function<float(Args...)> function;
1519
1520 static constexpr unsigned int ARGS = sizeof...(Args);
1521 unsigned int args() const { return ARGS; }
1522
1523 std::tuple<Args...> inputs;
1524
1525 // Helper function to extract the tail of a tuple
1526 template <typename First, typename... Rest>
1527 std::tuple<Rest...> tail(const std::tuple<First, Rest...>& t) const {
1528 return std::apply( [](const First&, const Rest&... rest) { return std::make_tuple(rest...); },t);
1529 }
1530
1531 template<typename FunctionPtr>
1532 Function() : function(nullptr) { }
1533
1534 template<typename FunctionPtr>
1535 Function(FunctionPtr function)
1536 : function(std::forward<FunctionPtr>(function)) {}
1537
1538 template<typename FunctionPtr, typename... OtherArgs>
1539 Function(FunctionPtr function, OtherArgs... args)
1541 with(args...);
1542 }
1543
1544 void input() override {
1545 std::get<0>(inputs) = in.value;
1546 }
1547
1548 // get the first argument
1549 template <typename First, typename... Rest>
1550 First first(First first, Rest...) { return first; }
1551
1552 // Function call operator to invoke the stored callable
1553 template<typename... FuncArgs>
1554 Function<SIGNAL,Args...>& operator()(const FuncArgs&... args) {
1555 if constexpr (ARGS > 1 && sizeof...(FuncArgs) == 1){
1556 in = first(args...);
1557 std::get<0>(inputs) = in.value;
1558 return *this;
1559 } else if constexpr (ARGS == sizeof...(FuncArgs)){
1560 in = first(args...);
1561 inputs = std::tuple<Args...>(args...);
1562 return *this;
1563 } else if constexpr (sizeof...(FuncArgs) == (ARGS - 1)){
1564 inputs = std::tuple<Args...>(in.value, args...);
1565 return *this;
1566 } else {
1567 in = first(args...);
1568 std::get<0>(inputs) = in.value;
1569 return *this;
1570 }
1571 }
1572
1573 // Function call operator to invoke the stored callable
1574 template<typename... FuncArgs>
1575 const float operator()(const FuncArgs&... args) const {
1576 signal in = this->in;
1577 std::tuple<Args...> inputs = this->inputs;
1578
1579 // configure inputs
1580 if constexpr (ARGS > 1 && sizeof...(FuncArgs) == 1) {
1581 in = first(args...);
1582 std::get<0>(inputs) = in.value;
1583 } else if constexpr (ARGS == sizeof...(FuncArgs)) {
1584 in = first(args...);
1585 inputs = std::tuple<Args...>(args...);
1586 } else if constexpr (sizeof...(FuncArgs) == (ARGS - 1)) {
1587 inputs = std::tuple<Args...>(in.value, args...);
1588 } else {
1589 in = first(args...);
1590 std::get<0>(inputs) = in.value;
1591 }
1592
1593 // return outputs
1594 if constexpr (ARGS > 1)
1595 return std::apply(function, inputs);
1596 else
1597 return function(in);
1598 }
1599
1600 template<typename... FuncArgs>
1601 Function<SIGNAL,Args...>& with(FuncArgs... args){
1602 static_assert(sizeof...(FuncArgs) == (ARGS - 1), "with() arguments must have all but first argument.");
1603 inputs = std::tuple<Args...>(in.value, args...);
1604
1605 return *this;
1606 }
1607
1609 if (!function)
1610 return 0.f;
1611 if constexpr (ARGS > 1)
1612 return std::apply(function, inputs);
1613 else
1614 return function(in);
1615 }
1616
1617 virtual void process() override {
1618 out = evaluate();
1619 }
1620
1622 klang::GraphPtr& operator>>(klang::GraphPtr& graph);
1623 };
1624
1625 // deduction guide for functions
1626 template <typename... Args>
1627 Function(float(*)(Args...)) -> Function<signal, Args...>;
1628
1629 template <typename... Args>
1630 Function() -> Function<signal, Args...>;
1631
1632 /// A line graph plotter
1633 template<int SIZE>
1634 struct Graph {
1635 virtual ~Graph() { };
1636
1637 size_t capacity() const { return SIZE; }
1638
1639 struct Series;
1640
1641 /// A data point
1642 struct Point {
1643 double x, y;
1644 bool valid() const { return !::isnan(x) && !::isinf(x) && !::isnan(y); } // NB: y can be +/- inf
1645
1647 };
1648
1649 struct Axis;
1650
1651 /// Data series
1652 struct Series : public Array<Point, SIZE + 1>, Input<signal> {
1653 virtual ~Series() { }
1654
1655 void* function = nullptr;
1656 uint64_t hash = 0;
1657
1658 using Array = Array<Point, SIZE + 1>;
1659 using Array::add;
1660 using Array::count;
1661 using Array::items;
1662
1663 void add(double y) {
1664 add({ (double)Array::size(), y });
1665 }
1666
1667 template<typename SIGNAL, typename... Args>
1668 void plot(Generic::Function<SIGNAL, Args...>& f, const Axis& x_axis) {
1669 constexpr int size = SIZE > 1024 ? 1024 : SIZE;
1670
1671 if (function != (void*)f || hash != f.hash()) {
1672 clear();
1673 function = (void*)f;
1674 hash = f.hash();
1675 double x = 0;
1676 const double dx = x_axis.range() / size;
1677 for (int i = 0; i <= size; i++) {
1678 x = x_axis.min + i * dx;
1679 add({ x, (double)(signal)f(x) });
1680 }
1681 }
1682 }
1683
1684 template<typename RETURN, typename ARG>
1685 void plot(RETURN(*f)(ARG), const Axis& x_axis) {
1686 constexpr int size = SIZE > 1024 ? 1024 : SIZE;
1687
1688 if (function != (void*)f) {
1689 clear();
1690 function = (void*)f;
1691 hash = 0;
1692 double x = 0;
1693 const double dx = x_axis.range() / size;
1694 for (int i = 0; i <= size; i++) {
1695 x = x_axis.min + i * dx;
1696 add({ x, (double)(signal)f((float)x) });
1697 }
1698 }
1699 }
1700
1701 bool operator==(const Series& in) const {
1702 if (count != in.count) return false;
1703 for (unsigned int i = 0; i < count; i++)
1704 if (items[i].x != in.items[i].x || items[i].y != in.items[i].y)
1705 return false;
1706 return true;
1707 }
1708
1709 bool operator!=(const Series& in) const {
1710 return !operator==(in);
1711 }
1712
1713 void clear() {
1714 function = nullptr;
1715 Array::clear();
1716 }
1717
1718 using Input::input;
1719 void input() override {
1720 add(in);
1721 }
1722 };
1723
1724 /// Graph axis
1725 struct Axis {
1726 double min = 0, max = 0;
1727 bool valid() const { return max != min; }
1728 double range() const { return max - min; }
1729 bool contains(double value) const { return value >= min && value <= max; }
1730 void clear() { min = max = 0; }
1731
1732 void from(const Series& series, double Point::* axis) {
1733 if (!series.count) return;
1734 int points = 0;
1735 for (unsigned int p = 0; p < series.count; p++) {
1736 const Point& pt = series[p];
1737 if (pt.valid() && !::isinf(pt.*axis)) {
1738 if (!points || pt.*axis < min) min = pt.*axis;
1739 if (!points || pt.*axis > max) max = pt.*axis;
1740 points++;
1741 }
1742 }
1743 if (std::abs(max) < 0.0000000001) max = 0;
1744 if (std::abs(min) < 0.0000000001) min = 0;
1745 if (std::abs(max) > 1000000000.0) max = 0;
1746 if (std::abs(min) > 1000000000.0) min = 0;
1747 if (min > max) max = min = 0;
1748 }
1749 };
1750
1751 /// Graph axes (x/y)
1752 struct Axes {
1754 bool valid() const { return x.valid() && y.valid(); }
1755 void clear() { x = { 0,0 }; y = { 0,0 }; }
1756 bool contains(const Point& pt) const { return x.contains(pt.x) && y.contains(pt.y); }
1757 };
1758
1759 void clear() {
1760 dirty = true;
1761 axes.clear();
1762 for (int s = 0; s < GRAPH_SERIES; s++)
1763 data[s].clear();
1764 data.clear();
1765 }
1766
1767 /// @cond
1768 bool isActive() const {
1769 if (data.count)
1770 return true;
1771 for (int s = 0; s < GRAPH_SERIES; s++)
1772 if (data[s].count)
1773 return true;
1774 return false;
1775 }
1776 /// @endcond
1777
1778 /// Graph data
1779 struct Data : public Array<Series, GRAPH_SERIES> {
1780 using Array<Series, GRAPH_SERIES>::items;
1781
1782 Series* find(void* function) {
1783 for (int s = 0; s < GRAPH_SERIES; s++)
1784 if (this->operator[](s).function == function)
1785 return &items[s];
1786 return nullptr;
1787 }
1788 };
1789
1790 Graph& operator()(double min, double max) {
1791 dirty = true;
1792 axes.x.min = min; axes.x.max = max;
1793 return *this;
1794 }
1795
1796 Graph::Series& operator[](int index) {
1797 dirty = true;
1798 return data[index];
1799 }
1800
1801 const Graph::Series& operator[](int index) const {
1802 return data[index];
1803 }
1804
1805 Graph& operator()(double x_min, double x_max, double y_min, double y_max) {
1806 dirty = true;
1807 axes.x.min = x_min; axes.x.max = x_max;
1808 axes.y.min = y_min; axes.y.max = y_max;
1809 return *this;
1810 }
1811
1813 dirty = true;
1814 return data[0];
1815 }
1816
1817 /// Plot the given Function
1818 template<typename SIGNAL, typename... Args>
1819 void plot(Generic::Function<SIGNAL, Args...>& function) {
1820 Graph::Series* series = Graph::data.find((void*)function);
1821 if (!series)
1822 series = Graph::data.add();
1823 if (series) {
1824 dirty = true;
1825 if (!axes.x.valid())
1826 axes.x = { -1, 1 };
1828 }
1829 }
1830
1831 /// Plot the given function of x
1832 template<typename TYPE>
1833 void plot(TYPE(*function)(TYPE)) {
1834 Graph::Series* series = Graph::data.find((void*)function);
1835 if (!series)
1836 series = Graph::data.add();
1837 if (series) {
1838 dirty = true;
1839 if (!axes.x.valid())
1840 axes.x = { -1, 1 };
1842 }
1843 }
1844
1845 /// Plot the given function for x plus additional arguments
1846 template<typename FUNCTION, typename... VALUES>
1847 void plot(FUNCTION f, VALUES... values) {
1848 thread_local static Function fun(f);
1849 Graph::Series* series = Graph::data.find((void*)fun);
1850 if (!series)
1851 series = Graph::data.add();
1852 if (series) {
1853 dirty = true;
1854 if (!axes.x.valid())
1855 axes.x = { -1, 1 };
1856 series->plot(fun.with(values...), axes.x);
1857 }
1858 }
1859
1860 /// Add a data point (incrementing x)
1861 template<typename TYPE>
1862 void add(TYPE y) { data[0].add(y); dirty = true; }
1863 /// Add a data point
1864 void add(const Point pt) { data[0].add(pt); dirty = true; }
1865
1866 /// Add a data point (incrementing x)
1867 template<typename TYPE>
1868 Graph& operator+=(TYPE y) { add(y); return *this; }
1869 /// Add a data point
1870 Graph& operator+=(const Point pt) { add(pt); return *this; }
1871
1872 /// Plot the given function of x
1873 template<typename TYPE>
1874 Graph& operator=(TYPE(*function)(TYPE)) {
1875 plot(function);
1876 return *this;
1877 }
1878
1879 /// Plot the given data points
1880 Graph& operator=(std::initializer_list<Point> values) {
1881 clear(); return operator+=(values);
1882 }
1883
1884 /// Plot the given data points
1885 Graph& operator+=(std::initializer_list<Point> values) {
1886 for (const auto& value : values)
1887 add(value);
1888 return *this;
1889 }
1890
1891 /// Plot the given function for x plus additional arguments
1892 template<typename... Args> Graph& operator<<(Function<Args...>& function) {
1893 plot(function.with());
1894 return *this;
1895 }
1896
1897 template<typename TYPE> Graph& operator<<(TYPE& in) { add(in); return *this; } // with processing
1898 template<typename TYPE> Graph& operator<<(const TYPE& in) { add(in); return *this; } // without/after processing
1899
1900 // returns the user-defined axes
1901 const Axes& getAxes() const { return axes; }
1902
1903 // calculates axes based on data
1904 void getAxes(Axes& axes) const {
1905 if (!axes.x.valid()) {
1906 axes.x.clear();
1907 for (int s = 0; s < GRAPH_SERIES; s++)
1908 axes.x.from(data[s], &Point::x);
1909 if (!axes.y.valid() && axes.y.max != 0)
1910 axes.y.min = 0;
1911 }
1912 if (!axes.y.valid()) {
1913 axes.y.clear();
1914 for (int s = 0; s < GRAPH_SERIES; s++)
1915 axes.y.from(data[s], &Point::y);
1916 if (!axes.y.valid() && axes.y.max != 0)
1917 axes.y.min = 0;
1918 }
1919 }
1920
1921 const Data& getData() const { return data; }
1922 bool isDirty() const { return dirty; }
1923 void setDirty(bool dirty) { Graph::dirty = dirty; }
1924
1925 void truncate(unsigned int count) {
1926 if (count < data.count)
1927 data.count = count;
1928
1929 for (int s = 0; s < GRAPH_SERIES; s++)
1930 if (count < data[s].count)
1931 data[s].count = count;
1932 }
1933
1934 protected:
1937 bool dirty = false;
1938 };
1939
1940 template<int SIZE>
1941 inline typename Graph<SIZE>::Series& Graph<SIZE>::Point::operator>>(Graph<SIZE>::Series& series) {
1942 series.add(*this);
1943 return series;
1944 }
1945
1946 /// Audio oscillator object (output)
1947 template<typename SIGNAL>
1948 struct Oscillator : public Generator<SIGNAL> {
1949 protected:
1950 Phase increment; // phase increment (per sample, in seconds or samples)
1951 Phase position = 0; // phase position (in radians or wavetable size)
1952 public:
1953 Frequency frequency = 1000.f; // fundamental frequency of oscillator (in Hz)
1954 Phase offset = 0; // phase offset (in radians - e.g. for modulation)
1955
1956 virtual ~Oscillator() { }
1957 virtual void reset() { position = 0; }
1958
1959 using Generator<SIGNAL>::set;
1960 virtual void set(param frequency) {
1961 Oscillator::frequency = frequency;
1962 increment = frequency * 2.f * pi.f / fs;
1963 }
1964
1965 virtual void set(param frequency, param phase) {
1966 position = phase;
1967 set(frequency);
1968 }
1969
1970 virtual void set(param frequency, relative phase) {
1971 set(frequency);
1972 set(phase);
1973 }
1974
1975 virtual void set(relative phase) {
1976 offset = phase * (2 * pi);
1977 }
1978 };
1979 }
1980
1981 /// Audio input object (mono)
1982 struct Input : Generic::Input<signal> { };
1983 /// Audio output object (mono)
1984 struct Output : Generic::Output<signal> { };
1985 /// Signal generator object (mono)
1987 /// Signal modifier object (mono input-output)
1988 struct Modifier : public Generic::Modifier<signal> { };
1989 /// Audio oscillator object (mono output)
1991
1992 /// @cond
1993 template <typename TYPE, typename SIGNAL>
1994 using GeneratorOrModifier = typename std::conditional<std::is_base_of<Generator, TYPE>::value, Generic::Generator<SIGNAL>,
1995 typename std::conditional<std::is_base_of<Modifier, TYPE>::value, Generic::Modifier<SIGNAL>, void>::type>::type;
1996 /// @endcond
1997
1998 /// A parallel bank of multiple audio objects
1999 template<typename TYPE, int COUNT>
2000 struct Bank : public GeneratorOrModifier<TYPE, signals<COUNT>> {
2001 using GeneratorOrModifier<TYPE, signals<COUNT>>::in;
2002 using GeneratorOrModifier<TYPE, signals<COUNT>>::out;
2003
2004 TYPE items[COUNT];
2005
2006 TYPE& operator[](int index) { return items[index]; }
2007 const TYPE& operator[](int index) const { return items[index]; }
2008
2009 template<typename... Args>
2010 void set(Args... args) {
2011 for (int n = 0; n < COUNT; n++)
2012 items[n].set(args...);
2013 }
2014
2015 void input() override {
2016 for (int n = 0; n < COUNT; n++)
2017 in[n] >> items[n];
2018 }
2019
2020 void process() override {
2021 for (int n = 0; n < COUNT; n++)
2022 items[n] >> out[n];
2023 }
2024 };
2025
2026 /// Applies a function to a signal (input-output)
2027 template<typename... Args>
2028 struct Function : public Generic::Function<signal, Args...> {
2029
2030 //static float Identity(float x) { return x; }
2031
2032 //Function() : Generic::Function<signal, float>([](float x) -> float { return x; }) { }
2033
2034 Function() : Generic::Function<signal, Args...>(nullptr) { }
2035
2036 Function(std::function<float(Args...)> function) : Generic::Function<signal, Args...>(function) { }
2037
2038 using Generic::Function<signal, Args...>::operator>>;
2039 };
2040
2041 /// A line graph plotter
2042 struct Graph : public Generic::Graph<GRAPH_SIZE> {
2043 using Generic::Graph<GRAPH_SIZE>::operator=;
2044 using Generic::Graph<GRAPH_SIZE>::plot;
2045
2046 /// Plot the given function for x plus additional arguments
2047 template<typename... Args> Graph& operator<<(Function<Args...>& function) {
2048 plot(function.with());
2049 return *this;
2050 }
2051 };
2052
2053 /// @cond
2054 struct GraphPtr {
2055 std::unique_ptr<Graph> ptr;
2056
2057 void check() {
2058 if (ptr.get() == nullptr)
2059 ptr = std::make_unique<Graph>();
2060 }
2061
2062 Graph* operator->() { check(); return (klang::Graph*)ptr.get(); }
2063 operator Graph* () { check(); return (klang::Graph*)ptr.get(); }
2064 operator Graph& () { check(); return *(klang::Graph*)ptr.get(); }
2065
2066 void clear() { check(); ptr->clear(); }
2067 bool isActive() const { return ptr ? ptr->isActive() : false; }
2068
2069 Graph& operator()(double min, double max) { check(); return (Graph&)ptr->operator()(min, max); }
2070
2071 Graph::Series& operator[](int index) { check(); return ptr->operator[](index); }
2072 const Graph::Series& operator[](int index) const { static const Graph::Series none = Graph::Series(); return ptr ? ptr->operator[](index) : none; }
2073
2074 Graph& operator()(double x_min, double x_max, double y_min, double y_max) { check(); return (Graph&)ptr->operator()(x_min, x_max, y_min, y_max); }
2075
2076 operator Graph::Series& () { check(); return ptr->operator Graph::Series& (); }
2077
2078 template<typename SIGNAL, typename... Args>
2079 void plot(Generic::Function<SIGNAL, Args...>& function) { check(); ((Graph*)(ptr.get()))->plot(function); }
2080
2081 template<typename TYPE>
2082 void plot(TYPE(*function)(TYPE)) { check(); ((Graph*)(ptr.get()))->plot(function); }
2083
2084 template<typename FUNCTION, typename... VALUES>
2085 void plot(FUNCTION f, VALUES... values) { check(); ((Graph*)(ptr.get()))->plot(f, values...); }
2086
2087 template<typename TYPE> void add(TYPE y) { check(); ptr->add(y); }
2088 void add(const Graph::Point pt) { check(); ptr->add(pt); }
2089
2090 template<typename TYPE> Graph& operator+=(TYPE y) { check(); return ptr->operator+=(y); }
2091 Graph& operator+=(const Graph::Point pt) { check(); return (Graph&)ptr->operator+=(pt); }
2092
2093 template<typename TYPE> Graph& operator=(TYPE(*function)(TYPE)) { check(); return (Graph&)ptr->operator=(function); }
2094
2095 Graph& operator=(std::initializer_list<Graph::Point> values) { check(); return (Graph&)ptr->operator=(values); }
2096 Graph& operator+=(std::initializer_list<Graph::Point> values) { check(); return (Graph&)ptr->operator+=(values); }
2097
2098 template<typename... Args> Graph& operator<<(Generic::Function<Args...>& function) { plot(function.with()); return *this; }
2099 template<typename TYPE> Graph& operator<<(TYPE& in) { add(in); return *this; } // with processing
2100 template<typename TYPE> Graph& operator<<(const TYPE& in) { add(in); return *this; } // without/after processing
2101
2102 const Graph::Axes& getAxes() const { static const Graph::Axes none; return ptr ? ptr->getAxes() : none; }
2103 void getAxes(Graph::Axes& axes) { check(); ptr->getAxes(axes); }
2104
2105 const Graph::Data& getData() { check(); return ptr->getData(); }
2106 bool isDirty() const { return ptr ? ptr->isDirty() : false; }
2107 void setDirty(bool dirty) { if (ptr) ptr->setDirty(dirty); }
2108
2109 void truncate(unsigned int count) { check(); ptr->truncate(count); }
2110 };
2111 /// @endcond
2112
2113
2114
2115 // deduction guide for functions
2116 template <typename... Args>
2117 Function(float(*)(Args...)) -> Function<Args...>;
2118
2119 //// deduction guide for functions
2120 //Function() -> Function<float>;
2121
2122 THREAD_LOCAL static GraphPtr graph;
2123
2124 template<typename SIGNAL, typename... Args>
2125 inline GraphPtr& Generic::Function<SIGNAL, Args...>::operator>>(klang::GraphPtr& graph) {
2126 graph.plot(*this);
2127 return graph;
2128 }
2129
2130 template<typename TYPE>
2131 static GraphPtr& operator>>(TYPE(*function)(TYPE), klang::GraphPtr& graph) {
2133 return graph;
2134 }
2135
2136 template<typename SIGNAL, typename... Args>
2137 inline Graph& Generic::Function<SIGNAL, Args...>::operator>>(klang::Graph& graph) {
2138 graph.plot(*this);
2139 return graph;
2140 }
2141
2142 template<typename TYPE>
2143 static Graph& operator>>(TYPE(*function)(TYPE), Graph& graph) {
2145 return graph;
2146 }
2147
2148 // syntax equivalence: a = b is the same as b >> a
2150 b >> *this;
2151 return *this;
2152 }
2153
2154 // supports summing of multiple outputs
2155 inline signal& signal::operator+=(Output& in) { // e.g. out += osc;
2156 value += signal(in);
2157 return *this;
2158 }
2159
2160 /// Square root function (audio object)
2161 inline static Function<float> sqrt(SQRTF);
2162 /// Absolute/rectify function (audio object)
2163 inline static Function<float> abs(FABS);
2164 /// Square function (audio object)
2165 inline static Function<float> sqr([](float x) -> float { return x * x; });
2166 /// Cube function (audio object)
2167 inline static Function<float> cube([](float x) -> float { return x * x * x; });
2168
2169 #define sqrt klang::sqrt // avoid conflict with std::sqrt
2170 #define abs klang::abs // avoid conflict with std::abs
2171
2172 /// Debug text output
2173 struct Console : public Text<16384> {
2174 static std::mutex _lock;
2175 THREAD_LOCAL static Text<16384> last;
2176 int length = 0;
2177
2178 void clear() {
2179 length = 0;
2180 string[0] = 0;
2181 }
2182
2183 Console& operator=(const char* in) {
2184 std::lock_guard<std::mutex> lock(_lock);
2185 length = std::min(capacity(), (int)strlen(in));
2186 memcpy(string, in, length);
2187 string[length] = 0;
2188 return *this;
2189 }
2190
2191 Console& operator=(const Console& in) {
2192 std::lock_guard<std::mutex> lock(_lock);
2193 length = std::min(capacity(), in.length);
2194 memcpy(string, in.string, length);
2195 string[length] = 0;
2196 return *this;
2197 }
2198
2199 Console& operator+=(const char* in) {
2200 std::lock_guard<std::mutex> lock(_lock);
2201 const int len = std::max(0, std::min(capacity() - length, (int)strlen(in)));
2202 memcpy(&string[length], in, len);
2203 length += len;
2204 string[length] = 0;
2205 memcpy(&last, in, len);
2206 last.string[len] = 0;
2207 return *this;
2208 }
2209
2210 bool hasText() const {
2211 return length != 0;
2212 }
2213
2214 int getText(char* buffer) {
2215 //if (!length) return 0;
2216 std::lock_guard<std::mutex> lock(_lock);
2217 const int _length = length;
2218 memcpy(buffer, string, length);
2219 buffer[length] = 0; // null terminator
2220 clear();
2221 return _length;
2222 }
2223 };
2224
2225 inline THREAD_LOCAL Text<16384> Console::last;
2226
2227#define PROFILE(func, ...) debug.print("%-16s = %fns\n", #func "(" #__VA_ARGS__ ")", debug.profile(1000, func, __VA_ARGS__));
2228
2229 /// The Klang debug interface
2230 struct Debug : Input {
2231
2232 /// Audio buffer for debug output
2233 struct Buffer : private buffer {
2234 using buffer::clear;
2235 using buffer::rewind;
2236 using buffer::operator++;
2237 using buffer::operator signal&;
2238
2239 Buffer() : buffer(16384) { }
2240
2241 enum Content {
2246 } content = Empty;
2247
2248 /* void attach(float* buffer, int size) {
2249 Debug::buffer = new klang::buffer(buffer, size);
2250 }
2251
2252 void detach() {
2253 klang::buffer* tmp = buffer;
2254 buffer = nullptr;
2255 delete tmp;
2256 }*/
2257
2258 bool active = false;
2259 int used = 0;
2260
2261 const float* get() {
2262 if (active) {
2263 active = false;
2264 return data();
2265 }
2266 else {
2267 return nullptr;
2268 }
2269 }
2270
2271 Buffer& operator+=(const signal in) {
2272 active = true;
2274 return *this;
2275 }
2276
2277 template<typename TYPE>
2278 Buffer& operator+=(TYPE& in) {
2279 active = true;
2280 buffer::operator+=(in);
2281 return *this;
2282 }
2283
2284 signal& operator>>(signal& destination) const {
2285 destination << *ptr;
2286 return destination;
2287 }
2288
2289 operator const signal& () const {
2290 return *ptr;
2291 }
2292 };
2293
2294 THREAD_LOCAL static Buffer buffer; // support multiple threads/instances
2295
2296 /// Debug console output
2298
2299 template <typename Func, typename... Args>
2300 inline static double profile(Func func, Args... args) {
2301 using namespace std::chrono;
2302
2304 func(args...);
2305 auto end = high_resolution_clock::now();
2306
2308 return (double)duration;
2309 }
2310
2311 template <typename Func, typename... Args>
2312 inline static double profile(int times, Func func, Args... args) {
2313 double sum = 0;
2314 while (times--) {
2315 sum += profile(func, args...);
2316 }
2317 return sum / 1000000.0;
2318 }
2319
2320 /// @cond
2321 struct Session {
2322 Session(float*, int size, Buffer::Content content) {
2323 //if (buffer) {
2324 //debug.attach(buffer, size);
2325 if (buffer.content != Buffer::Notes)
2326 buffer.clear(size);
2327 buffer.content = content;
2329 //}
2330 }
2331 ~Session() {
2332 //debug.detach();
2333 }
2334
2335 bool hasAudio() const {
2336 return buffer.active;
2337 }
2338 const float* getAudio() const {
2339 return buffer.get();
2340 }
2341 };
2342 /// @endcond
2343
2344 void print(const char* format, ...) {
2345 if (console.length < 10000) {
2346 THREAD_LOCAL static char string[1024] = { 0 };
2347 string[0] = 0;
2348 va_list args; // Initialize the variadic argument list
2349 va_start(args, format); // Start variadic argument processing
2350 vsnprintf(string, 1024, format, args); // Safely format the string into the buffer
2351 va_end(args); // Clean up the variadic argument list
2352 console += string;
2353 }
2354 }
2355
2356 void printOnce(const char* format, ...) {
2357 if (console.length < 1024) {
2358 THREAD_LOCAL static char string[1024] = { 0 };
2359 string[0] = 0;
2360 va_list args; // Initialize the variadic argument list
2361 va_start(args, format); // Start variadic argument processing
2362 vsnprintf(string, 1024, format, args); // Safely format the string into the buffer
2363 va_end(args); // Clean up the variadic argument list
2364
2365 if (console.last != string)
2366 console += string;
2367 }
2368 }
2369
2370 bool hasText() const {
2371 return console.hasText();
2372 }
2373
2374 int getText(char* buffer) {
2375 return console.getText(buffer);
2376 }
2377
2378 operator const signal& () const {
2379 return buffer.operator const klang::signal & ();
2380 }
2381
2382 using Input::input;
2383 void input() override {
2384 buffer += in;
2385 }
2386 };
2387
2388 //inline static Debug::Buffer& operator>>(const signal source, Debug& debug) {
2389 // return debug.buffer += source;
2390 //}
2391
2392 //template<typename TYPE>
2393 //inline static Debug::Buffer& operator>>(TYPE& source, Debug& debug) {
2394 // return debug.buffer += source;
2395 //}
2396
2397 static Debug debug;
2398 inline THREAD_LOCAL Debug::Buffer Debug::buffer; //
2399 inline std::mutex Console::_lock;
2400
2401#define FUNCTION(type) (void(*)(type, Result<type>&))[](type x, Result<type>& y)
2402
2403 /// @cond
2404 template <typename TYPE>
2405 struct Result {
2406 TYPE* y = nullptr;
2407 int i = 0;
2408 TYPE sum = 0;
2409
2410 Result(TYPE* array, int index) : y(&array[index]), i(index) { }
2411
2412 TYPE& operator[](int index) {
2413 return *(y + index);
2414 }
2415
2416 operator TYPE const () { return *y; }
2417
2418 Result& operator=(const TYPE& in) {
2419 *y = in;
2420 return *this;
2421 }
2422
2423 TYPE& operator++(int) { i++; return *++y; }
2424 };
2425 /// @endcond
2426
2427 /// Lookup table object
2428 template<typename TYPE, int SIZE>
2429 struct Table : public Array<TYPE, SIZE> {
2430 typedef Array<TYPE, SIZE> Array;
2431 typedef Result<TYPE> Result;
2432
2433 using Array::add;
2434
2435 // single argument
2436 Table(TYPE(*function)(TYPE)) {
2437 for (int x = 0; x < SIZE; x++)
2438 add(function(x));
2439 }
2440
2441 // double argument
2442 Table(void(*function)(TYPE, TYPE), TYPE arg) {
2443 Array::count = SIZE;
2444 for (int x = 0; x < SIZE; x++)
2445 Array::items[x] = function(x, arg);
2446 }
2447
2448 // single argument (enhanced)
2449 Table(void(*function)(TYPE x, Result& y)) {
2450 Array::count = SIZE;
2451 Result y(Array::items, 0);
2452 for (int x = 0; x < SIZE; x++) {
2453 function((TYPE)x, y);
2454 y.sum += Array::items[x];
2455 y++;
2456 }
2457 }
2458
2459 Table(std::initializer_list<TYPE> values) {
2460 for (TYPE value : values)
2461 add(value);
2462 }
2463
2464 using Array::operator[];
2465 TYPE operator[](float index) {
2466 if (index < 0) return Array::items[0];
2467 else if (index >= (SIZE - 1)) return Array::items[SIZE - 1];
2468 else {
2469 const float x = std::floor(index);
2470 const int i = int(x);
2471 const float dx = index - x;
2472 const float dy = Array::items[i + 1] - Array::items[i];
2473 return Array::items[i] + dx * dy;
2474 }
2475 }
2476 };
2477
2478 /// Audio delay object
2479 template<int SIZE>
2480 struct Delay : public Modifier {
2481 using Modifier::in;
2482 using Modifier::out;
2483
2484 buffer buffer;
2485 float time = 1;
2486 int position = 0;
2487
2488 Delay() : buffer(SIZE + 1, 0) { clear(); }
2489
2490 void clear() {
2491 buffer.clear();
2492 }
2493
2494 //void operator<<(const signal& input) override {
2495 void input() override {
2496 buffer++ = in;
2497 position++;
2498 if (buffer.finished()) {
2499 buffer.rewind();
2500 position = 0;
2501 }
2502 }
2503
2504 signal tap(int delay) const {
2505 int read = (position - 1) - delay;
2506 if (read < 0)
2507 read += SIZE;
2508 return buffer[read];
2509 }
2510
2511 signal tap(float delay) const {
2512 float read = (float)(position - 1) - delay;
2513 if (read < 0.f)
2514 read += SIZE;
2515
2516 const float f = floor(read);
2517 delay = read - f;
2518
2519 const int i = (int)read;
2520 const int j = (i == (SIZE - 1)) ? 0 : (i + 1);
2521
2522 return buffer[i] * (1.f - delay) + buffer[j] * delay;
2523 }
2524
2525 virtual void process() override {
2526 out = tap(time);
2527 }
2528
2529 virtual void set(param delay) override {
2530 Delay::time = delay <= SIZE ? (float)delay : SIZE;
2531 }
2532
2533 template<typename TIME>
2534 signal operator()(TIME& delay) {
2535 if constexpr (std::is_integral_v<TIME>)
2536 return tap((int)delay);
2537 else if constexpr (std::is_floating_point_v<TIME>)
2538 return tap((float)delay);
2539 else
2540 return tap((signal)delay);
2541 }
2542
2543 template<typename TIME>
2544 signal operator()(const TIME& delay) {
2545 if constexpr (std::is_integral_v<TIME>)
2546 return tap((int)delay);
2547 else if constexpr (std::is_floating_point_v<TIME>)
2548 return tap((float)delay);
2549 else
2550 return tap((signal)delay);
2551 }
2552
2553 unsigned int max() const { return SIZE; }
2554 };
2555
2556 /// Wavetable-based oscillator
2557 class Wavetable : public Oscillator {
2558 using Oscillator::set;
2559 protected:
2560 buffer buffer;
2561 const int size;
2562 public:
2563 Wavetable(int size = 2048) : buffer(size), size(size) { }
2564
2565 template<typename TYPE>
2566 Wavetable(TYPE oscillator, int size = 2048) : buffer(size), size(size) {
2567 operator=(oscillator);
2568 }
2569
2570 signal& operator[](int index) {
2571 return buffer[index];
2572 }
2573
2574 template<typename TYPE>
2575 Wavetable& operator=(TYPE& oscillator) {
2576 oscillator.set(fs / size);
2577 for (int s = 0; s < size; s++)
2578 buffer[s] = oscillator;
2579 return *this;
2580 }
2581
2582 virtual void set(param frequency) override {
2583 Oscillator::frequency = frequency;
2584 increment = frequency * (size / fs);
2585 }
2586
2587 virtual void set(param frequency, param phase) override {
2588 position = phase * float(size);
2589 set(frequency);
2590 }
2591
2592 virtual void set(relative phase) override {
2593
2594 offset = phase * float(size);
2595 }
2596
2597 virtual void set(param frequency, relative phase) override {
2598 set(frequency);
2599 set(phase);
2600 }
2601
2602 void process() override {
2603 position += { increment, size };
2604 out = buffer[position + offset /*klang::increment(offset, size)*/];
2605 }
2606 };
2607
2608 /// Envelope object
2609 class Envelope : public Generator {
2610 using Generator::set;
2611
2612 public:
2613
2614 struct Follower;
2615
2616 /// Abstract envelope ramp type
2617 struct Ramp : public Generator {
2618 float target;
2619 float rate;
2620 bool active = false;
2621 public:
2622
2623 // Create a null ramp (full signal)
2624 Ramp(float value = 1.f) {
2625 setValue(value);
2626 }
2627
2628 // Create a ramp from start to target over time (in seconds)
2629 Ramp(float start, float target, float time) {
2630 setValue(start);
2631 setTarget(target);
2632 setTime(time);
2633 }
2634
2635 virtual ~Ramp() { }
2636
2637 // Is ramp currently processing (ramping)?
2638 bool isActive() const {
2639 return active;
2640 }
2641
2642 // Set a new target (retains rate)
2643 virtual void setTarget(float target) {
2644 Ramp::target = target;
2645 active = (out != target);
2646 }
2647
2648 // Immediately jump to value (disables ramp)
2649 virtual void setValue(float value) {
2650 out = value;
2651 Ramp::target = value;
2652 active = false;
2653 }
2654
2655 // Set rate of change (per sample)
2656 virtual void setRate(float rate) { Ramp::rate = rate; }
2657
2658 // Set rate of change (by duration)
2659 virtual void setTime(float time) { Ramp::rate = time ? 1.f / (time * fs) : 0; }
2660
2661 // Return the current output and advanced the ramp
2662 virtual signal operator++(int) = 0;
2663
2664 void process() override { /* do nothing -> only process on ++ */ }
2665 };
2666
2667 /// Linear envelope ramp (default)
2668 struct Linear : public Ramp {
2669
2670 // Return the current output and process the next
2671 signal operator++(int) override {
2672 const signal output = out;
2673
2674 if (active) {
2675 if (target > out) {
2676 out += rate;
2677 if (out >= target) {
2678 out = target;
2679 active = false;
2680 }
2681 }
2682 else {
2683 out -= rate;
2684 if (out <= target) {
2685 out = target;
2686 active = false;
2687 }
2688 }
2689 }
2690
2691 return output;
2692 }
2693 };
2694
2695 /// Envelope stage
2697 /// Envelope mode
2698 enum Mode { Time, Rate };
2699
2700 /// Envelope point (x,y)
2701 struct Point {
2702 float x, y;
2703
2704 Point() : x(0), y(0) { }
2705
2706 template<typename T1, typename T2>
2707 Point(T1 x, T2 y) : x(float(x)), y(float(y)) { }
2708 };
2709
2710 /// @cond
2711 // Linked-list of points (for inline initialisation)
2712 struct Points : public Point {
2713 Points(float x, float y) {
2714 Point::x = x;
2715 Point::y = y;
2716 next = NULL;
2717 }
2718 ~Points() {
2719 delete next;
2720 }
2721
2722 Points& operator()(float x, float y) {
2723 last().next = new Points(x, y);
2724 return *this;
2725 }
2726
2727 Points& last() {
2728 return next ? next->last() : *this;
2729 }
2730
2731 int count() const {
2732 return next ? 1 + next->count() : 1;
2733 }
2734
2735 Points* next;
2736 };
2737 /// @endcond
2738
2739 /// Envelope loop
2740 struct Loop {
2741 Loop(int from = -1, int to = -1) : start(from), end(to) {}
2742
2743 void set(int from, int to) { start = from; end = to; }
2744 void reset() { start = end = -1; }
2745
2746 bool isActive() const { return start != -1 && end != -1; }
2747
2749 int end;
2750 };
2751
2752 // Default Envelope (full signal)
2753 Envelope() : ramp(new Linear()) { set(Points(0.f, 1.f)); }
2754
2755 // Creates a new envelope from a list of points, e.g. Envelope env = Envelope::Points(0,1)(1,0);
2756 Envelope(const Points& points) : ramp(new Linear()) { set(points); }
2757
2758 // Creates a new envelope from a list of points, e.g. Envelope env = { { 0,1 }, { 1,0 } };
2759 Envelope(std::initializer_list<Point> points) : ramp(new Linear()) { set(points); }
2760
2761 // Creates a copy of an envelope from another envelope
2762 Envelope(const Envelope& in) : ramp(new Linear()) { set(in.points); }
2763
2764 virtual ~Envelope() { }
2765
2766 // Checks if the envelope is at a specified stage (Sustain, Release, Off)
2767 bool operator==(Stage stage) const { return Envelope::stage == stage; }
2768 bool operator!=(Stage stage) const { return Envelope::stage != stage; }
2769
2770 operator float() const { return out; }
2771
2772 // assign points (without recreating envelope)
2773 Envelope& operator=(std::initializer_list<Point> points) {
2774 set(points);
2775 return *this;
2776 }
2777
2778 // Sets the envelope based on an array of points
2779 void set(const std::vector<Point>& points) {
2780 Envelope::points = points;
2782 }
2783
2784 // Sets the envelope from a list of points, e.g. env.set( Envelope::Points(0,1)(1,0) );
2785 void set(const Points& point){
2786 points.clear();
2787
2788 const Points* pPoint = &point;
2789 while(pPoint){
2790 points.push_back(*pPoint);
2791 pPoint = pPoint->next;
2792 }
2793
2795 }
2796
2797 // Converts envelope points based on relative time to absolute time
2798 void sequence() {
2799 float time = 0.f;
2800 for(Point& point : points) {
2801 const float delta = point.x;
2802 time += delta + 0.00001f;
2803 point.x = time;
2804 }
2806 }
2807
2808 // Sets an envelope loop between two points
2809 void setLoop(int startPoint, int endPoint){
2810 if(startPoint >= 0 && endPoint < points.size())
2811 loop.set(startPoint, endPoint);
2812 }
2813
2814 // Retrieve value at time (in seconds)
2815 signal at(param time) const {
2816 if (points.empty()) return 0;
2817 Point last = { 0, points[0].y };
2818 for (const Point& point : points) {
2819 if (point.x >= time) {
2820 const float dx = point.x - last.x;
2821 const float dy = point.y - last.y;
2822 const float x = time - last.x;
2823 return dx == 0 ? last.y : (last.y + x * dy / dx);
2824 }
2825 last = point;
2826 }
2827 return points.back().y;
2828 }
2829
2830 // Resets the envelope loop
2833 if(stage == Sustain && (point+1) < points.size())
2835 }
2836
2837 // Sets the current stage of the envelope
2838 void setStage(Stage stage){ this->stage = stage; }
2839
2840 // Returns the current stage of the envelope
2841 const Stage getStage() const { return stage; }
2842
2843 // Returns the total length of the envelope (ignoring loops)
2844 float getLength() const { return points.size() ? points[points.size() - 1].x : 0.f; }
2845
2846 // Trigger the release of the envelope
2847 virtual void release(float time, float level = 0.f){
2848 stage = Release;
2849 setTarget({ time, level }, 0);
2850 //ramp->setTime(time);
2851 //ramp->setTarget(0.f);
2852 }
2853
2854 // Returns true if the envelope has finished (is off)
2855 bool finished() const {
2856 return getStage() == Stage::Off;
2857 }
2858
2859 // Prepare envelope to (re)start
2861 point = 0;
2862 timeInc = 1.0f / fs;
2864 stage = Sustain;
2865 if(points.size()){
2866 out = points[0].y;
2868 if(points.size() > 1)
2870 }else{
2871 out = 1.0f;
2872 ramp->setValue(1.0f);
2873 }
2874 }
2875
2876 // Scales the envelope duration to specified length
2877 void resize(float length){
2878 const float old_length = getLength();
2879 if(old_length == 0.0)
2880 return;
2881
2882 const float multiplier = length / (fs * old_length);
2883 std::vector<Point>::iterator point = points.begin();
2884 while(point != points.end()){
2885 point->x *= multiplier;
2886 point++;
2887 }
2888
2890 }
2891
2892 // Set the current envelope target
2893 void setTarget(const Point& point, float time = 0.0){
2894 (this->*setTargetFunction)(point, time);
2895 }
2896
2897 // Returns the output of the envelope and advances the envelope.
2899 out = (*ramp)++;
2900
2901 switch(stage){
2902 case Sustain:
2903 time += timeInc;
2904 if (!ramp->isActive()) { // envelop segment end reached
2905 if (loop.isActive() && (point + 1) >= loop.end) {
2906 point = loop.start;
2908 if (loop.start != loop.end)
2910 } else if ((point + 1) < points.size()) {
2911 if (mode() == Rate || time >= points[point + 1].x) { // reached target point
2912 point++;
2913 ramp->setValue(points[point].y); // make sure exact value is set
2914
2915 if ((point + 1) < points.size()) // new target point?
2917 }
2918 } else {
2919 stage = Off;
2920 }
2921 } break;
2922 case Release:
2923 if (!ramp->isActive()) //if(out == 0.0)
2924 stage = Off;
2925 break;
2926 case Off:
2927 break;
2928 }
2929
2930 return out;
2931 }
2932
2933 void process() override { /* do nothing -> only process on ++ */
2934 out = *ramp;
2935 }
2936
2937 // Retrieve a specified envelope point (read-only)
2938 const Point& operator[](int point) const {
2939 return points[point];
2940 }
2941
2942 // Set the Ramp class (default: Envelope::Linear)
2943 void set(Ramp* ramp) {
2944 Envelope::ramp = std::shared_ptr<Ramp>(ramp);
2946 }
2947
2948 void setMode(Mode mode) {
2949 if (mode == Time)
2951 else
2953 }
2954
2956
2957 protected:
2958
2959 void (Envelope::* setTargetFunction)(const Point& point, float time) = &Envelope::setTargetTime;
2960
2961 void setTargetTime(const Point& point, float time = 0.0) {
2962 this->time = time;
2963 ramp->setTarget(point.y);
2964 ramp->setRate(abs(point.y - ramp->out) / ((point.x - time) * fs));
2965 }
2966
2967 void setTargetRate(const Point& point, float rate = 0.0) {
2968 this->time = 0;
2969 if (point.x == 0) {
2970 ramp->setValue(point.y);
2971 } else {
2972 ramp->setTarget(point.y);
2973 ramp->setRate(point.x);
2974 }
2975 }
2976
2977 std::vector<Point> points;
2979
2983
2984 std::shared_ptr<Ramp> ramp;
2985 };
2986
2987 /// Attack-Decay-Sustain-Release Envelope
2988 struct ADSR : public Envelope {
2989 private:
2990 using Envelope::Follower;
2991 public:
2993
2994 enum Mode { Time, Rate } mode = Time;
2995
2996 ADSR() { set(0.5, 0.5, 1, 0.5); }
2997
2998 void set(param attack, param decay, param sustain, param release) override {
2999 A = attack + 0.005f;
3000 D = decay + 0.005f;
3001 S = sustain;
3002 R = release + 0.005f;
3003
3004 points.resize(3);
3005 points[0] = { 0, 0 };
3006 points[1] = { A, 1 };
3007 points[2] = { A + D, S };
3008
3010 setLoop(2, 2);
3011 }
3012
3013 void release(float time = 0.f, float level = 0.f) override {
3014 Envelope::release(time ? time : float(R), level);
3015 }
3016
3017 bool operator==(Envelope::Stage stage) const {
3018 return getStage() == stage;
3019 }
3020 };
3021
3022 /// FM operator
3023 template<class OSCILLATOR>
3024 struct Operator : public OSCILLATOR, public Input {
3027
3028 Operator& operator()(param f) { OSCILLATOR::set(f); return *this; }
3029 Operator& operator()(param f, relative phase) { OSCILLATOR::set(f, phase); return *this; }
3030 Operator& operator()(relative phase) { OSCILLATOR::set(phase); return *this; }
3031
3032 virtual Operator& operator=(const Envelope::Points& points) {
3033 env = points;
3034 return *this;
3035 }
3036
3037 virtual Operator& operator=(const Envelope& points) {
3038 env = points;
3039 return *this;
3040 }
3041
3042 Operator& operator*(float amp) {
3043 Operator::amp = amp;
3044 return *this;
3045 }
3046
3047 virtual void process() override {
3048 OSCILLATOR::set(+in);
3050 OSCILLATOR::out *= env++ * amp;
3051 }
3052
3053 inline Operator& operator>>(Operator& carrier) {
3054 carrier << *this;
3055 return carrier;
3056 }
3057 };
3058
3059 template<class OSCILLATOR>
3060 inline const signal& operator>>(klang::signal modulator, Operator<OSCILLATOR>& carrier) {
3061 carrier << modulator;
3062 return carrier;
3063 }
3064
3065 /// Base class for UI / MIDI controll
3066 struct Controller {
3067 protected:
3068 virtual event control(int index, float value) { };
3069 virtual event preset(int index) { };
3070 virtual event midi(int status, int byte1, int byte2) { };
3071 public:
3072 virtual void onControl(int index, float value) { control(index, value); };
3073 virtual void onPreset(int index) { preset(index); };
3074 virtual void onMIDI(int status, int byte1, int byte2) { midi(status, byte1, byte2); }
3075 };
3076
3077 /// Base class for mini-plugin
3078 struct Plugin : public Controller {
3079 virtual ~Plugin() { }
3080
3083 };
3084
3085 /// Effect mini-plugin (mono)
3086 struct Effect : public Plugin, public Modifier {
3087 virtual ~Effect() { }
3088
3089 virtual void prepare() { };
3090 virtual void process() { out = in; }
3091 virtual void process(buffer buffer) {
3092 prepare();
3093 while (!buffer.finished()) {
3094 input(buffer);
3095 process();
3096 buffer++ = out;
3098 }
3099 }
3100 };
3101
3102 /// Base class for synthesiser notes
3103 template<class SYNTH>
3104 class NoteBase : public Controller {
3105 SYNTH* synth;
3106
3107 class Controls {
3108 klang::Controls* controls = nullptr;
3109 public:
3110 Controls& operator=(klang::Controls& controls) { Controls::controls = &controls; return *this; }
3111 signal& operator[](int index) { return controls->operator[](index).operator signal&(); }
3112 const signal& operator[](int index) const { return controls->operator[](index).operator const signal&(); }
3113 unsigned int size() { return controls ? controls->size() : 0; }
3114 };
3115
3116 protected:
3117 virtual event on(Pitch p, Velocity v) { }
3118 virtual event off(Velocity v = 0) { stage = Off; }
3119
3120 SYNTH* getSynth() { return synth; }
3121 public:
3124 Controls controls;
3125
3126 NoteBase() : synth(nullptr) { }
3127 virtual ~NoteBase() { }
3128
3129 void attach(SYNTH* synth) {
3130 NoteBase::synth = synth;
3132 init();
3133 }
3134
3135 virtual void init() { }
3136
3137 virtual void start(Pitch p, Velocity v) {
3138 stage = Onset;
3139 pitch = p;
3140 velocity = v;
3142 stage = Sustain;
3143 }
3144
3145 virtual bool release(Velocity v = 0) {
3146 if (stage == Off)
3147 return true;
3148
3149 if (stage != Release) {
3150 stage = Release;
3151 off(v);
3152 }
3153
3154 return stage == Off;
3155 }
3156
3157 virtual bool stop(Velocity v = 0) {
3158 stage = Off;
3159 return true;
3160 }
3161
3162 bool finished() const { return stage == Off; }
3163
3164 enum Stage { Onset, Sustain, Release, Off } stage = Off;
3165
3166 virtual void controlChange(int controller, int value) { midi(0xB0, controller, value); };
3167 };
3168
3169 struct Synth;
3170
3171 /// Synthesiser note (mono)
3172 struct Note : public NoteBase<Synth>, public Generator {
3173 virtual void prepare() { }
3174 virtual void process() override = 0;
3175 virtual bool process(buffer buffer) {
3176 prepare();
3177 while (!buffer.finished()) {
3178 process();
3179 buffer++ = out;
3181 }
3182 return !finished();
3183 }
3184 virtual bool process(buffer* buffer) {
3185 return process(buffer[0]);
3186 }
3187 };
3188
3189 /// Synthesiser note array
3190 template<class SYNTH, class NOTE = Note>
3191 struct Notes : Array<NOTE*, 128> {
3192 SYNTH* synth;
3193 typedef Array<NOTE*, 128> Array;
3194 using Array::items;
3195 using Array::count;
3196
3197 Notes(SYNTH* synth) : synth(synth) {
3198 for (int n = 0; n < 128; n++)
3199 items[n] = nullptr;
3200 }
3201 virtual ~Notes();
3202
3203 template<class TYPE>
3204 void add(int count) {
3205 for (int n = 0; n < count; n++) {
3206 TYPE* note = new TYPE();
3207 note->attach(synth);
3208 Array::add(note);
3209 }
3210 }
3211
3212 // returns index of a 'free' note (stealing oldest, if required)
3213 unsigned int noteOns = 0; // number of NoteOn events processed
3214 unsigned int noteStart[128] = { 0 }; // track age of notes (for note stealing)
3215
3216 int assign(){
3217 // favour unused voices
3218 for (int i = 0; i < count; i++) {
3219 if (items[i]->stage == NOTE::Off){
3220 noteStart[i] = noteOns++;
3221 return i;
3222 }
3223 }
3224
3225 // no free notes => steal oldest released note?
3226 int oldest = -1;
3227 unsigned int oldest_start = 0;
3228 for (int i = 0; i < count; i++) {
3229 if (items[i]->stage == NOTE::Release) {
3230 if(oldest == -1 || noteStart[i] < oldest_start){
3231 oldest = i;
3233 }
3234 }
3235 }
3236 if(oldest != -1){
3238 return oldest;
3239 }
3240
3241 // no available released notes => steal oldest playing note
3242 oldest = -1;
3243 oldest_start = 0;
3244 for (int i = 0; i < count; i++) {
3245 if(oldest == -1 || noteStart[i] < oldest_start){
3246 oldest = i;
3248 }
3249 }
3251 return oldest;
3252 }
3253 };
3254
3255 /// Synthesiser object (mono)
3256 struct Synth : public Effect {
3257 typedef Note Note;
3258
3260
3261 Synth() : notes(this) { }
3262 virtual ~Synth() { }
3263
3264 //virtual void presetLoaded(int preset) { }
3265 //virtual void optionChanged(int param, int item) { }
3266 //virtual void buttonPressed(int param) { };
3267
3268 int indexOf(Note* note) const {
3269 int index = 0;
3270 for (const auto* n : notes.items) {
3271 if (note == n)
3272 return index;
3273 index++;
3274 }
3275 return -1; // not found
3276 }
3277
3278 // pass to synth and notes
3279 virtual event onControl(int index, float value) override {
3280 control(index, value);
3281 for (unsigned int n = 0; n < notes.count; n++)
3282 notes[n]->onControl(index, value);
3283 };
3284
3285 // pass to synth and notes
3286 virtual event onPreset(int index) override {
3287 preset(index);
3288 for (unsigned int n = 0; n < notes.count; n++)
3289 notes[n]->onPreset(index);
3290 };
3291 };
3292
3293 template<class SYNTH, class NOTE>
3294 inline Notes<SYNTH, NOTE>::~Notes() {
3295 for (unsigned int n = 0; n < count; n++) {
3296 NOTE* tmp = items[n];
3297 items[n] = nullptr;
3298 delete tmp;
3299 }
3300 }
3301
3302 namespace Mono { using namespace klang; }
3303 namespace mono { using namespace klang; }
3304
3305 /// Objects supporting stereo audio functionality.
3306 namespace Stereo {
3307 /// Stereo audio signal
3308 typedef signals<2> signal;
3309
3310 /// Stereo sample frame
3311 struct frame {
3314
3315 frame(mono::signal& left, mono::signal& right) : l(left), r(right) { }
3316 frame(signal& signal) : l(signal.l), r(signal.r) { }
3317
3318 frame& operator+=(const frame& x) { l += x.l; r += x.r; return *this; }
3319 frame& operator-=(const frame& x) { l -= x.l; r -= x.r; return *this; }
3320 frame& operator*=(const frame& x) { l *= x.l; r *= x.r; return *this; }
3321 frame& operator/=(const frame& x) { l /= x.l; r /= x.r; return *this; }
3322
3323 frame& operator+=(const signal x) { l += x.l; r += x.r; return *this; }
3324 frame& operator-=(const signal x) { l -= x.l; r -= x.r; return *this; }
3325 frame& operator*=(const signal x) { l *= x.l; r *= x.r; return *this; }
3326 frame& operator/=(const signal x) { l /= x.l; r /= x.r; return *this; }
3327
3328 frame& operator+=(const mono::signal x) { l += x; r += x; return *this; }
3329 frame& operator-=(const mono::signal x) { l -= x; r -= x; return *this; }
3330 frame& operator*=(const mono::signal x) { l *= x; r *= x; return *this; }
3331 frame& operator/=(const mono::signal x) { l /= x; r /= x; return *this; }
3332
3333 frame& operator+=(float x) { l += x; r += x; return *this; }
3334 frame& operator-=(float x) { l -= x; r -= x; return *this; }
3335 frame& operator*=(float x) { l *= x; r *= x; return *this; }
3336 frame& operator/=(float x) { l /= x; r /= x; return *this; }
3337
3338 frame& operator+=(double x) { l += (float)x; r += (float)x; return *this; }
3339 frame& operator-=(double x) { l -= (float)x; r -= (float)x; return *this; }
3340 frame& operator*=(double x) { l *= (float)x; r *= (float)x; return *this; }
3341 frame& operator/=(double x) { l /= (float)x; r /= (float)x; return *this; }
3342
3343 frame& operator+=(int x) { l += (float)x; r += (float)x; return *this; }
3344 frame& operator-=(int x) { l -= (float)x; r -= (float)x; return *this; }
3345 frame& operator*=(int x) { l *= (float)x; r *= (float)x; return *this; }
3346 frame& operator/=(int x) { l /= (float)x; r /= (float)x; return *this; }
3347
3348 signal operator+(const signal x) const { return { l + x.l, r + x.r }; }
3349 signal operator-(const signal x) const { return { l - x.l, r - x.r }; }
3350 signal operator*(const signal x) const { return { l * x.l, r * x.r }; }
3351 signal operator/(const signal x) const { return { l / x.l, r / x.r }; }
3352
3353 signal operator+(const mono::signal x) const { return { l + x, r + x }; }
3354 signal operator-(const mono::signal x) const { return { l - x, r - x }; }
3355 signal operator*(const mono::signal x) const { return { l * x, r * x }; }
3356 signal operator/(const mono::signal x) const { return { l / x, r / x }; }
3357
3358 signal operator+(float x) const { return { l + x, r + x }; }
3359 signal operator-(float x) const { return { l - x, r - x }; }
3360 signal operator*(float x) const { return { l * x, r * x }; }
3361 signal operator/(float x) const { return { l / x, r / x }; }
3362
3363 signal operator+(double x) const { return { l + (float)x, r + (float)x }; }
3364 signal operator-(double x) const { return { l - (float)x, r - (float)x }; }
3365 signal operator*(double x) const { return { l * (float)x, r * (float)x }; }
3366 signal operator/(double x) const { return { l / (float)x, r / (float)x }; }
3367
3368 signal operator+(int x) const { return { l + (float)x, r + (float)x }; }
3369 signal operator-(int x) const { return { l - (float)x, r - (float)x }; }
3370 signal operator*(int x) const { return { l * (float)x, r * (float)x }; }
3371 signal operator/(int x) const { return { l / (float)x, r / (float)x }; }
3372
3373 frame& operator=(const signal& signal) {
3374 l = signal.l;
3375 r = signal.r;
3376 return *this;
3377 }
3378
3379 mono::signal mono() const {
3380 return (l + r) * 0.5f;
3381 }
3382 };
3383
3384 /// Audio input object (stereo)
3385 struct Input : Generic::Input<signal> { virtual ~Input() {} };
3386 /// Audio output object (stereo)
3387 struct Output : Generic::Output<signal> { virtual ~Output() {} };
3388 /// Signal generator object (stereo output)
3389 struct Generator : Generic::Generator<signal> { virtual ~Generator() {} };
3390 /// Signal modifier object (stereo, input-output)
3391 struct Modifier : Generic::Modifier<signal> { virtual ~Modifier() {} };
3392 /// Audio oscillator object (stereo, output)
3393 struct Oscillator : Generic::Oscillator<signal> { virtual ~Oscillator() {} };
3394
3395 //inline Modifier& operator>>(signal input, Modifier& modifier) {
3396 // modifier << input;
3397 // return modifier;
3398 //}
3399
3400 /// Stereo audio buffer
3401 // interleaved access to non-interleaved stereo buffers
3402 struct buffer {
3403 typedef Stereo::signal signal;
3405
3406 buffer(const buffer& buffer) : left(buffer.left), right(buffer.right) { rewind(); }
3407 buffer(mono::buffer& left, mono::buffer& right) : left(left), right(right) { rewind(); }
3408
3409 operator const signal() const { return { left, right }; }
3410 operator frame () { return { left, right }; }
3411 bool finished() const { return left.finished() && right.finished(); }
3412 frame operator++(int) { return { left++, right++ }; }
3413
3414 frame operator=(const signal& in) {
3415 return { left = in.l, right = in.r };
3416 }
3417
3418 buffer& operator=(const buffer& in) {
3419 left = in.left;
3420 right = in.right;
3421 return *this;
3422 }
3423
3424 buffer& operator+=(const signal& in) {
3425 left += in.l;
3426 right += in.r;
3427 return *this;
3428 }
3429
3430 buffer& operator=(const frame& in) { left = in.l; right = in.r; return *this; }
3431 buffer& operator+=(const frame& in) { left += in.l; right += in.r; return *this; }
3432 buffer& operator*=(const frame& in) { left *= in.l; right *= in.r; return *this; }
3433
3434 buffer& operator=(const mono::signal in) { left = in; right = in; return *this; }
3435 buffer& operator+=(const mono::signal in) { left += in; right += in;return *this; }
3436 buffer& operator*=(const mono::signal in) { left *= in; right *= in;return *this; }
3437
3438 frame operator[](int index) {
3439 return { left[index], right[index] };
3440 }
3441
3442 signal operator[](int index) const {
3443 return { left[index], right[index] };
3444 }
3445
3446 mono::buffer& channel(int index) {
3447 return index == 1 ? right : left;
3448 }
3449
3450 void clear() {
3453 }
3454
3455 void clear(int size) {
3456 left.clear(size);
3457 right.clear(size);
3458 }
3459
3460 void rewind() {
3463 }
3464 };
3465
3466 /// Stereo audio object adapter
3467 template<class TYPE>
3468 struct Bank : klang::Bank<TYPE, 2> { };
3469
3470 /// Audio delay object (stereo)
3471 template<int SIZE>
3472 struct Delay : Bank<klang::Delay<SIZE>> {
3473 using Bank<klang::Delay<SIZE>>::items;
3474 using Bank<klang::Delay<SIZE>>::in;
3475 using Bank<klang::Delay<SIZE>>::out;
3476
3477 void clear() {
3478 items[0].clear();
3479 items[1].clear();
3480 }
3481
3482 klang::Delay<SIZE> &l, &r;
3483 Delay<SIZE>() : l(items[0]), r(items[1]) { }
3484
3485 signal tap(int delay) const {
3486 int read = (items[0].position - 1) - delay;
3487 if (read < 0)
3488 read += SIZE;
3489 return { items[0].buffer[read], items[1].buffer[read] };
3490 }
3491
3492 signal tap(float delay) const {
3493 float read = (float)(items[0].position - 1) - delay;
3494 if (read < 0.f)
3495 read += SIZE;
3496
3497 const float f = floor(read);
3498 delay = read - f;
3499
3500 const int i = (int)read;
3501 const int j = (i == (SIZE - 1)) ? 0 : (i + 1);
3502
3503 return { items[0].buffer[i] * (1.f - delay) + items[0].buffer[j] * delay,
3504 items[1].buffer[i] * (1.f - delay) + items[1].buffer[j] * delay };
3505 }
3506
3507 virtual void process() override {
3508 out = tap(items[0].time);
3509 }
3510
3511 template<typename TIME>
3512 signal operator()(const TIME& delay) {
3513 if constexpr (std::is_integral_v<TIME>)
3514 return tap((int)delay);
3515 else if constexpr (std::is_floating_point_v<TIME>)
3516 return tap((float)delay);
3517 else if constexpr (std::is_same_v<TIME, signal>) // stereo signal (use for l/r delay times)
3518 return { items[0].tap(delay.l), items[1].tap(delay.r) };
3519 else
3520 return tap((klang::signal)delay); // else treat as single signal
3521 }
3522
3523 unsigned int max() const { return SIZE; }
3524 };
3525
3526 /// Stereo effect mini-plugin
3527 struct Effect : public Plugin, public Modifier {
3528 virtual ~Effect() { }
3529
3530 virtual void prepare() { };
3531 virtual void process() { out = in; };
3532 virtual void process(Stereo::buffer buffer) {
3533 prepare();
3534 while (!buffer.finished()) {
3535 input(buffer);
3536 process();
3537 buffer++ = out;
3539 }
3540 }
3541 };
3542
3543 struct Synth;
3544
3545 /// Base class for stereo synthesiser note
3546 struct Note : public NoteBase<Synth>, public Generator {
3547 //virtual signal output() { return 0; };
3548
3549 virtual void prepare() { }
3550 virtual void process() override = 0;
3551 virtual bool process(Stereo::buffer buffer) {
3552 prepare();
3553 while (!buffer.finished()) {
3554 process();
3555 buffer++ = out;
3556 }
3557 return !finished();
3558 }
3559 virtual bool process(mono::buffer* buffers) {
3560 buffer buffer = { buffers[0], buffers[1] };
3561 return process(buffer);
3562 }
3563 };
3564
3565 /// Synthesier mini-plugin (stereo)
3566 struct Synth : public Effect {
3567 typedef Stereo::Note Note;
3568
3569 /// Synthesiser note array (stereo)
3570 struct Notes : klang::Notes<Synth, Note> {
3571 using klang::Notes<Synth, Note>::Notes;
3572 } notes;
3573
3574 Synth() : notes(this) { }
3575 virtual ~Synth() { }
3576
3577 virtual void presetLoaded(int preset) { }
3578 virtual void optionChanged(int param, int item) { }
3579 virtual void buttonPressed(int param) { };
3580
3581 int indexOf(Note* note) const {
3582 int index = 0;
3583 for (const auto* n : notes.items) {
3584 if (note == n) return
3585 index;
3586 index++;
3587 }
3588 return -1; // not found
3589 }
3590 };
3591 }
3592
3593 /// @cond
3594 namespace stereo {
3595 using namespace Stereo;
3596 }
3597 /// @endcond
3598
3599 /// Feed audio source to destination (with source processing)
3600 template<typename SOURCE, typename DESTINATION>
3601 inline DESTINATION& operator>>(SOURCE& source, DESTINATION& destination) {
3602 if constexpr (is_derived_from<Input, DESTINATION>())
3603 destination.input(source); // input to destination (enables overriding of <<)
3604 else if constexpr (is_derived_from<Stereo::Input, DESTINATION>())
3605 destination.input(source); // input to destination (enables overriding of <<)
3606 else
3607 destination << source; // copy to destination
3608 return destination;
3609 }
3610
3611 /// Feed audio source to destination (no source processing)
3612 template<typename SOURCE, typename DESTINATION>
3613 inline DESTINATION& operator>>(const SOURCE& source, DESTINATION& destination) {
3614 if constexpr (is_derived_from<Input, DESTINATION>())
3615 destination.input(source); // input to destination (enables overriding of <<)
3616 else if constexpr (is_derived_from<Stereo::Input, DESTINATION>())
3617 destination.input(source); // input to destination (enables overriding of <<)
3618 else
3619 destination << source; // copy to destination
3620 return destination;
3621 }
3622
3623 /// Common audio generators / oscillators.
3624 namespace Generators {
3625 using namespace klang;
3626
3627 /// Simple oscillators
3628 namespace Basic {
3629 /// Sine wave oscillator
3630 struct Sine : public Oscillator {
3631 void process() {
3632 out = sin(position + offset);
3633 position += increment;
3634 }
3635 };
3636
3637 /// Saw wave oscillator (aliased)
3638 struct Saw : public Oscillator {
3639 void process() {
3640 out = position * pi.inv - 1.f;
3641 position += increment;
3642 }
3643 };
3644
3645 /// Triangle wave oscillator (aliased)
3646 struct Triangle : public Oscillator {
3647 void process() {
3648 out = abs(2.f * position * pi.inv - 2) - 1.f;
3649 position += increment;
3650 }
3651 };
3652
3653 /// Square wave oscillator (aliased)
3654 struct Square : public Oscillator {
3655 void process() {
3656 out = position > pi ? 1.f : -1.f;
3657 position += increment;
3658 }
3659 };
3660
3661 /// Pulse wave oscillator (aliased)
3662 struct Pulse : public Oscillator {
3663 param duty = 0.5f;
3664
3665 using Oscillator::set;
3666 void set(param frequency, param phase, param duty) {
3667 set(frequency, phase);
3668 Pulse::duty = duty;
3669 }
3670
3671 void process() {
3672 out = position > (duty * pi) ? 1.f : -1.f;
3673 position += increment;
3674 }
3675 };
3676
3677 /// White noise generator
3678 struct Noise : public Generator {
3679 void process() {
3680 out = rand() * 2.f/(const float)RAND_MAX - 1.f;
3681 }
3682 };
3683 };
3684
3685 /// Performance-optimised oscillators
3686 namespace Fast {
3687 constexpr float twoPi = float(2.0 * 3.1415926535897932384626433832795);
3688 constexpr float twoPiInv = float(1.0 / twoPi);
3689
3690 /// Phase increment (optimised)
3691 struct Increment {
3692 // represent phase delta using full range of int32
3693 // (integer math, no conditionals, free oversampling)
3694 signed int amount = 0;
3695
3696 void reset() { amount = 0; }
3697
3698 // set increment given frequency (in Hz)
3699 void set(Frequency f) {
3700 constexpr float FC4 = float(261.62556530059862); // Reference Freq (C4 = 261Hz)
3701 constexpr float FC4_FINTMAX = float(261.62556530059862 * 2147483648.0);
3702 const float FBASE = (FC4_FINTMAX) / klang::fs;
3703 amount = 2u * (signed int)(FBASE / FC4 * f);
3704 }
3705
3706 // convert int32 to float [0, 2pi)
3707 operator float() const {
3708 const unsigned int i = (amount >> 9) | 0x3f800000;
3709 return *(const float*)&i - 1.f;
3710 }
3711
3712 Increment operator+(const Increment& in) const {
3713 return { in.amount + amount };
3714 }
3715 };
3716
3717 /// Oscillator phase (optimised)
3718 struct Phase {
3719 // represent phase using full range of uint32
3720 // (integer math, no conditionals, free oversampling)
3721 unsigned int position = 0;
3722
3723 // convert float [0, 2pi) to uint32
3725 constexpr float FINTMAX = 2147483648.0f; // (float)INT_MAX + 1.f;
3726 phase = phase * FINTMAX / (2.f * pi);
3727 position = (unsigned int)phase;
3728 return *this;
3729
3730 //position = 2u * (signed int)(phase * (float(INT_MAX) + 1.f) * twoPiInv);
3731 //return *this;
3732 }
3733
3734 // convert uint32 to float [0, 1)
3735 operator float() const {
3736 const unsigned int i = (position >> 9) | 0x3f800000;
3737 return (*(const float*)&i - 1.f);
3738
3739 //// = quarter-turn (pi/2) phase offset
3740 //unsigned int phase = position + 0x40000000;
3741
3742 //// range reduce to [0,pi]
3743 //if (phase & 0x80000000) // cos(x) = cos(-x)
3744 // phase = ~phase;
3745
3746 //// convert to float in range [-pi/2,pi/2)
3747 //phase = (phase >> 8) | 0x3f800000;
3748 //return *(float*)&phase * pi - 3.f/2.f * pi; // 1.0f + (phase / (2^31))
3749 }
3750
3751 // returns offset phase
3752 float operator+(const Phase& offset) const {
3753
3754 unsigned int phase = (position + offset.position) + 0x40000000; // = quarter-turn (pi/2) phase offset
3755 // range reduce to [0,pi]
3756 if (phase & 0x80000000) // cos(x) = cos(-x)
3757 phase = ~phase;
3758
3759 // convert to float in range [-pi/2,pi/2)
3760 phase = (phase >> 8) | 0x3f800000;
3761 return *(float*)&phase * pi - 3.f / 2.f * pi; // 1.0f + (phase / (2^31))
3762 }
3763
3764 // convert uint32 to float [0, 2pi)
3765 float radians() const {
3766 return operator float();
3767 }
3768
3769 // applies increment and returns float [0, 2pi)
3770 //float operator+=(Increment i) {
3771 // unsigned int phase = position + 0x40000000; // = quarter-turn (pi/2) phase offset
3772 // position += i.amount; // apply increment
3773
3774 // // range reduce to [0,pi]
3775 // if (phase & 0x80000000) // cos(x) = cos(-x)
3776 // phase = ~phase;
3777
3778 // // convert to float in range [-pi/2,pi/2)
3779 // phase = (phase >> 8) | 0x3f800000;
3780 // return *(float*)&phase * pi - 3 / 2.f * pi; // 1.0f + (phase / (2^31))
3781 //}
3782
3783 // applies increment and returns float [0, 2pi)
3785 position += i.amount; // apply increment
3786 return *this;
3787 }
3788
3789 // applies increment and returns float [0, 2pi)
3790 //Phase operator+(const Phase& i) const {
3791 // return { position + i.position }; // apply increment
3792 //}
3793
3794 //// applies increment and returns float [0, 2pi)
3795 //float operator+=(Increment i) {
3796 // unsigned int phase = position + 0x40000000; // = quarter-turn (pi/2) phase offset
3797 // position += i.amount; // apply increment
3798
3799 // // range reduce to [0,pi]
3800 // if (phase & 0x80000000) // cos(x) = cos(-x)
3801 // phase = ~phase;
3802
3803 // // convert to float in range [-pi/2,pi/2)
3804 // phase = (phase >> 8) | 0x3f800000;
3805 // return *(float*)&phase * pi - 3/2.f * pi; // 1.0f + (phase / (2^31))
3806 //}
3807
3808 //Phase& operator+(Phase offset) const {
3809 // offset.position += position;
3810 // return offset;
3811 //}
3812
3813 //static void test() {
3814 // Phase p;
3815 // assert((float)(p = 0.f).radians() == 0.f);
3816 // assert((float)(p = pi/2).radians() == pi/2);
3817 // assert((float)(p = pi).radians() == pi);
3818 // assert((float)(p = 3*pi/2).radians() == 3*pi/2);
3819 // assert((float)(p = 2*pi).radians() == 0.f);
3820 //}
3821 };
3822
3823 /// sin approximation [-pi/2, pi/2] using odd minimax polynomial (Robin Green)
3824 inline static float polysin(float x) {
3825 const float x2 = x * x;
3826 return (((-0.00018542f * x2 + 0.0083143f) * x2 - 0.16666f) * x2 + 1.0f) * x;
3827 }
3828
3829 /// fast sine (based on V2/Farbrausch; using polysin)
3830 inline static float fastsin(float x)
3831 {
3832 // Range reduction to [0, 2pi]
3833 //x = fmodf(x, twoPi);
3834 //if (x < 0) // support -ve phase (e.g. for FM)
3835 // x += twoPi; //
3836 x = fast_mod2pi(x);
3837
3838 // Range reduction to [-pi/2, pi/2]
3839 if (x > 3/2.f * pi) // 3/2pi ... 2pi
3840 x -= twoPi; // (= translated)
3841 else if (x > pi/2) // pi/2 ... 3pi/2
3842 x = pi - x; // (= mirrored)
3843
3844 return polysin(x);
3845 }
3846
3847 /// fast sine (using polysin and integer math)
3848 inline static float fastsinp(unsigned int p)
3849 {
3850 // Range reduction to [0, 2pi]
3851 //x = fmodf(x, twoPi);
3852 //if (x < 0) // support -ve phase (e.g. for FM)
3853 // x += twoPi; //
3854 float x = fast_modp(p);
3855
3856 // Range reduction to [-pi/2, pi/2]
3857 if (x > 3.f/2.f * pi) // 3/2pi ... 2pi
3858 x -= twoPi; // (= translated)
3859 else if (x > pi/2.f) // pi/2 ... 3pi/2
3860 x = pi - x; // (= mirrored)
3861
3862 return polysin(x);
3863 }
3864
3865 /// Sine wave oscillator (band-limited, optimised)
3866 struct Sine : public Oscillator {
3867 void reset() override {
3868 Sine::position = Oscillator::position = 0;
3869 Sine::offset = Oscillator::offset = 0;
3870 set(Oscillator::frequency, 0.f);
3871 }
3872
3873 void set(param frequency) override {
3874 if (frequency != Oscillator::frequency) {
3875 Oscillator::frequency = frequency;
3876 increment.set(frequency);
3877 }
3878 }
3879
3880 void set(param frequency, param phase) override { // set frequency and phase
3881 Sine::position = Oscillator::position = phase;
3882 Sine::offset = Oscillator::offset = 0;
3883 set(frequency);
3884 }
3885
3886 void set(param frequency, relative phase) override { // set frequency and phase
3887 set(frequency);
3888 set(phase);
3889 }
3890
3891 void set(relative phase) override { // set frequency and phase
3892 Sine::offset = Oscillator::offset = phase * twoPi;
3893 }
3894
3895 void process() override {
3898 }
3899
3900 protected:
3903 };
3904
3905 /// Oscillator State Machine
3906 struct OSM {
3907 using Waveform = float(OSM::*)();
3908 const Waveform waveform;
3909
3910 OSM(Waveform waveform) : waveform(waveform) { }
3911
3924
3929 float delta;
3930
3931 // coeffeficients
3932 float f, omf, rcpf, rcpf2, col;
3933 float c1,c2;
3934
3935 param frequency = 0; // cached to optimise updates
3936
3937 void init() {
3939 f = delta;
3940 omf = 1.f - f;
3941 rcpf2 = 2.f * (rcpf = 1.f / f);
3942 col = duty;
3943
3944 c1 = 1.f / col;
3945 c2 = -1.f / (1.0f - col);
3946 }
3947
3948 void set(param frequency) {
3949 if (OSM::frequency != frequency) {
3950 OSM::frequency = frequency;
3951 increment.set(frequency);
3952 delta = increment;
3953 init();
3954 }
3955 }
3956
3957 void set(param frequency, param phase) {
3958 if (OSM::frequency != frequency) {
3959 OSM::frequency = frequency;
3960 increment.set(frequency);
3961 delta = increment;
3962 }
3963 offset = phase;
3964 init();
3965 }
3966
3967 void set(param frequency, param phase, param duty) {
3968 if (OSM::frequency != frequency) {
3969 OSM::frequency = frequency;
3970 increment.set(frequency);
3971 delta = increment;
3972 }
3973 offset = phase;
3974 setDuty(duty);
3975 }
3976
3977 void setDuty(param duty) {
3978 OSM::duty = duty * (2.f * pi);
3979 init();
3980 }
3981
3983 // old_up = new_up, new_up = (cnt < brpt)
3984 state = (State)(((state << 1) | (offset.position < duty.position)) & (NewUp|OldUp));
3985
3986 // we added freq to cnt going from the previous sample to the current one.
3987 // so if cnt is less than freq, we carried.
3988 const State transition = (State)(state | (offset.position < (unsigned int)increment.amount ? DownUpDown : Down));
3989
3990 // finally, tick the oscillator
3992
3993 return transition;
3994 }
3995
3996 inline static float sqr(float x) { return x * x; }
3997 inline float output() { return (this->*waveform)(); }
3998
3999 //inline float saw() {
4000 // const float f = delta;
4001 // const float omf = 1.f - f;
4002 // const float rcpf = 1.f / f;
4003 // const float col = duty;
4004 // const float c1 = 1.f / col;
4005 // const float c2 = -1.f / (1.0f - col);
4006 // const float p = offset - col;
4007 // float y = 0.0f;
4008 // // state machine action
4009 // switch (tick()) {
4010 // case Up: y = c1 * (p + p - f); break; // average of linear function = just sample in the middle
4011 // case Down: y = c2 * (p + p - f); break; // again, average of a linear function
4012 // case UpDown: y = rcpf * (c2 * sqr(p) - c1 * sqr(p - f)); break;
4013 // case DownUp: y = -rcpf * (1.f + c2 * sqr(p + omf) - c1 * sqr(p)); break;
4014 // case UpDownUp: y = -rcpf * (1.f + c1 * omf * (p + p + omf)); break;
4015 // case DownUpDown: y = -rcpf * (1.f + c2 * omf * (p + p + omf)); break;
4016 // default: y = -1; // should never happen
4017 // }
4018 // return y + 1.f;
4019 //}
4020
4021 float saw() { return saw(offset - col, tick()); }
4022 inline float saw(const float p, const State state) const {
4023 // state machine action
4024 switch (state) {
4025 case Up: return c1 * (p + p - f) + 1.f; break; // average of linear function = just sample in the middle
4026 case Down: return c2 * (p + p - f) + 1.f; break; // again, average of a linear function
4027 case UpDown: return rcpf * (c2 * sqr(p) - c1 * sqr(p - f)) + 1.f; break;
4028 case DownUp: return -rcpf * (1.f + c2 * sqr(p + omf) - c1 * sqr(p)) + 1.f; break;
4029 case UpDownUp: return -rcpf * (1.f + c1 * omf * (p + p + omf)) + 1.f; break;
4030 case DownUpDown: return -rcpf * (1.f + c2 * omf * (p + p + omf)) + 1.f; break;
4031 default: return 0.f; // should never happen
4032 }
4033 }
4034
4035 float pulse() { return pulse(offset, tick()); }
4036 inline float pulse(const float p, const State state) const {
4037 // state machine action
4038 switch (state) {
4039 case Up: return 1.f; break;
4040 case Down: return -1.f; break;
4041 case UpDown: return rcpf2 * (col - p) + 1.f; break;
4042 case DownUp: return rcpf2 * p - 1.f; break;
4043 case UpDownUp: return rcpf2 * (col - 1.0f) + 1.f; break;
4044 case DownUpDown: return rcpf2 * col - 1.f; break;
4045 default: return 0; // should never happen
4046 }
4047 }
4048 };
4049
4050 /// @cond
4051 struct Osm : public Oscillator {
4052 const float _Duty;
4053
4054 Osm(OSM::Waveform waveform, float duty = 0.f) : _Duty(duty), osm(waveform) { osm.setDuty(_Duty); }
4055
4056 void set(param frequency) {
4057 osm.set(frequency);
4058 }
4059
4060 void set(param frequency, param phase) {
4061 osm.set(frequency, phase);
4062 }
4063
4064 void set(param frequency, param phase, param duty) {
4065 osm.set(frequency, phase, duty);
4066 }
4067
4068 void process() {
4069 out = osm.output();
4070 }
4071
4072 protected:
4073 using Oscillator::set;
4074 OSM osm;
4075 };
4076 /// @endcond
4077
4078 /// Saw wave oscillator (band-limited, optimised)
4079 struct Saw : public Osm { Saw() : Osm(&OSM::saw, 0.f) {} };
4080 /// Triangle wave oscillator (band-limited, optimised)
4081 struct Triangle : public Osm { Triangle() : Osm(&OSM::saw, 1.f) {} };
4082 /// Square wave oscillator (band-limited, optimised)
4083 struct Square : public Osm { Square() : Osm(&OSM::pulse, 1.0f) {} };
4084 /// Pulse wave oscillator (band-limited, optimised)
4085 struct Pulse : public Osm { Pulse() : Osm(&OSM::pulse, 0.5f) {} };
4086
4087 /// White noise generator (optimised)
4088 struct Noise : public Generator {
4089 static constexpr unsigned int bias = 0b1000011100000000000000000000000;
4090 /// @cond
4091 union { unsigned int i; float f; };
4092 /// @endcond
4093 void process() {
4094 i = ((rand() & 0b111111111111111UL) << 1) | bias;
4095 out = f - 257.f;
4096 }
4097 };
4098 };
4099
4100 /// Wavetable-based oscillators
4101 namespace Wavetables {
4102 /// Sine wave oscillator (wavetable)
4103 struct Sine : public Wavetable {
4105 };
4106
4107 /// Saw wave oscillator (wavetable)
4108 struct Saw : public Wavetable {
4110 };
4111 }
4112 };
4113
4114 /// Common audio filters.
4115 namespace Filters {
4116
4117// namespace Basic {
4118
4119 /// Basic one-pole IIR filter.
4120 struct IIR : public Modifier {
4121 virtual ~IIR() { }
4122
4123 float a, b;
4124
4125 void set(param coeff) {
4126 a = coeff;
4127 b = 1 - a;
4128 }
4129
4130 void process() {
4131 out = (a * in) + (b * out);
4132 }
4133 };
4134
4135 /// Single-pole (one-pole, one-zero) First Order Filters
4136 namespace OnePole
4137 {
4138 /// Abstract filter class
4139 struct Filter : Modifier {
4140 virtual ~Filter() { }
4141
4142 float f = 0; // cutoff f
4143 //float shelf = 1; // shelving gain
4144
4145 float /*a0 = 1*/ a1 = 0, b0 = 1, b1 = 0; //coefficients
4146
4147 float exp0 = 0;
4148 //float tan0 = 0;
4149 float z = 0; // filter state
4150
4151 void reset() {
4152 a1 = 0;
4153 b0 = 1;
4154 b1 = 0;
4155 f = 0;
4156 z = 0;
4157 }
4158
4159 void set(param f) {
4160 if (Filter::f != f) {
4161 Filter::f = f;
4162 //tan0 = tanf(0.5f * f * fs.w);
4163 init();
4164 }
4165 }
4166
4167 virtual void init() = 0;
4168
4169 void process() {
4170 out = b0 * in + b1 * z + a1 * out + DENORMALISE;
4171 }
4172 };
4173
4174 /// Low-pass filter (LPF)
4175 struct LPF : Filter {
4176 virtual ~LPF() { }
4177
4178 void init() {
4179 const float exp0 = expf(-f * fs.w);
4180 b0 = 1 - exp0;
4181 a1 = exp0;
4182 }
4183
4184 void process() {
4185 out = b0 * in + a1 * out + DENORMALISE;
4186 }
4187 };
4188
4189 /// High-pass filter (HPF)
4190 struct HPF : Filter {
4191 virtual ~HPF() { }
4192
4193 void init() {
4194 const float exp0 = expf(-f * fs.w);
4195 b0 = 0.5f * (1.f + exp0);
4196 b1 = -b0;
4197 a1 = exp0;
4198 }
4199 };
4200 };
4201
4202 /// One-pole Butterworth filter.
4203 namespace Butterworth {
4204 /// Low-pass filter (LPF).
4205 struct LPF : OnePole::Filter {
4206 virtual ~LPF() { }
4207
4208 void init() {
4209 const float c = 1.f / tanf(pi * f * fs.inv);
4210 constant a0 = { 1.f + c };
4211 b0 = a0.inv; // b0 == b1
4212 a1 = (1.f - c) * a0.inv; // = (1-c) / a0
4213 }
4214 void process() {
4215 out = b0 * (in + z) - a1 * out;// +DENORMALISE;
4216 z = in;
4217 }
4218 };
4219 };
4220
4221 /// Transposed Direct Form II Biquadratic Filter
4222 namespace Biquad {
4223
4224 /// Abstract filter class
4226 {
4227 virtual ~Filter() { }
4228
4229 float f = 0; // cutoff/centre f
4230 float Q = 0; // Q (resonance)
4231
4232 float /*a0 = 1*/ a1 = 0, a2 = 0, b0 = 1, b1 = 0, b2 = 0; // coefficients
4233
4234 float a = 0; // alpha
4235 float cos0 = 1; // cos(omega)
4236 float sin0 = 0; // sin(omega)
4237 float z[2] = { 0 }; // filter state
4238
4239 /// Reset filter state
4240 void reset() {
4241 f = 0;
4242 Q = 0;
4243 b0 = 1;
4244 a1 = a2 = b1 = b2 = 0;
4245 a = 0;
4246 z[0] = z[1] = 0;
4247 }
4248
4249 /// Set the filter cutoff (and Q)
4250 void set(param f, param Q = root2.inv) {
4251 if (Filter::f != f || Filter::Q != Q) {
4252 Filter::f = f;
4253 Filter::Q = Q;
4254
4255 const float w = f * fs.w;
4256 cos0 = cosf(w);
4257 sin0 = sinf(w);
4258
4259 if (Q < 0.5) Q = 0.5;
4260 a = sin0 / (2.f * Q);
4261 init();
4262 }
4263 }
4264
4265 virtual void init() = 0;
4266
4267 /// Apply the biquad filter (Transposed Direct Form II)
4268 void process() noexcept {
4269 const float z0 = z[0];
4270 const float z1 = z[1];
4271 const float y = b0 * in + z0;
4272 z[0] = b1 * in - a1 * y + z1;
4273 z[1] = b2 * in - a2 * y;
4274 out = y;
4275 }
4276 };
4277
4278 /// Low-pass filter (LPF)
4279 struct LPF : Filter {
4280 virtual ~LPF() { }
4281
4282 void init() override {
4283 constant a0 = { 1.f + a };
4284 a1 = a0.inv * (-2.f * cos0);
4285 a2 = a0.inv * (1.f - a);
4286
4287 b2 = b0 = a0.inv * (1.f - cos0) * 0.5f;
4288 b1 = a0.inv * (1.f - cos0);
4289 }
4290 };
4291
4292 typedef LPF HCF; ///< High-cut filter (HCF)
4293 typedef LPF HRF; ///< High-reject filter (HRF)
4294
4295 /// High-pass filter (HPF)
4296 struct HPF : Filter {
4297 virtual ~HPF() { }
4298
4299 void init() {
4300 constant a0 = { 1.f + a };
4301 a1 = a0.inv * (-2.f * cos0);
4302 a2 = a0.inv * (1.f - a);
4303
4304 b2 = b0 = a0.inv * (1.f + cos0) * 0.5f;
4305 b1 = a0.inv * -(1.f + cos0);
4306 }
4307 };
4308
4309 typedef HPF LCF; ///< Low-cut filter (LCF)
4310 typedef HPF LRF; ///< Low-reject filter (LRF)
4311
4312 /// Band-pass filter (BPF)
4313 struct BPF : Filter {
4314
4315 enum Gain {
4316 ConstantSkirtGain, ///< Constant Skirt Gain
4317 ConstantPeakGain ///< Constant Peak Gain
4319
4320 /// Set the constant gain mode.
4323 init();
4324 return *this;
4325 }
4326
4327 using Init = void(BPF::*)(void); ///< @internal
4328 Init init_gain = &BPF::init_peak; ///< @internal
4329 void init() { (this->*init_gain)(); } ///< @internal
4330
4331 /// @internal
4332 void init_skirt() {
4333 // constant skirt gain
4334 constant a0 = { 1.f + a };
4335 a1 = a0.inv * (-2.f * cos0);
4336 a2 = a0.inv * (1.f - a);
4337
4338 b0 = a0.inv * sin0 * 0.5f;
4339 b1 = 0;
4340 b2 = -b0;
4341 }
4342
4343 /// @internal
4344 void init_peak() {
4345 // constant peak gain
4346 constant a0 = { 1.f + a };
4347 a1 = a0.inv * (-2.f * cos0);
4348 a2 = a0.inv * (1.f - a);
4349
4350 b0 = a0.inv * a;
4351 b1 = 0;
4352 b2 = a0.inv * -a;
4353 }
4354 };
4355
4356 /// Band-Reject Filter (BRF)
4357 struct BRF : Filter {
4358 void init() {
4359 constant a0 = { 1.f + a };
4360 b1 = a1 = a0.inv * (-2.f * cos0);
4361 a2 = a0.inv * (1.f - a);
4362 b0 = b2 = a0.inv;
4363 }
4364 };
4365
4366 typedef BRF BSF; ///< Band-stop filter (BSF)
4367
4368 /// All-pass filter (APF)
4369 struct APF : Filter {
4370 void init() {
4371 constant a0 = { 1.f + a };
4372 b1 = a1 = a0.inv * (-2.f * cos0);
4373 b0 = a2 = a0.inv * (1.f - a);
4374 b2 = 1.f;
4375 }
4376 };
4377 }
4378// }
4379 }
4380
4381 /// Envelope follower (Peak / RMS)
4383
4384 /// Attack / Release IIR Filter (~Butterworth when attack == release)
4385 struct AR : Modifier {
4388
4389 param A = 1, R = 1;
4390
4391 void set(param attack, param release) {
4392 if (AR::attack != attack || AR::release != release) {
4393 AR::attack = attack;
4394 AR::release = release;
4395 A = 1.f - (attack == 0.f ? 0.f : expf(-1.0f / (fs * attack)));
4396 R = 1.f - (release == 0.f ? 0.f : expf(-1.0f / (fs * release)));
4397 }
4398 }
4399
4400 void process() {
4401 const float smoothing = in > out ? A : R;
4402 (out + smoothing * (in - out)) >> out;
4403 }
4404 } ar;
4405
4406 // Peak / RMS Envelope Follower (default; filter-based)
4407 Follower() { set(0.01f, 0.1f); }
4408 void set(param attack, param release) {
4409 ar.set(attack, release);
4410 }
4411
4413 _process = (mode == RMS) ? &Follower::rms : &Follower::peak;
4414 return *this;
4415 }
4416
4417 using Process = void(Follower::*)();
4419
4420 void process() { (this->*_process)(); }
4421
4422 void peak() { abs(in) >> ar >> out; }
4423 void rms() { (in * in) >> ar >> sqrt >> out; }
4424
4425 /// Window-based envelope follower
4426 template<int WINDOW>
4428 {
4430 buffer buffer;
4431 double sum = 0; // NB: must be 64-bit to avoid rounding errors
4432 static constexpr constant window = { WINDOW };
4433
4435 set(0.01f, 0.1f);
4436 }
4437
4438 void set(param attack, param release) {
4439 ar.set(attack, release);
4440 }
4441
4443 _process = (mode == RMS) ? &Window::rms : &Window::mean;
4444 return *this;
4445 }
4446
4447 using Process = void(Window::*)();
4449
4450 void process() { (this->*_process)(); }
4451
4452 void mean() {
4453 sum -= double(buffer);
4454 abs(in) >> buffer;
4455 sum += double(buffer++);
4456 if (buffer.finished())
4457 buffer.rewind();
4458 sum * window.inv >> ar >> out;
4459 }
4460 void rms() {
4461 sum -= double(buffer);
4462 (in * in) >> buffer;
4463 sum += double(buffer++);
4464 if (buffer.finished())
4465 buffer.rewind();
4466 sum* window.inv >> sqrt >> ar >> out;
4467 }
4468 };
4469 };
4470
4471 namespace basic {
4472 using namespace klang;
4473
4474 using namespace Generators::Basic;
4475 using namespace Filters;
4476 using namespace Filters::Biquad;
4477 };
4478
4479 namespace optimised {
4480 using namespace klang;
4481
4482 using namespace Generators::Fast;
4483 using namespace Filters;
4484 using namespace Filters::Biquad;
4485 };
4486
4487 namespace minimal {
4488 using namespace klang;
4489 };
4490
4491 //using namespace optimised;
4492};
4493
4494//using namespace klang;
Envelope object.
Definition klang.h:2609
void process() override
Definition klang.h:2933
std::shared_ptr< Ramp > ramp
Definition klang.h:2984
virtual void release(float time, float level=0.f)
Definition klang.h:2847
operator float() const
Definition klang.h:2770
const Stage getStage() const
Definition klang.h:2841
Stage
Envelope stage.
Definition klang.h:2696
signal & operator++(int)
Definition klang.h:2898
std::vector< Point > points
Definition klang.h:2977
void set(Ramp *ramp)
Definition klang.h:2943
void setTargetRate(const Point &point, float rate=0.0)
Definition klang.h:2967
const Point & operator[](int point) const
Definition klang.h:2938
void setStage(Stage stage)
Definition klang.h:2838
signal at(param time) const
Definition klang.h:2815
bool operator==(Stage stage) const
Definition klang.h:2767
void initialise()
Definition klang.h:2860
void set(const std::vector< Point > &points)
Definition klang.h:2779
void resize(float length)
Definition klang.h:2877
void setLoop(int startPoint, int endPoint)
Definition klang.h:2809
bool operator!=(Stage stage) const
Definition klang.h:2768
Envelope(const Points &points)
Definition klang.h:2756
bool finished() const
Definition klang.h:2855
void setTargetTime(const Point &point, float time=0.0)
Definition klang.h:2961
Mode mode() const
Definition klang.h:2955
void set(const Points &point)
Definition klang.h:2785
Envelope & operator=(std::initializer_list< Point > points)
Definition klang.h:2773
float getLength() const
Definition klang.h:2844
void(Envelope::* setTargetFunction)(const Point &point, float time)
Definition klang.h:2959
Envelope(std::initializer_list< Point > points)
Definition klang.h:2759
void setTarget(const Point &point, float time=0.0)
Definition klang.h:2893
Envelope(const Envelope &in)
Definition klang.h:2762
virtual ~Envelope()
Definition klang.h:2764
void resetLoop()
Definition klang.h:2831
Mode
Envelope mode.
Definition klang.h:2698
void setMode(Mode mode)
Definition klang.h:2948
void sequence()
Definition klang.h:2798
float timeInc
Definition klang.h:2981
Base class for synthesiser notes.
Definition klang.h:3104
virtual event on(Pitch p, Velocity v)
Definition klang.h:3117
SYNTH * getSynth()
Definition klang.h:3120
virtual bool stop(Velocity v=0)
Definition klang.h:3157
virtual void init()
Definition klang.h:3135
bool finished() const
Definition klang.h:3162
void attach(SYNTH *synth)
Definition klang.h:3129
Controls controls
Definition klang.h:3124
virtual ~NoteBase()
Definition klang.h:3127
virtual void controlChange(int controller, int value)
Definition klang.h:3166
virtual void start(Pitch p, Velocity v)
Definition klang.h:3137
Velocity velocity
Definition klang.h:3123
virtual event off(Velocity v=0)
Definition klang.h:3118
virtual bool release(Velocity v=0)
Definition klang.h:3145
Wavetable-based oscillator.
Definition klang.h:2557
virtual void set(param frequency, param phase) override
Definition klang.h:2587
Wavetable(int size=2048)
Definition klang.h:2563
virtual void set(param frequency, relative phase) override
Definition klang.h:2597
virtual void set(param frequency) override
Definition klang.h:2582
signal & operator[](int index)
Definition klang.h:2570
virtual void set(relative phase) override
Definition klang.h:2592
const int size
Definition klang.h:2561
Wavetable(TYPE oscillator, int size=2048)
Definition klang.h:2566
void process() override
Definition klang.h:2602
Wavetable & operator=(TYPE &oscillator)
Definition klang.h:2575
Audio buffer (mono)
Definition klang.h:1188
constexpr unsigned int capacity(unsigned int n)
Definition klang.h:1190
signal operator[](float offset)
Definition klang.h:1264
signal & operator*=(const signal &in)
Definition klang.h:1311
virtual ~buffer()
Definition klang.h:1228
const bool owned
Definition klang.h:1203
signal & operator[](int offset)
Definition klang.h:1260
buffer(float *buffer, int size)
Definition klang.h:1211
const signal & operator[](int index) const
Definition klang.h:1278
int offset() const
Definition klang.h:1249
buffer(int size, float initial=0)
Definition klang.h:1222
float * samples
Definition klang.h:1204
signal * ptr
Definition klang.h:1205
buffer & operator=(const buffer &in)
Definition klang.h:1316
signal * end
Definition klang.h:1206
signal & operator=(const signal &in)
Definition klang.h:1302
const int size
Definition klang.h:1209
void clear(int size)
Definition klang.h:1245
signal operator[](float offset) const
Definition klang.h:1268
signal & operator+=(const signal &in)
Definition klang.h:1306
bool finished() const
Definition klang.h:1294
void rewind(int offset=0)
Definition klang.h:1233
void set(float value=0)
Definition klang.h:1253
const float * data() const
Definition klang.h:1327
const unsigned int mask
Definition klang.h:1202
operator signal &()
Definition klang.h:1282
signal & operator++(int)
Definition klang.h:1298
operator double() const
Definition klang.h:1290
buffer(float *buffer, int size, float initial)
Definition klang.h:1216
void clear()
Definition klang.h:1241
operator const signal &() const
Definition klang.h:1286
#define GRAPH_SIZE
Definition klang.h:51
#define DENORMALISE
Definition klang.h:85
#define KLANG_DEBUG
Definition klang.h:47
#define GRAPH_SERIES
Definition klang.h:54
#define abs
Definition klang.h:2170
#define IS_SIMPLE_TYPE(type)
Definition klang.h:64
#define sqrt
Definition klang.h:2169
Transposed Direct Form II Biquadratic Filter.
Definition klang.h:4222
BRF BSF
Band-stop filter (BSF)
Definition klang.h:4366
LPF HCF
High-cut filter (HCF)
Definition klang.h:4292
LPF HRF
High-reject filter (HRF)
Definition klang.h:4293
HPF LCF
Low-cut filter (LCF)
Definition klang.h:4309
HPF LRF
Low-reject filter (LRF)
Definition klang.h:4310
One-pole Butterworth filter.
Definition klang.h:4203
Single-pole (one-pole, one-zero) First Order Filters.
Definition klang.h:4137
Common audio filters.
Definition klang.h:4115
Simple oscillators.
Definition klang.h:3628
Performance-optimised oscillators.
Definition klang.h:3686
constexpr float twoPiInv
Definition klang.h:3688
constexpr float twoPi
Definition klang.h:3687
static float fastsin(float x)
fast sine (based on V2/Farbrausch; using polysin)
Definition klang.h:3830
static float fastsinp(unsigned int p)
fast sine (using polysin and integer math)
Definition klang.h:3848
static float polysin(float x)
sin approximation [-pi/2, pi/2] using odd minimax polynomial (Robin Green)
Definition klang.h:3824
Wavetable-based oscillators.
Definition klang.h:4101
Common audio generators / oscillators.
Definition klang.h:3624
Templates supporting common audio functionality.
Definition klang.h:1334
SIGNAL operator*(Output< SIGNAL > &output, float other)
Definition klang.h:1393
SIGNAL operator-(Output< SIGNAL > &output, float other)
Definition klang.h:1394
SIGNAL operator+(float other, Output< SIGNAL > &output)
Definition klang.h:1387
SIGNAL operator+(Output< SIGNAL > &output, float other)
Definition klang.h:1392
SIGNAL operator*(float other, Output< SIGNAL > &output)
Definition klang.h:1388
SIGNAL operator/(Output< SIGNAL > &output, float other)
Definition klang.h:1395
Function() -> Function< signal, Args... >
SIGNAL operator/(float other, Output< SIGNAL > &output)
Definition klang.h:1390
Function(float(*)(Args...)) -> Function< signal, Args... >
SIGNAL operator-(float other, Output< SIGNAL > &output)
Definition klang.h:1389
Objects supporting stereo audio functionality.
Definition klang.h:3306
signals< 2 > signal
Stereo audio signal.
Definition klang.h:3308
Definition klang.h:74
static Function< float > abs(FABS)
Absolute/rectify function (audio object)
static Control Slider(const char *name, float min=0.f, float max=1.f, float initial=0.f)
Definition klang.h:1072
static GraphPtr & operator>>(TYPE(*function)(TYPE), klang::GraphPtr &graph)
Definition klang.h:2131
static TYPE random(const TYPE min, const TYPE max)
Generates a random number between min and max. Use an integer types for whole numbers.
Definition klang.h:228
float fast_mod(float x, float y)
Definition klang.h:697
Values values
Definition klang.h:1146
double fast_mod2pi(double x)
Definition klang.h:729
static THREAD_LOCAL GraphPtr graph
Definition klang.h:2122
Amplitude Velocity
Control parameter (velocity)
Definition klang.h:950
signals< 4 > operator>>(const signals< 4 > &in, const Matrix &m)
Definition klang.h:769
const signal & operator>>(klang::signal modulator, Operator< OSCILLATOR > &carrier)
Definition klang.h:3060
float fast_mod2pi(float x)
Definition klang.h:717
constexpr constant ln2
The natural logorithm of 2 (and it's inverse).
Definition klang.h:221
static Graph & operator>>(TYPE(*function)(TYPE), Graph &graph)
Definition klang.h:2143
constexpr constant pi
The mathematical constant, pi (and it's inverse).
Definition klang.h:218
Function(float(*)(Args...)) -> Function< Args... >
const Control::Options NoOptions
Definition klang.h:1039
signals< CHANNELS > operator/(float x, const signals< CHANNELS > &y)
Return a copy of the signal with each channel divided into x.
Definition klang.h:623
static Control PitchBend()
Definition klang.h:1088
Mode
Klang mode identifiers (e.g. averages, level following)
Definition klang.h:83
@ Peak
Definition klang.h:83
@ RMS
Definition klang.h:83
@ Mean
Definition klang.h:83
double fast_mod(double x, double y)
Definition klang.h:702
static void random(const unsigned int seed)
Set the random seed (to allow repeatable random generation).
Definition klang.h:231
static Function< float > sqrt(SQRTF)
Square root function (audio object)
static Control Dial(const char *name, float min=0.f, float max=1.f, float initial=0.f)
Definition klang.h:1063
DESTINATION & operator>>(const SOURCE &source, DESTINATION &destination)
Feed audio source to destination (no source processing)
Definition klang.h:3613
double fast_modi(double x)
Definition klang.h:736
static param & operator>>(param &from, param &to)
Definition klang.h:676
TYPE1 max(TYPE1 a, TYPE2 b)
Return the minimum of two values.
Definition klang.h:215
static signal & operator>>(float input, signal &destination)
Stream a literal / constant / scalar type into a signal.
Definition klang.h:495
static Control Toggle(const char *name, bool initial=false)
Definition klang.h:1069
static Control Meter(const char *name, float min=0.f, float max=1.f, float initial=0.f)
Definition klang.h:1085
TYPE1 min(TYPE1 a, TYPE2 b)
Return the minimum of two values.
Definition klang.h:212
static Control Menu(const char *name, const Options... options)
Definition klang.h:1076
constexpr bool are_scalars(Head &&head, Tail &&... tail)
Definition klang.h:126
signals< CHANNELS > operator-(float x, const signals< CHANNELS > &y)
Return a copy of the signal with each channel subtracted from x.
Definition klang.h:619
const Control::Size Automatic
Definition klang.h:1038
static Debug debug
Definition klang.h:2397
signals< CHANNELS > operator*(float x, const signals< CHANNELS > &y)
Return a copy of the signal with each channel scaled by x.
Definition klang.h:621
float fast_modp(unsigned int x)
Definition klang.h:723
DESTINATION & operator>>(SOURCE &source, DESTINATION &destination)
Feed audio source to destination (with source processing)
Definition klang.h:3601
signals< 4 > operator*(const signals< 4 > &in, const Matrix &m)
Definition klang.h:762
Array< float, 128 > Values
Definition klang.h:1141
static Function< float > cube([](float x) -> float { return x *x *x;})
Cube function (audio object)
constexpr BASE poweri(BASE base)
Definition klang.h:132
signals< CHANNELS > operator+(float x, const signals< CHANNELS > &y)
Return a copy of the signal with each channel offset by x.
Definition klang.h:617
static Function< float > sqr([](float x) -> float { return x *x;})
Square function (audio object)
constexpr power_t< BASE, EXP > power(BASE base, EXP exp)
Raise base to the power exp.
Definition klang.h:150
float fast_mod1(float x)
Definition klang.h:707
Caption name
Definition klang.h:1145
constexpr constant root2
The square root of 2 (and it's inverse).
Definition klang.h:224
static Control ModWheel()
Definition klang.h:1091
double fast_mod1(double x)
Definition klang.h:712
Text< 32 > Caption
A short Text object used to label controls.
Definition klang.h:355
static Control Button(const char *name)
Definition klang.h:1066
void event
A function that handles an event.
Definition klang.h:234
constexpr bool is_derived_from()
Definition klang.h:121
constexpr power_t< BASE, EXP > power(BASE base, EXP exp)
Raise base to the power exp.
Definition klang.h:181
Factory preset.
Definition klang.h:1144
TYPE sqrt(TYPE x)
Definition klang.h:59
TYPE abs(TYPE x)
Definition klang.h:60
Attack-Decay-Sustain-Release Envelope.
Definition klang.h:2988
bool operator==(Envelope::Stage stage) const
Definition klang.h:3017
param R
Definition klang.h:2992
param S
Definition klang.h:2992
param D
Definition klang.h:2992
void release(float time=0.f, float level=0.f) override
Definition klang.h:3013
param A
Definition klang.h:2992
void set(param attack, param decay, param sustain, param release) override
Definition klang.h:2998
Control parameter (linear amplitude)
Definition klang.h:922
static THREAD_LOCAL Conversion dB
Definition klang.h:943
Amplitude(const dB &db)
Definition klang.h:927
Amplitude(float a=1.f)
Definition klang.h:926
const Amplitude * operator->() const
Definition klang.h:938
Variable-sized array, pre-allocated to a max. capacity.
Definition klang.h:238
unsigned int size() const
The current number of items in the array.
Definition klang.h:246
Array(std::initializer_list< TYPE > init_list)
Construct an array given the specified values.
Definition klang.h:306
float max() const
Find the maximum value in the array.
Definition klang.h:265
TYPE items[CAPACITY]
Definition klang.h:239
Array()=default
Construct an empty array.
void add(const TYPE &item)
Add the specified item to the end of the array.
Definition klang.h:249
float mean() const
Find the mean average of values in the array.
Definition klang.h:274
unsigned int count
Definition klang.h:240
void normalise(float target=1.f, int mode=Peak)
Normalises values in the array to the specified target, based on peak, mean, or RMS value;.
Definition klang.h:290
float rms() const
Find the root mean squared (RMS) average of values in the array.
Definition klang.h:282
void clear()
Clear the array contents. Only resets the item count, without wiping memory.
Definition klang.h:262
const TYPE & operator[](int index) const
Returns a read-only reference to the array item at the given index.
Definition klang.h:303
static int capacity()
The maximum capacity of the array.
Definition klang.h:243
TYPE * add()
Add a blank item to the end of the array, returning a pointer that allows the item to be modified.
Definition klang.h:255
TYPE & operator[](int index)
Returns a reference to the array item at the given index.
Definition klang.h:300
A parallel bank of multiple audio objects.
Definition klang.h:2000
void set(Args... args)
Definition klang.h:2010
TYPE items[COUNT]
Definition klang.h:2004
TYPE & operator[](int index)
Definition klang.h:2006
void process() override
Definition klang.h:2020
const TYPE & operator[](int index) const
Definition klang.h:2007
void input() override
Definition klang.h:2015
Debug text output.
Definition klang.h:2173
Console & operator=(const char *in)
Definition klang.h:2183
void clear()
Definition klang.h:2178
int getText(char *buffer)
Definition klang.h:2214
static std::mutex _lock
Definition klang.h:2174
static THREAD_LOCAL Text< 16384 > last
Definition klang.h:2175
bool hasText() const
Definition klang.h:2210
Console & operator=(const Console &in)
Definition klang.h:2191
Console & operator+=(const char *in)
Definition klang.h:2199
Control size.
Definition klang.h:969
Size(int x=-1, int y=-1, int width=-1, int height=-1)
Definition klang.h:970
bool isAuto() const
Definition klang.h:978
UI control / parameter.
Definition klang.h:954
float operator+(TYPE x) const
Definition klang.h:1026
float operator-(TYPE x) const
Definition klang.h:1028
Caption name
Definition klang.h:983
float max
Definition klang.h:987
Options options
Definition klang.h:991
operator signal &()
Definition klang.h:996
signal value
Definition klang.h:993
signal operator*(const Control &x) const
Definition klang.h:1022
Array< Caption, 128 > Options
Definition klang.h:981
Control & operator*=(float x)
Definition klang.h:1012
float operator/(TYPE x) const
Definition klang.h:1029
Control & operator-=(float x)
Definition klang.h:1013
const TYPE & operator>>(const TYPE &in)
Definition klang.h:1035
float operator*(TYPE x) const
Definition klang.h:1027
Control & operator+=(float x)
Definition klang.h:1011
signal smooth()
Definition klang.h:1002
signal operator-(const Control &x) const
Definition klang.h:1023
float min
Definition klang.h:986
signal operator+(const Control &x) const
Definition klang.h:1021
Control & set(float x)
Definition klang.h:1006
operator param() const
Definition klang.h:998
static constexpr float smoothing
Definition klang.h:1001
Control & operator/=(float x)
Definition klang.h:1014
float initial
Definition klang.h:988
operator Control *()
Definition klang.h:1004
operator const signal &() const
Definition klang.h:997
operator float() const
Definition klang.h:999
signal operator/(const Control &x) const
Definition klang.h:1024
TYPE & operator>>(TYPE &in)
Definition klang.h:1034
signal smoothed
Definition klang.h:994
Mapped UI control.
Definition klang.h:1042
operator const signal &() const
Definition klang.h:1050
operator param() const
Definition klang.h:1051
ControlMap(Control &control)
Definition klang.h:1046
signal smooth()
Definition klang.h:1053
Control * control
Definition klang.h:1043
operator float() const
Definition klang.h:1052
Base class for UI / MIDI controll.
Definition klang.h:3066
virtual void onMIDI(int status, int byte1, int byte2)
Definition klang.h:3074
virtual void onPreset(int index)
Definition klang.h:3073
virtual void onControl(int index, float value)
Definition klang.h:3072
virtual event midi(int status, int byte1, int byte2)
Definition klang.h:3070
virtual event control(int index, float value)
Definition klang.h:3068
virtual event preset(int index)
Definition klang.h:3069
Plugin UI controls.
Definition klang.h:1096
void operator+=(const Control &control)
Definition klang.h:1099
bool changed()
Definition klang.h:1123
void operator=(const Controls &controls)
Definition klang.h:1103
void operator=(std::initializer_list< Control > controls)
Definition klang.h:1108
void add(const char *name, Control::Type type=Control::ROTARY, float min=0.f, float max=1.f, float initial=0.f, Control::Size size=Automatic)
Definition klang.h:1113
float value[128]
Definition klang.h:1097
Audio buffer for debug output.
Definition klang.h:2233
Buffer & operator+=(const signal in)
Definition klang.h:2271
operator const signal &() const
Definition klang.h:2289
Buffer & operator+=(TYPE &in)
Definition klang.h:2278
const float * get()
Definition klang.h:2261
signal & operator>>(signal &destination) const
Definition klang.h:2284
The Klang debug interface.
Definition klang.h:2230
void print(const char *format,...)
Definition klang.h:2344
static double profile(int times, Func func, Args... args)
Definition klang.h:2312
int getText(char *buffer)
Definition klang.h:2374
void printOnce(const char *format,...)
Definition klang.h:2356
Console console
Debug console output.
Definition klang.h:2297
void input() override
Definition klang.h:2383
operator const signal &() const
Definition klang.h:2378
static THREAD_LOCAL Buffer buffer
Definition klang.h:2294
bool hasText() const
Definition klang.h:2370
static double profile(Func func, Args... args)
Definition klang.h:2300
Audio delay object.
Definition klang.h:2480
float time
Definition klang.h:2485
virtual void set(param delay) override
Definition klang.h:2529
signal tap(float delay) const
Definition klang.h:2511
signal tap(int delay) const
Definition klang.h:2504
void input() override
Definition klang.h:2495
signal operator()(TIME &delay)
Definition klang.h:2534
signal operator()(const TIME &delay)
Definition klang.h:2544
unsigned int max() const
Definition klang.h:2553
int position
Definition klang.h:2486
void clear()
Definition klang.h:2490
virtual void process() override
Definition klang.h:2525
Effect mini-plugin (mono)
Definition klang.h:3086
virtual void prepare()
Definition klang.h:3089
virtual void process(buffer buffer)
Definition klang.h:3091
virtual void process()
Definition klang.h:3090
virtual ~Effect()
Definition klang.h:3087
Attack / Release IIR Filter (~Butterworth when attack == release)
Definition klang.h:4385
void set(param attack, param release)
Definition klang.h:4391
Window-based envelope follower.
Definition klang.h:4428
Window & operator=(klang::Mode mode)
Definition klang.h:4442
static constexpr constant window
Definition klang.h:4432
void set(param attack, param release)
Definition klang.h:4438
Envelope follower (Peak / RMS)
Definition klang.h:4382
void set(param attack, param release)
Definition klang.h:4408
Follower & operator=(klang::Mode mode)
Definition klang.h:4412
Linear envelope ramp (default)
Definition klang.h:2668
signal operator++(int) override
Definition klang.h:2671
Envelope loop.
Definition klang.h:2740
void set(int from, int to)
Definition klang.h:2743
Loop(int from=-1, int to=-1)
Definition klang.h:2741
bool isActive() const
Definition klang.h:2746
Envelope point (x,y)
Definition klang.h:2701
Point(T1 x, T2 y)
Definition klang.h:2707
Abstract envelope ramp type.
Definition klang.h:2617
virtual void setRate(float rate)
Definition klang.h:2656
void process() override
Definition klang.h:2664
bool isActive() const
Definition klang.h:2638
virtual void setTime(float time)
Definition klang.h:2659
virtual signal operator++(int)=0
Ramp(float start, float target, float time)
Definition klang.h:2629
virtual void setTarget(float target)
Definition klang.h:2643
Ramp(float value=1.f)
Definition klang.h:2624
virtual void setValue(float value)
Definition klang.h:2649
All-pass filter (APF)
Definition klang.h:4369
Band-pass filter (BPF)
Definition klang.h:4313
BPF & operator=(Gain gain)
Set the constant gain mode.
Definition klang.h:4321
@ ConstantSkirtGain
Constant Skirt Gain.
Definition klang.h:4316
@ ConstantPeakGain
Constant Peak Gain.
Definition klang.h:4317
Band-Reject Filter (BRF)
Definition klang.h:4357
Abstract filter class.
Definition klang.h:4226
void process() noexcept
Apply the biquad filter (Transposed Direct Form II)
Definition klang.h:4268
void set(param f, param Q=root2.inv)
Set the filter cutoff (and Q)
Definition klang.h:4250
void reset()
Reset filter state.
Definition klang.h:4240
High-pass filter (HPF)
Definition klang.h:4296
Low-pass filter (LPF)
Definition klang.h:4279
void init() override
Definition klang.h:4282
Low-pass filter (LPF).
Definition klang.h:4205
Basic one-pole IIR filter.
Definition klang.h:4120
void set(param coeff)
Definition klang.h:4125
virtual ~IIR()
Definition klang.h:4121
Abstract filter class.
Definition klang.h:4139
High-pass filter (HPF)
Definition klang.h:4190
Low-pass filter (LPF)
Definition klang.h:4175
Control parameter (frequency)
Definition klang.h:884
Frequency(float f=1000.f)
Definition klang.h:887
Applies a function to a signal (input-output)
Definition klang.h:2028
Function(std::function< float(Args...)> function)
Definition klang.h:2036
Signal generator object (mono)
Definition klang.h:1986
White noise generator.
Definition klang.h:3678
Pulse wave oscillator (aliased)
Definition klang.h:3662
void set(param frequency, param phase, param duty)
Definition klang.h:3666
Saw wave oscillator (aliased)
Definition klang.h:3638
Sine wave oscillator.
Definition klang.h:3630
Square wave oscillator (aliased)
Definition klang.h:3654
Triangle wave oscillator (aliased)
Definition klang.h:3646
Phase increment (optimised)
Definition klang.h:3691
Increment operator+(const Increment &in) const
Definition klang.h:3712
White noise generator (optimised)
Definition klang.h:4088
static constexpr unsigned int bias
Definition klang.h:4089
Oscillator State Machine.
Definition klang.h:3906
Fast::Increment increment
Definition klang.h:3925
const Waveform waveform
Definition klang.h:3908
void set(param frequency)
Definition klang.h:3948
void set(param frequency, param phase)
Definition klang.h:3957
static float sqr(float x)
Definition klang.h:3996
void setDuty(param duty)
Definition klang.h:3977
float saw(const float p, const State state) const
Definition klang.h:4022
float pulse(const float p, const State state) const
Definition klang.h:4036
void set(param frequency, param phase, param duty)
Definition klang.h:3967
OSM(Waveform waveform)
Definition klang.h:3910
Oscillator phase (optimised)
Definition klang.h:3718
float operator+(const Phase &offset) const
Definition klang.h:3752
Phase & operator=(klang::Phase phase)
Definition klang.h:3724
Phase & operator+=(const Increment i)
Definition klang.h:3784
Pulse wave oscillator (band-limited, optimised)
Definition klang.h:4085
Saw wave oscillator (band-limited, optimised)
Definition klang.h:4079
Sine wave oscillator (band-limited, optimised)
Definition klang.h:3866
void process() override
Definition klang.h:3895
Fast::Increment increment
Definition klang.h:3901
void set(relative phase) override
Definition klang.h:3891
void reset() override
Definition klang.h:3867
void set(param frequency, param phase) override
Definition klang.h:3880
void set(param frequency) override
Definition klang.h:3873
void set(param frequency, relative phase) override
Definition klang.h:3886
Square wave oscillator (band-limited, optimised)
Definition klang.h:4083
Triangle wave oscillator (band-limited, optimised)
Definition klang.h:4081
Saw wave oscillator (wavetable)
Definition klang.h:4108
Sine wave oscillator (wavetable)
Definition klang.h:4103
Applies a function to a signal (input-output)
Definition klang.h:1476
Function< SIGNAL, Args... > & operator()(const FuncArgs &... args)
Definition klang.h:1554
klang::GraphPtr & operator>>(klang::GraphPtr &graph)
Definition klang.h:2125
virtual void process() override
Definition klang.h:1617
unsigned int args() const
Definition klang.h:1521
Function(FunctionPtr function)
Definition klang.h:1535
std::tuple< Args... > inputs
Definition klang.h:1523
const float operator()(const FuncArgs &... args) const
Definition klang.h:1575
static constexpr unsigned int ARGS
Definition klang.h:1520
void input() override
Definition klang.h:1544
klang::Graph & operator>>(klang::Graph &graph)
Definition klang.h:2137
Function< SIGNAL, Args... > & with(FuncArgs... args)
Definition klang.h:1601
First first(First first, Rest...)
Definition klang.h:1550
Function(FunctionPtr function, OtherArgs... args)
Definition klang.h:1539
std::tuple< Rest... > tail(const std::tuple< First, Rest... > &t) const
Definition klang.h:1527
signal evaluate() const
Definition klang.h:1608
Signal generator object (output only)
Definition klang.h:1404
operator const SIGNAL &() const override
Definition klang.h:1416
operator const SIGNAL &() override
Definition klang.h:1415
Output< SIGNAL > & operator()(params... p)
Definition klang.h:1409
Graph axes (x/y)
Definition klang.h:1752
bool contains(const Point &pt) const
Definition klang.h:1756
double range() const
Definition klang.h:1728
void from(const Series &series, double Point::*axis)
Definition klang.h:1732
bool contains(double value) const
Definition klang.h:1729
Series * find(void *function)
Definition klang.h:1782
Series & operator>>(Series &series)
void input() override
Definition klang.h:1719
bool operator==(const Series &in) const
Definition klang.h:1701
bool operator!=(const Series &in) const
Definition klang.h:1709
void plot(Generic::Function< SIGNAL, Args... > &f, const Axis &x_axis)
Definition klang.h:1668
void plot(RETURN(*f)(ARG), const Axis &x_axis)
Definition klang.h:1685
A line graph plotter.
Definition klang.h:1634
void setDirty(bool dirty)
Definition klang.h:1923
Graph & operator=(TYPE(*function)(TYPE))
Plot the given function of x.
Definition klang.h:1874
Graph & operator+=(TYPE y)
Add a data point (incrementing x)
Definition klang.h:1868
Graph & operator()(double min, double max)
Definition klang.h:1790
void truncate(unsigned int count)
Definition klang.h:1925
Graph & operator=(std::initializer_list< Point > values)
Plot the given data points.
Definition klang.h:1880
size_t capacity() const
Definition klang.h:1637
void add(const Point pt)
Add a data point.
Definition klang.h:1864
void plot(FUNCTION f, VALUES... values)
Plot the given function for x plus additional arguments.
Definition klang.h:1847
Graph::Series & operator[](int index)
Definition klang.h:1796
const Graph::Series & operator[](int index) const
Definition klang.h:1801
void getAxes(Axes &axes) const
Definition klang.h:1904
void plot(Generic::Function< SIGNAL, Args... > &function)
Plot the given Function.
Definition klang.h:1819
const Data & getData() const
Definition klang.h:1921
Graph & operator+=(const Point pt)
Add a data point.
Definition klang.h:1870
const Axes & getAxes() const
Definition klang.h:1901
Graph & operator+=(std::initializer_list< Point > values)
Plot the given data points.
Definition klang.h:1885
bool isDirty() const
Definition klang.h:1922
void add(TYPE y)
Add a data point (incrementing x)
Definition klang.h:1862
void plot(TYPE(*function)(TYPE))
Plot the given function of x.
Definition klang.h:1833
Graph & operator()(double x_min, double x_max, double y_min, double y_max)
Definition klang.h:1805
Audio input object.
Definition klang.h:1338
virtual const SIGNAL & input() const
Definition klang.h:1343
virtual void operator<<(const SIGNAL &source)
Definition klang.h:1346
virtual void input(const SIGNAL &source)
Definition klang.h:1347
virtual void input()
Definition klang.h:1351
Signal modifier object (input-output)
Definition klang.h:1442
virtual void process() override
Definition klang.h:1453
Modifier< SIGNAL > & operator()(params... p)
Definition klang.h:1457
operator const SIGNAL &() const override
Definition klang.h:1450
operator const SIGNAL &() override
Definition klang.h:1449
Audio oscillator object (output)
Definition klang.h:1948
virtual void set(param frequency, relative phase)
Definition klang.h:1970
virtual void set(param frequency)
Definition klang.h:1960
virtual void set(relative phase)
Definition klang.h:1975
virtual void reset()
Definition klang.h:1957
virtual void set(param frequency, param phase)
Definition klang.h:1965
Audio output object.
Definition klang.h:1356
SIGNAL operator+(TYPE &other)
Definition klang.h:1371
SIGNAL operator/(TYPE &other)
Definition klang.h:1374
virtual operator const SIGNAL &() const
Definition klang.h:1368
virtual const SIGNAL & output() const
Definition klang.h:1360
virtual operator const SIGNAL &()
Definition klang.h:1367
SIGNAL operator*(TYPE &other)
Definition klang.h:1372
virtual void process()=0
SIGNAL operator-(TYPE &other)
Definition klang.h:1373
TYPE & operator>>(TYPE &destination)
Definition klang.h:1364
A line graph plotter.
Definition klang.h:2042
Audio input object (mono)
Definition klang.h:1982
Matrix processor.
Definition klang.h:745
float v[4][4]
Definition klang.h:746
float operator()(int col, int row) const
Definition klang.h:752
const float * operator[](int col) const
Definition klang.h:749
float * operator[](int col)
Definition klang.h:748
float & operator()(int col, int row)
Definition klang.h:751
Signal modifier object (mono input-output)
Definition klang.h:1988
Synthesiser note (mono)
Definition klang.h:3172
virtual bool process(buffer buffer)
Definition klang.h:3175
virtual void process() override=0
virtual void prepare()
Definition klang.h:3173
virtual bool process(buffer *buffer)
Definition klang.h:3184
Synthesiser note array.
Definition klang.h:3191
int assign()
Definition klang.h:3216
virtual ~Notes()
Definition klang.h:3294
void add(int count)
Definition klang.h:3204
Notes(SYNTH *synth)
Definition klang.h:3197
SYNTH * synth
Definition klang.h:3192
unsigned int noteOns
Definition klang.h:3213
unsigned int noteStart[128]
Definition klang.h:3214
FM operator.
Definition klang.h:3024
Operator & operator*(float amp)
Definition klang.h:3042
Envelope env
Definition klang.h:3025
Operator & operator>>(Operator &carrier)
Definition klang.h:3053
Operator & operator()(param f, relative phase)
Definition klang.h:3029
virtual Operator & operator=(const Envelope &points)
Definition klang.h:3037
virtual Operator & operator=(const Envelope::Points &points)
Definition klang.h:3032
Operator & operator()(relative phase)
Definition klang.h:3030
virtual void process() override
Definition klang.h:3047
Operator & operator()(param f)
Definition klang.h:3028
Amplitude amp
Definition klang.h:3026
Audio oscillator object (mono output)
Definition klang.h:1990
Audio output object (mono)
Definition klang.h:1984
Control parameter (phase)
Definition klang.h:811
Phase operator%(float modulus)
Definition klang.h:843
param & operator+=(const increment &increment)
Definition klang.h:825
Phase operator+(const increment &increment) const
Definition klang.h:834
param & operator+=(float increment)
Definition klang.h:816
Control parameter (pitch)
Definition klang.h:851
Pitch operator-(TYPE in)
Definition klang.h:874
Pitch operator/(TYPE in)
Definition klang.h:876
const Pitch * operator->()
Definition klang.h:866
Pitch operator*(TYPE in)
Definition klang.h:875
Pitch operator+(TYPE in)
Definition klang.h:873
static THREAD_LOCAL Conversion Frequency
Definition klang.h:871
const char * text() const
Definition klang.h:859
Base class for mini-plugin.
Definition klang.h:3078
virtual ~Plugin()
Definition klang.h:3079
Presets presets
Definition klang.h:3082
Controls controls
Definition klang.h:3081
Factory presets.
Definition klang.h:1160
void operator+=(const Preset &preset)
Definition klang.h:1161
void operator=(const Presets &presets)
Definition klang.h:1165
void add(const char *name, const Values... values)
Definition klang.h:1176
void operator=(std::initializer_list< Preset > presets)
Definition klang.h:1170
Sample rate constants.
Definition klang.h:891
SampleRate(float sr)
Definition klang.h:899
float w
angular frequency (omega)
Definition klang.h:896
float nyquist
nyquist frequency (f / 2)
Definition klang.h:897
int i
sample rate (integer)
Definition klang.h:893
float f
sample rate (float)
Definition klang.h:892
double d
sample rate (double)
Definition klang.h:894
float inv
1 / sample rate (inverse)
Definition klang.h:895
Stereo audio object adapter.
Definition klang.h:3468
Audio delay object (stereo)
Definition klang.h:3472
signal operator()(const TIME &delay)
Definition klang.h:3512
unsigned int max() const
Definition klang.h:3523
signal tap(float delay) const
Definition klang.h:3492
klang::Delay< SIZE > & r
Definition klang.h:3482
klang::Delay< SIZE > & l
Definition klang.h:3482
virtual void process() override
Definition klang.h:3507
signal tap(int delay) const
Definition klang.h:3485
Stereo effect mini-plugin.
Definition klang.h:3527
virtual void prepare()
Definition klang.h:3530
virtual ~Effect()
Definition klang.h:3528
virtual void process(Stereo::buffer buffer)
Definition klang.h:3532
virtual void process()
Definition klang.h:3531
Signal generator object (stereo output)
Definition klang.h:3389
Audio input object (stereo)
Definition klang.h:3385
virtual ~Input()
Definition klang.h:3385
Signal modifier object (stereo, input-output)
Definition klang.h:3391
Base class for stereo synthesiser note.
Definition klang.h:3546
virtual bool process(Stereo::buffer buffer)
Definition klang.h:3551
virtual void process() override=0
virtual bool process(mono::buffer *buffers)
Definition klang.h:3559
virtual void prepare()
Definition klang.h:3549
Audio oscillator object (stereo, output)
Definition klang.h:3393
Audio output object (stereo)
Definition klang.h:3387
virtual ~Output()
Definition klang.h:3387
Synthesiser note array (stereo)
Definition klang.h:3570
Synthesier mini-plugin (stereo)
Definition klang.h:3566
int indexOf(Note *note) const
Definition klang.h:3581
virtual void presetLoaded(int preset)
Definition klang.h:3577
virtual void optionChanged(int param, int item)
Definition klang.h:3578
virtual void buttonPressed(int param)
Definition klang.h:3579
virtual ~Synth()
Definition klang.h:3575
Stereo audio buffer.
Definition klang.h:3402
buffer & operator=(const buffer &in)
Definition klang.h:3418
buffer(mono::buffer &left, mono::buffer &right)
Definition klang.h:3407
buffer & operator=(const mono::signal in)
Definition klang.h:3434
bool finished() const
Definition klang.h:3411
void clear(int size)
Definition klang.h:3455
buffer & operator*=(const frame &in)
Definition klang.h:3432
frame operator=(const signal &in)
Definition klang.h:3414
operator const signal() const
Definition klang.h:3409
mono::buffer right
Definition klang.h:3404
frame operator[](int index)
Definition klang.h:3438
buffer & operator=(const frame &in)
Definition klang.h:3430
buffer & operator+=(const frame &in)
Definition klang.h:3431
signal operator[](int index) const
Definition klang.h:3442
buffer(const buffer &buffer)
Definition klang.h:3406
mono::buffer & left
Definition klang.h:3404
buffer & operator*=(const mono::signal in)
Definition klang.h:3436
buffer & operator+=(const mono::signal in)
Definition klang.h:3435
frame operator++(int)
Definition klang.h:3412
mono::buffer & channel(int index)
Definition klang.h:3446
buffer & operator+=(const signal &in)
Definition klang.h:3424
Stereo sample frame.
Definition klang.h:3311
frame & operator*=(float x)
Definition klang.h:3335
signal operator*(const mono::signal x) const
Definition klang.h:3355
frame & operator+=(const mono::signal x)
Definition klang.h:3328
frame & operator-=(int x)
Definition klang.h:3344
signal operator*(int x) const
Definition klang.h:3370
signal operator-(double x) const
Definition klang.h:3364
frame & operator/=(int x)
Definition klang.h:3346
signal operator*(const signal x) const
Definition klang.h:3350
signal operator+(const mono::signal x) const
Definition klang.h:3353
signal operator+(float x) const
Definition klang.h:3358
signal operator-(float x) const
Definition klang.h:3359
frame & operator+=(double x)
Definition klang.h:3338
frame & operator*=(const signal x)
Definition klang.h:3325
signal operator-(const mono::signal x) const
Definition klang.h:3354
signal operator/(double x) const
Definition klang.h:3366
frame & operator+=(const frame &x)
Definition klang.h:3318
frame & operator*=(const mono::signal x)
Definition klang.h:3330
frame & operator*=(int x)
Definition klang.h:3345
signal operator-(const signal x) const
Definition klang.h:3349
frame & operator-=(double x)
Definition klang.h:3339
signal operator-(int x) const
Definition klang.h:3369
frame & operator/=(const frame &x)
Definition klang.h:3321
frame & operator-=(const mono::signal x)
Definition klang.h:3329
frame & operator*=(const frame &x)
Definition klang.h:3320
frame & operator=(const signal &signal)
Definition klang.h:3373
frame & operator-=(const frame &x)
Definition klang.h:3319
signal operator/(int x) const
Definition klang.h:3371
frame & operator*=(double x)
Definition klang.h:3340
signal operator+(int x) const
Definition klang.h:3368
signal operator/(const mono::signal x) const
Definition klang.h:3356
mono::signal & l
Definition klang.h:3312
frame & operator+=(int x)
Definition klang.h:3343
signal operator*(double x) const
Definition klang.h:3365
signal operator+(double x) const
Definition klang.h:3363
frame & operator/=(const mono::signal x)
Definition klang.h:3331
frame & operator+=(const signal x)
Definition klang.h:3323
signal operator+(const signal x) const
Definition klang.h:3348
frame & operator/=(const signal x)
Definition klang.h:3326
frame & operator+=(float x)
Definition klang.h:3333
mono::signal & r
Definition klang.h:3313
frame & operator/=(float x)
Definition klang.h:3336
signal operator*(float x) const
Definition klang.h:3360
signal operator/(float x) const
Definition klang.h:3361
frame(mono::signal &left, mono::signal &right)
Definition klang.h:3315
frame & operator/=(double x)
Definition klang.h:3341
frame & operator-=(float x)
Definition klang.h:3334
frame & operator-=(const signal x)
Definition klang.h:3324
signal operator/(const signal x) const
Definition klang.h:3351
frame(signal &signal)
Definition klang.h:3316
Synthesiser object (mono)
Definition klang.h:3256
Notes< Synth, Note > notes
Definition klang.h:3259
int indexOf(Note *note) const
Definition klang.h:3268
virtual event onPreset(int index) override
Definition klang.h:3286
virtual ~Synth()
Definition klang.h:3262
virtual event onControl(int index, float value) override
Definition klang.h:3279
Lookup table object.
Definition klang.h:2429
Table(std::initializer_list< TYPE > values)
Definition klang.h:2459
Table(TYPE(*function)(TYPE))
Definition klang.h:2436
Table(void(*function)(TYPE, TYPE), TYPE arg)
Definition klang.h:2442
TYPE operator[](float index)
Definition klang.h:2465
Table(void(*function)(TYPE x, Result &y))
Definition klang.h:2449
String of characters representing text.
Definition klang.h:317
static Text from(const char *in)
Create a new Text object from a C-string.
Definition klang.h:331
operator const char *() const
Automatic cast to constant C-string.
Definition klang.h:325
int capacity() const
Maximum size of the string.
Definition klang.h:322
bool operator==(const char *in) const
Returns true if Text matches the given C-string.
Definition klang.h:344
char string[SIZE+1]
The character buffer.
Definition klang.h:319
const char * c_str() const
Return constant C-string.
Definition klang.h:328
bool operator!=(const char *in) const
Returns true if Text does not matches the given C-string.
Definition klang.h:349
void operator=(const char *in)
Assign C-String to Text object.
Definition klang.h:338
Klang language version (major.minor.build.debug)
Definition klang.h:77
unsigned char build
Definition klang.h:78
unsigned char extra
Definition klang.h:78
bool isDebug() const
Definition klang.h:79
unsigned char minor
Definition klang.h:78
unsigned char major
Definition klang.h:78
Constant scalar (pre-converted to double, float and int).
Definition klang.h:88
float operator^(int x) const
Definition klang.h:103
const float inv
Inverse of constant.
Definition klang.h:97
const double d
Constant as double.
Definition klang.h:94
const float f
Constant as float.
Definition klang.h:95
float operator^(double x) const
Definition klang.h:104
float operator^(float x) const
Constant raised to the power, x.
Definition klang.h:102
constexpr constant(double value) noexcept
Create a constant from the given value.
Definition klang.h:91
constexpr operator float() const noexcept
Definition klang.h:99
const int i
Constant as integer.
Definition klang.h:96
Control parameter (idecibels)
Definition klang.h:907
static THREAD_LOCAL Conversion Amplitude
Definition klang.h:918
const dB * operator->()
Definition klang.h:913
dB(float gain=0.f)
Definition klang.h:911
A phase or wavetable increment.
Definition klang.h:639
increment(float amount, const float size=2 *pi)
Create a phase increment (default to radians).
Definition klang.h:644
float amount
The current phase.
Definition klang.h:640
increment(float amount, double size)
Create a phase increment.
Definition klang.h:648
increment & operator=(float in)
Set current phase.
Definition klang.h:651
increment(float amount, int size)
Create a phase increment (wavetable size).
Definition klang.h:646
const float size
The length of a a full cycle (e.g. 2 pi or wavetable size)
Definition klang.h:641
A signal used as a control parameter.
Definition klang.h:657
param(const float initial=0.f)
Definition klang.h:659
param(const signal &in)
Definition klang.h:660
param & operator+=(const increment &increment)
Definition klang.h:664
param(Control &in)
Definition klang.h:1061
param(constant in)
Definition klang.h:658
param(signal &in)
Definition klang.h:661
A signal used as an offset relative to another signal.
Definition klang.h:487
A mono audio signal (equivalent to a float).
Definition klang.h:362
signal & operator*=(const signal &x)
Multiply (modulate) signal by another signal.
Definition klang.h:399
signal operator^(int x) const
Return a copy of the signal raised to the power of x.
Definition klang.h:462
operator const float() const
Definition klang.h:464
signal & operator=(Output &in)
Assign processed output of in to signal.
Definition klang.h:2149
signal(const double initial)
Create signal from a 64-bit double.
Definition klang.h:372
relative operator+() const
Returns a copy of the signal to treat as a relative offset (e.g. for phase modulation).
Definition klang.h:490
signal operator*(double x) const
Return a copy of the signal scaled by x.
Definition klang.h:444
signal operator^(double x) const
Return a copy of the signal raised to the power of x.
Definition klang.h:460
signal operator*(float x) const
Multiply (modulate) two signals.
Definition klang.h:435
bool isDenormal() const
Check if the signal contains a denormal value.
Definition klang.h:468
signal operator^(float x) const
Return a copy of the signal raised to the power of x.
Definition klang.h:458
signal & operator-=(float x)
Subtract the specified amount from the signal.
Definition klang.h:406
signal & operator/=(double x)
Divide signal by the specified amount.
Definition klang.h:419
signal & operator>>(signal &destination) const
Stream operator (feedforward; allows further processing)
Definition klang.h:384
signal & operator+=(const signal &x)
Add (mix) another signal to the signal.
Definition klang.h:395
operator float &()
Definition klang.h:465
signal & operator+=(float x)
Add the specified amount to the signal.
Definition klang.h:404
signal operator-(double x) const
Return a copy of the signal offset by -x.
Definition klang.h:442
signal & operator-=(double x)
Subtract the specified amount from the signal.
Definition klang.h:415
float value
Definition klang.h:363
int channels() const
Returns the number of channels (1 = mono).
Definition klang.h:474
signal & operator/=(int x)
Divide signal by the specified amount.
Definition klang.h:428
signal & operator-=(int x)
Subtract the specified amount from the signal.
Definition klang.h:424
signal operator-(float x) const
Subtract one signal from another.
Definition klang.h:433
signal operator*(int x) const
Return a copy of the signal scaled by x.
Definition klang.h:453
signal & operator+=(double x)
Add the specified amount to the signal.
Definition klang.h:413
signal & operator+=(int x)
Add the specified amount to the signal.
Definition klang.h:422
signal(const float initial=0.f)
Create signal from a 32-bit float..
Definition klang.h:369
signal operator/(int x) const
Return a copy of the signal divided by x.
Definition klang.h:455
signal & operator+=(Output &in)
Adds processed output of in to signal.
Definition klang.h:2155
signal operator+(float x) const
Add two signals together.
Definition klang.h:431
signal & operator*=(double x)
Multiply signal by the specified amount.
Definition klang.h:417
signal & operator-=(const signal &x)
Subtract another signal from the signal.
Definition klang.h:397
signal & operator/=(float x)
Divide signal by the specified amount.
Definition klang.h:410
signal operator+(double x) const
Return a copy of the signal offset by x.
Definition klang.h:440
signal operator/(float x) const
Divide one signal by another.
Definition klang.h:437
signal & operator*=(int x)
Multiply signal by the specified amount.
Definition klang.h:426
signal operator-(int x) const
Return a copy of the signal offset by -x.
Definition klang.h:451
signal(constant initial)
Create signal from a constant.
Definition klang.h:366
signal(const int value)
Create signal from an 32-bit signed integer.
Definition klang.h:375
signal operator/(double x) const
Return a copy of the signal divided by.
Definition klang.h:446
signal & operator/=(const signal &x)
Divide signal by another signal.
Definition klang.h:401
signal operator+(int x) const
Return a copy of the signal offset by x.
Definition klang.h:449
signal & operator*=(float x)
Multiply signal by the specified amount.
Definition klang.h:408
A multi-channel audio signal (e.g. stereo).
Definition klang.h:502
signals operator-(float x) const
Return a copy of the signal with each channel offset by -x.
Definition klang.h:591
const signal & operator[](int index) const
Return a read-only reference to the signal at the specified index (0 = left, 1 = right).
Definition klang.h:519
signals operator/(double x) const
Return a copy of the signal with each channel divided by x.
Definition klang.h:604
signal mono() const
Return the mono mix of a stereo channel.
Definition klang.h:514
signals operator-(const signal x) const
Return a copy of the multi-channel signal, subtracting a mono signal from each channel.
Definition klang.h:582
signals operator+(float x) const
Return a copy of the signal with each channel offset by x.
Definition klang.h:589
signals(Args... initial)
Create a multi-channel signal with the given channel values.
Definition klang.h:540
signals operator*(const signals x) const
Multiply (modulate) two multi-channel signals.
Definition klang.h:570
signals(float initial=0.f)
Create a stereo signal with the given value.
Definition klang.h:522
signals operator+(const signals x) const
Add two multi-channel signals together.
Definition klang.h:566
signals operator/(const signals x) const
Divide one multi-channel signal by another.
Definition klang.h:572
signals operator*(double x) const
Return a copy of the signal with each channel scaled by x.
Definition klang.h:602
signals & operator>>(signals &destination) const
Stream operator (feedforward; allows further processing).
Definition klang.h:551
signals operator+(double x) const
Return a copy of the signal with each channel offset by x.
Definition klang.h:598
signals operator*(const signal x) const
Return a copy of the multi-channel signal, multiplying (modulating) each channel by a mono signal.
Definition klang.h:584
signals operator/(float x) const
Return a copy of the signal with each channel divided by x.
Definition klang.h:595
signals operator*(float x) const
Return a copy of the signal with each channel scaled by x.
Definition klang.h:593
signals(int left, int right)
Create a stereo signal with the given left and right value.
Definition klang.h:533
signals operator-(int x) const
Return a copy of the signal with each channel offset by -x.
Definition klang.h:609
signals & operator+=(const signals x)
Add (mix) another signal to the signal.
Definition klang.h:557
signals(double left, double right)
Create a stereo signal with the given left and right value.
Definition klang.h:531
signals & operator/=(const signals x)
Divide signal by another signal.
Definition klang.h:563
signals & operator*=(const signals x)
Multiply (modulate) signal by another signal.
Definition klang.h:561
int channels() const
Returns the number of channels in the signal.
Definition klang.h:543
signals operator/(int x) const
Return a copy of the signal with each channel divided by x.
Definition klang.h:613
signals(float left, float right)
Create a stereo signal with the given left and right value.
Definition klang.h:529
signals operator-(double x) const
Return a copy of the signal with each channel offset by -x.
Definition klang.h:600
signals operator-(const signals x) const
Subtract one multi-channel signal from another.
Definition klang.h:568
signals & operator-=(const signals x)
Subtract another signal from the signal.
Definition klang.h:559
signals operator+(const signal x) const
Return a copy of the multi-channel signal, adding a mono signal to each channel.
Definition klang.h:580
signals(double initial)
Create a stereo signal with the given value.
Definition klang.h:524
signals operator/(const signal x) const
Return a copy of the multi-channel signal, dividing each channel by a mono signal.
Definition klang.h:586
signals operator+(int x) const
Return a copy of the signal with each channel offset by x.
Definition klang.h:607
signals operator*(int x) const
Return a copy of the signal with each channel scaled by x.
Definition klang.h:611
signals(int initial)
Create a stereo signal with the given value.
Definition klang.h:526
signal & operator[](int index)
Return a reference to the signal at the specified index (0 = left, 1 = right).
Definition klang.h:517
signals(Args &... initial)
Create a multi-channel signal with the given channel values.
Definition klang.h:537