VirtualBox

source: vbox/trunk/include/VBox/vmm/pdmaudioifs.h@ 89342

Last change on this file since 89342 was 89342, checked in by vboxsync, 4 years ago

Audio: Removed unused PDMAUDIOFMT type and associated translators. bugref:9890

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 66.1 KB
Line 
1/** @file
2 * PDM - Pluggable Device Manager, Audio interfaces.
3 */
4
5/*
6 * Copyright (C) 2006-2020 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26/** @page pg_pdm_audio PDM Audio
27 *
28 * @section sec_pdm_audio_overview Audio architecture overview
29 *
30 * The audio architecture mainly consists of two PDM interfaces,
31 * PDMIAUDIOCONNECTOR and PDMIHOSTAUDIO.
32 *
33 * The PDMIAUDIOCONNECTOR interface is responsible of connecting a device
34 * emulation, such as SB16, AC'97 and HDA to one or multiple audio backend(s).
35 * Its API abstracts audio stream handling and I/O functions, device enumeration
36 * and so on.
37 *
38 * The PDMIHOSTAUDIO interface must be implemented by all audio backends to
39 * provide an abstract and common way of accessing needed functions, such as
40 * transferring output audio data for playing audio or recording input from the
41 * host.
42 *
43 * A device emulation can have one or more LUNs attached to it, whereas these
44 * LUNs in turn then all have their own PDMIAUDIOCONNECTOR, making it possible
45 * to connect multiple backends to a certain device emulation stream
46 * (multiplexing).
47 *
48 * An audio backend's job is to record and/or play audio data (depending on its
49 * capabilities). It highly depends on the host it's running on and needs very
50 * specific (host-OS-dependent) code. The backend itself only has very limited
51 * ways of accessing and/or communicating with the PDMIAUDIOCONNECTOR interface
52 * via callbacks, but never directly with the device emulation or other parts of
53 * the audio sub system.
54 *
55 *
56 * @section sec_pdm_audio_mixing Mixing
57 *
58 * The AUDIOMIXER API is optionally available to create and manage virtual audio
59 * mixers. Such an audio mixer in turn then can be used by the device emulation
60 * code to manage all the multiplexing to/from the connected LUN audio streams.
61 *
62 * Currently only input and output stream are supported. Duplex stream are not
63 * supported yet.
64 *
65 * This also is handy if certain LUN audio streams should be added or removed
66 * during runtime.
67 *
68 * To create a group of either input or output streams the AUDMIXSINK API can be
69 * used.
70 *
71 * For example: The device emulation has one hardware output stream (HW0), and
72 * that output stream shall be available to all connected LUN backends. For that
73 * to happen, an AUDMIXSINK sink has to be created and attached to the device's
74 * AUDIOMIXER object.
75 *
76 * As every LUN has its own AUDMIXSTREAM object, adding all those
77 * objects to the just created audio mixer sink will do the job.
78 *
79 * @note The AUDIOMIXER API is purely optional and is not used by all currently
80 * implemented device emulations (e.g. SB16).
81 *
82 *
83 * @section sec_pdm_audio_data_processing Data processing
84 *
85 * Audio input / output data gets handed off to/from the device emulation in an
86 * unmodified (raw) way. The actual audio frame / sample conversion is done via
87 * the AUDIOMIXBUF API.
88 *
89 * This concentrates the audio data processing in one place and makes it easier
90 * to test / benchmark such code.
91 *
92 * A PDMAUDIOFRAME is the internal representation of a single audio frame, which
93 * consists of a single left and right audio sample in time. Only mono (1) and
94 * stereo (2) channel(s) currently are supported.
95 *
96 *
97 * @section sec_pdm_audio_timing Timing
98 *
99 * Handling audio data in a virtual environment is hard, as the human perception
100 * is very sensitive to the slightest cracks and stutters in the audible data.
101 * This can happen if the VM's timing is lagging behind or not within the
102 * expected time frame.
103 *
104 * The two main components which unfortunately contradict each other is a) the
105 * audio device emulation and b) the audio backend(s) on the host. Those need to
106 * be served in a timely manner to function correctly. To make e.g. the device
107 * emulation rely on the pace the host backend(s) set - or vice versa - will not
108 * work, as the guest's audio system / drivers then will not be able to
109 * compensate this accordingly.
110 *
111 * So each component, the device emulation, the audio connector(s) and the
112 * backend(s) must do its thing *when* it needs to do it, independently of the
113 * others. For that we use various (small) ring buffers to (hopefully) serve all
114 * components with the amount of data *when* they need it.
115 *
116 * Additionally, the device emulation can run with a different audio frame size,
117 * while the backends(s) may require a different frame size (16 bit stereo
118 * -> 8 bit mono, for example).
119 *
120 * The device emulation can give the audio connector(s) a scheduling hint
121 * (optional), e.g. in which interval it expects any data processing.
122 *
123 * A data transfer for playing audio data from the guest on the host looks like
124 * this: (RB = Ring Buffer, MB = Mixing Buffer)
125 *
126 * (A) Device DMA -> (B) Device RB -> (C) Audio Connector %Guest MB -> (D) Audio
127 * Connector %Host MB -> (E) Backend RB (optional, up to the backend) -> (F)
128 * Backend audio framework.
129 *
130 * When capturing audio data the chain is similar to the above one, just in a
131 * different direction, of course.
132 *
133 * The audio connector hereby plays a key role when it comes to (pre-)buffering
134 * data to minimize any audio stutters and/or cracks. The following values,
135 * which also can be tweaked via CFGM / extra-data are available:
136 *
137 * - The pre-buffering time (in ms): Audio data which needs to be buffered
138 * before any playback (or capturing) can happen.
139 * - The actual buffer size (in ms): How big the mixing buffer (for C and D)
140 * will be.
141 * - The period size (in ms): How big a chunk of audio (often called period or
142 * fragment) for F must be to get handled correctly.
143 *
144 * The above values can be set on a per-driver level, whereas input and output
145 * streams for a driver also can be handled set independently. The verbose audio
146 * (release) log will tell about the (final) state of each audio stream.
147 *
148 *
149 * @section sec_pdm_audio_diagram Diagram
150 *
151 * @todo r=bird: Not quite able to make sense of this, esp. the
152 * AUDMIXSINK/AUDIOMIXER bits crossing the LUN connections.
153 *
154 * @verbatim
155 +----------------------------------+
156 |Device (SB16 / AC'97 / HDA) |
157 |----------------------------------|
158 |AUDIOMIXER (Optional) |
159 |AUDMIXSINK0 (Optional) |
160 |AUDMIXSINK1 (Optional) |
161 |AUDMIXSINKn (Optional) |
162 | |
163 | L L L |
164 | U U U |
165 | N N N |
166 | 0 1 n |
167 +-----+----+----+------------------+
168 | | |
169 | | |
170 +--------------+ | | | +-------------+
171 |AUDMIXSINK | | | | |AUDIOMIXER |
172 |--------------| | | | |-------------|
173 |AUDMIXSTREAM0 |+-|----|----|-->|AUDMIXSINK0 |
174 |AUDMIXSTREAM1 |+-|----|----|-->|AUDMIXSINK1 |
175 |AUDMIXSTREAMn |+-|----|----|-->|AUDMIXSINKn |
176 +--------------+ | | | +-------------+
177 | | |
178 | | |
179 +----+----+----+----+
180 |LUN |
181 |-------------------|
182 |PDMIAUDIOCONNECTOR |
183 |AUDMIXSTREAM |
184 | +------+
185 | | |
186 | | |
187 | | |
188 +-------------------+ |
189 |
190 +-------------------------+ |
191 +-------------------------+ +----+--------------------+
192 |PDMAUDIOSTREAM | |PDMIAUDIOCONNECTOR |
193 |-------------------------| |-------------------------|
194 |AUDIOMIXBUF |+------>|PDMAUDIOSTREAM Host |
195 |PDMAUDIOSTREAMCFG |+------>|PDMAUDIOSTREAM Guest |
196 | | |Device capabilities |
197 | | |Device configuration |
198 | | | |
199 | | +--+|PDMIHOSTAUDIO |
200 | | | |+-----------------------+|
201 +-------------------------+ | ||Backend storage space ||
202 | |+-----------------------+|
203 | +-------------------------+
204 |
205 +---------------------+ |
206 |PDMIHOSTAUDIO | |
207 |+--------------+ | |
208 ||DirectSound | | |
209 |+--------------+ | |
210 | | |
211 |+--------------+ | |
212 ||PulseAudio | | |
213 |+--------------+ |+-------+
214 | |
215 |+--------------+ |
216 ||Core Audio | |
217 |+--------------+ |
218 | |
219 | |
220 | |
221 | |
222 +---------------------+
223 @endverbatim
224 */
225
226#ifndef VBOX_INCLUDED_vmm_pdmaudioifs_h
227#define VBOX_INCLUDED_vmm_pdmaudioifs_h
228#ifndef RT_WITHOUT_PRAGMA_ONCE
229# pragma once
230#endif
231
232#include <iprt/assertcompile.h>
233#include <iprt/critsect.h>
234#include <iprt/circbuf.h>
235#include <iprt/list.h>
236#include <iprt/path.h>
237
238#include <VBox/types.h>
239#include <VBox/vmm/pdmcommon.h>
240#include <VBox/vmm/stam.h>
241
242/** @defgroup grp_pdm_ifs_audio PDM Audio Interfaces
243 * @ingroup grp_pdm_interfaces
244 * @{
245 */
246
247#ifndef VBOX_AUDIO_DEBUG_DUMP_PCM_DATA_PATH
248# if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
249# define VBOX_AUDIO_DEBUG_DUMP_PCM_DATA_PATH "c:\\temp\\"
250# else
251# define VBOX_AUDIO_DEBUG_DUMP_PCM_DATA_PATH "/tmp/"
252# endif
253#endif
254
255/**
256 * Audio direction.
257 */
258typedef enum PDMAUDIODIR
259{
260 /** Invalid zero value as per usual (guards against using unintialized values). */
261 PDMAUDIODIR_INVALID = 0,
262 /** Unknown direction. */
263 PDMAUDIODIR_UNKNOWN,
264 /** Input. */
265 PDMAUDIODIR_IN,
266 /** Output. */
267 PDMAUDIODIR_OUT,
268 /** Duplex handling. */
269 PDMAUDIODIR_DUPLEX,
270 /** End of valid values. */
271 PDMAUDIODIR_END,
272 /** Hack to blow the type up to 32-bit. */
273 PDMAUDIODIR_32BIT_HACK = 0x7fffffff
274} PDMAUDIODIR;
275
276
277/** @name PDMAUDIOHOSTDEV_F_XXX
278 * @{ */
279/** No flags set. */
280#define PDMAUDIOHOSTDEV_F_NONE UINT32_C(0)
281/** The default input (capture/recording) device (for the user). */
282#define PDMAUDIOHOSTDEV_F_DEFAULT_IN RT_BIT_32(0)
283/** The default output (playback) device (for the user). */
284#define PDMAUDIOHOSTDEV_F_DEFAULT_OUT RT_BIT_32(1)
285/** The device can be removed at any time and we have to deal with it. */
286#define PDMAUDIOHOSTDEV_F_HOTPLUG RT_BIT_32(2)
287/** The device is known to be buggy and needs special treatment. */
288#define PDMAUDIOHOSTDEV_F_BUGGY RT_BIT_32(3)
289/** Ignore the device, no matter what. */
290#define PDMAUDIOHOSTDEV_F_IGNORE RT_BIT_32(4)
291/** The device is present but marked as locked by some other application. */
292#define PDMAUDIOHOSTDEV_F_LOCKED RT_BIT_32(5)
293/** The device is present but not in an alive state (dead). */
294#define PDMAUDIOHOSTDEV_F_DEAD RT_BIT_32(6)
295/** Set if the PDMAUDIOHOSTDEV::pszId is allocated. */
296#define PDMAUDIOHOSTDEV_F_ID_ALLOC RT_BIT_32(30)
297/** Set if the extra backend specific data cannot be duplicated. */
298#define PDMAUDIOHOSTDEV_F_NO_DUP RT_BIT_32(31)
299/** @} */
300
301/**
302 * Audio device type.
303 */
304typedef enum PDMAUDIODEVICETYPE
305{
306 /** Invalid zero value as per usual (guards against using unintialized values). */
307 PDMAUDIODEVICETYPE_INVALID = 0,
308 /** Unknown device type. This is the default. */
309 PDMAUDIODEVICETYPE_UNKNOWN,
310 /** Dummy device; for backends which are not able to report
311 * actual device information (yet). */
312 PDMAUDIODEVICETYPE_DUMMY,
313 /** The device is built into the host (non-removable). */
314 PDMAUDIODEVICETYPE_BUILTIN,
315 /** The device is an (external) USB device. */
316 PDMAUDIODEVICETYPE_USB,
317 /** End of valid values. */
318 PDMAUDIODEVICETYPE_END,
319 /** Hack to blow the type up to 32-bit. */
320 PDMAUDIODEVICETYPE_32BIT_HACK = 0x7fffffff
321} PDMAUDIODEVICETYPE;
322
323/**
324 * Host audio device info, part of enumeration result.
325 *
326 * @sa PDMAUDIOHOSTENUM, PDMIHOSTAUDIO::pfnGetDevices
327 */
328typedef struct PDMAUDIOHOSTDEV
329{
330 /** List entry (like PDMAUDIOHOSTENUM::LstDevices). */
331 RTLISTNODE ListEntry;
332 /** Magic value (PDMAUDIOHOSTDEV_MAGIC). */
333 uint32_t uMagic;
334 /** Size of this structure and whatever backend specific data that follows it. */
335 uint32_t cbSelf;
336 /** The device type. */
337 PDMAUDIODEVICETYPE enmType;
338 /** Usage of the device. */
339 PDMAUDIODIR enmUsage;
340 /** Device flags, PDMAUDIOHOSTDEV_F_XXX. */
341 uint32_t fFlags;
342 /** Maximum number of input audio channels the device supports. */
343 uint8_t cMaxInputChannels;
344 /** Maximum number of output audio channels the device supports. */
345 uint8_t cMaxOutputChannels;
346 uint8_t abAlignment[ARCH_BITS == 32 ? 2 + 12 : 2];
347 /** Backend specific device identifier, can be NULL, used to select device.
348 * This can either point into some non-public part of this structure or to a
349 * RTStrAlloc allocation. PDMAUDIOHOSTDEV_F_ID_ALLOC is set in the latter
350 * case.
351 * @sa PDMIHOSTAUDIO::pfnSetDevice */
352 char *pszId;
353 /** Friendly name of the device, if any. Could be truncated. */
354 char szName[64];
355} PDMAUDIOHOSTDEV;
356AssertCompileSizeAlignment(PDMAUDIOHOSTDEV, 16);
357/** Pointer to audio device info (enumeration result). */
358typedef PDMAUDIOHOSTDEV *PPDMAUDIOHOSTDEV;
359/** Pointer to a const audio device info (enumeration result). */
360typedef PDMAUDIOHOSTDEV const *PCPDMAUDIOHOSTDEV;
361
362/** Magic value for PDMAUDIOHOSTDEV. */
363#define PDMAUDIOHOSTDEV_MAGIC PDM_VERSION_MAKE(0xa0d0, 2, 0)
364
365
366/**
367 * A host audio device enumeration result.
368 *
369 * @sa PDMIHOSTAUDIO::pfnGetDevices
370 */
371typedef struct PDMAUDIOHOSTENUM
372{
373 /** Magic value (PDMAUDIOHOSTENUM_MAGIC). */
374 uint32_t uMagic;
375 /** Number of audio devices in the list. */
376 uint32_t cDevices;
377 /** List of audio devices (PDMAUDIOHOSTDEV). */
378 RTLISTANCHOR LstDevices;
379} PDMAUDIOHOSTENUM;
380/** Pointer to an audio device enumeration result. */
381typedef PDMAUDIOHOSTENUM *PPDMAUDIOHOSTENUM;
382/** Pointer to a const audio device enumeration result. */
383typedef PDMAUDIOHOSTENUM const *PCPDMAUDIOHOSTENUM;
384
385/** Magic for the host audio device enumeration. */
386#define PDMAUDIOHOSTENUM_MAGIC PDM_VERSION_MAKE(0xa0d1, 1, 0)
387
388
389/**
390 * Audio configuration (static) of an audio host backend.
391 */
392typedef struct PDMAUDIOBACKENDCFG
393{
394 /** The backend's friendly name. */
395 char szName[32];
396 /** The size of the backend specific stream data (in bytes). */
397 uint32_t cbStream;
398 /** PDMAUDIOBACKEND_F_XXX. */
399 uint32_t fFlags;
400 /** Number of concurrent output (playback) streams supported on the host.
401 * UINT32_MAX for unlimited concurrent streams, 0 if no concurrent input streams are supported. */
402 uint32_t cMaxStreamsOut;
403 /** Number of concurrent input (recording) streams supported on the host.
404 * UINT32_MAX for unlimited concurrent streams, 0 if no concurrent input streams are supported. */
405 uint32_t cMaxStreamsIn;
406} PDMAUDIOBACKENDCFG;
407/** Pointer to a static host audio audio configuration. */
408typedef PDMAUDIOBACKENDCFG *PPDMAUDIOBACKENDCFG;
409
410/** @name PDMAUDIOBACKEND_F_XXX - PDMAUDIOBACKENDCFG::fFlags
411 * @{ */
412/** PDMIHOSTAUDIO::pfnStreamConfigHint should preferably be called on a
413 * worker thread rather than EMT as it may take a good while. */
414#define PDMAUDIOBACKEND_F_ASYNC_HINT RT_BIT_32(0)
415/** PDMIHOSTAUDIO::pfnStreamDestroy and any preceeding
416 * PDMIHOSTAUDIO::pfnStreamControl/DISABLE should be preferably be called on a
417 * worker thread rather than EMT as it may take a good while. */
418#define PDMAUDIOBACKEND_F_ASYNC_STREAM_DESTROY RT_BIT_32(1)
419/** @} */
420
421
422/**
423 * A single audio frame.
424 *
425 * Currently only two (2) channels, left and right, are supported.
426 *
427 * @note When changing this structure, make sure to also handle
428 * VRDP's input / output processing in DrvAudioVRDE, as VRDP
429 * expects audio data in st_sample_t format (historical reasons)
430 * which happens to be the same as PDMAUDIOFRAME for now.
431 *
432 * @todo r=bird: This is an internal AudioMixBuffer structure which should not
433 * be exposed here, I think. Only used to some sizeof statements in VRDE.
434 * (The problem with exposing it, is that we would like to move away from
435 * stereo and instead to anything from 1 to 16 channels. That means
436 * removing this structure entirely.)
437 */
438typedef struct PDMAUDIOFRAME
439{
440 /** Left channel. */
441 int64_t i64LSample;
442 /** Right channel. */
443 int64_t i64RSample;
444} PDMAUDIOFRAME;
445/** Pointer to a single (stereo) audio frame. */
446typedef PDMAUDIOFRAME *PPDMAUDIOFRAME;
447/** Pointer to a const single (stereo) audio frame. */
448typedef PDMAUDIOFRAME const *PCPDMAUDIOFRAME;
449
450
451/**
452 * Audio path: input sources and playback destinations.
453 *
454 * Think of this as the name of the socket you plug the virtual audio stream
455 * jack into.
456 *
457 * @note Not quite sure what the purpose of this type is. It used to be two
458 * separate enums (PDMAUDIOPLAYBACKDST & PDMAUDIORECSRC) without overlapping
459 * values and most commonly used in a union (PDMAUDIODSTSRCUNION). The output
460 * values were designated "channel" (e.g. "Front channel"), whereas this was not
461 * done to the input ones. So, I'm (bird) a little confused what the actual
462 * meaning was.
463 */
464typedef enum PDMAUDIOPATH
465{
466 /** Customary invalid zero value. */
467 PDMAUDIOPATH_INVALID = 0,
468
469 /** Unknown path / Doesn't care. */
470 PDMAUDIOPATH_UNKNOWN,
471
472 /** First output value. */
473 PDMAUDIOPATH_OUT_FIRST,
474 /** Output: Front. */
475 PDMAUDIOPATH_OUT_FRONT = PDMAUDIOPATH_OUT_FIRST,
476 /** Output: Center / LFE (Subwoofer). */
477 PDMAUDIOPATH_OUT_CENTER_LFE,
478 /** Output: Rear. */
479 PDMAUDIOPATH_OUT_REAR,
480 /** Last output value (inclusive) */
481 PDMAUDIOPATH_OUT_END = PDMAUDIOPATH_OUT_REAR,
482
483 /** First input value. */
484 PDMAUDIOPATH_IN_FIRST,
485 /** Input: Microphone. */
486 PDMAUDIOPATH_IN_MIC = PDMAUDIOPATH_IN_FIRST,
487 /** Input: CD. */
488 PDMAUDIOPATH_IN_CD,
489 /** Input: Video-In. */
490 PDMAUDIOPATH_IN_VIDEO,
491 /** Input: AUX. */
492 PDMAUDIOPATH_IN_AUX,
493 /** Input: Line-In. */
494 PDMAUDIOPATH_IN_LINE,
495 /** Input: Phone-In. */
496 PDMAUDIOPATH_IN_PHONE,
497 /** Last intput value (inclusive). */
498 PDMAUDIOPATH_IN_LAST = PDMAUDIOPATH_IN_PHONE,
499
500 /** End of valid values. */
501 PDMAUDIOPATH_END,
502 /** Hack to blow the typ up to 32 bits. */
503 PDMAUDIOPATH_32BIT_HACK = 0x7fffffff
504} PDMAUDIOPATH;
505
506/**
507 * Audio stream (data) layout.
508 */
509typedef enum PDMAUDIOSTREAMLAYOUT
510{
511 /** Invalid zero value as per usual (guards against using unintialized values). */
512 PDMAUDIOSTREAMLAYOUT_INVALID = 0,
513 /** Unknown access type; do not use (hdaR3StreamMapReset uses it). */
514 PDMAUDIOSTREAMLAYOUT_UNKNOWN,
515 /** Non-interleaved access, that is, consecutive access to the data.
516 * @todo r=bird: For plain stereo this is actually interleaves left/right. What
517 * I guess non-interleaved means, is that there are no additional
518 * information interleaved next to the interleaved stereo.
519 * https://stackoverflow.com/questions/17879933/whats-the-interleaved-audio */
520 PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED,
521 /** Interleaved access, where the data can be mixed together with data of other audio streams. */
522 PDMAUDIOSTREAMLAYOUT_INTERLEAVED,
523 /** Complex layout, which does not fit into the interleaved / non-interleaved layouts. */
524 PDMAUDIOSTREAMLAYOUT_COMPLEX,
525 /** Raw (pass through) data, with no data layout processing done.
526 *
527 * This means that this stream will operate on PDMAUDIOFRAME data
528 * directly. Don't use this if you don't have to.
529 *
530 * @deprecated Replaced by S64 (signed, 64-bit sample size). */
531 PDMAUDIOSTREAMLAYOUT_RAW,
532 /** End of valid values. */
533 PDMAUDIOSTREAMLAYOUT_END,
534 /** Hack to blow the type up to 32-bit. */
535 PDMAUDIOSTREAMLAYOUT_32BIT_HACK = 0x7fffffff
536} PDMAUDIOSTREAMLAYOUT;
537
538/**
539 * Stream channel data block.
540 */
541typedef struct PDMAUDIOSTREAMCHANNELDATA
542{
543 /** Circular buffer for the channel data. */
544 PRTCIRCBUF pCircBuf;
545 /** Amount of audio data (in bytes) acquired for reading. */
546 size_t cbAcq;
547 /** Channel data flags, PDMAUDIOSTREAMCHANNELDATA_FLAGS_XXX. */
548 uint32_t fFlags;
549} PDMAUDIOSTREAMCHANNELDATA;
550/** Pointer to audio stream channel data buffer. */
551typedef PDMAUDIOSTREAMCHANNELDATA *PPDMAUDIOSTREAMCHANNELDATA;
552
553/** @name PDMAUDIOSTREAMCHANNELDATA_FLAGS_XXX
554 * @{ */
555/** No stream channel data flags defined. */
556#define PDMAUDIOSTREAMCHANNELDATA_FLAGS_NONE UINT32_C(0)
557/** @} */
558
559/**
560 * Standard speaker channel IDs.
561 *
562 * This can cover up to 11.0 surround sound.
563 *
564 * @note Any of those channels can be marked / used as the LFE channel (played
565 * through the subwoofer).
566 */
567typedef enum PDMAUDIOSTREAMCHANNELID
568{
569 /** Invalid zero value as per usual (guards against using unintialized values). */
570 PDMAUDIOSTREAMCHANNELID_INVALID = 0,
571 /** Unknown / not set channel ID. */
572 PDMAUDIOSTREAMCHANNELID_UNKNOWN,
573 /** Front left channel. */
574 PDMAUDIOSTREAMCHANNELID_FRONT_LEFT,
575 /** Front right channel. */
576 PDMAUDIOSTREAMCHANNELID_FRONT_RIGHT,
577 /** Front center channel. */
578 PDMAUDIOSTREAMCHANNELID_FRONT_CENTER,
579 /** Low frequency effects (subwoofer) channel. */
580 PDMAUDIOSTREAMCHANNELID_LFE,
581 /** Rear left channel. */
582 PDMAUDIOSTREAMCHANNELID_REAR_LEFT,
583 /** Rear right channel. */
584 PDMAUDIOSTREAMCHANNELID_REAR_RIGHT,
585 /** Front left of center channel. */
586 PDMAUDIOSTREAMCHANNELID_FRONT_LEFT_OF_CENTER,
587 /** Front right of center channel. */
588 PDMAUDIOSTREAMCHANNELID_FRONT_RIGHT_OF_CENTER,
589 /** Rear center channel. */
590 PDMAUDIOSTREAMCHANNELID_REAR_CENTER,
591 /** Side left channel. */
592 PDMAUDIOSTREAMCHANNELID_SIDE_LEFT,
593 /** Side right channel. */
594 PDMAUDIOSTREAMCHANNELID_SIDE_RIGHT,
595 /** Left height channel. */
596 PDMAUDIOSTREAMCHANNELID_LEFT_HEIGHT,
597 /** Right height channel. */
598 PDMAUDIOSTREAMCHANNELID_RIGHT_HEIGHT,
599 /** End of valid values. */
600 PDMAUDIOSTREAMCHANNELID_END,
601 /** Hack to blow the type up to 32-bit. */
602 PDMAUDIOSTREAMCHANNELID_32BIT_HACK = 0x7fffffff
603} PDMAUDIOSTREAMCHANNELID;
604
605/**
606 * Mappings channels onto an audio stream.
607 *
608 * The mappings are either for a single (mono) or dual (stereo) channels onto an
609 * audio stream (aka stream profile). An audio stream consists of one or
610 * multiple channels (e.g. 1 for mono, 2 for stereo), depending on the
611 * configuration.
612 */
613typedef struct PDMAUDIOSTREAMMAP
614{
615 /** Array of channel IDs being handled.
616 * @note The first (zero-based) index specifies the leftmost channel. */
617 PDMAUDIOSTREAMCHANNELID aenmIDs[2];
618 /** Step size (in bytes) to the channel's next frame. */
619 uint32_t cbStep;
620 /** Frame size (in bytes) of this channel. */
621 uint32_t cbFrame;
622 /** Byte offset to the first frame in the data block. */
623 uint32_t offFirst;
624 /** Byte offset to the next frame in the data block. */
625 uint32_t offNext;
626 /** Associated data buffer. */
627 PDMAUDIOSTREAMCHANNELDATA Data;
628
629 /** @todo r=bird: I'd structure this very differently.
630 * I would've had an array of channel descriptors like this:
631 *
632 * struct PDMAUDIOCHANNELDESC
633 * {
634 * uint8_t off; //< Stream offset in bytes.
635 * uint8_t id; //< PDMAUDIOSTREAMCHANNELID
636 * };
637 *
638 * And I'd baked it into PDMAUDIOPCMPROPS as a fixed sized array with 16 entries
639 * (max HDA channel count IIRC). */
640} PDMAUDIOSTREAMMAP;
641/** Pointer to an audio stream channel mapping. */
642typedef PDMAUDIOSTREAMMAP *PPDMAUDIOSTREAMMAP;
643
644/**
645 * Properties of audio streams for host/guest for in or out directions.
646 */
647typedef struct PDMAUDIOPCMPROPS
648{
649 /** The frame size. */
650 uint8_t cbFrame;
651 /** Shift count used with PDMAUDIOPCMPROPS_F2B and PDMAUDIOPCMPROPS_B2F.
652 * Depends on number of stream channels and the stream format being used, calc
653 * value using PDMAUDIOPCMPROPS_MAKE_SHIFT.
654 * @sa PDMAUDIOSTREAMCFG_B2F, PDMAUDIOSTREAMCFG_F2B */
655 uint8_t cShiftX;
656 /** Sample width (in bytes). */
657 RT_GCC_EXTENSION
658 uint8_t cbSampleX : 4;
659 /** Number of audio channels. */
660 RT_GCC_EXTENSION
661 uint8_t cChannelsX : 4;
662 /** Signed or unsigned sample. */
663 bool fSigned : 1;
664 /** Whether the endianness is swapped or not. */
665 bool fSwapEndian : 1;
666 /** Raw mixer frames, only applicable for signed 64-bit samples.
667 * The raw mixer samples are really just signed 32-bit samples stored as 64-bit
668 * integers without any change in the value.
669 *
670 * @todo Get rid of this, only VRDE needs it an it should use the common
671 * mixer code rather than cooking its own stuff. */
672 bool fRaw : 1;
673 /** Sample frequency in Hertz (Hz). */
674 uint32_t uHz;
675} PDMAUDIOPCMPROPS;
676AssertCompileSize(PDMAUDIOPCMPROPS, 8);
677AssertCompileSizeAlignment(PDMAUDIOPCMPROPS, 8);
678/** Pointer to audio stream properties. */
679typedef PDMAUDIOPCMPROPS *PPDMAUDIOPCMPROPS;
680/** Pointer to const audio stream properties. */
681typedef PDMAUDIOPCMPROPS const *PCPDMAUDIOPCMPROPS;
682
683/** @name Macros for use with PDMAUDIOPCMPROPS
684 * @{ */
685/** Initializer for PDMAUDIOPCMPROPS. */
686#define PDMAUDIOPCMPROPS_INITIALIZER(a_cbSample, a_fSigned, a_cChannels, a_uHz, a_fSwapEndian) \
687 { (a_cbSample) * (a_cChannels), PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(a_cbSample, a_cChannels), a_cbSample, a_cChannels, \
688 a_fSigned, a_fSwapEndian, false /*fRaw*/, a_uHz }
689/** Calculates the cShift value of given sample bits and audio channels.
690 * @note Does only support mono/stereo channels for now, for non-stereo/mono we
691 * returns a special value which the two conversion functions detect
692 * and make them fall back on cbSample * cChannels. */
693#define PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(cbSample, cChannels) \
694 ( RT_IS_POWER_OF_TWO((unsigned)((cChannels) * (cbSample))) \
695 ? (uint8_t)(ASMBitFirstSetU32((unsigned)((cChannels) * (cbSample))) - 1) : (uint8_t)UINT8_MAX )
696/** Calculates the cShift value of a PDMAUDIOPCMPROPS structure. */
697#define PDMAUDIOPCMPROPS_MAKE_SHIFT(pProps) \
698 PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS((pProps)->cbSampleX, (pProps)->cChannelsX)
699/** Converts (audio) frames to bytes.
700 * @note Requires properly initialized properties, i.e. cbFrames correctly calculated
701 * and cShift set using PDMAUDIOPCMPROPS_MAKE_SHIFT. */
702#define PDMAUDIOPCMPROPS_F2B(pProps, cFrames) \
703 ( (pProps)->cShiftX != UINT8_MAX ? (cFrames) << (pProps)->cShiftX : (cFrames) * (pProps)->cbFrame )
704/** Converts bytes to (audio) frames.
705 * @note Requires properly initialized properties, i.e. cbFrames correctly calculated
706 * and cShift set using PDMAUDIOPCMPROPS_MAKE_SHIFT. */
707#define PDMAUDIOPCMPROPS_B2F(pProps, cb) \
708 ( (pProps)->cShiftX != UINT8_MAX ? (cb) >> (pProps)->cShiftX : (cb) / (pProps)->cbFrame )
709/** @} */
710
711/**
712 * An audio stream configuration.
713 */
714typedef struct PDMAUDIOSTREAMCFG
715{
716 /** Direction of the stream. */
717 PDMAUDIODIR enmDir;
718 /** Destination / source path. */
719 PDMAUDIOPATH enmPath;
720 /** The stream's PCM properties. */
721 PDMAUDIOPCMPROPS Props;
722 /** The stream's audio data layout.
723 * This indicates how the audio data buffers to/from the backend is being layouted.
724 *
725 * Currently, the following layouts are supported by the audio connector:
726 *
727 * PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED:
728 * One stream at once. The consecutive audio data is exactly in the format and frame width
729 * like defined in the PCM properties. This is the default.
730 *
731 * PDMAUDIOSTREAMLAYOUT_RAW:
732 * Can be one or many streams at once, depending on the stream's mixing buffer setup.
733 * The audio data will get handled as PDMAUDIOFRAME frames without any modification done.
734 *
735 * @todo r=bird: See PDMAUDIOSTREAMLAYOUT comments. */
736 PDMAUDIOSTREAMLAYOUT enmLayout;
737 /** Device emulation-specific data needed for the audio connector. */
738 struct
739 {
740 /** Scheduling hint set by the device emulation about when this stream is being served on average (in ms).
741 * Can be 0 if not hint given or some other mechanism (e.g. callbacks) is being used. */
742 uint32_t cMsSchedulingHint;
743 } Device;
744 /**
745 * Backend-specific data for the stream.
746 * On input (requested configuration) those values are set by the audio connector to let the backend know what we expect.
747 * On output (acquired configuration) those values reflect the values set and used by the backend.
748 * Set by the backend on return. Not all backends support all values / features.
749 */
750 struct
751 {
752 /** Period size of the stream (in audio frames).
753 * This value reflects the number of audio frames in between each hardware interrupt on the
754 * backend (host) side. 0 if not set / available by the backend. */
755 uint32_t cFramesPeriod;
756 /** (Ring) buffer size (in audio frames). Often is a multiple of cFramesPeriod.
757 * 0 if not set / available by the backend. */
758 uint32_t cFramesBufferSize;
759 /** Pre-buffering size (in audio frames). Frames needed in buffer before the stream becomes active (pre buffering).
760 * The bigger this value is, the more latency for the stream will occur.
761 * 0 if not set / available by the backend. UINT32_MAX if not defined (yet). */
762 uint32_t cFramesPreBuffering;
763 } Backend;
764 uint32_t u32Padding;
765 /** Friendly name of the stream. */
766 char szName[64];
767} PDMAUDIOSTREAMCFG;
768AssertCompileSizeAlignment(PDMAUDIOSTREAMCFG, 8);
769/** Pointer to audio stream configuration keeper. */
770typedef PDMAUDIOSTREAMCFG *PPDMAUDIOSTREAMCFG;
771/** Pointer to a const audio stream configuration keeper. */
772typedef PDMAUDIOSTREAMCFG const *PCPDMAUDIOSTREAMCFG;
773
774/** Converts (audio) frames to bytes. */
775#define PDMAUDIOSTREAMCFG_F2B(pCfg, frames) PDMAUDIOPCMPROPS_F2B(&(pCfg)->Props, (frames))
776/** Converts bytes to (audio) frames. */
777#define PDMAUDIOSTREAMCFG_B2F(pCfg, cb) PDMAUDIOPCMPROPS_B2F(&(pCfg)->Props, (cb))
778
779/**
780 * Audio mixer controls.
781 */
782typedef enum PDMAUDIOMIXERCTL
783{
784 /** Invalid zero value as per usual (guards against using unintialized values). */
785 PDMAUDIOMIXERCTL_INVALID = 0,
786 /** Unknown mixer control. */
787 PDMAUDIOMIXERCTL_UNKNOWN,
788 /** Master volume. */
789 PDMAUDIOMIXERCTL_VOLUME_MASTER,
790 /** Front. */
791 PDMAUDIOMIXERCTL_FRONT,
792 /** Center / LFE (Subwoofer). */
793 PDMAUDIOMIXERCTL_CENTER_LFE,
794 /** Rear. */
795 PDMAUDIOMIXERCTL_REAR,
796 /** Line-In. */
797 PDMAUDIOMIXERCTL_LINE_IN,
798 /** Microphone-In. */
799 PDMAUDIOMIXERCTL_MIC_IN,
800 /** End of valid values. */
801 PDMAUDIOMIXERCTL_END,
802 /** Hack to blow the type up to 32-bit. */
803 PDMAUDIOMIXERCTL_32BIT_HACK = 0x7fffffff
804} PDMAUDIOMIXERCTL;
805
806/**
807 * Audio stream commands.
808 *
809 * Used in the audio connector as well as in the actual host backends.
810 */
811typedef enum PDMAUDIOSTREAMCMD
812{
813 /** Invalid zero value as per usual (guards against using unintialized values). */
814 PDMAUDIOSTREAMCMD_INVALID = 0,
815 /** Enables the stream. */
816 PDMAUDIOSTREAMCMD_ENABLE,
817 /** Pauses the stream.
818 * This is currently only issued when the VM is suspended (paused).
819 * @remarks This is issued by DrvAudio, never by the mixer or devices. */
820 PDMAUDIOSTREAMCMD_PAUSE,
821 /** Resumes the stream.
822 * This is currently only issued when the VM is resumed.
823 * @remarks This is issued by DrvAudio, never by the mixer or devices. */
824 PDMAUDIOSTREAMCMD_RESUME,
825 /** Drain the stream, that is, play what's in the buffers and then stop.
826 *
827 * There will be no more samples written after this command is issued.
828 * PDMIAUDIOCONNECTOR::pfnStreamIterate will drive progress for DrvAudio and
829 * calls to PDMIHOSTAUDIO::pfnStreamPlay with a zero sized buffer will provide
830 * the backend with a way to drive it forwards. These calls will come at a
831 * frequency set by the device and be on an asynchronous I/O thread.
832 *
833 * A DISABLE command maybe submitted if the device/mixer wants to re-enable the
834 * stream while it's still draining or if it gets impatient and thinks the
835 * draining has been going on too long, in which case the stream should stop
836 * immediately.
837 *
838 * @note This should not wait for the stream to finish draining, just change
839 * the state. (The caller could be an EMT and it must not block for
840 * hundreds of milliseconds of buffer to finish draining.)
841 *
842 * @note Does not apply to input streams. Backends should refuse such requests. */
843 PDMAUDIOSTREAMCMD_DRAIN,
844 /** Stops the stream immediately w/o any draining. */
845 PDMAUDIOSTREAMCMD_DISABLE,
846 /** End of valid values. */
847 PDMAUDIOSTREAMCMD_END,
848 /** Hack to blow the type up to 32-bit. */
849 PDMAUDIOSTREAMCMD_32BIT_HACK = 0x7fffffff
850} PDMAUDIOSTREAMCMD;
851
852/**
853 * Audio volume parameters.
854 */
855typedef struct PDMAUDIOVOLUME
856{
857 /** Set to @c true if this stream is muted, @c false if not. */
858 bool fMuted;
859 /** Left channel volume.
860 * Range is from [0 ... 255], whereas 0 specifies
861 * the most silent and 255 the loudest value. */
862 uint8_t uLeft;
863 /** Right channel volume.
864 * Range is from [0 ... 255], whereas 0 specifies
865 * the most silent and 255 the loudest value. */
866 uint8_t uRight;
867} PDMAUDIOVOLUME;
868/** Pointer to audio volume settings. */
869typedef PDMAUDIOVOLUME *PPDMAUDIOVOLUME;
870/** Pointer to const audio volume settings. */
871typedef PDMAUDIOVOLUME const *PCPDMAUDIOVOLUME;
872
873/** Defines the minimum volume allowed. */
874#define PDMAUDIO_VOLUME_MIN (0)
875/** Defines the maximum volume allowed. */
876#define PDMAUDIO_VOLUME_MAX (255)
877
878
879/**
880 * Backend status.
881 */
882typedef enum PDMAUDIOBACKENDSTS
883{
884 /** Unknown/invalid status. */
885 PDMAUDIOBACKENDSTS_UNKNOWN = 0,
886 /** No backend attached. */
887 PDMAUDIOBACKENDSTS_NOT_ATTACHED,
888 /** The backend is in its initialization phase.
889 * Not all backends support this status. */
890 PDMAUDIOBACKENDSTS_INITIALIZING,
891 /** The backend has stopped its operation. */
892 PDMAUDIOBACKENDSTS_STOPPED,
893 /** The backend is up and running. */
894 PDMAUDIOBACKENDSTS_RUNNING,
895 /** The backend ran into an error and is unable to recover.
896 * A manual re-initialization might help. */
897 PDMAUDIOBACKENDSTS_ERROR,
898 /** Hack to blow the type up to 32-bit. */
899 PDMAUDIOBACKENDSTS_32BIT_HACK = 0x7fffffff
900} PDMAUDIOBACKENDSTS;
901
902/**
903 * PDM audio stream state.
904 *
905 * This is all the mixer/device needs. The PDMAUDIOSTREAM_STS_XXX stuff will
906 * become DrvAudio internal state once the backend stuff is destilled out of it.
907 *
908 * @note The value order is significant, don't change it willy-nilly.
909 */
910typedef enum PDMAUDIOSTREAMSTATE
911{
912 /** Invalid state value. */
913 PDMAUDIOSTREAMSTATE_INVALID = 0,
914 /** The stream is not operative and cannot be enabled. */
915 PDMAUDIOSTREAMSTATE_NOT_WORKING,
916 /** The stream needs to be re-initialized by the device/mixer
917 * (i.e. call PDMIAUDIOCONNECTOR::pfnStreamReInit). */
918 PDMAUDIOSTREAMSTATE_NEED_REINIT,
919 /** The stream is inactive (not enabled). */
920 PDMAUDIOSTREAMSTATE_INACTIVE,
921 /** The stream is enabled but nothing to read/write.
922 * @todo not sure if we need this variant... */
923 PDMAUDIOSTREAMSTATE_ENABLED,
924 /** The stream is enabled and captured samples can be read. */
925 PDMAUDIOSTREAMSTATE_ENABLED_READABLE,
926 /** The stream is enabled and samples can be written for playback. */
927 PDMAUDIOSTREAMSTATE_ENABLED_WRITABLE,
928 /** End of valid states. */
929 PDMAUDIOSTREAMSTATE_END,
930 /** Make sure the type is 32-bit wide. */
931 PDMAUDIOSTREAMSTATE_32BIT_HACK = 0x7fffffff
932} PDMAUDIOSTREAMSTATE;
933
934/** @name PDMAUDIOSTREAM_CREATE_F_XXX
935 * @{ */
936/** Does not need any mixing buffers, the device takes care of all conversion.
937 * @note this is now default and assumed always set. */
938#define PDMAUDIOSTREAM_CREATE_F_NO_MIXBUF RT_BIT_32(0)
939/** @} */
940
941/** @name PDMAUDIOSTREAM_WARN_FLAGS_XXX
942 * @{ */
943/** No stream warning flags set. */
944#define PDMAUDIOSTREAM_WARN_FLAGS_NONE 0
945/** Warned about a disabled stream. */
946#define PDMAUDIOSTREAM_WARN_FLAGS_DISABLED RT_BIT(0)
947/** @} */
948
949/**
950 * An input or output audio stream.
951 */
952typedef struct PDMAUDIOSTREAM
953{
954 /** Critical section protecting the stream.
955 *
956 * When not otherwise stated, DrvAudio will enter this before calling the
957 * backend. The backend and device/mixer can normally safely enter it prior to
958 * a DrvAudio call, however not to pfnStreamDestroy, pfnStreamRelease or
959 * anything that may access the stream list.
960 *
961 * @note Lock ordering:
962 * - After DRVAUDIO::CritSectGlobals.
963 * - Before DRVAUDIO::CritSectHotPlug. */
964 RTCRITSECT CritSect;
965 /** Magic value (PDMAUDIOSTREAM_MAGIC). */
966 uint32_t uMagic;
967 /** Audio direction of this stream. */
968 PDMAUDIODIR enmDir;
969 /** Size (in bytes) of the backend-specific stream data. */
970 uint32_t cbBackend;
971 /** Warnings shown already in the release log.
972 * See PDMAUDIOSTREAM_WARN_FLAGS_XXX. */
973 uint32_t fWarningsShown;
974 /** The stream properties (both sides when PDMAUDIOSTREAM_CREATE_F_NO_MIXBUF
975 * is used, otherwise the guest side). */
976 PDMAUDIOPCMPROPS Props;
977
978 /** Name of this stream. */
979 char szName[64];
980} PDMAUDIOSTREAM;
981/** Pointer to an audio stream. */
982typedef struct PDMAUDIOSTREAM *PPDMAUDIOSTREAM;
983/** Pointer to a const audio stream. */
984typedef struct PDMAUDIOSTREAM const *PCPDMAUDIOSTREAM;
985
986/** Magic value for PDMAUDIOSTREAM. */
987#define PDMAUDIOSTREAM_MAGIC PDM_VERSION_MAKE(0xa0d3, 5, 0)
988
989
990
991/** Pointer to a audio connector interface. */
992typedef struct PDMIAUDIOCONNECTOR *PPDMIAUDIOCONNECTOR;
993
994/**
995 * Audio connector interface (up).
996 */
997typedef struct PDMIAUDIOCONNECTOR
998{
999 /**
1000 * Enables or disables the given audio direction for this driver.
1001 *
1002 * When disabled, assiociated output streams consume written audio without passing them further down to the backends.
1003 * Associated input streams then return silence when read from those.
1004 *
1005 * @returns VBox status code.
1006 * @param pInterface Pointer to the interface structure containing the called function pointer.
1007 * @param enmDir Audio direction to enable or disable driver for.
1008 * @param fEnable Whether to enable or disable the specified audio direction.
1009 *
1010 * @note Be very careful when using this function, as this could
1011 * violate / run against the (global) VM settings. See @bugref{9882}.
1012 */
1013 DECLR3CALLBACKMEMBER(int, pfnEnable, (PPDMIAUDIOCONNECTOR pInterface, PDMAUDIODIR enmDir, bool fEnable));
1014
1015 /**
1016 * Returns whether the given audio direction for this driver is enabled or not.
1017 *
1018 * @returns True if audio is enabled for the given direction, false if not.
1019 * @param pInterface Pointer to the interface structure containing the called function pointer.
1020 * @param enmDir Audio direction to retrieve enabled status for.
1021 */
1022 DECLR3CALLBACKMEMBER(bool, pfnIsEnabled, (PPDMIAUDIOCONNECTOR pInterface, PDMAUDIODIR enmDir));
1023
1024 /**
1025 * Retrieves the current configuration of the host audio backend.
1026 *
1027 * @returns VBox status code.
1028 * @param pInterface Pointer to the interface structure containing the called function pointer.
1029 * @param pCfg Where to store the host audio backend configuration data.
1030 */
1031 DECLR3CALLBACKMEMBER(int, pfnGetConfig, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOBACKENDCFG pCfg));
1032
1033 /**
1034 * Retrieves the current status of the host audio backend.
1035 *
1036 * @returns Status of the host audio backend.
1037 * @param pInterface Pointer to the interface structure containing the called function pointer.
1038 * @param enmDir Audio direction to check host audio backend for. Specify PDMAUDIODIR_DUPLEX for the overall
1039 * backend status.
1040 */
1041 DECLR3CALLBACKMEMBER(PDMAUDIOBACKENDSTS, pfnGetStatus, (PPDMIAUDIOCONNECTOR pInterface, PDMAUDIODIR enmDir));
1042
1043 /**
1044 * Gives the audio drivers a hint about a typical configuration.
1045 *
1046 * This is a little hack for windows (and maybe other hosts) where stream
1047 * creation can take a relatively long time, making it very unsuitable for EMT.
1048 * The audio backend can use this hint to cache pre-configured stream setups,
1049 * so that when the guest actually wants to play something EMT won't be blocked
1050 * configuring host audio.
1051 *
1052 * @param pInterface Pointer to this interface.
1053 * @param pCfg The typical configuration. Can be modified by the
1054 * drivers in unspecified ways.
1055 */
1056 DECLR3CALLBACKMEMBER(void, pfnStreamConfigHint, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAMCFG pCfg));
1057
1058 /**
1059 * Creates an audio stream.
1060 *
1061 * @returns VBox status code.
1062 * @param pInterface Pointer to the interface structure containing the called function pointer.
1063 * @param fFlags PDMAUDIOSTREAM_CREATE_F_XXX.
1064 * @param pCfgHost Stream configuration for host side.
1065 * @param pCfgGuest Stream configuration for guest side.
1066 * @param ppStream Pointer where to return the created audio stream on success.
1067 * @todo r=bird: It is not documented how pCfgHost and pCfgGuest can be
1068 * modified the DrvAudio...
1069 */
1070 DECLR3CALLBACKMEMBER(int, pfnStreamCreate, (PPDMIAUDIOCONNECTOR pInterface, uint32_t fFlags, PPDMAUDIOSTREAMCFG pCfgHost,
1071 PPDMAUDIOSTREAMCFG pCfgGuest, PPDMAUDIOSTREAM *ppStream));
1072
1073
1074 /**
1075 * Destroys an audio stream.
1076 *
1077 * @param pInterface Pointer to the interface structure containing the called function pointer.
1078 * @param pStream Pointer to audio stream.
1079 * @param fImmediate Whether to immdiately stop and destroy a draining
1080 * stream (@c true), or to allow it to complete
1081 * draining first (@c false) if that's feasable.
1082 * The latter depends on the draining stage and what
1083 * the backend is capable of.
1084 */
1085 DECLR3CALLBACKMEMBER(int, pfnStreamDestroy, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream, bool fImmediate));
1086
1087 /**
1088 * Re-initializes the stream in response to PDMAUDIOSTREAM_STS_NEED_REINIT.
1089 *
1090 * @returns VBox status code.
1091 * @param pInterface Pointer to this interface.
1092 * @param pStream The audio stream needing re-initialization.
1093 */
1094 DECLR3CALLBACKMEMBER(int, pfnStreamReInit, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));
1095
1096 /**
1097 * Adds a reference to the specified audio stream.
1098 *
1099 * @returns New reference count. UINT32_MAX on error.
1100 * @param pInterface Pointer to the interface structure containing the called function pointer.
1101 * @param pStream Pointer to audio stream adding the reference to.
1102 */
1103 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamRetain, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));
1104
1105 /**
1106 * Releases a reference from the specified stream.
1107 *
1108 * @returns New reference count. UINT32_MAX on error.
1109 * @param pInterface Pointer to the interface structure containing the called function pointer.
1110 * @param pStream Pointer to audio stream releasing a reference from.
1111 */
1112 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamRelease, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));
1113
1114 /**
1115 * Controls a specific audio stream.
1116 *
1117 * @returns VBox status code.
1118 * @param pInterface Pointer to the interface structure containing the called function pointer.
1119 * @param pStream Pointer to audio stream.
1120 * @param enmStreamCmd The stream command to issue.
1121 */
1122 DECLR3CALLBACKMEMBER(int, pfnStreamControl, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream,
1123 PDMAUDIOSTREAMCMD enmStreamCmd));
1124
1125 /**
1126 * Processes stream data.
1127 *
1128 * @param pInterface Pointer to the interface structure containing the called function pointer.
1129 * @param pStream Pointer to audio stream.
1130 */
1131 DECLR3CALLBACKMEMBER(int, pfnStreamIterate, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));
1132
1133 /**
1134 * Returns the state of a specific audio stream (destilled status).
1135 *
1136 * @returns PDMAUDIOSTREAMSTATE value.
1137 * @retval PDMAUDIOSTREAMSTATE_INVALID if the input isn't valid (w/ assertion).
1138 * @param pInterface Pointer to the interface structure containing the called function pointer.
1139 * @param pStream Pointer to audio stream.
1140 */
1141 DECLR3CALLBACKMEMBER(PDMAUDIOSTREAMSTATE, pfnStreamGetState, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));
1142
1143 /**
1144 * Returns the number of bytes that can be written to an audio output stream.
1145 *
1146 * @returns Number of bytes writable data.
1147 * @param pInterface Pointer to the interface structure containing the called function pointer.
1148 * @param pStream Pointer to audio stream.
1149 */
1150 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetWritable, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));
1151
1152 /**
1153 * Plays (writes to) an audio output stream.
1154 *
1155 * @returns VBox status code.
1156 * @param pInterface Pointer to the interface structure containing the called function pointer.
1157 * @param pStream Pointer to audio stream to read from.
1158 * @param pvBuf Audio data to be written.
1159 * @param cbBuf Number of bytes to be written.
1160 * @param pcbWritten Bytes of audio data written. Optional.
1161 */
1162 DECLR3CALLBACKMEMBER(int, pfnStreamPlay, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream,
1163 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten));
1164
1165 /**
1166 * Returns the number of bytes that can be read from an input stream.
1167 *
1168 * @returns Number of bytes of readable data.
1169 * @param pInterface Pointer to the interface structure containing the called function pointer.
1170 * @param pStream Pointer to audio stream.
1171 */
1172 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetReadable, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));
1173
1174 /**
1175 * Captures (reads) samples from an audio input stream.
1176 *
1177 * @returns VBox status code.
1178 * @param pInterface Pointer to the interface structure containing the called function pointer.
1179 * @param pStream Pointer to audio stream to write to.
1180 * @param pvBuf Where to store the read data.
1181 * @param cbBuf Number of bytes to read.
1182 * @param pcbRead Bytes of audio data read. Optional.
1183 */
1184 DECLR3CALLBACKMEMBER(int, pfnStreamCapture, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream,
1185 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead));
1186} PDMIAUDIOCONNECTOR;
1187
1188/** PDMIAUDIOCONNECTOR interface ID. */
1189#define PDMIAUDIOCONNECTOR_IID "36fee65e-cbb3-4bb7-a028-e88e6acc1c46"
1190
1191
1192/**
1193 * Host audio backend specific stream data.
1194 *
1195 * The backend will put this as the first member of it's own data structure.
1196 */
1197typedef struct PDMAUDIOBACKENDSTREAM
1198{
1199 /** Magic value (PDMAUDIOBACKENDSTREAM_MAGIC). */
1200 uint32_t uMagic;
1201 /** Explicit zero padding - do not touch! */
1202 uint32_t uReserved;
1203 /** Pointer to the stream this backend data is associated with. */
1204 PPDMAUDIOSTREAM pStream;
1205 /** Reserved for future use (zeroed) - do not touch. */
1206 void *apvReserved[2];
1207} PDMAUDIOBACKENDSTREAM;
1208/** Pointer to host audio specific stream data! */
1209typedef PDMAUDIOBACKENDSTREAM *PPDMAUDIOBACKENDSTREAM;
1210
1211/** Magic value for PDMAUDIOBACKENDSTREAM. */
1212#define PDMAUDIOBACKENDSTREAM_MAGIC PDM_VERSION_MAKE(0xa0d4, 1, 0)
1213
1214/**
1215 * Host audio (backend) stream state returned by PDMIHOSTAUDIO::pfnStreamGetState.
1216 */
1217typedef enum PDMHOSTAUDIOSTREAMSTATE
1218{
1219 /** Invalid zero value, as per usual. */
1220 PDMHOSTAUDIOSTREAMSTATE_INVALID = 0,
1221 /** The stream is being initialized.
1222 * This should also be used when switching to a new device and the stream
1223 * stops to work with the old device while the new one being configured. */
1224 PDMHOSTAUDIOSTREAMSTATE_INITIALIZING,
1225 /** The stream does not work (async init failed, audio subsystem gone
1226 * fishing, or similar). */
1227 PDMHOSTAUDIOSTREAMSTATE_NOT_WORKING,
1228 /** Backend is working okay. */
1229 PDMHOSTAUDIOSTREAMSTATE_OKAY,
1230 /** Backend is working okay, but currently draining the stream. */
1231 PDMHOSTAUDIOSTREAMSTATE_DRAINING,
1232 /** Backend is working but doesn't want any commands or data reads/writes. */
1233 PDMHOSTAUDIOSTREAMSTATE_INACTIVE,
1234 /** End of valid values. */
1235 PDMHOSTAUDIOSTREAMSTATE_END,
1236 /** Blow the type up to 32 bits. */
1237 PDMHOSTAUDIOSTREAMSTATE_32BIT_HACK = 0x7fffffff
1238} PDMHOSTAUDIOSTREAMSTATE;
1239
1240
1241/** Pointer to a host audio interface. */
1242typedef struct PDMIHOSTAUDIO *PPDMIHOSTAUDIO;
1243
1244/**
1245 * PDM host audio interface.
1246 */
1247typedef struct PDMIHOSTAUDIO
1248{
1249 /**
1250 * Returns the host backend's configuration (backend).
1251 *
1252 * @returns VBox status code.
1253 * @param pInterface Pointer to the interface structure containing the called function pointer.
1254 * @param pBackendCfg Where to store the backend audio configuration to.
1255 */
1256 DECLR3CALLBACKMEMBER(int, pfnGetConfig, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg));
1257
1258 /**
1259 * Returns (enumerates) host audio device information (optional).
1260 *
1261 * @returns VBox status code.
1262 * @param pInterface Pointer to the interface structure containing the called function pointer.
1263 * @param pDeviceEnum Where to return the enumerated audio devices.
1264 */
1265 DECLR3CALLBACKMEMBER(int, pfnGetDevices, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOHOSTENUM pDeviceEnum));
1266
1267 /**
1268 * Changes the output or input device.
1269 *
1270 * @returns VBox status code.
1271 * @param pInterface Pointer to this interface.
1272 * @param enmDir The direction to set the device for: PDMAUDIODIR_IN,
1273 * PDMAUDIODIR_OUT or PDMAUDIODIR_DUPLEX (both the
1274 * previous).
1275 * @param pszId The PDMAUDIOHOSTDEV::pszId value of the device to
1276 * use, or NULL / empty string for the default device.
1277 */
1278 DECLR3CALLBACKMEMBER(int, pfnSetDevice, (PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir, const char *pszId));
1279
1280 /**
1281 * Returns the current status from the audio backend (optional).
1282 *
1283 * @returns PDMAUDIOBACKENDSTS enum.
1284 * @param pInterface Pointer to the interface structure containing the called function pointer.
1285 * @param enmDir Audio direction to get status for. Pass PDMAUDIODIR_DUPLEX for overall status.
1286 */
1287 DECLR3CALLBACKMEMBER(PDMAUDIOBACKENDSTS, pfnGetStatus, (PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir));
1288
1289 /**
1290 * Callback for genric on-worker-thread requests initiated by the backend itself.
1291 *
1292 * This is the counterpart to PDMIHOSTAUDIOPORT::pfnDoOnWorkerThread that will
1293 * be invoked on a worker thread when the backend requests it - optional.
1294 *
1295 * This does not return a value, so the backend must keep track of
1296 * failure/success on its own.
1297 *
1298 * This method is optional. A non-NULL will, together with pfnStreamInitAsync
1299 * and PDMAUDIOBACKEND_F_ASYNC_HINT, force DrvAudio to create the thread pool.
1300 *
1301 * @param pInterface Pointer to this interface.
1302 * @param pStream Optionally a backend stream if specified in the
1303 * PDMIHOSTAUDIOPORT::pfnDoOnWorkerThread() call.
1304 * @param uUser User specific value as specified in the
1305 * PDMIHOSTAUDIOPORT::pfnDoOnWorkerThread() call.
1306 * @param pvUser User specific pointer as specified in the
1307 * PDMIHOSTAUDIOPORT::pfnDoOnWorkerThread() call.
1308 */
1309 DECLR3CALLBACKMEMBER(void, pfnDoOnWorkerThread,(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
1310 uintptr_t uUser, void *pvUser));
1311
1312 /**
1313 * Gives the audio backend a hint about a typical configuration (optional).
1314 *
1315 * This is a little hack for windows (and maybe other hosts) where stream
1316 * creation can take a relatively long time, making it very unsuitable for EMT.
1317 * The audio backend can use this hint to cache pre-configured stream setups,
1318 * so that when the guest actually wants to play something EMT won't be blocked
1319 * configuring host audio.
1320 *
1321 * The backend can return PDMAUDIOBACKEND_F_ASYNC_HINT in
1322 * PDMIHOSTAUDIO::pfnGetConfig to avoid having EMT making this call and thereby
1323 * speeding up VM construction.
1324 *
1325 * @param pInterface Pointer to this interface.
1326 * @param pCfg The typical configuration. (Feel free to change it
1327 * to the actual stream config that would be used,
1328 * however caller will probably ignore this.)
1329 */
1330 DECLR3CALLBACKMEMBER(void, pfnStreamConfigHint, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAMCFG pCfg));
1331
1332 /**
1333 * Creates an audio stream using the requested stream configuration.
1334 *
1335 * If a backend is not able to create this configuration, it will return its
1336 * best match in the acquired configuration structure on success.
1337 *
1338 * @returns VBox status code.
1339 * @retval VINF_AUDIO_STREAM_ASYNC_INIT_NEEDED if
1340 * PDMIHOSTAUDIO::pfnStreamInitAsync should be called.
1341 * @param pInterface Pointer to the interface structure containing the called function pointer.
1342 * @param pStream Pointer to audio stream.
1343 * @param pCfgReq Pointer to requested stream configuration.
1344 * @param pCfgAcq Pointer to acquired stream configuration.
1345 * @todo r=bird: Implementation (at least Alsa) seems to make undocumented
1346 * assumptions about the content of @a pCfgAcq.
1347 */
1348 DECLR3CALLBACKMEMBER(int, pfnStreamCreate, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
1349 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq));
1350
1351 /**
1352 * Asynchronous stream initialization step, optional.
1353 *
1354 * This is called on a worker thread iff the PDMIHOSTAUDIO::pfnStreamCreate
1355 * method returns VINF_AUDIO_STREAM_ASYNC_INIT_NEEDED.
1356 *
1357 * @returns VBox status code.
1358 * @param pInterface Pointer to this interface.
1359 * @param pStream Pointer to audio stream to continue
1360 * initialization of.
1361 * @param fDestroyed Set to @c true if the stream has been destroyed
1362 * before the worker thread got to making this
1363 * call. The backend should just ready the stream
1364 * for destruction in that case.
1365 */
1366 DECLR3CALLBACKMEMBER(int, pfnStreamInitAsync, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, bool fDestroyed));
1367
1368 /**
1369 * Destroys an audio stream.
1370 *
1371 * @returns VBox status code.
1372 * @param pInterface Pointer to the interface containing the called function.
1373 * @param pStream Pointer to audio stream.
1374 * @param fImmediate Whether to immdiately stop and destroy a draining
1375 * stream (@c true), or to allow it to complete
1376 * draining first (@c false) if that's feasable.
1377 */
1378 DECLR3CALLBACKMEMBER(int, pfnStreamDestroy, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, bool fImmediate));
1379
1380 /**
1381 * Called from PDMIHOSTAUDIOPORT::pfnNotifyDeviceChanged so the backend can start
1382 * the device change for a stream.
1383 *
1384 * This is mainly to avoid the need for a list of streams in the backend.
1385 *
1386 * @param pInterface Pointer to this interface.
1387 * @param pStream Pointer to audio stream (locked).
1388 * @param pvUser Backend specific parameter from the call to
1389 * PDMIHOSTAUDIOPORT::pfnNotifyDeviceChanged.
1390 */
1391 DECLR3CALLBACKMEMBER(void, pfnStreamNotifyDeviceChanged,(PPDMIHOSTAUDIO pInterface,
1392 PPDMAUDIOBACKENDSTREAM pStream, void *pvUser));
1393
1394 /**
1395 * Controls an audio stream.
1396 *
1397 * @returns VBox status code.
1398 * @retval VERR_AUDIO_STREAM_NOT_READY if stream is not ready for required operation (yet).
1399 * @param pInterface Pointer to the interface structure containing the called function pointer.
1400 * @param pStream Pointer to audio stream.
1401 * @param enmStreamCmd The stream command to issue.
1402 */
1403 DECLR3CALLBACKMEMBER(int, pfnStreamControl, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
1404 PDMAUDIOSTREAMCMD enmStreamCmd));
1405
1406 /**
1407 * Returns the amount which is readable from the audio (input) stream.
1408 *
1409 * @returns For non-raw layout streams: Number of readable bytes.
1410 * for raw layout streams : Number of readable audio frames.
1411 * @param pInterface Pointer to the interface structure containing the called function pointer.
1412 * @param pStream Pointer to audio stream.
1413 */
1414 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetReadable, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));
1415
1416 /**
1417 * Returns the amount which is writable to the audio (output) stream.
1418 *
1419 * @returns Number of writable bytes.
1420 * @param pInterface Pointer to the interface structure containing the called function pointer.
1421 * @param pStream Pointer to audio stream.
1422 */
1423 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetWritable, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));
1424
1425 /**
1426 * Returns the number of buffered bytes that hasn't been played yet (optional).
1427 *
1428 * Is not valid on an input stream, implementions shall assert and return zero.
1429 *
1430 * @returns Number of pending bytes.
1431 * @param pInterface Pointer to this interface.
1432 * @param pStream Pointer to audio stream.
1433 *
1434 * @todo This is no longer not used by DrvAudio and can probably be removed.
1435 */
1436 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetPending, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));
1437
1438 /**
1439 * Returns the current state of the given backend stream.
1440 *
1441 * @returns PDMHOSTAUDIOSTREAMSTATE value.
1442 * @retval PDMHOSTAUDIOSTREAMSTATE_INVALID if invalid stream.
1443 * @param pInterface Pointer to the interface structure containing the called function pointer.
1444 * @param pStream Pointer to audio stream.
1445 */
1446 DECLR3CALLBACKMEMBER(PDMHOSTAUDIOSTREAMSTATE, pfnStreamGetState, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));
1447
1448 /**
1449 * Plays (writes to) an audio (output) stream.
1450 *
1451 * This is always called with data in the buffer, except after
1452 * PDMAUDIOSTREAMCMD_DRAIN is issued when it's called every so often to assist
1453 * the backend with moving the draining operation forward (kind of like
1454 * PDMIAUDIOCONNECTOR::pfnStreamIterate).
1455 *
1456 * @returns VBox status code.
1457 * @param pInterface Pointer to the interface structure containing the called function pointer.
1458 * @param pStream Pointer to audio stream.
1459 * @param pvBuf Pointer to audio data buffer to play. This will be NULL
1460 * when called to assist draining the stream.
1461 * @param cbBuf The number of bytes of audio data to play. This will be
1462 * zero when called to assist draining the stream.
1463 * @param pcbWritten Where to return the actual number of bytes played.
1464 */
1465 DECLR3CALLBACKMEMBER(int, pfnStreamPlay, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
1466 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten));
1467
1468 /**
1469 * Captures (reads from) an audio (input) stream.
1470 *
1471 * @returns VBox status code.
1472 * @param pInterface Pointer to the interface structure containing the called function pointer.
1473 * @param pStream Pointer to audio stream.
1474 * @param pvBuf Buffer where to store read audio data.
1475 * @param cbBuf Size of the audio data buffer in bytes.
1476 * @param pcbRead Where to return the number of bytes actually captured.
1477 */
1478 DECLR3CALLBACKMEMBER(int, pfnStreamCapture, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
1479 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead));
1480} PDMIHOSTAUDIO;
1481
1482/** PDMIHOSTAUDIO interface ID. */
1483#define PDMIHOSTAUDIO_IID "da3c9d33-e532-415b-9156-db31521f59ef"
1484
1485
1486/** Pointer to a audio notify from host interface. */
1487typedef struct PDMIHOSTAUDIOPORT *PPDMIHOSTAUDIOPORT;
1488
1489/**
1490 * PDM host audio port interface, upwards sibling of PDMIHOSTAUDIO.
1491 */
1492typedef struct PDMIHOSTAUDIOPORT
1493{
1494 /**
1495 * Ask DrvAudio to call PDMIHOSTAUDIO::pfnDoOnWorkerThread on a worker thread.
1496 *
1497 * Generic method for doing asynchronous work using the DrvAudio thread pool.
1498 *
1499 * This function will not wait for PDMIHOSTAUDIO::pfnDoOnWorkerThread to
1500 * complete, but returns immediately after submitting the request to the thread
1501 * pool.
1502 *
1503 * @returns VBox status code.
1504 * @param pInterface Pointer to this interface.
1505 * @param pStream Optional backend stream structure to pass along. The
1506 * reference count will be increased till the call
1507 * completes to make sure the stream stays valid.
1508 * @param uUser User specific value.
1509 * @param pvUser User specific pointer.
1510 */
1511 DECLR3CALLBACKMEMBER(int, pfnDoOnWorkerThread,(PPDMIHOSTAUDIOPORT pInterface, PPDMAUDIOBACKENDSTREAM pStream,
1512 uintptr_t uUser, void *pvUser));
1513
1514 /**
1515 * The device for the given direction changed.
1516 *
1517 * The driver above backend (DrvAudio) will call the backend back
1518 * (PDMIHOSTAUDIO::pfnStreamNotifyDeviceChanged) for all open streams in the
1519 * given direction. (This ASSUMES the backend uses one output device and one
1520 * input devices for all streams.)
1521 *
1522 * @param pInterface Pointer to this interface.
1523 * @param enmDir The audio direction.
1524 * @param pvUser Backend specific parameter for
1525 * PDMIHOSTAUDIO::pfnStreamNotifyDeviceChanged.
1526 */
1527 DECLR3CALLBACKMEMBER(void, pfnNotifyDeviceChanged,(PPDMIHOSTAUDIOPORT pInterface, PDMAUDIODIR enmDir, void *pvUser));
1528
1529 /**
1530 * Notification that the stream is about to change device in a bit.
1531 *
1532 * This will assume PDMAUDIOSTREAM_STS_PREPARING_SWITCH will be set when
1533 * PDMIHOSTAUDIO::pfnStreamGetStatus is next called and change the stream state
1534 * accordingly.
1535 *
1536 * @param pInterface Pointer to this interface.
1537 * @param pStream The stream that changed device (backend variant).
1538 */
1539 DECLR3CALLBACKMEMBER(void, pfnStreamNotifyPreparingDeviceSwitch,(PPDMIHOSTAUDIOPORT pInterface,
1540 PPDMAUDIOBACKENDSTREAM pStream));
1541
1542 /**
1543 * The stream has changed its device and left the
1544 * PDMAUDIOSTREAM_STS_PREPARING_SWITCH state (if it entered it at all).
1545 *
1546 * @param pInterface Pointer to this interface.
1547 * @param pStream The stream that changed device (backend variant).
1548 * @param fReInit Set if a re-init is required, clear if not.
1549 */
1550 DECLR3CALLBACKMEMBER(void, pfnStreamNotifyDeviceChanged,(PPDMIHOSTAUDIOPORT pInterface,
1551 PPDMAUDIOBACKENDSTREAM pStream, bool fReInit));
1552
1553 /**
1554 * One or more audio devices have changed in some way.
1555 *
1556 * The upstream driver/device should re-evaluate the devices they're using.
1557 *
1558 * @todo r=bird: The upstream driver/device does not know which host audio
1559 * devices they are using. This is mainly for triggering enumeration and
1560 * logging of the audio devices.
1561 *
1562 * @param pInterface Pointer to this interface.
1563 */
1564 DECLR3CALLBACKMEMBER(void, pfnNotifyDevicesChanged,(PPDMIHOSTAUDIOPORT pInterface));
1565} PDMIHOSTAUDIOPORT;
1566
1567/** PDMIHOSTAUDIOPORT interface ID. */
1568#define PDMIHOSTAUDIOPORT_IID "9f91ec59-95ba-4925-92dc-e75be1c63352"
1569
1570/** @} */
1571
1572#endif /* !VBOX_INCLUDED_vmm_pdmaudioifs_h */
1573
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette