Мы добавили в Android Game SDK библиотеку Oboe C++ для работы со звуком. Она позволяет разрабатывать высокопроизводительные аудиоприложения с низкой задержкой для максимального спектра устройств Android. Эта библиотека также отлично подойдет большинству разработчиков игр. О ней и о том как с ней работать в Android Game SDK мы и хотим рассказать в этой статье.

Один API

Библиотека Oboe использует усовершенствованный интерфейс AAudio с расширенными функциями на устройствах под управлением Android 8.1 (API уровня 27) или более поздней версии, а также обеспечивает обратную совместимость (через OpenSL ES) с Android 4.1 (API уровня 16) или более поздней версии. В дополнение к API платформы библиотека Oboe предлагает разработчикам аудиоприложений ключевые функции для комфортной работы, такие как ресемплинг, преобразование форматов и динамическая корректировка задержек. При необходимости она позволяет преобразовывать аудиоданные, например конвертировать число каналов, чтобы повышать производительность выбранных устройств. Также библиотека предлагает обходные решения для других особенностей работы конкретных устройств, что повышает эффективность кода для обработки звука. В двух словах, теперь библиотека Oboe считается рекомендуемым решением при написании кода для работы со звуком на C/C++ для платформы Android.

Интеграция Oboe

Встроить элементы кода на базе Oboe в проект можно двумя основными способами. Если вы используете плагин Android Gradle 4.1.0 или более поздней версии вместе с CMake, а также используете (или можете подключить) общую библиотеку STL, для включения библиотеки Oboe достаточно добавить ее в список зависимостей Gradle, включить объекты prefab и добавить несколько строк кода в файл CMakeLists.

Интегрировать Oboe также можно с помощью статического связывания при помощи Android Game SDK. Сначала скачайте библиотеку и зарегистрируйте ее в системе управления версиями. Работать нужно с minSdkVersion 16 или более поздней версии, а также с NDK 18 или более поздней версии. Затем укажите версию игрового SDK для привязки, которая скомпилирована для заданной комбинации ABI, уровня API, NDK и STL, добавив путь к компилятору в следующем формате:

gamesdk/libs/[architecture]_API[apiLevel]_NDK[ndkVersion]_[stlVersion]_Release
Example: gamesdk/libs/arm64-v8a_API24_NDK18_cpp_static_Release

Затем добавьте ключ -loboe_static в команду компоновщика. Поскольку включать общую библиотеку liboboe.so не требуется, статическое связывание позволяет сократить размер кода. Если для комбинации ABI, уровня API, NDK и STL нет предварительно скомпилированной версии SDK под ваши настройки, можно выполнить связывание с общей библиотекой. Дополнительные указания, в том числе о настройке CMake для статических библиотек, см. в документации для разработчиков.

Основы Oboe

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

oboe::AudioStreamBuilder builder;
builder.setPerformanceMode(oboe::PerformanceMode::LowLatency)
  ->setSharingMode(oboe::SharingMode::Exclusive)
  ->setDataCallback(myCallback)
  ->setFormat(oboe::AudioFormat::Float);

Аудиоданные передаются внутри такого обратного вызова. В случае успешного создания вы получаете поток с запрошенным типом. Если такие типы не указывались, выполните запрос и изучите возвращенный формат.

class MyCallback : public oboe::AudioStreamDataCallback {
public:
    oboe::DataCallbackResult
    onAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames) {
        // We requested AudioFormat::Float
        auto *outputData = static_cast<float *>(audioData);
        // TODO: populate audioData here
        return oboe::DataCallbackResult::Continue;
    }
};

Подробные сведения об использовании Oboe см. в документациипримерах кода и документации по API. Вы также можете ознакомиться с практической работой, в которой показано создание простой ритмической игры.

Обратная связь

Если вы столкнулись с проблемами, сообщите нам о них через GitHub.