Android声音合成

Android声音合成,android,audio,audiotrack,sound-synthesis,Android,Audio,Audiotrack,Sound Synthesis,我正在尝试使用AudioTrack类播放合成声音(基本上是两个正弦波和一些噪声)。它似乎与javax.sound.sampled中的SourceDataLine没有什么不同,但是合成速度非常慢。即使对于ARM标准,认为32768个样本(16位,立体声,总共65536个)在Nexus 4上渲染需要1秒以上(使用System.nanotime()测量,写入到AudioTrack除外)也是不现实的。 合成部分几乎与此相同,唯一的区别是我播放立体声(我不能将其还原为单声道,因为它是双耳音调) 有什么想法

我正在尝试使用AudioTrack类播放合成声音(基本上是两个正弦波和一些噪声)。它似乎与javax.sound.sampled中的SourceDataLine没有什么不同,但是合成速度非常慢。即使对于ARM标准,认为32768个样本(16位,立体声,总共65536个)在Nexus 4上渲染需要1秒以上(使用System.nanotime()测量,写入到AudioTrack除外)也是不现实的。 合成部分几乎与此相同,唯一的区别是我播放立体声(我不能将其还原为单声道,因为它是双耳音调)

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


提前感谢

您是否尝试过评测代码?听起来可能是其他原因导致了您的速度减慢,分析将有助于突出原因


Mike

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

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

  • 双精度浮点运算在ARM Cortex A-x霓虹灯装置上特别昂贵,因为单精度运算速度非常快,并且高度可并行化
    Math.sin()
    返回一个
    double
    ,因此不必要地精确,而且速度很慢。单精度浮点值提供的24尾数远远大于音频子系统使用的16位int
  • 您可以预先计算sin(x),然后在渲染循环中执行表查找
  • 之前在SO上有一篇关于android上的
    Math.sin(x)
    的帖子,建议随着
    x
    变得越来越大,性能会下降,这在本例中很可能会随着时间的推移 对于更高级的基于表的合成器,您可以考虑使用DDS振荡器。<李>
    <>最后,您可以考虑使用NDK。p> 马尔科的回答似乎很好。但是,如果你仍然在你的项目的实验/研究阶段,你可能想考虑使用,它已经被实现为Android库/NDK库的组合,这将允许你以相对简单的方式合成许多声音并与它们交互。p> 这是纯数据的Android实现。在和上可以找到一些很好的起始参考

    附录:我发现了一个基本的Android Midi驱动程序的功能实现。可以找到相关代码


    您可以在我的Android应用程序(,或上)中查看我如何使用它。

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

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

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


    感谢您的建议:我已经在为sin函数使用LUT,并且我知道Math.sin对于大数的性能问题。我刚刚尝试在可能的情况下将double替换为float,但速度仍然太慢。我已经与在我的pc上运行的相同代码进行了比较,但我看不出为什么它是slowe的150倍r(测量)在我的手机上,我可以理解10次慢,但150次是荒谬的。Pentium 1会更快。从角度来看,我从一个相当重的减法合成器引擎中得到32个声音,它是在1GHz TI OMAP44 30的两个核心之一上可靠运行的。代码是C++,唯一的优化是编译器对并行的暗示。e一些代码路径-它非常有效。谢谢你指出你的jsyn。我想知道是否有类似于android/desktop的tone.js或android的javascript CreateSonator()的东西。我发现了一个java库