예제 #1
0
    bool OME::interpolateResponse(const RealVec &freqs)
    {
        if(freqs.empty())
        {
            LOUDNESS_ERROR("OME: Input vector has no elements.");
            return 0;
        }
        else
        {
            response_.resize(freqs.size(), 0.0);

            //load the data into vectors
            getData();    

            //the spline
            spline s;

            //middle ear
            if(middleEarType_ != NONE)
            {
                s.set_points(middleEarFreqPoints_, middleEardB_);

                for (uint i=0; i < freqs.size(); i++)
                {
                    if((freqs[i]<=75) && (middleEarType_ == ANSIS342007_MIDDLE_EAR_HPF))
                            response_[i] = -14.6; //Post HPF correction
                    else if(freqs[i] >= middleEarFreqPoints_[40])
                        response_[i] = middleEardB_[40];
                    else
                        response_[i] = s(freqs[i]);
                }
            }
            else
            {
                LOUDNESS_WARNING("OME: No middle ear filter used.");
            }

            //outer ear
            if(outerEarType_ != NONE)
            {
                Real lastFreq = outerEarFreqPoints_.back();
                Real lastDataPoint = outerEardB_.back();
                s.set_points(outerEarFreqPoints_, outerEardB_);

                for(uint i = 0; i < freqs.size(); i++)
                {
                    if(freqs[i] >= lastFreq)
                        response_[i] += lastDataPoint;
                    else
                        response_[i] += s(freqs[i]);
                }
            }
            else
            {
                LOUDNESS_WARNING("OME: No outer ear filter used.");
            }

            return 1;
        }
    }
예제 #2
0
파일: Model.cpp 프로젝트: faroit/loudness
 void Model::process(const SignalBank &input)
 {
     if (initialized_)
         modules_[0] -> process(input);
     else
         LOUDNESS_WARNING(name_ << ": Not initialised!");
 }
    bool DynamicPartialLoudnessGM::initializeInternal(const TrackBank &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())
        {
            LOUDNESS_WARNING(name_
                    << ": No filter coefficients, opting to weight power spectrum.");

            weightSpectrum = true;

            //should we use for HPF for low freqs? default is true
            if(hpf_)
            {
                LOUDNESS_DEBUG(name_ << ": Using 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(input.getNTracks(), bCoefs, aCoefs))); 
            else
                modules_.push_back(unique_ptr<Module>
                        (new FIR(bCoefs))); 

            //clean up
            delete [] data;
        }

        /*
         * Frame generator for spectrogram
         */
        int windowSize = round(0.064*input.getFs());
        int hopSize = round(timeStep_*input.getFs());
        modules_.push_back(unique_ptr<Module> 
                (new FrameGenerator(windowSize, hopSize)));

        /*
         * Multi-resolution spectrogram
         */
        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};
        
        //create appropriate power spectrum module
        if(stereoToMono_)
        {
            modules_.push_back(unique_ptr<Module> 
                    (new PowerSpectrumAndSpatialDetection(bandFreqsHz, windowSizeSecs, uniform_)));
        }
        else
        {
            modules_.push_back(unique_ptr<Module>
                    (new PowerSpectrum(bandFreqsHz, windowSizeSecs, uniform_)));
        }

        /*
         * Compression
         */
        if(compressionCriterion_ > 0)
            modules_.push_back(unique_ptr<Module>
                    (new CompressSpectrum(compressionCriterion_))); 

        /*
         * Spectral weighting if necessary
         */
        if(weightSpectrum)
        {
            OME::MiddleEarType middleEar = OME::ANSI;
            OME::OuterEarType outerEar = OME::ANSI_FREE;
            if(hpf_)
                middleEar = OME::ANSI_HPF;
            if(diffuseField_)
                outerEar = OME::ANSI_DIFFUSE;

            modules_.push_back(unique_ptr<Module> 
                    (new WeightSpectrum(middleEar, outerEar))); 
        }

        /*
         * Roex filters
         */
        if(fastBank_)
        {
            modules_.push_back(unique_ptr<Module>
                    (new FastRoexBank(filterSpacing_, interpRoexBank_)));
        }
        else
        {
            modules_.push_back(unique_ptr<Module> 
                    (new RoexBankANSIS3407(1.8, 38.9, filterSpacing_)));
        }
        
        /*
         * Specific loudness
         */
        modules_.push_back(unique_ptr<Module>
                (new SpecificPartialLoudnessGM()));

        /*
         * Loudness integration
         */
        modules_.push_back(unique_ptr<Module>
                (new IntegratedPartialLoudnessGM(diotic_, true)));

        return 1;
    }
예제 #4
0
    bool PowerSpectrum::initializeInternal(const SignalBank &input)
    {
        
        ffts_.clear();

        //number of windows
        int nWindows = (int)windowSizes_.size();
        LOUDNESS_ASSERT(input.getNChannels() == nWindows,
                name_ << ": Number of channels do not match number of windows");
        LOUDNESS_ASSERT((int)bandFreqsHz_.size() == (nWindows + 1),
                name_ << ": Number of frequency bands should equal number of input channels + 1.");
        LOUDNESS_ASSERT(!anyAscendingValues(windowSizes_),
                    name_ << ": Window lengths must be in descending order.");

        //work out FFT configuration (constrain to power of 2)
        int largestWindowSize = input.getNSamples();
        vector<int> fftSize(nWindows, nextPowerOfTwo(largestWindowSize));
        if(sampleSpectrumUniformly_)
        {
            ffts_.push_back(unique_ptr<FFT> (new FFT(fftSize[0]))); 
            ffts_[0] -> initialize();
        }
        else
        {
            for(int w=0; w<nWindows; w++)
            {
                fftSize[w] = nextPowerOfTwo(windowSizes_[w]);
                ffts_.push_back(unique_ptr<FFT> (new FFT(fftSize[w]))); 
                ffts_[w] -> initialize();
            }
        }

        //desired bins indices (lo and hi) per band
        bandBinIndices_.resize(nWindows);
        normFactor_.resize(nWindows);
        int fs = input.getFs();
        int nBins = 0;
        for(int i=0; i<nWindows; i++)
        {
            //bin indices to use for compiled spectrum
            bandBinIndices_[i].resize(2);
            //These are NOT the nearest components but satisfies f_k in [f_lo, f_hi)
            bandBinIndices_[i][0] = ceil(bandFreqsHz_[i]*fftSize[i]/fs);
            // use < bandBinIndices_[i][1] to exclude upper bin
            bandBinIndices_[i][1] = ceil(bandFreqsHz_[i+1]*fftSize[i]/fs);
            LOUDNESS_ASSERT(bandBinIndices_[i][1]>0, 
                    name_ << ": No components found in band number " << i);

            //exclude DC and Nyquist if found
            int nyqIdx = (fftSize[i]/2) + (fftSize[i]%2);
            if(bandBinIndices_[i][0]==0)
            {
                LOUDNESS_WARNING(name_ << ": DC found...excluding.");
                bandBinIndices_[i][0] = 1;
            }
            if((bandBinIndices_[i][1]-1) >= nyqIdx)
            {
                LOUDNESS_WARNING(name_ << 
                        ": Bin is >= nyquist...excluding.");
                bandBinIndices_[i][1] = nyqIdx;
            }

            nBins += bandBinIndices_[i][1]-bandBinIndices_[i][0];

            //Power spectrum normalisation
            Real refSquared = referenceValue_ * referenceValue_;
            switch (normalisation_)
            {
                case NONE:
                    normFactor_[i] = 1.0 / refSquared;
                    break;
                case ENERGY:
                    normFactor_[i] = 2.0/(fftSize[i] * refSquared);
                    break;
                case AVERAGE_POWER:
                    normFactor_[i] = 2.0/(fftSize[i] * windowSizes_[i] * refSquared);
                    break;
                default:
                    normFactor_[i] = 2.0/(fftSize[i] * refSquared);
            }

            LOUDNESS_DEBUG(name_ << ": Normalisation factor : " << normFactor_[i]);
        }

        //total number of bins in the output spectrum
        LOUDNESS_DEBUG(name_ 
                << ": Total number of bins comprising the output spectrum: " << nBins);

        //initialize the output SignalBank
        output_.initialize(input.getNEars(), nBins, 1, fs);
        output_.setFrameRate(input.getFrameRate());

        //output frequencies in Hz
        int j = 0, k = 0;
        for(int i=0; i<nWindows; i++)
        {
            j = bandBinIndices_[i][0];
            while(j < bandBinIndices_[i][1])
                output_.setCentreFreq(k++, (j++)*fs/(Real)fftSize[i]);

            LOUDNESS_DEBUG(name_ 
                    << ": Included freq Hz (band low): " 
                    << fs * bandBinIndices_[i][0] / float(fftSize[i]) 
                    << ": Included freq Hz (band high): " 
                    << fs * (bandBinIndices_[i][1] - 1) / float(fftSize[i])); 
        }

        return 1;
    }