VirtualBox

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

Last change on this file since 82252 was 82252, checked in by vboxsync, 5 years ago

vmm/pdmaudioifs.h: Style, docs and other nits. First, it's always _FLAGS_ never _FLAG_. Second, enums generally should start with _INVALID = 0 to ensure we don't mistake zero-initialized memory for valid data. Struct member names shall be indented on a tab (+4) boundrary. PDM is part of the VMM, so it follows the VMM coding guidelines strictly. Skip the 'Structure for keeping a ... around' fluff, the first sentence of a structure (or anything else for that matter) documentation shall be brief and to the point. It is automatically turned into a @brief. Furthermore, additional text should be a separate paragraph as it provides details the reader doesn't necessarily need to read. bugref:9218

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