探索iOS之CoreAudio核心音频框架

iOS的CoreAudio分为三层:应用服务层、驱动层、硬件层。其中,应用服务层包括:AudioQueue Service、AudioPlayer Service、AudioSession Service、AudioFile Service、AudioUnit等。

一、CoreAudio整体架构

CoreAudio的整体架构自顶向下是Service层、Driver层、Hardware层,如下图所示:

 二、Service层级架构

Service层按照等级分层,自顶向下是High-Level、Mid-Level、Low-Level。其中,高级别Service有AVAudioPlayer、AudioQueue、OpenAL等;中级别Service有AudioConverter、AudioFile、AudioUnit等;低级别Service有IOKit、Auido HAL等。如下图所示:

三、 AudioQueue

AudioQueue可用于音频播放、录音。我们不用了解硬件接口,就可以使用硬件录制和播放设备

1、播放

AudioQueue播放的数据源采用回调方式获取,提供缓冲队列,最终输出给扬声器播放。如下图所示:

2、录音

AudioQueue录音的数据源来自麦克风,内部提供缓冲队列,最终回调给业务层。如下图所示:

四、AudioConverter

AudioConverter提供音频格式转换。以mp3转aac为例,输入mp3解码得到pcn,然后pcm编码成aac。转换流程如下图所示:

五、AudioSession

AudioSession用于访问麦克风、扬声器的会话,提供管理音频服务、监听Route变化,如下图所示:

1、配置AudioSession

关于AudioSession的配置,示例代码如下:

let session = AVAudioSession.sharedInstance()
do {
    // Configure the audio session for playback
    try session.setCategory(AVAudioSessionCategoryPlayback,
                            mode: AVAudioSessionModeMoviePlayback,
                            options: [])
    // Activate audio session to enable your custom configuration
    try session.setActive(true)
} catch let error as NSError {
    print("Unable to activate audio session:  \(error.localizedDescription)")
}

2、后台播放

如果要后台播放音乐,或者Airplay投屏、画中画播放,需要把后台模式打开:

3、处理中断

不同session之间会互相中断。比如当前正在播放音乐,有个语音电话打进来,那么就会中断音乐播放,保存状态和上下文。等到通话结束,然后使用状态和上下文恢复音乐播放。示意图如下:

监听中断通知以及处理中断,示例代码如下:

func registerForNotifications() {
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(handleInterruption),
                                           name: .AVAudioSessionInterruption,
                                           object: AVAudioSession.sharedInstance())
}

func handleInterruption(_ notification: Notification) {
    guard let info = notification.userInfo,
        let typeValue = info[AVAudioSessionInterruptionTypeKey] as? UInt,
        let type = AVAudioSessionInterruptionType(rawValue: typeValue) else {
            return
    }
    if type == .began {
        // save state and context
    }
    else if type == .ended {
        guard let optionsValue =
            userInfo[AVAudioSessionInterruptionOptionKey] as? UInt else {
                return
        }
        let options = AVAudioSessionInterruptionOptions(rawValue: optionsValue)
        if options.contains(.shouldResume) {
            // Interruption Ended, resume to playback
        }
    }
}

5、监听Route变化

通知注册AVAudioSessionRouteChangeNotification来监听。以监听连接耳机为例,代码示例如下:

func setupNotification() {
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(handleRouteChange),
                                           name: .AVAudioSessionRouteChange,
                                           object: AVAudioSession.sharedInstance())
}

func handleRouteChange(notification: NSNotification) {
    guard let userInfo = notification.userInfo,
        let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt,
        let reason = AVAudioSessionRouteChangeReason(rawValue:reasonValue) else {
            return
    }
    switch reason {
    case .newDeviceAvailable:
        let session = AVAudioSession.sharedInstance()
        for output in session.currentRoute.outputs where output.portType == AVAudioSessionPortHeadphones {
            // headphone connected
        }
    case .oldDeviceUnavailable:
        if let previousRoute =
            userInfo[AVAudioSessionRouteChangePreviousRouteKey] as? AVAudioSessionRouteDescription {
            for output in previousRoute.outputs where output.portType == AVAudioSessionPortHeadphones {
                // headphone disconnected
            }
        }
    default: ()
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

徐福记456

您的鼓励和肯定是我创作动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值