jn_*_*pdx 10 java audio android audiotrack
我有一个应用程序,我使用AudioTrack流媒体模式播放动态生成的音频.该应用程序不必立即响应输入,因此延迟问题不会打扰我的程序的那一面.
问题是我有一个动画需要与音频尽可能精确地"同步",似乎不同的设备在AudioTrack停止阻止write()呼叫和要求更多数据之间有不同的时间量,并且从扬声器播放音频.
我目前的解决方案让我大部分都在那里 - 我计算AudioTrack到目前为止我传入的帧数,并将其与之进行比较getPlaybackHeadPosition().它看起来基本上像:
long currentTimeInFrames = 0;
while(playingAudio) {
currentTimeInFrames += numberOfFramesToWrite;
long delayInFrames = (currentTimeInFrames - audioTrack.getPlaybackHeadPosition());
audioTrack.write(frameBuffer,0,sampleSize);
doAnimationAfterDelay(delayInFrames);
}
Run Code Online (Sandbox Code Playgroud)
但是,仍然存在一些getPlaybackHeadPosition()似乎没有因设备而异的延迟.
有没有办法在系统中轮询AudioTrack的延迟?
AudioTrackAPI 级别 19 添加了一个名为 getTimeStamp()的方法。从文档中:
按需轮询时间戳。
如果您需要在初始预热期间或在路由或模式更改之后跟踪时间戳,则应定期请求新的时间戳,直到报告的时间戳显示帧位置正在前进,或者直到明确时间戳不可用于该路由。
您指定一个AudioTimestamp对象作为函数的参数,它将填充最近“呈现”的帧位置及其“估计”时间戳(以纳秒为单位)。纳秒值对应于SystemClock.uptimeMillis()返回的毫秒值。
然后,您可以通过计算该特定帧写入的时间与AudioTrack实际getTimestamp()呈现的时间来确定延迟。我发现这种方法比上面提到的其他方法更准确。
不过你必须小心。文档说getTimeStamp()并非所有平台或所有路线都支持。您可以通过检查返回值来判断调用是否成功boolean。我发现在我测试过的设备上,该函数返回 false,直到音频开始呈现,然后后续调用返回 true。我只在AudioTrackinSTREAM_MUSIC模式下进行过测试。你的旅费可能会改变。
考虑驱动程序的延迟。有隐藏函数 AudioManager.getOutputLatency(int) 来获取它。
像这样称呼它:
AudioManager am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
try{
Method m = am.getClass().getMethod("getOutputLatency", int.class);
latency = (Integer)m.invoke(am, AudioManager.STREAM_MUSIC);
}catch(Exception e){
}
Run Code Online (Sandbox Code Playgroud)
我在不同的设备上得到了大约 45 - 50 毫秒的时间。在计算中使用结果。
| 归档时间: |
|
| 查看次数: |
3987 次 |
| 最近记录: |