Правильный способ воспроизведения звука несколько раз в iOS - PullRequest
3 голосов
/ 02 февраля 2012

Мне нужно было реализовать воспроизведение .aiff звука 3 раза подряд. Длина звука составляет 0,1 мс, а интервалы между воспроизведением также должны составлять 0,1 мс. Поэтому я решил сделать это с NSTimer. Это мое решение:

-(void)playSound{
    timerCounter = 0;
    timerForSound = [NSTimer scheduledTimerWithTimeInterval:0.2
                                                     target:self 
                                                   selector:@selector(playSoundThreeTimes)
                                                   userInfo:nil
                                                    repeats:YES];
}

-(void)playSoundThreeTimes{
    // play alert sound
    AudioServicesPlaySystemSound(beepSound);
    timerCounter++;
    if(timerCounter == 3){ // sound played 3 times
        [timerForSound invalidate];
        timerCounter = 0;
    }
}

Проблема в том, что звук иногда отстает, даже если я установил интервал 0,25 (0,2 - потому что длина звука + интервал = 0,2).

Может кто-нибудь предложить лучший способ сделать это или сказать, чем может быть вызвана проблема.

Артем

Редактировать: Добавление этого в асинхронный поток также не работает:

dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [self playSound];
    });

Ответы [ 3 ]

2 голосов
/ 02 февраля 2012

Две причины: 1. NSTimer не на 100% точен. 2. Вы запускаете события в главном потоке, где находится остальная часть пользовательского интерфейса.

Как говорит Адам, вы можете поместить его в свой собственный поток. Или, может быть, использовать что-то вроде CADisplayLink вместо NSTimer.

Редактировать: Если вы правы, и виновником является AudioSystemServices ... Я не знаю, сработает ли это, но вы можете попробовать создать 3 разные ссылки на beepSound и затем вызвать beepSound1, beepSound2, beepSound3? Потому что я думаю, что он может ждать, пока прекратится предыдущий звук. Если это не сработает, я думаю, что, возможно, вам нужно использовать Audio Queue или OpenAL, возможно ...

2 голосов
/ 02 февраля 2012

Я могу ошибаться, но аудио должно быть в своем собственном потоке, однако я не уверен, что делать с этим в ObjC (я программирую аудио на c ++).быть точным, поскольку (я думаю) это ветка сообщений.На больших интервалах (1 секунда +) это не будет заметно, но на таких коротких скоростях оно, вероятно, будет отставать.

0 голосов
/ 02 февраля 2012

Попробуйте:

-(void)playMyAudio {

    //play audio method
    if (loop<3) {   
        [self performSelector:@selector(playAudio) withObject:nil afterDelay:0.1];
        loop++;
    }
    else {
       loop = 0
    }
}

, если все еще отстает, единственный способ, который я нашел, - это создать 3,4 avplayer и играть в режиме FIFO с AVAudioSession

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...