void DSP::sample(signed channel[]) { for(unsigned c = 0; c < settings.channels; c++) { buffer.write(c) = (real)channel[c] * settings.intensityInverse; } buffer.wroffset++; resampler->sample(); }
void ResamplerTest::performDownsampling(Resampler &resampler) { AudioBuffer tmpInputBuffer(TMP_HIGHSMPLR_BUFFER_LENGTH, AudioFormat(16000, 1)); AudioBuffer tmpOutputBuffer(TMP_LOWSMPLR_BUFFER_LENGTH, AudioFormat::MONO()); for (size_t i = 0, j = 0; i < inputBuffer.frames(); i += tmpInputBuffer.frames(), j += tmpOutputBuffer.frames()) { tmpInputBuffer.copy(inputBuffer, i); resampler.resample(tmpInputBuffer, tmpOutputBuffer); outputBuffer.copy(tmpOutputBuffer, -1, 0, j); } }
void RESAMPLER_reset(void *res){ Resampler *resampler = static_cast<Resampler*>(res); return resampler->reset(); }
int RESAMPLER_read(void *res,double ratio,int num_frames, float *out){ Resampler *resampler = static_cast<Resampler*>(res); return resampler->read(ratio,num_frames,out); }
bool ResamplerPlugIn::execute(PlugInArgList* pInArgList, PlugInArgList* pOutArgList) { VERIFY(pInArgList != NULL && pOutArgList != NULL); ProgressTracker progress(pInArgList->getPlugInArgValue<Progress>(Executable::ProgressArg()), "Executing Spectral Resampler.", "spectral", "{88CD3E49-A522-431A-AE2A-96A6B2EB4012}"); Service<DesktopServices> pDesktop; const DataElement* pElement(NULL); std::string waveFilename; // get default resampling options from user config std::string resampleMethod = ResamplerOptions::getSettingResamplerMethod(); double dropOutWindow = ResamplerOptions::getSettingDropOutWindow(); double fwhm = ResamplerOptions::getSettingFullWidthHalfMax(); bool useFillValue = ResamplerOptions::getSettingUseFillValue(); double fillValue = ResamplerOptions::getSettingSignatureFillValue(); std::vector<Signature*> originalSignatures; std::auto_ptr<std::vector<Signature*> > pResampledSignatures(new std::vector<Signature*>); std::string errorMsg; if (isBatch()) { VERIFY(pInArgList->getPlugInArgValue("Signatures to resample", originalSignatures)); if (originalSignatures.empty()) { Signature* pSignature = pInArgList->getPlugInArgValue<Signature>("Signature to resample"); if (pSignature != NULL) { originalSignatures.push_back(pSignature); } } if (originalSignatures.empty()) { progress.report("No signatures are available to be resampled.", 0, ERRORS, true); return false; } pElement = pInArgList->getPlugInArgValue<DataElement>("Data element wavelength source"); Filename* pWaveFilename = pInArgList->getPlugInArgValue<Filename>("Wavelengths Filename"); if (pWaveFilename != NULL) { waveFilename = pWaveFilename->getFullPathAndName(); } VERIFY(pInArgList->getPlugInArgValue("Resampling Method", resampleMethod)); VERIFY(pInArgList->getPlugInArgValue("Drop out window", dropOutWindow)); VERIFY(pInArgList->getPlugInArgValue("FWHM", fwhm)); VERIFY(pInArgList->getPlugInArgValue("Use fill value", useFillValue)); VERIFY(pInArgList->getPlugInArgValue("Fill value", fillValue)); } else { ResamplerPlugInDlg dlg(pDesktop->getMainWidget()); if (dlg.exec() == QDialog::Rejected) { progress.report("User canceled resampling.", 0, ABORT, true); progress.upALevel(); return false; } originalSignatures = dlg.getSignaturesToResample(); resampleMethod = dlg.getResamplingMethod(); dropOutWindow = dlg.getDropOutWindow(); fwhm = dlg.getFWHM(); useFillValue = dlg.getUseFillValue(); fillValue = dlg.getFillValue(); pElement = dlg.getWavelengthsElement(); waveFilename = dlg.getWavelengthsFilename(); } std::string resampledTo; FactoryResource<Wavelengths> pWavelengths; if (pElement != NULL) // try loading wavelengths from user specified data element { if (getWavelengthsFromElement(pElement, pWavelengths.get(), errorMsg) == false) { progress.report(errorMsg, 0, ERRORS, true); return false; } resampledTo = pElement->getName(); } else if (waveFilename.empty() == false) // if no user provided raster, look for a wavelengths file { if (QFile::exists(QString::fromStdString(waveFilename))) { if (getWavelengthsFromFile(waveFilename, pWavelengths.get(), errorMsg) == false) { progress.report(errorMsg, 0, ERRORS, true); return false; } } else { errorMsg = "The wavelengths file \"" + waveFilename + "\" could not be found."; progress.report(errorMsg, 0, ERRORS, true); return false; } resampledTo = waveFilename; } else // if no wavelength source provided, look for raster in current active spatial data view { SpatialDataView* pView = dynamic_cast<SpatialDataView*>(pDesktop->getCurrentWorkspaceWindowView()); if (pView != NULL) { LayerList* pLayerList = pView->getLayerList(); if (pLayerList != NULL) { pElement = pLayerList->getPrimaryRasterElement(); pWavelengths->initializeFromDynamicObject(pElement->getMetadata(), false); if (pWavelengths->isEmpty()) { progress.report("No target wavelengths are available for resampling the signatures.", 0, ERRORS, true); return false; } resampledTo = pElement->getName(); } } } PlugInResource pPlugIn("Resampler"); Resampler* pResampler = dynamic_cast<Resampler*>(pPlugIn.get()); if (pResampler == NULL) { progress.report("The \"Resampler\" plug-in is not available so the signatures can not be resampled.", 0, ERRORS, true); return false; } std::string dataName("Reflectance"); std::string wavelengthName("Wavelength"); // save user config settings - Resampler doesn't have interface to set them separately from user config std::string configMethod = ResamplerOptions::getSettingResamplerMethod(); ResamplerOptions::setSettingResamplerMethod(resampleMethod); double configDropout = ResamplerOptions::getSettingDropOutWindow(); ResamplerOptions::setSettingDropOutWindow(dropOutWindow); double configFwhm = ResamplerOptions::getSettingFullWidthHalfMax(); ResamplerOptions::setSettingFullWidthHalfMax(fwhm); std::vector<double> toWavelengths = pWavelengths->getCenterValues(); std::vector<double> toFwhm = pWavelengths->getFwhm(); if (toFwhm.size() != toWavelengths.size()) { toFwhm.clear(); // Resampler will use the default config setting fwhm if this vector is empty } unsigned int numSigs = originalSignatures.size(); unsigned int numSigsResampled(0); progress.report("Begin resampling signatures...", 0, NORMAL); for (unsigned int index = 0; index < numSigs; ++index) { if (isAborted()) { progress.report("Resampling aborted by user", 100 * index / numSigs, ABORT, true); return false; } if (originalSignatures[index] == NULL) { continue; } // check if signature has target wavelength centers and doesn't need to be resampled if (needToResample(originalSignatures[index], pWavelengths.get()) == false) { pResampledSignatures->push_back(originalSignatures[index]); ++numSigsResampled; continue; } DataVariant var = originalSignatures[index]->getData(dataName); if (var.isValid() == false) { continue; } std::vector<double> fromData; if (!var.getValue(fromData)) { continue; } var = originalSignatures[index]->getData(wavelengthName); if (var.isValid() == false) { continue; } std::vector<double> fromWavelengths; if (!var.getValue(fromWavelengths)) { continue; } std::string resampledSigName = originalSignatures[index]->getName() + "_resampled"; int suffix(2); ModelResource<Signature> pSignature(resampledSigName, NULL); // probably not needed but just in case resampled name already used while (pSignature.get() == NULL) { pSignature = ModelResource<Signature>(resampledSigName + StringUtilities::toDisplayString(suffix), NULL); ++suffix; } if (resampledTo.empty() == false) { DynamicObject* pMetaData = pSignature->getMetadata(); if (pMetaData != NULL) { pMetaData->setAttribute(CommonSignatureMetadataKeys::ResampledTo(), resampledTo); } } std::vector<double> toData; std::vector<int> toBands; if (pResampler->execute(fromData, toData, fromWavelengths, toWavelengths, toFwhm, toBands, errorMsg)) { if (toWavelengths.size() != toBands.size()) { if (toBands.size() < 2) // no need to try if only one point { continue; } if (useFillValue) { std::vector<double> values(toWavelengths.size(), fillValue); for (unsigned int i = 0; i < toBands.size(); ++i) { values[static_cast<unsigned int>(toBands[i])] = toData[i]; } toData.swap(values); DynamicObject* pMetaData = pSignature->getMetadata(); if (pMetaData != NULL) { pMetaData->setAttribute(CommonSignatureMetadataKeys::FillValue(), fillValue); } } else { std::vector<double> wavelengths(toBands.size()); for (unsigned int i = 0; i < toBands.size(); ++i) { wavelengths[i] = toWavelengths[static_cast<unsigned int>(toBands[i])]; } toWavelengths.swap(wavelengths); } } pSignature->setData(dataName, toData); pSignature->setData(wavelengthName, toWavelengths); SignatureDataDescriptor* pDesc = dynamic_cast<SignatureDataDescriptor*>(pSignature->getDataDescriptor()); if (pDesc == NULL) { continue; } pDesc->setUnits(dataName, originalSignatures[index]->getUnits(dataName)); pResampledSignatures->push_back(pSignature.release()); ++numSigsResampled; } std::string progressStr = QString("Resampled signature %1 of %2 signatures").arg(index + 1).arg(numSigs).toStdString(); progress.report(progressStr, (index + 1) * 100 / numSigs, NORMAL); } // reset config options ResamplerOptions::setSettingResamplerMethod(configMethod); ResamplerOptions::setSettingDropOutWindow(configDropout); ResamplerOptions::setSettingFullWidthHalfMax(configFwhm); if (numSigsResampled == numSigs) { progress.report("Complete", 100, NORMAL); progress.upALevel(); } else { errorMsg = QString("Only %1 of the %2 signatures were successfully resampled.").arg( numSigsResampled).arg(numSigs).toStdString(); progress.report(errorMsg, 100, WARNING, true); } VERIFY(pOutArgList->setPlugInArgValue("Resampled signatures", pResampledSignatures.release())); return true; }
long SBSMSInterfaceDecoderImp :: samples(audio *buf, long n) { return preResampler->read(buf, n); }
bool ElmFile::readResults() { StepResource pStep("Read Gains/Offsets File", "app", "D52A2267-4D43-44c1-A772-A8C6FD130E87"); VERIFY(pStep.get() != NULL); ifstream input(mFilename.c_str()); if (input.good() == false) { pStep->finalize(Message::Failure, "Unable to open file \"" + mFilename + "\"."); return false; } vector<double> wavelengths; vector<double> gains; vector<double> offsets; while (input.good() == true) { double wavelength = 0; double gain = 0; double offset = 0; input >> wavelength >> gain >> offset; if (input.good() == true) { wavelengths.push_back(wavelength); gains.push_back(gain); offsets.push_back(offset); } } input.close(); PlugInResource pPlugIn("Resampler"); Resampler* pResampler = dynamic_cast<Resampler*>(pPlugIn.get()); if (pResampler == NULL) { pStep->finalize(Message::Failure, "The Resampler plug-in is not available"); return false; } string errorMsg; vector<int> toBands; vector<double> toFwhm; vector<double> toGains; if (pResampler->execute(gains, toGains, wavelengths, mCenterWavelengths, toFwhm, toBands, errorMsg) == false) { pStep->finalize(Message::Failure, "Unable to compute Gains.\nResampler reported \"" + errorMsg + "\"."); return false; } vector<double> toOffsets; if (pResampler->execute(offsets, toOffsets, wavelengths, mCenterWavelengths, toFwhm, toBands, errorMsg) == false) { pStep->finalize(Message::Failure, "Unable to compute Offsets.\nResampler reported \"" + errorMsg + "\"."); return false; } if (toGains.size() == 0) { pStep->finalize(Message::Failure, "The results vector is empty."); return false; } int width = 1; for (unsigned int size = toGains.size(); (size - 1) / 10 > 0; size /= 10) { width++; } for (unsigned int bandCount = 0; bandCount < toGains.size(); ++bandCount) { stringstream name; name << "Band "; name << setw(width) << setfill('0') << (bandCount + 1); stringstream text; text << "Gain: " << setprecision(16) << toGains[bandCount]; text << ", Offset: " << setprecision(16) << toOffsets[bandCount]; pStep->addProperty(name.str(), text.str()); mpGainsOffsets[bandCount][0] = toGains[bandCount]; mpGainsOffsets[bandCount][1] = toOffsets[bandCount]; } pStep->finalize(); return true; }
bool SpectralLibraryManager::generateResampledLibrary(const RasterElement* pRaster) { VERIFY(pRaster != NULL); // check that lib sigs are in same units as the raster element const RasterDataDescriptor* pDesc = dynamic_cast<const RasterDataDescriptor*>(pRaster->getDataDescriptor()); VERIFY(pDesc != NULL); const Units* pUnits = pDesc->getUnits(); if (pDesc->getUnits()->getUnitType() != mLibraryUnitType) { if (Service<DesktopServices>()->showMessageBox("Mismatched Units", "The data are not in the " "same units as the spectral library.\n Do you want to continue anyway?", "Yes", "No") == 1) { return false; } } FactoryResource<Wavelengths> pWavelengths; pWavelengths->initializeFromDynamicObject(pRaster->getMetadata(), false); // populate the library with the resampled signatures PlugInResource pPlugIn("Resampler"); Resampler* pResampler = dynamic_cast<Resampler*>(pPlugIn.get()); VERIFY(pResampler != NULL); if (pWavelengths->getNumWavelengths() != pDesc->getBandCount()) { mpProgress->updateProgress("Wavelength information in metadata does not match the number of bands " "in the raster element", 0, ERRORS); return false; } // get resample suitable signatures - leave out signatures that don't cover the spectral range of the data std::vector<std::vector<double> > resampledData; resampledData.reserve(mSignatures.size()); std::vector<Signature*> resampledSignatures; resampledSignatures.reserve(mSignatures.size()); std::vector<std::string> unsuitableSignatures; std::vector<double> sigValues; std::vector<double> sigWaves; std::vector<double> rasterWaves = pWavelengths->getCenterValues(); std::vector<double> rasterFwhm = pWavelengths->getFwhm(); std::vector<double> resampledValues; std::vector<int> bandIndex; DataVariant data; for (std::vector<Signature*>::const_iterator it = mSignatures.begin(); it != mSignatures.end(); ++it) { data = (*it)->getData(SpectralLibraryMatch::getNameSignatureWavelengthData()); VERIFY(data.isValid()); VERIFY(data.getValue(sigWaves)); resampledValues.clear(); data = (*it)->getData(SpectralLibraryMatch::getNameSignatureAmplitudeData()); VERIFY(data.isValid()); VERIFY(data.getValue(sigValues)); double scaleFactor = (*it)->getUnits( SpectralLibraryMatch::getNameSignatureAmplitudeData())->getScaleFromStandard(); for (std::vector<double>::iterator sit = sigValues.begin(); sit != sigValues.end(); ++sit) { *sit *= scaleFactor; } std::string msg; if (pResampler->execute(sigValues, resampledValues, sigWaves, rasterWaves, rasterFwhm, bandIndex, msg) == false || resampledValues.size() != rasterWaves.size()) { unsuitableSignatures.push_back((*it)->getName()); continue; } resampledData.push_back(resampledValues); resampledSignatures.push_back(*it); } if (resampledSignatures.empty()) { std::string errMsg = "None of the signatures in the library cover the spectral range of the data."; if (mpProgress != NULL) { mpProgress->updateProgress(errMsg, 0, ERRORS); return false; } } if (unsuitableSignatures.empty() == false) { std::string warningMsg = "The following library signatures do not cover the spectral range of the data:\n"; for (std::vector<std::string>::iterator it = unsuitableSignatures.begin(); it != unsuitableSignatures.end(); ++it) { warningMsg += *it + "\n"; } warningMsg += "These signatures will not be searched for in the data."; Service<DesktopServices>()->showMessageBox("SpectralLibraryManager", warningMsg); StepResource pStep("Spectral LibraryManager", "spectral", "64B6C87A-A6C3-4378-9B6E-221D89D8707B"); pStep->finalize(Message::Unresolved, warningMsg); } std::string libName = "Resampled Spectral Library"; // Try to get the resampled lib element in case session was restored. If NULL, create a new raster element with // num rows = num valid signatures, num cols = 1, num bands = pRaster num bands RasterElement* pLib = dynamic_cast<RasterElement*>(Service<ModelServices>()->getElement(libName, TypeConverter::toString<RasterElement>(), pRaster)); if (pLib != NULL) { // check that pLib has same number of sigs as SpectralLibraryManager RasterDataDescriptor* pLibDesc = dynamic_cast<RasterDataDescriptor*>(pLib->getDataDescriptor()); VERIFY(pLibDesc != NULL); if (pLibDesc->getRowCount() != mSignatures.size()) { mpProgress->updateProgress("An error occurred during session restore and some signatures were not restored." " Check the spectral library before using.", 0, ERRORS); Service<ModelServices>()->destroyElement(pLib); pLib = NULL; } } bool isNewElement(false); if (pLib == NULL) { pLib = RasterUtilities::createRasterElement(libName, static_cast<unsigned int>(resampledData.size()), 1, pDesc->getBandCount(), FLT8BYTES, BIP, true, const_cast<RasterElement*>(pRaster)); isNewElement = true; } if (pLib == NULL) { mpProgress->updateProgress("Error occurred while trying to create the resampled spectral library", 0, ERRORS); return false; } RasterDataDescriptor* pLibDesc = dynamic_cast<RasterDataDescriptor*>(pLib->getDataDescriptor()); VERIFY(pLibDesc != NULL); // copy resampled data into new element if (isNewElement) { FactoryResource<DataRequest> pRequest; pRequest->setWritable(true); pRequest->setRows(pLibDesc->getActiveRow(0), pLibDesc->getActiveRow(pLibDesc->getRowCount()-1), 1); DataAccessor acc = pLib->getDataAccessor(pRequest.release()); for (std::vector<std::vector<double> >::iterator sit = resampledData.begin(); sit != resampledData.end(); ++sit) { VERIFY(acc->isValid()); void* pData = acc->getColumn(); memcpy(acc->getColumn(), &(sit->begin()[0]), pLibDesc->getBandCount() * sizeof(double)); acc->nextRow(); } // set wavelength info in resampled library pWavelengths->applyToDynamicObject(pLib->getMetadata()); FactoryResource<Units> libUnits; libUnits->setUnitType(mLibraryUnitType); libUnits->setUnitName(StringUtilities::toDisplayString<UnitType>(mLibraryUnitType)); pLibDesc->setUnits(libUnits.get()); } pLib->attach(SIGNAL_NAME(Subject, Deleted), Slot(this, &SpectralLibraryManager::resampledElementDeleted)); mLibraries[pRaster] = pLib; mResampledSignatures[pLib] = resampledSignatures; const_cast<RasterElement*>(pRaster)->attach(SIGNAL_NAME(Subject, Deleted), Slot(this, &SpectralLibraryManager::elementDeleted)); return true; }
bool AceAlgorithm::resampleSpectrum(Signature* pSignature, vector<double>& resampledAmplitude, const Wavelengths& wavelengths, vector<int>& resampledBands) { StepResource pStep("Resample Signature", "spectral", "E1C6F0EA-4D00-4B0E-851F-F677A479169D"); Progress* pProgress = getProgress(); if (wavelengths.isEmpty()) { // Check for an in-scene signature RasterElement* pElement = getRasterElement(); VERIFY(pElement != NULL); if (pSignature->getParent() == pElement) { vector<double> sigReflectances = dv_cast<vector<double> >(pSignature->getData("Reflectance"), vector<double>()); resampledAmplitude = sigReflectances; resampledBands.clear(); for (vector<double>::size_type i = 0; i < sigReflectances.size(); ++i) { resampledBands.push_back(static_cast<int>(i)); } pStep->finalize(Message::Success); return true; } string messageText = "The data set wavelengths are invalid."; if (pProgress != NULL) pProgress->updateProgress(messageText, 0, ERRORS); pStep->finalize(Message::Failure, messageText); return false; } vector<double> fwhm = const_cast<Wavelengths&>(wavelengths).getFwhm(); PlugInResource resampler("Resampler"); Resampler* pResampler = dynamic_cast<Resampler*>(resampler.get()); if (pResampler == NULL) { string messageText = "The resampler plug-in could not be created."; if (pProgress != NULL) pProgress->updateProgress(messageText, 0, ERRORS); pStep->finalize(Message::Failure, messageText); return false; } string err; try { vector<double> sigReflectance = dv_cast<vector<double> >(pSignature->getData("Reflectance")); resampledAmplitude.reserve(sigReflectance.size()); resampledBands.reserve(sigReflectance.size()); if (!pResampler->execute(sigReflectance, resampledAmplitude, dv_cast<vector<double> >(pSignature->getData("Wavelength")), wavelengths.getCenterValues(), fwhm, resampledBands, err)) { string messageText = "Resampling failed: " + err; if (pProgress != NULL) pProgress->updateProgress(messageText, 0, ERRORS); pStep->finalize(Message::Failure, messageText); return false; } } catch(std::bad_cast&) { string messageText = "Resampling failed: " + err; if (pProgress != NULL) pProgress->updateProgress(messageText, 0, ERRORS); pStep->finalize(Message::Failure, messageText); return false; } pStep->finalize(Message::Success); return true; }
void DSP::clear() { buffer.clear(); output.clear(); resampler->clear(); }
bool SignatureLibraryImp::insertSignatures(const vector<Signature*>& signatures) { if (find(signatures.begin(), signatures.end(), static_cast<Signature*>(NULL)) != signatures.end()) { return false; } SignatureLibrary* pInterface = dynamic_cast<SignatureLibrary*>(this); if (!mOriginalAbscissa.empty()) { return false; } const DynamicObject* pMetadata = getMetadata(); VERIFY(pMetadata != NULL); const vector<double>* pWavelengths = dv_cast<vector<double> >(&pMetadata->getAttributeByPath(CENTER_WAVELENGTHS_METADATA_PATH)); if (pWavelengths == NULL || pWavelengths->empty()) { return false; } RasterDataDescriptor* pRasterDescriptor = RasterUtilities::generateRasterDataDescriptor(getName(), pInterface, signatures.size(), pWavelengths->size(), 1, BIP, FLT8BYTES, ON_DISK); if (pRasterDescriptor == NULL) { return false; } ModelResource<RasterElement> pRasterElement (dynamic_cast<RasterElement*>( Service<ModelServices>()->createElement(pRasterDescriptor))); if (pRasterElement.get() == NULL) { return false; } PlugInResource resampler("Resampler"); Resampler* pResampler = dynamic_cast<Resampler*>(resampler.get()); if (pResampler == NULL) { return false; } DataAccessor accessor = pRasterElement->getDataAccessor(); vector<Signature*>::const_iterator ppSignature; int i = 0; for (ppSignature = signatures.begin(); ppSignature != signatures.end(); ++ppSignature, ++i) { if (!accessor.isValid()) { return false; } double* pRasterData = reinterpret_cast<double*>(accessor->getRow()); const vector<double>* pFromData = dv_cast<vector<double> >(&(*ppSignature)->getData("Reflectance")); const vector<double>* pFromWavelengths = dv_cast<vector<double> >(&(*ppSignature)->getData("Wavelength")); if (pFromData == NULL || pFromWavelengths == NULL) { return false; } vector<double> toData; vector<int> toBands; vector<double> toFwhm; string errorMessage; bool success = pResampler->execute(*pFromData, toData, *pFromWavelengths, *pWavelengths, toFwhm, toBands, errorMessage); if (success == false || toBands.size() != pWavelengths->size()) { return false; } std::copy(toData.begin(), toData.end(), pRasterData); accessor->nextRow(); string name = (*ppSignature)->getName(); DataDescriptor* pDataDesc = Service<ModelServices>()->createDataDescriptor(name, "DataElement", pInterface); DataDescriptorImp* pSigDesc = dynamic_cast<DataDescriptorImp*>(pDataDesc); mSignatures.push_back(new LibrarySignatureAdapter(*pSigDesc, SessionItemImp::generateUniqueId(), i, pInterface)); mSignatureNames[name] = mSignatures.back(); } mpOdre.reset(pRasterElement.release()); mOriginalAbscissa = *pWavelengths; notify(SIGNAL_NAME(Subject, Modified)); return true; }
bool SignatureLibraryImp::resample(const vector<double> &abscissa) { if (mpOdre.get() == NULL) { return false; } if (abscissa == mAbscissa) { return true; } PlugInResource resampler("Resampler"); Resampler* pResampler = dynamic_cast<Resampler*>(resampler.get()); if (pResampler == NULL) { return false; } desample(); if (abscissa.empty()) { return true; } RasterDataDescriptor* pDesc = dynamic_cast<RasterDataDescriptor*>(mpOdre->getDataDescriptor()); VERIFY(pDesc != NULL); unsigned int numSigs = pDesc->getRowCount(); if (numSigs == 0) { return true; } mResampledData.resize(numSigs * abscissa.size()); DataAccessor da = mpOdre->getDataAccessor(); if (da.isValid() == false) { desample(); return false; } vector<double> originalOrdinateData(mOriginalAbscissa.size()); vector<double> toData; vector<double> toFwhm; vector<int> toBands; string errorMessage; for (unsigned int i = 0; i < mSignatures.size(); ++i) { switchOnEncoding(pDesc->getDataType(), getOriginalAsDouble, da->getRow(), mOriginalAbscissa.size(), originalOrdinateData); toData.clear(); toData.reserve(mAbscissa.size()); toBands.clear(); toBands.reserve(mAbscissa.size()); bool success = pResampler->execute(originalOrdinateData, toData, mOriginalAbscissa, abscissa, toFwhm, toBands, errorMessage); if (!success || toData.size() != abscissa.size()) { desample(); return false; } std::copy(toData.begin(), toData.end(), &mResampledData[i*abscissa.size()]); da->nextRow(); } mAbscissa = abscissa; mNeedToResample = false; notify(SIGNAL_NAME(Subject, Modified)); return true; }
void CQInverse::initialise() { m_octaves = int(ceil(log(m_maxFrequency / m_minFrequency) / log(2))); if (m_octaves < 1) { m_kernel = 0; // incidentally causing isValid() to return false return; } m_kernel = new CQKernel(m_inparams); m_p = m_kernel->getProperties(); // Use exact powers of two for resampling rates. They don't have // to be related to our actual samplerate: the resampler only // cares about the ratio, but it only accepts integer source and // target rates, and if we start from the actual samplerate we // risk getting non-integer rates for lower octaves int sourceRate = pow(2, m_octaves); vector<int> latencies; // top octave, no resampling latencies.push_back(0); m_upsamplers.push_back(0); for (int i = 1; i < m_octaves; ++i) { int factor = pow(2, i); Resampler *r = new Resampler (sourceRate / factor, sourceRate, 50, 0.05); #ifdef DEBUG_CQ cerr << "inverse: octave " << i << ": resample from " << sourceRate/factor << " to " << sourceRate << endl; #endif // See ConstantQ.cpp for discussion on latency -- output // latency here is at target rate which, this way around, is // what we want latencies.push_back(r->getLatency()); m_upsamplers.push_back(r); } // additionally we will have fftHop latency at individual octave // rate (before upsampling) for the overlap-add in each octave for (int i = 0; i < m_octaves; ++i) { latencies[i] += m_p.fftHop * pow(2, i); } // Now reverse the drop adjustment made in ConstantQ to align the // atom centres across different octaves (but this time at output // sample rate) int emptyHops = m_p.firstCentre / m_p.atomSpacing; vector<int> pushes; for (int i = 0; i < m_octaves; ++i) { int factor = pow(2, i); int pushHops = emptyHops * pow(2, m_octaves - i - 1) - emptyHops; int push = ((pushHops * m_p.fftHop) * factor) / m_p.atomsPerFrame; pushes.push_back(push); } int maxLatLessPush = 0; for (int i = 0; i < m_octaves; ++i) { int latLessPush = latencies[i] - pushes[i]; if (latLessPush > maxLatLessPush) maxLatLessPush = latLessPush; } int totalLatency = maxLatLessPush + 10; if (totalLatency < 0) totalLatency = 0; m_outputLatency = totalLatency + m_p.firstCentre * pow(2, m_octaves-1); #ifdef DEBUG_CQ cerr << "totalLatency = " << totalLatency << ", m_outputLatency = " << m_outputLatency << endl; #endif for (int i = 0; i < m_octaves; ++i) { // Calculate the difference between the total latency applied // across all octaves, and the existing latency due to the // upsampler for this octave. int latencyPadding = totalLatency - latencies[i] + pushes[i]; #ifdef DEBUG_CQ cerr << "octave " << i << ": push " << pushes[i] << ", resampler latency inc overlap space " << latencies[i] << ", latencyPadding = " << latencyPadding << " (/factor = " << latencyPadding / pow(2, i) << ")" << endl; #endif m_buffers.push_back(RealSequence(latencyPadding, 0.0)); } for (int i = 0; i < m_octaves; ++i) { // Fixed-size buffer for IFFT overlap-add m_olaBufs.push_back(RealSequence(m_p.fftSize, 0.0)); } m_fft = new FFTReal(m_p.fftSize); }