如何阻止AVAudioPlayer在数据到达之前重复执行?

通过将numberOfLoops属性设置为-1,我正在使用AVAudioPlayer播放循环声音。 我想以编程方式控制循环速率,所以我正在像这样加载我的audio数据:

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

然后在初始化audio播放器之前更改其长度:

 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次! 但是,如果我loggingsoundData,我可以看到它的长度已经翻了一番。

似乎在循环机制中内置了一些智能,它使得循环在它认为是应该的时候重启,而不是当它到达数据的末尾。 有没有人有洞察到真正发生的事情,以及如何解决它以获得我想要的结果?

更新:我发现,如果我在audio编辑器中打开我的原始声音文件,并将静音添加到结尾,为了使它们足够长,以使我的最低循环速度,AVAudioPlayer处理它们,如我所愿。 但是当我查看NSLog输出时,我看到这个数据也全部以0结束。 为什么AVAudioPlayer尊重我在audio编辑器中添加的沉默,而不是通过以编程方式填充数据添加的沉默?

声音数据不仅仅是数据。 这是一个AIF文件,它也包含一个标题,它定义了内容的长度。 AVAudioPlayer显然是看标题,而不是在你的缓冲区的长度。