Android声音合成

时间:2013-04-29 11:25:20

标签: android audio audiotrack sound-synthesis

我正在尝试使用AudioTrack类播放合成声音(基本上是2个正弦波和一些噪声)。它似乎与javax.sound.sampled中的SourceDataLine没有任何不同,但合成真的很慢。即使对于ARM标准,认为32768个样本(16位,立体声,总共65536)在Nexus 4上渲染需要1秒钟(用System.nanotime()测量,写入AudioTrack除外)是不现实的。 合成部分与此http://audioprograming.wordpress.com/2012/10/18/a-simple-synth-in-android-step-by-step-guide-using-the-java-sdk/几乎完全相同,唯一的区别是我播放立体声(我无法将其降低为单声道,因为它是双耳音)。

有什么想法吗?我能做什么?

提前致谢

4 个答案:

答案 0 :(得分:6)

Marko的回答似乎非常好。但是,如果您仍处于项目的实验/研究阶段,您可能需要考虑使用Pure Data,它已经作为Android库/ NDK库的组合实现,这将允许您合成许多声音和以相对简单的方式与他们互动。

libpd distribution是Pure Data的Android实现。可以在SoundOnSound sitethis site找到一些不错的首发参考资料。

附录:我通过this discussion link找到了Android Midi驱动程序的基本功能实现。可以找到相关代码here (github, project by billthefarmer, named mididriver)

您可以在我的Android应用中imSynt link leads you to Google Play)YouTube查看我的使用方式。

答案 1 :(得分:4)

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

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

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

答案 2 :(得分:0)

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

麦克

答案 3 :(得分:0)

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

你在一部很旧的手机上吗?您没有提到硬件或操作系统版本。

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

https://github.com/philburk/jsyn