Make App Pie

Training for Developers and Artists

Ducking Sound in AVAudioSession

title shot

Ducking has nothing to do with waterfowl. Sometimes you’ll want to add sound to your app, but the user will be using the music or others app along with your app.  For that, you’ll want to slightly lower the volume of the background music so you can put your sounds in the foreground. That;’s ducking, and Its not very hard to do.  

 Download the exercise file which is Speech synthesizer app from an earlier tip.  I’m running this on my iPad mini , but before I do, I’ll start a bit of music.  Now run the app.  Tap the button on the app, and the music disappears. Stop the app. 

There’s a class called AVAudioSession which controls the audio output. While part of AVFoundation, it has a default setting without AVFoundation which plays only one channel of sound. To combine channels, you have to configure the current AVAudioSession to do so. Usually, you’ll do this once in the AppDelegate. Head over there and add AVFoundation

import AVFoundation

In didFinishLaunchingWithOptions, make an identifier for AVAudioSession’s singleton sharedInstance.

let session = AVAudioSession.sharedInstance()

AVAudioSession has a category property. You set the property with a setCategory method, which throws errors, So set up a do…try…catch

} catch {
    print ("Unable to set audio category")

After the try, add the setCategory method. For the category, use a AVAudioSession.Category.playback

try session.setCategory(AVAudioSession.Category.playback 

The second parameter is mode. I’ll set this to default.

try session.setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.default, 

The with is an array of options. I’ll add two options. The first is a bit redundant, but doesn’t hurt to add. mixWiithOthers assures that the foreground and background channels mix. Alone you’ll have them at the same volume.  The second one duckOthers,  softens the background sound` a bit.

try session.setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.default, options: [.mixWithOthers,.duckOthers])

Our last step is to activate the session directly under the setCategory. Setting the category supposedly activates it, but in some circumstances, it won’t. If you need it, it’s here, but I’ll comment it out this time.

//try session.setActive(true, options: [])

        Build and run the project.  I’ll start the music again, and then I’ll start the speech synthesizer. The music ducks under the speech synthesizer.

You can use this in a lot of places where you want your sound effects and you’re user might want their own music or media. 

The Whole Code

Here’s the code in the app delegate for ducking. See the GitHub download for the ducking and speech synthesizer.

//  AppDelegate.swift
//  SpeechSynthesizer
//  An exercise file for iOS Development Tips Weekly
//  by Steven Lipton (C)2018, All rights reserved
//  For videos go to
//  For code go to

import UIKit
import AVFoundation
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        let session = AVAudioSession.sharedInstance()
        do {
            try session.setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.default, options: [.mixWithOthers,.duckOthers])
            //try session.setActive(true, options: [])
        } catch {
            print ("Unable to set audio category")
        return true

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: