音訊
音訊輸出的實作。時鐘與同步見 engine.md,格式見 codecs.md。
FlowAVAudio 以 AVAudioOutputFactory 註冊 AudioOutput,由 AVAudioEngine 實作。
音訊圖
- 正常速度:
AVAudioSourceNode(interleaved Float32)直接接輸出,不經 mixer;音量由核心的AudioRenderSource套用。 - 倍速:才接入
AVAudioUnitTimePitch(保持音高)。即使 bypass 它每個 IO 週期仍要 deinterleave 與 interleave,故只在倍速時留在圖中。 - 格式:取樣率跟隨裝置,唯一的重取樣在解碼器(非即時執行緒);最多雙聲道,由解碼器 downmix。
- 格式變更:裝置的取樣率或聲道數改變時,output 以
AudioRenderSource.outputFormatDidChange()通知核心,通知前後仍以舊格式輸出、由 output unit 轉換。核心停止輸出、以AudioOutput.updateFormat()取得新格式,重建 PCM ring 與音訊解碼器,並從播放位置以.exactseek 重新解碼(同解碼策略)。AVAudioSourceNode會從建立時的格式轉換,故換格式時重建。
Render
- render block 不捕捉任何值,經
RenderSlots找到RenderState,Swift 不在 render 執行緒做參照計數。 - 只呼叫
AudioRenderSource、讀 atomic 與運算:無鎖、無配置、無 log 與 signpost(硬即時,見執行緒分級)。 - 限制只在 render callback 內;Core Audio 每個 IO 週期在 callback 外自行上鎖一次,屬正常。
- 量測 callback 時把時間戳寫入 ring buffer,由其他執行緒發 signpost。
裝置與延遲
- IO 緩衝:1024 frames(預設的兩倍),IO 週期與其固定成本減半;多出的 10 ms 由延遲補償,只有暫停與音量變慢。依裝置範圍夾限,每次啟動重新套用。
- 延遲:裝置、串流、safety offset、IO 緩衝,倍速時另加 time-stretch;啟動與裝置變更時重新查詢。
- 裝置變更:引擎自行停止後在新裝置上重啟;格式不同時見格式變更。停止期間換的裝置在
start時檢查。
生命週期
- 暫停:
engine.stop(),釋放 IO 資源。不用pause():恢復後 host time 從暫停處繼續,落後暫停的時長。 - 切換速度、flush:引擎停止時改圖或重設 time-stretch,再重啟;sample time 歸零,由核心重新錨定時鐘。
- 預熱:模組啟用時背景建立一次 output unit,先付載入 audio HAL 與 plug-in 的成本(M4 Max 約 65 ms),不開裝置 IO(PERF-02)。