AudioToolbox 的初探與實作

Phineas
6 min readJul 19, 2019

--

https://ichef.bbci.co.uk/news/640/cpsprodpb/9E89/production/_87558504_87558503.jpg

前言

近期,公司需求,需要實做一份播放音樂的程式,然而如果只是一般播放音樂檔案,那使用 AVFoundation 就僅僅足以,但這次不太依樣的地方是 Rescource 是純粹的 buffer array, 恩? 對,不要懷疑真的就是 Array,不過藉此機會稍微研究一下使用 AudioToolbox。

首先要先感謝兩份 blog,码农人生 羊羽shine,前者讓我對 AudioToolbox 的原理更了解一些,後者則實在實作中解答了我部份的疑惑,兩篇文章皆有附上連結。

AudioToolbox 功能非常的多,這邊僅介紹如何讀檔解析 buffer,放在 Queue,最後播放出來,附上我的 Github,雖然程式碼沒有考慮的多詳盡,但對於初學者來說應該能更快進入學習狀況,由於原理其他文章描述更加詳細,這篇主軸就快速帶領程式碼的解讀部分。

流程及原理

https://developer.apple.com/library/archive/documentation/MusicAudio/Conceptual/AudioQueueProgrammingGuide/AboutAudioQueues/AboutAudioQueues.html#//apple_ref/doc/uid/TP40005343-CH5-SW9

Step 1: 取得音檔路徑
Step 2: 讀取音樂檔案
Step 3: 解讀音檔資料(Description, buffer data)
Step 4: 開始跑 Audio Queue 流程
Step 4.1: 創造 AudioQueue
Step 4.2: 計算好一次 package 的量,並準備好 buffer array 準備播放
Step 4.3: 使用 AudioQueueAllocateBuffer 建立 AudioQueueBufferRef,並放入 buffer
Step 4.4: 使用 AudioQueueEnqueueBuffer 將 buffer 插入 AudioQueue 中
Step 4.5: 執行 AudioQueueStart 開始播放
Step 4.6: 播放完一個 buffer 後,透過 callback 回傳,並繼續播放下一個 buffer
Step 5: 若要繼續播放下一個音檔,切記停止 Audio Queue

讀取音樂檔案路徑

定義跟 Global 變數

讀取音檔

解析 Audio Description

開始執行 Audio Queue 流程

在 prepareAudioFile function 中

a. 創造 AudioQueue,註冊 callback

b. 計算好一次 package 的量,並準備好 buffer array 準備播放

c. 使用 AudioQueueAllocateBuffer 建立 AudioQueueBufferRef,並放入 buffer

在 audioQueueOutputWithQueue function 中

a. 讀取片段 buffer 資料,並放入 audio buffer 中

b. 使用 AudioQueueEnqueueBuffer 將 buffer 插入 AudioQueue 中

播放完一個 buffer 後,透過 callback 回傳,並繼續播放下一個 buffer

最後,警記,在下一次播放開始前,由於 queue 會把 buffer 暫存住,記得要先 release 前一筆的 queue,不然會跟我依樣遇到 memory leak。

附上 Memory Leak StackOverflow

題外話

假設 Audio buffer 直接給你 array buffer,可以跳過前面大段步驟,直接產生 Audio description,放到 Queue 裡,讓他播放即可,如以下範例。

這邊提供一份簡單的 buffer 音效檔案 Audio File

心得

這次的學習是一個很棒的體驗,早在之前就有規劃要來讀一下 iOS 播音樂流程,但基於自己的繁忙事情的安排(自己的懶),總是有個理由往後推,這次遇到公司安排這個 Task,剛好藉此機會來了解一下,也順便寫下此篇,不管是讓自己未來再遇到問題時,可以翻出來快速查閱或者是透過文字描述,讓自己對於整個流程是有一個更近一步了解,不管怎麼說都是自我大大提升,感覺自己“粉棒”,呵呵。雖然這故事的結尾是最後發現公司交代的任務跟這個好像不太依樣 = =,但是這又是另外一個故事了。

--

--

Phineas
Phineas

Written by Phineas

Garminer. 程式是照你寫的在跑,而不是依你想的在執行

No responses yet