前段時(shí)間在閱讀蘋果音頻文檔(均列在參考資料一節(jié)里面了),并做了一些音頻相關(guān)的開發(fā)(主要是帶回音消除的錄音)。這里做一個(gè)總結(jié)。
主要從事網(wǎng)頁設(shè)計(jì)、PC網(wǎng)站建設(shè)(電腦版網(wǎng)站建設(shè))、wap網(wǎng)站建設(shè)(手機(jī)版網(wǎng)站建設(shè))、成都響應(yīng)式網(wǎng)站建設(shè)公司、程序開發(fā)、微網(wǎng)站、微信小程序等,憑借多年來在互聯(lián)網(wǎng)的打拼,我們在互聯(lián)網(wǎng)網(wǎng)站建設(shè)行業(yè)積累了豐富的成都做網(wǎng)站、成都網(wǎng)站制作、成都外貿(mào)網(wǎng)站建設(shè)、網(wǎng)絡(luò)營銷經(jīng)驗(yàn),集策劃、開發(fā)、設(shè)計(jì)、營銷、管理等多方位專業(yè)化運(yùn)作于一體,具備承接不同規(guī)模與類型的建設(shè)項(xiàng)目的能力。
每一個(gè) app 帶有一個(gè) AVAudioSession 的單例(也就是說正常情況下你無法獲得第二個(gè) AVAudioSession 實(shí)例)。iOS 系統(tǒng)上每個(gè) app 有各自不同的 AVAudioSession 實(shí)例。通過使用這個(gè)實(shí)例的方法可以告訴系統(tǒng)當(dāng)前的 app 是怎樣使用手機(jī)的音頻服務(wù)的,然后系統(tǒng)會(huì)根據(jù)每個(gè) app 的配置進(jìn)行相應(yīng)的協(xié)調(diào), 盡量 滿足所有 app 的請求,當(dāng)無法滿足的時(shí)候,系統(tǒng)盡量滿足前臺(tái) app 的要求或者系統(tǒng)電話服務(wù)等。比如說,如果當(dāng)前另外一個(gè) app 正在播放的話,當(dāng)前 app 可能希望能將其播放的音頻和其他 app 的音頻一起播放,而不是暫停其他 app 的音頻服務(wù);又比如說當(dāng)前 app 需要播放音頻或者進(jìn)行錄音;比如當(dāng)前 app 只是播放音頻;比如當(dāng)前 app 只是錄音;比如當(dāng)前 app 播放音頻時(shí)候屏蔽所有其他 app 的音頻等等,總之就是告訴系統(tǒng)當(dāng)前 app 是如何使用它的音頻服務(wù)的。
Audio Session 有三個(gè)比較重要的概念:
通過配置這三個(gè)內(nèi)容,表達(dá)了當(dāng)前 app 的使用音頻服務(wù)的具體意圖。
在某些情況下,我們不需要配置 Audio Session 的 category,比如如果使用 AVAudioRecorder 來錄音,并不需要配置 category 為 AVAudioSessionCategoryRecord ,因?yàn)橄到y(tǒng)在我們使用 AVAudioRecorder 的錄音服務(wù)的時(shí)候已經(jīng)為我們配置了。同時(shí) Audio Session 有默認(rèn)配置(如果當(dāng)前 app 不進(jìn)行配置的話)。當(dāng)默認(rèn)配置無法滿足需求的時(shí)候,就可以手動(dòng)配置 Audio Session
Audio Session 另一個(gè)重要功能是配置系統(tǒng)音頻服務(wù)硬件參數(shù),比如配置輸入的聲道數(shù),采樣率,IO 緩存時(shí)間等等。其 API 中 setPreferred__ 開頭的方法作用就是這些。
配置完 Audio Session 以后,當(dāng)我們要求的音頻服務(wù)受到打斷(比如,電話來了,則系統(tǒng)要停止錄音和播放;比如,app 退到后臺(tái)運(yùn)行了,如果沒有配置后臺(tái)運(yùn)行的話,系統(tǒng)也會(huì)停止當(dāng)前 app 的音頻服務(wù);),我們可以使用通知中心的方式來監(jiān)聽,并做一下相應(yīng)的處理。音頻服務(wù)中斷有兩個(gè)概念比較重要,就是中斷開始以及中斷結(jié)束,我們可以在中斷開始的時(shí)候記錄當(dāng)前播放時(shí)間點(diǎn),中斷結(jié)束的時(shí)候重新開始播放(當(dāng)然系統(tǒng)默認(rèn)行為是會(huì)在中斷結(jié)束時(shí)重新開始播放音頻,但是如果默認(rèn)行為無法滿足需求時(shí)候,就需要自行處理了)。
Audio Session 另一個(gè)重要我們需要監(jiān)聽的變化是路由變化 (Route Change)。比如有新的輸出源來了(比如用戶把耳機(jī)插進(jìn)去或者是用戶開始使用藍(lán)牙耳機(jī)),或者原來的輸出源不可用了(用戶拔掉耳機(jī)等)。
還有一些其他的功能,比如當(dāng)前其他 app 是否在播放音頻,請求麥克風(fēng)權(quán)限等,可以查看具體的 API 文檔 AVAudioSession 。
使用 Audio Queue Service 我們可以做到錄音或者播放音頻。當(dāng)然我們使用 AVAudioPlayer 也能很簡單的做播放音頻功能,那為什么要用到 Audio Queue Service 呢?它有幾個(gè)優(yōu)點(diǎn)
理解 Audio Queue Service 比較重要的是它的 buffer queue。拿錄音來說,一般設(shè)置的緩存是3個(gè)。首先通過 AudioQueueEnqueueBuffer 將可用緩存提供給相應(yīng)的 queue。然后系統(tǒng)開始將記錄下的音頻數(shù)據(jù)放到第一個(gè)緩存,當(dāng)緩存滿的時(shí)候,回調(diào)函數(shù)會(huì)將該 buffer 返回給你并將該緩存出列,在回調(diào)函數(shù)中我們可以對這些數(shù)據(jù)進(jìn)行處理,與此同時(shí)系統(tǒng)開始將數(shù)據(jù)寫到第二個(gè)緩存,當(dāng)我們的回調(diào)函數(shù)處理完第一個(gè)返回的緩存時(shí)候,我們需要重新使用 AudioQueueEnqueueBuffer 將該緩存入列,以便系統(tǒng)再次使用。當(dāng)?shù)诙€(gè)緩存返回的時(shí)候,系統(tǒng)開始往第三個(gè)緩存寫數(shù)據(jù),寫完之后返回第三個(gè)緩存,并開始往之前返回的第一個(gè)緩存寫數(shù)據(jù)。這就是一個(gè)典型的隊(duì)列結(jié)構(gòu)(先進(jìn)先出,后進(jìn)后出)。
Audio Unit 是所有 iOS 以及 macOS 上音頻框架的最底層,無論使用的是 AVAudioRecorder、AVAudioPlayer、或者 Audio Queue Service、OpenAL 等,最終底層實(shí)現(xiàn)都是通過 Audio Unit 來完成的。
在 iOS 上可用的 audio unit 是有限的,macOS 上面可以自定義一個(gè) audio unit 但是 iOS 上不行,只能使用系統(tǒng)提供的 audio unit。
什么時(shí)候使用 Audio Unit ?官方的說法是,當(dāng)你需要高度可控的、高性能、高靈活性或者需要某種特別的功能(比如回音消除,只在 audio unit 提供支持,所有高層 API 均不支持回音消除)的時(shí)候,才需要使用 audio unit。
有4類 audio unit(具體用途看名字就能理解):
使用 audio unit 有兩種方式:
第一種方式是對于比較簡單的結(jié)構(gòu)。
第二種方式是用于構(gòu)建復(fù)雜的音頻處理流程。配置具體的 audio unit 的屬性的時(shí)候還是會(huì)用到直接使用種的方法。
audio unit 重要的概念是 scope 和 element。scope 包含 element。
scope 分三種:
scope 概念有一點(diǎn)抽象,可以這樣理解 scope,比如 input scope 表示里面所有的 element 都需要一個(gè)輸入。output scope 表示里面所有的 element 都會(huì)輸出到某個(gè)地方。至于 global scope,應(yīng)該是用來配置一些和輸入輸出概念無關(guān)的屬性。
element 官方的解釋是可以理解成 bus,就是將數(shù)據(jù)從 element 的一頭傳到另一頭。
這里有些問題我也不知道如何解答,若有了解的,請多多指教一下。
我只知道一個(gè)lamemp3庫將PCM錄音數(shù)據(jù)壓縮為MP3格式的。
你可以百度“IOS 實(shí)現(xiàn)錄音PCM轉(zhuǎn)MP3格式” 第一個(gè)搜索結(jié)果就可以幫到你。
一、簡單介紹
簡單來說,音頻可以分為2種
(1)音效
又稱“短音頻”,通常在程序中的播放時(shí)長為1~2秒
在應(yīng)用程序中起到點(diǎn)綴效果,提升整體用戶體驗(yàn)
(2)音樂
比如游戲中的“背景音樂”,一般播放時(shí)間較長
框架:播放音頻需要用到AVFoundation.framework框架
二、音效的播放
1.獲得音效文件的路徑
復(fù)制代碼 代碼如下:
NSURL *url = [[NSBundle mainBundle] URLForResource:@"m_03.wav" withExtension:nil];
2.加載音效文件,得到對應(yīng)的音效ID
復(fù)制代碼 代碼如下:
SystemSoundID soundID = 0;
AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), soundID);
3.播放音效
復(fù)制代碼 代碼如下:
AudioServicesPlaySystemSound(soundID);
注意:音效文件只需要加載1次
4.音效播放常見函數(shù)總結(jié)
加載音效文件
復(fù)制代碼 代碼如下:
AudioServicesCreateSystemSoundID(CFURLRef inFileURL, SystemSoundID *outSystemSoundID)
釋放音效資源
復(fù)制代碼 代碼如下:
AudioServicesDisposeSystemSoundID(SystemSoundID inSystemSoundID)
播放音效
復(fù)制代碼 代碼如下:
AudioServicesPlaySystemSound(SystemSoundID inSystemSoundID)
播放音效帶點(diǎn)震動(dòng)
復(fù)制代碼 代碼如下:
AudioServicesPlayAlertSound(SystemSoundID inSystemSoundID)
三、程序示例
先導(dǎo)入需要依賴的框架
導(dǎo)入需要播放的音效文件素材
說明:AVFoundation.framework框架中的東西轉(zhuǎn)換為CF需要使用橋接。
代碼示例:
復(fù)制代碼 代碼如下:
YYViewController.m文件
//
// YYViewController.m
// 14-音效播放
//
// Created by apple on 14-8-8.
// Copyright (c) 2014年 yangyong. All rights reserved.
//
#import "YYViewController.h"
#import
@interface YYViewController ()
@end
復(fù)制代碼 代碼如下:
@implementation YYViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//1.獲得音效文件的全路徑
NSURL *url=[[NSBundle mainBundle]URLForResource:@"buyao.wav" withExtension:nil];
//2.加載音效文件,創(chuàng)建音效ID(SoundID,一個(gè)ID對應(yīng)一個(gè)音效文件)
SystemSoundID soundID=0;
AudioServicesCreateSystemSoundID((__bridge CFURLRef)url, soundID);
//把需要銷毀的音效文件的ID傳遞給它既可銷毀
//AudioServicesDisposeSystemSoundID(soundID);
//3.播放音效文件
//下面的兩個(gè)函數(shù)都可以用來播放音效文件,第一個(gè)函數(shù)伴隨有震動(dòng)效果
AudioServicesPlayAlertSound(soundID);
//AudioServicesPlaySystemSound(#systemsoundid)
}
@end
說明:點(diǎn)擊屏幕可以播放音效文件。
音樂的播放
一、簡單說明
音樂播放用到一個(gè)叫做AVAudioPlayer的`類,這個(gè)類可以用于播放手機(jī)本地的音樂文件。
注意:
(1)該類(AVAudioPlayer)只能用于播放本地音頻。
(2)時(shí)間比較短的(稱之為音效)使用AudioServicesCreateSystemSoundID來創(chuàng)建,而本地時(shí)間較長(稱之為音樂)使用AVAudioPlayer類。
二、代碼示例
AVAudioPlayer類依賴于AVFoundation框架,因此使用該類必須先導(dǎo)入AVFoundation框架,并包含其頭文件(包含主頭文件即可)。
導(dǎo)入必要的,需要播放的音頻文件到項(xiàng)目中。
代碼示例:
復(fù)制代碼 代碼如下:
//
// YYViewController.m
// 15-播放音樂
//
#import "YYViewController.h"
#import
@interface YYViewController ()
@end
復(fù)制代碼 代碼如下:
@implementation YYViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//1.音頻文件的url路徑
NSURL *url=[[NSBundle mainBundle]URLForResource:@"235319.mp3" withExtension:Nil];
//2.創(chuàng)建播放器(注意:一個(gè)AVAudioPlayer只能播放一個(gè)url)
AVAudioPlayer *audioPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:Nil];
//3.緩沖
[audioPlayer prepareToPlay];
//4.播放
[audioPlayer play];
}
@end
代碼說明:運(yùn)行程序,點(diǎn)擊模擬器界面,卻并沒有能夠播放音頻文件,原因是代碼中創(chuàng)建的AVAudioPlayer播放器是一個(gè)局部變量,應(yīng)該調(diào)整為全局屬性。
可將代碼調(diào)整如下,即可播放音頻:
復(fù)制代碼 代碼如下:
#import "YYViewController.h"
#import
@interface YYViewController ()
@property(nonatomic,strong)AVAudioPlayer *audioplayer;
@end
復(fù)制代碼 代碼如下:
@implementation YYViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//1.音頻文件的url路徑
NSURL *url=[[NSBundle mainBundle]URLForResource:@"235319.mp3" withExtension:Nil];
//2.創(chuàng)建播放器(注意:一個(gè)AVAudioPlayer只能播放一個(gè)url)
self.audioplayer=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:Nil];
//3.緩沖
[self.audioplayer prepareToPlay];
//4.播放
[self.audioplayer play];
}
@end
注意:一個(gè)AVAudioPlayer只能播放一個(gè)url,如果想要播放多個(gè)文件,那么就得創(chuàng)建多個(gè)播放器。
三、相關(guān)說明
新建一個(gè)項(xiàng)目,在storyboard中放三個(gè)按鈕,分別用來控制音樂的播放、暫停和停止。
程序代碼如下:
復(fù)制代碼 代碼如下:
#import "YYViewController.h"
#import
@interface YYViewController ()
@property(nonatomic,strong)AVAudioPlayer *player;
- (IBAction)play;
- (IBAction)pause;
- (IBAction)stop;
@end
@implementation YYViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//1.音頻文件的url路徑
NSURL *url=[[NSBundle mainBundle]URLForResource:@"235319.mp3" withExtension:Nil];
//2.創(chuàng)建播放器(注意:一個(gè)AVAudioPlayer只能播放一個(gè)url)
self.player=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:Nil];
//3.緩沖
[self.player prepareToPlay];
}
- (IBAction)play {
//開始播放/繼續(xù)播放
[self.player play];
}
- (IBAction)pause {
//暫停
[self.player pause];
}
- (IBAction)stop {
//停止
//注意:如果點(diǎn)擊了stop,那么一定要讓播放器重新創(chuàng)建,否則會(huì)出現(xiàn)一些莫名其面的問題
[self.player stop];
}
@end
注意:如果點(diǎn)了“停止”,那么一定要播放器重新創(chuàng)建,不然的話會(huì)出現(xiàn)莫名其妙的問題。
點(diǎn)擊了stop之后,播放器實(shí)際上就不能再繼續(xù)使用了,如果還繼續(xù)使用,那么后續(xù)的一些東西會(huì)無法控制。
推薦代碼:
復(fù)制代碼 代碼如下:
#import "YYViewController.h"
#import
@interface YYViewController ()
@property(nonatomic,strong)AVAudioPlayer *player;
- (IBAction)play;
- (IBAction)pause;
- (IBAction)stop;
@end
復(fù)制代碼 代碼如下:
@implementation YYViewController
#pragma mark-懶加載
-(AVAudioPlayer *)player
{
if (_player==Nil) {
//1.音頻文件的url路徑
NSURL *url=[[NSBundle mainBundle]URLForResource:@"235319.mp3" withExtension:Nil];
//2.創(chuàng)建播放器(注意:一個(gè)AVAudioPlayer只能播放一個(gè)url)
self.player=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:Nil];
//3.緩沖
[self.player prepareToPlay];
}
return _player;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (IBAction)play {
//開始播放/繼續(xù)播放
[self.player play];
}
- (IBAction)pause {
//暫停
[self.player pause];
}
- (IBAction)stop {
//停止
//注意:如果點(diǎn)擊了stop,那么一定要讓播放器重新創(chuàng)建,否則會(huì)出現(xiàn)一些莫名其面的問題
[self.player stop];
self.player=Nil;
}
@end
四、播放多個(gè)文件
點(diǎn)擊,url,按住common建查看。
可以發(fā)現(xiàn),這個(gè)url是只讀的,因此只能通過initWithContentsOfUrl的方式進(jìn)行設(shè)置,也就意味著一個(gè)播放器對象只能播放一個(gè)音頻文件。
那么如何實(shí)現(xiàn)播放多個(gè)音頻文件呢?
可以考慮封裝一個(gè)播放音樂的工具類,下一篇文章將會(huì)介紹具體怎么實(shí)現(xiàn)。
Core Audio 是iOS和MAC系統(tǒng)中的關(guān)于數(shù)字音頻處理的基礎(chǔ),它是應(yīng)用程序用來處理音頻的一組軟件框架,所有關(guān)于iOS音頻開發(fā)的接口都是由Core Audio來提供或者經(jīng)過它提供的接口來進(jìn)行封裝的。
其實(shí)一句話,它是任何iOS或者M(jìn)AC系統(tǒng)音頻處理框架的基礎(chǔ)。
具體可以用官方文檔的一張圖表示。
接下來我們就一起分析一下。
這里的高級(jí)別服務(wù),更加接近于頂層,基本上我們很多關(guān)于音頻開發(fā)的工作在這一層就可以完成。
它位于框架 AudioToolbox 中。
提供錄制、播放、暫停、循環(huán)、和同步音頻它自動(dòng)采用必要的編解碼器處理壓縮的音頻格式。
要在iOS設(shè)備上播放和錄制音頻,蘋果推薦我們使用 AVFoundation 框架中的 AVAudioPlayer 和 AVAudioRecorder 類。雖然用法比較簡單,但是不支持流式;這就意味著:在播放音頻前,必須等到整個(gè)音頻加載完成后,才能開始播放音頻;錄音時(shí),也必須等到錄音結(jié)束后,才能獲取到錄音數(shù)據(jù)。這給應(yīng)用造成了很大的局限性。為了解決這個(gè)問題,我們就需要使用 Audio Queue Services 來播放和錄制音頻。感興趣的可以看我前面寫的幾篇關(guān)于 Audio Queue Services 的文章。這里只是簡單的給出錄音和播放的原理圖,具體原理和流程,看我前面寫的那幾篇,都有詳細(xì)的介紹。
它位于框架 AVFoundation 中。
是專為IOS平臺(tái)提供的基于Objective-C接口的音頻播放類,可以支持iOS所支持的所有音頻的播放,它主要支持以下音頻格式。
這個(gè)是純OC的實(shí)現(xiàn),特點(diǎn)就是調(diào)用簡單,下面簡單的看一下他的API。
由 Audio File 與 Audio Converter 組合而成,提供壓縮及無壓縮音頻文件的讀寫能力。
它與 Audio File Services 、 Audio File Stream Services 和 Audio Queue Services 等同時(shí)存在 AudioToolbox 框架中。 ExtendedAudioFile 相對 Audio File Services 和 Audio Converter Services ,API調(diào)用非常簡單和明確,并且不需要去處理 AudioStreamPacketDescription ,在實(shí)際開發(fā)中邏輯更為清晰。
它就是存在框架 OpenAL 中。
是CoreAudio對OpenAL標(biāo)準(zhǔn)的實(shí)現(xiàn),可以播放3D混音效果。
OpenAL 主要的功能是在來源物體、音效緩沖和收聽者中編碼。來源物體包含一個(gè)指向緩沖區(qū)的指標(biāo)、聲音的速度、位置和方向,以及聲音強(qiáng)度。收聽者物體包含收聽者的速度、位置和方向,以及全部聲音的整體增益。緩沖里包含 8 或 16 位元、單聲道或立體聲 PCM 格式的音效資料,表現(xiàn)引擎進(jìn)行所有必要的計(jì)算,如距離衰減、多普勒效應(yīng)等。
不同于 OpenGL 規(guī)格,OpenAL 規(guī)格包含兩個(gè)API分支;以實(shí)際 OpenAL 函式組成的核心,和 ALC API , ALC 用于管理表現(xiàn)內(nèi)容、資源使用情況,并將跨平臺(tái)風(fēng)格封在其中。還有 “ALUT ”程式庫,提供高階“易用”的函式,其定位相當(dāng)于 OpenGL 的 GLUT 。
該層功能比較齊全,包括音頻數(shù)據(jù)格式轉(zhuǎn)換,音頻文件讀寫,音頻流解析,插件工作支持等。
它位于框架 AudioToolbox 中。
負(fù)責(zé)音頻數(shù)據(jù)格式的轉(zhuǎn)換
它位于框架 AudioToolbox 中。
負(fù)責(zé)音頻數(shù)據(jù)的讀寫。
它位于框架 AudioToolbox 中。
支持均衡器和混音器等數(shù)字信號(hào)處理的插件。
它位于框架 AudioToolbox 中。
負(fù)責(zé)流解析。
它位于框架 Core Audio 中。
負(fù)責(zé)音頻音頻時(shí)鐘同步。
該主要在MAC上的音頻APP實(shí)現(xiàn)中并且需要最大限度的實(shí)時(shí)性能的情況下使用,大部分音頻APP不需要使用該層的服務(wù)。而且,在iOS上也提供了具備較高實(shí)時(shí)性能的高層API達(dá)到你的需求。例如 OpenAL ,在游戲中具備與I/O直接調(diào)用的實(shí)時(shí)音頻處理能力。
它在 IOKit 框架中,與硬件驅(qū)動(dòng)交互。
獲得用戶空間訪問硬件設(shè)備和驅(qū)動(dòng)程序。 I / O Kit 框架通過設(shè)備接口機(jī)制實(shí)現(xiàn)對I / O Kit對象(驅(qū)動(dòng)程序和結(jié)點(diǎn))的非內(nèi)核訪問。
音頻硬件抽象層,使API調(diào)用與實(shí)際硬件相分離,保持獨(dú)立。
它位于 Core MIDI 框架中,與MIDI設(shè)備(如硬件鍵盤和合成器)進(jìn)行通信。
Core MIDI 框架提供了用于與MIDI(樂器數(shù)字接口)設(shè)備(包括硬件鍵盤和合成器)進(jìn)行通信的API。 使用基座連接器或網(wǎng)絡(luò)從iOS設(shè)備進(jìn)行連接。 有關(guān)使用基座連接器的更多信息,請參閱Apple的 MFi program 。
訪問電腦硬件時(shí)鐘。
只實(shí)現(xiàn)音頻的播放,沒有其他需求, AVAudioPlayer 就可以滿足需求。它的接口使用簡單,不用關(guān)心其中的細(xì)節(jié),通常只提供給它一個(gè)播放源的URL地址,并且調(diào)用其play、pause、stop等方法進(jìn)行控制,observer其播放狀態(tài)更新UI即可。
APP需要對音頻進(jìn)行流播放,就需要 AudioFileStreamer 加 Audio Queue ,將網(wǎng)絡(luò)或者本地的流讀取到內(nèi)存,提交給 AudioFileStreamer 解析分離音頻幀,分離出來的音頻幀可以送給 AudioQueue 進(jìn)行解碼和播放,可參考下面。
AudioStreamer
FreeStreamer
AFSoundManager
APP需要需要對音頻施加音效(均衡器、混響器),就是除了數(shù)據(jù)的讀取和解析以外還需要用到AudioConverter或者Codec來把音頻數(shù)據(jù)轉(zhuǎn)換成PCM數(shù)據(jù),再由AudioUnit+AUGraph來進(jìn)行音效處理和播放,可參考下面。
DouAudioStreamer
TheAmazingAudioEngine
AudioKit
1. iOS Audio Unit(一)
任何吸引人的游戲都少不了聲音。iOS開發(fā)者在游戲中需要使用聲音時(shí)有多種選擇,取決于對游戲中音頻的控制需求,可以選擇簡單的內(nèi)置服務(wù),也可以選擇更高級(jí)的API(比如OpenAL)。
通過音頻API,可以實(shí)現(xiàn)流式音頻,播放簡短音效,甚至模擬3d空間的音頻。有些游戲可以通過音軌讓玩家沉浸在特定的心境中玩游戲,設(shè)置鼓勵(lì)用戶使用耳機(jī)來獲得更完美的體驗(yàn)。
本系列文章中,會(huì)陸續(xù)整理近幾年來在工作中涉及到的音頻的相關(guān)知識(shí),以算做對自己知識(shí)體系的一次梳理吧,大體包括Core Audio、OpenAL 以及Cocos2d引擎中的音效部分等三個(gè)方面。
? Core Audio 是什么?
? Core Audio 中提供的音頻服務(wù)
? Core Audio 中的有關(guān)音頻框架
? 有關(guān) Core Audio 的變化及更新
Core Audio 是什么?
Core Audio 是iOS和 MAC 的關(guān)于數(shù)字音頻處理的基礎(chǔ),它提供應(yīng)用程序用來處理音頻的一組軟件框架,所有關(guān)于IOS音頻開發(fā)的接口都是由Core Audio來提供或者經(jīng)過它提供的接口來進(jìn)行封裝的,按照官方的說法是集播放、音頻處理、錄制為一體的專業(yè)技術(shù),通過它我們的程序可以同時(shí)錄制,播放一個(gè)或者多個(gè)音頻流,自動(dòng)適應(yīng)耳機(jī),藍(lán)牙耳機(jī)等硬件,響應(yīng)各種電話中斷,靜音,震動(dòng)等,甚至提供3D效果的音樂播放。
相關(guān)鏈接:
Core Audio Overview
Audio Video Starting Point
Core Audio Glossary
Core Audio中提供的音頻服務(wù)
Core Audio 本身是一個(gè)很龐大的話題,涉及到多個(gè)領(lǐng)域中的不同服務(wù),為了更方便的使用Core Audio,通??梢詫⑵浞指顬楦〉哪K。圖一展示了根據(jù)應(yīng)用程序服務(wù)層分解的示意圖。構(gòu)建在應(yīng)用程序棧最下面的是底層硬件。接下來往上是驅(qū)動(dòng)程序?qū)?。?gòu)建在驅(qū)動(dòng)層之上的每一層都是蘋果提供給開發(fā)人員的應(yīng)用層服務(wù),包括各類音頻API和框架。
主要的幾類服務(wù):
Audio Unit
Audio Unit 是Core Audio 在應(yīng)用層中最底層的服務(wù)。在使用其他音頻API時(shí),最終在底層都會(huì)調(diào)用到Audio Unit。在所有的API中,Audio Unit 是延遲最短且最靈活的,但代價(jià)就是它的使用相當(dāng)?shù)膹?fù)雜,幸運(yùn)的是在實(shí)際使用中,我們很少直接使用Audio Unit。
相關(guān)鏈接:
Audio Unit Framework Reference
相關(guān)項(xiàng)目工程:
Core Audio Utility Classes
Audio File Service
通過Audio File Service 提供的API可以打開并讀取或者寫入磁盤上存儲(chǔ)的文件。
Audio File Stream Service
它是對Audio File Service 的擴(kuò)展補(bǔ)充。Audio File Service 對存儲(chǔ)到磁盤上的音頻文件進(jìn)行操作,而Audio File Stream Service
并不一定關(guān)聯(lián)到某個(gè)文件上,它更適合基于網(wǎng)絡(luò)的音頻應(yīng)用程序。
Audio Conversion Service
通過它可以將數(shù)據(jù)轉(zhuǎn)換為PCM格式或者從PCM格式轉(zhuǎn)換成數(shù)據(jù)。
Extended Audio File Service
可以將它理解為Audio File Service 和 Audio File Service 的組合。通過這種API 可以直接加在并轉(zhuǎn)換音頻文件。
Audio Session Service
和Core Audio中的其他API不同,它的主要用于 iOS 系統(tǒng)中協(xié)調(diào)應(yīng)用程序之間的音頻播放的 API 的。例如,當(dāng)有電話打進(jìn)來時(shí),音頻的播放就會(huì)被暫停;在用戶啟動(dòng)電影時(shí),音樂的播放就會(huì)停止。我們需要使用這些 API 來確保一個(gè)應(yīng)用程序能夠正確響應(yīng)并處理這類事件。
System Sound Service
它是一種允許播放短音效和警告的基本服務(wù),還具有提供振動(dòng)功能的獨(dú)特能力,Core Audio中的其他任何服務(wù)都不能訪問振動(dòng)系統(tǒng)。
Audio Queue Service
它可以對播放音頻進(jìn)行精細(xì)的控制,比如暫停、繼續(xù)、循環(huán)播放和音頻同步等,因此特別適合于播放和錄制持續(xù)時(shí)間很長的音頻。在游戲中進(jìn)行語音敘述等情景時(shí),需要音樂或者長時(shí)間的播放文件,便會(huì)需要它。
AVFoundation
它是Core Audio中唯一基于Objective-C的框架。這個(gè)框架提供了AVAudioPlayer類用于播放,AVAudioReconder類用于錄音,以及AVAudioSession類用于設(shè)置音頻回話。和其他高層API一樣,我們需要在易用性和功能之間做出權(quán)衡。如果在此框架中找不到我們需要的特性或者功能,那么就必須深入底層服務(wù)并直接使用底層的API。
相關(guān)鏈接:
AV Foundation Framework Reference
AV Foundation Programming Guide
Audio Session Programming Guide
相關(guān)的項(xiàng)目工程:
AVCaptureAudioDataOutput To AudioUnit iOS
OpenAL
和其他專用API不同,OpenAL是一個(gè)狂平臺(tái)的用于播放和捕捉音頻的工業(yè)標(biāo)準(zhǔn)。OpenAL更適合播放空間音頻(spatialized sound)或者定位音頻(positional sound)??梢詫⒖臻g音頻理解成3D空間中的聲音,通過OpanAL可以對音效添加一些效果,比如位置屬性,這樣會(huì)使遠(yuǎn)程的聲音比近處的聲音聽起來要弱一些。
相關(guān)鏈接:
OpenAL FAQ for iPhone OS
相關(guān)的項(xiàng)目工程:
oalTouch
Core Audio中的有關(guān)音頻框架
Core Audio 中的服務(wù)和框架并沒有一對一的對應(yīng)關(guān)系,應(yīng)用層的服務(wù)實(shí)際上分為5個(gè)不同的框架:Core Audio、Audio Toolbox、Audio Unit、AVFoundtaion、OpenAL。圖二中很好的展示了這些框架和服務(wù)之間的映射關(guān)系。
Audio Unit、AVFoundation和OpenAL的框架非常明了,和他們同名的服務(wù)直接對應(yīng),其中AVFoundtion有三個(gè)Objective-C類組成:AVAudioPlayer、AVAudioRecorder和AVAudioSession。
Audio Toolbox 框架提供了前面列出的其他剩下的應(yīng)用層服務(wù),包括非常重要的Audio Session Service。
相關(guān)鏈接:
Audio Toolbox Framework Reference
其他相關(guān)框架:
Media Player Framework
它是一個(gè)用于音頻和視頻播放的高層級(jí)接口,它包含了一個(gè)可以在應(yīng)用中直接使用的默認(rèn)的用戶界面,可以使用它來播放用戶在 iPod 庫中的項(xiàng)目,或者播放本地文件以及網(wǎng)絡(luò)流。另外,這個(gè)框架也包括了查找用戶媒體庫中內(nèi)容的 API,同時(shí)還可以配置像是在鎖屏界面或者控制中心里的音頻控件。
相關(guān)鏈接:
Media Player Framework Reference
Core MIDI Framework
提供與MIDI設(shè)備通訊的標(biāo)準(zhǔn)方式,包括硬件鍵盤和合成器??梢允褂眠@個(gè)框架來發(fā)送和接收MIDI消息以及與通過dock連接器或網(wǎng)絡(luò)連接到iOS設(shè)備的MIDI外設(shè)交互。
相關(guān)鏈接:
Core MIDI Framework Reference
OS 4.0以后的功能變化如下:
iOS 7.1
Support for External Media Players (CarPlay相關(guān)的)
iOS 7.0
新增 Inter-App Audio和 AudioCopy
強(qiáng)化 Media Player / AV Foundation Framework
棄用 Audio Toolbox framework內(nèi)的Audio Session API
iOS 6.0
新增 Audio UnitのComponent
強(qiáng)化 Media Player / Core Media / AV Foundation Framework
iOS 5.0
新增 Audio UnitのComponent
強(qiáng)化 Media Player / AV Foundation / AudioToolbox Frameworks
iOS 4.3
強(qiáng)化 AV Foundation
強(qiáng)化 Media Player / Audio Unit / Audio Toolbox Frameworks
iOS 4.2
新增 Core MIDI framework
強(qiáng)化 Media Player Framework
新增 AirPlay
iOS 4.1
強(qiáng)化 AV Foundation
iOS 4.0
新增 Core Media Framework
強(qiáng)化 AV Foundation
相關(guān)鏈接:What's New in iOS
AAC實(shí)際上是高級(jí)音頻編碼的縮寫,目前只有蘋果的硬盤式MP3支持這一種格式。AAC是由Fraunhofer IIS-A、杜比和ATT共同開發(fā)的一種音頻格式,它是MPEG-2規(guī)范的一部分。AAC所采用的運(yùn)算法則與MP3的運(yùn)算法則有所不同,AAC通過結(jié)合其他的功能 來提高編碼效率。AAC的音頻算法在壓縮能力上遠(yuǎn)遠(yuǎn)超過了以前的一些壓縮算法(比如MP3等)。它還同時(shí)支持多達(dá)48個(gè)音軌、15個(gè)低頻音軌、更多種采樣率和比特率、多種語言的兼容能力、更高的解碼效率??傊?,AAC可以在比MP3文件縮小30%的前提下提供更好的音質(zhì)。