开发者

Playing multiple sounds at once?

I have 6 sounds on one view.

However I want it so that I can play more than one at once, So you tap sound 1 (sound 1 is playing) then sound 2 plays. while sound 1 is still playing.

But at the moment I press sound 1 (sound 1 plays), press sound 2 (sound 2 plays, but sound 1 stops)

Here is the code for the audio part.

- (IBAction)oneSound:(id)sender; {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"1" ofType:@"wav"];
    if (theAudio) [theAudio release];
    theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
    theAudio.delegate = self;
    [theAudio play];   
    volumeTimer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(updateVolume) userInfo:nil repeats:YES];
}

- (IBAction)twoSound:(id)sender; {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"2" ofType:@"wav"];
    if (theAudio) [theAudio release];
    theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] erro开发者_开发问答r:NULL];
    theAudio.delegate = self;
    [theAudio play];   
    volumeTimer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(updateVolume) userInfo:nil repeats:YES];
}


There is some important code missing, but it looks as if theAudio is a global you are using to manage the playing of your sounds. Since you destroy it whenever a sound is played whatever is currently playing will stop in preparation for the next sound.

There are several ways to fix this, one being that each sound gets its own unique AVAudioPlayer instance.


don't release the player just because it exists. release when finished playing

You should implement this in the app delegate or a property of the app delegate so that the delegate reference remains valid if you pop the view.

You should not need to do this for each voice. Each voice will initial the player with a different filename or URL. You gain this by making sure that you will release when finished playing. The other thing to take care of is releasing players if the player doesn't finish because of an interruption.

#pragma mark -
#pragma mark Audio methods

-(void)playNote:(NSInteger)noteNumber {

    NSString *soundFilePath =
    [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%i", noteNumber ]
                                    ofType: @"caf"];

    NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];

    AVAudioPlayer *playerToPrepare = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL
                                                                            error:nil];

    [fileURL release];

    [playerToPrepare prepareToPlay];
    [playerToPrepare setDelegate: self];

    [playerToPrepare play];

}

#pragma mark -
#pragma mark AVAudioPlayer delegate methods

- (void) audioPlayerDidFinishPlaying: (AVAudioPlayer *) playerThatFinished
                        successfully: (BOOL) completed {
    if (completed) {
        [playerThatFinished release];
    }
}


You can declare and use:

AVAudioPlayer *theAudio1;    // for file 1.wav
AVAudioPlayer *theAudio2;    // for file 2.wav
...
AVAudioPlayer *theAudio6;    // etc.

instead of releasing and reusing just one AVAudioPlayer.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜