VirtualBox

source: vbox/trunk/src/VBox/Devices/Audio/AudioMixBuffer-Convert.cpp.h

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.4 KB
Line 
1/* $Id: AudioMixBuffer-Convert.cpp.h 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * Audio mixing buffer - Format conversion template.
4 */
5
6/*
7 * Copyright (C) 2014-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/* used to be: #define AUDMIXBUF_CONVERT(a_Name, a_Type, a_Min, a_Max, a_fSigned, a_cShift) */
30
31/* Clips a specific output value to a single sample value. */
32DECLINLINE(int32_t) RT_CONCAT(audioMixBufSampleFrom,a_Name)(a_Type aVal)
33{
34 /* left shifting of signed values is not defined, therefore the intermediate uint64_t cast */
35 if (a_fSigned)
36 return (int32_t) (((uint32_t) ((int32_t) aVal )) << (32 - a_cShift));
37 return (int32_t) (((uint32_t) ((int32_t) aVal - ((a_Max >> 1) + 1))) << (32 - a_cShift));
38}
39
40/* Clips a single sample value to a specific output value. */
41DECLINLINE(a_Type) RT_CONCAT(audioMixBufSampleTo,a_Name)(int32_t iVal)
42{
43 if (a_fSigned)
44 return (a_Type) (iVal >> (32 - a_cShift));
45 return (a_Type) ((iVal >> (32 - a_cShift)) + ((a_Max >> 1) + 1));
46}
47
48/* Encoders for peek: */
49
50/* Generic */
51static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncodeGeneric,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames,
52 PAUDIOMIXBUFPEEKSTATE pState)
53{
54 RT_NOREF_PV(pState);
55 uintptr_t const cSrcChannels = pState->cSrcChannels;
56 uintptr_t const cDstChannels = pState->cDstChannels;
57 a_Type *pDst = (a_Type *)pvDst;
58 while (cFrames-- > 0)
59 {
60 uintptr_t idxDst = cDstChannels;
61 while (idxDst-- > 0)
62 {
63 intptr_t idxSrc = pState->aidxChannelMap[idxDst];
64 if (idxSrc >= 0)
65 pDst[idxDst] = RT_CONCAT(audioMixBufSampleTo,a_Name)(pi32Src[idxSrc]);
66 else if (idxSrc != -2)
67 pDst[idxDst] = (a_fSigned) ? 0 : (a_Max >> 1);
68 else
69 pDst[idxDst] = 0;
70 }
71 pDst += cDstChannels;
72 pi32Src += cSrcChannels;
73 }
74}
75
76/* 2ch -> 2ch */
77static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode2ChTo2Ch,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames,
78 PAUDIOMIXBUFPEEKSTATE pState)
79{
80 RT_NOREF_PV(pState);
81 a_Type *pDst = (a_Type *)pvDst;
82 while (cFrames-- > 0)
83 {
84 pDst[0] = RT_CONCAT(audioMixBufSampleTo,a_Name)(pi32Src[0]);
85 pDst[1] = RT_CONCAT(audioMixBufSampleTo,a_Name)(pi32Src[1]);
86 AUDMIXBUF_MACRO_LOG(("%p: %RI32 / %RI32 => %RI32 / %RI32\n",
87 &pi32Src[0], pi32Src[0], pi32Src[1], (int32_t)pDst[0], (int32_t)pDst[1]));
88 pDst += 2;
89 pi32Src += 2;
90 }
91}
92
93/* 2ch -> 1ch */
94static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode2ChTo1Ch,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames,
95 PAUDIOMIXBUFPEEKSTATE pState)
96{
97 RT_NOREF_PV(pState);
98 a_Type *pDst = (a_Type *)pvDst;
99 while (cFrames-- > 0)
100 {
101 pDst[0] = RT_CONCAT(audioMixBufSampleTo,a_Name)(audioMixBufBlendSampleRet(pi32Src[0], pi32Src[1]));
102 pDst += 1;
103 pi32Src += 2;
104 }
105}
106
107/* 1ch -> 2ch */
108static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode1ChTo2Ch,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames,
109 PAUDIOMIXBUFPEEKSTATE pState)
110{
111 RT_NOREF_PV(pState);
112 a_Type *pDst = (a_Type *)pvDst;
113 while (cFrames-- > 0)
114 {
115 pDst[0] = pDst[1] = RT_CONCAT(audioMixBufSampleTo,a_Name)(pi32Src[0]);
116 pDst += 2;
117 pi32Src += 1;
118 }
119}
120/* 1ch -> 1ch */
121static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode1ChTo1Ch,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames,
122 PAUDIOMIXBUFPEEKSTATE pState)
123{
124 RT_NOREF_PV(pState);
125 a_Type *pDst = (a_Type *)pvDst;
126 while (cFrames-- > 0)
127 {
128 pDst[0] = RT_CONCAT(audioMixBufSampleTo,a_Name)(pi32Src[0]);
129 pDst += 1;
130 pi32Src += 1;
131 }
132}
133
134/* Decoders for write: */
135
136/* Generic */
137static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecodeGeneric,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames,
138 PAUDIOMIXBUFWRITESTATE pState)
139{
140 RT_NOREF_PV(pState);
141 uintptr_t const cSrcChannels = pState->cSrcChannels;
142 uintptr_t const cDstChannels = pState->cDstChannels;
143 a_Type const *pSrc = (a_Type const *)pvSrc;
144 while (cFrames-- > 0)
145 {
146 uintptr_t idxDst = cDstChannels;
147 while (idxDst-- > 0)
148 {
149 intptr_t idxSrc = pState->aidxChannelMap[idxDst];
150 if (idxSrc >= 0)
151 pi32Dst[idxDst] = RT_CONCAT(audioMixBufSampleFrom,a_Name)(pSrc[idxSrc]);
152 else if (idxSrc != -2)
153 pi32Dst[idxDst] = (a_fSigned) ? 0 : (a_Max >> 1);
154 else
155 pi32Dst[idxDst] = 0;
156 }
157 pi32Dst += cDstChannels;
158 pSrc += cSrcChannels;
159 }
160}
161
162/* 2ch -> 2ch */
163static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode2ChTo2Ch,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames,
164 PAUDIOMIXBUFWRITESTATE pState)
165{
166 RT_NOREF_PV(pState);
167 a_Type const *pSrc = (a_Type const *)pvSrc;
168 while (cFrames-- > 0)
169 {
170 pi32Dst[0] = RT_CONCAT(audioMixBufSampleFrom,a_Name)(pSrc[0]);
171 pi32Dst[1] = RT_CONCAT(audioMixBufSampleFrom,a_Name)(pSrc[1]);
172 AUDMIXBUF_MACRO_LOG(("%p: %RI32 / %RI32 => %RI32 / %RI32\n",
173 &pSrc[0], (int32_t)pSrc[0], (int32_t)pSrc[1], pi32Dst[0], pi32Dst[1]));
174 pi32Dst += 2;
175 pSrc += 2;
176 }
177}
178
179/* 2ch -> 1ch */
180static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode2ChTo1Ch,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames,
181 PAUDIOMIXBUFWRITESTATE pState)
182{
183 RT_NOREF_PV(pState);
184 a_Type const *pSrc = (a_Type const *)pvSrc;
185 while (cFrames-- > 0)
186 {
187 pi32Dst[0] = audioMixBufBlendSampleRet(RT_CONCAT(audioMixBufSampleFrom,a_Name)(pSrc[0]),
188 RT_CONCAT(audioMixBufSampleFrom,a_Name)(pSrc[1]));
189 pi32Dst += 1;
190 pSrc += 2;
191 }
192}
193
194/* 1ch -> 2ch */
195static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode1ChTo2Ch,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames,
196 PAUDIOMIXBUFWRITESTATE pState)
197{
198 RT_NOREF_PV(pState);
199 a_Type const *pSrc = (a_Type const *)pvSrc;
200 while (cFrames-- > 0)
201 {
202 pi32Dst[1] = pi32Dst[0] = RT_CONCAT(audioMixBufSampleFrom,a_Name)(pSrc[0]);
203 pi32Dst += 2;
204 pSrc += 1;
205 }
206}
207
208/* 1ch -> 1ch */
209static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode1ChTo1Ch,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames,
210 PAUDIOMIXBUFWRITESTATE pState)
211{
212 RT_NOREF_PV(pState);
213 a_Type const *pSrc = (a_Type const *)pvSrc;
214 while (cFrames-- > 0)
215 {
216 pi32Dst[0] = RT_CONCAT(audioMixBufSampleFrom,a_Name)(pSrc[0]);
217 pi32Dst += 1;
218 pSrc += 1;
219 }
220}
221
222/* Decoders for blending: */
223
224/* Generic */
225static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecodeGeneric,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc,
226 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)
227{
228 RT_NOREF_PV(pState);
229 uintptr_t const cSrcChannels = pState->cSrcChannels;
230 uintptr_t const cDstChannels = pState->cDstChannels;
231 a_Type const *pSrc = (a_Type const *)pvSrc;
232 while (cFrames-- > 0)
233 {
234 uintptr_t idxDst = cDstChannels;
235 while (idxDst-- > 0)
236 {
237 intptr_t idxSrc = pState->aidxChannelMap[idxDst];
238 if (idxSrc >= 0)
239 audioMixBufBlendSample(&pi32Dst[idxDst], RT_CONCAT(audioMixBufSampleFrom,a_Name)(pSrc[idxSrc]));
240 }
241 pi32Dst += cDstChannels;
242 pSrc += cSrcChannels;
243 }
244}
245
246/* 2ch -> 2ch */
247static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode2ChTo2Ch,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc,
248 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)
249{
250 RT_NOREF_PV(pState);
251 a_Type const *pSrc = (a_Type const *)pvSrc;
252 while (cFrames-- > 0)
253 {
254 audioMixBufBlendSample(&pi32Dst[0], RT_CONCAT(audioMixBufSampleFrom,a_Name)(pSrc[0]));
255 audioMixBufBlendSample(&pi32Dst[1], RT_CONCAT(audioMixBufSampleFrom,a_Name)(pSrc[1]));
256 AUDMIXBUF_MACRO_LOG(("%p: %RI32 / %RI32 => %RI32 / %RI32\n",
257 &pSrc[0], (int32_t)pSrc[0], (int32_t)pSrc[1], pi32Dst[0], pi32Dst[1]));
258 pi32Dst += 2;
259 pSrc += 2;
260 }
261}
262
263/* 2ch -> 1ch */
264static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode2ChTo1Ch,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc,
265 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)
266{
267 RT_NOREF_PV(pState);
268 a_Type const *pSrc = (a_Type const *)pvSrc;
269 while (cFrames-- > 0)
270 {
271 audioMixBufBlendSample(&pi32Dst[0], audioMixBufBlendSampleRet(RT_CONCAT(audioMixBufSampleFrom,a_Name)(pSrc[0]),
272 RT_CONCAT(audioMixBufSampleFrom,a_Name)(pSrc[1])));
273 pi32Dst += 1;
274 pSrc += 2;
275 }
276}
277
278/* 1ch -> 2ch */
279static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode1ChTo2Ch,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc,
280 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)
281{
282 RT_NOREF_PV(pState);
283 a_Type const *pSrc = (a_Type const *)pvSrc;
284 while (cFrames-- > 0)
285 {
286 int32_t const i32Src = RT_CONCAT(audioMixBufSampleFrom,a_Name)(pSrc[0]);
287 audioMixBufBlendSample(&pi32Dst[0], i32Src);
288 audioMixBufBlendSample(&pi32Dst[1], i32Src);
289 pi32Dst += 2;
290 pSrc += 1;
291 }
292}
293
294/* 1ch -> 1ch */
295static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode1ChTo1Ch,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc,
296 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)
297{
298 RT_NOREF_PV(pState);
299 a_Type const *pSrc = (a_Type const *)pvSrc;
300 while (cFrames-- > 0)
301 {
302 audioMixBufBlendSample(&pi32Dst[0], RT_CONCAT(audioMixBufSampleFrom,a_Name)(pSrc[0]));
303 pi32Dst += 1;
304 pSrc += 1;
305 }
306}
307
308
309#undef a_Name
310#undef a_Type
311#undef a_Min
312#undef a_Max
313#undef a_fSigned
314#undef a_cShift
315
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use