Search code examples
iosswiftswiftuiavfoundationavaudioplayer

How to fix lags and "Exception caught in AudioQueueInternalNotifyRunning - error -66671" when playing sound on iPadOS device?


I tried to fix this issue with a non-local variable, but I still have the same error and the interface (SwiftUI) is lagging. Here is my SoundManager file:

import Foundation
import AVFoundation

class SoundService {
    static let shared = SoundService()
    private var soundEffect: AVAudioPlayer?
    
    public func tockSound() {
        let path = Bundle.main.path(forResource: "tock.mp3", ofType:nil)!
        playSound(path: path)
    }
    
    // other sounds...
    
    private func playSound(path: String) {
        let url = URL(fileURLWithPath: path)
        do {
            soundEffect = try AVAudioPlayer(contentsOf: url)
            print("[SoundService] Play sound")
            soundEffect?.play()
        } catch {
            print("[SoundService] Could not load file \(error.localizedDescription)")
        }
    }
}

Here is the code I use in the interface to play the sound:

SoundService.shared.tockSound()

Solution

  • I could fix this issue with a local variable that inserts a timer - so there is a very short gap between new sounds. Time_Control is a module for pausing code I found here on StackOverflow.

    private var control: Time_Control = Time_Control(0)
    
    private func playSound(path: String) {
        
        // Plays sound only if sounds are activated in app settings
        if serviceActivated {
            let url = URL(fileURLWithPath: path)
            do {
                
                // start an async timer so the maximum is 10 sound effects per second (= 0.1 seconds)
                if control.can_send {
                    control = Time_Control(0.1)
                    control.start()
                    soundEffect = try AVAudioPlayer(contentsOf: url)
                    print("[SoundService] Play sound")
                    //            soundEffect?.currentTime = 0
                    soundEffect?.play()
                }
                
            } catch {
                print("[SoundService] Could not load file \(error.localizedDescription)")
            }
        }
    }