蓝牙延迟和Android音频提示

时间:2018-03-09 00:37:34

标签: android audio bluetooth

我的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

1 个答案:

答案 0 :(得分:1)

您应首先启动蓝牙SCO然后再播放。这将及时唤醒扬声器。