Лаги при воспроизведении 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. Лучший шанс соединить два звука - это сыграть их в одном потоке.