Search code examples
iphoneobjective-cioscocos2d-iphone

How do I Crossfade music in cocos2d?


Simple enough... I have a background song playing on my game, and I would like to crossfade a track, instead of a hard stop.

//Prep Background Music
        if (![[SimpleAudioEngine sharedEngine]isBackgroundMusicPlaying]) {
             [[SimpleAudioEngine sharedEngine] preloadBackgroundMusic:@"song.mp3"];
        }
        [[SimpleAudioEngine sharedEngine] setBackgroundMusicVolume:1.0]; 

        //Play Background Music
         if (![[SimpleAudioEngine sharedEngine]isBackgroundMusicPlaying]) {
             [[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"song.mp3" loop:YES];
         }

Solution

  • You can't do that using SimpleAudioEngine. Here is how I did it:

    1. Create a class that extends CDAudioManager

    2. In the method that you call to start playing a new background music, first check if the ivar backgroundMusic (inherited from CDAudioManager) is not nil and is playing. If it is, then fade it out using CDLongAudioSourceFader.

    3. Load the new background music into backgroundMusic (it's an instance of CDLongAudioSource -- look it up). Fade it in using CDLongAudioSourceFader.

    Here's a snippet of the method in step 2 (sorry can't show you the rest as it is part of my own proprietary library)

    - (void)audioBackgroundPlay:(NSString *)bgmfile crossfade:(float)fade {
        CDLongAudioSource *audioSource = [self audioBackgroundLoad:bgmfile];
        if (audioSource != backgroundMusic) {
            if (backgroundMusic) {
                [self audioBackgroundControl:AUDIOCTRL_STOP fade:fade];
                backgroundMusic.audioSourcePlayer.meteringEnabled = NO;
                [backgroundMusic release];
            }
            backgroundMusic = [audioSource retain];
            if (meteringEnabled_) {
                backgroundMusic.audioSourcePlayer.meteringEnabled = YES;
            }
        }
        if (![backgroundMusic isPlaying]) {
            [self audioBackgroundControl:AUDIOCTRL_PLAY fade:fade];
        }
    }