VirtualBox

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

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

pdmaudioifs.h: doxygen. bugref:9890

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

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