VirtualBox

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

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

Audio: Fixed broken DrvAudioHlpBytesToNano and DrvAudioHlpBytesToMicro implementation (overflow), the latter is the only one used. Also fixed silly confusion about 'const' and pointers (you want what they point to to be const, not the pointers themselves. duh) bugref:9890

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 71.0 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 PDMAUDIOMIXBUF 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 |PDMAUDIOMIXBUF |+------>|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/circbuf.h>
234#include <iprt/list.h>
235#include <iprt/path.h>
236
237#include <VBox/types.h>
238#ifdef VBOX_WITH_STATISTICS
239# include <VBox/vmm/stam.h>
240#endif
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/** PDM audio driver instance flags. */
256typedef uint32_t PDMAUDIODRVFLAGS;
257
258/** No flags set. */
259#define PDMAUDIODRVFLAGS_NONE 0
260/** Marks a primary audio driver which is critical
261 * when running the VM. */
262#define PDMAUDIODRVFLAGS_PRIMARY RT_BIT(0)
263
264/**
265 * Audio format in signed or unsigned variants.
266 */
267typedef enum PDMAUDIOFMT
268{
269 /** Invalid format, do not use. */
270 PDMAUDIOFMT_INVALID = 0,
271 /** 8-bit, unsigned. */
272 PDMAUDIOFMT_U8,
273 /** 8-bit, signed. */
274 PDMAUDIOFMT_S8,
275 /** 16-bit, unsigned. */
276 PDMAUDIOFMT_U16,
277 /** 16-bit, signed. */
278 PDMAUDIOFMT_S16,
279 /** 32-bit, unsigned. */
280 PDMAUDIOFMT_U32,
281 /** 32-bit, signed. */
282 PDMAUDIOFMT_S32,
283 /** Hack to blow the type up to 32-bit. */
284 PDMAUDIOFMT_32BIT_HACK = 0x7fffffff
285} PDMAUDIOFMT;
286
287/**
288 * Audio direction.
289 */
290typedef enum PDMAUDIODIR
291{
292 /** Invalid zero value as per usual (guards against using unintialized values). */
293 PDMAUDIODIR_INVALID = 0,
294 /** Unknown direction. */
295 PDMAUDIODIR_UNKNOWN,
296 /** Input. */
297 PDMAUDIODIR_IN,
298 /** Output. */
299 PDMAUDIODIR_OUT,
300 /** Duplex handling. */
301 PDMAUDIODIR_ANY,
302 /** Hack to blow the type up to 32-bit. */
303 PDMAUDIODIR_32BIT_HACK = 0x7fffffff
304} PDMAUDIODIR;
305
306/** Device latency spec in milliseconds (ms). */
307typedef uint32_t PDMAUDIODEVLATSPECMS;
308
309/** Device latency spec in seconds (s). */
310typedef uint32_t PDMAUDIODEVLATSPECSEC;
311
312/** @name PDMAUDIODEV_FLAGS_XXX
313 * @{ */
314/** No flags set. */
315#define PDMAUDIODEV_FLAGS_NONE UINT32_C(0)
316/** The device marks the default device within the host OS. */
317#define PDMAUDIODEV_FLAGS_DEFAULT RT_BIT_32(0)
318/** The device can be removed at any time and we have to deal with it. */
319#define PDMAUDIODEV_FLAGS_HOTPLUG RT_BIT_32(1)
320/** The device is known to be buggy and needs special treatment. */
321#define PDMAUDIODEV_FLAGS_BUGGY RT_BIT_32(2)
322/** Ignore the device, no matter what. */
323#define PDMAUDIODEV_FLAGS_IGNORE RT_BIT_32(3)
324/** The device is present but marked as locked by some other application. */
325#define PDMAUDIODEV_FLAGS_LOCKED RT_BIT_32(4)
326/** The device is present but not in an alive state (dead). */
327#define PDMAUDIODEV_FLAGS_DEAD RT_BIT_32(5)
328/** @} */
329
330/**
331 * Audio device type.
332 */
333typedef enum PDMAUDIODEVICETYPE
334{
335 /** Invalid zero value as per usual (guards against using unintialized values). */
336 PDMAUDIODEVICETYPE_INVALID = 0,
337 /** Unknown device type. This is the default. */
338 PDMAUDIODEVICETYPE_UNKNOWN,
339 /** Dummy device; for backends which are not able to report
340 * actual device information (yet). */
341 PDMAUDIODEVICETYPE_DUMMY,
342 /** The device is built into the host (non-removable). */
343 PDMAUDIODEVICETYPE_BUILTIN,
344 /** The device is an (external) USB device. */
345 PDMAUDIODEVICETYPE_USB,
346 /** Hack to blow the type up to 32-bit. */
347 PDMAUDIODEVICETYPE_32BIT_HACK = 0x7fffffff
348} PDMAUDIODEVICETYPE;
349
350/**
351 * Audio device info (enumeration result).
352 * @sa PDMAUDIODEVICEENUM, PDMIHOSTAUDIO::pfnGetDevices
353 */
354typedef struct PDMAUDIODEVICE
355{
356 /** List node. */
357 RTLISTNODE Node;
358 /** Additional data which might be relevant for the current context.
359 * @todo r=bird: I would do this C++ style, having the host specific bits
360 * appended after this structure and downcast. */
361 void *pvData;
362 /** Size of the additional data. */
363 size_t cbData;
364 /** The device type. */
365 PDMAUDIODEVICETYPE enmType;
366 /** Usage of the device. */
367 PDMAUDIODIR enmUsage;
368 /** Device flags, PDMAUDIODEV_FLAGS_XXX. */
369 uint32_t fFlags;
370 /** Reference count indicating how many audio streams currently are relying on this device. */
371 uint8_t cRefCount;
372 /** Maximum number of input audio channels the device supports. */
373 uint8_t cMaxInputChannels;
374 /** Maximum number of output audio channels the device supports. */
375 uint8_t cMaxOutputChannels;
376 /** Device type union, based on enmType. */
377 union
378 {
379 /** USB type specifics. */
380 struct
381 {
382 /** Vendor ID.
383 * @todo r=bird: Why signed?? VUSB uses uint16_t for idVendor and idProduct! */
384 int16_t VID;
385 /** Product ID. */
386 int16_t PID;
387 } USB;
388 } Type;
389 /** Friendly name of the device, if any. */
390 char szName[64];
391} PDMAUDIODEVICE;
392/** Pointer to audio device info (enum result). */
393typedef PDMAUDIODEVICE *PPDMAUDIODEVICE;
394
395/**
396 * An audio device enumeration result.
397 * @sa PDMIHOSTAUDIO::pfnGetDevices
398 */
399typedef struct PDMAUDIODEVICEENUM
400{
401 /** Number of audio devices in the list. */
402 uint16_t cDevices;
403 /** List of audio devices. */
404 RTLISTANCHOR lstDevices;
405} PDMAUDIODEVICEENUM;
406/** Pointer to an audio device enumeration result. */
407typedef PDMAUDIODEVICEENUM *PPDMAUDIODEVICEENUM;
408
409/**
410 * Audio configuration (static) of an audio host backend.
411 */
412typedef struct PDMAUDIOBACKENDCFG
413{
414 /** The backend's friendly name. */
415 char szName[32];
416 /** Size (in bytes) of the host backend's audio output stream structure. */
417 size_t cbStreamOut;
418 /** Size (in bytes) of the host backend's audio input stream structure. */
419 size_t cbStreamIn;
420 /** Number of concurrent output (playback) streams supported on the host.
421 * UINT32_MAX for unlimited concurrent streams, 0 if no concurrent input streams are supported. */
422 uint32_t cMaxStreamsOut;
423 /** Number of concurrent input (recording) streams supported on the host.
424 * UINT32_MAX for unlimited concurrent streams, 0 if no concurrent input streams are supported. */
425 uint32_t cMaxStreamsIn;
426} PDMAUDIOBACKENDCFG;
427/** Pointer to a static host audio audio configuration. */
428typedef PDMAUDIOBACKENDCFG *PPDMAUDIOBACKENDCFG;
429
430/**
431 * A single audio frame.
432 *
433 * Currently only two (2) channels, left and right, are supported.
434 *
435 * @note When changing this structure, make sure to also handle
436 * VRDP's input / output processing in DrvAudioVRDE, as VRDP
437 * expects audio data in st_sample_t format (historical reasons)
438 * which happens to be the same as PDMAUDIOFRAME for now.
439 */
440typedef struct PDMAUDIOFRAME
441{
442 /** Left channel. */
443 int64_t i64LSample;
444 /** Right channel. */
445 int64_t i64RSample;
446} PDMAUDIOFRAME;
447/** Pointer to a single (stereo) audio frame. */
448typedef PDMAUDIOFRAME *PPDMAUDIOFRAME;
449/** Pointer to a const single (stereo) audio frame. */
450typedef PDMAUDIOFRAME const *PCPDMAUDIOFRAME;
451
452typedef enum PDMAUDIOENDIANNESS
453{
454 /** The usual invalid value. */
455 PDMAUDIOENDIANNESS_INVALID = 0,
456 /** Little endian. */
457 PDMAUDIOENDIANNESS_LITTLE,
458 /** Bit endian. */
459 PDMAUDIOENDIANNESS_BIG,
460 /** Endianness doesn't have a meaning in the context. */
461 PDMAUDIOENDIANNESS_NA,
462 /** The end of the valid endian values (exclusive). */
463 PDMAUDIOENDIANNESS_END,
464 /** Hack to blow the type up to 32-bit. */
465 PDMAUDIOENDIANNESS_32BIT_HACK = 0x7fffffff
466} PDMAUDIOENDIANNESS;
467
468/** @def PDMAUDIOHOSTENDIANNESS
469 * The PDMAUDIOENDIANNESS value for the host. */
470#if defined(RT_LITTLE_ENDIAN)
471# define PDMAUDIOHOSTENDIANNESS PDMAUDIOENDIANNESS_LITTLE
472#elif defined(RT_BIG_ENDIAN)
473# define PDMAUDIOHOSTENDIANNESS PDMAUDIOENDIANNESS_BIG
474#else
475# error "Port me!"
476#endif
477
478/**
479 * Audio playback destinations.
480 */
481typedef enum PDMAUDIOPLAYBACKDST
482{
483 /** Invalid zero value as per usual (guards against using unintialized values). */
484 PDMAUDIOPLAYBACKDST_INVALID = 0,
485 /** Unknown destination. */
486 PDMAUDIOPLAYBACKDST_UNKNOWN,
487 /** Front channel. */
488 PDMAUDIOPLAYBACKDST_FRONT,
489 /** Center / LFE (Subwoofer) channel. */
490 PDMAUDIOPLAYBACKDST_CENTER_LFE,
491 /** Rear channel. */
492 PDMAUDIOPLAYBACKDST_REAR,
493 /** Hack to blow the type up to 32-bit. */
494 PDMAUDIOPLAYBACKDST_32BIT_HACK = 0x7fffffff
495} PDMAUDIOPLAYBACKDST;
496
497/**
498 * Audio recording sources.
499 *
500 * @note Because this is almost exclusively used in PDMAUDIODSTSRCUNION where it
501 * overlaps with PDMAUDIOPLAYBACKDST, the values starts at 64 instead of 0.
502 */
503typedef enum PDMAUDIORECSRC
504{
505 /** Unknown recording source. */
506 PDMAUDIORECSRC_UNKNOWN = 64,
507 /** Microphone-In. */
508 PDMAUDIORECSRC_MIC,
509 /** CD. */
510 PDMAUDIORECSRC_CD,
511 /** Video-In. */
512 PDMAUDIORECSRC_VIDEO,
513 /** AUX. */
514 PDMAUDIORECSRC_AUX,
515 /** Line-In. */
516 PDMAUDIORECSRC_LINE,
517 /** Phone-In. */
518 PDMAUDIORECSRC_PHONE,
519 /** Hack to blow the type up to 32-bit. */
520 PDMAUDIORECSRC_32BIT_HACK = 0x7fffffff
521} PDMAUDIORECSRC;
522
523/**
524 * Union for keeping an audio stream destination or source.
525 */
526typedef union PDMAUDIODSTSRCUNION
527{
528 /** Desired playback destination (for an output stream). */
529 PDMAUDIOPLAYBACKDST enmDst;
530 /** Desired recording source (for an input stream). */
531 PDMAUDIORECSRC enmSrc;
532} PDMAUDIODSTSRCUNION;
533/** Pointer to an audio stream src/dst union. */
534typedef PDMAUDIODSTSRCUNION *PPDMAUDIODSTSRCUNION;
535
536/**
537 * Audio stream (data) layout.
538 */
539typedef enum PDMAUDIOSTREAMLAYOUT
540{
541 /** Invalid zero value as per usual (guards against using unintialized values). */
542 PDMAUDIOSTREAMLAYOUT_INVALID = 0,
543 /** Unknown access type; do not use (hdaR3StreamMapReset uses it). */
544 PDMAUDIOSTREAMLAYOUT_UNKNOWN,
545 /** Non-interleaved access, that is, consecutive
546 * access to the data. */
547 PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED,
548 /** Interleaved access, where the data can be
549 * mixed together with data of other audio streams. */
550 PDMAUDIOSTREAMLAYOUT_INTERLEAVED,
551 /** Complex layout, which does not fit into the
552 * interleaved / non-interleaved layouts. */
553 PDMAUDIOSTREAMLAYOUT_COMPLEX,
554 /** Raw (pass through) data, with no data layout processing done.
555 *
556 * This means that this stream will operate on PDMAUDIOFRAME data
557 * directly. Don't use this if you don't have to. */
558 PDMAUDIOSTREAMLAYOUT_RAW,
559 /** Hack to blow the type up to 32-bit. */
560 PDMAUDIOSTREAMLAYOUT_32BIT_HACK = 0x7fffffff
561} PDMAUDIOSTREAMLAYOUT;
562
563/**
564 * Stream channel data block.
565 */
566typedef struct PDMAUDIOSTREAMCHANNELDATA
567{
568 /** Circular buffer for the channel data. */
569 PRTCIRCBUF pCircBuf;
570 /** Amount of audio data (in bytes) acquired for reading. */
571 size_t cbAcq;
572 /** Channel data flags, PDMAUDIOSTREAMCHANNELDATA_FLAGS_XXX. */
573 uint32_t fFlags;
574} PDMAUDIOSTREAMCHANNELDATA;
575/** Pointer to audio stream channel data buffer. */
576typedef PDMAUDIOSTREAMCHANNELDATA *PPDMAUDIOSTREAMCHANNELDATA;
577
578/** @name PDMAUDIOSTREAMCHANNELDATA_FLAGS_XXX
579 * @{ */
580/** No stream channel data flags defined. */
581#define PDMAUDIOSTREAMCHANNELDATA_FLAGS_NONE UINT32_C(0)
582/** @} */
583
584/**
585 * Standard speaker channel IDs.
586 *
587 * This can cover up to 11.0 surround sound.
588 *
589 * @note Any of those channels can be marked / used as the LFE channel (played
590 * through the subwoofer).
591 */
592typedef enum PDMAUDIOSTREAMCHANNELID
593{
594 /** Invalid zero value as per usual (guards against using unintialized values). */
595 PDMAUDIOSTREAMCHANNELID_INVALID = 0,
596 /** Unknown / not set channel ID. */
597 PDMAUDIOSTREAMCHANNELID_UNKNOWN,
598 /** Front left channel. */
599 PDMAUDIOSTREAMCHANNELID_FRONT_LEFT,
600 /** Front right channel. */
601 PDMAUDIOSTREAMCHANNELID_FRONT_RIGHT,
602 /** Front center channel. */
603 PDMAUDIOSTREAMCHANNELID_FRONT_CENTER,
604 /** Low frequency effects (subwoofer) channel. */
605 PDMAUDIOSTREAMCHANNELID_LFE,
606 /** Rear left channel. */
607 PDMAUDIOSTREAMCHANNELID_REAR_LEFT,
608 /** Rear right channel. */
609 PDMAUDIOSTREAMCHANNELID_REAR_RIGHT,
610 /** Front left of center channel. */
611 PDMAUDIOSTREAMCHANNELID_FRONT_LEFT_OF_CENTER,
612 /** Front right of center channel. */
613 PDMAUDIOSTREAMCHANNELID_FRONT_RIGHT_OF_CENTER,
614 /** Rear center channel. */
615 PDMAUDIOSTREAMCHANNELID_REAR_CENTER,
616 /** Side left channel. */
617 PDMAUDIOSTREAMCHANNELID_SIDE_LEFT,
618 /** Side right channel. */
619 PDMAUDIOSTREAMCHANNELID_SIDE_RIGHT,
620 /** Left height channel. */
621 PDMAUDIOSTREAMCHANNELID_LEFT_HEIGHT,
622 /** Right height channel. */
623 PDMAUDIOSTREAMCHANNELID_RIGHT_HEIGHT,
624 /** Hack to blow the type up to 32-bit. */
625 PDMAUDIOSTREAMCHANNELID_32BIT_HACK = 0x7fffffff
626} PDMAUDIOSTREAMCHANNELID;
627
628/**
629 * Mappings channels onto an audio stream.
630 *
631 * The mappings are either for a single (mono) or dual (stereo) channels onto an
632 * audio stream (aka stream profile). An audio stream consists of one or
633 * multiple channels (e.g. 1 for mono, 2 for stereo), depending on the
634 * configuration.
635 */
636typedef struct PDMAUDIOSTREAMMAP
637{
638 /** Array of channel IDs being handled.
639 * @note The first (zero-based) index specifies the leftmost channel. */
640 PDMAUDIOSTREAMCHANNELID aenmIDs[2];
641 /** Step size (in bytes) to the channel's next frame. */
642 uint32_t cbStep;
643 /** Frame size (in bytes) of this channel. */
644 uint32_t cbFrame;
645 /** Byte offset to the first frame in the data block. */
646 uint32_t offFirst;
647 /** Byte offset to the next frame in the data block. */
648 uint32_t offNext;
649 /** Associated data buffer. */
650 PDMAUDIOSTREAMCHANNELDATA Data;
651} PDMAUDIOSTREAMMAP;
652/** Pointer to an audio stream channel mapping. */
653typedef PDMAUDIOSTREAMMAP *PPDMAUDIOSTREAMMAP;
654
655/**
656 * Properties of audio streams for host/guest for in or out directions.
657 */
658typedef struct PDMAUDIOPCMPROPS
659{
660 /** Sample width (in bytes). */
661 uint8_t cbSample;
662 /** Number of audio channels. */
663 uint8_t cChannels;
664 /** Shift count used with PDMAUDIOPCMPROPS_F2B and PDMAUDIOPCMPROPS_B2F.
665 * Depends on number of stream channels and the stream format being used, calc
666 * value using PDMAUDIOPCMPROPS_MAKE_SHIFT.
667 * @sa PDMAUDIOSTREAMCFG_B2F, PDMAUDIOSTREAMCFG_F2B
668 * @todo r=bird: The original brief description: "Shift count used
669 * for faster calculation of various values, such as the alignment, bytes
670 * to frames and so on." I cannot make heads or tails from that.
671 * @todo Use some RTAsmXXX functions instead? */
672 uint8_t cShift;
673 /** Signed or unsigned sample. */
674 bool fSigned : 1;
675 /** Whether the endianness is swapped or not. */
676 bool fSwapEndian : 1;
677 /** Sample frequency in Hertz (Hz). */
678 uint32_t uHz;
679} PDMAUDIOPCMPROPS;
680AssertCompileSize(PDMAUDIOPCMPROPS, 8);
681AssertCompileSizeAlignment(PDMAUDIOPCMPROPS, 8);
682/** Pointer to audio stream properties. */
683typedef PDMAUDIOPCMPROPS *PPDMAUDIOPCMPROPS;
684/** Pointer to const audio stream properties. */
685typedef PDMAUDIOPCMPROPS const *PCPDMAUDIOPCMPROPS;
686
687/** @name Macros for use with PDMAUDIOPCMPROPS
688 * @{ */
689/** Initializor for PDMAUDIOPCMPROPS. */
690#define PDMAUDIOPCMPROPS_INITIALIZOR(a_cBytes, a_fSigned, a_cCannels, a_uHz, a_cShift, a_fSwapEndian) \
691 { a_cBytes, a_cCannels, a_cShift, a_fSigned, a_fSwapEndian, a_uHz }
692/** Calculates the cShift value of given sample bits and audio channels.
693 * @note Does only support mono/stereo channels for now. */
694#define PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(cBytes, cChannels) ((cChannels == 2) + (cBytes / 2))
695/** Calculates the cShift value of a PDMAUDIOPCMPROPS structure. */
696#define PDMAUDIOPCMPROPS_MAKE_SHIFT(pProps) PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS((pProps)->cbSample, (pProps)->cChannels)
697/** Converts (audio) frames to bytes.
698 * Needs the cShift value set correctly, using PDMAUDIOPCMPROPS_MAKE_SHIFT. */
699#define PDMAUDIOPCMPROPS_F2B(pProps, frames) ((frames) << (pProps)->cShift)
700/** Converts bytes to (audio) frames.
701 * Needs the cShift value set correctly, using PDMAUDIOPCMPROPS_MAKE_SHIFT. */
702#define PDMAUDIOPCMPROPS_B2F(pProps, cb) ((cb) >> (pProps)->cShift)
703/** @} */
704
705/**
706 * An audio stream configuration.
707 */
708typedef struct PDMAUDIOSTREAMCFG
709{
710 /** Direction of the stream. */
711 PDMAUDIODIR enmDir;
712 /** Destination / source indicator, depending on enmDir. */
713 PDMAUDIODSTSRCUNION u;
714 /** The stream's PCM properties. */
715 PDMAUDIOPCMPROPS Props;
716 /** The stream's audio data layout.
717 * This indicates how the audio data buffers to/from the backend is being layouted.
718 *
719 * Currently, the following layouts are supported by the audio connector:
720 *
721 * PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED:
722 * One stream at once. The consecutive audio data is exactly in the format and frame width
723 * like defined in the PCM properties. This is the default.
724 *
725 * PDMAUDIOSTREAMLAYOUT_RAW:
726 * Can be one or many streams at once, depending on the stream's mixing buffer setup.
727 * The audio data will get handled as PDMAUDIOFRAME frames without any modification done. */
728 PDMAUDIOSTREAMLAYOUT enmLayout;
729 /** Device emulation-specific data needed for the audio connector. */
730 struct
731 {
732 /** Scheduling hint set by the device emulation about when this stream is being served on average (in ms).
733 * Can be 0 if not hint given or some other mechanism (e.g. callbacks) is being used. */
734 uint32_t cMsSchedulingHint;
735 } Device;
736 /**
737 * Backend-specific data for the stream.
738 * On input (requested configuration) those values are set by the audio connector to let the backend know what we expect.
739 * On output (acquired configuration) those values reflect the values set and used by the backend.
740 * Set by the backend on return. Not all backends support all values / features.
741 */
742 struct
743 {
744 /** Period size of the stream (in audio frames).
745 * This value reflects the number of audio frames in between each hardware interrupt on the
746 * backend (host) side. 0 if not set / available by the backend. */
747 uint32_t cFramesPeriod;
748 /** (Ring) buffer size (in audio frames). Often is a multiple of cFramesPeriod.
749 * 0 if not set / available by the backend. */
750 uint32_t cFramesBufferSize;
751 /** Pre-buffering size (in audio frames). Frames needed in buffer before the stream becomes active (pre buffering).
752 * The bigger this value is, the more latency for the stream will occur.
753 * 0 if not set / available by the backend. UINT32_MAX if not defined (yet). */
754 uint32_t cFramesPreBuffering;
755 } Backend;
756 uint32_t u32Padding;
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) ((frames) << (pCfg->Props).cShift)
768/** Converts bytes to (audio) frames. */
769#define PDMAUDIOSTREAMCFG_B2F(pCfg, cb) (cb >> (pCfg->Props).cShift)
770
771/**
772 * Audio mixer controls.
773 */
774typedef enum PDMAUDIOMIXERCTL
775{
776 /** Invalid zero value as per usual (guards against using unintialized values). */
777 PDMAUDIOMIXERCTL_INVALID = 0,
778 /** Unknown mixer control. */
779 PDMAUDIOMIXERCTL_UNKNOWN,
780 /** Master volume. */
781 PDMAUDIOMIXERCTL_VOLUME_MASTER,
782 /** Front. */
783 PDMAUDIOMIXERCTL_FRONT,
784 /** Center / LFE (Subwoofer). */
785 PDMAUDIOMIXERCTL_CENTER_LFE,
786 /** Rear. */
787 PDMAUDIOMIXERCTL_REAR,
788 /** Line-In. */
789 PDMAUDIOMIXERCTL_LINE_IN,
790 /** Microphone-In. */
791 PDMAUDIOMIXERCTL_MIC_IN,
792 /** Hack to blow the type up to 32-bit. */
793 PDMAUDIOMIXERCTL_32BIT_HACK = 0x7fffffff
794} PDMAUDIOMIXERCTL;
795
796/**
797 * Audio stream commands.
798 *
799 * Used in the audio connector as well as in the actual host backends.
800 */
801typedef enum PDMAUDIOSTREAMCMD
802{
803 /** Invalid zero value as per usual (guards against using unintialized values). */
804 PDMAUDIOSTREAMCMD_INVALID = 0,
805 /** Unknown command, do not use. */
806 PDMAUDIOSTREAMCMD_UNKNOWN,
807 /** Enables the stream. */
808 PDMAUDIOSTREAMCMD_ENABLE,
809 /** Disables the stream.
810 * For output streams this stops the stream after playing the remaining (buffered) audio data.
811 * For input streams this will deliver the remaining (captured) audio data and not accepting
812 * any new audio input data afterwards. */
813 PDMAUDIOSTREAMCMD_DISABLE,
814 /** Pauses the stream. */
815 PDMAUDIOSTREAMCMD_PAUSE,
816 /** Resumes the stream. */
817 PDMAUDIOSTREAMCMD_RESUME,
818 /** Tells the stream to drain itself.
819 * For output streams this plays all remaining (buffered) audio frames,
820 * for input streams this permits receiving any new audio frames.
821 * No supported by all backends. */
822 PDMAUDIOSTREAMCMD_DRAIN,
823 /** Tells the stream to drop all (buffered) audio data immediately.
824 * No supported by all backends. */
825 PDMAUDIOSTREAMCMD_DROP,
826 /** Hack to blow the type up to 32-bit. */
827 PDMAUDIOSTREAMCMD_32BIT_HACK = 0x7fffffff
828} PDMAUDIOSTREAMCMD;
829
830/**
831 * Audio volume parameters.
832 */
833typedef struct PDMAUDIOVOLUME
834{
835 /** Set to @c true if this stream is muted, @c false if not. */
836 bool fMuted;
837 /** Left channel volume.
838 * Range is from [0 ... 255], whereas 0 specifies
839 * the most silent and 255 the loudest value. */
840 uint8_t uLeft;
841 /** Right channel volume.
842 * Range is from [0 ... 255], whereas 0 specifies
843 * the most silent and 255 the loudest value. */
844 uint8_t uRight;
845} PDMAUDIOVOLUME;
846/** Pointer to audio volume settings. */
847typedef PDMAUDIOVOLUME *PPDMAUDIOVOLUME;
848
849/** Defines the minimum volume allowed. */
850#define PDMAUDIO_VOLUME_MIN (0)
851/** Defines the maximum volume allowed. */
852#define PDMAUDIO_VOLUME_MAX (255)
853
854/**
855 * Rate processing information of a source & destination audio stream.
856 *
857 * This is needed because both streams can differ regarding their rates and
858 * therefore need to be treated accordingly.
859 */
860typedef struct PDMAUDIOSTREAMRATE
861{
862 /** Current (absolute) offset in the output (destination) stream.
863 * @todo r=bird: Please reveal which unit these members are given in. */
864 uint64_t offDst;
865 /** Increment for moving offDst for the destination stream.
866 * This is needed because the source <-> destination rate might be different. */
867 uint64_t uDstInc;
868 /** Current (absolute) offset in the input stream. */
869 uint32_t offSrc;
870 /** Explicit alignment padding. */
871 uint32_t u32AlignmentPadding;
872 /** Last processed frame of the input stream.
873 * Needed for interpolation. */
874 PDMAUDIOFRAME SrcFrameLast;
875} PDMAUDIOSTREAMRATE;
876/** Pointer to rate processing information of a stream. */
877typedef PDMAUDIOSTREAMRATE *PPDMAUDIOSTREAMRATE;
878
879/**
880 * Mixing buffer volume parameters.
881 *
882 * The volume values are in fixed point style and must be converted to/from
883 * before using with e.g. PDMAUDIOVOLUME.
884 */
885typedef struct PDMAUDMIXBUFVOL
886{
887 /** Set to @c true if this stream is muted, @c false if not. */
888 bool fMuted;
889 /** Left volume to apply during conversion.
890 * Pass 0 to convert the original values. May not apply to all conversion functions. */
891 uint32_t uLeft;
892 /** Right volume to apply during conversion.
893 * Pass 0 to convert the original values. May not apply to all conversion functions. */
894 uint32_t uRight;
895} PDMAUDMIXBUFVOL;
896/** Pointer to mixing buffer volument parameters. */
897typedef PDMAUDMIXBUFVOL *PPDMAUDMIXBUFVOL;
898
899/*
900 * Frame conversion parameters for the audioMixBufConvFromXXX / audioMixBufConvToXXX functions.
901 */
902typedef struct PDMAUDMIXBUFCONVOPTS
903{
904 /** Number of audio frames to convert. */
905 uint32_t cFrames;
906 union
907 {
908 struct
909 {
910 /** Volume to use for conversion. */
911 PDMAUDMIXBUFVOL Volume;
912 } From;
913 } RT_UNION_NM(u);
914} PDMAUDMIXBUFCONVOPTS;
915/** Pointer to conversion parameters for the audio mixer. */
916typedef PDMAUDMIXBUFCONVOPTS *PPDMAUDMIXBUFCONVOPTS;
917/** Pointer to const conversion parameters for the audio mixer. */
918typedef PDMAUDMIXBUFCONVOPTS const *PCPDMAUDMIXBUFCONVOPTS;
919
920/**
921 * @note All internal handling is done in audio frames, not in bytes!
922 * @todo r=bird: What does this node actually apply to?
923 */
924typedef uint32_t PDMAUDIOMIXBUFFMT;
925typedef PDMAUDIOMIXBUFFMT *PPDMAUDIOMIXBUFFMT;
926
927/**
928 * Convertion-from function used by the PDM audio buffer mixer.
929 *
930 * @returns Number of audio frames returned.
931 * @param paDst Where to return the converted frames.
932 * @param pvSrc The source frame bytes.
933 * @param cbSrc Number of bytes to convert.
934 * @param pOpts Conversion options.
935 * @todo r=bird: The @a paDst size is presumable given in @a pOpts->cFrames?
936 */
937typedef DECLCALLBACKTYPE(uint32_t, FNPDMAUDIOMIXBUFCONVFROM,(PPDMAUDIOFRAME paDst, const void *pvSrc, uint32_t cbSrc,
938 PCPDMAUDMIXBUFCONVOPTS pOpts));
939/** Pointer to a convertion-from function used by the PDM audio buffer mixer. */
940typedef FNPDMAUDIOMIXBUFCONVFROM *PFNPDMAUDIOMIXBUFCONVFROM;
941
942/**
943 * Convertion-to function used by the PDM audio buffer mixer.
944 *
945 * @param pvDst Output buffer.
946 * @param paSrc The input frames.
947 * @param pOpts Conversion options.
948 * @todo r=bird: The @a paSrc size is presumable given in @a pOpts->cFrames and
949 * this implicitly gives the pvDst size too, right?
950 */
951typedef DECLCALLBACKTYPE(void, FNPDMAUDIOMIXBUFCONVTO,(void *pvDst, PCPDMAUDIOFRAME paSrc, PCPDMAUDMIXBUFCONVOPTS pOpts));
952/** Pointer to a convertion-to function used by the PDM audio buffer mixer. */
953typedef FNPDMAUDIOMIXBUFCONVTO *PFNPDMAUDIOMIXBUFCONVTO;
954
955/** Pointer to audio mixing buffer. */
956typedef struct PDMAUDIOMIXBUF *PPDMAUDIOMIXBUF;
957
958/**
959 * Audio mixing buffer.
960 */
961typedef struct PDMAUDIOMIXBUF
962{
963 RTLISTNODE Node;
964 /** Name of the buffer. */
965 char *pszName;
966 /** Frame buffer. */
967 PPDMAUDIOFRAME pFrames;
968 /** Size of the frame buffer (in audio frames). */
969 uint32_t cFrames;
970 /** The current read position (in frames). */
971 uint32_t offRead;
972 /** The current write position (in frames). */
973 uint32_t offWrite;
974 /**
975 * Total frames already mixed down to the parent buffer (if any).
976 *
977 * Always starting at the parent's offRead position.
978 * @note Count always is specified in parent frames, as the sample count can
979 * differ between parent and child.
980 */
981 uint32_t cMixed;
982 /** How much audio frames are currently being used
983 * in this buffer.
984 * Note: This also is known as the distance in ring buffer terms. */
985 uint32_t cUsed;
986 /** Pointer to parent buffer (if any). */
987 PPDMAUDIOMIXBUF pParent;
988 /** List of children mix buffers to keep in sync with (if being a parent buffer). */
989 RTLISTANCHOR lstChildren;
990 /** Number of children mix buffers kept in lstChildren. */
991 uint32_t cChildren;
992 /** Intermediate structure for buffer conversion tasks. */
993 PPDMAUDIOSTREAMRATE pRate;
994 /** Internal representation of current volume used for mixing. */
995 PDMAUDMIXBUFVOL Volume;
996 /** This buffer's audio format.
997 * @todo r=bird: This seems to be a value created by AUDMIXBUF_AUDIO_FMT_MAKE(),
998 * which is not define here. Does this structure really belong here at
999 * all? */
1000 PDMAUDIOMIXBUFFMT uAudioFmt;
1001 /** Standard conversion-to function for set uAudioFmt. */
1002 PFNPDMAUDIOMIXBUFCONVTO pfnConvTo;
1003 /** Standard conversion-from function for set uAudioFmt. */
1004 PFNPDMAUDIOMIXBUFCONVFROM pfnConvFrom;
1005 /**
1006 * Ratio of the associated parent stream's frequency by this stream's
1007 * frequency (1<<32), represented as a signed 64 bit integer.
1008 *
1009 * For example, if the parent stream has a frequency of 44 khZ, and this
1010 * stream has a frequency of 11 kHz, the ration then would be
1011 * (44/11 * (1 << 32)).
1012 *
1013 * Currently this does not get changed once assigned.
1014 */
1015 int64_t iFreqRatio;
1016 /** For quickly converting frames <-> bytes and vice versa. */
1017 uint8_t cShift;
1018} PDMAUDIOMIXBUF;
1019
1020/** @name PDMAUDIOFILE_FLAGS_XXX
1021 * @{ */
1022/** No flags defined. */
1023#define PDMAUDIOFILE_FLAGS_NONE UINT32_C(0)
1024/** Keep the audio file even if it contains no audio data. */
1025#define PDMAUDIOFILE_FLAGS_KEEP_IF_EMPTY RT_BIT_32(0)
1026/** Audio file flag validation mask. */
1027#define PDMAUDIOFILE_FLAGS_VALID_MASK UINT32_C(0x1)
1028/** @} */
1029
1030/** Audio file default open flags.
1031 * @todo r=bird: What is the exact purpose of this? */
1032#define PDMAUDIOFILE_DEFAULT_OPEN_FLAGS (RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE)
1033
1034/**
1035 * Audio file types.
1036 */
1037typedef enum PDMAUDIOFILETYPE
1038{
1039 /** The customary invalid zero value. */
1040 PDMAUDIOFILETYPE_INVALID = 0,
1041 /** Unknown type, do not use. */
1042 PDMAUDIOFILETYPE_UNKNOWN,
1043 /** Raw (PCM) file. */
1044 PDMAUDIOFILETYPE_RAW,
1045 /** Wave (.WAV) file. */
1046 PDMAUDIOFILETYPE_WAV,
1047 /** Hack to blow the type up to 32-bit. */
1048 PDMAUDIOFILETYPE_32BIT_HACK = 0x7fffffff
1049} PDMAUDIOFILETYPE;
1050
1051/** @name PDMAUDIOFILENAME_FLAGS_XXX
1052 * @{ */
1053/** No flags defined. */
1054#define PDMAUDIOFILENAME_FLAGS_NONE UINT32_C(0)
1055/** Adds an ISO timestamp to the file name. */
1056#define PDMAUDIOFILENAME_FLAGS_TS RT_BIT(0)
1057/** @} */
1058
1059/**
1060 * Audio file handle.
1061 */
1062typedef struct PDMAUDIOFILE
1063{
1064 /** Type of the audio file. */
1065 PDMAUDIOFILETYPE enmType;
1066 /** Audio file flags, PDMAUDIOFILE_FLAGS_XXX. */
1067 uint32_t fFlags;
1068 /** Actual file handle. */
1069 RTFILE hFile;
1070 /** Data needed for the specific audio file type implemented.
1071 * Optional, can be NULL. */
1072 void *pvData;
1073 /** Data size (in bytes). */
1074 size_t cbData;
1075 /** File name and path. */
1076 char szName[RTPATH_MAX];
1077} PDMAUDIOFILE;
1078/** Pointer to an audio file handle. */
1079typedef PDMAUDIOFILE *PPDMAUDIOFILE;
1080
1081/** @name PDMAUDIOSTREAMSTS_FLAGS_XXX
1082 * @{ */
1083/** No flags being set. */
1084#define PDMAUDIOSTREAMSTS_FLAGS_NONE UINT32_C(0)
1085/** Whether this stream has been initialized by the
1086 * backend or not. */
1087#define PDMAUDIOSTREAMSTS_FLAGS_INITIALIZED RT_BIT_32(0)
1088/** Whether this stream is enabled or disabled. */
1089#define PDMAUDIOSTREAMSTS_FLAGS_ENABLED RT_BIT_32(1)
1090/** Whether this stream has been paused or not. This also implies
1091 * that this is an enabled stream! */
1092#define PDMAUDIOSTREAMSTS_FLAGS_PAUSED RT_BIT_32(2)
1093/** Whether this stream was marked as being disabled
1094 * but there are still associated guest output streams
1095 * which rely on its data. */
1096#define PDMAUDIOSTREAMSTS_FLAGS_PENDING_DISABLE RT_BIT_32(3)
1097/** Whether this stream is in re-initialization phase.
1098 * All other bits remain untouched to be able to restore
1099 * the stream's state after the re-initialization bas been
1100 * finished. */
1101#define PDMAUDIOSTREAMSTS_FLAGS_PENDING_REINIT RT_BIT_32(4)
1102/** Validation mask. */
1103#define PDMAUDIOSTREAMSTS_VALID_MASK UINT32_C(0x0000001F)
1104/** Stream status flag, PDMAUDIOSTREAMSTS_FLAGS_XXX. */
1105typedef uint32_t PDMAUDIOSTREAMSTS;
1106/** @} */
1107
1108/**
1109 * Backend status.
1110 */
1111typedef enum PDMAUDIOBACKENDSTS
1112{
1113 /** Unknown/invalid status. */
1114 PDMAUDIOBACKENDSTS_UNKNOWN = 0,
1115 /** No backend attached. */
1116 PDMAUDIOBACKENDSTS_NOT_ATTACHED,
1117 /** The backend is in its initialization phase.
1118 * Not all backends support this status. */
1119 PDMAUDIOBACKENDSTS_INITIALIZING,
1120 /** The backend has stopped its operation. */
1121 PDMAUDIOBACKENDSTS_STOPPED,
1122 /** The backend is up and running. */
1123 PDMAUDIOBACKENDSTS_RUNNING,
1124 /** The backend ran into an error and is unable to recover.
1125 * A manual re-initialization might help. */
1126 PDMAUDIOBACKENDSTS_ERROR,
1127 /** Hack to blow the type up to 32-bit. */
1128 PDMAUDIOBACKENDSTS_32BIT_HACK = 0x7fffffff
1129} PDMAUDIOBACKENDSTS;
1130
1131/**
1132 * The specifics for an audio input stream.
1133 *
1134 * Do not use directly, use PDMAUDIOSTREAM instead.
1135 */
1136typedef struct PDMAUDIOSTREAMIN
1137{
1138#ifdef VBOX_WITH_STATISTICS
1139 struct
1140 {
1141 STAMCOUNTER TotalFramesCaptured;
1142 STAMCOUNTER AvgFramesCaptured;
1143 STAMCOUNTER TotalTimesCaptured;
1144 STAMCOUNTER TotalFramesRead;
1145 STAMCOUNTER AvgFramesRead;
1146 STAMCOUNTER TotalTimesRead;
1147 } Stats;
1148#endif
1149 struct
1150 {
1151 /** File for writing stream reads. */
1152 PPDMAUDIOFILE pFileStreamRead;
1153 /** File for writing non-interleaved captures. */
1154 PPDMAUDIOFILE pFileCaptureNonInterleaved;
1155 } Dbg;
1156} PDMAUDIOSTREAMIN;
1157/** Pointer to the specifics for an audio input stream. */
1158typedef PDMAUDIOSTREAMIN *PPDMAUDIOSTREAMIN;
1159
1160/**
1161 * The specifics for an audio output stream.
1162 *
1163 * Do not use directly, use PDMAUDIOSTREAM instead.
1164 */
1165typedef struct PDMAUDIOSTREAMOUT
1166{
1167#ifdef VBOX_WITH_STATISTICS
1168 struct
1169 {
1170 STAMCOUNTER TotalFramesPlayed;
1171 STAMCOUNTER AvgFramesPlayed;
1172 STAMCOUNTER TotalTimesPlayed;
1173 STAMCOUNTER TotalFramesWritten;
1174 STAMCOUNTER AvgFramesWritten;
1175 STAMCOUNTER TotalTimesWritten;
1176 } Stats;
1177#endif
1178 struct
1179 {
1180 /** File for writing stream writes. */
1181 PPDMAUDIOFILE pFileStreamWrite;
1182 /** File for writing stream playback. */
1183 PPDMAUDIOFILE pFilePlayNonInterleaved;
1184 } Dbg;
1185} PDMAUDIOSTREAMOUT;
1186/** Pointer to the specifics for an audio output stream. */
1187typedef PDMAUDIOSTREAMOUT *PPDMAUDIOSTREAMOUT;
1188
1189/** Pointer to an audio stream. */
1190typedef struct PDMAUDIOSTREAM *PPDMAUDIOSTREAM;
1191
1192/**
1193 * Audio stream context.
1194 * Needed for separating data from the guest and host side (per stream).
1195 */
1196typedef struct PDMAUDIOSTREAMCTX
1197{
1198 /** The stream's audio configuration. */
1199 PDMAUDIOSTREAMCFG Cfg;
1200 /** This stream's mixing buffer. */
1201 PDMAUDIOMIXBUF MixBuf;
1202} PDMAUDIOSTREAMCTX;
1203
1204/** Pointer to an audio stream context. */
1205typedef struct PDMAUDIOSTREAM *PPDMAUDIOSTREAMCTX;
1206
1207/** No stream warning flags set. */
1208#define PDMAUDIOSTREAM_WARN_FLAGS_NONE 0
1209/** Warned about a disabled stream. */
1210#define PDMAUDIOSTREAM_WARN_FLAGS_DISABLED RT_BIT(0)
1211
1212/**
1213 * An input or output audio stream.
1214 */
1215typedef struct PDMAUDIOSTREAM
1216{
1217 /** List node. */
1218 RTLISTNODE Node;
1219 /** Name of this stream. */
1220 char szName[64];
1221 /** Number of references to this stream.
1222 * Only can be destroyed when the reference count reaches 0. */
1223 uint32_t cRefs;
1224 /** Number of (re-)tries while re-initializing the stream. */
1225 uint32_t cTriesReInit;
1226 /** Warnings shown already in the release log.
1227 * See PDMAUDIOSTREAM_WARN_FLAGS_XXX defines. */
1228 uint32_t fWarningsShown;
1229 /** Stream status flag. */
1230 PDMAUDIOSTREAMSTS fStatus;
1231 /** Audio direction of this stream. */
1232 PDMAUDIODIR enmDir;
1233 /** For output streams this indicates whether the stream has reached
1234 * its playback threshold, e.g. is playing audio.
1235 * For input streams this indicates whether the stream has enough input
1236 * data to actually start reading audio. */
1237 bool fThresholdReached;
1238 bool afPadding[3];
1239 /** The guest side of the stream. */
1240 PDMAUDIOSTREAMCTX Guest;
1241 /** The host side of the stream. */
1242 PDMAUDIOSTREAMCTX Host;
1243 /** Union for input/output specifics depending on enmDir. */
1244 union
1245 {
1246 PDMAUDIOSTREAMIN In;
1247 PDMAUDIOSTREAMOUT Out;
1248 } RT_UNION_NM(u);
1249 /** Timestamp (in ns) since last trying to re-initialize.
1250 * Might be 0 if has not been tried yet. */
1251 uint64_t tsLastReInitNs;
1252 /** Timestamp (in ns) since last iteration. */
1253 uint64_t tsLastIteratedNs;
1254 /** Timestamp (in ns) since last playback / capture. */
1255 uint64_t tsLastPlayedCapturedNs;
1256 /** Timestamp (in ns) since last read (input streams) or
1257 * write (output streams). */
1258 uint64_t tsLastReadWrittenNs;
1259 /** Data to backend-specific stream data.
1260 * This data block will be casted by the backend to access its backend-dependent data.
1261 *
1262 * That way the backends do not have access to the audio connector's data. */
1263 void *pvBackend;
1264 /** Size (in bytes) of the backend-specific stream data. */
1265 size_t cbBackend;
1266} PDMAUDIOSTREAM;
1267
1268
1269/**
1270 * Audio callback source.
1271 */
1272typedef enum PDMAUDIOCBSOURCE
1273{
1274 /** Invalid, do not use. */
1275 PDMAUDIOCBSOURCE_INVALID = 0,
1276 /** Device emulation. */
1277 PDMAUDIOCBSOURCE_DEVICE,
1278 /** Audio connector interface. */
1279 PDMAUDIOCBSOURCE_CONNECTOR,
1280 /** Backend (lower). */
1281 PDMAUDIOCBSOURCE_BACKEND,
1282 /** Hack to blow the type up to 32-bit. */
1283 PDMAUDIOCBSOURCE_32BIT_HACK = 0x7fffffff
1284} PDMAUDIOCBSOURCE;
1285
1286/**
1287 * Audio device callback types.
1288 * Those callbacks are being sent from the audio connector -> device emulation.
1289 */
1290typedef enum PDMAUDIODEVICECBTYPE
1291{
1292 /** Invalid, do not use. */
1293 PDMAUDIODEVICECBTYPE_INVALID = 0,
1294 /** Data is availabe as input for passing to the device emulation. */
1295 PDMAUDIODEVICECBTYPE_DATA_INPUT,
1296 /** Free data for the device emulation to write to the backend. */
1297 PDMAUDIODEVICECBTYPE_DATA_OUTPUT,
1298 /** Hack to blow the type up to 32-bit. */
1299 PDMAUDIODEVICECBTYPE_32BIT_HACK = 0x7fffffff
1300} PDMAUDIODEVICECBTYPE;
1301
1302#if 0 /** @todo r=bird: Who needs this exactly? Fix the style or remove */
1303/**
1304 * Device callback data for audio input.
1305 */
1306typedef struct PDMAUDIODEVICECBDATA_DATA_INPUT
1307{
1308 /** Input: How many bytes are availabe as input for passing
1309 * to the device emulation. */
1310 uint32_t cbInAvail;
1311 /** Output: How many bytes have been read. */
1312 uint32_t cbOutRead;
1313} PDMAUDIODEVICECBDATA_DATA_INPUT;
1314typedef PDMAUDIODEVICECBDATA_DATA_INPUT *PPDMAUDIODEVICECBDATA_DATA_INPUT;
1315
1316/**
1317 * Device callback data for audio output.
1318 */
1319typedef struct PDMAUDIODEVICECBDATA_DATA_OUTPUT
1320{
1321 /** Input: How many bytes are free for the device emulation to write. */
1322 uint32_t cbInFree;
1323 /** Output: How many bytes were written by the device emulation. */
1324 uint32_t cbOutWritten;
1325} PDMAUDIODEVICECBDATA_DATA_OUTPUT, *PPDMAUDIODEVICECBDATA_DATA_OUTPUT;
1326#endif
1327
1328/**
1329 * Audio backend callback types.
1330 * Those callbacks are being sent from the backend -> audio connector.
1331 */
1332typedef enum PDMAUDIOBACKENDCBTYPE
1333{
1334 /** Invalid, do not use. */
1335 PDMAUDIOBACKENDCBTYPE_INVALID = 0,
1336 /** The backend's status has changed. */
1337 PDMAUDIOBACKENDCBTYPE_STATUS,
1338 /** One or more host audio devices have changed. */
1339 PDMAUDIOBACKENDCBTYPE_DEVICES_CHANGED,
1340 /** Hack to blow the type up to 32-bit. */
1341 PDMAUDIOBACKENDCBTYPE_32BIT_HACK = 0x7fffffff
1342} PDMAUDIOBACKENDCBTYPE;
1343
1344/** Pointer to a host audio interface. */
1345typedef struct PDMIHOSTAUDIO *PPDMIHOSTAUDIO;
1346
1347/**
1348 * Host audio callback function.
1349 * This function will be called from a backend to communicate with the host audio interface.
1350 *
1351 * @returns IPRT status code.
1352 * @param pDrvIns Pointer to driver instance which called us.
1353 * @param enmType Callback type.
1354 * @param pvUser User argument.
1355 * @param cbUser Size (in bytes) of user argument.
1356 */
1357typedef DECLCALLBACKTYPE(int, FNPDMHOSTAUDIOCALLBACK,(PPDMDRVINS pDrvIns, PDMAUDIOBACKENDCBTYPE enmType,
1358 void *pvUser, size_t cbUser));
1359/** Pointer to a FNPDMHOSTAUDIOCALLBACK(). */
1360typedef FNPDMHOSTAUDIOCALLBACK *PFNPDMHOSTAUDIOCALLBACK;
1361
1362/**
1363 * Audio callback registration record.
1364 */
1365typedef struct PDMAUDIOCBRECORD
1366{
1367 /** List node. */
1368 RTLISTANCHOR Node;
1369 /** Callback source. */
1370 PDMAUDIOCBSOURCE enmSource;
1371 /** Callback type, based on the given source. */
1372 union
1373 {
1374 /** Device callback stuff. */
1375 struct
1376 {
1377 PDMAUDIODEVICECBTYPE enmType;
1378 } Device;
1379 } RT_UNION_NM(u);
1380 /** Pointer to context data. Optional. */
1381 void *pvCtx;
1382 /** Size (in bytes) of context data.
1383 * Must be 0 if pvCtx is NULL. */
1384 size_t cbCtx;
1385} PDMAUDIOCBRECORD;
1386/** Pointer to an audio callback registration record. */
1387typedef PDMAUDIOCBRECORD *PPDMAUDIOCBRECORD;
1388
1389/** @todo r=bird: What is this exactly? */
1390#define PPDMAUDIOBACKENDSTREAM void *
1391
1392/** Pointer to a audio connector interface. */
1393typedef struct PDMIAUDIOCONNECTOR *PPDMIAUDIOCONNECTOR;
1394
1395/**
1396 * Audio connector interface (up).
1397 */
1398typedef struct PDMIAUDIOCONNECTOR
1399{
1400 /**
1401 * Enables or disables the given audio direction for this driver.
1402 *
1403 * When disabled, assiociated output streams consume written audio without passing them further down to the backends.
1404 * Associated input streams then return silence when read from those.
1405 *
1406 * @returns VBox status code.
1407 * @param pInterface Pointer to the interface structure containing the called function pointer.
1408 * @param enmDir Audio direction to enable or disable driver for.
1409 * @param fEnable Whether to enable or disable the specified audio direction.
1410 *
1411 * @note Be very careful when using this function, as this could
1412 * violate / run against the (global) VM settings. See @bugref{9882}.
1413 */
1414 DECLR3CALLBACKMEMBER(int, pfnEnable, (PPDMIAUDIOCONNECTOR pInterface, PDMAUDIODIR enmDir, bool fEnable));
1415
1416 /**
1417 * Returns whether the given audio direction for this driver is enabled or not.
1418 *
1419 * @returns True if audio is enabled for the given direction, false if not.
1420 * @param pInterface Pointer to the interface structure containing the called function pointer.
1421 * @param enmDir Audio direction to retrieve enabled status for.
1422 */
1423 DECLR3CALLBACKMEMBER(bool, pfnIsEnabled, (PPDMIAUDIOCONNECTOR pInterface, PDMAUDIODIR enmDir));
1424
1425 /**
1426 * Retrieves the current configuration of the host audio backend.
1427 *
1428 * @returns VBox status code.
1429 * @param pInterface Pointer to the interface structure containing the called function pointer.
1430 * @param pCfg Where to store the host audio backend configuration data.
1431 */
1432 DECLR3CALLBACKMEMBER(int, pfnGetConfig, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOBACKENDCFG pCfg));
1433
1434 /**
1435 * Retrieves the current status of the host audio backend.
1436 *
1437 * @returns Status of the host audio backend.
1438 * @param pInterface Pointer to the interface structure containing the called function pointer.
1439 * @param enmDir Audio direction to check host audio backend for. Specify PDMAUDIODIR_ANY for the overall
1440 * backend status.
1441 */
1442 DECLR3CALLBACKMEMBER(PDMAUDIOBACKENDSTS, pfnGetStatus, (PPDMIAUDIOCONNECTOR pInterface, PDMAUDIODIR enmDir));
1443
1444 /**
1445 * Creates an audio stream.
1446 *
1447 * @returns VBox status code.
1448 * @param pInterface Pointer to the interface structure containing the called function pointer.
1449 * @param pCfgHost Stream configuration for host side.
1450 * @param pCfgGuest Stream configuration for guest side.
1451 * @param ppStream Pointer where to return the created audio stream on success.
1452 */
1453 DECLR3CALLBACKMEMBER(int, pfnStreamCreate, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAMCFG pCfgHost,
1454 PPDMAUDIOSTREAMCFG pCfgGuest, PPDMAUDIOSTREAM *ppStream));
1455
1456 /**
1457 * Destroys an audio stream.
1458 *
1459 * @param pInterface Pointer to the interface structure containing the called function pointer.
1460 * @param pStream Pointer to audio stream.
1461 */
1462 DECLR3CALLBACKMEMBER(int, pfnStreamDestroy, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));
1463
1464 /**
1465 * Adds a reference to the specified audio stream.
1466 *
1467 * @returns New reference count. UINT32_MAX on error.
1468 * @param pInterface Pointer to the interface structure containing the called function pointer.
1469 * @param pStream Pointer to audio stream adding the reference to.
1470 */
1471 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamRetain, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));
1472
1473 /**
1474 * Releases a reference from the specified stream.
1475 *
1476 * @returns New reference count. UINT32_MAX on error.
1477 * @param pInterface Pointer to the interface structure containing the called function pointer.
1478 * @param pStream Pointer to audio stream releasing a reference from.
1479 */
1480 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamRelease, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));
1481
1482 /**
1483 * Reads PCM audio data from the host (input).
1484 *
1485 * @returns VBox status code.
1486 * @param pInterface Pointer to the interface structure containing the called function pointer.
1487 * @param pStream Pointer to audio stream to write to.
1488 * @param pvBuf Where to store the read data.
1489 * @param cbBuf Number of bytes to read.
1490 * @param pcbRead Bytes of audio data read. Optional.
1491 */
1492 DECLR3CALLBACKMEMBER(int, pfnStreamRead, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream,
1493 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead));
1494
1495 /**
1496 * Writes PCM audio data to the host (output).
1497 *
1498 * @returns VBox status code.
1499 * @param pInterface Pointer to the interface structure containing the called function pointer.
1500 * @param pStream Pointer to audio stream to read from.
1501 * @param pvBuf Audio data to be written.
1502 * @param cbBuf Number of bytes to be written.
1503 * @param pcbWritten Bytes of audio data written. Optional.
1504 */
1505 DECLR3CALLBACKMEMBER(int, pfnStreamWrite, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream,
1506 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten));
1507
1508 /**
1509 * Controls a specific audio stream.
1510 *
1511 * @returns VBox status code.
1512 * @param pInterface Pointer to the interface structure containing the called function pointer.
1513 * @param pStream Pointer to audio stream.
1514 * @param enmStreamCmd The stream command to issue.
1515 */
1516 DECLR3CALLBACKMEMBER(int, pfnStreamControl, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream,
1517 PDMAUDIOSTREAMCMD enmStreamCmd));
1518
1519 /**
1520 * Processes stream data.
1521 *
1522 * @param pInterface Pointer to the interface structure containing the called function pointer.
1523 * @param pStream Pointer to audio stream.
1524 */
1525 DECLR3CALLBACKMEMBER(int, pfnStreamIterate, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));
1526
1527 /**
1528 * Returns the number of readable data (in bytes) of a specific audio input stream.
1529 *
1530 * @returns Number of readable data (in bytes).
1531 * @param pInterface Pointer to the interface structure containing the called function pointer.
1532 * @param pStream Pointer to audio stream.
1533 */
1534 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetReadable, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));
1535
1536 /**
1537 * Returns the number of writable data (in bytes) of a specific audio output stream.
1538 *
1539 * @returns Number of writable data (in bytes).
1540 * @param pInterface Pointer to the interface structure containing the called function pointer.
1541 * @param pStream Pointer to audio stream.
1542 */
1543 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetWritable, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));
1544
1545 /**
1546 * Returns the status of a specific audio stream.
1547 *
1548 * @returns Audio stream status
1549 * @param pInterface Pointer to the interface structure containing the called function pointer.
1550 * @param pStream Pointer to audio stream.
1551 */
1552 DECLR3CALLBACKMEMBER(PDMAUDIOSTREAMSTS, pfnStreamGetStatus, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream));
1553
1554 /**
1555 * Sets the audio volume of a specific audio stream.
1556 *
1557 * @returns VBox status code.
1558 * @param pInterface Pointer to the interface structure containing the called function pointer.
1559 * @param pStream Pointer to audio stream.
1560 * @param pVol Pointer to audio volume structure to set the stream's audio volume to.
1561 */
1562 DECLR3CALLBACKMEMBER(int, pfnStreamSetVolume, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream, PPDMAUDIOVOLUME pVol));
1563
1564 /**
1565 * Plays (transfers) available audio frames to the host backend. Only works with output streams.
1566 *
1567 * @returns VBox status code.
1568 * @param pInterface Pointer to the interface structure containing the called function pointer.
1569 * @param pStream Pointer to audio stream.
1570 * @param pcFramesPlayed Number of frames played. Optional.
1571 */
1572 DECLR3CALLBACKMEMBER(int, pfnStreamPlay, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream, uint32_t *pcFramesPlayed));
1573
1574 /**
1575 * Captures (transfers) available audio frames from the host backend. Only works with input streams.
1576 *
1577 * @returns VBox status code.
1578 * @param pInterface Pointer to the interface structure containing the called function pointer.
1579 * @param pStream Pointer to audio stream.
1580 * @param pcFramesCaptured Number of frames captured. Optional.
1581 */
1582 DECLR3CALLBACKMEMBER(int, pfnStreamCapture, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream,
1583 uint32_t *pcFramesCaptured));
1584
1585 /**
1586 * Registers (device) callbacks.
1587 * This is handy for letting the device emulation know of certain events, e.g. processing input / output data
1588 * or configuration changes.
1589 *
1590 * @returns VBox status code.
1591 * @param pInterface Pointer to the interface structure containing the called function pointer.
1592 * @param paCallbacks Pointer to array of callbacks to register.
1593 * @param cCallbacks Number of callbacks to register.
1594 */
1595 DECLR3CALLBACKMEMBER(int, pfnRegisterCallbacks, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOCBRECORD paCallbacks,
1596 size_t cCallbacks));
1597
1598} PDMIAUDIOCONNECTOR;
1599
1600/** PDMIAUDIOCONNECTOR interface ID. */
1601#define PDMIAUDIOCONNECTOR_IID "00e704ef-0078-4bb6-0005-a5fd000ded9f"
1602
1603
1604/**
1605 * PDM host audio interface.
1606 */
1607typedef struct PDMIHOSTAUDIO
1608{
1609 /**
1610 * Initializes the host backend (driver).
1611 *
1612 * @returns VBox status code.
1613 * @param pInterface Pointer to the interface structure containing the called function pointer.
1614 */
1615 DECLR3CALLBACKMEMBER(int, pfnInit, (PPDMIHOSTAUDIO pInterface));
1616
1617 /**
1618 * Shuts down the host backend (driver).
1619 *
1620 * @returns VBox status code.
1621 * @param pInterface Pointer to the interface structure containing the called function pointer.
1622 */
1623 DECLR3CALLBACKMEMBER(void, pfnShutdown, (PPDMIHOSTAUDIO pInterface));
1624
1625 /**
1626 * Returns the host backend's configuration (backend).
1627 *
1628 * @returns VBox status code.
1629 * @param pInterface Pointer to the interface structure containing the called function pointer.
1630 * @param pBackendCfg Where to store the backend audio configuration to.
1631 */
1632 DECLR3CALLBACKMEMBER(int, pfnGetConfig, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg));
1633
1634 /**
1635 * Returns (enumerates) host audio device information.
1636 *
1637 * @returns VBox status code.
1638 * @param pInterface Pointer to the interface structure containing the called function pointer.
1639 * @param pDeviceEnum Where to return the enumerated audio devices.
1640 */
1641 DECLR3CALLBACKMEMBER(int, pfnGetDevices, (PPDMIHOSTAUDIO pInterface, PPDMAUDIODEVICEENUM pDeviceEnum));
1642
1643 /**
1644 * Returns the current status from the audio backend.
1645 *
1646 * @returns PDMAUDIOBACKENDSTS enum.
1647 * @param pInterface Pointer to the interface structure containing the called function pointer.
1648 * @param enmDir Audio direction to get status for. Pass PDMAUDIODIR_ANY for overall status.
1649 */
1650 DECLR3CALLBACKMEMBER(PDMAUDIOBACKENDSTS, pfnGetStatus, (PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir));
1651
1652 /**
1653 * Sets a callback the audio backend can call. Optional.
1654 *
1655 * @returns VBox status code.
1656 * @param pInterface Pointer to the interface structure containing the called function pointer.
1657 * @param pfnCallback The callback function to use, or NULL when unregistering.
1658 */
1659 DECLR3CALLBACKMEMBER(int, pfnSetCallback, (PPDMIHOSTAUDIO pInterface, PFNPDMHOSTAUDIOCALLBACK pfnCallback));
1660
1661 /**
1662 * Creates an audio stream using the requested stream configuration.
1663 *
1664 * If a backend is not able to create this configuration, it will return its
1665 * best match in the acquired configuration structure on success.
1666 *
1667 * @returns VBox status code.
1668 * @param pInterface Pointer to the interface structure containing the called function pointer.
1669 * @param pStream Pointer to audio stream.
1670 * @param pCfgReq Pointer to requested stream configuration.
1671 * @param pCfgAcq Pointer to acquired stream configuration.
1672 * @todo r=bird: Implementation (at least Alsa) seems to make undocumented
1673 * assumptions about the content of @a pCfgAcq.
1674 */
1675 DECLR3CALLBACKMEMBER(int, pfnStreamCreate, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
1676 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq));
1677
1678 /**
1679 * Destroys an audio stream.
1680 *
1681 * @returns VBox status code.
1682 * @param pInterface Pointer to the interface structure containing the called function pointer.
1683 * @param pStream Pointer to audio stream.
1684 */
1685 DECLR3CALLBACKMEMBER(int, pfnStreamDestroy, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));
1686
1687 /**
1688 * Controls an audio stream.
1689 *
1690 * @returns VBox status code.
1691 * @retval VERR_AUDIO_STREAM_NOT_READY if stream is not ready for required operation (yet).
1692 * @param pInterface Pointer to the interface structure containing the called function pointer.
1693 * @param pStream Pointer to audio stream.
1694 * @param enmStreamCmd The stream command to issue.
1695 */
1696 DECLR3CALLBACKMEMBER(int, pfnStreamControl, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
1697 PDMAUDIOSTREAMCMD enmStreamCmd));
1698
1699 /**
1700 * Returns the amount which is readable from the audio (input) stream.
1701 *
1702 * @returns For non-raw layout streams: Number of readable bytes.
1703 * for raw layout streams : Number of readable audio frames.
1704 * @param pInterface Pointer to the interface structure containing the called function pointer.
1705 * @param pStream Pointer to audio stream.
1706 */
1707 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetReadable, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));
1708
1709 /**
1710 * Returns the amount which is writable to the audio (output) stream.
1711 *
1712 * @returns For non-raw layout streams: Number of writable bytes.
1713 * for raw layout streams : Number of writable audio frames.
1714 * @param pInterface Pointer to the interface structure containing the called function pointer.
1715 * @param pStream Pointer to audio stream.
1716 */
1717 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetWritable, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));
1718
1719 /**
1720 * Returns the amount which is pending (in other words has not yet been processed) by/from the backend yet.
1721 * Optional.
1722 *
1723 * For input streams this is read audio data by the backend which has not been processed by the host yet.
1724 * For output streams this is written audio data to the backend which has not been processed by the backend yet.
1725 *
1726 * @returns For non-raw layout streams: Number of pending bytes.
1727 * for raw layout streams : Number of pending audio frames.
1728 * @param pInterface Pointer to the interface structure containing the called function pointer.
1729 * @param pStream Pointer to audio stream.
1730 */
1731 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetPending, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));
1732
1733 /**
1734 * Returns the current status of the given backend stream.
1735 *
1736 * @returns PDMAUDIOSTREAMSTS
1737 * @param pInterface Pointer to the interface structure containing the called function pointer.
1738 * @param pStream Pointer to audio stream.
1739 */
1740 DECLR3CALLBACKMEMBER(PDMAUDIOSTREAMSTS, pfnStreamGetStatus, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));
1741
1742 /**
1743 * Gives the host backend the chance to do some (necessary) iteration work.
1744 *
1745 * @returns VBox status code.
1746 * @param pInterface Pointer to the interface structure containing the called function pointer.
1747 * @param pStream Pointer to audio stream.
1748 */
1749 DECLR3CALLBACKMEMBER(int, pfnStreamIterate, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));
1750
1751 /**
1752 * Signals the backend that the host wants to begin playing for this iteration. Optional.
1753 *
1754 * @param pInterface Pointer to the interface structure containing the called function pointer.
1755 * @param pStream Pointer to audio stream.
1756 */
1757 DECLR3CALLBACKMEMBER(void, pfnStreamPlayBegin, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));
1758
1759 /**
1760 * Plays (writes to) an audio (output) stream.
1761 *
1762 * @returns VBox status code.
1763 * @param pInterface Pointer to the interface structure containing the called function pointer.
1764 * @param pStream Pointer to audio stream.
1765 * @param pvBuf Pointer to audio data buffer to play.
1766 * @param uBufSize The audio data buffer size (see note below for unit).
1767 * @param puWritten Number of unit written.
1768 * @note The @a uBufSize and @a puWritten values are in bytes for non-raw
1769 * layout streams and in frames for raw layout ones.
1770 */
1771 DECLR3CALLBACKMEMBER(int, pfnStreamPlay, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
1772 const void *pvBuf, uint32_t uBufSize, uint32_t *puWritten));
1773
1774 /**
1775 * Signals the backend that the host finished playing for this iteration. Optional.
1776 *
1777 * @param pInterface Pointer to the interface structure containing the called function pointer.
1778 * @param pStream Pointer to audio stream.
1779 */
1780 DECLR3CALLBACKMEMBER(void, pfnStreamPlayEnd, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));
1781
1782 /**
1783 * Signals the backend that the host wants to begin capturing for this iteration. Optional.
1784 *
1785 * @param pInterface Pointer to the interface structure containing the called function pointer.
1786 * @param pStream Pointer to audio stream.
1787 */
1788 DECLR3CALLBACKMEMBER(void, pfnStreamCaptureBegin, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));
1789
1790 /**
1791 * Captures (reads from) an audio (input) stream.
1792 *
1793 * @returns VBox status code.
1794 * @param pInterface Pointer to the interface structure containing the called function pointer.
1795 * @param pStream Pointer to audio stream.
1796 * @param pvBuf Buffer where to store read audio data.
1797 * @param uBufSize Size of the audio data buffer (see note below for unit).
1798 * @param puRead Returns number of units read.
1799 * @note The @a uBufSize and @a puRead values are in bytes for non-raw
1800 * layout streams and in frames for raw layout ones.
1801 */
1802 DECLR3CALLBACKMEMBER(int, pfnStreamCapture, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
1803 void *pvBuf, uint32_t uBufSize, uint32_t *puRead));
1804
1805 /**
1806 * Signals the backend that the host finished capturing for this iteration. Optional.
1807 *
1808 * @param pInterface Pointer to the interface structure containing the called function pointer.
1809 * @param pStream Pointer to audio stream.
1810 */
1811 DECLR3CALLBACKMEMBER(void, pfnStreamCaptureEnd, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));
1812
1813} PDMIHOSTAUDIO;
1814
1815/** PDMIHOSTAUDIO interface ID. */
1816#define PDMIHOSTAUDIO_IID "007847a0-0075-4964-007d-343f0010f081"
1817
1818/** @} */
1819
1820#endif /* !VBOX_INCLUDED_vmm_pdmaudioifs_h */
1821
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