bmueller
bmueller

Reputation: 2701

AVAudioPlayer makes click/pop noise when song is started/stopped

I'm using AVAudioPlayer to play a music file. When I call start or stop, there's an audible "click" or "pop" noise. I've tried it with both mp3 and caf files, and hear it in both cases (though I don't hear it every single time). Does anyone know how to prevent these glitchy noises?

Upvotes: 2

Views: 2181

Answers (4)

backslash-f
backslash-f

Reputation: 8193

The only thing that fixed the audio issue on my side (iPhone XS/XR, iOS 13), was to use AVQueuePlayer instead of AVAudioPlayer:

func play() {
    guard let url = Bundle.main.url(forResource: "Sound", withExtension: "wav") else {
        return
    }
    let player = AVQueuePlayer(url: url) // It was AVAudioPlayer before 👈🏻
    player.volume = 1.0
    player.play()
}

Don't ask me why that works, but it does. AVAudioPlayer produces click/pop noises in our XS/XR devices. ¯_(ツ)_/¯

Upvotes: 1

CHIEN-MING LEE
CHIEN-MING LEE

Reputation: 23

The following tip is to just work on stop audio playing.

When we need to call stop to stop the audio playback, we can call pause first and followed by stop. That means in our custom stop method, we use pause and stop from AVAudioPlayer to stop the playback and also prevent the pop or the click noise.

Upvotes: 2

Dave Levy
Dave Levy

Reputation: 1192

I ended up using Swift's fade in function. I did not notice a pop on the stop, but I am pretty certain you could something similar to fix that too. Here is an example of how I implemented it. Note, in my viewDidLoad I am also initializing some audio settings. You may have to experiment with the fade timing to perfect your audio.

   import UIKit
    import AVKit

    var audioPlayer = AVAudioPlayer()

   override func viewDidLoad() {
        super.viewDidLoad()

        initializeAudioPlayer()
    }

func initializeAudioPlayer() {
    do {
        try session.setCategory(AVAudioSessionCategoryPlayback)
        try session.setActive(true)
    } catch {
        print(error)
    }
}


func soundButtonTapped() {

        let tuneURL:URL = Bundle.main.url(forResource: "left", withExtension: "wav")!
        playSound(tuneURL, withDelay: 0.1)
}




func playSound(_ tuneURL: URL, withDelay delay:Double) {

    do {

        audioPlayer = try AVAudioPlayer(contentsOf: tuneURL, fileTypeHint: AVFileTypeMPEGLayer3) //old version of Swift AVFileType.mp3.rawValue
        audioPlayer = try AVAudioPlayer(contentsOf: tuneURL, fileTypeHint: AVFileTypeMPEG4)
        audioPlayer = try AVAudioPlayer(contentsOf: tuneURL, fileTypeHint: AVFileTypeWAVE)

        audioPlayer.volume = 0.0 //start it at zero
        audioPlayer.numberOfLoops = -1  //loop on
        audioPlayer.prepareToPlay()
        audioPlayer.play()
        audioPlayer.setVolume(1, fadeDuration: delay) //fade in with delay

    } catch let error as NSError {
        NSLog(error.description)
    }
}

Upvotes: 0

bmueller
bmueller

Reputation: 2701

For anyone who happens upon this in the future, you have to turn the AVAudioPlayer's volume down to 0, then call stop ~0.5s later.

Upvotes: 4

Related Questions