声音与多次按下按钮重叠

Sound overlapping with multiple button presses

提问人:alfred 提问时间:11/12/2011 最后编辑:Jaroslav Kadlecalfred 更新时间:6/7/2015 访问量:1421

问:

当我按下一个按钮,然后按下另一个按钮时,声音会重叠。我怎样才能解决这个问题,以便在按下另一个声音时第一个声音停止?

 - (void)playOnce:(NSString *)aSound {

NSString *path = [[NSBundle mainBundle] pathForResource:aSound ofType:@"caf"];
AVAudioPlayer* theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[theAudio setDelegate: self];
[theAudio setNumberOfLoops:0];
[theAudio setVolume:1.0];
[theAudio play];    
 }

- (void)playLooped:(NSString *)aSound {

NSString *path = [[NSBundle mainBundle] pathForResource:aSound ofType:@"caf"];
AVAudioPlayer* theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[theAudio setDelegate: self];
// loop indefinitely
[theAudio setNumberOfLoops:-1];
[theAudio setVolume:1.0];
[theAudio play];
[theAudio release];


    }
iPhone iOS4 内存 音频

评论

0赞 wbyoung 11/12/2011
你需要真正问一个问题。
0赞 alfred 11/12/2011
我的问题是,当我单击一个按钮时,它会播放声音,但随后我单击另一个按钮,它们会重叠
0赞 atbebtg 11/12/2011
您可以执行以下操作之一: 1.单击按钮时,检查AVaudioplayer是否仍在播放。如果是,您可以忽略它并且不做任何事情,或者 2 您可以停止它,然后播放新声音。
0赞 alfred 11/12/2011
- (void)playOnce:(NSString *)aSound;
0赞 alfred 11/12/2011
- (IBAction) beatButton50 { [self playOnce:@“racecars”];

答:

0赞 ader 11/12/2011 #1

在 viewController 的标头中声明 AVAudioPlayer(不要在每次播放声音时都分配一个新的)。这样,你将有一个可以在 StopAudio 方法中使用的指针。

@interface myViewController : UIViewController <AVAudioPlayerDelegate> { 
    AVAudioPlayer *theAudio;
}
@property (nonatomic, retain) AVAudioPlayer *theAudio;
@end


@implementation myViewController
@synthesize theAudio;
- (void)dealloc {
    [theAudio release];
}
@end



- (void)playOnce:(NSString *)aSound {
    NSString *path = [[NSBundle mainBundle] pathForResource:aSound ofType:@"caf"];
    if(!theAudio){
        theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL: [NSURL fileURLWithPath:path] error:NULL];
    }
    [theAudio setDelegate: self];
    [theAudio setNumberOfLoops:0];
    [theAudio setVolume:1.0];
    [theAudio play];
}

- (void)playLooped:(NSString *)aSound {
    NSString *path = [[NSBundle mainBundle] pathForResource:aSound ofType:@"caf"];
    if(!theAudio){
        theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL: [NSURL fileURLWithPath:path] error:NULL];
    }
    [theAudio setDelegate: self];
    // loop indefinitely
    [theAudio setNumberOfLoops:-1];
    [theAudio setVolume:1.0];
    [theAudio play];
}

- (void)stopAudio {
    [theAudio stop];
    [theAudio setCurrentTime:0];
}

也请务必阅读 Apple Docs

评论

0赞 alfred 11/12/2011
我将如何在头文件中创建 AVAudioPlayer 我是新手,不太了解
0赞 alfred 11/12/2011
我添加了这些代码行,声音仍然重叠
0赞 ader 11/12/2011
刚刚编辑了上面的代码。您能更详细地描述一下您想要实现的目标吗?
0赞 alfred 11/12/2011
我正在制作一个有 20 个按钮的应用程序,每个按钮播放不同的声音,但当我单击其他按钮时,声音是重叠的
0赞 ader 11/12/2011
然后在播放下一个声音之前停止 AVAudioPlayer。
0赞 atbebtg 11/12/2011 #2

您可以执行如下操作:

    (void) playLooped: (NSString * ) aSound {
        NSString * path = [[NSBundle mainBundle] pathForResource: aSound ofType: @"caf"];

    //stop audio player from playing so the sound don't overlap
    if([theAudio isPlaying])
    {
        [theAudio stop]; //try this instead of stopAudio

    }

    if (!theAudio) {
        theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL: [NSURL fileURLWithPath: path] error: NULL];
    } 
    [theAudio setDelegate: self];
    // loop indefinitely
    [theAudio setNumberOfLoops: -1];
    [theAudio setVolume: 1.0];
    [theAudio play];
}

评论

0赞 alfred 11/12/2011
它告诉我找不到stopAudio
0赞 alfred 11/12/2011
奇怪的是,当我按下多个按钮时,音频仍然重叠
0赞 atbebtg 11/12/2011
您是否交易了代码并确保调用了 [theAudio stop]?
0赞 alfred 11/12/2011
我如何交易代码,我必须释放它,它是编程的新手,我仍在尝试学习
0赞 Eric 11/12/2011 #3

您发布的代码将只播放一种声音,即发送到该方法的第一个声音。

如果您只想播放一种可变声音,请在停止播放器后释放音频,然后设置新声音。

评论

0赞 alfred 11/12/2011
如何释放音频并设置新的音频
0赞 Alan Moore 11/12/2011 #4

在 playOnce 方法中,“path”变量未使用 -- 删除它以消除警告消息。你的playOnce没有设置任何播放内容,所以我不确定它应该如何工作 - 除非你先调用playLooped?还需要在 initWithContentsOfUrl 之后调用 prepareToPlay。

 - (void)playOnce:(NSString *)aSound {

  NSString *path = [[NSBundle mainBundle] pathForResource:aSound ofType:@"caf"];
  if (theAudio && [theAudio isPlaying]) {
    [theAudio stop]
  } else {
         theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL: [NSURL fileURLWithPath: path] error: NULL];
         [theAudio prepareToPlay];

         [theAudio setDelegate: self];
    [theAudio setNumberOfLoops: 1];
    [theAudio setVolume: 1.0];
    [theAudio play];
  }

}

评论

0赞 alfred 11/12/2011
我删除了playLoop行,因为我真的不需要它,我删除了路径行,但仍然没有声音播放
0赞 Alan Moore 11/12/2011
添加 prepareToPlay,你试过了吗?您确实需要调用 playLoop 中的代码来设置 AVAudioPlayer。
0赞 alfred 11/12/2011
我做到了,声音停止重叠,现在它只在我尝试按下另一个具有不同声音的按钮时播放相同的声音
0赞 Alan Moore 11/12/2011
啊,对了,我明白你在说什么了。我想你必须检查一下你是否有不同的声音,然后在这种情况下重新加载播放器。
0赞 alfred 11/12/2011
我有所有按钮的代码,但是我如何查看我是否有不同的声音播放并重新加载播放器,我是编程新手,所以我知道的不多
0赞 esqew 11/12/2011 #5

添加一个检查,以查看玩家是否已经在每种方法的开头玩游戏:

if (theAudio.playing == YES) {
    [theAudio stop];
}

AVAudioPlayer 类参考

0赞 GhostShaman 12/20/2011 #6

您需要使用 BOOL 值才能使其正常工作。

在您的 .m 文件中,@implementation之前把这个:

static BOOL soundIsPlaying = NO;

然后,您的 IBAction 需要如下所示:

- (IBAction)play {
    if (soundIsPlaying == YES) {
        [theAudio release];
        soundIsPlaying = NO;

    }

    else if (soundIsPlaying == NO) {
        NSString *path = [[NSBundle mainBundle] pathForResource:@"SOUNDFILENAME" ofType:@"wav"];
        theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
        theAudio.delegate = self;
        theAudio.volume = 1.0;
        theAudio.numberOfLoops = 0;
        [theAudio play];
        soundIsPlaying = YES;

    }   
}

老实说,就是这样。当按下另一个按钮时,它会停止声音。