欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

iOS的音頻文件的格式轉(zhuǎn)換示例

 更新時(shí)間:2018年09月10日 10:27:49   作者:洪呵呵  
這篇文章主要介紹了iOS的音頻文件的格式轉(zhuǎn)換示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

背景

因?yàn)槲业墓拘枰O(shè)計(jì)到app與硬件的通信,所以去年深入的研究了一下音頻各種格式的轉(zhuǎn)換,曾寫(xiě)過(guò)一篇簡(jiǎn)書(shū),現(xiàn)在搬過(guò)來(lái)豐富下自己的blog。

首先介紹一下常用的音頻文件格式

  • .amr:體積很小,1秒到約為1kb,所以音質(zhì)縮水也很厲害,一般用于手機(jī)鈴聲或彩信
  • .mp3:比較流行的,有損音頻,某些部分失真,,音質(zhì)隨碼率的提高,越高越好
  • .wav:為無(wú)損音頻
  • .pcm:無(wú)損的wav文件中音頻數(shù)據(jù)的一種編碼方式

由于App是通過(guò)AVAudioRecorder錄制音頻,默認(rèn)格式為pcm,文件比較大,所以不適合用于聊天通信的文件格式,所以最優(yōu)的選擇是轉(zhuǎn)換成amr格式

音頻格式轉(zhuǎn)換方式

.pcm-->.wav-->.amr

a)將pcm轉(zhuǎn)成wav

什么是WAV和PCM?

WAV:wav是一種無(wú)損的音頻文件格式,WAV符合 PIFF(Resource Interchange File Format)規(guī)范。所有的WAV都有一個(gè)文件頭,這個(gè)文件頭音頻流的編碼參數(shù)。WAV對(duì)音頻流的編碼沒(méi)有硬性規(guī)定,除了PCM之外,還有幾乎所有支持ACM規(guī)范的編碼都可以為WAV的音頻流進(jìn)行編碼。

PCM:PCM(Pulse Code Modulation----脈碼調(diào)制錄音)。所謂PCM錄音就是將聲音等模擬信號(hào)變成符號(hào)化的脈沖列,再予以記錄。PCM信號(hào)是由[1]、[0]等符號(hào)構(gòu)成的數(shù)字信號(hào),而未經(jīng)過(guò)任何編碼和壓縮處理。與模擬信號(hào)比,它不易受傳送系統(tǒng)的雜波及失真的影響。動(dòng)態(tài)范圍寬,可得到音質(zhì)相當(dāng)好的影響效果。

簡(jiǎn)單來(lái)說(shuō):wav是一種無(wú)損的音頻文件格式,pcm是沒(méi)有壓縮的編碼方式。

WAV和PCM的關(guān)系

WAV可以使用多種音頻編碼來(lái)壓縮其音頻流,不過(guò)我們常見(jiàn)的都是音頻流被PCM編碼處理的WAV,但這不表示W(wǎng)AV只能使用PCM編碼,MP3編碼同樣也可以運(yùn)用在WAV中,和AVI一樣,只要安裝好了相應(yīng)的Decode,就可以欣賞這些WAV了。在Windows平臺(tái)下,基于PCM編碼的WAV是被支持得最好的音頻格式,所有音頻軟件都能完美支持,由于本身可以達(dá)到較高的音質(zhì)的要求,因此,WAV也是音樂(lè)編輯創(chuàng)作的首選格式,適合保存音樂(lè)素材。因此,基于PCM編碼的WAV被作為了一種中介的格式,常常使用在其他編碼的相互轉(zhuǎn)換之中,例如MP3轉(zhuǎn)換成WMA。

簡(jiǎn)單來(lái)說(shuō):pcm是無(wú)損wav文件中音頻數(shù)據(jù)的一種編碼方式,但wav還可以用其它方式編碼。

這里詳細(xì)寫(xiě)了pcm和wav的區(qū)別,我簡(jiǎn)單概括成pcm少了一個(gè)wav頭描述信息。為此我從訊飛語(yǔ)音的sdk中移植出填寫(xiě)wav頭的函數(shù)并修改了一下

// 為pcm文件寫(xiě)入wav頭
+ (NSData*) writeWavHead:(NSData *)audioData {
 long sampleRate = [[self GetAudioRecorderSettingDict][AVSampleRateKey] longValue];
 long numOfChannelsKey = [[self GetAudioRecorderSettingDict][AVNumberOfChannelsKey] longValue];
 Byte waveHead[44];
 waveHead[0] = 'R';
 waveHead[1] = 'I';
 waveHead[2] = 'F';
 waveHead[3] = 'F';
 
 long totalDatalength = [audioData length] + 44;
 waveHead[4] = (Byte)(totalDatalength & 0xff);
 waveHead[5] = (Byte)((totalDatalength >> 8) & 0xff);
 waveHead[6] = (Byte)((totalDatalength >> 16) & 0xff);
 waveHead[7] = (Byte)((totalDatalength >> 24) & 0xff);
 
 waveHead[8] = 'W';
 waveHead[9] = 'A';
 waveHead[10] = 'V';
 waveHead[11] = 'E';
 
 waveHead[12] = 'f';
 waveHead[13] = 'm';
 waveHead[14] = 't';
 waveHead[15] = ' ';
 
 waveHead[16] = 16; //size of 'fmt '
 waveHead[17] = 0;
 waveHead[18] = 0;
 waveHead[19] = 0;
 
 waveHead[20] = 1; //format
 waveHead[21] = 0;
 
 waveHead[22] = numOfChannelsKey; //chanel
 waveHead[23] = 0;
 
 waveHead[24] = (Byte)(sampleRate & 0xff);
 waveHead[25] = (Byte)((sampleRate >> 8) & 0xff);
 waveHead[26] = (Byte)((sampleRate >> 16) & 0xff);
 waveHead[27] = (Byte)((sampleRate >> 24) & 0xff);
 
 long byteRate = sampleRate * 2 * (16 >> 3);;
 waveHead[28] = (Byte)(byteRate & 0xff);
 waveHead[29] = (Byte)((byteRate >> 8) & 0xff);
 waveHead[30] = (Byte)((byteRate >> 16) & 0xff);
 waveHead[31] = (Byte)((byteRate >> 24) & 0xff);
 
 waveHead[32] = 2*(16 >> 3);
 waveHead[33] = 0;
 
 waveHead[34] = 16;
 waveHead[35] = 0;
 
 waveHead[36] = 'd';
 waveHead[37] = 'a';
 waveHead[38] = 't';
 waveHead[39] = 'a';
 
 long totalAudiolength = [audioData length];
 
 waveHead[40] = (Byte)(totalAudiolength & 0xff);
 waveHead[41] = (Byte)((totalAudiolength >> 8) & 0xff);
 waveHead[42] = (Byte)((totalAudiolength >> 16) & 0xff);
 waveHead[43] = (Byte)((totalAudiolength >> 24) & 0xff);
 
 NSMutableData *pcmData = [[NSMutableData alloc]initWithBytes:&waveHead length:sizeof(waveHead)];
 [pcmData appendData:audioData];
 
 
 return pcmData;
 // [pcmData writeToFile:kVoiceWav atomically:true];
 
}

同時(shí)還需把關(guān)鍵的屬性抽取出來(lái)(如:采樣率,通道數(shù)…)

//錄音格式的設(shè)置
+ (NSDictionary*)GetAudioRecorderSettingDict{
 NSDictionary *recordSetting = [[NSDictionary alloc] initWithObjectsAndKeys:
         [NSNumber numberWithFloat: 8000],AVSampleRateKey, //采樣率
         [NSNumber numberWithInt: kAudioFormatLinearPCM],AVFormatIDKey,
         [NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,//采樣位數(shù) 默認(rèn) 16
         [NSNumber numberWithInt: 2], AVNumberOfChannelsKey,//通道的數(shù)目
         nil];
 return recordSetting;
}

b)將wav轉(zhuǎn)成amr

使用VoiceConvert(by:Tang Xiaoping)庫(kù)能將wav轉(zhuǎn)成amr,后來(lái)發(fā)現(xiàn)環(huán)信的EaseUI框架中也使用了這個(gè)

反過(guò)來(lái)轉(zhuǎn)換也是差不多的

pcm<--->mp3

這個(gè)就很簡(jiǎn)單了,用lame的框架進(jìn)行轉(zhuǎn)換,這個(gè)框架網(wǎng)上資料一大堆

本人為此花了不少時(shí)間整理了一下這些文件格式的轉(zhuǎn)換方法

/**
 * 轉(zhuǎn)換wav到amr
 *
 * @param wavPath wav文件路徑
 * @param isDelete 轉(zhuǎn)換成功后是否刪除源文件
 *
 * @return NO 失敗 YES成功
 */
+ (BOOL) wav2Amr:(NSString *)wavPath isDeleteSourchFile:(BOOL)isDelete;
 
/**
 * 轉(zhuǎn)換amr到wav
 *
 * @param amrPath amr文件路徑
 * @param isDelete 轉(zhuǎn)換成功后是否刪除源文件
 *
 * @return NO 失敗 YES成功
 */
+ (BOOL) amr2Wav:(NSString *)amrPath isDeleteSourchFile:(BOOL)isDelete;
 
/**
 * 轉(zhuǎn)換pcm到mp3
 *
 * @param pcmPath pcm文件路徑
 * @param isDelete 轉(zhuǎn)換成功后是否刪除源文件
 *
 * @return NO 失敗 YES成功
 */
+ (BOOL) pcm2Mp3: (NSString *)pcmPath isDeleteSourchFile:(BOOL)isDelete;
/**
 * 轉(zhuǎn)換pcm到wav
 *
 * @param pcmPath pcm文件路徑
 * @param isDelete 轉(zhuǎn)換成功后是否刪除源文件
 *
 * @return NO 失敗 YES成功
 */
+ (BOOL) pcm2Wav: (NSString *)pcmPath isDeleteSourchFile:(BOOL)isDelete;
 
/**
 * 轉(zhuǎn)換pcm到amr
 *
 * @param pcmPath pcm文件路徑
 * @param isDelete 轉(zhuǎn)換成功后是否刪除源文件
 *
 * @return NO 失敗 YES成功
 */
+ (BOOL) pcm2Amr:(NSString *)pcmPath isDeleteSourchFile:(BOOL)isDelete;
 
/**
 * 為pcm文件寫(xiě)入wav頭 
 */
+ (NSData*) writeWavHead:(NSData *)audioData;
void conventToMp3(NSString *pcmFile,NSString *mp3File);
 
/**
 錄音格式設(shè)置,轉(zhuǎn)換的時(shí)候需要獲取.(如:采樣率、采樣位數(shù)、通道的數(shù)目)
 建議使用此設(shè)置,如有修改,則轉(zhuǎn)換amr時(shí)也要對(duì)應(yīng)修改參數(shù),比較麻煩
 
 @returns 錄音設(shè)置
 */
+ (NSDictionary*)GetAudioRecorderSettingDict;

demo的下載地址https://github.com/qq631192328/PFAudio.git,如果覺(jué)得好麻煩點(diǎn)下星,如果有什么問(wèn)題歡迎指正

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • iOS開(kāi)發(fā)系列--詳細(xì)介紹數(shù)據(jù)存取

    iOS開(kāi)發(fā)系列--詳細(xì)介紹數(shù)據(jù)存取

    本篇文章主要介紹了iOS開(kāi)發(fā)系列--詳細(xì)介紹數(shù)據(jù)存取,詳細(xì)介紹了IOS數(shù)據(jù)的存儲(chǔ)問(wèn)題,具有一定的參考價(jià)值,有興趣的同學(xué)可以了解一下。
    2016-11-11
  • iOS禁用側(cè)滑返回手勢(shì)要點(diǎn)解析

    iOS禁用側(cè)滑返回手勢(shì)要點(diǎn)解析

    這篇文章主要為大家詳細(xì)解析了iOS禁用側(cè)滑返回手勢(shì)要點(diǎn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • ios之UIScrollerView滾動(dòng)視圖總結(jié)

    ios之UIScrollerView滾動(dòng)視圖總結(jié)

    本篇文章主要介紹了ios之UIScrollerView滾動(dòng)視圖總結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-01-01
  • iOS 攔截重定向302跳轉(zhuǎn)的方法詳解

    iOS 攔截重定向302跳轉(zhuǎn)的方法詳解

    這篇文章主要介紹了iOS 攔截重定向302跳轉(zhuǎn)的方法詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • iOS實(shí)現(xiàn)微信朋友圈視頻截取功能

    iOS實(shí)現(xiàn)微信朋友圈視頻截取功能

    這篇文章主要介紹了iOS實(shí)現(xiàn)微信朋友圈視頻截取功能,微信使用非常普遍,功能也很強(qiáng)大,不知道大家對(duì)微信朋友圈視頻截取功能有沒(méi)有了解,下面腳本之家小編給大家?guī)?lái)詳解介紹,感興趣的朋友一起看看吧
    2018-07-07
  • iOS實(shí)現(xiàn)UIButton的拖拽功能

    iOS實(shí)現(xiàn)UIButton的拖拽功能

    這篇文章主要為大家詳細(xì)介紹了iOS實(shí)現(xiàn)UIButton的拖拽功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 簡(jiǎn)介Objective-C解析XML與JSON數(shù)據(jù)格式的方法

    簡(jiǎn)介Objective-C解析XML與JSON數(shù)據(jù)格式的方法

    這篇文章主要介紹了Objective-C解析XML與JSON數(shù)據(jù)格式的方法,文中解析JSON包括拼接JSON字符串用到了SBJson這個(gè)解析器,需要的朋友可以參考下
    2016-01-01
  • iOS13適配的實(shí)現(xiàn)方法

    iOS13適配的實(shí)現(xiàn)方法

    這篇文章主要介紹了iOS13適配的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • iOS實(shí)現(xiàn)圖片保存與搜索功能

    iOS實(shí)現(xiàn)圖片保存與搜索功能

    這篇文章主要介紹了iOS實(shí)現(xiàn)圖片保存與搜索功能的相關(guān)資料,需要的朋友可以參考下
    2016-02-02
  • iOS使用視聽(tīng)媒體框架AVFoundation實(shí)現(xiàn)照片拍攝

    iOS使用視聽(tīng)媒體框架AVFoundation實(shí)現(xiàn)照片拍攝

    這篇文章主要為大家詳細(xì)介紹了iOS使用視聽(tīng)媒體框架AVFoundation實(shí)現(xiàn)照片拍攝,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-04-04

最新評(píng)論