iOS開發(fā)之音頻口通信-通過方波來收發(fā)數(shù)據(jù)

之前做過的項(xiàng)目有需要通過音頻口通信用方波來收發(fā)數(shù)據(jù)帅腌,由于這方面的資料比較少枉圃,下面就介紹下其原理,希望能給大家?guī)椭?/p>

一. 音頻通信簡介
大家應(yīng)該都知道支付寶聲波支付和拉卡拉吧齐帚,它們都是利用手機(jī)的音頻口(手機(jī)耳機(jī)口)來實(shí)現(xiàn)全雙工的通信(手機(jī)與設(shè)備之間的雙向通信)。其優(yōu)點(diǎn)是低成本彼哼,編碼芯片成本低对妄,手機(jī)的 3.5mm 通信接口廣泛。

二. 市場應(yīng)用
支付寶聲波支付
手機(jī)刷卡器
皮膚檢測儀
檢測如甲醛沪羔、氣壓、溫度象浑、濕度等等
心率蔫饰、血壓等等
.......................


三. 通信原理
手機(jī)上用的耳機(jī)大多都是3.5mm的四芯座,在這四個(gè)芯中愉豺,分別是:地(GND)篓吁、左聲道(L)、右聲道(R)和線控開關(guān)(MIC)蚪拦。
左右聲道作用:向外設(shè)擴(kuò)展頭供電和發(fā)送數(shù)據(jù)
MIC作用:接收數(shù)據(jù)
市場上耳機(jī)主要有兩種標(biāo)準(zhǔn):國內(nèi)標(biāo)準(zhǔn)(如下圖所示)杖剪,國際標(biāo)準(zhǔn)(MIC和GND和國內(nèi)標(biāo)準(zhǔn)是反的,其他一樣)


國內(nèi)標(biāo)準(zhǔn)

聲音波形調(diào)制有調(diào)幅(AM)驰贷、調(diào)頻(FM)和調(diào)相(PM)三種盛嘿,而調(diào)制又有模擬調(diào)制和數(shù)字調(diào)制之分。(模擬調(diào)制和數(shù)字調(diào)制基本知識(shí)參考來源)

模擬調(diào)制:這種編碼方式是將數(shù)字?jǐn)?shù)據(jù)調(diào)制成模擬信號進(jìn)行傳輸括袒。通常采用三種模擬信號的載波特性(振幅次兆、頻率和相位)之一來表示被調(diào)制的數(shù)字?jǐn)?shù)據(jù),并由此產(chǎn)生三種基本調(diào)制方式锹锰。

模擬信號三種調(diào)制方式

(1) 幅移鍵控(ASK)法

ASK(Amplitude Shift Keying)是使用載波頻率的兩個(gè)不同振幅來表示兩個(gè)二進(jìn)制值芥炭。在一般情況下,用振幅恒定載波的存在與否來表示兩個(gè)二進(jìn)制字恃慧。ASK方式的編碼效率較低园蝠,容易受增益變化的影響,抗干擾性較差痢士。在音頻電話線路上彪薛,一般只能達(dá)到 1200 b/s的傳輸速率。

(2) 頻移鍵控(FSK)法

FSK(Frequency Shift Keying)是使用載波頻率附近的兩個(gè)不同頻率來表示兩個(gè)二進(jìn)制值怠蹂。FSK比ASK的編碼效率高陪汽,不易受干擾的影響,抗干擾性較強(qiáng)褥蚯。在音頻電話線路上的傳輸速率可以大于1 200 b/s挚冤。

(3) 相移鍵控(PSK)法

PSK(Phase Shift Keying)是使用載波信號的相位移動(dòng)來表示二進(jìn)制數(shù)據(jù)。在PSK方式中赞庶,信號相位與前面信號序列同相位的信號表示 0训挡,信號相位與前面信號序列反相位的信號表示 1澳骤。PSK方式也可以用于多相的調(diào)制,例如在四相調(diào)制中可把每個(gè)信號序列編碼為兩位澜薄。PSK方式具有很強(qiáng)的抗干擾能力为肮,其編碼效率比FSK還要高。在音頻線路上肤京,傳輸速率可達(dá) 9600b/s颊艳。
這些信號調(diào)制技術(shù)主要用于調(diào)制解調(diào)器(Modem)中。在實(shí)際的Modem中忘分,一般將這些基本的調(diào)制技術(shù)組合起來使用棋枕,以增強(qiáng)抗干擾能力和編碼效率。常見的組合是PSK和FSK方式的組合或者PSK和ASK方式的組合妒峦。

數(shù)字信號編碼: 對于傳輸數(shù)字信號來說重斑,最簡單的信號編碼方法是用信號的兩個(gè)不同電壓值來表示兩個(gè)二進(jìn)制數(shù)據(jù)。例如肯骇,用無電壓來表示 0窥浪,用恒定的正電壓表示 1;也可用正電壓表示 1笛丙,而用負(fù)電壓表示 0漾脂。然而,為了提高信號抗干擾能力胚鸯,并且便于信號接收同步符相,通常采用更為有效的信號編碼方法。

常用的數(shù)字信號編碼有不歸零 NRZ (Non Return to Zero)碼蠢琳、差分不歸零DNRZ 碼啊终、曼徹斯特(Manchester)碼及差分曼徹斯特(Differential Manchester)碼等。

(1) NRZ碼

NRZ碼是用信號的幅度來表示二進(jìn)制數(shù)據(jù)的傲须,通常用正電壓表示數(shù)據(jù)“1”蓝牲,用負(fù)電壓表示數(shù)據(jù)“0”,并且在表示一個(gè)碼元時(shí)泰讽,電壓均無需回到零例衍,故稱不歸零碼。NRZ碼的特點(diǎn)是一種全寬碼已卸,即一位碼元占一個(gè)單位脈沖的寬度佛玄。全寬碼的優(yōu)點(diǎn):一是每個(gè)脈沖寬度越大,發(fā)送信號的能量就越大這對于提高接收端的信噪比有利累澡;二是脈沖時(shí)間寬度與傳輸帶寬成反比關(guān)系梦抢,即全寬碼在信道上占用較窄的頻帶,并且在頻譜中包含了碼位的速度愧哟。

NRZ碼的主要缺點(diǎn)是:當(dāng)數(shù)據(jù)流中連續(xù)出現(xiàn)0 或1時(shí)奥吩,接收端很難以分辨1個(gè)信號位的開始或結(jié)束哼蛆,必須采用某種方法在發(fā)送端和接收端之間提供必要的信號定時(shí)同步。同時(shí)霞赫,這種編碼還會(huì)產(chǎn)生直流分量的積累問題腮介,這將導(dǎo)致信號的失真與畸變,使傳輸?shù)目煽啃越档投怂ィ⑶矣捎谥绷鞣至康拇嬖诘矗沟脽o法使用一些交流耦合的線路和設(shè)備。因此旅东,一般的數(shù)據(jù)傳輸系統(tǒng)都不采用這種編碼方式灭抑。

(2) DNRZ碼

DNRZ碼是一種NRZ碼的改進(jìn)形式,它是用信號的相位變化來表示二進(jìn)制數(shù)據(jù)的玉锌,一個(gè)信號位的起始處有跳變表示數(shù)據(jù)“1”名挥,而無跳變表示數(shù)據(jù)“0”疟羹。DNRZ碼不僅保持了全寬碼的優(yōu)點(diǎn)主守,同時(shí)提高了信號的抗干擾性和易同步性。

近年來榄融,越來越多的高速網(wǎng)絡(luò)系統(tǒng)采用了DNRZ碼参淫,成為主流的信號編碼技術(shù),在FDDI愧杯、100BASE-T及100VG-AnyLAN等高速網(wǎng)絡(luò)中都采用了DNRZ編碼涎才。其原因是在高速網(wǎng)絡(luò)中要求盡量降低信號的傳輸帶寬,以利于提高傳輸?shù)目煽啃院徒档蛯鬏斀橘|(zhì)帶寬的要求力九。而DNRZ編碼中的碼元速率與編碼時(shí)鐘速率相一致耍铜,具有很高的編碼效率,符合高速網(wǎng)絡(luò)對信號編碼的要求跌前。同時(shí)棕兼,為了解決數(shù)據(jù)流中連續(xù)出現(xiàn)0 或1時(shí)所帶來的信號編碼問題,通常采用兩級編碼方案抵乓,第一級是預(yù)編碼器伴挚,對數(shù)據(jù)流進(jìn)行預(yù)編碼,使編碼后的數(shù)據(jù)流不會(huì)出現(xiàn)連續(xù) 0 或連續(xù) 1灾炭,常用的預(yù)編碼方法有4B5B茎芋、5B6B等;第二級是DNRZ編碼蜈出,實(shí)現(xiàn)物理信號的傳輸田弥。這種兩級編碼方案的編碼效率可達(dá)到 80%以上。例如铡原,在4B5B編碼中皱蹦,每4位數(shù)據(jù)用5位編碼來表示煤杀,即4位數(shù)據(jù)就會(huì)增加 1 位的編碼開銷,編碼效率仍為80%沪哺。

(3) 曼徹斯特碼

在曼徹斯特碼中沈自,用一個(gè)信號碼元中間電壓跳變的相位不同來區(qū)分?jǐn)?shù)據(jù)“1”和“0”,它用正的電壓跳變表示“0”辜妓;用負(fù)的電壓跳變表示“1”枯途。因此,這種編碼也是一種相位碼籍滴。由于電壓跳變都發(fā)生在每一個(gè)碼元的中間酪夷,接收端可以方便地利用它作為位同步時(shí)鐘,因此這種編碼也稱為自同步碼孽惰。10Mb/s 以太網(wǎng)(Ethernet)采用這種曼徹斯特碼晚岭。

(4) 差分曼徹斯特碼

差分曼徹斯特碼是一種曼徹斯特碼的改進(jìn)形式,其差別在于:每個(gè)碼元的中間跳變只作為同步時(shí)鐘信號勋功;而數(shù)據(jù)“0”和“1”的取值是用信號位的起始處有無跳變來表示坦报,若有跳變則為“0”;若無跳變則為“1”狂鞋。這種編碼的特點(diǎn)是每一位均用不同電平的兩個(gè)半位來表示片择,因而始終能保持直流的平衡。這種編碼也是一種自同步編碼骚揍。
令牌環(huán)(Token-Ring)網(wǎng)采用這種差分曼徹斯特編碼字管。

這兩種曼徹斯特編碼主要用于中速網(wǎng)絡(luò)(Ethernet為 10 Mb/s;Token-Ring最高為16 Mb/s)中信不,而高速網(wǎng)絡(luò)并不采用曼徹斯特編碼技術(shù)嘲叔。其原因是它的信號速率為數(shù)據(jù)速率的兩倍,即對于 10 Mb/s的數(shù)據(jù)速率抽活,則編碼后的信號速率為 20 Mb/s硫戈,編碼的有效率為 50%。對于 100 Mb/s的高速網(wǎng)絡(luò)來說酌壕,200 Mb/s的信號速率無論對傳輸介質(zhì)的帶寬的要求掏愁,還是對傳輸可靠性的控制都未免太高了,將會(huì)增加信號傳輸技術(shù)的復(fù)雜性和實(shí)現(xiàn)成本卵牍,難以推廣應(yīng)用果港。因此,高速網(wǎng)絡(luò)主要采用兩級的DNRZ編碼方案糊昙,而中速網(wǎng)絡(luò)采用曼徹斯特編碼方案辛掠,盡管它增加了傳輸所需的帶寬,但在實(shí)現(xiàn)起來簡單易行。

要實(shí)現(xiàn)手機(jī)端和擴(kuò)展頭的全雙工通信萝衩,必須滿足2個(gè)條件:1.信號必須在音頻頻率之內(nèi)回挽;2.需要是低功耗的。第一個(gè)條件限制了信號帶寬猩谊,第二個(gè)條件限制了成本和功率千劈。在這2種限制條件下,主要有2種方式實(shí)現(xiàn)這種同時(shí)的雙向通信:FSK調(diào)制和基于曼徹斯特編碼的直接數(shù)字通信牌捷。

這里主要講解下通過數(shù)字調(diào)制中的FSK調(diào)頻調(diào)制方波墙牌。FSK有2FSK(2進(jìn)制調(diào)制)、4FSK(4進(jìn)制調(diào)制)暗甥、8FSK(8進(jìn)制調(diào)制)等等喜滨。

由于在數(shù)字系統(tǒng)中,使用的是0撤防、1表示的二進(jìn)制數(shù)據(jù)虽风,在這里,我使用了2FSK來作為信號的調(diào)制寄月。

2FSK調(diào)頻調(diào)制方波的原理:用一個(gè)頻率表示1辜膝,另一個(gè)不同的頻率表示0。比如使用613Hz的信號代表0剥懒,1226Hz的信號代表1内舟。如下圖所示


方波可以用Cool Edit Pro工具生成合敦,方便調(diào)試和研究初橘。具體方法是:
打開工具,新建文件充岛,然后會(huì)彈出下面窗口


   這里根據(jù)你需求設(shè)置波形的采樣率保檐,聲道和采樣精度(一般是44100HZ,單聲道崔梗,16位采樣精度)

接下來選擇菜單項(xiàng)-生成

你會(huì)看到如下界面夜只,這里可以通過設(shè)置不同頻率和設(shè)置調(diào)味為方波生成波形了


方波

那么在iOS下如何接收方波解析和發(fā)送方波咧?

每段波形其實(shí)是由N(N=采樣率/位持續(xù)時(shí)間(每位數(shù)據(jù)頻率))個(gè)有符號的數(shù)據(jù)點(diǎn)組成蒜魄,這些有正有負(fù)的數(shù)組成了一段段波形,比如波形0則有N個(gè)127組成的波峰波形或者N個(gè)-128組成的波底波形扔亥,而波形1則有N/2個(gè)波峰+N/2個(gè)波低組成,這個(gè)波峰波底具體數(shù)值定義可自已靈活定義谈为,如下圖所示

波形組成原理

舉個(gè)例子:比如發(fā)送個(gè)數(shù)據(jù)5旅挤,其二進(jìn)制數(shù)據(jù)為0000 0101 ,這里設(shè)置采樣率為44100HZ,每段波形時(shí)間頻率1000HZ伞鲫,定義波形為0 波峰上全是44個(gè)127粘茄,波形為0 波底上全是44個(gè)-128,波形為1的數(shù)據(jù) 半個(gè) 波峰上全是44/2個(gè)127,半個(gè) 波底上全是44/2個(gè)-128,那么5 生成波形的數(shù)據(jù)就是 0(44個(gè)127) 0 (44個(gè)-128) 0(44個(gè)127) 0 (44個(gè)-128) 0(44個(gè)127)1(44/2個(gè)-128+44/2個(gè)127)0(44個(gè)-128)1(44個(gè)127)柒瓣。知道這個(gè)原理了方波解析和發(fā)送數(shù)據(jù)就簡單了儒搭。

音頻使用的基本步驟如下:

1.設(shè)置音頻格式和采樣率

mAudioFormat.mSampleRate=AUDIO_SAMPLE_RATE;//采樣率
mAudioFormat.mFormatID=kAudioFormatLinearPCM;//PCM格式
mAudioFormat.mFormatFlags        = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
mAudioFormat.mFramesPerPacket    = 1;//每個(gè)數(shù)據(jù)包多少幀
mAudioFormat.mChannelsPerFrame   = kChannels/2;//1單聲道,2立體聲
mAudioFormat.mBitsPerChannel     = 16;//語音每采樣點(diǎn)占用位數(shù)
mAudioFormat.mBytesPerFrame      = mAudioFormat.mBitsPerChannel*mAudioFormat.mChannelsPerFrame/8;//每幀的bytes數(shù)
mAudioFormat.mBytesPerPacket     = mAudioFormat.mBytesPerFrame*mAudioFormat.mFramesPerPacket;//每個(gè)數(shù)據(jù)包的bytes總數(shù)芙贫,每幀的bytes數(shù)*每個(gè)數(shù)據(jù)包的幀數(shù)
mAudioFormat.mReserved           = 0;

2.設(shè)置remote io unit的渲染回調(diào),從輸入硬件獲得采樣傳入到回調(diào)函數(shù)進(jìn)行渲染,從而獲得錄音數(shù)據(jù)解析數(shù)據(jù). 向回調(diào)函數(shù)填數(shù)據(jù),從而向輸出硬件提供數(shù)據(jù)進(jìn)行放音發(fā)送數(shù)據(jù).
CheckError(AudioUnitSetProperty(toneUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, disable, &mAudioFormat, sizeof(mAudioFormat)), "couldn't set the remote I/O unit's output client format");
CheckError(AudioUnitSetProperty(toneUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, enable, &mAudioFormat, sizeof(mAudioFormat)), "couldn't set the remote I/O unit's input client format");

回調(diào)函數(shù)OSStatus RenderTone(
                void *inRefCon,
                AudioUnitRenderActionFlags  *ioActionFlags,
                const AudioTimeStamp        *inTimeStamp,
                UInt32                      inBusNumber,
                UInt32                      inNumberFrames,
                AudioBufferList             *ioData)搂鲫;通過這個(gè)回調(diào)函數(shù)就可以發(fā)送數(shù)據(jù)和解析數(shù)據(jù)

數(shù)據(jù)編碼發(fā)送具體代碼可參考demo里,知道了編碼原理磺平,解碼對你來說就簡單了

參考文檔:
http://blog.csdn.net/it1988888/article/details/9073767
http://www.seeedstudio.com/wiki/index.php?title=Hijack
http://blog.csdn.net/xiejx618/article/details/9790709

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末默穴,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子褪秀,更是在濱河造成了極大的恐慌蓄诽,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件媒吗,死亡現(xiàn)場離奇詭異仑氛,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)闸英,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進(jìn)店門锯岖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人甫何,你說我怎么就攤上這事出吹。” “怎么了辙喂?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵捶牢,是天一觀的道長。 經(jīng)常有香客問我巍耗,道長秋麸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任炬太,我火速辦了婚禮灸蟆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘亲族。我一直安慰自己炒考,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布霎迫。 她就那樣靜靜地躺著斋枢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪女气。 梳的紋絲不亂的頭發(fā)上杏慰,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼缘滥。 笑死轰胁,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的朝扼。 我是一名探鬼主播赃阀,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼擎颖!你這毒婦竟也來了榛斯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤搂捧,失蹤者是張志新(化名)和其女友劉穎驮俗,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體允跑,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡王凑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了聋丝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片索烹。...
    茶點(diǎn)故事閱讀 39,688評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖弱睦,靈堂內(nèi)的尸體忽然破棺而出百姓,到底是詐尸還是另有隱情,我是刑警寧澤况木,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布垒拢,位于F島的核電站,受9級特大地震影響焦读,放射性物質(zhì)發(fā)生泄漏子库。R本人自食惡果不足惜舱权,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一矗晃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧宴倍,春花似錦张症、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至阔逼,卻和暖如春兆衅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工羡亩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留摩疑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓畏铆,卻偏偏與公主長得像雷袋,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子辞居,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評論 2 353

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