亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

iOS音頻系列(三)--AudioQueue

2019-11-14 11:12:41
字體:
來源:轉載
供稿:網友

本篇是AudioQueue的官方文檔的筆記。Audio Queue Services可以play和record以下三類任何audio data:

Linear PCM.Any comPRessed format supported natively on the Apple platform you are developing for.Any other format for which a user has an installed codec.

對于最后一種類型,我們可以在使用AudioQueue同時自己將自己需要的format轉化成LPCM。AudioQueue是對mic和speaker的高度抽象,同時可以非常簡單的時間音頻codecs。與此同時,它也有一些高級功能,例如多個音頻的同步播放,回放等等。


About Audio Queues

這章會了解到audio queue的功能,結構體,以及內部運行的機理。具體的內容包括audio queues,audio queue buffers,audio queue會使用到的callback等。還有就是audio queue的狀態以及參數。

What Is an Audio Queue?

An audio queue 是iOS中play和record audio的對象.底層是AudioQueueRef。Audio queue可以完成以下工作:

Connecting to audio hardwareManaging memoryEmploying codecs, as needed, for compressed audio formatsMediating recording or playback

Audio Queue Architecture

Audio queue的具體結構有以下幾個部分構成:

A set of audio queue buffers, each of which is a temporary repository for some audio dataA buffer queue, an ordered list for the audio queue buffersAn audio queue callback function, that you write

根據我們使用audio queue的用途(record or play),具體的結構略有不同,僅僅只是callback函數函數的內容不同。

Audio Queues for Recording

一個用于record 的audio queue,需要使用AudioQueueNewInput方法創建,它的具體結構如圖:

A recording audio queue

Audio Queues for Playback

一個用于play的audio queue,需要使用AudioQueueNewOutput函數創建,

A playback audio queue

Audio Queue Buffers

audio queue buffer的數據結構如下:

1234567
typedef struct AudioQueueBuffer {    const UInt32   mAudioDataBytesCapacity;    void *const    mAudioData;    UInt32         mAudioDataByteSize;    void           *mUserData;} AudioQueueBuffer;typedef AudioQueueBuffer *AudioQueueBufferRef;

其中mAudioData字段表示這個buffer中的有用數據的地址,其他的字段用來輔助audio queue來管理使用這個buffer。一個audio queue可以使用任何數目的buffers。但是我們一般選擇3個,比較好管理。

Audio queue通過下面的方式管理它們內部的buffers:

An audio queue allocates a buffer when you call the AudioQueueAllocateBuffer function.When you release an audio queue by calling the AudioQueueDispose function, the queue releases its buffers.

The Buffer Queue and Enqueuing

buffer queue是由audio buffers組成的,是audio queue中的buffers。我們前面介紹了audio queue是如何使用callback管理內部的buffers。不論當前是用于record或者是pleyback,將buffer放到audio queue都是需要我們在callback函數中去手動調用的。

The Recording Process

The recording process

In step 1 , recording begins. The audio queue fills a buffer with acquired data.In step 2, the first buffer has been filled. The audio queue invokes the callback, handing it the full buffer (buffer 1). The callback (step 3) writes the contents of the buffer to an audio file. At the same time, the audio queue fills another buffer (buffer 2) with freshly acquired data.In step 4, the callback enqueues the buffer (buffer 1) that it has just written to disk, putting it in line to be filled again. The audio queue again invokes the callback (step 5), handing it the next full buffer (buffer 2). The callback (step 6) writes the contents of this buffer to the audio file. This looping steady state continues until the user stops the recording.

The Playback Process

The playback process

Controlling the Playback Process

Audio queue buffers在queue是順序播放的,我們可以通theAudioQueueEnqueueBufferWithParameters方法來進行控制

The Audio Queue Callback Function

Audio queue在運行過程中會不斷的調用callback函數,通常間隔時間和audio queue buffer的大小相關,一般是幾秒一次。

audio queue callback主要任務是將audio queue buffer歸還給audio queue。callback中通過AudioQueueEnqueueBuffer方法將buffer加載到audio queue的最后。在playback中,可以使用AudioQueueEnqueueBufferWithParameters在enqueue的過程中進行更多的控制。

The Recording Audio Queue Callback Function

如果你僅僅使用audio queue去將record的audio data寫入file system,callback的方法實現的原型如下:

12345678
AudioQueueInputCallback (    void                               *inUserData,    AudioQueueRef                      inAQ,    AudioQueueBufferRef                inBuffer,    const AudioTimeStamp               *inStartTime,    UInt32                             inNumberPacketDescriptions,    const AudioStreamPacketDescription *inPacketDescs);

一個recording audio queue會觸發我們注冊的callback,會在callback的參數中傳入所有需要的關于audio data的相關信息:

inUserData 是一個自定義的結構體,用來存儲audio queueu以及audio queue buffer的狀態信息,也包括AudioFileID,audio data format等。inAQ 表示哪個audio queue觸發這個callback。inBuffer 是一個audio queue buffer,它的內容是由audio queue填充的,內部包括最新的audio data。并且這些audio data已經根據初始化時候傳遞的格式參數格式化好的數據。inStartTime 表示這個buffer中的第一個采樣的采樣時間點,一般app中不太需要這個參數。inNumberPacketDescriptions 表示inPacketDescs參數中的packet descriptions的個數。如果你是錄入VBR format,audio queue就會在callback中提供這個參數,如果是CBR,audio queue就不會使用packet descriptions參數,這個參數會是NULL。inPacketDescs 表示buffer中samples相關的一系列的packet descriptions。是否設置同上一個參數。

The Playback Audio Queue Callback Function

這個片段會介紹如果使用playing audio queue,那么callback應該的信息:

12345
AudioQueueOutputCallback (    void                  *inUserData,    AudioQueueRef         inAQ,    AudioQueueBufferRef   inBuffer);

一個playback audio queue會觸發這個callback,提供一些關于audio data的有用信息:

inUserData 見上inAQ 表示哪個audio queue觸發這個callback。inBuffer 表示被audio queue設置為空的audio queue buffer,你需要在callback中將其內部信息填滿,填充內容是你從AudioFile中讀取的audio data。

Using Codecs and Audio Data Formats

我們日常使用Audio Queue Services時,都會使用codecs(audio data coding/decoding componets)用來在不同audio format之間進行轉化。

每個audio queue都有一個audio data format,可以在AudioStreamBasicDescription結構體中得到。當我們在ASBD中指定了mFormatID以后,audio queue在向buffer中填充數據時候就會使用相應的codec。同樣如果指定sample rate和channel count,audio queue也會同樣。具體的過程見下圖:

Audio format conversion during recording

第一步中,app會告知audio queue開始record,同時告訴它使用的的data format。第二步中,audio queue將獲取到的new data使用codec轉化成目標format。然后audio queue會調用callback函數,傳入格式化以后的audio data。第三步中,callback函數會將格式化以后的audio data寫入file中。

整個過程中,callback函數壓根就不需要知道data fromat是什么。

Audio format conversion during playback

在播放過程中,正好和錄音過程相反,只需要在創建audio queue時候將data format告知即可。


Audio Queue Control and State

audio queue在創建和銷毀的過程有一個聲明周期。app需要管理它的聲明周期,控制它的狀態,具體控制狀態的方法如下:

Start (AudioQueueStart).初始化audio queue用來record或者playback。Prime (AudioQueuePrime).對于playback,在調用AudioQueueStart摯愛去哪調用確保數據可用,這個方法和record沒有關系。Stop (AudioQueueStop). 調用以后會重置audio queue,然后會停止record或者playback。在playback應用中,一般在沒有audio data可以播放時候調用。Pause (AudioQueuePause). 在record或者playback中調用這個方法不會影響到buffers。如果需要恢復,調用AudioQueueStart。Flush (AudioQueueFlush). 在enqueue最后一個audio queue buffer以后調用這個方法,確保所有的數據被record或者play(主要是在midst processing的數據)。Reset (AudioQueueReset). 調用以后立即停止audio queue,然后將所有的buffers移除,重置所有的DSP狀態等到。

在調用AudioQueueStop方法時候有兩種模式:同步和異步。

Synchronous stopping happens immediately, without regard for previously buffered audio data.Asynchronous stopping happens after all queued buffers have been played or recorded.

Recording Audio

當我們的record使用Audio Queue Services,存儲的路徑可以是磁盤上的任何地方,或者網絡,或者內存中。這部分內容記錄大多數的使用場景,存儲在磁盤中。

具體的步驟如下:

定義一個結構體去存儲狀態,format,文件路徑等信息。完成audio queue callback函數,其中將record以后的數據進行存儲。為audio queue buffers計算出合適的大小,并且在file中寫入magic cookies。初始化自定義的結構體創建recording audio queue,然后給它創建3個audio queue buffers,然后創建一個file用來存儲record以后的audio data。啟動audio queue當audio queue停止以后,dispose它以及buffers

具體的實現內容可以參考Apple官方文檔:Recording Audio。

Playing Audio

當我們使用Audio Queue Service去play audio時,音頻源文件可以是任何在disk file或者memory中,這部分內容是如何用Audio Queue Service播放存儲在disk上的audio file。

具體的步驟如下:

定義一個結構體管理Audio queue的狀態,format,file path等完成audio queue callback函數去進行實際的播放創建一個函數用來計算最適合的audio queue buffer的大小打開audio file,確定它的audio data format創建audio queue,對它進行配置為audio queue創建buffers,然后啟動audio queue,當播放結束,callback讓audio queue停止播放銷毀audio queue

具體的實現內容可以參考Apple官方文檔:Playing Audio。

可運行的Demo

請參考我的github: https://github.com/brownfeng/AudioQueueServiceDemo


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美激情欧美激情在线五月| 日韩成人在线免费观看| 亚洲福利在线看| 麻豆国产精品va在线观看不卡| 国产丝袜精品视频| 精品视频在线导航| 欧美激情视频在线免费观看 欧美视频免费一| 久久久久久久爱| 亚洲福利视频在线| 精品欧美一区二区三区| 国产视频一区在线| 久久精品色欧美aⅴ一区二区| 日韩在线国产精品| 欧美性生交大片免费| 色樱桃影院亚洲精品影院| 国产va免费精品高清在线| 欧美日韩人人澡狠狠躁视频| 高清一区二区三区日本久| 国产+成+人+亚洲欧洲| 91久久国产婷婷一区二区| 欧美亚洲免费电影| 欧美性理论片在线观看片免费| 国产成人精品久久二区二区91| 国产精品精品久久久| 国产欧美精品在线播放| 亚洲成人精品久久| 国产成人精品视频| xxx一区二区| 国产v综合ⅴ日韩v欧美大片| 欧美激情一级二级| 亚洲精品久久久久久久久| 黄色一区二区在线| 免费成人高清视频| 欧美日韩亚洲一区二区三区| 日韩av黄色在线观看| 亚洲欧美中文在线视频| 影音先锋欧美在线资源| 久久久亚洲国产| 欧美日韩亚洲激情| 久久久久久久激情视频| 性欧美在线看片a免费观看| 九色精品免费永久在线| 欧美黑人一区二区三区| 精品国产乱码久久久久酒店| 欧美黑人一区二区三区| 国产精品视频白浆免费视频| 蜜月aⅴ免费一区二区三区| 欧美日韩精品在线| 国产成人综合精品| 色婷婷成人综合| 国产午夜精品全部视频播放| 欧美亚洲视频在线看网址| 亚洲国产精品久久久久秋霞蜜臀| 国产精品男人爽免费视频1| 中文字幕视频一区二区在线有码| 亚洲自拍偷拍色片视频| 97成人超碰免| 亚洲第一在线视频| 91久久久久久久久久久久久| 精品国产视频在线| 亚洲已满18点击进入在线看片| 日本精品久久电影| 亚洲精品久久久久久久久久久久| 欧美成人在线免费视频| 亚洲伊人一本大道中文字幕| 国产在线观看91精品一区| 国内精品免费午夜毛片| 日韩在线激情视频| 韩剧1988免费观看全集| 精品亚洲夜色av98在线观看| 精品欧美一区二区三区| 98精品国产自产在线观看| 国产精品久久久久久av福利| 一个人看的www欧美| 最近2019年日本中文免费字幕| 亚洲专区在线视频| 亚洲成人黄色在线| 成人福利在线观看| 欧美大尺度在线观看| 欧美在线免费视频| 国产精品一区二区三区久久久| 亚洲区bt下载| 欧美日韩在线一区| 全亚洲最色的网站在线观看| 日韩小视频在线| 欧美激情亚洲一区| 亚洲成人在线视频播放| 日韩毛片在线看| 久久亚洲精品国产亚洲老地址| 欧美性猛交xxxx乱大交蜜桃| 亚洲aa中文字幕| 欧美日韩中国免费专区在线看| 欧美成人一区在线| 欧美精品www在线观看| 国产最新精品视频| 亚洲欧美国产精品久久久久久久| 欧美一区二区三区艳史| 欧美一乱一性一交一视频| 成人h片在线播放免费网站| 欧美日韩激情视频8区| 精品丝袜一区二区三区| 久久精品亚洲一区| 国产精品美女午夜av| 欧美精品手机在线| 国产日韩欧美在线观看| 久久久久久亚洲精品中文字幕| 亚洲国产成人一区| 亚洲自拍偷拍视频| 欧美最猛性xxxx| 欧美国产精品日韩| 久久视频精品在线| 国产69精品99久久久久久宅男| 国产精品视频网址| 亚洲国产精品悠悠久久琪琪| 91美女福利视频高清| 亚洲日本aⅴ片在线观看香蕉| 九九热99久久久国产盗摄| 精品国模在线视频| 日韩av高清不卡| 欧美综合第一页| 欧美激情亚洲视频| 一区三区二区视频| 国产欧美一区二区三区在线看| 尤物yw午夜国产精品视频明星| 欧美理论电影在线播放| 久久久久久亚洲精品| 国产一区视频在线播放| 国语对白做受69| 久久综合久中文字幕青草| 欧美一区二三区| 欧美黑人xxxⅹ高潮交| 欧美资源在线观看| 97精品国产97久久久久久免费| 国内外成人免费激情在线视频| 亚洲福利精品在线| 亚洲视频在线观看视频| 久久精品电影网站| 精品国产一区二区三区久久狼5月| 亚洲男子天堂网| 91午夜理伦私人影院| 亚洲精品www久久久| 国产91精品久久久久| 国产精品成人一区二区| 国产精品美女呻吟| 国产脚交av在线一区二区| 另类视频在线观看| 国产日本欧美一区二区三区| 亚洲天堂av图片| 亚洲欧洲一区二区三区久久| 欧美成人午夜剧场免费观看| 久久久久久网站| 亚洲国产精品美女| 欧美韩国理论所午夜片917电影| 久久久久久久亚洲精品| 黄色成人av在线| 欧美日韩精品中文字幕| 国产精品中文字幕久久久| 欧美日韩亚洲成人| 久久999免费视频| 国产精品久久久久久久久久ktv| 国产精品麻豆va在线播放| 91精品国产综合久久香蕉最新版| 国产欧美最新羞羞视频在线观看| 国产亚洲视频在线观看|