Несколько аудиоплееров (Java или C++), которые можно изменять в режиме реального времени.

Нужна помощь с воспроизведением аудио на Android. У нас есть приложение OpenGL (Java + C++), и теперь мы хотим воспроизвести звуковые эффекты. Игроки должны позволять изменять скорость воспроизведения и громкость во время игры. Может быть OpenSL или Audiotrack.

Первый вопрос? Есть ли бесплатная или коммерческая библиотека/оболочка, которая может это сделать? (может быть, Java или нативная)

.., если нет, я объясню, что мы сделали до сих пор, и проблемы, с которыми мы столкнулись.

Мы создали класс MusicPlayer (расширяет AsyncTask) с экземпляром AudioTrack. В onResume() активности мы создали 5 экземпляров, выполняя их в пуле потоков. В задаче doInBackground() у нас есть работающий цикл, который проверяет изменение состояния, загружает файлы и записывает в буфер. В JNI у нас есть синглтон, который хранит очередь событий и отправляет их в java раз в 10 миллисекунд. Это как-то работает, но довольно далеко от того, чтобы быть приемлемым. Мы испытываем следующие проблемы:

  1. Когда файл начинает воспроизводиться, мы слышим короткий шум при запуске. Например, щелчок или что-то в этом роде.
  2. Даже если мы сбрасываем или отпускаем AudioTrack, кажется, что звук воспроизводится в очереди (особенно когда нужно быстро изменить буферы)
  3. Мы не можем создать цикл в MODE_STREAM
  4. Когда мы изменяем локальную переменную AsyncTask CHANGE_RATE и RATE, она должна вызывать audioTrack.setPlaybackRate(RATE). Это происходит, но ничего не происходит.

Раньше я писал на Obj-C для iOS, и есть много «готовых к использованию» решений (например, управление какао). Никогда не думал, что работа со звуком на Android станет таким кошмаром;/ Будем очень признательны за любую помощь :)


person rafalczuj    schedule 21.02.2014    source источник
comment
Мы не можем создать цикл в MODE_STREAM Почему бы и нет? Вы заполняете буферы, которые записываете в файл AudioTrack. Если вы снова и снова заполняете буферы одними и теми же данными PCM, вы будете слышать одни и те же данные PCM снова и снова.   -  person Michael    schedule 21.02.2014
comment
@Майкл Спасибо за ответ. Сделал аналогично - теперь работает :) Еще мы убрали несколько первых байтов, и теперь у нас нет кликов. Основная проблема заключалась в том, что мы отправляем в буфер сразу весь файл. Теперь мы разделили его на части 3072b, и теперь все в порядке.   -  person rafalczuj    schedule 24.02.2014


Ответы (1)


Android 4.0 или выше больше не поддерживает управление скоростью воспроизведения. Я не уверен, что было причиной его отключения. Мне пришлось принять алгоритм SOLA, реализованный SoundTouch, чтобы добавить в приложение управление скоростью воспроизведения.

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

Обновление от 22 января 2016 г. Android включает библиотеку Sonic в выпуск 6.0. Таким образом, управление скоростью воспроизведения должно быть доступно начиная с Android M.

person sergej shafarenka    schedule 25.02.2014
comment
Я попробовал с AudioTrack, и он работал вполне нормально — никаких проблем с изменением скорости воспроизведения. Но мне пришлось перейти с Java AudioTrack на OpenSL по соображениям производительности. Разный подход к разным проблемам :) Только что создал для этого новую тему: stackoverflow.com/questions/23083874/ - person rafalczuj; 15.04.2014
comment
Я использую библиотеку Sonic в своем приложении, о которой я упоминал в посте выше. Вот ссылка на бета-сообщество, если вы хотите узнать, как это звучит: plus.google .com/u/0/communities/102599894094628040492 - person sergej shafarenka; 22.01.2016