Android上的低延迟audio播放
我目前正试图最小化一个简单的应用程序的audio延迟:
我在PC上有一个video,我通过RTP将video的audio传输到移动客户端。 使用非常相似的缓冲algorithm,我可以在iOS上实现90毫秒的延迟,但在Android上可达到±180毫秒。
我猜测这种差异源于Android上众所周知的延迟问题 。
然而,在阅读了一下之后, 我发现了这篇文章 ,里面写道:
-
低延迟audio从某些设备的Android 4.1 / 4.2版本开始可用。
-
低延迟audio可以使用libpd(Android的Pure Data library)来实现 。
我有两个问题,直接关系到那两个陈述:
-
我在哪里可以find有关Jellybean中新的低延迟audio的更多信息? 这是我能find的所有东西,但缺乏具体的信息 。 如果这些变化对我来说是透明的,还是有一些新的类/ API调用,我应该为我注意到我的应用程序中的任何变化? 我正在使用AudioTrack API,我甚至不知道是否应该从这种改进中获益,或者我应该考虑用于audio播放的其他机制。
-
我应该看看使用libpd吗? 在我看来,这是我获得较低延迟的唯一机会,但是由于我一直认为PD是一个audio合成实用程序,它是否真的适合于从networkingstream中抓取帧并播放它的项目? 我没有真正做综合。 我跟着错误的线索?
另外还有一点需要注意的是,在有人提到OpenSL ES之前, 这篇文章明确表示,不应该期望延迟的改进。
“由于OpenSL ES是一个本地C API,调用OpenSL ES的非Dalvik应用程序线程没有Dalvik相关的开销,例如垃圾收集暂停,但除此之外,使用OpenSL ES没有额外的性能优势。特别是使用OpenSL ES不会导致比平台通常提供的更低的audio延迟,更高的调度优先级等。
对于Android 4.2.2以来的最低延迟,您应该执行以下操作,从最不明显的顺序排列:
-
如果可能,select支持FEATURE_AUDIO_PRO的设备,否则selectFEATURE_AUDIO_LOW_LATENCY。 (“低延迟”是50ms,单程<20ms)。
-
使用OpenSL。 Dalvik GC具有较低的分摊成本,但是在运行时需要比低延迟audio线程所允许的更多的时间。
-
在缓冲区队列callback中处理audio。 系统在比正常用户模式线程更有利的调度的线程中运行缓冲区队列callback。
-
使您的缓冲区大小为AudioManager.getProperty(PROPERTY_OUTPUT_FRAMES_PER_BUFFER)的倍数。 否则,你的callback偶尔会得到每个时间片两个电话,而不是一个。 除非你的CPU使用率真的很低,否则这可能会出现问题。 (在Android M上,由于缓冲区处理代码中的错误,使用EXACTLY系统缓冲区大小非常重要。)
-
使用AudioManager.getProperty提供的采样率(PROPERTY_OUTPUT_SAMPLE_RATE)。 否则,您的缓冲区将绕行系统重采样器。
-
切勿在缓冲区callback中进行系统调用或locking同步对象。 如果您必须同步,请使用无锁结构。 为了获得最佳效果,请使用完全等待的结构,如单读取器单写入器环形缓冲区。 开发人员的负担得到这个错误,并最终出现难以预料,难以debugging的故障。
-
使用向量指令,例如NEON,SSE或任何等效指令集在目标处理器上。
-
testing和测量你的代码。 跟踪运行需要多长时间 – 请记住,您需要了解最差情况的performance,而不是平均水平,因为最糟糕的情况是导致毛刺的原因。 并保守。 您已经知道,如果处理audio比播放audio要花费更多的时间,则永远不会得到低延迟。 但在Android上这一点更为重要,因为CPU频率波动很大。 您可以使用大约60-70%的CPUaudio,但请记住,随着设备变热或变凉,或WiFi或LTE无线电开始和停止等等,这将会改变。
低延迟audio不再是Android的一项新function,但它仍然需要在硬件,驱动程序,内核和框架上进行特定于设备的更改。 这意味着不同设备的延迟可能会有很大的变化,并且考虑到Android手机销售的价格有多less,可能总会有差异。 查找FEATURE_AUDIO_PRO或FEATURE_AUDIO_LOW_LATENCY,以确定符合您应用所需延迟标准的设备。
使用OpenSL ES时,您应该满足以下要求,以在Jellybean和更高版本的Android上获得低延迟输出:
-
audio应该是单声道或立体声,线性PCM。
-
audio采样率应该与输出本地速率相同(在某些设备上实际上可能不需要,因为如果供应商configuration它,
FastMixer
可以重新采样,但是在我的testing中,FastMixer
从44.1到48 kHz的上采样时出现明显的伪像)。 -
你的
BufferQueue
应该至less有2个缓冲区。 (这个要求已经被放宽了,见Glenn Kasten的这个提交 ,我不确定哪个Android版本最初出现,但猜测是4.4)。 -
您不能使用某些效果(例如,混响,低音增强,均衡,虚拟化…)。
在可能的情况下, SoundPool
类也将尝试在内部使用快速AudioTrack
(除了BufferQueue
部分外,与上述相同的标准也适用)。
从您的链接点1:
“低延迟audio
Android 4.2改进了对低延迟audio播放的支持,从使用OpenSL ES,Soundpool和audio发生器API的Android 4.1发行版对audio输出延迟的改进开始。 这些改进取决于硬件支持 – 提供这些低延迟audiofunction的设备可以通过硬件function常数向应用宣传其支持。“
您完整的引用forms:
“性能
由于OpenSL ES是本地C API,调用OpenSL ES的非Dalvik应用程序线程没有Dalvik相关的开销,例如垃圾收集暂停。 但是,除此之外,使用OpenSL ES没有额外的性能优势。 特别是,使用OpenSL ES不会导致比平台通常提供的更低的audio延迟,更高的调度优先级等。 另一方面,随着Android平台和特定设备实现的不断发展,OpenSL ES应用程序可望从未来的系统性能改善中受益。“
所以,api与驱动程序交stream,然后hw是OpenSl(与Opengl用graphics相同的方式)。 虽然早期版本的Android在驱动程序和/或hw中的devise都很糟糕。 这些问题已经在4.1和4.2版本中得到了解决和纠正,所以如果高清有这个function,那么使用OpenSL就会获得较低的延迟。
同样,从puredata图书馆网站的这个注释中可以看出,图书馆使用OpenSL本身来实现低延迟:
对兼容设备的低延迟支持最新版本的Android版Pd(截至2012年12月28日)支持低延迟audio,以支持兼容的Android设备。 更新副本时,请确保从GitHub中获取最新版本的pd-for-android和libpd子模块。
在撰写本文时,Galaxy Nexus,Nexus 4和Nexus 10为audio输出提供低延迟音轨。 为了达到低延迟的轨道,应用程序必须使用OpenSL,并且必须以正确的采样率和缓冲区大小运行。 这些参数取决于设备(Galaxy Nexus和Nexus 10工作在44100Hz,而Nexus 4工作在48000Hz;每个设备的缓冲区大小不同)。
就像它的习惯一样,Pd for Android尽可能地复杂了所有这些复杂性,提供了新的低延迟function,同时保持向后兼容早期版本的Android。 在此基础上,Android的Pd的audio组件将使用Android 2.3及更高版本的OpenSL,而在Android 2.2及更早版本的Java中则会回落到原来的AudioTrack / AudioRecord API。
您对Android的10毫秒问题(即Android上的低延迟audio)更感兴趣。 我们在Superpowered创build了Androidaudiopath延迟解释器。 请看这里:
http://superpowered.com/androidaudiopathlatency/#axzz3fDHsEe56
测量sampleRate和bufferSize的应用程序: https : //code.google.com/p/high-performance-audio/source/checkout和http://audiobuffersize.appspot.com/结果数据库;
- 如何取消注册BroadcastReceiver
- 如何处理:java.util.concurrent.TimeoutException:android.os.BinderProxy.finalize()10秒后超时错误?
- 检查目录是否存在于Android的SD卡上
- 编写向后兼容的Android代码
- FragmentTransactionanimation滑过顶部
- 如何使用不同的屏幕分辨率
- Android:在向ExpandableListView添加标题视图时发生ClassCastException
- 如何在android中以编程方式从像素中计算dp
- android:ViewPager和HorizontalScrollVIew