基于 oss 框架的音频驱动
基于 oss 框架完成系统平台音频驱动的适配。
oss 框架可被多个平台应用,因此 oss 提供 OS 目录来存放平台文件(比如:linux.c),该文件主要提供平台对 oss 框架封装后的相关接口。
以 Linux 为例,入口接口为:
调用 oss 框架通用初始接口 oss_commit_init 。
初始工作完成后,便可注册音频驱动,oss 框架中提供 drv 目录来存放驱动文件。
oss 框架中驱动涉及:
- mixer(混频器),提供的接口为 oss_install_mixer,创建设备文件并提供文件操作集合 mixer_cdev_drv。
- audio dev (音频设备),提供的接口为 oss_install_audio,创建设备文件并提供文件操作集合 audio_cdev_drv。
- 创建虚拟混频器 vmix_mixer,实现混音功能。
驱动主要对上述中 mixer,audio dev 的操作进行实现,对应的操作结构为 _mixer_driver_t 和 audiodrv_t。
oss 框架提供了命令模式来操作音频设备,比如:
录音操作, oss_record 命令,该命令接口为 ossrecord_main():
-
解析命令参数,oss 框架提供 dspdev_t 结构体与全局变量这两种形式对命令参数进行记录。
比如:参数 结构体/全局变量 -v -d <设备文件名 dsp->name> -s <速率 force_speed> -c <通道 force_channels> -t <时间 datalimit> -
录音操作,置只读标记(dsp->flags),调用 open_device 接口,传参为 dspdev_t 结构。打开设备以文件形式来执行,入口为 Linux.c 提供的 open 接口。
Linux 提供了统一的创建字符设备接口,该接口为所有设备绑定统一的文件操作集合。
注意,音频设备又包含 mixer,audio dev 等不同的硬件组件,因此 oss 框架为不同的硬件组件提供了对应的操作。因此,文件操作实际是对这些操作的封装。比如:Linux 的 open 实际执行的操作是 oss_audio_open_devfile 接口。
-
oss_audio_open_devfile 接口根据设备编号在全局数组 audio_devfiles 中获取 adev_t 结构,audio_devfiles 为全局数组,创建 audio dev 过程中会被应用。若 adev_t 结构不为空,则调用 oss_audio_open_engine 接口。
-
oss_audio_open_engine 接口根据设备编号在全局数组 audio_engine 获取 adev_t 结构,audio_engine 数组与 audi_devfiles 数组作用相同。随后,调用驱动自定义 open 接口。以 usb audio 为例,此时会对 usb 进行初始化,比如:缓存,urb 等。同时,oss 框架会对 adev_t 结构进行初始化。
此时,设备已打开且完成必要的初始化操作。
- 调用 encode_sound 接口开始录音及编码,编码工作由 oss 框架自行完成。上述过程中,并未对音频设备的格式,通道,采样率等进行配置,因此,调用 setup_device() 接口,判断格式,速率,通道匹配是否与命令参数一致,若不一致,则关闭设备并重新打开。随后,通过 ioctl 接口重新设置设备的通道等信息。
若需要对录音进行保存,则 oss 框架会创建录音文件,并写入文件头部信息以及录音数据,文件头部信息主要说明音频文件的格式,采样频率等信息。
- record 接口完成录音操作,在 while(1) 循环中完成录音工作,申请一段内存空间,将读取的数据保存到该空间, 文件操作接口为 read。
read 接口的操作流程与 open 类似,linux.c 自定义 read 接口。
随后依次执行 oss_audio_read --> prepare_input --> launch_input
| |
| |
adrv_prepare_for_input adrv_start_input --> adrv_trigger (注:操作由驱动来完成具体的实现)
- 完成录音文件。
oss 框架提供 ossplay_main() 接口进行播放操作,过程简析(大致与录音过程类似):
- 解析播放命令参数。(-d,将设备名赋值给 dsp->name)。
- 标记只写标志,dsp->flag = O_WRONLY;
- open_device() 打开设备。调用顺序与录音相同,依次为 lib_open --> oss_open --> oss_audio_open_devfile --> oss_aduio_open_engine --> usbaudio_open
- play_file() 读取音频文件,并解析文件头,根据文件头类型选择对应的操作。
- play_iff() --> decode_sound() 播放音频文件。
- 申请内存空间,读取音频文件,将数据写入该空间中,调用 write 接口开始将数据写入设备。与录音相同,创建 uio 结构,调用 oss_audio_write()。
- 获取音频设备 audio_dev,查找其拥有 dmap_out 地址空间,将数据写入该控件,随后调用 launch_output()。
- 触发输出标记,开始将 dmap 空间中的数据进行输出。
调用 open 打开设备阶段,oss 框架为每一个音频设备创建内存空间,由 dmap_p 结构进行相关的描述,实际类型为 _dmap_t。
因此,oss 框架中,核心结构体为 _adev_t 结构,用于对设备进行描述,后期的初始,读,写等操作都是通过 _adev_t 结构来完成。
驱动主要对 _adev_t 结构进行填充,主要为驱动操作集合,使用的端口。
驱动集合结构为 audiodrv_t 和 _mixer_driver_t。端口由驱动根据硬件设备构建,同时由 _adev_t 指向。
设备打开时,驱动主要自行对端口进行设置。以 USB 为例,驱动主要为设备关联 usb 设备端点,同时创建通信管道(即 urb)。触发设备时,查看当前端口触发条件,随后通过端口的 usb 端点设备进行数据的发送或接收。
相关文章:
基于 oss 框架的音频驱动
基于 oss 框架完成系统平台音频驱动的适配。 oss 框架可被多个平台应用,因此 oss 提供 OS 目录来存放平台文件(比如:linux.c),该文件主要提供平台对 oss 框架封装后的相关接口。 以 Linux 为例,入口接口为…...
【golang】如何定制化zap日志库以及如何使用
Zap 日志 前言 本文主要介绍Go语言日志库如何简易定制化,以及如何在开发中使用。 为什么需要日志? 一个产品的诞生一定是因为有需求!新技术大部分都是为了更加便利和实用而诞生的,日志也不例外。日志顾名思义就是对整个项目的事件进行记…...
如何将 Ubuntu 升级到 22.04 LTS Jammy Jellyfish
在本教程中,我们将详细介绍如何将你的 Ubuntu 系统升级到版本 22.04 Jammy Jellyfish,这是最新的长期支持版本。 Ubuntu 22.04 LTS Jammy Jellyfish 将于 2022 年 4 月 21 日发布。它是下个两年一次的长期支持(LTS)版本,因此值得注意,而且现在 Ubuntu 21.10 的用户可以升…...
ubuntu20.04安装docker与docker-compose
安装docker 查看系统发行版本 cat /proc/version1、更新apt包 sudo apt-get update2、安装必备的软件包以允许apt通过 HTTPS 使用存储库(repository): sudo apt-get install ca-certificates curl gnupg lsb-release3、添加Docker官方版本…...
笔试题-2023-加特兰-数字IC设计【纯净题目版】
回到首页:2023 数字IC设计秋招复盘——数十家公司笔试题、面试实录 推荐内容:数字IC设计学习比较实用的资料推荐 题目背景 笔试时间:2022.07.27应聘岗位:数字电路设计工程师(SoC) - 2023届笔试时长:90min笔试平台:nowcoder牛客网题目类型:问答题(11道)主观评价 难易…...
动态内存管理
目录1.为什么要动态内存分配2.动态内存函数malloc](https://cplusplus.com/reference/cstdlib/malloc/?kwmalloc)和[freecallocrealloc3.使用动态内存要注意的几点对NULL的解引用对同一块动态内存多次释放free非动态开辟的内存使用free释放一块动态开辟内存的一部分一个函数中…...
Unsupervised Question Answering 简单综述
Unsupervised Question Answering by Cloze Translation, ACL 2019 随机从文本中抽取noun phrases或者named entity作为答案将答案部分mask掉,生成cloze question利用无监督翻译,将cloze question转化为natural question 缺点: 直接利用原句…...
智慧物流管理系统
智慧物流运用物联网、大数据、云计算、人工智能等技术优化物流决策过程。智慧物流获取、分析物流信息并做出决策,从商品源开始实时跟踪与管理,保证信息流快于商品流,实现信息与物质快速、高效、流畅地运转,集自动化、数字化、网络…...
单表查询--实例
#素材: 表名:worker-- 表中字段均为中文,比如 部门号 工资 职工号 参加工作 等 >CREATE TABLE worker ( >部门号 int(11) NOT NULL, >职工号 int(11) NOT NULL, >工作时间 date NOT NULL, >工资 float(8,2) NOT NULL, >政治…...
c语言递归 累和 ,累乘积,斐波那契数列,字符串长度
目录 递归使用场景 1:使用递归的方式计算 Sn123..100 2:计算 n!n*(n-1)*(n-2)*......*1; 3:计算输出斐波那契数列前20项,并按每行4个数的格式输出(2019年) 4: 用递归和非递归两种方式编写函数strlength()。该函数…...
数据与C(ASCII码,char)
目录 一.ASCII码讲解 二.非打印字符(转义字符) 三.扩展小知识 一.ASCII码讲解 char类型用于存储字符,从技术层面看,char时整数类型,因为char类型实际上存储的是整数而不是字符。计算机使用数字编码来处理字符&…...
第一个C语言代码(visual studin创建调试以及项目文件功能讲解)
这里我主要使用visual Studio进行编程 目录 一.创建项目 二.编写代码 1.代码编写 2.代码分析 3.main() 4.注释符 5.{} 花括号 6.声明 7.赋值 8.printf()函数 9.return 0; 一.创建项目 这里大家可能会比较疑惑,为啥都是C,没看见C的项目&…...
VIF原理
文章目录一、VIF公式和原理对于R方一般回归模型皮尔逊相关系数中的方差VIF原理:一、VIF公式和原理 所谓VIF方法,计算难度并不高。在线性回归方法里,应用最广泛的就是最小二乘法(OLS),只不过我们对每个因子…...
nginx相关反爬策略总结笔记
引言 互联网站点的流量一部分由人类正常访问行为产生,而高达30%-60%的流量则是由网络爬虫产生的,其中一部分包含友好网络爬虫,如搜索引擎的爬虫、广告程序、第三方合作伙伴程序、Robots协议友好程序等;而并非所有的网络爬虫都是友好的&#x…...
【Vue3】电商网站吸顶功能
头部分类导航-吸顶功能 电商网站的首页内容会比较多,页面比较长,为了能让用户在滚动浏览内容的过程中都能够快速的切换到其它分类。需要分类导航一直可见,所以需要一个吸顶导航的效果。 目标:完成头部组件吸顶效果的实现 交互要求 滚动距离大…...
HOMER docker版本安装详细流程
概述 HOMER是一款100%开源的针对SIP/VOIP/RTC的抓包工具和监控工具。 HOMER是一款强大的、运营商级、可扩展的数据包和事件捕获系统,是基于HEP/EEP协议的VoIP/RTC监控应用程序,并可以使用即时搜索、处理和存储大量的信令、RTC事件、日志和统计信息。 …...
【数据结构】单向链表的练习题
目录 前言 1、删除链表中等于给定值val的所有节点。 【题目描述】 【代码示例】 【 画图理解】 2、反转一个点链表 【题目描述】 【 代码思路】 【代码示例】 【画图理解】 3、给定一个带有头节点head的非空单链表,返回链表的中间节点,如果有两个…...
我的企业需要一个网站吗?答案是肯定的 10 个理由
如果您的企业在没有网站的情况下走到了这一步,您可能会想:我的企业需要一个网站吗?如果我的企业没有一个就已经成功了,那又有什么意义呢?简短的回答是,现在是为您的企业投资网站的最佳或更重要的时机。网站…...
CHI协议定义的NOC组件
请求结点RN 可以向NOC发送读/写等请求事务,有以下几种类型的RN: RN-F 一般是处理器核或者核簇结点,包含了局部cache和一致性部件snoopee。与NOC上的一致性部件一起,维护“可缓存”数据的一致性(这种可缓存数据…...
Python+Flask+MySQL开发的在线外卖订餐系统(附源码)
文章目录一、项目模块及功能介绍1、登录模块2、注册模块3、商家用户模块4、买家用户模块5、系统管理员模块源码二、项目结构三、环境依赖四、运行方法五、系统部分界面展示1、首页2、注册界面3、登录界面4、商家主界面5、商家菜单界面6、商家添加菜品界面7、商家修改菜品界面8、…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
认识CMake并使用CMake构建自己的第一个项目
1.CMake的作用和优势 跨平台支持:CMake支持多种操作系统和编译器,使用同一份构建配置可以在不同的环境中使用 简化配置:通过CMakeLists.txt文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本…...
jdbc查询mysql数据库时,出现id顺序错误的情况
我在repository中的查询语句如下所示,即传入一个List<intager>的数据,返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致,会导致返回的id是从小到大排列的,但我不希望这样。 Query("SELECT NEW com…...
生产管理系统开发:专业软件开发公司的实践与思考
生产管理系统开发的关键点 在当前制造业智能化升级的转型背景下,生产管理系统开发正逐步成为企业优化生产流程的重要技术手段。不同行业、不同规模的企业在推进生产管理数字化转型过程中,面临的挑战存在显著差异。本文结合具体实践案例,分析…...
大模型智能体核心技术:CoT与ReAct深度解析
**导读:**在当今AI技术快速发展的背景下,大模型的推理能力和可解释性成为业界关注的焦点。本文深入解析了两项核心技术:CoT(思维链)和ReAct(推理与行动),这两种方法正在重新定义大模…...
链结构与工作量证明7️⃣:用 Go 实现比特币的核心机制
链结构与工作量证明:用 Go 实现比特币的核心机制 如果你用 Go 写过区块、算过哈希,也大致理解了非对称加密、数据序列化这些“硬核知识”,那么恭喜你,现在我们终于可以把这些拼成一条完整的“区块链”。 不过别急,这一节我们重点搞懂两件事: 区块之间是怎么连接成“链”…...
JVM——对象模型:JVM对象的内部机制和存在方式是怎样的?
引入 在Java的编程宇宙中,“Everything is object”是最核心的哲学纲领。当我们写下new Book()这样简单的代码时,JVM正在幕后构建一个复杂而精妙的“数据实体”——对象。这个看似普通的对象,实则是JVM内存管理、类型系统和多态机制的基石。…...
Ansys Maxwell:线圈和磁体的静磁 3D 分析
本博客展示了如何在 Ansys Maxwell 中执行静磁 3D 分析,以计算载流线圈和永磁体之间相互作用产生的扭矩。在这个例子中,线圈中的电流产生一个沿 Y 轴指向的磁场,而永磁体沿 X 轴被磁化。这种配置导致围绕 Z 轴的扭矩。分步工作流程包括构建几…...
《开篇:课程目录》
大家好!我是一名.NET技术开发者,长期以来积累了比较多的项目实战经验,现在把它分享给大家,希望能够帮助到大家,同时为.NET社区提供一份力量,让更多的开发者参与进来。 要讲解的课程如下: 《介绍…...
