VirtualBox

source: vbox/trunk/src/VBox/Devices/Audio/AudioMixBuffer.h@ 89316

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

Audio: Reworking the capture (recording) code path, part 3: Apply volume in the device mixer rather than in DrvAudio. bugref:9890

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.6 KB
Line 
1/* $Id: AudioMixBuffer.h 89314 2021-05-27 11:33:04Z vboxsync $ */
2/** @file
3 * Audio Mixing bufer convert audio samples to/from different rates / formats.
4 */
5
6/*
7 * Copyright (C) 2014-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef VBOX_INCLUDED_SRC_Audio_AudioMixBuffer_h
19#define VBOX_INCLUDED_SRC_Audio_AudioMixBuffer_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#include <iprt/cdefs.h>
25#include <VBox/vmm/pdmaudioifs.h>
26
27
28/**
29 * Rate processing information of a source & destination audio stream.
30 *
31 * This is needed because both streams can differ regarding their rates and
32 * therefore need to be treated accordingly.
33 */
34typedef struct AUDIOSTREAMRATE
35{
36 /** Current (absolute) offset in the output (destination) stream.
37 * @todo r=bird: Please reveal which unit these members are given in. */
38 uint64_t offDst;
39 /** Increment for moving offDst for the destination stream.
40 * This is needed because the source <-> destination rate might be different. */
41 uint64_t uDstInc;
42 /** Current (absolute) offset in the input stream. */
43 uint32_t offSrc;
44 /** Set if no conversion is necessary. */
45 bool fNoConversionNeeded;
46 bool afPadding[3];
47
48 /** Last processed frame of the input stream.
49 * Needed for interpolation. */
50 union
51 {
52 int64_t ai64Samples[2];
53 PDMAUDIOFRAME Frame;
54 } SrcLast;
55
56 /**
57 * Resampling function.
58 * @returns Number of destination frames written.
59 */
60 DECLR3CALLBACKMEMBER(uint32_t, pfnResample, (int64_t *pi64Dst, uint32_t cDstFrames,
61 int64_t const *pi64Src, uint32_t cSrcFrames, uint32_t *pcSrcFramesRead,
62 struct AUDIOSTREAMRATE *pRate));
63
64} AUDIOSTREAMRATE;
65/** Pointer to rate processing information of a stream. */
66typedef AUDIOSTREAMRATE *PAUDIOSTREAMRATE;
67
68/**
69 * Mixing buffer volume parameters.
70 *
71 * The volume values are in fixed point style and must be converted to/from
72 * before using with e.g. PDMAUDIOVOLUME.
73 */
74typedef struct AUDMIXBUFVOL
75{
76 /** Set to @c true if this stream is muted, @c false if not. */
77 bool fMuted;
78 /** Left volume to apply during conversion.
79 * Pass 0 to convert the original values. May not apply to all conversion functions. */
80 uint32_t uLeft;
81 /** Right volume to apply during conversion.
82 * Pass 0 to convert the original values. May not apply to all conversion functions. */
83 uint32_t uRight;
84} AUDMIXBUFVOL;
85/** Pointer to mixing buffer volument parameters. */
86typedef AUDMIXBUFVOL *PAUDMIXBUFVOL;
87
88/*
89 * Frame conversion parameters for the audioMixBufConvFromXXX / audioMixBufConvToXXX functions.
90 */
91typedef struct AUDMIXBUFCONVOPTS
92{
93 /** Number of audio frames to convert. */
94 uint32_t cFrames;
95 union
96 {
97 struct
98 {
99 /** Volume to use for conversion. */
100 AUDMIXBUFVOL Volume;
101 } From;
102 } RT_UNION_NM(u);
103} AUDMIXBUFCONVOPTS;
104/** Pointer to conversion parameters for the audio mixer. */
105typedef AUDMIXBUFCONVOPTS *PAUDMIXBUFCONVOPTS;
106/** Pointer to const conversion parameters for the audio mixer. */
107typedef AUDMIXBUFCONVOPTS const *PCAUDMIXBUFCONVOPTS;
108
109/**
110 * @note All internal handling is done in audio frames, not in bytes!
111 * @todo r=bird: What does this note actually apply to?
112 */
113typedef uint32_t AUDIOMIXBUFFMT;
114typedef AUDIOMIXBUFFMT *PAUDIOMIXBUFFMT;
115
116/**
117 * Convertion-from function used by the audio buffer mixer.
118 *
119 * @returns Number of audio frames returned.
120 * @param paDst Where to return the converted frames.
121 * @param pvSrc The source frame bytes.
122 * @param cbSrc Number of bytes to convert.
123 * @param pOpts Conversion options.
124 * @todo r=bird: The @a paDst size is presumable given in @a pOpts->cFrames?
125 */
126typedef DECLCALLBACKTYPE(uint32_t, FNAUDIOMIXBUFCONVFROM,(PPDMAUDIOFRAME paDst, const void *pvSrc, uint32_t cbSrc,
127 PCAUDMIXBUFCONVOPTS pOpts));
128/** Pointer to a convertion-from function used by the audio buffer mixer. */
129typedef FNAUDIOMIXBUFCONVFROM *PFNAUDIOMIXBUFCONVFROM;
130
131/**
132 * Convertion-to function used by the audio buffer mixer.
133 *
134 * @param pvDst Output buffer.
135 * @param paSrc The input frames.
136 * @param pOpts Conversion options.
137 * @todo r=bird: The @a paSrc size is presumable given in @a pOpts->cFrames and
138 * this implicitly gives the pvDst size too, right?
139 */
140typedef DECLCALLBACKTYPE(void, FNAUDIOMIXBUFCONVTO,(void *pvDst, PCPDMAUDIOFRAME paSrc, PCAUDMIXBUFCONVOPTS pOpts));
141/** Pointer to a convertion-to function used by the audio buffer mixer. */
142typedef FNAUDIOMIXBUFCONVTO *PFNAUDIOMIXBUFCONVTO;
143
144/** Pointer to audio mixing buffer. */
145typedef struct AUDIOMIXBUF *PAUDIOMIXBUF;
146/** Pointer to a const audio mixing buffer. */
147typedef struct AUDIOMIXBUF const *PCAUDIOMIXBUF;
148
149
150/**
151 * State & config for AudioMixBufPeek created by AudioMixBufInitPeekState.
152 */
153typedef struct AUDIOMIXBUFPEEKSTATE
154{
155 /** Encodes @a cFrames from @a paSrc to @a pvDst. */
156 DECLR3CALLBACKMEMBER(void, pfnEncode,(void *pvDst, int64_t const *paSrc, uint32_t cFrames, struct AUDIOMIXBUFPEEKSTATE *pState));
157 /** Sample rate conversion state (only used when needed). */
158 AUDIOSTREAMRATE Rate;
159 /** Source (mixer) channels. */
160 uint8_t cSrcChannels;
161 /** Destination channels. */
162 uint8_t cDstChannels;
163 /** Destination frame size. */
164 uint8_t cbDstFrame;
165} AUDIOMIXBUFPEEKSTATE;
166/** Pointer to peek state & config. */
167typedef AUDIOMIXBUFPEEKSTATE *PAUDIOMIXBUFPEEKSTATE;
168
169
170/**
171 * State & config for AudioMixBufWrite, AudioMixBufSilence, AudioMixBufBlend and
172 * AudioMixBufBlendGap, created by AudioMixBufInitWriteState.
173 */
174typedef struct AUDIOMIXBUFWRITESTATE
175{
176 /** Encodes @a cFrames from @a pvSrc to @a paDst. */
177 DECLR3CALLBACKMEMBER(void, pfnDecode,(int64_t *paDst, const void *pvSrc, uint32_t cFrames, struct AUDIOMIXBUFWRITESTATE *pState));
178 /** Encodes @a cFrames from @a pvSrc blending into @a paDst. */
179 DECLR3CALLBACKMEMBER(void, pfnDecodeBlend,(int64_t *paDst, const void *pvSrc, uint32_t cFrames, struct AUDIOMIXBUFWRITESTATE *pState));
180 /** Sample rate conversion state (only used when needed). */
181 AUDIOSTREAMRATE Rate;
182 /** Destination (mixer) channels. */
183 uint8_t cDstChannels;
184 /** Source hannels. */
185 uint8_t cSrcChannels;
186 /** Source frame size. */
187 uint8_t cbSrcFrame;
188} AUDIOMIXBUFWRITESTATE;
189/** Pointer to write state & config. */
190typedef AUDIOMIXBUFWRITESTATE *PAUDIOMIXBUFWRITESTATE;
191
192
193/**
194 * Audio mixing buffer.
195 */
196typedef struct AUDIOMIXBUF
197{
198 /** Magic value (AUDIOMIXBUF_MAGIC). */
199 uint32_t uMagic;
200 uint8_t abPadding[4];
201 /* ???Undocumented??? */
202 RTLISTNODE Node;
203 /** Name of the buffer. */
204 char *pszName;
205 /** Frame buffer. */
206 PPDMAUDIOFRAME pFrames;
207 /** Size of the frame buffer (in audio frames). */
208 uint32_t cFrames;
209 /** The current read position (in frames). */
210 uint32_t offRead;
211 /** The current write position (in frames). */
212 uint32_t offWrite;
213 /** Total frames already mixed down to the parent buffer (if any).
214 *
215 * Always starting at the parent's offRead position.
216 * @note Count always is specified in parent frames, as the sample count can
217 * differ between parent and child. */
218 uint32_t cMixed;
219 /** How much audio frames are currently being used in this buffer.
220 * @note This also is known as the distance in ring buffer terms. */
221 uint32_t cUsed;
222 /** Number of children mix buffers kept in lstChildren. */
223 uint32_t cChildren;
224 /** List of children mix buffers to keep in sync with (if being a parent buffer). */
225 RTLISTANCHOR lstChildren;
226 /** Pointer to parent buffer (if any). */
227 PAUDIOMIXBUF pParent;
228 /** Intermediate structure for buffer conversion tasks. */
229 PAUDIOSTREAMRATE pRate;
230 /** Internal representation of current volume used for mixing. */
231 AUDMIXBUFVOL Volume;
232 /** This buffer's audio format.
233 * @todo r=bird: This seems to be a value created by AUDMIXBUF_AUDIO_FMT_MAKE(),
234 * which is not define here. Does this structure really belong here at
235 * all? */
236 AUDIOMIXBUFFMT uAudioFmt;
237 /** Audio input properties.
238 * @note There is only one set of audio properties here because we have one
239 * mixer buffer for the guest side and a separate one for the host side.
240 * @todo r=bird: Why exactly do we need to use separate mixer buffers?
241 * Couldn't we just have different conversion fuctions and save the
242 * extra copying? */
243 PDMAUDIOPCMPROPS Props;
244 /** Standard conversion-to function for set uAudioFmt. */
245 PFNAUDIOMIXBUFCONVTO pfnConvTo;
246 /** Standard conversion-from function for set uAudioFmt. */
247 PFNAUDIOMIXBUFCONVFROM pfnConvFrom;
248
249 /** Ratio of the associated parent stream's frequency by this stream's
250 * frequency (1<<32), represented as a signed 64 bit integer.
251 *
252 * For example, if the parent stream has a frequency of 44 khZ, and this
253 * stream has a frequency of 11 kHz, the ration then would be
254 * (44/11 * (1 << 32)).
255 *
256 * Currently this does not get changed once assigned. */
257 int64_t iFreqRatio;
258} AUDIOMIXBUF;
259
260/** Magic value for AUDIOMIXBUF (Antonio Lucio Vivaldi). */
261#define AUDIOMIXBUF_MAGIC UINT32_C(0x16780304)
262/** Dead mixer buffer magic. */
263#define AUDIOMIXBUF_MAGIC_DEAD UINT32_C(0x17410728)
264
265
266/** Constructs 32 bit value for given frequency, number of channels, bits per sample and signed bit.
267 * @note This currently matches 1:1 the VRDE encoding -- this might change in the future, so better don't rely on this fact! */
268#define AUDMIXBUF_AUDIO_FMT_MAKE(freq, c, bps, s) ((((s) & 0x1) << 28) + (((bps) & 0xFF) << 20) + (((c) & 0xF) << 16) + ((freq) & 0xFFFF))
269
270/** Decodes frequency (Hz). */
271#define AUDMIXBUF_FMT_SAMPLE_FREQ(a) ((a) & 0xFFFF)
272/** Decodes number of channels. */
273#define AUDMIXBUF_FMT_CHANNELS(a) (((a) >> 16) & 0xF)
274/** Decodes signed bit. */
275#define AUDMIXBUF_FMT_SIGNED(a) (((a) >> 28) & 0x1)
276/** Decodes number of bits per sample. */
277#define AUDMIXBUF_FMT_BITS_PER_SAMPLE(a) (((a) >> 20) & 0xFF)
278/** Decodes number of bytes per sample. */
279#define AUDMIXBUF_FMT_BYTES_PER_SAMPLE(a) ((AUDMIXBUF_AUDIO_FMT_BITS_PER_SAMPLE(a) + 7) / 8)
280
281/** Converts (audio) frames to bytes. */
282#define AUDIOMIXBUF_F2B(a_pMixBuf, a_cFrames) PDMAUDIOPCMPROPS_F2B(&(a_pMixBuf)->Props, a_cFrames)
283/** Converts bytes to (audio) frames.
284 * @note Does *not* take the conversion ratio into account. */
285#define AUDIOMIXBUF_B2F(a_pMixBuf, a_cb) PDMAUDIOPCMPROPS_B2F(&(a_pMixBuf)->Props, a_cb)
286
287/** Converts frames to bytes, respecting the conversion ratio to
288 * a linked buffer. */
289#define AUDIOMIXBUF_F2B_RATIO(a_pMixBuf, a_cFrames) AUDIOMIXBUF_F2B(a_pMixBuf, AUDIOMIXBUF_F2F_RATIO(a_pMixBuf, a_cFrames))
290/** Converts number of frames according to the buffer's ratio.
291 * @todo r=bird: Why the *signed* cast? */
292#define AUDIOMIXBUF_F2F_RATIO(a_pMixBuf, a_cFrames) (((int64_t)(a_cFrames) << 32) / (a_pMixBuf)->iFreqRatio)
293
294
295int AudioMixBufInit(PAUDIOMIXBUF pMixBuf, const char *pszName, PCPDMAUDIOPCMPROPS pProps, uint32_t cFrames);
296void AudioMixBufDestroy(PAUDIOMIXBUF pMixBuf);
297
298int AudioMixBufInitPeekState(PCAUDIOMIXBUF pMixBuf, PAUDIOMIXBUFPEEKSTATE pState, PCPDMAUDIOPCMPROPS pDstProps);
299void AudioMixBufPeek(PCAUDIOMIXBUF pMixBuf, uint32_t offSrcFrame, uint32_t cMaxSrcFrames, uint32_t *pcSrcFramesPeeked,
300 PAUDIOMIXBUFPEEKSTATE pState, void *pvDst, uint32_t cbDst, uint32_t *pcbDstPeeked);
301void AudioMixBufAdvance(PAUDIOMIXBUF pMixBuf, uint32_t cFrames);
302void AudioMixBufDrop(PAUDIOMIXBUF pMixBuf);
303
304int AudioMixBufInitWriteState(PCAUDIOMIXBUF pMixBuf, PAUDIOMIXBUFWRITESTATE pState, PCPDMAUDIOPCMPROPS pSrcProps);
305void AudioMixBufWrite(PAUDIOMIXBUF pMixBuf, PAUDIOMIXBUFWRITESTATE pState, const void *pvSrcBuf, uint32_t cbSrcBuf,
306 uint32_t offDstFrame, uint32_t cMaxDstFrames, uint32_t *pcDstFramesWritten);
307void AudioMixBufSilence(PAUDIOMIXBUF pMixBuf, PAUDIOMIXBUFWRITESTATE pState, uint32_t offFrame, uint32_t cFrames);
308void AudioMixBufBlend(PAUDIOMIXBUF pMixBuf, PAUDIOMIXBUFWRITESTATE pState, const void *pvSrcBuf, uint32_t cbSrcBuf,
309 uint32_t offDstFrame, uint32_t cMaxDstFrames, uint32_t *pcDstFramesBlended);
310void AudioMixBufBlendGap(PAUDIOMIXBUF pMixBuf, PAUDIOMIXBUFWRITESTATE pState, uint32_t cFrames);
311void AudioMixBufCommit(PAUDIOMIXBUF pMixBuf, uint32_t cFrames);
312
313void AudioMixBufClear(PAUDIOMIXBUF pMixBuf);
314void AudioMixBufFinish(PAUDIOMIXBUF pMixBuf, uint32_t cFramesToClear);
315uint32_t AudioMixBufFree(PAUDIOMIXBUF pMixBuf);
316uint32_t AudioMixBufFreeBytes(PAUDIOMIXBUF pMixBuf);
317bool AudioMixBufIsEmpty(PAUDIOMIXBUF pMixBuf);
318int AudioMixBufLinkTo(PAUDIOMIXBUF pMixBuf, PAUDIOMIXBUF pParent);
319uint32_t AudioMixBufLive(PAUDIOMIXBUF pMixBuf);
320int AudioMixBufMixToParent(PAUDIOMIXBUF pMixBuf, uint32_t cSrcFrames, uint32_t *pcSrcMixed);
321int AudioMixBufMixToParentEx(PAUDIOMIXBUF pMixBuf, uint32_t cSrcOffset, uint32_t cSrcFrames, uint32_t *pcSrcMixed);
322int AudioMixBufPeekMutable(PAUDIOMIXBUF pMixBuf, uint32_t cFramesToRead, PPDMAUDIOFRAME *ppvSamples, uint32_t *pcFramesRead);
323uint32_t AudioMixBufUsed(PAUDIOMIXBUF pMixBuf);
324uint32_t AudioMixBufUsedBytes(PAUDIOMIXBUF pMixBuf);
325int AudioMixBufAcquireReadBlock(PAUDIOMIXBUF pMixBuf, void *pvBuf, uint32_t cbBuf, uint32_t *pcAcquiredFrames);
326int AudioMixBufAcquireReadBlockEx(PAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pDstProps,
327 void *pvBuf, uint32_t cbBuf, uint32_t *pcAcquiredFrames);
328void AudioMixBufReleaseReadBlock(PAUDIOMIXBUF pMixBuf, uint32_t cFrames);
329uint32_t AudioMixBufReadPos(PAUDIOMIXBUF pMixBuf);
330void AudioMixBufReset(PAUDIOMIXBUF pMixBuf);
331void AudioMixBufSetVolume(PAUDIOMIXBUF pMixBuf, PCPDMAUDIOVOLUME pVol);
332uint32_t AudioMixBufSize(PAUDIOMIXBUF pMixBuf);
333uint32_t AudioMixBufSizeBytes(PAUDIOMIXBUF pMixBuf);
334void AudioMixBufUnlink(PAUDIOMIXBUF pMixBuf);
335int AudioMixBufWriteAt(PAUDIOMIXBUF pMixBuf, uint32_t offSamples, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
336int AudioMixBufWriteAtEx(PAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pSrcProps, uint32_t offFrames,
337 const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
338int AudioMixBufWriteCirc(PAUDIOMIXBUF pMixBuf, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
339int AudioMixBufWriteCircEx(PAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pSrcProps,
340 const void *pvBuf,uint32_t cbBuf, uint32_t *pcWritten);
341uint32_t AudioMixBufWritePos(PAUDIOMIXBUF pMixBuf);
342
343#ifdef DEBUG
344void AudioMixBufDbgPrint(PAUDIOMIXBUF pMixBuf);
345void AudioMixBufDbgPrintChain(PAUDIOMIXBUF pMixBuf);
346#endif
347
348#endif /* !VBOX_INCLUDED_SRC_Audio_AudioMixBuffer_h */
349
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