Визуализация спектра звуковых частот на iOS

Погружение в Accelerate Framework и FFT (быстрое преобразование Фурье)

Не каждый день мне приходится использовать преобразование Фурье, но сегодня был один из таких дней. На прошлой неделе мне довелось поэкспериментировать с Accelerate Framework на iOS. Accelerate Framework реализует быстрое преобразование Фурье (БПФ) как часть оптимизированных по ресурсам и скорости преобразований, доступных через SDK для vDSP (обработка цифровых сигналов).

Ускоренная структура

Accelerate Framework от Apple — это низкоуровневый C API, который реализует несколько математических операций для быстрого и эффективного выполнения на оборудовании Apple. Библиотека доступна как для iOS, так и для OSX и может использоваться для обработки изображений, обработки сигналов, матричных математических и векторных операций. Конкретным приложением, с которым я здесь экспериментирую, является быстрое преобразование Фурье (БПФ), поскольку оно применяется к цифровой обработке сигналов.

На прошлой неделе я создал простое приложение CoreAudioMixer, которое реализовало AUGraph из API CoreAudio AUToolbox для одновременного воспроизведения пары звуковых дорожек и позволило установить громкость воспроизведения каждой дорожки. Я подумал, что было бы здорово иметь некоторую визуализацию звука во время воспроизведения трека, и начал исследовать варианты. Мне также нужна была возможность использовать Accelerate Framework, поэтому визуализация БПФ и звукового спектра мне показалась отличной.

Приложение CoreAudioMixer обрабатывает входные данные двух отдельных звуковых дорожек, загружаемых из файла: гитары и ударных. Треки сохраняются в буфере и отправляются на вывод в методе AURenderCallback. Метод обратного вызова обрабатывает аудиоданные в буферизованных сегментах по 512 кадров. Данные обрабатываются в режиме реального времени и отправляются на выход по мере воспроизведения звука.

Чтобы проанализировать спектр звуковых частот воспроизводимого звука, можно использовать быстрое преобразование Фурье для преобразования звуковых данных, основанных на времени, в сегменты частотного спектра с уровнями интенсивности. Это вычисление должно выполняться для массива из 512 кадров данных, поэтому оно должно происходить быстро. Библиотека vDSP в Accelerate Framework предоставляет необходимые нам вызовы. vDSP_fft_zrip используется для выполнения прямого преобразования вектора данных и генерации выходных данных реального и мнимого компонентов. Результирующий массив точек данных сохраняется в виде снимка из 256 точек во время воспроизведения звука. Класс CoreAudioManager поддерживает окно данных и позволяет потребителю (UI) запрашивать обновленный набор данных, когда это необходимо.

Ниже приведен код, используемый для выполнения БПФ над аудиобуфером в методе AURenderCallback:

Интерфейс просмотра частоты

Чтобы каким-то образом визуализировать данные звукового спектра, я настроил простой класс FrequencyView, чтобы просто отображать полосы в каждом из частотных сегментов, предоставленных в качестве выходных данных БПФ. Представление написано на Swift и содержит массив значений с плавающей запятой, которые можно обновлять. Всякий раз, когда значения обновляются, представление настраивает представления столбцов на соответствующую высоту на экране.

Я устанавливаю простой NSTimer в основном классе ViewController, который выполняет запрос новых данных спектра каждые 0,01 секунды. Затем UIViews внутри FrequencyView обновляются на основе новых данных:

Я реализовал компоненты пользовательского интерфейса на Swift. Swift предоставляет удобный способ сделать массив Float из указателя буфера, который возвращается классом Objective-C через UnsafeBufferPointer. Это позволяет представлениям Swift легко собирать и использовать данные.

Источник

Вы можете проверить исходный код CoreAudioMixer на GitHub.

Чтобы узнать больше о CoreAudio, посетите iOS CoreAudio Apple Developer Library.

Первоначально опубликовано на www.myuiviews.com 4 марта 2016 г.