Changeset 88269 in vbox for trunk/include/VBox
- Timestamp:
- Mar 24, 2021 11:45:54 AM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 143474
- Location:
- trunk/include/VBox/vmm
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/pdmaudioifs.h
r88259 r88269 570 570 /** Unknown access type; do not use (hdaR3StreamMapReset uses it). */ 571 571 PDMAUDIOSTREAMLAYOUT_UNKNOWN, 572 /** Non-interleaved access, that is, consecutive 573 * access to the data. */ 572 /** Non-interleaved access, that is, consecutive access to the data. 573 * @todo r=bird: For plain stereo this is actually interleaves left/right. What 574 * I guess non-interleaved means, is that there are no additional 575 * information interleaved next to the interleaved stereo. 576 * https://stackoverflow.com/questions/17879933/whats-the-interleaved-audio */ 574 577 PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED, 575 /** Interleaved access, where the data can be 576 * mixed together with data of other audio streams. */ 578 /** Interleaved access, where the data can be mixed together with data of other audio streams. */ 577 579 PDMAUDIOSTREAMLAYOUT_INTERLEAVED, 578 /** Complex layout, which does not fit into the 579 * interleaved / non-interleaved layouts. */ 580 /** Complex layout, which does not fit into the interleaved / non-interleaved layouts. */ 580 581 PDMAUDIOSTREAMLAYOUT_COMPLEX, 581 582 /** Raw (pass through) data, with no data layout processing done. 582 583 * 583 584 * This means that this stream will operate on PDMAUDIOFRAME data 584 * directly. Don't use this if you don't have to. */ 585 * directly. Don't use this if you don't have to. 586 * 587 * @deprecated Replaced by S64 (signed, 64-bit sample size). */ 585 588 PDMAUDIOSTREAMLAYOUT_RAW, 586 589 /** End of valid values. */ … … 689 692 typedef struct PDMAUDIOPCMPROPS 690 693 { 691 /** @todo squeeze cbSample and cChannels into one uint8_t; Add cbFrame. */ 694 /** The frame size. */ 695 uint8_t cbFrame; 692 696 /** Sample width (in bytes). */ 693 uint8_t cbSample ;697 uint8_t cbSampleX : 4; 694 698 /** Number of audio channels. */ 695 uint8_t cChannels ;699 uint8_t cChannelsX : 4; 696 700 /** Shift count used with PDMAUDIOPCMPROPS_F2B and PDMAUDIOPCMPROPS_B2F. 697 701 * Depends on number of stream channels and the stream format being used, calc 698 702 * value using PDMAUDIOPCMPROPS_MAKE_SHIFT. 699 * @sa PDMAUDIOSTREAMCFG_B2F, PDMAUDIOSTREAMCFG_F2B 700 * @todo r=bird: The original brief description: "Shift count used 701 * for faster calculation of various values, such as the alignment, bytes 702 * to frames and so on." I cannot make heads or tails from that. 703 * @todo Use some RTAsmXXX functions instead? */ 704 uint8_t cShift; 703 * @sa PDMAUDIOSTREAMCFG_B2F, PDMAUDIOSTREAMCFG_F2B */ 704 uint8_t cShiftX; 705 705 /** Signed or unsigned sample. */ 706 706 bool fSigned : 1; 707 707 /** Whether the endianness is swapped or not. */ 708 708 bool fSwapEndian : 1; 709 /** Raw mixer frames, only applicable for signed 64-bit samples. */ 710 bool fRaw : 1; 709 711 /** Sample frequency in Hertz (Hz). */ 710 712 uint32_t uHz; … … 719 721 /** @name Macros for use with PDMAUDIOPCMPROPS 720 722 * @{ */ 721 /** Initializer for PDMAUDIOPCMPROPS. 722 * @todo /PDMAUDIOPCMPROPS_INITIALIZOR/PDMAUDIOPCMPROPS_INITIALIZER/ */ 723 #define PDMAUDIOPCMPROPS_INITIALIZOR(a_cBytes, a_fSigned, a_cCannels, a_uHz, a_cShift, a_fSwapEndian)\724 { a_cBytes, a_cCannels, a_cShift, a_fSigned, a_fSwapEndian, a_uHz }723 /** Initializer for PDMAUDIOPCMPROPS. */ 724 #define PDMAUDIOPCMPROPS_INITIALIZER(a_cbSample, a_fSigned, a_cChannels, a_uHz, a_fSwapEndian) \ 725 { (a_cbSample) * (a_cChannels), a_cbSample, a_cChannels, PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(a_cbSample, a_cChannels), \ 726 a_fSigned, a_fSwapEndian, false /*fRaw*/, a_uHz } 725 727 /** Calculates the cShift value of given sample bits and audio channels. 726 * @note This only works when the frame size is a 727 * Does only support mono/stereo channels for now, for non-stereo/mono we 728 * @note Does only support mono/stereo channels for now, for non-stereo/mono we 728 729 * returns a special value which the two conversion functions detect 729 730 * and make them fall back on cbSample * cChannels. */ … … 733 734 /** Calculates the cShift value of a PDMAUDIOPCMPROPS structure. */ 734 735 #define PDMAUDIOPCMPROPS_MAKE_SHIFT(pProps) \ 735 PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS((pProps)->cbSample , (pProps)->cChannels)736 PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS((pProps)->cbSampleX, (pProps)->cChannelsX) 736 737 /** Converts (audio) frames to bytes. 737 * Needs the cShift value set correctly, using PDMAUDIOPCMPROPS_MAKE_SHIFT. */ 738 * @note Requires properly initialized properties, i.e. cbFrames correctly calculated 739 * and cShift set using PDMAUDIOPCMPROPS_MAKE_SHIFT. */ 738 740 #define PDMAUDIOPCMPROPS_F2B(pProps, cFrames) \ 739 ( (pProps)->cShift != UINT8_MAX ? (cFrames) << (pProps)->cShift : (cFrames) * ((pProps)->cbSample * (pProps)->cChannels))741 ( (pProps)->cShiftX != UINT8_MAX ? (cFrames) << (pProps)->cShiftX : (cFrames) * (pProps)->cbFrame ) 740 742 /** Converts bytes to (audio) frames. 741 * Needs the cShift value set correctly, using PDMAUDIOPCMPROPS_MAKE_SHIFT. */ 743 * @note Requires properly initialized properties, i.e. cbFrames correctly calculated 744 * and cShift set using PDMAUDIOPCMPROPS_MAKE_SHIFT. */ 742 745 #define PDMAUDIOPCMPROPS_B2F(pProps, cb) \ 743 ( (pProps)->cShift != UINT8_MAX ? (cb) >> (pProps)->cShift : (cb) / ((pProps)->cbSample * (pProps)->cChannels))746 ( (pProps)->cShiftX != UINT8_MAX ? (cb) >> (pProps)->cShiftX : (cb) / (pProps)->cbFrame ) 744 747 /** @} */ 745 748 … … 766 769 * PDMAUDIOSTREAMLAYOUT_RAW: 767 770 * Can be one or many streams at once, depending on the stream's mixing buffer setup. 768 * The audio data will get handled as PDMAUDIOFRAME frames without any modification done. */ 771 * The audio data will get handled as PDMAUDIOFRAME frames without any modification done. 772 * 773 * @todo r=bird: See PDMAUDIOSTREAMLAYOUT comments. */ 769 774 PDMAUDIOSTREAMLAYOUT enmLayout; 770 775 /** Device emulation-specific data needed for the audio connector. */ … … 806 811 807 812 /** Converts (audio) frames to bytes. */ 808 #define PDMAUDIOSTREAMCFG_F2B(pCfg, frames) ((frames) << (pCfg->Props).cShift)813 #define PDMAUDIOSTREAMCFG_F2B(pCfg, frames) PDMAUDIOPCMPROPS_F2B(&(pCfg)->Props, (frames)) 809 814 /** Converts bytes to (audio) frames. */ 810 #define PDMAUDIOSTREAMCFG_B2F(pCfg, cb) (cb >> (pCfg->Props).cShift)815 #define PDMAUDIOSTREAMCFG_B2F(pCfg, cb) PDMAUDIOPCMPROPS_B2F(&(pCfg)->Props, (cb)) 811 816 812 817 /** … … 1008 1013 /** Magic value (PDMAUDIOMIXBUF_MAGIC). */ 1009 1014 uint32_t uMagic; 1010 /** For quickly converting frames <-> bytes and vice versa. */ 1011 uint8_t cShift; 1012 uint8_t abPadding[3]; 1015 uint8_t abPadding[4]; 1013 1016 /* ???Undocumented??? */ 1014 1017 RTLISTNODE Node; … … 1048 1051 * all? */ 1049 1052 PDMAUDIOMIXBUFFMT uAudioFmt; 1053 /** Audio input properties. 1054 * @note There is only one set of audio properties here because we have one 1055 * mixer buffer for the guest side and a separate one for the host side. 1056 * @todo r=bird: Why exactly do we need to use separate mixer buffers? 1057 * Couldn't we just have different conversion fuctions and save the 1058 * extra copying? */ 1059 PDMAUDIOPCMPROPS Props; 1050 1060 /** Standard conversion-to function for set uAudioFmt. */ 1051 1061 PFNPDMAUDIOMIXBUFCONVTO pfnConvTo; 1052 1062 /** Standard conversion-from function for set uAudioFmt. */ 1053 1063 PFNPDMAUDIOMIXBUFCONVFROM pfnConvFrom; 1064 1054 1065 /** Ratio of the associated parent stream's frequency by this stream's 1055 1066 * frequency (1<<32), represented as a signed 64 bit integer. -
trunk/include/VBox/vmm/pdmaudioinline.h
r88136 r88269 365 365 if (pCfg) 366 366 LogFunc(("szName=%s enmDir=%RU32 uHz=%RU32 cBits=%RU8%s cChannels=%RU8\n", pCfg->szName, pCfg->enmDir, 367 pCfg->Props.uHz, pCfg->Props.cbSample * 8, pCfg->Props.fSigned ? "S" : "U", pCfg->Props.cChannels));367 pCfg->Props.uHz, pCfg->Props.cbSampleX * 8, pCfg->Props.fSigned ? "S" : "U", pCfg->Props.cChannelsX)); 368 368 } 369 369 … … 467 467 468 468 /** 469 * Initialize PCM audio properties. 470 */ 471 DECLINLINE(void) PDMAudioPropsInit(PPDMAUDIOPCMPROPS pProps, uint8_t cbSample, bool fSigned, uint8_t cChannels, uint32_t uHz) 472 { 473 pProps->cbFrame = cbSample * cChannels; 474 pProps->cbSampleX = cbSample; 475 pProps->cChannelsX = cChannels; 476 pProps->cShiftX = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(cbSample, cChannels); 477 pProps->fSigned = fSigned; 478 pProps->fSwapEndian = false; 479 pProps->fRaw = false; 480 pProps->uHz = uHz; 481 482 Assert(pProps->cbFrame == (uint32_t)cbSample * cChannels); 483 Assert(pProps->cbSampleX == cbSample); 484 Assert(pProps->cChannelsX == cChannels); 485 } 486 487 /** 488 * Initialize PCM audio properties, extended version. 489 */ 490 DECLINLINE(void) PDMAudioPropsInitEx(PPDMAUDIOPCMPROPS pProps, uint8_t cbSample, bool fSigned, uint8_t cChannels, uint32_t uHz, 491 bool fLittleEndian, bool fRaw) 492 { 493 Assert(!fRaw || cbSample == sizeof(int64_t)); 494 pProps->cbFrame = cbSample * cChannels; 495 pProps->cbSampleX = cbSample; 496 pProps->cChannelsX = cChannels; 497 pProps->cShiftX = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(cbSample, cChannels); 498 pProps->fSigned = fSigned; 499 #ifdef RT_LITTLE_ENDIAN 500 pProps->fSwapEndian = !fLittleEndian; 501 #else 502 pProps->fSwapEndian = fLittleEndian; 503 #endif 504 pProps->fRaw = fRaw; 505 pProps->uHz = uHz; 506 507 Assert(pProps->cbFrame == (uint32_t)cbSample * cChannels); 508 Assert(pProps->cbSampleX == cbSample); 509 Assert(pProps->cChannelsX == cChannels); 510 } 511 512 /** 513 * Modifies the channel count. 514 * 515 * @param pProps The PCM properties to update. 516 * @param cChannels The new channel count. 517 */ 518 DECLINLINE(void) PDMAudioPropsSetChannels(PPDMAUDIOPCMPROPS pProps, uint8_t cChannels) 519 { 520 Assert(cChannels > 0); Assert(cChannels < 16); 521 pProps->cChannelsX = cChannels; 522 pProps->cbFrame = pProps->cbSampleX * cChannels; 523 pProps->cShiftX = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pProps->cbSampleX, cChannels); 524 } 525 526 /** 527 * Modifies the sample size. 528 * 529 * @param pProps The PCM properties to update. 530 * @param cbSample The new sample size (in bytes). 531 */ 532 DECLINLINE(void) PDMAudioPropsSetSampleSize(PPDMAUDIOPCMPROPS pProps, uint8_t cbSample) 533 { 534 Assert(cbSample == 1 || cbSample == 2 || cbSample == 4 || cbSample == 8); 535 pProps->cbSampleX = cbSample; 536 pProps->cbFrame = cbSample * pProps->cChannelsX; 537 pProps->cShiftX = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(cbSample, pProps->cChannelsX); 538 } 539 540 /** 469 541 * Gets the bitrate. 470 542 * … … 476 548 DECLINLINE(uint32_t) PDMAudioPropsGetBitrate(PCPDMAUDIOPCMPROPS pProps) 477 549 { 478 return pProps->cbSample * pProps->cChannels * pProps->uHz * 8; 550 Assert(pProps->cbFrame == pProps->cbSampleX * pProps->cChannelsX); 551 return pProps->cbFrame * pProps->uHz * 8; 552 } 553 554 /** 555 * Gets the number of channels. 556 * @returns The channel count. 557 * @param pProps The PCM properties. 558 */ 559 DECL_FORCE_INLINE(uint8_t) PDMAudioPropsChannels(PCPDMAUDIOPCMPROPS pProps) 560 { 561 return pProps->cChannelsX; 562 } 563 564 /** 565 * Gets the sample size in bytes. 566 * @returns Number of bytes per sample. 567 * @param pProps The PCM properties. 568 */ 569 DECL_FORCE_INLINE(uint8_t) PDMAudioPropsSampleSize(PCPDMAUDIOPCMPROPS pProps) 570 { 571 return pProps->cbSampleX; 572 } 573 574 /** 575 * Gets the sample size in bits. 576 * @returns Number of bits per sample. 577 * @param pProps The PCM properties. 578 */ 579 DECLINLINE(uint8_t) PDMAudioPropsSampleBits(PCPDMAUDIOPCMPROPS pProps) 580 { 581 return pProps->cbSampleX * 8; 582 } 583 584 /** 585 * Gets the frame size in bytes. 586 * @returns Number of bytes per frame. 587 * @param pProps The PCM properties. 588 */ 589 DECL_FORCE_INLINE(uint8_t) PDMAudioPropsFrameSize(PCPDMAUDIOPCMPROPS pProps) 590 { 591 return pProps->cbFrame; 592 } 593 594 /** 595 * Gets the frequency. 596 * @returns Frequency. 597 * @param pProps The PCM properties. 598 */ 599 DECL_FORCE_INLINE(uint32_t) PDMAudioPropsHz(PCPDMAUDIOPCMPROPS pProps) 600 { 601 return pProps->uHz; 602 } 603 604 /** 605 * Checks if the format is signed or unsigned. 606 * @returns true if signed, false if unsigned. 607 * @param pProps The PCM properties. 608 */ 609 DECL_FORCE_INLINE(bool) PDMAudioPropsIsSigned(PCPDMAUDIOPCMPROPS pProps) 610 { 611 return pProps->fSigned; 612 } 613 614 /** 615 * Checks if the format is little-endian or not. 616 * @returns true if little-endian (or if 8-bit), false if big-endian. 617 * @param pProps The PCM properties. 618 */ 619 DECL_FORCE_INLINE(bool) PDMAudioPropsIsLittleEndian(PCPDMAUDIOPCMPROPS pProps) 620 { 621 #ifdef RT_LITTLE_ENDIAN 622 return !pProps->fSwapEndian || pProps->cbSampleX < 2; 623 #else 624 return pProps->fSwapEndian || pProps->cbSampleX < 2; 625 #endif 626 } 627 628 /** 629 * Checks if the format is big-endian or not. 630 * @returns true if big-endian (or if 8-bit), false if little-endian. 631 * @param pProps The PCM properties. 632 */ 633 DECL_FORCE_INLINE(bool) PDMAudioPropsIsBigEndian(PCPDMAUDIOPCMPROPS pProps) 634 { 635 #ifdef RT_LITTLE_ENDIAN 636 return pProps->fSwapEndian || pProps->cbSampleX < 2; 637 #else 638 return !pProps->fSwapEndian || pProps->cbSampleX < 2; 639 #endif 479 640 } 480 641 … … 775 936 */ 776 937 AssertPtrReturnVoid(pProps); 777 Assert(pProps->cbSample );938 Assert(pProps->cbSampleX); 778 939 if (!cbBuf || !cFrames) 779 940 return; … … 788 949 AssertStmt(cbToClear <= cbBuf, cbToClear = cbBuf); 789 950 790 Log2Func(("pProps=%p, pvBuf=%p, cFrames=%RU32, fSigned=%RTbool, c Bytes=%RU8\n",791 pProps, pvBuf, cFrames, pProps->fSigned, pProps->cbSample ));951 Log2Func(("pProps=%p, pvBuf=%p, cFrames=%RU32, fSigned=%RTbool, cbSample=%RU8\n", 952 pProps, pvBuf, cFrames, pProps->fSigned, pProps->cbSampleX)); 792 953 793 954 /* … … 798 959 else /* Unsigned formats. */ 799 960 { 800 switch (pProps->cbSample )961 switch (pProps->cbSampleX) 801 962 { 802 963 case 1: /* 8 bit */ … … 820 981 821 982 default: 822 AssertMsgFailed(("Invalid bytes per sample: %RU8\n", pProps->cbSample ));983 AssertMsgFailed(("Invalid bytes per sample: %RU8\n", pProps->cbSampleX)); 823 984 } 824 985 } … … 841 1002 842 1003 return pProps1->uHz == pProps2->uHz 843 && pProps1->cChannels == pProps2->cChannels844 && pProps1->cbSample == pProps2->cbSample1004 && pProps1->cChannelsX == pProps2->cChannelsX 1005 && pProps1->cbSampleX == pProps2->cbSampleX 845 1006 && pProps1->fSigned == pProps2->fSigned 846 1007 && pProps1->fSwapEndian == pProps2->fSwapEndian; … … 862 1023 AssertPtrReturn(pProps, false); 863 1024 864 AssertReturn(pProps->cChannels != 0, false); 865 AssertMsgReturn(pProps->cbSample == 1 || pProps->cbSample == 2 || pProps->cbSample == 4, 866 ("%u\n", pProps->cbSample), false); 1025 AssertReturn(pProps->cChannelsX != 0, false); 1026 AssertMsgReturn( pProps->cbSampleX == 1 || pProps->cbSampleX == 2 || pProps->cbSampleX == 4 || (pProps->cbSampleX == 8 && pProps->fRaw), 1027 ("%u\n", pProps->cbSampleX), false); 1028 AssertMsgReturn(pProps->cbFrame == pProps->cbSampleX * pProps->cChannelsX, 1029 ("cbFrame=%u cbSample=%u cChannels=%u\n", pProps->cbFrame, pProps->cbSampleX, pProps->cChannelsX), 1030 false); 867 1031 AssertMsgReturn(pProps->uHz >= 1000 && pProps->uHz < 1000000, ("%u\n", pProps->uHz), false); 868 AssertMsgReturn(pProps->cShift == PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pProps->cbSample, pProps->cChannels),869 ("cShift=%u cbSample=%u cChannels=%u\n", pProps->cShift , pProps->cbSample, pProps->cChannels),1032 AssertMsgReturn(pProps->cShiftX == PDMAUDIOPCMPROPS_MAKE_SHIFT(pProps), 1033 ("cShift=%u cbSample=%u cChannels=%u\n", pProps->cShiftX, pProps->cbSampleX, pProps->cChannelsX), 870 1034 false); 1035 AssertReturn(!pProps->fRaw || (pProps->fSigned && pProps->cbSampleX == sizeof(int64_t)), false); 871 1036 return true; 872 1037 } … … 887 1052 * Prints PCM properties to the debug log. 888 1053 * 889 * @param pProps Stream configuration to log.1054 * @param pProps PCM properties to use. 890 1055 */ 891 1056 DECLINLINE(void) PDMAudioPropsLog(PCPDMAUDIOPCMPROPS pProps) … … 894 1059 895 1060 Log(("uHz=%RU32, cChannels=%RU8, cBits=%RU8%s", 896 pProps->uHz, pProps->cChannels, pProps->cbSample * 8, pProps->fSigned ? "S" : "U")); 897 } 1061 pProps->uHz, pProps->cChannelsX, pProps->cbSampleX * 8, pProps->fSigned ? "S" : "U")); 1062 } 1063 1064 /** Max necessary buffer space for PDMAudioPropsToString */ 1065 #define PDMAUDIOPROPSTOSTRING_MAX sizeof("16ch S64 4294967296Hz swap raw") 1066 1067 /** 1068 * Formats the PCM audio properties into a string buffer. 1069 * 1070 * @returns pszDst 1071 * @param pProps PCM properties to use. 1072 * @param pszDst The destination buffer. 1073 * @param cchDst The size of the destination buffer. Recommended to be at 1074 * least PDMAUDIOPROPSTOSTRING_MAX bytes. 1075 */ 1076 DECLINLINE(char *) PDMAudioPropsToString(PCPDMAUDIOPCMPROPS pProps, char *pszDst, size_t cchDst) 1077 { 1078 /* 2ch S64 44100Hz swap raw */ 1079 RTStrPrintf(pszDst, cchDst, "%uch %c%u %RU32Hz%s%s", 1080 PDMAudioPropsChannels(pProps), PDMAudioPropsIsSigned(pProps) ? 'S' : 'U', PDMAudioPropsSampleBits(pProps), 1081 PDMAudioPropsHz(pProps), pProps->fSwapEndian ? " swap" : "", pProps->fRaw ? " raw" : ""); 1082 return pszDst; 1083 } 1084 1085 898 1086 899 1087 /** @} */
Note:
See TracChangeset
for help on using the changeset viewer.