Sphinx應用程式編寫

2021-09-06 05:38:46 字數 4006 閱讀 1746

pocketsphinx api核心理念

pocketsphinx api 被設計是為了減輕編寫語音識別功能應用程式。

由於使用抽象類,所以在源**和二進位制檔案相容方面,更能保持穩定。

因為它完全可重入,所以在同一程序中擁有多個編碼器也不會出現問題。

在執行時,新的語言模型的介面(在sphinxbase)支援線性多模型插值。

它能大幅度減少**量而且能明顯減少記憶體消耗。

相關文件見:

基本用法(hello world

你需要知道幾個關鍵的點如何使用應用程式介面(api):

命令列通過外部來解析;

一切都需要乙個ps_decoder_t*作為第乙個引數。

為了說明新的介面,我們將通過乙個簡單的「hello world」的例子。這個例子為unix原始檔和匯程式設計序。我們將建立乙個叫hello_ps.c的c原始檔。我們使用如下命令來編譯:

gcc -o hello_ps hello_ps.c \

-dmodeldir=\"`pkg-config --variable=modeldir pocketsphinx`\"

`pkg-config --cflags --libs pocketsphinx sphinxbase`

請注意,編譯錯誤在這裡意味著你沒有仔細閱讀教程和不遵循上述安裝指南。例如pocketsphinx需要通過pkg-config系統來正確安裝。為了檢查pocketsphinx正確安裝與否,只要在命令列執行 pkg-config --cflags --libs pocketsphinx sphinxbase 就可以從輸出結果看出。

-i/usr/local/include/sphinxbase  -i/usr/local/include/pocketsphinx 

-l/usr/local/lib -lpocketsphinx -lsphinxbase –lsphinxad

pkg-config --variable=modeldir pocketsphinx

顯示結果輸出:/usr/local/share/pocketsphinx/model

補充:gcc -o recog recog.c \-dmodeldir=\"/usr/local/share/pocketsphinx/model\"  -i/usr/local/include/sphinxbase  -i/usr/local/include/pocketsphinx  -l/usr/local/lib -lpocketsphinx -lsphinxbase -lsphinxad

初始化

首先我們需要做的是建立乙個配置物件,由於某種原因叫作cmd_ln_t。我們將按如下程式這樣做:

#include

int main(int argc, char *argv)

ps_decoder_t *ps;

cmd_ln_t *config;

config = cmd_ln_init(null, ps_args(), true,

"-hmm",modeldir "/hmm/en_us/ hub4wsj_sc_8k",

"-lm", modeldir "/lm/en/turtle.dmp",

"-dict", modeldir "/lm/en/turtle.dic",

null);

if (config == null)

return 1;

return 0;

該cmd_ln_init()功能採用可變數目的空結束null的字串引數。第乙個引數是之前要更新的cmd_ln_t *。第二引數是乙個陣列引數定義—通過呼叫ps_args()來進行設定。第三個引數是乙個標誌,告訴引數解析器將是「嚴格」的—如果這是真的,然後重複的引數或未知引數會導致解析失敗。

該modeldir巨集定義是在gcc命令列中使用pkg-config從pocketsphinx配置中獲得modeldir變數。在windows系統中,你可以簡單的增加乙個預處理巨集定義到**中,像這樣:

#define modeldir "c:/sphinx/model"

(無論你的模型安裝在哪個目錄下),現在,為了初始化解碼器,使用ps_init如下:

ps = ps_init(config);

if (ps == null)

return 1;

解碼檔案流

現在現場音訊輸入受到一些特定平台的影響,這將限制我們自已去解碼音訊檔案。「turtle」語言模式識別的乙個非常簡單的「robot control」語言,其中包括一些諸如「go forward ten meters」的短語。事實上,乙個音訊檔案包含在pocketsphinx源**的句子中。你可以在test/data/goforward.raw中找到。把它複製到當前目錄。如果你想建立自己的版本,需要乙個單聲道,小端,無頭16-bit pcm有符號,取樣率為16khz的音訊檔案。

為了這樣做,首先我們開啟檔案:

file *fh;

fh = fopen("goforward.raw", "rb");

if (fh == null)

2930 rv = ps_decode_raw(ps, fh, "

goforward

", -1

);31

if (rv < 0)32

return1;

33 hyp = ps_get_hyp(ps, &score, &uttid);

34if (hyp ==null)

35return1;

36 printf("

recognized: %s\n

", hyp);

3738 fseek(fh, 0

, seek_set);

39 rv = ps_start_utt(ps, "

goforward");

40if (rv < 0)41

return1;

42while (!feof(fh))

47 rv =ps_end_utt(ps);

48if (rv < 0)49

return1;

50 hyp = ps_get_hyp(ps, &score, &uttid);

51if (hyp ==null)

52return1;

53 printf("

recognized: %s\n

", hyp);

5455

fclose(fh);

56ps_free(ps);

57return0;

58 }

高階用法

對於使用更複雜的老api,有一些明顯的不同地點:

得到部分和全部假設不再有單獨的功能;

詞語切分是通過訪問迭代器而不是返回的陣列或列表;

語言模型的轉換是通過外部()。

首先這些都是簡單的。在這之前,你必須使用uttproc_partial_result()得到部分結果(例如在uttproc_end_utt()前),使用uttproc_result()得到全部結果。現在,ps_get_hyp()能工作在兩種方式下。

對於字的分割,api提供了乙個遍歷所有字序列的迭代器物件。這個迭代器物件是乙個抽象類,這個抽象類為一些訪問器提供獲取每個字的時間點,分數和(最有趣的)後驗概率。

最後,語言模型切換是完全不同的。解碼器總是與乙個語言模型集物件聯絡在一起。切換語言模型是通過以下:

得到乙個控制代碼然後給語言模型集物件:ps_get_lmset()

選擇乙個新的語言模型:ngram_model_set_select()

告訴解碼器語言模型集已更新:ps_update_lmset()

翻譯於2023年9月21日

參考官網:

如何編寫應用程式

每次要編寫嵌入式應用程式的時候總是不知道該如何入手,於是簡單的研究了下現在普遍的掃碼支付模組的sdk開發結構。拿到乙個專案需求時,我們需要看下該專案分為幾個模組,每個模組之間又是以什麼形式連線的。模組化會使程式結構清晰,維護也會方便很多。比如說掃碼支付模組就分為三個部分,底層core部分,mqtt功...

21 編寫iOS應用程式

原文 1 引言 2 objective c 程式設計 3 類 物件和方法 4 資料型別和表示式 5 迴圈結構 6 選擇結構 7 類8 繼承 9 多型 動態型別和動態繫結 10 變數和資料型別 11 分類和協議 12 預處理程式 13 基本的c語言特性 14 foundation框架簡介 15 數字 ...

用PB編寫郵件應用程式

圖1 2 閱讀郵件 使用者資訊在伺服器上通過驗證以後,乙個有效的郵件會話就建立了,接下來要做的工作就是接發郵件。pb用乙個mailmessage物件來描述一封郵件,該物件封裝了郵件的主題 位址 訊息體和附件等資訊。圖1是郵件應用程式的閱讀介面,它列出了收件箱中的所有郵件,可選擇其中一封進行閱讀。主視...