conf: add support for audio backend specific settings

This pulls in the remaining QEMU audio backend specific settings to the
XML schema.

    <audio id="1" type="alsa">
      <input dev="/dev/dsp0"/>
      <output dev="/dev/dsp1"/>
    </audio>

    <audio id="1" type="coreaudio">
      <input bufferCount="50"/>
      <output bufferCount="42"/>
    </audio>

    <audio id="1" type="file" path="audio.wav"/>

    <audio id="1" type="jack">
      <input serverName="fish" clientName="food" connectPorts="yum"/>
      <output serverName="fish" clientName="food" connectPorts="yum"/>
    </audio>

    <audio id="1" type="oss" tryMMap="yes" exclusive="yes" dspPolicy="3">
      <input dev="/dev/dsp0" bufferCount="50" tryPoll="yes"/>
      <output dev="/dev/dsp1" bufferCount="30" tryPoll="no"/>
    </audio>

    <audio id="1" type="pulseaudio" serverName="acme.example.org">
      <input name="fish" streamName="food" latency="100"/>
      <output name="fish" streamName="food" latency="200"/>
    </audio>

    <audio type='sdl' id='1' driver='pulseaudio'>
      <input bufferCount='40'/>
      <output bufferCount='40'/>
    </audio>

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-03-02 17:34:21 +00:00
parent c99e72d18d
commit 3e97d81a81
4 changed files with 566 additions and 28 deletions

View File

@ -6929,29 +6929,6 @@ 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
@ -6962,9 +6939,116 @@ and ``<output>`` elements
::
<audio type='oss' id='1'>
<input dev='/dev/dsp0'/>
<output dev='/dev/dsp0'/>
<audio id="1" type="alsa">
<input dev="/dev/dsp0"/>
<output dev="/dev/dsp1"/>
</audio>
: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.
The following additional attributes are permitted on the ``<input>``
and ``<output>`` elements
* ``bufferCount``
The number of buffers. It is recommended to set the ``bufferLength``
attribute at the same time.
::
<audio id="1" type="coreaudio">
<input bufferCount="50"/>
<output bufferCount="42"/>
</audio>
:since:`Since 7.2.0, qemu`
Jack audio backend
^^^^^^^^^^^^^^^^^^
The 'jack' audio backend delegates to a Jack daemon for audio input
and output.
The following additional attributes are permitted on the ``<input>``
and ``<output>`` elements
* ``serverName``
Select the Jack server instance to connect to.
* ``clientName``
The client name to identify as. The server may modify this to
ensure uniqueness unless ``exactName`` is enabled
* ``connectPorts``
A regular expression of Jack client port names to monitor and
connect to.
* ``exactName``
Use the exact ``clientName`` requested
::
<audio id="1" type="jack">
<input serverName="fish" clientName="food" connectPorts="system:capture_[13]" exactName="yes"/>
<output serverName="fish" clientName="food" connectPorts="system:playback_[13]" exactName="yes"/>
</audio>
: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 ``<audio>``
element
* ``tryMMap``
Attempt to use mmap for data transfer
* ``exclusive``
Enforce exclusive access to the host device
* ``dspPolicy``
Set the timing policy of the device, values between -1 and 10.
Smaller numbers result in lower latency but higher CPU usage.
A negatve value requests use of fragment mode.
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.
* ``bufferCount``
The number of buffers. It is recommended to set the ``bufferLength``
attribute at the same time.
* ``tryPoll``
Attempt to use polling mode
::
<audio type='oss' id='1' tryMMap='yes' exclusive='yes' dspPolicy='4'>
<input dev='/dev/dsp0' bufferCount='40' tryPoll='yes'/>
<output dev='/dev/dsp0' bufferCount='40' tryPoll='yes'/>
</audio>
:since:`Since 6.7.0, bhyve; Since 7.2.0, qemu`
@ -6975,6 +7059,35 @@ PulseAudio audio backend
The 'pulseaudio' audio backend delegates to a PulseAudio daemon audio input
and output.
The following additional attributes are permitted on the ``<audio>``
element
* ``serverName``
Hostname of the PulseAudio server
The following additional attributes are permitted on the ``<input>``
and ``<output>`` elements
* ``name``
The sink/source name to use
* ``streamName``
The name to identify the stream associated with the VM
* ``latency``
Desired latency for the server to target in microseconds
::
<audio id="1" type="pulseaudio" serverName="acme.example.org">
<input name="fish" streamName="food" latency="100"/>
<output name="fish" streamName="food" latency="200"/>
</audio>
:since:`Since 7.2.0, qemu`
SDL audio backend
@ -6991,9 +7104,20 @@ element
SDL audio driver. The ``name`` attribute specifies SDL driver name,
one of 'esd', 'alsa', 'arts', 'pulseaudio'.
The following additional attributes are permitted on the ``<input>``
and ``<output>`` elements
* ``bufferCount``
The number of buffers. It is recommended to set the ``bufferLength``
attribute at the same time.
::
<audio type='sdl' id='1' driver='pulseaudio'/>
<audio type='sdl' id='1' driver='pulseaudio'>
<input bufferCount='40'/>
<output bufferCount='40'/>
</audio>
:since:`Since 7.2.0, qemu`
@ -7005,6 +7129,10 @@ 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.
::
<audio type='spice' id='1'/>
:since:`Since 7.2.0, qemu`
File audio backend
@ -7014,6 +7142,10 @@ 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.
::
<audio id="1" type="file" path="audio.wav"/>
:since:`Since 7.2.0, qemu`
:anchor:`<a id="elementsWatchdog"/>`

View File

@ -4608,6 +4608,26 @@
<define name="audiojack">
<ref name="audiocommonattr"/>
<optional>
<attribute name="serverName">
<data type="string"/>
</attribute>
</optional>
<optional>
<attribute name="clientName">
<data type="string"/>
</attribute>
</optional>
<optional>
<attribute name="connectPorts">
<data type="string"/>
</attribute>
</optional>
<optional>
<attribute name="exactName">
<ref name="virYesNo"/>
</attribute>
</optional>
<ref name="audiocommonchild"/>
</define>
@ -4618,16 +4638,46 @@
<ref name="deviceName"/>
</attribute>
</optional>
<optional>
<attribute name="bufferCount">
<ref name="uint32"/>
</attribute>
</optional>
<optional>
<attribute name="tryPoll">
<ref name="virYesNo"/>
</attribute>
</optional>
<ref name="audiocommonchild"/>
</define>
<define name="audiopulseaudio">
<ref name="audiocommonattr"/>
<optional>
<attribute name="name">
<data type="string"/>
</attribute>
</optional>
<optional>
<attribute name="streamName">
<data type="string"/>
</attribute>
</optional>
<optional>
<attribute name="latency">
<ref name="uint32"/>
</attribute>
</optional>
<ref name="audiocommonchild"/>
</define>
<define name="audiosdl">
<ref name="audiocommonattr"/>
<optional>
<attribute name="bufferCount">
<ref name="uint32"/>
</attribute>
</optional>
<ref name="audiocommonchild"/>
</define>
@ -4721,6 +4771,21 @@
<value>oss</value>
</choice>
</attribute>
<optional>
<attribute name="tryMMap">
<ref name="virYesNo"/>
</attribute>
</optional>
<optional>
<attribute name="exclusive">
<ref name="virYesNo"/>
</attribute>
</optional>
<optional>
<attribute name="dspPolicy">
<data type="int"/>
</attribute>
</optional>
<interleave>
<optional>
<element name="input">
@ -4738,6 +4803,11 @@
<attribute name="type">
<value>pulseaudio</value>
</attribute>
<optional>
<attribute name="serverName">
<data type="string"/>
</attribute>
</optional>
<interleave>
<optional>
<element name="input">
@ -4799,6 +4869,11 @@
<attribute name="type">
<value>file</value>
</attribute>
<optional>
<attribute name="path">
<ref name="filePath"/>
</attribute>
</optional>
<interleave>
<optional>
<element name="input">

View File

@ -2918,12 +2918,33 @@ void virDomainSoundDefFree(virDomainSoundDefPtr def)
g_free(def);
}
static void
virDomainAudioIOALSAFree(virDomainAudioIOALSAPtr def)
{
g_free(def->dev);
}
static void
virDomainAudioIOJackFree(virDomainAudioIOJackPtr def)
{
g_free(def->serverName);
g_free(def->clientName);
g_free(def->connectPorts);
}
static void
virDomainAudioIOOSSFree(virDomainAudioIOOSSPtr def)
{
g_free(def->dev);
}
static void
virDomainAudioIOPulseAudioFree(virDomainAudioIOPulseAudioPtr def)
{
g_free(def->name);
g_free(def->streamName);
}
void
virDomainAudioDefFree(virDomainAudioDefPtr def)
{
@ -2935,12 +2956,16 @@ virDomainAudioDefFree(virDomainAudioDefPtr def)
break;
case VIR_DOMAIN_AUDIO_TYPE_ALSA:
virDomainAudioIOALSAFree(&def->backend.alsa.input);
virDomainAudioIOALSAFree(&def->backend.alsa.output);
break;
case VIR_DOMAIN_AUDIO_TYPE_COREAUDIO:
break;
case VIR_DOMAIN_AUDIO_TYPE_JACK:
virDomainAudioIOJackFree(&def->backend.jack.input);
virDomainAudioIOJackFree(&def->backend.jack.output);
break;
case VIR_DOMAIN_AUDIO_TYPE_OSS:
@ -2949,6 +2974,9 @@ virDomainAudioDefFree(virDomainAudioDefPtr def)
break;
case VIR_DOMAIN_AUDIO_TYPE_PULSEAUDIO:
virDomainAudioIOPulseAudioFree(&def->backend.pulseaudio.input);
virDomainAudioIOPulseAudioFree(&def->backend.pulseaudio.output);
g_free(def->backend.pulseaudio.serverName);
break;
case VIR_DOMAIN_AUDIO_TYPE_SDL:
@ -2958,6 +2986,7 @@ virDomainAudioDefFree(virDomainAudioDefPtr def)
break;
case VIR_DOMAIN_AUDIO_TYPE_FILE:
g_free(def->backend.file.path);
break;
case VIR_DOMAIN_AUDIO_TYPE_LAST:
@ -14046,12 +14075,118 @@ virDomainAudioCommonParse(virDomainAudioIOCommonPtr def,
}
static void
virDomainAudioALSAParse(virDomainAudioIOALSAPtr def,
xmlNodePtr node)
{
def->dev = virXMLPropString(node, "dev");
}
static int
virDomainAudioCoreAudioParse(virDomainAudioIOCoreAudioPtr def,
xmlNodePtr node)
{
g_autofree char *bufferCount = virXMLPropString(node, "bufferCount");
if (bufferCount &&
virStrToLong_ui(bufferCount, NULL, 10,
&def->bufferCount) < 0) {
virReportError(VIR_ERR_XML_ERROR,
_("cannot parse 'bufferCount' value '%s'"), bufferCount);
return -1;
}
return 0;
}
static int
virDomainAudioJackParse(virDomainAudioIOJackPtr def,
xmlNodePtr node)
{
g_autofree char *exactName = virXMLPropString(node, "exactName");
def->serverName = virXMLPropString(node, "serverName");
def->clientName = virXMLPropString(node, "clientName");
def->connectPorts = virXMLPropString(node, "connectPorts");
if (exactName &&
((def->exactName =
virTristateBoolTypeFromString(exactName)) <= 0)) {
virReportError(VIR_ERR_XML_ERROR,
_("unknown 'exactName' value '%s'"), exactName);
return -1;
}
return 0;
}
static int
virDomainAudioOSSParse(virDomainAudioIOOSSPtr def,
xmlNodePtr node)
{
g_autofree char *tryPoll = virXMLPropString(node, "tryPoll");
g_autofree char *bufferCount = virXMLPropString(node, "bufferCount");
def->dev = virXMLPropString(node, "dev");
if (tryPoll &&
((def->tryPoll =
virTristateBoolTypeFromString(tryPoll)) <= 0)) {
virReportError(VIR_ERR_XML_ERROR,
_("unknown 'tryPoll' value '%s'"), tryPoll);
return -1;
}
if (bufferCount &&
virStrToLong_ui(bufferCount, NULL, 10,
&def->bufferCount) < 0) {
virReportError(VIR_ERR_XML_ERROR,
_("cannot parse 'bufferCount' value '%s'"), bufferCount);
return -1;
}
return 0;
}
static int
virDomainAudioPulseAudioParse(virDomainAudioIOPulseAudioPtr def,
xmlNodePtr node)
{
g_autofree char *latency = virXMLPropString(node, "latency");
def->name = virXMLPropString(node, "name");
def->streamName = virXMLPropString(node, "streamName");
if (latency &&
virStrToLong_ui(latency, NULL, 10,
&def->latency) < 0) {
virReportError(VIR_ERR_XML_ERROR,
_("cannot parse 'latency' value '%s'"), latency);
return -1;
}
return 0;
}
static int
virDomainAudioSDLParse(virDomainAudioIOSDLPtr def,
xmlNodePtr node)
{
g_autofree char *bufferCount = virXMLPropString(node, "bufferCount");
if (bufferCount &&
virStrToLong_ui(bufferCount, NULL, 10,
&def->bufferCount) < 0) {
virReportError(VIR_ERR_XML_ERROR,
_("cannot parse 'bufferCount' value '%s'"), bufferCount);
return -1;
}
return 0;
}
@ -14109,22 +14244,69 @@ virDomainAudioDefParseXML(virDomainXMLOptionPtr xmlopt G_GNUC_UNUSED,
break;
case VIR_DOMAIN_AUDIO_TYPE_ALSA:
if (inputNode)
virDomainAudioALSAParse(&def->backend.alsa.input, inputNode);
if (outputNode)
virDomainAudioALSAParse(&def->backend.alsa.output, outputNode);
break;
case VIR_DOMAIN_AUDIO_TYPE_COREAUDIO:
if (inputNode)
virDomainAudioCoreAudioParse(&def->backend.coreaudio.input, inputNode);
if (outputNode)
virDomainAudioCoreAudioParse(&def->backend.coreaudio.output, outputNode);
break;
case VIR_DOMAIN_AUDIO_TYPE_JACK:
if (inputNode)
virDomainAudioJackParse(&def->backend.jack.input, inputNode);
if (outputNode)
virDomainAudioJackParse(&def->backend.jack.output, outputNode);
break;
case VIR_DOMAIN_AUDIO_TYPE_OSS:
case VIR_DOMAIN_AUDIO_TYPE_OSS: {
g_autofree char *tryMMap = virXMLPropString(node, "tryMMap");
g_autofree char *exclusive = virXMLPropString(node, "exclusive");
g_autofree char *dspPolicy = virXMLPropString(node, "dspPolicy");
if (tryMMap && ((def->backend.oss.tryMMap =
virTristateBoolTypeFromString(tryMMap)) <= 0)) {
virReportError(VIR_ERR_XML_ERROR,
_("unknown 'tryMMap' value '%s'"), tryMMap);
goto error;
}
if (exclusive && ((def->backend.oss.exclusive =
virTristateBoolTypeFromString(exclusive)) <= 0)) {
virReportError(VIR_ERR_XML_ERROR,
_("unknown 'exclusive' value '%s'"), exclusive);
goto error;
}
if (dspPolicy) {
if (virStrToLong_i(dspPolicy, NULL, 10,
&def->backend.oss.dspPolicy) < 0) {
virReportError(VIR_ERR_XML_ERROR,
_("cannot parse 'dspPolicy' value '%s'"), dspPolicy);
goto error;
}
def->backend.oss.dspPolicySet = true;
}
if (inputNode)
virDomainAudioOSSParse(&def->backend.oss.input, inputNode);
if (outputNode)
virDomainAudioOSSParse(&def->backend.oss.output, outputNode);
break;
}
case VIR_DOMAIN_AUDIO_TYPE_PULSEAUDIO:
def->backend.pulseaudio.serverName = virXMLPropString(node, "serverName");
if (inputNode)
virDomainAudioPulseAudioParse(&def->backend.pulseaudio.input, inputNode);
if (outputNode)
virDomainAudioPulseAudioParse(&def->backend.pulseaudio.output, outputNode);
break;
case VIR_DOMAIN_AUDIO_TYPE_SDL: {
@ -14136,6 +14318,11 @@ virDomainAudioDefParseXML(virDomainXMLOptionPtr xmlopt G_GNUC_UNUSED,
_("unknown SDL driver '%s'"), driver);
goto error;
}
if (inputNode)
virDomainAudioSDLParse(&def->backend.sdl.input, inputNode);
if (outputNode)
virDomainAudioSDLParse(&def->backend.sdl.output, outputNode);
break;
}
@ -14143,6 +14330,7 @@ virDomainAudioDefParseXML(virDomainXMLOptionPtr xmlopt G_GNUC_UNUSED,
break;
case VIR_DOMAIN_AUDIO_TYPE_FILE:
def->backend.file.path = virXMLPropString(node, "path");
break;
case VIR_DOMAIN_AUDIO_TYPE_LAST:
@ -26635,11 +26823,68 @@ virDomainAudioCommonFormat(virDomainAudioIOCommonPtr def,
}
}
static void
virDomainAudioALSAFormat(virDomainAudioIOALSAPtr def,
virBufferPtr buf)
{
virBufferEscapeString(buf, " dev='%s'", def->dev);
}
static void
virDomainAudioCoreAudioFormat(virDomainAudioIOCoreAudioPtr def,
virBufferPtr buf)
{
if (def->bufferCount)
virBufferAsprintf(buf, " bufferCount='%u'", def->bufferCount);
}
static void
virDomainAudioJackFormat(virDomainAudioIOJackPtr def,
virBufferPtr buf)
{
virBufferEscapeString(buf, " serverName='%s'", def->serverName);
virBufferEscapeString(buf, " clientName='%s'", def->clientName);
virBufferEscapeString(buf, " connectPorts='%s'", def->connectPorts);
if (def->exactName)
virBufferAsprintf(buf, " exactName='%s'",
virTristateBoolTypeToString(def->exactName));
}
static void
virDomainAudioOSSFormat(virDomainAudioIOOSSPtr def,
virBufferPtr buf)
{
virBufferEscapeString(buf, " dev='%s'", def->dev);
if (def->bufferCount)
virBufferAsprintf(buf, " bufferCount='%u'", def->bufferCount);
if (def->tryPoll)
virBufferAsprintf(buf, " tryPoll='%s'",
virTristateBoolTypeToString(def->tryPoll));
}
static void
virDomainAudioPulseAudioFormat(virDomainAudioIOPulseAudioPtr def,
virBufferPtr buf)
{
virBufferEscapeString(buf, " name='%s'", def->name);
virBufferEscapeString(buf, " streamName='%s'", def->streamName);
if (def->latency)
virBufferAsprintf(buf, " latency='%u'", def->latency);
}
static void
virDomainAudioSDLFormat(virDomainAudioIOSDLPtr def,
virBufferPtr buf)
{
if (def->bufferCount)
virBufferAsprintf(buf, " bufferCount='%u'", def->bufferCount);
}
@ -26665,20 +26910,40 @@ virDomainAudioDefFormat(virBufferPtr buf,
break;
case VIR_DOMAIN_AUDIO_TYPE_ALSA:
virDomainAudioALSAFormat(&def->backend.alsa.input, &inputBuf);
virDomainAudioALSAFormat(&def->backend.alsa.output, &outputBuf);
break;
case VIR_DOMAIN_AUDIO_TYPE_COREAUDIO:
virDomainAudioCoreAudioFormat(&def->backend.coreaudio.input, &inputBuf);
virDomainAudioCoreAudioFormat(&def->backend.coreaudio.output, &outputBuf);
break;
case VIR_DOMAIN_AUDIO_TYPE_JACK:
virDomainAudioJackFormat(&def->backend.jack.input, &inputBuf);
virDomainAudioJackFormat(&def->backend.jack.output, &outputBuf);
break;
case VIR_DOMAIN_AUDIO_TYPE_OSS:
if (def->backend.oss.tryMMap)
virBufferAsprintf(buf, " tryMMap='%s'",
virTristateBoolTypeToString(def->backend.oss.tryMMap));
if (def->backend.oss.exclusive)
virBufferAsprintf(buf, " exclusive='%s'",
virTristateBoolTypeToString(def->backend.oss.exclusive));
if (def->backend.oss.dspPolicySet)
virBufferAsprintf(buf, " dspPolicy='%d'", def->backend.oss.dspPolicy);
virDomainAudioOSSFormat(&def->backend.oss.input, &inputBuf);
virDomainAudioOSSFormat(&def->backend.oss.output, &outputBuf);
break;
case VIR_DOMAIN_AUDIO_TYPE_PULSEAUDIO:
virBufferEscapeString(buf, " serverName='%s'",
def->backend.pulseaudio.serverName);
virDomainAudioPulseAudioFormat(&def->backend.pulseaudio.input, &inputBuf);
virDomainAudioPulseAudioFormat(&def->backend.pulseaudio.output, &outputBuf);
break;
case VIR_DOMAIN_AUDIO_TYPE_SDL:
@ -26686,12 +26951,16 @@ virDomainAudioDefFormat(virBufferPtr buf,
virBufferAsprintf(buf, " driver='%s'",
virDomainAudioSDLDriverTypeToString(
def->backend.sdl.driver));
virDomainAudioSDLFormat(&def->backend.sdl.input, &inputBuf);
virDomainAudioSDLFormat(&def->backend.sdl.output, &outputBuf);
break;
case VIR_DOMAIN_AUDIO_TYPE_SPICE:
break;
case VIR_DOMAIN_AUDIO_TYPE_FILE:
virBufferEscapeString(buf, " path='%s'", def->backend.file.path);
break;
case VIR_DOMAIN_AUDIO_TYPE_LAST:

View File

@ -1494,11 +1494,47 @@ struct _virDomainAudioIOCommon {
unsigned int bufferLength; /* milliseconds */
};
typedef struct _virDomainAudioIOALSA virDomainAudioIOALSA;
typedef virDomainAudioIOALSA *virDomainAudioIOALSAPtr;
struct _virDomainAudioIOALSA {
char *dev;
};
typedef struct _virDomainAudioIOCoreAudio virDomainAudioIOCoreAudio;
typedef virDomainAudioIOCoreAudio *virDomainAudioIOCoreAudioPtr;
struct _virDomainAudioIOCoreAudio {
unsigned int bufferCount;
};
typedef struct _virDomainAudioIOJack virDomainAudioIOJack;
typedef virDomainAudioIOJack *virDomainAudioIOJackPtr;
struct _virDomainAudioIOJack {
char *serverName;
char *clientName;
char *connectPorts;
virTristateBool exactName;
};
typedef struct _virDomainAudioIOOSS virDomainAudioIOOSS;
typedef virDomainAudioIOOSS *virDomainAudioIOOSSPtr;
struct _virDomainAudioIOOSS {
char *dev;
unsigned int bufferCount;
virTristateBool tryPoll;
};
typedef struct _virDomainAudioIOPulseAudio virDomainAudioIOPulseAudio;
typedef virDomainAudioIOPulseAudio *virDomainAudioIOPulseAudioPtr;
struct _virDomainAudioIOPulseAudio {
char *name;
char *streamName;
unsigned int latency;
};
typedef struct _virDomainAudioIOSDL virDomainAudioIOSDL;
typedef virDomainAudioIOSDL *virDomainAudioIOSDLPtr;
struct _virDomainAudioIOSDL {
unsigned int bufferCount;
};
struct _virDomainAudioDef {
@ -1509,13 +1545,39 @@ struct _virDomainAudioDef {
virDomainAudioIOCommon input;
virDomainAudioIOCommon output;
union {
struct {
virDomainAudioIOALSA input;
virDomainAudioIOALSA output;
} alsa;
struct {
virDomainAudioIOCoreAudio input;
virDomainAudioIOCoreAudio output;
} coreaudio;
struct {
virDomainAudioIOJack input;
virDomainAudioIOJack output;
} jack;
struct {
virDomainAudioIOOSS input;
virDomainAudioIOOSS output;
virTristateBool tryMMap;
virTristateBool exclusive;
bool dspPolicySet;
int dspPolicy;
} oss;
struct {
virDomainAudioIOPulseAudio input;
virDomainAudioIOPulseAudio output;
char *serverName;
} pulseaudio;
struct {
virDomainAudioIOSDL input;
virDomainAudioIOSDL output;
int driver; /* virDomainAudioSDLDriver */
} sdl;
struct {
char *path;
} file;
} backend;
};