Успех мультимедийной платформы зачастую определяет качество контента. Поэтому существует множество инструментов для управления контентом — например, ручная или автоматическая модерация на предмет грубого и оскорбительного контента или нарушения авторских прав; автоматическая или ручная обработка загруженного контента. Один из способов автоматического улучшения контента — обрезка тишины.
Задача выделения голоса или звуков очень нетривиальная. О том, как мы искали пути ее решения при разработке одного из наших проектов — голосового чата BlaBlaPlay — и как реализовать это в вашем iOS-приложении, расскажем в этой статье.
[Теория] Когда нужна функция обрезки тишины?
Например, у вас есть аудиофайл с промежутками, где уровень громкости слишком низкий для человеческого восприятия. В таком случае может потребоваться удалить эти участки из файла. Или, например, вы записываете аудиосообщение и долго собираетесь с мыслями в начале. Чтобы не перематывать несколько секунд тишины снова снова, их проще обрезать вовсе. Можно описать еще много подобных случаев, но вывод напрашивается один — обрезка тишины требуется для улучшения контента и качества его восприятия.
Реализовать это можно по-разному, используя разные инструменты. Изначально можно выделить 2 основные группы инструментов:
- для ручного удаления: например, любой аудиоредактор имеет базовую функцию выделения отрезка, который нужно удалить / оставить
- для автоматического удаления — они используют ряд вспомогательных технологий для достижения результата. Рассмотрим их подробнее.
[Теория] Автоматические способы определения тишины
Их может быть довольно много и выбор зависит от стоящей перед разработчиком задачи. Это в первую очередь связано с тем, что одни инструменты позволяют выделять из аудиопотока исключительно голос, а другие — работать с голосом и с посторонними звуками.
Определение тишины по уровню звука
Итак, определение по уровню звука или, если говорить более точно, по значению — это самый простой и быстрый для выполнения способ. Поэтому его можно использовать для потокового аудио и определять тишину в реальном времени. Но в то же время это самый неточный и хрупкий способ определения тишины. Технология простая:
- Задается константное значение в децибелах — примерно равное порогу слышимости для человека.
- Далее все, что ниже этого порога, автоматически считается тишиной и подлежит обрезке.
Способ подходит только в случае, когда необходимо определить абсолютную тишину и не нужно определять голос или любые посторонние шумы. Абсолютная тишина — явление редкое, поэтому способ малоэффективен. Следовательно, применяться он может только для индикации наличия или отсутствия звука, а не обработки тишины.
Выделение голоса из аудиопотока
Это подход от обратного — если есть речь, значит, тишины нет.
Выделение звука из аудиопотока — задача нетривиальная и решается путем оценки фрагмента уровней звука или его спектрограммы — схемы колебаний уровня звука. Есть 2 подхода к оценке: аналитический и нейросетевой. В нашем приложении мы использовали Voice Activity Detector (VAD) — детектор речи для выделения голоса или речи из шума или тишины. Рассмотрим на его примере.
Аналитическая оценка
В рамках работы с речевым сигналом как правило используют частотно-временную область обработки. Среди основных методов:
• анализ с использованием вейвлет-преобразования.
• анализ с использованием линейного предсказания.
• анализ с использованием преобразования Гильберта-Хуанга.
• анализ с использованием преобразования Фурье.
• анализ с использованием корреляционной функции.
Наиболее эффективным для выделения речи является метод, основанный на том, что речевой аппарат человека способен генерировать определенный пул частот. Эти частоты называются “форманты”.
Входные данные в этом методе представляют собой непрерывную осциллограмму (кривую, отображающую колебания) звуковой волны. Для выделения речи ее разбивают на фреймы — фрагменты звукового потока длительностью от 10 до 20 мс и шагом 10 мс. Такой размер соответствует скорости человеческой речи: в среднем за 3 секунды человек произносит 3 слова, в каждом из которых около 4 звуков, каждый звук разбивается на 3 этапа. Каждый фрейм независимо трансформируется и подвергается извлечению акустических признаков
Далее для каждого окна выполняется преобразование Фурье:
- Производится поиск пиковых значений
- На основе формального анализа акустических признаков принимается решение: есть речевой сигнал или нет. Подробнее процесс описан в работе У.А. Ли. 1983. “Методы автоматического распознавания речи”.
[Теория] Нейросетевой подход к оценке
Нейросетевой подход состоит из двух частей.
- Так называемый feature extractor — средство для извлечения признаков и построения low dimensional space. На вход экстрактору подается осциллограмма звуковой волны и, например, с помощью преобразования Фурье, строится ее low dimensional space. Т.е. из большого числа признаков выделяются ключевые и формируется в новое пространство.
- Дальше экстрактор организует звуки в пространстве так, чтобы похожие были рядом. Например, звуки речи будут сгруппированы вместе, но размещены вдали от звуков барабанов и автомобилей.
Далее модель классификации берет выходные данные экстрактора признаков и вычисляет вероятность речи среди полученных данных.
Что использовать?
Процесс выделения звуков или речи сложный и требует много вычислительных ресурсов для быстрой работы. Давайте разберемся, когда и какой метод стоит применять.
Итак, как видим, определение по уровню сигнала не подойдет, если вам нужна точность.
С аналитическим и нейросетевым подходами есть нюансы. Оба требуют высокой вычислительной мощности — это ограничивает их использование с потоковым аудио. Но в случае с аналитическим подходом эту проблему можно решить, используя более простые реализации в угоду точности. Например, WebRTC_VAD — он хоть и не сильно точен, но работает быстро с потоковым аудио даже на слабых устройствах.
А если вычислительная мощность есть и вы хотите определять не только речь, но и звуки птиц, гитары или чего угодно еще, нейросеть решит все ваши проблемы с высоким уровнем точности и за приемлемое время.
[Практика] Пример для детекта и обрезки тишины iOS в начале аудиозаписи
Все iPhone достаточно производительны, а фреймворки от Apple оптимизированы под устройства. Поэтому можем смело использовать нейросети для детекта тишины в потоковом аудио, используя подход от обратного: где нет звуков — там тишина. Для детекта будем использовать фреймворк Sound Analysis, а для записи аудио и обрезки — AVFoundation.
Получение и отправка буферов аудио во время записи
Для выборки буферов из потока аудиозаписи нужен объект AVAudioEngine. А для доставки полученных буферов нужно добавить наблюдателя на выход к подключенной аудионоде.
Обработка буфера в нейросети и получение результата
Фреймворк Sound Analysis из коробки распознает 300 звуков, чего более чем достаточно для нашей задачи. Создадим класс классификатора и правильно сконфигурируем объект SNClassifySoundRequest.
При создании SNClassifySoundRequest c использованием константного значения для окна windowDuration крайне важно использовать overlapFactor отличный от нуля. Он описывает, насколько окна перекрывают друг друга при анализе. Тем самым создает непрерывный контекст и связность между окнами.
Дальше нужен какой-то класс наблюдателя, соответствующий протоколу SNResultsObserving. В него будут приходить все результаты классификации.
Наблюдателя создали, теперь можно создать сам поток для анализа, приходящих аудиобуферов — SNAudioStreamAnalyzer.
Теперь все готово. Можно принимать аудиобуферы и отправлять их в нейросеть на анализ. Сделать это очень просто:
После того, как AVAudioPCMBuffer будет успешно распознан в AudioClassifireObserver.audioClassificationEvent придет событие AudioClassificationEvent.result(SNClassificationResult). Оно будет содержать все распознанные звуки и уровни их доверия (confidence). Соответственно, если звуков нет или их confidence < 0.75, можно считать, что звук не был распознан — результатом можно пренебречь. Определить это можно так:
Обрезка аудиофайла на основе работы детектора звуков
После того, как запись началась и первые аудиобуферы начали поступать в нейросеть для анализа, нужно запустить таймер. Он будет отсчитывать время до появления первых ненулевых результатов. Тут стоит помнить, что первые результаты будут получены не раньше, чем через request?.windowDuration = CMTimeMakeWithSeconds(1.3, preferredTimescale: 44_100). Поэтому стартовые значения таймера должны это учитывать.
При первых ненулевых результатах останавливаем таймер и на основании recordSilenceTime можем отрезать кусочек от начала аудиозаписи.
Обрезка файла осуществляется с помощью AVAssetExportSession.
Результаты и вывод
Обнаружение тишины или звуков в аудиозаписи становится более доступно для приложений, которые в основном не специализируются на профессиональной обработке, не теряя в эффективности и точности полученного результата.
У Apple уже есть готовые инструменты для этого, поэтому тратить год и больше для разработки такого функционала вручную не нужно. Love neural networks. Посмотрите, как это работает в нашем BlaBlaPlay или напишите нам, чтобы реализовать функцию обрезки тишины в вашем iOS-приложении.
Комментарии