ALSA 中的跟踪点

2017/07/02 Takasahi Sakamoto

ALSA PCM 核心中的跟踪点

ALSA PCM 核心向内核跟踪点系统注册 snd_pcm 子系统。此子系统包括两类跟踪点;用于 PCM 缓冲区状态和用于处理 PCM 硬件参数。当启用相应的内核配置时,这些跟踪点可用。当启用 CONFIG_SND_DEBUG 时,后一类跟踪点可用。当同时启用额外的 SND_PCM_XRUN_DEBUG 时,前一类跟踪点将启用。

用于 PCM 缓冲区状态的跟踪点

此类包含四个跟踪点;hwptrapplptrxrunhw_ptr_error

用于处理 PCM 硬件参数的跟踪点

此类包含两个跟踪点;hw_mask_paramhw_interval_param

在 ALSA PCM 核心的设计中,数据传输被抽象为 PCM 子流。应用程序管理 PCM 子流以维护 PCM 帧的数据传输。在开始数据传输之前,应用程序需要配置 PCM 子流。在此过程中,PCM 硬件参数由应用程序和 ALSA PCM 核心之间的交互决定。一旦确定,PCM 子流的运行时将保持这些参数。

这些参数在 struct snd_pcm_hw_params 中描述。此结构包括几种类型的参数。应用程序将首选值设置为这些参数,然后使用 SNDRV_PCM_IOCTL_HW_REFINE 或 SNDRV_PCM_IOCTL_HW_PARAMS 执行 ioctl(2)。前者仅用于优化可用的参数集。后者用于实际确定参数。

struct snd_pcm_hw_params 结构具有以下成员

flags

可配置。ALSA PCM 核心和一些驱动程序处理此标志以选择方便的参数或更改其行为。

masks

可配置。此类型的参数在 struct snd_mask 中描述,并表示掩码值。截至 PCM 协议 v2.0.13,定义了三种类型。

  • SNDRV_PCM_HW_PARAM_ACCESS

  • SNDRV_PCM_HW_PARAM_FORMAT

  • SNDRV_PCM_HW_PARAM_SUBFORMAT

intervals

可配置。此类型的参数在 struct snd_interval 中描述,并表示具有范围的值。截至 PCM 协议 v2.0.13,定义了十二种类型。

  • SNDRV_PCM_HW_PARAM_SAMPLE_BITS

  • SNDRV_PCM_HW_PARAM_FRAME_BITS

  • SNDRV_PCM_HW_PARAM_CHANNELS

  • SNDRV_PCM_HW_PARAM_RATE

  • SNDRV_PCM_HW_PARAM_PERIOD_TIME

  • SNDRV_PCM_HW_PARAM_PERIOD_SIZE

  • SNDRV_PCM_HW_PARAM_PERIOD_BYTES

  • SNDRV_PCM_HW_PARAM_PERIODS

  • SNDRV_PCM_HW_PARAM_BUFFER_TIME

  • SNDRV_PCM_HW_PARAM_BUFFER_SIZE

  • SNDRV_PCM_HW_PARAM_BUFFER_BYTES

  • SNDRV_PCM_HW_PARAM_TICK_TIME

rmask

可配置。仅在执行带有 SNDRV_PCM_IOCTL_HW_REFINE 的 ioctl(2) 时对其进行评估。应用程序可以选择 ALSA PCM 核心可以更改哪些掩码/间隔参数。对于 SNDRV_PCM_IOCTL_HW_PARAMS,将忽略此掩码,并且将更改所有参数。

cmask

只读。从 ioctl(2) 返回后,用户空间中用于 struct snd_pcm_hw_params 的缓冲区包含每次操作的结果。此掩码表示实际更改了哪些掩码/间隔参数。

info

只读。这表示硬件/驱动程序功能,作为带有 SNDRV_PCM_INFO_XXX 的位标志。通常,应用程序执行带有 SNDRV_PCM_IOCTL_HW_REFINE 的 ioctl(2) 来检索此标志,然后确定参数的候选者,并执行带有 SNDRV_PCM_IOCTL_HW_PARAMS 的 ioctl(2) 来配置 PCM 子流。

msbits

只读。此值表示 PCM 采样 MSB 侧的可用位宽。当 SNDRV_PCM_HW_PARAM_SAMPLE_BITS 的参数被确定为固定数字时,此值也会根据该值计算。否则,为零。但是此行为取决于驱动程序端的实现。

rate_num

只读。此值表示采样率的分数表示法的分子。基本上,当 SNDRV_PCM_HW_PARAM_RATE 的参数被确定为单个值时,此值也会根据该值计算。否则,为零。但是此行为取决于驱动程序端的实现。

rate_den

只读。此值表示采样率的分数表示法中的分母。基本上,当 SNDRV_PCM_HW_PARAM_RATE 的参数被确定为单个值时,此值也会根据该值计算。否则,为零。但是此行为取决于驱动程序端的实现。

fifo_size

只读。此值表示硬件串行声音接口中 FIFO 的大小。基本上,每个驱动程序都可以为此参数分配适当的值,但是一些驱动程序会出于硬件设计或数据传输协议的考虑而有意将其设置为零。

当应用程序执行带有 SNDRV_PCM_HW_REFINE 或 SNDRV_PCM_HW_PARAMS 的 ioctl(2) 时,ALSA PCM 核心会处理 struct snd_pcm_hw_params 的缓冲区。缓冲区中的参数会根据 struct snd_pcm_hardware 以及运行时的约束规则进行更改。该结构描述了所处理硬件的功能。这些规则描述了一个参数如何根据多个参数确定。规则具有回调函数,并且驱动程序可以注册任意函数来计算目标参数。ALSA PCM 核心默认向运行时注册一些规则。

只要驱动程序在 struct snd_pcm_ops.open 的回调中准备好两个方面,它就可以参与交互。

  1. 在回调中,驱动程序应根据相应硬件的容量更改运行时中 struct snd_pcm_hardware 类型的成员。

  2. 在同一回调中,当多个参数由于硬件设计而具有依赖关系时,驱动程序还应在运行时注册额外的约束规则。

驱动程序可以在 struct snd_pcm_ops.hw_params 的回调中引用交互结果,但不应更改内容。

此类别中的跟踪点旨在跟踪掩码/间隔参数的更改。当 ALSA PCM 核心更改它们时,会根据更改的参数类型探测 hw_mask_paramhw_interval_param 事件。

ALSA PCM 核心还为每个跟踪点提供了一个美观的打印格式。以下是 hw_mask_param 的示例。

hw_mask_param: pcmC0D0p 001/023 FORMAT 00000000000000000000001000000044 00000000000000000000001000000044

以下是 hw_interval_param 的示例。

hw_interval_param: pcmC0D0p 000/023 BUFFER_SIZE 0 0 [0 4294967295] 0 1 [0 4294967295]

前三个字段是通用的。它们按顺序表示 ALSA PCM 字符设备的名称、约束规则和更改的参数的名称。约束规则字段由两个子字段组成;应用规则的索引和添加到运行时的规则总数。作为例外,索引 000 表示参数是由 ALSA PCM 核心更改的,与规则无关。

其余字段表示更改前/后的参数状态。这些字段根据参数类型而有所不同。对于掩码类型的参数,这些字段表示参数内容的十六进制转储。对于间隔类型的参数,这些字段按顺序表示 struct snd_interval 中 emptyintegeropenminminmaxopenmax 的每个成员的值。

驱动程序中的跟踪点

一些驱动程序具有用于开发人员方便的跟踪点。有关它们的信息,请参阅每个文档或实现。