【问题标题】:Understanding AudioTrack Assertion in Android了解 Android 中的 AudioTrack 断言
【发布时间】:2016-03-14 23:15:29
【问题描述】:

在我的 Android 应用程序中,我使用 AudioTrack API 来输出从 RFCOMM 蓝牙连接接收到的音频字节。音频按预期播放,非常清晰。但是,由于 AudioTrackShared.cpp 中的以下断言,应用程序偶尔会崩溃:

stepCount <= mUnreleased && mUnreleased <= mFrameCount

我不太确定这个断言意味着什么,但有人知道什么可能导致这个问题吗?如果需要,我可以提供额外的源代码:

我对 AudioTrack 的设置:

int minSize = AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_8BIT);
mAudioPlayer = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_8BIT, minSize * 4, AudioTrack.MODE_STREAM);

【问题讨论】:

  • 您是否重用了写入 AudioTrack 的缓冲区?
  • @MimmoGrottoli 每次写入 AudioTrack 时,我都会创建一个大小为 64 的新数组。
  • 是你从 AudioTrach.getMinBufferSize 得到的值吗?
  • 不是,但我不明白为什么会导致问题?
  • 我相信你用很少的字节喂 AudioTrack,但这是一个假设。您在创建 AudioTrack 时是否尝试过仅使用 minSize 而不是 minSize * 4?

标签: java android audiotrack


【解决方案1】:

隐藏的错误

错误audioBuffer 大小与minBufferSize 直接相关。假设这两者必须相同,即使不是误用,也是对 API 的误解。 (†)

此明显修复背后的原因是,具有相同的大小可确保 audioBuffermAudioPlayer.write(audioBuffer, 0, audioBuffer.length) 期间每次、每次都被完整复制。

崩溃的实际原因是audioBuffer,当大于minBufferSize时,可能没有被完整复制,然后在mAudioPlayer.write(audioBuffer, 0, audioBuffer.length)有机会完成之前被丢弃。

解决方案

  • 检查audioBuffer 分配和解除分配
  • 在多线程或异步环境中,确保在分配之间使用了 audioBuffer

(†)

  1. AudioTrack 缓冲区大小 > audioBuffer 大小:
    您可能有许多小数据包不规律地到达,可以利用AudioTrack 缓冲系统来弥补这些不规律性

  2. AudioTrack 缓冲区大小 == audioBuffer 大小:
    1对1匹配; mAudioPlayer.write 几乎可以保证在返回时已将 audioBuffer 完全复制到 AudioTrack 缓冲区中

  3. AudioTrack 缓冲区大小 audioBuffer 大小:
    轨道将根据需要遍历audioBufferaudioBuffer 生命周期更好持续足够长的时间

在所有情况下,audioBuffer 必须保持分配状态直到被使用,并且在数据用完之前将一个缓冲区呈现给mAudioPlayer.write,以避免播放中的间隙。

【讨论】:

    【解决方案2】:

    使 AudioTrack 缓冲区大小与从 minBufferSize 获得的相同。这可以解决您的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多