[alsa-devel] ALSA device with slave clock

Takashi Sakamoto o-takashi at sakamocchi.jp
Mon Jan 15 03:06:06 CET 2018


Hi,

On Jan 15 2018 05:37, Jussi Laako wrote:
> 1) How is application supposed to use ALSA capture device when it 
> doesn't know the sampling rate? For example with ASIO on Windows 
> application sets sampling rate to 0 to indicate slave and then starts 
> the device and retrieves the rate using ASIOGetSampleRate(). There are 
> typically also reset request messages when the rate changes.

When delegating the desicion to ALSA PCM core, applications should set
'struct snd_pcm_hw_params.intervals[SNDRV_PCM_HW_PARAM_RATE]' for
'any' state (see 'snd_interval_any()' in 'src/pcm/interval_inline.h' of
alsa-lib), then call ioctl(2) with 'SNDRV_PCM_IOCTL_HW_PARAMS' command.
In this case, ALSA PCM core select the _minimum_ value of available
sampling rates supported by the driver. You can see the selection
process in 'snd_pcm_hw_params_choose()' in 'sound/core/pcm_native.c' of 
kernel source.

When applying restrictions to the available sampling rates, ALSA PCM
drivers are expected to describe relevant parameters on
'struct snd_pcm_hardware' properly when handling calls of open(2) to
any ALSA PCM character devices.

```
(include/sound/pcm.h)
struct snd_pcm_hardware {
   ...
   unsigned int rates;
   unsigned int rate_min;
   unsigned int rate_max;
   ...
};
```

Below is an example to limit available sampling rates just to 44100.

```
(In an implementation of 'struct snd_pcm_ops.open')
struct snd_pcm_hardware info;
...
info.rate_min = 44100;
info.rate_max = 44100;
info.rates = snd_pcm_rate_to_rate_bit(44100);
substream->runtime.hw = info;
...
```

You can see actual example in snd-dice driver in
'sound/firewire/dice/dice-pcm.c' ('limit_channels_and_rates()'). For
several reasons, this driver reads registers on target devices, then
limit sampling rate for ALSA PCM substream to actual supported sampling
rate. The state of device can be changed by the other applications, so
the driver dynamically change the restriction.

> 2) Some USB devices have indicator for lock status between set sampling 
> rate and detected input rate. One such device I have is Motu 8D (UAC2 
> device):
>      Simple mixer control 'Internal Clock Validity',0
>        Capabilities: pswitch pswitch-joined
>        Playback channels: Mono
>        Mono: Playback [on]
> As long as the status is valid, I can set sampling rate to the same, or 
> something else. When the status becomes invalid due to rate mismatch, 
> ALSA fails to set any of the sampling rates, even correct one and 
> there's an error message in dmesg: "usb 3-14: clock source 1 is not 
> valid, cannot use". So the clock source cannot be made valid again by 
> changing sampling rate once it has become invalid, because it is 
> currently invalid...

I've never read related codes for your device. In my opinion, current
'snd-usb-audio' doesn't handle such restriction correctly. In theory,
the driver should read state of the device, then applying the
restriction to runtime of the PCM substream when handling open(2) from
userspace applications, as I described.

> 3) What is the correct way to deal with clock slave device from both 
> driver and application perspective? So that application can retrieve the 
> current sampling rate, instead of setting one... UAC2 has provisions for 
> this, but this doesn't seem to be supported by the current driver. I 
> have also some hardware where I would like to do the same with I2S - 
> where clock generator is outside of the SoC and the SoC is just a slave 
> (for example S/PDIF or AES/EBU input to a SoC where clock is generated 
> from the input stream using PLL).

It's better for your driver to describe 'struct snd_pcm_hardware'
correctly, as I noted.

For the interaction between application/kernel-stuffs, this low-level
sample program may be good information to you.
https://github.com/takaswie/alsa-ioctl-test/blob/master/refine-pcm-params.c


Regards

Takashi Sakamoto


More information about the Alsa-devel mailing list