VirtualBox

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

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

Audio: Eliminated the DrvAudio mixing buffers for output streams on devices without their own mixer. Changed the prebuffering to not default to the whole backend buffer size, but only 2/3 of it, so that there is room for a bit of incoming data from the device once we start playing. We don't want to have that gather in the device mixer or internal DMA buffers. This code needs some more testing and work, only tested on linux against ALSA. bugref:9890

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.1 KB
Line 
1/* $Id: AudioMixBuffer.h 88433 2021-04-09 12:55:19Z 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 (mixer) 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 * Audio mixing buffer.
172 */
173typedef struct AUDIOMIXBUF
174{
175 /** Magic value (AUDIOMIXBUF_MAGIC). */
176 uint32_t uMagic;
177 uint8_t abPadding[4];
178 /* ???Undocumented??? */
179 RTLISTNODE Node;
180 /** Name of the buffer. */
181 char *pszName;
182 /** Frame buffer. */
183 PPDMAUDIOFRAME pFrames;
184 /** Size of the frame buffer (in audio frames). */
185 uint32_t cFrames;
186 /** The current read position (in frames). */
187 uint32_t offRead;
188 /** The current write position (in frames). */
189 uint32_t offWrite;
190 /** Total frames already mixed down to the parent buffer (if any).
191 *
192 * Always starting at the parent's offRead position.
193 * @note Count always is specified in parent frames, as the sample count can
194 * differ between parent and child. */
195 uint32_t cMixed;
196 /** How much audio frames are currently being used in this buffer.
197 * @note This also is known as the distance in ring buffer terms. */
198 uint32_t cUsed;
199 /** Number of children mix buffers kept in lstChildren. */
200 uint32_t cChildren;
201 /** List of children mix buffers to keep in sync with (if being a parent buffer). */
202 RTLISTANCHOR lstChildren;
203 /** Pointer to parent buffer (if any). */
204 PAUDIOMIXBUF pParent;
205 /** Intermediate structure for buffer conversion tasks. */
206 PAUDIOSTREAMRATE pRate;
207 /** Internal representation of current volume used for mixing. */
208 AUDMIXBUFVOL Volume;
209 /** This buffer's audio format.
210 * @todo r=bird: This seems to be a value created by AUDMIXBUF_AUDIO_FMT_MAKE(),
211 * which is not define here. Does this structure really belong here at
212 * all? */
213 AUDIOMIXBUFFMT uAudioFmt;
214 /** Audio input properties.
215 * @note There is only one set of audio properties here because we have one
216 * mixer buffer for the guest side and a separate one for the host side.
217 * @todo r=bird: Why exactly do we need to use separate mixer buffers?
218 * Couldn't we just have different conversion fuctions and save the
219 * extra copying? */
220 PDMAUDIOPCMPROPS Props;
221 /** Standard conversion-to function for set uAudioFmt. */
222 PFNAUDIOMIXBUFCONVTO pfnConvTo;
223 /** Standard conversion-from function for set uAudioFmt. */
224 PFNAUDIOMIXBUFCONVFROM pfnConvFrom;
225
226 /** Ratio of the associated parent stream's frequency by this stream's
227 * frequency (1<<32), represented as a signed 64 bit integer.
228 *
229 * For example, if the parent stream has a frequency of 44 khZ, and this
230 * stream has a frequency of 11 kHz, the ration then would be
231 * (44/11 * (1 << 32)).
232 *
233 * Currently this does not get changed once assigned. */
234 int64_t iFreqRatio;
235} AUDIOMIXBUF;
236
237/** Magic value for AUDIOMIXBUF (Antonio Lucio Vivaldi). */
238#define AUDIOMIXBUF_MAGIC UINT32_C(0x16780304)
239/** Dead mixer buffer magic. */
240#define AUDIOMIXBUF_MAGIC_DEAD UINT32_C(0x17410728)
241
242
243/** Constructs 32 bit value for given frequency, number of channels, bits per sample and signed bit.
244 * @note This currently matches 1:1 the VRDE encoding -- this might change in the future, so better don't rely on this fact! */
245#define AUDMIXBUF_AUDIO_FMT_MAKE(freq, c, bps, s) ((((s) & 0x1) << 28) + (((bps) & 0xFF) << 20) + (((c) & 0xF) << 16) + ((freq) & 0xFFFF))
246
247/** Decodes frequency (Hz). */
248#define AUDMIXBUF_FMT_SAMPLE_FREQ(a) ((a) & 0xFFFF)
249/** Decodes number of channels. */
250#define AUDMIXBUF_FMT_CHANNELS(a) (((a) >> 16) & 0xF)
251/** Decodes signed bit. */
252#define AUDMIXBUF_FMT_SIGNED(a) (((a) >> 28) & 0x1)
253/** Decodes number of bits per sample. */
254#define AUDMIXBUF_FMT_BITS_PER_SAMPLE(a) (((a) >> 20) & 0xFF)
255/** Decodes number of bytes per sample. */
256#define AUDMIXBUF_FMT_BYTES_PER_SAMPLE(a) ((AUDMIXBUF_AUDIO_FMT_BITS_PER_SAMPLE(a) + 7) / 8)
257
258/** Converts (audio) frames to bytes. */
259#define AUDIOMIXBUF_F2B(a_pMixBuf, a_cFrames) PDMAUDIOPCMPROPS_F2B(&(a_pMixBuf)->Props, a_cFrames)
260/** Converts bytes to (audio) frames.
261 * @note Does *not* take the conversion ratio into account. */
262#define AUDIOMIXBUF_B2F(a_pMixBuf, a_cb) PDMAUDIOPCMPROPS_B2F(&(a_pMixBuf)->Props, a_cb)
263
264/** Converts frames to bytes, respecting the conversion ratio to
265 * a linked buffer. */
266#define AUDIOMIXBUF_F2B_RATIO(a_pMixBuf, a_cFrames) AUDIOMIXBUF_F2B(a_pMixBuf, AUDIOMIXBUF_F2F_RATIO(a_pMixBuf, a_cFrames))
267/** Converts number of frames according to the buffer's ratio.
268 * @todo r=bird: Why the *signed* cast? */
269#define AUDIOMIXBUF_F2F_RATIO(a_pMixBuf, a_cFrames) (((int64_t)(a_cFrames) << 32) / (a_pMixBuf)->iFreqRatio)
270
271
272int AudioMixBufInit(PAUDIOMIXBUF pMixBuf, const char *pszName, PCPDMAUDIOPCMPROPS pProps, uint32_t cFrames);
273void AudioMixBufDestroy(PAUDIOMIXBUF pMixBuf);
274
275int AudioMixBufInitPeekState(PCAUDIOMIXBUF pMixBuf, PAUDIOMIXBUFPEEKSTATE pState, PCPDMAUDIOPCMPROPS pDstProps);
276void AudioMixBufPeek(PCAUDIOMIXBUF pMixBuf, uint32_t offSrcFrame, uint32_t cMaxSrcFrames, uint32_t *pcSrcFramesPeeked,
277 PAUDIOMIXBUFPEEKSTATE pState, void *pvDst, uint32_t cbDst, uint32_t *pcbDstPeeked);
278void AudioMixBufAdvance(PAUDIOMIXBUF pMixBuf, uint32_t cFrames);
279void AudioMixBufDrop(PAUDIOMIXBUF pMixBuf);
280
281void AudioMixBufClear(PAUDIOMIXBUF pMixBuf);
282void AudioMixBufFinish(PAUDIOMIXBUF pMixBuf, uint32_t cFramesToClear);
283uint32_t AudioMixBufFree(PAUDIOMIXBUF pMixBuf);
284uint32_t AudioMixBufFreeBytes(PAUDIOMIXBUF pMixBuf);
285bool AudioMixBufIsEmpty(PAUDIOMIXBUF pMixBuf);
286int AudioMixBufLinkTo(PAUDIOMIXBUF pMixBuf, PAUDIOMIXBUF pParent);
287uint32_t AudioMixBufLive(PAUDIOMIXBUF pMixBuf);
288int AudioMixBufMixToParent(PAUDIOMIXBUF pMixBuf, uint32_t cSrcFrames, uint32_t *pcSrcMixed);
289int AudioMixBufMixToParentEx(PAUDIOMIXBUF pMixBuf, uint32_t cSrcOffset, uint32_t cSrcFrames, uint32_t *pcSrcMixed);
290int AudioMixBufPeekMutable(PAUDIOMIXBUF pMixBuf, uint32_t cFramesToRead, PPDMAUDIOFRAME *ppvSamples, uint32_t *pcFramesRead);
291uint32_t AudioMixBufUsed(PAUDIOMIXBUF pMixBuf);
292uint32_t AudioMixBufUsedBytes(PAUDIOMIXBUF pMixBuf);
293int AudioMixBufReadAt(PAUDIOMIXBUF pMixBuf, uint32_t offFrames, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead);
294int AudioMixBufReadAtEx(PAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pDstProps, uint32_t offFrames,
295 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead);
296int AudioMixBufAcquireReadBlock(PAUDIOMIXBUF pMixBuf, void *pvBuf, uint32_t cbBuf, uint32_t *pcAcquiredFrames);
297int AudioMixBufAcquireReadBlockEx(PAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pDstProps,
298 void *pvBuf, uint32_t cbBuf, uint32_t *pcAcquiredFrames);
299void AudioMixBufReleaseReadBlock(PAUDIOMIXBUF pMixBuf, uint32_t cFrames);
300uint32_t AudioMixBufReadPos(PAUDIOMIXBUF pMixBuf);
301void AudioMixBufReset(PAUDIOMIXBUF pMixBuf);
302void AudioMixBufSetVolume(PAUDIOMIXBUF pMixBuf, PPDMAUDIOVOLUME pVol);
303uint32_t AudioMixBufSize(PAUDIOMIXBUF pMixBuf);
304uint32_t AudioMixBufSizeBytes(PAUDIOMIXBUF pMixBuf);
305void AudioMixBufUnlink(PAUDIOMIXBUF pMixBuf);
306int AudioMixBufWriteAt(PAUDIOMIXBUF pMixBuf, uint32_t offSamples, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
307int AudioMixBufWriteAtEx(PAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pSrcProps, uint32_t offFrames,
308 const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
309int AudioMixBufWriteCirc(PAUDIOMIXBUF pMixBuf, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
310int AudioMixBufWriteCircEx(PAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pSrcProps,
311 const void *pvBuf,uint32_t cbBuf, uint32_t *pcWritten);
312uint32_t AudioMixBufWritePos(PAUDIOMIXBUF pMixBuf);
313
314#ifdef DEBUG
315void AudioMixBufDbgPrint(PAUDIOMIXBUF pMixBuf);
316void AudioMixBufDbgPrintChain(PAUDIOMIXBUF pMixBuf);
317#endif
318
319#endif /* !VBOX_INCLUDED_SRC_Audio_AudioMixBuffer_h */
320
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