3 |
* LinuxSampler - modular, streaming capable sampler * |
* LinuxSampler - modular, streaming capable sampler * |
4 |
* * |
* * |
5 |
* Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * |
* Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * |
6 |
|
* Copyright (C) 2005 Christian Schoenebeck * |
7 |
* * |
* * |
8 |
* This program is free software; you can redistribute it and/or modify * |
* This program is free software; you can redistribute it and/or modify * |
9 |
* it under the terms of the GNU General Public License as published by * |
* it under the terms of the GNU General Public License as published by * |
72 |
bq_t y1; |
bq_t y1; |
73 |
bq_t y2; |
bq_t y2; |
74 |
|
|
75 |
|
#if __GNUC__ >= 4 |
76 |
|
float fbc; |
77 |
|
#else |
78 |
const static float fbc = 0.98; |
const static float fbc = 0.98; |
79 |
|
#endif |
80 |
|
|
81 |
/** |
/** |
82 |
* Prevent \a f from going into denormal mode which would slow down |
* Prevent \a f from going into denormal mode which would slow down |
91 |
public: |
public: |
92 |
BiquadFilter() { |
BiquadFilter() { |
93 |
Reset(); |
Reset(); |
94 |
|
#if __GNUC__ >= 4 |
95 |
|
fbc = 0.98f; |
96 |
|
#endif |
97 |
} |
} |
98 |
|
|
99 |
void Reset() { |
void Reset() { |
131 |
return y; |
return y; |
132 |
} |
} |
133 |
|
|
134 |
#if ARCH_X86 |
#if CONFIG_ASM && ARCH_X86 |
135 |
// expects to find input in xmm0 (xmm0 stays unmodified) and finally leaves output in xmm6 |
// expects to find input in xmm0 (xmm0 stays unmodified) and finally leaves output in xmm6 |
136 |
inline void Apply4StepsSSE(biquad_param_t* param) { |
inline void Apply4StepsSSE(biquad_param_t* param) { |
137 |
__asm__ __volatile__ ( |
__asm__ __volatile__ ( |
218 |
"r" (¶m->b0) /* %2 */ |
"r" (¶m->b0) /* %2 */ |
219 |
); |
); |
220 |
} |
} |
221 |
#endif // ARCH_X86 |
#endif // CONFIG_ASM && ARCH_X86 |
222 |
|
|
223 |
inline bq_t ApplyFB(bq_t x, const bq_t fb) { |
inline bq_t ApplyFB(bq_t x, const bq_t fb) { |
224 |
bq_t y; |
bq_t y; |
250 |
return y; |
return y; |
251 |
} |
} |
252 |
|
|
253 |
#if ARCH_X86 |
#if CONFIG_ASM && ARCH_X86 |
254 |
// expects to find input in xmm0 (xmm0 stays unmodified) and finally leaves output in xmm7 |
// expects to find input in xmm0 (xmm0 stays unmodified) and finally leaves output in xmm7 |
255 |
inline void ApplyFB4StepsSSE(biquad_param_t* param, const bq_t &fb) { |
inline void ApplyFB4StepsSSE(biquad_param_t* param, const bq_t &fb) { |
256 |
float xs, ys; |
float xs, ys; |
446 |
:: |
:: |
447 |
); |
); |
448 |
} |
} |
449 |
#endif // ARCH_X86 |
#endif // CONFIG_ASM && ARCH_X86 |
450 |
}; |
}; |
451 |
|
|
452 |
|
/** @brief Lowpass Filter |
453 |
|
* |
454 |
|
* Lowpass filter based on biquad filter implementation. |
455 |
|
*/ |
456 |
class LowpassFilter : public BiquadFilter { |
class LowpassFilter : public BiquadFilter { |
457 |
public: |
public: |
458 |
inline LowpassFilter() : BiquadFilter() {} |
inline LowpassFilter() : BiquadFilter() {} |
486 |
} |
} |
487 |
}; |
}; |
488 |
|
|
489 |
|
/** @brief Bandpass Filter |
490 |
|
* |
491 |
|
* Bandpass filter based on biquad filter implementation. |
492 |
|
*/ |
493 |
class BandpassFilter : public BiquadFilter { |
class BandpassFilter : public BiquadFilter { |
494 |
public: |
public: |
495 |
inline BandpassFilter() : BiquadFilter() {} |
inline BandpassFilter() : BiquadFilter() {} |
501 |
bq_t alpha = sn * sinh(M_LN2 / 2.0 * bw * omega / sn); |
bq_t alpha = sn * sinh(M_LN2 / 2.0 * bw * omega / sn); |
502 |
|
|
503 |
const float a0r = 1.0 / (1.0 + alpha); |
const float a0r = 1.0 / (1.0 + alpha); |
504 |
this->b0 = a0r * alpha; |
this->b0 = a0r * sn * 0.71; |
505 |
this->b1 = 0.0; |
this->b1 = 0.0; |
506 |
this->b2 = a0r * -alpha; |
this->b2 = a0r * -sn * 0.71; |
507 |
this->a1 = a0r * (2.0 * cs); |
this->a1 = a0r * (2.0 * cs); |
508 |
this->a2 = a0r * (alpha - 1.0); |
this->a2 = a0r * (alpha - 1.0); |
509 |
} |
} |
515 |
bq_t alpha = sn * sinh(M_LN2 / 2.0 * bw * omega / sn); |
bq_t alpha = sn * sinh(M_LN2 / 2.0 * bw * omega / sn); |
516 |
|
|
517 |
const float a0r = 1.0 / (1.0 + alpha); |
const float a0r = 1.0 / (1.0 + alpha); |
518 |
param->b0 = a0r * alpha; |
param->b0 = a0r * sn * 0.71; |
519 |
param->b1 = 0.0; |
param->b1 = 0.0; |
520 |
param->b2 = a0r * -alpha; |
param->b2 = a0r * -sn * 0.71; |
521 |
param->a1 = a0r * (2.0 * cs); |
param->a1 = a0r * (2.0 * cs); |
522 |
param->a2 = a0r * (alpha - 1.0); |
param->a2 = a0r * (alpha - 1.0); |
523 |
} |
} |
524 |
}; |
}; |
525 |
|
|
526 |
|
/** @brief Highpass Filter |
527 |
|
* |
528 |
|
* Highpass filter based on biquad filter implementation. |
529 |
|
*/ |
530 |
class HighpassFilter : public BiquadFilter { |
class HighpassFilter : public BiquadFilter { |
531 |
public: |
public: |
532 |
inline HighpassFilter() : BiquadFilter() {} |
inline HighpassFilter() : BiquadFilter() {} |