Make Your Own iPhone Game, Day 11


Conan makes me laugh with his “heeya!” noise

Here’s a simple bit of code which creates a cocos2d denshion sound asynchronous engine as a super-easy-to-use singleton:

static Sound* soundSingleton = nil;
@interface Sound : NSObject
	{
		BOOL soundReady;
	}

	+(Sound*) getSingleton;
	+(void) purgeSingleton;

	-(void) loadSound;
	-(void) loadSoundFx:(NSObject*)data;
	-(void) updateSound;
	-(void) playSound:(int)fx;
	-(void) playSound:(id)sender data:(void*)data;
	-(void) playSound:(int)fx volume:(CGFloat)volume pan:(CGFloat)pan pitch:(CGFloat)pitch loop:(BOOL)loop;
@end

@implementation Sound
	+(Sound*) getSingleton
	{
		@synchronized([Sound class])
		{
			if (!soundSingleton)
				soundSingleton = [[self alloc] init];
		}
		return soundSingleton;
	}

	+(id) alloc
	{
		@synchronized([Sound class])
		{
			NSAssert(soundSingleton == nil, @"Tried to allocate a second instance of Sound singleton");
			return [super alloc];
		}
		return nil;
	}

	+(void) purgeSingleton
	{
		@synchronized(self)
		{
			[soundSingleton release];
		}
	}

	-(id) init
	{
		self = [super init];
		if(self != nil)
		{
			// setup a few groups for sound effect playback
			int groups[kSoundGroupTotal];
			groups[kSoundGroupSingle] = 1; // only one at a time
			groups[kSoundGroupMultiple] = 16; // 16 sounds at a time

			// initialize audio manager asynchronously as it can take a few seconds
			[CDAudioManager initAsynchronously:kAudioManagerFxPlusMusicIfNoOtherAudio
				channelGroupDefinitions:groups channelGroupTotal:kSoundGroupTotal];
		}
		return self;
	}

	- (void) dealloc
	{
		soundSingleton = nil;
		[super dealloc];
	}

	-(void) loadSound
	{
		// we will check this later
		soundReady = NO;

		// sound engine is already ready
		if ([CDAudioManager sharedManagerState] == kAMStateInitialised)
		{
			[self loadSoundFx:nil];
		}

		// load sound fx when engine is done
		else
		{
			// don't ask me how this works
			NSInvocationOperation* op = [[[NSInvocationOperation alloc]
				initWithTarget:self selector:@selector(loadSoundFx:) object:nil] autorelease];
			NSOperationQueue *opQ = [[[NSOperationQueue alloc] init] autorelease];
			[opQ addOperation:op];
		}
	}

	-(void) loadSoundFx:(NSObject*)data
	{
		// wait until engine is ready...
		while([CDAudioManager sharedManagerState] != kAMStateInitialised)
			[NSThread sleepForTimeInterval:0.1];

		// create requests to load sound fx
		NSMutableArray *loadRequests = [[[NSMutableArray alloc] init] autorelease];
		[loadRequests addObject:[[[CDBufferLoadRequest alloc] init:kFxKarate filePath:@"karate.wav"] autorelease]];
		[loadRequests addObject:[[[CDBufferLoadRequest alloc] init:kFxBelch filePath:@"belch.wav"] autorelease]];
		[loadRequests addObject:[[[CDBufferLoadRequest alloc] init:kFxChomp filePath:@"chomp.aiff"] autorelease]];
		[loadRequests addObject:[[[CDBufferLoadRequest alloc] init:kFxStab filePath:@"stab.caf"] autorelease]];

		// load fx in the background
		CDSoundEngine* engine = [CDAudioManager sharedManager].soundEngine;
		[engine loadBuffersAsynchronously:loadRequests];
	}

	-(void) playSound:(int)fx
	{
		[self playSound:fx volume:1.0f pan:1.0f pitch:1.0f loop:NO];
	}

	-(void) playSound:(int)fx volume:(CGFloat)volume pan:(CGFloat)pan pitch:(CGFloat)pitch loop:(BOOL)loop
	{
		[self updateSound];

		if(soundReady)
		{
			CDSoundEngine* engine = [CDAudioManager sharedManager].soundEngine;
			[engine playSound:fx channelGroupId:kSoundGroupMultiple pitch:pitch pan:pitch gain:volume loop:loop];
		}
	}

	-(void) updateSound
	{
		// check if sound buffers have completed loading
		if([CDAudioManager sharedManager].soundEngine.asynchLoadProgress >= 1.0f)
		{
			// done
			soundReady = YES;
			//[[CDAudioManager sharedManager] setBackgroundMusicCompletionListener:self selector:@selector(backgroundMusicFinished)];
			//[[CDAudioManager sharedManager].soundEngine setChannelGroupNonInterruptible:CGROUP_NON_INTERRUPTIBLE isNonInterruptible:TRUE];
			[[CDAudioManager sharedManager] setResignBehavior:kAMRBStopPlay autoHandle:TRUE];
		}

		//NSLog(@"Sound buffers loading %0.1f", [CDAudioManager sharedManager].soundEngine.asynchLoadProgress);
	}
@end

Leave a Reply

Spam protection by WP Captcha-Free

Storyteller   .:.   Musician   .:.   Vagabond   .:.   Wizard