Как я могу остановить повторение AVAudioPlayer до того, как он достигнет конца моих данных? - PullRequest
2 голосов
/ 28 января 2012

Я играю зацикленный звук с AVAudioPlayer, установив для свойства numberOfLoops значение -1.И я хочу программно контролировать частоту зацикливания, поэтому я загружаю свои аудиоданные следующим образом:

NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:@"Click" ofType:@"aif"];
NSMutableData *soundData = [NSMutableData dataWithContentsOfFile:soundFilePath];

, а затем изменяю его длину перед инициализацией аудиоплеера:

int loopDuration = .5; // seconds
int desiredDataLength = loopDuration * 2 * 44100; // this assumes 16-bit mono data
[soundData setLength:desiredDataLength];
NSLog(@"data: %@", soundData); // this shows the data after our length change
AVAudioPlayer soundPlayer = [[AVAudioPlayer alloc] initWithData:soundData error:NULL];
soundPlayer.numberOfLoops = -1;
[soundPlayer play];

Это прекрасно работает, если я устанавливаю loopDuration, которое меньше продолжительности исходного файла - дополнительные данные усекаются, и цикл воспроизводится с желаемой скоростью.Но если я установлю loopDuration, который длиннее исходного файла, цикл будет воспроизводиться слишком быстро - каждая итерация длится столько времени, сколько длится исходный файл.

Я могу подтвердить из строки NSLog, что soundDataполучить дополнить до правильной длины.Я подумал, что, возможно, AVAudioPlayer игнорирует конечные 0 в данных и перезапускает цикл, когда видит все эти 0, поэтому вместо простой установки длины данных я попытался заполнить его некоторыми значениями:

NSData *filler = [@"1234" dataUsingEncoding:NSASCIIStringEncoding];
while (desiredDataLength > [soundData length]) {
    [soundData appendData:filler];
}

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

    [soundData appendData:soundData];

..., а затем установить numberOfLoops на 4 и воспроизвести данные.Я ожидал услышать звук 8 раз, но слышал только 4 раза!Но если я регистрирую soundData, я вижу, что его длина была удвоена.

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

ОБНОВЛЕНИЕ: Я обнаружил, что если я открою свои оригинальные звуковые файлы в аудио-редакторе и добавлю тишину до конца, чтобы сделать их достаточно длинными для моей самой низкой скорости цикла, AVAudioPlayer обрабатывает их так, как я хочу.Но когда я просматриваю вывод NSLog, я вижу, что эти данные также заканчиваются на все 0.Почему AVAudioPlayer соблюдает тишину, которую я добавил в аудиоредакторе, а не тишину, которую я добавил, заполняя данные программно?

1 Ответ

0 голосов
/ 08 марта 2012

Звуковые данные - это не просто данные. Это AIF-файл, который также содержит заголовок, который определяет длину содержимого. AVAudioPlayer явно смотрит на заголовок, а не на длину вашего буфера.

...