我正在尝试使用 OpenSMILE 从音频样本中提取一些功能,但我意识到设置配置文件是多么困难。
该文档不是很有帮助。我能做的最好的事情就是运行提供的一些示例配置文件,看看结果是什么,然后进入配置文件并尝试确定指定功能的位置。 这是我所做的:
我使用了INTERSPEECH 2010 Paralanguage Challenge(IS10_paraling.conf)中使用的默认功能集。
我在一个示例音频文件上运行它。
我看着结果。然后,我深入阅读了配置文件,试图找出指定功能的位置。
这里有一个小的降价表,显示了我的探索结果:
| Feature generated | instruction in the conf file |
|-------------------|---------------------------------------------------------|
| pcm_loudness | I see: 'loudness=1' |
| mfcc | I see a section: [mfcc:cMfcc] |
| lspFreq | no matches for the text 'lspFreq' anywhere |
| F0finEnv | I seeF0finalEnv = 1 under [pitchSmooth:cPitchSmoother] |
我看到的是 4 个不同的功能,它们都由配置文件中的不同指令生成。好吧,对于其中之一,我可以找到的配置文件中没有令人不安的说明。 由于没有模式或直观的语法或明显的系统,我不知道如何最终弄清楚如何指定我想要生成的自己的功能。
没有教程,没有YouTube视频,没有StackOverflow问题,也没有博客文章讨论如何做到这一点。这真的很令人惊讶,因为这显然是使用OpenSMILE的重要组成部分。
如果有人发现这个,请,你能告诉我如何创建OpenSMILE的自定义配置文件吗?谢谢!
感谢您对openSMILE的兴趣以及构建自己的配置文件的渴望。
科学界的大多数用户实际上将openSMILE用于其预定义的基线功能集配置文件,在2.3版本中使用起来更加灵活(更多的命令行选项可以输出到不同的文件格式等)。
我承认提供的文档没有达到应有的水平。然而,openSMILE是一个非常复杂的软件,具有许多功能,其中只有最重要的部分目前有很好的文档记录。
最好的起点是阅读 openSMILE 书籍和 SIG'MM 教程,这些教程都在 http://opensmile.audeering.com/上引用。它包含有关如何编写配置文件的部分。下一个重要元素是二进制文件的在线帮助:
- SMILExtract -L列出了可用的组件
- SMILExtract -H cComponentName列出了给定组件支持的所有选项(因此也可以提取功能),并为每个选项提供简短描述
- SMILExtract -configDflt cComponentName为您提供了组件的模板配置部分,其中列出了所有选项并设置了默认值
由于openSMILE的架构以所有音频功能的增量处理为中心,因此(至少现在还没有)没有简单的语法来定义您想要的功能。相反,您可以通过添加组件来定义处理链:
- 数据源将读取数据(例如,从音频文件、CSV 文件或麦克风读取数据), 数据处理器
- 将在各个步骤中进行信号处理和特征提取(窗口,窗口函数,FFT,幅度,mel-spectrum,倒谱系数(MFCC),例如用于提取MFCC);每个步骤都有一个数据处理器。
- 数据接收器将数据写入输出文件或将结果发送到服务器等。
您可以通过"reader.dmLevel"和"writer.dmLevel"选项连接组件。它们定义了组件用于交换数据的数据存储器级别的名称。只有一个组件可以写入一个级别,即 writer.dmLevel=levelName 定义级别并且只能出现一次。多个组件可以通过设置 reader.dmLevel=levelName 从此级别读取。
然后,在每个组件中设置选项以启用特征计算并为此设置参数。要回答有关 lspFreq 的问题:这可能在 cLsp 组件中默认启用,因此您看不到它的显式选项。对于 openSMILE 的未来版本,明确设置所有选项的做法将而且应该更严格地遵循。
输出中要素的名称将由组件自动定义。通常,每个组件都会添加名称中的部件,因此您可以从名称中推断出完整的处理链。选项nameAppend和copyInputName(适用于大多数数据处理器)控制此行为,尽管某些组件可能会在内部覆盖它们或稍微更改行为。
要查看每个数据存储器级别的名称(和其他信息),包括例如配置中组件产生的哪些功能,您可以在组件实例:cComponentManager部分中设置选项"printLevelStats=5"。
由于openSMILE中的每一个都是为实时增量处理而构建的,因此每个数据存储器级别都有一个缓冲区,默认情况下,该缓冲区是一个环形缓冲区,用于在应用程序运行较长时间时保持内存占用不变。 有时您可能希望总结给定长度的窗口(例如,使用 cFunctionals 组件)的特征。在这种情况下,必须确保此组件的输入电平的缓冲区大小足以容纳整个窗口。您可以通过以下选项执行此操作:
-
writer.levelconf.isRb = 1/0 :将缓冲区类型设置为 ringbuffer (1) 或固定大小缓冲区
-
writer.levelconf.growDyn = 1/0 :将缓冲区设置为在写入更多数据时动态增长 (1)
-
writer.levelconf.nT = 设置缓冲区的大小(以帧为单位)。或者,您可以使用 bufferSizeSec=x 以秒为单位设置大小大小并自动转换为帧。
在大多数情况下,大小将自动正确设置。后续级别也会继承先前级别的配置。例外情况是,当您将 cFunctionals 组件设置为读取完整输入(例如,仅在文件末尾生成一个特征)时,您必须在函数组件读取的级别上使用 growDyn=1,或者如果您使用变量成帧模式(见下文)。
cFunctionals 组件提供帧模式、帧大小和帧步长选项。其中 frameMode 可以是full*(在输入/文件末尾生成的一个向量)、**list(指定帧列表)、var(接收消息,例如来自 cTurnDetector 组件,用于动态定义帧)或固定(固定长度窗口)。只有在固定选项的情况下 frameSize 设置此窗口的大小,并且frameStep窗口向前移动的速率。在固定的情况下,输入电平的缓冲区大小会自动正确设置,在其他情况下,您必须手动设置。
我希望这可以帮助您入门! 随着每一个新的openSMILE版本,我们在audEERING都试图更好地记录事情,并通过各种组件统一事物。
我们也欢迎来自社区的贡献(例如,有人愿意编写一个图形配置文件编辑器,您可以在其中拖放组件并以图形方式连接它们吗? ;)) - 尽管我们知道更多的文档将使这更容易。在此之前,您始终必须使用源代码才能读取;)
干杯 佛瑞恩