Пример #1
0
    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;
    }
Пример #2
0
    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;
    }