My iPhone application requires that I know when a user has/has not plugged in her headphones. That's easy. AudioSessionAddPropertyListener with a callback listening to kAudioSessionProperty_AudioRouteChange.
I write logs with NSLog as things happen. User plugs the headphones in? Get a notification, and a line in the gdb console. User unplugs the headphones? Ditto.
At the same time I'm sensing the noise level of the environment by starting a recording audio queue. This, too, works great: I can get the mic noise level and listen for audio route changes just fine.
What I find is that after an interruption, and I've reactivated the audio session and restored the audio category to kAudioSessionCategory_RecordAudio, the audio route notifications go a bit haywire.
When I plug in the headphones, I see no notification. When I unplug the headphones I see BOTH the "plugged in" notification AND the "unplugged" notification, in rapid succession.
It's like the "plugged in" notification's delayed and, when the "unplugged" notification arrives, the queue of pending notifications is flushed.
What am I doing wrong? How do I correctly restore the audio session to get timeous notifications?
EDIT: iPhone OS 3.1.2, running on an iPhone 3G. I'm running a program compiled with the 3.0 SDK (from within XCode 3.1.2).
I have the same problem, but more information, and thus questions for you.
Are you using OpenAL for sound like me.
Do you also support iPod music like me.
I get headphone disconnects in quartz menu screens fine, but in the glView game screen it mostly fails like you. Sometimes the first disconnect works, then failure. Sometime the reconnect also fails to fire, so when I switch to quartz screen I get a que of a half dozen disconnect dialogs I have to click on. This is with OpenAL sound.
With iPod music I switch to a NSNotificationCenter MPMusicPlayerControllerPlaybackStateDidChangeNotification notification and that works, but only while the iPod music is playing.
OS 3.1.3 with a build to OS 3.1.0 on iPhone and iTouch.
Look at your return error code from AudioSessionInitialize(), that was my problem, it was not being called first, and failed.
EDIT: Fix failed, it is an intermittent/random issue, seemingly caused by high CPU load.
Related
I am working on app in which audio file playing very vital role.
for playing audio file I am using AVaudioPlayer in my app.
but one problem is suppose device is in silent mode and user starts running the app
and suppose he/she turns on silent/ring switch in the middle of the app.
right now he/she must exit the game but I want such kind of functionality in
which He/she should not exit the app and in the middle of the app user should be
able to hear the sound when he turns on the ring/silent switch from the device.
iOS apps have the ability to play music in the background whether they be games or not, since multitasking was introduced in iOS.
See the following tutorial.
http://mobile.tutsplus.com/tutorials/iphone/ios-sdk_background-audio/
Whether its legit for a game to do this I seriously question. But thats your call.
I have read many posts and still i cannot achieve the desired functionality while my application is suspended in the background.
My reference point is this radio alarm application.
The things i cannot do using local notifications (which are successfully implemented in the radio clock above) are:
play alarm sound in the background while phone is muted
change phone volume.
play mp3 songs.
Also i noticed that they are able to play sounds longer than 30 seconds and even radio as alarm sounds which probably means that local notifications are not being used (audio-wise)
any insight would be appriciated...
The reason that this Radio App succeeds in playing a long audio file , is that it actually plays a background silent loop audio while waiting for the alarm .
IMO that's the reason people complain it drains the battery.
Is it possible to still play sound / music even if audio has been interrupted, or more precisely: even if MyInterruptionListener got called from the OS with the interruption state kAudioSessionBeginInterruption ?
Yeah I know that's not good idea to do. But want to know anyways.
By the time you get an interrupt message, the audio resources you've been using have been shut down.
For AVAudioPlayer, playback will be stopped until you start it again.
For OpenAL, your context will be invalid. All OpenAL commands will fail with an error until you clear the current context and set it to current again.
For Audio Units, your graph will be in an invalid state. No sound will be played until you set the graph inactive and then active.
I don't know what would happen if you tried to start your audio resources again upon getting an interrupt start message, but at the very least you'd get rejected in the app store if the reviewers ever discovered this behavior.
I would like to stop my application playing a sound if the user has switched the iPhone to silent mode. Where can I read that the phone is in silent mode? Is there some flag I can query? I noticed that some applications ignore the silent mode and some not, while I would have expected all apps to respect that silent is silent !!
Any hints or input would be greatly appreciated.
Thanks
Al
The Human Interface Guidelines published by Apple describes what is the ideal behavior for Apps to follow for Ring/Silent switch. So you may not need to disable audio if the user explicitly played that audio clip despite on silent mode.
The Ring/Silent Switch—What Users Expect
Users use the Ring/Silent switch to silence their devices when they want to:
Avoid being interrupted by unexpected
sounds, such as Phone ringtones and
incoming message sounds.
Avoid hearing sounds that are the
byproducts of user actions, such as
keyboard or other feedback sounds,
incidental sounds, or application
startup sounds.
Avoid hearing game sounds, including
incidental sounds and soundtracks,
that are not essential to using the
game.
For example, in a theater users switch their devices to silent to avoid bothering other people in the theater. In this situation, users still want to be able to use applications on their devices, but they don’t want to be surprised by sounds they don’t expect or explicitly request, such as ringtones or new message sounds.
However, the Ring/Silent switch does not silence sounds that result from user actions that are solely and explicitly intended to produce sound. For example:
Media playback in a media-only
application is not silenced by the
Ring/Silent switch because the media
playback was explicitly requested by
the user.
A Clock alarm is not silenced by the
Ring/Silent switch because the alarm
was explicitly set by the user.
A sound clip in a language-learning
application is not silenced by the
Ring/Silent switch because the user
took explicit action to hear it.
Conversation in an audio chat
application is not silenced by the
Ring/Silent switch because the user
started such an application for the
sole purpose of having an audio chat.
This behavior follows the principle of user control because it is up to the user, not the device, to decide whether it's appropriate to hear sounds the user explicitly requests.
You need to set the appropriate Audio Session Category.
You tell iPhone OS your application’s
audio intentions by designating a
category for your audio session.
For more detail see - Configuring the Audio Session
If the iPhone is silent, why stop playing a sound?
Or, does silent mode just not play certain sounds? I don't have an iPhone (iPod Touch) so I'm not sure.
I've tried looking through the documentation, but I can't seem to find (or recognize) what I'm looking for.
The iPhone and iPod Touch have a momentary switch on the headphones, which I believe is called the "remote" (please correct me if I'm wrong). It is used to start/stop/forward/back for music or to pickup/end a phone call. I'd like to know when this switch is clicked in my native application.
In which framework and classes would I find this?
I don't believe this functionality is supported by any current framework.
If your application has iPod playback during execution you could register for MPMusicPlayerController notifications - Music Player Notifications
This will notify you of the playback state changes you mention above. However, it will not tell you whether the state was changed via the remote or the UI. But it's the only way that I know of to 'guess' if the remote button was clicked - I use this method in one of my own apps.