第三篇:知其然,知其所以然-USB音频设备的开发过程
最近,有朋友正好在开发一个USB音频设备,所以询问我一些USB音频设备开发方面的技术细节问题;也和音响发烧友聊到USB音频设备的实现方式与其优缺点;后来,也和人谈到实现一个USB音频设备的难易度.
以前在做USB Dongle PCTV Windows driver的时候,我们所用的到方案是一个USB Composite device,其中的一个Interface就是标准的USB音频输入设备,其驱动程序是微软标准的USB Audio device driver,所以并没有对上层驱动,还是对底层设备实现有一个非常深入的了解.
前阵子,为了验证USB3.0 device IP的ISO IN/OUT功能,所以接手了这个基于自开发的USB IP实现音频设备的项目,从而对设备实现有了进一步的了解.
正好这几周一直在跟踪一个xHCI IP开发过程中,USB Golden tree test时,Win8电源请求超时(Power IRP timeout)导致蓝屏(BSOD)的问题,已经根据DUMP FILE初步定位第四级的SS HUB无法正常进入睡眠,但始终确认不了根本原因,而且要重现这个BUG,往往一天时间都重现不了,于是决定先写一写USB音频设备方面的东西,再回过头去看那个问题,或许能有新的发现.
长话简说,第一,先说一下USB音频设备的硬件系统组成,列表如下:
Audio codec,音频编解码芯片
USB chip or IP,USB device控制芯片
MCU or ARM,CPU用来对Audio codec, USB device controller, DMA进行配置,比起USB Video device项目, CPU需要起到增加12字节的header到数据包前面的作用,音频方面CPU不需要参与.
DMA controller,用来USB ISO in/out EP buffer与Audio coded所使用的Memory间的数据搬运,如果系统中他们使用同一块memory地址,可以省略该DMA.
第二,软件
由于这个项目的根本目的是验证自开发的USB3.0 IP的ISO IN/OUT传输功能,所以,应该首先使用USB General functional driver与上层读写应用程序对ISO传输进行验证.
USB设备这边,需要编写firmware,功能就是接收ISO OUT/BULK OUT数据,通过ISO IN/BULK IN回传给PC,PC对发送与接收的数据进行比较.
其中的组合如下:BULK OUT+ISO IN,用来验证ISO IN, ISO OUT+BULK IN,用来验证ISO OUT, 最后ISO OUT/ISO IN用来验证两者间是否存在IP设计上的冲突问题.
我所走的弯路就是,跳过了这一步,结果在USB IP产生问题的时候,由于无法证明到底是USB IP的问题,还是fimware的问题,而且对USB AUDIO DRIVER控制度也不如自己开发的USB GENERAL FUNCTIONAL DRIVER灵活度高,结果造成时间上的浪费.最终,还是回过头来,实现USB loopback device, 将问题的排查范围缩小直至定位.
这一步对于选择现成USB DEVICE CONTROLLER CHIP的方案,可以跳过.
Windows驱动是现成的,所以,只要USB设备实现上不存在问题,Windows就能枚举,工作.驱动的名称为USBAudio.sys.
设备实现上需要做的工作包括以下几个方面:
WM8753的配置
DMA数据传输的配置
USB音频框架的搭建,包括:
1. 选择一种适合的USB音频设备拓扑结构(后面会再提及相关文档)
2. 编码选定拓扑结构下的USB标准描述符与USB音频设备类描述符
3. 实现USB标准设备请求与USB音频设备类相关请求,这一点也与所选择的拓扑结构关联度很大,简而言之,选择的拓扑结构简单,所需要实现的音频类请求也简单,反之亦然.
4. 实现ISO数据传输. 这一点必须考虑与DMA的同步配合,否则,就会出现数据上溢或者下溢的情况,这将会表现在音效上.
还有就是GraphEdit
在Windows上开发音视频的得力助手,通过Audio renderer与Advanced可以得到许多音频相关的统计数据.
第三,相关的资料:
1. WM8753的用户手册
2. USB DEVICE CONTROLLER CHIP的用户手册,如果有更上一层的API,就能够更加快速地对其编程(Cypress的FX2, FX3提供了这样的API)
3. USB1.1/1.0,2.0,3.0协议
USB2.0与USB1.1/1.0差别并不大,但USB3.0与前者差别非常大,特别表现在Physical,Linker layer与Protocol layer.
不过,如果是只从USB音频设备的实现来讲,只需要将精力花在第九章,如果是USB3.0还应该了解一下第八章.
4. USB audio class协议
主要精力花在第四章与第五章
5. Basic audio device文档
该文档给出对Headphone, Microphone, Headset 各种拓扑结构,描述符的详尽描述.
需要注意的是,如果你想实现的是一个HEADSET USB音频设备,不要尝试STEREO MIC, STEREO HEADPHONE的这种方案,否则就是徙劳.
深层次的原因我不清楚,但是:
第一,该文档中没有给出这种方案,第二,即使你实现了这个方案,Windows也不能正确枚举这样的设备
我想,这就是规定,有了这个规定,USB-IF与MICROSOFT是站在统一战线上的.
笔者就是在这个方面尝试,但浪费了很多时间.
一些细节:
1. 拓扑结构的选择,请根据硬件方案,面对的市场,进行有效的选择.
举例来讲:USB音频拓扑结构的元素包括,MIXER,SELECTOR,FEATURE UNIT,Processing Unit以及Extension Unit.
其中,PROCESSING UNIT又包括了:DOLBY, 3D STEREO, REVERBERATION, CHORUS, DYNAMIC RANGE COMPRESSOR 等类型.
如果硬件上没有相对应的支持,就没有必要将这些纳入到拓扑结构中去.
这也能解释给HIFI发烧友,为什么同样是USB HEADSET,价格从十美元到二百美元不等,因为包括硬件与软件上都需要更多的成本去增加新的FEATURE.
2. 对各类Audio class请求的管理
由于请求是呈现交织状的,软件上最好的管理办法就是链表加链表的办法.
3. 同步问题
USB音频设备同步实现上有三种办法,他们是自适应adaptive,异步async与同步sync.
如果通过反馈方式来进行同步,在实现上无疑增加了很大的复杂度.
增加锁向环又给面向普通大众的产品,带来成本上的提高.
比较简单的办法,可以通过插值与丢数据的办法实现,具体算法实现不属于本文的讨论范围.
4. 一般情况,音频设备都伴随一个USB HID的Interface, 其功能主要包括音量增减,静音控制,如果做得更好,可以包括其它功能.
由于HID设备需要用到USB INTERRUPT传输,同时需要设计REPORT DESCRIPTOR,相关文章网上比较多,可以查阅.
最后谈一下测试:
一个USB设备需要通过USB-IF的认证,需要通过
Electrical, link layer, USB CV, USB INTEROP一系列的测试.USB3.0比USB2.0/1.1/1.0在测试难度上有了明显的增加.
而且这些测试,不光针对USB IP开发商,对于产品开发商同样需要.
如果音频驱动是第三方提供的,还需要对驱动进行WHQL/WHCK测试,得到微软的认证.
以上简要介绍了USB音频设备的开发过程,希望对USB音频开发者有所帮助,也使HIFI发烧友对USB音频设备有一个概念上的基本了解.
第三篇:知其然,知其所以然-USB音频设备的开发过程相关推荐
- 知行合一:知其然知其所以然
知行合一:知其然知其所以然. 一个事情做成了,并不意味着你知道做成这件事背后蕴藏的原理. 只有使用冥思.事上练的方法了,将背后的原理提取出来,才能说做到了执行合一. 这个过程是行对知的精进过程. 转载 ...
- 锁,知其然知其所以然
Taken by iCola 今天,从一个小问题聊起. 假设你账户上原来有100元钱,你用微信支付100元,与此同时你女票用支付宝给你转100元零花钱,你帐户的余额有没有可能变成200元或者0元? ...
- 字符串去掉两端的引号_Python3.7知其然知其所以然-第六章 字符串
在开发过程中,经常会用到字符串来存储字符内容.在其他编程语言中用成对双引号" "声明字符串,用成对单引号' '声明单个字符,而Python没有这种区别,它无论单个或多个字符都用字符 ...
- redis zset转set 反序列化失败_关于Redis中的五种数据结构,要知其然知其所以然...
Redis作为Nosql的代表,想必大家已经再熟悉不过了,除了作为缓存来使用,Redis还提供了其他很多有用的功能,例如可作为消息队列.分布式锁.不隆过滤器.限流等功能使用.今天先来说一说redis作 ...
- bootstraptable获取所有数据_关于Redis中的五种数据结构,要知其然知其所以然
Redis作为Nosql的代表,想必大家已经再熟悉不过了,除了作为缓存来使用,Redis还提供了其他很多有用的功能,例如可作为消息队列.分布式锁.不隆过滤器.限流等功能使用.今天先来说一说redis作 ...
- Android转换位图BUG,知其然不知其所以然
在开发某App的时候,发现了一个很奇怪的bug,前面我也发了关于bitmap的总结,但是这个问题恰恰出在BitmapFactory.decodeFile(pathName)这个函数上,使用这个函数在我 ...
- 算出当前系统后某个月的日期_Python3.7知其然知其所以然-第十八章 日期函数
时光不可追,往事不可回.以往创建的数据,如若没有日期做标识,不堪回首.几乎任何一个产品都会用到日期,如登录日期.创建日期.修改日期等.正因如此,编程语言中,几乎都有内置日期函数. 18.1 当前日期 ...
- Vue2.0源码解析 - 知其然知其所以然之Vue.use
前言 小伙伴们大家好.用过Vue的小伙伴都知道,在我们进行Vue开发时,避免不了会使用一些第三方的库,比如说ElementUI组件库.当我们导入好这些组件库后会执行一个Vue.use函数,然后把导进来 ...
- Pandas数据处理误区要知其然知其所以然
背景 在Python里面处理数据,必然离不开Pandas,但目前网上的文章大部分都是介绍函数怎么使用,至于为什么有时数据处理结果是错误的,并没有深入研究,也可能是由于Pandas的一些BUG,没有人提 ...
- Vue2.0源码解析 - 知其然知其所以然之keep-alive
前言 [一天一个小知识,每天进步一点点]小伙伴们大家好,今天将要给大家分享是Vue中关于组件缓存的一个内置组件 - keep-alive 不知道小伙伴们有没有遇到这样一种情况,在我们的项目开发中,有时 ...
最新文章
- Python控制结构总结
- 举重若轻的人人车移动端数据平台
- Firefox火狐浏览器自用技巧汇总--以备使用--13.5.16
- BugKuCTF WEB 变量1
- 【linux】修改机器时间
- 程序员,请您不要老是熬夜
- logstash的使用教程
- 【python 11】super()
- springcloud 相同服务名_SpringCloud系列之SpringCloud Stream
- java什么时候需要同步_JAVA中线程在什么时候需要同步和互斥
- 「数据分析」Sqlserver中的窗口函数的精彩应用-问题篇
- “12306”是如何支撑百万QPS的?
- java B2B2C Springboot电子商城系统-消息队列之 RabbitMQ
- android 微积分计算器,不到1M的良心之作 连微积分都能算的计算器APP
- 星环科技TDH8.0使用必读2: 10种数据模型全支持 未来属于多模型大数据平台
- 新加坡国立大学计算机系访学,从实践中来,到实践中去——记新加坡国立大学访学项目...
- Animate.css动画库的使用操作
- tp-link与台式计算机连接教程,【详细图解】TP-Link TL-WDR6510路由器电脑设置教程...
- 电脑使用android手机摄像头,电脑怎么使用安卓手机摄像头 电脑使用手机摄像头的方法-电脑教程...
- RiPro美化二开详细修改路径介绍