# HG changeset patch # User Chris Cannam # Date 1562433174 -3600 # Node ID 7763893904730ad782b13ac823a5b5c95f33e299 # Parent 043e05c956fb7775afefa7efccb8abdf7164a1b1# Parent fd7f127ecd89e87e6901dcaad2ac4c9d8209601c Merge diff -r 043e05c956fb -r 776389390473 base/ById.h --- a/base/ById.h Sat Jul 06 18:12:38 2019 +0100 +++ b/base/ById.h Sat Jul 06 18:12:54 2019 +0100 @@ -31,16 +31,15 @@ //!!! further possibilities: // -// - id can only be queried when an object is added to ById (maybe -// add() returns the id, and there is a ById::idOf, but the -// object has no public getId()) -// // - get() returns a pointer wrapper that cannot be shared/copied // again by the caller (except by the usual C++ trickery) // // also to do: review how often we are calling getAs<...> when we // could just be using get +//!!! NB we still haven't solved the problem of what to do for a +//!!! user-initiated cancel of a transform + struct IdAlloc { // The value NO_ID (-1) is never allocated diff -r 043e05c956fb -r 776389390473 data/model/Model.cpp --- a/data/model/Model.cpp Sat Jul 06 18:12:38 2019 +0100 +++ b/data/model/Model.cpp Sat Jul 06 18:12:54 2019 +0100 @@ -25,15 +25,6 @@ Model::~Model() { SVDEBUG << "Model::~Model: " << this << " with id " << getId() << endl; -/*!!! - if (!m_aboutToDelete) { - SVDEBUG << "NOTE: Model(" << this << ", \"" - << objectName() << "\", type uri <" - << m_typeUri << ">)::~Model(): Model deleted " - << "with no aboutToDelete notification" - << endl; - } -*/ //!!! see notes in header - sort this out /* if (!m_alignmentModel.isNone()) { @@ -45,13 +36,6 @@ void Model::setSourceModel(ModelId modelId) { -/*!!! - if (m_sourceModel) { - disconnect(m_sourceModel, SIGNAL(aboutToBeDeleted()), - this, SLOT(sourceModelAboutToBeDeleted())); - } -*/ - m_sourceModel = modelId; auto model = ModelById::get(m_sourceModel); @@ -59,45 +43,9 @@ connect(model.get(), SIGNAL(alignmentCompletionChanged(ModelId)), this, SIGNAL(alignmentCompletionChanged(ModelId))); } - - -/* - if (m_sourceModel) { - connect(m_sourceModel, SIGNAL(alignmentCompletionChanged()), - this, SIGNAL(alignmentCompletionChanged())); - connect(m_sourceModel, SIGNAL(aboutToBeDeleted()), - this, SLOT(sourceModelAboutToBeDeleted())); - } -*/ -} -/*!!! -void -Model::aboutToDelete() -{ - SVDEBUG << "Model(" << this << ", \"" - << objectName() << "\", type name \"" - << getTypeName() << "\", type uri <" - << m_typeUri << ">)::aboutToDelete()" << endl; - - if (m_aboutToDelete) { - SVDEBUG << "WARNING: Model(" << this << ", \"" - << objectName() << "\", type uri <" - << m_typeUri << ">)::aboutToDelete: " - << "aboutToDelete called more than once for the same model" - << endl; - } - - emit aboutToBeDeleted(); - m_aboutToDelete = true; } void -Model::sourceModelAboutToBeDeleted() -{ - m_sourceModel = nullptr; -} -*/ -void Model::setAlignment(ModelId alignmentModel) { SVDEBUG << "Model(" << this << "): accepting alignment model " diff -r 043e05c956fb -r 776389390473 data/model/Model.h --- a/data/model/Model.h Sat Jul 06 18:12:38 2019 +0100 +++ b/data/model/Model.h Sat Jul 06 18:12:54 2019 +0100 @@ -133,31 +133,6 @@ virtual bool isSparse() const { return false; } /** - * Mark the model as abandoning. This means that the application - * no longer needs it, so it can stop doing any background - * calculations it may be involved in. Note that as far as the - * model API is concerned, this does nothing more than tell the - * model to return true from isAbandoning(). The actual response - * to this will depend on the model's context -- it's possible - * nothing at all will change. - */ - //!!! aim to lose this (???) - /*!!! - virtual void abandon() { - m_abandoning = true; - } - */ - - /** - * Query whether the model has been marked as abandoning. - */ - //!!! aim to lose this - /*!!! - virtual bool isAbandoning() const { - return m_abandoning; - } - */ - /** * Return true if the model has finished loading or calculating * all its data, for a model that is capable of calculating in a * background thread. @@ -329,7 +304,6 @@ protected: Model() : -//!!! m_abandoning(false), m_extendTo(0) { } // Not provided. @@ -339,7 +313,6 @@ ModelId m_sourceModel; ModelId m_alignmentModel; QString m_typeUri; -//!!! bool m_abandoning; sv_frame_t m_extendTo; }; diff -r 043e05c956fb -r 776389390473 transform/FeatureExtractionModelTransformer.cpp --- a/transform/FeatureExtractionModelTransformer.cpp Sat Jul 06 18:12:38 2019 +0100 +++ b/transform/FeatureExtractionModelTransformer.cpp Sat Jul 06 18:12:54 2019 +0100 @@ -648,17 +648,29 @@ if (m_abandoned) return; ModelId inputId = getInputModel(); - auto input = ModelById::getAs(inputId); - if (!input) { - abandon(); - return; - } - sv_samplerate_t sampleRate = input->getSampleRate(); + sv_samplerate_t sampleRate; + int channelCount; + sv_frame_t startFrame; + sv_frame_t endFrame; + + { // scope so as not to have this borrowed pointer retained around + // the edges of the process loop + auto input = ModelById::getAs(inputId); + if (!input) { + abandon(); + return; + } - int channelCount = input->getChannelCount(); - if ((int)m_plugin->getMaxChannelCount() < channelCount) { - channelCount = 1; + sampleRate = input->getSampleRate(); + + channelCount = input->getChannelCount(); + if ((int)m_plugin->getMaxChannelCount() < channelCount) { + channelCount = 1; + } + + startFrame = input->getStartFrame(); + endFrame = input->getEndFrame(); } float **buffers = new float*[channelCount]; @@ -696,9 +708,6 @@ } } - sv_frame_t startFrame = input->getStartFrame(); - sv_frame_t endFrame = input->getEndFrame(); - RealTime contextStartRT = primaryTransform.getStartTime(); RealTime contextDurationRT = primaryTransform.getDuration(); @@ -761,6 +770,11 @@ ((((blockFrame - contextStart) / stepSize) * 99) / (contextDuration / stepSize + 1)); + if (!ModelById::get(inputId)) { + abandon(); + return; + } + // channelCount is either input->channelCount or 1 if (frequencyDomain) { diff -r 043e05c956fb -r 776389390473 transform/RealTimeEffectModelTransformer.cpp --- a/transform/RealTimeEffectModelTransformer.cpp Sat Jul 06 18:12:38 2019 +0100 +++ b/transform/RealTimeEffectModelTransformer.cpp Sat Jul 06 18:12:54 2019 +0100 @@ -142,6 +142,25 @@ return; } + sv_samplerate_t sampleRate; + int channelCount; + sv_frame_t startFrame; + sv_frame_t endFrame; + + { // scope so as not to have this borrowed pointer retained around + // the edges of the process loop + auto input = ModelById::getAs(getInputModel()); + if (!input) { + abandon(); + return; + } + + sampleRate = input->getSampleRate(); + channelCount = input->getChannelCount(); + startFrame = input->getStartFrame(); + endFrame = input->getEndFrame(); + } + auto stvm = ModelById::getAs(m_outputs[0]); auto wwfm = ModelById::getAs(m_outputs[0]); @@ -153,17 +172,12 @@ return; } - sv_samplerate_t sampleRate = input->getSampleRate(); - int channelCount = input->getChannelCount(); if (!wwfm && m_input.getChannel() != -1) channelCount = 1; sv_frame_t blockSize = m_plugin->getBufferSize(); float **inbufs = m_plugin->getAudioInputBuffers(); - sv_frame_t startFrame = input->getStartFrame(); - sv_frame_t endFrame = input->getEndFrame(); - Transform transform = m_transforms[0]; RealTime contextStartRT = transform.getStartTime(); @@ -205,6 +219,12 @@ sv_frame_t got = 0; + auto input = ModelById::getAs(getInputModel()); + if (!input) { + abandon(); + return; + } + if (channelCount == 1) { if (inbufs && inbufs[0]) { auto data = input->getData