Компания
281,84
рейтинг
3 марта 2015 в 09:15

Дизайн → Оптимизация PhonoPaper с использованием инструментов Intel

Некоторое время назад я уже писал про одну из своих разработок — технологию PhonoPaper и одноименную программу, позволяющую играть звук, напечатанный в виде спектрограммы на бумаге или любой другой поверхности. Процесс выглядит примерно так: 10-секунд звука (голос, кусок песни) преобразуются в картинку специального формата. Картинка распечатывается и, к примеру, клеится на стену. Прохожий, заметив код, запускает PhonoPaper-сканер на телефоне, наводит камерой на картинку и в тот же миг начинает слышать звук, закодированный в ней. При этом пользователь полностью вовлечен в процесс — от движения его руки зависит направление и скорость воспроизведения (хотя имеется и автоматический режим). Вся необходимая информация хранится в изображении, выход в Интернет не требуется.



PhonoPaper вызвал живой интерес в среде музыкантов, художников и просто любителей необычных экспериментов. А в 3 квартале прошлого года приложение заняло первое место в проекте «Рейтинг Intel для разработчиков» на сайте Apps4All.ru. В связи с чем Intel любезно предоставила мне планшет на базе Android x86 для дальнейшего улучшения и оптимизации PhonoPaper. Я поспешил этим воспользоваться, а о проделанной работе и результатах расскажу далее.

Захват видео


Первое, что было сделано — это подключен набор библиотек Intel INDE Media for Mobile. А конкретно — класс GLCapture для захвата видео c OpenGL ES поверхности в реальном времени (в HD-качестве и со звуком). Зачем это нужно? Во-первых, сам процесс поиска и проигрывания PhonoPaper-кодов — это fun, захватывающее зрелище, напоминающее игру на каком-то необычном музыкальном инструменте. Во-вторых, PhonoPaper может работать в свободном режиме, когда в звук преобразуется все без разбора — в том числе ваш ковер и кошка. И то и другое было бы здорово записывать и выкладывать на YouTube.


PhonoPaper-коды, нарисованные от руки


Свободный режим — любое изображение с камеры воспринимается, как спектр звука.

Процесс подключения GLCapture неоднократно описан в разных статьях. Расскажу лишь о нескольких моментах, о которых желательно знать перед началом работы.
  • Версия Android должна быть не меньше 4.3. Для старых устройств я сделал кросс-платформенный MJPEG рекордер, скорость и качество которого, конечно же, сильно уступает hardware-accelerated GLCapture, пишущего в mp4.
  • Приложение должно быть построено на базе OpenGL ES 2.0. Мои программы исторически использовали версию 1.1, поэтому код пришлось переписывать. Но переход на GLES 2.0 в конечном итоге положительно сказался на производительности, т. к. появилась возможность вручную настраивать шейдеры.
  • GLCapture может писать звук с микрофона. Это хорошо, если вам нужно сопровождать видео своими комментариями. Если же требуется звук высокого качества непосредственно из приложения, то придется записывать его отдельно в файл, а потом объединять с mp4. Для объединения можно использовать класс MediaComposer с эффектом SubstituteAudioEffect из комплекта Media for Mobile. Другой путь — запись в WAV, кодирование из WAV в AAC, добавление AAC-дорожки в mp4-файл при помощи библиотеки mp4parser.

Так как PhonoPaper написан на языке программирования Pixilang, то функция захвата видео в дальнейшем распространится на другие pixilang-based приложения (PixiTracker, PixiVisor, Nature — Oscillator, Virtual ANS), а главное — будет доступна для всех разработчиков, использующих Pixilang. При этом доступна очень легко (всего несколько функций: для запуска захвата, для остановки и сохранения).

Intel C++ и оптимизация


Следующий шаг — сборка x86 Android-версии PhonoPaper при помощи компилятора Intel (версия 15.0.0) и сравнение результатов с GCC 4.8. Я пользователь Debian Linux и довольно старой версии к тому же. Поэтому первой проблемой стало найти соответствующую версию Intel C++. Почему-то большая часть ссылок вела на проект Intel INDE, внутри которого имеется нужный компилятор, но только для Windows и OS X. Это показалось странным… К счастью, нужный дистрибутив таки был найден — это Intel System Studio 2015. И не смотря на предупреждения при установке, все заработало и первая же сборка прошла успешно.

Компиляция выполнялась со следующими ключами: -xATOM_SSSE3 -ipo -fomit-frame-pointer -fstrict-aliasing -finline-limit=300 -ffunction-sections -restrict. Для проверки производительности виртуальной машины Pixilang (она в основе всех моих приложений) были написаны небольшие тесты, исходники и результаты которых можно посмотреть в этом архиве. В итоге, даже без предварительной подготовки, некоторые куски кода были ускорены в 5 (!) раз. Довольно впечатляющие результаты!

В PhonoPaper большая часть нагрузки идет на функцию спектрального синтезатора (таблично-волнового, не FFT) — wavetable_generator(). Для нее был написан отдельный тест, который в течение четырех секунд рендерит поток звука со случайным спектром. В конце тест выдает максимально возможную частоту дискретизации. Увы, здесь ICC справился хуже: 105 кГц против 100 кГц на GCC. Добавляем при компиляции ключ -qopt-report=2 и в отчете видим сообщение:

loop was not vectorized: vector dependence prevents vectorization.

Основной цикл внутри нашей функции не удалось векторизовать, т. к. указатели входных данных могут указывать на пересекающиеся участки памяти:

int* amp = (int*)amp_cont->data
int* amp_delta = (int*)amp_delta_cont->data;

Как разработчик, я вижу, что в данном месте пересечение исключено и об этом просто нужно сообщить компилятору. В C/C++ существует специальное ключевое слово restrict, сообщающее о том, что объявляемый указатель указывает на блок памяти, на который не указывает никакой другой указатель. Поэтому вышеприведенный код заменяем на такой:

int* restrict amp = (int*)amp_cont->data;
int* restrict amp_delta = (int*)amp_delta_cont->data;

После чего еще раз собираем приложение и видим, что цикл успешно векторизован. С учетом некоторых дополнительных изменений (в процессе оказалось, что можно избавиться от нескольких битовых операций) имеем результат — 190 кГц. GCC с учетом тех же изменений выдал 130 кГц. Получаем прирост производительности в 1.46 раз!

Что дальше


Как видим, результаты весьма позитивные! PhonoPaper стал быстрее (во многом благодаря компилятору Intel C++) и обрел функционал захвата видео. Кроме того, запись видео появится в виде нескольких простых функций в ближайшем обновлении Pixilang 3.6.
Для тех, кто не в курсе, Pixilang — это открытый кроссплатформенный язык программирования, заточенный на работу со звуком и графикой. Синтаксис языка весьма минималистичен и представляет собой некий гибрид Бейсика и Си, что вкупе с другими особенностями (возможность писать код без функций, универсальные контейнеры для хранения любых данных) снижает порог вхождения.
Автор: @NightRadio
Intel
рейтинг 281,84

Похожие публикации

Комментарии (9)

  • +7
    слушал ковёр. психоделичненько.
  • 0
    В принципе вы изобрели факс ;) А вообще надо немного подумать и придумать для чего это можно применить в реальности: звук картинка + движение. Надо подумать…
    • +2
      Ну, для городских игр кое-какие перспективы точно открываются уже.
  • +1
    Ай, спасибо, добрый человек! Я как раз ломал голову, что бы такого с детьми на открытом уроке по теме «звук» руками поделать. Теперь я знаю! Мы будем рисовать звук и смотреть, у кого получится музыкальнее. Спасибо!!!
  • 0

    так вот, что переоткрыли
    • 0
      8-бит прям :)
  • +3
    «Ой, мороз, мороз» отлично звучит.
    P.S. long live to PixiLang!
  • +1
    Я не слоупок :) Ещё раз спасибо за статью. Благодаря ей открытый урок на городском «учителе года» получился очень интересным. Может вам пригодится куда, вот тут видео с урока с использованием PhonoPaper: www.youtube.com/watch?v=nFDn24Uimkw (часть 1), www.youtube.com/watch?v=hBmwIxpuwv8 (часть 2, тут как раз начинается про вашу программу).
    • 0
      Отлично получилось. Спасибо!

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Дизайн