如何从重复到达我的数据在年底前停止AVAudioPlayer? [英] How can I stop AVAudioPlayer from repeating before it reaches the end of my data?

查看:139
本文介绍了如何从重复到达我的数据在年底前停止AVAudioPlayer?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我被numberOfLoops属性设置为-1循环播放声音AVAudioPlayer。我想以编程方式控制循环速度,让我加载像这样我的音频数据:

I'm playing looped sound with AVAudioPlayer by setting the numberOfLoops property to -1. And I want to control the loop rate programmatically, so I'm loading my audio data like this:

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

然后初始化音频播放器之前,改变它的长度:

And then changing its length before initializing the audio player:

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这比原始文件长,循环起着太快 - 只要每次迭代仅持续作为原始文件的持续时间

This works perfectly if I set a loopDuration that's smaller than the duration of the original file -- the extra data is truncated and the loop plays at the desired speed. But if I set a loopDuration that's longer than the original file, the loop plays too quickly -- each iteration only lasts as long as the duration of the original file.

我可以从soundData是越来越填充到正确长度的NSLog行确认。我想,也许AVAudioPlayer无视尾随0的数据,并重新启动循环时,看到那些0,所以不是简单地设置数据长度,我试着用一些值填充它:

I can confirm from the NSLog line that soundData is getting padded to the correct length. I thought maybe AVAudioPlayer was ignoring the trailing 0's in the data and restarting the loop when it saw all those 0's, so instead of simply setting the data length, I tried padding it with some values:

NSData *filler = [@"1234" dataUsingEncoding:NSASCIIStringEncoding];
while (desiredDataLength > [soundData length]) {
    [soundData appendData:filler];
}

但环还在那里原来的文件数据停止点重新启动。作为一个全面的检查,我尝试将声音数据增加了一倍......

But the loop still restarts at the point where the original file data stops. As a sanity check, I tried doubling the sound data...

    [soundData appendData:soundData];

...然后设置numberOfLoops 4和播放数据。我希望听到的声音8次,但我只听到发挥它的4倍!但是,如果我登录soundData,我可以看到,它的长度增加了一倍。

...and then setting numberOfLoops to 4 and playing the data. I expected to hear the sound 8 times, but I only heard it play 4 times! But if I log soundData, I can see that its length has been doubled.

好像有某种智能的内置的循环机制,使得当它认为它应该在循环重新开始,而不是当它到达了数据的结尾。有没有人有见识到了什么是真正发生的事情,我怎么能解决它让我想要的结果?

It seems like there's some kind of intelligence built into the looping mechanism that makes the loop restart when it thinks it should, instead of when it gets to the end of the data. Does anyone have insight into what's really happening, and how I can work around it to get my desired result?

更新:我发现,如果我在音频编辑器中打开我原来的声音文件,并添加沉默两端,使他们足以让我最慢的速度闭环长,AVAudioPlayer处理它们的方式我想它。但是,当我查看的NSLog输出,我看到这个数据也是在所有0结束。为什么AVAudioPlayer尊重我在音频编辑器增加了沉默,而不是沉默,我添加以编程方式填充的数据?

UPDATE: I found that if I open my original sound files in an audio editor and add silence to the ends, to make them long enough for my slowest loop speed, AVAudioPlayer handles them as I want it to. But when I view the NSLog output, I see that this data also ends in all 0's. Why does AVAudioPlayer respect the silence I added in an audio editor, but not the silence I added by padding the data programmatically?

推荐答案

声音数据不仅仅是数据。它是一个AIF文件,该文件还包含一个头限定的内容的长度。 AVAudioPlayer显然在看标头,而不是在您的缓冲区的长度

The sound data is not just data. It's an AIF file which also contains a header which defines the length of the contents. AVAudioPlayer clearly is looking at the header, not at the length of your buffer.

这篇关于如何从重复到达我的数据在年底前停止AVAudioPlayer?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆