我的Android应用使用SoundPool播放简短的wav语音片段。对于连接的某些蓝牙扬声器,可以截断初始播放,并且可以听到其余部分。通过本地电话扬声器输出都很好。
Soundpool是低延迟的。某些蓝牙扬声器可能会滞后于电源管理中的睡眠。我主要考虑蓝牙4.x,目前使用Android 7.0,但用户将使用其他版本。
是否有最佳做法来弥补这种情况?我应该在语音片段中添加一个无声的领导者(例如' X'毫秒) - 让蓝牙时间唤醒,以便之后能够正常听到重要部分吗?某些声音文件规格是否首选?游戏程序员的任何见解?
谢谢!
我的代码初始化soundPool(带有声音ID的散列图)并播放声音以及释放和停止soundPool。在我的主程序中调用playSound的示例是SoundPoolManager.getInstance()。playSound(R.raw._whistle);
public void InitializeSoundPool(Activity activity, final ISoundPoolLoaded callback) throws Exception {
if (sounds == null || sounds.size() == 0) {
throw new Exception("Sounds not set");
}
int maxStreams = 1;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
soundPool = new SoundPool.Builder()
.setMaxStreams(maxStreams)
.build();
} else {
soundPool = new SoundPool(maxStreams, AudioManager.STREAM_MUSIC, 0);
}
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
SoundSampleEntity entity = getEntity(sampleId);
if (entity != null) {
entity.setLoaded(status == 0);
}
if (sampleId == maxSampleId()) {
callback.onSuccess();
}
}
});
int length = sounds.size();
hashMap = new HashMap<Integer, SoundSampleEntity>();
int index;
for (index = 0; index < length; index++) {
hashMap.put(sounds.get(index), new SoundSampleEntity(0, false));
}
index = 0;
for (Map.Entry<Integer, SoundSampleEntity> entry : hashMap.entrySet()) {
index++;
entry.getValue().setSampleId(soundPool.load(activity, entry.getKey(), index));
}
}
public void playSound(int resourceId) {
if (isPlaySound()) {
SoundSampleEntity entity = hashMap.get(resourceId);
if (entity.getSampleId() > 0 && entity.isLoaded()) {
soundPool.play(entity.getSampleId(), .99f, .99f, 1, 0, 1f);
}
}
}
public void release() {
if (soundPool != null) {
soundPool.release();
}
}
public void stop() {
if (soundPool != null) {
for (Map.Entry<Integer, SoundSampleEntity> entry : hashMap.entrySet()) {
SoundSampleEntity entity = entry.getValue();
soundPool.stop(entity.getSampleId());
}
}
}
我已经添加了一个SCO广播接收器:
public class SCOBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1) ==
AudioManager.SCO_AUDIO_STATE_CONNECTED) {
// SCO now connected
SoundPoolManager.isPlaySound = true;
Log.e("SCOBroadcastReceiver", "SCO_AUDIO_STATE_CONNECTED");
} else if (intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1) ==
AudioManager.SCO_AUDIO_STATE_DISCONNECTED) {
// SCO now disconnected
SoundPoolManager.isPlaySound = false;
Log.e("SCOBroadcastReceiver", "SCO_AUDIO_STATE_DISCONNECTED");
}
}
}
之后我运行的应用程序的日志输出是:
03-09 13:08:34.160 2615-2615 / com.foobar.foo E / SCOBroadcastReceiver:SCO_AUDIO_STATE_CONNECTED 03-09 13:08:39.404 2615-2615 / com.foobar.foo W / AudioTrack:服务器拒绝了AUDIO_OUTPUT_FLAG_FAST; frameCount 70229 03-09 13:09:09.278 2615-2615 / com.foobar.foo W / AudioTrack:服务器拒绝了AUDIO_OUTPUT_FLAG_FAST; frameCount 78728 03-09 13:09:21.312 2615-2615 / com.foobar.foo W / AudioTrack:服务器拒绝了AUDIO_OUTPUT_FLAG_FAST; frameCount 79623 03-09 13:09:33.345 2615-2615 / com.foobar.foo W / AudioTrack:服务器拒绝了AUDIO_OUTPUT_FLAG_FAST; frameCount 73808 03-09 13:09:45.377 2615-2615 / com.foobar.foo W / AudioTrack:服务器拒绝了AUDIO_OUTPUT_FLAG_FAST; frameCount 43391 03-09 13:09:57.400 2615-2615 / com.foobar.foo W / AudioTrack:服务器拒绝了AUDIO_OUTPUT_FLAG_FAST; frameCount 46074 03-09 13:10:09.425 2615-2615 / com.foobar.foo W / AudioTrack:服务器拒绝了AUDIO_OUTPUT_FLAG_FAST; frameCount 46075
答案 0 :(得分:1)
您应首先启动蓝牙SCO然后再播放。这将及时唤醒扬声器。