BEAST/BSE - Better Audio System and Sound Engine
0.8.2
|
00001 // Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html 00002 #ifndef __BSE_SIGNAL_H__ 00003 #define __BSE_SIGNAL_H__ 00004 00005 #include <bse/bsemath.hh> 00006 #include <bse/bseglobals.hh> 00007 #include <bse/bsetype.hh> // for BseMusicalTuningType 00008 00009 G_BEGIN_DECLS 00010 00014 #define BSE_SIGNAL_EPSILON (1.15e-14) /* 1.16415321826934814453125e-9 ~= 1/2^33 */ 00015 00019 #define BSE_SIGNAL_KAPPA (1.5) 00020 00026 #define BSE_SIGNAL_RAISING_EDGE(v1,v2) ((v1) < (v2)) 00027 00030 #define BSE_SIGNAL_FALLING_EDGE(v1,v2) ((v1) > (v2)) 00031 00035 #define BSE_SIGNAL_FREQ_CHANGED(v1,v2) (fabs ((v1) - (v2)) > 1e-7) 00036 00039 #define BSE_SIGNAL_FREQ_EQUALS(v1,v2) (!BSE_SIGNAL_FREQ_CHANGED (v1, v2)) 00040 00044 #define BSE_SIGNAL_MOD_CHANGED(v1,v2) (fabs ((v1) - (v2)) > 1e-8) 00045 00049 #define BSE_SIGNAL_GAIN_CHANGED(v1,v2) (fabs ((v1) - (v2)) > 1e-8) 00050 00054 #define BSE_SIGNAL_TO_FREQ_FACTOR (BSE_MAX_FREQUENCY) 00055 #define BSE_SIGNAL_FROM_FREQ_FACTOR (1.0 / BSE_MAX_FREQUENCY) 00056 #define BSE_SIGNAL_TO_FREQ(value) (BSE_FREQ_FROM_VALUE (value)) 00057 #define BSE_SIGNAL_FROM_FREQ(freq) (BSE_VALUE_FROM_FREQ (freq)) 00058 00059 #define BSE_SIGNAL_CLIP(v) bse_signal_value_clip (v) 00060 00061 static inline double bse_signal_value_clip (register double x) G_GNUC_CONST; 00062 static inline double G_GNUC_CONST 00063 bse_signal_value_clip (register double x) 00064 { 00065 if (G_UNLIKELY (x > 1.0)) 00066 return 1.0; 00067 if (G_UNLIKELY (x < -1.0)) 00068 return -1.0; 00069 return x; 00070 } 00071 00072 00073 /* --- frequency modulation --- */ 00074 typedef struct { 00075 gfloat fm_strength; /* linear: 0..1, exponential: n_octaves */ 00076 guint exponential_fm : 1; 00077 gfloat signal_freq; /* for ifreq == NULL (as BSE_SIGNAL_FROM_FREQ) */ 00078 gint fine_tune; /* -100..+100 */ 00079 } BseFrequencyModulator; 00080 00081 void bse_frequency_modulator (const BseFrequencyModulator *fm, 00082 guint n_values, 00083 const gfloat *ifreq, 00084 const gfloat *ifmod, 00085 gfloat *fm_buffer); 00086 00087 00088 /* --- windows --- */ 00089 double bse_window_bartlett (double x); /* narrowest */ 00090 double bse_window_blackman (double x); 00091 double bse_window_cos (double x); 00092 double bse_window_hamming (double x); 00093 double bse_window_sinc (double x); 00094 double bse_window_rect (double x); /* widest */ 00095 00096 00097 /* --- function approximations --- */ 00098 00110 static inline double bse_approx_atan1 (register double x) G_GNUC_CONST; 00111 00120 double bse_approx_atan1_prescale (double boost_amount); 00121 00131 static inline double bse_approx_qcircle1 (register double x) G_GNUC_CONST; 00132 00142 static inline double bse_approx_qcircle2 (register double x) G_GNUC_CONST; 00143 00153 static inline double bse_approx_qcircle3 (register double x) G_GNUC_CONST; 00154 00164 static inline double bse_approx_qcircle4 (register double x) G_GNUC_CONST; 00165 00176 static inline double bse_approx2_exp2 (float ex) G_GNUC_CONST; 00177 00188 static inline double bse_approx3_exp2 (float ex) G_GNUC_CONST; 00189 00200 static inline double bse_approx4_exp2 (float ex) G_GNUC_CONST; 00201 00212 static inline double bse_approx5_exp2 (float ex) G_GNUC_CONST; 00213 00224 static inline double bse_approx6_exp2 (float ex) G_GNUC_CONST; 00225 00236 static inline double bse_approx7_exp2 (float ex) G_GNUC_CONST; 00237 00249 static inline double bse_approx8_exp2 (float ex) G_GNUC_CONST; 00250 00262 static inline double bse_approx9_exp2 (float ex) G_GNUC_CONST; 00263 00273 static inline double bse_approx2_tanh (float x) G_GNUC_CONST; 00274 00284 static inline double bse_approx3_tanh (float x) G_GNUC_CONST; 00285 00295 static inline double bse_approx4_tanh (float x) G_GNUC_CONST; 00296 00306 static inline double bse_approx5_tanh (float x) G_GNUC_CONST; 00307 00317 static inline double bse_approx6_tanh (float x) G_GNUC_CONST; 00318 00328 static inline double bse_approx7_tanh (float x) G_GNUC_CONST; 00329 00340 static inline double bse_approx8_tanh (float x) G_GNUC_CONST; 00341 00352 static inline double bse_approx9_tanh (float x) G_GNUC_CONST; 00353 00364 static inline double bse_saturate_hard (double value, 00365 double limit) G_GNUC_CONST; 00366 00377 static inline double bse_saturate_branching (double value, 00378 double limit) G_GNUC_CONST; 00379 00380 /* --- semitone factors (for +-11 octaves) --- */ 00381 const double* bse_semitone_table_from_tuning (BseMusicalTuningType musical_tuning); /* returns [-132..+132] */ 00382 double bse_transpose_factor (BseMusicalTuningType musical_tuning, 00383 int index /* [-132..+132] */); 00384 00385 /* --- cents (1/100th of a semitone) --- */ 00386 00387 double bse_cent_tune (double fine_tune); 00388 00399 static inline double bse_cent_tune_fast (int fine_tune /* -100..+100 */) G_GNUC_CONST; 00400 00401 /* --- implementation details --- */ 00402 static inline double G_GNUC_CONST 00403 bse_approx_atan1 (register double x) 00404 { 00405 if (x < 0) /* make use of -atan(-x)==atan(x) */ 00406 { 00407 register double numerator, denominator = -1.0; 00408 00409 denominator += x * 0.81901156857081841441890603235599; /* d1 */ 00410 numerator = x * 0.41156875521951602506487246309908; /* -n1 */ 00411 denominator *= x; 00412 numerator += -1.0091272542790025586079663559158; /* n2 */ 00413 denominator += 1.0091272542790025586079663559158; /* d2 */ 00414 00415 return -1.0 - numerator / denominator; 00416 } 00417 else 00418 { 00419 register double numerator, denominator = 1.0; 00420 00421 denominator += x * 0.81901156857081841441890603235599; /* d1 */ 00422 numerator = x * -0.41156875521951602506487246309908; /* n1 */ 00423 denominator *= x; 00424 numerator += -1.0091272542790025586079663559158; /* n2 */ 00425 denominator += 1.0091272542790025586079663559158; /* d2 */ 00426 00427 return 1.0 + numerator / denominator; 00428 } 00429 /* atan1_positive(x)=1+(x*-0.411568755219516-1.009127254279)/((1+x*0.81901156857)*x+1.009127254279) 00430 * atan1(x)=x<0 ? -atan1_positive(-x) : atan1_positive(x) 00431 */ 00432 } 00433 00434 static inline double G_GNUC_CONST 00435 bse_approx_qcircle1 (register double x) 00436 { 00437 double numerator = 1.20460124790369468987715633298929 * x - 1.20460124790369468987715633298929; 00438 double denominator = x - 1.20460124790369468987715633298929; 00439 /* R1(x)=(1.2046012479036946898771563 * x - 1.2046012479036946898771563) / (x - 1.2046012479036946898771563) */ 00440 return numerator / denominator; 00441 } 00442 00443 static inline double G_GNUC_CONST 00444 bse_approx_qcircle2 (register double x) 00445 { 00446 double numerator = 1.20460124790369468987715633298929*x; 00447 double denominator = x + 0.20460124790369468987715633298929; 00448 /* R2(x)=1.2046012479036946898771563*x/(x + 0.2046012479036946898771563) */ 00449 return numerator / denominator; 00450 } 00451 00452 static inline double G_GNUC_CONST 00453 bse_approx_qcircle3 (register double x) 00454 { 00455 double numerator = 0.20460124790369468987715633298929 - 0.20460124790369468987715633298929 * x; 00456 double denominator = x + 0.20460124790369468987715633298929; 00457 /* R3(x)=(0.2046012479036946898771563 - 0.2046012479036946898771563 * x) / (x + 0.2046012479036946898771563) */ 00458 return numerator / denominator; 00459 } 00460 00461 static inline double G_GNUC_CONST 00462 bse_approx_qcircle4 (register double x) 00463 { 00464 double numerator = -0.20460124790369468987715633298929 * x; 00465 double denominator = x - 1.20460124790369468987715633298929; 00466 /* R4(x)=-0.2046012479036946898771563 * x / (x - 1.2046012479036946898771563) */ 00467 return numerator / denominator; 00468 } 00469 00470 static inline double G_GNUC_CONST 00471 bse_approx2_exp2 (float ex) 00472 { 00473 register BseFloatIEEE754 fp = { 0, }; 00474 register int i = bse_ftoi (ex); 00475 fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i; 00476 register double x = ex - i; 00477 return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 + 00478 x * (0.24022650695910071233355126316333))); 00479 } 00480 00481 static inline double G_GNUC_CONST 00482 bse_approx3_exp2 (float ex) 00483 { 00484 register BseFloatIEEE754 fp = { 0, }; 00485 register int i = bse_ftoi (ex); 00486 fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i; 00487 register double x = ex - i; 00488 return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 + 00489 x * (0.24022650695910071233355126316333 + 00490 x * (0.055504108664821579953142263768622)))); 00491 /* exp2frac(x)=x-ftoi(x) 00492 * exp2a3(x)=2**ftoi(x)*(1+exp2frac(x)*(0.6931471805599453+exp2frac(x)*(0.2402265069591+exp2frac(x)*0.0555041086648))) 00493 */ 00494 } 00495 00496 static inline double G_GNUC_CONST 00497 bse_approx4_exp2 (float ex) 00498 { 00499 register BseFloatIEEE754 fp = { 0, }; 00500 register int i = bse_ftoi (ex); 00501 fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i; 00502 register double x = ex - i; 00503 return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 + 00504 x * (0.24022650695910071233355126316333 + 00505 x * (0.055504108664821579953142263768622 + 00506 x * (0.0096181291076284771619790715736589))))); 00507 /* ftoi(x)=int(x<-0.0 ? x - 0.5 : x + 0.5) 00508 * exp2frac(x)=x-ftoi(x) 00509 * exp2a4(x)=2**ftoi(x)*(1+exp2frac(x)*(0.6931471805599453+exp2frac(x)*(0.2402265069591+exp2frac(x)*(0.0555041086648+exp2frac(x)*0.009618129107628477)))) 00510 */ 00511 } 00512 00513 static inline double G_GNUC_CONST 00514 bse_approx5_exp2 (float ex) 00515 { 00516 register BseFloatIEEE754 fp = { 0, }; 00517 register int i = bse_ftoi (ex); 00518 fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i; 00519 register double x = ex - i; 00520 return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 + 00521 x * (0.24022650695910071233355126316333 + 00522 x * (0.055504108664821579953142263768622 + 00523 x * (0.0096181291076284771619790715736589 + 00524 x * (0.0013333558146428443423412221987996)))))); 00525 } 00526 00527 static inline double G_GNUC_CONST 00528 bse_approx6_exp2 (float ex) 00529 { 00530 register BseFloatIEEE754 fp = { 0, }; 00531 register int i = bse_ftoi (ex); 00532 fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i; 00533 register double x = ex - i; 00534 return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 + 00535 x * (0.24022650695910071233355126316333 + 00536 x * (0.055504108664821579953142263768622 + 00537 x * (0.0096181291076284771619790715736589 + 00538 x * (0.0013333558146428443423412221987996 + 00539 x * (0.00015403530393381609954437097332742))))))); 00540 } 00541 00542 static inline double G_GNUC_CONST 00543 bse_approx7_exp2 (float ex) 00544 { 00545 register BseFloatIEEE754 fp = { 0, }; 00546 register int i = bse_ftoi (ex); 00547 fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i; 00548 register double x = ex - i; 00549 return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 + 00550 x * (0.24022650695910071233355126316333 + 00551 x * (0.055504108664821579953142263768622 + 00552 x * (0.0096181291076284771619790715736589 + 00553 x * (0.0013333558146428443423412221987996 + 00554 x * (0.00015403530393381609954437097332742 + 00555 x * (0.00001525273380405984028002543901201)))))))); 00556 } 00557 00558 static inline double G_GNUC_CONST 00559 bse_approx8_exp2 (float ex) 00560 { 00561 register BseFloatIEEE754 fp = { 0, }; 00562 register int i = bse_ftoi (ex); 00563 fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i; 00564 register double x = ex - i; 00565 return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 + 00566 x * (0.24022650695910071233355126316333 + 00567 x * (0.055504108664821579953142263768622 + 00568 x * (0.0096181291076284771619790715736589 + 00569 x * (0.0013333558146428443423412221987996 + 00570 x * (0.00015403530393381609954437097332742 + 00571 x * (0.00001525273380405984028002543901201 + 00572 x * (0.0000013215486790144309488403758228288))))))))); 00573 } 00574 00575 static inline double G_GNUC_CONST 00576 bse_approx9_exp2 (float ex) 00577 { 00578 register BseFloatIEEE754 fp = { 0, }; 00579 register int i = bse_ftoi (ex); 00580 fp.mpn.biased_exponent = BSE_FLOAT_BIAS + i; 00581 register double x = ex - i; 00582 return fp.v_float * (1.0 + x * (0.69314718055994530941723212145818 + 00583 x * (0.24022650695910071233355126316333 + 00584 x * (0.055504108664821579953142263768622 + 00585 x * (0.0096181291076284771619790715736589 + 00586 x * (0.0013333558146428443423412221987996 + 00587 x * (0.00015403530393381609954437097332742 + 00588 x * (0.00001525273380405984028002543901201 + 00589 x * (0.0000013215486790144309488403758228288 + 00590 x * 0.00000010178086009239699727490007597745))))))))); 00591 } 00592 00593 static inline double G_GNUC_CONST 00594 bse_approx2_tanh (float x) 00595 { 00596 if (G_UNLIKELY (x < -20)) 00597 return -1; 00598 if (G_UNLIKELY (x > 20)) 00599 return 1; 00600 register double bpot = bse_approx2_exp2 (x * BSE_2_DIV_LN2); 00601 return (bpot - 1) / (bpot + 1); 00602 } 00603 00604 static inline double G_GNUC_CONST 00605 bse_approx3_tanh (float x) 00606 { 00607 if (G_UNLIKELY (x < -20)) 00608 return -1; 00609 if (G_UNLIKELY (x > 20)) 00610 return 1; 00611 register double bpot = bse_approx3_exp2 (x * BSE_2_DIV_LN2); 00612 return (bpot - 1) / (bpot + 1); 00613 } 00614 00615 static inline double G_GNUC_CONST 00616 bse_approx4_tanh (float x) 00617 { 00618 if (G_UNLIKELY (x < -20)) 00619 return -1; 00620 if (G_UNLIKELY (x > 20)) 00621 return 1; 00622 register double bpot = bse_approx4_exp2 (x * BSE_2_DIV_LN2); 00623 return (bpot - 1) / (bpot + 1); 00624 /* tanha4(x)=x<-20 ? -1 : x>20 ? 1 : (exp2a4(x*2.885390081777926814719849362)-1) / (exp2a4(x*2.885390081777926814719849362)+1) */ 00625 } 00626 00627 static inline double G_GNUC_CONST 00628 bse_approx5_tanh (float x) 00629 { 00630 if (G_UNLIKELY (x < -20)) 00631 return -1; 00632 if (G_UNLIKELY (x > 20)) 00633 return 1; 00634 register double bpot = bse_approx5_exp2 (x * BSE_2_DIV_LN2); 00635 return (bpot - 1) / (bpot + 1); 00636 } 00637 00638 static inline double G_GNUC_CONST 00639 bse_approx6_tanh (float x) 00640 { 00641 if (G_UNLIKELY (x < -20)) 00642 return -1; 00643 if (G_UNLIKELY (x > 20)) 00644 return 1; 00645 register double bpot = bse_approx6_exp2 (x * BSE_2_DIV_LN2); 00646 return (bpot - 1) / (bpot + 1); 00647 } 00648 00649 static inline double G_GNUC_CONST 00650 bse_approx7_tanh (float x) 00651 { 00652 if (G_UNLIKELY (x < -20)) 00653 return -1; 00654 if (G_UNLIKELY (x > 20)) 00655 return 1; 00656 register double bpot = bse_approx7_exp2 (x * BSE_2_DIV_LN2); 00657 return (bpot - 1) / (bpot + 1); 00658 } 00659 00660 static inline double G_GNUC_CONST 00661 bse_approx8_tanh (float x) 00662 { 00663 if (G_UNLIKELY (x < -20)) 00664 return -1; 00665 if (G_UNLIKELY (x > 20)) 00666 return 1; 00667 register double bpot = bse_approx8_exp2 (x * BSE_2_DIV_LN2); 00668 return (bpot - 1) / (bpot + 1); 00669 } 00670 00671 static inline double G_GNUC_CONST 00672 bse_approx9_tanh (float x) 00673 { 00674 if (G_UNLIKELY (x < -20)) 00675 return -1; 00676 if (G_UNLIKELY (x > 20)) 00677 return 1; 00678 register double bpot = bse_approx9_exp2 (x * BSE_2_DIV_LN2); 00679 return (bpot - 1) / (bpot + 1); 00680 } 00681 00682 static inline double G_GNUC_CONST 00683 bse_saturate_hard (double value, 00684 double limit) 00685 { 00686 register double v1 = fabsf (value + limit); 00687 register double v2 = fabsf (value - limit); 00688 return 0.5 * (v1 - v2); /* CLAMP() without branching */ 00689 } 00690 00691 static inline double G_GNUC_CONST 00692 bse_saturate_branching (double value, 00693 double limit) 00694 { 00695 if (G_UNLIKELY (value >= limit)) 00696 return limit; 00697 if (G_UNLIKELY (value <= limit)) 00698 return -limit; 00699 return value; 00700 } 00701 00702 void _bse_init_signal (void); 00703 00704 extern const double * const bse_cent_table; 00705 00706 static inline double G_GNUC_CONST 00707 bse_cent_tune_fast (int fine_tune) 00708 { 00709 return bse_cent_table[CLAMP (fine_tune, -100, 100)]; 00710 } 00711 00712 G_END_DECLS 00713 00714 #endif /* __BSE_SIGNAL_H__ */