VirtualBox

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

Last change on this file since 73353 was 73342, checked in by vboxsync, 6 years ago

Audio/AudioMixer: Added the option to also use a small ring buffer for the sink streams to buffer data between the device emulation and the audio connector (only output streams for now).

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