XML 管道(Pipeline)本文主要讲 SSI 的 XML 接口, 该接口允许将管道定义为文本文件. 既不要求使用者会编程, 也不需要特定的开发环境, 就能装配一个任何文本编辑器都能用的管道. 不过, SSI 也自带了一个 XML 编辑器, 该编辑器除了提供了一些特殊的功能外, 还简化了将数据写入管道的步骤, 比如: 列出可选项和解释说明某个选中的组件.
图 6: 在 SSI 的 XML 编辑器中能方便访问现有的组件 (左边的面板). 此外, 组件的选项能直接访问和修改(右边的面板). 让我们用一个简单的例子, 说明下如何在 SSI 中创建 XML 管道. 假设, 我们要写个程序, 将声音信号转换成频谱(spectrogram). 这是音频处理中最常见的功能之一. 因为, 我们可以通过频率分析语音中的诸多属性. 下面例子中的管道, 通过麦克风捕捉音频信号, 然后转换成频谱. 并把原始的信号, 和转换过的信号显示出来.
由于 SSI 支持插件, 组件都是在运行时, 动态加载的. 所以, 我们把需要加载的 DLL 放在 <register> 标志中. 在本例中, 需要加载3个 DLL 文件, ssiaudio.dll, 包含从音频源读取数据的组件, ssisignal.dll, 包含通用的信号处理算法, 和 ssigraphic.dll, 包含各种显示原始信号和处理过的信号的工具. 管道剩下的那一部分用来定义, 要创建哪些组件, 以及用什么方式把它们关联到一起. <sensor> 用来定义管道源. 这里的 ssi_sensor_Audio 是组件的名称, 该组件负责音频输入这部分功能. 通常, 组件都有选项, 允许我们修改组件的行为. 如, 设scale=“true“则让音频传感器,以范围为[-1..1]的浮点数传回波形信号,否则, 我们收到的波形信号是整数流. 而设 option=“audio“, 则是要把配置存到 audio.option 文件中. 接下来,我们要定义哪一个源是我们想监听的.一个传感器至少有一个频道. <provider>用来指定要连接的频道,这个标志包含两个属性: channel 是频道的标识符, pin 则是个可选的标识符, 后面我们会用来引用信号流. SSI 内部有一个缓存, 音频采样数据会持续不断的被写进去. 默认情况下, 缓存会保留最后 10 秒的数据. 所以, 从缓存读取数据的组件能收到一份它需要的采样数据. 连接数据流的组件, 通常会对数据处理, 然后把处理过的数据当作新的数据流输出, 这些组件放在 <transformer>中. 新的数据流跟原来的数据在采样率和类型上会有差别. 比如, 视频图像可能映射成一个表示坐标的值. 又如, 在我们的例子中, 16kHz 的一维音频数据流被映射成多维低频频谱. 频谱用来显示不同频率区的能量分布. SSI中能进行这类数据转换的组件名为 ssi_feature_Spectrogram. 通过选项 minfreq, maxfreq, 和 nbanks, 我们可以设置频率范围 [minfreq...maxfreq](以Hz为单位), 和频率区的数量. 像傅立叶转换的系数(nfft) 和窗口类别 (wintype), 如果没有设置, 则用默认值对其初始化(除非像音频传感器的例子那样, 间接重写由option加载的选项文件的内容). 通过<input> 给转换器指定输入流, 由于我们要读取的是原始的音频采样数据, 所以把 pin 设为 audio. 接下来, 通过属性frame设置输入流的数据块大小. 而读取操作完成后, 窗口平移的数量, 通过属性 delta 来设置. 在本例中, 分别设为0.01s 和0.015s. 也就是说, 每一次循环, 会读取长度为 0.025 秒的数据, 再平移 0.01 秒. 如果采样率为 16kHz(音频流的默认采样率), 就会得到400个采样数据(16kHz*[0.01s+0.015s]) 和一个160个单位的帧平移 (16kHz*0.01s). 换句话说, 每一次从缓存中复制 400 个采样数据后, 当前读指针的位置就会自增 160. 由于输出的数据采样率是 100Hz(1/0.01s), 刚好跟频谱里面的频率区的数量相等. 若要将转换过的新的数据流, 存在 SSI 的另外一个缓存里面, 我们需要将 <output> 的属性 pin 设为spect .
现在, 在命令窗口中输入 xmlpipe <filename> 测试下效果 (如果你用的是SSI的 XML 编辑器, 按 F5 直接运行). 第一次运行的时候, 会弹出一个选择输入源的窗口. 选好后, 选择的内容会存在 audio.option文件中. 运行的结果如下: 图 7: 左上: 原始音频信号图. 左下: 频普图,蓝色表示低频率, 红色表示高能量. 命令窗口显示当前管道的状态. 有的时候, 管道文件内容太长, 需要把重要的选项放到另外一文件中. 我们可以在管道文件里面使用 $(<key>) 代替原来的值, 然后再创建一个新的文件, 在这个文件里面, 使用格式 <key> = <value> 赋值. 比如, 我们可以把频谱转换部分改成:
然后另外建一个文件给这些选项赋值(管道文件以 .pipeline 结尾, 配置文件以 .pipeline-config 文件): minfreq = 100 # 最低频率 为了方便使用, SSI 自带一个图形界面程序 xmlpipeui.exe, 该程序能将某个表中的选项列出来, 并自动分析管道文件中新加的 key: 图 8: 管理选项, 和使用不同配置文件运行管道的图形界面. |