【发布时间】:2012-01-27 20:58:52
【问题描述】:
我通过将 numberOfLoops 属性设置为 -1 来使用 AVAudioPlayer 播放循环声音。我想以编程方式控制循环速率,所以我像这样加载我的音频数据:
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 尊重我在音频编辑器中添加的静音,而不尊重我通过编程填充数据添加的静音?
【问题讨论】:
标签: ios audio avaudioplayer nsdata