Core Audio
Core Audio提供了數(shù)字音頻服務(wù)為iOS與OS X, 它提供了一系列框架去處理音頻.
Core Audio中包含我們最常用的Audio Toolbox與Audio Unit框架.
- 使用Audio Queue做錄制,播放,暫停,循環(huán)與同步音頻
- 使用Audio File, Converter, Codec Services去從磁盤讀取與寫入以及執(zhí)行音頻轉(zhuǎn)換等功能.
- 使用Audio Unit與Audio Processing Graph在應(yīng)用程序中管理音頻單元.在OS X中可以自定義audio units.
- 使用Music Sequencing Services播放基于MIDI控制的音頻數(shù)據(jù)
- 使用Core Audio Clock Services用于音頻和MIDI同步以及時(shí)間格式管理
- 使用System Sound Services播放系統(tǒng)聲音與界面的音效.
Core Audio在iOS中針對移動(dòng)平臺的計(jì)算資源作出了優(yōu)化,同時(shí),音頻服務(wù)必須嚴(yán)格由系統(tǒng)進(jìn)行管理,特別是HAL與I/O Kit,然而Apple也提供了只在iOS平臺中才有的服務(wù),如Audio Session Service將幫助我們管理音頻上下文.
1. Digital Audio與Linear PCM
PCM是最常用的無損壓縮數(shù)字音頻格式數(shù)據(jù),根據(jù)采樣率以規(guī)則間隔測量模擬(真實(shí)世界)數(shù)字音頻信號并將每個(gè)采集到的樣本轉(zhuǎn)換為數(shù)值來創(chuàng)建PCM數(shù)據(jù).如標(biāo)準(zhǔn)光盤(CD)音頻使用44.1 kHz的采樣率,16位整數(shù)描述每個(gè)樣本 - 構(gòu)成分辨率或位深度。
- sample:一個(gè)采樣點(diǎn)是對單聲道采集到聲音的數(shù)值
- frame:一幀數(shù)據(jù)是一組時(shí)間一致的samples,如雙聲道聲音文件中一幀有兩個(gè)samples,一個(gè)左聲道,一個(gè)右聲道.
- packet:一個(gè)或多個(gè)連續(xù)幀的集合.在線性PCM中,一個(gè)packet總是單幀.在其他壓縮格式中,一個(gè)packet定義給定音頻數(shù)據(jù)格式的最小有意義的幀組蔼两。
iOS中使用integer與fixed-point音頻數(shù)據(jù),目的是在處理音頻數(shù)據(jù)時(shí)增加計(jì)算速度,減小電池能耗.iOS也提供了來自Audio Converter Services的Converter audio unit服務(wù).
iOS與OS X中,Core Audio提供了最常用的文件格式用于存儲域播放音頻數(shù)據(jù).
2.Audio Unit
Apple針對移動(dòng)平臺對iOS的Audio Unit作出了效率與性能優(yōu)化,在開發(fā)中我們必須將audio unit靜態(tài)編譯進(jìn)APP,所以無法使用別的APP中的Audio Unit.
3.HAL(Hardware Abstraction Layer)
大多情況下,我們無法直接與HAL進(jìn)行交互,Apple提供了一個(gè)特別的audio unit,即OS X中的AUHAL, iOS中的AURemoteIO, 我們可以通過它們讓音頻與硬件交互.
4.Properties, Scopes, and Elements
Core Audio接口中使用property管理對象的行為與狀態(tài).
- 屬性通常用易記憶的關(guān)鍵字格式,如kAudioFilePropertyFileFormat or kAudioQueueDeviceProperty_NumberChannels.
- 屬性值適用于特定的數(shù)據(jù)類型,如void*, Float64, AudioChannelLayout...
- Core Audio對象有一個(gè)內(nèi)部結(jié)構(gòu),其中每一部分都有屬于自己的屬性,如一個(gè)audio unit對象都有一個(gè)input scope, output scope, global scope. 每個(gè)scope由一個(gè)或多個(gè)elements(類似于音頻總線)組成.
5.回調(diào)函數(shù)
Core Audio中常用回調(diào)函數(shù)以實(shí)現(xiàn)音頻數(shù)據(jù)通信,回調(diào)函數(shù)常有一下功能
- 提供給應(yīng)用程序音頻數(shù)據(jù)(如:用麥克風(fēng)進(jìn)行錄制,將麥克風(fēng)采集的數(shù)據(jù)通過回調(diào)函數(shù)傳給使用者)
- 從應(yīng)用程序中請求音頻數(shù)據(jù)(如:播放回調(diào))
- 監(jiān)聽某個(gè)對象狀態(tài)的變化
為了去使用回調(diào)函數(shù),我們需要做以下兩件事情
- 注冊回調(diào)函數(shù)(如實(shí)現(xiàn)錄制,播放回調(diào),需要我們在初始化時(shí)提供一個(gè)函數(shù))
- 實(shí)現(xiàn)回調(diào)函數(shù)的功能.(實(shí)現(xiàn)初始化時(shí)提供的函數(shù))
Note: 在OC中,回調(diào)函數(shù)是一個(gè)C語言形式的函數(shù),我們回調(diào)OC本類對象作為對象傳入其中, 所以回調(diào)函數(shù)中不能直接引用
self.xxx
,需要借助傳入的OC對象去實(shí)現(xiàn)本類的功能.
6. 音頻數(shù)據(jù)格式
Core Audio封裝了音頻數(shù)據(jù)格式侵浸,我們只需要對給定結(jié)構(gòu)體賦正確的參數(shù)即可铜犬。
struct AudioStreamBasicDescription {
Float64 mSampleRate;
UInt32 mFormatID;
UInt32 mFormatFlags;
UInt32 mBytesPerPacket;
UInt32 mFramesPerPacket;
UInt32 mBytesPerFrame;
UInt32 mChannelsPerFrame;
UInt32 mBitsPerChannel;
UInt32 mReserved;
};
typedef struct AudioStreamBasicDescription AudioStreamBasicDescription;
struct AudioStreamPacketDescription {
SInt64 mStartOffset;
UInt32 mVariableFramesInPacket;
UInt32 mDataByteSize;
};
typedef struct AudioStreamPacketDescription AudioStreamPacketDescription;
注意匣掸,上面結(jié)構(gòu)體中mReserved
是Apple的保留參數(shù)鸭叙,必須為0. 其他一些參數(shù)在特定情況下也需為0霹娄,如:壓縮音頻格式每個(gè)sample使用不同數(shù)量的bits能犯。對于這些格式鲫骗,mBitsPerChannel成員的值為0。
- 為AudioStreamBasicDescription賦值
你可以手動(dòng)為ASBD的成員賦值踩晶,如果有些值是你不知道的执泰,可以賦0,Core Audio將自動(dòng)選擇適當(dāng)?shù)闹怠?/p>
- 標(biāo)準(zhǔn)的音頻數(shù)據(jù)格式
iOS: 線性PCM 16bit integer, Noninterleaved linear PCM 8.24bit 定點(diǎn)samples
struct AudioStreamBasicDescription {
mSampleRate = 44100.0;
mFormatID = kAudioFormatLinearPCM;
mFormatFlags = kAudioFormatFlagsAudioUnitCanonical;
mBitsPerChannel = 8 * sizeof (AudioUnitSampleType); // 32 bits
mChannelsPerFrame = 2;
mBytesPerFrame = mChannelsPerFrame * sizeof (AudioUnitSampleType); // 8 bytes
mFramesPerPacket = 1;
mBytesPerPacket = mFramesPerPacket * mBytesPerFrame; // 8 bytes
mReserved = 0;
};
7. Magic Cookie
在Core Audio中渡蜻,magic cookie表示被附加到壓縮音頻數(shù)據(jù)(文件或流)中的元數(shù)據(jù)(metadata)术吝。元數(shù)據(jù)為解碼器提供了正確解碼文件或流所需要的詳細(xì)信息。Core Audio可以復(fù)制茸苇,讀取排苍,使用元數(shù)據(jù)包含的信息。
下面的例子展示了如何將一個(gè)文件中magic cookie拷貝提供給audio queue.
- (void) copyMagicCookieToQueue: (AudioQueueRef) queue fromFile: (AudioFileID) file {
UInt32 propertySize = sizeof (UInt32);
OSStatus result = AudioFileGetPropertyInfo (
file,
kAudioFilePropertyMagicCookieData,
&propertySize,
NULL
);
if (!result && propertySize) {
char *cookie = (char *) malloc (propertySize);
AudioFileGetProperty (
file,
kAudioFilePropertyMagicCookieData,
&propertySize,
cookie
);
AudioQueueSetProperty (
queue,
kAudioQueueProperty_MagicCookie,
cookie,
propertySize
);
free (cookie);
}
}
8.Audio Data Packets
音頻數(shù)據(jù)包(packet)是一個(gè)或多個(gè)幀的集合学密,對于特定音頻格式淘衙,它是有意義的最小幀集合,因此它是最佳表示一段時(shí)間音頻數(shù)據(jù)的單位腻暮。
- CBR(固定的比特率):PCM,IMA,ADPCM,所有packet具有相同size.
- VBR(可變的比特率):AAC,MP3,Apple Lossless,所有packet都具有相同的幀數(shù)彤守,但是每一幀中的位數(shù)不同。
- VFR(可變的幀率): 每個(gè)包中具有不同的幀數(shù)哭靖,沒有這種類型常用的格式具垫。
在CBR,VBR的格式中试幽,對于給定的音頻文件或流筝蚕,每秒鐘的包數(shù)是固定的,
9.數(shù)據(jù)格式轉(zhuǎn)換
使用audio converter可以改變音頻采樣率铺坞,交錯(cuò)或不交錯(cuò)起宽,以及壓縮與未壓縮數(shù)據(jù)格式相互轉(zhuǎn)換。
- 將壓縮數(shù)據(jù)格式(如AAC)轉(zhuǎn)成線性PCM格式
- 將線性PCM格式轉(zhuǎn)成其他格式
- 在16位signed integer線性PCM與8.24定點(diǎn)PCM間相互轉(zhuǎn)換康震。
10.音頻文件
Core Audio中使用Audio File Service為創(chuàng)建與訪問音頻文件及包含在其中元數(shù)據(jù)提供了一個(gè)強(qiáng)大的抽象燎含。我們不僅可以使用文件的ID,type,數(shù)據(jù)格式,還可以添加標(biāo)記腿短,循環(huán),回放等等功能绘梦。
- 創(chuàng)建一個(gè)音頻文件
- 確定文件路徑(CFURL/NSURL)
- 確定文件標(biāo)識符(ex CAF:kAudioFileCAFType)
- 放在文件中的ABSD橘忱。
AudioFileCreateWithURL (
audioFileURL,
kAudioFileCAFType,
&audioFormat,
kAudioFileFlags_EraseFile,
&audioFileID // the function provides the new file object here
);
- 打開一個(gè)音頻文件
使用AudioFileOpenURL
函數(shù)打開一個(gè)文件,提供URL,文件類型卸奉,訪問權(quán)限成功后返回一個(gè)文件ID,使用這個(gè)ID以及常用函數(shù)可以檢索我們需要的文件信息钝诚。下面列舉了一些常用函數(shù)
kAudioFilePropertyFileFormat
kAudioFilePropertyDataFormat
kAudioFilePropertyMagicCookieData
kAudioFilePropertyChannelLayout
當(dāng)一個(gè)VBR文件過大時(shí),檢索信息速度會較慢榄棵,可以使用kAudioFilePropertyPacketSizeUpperBound and kAudioFilePropertyEstimatedDuration.
這兩個(gè)函數(shù)快速獲取近似值凝颇。
-
讀寫文件
- 讀寫包僅僅針對VBR數(shù)據(jù)
- 使用基于包的操作更容易計(jì)算時(shí)間
擴(kuò)展
Core Audio提供了一個(gè)的API潘拱,稱為擴(kuò)展音頻文件服務(wù)。該接口包含音頻文件服務(wù)和音頻轉(zhuǎn)換器服務(wù)中的基本功能拧略,提供與線性PCM之間的自動(dòng)數(shù)據(jù)轉(zhuǎn)換iPhone 支持的Audio file格式
Format name | Format filename extensions |
---|---|
AIFF | .aif,.aiff |
CAF | .caf |
MPEG-1,layer 3 | .mp3 |
MPEG-2 or MPEG-4 ADTS | .aac |
MPEG-4 | .m4a, .mp4 |
WAV | .wav |
AC-3 (Dolby Digital) | .ac3 |
Enhanced AC-3 (Dolby Digital Plus) | .ec3 |
iOS與OS X中原生音頻文件格式為CAF(Core Audio Format),它可以支持平臺中任意音頻數(shù)據(jù)格式芦岂。它沒有大小限制,可以支持多種元數(shù)據(jù)垫蛆,如聲道信息禽最,文本注釋等
11.音頻流
與音頻文件不同,我們無法確定一個(gè)audio file stream(音頻流)的開始與結(jié)束點(diǎn).因?yàn)槲覀兺峭ㄟ^網(wǎng)絡(luò)接受音頻流數(shù)據(jù),開始與結(jié)束的時(shí)機(jī)取決于用戶的交互,并且,音頻流數(shù)據(jù)也無法保證一定可以獲取,因?yàn)榫W(wǎng)絡(luò)傳輸中可能會存儲在丟幀,暫停等等情況.
Audio File Service可以通過解析(parse)讓我們使用音頻流.通過回調(diào)函數(shù)獲取parse到的一系列音頻數(shù)據(jù).
12.Audio Sessions: 配合Core Audio工作
在iOS中,有時(shí)我們需要處理高優(yōu)先級任務(wù),如接電話,如果當(dāng)前APP正在播放視頻,我們必須做出符合用戶期望的事情以協(xié)調(diào)APP與系統(tǒng)電話.Audio Session對象充當(dāng)了兩者之間的一個(gè)中介.每個(gè)iPhone應(yīng)用程序只有一個(gè)audio session,通過配置其屬性以使用.
開始之前,我們要明確下面幾個(gè)問題
- 如何讓應(yīng)用程序響應(yīng)一些意外中斷,如接電話
- 你打算讓你的音頻與其他應(yīng)用程序中的音頻混合起來,還是打算對它們做靜音操作
- 應(yīng)用程序如何響應(yīng)音頻線路改變,如用戶插拔耳機(jī)
為了解決上面的問題,我們需要配置audio session使用如下特性
Audio Session feature | Description |
---|---|
Categories | 一個(gè)category標(biāo)識著一組音頻行為的鍵,通過設(shè)置分類,可以表明音頻的行為,如鎖屏?xí)r是否應(yīng)該繼續(xù)播放音頻. |
Interruptions and route changes | 當(dāng)音頻被中斷或音頻線路發(fā)生改變時(shí),audio session將發(fā)送一個(gè)通知,通過接收通知以作出相應(yīng)響應(yīng). |
Hardware characteristics | 通過audio session可以查詢當(dāng)前設(shè)備的一些硬件信息,如采樣率,聲道數(shù),輸入源設(shè)備等 |
- Audio Session默認(rèn)行為
- 當(dāng)用戶將手機(jī)按鍵中的靜音撥動(dòng)時(shí),音頻將會被靜音
- 當(dāng)用戶按下鎖屏鍵時(shí),音頻會被靜音
- 當(dāng)你的音頻啟用時(shí),當(dāng)前正在播放的其他應(yīng)用程序的音頻會被靜音
以上行為是audio session默認(rèn)分類(kAudioSessionCategory_SoloAmbientSound)的行為
- 中斷:停用與激活(Deactivation and Activation)
默認(rèn)的audio session中缺少一個(gè)重要功能就是在中斷后無法恢復(fù).audio session有兩個(gè)重要狀態(tài):激活,停用.音頻僅能夠在激活狀態(tài)下使用.
啟動(dòng)時(shí),默認(rèn)的audio session是激活狀態(tài),然而,如果有電話打進(jìn)來(interruption),audio session馬上處于停用狀態(tài)且應(yīng)用程序音頻停止.如果用戶選擇忽略當(dāng)前電話,你的應(yīng)用程序繼續(xù)運(yùn)行,但是audio session仍是未激活狀態(tài),音頻無法繼續(xù)工作.
如果應(yīng)用程序中使用OpenAL, I/O unit, Audio Queue Services,我們必須寫一個(gè)監(jiān)聽中斷的回調(diào)函數(shù),在中斷結(jié)束后重新激活audio session.
- 決定輸入源是否可用
使用錄制功能的APP是否能錄制取決于當(dāng)前選擇的硬件音頻輸入端,使用kAudioSessionProperty_AudioInputAvailable
可以測試當(dāng)前輸入端是否可用
UInt32 audioInputIsAvailable;
UInt32 propertySize = sizeof (audioInputIsAvailable);
AudioSessionGetProperty (
kAudioSessionProperty_AudioInputAvailable,
&propertySize,
&audioInputIsAvailable // A nonzero value on output means that
// audio input is available
);
- 使用Audio Session
應(yīng)用程序僅有一個(gè)audio session分類在同一時(shí)間(此規(guī)則的一個(gè)例外是使用System Sound Services播放的音頻 - 用于警報(bào)和用戶界面聲音效果的API。此類音頻始終使用最低優(yōu)先級的音頻會話類別),
13.使用AVAudioPlayer播放
如果你的應(yīng)用程序不需要雙聲道,精確同步以及播放網(wǎng)絡(luò)流音頻,可以使用AVAudioPlayer
類實(shí)現(xiàn)簡單的音頻播放.
以下使用范圍
- 播放任意時(shí)間段音頻
- 從文件或內(nèi)存中播放音頻
- 循環(huán)音頻
- 同時(shí)播放多個(gè)音頻
- 控制正在播放每個(gè)聲音相對播放水平
- 尋找音頻文件中特定點(diǎn),支持快進(jìn)快退
- 獲取音量
NSString *soundFilePath =
[[NSBundle mainBundle] pathForResource: @"sound"
ofType: @"wav"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];
AVAudioPlayer *newPlayer =
[[AVAudioPlayer alloc] initWithContentsOfURL: fileURL
error: nil];
[fileURL release];
self.player = newPlayer;
[newPlayer release];
[self.player prepareToPlay];
[self.player setDelegate: self];
- (void) audioPlayerDidFinishPlaying: (AVAudioPlayer *) player
successfully: (BOOL) flag {
if (flag == YES) {
[self.button setTitle: @"Play" forState: UIControlStateNormal];
}
}
- (IBAction) playOrPause: (id) sender {
// if already playing, then pause
if (self.player.playing) {
[self.button setTitle: @"Play" forState: UIControlStateHighlighted];
[self.button setTitle: @"Play" forState: UIControlStateNormal];
[self.player pause];
// if stopped or paused, start playing
} else {
[self.button setTitle: @"Pause" forState: UIControlStateHighlighted];
[self.button setTitle: @"Pause" forState: UIControlStateNormal];
[self.player play];
}
[self.player setVolume: 1.0]; // available range is 0.0 through 1.0
14.錄制與播放 Audio Queue Services
Audio Queue Services提供了一種低開銷,直接的方式去錄制和播放音頻,它使你的應(yīng)用程序使用硬件(麥克風(fēng)與揚(yáng)聲器)錄制與播放并且無需了解硬件接口.它也讓我們使用復(fù)雜的編解碼器而無需了解編解碼器的工作原理.
Audio Queue提供了更精確的定時(shí)播放以支持預(yù)定播放與同步,你可以使用它去同步多個(gè)音頻播放隊(duì)列,同時(shí)播放聲音,獨(dú)立控制每個(gè)隊(duì)里的音量以及循環(huán)播放.
Audio Queue與AVAudioPlayer兩者是在iPhone上播放音頻的唯一方式
- 錄制與播放的回調(diào)函數(shù)
通過屬性與回調(diào)函數(shù)讓我們與audio queue對象間交互.對于錄制,我們通過回調(diào)函數(shù)接收音頻數(shù)據(jù).
對于播放回調(diào),當(dāng)你的音頻播放隊(duì)列需要播放一個(gè)音頻數(shù)據(jù)時(shí)它將被調(diào)用.你的回調(diào)函數(shù)將從磁盤讀取指定數(shù)量的音頻數(shù)據(jù)包然后將它們封裝在audio queue對象的buffer中.audio queue將按順序播放這些buffer.
- 創(chuàng)建Audio Queue
- AudioQueueNewInput:創(chuàng)建錄制audio queue對象
- AudioQueueNewOutput: 創(chuàng)建播放audio queue對象
實(shí)現(xiàn)一個(gè)播放隊(duì)列
a. 創(chuàng)建一個(gè)結(jié)構(gòu)體管理audio queue需要的信息,如音頻格式,采樣率等等
b. 定義一個(gè)回調(diào)函數(shù)管理audio queue buffers,這個(gè)回調(diào)函數(shù)使用Audio File Services去讀取你想要播放的文件.
c. 初始化audio queue并且使用AudioQueueNewOutput創(chuàng)建對象.
static const int kNumberBuffers = 3;
// Create a data structure to manage information needed by the audio queue
struct myAQStruct {
AudioFileID mAudioFile;
CAStreamBasicDescription mDataFormat;
AudioQueueRef mQueue;
AudioQueueBufferRef mBuffers[kNumberBuffers];
SInt64 mCurrentPacket;
UInt32 mNumPacketsToRead;
AudioStreamPacketDescription *mPacketDescs;
bool mDone;
};
// Define a playback audio queue callback function
static void AQTestBufferCallback(
void *inUserData,
AudioQueueRef inAQ,
AudioQueueBufferRef inCompleteAQBuffer
) {
myAQStruct *myInfo = (myAQStruct *)inUserData;
if (myInfo->mDone) return;
UInt32 numBytes;
UInt32 nPackets = myInfo->mNumPacketsToRead;
AudioFileReadPackets (
myInfo->mAudioFile,
false,
&numBytes,
myInfo->mPacketDescs,
myInfo->mCurrentPacket,
&nPackets,
inCompleteAQBuffer->mAudioData
);
if (nPackets > 0) {
inCompleteAQBuffer->mAudioDataByteSize = numBytes;
AudioQueueEnqueueBuffer (
inAQ,
inCompleteAQBuffer,
(myInfo->mPacketDescs ? nPackets : 0),
myInfo->mPacketDescs
);
myInfo->mCurrentPacket += nPackets;
} else {
AudioQueueStop (
myInfo->mQueue,
false
);
myInfo->mDone = true;
}
}
// Instantiate an audio queue object
AudioQueueNewOutput (
&myInfo.mDataFormat,
AQTestBufferCallback,
&myInfo,
CFRunLoopGetCurrent(),
kCFRunLoopCommonModes,
0,
&myInfo.mQueue
);
- 控制Audio Queue播放的音量
Audio queue對象提供了兩種方式控制播放音量,一種是直接設(shè)置,如下,設(shè)置后可以立即生效.
Float32 volume = 1;
AudioQueueSetParameter (
myAQstruct.audioQueueObject,
kAudioQueueParam_Volume,
volume
);
另一種是使用AudioQueueEnqueueBufferWithParameters
,設(shè)置后在audio queue buffer開始播放時(shí)生效.
- Indicating Audio Queue Playback Level
通過查詢audio queue對象的kAudioQueueProperty_CurrentLevelMeterDB
屬性可以獲取當(dāng)前播放的級別.
typedef struct AudioQueueLevelMeterState {
Float32 mAveragePower;
Float32 mPeakPower;
}; AudioQueueLevelMeterState;
- 同時(shí)播放多個(gè)聲音
為了同時(shí)播放多個(gè)音頻,需要為每個(gè)音頻創(chuàng)建一個(gè)播放audio queue對象.對于每個(gè)audio queue,使用AudioQueueEnqueueBufferWithParameters
函數(shù)安排第一個(gè)音頻buffer同時(shí)啟動(dòng)袱饭。
同時(shí)播放多個(gè)音頻,音頻格式顯得至關(guān)重要,因?yàn)閕OS中某些音頻格式使用了高效的硬件編解碼器,只能在設(shè)備上播放以下格式之一的單個(gè)實(shí)例.
a. AAC
b. ALAC
c. MP3
如果要播放高質(zhì)量同步的音頻,需要使用線性PCM或IMA4格式.
a. 線性PCM和IMA / ADPCM(IMA4)音頻您可以在iOS中同時(shí)播放多個(gè)線性PCM或IMA4格式聲音川无,而不會產(chǎn)生CPU資源問題。
b. AAC虑乖,MP3和Apple Lossless(ALAC)一次只能播放一首此類聲音
15.使用OpenAL定位播放
開源的OpenAL音頻API(可在OpenAL框架中使用懦趋,構(gòu)建于Core Audio之上)針對播放期間的聲音定位進(jìn)行了優(yōu)化。使用OpenGL建模的界面疹味,OpenAL可以輕松播放愕够,定位,混合和移動(dòng)聲音,OpenAL和OpenGL共享一個(gè)通用坐標(biāo)系統(tǒng)佛猛,使您可以同步音頻和視頻惑芭。OpenAL直接使用Core Audio的I / O audio unit),從而實(shí)現(xiàn)最低延遲播放继找。OpenAL是在iPhone和iPod touch上播放游戲應(yīng)用中的聲音效果的最佳選擇遂跟。
16.系統(tǒng)聲音
Audio Toolbox中的AudioServices.h提供了系統(tǒng)的聲音服務(wù),當(dāng)你僅僅想播放一個(gè)系統(tǒng)的短音頻時(shí),它將是最好的選擇,iOS中播放系統(tǒng)聲音最不不能超過30秒.
在iOS中,調(diào)用AudioServicesPlaySystemSound
可以立即播放,你也可以調(diào)用AudioServicesPlayAlertSound
提示用戶是否播放.
調(diào)用AudioServicesPlaySystemSound
時(shí)使用kSystemSoundID_Vibrate
常量可以顯式設(shè)置振動(dòng)效果.
#include <AudioToolbox/AudioToolbox.h>
#include <CoreFoundation/CoreFoundation.h>
// Define a callback to be called when the sound is finished
// playing. Useful when you need to free memory after playing.
static void MyCompletionCallback (
SystemSoundID mySSID,
void * myURLRef
) {
AudioServicesDisposeSystemSoundID (mySSID);
CFRelease (myURLRef);
CFRunLoopStop (CFRunLoopGetCurrent());
}
int main (int argc, const char * argv[]) {
// Set up the pieces needed to play a sound.
SystemSoundID mySSID;
CFURLRef myURLRef;
myURLRef = CFURLCreateWithFileSystemPath (
kCFAllocatorDefault,
CFSTR ("../../ComedyHorns.aif"),
kCFURLPOSIXPathStyle,
FALSE
);
// create a system sound ID to represent the sound file
OSStatus error = AudioServicesCreateSystemSoundID (myURLRef, &mySSID);
// Register the sound completion callback.
// Again, useful when you need to free memory after playing.
AudioServicesAddSystemSoundCompletion (
mySSID,
NULL,
NULL,
MyCompletionCallback,
(void *) myURLRef
);
// Play the sound file.
AudioServicesPlaySystemSound (mySSID);
// Invoke a run loop on the current thread to keep the application
// running long enough for the sound to play; the sound completion
// callback later stops this run loop.
CFRunLoopRun ();
return 0;
}
17.Audio Unit
在iOS中,Audio Unit為應(yīng)用程序提供了實(shí)現(xiàn)低延遲輸入和輸出的機(jī)制婴渡。它們還提供某些DSP功能.
iOS中Audio Unit輸入輸出使用8.24位定點(diǎn)線性PCM音頻數(shù)據(jù).唯一例外的是以下情況.
- 3D mix unit: 允許任意數(shù)量的單聲道輸入幻锁,每個(gè)輸入可以是8位或16位線性PCM.在8.24位定點(diǎn)PCM中提供一個(gè)立體聲輸出,3D混音器單元對其輸入執(zhí)行采樣率轉(zhuǎn)換,并對每個(gè)輸入通道提供大量控制边臼。此控件包括這些更改的音量哄尔,靜音,平移柠并,距離衰減和速率控制岭接。以編程方式,這是kAudioUnitSubType_AU3DMixerEmbedded單元臼予。
- Multichannel mixer unit: 允許任意數(shù)量的單聲道或立體聲輸入鸣戴,每個(gè)輸入可以是16位線性或8.24位定點(diǎn)PCM醋火。在8.24位定點(diǎn)PCM中提供一個(gè)立體聲輸出呵萨。您的應(yīng)用程序可以靜音和取消靜音每個(gè)輸入通道以及控制其音量。以編程方式木柬,這是kAudioUnitSubType_MultiChannelMixer單元缰雇。
- Converter unit: 提供采樣率入偷,位深度和位格式(線性到定點(diǎn))轉(zhuǎn)換追驴。 iPhone converter unit’s的規(guī)范數(shù)據(jù)格式是8.24位定點(diǎn)PCM。它轉(zhuǎn)換為此格式或從此格式轉(zhuǎn)換疏之。以編程方式殿雪,這是kAudioUnitSubType_AUConverter單元。
- I/O unit:提供實(shí)時(shí)音頻輸入和輸出体捏,并根據(jù)需要執(zhí)行采樣率轉(zhuǎn)換冠摄。以編程方式,這是kAudioUnitSubType_RemoteIO單元几缭。
- iPod EQ unit:提供可在應(yīng)用程序中使用的簡單均衡器河泳,并在內(nèi)置iPhone iPod應(yīng)用程序中提供相同的預(yù)設(shè)。 iPod EQ單元使用8.24位定點(diǎn)PCM輸入和輸出年栓。以編程方式拆挥,這是kAudioUnitSubType_AUiPodEQ單元。
每個(gè)Audio Unit的唯一標(biāo)識符由類型,子類型,制造商代碼(type, subtype, and manufacturer code)確定.每種子類型更加精確的描述了audio unit的用途.Audio Unit使用屬性配置音頻信息,如 Properties, Scopes, and Elements.每種audio unit需要一些指定屬性,
18.編解碼器
iOS中可以用的錄制和播放編解碼器來平衡音頻質(zhì)量某抓,應(yīng)用程序開發(fā)的靈活性纸兔,硬件功能和電池壽命。
19.Audio Processing Graphs
AUGraph:定義了一組復(fù)雜的音頻執(zhí)行任務(wù).