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是郵件應用程式的閱讀介面,它列出了收件箱中的所有郵件,可選擇其中一封進行閱讀。主視...