# HG changeset patch # User ronw@google.com # Date 1370973548 0 # Node ID 3f01a136c5373c821f3e7854680c7b3e96471ed7 # Parent 16dfff1de47a26c0e57def09a00533421909e53c DISALLOW_COPY_AND_ASSIGN in CARFAC classes and fix a few funny indentations. diff -r 16dfff1de47a -r 3f01a136c537 carfac/carfac.cc --- a/carfac/carfac.cc Tue Jun 11 15:04:55 2013 +0000 +++ b/carfac/carfac.cc Tue Jun 11 17:59:08 2013 +0000 @@ -27,18 +27,19 @@ using std::vector; CARFAC::CARFAC(const int num_ears, const FPType sample_rate, - const CARParams& car_params, const IHCParams& ihc_params, - const AGCParams& agc_params) { + const CARParams& car_params, const IHCParams& ihc_params, + const AGCParams& agc_params) { + Reset(num_ears, sample_rate, car_params, ihc_params, agc_params); +} + +void CARFAC::Reset(const int num_ears, const FPType sample_rate, + const CARParams& car_params, const IHCParams& ihc_params, + const AGCParams& agc_params) { num_ears_ = num_ears; sample_rate_ = sample_rate; - ears_.resize(num_ears_); car_params_ = car_params; ihc_params_ = ihc_params; agc_params_ = agc_params; - Reset(); -} - -void CARFAC::Reset() { num_channels_ = 0; FPType pole_hz = car_params_.first_pole_theta * sample_rate_ / (2 * kPi); while (pole_hz > car_params_.min_pole_hz) { @@ -62,8 +63,10 @@ // This code initializes the coefficients for each of the AGC stages. DesignAGCCoeffs(agc_params_, sample_rate_, &agc_coeffs); // Once we have the coefficient structure we can design the ears. - for (auto& ear : ears_) { - ear.Init(num_channels_, car_coeffs, ihc_coeffs, agc_coeffs); + ears_.clear(); + ears_.reserve(num_ears_); + for (int i = 0; i < num_ears_; ++i) { + ears_.push_back(new Ear(num_channels_, car_coeffs, ihc_coeffs, agc_coeffs)); } } @@ -76,15 +79,15 @@ for (int32_t timepoint = 0; timepoint < length; ++timepoint) { for (int audio_channel = 0; audio_channel < num_ears_; ++audio_channel) { // First we create a reference to the current Ear object. - Ear& ear = ears_[audio_channel]; + Ear* ear = ears_[audio_channel]; // This stores the audio sample currently being processed. FPType input = sound_data[audio_channel][start + timepoint]; // Now we apply the three stages of the model in sequence to the current // audio sample. - ear.CARStep(input); - ear.IHCStep(ear.car_out()); - updated = ear.AGCStep(ear.ihc_out()); + ear->CARStep(input); + ear->IHCStep(ear->car_out()); + updated = ear->AGCStep(ear->ihc_out()); } seg_output->AppendOutput(ears_); if (updated) { @@ -99,23 +102,23 @@ } void CARFAC::CrossCouple() { - for (int stage = 0; stage < ears_[0].agc_num_stages(); ++stage) { - if (ears_[0].agc_decim_phase(stage) > 0) { + for (int stage = 0; stage < ears_[0]->agc_num_stages(); ++stage) { + if (ears_[0]->agc_decim_phase(stage) > 0) { break; } else { - FPType mix_coeff = ears_[0].agc_mix_coeff(stage); + FPType mix_coeff = ears_[0]->agc_mix_coeff(stage); if (mix_coeff > 0) { ArrayX stage_state; ArrayX this_stage_values = ArrayX::Zero(num_channels_); - for (auto& ear : ears_) { - stage_state = ear.agc_memory(stage); + for (const auto& ear : ears_) { + stage_state = ear->agc_memory(stage); this_stage_values += stage_state; } this_stage_values /= num_ears_; - for (auto& ear : ears_) { - stage_state = ear.agc_memory(stage); - ear.set_agc_memory(stage, stage_state + mix_coeff * - (this_stage_values - stage_state)); + for (const auto& ear : ears_) { + stage_state = ear->agc_memory(stage); + ear->set_agc_memory(stage, stage_state + mix_coeff * + (this_stage_values - stage_state)); } } } @@ -123,13 +126,13 @@ } void CARFAC::CloseAGCLoop() { - for (auto& ear: ears_) { - ArrayX undamping = 1 - ear.agc_memory(0); + for (auto& ear : ears_) { + ArrayX undamping = 1 - ear->agc_memory(0); // This updates the target stage gain for the new damping. - ear.set_dzb_memory((ear.zr_coeffs() * undamping - ear.zb_memory()) / - ear.agc_decimation(0)); - ear.set_dg_memory((ear.StageGValue(undamping) - ear.g_memory()) / - ear.agc_decimation(0)); + ear->set_dzb_memory((ear->zr_coeffs() * undamping - ear->zb_memory()) / + ear->agc_decimation(0)); + ear->set_dg_memory((ear->StageGValue(undamping) - ear->g_memory()) / + ear->agc_decimation(0)); } } diff -r 16dfff1de47a -r 3f01a136c537 carfac/carfac.h --- a/carfac/carfac.h Tue Jun 11 15:04:55 2013 +0000 +++ b/carfac/carfac.h Tue Jun 11 17:59:08 2013 +0000 @@ -48,19 +48,20 @@ // rate. This initializes a vector of 'Ear' objects -- one for mono, two for // stereo, or more. CARFAC(const int num_ears, const FPType sample_rate, - const CARParams& car_params, const IHCParams& ihc_params, - const AGCParams& agc_params); - + const CARParams& car_params, const IHCParams& ihc_params, + const AGCParams& agc_params); + + void Reset(const int num_ears, const FPType sample_rate, + const CARParams& car_params, const IHCParams& ihc_params, + const AGCParams& agc_params); + // The 'RunSegment' method processes individual sound segments and stores the // output of the model in a CARFACOutput object. void RunSegment(const std::vector>& sound_data, const int32_t start, const int32_t length, const bool open_loop, CARFACOutput* seg_output); - void Reset(); private: - // TODO (alexbrandmeyer): figure out why this breaks object initialization. - //DISALLOW_COPY_AND_ASSIGN(CARFAC); void DesignCARCoeffs(const CARParams& car_params, const FPType sample_rate, const ArrayX& pole_freqs, CARCoeffs* car_coeffs); void DesignIHCCoeffs(const IHCParams& ihc_params, const FPType sample_rate, @@ -69,7 +70,7 @@ std::vector* agc_coeffs); void CrossCouple(); void CloseAGCLoop(); - + // Function: ERBHz // Auditory filter nominal Equivalent Rectangular Bandwidth // Ref: Glasberg and Moore: Hearing Research, 47 (1990), 103-138 @@ -85,10 +86,12 @@ FPType sample_rate_; int num_channels_; FPType max_channels_per_octave_; - + // We store a vector of Ear objects for mono/stereo/multichannel processing: - std::vector ears_; + std::vector ears_; ArrayX pole_freqs_; + + DISALLOW_COPY_AND_ASSIGN(CARFAC); }; -#endif // CARFAC_CARFAC_H \ No newline at end of file +#endif // CARFAC_CARFAC_H diff -r 16dfff1de47a -r 3f01a136c537 carfac/carfac_output.cc --- a/carfac/carfac_output.cc Tue Jun 11 15:04:55 2013 +0000 +++ b/carfac/carfac_output.cc Tue Jun 11 17:59:08 2013 +0000 @@ -25,8 +25,8 @@ using std::vector; CARFACOutput::CARFACOutput(const bool store_nap, const bool store_nap_decim, - const bool store_bm, const bool store_ohc, - const bool store_agc) { + const bool store_bm, const bool store_ohc, + const bool store_agc) { store_nap_ = store_nap; store_nap_decim_ = store_nap_decim; store_bm_ = store_bm; @@ -35,29 +35,29 @@ } -void CARFACOutput::AppendOutput(const vector& ears) { +void CARFACOutput::AppendOutput(const vector& ears) { if (store_nap_) { nap_.push_back(vector()); - for (auto ear : ears) { - nap_.back().push_back(ear.ihc_out()); + for (const auto& ear : ears) { + nap_.back().push_back(ear->ihc_out()); } } if (store_ohc_) { ohc_.push_back(vector()); - for (auto ear : ears) { - ohc_.back().push_back(ear.za_memory()); + for (const auto& ear : ears) { + ohc_.back().push_back(ear->za_memory()); } } if (store_agc_) { agc_.push_back(vector()); - for (auto ear : ears) { - agc_.back().push_back(ear.zb_memory()); + for (const auto& ear : ears) { + agc_.back().push_back(ear->zb_memory()); } } if (store_bm_) { bm_.push_back(vector()); - for (auto ear : ears) { - bm_.back().push_back(ear.zy_memory()); + for (const auto& ear : ears) { + bm_.back().push_back(ear->zy_memory()); } } -} \ No newline at end of file +} diff -r 16dfff1de47a -r 3f01a136c537 carfac/carfac_output.h --- a/carfac/carfac_output.h Tue Jun 11 15:04:55 2013 +0000 +++ b/carfac/carfac_output.h Tue Jun 11 17:59:08 2013 +0000 @@ -37,28 +37,28 @@ // The constructor takes five boolean values as arguments which indicate // the portions of the CARFAC model's output to be stored. CARFACOutput(const bool store_nap, const bool store_nap_decim, - const bool store_bm, const bool store_ohc, const bool store_agc); - + const bool store_bm, const bool store_ohc, const bool store_agc); + // The AppendOutput method is called on a sample by sample basis by the // CARFAC::RunSegemtn method, appending a single frame of n_ears x n_channels // data to the end of the individual data members selected for storage. - void AppendOutput(const std::vector& ears); + void AppendOutput(const std::vector& ears); + const std::deque>& nap() const { return nap_; } const std::deque>& bm() const { return bm_; } const std::deque>& nap_decim() const { - return nap_decim_; } + return nap_decim_; + } const std::deque>& ohc() const { return ohc_; } const std::deque>& agc() const { return agc_; } private: - // TODO (alexbrandmeyer): figure out why this breaks object initialization. - //DISALLOW_COPY_AND_ASSIGN(CARFACOutput); bool store_nap_; bool store_nap_decim_; bool store_bm_; bool store_ohc_; bool store_agc_; - + // CARFAC outputs are stored in nested containers with dimensions: // n_frames x n_ears x n_channels. std::deque> nap_; @@ -66,6 +66,8 @@ std::deque> bm_; std::deque> ohc_; std::deque> agc_; + + DISALLOW_COPY_AND_ASSIGN(CARFACOutput); }; -#endif // CARFAC_CARFAC_OUTPUT_H \ No newline at end of file +#endif // CARFAC_CARFAC_OUTPUT_H diff -r 16dfff1de47a -r 3f01a136c537 carfac/common.h --- a/carfac/common.h Tue Jun 11 15:04:55 2013 +0000 +++ b/carfac/common.h Tue Jun 11 17:59:08 2013 +0000 @@ -45,4 +45,4 @@ // A fixed value of PI is defined throughout the project. static const FPType kPi = 3.141592653589793238; -#endif // CARFAC_COMMON_H \ No newline at end of file +#endif // CARFAC_COMMON_H diff -r 16dfff1de47a -r 3f01a136c537 carfac/ear.cc --- a/carfac/ear.cc Tue Jun 11 15:04:55 2013 +0000 +++ b/carfac/ear.cc Tue Jun 11 17:59:08 2013 +0000 @@ -23,19 +23,25 @@ #include #include "ear.h" -void Ear::Init(const int num_channels, const CARCoeffs& car_coeffs, - const IHCCoeffs& ihc_coeffs, - const std::vector& agc_coeffs) { +Ear::Ear(const int num_channels, const CARCoeffs& car_coeffs, + const IHCCoeffs& ihc_coeffs, + const std::vector& agc_coeffs) { + Reset(num_channels, car_coeffs, ihc_coeffs, agc_coeffs); +} + +void Ear::Reset(const int num_channels, const CARCoeffs& car_coeffs, + const IHCCoeffs& ihc_coeffs, + const std::vector& agc_coeffs) { num_channels_ = num_channels; car_coeffs_ = car_coeffs; ihc_coeffs_ = ihc_coeffs; agc_coeffs_ = agc_coeffs; - InitCARState(); - InitIHCState(); - InitAGCState(); + ResetCARState(); + ResetIHCState(); + ResetAGCState(); } -void Ear::InitCARState() { +void Ear::ResetCARState() { car_state_.z1_memory.setZero(num_channels_); car_state_.z2_memory.setZero(num_channels_); car_state_.za_memory.setZero(num_channels_); @@ -46,7 +52,7 @@ car_state_.dg_memory.setZero(num_channels_); } -void Ear::InitIHCState() { +void Ear::ResetIHCState() { ihc_state_.ihc_accum = ArrayX::Zero(num_channels_); if (! ihc_coeffs_.just_half_wave_rectify) { ihc_state_.ac_coupler.setZero(num_channels_); @@ -61,7 +67,7 @@ } } -void Ear::InitAGCState() { +void Ear::ResetAGCState() { int n_agc_stages = agc_coeffs_.size(); agc_state_.resize(n_agc_stages); for (auto& stage_state : agc_state_) { @@ -283,4 +289,4 @@ return (1 - 2 * r * car_coeffs_.a0_coeffs + (r * r)) / (1 - 2 * r * car_coeffs_.a0_coeffs + car_coeffs_.h_coeffs * r * car_coeffs_.c0_coeffs + (r * r)); -} \ No newline at end of file +} diff -r 16dfff1de47a -r 3f01a136c537 carfac/ear.h --- a/carfac/ear.h Tue Jun 11 15:04:55 2013 +0000 +++ b/carfac/ear.h Tue Jun 11 17:59:08 2013 +0000 @@ -33,27 +33,33 @@ // The Ear object carries out the three steps of the CARFAC model on a single // channel of audio data, and stores information about the CAR, IHC and AGC -// coefficients and states. +// coefficients and states. class Ear { public: - - // This is the primary initialization function that is called for each - // Ear object by the CARFAC::Design method. - void Init(const int num_channels, const CARCoeffs& car_coeffs, - const IHCCoeffs& ihc_coeffs, - const std::vector& agc_coeffs); - + Ear(const int num_channels, const CARCoeffs& car_coeffs, + const IHCCoeffs& ihc_coeffs, + const std::vector& agc_coeffs); + + void Reset(const int num_channels, const CARCoeffs& car_coeffs, + const IHCCoeffs& ihc_coeffs, + const std::vector& agc_coeffs); + // These three methods apply the different steps of the model in sequence // to individual audio samples during the call to CARFAC::RunSegment. void CARStep(const FPType input); + // TODO(ronw): Consider changing the interface for the following two + // methods to access the internal state members directly instead of + // requiring callers to confusingly have to call an accessor method + // just to pass internal data back into the same object as in: + // ear.IHCStep(ear.car_out()); void IHCStep(const ArrayX& car_out); bool AGCStep(const ArrayX& ihc_out); - + // These accessor functions return portions of the CAR state for storage in // the CAROutput structures. const ArrayX& za_memory() const { return car_state_.za_memory; } const ArrayX& zb_memory() const { return car_state_.zb_memory; } - + // The zy_memory_ of the CARState is equivalent to the CAR output. A second // accessor function is included for documentation purposes. const ArrayX& zy_memory() const { return car_state_.zy_memory; } @@ -62,7 +68,7 @@ const ArrayX& ihc_out() const { return ihc_state_.ihc_out; } const ArrayX& dzb_memory() const { return car_state_.dzb_memory; } const ArrayX& zr_coeffs() const { return car_coeffs_.zr_coeffs; } - + // These accessor functions return portions of the AGC state during the cross // coupling of the ears. const int agc_num_stages() const { return agc_coeffs_.size(); } @@ -74,14 +80,14 @@ return agc_state_[stage].agc_memory; } const int agc_decimation(const int stage) const { return agc_coeffs_[stage].decimation; } - + // This returns the stage G value during the closing of the AGC loop. ArrayX StageGValue(const ArrayX& undamping); - + // This function sets the AGC memory during the cross coupling stage. void set_agc_memory(const int stage, const ArrayX& new_values) { agc_state_[stage].agc_memory = new_values; } - + // These are the setter functions for the CAR memory states. void set_dzb_memory(const ArrayX& new_values) { car_state_.dzb_memory = new_values; } @@ -89,14 +95,11 @@ car_state_.dg_memory = new_values; } private: - // TODO (alexbrandmeyer): figure out why this breaks object initialization. - //DISALLOW_COPY_AND_ASSIGN(Ear); - // These methodsinitialize the model state variables prior to runtime. - void InitIHCState(); - void InitAGCState(); - void InitCARState(); - + void ResetIHCState(); + void ResetAGCState(); + void ResetCARState(); + // These are the helper sub-functions called during the model runtime. void OHCNonlinearFunction(const ArrayX& velocities, ArrayX* nonlinear_fun); @@ -109,12 +112,14 @@ CARState car_state_; IHCCoeffs ihc_coeffs_; IHCState ihc_state_; - + // The AGC coefficient and state variables are both stored in vectors - // containing one element for each stage (default = 4). + // containing one element for each stage (default = 4). std::vector agc_coeffs_; std::vector agc_state_; int num_channels_; + + DISALLOW_COPY_AND_ASSIGN(Ear); }; -#endif // CARFAC_EAR_H \ No newline at end of file +#endif // CARFAC_EAR_H