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.