這個星期我完成了一個具有基本錄音和回放的功能,一開始也不知道從何入手,也查找了很多相關的資料。與此同時,我也學會了很多關於音頻方面的東西,這也對后面的錄音配置有一定的幫助。其中參照了《iPhone開發之音頻: 文件和數據類型(一)》,啟發比較大。
一、音頻格式
iPhone上支持的音頻編碼格式還是比較多的,而且有很多我是以前聽都沒有聽過的。我就先簡單列出來(以下是摘錄自《iPhone開發之音頻: 文件和數據類型(一)》):
- AAC: AAC其實是“高級音頻編碼(advanced audio coding)”的縮寫,它是被設計用來取代MP3格式的。你可能會想,它壓縮了原始的聲音,導致容量占用少但是質量肯定會有所下降。不過這些質量的損失 取決於聲音比特率的大小,當比特率合適的時候,這些損失人耳是很難聽出來的。事實上,aac比mp3有更好的壓縮率,特別是在比特率低於128bit/s 的時候。
- HE-AAC: HE-AAC是AAC的一個超集,這個“HE”代表的是“High efficiency”。 HE-AAC是專門為低比特率所優化的一種音頻編碼格式,比如streaming audio就特別適合使用這種編碼格式。
- AMR: AMR全稱是“Adaptive Multi-Rate”,它也是另一個專門為“說話(speech)”所優化的編碼格式,也是適合低比特率環境下采用。
- ALAC: 它全稱是“Apple Lossless”,這是一種沒有任何質量損失的音頻編碼方式,也就是我們說的無損壓縮。在實際使用過程中,它能夠壓縮40%-60%的原始數據。這種編碼格式的解碼速度非常快,這對iphone或者ipod這種小型設備來說非常適合。
- iLBC: 這是另一種專門為說話所設計的音頻編碼格式,它非常適合於IP電話等其它需要流式音頻的場合。
- IMA4: 這是一個在16-bit音頻文件下按照4:1的壓縮比來進行壓縮的格式。這是iphone上面一種非常重要的編碼格式。
它的中文意思是基於線性脈沖編碼調制,用於將模擬聲音數據轉換成數字聲音數據。簡而言之,就是意味着無壓縮數據。由於數據是非壓縮的,它可以非常快的播放,並且當空間不是問題時,這是在iphone上面首選的音頻編碼方式。 - μ-law and a-law: 就我所知道的,這種編碼是交替的編碼模擬數據為數字格式數據,但是在speech優化方面比linear PCM更好。
- MP3: 這種格式是我們都知道也喜歡的,雖然很多年過去了,但MP3到目前為止仍然是一種非常流行的編碼格式,它也能被iphone很好地支持。
- LPCM也很早就被定義在DVD播放機 的標准內,為了和CD有所區別,DVD的的采樣規格為16bit/48KHz,隨着技術的發展,DVD的的采樣規格更提升到24bit/96KHz,以達 到更高的播放品質,用96KHz/24bit方式記錄的音頻信號所能達到的頻率上限是96÷2= 48KHz,而它的最大動態范圍將可以達到24×6=144dB。從指標上就可以看出:它的聲音比CD要好得多。pcm編碼的最大的優點就是音質好,最大的缺點就是體數據量大。
而我自己對此的理解是,主流格式iPhone都可以很好地支持了(APE、FLAC暫時忽略)。不過這里值得一提的就是,編碼格式與文件格式並不可以混為一談。為了省事,我就直接選用了caf文件格式,因為caf能包含任何iphone支持的編碼格式的數據,在iPhone上面它是推薦的文件格式。
文件格式選好以后,還是有很多的參數可以自己設定的,比特率、采樣率和位寬等。當然,選用合適的音頻格式還是比較重要,因為不同的格式之間文件大小差異還是比較明顯的。就以AAC和LPCM對比為例,采樣率同為44100Hz,默認的AAC一分鍾的大小約為500kB,但是16bit位寬的LPCM就可以達到5MB。但作為我用於錄音的用途,這么大的錄音文件,估計錄不了多少,用戶就會罵我的程序怎么占用這么多空間了。錄音務求能夠聽得出咬字清晰,不需要追求無損的音質。因此,我就選擇了AAC格式,同時更小的空間占用也便於上傳。
二、調用錄音
想要調用關於音頻方面的API,就要使用到AVAudioSession了。根據參考庫的資料,AVAudioSession類參考和AVAudioSessionDelegate協議參考描述了一個管理音頻會話的精簡接口。如果要使音頻會話支持中斷,則可以直接使用基於C語言的音頻會話服務接口。它是屬於C級別的API,錄音前,要先將它設為活動。
具體代碼
1 AVAudioSession *avSession = [AVAudioSession sharedInstance]; 2 [avSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; 3 [avSession setActive:YES error:nil];
這是錄音前的准備,要實現錄音,還需要AVAudioRecorder對象。
1 NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys: 2 [NSNumber numberWithFloat:44100.0], AVSampleRateKey, 3 [NSNumber numberWithInt:kAudioFormatMPEG4AAC], AVFormatIDKey, 4 [NSNumber numberWithInt:1], AVNumberOfChannelsKey, 5 nil]; 6 7 AVAudioRecorder *avRecorder = [[AVAudioRecorder alloc] initWithURL:recordUrl 8 settings:settings 9 error:nil];
這就創建了一個編碼格式為AAC的AVAudioRecorder對象了,記得要將文件路徑轉換成NSURL。
1 [avRecorder prepareToRecord]; 2 [avRecorder peakPowerForChannel:0]; 3 [avRecorder record];
這樣就可以開始錄音了,停止就調用
1 [avRecorder stop];
當然,還用再次將AVAudioSession的對象設為不活動,所以最好還是調用AVAudioRecorderDelegate的方法-(void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag。
1 [avSession setActive: NO error: nil];
那么,錄音的操作就已經完成了。
三、回放錄音
本來這個和錄音都是大同小異,沒什么值得重復說,都要將會話設為活動,實現完成時的delegate方法。但是,我后來發現,這么做有一個問題,回放的聲音超級小。起初我以為是音量有問題,就setVolume:1.0。但是依然不起作用,於是上網查了一下,原來要重新將AVAudioSession設一下。
1 [avSession setCategory: AVAudioSessionCategorySoloAmbient error: nil];
其余的也就差不多,不多說了。