--- linuxsampler/trunk/src/engines/gig/Filter.h 2004/04/26 17:15:51 53 +++ linuxsampler/trunk/src/engines/gig/Filter.h 2005/07/05 19:30:37 685 @@ -2,7 +2,8 @@ * * * LinuxSampler - modular, streaming capable sampler * * * - * Copyright (C) 2003 by Benno Senoner and Christian Schoenebeck * + * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * + * Copyright (C) 2005 Christian Schoenebeck * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -25,23 +26,19 @@ #include "../../common/global.h" -#if DEBUG_HEADERS -# warning Filter.h included -#endif // DEBUG_HEADERS +#include #include "../common/BiquadFilter.h" // TODO: Gigasampler's "Turbo Lowpass" and "Bandreject" filters not implemented yet -#include "../../lib/fileloader/libgig/gig.h" - #define LSF_BW 0.9 #define LSF_FB 0.9f namespace LinuxSampler { namespace gig { /** - * This is a filter similar to the ones from Gigasampler. + * These are filters similar to the ones from Gigasampler. */ class Filter { protected: @@ -54,13 +51,21 @@ bq_t resonance; bq_t cutoff; ::gig::vcf_type_t Type; +#if __GNUC__ >= 4 + float fFB; +#else + static const float fFB = LSF_FB; +#endif + public: - bool Enabled; - inline Filter() { + Filter() { // set filter type to 'lowpass' by default pFilter = &LPFilter; Type = ::gig::vcf_type_lowpass; +#if __GNUC__ >= 4 + fFB = LSF_FB; +#endif } inline bq_t Cutoff() { return cutoff; } @@ -73,13 +78,13 @@ pFilter = &HPFilter; break; case ::gig::vcf_type_bandreject: //TODO: not implemented yet - Type = ::gig::vcf_type_bandpass; + FilterType = ::gig::vcf_type_bandpass; case ::gig::vcf_type_bandpass: pFilter = &BPFilter; break; case ::gig::vcf_type_lowpassturbo: //TODO: not implemented yet default: - Type = ::gig::vcf_type_lowpass; + FilterType = ::gig::vcf_type_lowpass; case ::gig::vcf_type_lowpass: pFilter = &LPFilter; @@ -105,11 +110,71 @@ this->cutoff = cutoff; } + inline void SetParameters(biquad_param_t* base, biquad_param_t* main, bq_t cutoff, bq_t resonance, bq_t fs) { + BasicBPFilter.SetParameters(base, cutoff, 0.7, fs); + switch (Type) { + case ::gig::vcf_type_highpass: + HPFilter.SetParameters(main, cutoff, 1.0 - resonance * LSF_BW, fs); + break; + case ::gig::vcf_type_bandpass: + BPFilter.SetParameters(main, cutoff, 1.0 - resonance * LSF_BW, fs); + break; + case ::gig::vcf_type_lowpass: + LPFilter.SetParameters(main, cutoff, 1.0 - resonance * LSF_BW, fs); + break; + } + this->scale = 1.0f - resonance * 0.7f; + this->resonance = resonance; + this->cutoff = cutoff; + } + + void Reset() { + BasicBPFilter.Reset(); + HPFilter.Reset(); + BPFilter.Reset(); + LPFilter.Reset(); + } + inline bq_t Apply(const bq_t in) { - return (Enabled) ? pFilter->Apply(in) * this->scale + - BasicBPFilter.ApplyFB(in, this->resonance * LSF_FB) * this->resonance - : in; + return pFilter->Apply(in) * this->scale + + BasicBPFilter.ApplyFB(in, this->resonance * LSF_FB) * this->resonance; } + + inline bq_t Apply(biquad_param_t* base, biquad_param_t* main, const bq_t in) { + return pFilter->Apply(main, in) * this->scale + + BasicBPFilter.ApplyFB(base, in, this->resonance * LSF_FB) * this->resonance; + } + +#if CONFIG_ASM && ARCH_X86 + // expects to find input in xmm0 and leaves output in xmm7 + inline void Apply4StepsSSE(biquad_param_t* base, biquad_param_t* main) { + float fb; + __asm__ __volatile__ ( + "movss %0, %%xmm4\n\t" + "mulss %1, %%xmm4 # this->resonance * LSF_FB\n\t" + "movss %%xmm4, %2\n\t" + :: "m" (fFB), /* %0 */ + "m" (resonance), /* %1 */ + "m" (fb) /* %2 */ + ); + BasicBPFilter.ApplyFB4StepsSSE(base, fb); // leaves output in xmm7 + __asm__ __volatile__ ( + "movss %0, %%xmm4\n\t" + "shufps $0, %%xmm4, %%xmm4 # copy to other 3 cells\n\t" + "mulps %%xmm4, %%xmm7 # ApplyFB() * this->resonance\n\t" + :: "m" (resonance) /* %0 */ + ); + pFilter->Apply4StepsSSE(main); // leaves output in xmm6 + __asm__ __volatile__ ( + "movss %0, %%xmm5\n\t" + "shufps $0, %%xmm5, %%xmm5 # copy to other 3 cells\n\t" + "mulps %%xmm5, %%xmm6 # Apply() * this->scale\n\t" + "addps %%xmm6, %%xmm7 # xmm7 = result\n\t" + :: "m" (scale) /* %0 */ + ); + } +#endif // CONFIG_ASM && ARCH_X86 + }; }} //namespace LinuxSampler::gig