1. 程式人生 > >【iOS開發】---- 語音識別

【iOS開發】---- 語音識別

        最近iOS專案中需要用到語音識別技術(也被稱為自動語音識別,英語:Automatic Speech Recognition, ASR)。去google搜尋了一下,發現語音識別做的不錯的有谷歌,微軟和科大訊飛。但是微軟的語音識別只能在window平臺,科大訊飛的語音識別現在主要是中文和英文,而谷歌的語音識別是可以支援多國語言的,考慮到專案以後可能會有多種語言,所以我選擇用谷歌的語音識別。
這裡有一篇文章,比較詳細的對比了三種語音識別:Google,微軟,科大訊飛的語音識別引擎對比。
語音識別的流程包括兩個步驟:1.語音錄入; 2.語音識別.

語音錄入

語音錄入的方法我使用了兩種:

1.參照官方文件例子SpeakHere(使用了OC,C++混編,後來發現有些OC方法,在iOS 7中已經不建議使用了

2.使用AVAudioRecorder來錄音(建議使用第二種方法)

注意:從查得的資料來看,使用谷歌語音搜尋的音訊編碼暫時可用的有flac,speex,wav三種。網上說flac在iOS上獲得比較複雜,speex暫不清楚,wav是可以得到的。獲取wav編碼格式的設定方式如下:

#pragma mark - 
#pragma mark 錄音設定

- (NSString *) audioRecordingPath
{
    return [NSTemporaryDirectory() stringByAppendingFormat:@"voice.wav"];
}

- (NSDictionary *) audioRecordingSettings{
    NSDictionary *result = nil;
    /* Let's prepare the audio recorder options in the dictionary.
     Later we will use this dictionary to instantiate an audio
     recorder of type AVAudioRecorder */
    NSMutableDictionary *settings = [[NSMutableDictionary alloc] init];
    
    [settings setValue:[NSNumber numberWithInteger:kAudioFormatLinearPCM]
                forKey:AVFormatIDKey];
    
    [settings setValue:[NSNumber numberWithFloat:16000]
                forKey:AVSampleRateKey];
    
    [settings setValue:[NSNumber numberWithInteger:1]
                forKey:AVNumberOfChannelsKey];
    
    [settings setValue:[NSNumber numberWithInteger:AVAudioQualityLow]
                forKey:AVEncoderAudioQualityKey];
    
    result = [NSDictionary dictionaryWithDictionary:settings];
    return result;
}


錄音完成之後,將音訊檔案儲存,然後進行語音識別。

語音識別

  • 基本流程:
一、從音訊輸入裝置獲取原始資料。 二、對原始資料進行包裝、編碼。 三、將編碼後的音訊POST至介面地址。 四、分析處理介面返回的JSON並得出結果。
  • 請求介面
  • 音訊編碼格式
FLAC或WAV或SPEEX

iOS語音識別請求實現程式碼:

- (void)beginRecognition
{
    NSURL *url = [NSURL URLWithString:@"http://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=en"];
    ASIFormDataRequest *request = [[ASIFormDataRequest alloc] initWithURL:url];
    [request setRequestMethod:@"POST"];

    NSString *filePath_voice = [self audioRecordingPath];
    [request appendPostDataFromFile:filePath_voice];
    [request addRequestHeader:@"Content-Type" value:@"audio/L16; rate=16000"];
    [request setDidFailSelector:@selector(recognitionFailed:)];
    [request setDidFinishSelector:@selector(recognitionFinished:)];
    request.delegate=self;
    [request startAsynchronous];
}

返回結果:

{
    "status":0,//返回狀態
    "id":"",
    "hypotheses"://結果列表
    [
     {
         "utterance":"hello", //語音所轉換的文字
         "confidence":0.8394497 //識別信心度
     }
     ]
}

因為專案中語音是用來做搜尋用,基本輸入幾個詞彙就行,不需要大篇幅如簡訊一般。所以,我希望能在我說完話後,自動停止錄音。這樣,我們需要自動識別什麼時候錄入完畢了。

自動識別語音錄入完畢

基本流程:

  • 錄音開始,新增一個定時器,不停地檢測話筒是否有接收到聲音;
  • 一旦檢測到有聲音,說明開始有說話(期間定時器仍然在檢測);
  • 再次檢測到沒有聲音,說明錄入完畢,然後停止定時器重新整理,停止錄音。

定時器檢測實現方法以及相關注釋:

-(void)refresh:(id)sender
{
    //傳送updateMeters訊息來重新整理平均和峰值功率
    [audioRecorder updateMeters];
    
    //此計數是以對數刻度計量的,-160表示完全安靜,0表示最大輸入值。
    //為方便,我們將其轉換為0-1,0代表完全安靜,1代表最大音量。
    float peakPowerForChannel = pow(10, 0.05*[audioRecorder peakPowerForChannel:0]);
    float averagePowerForChannel = pow(10, 0.05*[audioRecorder averagePowerForChannel:0]);
    
    NSLog(@"Average input: %f Peak input: %f", peakPowerForChannel,averagePowerForChannel);
    
    lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * lowPassResults;
    averagePassResults = ALPHA * averagePowerForChannel + (1.0 - ALPHA) * averagePassResults;
    
    indicateHigh.alpha = averagePassResults;
    
    if (lowPassResults > 0.55f)
    {//此時mic接收到震動
        blowDetected = YES;
    }
    else
    {
        if (blowDetected)
        {
            blowDetected = NO;
            [self stopRecord];
            NSLog(@"錄音完成");
        }
    }
}

噪聲/聲音是由低頻聲音組成的。我們將使用low pass filter(低頻濾波) 來降低來自麥克的高頻聲音;當濾波訊號的電平等級突然增大時,我們就知道有人向麥克說話了。

blowDetected是一個bool值,因為一開始錄音和完成錄音都是電頻等級較低的時候,所以需要一個開關來區分,否則錄音沒剛始就結束了。

indicateHigh是個view,時刻改變透明度以告訴使用者有人在說話,你也可以用其他方式來指示。

lowPassResults通過低頻濾波演算法得到,有興趣的可以研究一下。其中ALPHA這裡值為0.05.

好了,到這裡語音識別需要的東西基本就完成了。

其實這篇文章只能算是一個彙總吧,把我需要的東西都記在這裡,非常感謝網路上那些樂於分享的同學。

參考:

Iphone開發之音訊101:

檢測使用者向麥克吹氣:

點選開啟連結

自動識別語音錄入完畢:

點選開啟連結

"Unknown type name 'class'; did you mean 'Class'?"(OC與C++混編髮生的問題):
點選開啟連結

CADebugPrintf.h file not found:
點選開啟連結

Google,微軟,科大訊飛的語音識別引擎對比:
點選開啟連結

相關推薦

iOS開發---- 語音識別

        最近iOS專案中需要用到語音識別技術(也被稱為自動語音識別,英語:Automatic Speech Recognition, ASR)。去google搜尋了一下,發現語音識別做的不錯的

iOS開發iOS移動端架構

引言:一個app的初始階段,必然是先滿足各種業務需求。然後,經過多次版本迭代之後,先前的由於急於滿足需求而導致的雜亂程式碼則會充斥整個專案。而此時,專案有了一定的規模,有了一定數量的開發人員,那麼為了達到快速迭代版本的需求,則是需要有一個強大的架構來支撐。

iOS開發Gitlab教程 (一)

一 、gitLab 建立工程 Project name : 工程名字起一個,最好和專案相關; Namespace : 你自己的gitLab工作空間,預設就好; Description : 描述,隨便寫。 Visibi

iOS開發判斷app啟動的方式(launchOptions)

iOS app啟動的方式有哪些: 自己啟動(使用者手動點選啟動)urlscheme啟動(關於urlScheme的詳解點選開啟連結)本地通知啟動  (自己寫的本地通知啟動,藍芽模組的啟動,地理圍欄的啟動)遠端通知啟動    (後臺伺服器的推送通知)在appdelegate.m

iOS開發SEL和Selector 原理小結

一 、Selector(選擇器)簡介 選擇器是用來選擇一個方法來為一個物件 執行的名稱,或是在編譯原始碼時替換該名稱的 唯一識別符號的名稱。一個選擇器本身不做任何事情。它簡單地識別了一種方法。唯一使選擇器的方法名稱不同於普通字串,編譯器確保選擇器是獨特的。

iOS開發一些常見的警告解決方案(更新中。。。)

Unknown pattern color for the Background Color attribute 1.背景色屬性為未知模式的顏色 解決:預設xib裡面控制元件的背景色為Default。如果出現警告,可能是你定義的顏色Xcode啟動

iOS開發UIWebView載入html時不顯示網路圖片解決辦法

NSString *html = @"<html><body><p>怎麼顯示網路圖片 <img src=\"http://p0.ifengimg.com/pmop/2017/1218/F9636BB16CC72EC34B5FCB78

APP內開啟另一個APP(URL Scheme與openURL)iOS開發

目標 平常我們做iOS開發,會經常遇到開啟其他的APP的功能。本篇文章講的就是開啟別人的APP的一些知識。我們的目標是: 開啟別人的APP讓別人開啟我們的APPiOS9的適配問題使用URL Schemes傳遞資料 準備工作 建立一個名為OpenApp的工作空間,用來存放

iOS開發陣列的去重(無序和有序)

一、 無序的去重 1.利用NSDictionary的AllKeys(AllValues)方法 可以將NSArray中的元素存入一個字典,然後利用AllKeys或者AllValues取得字典的所有鍵或值,這些鍵或值都是去重的。 程式碼:

iOS開發---- tableView背景隨表滾動

        最近專案中用到了“圖隨表動”,如下圖所示:         這是一個訂單,需要add shipping insurance以上的部分隨著表格的滾動而滾動,這裡表格是group型別的,所以背景加在cell上是達不到效果的,在code4App上找到了一個例子(

IOS 開發Object

.一. 類定義類定義需要實現兩部分 : -- 介面部分 : 定義類的成員變數和方法, 方法是抽象的, 在標頭檔案中定義;-- 實現部分 : 引入介面部分的標頭檔案, 實現抽象方法;1. 介面部分定義 (

iOS開發UIView(包括子類)的幾個初始化方法

-(id)initWithFrame:(CGRect)frame UIView的指定初始化方法; 總是傳送給UIView去初始化, 除非是從一個nib檔案中載入的; -(id

iOS開發NSThread

 atomic    原子屬性,是預設屬性     * 是在多執行緒開發時,保證多個執行緒在"寫入"的時候,能夠保證只有一條執行緒執行寫入操作!     * 是一個單(執行緒)寫多(執行緒)讀的多執行緒技術     * 原子屬性,解決不了賣票問題,因為賣票的讀寫都需要鎖定

iOS開發launch Images啟動圖片設定(UILaunchImageFile)之002

一、實現效果: 通過直接給圖片起預設的名字,讓app啟動頁自動載入啟動圖片。 二、注意點: ·圖片命名一定要按蘋果官方的指定規則命名,圖片的畫素也要符合規則; ·如果橫豎屏圖片都需要,記得在Xcode中勾選上專案支援橫豎屏。 三、官方描述:

iOS 開發將自己的框架打包成 Framework 的方法

建立 Framework 工程1. 建立打包工程開啟 Xcode 新建一個工程,選擇 Framework & Libray 選項中的 Cocoa Touch Framework ,這裡說一下我的 Xcode 版本是 8.3.2 。建立工程因為要打包所需的檔案,所以這裡我自己建立了一個測試類,在實際的打

iOS開發 常遇到的Crash和Bug處理

七:pngcrush caught libpng error,Not a PNG file Could not find file While reading /XXX/XXX/XXX/img1.png pngcrush caught libpng error:   Not a PNG filCou

iOS開發---- 手把手教你github託管程式碼

       在csdn上還有一篇介紹如何使用github託管程式碼的: 兩分鐘學會在GitHub託管程式碼。我照著這個教程嘗試了一遍,發現程式碼並沒有託管上去,只是建立了一個存放程式碼的倉庫(re

iOS 開發Status Bar 狀態列設定彙總

狀態列 個人覺得 iOS 的 Status Bar 狀態列也是一個比較坑的地方,所以還是寫一個總結,有遇到這方面問題的朋友可以看一下。 Status Bar 狀態列的隱藏 1. 通過設定 Info.plist 檔案實現狀態列的全域性隱藏 在 Info.pl

iOS開發---- 快速將大圖儲存到本地

       碰到一個問題:如何快速的批量儲存iphone相簿中的圖片(原始的大圖,解析度高)到本地? 儲存圖片到本地,首先得拿到這個圖片:alAsset.defaultRepresentation.fullResolutionImage.但是圖片太大了,大批量的儲存取這個

iOS開發從 UIWebView 到 WKWebView

引言 ①本文章適合有 UIWebView 基礎的人看,如果實在沒用過的話,至少你要知道 UIWebView 是個什麼東西。 ② UIWebView 和 WKWebView 的區別 WKWebView 更快(佔用記憶體可能只有 UIWebView 的1/3~1/4),沒有快取,更為細緻地拆分了 UIWebVi