Воспроизведение звуков в играх для iPhone - замедления - PullRequest
4 голосов
/ 03 марта 2009

Я использую AVAudioPlayer для воспроизведения звука FX в отдельном потоке в моем приложении. Прямо сейчас мое приложение довольно простое, у меня есть UIScrollView для фона прокрутки и пара CALayers, которые представляют игрока и врага в простой игре типа боковой скроллер (например, Марио или Кунг-фу или еще много чего) может перемещать игрока влево и вправо, с возможностью прокрутки вида без проблем. У меня есть кнопка «Атака», которая воспроизводит звуковой эффект ... и много раз, когда я играю звуковой эффект, я получаю небольшую заминку, графически. Это просто курс на iPhone с использованием Quartz? Есть ли способ сделать это более плавным, не начав исследовать OpenGL?

Ответы [ 8 ]

4 голосов
/ 04 марта 2009

Используйте данные NSDataWithContentsOfMappedFile вместо dataWithContentsOfFile.

Также AVAudioPlayer обрабатывает свои собственные потоки, вам не нужно создавать их. [AVAudioPlayer play] возвращается после начала воспроизведения, а не после завершения воспроизведения.

И не забудьте выпустить AVAudioPlayer, когда он вам больше не нужен, например, если вы хотите воспроизводить только звук, реализуйте audioPlayerDidFinishPlaying: успешно: делегируйте и отпустите его там.

2 голосов
/ 06 мая 2011

Сначала была такая же проблема. В соответствии с документацией вам нужно вызывать «prepareToPlay» каждый раз, когда закончится воспроизведение звука. Принятие протокола AVAudioPlayerDelegate и добавление следующего метода сделает это.

-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
    [player prepareToPlay];
}
2 голосов
/ 20 апреля 2009

У меня была такая же проблема с замедлением. Чтобы решить эту проблему, я сначала играю и приостанавливаю звук при первой загрузке на уровне громкости 0 - это работает лучше, чем prepareToPlay, что, по-видимому, приводит к замедлению:

player.volume = 0.0;
[player play];
[player pause];
player.volume = 1.0;

Когда приходит время воспроизвести звук, я просто [игрок играет] ;. Затем в каждом цикле обновления я перебираю все свои активные звуки и ловлю те, которые вот-вот заканчиваются, и перематывает их вместо того, чтобы дать им истечь - это позволяет избежать накладных расходов и замедления запуска звука с нуля. Пример здесь останавливает звуки на 1/15 секунды от конца звука:

for ({each player in active sounds})
{
  if ((player.duration - player.currentTime) <= (1.0/15.0))
  {
    [player pause];
    player.currentTime = 0.0;
  }
}

Теперь он готов к следующей игре. Кажется, работает нормально!

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

2 голосов
/ 03 марта 2009

Как ты играешь звук? Если бы я догадался, это было бы то, что каждый раз, когда воспроизводится звук, ОС фактически загружает его с диска, а также воспроизводит его.

Обновление:

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

1 голос
/ 20 апреля 2009

Почему бы просто не использовать AudioServicesPlaySystemSound? Это хорошо подходит для звуковых эффектов.

Я использую его в своей игре (vConqr), которая также основана на UIScrollView, с множеством других представлений (поэтому все имеют свой собственный CALayer), и это не оказывает существенного влияния на производительность.

1 голос
/ 04 марта 2009

Я думаю, что тема слишком усложняет вашего игрока. Попробуйте на ходу:

/* setup the sound player */
AVAudioPlayer *player1=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL     fileURLWithPath:audioFilePath] error:NULL];
player1.numberOfLoops = 0;
player1.volume=1.0f;
[player1 prepareToPlay];

и затем playSound становится

[player play];

И не забудьте правильно установить категорию AudioSession.

1 голос
/ 04 марта 2009

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

Мой метод воспроизведения звука следующий:

- (void)playSoundThreaded:(id)soundPlayer
{
  if(soundPlayer == nil)
    return;

  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  [(AVAudioPlayer*)soundPlayer play];
  [pool release];
}

- (void)playSound:(AVAudioPlayer*)player
{
  if(player == nil)
    return;

  [NSThread detachNewThreadSelector:@selector(playSoundThreaded:)
    toTarget:self withObject:(id)player];
}

И звук загружается следующим образом:

fxPlayer = [[AVAudioPlayer alloc] initWithData:
  [NSData dataWithContentsOfFile:
    [[NSBundle mainBundle] pathForResource:@"voicehiya" ofType:@"caf"]] error:NULL];

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

0 голосов
/ 29 ноября 2011

Я занимаюсь этим уже несколько дней благодаря проекту, над которым я работаю. Я добавил несколько профилированных профилей в свой код и обнаружил, что вызовы для воспроизведения звуков вызывают проблемы с частотой кадров в моей игре OpenGL. У меня есть несколько рекомендаций для вас на основе того, что я нашел:

  1. Используйте AVAudioPlayer, воспроизводящий mp3 для фоновой музыки.

  2. Используйте OpenAL для ваших звуковых эффектов.

  3. Для звуковых эффектов используйте инструмент командной строки конвертера аудио из apple, чтобы перевести ваши звуки в формат .caf. Это несжатый формат, который не требует от процессора распаковки звука в память перед отправкой на звуковую карту. Это может идти напрямую, экономя ваше время. Инструкции по использованию инструмента можно найти ЗДЕСЬ . (прокрутите до самого низа страницы)

  4. Используйте самые низкие битовые глубины, которые все еще звучат хорошо. Вам действительно не нужно 128 кбит / с - вы, вероятно, можете сэкономить 20 для многих вещей. Меньший битрейт = меньше обработки = быстрее звук.

Я дам вам знать, если найду что-нибудь еще полезное! Удачи!

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