Takashi Sakamoto | d8b53bf | 2017-07-02 11:44:43 +0900 | [diff] [blame] | 1 | =================== |
| 2 | Tracepoints in ALSA |
| 3 | =================== |
| 4 | |
| 5 | 2017/07/02 |
| 6 | Takasahi Sakamoto |
| 7 | |
| 8 | Tracepoints in ALSA PCM core |
| 9 | ============================ |
| 10 | |
| 11 | ALSA PCM core registers ``snd_pcm`` subsystem to kernel tracepoint system. |
| 12 | This subsystem includes two categories of tracepoints; for state of PCM buffer |
| 13 | and for processing of PCM hardware parameters. These tracepoints are available |
| 14 | when corresponding kernel configurations are enabled. When ``CONFIG_SND_DEBUG`` |
| 15 | is enabled, the latter tracepoints are available. When additional |
| 16 | ``SND_PCM_XRUN_DEBUG`` is enabled too, the former trace points are enabled. |
| 17 | |
| 18 | Tracepoints for state of PCM buffer |
| 19 | ------------------------------------ |
| 20 | |
| 21 | This category includes four tracepoints; ``hwptr``, ``applptr``, ``xrun`` and |
| 22 | ``hw_ptr_error``. |
| 23 | |
| 24 | Tracepoints for processing of PCM hardware parameters |
| 25 | ----------------------------------------------------- |
| 26 | |
| 27 | This category includes two tracepoints; ``hw_mask_param`` and |
| 28 | ``hw_interval_param``. |
| 29 | |
| 30 | In a design of ALSA PCM core, data transmission is abstracted as PCM substream. |
| 31 | Applications manage PCM substream to maintain data transmission for PCM frames. |
| 32 | Before starting the data transmission, applications need to configure PCM |
| 33 | substream. In this procedure, PCM hardware parameters are decided by |
| 34 | interaction between applications and ALSA PCM core. Once decided, runtime of |
| 35 | the PCM substream keeps the parameters. |
| 36 | |
| 37 | The parameters are described in :c:type:`struct snd_pcm_hw_params`. This |
| 38 | structure includes several types of parameters. Applications set preferable |
| 39 | value to these parameters, then execute ioctl(2) with SNDRV_PCM_IOCTL_HW_REFINE |
| 40 | or SNDRV_PCM_IOCTL_HW_PARAMS. The former is used just for refining available |
| 41 | set of parameters. The latter is used for an actual decision of the parameters. |
| 42 | |
| 43 | The :c:type:`struct snd_pcm_hw_params` structure has below members: |
| 44 | |
| 45 | ``flags`` |
| 46 | Configurable. ALSA PCM core and some drivers handle this flag to select |
| 47 | convenient parameters or change their behaviour. |
| 48 | ``masks`` |
| 49 | Configurable. This type of parameter is described in |
| 50 | :c:type:`struct snd_mask` and represent mask values. As of PCM protocol |
| 51 | v2.0.13, three types are defined. |
| 52 | |
| 53 | - SNDRV_PCM_HW_PARAM_ACCESS |
| 54 | - SNDRV_PCM_HW_PARAM_FORMAT |
| 55 | - SNDRV_PCM_HW_PARAM_SUBFORMAT |
| 56 | ``intervals`` |
| 57 | Configurable. This type of parameter is described in |
| 58 | :c:type:`struct snd_interval` and represent values with a range. As of |
| 59 | PCM protocol v2.0.13, twelve types are defined. |
| 60 | |
| 61 | - SNDRV_PCM_HW_PARAM_SAMPLE_BITS |
| 62 | - SNDRV_PCM_HW_PARAM_FRAME_BITS |
| 63 | - SNDRV_PCM_HW_PARAM_CHANNELS |
| 64 | - SNDRV_PCM_HW_PARAM_RATE |
| 65 | - SNDRV_PCM_HW_PARAM_PERIOD_TIME |
| 66 | - SNDRV_PCM_HW_PARAM_PERIOD_SIZE |
| 67 | - SNDRV_PCM_HW_PARAM_PERIOD_BYTES |
| 68 | - SNDRV_PCM_HW_PARAM_PERIODS |
| 69 | - SNDRV_PCM_HW_PARAM_BUFFER_TIME |
| 70 | - SNDRV_PCM_HW_PARAM_BUFFER_SIZE |
| 71 | - SNDRV_PCM_HW_PARAM_BUFFER_BYTES |
| 72 | - SNDRV_PCM_HW_PARAM_TICK_TIME |
| 73 | ``rmask`` |
| 74 | Configurable. This is evaluated at ioctl(2) with |
| 75 | SNDRV_PCM_IOCTL_HW_REFINE only. Applications can select which |
| 76 | mask/interval parameter can be changed by ALSA PCM core. For |
| 77 | SNDRV_PCM_IOCTL_HW_PARAMS, this mask is ignored and all of parameters |
| 78 | are going to be changed. |
| 79 | ``cmask`` |
| 80 | Read-only. After returning from ioctl(2), buffer in user space for |
| 81 | :c:type:`struct snd_pcm_hw_params` includes result of each operation. |
| 82 | This mask represents which mask/interval parameter is actually changed. |
| 83 | ``info`` |
| 84 | Read-only. This represents hardware/driver capabilities as bit flags |
| 85 | with SNDRV_PCM_INFO_XXX. Typically, applications execute ioctl(2) with |
| 86 | SNDRV_PCM_IOCTL_HW_REFINE to retrieve this flag, then decide candidates |
| 87 | of parameters and execute ioctl(2) with SNDRV_PCM_IOCTL_HW_PARAMS to |
| 88 | configure PCM substream. |
| 89 | ``msbits`` |
| 90 | Read-only. This value represents available bit width in MSB side of |
| 91 | a PCM sample. When a parameter of SNDRV_PCM_HW_PARAM_SAMPLE_BITS was |
| 92 | decided as a fixed number, this value is also calculated according to |
| 93 | it. Else, zero. But this behaviour depends on implementations in driver |
| 94 | side. |
| 95 | ``rate_num`` |
| 96 | Read-only. This value represents numerator of sampling rate in fraction |
| 97 | notation. Basically, when a parameter of SNDRV_PCM_HW_PARAM_RATE was |
| 98 | decided as a single value, this value is also calculated according to |
| 99 | it. Else, zero. But this behaviour depends on implementations in driver |
| 100 | side. |
| 101 | ``rate_den`` |
| 102 | Read-only. This value represents denominator of sampling rate in |
| 103 | fraction notation. Basically, when a parameter of |
| 104 | SNDRV_PCM_HW_PARAM_RATE was decided as a single value, this value is |
| 105 | also calculated according to it. Else, zero. But this behaviour depends |
| 106 | on implementations in driver side. |
| 107 | ``fifo_size`` |
| 108 | Read-only. This value represents the size of FIFO in serial sound |
| 109 | interface of hardware. Basically, each driver can assigns a proper |
| 110 | value to this parameter but some drivers intentionally set zero with |
| 111 | a care of hardware design or data transmission protocol. |
| 112 | |
| 113 | ALSA PCM core handles buffer of :c:type:`struct snd_pcm_hw_params` when |
| 114 | applications execute ioctl(2) with SNDRV_PCM_HW_REFINE or SNDRV_PCM_HW_PARAMS. |
| 115 | Parameters in the buffer are changed according to |
| 116 | :c:type:`struct snd_pcm_hardware` and rules of constraints in the runtime. The |
| 117 | structure describes capabilities of handled hardware. The rules describes |
| 118 | dependencies on which a parameter is decided according to several parameters. |
| 119 | A rule has a callback function, and drivers can register arbitrary functions |
| 120 | to compute the target parameter. ALSA PCM core registers some rules to the |
| 121 | runtime as a default. |
| 122 | |
| 123 | Each driver can join in the interaction as long as it prepared for two stuffs |
| 124 | in a callback of :c:type:`struct snd_pcm_ops.open`. |
| 125 | |
| 126 | 1. In the callback, drivers are expected to change a member of |
| 127 | :c:type:`struct snd_pcm_hardware` type in the runtime, according to |
| 128 | capacities of corresponding hardware. |
| 129 | 2. In the same callback, drivers are also expected to register additional rules |
| 130 | of constraints into the runtime when several parameters have dependencies |
| 131 | due to hardware design. |
| 132 | |
| 133 | The driver can refers to result of the interaction in a callback of |
| 134 | :c:type:`struct snd_pcm_ops.hw_params`, however it should not change the |
| 135 | content. |
| 136 | |
| 137 | Tracepoints in this category are designed to trace changes of the |
| 138 | mask/interval parameters. When ALSA PCM core changes them, ``hw_mask_param`` or |
| 139 | ``hw_interval_param`` event is probed according to type of the changed parameter. |
| 140 | |
| 141 | ALSA PCM core also has a pretty print format for each of the tracepoints. Below |
| 142 | is an example for ``hw_mask_param``. |
| 143 | |
| 144 | :: |
| 145 | |
| 146 | hw_mask_param: pcmC0D0p 001/023 FORMAT 00000000000000000000001000000044 00000000000000000000001000000044 |
| 147 | |
| 148 | |
| 149 | Below is an example for ``hw_interval_param``. |
| 150 | |
| 151 | :: |
| 152 | |
| 153 | hw_interval_param: pcmC0D0p 000/023 BUFFER_SIZE 0 0 [0 4294967295] 0 1 [0 4294967295] |
| 154 | |
| 155 | The first three fields are common. They represent name of ALSA PCM character |
| 156 | device, rules of constraint and name of the changed parameter, in order. The |
| 157 | field for rules of constraint consists of two sub-fields; index of applied rule |
| 158 | and total number of rules added to the runtime. As an exception, the index 000 |
| 159 | means that the parameter is changed by ALSA PCM core, regardless of the rules. |
| 160 | |
| 161 | The rest of field represent state of the parameter before/after changing. These |
| 162 | fields are different according to type of the parameter. For parameters of mask |
| 163 | type, the fields represent hexadecimal dump of content of the parameter. For |
| 164 | parameters of interval type, the fields represent values of each member of |
| 165 | ``empty``, ``integer``, ``openmin``, ``min``, ``max``, ``openmax`` in |
| 166 | :c:type:`struct snd_interval` in this order. |
| 167 | |
| 168 | Tracepoints in drivers |
| 169 | ====================== |
| 170 | |
| 171 | Some drivers have tracepoints for developers' convenience. For them, please |
| 172 | refer to each documentation or implementation. |