Changeset 89378 in vbox for trunk/src/VBox
- Timestamp:
- May 30, 2021 2:14:34 AM (4 years ago)
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp
r89377 r89378 221 221 222 222 /** 223 * Merges @a i 64Src into the value stored at @a pi64Dst.224 * 225 * @param pi 64Dst The value to merge @a i64Src into.226 * @param i 64Src The new value to add.227 */ 228 DECL_FORCE_INLINE(void) audioMixBufBlendSample(int 64_t *pi64Dst, int64_t i64Src)229 { 230 if (i 64Src)231 { 232 int64_t const i 64Dst = *pi64Dst;233 if (!i 64Dst)234 *pi 64Dst = i64Src;223 * Merges @a i32Src into the value stored at @a pi32Dst. 224 * 225 * @param pi32Dst The value to merge @a i32Src into. 226 * @param i32Src The new value to add. 227 */ 228 DECL_FORCE_INLINE(void) audioMixBufBlendSample(int32_t *pi32Dst, int32_t i32Src) 229 { 230 if (i32Src) 231 { 232 int64_t const i32Dst = *pi32Dst; 233 if (!i32Dst) 234 *pi32Dst = i32Src; 235 235 else 236 *pi 64Dst = (i64Dst + i64Src) / 2;236 *pi32Dst = (int32_t)(((int64_t)i32Dst + i32Src) / 2); 237 237 } 238 238 } … … 244 244 * This is used for stereo -> mono. 245 245 */ 246 DECL_FORCE_INLINE(int 64_t) audioMixBufBlendSampleRet(int64_t i64Sample1, int64_t i64Sample2)247 { 248 if (!i 64Sample1)249 return i 64Sample2;250 if (!i 64Sample2)251 return i 64Sample1;252 return (i 64Sample1 + i64Sample2) / 2;246 DECL_FORCE_INLINE(int32_t) audioMixBufBlendSampleRet(int32_t i32Sample1, int32_t i32Sample2) 247 { 248 if (!i32Sample1) 249 return i32Sample2; 250 if (!i32Sample2) 251 return i32Sample1; 252 return (int32_t)(((int64_t)i32Sample1 + i32Sample2) / 2); 253 253 } 254 254 … … 261 261 * - otherwise sum and divide by two. 262 262 * 263 * @param pi 64Dst The destination stream buffer (input and output).264 * @param pi 64Src The source stream buffer.263 * @param pi32Dst The destination stream buffer (input and output). 264 * @param pi32Src The source stream buffer. 265 265 * @param cFrames Number of frames to process. 266 266 * @param cChannels Number of channels. 267 267 */ 268 static void audioMixBufBlendBuffer(int 64_t *pi64Dst, int64_t const *pi64Src, uint32_t cFrames, uint8_t cChannels)268 static void audioMixBufBlendBuffer(int32_t *pi32Dst, int32_t const *pi32Src, uint32_t cFrames, uint8_t cChannels) 269 269 { 270 270 switch (cChannels) … … 273 273 while (cFrames-- > 0) 274 274 { 275 audioMixBufBlendSample(&pi 64Dst[0], pi64Src[0]);276 audioMixBufBlendSample(&pi 64Dst[1], pi64Src[1]);277 pi 64Dst += 2;278 pi 64Src += 2;275 audioMixBufBlendSample(&pi32Dst[0], pi32Src[0]); 276 audioMixBufBlendSample(&pi32Dst[1], pi32Src[1]); 277 pi32Dst += 2; 278 pi32Src += 2; 279 279 } 280 280 break; … … 286 286 while (cFrames-- > 0) 287 287 { 288 audioMixBufBlendSample(pi 64Dst, pi64Src[0]);289 pi 64Dst++;290 pi 64Src++;288 audioMixBufBlendSample(pi32Dst, pi32Src[0]); 289 pi32Dst++; 290 pi32Src++; 291 291 } 292 292 break; … … 312 312 #define AUDMIXBUF_CONVERT(a_Name, a_Type, _aMin, _aMax, _aSigned, _aShift) \ 313 313 /* Clips a specific output value to a single sample value. */ \ 314 DECLINLINE(int 64_t) audioMixBufClipFrom##a_Name(a_Type aVal) \314 DECLINLINE(int32_t) audioMixBufSampleFrom##a_Name(a_Type aVal) \ 315 315 { \ 316 316 /* left shifting of signed values is not defined, therefore the intermediate uint64_t cast */ \ 317 317 if (_aSigned) \ 318 return (int 64_t) (((uint64_t) ((int64_t) aVal )) << (32 - _aShift)); \319 return (int 64_t) (((uint64_t) ((int64_t) aVal - ((_aMax >> 1) + 1))) << (32 - _aShift)); \318 return (int32_t) (((uint32_t) ((int32_t) aVal )) << (32 - _aShift)); \ 319 return (int32_t) (((uint32_t) ((int32_t) aVal - ((_aMax >> 1) + 1))) << (32 - _aShift)); \ 320 320 } \ 321 321 \ 322 322 /* Clips a single sample value to a specific output value. */ \ 323 DECLINLINE(a_Type) audioMixBuf ClipTo##a_Name(int64_t iVal) \323 DECLINLINE(a_Type) audioMixBufSampleTo##a_Name(int32_t iVal) \ 324 324 { \ 325 /*if (iVal >= 0x7fffffff) return _aMax; if (iVal < -INT64_C(0x80000000)) return _aMin;*/ \ 326 if (!(((uint64_t)iVal + UINT64_C(0x80000000)) & UINT64_C(0xffffffff00000000))) \ 327 { \ 328 if (_aSigned) \ 329 return (a_Type) (iVal >> (32 - _aShift)); \ 330 return (a_Type) ((iVal >> (32 - _aShift)) + ((_aMax >> 1) + 1)); \ 331 } \ 332 AssertMsgFailed(("%RI64 (%#RX64)\n", iVal, iVal)); /* shouldn't be possible with current buffer operations */ \ 333 return iVal >= 0 ? _aMax : _aMin; \ 325 if (_aSigned) \ 326 return (a_Type) (iVal >> (32 - _aShift)); \ 327 return (a_Type) ((iVal >> (32 - _aShift)) + ((_aMax >> 1) + 1)); \ 334 328 } \ 335 329 \ … … 337 331 \ 338 332 /* 2ch -> 2ch */ \ 339 static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode2ChTo2Ch,a_Name)(void *pvDst, int 64_t const *pi64Src, uint32_t cFrames, \333 static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode2ChTo2Ch,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames, \ 340 334 PAUDIOMIXBUFPEEKSTATE pState) \ 341 335 { \ … … 344 338 while (cFrames-- > 0) \ 345 339 { \ 346 pDst[0] = audioMixBuf ClipTo##a_Name(pi64Src[0]); \347 pDst[1] = audioMixBuf ClipTo##a_Name(pi64Src[1]); \348 AUDMIXBUF_MACRO_LOG(("%p: %RI 64 / %RI64 => %RI64 / %RI64\n", \349 &pi 64Src[0], pi64Src[0], pi64Src[1], (int64_t)pDst[0], (int64_t)pDst[1])); \340 pDst[0] = audioMixBufSampleTo##a_Name(pi32Src[0]); \ 341 pDst[1] = audioMixBufSampleTo##a_Name(pi32Src[1]); \ 342 AUDMIXBUF_MACRO_LOG(("%p: %RI32 / %RI32 => %RI32 / %RI32\n", \ 343 &pi32Src[0], pi32Src[0], pi32Src[1], (int32_t)pDst[0], (int32_t)pDst[1])); \ 350 344 pDst += 2; \ 351 pi 64Src += 2; \345 pi32Src += 2; \ 352 346 } \ 353 347 } \ 354 348 \ 355 349 /* 2ch -> 1ch */ \ 356 static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode2ChTo1Ch,a_Name)(void *pvDst, int 64_t const *pi64Src, uint32_t cFrames, \350 static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode2ChTo1Ch,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames, \ 357 351 PAUDIOMIXBUFPEEKSTATE pState) \ 358 352 { \ … … 361 355 while (cFrames-- > 0) \ 362 356 { \ 363 pDst[0] = audioMixBuf ClipTo##a_Name(audioMixBufBlendSampleRet(pi64Src[0], pi64Src[1])); \357 pDst[0] = audioMixBufSampleTo##a_Name(audioMixBufBlendSampleRet(pi32Src[0], pi32Src[1])); \ 364 358 pDst += 1; \ 365 pi 64Src += 2; \359 pi32Src += 2; \ 366 360 } \ 367 361 } \ 368 362 \ 369 363 /* 1ch -> 2ch */ \ 370 static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode1ChTo2Ch,a_Name)(void *pvDst, int 64_t const *pi64Src, uint32_t cFrames, \364 static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode1ChTo2Ch,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames, \ 371 365 PAUDIOMIXBUFPEEKSTATE pState) \ 372 366 { \ … … 375 369 while (cFrames-- > 0) \ 376 370 { \ 377 pDst[0] = pDst[1] = audioMixBuf ClipTo##a_Name(pi64Src[0]); \371 pDst[0] = pDst[1] = audioMixBufSampleTo##a_Name(pi32Src[0]); \ 378 372 pDst += 2; \ 379 pi 64Src += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */\373 pi32Src += 1; \ 380 374 } \ 381 375 } \ 382 376 /* 1ch -> 1ch */ \ 383 static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode1ChTo1Ch,a_Name)(void *pvDst, int 64_t const *pi64Src, uint32_t cFrames, \377 static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode1ChTo1Ch,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames, \ 384 378 PAUDIOMIXBUFPEEKSTATE pState) \ 385 379 { \ … … 388 382 while (cFrames-- > 0) \ 389 383 { \ 390 pDst[0] = audioMixBuf ClipTo##a_Name(pi64Src[0]); \384 pDst[0] = audioMixBufSampleTo##a_Name(pi32Src[0]); \ 391 385 pDst += 1; \ 392 pi 64Src += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */\386 pi32Src += 1; \ 393 387 } \ 394 388 } \ … … 397 391 \ 398 392 /* 2ch -> 2ch */ \ 399 static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode2ChTo2Ch,a_Name)(int 64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, \393 static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode2ChTo2Ch,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames, \ 400 394 PAUDIOMIXBUFWRITESTATE pState) \ 401 395 { \ … … 404 398 while (cFrames-- > 0) \ 405 399 { \ 406 pi 64Dst[0] = audioMixBufClipFrom##a_Name(pSrc[0]); \407 pi 64Dst[1] = audioMixBufClipFrom##a_Name(pSrc[1]); \408 AUDMIXBUF_MACRO_LOG(("%p: %RI 64 / %RI64 => %RI64 / %RI64\n", \409 &pSrc[0], (int 64_t)pSrc[0], (int64_t)pSrc[1], pi64Dst[0], pi64Dst[1])); \410 pi 64Dst += 2; \400 pi32Dst[0] = audioMixBufSampleFrom##a_Name(pSrc[0]); \ 401 pi32Dst[1] = audioMixBufSampleFrom##a_Name(pSrc[1]); \ 402 AUDMIXBUF_MACRO_LOG(("%p: %RI32 / %RI32 => %RI32 / %RI32\n", \ 403 &pSrc[0], (int32_t)pSrc[0], (int32_t)pSrc[1], pi32Dst[0], pi32Dst[1])); \ 404 pi32Dst += 2; \ 411 405 pSrc += 2; \ 412 406 } \ … … 414 408 \ 415 409 /* 2ch -> 1ch */ \ 416 static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode2ChTo1Ch,a_Name)(int 64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, \410 static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode2ChTo1Ch,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames, \ 417 411 PAUDIOMIXBUFWRITESTATE pState) \ 418 412 { \ … … 421 415 while (cFrames-- > 0) \ 422 416 { \ 423 pi 64Dst[0] = audioMixBufBlendSampleRet(audioMixBufClipFrom##a_Name(pSrc[0]), audioMixBufClipFrom##a_Name(pSrc[1])); \424 pi 64Dst += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */\417 pi32Dst[0] = audioMixBufBlendSampleRet(audioMixBufSampleFrom##a_Name(pSrc[0]), audioMixBufSampleFrom##a_Name(pSrc[1])); \ 418 pi32Dst += 1; \ 425 419 pSrc += 2; \ 426 420 } \ … … 428 422 \ 429 423 /* 1ch -> 2ch */ \ 430 static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode1ChTo2Ch,a_Name)(int 64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, \424 static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode1ChTo2Ch,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames, \ 431 425 PAUDIOMIXBUFWRITESTATE pState) \ 432 426 { \ … … 435 429 while (cFrames-- > 0) \ 436 430 { \ 437 pi 64Dst[1] = pi64Dst[0] = audioMixBufClipFrom##a_Name(pSrc[0]); \438 pi 64Dst += 2; \431 pi32Dst[1] = pi32Dst[0] = audioMixBufSampleFrom##a_Name(pSrc[0]); \ 432 pi32Dst += 2; \ 439 433 pSrc += 1; \ 440 434 } \ … … 442 436 \ 443 437 /* 1ch -> 1ch */ \ 444 static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode1ChTo1Ch,a_Name)(int 64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, \438 static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode1ChTo1Ch,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames, \ 445 439 PAUDIOMIXBUFWRITESTATE pState) \ 446 440 { \ … … 449 443 while (cFrames-- > 0) \ 450 444 { \ 451 pi 64Dst[0] = audioMixBufClipFrom##a_Name(pSrc[0]); \452 pi 64Dst += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */\445 pi32Dst[0] = audioMixBufSampleFrom##a_Name(pSrc[0]); \ 446 pi32Dst += 1; \ 453 447 pSrc += 1; \ 454 448 } \ … … 458 452 \ 459 453 /* 2ch -> 2ch */ \ 460 static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode2ChTo2Ch,a_Name,Blend)(int 64_t *pi64Dst, void const *pvSrc, \454 static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode2ChTo2Ch,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc, \ 461 455 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \ 462 456 { \ … … 465 459 while (cFrames-- > 0) \ 466 460 { \ 467 audioMixBufBlendSample(&pi 64Dst[0], audioMixBufClipFrom##a_Name(pSrc[0])); \468 audioMixBufBlendSample(&pi 64Dst[1], audioMixBufClipFrom##a_Name(pSrc[1])); \469 AUDMIXBUF_MACRO_LOG(("%p: %RI 64 / %RI64 => %RI64 / %RI64\n", \470 &pSrc[0], (int 64_t)pSrc[0], (int64_t)pSrc[1], pi64Dst[0], pi64Dst[1])); \471 pi 64Dst += 2; \461 audioMixBufBlendSample(&pi32Dst[0], audioMixBufSampleFrom##a_Name(pSrc[0])); \ 462 audioMixBufBlendSample(&pi32Dst[1], audioMixBufSampleFrom##a_Name(pSrc[1])); \ 463 AUDMIXBUF_MACRO_LOG(("%p: %RI32 / %RI32 => %RI32 / %RI32\n", \ 464 &pSrc[0], (int32_t)pSrc[0], (int32_t)pSrc[1], pi32Dst[0], pi32Dst[1])); \ 465 pi32Dst += 2; \ 472 466 pSrc += 2; \ 473 467 } \ … … 475 469 \ 476 470 /* 2ch -> 1ch */ \ 477 static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode2ChTo1Ch,a_Name,Blend)(int 64_t *pi64Dst, void const *pvSrc, \471 static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode2ChTo1Ch,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc, \ 478 472 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \ 479 473 { \ … … 482 476 while (cFrames-- > 0) \ 483 477 { \ 484 audioMixBufBlendSample(&pi 64Dst[0], audioMixBufBlendSampleRet(audioMixBufClipFrom##a_Name(pSrc[0]), \485 audioMixBuf ClipFrom##a_Name(pSrc[1]))); \486 pi 64Dst += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */\478 audioMixBufBlendSample(&pi32Dst[0], audioMixBufBlendSampleRet(audioMixBufSampleFrom##a_Name(pSrc[0]), \ 479 audioMixBufSampleFrom##a_Name(pSrc[1]))); \ 480 pi32Dst += 1; \ 487 481 pSrc += 2; \ 488 482 } \ … … 490 484 \ 491 485 /* 1ch -> 2ch */ \ 492 static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode1ChTo2Ch,a_Name,Blend)(int 64_t *pi64Dst, void const *pvSrc, \486 static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode1ChTo2Ch,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc, \ 493 487 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \ 494 488 { \ … … 497 491 while (cFrames-- > 0) \ 498 492 { \ 499 int 64_t const i64Src = audioMixBufClipFrom##a_Name(pSrc[0]); \500 audioMixBufBlendSample(&pi 64Dst[0], i64Src); \501 audioMixBufBlendSample(&pi 64Dst[1], i64Src); \502 pi 64Dst += 2; \493 int32_t const i32Src = audioMixBufSampleFrom##a_Name(pSrc[0]); \ 494 audioMixBufBlendSample(&pi32Dst[0], i32Src); \ 495 audioMixBufBlendSample(&pi32Dst[1], i32Src); \ 496 pi32Dst += 2; \ 503 497 pSrc += 1; \ 504 498 } \ … … 506 500 \ 507 501 /* 1ch -> 1ch */ \ 508 static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode1ChTo1Ch,a_Name,Blend)(int 64_t *pi64Dst, void const *pvSrc, \502 static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode1ChTo1Ch,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc, \ 509 503 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \ 510 504 { \ … … 513 507 while (cFrames-- > 0) \ 514 508 { \ 515 audioMixBufBlendSample(&pi 64Dst[0], audioMixBufClipFrom##a_Name(pSrc[0])); \516 pi 64Dst += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */\509 audioMixBufBlendSample(&pi32Dst[0], audioMixBufSampleFrom##a_Name(pSrc[0])); \ 510 pi32Dst += 1; \ 517 511 pSrc += 1; \ 518 512 } \ … … 520 514 521 515 522 /* audioMixBufConvXXXS8: 8 516 /* audioMixBufConvXXXS8: 8-bit, signed. */ 523 517 AUDMIXBUF_CONVERT(S8 /* Name */, int8_t, INT8_MIN /* Min */, INT8_MAX /* Max */, true /* fSigned */, 8 /* cShift */) 524 /* audioMixBufConvXXXU8: 8 518 /* audioMixBufConvXXXU8: 8-bit, unsigned. */ 525 519 AUDMIXBUF_CONVERT(U8 /* Name */, uint8_t, 0 /* Min */, UINT8_MAX /* Max */, false /* fSigned */, 8 /* cShift */) 526 /* audioMixBufConvXXXS16: 16 520 /* audioMixBufConvXXXS16: 16-bit, signed. */ 527 521 AUDMIXBUF_CONVERT(S16 /* Name */, int16_t, INT16_MIN /* Min */, INT16_MAX /* Max */, true /* fSigned */, 16 /* cShift */) 528 /* audioMixBufConvXXXU16: 16 522 /* audioMixBufConvXXXU16: 16-bit, unsigned. */ 529 523 AUDMIXBUF_CONVERT(U16 /* Name */, uint16_t, 0 /* Min */, UINT16_MAX /* Max */, false /* fSigned */, 16 /* cShift */) 530 /* audioMixBufConvXXXS32: 32 524 /* audioMixBufConvXXXS32: 32-bit, signed. */ 531 525 AUDMIXBUF_CONVERT(S32 /* Name */, int32_t, INT32_MIN /* Min */, INT32_MAX /* Max */, true /* fSigned */, 32 /* cShift */) 532 /* audioMixBufConvXXXU32: 32 526 /* audioMixBufConvXXXU32: 32-bit, unsigned. */ 533 527 AUDMIXBUF_CONVERT(U32 /* Name */, uint32_t, 0 /* Min */, UINT32_MAX /* Max */, false /* fSigned */, 32 /* cShift */) 528 /* audioMixBufConvXXXRaw: 32-bit stored as 64-bit, signed. */ 529 AUDMIXBUF_CONVERT(Raw /* Name */, int64_t, INT32_MIN /* Min */, INT32_MAX /* Max */, true /* fSigned */, 32 /* cShift */) 534 530 535 531 #undef AUDMIXBUF_CONVERT 536 537 /*538 * Manually coded signed 64-bit conversion.539 */540 541 /* Encoders for peek: */542 543 static DECLCALLBACK(void)544 audioMixBufEncode2ChTo2ChRaw(void *pvDst, int64_t const *pi64Src, uint32_t cFrames, PAUDIOMIXBUFPEEKSTATE pState)545 {546 RT_NOREF_PV(pState);547 memcpy(pvDst, pi64Src, sizeof(int64_t) * 2 * cFrames);548 }549 550 static DECLCALLBACK(void)551 audioMixBufEncode2ChTo1ChRaw(void *pvDst, int64_t const *pi64Src, uint32_t cFrames, PAUDIOMIXBUFPEEKSTATE pState)552 {553 RT_NOREF_PV(pState);554 int64_t *pi64Dst = (int64_t *)pvDst;555 while (cFrames-- > 0)556 {557 *pi64Dst = (pi64Src[0] + pi64Src[1]) / 2;558 pi64Dst += 1;559 pi64Src += 2;560 }561 }562 563 static DECLCALLBACK(void)564 audioMixBufEncode1ChTo2ChRaw(void *pvDst, int64_t const *pi64Src, uint32_t cFrames, PAUDIOMIXBUFPEEKSTATE pState)565 {566 RT_NOREF_PV(pState);567 int64_t *pi64Dst = (int64_t *)pvDst;568 while (cFrames-- > 0)569 {570 pi64Dst[0] = pi64Dst[1] = *pi64Src;571 pi64Dst += 2;572 pi64Src += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */573 }574 }575 576 static DECLCALLBACK(void)577 audioMixBufEncode1ChTo1ChRaw(void *pvDst, int64_t const *pi64Src, uint32_t cFrames, PAUDIOMIXBUFPEEKSTATE pState)578 {579 RT_NOREF_PV(pState);580 /** @todo memcpy(pvDst, pi64Src, sizeof(int64_t) * 1 * cFrames); when we do581 * multi channel mixbuf support. */582 int64_t *pi64Dst = (int64_t *)pvDst;583 while (cFrames-- > 0)584 {585 *pi64Dst = *pi64Src;586 pi64Dst += 1;587 pi64Src += 2;588 }589 }590 591 592 /* Decoders for write: */593 594 static DECLCALLBACK(void)595 audioMixBufDecode2ChTo2ChRaw(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)596 {597 RT_NOREF_PV(pState);598 memcpy(pi64Dst, pvSrc, sizeof(int64_t) * 2 * cFrames);599 }600 601 static DECLCALLBACK(void)602 audioMixBufDecode2ChTo1ChRaw(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)603 {604 RT_NOREF_PV(pState);605 int64_t const *pi64Src = (int64_t const *)pvSrc;606 while (cFrames-- > 0)607 {608 *pi64Dst = (pi64Src[0] + pi64Src[1]) / 2;609 pi64Dst += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */610 pi64Src += 2;611 }612 }613 614 static DECLCALLBACK(void)615 audioMixBufDecode1ChTo2ChRaw(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)616 {617 RT_NOREF_PV(pState);618 int64_t const *pi64Src = (int64_t const *)pvSrc;619 while (cFrames-- > 0)620 {621 pi64Dst[0] = pi64Dst[1] = *pi64Src;622 pi64Dst += 2;623 pi64Src += 1;624 }625 }626 627 static DECLCALLBACK(void)628 audioMixBufDecode1ChTo1ChRaw(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)629 {630 RT_NOREF_PV(pState);631 /** @todo memcpy(pi64Dst, pvSrc, sizeof(int64_t) * 1 * cFrames); when we do632 * multi channel mixbuf support. */633 int64_t const *pi64Src = (int64_t const *)pvSrc;634 while (cFrames-- > 0)635 {636 *pi64Dst = *pi64Src;637 pi64Dst += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */638 pi64Src += 1;639 }640 }641 642 643 /* Decoders for blending: */644 645 static DECLCALLBACK(void)646 audioMixBufDecode2ChTo2ChRawBlend(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)647 {648 RT_NOREF_PV(pState);649 audioMixBufBlendBuffer(pi64Dst, (int64_t const *)pvSrc, cFrames, 2);650 }651 652 static DECLCALLBACK(void)653 audioMixBufDecode2ChTo1ChRawBlend(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)654 {655 RT_NOREF_PV(pState);656 int64_t const *pi64Src = (int64_t const *)pvSrc;657 while (cFrames-- > 0)658 {659 audioMixBufBlendSample(pi64Dst, audioMixBufBlendSampleRet(pi64Src[0], pi64Src[1]));660 pi64Dst += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */661 pi64Src += 2;662 }663 }664 665 static DECLCALLBACK(void)666 audioMixBufDecode1ChTo2ChRawBlend(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)667 {668 RT_NOREF_PV(pState);669 int64_t const *pi64Src = (int64_t const *)pvSrc;670 while (cFrames-- > 0)671 {672 int64_t const i64Src = *pi64Src;673 audioMixBufBlendSample(&pi64Dst[0], i64Src);674 audioMixBufBlendSample(&pi64Dst[1], i64Src);675 pi64Dst += 2;676 pi64Src += 1;677 }678 }679 680 static DECLCALLBACK(void)681 audioMixBufDecode1ChTo1ChRawBlend(int64_t *pi64Dst, void const *pvSrc, uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState)682 {683 RT_NOREF_PV(pState);684 /** @todo memcpy(pi64Dst, pvSrc, sizeof(int64_t) * 1 * cFrames); when we do685 * multi channel mixbuf support. */686 int64_t const *pi64Src = (int64_t const *)pvSrc;687 while (cFrames-- > 0)688 {689 audioMixBufBlendSample(&pi64Dst[0], *pi64Src);690 pi64Dst += 2; /** @todo when we do multi channel mixbuf support, this can change to 1 */691 pi64Src += 1;692 }693 }694 695 532 #undef AUDMIXBUF_MACRO_LOG 533 696 534 697 535 /* … … 699 537 */ 700 538 /** @todo Separate down- and up-sampling, borrow filter code from RDP. */ 701 #define COPY_LAST_FRAME_1CH(a_pi 64Dst, a_pi64Src, a_cChannels) do { \702 (a_pi 64Dst)[0] = (a_pi64Src)[0]; \539 #define COPY_LAST_FRAME_1CH(a_pi32Dst, a_pi32Src, a_cChannels) do { \ 540 (a_pi32Dst)[0] = (a_pi32Src)[0]; \ 703 541 } while (0) 704 #define COPY_LAST_FRAME_2CH(a_pi 64Dst, a_pi64Src, a_cChannels) do { \705 (a_pi 64Dst)[0] = (a_pi64Src)[0]; \706 (a_pi 64Dst)[1] = (a_pi64Src)[1]; \542 #define COPY_LAST_FRAME_2CH(a_pi32Dst, a_pi32Src, a_cChannels) do { \ 543 (a_pi32Dst)[0] = (a_pi32Src)[0]; \ 544 (a_pi32Dst)[1] = (a_pi32Src)[1]; \ 707 545 } while (0) 708 546 709 #define INTERPOLATE_ONE(a_pi 64Dst, a_pi64Src, a_pi64Last, a_i64FactorCur, a_i64FactorLast, a_iCh) \710 (a_pi 64Dst)[a_iCh] = ((a_pi64Last)[a_iCh] * a_i64FactorLast + (a_pi64Src)[a_iCh] * a_i64FactorCur) >> 32711 #define INTERPOLATE_1CH(a_pi 64Dst, a_pi64Src, a_pi64Last, a_i64FactorCur, a_i64FactorLast, a_cChannels) do { \712 INTERPOLATE_ONE(a_pi 64Dst, a_pi64Src, a_pi64Last, a_i64FactorCur, a_i64FactorLast, 0); \547 #define INTERPOLATE_ONE(a_pi32Dst, a_pi32Src, a_pi32Last, a_i64FactorCur, a_i64FactorLast, a_iCh) \ 548 (a_pi32Dst)[a_iCh] = ((a_pi32Last)[a_iCh] * a_i64FactorLast + (a_pi32Src)[a_iCh] * a_i64FactorCur) >> 32 549 #define INTERPOLATE_1CH(a_pi32Dst, a_pi32Src, a_pi32Last, a_i64FactorCur, a_i64FactorLast, a_cChannels) do { \ 550 INTERPOLATE_ONE(a_pi32Dst, a_pi32Src, a_pi32Last, a_i64FactorCur, a_i64FactorLast, 0); \ 713 551 } while (0) 714 #define INTERPOLATE_2CH(a_pi 64Dst, a_pi64Src, a_pi64Last, a_i64FactorCur, a_i64FactorLast, a_cChannels) do { \715 INTERPOLATE_ONE(a_pi 64Dst, a_pi64Src, a_pi64Last, a_i64FactorCur, a_i64FactorLast, 0); \716 INTERPOLATE_ONE(a_pi 64Dst, a_pi64Src, a_pi64Last, a_i64FactorCur, a_i64FactorLast, 1); \552 #define INTERPOLATE_2CH(a_pi32Dst, a_pi32Src, a_pi32Last, a_i64FactorCur, a_i64FactorLast, a_cChannels) do { \ 553 INTERPOLATE_ONE(a_pi32Dst, a_pi32Src, a_pi32Last, a_i64FactorCur, a_i64FactorLast, 0); \ 554 INTERPOLATE_ONE(a_pi32Dst, a_pi32Src, a_pi32Last, a_i64FactorCur, a_i64FactorLast, 1); \ 717 555 } while (0) 718 556 … … 720 558 /** @returns Number of destination frames written. */ \ 721 559 static DECLCALLBACK(uint32_t) \ 722 audioMixBufResample##a_cChannels##Ch##a_Suffix(int 64_t *pi64Dst, uint32_t cDstFrames, \723 int 64_t const *pi64Src, uint32_t cSrcFrames, uint32_t *pcSrcFramesRead, \560 audioMixBufResample##a_cChannels##Ch##a_Suffix(int32_t *pi32Dst, uint32_t cDstFrames, \ 561 int32_t const *pi32Src, uint32_t cSrcFrames, uint32_t *pcSrcFramesRead, \ 724 562 PAUDIOSTREAMRATE pRate) \ 725 563 { \ 726 564 Log5(("Src: %RU32 L %RU32; Dst: %RU32 L%RU32; uDstInc=%#RX64\n", \ 727 565 pRate->offSrc, cSrcFrames, RT_HI_U32(pRate->offDst), cDstFrames, pRate->uDstInc)); \ 728 int 64_t * const pi64DstStart = pi64Dst; \729 int 64_t const * const pi64SrcStart = pi64Src; \566 int32_t * const pi32DstStart = pi32Dst; \ 567 int32_t const * const pi32SrcStart = pi32Src; \ 730 568 \ 731 int 64_t ai64LastFrame[a_cChannels]; \732 COPY_LAST_FRAME_##a_cChannels##CH(ai 64LastFrame, pRate->SrcLast.ai64Samples, a_cChannels); \569 int32_t ai32LastFrame[a_cChannels]; \ 570 COPY_LAST_FRAME_##a_cChannels##CH(ai32LastFrame, pRate->SrcLast.ai32Samples, a_cChannels); \ 733 571 \ 734 572 while (cDstFrames > 0 && cSrcFrames > 0) \ … … 741 579 pRate->offSrc += (uint32_t)cSrcNeeded; \ 742 580 cSrcFrames -= (uint32_t)cSrcNeeded; \ 743 pi 64Src += (uint32_t)cSrcNeeded * a_cChannels; \744 COPY_LAST_FRAME_##a_cChannels##CH(ai 64LastFrame, &pi64Src[-a_cChannels], a_cChannels); \581 pi32Src += (uint32_t)cSrcNeeded * a_cChannels; \ 582 COPY_LAST_FRAME_##a_cChannels##CH(ai32LastFrame, &pi32Src[-a_cChannels], a_cChannels); \ 745 583 } \ 746 584 else \ 747 585 { \ 748 pi 64Src += cSrcFrames * a_cChannels; \586 pi32Src += cSrcFrames * a_cChannels; \ 749 587 pRate->offSrc += cSrcFrames; \ 750 COPY_LAST_FRAME_##a_cChannels##CH(pRate->SrcLast.ai 64Samples, &pi64Src[-a_cChannels], a_cChannels); \751 *pcSrcFramesRead = (pi 64Src - pi64SrcStart) / a_cChannels; \752 return (pi 64Dst - pi64DstStart) / a_cChannels; \588 COPY_LAST_FRAME_##a_cChannels##CH(pRate->SrcLast.ai32Samples, &pi32Src[-a_cChannels], a_cChannels); \ 589 *pcSrcFramesRead = (pi32Src - pi32SrcStart) / a_cChannels; \ 590 return (pi32Dst - pi32DstStart) / a_cChannels; \ 753 591 } \ 754 592 } \ … … 757 595 int64_t const offFactorCur = pRate->offDst & UINT32_MAX; \ 758 596 int64_t const offFactorLast = (int64_t)_4G - offFactorCur; \ 759 INTERPOLATE_##a_cChannels##CH(pi 64Dst, pi64Src, ai64LastFrame, offFactorCur, offFactorLast, a_cChannels); \597 INTERPOLATE_##a_cChannels##CH(pi32Dst, pi32Src, ai32LastFrame, offFactorCur, offFactorLast, a_cChannels); \ 760 598 \ 761 599 /* Advance. */ \ 762 600 pRate->offDst += pRate->uDstInc; \ 763 pi 64Dst += a_cChannels; \601 pi32Dst += a_cChannels; \ 764 602 cDstFrames -= 1; \ 765 603 } \ 766 604 \ 767 COPY_LAST_FRAME_##a_cChannels##CH(pRate->SrcLast.ai 64Samples, ai64LastFrame, a_cChannels); \768 *pcSrcFramesRead = (pi 64Src - pi64SrcStart) / a_cChannels; \769 return (pi 64Dst - pi64DstStart) / a_cChannels; \605 COPY_LAST_FRAME_##a_cChannels##CH(pRate->SrcLast.ai32Samples, ai32LastFrame, a_cChannels); \ 606 *pcSrcFramesRead = (pi32Src - pi32SrcStart) / a_cChannels; \ 607 return (pi32Dst - pi32DstStart) / a_cChannels; \ 770 608 } 771 609 … … 783 621 pRate->offDst = 0; 784 622 pRate->offSrc = 0; 785 for (uintptr_t i = 0; i < RT_ELEMENTS(pRate->SrcLast.ai 64Samples); i++)786 pRate->SrcLast.ai 64Samples[0] = 0;623 for (uintptr_t i = 0; i < RT_ELEMENTS(pRate->SrcLast.ai32Samples); i++) 624 pRate->SrcLast.ai32Samples[0] = 0; 787 625 } 788 626 … … 866 704 Assert(PDMAudioPropsAreValid(pProps)); 867 705 868 pMixBuf->uMagic = AUDIOMIXBUF_MAGIC; 869 870 pMixBuf->pFrames = NULL; 871 pMixBuf->cFrames = 0; 872 873 pMixBuf->offRead = 0; 874 pMixBuf->offWrite = 0; 875 pMixBuf->cUsed = 0; 876 877 /* Set initial volume to max. */ 878 pMixBuf->Volume.fMuted = false; 879 pMixBuf->Volume.uLeft = AUDIOMIXBUF_VOL_0DB; 880 pMixBuf->Volume.uRight = AUDIOMIXBUF_VOL_0DB; 881 882 pMixBuf->Props = *pProps; 883 884 pMixBuf->pszName = RTStrDup(pszName); 885 if (pMixBuf->pszName) 886 { 887 pMixBuf->pFrames = (PPDMAUDIOFRAME)RTMemAllocZ(cFrames * sizeof(PDMAUDIOFRAME)); 888 if (pMixBuf->pFrames) 706 /* 707 * Initialize all members, setting the volume to max (0dB). 708 */ 709 pMixBuf->cFrames = 0; 710 pMixBuf->pi32Samples = NULL; 711 pMixBuf->cChannels = 0; 712 pMixBuf->cbFrame = 0; 713 pMixBuf->offRead = 0; 714 pMixBuf->offWrite = 0; 715 pMixBuf->cUsed = 0; 716 pMixBuf->Props = *pProps; 717 pMixBuf->Volume.fMuted = false; 718 pMixBuf->Volume.fAllMax = true; 719 for (uintptr_t i = 0; i < RT_ELEMENTS(pMixBuf->Volume.auChannels); i++) 720 pMixBuf->Volume.auChannels[i] = AUDIOMIXBUF_VOL_0DB; 721 722 int rc; 723 uint8_t const cChannels = PDMAudioPropsChannels(pProps); 724 if (cChannels >= 1 && cChannels <= PDMAUDIO_MAX_CHANNELS) 725 { 726 pMixBuf->pszName = RTStrDup(pszName); 727 if (pMixBuf->pszName) 889 728 { 890 pMixBuf->cFrames = cFrames; 729 pMixBuf->pi32Samples = (int32_t *)RTMemAllocZ(cFrames * cChannels * sizeof(pMixBuf->pi32Samples[0])); 730 if (pMixBuf->pi32Samples) 731 { 732 pMixBuf->cFrames = cFrames; 733 pMixBuf->cChannels = cChannels; 734 pMixBuf->cbFrame = cChannels * sizeof(pMixBuf->pi32Samples[0]); 735 pMixBuf->uMagic = AUDIOMIXBUF_MAGIC; 891 736 #ifdef AUDMIXBUF_LOG_ENABLED 892 char szTmp[PDMAUDIOPROPSTOSTRING_MAX];893 AUDMIXBUF_LOG(("%s: %s - cFrames=%#x (%d)\n",894 pMixBuf->pszName, PDMAudioPropsToString(pProps, szTmp, sizeof(szTmp)), cFrames, cFrames));737 char szTmp[PDMAUDIOPROPSTOSTRING_MAX]; 738 AUDMIXBUF_LOG(("%s: %s - cFrames=%#x (%d)\n", 739 pMixBuf->pszName, PDMAudioPropsToString(pProps, szTmp, sizeof(szTmp)), cFrames, cFrames)); 895 740 #endif 896 return VINF_SUCCESS; 741 return VINF_SUCCESS; 742 } 743 RTStrFree(pMixBuf->pszName); 744 pMixBuf->pszName = NULL; 745 rc = VERR_NO_MEMORY; 897 746 } 898 RTStrFree(pMixBuf->pszName); 899 pMixBuf->pszName = NULL; 747 else 748 rc = VERR_NO_STR_MEMORY; 749 } 750 else 751 { 752 LogRelMaxFunc(64, ("cChannels=%d pszName=%s\n", cChannels, pszName)); 753 rc = VERR_OUT_OF_RANGE; 900 754 } 901 755 pMixBuf->uMagic = AUDIOMIXBUF_MAGIC_DEAD; 902 return VERR_NO_MEMORY;756 return rc; 903 757 } 904 758 … … 919 773 { 920 774 Assert(!pMixBuf->pszName); 921 Assert(!pMixBuf->p Frames);775 Assert(!pMixBuf->pi32Samples); 922 776 Assert(!pMixBuf->cFrames); 923 777 return; … … 935 789 } 936 790 937 if (pMixBuf->p Frames)791 if (pMixBuf->pi32Samples) 938 792 { 939 793 Assert(pMixBuf->cFrames); 940 941 RTMemFree(pMixBuf->pFrames);942 pMixBuf->pFrames = NULL;943 } 944 945 pMixBuf->c Frames = 0;794 RTMemFree(pMixBuf->pi32Samples); 795 pMixBuf->pi32Samples = NULL; 796 } 797 798 pMixBuf->cFrames = 0; 799 pMixBuf->cChannels = 0; 946 800 } 947 801 … … 1409 1263 { 1410 1264 /* Rate conversion into temporary buffer. */ 1411 int 64_t ai64DstRate[1024];1265 int32_t ai32DstRate[1024]; 1412 1266 uint32_t cSrcFrames = RT_MIN(pMixBuf->cFrames - offSrcFrame, cMaxSrcFrames); 1413 uint32_t cMaxDstFrames = RT_MIN(RT_ELEMENTS(ai 64DstRate) / pState->cDstChannels, cbDst / pState->cbDstFrame);1414 uint32_t const cDstFrames = pState->Rate.pfnResample(ai 64DstRate, cMaxDstFrames,1415 &pMixBuf->p Frames[offSrcFrame].i64LSample, cSrcFrames, &cSrcFrames,1416 &pState->Rate);1267 uint32_t cMaxDstFrames = RT_MIN(RT_ELEMENTS(ai32DstRate) / pState->cDstChannels, cbDst / pState->cbDstFrame); 1268 uint32_t const cDstFrames = pState->Rate.pfnResample(ai32DstRate, cMaxDstFrames, 1269 &pMixBuf->pi32Samples[offSrcFrame * pMixBuf->cChannels], 1270 cSrcFrames, &cSrcFrames, &pState->Rate); 1417 1271 *pcSrcFramesPeeked += cSrcFrames; 1418 1272 cMaxSrcFrames -= cSrcFrames; … … 1421 1275 /* Encode the converted frames. */ 1422 1276 uint32_t const cbDstEncoded = cDstFrames * pState->cbDstFrame; 1423 pState->pfnEncode(pvDst, ai 64DstRate, cDstFrames, pState);1277 pState->pfnEncode(pvDst, ai32DstRate, cDstFrames, pState); 1424 1278 *pcbDstPeeked += cbDstEncoded; 1425 1279 cbDst -= cbDstEncoded; … … 1484 1338 /* First chunk. */ 1485 1339 uint32_t const cSrcFrames1 = RT_MIN(pMixBuf->cFrames - offSrcFrame, cMaxSrcFrames); 1486 pState->pfnEncode(pvDst, &pMixBuf->p Frames[offSrcFrame].i64LSample, cSrcFrames1, pState);1340 pState->pfnEncode(pvDst, &pMixBuf->pi32Samples[offSrcFrame * pMixBuf->cChannels], cSrcFrames1, pState); 1487 1341 1488 1342 /* Another chunk from the start of the mixing buffer? */ 1489 1343 if (cMaxSrcFrames > cSrcFrames1) 1490 1344 pState->pfnEncode((uint8_t *)pvDst + cSrcFrames1 * pState->cbDstFrame, 1491 &pMixBuf->p Frames[0].i64LSample, cMaxSrcFrames - cSrcFrames1, pState);1345 &pMixBuf->pi32Samples[0], cMaxSrcFrames - cSrcFrames1, pState); 1492 1346 } 1493 1347 else … … 1507 1361 { 1508 1362 /* Decode into temporary buffer. */ 1509 int 64_t ai64SrcDecoded[1024];1510 uint32_t cFramesDecoded = RT_MIN(RT_ELEMENTS(ai 64SrcDecoded) / pState->cSrcChannels, cbSrcBuf / pState->cbSrcFrame);1511 pState->pfnDecode(ai 64SrcDecoded, pvSrcBuf, cFramesDecoded, pState);1363 int32_t ai32SrcDecoded[1024]; 1364 uint32_t cFramesDecoded = RT_MIN(RT_ELEMENTS(ai32SrcDecoded) / pState->cSrcChannels, cbSrcBuf / pState->cbSrcFrame); 1365 pState->pfnDecode(ai32SrcDecoded, pvSrcBuf, cFramesDecoded, pState); 1512 1366 cbSrcBuf -= cFramesDecoded * pState->cbSrcFrame; 1513 1367 pvSrcBuf = (uint8_t const *)pvSrcBuf + cFramesDecoded * pState->cbSrcFrame; … … 1519 1373 uint32_t cDstMaxFrames = RT_MIN(pMixBuf->cFrames - offDstFrame, cMaxDstFrames); 1520 1374 uint32_t cSrcFrames = cFramesDecoded - iFrameDecoded; 1521 uint32_t const cDstFrames = pState->Rate.pfnResample(&pMixBuf->pFrames[offDstFrame].i64LSample, cDstMaxFrames, 1522 &ai64SrcDecoded[iFrameDecoded * pState->cSrcChannels], 1375 uint32_t const cDstFrames = pState->Rate.pfnResample(&pMixBuf->pi32Samples[offDstFrame * pMixBuf->cChannels], 1376 cDstMaxFrames, 1377 &ai32SrcDecoded[iFrameDecoded * pState->cSrcChannels], 1523 1378 cSrcFrames, &cSrcFrames, &pState->Rate); 1524 1379 … … 1587 1442 /* First chunk. */ 1588 1443 uint32_t const cDstFrames1 = RT_MIN(pMixBuf->cFrames - offDstFrame, cMaxDstFrames); 1589 pState->pfnDecode(&pMixBuf->p Frames[offDstFrame].i64LSample, pvSrcBuf, cDstFrames1, pState);1444 pState->pfnDecode(&pMixBuf->pi32Samples[offDstFrame * pMixBuf->cChannels], pvSrcBuf, cDstFrames1, pState); 1590 1445 1591 1446 /* Another chunk from the start of the mixing buffer? */ 1592 1447 if (cMaxDstFrames > cDstFrames1) 1593 pState->pfnDecode(&pMixBuf->p Frames[0].i64LSample, (uint8_t *)pvSrcBuf + cDstFrames1 * pState->cbSrcFrame,1448 pState->pfnDecode(&pMixBuf->pi32Samples[0], (uint8_t *)pvSrcBuf + cDstFrames1 * pState->cbSrcFrame, 1594 1449 cMaxDstFrames - cDstFrames1, pState); 1595 1450 } … … 1610 1465 { 1611 1466 /* Decode into temporary buffer. */ 1612 int 64_t ai64SrcDecoded[1024];1613 uint32_t cFramesDecoded = RT_MIN(RT_ELEMENTS(ai 64SrcDecoded) / pState->cSrcChannels, cbSrcBuf / pState->cbSrcFrame);1614 pState->pfnDecode(ai 64SrcDecoded, pvSrcBuf, cFramesDecoded, pState);1467 int32_t ai32SrcDecoded[1024]; 1468 uint32_t cFramesDecoded = RT_MIN(RT_ELEMENTS(ai32SrcDecoded) / pState->cSrcChannels, cbSrcBuf / pState->cbSrcFrame); 1469 pState->pfnDecode(ai32SrcDecoded, pvSrcBuf, cFramesDecoded, pState); 1615 1470 cbSrcBuf -= cFramesDecoded * pState->cbSrcFrame; 1616 1471 pvSrcBuf = (uint8_t const *)pvSrcBuf + cFramesDecoded * pState->cbSrcFrame; … … 1620 1475 while (iFrameDecoded < cFramesDecoded) 1621 1476 { 1622 int 64_t ai64SrcRate[1024];1623 uint32_t cDstMaxFrames = RT_MIN(RT_ELEMENTS(ai 64SrcRate), cMaxDstFrames);1477 int32_t ai32SrcRate[1024]; 1478 uint32_t cDstMaxFrames = RT_MIN(RT_ELEMENTS(ai32SrcRate), cMaxDstFrames); 1624 1479 uint32_t cSrcFrames = cFramesDecoded - iFrameDecoded; 1625 uint32_t const cDstFrames = pState->Rate.pfnResample(&ai 64SrcRate[0], cDstMaxFrames,1626 &ai 64SrcDecoded[iFrameDecoded * pState->cSrcChannels],1480 uint32_t const cDstFrames = pState->Rate.pfnResample(&ai32SrcRate[0], cDstMaxFrames, 1481 &ai32SrcDecoded[iFrameDecoded * pState->cSrcChannels], 1627 1482 cSrcFrames, &cSrcFrames, &pState->Rate); 1628 1483 1629 1484 /* First chunk.*/ 1630 1485 uint32_t const cDstFrames1 = RT_MIN(pMixBuf->cFrames - offDstFrame, cDstFrames); 1631 audioMixBufBlendBuffer(&pMixBuf->pFrames[offDstFrame].i64LSample, ai64SrcRate, cDstFrames1, pState->cSrcChannels); 1486 audioMixBufBlendBuffer(&pMixBuf->pi32Samples[offDstFrame * pMixBuf->cChannels], 1487 ai32SrcRate, cDstFrames1, pState->cSrcChannels); 1632 1488 1633 1489 /* Another chunk from the start of the mixing buffer? */ 1634 1490 if (cDstFrames > cDstFrames1) 1635 audioMixBufBlendBuffer(&pMixBuf->p Frames[0].i64LSample, &ai64SrcRate[cDstFrames1 * pState->cSrcChannels],1491 audioMixBufBlendBuffer(&pMixBuf->pi32Samples[0], &ai32SrcRate[cDstFrames1 * pState->cSrcChannels], 1636 1492 cDstFrames - cDstFrames1, pState->cSrcChannels); 1637 1493 … … 1687 1543 /* First chunk. */ 1688 1544 uint32_t const cDstFrames1 = RT_MIN(pMixBuf->cFrames - offDstFrame, cMaxDstFrames); 1689 pState->pfnDecodeBlend(&pMixBuf->p Frames[offDstFrame].i64LSample, pvSrcBuf, cDstFrames1, pState);1545 pState->pfnDecodeBlend(&pMixBuf->pi32Samples[offDstFrame * pMixBuf->cChannels], pvSrcBuf, cDstFrames1, pState); 1690 1546 1691 1547 /* Another chunk from the start of the mixing buffer? */ 1692 1548 if (cMaxDstFrames > cDstFrames1) 1693 pState->pfnDecodeBlend(&pMixBuf->p Frames[0].i64LSample, (uint8_t *)pvSrcBuf + cDstFrames1 * pState->cbSrcFrame,1549 pState->pfnDecodeBlend(&pMixBuf->pi32Samples[0], (uint8_t *)pvSrcBuf + cDstFrames1 * pState->cbSrcFrame, 1694 1550 cMaxDstFrames - cDstFrames1, pState); 1695 1551 } … … 1742 1598 */ 1743 1599 uint32_t const cFramesChunk1 = RT_MIN(pMixBuf->cFrames - offFrame, cFrames); 1744 RT_BZERO(&pMixBuf->p Frames[offFrame], cFramesChunk1 * sizeof(pMixBuf->pFrames[0]));1600 RT_BZERO(&pMixBuf->pi32Samples[offFrame * pMixBuf->cChannels], cFramesChunk1 * pMixBuf->cbFrame); 1745 1601 1746 1602 /* … … 1751 1607 cFrames -= cFramesChunk1; 1752 1608 AssertStmt(cFrames <= pMixBuf->cFrames, cFrames = pMixBuf->cFrames); 1753 RT_BZERO(&pMixBuf->p Frames[0], cFrames * sizeof(pMixBuf->pFrames[0]));1609 RT_BZERO(&pMixBuf->pi32Samples[0], cFrames * pMixBuf->cbFrame); 1754 1610 } 1755 1611 … … 1809 1665 static void audioMixAdjustVolumeWorker(PAUDIOMIXBUF pMixBuf, uint32_t off, uint32_t cFrames) 1810 1666 { 1811 PPDMAUDIOFRAME const paFrames = pMixBuf->pFrames; 1812 uint32_t const uLeft = pMixBuf->Volume.uLeft; 1813 uint32_t const uRight = pMixBuf->Volume.uRight; 1814 while (cFrames-- > 0) 1815 { 1816 paFrames[off].i64LSample = ASMMult2xS32RetS64(paFrames[off].i64LSample, uLeft) >> AUDIOMIXBUF_VOL_SHIFT; 1817 paFrames[off].i64RSample = ASMMult2xS32RetS64(paFrames[off].i64RSample, uRight) >> AUDIOMIXBUF_VOL_SHIFT; 1818 off++; 1667 int32_t *pi32Samples = &pMixBuf->pi32Samples[off * pMixBuf->cChannels]; 1668 switch (pMixBuf->cChannels) 1669 { 1670 case 1: 1671 { 1672 uint32_t const uFactorCh0 = pMixBuf->Volume.auChannels[0]; 1673 while (cFrames-- > 0) 1674 { 1675 *pi32Samples = (int32_t)(ASMMult2xS32RetS64(*pi32Samples, uFactorCh0) >> AUDIOMIXBUF_VOL_SHIFT); 1676 pi32Samples++; 1677 } 1678 break; 1679 } 1680 1681 case 2: 1682 { 1683 uint32_t const uFactorCh0 = pMixBuf->Volume.auChannels[0]; 1684 uint32_t const uFactorCh1 = pMixBuf->Volume.auChannels[1]; 1685 while (cFrames-- > 0) 1686 { 1687 pi32Samples[0] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[0], uFactorCh0) >> AUDIOMIXBUF_VOL_SHIFT); 1688 pi32Samples[1] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[1], uFactorCh1) >> AUDIOMIXBUF_VOL_SHIFT); 1689 pi32Samples += 2; 1690 } 1691 break; 1692 } 1693 1694 case 3: 1695 { 1696 uint32_t const uFactorCh0 = pMixBuf->Volume.auChannels[0]; 1697 uint32_t const uFactorCh1 = pMixBuf->Volume.auChannels[1]; 1698 uint32_t const uFactorCh2 = pMixBuf->Volume.auChannels[2]; 1699 while (cFrames-- > 0) 1700 { 1701 pi32Samples[0] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[0], uFactorCh0) >> AUDIOMIXBUF_VOL_SHIFT); 1702 pi32Samples[1] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[1], uFactorCh1) >> AUDIOMIXBUF_VOL_SHIFT); 1703 pi32Samples[2] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[2], uFactorCh2) >> AUDIOMIXBUF_VOL_SHIFT); 1704 pi32Samples += 3; 1705 } 1706 break; 1707 } 1708 1709 case 4: 1710 { 1711 uint32_t const uFactorCh0 = pMixBuf->Volume.auChannels[0]; 1712 uint32_t const uFactorCh1 = pMixBuf->Volume.auChannels[1]; 1713 uint32_t const uFactorCh2 = pMixBuf->Volume.auChannels[2]; 1714 uint32_t const uFactorCh3 = pMixBuf->Volume.auChannels[3]; 1715 while (cFrames-- > 0) 1716 { 1717 pi32Samples[0] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[0], uFactorCh0) >> AUDIOMIXBUF_VOL_SHIFT); 1718 pi32Samples[1] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[1], uFactorCh1) >> AUDIOMIXBUF_VOL_SHIFT); 1719 pi32Samples[2] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[2], uFactorCh2) >> AUDIOMIXBUF_VOL_SHIFT); 1720 pi32Samples[3] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[3], uFactorCh3) >> AUDIOMIXBUF_VOL_SHIFT); 1721 pi32Samples += 4; 1722 } 1723 break; 1724 } 1725 1726 case 5: 1727 { 1728 uint32_t const uFactorCh0 = pMixBuf->Volume.auChannels[0]; 1729 uint32_t const uFactorCh1 = pMixBuf->Volume.auChannels[1]; 1730 uint32_t const uFactorCh2 = pMixBuf->Volume.auChannels[2]; 1731 uint32_t const uFactorCh3 = pMixBuf->Volume.auChannels[3]; 1732 uint32_t const uFactorCh4 = pMixBuf->Volume.auChannels[4]; 1733 while (cFrames-- > 0) 1734 { 1735 pi32Samples[0] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[0], uFactorCh0) >> AUDIOMIXBUF_VOL_SHIFT); 1736 pi32Samples[1] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[1], uFactorCh1) >> AUDIOMIXBUF_VOL_SHIFT); 1737 pi32Samples[2] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[2], uFactorCh2) >> AUDIOMIXBUF_VOL_SHIFT); 1738 pi32Samples[3] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[3], uFactorCh3) >> AUDIOMIXBUF_VOL_SHIFT); 1739 pi32Samples[4] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[4], uFactorCh4) >> AUDIOMIXBUF_VOL_SHIFT); 1740 pi32Samples += 5; 1741 } 1742 break; 1743 } 1744 1745 case 6: 1746 { 1747 uint32_t const uFactorCh0 = pMixBuf->Volume.auChannels[0]; 1748 uint32_t const uFactorCh1 = pMixBuf->Volume.auChannels[1]; 1749 uint32_t const uFactorCh2 = pMixBuf->Volume.auChannels[2]; 1750 uint32_t const uFactorCh3 = pMixBuf->Volume.auChannels[3]; 1751 uint32_t const uFactorCh4 = pMixBuf->Volume.auChannels[4]; 1752 uint32_t const uFactorCh5 = pMixBuf->Volume.auChannels[5]; 1753 while (cFrames-- > 0) 1754 { 1755 pi32Samples[0] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[0], uFactorCh0) >> AUDIOMIXBUF_VOL_SHIFT); 1756 pi32Samples[1] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[1], uFactorCh1) >> AUDIOMIXBUF_VOL_SHIFT); 1757 pi32Samples[2] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[2], uFactorCh2) >> AUDIOMIXBUF_VOL_SHIFT); 1758 pi32Samples[3] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[3], uFactorCh3) >> AUDIOMIXBUF_VOL_SHIFT); 1759 pi32Samples[4] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[4], uFactorCh4) >> AUDIOMIXBUF_VOL_SHIFT); 1760 pi32Samples[5] = (int32_t)(ASMMult2xS32RetS64(pi32Samples[5], uFactorCh5) >> AUDIOMIXBUF_VOL_SHIFT); 1761 pi32Samples += 6; 1762 } 1763 break; 1764 } 1765 1766 default: 1767 while (cFrames-- > 0) 1768 for (uint32_t iCh = 0; iCh < pMixBuf->cChannels; iCh++, pi32Samples++) 1769 *pi32Samples = ASMMult2xS32RetS64(*pi32Samples, pMixBuf->Volume.auChannels[iCh]) >> AUDIOMIXBUF_VOL_SHIFT; 1770 break; 1819 1771 } 1820 1772 } … … 1841 1793 /* first chunk */ 1842 1794 uint32_t const cFramesChunk1 = RT_MIN(pMixBuf->cFrames - offFirst, cFrames); 1843 RT_BZERO(&pMixBuf->p Frames[offFirst], sizeof(pMixBuf->pFrames[0])* cFramesChunk1);1795 RT_BZERO(&pMixBuf->pi32Samples[offFirst * pMixBuf->cChannels], pMixBuf->cbFrame * cFramesChunk1); 1844 1796 1845 1797 /* second chunk */ 1846 1798 if (cFramesChunk1 < cFrames) 1847 RT_BZERO(&pMixBuf->p Frames[0], sizeof(pMixBuf->pFrames[0])* (cFrames - cFramesChunk1));1799 RT_BZERO(&pMixBuf->pi32Samples[0], pMixBuf->cbFrame * (cFrames - cFramesChunk1)); 1848 1800 } 1849 1801 /* 1850 1802 * Less than max volume? 1851 1803 */ 1852 else if ( pMixBuf->Volume.uLeft != AUDIOMIXBUF_VOL_0DB 1853 || pMixBuf->Volume.uRight != AUDIOMIXBUF_VOL_0DB) 1804 else if (!pMixBuf->Volume.fAllMax) 1854 1805 { 1855 1806 /* first chunk */ … … 1909 1860 if (!pVol->fMuted) 1910 1861 { 1911 pMixBuf->Volume.fMuted = false; 1862 pMixBuf->Volume.fMuted = false; 1863 1912 1864 AssertCompileSize(pVol->uLeft, sizeof(uint8_t)); 1913 pMixBuf->Volume.uLeft = s_aVolumeConv[pVol->uLeft ] * (AUDIOMIXBUF_VOL_0DB >> 16); 1914 pMixBuf->Volume.uRight = s_aVolumeConv[pVol->uRight] * (AUDIOMIXBUF_VOL_0DB >> 16); 1865 pMixBuf->Volume.auChannels[0] = s_aVolumeConv[pVol->uLeft ] * (AUDIOMIXBUF_VOL_0DB >> 16); 1866 pMixBuf->Volume.auChannels[1] = s_aVolumeConv[pVol->uRight] * (AUDIOMIXBUF_VOL_0DB >> 16); 1867 for (uintptr_t i = 2; i < pMixBuf->cChannels; i++) 1868 pMixBuf->Volume.auChannels[i] = pMixBuf->Volume.auChannels[1]; 1869 1870 pMixBuf->Volume.fAllMax = true; 1871 for (uintptr_t i = 0; i < pMixBuf->cChannels; i++) 1872 if (pMixBuf->Volume.auChannels[i] != AUDIOMIXBUF_VOL_0DB) 1873 { 1874 pMixBuf->Volume.fAllMax = false; 1875 break; 1876 } 1915 1877 } 1916 1878 else 1917 1879 { 1918 pMixBuf->Volume.fMuted = true; 1919 pMixBuf->Volume.uLeft = 0; 1920 pMixBuf->Volume.uRight = 0; 1921 } 1922 } 1923 1880 pMixBuf->Volume.fMuted = true; 1881 pMixBuf->Volume.fAllMax = false; 1882 for (uintptr_t i = 0; i < RT_ELEMENTS(pMixBuf->Volume.auChannels); i++) 1883 pMixBuf->Volume.auChannels[i] = 0; 1884 } 1885 } 1886 -
trunk/src/VBox/Devices/Audio/AudioMixBuffer.h
r89373 r89378 50 50 union 51 51 { 52 int64_t ai64Samples[2]; 53 PDMAUDIOFRAME Frame; 52 int32_t ai32Samples[PDMAUDIO_MAX_CHANNELS]; 54 53 } SrcLast; 55 54 … … 58 57 * @returns Number of destination frames written. 59 58 */ 60 DECLR3CALLBACKMEMBER(uint32_t, pfnResample, (int 64_t *pi64Dst, uint32_t cDstFrames,61 int 64_t const *pi64Src, uint32_t cSrcFrames, uint32_t *pcSrcFramesRead,59 DECLR3CALLBACKMEMBER(uint32_t, pfnResample, (int32_t *pi32Dst, uint32_t cDstFrames, 60 int32_t const *pi32Src, uint32_t cSrcFrames, uint32_t *pcSrcFramesRead, 62 61 struct AUDIOSTREAMRATE *pRate)); 63 62 … … 76 75 /** Set to @c true if this stream is muted, @c false if not. */ 77 76 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; 77 /** Set if all (relevant) channels are at max. */ 78 bool fAllMax; 79 /** The per-channels values. */ 80 uint32_t auChannels[PDMAUDIO_MAX_CHANNELS]; 84 81 } AUDMIXBUFVOL; 85 82 /** Pointer to mixing buffer volument parameters. */ … … 99 96 { 100 97 /** Encodes @a cFrames from @a paSrc to @a pvDst. */ 101 DECLR3CALLBACKMEMBER(void, pfnEncode,(void *pvDst, int 64_t const *paSrc, uint32_t cFrames, struct AUDIOMIXBUFPEEKSTATE *pState));98 DECLR3CALLBACKMEMBER(void, pfnEncode,(void *pvDst, int32_t const *paSrc, uint32_t cFrames, struct AUDIOMIXBUFPEEKSTATE *pState)); 102 99 /** Sample rate conversion state (only used when needed). */ 103 100 AUDIOSTREAMRATE Rate; … … 120 117 { 121 118 /** Encodes @a cFrames from @a pvSrc to @a paDst. */ 122 DECLR3CALLBACKMEMBER(void, pfnDecode,(int 64_t *paDst, const void *pvSrc, uint32_t cFrames, struct AUDIOMIXBUFWRITESTATE *pState));119 DECLR3CALLBACKMEMBER(void, pfnDecode,(int32_t *paDst, const void *pvSrc, uint32_t cFrames, struct AUDIOMIXBUFWRITESTATE *pState)); 123 120 /** Encodes @a cFrames from @a pvSrc blending into @a paDst. */ 124 DECLR3CALLBACKMEMBER(void, pfnDecodeBlend,(int 64_t *paDst, const void *pvSrc, uint32_t cFrames, struct AUDIOMIXBUFWRITESTATE *pState));121 DECLR3CALLBACKMEMBER(void, pfnDecodeBlend,(int32_t *paDst, const void *pvSrc, uint32_t cFrames, struct AUDIOMIXBUFWRITESTATE *pState)); 125 122 /** Sample rate conversion state (only used when needed). */ 126 123 AUDIOSTREAMRATE Rate; … … 145 142 /** Size of the frame buffer (in audio frames). */ 146 143 uint32_t cFrames; 147 /** Frame buffer. */ 148 PPDMAUDIOFRAME pFrames; 144 /** The frame buffer. 145 * This is a two dimensional array consisting of cFrames rows and 146 * cChannels columns. */ 147 int32_t *pi32Samples; 148 /** The number of channels. */ 149 uint8_t cChannels; 150 /** The frame size (row size if you like). */ 151 uint8_t cbFrame; 152 uint8_t abPadding[2]; 149 153 /** The current read position (in frames). */ 150 154 uint32_t offRead;
Note:
See TracChangeset
for help on using the changeset viewer.