Audio stops when device suspends

Hello,

The sounds and music of my app stop when iPad suspends then resumes. I have 2 AudioSources, one looping compressed background music, the other one playing uncompressed sounds. When I resume, music + sounds stop. After a while, music resumes (when looping). If I load another scene everything goes back to normal.

Sometimes when I resume I can hear a short piece (~300ms) of the music that was playing before suspending, then it stops.

There is no error on the console (only the → applicationDidResignActive() → applicationDidBecomeActive()).

I tried to enable / disable the hardware decoding on the background audioclip, but that did not change anything.

Running on Unity 3 pro + iPhone advanced, device is iPad running iOS 3.2.2.

Any idea ?

Thanks

Camille

Sounds similar to what I recently posted - I submitted a bug report as I was getting an audio error in the xcode console on resuming.

same her! And I thought it was my mistake ^^ But I’m not alone BORAY!!

I have the same problem, but for now I’ve bodged the music by starting it again after the app comes out of pause. I also check to see if my player prefs is set to play music at the same time.

function OnApplicationPause(Pause : boolean)
{

	if(!Pause  PlayerPrefs.GetInt("Music") == 0) this.audio.Play();	

}

Hope this helps,

Richard

Thank you Gnimmel ! I did not even know OnApplicationPause was called on iOS.

I had to make this more generic (I have to save the time of the AudioSource because I often play audio tutorials that have to keep in sync with what’s happening on the screen). Here is what I use :

using UnityEngine;
using System.Collections;

public class AudioSourceSuspendHack : MonoBehaviour {
    private class AudioSourceInfo {
        public AudioSource audioSource;
        public float time;
        public bool wasPlaying;
    }
    
    
    private AudioSourceInfo[] sourcesToBeResumed;
    
    #if UNITY_IPHONE
    void OnApplicationPause(bool pause) {
        if (pause) {
            // Application is pausing.
            // Save infos about the audio sources in the scene
            AudioSource[] sources = (AudioSource[]) FindObjectsOfType(typeof(AudioSource));
            if (sources != null  sources.Length > 0) {
                // Create array of sources for resume
                sourcesToBeResumed = new AudioSourceInfo[sources.Length];
                
                for (int i = 0; i < sourcesToBeResumed.Length; i++) {
                    // Store informations about the sources
                    sourcesToBeResumed[i] = new AudioSourceSuspendHack.AudioSourceInfo();
                    sourcesToBeResumed[i].audioSource = sources[i];
                    sourcesToBeResumed[i].time = sources[i].time;
                    
                    // For some reason, sources[i].isPlaying always returns false, even if the source is actually playing.
                    // We have to check the time instead.
                    if (sources[i].time > 0) {
                        sourcesToBeResumed[i].wasPlaying = true;
                    } else {
                        sourcesToBeResumed[i].wasPlaying = false;
                    }                    
                    
                    // Stop the source
                    sources[i].Stop();
                }
            } else {
                sourcesToBeResumed = null;
            }
        } else if (sourcesToBeResumed != null  sourcesToBeResumed.Length > 0) {
            // Application is resuming and there are sources to be resumed.
            // Restore audio source settings.
            
            foreach (AudioSourceInfo ainfo in sourcesToBeResumed) {
                if (ainfo.wasPlaying) {
                    ainfo.audioSource.time = ainfo.time;
                    ainfo.audioSource.Play ();
                }
            }
        }
    }
    #endif
}

This works like a charm for me !

Thanks again

Camille

Here is an update for iOS 4.2 : the script works well when the app goes background / foreground, but does not when suspending the iPad.

I found out that when switching between apps, the correct events are sent to AppController.mm : applicationWillEnterForeground (which tells Unity Audio has to be restored), then applicationDidBecomeActive (which un-pauses Unity).

However, when suspending the iPad, applicationWillEnterForeground is not called by iOS, therefore Unity is never told to restore the audio session. To fix this, I slightly changed the two functions in AppController.mm :

// For iOS 4
// Callback order:
//   applicationWillEnterForeground()
//   applicationDidBecomeActive()
bool bNeedToRestoreIPhoneAudioSession = false;
- (void)applicationWillEnterForeground:(UIApplication *)application
{
    /[B]/bNeedToRestoreIPhoneAudioSession = true;[/B]
    printf_console("-> applicationWillEnterForeground()\n");
}
	
- (void) applicationDidBecomeActive:(UIApplication*)application
{
	[B]bNeedToRestoreIPhoneAudioSession = true;[/B]
	printf_console("-> applicationDidBecomeActive()\n");
	if (_didResignActive)
	{
		UnityPause(false);
	}

	_didResignActive = NO;
}

This seems to work on the device, but I have no idea if it is viable or not.

Has anyone found another solution ?

Thanks,
Camille

Another one here… i have a post about this too but for iPhone return from suspension.