Skip to content

AUv3: parameter changes stop syncing in both directions when audio processing pauses #538

Description

@singularpoint

With a CLAP plugin wrapped as AUv3, parameter changes stop synchronizing in both directions while audio processing is suspended, even though parameters remain editable. Resuming audio processing delivers the pending changes.

Reproduced with AUv3 in both hosts:

  • REAPER 7.79
  • Audio Hijack 4.6.0

Tested on macOS 26.6.2 / Apple Silicon, using next at 9501dad0, matching upstream next when checked.

Expected behavior

Parameter exchange should continue without requiring audio processing to resume. CLAP explicitly provides params.flush() for this purpose. Its parameter contract says host-control changes are delivered through process() or flush(), and host_params.request_flush() requires the host to schedule one of those calls. Here, the wrapper is the CLAP host. CLAP parameter contract, at the SDK revision used.

flush() must not run concurrently with process() and must follow CLAP's active/inactive thread rules. Those constraints require serialized delivery; they do not make audio processing a prerequisite for parameter exchange.

Quick reproduction — no debugger

Attached: passive-parameters-repro.zip. It contains a small CLAP plugin, AUv3 build/install instructions, and detailed reproduction steps. The plugin has one parameter, silent audio output, exact-value buttons, and an event log.

The following steps use Audio Hijack's block off/on control as a concrete example. Build/install the plugin, load Example: Passive Parameters, and start the session with the block on. Locate both the plugin editor and the host's own Value control.

  1. Click Set 0.25 in the plugin editor; confirm both sides show 0.25.
  2. Turn the block off, click Set 0.75, and wait five seconds.
    Plugin: 0.75; host: still 0.25.
  3. Turn the block on, without another edit. The host catches up to 0.75.
  4. Reset both sides to 0.25 while on, then turn the block off again.
  5. Change Value through the host's control to approximately 0.6 and wait.
    Host: new value; plugin: still 0.25.
  6. Turn the block on. The plugin catches up.

The expected result in steps 2 and 5 is agreement while the block stays off. The log identifies events delivered via process or flush; compare both value displays, since acceptance of a CLAP output event alone does not prove AUv3 delivery.

Investigation

The following runtime observations were collected in Audio Hijack.

  • Plugin -> Host: the request reaches
    param_request_flush(),
    which only logs it. The outgoing change remains pending until processing resumes.
  • Host -> Plugin: the
    AU parameter observer
    sees _renderResourcesAllocated == YES even with the block off, queues the change for audio processing, and skips flush(). We observed pending changes and stale plugin state; enabling the block drained them through process().

Apple defines renderResourcesAllocated as resource-allocation state, not a guarantee of subsequent processing callbacks. Relying on it to defer all delivery leaves parameter exchange stalled in this state.

passive-parameters-repro.zip

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions