Skip to content

Instantly share code, notes, and snippets.

@warpling
Last active August 29, 2015 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save warpling/6b6807ee16ba6f097e02 to your computer and use it in GitHub Desktop.
Save warpling/6b6807ee16ba6f097e02 to your computer and use it in GitHub Desktop.
Soundboard - Using TheAmazingAudioEngine to play app sound effects
//
// Soundboard.h
//
//
// Created by Ryan McLeod on 8/19/15.
//
//
#import <Foundation/Foundation.h>
static NSString *const SFX_Sound1 = @"sound1.aif";
static NSString *const SFX_Sound2 = @"sound2.wav";
@interface Soundboard : NSObject
+ (Soundboard*) sharedInstance;
+ (void) play:(NSString *)soundName;
@end
//
// Soundboard.m
//
//
// Created by Ryan McLeod on 8/19/15.
//
//
#import "Soundboard.h"
@interface Soundboard ()
@property NSDictionary *sounds;
@end
@implementation Soundboard
static Soundboard *sharedInstance = nil;
- (instancetype) init {
self = [super init];
if (self) {
// Build all necessary AEAudioFilePlayers
NSMutableDictionary *sounds = [NSMutableDictionary new];
NSArray *filenames = @[SFX_Sound1,
SFX_Sound2];
for (NSString *filename in filenames) {
[sounds setObject:[Soundboard playerForSoundInSoundsBundle:filename] forKey:filename];
}
self.sounds = sounds;
// Get the audio controller
AEAudioController *audioController = ((AppDelegate*)[[UIApplication sharedApplication] delegate]).audioController;
NSAssert(audioController, @"AEAudioController not found in AppDelegate");
// Setup a sound effects channel group and add all our sounds to it
AEChannelGroupRef sfxChannel = [audioController createChannelGroup];
[audioController addChannels:[self.sounds allValues] toChannelGroup:sfxChannel];
}
return self;
}
+ (instancetype) sharedInstance {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[Soundboard alloc] init];
});
return sharedInstance;
}
+ (void) play:(NSString *)soundName {
AEAudioFilePlayer *sound = [[Soundboard sharedInstance].sounds objectForKey:soundName];
if (sound) {
sound.currentTime = 0;
sound.channelIsPlaying = YES;
}
}
+ (AEAudioFilePlayer*) playerForSoundInSoundsBundle:(NSString*)filename {
return [Soundboard playerForSoundInBundle:@"Sounds" filename:filename];
}
+ (AEAudioFilePlayer*) playerForSoundInBundle:(NSString*)bundleName filename:(NSString*)filename {
NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:bundleName ofType:@"bundle"]];
NSURL *url = [bundle URLForResource:[filename stringByDeletingPathExtension] withExtension:[filename pathExtension]];
AEAudioFilePlayer *sound = [AEAudioFilePlayer audioFilePlayerWithURL:url error:nil];
sound.loop = NO;
sound.channelIsPlaying = NO;
return sound;
}
@end
@warpling
Copy link
Author

It should be noted that TAAE has to be started-up before playing sounds!

I keep a shared instance in my AppDelegate and initialize it in application:didFinishLaunchingWithOptions: like so:

AudioStreamBasicDescription streamFormat = [AEAudioController nonInterleaved16BitStereoAudioDescription];
self.audioController = [[AEAudioController alloc] initWithAudioDescription:streamFormat inputEnabled:YES useVoiceProcessing:NO outputEnabled:YES];
// Using ambient will respect the user's silence switch
[self.audioController setAudioSessionCategory:AVAudioSessionCategoryAmbient];

Referencing the soundboard's sharedInstance ([Soundboard sharedInstance]) here would probably be a good idea to avoid any initial delay when the first sound is played and it is forced to build all of its audio players.

@warpling
Copy link
Author

Note: the convenience method playerForSoundInSoundsBundle: assumes your sounds are stored in a bundle called Sounds.bundle in your app's root directory!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment