LMMS
Loading...
Searching...
No Matches
primitives.h
Go to the documentation of this file.
1/* Calf DSP Library
2 * DSP primitives.
3 *
4 * Copyright (C) 2001-2007 Krzysztof Foltman
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02111-1307, USA.
20 */
21#ifndef __CALF_PRIMITIVES_H
22#define __CALF_PRIMITIVES_H
23
24#include <assert.h>
25#include <stdint.h>
26#include <stdio.h>
27#include <string.h>
28#include <cmath>
29#include <cstdlib>
30#include <map>
31#include <algorithm>
32
33#ifndef M_PI
34#define M_PI 3.14159265358979323846264338327
35#endif
36
37
38namespace dsp {
39
41inline void zero(float &v) {
42 v = 0.f;
43};
44
46inline void zero(double &v) {
47 v = 0.0;
48};
49
51inline void zero(uint64_t &v) { v = 0; };
53inline void zero(uint32_t &v) { v = 0; };
55inline void zero(uint16_t &v) { v = 0; };
57inline void zero(uint8_t &v) { v = 0; };
59inline void zero(int64_t &v) { v = 0; };
61inline void zero(int32_t &v) { v = 0; };
63inline void zero(int16_t &v) { v = 0; };
65inline void zero(int8_t &v) { v = 0; };
66
68template<class T>
69void zero(T *data, unsigned int size) {
70 T value;
72 for (unsigned int i=0; i<size; i++)
73 *data++ = value;
74}
75
77template<class T>
78void fill(T *data, T value, unsigned int size) {
79 for (unsigned int i=0; i<size; i++)
80 *data++ = value;
81}
82
83template<class T = float>struct stereo_sample {
87 inline stereo_sample() {
88 }
89 inline stereo_sample(T _left, T _right) {
90 left = _left;
91 right = _right;
92 }
93 inline stereo_sample(T _both) {
94 left = right = _both;
95 }
96 template<typename U>
98 left = value.left;
99 right = value.right;
100 }
101 inline stereo_sample& operator=(const T &value) {
102 left = right = value;
103 return *this;
104 }
105 template<typename U>
107 left = value.left;
108 right = value.right;
109 return *this;
110 }
111/*
112 inline operator T() const {
113 return (left+right)/2;
114 }
115*/
116 inline stereo_sample& operator*=(const T &multiplier) {
117 left *= multiplier;
118 right *= multiplier;
119 return *this;
120 }
122 left += value.left;
123 right += value.right;
124 return *this;
125 }
127 left -= value.left;
128 right -= value.right;
129 return *this;
130 }
131 template<typename U> inline stereo_sample<U> operator*(const U &value) const {
133 }
134 /*inline stereo_sample<float> operator*(float value) const {
135 return stereo_sample<float>(left*value, right*value);
136 }
137 inline stereo_sample<double> operator*(double value) const {
138 return stereo_sample<double>(left*value, right*value);
139 }*/
141 return stereo_sample(left+value.left, right+value.right);
142 }
144 return stereo_sample(left-value.left, right-value.right);
145 }
148 }
151 }
164};
165
167template<class T>
168inline stereo_sample<T> operator*(const T &value, const stereo_sample<T> &value2) {
169 return stereo_sample<T>(value2.left*value, value2.right*value);
170}
171
173template<class T>
174inline stereo_sample<T> operator+(const T &value, const stereo_sample<T> &value2) {
175 return stereo_sample<T>(value2.left+value, value2.right+value);
176}
177
179template<class T>
180inline stereo_sample<T> operator-(const T &value, const stereo_sample<T> &value2) {
181 return stereo_sample<T>(value-value2.left, value-value2.right);
182}
183
185template<typename T>
186inline stereo_sample<T> shr(stereo_sample<T> v, int bits = 1) {
187 v.left = shr(v.left, bits);
188 v.right = shr(v.right, bits);
189 return v;
190}
191
193template<typename T>
194inline void zero(stereo_sample<T> &v) {
195 dsp::zero(v.left);
196 dsp::zero(v.right);
197}
198
200template<typename T>
201inline T small_value() {
202 return 0;
203}
204
206template<>
207inline float small_value<float>() {
208 return (1.0/16777216.0); // allows for 2^-24, should be enough for 24-bit DACs at least :)
209}
210
212template<>
213inline double small_value<double>() {
214 return (1.0/16777216.0);
215}
216
218template<typename T>
219inline float mono(T v) {
220 return v;
221}
222
224template<typename T>
226 return shr(v.left+v.right);
227}
228
230template<typename T>
231inline T clip(T value, T min, T max) {
232 if (value < min) return min;
233 if (value > max) return max;
234 return value;
235}
236
238inline double clip11(double value) {
239 double a = fabs(value);
240 if (a<=1) return value;
241 return (value<0) ? -1.0 : 1.0;
242}
243
245inline float clip11(float value) {
246 float a = fabsf(value);
247 if (a<=1) return value;
248 return (value<0) ? -1.0f : 1.0f;
249}
250
252inline double clip01(double value) {
253 double a = fabs(value-0.5);
254 if (a<=0.5) return value;
255 return (a<0) ? -0.0 : 1.0;
256}
257
259inline float clip01(float value) {
260 float a = fabsf(value-0.5f);
261 if (a<=0.5f) return value;
262 return (value < 0) ? -0.0f : 1.0f;
263}
264
265// Linear interpolation (mix-way between v1 and v2).
266template<typename T, typename U>
267inline T lerp(T v1, T v2, U mix) {
268 return v1+(v2-v1)*mix;
269}
270
271// Linear interpolation for stereo values (mix-way between v1 and v2).
272template<typename T>
274 return stereo_sample<T>(v1.left+(v2.left-v1.left)*mix, v1.right+(v2.right-v1.right)*mix);
275}
276
280class decay
281{
282 double value, initial;
283 unsigned int age, mask;
284 bool active;
285public:
287 active = false;
288 mask = 127;
289 initial = value = 0.0;
290 }
291 inline bool get_active() {
292 return active;
293 }
294 inline double get() {
295 return active ? value : 0.0;
296 }
297 inline void set(double v) {
298 initial = value = v;
299 active = true;
300 age = 0;
301 }
302
303 inline void reinit()
304 {
305 initial = value;
306 age = 1;
307 }
308 inline void add(double v) {
309 if (active)
310 value += v;
311 else
312 value = v;
313 initial = value;
314 age = 0;
315 active = true;
316 }
317 static inline double calc_exp_constant(double times, double cycles)
318 {
319 if (cycles < 1.0)
320 cycles = 1.0;
321 return pow(times, 1.0 / cycles);
322 }
323 inline void age_exp(double constant, double epsilon) {
324 if (active) {
325 if (!(age & mask))
326 value = initial * pow(constant, (double)age);
327 else
328 value *= constant;
329 if (value < epsilon)
330 active = false;
331 age++;
332 }
333 }
334 inline void age_lin(double constant, double epsilon) {
335 if (active) {
336 if (!(age & mask))
337 value = initial - constant * age;
338 else
339 value -= constant;
340 if (value < epsilon)
341 active = false;
342 age++;
343 }
344 }
345 inline void deactivate() {
346 active = false;
347 value = 0;
348 }
349};
350
354inline void sanitize(float &value)
355{
356 // real number?
357 if (std::abs(value) < small_value<float>())
358 value = 0.f;
359 // close to 0?
360 const int val = *reinterpret_cast <const int *> (&value);
361 if ((val & 0x7F800000) == 0 && (val & 0x007FFFFF) != 0)
362 value = 0.f;
363}
364inline float _sanitize(float value)
365{
366 if (std::abs(value) < small_value<float>())
367 return 0.f;
368 return value;
369}
370
374inline void sanitize_denormal(float& value)
375{
376 if (!std::isnormal(value))
377 value = 0.f;
378}
379
383inline void sanitize_denormal(double & value)
384{
385 if (!std::isnormal(value))
386 value = 0.f;
387}
388
392inline void sanitize(double &value)
393{
394 if (std::abs(value) < small_value<double>())
395 value = 0.0;
396}
397
398inline double _sanitize(double value)
399{
400 if (std::abs(value) < small_value<double>())
401 return 0.0;
402
403 return value;
404}
405
408template<class T>
410{
411 sanitize(value.left);
412 sanitize(value.right);
413}
414
415inline float fract16(unsigned int value)
416{
417 return (value & 0xFFFF) * (1.0 / 65536.0);
418}
419
423template<class T, int N, int Multiplier>
425{
426public:
427 static bool initialized;
428 static T data[N+1];
430 if (initialized)
431 return;
432 initialized = true;
433 for (int i=0; i<N+1; i++)
434 data[i] = (T)(Multiplier*sin(i*2*M_PI*(1.0/N)));
435 }
436};
437
438template<class T, int N, int Multiplier>
440
441template<class T, int N, int Multiplier>
443
445inline int fastf2i_drm(float f)
446{
447#ifdef __X86__
448 volatile int v;
449 __asm ( "flds %1; fistpl %0" : "=m"(v) : "m"(f));
450 return v;
451#else
452 return (int)nearbyintf(f);
453#endif
454}
455
457inline float note_to_hz(double note, double detune_cents = 0.0)
458{
459 return 440 * pow(2.0, (note - 69 + detune_cents/100.0) / 12.0);
460}
461
468inline float normalized_hermite(float t, float p0, float p1, float m0, float m1)
469{
470 float t2 = t*t;
471 float t3 = t2*t;
472 return (2*t3 - 3*t2 + 1) * p0 + (t3 - 2*t2 + t) * m0 + (-2*t3 + 3*t2) * p1 + (t3-t2) * m1;
473}
474
483inline float hermite_interpolation(float x, float x0, float x1, float p0, float p1, float m0, float m1)
484{
485 float width = x1 - x0;
486 float t = (x - x0) / width;
487 m0 *= width;
488 m1 *= width;
489 float t2 = t*t;
490 float t3 = t2*t;
491
492 float ct0 = p0;
493 float ct1 = m0;
494 float ct2 = -3 * p0 - 2 * m0 + 3 * p1 - m1;
495 float ct3 = 2 * p0 + m0 - 2 * p1 + m1;
496
497 return ct3 * t3 + ct2 * t2 + ct1 * t + ct0;
498 //return (2*t3 - 3*t2 + 1) * p0 + (t3 - 2*t2 + t) * m0 + (-2*t3 + 3*t2) * p1 + (t3-t2) * m1;
499}
500
502inline float amp2dB(float amp)
503{
504 return 20 * log10(amp);
505}
506
507inline float dB2amp(float db)
508{
509 return exp((db / 20.0) * log(10.0));
510}
511
514inline void print_bits(size_t const size, void const * const ptr)
515{
516 unsigned char *b = (unsigned char*) ptr;
517 unsigned char byte;
518 for (int i = size - 1; i >=0 ; i--) {
519 for (int j = 7; j >= 0; j--) {
520 byte = b[i] & (1<<j);
521 byte >>= j;
522 printf("%u", byte);
523 }
524 }
525 puts("");
526}
527
528
530{
531 int note;
532 double cents;
533 double freq;
535 const char *name;
536};
537
538inline note_desc hz_to_note (double hz, double tune)
539{
540 note_desc desc;
541 static const char notenames[] = "C\0\0C#\0D\0\0D#\0E\0\0F\0\0F#\0G\0\0G#\0A\0\0A#\0B\0\0";
542 double f2 = log2(hz / tune);
543 double cn = fmod(f2 * 1200., 100.);
544 desc.freq = hz;
545 desc.note = std::max(0., round(12 * f2 + 69));
546 desc.name = notenames + (desc.note % 12) * 3;
547 desc.cents = (cn < -50) ? 100 + cn : (cn > 50) ? -(100 - cn) : cn;
548 desc.octave = int(desc.note / 12) - 1;
549 return desc;
550}
551
552
554
555inline double convert_periodic (double val, periodic_unit unit_in, periodic_unit unit_out)
556{
557 // calculates different periodical units into each other.
558 // it is used for e.g. pulsator or vintage delay to unify
559 // the selected timing method
560 if (unit_in == unit_out)
561 return val;
562 double freq = 0.;
563 switch (unit_in) {
564 case UNIT_BPM: freq = val / 60.; break;
565 case UNIT_MS: freq = 1. / (val / 1000.); break;
566 case UNIT_HZ: freq = val; break;
567 case UNIT_SYNC: freq = val / 60.; break;
568 }
569 switch (unit_out) {
570 default:
571 case UNIT_BPM: return freq * 60.;
572 case UNIT_MS: return (1. / freq) / 1000.;
573 case UNIT_HZ: return freq;
574 case UNIT_SYNC: return freq * 60.;
575 }
576};
577
578
579
580};
581#endif
uint8_t a
Definition Spc_Cpu.h:141
#define byte
Definition blargg_source.h:87
double initial
Definition primitives.h:282
static double calc_exp_constant(double times, double cycles)
Definition primitives.h:317
void age_exp(double constant, double epsilon)
Definition primitives.h:323
unsigned int mask
Definition primitives.h:283
void deactivate()
Definition primitives.h:345
void age_lin(double constant, double epsilon)
Definition primitives.h:334
bool get_active()
Definition primitives.h:291
double get()
Definition primitives.h:294
void set(double v)
Definition primitives.h:297
double value
Definition primitives.h:282
void reinit()
reinitialise envelope (must be called if shape changes from linear to exponential or vice versa in th...
Definition primitives.h:303
unsigned int age
Definition primitives.h:283
bool active
Definition primitives.h:284
decay()
Definition primitives.h:286
void add(double v)
Definition primitives.h:308
sine_table()
Definition primitives.h:429
static bool initialized
Definition primitives.h:427
static T data[N+1]
Definition primitives.h:428
#define M_PI
Definition compat.h:149
struct huft * t
Definition inflate.c:943
register unsigned j
Definition inflate.c:1576
unsigned v[N_MAX]
Definition inflate.c:1584
register unsigned i
Definition inflate.c:1575
unsigned x[BMAX+1]
Definition inflate.c:1586
unsigned f
Definition inflate.c:1572
static void v2(register WDL_FFT_REAL *a)
Definition fft.c:1099
#define U(x)
Definition fmopl.c:132
static PuglViewHint int value
Definition pugl.h:1708
static int width
Definition pugl.h:1593
JHUFF_TBL long freq[]
Definition jchuff.h:50
int val
Definition jpeglib.h:956
unsigned short uint16_t
Definition mid.cpp:99
int int32_t
Definition mid.cpp:97
unsigned int uint32_t
Definition mid.cpp:100
short int16_t
Definition mid.cpp:96
unsigned char uint8_t
Definition mid.cpp:98
signed char int8_t
Definition mid.cpp:95
Definition audio_fx.h:36
double clip01(double value)
Clip a double to [0.0, +1.0].
Definition primitives.h:252
float _sanitize(float value)
Definition primitives.h:364
T lerp(T v1, T v2, U mix)
Definition primitives.h:267
void zero(float &v)
Set a float to zero.
Definition primitives.h:41
stereo_sample< T > operator-(const T &value, const stereo_sample< T > &value2)
Subtract stereo_value from constant (yields stereo_value of course).
Definition primitives.h:180
double convert_periodic(double val, periodic_unit unit_in, periodic_unit unit_out)
Definition primitives.h:555
fixed_point< T, FractBits > operator*(int v, fixed_point< T, FractBits > v2)
Definition fixed_point.h:258
stereo_sample< T > operator+(const T &value, const stereo_sample< T > &value2)
Add constant to stereo_value.
Definition primitives.h:174
periodic_unit
Definition primitives.h:553
@ UNIT_HZ
Definition primitives.h:553
@ UNIT_SYNC
Definition primitives.h:553
@ UNIT_MS
Definition primitives.h:553
@ UNIT_BPM
Definition primitives.h:553
T sine_table< T, N, Multiplier >::data[N+1]
Definition primitives.h:442
float dB2amp(float db)
convert dB to amplitude value
Definition primitives.h:507
uint32_t shr(uint32_t v, int bits=1)
Definition fixed_point.h:26
T small_value()
'Small value' for integer and other types
Definition primitives.h:201
float normalized_hermite(float t, float p0, float p1, float m0, float m1)
Definition primitives.h:468
float fract16(unsigned int value)
Definition primitives.h:415
double clip11(double value)
Clip a double to [-1.0, +1.0].
Definition primitives.h:238
note_desc hz_to_note(double hz, double tune)
Definition primitives.h:538
int fastf2i_drm(float f)
fast float to int conversion using default rounding mode
Definition primitives.h:445
void sanitize(float &value)
Definition primitives.h:354
float small_value< float >()
'Small value' for floats (2^-24) - used for primitive underrun prevention. The value is pretty much a...
Definition primitives.h:207
double small_value< double >()
'Small value' for doubles (2^-24) - used for primitive underrun prevention. The value is pretty much ...
Definition primitives.h:213
float hermite_interpolation(float x, float x0, float x1, float p0, float p1, float m0, float m1)
Definition primitives.h:483
void print_bits(size_t const size, void const *const ptr)
Definition primitives.h:514
float mono(T v)
Convert a single value to single value = do nothing :) (but it's a generic with specialisation for st...
Definition primitives.h:219
void sanitize_denormal(float &value)
Definition primitives.h:374
T clip(T value, T min, T max)
Clip a value to [min, max].
Definition primitives.h:231
float note_to_hz(double note, double detune_cents=0.0)
Convert MIDI note to frequency in Hz.
Definition primitives.h:457
void fill(Buf &buf, T value)
Definition buffer.h:50
float amp2dB(float amp)
convert amplitude value to dB
Definition primitives.h:502
#define N
Definition nseel-cfunc.c:36
#define min(x, y)
Definition os.h:74
#define max(x, y)
Definition os.h:78
Definition primitives.h:530
double freq
Definition primitives.h:533
const char * name
Definition primitives.h:535
int octave
Definition primitives.h:534
int note
Definition primitives.h:531
double cents
Definition primitives.h:532
Definition primitives.h:83
stereo_sample< T > operator+(const stereo_sample< T > &value)
Definition primitives.h:140
stereo_sample< T > operator+(const T &value)
Definition primitives.h:146
stereo_sample< double > operator-(double value)
Definition primitives.h:161
stereo_sample(const stereo_sample< U > &value)
Definition primitives.h:97
stereo_sample & operator*=(const T &multiplier)
Definition primitives.h:116
stereo_sample< double > operator+(double value)
Definition primitives.h:158
stereo_sample< T > operator-(const stereo_sample< T > &value)
Definition primitives.h:143
stereo_sample< float > operator-(float value)
Definition primitives.h:155
stereo_sample()
default constructor - preserves T's semantics (ie. no implicit initialization to 0)
Definition primitives.h:87
stereo_sample(T _both)
Definition primitives.h:93
stereo_sample< U > operator*(const U &value) const
Definition primitives.h:131
stereo_sample & operator=(const T &value)
Definition primitives.h:101
T right
Definition primitives.h:85
stereo_sample & operator=(const stereo_sample< U > &value)
Definition primitives.h:106
stereo_sample & operator-=(const stereo_sample< T > &value)
Definition primitives.h:126
T left
Definition primitives.h:84
stereo_sample< T > operator-(const T &value)
Definition primitives.h:149
stereo_sample(T _left, T _right)
Definition primitives.h:89
stereo_sample & operator+=(const stereo_sample< T > &value)
Definition primitives.h:121
stereo_sample< float > operator+(float value)
Definition primitives.h:152
b
Definition crypt.c:628
ulg size
Definition extract.c:2350
typedef int(UZ_EXP MsgFn)()