PageRenderTime 42ms CodeModel.GetById 18ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/libs/ObjectAL/ObjectAL.h

http://github.com/kstenerud/ObjectAL-for-iPhone
C Header | 718 lines | 23 code | 7 blank | 688 comment | 0 complexity | 5aeb8d979676d41502ff5a9b873b221a MD5 | raw file
  1//
  2//  ObjectAL.h
  3//  ObjectAL
  4//
  5//  Created by Karl Stenerud on 15/12/09.
  6//
  7// Copyright 2009 Karl Stenerud
  8//
  9// Licensed under the Apache License, Version 2.0 (the "License");
 10// you may not use this file except in compliance with the License.
 11// You may obtain a copy of the License at
 12//
 13// http://www.apache.org/licenses/LICENSE-2.0
 14//
 15// Unless required by applicable law or agreed to in writing, software
 16// distributed under the License is distributed on an "AS IS" BASIS,
 17// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 18// See the License for the specific language governing permissions and
 19// limitations under the License.
 20//
 21// Note: You are NOT required to make the license available from within your
 22// iOS application. Including it in your project is sufficient.
 23//
 24// Attribution is not required, but appreciated :)
 25//
 26
 27// Actions
 28#import "OALAction.h"
 29#import "OALAudioActions.h"
 30#import "OALUtilityActions.h"
 31#import "OALActionManager.h"
 32#import "OALFunction.h"
 33
 34// AudioTrack
 35#import "OALAudioTrack.h"
 36#import "OALAudioTracks.h"
 37#import "OALAudioTrackNotifications.h"
 38
 39// OpenAL
 40#import "ALTypes.h"
 41#import "ALBuffer.h"
 42#import "ALCaptureDevice.h"
 43#import "ALContext.h"
 44#import "ALDevice.h"
 45#import "ALListener.h"
 46#import "ALSource.h"
 47#import "ALWrapper.h"
 48#import "ALChannelSource.h"
 49#import "ALSoundSourcePool.h"
 50#import "OpenALManager.h"
 51#import "OALAudioFile.h"
 52
 53// Other
 54#import "OALNotifications.h"
 55#import "OALAudioSession.h"
 56#import "OALSimpleAudio.h"
 57
 58
 59
 60/** \mainpage ObjectAL for iPhone
 61 
 62 <strong>iOS Audio development, minus the headache.</strong> <br><br>
 63 
 64 Version 2.0 <br> <br>
 65 
 66 Copyright 2009-2011 Karl Stenerud <br><br>
 67 
 68 Released under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License v2.0</a>
 69 
 70 <br> <br>
 71 \section contents_sec Contents
 72 - \ref intro_sec
 73 - \ref objectal_and_openal_sec
 74 - \ref add_objectal_sec (also, installing the documentation into XCode)
 75 - \ref configuration_sec
 76 - \ref audio_formats_sec
 77 - \ref choosing_sec
 78 - \ref use_iossimpleaudio_sec
 79 - \ref use_objectal_sec
 80 - \ref other_examples_sec
 81 - \ref ios_issues_sec
 82 - \ref simulator_issues_sec
 83 
 84 
 85 <br> <br>
 86 \section intro_sec Introduction
 87 
 88 <strong>ObjectAL for iPhone</strong> is designed to be a simpler, more intuitive interface to
 89 OpenAL and AVAudioPlayer.
 90 There are four main parts to <strong>ObjectAL for iPhone</strong>:<br/><br/>
 91 
 92 \image html ObjectAL-Overview1.png
 93 \image latex ObjectAL-Overview1.eps
 94
 95 - <a class="el" href="index.html#objectal_and_openal_sec">ObjectAL</a>
 96   gives you full access to the OpenAL system without the hassle of the C API.
 97   All OpenAL operations can be performed using first class objects and properties, without needing
 98   to muddle around with arrays of data, maintain IDs, or pass around pointers to basic types.
 99   ObjectALManager also provides sound loading routines.
100
101 - OALAudioTrack provides a simpler interface to AVAudioPlayer, allowing you to play, stop,
102   pause, fade, and mute background music tracks.
103 
104 - OALAudioSession handles audio session management in iOS devices, and provides an easy
105   way to configure session behavior such as how to handle iPod-style music and the silent
106   switch.
107 
108 - OALSimpleAudio layers on top of the other three, providing an even simpler interface for
109   playing background music and sound effects.
110  
111 
112 <br> <br>
113 \section objectal_and_openal_sec ObjectAL and OpenAL
114 
115 <strong>ObjectAL</strong> follows the same basic principles as the
116 <a href="http://connect.creativelabs.com/openal">OpenAL API by Creative Labs</a>.
117 
118 \image html ObjectAL-Overview2.png
119 \image latex ObjectAL-Overview2.eps
120 
121 - OpenALManager provides some overall controls that affect everything, manages the current
122   context, and provides audio loading routines.
123 
124 - ALDevice represents a physical audio device. <br>
125   Each device can have one or more contexts (ALContext) created on it, and can have multiple
126   buffers (ALBuffer) associated with it.
127
128 - ALContext controls the overall sound environment, such as distance model, doppler effect, and
129   speed of sound. <br>
130   Each context has one listener (ALListener), and can have multiple sources (ALSource) opened on
131   it (up to a maximum of 32 overall on iPhone).
132 
133 - ALListener represents the listener of sounds originating on its context (one listener per
134   context). It has position, orientation, and velocity.
135 
136 - ALSource is a sound emitting source that plays sound data from an ALBuffer. It has position,
137   direction, velocity, as well as other properties which determine how the sound is emitted.
138 
139 - ALChannelSource allows you to reserve a certain number of sources for special purposes.
140 
141 - ALBuffer is simply a container for sound data. Only linear PCM is supported directly, but
142   OpenALManager load methods, and OALSimpleAudio effect preload and play methods, will
143   automatically convert any formats that don't require hardware decoding (though conversion
144   results in a longer loading time).
145 
146 <strong>Note:</strong> While OpenAL allows for multiple devices and contexts, in practice
147 you'll only use one device and one context when using OpenAL under iOS.
148
149 Further information regarding the more advanced features of OpenAL (such as distance models)
150 are available via the
151 <a href="http://connect.creativelabs.com/openal/Documentation/Forms/AllItems.aspx">
152 OpenAL Documentation at Creative Labs</a>. <br>
153 In particular, read up on the various property values for sources and listeners (such as Doppler
154 Shift) in the
155 <a href="http://connect.creativelabs.com/openal/Documentation/OpenAL_Programmers_Guide.pdf">OpenAL Programmer's Guide</a>,
156 and distance models in section 3 of the
157 <a href="http://connect.creativelabs.com/openal/Documentation/OpenAL%201.1%20Specification.pdf">OpenAL Specification</a>.
158 
159 
160 <br> <br>
161 \section add_objectal_sec Adding ObjectAL to your project
162 
163 To add ObjectAL to your project, do the following:
164
165 <ol>
166	<li>Copy libs/ObjectAL from this project into your project. You can simply drag it into the
167		"Groups & Files" section in xcode if you like (be sure to select "Copy items into
168		destination group's folder"). <br/>
169		Alternatively, you can build ObjectAL as a static library (as it's configured to do in the
170		ObjectAL demo project).<br/><br/>
171	</li>
172
173	<li>Add the following frameworks to your project:
174		<ul>
175			<li>OpenAL.framework</li>
176			<li>AudioToolbox.framework</li>
177			<li>AVFoundation.framework</li>
178		</ul><br/>
179	</li>
180 
181	<li>Start using ObjectAL!<br/><br/></li>
182 </ol>
183 <br/>
184 <strong>Note:</strong> The demos in this project use
185 <a href="http://www.cocos2d-iphone.org">Cocos2d</a>, a very nice 2d game engine. However,
186 ObjectAL doesn't require it. You can just as easily use ObjectAL in your Cocoa app or anything
187 you wish.
188 <br/> <br/>
189 <strong>Note #2:</strong> You do NOT have to provide a link to the Apache license from within your
190 application. Simply including a copy of the license in your project is sufficient.
191
192 <br>
193 \subsection install_dox Installing the ObjectAL Documentation into XCode
194 
195 By installing the ObjectAL documentation into XCode's Developer Documentation system, you gain
196 the ability to look up ObjectAL classes and methods just like you'd look up Apple classes and
197 methods. You can install the ObjectAL documentation into XCode's Developer Documentation
198 system by doing the following: 
199 -# Install <a href="http://www.doxygen.org">Doxygen</a>. You can either use the OSX installer or
200    MacPorts.
201 -# Build the "Documentation" target in this project.
202 -# Open the developer documentation and type "ObjectAL" into the search box.
203 
204 
205 <br> <br>
206 \section configuration_sec Compile-Time Configuration
207 
208 <strong>ObjectALConfig.h</strong> contains configuration defines that will affect at a high level
209 how ObjectAL behaves. Look inside <strong>ObjectALConfig.h</strong> to see what can be
210 configured, and what each configuration value does. <br>
211 The recommended values are fine for most users, but Cocos2D users may want to set
212 OBJECTAL_USE_COCOS2D_ACTIONS so that the audio actions (such as fade) use the Cocos2D action manager.
213 
214 
215 <br> <br>
216 \section audio_formats_sec Audio Formats
217 
218 The audio formats officially supported by Apple are
219 <a href="http://developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/MultimediaPG/UsingAudio/UsingAudio.html">
220 defined here</a>.
221 <br><br>
222 
223 \subsection audio_formats_avaudioplayer OALAudioTrack Supported Formats
224 
225 OALAudioTrack supports all hardware and software decoded formats.
226 <br><br>
227 
228 \subsection audio_formats_openal OpenAL Supported Formats
229 
230 OpenAL officially supports 8 or 16 bit PCM data only. However, Apple's implementation
231 only seems to work with 16 bit data. <br>
232 
233 The effects preloading/playing methods in OALSimpleAudio and the buffer loading methods
234 in OpenALManager can load any audio file that can be software decoded. However, there
235 is a cost incurred at load time converting to a native OpenAL format. To avoid this,
236 convert all of your samples to a CAFF container with 16-bit little endian integer PCM
237 format and the same sample rate as "mixerOutputFrequency" in OpenALManager
238 (by default, 44100Hz). Note, however, that uncompressed files can get quite large.<br>
239 
240 Convert to iOS native uncompressed format using Apple's "afconvert" command line tool:
241 
242 \code afconvert -f caff -d LEI16@44100 sourcefile.wav destfile.caf \endcode
243 
244 Alternatively, if sound file load time is not an issue for you, you can lower your app
245 footprint size (for over-the-air app download) by using a compressed format. <br>
246 
247 Convert to AAC compressed format with CAFF container using Apple's "afconvert" command
248 line tool:
249 
250 \code afconvert -f caff -d aac sourcefile.wav destfile.caf \endcode
251 
252 
253 <br> <br>
254 \section choosing_sec Choosing Playback Types
255 
256 <strong>OpenAL</strong> (ALSource, or effects in OALSimpleAudio) and
257 <strong>AVAudioPlayer</strong> (OALAudioTrack, or background audio in OALSimpleAudio)
258 are playback technologies built for different purposes. OpenAL is designed for game-style
259 short sound effects that have no playback delay. AVAudioPlayer is designed for music
260 playback. You can of course mix and match as you please.
261 
262 <table>
263   <tr>
264     <td></td>
265     <td><strong>OpenAL</strong></td>
266     <td><strong>AVAudioPlayer</strong></td>
267   </tr>
268   <tr>
269     <td><strong>Playback Delay</strong></td>
270     <td>None</td>
271     <td>Small delay if not preloaded</td>
272   </tr>
273   <tr>
274     <td><strong>Format on Disk</strong></td>
275     <td><a href="http://developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/MultimediaPG/UsingAudio/UsingAudio.html">
276		 Any software decodable format</a></td>
277     <td><a href="http://developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/MultimediaPG/UsingAudio/UsingAudio.html">
278         Any software decodable format, or any hardware format if using hardware</a></td>
279   </tr>
280   <tr>
281     <td><strong>Decoding</strong></td>
282     <td>During load</td>
283     <td>During playback</td>
284   </tr>
285   <tr>
286     <td><strong>Memory Use</strong></td>
287     <td>Entire file loaded and decompressed into memory</td>
288     <td>File streamed realtime (very low memory use)</td>
289   </tr>
290   <tr>
291     <td><strong>Max Simult. Sources</strong></td>
292     <td>32</td>
293     <td>As many as the CPU can handle</td>
294   </tr>
295   <tr>
296     <td><strong>Playback Performance</strong></td>
297     <td>Good</td>
298     <td>Excellent with 1 track (if using hardware). Good with 2 tracks. Not so good with more
299         (each non-hardware track taxes the CPU significantly, especially if the files are compressed).</td>
300   </tr>
301   <tr>
302     <td><strong>Looped Playback</strong></td>
303     <td>Yes (on or off)</td>
304     <td>Yes (specify number of loops or -1 = forever)</td>
305   </tr>
306 <tr>
307     <td><strong>Panning</strong></td>
308     <td>Yes (mono files only)</td>
309     <td>Yes (iOS 4.0+ only)</td>
310   </tr>
311   <tr>
312     <td><strong>Positional Audio</strong></td>
313     <td>Yes (mono files only)</td>
314     <td>No</td>
315   </tr>
316   <tr>
317     <td><strong>Modify Pitch</strong></td>
318     <td>Yes</td>
319     <td>No</td>
320   </tr>
321   <tr>
322     <td><strong>Audio Power Metering</strong></td>
323     <td>No</td>
324     <td>Yes</td>
325   </tr>
326 </table>
327 
328
329 <br> <br>
330 \section use_iossimpleaudio_sec Using OALSimpleAudio
331 
332 By far, the easiest component to use is OALSimpleAudio. You sacrifice some power for
333 ease-of-use, but for many projects it is more than sufficient. You can also use your own instances
334 of OALAudioTrack, ALSource, ALBuffer and such alongside of OALSimpleAudio if you want (just be sure
335 to set OALSimpleAudio's reservedSources to less than 32 if you want to make your own instances of
336 ALSource).
337 
338 Here is a code example using purely OALSimpleAudio:
339 
340 \code
341// OALSimpleAudioSample.h
342
343@interface OALSimpleAudioSample : NSObject
344{
345	// No objects to keep track of...
346}
347
348@end
349
350
351// OALSimpleAudioSample.m
352
353#import "OALSimpleAudioSample.h"
354#import "ObjectAL.h"
355
356
357#define SHOOT_SOUND @"shoot.caf"
358#define EXPLODE_SOUND @"explode.caf"
359
360#define INGAME_MUSIC_FILE @"bg_music.mp3"
361#define GAMEOVER_MUSIC_FILE @"gameover_music.mp3"
362
363
364@implementation OALSimpleAudioSample
365
366- (id) init
367{
368	if(nil != (self = [super init]))
369	{
370		// We don't want ipod music to keep playing since
371		// we have our own bg music.
372		[OALSimpleAudio sharedInstance].allowIpod = NO;
373		
374		// Mute all audio if the silent switch is turned on.
375		[OALSimpleAudio sharedInstance].honorSilentSwitch = YES;
376		
377		// This loads the sound effects into memory so that
378		// there's no delay when we tell it to play them.
379		[[OALSimpleAudio sharedInstance] preloadEffect:SHOOT_SOUND];
380		[[OALSimpleAudio sharedInstance] preloadEffect:EXPLODE_SOUND];
381	}
382	return self;
383}
384
385- (void) onGameStart
386{
387	// Play the BG music and loop it.
388	[[OALSimpleAudio sharedInstance] playBg:INGAME_MUSIC_FILE loop:YES];
389}
390
391- (void) onGamePause
392{
393	[OALSimpleAudio sharedInstance].paused = YES;
394}
395
396- (void) onGameResume
397{
398	[OALSimpleAudio sharedInstance].paused = NO;
399}
400
401- (void) onGameOver
402{
403	// Could use stopEverything here if you want
404	[[OALSimpleAudio sharedInstance] stopAllEffects];
405	
406	// We only play the game over music through once.
407	[[OALSimpleAudio sharedInstance] playBg:GAMEOVER_MUSIC_FILE];
408}
409
410- (void) onShipShotABullet
411{
412	[[OALSimpleAudio sharedInstance] playEffect:SHOOT_SOUND];
413}
414
415- (void) onShipGotHit
416{
417	[[OALSimpleAudio sharedInstance] playEffect:EXPLODE_SOUND];
418}
419
420- (void) onQuitToMainMenu
421{
422	// Stop all music and sound effects.
423	[[OALSimpleAudio sharedInstance] stopEverything];	
424	
425	// Unload all sound effects and bg music so that it doesn't fill
426	// memory unnecessarily.
427	[[OALSimpleAudio sharedInstance] unloadAllEffects];
428}
429
430@end
431 \endcode
432 
433 
434 <br> <br>
435 \section use_objectal_sec Using the OpenAL Objects and OALAudioTrack
436 
437 The OpenAL objects and OALAudioTrack offer you much more power at the cost
438 of complexity.
439 Here's the same thing as above, done using OpenAL components and OALAudioTrack:
440 
441 \code
442// OpenALAudioTrackSample.h
443
444#import <Foundation/Foundation.h>
445#import "ObjectAL.h"
446
447
448@interface OpenALAudioTrackSample : NSObject
449{
450	// Sound Effects
451	ALDevice* device;
452	ALContext* context;
453	ALChannelSource* channel;
454	ALBuffer* shootBuffer;	
455	ALBuffer* explosionBuffer;
456	
457	// Background Music
458	OALAudioTrack* musicTrack;
459}
460
461@end
462
463
464// OpenALAudioTrackSample.m
465
466#import "OpenALAudioTrackSample.h"
467
468
469#define SHOOT_SOUND @"shoot.caf"
470#define EXPLODE_SOUND @"explode.caf"
471
472#define INGAME_MUSIC_FILE @"bg_music.mp3"
473#define GAMEOVER_MUSIC_FILE @"gameover_music.mp3"
474
475
476@implementation OpenALAudioTrackSample
477
478- (id) init
479{
480	if(nil != (self = [super init]))
481	{
482		// Create the device and context.
483		// Note that it's easier to just let OALSimpleAudio handle
484		// these rather than make and manage them yourself.
485		device = [[ALDevice deviceWithDeviceSpecifier:nil] retain];
486		context = [[ALContext contextOnDevice:device attributes:nil] retain];
487		[OpenALManager sharedInstance].currentContext = context;
488		
489		// Deal with interruptions for me!
490		[OALAudioSession sharedInstance].handleInterruptions = YES;
491		
492		// We don't want ipod music to keep playing since
493		// we have our own bg music.
494		[OALAudioSession sharedInstance].allowIpod = NO;
495		
496		// Mute all audio if the silent switch is turned on.
497		[OALAudioSession sharedInstance].honorSilentSwitch = YES;
498		
499		// Take all 32 sources for this channel.
500		// (we probably won't use that many but what the heck!)
501		channel = [[ALChannelSource channelWithSources:32] retain];
502		
503		// Preload the buffers so we don't have to load and play them later.
504		shootBuffer = [[[OpenALManager sharedInstance]
505						bufferFromFile:SHOOT_SOUND] retain];
506		explosionBuffer = [[[OpenALManager sharedInstance]
507							bufferFromFile:EXPLODE_SOUND] retain];
508		
509		// Background music track.
510		musicTrack = [[OALAudioTrack track] retain];
511	}
512	return self;
513}
514
515- (void) dealloc
516{
517	[musicTrack release];
518	
519	[channel release];
520	[shootBuffer release];
521	[explosionBuffer release];
522	
523	// Note: You'll likely only have one device and context open throughout
524	// your program, so in a real program you'd be better off making a
525	// singleton object that manages the device and context, rather than
526	// allocating/deallocating it here.
527	// Most of the demos just let OALSimpleAudio manage the device and context
528	// for them.
529	[context release];
530	[device release];
531	
532	[super dealloc];
533}
534
535- (void) onGameStart
536{
537	// Play the BG music and loop it forever.
538	[musicTrack playFile:INGAME_MUSIC_FILE loops:-1];
539}
540
541- (void) onGamePause
542{
543	musicTrack.paused = YES;
544	channel.paused = YES;
545}
546
547- (void) onGameResume
548{
549	channel.paused = NO;
550	musicTrack.paused = NO;
551}
552
553- (void) onGameOver
554{
555	[channel stop];
556	[musicTrack stop];
557	
558	// We only play the game over music through once.
559	[musicTrack playFile:GAMEOVER_MUSIC_FILE];
560}
561
562- (void) onShipShotABullet
563{
564	[channel play:shootBuffer];
565}
566
567- (void) onShipGotHit
568{
569	[channel play:explosionBuffer];
570}
571
572- (void) onQuitToMainMenu
573{
574	// Stop all music and sound effects.
575	[channel stop];
576	[musicTrack stop];
577}
578
579@end
580 \endcode
581 
582 
583 
584 <br> <br>
585 \section other_examples_sec Other Examples
586 
587 The demo scenes in this distribution have been crafted to demonstrate common uses of this library.
588 Try them out and go through the code to see how it's done. I've done my best to keep the code
589 readable. Really!
590 
591 The current demos are:
592 - <strong>SingleSourceDemo</strong>: Demonstrates using a location based source and a listener.
593 - <strong>TwoSourceDemo</strong>: Demonstrates using two location based sources and a listener.
594 - <strong>VolumePitchPanDemo</strong>: Demonstrates using gain, pitch, and pan controls.
595 - <strong>CrossFadeDemo</strong>: Demonstrates crossfading between two sources.
596 - <strong>ChannelsDemo</strong>: Demonstrates using audio channels.
597 - <strong>FadeDemo</strong>: Demonstrates realtime fading with OALAudioTrack and ALSource.
598 - <strong>AudioTrackDemo</strong>: Demonstrates using multiple OALAudioTrack objects.
599 - <strong>HardwareDemo</strong>: Demonstrates hardware monitoring features.
600 - <strong>AudioSessionDemo</strong>: Allows you to play with various audio session settings.
601 - <strong>PlanetKillerDemo</strong>: Demonstrates using OALSimpleAudio in a game setting.
602 
603 
604 
605 <br> <br>
606 \section ios_issues_sec iOS Issues that can impede playback
607 
608 Certain versions of iOS have bugs or quirks, requiring workarounds. ObjectAL tries to handle
609 most of these automatically, but there are cases that require specific handling by the developer.
610 These are:
611
612 <br>
613 \subsection mpmovieplayercontroller_ios3 MPMoviePlayerController on iOS 3.x
614 
615 In iOS 3.x, MPMoviePlayerController doesn't play nice, and takes over the audio session when
616 you play a video. In order to mitigate this, you must manually suspend OpenAL, play the video,
617 and then manually unsuspend once video playback finishes:
618 
619 \code
620- (void) playVideo
621{	
622	if([myMoviePlayer respondsToSelector:@selector(view)])
623	{
624		[myMoviePlayer setFullscreen:YES animated:YES];
625	}
626	else
627	{
628		// No "view" method means we are < 4.0
629		// Manually suspend so iOS 3.x doesn't clobber our session!
630		[OpenALManager sharedInstance].manuallySuspended = YES;
631	}
632
633	[myMoviePlayer play];
634	
635	[[NSNotificationCenter defaultCenter] 
636	 addObserver:self
637	 selector:@selector(movieFinishedCallback:)
638	 name:MPMoviePlayerPlaybackDidFinishNotification
639	 object:myMoviePlayer];
640}
641
642-(void)movieFinishedCallback:(NSNotification *)notification
643{
644	if([myMoviePlayer respondsToSelector:@selector(view)])
645	{
646		if (myMoviePlayer.fullscreen)
647		{
648			[myMoviePlayer setFullscreen:NO animated:YES];
649		}
650	}
651	else
652	{
653		// No "view" method means we are < 4.0
654		// Manually unsuspend
655		[OpenALManager sharedInstance].manuallySuspended = NO;
656	}
657}
658 \endcode
659 <br>
660 \subsection mpmusicplayercontroller_ios4_0 MPMusicPlayerController on iOS 4.0
661
662 On iOS 4.0, MPMusicPlayerController sends an interrupt when it begins playback, but doesn't send
663 a corresponding "end interrupt" when it ends. To work around this, force an "end interrupt"
664 after starting playback:
665 \code
666	[[OALAudioSession sharedInstance] forceEndInterruption];
667 \endcode
668
669 
670 
671 <br> <br>
672 \section simulator_issues_sec Simulator Issues
673 
674 As you've likely heard time and time again, the simulator is no substitute for the real thing.
675 The simulator is buggy. It can run faster or slower than a real device. It fails system calls
676 that a real device doesn't. It shows graphics glitches that a real device doesn't. Sounds stop
677 working, clicks and static, dogs and cats living together, etc, etc.
678 When things look wrong, try it on a real device before bugging people.
679 
680 
681 <br>
682 \subsection simulator_limitations Simulator Limitations
683 
684 The simulator does not support setting audio modes, so setting allowIpod or honorSilentSwitch
685 in OALAudioSession will have no effect in the simulator.
686 
687 
688 <br>
689 \subsection simulator_errors Error Codes on the Simulator
690 
691 From time to time, the simulator can get confused, and start spitting out spurious errors.
692 When this happens, check on a real device to make sure it's not just a simulator issue.
693 Usually quitting and restarting the simulator will fix it, but sometimes you may have to reboot
694 your machine as well.
695 
696 
697 <br>
698 \subsection simulator_playback Playback Issues
699 
700 The simulator is notoriously finicky when it comes to audio playback. Any number of programs
701 you've installed on your mac can cause the simulator to stop playing bg music, or effects, or
702 both!
703 
704 Some things to check when sound stops working:
705 - Try resetting and restarting the simulator.
706 - Try restarting XCode, cleaning, and recompiling your project.
707 - Try rebooting your computer.
708 - Open "Audio MIDI Setup" (type "midi" into spotlight to find it) and make sure "Built-in Output"
709 is set to 44100.0 Hz.
710 - Go to System Preferences -> Sound -> Output, and ensure that "Play sound effects through" is set
711   to "Internal Speakers"
712 - Go to System Preferences -> Sound -> Input, and ensure that it is using internal sound devices.
713 - Go to System Preferences -> Sound -> Sound Effects, and ensure "Play user interface sound
714   effects" is checked.
715 - Some codecs may cause problems with sound playback. Try removing them.
716 - Programs that redirect audio can wreak havoc on the simulator. Try removing them.
717 
718*/