Beast - Music Synthesizer and Composer  0.11.1+10.g2da35
bsemathsignal.hh
Go to the documentation of this file.
1  // Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
2 #ifndef __BSE_SIGNAL_H__
3 #define __BSE_SIGNAL_H__
4 
5 #include <bse/bsemath.hh>
6 #include <bse/bseglobals.hh>
7 #include <bse/bsetype.hh> // for BseMusicalTuningType
8 
12 #define BSE_SIGNAL_EPSILON (1.15e-14) /* 1.16415321826934814453125e-9 ~= 1/2^33 */
13 
17 #define BSE_SIGNAL_KAPPA (1.5)
18 
24 #define BSE_SIGNAL_RAISING_EDGE(v1,v2) ((v1) < (v2))
25 
28 #define BSE_SIGNAL_FALLING_EDGE(v1,v2) ((v1) > (v2))
29 
33 #define BSE_SIGNAL_FREQ_CHANGED(v1,v2) (fabs ((v1) - (v2)) > 1e-7)
34 
37 #define BSE_SIGNAL_FREQ_EQUALS(v1,v2) (!BSE_SIGNAL_FREQ_CHANGED (v1, v2))
38 
42 #define BSE_SIGNAL_MOD_CHANGED(v1,v2) (fabs ((v1) - (v2)) > 1e-8)
43 
47 #define BSE_SIGNAL_GAIN_CHANGED(v1,v2) (fabs ((v1) - (v2)) > 1e-8)
48 
52 #define BSE_SIGNAL_TO_FREQ_FACTOR (BSE_MAX_FREQUENCY)
53 #define BSE_SIGNAL_FROM_FREQ_FACTOR (1.0 / BSE_MAX_FREQUENCY)
54 #define BSE_SIGNAL_TO_FREQ(value) (BSE_FREQ_FROM_VALUE (value))
55 #define BSE_SIGNAL_FROM_FREQ(freq) (BSE_VALUE_FROM_FREQ (freq))
56 
57 #define BSE_SIGNAL_CLIP(v) bse_signal_value_clip (v)
58 
59 static inline double bse_signal_value_clip (register double x) G_GNUC_CONST;
60 static inline double G_GNUC_CONST
61 bse_signal_value_clip (register double x)
62 {
63  if (G_UNLIKELY (x > 1.0))
64  return 1.0;
65  if (G_UNLIKELY (x < -1.0))
66  return -1.0;
67  return x;
68 }
69 
70 
71 /* --- frequency modulation --- */
72 typedef struct {
73  gfloat fm_strength; /* linear: 0..1, exponential: n_octaves */
74  guint exponential_fm : 1;
75  gfloat signal_freq; /* for ifreq == NULL (as BSE_SIGNAL_FROM_FREQ) */
76  gint fine_tune; /* -100..+100 */
78 
79 void bse_frequency_modulator (const BseFrequencyModulator *fm,
80  guint n_values,
81  const gfloat *ifreq,
82  const gfloat *ifmod,
83  gfloat *fm_buffer);
84 
85 
86 /* --- windows --- */
87 double bse_window_bartlett (double x); /* narrowest */
88 double bse_window_blackman (double x);
89 double bse_window_cos (double x);
90 double bse_window_hamming (double x);
91 double bse_window_sinc (double x);
92 double bse_window_rect (double x); /* widest */
93 
94 
95 /* --- function approximations --- */
96 
108 static inline double bse_approx_atan1 (register double x) G_GNUC_CONST;
109 
118 double bse_approx_atan1_prescale (double boost_amount);
119 
129 static inline double bse_approx_qcircle1 (register double x) G_GNUC_CONST;
130 
140 static inline double bse_approx_qcircle2 (register double x) G_GNUC_CONST;
141 
151 static inline double bse_approx_qcircle3 (register double x) G_GNUC_CONST;
152 
162 static inline double bse_approx_qcircle4 (register double x) G_GNUC_CONST;
163 
174 static inline double bse_approx2_exp2 (float ex) G_GNUC_CONST;
175 
186 static inline double bse_approx3_exp2 (float ex) G_GNUC_CONST;
187 
198 static inline double bse_approx4_exp2 (float ex) G_GNUC_CONST;
199 
210 static inline double bse_approx5_exp2 (float ex) G_GNUC_CONST;
211 
222 static inline double bse_approx6_exp2 (float ex) G_GNUC_CONST;
223 
234 static inline double bse_approx7_exp2 (float ex) G_GNUC_CONST;
235 
247 static inline double bse_approx8_exp2 (float ex) G_GNUC_CONST;
248 
260 static inline double bse_approx9_exp2 (float ex) G_GNUC_CONST;
261 
271 static inline double bse_approx2_tanh (float x) G_GNUC_CONST;
272 
282 static inline double bse_approx3_tanh (float x) G_GNUC_CONST;
283 
293 static inline double bse_approx4_tanh (float x) G_GNUC_CONST;
294 
304 static inline double bse_approx5_tanh (float x) G_GNUC_CONST;
305 
315 static inline double bse_approx6_tanh (float x) G_GNUC_CONST;
316 
326 static inline double bse_approx7_tanh (float x) G_GNUC_CONST;
327 
338 static inline double bse_approx8_tanh (float x) G_GNUC_CONST;
339 
350 static inline double bse_approx9_tanh (float x) G_GNUC_CONST;
351 
362 static inline double bse_saturate_hard (double value,
363  double limit) G_GNUC_CONST;
364 
375 static inline double bse_saturate_branching (double value,
376  double limit) G_GNUC_CONST;
377 
378 /* --- semitone factors (for +-11 octaves) --- */
379 const double* bse_semitone_table_from_tuning (Bse::MusicalTuning musical_tuning); /* returns [-132..+132] */
380 double bse_transpose_factor (Bse::MusicalTuning musical_tuning, int index /* [-132..+132] */);
381 
382 /* --- cents (1/100th of a semitone) --- */
383 
384 double bse_cent_tune (double fine_tune);
385 
396 static inline double bse_cent_tune_fast (int fine_tune /* -100..+100 */) G_GNUC_CONST;
397 
398 /* --- implementation details --- */
399 static inline double G_GNUC_CONST
400 bse_approx_atan1 (register double x)
401 {
402  if (x < 0) /* make use of -atan(-x)==atan(x) */
403  {
404  register double numerator, denominator = -1.0;
405 
406  denominator += x * 0.81901156857081841441890603235599; /* d1 */
407  numerator = x * 0.41156875521951602506487246309908; /* -n1 */
408  denominator *= x;
409  numerator += -1.0091272542790025586079663559158; /* n2 */
410  denominator += 1.0091272542790025586079663559158; /* d2 */
411 
412  return -1.0 - numerator / denominator;
413  }
414  else
415  {
416  register double numerator, denominator = 1.0;
417 
418  denominator += x * 0.81901156857081841441890603235599; /* d1 */
419  numerator = x * -0.41156875521951602506487246309908; /* n1 */
420  denominator *= x;
421  numerator += -1.0091272542790025586079663559158; /* n2 */
422  denominator += 1.0091272542790025586079663559158; /* d2 */
423 
424  return 1.0 + numerator / denominator;
425  }
426  /* atan1_positive(x)=1+(x*-0.411568755219516-1.009127254279)/((1+x*0.81901156857)*x+1.009127254279)
427  * atan1(x)=x<0 ? -atan1_positive(-x) : atan1_positive(x)
428  */
429 }
430 
431 static inline double G_GNUC_CONST
432 bse_approx_qcircle1 (register double x)
433 {
434  double numerator = 1.20460124790369468987715633298929 * x - 1.20460124790369468987715633298929;
435  double denominator = x - 1.20460124790369468987715633298929;
436  /* R1(x)=(1.2046012479036946898771563 * x - 1.2046012479036946898771563) / (x - 1.2046012479036946898771563) */
437  return numerator / denominator;
438 }
439 
440 static inline double G_GNUC_CONST
441 bse_approx_qcircle2 (register double x)
442 {
443  double numerator = 1.20460124790369468987715633298929*x;
444  double denominator = x + 0.20460124790369468987715633298929;
445  /* R2(x)=1.2046012479036946898771563*x/(x + 0.2046012479036946898771563) */
446  return numerator / denominator;
447 }
448 
449 static inline double G_GNUC_CONST
450 bse_approx_qcircle3 (register double x)
451 {
452  double numerator = 0.20460124790369468987715633298929 - 0.20460124790369468987715633298929 * x;
453  double denominator = x + 0.20460124790369468987715633298929;
454  /* R3(x)=(0.2046012479036946898771563 - 0.2046012479036946898771563 * x) / (x + 0.2046012479036946898771563) */
455  return numerator / denominator;
456 }
457 
458 static inline double G_GNUC_CONST
459 bse_approx_qcircle4 (register double x)
460 {
461  double numerator = -0.20460124790369468987715633298929 * x;
462  double denominator = x - 1.20460124790369468987715633298929;
463  /* R4(x)=-0.2046012479036946898771563 * x / (x - 1.2046012479036946898771563) */
464  return numerator / denominator;
465 }
466 
467 static inline double G_GNUC_CONST
468 bse_approx2_exp2 (float ex)
469 {
470  register BseFloatIEEE754 fp = { 0, };
471  register int i = bse_ftoi (ex);
472  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
473  register double x = ex - i;
474  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
475  x * (0.24022650695910071233355126316333)));
476 }
477 
478 static inline double G_GNUC_CONST
479 bse_approx3_exp2 (float ex)
480 {
481  register BseFloatIEEE754 fp = { 0, };
482  register int i = bse_ftoi (ex);
483  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
484  register double x = ex - i;
485  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
486  x * (0.24022650695910071233355126316333 +
487  x * (0.055504108664821579953142263768622))));
488  /* exp2frac(x)=x-ftoi(x)
489  * exp2a3(x)=2**ftoi(x)*(1+exp2frac(x)*(0.6931471805599453+exp2frac(x)*(0.2402265069591+exp2frac(x)*0.0555041086648)))
490  */
491 }
492 
493 static inline double G_GNUC_CONST
494 bse_approx4_exp2 (float ex)
495 {
496  register BseFloatIEEE754 fp = { 0, };
497  register int i = bse_ftoi (ex);
498  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
499  register double x = ex - i;
500  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
501  x * (0.24022650695910071233355126316333 +
502  x * (0.055504108664821579953142263768622 +
503  x * (0.0096181291076284771619790715736589)))));
504  /* ftoi(x)=int(x<-0.0 ? x - 0.5 : x + 0.5)
505  * exp2frac(x)=x-ftoi(x)
506  * exp2a4(x)=2**ftoi(x)*(1+exp2frac(x)*(0.6931471805599453+exp2frac(x)*(0.2402265069591+exp2frac(x)*(0.0555041086648+exp2frac(x)*0.009618129107628477))))
507  */
508 }
509 
510 static inline double G_GNUC_CONST
511 bse_approx5_exp2 (float ex)
512 {
513  register BseFloatIEEE754 fp = { 0, };
514  register int i = bse_ftoi (ex);
515  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
516  register double x = ex - i;
517  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
518  x * (0.24022650695910071233355126316333 +
519  x * (0.055504108664821579953142263768622 +
520  x * (0.0096181291076284771619790715736589 +
521  x * (0.0013333558146428443423412221987996))))));
522 }
523 
524 static inline double G_GNUC_CONST
525 bse_approx6_exp2 (float ex)
526 {
527  register BseFloatIEEE754 fp = { 0, };
528  register int i = bse_ftoi (ex);
529  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
530  register double x = ex - i;
531  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
532  x * (0.24022650695910071233355126316333 +
533  x * (0.055504108664821579953142263768622 +
534  x * (0.0096181291076284771619790715736589 +
535  x * (0.0013333558146428443423412221987996 +
536  x * (0.00015403530393381609954437097332742)))))));
537 }
538 
539 static inline double G_GNUC_CONST
540 bse_approx7_exp2 (float ex)
541 {
542  register BseFloatIEEE754 fp = { 0, };
543  register int i = bse_ftoi (ex);
544  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
545  register double x = ex - i;
546  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
547  x * (0.24022650695910071233355126316333 +
548  x * (0.055504108664821579953142263768622 +
549  x * (0.0096181291076284771619790715736589 +
550  x * (0.0013333558146428443423412221987996 +
551  x * (0.00015403530393381609954437097332742 +
552  x * (0.00001525273380405984028002543901201))))))));
553 }
554 
555 static inline double G_GNUC_CONST
556 bse_approx8_exp2 (float ex)
557 {
558  register BseFloatIEEE754 fp = { 0, };
559  register int i = bse_ftoi (ex);
560  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
561  register double x = ex - i;
562  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
563  x * (0.24022650695910071233355126316333 +
564  x * (0.055504108664821579953142263768622 +
565  x * (0.0096181291076284771619790715736589 +
566  x * (0.0013333558146428443423412221987996 +
567  x * (0.00015403530393381609954437097332742 +
568  x * (0.00001525273380405984028002543901201 +
569  x * (0.0000013215486790144309488403758228288)))))))));
570 }
571 
572 static inline double G_GNUC_CONST
573 bse_approx9_exp2 (float ex)
574 {
575  register BseFloatIEEE754 fp = { 0, };
576  register int i = bse_ftoi (ex);
577  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
578  register double x = ex - i;
579  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
580  x * (0.24022650695910071233355126316333 +
581  x * (0.055504108664821579953142263768622 +
582  x * (0.0096181291076284771619790715736589 +
583  x * (0.0013333558146428443423412221987996 +
584  x * (0.00015403530393381609954437097332742 +
585  x * (0.00001525273380405984028002543901201 +
586  x * (0.0000013215486790144309488403758228288 +
587  x * 0.00000010178086009239699727490007597745)))))))));
588 }
589 
590 static inline double G_GNUC_CONST
591 bse_approx2_tanh (float x)
592 {
593  if (G_UNLIKELY (x < -20))
594  return -1;
595  if (G_UNLIKELY (x > 20))
596  return 1;
597  register double bpot = bse_approx2_exp2 (x * BSE_2_DIV_LN2);
598  return (bpot - 1) / (bpot + 1);
599 }
600 
601 static inline double G_GNUC_CONST
602 bse_approx3_tanh (float x)
603 {
604  if (G_UNLIKELY (x < -20))
605  return -1;
606  if (G_UNLIKELY (x > 20))
607  return 1;
608  register double bpot = bse_approx3_exp2 (x * BSE_2_DIV_LN2);
609  return (bpot - 1) / (bpot + 1);
610 }
611 
612 static inline double G_GNUC_CONST
613 bse_approx4_tanh (float x)
614 {
615  if (G_UNLIKELY (x < -20))
616  return -1;
617  if (G_UNLIKELY (x > 20))
618  return 1;
619  register double bpot = bse_approx4_exp2 (x * BSE_2_DIV_LN2);
620  return (bpot - 1) / (bpot + 1);
621  /* tanha4(x)=x<-20 ? -1 : x>20 ? 1 : (exp2a4(x*2.885390081777926814719849362)-1) / (exp2a4(x*2.885390081777926814719849362)+1) */
622 }
623 
624 static inline double G_GNUC_CONST
625 bse_approx5_tanh (float x)
626 {
627  if (G_UNLIKELY (x < -20))
628  return -1;
629  if (G_UNLIKELY (x > 20))
630  return 1;
631  register double bpot = bse_approx5_exp2 (x * BSE_2_DIV_LN2);
632  return (bpot - 1) / (bpot + 1);
633 }
634 
635 static inline double G_GNUC_CONST
636 bse_approx6_tanh (float x)
637 {
638  if (G_UNLIKELY (x < -20))
639  return -1;
640  if (G_UNLIKELY (x > 20))
641  return 1;
642  register double bpot = bse_approx6_exp2 (x * BSE_2_DIV_LN2);
643  return (bpot - 1) / (bpot + 1);
644 }
645 
646 static inline double G_GNUC_CONST
647 bse_approx7_tanh (float x)
648 {
649  if (G_UNLIKELY (x < -20))
650  return -1;
651  if (G_UNLIKELY (x > 20))
652  return 1;
653  register double bpot = bse_approx7_exp2 (x * BSE_2_DIV_LN2);
654  return (bpot - 1) / (bpot + 1);
655 }
656 
657 static inline double G_GNUC_CONST
658 bse_approx8_tanh (float x)
659 {
660  if (G_UNLIKELY (x < -20))
661  return -1;
662  if (G_UNLIKELY (x > 20))
663  return 1;
664  register double bpot = bse_approx8_exp2 (x * BSE_2_DIV_LN2);
665  return (bpot - 1) / (bpot + 1);
666 }
667 
668 static inline double G_GNUC_CONST
669 bse_approx9_tanh (float x)
670 {
671  if (G_UNLIKELY (x < -20))
672  return -1;
673  if (G_UNLIKELY (x > 20))
674  return 1;
675  register double bpot = bse_approx9_exp2 (x * BSE_2_DIV_LN2);
676  return (bpot - 1) / (bpot + 1);
677 }
678 
679 static inline double G_GNUC_CONST
680 bse_saturate_hard (double value,
681  double limit)
682 {
683  register double v1 = fabsf (value + limit);
684  register double v2 = fabsf (value - limit);
685  return 0.5 * (v1 - v2); /* CLAMP() without branching */
686 }
687 
688 static inline double G_GNUC_CONST
689 bse_saturate_branching (double value,
690  double limit)
691 {
692  if (G_UNLIKELY (value >= limit))
693  return limit;
694  if (G_UNLIKELY (value <= limit))
695  return -limit;
696  return value;
697 }
698 
699 void _bse_init_signal (void);
700 
701 extern const double * const bse_cent_table;
702 
703 static inline double G_GNUC_CONST
704 bse_cent_tune_fast (int fine_tune)
705 {
706  return bse_cent_table[CLAMP (fine_tune, -100, 100)];
707 }
708 
709 #endif /* __BSE_SIGNAL_H__ */
double bse_approx_atan1_prescale(double boost_amount)
Definition: bsemathsignal.cc:649
fabsf
Definition: bseieee754.hh:127
double bse_cent_tune(double fine_tune)
Definition: bsemathsignal.cc:210
Definition: bsemathsignal.hh:72