【问题标题】:Playing generative sound with OpenSL使用 OpenSL 播放生成声音
【发布时间】:2014-02-06 17:30:01
【问题描述】:

我正在构建一个应用程序,它会产生声音(目前它主要是实验性的)并在 Android 手机上播放它。

现在我正在尝试播放简单的正弦波声音 (440 Hz),并首先尝试使用 Audiotrack,但遇到了一些缓冲区欠载。所以我决定看看 OpenSL。

现在我已经阅读了很多关于这方面的教程和博客文章,最后使用带有 Android 简单缓冲区队列的 OpenSL 引擎制作了自己的实现。

现在在缓冲区回调中,我生成了一个新的缓冲区数据并将其添加到队列中,但是延迟比音轨差得多(我可以听到每个缓冲区之间的间隙)。

我的问题是,在 OpenSL 中生成声音的最佳实践/架构是什么?我应该在另一个线程中填充缓冲区(然后需要一些与缓冲区回调同步的过程)吗?

我还没有找到有关生成声音的 OpenSL ES 教程(大多数是关于播放音频文件或将音频输入重定向到音频输出)。

【问题讨论】:

  • “延迟比音轨差很多(我可以听到每个缓冲区之间的间隙)”。在我看来,您在描述缓冲区不足(缓冲区正在排队,但尚未完全填满)。除非您在每个缓冲区之间停止并重新启动播放器对象,否则缓冲区之间应该没有延迟;当您第一次启动播放器对象时,只有第一个。至于你的问题;我只是使用缓冲区队列回调将下一个缓冲区排入队列,但我必须尝试不同的缓冲区大小才能找到一个有效的缓冲区。

标签: android android-ndk opensl


【解决方案1】:

关于延迟:为您的设备选择正确的采样率和缓冲区大小非常重要。您可以使用 Android SDK 的 AudioManager 查询设备的推荐值(PROPERTY_OUTPUT_SAMPLE_RATEPROPERTY_OUTPUT_FRAMES_PER_BUFFER 仅在 API 级别 17 中可用)并将值传递到 NDK 应用程序:

// getting the samplerate and buffer size
if ( android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 )
{
    AudioManager am = ( AudioManager ) aContext.getSystemService( Context.AUDIO_SERVICE );
    int sampleRate = Integer.parseInt( am.getProperty( AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE ));
    int bufferSize = Integer.parseInt( am.getProperty( AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER ));
}

正确获取采样率的重要性在于,如果它不同于设备的首选采样率(一些使用 48 kHz,另一些使用 44.1 kHz),音频在被硬件输出之前会通过系统重采样器,添加到整体延迟。此外,获得正确缓冲区大小的重要性是防止在几次缓冲区回调后样本/帧丢失,这可能会导致您描述的问题在回调之间发生间隙/故障的位置。您可以使用倍数(2 的幂)来减少/增加缓冲区大小,以试验更稳定的引擎(更大的缓冲区大小)和更快的响应(更小的缓冲区大小)。

在创建了一些简单的 Android 应用程序之后,我写了一篇小文章,稍微更详细地解释了上述建议以及如何构建音乐相关应用程序的基本序列引擎,但是页面只是一个基本的架构大纲,根据你的需要可能完全没用>Android audio engine in OpenSL

【讨论】:

  • 我不明白,谷歌将 Oboe 宣传为 api 16+,但 AudioManager 是 OpenSL 的必需品,并且需要 API 17。我很困惑。我的最低 sdk 是 api16 但现在我必须将其设为 17 吗?我不想失去 0.6% 的市场份额,有什么解决方法吗?
  • AudioManager 实际上可从 API 1 获得,但采样率和每个缓冲区的样本的属性仅在 API 17 中添加。OpenSL 实际上适用于 API 10。您可以为用户做的事情
  • 听起来很合理,谢谢。我想我会将我的 API 设置为 16 并尝试一下
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-19
  • 2013-10-04
  • 1970-01-01
  • 1970-01-01
  • 2021-12-02
  • 1970-01-01
相关资源
最近更新 更多