Лаги при воспроизведении 2 звуков одновременно в таймере

У меня есть небольшое приложение, которое в основном устанавливает таймер и воспроизводит наборы из 2 звуков один за другим.

Я попробовал 2 таймера, потому что я хотел, чтобы оба звука запускались точно в одно и то же время каждый раз. Я дал приложению 500 мс для установки обоих таймеров до их запуска

    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 - это объект SoundManager, основанный на этом руководстве. Единственное изменение, которое я сделал, - это уменьшение количества доступных потоков с 20 до 2, так как я играю только 2 звука одновременно.

Теперь проблема. Он не играет с одинаковой скоростью ни на моем Motorola RAZR, ни на эмуляторе. Приложение иногда замедляется, делая более длительный тормоз, чем хотелось бы. Я не могу этого допустить. Что здесь может быть не так?

Я использую очень короткие звуки в формате OGG

РЕДАКТИРОВАТЬ: Я сделал некоторые исследования. Использовано 2 подхода. Я измерял миллисекундные расстояния между звуками. Частота обновления составила 500 мс.

  • Первым подходом был TimerTask - это большой провал. Он начался в 300 мс, затем постоянно рос, и через некоторое время (2 минуты) стабилизировался в 497 мс, что было бы просто замечательно, если бы началось так.
  • Второй подход был в то время как цикл на AsyncTask - он давал мне выходные данные от 475 до 500 мс, что лучше, чем TimerTask, но все еще неточно

В конце ни один из подходов не играл гладко. Всегда были лаги

2 ответа

Я знаю, что это может быть слишком много, но вы можете попробовать другую реализацию 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 Если проблема не исчезнет даже с этим кодом, оставьте комментарий, и я перезвоню вам.

Вы используете SoundPool? Это быстрее, чем MediaPlayer. Лучший шанс соединить два звука - это сыграть их в одном потоке.

Другие вопросы по тегам