5

我正在尝试使用 AudioTrack 类播放合成声音(基本上是 2 个正弦波和一些噪音)。它似乎与 javax.sound.sampled 中的 SourceDataLine 没有什么不同,但合成真的很慢。即使对于 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/相同,唯一的区别是我播放立体声(我不能将其降低为单声道,因为它是双耳音调)。

有任何想法吗?我能做些什么?

提前致谢

4

4 回答 4

6

Marko 的回答似乎很好。但是,如果您仍处于项目的实验/调查阶段,您可能需要考虑使用Pure Data,它已经作为 Android 库/NDK 库的组合实现,可以让您合成许多声音并与之交互以相对简单的方式。

libpd发行版是 Pure Data 的 Android 实现。在SoundOnSound 站点这个站点上可以找到一些很好的参考资料。

附录:我通过这个讨论链接找到了一个 Android Midi 驱动程序的基本但功能实现。相关代码可以在这里找到(github,billthefarmer 的项目名为mididriver

您可以在我的 Android 应用程序(imSynt 链接将您引导至 Google Play)YouTube 上查看我如何使用它。

于 2013-04-29T14:31:46.300 回答
4

ARM 上的音频合成性能实际上是非常可观的,其原生代码充分利用了 NEON 单元。Dalvik 的 JIT 编译器永远不会接近浮点密集型代码的这种性能水平。
查看大量适用于 iOS 的软合成器应用程序,充分证明了在具有类似性能水平的 ARM 设备上应该可以实现的功能。

但是,您报告的性能比我预期的要低几个数量级。您可以考虑以下几点:

  1. 双精度浮点运算在 ARM Cortex Ax NEON 单元上特别昂贵,因为单精度非常快且高度可并行化。 Math.sin()返回 a double,因此不必要地精确,并且可能很慢。单精度浮点值提供的 24 位尾数大大大于音频子系统使用的 16 位 int。
  2. 您可以预先计算sin(x),然后在渲染循环中执行表查找。
  3. 之前有一篇关于 SO 的文章关于Math.sin(x)android 表明性能会随着时间的推移而降低x,因为在这种情况下很可能会随着时间的推移而降低性能。
  4. 对于更高级的基于表格的合成器,您可以考虑使用 DDS 振荡器。

最终,您可能会考虑将本机代码与 NDK 一起使用。

于 2013-04-29T13:41:36.907 回答
1

您应该能够使用过滤器和包络渲染多个振荡器,并且仍然有剩余的 CPU 时间。检查您的内部循环以确保没有系统调用。

您使用的是非常旧的手机吗?您没有提及硬件或操作系统版本。

您可能想尝试使用 JSyn。它是一个免费的模块化 Java 合成器,可在包括桌面、Raspberry Pi 和 Android 在内的任何 Java 平台上运行。

https://github.com/philburk/jsyn

于 2016-04-02T17:46:35.057 回答
0

您是否尝试过分析您的代码?听起来其他东西可能会导致您的速度变慢,分析将有助于突出原因。

麦克风

于 2013-04-29T13:26:54.270 回答