UAC Host

UAC Host 流程

UACFM1.png

代码流程都是类似的找到sound/usb/pcm.c文件里的struct snd_pcm_ops 结构体,相关回调都在这里:

1
2
3
4
5
6
7
8
9
10
11
static const struct snd_pcm_ops snd_usb_playback_ops = {
.open = snd_usb_pcm_open,
.close = snd_usb_pcm_close,
.hw_params = snd_usb_pcm_hw_params,
.hw_free = snd_usb_pcm_hw_free,
.prepare = snd_usb_pcm_prepare,
.trigger = snd_usb_substream_playback_trigger,
.sync_stop = snd_usb_pcm_sync_stop,
.pointer = snd_usb_pcm_pointer,
.ack = snd_usb_pcm_playback_ack,
};

主要关注下snd_usb_substream_playback_trigger函数,收到SNDRV_PCM_TRIGGER_START消息后会调用start_endpoints(subs);将usb 端点启动,然后注册端点操作函数指针,主要有两个:prepare_data_urb 和retire_data_urb 其中

  • prepare_data_urb 就是负责将alsa hw buffer里的数据搬运到urb ring buffer里,usb控制器会将该ring buffer里的数据送到usb总线发送出去
  • retire_data_urb 是usb传输完成后的回调函数,可以不用关心

Pipeline

以下是之前通过打印时间戳的方式统计的数据,实际存在一些偏差。 UACFM2.png

UAC Device

UACFM3.png

这是UAC Device驱动框架,实际只需要关注两个文件即可,

  • drivers/usb/gadget/function/f_uac2.c:该文件主要提供usb配置描述符、端点描述符、拓扑关系的描述以及UAC参数处理
  • drivers/usb/gadget/function/u_audio.c:该文件主要负责uac 声卡启动、停止、数据流管理等,这个文件需要关注的点如下:
    • u_audio_start_playback/u_audio_stop_playback:uac device 开始/停止播放声音函数
    • u_audio_start_capture/u_audio_stop_capture:uac device开始/停止录制声音的函数
    • u_audio_iso_complete:uac收发回调函数,uac所有接收和发送数据都调用该函数,latency问题主要关注该函数。
      • uac发送数据时,该函数里将alsa hw buffer里的数据memcpy到urb buffer中
      • uac接收数据时,该函数将urb buffer里的数据memcpy到alsa hw buffer里
  • struct snd_pcm_ops uac_pcm_ops:该数据结果就是提供给alsa driver的open、close、triger、prepare等回调接口