2012-01-27 57 views
2

我通过将numberOfLoops属性设置为-1来播放AVAudioPlayer的循环声音。我希望通过编程来控制循环速度,让我加载我的音频数据是这样的:如何阻止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尊重我在音频编辑器中添加的静音,但不是通过以编程方式填充数据而添加的静音?

回答

0

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

+0

这是有道理的,并匹配我看到的行为。我在这里找到了AIFF标题的描述:http://www-mmsp.ece.mcgill.ca/documents/audioformats/aiff/Docs/AIFF-C.9.26.91.pdf。当我操纵数据本身以确定时,我需要弄清楚如何处理大小值;同时我会认为这是发生了什么事。 – arlomedia 2012-03-12 22:33:33

相关问题