Android手機(jī)直播(三)聲音采集

一蔑歌、文章說(shuō)明

開(kāi)始寫文章了羹应,才知道寫文章真心耗費(fèi)心力,希望自己盡量做到快速更新次屠,也希望這些文章真心能幫助到開(kāi)發(fā)者們园匹。
這篇文章主要講述Android聲音采集相關(guān)的知識(shí),首先介紹聲音的基礎(chǔ)知識(shí)劫灶,然后介紹如何采集聲音裸违,最后再講述Android上聲音錄制和回聲消除的相關(guān)步驟。

整個(gè)項(xiàng)目已經(jīng)開(kāi)源本昏,開(kāi)源地址:SopCastComponent

二供汛、基礎(chǔ)知識(shí)

聲音的原理

聲音是振動(dòng)產(chǎn)生的聲波,通過(guò)介質(zhì)(空氣或固體涌穆、液體)傳播并能被人或動(dòng)物聽(tīng)覺(jué)器官所感知的波動(dòng)現(xiàn)象怔昨。聲音的頻率一般會(huì)以赫茲表示,記為Hz宿稀,指每秒鐘周期性振動(dòng)的次數(shù)趁舀。而分貝是用來(lái)表示聲音強(qiáng)度的單位,記為dB祝沸。
聲音是一種波動(dòng)矮烹,當(dāng)演奏樂(lè)器巡蘸、拍打一扇門或者敲擊桌面時(shí),聲音的振動(dòng)會(huì)引起介質(zhì)——空氣分子有節(jié)奏的振動(dòng)擂送,使周圍的空氣產(chǎn)生疏密變化悦荒,形成疏密相間的縱波,這就產(chǎn)生了聲波嘹吨,這種現(xiàn)象會(huì)一直延續(xù)到振動(dòng)消失為止搬味。
任何器官所接收的聲音頻率都有其范圍限制。人類的耳朵一般只能聽(tīng)到約在20Hz至20000 Hz(20kHz)范圍內(nèi)的聲音蟀拷,其上限會(huì)隨年齡增加而降低碰纬。其他物種動(dòng)物的聽(tīng)覺(jué)頻率范圍也有所不同,像狗可以聽(tīng)到超過(guò)20kHz的聲音问芬,但無(wú)法聽(tīng)到40Hz以下的聲音悦析。不同物種動(dòng)物的聽(tīng)覺(jué)頻率范圍如下:

蝙蝠:1000~120000Hz
海豚:2000~100000Hz
貓:60~65000Hz
狗:40~50000Hz
人:20~20000Hz

紅:次聲波、藍(lán):可聽(tīng)聲波此衅、綠:超聲波
麥克風(fēng)采集

麥克風(fēng)(又稱微音器或話筒强戴,正式的中文名是傳聲器),譯自英文microphone挡鞍,是一種將聲音轉(zhuǎn)換成電子信號(hào)的換能器骑歹。根據(jù)麥克風(fēng)的制作原理,分為以下幾類:

動(dòng)圈麥克風(fēng)
動(dòng)圈式麥克風(fēng)基本構(gòu)造包含線圈墨微、振膜道媚、永久磁鐵三部分。當(dāng)聲波進(jìn)入麥克風(fēng)翘县,振膜受到聲波的壓力而產(chǎn)生振動(dòng)最域,與振膜連接在一起的線圈則開(kāi)始在磁場(chǎng)中移動(dòng),根據(jù)法拉第定律以及楞次定律锈麸,線圈會(huì)產(chǎn)生感應(yīng)電流镀脂。
動(dòng)圈式麥克風(fēng)因?yàn)楹芯€圈和磁鐵,不像電容式麥克風(fēng)輕便掐隐,靈敏度較低狗热,高低頻響應(yīng)表現(xiàn)較差钞馁。優(yōu)點(diǎn)是聲音較為柔潤(rùn)虑省,適合用來(lái)收錄人聲。


1僧凰、聲波 2探颈、振動(dòng)膜 3、線圈 4训措、磁鐵 5伪节、輸出信號(hào)

電容式麥克風(fēng)
電容式麥克風(fēng)并沒(méi)有線圈及磁鐵光羞,靠著電容兩片隔板間距離的改變來(lái)產(chǎn)生電壓變化。當(dāng)聲波進(jìn)入麥克風(fēng)怀大,振動(dòng)膜產(chǎn)生振動(dòng)纱兑,因?yàn)榛迨枪潭ǖ模沟谜駝?dòng)膜和基板之間的距離會(huì)隨著振動(dòng)而改變化借,根據(jù)電容的特性潜慎,當(dāng)兩塊隔板距離發(fā)生變化時(shí),電容值C會(huì)產(chǎn)生改變蓖康,又由于Q = C * V铐炫,當(dāng)C改變時(shí)就會(huì)造成電量Q的改變。因?yàn)樵陔娙菔禁溈孙L(fēng)中需要維持固定的極板電壓V蒜焊,所以此類麥克風(fēng)需要額外的電源才能運(yùn)作倒信,一般常見(jiàn)的電源為電池。電容式麥克風(fēng)因靈敏度較高泳梆,常用于高質(zhì)量的錄音鳖悠。


1、聲波 2优妙、振動(dòng)膜 3竞穷、基板 4、電池 5鳞溉、電阻 6瘾带、輸出信號(hào)

駐極體電容麥克風(fēng)
電容式麥克風(fēng)一般需要額外的電源才能運(yùn)作,但是駐極體電容麥克風(fēng)卻可以不需要額外的電源熟菲。駐極體又叫“永電體”看政,本身會(huì)帶有固定數(shù)量的電荷數(shù),整個(gè)線路沒(méi)有電量消耗(線路去除上圖的電池和電阻)抄罕,根據(jù)公式:Q =CU 所以當(dāng)C變化時(shí)必然引起電容器兩端電壓U的變化允蚣,從而輸出電信號(hào),實(shí)現(xiàn)聲—電的變換呆贿。由于實(shí)際電容器的電容量很小嚷兔,輸出的電信號(hào)極為微弱,輸出阻抗極高做入,可達(dá)數(shù)百兆歐以上冒晰。因此,它不能直接與放大電路相連接竟块,必須連接阻抗變換器壶运。通常用一個(gè)專用的場(chǎng)效應(yīng)管和一個(gè)二極管復(fù)合組成阻抗變換器。由于場(chǎng)效應(yīng)管是有源器件浪秘,需要一定的偏置和電流才可以工作在放大狀態(tài)蒋情,因此埠况,駐極體話筒都要加一個(gè)直流偏置才能工作。

微機(jī)電麥克風(fēng)
微機(jī)電麥克風(fēng)指使用微機(jī)電技術(shù)做成的麥克風(fēng)棵癣,也稱麥克風(fēng)芯片或硅麥克風(fēng)辕翰。 微機(jī)電麥克風(fēng)的壓力感應(yīng)膜是以微機(jī)電技術(shù)直接蝕刻在硅芯片上,此集成電路芯片通常也集成入一些相關(guān)電路狈谊,如前置放大器金蜀。 大多數(shù)微機(jī)電麥克風(fēng)的設(shè)計(jì),在基本原理上是屬于電容式麥克風(fēng)的一種變型的畴。 微機(jī)電麥克風(fēng)也常內(nèi)置模擬數(shù)字轉(zhuǎn)換器渊抄,直接輸出數(shù)字信號(hào),成為數(shù)字式麥克風(fēng)丧裁,以利與現(xiàn)今的數(shù)字電路連接护桦。微機(jī)電麥克風(fēng)的主要應(yīng)用于部分的手機(jī)、PDA等小型移動(dòng)產(chǎn)品煎娇。

還有其他類型的麥克風(fēng)在這就不多做講述二庵。

麥克風(fēng)降噪

隨著科技的發(fā)展,現(xiàn)在即使在非常嘈雜的環(huán)境下缓呛,接聽(tīng)電話的另一方也能聽(tīng)得清清楚楚催享,這主要得益于手機(jī)降噪技術(shù)的發(fā)展。在現(xiàn)在的手機(jī)我們常秤窗恚看到不僅僅只有一個(gè)麥克風(fēng)因妙,而是有2個(gè)甚至是3個(gè),而這多出來(lái)的幾個(gè)就是手機(jī)降噪的關(guān)鍵票髓。


麥克風(fēng)降噪

一般來(lái)說(shuō)手機(jī)都有兩個(gè)麥克風(fēng)攀涵,頂部和底部都各有一個(gè)。這兩個(gè)麥看起來(lái)都非常小洽沟,但是兩者的作用有著明顯的區(qū)別以故,其中底部的麥?zhǔn)怯脕?lái)提供清晰通話,而頂部的麥?zhǔn)怯脕?lái)消除噪音裆操。
由于頂部和底部在通話時(shí)距離音源的距離不同怒详,所以兩個(gè)麥?zhǔn)叭〉囊袅看笮∫彩怯胁煌模眠@個(gè)差別踪区,我們就可以過(guò)濾掉噪聲保留人聲了昆烁。在打電話時(shí),兩個(gè)麥克風(fēng)所拾取的背景噪聲音量是基本相同的朽缴,而記錄的人聲會(huì)有6dB左右的音量差善玫。頂端麥?zhǔn)占肼暫笏ㄟ^(guò)解碼生成補(bǔ)償信號(hào)后就可以用來(lái)消除噪音了密强。

回聲

回聲(或稱回音)是指障礙物對(duì)聲音的反射茅郎。聲波在遇到障礙物時(shí),一部分聲波會(huì)穿過(guò)障礙物或渤,而另一部分聲波會(huì)反射回來(lái)形成回聲系冗。若障礙物具有堅(jiān)硬光滑的表面易產(chǎn)生回聲;反之薪鹦,具有柔軟的表面則易吸收聲音掌敬;另外,粗糙的表面易散射聲音池磁”己Γ回聲相比那些直接傳播的聲音所經(jīng)過(guò)的路程更長(zhǎng),所以會(huì)比直接傳播的聲音晚被聽(tīng)到地熄。如果兩列聲波的時(shí)間間隔小于0.1秒华临,人耳邊無(wú)法分辨,只能聽(tīng)到被延長(zhǎng)的聲音端考。因?yàn)槭覝兀?0℃)時(shí)空氣中的聲速是343米每秒雅潭,所以站在聲源處的人要聽(tīng)到回聲需要障礙物到聲源的距離至少17米。

回聲消除

很多時(shí)候直播有連麥的需求却特,這時(shí)候就需要對(duì)采集的聲音進(jìn)行回聲消除扶供。當(dāng)處在連麥的情況下,手機(jī)一邊播放對(duì)方的聲音裂明,一邊用麥克風(fēng)進(jìn)行采集椿浓,然后又將采集的聲音傳送給對(duì)方,這樣的話對(duì)方就會(huì)聽(tīng)到自己的回聲闽晦,由于這個(gè)循環(huán)回路一直進(jìn)行轰绵,從而就會(huì)使得回聲越來(lái)越多,最后出現(xiàn)嗡鳴聲尼荆。
回聲消除就是在麥克風(fēng)錄制外音的時(shí)候去除掉手機(jī)自身播放出來(lái)的聲音左腔,這樣就將對(duì)方的聲音從采集的聲音中過(guò)濾出去,從而就避免了回聲的產(chǎn)生捅儒。下面一張圖片很好展示了回聲消除的機(jī)制液样。


回聲消除

在近端,麥克風(fēng)會(huì)采集到揚(yáng)聲器播放出來(lái)的遠(yuǎn)端聲音巧还,假設(shè)這路聲音為y(n)鞭莽,當(dāng)然由于需要將遠(yuǎn)端傳來(lái)播放出來(lái),我們當(dāng)然能得到遠(yuǎn)端傳來(lái)的聲音信號(hào)麸祷,假設(shè)這路聲音為x(n)澎怒。不難發(fā)現(xiàn)x(n)經(jīng)過(guò)揚(yáng)聲器的播放,然后經(jīng)過(guò)空氣的傳播阶牍,最后被麥克風(fēng)采集喷面,然后變?yōu)閥(n)星瘾,x(n)和y(n)具有明顯的相關(guān)性。假設(shè)麥克風(fēng)采集到的總聲音信號(hào)為z(n)惧辈,這時(shí)候需要通過(guò)自適應(yīng)濾波器根據(jù)x(n)找出z(n)中的y(n)琳状,然后從z(n)中過(guò)濾掉y(n)。

三盒齿、聲音采集

在之前已經(jīng)講述了麥克風(fēng)的工作原理念逞,麥克風(fēng)采集到聲音后轉(zhuǎn)化為模擬電信號(hào),之后需要將模擬電信號(hào)數(shù)字化轉(zhuǎn)化為計(jì)算機(jī)能夠識(shí)別的模擬信號(hào)边翁。

Android中利用AudioRecord可以錄制聲音翎承,錄制出來(lái)的聲音可以設(shè)置為PCM聲音。想要將聲音用計(jì)算機(jī)語(yǔ)言表述符匾,則必須將聲音進(jìn)行數(shù)字化审洞。將聲音數(shù)字化,最常見(jiàn)的方式是通過(guò)脈沖編碼調(diào)制PCM(Pulse Code Modulation) 待讳。聲音經(jīng)過(guò)麥克風(fēng)芒澜,轉(zhuǎn)換成一連串電壓變化的信號(hào)。要將這樣的電壓變化的信號(hào)轉(zhuǎn)化成為PCM信號(hào)則需要進(jìn)行三個(gè)過(guò)程:抽樣创淡、量化痴晦、編碼。要實(shí)現(xiàn)這三個(gè)過(guò)程琳彩,則需要使用三個(gè)參數(shù)誊酌,它們是:采樣頻率、采樣位數(shù)和聲道數(shù)露乏。


Pulse Code Modulation
1碧浊、采樣頻率

采樣頻率即取樣頻率,指每秒鐘取得聲音樣本的次數(shù)瘟仿。采樣頻率越高箱锐,聲音的質(zhì)量也就越好,聲音的還原也就越真實(shí)劳较,但同時(shí)它占的資源比較多驹止。由于人耳的分辨率很有限,太高的頻率并不能分辨出來(lái)观蜗。在16位聲卡中有22KHz臊恋、44KHz等幾級(jí),其中墓捻,22KHz相當(dāng)于普通FM廣播的音質(zhì)抖仅,44KHz已相當(dāng)于CD音質(zhì)了,目前的常用采樣頻率都不超過(guò)48KHz。

2撤卢、采樣位數(shù)

采樣位數(shù)即采樣值或取樣值(就是將采樣樣本幅度量化)环凿。它是用來(lái)衡量聲音波動(dòng)變化的一個(gè)參數(shù),也可以說(shuō)是聲卡的分辨率凸丸。它的數(shù)值越大拷邢,分辨率也就越高袱院,所發(fā)出聲音的能力越強(qiáng)屎慢。
在計(jì)算機(jī)中采樣位數(shù)一般有8位和16位之分,8位不是說(shuō)把縱坐標(biāo)分成8份忽洛,而是分成2的8次方即256份腻惠; 同理16位是把縱坐標(biāo)分成2的16次方65536份。
采樣率和采樣大小的值越大欲虚,記錄的波形更接近原始信號(hào)集灌。

3、聲道數(shù)

很好理解复哆,有單聲道和立體聲之分欣喧,單聲道的聲音只能使用一個(gè)喇叭發(fā)聲(有的也處理成兩個(gè)喇叭輸出同一個(gè)聲道的聲音),立體聲的pcm可以使兩個(gè)喇叭都發(fā)聲(一般左右聲道有分工) 梯找,更能感受到空間效果唆阿。

那么,現(xiàn)在我們就可以得到pcm文件所占容量的公式:
存儲(chǔ)量 = (采樣頻率 · 采樣位數(shù) · 聲道 · 時(shí)間)/8 (單位:字節(jié)數(shù))

四锈锤、聲音錄制

Android中使用AudioRecord錄制聲音驯鳖,根據(jù)上面講述的聲音采集原理,需要傳遞給AudioRecord采樣頻率久免、采樣位數(shù)和聲道數(shù)浅辙,除此之外還需要傳入兩個(gè)參數(shù),一個(gè)是聲音源阎姥,一個(gè)是緩沖區(qū)大小记舆。

權(quán)限

在Android中錄制聲音需要相應(yīng)的權(quán)限,注意動(dòng)態(tài)申請(qǐng)權(quán)限的問(wèn)題呼巴。

<uses-permission android:name="android.permission.RECORD_AUDIO" />
音頻源

下面是Android支持的音頻源:

/** 默認(rèn)聲音 **/
public static final int DEFAULT = 0;
/** 麥克風(fēng)聲音 */
public static final int MIC = 1;
/** 通話上行聲音 */
public static final int VOICE_UPLINK = 2;
/** 通話下行聲音 */
public static final int VOICE_DOWNLINK = 3;
/** 通話上下行聲音 */
public static final int VOICE_CALL = 4;
/** 根據(jù)攝像頭轉(zhuǎn)向選擇麥克風(fēng)*/
public static final int CAMCORDER = 5;
/** 對(duì)麥克風(fēng)聲音進(jìn)行聲音識(shí)別氨淌,然后進(jìn)行錄制 */
public static final int VOICE_RECOGNITION = 6;
/** 對(duì)麥克風(fēng)中類似ip通話的交流聲音進(jìn)行識(shí)別,默認(rèn)會(huì)開(kāi)啟回聲消除和自動(dòng)增益 */
public static final int VOICE_COMMUNICATION = 7;
/** 錄制系統(tǒng)內(nèi)置聲音 */
public static final int REMOTE_SUBMIX = 8;
緩沖區(qū)大小

接下來(lái)便是要設(shè)置緩沖區(qū)大小伊磺。麥克風(fēng)采集到的數(shù)據(jù)先放置在一個(gè)緩沖區(qū)里面盛正,之后我們?cè)購(gòu)倪@個(gè)緩沖區(qū)里面讀取數(shù)據(jù),從而獲取到麥克風(fēng)錄制的音頻數(shù)據(jù)屑埋。在Android中不同的聲道數(shù)豪筝、采樣位數(shù)和采樣頻率會(huì)有不同的最小緩沖區(qū)大小,當(dāng)AudioRecord傳入的緩沖區(qū)大小小于最小緩沖區(qū)大小的時(shí)候則會(huì)初始化失敗。大的緩沖區(qū)大小可以達(dá)到更為平滑的錄制效果续崖,相應(yīng)的也會(huì)帶來(lái)更大一點(diǎn)的延時(shí)敲街。


聲音緩沖區(qū)

通過(guò)下面的方法可以獲得最小緩沖區(qū)的大小:

AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding);

當(dāng)獲取失敗后會(huì)返還負(fù)數(shù)严望,根據(jù)錯(cuò)誤碼可以得到相應(yīng)的錯(cuò)誤信息多艇。

初始化

在對(duì)AudioRecord進(jìn)行錄音前需要對(duì)采樣率進(jìn)行設(shè)置,對(duì)于采樣率像吻,Android官方文檔要求所有的手機(jī)需要對(duì)44100Hz的采樣率進(jìn)行支持峻黍,可是國(guó)內(nèi)的一些極其少數(shù)的手機(jī)依然不支持44100Hz的采樣率。以下是幾種常見(jiàn)的采樣率:

8000, 11025, 16000, 22050, 44100, 48000

在設(shè)置采樣率之前需要對(duì)手機(jī)對(duì)設(shè)置的采樣率是否支持進(jìn)行檢測(cè)拨匆,下面是一段代碼是獲取手機(jī)支持的音頻采樣率:

public void getValidSampleRates() {
    for (int rate : new int[] {8000, 11025, 16000, 22050, 44100}) {  // add the rates you wish to check against
        int bufferSize = AudioRecord.getMinBufferSize(rate, AudioFormat.CHANNEL_CONFIGURATION_DEFAULT, AudioFormat.ENCODING_PCM_16BIT);
        if (bufferSize > 0) {
            // buffer size is valid, Sample rate supported

        }
    }
}

為了達(dá)到立體聲的效果姆涩,Android也是支持多個(gè)聲道采集的,一些情況下為了完成在所有手機(jī)上的視頻惭每,我們需要把聲道設(shè)置為AudioFormat.CHANNEL_CONFIGURATION_MONO(單聲道)骨饿。
對(duì)于采樣位數(shù),選的值也是以常量的形式定義在 AudioFormat 類中台腥,常用的是 ENCODING_PCM_16BIT(16bit)宏赘,ENCODING_PCM_8BIT(8bit),ENCODING_PCM_16BIT可以保證兼容所有Android手機(jī)的黎侈。

下面便是AudioRecord的初始化方法:

public AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, 
                      int audioFormat, int bufferSizeInBytes) throws IllegalArgumentException

當(dāng)傳入的參數(shù)出現(xiàn)問(wèn)題時(shí)會(huì)拋出異常察署。AudioRecord有一個(gè)狀態(tài)量用來(lái)表示AudioRecord是否被成功初始化,通過(guò)getState()方法可以獲取蜓竹,當(dāng)返回為STATE_UNINITIALIZED表示未成功初始化箕母,當(dāng)返回為STATE_INITIALIZED表示已經(jīng)成功初始化了。

讀取數(shù)據(jù)

AudioRecord通過(guò)下面的方法可以讀取到相應(yīng)的錄音數(shù)據(jù):

public int read(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes) {    
        return read(audioData, offsetInBytes, sizeInBytes, READ_BLOCKING);
}

當(dāng)讀取失敗的時(shí)候會(huì)返回相應(yīng)的負(fù)數(shù)錯(cuò)誤碼俱济。

參數(shù)選擇

Android手機(jī)有很多廠商嘶是,對(duì)于開(kāi)發(fā)者來(lái)說(shuō)兼容性一直以來(lái)都是一個(gè)重要的問(wèn)題。在錄音過(guò)程中蛛碌,Android推薦的參數(shù)如下:

sampleRateInHz = 44100;
channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
audioFormat = AudioFormat.ENCODING_PCM_16BIT

五聂喇、回聲消除

在Android中回聲消除可以通過(guò)三種方式進(jìn)行處理:1、通過(guò)VOICE_COMMUNICATION模式進(jìn)行錄音蔚携,自動(dòng)實(shí)現(xiàn)回聲消除希太;2、利用Android自身帶的AcousticEchoCanceler進(jìn)行回聲消除處理酝蜒;3誊辉、使用第三方庫(kù)(Speex、Webrtc)進(jìn)行回聲消除處理亡脑。

使用AudioRecord模式進(jìn)行錄音的時(shí)候堕澄,需要將AudioManager設(shè)置模式為MODE_IN_COMMUNICATION邀跃,還需要將麥克風(fēng)打開(kāi)。有一點(diǎn)需要特別注意蛙紫,音頻采樣率必須設(shè)置8000或者16000拍屑,通道數(shù)必須設(shè)為1個(gè)

AudioManager audioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
audioManager.setSpeakerphoneOn(true);

使用AcousticEchoCanceler過(guò)程比較簡(jiǎn)單坑傅,錄制聲音的時(shí)候可以通過(guò)AudioRecord得到AudioSessionId僵驰,在創(chuàng)建AudioTrack的時(shí)候也可以傳入一個(gè)AudioSessionId,這時(shí)候?qū)⑦@個(gè)統(tǒng)一的AudioSessionId傳入AcousticEchoCanceler唁毒,那么AcousticEchoCanceler將根據(jù)之前講過(guò)的回聲消除的原理進(jìn)行回聲消除蒜茴。

 private void initAec(int audioSessionId) {
    if(!AudioAecUtils.isAcousticEchoCancelerApproved()) {
        aecSwitch.setEnabled(false);
        return;
    }
    aec = AcousticEchoCanceler.create(audioSessionId);
    if (aec == null) {
        Log.e(TAG, "AcousticEchoCanceler.create failed");
        aecSwitch.setEnabled(false);
        return;
    }
}

private boolean setEnableAec(boolean enable) {
    if (aec == null) {
        return false;
    }
    int ret = aec.setEnabled(enable);
    if (ret != AudioEffect.SUCCESS) {
        Log.e(TAG, "AcousticEchoCanceler.setEnabled failed");
        return false;
    }
    if(enable) {
        Log.d(TAG, "Aec On");
    } else {
        Log.d(TAG, "Aec Off");
    }
    return true;
}

當(dāng)使用Speex或者Webrtc第三方庫(kù)進(jìn)行回聲消除的時(shí)候,需要將采集到的音頻數(shù)據(jù)傳入作為源數(shù)據(jù)枉证,需要將此刻播放的音頻數(shù)據(jù)傳入作為參考數(shù)據(jù)矮男,然后還需要傳入一個(gè)延時(shí)間隔移必,這樣第三方庫(kù)就能工作室谚,從而得到回聲消除后的聲音。因?yàn)椴シ诺穆曇粜枰獋鞑ゴ薇茫饮溈孙L(fēng)采集聲音還有相應(yīng)的緩沖區(qū)秒赤,因此需要傳入一個(gè)延時(shí)間隔。關(guān)于Speex和Webrtc在github上能找到相應(yīng)的Android ndk庫(kù)憎瘸。

本人三種方式都進(jìn)行了嘗試入篮,發(fā)現(xiàn)第一種效果最好,兼容性也較好幌甘,因?yàn)槭謾C(jī)免提通話的時(shí)候就進(jìn)行了回聲消除處理潮售,所以基本上所有的手機(jī)是支持的。第二種方式支持的很少锅风,Nexus 5支持第二種方式酥诽。理論上第三種方式兼容性最好,但是本人多次實(shí)驗(yàn)發(fā)現(xiàn)要設(shè)置合適的延時(shí)間隔很難皱埠,有些時(shí)候設(shè)置好了肮帐,但是通話一段時(shí)間效果又變差。

六边器、聲音模式

在Android系統(tǒng)中有著多種的聲音模式训枢,通過(guò)AudioManager.setMode()可以設(shè)置聲音的模式。就像上面回聲消除所描述的忘巧,通過(guò)設(shè)置聲音模式為MODE_IN_COMMUNICATION恒界,加上一些聲音參數(shù)的設(shè)置可以啟動(dòng)Android自身的硬件回聲消除(通話時(shí)候的回聲消除)。

設(shè)置聲音模式的時(shí)候需要權(quán)限“android.permission.MODIFY_AUDIO_SETTINGS”砚嘴。不同的聲音模式聲音的輸出行為不一樣十酣。

當(dāng)設(shè)置為MODE_IN_COMMUNICATION模式時(shí)眯勾,聲音默認(rèn)是聽(tīng)筒出聲,這時(shí)候如果是在連麥模式而且主播沒(méi)有戴耳機(jī)的情況下顯然這樣不符合婆誓,這時(shí)候需要調(diào)用audioManager.setSpeakerphoneOn(true)切換成外放出聲吃环。當(dāng)插上耳機(jī)后,聲音不需要外放洋幻,需要從耳機(jī)出聲郁轻,這樣可以設(shè)置audioManager.setSpeakerphoneOn(false)。

當(dāng)聲音模式為MODE_NORMAL文留,沒(méi)有插耳機(jī)的時(shí)候聲音自動(dòng)外放好唯,插上耳機(jī)聲音從耳機(jī)出聲,不需要進(jìn)行相應(yīng)的設(shè)置燥翅。

七骑篙、相關(guān)鏈接

Android手機(jī)直播(一)總覽
Android手機(jī)直播(二)攝像機(jī)
Android手機(jī)直播(三)聲音采集
Android手機(jī)直播(四)Android Media API

八、結(jié)束語(yǔ)

終于寫完了森书,各位看官覺(jué)得文章不錯(cuò)的話不妨點(diǎn)個(gè)喜歡~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末靶端,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子凛膏,更是在濱河造成了極大的恐慌杨名,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件猖毫,死亡現(xiàn)場(chǎng)離奇詭異台谍,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)吁断,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門趁蕊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人仔役,你說(shuō)我怎么就攤上這事掷伙。” “怎么了骂因?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵炎咖,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我寒波,道長(zhǎng)乘盼,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任俄烁,我火速辦了婚禮绸栅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘页屠。我一直安慰自己粹胯,他們只是感情好蓖柔,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著风纠,像睡著了一般况鸣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上竹观,一...
    開(kāi)封第一講書(shū)人閱讀 51,624評(píng)論 1 305
  • 那天镐捧,我揣著相機(jī)與錄音,去河邊找鬼臭增。 笑死懂酱,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的誊抛。 我是一名探鬼主播列牺,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼拗窃!你這毒婦竟也來(lái)了瞎领?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤并炮,失蹤者是張志新(化名)和其女友劉穎默刚,沒(méi)想到半個(gè)月后甥郑,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體逃魄,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年澜搅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了伍俘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡勉躺,死狀恐怖癌瘾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情饵溅,我是刑警寧澤妨退,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站蜕企,受9級(jí)特大地震影響咬荷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜轻掩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一幸乒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧唇牧,春花似錦罕扎、人聲如沸聚唐。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)杆查。三九已至,卻和暖如春臀蛛,著一層夾襖步出監(jiān)牢的瞬間根灯,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工掺栅, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留烙肺,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓氧卧,卻偏偏與公主長(zhǎng)得像桃笙,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子沙绝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

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