2011-11-16 91 views
1

我正在製作Android遊戲,當玩家與遊戲對象進行交互時,需要實現無滯後音效。爲了簡單起見,物體在屏幕上四處移動,玩家必須點擊它們才能觸發音效。我遇到的問題是,當玩家在很短的時間內敲擊很多物體時,每個音效之間會有明顯的延遲。例如,玩家敲擊對象1,播放聲音,敲擊對象2,播放聲音,並繼續前進,直到玩家敲擊對象n,聲音播放,但與之前播放的聲音效果聽起來有點延遲。Android實現同步音效

我試圖設置我的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; 
     } 
    } 
} 

概括起來,問題是,假設5「啪」的聲音要在1秒鐘內播放。我聽到彈出的聲音播放了5次,但是它們被延遲並與遊戲中實際發生的事情不同步。這可能是硬件限制嗎?如果沒有,那麼我是否錯誤地實現了我的代碼?這個問題有什麼解決方法?

回答

0

This answer到一個類似的問題可能會有所幫助。那個問題的OP是他們的應用程序崩潰,如果他們試圖用SoundPool播放多個聲音,但它可能是同一問題的不同症狀。

+0

這並沒有完全解決我的問題。由於我的聲音效果非常短暫,因此這個可馴服的隊列沒有做任何有意義的事情。我對SoundPool對象的關注是它允許同時播放音頻軌道,即每個聲音效果是否在不同的線程上播放? – Dan

0

使用AudioTrack代替SoundPool可能會獲得更好的結果,但代價是需要更多的代碼。