按一下按钮发出声音。快速按下按钮,声音播放弹出和点击

时间:2011-07-06 10:17:55

标签: ios cocoa-touch avaudioplayer openal

我有6个按钮,每个按钮都播放一个.caf文件中的音频样本。如果我按下一个按钮,声音就会正常播放,如果我等待它再次按下它会播放正常,但是如果我快速按下按钮,那么声音会在播放前弹出并点击。

我在每次单击按钮时简单地分配AVAudioPlayer时最初没有出现这种弹出问题,但是这会产生多次分配的内存泄漏。所以我为每个按钮创建了6个AVAudioPlayers并重新使用它,这消除了内存泄漏,但现在样本在被覆盖时单击/弹出。

我尝试了很多不同的方法来阻止这种情况发生,从将音量设置为0,在播放下一个样本之前停止AVAudioPlayer实例等但是无法通过快速按下按钮找到重复播放相同样本声音的正确方法并停止弹出。

我确实在.h中保留了AVAudioPlayer属性,并在alloc语句中使用autorelease。

请帮忙吗?

**编辑:找到了一个解决方案,它并不漂亮,但它确实有效。

基本上我创建了10个自动释放的AVAudioPlayers,如果有一个[myPlayer1 isPlaying],那么我会使用下一个。

e.g。

 BOOL done = NO;

if(![self.audioPlayer0 isPlaying] && done == NO) {
    self.audioPlayer0 = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ];
    [audioPlayer0 play];
    done = YES;
}

if(![self.audioPlayer1 isPlaying] && done == NO) {
    self.audioPlayer1 = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ];
    [audioPlayer1 play];
    done = YES;
}

if(![self.audioPlayer2 isPlaying] && done == NO) {
    self.audioPlayer2 = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ];
    [audioPlayer2 play];
    done = YES;
}

if(![self.audioPlayer3 isPlaying] && done == NO) {
    self.audioPlayer3 = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ];
    [audioPlayer3 play];
    done = YES;
}

if(![self.audioPlayer4 isPlaying] && done == NO) {
    self.audioPlayer4 = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ];
    [audioPlayer4 play];
    done = YES;
}

if(![self.audioPlayer5 isPlaying] && done == NO) {
    self.audioPlayer5 = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ];
    [audioPlayer5 play];
    done = YES;
}

if(![self.audioPlayer6 isPlaying] && done == NO) {
    self.audioPlayer6 = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ];
    [audioPlayer6 play];
    done = YES;
}

if(![self.audioPlayer7 isPlaying] && done == NO) {
    self.audioPlayer7 = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ];
    [audioPlayer7 play];
    done = YES;
}

if(![self.audioPlayer8 isPlaying] && done == NO) {
    self.audioPlayer8 = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ];
    [audioPlayer8 play];
    done = YES;
}

if(![self.audioPlayer9 isPlaying] && done == NO) {
    self.audioPlayer9 = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ];
    [audioPlayer9 play];
}

2 个答案:

答案 0 :(得分:1)

为什么要记住所有十个音频播放器而不是动态创建它们?

在你的新解决方案中,你正在做的是循环所有的音频播放器以找到一个没有播放的音频播放器。为什么不在数组中做同样的事情呢?

NSMutableArray *playerHolder = [[NSMutableArray alloc] init];
int maxNumberOfBuffers = 10;

for (int i=0; i<maxNumberOfBuffers; i++)
{
    AVAudioPlayer *audioPlayer;
    [playerHolder addObject:audioPlayer];
}

然后,在尝试播放某些内容时,只需查看数组:

for (int i=0; i<playerHolder.count; i++)
{
    if (![[playerHolder objectAtIndex:i] isPlaying])
    {
        AVAudioPlayer *freePlayer = [playerHolder objectAtIndex:i];
        freePlayer = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ];
        [freePlayer play];
    }
}

从理论上讲,这应该与解决方案完全相同,没有混乱。

答案 1 :(得分:0)

我无法确定,但问题可能是因为您在非零交叉处截断波,这会导致波形中的垂直部分(讨厌的谐波,单击/弹出)。您需要淡化波形而不是将其切除。研究升余弦平滑/整形。

相关问题