您好,登錄后才能下訂單哦!
前一段時間為了實現(xiàn)聲波傳輸,網(wǎng)上找了半天,好不容易找到一個實現(xiàn),但準(zhǔn)確性遠(yuǎn)不能滿足要求,沒辦法,只好自己寫了一個。
后來一哥們要求在mipsel平臺和arm平臺上使用,就幫他用c移植到了mipsel平臺,實現(xiàn)了在不到普通電腦千分之一cpu的系統(tǒng)平臺上的運行。搞定這個后cpu消耗非常低,基本上應(yīng)該算是沒有運行不了的平臺了。
準(zhǔn)確性95%以上,如果有識別有問題的情況,你可以開啟調(diào)試模式,該模式下會自動保存識別失敗的的音頻段,你可以發(fā)給我分析識別失敗的原因,如果真是識別器沒有考慮到的情況的話,調(diào)整識別規(guī)則就可以完善識別到了。而且傳輸中加入了校驗碼,校驗碼有兩個目的,一個是保證識別正確性。保證識別結(jié)果不然就識別失敗,而如果識別到了就一定是對的,也就是說不會出現(xiàn)傳輸?shù)氖?,而識別提示為0;另一個是錯誤自動修正,從而保證傳輸中可以有20%左右(取決于你傳輸?shù)臄?shù)據(jù)長度)的錯誤而可以自動修正,從而使得使用過程中基本上識別是不會出錯的。識別接口中參數(shù)指定了識別是否成功完成,錯誤碼指出了如果識別失敗的話,失敗的原因。
我的接口盡量做得簡單,這樣用起來也比較小白,既然是當(dāng)成一個庫,使用起來越簡單越好,就盡量不要去管底層的一些控制參數(shù),比如說聲音采樣頻率、采樣精度、采樣格式、傳輸頻率、傳輸碼表、音量、緩沖區(qū)大小,這些在參數(shù)中你就不用管了,當(dāng)然你想定制的話其實這些參數(shù)也全部是都是可以定制的。在這里,這些參數(shù)的默認(rèn)值我也說一下:聲音方面默認(rèn)參數(shù)為:聲音采樣頻率為44100,單聲道,2個字節(jié)(16位)長的采樣精度,小端編碼,楨大小就為1*2=2個字節(jié),那么每秒處理的數(shù)據(jù)量就是44100*2=88200字節(jié)。傳輸頻率為高頻段,抗干擾能力非常好,不管你是在鬧市、馬路、×××、或者其它室外場景下,或者你在家里開著大音箱聽歌都不會影響到數(shù)據(jù)的傳輸。碼表為16進(jìn)制的數(shù)據(jù)編碼,也就是所有數(shù)據(jù)都會編成16進(jìn)制后傳輸。緩沖區(qū)的話默認(rèn)需10k左右的緩沖區(qū)(里面其它的內(nèi)存分配都在內(nèi)存池中完成,長時間運行解碼不會再分配內(nèi)存)。如果這些參數(shù)你完全不懂,就忽略就算了,因為接口足夠簡單,能用就可以了,也不用理解那么多原理。不過×××要求你傳入的音頻數(shù)據(jù)是這些格式,特別是輸入數(shù)據(jù)要求為44100,單聲道,16bits采樣精度,小端編碼的音頻數(shù)據(jù)。
另外實際上因為傳輸頻率屬于高頻段,開始超出正常人可聽到的階段,所以發(fā)送的時候感覺沒什么反應(yīng)一樣,所以可以在人耳可聽到的范圍另外加一段可聽到的音頻音效(咻咻咻、啾啾啾隨便你,呵呵)讓用戶知道系統(tǒng)正在通訊中,最后的效果就是人聽到的是人耳可聽到那部分你加的音頻音效,可實際上設(shè)備則可解碼出真正的信號,而不會相互干擾。
傳輸距離的話是取決于音量的,音量比較大的,傳輸距離就大,一般以手機的最大音量5-10米沒問題,音量設(shè)小的話可以控制在10cm-30cm左右。
至于性能,系統(tǒng)有兩種工作模式:一種是優(yōu)化內(nèi)存模式,耗CPU稍多一點,但耗內(nèi)存小,在當(dāng)前正常使用的電腦或者現(xiàn)在的智能手機下使用是沒有問題的,正常pc機的cpu基于可以看到在1%以下,反正windows任務(wù)管理器里顯示的是0,應(yīng)該是1%以下就會顯示為0%,估計在百分之零點幾左右吧。另一種是優(yōu)化CPU模式,如果你是在計算能力非常有限的平臺上使用,比如說計算能力不到pc千分之一的平臺上使用,你可以使用這種模式,這種模式下,基本不會占用你的CPU,但會占內(nèi)存會大一些,但如果你的CPU真的非常慢,你解碼時間會長一點,但無論你的系統(tǒng)有多慢,都不會解不出來,也不會影響解碼正確性,只是速度慢的話解碼出來的時間就稍長一些。
說一說傳輸數(shù)據(jù)量的問題,首先我要說一下,我最先了解聲波通訊的時候還以為傳輸率可以達(dá)到幾k/秒,實際上聲波1秒也就傳輸個十幾個字符左右,而且一般來說傳輸總字符如果達(dá)到40個以上,解碼正確率就會下降,數(shù)據(jù)量越大,出錯率就會升高。所以想以k級來傳輸數(shù)據(jù)量的人就不要想了。當(dāng)然這也是對怎么使用聲波通訊的機制不了解的原因:聲波傳輸使用時主要是作為握手和對接使用,真正的數(shù)據(jù)是通過對接后在互聯(lián)網(wǎng)上傳輸。比如說面對面的聲波支付,A要付款給B,那么聲波通訊在這里面主要是傳輸用戶標(biāo)志,或者付款單編號來快速握手(這當(dāng)然跟你設(shè)計的支付流程有關(guān))。我這里以一種模擬刷卡的流程舉例說明:A(客戶)要付款給B(商家),我們設(shè)想如果是刷卡的話,流程可能是這樣的,A(客戶)在B(商家)的POS機上刷一下銀行卡,B(商家)就知道A(客戶)是哪張銀行卡,從而把該卡和金額傳到支付公司去扣款。那么換成聲波后也是一樣的,A(客戶)在手機上點一下付款,A(客戶)的手機發(fā)出一串聲波,聲波上傳輸A(客戶)的用戶標(biāo)識,傳到B(商家)的手機,這時B(商家)就可以把A(客戶)的標(biāo)志和扣款金額傳到支付公司去扣款了。當(dāng)然你也可以設(shè)計一個反過來的流程,就是由B端(商家端)發(fā)出一串賬單音頻,而由A端接收(客戶關(guān)),但原理是一樣的。所以在這整個流程里面,聲波是做系統(tǒng)對接使用的,替代刷銀行卡、或者掃二維碼的對接方式,然后真正的數(shù)據(jù)傳輸還是在互聯(lián)網(wǎng)上傳輸。
我這里采用的是16進(jìn)制的傳輸碼,你自己要傳輸?shù)男畔⒖梢宰约合染幊?6進(jìn)制碼,不過碼表其實是可以定制的,比如說你想傳輸數(shù)據(jù)量更大一點,那也可以擴展到32進(jìn)制,這樣相對來說傳輸數(shù)據(jù)量編碼后會更小,數(shù)據(jù)量可以傳輸?shù)酶笠恍?。如果你要傳輸?shù)氖菙?shù)字,先把數(shù)字編成16進(jìn)制編碼,如果你要傳字母,那么一個字母可以編成2個16進(jìn)制的字符。
我這里列出幾種編碼的情況,比如說你要傳輸QQ號,手機號這類數(shù)字,那就最好轉(zhuǎn)成16進(jìn)制后再傳輸。以傳輸手機號為例:因為手機號肯定是以1開始的,那么1就可以不傳了,而且都是以13,15,18開頭,那么你可以把3,5,8先映射為1,2,3,然后再做16進(jìn)制轉(zhuǎn)碼。當(dāng)然解碼端你自己怎么做的編碼就怎么做解碼,這樣一個手機號本來有11位,優(yōu)化下來就可以做到9位,或者8位。呵呵,聲波傳輸就是要做到盡量小的數(shù)據(jù)量,數(shù)據(jù)量越小傳輸準(zhǔn)確率就越可靠,你的系統(tǒng)就越可靠。
我這里列出幾種編碼的示例。
手機號編成16進(jìn)制聲波通訊編碼:
[java] view plaincopy
/************************************************************************
聲波通訊庫示例,16進(jìn)制聲波通訊編碼
聲波通訊庫特征:
準(zhǔn)確性95%以上,其實一般是不會出錯的。
接口非常簡單,有完整的示例,3分鐘就可以讓你的應(yīng)用增加聲波通訊功能
抗干擾性強,基本上無論外界怎么干擾,信號都是準(zhǔn)確的
基本的編碼為16進(jìn)制,而通過編碼可傳輸任何字符
性能非常強,沒有運行不了的平臺,而且通過內(nèi)存池優(yōu)化,長時間解碼不再分配新內(nèi)存,可7*24小時運行
可支持任何平臺,常見的平臺android, iphone, windows, linux, arm, mipsel都有示例
詳情可查看:http://blog.csdn.net/softlgh
作者: 夜行俠 QQ:3116009971 郵件:3116009971@qq.com
************************************************************************/
//13,14,15,18開頭的手機號,手機號去除1以后,16進(jìn)制在9位以內(nèi)
public static String encode(String _mobile)
{
if(_mobile.length() == 11 && _mobile.startsWith("1"))
{
long _number = Long.parseLong(_mobile.substring(1));
String s = Long.toHexString(_number);
while(s.length() < 9)
{
s = "0" + s;
}
return s;
}
return null;
}
任意字符串(先換成byte[])編成16進(jìn)制聲波通訊編碼:
[java] view plaincopy
/************************************************************************
聲波通訊庫示例,16進(jìn)制聲波通訊編碼
聲波通訊庫特征:
準(zhǔn)確性95%以上,其實一般是不會出錯的。
接口非常簡單,有完整的示例,3分鐘就可以讓你的應(yīng)用增加聲波通訊功能
抗干擾性強,基本上無論外界怎么干擾,信號都是準(zhǔn)確的
基本的編碼為16進(jìn)制,而通過編碼可傳輸任何字符
性能非常強,沒有運行不了的平臺,而且通過內(nèi)存池優(yōu)化,長時間解碼不再分配新內(nèi)存,可7*24小時運行
可支持任何平臺,常見的平臺android, iphone, windows, linux, arm, mipsel都有示例
詳情可查看:http://blog.csdn.net/softlgh
作者: 夜行俠 QQ:3116009971 郵件:3116009971@qq.com
************************************************************************/
public static final char[] hexChars = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
public static String encodeString(byte[] _val)
{
StringBuffer result = new StringBuffer(_val.length*2);
for(int i = 0; i < _val.length; i ++)
{
result.append(hexChars[(_val[i] >> 4) & 0x0f]);
result.append(hexChars[_val[i] & 0x0f]);
}
return result.toString();
}
這里也把現(xiàn)在市場上的一些應(yīng)用到了聲波的先列一下:支付寶的聲波支付,微信的聲波雷達(dá)加好友,QQ音樂中的歌曲的聲波分享,茄子快傳,蛐蛐兒等等,國外的apple,google對聲波通訊也都有應(yīng)用。
聲波實際上可以看成是一種比二維碼可友好的傳輸方式,二維碼能實現(xiàn)的功能與聲波有很大的相似性,但聲波使用時會更友好。做以上這些功能的時候,基本上都是只要靠近在手機上點一下/劃一下/推一下/甩一下/搖一下(這是你自己定的)就可以了,而不需要像二維碼一樣還要打開攝像頭、對準(zhǔn)去拍那樣比較麻煩。相比來說,聲波傳輸更像刷卡一樣方便簡單,可以理解為類似NFC的一種近場通訊技術(shù)。
比如說你可以用聲波支付,聲波會員卡,聲波券票,聲音名片,聲波簽到,聲波排隊,做wifi和密碼共享或者設(shè)定,做文件/圖片、你App里面的任何項目分享,用聲波關(guān)注微博、微信等等。
聲波支付的流程前面有講過,實際上有可能稍微復(fù)雜一點,但大概是這樣的思路。
聲波會員卡是指用戶到店鋪后不需要帶物理卡了,而是手機代替了所有的會員卡,在商家一碰,會員信息就自動顯示出來了。
聲波券票也很簡單,比如說一張電子團(tuán)購券,電子電影券,可以設(shè)置成一個唯一的編碼,到場后與錄音設(shè)備一碰,系統(tǒng)就能識別到這張券票
聲波簽到是指在固定位置安裝簽到軟件,用戶到達(dá)后,可以快速完成簽到操作。
聲波分享以文件/圖片、或者你App里面的任何項目為例:比如A要把一張圖片發(fā)送給B,那么A點擊一下共享按鈕(或者一推一丟都行),這時手機通過聲音把這個圖片的編號發(fā)送出去,當(dāng)B收到這個標(biāo)志時,馬上從你平臺的服務(wù)器上下載這張圖片。最后的效果就是A在要分享的圖片上一點,B就能收到該張圖片,非常的方便快捷。
這個聲波傳輸庫可以運行在windows平臺(所有windows系統(tǒng)), linux平臺, mipsel平臺, arm平臺, iphone平臺, android平臺,全部都有SDK,后面的附件中有各個平臺的庫,你自己可以選擇下載
庫的結(jié)構(gòu)非常簡單:一個發(fā)送端,一個接收端。發(fā)送端很簡單,基本上就是一個send函數(shù)。接收端稍微復(fù)雜一點,但也是很簡單的:創(chuàng)建一個×××,設(shè)置監(jiān)聽,往×××送音頻數(shù)據(jù)(×××就會開始分析音頻數(shù)據(jù),并在監(jiān)聽到信號后通知你),最后停止×××和銷毀×××。使用還是很簡單的,下面和附件中有例子說明。
這種庫的使用畢竟是商用,所以就不能免費了,呵呵。不過如果你完全是沒有任何商業(yè)目的的公益項目,我也是完全可以免費給你用的。
試用庫識別次數(shù)有限,或者沒有進(jìn)行降噪處理
各個平臺的例子及源碼
android平臺聲波通訊發(fā)送端接口:
[java] view plaincopy
/************************************************************************
聲波通訊庫示例,android平臺聲波通訊發(fā)送端
聲波通訊庫特征:
準(zhǔn)確性95%以上,其實一般是不會出錯的。
接口非常簡單,有完整的示例,3分鐘就可以讓你的應(yīng)用增加聲波通訊功能
抗干擾性強,基本上無論外界怎么干擾,信號都是準(zhǔn)確的
基本的編碼為16進(jìn)制,而通過編碼可傳輸任何字符
性能非常強,沒有運行不了的平臺,而且通過內(nèi)存池優(yōu)化,長時間解碼不再分配新內(nèi)存,可7*24小時運行
可支持任何平臺,常見的平臺android, iphone, windows, linux, arm, mipsel都有示例
詳情可查看:http://blog.csdn.net/softlgh
作者: 夜行俠 QQ:3116009971 郵件:3116009971@qq.com
************************************************************************/
//創(chuàng)建聲波通訊播放器
player = new VoicePlayer();
//開始播放
player.play("12345678abcdef", 1, 200);
iphone平臺聲波通訊發(fā)送端接口:
[objc] view plaincopy
/************************************************************************
聲波通訊庫示例,iphone平臺聲波通訊發(fā)送端
聲波通訊庫特征:
準(zhǔn)確性95%以上,其實一般是不會出錯的。
接口非常簡單,有完整的示例,3分鐘就可以讓你的應(yīng)用增加聲波通訊功能
抗干擾性強,基本上無論外界怎么干擾,信號都是準(zhǔn)確的
基本的編碼為16進(jìn)制,而通過編碼可傳輸任何字符
性能非常強,沒有運行不了的平臺,而且通過內(nèi)存池優(yōu)化,長時間解碼不再分配新內(nèi)存,可7*24小時運行
可支持任何平臺,常見的平臺android, iphone, windows, linux, arm, mipsel都有示例
詳情可查看:http://blog.csdn.net/softlgh
作者: 夜行俠 QQ:3116009971 郵件:3116009971@qq.com
************************************************************************/
NSAutoreleasePool *tempPool = [[NSAutoreleasePool alloc] init];
//創(chuàng)建聲波通訊播放器
VoicePlayer *player=[[VoicePlayer alloc] init];
//播放
[player play:@"12345678" playCount:1 muteInterval:0];
//沒播放完之前,不要釋放內(nèi)存
while (![player isStopped]) {
usleep(3300 * 1000);//300ms
}
[tempPool drain];
Android平臺聲波通訊解碼端代碼:
[java] view plaincopy
/************************************************************************
聲波通訊庫示例,Android平臺聲波通訊解碼端
聲波通訊庫特征:
準(zhǔn)確性95%以上,其實一般是不會出錯的。
接口非常簡單,有完整的示例,3分鐘就可以讓你的應(yīng)用增加聲波通訊功能
抗干擾性強,基本上無論外界怎么干擾,信號都是準(zhǔn)確的
基本的編碼為16進(jìn)制,而通過編碼可傳輸任何字符
性能非常強,沒有運行不了的平臺,而且通過內(nèi)存池優(yōu)化,長時間解碼不再分配新內(nèi)存,可7*24小時運行
可支持任何平臺,常見的平臺android, iphone, windows, linux, arm, mipsel都有示例
詳情可查看:http://blog.csdn.net/softlgh
作者: 夜行俠 QQ:3116009971 郵件:3116009971@qq.com
************************************************************************/
VoiceRecognition mRecognition = new VoiceRecognition();
mRecognition.setListener(new VoiceRecognitionListener()
{
@Override
public void onRecognitionStart() {
}
public void onRecognitionEnd(int _recogStatus, String _val)
{
if(_recogStatus == VoiceRecognition.Status_Success)
{
System.out.println(_val);
}
}
});
mRecognition.start();
c通用聲波通訊解碼端接口
[cpp] view plaincopy
/************************************************************************
聲波通訊庫示例,聲波通訊庫c解碼接口
聲波通訊庫特征:
準(zhǔn)確性95%以上,其實一般是不會出錯的。
接口非常簡單,有完整的示例,3分鐘就可以讓你的應(yīng)用增加聲波通訊功能
抗干擾性強,基本上無論外界怎么干擾,信號都是準(zhǔn)確的
基本的編碼為16進(jìn)制,而通過編碼可傳輸任何字符
性能非常強,沒有運行不了的平臺,而且通過內(nèi)存池優(yōu)化,長時間解碼不再分配新內(nèi)存,可7*24小時運行
可支持任何平臺,常見的平臺android, iphone, windows, linux, arm, mipsel都有示例
詳情可查看:http://blog.csdn.net/softlgh
作者: 夜行俠 QQ:3116009971 郵件:3116009971@qq.com
************************************************************************/
#ifdef VOICE_RECOG_DLL
#define VOICERECOGNIZEDLL_API __declspec(dllexport)
#else
#ifdef WIN32
#define VOICERECOGNIZEDLL_API __declspec(dllimport)
#else
#define VOICERECOGNIZEDLL_API
#endif
#endif
#ifndef VOICE_RECOG_H
#define VOICE_RECOG_H
#ifdef __cplusplus
extern "C" {
#endif
enum VRErrorCode
{
VR_SUCCESS = 0
};
enum DecoderPriority
{
CPUUsePriority = 1//不占內(nèi)存,但CPU消耗比較大一些
, MemoryUsePriority = 2//不占CPU,但內(nèi)存消耗大一些
};
typedef enum {vr_false = 0, vr_true = 1} vr_bool;
typedef void (*vr_pRecognizerStartListener)(void);
//_result如果為VR_SUCCESS,則表示識別成功,否則為錯誤碼,成功的話_data才有數(shù)據(jù)
typedef void (*vr_pRecognizerEndListener)(int _result, char *_data, int _dataLen);
//創(chuàng)建聲波識別器
VOICERECOGNIZEDLL_API void *vr_createVoiceRecognizer(DecoderPriority _decoderPriority = CPUUsePriority);
//銷毀識別器
VOICERECOGNIZEDLL_API void vr_destroyVoiceRecognizer(void *_recognizer);
//設(shè)置識別到信號的監(jiān)聽器
VOICERECOGNIZEDLL_API void vr_setRecognizerListener(void *_recognizer, vr_pRecognizerStartListener _startListener, vr_pRecognizerEndListener _endListener);
//開始識別
//這里一般是線程,這個函數(shù)在停止識別之前不會返回
VOICERECOGNIZEDLL_API void vr_runRecognizer(void *_recognizer);
//停止識別,該函數(shù)調(diào)用后vr_runRecognizer會返回
//該函數(shù)只是向識別線程發(fā)出退出信號,判斷識別器是否真正已經(jīng)退出要使用以下的vr_isRecognizerStopped函數(shù)
VOICERECOGNIZEDLL_API void vr_stopRecognize(void *_recognizer);
//判斷識別器線程是否已經(jīng)退出
VOICERECOGNIZEDLL_API vr_bool vr_isRecognizerStopped(void *_recognizer);
//要求輸入數(shù)據(jù)要求為44100,單聲道,16bits采樣精度,小端編碼的音頻數(shù)據(jù)
//小端編碼不用特別處理,一般你錄到的數(shù)據(jù)都是小端編碼的
VOICERECOGNIZEDLL_API int vr_writeData(void *_recognizer, char *_data, int _dataLen);
#ifdef __cplusplus
}
#endif
#endif
使用c聲波通訊接口從wav文件中解碼的例子:
[cpp] view plaincopy
/************************************************************************
聲波通訊庫示例,從wav文件中讀取音頻信號進(jìn)行解碼,該工程示例是可跨平臺的
聲波通訊庫特征:
準(zhǔn)確性95%以上,其實一般是不會出錯的。
接口非常簡單,有完整的示例,3分鐘就可以讓你的應(yīng)用增加聲波通訊功能
抗干擾性強,基本上無論外界怎么干擾,信號都是準(zhǔn)確的
基本的編碼為16進(jìn)制,而通過編碼可傳輸任何字符
性能非常強,沒有運行不了的平臺,而且通過內(nèi)存池優(yōu)化,長時間解碼不再分配新內(nèi)存,可7*24小時運行
可支持任何平臺,常見的平臺android, iphone, windows, linux, arm, mipsel都有示例
詳情可查看:http://blog.csdn.net/softlgh
作者: 夜行俠 QQ:3116009971 郵件:3116009971@qq.com
************************************************************************/
//當(dāng)次解碼結(jié)束的回調(diào)函數(shù)
void waveRecognizerEnd(int _recogStatus, char *_data, int _dataLen)
{
if (_recogStatus == VR_SUCCESS)
{
char buf[51];
memcpy(buf, _data, _dataLen);
buf[_dataLen] = 0;
printf("------------------recognized data:%s\n", buf);
}
else
{
printf("------------------recognize invalid data, errorCode:%d\n", _recogStatus);
}
}
//識別到有信號時開始解碼回調(diào)函數(shù)
void waveRecognizerStart()
{
printf("------------------recognize start\n");
}
//WIN32與linux所需的線程函數(shù)原型有點不一樣
#ifdef WIN32
DWORD WINAPI waveRunVoiceRecognize( LPVOID _recognizer)
{
#else
void *waveRunVoiceRecognize( void * _recognizer)
{
printf("voice recognizer thread start:%d\n", getpid());
#endif
vr_runRecognizer(_recognizer);
return 0;
}
//從wav文件中裝載數(shù)據(jù)進(jìn)入聲波識別器
void test_voiceRecog_from_wav(int argc, char* argv[])
{
char *wavFile = (char *)"data.wav";
if(argc > 1)
{
wavFile = argv[1];
}
//讀入wav文件
struct WavData wavData;
memset(&wavData, 0, sizeof(wavData));
readWave(wavFile, &wavData);
printf("%s data size:%d\n", wavFile, (int)wavData.size);
//創(chuàng)建識別器,并開始運行
void *recognizer = vr_createVoiceRecognizer(MemoryUsePriority);
vr_setRecognizerListener(recognizer, waveRecognizerStart, waveRecognizerEnd);
#ifdef WIN32
HANDLE recogThread = CreateThread( NULL, 0, waveRunVoiceRecognize, recognizer, 0, 0 );
//_beginthread(waveRunVoiceRecognize, 0, recognizer);
#else
pthread_t recogThread;
pthread_create(&recogThread, NULL, waveRunVoiceRecognize, recognizer);
//printf("voice recognizer thread id:%lu\n", (recogThread));
#endif
//往識別器寫入數(shù)據(jù),這里可以反復(fù)寫
vr_writeData(recognizer, wavData.data, wavData.size);
//通知識別器停止,并等待識別器真正退出
do
{
vr_stopRecognize(recognizer);
printf("recognizer is quiting\n");
#ifdef WIN32
Sleep(1000);
#else
sleep(1);
#endif
} while (!vr_isRecognizerStopped(recognizer));
//銷毀識別器
vr_destroyVoiceRecognizer(recognizer);
printf("press enter key to exit.......\n");
char c;
scanf("%c", &c);
}
使用c聲波通訊接口從實時錄音數(shù)據(jù)中解碼的例子:
[cpp] view plaincopy
/************************************************************************
聲波通訊庫示例,從實時錄音數(shù)據(jù)獲取音頻信號進(jìn)行解碼,該工程示例是可跨平臺的
聲波通訊庫特征:
準(zhǔn)確性95%以上,其實一般是不會出錯的。
接口非常簡單,有完整的示例,3分鐘就可以讓你的應(yīng)用增加聲波通訊功能
抗干擾性強,基本上無論外界怎么干擾,信號都是準(zhǔn)確的
基本的編碼為16進(jìn)制,而通過編碼可傳輸任何字符
性能非常強,沒有運行不了的平臺,而且通過內(nèi)存池優(yōu)化,長時間解碼不再分配新內(nèi)存,可7*24小時運行
可支持任何平臺,常見的平臺android, iphone, windows, linux, arm, mipsel都有示例
詳情可查看:http://blog.csdn.net/softlgh
作者: 夜行俠 QQ:3116009971 郵件:3116009971@qq.com
************************************************************************/
//識別到有信號時開始解碼回調(diào)函數(shù)
void recorderRecognizerStart()
{
printf("------------------recognize start\n");
}
//當(dāng)次解碼結(jié)束的回調(diào)函數(shù)
void recorderRecognizerEnd(int _recogStatus, char *_data, int _dataLen)
{
if (_recogStatus == VR_SUCCESS)
{
char buf[51];
memcpy(buf, _data, _dataLen);
buf[_dataLen] = 0;
printf("------------------recognized data:%s\n", buf);
}
else
{
printf("------------------recognize invalid data, errorCode:%d\n", _recogStatus);
}
}
#ifdef WIN32
void runRecorderVoiceRecognize( void * _recognizer)
#else
void *runRecorderVoiceRecognize( void * _recognizer)
#endif
{
vr_runRecognizer(_recognizer);
}
int recorderShortWrite(void *_writer, const void *_data, unsigned long _sampleCout)
{
char *data = (char *)_data;
void *recognizer = _writer;
return vr_writeData(recognizer, data, (int)_sampleCout);
}
void test_recorderVoiceRecog()
{
//創(chuàng)建識別器,并設(shè)置監(jiān)聽器
void *recognizer = vr_createVoiceRecognizer();
vr_setRecognizerListener(recognizer, recorderRecognizerStart, recorderRecognizerEnd);
//創(chuàng)建錄音機
void *recorder = NULL;
int r = initRecorder(44100, 1, 16, 512, &recorder);//要求錄取short數(shù)據(jù)
if(r != 0)
{
printf("recorder init error:%d", r);
return;
}
//開始錄音
//r = startRecord(recorder, recognizer, recorderFloatWrite);//float數(shù)據(jù)
r = startRecord(recorder, recognizer, recorderShortWrite);//short數(shù)據(jù)
if(r != 0)
{
printf("recorder record error:%d", r);
return;
}
//開始識別
#ifdef WIN32
//CreateThread( NULL, 0, runRecorderVoiceRecognize, recognizer, 0, 0 );
_beginthread(runRecorderVoiceRecognize, 0, recognizer);
#else
pthread_t ntid;
pthread_create(&ntid, NULL, runRecorderVoiceRecognize, recognizer);
#endif
printf("\n\n\nrecognize start, waiting for signals ............\n");
char c = 0;
do
{
printf("press q to end recognize\n");
scanf_s("%c", &c);
} while (c != 'q');
//停止錄音
r = stopRecord(recorder);
if(r != 0)
{
printf("recorder stop record error:%d", r);
}
r = releaseRecorder(recorder);
if(r != 0)
{
printf("recorder release error:%d", r);
}
//通知識別器停止,并等待識別器真正退出
do
{
vr_stopRecognize(recognizer);
printf("recognizer is quiting\n");
#ifdef WIN32
Sleep(1000);
#else
sleep(1);
#endif
} while (!vr_isRecognizerStopped(recognizer));
//銷毀識別器
vr_destroyVoiceRecognizer(recognizer);
}
所有代碼都在附件中
附件說明:
各平臺相應(yīng)的文件在相應(yīng)平臺的文件夾下,有些平臺文件夾下只有編碼端或者解碼端,或者是因為不需要,或者是我自己現(xiàn)在沒用到,也懶得去編譯了,你自己需要的時候找我吧。各平臺的庫是demo版,c語言版是限制了解碼次數(shù),android的java版是沒有去除噪音功能,你自己如果真正需要相應(yīng)的正式版,再找我吧。各個平臺的編碼端都沒有任何限制
本文件夾下包含:
VoiceRecogFromRecorder.exe:從windows錄音設(shè)備讀取音頻數(shù)據(jù)解碼信號的示例程序,其代碼在windows文件夾下。該示例工程是可跨平臺編譯的,鏈接時去鏈接相應(yīng)平臺的.so文件就可以了。使用時確保windows錄音正常,然后從android手機播放信號后windows上就能識別到了。
VoiceRecogFromWav.exe:從本目錄下的data.wav文件讀取音頻數(shù)據(jù)解碼信號的示例,代碼在windows文件夾下。該示例工程是可跨平臺編譯的,鏈接時去鏈接相應(yīng)平臺的.so文件就可以了。
聲波通訊測試.apk:android平臺上同時進(jìn)行音頻編碼和解碼的示例,其代碼在android文件夾下
voiceDemoWithNoise.jar:android平臺上同時進(jìn)行音頻編碼和解碼庫,此庫為沒有處理噪音的開發(fā)版,不是正式版
各平臺文件夾:
android:示例apk,java版的編碼和解碼庫,相應(yīng)的解碼、解碼使用示例代碼,但解碼庫沒有降噪處理,錯誤率比正式版高。
iphone:現(xiàn)在我只用到了編碼端和使用示例代碼,解碼端沒有編譯。
windows:現(xiàn)在我只用到了解碼端,所以只有解碼庫,限制了使用次數(shù)。windows平臺文件夾下有使用聲波通訊庫的完整示例代碼,這些示例代碼實際上是跨平臺,可在任何支持c的平臺上編譯運行,包括linux,arm,mipsel等平臺,arm平臺,linux平臺,mipsel平臺上使用解碼庫與windows相同,鏈接時去鏈接相應(yīng)平臺的.so文件就可以了。示例中包括從wav文件讀取音頻數(shù)據(jù),或者從錄音機讀取音頻數(shù)據(jù)。
arm:現(xiàn)在我只用到了解碼端,所以只有解碼庫,限制了使用次數(shù)。解碼使用示例代碼見windows文件夾下
linux:現(xiàn)在我只用到了解碼端,所以只有解碼庫,限制了使用次數(shù)。解碼使用示例代碼見windows文件夾下
mipsel:現(xiàn)在我只用到了解碼端,所以只有解碼庫,限制了使用次數(shù)。解碼使用示例代碼見windows文件夾下
下載附件:附件
51CTO下載附件地址
作者: 夜行俠 QQ:3116009971 郵件:3116009971@qq.com
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。