回顾一下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流程分析相关推荐

  1. yocto 编译流程分析

    yocto 编译流程分析 2015年04月15日 10:55:13 日月星辰007 阅读数:4955 git clone 一份poky 的工程到本地. source poky/oe-init-buil ...

  2. VLC架构及流程分析

    0x00 前置信息 VLC是一个非常庞大的工程,我从它的架构及流程入手进行分析,涉及到一些很细的概念先搁置一边,日后详细分析. 0x01 源码结构(Android Java相关的暂未分析) # bui ...

  3. 动态执行流程分析和性能瓶颈分析的利器——gperftools的Cpu Profiler

    在<动态执行流程分析和性能瓶颈分析的利器--valgrind的callgrind>中,我们领略了valgrind对流程和性能瓶颈分析的强大能力.本文将介绍拥有相似能力的gperftools ...

  4. 动态执行流程分析和性能瓶颈分析的利器——valgrind的callgrind

    在<内存.性能问题分析的利器--valgrind>一文中我们简单介绍了下valgrind工具集,本文将使用callgrind工具进行动态执行流程分析和性能瓶颈分析.(转载请指明出于brea ...

  5. 解析并符号 读取dll_Spring IOC容器之XmlBeanFactory启动流程分析和源码解析

    一. 前言 Spring容器主要分为两类BeanFactory和ApplicationContext,后者是基于前者的功能扩展,也就是一个基础容器和一个高级容器的区别.本篇就以BeanFactory基 ...

  6. Java多线程- 线程池的基本使用和执行流程分析 - ThreadPoolExecutor

    线程池的实现原理 池化技术 一说到线程池自然就会想到池化技术. 其实所谓池化技术,就是把一些能够复用的东西放到池中,避免重复创建.销毁的开销,从而极大提高性能. 常见池化技术的例如: 线程池 内存池 ...

  7. Android 7.0 WifiMonitor工作流程分析

    2019独角兽企业重金招聘Python工程师标准>>> 在wifi启动扫描的分析过程中,出现了多次WifiMonitor的操作,在此分析一下这个函数是如何工作的. 在Android的 ...

  8. 转:Android之 MTP框架和流程分析

    2019独角兽企业重金招聘Python工程师标准>>> 转载:http://www.cnblogs.com/skywang12345/p/3474206.html 概要 本文的目的是 ...

  9. Zygote进程启动流程分析

    文中的源代码版本为api23 Zygote进程启动流程分析 先说结论,zygote进程启动过程中主要做了下面这些事情: 启动DVM虚拟机 预加载部分资源,如一些通用类.通用资源.共享库等 启动syst ...

最新文章

  1. C enum(枚举)
  2. Python基础06 循环
  3. awesome xjtlu github project
  4. mysql临时表的使用实例_MySQL中临时表的使用示例
  5. 以 DirectUI 方式实现的ImageButton
  6. c语言信息管理系统排序怎么编,C语言编职工信息管理系统怎么做?
  7. for 与 while 区别?
  8. 从开场白第一句到得分
  9. 1.7 LINUX启动流程
  10. oracle数据库主主复制
  11. 旅游中用稳定器和相机拍视频是怎样的体验?
  12. java 读取文件 效率_JAVA读写文本文件的效率
  13. 虚拟打印机安装后没了该怎么办
  14. kmeans聚类算法如何选k值?
  15. 详解Docker的网络模式之host模式(host网络模式)
  16. 斯伦贝谢宣布2020年第三季度业绩
  17. python错误警告 PEP8 W605 invalid escape sequence ‘\.‘
  18. STARK中的FRI代码解析
  19. [转]编写简单的中文分词程序
  20. buck降压斩波电路

热门文章

  1. while0表示什么意思_轮胎上的各种字符都表示什么意思,家用车的轮胎又该如何选择呢?...
  2. pdffactory字体打印不对_标准论文格式字体要求
  3. vue单选框选中_vue中单选框与多选框的实现与美化
  4. 华为手机服务器响应,服务器响应优化
  5. html5app微信登陆,基于h5+的微信登陆,hbuilder打包
  6. (3)websocket实现单聊和群聊
  7. 分析|CVE-2021-3156-sudo堆溢出高危漏洞
  8. 记一次糟心的内网靶场实战
  9. 在控制台中录入学生姓名(python)
  10. 无偏PU learning简介