Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions src/detail/auv2/auv2_base_classes.h
Original file line number Diff line number Diff line change
Expand Up @@ -834,7 +834,11 @@ class WrapAsAUV2 : public ausdk::AUBase,
// caller must treat that as a failed initialization.
bool activateCLAP();
void deactivateCLAP();
// parameter-only round trip on a throwaway process adapter, for when no render
// the process adapter used while the CLAP is deactivated: SetParameter queues
// the host's values on it and flushParameters() delivers them. Built on first
// use; call under _processLock. Null when the plugin has no params extension.
Clap::AUv2::ProcessAdapter *ensureFlushAdapter();
// parameter-only round trip on the deactivated-case adapter, for when no render
// is running to carry the events. Only legal while the CLAP is deactivated.
void flushParameters();
// the AU-level half of the teardown, which an internal restart must not do
Expand All @@ -857,8 +861,11 @@ class WrapAsAUV2 : public ausdk::AUBase,
std::shared_ptr<Clap::Plugin> _plugin = nullptr;

std::unique_ptr<Clap::AUv2::ProcessAdapter> _processAdapter;
// Only for the deactivated-plugin flush, where _processAdapter does not
// exist. Lives across flushes so gestures pair up; see flushParameters().
// Only while the plugin is deactivated, where _processAdapter does not exist:
// SetParameter queues the host's values on it (a host sets bypass and
// parameters on a unit before it calls Initialize), and the idle flush or
// activateCLAP() -- whichever comes first -- delivers them. Lives across
// flushes so gestures pair up; see ensureFlushAdapter().
std::unique_ptr<Clap::AUv2::ProcessAdapter> _flushAdapter;
std::atomic<bool> _initialized = false;

Expand Down
51 changes: 51 additions & 0 deletions src/detail/auv2/process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -852,4 +852,55 @@ void ProcessAdapter::addParameterEvent(const clap_param_info_t &info, double val
this->_eventindices.emplace_back(this->_events.size());
this->_events.emplace_back(n);
}

// Moves the queued parameter events onto another adapter. This exists for one
// moment: deactivateCLAP() drops the process adapter, and anything the host set
// since the last render or flush is still sitting in it. Those values are as
// real as any other -- a host that sets a parameter and then deactivates the
// unit (a restart, a format change, a project close-and-reopen) has been told
// nothing went wrong -- so they move to the adapter the deactivated state
// flushes from rather than dying with this one.
//
// Only parameter events move. Everything else queued here belongs to a render
// that is not going to happen now, and a flush may not carry it anyway.
//
// The offsets go with the block they were offsets into, and dropping them is
// not tidiness: sortEventIndices() sorts on time first, and only breaks ties on
// the insertion index. Left as they were, an event stamped into some earlier
// block would sort *after* a value the deactivated state queues later at time
// 0 -- the stale value applied last, which is the inversion this transfer
// exists to avoid. At 0 they all tie, and the tiebreak then orders them the way
// they arrived: these first, anything queued afterwards over the top.
//
// Order follows position in _events, because flush() rebuilds _eventindices
// over it before sorting. Keeping the index list in step here is for a
// process() that never comes on the adapter these are going to.
size_t ProcessAdapter::transferPendingParametersTo(ProcessAdapter &other)
{
if (&other == this) return 0;

size_t moved = 0;
size_t kept = 0;
for (size_t i = 0; i < _events.size(); ++i)
{
if (isParameterEvent(_events[i].header.type))
{
clap_multi_event_t n = _events[i];
n.header.time = 0;
other._eventindices.emplace_back(other._events.size());
other._events.emplace_back(n);
++moved;
}
else
{
_events[kept++] = _events[i];
}
}

_events.resize(kept);
_eventindices.clear();
for (size_t i = 0; i < kept; ++i) _eventindices.emplace_back(i);

return moved;
}
} // namespace Clap::AUv2
4 changes: 4 additions & 0 deletions src/detail/auv2/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ class ProcessAdapter
UInt32 inOffsetSampleFrame);
void stopNote(int32_t note_id, int16_t channel, UInt32 inOffsetSampleFrame);
void addParameterEvent(const clap_param_info_t &info, double value, uint32_t inOffsetSampleFrame);
// Hands the parameter events still queued here to another adapter, so they
// survive this one being destroyed. Returns how many moved. See
// WrapAsAUV2::deactivateCLAP().
size_t transferPendingParametersTo(ProcessAdapter &other);
// void startNote()
~ProcessAdapter();

Expand Down
Loading
Loading