Changeset 89423 in vbox for trunk/src/VBox
- Timestamp:
- Jun 1, 2021 10:14:16 AM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 144776
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvHostAudioPulseAudio.cpp
r89258 r89423 141 141 /** Pointer to opaque PulseAudio stream. */ 142 142 pa_stream *pStream; 143 /** Pulse sample format and attribute specification. */144 pa_sample_spec SampleSpec;145 /** Pulse playback and buffer metrics. */146 pa_buffer_attr BufAttr;147 143 /** Input: Pointer to Pulse sample peek buffer. */ 148 144 const uint8_t *pbPeekBuf; … … 175 171 uint32_t cUnderflows; 176 172 #endif 173 /** Pulse sample format and attribute specification. */ 174 pa_sample_spec SampleSpec; 175 /** Channel map. */ 176 pa_channel_map ChannelMap; 177 /** Pulse playback and buffer metrics. */ 178 pa_buffer_attr BufAttr; 177 179 } PULSEAUDIOSTREAM; 178 180 /** Pointer to pulse audio stream data. */ … … 905 907 * Create the stream. 906 908 */ 907 pa_stream *pStream = pa_stream_new(pThis->pContext, pszName, &pStreamPA->SampleSpec, NULL /* pa_channel_map */);909 pa_stream *pStream = pa_stream_new(pThis->pContext, pszName, &pStreamPA->SampleSpec, &pStreamPA->ChannelMap); 908 910 if (!pStream) 909 911 { … … 1022 1024 1023 1025 /** 1026 * Translates a PDM channel ID to a PA channel position. 1027 * 1028 * @returns PA channel position, INVALID if no mapping found. 1029 */ 1030 static pa_channel_position_t drvHstAudPaConvertChannelId(uint8_t idChannel) 1031 { 1032 switch (idChannel) 1033 { 1034 case PDMAUDIOCHANNELID_FRONT_LEFT: return PA_CHANNEL_POSITION_FRONT_LEFT; 1035 case PDMAUDIOCHANNELID_FRONT_RIGHT: return PA_CHANNEL_POSITION_FRONT_RIGHT; 1036 case PDMAUDIOCHANNELID_FRONT_CENTER: return PA_CHANNEL_POSITION_FRONT_CENTER; 1037 case PDMAUDIOCHANNELID_LFE: return PA_CHANNEL_POSITION_LFE; 1038 case PDMAUDIOCHANNELID_REAR_LEFT: return PA_CHANNEL_POSITION_REAR_LEFT; 1039 case PDMAUDIOCHANNELID_REAR_RIGHT: return PA_CHANNEL_POSITION_REAR_RIGHT; 1040 case PDMAUDIOCHANNELID_FRONT_LEFT_OF_CENTER: return PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER; 1041 case PDMAUDIOCHANNELID_FRONT_RIGHT_OF_CENTER: return PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER; 1042 case PDMAUDIOCHANNELID_REAR_CENTER: return PA_CHANNEL_POSITION_REAR_CENTER; 1043 case PDMAUDIOCHANNELID_SIDE_LEFT: return PA_CHANNEL_POSITION_SIDE_LEFT; 1044 case PDMAUDIOCHANNELID_SIDE_RIGHT: return PA_CHANNEL_POSITION_SIDE_RIGHT; 1045 case PDMAUDIOCHANNELID_TOP_CENTER: return PA_CHANNEL_POSITION_TOP_CENTER; 1046 case PDMAUDIOCHANNELID_FRONT_LEFT_HEIGHT: return PA_CHANNEL_POSITION_TOP_FRONT_LEFT; 1047 case PDMAUDIOCHANNELID_FRONT_CENTER_HEIGHT: return PA_CHANNEL_POSITION_TOP_FRONT_CENTER; 1048 case PDMAUDIOCHANNELID_FRONT_RIGHT_HEIGHT: return PA_CHANNEL_POSITION_TOP_FRONT_RIGHT; 1049 case PDMAUDIOCHANNELID_REAR_LEFT_HEIGHT: return PA_CHANNEL_POSITION_TOP_REAR_LEFT; 1050 case PDMAUDIOCHANNELID_REAR_CENTER_HEIGHT: return PA_CHANNEL_POSITION_TOP_REAR_CENTER; 1051 case PDMAUDIOCHANNELID_REAR_RIGHT_HEIGHT: return PA_CHANNEL_POSITION_TOP_REAR_RIGHT; 1052 default: return PA_CHANNEL_POSITION_INVALID; 1053 } 1054 } 1055 1056 1057 /** 1058 * Translates a PA channel position to a PDM channel ID. 1059 * 1060 * @returns PDM channel ID, UNKNOWN if no mapping found. 1061 */ 1062 static PDMAUDIOCHANNELID drvHstAudPaConvertChannelPos(pa_channel_position_t enmChannelPos) 1063 { 1064 switch (enmChannelPos) 1065 { 1066 case PA_CHANNEL_POSITION_INVALID: return PDMAUDIOCHANNELID_INVALID; 1067 case PA_CHANNEL_POSITION_MONO: return PDMAUDIOCHANNELID_MONO; 1068 case PA_CHANNEL_POSITION_FRONT_LEFT: return PDMAUDIOCHANNELID_FRONT_LEFT; 1069 case PA_CHANNEL_POSITION_FRONT_RIGHT: return PDMAUDIOCHANNELID_FRONT_RIGHT; 1070 case PA_CHANNEL_POSITION_FRONT_CENTER: return PDMAUDIOCHANNELID_FRONT_CENTER; 1071 case PA_CHANNEL_POSITION_LFE: return PDMAUDIOCHANNELID_LFE; 1072 case PA_CHANNEL_POSITION_REAR_LEFT: return PDMAUDIOCHANNELID_REAR_LEFT; 1073 case PA_CHANNEL_POSITION_REAR_RIGHT: return PDMAUDIOCHANNELID_REAR_RIGHT; 1074 case PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER: return PDMAUDIOCHANNELID_FRONT_LEFT_OF_CENTER; 1075 case PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER: return PDMAUDIOCHANNELID_FRONT_RIGHT_OF_CENTER; 1076 case PA_CHANNEL_POSITION_REAR_CENTER: return PDMAUDIOCHANNELID_REAR_CENTER; 1077 case PA_CHANNEL_POSITION_SIDE_LEFT: return PDMAUDIOCHANNELID_SIDE_LEFT; 1078 case PA_CHANNEL_POSITION_SIDE_RIGHT: return PDMAUDIOCHANNELID_SIDE_RIGHT; 1079 case PA_CHANNEL_POSITION_TOP_CENTER: return PDMAUDIOCHANNELID_TOP_CENTER; 1080 case PA_CHANNEL_POSITION_TOP_FRONT_LEFT: return PDMAUDIOCHANNELID_FRONT_LEFT_HEIGHT; 1081 case PA_CHANNEL_POSITION_TOP_FRONT_CENTER: return PDMAUDIOCHANNELID_FRONT_CENTER_HEIGHT; 1082 case PA_CHANNEL_POSITION_TOP_FRONT_RIGHT: return PDMAUDIOCHANNELID_FRONT_RIGHT_HEIGHT; 1083 case PA_CHANNEL_POSITION_TOP_REAR_LEFT: return PDMAUDIOCHANNELID_REAR_LEFT_HEIGHT; 1084 case PA_CHANNEL_POSITION_TOP_REAR_CENTER: return PDMAUDIOCHANNELID_REAR_CENTER_HEIGHT; 1085 case PA_CHANNEL_POSITION_TOP_REAR_RIGHT: return PDMAUDIOCHANNELID_REAR_RIGHT_HEIGHT; 1086 default: return PDMAUDIOCHANNELID_UNKNOWN; 1087 } 1088 } 1089 1090 1091 1092 /** 1024 1093 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate} 1025 1094 */ … … 1049 1118 pStreamPA->SampleSpec.format = drvHostAudioPaPropsToPulse(&pCfgReq->Props); 1050 1119 1051 LogFunc(("Opening '%s', rate=%dHz, channels=%d, format=%s\n", szName, pStreamPA->SampleSpec.rate, 1052 pStreamPA->SampleSpec.channels, pa_sample_format_to_string(pStreamPA->SampleSpec.format))); 1120 /* 1121 * Initialize the channelmap. This may change the channel count. 1122 */ 1123 AssertCompile(RT_ELEMENTS(pStreamPA->ChannelMap.map) >= PDMAUDIO_MAX_CHANNELS); 1124 uint8_t const cSrcChannels = pStreamPA->ChannelMap.channels = PDMAudioPropsChannels(&pCfgReq->Props); 1125 uintptr_t iDst = 0; 1126 if (cSrcChannels == 1 && pCfgReq->Props.aidChannels[0] == PDMAUDIOCHANNELID_MONO) 1127 pStreamPA->ChannelMap.map[iDst++] = PA_CHANNEL_POSITION_MONO; 1128 else 1129 { 1130 uintptr_t iSrc; 1131 for (iSrc = iDst = 0; iSrc < cSrcChannels; iSrc++) 1132 { 1133 pStreamPA->ChannelMap.map[iDst] = drvHstAudPaConvertChannelId(pCfgReq->Props.aidChannels[iSrc]); 1134 if (pStreamPA->ChannelMap.map[iDst] != PA_CHANNEL_POSITION_INVALID) 1135 iDst++; 1136 else 1137 { 1138 LogRel2(("PulseAudio: Dropping channel #%u (%d/%s)\n", iSrc, pCfgReq->Props.aidChannels[iSrc], 1139 PDMAudioChannelIdGetName((PDMAUDIOCHANNELID)pCfgReq->Props.aidChannels[iSrc]))); 1140 pStreamPA->ChannelMap.channels--; 1141 pStreamPA->SampleSpec.channels--; 1142 PDMAudioPropsSetChannels(&pCfgAcq->Props, pStreamPA->SampleSpec.channels); 1143 } 1144 } 1145 Assert(iDst == pStreamPA->ChannelMap.channels); 1146 } 1147 while (iDst < RT_ELEMENTS(pStreamPA->ChannelMap.map)) 1148 pStreamPA->ChannelMap.map[iDst++] = PA_CHANNEL_POSITION_INVALID; 1149 1150 LogFunc(("Opening '%s', rate=%dHz, channels=%d (%d), format=%s\n", szName, pStreamPA->SampleSpec.rate, 1151 pStreamPA->SampleSpec.channels, cSrcChannels, pa_sample_format_to_string(pStreamPA->SampleSpec.format))); 1053 1152 1054 1153 if (pa_sample_spec_valid(&pStreamPA->SampleSpec)) … … 1064 1163 if (pCfgReq->enmDir == PDMAUDIODIR_IN) 1065 1164 { 1066 pStreamPA->BufAttr.fragsize = PDMAudioPropsFramesToBytes(&pCfg Req->Props, pCfgReq->Backend.cFramesPeriod);1165 pStreamPA->BufAttr.fragsize = PDMAudioPropsFramesToBytes(&pCfgAcq->Props, pCfgReq->Backend.cFramesPeriod); 1067 1166 LogFunc(("Requesting: BufAttr: fragsize=%RU32\n", pStreamPA->BufAttr.fragsize)); 1068 1167 /* (rlength, minreq and prebuf are playback only) */ … … 1070 1169 else 1071 1170 { 1072 pStreamPA->cUsLatency = PDMAudioPropsFramesToMicro(&pCfg Req->Props, pCfgReq->Backend.cFramesBufferSize);1171 pStreamPA->cUsLatency = PDMAudioPropsFramesToMicro(&pCfgAcq->Props, pCfgReq->Backend.cFramesBufferSize); 1073 1172 pStreamPA->BufAttr.tlength = pa_usec_to_bytes(pStreamPA->cUsLatency, &pStreamPA->SampleSpec); 1074 pStreamPA->BufAttr.minreq = PDMAudioPropsFramesToBytes(&pCfg Req->Props, pCfgReq->Backend.cFramesPeriod);1075 pStreamPA->BufAttr.prebuf = pa_usec_to_bytes(PDMAudioPropsFramesToMicro(&pCfg Req->Props,1173 pStreamPA->BufAttr.minreq = PDMAudioPropsFramesToBytes(&pCfgAcq->Props, pCfgReq->Backend.cFramesPeriod); 1174 pStreamPA->BufAttr.prebuf = pa_usec_to_bytes(PDMAudioPropsFramesToMicro(&pCfgAcq->Props, 1076 1175 pCfgReq->Backend.cFramesPreBuffering), 1077 1176 &pStreamPA->SampleSpec); … … 1111 1210 / RT_MAX(pCfgReq->Backend.cFramesBufferSize, 1); 1112 1211 } 1212 1213 /* 1214 * Translate back the channel mapping. 1215 */ 1216 for (iDst = 0; iDst < pStreamPA->ChannelMap.channels; iDst++) 1217 pCfgReq->Props.aidChannels[iDst] = drvHstAudPaConvertChannelPos(pStreamPA->ChannelMap.map[iDst]); 1218 while (iDst < RT_ELEMENTS(pCfgReq->Props.aidChannels)) 1219 pCfgReq->Props.aidChannels[iDst++] = PDMAUDIOCHANNELID_INVALID; 1220 1113 1221 PDMAudioStrmCfgCopy(&pStreamPA->Cfg, pCfgAcq); 1114 1222 }
Note:
See TracChangeset
for help on using the changeset viewer.