Changeset 89661 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Jun 13, 2021 11:08:07 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 145106
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
r89640 r89661 304 304 /** 305 305 * Buffer Descriptor List Entry (BDLE). 306 * 307 * (See section 3.2.1 in Intel document number 252751-001, or section 1.2.2.1 in 308 * Intel document number 302349-003.) 306 309 */ 307 310 typedef struct AC97BDLE … … 319 322 /** 320 323 * Bus master register set for an audio stream. 324 * 325 * (See section 16.2 in Intel document 301473-002, or section 2.2 in Intel 326 * document 302349-003.) 321 327 */ 322 328 typedef struct AC97BMREGS … … 326 332 uint8_t lvi; /**< rw 0, Last valid index. */ 327 333 uint16_t sr; /**< rw 1, Status register. */ 328 uint16_t picb; /**< ro 0, Position in current buffer ( in samples). */334 uint16_t picb; /**< ro 0, Position in current buffer (samples left to process). */ 329 335 uint8_t piv; /**< ro 0, Prefetched index value. */ 330 336 uint8_t cr; /**< rw 0, Control register. */ … … 1265 1271 PAC97STREAM pStream, PAC97STREAMR3 pStreamCC) 1266 1272 { 1267 int rc2; 1268 PAUDMIXSINK pSink = ichac97R3IndexToSink(pThisCC, pStream->u8SD); 1273 /* 1274 * Make sure we're running and got an active mixer sink. 1275 */ 1276 PAUDMIXSINK pSink = ichac97R3IndexToSink(pThisCC, pStream->u8SD); /** @todo caller will need + check this too afterwards... */ 1269 1277 AssertPtr(pSink); 1270 if (AudioMixerSinkIsActive(pSink)) 1271 { 1272 if (pStreamCC->State.Cfg.enmDir == PDMAUDIODIR_OUT) /* Output (SDO). */ 1278 if (RT_LIKELY(AudioMixerSinkIsActive(pSink))) 1279 { /* likely */ } 1280 else 1281 return; 1282 1283 int rc2; 1284 1285 /* 1286 * Output streams (SDO). 1287 */ 1288 if (pStreamCC->State.Cfg.enmDir == PDMAUDIODIR_OUT) 1289 { 1290 uint32_t cbStreamFree = ichac97R3StreamGetFree(pStreamCC); 1291 if (cbStreamFree) 1292 { /* likely */ } 1293 else 1273 1294 { 1274 uint32_t cbStreamFree = ichac97R3StreamGetFree(pStreamCC); 1275 if (cbStreamFree) 1276 { /* likely */ } 1277 else 1278 { 1279 /** @todo Record this as a statistic. Try make some space available. */ 1280 } 1281 if (cbStreamFree) 1282 { 1283 Log3Func(("[SD%RU8] PICB=%zu (%RU64ms), cbFree=%zu (%RU64ms), cbTransferChunk=%zu (%RU64ms)\n", 1284 pStream->u8SD, 1285 (pStream->Regs.picb << 1), PDMAudioPropsBytesToMilli(&pStreamCC->State.Cfg.Props, pStream->Regs.picb << 1), 1286 cbStreamFree, PDMAudioPropsBytesToMilli(&pStreamCC->State.Cfg.Props, cbStreamFree), 1287 pStreamCC->State.cbTransferChunk, PDMAudioPropsBytesToMilli(&pStreamCC->State.Cfg.Props, pStreamCC->State.cbTransferChunk))); 1288 1289 /* Do the DMA transfer. */ 1290 rc2 = ichac97R3StreamTransfer(pDevIns, pThis, pStream, pStreamCC, 1291 RT_MIN(pStreamCC->State.cbTransferChunk, cbStreamFree)); 1292 AssertRC(rc2); 1293 1294 pStreamCC->State.tsLastUpdateNs = RTTimeNanoTS(); 1295 } 1296 1295 /** @todo Record this as a statistic. Try make some space available. */ 1296 } 1297 if (cbStreamFree) 1298 { 1299 Log3Func(("[SD%RU8] PICB=%zu (%RU64ms), cbFree=%zu (%RU64ms), cbTransferChunk=%zu (%RU64ms)\n", 1300 pStream->u8SD, 1301 (pStream->Regs.picb << 1), PDMAudioPropsBytesToMilli(&pStreamCC->State.Cfg.Props, pStream->Regs.picb << 1), 1302 cbStreamFree, PDMAudioPropsBytesToMilli(&pStreamCC->State.Cfg.Props, cbStreamFree), 1303 pStreamCC->State.cbTransferChunk, PDMAudioPropsBytesToMilli(&pStreamCC->State.Cfg.Props, pStreamCC->State.cbTransferChunk))); 1304 1305 /* Do the DMA transfer. */ 1306 rc2 = ichac97R3StreamTransfer(pDevIns, pThis, pStream, pStreamCC, 1307 RT_MIN(pStreamCC->State.cbTransferChunk, cbStreamFree)); 1308 AssertRC(rc2); 1309 1310 pStreamCC->State.tsLastUpdateNs = RTTimeNanoTS(); 1311 } 1312 1313 rc2 = AudioMixerSinkSignalUpdateJob(pSink); 1314 AssertRC(rc2); 1315 } 1316 else /* Input (SDI). */ 1317 { 1318 #if 0 /* bird: I just love when crusial code like this with no explanation. This just causing AIO 1319 * skipping a DMA timer cycle if the timer callback is a bit quicker than the 'hint' (see HDA/9890). */ 1320 const uint64_t tsNowNs = RTTimeNanoTS(); 1321 if (tsNowNs - pStreamCC->State.tsLastUpdateNs >= pStreamCC->State.Cfg.Device.cMsSchedulingHint * RT_NS_1MS) 1322 { 1297 1323 rc2 = AudioMixerSinkSignalUpdateJob(pSink); 1298 1324 AssertRC(rc2); 1325 1326 pStreamCC->State.tsLastUpdateNs = tsNowNs; 1299 1327 } 1300 else /* Input (SDI). */ 1328 #endif 1329 1330 uint32_t cbStreamUsed = ichac97R3StreamGetUsed(pStreamCC); 1331 if (cbStreamUsed) 1332 { /* likey */ } 1333 else 1301 1334 { 1302 #if 0 /* bird: I just love when crusial code like this with no explanation. This just causing AIO 1303 * skipping a DMA timer cycle if the timer callback is a bit quicker than the 'hint' (see HDA/9890). */ 1304 const uint64_t tsNowNs = RTTimeNanoTS(); 1305 if (tsNowNs - pStreamCC->State.tsLastUpdateNs >= pStreamCC->State.Cfg.Device.cMsSchedulingHint * RT_NS_1MS) 1306 { 1307 rc2 = AudioMixerSinkSignalUpdateJob(pSink); 1308 AssertRC(rc2); 1309 1310 pStreamCC->State.tsLastUpdateNs = tsNowNs; 1311 } 1312 #endif 1313 1314 uint32_t cbStreamUsed = ichac97R3StreamGetUsed(pStreamCC); 1315 if (cbStreamUsed) 1316 { /* likey */ } 1317 else 1318 { 1319 /** @todo Record this as a statistic. Try pull some data into the DMA buffer.*/ 1320 } 1321 1322 if (cbStreamUsed) 1323 { 1324 /* When running synchronously, do the DMA data transfers here. 1325 * Otherwise this will be done in the stream's async I/O thread. */ 1326 rc2 = ichac97R3StreamTransfer(pDevIns, pThis, pStream, pStreamCC, cbStreamUsed); 1327 AssertRC(rc2); 1328 } 1329 1330 /* 1331 * We should always kick the AIO thread. 1332 */ 1333 /** @todo This isn't entirely ideal. If we get into an underrun situation, 1334 * we ideally want the AIO thread to run right before the DMA timer 1335 * rather than right after it ran. */ 1336 Log5Func(("Notifying AIO thread\n")); 1337 rc2 = AudioMixerSinkSignalUpdateJob(pSink); 1335 /** @todo Record this as a statistic. Try pull some data into the DMA buffer.*/ 1336 } 1337 1338 if (cbStreamUsed) 1339 { 1340 /* When running synchronously, do the DMA data transfers here. 1341 * Otherwise this will be done in the stream's async I/O thread. */ 1342 rc2 = ichac97R3StreamTransfer(pDevIns, pThis, pStream, pStreamCC, cbStreamUsed); 1338 1343 AssertRC(rc2); 1339 pStreamCC->State.tsLastUpdateNs = RTTimeNanoTS();1340 1344 } 1345 1346 /* 1347 * We should always kick the AIO thread. 1348 */ 1349 /** @todo This isn't entirely ideal. If we get into an underrun situation, 1350 * we ideally want the AIO thread to run right before the DMA timer 1351 * rather than right after it ran. */ 1352 Log5Func(("Notifying AIO thread\n")); 1353 rc2 = AudioMixerSinkSignalUpdateJob(pSink); 1354 AssertRC(rc2); 1355 pStreamCC->State.tsLastUpdateNs = RTTimeNanoTS(); 1341 1356 } 1342 1357 } … … 3268 3283 { 3269 3284 ichac97MixerSet(pThis, AC97_PCM_Front_DAC_Rate, 0xbb80); /* Set default (48000 Hz). */ 3285 /** @todo r=bird: Why reopen it now? Can't we put that off till it's 3286 * actually used? */ 3270 3287 ichac97R3StreamReOpen(pDevIns, pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX], 3271 3288 &pThisCC->aStreams[AC97SOUNDSOURCE_PO_INDEX], true /* fForce */); 3272 3289 3273 3290 ichac97MixerSet(pThis, AC97_PCM_LR_ADC_Rate, 0xbb80); /* Set default (48000 Hz). */ 3291 /** @todo r=bird: Why reopen it now? Can't we put that off till it's 3292 * actually used? */ 3274 3293 ichac97R3StreamReOpen(pDevIns, pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX], 3275 3294 &pThisCC->aStreams[AC97SOUNDSOURCE_PI_INDEX], true /* fForce */); … … 3284 3303 { 3285 3304 ichac97MixerSet(pThis, AC97_MIC_ADC_Rate, 0xbb80); /* Set default (48000 Hz). */ 3305 /** @todo r=bird: Why reopen it now? Can't we put that off till it's 3306 * actually used? */ 3286 3307 ichac97R3StreamReOpen(pDevIns, pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX], 3287 3308 &pThisCC->aStreams[AC97SOUNDSOURCE_MC_INDEX], true /* fForce */); … … 3302 3323 LogRel2(("AC97: Setting front DAC rate to 0x%x\n", u32)); 3303 3324 ichac97MixerSet(pThis, offPort, u32); 3325 /** @todo r=bird: Why reopen it now? Can't we put that off till it's 3326 * actually used? */ 3304 3327 ichac97R3StreamReOpen(pDevIns, pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX], 3305 3328 &pThisCC->aStreams[AC97SOUNDSOURCE_PO_INDEX], true /* fForce */); … … 3317 3340 LogRel2(("AC97: Setting microphone ADC rate to 0x%x\n", u32)); 3318 3341 ichac97MixerSet(pThis, offPort, u32); 3342 /** @todo r=bird: Why reopen it now? Can't we put that off till it's 3343 * actually used? */ 3319 3344 ichac97R3StreamReOpen(pDevIns, pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX], 3320 3345 &pThisCC->aStreams[AC97SOUNDSOURCE_MC_INDEX], true /* fForce */); … … 3332 3357 LogRel2(("AC97: Setting line-in ADC rate to 0x%x\n", u32)); 3333 3358 ichac97MixerSet(pThis, offPort, u32); 3359 /** @todo r=bird: Why reopen it now? Can't we put that off till it's 3360 * actually used? */ 3334 3361 ichac97R3StreamReOpen(pDevIns, pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX], 3335 3362 &pThisCC->aStreams[AC97SOUNDSOURCE_PI_INDEX], true /* fForce */);
Note:
See TracChangeset
for help on using the changeset viewer.