【问题标题】:What is SLDataLocator_AndroidSimpleBufferQueue (Android 4.3)?什么是 SLDataLocator_AndroidSimpleBufferQueue (Android 4.3)?
【发布时间】:2014-03-26 12:07:29
【问题描述】:

下面的“2”代表什么:

SLDataLocator_AndroidSimpleBufferQueue loc_bq   =
{SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};

根据我的阅读,这是缓冲区的数量。

为什么是 2?为什么不只是 1 ?如果 2 更好,为什么不 10 让它变得更好呢?

谢谢

【问题讨论】:

  • 2 是与生成重叠播放所需的最小值(谷歌“双缓冲”)。在不定期安排回调的情况下,超过 2 个可能很有用。我见过使用超过 2 个缓冲区的示例代码。例如,PortAudio 为许多原生 API 使用了超过 2 个缓冲区。

标签: android c audio android-ndk opensl


【解决方案1】:

为什么是 2 个?

如果您有 2 个缓冲区,您可以在另一个正在播放时用新数据填充其中一个。另外,直到最近,如果您希望能够使用 Android 的低延迟音频路径,您还需要在缓冲区队列中至少有 2 个缓冲区。

为什么不只有 1 个?

如果您只有一个缓冲区,则用新数据填充缓冲区会变得非常棘手,因为您可能无法足够快地生成新数据。

如果 2 更好,为什么不 10 让它变得更好呢?

当您增加缓冲区数量时,您也会增加延迟(从您将缓冲区入队到播放该缓冲区的时间),假设您保持缓冲区大小相同。

【讨论】:

  • 我不确定我是否理解。如果调用用户的 openSL 扬声器回调实现,那是因为音频子系统已准备好接收更多扬声器数据。所以你说这不是真的吗?让我们举一个只有 1 个缓冲区的例子:在 t = 0 时调用 [1] 扬声器回调。缓冲区被 10 毫秒的音频填满。 [2] 在 t = 10ms 时调用扬声器回调。缓冲区充满了 10 毫秒的音频.....等等......所以你是说在 [2] 中写入缓冲区的数据可能会覆盖尚未呈现的数据(即使 openSL 调用更多数据)???
  • 在播放器消耗完缓冲区后,您将获得缓冲区队列回调,这意味着下一个要排队的数据必须立即准备好(即使这样我也不确定您是否'将能够在玩家想要开始消耗更多缓冲区数据之前将其入队)。如果您的缓冲区队列中有 2 个或更多缓冲区,则队列中仍会保留 1 个或更多缓冲区,这使您有一些时间来生成另一个缓冲区并将其排入队列。
  • 你说我在我的缓冲区被消耗后获得了缓冲区队列回调,然后 - 同时 - 你说你不确定我是否能够在玩家想要开始消耗更多数据。这没有意义。如果您收到回调,则播放器 准备好消耗更多数据,对吗?因此,如果在调用回调时保证数据可用,那么只有一个缓冲区就足够了;即回调被调用,数据入队,并且下次调用回调时入队的数据已被消耗,因此您将下一个数据入队
  • “只有一个缓冲区就足够了” 我只是说我不确定(因为没有什么是瞬时的)。您可以对其进行测试,看看它对于您的应用程序是否足够强大。
  • 考虑零拷贝情况:通常双缓冲的情况是一个缓冲区播放而另一个缓冲区被填充(类似于帧缓冲区交换图形)。只有一个缓冲区(正在播放或正在填充),无法向输出呈现连续的音频流。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-21
  • 2011-10-02
相关资源
最近更新 更多