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 остается? И если да, есть ли лучший способ реализовать функциональность, которую я хотел бы получить?

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

  • Как обратный вызов C возвращает объект Objective-C с помощью указателя userdata?
  • Различие KVO между willChangeValueForKey и didChangeValueForKey - оба необходимы?
  • Прием вызовов CFSocket не вызывается. Что я пропустил?
  • iOS: ShareKit >> Настройки Twitter >> Обратный звонок - что это такое?
  • iOS: сохранение и запуск блока обратного вызова
  • обратный вызов обратной кнопки в navigationController в iOS
  • Как создать callBack в iOS, который должен вызываться библиотекой
  • OAuth Swift: Какой URL-адрес обратного вызова для приложения Dribbble?
  • handleTurnEventForMatch: didBecomeActive: обратные вызовы только прибывают некоторое время
  • Обработчик обратного вызова Objective-C
  • Как заменить устаревшие методы наSuccessCallbackString и writeJavascript в Objective-C?
  • Приглашение друга Facebook graph api принять обратный вызов (iOS)
  • Interesting Posts

    Отказ приложения iOS из-за кнопки «Зарегистрироваться» на странице входа в систему авторизации

    Действительно ли работаетMonitoringForRegion?

    Ошибка загрузки таблицыView в iOS-симуляторе 64-разрядная

    Оценочный размер магазина приложений на Xcode 6 показывает огромный размер (Unity iOS Export)

    Разрешить использование одного распознавателя жестов и двойного нажатия в UIScrollView

    iOS 7 UITextView вертикальное выравнивание

    Отключите масштабирование интерфейса UIWebView, но сохраните другое взаимодействие с пользователем.

    UINavigationController и альтернативный ландшафт

    Основные данные NSManagedObject – отслеживание, если атрибут был изменен

    Как прокручивать изображения влево и вправо, когда оно отображается на большом изображении

    Совместное использование цветовой палитры в xcode

    Рассматривать общий экземпляр TypeA как общий экземпляр SuperclassOfTypeA

    Сбросить одновременно несколько контроллеров просмотра

    Как удалить или скрыть верхнюю тень панелей инструментов

    Настройка выбранного изображения в панели управления вкладкой с раскадровки

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