BEAST - Free Software Audio Synthesizer and Tracker  0.10.0
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 (Bse::MusicalTuning musical_tuning); /* returns [-132..+132] */
382 double bse_transpose_factor (Bse::MusicalTuning musical_tuning, int index /* [-132..+132] */);
383 
384 /* --- cents (1/100th of a semitone) --- */
385 
386 double bse_cent_tune (double fine_tune);
387 
398 static inline double bse_cent_tune_fast (int fine_tune /* -100..+100 */) G_GNUC_CONST;
399 
400 /* --- implementation details --- */
401 static inline double G_GNUC_CONST
402 bse_approx_atan1 (register double x)
403 {
404  if (x < 0) /* make use of -atan(-x)==atan(x) */
405  {
406  register double numerator, denominator = -1.0;
407 
408  denominator += x * 0.81901156857081841441890603235599; /* d1 */
409  numerator = x * 0.41156875521951602506487246309908; /* -n1 */
410  denominator *= x;
411  numerator += -1.0091272542790025586079663559158; /* n2 */
412  denominator += 1.0091272542790025586079663559158; /* d2 */
413 
414  return -1.0 - numerator / denominator;
415  }
416  else
417  {
418  register double numerator, denominator = 1.0;
419 
420  denominator += x * 0.81901156857081841441890603235599; /* d1 */
421  numerator = x * -0.41156875521951602506487246309908; /* n1 */
422  denominator *= x;
423  numerator += -1.0091272542790025586079663559158; /* n2 */
424  denominator += 1.0091272542790025586079663559158; /* d2 */
425 
426  return 1.0 + numerator / denominator;
427  }
428  /* atan1_positive(x)=1+(x*-0.411568755219516-1.009127254279)/((1+x*0.81901156857)*x+1.009127254279)
429  * atan1(x)=x<0 ? -atan1_positive(-x) : atan1_positive(x)
430  */
431 }
432 
433 static inline double G_GNUC_CONST
434 bse_approx_qcircle1 (register double x)
435 {
436  double numerator = 1.20460124790369468987715633298929 * x - 1.20460124790369468987715633298929;
437  double denominator = x - 1.20460124790369468987715633298929;
438  /* R1(x)=(1.2046012479036946898771563 * x - 1.2046012479036946898771563) / (x - 1.2046012479036946898771563) */
439  return numerator / denominator;
440 }
441 
442 static inline double G_GNUC_CONST
443 bse_approx_qcircle2 (register double x)
444 {
445  double numerator = 1.20460124790369468987715633298929*x;
446  double denominator = x + 0.20460124790369468987715633298929;
447  /* R2(x)=1.2046012479036946898771563*x/(x + 0.2046012479036946898771563) */
448  return numerator / denominator;
449 }
450 
451 static inline double G_GNUC_CONST
452 bse_approx_qcircle3 (register double x)
453 {
454  double numerator = 0.20460124790369468987715633298929 - 0.20460124790369468987715633298929 * x;
455  double denominator = x + 0.20460124790369468987715633298929;
456  /* R3(x)=(0.2046012479036946898771563 - 0.2046012479036946898771563 * x) / (x + 0.2046012479036946898771563) */
457  return numerator / denominator;
458 }
459 
460 static inline double G_GNUC_CONST
461 bse_approx_qcircle4 (register double x)
462 {
463  double numerator = -0.20460124790369468987715633298929 * x;
464  double denominator = x - 1.20460124790369468987715633298929;
465  /* R4(x)=-0.2046012479036946898771563 * x / (x - 1.2046012479036946898771563) */
466  return numerator / denominator;
467 }
468 
469 static inline double G_GNUC_CONST
470 bse_approx2_exp2 (float ex)
471 {
472  register BseFloatIEEE754 fp = { 0, };
473  register int i = bse_ftoi (ex);
474  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
475  register double x = ex - i;
476  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
477  x * (0.24022650695910071233355126316333)));
478 }
479 
480 static inline double G_GNUC_CONST
481 bse_approx3_exp2 (float ex)
482 {
483  register BseFloatIEEE754 fp = { 0, };
484  register int i = bse_ftoi (ex);
485  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
486  register double x = ex - i;
487  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
488  x * (0.24022650695910071233355126316333 +
489  x * (0.055504108664821579953142263768622))));
490  /* exp2frac(x)=x-ftoi(x)
491  * exp2a3(x)=2**ftoi(x)*(1+exp2frac(x)*(0.6931471805599453+exp2frac(x)*(0.2402265069591+exp2frac(x)*0.0555041086648)))
492  */
493 }
494 
495 static inline double G_GNUC_CONST
496 bse_approx4_exp2 (float ex)
497 {
498  register BseFloatIEEE754 fp = { 0, };
499  register int i = bse_ftoi (ex);
500  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
501  register double x = ex - i;
502  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
503  x * (0.24022650695910071233355126316333 +
504  x * (0.055504108664821579953142263768622 +
505  x * (0.0096181291076284771619790715736589)))));
506  /* ftoi(x)=int(x<-0.0 ? x - 0.5 : x + 0.5)
507  * exp2frac(x)=x-ftoi(x)
508  * exp2a4(x)=2**ftoi(x)*(1+exp2frac(x)*(0.6931471805599453+exp2frac(x)*(0.2402265069591+exp2frac(x)*(0.0555041086648+exp2frac(x)*0.009618129107628477))))
509  */
510 }
511 
512 static inline double G_GNUC_CONST
513 bse_approx5_exp2 (float ex)
514 {
515  register BseFloatIEEE754 fp = { 0, };
516  register int i = bse_ftoi (ex);
517  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
518  register double x = ex - i;
519  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
520  x * (0.24022650695910071233355126316333 +
521  x * (0.055504108664821579953142263768622 +
522  x * (0.0096181291076284771619790715736589 +
523  x * (0.0013333558146428443423412221987996))))));
524 }
525 
526 static inline double G_GNUC_CONST
527 bse_approx6_exp2 (float ex)
528 {
529  register BseFloatIEEE754 fp = { 0, };
530  register int i = bse_ftoi (ex);
531  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
532  register double x = ex - i;
533  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
534  x * (0.24022650695910071233355126316333 +
535  x * (0.055504108664821579953142263768622 +
536  x * (0.0096181291076284771619790715736589 +
537  x * (0.0013333558146428443423412221987996 +
538  x * (0.00015403530393381609954437097332742)))))));
539 }
540 
541 static inline double G_GNUC_CONST
542 bse_approx7_exp2 (float ex)
543 {
544  register BseFloatIEEE754 fp = { 0, };
545  register int i = bse_ftoi (ex);
546  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
547  register double x = ex - i;
548  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
549  x * (0.24022650695910071233355126316333 +
550  x * (0.055504108664821579953142263768622 +
551  x * (0.0096181291076284771619790715736589 +
552  x * (0.0013333558146428443423412221987996 +
553  x * (0.00015403530393381609954437097332742 +
554  x * (0.00001525273380405984028002543901201))))))));
555 }
556 
557 static inline double G_GNUC_CONST
558 bse_approx8_exp2 (float ex)
559 {
560  register BseFloatIEEE754 fp = { 0, };
561  register int i = bse_ftoi (ex);
562  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
563  register double x = ex - i;
564  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
565  x * (0.24022650695910071233355126316333 +
566  x * (0.055504108664821579953142263768622 +
567  x * (0.0096181291076284771619790715736589 +
568  x * (0.0013333558146428443423412221987996 +
569  x * (0.00015403530393381609954437097332742 +
570  x * (0.00001525273380405984028002543901201 +
571  x * (0.0000013215486790144309488403758228288)))))))));
572 }
573 
574 static inline double G_GNUC_CONST
575 bse_approx9_exp2 (float ex)
576 {
577  register BseFloatIEEE754 fp = { 0, };
578  register int i = bse_ftoi (ex);
579  fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i;
580  register double x = ex - i;
581  return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 +
582  x * (0.24022650695910071233355126316333 +
583  x * (0.055504108664821579953142263768622 +
584  x * (0.0096181291076284771619790715736589 +
585  x * (0.0013333558146428443423412221987996 +
586  x * (0.00015403530393381609954437097332742 +
587  x * (0.00001525273380405984028002543901201 +
588  x * (0.0000013215486790144309488403758228288 +
589  x * 0.00000010178086009239699727490007597745)))))))));
590 }
591 
592 static inline double G_GNUC_CONST
593 bse_approx2_tanh (float x)
594 {
595  if (G_UNLIKELY (x < -20))
596  return -1;
597  if (G_UNLIKELY (x > 20))
598  return 1;
599  register double bpot = bse_approx2_exp2 (x * BSE_2_DIV_LN2);
600  return (bpot - 1) / (bpot + 1);
601 }
602 
603 static inline double G_GNUC_CONST
604 bse_approx3_tanh (float x)
605 {
606  if (G_UNLIKELY (x < -20))
607  return -1;
608  if (G_UNLIKELY (x > 20))
609  return 1;
610  register double bpot = bse_approx3_exp2 (x * BSE_2_DIV_LN2);
611  return (bpot - 1) / (bpot + 1);
612 }
613 
614 static inline double G_GNUC_CONST
615 bse_approx4_tanh (float x)
616 {
617  if (G_UNLIKELY (x < -20))
618  return -1;
619  if (G_UNLIKELY (x > 20))
620  return 1;
621  register double bpot = bse_approx4_exp2 (x * BSE_2_DIV_LN2);
622  return (bpot - 1) / (bpot + 1);
623  /* tanha4(x)=x<-20 ? -1 : x>20 ? 1 : (exp2a4(x*2.885390081777926814719849362)-1) / (exp2a4(x*2.885390081777926814719849362)+1) */
624 }
625 
626 static inline double G_GNUC_CONST
627 bse_approx5_tanh (float x)
628 {
629  if (G_UNLIKELY (x < -20))
630  return -1;
631  if (G_UNLIKELY (x > 20))
632  return 1;
633  register double bpot = bse_approx5_exp2 (x * BSE_2_DIV_LN2);
634  return (bpot - 1) / (bpot + 1);
635 }
636 
637 static inline double G_GNUC_CONST
638 bse_approx6_tanh (float x)
639 {
640  if (G_UNLIKELY (x < -20))
641  return -1;
642  if (G_UNLIKELY (x > 20))
643  return 1;
644  register double bpot = bse_approx6_exp2 (x * BSE_2_DIV_LN2);
645  return (bpot - 1) / (bpot + 1);
646 }
647 
648 static inline double G_GNUC_CONST
649 bse_approx7_tanh (float x)
650 {
651  if (G_UNLIKELY (x < -20))
652  return -1;
653  if (G_UNLIKELY (x > 20))
654  return 1;
655  register double bpot = bse_approx7_exp2 (x * BSE_2_DIV_LN2);
656  return (bpot - 1) / (bpot + 1);
657 }
658 
659 static inline double G_GNUC_CONST
660 bse_approx8_tanh (float x)
661 {
662  if (G_UNLIKELY (x < -20))
663  return -1;
664  if (G_UNLIKELY (x > 20))
665  return 1;
666  register double bpot = bse_approx8_exp2 (x * BSE_2_DIV_LN2);
667  return (bpot - 1) / (bpot + 1);
668 }
669 
670 static inline double G_GNUC_CONST
671 bse_approx9_tanh (float x)
672 {
673  if (G_UNLIKELY (x < -20))
674  return -1;
675  if (G_UNLIKELY (x > 20))
676  return 1;
677  register double bpot = bse_approx9_exp2 (x * BSE_2_DIV_LN2);
678  return (bpot - 1) / (bpot + 1);
679 }
680 
681 static inline double G_GNUC_CONST
682 bse_saturate_hard (double value,
683  double limit)
684 {
685  register double v1 = fabsf (value + limit);
686  register double v2 = fabsf (value - limit);
687  return 0.5 * (v1 - v2); /* CLAMP() without branching */
688 }
689 
690 static inline double G_GNUC_CONST
691 bse_saturate_branching (double value,
692  double limit)
693 {
694  if (G_UNLIKELY (value >= limit))
695  return limit;
696  if (G_UNLIKELY (value <= limit))
697  return -limit;
698  return value;
699 }
700 
701 void _bse_init_signal (void);
702 
703 extern const double * const bse_cent_table;
704 
705 static inline double G_GNUC_CONST
706 bse_cent_tune_fast (int fine_tune)
707 {
708  return bse_cent_table[CLAMP (fine_tune, -100, 100)];
709 }
710 
711 G_END_DECLS
712 
713 #endif /* __BSE_SIGNAL_H__ */
double bse_approx_atan1_prescale(double boost_amount)
Definition: bsemathsignal.cc:649
fabsf
Definition: bseieee754.hh:129
double bse_cent_tune(double fine_tune)
Definition: bsemathsignal.cc:210
Definition: bsemathsignal.hh:74