2013-04-29 2 views
2

Я пытаюсь воспроизвести синтезированный звук (в основном 2 синусоидальных волны и некоторый шум) с использованием класса AudioTrack. Кажется, что это не похоже на SourceDataLine в javax.sound.sampled, но синтез ДЕЙСТВИТЕЛЬНО SLOW. Даже для стандартов ARM нереально думать, что 32768 отсчетов (16 бит, стерео, всего 65536) занимают более 1 секунды для рендеринга на Nexus 4 (измеряется с помощью System.nanotime(), запись в AudioTrack исключена). Компонент синтеза почти идентичен этому http://audioprograming.wordpress.com/2012/10/18/a-simple-synth-in-android-step-by-step-guide-using-the-java-sdk/, единственное различие заключается в том, что я воспроизвожу стерео звук (я не могу уменьшить его до моно, потому что это бинауральный тон).Синтез звука Android

Любые идеи? что я могу сделать?

Заранее спасибо

ответ

0

Вы пробовали профилирования кода? Похоже, что что-то еще может привести к замедлению, профилирование поможет выявить причину.

Майк

3

Производительность звукового синтеза на ARM на самом деле очень респектабельный с машинным кодом, который делает хорошее использование устройства NEON. Компилятор JIT Dalvik никогда не приблизится к этому уровню производительности для интенсивного кода с плавающей запятой.
Взгляд на огромное количество приложений для софт-синтеза для iOS дает достаточные доказательства того, что должно быть возможно на устройствах ARM с одинаковым уровнем производительности.

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

  1. двойной точности с плавающей точкой арифметика особенно дорого на ARM Cortex A-х единиц неон, где в качестве одинарной точности является очень быстрым и очень параллелизуемое. Math.sin() возвращает double, поэтому излишне точен и должен быть медленным. 24-мантисса, обеспечиваемая значением одинарной точности с плавающей запятой, существенно больше, чем 16-битный int, используемый аудиоподсистемой.
  2. Вы можете прекомпилировать sin(x), а затем выполнить поиск таблицы в цикле рендеринга.
  3. Предыдущее сообщение по теме относительно Math.sin(x) на андроиде, предлагающее ухудшающую производительность, поскольку x становится большим, так как это может произойти в этом случае с течением времени.
  4. Для более продвинутого настольного синтезатора вы можете использовать DDS-генератор.

В конечном счете, вы можете использовать собственный код для синтеза, с NDK.

+0

спасибо за предложения: Я уже с помощью LUT для функции греха и я отдаю себе отчет в вопросе производительности Math.sin для больших чисел. Я только что попытался заменить double float, где это возможно, но он все еще слишком медленный. я сравнил с тем же кодом, который работает на моем компьютере, и я не вижу причины, по которой он в 150 раз медленнее (измеряется) на моем телефоне. я могу понять, может быть, на 10 раз медленнее, но 150 абсурдно. pentium 1 будет быстрее. – dosse91214

+0

Я боюсь, что мне придется жестоко писать собственный код :( – dosse91214

+0

Чтобы выразить это, я получил 32 голоса из довольно тяжелого образца субтрактивного синтезатора, прочно работающего на одном из двух ядер 1 ГГц TI OMAP4430. Код был C++, единственные оптимизации - это намеки на компилятор для параллелизации некоторых путей кода, что очень эффективно. – marko

5

Ответ Марко кажется очень хорошим. Но если вы все еще находитесь в экспериментальной/исследовательской фазе своего проекта, вам может потребоваться использовать Pure Data, который уже реализован как комбинация библиотеки Android/библиотеки NDK и которая позволит вам синтезировать многие звуки и взаимодействовать с ними в относительно простой способ.

libpd distribution - это реализация чистых данных для Android. Некоторые хорошие исходные ссылки можно найти на SoundOnSound site, а также в this site.

Addendum: Я нашел базовую, но функциональную реализацию Android Midi Driver через this discussion link. Соответствующий код может быть найден here (github, project by billthefarmer, named mididriver).

Вы можете посмотреть, как я использую его в моем Android приложение (imSynt link leads you to Google Play), или на YouTube.

0

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

вы на очень старом телефоне? Вы не упомянули аппаратную или версию операционной системы.

Вы можете попробовать использовать JSyn. это бесплатный модульный синтезатор Java который работает на любой платформе Java, включая настольные компьютеры, Raspberry Pi и Android.

https://github.com/philburk/jsyn

Смежные вопросы