first run through for sound on iOS platforms. Currently works only for simulator unless the music files are extracted from the zip file onto the filesystem.

This commit is contained in:
techdragon.nguyen@gmail.com
2012-02-03 11:23:27 +00:00
parent 52f2435c48
commit 78c08af9f5
8 changed files with 1546 additions and 14 deletions

View File

@@ -0,0 +1,861 @@
//
// SoundManager.m
// SLQTSOR
//
// Created by Michael Daley on 22/05/2009.
// Copyright 2009 Michael Daley. All rights reserved.
//
#import "SoundManager.h"
#import "SynthesizeSingleton.h"
#import "MyOpenALSupport.h"
#pragma mark -
#pragma mark Private interface
@interface SoundManager (Private)
// This method is used to initialize OpenAL. It gets the default device, creates a new context
// to be used and then preloads the define # sources. This preloading means we wil be able to play up to
// (max 32) different sounds at the same time
- (BOOL)initOpenAL;
// Used to get the next available OpenAL source. The returned source is then bound to a sound
// buffer so that the sound can be played. This method checks each of the available OpenAL
// soucres which have been generated and returns the first source which is not currently being
// used. If no sources are found to be free then the first looping source is returned. If there
// are no looping sources then the first source created is returned
- (NSUInteger)nextAvailableSource;
// Used to set the current state of OpenAL. When the game is interrupted the OpenAL state is
// stopped and then restarted when the game becomes active again.
- (void)setActivated:(BOOL)aState;
// If audio is currently playing this method returns YES
- (BOOL)isAudioPlaying;
// Checks to see if an OpenAL error has been logged. If so it renders the error to the screen
- (void)checkForErrors;
@end
#pragma mark -
#pragma mark Public implementation
@implementation SoundManager
// Make this class a singleton class
SYNTHESIZE_SINGLETON_FOR_CLASS(SoundManager);
@synthesize currentMusicVolume;
@synthesize fxVolume;
@synthesize isExternalAudioPlaying;
@synthesize isMusicPlaying;
@synthesize usePlaylist;
@synthesize loopLastPlaylistTrack;
@synthesize musicVolume;
#pragma mark -
#pragma mark Dealloc and Init and Shutdown
- (void)dealloc {
// Loop through the OpenAL sources and delete them
for(NSNumber *sourceIDVal in soundSources) {
NSUInteger sourceID = [sourceIDVal unsignedIntValue];
alDeleteSources(1, &sourceID);
[self checkForErrors];
}
// Loop through the OpenAL buffers and delete
NSEnumerator *enumerator = [soundLibrary keyEnumerator];
id key;
while ((key = [enumerator nextObject])) {
NSNumber *bufferIDVal = [soundLibrary objectForKey:key];
NSUInteger bufferID = [bufferIDVal unsignedIntValue];
alDeleteBuffers(1, &bufferID);
[self checkForErrors];
}
// Release the arrays and dictionaries we have been using
[soundLibrary release];
[soundSources release];
[musicLibrary release];
[musicPlaylists release];
if (currentPlaylistTracks) {
[currentPlaylistTracks release];
}
// If background music has been played then release the AVAudioPlayer
if(musicPlayer)
[musicPlayer release];
// Disable and then destroy the context
alcMakeContextCurrent(NULL);
[self checkForErrors];
alcDestroyContext(context);
[self checkForErrors];
// Close the device
alcCloseDevice(device);
[self checkForErrors];
[super dealloc];
}
- (id)init {
self = [super init];
if(self != nil) {
// Initialize the array and dictionaries we are going to use
soundSources = [[NSMutableArray alloc] init];
soundLibrary = [[NSMutableDictionary alloc] init];
musicLibrary = [[NSMutableDictionary alloc] init];
musicPlaylists = [[NSMutableDictionary alloc] init];
// Grab a reference to the AVAudioSession singleton
audioSession = [AVAudioSession sharedInstance];
// Reset the error ivar
audioSessionError = nil;
// Check to see if music is already playing. If that is the case then you can leave the sound category as AmbientSound.
// If music is not playing we can set the sound category to SoloAmbientSound so that decoding is done using the hardware.
isExternalAudioPlaying = [self isAudioPlaying];
if (!isExternalAudioPlaying) {
NSLog(@"INFO - SoundManager: No external audio playing so using the SoloAmbient audio session category");
soundCategory = AVAudioSessionCategorySoloAmbient;
} else {
NSLog(@"INFO - SoundManager: External sound detected so using the Ambient audio session category");
soundCategory = AVAudioSessionCategoryAmbient;
}
// Having decided on the category we then set it
[audioSession setCategory:soundCategory error:&audioSessionError];
if (audioSessionError) {
NSLog(@"WARNING - SoundManager: Unable to set the sound category to ambient");
}
// Set up the OpenAL. If an error occurs then nil will be returned.
BOOL success = [self initOpenAL];
if(!success) {
NSLog(@"ERROR - SoundManager: Error initializing OpenAL");
return nil;
}
// Set up the listener position
float listener_pos[] = {0, 0, 0};
float listener_ori[] = {0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
float listener_vel[] = {0, 0, 0};
alListenerfv(AL_POSITION, listener_pos);
[self checkForErrors];
alListenerfv(AL_ORIENTATION, listener_ori);
[self checkForErrors];
alListenerfv(AL_VELOCITY, listener_vel);
[self checkForErrors];
// Set the default volume for music and fx along the fading flag
currentMusicVolume = 0.5f;
musicVolume = 0.5f;
fxVolume = 0.5f;
playlistIndex = 0;
// Set up initial flag values
isFading = NO;
isMusicPlaying = NO;
stopMusicAfterFade = YES;
usePlaylist = NO;
loopLastPlaylistTrack = NO;
}
return self;
}
- (void)shutdownSoundManager {
@synchronized(self) {
if(sharedSoundManager != nil) {
[self dealloc];
}
}
}
#pragma mark -
#pragma mark Sound management
- (void)loadSoundWithKey:(NSString*)aSoundKey musicFile:(NSString*)aMusicFile {
// Check to make sure that a sound with the same key does not already exist
NSNumber *numVal = [soundLibrary objectForKey:aSoundKey];
// If the key is not found log it and finish
if(numVal != nil) {
NSLog(@"WARNING - SoundManager: Sound key '%@' already exists.", aSoundKey);
return;
}
NSUInteger bufferID;
// Generate a buffer within OpenAL for this sound
alGenBuffers(1, &bufferID);
[self checkForErrors];
// Set up the variables which are going to be used to hold the format
// size and frequency of the sound file we are loading
ALenum format;
ALsizei size;
ALsizei freq;
ALvoid *data;
alError = AL_NO_ERROR;
NSBundle *bundle = [NSBundle mainBundle];
// Get the audio data from the file which has been passed in
NSString *fileName = [[aMusicFile lastPathComponent] stringByDeletingPathExtension];
NSString *fileType = [aMusicFile pathExtension];
NSString *filePath = [bundle pathForResource:fileName ofType:fileType];
if ( filePath == nil )
filePath = aMusicFile;
CFURLRef fileURL = (CFURLRef)[[NSURL fileURLWithPath: filePath] retain];
if (fileURL)
{
data = MyGetOpenALAudioData(fileURL, &size, &format, &freq);
CFRelease(fileURL);
if((alError = alGetError()) != AL_NO_ERROR) {
NSLog(@"ERROR - SoundManager: Error loading sound: %@ with error %x\n", fileName, alError);
}
// Use the static buffer data API
alBufferData(bufferID, format, data, size, freq);
[self checkForErrors];
if((alError = alGetError()) != AL_NO_ERROR) {
NSLog(@"ERROR - SoundManager: Error attaching audio to buffer: %x\n", alError);
}
// Free the memory we used when getting the audio data
if (data)
free(data);
}
else
{
NSLog(@"ERROR - SoundManager: Could not find file '%@.%@'", fileName, fileType);
if (data)
free(data);
data = NULL;
}
// Place the buffer ID into the sound library against |aSoundKey|
[soundLibrary setObject:[NSNumber numberWithUnsignedInt:bufferID] forKey:aSoundKey];
NSLog(@"INFO - SoundManager: Loaded sound with key '%@' into buffer '%d'", aSoundKey, bufferID);
}
- (void)removeSoundWithKey:(NSString*)aSoundKey {
// Reset errors in OpenAL
alError = alGetError();
alError = AL_NO_ERROR;
// Find the buffer which has been linked to the sound key provided
NSNumber *numVal = [soundLibrary objectForKey:aSoundKey];
// If the key is not found log it and finish
if(numVal == nil) {
NSLog(@"WARNING - SoundManager: No sound with key '%@' was found so cannot be removed", aSoundKey);
return;
}
// Get the buffer number from
NSUInteger bufferID = [numVal unsignedIntValue];
NSInteger bufferForSource;
NSInteger sourceState;
for(NSNumber *sourceID in soundSources) {
NSUInteger currentSourceID = [sourceID unsignedIntValue];
// Grab the current state of the source and also the buffer attached to it
alGetSourcei(currentSourceID, AL_SOURCE_STATE, &sourceState);
[self checkForErrors];
alGetSourcei(currentSourceID, AL_BUFFER, &bufferForSource);
[self checkForErrors];
// If this source is not playing then unbind it. If it is playing and the buffer it
// is playing is the one we are removing, then also unbind that source from this buffer
if(sourceState != AL_PLAYING || (sourceState == AL_PLAYING && bufferForSource == bufferID)) {
alSourceStop(currentSourceID);
[self checkForErrors];
alSourcei(currentSourceID, AL_BUFFER, 0);
[self checkForErrors];
}
}
// Delete the buffer
alDeleteBuffers(1, &bufferID);
// Check for any errors
if((alError = alGetError()) != AL_NO_ERROR) {
NSLog(@"ERROR - SoundManager: Could not delete buffer %d with error %x", bufferID, alError);
exit(1);
}
// Remove the soundkey from the soundLibrary
[soundLibrary removeObjectForKey:aSoundKey];
NSLog(@"INFO - SoundManager: Removed sound with key '%@'", aSoundKey);
}
- (void)loadBackgroundMusicWithKey:(NSString*)aMusicKey musicFile:(NSString*)aMusicFile {
// Get the filename and type from the music file name passed in
NSString *fileName = [[aMusicFile lastPathComponent] stringByDeletingPathExtension];
NSString *fileType = [aMusicFile pathExtension];
// Check to make sure that a sound with the same key does not already exist
NSString *path = [musicLibrary objectForKey:aMusicKey];
// If the key is found log it and finish
if(path != nil) {
NSLog(@"WARNING - SoundManager: Music with the key '%@' already exists.", aMusicKey);
return;
}
path = [[NSBundle mainBundle] pathForResource:fileName ofType:fileType];
if (!path) {
if ( ![[NSFileManager defaultManager] fileExistsAtPath: aMusicFile] )
{
NSLog(@"WARNING - SoundManager: Cannot find file '%@.%@'", fileName, fileType);
return;
}
else
path = aMusicFile;
}
[musicLibrary setObject:path forKey:aMusicKey];
NSLog(@"INFO - SoundManager: Loaded background music with key '%@'", aMusicKey);
}
- (void)removeBackgroundMusicWithKey:(NSString*)aMusicKey {
NSString *path = [musicLibrary objectForKey:aMusicKey];
if(path == NULL) {
NSLog(@"WARNING - SoundManager: No music found with key '%@' was found so cannot be removed", aMusicKey);
return;
}
[musicLibrary removeObjectForKey:aMusicKey];
NSLog(@"INFO - SoundManager: Removed music with key '%@'", aMusicKey);
}
- (void)addToPlaylistNamed:(NSString*)aPlaylistName track:(NSString*)aTrackName {
NSString *path = [musicLibrary objectForKey:aTrackName];
if (!path) {
NSLog(@"WARNING - SoundManager: Track '%@' does not exist in the music library and cannot be added to the play list.");
return;
}
// See if the playlist already exists
NSMutableArray *playlistTracks = [musicPlaylists objectForKey:aPlaylistName];
if (!playlistTracks) {
playlistTracks = [[NSMutableArray alloc] init];
}
[playlistTracks addObject:aTrackName];
// Add the track key to the play list
[musicPlaylists setObject:playlistTracks forKey:aPlaylistName];
}
- (void)startPlaylistNamed:(NSString*)aPlaylistName {
NSMutableArray *playlistTracks = [musicPlaylists objectForKey:aPlaylistName];
if (!playlistTracks) {
NSLog(@"WARNING - SoundManager: No play list exists with the name '%@'", aPlaylistName);
return;
}
currentPlaylistName = aPlaylistName;
currentPlaylistTracks = playlistTracks;
usePlaylist = YES;
[self playMusicWithKey:[playlistTracks objectAtIndex:0] timesToRepeat:0];
}
- (void)removeFromPlaylistNamed:(NSString*)aPlaylistName track:(NSString*)aTrackName {
NSMutableArray *playlistTracks = [musicPlaylists objectForKey:aPlaylistName];
if (playlistTracks) {
int indexToRemove;
for (int index=0; index < [currentPlaylistTracks count]; index++) {
if ([[currentPlaylistTracks objectAtIndex:index] isEqualToString:aTrackName]) {
indexToRemove = index;
break;
}
}
[currentPlaylistTracks removeObjectAtIndex:indexToRemove];
}
}
- (void)removePlaylistNamed:(NSString*)aPlaylistName {
[musicPlaylists removeObjectForKey:aPlaylistName];
}
- (void)clearPlaylistNamed:(NSString*)aPlaylistName {
NSMutableArray *playlistTracks = [musicPlaylists objectForKey:aPlaylistName];
if (playlistTracks) {
[playlistTracks removeAllObjects];
}
}
#pragma mark -
#pragma mark Sound control
- (NSUInteger)playSoundWithKey:(NSString*)aSoundKey gain:(float)aGain pitch:(float)aPitch location:(CGPoint)aLocation shouldLoop:(BOOL)aLoop sourceID:(NSUInteger)aSourceID {
// Find the buffer linked to the key which has been passed in
NSNumber *numVal = [soundLibrary objectForKey:aSoundKey];
if(numVal == nil) return 0;
NSUInteger bufferID = [numVal unsignedIntValue];
// Find an available source if -1 has been passed in as the sourceID. If the sourceID is
// not -1 i.e. a source ID has been passed in then check to make sure that source is not playing
// and if not play the identified buffer ID within the provided source
NSUInteger sourceID;
if(aSourceID == -1) {
sourceID = [self nextAvailableSource];
} else {
NSInteger sourceState;
alGetSourcei(aSourceID, AL_SOURCE_STATE, &sourceState);
if(sourceState == AL_PLAYING)
return 0;
sourceID = aSourceID;
}
// Make sure that the source is clean by resetting the buffer assigned to the source
// to 0
alSourcei(sourceID, AL_BUFFER, 0);
// Attach the buffer we have looked up to the source we have just found
alSourcei(sourceID, AL_BUFFER, bufferID);
// Set the pitch and gain of the source
alSourcef(sourceID, AL_PITCH, aPitch);
alSourcef(sourceID, AL_GAIN, aGain * fxVolume);
// Set the looping value
if(aLoop) {
alSourcei(sourceID, AL_LOOPING, AL_TRUE);
} else {
alSourcei(sourceID, AL_LOOPING, AL_FALSE);
}
// Set the source location
alSource3f(sourceID, AL_POSITION, aLocation.x, aLocation.y, 0.0f);
// Now play the sound
alSourcePlay(sourceID);
alError = alGetError();
// Check to see if there were any errors
[self checkForErrors];
// Return the source ID so that loops can be stopped etc
return sourceID;
}
- (void)stopSoundWithKey:(NSString*)aSoundKey {
// Reset errors in OpenAL
alError = alGetError();
alError = AL_NO_ERROR;
// Find the buffer which has been linked to the sound key provided
NSNumber *numVal = [soundLibrary objectForKey:aSoundKey];
// If the key is not found log it and finish
if(numVal == nil) {
NSLog(@"WARNING - SoundManager: No sound with key '%@' was found so cannot be stopped", aSoundKey);
return;
}
// Get the buffer number from
NSUInteger bufferID = [numVal unsignedIntValue];
NSInteger bufferForSource;
NSInteger sourceState;
for(NSNumber *sourceID in soundSources) {
NSUInteger currentSourceID = [sourceID unsignedIntValue];
// Grab the current state of the source and also the buffer attached to it
alGetSourcei(currentSourceID, AL_SOURCE_STATE, &sourceState);
alGetSourcei(currentSourceID, AL_BUFFER, &bufferForSource);
// If this source is not playing then unbind it. If it is playing and the buffer it
// is playing is the one we are removing, then also unbind that source from this buffer
if(bufferForSource == bufferID) {
alSourceStop(currentSourceID);
alSourcei(currentSourceID, AL_BUFFER, 0);
}
}
// Check for any errors
[self checkForErrors];
// Remove the soundkey from the soundLibrary
[soundLibrary removeObjectForKey:aSoundKey];
NSLog(@"INFO - SoundManager: Removed sound with key '%@'", aSoundKey);
}
- (void)playMusicWithKey:(NSString*)aMusicKey timesToRepeat:(NSUInteger)aRepeatCount {
NSError *error;
NSString *path = [musicLibrary objectForKey:aMusicKey];
if(!path) {
NSLog(@"ERROR - SoundManager: The music key '%@' could not be found", aMusicKey);
return;
}
if(musicPlayer)
[musicPlayer release];
// Initialize the AVAudioPlayer using the path that we have retrieved from the music library dictionary
musicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&error];
// If the backgroundMusicPlayer object is nil then there was an error
if(!musicPlayer) {
NSLog(@"ERROR - SoundManager: Could not play music for key '%d'", error);
return;
}
// Set the delegate for this music player to be the sound manager
musicPlayer.delegate = self;
// Set the number of times this music should repeat. -1 means never stop until its asked to stop
[musicPlayer setNumberOfLoops:aRepeatCount];
// Set the volume of the music
[musicPlayer setVolume:currentMusicVolume];
// Play the music
[musicPlayer play];
// Set the isMusicPlaying flag
isMusicPlaying = YES;
}
- (void)playNextTrack {
if (playlistIndex + 1 == [currentPlaylistTracks count]-1 && loopLastPlaylistTrack) {
playlistIndex += 1;
[self playMusicWithKey:[currentPlaylistTracks objectAtIndex:playlistIndex] timesToRepeat:-1];
} else if (playlistIndex + 1 < [currentPlaylistTracks count]) {
playlistIndex += 1;
[self playMusicWithKey:[currentPlaylistTracks objectAtIndex:playlistIndex] timesToRepeat:0];
} else if (loopPlaylist) {
playlistIndex = 0;
[self playMusicWithKey:[currentPlaylistTracks objectAtIndex:playlistIndex] timesToRepeat:0];
}
}
- (void)stopMusic {
[musicPlayer stop];
isMusicPlaying = NO;
usePlaylist = NO;
}
- (void)pauseMusic {
if(musicPlayer)
[musicPlayer pause];
isMusicPlaying = NO;
}
- (void)resumeMusic {
if (musicPlayer) {
[musicPlayer play];
isMusicPlaying = YES;
}
}
#pragma mark -
#pragma mark SoundManager settings
- (void)setMusicVolume:(float)aVolume {
// Set the volume iVar
if (aVolume > 1)
aVolume = 1.0f;
currentMusicVolume = aVolume;
musicVolume = aVolume;
// Check to make sure that the audio player exists and if so set its volume
if(musicPlayer) {
[musicPlayer setVolume:currentMusicVolume];
}
}
- (void)setFxVolume:(float)aVolume {
fxVolume = aVolume;
}
- (void)setListenerPosition:(CGPoint)aPosition {
listenerPosition = aPosition;
alListener3f(AL_POSITION, aPosition.x, aPosition.y, 0.0f);
}
- (void)setOrientation:(CGPoint)aPosition {
float orientation[] = {aPosition.x, aPosition.y, 0.0f, 0.0f, 0.0f, 1.0f};
alListenerfv(AL_ORIENTATION, orientation);
}
- (void)fadeMusicVolumeFrom:(float)aFromVolume toVolume:(float)aToVolume duration:(float)aSeconds stop:(BOOL)aStop {
// If there is already a fade timer active, invalidate it so we can start another one
if (timer) {
[timer invalidate];
timer = NULL;
}
// Work out how much to fade the music by based on the current volume, the requested volume
// and the duration
fadeAmount = (aToVolume - aFromVolume) / (aSeconds / kFadeInterval);
currentMusicVolume = aFromVolume;
// Reset the fades duration
fadeDuration = 0;
targetFadeDuration = aSeconds;
isFading = YES;
stopMusicAfterFade = aStop;
// Set up a timer that fires kFadeInterval times per second calling the fadeVolume method
timer = [NSTimer scheduledTimerWithTimeInterval:kFadeInterval target:self selector:@selector(fadeVolume:) userInfo:nil repeats:TRUE];
}
- (void)crossFadeTo:(NSString*)aTrack duration:(float)aDuration {
// TODO: Finish this method
}
#pragma mark -
#pragma mark AVAudioPlayerDelegate
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
isMusicPlaying = NO;
// If we are using a play list then handle the next track to be played
if (usePlaylist) {
[self playNextTrack];
}
}
#pragma mark -
#pragma mark AVAudioSessionDelegate
- (void)beginInterruption {
NSLog(@"BEGIN");
[self setActivated:NO];
}
- (void)endInterruption {
[self setActivated:YES];
}
@end
#pragma mark -
#pragma mark Private implementation
@implementation SoundManager (Private)
// Define the number of sources which will be created. iPhone can have a max of 32
#define MAX_OPENAL_SOURCES 16
- (BOOL)initOpenAL {
NSLog(@"INFO - Sound Manager: Initializing sound manager");
// Get the device we are going to use for sound. Using NULL gets the default device
device = alcOpenDevice(NULL);
// If a device has been found we then need to create a context, make it current and then
// preload the OpenAL Sources
if(device) {
// Use the device we have now got to create a context in which to play our sounds
context = alcCreateContext(device, NULL);
[self checkForErrors];
// Make the context we have just created into the active context
alcMakeContextCurrent(context);
[self checkForErrors];
// Set the distance model to be used
alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
[self checkForErrors];
// Pre-create sound sources which can be dynamically allocated to buffers (sounds)
NSUInteger sourceID;
for(int index = 0; index < MAX_OPENAL_SOURCES; index++) {
// Generate an OpenAL source
alGenSources(1, &sourceID);
[self checkForErrors];
// Configure the generated source so that sounds fade as the player moves
// away from them
alSourcef(sourceID, AL_REFERENCE_DISTANCE, 25.0f);
alSourcef(sourceID, AL_MAX_DISTANCE, 150.0f);
alSourcef(sourceID, AL_ROLLOFF_FACTOR, 6.0f);
[self checkForErrors];
// Add the generated sourceID to our array of sound sources
[soundSources addObject:[NSNumber numberWithUnsignedInt:sourceID]];
}
NSLog(@"INFO - Sound Manager: Finished initializing the sound manager");
// Return YES as we have successfully initialized OpenAL
return YES;
}
// We were unable to obtain a device for playing sound so tell the user and return NO.
NSLog(@"ERROR - SoundManager: Unable to allocate a device for sound.");
return NO;
}
- (NSUInteger)nextAvailableSource {
// Holder for the current state of the current source
NSInteger sourceState;
// Find a source which is not being used at the moment
for(NSNumber *sourceNumber in soundSources) {
alGetSourcei([sourceNumber unsignedIntValue], AL_SOURCE_STATE, &sourceState);
// If this source is not playing then return it
if(sourceState != AL_PLAYING) return [sourceNumber unsignedIntValue];
}
// If all the sources are being used we look for the first non looping source
// and use the source associated with that
NSInteger looping;
for(NSNumber *sourceNumber in soundSources) {
alGetSourcei([sourceNumber unsignedIntValue], AL_LOOPING, &looping);
if(!looping) {
// We have found a none looping source so return this source and stop checking
NSUInteger sourceID = [sourceNumber unsignedIntValue];
alSourceStop(sourceID);
return sourceID;
}
}
// If there are no looping sources to be found then just use the first source and use that
NSUInteger sourceID = [[soundSources objectAtIndex:0] unsignedIntegerValue];
alSourceStop(sourceID);
// Check for any errors that may have been raised
[self checkForErrors];
// Return the sourceID found
return sourceID;
}
#pragma mark -
#pragma mark Interruption handling
- (void)setActivated:(BOOL)aState {
OSStatus result;
if(aState) {
NSLog(@"INFO - SoundManager: OpenAL Active");
// Set the AudioSession AudioCategory to what has been defined in soundCategory
[audioSession setCategory:soundCategory error:&audioSessionError];
if(audioSessionError) {
NSLog(@"ERROR - SoundManager: Unable to set the audio session category");
return;
}
// Set the audio session state to true and report any errors
[audioSession setActive:YES error:&audioSessionError];
if (audioSessionError) {
NSLog(@"ERROR - SoundManager: Unable to set the audio session state to YES with error %d.", result);
return;
}
if (musicPlayer) {
[musicPlayer play];
}
// As we are finishing the interruption we need to bind back to our context.
alcMakeContextCurrent(context);
[self checkForErrors];
} else {
NSLog(@"INFO - SoundManager: OpenAL Inactive");
// As we are being interrupted we set the current context to NULL. If this sound manager is to be
// compaitble with firmware prior to 3.0 then the context would need to also be destroyed and
// then re-created when the interruption ended.
alcMakeContextCurrent(NULL);
[self checkForErrors];
}
}
- (BOOL)isAudioPlaying {
UInt32 audioPlaying = 0;
UInt32 audioPlayingSize = sizeof(audioPlaying);
AudioSessionGetProperty(kAudioSessionProperty_OtherAudioIsPlaying, &audioPlayingSize, &audioPlaying);
return (BOOL)audioPlaying;
}
- (void)fadeVolume:(NSTimer*)aTimer {
fadeDuration += kFadeInterval;
if (fadeDuration > targetFadeDuration) {
if (timer) {
[timer invalidate];
timer = NULL;
}
isFading = NO;
if (stopMusicAfterFade) {
[musicPlayer stop];
isMusicPlaying = NO;
}
} else {
currentMusicVolume += fadeAmount;
}
// If music is current playing then set its volume
if(isMusicPlaying) {
[musicPlayer setVolume:currentMusicVolume];
}
}
- (void)checkForErrors {
alError = alGetError();
if(alError != AL_NO_ERROR) {
NSLog(@"ERROR - SoundManager: OpenAL reported error '%d'", alError);
}
}
@end