Changeset 88480 in vbox
- Timestamp:
- Apr 13, 2021 12:52:25 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvHostAudioPulseAudio.cpp
r88479 r88480 134 134 { 135 135 /** The stream's acquired configuration. */ 136 P PDMAUDIOSTREAMCFG pCfg;136 PDMAUDIOSTREAMCFG Cfg; 137 137 /** Pointer to driver instance. */ 138 138 PDRVHOSTPULSEAUDIO pDrv; … … 398 398 * - 1: End of list, no info. 399 399 * - -1: Error callback, no info. 400 * @param pvUserData Pointer to our PULSEAUDIOENUMCBCTX structure. 400 401 */ 401 402 static void drvHostAudioPaEnumSourceCallback(pa_context *pCtx, const pa_source_info *pInfo, int eol, void *pvUserData) … … 433 434 * - 1: End of list, no info. 434 435 * - -1: Error callback, no info. 436 * @param pvUserData Pointer to our PULSEAUDIOENUMCBCTX structure. 435 437 */ 436 438 static void drvHostAudioPaEnumSinkCallback(pa_context *pCtx, const pa_sink_info *pInfo, int eol, void *pvUserData) … … 659 661 660 662 661 static pa_sample_format_t drvHostAudioPaPropsToPulse(PPDMAUDIOPCMPROPS pProps)662 {663 switch (PDMAudioPropsSampleSize(pProps))664 {665 case 1:666 if (!pProps->fSigned)667 return PA_SAMPLE_U8;668 break;669 670 case 2:671 if (pProps->fSigned)672 return PDMAudioPropsIsLittleEndian(pProps) ? PA_SAMPLE_S16LE : PA_SAMPLE_S16BE;673 break;674 675 #ifdef PA_SAMPLE_S32LE676 case 4:677 if (pProps->fSigned)678 return PDMAudioPropsIsLittleEndian(pProps) ? PA_SAMPLE_S32LE : PA_SAMPLE_S32BE;679 break;680 #endif681 }682 683 AssertMsgFailed(("%RU8%s not supported\n", PDMAudioPropsSampleSize(pProps), pProps->fSigned ? "S" : "U"));684 return PA_SAMPLE_INVALID;685 }686 687 688 static int drvHostAudioPaToAudioProps(PPDMAUDIOPCMPROPS pProps, pa_sample_format_t pulsefmt, uint8_t cChannels, uint32_t uHz)689 {690 AssertReturn(cChannels > 0, VERR_INVALID_PARAMETER);691 AssertReturn(cChannels < 16, VERR_INVALID_PARAMETER);692 693 switch (pulsefmt)694 {695 case PA_SAMPLE_U8:696 PDMAudioPropsInit(pProps, 1 /*8-bit*/, false /*signed*/, cChannels, uHz);697 break;698 699 case PA_SAMPLE_S16LE:700 PDMAudioPropsInitEx(pProps, 2 /*16-bit*/, true /*signed*/, cChannels, uHz, true /*fLittleEndian*/, false /*fRaw*/);701 break;702 703 case PA_SAMPLE_S16BE:704 PDMAudioPropsInitEx(pProps, 2 /*16-bit*/, true /*signed*/, cChannels, uHz, false /*fLittleEndian*/, false /*fRaw*/);705 break;706 707 #ifdef PA_SAMPLE_S32LE708 case PA_SAMPLE_S32LE:709 PDMAudioPropsInitEx(pProps, 4 /*32-bit*/, true /*signed*/, cChannels, uHz, true /*fLittleEndian*/, false /*fRaw*/);710 break;711 #endif712 713 #ifdef PA_SAMPLE_S32BE714 case PA_SAMPLE_S32BE:715 PDMAudioPropsInitEx(pProps, 4 /*32-bit*/, true /*signed*/, cChannels, uHz, false /*fLittleEndian*/, false /*fRaw*/);716 break;717 #endif718 719 default:720 AssertLogRelMsgFailed(("PulseAudio: Format (%d) not supported\n", pulsefmt));721 return VERR_NOT_SUPPORTED;722 }723 724 return VINF_SUCCESS;725 }726 727 728 663 /** 729 664 * Stream status changed. … … 819 754 #endif /* DEBUG */ 820 755 821 822 static int drvHostAudioPaStreamOpen(PDRVHOSTPULSEAUDIO pThis, PPULSEAUDIOSTREAM pStreamPA, bool fIn, const char *pszName) 823 { 824 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 825 AssertPtrReturn(pStreamPA, VERR_INVALID_POINTER); 826 AssertPtrReturn(pszName, VERR_INVALID_POINTER); 827 756 /** 757 * Converts from PDM PCM properties to pulse audio format. 758 * 759 * Worker for the stream creation code. 760 * 761 * @returns PA format. 762 * @retval PA_SAMPLE_INVALID if format not supported. 763 * @param pProps The PDM audio source properties. 764 */ 765 static pa_sample_format_t drvHostAudioPaPropsToPulse(PCPDMAUDIOPCMPROPS pProps) 766 { 767 switch (PDMAudioPropsSampleSize(pProps)) 768 { 769 case 1: 770 if (!PDMAudioPropsIsSigned(pProps)) 771 return PA_SAMPLE_U8; 772 break; 773 774 case 2: 775 if (PDMAudioPropsIsSigned(pProps)) 776 return PDMAudioPropsIsLittleEndian(pProps) ? PA_SAMPLE_S16LE : PA_SAMPLE_S16BE; 777 break; 778 779 #ifdef PA_SAMPLE_S32LE 780 case 4: 781 if (PDMAudioPropsIsSigned(pProps)) 782 return PDMAudioPropsIsLittleEndian(pProps) ? PA_SAMPLE_S32LE : PA_SAMPLE_S32BE; 783 break; 784 #endif 785 } 786 787 AssertMsgFailed(("%RU8%s not supported\n", PDMAudioPropsSampleSize(pProps), PDMAudioPropsIsSigned(pProps) ? "S" : "U")); 788 return PA_SAMPLE_INVALID; 789 } 790 791 792 /** 793 * Converts from pulse audio sample specification to PDM PCM audio properties. 794 * 795 * Worker for the stream creation code. 796 * 797 * @returns VBox status code. 798 * @param pProps The PDM audio source properties. 799 */ 800 static int drvHostAudioPaToAudioProps(PPDMAUDIOPCMPROPS pProps, pa_sample_format_t pulsefmt, uint8_t cChannels, uint32_t uHz) 801 { 802 AssertReturn(cChannels > 0, VERR_INVALID_PARAMETER); 803 AssertReturn(cChannels < 16, VERR_INVALID_PARAMETER); 804 805 switch (pulsefmt) 806 { 807 case PA_SAMPLE_U8: 808 PDMAudioPropsInit(pProps, 1 /*8-bit*/, false /*signed*/, cChannels, uHz); 809 break; 810 811 case PA_SAMPLE_S16LE: 812 PDMAudioPropsInitEx(pProps, 2 /*16-bit*/, true /*signed*/, cChannels, uHz, true /*fLittleEndian*/, false /*fRaw*/); 813 break; 814 815 case PA_SAMPLE_S16BE: 816 PDMAudioPropsInitEx(pProps, 2 /*16-bit*/, true /*signed*/, cChannels, uHz, false /*fLittleEndian*/, false /*fRaw*/); 817 break; 818 819 #ifdef PA_SAMPLE_S32LE 820 case PA_SAMPLE_S32LE: 821 PDMAudioPropsInitEx(pProps, 4 /*32-bit*/, true /*signed*/, cChannels, uHz, true /*fLittleEndian*/, false /*fRaw*/); 822 break; 823 #endif 824 825 #ifdef PA_SAMPLE_S32BE 826 case PA_SAMPLE_S32BE: 827 PDMAudioPropsInitEx(pProps, 4 /*32-bit*/, true /*signed*/, cChannels, uHz, false /*fLittleEndian*/, false /*fRaw*/); 828 break; 829 #endif 830 831 default: 832 AssertLogRelMsgFailed(("PulseAudio: Format (%d) not supported\n", pulsefmt)); 833 return VERR_NOT_SUPPORTED; 834 } 835 836 return VINF_SUCCESS; 837 } 838 839 840 /** 841 * Worker that does the actual creation of an PA stream. 842 * 843 * @returns VBox status code. 844 * @param pThis Our driver instance data. 845 * @param pStreamPA Our stream data. 846 * @param fIn The direction indicator. 847 * @param pszName How we name the stream. 848 * @param pCfgAcq Where to return the actual stream properties. (ASSUMES 849 * same as pCfgAcq on input.) 850 */ 851 static int drvHostAudioPaStreamOpen(PDRVHOSTPULSEAUDIO pThis, PPULSEAUDIOSTREAM pStreamPA, bool fIn, 852 const char *pszName, PPDMAUDIOSTREAMCFG pCfgAcq) 853 { 828 854 int rc = VERR_AUDIO_STREAM_COULD_NOT_CREATE; 829 855 pa_stream *pStream = NULL; … … 930 956 pBufAttr->tlength, pBufAttr->maxlength, pBufAttr->minreq, pBufAttr->fragsize, pBufAttr->prebuf)); 931 957 932 pStreamPA->pStream = pStream; 933 934 pa_threaded_mainloop_unlock(pThis->pMainLoop); 935 LogFlowFuncLeaveRC(VINF_SUCCESS); 936 return VINF_SUCCESS; 937 958 /* 959 * Convert it to PDM speak. 960 */ 961 rc = drvHostAudioPaToAudioProps(&pCfgAcq->Props, pStreamPA->SampleSpec.format, 962 pStreamPA->SampleSpec.channels, pStreamPA->SampleSpec.rate); 963 if (RT_SUCCESS(rc)) 964 { 965 pStreamPA->pStream = pStream; 966 pa_threaded_mainloop_unlock(pThis->pMainLoop); 967 LogFlowFuncLeaveRC(VINF_SUCCESS); 968 return VINF_SUCCESS; 969 } 970 LogRel(("PulseAudio: Cannot find audio capture format %ld\n", pStreamPA->SampleSpec.format)); 938 971 } while (0); 939 972 … … 952 985 953 986 static int drvHostAudioPaCreateStreamOut(PDRVHOSTPULSEAUDIO pThis, PPULSEAUDIOSTREAM pStreamPA, 954 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 955 { 956 pStreamPA->pDrainOp = NULL; 957 958 pStreamPA->SampleSpec.format = drvHostAudioPaPropsToPulse(&pCfgReq->Props); 959 pStreamPA->SampleSpec.rate = PDMAudioPropsHz(&pCfgReq->Props); 960 pStreamPA->SampleSpec.channels = PDMAudioPropsChannels(&pCfgReq->Props); 961 962 pStreamPA->curLatencyUs = PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize) * RT_US_1MS; 963 964 const uint32_t cbLatency = pa_usec_to_bytes(pStreamPA->curLatencyUs, &pStreamPA->SampleSpec); 965 966 LogRel2(("PulseAudio: Initial output latency is %RU64ms (%RU32 bytes)\n", pStreamPA->curLatencyUs / RT_US_1MS, cbLatency)); 967 968 pStreamPA->BufAttr.tlength = cbLatency; 969 pStreamPA->BufAttr.maxlength = -1; /* Let the PulseAudio server choose the biggest size it can handle. */ 970 pStreamPA->BufAttr.prebuf = cbLatency; 971 pStreamPA->BufAttr.minreq = PDMAudioPropsFramesToBytes(&pCfgReq->Props, pCfgReq->Backend.cFramesPeriod); 972 987 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq, const char *pszName) 988 { 989 Assert(pCfgReq->enmDir == PDMAUDIODIR_OUT); 990 991 pStreamPA->curLatencyUs = PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize) * RT_US_1MS; 992 uint32_t const cbLatency = pa_usec_to_bytes(pStreamPA->curLatencyUs, &pStreamPA->SampleSpec); 993 pStreamPA->BufAttr.tlength = cbLatency; 994 pStreamPA->BufAttr.maxlength = -1; /* Let the PulseAudio server choose the biggest size it can handle. */ 995 pStreamPA->BufAttr.prebuf = cbLatency; 996 pStreamPA->BufAttr.minreq = PDMAudioPropsFramesToBytes(&pCfgReq->Props, pCfgReq->Backend.cFramesPeriod); 997 LogRel2(("PulseAudio: Initial output latency is %RU64 ms (%RU32 bytes)\n", pStreamPA->curLatencyUs / RT_US_1MS, cbLatency)); 973 998 LogFunc(("Requested: BufAttr tlength=%RU32, maxLength=%RU32, minReq=%RU32\n", 974 999 pStreamPA->BufAttr.tlength, pStreamPA->BufAttr.maxlength, pStreamPA->BufAttr.minreq)); 975 1000 976 Assert(pCfgReq->enmDir == PDMAUDIODIR_OUT); 977 978 char szName[256]; 979 RTStrPrintf(szName, sizeof(szName), "VirtualBox %s [%s]", PDMAudioPlaybackDstGetName(pCfgReq->u.enmDst), pThis->szStreamName); 980 981 /* Note that the struct BufAttr is updated to the obtained values after this call! */ 982 int rc = drvHostAudioPaStreamOpen(pThis, pStreamPA, false /* fIn */, szName); 983 if (RT_FAILURE(rc)) 984 return rc; 985 986 rc = drvHostAudioPaToAudioProps(&pCfgAcq->Props, pStreamPA->SampleSpec.format, 987 pStreamPA->SampleSpec.channels, pStreamPA->SampleSpec.rate); 988 if (RT_FAILURE(rc)) 989 { 990 LogRel(("PulseAudio: Cannot find audio output format %ld\n", pStreamPA->SampleSpec.format)); 991 return rc; 992 } 993 994 LogFunc(("Acquired: BufAttr tlength=%RU32, maxLength=%RU32, minReq=%RU32\n", 995 pStreamPA->BufAttr.tlength, pStreamPA->BufAttr.maxlength, pStreamPA->BufAttr.minreq)); 996 997 pCfgAcq->Backend.cFramesPeriod = PDMAUDIOSTREAMCFG_B2F(pCfgAcq, pStreamPA->BufAttr.minreq); 998 pCfgAcq->Backend.cFramesBufferSize = PDMAUDIOSTREAMCFG_B2F(pCfgAcq, pStreamPA->BufAttr.tlength); 999 pCfgAcq->Backend.cFramesPreBuffering = PDMAUDIOSTREAMCFG_B2F(pCfgAcq, pStreamPA->BufAttr.prebuf); 1000 1001 pStreamPA->pDrv = pThis; 1002 1001 int rc = drvHostAudioPaStreamOpen(pThis, pStreamPA, false /* fIn */, pszName, pCfgReq); 1002 if (RT_SUCCESS(rc)) 1003 { 1004 /* Note! BuffAttr contains the acquired values now.*/ 1005 LogFunc(("Acquired: BufAttr tlength=%RU32, maxLength=%RU32, minReq=%RU32\n", 1006 pStreamPA->BufAttr.tlength, pStreamPA->BufAttr.maxlength, pStreamPA->BufAttr.minreq)); 1007 pCfgAcq->Backend.cFramesPeriod = PDMAudioPropsBytesToFrames(&pCfgAcq->Props, pStreamPA->BufAttr.minreq); 1008 pCfgAcq->Backend.cFramesBufferSize = PDMAudioPropsBytesToFrames(&pCfgAcq->Props, pStreamPA->BufAttr.tlength); 1009 pCfgAcq->Backend.cFramesPreBuffering = PDMAudioPropsBytesToFrames(&pCfgAcq->Props, pStreamPA->BufAttr.prebuf); 1010 } 1003 1011 return rc; 1004 1012 } … … 1006 1014 1007 1015 static int drvHostAudioPaCreateStreamIn(PDRVHOSTPULSEAUDIO pThis, PPULSEAUDIOSTREAM pStreamPA, 1008 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 1009 { 1010 pStreamPA->SampleSpec.format = drvHostAudioPaPropsToPulse(&pCfgReq->Props); 1011 pStreamPA->SampleSpec.rate = PDMAudioPropsHz(&pCfgReq->Props); 1012 pStreamPA->SampleSpec.channels = PDMAudioPropsChannels(&pCfgReq->Props); 1013 1014 pStreamPA->BufAttr.fragsize = PDMAudioPropsFramesToBytes(&pCfgReq->Props, pCfgReq->Backend.cFramesPeriod); 1015 pStreamPA->BufAttr.maxlength = -1; /* Let the PulseAudio server choose the biggest size it can handle. */ 1016 1016 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq, const char *pszName) 1017 { 1017 1018 Assert(pCfgReq->enmDir == PDMAUDIODIR_IN); 1018 1019 1019 char szName[256]; 1020 RTStrPrintf(szName, sizeof(szName), "VirtualBox %s [%s]", PDMAudioRecSrcGetName(pCfgReq->u.enmSrc), pThis->szStreamName); 1021 1022 /* Note: Other members of BufAttr are ignored for record streams. */ 1023 int rc = drvHostAudioPaStreamOpen(pThis, pStreamPA, true /* fIn */, szName); 1024 if (RT_FAILURE(rc)) 1025 return rc; 1026 1027 rc = drvHostAudioPaToAudioProps(&pCfgAcq->Props, pStreamPA->SampleSpec.format, 1028 pStreamPA->SampleSpec.channels, pStreamPA->SampleSpec.rate); 1029 if (RT_FAILURE(rc)) 1030 { 1031 LogRel(("PulseAudio: Cannot find audio capture format %ld\n", pStreamPA->SampleSpec.format)); 1032 return rc; 1033 } 1034 1035 pStreamPA->pDrv = pThis; 1036 pStreamPA->pu8PeekBuf = NULL; 1037 1038 pCfgAcq->Backend.cFramesPeriod = PDMAUDIOSTREAMCFG_B2F(pCfgAcq, pStreamPA->BufAttr.fragsize); 1039 pCfgAcq->Backend.cFramesBufferSize = pStreamPA->BufAttr.maxlength != UINT32_MAX /* paranoia */ 1040 ? PDMAUDIOSTREAMCFG_B2F(pCfgAcq, pStreamPA->BufAttr.maxlength) 1041 : pCfgAcq->Backend.cFramesPeriod * 2 /* whatever */; 1042 pCfgAcq->Backend.cFramesPreBuffering = pCfgAcq->Backend.cFramesPeriod; 1043 1044 LogFlowFuncLeaveRC(rc); 1020 pStreamPA->BufAttr.fragsize = PDMAudioPropsFramesToBytes(&pCfgReq->Props, pCfgReq->Backend.cFramesPeriod); 1021 pStreamPA->BufAttr.maxlength = -1; /* Let the PulseAudio server choose the biggest size it can handle. */ 1022 1023 int rc = drvHostAudioPaStreamOpen(pThis, pStreamPA, true /* fIn */, pszName, pCfgAcq); 1024 if (RT_SUCCESS(rc)) 1025 { 1026 /* Note! BuffAttr contains the acquired values now.*/ 1027 pCfgAcq->Backend.cFramesPeriod = PDMAudioPropsBytesToFrames(&pCfgAcq->Props, pStreamPA->BufAttr.fragsize); 1028 pCfgAcq->Backend.cFramesBufferSize = pStreamPA->BufAttr.maxlength != UINT32_MAX /* paranoia */ 1029 ? PDMAudioPropsBytesToFrames(&pCfgAcq->Props, pStreamPA->BufAttr.maxlength) 1030 : pCfgAcq->Backend.cFramesPeriod * 2 /* whatever */; 1031 pCfgAcq->Backend.cFramesPreBuffering = pCfgAcq->Backend.cFramesPeriod; 1032 } 1045 1033 return rc; 1046 1034 } … … 1058 1046 AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER); 1059 1047 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER); 1060 1061 1048 AssertReturn(pCfgReq->enmDir == PDMAUDIODIR_IN || pCfgReq->enmDir == PDMAUDIODIR_OUT, VERR_INVALID_PARAMETER); 1062 1049 int rc; 1063 if (pCfgReq->enmDir == PDMAUDIODIR_IN) 1064 rc = drvHostAudioPaCreateStreamIn (pThis, pStreamPA, pCfgReq, pCfgAcq); 1065 else if (pCfgReq->enmDir == PDMAUDIODIR_OUT) 1066 rc = drvHostAudioPaCreateStreamOut(pThis, pStreamPA, pCfgReq, pCfgAcq); 1050 1051 /* 1052 * Common prep bits. 1053 */ 1054 char szName[256]; 1055 RTStrPrintf(szName, sizeof(szName), "VirtualBox %s [%s]", 1056 pCfgReq->enmDir == PDMAUDIODIR_IN 1057 ? PDMAudioRecSrcGetName(pCfgReq->u.enmSrc) : PDMAudioPlaybackDstGetName(pCfgReq->u.enmDst), 1058 pThis->szStreamName); 1059 1060 pStreamPA->pDrv = pThis; 1061 pStreamPA->pDrainOp = NULL; 1062 pStreamPA->pu8PeekBuf = NULL; 1063 pStreamPA->SampleSpec.rate = PDMAudioPropsHz(&pCfgReq->Props); 1064 pStreamPA->SampleSpec.channels = PDMAudioPropsChannels(&pCfgReq->Props); 1065 pStreamPA->SampleSpec.format = drvHostAudioPaPropsToPulse(&pCfgReq->Props); 1066 1067 LogFunc(("Opening '%s', rate=%dHz, channels=%d, format=%s\n", szName, pStreamPA->SampleSpec.rate, 1068 pStreamPA->SampleSpec.channels, pa_sample_format_to_string(pStreamPA->SampleSpec.format))); 1069 1070 if (pa_sample_spec_valid(&pStreamPA->SampleSpec)) 1071 { 1072 /* 1073 * Do some direction specific buffer config and call drvHostAudioPaStreamOpen. 1074 */ 1075 if (pCfgReq->enmDir == PDMAUDIODIR_IN) 1076 rc = drvHostAudioPaCreateStreamIn (pThis, pStreamPA, pCfgReq, pCfgAcq, szName); 1077 else 1078 rc = drvHostAudioPaCreateStreamOut(pThis, pStreamPA, pCfgReq, pCfgAcq, szName); 1079 1080 PDMAudioStrmCfgCopy(&pStreamPA->Cfg, pCfgAcq); 1081 } 1067 1082 else 1068 AssertFailedReturn(VERR_NOT_IMPLEMENTED); 1069 1070 if (RT_SUCCESS(rc)) 1071 { 1072 pStreamPA->pCfg = PDMAudioStrmCfgDup(pCfgAcq); 1073 if (!pStreamPA->pCfg) 1074 rc = VERR_NO_MEMORY; 1075 } 1076 1083 { 1084 LogRel(("PulseAudio: Unsupported sample specification for stream '%s'\n", szName)); 1085 rc = VERR_AUDIO_STREAM_COULD_NOT_CREATE; 1086 } 1087 1088 LogFlowFuncLeaveRC(rc); 1077 1089 return rc; 1078 1090 } … … 1105 1117 1106 1118 pa_threaded_mainloop_unlock(pThis->pMainLoop); 1107 }1108 1109 if (pStreamPA->pCfg)1110 {1111 PDMAudioStrmCfgFree(pStreamPA->pCfg);1112 pStreamPA->pCfg = NULL;1113 1119 } 1114 1120 … … 1246 1252 AssertPtrReturn(pStreamPA, VERR_INVALID_POINTER); 1247 1253 1248 if (!pStreamPA->pCfg) /* Not (yet) configured? Skip. */1249 return VINF_SUCCESS;1250 1251 1254 int rc; 1252 if (pStreamPA-> pCfg->enmDir == PDMAUDIODIR_IN)1255 if (pStreamPA->Cfg.enmDir == PDMAUDIODIR_IN) 1253 1256 rc = drvHostAudioPaStreamControlIn (pThis, pStreamPA, enmStreamCmd); 1254 else if (pStreamPA-> pCfg->enmDir == PDMAUDIODIR_OUT)1257 else if (pStreamPA->Cfg.enmDir == PDMAUDIODIR_OUT) 1255 1258 rc = drvHostAudioPaStreamControlOut(pThis, pStreamPA, enmStreamCmd); 1256 1259 else … … 1269 1272 if (PA_STREAM_IS_GOOD(pa_stream_get_state(pStreamPA->pStream))) 1270 1273 { 1271 if (pStreamPA-> pCfg->enmDir == PDMAUDIODIR_IN)1274 if (pStreamPA->Cfg.enmDir == PDMAUDIODIR_IN) 1272 1275 { 1273 1276 cbAvail = (uint32_t)pa_stream_readable_size(pStreamPA->pStream); 1274 1277 Log3Func(("cbReadable=%RU32\n", cbAvail)); 1275 1278 } 1276 else if (pStreamPA-> pCfg->enmDir == PDMAUDIODIR_OUT)1279 else if (pStreamPA->Cfg.enmDir == PDMAUDIODIR_OUT) 1277 1280 { 1278 1281 size_t cbWritable = pa_stream_writable_size(pStreamPA->pStream);
Note:
See TracChangeset
for help on using the changeset viewer.

