轉載請註明文章出處和作者!
出處:http://blog.csdn.net/xl19862005
作者:大熊(Xandy)
一、前言
之前一直都在部落格園混(地址:http://www.cnblogs.com/xl19862005),最近才搬家至CSDN,由於前幾個月剛換新工作,好久沒有更新部落格了,抱歉!
今天要和大家分享一個本人最近研發的完全具有自主智慧財產權的項目——android音頻口通訊,並尋求有興趣的同行和友人一起合作!
大家都知道拉卡拉,但它具體的技術實現我相信很少有人能說出來個一二,本人也正是抱著遇見問題勇往直前的技術男的精神,花了一兩個月的時間,完全摸透並已初步實現了用android手機的音頻口(耳機輸出輸入)來實現全雙工系統的通訊,一但通訊協定建立了,下面好玩的東西就多了!!
你可以完全不再用擔心你家的電視或者空調等此類用紅外遙控的電器一時找不到遙控器而煩惱了,加上我現在研發的音頻口擴充頭,將其插入你的android手機的耳機口,裝上特製的APP,你將可以用它來遙控你家的任何帶紅外遙控功能的電器!
你也可以拋開目前那種單調的耳機口防塵塞,加上相應的擴充頭,你將可以即時知道你周圍環境的溫度、濕度等等指標……
諸如此類的運用,數不勝數,在這裡我就不一一列舉了,下面轉入我們的正題吧(^_^不好意思,閑話說多啦,哈哈……)
二、通訊建立的基礎——耳機線上傳輸的訊號
我們知道,耳機是用來聽音樂,打電話的,既然是和聲音相關的,那麼耳機線上傳輸的就是音頻訊號,常見的音頻訊號一般都是在100Hz——10KHz左右的範圍內,那麼手機裡面的音訊輸出系統(DA和音頻功放)的幅頻特性(也既頻寬)一定也是在這個範圍(這是本人的猜想,由於裝置和儀器有限,沒有進行系統的測試,有興趣的朋友可以用相關的測試儀器測測),那麼,既然有頻寬,好傢夥,我們就可以通過努力在這個頻帶內實現我們的通訊通道了!另外值得提的一點是,耳機線上傳輸的音頻訊號是交流的!
下面我們來看看市面上常見的耳機座(公頭)的引腳定義,android手機上用的耳機大多都是3.5mm的四芯座,在這四個芯中,分別是:地、左聲道、右聲道和線控開關(MIC),而這四芯的排列常見的有如下兩種:
1、國家標準
2、國際標準
國際標準耳機座MIC和GND和國內標準是反的,其它的一樣!
不難發現有了左右聲道,向外設擴充頭供電和發送資料就有了相應通訊線路的支援,另外有了MIC這個打電話時輸入說話的訊號通道,那麼手機接收資料也有了硬體通道的支援了!
三、如何調製資料
說到訊號的調製解調,很多人都會想到收音機,沒錯,收音機之所以能聽到千裡之外的歌聲,正是利用了電磁波作為傳輸媒介,將聲源的訊號通過特定的調製載入到電磁波上,然後傳輸到廣闊的空間裡的,無線電的調製有調幅(AM)、調頻(FM)和調相(PM)三種,而調製又有類比調製和數字調製之分,類比調製就是把類比訊號(比如人說話的聲音)直接載入到電磁波上,使得電磁波的某一特性隨著聲源的變化而變化;而數字調製是近現才發展起來的,特別是DSP(沒錯,就是數字訊號處理)技術的發展,數字調製中的FM有2FSK(2進位調製)、4FSK(4進位調製)、8FSK(8進位調製)等等。
由於在數字系統中,使用的是0、1表示的位元據,在這裡,我使用了2FSK來作為訊號的調製。
3.1 何為2FSK
2FSK按字面的英語全稱是:2(binary system) Frequency-shift keying(二進位頻移鍵控),就是用二進位裡的0、1來控制載波的頻率,從而達到通訊的目的!例如:我們用1ms長、1KHz的正弦訊號來代表二進位裡的1;用1ms長、2KHz的正弦來代表二進位裡的0;那一連串的1KHz、2KHz的訊號解調出來就是一連串的0和1,這樣是不是達到了我們想要的二進位調製的目的了?
下面我們來看一張更加形像的gif動畫圖
3.2 android下實現2FSK(純軟體調製)
要實現2FSK,首先我們得在android系統下面獲得一個基準的正弦訊號發生器,有了這個基準的正弦訊號發生器,只要給它一個二進位量(0 or 1),就可改變輸出頻率,從而達到我們想要的訊號調製目的。
下面直接了,經過調製後的訊號輸出波形圖:(黃色的是實際輸出波型、紅色方波是我後來P上去的對應位元據)
這是我定義的通訊協定頭的一部分是:0x5AA5
3.3 android下音頻播放相關
android下音頻播放的基本步驟如下:
①擷取對應音頻採樣率下的最小緩衝區的大小
public static int pwMinBufferSize = AudioTrack.getMinBufferSize(EncoderCore.getPowerSupplySamplerate(),AudioFormat.CHANNEL_OUT_STEREO,AudioFormat.ENCODING_PCM_8BIT);
②建立AudioTrack
AudioTrack pwAT = new AudioTrack(AudioManager.STREAM_MUSIC,EncoderCore.getPowerSupplySamplerate(),AudioFormat.CHANNEL_OUT_MONO,AudioFormat.ENCODING_PCM_8BIT, pwMinBufferSize*2,AudioTrack.MODE_STATIC);
③將緩衝區中的音頻資料寫入音頻播放線程並設定左右聲道音量等
pwAT.write(carrierSignal, 0, EncoderCore.getPowerSupplyBufferSize());//寫入音頻資料 pwAT.flush();//重新整理pwAT.setStereoVolume(1, 0);//設定左右聲道播放音量pwAT.setLoopPoints(0, EncoderCore.getPowerSupplyBufferSize(), -1);//設定音頻播放迴圈點 pwAT.play();//開始播放
這部分代碼是左聲道對外部擴充頭進行供電的,所以要設定迴圈播放,如果是發送訊息就不必迴圈了!
訊號的調製就到這裡,下一節將分享2FSK訊號的解調。
樣本源碼:http://download.csdn.net/detail/xl19862005/5016843
最新變種版調製解調 apk
http://download.csdn.net/download/xl19862005/5333232