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