Android上的低延迟音频播放

时间:2013-02-12 22:11:33

标签: android audio opensl

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

我在PC上有一个视频,我正在通过RTP将视频的音频传输到移动客户端。使用非常相似的缓冲算法,我可以在iOS上实现90ms的延迟,但在Android上可以实现±180ms的可怕延迟。

我猜测差异源于Android上的well-known延迟issues

然而,在阅读了一下I came upon this article之后,其中指出:

  1. 自某些设备中的Android 4.1 / 4.2以来,可以使用低延迟音频。

  2. 使用libpd, which is Pure Data library for Android可以实现低延迟音频。

  3. 我有两个问题,与这两个陈述直接相关:

    1. 在哪里可以找到有关Jellybean中新的低延迟音频的更多信息? This is all I can find but it's sorely lacking in specific information。如果这些更改对我来说是透明的,或者是否有一些新的类/ API调用我应该实现我注意到我的应用程序中的任何更改?我正在使用AudioTrack API,我甚至不确定它是否应该从这种改进中获益,或者我是否应该考虑其他一些音频播放机制。

    2. 我应该考虑使用libpd吗?在我看来,这是我实现更低延迟的唯一机会,但由于我一直认为PD是一个音频合成实用程序,它是否真的适合于只从网络流中抓取帧并播放它们的项目?我不是在做任何合成。我跟踪错误的路径吗?

    3. 作为补充说明,在有人提及OpenSL ES之前,this article makes it quite clear that no improvements in latency should be expected from using it

        

      “由于OpenSL ES是本机C API,非Dalvik应用程序线程   调用OpenSL ES没有与Dalvik相关的开销,例如垃圾   收集暂停。但是,没有额外的性能优势   使用除此之外的OpenSL ES。特别是使用OpenSL   ES不会导致较低的音频延迟,较高的调度优先级,   等于平台通常提供的内容。“

7 个答案:

答案 0 :(得分:65)

对于Android版本4.2.2的最低延迟,您应该执行以下操作,从最不明显到最明显的排序:

  1. 如果可能,选择支持FEATURE_AUDIO_PRO的设备,否则选择FEATURE_AUDIO_LOW_LATENCY。 (“低延迟”是单程50ms; pro是<20ms往返。)

  2. 使用OpenSL。 Dalvik GC的摊销成本较低,但运行时需要的时间比低延迟音频线程所允许的时间长。

  3. 处理缓冲区队列回调中的音频。系统在一个比普通用户模式线程更有利的调度的线程中运行缓冲区队列回调。

  4. 使缓冲区大小为AudioManager.getProperty(PROPERTY_OUTPUT_FRAMES_PER_BUFFER)的倍数。否则,您的回调有时会每次拨打两次而不是一次。除非您的CPU使用率非常低,否则这可能会导致故障。 (在Android M上,由于缓冲区处理代码中的错误,完全使用系统缓冲区大小非常重要。)

  5. 使用AudioManager.getProperty(PROPERTY_OUTPUT_SAMPLE_RATE)提供的采样率。否则,您的缓冲区会绕过系统重新采样器。

  6. 永远不要在缓冲区回调中进行系统调用或锁定同步对象。如果必须同步,请使用无锁结构。为获得最佳效果,请使用完全等待的结构,例如单读取器单写入器环形缓冲区。大量的开发人员错了,最终导致无法预测且难以调试的故障。

  7. 使用向量指令,例如NEON,SSE或目标处理器上的等效指令集。

  8. 测试并测量您的代码。跟踪运行所需的时间 - 并记住您需要知道最坏情况的性能,而不是平均值,因为最坏的情况是导致故障的原因。保守。您已经知道,如果处理音频需要花费更多时间而不是播放音频,您将永远不会获得低延迟。但在Android上,这更为重要,因为CPU频率波动很大。您可以将60-70%的CPU用于音频,但请记住,这会随着设备变得更热或更冷,或者因为wifi或LTE无线电的启动和停止而改变,等等。

  9. 低延迟音频不再是Android的新功能,但仍需要硬件,驱动程序,内核和框架中特定于设备的更改才能实现。这意味着您可以从不同的设备中获得的延迟有很多变化,并且鉴于Android手机销售的价格有多少不同,可能总会存在差异。寻找FEATURE_AUDIO_PRO或FEATURE_AUDIO_LOW_LATENCY来识别符合您的应用所需延迟标准的设备。

答案 1 :(得分:6)

使用OpenSL ES时,您应该满足以下要求,以便在Jellybean和更高版本的Android上获得低延迟输出:

  • 音频应为单声道或立体声,线性PCM。

  • 音频采样率应与输出的本机速率相同(这可能在某些设备上实际上不需要,因为FastMixer 能够重新采样,如果供应商将其配置为这样做。但在我的测试中,当FastMixer)从44.1升频到48 kHz时,我得到了非常明显的伪像。

  • 您的BufferQueue应至少有2个缓冲区。 (此要求已经放宽了。请参阅Glenn Kasten的this commit。我不确定首次出现的Android版本,但猜测是4.4。)

  • 您不能使用某些效果(例如混响,低音增强,均衡,虚拟化......)。

SoundPool课程也会尝试在可能的情况下在内部使用快速AudioTrack(除BufferQueue部分外,适用上述标准相同)。

答案 2 :(得分:5)

从您点1的链接:

  

“低延迟音频

     

Android 4.2改进了对低延迟音频播放的支持   来自Android 4.1发布的音频输出改进   使用OpenSL ES,Soundpool和音频生成器API的延迟。这些   改进取决于硬件支持 - 提供这些的设备   低延迟音频功能可以通过宣传他们对应用的支持   硬件特征常量。“

您的完整形式的引用:

  

“性能

     

由于OpenSL ES是本机C API,非Dalvik应用程序线程   调用OpenSL ES没有与Dalvik相关的开销,例如垃圾   收集暂停。但是,没有额外的性能优势   使用除此之外的OpenSL ES。特别是使用OpenSL   ES不会导致较低的音频延迟,较高的调度优先级,   等于平台通常提供的内容。另一方面,作为   Android平台和特定设备实施继续   进化,OpenSL ES应用程序可望从任何未来中受益   系统性能改进。“

因此,与驱动程序通信的api然后是hw是OpenSl(与Opengl以图形方式相同的方式)。不过,早期版本的Android在驱动程序和/或hw中设计不佳。这些问题已通过4.1和4.2版本得到解决和纠正,因此如果高清电源具有电源,则使用OpenSL可以获得低延迟。

再次,从puredata库网站的这个注释中可以看出,该库使用OpenSL本身来实现低延迟:

  

对兼容设备的低延迟支持   最新版本的Pd for   Android(截至12/28/2012)支持兼容的低延迟音频   Android设备。更新副本时,请务必提取最新信息   pd-for-android的版本和GitHub的libpd子模块。

     

在撰写本文时,Galaxy Nexus,Nexus 4和Nexus 10提供了一个   用于音频输出的低延迟音轨。为了达到低延迟   跟踪,应用程序必须使用OpenSL,它必须正确运行   采样率和缓冲区大小。这些参数取决于设备   (Galaxy Nexus和Nexus 10的运行频率为44100Hz,而Nexus 4则运行   在48000Hz;每个设备的缓冲区大小不同。)

     

就像它不习惯的那样,用于Android的Pd将所有这些复杂性都归结为   尽可能提供对新的低延迟功能的访问   在可用的同时保持与之前的向后兼容   Android版本。在引擎盖下,Pd的音频组件   Android将在Android 2.3及更高版本上使用OpenSL,同时退回   在Android 2.2和Java上使用Java的旧AudioTrack / AudioRecord API   早。

答案 3 :(得分:3)

你们这些人对Android的10毫秒问题更感兴趣,即Android上的低延迟音频。我们Superpowered创建了Android Audio Path Latency Explainer。请看这里:

http://superpowered.com/androidaudiopathlatency/#axzz3fDHsEe56

答案 4 :(得分:2)

另一个使用音频延迟和缓冲区大小的数据库:

http://superpowered.com/latency/#table

源代码:

https://github.com/superpoweredSDK/SuperpoweredLatency

答案 5 :(得分:0)

答案 6 :(得分:0)

有一个新的C ++库Oboe,可帮助减少音频延迟。我已经在项目中使用了它,并且效果很好。 它具有有助于减少音频延迟的功能:

  
      
  • 自动延迟调整
  •   
  • 选择音频API(API 16+上的OpenSL ES或API 27+上的AAudio)
  •