Android AudioTrack:如何检测声音的结尾?

Android AudioTrack:如何检测声音的结尾?,android,audio,audiotrack,Android,Audio,Audiotrack,我正在使用AudioTrack在Android上播放PCM WAV声音文件(另请参阅)。流模式,工作线程。我想知道如何检测声音的结束,以便释放和释放音轨。write()调用似乎正在阻塞-但它是否会阻塞,直到所提供数据的回放完成?不太确定 是我,还是这门课上的文件少得可怜?如果您碰巧有一个指向AudioTrack的非官方指南的链接,我很乐意看一个。根据我的经验,AudioTrack.write()调用会一直阻塞,直到数据写入硬件的音频缓冲区 因此,在write()完成后,音频将被保证播放。基本上它

我正在使用
AudioTrack
在Android上播放PCM WAV声音文件(另请参阅)。流模式,工作线程。我想知道如何检测声音的结束,以便释放和释放
音轨
write()
调用似乎正在阻塞-但它是否会阻塞,直到所提供数据的回放完成?不太确定


是我,还是这门课上的文件少得可怜?如果您碰巧有一个指向
AudioTrack
的非官方指南的链接,我很乐意看一个。

根据我的经验,
AudioTrack.write()
调用会一直阻塞,直到数据写入硬件的音频缓冲区

因此,在
write()
完成后,音频将被保证播放。基本上它工作得很好

要更精确地检测音频结束,请使用
AudioTrack.setNotificationMarkerPosition()
AudioTrack.setPlaybackPositionUpdateListener()
。注意
setNotificationMarkerPosition()
对音频样本(而不是字节)进行计数,因此如果您的音频是16位样本,则位置将为dataSize/2

我的项目中有一个例子:

我不知道有什么指南,但您可以直接找到源代码:那里几乎没有Java逻辑—都是对本机函数的调用。对—但这是了解其工作原理的起点。您也可以随时查看本机代码。现在让我们看看,如果我不知道底层API的话,我是否能够理解逻辑。在大多数简单的情况下,你肯定是对的,但你的陈述是错的。write()并不总是保证它播放它得到的内容。查看下一条评论。阅读文档:在流模式下,阻塞行为取决于写入模式。如果写入模式为写入阻塞,则写入通常会阻塞,直到所有数据排队等待播放,并将返回完整的传输计数。但是,如果写入模式为“写入非阻塞”,或者曲目在输入时停止或暂停,或者另一个线程通过调用“停止”或“暂停”中断写入,或者在写入过程中发生I/O错误,则写入可能会返回一个短的传输计数。“因此,如果音频是16位采样,则位置将为dataSize/2”不精确,这取决于不止一件事。每个通道中每个数据的通道数和字节数。这种简单的计算只适用于线性未压缩音频,如PCM,请参见AudioFormat#getBytesPerSample()。