2010-10-27 2 views
1

У меня есть простая классическая инструкция: каждые 200 миллисекунд воспроизводят звук (метроном).Metronome Timer slowdown (через Handler, или Threads too)

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

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

Любые идеи?

Вот код:

общественный класс метроном реализует 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); 
    } 

};

+0

Это проблема с точными таймингами на таких устройствах. Не уверен, что есть решение вообще, не говоря уже о простом – Falmarri

ответ

0

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

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

0

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

+0

. Подобная идея: создать звуковой поток, который имеет звук метронома, за которым следует тишина, вместо того, чтобы воспроизводить звук и останавливаться. Пока ваш поток получает достаточное количество процессорного времени для полного заполнения звукового буфера, ваш метроном будет оставаться вовремя, даже если другие элементы в системе активны. – fadden

0

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

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); 
Смежные вопросы