在AudioTrack上播放非阻塞数据

时间:2013-01-21 20:47:06

标签: android audiotrack

我正在实施一个RTP接收器。它接收UDP数据包,解码编解码器并将PCM样本写入AudioTrack进行回放。一个问题似乎是,AudioTrack.write正在阻塞,因此我会在此期间错过UDP数据包。

有没有关于如何处理这个问题的已知解决方案?

我尝试将自己的缓冲区用于音频数据和setNotificationMarkerPosition,但似乎只有在缓冲区填充到某种程度时才会播放音频轨道,因此永远不会达到标记位置或{{1}再次变得阻塞。

我还尝试在每次写入之前执行audioTrack.write,然后再次audioTrack.pause(),但这似乎会显着影响音质。

2 个答案:

答案 0 :(得分:3)

我不知道你是否解决了你的问题,我有一些问题。我能做的最好的事情是将一个线程中的UDP数据包抓取到ArrayBlockingQueue(ABQ)中,然后在另一个从ABQ中逐个获取的线程中播放它们。但是这次播放受到影响(并非所有设备都有,一些设备很酷,双线程),ABQ的大小增加,这意味着延迟增加。因此,我检查大小并系统地丢弃一些数据包(只是不写入AudioTrack)以减少延迟,但如果你对延迟没问题就是你的电话。

还有一件事,我正在增加线程的优先级:

private class Player extends Thread {
  public void run() {
     Process.setThreadPriority(Process.THREAD_PRIORITY_AUDIO );
       ....
  }
}

提供更好的速度。

解决方案仍然以某种方式阻塞,但是UDP数据包不会被播放器阻止,直到ABQ大小增加为容量。

答案 1 :(得分:0)

我认为我可能比“添加缓冲区和线程”解决方案更具吸引力。该解决方案为您的(可能)延迟敏感系统增加了一些延迟。这是你可以做的:

注意AudioTrack的缓冲区大小。然后跟踪在最后X毫秒内已经写入缓冲区的字节数(这应该以不太强大的计算方式实现),其中X是您可以适应的音频的毫秒数。缓冲区(基于缓冲区大小和采样率和量化速率(位/样本)和通道数的简单计算)。如果您在X毫秒内写入“缓冲​​区大小”数据量,那么您应该删除音频数据包。请注意,丢弃数据包也将成为“添加缓冲区和线程”解决方案的症状。

您可能想要添加一个小阈值,以便您永远不会实际填充缓冲区(假设缓冲区比实际缓冲区小一点)。

祝你好运!