]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
conf: qemu: Add support for multi-channel mode for 'usb' sound cards
authorPeter Krempa <pkrempa@redhat.com>
Tue, 9 May 2023 11:10:30 +0000 (13:10 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 9 May 2023 13:12:03 +0000 (15:12 +0200)
Allow users controlling the multi-channel mode by adding a
'multichannel' property parsed for USB audio devices and wire up the
support in the qemu driver.

Closes: https://gitlab.com/libvirt/libvirt/-/issues/472
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
docs/formatdomain.rst
src/conf/domain_conf.c
src/conf/domain_conf.h
src/conf/schemas/domaincommon.rng
src/qemu/qemu_command.c
tests/qemuxml2argvdata/sound-device.x86_64-4.2.0.args
tests/qemuxml2argvdata/sound-device.x86_64-latest.args
tests/qemuxml2argvdata/sound-device.xml
tests/qemuxml2xmloutdata/sound-device.x86_64-latest.xml

index d62bda9adb3dac51ec0f1a64e4f2691b3924eb03..99383e725c363a7c3a2ab006dafb021a99be85ab 100644 (file)
@@ -7235,6 +7235,11 @@ Valid values are:
    </devices>
    ...
 
+:since:`Since 9.4.0` the ``usb`` sound device can be optionally switched into
+multi-channel mode by using the ``multichannel`` attribute::
+
+  <sound model='usb' multichannel='yes'/>
+
 Each ``sound`` element has an optional sub-element ``<address>`` which can tie
 the device to a particular PCI slot. See `Device Addresses`_.
 
index 204b6a85e124f5aac96dbb8f0d63f5c32d3e0a8b..6a864a8db9e7db999ab73dd0d5f8ecf95cfa1f79 100644 (file)
@@ -11689,6 +11689,12 @@ virDomainSoundDefParseXML(virDomainXMLOption *xmlopt,
         }
     }
 
+    if (def->model == VIR_DOMAIN_SOUND_MODEL_USB) {
+        if (virXMLPropTristateBool(node, "multichannel", VIR_XML_PROP_NONE,
+                                   &def->multichannel) < 0)
+            return NULL;
+    }
+
     audioNode = virXPathNode("./audio", ctxt);
     if (audioNode) {
         if (virXMLPropUInt(audioNode, "id", 10,
@@ -11721,6 +11727,9 @@ virDomainSoundDefEquals(const virDomainSoundDef *a,
             return false;
     }
 
+    if (a->multichannel != b->multichannel)
+        return false;
+
     if (a->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
         !virDomainDeviceInfoAddressIsEqual(&a->info, &b->info))
         return false;
@@ -20010,6 +20019,14 @@ virDomainSoundDefCheckABIStability(virDomainSoundDef *src,
         return false;
     }
 
+    if (src->multichannel != dst->multichannel) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Target sound card multichannel setting '%1$s' does not match source '%2$s'"),
+                       virTristateBoolTypeToString(dst->multichannel),
+                       virTristateBoolTypeToString(src->multichannel));
+        return false;
+    }
+
     if (!virDomainDeviceInfoCheckABIStability(&src->info, &dst->info))
         return false;
 
@@ -24531,6 +24548,12 @@ virDomainSoundDefFormat(virBuffer *buf,
 
     virBufferAsprintf(&attrBuf, " model='%s'",  model);
 
+    if (def->model == VIR_DOMAIN_SOUND_MODEL_USB &&
+        def->multichannel != VIR_TRISTATE_BOOL_ABSENT) {
+        virBufferAsprintf(&attrBuf, " multichannel='%s'",
+                          virTristateBoolTypeToString(def->multichannel));
+    }
+
     virXMLFormatElement(buf,  "sound", &attrBuf, &childBuf);
 
     return 0;
index a04f7decc69c8e721d3ba8d9018a412bc2104fb1..c1cb2ed69d8f1fabbe619b412d8a1fb0ac5b88e8 100644 (file)
@@ -1596,6 +1596,10 @@ struct _virDomainSoundDef {
     size_t ncodecs;
     virDomainSoundCodecDef **codecs;
 
+    /* VIR_DOMAIN_SOUND_MODEL_USB can be optionally switched to
+     * multi-channel mode */
+    virTristateBool multichannel;
+
     unsigned int audioId;
 };
 
index 57fb4a5e33adf7f0f30c0cf3d2ffb235e34a6072..f8c7b6a64854004adab12b0504facb51f7dddc63 100644 (file)
           <value>usb</value>
         </choice>
       </attribute>
+      <optional>
+        <attribute name="multichannel">
+          <ref name="virYesNo"/>
+        </attribute>
+      </optional>
       <interleave>
         <optional>
           <ref name="alias"/>
index dcad449413a58d29772f9664cd76358493d123f0..2a6d9408f6e264d4967918a26beb202138cdece3 100644 (file)
@@ -4384,6 +4384,7 @@ qemuBuildSoundDevCmd(virCommand *cmd,
     g_autoptr(virJSONValue) props = NULL;
     const char *model = NULL;
     g_autofree char *audioid = NULL;
+    virTristateBool multichannel = VIR_TRISTATE_BOOL_ABSENT;
 
     switch (sound->model) {
     case VIR_DOMAIN_SOUND_MODEL_ES1370:
@@ -4397,6 +4398,7 @@ qemuBuildSoundDevCmd(virCommand *cmd,
         break;
     case VIR_DOMAIN_SOUND_MODEL_USB:
         model = "usb-audio";
+        multichannel = sound->multichannel;
         break;
     case VIR_DOMAIN_SOUND_MODEL_ICH9:
         model = "ich9-intel-hda";
@@ -4419,6 +4421,7 @@ qemuBuildSoundDevCmd(virCommand *cmd,
                               "s:driver", model,
                               "s:id", sound->info.alias,
                               "S:audiodev", audioid,
+                              "T:multi", multichannel,
                               NULL) < 0)
         return -1;
 
index 121b37ff99d21c3e01a200a4faaefabba29cd007..b2a5afd8c88d5fd987e9cf7e8523718ce3e15bff 100644 (file)
@@ -44,7 +44,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
 -device hda-micro,id=sound7-codec0,bus=sound7.0,cad=0,audiodev=audio1 \
 -device hda-duplex,id=sound7-codec1,bus=sound7.0,cad=1,audiodev=audio1 \
 -device hda-output,id=sound7-codec2,bus=sound7.0,cad=2,audiodev=audio1 \
--device usb-audio,id=sound8,audiodev=audio1,bus=usb.0,port=1 \
+-device usb-audio,id=sound8,audiodev=audio1,multi=on,bus=usb.0,port=1 \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x8 \
 -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
 -msg timestamp=on
index 3132760fe044984d995877fee5685ae3448453f7..e0a2f21b319f515f776537f75a3d692b902bfab7 100644 (file)
@@ -44,7 +44,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
 -device '{"driver":"hda-micro","id":"sound7-codec0","bus":"sound7.0","cad":0,"audiodev":"audio1"}' \
 -device '{"driver":"hda-duplex","id":"sound7-codec1","bus":"sound7.0","cad":1,"audiodev":"audio1"}' \
 -device '{"driver":"hda-output","id":"sound7-codec2","bus":"sound7.0","cad":2,"audiodev":"audio1"}' \
--device '{"driver":"usb-audio","id":"sound8","audiodev":"audio1","bus":"usb.0","port":"1"}' \
+-device '{"driver":"usb-audio","id":"sound8","audiodev":"audio1","multi":true,"bus":"usb.0","port":"1"}' \
 -device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x8"}' \
 -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
 -msg timestamp=on
index 35a60da197c8652b680da418828eaf230913a278..c58033235c9f8f4d77cbf87c757b718964335bba 100644 (file)
@@ -34,7 +34,7 @@
       <codec type='duplex'/>
       <codec type='output'/>
     </sound>
-    <sound model='usb'/>
+    <sound model='usb' multichannel='yes'/>
     <memballoon model='virtio'/>
   </devices>
 </domain>
index 89f537bb018e3497b82dc91254e4272ee15d6819..29d700cebb4780a41bdb12bad5e842f9ca252d68 100644 (file)
@@ -52,7 +52,7 @@
       <codec type='output'/>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
     </sound>
-    <sound model='usb'/>
+    <sound model='usb' multichannel='yes'/>
     <audio id='1' type='none'/>
     <memballoon model='virtio'>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>