AUv2: activation state, Render() flags and lock, and preset publication - #564
Merged
Merged
Conversation
…t be deactivated twice activateCLAP() now propagates clap_plugin.activate()'s failure, and deactivateCLAP() leaves an inactive plugin alone.
…wait on the process lock Only the offline non-render phases refuse a render now; the input pull gets a copy of the flags, and Render() try_locks instead of spinning behind an idle flush.
rebuildPresetCache() no longer numbers a partial, unsorted list and leaves the cache empty until the index finishes.
This was referenced Sep 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #549, #550, #552. Three commits, in dependency order — all three live in
wrapasauv2.cpp, which is why they are one PR.1. Explicit CLAP activation state (#549).
activateCLAP()ignoredclap_plugin.activate()'s result and set_initialized = trueregardless;deactivateCLAP()calledstop_processing()/deactivate()guarded only byif (_plugin). A failed reactivation therefore left a later AUUninitializedeactivating an already-inactive plugin, which CLAP forbids. New_clapActive(main-thread only, so no atomic) records the fact_initializedwas being asked to stand in for — it conflated "CLAP is down" with "running but not initialized".activateCLAP()now propagates the failure, and tears its own process adapter back down on the way out so nothing queues on an adapter no flush will drain.2.
Render()(#550). Three parts:inFlags == 0, so any host-set flag produced silence —kAudioUnitRenderAction_DoNotCheckRenderArgsmerely tells AUBase to skip argument checks, and an input marked silent upstream must still reach a plugin with a tail. OnlykAudioOfflineUnitRenderAction_Preflight|Completenow refuse a render, and this is not an offline unit, so they should never arrive at all.ProcessData::flagsis passed by reference intoPullInput, which ORs in whatever the upstream unit reports — so itsOutputIsSilencecould surface as this wrapper's output flag. The pull now gets a local copy, and the wrapper sets its own flag deliberately.Render()spun on_processLock, whichonIdle()can hold acrossclap_plugin_params.flush()— plugin code of unbounded duration. Nowtry_lock, falling into the existing zero-and-flag-silence path. Required adding a four-line additivetry_lock()todetail/shared/spinlock.h; no existing behaviour changes.3. Preset publication (#552). Note the issue text is misleading: the
isComplete()gate it asks for already existed (b187f89, before the issue was filed). The actual defect is thatrebuildPresetCache()still filled the cache from the partial list and numbered it, merely flagging it unbuilt. Sincestable_sortruns only at the end of the crawl, a host reading mid-crawl saw names against numbers that resolve elsewhere once the sort lands. The cache now stays empty until the crawl completes, matching what PD-2/PD-4 (9617822) settled for VST3.Follow-on, deliberately not fixed here:
Plugin::start_processing()also returns a bool that is ignored, so a plugin that activates but refuses to start processing still gets_initialized = trueand aprocess()call. Fixing that needs a second (processing) state, sincestop_processing()would then be illegal too. Same family as #549, but not what it describes — worth its own issue.Build-gated on
clap-first-distortion_auv2after each commit, clean. Not yet run throughauval.