sphinx4 FrontEnd流程分析
回顧一下sphinx4的整體架構:
從上面我們看到,應用程序的輸入Input(一般是錄音數據),首先經過前端(FrontEnd)處理。前端處理有一序列的步驟,最后會得到聲音對應的特征值,也就是所謂的Feature。然后將得到的feature傳給×××Decoder中的Scorer模塊進行處理。今天我們從整體上分析一下FrontEnd的處理流程。
我們還是以HelloWorld這個為例,先來看一下它的配置文件:
<component name="threadedScorer"
type="edu.cmu.sphinx.decoder.scorer.ThreadedAcousticScorer">
? ? ? ?<propertyname="frontend"value="${frontend}"/>
</component>
threadedScorer有FrontEnd這個屬性,在看一下FrontEnd的配置:
<component name="frontEnd" type="edu.cmu.sphinx.frontend.FrontEnd">
? ? ? ?<propertylist name="pipeline">
? ? ? ? ? ? ? ?<item>microphone </item>
? ? ? ? ? ? ? ?<item>preemphasizer </item>
? ? ? ? ? ? ? ?<item>windower </item>
? ? ? ? ? ? ? ?<item>fft </item>
? ? ? ? ? ? ? ?<item>melFilterBank </item>
? ? ? ? ? ? ? ?<item>dct </item>
? ? ? ? ? ? ? ?<item>liveCMN </item>
? ? ? ? ? ? ? ?<item>featureExtraction </item>
? ? ? ?</propertylist>
</component>
從配置文件可以看到,FrontEnd有一個屬性列表,列表中的每一個item都是前段處理的一個模塊。熟悉設計模式的應該知道,這里顯然用到了責任鏈設計模式。首先從microphone開始,錄音數據處理完后再沿著這條管道線交給下一個處理,最后到達featureExtraction,進行最后的特征提取,提取完特征再傳遞給Scorer處理。
下面這個是 FrontEnd 的處理流程:
上面的那些item對應的java類,實際上都是一個DataProcessor,即它們都繼承了BaseDataProcessor這個類,DataProcessor有一個方法getData(),可以得到DataProcessor處理完后的數據。
我們再來看一下FrontEnd的相關定義。在FrontEnd定義了一個DataProcessor的List,用來存放上面配置文件中的那些item對應的實例對象,還定義了兩個DataProcessor,first表示第一個DataProcessor,last表示下一個DataProcessor:
private List<DataProcessor> frontEndList;
private DataProcessor first;
private DataProcessor last;
而得到這些示例對象是通過它的newProperties回調方法,有關解析和屬性相關的內容前面已經介紹過了。
@Override
public void newProperties(PropertySheet ps) throws PropertyException {
? ? ? ?super.newProperties(ps);
? ? ? ?frontEndList = ps.getComponentList(PROP_PIPELINE, DataProcessor.class);
? ? ? ?init();
}
獲取完屬性列表后,接著調用了init方法:
private void init() {
? ? ? ?last = null;
? ? ? ?for (DataProcessor dp : frontEndList) {
? ? ? ? ? ? ? ?assert dp != null;
? ? ? ? ? ? ? ?if (last != null)
? ? ? ? ? ? ? ? ? ? ? ?dp.setPredecessor(last);
? ? ? ? ? ? ? ?if (first == null) {
? ? ? ? ? ? ? ? ? ? ? ?first = dp;
? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?last = dp;
? ? ? ?}
? ? ? ?initialize();
? ?}
這個方法的作用就是遍歷整個DataProcessor List,按順序依次設置下一個DataProcessor,這樣整個List就串起來了,接著又調用了initialize方法:
@Override
public void initialize() {
? ? ? ?super.initialize();
? ? ? ?for (DataProcessor dp : frontEndList) {
? ? ? ? ? ? ? ?dp.initialize();
? ? ? ?}
? ?}
initialize這個是接口DataProcessor定義的一個抽象方法,每個子類必須實現自己的版本。這個方法遍歷了所有的DataProcessor,然后調用它們自己的initialize,完成自己的初始化工作。
FontEnd還有一個 getData方法,用來獲取整個流程處理完后最終的數據:
@Override
public Data getData() throws DataProcessingException {
? ? ? ?Data data = last.getData();
? ? ? ?// fire the signal listeners if its a signal
? ? ? ?if (data instanceof Signal) {
? ? ? ? ? ? ? ?fireSignalListeners((Signal) data);
? ? ? ?}
? ?return data;
}
以上就是FrontEnd的大致的處理流程,本質上就是使用了責任鏈設計模式,將所有需要對語音進行處理的DataProcessor串成一個鏈條,然后沿著這個鏈條逐一處理,處理完后通過getData獲取最終的數據。
轉載于:https://blog.51cto.com/ikinglai/1251156
總結
以上是生活随笔為你收集整理的sphinx4 FrontEnd流程分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ubuntu12.10下arm-linu
- 下一篇: vim的巧用---对比操作