Как создать пользовательские файлы конфигурации в OpenSMILE
Я пытаюсь извлечь некоторые функции из аудиосэмпла, используя OpenSMILE, но я понимаю, насколько сложно настроить файл конфигурации.
Документация не очень полезна. Лучшее, что я мог сделать, - это запустить некоторые из предоставленных примеров файлов конфигурации, посмотреть, что получилось, а затем перейти в файл конфигурации и попытаться определить, где была указана эта функция. Вот что я сделал:
Я использовал набор функций по умолчанию, использованный в Паралингвистическом конкурсе INTERSPEECH 2010 (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, нет вопросов о Stackru и нет сообщений в блогах, рассказывающих о том, как это можно сделать. Что действительно удивительно, поскольку это, очевидно, огромная часть использования OpenSMILE.
Если кто-то найдет это, пожалуйста, можете ли вы посоветовать мне, как создавать собственные файлы конфигурации OpenSMILE? Спасибо!
1 ответ
Спасибо за ваш интерес к openSMILE и ваше стремление создавать собственные файлы конфигурации.
Большинство пользователей в научном сообществе фактически используют openSMILE для своих предопределенных файлов конфигурации для базовых наборов функций, которые в версии 2.3 еще более гибки в использовании (больше опций командной строки для вывода в различные форматы файлов и т. Д.).
Я признаю, что предоставленная документация не так хороша, как могла бы быть. Тем не менее, openSMILE является очень сложной частью программного обеспечения с большим количеством функциональных возможностей, из которых только самые важные части в настоящее время хорошо документированы.
Лучшая отправная точка - прочитать книгу openSMILE и учебные пособия по SIG'MM, на которые есть ссылки на http://opensmile.audeering.com/. Он содержит раздел о том, как писать файлы конфигурации. Следующий важный элемент - онлайн-справка двоичного файла:
- SMILExtract -L перечисляет доступные компоненты
- SMILExtract -H cComponentName перечисляет все опции, которые поддерживает данный компонент (и, следовательно, также функции, которые он может извлечь) с кратким описанием для каждого
- SMILExtract -configDflt cComponentName предоставляет раздел конфигурации шаблона для компонента со всеми перечисленными параметрами и установленными значениями по умолчанию
Из-за архитектуры openSMILE, которая основана на пошаговой обработке всех аудиофункций, нет (по крайней мере, пока) простого синтаксиса для определения нужных функций. Скорее, вы определяете цепочку обработки, добавляя компоненты:
- источники данных будут считывать данные (например, из аудиофайлов, CSV-файлов или микрофона),
- обработчики данных будут выполнять обработку сигналов и извлечение признаков на отдельных этапах (управление окнами, оконная функция, БПФ, величины, mel-спектр, кепстральные коэффициенты (MFCC), например, для извлечения MFCC); для каждого шага есть процессор данных.
- приемники данных будут записывать данные в выходные файлы или отправлять результаты на сервер и т. д.
Вы подключаете компоненты с помощью опций "reader.dmLevel" и "writer.dmLevel". Они определяют имя уровня памяти данных, который компоненты используют для обмена данными. Только один компонент может выполнять запись на один уровень, т.е. writer.dmLevel=levelName определяет уровень и может появляться только один раз. Несколько компонентов могут читать с этого уровня, установив reader.dmLevel=levelName.
Затем в каждом компоненте вы устанавливаете параметры, чтобы включить вычисление объектов, и задаете параметры для этого. Чтобы ответить на ваш вопрос о lspFreq: он, вероятно, включен по умолчанию в компоненте cLsp, поэтому вы не видите явной опции для него. Для будущих версий openSMILE практика явной установки всех опций будет и должна соблюдаться более строго.
Названия объектов в выводе будут автоматически определены компонентами. Часто каждый компонент добавляет часть имени, поэтому вы можете вывести из имени полную цепочку обработки. Параметры nameAppend и copyInputName (доступные для большинства обработчиков данных) управляют этим поведением, хотя некоторые компоненты могут переопределить их внутренне или немного изменить поведение.
Чтобы увидеть имена (и другую информацию) для каждого уровня памяти данных, в том числе, например, какие функции создает компонент в конфигурации, вы можете установить параметр "printLevelStats=5" в разделе componentInstances:cComponentManager.
Поскольку все в openSMILE построено для инкрементальной обработки в реальном времени, каждый уровень памяти данных имеет буфер, который по умолчанию является кольцевым буфером, чтобы поддерживать постоянный объем памяти, когда приложение работает дольше. Иногда вы можете захотеть суммировать объекты в окне заданной длины (например, с помощью компонента cFunctionals). В этом случае вы должны убедиться, что размер буфера входного уровня для этого компонента достаточно велик, чтобы вместить полное окно. Вы делаете это с помощью следующих опций:
writer.levelconf.isRb = 1/0: устанавливает тип буфера в кольцевой буфер (1) или буфер фиксированного размера
writer.levelconf.growDyn = 1/0: устанавливает динамический рост буфера, если в него записывается больше данных (1)
writer.levelconf.nT = устанавливает размер буфера в кадрах. В качестве альтернативы вы можете использовать bufferSizeSec=x, чтобы установить размер в секундах и автоматически конвертировать в кадры.
В большинстве случаев размеры будут установлены правильно автоматически. Последующие уровни также наследуют конфигурацию от предыдущих уровней. Исключение составляют случаи, когда вы устанавливаете компонент cFunctionals для чтения полного ввода (например, создаете только одну функцию в конце файла), вы должны использовать growDyn = 1 на уровне, с которого компонент Functionals читает, или если вы используете переменную режим кадрирования (см. ниже).
Компонент cFunctionals предоставляет параметры frameMode, frameSize и frameStep. Где frameMode может быть полным * (один вектор создается в конце входного файла / файла), ** list (указать список кадров), var (принимать сообщения, например, от компонента cTurnDetector, которые определяют кадры на лету), или исправить (окно фиксированной длины). Только в случае исправления параметры frameSize устанавливают размер этого окна, а frameStep - скорость, с которой окно смещается вперед. В случае исправления размер буфера входного уровня устанавливается правильно автоматически, в остальных случаях его нужно устанавливать вручную.
Я надеюсь, что это поможет вам начать! С каждым новым выпуском openSMILE мы в AudEERING пытаемся документировать вещи немного лучше и объединять вещи с помощью различных компонентов.
Мы также приветствуем вклад сообщества (например, любого, кто хочет написать графический редактор файлов конфигурации, куда вы перетаскиваете компоненты и подключаете их графически?;)) - хотя мы знаем, что больше документации сделает это проще. До тех пор, вы всегда должны читать исходный код;)
Ура, Флориан