USB Audio调试知识

1 USB isochronous
1.1 USB isochronous
USB为何要用isochronous机制呢?这是一个历史问题,我们熟悉的SPDIF接口,AES/EBU接口都是基于isochronous的。

With voice latency of 15 milliseconds being a threshold where most people can start noticing.
The Linux batching of iso packets in one urb.

1.2 USB SOF
FS: 1.000ms ± 500ns, jitter = 500ns
HS: 125.0µs ± 62.5ns, jitter = 62.5ns
高速设备在每1 ms的周期内,会看到具有相同帧号的SOF包8次(每125 µs)。如果需要,高速设备可以通过检测具有与前一个SOF不同的帧号的SOF,并将其作为第0个微帧,以此来确定特定的微帧编号。接下来的7个具有相同帧号的SOF可以视为第1至第7个微帧。
USB ISO ASAP: start_frame = cur_frame_number + 1

2 USB Audio
2.1 I2S多声道
2.1.1 2声道I2S的pin定义
LRCK - 帧时钟,左右声道切换频率,高(右声道)低(左声道)为一个周期;等于采样频率
BCLK - bit位时钟,等于采样频率 x SDATA声道数 x 采样bit数
SDATA - 串行数据,左右声道

2.1.2 多声道I2S的pin定义
实现一:
有多路的SDATA线,每线上可以传输两声道的信号,公用LRCLK、BCLK等。代表产品XMOS芯片(ex-INMOS,International NMOS)。
LRCK - 帧时钟,左右声道切换频率,高(右声道)低(左声道)为一个周期;等于采样频率
BCLK - bit位时钟,等于采样频率 x SDATA1声道数 x 采样bit数
SDATA1 - 串行数据,声道1和2
SDATA2 - 串行数据,声道3和4
SDATA3 - 串行数据,声道5和6

实现二:
将I2S配置成TDM(时分复用,主要是车机用),I2S的SDATA只能传输2声道,但是配成TDM后SDATA却可以支持多声道,代表产品NXP LPC5460x

2.2 USB多声道
- UAC1.0最高只支持到双声道192Khz 16bit的音源
- UAC2.0可以最高支持15声道384Khz 32bit的音源
1)只有一个playback接口(stream interface),该接口的一个ISO endpoint实现多声道(声道数bNrChannels和空间位置位图配置bmChannelConfig),代表产品XMOS USB声卡

2.3 ADC和DAC需求
- ADC的每个channel传输一个声道的数据,例如5.1声道录音就需要6个channel的ADC
- DAC的每个channel传输一个声道的数据,例如5.1声道放音就需要6个channel的DAC

2.4 USB FS ISO最大包尺寸
Table 5-4. Full-speed Isochronous Transaction Limits from the USB 2.0 standard
传输一帧ISO报文后(1023 + 9 overhead),每帧剩余字节数为468 = 1500 - 1032;而High-speed的overhead等于偶数。
UAC1: 1023 bytes
UAC2: 1024 bytes

48KHz/16bit/2ch,则每1ms(+/-500ns)的数据量为48个采样,也即是1ms可以分成48个等份,每个等份的间隔是20.83us(= 1/48KHz),1ms传输的数据量为192字节。
ISO urb->interval = pow(2, (bInterval - 1))
qh->period == urb->interval
0 <= qh->phase <= qh->period - 1
USB ISO start_frame = current_frame_number + 10 + phase_correction
AVB Class C的调度间隔是1.3333ms,每个间隔分成64等份,每个等份的时间是20.83us(= 1/48KHz)。

2.5 Feedback Endpoint
UAC反馈端点实际反应的是当前音频设备的采样率。
UAC 1.0 10.14 (full-speed and high-speed)
feedbackValue = ((curSampleFrequency / 1000) << 14) | ((curSampleFrequency % 1000) << 4)
UAC 2.0 16.16 (high-speed)
feedbackValue = ((curSampleFrequency / 1000) << 13) | ((curSampleFrequency % 1000) << 3)

MP3解码库for MCU:helix库

2.6 ALSA PCM插件
aplay -D plughw:0,0 xxx.wav
plughw后面的0,0指的是声卡id和设备id,(card0,device0),对应到/dev/snd/pcmCxDyp,使用aplay -l查找。
hw: accesses the hardware device directly.
plughw: inserts sample rate and format conversion plugins, if needed.

1)ALSA plugin库和配置文件之间的名字关系规则:libasound_module_pcm_xxx.so,这里的xxx对应conf文件中pcm.xxx {}。ALSA工具使用-D xxx就会使用配置文件中的pcm.xxx {}内容。
2)2个重要plugin:hw和plug。
3)showcase
pcm子参数名xxx可以通过‘.’定义也可以用花括号定义。
pcm.!default { type hw card 0 }
感叹号使得原来的pcm.default定义被覆盖。
pcm.?default { type hw card 1 }
问号会忽略掉参数值已经存在的参数。定义第一个设备的第二个声卡作为default device,但是如果default在之前已经定义过,那么这个声明无效。
4)调整widget的上下电顺序,从而修复pop音问题。
5)Linux /dev/snd/pcm*是支持多声道的,查下pcm节点支持最大ch数是多少,设置ch数就可以了,只要在范围内就没问题。
6)AVB的调度间隔对应到ALSA的period中断。

3 Android audio underrun
当检测到当前写入音频数据的时间与上次出现警告的时间间隔大于预定的最大时间间隔(5秒)后,系统将判定音频播放过程出现了underrun。然后系统会调用usleep()函数对当前 PlaybackThread进行短时间阻塞,这样上层APP就能为 PlaybackThread准备好更多音频数据。这个usleep()的时长是根据相邻2次写入音频数据的时间间隔实时计算出的。

4 Tools
Cubase

你可能感兴趣的:(USB,ESS,Zoran,UAC2)