AVAudioPlayer начал с вызовов обратного вызова C ++. AudioPlayerDidFinishPlaying как-то поздно

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

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

Это мой .h-файл (с оставленными неактуальными материалами):

#import <AVFoundation/AVFoundation.h> @interface mytest_appViewController : UIViewController <AVAudioPlayerDelegate> { AVAudioPlayer *player; .... } void HaveSoundCallback(const short *psSamples, long lSamplesNum, void *pOwner); .... @property (nonatomic, retain) AVAudioPlayer *player; @end 

И это одна из частей реализации:

 .... #import "MyCplusplusSoundGeneratingLibrary.h" .... - (IBAction)GoButtonTouched:(UIButton *)sender{ // calling the C++ made GenerateSound and passing it the callback int ret=GenerateSound(couple_of_parameters, HaveSoundCallback, self); } 

Как правило, я не знаю, сколько звуков произведет функция GenerateSound (за один вызов), но всякий раз, когда он ее производит, он вызывает DoSoundCallback, который должен позаботиться об этом (он также отправляет «я» в качестве «владельца» звук).

Теперь это реализация обратного вызова (она находится в том же .mm, но вне @implementation … @ end):

 void HaveSoundCallback(const short *psSamples, long lSamplesNum, void *pOwner){ NSString *OutWave; NSLog(@"Entered the callback function"); OutWave=[pOwner getDocumentFile:@"out.wav"]; [pOwner SaveSoundData:OutWave pcm:psSamples len:lSamplesNum]; [pOwner PlaySound:OutWave]; [OutWave release]; } 

Это означает, что функция обратного вызова сохраняет звуковые данные в wav (вызывая SaveSoundData), а затем вызывает PlaySound для их воспроизведения. Реализация PlaySound и audioPlayerDidFinishPlaying снова находится в классе mytest_appViewController:

 - (void)PlaySound:(NSString *)WaveFile{ NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:WaveFile]; NSLog(@"Playing started"); self.player =[[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil]; self.player.delegate = self; [self.player play]; while (self.player.playing) { sleep(0.01); } [fileURL release]; NSLog(@"Playing finished"); } - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)p successfully:(BOOL)flag { NSLog(@"hi from audioPlayerDidFinishPlaying"); } 

Я намеренно жду здесь в цикле while, чтобы игрок не мог воспроизводить все возможные возвращающиеся звуки одновременно – другой обратный вызов происходит после того, как плеер перестает воспроизводить текущий звук. Но я хотел бы запустить законченную игру player.delegate. Итак, для моих экспериментальных (и ObjC «self-tutoring») я реализовал делегат audioPlayerDidFinishPlaying.

И теперь ситуация с тестированием: позволяет сказать, что GenerateSound производит 3 звука (с короткими задержками между ними). Я бы ожидал, что выходная консоль будет выглядеть примерно так:

 Entered the callback function Playing started hi from audioPlayerDidFinishPlaying Playing finished Entered the callback function Playing started hi from audioPlayerDidFinishPlaying Playing finished Entered the callback function Playing started hi from audioPlayerDidFinishPlaying Playing finished 

Но вместо этого, audioPlayerDidFinishPlaying вызывается в самом конце 3 раза, то есть:

 Entered the callback function Playing started Playing finished Entered the callback function Playing started Playing finished Entered the callback function Playing started Playing finished hi from audioPlayerDidFinishPlaying hi from audioPlayerDidFinishPlaying hi from audioPlayerDidFinishPlaying 

Что я делаю неправильно? Почему не выполняется AudioPlayerDidFinishPlaying, когда игра действительно закончена, и вместо этого она укладывается где-то и выполняется 3 раза в конце?

Имеет ли это что-то общее с тем, что программа на самом деле все время находится внутри библиотечной функции C ++ GenerateSound, и, таким образом, функция audioPlayerDidFinishPlaying выполняется, как только GenerateSound остается? И если да, есть ли лучший способ реализовать функциональность, которую я хотел бы получить?

Большое спасибо за любую помощь!

PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.