第三篇:知其然,知其所以然-USB音频设备的开发过程

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u013140088/article/details/17398679

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









展开阅读全文

没有更多推荐了,返回首页