java - Android实现同步音效

标签 java android

我正在制作一款 Android 游戏,需要在玩家与游戏对象交互时实现无延迟的音效。为了简单起见,对象在屏幕上移动,玩家必须点击它们才能触发声音效果。我遇到的问题是,当玩家在短时间内点击许多对象时,每个声音效果之间存在明显的延迟。例如,玩家点击对象 1,声音播放,点击对象 2,声音播放,一直持续到玩家点击对象 n,声音播放,但听起来比之前播放的音效有点延迟。

我尝试设置我的 SoundPool 对象以从同一资源加载不同的声音,但它似乎没有多大作用。那么有没有一种方法可以让音效的每次迭代都重叠,甚至停止上一次的音效迭代被新的音效替换,而不会出现明显的声音延迟呢?下面是我的代码:

protected SoundPool mSoundPool;
protected boolean mLoaded;
protected int mBalloonPopStreams = 5;
protected int[] mSoundIds;
protected int mSoundIdx = 0;

protected void initializeMedia() {
    this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
    mSoundPool = new SoundPool(mBalloonPopStreams, AudioManager.STREAM_MUSIC, 0);

    mSoundIds = new int[mBalloonPopStreams];
    for (int i = 0; i < mBalloonPopStreams; i++) {
        mSoundIds[i] = mSoundPool.load(this, R.raw.sound_effect, 1);
    }
    mSoundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
        @Override
        public void onLoadComplete(SoundPool soundPool, int sampleId,
                int status) {
            mLoaded = true;
        }
    });
}

protected OnTouchListener mTouchEvent = new OnTouchListener() {
    @Override
    public boolean onTouch(View arg0, MotionEvent arg1) {           
        int action = arg1.getAction();
        int actionCode = action & MotionEvent.ACTION_MASK;
        int pointerId = action >> MotionEvent.ACTION_POINTER_ID_SHIFT;
        int x;
        int y;

        x = (int)arg1.getX(pointerId);
        y = (int)arg1.getY(pointerId);
        if (actionCode == MotionEvent.ACTION_DOWN || actionCode == MotionEvent.ACTION_POINTER_DOWN) {
            // Check if the player tapped a game object
            playSound();
        }


        return true;
    }
};

public void playSound() {
    if (mLoaded) {
        synchronized(mSoundPool) {
            AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
            float actualVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
            float maxVolume = (float) audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
            float volume = actualVolume / maxVolume;
            mSoundPool.play(mSoundIds[mSoundIdx], volume, volume, 1, 0, 1f);
            mSoundIdx = ++mSoundIdx % mBalloonPopStreams;   
        }
    }
}

总而言之,问题在于,假设要在 1 秒内播放 5 次“啪”声。我听到爆裂声播放了 5 次,但它们有延迟并且与游戏中实际发生的情况不同步。这可能是硬件的限制吗?如果不是,那么我是否错误地实现了我的代码?有哪些解决方法可以解决此问题?

最佳答案

This answer类似的问题可能会有所帮助。该问题的 OP 是,如果他们尝试使用 SoundPool 播放多个声音,他们的应用程序就会崩溃,但这可能是同一问题的不同症状。

关于java - Android实现同步音效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8146740/

相关文章:

android - 在 DrawerLayout 中滚动时标题后面的项目列表

android - 生成签名 APK : Project Name

java - Java中是否允许空字符串作为枚举成员

java - 如何在底部导航 View 中的每个项目名称下方添加行( View )?

java - 应用程序在菜单膨胀时崩溃。如何纠正?

android - 连接 VPN 时缺少 ConnectivityManager

java - 如何从 xml 中的 TextView 获取文本并使用共享按钮共享?

Java:创建具有最大大小的实例

java - 在 tabWidget 中跳过一行

线性布局的Android幻灯片动画