Замедление таймера метронома (с помощью обработчика или потоков) - PullRequest
1 голос
/ 27 октября 2010

У меня есть простое, классическое утверждение, что каждые 200 миллисекунд воспроизводится звук (метроном).

Я написал это с помощью обработчиков, а затем по-другому, используя потоки. Проблема одинакова в обоих случаях: когда я нажимаю аппаратную кнопку «домой» или просто когда я нажимаю кнопку, чтобы открыть ListView, метроном на какое-то время ужасно замедляется.

Эта проблема (не такая сильная, но, тем не менее, присутствует) представляет собой также ничего не делать и оставлять приложение на переднем плане.

Есть идеи?

Вот код:

открытый класс Metronome реализует Runnable {

private Handler mHandler = new Handler();
public static long mStartTime;

Main mainContext; 

public Metronomo(Main context) {
    mainContext = context;
}


public void play() {
    mStartTime = System.currentTimeMillis();
    mHandler.postDelayed(this, 100);
}

public final void stop(){
    mHandler.removeCallbacks(this);
}

public void run(){
        //play the ogg file in position 1
        mSoundManager.playSound(1);

        //reschedule the next playing after 200ms
        mHandler.postAtTime(this, SystemClock.uptimeMillis() + 200);
   }

};

Ответы [ 3 ]

0 голосов
/ 27 октября 2010

Кажется, мой телефон может воспроизводить миди-файлы, которые представляют собой довольно компактный способ представления звука, возможно, вы могли бы динамически создать его и использовать его для метронома? Я предполагаю, что синтез обрабатывается на более низком уровне, чем обычно был бы доступен для вас, так что время было бы лучше, но я не знаю это на самом деле.

0 голосов
/ 07 января 2016

Когда этот звук воспроизведения называется

mSoundManager.playSound(1);

Android ожидает завершения этого вызова, затем вы набираете

mHandler.postAtTime(this, SystemClock.uptimeMillis() + 200);

, однако, если вы отмените эти вызовы, вы можете обнаружить, чтовремя более точное.

mHandler.postAtTime(this, SystemClock.uptimeMillis() + 200);
mSoundManager.playSound(1);

Вы не можете рассчитывать на то, что ваш звук занимает ровно столько же времени для воспроизведения, поэтому советовать обработчику публиковать сообщение первым лучше.Однако все еще не идеален.

Другое соображение заключается в том, что вы пересчитываете время безотказной работы и добавляете к этому еще немного времени (в нашем случае 200).Почему бы не использовать оператор модуля в вашем рабочем времени, чтобы гарантировать, что ваше следующее запрошенное время поста будет более точно запланировано?

long divisions = SystemClock.uptimeMillis() % 200; // precisely scheduled event timings since system boot.
long nextDivision = divisions + 1; // the next desired event timing
mHandler.postAtTime(this, nextDivision * 200); // scaled back up to number of milli seconds
// now do more heavy lifting that would otherwise have affected uptimeMillis call
mSoundManager.playSound(1);
0 голосов
/ 27 октября 2010

Используете ли вы какое-то выражение паузы для ожидания между ударами? Вместо этого вы можете попытаться основать время на множителях системных часов. Таким образом, вы все равно можете получить удары, которые происходят поздно (или не совсем), но вы не получите замедления. Надеюсь, это имеет какой-то смысл.

Это скорее комментарий, но у меня недостаточно представителей, чтобы оставлять комментарии.

...