BEAST/BSE - Better Audio System and Sound Engine  0.9.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 
9 G_BEGIN_DECLS
10 
14 #define BSE_SIGNAL_EPSILON (1.15e-14) /* 1.16415321826934814453125e-9 ~= 1/2^33 */
15 
19 #define BSE_SIGNAL_KAPPA (1.5)
20 
26 #define BSE_SIGNAL_RAISING_EDGE(v1,v2) ((v1) < (v2))
27 
30 #define BSE_SIGNAL_FALLING_EDGE(v1,v2) ((v1) > (v2))
31 
35 #define BSE_SIGNAL_FREQ_CHANGED(v1,v2) (fabs ((v1) - (v2)) > 1e-7)
36 
39 #define BSE_SIGNAL_FREQ_EQUALS(v1,v2) (!BSE_SIGNAL_FREQ_CHANGED (v1, v2))
40 
44 #define BSE_SIGNAL_MOD_CHANGED(v1,v2) (fabs ((v1) - (v2)) > 1e-8)
45 
49 #define BSE_SIGNAL_GAIN_CHANGED(v1,v2) (fabs ((v1) - (v2)) > 1e-8)
50 
54 #define BSE_SIGNAL_TO_FREQ_FACTOR (BSE_MAX_FREQUENCY)
55 #define BSE_SIGNAL_FROM_FREQ_FACTOR (1.0 / BSE_MAX_FREQUENCY)
56 #define BSE_SIGNAL_TO_FREQ(value) (BSE_FREQ_FROM_VALUE (value))
57 #define BSE_SIGNAL_FROM_FREQ(freq) (BSE_VALUE_FROM_FREQ (freq))
58 
59 #define BSE_SIGNAL_CLIP(v) bse_signal_value_clip (v)
60 
61 static inline double bse_signal_value_clip (register double x) G_GNUC_CONST;
62 static inline double G_GNUC_CONST
63 bse_signal_value_clip (register double x)
64 {
65  if (G_UNLIKELY (x > 1.0))
66  return 1.0;
67  if (G_UNLIKELY (x < -1.0))
68  return -1.0;
69  return x;
70 }
71 
72 
73 /* --- frequency modulation --- */
74 typedef struct {
75  gfloat fm_strength; /* linear: 0..1, exponential: n_octaves */
76  guint exponential_fm : 1;
77  gfloat signal_freq; /* for ifreq == NULL (as BSE_SIGNAL_FROM_FREQ) */
78  gint fine_tune; /* -100..+100 */
80 
81 void bse_frequency_modulator (const BseFrequencyModulator *fm,
82  guint n_values,
83  const gfloat *ifreq,
84  const gfloat *ifmod,
85  gfloat *fm_buffer);
86 
87 
88 /* --- windows --- */
89 double bse_window_bartlett (double x); /* narrowest */
90 double bse_window_blackman (double x);
91 double bse_window_cos (double x);
92 double bse_window_hamming (double x);
93 double bse_window_sinc (double x);
94 double bse_window_rect (double x); /* widest */
95 
96 
97 /* --- function approximations --- */
98 
110 static inline double bse_approx_atan1 (register double x) G_GNUC_CONST;
111 
120 double bse_approx_atan1_prescale (double boost_amount);
121 
131 static inline double bse_approx_qcircle1 (register double x) G_GNUC_CONST;
132 
142 static inline double bse_approx_qcircle2 (register double x) G_GNUC_CONST;
143 
153 static inline double bse_approx_qcircle3 (register double x) G_GNUC_CONST;
154 
164 static inline double bse_approx_qcircle4 (register double x) G_GNUC_CONST;
165 
176 static inline double bse_approx2_exp2 (float ex) G_GNUC_CONST;
177 
188 static inline double bse_approx3_exp2 (float ex) G_GNUC_CONST;
189 
200 static inline double bse_approx4_exp2 (float ex) G_GNUC_CONST;
201 
212 static inline double bse_approx5_exp2 (float ex) G_GNUC_CONST;
213 
224 static inline double bse_approx6_exp2 (float ex) G_GNUC_CONST;
225 
236 static inline double bse_approx7_exp2 (float ex) G_GNUC_CONST;
237 
249 static inline double bse_approx8_exp2 (float ex) G_GNUC_CONST;
250 
262 static inline double bse_approx9_exp2 (float ex) G_GNUC_CONST;
263 
273 static inline double bse_approx2_tanh (float x) G_GNUC_CONST;
274 
284 static inline double bse_approx3_tanh (float x) G_GNUC_CONST;
285 
295 static inline double bse_approx4_tanh (float x) G_GNUC_CONST;
296 
306 static inline double bse_approx5_tanh (float x) G_GNUC_CONST;
307 
317 static inline double bse_approx6_tanh (float x) G_GNUC_CONST;
318 
328 static inline double bse_approx7_tanh (float x) G_GNUC_CONST;
329 
340 static inline double bse_approx8_tanh (float x) G_GNUC_CONST;
341 
352 static inline double bse_approx9_tanh (float x) G_GNUC_CONST;
353 
364 static inline double bse_saturate_hard (double value,
365  double limit) G_GNUC_CONST;
366 
377 static inline double bse_saturate_branching (double value,
378  double limit) G_GNUC_CONST;
379 
380 /* --- semitone factors (for +-11 octaves) --- */
381 const double* bse_semitone_table_from_tuning (BseMusicalTuningType musical_tuning); /* returns [-132..+132] */
382 double bse_transpose_factor (BseMusicalTuningType musical_tuning,
383  int index /* [-132..+132] */);
384 
385 /* --- cents (1/100th of a semitone) --- */
386 
387 double bse_cent_tune (double fine_tune);
388 
399 static inline double bse_cent_tune_fast (int fine_tune /* -100..+100 */) G_GNUC_CONST;
400 
401 /* --- implementation details --- */
402 static inline double G_GNUC_CONST
403 bse_approx_atan1 (register double x)
404 {
405  if (x < 0) /* make use of -atan(-x)==atan(x) */
406  {
407  register double numerator, denominator = -1.0;
408 
409  denominator += x * 0.81901156857081841441890603235599; /* d1 */
410  numerator = x * 0.41156875521951602506487246309908; /* -n1 */
411  denominator *= x;
412  numerator += -1.0091272542790025586079663559158; /* n2 */
413  denominator += 1.0091272542790025586079663559158; /* d2 */
414 
415  return -1.0 - numerator / denominator;
416  }
417  else
418  {
419  register double numerator, denominator = 1.0;
420 
421  denominator += x * 0.81901156857081841441890603235599; /* d1 */
422  numerator = x * -0.41156875521951602506487246309908; /* n1 */
423  denominator *= x;
424  numerator += -1.0091272542790025586079663559158; /* n2 */
425  denominator += 1.0091272542790025586079663559158; /* d2 */
426 
427  return 1.0 + numerator / denominator;
428  }
429  /* atan1_positive(x)=1+(x*-0.411568755219516-1.009127254279)/((1+x*0.81901156857)*x+1.009127254279)
430  * atan1(x)=x<0 ? -atan1_positive(-x) : atan1_positive(x)
431  */
432 }
433 
434 static inline double G_GNUC_CONST
435 bse_approx_qcircle1 (register double x)
436 {
437  double numerator = 1.20460124790369468987715633298929 * x - 1.20460124790369468987715633298929;
438  double denominator = x - 1.20460124790369468987715633298929;
439  /* R1(x)=(1.2046012479036946898771563 * x - 1.2046012479036946898771563) / (x - 1.2046012479036946898771563) */
440  return numerator / denominator;
441 }
442 
443 static inline double G_GNUC_CONST
444 bse_approx_qcircle2 (register double x)
445 {
446  double numerator = 1.20460124790369468987715633298929*x;
447  double denominator = x + 0.20460124790369468987715633298929;
448  /* R2(x)=1.2046012479036946898771563*x/(x + 0.2046012479036946898771563) */
449  return numerator / denominator;
450 }
451 
452 static inline double G_GNUC_CONST
453 bse_approx_qcircle3 (register double x)
454 {
455  double numerator = 0.20460124790369468987715633298929 - 0.20460124790369468987715633298929 * x;
456  double denominator = x + 0.20460124790369468987715633298929;
457  /* R3(x)=(0.2046012479036946898771563 - 0.2046012479036946898771563 * x) / (x + 0.2046012479036946898771563) */
458  return numerator / denominator;
459 }
460 
461 static inline double G_GNUC_CONST
462 bse_approx_qcircle4 (register double x)
463 {
464  double numerator = -0.20460124790369468987715633298929 * x;
465  double denominator = x - 1.20460124790369468987715633298929;
466  /* R4(x)=-0.2046012479036946898771563 * x / (x - 1.2046012479036946898771563) */
467  return numerator / denominator;
468 }
469 
470 static inline double G_GNUC_CONST
471 bse_approx2_exp2 (float ex)
472 {
473  register BseFloatIEEE754 fp = { 0, };
474  register int i = bse_ftoi (ex);
475  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
476  register double x = ex - i;
477  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
478  x * (0.24022650695910071233355126316333)));
479 }
480 
481 static inline double G_GNUC_CONST
482 bse_approx3_exp2 (float ex)
483 {
484  register BseFloatIEEE754 fp = { 0, };
485  register int i = bse_ftoi (ex);
486  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
487  register double x = ex - i;
488  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
489  x * (0.24022650695910071233355126316333 +
490  x * (0.055504108664821579953142263768622))));
491  /* exp2frac(x)=x-ftoi(x)
492  * exp2a3(x)=2**ftoi(x)*(1+exp2frac(x)*(0.6931471805599453+exp2frac(x)*(0.2402265069591+exp2frac(x)*0.0555041086648)))
493  */
494 }
495 
496 static inline double G_GNUC_CONST
497 bse_approx4_exp2 (float ex)
498 {
499  register BseFloatIEEE754 fp = { 0, };
500  register int i = bse_ftoi (ex);
501  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
502  register double x = ex - i;
503  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
504  x * (0.24022650695910071233355126316333 +
505  x * (0.055504108664821579953142263768622 +
506  x * (0.0096181291076284771619790715736589)))));
507  /* ftoi(x)=int(x<-0.0 ? x - 0.5 : x + 0.5)
508  * exp2frac(x)=x-ftoi(x)
509  * exp2a4(x)=2**ftoi(x)*(1+exp2frac(x)*(0.6931471805599453+exp2frac(x)*(0.2402265069591+exp2frac(x)*(0.0555041086648+exp2frac(x)*0.009618129107628477))))
510  */
511 }
512 
513 static inline double G_GNUC_CONST
514 bse_approx5_exp2 (float ex)
515 {
516  register BseFloatIEEE754 fp = { 0, };
517  register int i = bse_ftoi (ex);
518  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
519  register double x = ex - i;
520  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
521  x * (0.24022650695910071233355126316333 +
522  x * (0.055504108664821579953142263768622 +
523  x * (0.0096181291076284771619790715736589 +
524  x * (0.0013333558146428443423412221987996))))));
525 }
526 
527 static inline double G_GNUC_CONST
528 bse_approx6_exp2 (float ex)
529 {
530  register BseFloatIEEE754 fp = { 0, };
531  register int i = bse_ftoi (ex);
532  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
533  register double x = ex - i;
534  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
535  x * (0.24022650695910071233355126316333 +
536  x * (0.055504108664821579953142263768622 +
537  x * (0.0096181291076284771619790715736589 +
538  x * (0.0013333558146428443423412221987996 +
539  x * (0.00015403530393381609954437097332742)))))));
540 }
541 
542 static inline double G_GNUC_CONST
543 bse_approx7_exp2 (float ex)
544 {
545  register BseFloatIEEE754 fp = { 0, };
546  register int i = bse_ftoi (ex);
547  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
548  register double x = ex - i;
549  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
550  x * (0.24022650695910071233355126316333 +
551  x * (0.055504108664821579953142263768622 +
552  x * (0.0096181291076284771619790715736589 +
553  x * (0.0013333558146428443423412221987996 +
554  x * (0.00015403530393381609954437097332742 +
555  x * (0.00001525273380405984028002543901201))))))));
556 }
557 
558 static inline double G_GNUC_CONST
559 bse_approx8_exp2 (float ex)
560 {
561  register BseFloatIEEE754 fp = { 0, };
562  register int i = bse_ftoi (ex);
563  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
564  register double x = ex - i;
565  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
566  x * (0.24022650695910071233355126316333 +
567  x * (0.055504108664821579953142263768622 +
568  x * (0.0096181291076284771619790715736589 +
569  x * (0.0013333558146428443423412221987996 +
570  x * (0.00015403530393381609954437097332742 +
571  x * (0.00001525273380405984028002543901201 +
572  x * (0.0000013215486790144309488403758228288)))))))));
573 }
574 
575 static inline double G_GNUC_CONST
576 bse_approx9_exp2 (float ex)
577 {
578  register BseFloatIEEE754 fp = { 0, };
579  register int i = bse_ftoi (ex);
580  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
581  register double x = ex - i;
582  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
583  x * (0.24022650695910071233355126316333 +
584  x * (0.055504108664821579953142263768622 +
585  x * (0.0096181291076284771619790715736589 +
586  x * (0.0013333558146428443423412221987996 +
587  x * (0.00015403530393381609954437097332742 +
588  x * (0.00001525273380405984028002543901201 +
589  x * (0.0000013215486790144309488403758228288 +
590  x * 0.00000010178086009239699727490007597745)))))))));
591 }
592 
593 static inline double G_GNUC_CONST
594 bse_approx2_tanh (float x)
595 {
596  if (G_UNLIKELY (x < -20))
597  return -1;
598  if (G_UNLIKELY (x > 20))
599  return 1;
600  register double bpot = bse_approx2_exp2 (x * BSE_2_DIV_LN2);
601  return (bpot - 1) / (bpot + 1);
602 }
603 
604 static inline double G_GNUC_CONST
605 bse_approx3_tanh (float x)
606 {
607  if (G_UNLIKELY (x < -20))
608  return -1;
609  if (G_UNLIKELY (x > 20))
610  return 1;
611  register double bpot = bse_approx3_exp2 (x * BSE_2_DIV_LN2);
612  return (bpot - 1) / (bpot + 1);
613 }
614 
615 static inline double G_GNUC_CONST
616 bse_approx4_tanh (float x)
617 {
618  if (G_UNLIKELY (x < -20))
619  return -1;
620  if (G_UNLIKELY (x > 20))
621  return 1;
622  register double bpot = bse_approx4_exp2 (x * BSE_2_DIV_LN2);
623  return (bpot - 1) / (bpot + 1);
624  /* tanha4(x)=x<-20 ? -1 : x>20 ? 1 : (exp2a4(x*2.885390081777926814719849362)-1) / (exp2a4(x*2.885390081777926814719849362)+1) */
625 }
626 
627 static inline double G_GNUC_CONST
628 bse_approx5_tanh (float x)
629 {
630  if (G_UNLIKELY (x < -20))
631  return -1;
632  if (G_UNLIKELY (x > 20))
633  return 1;
634  register double bpot = bse_approx5_exp2 (x * BSE_2_DIV_LN2);
635  return (bpot - 1) / (bpot + 1);
636 }
637 
638 static inline double G_GNUC_CONST
639 bse_approx6_tanh (float x)
640 {
641  if (G_UNLIKELY (x < -20))
642  return -1;
643  if (G_UNLIKELY (x > 20))
644  return 1;
645  register double bpot = bse_approx6_exp2 (x * BSE_2_DIV_LN2);
646  return (bpot - 1) / (bpot + 1);
647 }
648 
649 static inline double G_GNUC_CONST
650 bse_approx7_tanh (float x)
651 {
652  if (G_UNLIKELY (x < -20))
653  return -1;
654  if (G_UNLIKELY (x > 20))
655  return 1;
656  register double bpot = bse_approx7_exp2 (x * BSE_2_DIV_LN2);
657  return (bpot - 1) / (bpot + 1);
658 }
659 
660 static inline double G_GNUC_CONST
661 bse_approx8_tanh (float x)
662 {
663  if (G_UNLIKELY (x < -20))
664  return -1;
665  if (G_UNLIKELY (x > 20))
666  return 1;
667  register double bpot = bse_approx8_exp2 (x * BSE_2_DIV_LN2);
668  return (bpot - 1) / (bpot + 1);
669 }
670 
671 static inline double G_GNUC_CONST
672 bse_approx9_tanh (float x)
673 {
674  if (G_UNLIKELY (x < -20))
675  return -1;
676  if (G_UNLIKELY (x > 20))
677  return 1;
678  register double bpot = bse_approx9_exp2 (x * BSE_2_DIV_LN2);
679  return (bpot - 1) / (bpot + 1);
680 }
681 
682 static inline double G_GNUC_CONST
683 bse_saturate_hard (double value,
684  double limit)
685 {
686  register double v1 = fabsf (value + limit);
687  register double v2 = fabsf (value - limit);
688  return 0.5 * (v1 - v2); /* CLAMP() without branching */
689 }
690 
691 static inline double G_GNUC_CONST
692 bse_saturate_branching (double value,
693  double limit)
694 {
695  if (G_UNLIKELY (value >= limit))
696  return limit;
697  if (G_UNLIKELY (value <= limit))
698  return -limit;
699  return value;
700 }
701 
702 void _bse_init_signal (void);
703 
704 extern const double * const bse_cent_table;
705 
706 static inline double G_GNUC_CONST
707 bse_cent_tune_fast (int fine_tune)
708 {
709  return bse_cent_table[CLAMP (fine_tune, -100, 100)];
710 }
711 
712 G_END_DECLS
713 
714 #endif /* __BSE_SIGNAL_H__ */
double bse_approx_atan1_prescale(double boost_amount)
Definition: bsemathsignal.cc:650
fabsf
Definition: bseieee754.hh:129
double bse_cent_tune(double fine_tune)
Definition: bsemathsignal.cc:210
Definition: bsemathsignal.hh:74