2011-01-13 4 views
3

Я работаю над созданием простого метронома на iPhone. То, что приложение делает прямо сейчас, - это запустить таймер, введя функцию таймера каждые 1/1000th секунды. Затем он проверяет текущее время и время запуска приложения (я пользуюсь функцией CACurrentMediaTime()).Как играть в точные моменты на iPhone?

CFTimeInterval currentTime = CACurrentMediaTime(); 
if (self.beatingStartTime == 0) { 
    self.beatingStartTime = currentTime; 
} 
if ((currentTime - self.beatingStartTime) >= self.timeIntevalBetweenTicks * self.internalTimerCounter) { 
    self.internalTimerCounter ++; 
    // ... 
} 

Если есть хороший момент для воспроизведения звука, код, использующий OpenAL для его воспроизведения, срабатывает.

Принципиально все. Я проверил звуки, воспроизводимые при запуске как в симуляторе, так и на двух устройствах (iPad и jailbroken iPhone 3GS), и есть проблема - когда я записал звук и просмотрел форму волны в программном обеспечении Reaper, некоторые звуки немного затухают, и некоторые из них - слишком рано (даже я мог понять часть «слишком поздно», я действительно не понимаю, как это можно играть раньше, чем нужно), поскольку приложение проверяет количество секунд каждый раз, t be ealier, а затем укажите время, но это, согласно моим рекомендациям).

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


редактировать: Изменение таймера вызова от 1/однотысячной секунды до, например 1/100 не помогает.

Редактировать 2: Когда я переключился с таймера на потоки (и я поставил поток спать в течение указанного времени), я все еще получаю странное поведение. Темп перемещается, и, хотя я могу понять небольшое отставание и играть некоторые звуки слишком поздно, проблема в том, что некоторые из них действительно играют слишком рано - это означает, что расстояние между двумя ударами меньше времени, которое должно пройти.

Дифференция составляет около 3%, что соответствует примерно 10-15 миллисекундам, что для меня довольно много. Кто-нибудь понял, почему звук может играть раньше? Я попробовал это как на симуляторе iPhone, так и на самом iPad-устройстве, и только догадываюсь, что с таймером что-то не так - CACurrentMediaTime() возвращает больше секунд, чтобы это было. Возможно ли это?

+0

Почему вы используете OpenAL, а не простой AVAudioPlayer? (Требуется ли ваш метроном позиционный звук?) –

+0

Нет. Но раньше у меня была аналогичная проблема (или, что еще хуже) с AVAudioPlayer, когда я это использовал. И я нашел совет использовать OpenAL вместо этого, так как лучше всего играть в определенные моменты (синхронизируется с рамкой игровой части и т. Д.). - в этой записи в блоге http://benbritten.com/2008/11/06/openal-sound-on-the-iphone/ упоминается «Для лучшего управления звуком вам потребуются либо openAL, либо audioUnits, либо audioQueue»). – kender

+1

@kender, также вы не можете вызвать таймер 1000 раз в секунду и попросить его ответить. Вы просите много неприятностей, поэтому может показаться, что он никогда не попадает в нее. Даже если вы установите метроном на 16-ю ноту с темпом 240, вам нужен только таймер с разрешением 0,015625 секунд. Вы не получите миллисекундную точность на iphone, не запустив свои собственные c-библиотеки, и тогда это правда. –

ответ

5

Попробуйте использовать NSSound и загрузите его в качестве переменной экземпляра и не освободите его, если ваш метроном не запущен. Задержки могут быть вызваны загрузкой файла в память цикла. Другое дело, что метроном, вероятно, не нужно опросить каждые 1/1000 секунды. Если вы делаете это реже, вы с меньшей вероятностью насытите процессор, и вы сможете получить более последовательные результаты.

Наконец, проверить, как демо от Apple работает: http://developer.apple.com/library/ios/#samplecode/Metronome/Introduction/Intro.html

может дать вам лучшее представление о том, как добиться того, что вы пытаетесь сделать :)

+0

Сейчас я использую OpenAL, и мои звуки считываются в переменные экземпляра при запуске метронома, t действительно нужно читать из файла на каждой итерации. – kender

2

Что вы хотите COCOS DENSHION который простая надежная простая в использовании звуковая библиотека, которую мы нашли, решает все проблемы.

Я (просто лично) не люблю «Cocos2D», но вы можете просто взять и использовать CocosDenshion.

Во-вторых - 1000-я секунда смешна для таймера. Просто полностью забывай об этом.

В-третьих - AVAudioPlayer бесполезен, как вы нашли.

Примечание - "ObjectAL" является новым, возможно, лучше, альтернатива

к CocosDenshion. Проверьте это.

Смежные вопросы