耳机网-耳机大家坛

标题: 【原创】拒绝YY 从基础讲解USB/UAC运作原理 [打印本页]

作者: aarwwefdds    时间: 2017-4-23 19:58
标题: 【原创】拒绝YY 从基础讲解USB/UAC运作原理
本帖最后由 aarwwefdds 于 2017-4-23 21:20 编辑

USB是通用串行总线的意思,本质上并不是专门用来传输音频数据的。这里先简单列举USB2.0几个特性:双绞线、带电源、数据速率与传输频率无关、自同步(不需要单独传输时钟)、Token(令牌)轮询特性[1]。双绞线的特性使得USB天生具有抗共模干扰的能力,带供电使得它带的设备可以不需要电源,令牌轮询特性用于“交通管制”。

USB是主从模式的总线,Host控制器决定它下面所有设备一切事务的发送/接收时机。全速下,Host每1ms±500μs生成一个“帧”(frame)。高速下,每125us±0.0625μs生成一个“帧”[2]。一个“帧”以SOF包打头,包含发送给同一个Host控制器下的不同设备的若干个USB数据包。因此同一个控制器下的USB设备带宽共享:


在同一个USB控制器上的全速设备(FullSpeed/FS)、低速设备(LowSpeed/LS)设备之间共享带宽。高速设备(HighSpeed/HS)之间共享带宽,不与全速/低速设备共享,甚至很多南桥会单独设计高速USB2.0控制器。这种共享带宽,在下行中是这样实现的:Host设备发给高速设备 H1的数据包,高速设备H2同样会收到相同的数据包,但是因为接收地址与自身地址不符,H2设备会无视该数据包。同样的,Host发给F1全速设备的数据包,F2全速设备和L1/L2慢速设备也会收到同样的包,但是会将其无视。[3]

上行带宽共享则是由主机控制:除非主机在“帧”中发送了IN包告诉这个设备准许发送数据,否则设备不允许发送数据。这样就避免了冲突产生。

USB有四种传输通道类型(Endpoint):控制(Control)、中断(Interrupt)、批量(Bulk)、同步(Isochronous)。
Control用于USB总线控制等(所有设备都有),Interrupt多用于鼠标键盘的数据传输(其实在USB令牌轮询的特性下这是个伪Interrupt),Bulk多用于U盘数据传输。
前三种类型都有重传,各有特点这里略过。但USB音频类(USB Audio Class,简称UAC)采用的音频数据传输是第四种端口,也就是Isochronous,拥有错误检测机制,但是没有重传。

为何没有重传呢。
一是音频/视频是很讲究“实时性”的,否则会音画不同步,带来的恶果是很蛋疼的。因此音频/视频设备本质上都需要与主机同步,重传会打乱同步。
二是同步(Isochronous)类型因为要求低延迟,不像别的传输类型有握手过程,同一个"传输端口"内数据包是单向移动的(要么入要么出),Host不会给一个OUT方向的同步传输通道发送IN包,没有办法引入重传机制(发生错误时无法通知主机)。[4]
另外还有一点,为了“同步”,每个“帧”中的每个同步(Isochronous)通道只会传送一次数据。

这里有人要问了 用一个IN和一个OUT的Isochronous通道不就可以解决错误处理了?(ASYNC异步下也确实有一对IN和OUT通道,具体作用下文会解释,反正不是用来“错误检测”)

事实上,不可能。Host在一个Frame中轮询各个Endpoint的顺序是不可知的,很可能Host在一个Frame中先轮询了你的IN通道,但此时Host还没给你的OUT通道传送数据。这样就产生了:数据还没发送 怎么能确认数据收到了呢。


但这是否值得担忧呢?USB自身抗干扰特性(双绞线/屏蔽层)使得正常/正确使用的情况下,产生错误的概率非常非常低。真产生错误了,设备因为CRC校验失败,会将错误的USB数据包丢弃,而这会导致USB界面缓冲区欠载,导致短暂静音/爆音
作者: aarwwefdds    时间: 2017-4-23 19:59
本帖最后由 aarwwefdds 于 2017-4-23 22:12 编辑

前文已经可以得到结论,USB总线比较复杂,并不是为音频传输特别设置的传输方式。一个控制器通常需要对应多个设备,PC也有很多任务,其传输延迟会相对不那么稳定。

但是声卡设备需要与主机同步,否则会产生音画不同步问题,DAC也需要喂按采样率喂数据,因此就有了大家熟知的三种同步方式:SYNC、自适应、ASYNC模式(俗称“异步” 注意不要和Endpoint类型搞混)。顺带一提 很多人有个误区,以为ASYNC是UAC2引入的,其实并不是。早在UAC1就已经支持ASYNC[5],但因为各种原因(开发困难/成本高/效果一般)并没有被大规模采用。在UAC2时才因为XMOS等界面的出现降低了开发难度简化了实现而且效果好而被广为采用。

SYNC是将输出时钟与每个Frame的SOF包同步,但前文可以看到SOF包本身就允许较大的抖动。自适应是根据Host传送数据的速率调整输出频率(有点像SPDIF的工作方式不是么)。这两种同步方式下USB界面都是被动适应Host端的发送节奏,本身没有反馈机制,产生的Jitter受USB总线影响较大。当然芯片厂商为了减少影响也是绞尽脑汁,例如TI的所谓“SpAct时钟恢复”引入8xPLL等尽可能减少影响。最后根据某个外国人测出来大概PCM270x能把Jitter压到低于1us[6](还是挺高的按照现在的标准)

ASYNC下,USB界面会额外申请一条Feedback传输端口。这里有两种实现,一种是显式Feedback,一种是隐式Feedback。

显式Feedback下,USB界面会将单位时间内该传多少Samples回传给Host(实际有一套相当复杂的计算方式,此处略),让Host计算并知道之后该“补”多少或者该“少”多少采样传给USB界面,这样就能与USB界面主时钟同步并保持不溢出/欠载的缓冲区。UAC1使用数据格式10.14(因为是1ms),UAC2使用数据格式16.16(因为是125us),有所不同

这里以俗知的Amanero界面为例:
  1. Endpoint Descriptor:
  2. ------------------------------
  3. 0x07        bLength
  4. 0x05        bDescriptorType
  5. 0x05        bEndpointAddress   (OUT Endpoint) #主机端->USB界面
  6. 0x05        bmAttributes        (Transfer: Isochronous / Synch: Asynchronous / Usage: Data) #传输类型Isochronous 同步方式Asynchronous
  7. 0x0400        wMaxPacketSize   (1024 Bytes) #最大包大小
  8. 0x01        bInterval #传输间隔 2^(1-1) x 125。也就是125us传输一次

  9. Endpoint Descriptor:
  10. ------------------------------
  11. 0x07        bLength
  12. 0x05        bDescriptorType
  13. 0x81        bEndpointAddress   (IN Endpoint) #USB界面->主机端
  14. 0x11        bmAttributes        (Transfer: Isochronous / Synch: None / Usage: Feedback) #传输类型Isochronous 用于Feedback
  15. 0x0004        wMaxPacketSize   (4 Bytes)  #最大包大小4字节
  16. 0x06        bInterval #传输间隔 2^(6-1) x 125。也就是4000us(4ms)传输一次
复制代码


这是一个典型的显式Feedback的ASYNC,上行反馈Endpoint,每4ms传输一次,最大包大小是4字节(因为只是反馈Rate不需要太大)。再来看看Linux的UAC驱动是如何处理反馈的
节选:http://lxr.free-electrons.com/source/sound/usb/endpoint.c
...
1156         /*
1157          * process after playback sync complete
1158          *
1159          * Full speed devices report feedback values in 10.14 format as samples
1160          * per frame, high speed devices in 16.16 format as samples per
1161          * microframe.
1162          *
1163          * Because the Audio Class 1 spec was written before USB 2.0, many high
1164          * speed devices use a wrong interpretation, some others use an
1165          * entirely different format.
1166          *
1167          * Therefore, we cannot predict what format any particular device uses
1168          * and must detect it automatically.
1169          */
1170
1171         if (urb->iso_frame_desc[0].status != 0 ||
1172             urb->iso_frame_desc[0].actual_length < 3)
1173                 return;
1174
1175         f = le32_to_cpup(urb->transfer_buffer);
1176         if (urb->iso_frame_desc[0].actual_length == 3)
1177                 f &= 0x00ffffff;
1178         else
1179                 f &= 0x0fffffff;
1180
1181         if (f == 0)
1182                 return;
1183
1184         if (unlikely(sender->tenor_fb_quirk)) {
1185                 /*
1186                  * Devices based on Tenor 8802 chipsets (TEAC UD-H01
1187                  * and others) sometimes change the feedback value
1188                  * by +/- 0x1.0000.
1189                  */
1190                 if (f < ep->freqn - 0x8000)
1191                         f += 0xf000;
1192                 else if (f > ep->freqn + 0x8000)
1193                         f -= 0xf000;
1194         } else if (unlikely(ep->freqshift == INT_MIN)) {
1195                 /*
1196                  * The first time we see a feedback value, determine its format
1197                  * by shifting it left or right until it matches the nominal
1198                  * frequency value.  This assumes that the feedback does not
1199                  * differ from the nominal value more than +50% or -25%.
1200                  */
1201                 shift = 0;
1202                 while (f < ep->freqn - ep->freqn / 4) {
1203                         f <<= 1;
1204                         shift++;
1205                 }
1206                 while (f > ep->freqn + ep->freqn / 2) {
1207                         f >>= 1;
1208                         shift--;
1209                 }
1210                 ep->freqshift = shift;
1211         } else if (ep->freqshift >= 0)
1212                 f <<= ep->freqshift;
1213         else
1214                 f >>= -ep->freqshift;
1215
1216         if (likely(f >= ep->freqn - ep->freqn / 8 && f <= ep->freqmax)) {
1217                 /*
1218                  * If the frequency looks valid, set it.
1219                  * This value is referred to in prepare_playback_urb().
1220                  */
1221                 spin_lock_irqsave(&ep->lock, flags);
1222                 ep->freqm = f;
1223                 spin_unlock_irqrestore(&ep->lock, flags);
1224         } else {
1225                 /*
1226                  * Out of range; maybe the shift value is wrong.
1227                  * Reset it so that we autodetect again the next time.
1228                  */
1229                 ep->freqshift = INT_MIN;
1230         }

这里主要是处理来自于USB界面的反馈(并且应付一些不按标准做的USB界面),将获取的值保存进freqm。之后这个值会在snd_usb_endpoint_next_packet_size函数被使用。
145 int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep)
146 {
147         unsigned long flags;
148         int ret;
149
150         if (ep->fill_max)
151                 return ep->maxframesize;
152
153         spin_lock_irqsave(&ep->lock, flags);
154         ep->phase = (ep->phase & 0xffff)
155                 + (ep->freqm << ep->datainterval);
156         ret = min(ep->phase >> 16, ep->maxframesize);
157         spin_unlock_irqrestore(&ep->lock, flags);
158
159         return ret;
160 }

这里将freqm转化为下一次的包大小,并供prepare_playback_urb使用
节选http://lxr.free-electrons.com/source/sound/usb/pcm.c:
1451 static void prepare_playback_urb(struct snd_usb_substream *subs,
1452                                  struct urb *urb)
1453 {
1454         struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
1455         struct snd_usb_endpoint *ep = subs->data_endpoint;
1456         struct snd_urb_ctx *ctx = urb->context;
1457         unsigned int counts, frames, bytes;
1458         int i, stride, period_elapsed = 0;
1459         unsigned long flags;
1460
1461         stride = runtime->frame_bits >> 3;
1462
1463         frames = 0;
1464         urb->number_of_packets = 0;
1465         spin_lock_irqsave(&subs->lock, flags);
1466         subs->frame_limit += ep->max_urb_frames;
1467         for (i = 0; i < ctx->packets; i++) {
1468                 if (ctx->packet_size)
1469                         counts = ctx->packet_size;
1470                 else
1471                         counts = snd_usb_endpoint_next_packet_size(ep);

...

prepare_playback_urb这个函数主要决定了音频回放的USB请求数据块(URB)准备工作,包括该传多少USB数据给界面,而这里可以看到snd_usb_endpoint_next_packet_size对于包大小很重要。除此之外没有什么其它作用

如果仔细读代码,可以发现ASYNC和别的同步方式的最大区别它如何影响主机发送数据的多少,其它是与对待别的同步方式一模一样的。

除显式反馈之外还有隐式反馈(这种Feedback是把主机传给USB设备的数据回传回来 让主机自己计算数据速率)。这里就不说明了

ASYNC的最大好处是,USB界面决定了主机每次Frame中每个包该给多少Samples给它,这样USB界面可以自己决定主时钟并且用这个时钟去“校准”主机发送的数据速率,而不再需要适应Host的发送频率

通常高速需要有125us x 2的Buffer,全速需要1ms x 2的buffer。这些构成了USB音频的最小延迟。配合一定的USB Buffer以及合适的FIFO Buffer,就可以从根本上对USB总线的不稳定时钟“去耦”了。这就好比在线看视频听音乐,你的播放软件会维护一个缓冲区,缓冲网络上的数据,这样你就不需要下载所有数据以后才开始观看,并且播放软件实际上也会反馈给服务器相对应的发送速率(虽然实际情形中反馈方式并不像UAC这样)。我觉得没人会说从网络上在线听音乐会有“jitter”吧?最多是缓冲区欠载产生播放停顿 或者缓冲区溢出程序没处理好造成程序崩溃

对于USB界面自身,需要监控自身主时钟与来自主机的SOF包之间的时间,计算出偏差不断给Host反馈。并且因为Host发送速率和实际播放速率并不一致,USB界面自身需要合成与播放相关的Clock(对于德西架构的DAC 最重要的是MCLK),这个合成实现具体做法十分影响最终出来的效果,这对嵌入式开发者是一个不小的挑战。早在十年前TAS1020就已经有异步模式,但需要自己开发单片机程序,开发难度高于像现在XMOS这样的一体式方案,最终出来的jitter也没有现在的XMOS/Amanero等界面那么优异。

另外还有一个常见的误区,就是异步每次数据包里包含的“采样数”可以变化很大,实际上并不是这样(从代码里就可以看出F有个合理范围,超出会认为错误)。USB规范中最多允许每个USB包包含的samples变化在±1内[7]。因此如果之前数据错误丢失了采样,也不可以因此“索取”更多的“采样”


而在实际应用中,解码器厂商需要做好对USB的电气隔离/地线隔离,以免影响USB界面的工作能力以及把PC传过来的共模干扰带进DAC里。

以上的文章内容来自于我对USB2.0/UAC规范的理解。但为了“相对”严谨起见,我列出以下参考以便印证。如有错误欢迎指正
[1]USB的英文维基百科:https://en.wikipedia.org/wiki/USB
[2]USB协议以及其SOF包时间:http://www.beyondlogic.org/usbnutshell/usb3.shtml
[3]共享带宽的方式:https://www.totalphase.com/support/articles/200349256-USB-Background/#s1.1.2.1
[4]Isochronous的通信方式:http://www.beyondlogic.org/usbnutshell/usb4.shtml
[5]UAC1规范:www.usb.org/developers/docs/devclass_docs/audio10.pdf
[6]PCM2706的jitter测量以及主机电源如何影响时钟稳定性:https://www.audialonline.com/articles/spdif-or-usb/
[7]关于XMOS界面的工作原理:https://www.xmos.com/download/private/USB-Audio-Software-Design-Guide(6.6.0rc5.a).pdf
作者: aarwwefdds    时间: 2017-4-23 20:07
本帖最后由 aarwwefdds 于 2017-4-23 21:34 编辑

其实本来是想包含在“15周年征文”里的 然而发现篇幅变得太大可以单独出来了。所以单独出来发表了

补充一下一些可能的“小技巧”。这些“技巧”与上文不同,没有什么可靠来源,仅供参考
1.尽可能单独一个控制器下挂解码器,减轻控制器与USB界面的负担。避免额外的HUB
2.对于USB界面有独立供电的,可以考虑断开供电/地线,以及单边断开USB线的屏蔽层,避免诸如共地干扰这样的问题。
3.使用合格的USB线
4.PC优化ISR与DPC延迟,这对于降低延迟有好处。虽然低延迟对于高保真音频回放没什么用,只对监听有用
作者: ktvzk    时间: 2017-4-23 20:11
最近,技术文不少啊
作者: soil    时间: 2017-4-23 20:23
技术贴,支持!
作者: cloud119    时间: 2017-4-23 20:32
技术贴支持了
坐等坛子的大神出来开撕
作者: aarwwefdds    时间: 2017-4-23 20:58
cloud119 发表于 2017-4-23 20:32
技术贴支持了
坐等坛子的大神出来开撕

不要撕,要和气。我觉得大神都不屑于和我撕呢...

当然我写的都是有来据可以相互印证的内容,有错误可以好好提,带上相关依据就可以,测量的数据/相关技术文章/代码等 什么都好。只要不是什么听感就行
作者: real911    时间: 2017-4-23 21:04
好东西先顶后看
作者: 夜惊风    时间: 2017-4-23 21:21
USB之所以使用UAC传输音频,很大原因是接收端简陋的硬件条件造成的,早期的USB接收界面之所以简陋,那是因为这东西设计下来本就是随便用用的,穷人的劳斯莱斯啊,不用买碟就可以很方便的听歌,谁会想到今天一大帮人转着HIFI起来了

假如接收端有足够大的RAM,使用BULK完全没问题,基于ASRC时钟模式可以匹敌DP,之前听朋友说过,还真的有这么一台发烧机器,不过换曲延迟大一点。


作者: 夜惊风    时间: 2017-4-23 21:27
额,假如是使用BULK就不能说是ASRC模式了,是本地时钟模式
作者: aarwwefdds    时间: 2017-4-23 21:53
本帖最后由 aarwwefdds 于 2017-4-23 21:58 编辑
夜惊风 发表于 2017-4-23 21:21
USB之所以使用UAC传输音频,很大原因是接收端简陋的硬件条件造成的,早期的USB接收界面之所以简陋,那是因 ...

其实buffer也没那么精贵,现在的设备挂个几兆RAM轻而易举的事情,也不增加多少成本

主要是现在有两种思路。

要么完全给HiFi玩,搞大量的buffer,完全不与PC同步。需要自己写实现写协议写驱动。最后出来的东西还只能给HiFi用,成本高

要么按标准走,走ASYNC同步,而ASYNC同步必须避免必要之外的缓存(要有缓存但是不能太多了),否则会影响反馈,有害无利(来自于XMOS文档)。


而这两者都是本地时钟生成,“理论上”不应该有多少差异。然后因为后者显然可以使得自己的解决方案适用于多种应用场景,还能解决例如MAC/Linux这样的系统的驱动问题。那自然就是后者用的多了
作者: 夜惊风    时间: 2017-4-23 22:12
aarwwefdds 发表于 2017-4-23 21:53
其实buffer也没那么精贵,现在的设备挂个几兆闪存轻而易举的事情,也不增加多少成本

主要是现在有两种 ...

           buffer芯片现在很便宜,但是基于UAC的芯片设计思路已经转不过来了,为了适应市场不能再随意修改硬件架构。

          USB界面硬件设计得再豪华,一个UAC协议就是死穴,很多人说没误码没爆音就是没影响,就我调试数播的经验,优化一个SD读卡的函数都能带来不小区别。



作者: aarwwefdds    时间: 2017-4-23 22:36
本帖最后由 aarwwefdds 于 2017-4-23 22:38 编辑
夜惊风 发表于 2017-4-23 22:12
buffer芯片现在很便宜,但是基于UAC的芯片设计思路已经转不过来了,为了适应市场不能再随意修 ...

实干是好事,我也正考虑以后实干一下。在实干前先不烧了

不过不知道你遇上的影响是否用仪器测过,是否可以测出差异呢。
作者: aarwwefdds    时间: 2017-4-23 23:06
另外。。。不与PC同步的 某种意义上已经不能叫声卡 因为必定会导致音画不同步。这使得它应用范围就小了,只能用于高品质音乐回放。做方案的厂子显然不会给自己的东西那么窄的应用范围,不好不好卖啊

UAC我认为标准制定者在最开始的UAC1就给了ASYNC模式就是标准制定者的远见,说标准制定者没看到usb下可能存在的问题,这点我是持有异议的。而USB的坏名声也主要是因为多年前没啥厂子用好了它

作者: 蓝子风    时间: 2017-4-23 23:11
aarwwefdds 发表于 2017-4-23 22:36
实干是好事,我也正考虑以后实干一下。在实干前先不烧了

不过不知道你遇上的影响是否用仪器测过,是否 ...

看处理顺序。我记得一个朋友做数播的时候,数据接收后的处理环节镶套顺序不同也会导致声音的变化。当然这个只是数播

反映过来,其实UAC规范不是问题,问题在于本地接收到数据之后怎么处理的问题

作者: aarwwefdds    时间: 2017-4-23 23:21
蓝子风 发表于 2017-4-23 23:11
看处理顺序。我记得一个朋友做数播的时候,数据接收后的处理环节镶套顺序不同也会导致声音的变化。当然这 ...

这是的,数据来了不能直接用,例如XMOS就有个去耦的过程。单片机上的最终实现方式对最终效果影响很大,就像以前的TAS1020的ASYNC出来的效果不能与现在的方案比不是

作者: lmjnyhg    时间: 2017-4-23 23:33
这代码没注释看着好累23333,恕我才疏学浅。
作者: lmjnyhg    时间: 2017-4-23 23:33
这代码没注释看着好累23333,恕我才疏学浅。
作者: 冯赌必晟    时间: 2017-4-24 03:13
好贴 PChufi用户表示支持技术贴
作者: 夜惊风    时间: 2017-4-24 08:44
本帖最后由 夜惊风 于 2017-4-24 08:48 编辑
aarwwefdds 发表于 2017-4-23 23:06
另外。。。不与PC同步的 某种意义上已经不能叫声卡 因为必定会导致音画不同步。这使得它应用范围就小了,只 ...

        其实吧,UAC协议的制定者只是给出了一个现实条件下最好的解决方案,就像你说的,要考虑音画同步,不能一昧的照顾HIFI,这必然存在妥协

        其实USB用BULK传输音频数据,跟做USB读取硬盘文件很像,硬件结构基本兼容,都是PHY之后大缓存,只是目前没有驱动方面的支援。

      


        

作者: phoexi    时间: 2017-4-24 08:50

作者: brthrush    时间: 2017-4-24 10:23
按我的理解USB用BULK传输音频数据相当于吧歌曲下载到DAC再播放,这样DAC其实跟数字转盘没区别了
作者: aarwwefdds    时间: 2017-4-24 11:14
本帖最后由 aarwwefdds 于 2017-4-24 11:16 编辑
brthrush 发表于 2017-4-24 10:23
按我的理解USB用BULK传输音频数据相当于吧歌曲下载到DAC再播放,这样DAC其实跟数字转盘没区别了

Bulk无法同步 有比较大的延迟问题 而且延迟还会很不稳定

因此实际应用中由于成本和收效/收益很不成比例 也很少使用

根据标准,UAC理论上涵盖了从消费级到HiFi级的各种同步方式。而且UAC的应用已经很成熟 如果你要自己搞一套 成本摆在那里 最后搞出来说不准还不如用已有的UAC异步方案

作者: dragonlch    时间: 2017-4-27 16:26
现在大部分界面都采用“USB异步传输”

乐之邦的比较奇怪,采用“Bulk模式”

当一回搬运工!!!!!

http://www.erji.net/forum.php?mo ... hlight=%D2%EC%B2%BD
作者: aarwwefdds    时间: 2017-4-27 16:59
本帖最后由 aarwwefdds 于 2017-4-27 17:27 编辑
dragonlch 发表于 2017-4-27 16:26
现在大部分界面都采用“USB异步传输”

乐之邦的比较奇怪,采用“Bulk模式”

你这搬运工没搬好 连接都挂了

bulk有个最大的问题,它带宽不被保证,如果传高采样率数据占去很大带宽,同时总线上又有其他高优先级的数据传输,bulk就会产生不稳定的时延。而这个反过来会影响PC的音画同步

所以bulk只能拿来听音乐 不能干别的
作者: aarwwefdds    时间: 2017-4-28 08:43
蓝子风 发表于 2017-4-23 23:11
看处理顺序。我记得一个朋友做数播的时候,数据接收后的处理环节镶套顺序不同也会导致声音的变化。当然这 ...

突然发现你还有个黑历史
http://www.erji.net/forum.php?mod=viewthread&tid=767228&extra=&page=2

作者: 蓝子风    时间: 2017-4-28 08:52
aarwwefdds 发表于 2017-4-28 08:43
突然发现你还有个黑历史
http://www.erji.net/forum.php?mod=viewthread&tid=767228&extra=&page=2

是呀,黑历史谁都有的。毕竟过去认知不够清楚的时候都有过的。

作者: 夜惊风    时间: 2017-4-28 09:28
aarwwefdds 发表于 2017-4-27 16:59
你这搬运工没搬好 连接都挂了

bulk有个最大的问题,它带宽不被保证,如果传高采样率数据占去很大带宽 ...

       有个不懂的地方请教一下,假如在界面跟PC之间串入了HOST,那PC跟HOST之间是UAC还是BULK?

作者: 蓝子风    时间: 2017-4-28 09:45
夜惊风 发表于 2017-4-28 09:28
有个不懂的地方请教一下,假如在界面跟PC之间串入了HOST,那PC跟HOST之间是UAC还是BULK?

按照USB规范,是BULK

作者: 夜惊风    时间: 2017-4-28 09:51
蓝子风 发表于 2017-4-28 09:45
按照USB规范,是BULK

       那我在COMBO384的ARM前面加一个HOST芯片,可以很大降低USB线的影响了

作者: paozuo    时间: 2017-4-28 09:54
火线大法好
作者: aarwwefdds    时间: 2017-4-28 10:08
蓝子风 发表于 2017-4-28 09:45
按照USB规范,是BULK

USB规范允许两个Host?不对吧 你看到的Bulk是在哪里看到的

作者: aarwwefdds    时间: 2017-4-28 10:13
夜惊风 发表于 2017-4-28 09:28
有个不懂的地方请教一下,假如在界面跟PC之间串入了HOST,那PC跟HOST之间是UAC还是BULK?

就USB总线本身来说,USB总线只允许有一个Host。像OTG也只是协商这个连线之间谁做Host,如果其中一个Master另一个必定是Slave

如果要将一个Host接入PC,恐怕就只有PCI-E这样的可以用了。市面上也确实有些号称超低Jitter的单独USB输出卡走PCI-E之类的,效果嘛....没用过不评价

作者: 夜惊风    时间: 2017-4-28 10:17
aarwwefdds 发表于 2017-4-28 10:13
就USB总线本身来说,USB总线只允许有一个Host。像OTG也只是协商这个连线之间谁做Host,如果其中一个Maste ...

        

作者: aarwwefdds    时间: 2017-4-28 10:21
像USB音频这样的应用,如果在PC和USB解码器界面串入另一个“Host”,而且和PC还得走USB的话。

那么只有一种办法,这个串入的设备必须是一从一主,从端接入PC,主端连接USB解码器界面。从端和PC之间走什么协定随意,只要有合适的驱动方式就行。
作者: 夜惊风    时间: 2017-4-28 10:23
aarwwefdds 发表于 2017-4-28 10:21
像USB音频这样的应用,如果在PC和USB解码器界面串入另一个“Host”,而且和PC还得走USB的话。

那么只有 ...

         给推荐个合适的HOST芯片,我来试试

作者: aarwwefdds    时间: 2017-4-28 10:23
夜惊风 发表于 2017-4-28 10:17

没看到单独的晶振啊233 这个只是普通的USB3的PCI-E扩展卡吧 我用过

作者: 蓝子风    时间: 2017-4-28 10:34
本帖最后由 蓝子风 于 2017-4-28 10:37 编辑
aarwwefdds 发表于 2017-4-28 10:08
USB规范允许两个Host?不对吧 你看到的Bulk是在哪里看到的

我记得USB规范中描述BULK的时候给出的一个示意图就有一个HUB的

作者: aarwwefdds    时间: 2017-4-28 10:34
夜惊风 发表于 2017-4-28 10:23
给推荐个合适的HOST芯片,我来试试

我好像还没见过这么蛋疼的玩意。大概只能自己搞了
可以考虑用树莓派来做吧


作者: aarwwefdds    时间: 2017-4-28 10:35
蓝子风 发表于 2017-4-28 10:34
我记得USB规范中描述BULK的时候给出的一个示意图就有一个HUB的

HUB相对于PC也不是Host啊...

作者: 蓝子风    时间: 2017-4-28 10:41
aarwwefdds 发表于 2017-4-28 10:35
HUB相对于PC也不是Host啊...

相对于下一级设备就是HOST了呀

作者: aarwwefdds    时间: 2017-4-28 10:51
本帖最后由 aarwwefdds 于 2017-4-28 10:52 编辑
蓝子风 发表于 2017-4-28 10:41
相对于下一级设备就是HOST了呀

...所有的HUB都是“集线”作用 正常情况下它是透明的 不破坏与主机之间的网络拓扑。最终还是以主机的SOF为时钟标准。HUB或许可以做一些PLL,但是范围不能太大影响正常的时序 否则通讯无法进行

最难理解的部分是高速HUB与全速设备之间的互动 涉及到USB标准中最复杂的事务翻译。好在UAC2是跑在高速下的 不需要考虑这问题
作者: aarwwefdds    时间: 2017-4-28 11:02
本帖最后由 aarwwefdds 于 2017-4-28 11:05 编辑

影响主从的只有switch,不过我好像没见过“USB switch”。只有以太网有switch和hub,把以太网的hub和switch概念代换一下就懂了。老外用词还是很准确的

hub不破坏主从关系和带宽分配的,HUB需要做一些特殊的事情例如对全速设备的“事务翻译”和对设备的插入等拔出通知Host,还有某些情况下的带宽管理,丢弃掉一些包之类的
作者: 蓝子风    时间: 2017-4-28 11:05
本帖最后由 蓝子风 于 2017-4-28 11:08 编辑
aarwwefdds 发表于 2017-4-28 10:51
...所有的HUB都是“集线”作用 正常情况下它是透明的 不破坏与主机之间的网络拓扑。最终还是以主机的SOF ...

MTT技术的USB HUB。实际是一个对下一级设备的HOST作用的设备了。

毕竟和主机连接的协议已经和次级设备的连接协议分隔开来了。因为分出来的接口不管是接HIGH-SPEED还是FULL-SPEED或者多个速率的设备,HUB和主机之间的连接都是HIGH-SPEED。虽然算是一种多重转译,但是也可以算是理解成一种重分配。

作者: aarwwefdds    时间: 2017-4-28 11:12
本帖最后由 aarwwefdds 于 2017-4-28 11:20 编辑
蓝子风 发表于 2017-4-28 11:05
MTT技术的USB HUB。实际是一个对下一级设备的HOST作用的设备了。

毕竟和主机连接的协议已经和次级设备 ...

事务翻译仅影响高速HUB与全速/低速设备之间的互动,不管是单TT还是多TT,都只影响全速/低速设备。

多TT相对于单TT的好处只是不同的全速设备之间的带宽不互相影响。无论是啥TT,都不影响高速设备与高速HUB与Host的互动,而UAC2是高速标准 不受影响,所以我才开始就强调了 好在UAC2是跑在高速下的 不需要管事务翻译那个蛋疼的问题

修订:说的更准确些
作者: 蓝子风    时间: 2017-4-28 11:24
本帖最后由 蓝子风 于 2017-4-28 11:33 编辑
aarwwefdds 发表于 2017-4-28 11:12
事务翻译仅影响高速HUB与全速/低速设备之间的互动,不管是单TT还是多TT,都只影响全速/低速设备。

多T ...

实际上HUB转译之后,变相的相当于时钟重新分配了。如果能再加上传输损耗补偿就更好了。对于UAC也算是一个大帮助

另外,我没记错的话啊,STT的话,后端一个扩展口接FULL-SPEED设备的话,4个扩展口的连接速率都会统一成FULL-SPEED,共享带宽。

作者: aarwwefdds    时间: 2017-4-28 11:51
本帖最后由 aarwwefdds 于 2017-4-28 11:56 编辑
蓝子风 发表于 2017-4-28 11:24
实际上HUB转译之后,变相的相当于时钟重新分配了。如果能再加上传输损耗补偿就更好了。对于UAC也算是一个 ...

不会的...HUB不转译高速设备的数据包 直接pass下去...

你可以看下TT的USB包是怎么结合进高速链路里的。即使是TT 也是Host告诉HUB可以发送TT的包以后HUB才发送..因此本质上还是Host决定HUB什么时候可以发全速设备的数据。当然因此HUB需要一定的控制和buffer机制 比较复杂

另外...之所以需要TT就是为了避免你说的插一个全速其它都变全速这种情况。

补充:不然还要啥TT,直接插入全速设备的时候HUB声明自己变全速就行了...
作者: ikkaruis    时间: 2017-4-28 12:04
蓝子风 发表于 2017-4-28 11:24
实际上HUB转译之后,变相的相当于时钟重新分配了。如果能再加上传输损耗补偿就更好了。对于UAC也算是一个 ...

又看到蓝子风同学打肿脸充胖子,各种自黑

作者: aarwwefdds    时间: 2017-4-28 12:09
你可以认为多个TT相当于HUB集成了多个全速/低速控制器 单个TT相当于HUB只有一个全速/低速控制器。单TT的话HUB上的全速/低速设备都共享一个12M带宽,多个TT就是不同的口有不同的12M带宽,但上行口还是一样的 高速

这里我要YY下:因为每个全速/低速口怎么传数据需要HUB和Host共同协作,产生的时间抖动不稳定问题“可能”会更严重/复杂

至于HUB上的高速设备...它实际上能看到HUB接收的TT包,所以对于HUB的上的高速设备,HUB上的全速/低速设备只不过是总线上另一个传输事务罢了。HUB不需要为高速设备做事务翻译 完全不需要
作者: duben    时间: 2017-4-28 13:27
这个贴是不是要发到PCHIFI板块去
作者: aarwwefdds    时间: 2017-4-28 13:41
duben 发表于 2017-4-28 13:27
这个贴是不是要发到PCHIFI板块去

这个属于“HIFI理论”吧,发这里我觉得没啥不对。特别是关乎于所谓的“数字界面”(实际是DDC)的一些运作方式,这些是基础了

如果有空的话我再写写关于真·“数字界面”的事情 什么8XR之类的
作者: dragonlch    时间: 2017-4-28 14:28
aarwwefdds 发表于 2017-4-28 08:43
突然发现你还有个黑历史
http://www.erji.net/forum.php?mod=viewthread&tid=767228&extra=&page=2

谢谢搬运!

作者: 蓝子风    时间: 2017-4-28 17:38
本帖最后由 蓝子风 于 2017-4-28 17:44 编辑
aarwwefdds 发表于 2017-4-28 12:09
你可以认为多个TT相当于HUB集成了多个全速/低速控制器 单个TT相当于HUB只有一个全速/低速控制器。单TT的话H ...

哦,明白了,3Q呢。这样说来HUB还有肩负一个任务就是分类PC-HUB之间的带宽给下一级设备,STT就是只有提供一个低速或者全速的带宽,而MTT则是为后面每一个设备提供一个低速/全速带宽。这样转换到上行的时候。肯定会有一个数据重新整合的过程。
作者: 蓝子风    时间: 2017-4-28 17:44
aarwwefdds 发表于 2017-4-28 13:41
这个属于“HIFI理论”吧,发这里我觉得没啥不对。特别是关乎于所谓的“数字界面”(实际是DDC)的一些运 ...

期待科普

作者: aarwwefdds    时间: 2017-4-28 19:05
蓝子风 发表于 2017-4-28 17:38
哦,明白了,3Q呢。这样说来HUB还有肩负一个任务就是分类PC-HUB之间的带宽给下一级设备,STT就是只有提供 ...

有的 HUB也确实需要一定的带宽管理。不过主要的分配任务还是在PC,也就是Host上。Host会给出什么时候应该做分割传输的信号,然后这时候HUB再把低速/全速设备的数据往上报。当然实际的流程更复杂,期间涉及多个buffer的管理和控制,是USB2.0里最复杂的逻辑了

它的逻辑方式可以参考一下这个
http://read.pudn.com/downloads129/ebook/551313/USB_2.0.pdf

然后USB3...这货就直接不要什么TT了 物理上向下兼容...
作者: TokuRin    时间: 2017-9-22 15:48
楼主,咨询个问题!!!
音频文件本身采样精度是16bit,外置音频解码器(乐之邦的一个设备)是32bit(bBitResolution)。
那么通过usb的iso方式传输数据时,一个样本应该是传多大?

我的理解:
1,一个样本传16bit?但是好像没有方法设定外置解码器的bBitResolution值。
2,一个样本传32bit?我需要在host的软件端,把音频文件的一个样本从16bit扩展成32bit,在传给外设??

其实就是问在主机端,外设的bBitResolution是可以更改的么?
还是需要在usb传输之前,通过软件把不同采样精度的音频,全部转换为符合外设要求的采样精度,然后传输?

本人刚开始接触UAC,问的问题比较低级,望解答一下,谢谢!
或者指明一下uac文档的那个章节可以找到,看了3天没找到。。。

作者: aarwwefdds    时间: 2017-9-23 04:16
TokuRin 发表于 2017-9-22 15:48
楼主,咨询个问题!!!
音频文件本身采样精度是16bit,外置音频解码器(乐之邦的一个设备)是32bit(bBit ...

最好的办法就是直接塞0了。方便处理

而且在某些情况下,例如在播放过程中应用了DSP,你可以很方便的从塞0直接转变为32位输出,保留更多的信息给解码器

作者: yanagi_yui    时间: 2017-9-23 07:15
好帖战马。换一条线就能有提升?
作者: TokuRin    时间: 2017-9-23 17:57
aarwwefdds 发表于 2017-9-23 04:16
最好的办法就是直接塞0了。方便处理

而且在某些情况下,例如在播放过程中应用了DSP,你可以很方便的从 ...

多谢回复!!!
所以,是通过主机端软件修改音频数据,达到主机端和外设端相互匹配bit参数的(外设的bit值是恒定的)。而不是通过向外设发送控制请求,修改外设参数。
这样理解?

在问一下,主机和外设的通道数需要匹配么?
例如,主机端拿到的音频数据是2声道,外设如果是4声道,那这个转换,需要那边来做?


作者: aarwwefdds    时间: 2017-9-23 19:34
TokuRin 发表于 2017-9-23 17:57
多谢回复!!!
所以,是通过主机端软件修改音频数据,达到主机端和外设端相互匹配bit参数的(外设的bit ...

descriptor这玩意你改不了

然后是,(排除掉软件混音设备和SRC)在主机端处理过程中其实都是32位的。最后再根据需要裁切或者塞0。这个过程对音质无损

外设是4声道,音源是2声道的话。看你自己怎么弄,你可以把2声道直接输出到FL和FR(这个映射你可以自己在驱动面板设置或者驱动也有默认映射信息)。或者扩展成4声道输出给设备。一般情况下这些是主机端软件完成

作者: TokuRin    时间: 2017-9-23 21:42
我可能大背景没描述!

我是在Linux下,在应用层,去实现uac2.0协议(绕过了底层uac驱动),和外接音频解码器通信。
现在已经能够完全识别设备,并进行控制传输。
在播放音频时,即同步传输(iso)时,播放效果很乱(音频失真还有杂音)。

外接音频解码器:32bit,4声道。(设备信息中读取的)
音源:16bit,2声道。

按照你的讲解,我应该要把音源数据转换成32bit、4声道,再传给外设就OK?

作者: aarwwefdds    时间: 2017-9-24 22:04
TokuRin 发表于 2017-9-23 21:42
我可能大背景没描述!

我是在Linux下,在应用层,去实现uac2.0协议(绕过了底层uac驱动),和外接音频解 ...

我觉得你应该考虑是扩声道,位深可能不是问题

作者: rgwan    时间: 2017-10-18 22:52
本帖最后由 rgwan 于 2017-10-18 22:58 编辑
aarwwefdds 发表于 2017-4-23 21:53
其实buffer也没那么精贵,现在的设备挂个几兆RAM轻而易举的事情,也不增加多少成本

主要是现在有两种 ...

其实这个东西还得看芯片。对通用单片机/FPGA之类的没APLL电路的芯片来说。做异步反而简单。如果系统有可以lock住SOF的PLL,那就是做同步简单了。

我个人还是比较喜欢做异步,因为好控制,对现在我手上的平台来说,实现比较简单(虽然对PC上需要实时应用的软件不友好),也比较好控制。近期打算公开一个STM32F205+CPLD UAC1、UAC2的实现,有空可以去我GitHub逛逛。


作者: rgwan    时间: 2017-10-18 22:54
本帖最后由 rgwan 于 2017-10-18 23:17 编辑
TokuRin 发表于 2017-9-23 21:42
我可能大背景没描述!

我是在Linux下,在应用层,去实现uac2.0协议(绕过了底层uac驱动),和外接音频解 ...

在应用层(user-space)上,实时性是比较难保证的,你可能遇到的是丢帧和长度调整不到位的问题(跟随声卡要求)。建议你还是用内核驱动,但是独占ALSA接口。


作者: rgwan    时间: 2017-10-18 23:14
蓝子风 发表于 2017-4-28 09:45
按照USB规范,是BULK

求仔细读文档,看不懂就看实现……别上来就言之凿凿

上次在B站闲逛还看到你和其他人争论频率分辨率是和采样率有关还是跟分析窗口有关……本来很想发给你一本奥本海姆的信号与系统,可惜没绑手机发不出去233333333


作者: 蓝子风    时间: 2017-10-20 23:01
本帖最后由 蓝子风 于 2017-10-20 23:14 编辑
rgwan 发表于 2017-10-18 23:14
求仔细读文档,看不懂就看实现……别上来就言之凿凿

上次在B站闲逛还看到你和其他人争论频率分辨 ...

B站上的那个呀,如果纯粹正弦波可以没问题,但是问题是音频信号中不止正弦波。你的很多信号理论也基本是根据这样的,比如22.05K信号只有2个采样的波形,你怎么分辨是正弦波还是三角波或者方波?所以其实越接近采样表达的极限,会有一定的问题。因为很多差不多比较高频的非线性波形,包含的谐波成分已经远超过这个频段了。所以就造成了损失。而很多这样的波形变化,是人耳可以分辨出来的。这也是为什么虽然人耳只能听到20-20K的音频信号,但是高采样高比特在声音上会比CD标准的16BIT/44.1K要出色。

有些时候是有认知错误,是真的错了,自然需要改正。我也有过不少的认知错误,比如早期的时候对于异步模式的理解错误。

当然了,你是专业者,或者你可以直接按照自己的元件用FPGA什么的搭一个你所谓的信号理论出来的USB DAC???

作者: wangzx998    时间: 2017-10-20 23:58
  技术文好评,虽然难以看懂
  个人见解,HIFI烧油,也是PC攒机烧友
  相对于笔记本,尽量不要USB直连,OEM的板子用料什么的不会太好。
  攒机里对于声卡就不必多说了,ROG的板子声卡也不会太好
  至于USB,现在都是3.0,3.1的时代了,稍微超频好点的板子用料,元器件都不会太差。
  发射端完全就不是瓶颈,看你收不收得到了,而且USB还可以绕过板载声卡(我的板载都是关闭的不用)
  USB是趋势,以后PCHIFI会占大多数,界面无可匹敌,通用性无敌~
  手上是华擎X370太极,买根乐机宝得的线刚开始有刺啦声,现在完全没有,听的美滋滋~
作者: wangzx998    时间: 2017-10-21 00:03
wangzx998 发表于 2017-10-20 23:58
技术文好评,虽然难以看懂
  个人见解,HIFI烧油,也是PC攒机烧友
  相对于笔记本,尽量不要USB直连,O ...

  usb这个东西通用程度太高,不止音频传输,设备输入输出慢慢都做成USB了
  可能没资格评论这个技术文(因为这些东西真的不懂啊)
  但是这是趋势,USB相当于一台1000马力的八缸发动机了,怎么基于这个心脏做出好车,匹配好变速箱已经不是发动机的问题了

作者: rgwan    时间: 2017-10-21 15:54
本帖最后由 rgwan 于 2017-10-21 15:58 编辑
蓝子风 发表于 2017-10-20 23:01
B站上的那个呀,如果纯粹正弦波可以没问题,但是问题是音频信号中不止正弦波。你的很多信号理论也基本是 ...

公开了,欢迎去我的GitHub。最近缺钱,打算做一个套件回血。到时候板子我能免费送一波,器件就没法送了。

另外的,20k的非正弦波当然会被切除高频谐波变为正弦波,毕竟数字采样只能够表示带限信号。不过……首先你得能分辨的出20k以上谐波的存在……

作者: 蓝子风    时间: 2017-10-21 21:23
rgwan 发表于 2017-10-21 15:54
公开了,欢迎去我的GitHub。最近缺钱,打算做一个套件回血。到时候板子我能免费送一波,器件就没法送了。 ...

你的GitHub???恕我孤陋寡闻,查了下,不是软件项目的托管平台吗?给个访问方式呀~~~有空可以捧捧场的说呢。

期待早日能成功吧~~~因为每年这么多身怀“高大上”作品的人被淹没在茫茫人海中。祝阁下能脱颖而出吧。

=================================================================================

理论上人耳虽然听不出来20K以上的正弦波,但是不代表人耳听不出20K以上信号对20K以内信号的影响。所以个人是认同高采样是会带来可闻的听感改善。同样高BIT带来的动态和细节上的提升应该更容易让人感觉到提高。这就是我在B站那个视频里坚持的理论,只是表达方式上可能被人带歪了。

作者: 天将明    时间: 2017-10-22 03:25
wangzx998 发表于 2017-10-21 00:03
usb这个东西通用程度太高,不止音频传输,设备输入输出慢慢都做成USB了
  可能没资格评论这个技术文( ...

虽然我没有看懂,但我怎么觉得这个意思是USB现在是个100马力的发动机,难题就在如何基于它做出好车。

作者: wangzx998    时间: 2017-10-22 21:29
天将明 发表于 2017-10-22 03:25
虽然我没有看懂,但我怎么觉得这个意思是USB现在是个100马力的发动机,难题就在如何基于它做出好车。

  正是这个意思,通用性上USB无可匹敌
  协议和技术上可以挖掘的东西还有很多,而且支持的格式也多

作者: 专业尸体    时间: 2018-12-14 17:02
楼主你好,本人小白刚接触一点usb音频,我enable了playback interface之后,给isochronous endpoint按照maxpacketsize和interval发送pcm数据,从耳机那边只能听到嗡嗡的杂音,请问这是问什么呀?
作者: ppqppqpp    时间: 2018-12-14 21:18
专业尸体 发表于 2018-12-14 17:02
楼主你好,本人小白刚接触一点usb音频,我enable了playback interface之后,给isochronous endpoint按照max ...

20年经验老师傅,专业维修菊花

作者: 专业尸体    时间: 2018-12-17 10:22
ppqppqpp 发表于 2018-12-14 21:18
20年经验老师傅,专业维修菊花

菊花很健康,暂无维修需求

作者: 514PRO    时间: 2023-1-22 13:25
挖个帖。
大佬我想问问很多玩OSU这种对延迟比较敏感游戏的玩家常常说独立解码器会有声画不同步的情况,他们反而推荐使用板载声卡。
请问属实吗?(我自己没这方面感受),是什么原因造成的?




欢迎光临 耳机网-耳机大家坛 (http://www2.erji.net/) Powered by Discuz! X3.2