Более эффективный код? (AVAudioPlayer) - PullRequest
1 голос
/ 15 октября 2011

В телефоне ниже я готовлю AVAudioPlayer для четырех разных звуков в моем приложении.Если я этого не сделаю, приложение будет задерживаться примерно на 1,5 секунды, если я просто сделаю это там, где мне нужно это услышать.Так есть ли способ заставить этот код выглядеть лучше или работать эффективнее, потому что теперь я готовлю эти звуки в моем App-Delegate, и это немного замедляет запуск.Итак, вот код, и дайте мне знать, если есть какой-нибудь способ сделать этот код ниже:

- (void)readySounds {
        NSString *path = [[NSBundle mainBundle] pathForResource:@"TrackUno" ofType:@"mp3"];
        NSURL *file = [[NSURL alloc] initFileURLWithPath:path];
        AVAudioPlayer *one = [[AVAudioPlayer alloc] initWithContentsOfURL:file error:nil];
        [file release];
        self.tr1 = one;
        [one release];
        [tr1 prepareToPlay];
        [tr1 setDelegate:self];

        NSString *path2 = [[NSBundle mainBundle] pathForResource:@"TrackDos" ofType:@"mp3"];
        NSURL *file2 = [[NSURL alloc] initFileURLWithPath:path2];
        AVAudioPlayer *two = [[AVAudioPlayer alloc] initWithContentsOfURL:file2 error:nil];
        [file2 release];
        self.tr2 = two;
        [two release];
        [tr2 prepareToPlay];
        [tr2 setDelegate:self];

        NSString *path3 = [[NSBundle mainBundle] pathForResource:@"Click" ofType:@"mp3"];
        NSURL *file3 = [[NSURL alloc] initFileURLWithPath:path3];
        AVAudioPlayer *three = [[AVAudioPlayer alloc] initWithContentsOfURL:file3 error:nil];
        [file3 release];
        self.clk = three;
        [three release];
        [clk prepareToPlay];
        [clk setDelegate:self];

        NSString *path4 = [[NSBundle mainBundle] pathForResource:@"HSSound" ofType:@"mp3"];
        NSURL *file4 = [[NSURL alloc] initFileURLWithPath:path4];
        AVAudioPlayer *four = [[AVAudioPlayer alloc] initWithContentsOfURL:file4 error:nil];
        [file4 release];
        self.hs = four;
        [four release];
        [hs prepareToPlay];
        [hs setDelegate:self];
    }

Ответы [ 2 ]

2 голосов
/ 16 октября 2011

Если время инициализации является вашей единственной задачей, вы можете * создать это во вторичном потоке и улучшить воспринимаемое время запуска.Затем он запускает потоки и декодеры и открывает аудиофайлы с диска из вторичного потока.

Если воспроизведение, подсчет потока, использование памяти, ЦП, время загрузки, декодирование, фильтрация, повторная выборка и т. Д.факторы по-прежнему: вы используете API-интерфейсы самого высокого уровня, вы можете опустить несколько уровней и получить полный контроль над каждым из этих аспектов.

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


* 'возможно', поскольку я использовал только API более низкого уровня, я не знаю, имеет ли AVAudioPlayer ограничения потоков.


Пример рефакторинга с добавленной проверкой ошибок:

Не скомпилировано, но вы получите идею:

- (AVAudioPlayer *)newAudioPlayerForFile:(NSString *)fileName extension:(NSString *)extension inBundle:(NSBundle *)bundle
{
  assert(fileName && extension && bundle);
  NSURL * url = [bundle URLForResource:fileName ofType:extension];
  if (nil == url) {
    assert(0 && "could not locate resource");
    return nil;
  }

  NSError * error = 0;
  AVAudioPlayer * spieler = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
  assert(spieler);

  if (nil != error) {
    NSLog(@"Error encountered creating audio player for file (%@): %@", fileName, error);
    [spieler release], spieler = nil;
    return nil;
  }

  [spieler prepareToPlay];
  [spieler setDelegate:self];

  return spieler;
}

- (void)readySounds
{
  NSAutoreleasePool * pool = [NSAutoreleasePool new];
  NSBundle * mainBundle = [NSBundle mainBundle];
  self.tr1 = [[self newAudioPlayerForFile:@"TrackUno" extension:@"mp3" inBundle:mainBundle] autorelease];
  self.tr2 = [[self newAudioPlayerForFile:@"TrackDos" extension:@"mp3" inBundle:mainBundle] autorelease];
  self.clk = [[self newAudioPlayerForFile:@"Click" extension:@"mp3" inBundle:mainBundle] autorelease];
  self.hs = [[self newAudioPlayerForFile:@"HSSound" extension:@"mp3" inBundle:mainBundle] autorelease];
  [pool release], pool = nil;
}
1 голос
/ 25 августа 2012

Я обнаружил, что решение для загрузки в фоновом режиме было проблемой ... оно работало, а затем в 30-й раз, когда я использовал звук из основного потока, весь звук перестал работать.Могло произойти несколько вещей: мне пришлось создать свой собственный пул автоматического выпуска, и фоновый поток мог бы исчезнуть, испортив объект.

Подумав об этом, у меня только короткие звуковые эффекты - создание первогоAVAudioPlayer был медленным, но последующие были в порядке.Поэтому, чтобы решить эту проблему, я создал крошечный тихий wav-файл и использовал его как первый для загрузки.Я использовал audacity, чтобы создать файл, и сделал Tracks> Add New> Audio Track, затем я сделал Generate> Silence, выбрал очень маленький интервал, как .01s, затем I File> Export'ed звук и добавил файл в XCode.

Я заставляю небольшой, тихий wav-файл загружаться в viewDidLoad, и это сокращает отставание для меня.

Надеюсь, это поможет кому-то с подобной проблемой.

...