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; } }
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; }
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; }