Changeset 89335 in vbox for trunk/src/VBox
- Timestamp:
- May 28, 2021 8:44:41 AM (4 years ago)
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp
r89334 r89335 150 150 if (pMixBuf->cFrames) 151 151 RT_BZERO(pMixBuf->pFrames, pMixBuf->cFrames * sizeof(PDMAUDIOFRAME)); 152 }153 154 /**155 * Clears (zeroes) the buffer by a certain amount of (used) frames and156 * keeps track to eventually assigned children buffers.157 *158 * @param pMixBuf Mixing buffer to clear.159 * @param cFramesToClear Number of audio frames to clear.160 */161 void AudioMixBufFinish(PAUDIOMIXBUF pMixBuf, uint32_t cFramesToClear)162 {163 AUDMIXBUF_LOG(("cFramesToClear=%RU32\n", cFramesToClear));164 AUDMIXBUF_LOG(("%s: offRead=%RU32, cUsed=%RU32\n",165 pMixBuf->pszName, pMixBuf->offRead, pMixBuf->cUsed));166 167 AssertStmt(cFramesToClear <= pMixBuf->cFrames, cFramesToClear = pMixBuf->cFrames);168 169 /** @todo r=bird: waste of time? */170 uint32_t cClearOff;171 uint32_t cClearLen;172 173 /* Clear end of buffer (wrap around). */174 if (cFramesToClear > pMixBuf->offRead)175 {176 cClearOff = pMixBuf->cFrames - (cFramesToClear - pMixBuf->offRead);177 cClearLen = pMixBuf->cFrames - cClearOff;178 179 AUDMIXBUF_LOG(("Clearing1: %RU32 - %RU32\n", cClearOff, cClearOff + cClearLen));180 181 RT_BZERO(pMixBuf->pFrames + cClearOff, cClearLen * sizeof(PDMAUDIOFRAME));182 183 Assert(cFramesToClear >= cClearLen);184 cFramesToClear -= cClearLen;185 }186 187 /* Clear beginning of buffer. */188 if ( cFramesToClear189 && pMixBuf->offRead)190 {191 Assert(pMixBuf->offRead >= cFramesToClear);192 193 cClearOff = pMixBuf->offRead - cFramesToClear;194 cClearLen = cFramesToClear;195 196 Assert(cClearOff + cClearLen <= pMixBuf->cFrames);197 198 AUDMIXBUF_LOG(("Clearing2: %RU32 - %RU32\n", cClearOff, cClearOff + cClearLen));199 200 RT_BZERO(pMixBuf->pFrames + cClearOff, cClearLen * sizeof(PDMAUDIOFRAME));201 }202 152 } 203 153 … … 1210 1160 } 1211 1161 1212 /**1213 * Reads audio frames. The audio format of the mixing buffer will be used.1214 *1215 * @returns VBox status code.1216 * @param pMixBuf Mixing buffer to read audio frames from.1217 * @param pvBuf Pointer to buffer to write output to.1218 * @param cbBuf Size (in bytes) of buffer to write to.1219 * @param pcAcquiredFrames Where to return the number of frames in1220 * the block that was acquired.1221 */1222 int AudioMixBufAcquireReadBlock(PAUDIOMIXBUF pMixBuf, void *pvBuf, uint32_t cbBuf, uint32_t *pcAcquiredFrames)1223 {1224 return AudioMixBufAcquireReadBlockEx(pMixBuf, &pMixBuf->Props, pvBuf, cbBuf, pcAcquiredFrames);1225 }1226 1227 /**1228 * Reads audio frames in a specific audio format.1229 *1230 * If the audio format of the mixing buffer and the requested audio format do1231 * not match the output will be converted accordingly.1232 *1233 * @returns VBox status code.1234 * @param pMixBuf Mixing buffer to read audio frames from.1235 * @param pDstProps The target format.1236 * @param pvBuf Pointer to buffer to write output to.1237 * @param cbBuf Size (in bytes) of buffer to write to.1238 * @param pcAcquiredFrames Where to return the number of frames in1239 * the block that was acquired.1240 */1241 int AudioMixBufAcquireReadBlockEx(PAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pDstProps,1242 void *pvBuf, uint32_t cbBuf, uint32_t *pcAcquiredFrames)1243 {1244 AssertPtrReturn(pMixBuf, VERR_INVALID_POINTER);1245 AssertReturn(cbBuf, VERR_INVALID_PARAMETER);1246 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);1247 AssertPtrReturn(pcAcquiredFrames, VERR_INVALID_POINTER);1248 1249 /* Make sure that we at least have space for a full audio frame. */1250 AssertReturn(AUDIOMIXBUF_B2F(pMixBuf, cbBuf), VERR_INVALID_PARAMETER);1251 1252 uint32_t cFramesToRead = RT_MIN(pMixBuf->cUsed, AUDIOMIXBUF_B2F(pMixBuf, cbBuf));1253 1254 #ifdef AUDMIXBUF_LOG_ENABLED1255 char szTmp1[PDMAUDIOPROPSTOSTRING_MAX], szTmp2[PDMAUDIOPROPSTOSTRING_MAX];1256 #endif1257 AUDMIXBUF_LOG(("%s: cbBuf=%RU32 (%RU32 frames), cFramesToRead=%RU32, MixBuf=%s, pDstProps=%s\n",1258 pMixBuf->pszName, cbBuf, AUDIOMIXBUF_B2F(pMixBuf, cbBuf), cFramesToRead,1259 PDMAudioPropsToString(&pMixBuf->Props, szTmp1, sizeof(szTmp1)),1260 PDMAudioPropsToString(pDstProps, szTmp2, sizeof(szTmp2))));1261 if (!cFramesToRead)1262 {1263 #ifdef DEBUG1264 audioMixBufDbgPrintInternal(pMixBuf, __FUNCTION__);1265 #endif1266 *pcAcquiredFrames = 0;1267 return VINF_SUCCESS;1268 }1269 1270 PFNAUDIOMIXBUFCONVTO pfnConvTo;1271 if (PDMAudioPropsAreEqual(&pMixBuf->Props, pDstProps))1272 pfnConvTo = pMixBuf->pfnConvTo;1273 else1274 pfnConvTo = audioMixBufConvToLookup(pDstProps);1275 AssertReturn(pfnConvTo, VERR_NOT_SUPPORTED);1276 1277 cFramesToRead = RT_MIN(cFramesToRead, pMixBuf->cFrames - pMixBuf->offRead);1278 if (cFramesToRead)1279 {1280 AUDMIXBUFCONVOPTS convOpts;1281 RT_ZERO(convOpts);1282 convOpts.cFrames = cFramesToRead;1283 1284 AUDMIXBUF_LOG(("cFramesToRead=%RU32\n", cFramesToRead));1285 1286 pfnConvTo(pvBuf, pMixBuf->pFrames + pMixBuf->offRead, &convOpts);1287 1288 #ifdef AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA1289 RTFILE fh;1290 int rc2 = RTFileOpen(&fh, AUDIOMIXBUF_DEBUG_DUMP_PCM_DATA_PATH "mixbuf_readcirc.pcm",1291 RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);1292 if (RT_SUCCESS(rc2))1293 {1294 RTFileWrite(fh, pvBuf, AUDIOMIXBUF_F2B(pMixBuf, cFramesToRead), NULL);1295 RTFileClose(fh);1296 }1297 #endif1298 }1299 1300 *pcAcquiredFrames = cFramesToRead;1301 1302 #ifdef DEBUG1303 audioMixBufDbgValidate(pMixBuf);1304 #endif1305 1306 AUDMIXBUF_LOG(("*pcAcquiredFrames=%RU32 (%RU32 bytes)\n", cFramesToRead, AUDIOMIXBUF_F2B(pMixBuf, cFramesToRead)));1307 return VINF_SUCCESS;1308 }1309 1310 /**1311 * Releases a formerly acquired read block.1312 *1313 * @param pMixBuf Mixing buffer to release acquired read block for.1314 * @param cFrames The number of frames to release. (Can be less than the1315 * acquired count.)1316 */1317 void AudioMixBufReleaseReadBlock(PAUDIOMIXBUF pMixBuf, uint32_t cFrames)1318 {1319 AssertPtrReturnVoid(pMixBuf);1320 1321 if (cFrames)1322 {1323 AssertStmt(pMixBuf->cUsed >= cFrames, cFrames = pMixBuf->cUsed);1324 pMixBuf->offRead = (pMixBuf->offRead + cFrames) % pMixBuf->cFrames;1325 pMixBuf->cUsed -= cFrames;1326 }1327 }1328 1162 1329 1163 /** -
trunk/src/VBox/Devices/Audio/AudioMixBuffer.h
r89333 r89335 276 276 277 277 void AudioMixBufClear(PAUDIOMIXBUF pMixBuf); 278 void AudioMixBufFinish(PAUDIOMIXBUF pMixBuf, uint32_t cFramesToClear);279 278 uint32_t AudioMixBufFree(PAUDIOMIXBUF pMixBuf); 280 279 uint32_t AudioMixBufFreeBytes(PAUDIOMIXBUF pMixBuf); … … 283 282 uint32_t AudioMixBufUsed(PAUDIOMIXBUF pMixBuf); 284 283 uint32_t AudioMixBufUsedBytes(PAUDIOMIXBUF pMixBuf); 285 int AudioMixBufAcquireReadBlock(PAUDIOMIXBUF pMixBuf, void *pvBuf, uint32_t cbBuf, uint32_t *pcAcquiredFrames);286 int AudioMixBufAcquireReadBlockEx(PAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pDstProps,287 void *pvBuf, uint32_t cbBuf, uint32_t *pcAcquiredFrames);288 void AudioMixBufReleaseReadBlock(PAUDIOMIXBUF pMixBuf, uint32_t cFrames);289 284 uint32_t AudioMixBufReadPos(PAUDIOMIXBUF pMixBuf); 290 285 void AudioMixBufReset(PAUDIOMIXBUF pMixBuf); -
trunk/src/VBox/Devices/Audio/testcase/tstAudioMixBuffer.cpp
r89333 r89335 215 215 RTTESTI_CHECK(AUDIOMIXBUF_F2B(&mb, AudioMixBufFree(&mb)) == AudioMixBufFreeBytes(&mb)); 216 216 217 AUDIOMIXBUFWRITESTATE WrState; 218 RTTESTI_CHECK_RC(AudioMixBufInitWriteState(&mb, &WrState, &config), VINF_SUCCESS); 217 AUDIOMIXBUFWRITESTATE WriteState; 218 RTTESTI_CHECK_RC(AudioMixBufInitWriteState(&mb, &WriteState, &config), VINF_SUCCESS); 219 220 AUDIOMIXBUFPEEKSTATE PeekState; 221 RTTESTI_CHECK_RC(AudioMixBufInitPeekState(&mb, &PeekState, &config), VINF_SUCCESS); 219 222 220 223 /* … … 227 230 RTTESTI_CHECK(AudioMixBufUsed(&mb) == 0); 228 231 229 AudioMixBufWrite(&mb, &Wr State, &aFrames16, sizeof(aFrames16), 0 /*offDstFrame*/, cBufSize / 4, &cFramesWritten);232 AudioMixBufWrite(&mb, &WriteState, &aFrames16, sizeof(aFrames16), 0 /*offDstFrame*/, cBufSize / 4, &cFramesWritten); 230 233 RTTESTI_CHECK(cFramesWritten == 1 /* Frames */); 231 234 RTTESTI_CHECK(AudioMixBufUsed(&mb) == 0); … … 235 238 RTTESTI_CHECK(AudioMixBufWritePos(&mb) == 1); 236 239 237 AudioMixBufWrite(&mb, &Wr State, &aFrames32, sizeof(aFrames32), 0 /*offDstFrame*/, cBufSize / 4, &cFramesWritten);240 AudioMixBufWrite(&mb, &WriteState, &aFrames32, sizeof(aFrames32), 0 /*offDstFrame*/, cBufSize / 4, &cFramesWritten); 238 241 RTTESTI_CHECK(cFramesWritten == 2 /* Frames */); 239 242 AudioMixBufCommit(&mb, cFramesWritten); … … 253 256 uint16_t *paSamples = (uint16_t *)RTMemAlloc(cbSamples); 254 257 RTTESTI_CHECK_RETV(paSamples); 255 AudioMixBufWrite(&mb, &Wr State, paSamples, cbSamples, 0 /*offDstFrame*/, cBufSize, &cFramesWritten);258 AudioMixBufWrite(&mb, &WriteState, paSamples, cbSamples, 0 /*offDstFrame*/, cBufSize, &cFramesWritten); 256 259 RTTESTI_CHECK(cFramesWritten == cBufSize); 257 260 AudioMixBufCommit(&mb, cFramesWritten); … … 263 266 264 267 /* 265 * Circular writes.268 * Writes and reads (used to be circular). 266 269 */ 267 270 AudioMixBufReset(&mb); … … 272 275 for (uint32_t i = 0; i < cToWrite; i++) 273 276 { 274 AudioMixBufWrite(&mb, &Wr State, &aFrames16[0], sizeof(aFrames16), 0 /*offDstFrame*/, 1, &cFramesWritten);277 AudioMixBufWrite(&mb, &WriteState, &aFrames16[0], sizeof(aFrames16), 0 /*offDstFrame*/, 1, &cFramesWritten); 275 278 RTTESTI_CHECK(cFramesWritten == 1); 276 279 AudioMixBufCommit(&mb, cFramesWritten); … … 281 284 RTTESTI_CHECK(AudioMixBufUsed(&mb) == cToWrite + cFramesWrittenAbs /* + last absolute write */); 282 285 283 AudioMixBufWrite(&mb, &Wr State, &aFrames16[0], sizeof(aFrames16), 0 /*offDstFrame*/, 1, &cFramesWritten);286 AudioMixBufWrite(&mb, &WriteState, &aFrames16[0], sizeof(aFrames16), 0 /*offDstFrame*/, 1, &cFramesWritten); 284 287 RTTESTI_CHECK(cFramesWritten == 1); 285 288 AudioMixBufCommit(&mb, cFramesWritten); … … 288 291 RTTESTI_CHECK(AudioMixBufUsed(&mb) == cBufSize); 289 292 290 /* Circular reads. */ 293 /* Reads. */ 294 RTTESTI_CHECK(AudioMixBufReadPos(&mb) == 0); 295 uint32_t cbRead; 296 uint16_t aFrames16Buf[RT_ELEMENTS(aFrames16)]; 291 297 uint32_t cToRead = AudioMixBufSize(&mb) - cFramesWrittenAbs - 1; 292 298 for (uint32_t i = 0; i < cToRead; i++) 293 299 { 294 RTTESTI_CHECK_RC_OK(AudioMixBufAcquireReadBlock(&mb, &aFrames16, sizeof(aFrames16), &cFramesRead));300 AudioMixBufPeek(&mb, 0 /*offSrcFrame*/, 1, &cFramesRead, &PeekState, aFrames16Buf, sizeof(aFrames16Buf), &cbRead); 295 301 RTTESTI_CHECK(cFramesRead == 1); 296 AudioMixBufReleaseReadBlock(&mb, cFramesRead); 297 AudioMixBufFinish(&mb, cFramesRead); 302 RTTESTI_CHECK(cbRead == sizeof(aFrames16Buf)); 303 AudioMixBufAdvance(&mb, cFramesRead); 304 RTTESTI_CHECK(AudioMixBufReadPos(&mb) == i + 1); 298 305 } 299 306 RTTESTI_CHECK(!AudioMixBufIsEmpty(&mb)); … … 302 309 RTTESTI_CHECK(AudioMixBufUsed(&mb) == cBufSize - cToRead); 303 310 304 RTTESTI_CHECK_RC_OK(AudioMixBufAcquireReadBlock(&mb, &aFrames16, sizeof(aFrames16), &cFramesRead));311 AudioMixBufPeek(&mb, 0 /*offSrcFrame*/, 1, &cFramesRead, &PeekState, aFrames16Buf, sizeof(aFrames16Buf), &cbRead); 305 312 RTTESTI_CHECK(cFramesRead == 1); 306 AudioMixBufReleaseReadBlock(&mb, cFramesRead);307 AudioMixBuf Finish(&mb, cFramesRead);313 RTTESTI_CHECK(cbRead == sizeof(aFrames16Buf)); 314 AudioMixBufAdvance(&mb, cFramesRead); 308 315 RTTESTI_CHECK(AudioMixBufFree(&mb) == cBufSize - cFramesWrittenAbs); 309 316 RTTESTI_CHECK(AudioMixBufFreeBytes(&mb) == AUDIOMIXBUF_F2B(&mb, cBufSize - cFramesWrittenAbs)); 310 317 RTTESTI_CHECK(AudioMixBufUsed(&mb) == cFramesWrittenAbs); 318 RTTESTI_CHECK(AudioMixBufReadPos(&mb) == 0); 311 319 312 320 AudioMixBufDestroy(&mb);
Note:
See TracChangeset
for help on using the changeset viewer.