Daniel P. Berrangé wrote: > On Sat, Jul 18, 2020 at 04:31:16PM +0400, Roman Bogorodskiy wrote: > > Extend <sound> device element to accept "soundDevice" > > sub-element which allows to map guest sound device to host > > sound device. > > > > Example > > > > <sound model='ich6'> > > <soundDevice playback='/dev/dsp0' recording='/dev/dsp0'/> > > </sound> > > IIUC, FreeBSD's audio subsystem is the classic OSS API ? The sound(4) manpage[1] claims it supports most of the OSS ioctls(). > > > > > The "playback" attribute points to the playback device, > > and "recording" attribute points to the recording device. > > I'm thinking about how we'll have to deal with QEMU's sound backend > options, and alignment with BHyve / FreeBSD. > > In QEMU there are multiple backends, OSS, ALSA, PulseAudio, SPICE, > VNC, and many more. The backends have many properties, and many > of the properties can be set separately for input and output. > > IIUC, QEMU can expose multiple sound devices to the guest too. > > I think this means that we can have a M:N relationship between > a sound device, and an audio backend, not just 1:1. > > Assuming I'm right about the M:N relationship, I assume that > of multiple cards all do playback concurrently, something > will have todo mixing of the streams ? How will that work > with audio capture, is only one card allowed to capture at > any time ? In case of FreeBSD, the sound driver does mixing on its own, i.e. you can boot multiple guests pointed to /dev/dsp0 and audio streams from these guests will be played properly. I didn't test capturing though. > I'm copying Gerd to confirm the above... > > Anyway, if we have M:N relation, then we'll need separate > configuration elements. > > So I think we'd need to allow something like this: > > <sound model='ich6'> > <audio id="audio0"/> > </sound> > > <sound model='ich6'> > <audio id="audio1"/> > </sound> > > <sound model='ich6'> > <audio id="audio1"/> > </sound> > > <audio type="oss" id="audio0"> > <input dev='/dev/dsp0'/> > <output dev='/dev/dsp0'/> > </audio> > > <audio type="spice" id="audio1"/> > > > Here we have one sound device connected to OSS, and two sound > devices connected to SPICE. > > > > > Signed-off-by: Roman Bogorodskiy <bogorodskiy@xxxxxxxxx> > > --- > > docs/schemas/domaincommon.rng | 15 +++++++++++++++ > > src/conf/domain_conf.c | 24 ++++++++++++++++++++++++ > > src/conf/domain_conf.h | 3 +++ > > 3 files changed, 42 insertions(+) > > > > diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng > > index a810f569c6..b11b3f2af6 100644 > > --- a/docs/schemas/domaincommon.rng > > +++ b/docs/schemas/domaincommon.rng > > @@ -4346,6 +4346,18 @@ > > </attribute> > > </element> > > </define> > > + <define name="soundDevice"> > > + <element name="soundDevice"> > > + <attribute name="playback"> > > + <text/> > > + </attribute> > > + <optional> > > + <attribute name="recording"> > > + <text/> > > + </attribute> > > + </optional> > > + </element> > > + </define> > > <define name="sound"> > > <element name="sound"> > > <attribute name="model"> > > @@ -4366,6 +4378,9 @@ > > <optional> > > <ref name="address"/> > > </optional> > > + <optional> > > + <ref name="soundDevice"/> > > + </optional> > > <zeroOrMore> > > <ref name="codec"/> > > </zeroOrMore> > > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > > index 7ecd2818b9..b678a2319d 100644 > > --- a/src/conf/domain_conf.c > > +++ b/src/conf/domain_conf.c > > @@ -2850,6 +2850,9 @@ void virDomainSoundDefFree(virDomainSoundDefPtr def) > > virDomainSoundCodecDefFree(def->codecs[i]); > > VIR_FREE(def->codecs); > > > > + VIR_FREE(def->playback); > > + VIR_FREE(def->recording); > > + > > VIR_FREE(def); > > } > > > > @@ -14984,6 +14987,8 @@ virDomainSoundDefParseXML(virDomainXMLOptionPtr xmlopt, > > virDomainSoundDefPtr def; > > VIR_XPATH_NODE_AUTORESTORE(ctxt); > > g_autofree char *model = NULL; > > + char *recording = NULL; > > + xmlNodePtr soundDeviceNode; > > > > if (VIR_ALLOC(def) < 0) > > return NULL; > > @@ -15024,6 +15029,14 @@ virDomainSoundDefParseXML(virDomainXMLOptionPtr xmlopt, > > } > > } > > > > + soundDeviceNode = virXPathNode("./soundDevice", ctxt); > > + if (soundDeviceNode) { > > + def->playback = virXMLPropString(soundDeviceNode, "playback"); > > + recording = virXMLPropString(soundDeviceNode, "recording"); > > + if (recording) > > + def->recording = recording; > > + } > > + > > if (virDomainDeviceInfoParseXML(xmlopt, node, &def->info, flags) < 0) > > goto error; > > > > @@ -15056,6 +15069,9 @@ virDomainSoundDefEquals(const virDomainSoundDef *a, > > !virDomainDeviceInfoAddressIsEqual(&a->info, &b->info)) > > return false; > > > > + if ((a->playback != b->playback) || (a->recording != b->recording)) > > + return false; > > + > > return true; > > } > > > > @@ -27284,6 +27300,14 @@ virDomainSoundDefFormat(virBufferPtr buf, > > for (i = 0; i < def->ncodecs; i++) > > virDomainSoundCodecDefFormat(&childBuf, def->codecs[i]); > > > > + if (def->playback) { > > + virBufferAsprintf(&childBuf, "<soundDevice playback='%s'", def->playback); > > + if (def->recording) > > + virBufferAsprintf(&childBuf, " recording='%s'/>\n", def->recording); > > + else > > + virBufferAddLit(&childBuf, "/>\n"); > > + } > > + > > if (virDomainDeviceInfoFormat(&childBuf, &def->info, flags) < 0) > > return -1; > > > > diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h > > index 241149af24..b501f48442 100644 > > --- a/src/conf/domain_conf.h > > +++ b/src/conf/domain_conf.h > > @@ -1415,6 +1415,9 @@ struct _virDomainSoundDef { > > > > size_t ncodecs; > > virDomainSoundCodecDefPtr *codecs; > > + > > + char *playback; > > + char *recording; > > }; > > > > typedef enum { > > -- > > 2.27.0 > > > > Regards, > Daniel > -- > |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| > |: https://libvirt.org -o- https://fstop138.berrange.com :| > |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :| > Roman Bogorodskiy
Attachment:
signature.asc
Description: PGP signature