bool DynamicLoudnessGM2002::initializeInternal(const SignalBank &input) { /* * Outer-Middle ear filter */ //if filter coefficients have not been provided //use spectral weighting to approximate outer and middle ear response bool weightSpectrum = false; if (pathToFilterCoefs_.empty()) { weightSpectrum = true; //should we use for useHpf for low freqs? default is true if (middleEarFilter_ == OME::ANSIS342007_MIDDLE_EAR_HPF) { modules_.push_back(unique_ptr<Module> (new Butter(3, 0, 50.0))); } } else { //otherwise, load them //load numpy array holding the filter coefficients cnpy::NpyArray arr = cnpy::npy_load(pathToFilterCoefs_); Real *data = reinterpret_cast<Real*> (arr.data); //check if filter is IIR or FIR bool iir = false; if(arr.shape[0]==2) iir = true; //load the coefficients RealVec bCoefs, aCoefs; for(unsigned int i=0; i<arr.shape[1];i++) { bCoefs.push_back(data[i]); if(iir) aCoefs.push_back(data[i+arr.shape[1]]); } //create module if(iir) modules_.push_back(unique_ptr<Module> (new IIR(bCoefs, aCoefs))); else modules_.push_back(unique_ptr<Module> (new FIR(bCoefs))); //clean up delete [] data; } /* * Multi-resolution spectrogram * 10 Hz to include energy caused by sidebands for frequencies near * 20Hz but exclude DC. * 15001 Hz so top frequencies included. */ RealVec bandFreqsHz {10, 80, 500, 1250, 2540, 4050, 15001}; //window spec RealVec windowSizeSecs {0.064, 0.032, 0.016, 0.008, 0.004, 0.002}; vector<int> windowSizeSamples(6, 0); //round to nearest sample and force to be even such that centre samples //are aligned (using periodic Hann window) for (int w = 0; w < 6; w++) { if (isSpectralResolutionDoubled_) windowSizeSecs[w] *= 2; windowSizeSamples[w] = (int)round(windowSizeSecs[w] * input.getFs()); windowSizeSamples[w] += windowSizeSamples[w] % 2; } // hop size to the nearest sample int hopSize = round(input.getFs() / rate_); //power spectrum if (isHoppingGoertzelDFTUsed_) { compressionCriterionInCams_ = 0; modules_.push_back(unique_ptr<Module> (new HoppingGoertzelDFT(bandFreqsHz, windowSizeSamples, hopSize, true, true))); //outputModules_["PowerSpectrum"] = modules_.back().get(); } else { modules_.push_back(unique_ptr<Module> (new FrameGenerator(windowSizeSamples[0], hopSize, isFirstSampleAtWindowCentre_))); //windowing: Periodic hann window modules_.push_back(unique_ptr<Module> (new Window(Window::HANN, windowSizeSamples, true))); modules_.push_back(unique_ptr<Module> (new PowerSpectrum(bandFreqsHz, windowSizeSamples, isSpectrumSampledUniformly_))); } /* * Compression */ if((compressionCriterionInCams_ > 0) && (isSpectrumSampledUniformly_)) { modules_.push_back(unique_ptr<Module> (new CompressSpectrum(compressionCriterionInCams_))); } /* * Spectral weighting if necessary */ if (weightSpectrum) { if ((middleEarFilter_ != OME::NONE) || (outerEarFilter_ != OME::NONE)) { modules_.push_back(unique_ptr<Module> (new WeightSpectrum(middleEarFilter_, outerEarFilter_))); } } int lastSpectrumIdx = modules_.size()-1; /* * Roex filters */ if(isRoexBankFast_) { modules_.push_back(unique_ptr<Module> (new FastRoexBank(filterSpacingInCams_, isExcitationPatternInterpolated_, isInterpolationCubic_))); } else { modules_.push_back(unique_ptr<Module> (new RoexBankANSIS342007(1.8, 38.9, filterSpacingInCams_))); } outputModules_["Excitation"] = modules_.back().get(); /* * Specific loudness */ isBinauralInhibitionUsed_ = isBinauralInhibitionUsed_ * (input.getNEars() == 2); modules_.push_back(unique_ptr<Module> (new SpecificLoudnessANSIS342007(isSpecificLoudnessANSIS342007_, isBinauralInhibitionUsed_))); /* * Binaural inhibition */ if (isBinauralInhibitionUsed_) { modules_.push_back(unique_ptr<Module> (new BinauralInhibitionMG2007)); } outputModules_["SpecificLoudness"] = modules_.back().get(); /* * Instantaneous loudness */ modules_.push_back(unique_ptr<Module> (new InstantaneousLoudness(1.0, isPresentationDiotic_))); outputModules_["InstantaneousLoudness"] = modules_.back().get(); /* * Short-term loudness */ modules_.push_back(unique_ptr<Module> (new ARAverager(attackTimeSTL_, releaseTimeSTL_))); outputModules_["ShortTermLoudness"] = modules_.back().get(); /* * Long-term loudness */ modules_.push_back(unique_ptr<Module> (new ARAverager(attackTimeLTL_, releaseTimeLTL_))); outputModules_["LongTermLoudness"] = modules_.back().get(); //configure targets configureLinearTargetModuleChain(); // Masking conditions if ((input.getNSources() > 1) && (isPartialLoudnessUsed_)) { LOUDNESS_DEBUG(name_ << ": Setting up modules for partial loudness..."); // Excitation transformation based on all sources modules_.push_back(unique_ptr<Module> (new MultiSourceRoexBank(filterSpacingInCams_))); outputModules_["MultiSourceExcitation"] = modules_.back().get(); int moduleIdx = modules_.size() - 1; // Push spectrum to second excitation transformation stage Module* ptrToWeightedSpectrum = modules_[lastSpectrumIdx].get(); ptrToWeightedSpectrum -> addTargetModule (*outputModules_["MultiSourceExcitation"]); // Partial loudness modules_.push_back(unique_ptr<Module> (new SpecificPartialLoudnessMGB1997( isSpecificLoudnessANSIS342007_, isBinauralInhibitionUsed_))); if (isBinauralInhibitionUsed_) modules_.push_back(unique_ptr<Module> (new BinauralInhibitionMG2007)); outputModules_["SpecificPartialLoudness"] = modules_.back().get(); /* * Instantaneous partial loudness */ modules_.push_back(unique_ptr<Module> (new InstantaneousLoudness(1.0, isPresentationDiotic_))); outputModules_["InstantaneousPartialLoudness"] = modules_.back().get(); /* * Short-term partial loudness */ modules_.push_back(unique_ptr<Module> (new ARAverager(attackTimeSTL_, releaseTimeSTL_))); outputModules_["ShortTermPartialLoudness"] = modules_.back().get(); /* * Long-term partial loudness */ modules_.push_back(unique_ptr<Module> (new ARAverager(attackTimeLTL_, releaseTimeLTL_))); outputModules_["LongTermPartialLoudness"] = modules_.back().get(); // configure targets for second (parallel) chain configureLinearTargetModuleChain(moduleIdx); } return 1; }
bool DynamicLoudnessCH2012::initializeInternal(const SignalBank &input) { //if filter coefficients have not been provided //use spectral weighting to approximate outer and middle ear response if(!pathToFilterCoefs_.empty()) { //load numpy array holding the filter coefficients cnpy::NpyArray arr = cnpy::npy_load(pathToFilterCoefs_); Real *data = reinterpret_cast<Real*> (arr.data); //check if filter is IIR or FIR bool iir = false; if(arr.shape[0]==2) iir = true; //load the coefficients RealVec bCoefs, aCoefs; for(unsigned int i=0; i<arr.shape[1];i++) { bCoefs.push_back(data[i]); if(iir) aCoefs.push_back(data[i+arr.shape[1]]); } //create module if(iir) { modules_.push_back(unique_ptr<Module> (new IIR(bCoefs, aCoefs))); } else { modules_.push_back(unique_ptr<Module> (new FIR(bCoefs))); } //clean up delete [] data; } /* * Multi-resolution spectrogram */ RealVec bandFreqsHz {10, 80, 500, 1250, 2540, 4050, 16001}; //window spec RealVec windowSizeSecs {0.128, 0.064, 0.032, 0.016, 0.008, 0.004}; vector<int> windowSizeSamples(6,0); //round to nearest sample and force to be even such that centre samples //are aligned (using periodic Hann window) for(int w=0; w<6; w++) { windowSizeSamples[w] = (int)round(windowSizeSecs[w] * input.getFs()); windowSizeSamples[w] += windowSizeSamples[w] % 2; } // hop size to the nearest sample int hopSize = round(input.getFs() / rate_); //power spectrum if (isHoppingGoertzelDFTUsed_) { compressionCriterionInCams_ = 0; modules_.push_back(unique_ptr<Module> (new HoppingGoertzelDFT(bandFreqsHz, windowSizeSamples, hopSize, true, true))); } else { modules_.push_back(unique_ptr<Module> (new FrameGenerator(windowSizeSamples[0], hopSize, isFirstSampleAtWindowCentre_))); //windowing: Periodic hann window modules_.push_back(unique_ptr<Module> (new Window(Window::HANN, windowSizeSamples, true))); modules_.push_back(unique_ptr<Module> (new PowerSpectrum(bandFreqsHz, windowSizeSamples, isSpectrumSampledUniformly_))); } /* * Compression */ if((compressionCriterionInCams_ > 0) && (isSpectrumSampledUniformly_)) { modules_.push_back(unique_ptr<Module> (new CompressSpectrum(compressionCriterionInCams_))); } /* * Spectral weighting */ if(pathToFilterCoefs_.empty()) { modules_.push_back(unique_ptr<Module> (new WeightSpectrum(OME::CHGM2011_MIDDLE_EAR, outerEarType_))); } /* * Roex filters */ // Set up scaling factors depending on output config Real doubleRoexBankfactor, instantaneousLoudnessFactor; if (isSpecificLoudnessOutput_) { doubleRoexBankfactor = 1.53e-8; instantaneousLoudnessFactor = 1.0; LOUDNESS_DEBUG(name_ << ": Excitation pattern will be scaled for specific loudness"); } else { doubleRoexBankfactor = 1.0; instantaneousLoudnessFactor = 1.53e-8; } isBinauralInhibitionUsed_ = isBinauralInhibitionUsed_ * (input.getNEars() == 2) * isSpecificLoudnessOutput_; if (isBinauralInhibitionUsed_) doubleRoexBankfactor /= 0.75; modules_.push_back(unique_ptr<Module> (new DoubleRoexBank(1.5, 40.2, filterSpacingInCams_, doubleRoexBankfactor, isExcitationPatternInterpolated_, isInterpolationCubic_))); /* * Binaural inhibition */ if (isBinauralInhibitionUsed_) { modules_.push_back(unique_ptr<Module> (new BinauralInhibitionMG2007)); } else { LOUDNESS_DEBUG(name_ << ": No binaural inhibition."); } outputModules_["SpecificLoudness"] = modules_.back().get(); /* * Instantaneous loudness */ modules_.push_back(unique_ptr<Module> (new InstantaneousLoudness(instantaneousLoudnessFactor, isPresentationDiotic_))); outputModules_["InstantaneousLoudness"] = modules_.back().get(); /* * Short-term loudness */ modules_.push_back(unique_ptr<Module> (new ARAverager(attackTimeSTL_, releaseTimeSTL_))); outputModules_["ShortTermLoudness"] = modules_.back().get(); /* * Long-term loudness */ modules_.push_back(unique_ptr<Module> (new ARAverager(attackTimeLTL_, releaseTimeLTL_))); outputModules_["LongTermLoudness"] = modules_.back().get(); //configure targets configureLinearTargetModuleChain(); //Option to provide PeakFollower if (isPeakSTLFollowerUsed_) { modules_.push_back(unique_ptr<Module> (new PeakFollower(2.0))); outputModules_["PeakShortTermLoudness"] = modules_.back().get(); outputModules_["ShortTermLoudness"] -> addTargetModule (*outputModules_["PeakShortTermLoudness"]); } return 1; }