我使用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函数会产生多少声音(每次调用),但每当它产生一个声音时,它会调用应该处理它的HaveSoundCallback(它还会发送“self”作为“所有者“声音”。
现在这是回调实现(它在同一个.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“自学辅导”)目的,我实现了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中的事实有关,因此只要GenerateSound被保留就会执行audioPlayerDidFinishPlaying?如果是的话,有没有更好的方法来实现我想要的功能?
非常感谢您提供任何帮助!