我的应用程序中有一个AudioTrack,设置为Stream模式.我想写一些通过无线连接收到的音频.AudioTrack声明如下:
mPlayer = new AudioTrack(STREAM_TYPE,
FREQUENCY,
CHANNEL_CONFIG_OUT,
AUDIO_ENCODING,
PLAYER_CAPACITY,
PLAY_MODE);
Run Code Online (Sandbox Code Playgroud)
参数定义如下:
private static final int FREQUENCY = 8000,
CHANNEL_CONFIG_OUT = AudioFormat.CHANNEL_OUT_MONO,
AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT,
PLAYER_CAPACITY = 2048,
STREAM_TYPE = AudioManager.STREAM_MUSIC,
PLAY_MODE = AudioTrack.MODE_STREAM;
Run Code Online (Sandbox Code Playgroud)
但是,当我使用write()将数据写入AudioTrack时,它将播放不稳定...调用
byte[] audio = packet.getData();
mPlayer.write(audio, 0, audio.length);
Run Code Online (Sandbox Code Playgroud)
只要通过网络连接接收到数据包就会生成.有没有人知道为什么它听起来不稳定?也许它与WiFi连接本身有关?我不这么认为,因为当我通过UDP将数据从Android手机发送到另一个来源时,声音听起来并不可怕.声音听起来完整而且根本没有波动......所以有人知道为什么会发生这种情况吗?
您知道接收的每秒字节数,数据包之间的平均时间比较以及数据包之间的最大时间吗?如果没有,你可以添加代码来计算吗?
需要首先平均8000个样本/秒*2字节/采样= 每秒16000个字节,以保持填充流.
传入数据包之间的间隔超过2048字节/(16000字节/秒)= 128毫秒将导致您的流干运行并且音频断断续续.
防止它的一种方法是增加缓冲区大小(PLAYER_CAPACITY).较大的缓冲区将能够更好地处理传入数据包大小和速率的变化.额外稳定性的成本是在等待缓冲区初始填充时开始播放的较大延迟.
我已经通过放入mPlayer.write(audio, 0, audio.length);它自己的部分解决了它Thread.这确实消除了一些不稳定因素(由于写入是阻塞呼叫的事实),但是在一秒钟或2秒之后它仍然听起来不稳定.它仍然有2-3秒的显着延迟.
new Thread(){
public void run(){
byte[] audio = packet.getData();
mPlayer.write(audio, 0, audio.length);
}
}.start();
Run Code Online (Sandbox Code Playgroud)
只是有点匿名Thread,现在写作...
有人知道如何解决这个问题吗?
编辑:
经过一些进一步的检查和调试后,我注意到这是gainBuffer的一个问题.我查看了AudioTrack的java代码和AudioTrack的C++代码.我注意到它只能出现在C++代码中.
if (__builtin_expect(result!=NO_ERROR, false)) {
LOGW( "obtainBuffer timed out (is the CPU pegged?) "
"user=%08x, server=%08x", u, s);
mAudioTrack->start(); // FIXME: Wake up audioflinger
timeout = 1;
}
Run Code Online (Sandbox Code Playgroud)
我注意到FIXME这段代码中有一个.:<但无论如何,有谁可以解释这个C++代码是如何工作的?我有过一些经验,但它从未如此复杂......
编辑2:
我现在尝试了一些不同,不同之处在于我缓冲了我收到的数据,然后当缓冲区充满了一些数据时,它被写入播放器.然而,玩家继续消耗几个周期,然后obtainBuffer timed out (is the CPU pegged?)警告开始,并且没有任何数据写入玩家,直到它开始恢复生命......之后,它将不断获取数据到它,直到缓冲区被清空.
另一个细微的差别是我现在将文件流式传输到播放器.也就是说,以块的形式读取它,将这些块写入缓冲区.这模拟了通过wifi接收的包裹......
我开始怀疑这是否只是Android的操作系统问题,而且我不能自己解决这个问题......有人对此有什么想法吗?
编辑3:
我做了更多测试,但这对我没有任何帮助.这个测试告诉我,当我第一次尝试写入AudioTrack时,我只会遇到延迟.这需要1到3秒才能完成.我通过使用以下代码来完成此操作:
long beforeTime = Utilities.getCurrentTimeMillis(), afterTime = 0;
mPlayer.write(data, 0, data.length);
afterTime = Utilities.getCurrentTimeMillis();
Log.e("WriteToPlayerThread", "Writing a package took " + (afterTime - beforeTime) + " milliseconds");
Run Code Online (Sandbox Code Playgroud)
但是,我得到以下结果: Logcat Image http://img810.imageshack.us/img810/3453/logcatimage.png
这些表明滞后最初发生在开始,之后AudioTrack不断获取数据...我真的需要修复这个...
| 归档时间: |
|
| 查看次数: |
7105 次 |
| 最近记录: |