我正在尝试使用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/几乎完全相同,唯一的区别是我播放立体声(我无法将其降低为单声道,因为它是双耳音)。
有什么想法吗?我能做什么?
提前致谢
答案 0 :(得分:6)
Marko的回答似乎非常好。但是,如果您仍处于项目的实验/研究阶段,您可能需要考虑使用Pure Data,它已经作为Android库/ NDK库的组合实现,这将允许您合成许多声音和以相对简单的方式与他们互动。
libpd distribution是Pure Data的Android实现。可以在SoundOnSound site和this 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设备上应该有什么。
但是,您报告的性能比我预期的要低几个数量级。您可以考虑以下事项:
Math.sin()
返回double
,因此不必要的精确,并且可能会很慢。单精度浮点值提供的24尾数远大于音频子系统使用的16位int。 sin(x)
,然后在渲染循环中执行表查找。Math.sin(x)
上有一篇关于x
的帖子,因为{{1}}变得很大,因为在这种情况下,随着时间的推移可能会降低性能。 最终,您可以考虑使用本机代码进行合成,使用NDK。
答案 2 :(得分:0)
您是否尝试过分析代码?这听起来像其他东西可能导致你的速度减慢,分析将有助于突出原因。
麦克
答案 3 :(得分:0)
您应该能够使用滤波器和信封渲染多个振荡器,并且仍然有剩余的CPU时间。检查内部循环以确保没有系统调用。
你在一部很旧的手机上吗?您没有提到硬件或操作系统版本。
您可能想尝试使用JSyn。它是一个免费的模块化Java合成器,可在任何Java平台上运行,包括桌面,Raspberry Pi和Android。