Android:声音 API(确定性、低延迟)

标签 android android-ndk

我正在审查各种 Android 声音 API,我想知道我应该使用哪一个。 我的目标是获得低延迟的音频,或者至少是关于播放延迟的确定性行为。

我们遇到了很多问题,Android 声音 API 似乎很垃圾,所以我正在探索可能性。

我们遇到的问题是 sound_out.write(sound_samples); 和扬声器播放的实际声音之间存在明显延迟。通常为 300 毫秒左右。问题是在所有设备上都是不同的。有些人没有这个问题,但大多数人都瘫痪了(但是,CS 调用的延迟为零)。这种荒谬延迟的最大问题是,在某些设备上,这种延迟似乎是某个随机值(即并不总是 300 毫秒)。

我正在阅读有关 OpenSL ES 的信息,我想知道是否有人对此有经验,或者它是相同的狗屎但包装在不同的包装中?

我更喜欢本地访问,但我不介意 Java 层间接,只要我可以获得确定性行为:要么延迟必须是恒定的(对于给定的设备),要么我想获得访问到当前播放位置,而不是猜测它,误差范围为±300 ms...

编辑:
1.5 年后,我尝试了多部 Android 手机,看看如何获​​得最佳的实时语音通信延迟。我使用专门的工具测量了波形输出路径的延迟。最佳结果超过 100 毫秒,大多数手机都在 180 毫秒范围内。有人有想法吗?

最佳答案

SoundPool 是大多数设备上延迟最低的接口(interface),因为池存储在音频进程中。所有其他音频路径都需要进程间通信。如果 SoundPool 不能满足您的需求,OpenSL 是最佳选择。

为什么选择 OpenSL? AudioTrack 和 OpenSL 具有相似的延迟,但有一个重要区别:AudioTrack 缓冲区回调在 Dalvik 中提供服务,而 OpenSL 回调在 native 线程中提供服务。 Dalvik 的当前实现无法以极低的延迟为回调提供服务,因为在音频回调期间无法暂停垃圾收集。这意味着 AudioTrack 缓冲区的最小大小必须大于 OpenSL 缓冲区的最小大小才能维持无故障播放。

在大多数 Android 版本中,AudioTrack 和 OpenSL 之间的这种差异根本没有任何区别。但是有了 Jellybean,Android 现在有了一个低延迟的音频路径。实际延迟仍然取决于设备,但它可能比以前低得多。例如,http://code.google.com/p/music-synthesizer-for-android/在 Galaxy Nexus 上使用 384 帧缓冲区,总输出延迟低于 30 毫秒。这要求音频线程大约每 8 毫秒为缓冲区提供一次服务,这在以前的 Android 版本中是不可行的。在 Dalvik 线程中仍然不可行。

这种解释假设了两件事:首先,您从 OpenSL 请求尽可能小的缓冲区,并在缓冲区回调中进行处理,而不是使用缓冲区队列。其次,您的设备支持低延迟路径。在大多数当前设备上,您不会看到 AudioTrack 和 OpenSL ES 之间有太大区别。但在支持 Jellybean+ 和低延迟音频的设备上,OpenSL ES 将为您提供最低延迟路径。

关于Android:声音 API(确定性、低延迟),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7266298/

相关文章:

java - Android 选项卡式 Activity - 将微调器值从嵌套 fragment 传递到父 Activity 中的选项卡 fragment

android - 除了使用 LinearLayouts 和 layout_weight 之外,还有其他方法可以均匀分布 View 吗?

java - 结果显示图像上有衬里

java - JNI 应用程序状态

Android NDK线程无效使用非静态成员函数

android - 如何在设备中检索支持的 android JNI 版本?

android - 如何使用 android 中的相机捕获自定义图像大小?

android - 是否有适用于 Android 的最新图形数据库?

android - Firebase动态链接自动打开链接,无需等待AppInviteApi.getInvitation调用

android - 在 android 的 init.rc 中注册我的应用程序,以自动重启