添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
神勇威武的楼梯  ·  Testing Types | Guide ...·  1 月前    · 
俊逸的萝卜  ·  电影喵 - 誉望电影百科·  1 月前    · 
有腹肌的烤红薯  ·  Windows11·  3 月前    · 
我正在编写一些旨在获取 Wave 文件的代码,并将其写入模式流中的 AudioTrack。这是使 AudioTrack 流模式工作的最小可行测试。但是一旦我将一些音频缓冲区写入 AudioTrack,然后调用 play(),getPlaybackHeadPosition() 方法就会不断返回 0。编辑:如果我忽略我的可用帧检查,只是不断地将缓冲区写入 AudioTrack,则 write 方法返回 0(在第一次缓冲区写入之后),表明它根本没有再写入任何音频。所以似乎 AudioTrack 只是不想开始播放。我的代码正确启动了音轨。play 方法没有抛出任何异常,所以我不确定出了什么问题。单步执行代码时,我的所有内容都与我的预期完全一致,所以我在想我的 AudioTrack 配置错误。我在模拟器上运行,但我认为这不应该是一个问题。我使用的 WavFile 类是一个经过审查的类,我已经在许多 Java 项目中可靠地运行它,它经过测试运行良好。观察以下日志写入,这是来自较大代码块的片段。此日志写入永远不会命中...                if (headPosition > 0)                    Log.e("headPosition is greater than zero!!");..public static void writeToAudioTrackStream(final WavFile wave)     {    Log.e("writeToAudioTrackStream");    Thread thread = new Thread()    {        public void run()        {            try {                final float[] data = wave.getData();                int format = -1;                if (wave.getChannel() == 1)                    format = AudioFormat.CHANNEL_OUT_MONO;                else if (wave.getChannel() == 2)                    format = AudioFormat.CHANNEL_OUT_STEREO;                else                    throw new RuntimeException("writeToAudioTrackStatic() - unsupported number of channels value = "+wave.getChannel());                final int bufferSizeInFrames = 2048;                final int bytesPerSmp = wave.getBytesPerSmp();                final int bufferSizeInBytes = bufferSizeInFrames * bytesPerSmp * wave.getChannel();                AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, wave.getSmpRate(),                        format,                        AudioFormat.ENCODING_PCM_FLOAT,                        bufferSizeInBytes,                        AudioTrack.MODE_STREAM);                int index = 0;                float[] buffer = new float[bufferSizeInFrames * wave.getChannel()];                boolean started = false;                int framesWritten = 0;
查看完整描述

TA贡献1824条经验 获得超5个赞

根据 文档

为了可移植性,应用程序应通过写入数据将数据路径设置为允许的最大值,直到 write() 方法返回一个短传输计数。这允许 play() 立即启动,并减少欠载的机会。

仔细阅读,这可能会与之前的说法相矛盾:

...您可以选择在调用 play() 之前初始化数据路径,方法是 写到 bufferSizeInBytes ...

(强调我的),但意图很清楚:你应该先写一篇短文。

这只是为了开始游戏。实际上,一旦发生这种情况,您就可以 getPlaybackHeadPosition() 用来确定何时有更多可用空间。我已经在我自己的代码中成功地使用了这种技术,在许多不同的设备/API 级别上。

顺便说一句:您应该准备好 getPlaybackHeadPosition() 仅以较大的增量进行更改(如果我没记错的话,它是 getMinBufferSize()/2 )。这是系统可用的最大分辨率; onMarkerReached() 不能用来做得更好。


查看完整回答