On Wed, Jul 07, 2021 at 03:13:37PM +0100, Edd Barrett wrote:
> Hi,
> 
> This diff is an attempt to make identifying audio devices easier by
> giving each device a human-readable description that can be read from
> userspace (and without scraping dmesg).
> 
> This is implemented on a per-audio-device basis using a new `descr`
> interface to `audio_hw_if`. For now I've only implemented this on:
> 
>  - azalia(4), which uses the codec info, e.g. `Realtek ALC1150`
> 
>  - uaudio(4), which uses the USB vendor and model info, e.g.
>    `Logitech HD Pro Webcam C920`.
> 
> For drivers, which currently don't implement this interface, the
> description string defaults to the audio device node name, e.g.
> `uaudio2`.
> 
> The string is exposed to userspace via the AUDIO_GETDEV ioctl(2). I've
> reclaimed the space currently occupied by the (unused) `version` and
> `config` fields in `audio_device_t` and used it for a new `descr` field.
> Thus the size of `audio_device_t` remains the same for now.
> 
> I've also made audioctl(8) display the description string, e.g.:
> ```
> # audioctl                                                       
> name=azalia1
> descr=Realtek ALC1150
> ...
> # audioctl -f /dev/audioctl1 
> name=uaudio0
> descr=SteelSeries SteelSeries Arctis 
> ...
> ```
> 
> I'm hoping that later we can have sndiod read these strings and expose
> them to its clients. For example, I'd like for sndioctl(1) to allow
> choosing a device based on the device description string (instead of the
> sndio device index), and for xfce4-mixer to allow choosing a device via
> its description in the GUI using a drop-down box.
> 
> Diff follows.
> 

[...]

> @@ -4019,6 +4021,37 @@ azalia_set_nblks(void *v, int mode,
>               nblks = HDA_BDL_MAX;
>  
>       return nblks;
> +}
> +
> +void
> +azalia_descr(void *arg, char *descr, size_t len)
> +{
> +     azalia_t *az = arg;
> +     codec_t *codec;
> +     const char *vendor;
> +     char buf[MAX_AUDIO_DESCR_LEN];
> +     int i;
> +
> +     *descr = '\0';
> +     for (i = 0; i < az->ncodecs; i++) {

azalia(4) fetches all codecs, but uses (and supports) only one of
them. You should copy the name of the one in use, ie
az->codecs[az->codecno].

> +             codec = &az->codecs[i];
> +             /* adapted from azalia_print_codec() */
> +             if (codec->name == NULL) {
> +                     vendor = pci_findvendor(codec->vid >> 16);
> +                     if (vendor == NULL)
> +                             snprintf(buf, MAX_AUDIO_DESCR_LEN,
> +                                 "0x%04x/0x%04x", codec->vid >> 16,
> +                                 codec->vid & 0xffff);
> +                     else
> +                             snprintf(buf, MAX_AUDIO_DESCR_LEN, "%s/0x%04x",
> +                                 vendor, codec->vid & 0xffff);
> +             } else
> +                     snprintf(buf, MAX_AUDIO_DESCR_LEN, "%s", codec->name);
> +
> +             if (i > 0)
> +                     strlcat(descr, ", ", len);
> +             strlcat(descr, buf, len);
> +     }
>  }
>  
>  int
> Index: sys/sys/audioio.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/audioio.h,v
> retrieving revision 1.27
> diff -u -p -r1.27 audioio.h
> --- sys/sys/audioio.h 14 Sep 2016 06:12:20 -0000      1.27
> +++ sys/sys/audioio.h 7 Jul 2021 10:23:09 -0000
> @@ -76,10 +76,10 @@ struct audio_status {
>   * audio devices.
>   */
>  #define MAX_AUDIO_DEV_LEN    16
> +#define MAX_AUDIO_DESCR_LEN  32
>  typedef struct audio_device {
>       char name[MAX_AUDIO_DEV_LEN];
> -     char version[MAX_AUDIO_DEV_LEN];
> -     char config[MAX_AUDIO_DEV_LEN];
> +     char descr[MAX_AUDIO_DESCR_LEN]; /* device description string */
>  } audio_device_t;
>

The intent of the "name" field was to be human-readable as well. You
could just replace it. There's no benefit in having two fields for the
same thing.

Reply via email to