幾種播放音頻文件的方式(六) —— 音頻隊(duì)列服務(wù)(Audio Queue Services)之關(guān)于音頻隊(duì)列(三)

版本記錄

版本號(hào) 時(shí)間
V1.0 2017.12.27

前言

ios系統(tǒng)中有很多方式可以播放音頻文件,這里我們就詳細(xì)的說(shuō)明下播放音樂文件的原理和實(shí)例。感興趣的可以看我寫的上面幾篇鬼吵。
1. 幾種播放音頻文件的方式(一) —— 播放本地音樂
2. 幾種播放音頻文件的方式(二) —— 音效播放
3. 幾種播放音頻文件的方式(三) —— 網(wǎng)絡(luò)音樂播放
4. 幾種播放音頻文件的方式(四) —— 音頻隊(duì)列服務(wù)(Audio Queue Services)(一)
5. 幾種播放音頻文件的方式(五) —— 音頻隊(duì)列服務(wù)(Audio Queue Services)簡(jiǎn)介(二)

About Audio Queues - 關(guān)于音頻隊(duì)列

在本章中,您將了解音頻隊(duì)列的功能,體系結(jié)構(gòu)和內(nèi)部工作原理但绕。 您將了解音頻隊(duì)列audio queues,音頻隊(duì)列緩沖區(qū)audio queue buffers以及音頻隊(duì)列用于錄制或回放的回調(diào)函數(shù)callback惶看。 您還可以了解有關(guān)音頻隊(duì)列狀態(tài)和參數(shù)的信息壁熄。 到本章結(jié)束時(shí)帚豪,您將獲得有效使用此技術(shù)所需的概念性理解。


What Is an Audio Queue? - 音頻隊(duì)列是什么草丧?

音頻隊(duì)列Audio Queue是用于在iOS或Mac OS X中錄制或播放音頻的軟件對(duì)象狸臣。它由AudioQueue.h頭文件中聲明的AudioQueueRef不透明數(shù)據(jù)類型表示。

音頻隊(duì)列的工作是:

  • 連接到音頻硬件
  • 管理內(nèi)存
  • 根據(jù)需要使用編解碼器壓縮音頻格式
  • 調(diào)解錄制或播放

您可以將音頻隊(duì)列與其他Core Audio接口以及相對(duì)較少量的自定義代碼一起使用昌执,以在應(yīng)用程序中創(chuàng)建完整的數(shù)字音頻錄制或播放解決方案烛亦。


Audio Queue Architecture - 音頻隊(duì)列結(jié)構(gòu)

下面我們就看一下音頻隊(duì)列的結(jié)構(gòu)。

所有音頻隊(duì)列具有相同的總體結(jié)構(gòu)懂拾,由以下部分組成:

  • 一組音頻隊(duì)列緩沖區(qū)audio queue buffers煤禽,每個(gè)緩沖區(qū)都是一些音頻數(shù)據(jù)的臨時(shí)存儲(chǔ)庫(kù)
  • 緩沖隊(duì)列buffer queue,音頻隊(duì)列緩沖區(qū)audio queue buffers的有序列表
  • 一個(gè)你寫的音頻隊(duì)列回調(diào)函數(shù)audio queue callback

結(jié)構(gòu)的改變?nèi)Q于音頻隊(duì)列是用于記錄還是回放岖赋。 不同點(diǎn)在于音頻隊(duì)列如何連接其輸入和輸出檬果,以及回調(diào)函數(shù)的作用。

Audio Queues for Recording - 音頻隊(duì)列用于記錄

使用AudioQueueNewInput函數(shù)創(chuàng)建的錄制音頻隊(duì)列的結(jié)構(gòu)如圖1-1所示唐断。

Figure 1-1 A recording audio queue

記錄音頻隊(duì)列的輸入側(cè)通常連接到外部音頻硬件选脊,如麥克風(fēng)。例如脸甘,在iOS中恳啥,音頻來(lái)自用戶內(nèi)置麥克風(fēng)或耳機(jī)麥克風(fēng)所連接的設(shè)備。在Mac OS X的默認(rèn)情況下丹诀,音頻來(lái)自系統(tǒng)偏好設(shè)置中由用戶設(shè)置的系統(tǒng)的默認(rèn)音頻輸入設(shè)備钝的。

錄制音頻隊(duì)列的輸出端使用您編寫的回調(diào)函數(shù)。在錄制到磁盤時(shí)铆遭,回調(diào)會(huì)將新音頻數(shù)據(jù)的緩沖區(qū)(從音頻隊(duì)列接收)寫入音頻文件硝桩。但是,記錄音頻隊(duì)列可以以其他方式使用枚荣。例如碗脊,您的回調(diào)可以將音頻數(shù)據(jù)直接提供給您的應(yīng)用程序,而不是將其寫入磁盤棍弄。

您將在 The Recording Audio Queue Callback Function中了解有關(guān)此回調(diào)的更多信息望薄。

每個(gè)音頻隊(duì)列(無(wú)論是用于記錄還是播放)都有一個(gè)或多個(gè)音頻隊(duì)列緩沖區(qū)audio queue buffers。這些緩沖區(qū)按照一個(gè)稱為緩沖隊(duì)列buffer queue的特定順序排列呼畸。在圖中痕支,音頻隊(duì)列緩沖區(qū)按照它們被填充的順序進(jìn)行編號(hào) - 這與它們被交給回調(diào)的順序是相同的。您將了解音頻隊(duì)列如何在The Buffer Queue and Enqueuing中使用其緩沖區(qū)buffers蛮原。

Audio Queues for Playback - 音頻隊(duì)列回放

播放音頻隊(duì)列(使用AudioQueueNewOutput函數(shù)創(chuàng)建)的結(jié)構(gòu)如圖1-2所示卧须。

Figure 1-2 A playback audio queue

在回放音頻隊(duì)列中,回調(diào)位于輸入端。 該回調(diào)負(fù)責(zé)從磁盤(或其他來(lái)源)獲取音頻數(shù)據(jù)花嘶,并將其交給音頻隊(duì)列笋籽。 回放回調(diào)還會(huì)告訴音頻隊(duì)列在沒有更多數(shù)據(jù)可以播放時(shí)停止播放。 您將在The Playback Audio Queue Callback Function中了解有關(guān)此回調(diào)的更多信息椭员。

回放音頻隊(duì)列的輸出通常連接到外部音頻硬件车海,如揚(yáng)聲器。 在iOS中隘击,音頻會(huì)轉(zhuǎn)到用戶選擇的設(shè)備上侍芝,例如接收器或耳機(jī)。 在Mac OS X的默認(rèn)情況下埋同,音頻將轉(zhuǎn)到系統(tǒng)偏好設(shè)置中由用戶設(shè)置的系統(tǒng)的默認(rèn)音頻輸出設(shè)備州叠。


Audio Queue Buffers - 音頻隊(duì)列緩沖

音頻隊(duì)列緩沖區(qū)是AudioQueue.h頭文件中聲明的AudioQueueBuffer類型的數(shù)據(jù)結(jié)構(gòu):

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

在代碼清單中突出顯示的mAudioData字段指向緩沖區(qū)本身:一塊內(nèi)存,用作正在播放或錄音的音頻數(shù)據(jù)的瞬時(shí)塊的容器凶赁。其他字段中的信息有助于音頻隊(duì)列audio queue管理緩沖區(qū)buffer咧栗。

音頻隊(duì)列可以使用任意數(shù)量的緩沖區(qū)。你的應(yīng)用程序指定多少虱肄。一個(gè)典型的數(shù)字是三個(gè)致板。這使得一個(gè)用于寫入磁盤,而另一個(gè)正在填充新的音頻數(shù)據(jù)浩峡。如果需要補(bǔ)償磁盤I / O延遲等問(wèn)題可岂,那么第三個(gè)緩沖區(qū)就有用了错敢。Figure 1-3說(shuō)明了這一點(diǎn)翰灾。

音頻隊(duì)列為其緩沖區(qū)執(zhí)行內(nèi)存管理。

  • 當(dāng)您調(diào)用AudioQueueAllocateBuffer函數(shù)時(shí)尿瞭,音頻隊(duì)列將分配一個(gè)緩沖區(qū)挨队。
  • 通過(guò)調(diào)用AudioQueueDispose函數(shù)釋放音頻隊(duì)列時(shí)董栽,隊(duì)列釋放緩沖區(qū)。

這提高了您添加到應(yīng)用程序的錄制和播放功能的穩(wěn)健性咽块。它還有助于優(yōu)化資源使用。

有關(guān)AudioQueueBuffer數(shù)據(jù)結(jié)構(gòu)的完整說(shuō)明欺税,請(qǐng)參閱Audio Queue Services Reference侈沪。


The Buffer Queue and Enqueuing - 緩沖隊(duì)列和入隊(duì)

緩沖隊(duì)列就是給音頻隊(duì)列,實(shí)際上是音頻隊(duì)列服務(wù)晚凿,他們的名字的對(duì)象亭罪。 您在Audio Queue Architecture中認(rèn)識(shí)了緩沖區(qū)隊(duì)列 —— 一個(gè)有序的緩沖區(qū)列表。 在這里歼秽,您將了解到音頻隊(duì)列對(duì)象與回調(diào)函數(shù)在錄制或回放過(guò)程中如何管理緩沖區(qū)隊(duì)列应役。 尤其是,您了解入隊(duì)enqueuing,將音頻隊(duì)列緩沖區(qū)添加到緩沖區(qū)隊(duì)列箩祥。 無(wú)論您正在執(zhí)行錄制還是回放院崇,入隊(duì)都是回調(diào)執(zhí)行的任務(wù)。

1. The Recording Process - 錄音過(guò)程

錄制時(shí)袍祖,一個(gè)音頻隊(duì)列緩沖區(qū)正在填充從輸入設(shè)備(如麥克風(fēng))獲取的音頻數(shù)據(jù)底瓣。 緩沖區(qū)隊(duì)列中剩余的緩沖區(qū)排列在當(dāng)前緩沖區(qū)后面,等待依次填充音頻數(shù)據(jù)蕉陋。

音頻隊(duì)列按已獲取音頻數(shù)據(jù)的填充緩沖區(qū)的順序?qū)⑺鼈儌鬟f給您的回調(diào)濒持。 圖1-3說(shuō)明了使用音頻隊(duì)列時(shí)錄制的工作原理。

Figure 1-3 The recording process

在圖1-3的步驟1中寺滚,開始記錄柑营。 音頻隊(duì)列用獲取的數(shù)據(jù)填充緩沖區(qū)。

在第2步中村视,第一個(gè)緩沖區(qū)已被填充官套。 音頻隊(duì)列調(diào)用回調(diào)函數(shù),將其交給完整的緩沖區(qū)(緩沖區(qū)1)蚁孔。 回調(diào)(步驟3)將緩沖區(qū)的內(nèi)容寫入音頻文件奶赔。 同時(shí),音頻隊(duì)列用新獲取的數(shù)據(jù)填充另一個(gè)緩沖區(qū)(緩沖區(qū)2)杠氢。

在第4步中站刑,回調(diào)將剛剛寫入磁盤的緩沖區(qū)(緩沖區(qū)1)排入隊(duì)列,以便再次進(jìn)行填充鼻百。 音頻隊(duì)列再次調(diào)用回調(diào)(步驟5)绞旅,把下一個(gè)完整的緩沖區(qū)(緩沖區(qū)2)交給它。 回調(diào)(第6步)將此緩沖區(qū)的內(nèi)容寫入音頻文件温艇。 這種循環(huán)穩(wěn)定狀態(tài)一直持續(xù)到用戶停止記錄因悲。

2. The Playback Process - 播放過(guò)程

播放時(shí),一個(gè)音頻隊(duì)列緩沖區(qū)正在發(fā)送到輸出設(shè)備勺爱,如揚(yáng)聲器晃琳。 緩沖區(qū)隊(duì)列中剩余的緩沖區(qū)排列在當(dāng)前緩沖區(qū)后面,等待依次播放琐鲁。

音頻隊(duì)列按照播放的順序?qū)⒉シ诺囊纛l數(shù)據(jù)緩沖區(qū)傳遞到您的回調(diào)卫旱。 回調(diào)會(huì)將新的音頻數(shù)據(jù)讀入緩沖區(qū),然后將其排入隊(duì)列围段。 圖1-4說(shuō)明了使用音頻隊(duì)列時(shí)的播放方式顾翼。

Figure 1-4 The playback process

在圖1-4的步驟1中,應(yīng)用程序啟動(dòng)播放音頻隊(duì)列蒜撮。 應(yīng)用程序?yàn)槊總€(gè)音頻隊(duì)列緩沖區(qū)調(diào)用一次回調(diào)函數(shù)暴构,將其填充并添加到緩沖區(qū)隊(duì)列中跪呈。 啟動(dòng)確保播放可以在您的應(yīng)用程序調(diào)用AudioQueueStart函數(shù)時(shí)立即啟動(dòng)(步驟2)。

在步驟3中取逾,音頻隊(duì)列發(fā)送第一個(gè)緩沖區(qū)(緩沖區(qū)1)輸出耗绿。

一旦第一個(gè)緩沖器被播放,回放音頻隊(duì)列就進(jìn)入循環(huán)穩(wěn)定狀態(tài)砾隅。 音頻隊(duì)列開始播放下一個(gè)緩沖區(qū)(緩沖區(qū)2误阻,步驟4)并調(diào)用回調(diào)(步驟5),將剛剛播放的緩沖區(qū)(緩沖區(qū)1)傳送給它晴埂。 回調(diào)(第6步)從音頻文件中填充緩沖區(qū)究反,然后將其排入隊(duì)列進(jìn)行回放。

3. Controlling the Playback Process - 控制播放過(guò)程

音頻隊(duì)列緩沖區(qū)總是以它們?nèi)腙?duì)的順序播放儒洛。 但是精耐,音頻隊(duì)列服務(wù)使用AudioQueueEnqueueBufferWithParameters函數(shù)為播放過(guò)程提供了一些控制。 這個(gè)功能可以讓你:

  • 為緩沖區(qū)設(shè)置精確的播放時(shí)間琅锻。 這可以讓你支持同步卦停。
  • 修剪音頻隊(duì)列緩沖區(qū)開始或結(jié)束處的幀。 這可以讓你刪除前導(dǎo)或尾隨靜默恼蓬。
  • 以緩沖區(qū)的粒度設(shè)置回放增益惊完。

有關(guān)設(shè)置回放增益的更多信息,請(qǐng)參閱Audio Queue Parameters处硬。 有關(guān)AudioQueueEnqueueBufferWithParameters函數(shù)的完整說(shuō)明小槐,請(qǐng)參閱 Audio Queue Services Reference


The Audio Queue Callback Function - 音頻隊(duì)列回調(diào)函數(shù)

通常荷辕,使用音頻隊(duì)列服務(wù)的大部分編程工作包括編寫音頻隊(duì)列回調(diào)函數(shù)凿跳。

在錄制或回放過(guò)程中,音頻隊(duì)列回調(diào)函數(shù)由擁有它的音頻隊(duì)列重復(fù)調(diào)用桐腌。 兩次調(diào)用之間的時(shí)間取決于音頻隊(duì)列緩沖區(qū)的容量拄显,一般范圍從半秒到幾秒苟径。

無(wú)論是用于記錄還是回放案站,音頻隊(duì)列回調(diào)的一個(gè)責(zé)任是將音頻隊(duì)列緩沖audio queue buffers返回到緩沖區(qū)隊(duì)列buffer queue。 回調(diào)函數(shù)使用AudioQueueEnqueueBuffer函數(shù)將緩沖區(qū)添加到緩沖區(qū)隊(duì)列的末尾棘街。 對(duì)于播放蟆盐,如果需要更多控制,則可以使用AudioQueueEnqueueBufferWithParameters函數(shù)遭殉,如Controlling the Playback Process中所述石挂。

1. The Recording Audio Queue Callback Function - 錄制音頻隊(duì)列回調(diào)函數(shù)

本節(jié)介紹將音頻錄制到磁盤文件的常見情況而寫的回調(diào)。 以下是AudioQueue.h頭文件中聲明的錄音音頻隊(duì)列回調(diào)的原型:

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

記錄音頻隊(duì)列在調(diào)用回調(diào)函數(shù)時(shí)提供了回調(diào)函數(shù)將下一組音頻數(shù)據(jù)寫入音頻文件的所有內(nèi)容:

  • inUserData险污,通常情況下痹愚,你已經(jīng)設(shè)置了以包含音頻隊(duì)列代表你對(duì)文件的寫入狀態(tài)信息和其緩沖區(qū)富岳,音頻文件對(duì)象(類型AudioFileID的)的自定義結(jié)構(gòu),以及音頻數(shù)據(jù)格式的信息文件拯腮。
  • inAQ是調(diào)用回調(diào)的音頻隊(duì)列窖式。
  • inBuffer是一個(gè)音頻隊(duì)列緩沖區(qū),由音頻隊(duì)列新填充动壤,包含回調(diào)函數(shù)需要寫入磁盤的新數(shù)據(jù)萝喘。數(shù)據(jù)已根據(jù)您在自定義結(jié)構(gòu)中指定的格式(在inUserData參數(shù)中傳遞)格式化。有關(guān)詳情琼懊,請(qǐng)參閱Using Codecs and Audio Data Formats阁簸。
  • inStartTime是緩沖區(qū)中第一個(gè)采樣的采樣時(shí)間。對(duì)于基本錄音哼丈,你的callback不使用此參數(shù)启妹。
  • inNumberPacketDescriptionsinPacketDescs參數(shù)中的數(shù)據(jù)包描述的數(shù)量。如果您正在錄制為VBR(可變比特率)格式醉旦,則音頻隊(duì)列會(huì)將此參數(shù)的值提供給您的callback翅溺,然后將該值傳遞AudioFileWritePackets函數(shù)。 CBR(恒定比特率)格式不使用數(shù)據(jù)包描述髓抑。對(duì)于CBR記錄咙崎,音頻隊(duì)列將此設(shè)置和inPacketDescs參數(shù)設(shè)置為NULL
  • inPacketDescs是與緩沖區(qū)中的樣本對(duì)應(yīng)的一組數(shù)據(jù)描述吨拍。同樣褪猛,音頻隊(duì)列為此參數(shù)提供值,如果音頻數(shù)據(jù)是在VBR的格式羹饰,你的callback將其傳遞到AudioFileWritePackets函數(shù)(在AudioFile.h頭文件中聲明)伊滋。

有關(guān)錄音callback的更多信息,請(qǐng)參閱本文檔中的Recording Audio队秩,并參閱Audio Queue Services Reference笑旺。

2. The Playback Audio Queue Callback Function - 播放音頻回調(diào)函數(shù)

本節(jié)介紹您為從磁盤文件播放音頻的常見情況而寫的回調(diào)。 以下是AudioQueue.h頭文件中聲明的回放音頻隊(duì)列回調(diào)的原型:

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

回放音頻隊(duì)列在調(diào)用回調(diào)函數(shù)時(shí)提供回調(diào)需要從音頻文件讀取下一組音頻數(shù)據(jù)的內(nèi)容:

  • inUserData馍资,通常情況下筒主,你已經(jīng)設(shè)置了以包含音頻隊(duì)列代表你對(duì)文件的寫入狀態(tài)信息和其緩沖區(qū),音頻文件對(duì)象(類型AudioFileID的)的自定義結(jié)構(gòu)鸟蟹,以及音頻數(shù)據(jù)格式的信息文件乌妙。在播放音頻隊(duì)列的情況下,您的回調(diào)會(huì)使用此結(jié)構(gòu)中的字段跟蹤當(dāng)前數(shù)據(jù)包索引建钥。
  • inAQ是調(diào)用callback的音頻隊(duì)列藤韵。
  • inBuffer是音頻隊(duì)列緩沖區(qū),由音頻隊(duì)列提供熊经,您的回調(diào)函數(shù)將填充從正在播放的文件中讀取的下一組數(shù)據(jù)泽艘。

如果您的應(yīng)用程序正在播放VBR數(shù)據(jù)欲险,則回調(diào)callback需要獲取正在讀取的音頻數(shù)據(jù)的數(shù)據(jù)包信息。它通過(guò)調(diào)用AudioFile.h頭文件中聲明AudioFileReadPackets函數(shù)來(lái)完成此操作匹涮。該回調(diào)然后將包信息放置在自定義數(shù)據(jù)結(jié)構(gòu)中以使其可用于回放音頻隊(duì)列盯荤。

有關(guān)回放回調(diào)callback的更多信息,請(qǐng)參閱本文檔中的Playing Audio焕盟,并參閱Audio Queue Services Reference秋秤。


Using Codecs and Audio Data Formats - 使用編解碼器和音頻數(shù)據(jù)格式

音頻隊(duì)列服務(wù)使用編解碼器(音頻數(shù)據(jù)編碼/解碼組件)根據(jù)需要在音頻格式之間進(jìn)行轉(zhuǎn)換。 您的錄制或回放應(yīng)用程序可以使用任何已安裝編解碼器的音頻格式脚翘。 您不需要編寫自定義代碼來(lái)處理各種音頻格式灼卢。 具體來(lái)說(shuō),你的回調(diào)不需要知道數(shù)據(jù)格式来农。

這里就是如何工作的鞋真。 每個(gè)音頻隊(duì)列都有一個(gè)音頻數(shù)據(jù)格式,以AudioStreamBasicDescription結(jié)構(gòu)表示沃于。 當(dāng)您在結(jié)構(gòu)體的mFormatID字段中指定格式時(shí)涩咖,音頻隊(duì)列使用適當(dāng)?shù)木幗獯a器。 然后指定采樣率和通道數(shù)繁莹,這就是它的全部檩互。 您將看到在Recording AudioPlaying Audio中設(shè)置音頻數(shù)據(jù)格式的示例。

錄制音頻隊(duì)列使用已安裝的編解碼器咨演,如圖1-5所示闸昨。

Figure 1-5 Audio format conversion during recording

在圖1-5的第1步中,你的應(yīng)用程序告訴一個(gè)音頻隊(duì)列開始記錄薄风,并告訴它要使用的數(shù)據(jù)格式饵较。 在步驟2中,音頻隊(duì)列獲取新的音頻數(shù)據(jù)遭赂,并使用編解碼器根據(jù)您指定的格式進(jìn)行轉(zhuǎn)換循诉。 音頻隊(duì)列然后調(diào)用回調(diào)函數(shù),將緩沖區(qū)中包含適當(dāng)格式的音頻數(shù)據(jù)撇他。 在第3步中茄猫,您的回調(diào)會(huì)將格式化的音頻數(shù)據(jù)寫入磁盤。 同樣逆粹,你的回調(diào)不需要知道數(shù)據(jù)格式募疮。

播放音頻隊(duì)列使用已安裝的編解碼器,如圖1-6所示僻弹。

Figure 1-6 Audio format conversion during playback

在圖1-6的第1步中,你的應(yīng)用程序通知一個(gè)音頻隊(duì)列開始播放他嚷,并且還告訴它要播放的音頻文件中包含的數(shù)據(jù)格式蹋绽。在步驟2中芭毙,音頻隊(duì)列調(diào)用您的回調(diào),它從音頻文件中讀取數(shù)據(jù)卸耘⊥硕兀回調(diào)將原始格式的數(shù)據(jù)轉(zhuǎn)交給音頻隊(duì)列。在步驟3中蚣抗,音頻隊(duì)列使用適當(dāng)?shù)木幗獯a器侈百,然后將音頻發(fā)送到目的地。

音頻隊(duì)列可以使用任何已安裝的編解碼器翰铡,無(wú)論是原生的Mac OS X還是由第三方提供钝域。要指定要使用的編解碼器,請(qǐng)將其四個(gè)字符的編碼ID提供給音頻隊(duì)列的AudioStreamBasicDescription結(jié)構(gòu)锭魔。您將在Recording Audio中看到這個(gè)例子例证。

Mac OS X包含各種各樣的音頻編碼解碼器,如CoreAudioTypes.h頭文件中的格式ID枚舉所示迷捧,以及 Core Audio Data Types Reference中所述织咧。您可以使用Audio Toolbox Framework中的AudioFormat.h頭文件中的接口來(lái)確定系統(tǒng)上可用的編解碼器。您可以使用Fiendishthngs應(yīng)用程序在系統(tǒng)上顯示編解碼器漠秋,可在http://developer.apple.com/samplecode/Fiendishthngs/上以示例代碼的形式獲得笙蒙。


Audio Queue Control and State - 音頻隊(duì)列控制和狀態(tài)

音頻隊(duì)列在創(chuàng)建和銷毀之間有一個(gè)生命周期。你的應(yīng)用程序管理這個(gè)生命周期庆锦,并使用AudioQueue.h頭文件中聲明的六個(gè)函數(shù)來(lái)控制音頻隊(duì)列的狀態(tài):

  • StartAudioQueueStart)手趣。調(diào)用開始錄制或播放。
  • PrimeAudioQueuePrime)肥荔。要進(jìn)行播放绿渣,請(qǐng)?jiān)谡{(diào)用AudioQueueStart之前調(diào)用,以確保立即有數(shù)據(jù)可供音頻隊(duì)列播放燕耿。此功能與錄音無(wú)關(guān)中符。
  • StopAudioQueueStop)。調(diào)用以重置音頻隊(duì)列(請(qǐng)參閱下面的說(shuō)明AudioQueueReset)誉帅,然后停止錄制或播放淀散。播放音頻隊(duì)列回調(diào)callback在沒有更多數(shù)據(jù)播放時(shí)調(diào)用此函數(shù)。
  • PauseAudioQueuePause)蚜锨。調(diào)用暫停錄音或播放而不影響緩沖區(qū)或重置音頻隊(duì)列档插。要恢復(fù),請(qǐng)調(diào)用AudioQueueStart函數(shù)亚再。
  • FlushAudioQueueFlush)郭膛。排隊(duì)最后一個(gè)音頻隊(duì)列緩沖區(qū)后調(diào)用,以確保所有緩沖的數(shù)據(jù)以及處理過(guò)程中的所有音頻數(shù)據(jù)都被記錄或播放氛悬。
  • ResetAudioQueueReset)则剃。調(diào)用立即靜音音頻隊(duì)列耘柱,刪除以前計(jì)劃使用的所有緩沖區(qū),并重置所有解碼器和DSP狀態(tài)棍现。

您可以在同步或異步模式下使用AudioQueueStop功能:

  • Synchronous调煎,停止立即發(fā)生,不考慮以前緩沖的音頻數(shù)據(jù)己肮。
  • Asynchronous士袄,在所有排隊(duì)的緩沖區(qū)被播放或記錄之后發(fā)生異步停止。

有關(guān)每個(gè)功能的完整說(shuō)明谎僻,請(qǐng)參閱Audio Queue Services Reference娄柳,其中包括關(guān)于音頻隊(duì)列的同步停止和異步停止的更多信息。


Audio Queue Parameters - 音頻隊(duì)列參數(shù)

音頻隊(duì)列具有可調(diào)參數(shù)設(shè)置稱為parameters戈稿。每個(gè)參數(shù)都有一個(gè)枚舉常量作為鍵西土,一個(gè)浮點(diǎn)數(shù)作為其值。參數(shù)通常用于回放鞍盗,而不是記錄需了。

在Mac OS X v10.5中,唯一可用的音頻隊(duì)列參數(shù)用于增益般甲。此參數(shù)的值是使用kAudioQueueParam_Volume常量設(shè)置或檢索的肋乍,其可用范圍從0.0到單位增益為1.0。

您的應(yīng)用程序可以通過(guò)兩種方式設(shè)置音頻隊(duì)列參數(shù)

  • 每個(gè)音頻隊(duì)列Per audio queue敷存,使用AudioQueueSetParameter函數(shù)墓造。這使您可以直接更改音頻隊(duì)列的設(shè)置。這些變化立即生效锚烦。
  • 每個(gè)音頻隊(duì)列緩沖區(qū)Per audio queue buffer觅闽,使用AudioQueueEnqueueBufferWithParameters函數(shù)。這使您可以分配音頻隊(duì)列設(shè)置涮俄,實(shí)際上蛉拙,您在排入音頻隊(duì)列緩沖區(qū)時(shí)會(huì)將其設(shè)置為音頻隊(duì)列緩沖區(qū)。音頻隊(duì)列緩沖區(qū)開始播放時(shí)彻亲,這些更改才會(huì)生效孕锄。

在這兩種情況下,音頻隊(duì)列的參數(shù)設(shè)置都會(huì)一直有效苞尝,直到您更改它們畸肆。

您可以隨時(shí)使用AudioQueueGetParameter函數(shù)訪問(wèn)音頻隊(duì)列的當(dāng)前參數(shù)值。有關(guān)獲取和設(shè)置參數(shù)值的函數(shù)的完整說(shuō)明宙址,請(qǐng)參閱Audio Queue Services Reference轴脐。

后記

未完,待續(xù)~~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市豁辉,隨后出現(xiàn)的幾起案子令野,更是在濱河造成了極大的恐慌舀患,老刑警劉巖徽级,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異聊浅,居然都是意外死亡餐抢,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門低匙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)旷痕,“玉大人,你說(shuō)我怎么就攤上這事顽冶∑劭梗” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵强重,是天一觀的道長(zhǎng)绞呈。 經(jīng)常有香客問(wèn)我,道長(zhǎng)间景,這世上最難降的妖魔是什么佃声? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮倘要,結(jié)果婚禮上圾亏,老公的妹妹穿的比我還像新娘。我一直安慰自己封拧,他們只是感情好志鹃,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著泽西,像睡著了一般曹铃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上尝苇,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天铛只,我揣著相機(jī)與錄音,去河邊找鬼糠溜。 笑死淳玩,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的非竿。 我是一名探鬼主播蜕着,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了承匣?” 一聲冷哼從身側(cè)響起蓖乘,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎韧骗,沒想到半個(gè)月后嘉抒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡袍暴,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年些侍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片政模。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡岗宣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出淋样,到底是詐尸還是另有隱情耗式,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布趁猴,位于F島的核電站刊咳,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏躲叼。R本人自食惡果不足惜芦缰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望枫慷。 院中可真熱鬧让蕾,春花似錦、人聲如沸或听。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)誉裆。三九已至顿颅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間足丢,已是汗流浹背粱腻。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留斩跌,地道東北人绍些。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像耀鸦,于是被迫代替她去往敵國(guó)和親柬批。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容