I'm developing a game that includes an audio multitrack player running in the background. When dealing with pausing all tracks and then resuming when the pause button is pressed, I've found no significant difficulty:
class AudioMultiTrack {
var tracks : [AudioTrack]
var mixer : AVAudioMixerNode
var pauseTime : AVAudioTime?
var engine = AVAudioEngine()
var volumes = [Float]()
init(audioTracks: [AudioTrack]){
tracks = audioTracks
mixer = engine.mainMixerNode
}
func initialize() {
for track in tracks {
track.setUpTrack()
engine.attach(track.audioPlayer)
engine.connect(track.audioPlayer, to: mixer, format: track.format)
track.scheduleFile()
}
do {
try engine.start()
} catch {
fatalError("error starting engine")
}
}
func play() {
for track in tracks {
track.audioPlayer.play(at: startTime())
}
}
func pause() {
pauseTime = tracks[0].audioPlayer.lastRenderTime
for track in tracks {
track.audioPlayer.pause()
}
}
func unPause() {
for track in tracks {
track.scheduleFile()
track.audioPlayer.play(at: pauseTime)
}
}
func stop() {
pauseTime = tracks[0].audioPlayer.lastRenderTime
engine.stop()
for track in tracks {
engine.detach(track.audioPlayer)
}
engine.reset()
}
func startTime() ->AVAudioTime {
let sampleRate = tracks[0].format.sampleRate
let sampleTime = AVAudioFramePosition(sampleRate)
return AVAudioTime(sampleTime: sampleTime, atRate: sampleRate)
}
When pause is pressed in the GameViewController:
func pausePressed() {
audio.pause()
}
func continuePressed() {
audio.unPause()
}
However, when dealing with interruptions or route changes in this manner:
func handleInterruption(notification: NSNotification) {
guard let info = notification.userInfo else { return }
switch info[AVAudioSessionInterruptionTypeKey] as! Int {
case 0:
audio.unPause()
case 1:
audio.pause()
default:
break;
}
}
The program crashes and I receive:
*** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: _engine->IsRunning()'
So it looks like the audio engine is stopping, and I don't want to re-initalize the audio player for a number of reasons including setup time and continuity of game play...
I am correct in my assessment of the problem? If so, how can I keep the audio engine running through an interruption or route change?