Skip to content

Investigate whether device changes require a full teardown #178

Description

@dariuscorvus

Summary

Every default-output change and every AVAudioEngineConfigurationChange triggers a complete stop() + start() — helper, tap, aggregate, ring, and graph all rebuilt — splicing roughly 100 ms of silence into playback. Determine which changes actually require new Core Audio objects.

This is a research issue, not an implementation commitment.

Motivation

The codebase already made exactly this argument once and acted on it. The comment at AudioEngine.swift:626-638 explains that restarting the tap for every new audio process cost ~100 ms of silence (#140), and that the helper now refreshes the live tap in place instead.

The same reasoning was never applied to device changes. Since the helper taps processes, not the output device, an output-device change may not require touching the helper at all.

Evidence

  • AudioEngine.swift:590-624handleDeviceChangerestartTap()stop() + start()
  • AudioEngine.swift:371-383 — the AVAudioEngineConfigurationChange observer triggers the same path
  • AudioEngine.swift:626-638 — the in-place tap refresh already adopted for Tap restart on every new audio process splices ~100 ms of silence into playback #140, with its dropout rationale
  • CaptureClient.stop() terminates the helper and unmaps the ring; start() rebuilds all of it

Investigation question

Which of these require rebuilding which objects: a default-output change, a sample-rate change, a channel-layout change, a Continuity migration, device disappearance?

Method

  1. Instrument the current code to record what actually changes on each event — tap format, output format, device UID, channel count.
  2. Attempt to keep the helper and ring alive across an output-device change, rebuilding only the AVAudioEngine graph.
  3. Measure the dropout before and after, on at least built-in output plus one external USB DAC plus AirPods.
  4. Verify whether the tap format changes when the output device does. If it does, the ring geometry changes and the helper must be rebuilt.

Evidence to collect

Per event type: which formats changed; whether the helper survived; measured interruption duration; whether Continuity handoff still works.

Effort bound

One focused investigation. Produce a written finding; do not implement in this issue.

Decision outputs

Either a bounded implementation issue for in-place reconfiguration of the classes of change that permit it, or a documented finding that a full rebuild is required, with the reason.

Non-goals

Acceptance criteria

  • Each change type is classified as requiring in-place reconfiguration or full rebuild
  • Measured on built-in output and at least one external device
  • Documents whether tap format tracks output device
  • States the expected dropout for each class
  • Produces either a bounded implementation issue or a documented rejection

Test plan

  • Manual: measure dropout on output switch, built-in ↔ external
  • Manual: measure on Continuity migration
  • Manual: confirm AirPods handoff still works under any prototype
  • Manual: sample-rate change via Audio MIDI Setup

Dependencies

Delivery estimate

Size S as an investigation; the follow-on implementation is likely M. Primary uncertainty: whether the tap format is coupled to the output device. Review specialties: Core Audio device lifecycle. Rollback boundary: no production change in this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions