Android:声音 API(确定性、低延迟) [英] Android: sound API (deterministic, low latency)

查看:23
本文介绍了Android:声音 API(确定性、低延迟)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm reviewing all kinds of Android sound API and I'd like to know which one I should use. My goal is to get low latency audio or, at least, deterministic behavior regarding delay of playback.

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

We've had a lot of problems and it seems that Android sound API is crap, so I'm exploring possibilities.

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

The problem we have is that there is significant delay between sound_out.write(sound_samples); and actual sound played from the speakers. Usually it is around 300 ms. The problem is that on all devices it's different; some don't have that problem, but most are crippled (however, CS call has zero latency). The biggest issue with this ridiculous delay is that on some devices this delay appears to be some random value (i.e. it's not always 300ms).

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

I'm reading about OpenSL ES and I'd like to know if anybody had experience with it, or it's the same shit but wrapped in different package?

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

I prefer to have native access, but I don't mind Java layer indirection as long as I can get deterministic behavior: either the delay has to be constant (for a given device), or I'd like to get access to current playback position instead of guessing it with a error range of ±300 ms...


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


1.5 years later I tried multiple android phones to see how I can get best possible latency for a real time voice communication. Using specialized tools I measured the delay of waveout path. Best results were over 100 ms, most phones were in 180ms range. Anybody have ideas?

推荐答案

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

SoundPool is the lowest-latency interface on most devices, because the pool is stored in the audio process. All of the other audio paths require inter-process communication. OpenSL is the best choice if SoundPool doesn't meet your needs.

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

Why OpenSL? AudioTrack and OpenSL have similar latencies, with one important difference: AudioTrack buffer callbacks are serviced in Dalvik, while OpenSL callbacks are serviced in native threads. The current implementation of Dalvik isn't capable of servicing callbacks at extremely low latencies, because there is no way to suspend garbage collection during audio callbacks. This means that the minimum size for AudioTrack buffers has to be larger than the minimum size for OpenSL buffers to sustain glitch-free playback.

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

On most Android releases this difference between AudioTrack and OpenSL made no difference at all. But with Jellybean, Android now has a low-latency audio path. The actual latency is still device dependent, but it can be considerably lower than previously. For instance, http://code.google.com/p/music-synthesizer-for-android/ uses 384-frame buffers on the Galaxy Nexus for a total output latency of under 30ms. This requires the audio thread to service buffers approximately once every 8ms, which was not feasible on previous Android releases. It is still not feasible in a Dalvik thread.

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

This explanation assumes two things: first, that you are requesting the smallest possible buffers from OpenSL and doing your processing in the buffer callback rather than with a buffer queue. Second, that your device supports the low-latency path. On most current devices you will not see much difference between AudioTrack and OpenSL ES. But on devices that support Jellybean+ and low-latency audio, OpenSL ES will give you the lowest-latency path.

这篇关于Android:声音 API(确定性、低延迟)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆