探索iOS之CoreAudio核心音频框架

news2024/11/24 6:44:43

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: ()
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/540411.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

求最小生成树(Prim算法与Kruskal算法与并查集)

目录 1、案例要求2、算法设计与实现2.1 Prim算法2.1.1 构造无向图2.1.2 编写Prim算法函数2.1.3 实现代码2.1.4 运行结果截图 2.2 Kruskal算法2.2.1 构造无向图2.2.2 编写并查集UnionFind类2.2.3 编写Kruskal算法2.2.4 实现代码2.2.5 运行结果截图 3、总结 1、案例要求 利用贪心…

CameraLink 高清医学影像分析模块

FMC-XM202是一款基于FMC接口标准的1路CameraLink Full模式(或者2路CameraLink Base模式)采集、1路HDMI(DVI)视频输出的子卡模块,该模块具有2个CameraLink端口(SDR,26PIN)&#xff0c…

简单线性线性回归

文章目录 brief直线回归的一般形式参数计算y观测值和回归值的关系基本前提假定假设检验直线回归的变异来源自由度问题:假设检验 多元线性回归 brief 当研究两个有因果关系的变量时,我们希望建立一个方程式表示两者的关系,这样有一个变量得知…

公司里的5种人,建议马上开除

作者| Mr.K 编辑| Emma 来源| 技术领导力(ID:jishulingdaoli) 多年前,马云在某期湖畔大学开学演讲时,说了一句经典名言:“小公司的成败在于你聘请什么样的人,大公司的成败在于你开除什么样的人。”K哥觉得&#xff0…

Ocean Optics USB2000光谱仪无法在Win10/8系统运行

1、问题描述 USB2000型光谱仪,由于生产年代过于久远,虽然能被Win10系统识别,但是驱动程序安装完成后依然报错, 提示:该设备无法启动。(代码 10) 请求USB BOS 描述符失败。 运行SpectraSuite软件…

操作系统原理 —— 什么是信号量,信号量如何实现进程互斥、进程同步?(十五)

在之前的章节中,我们提到了进程互斥,以及进程互斥实现的几种方式,那么今天我们再来讲解一种,基于 信号量 来实现进程之间的同步、互斥的方式。 用户进程可以通过使用操作性提供的一对原语来对信号量进行操作,从而很方…

C语言基础知识:C语言中的指针

目录 1、为什么需要指针? 2、指针是什么? 3、指针与变量的关系 4、指针的分类 5、指针的用法 6、指针的运算 7、野指针 8、指针使用时的注意事项 同C语言中其他变量一样,把指针也可以看成是一种变量。不过,这种变量专门存储地址值。…

vscode链接远程服务器开发c++项目

因为要在linux环境下开发c应用,需要一个比较好用的远程工具。之前做深度学习的时候一直用vscode链接服务器写python,感觉用起来很舒服。 vscode下载安装这些就略过了,从插件安装和配置文件开始介绍 参考文章:https://zhuanlan.zh…

如何做一份精致的性能测试报告?

相比于普通的功能测试,性能测试对测试工程师的技能要求更高,一般来说,也只有中高级测试工程师才会有机会做性能测试。 对于题主关心的问题,我拆分出下面三个部分来做解答: 1、性能测试报告的目的 2、性能测试过程中的关…

【算法分析与设计报告】快递终端送货配送系统、基因序列比较、地图染色、文章查重系统、果园篱笆问题(附源码)

一、快递终端送货分配问题 问题描述 假设某快递终端投递站,服务n个小区,小区与快递点之间有道路相连,如下图,边上的权值表示距离。 图1-1 小区快递点图 现在设有m包裹,每个包裹都有自己的目的地及总量。 假设送货员一…

IPB072N15N3G-ASEMI代理英飞凌高压MOS管IPB072N15N3G

编辑:ll IPB072N15N3G-ASEMI代理英飞凌高压MOS管IPB072N15N3G 型号:IPB072N15N3G 品牌:英飞凌 封装:TO-263 最大漏源电流:31A 漏源击穿电压:600V RDS(ON)Max:99mΩ…

第四届“中国法研杯”司法人工智能挑战赛-刑期预测赛道三等奖方案

一、前言 本文将回顾第四届“中国法研杯”司法人工智能挑战赛-刑期预测算法赛道比赛。使用多任务预训练、然后进行微调的形式最终在比赛中取得了三等奖的成绩。 二、任务介绍 主办方在第一届“中国法研杯”比赛上提出了刑期预测任务,本届将针对往届刑期预测准确率…

《终身成长》笔记六——称赞努力的过程,也将其与结果关联

目录 经典摘录 成为好父母好老师 成长型思维模式的真伪 第一种错误理解:很多人将他们身上某些他们喜欢的优点称作“成长型思维模式” 第二种错误理解:很多人认为成长型思维模式只关乎努力,特别是去夸奖别人的努力 第三种错误理解&#xff…

基于树莓派4B的智能家居

基于树莓派4B的智能家居 前言C语言的简单工厂模式工厂模式介绍类和对象工厂模式的优缺点优点缺点 智能家居框架产品工厂卫生间灯设备二楼灯设备餐厅灯设备客厅灯设备泳池灯设备风扇设备锁设备警报器设备地震监测设备火灾监测设备温湿度检测设备 指令工厂语音控制设备server控制…

如何创建样本手册?

第一步:提前研究和规划 首先明确目标客户群体在其中扮演的角色。 谁会穿你的衣服?您品牌的潜在客户是谁?他们的愿望是什么?他们会被什么打动?设置客户角色至关重要,因为它将决定样本手册的基调&#xff0…

Simulink 自动代码生成电机控制:模型仿真速度的优化

目录 方法一 Simulationmode 方法二 多核并行 方法三 Performance Advisor 总结 方法一 Simulationmode 执行下面的指令获取Simulink仿真实时,这里以霍尔FOC的模型为例,在切换模式为Accelerator时不能使用调用子模型的形式,需要把子模型复制…

map的forEach区别

map的forEach区别 先总结下: map和forEach区别是: 1.map有返回值而且必须return返回一个数组才行 ; 而forEach没有返回值可直接打印结果; 即:forEach()方法不会返回执行结果,而是undefined。也就是说,forEa…

vue 在线聊天实战范例(含选择发送表情、图片、视频、音频,自定义右键快捷菜单,一键复制,左右聊天气泡)

最终效果 完整代码 index.vue <template><div class"page"><div class"leftBox"><h1>访客</h1><div class"chatBox"><div class"chatRecordBox"><div v-for"(item, index) in cha…

DBCO-COOH分子量:305.3,CAS:1353016-70-2,二苯基环辛炔-羧基;类似有DBCO-NH2、SH、MAL、NHS等等

中文名称&#xff1a;二苯基环辛炔-羧基 英文名称&#xff1a;DBCO-acid 英文别称&#xff1a;DBCO-COOH cas: 1353016-70-2 分子式&#xff1a;C19H15NO3 分子量&#xff1a;305.3 DBCO-COOH是DBCO 衍生化的常用构件&#xff0c;在EDC、DCC和HATU等活化剂存在下&#xf…

linux kernel menuconfig kconfig makefile

概述 menuconfig是Linux平台用于管理代码工程、模块及功能的实用工具。 menuconfig的使用方式通常是在编译系统之前在系统源代码根目录下执行make menuconfig命令从而打开一个图形化配置界面&#xff0c;再通过对各项的值按需配置从而达到影响系统编译结果的目的。 Nuttx的me…