VirtualBox

source: vbox/trunk/src/VBox/Devices/Audio/AudioMixer.h@ 88891

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

DrvAudio,Mixer: Changed PDMIAUDIOCONNECTOR::pfnStreamGetStatus into pfnStreamGetState and defined a simpler state enum (PDMAUDIOSTREAMSTATE) that fits the Mixer's need and nothing more. PDMAUDIOSTREAM_STS_XXX will soon be DrvAudio internal. Changed some state checks in the mixer from ENABLED and ENABLED+WRITABLE/READABLE (probably more that needs adjusting). bugref:9890

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.6 KB
Line 
1/* $Id: AudioMixer.h 88884 2021-05-05 18:27:18Z vboxsync $ */
2/** @file
3 * VBox audio - Mixing routines.
4 *
5 * The mixing routines are mainly used by the various audio device emulations
6 * to achieve proper multiplexing from/to attached devices LUNs.
7 */
8
9/*
10 * Copyright (C) 2014-2020 Oracle Corporation
11 *
12 * This file is part of VirtualBox Open Source Edition (OSE), as
13 * available from http://www.virtualbox.org. This file is free software;
14 * you can redistribute it and/or modify it under the terms of the GNU
15 * General Public License (GPL) as published by the Free Software
16 * Foundation, in version 2 as it comes in the "COPYING" file of the
17 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19 */
20
21#ifndef VBOX_INCLUDED_SRC_Audio_AudioMixer_h
22#define VBOX_INCLUDED_SRC_Audio_AudioMixer_h
23#ifndef RT_WITHOUT_PRAGMA_ONCE
24# pragma once
25#endif
26
27#include <iprt/cdefs.h>
28#include <iprt/critsect.h>
29
30#include <VBox/vmm/pdmaudioifs.h>
31#include "AudioMixBuffer.h"
32#include "AudioHlp.h"
33
34
35/** Pointer to an audio mixer sink. */
36typedef struct AUDMIXSINK *PAUDMIXSINK;
37
38
39/**
40 * Audio mixer instance.
41 */
42typedef struct AUDIOMIXER
43{
44 /** The mixer's name. */
45 char *pszName;
46 /** The mixer's critical section. */
47 RTCRITSECT CritSect;
48 /** The master volume of this mixer. */
49 PDMAUDIOVOLUME VolMaster;
50 /** List of audio mixer sinks. */
51 RTLISTANCHOR lstSinks;
52 /** Number of used audio sinks. */
53 uint8_t cSinks;
54 /** Mixer flags. See AUDMIXER_FLAGS_XXX. */
55 uint32_t fFlags;
56} AUDIOMIXER;
57/** Pointer to an audio mixer instance. */
58typedef AUDIOMIXER *PAUDIOMIXER;
59
60
61/** Defines an audio mixer stream's flags. */
62#define AUDMIXSTREAMFLAGS uint32_t
63
64/** No flags specified. */
65#define AUDMIXSTREAM_F_NONE 0
66/** The mixing stream is flagged as being enabled (active). */
67#define AUDMIXSTREAM_F_ENABLED RT_BIT(0)
68
69/** Defines an audio mixer stream's internal status. */
70#define AUDMIXSTREAMSTATUS uint32_t
71
72/** @name AUDMIXSTREAM_STATUS_XXX - mixer stream status.
73 * (This is a destilled version of PDMAUDIOSTREAM_STS_XXX.)
74 * @{ */
75/** No status set. */
76#define AUDMIXSTREAM_STATUS_NONE 0
77/** The mixing stream is enabled (active). */
78#define AUDMIXSTREAM_STATUS_ENABLED RT_BIT(0)
79/** The mixing stream can be read from.
80 * Always set together with AUDMIXSTREAM_STATUS_ENABLED. */
81#define AUDMIXSTREAM_STATUS_CAN_READ RT_BIT(1)
82/** The mixing stream can be written to.
83 * Always set together with AUDMIXSTREAM_STATUS_ENABLED. */
84#define AUDMIXSTREAM_STATUS_CAN_WRITE RT_BIT(2)
85/** @} */
86
87
88/**
89 * Audio mixer stream.
90 */
91typedef struct AUDMIXSTREAM
92{
93 /** List node. */
94 RTLISTNODE Node;
95 /** Name of this stream. */
96 char *pszName;
97 /** The statistics prefix. */
98 char *pszStatPrefix;
99 /** Sink this stream is attached to. */
100 PAUDMIXSINK pSink;
101 /** Stream flags of type AUDMIXSTREAM_F_. */
102 uint32_t fFlags;
103 /** Stream status of type AUDMIXSTREAM_STATUS_. */
104 uint32_t fStatus;
105 /** Pointer to audio connector being used. */
106 PPDMIAUDIOCONNECTOR pConn;
107 /** Pointer to PDM audio stream this mixer stream handles. */
108 PPDMAUDIOSTREAM pStream;
109 /** Mixing buffer peeking state & config. */
110 AUDIOMIXBUFPEEKSTATE PeekState;
111 /** Last read (recording) / written (playback) timestamp (in ns). */
112 uint64_t tsLastReadWrittenNs;
113 /** The streams's critical section. */
114 RTCRITSECT CritSect;
115} AUDMIXSTREAM, *PAUDMIXSTREAM;
116
117/** Defines an audio sink's current status. */
118#define AUDMIXSINKSTS uint32_t
119
120/** No status specified. */
121#define AUDMIXSINK_STS_NONE 0
122/** The sink is active and running. */
123#define AUDMIXSINK_STS_RUNNING RT_BIT(0)
124/** The sink is in a pending disable state. */
125#define AUDMIXSINK_STS_PENDING_DISABLE RT_BIT(1)
126/** Dirty flag.
127 * - For output sinks this means that there is data in the sink which has not
128 * been played yet.
129 * - For input sinks this means that there is data in the sink which has been
130 * recorded but not transferred to the destination yet. */
131#define AUDMIXSINK_STS_DIRTY RT_BIT(2)
132
133/**
134 * Audio mixer sink direction.
135 * @todo r=bird: use PDMAUDIODIR instead.
136 */
137typedef enum AUDMIXSINKDIR
138{
139 /** Unknown direction. */
140 AUDMIXSINKDIR_UNKNOWN = 0,
141 /** Input (capturing from a device). */
142 AUDMIXSINKDIR_INPUT,
143 /** Output (playing to a device). */
144 AUDMIXSINKDIR_OUTPUT,
145 /** The usual 32-bit hack. */
146 AUDMIXSINKDIR_32BIT_HACK = 0x7fffffff
147} AUDMIXSINKDIR;
148
149/**
150 * Audio mixer sink command.
151 */
152typedef enum AUDMIXSINKCMD
153{
154 /** Unknown command, do not use. */
155 AUDMIXSINKCMD_UNKNOWN = 0,
156 /** Enables the sink. */
157 AUDMIXSINKCMD_ENABLE,
158 /** Disables the sink. */
159 AUDMIXSINKCMD_DISABLE,
160 /** Pauses the sink. */
161 AUDMIXSINKCMD_PAUSE,
162 /** Resumes the sink. */
163 AUDMIXSINKCMD_RESUME,
164 /** Hack to blow the type up to 32-bit. */
165 AUDMIXSINKCMD_32BIT_HACK = 0x7fffffff
166} AUDMIXSINKCMD;
167
168/**
169 * Audio input sink specifics.
170 *
171 * Do not use directly. Instead, use AUDMIXSINK.
172 */
173typedef struct AUDMIXSINKIN
174{
175 /** The current recording source. Can be NULL if not set. */
176 PAUDMIXSTREAM pStreamRecSource;
177} AUDMIXSINKIN;
178
179/**
180 * Audio output sink specifics.
181 *
182 * Do not use directly. Instead, use AUDMIXSINK.
183 */
184typedef struct AUDMIXSINKOUT
185{
186} AUDMIXSINKOUT;
187
188/**
189 * Audio mixer sink.
190 */
191typedef struct AUDMIXSINK
192{
193 RTLISTNODE Node;
194 /** Pointer to mixer object this sink is bound to. */
195 PAUDIOMIXER pParent;
196 /** Name of this sink. */
197 char *pszName;
198 /** The sink direction, that is,
199 * if this sink handles input or output. */
200 AUDMIXSINKDIR enmDir;
201 /** The sink's critical section. */
202 RTCRITSECT CritSect;
203 /** This sink's mixing buffer, acting as
204 * a parent buffer for all streams this sink owns. */
205 AUDIOMIXBUF MixBuf;
206 /** Scratch buffer for multiplexing / mixing. Might be NULL if not needed. */
207 uint8_t *pabScratchBuf;
208 /** Size (in bytes) of pabScratchBuf. Might be 0 if not needed. */
209 size_t cbScratchBuf;
210 /** Union for input/output specifics. */
211 union
212 {
213 AUDMIXSINKIN In;
214 AUDMIXSINKOUT Out;
215 };
216 /** Sink status of type AUDMIXSINK_STS_XXX. */
217 AUDMIXSINKSTS fStatus;
218 /** The sink's PCM format. */
219 PDMAUDIOPCMPROPS PCMProps;
220 /** Number of streams assigned. */
221 uint8_t cStreams;
222 /** List of assigned streams.
223 * @note All streams have the same PCM properties, so the mixer does not do
224 * any conversion. */
225 /** @todo Use something faster -- vector maybe? */
226 RTLISTANCHOR lstStreams;
227 /** The volume of this sink. The volume always will
228 * be combined with the mixer's master volume. */
229 PDMAUDIOVOLUME Volume;
230 /** The volume of this sink, combined with the last set master volume. */
231 PDMAUDIOVOLUME VolumeCombined;
232 /** Timestamp since last update (in ms). */
233 uint64_t tsLastUpdatedMs;
234 /** Last read (recording) / written (playback) timestamp (in ns). */
235 uint64_t tsLastReadWrittenNs;
236 struct
237 {
238 PAUDIOHLPFILE pFile;
239 } Dbg;
240} AUDMIXSINK;
241
242/**
243 * Audio mixer operation.
244 */
245typedef enum AUDMIXOP
246{
247 /** Invalid operation, do not use. */
248 AUDMIXOP_INVALID = 0,
249 /** Copy data from A to B, overwriting data in B. */
250 AUDMIXOP_COPY,
251 /** Blend data from A with (existing) data in B. */
252 AUDMIXOP_BLEND,
253 /** The usual 32-bit hack. */
254 AUDMIXOP_32BIT_HACK = 0x7fffffff
255} AUDMIXOP;
256
257/** No flags specified. */
258#define AUDMIXSTRMCTL_F_NONE 0
259
260/** No mixer flags specified. */
261#define AUDMIXER_FLAGS_NONE 0
262/** Debug mode enabled.
263 * This writes .WAV file to the host, usually to the temporary directory. */
264#define AUDMIXER_FLAGS_DEBUG RT_BIT(0)
265/** Validation mask. */
266#define AUDMIXER_FLAGS_VALID_MASK UINT32_C(0x00000001)
267
268int AudioMixerCreate(const char *pszName, uint32_t fFlags, PAUDIOMIXER *ppMixer);
269int AudioMixerCreateSink(PAUDIOMIXER pMixer, const char *pszName, AUDMIXSINKDIR enmDir, PPDMDEVINS pDevIns, PAUDMIXSINK *ppSink);
270void AudioMixerDestroy(PAUDIOMIXER pMixer, PPDMDEVINS pDevIns);
271void AudioMixerInvalidate(PAUDIOMIXER pMixer);
272void AudioMixerRemoveSink(PAUDIOMIXER pMixer, PAUDMIXSINK pSink);
273int AudioMixerSetMasterVolume(PAUDIOMIXER pMixer, PPDMAUDIOVOLUME pVol);
274void AudioMixerDebug(PAUDIOMIXER pMixer, PCDBGFINFOHLP pHlp, const char *pszArgs);
275
276int AudioMixerSinkAddStream(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream);
277int AudioMixerSinkCreateStream(PAUDMIXSINK pSink, PPDMIAUDIOCONNECTOR pConnector, PPDMAUDIOSTREAMCFG pCfg,
278 AUDMIXSTREAMFLAGS fFlags, PPDMDEVINS pDevIns, PAUDMIXSTREAM *ppStream);
279int AudioMixerSinkCtl(PAUDMIXSINK pSink, AUDMIXSINKCMD enmCmd);
280void AudioMixerSinkDestroy(PAUDMIXSINK pSink, PPDMDEVINS pDevIns);
281uint32_t AudioMixerSinkGetReadable(PAUDMIXSINK pSink);
282uint32_t AudioMixerSinkGetWritable(PAUDMIXSINK pSink);
283AUDMIXSINKDIR AudioMixerSinkGetDir(PAUDMIXSINK pSink);
284const char *AudioMixerSinkGetName(const PAUDMIXSINK pSink);
285PAUDMIXSTREAM AudioMixerSinkGetRecordingSource(PAUDMIXSINK pSink);
286PAUDMIXSTREAM AudioMixerSinkGetStream(PAUDMIXSINK pSink, uint8_t uIndex);
287AUDMIXSINKSTS AudioMixerSinkGetStatus(PAUDMIXSINK pSink);
288uint8_t AudioMixerSinkGetStreamCount(PAUDMIXSINK pSink);
289bool AudioMixerSinkIsActive(PAUDMIXSINK pSink);
290int AudioMixerSinkRead(PAUDMIXSINK pSink, AUDMIXOP enmOp, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead);
291void AudioMixerSinkRemoveStream(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream);
292void AudioMixerSinkRemoveAllStreams(PAUDMIXSINK pSink);
293void AudioMixerSinkReset(PAUDMIXSINK pSink);
294void AudioMixerSinkGetFormat(PAUDMIXSINK pSink, PPDMAUDIOPCMPROPS pPCMProps);
295int AudioMixerSinkSetFormat(PAUDMIXSINK pSink, PCPDMAUDIOPCMPROPS pPCMProps);
296int AudioMixerSinkSetRecordingSource(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream);
297int AudioMixerSinkSetVolume(PAUDMIXSINK pSink, PPDMAUDIOVOLUME pVol);
298int AudioMixerSinkWrite(PAUDMIXSINK pSink, AUDMIXOP enmOp, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten);
299int AudioMixerSinkUpdate(PAUDMIXSINK pSink);
300
301int AudioMixerStreamCtl(PAUDMIXSTREAM pStream, PDMAUDIOSTREAMCMD enmCmd, uint32_t fCtl);
302void AudioMixerStreamDestroy(PAUDMIXSTREAM pStream, PPDMDEVINS pDevIns);
303
304#endif /* !VBOX_INCLUDED_SRC_Audio_AudioMixer_h */
305
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