annotate trunk/src/Modules/BMM/ModuleGammatone.cc @ 276:a57b29e373c7

- Added stub for a Slaney IIR Gammatone filterbank
author tomwalters
date Tue, 16 Feb 2010 18:40:55 +0000
parents
children 6b4921704eb1
rev   line source
tomwalters@276 1 // Copyright 2009-2010, Thomas Walters
tomwalters@276 2 //
tomwalters@276 3 // AIM-C: A C++ implementation of the Auditory Image Model
tomwalters@276 4 // http://www.acousticscale.org/AIMC
tomwalters@276 5 //
tomwalters@276 6 // This program is free software: you can redistribute it and/or modify
tomwalters@276 7 // it under the terms of the GNU General Public License as published by
tomwalters@276 8 // the Free Software Foundation, either version 3 of the License, or
tomwalters@276 9 // (at your option) any later version.
tomwalters@276 10 //
tomwalters@276 11 // This program is distributed in the hope that it will be useful,
tomwalters@276 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
tomwalters@276 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
tomwalters@276 14 // GNU General Public License for more details.
tomwalters@276 15 //
tomwalters@276 16 // You should have received a copy of the GNU General Public License
tomwalters@276 17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
tomwalters@276 18
tomwalters@276 19 /*! \file
tomwalters@276 20 * \brief Slaney's gammatone filterbank
tomwalters@276 21 *
tomwalters@276 22 * \author Thomas Walters <tom@acousticscale.org>
tomwalters@276 23 * \date created 2009/11/13
tomwalters@276 24 * \version \$Id$
tomwalters@276 25 */
tomwalters@276 26
tomwalters@276 27 #include <complex>
tomwalters@276 28
tomwalters@276 29 #include "Modules/BMM/ModuleGammatone.h"
tomwalters@276 30
tomwalters@276 31 namespace aimc {
tomwalters@276 32 using std::complex;
tomwalters@276 33 ModuleGammatone::ModuleGammatone(Parameters *params) : Module(params) {
tomwalters@276 34 module_identifier_ = "gtfb";
tomwalters@276 35 module_type_ = "bmm";
tomwalters@276 36 module_description_ = "Gammatone filterbank (Slaney's IIR gammatone)";
tomwalters@276 37 module_version_ = "$Id$";
tomwalters@276 38
tomwalters@276 39 num_channels_ = parameters_->DefaultInt("gtfb.channel_count", 200);
tomwalters@276 40 min_frequency_ = parameters_->DefaultFloat("gtfb.min_frequency", 86.0f);
tomwalters@276 41 max_frequency_ = parameters_->DefaultFloat("gtfb.max_frequency", 16000.0f);
tomwalters@276 42 }
tomwalters@276 43
tomwalters@276 44 bool ModuleGammatone::InitializeInternal(const SignalBank& input) {
tomwalters@276 45 // Calculate number of channels, and centre frequencies
tomwalters@276 46
tomwalters@276 47 forward_.resize(num_channels_);
tomwalters@276 48 feedback_.resize(num_channels_);
tomwalters@276 49
tomwalters@276 50 for (int ch = 0; ch < num_channels_; ++ch) {
tomwalters@276 51 float erb = Freq2ERBw(cf)
tomwalters@276 52
tomwalters@276 53 // Sample interval
tomwalters@276 54 float dt = 1.0f / fs;
tomwalters@276 55
tomwalters@276 56 // Bandwidth parameter
tomwalters@276 57 float b = 1.019f * 2.0f * M_PI * erb;
tomwalters@276 58
tomwalters@276 59 // All of the following expressions are derived in Apple TR #35, "An
tomwalters@276 60 // Efficient Implementation of the Patterson-Holdsworth Cochlear
tomwalters@276 61 // Filter Bank".
tomwalters@276 62
tomwalters@276 63 // Calculate the gain:
tomwalters@276 64 complex<float> exponent(0.0f, 2.0f * cf * M_PI * T);
tomwalters@276 65 complex<float> ec = exp(2.0f * complex_exponent);
tomwalters@276 66 complex<float> two_cf_pi_t(2.0f * cf * M_PI * T, 0.0f);
tomwalters@276 67 complex<float> two_pow(pow(2.0f, (3.0f/2.0f)), 0.0f);
tomwalters@276 68
tomwalters@276 69 complex<float> p = -2.0f * ec * T + 2.0f * exp(-(B * T) + exponent) * dt;
tomwalters@276 70
tomwalters@276 71 float gain = abs(
tomwalters@276 72 (part1 * (cos(two_cf_pi_t) - sqrt(3.0f - twopow) * sin(two_cf_pi_t)))
tomwalters@276 73 * (part1 * (cos(two_cf_pi_t) + sqrt(3.0f - twopow) * sin(two_cf_pi_t)))
tomwalters@276 74 * (part1 * (cos(two_cf_pi_t) - sqrt(3.0f + twopow) * sin(two_cf_pi_t)))
tomwalters@276 75 * (part1 * (cos(two_cf_pi_t) + sqrt(3.0f + twopow) * sin(two_cf_pi_t)))
tomwalters@276 76 / pow(-2.0f / exp(2.0f * b * dt) - 2.0f * ec + 2.0f * (1.0f + ec)
tomwalters@276 77 / exp(b * dt), 4.0f));
tomwalters@276 78
tomwalters@276 79 // The filter coefficients themselves:
tomwalters@276 80 forward[ch].resize(5, 0.0f);
tomwalters@276 81 feedback[ch].resize(9, 0.0f);
tomwalters@276 82
tomwalters@276 83 forward[ch][0] = pow(T, 4.0f) / gain;
tomwalters@276 84 forward[ch][1] = (-4.0f * pow(T, 4.0f) * cos(2.0f * cf * M_PI * dt)
tomwalters@276 85 / exp(b * dt) / gain);
tomwalters@276 86 forward[ch][2] = (6.0f * pow(T, 4.0f) * cos(4.0f * cf * M_PI * dt)
tomwalters@276 87 / exp(2.0f * b * dt) / gain);
tomwalters@276 88 forward[ch][3] = (-4.0f * pow(T, 4.0f) * cos(6.0f * cf * M_PI * dt)
tomwalters@276 89 / exp(3.0f * b * dt) / gain);
tomwalters@276 90 forward[ch][4] = (pow(T,4.0f) * cos(8.0f * cf * M_PI * dt)
tomwalters@276 91 / exp(4.0f * b * dt) / gain);
tomwalters@276 92
tomwalters@276 93 feedback[ch][0] = 1.0f;
tomwalters@276 94 feedback[ch][1] = -8.0f * cos(2.0f * cf * M_PI * T) / exp(b * dt);
tomwalters@276 95 feedback[ch][2] = (4.0f * (4.0f + 3.0f * cos(4.0f * cf * M_PI * dt))
tomwalters@276 96 / exp(2.0f * b * dt));
tomwalters@276 97 feedback[ch][3] = (-8.0f * (6.0f * cos(2.0f * cf * M_PI * dt)
tomwalters@276 98 + cos(6.0f * cf * M_PI * dt))
tomwalters@276 99 / exp(3.0f * b * dt));
tomwalters@276 100 feedback[ch][4] = (2.0f * (18.0f + 16.0f * cos(4.0f * cf * M_PI * dt)
tomwalters@276 101 + cos(8.0f * cf * M_PI * dt))
tomwalters@276 102 / exp(4.0f * b * dt));
tomwalters@276 103 feedback[ch][5] = (-8.0f * (6.0f * cos(2.0f * cf * M_PI * T)
tomwalters@276 104 + cos(6.0f * cf * M_PI * T))
tomwalters@276 105 / exp(5.0f * B * T));
tomwalters@276 106 feedback[ch][6] = (4.0f * (4.0f + 3.0f * cos(4.0f * cf * M_PI * T))
tomwalters@276 107 / exp(6.0f * B * T));
tomwalters@276 108 feedback[ch][7] = -8.0f * cos(2.0f * cf * M_PI * dt) / exp(7.0f * b * dt);
tomwalters@276 109 feedback[ch][8] = exp(-8.0f * b * dt);
tomwalters@276 110 }
tomwalters@276 111 }
tomwalters@276 112 } // namespace aimc