最近,有朋友正好在开发一个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音频设备的开发过程相关推荐

  1. 知行合一:知其然知其所以然

    知行合一:知其然知其所以然. 一个事情做成了,并不意味着你知道做成这件事背后蕴藏的原理. 只有使用冥思.事上练的方法了,将背后的原理提取出来,才能说做到了执行合一. 这个过程是行对知的精进过程. 转载 ...

  2. 锁,知其然知其所以然

    ​ Taken by iCola 今天,从一个小问题聊起. 假设你账户上原来有100元钱,你用微信支付100元,与此同时你女票用支付宝给你转100元零花钱,你帐户的余额有没有可能变成200元或者0元? ...

  3. 字符串去掉两端的引号_Python3.7知其然知其所以然-第六章 字符串

    在开发过程中,经常会用到字符串来存储字符内容.在其他编程语言中用成对双引号" "声明字符串,用成对单引号' '声明单个字符,而Python没有这种区别,它无论单个或多个字符都用字符 ...

  4. redis zset转set 反序列化失败_关于Redis中的五种数据结构,要知其然知其所以然...

    Redis作为Nosql的代表,想必大家已经再熟悉不过了,除了作为缓存来使用,Redis还提供了其他很多有用的功能,例如可作为消息队列.分布式锁.不隆过滤器.限流等功能使用.今天先来说一说redis作 ...

  5. bootstraptable获取所有数据_关于Redis中的五种数据结构,要知其然知其所以然

    Redis作为Nosql的代表,想必大家已经再熟悉不过了,除了作为缓存来使用,Redis还提供了其他很多有用的功能,例如可作为消息队列.分布式锁.不隆过滤器.限流等功能使用.今天先来说一说redis作 ...

  6. Android转换位图BUG,知其然不知其所以然

    在开发某App的时候,发现了一个很奇怪的bug,前面我也发了关于bitmap的总结,但是这个问题恰恰出在BitmapFactory.decodeFile(pathName)这个函数上,使用这个函数在我 ...

  7. 算出当前系统后某个月的日期_Python3.7知其然知其所以然-第十八章 日期函数

    时光不可追,往事不可回.以往创建的数据,如若没有日期做标识,不堪回首.几乎任何一个产品都会用到日期,如登录日期.创建日期.修改日期等.正因如此,编程语言中,几乎都有内置日期函数. 18.1 当前日期 ...

  8. Vue2.0源码解析 - 知其然知其所以然之Vue.use

    前言 小伙伴们大家好.用过Vue的小伙伴都知道,在我们进行Vue开发时,避免不了会使用一些第三方的库,比如说ElementUI组件库.当我们导入好这些组件库后会执行一个Vue.use函数,然后把导进来 ...

  9. Pandas数据处理误区要知其然知其所以然

    背景 在Python里面处理数据,必然离不开Pandas,但目前网上的文章大部分都是介绍函数怎么使用,至于为什么有时数据处理结果是错误的,并没有深入研究,也可能是由于Pandas的一些BUG,没有人提 ...

  10. Vue2.0源码解析 - 知其然知其所以然之keep-alive

    前言 [一天一个小知识,每天进步一点点]小伙伴们大家好,今天将要给大家分享是Vue中关于组件缓存的一个内置组件 - keep-alive 不知道小伙伴们有没有遇到这样一种情况,在我们的项目开发中,有时 ...

最新文章

  1. Python控制结构总结
  2. 举重若轻的人人车移动端数据平台
  3. Firefox火狐浏览器自用技巧汇总--以备使用--13.5.16
  4. BugKuCTF WEB 变量1
  5. 【linux】修改机器时间
  6. 程序员,请您不要老是熬夜
  7. logstash的使用教程
  8. 【python 11】super()
  9. springcloud 相同服务名_SpringCloud系列之SpringCloud Stream
  10. java什么时候需要同步_JAVA中线程在什么时候需要同步和互斥
  11. 「数据分析」Sqlserver中的窗口函数的精彩应用-问题篇
  12. “12306”是如何支撑百万QPS的?
  13. java B2B2C Springboot电子商城系统-消息队列之 RabbitMQ
  14. android 微积分计算器,不到1M的良心之作 连微积分都能算的计算器APP
  15. 星环科技TDH8.0使用必读2: 10种数据模型全支持 未来属于多模型大数据平台
  16. 新加坡国立大学计算机系访学,从实践中来,到实践中去——记新加坡国立大学访学项目...
  17. Animate.css动画库的使用操作
  18. tp-link与台式计算机连接教程,【详细图解】TP-Link TL-WDR6510路由器电脑设置教程...
  19. 电脑使用android手机摄像头,电脑怎么使用安卓手机摄像头 电脑使用手机摄像头的方法-电脑教程...
  20. RiPro美化二开详细修改路径介绍

热门文章

  1. VMware5.5-VMware补丁程序VUM
  2. 《炬丰科技-半导体工艺》--技术资料合集14
  3. 大学生社会实践报告 模板
  4. 手机android flash,安卓手机flash插件最新版
  5. SpringBoot + Vue基本知识点荟萃
  6. 网站小图标制作及配置
  7. [Ant]Note of develop java with Ant
  8. 分享10款效果惊艳的HTML5图片特效
  9. UE4蓝图API翻译【节点】---? Is Valid
  10. 华为模拟器eNSP - HCIP - OSPF的Totally STUB 、Totally NSSA综合实验