conf: add coverage for all QEMU audio backend types

The current <audio> element only allows an "OSS" audio backend, as this
is all that BHyve needed. This is now extended to cover most QEMU audio
backends. These backends all have a variety of attributes they support,
but this initial impl does the bare minimum, relying on built-in
defaults for everything. The only QEMU backend omitted is "dsound" since
the libvirt QEMU driver is not built on Windows platforms.

The SDL audio driver names are based on the SDL 2.0 drivers. It is not
intended to support SDL 1.2 drivers.

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2021-02-23 17:50:21 +00:00
parent 8149518ee1
commit 915b637257
5 changed files with 312 additions and 33 deletions

View File

@ -6827,32 +6827,117 @@ Audio devices
~~~~~~~~~~~~~
A virtual audio device corresponds to a host audio backend that is mapped
to the guest sound device. :since:`Since 6.7.0, bhyve only`
to the guest sound device.
``type``
The required ``type`` attribute specifies audio backend type.
Currently, the only supported value is 'oss'.
Currently, the supported values are 'none', 'alsa', 'coreaudio',
'jack', 'oss', 'pulseaudio', 'sdl', 'spice', 'file'.
``id``
Integer id of the audio device. Must be greater than 0.
The 'oss' audio type supports additional configuration:
None audio backend
^^^^^^^^^^^^^^^^^^
The 'none' audio backend is a dummy backend that does not connect to
any host audio framework. It still allows a remote desktop server
like VNC to send and receive audio though. This is the default backend
when VNC graphics are enabled in QEMU.
:since:`Since 7.2.0, qemu`
ALSA audio backend
^^^^^^^^^^^^^^^^^^
The 'alsa' audio type uses the ALSA host audio device framework.
:since:`Since 7.2.0, qemu`
Coreaudio audio backend
^^^^^^^^^^^^^^^^^^^^^^^
The 'coreaudio' audio backend delegates to a CoreAudio host audio framework
for input and output on macOS.
:since:`Since 7.2.0, qemu`
Jack audio backend
^^^^^^^^^^^^^^^^^^
The 'jack' audio backend delegates to a Jack daemon for audio input
and output.
:since:`Since 7.2.0, qemu`
OSS audio backend
^^^^^^^^^^^^^^^^^
The 'oss' audio type uses the OSS host audio device framework.
The following additional attributes are permitted on the ``<input>``
and ``<output>`` elements
* ``dev``
Path to the host device node to connect the backend to. A hypervisor
specific default applies if not specified.
::
...
<devices>
<audio type='oss' id='1'>
<input dev='/dev/dsp0'/>
<output dev='/dev/dsp0'/>
</audio>
</devices>
<audio type='oss' id='1'>
<input dev='/dev/dsp0'/>
<output dev='/dev/dsp0'/>
</audio>
``input``
Input device. The required ``dev`` attribute specifies device path.
:since:`Since 6.7.0, bhyve; Since 7.2.0, qemu`
``output``
Output device. The required ``dev`` attribute specifies device path.
PulseAudio audio backend
^^^^^^^^^^^^^^^^^^^^^^^^
The 'pulseaudio' audio backend delegates to a PulseAudio daemon audio input
and output.
:since:`Since 7.2.0, qemu`
SDL audio backend
^^^^^^^^^^^^^^^^^
The 'sdl' audio backend delegates to the SDL library for audio input
and output.
The following additional attributes are permitted on the ``<audio>``
element
* ``driver``
SDL audio driver. The ``name`` attribute specifies SDL driver name,
one of 'esd', 'alsa', 'arts', 'pulseaudio'.
::
<audio type='sdl' id='1' driver='pulseaudio'/>
:since:`Since 7.2.0, qemu`
Spice audio backend
^^^^^^^^^^^^^^^^^^^
The 'spice' audio backend is similar to the 'none' backend in that
it does not connect to any host audio framework. It exclusively
allows a SPICE server to send and receive audio. This is the default
backend when SPICE graphics are enabled in QEMU.
:since:`Since 7.2.0, qemu`
File audio backend
^^^^^^^^^^^^^^^^^^
The 'file' audio backend is an output only driver which records
audio to a file. The file format is implementation defined, and
defaults to 'WAV' with QEMU.
:since:`Since 7.2.0, qemu`
:anchor:`<a id="elementsWatchdog"/>`

View File

@ -4532,23 +4532,77 @@
<attribute name="id">
<ref name="uint8"/>
</attribute>
<attribute name="type">
<choice>
<value>oss</value>
</choice>
</attribute>
<interleave>
<optional>
<element name="input">
<ref name="audiooss"/>
</element>
</optional>
<optional>
<element name="output">
<ref name="audiooss"/>
</element>
</optional>
</interleave>
<choice>
<group>
<attribute name="type">
<value>none</value>
</attribute>
</group>
<group>
<attribute name="type">
<value>alsa</value>
</attribute>
</group>
<group>
<attribute name="type">
<value>coreaudio</value>
</attribute>
</group>
<group>
<attribute name="type">
<value>jack</value>
</attribute>
</group>
<group>
<attribute name="type">
<choice>
<value>oss</value>
</choice>
</attribute>
<interleave>
<optional>
<element name="input">
<ref name="audiooss"/>
</element>
</optional>
<optional>
<element name="output">
<ref name="audiooss"/>
</element>
</optional>
</interleave>
</group>
<group>
<attribute name="type">
<value>pulseaudio</value>
</attribute>
</group>
<group>
<attribute name="type">
<value>sdl</value>
</attribute>
<optional>
<attribute name="driver">
<choice>
<value>esd</value>
<value>alsa</value>
<value>arts</value>
<value>pulseaudio</value>
</choice>
</attribute>
</optional>
</group>
<group>
<attribute name="type">
<value>spice</value>
</attribute>
</group>
<group>
<attribute name="type">
<value>file</value>
</attribute>
</group>
</choice>
</element>
</define>
<define name="watchdog">

View File

@ -524,11 +524,22 @@ bhyveBuildSoundArgStr(const virDomainDef *def G_GNUC_UNUSED,
break;
case VIR_DOMAIN_AUDIO_TYPE_LAST:
case VIR_DOMAIN_AUDIO_TYPE_NONE:
case VIR_DOMAIN_AUDIO_TYPE_ALSA:
case VIR_DOMAIN_AUDIO_TYPE_COREAUDIO:
case VIR_DOMAIN_AUDIO_TYPE_JACK:
case VIR_DOMAIN_AUDIO_TYPE_PULSEAUDIO:
case VIR_DOMAIN_AUDIO_TYPE_SDL:
case VIR_DOMAIN_AUDIO_TYPE_SPICE:
case VIR_DOMAIN_AUDIO_TYPE_FILE:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported audio backend '%s'"),
virDomainAudioTypeTypeToString(audio->type));
return -1;
case VIR_DOMAIN_AUDIO_TYPE_LAST:
default:
virReportEnumRangeError(virDomainAudioType, audio->type);
return -1;
}
}

View File

@ -736,7 +736,24 @@ VIR_ENUM_IMPL(virDomainSoundModel,
VIR_ENUM_IMPL(virDomainAudioType,
VIR_DOMAIN_AUDIO_TYPE_LAST,
"none",
"alsa",
"coreaudio",
"jack",
"oss",
"pulseaudio",
"sdl",
"spice",
"file",
);
VIR_ENUM_IMPL(virDomainAudioSDLDriver,
VIR_DOMAIN_AUDIO_SDL_DRIVER_LAST,
"",
"esd",
"alsa",
"arts",
"pulseaudio",
);
VIR_ENUM_IMPL(virDomainKeyWrapCipherName,
@ -2902,11 +2919,35 @@ virDomainAudioDefFree(virDomainAudioDefPtr def)
return;
switch ((virDomainAudioType) def->type) {
case VIR_DOMAIN_AUDIO_TYPE_NONE:
break;
case VIR_DOMAIN_AUDIO_TYPE_ALSA:
break;
case VIR_DOMAIN_AUDIO_TYPE_COREAUDIO:
break;
case VIR_DOMAIN_AUDIO_TYPE_JACK:
break;
case VIR_DOMAIN_AUDIO_TYPE_OSS:
virDomainAudioIOOSSFree(&def->backend.oss.input);
virDomainAudioIOOSSFree(&def->backend.oss.output);
break;
case VIR_DOMAIN_AUDIO_TYPE_PULSEAUDIO:
break;
case VIR_DOMAIN_AUDIO_TYPE_SDL:
break;
case VIR_DOMAIN_AUDIO_TYPE_SPICE:
break;
case VIR_DOMAIN_AUDIO_TYPE_FILE:
break;
case VIR_DOMAIN_AUDIO_TYPE_LAST:
break;
}
@ -13934,6 +13975,18 @@ virDomainAudioDefParseXML(virDomainXMLOptionPtr xmlopt G_GNUC_UNUSED,
outputNode = virXPathNode("./output", ctxt);
switch ((virDomainAudioType) def->type) {
case VIR_DOMAIN_AUDIO_TYPE_NONE:
break;
case VIR_DOMAIN_AUDIO_TYPE_ALSA:
break;
case VIR_DOMAIN_AUDIO_TYPE_COREAUDIO:
break;
case VIR_DOMAIN_AUDIO_TYPE_JACK:
break;
case VIR_DOMAIN_AUDIO_TYPE_OSS:
if (inputNode)
virDomainAudioOSSParse(&def->backend.oss.input, inputNode);
@ -13941,7 +13994,28 @@ virDomainAudioDefParseXML(virDomainXMLOptionPtr xmlopt G_GNUC_UNUSED,
virDomainAudioOSSParse(&def->backend.oss.output, outputNode);
break;
case VIR_DOMAIN_AUDIO_TYPE_PULSEAUDIO:
break;
case VIR_DOMAIN_AUDIO_TYPE_SDL: {
g_autofree char *driver = virXMLPropString(node, "driver");
if (driver &&
(def->backend.sdl.driver =
virDomainAudioSDLDriverTypeFromString(driver)) <= 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown SDL driver '%s'"), driver);
goto error;
}
break;
}
case VIR_DOMAIN_AUDIO_TYPE_SPICE:
case VIR_DOMAIN_AUDIO_TYPE_FILE:
break;
case VIR_DOMAIN_AUDIO_TYPE_LAST:
default:
virReportEnumRangeError(virDomainAudioType, def->type);
break;
}
@ -26413,11 +26487,44 @@ virDomainAudioDefFormat(virBufferPtr buf,
virBufferAsprintf(buf, "<audio id='%d' type='%s'", def->id, type);
switch (def->type) {
switch ((virDomainAudioType)def->type) {
case VIR_DOMAIN_AUDIO_TYPE_NONE:
break;
case VIR_DOMAIN_AUDIO_TYPE_ALSA:
break;
case VIR_DOMAIN_AUDIO_TYPE_COREAUDIO:
break;
case VIR_DOMAIN_AUDIO_TYPE_JACK:
break;
case VIR_DOMAIN_AUDIO_TYPE_OSS:
virDomainAudioOSSFormat(&def->backend.oss.input, &inputBuf);
virDomainAudioOSSFormat(&def->backend.oss.output, &outputBuf);
break;
case VIR_DOMAIN_AUDIO_TYPE_PULSEAUDIO:
break;
case VIR_DOMAIN_AUDIO_TYPE_SDL:
if (def->backend.sdl.driver)
virBufferAsprintf(buf, " driver='%s'",
virDomainAudioSDLDriverTypeToString(
def->backend.sdl.driver));
break;
case VIR_DOMAIN_AUDIO_TYPE_SPICE:
break;
case VIR_DOMAIN_AUDIO_TYPE_FILE:
break;
case VIR_DOMAIN_AUDIO_TYPE_LAST:
default:
virReportEnumRangeError(virDomainAudioType, def->type);
return -1;
}
virDomainAudioCommonFormat(&childBuf, &inputBuf, "input");

View File

@ -1446,11 +1446,29 @@ struct _virDomainSoundDef {
};
typedef enum {
VIR_DOMAIN_AUDIO_TYPE_NONE,
VIR_DOMAIN_AUDIO_TYPE_ALSA,
VIR_DOMAIN_AUDIO_TYPE_COREAUDIO,
VIR_DOMAIN_AUDIO_TYPE_JACK,
VIR_DOMAIN_AUDIO_TYPE_OSS,
VIR_DOMAIN_AUDIO_TYPE_PULSEAUDIO,
VIR_DOMAIN_AUDIO_TYPE_SDL,
VIR_DOMAIN_AUDIO_TYPE_SPICE,
VIR_DOMAIN_AUDIO_TYPE_FILE,
VIR_DOMAIN_AUDIO_TYPE_LAST
} virDomainAudioType;
typedef enum {
VIR_DOMAIN_AUDIO_SDL_DRIVER_DEFAULT,
VIR_DOMAIN_AUDIO_SDL_DRIVER_ESD,
VIR_DOMAIN_AUDIO_SDL_DRIVER_ALSA,
VIR_DOMAIN_AUDIO_SDL_DRIVER_ARTS,
VIR_DOMAIN_AUDIO_SDL_DRIVER_PULSEAUDIO,
VIR_DOMAIN_AUDIO_SDL_DRIVER_LAST
} virDomainAudioSDLDriver;
typedef struct _virDomainAudioIOOSS virDomainAudioIOOSS;
typedef virDomainAudioIOOSS *virDomainAudioIOOSSPtr;
struct _virDomainAudioIOOSS {
@ -1467,6 +1485,9 @@ struct _virDomainAudioDef {
virDomainAudioIOOSS input;
virDomainAudioIOOSS output;
} oss;
struct {
int driver; /* virDomainAudioSDLDriver */
} sdl;
} backend;
};
@ -3696,6 +3717,7 @@ VIR_ENUM_DECL(virDomainChrSpicevmc);
VIR_ENUM_DECL(virDomainSoundCodec);
VIR_ENUM_DECL(virDomainSoundModel);
VIR_ENUM_DECL(virDomainAudioType);
VIR_ENUM_DECL(virDomainAudioSDLDriver);
VIR_ENUM_DECL(virDomainKeyWrapCipherName);
VIR_ENUM_DECL(virDomainMemballoonModel);
VIR_ENUM_DECL(virDomainSmbiosMode);