5

I have a small app that basically sets up a timer and plays sets of 2 sounds one after another.

I've tried 2 timers, because I wanted both sounds to start exactly at the same time each time. I gave the app 500ms for setting both timers before they start

    Calendar cal = Calendar.getInstance();
    Date start = new Date(cal.getTime().getTime() + 500);

    timerTask1 = new TimerTask() { //1st timer
      @Override
      public void run() {
          soundManager.playSound(1);
      }
    };
    timer1 = new Timer();
    timer1.schedule(timerTask1, start, 550);


    timerTask2 = new TimerTask() { //2nd timer
      @Override
      public void run() {
          soundManager.playSound(2);
      }
    };
    timer2 = new Timer();
    timer2.schedule(timerTask2, start, 550);
}

soundManager is a SoundManager object which is based on this tutorial. Thew only change I've made was decreasing number of avalible streams from 20 to 2 since I play only 2 sounds at the same time.

Now the problem. It's not playing at the equal rate neither on my Motorola RAZR or the emulator. The app slows sometimes, making a longer brake than desired. I can't let that happen. What could be wrong here?

I'm using very short sounds in OGG format

EDIT: I've made some research. Used 2 aproaches. I was measuring milisecond distances between sound was fired. Refresh rate was 500 ms.

  • 1st aproach was TimerTask - it is a big fail. It started at 300ms, then was constantly growing, and after some time (2 mins) stabilized at 497ms which would be just fine if it started as that.
  • 2nd aproach was while loop on AsyncTask - it was giving me outputs from 475 to 500ms which is better than TimerTask but still inaccurate

At the end none of aproach was playing smoothly. There were always lags

4

2 回答 2

5

我知道这可能有点太多了,但你可以尝试不同的 SoundPool 实现:

public class Sound {
    SoundPool soundPool;
    int soundID;

    public Sound(SoundPool soundPool, int soundID) {
        this.soundPool = soundPool;
        this.soundID = soundID;
    }

    public void play(float volume) {
        soundPool.play(soundID, volume, volume, 0, 0, 1);
    }

    public void dispose() {
        soundPool.unload(soundID);
    }
}

要使用它,您可以执行以下操作:

SoundPool soundPool = new SoundPool(20, AudioManager.STREAM_MUSIC, 0);
AssetFileDescriptor assetFileDescriptor = activity.getAssets().openFd(fileName);
int soundID = soundPool.load(assetFileDescriptor, 0);

Sound sound = new Sound(soundPool, soundID);

然后播放:

sound.play(volume);

PS如果即使使用此代码问题仍然存在,请发表评论,我会回复您。

于 2012-08-26T12:17:04.040 回答
1

您在使用 SoundPool 吗?它比 MediaPlayer 更快。将两种声音放在一起的最佳机会是在同一线程上播放它们。

于 2012-08-24T10:39:18.787 回答