UAC音频端点大小设置
2025-12-03
本文链接为:http://www.usbzh.com/article/detail-1602.html ,欢迎转载,转载请附上本文链接。
UAC是麦克风和扬声器,其音频端点的大小代表每次传输的数据大小。
UAC音频数据使用同步传输,故也端点描述符的bInterval相关。
关于bInterval详细解释详见https://www.usbzh.com/article/detail-637.html
由于音频数据是使用的同步模式传输,故bInterval表示多信传输一次数据,其具体含义为多少个微帧周期获传输一次数据。
对于全速,每秒有1000个帧,而对于高速和超高速,由于微帧的存在,每秒有8000个微帧。而bInterval的计算含义为:
2^(N-1)个周期单位
- 1 1; 每个总线间隔传输数据。
- 2 2; 数据每隔一个总线间隔传输一次。
- 3 4; 每四个总线间隔传输一次数据。
- 4 8; 每八个总线间隔传输一次数据。
那么计算音频数据包每次传输的大小计算过程如下:
factor表示微帧的数量,为1000或8000。
那么 a = factor / 2^(bInterval-1) 表示多少个微帧传输一次数据。
每秒传输的最大数据 = 通道数 × 采样大小 × 采样率
那么每次传输的数据为总大小除以a
每秒传输的最大数据 除以 多少个微帧传输一次数据 表示每次传输的数据大小。
以上只是理论计算,实际由于除法,导致误差,故需要优化。

- srate:表示采样率
- ssize:表示采样字节数
- chl:表示通道数
- factor:表示每秒的帧数
那么括号内部表示每秒需要的采样数,+1表示向上取整。
这里强制向上+1取整,实际可以判断是否整除而决定是否向上取整。
linux5.10的USB GADGET f_uac1.c源代码如下:
static int set_ep_max_packet_size(const struct f_uac1_opts *opts,
struct usb_endpoint_descriptor *ep_desc,
enum usb_device_speed speed, bool is_playback)
{
int chmask, srate = 0, ssize;
u16 max_size_bw, max_size_ep;
unsigned int factor;
int i;
switch (speed) {
case USB_SPEED_FULL:
max_size_ep = 1023;//USB规范允许的等时端点最大包大小
factor = 1000; //全速USB微帧=1ms
break;
case USB_SPEED_HIGH://高速和超高速一致
fallthrough;
case USB_SPEED_SUPER:
max_size_ep = 1024;//USB规范允许的等时端点最大包大小
factor = 8000; // 高速USB微帧=125μs (1/8000秒)
break;
default:
return -EINVAL;
}
if (is_playback) {
chmask = opts->p_chmask;
for (i = 0; i < UAC_MAX_RATES; i++) {
if (opts->p_srates[i] == 0)
break;
if (opts->p_srates[i] > srate)
srate = opts->p_srates[i];
}
ssize = opts->p_ssize;
} else {
chmask = opts->c_chmask;
for (i = 0; i < UAC_MAX_RATES; i++) {
if (opts->c_srates[i] == 0)
break;
if (opts->c_srates[i] > srate)
srate = opts->c_srates[i];
}
ssize = opts->c_ssize;
}
//srate采样率 48000
//chmask 通道掩码,通过num_channels获取通道数
//sssize为每通道的采样字节数大小。2字节等
//ch * byte * fre = total 1s
// 每个微帧的采样数 (srate / (factor / (1 << (ep_desc->bInterval - 1)))) + 1
max_size_bw = num_channels(chmask) * ssize * ((srate / (factor / (1 << (ep_desc->bInterval - 1)))) + 1);
//不能超过协议规定的最大包大小
ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw, max_size_ep));
return 0;
}
本文链接为:http://www.usbzh.com/article/detail-1602.html ,欢迎转载,转载请附上本文链接。
HID人机交互QQ群:564808376
UAC音频QQ群:218581009
UVC相机QQ群:331552032
BOT&UASP大容量存储QQ群:258159197
STC-USB单片机QQ群:315457461
USB技术交流QQ群2:580684376
USB技术交流QQ群:952873936 USB技术交流3:1031974172
UAC规范(USB音频)





