Search code examples
cocos2d-iphoneaudiosimpleaudioengine

Sound effect stops midway when multiple sounds are being played?


I have a charging up sound effect that is 8 seconds long, which is triggered to play only at the end of each level in my game.

The problem is, the sound effect stops midway through when there are other sounds playing at the same time (lasers, explosions, etc). I was reading elsewhere that you can have up to 32 simultaneous sounds playing at the same time, but the game is maybe playing up to 7 or 8 sound effects at the same time max. But the charging up sound effect still cuts out.

If I don't do any shooting in the game and let the charging up effect just play, it plays all the way through.

I preload my sounds at start up like so:

-(void)setupSound
{
    [[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"Kickshock.mp3" loop:YES];
    [[SimpleAudioEngine sharedEngine] preloadEffect:@"explosion_large.caf"];
    [[SimpleAudioEngine sharedEngine] preloadEffect:@"explosion_small.caf"];
    [[SimpleAudioEngine sharedEngine] preloadEffect:@"laser_ship.caf"];
    [[SimpleAudioEngine sharedEngine] preloadEffect:@"powerup.mp3"];
    [[SimpleAudioEngine sharedEngine] preloadEffect:@"railgun.mp3"];
    [[SimpleAudioEngine sharedEngine] preloadEffect:@"metal.mp3"];
    [[SimpleAudioEngine sharedEngine] preloadEffect:@"count.mp3"];
    [[SimpleAudioEngine sharedEngine] preloadEffect:@"charge_up.mp3"];
}

-(id)init
{
    if( (self = [super init]) )
    {
        [self setupSound];
        // Rest of other code..
    }
    return self;
}

and I play them when needed (shooting laser, end of level, things exploding, etc):

[[SimpleAudioEngine sharedEngine] playEffect:@"charge_up.mp3" pitch:1.0 pan:0.0 gain:0.4];

I'm guessing that the charge up sound is losing its "slot" since other sounds are playing? Like mentioned above, I only have 7 or 8 sounds max playing simultaneously when the charging up sound effect cuts off.

If my sound is losing its "slot", is there a way that I can lock in a particular sound effect so that it won't lose its "slot"?

Any idea on what I'm doing wrong or what I can do to remedy this? Any help is greatly appreciated! :D Thanks for looking.


Solution

  • To play multiple sounds, I'd use CDAudioManager with CDSoundEngine instead of SimpleAudioEngine.

    CDSoundEngine allows multiple channels (up to 32), which can play sounds at the same time.

    Example:

    // create engine
    CDSoundEngine * engine = [CDAudioManager sharedManager].soundEngine;
    
    // assign groups
    NSArray * groups = [NSArray arrayWithObjects:
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1],
        [NSNumber numberWithInt:1], nil];
    
    [engine defineSourceGroups:groups];
    [CDAudioManager initAsynchronously:kAMM_FxPlusMusicIfNoOtherAudio];
    
    // load requests
    NSMutableArray * requests = [[[NSMutableArray alloc] init] autorelease];
    
    NSString * plist_sounds = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"Sounds.plist"]];
    if (![[NSFileManager defaultManager] fileExistsAtPath:plist_sounds]) {
        plist_sounds = [[NSBundle mainBundle] pathForResource:@"Sounds" ofType:@"plist"];
    }
    NSDictionary * dictionary_sounds = [[NSDictionary dictionaryWithContentsOfFile:plist_sounds] objectForKey:@"Sounds"];   
    if (dictionary_sounds != nil) {
        for (id key in dictionary_sounds) {
            [requests addObject:[[[CDBufferLoadRequest alloc] init:[key intValue] filePath:[dictionary_sounds objectForKey:key]] autorelease]];
        }
    }
    
    [engine loadBuffersAsynchronously:requests];
    

    Then to play a sound:

    - (ALuint)play:(NSInteger)sound group:(NSInteger)group loop:(BOOL)forever volume:(float)volume {
         [[CDAudioManager sharedManager].soundEngine playSound:sound sourceGroupId:group pitch:1.0f pan:0.0f gain:volume loop:forever];
    }