從CMSampleBufferRef中提取PCM數(shù)據(jù)

從CMSampleBufferRef中提取PCM數(shù)據(jù)

脈沖編碼調(diào)制罢屈,其實(shí)是將不規(guī)則的模擬信號轉(zhuǎn)換成數(shù)字信號色建,這樣就可以通過物理介質(zhì)存儲起來茴她。
而聲音也是一種特定頻率(20-20000HZ)的模擬信號旅东,也可以通過這種技術(shù)轉(zhuǎn)換成數(shù)字信號,從而保存下來玲献。
PCM格式港庄,就是錄制聲音時习霹,保存的最原始的聲音數(shù)據(jù)格式呜投。比如 wav格式的音頻加匈,它其實(shí)就是給PCM數(shù)據(jù)流加上一段header數(shù)據(jù)存璃,就成為了wav格式仑荐。而wav格式有時候之所以被稱為無損格式,就是因?yàn)樗4娴氖窃紁cm數(shù)據(jù)(也跟采樣率和比特率有關(guān))纵东。像我們耳熟能詳?shù)哪切┮纛l格式粘招,mp3,aac等等偎球,都是有損壓縮洒扎,為了節(jié)約占用空間,在很少損失音效的基礎(chǔ)上衰絮,進(jìn)行最大程度的壓縮袍冷。
所有的音頻編碼器,都支持pcm編碼猫牡,而且錄制的聲音胡诗,默認(rèn)也是PCM格式,所以我們下一步就是要獲取錄制的PCM數(shù)據(jù)。

-(NSData *) convertAudioSmapleBufferToPcmData:(CMSampleBufferRef) audioSample{

AudioStreamBasicDescription inAudioStreamBasicDescription = *CMAudioFormatDescriptionGetStreamBasicDescription((CMAudioFormatDescriptionRef)CMSampleBufferGetFormatDescription(pcmData));
    
//獲取CMBlockBufferRef
    CMBlockBufferRef blockBufferRef = CMSampleBufferGetDataBuffer(pcmData);
//獲取pcm數(shù)據(jù)大小
    size_t length = CMBlockBufferGetDataLength(blockBufferRef);
    
//分配空間
    char buffer[length];
//直接將數(shù)據(jù)copy至我們自己分配的內(nèi)存中
    CMBlockBufferCopyDataBytes(blockBufferRef, 0, length, buffer);
    
    if ((inAudioStreamBasicDescription.mFormatFlags & kAudioFormatFlagIsBigEndian) == kAudioFormatFlagIsBigEndian)
    {
        for (int i = 0; i < length; i += 2)
        {
            char tmp = buffer[i];
            buffer[i] = buffer[i+1];
            buffer[i+1] = tmp;
        }
    }
    
    uint32_t ch = inAudioStreamBasicDescription.mChannelsPerFrame;
    uint32_t fs = inAudioStreamBasicDescription.mSampleRate;

    //返回?cái)?shù)據(jù)
    return [NSData dataWithBytesNoCopy:buffer length:audioDataSize];
}

PCM填充CMSampleBufferRef

根據(jù)采樣精度我們可以知道一個采樣點(diǎn)的數(shù)據(jù)量煌恢,比如16位精度骇陈,即一個采樣點(diǎn)需要2子節(jié),則有200ms需要的數(shù)據(jù)量為:

//200ms 采樣點(diǎn)數(shù)量
NSUInteger samples = self->mSampleRate * 200 * self->mChannelsPerFrame/1000;
//200ms pcm數(shù)量量
int len = samples*2;

PCM填充CMSampleBufferRef 代碼示例:

- (CMSampleBufferRef)createAudioSampleBuffer:(char*) buf withLen:(int) len withASBD:(AudioStreamBasicDescription) asbd{
    
    AudioBufferList audioData;
    audioData.mNumberBuffers = 1;
    char* tmp = malloc(len);
    memcpy(tmp, buf, len);
    
    audioData.mBuffers[0].mData = tmp;
    audioData.mBuffers[0].mNumberChannels = asbd.mChannelsPerFrame;
    audioData.mBuffers[0].mDataByteSize = len;
    
    
    CMSampleBufferRef buff = NULL;
    CMFormatDescriptionRef format =NULL;
    OSStatus status = CMAudioFormatDescriptionCreate(kCFAllocatorDefault, &asbd,0, NULL, 0, NULL, NULL, &format);
    
    if (status) {
        return nil;
    }
    CMSampleTimingInfo timing = {CMTimeMake(asbd.mFramesPerPacket,asbd.mSampleRate), kCMTimeZero, kCMTimeInvalid };
    
    
    status = CMSampleBufferCreate(kCFAllocatorDefault,NULL, false,NULL, NULL, format, (CMItemCount)asbd.mFramesPerPacket,1, &timing, 0,NULL, &buff);
    
    if (status) { //失敗
        return nil;
    }
    
    status = CMSampleBufferSetDataBufferFromAudioBufferList(buff,kCFAllocatorDefault,kCFAllocatorDefault,0, &audioData);
    
    if (tmp) {
        free(tmp);
    }
    CFRelease(format);
    
    return buff;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瑰抵,一起剝皮案震驚了整個濱河市你雌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌二汛,老刑警劉巖婿崭,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異肴颊,居然都是意外死亡逛球,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門苫昌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來颤绕,“玉大人,你說我怎么就攤上這事祟身“挛瘢” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵袜硫,是天一觀的道長氯葬。 經(jīng)常有香客問我,道長婉陷,這世上最難降的妖魔是什么帚称? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮秽澳,結(jié)果婚禮上闯睹,老公的妹妹穿的比我還像新娘。我一直安慰自己担神,他們只是感情好楼吃,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著妄讯,像睡著了一般孩锡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上亥贸,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天躬窜,我揣著相機(jī)與錄音,去河邊找鬼炕置。 笑死荣挨,一個胖子當(dāng)著我的面吹牛溜族,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播垦沉,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼煌抒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了厕倍?” 一聲冷哼從身側(cè)響起寡壮,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎讹弯,沒想到半個月后况既,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡组民,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年棒仍,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片臭胜。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡莫其,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出耸三,到底是詐尸還是另有隱情乱陡,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布仪壮,位于F島的核電站憨颠,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏积锅。R本人自食惡果不足惜爽彤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望缚陷。 院中可真熱鬧适篙,春花似錦、人聲如沸蹬跃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蝶缀。三九已至,卻和暖如春薄货,著一層夾襖步出監(jiān)牢的瞬間翁都,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工谅猾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留柄慰,地道東北人鳍悠。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像坐搔,于是被迫代替她去往敵國和親藏研。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

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