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