最近,有朋友正好在开发一个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音频设备有一个概念上的基本了解.