在Android低延迟音频播放 [英] Low-latency audio playback on Android

查看:470
本文介绍了在Android低延迟音频播放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我正在试图最小化一个简单的应用程序的音频延迟:

我有一台PC上的视频,和我通过发送RTP视频的音频到移动客户端。有了一个非常类似的缓冲算法,我可以实现延迟90毫秒的iOS上,但在Android上一个可怕的±180ms的。

我猜差从知名茎延迟问题在Android上。

不过,读绕了一下,<后href="http://createdigitalmusic.com/2012/07/android-high-performance-audio-in-4-1-and-what-it-means-plus-libpd-goodness-today/">I来到这篇文章,其中指出:

  1. 低延迟音频是在某些器件由于Android 4.1 / 4.2。

  2. 低延迟的音频可以使用 libpd,这是Android 的纯数据库来实现。

我有2个问题,直接关系到这些2语句:

  1. 我在哪里可以找到在杰利贝恩新的低延迟音频的更多信息? 这是所有我能找到,但它是非常缺乏的特定信息。如果变化是透明的我来说,还是有一些新的类/ API调用我应该执行我注意到在我的应用程序的任何变化?我使用的是AudioTrack API,我甚至不知道是否应该获得这一改进或利益,我应该寻找到一些其他机制的音频播放。

  2. 我应该考虑使用libpd?在我看来,就像它是唯一的机会,我已经实现更低的延迟,但因为我一直认为PD作为一个音频合成工具,是不是真的适合,只是抓住帧从网络流的项目并播放他们回来?我没有真的做任何合成。难道我下错了线索?

作为一个附加的注意事项,有人提到OpenSL ES之前,本文使得它很清楚,在潜伏期没有任何改进,应该使用它的预期:

  

作为OpenSL ES是一个原生的C API,非Dalvik的应用程序线程这   拨打OpenSL ES没有的Dalvik相关的开销,如垃圾   收集暂停。然而,没有额外的性能益处   于使用OpenSL的ES除此以外。特别是,使用OpenSL的   ES不导致较低的音频等待时间,更高的调度优先级,   等比什么平台通常提供。

解决方案

有关Android的延迟最低的为4.2.2版本,你应该做到以下几点,下令从最低到最高显而易见的:

  1. 接,支持低等待时间的音频,并且不具有侵略性的节电电路的装置。 (Galaxy Nexus的是目前低延迟冠军;像的Nexus 4和Nexus 7新设备具有更积极的和复杂的电源电路,具有相对较高的延迟)

  2. 使用OpenSL。在Dalvik GC具有较低的摊余成本,但它运行时,它花费的时间比低延迟的音频线可以让更多的时间。

  3. 在一个缓冲队列回调处理音频。该系统运行缓冲队列的回调线程,有更有利的安排比正常用户模式线程。

  4. 请您缓冲区大小AudioManager.getProperty(PROPERTY_OUTPUT_FRAMES_PER_BUFFER)的倍数。否则,你的回调偶尔会得到每时间片而不是一个两个电话。除非你的CPU使用率是真的很轻,这最终可能会出现毛刺。

  5. 使用由AudioManager.getProperty(PROPERTY_OUTPUT_SAMPLE_RATE)提供的采样率。否则,你的缓冲带通过该系统重采样绕道而行。

  6. 千万不要做一个系统调用或锁定缓冲区回调内部的同步对象。如果必须同步,使用无锁结构。为获得最佳效果,使用完全无等待结构,如单阅读器单写环形缓冲区。开发商负荷犯了这个错误,并最终与故障是联合国predictable,难以调试。

  7. 使用向量指令如霓虹灯,SSE,或任何等价的指令集是在你的目标处理器。

  8. 测试和测量你的code。跟踪它需要运行多长时间 - 记住,你需要知道最坏情况下的性能,而不是平均的,因为最坏的情况是什么原因造成的故障。而且是保守的。你已经知道,如果它需要更多的时间来处理你的声音比它打它,你将永远不会获得低延迟。但是,在Android上,你确实需要处理每个缓冲区显著的时间比它需要发挥它 - 现在好像播放时间的15%是针对Galaxy Nexus的一个不错的选择。

低延迟音频是Android一个相当新的功能,它要求框架的变化在硬件,驱动程序,内核,并拉断。这意味着,现在有很多的变化在等待时间,你可以从不同的设备期望。如果你不能得到你想要的延迟,你怪自己的code之前,自己动手做一个Galaxy Nexus的厚待和测试。并密切关注新版本 - 谷歌不这样做提高了Android的潜伏期又

I'm currently attempting to minimize audio latency for a simple application:

I have a video on a PC, and I'm transmitting the video's audio through RTP to a mobile client. With a very similar buffering algorithm, I can achieve 90ms of latency on iOS, but a dreadful ±180ms on Android.

I'm guessing the difference stems from the well-known latency issues on Android.

However, after reading around for a bit, I came upon this article, which states that:

  1. Low-latency audio is available since Android 4.1/4.2 in certain devices.

  2. Low-latency audio can be achieved using libpd, which is Pure Data library for Android.

I have 2 questions, directly related to those 2 statements:

  1. Where can I find more information on the new low-latency audio in Jellybean? This is all I can find but it's sorely lacking in specific information. Should the changes be transparent to me, or is there some new class/API calls I should be implementing for me to notice any changes in my application? I'm using the AudioTrack API, and I'm not even sure if it should reap benefits from this improvement or if I should be looking into some other mechanism for audio playback.

  2. Should I look into using libpd? It seems to me like it's the only chance I have of achieving lower latencies, but since I've always thought of PD as an audio synthesis utility, is it really suited for a project that just grabs frames from a network stream and plays them back? I'm not really doing any synthesizing. Am I following the wrong trail?

As an additional note, before someone mentions OpenSL ES, this article makes it quite clear that no improvements in latency should be expected from using it:

"As OpenSL ES is a native C API, non-Dalvik application threads which call OpenSL ES have no Dalvik-related overhead such as garbage collection pauses. However, there is no additional performance benefit to the use of OpenSL ES other than this. In particular, use of OpenSL ES does not result in lower audio latency, higher scheduling priority, etc. than what the platform generally provides."

解决方案

For lowest latency on Android as of version 4.2.2, you should do the following, ordered from least to most obvious:

  1. Pick a device that supports low-latency audio, and does not have aggressive power-saving circuitry. (Galaxy Nexus is currently the low-latency champ; newer devices like the Nexus 4 and Nexus 7 have more aggressive and complex power circuitry and have correspondingly higher latency.)

  2. Use OpenSL. The Dalvik GC has a low amortized cost, but when it runs it takes more time than a low-latency audio thread can allow.

  3. Process audio in a buffer queue callback. The system runs buffer queue callbacks in a thread that has more favorable scheduling than normal user-mode threads.

  4. Make your buffer size a multiple of AudioManager.getProperty(PROPERTY_OUTPUT_FRAMES_PER_BUFFER). Otherwise your callback will occasionally get two calls per timeslice rather than one. Unless your CPU usage is really light, this will probably end up glitching.

  5. Use the sample rate provided by AudioManager.getProperty(PROPERTY_OUTPUT_SAMPLE_RATE). Otherwise your buffers take a detour through the system resampler.

  6. Never make a syscall or lock a synchronization object inside the buffer callback. If you must synchronize, use a lock-free structure. For best results, use a completely wait-free structure such as a single-reader single-writer ring buffer. Loads of developers get this wrong and end up with glitches that are unpredictable and hard to debug.

  7. Use vector instructions such as NEON, SSE, or whatever the equivalent instruction set is on your target processor.

  8. Test and measure your code. Track how long it takes to run--and remember that you need to know the worst-case performance, not the average, because the worst case is what causes the glitches. And be conservative. You already know that if it takes more time to process your audio than it does to play it, you'll never get low latency. But on Android you actually need to process each buffer in significantly less time than it takes to play it--currently it seems like 15% of playback time is a good choice for the Galaxy Nexus.

Low-latency audio is a fairly new feature for Android, and it requires changes in the hardware, drivers, kernel, and framework to pull off. This means that right now there's a lot of variation in the latency you can expect from different devices. If you can't get the latency you want, do yourself a favor and test on a Galaxy Nexus before you blame your own code. And keep an eye on new releases--Google is not done improving Android latency yet.

这篇关于在Android低延迟音频播放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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