Changeset 61523 in vbox for trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
- Timestamp:
- Jun 7, 2016 9:47:21 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
r61399 r61523 46 46 *********************************************************************************************************************************/ 47 47 48 #ifdef DEBUG 49 //#define DEBUG_LUN 50 # ifdef DEBUG_LUN 51 # define DEBUG_LUN_NUM 1 48 #ifdef DEBUG_andy 49 /* 50 * AC97_DEBUG_DUMP_PCM_DATA enables dumping the raw PCM data 51 * to a file on the host. Be sure to adjust AC97_DEBUG_DUMP_PCM_DATA_PATH 52 * to your needs before using this! 53 */ 54 # define AC97_DEBUG_DUMP_PCM_DATA 55 # ifdef RT_OS_WINDOWS 56 # define AC97_DEBUG_DUMP_PCM_DATA_PATH "c:\\temp\\" 57 # else 58 # define AC97_DEBUG_DUMP_PCM_DATA_PATH "/tmp/" 52 59 # endif 53 #endif /* DEBUG */60 #endif /* DEBUG_andy */ 54 61 55 62 #define AC97_SSM_VERSION 1 … … 76 83 #define CR_IOCE RT_BIT(4) /* rw, Interrupt On Completion Enable. */ 77 84 #define CR_FEIE RT_BIT(3) /* rw FIFO Error Interrupt Enable. */ 78 #define CR_LVBIE RT_BIT(2) /* rw */79 #define CR_RR RT_BIT(1) /* rw */80 #define CR_RPBM RT_BIT(0) /* rw */85 #define CR_LVBIE RT_BIT(2) /* rw Last Valid Buffer Interrupt Enable. */ 86 #define CR_RR RT_BIT(1) /* rw Reset Registers. */ 87 #define CR_RPBM RT_BIT(0) /* rw Run/Pause Bus Master. */ 81 88 #define CR_VALID_MASK (RT_BIT(5) - 1) 82 89 #define CR_DONT_CLEAR_MASK (CR_IOCE | CR_FEIE | CR_LVBIE) … … 263 270 uint8_t lvi; /** rw 0, Last valid index. */ 264 271 uint16_t sr; /** rw 1, Status register. */ 265 uint16_t picb; /** ro 0, Position in current buffer . */272 uint16_t picb; /** ro 0, Position in current buffer (in samples). */ 266 273 uint8_t piv; /** ro 0, Prefetched index value. */ 267 274 uint8_t cr; /** rw 0, Control register. */ … … 423 430 static DECLCALLBACK(void) ichac97Timer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser); 424 431 #endif 425 static int ichac97TransferAudio(PAC97STATE pThis, PAC97STREAM pStream , uint32_t cbElapsed);432 static int ichac97TransferAudio(PAC97STATE pThis, PAC97STREAM pStream); 426 433 427 434 static void ichac97WarmReset(PAC97STATE pThis) … … 532 539 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 533 540 534 bool fActive = AudioMixerSink HasData(ichac97IndexToSink(pThis, pStream->u8Strm));541 bool fActive = AudioMixerSinkGetStatus(ichac97IndexToSink(pThis, pStream->u8Strm)); 535 542 536 543 LogFlowFunc(("SD=%RU8, fActive=%RTbool\n", pStream->u8Strm, fActive)); … … 1145 1152 * @param pcbWritten 1146 1153 */ 1147 static int ichac97WriteAudio(PAC97STATE pThis, PAC97STREAM pStream, uint32_t cb Max, uint32_t *pcbWritten)1154 static int ichac97WriteAudio(PAC97STATE pThis, PAC97STREAM pStream, uint32_t cbToWrite, uint32_t *pcbWritten) 1148 1155 { 1149 1156 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1150 1157 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1151 AssertReturn(cb Max,VERR_INVALID_PARAMETER);1158 AssertReturn(cbToWrite, VERR_INVALID_PARAMETER); 1152 1159 /* pcbWritten is optional. */ 1153 1160 … … 1158 1165 uint32_t cbWrittenTotal = 0; 1159 1166 1160 Log3Func(("PICB=%RU16, cbMax=%RU32\n", pRegs->picb, cb Max));1161 1162 uint32_t cbToWrite = RT_MIN((uint32_t)(pRegs->picb << 1), cbMax); /** @todo r=andy Assumes 16bit sample size. */1167 Log3Func(("PICB=%RU16, cbMax=%RU32\n", pRegs->picb, cbToWrite)); 1168 1169 cbToWrite = RT_MIN((uint32_t)(pRegs->picb << 1), cbToWrite); /** @todo r=andy Assumes 16bit sample size. */ 1163 1170 if (!cbToWrite) 1164 1171 { … … 1170 1177 int rc = VINF_SUCCESS; 1171 1178 1172 LogFlowFunc(("pReg =%p, cbMax=%RU32, cbToWrite=%RU32\n", pRegs, cbMax, cbToWrite));1179 LogFlowFunc(("pRegs=%p, cbMax=%RU32, cbToWrite=%RU32\n", pRegs, cbToWrite, cbToWrite)); 1173 1180 1174 1181 Assert(pStream->State.offFIFOW <= pStream->State.cbFIFOW); … … 1182 1189 PDMDevHlpPhysRead(pDevIns, addr, pu8FIFOW, cbToRead); /** @todo r=andy Check rc? */ 1183 1190 1184 #if defined (RT_OS_LINUX) && defined(DEBUG_andy)1191 #ifdef AC97_DEBUG_DUMP_PCM_DATA 1185 1192 RTFILE fh; 1186 RTFileOpen(&fh, "/tmp/ac97WriteAudio.pcm",1193 RTFileOpen(&fh, AC97_DEBUG_DUMP_PCM_DATA_PATH "ac97WriteAudio.pcm", 1187 1194 RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 1188 1195 RTFileWrite(fh, pu8FIFOW, cbToRead, NULL); … … 1234 1241 static void ichac97WriteBUP(PAC97STATE pThis, uint32_t cbElapsed) 1235 1242 { 1243 LogFlowFunc(("cbElapsed=%RU32\n", cbElapsed)); 1244 1236 1245 if (!(pThis->bup_flag & BUP_SET)) 1237 1246 { … … 1240 1249 unsigned int i; 1241 1250 uint32_t *p = (uint32_t*)pThis->silence; 1242 for (i = 0; i < sizeof(pThis->silence) / 4; i++) 1251 for (i = 0; i < sizeof(pThis->silence) / 4; i++) /** @todo r=andy Assumes 16-bit samples, stereo. */ 1243 1252 *p++ = pThis->last_samp; 1244 1253 } … … 1269 1278 } 1270 1279 1271 static int ichac97ReadAudio(PAC97STATE pThis, PAC97STREAM pStream, uint32_t cb Max, uint32_t *pcbRead)1280 static int ichac97ReadAudio(PAC97STATE pThis, PAC97STREAM pStream, uint32_t cbToRead, uint32_t *pcbRead) 1272 1281 { 1273 1282 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1274 1283 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1275 AssertReturn(cb Max,VERR_INVALID_PARAMETER);1284 AssertReturn(cbToRead, VERR_INVALID_PARAMETER); 1276 1285 /* pcbRead is optional. */ 1277 1286 … … 1285 1294 1286 1295 uint32_t cbRead = 0; 1287 uint32_t cbToRead = RT_MIN((uint32_t)(pRegs->picb << 1), 1288 RT_MIN(pStream->State.cbFIFOW, cbMax)); /** @todo r=andy Assumes 16bit samples. */ 1296 1297 cbToRead = RT_MIN((uint32_t)(pRegs->picb << 1), 1298 RT_MIN(pStream->State.cbFIFOW, cbToRead)); /** @todo r=andy Assumes 16bit samples. */ 1289 1299 1290 1300 if (!cbToRead) … … 1365 1375 uint64_t cTicksPerSec = TMTimerGetFreq(pTimer); 1366 1376 1377 LogFlowFuncEnter(); 1378 1367 1379 /* Update current time timestamp. */ 1368 1380 pThis->uTimerTS = cTicksNow; 1369 1381 1370 LogFlowFuncEnter(); 1371 1372 uint32_t cbLineIn; 1373 AudioMixerSinkTimerUpdate(pThis->pSinkLineIn, pThis->cTimerTicks, cTicksPerSec, &cbLineIn); 1374 if (cbLineIn) 1375 ichac97TransferAudio(pThis, &pThis->StreamLineIn, cbLineIn); 1376 1377 uint32_t cbMicIn; 1378 AudioMixerSinkTimerUpdate(pThis->pSinkMicIn , pThis->cTimerTicks, cTicksPerSec, &cbMicIn); 1379 if (cbMicIn) 1380 ichac97TransferAudio(pThis, &pThis->StreamMicIn, cbMicIn); 1381 1382 uint32_t cbOut; 1383 AudioMixerSinkTimerUpdate(pThis->pSinkOutput, pThis->cTimerTicks, cTicksPerSec, &cbOut); 1384 if (cbOut) 1385 ichac97TransferAudio(pThis, &pThis->StreamOut, cbOut); 1382 /* Flag indicating whether to kick the timer again for a 1383 * new data processing round. */ 1384 bool fKickTimer = false; 1385 1386 AudioMixerSinkTimerUpdate(pThis->pSinkLineIn, pThis->cTimerTicks, cTicksPerSec); 1387 ichac97TransferAudio(pThis, &pThis->StreamLineIn); 1388 1389 fKickTimer = AudioMixerSinkGetStatus(pThis->pSinkLineIn) & AUDMIXSINK_STS_DIRTY; 1390 1391 AudioMixerSinkTimerUpdate(pThis->pSinkMicIn , pThis->cTimerTicks, cTicksPerSec); 1392 ichac97TransferAudio(pThis, &pThis->StreamMicIn); 1393 1394 fKickTimer = AudioMixerSinkGetStatus(pThis->pSinkMicIn) & AUDMIXSINK_STS_DIRTY; 1395 1396 AudioMixerSinkTimerUpdate(pThis->pSinkOutput, pThis->cTimerTicks, cTicksPerSec); 1397 ichac97TransferAudio(pThis, &pThis->StreamOut); 1398 1399 fKickTimer = AudioMixerSinkGetStatus(pThis->pSinkOutput) & AUDMIXSINK_STS_DIRTY; 1386 1400 1387 1401 if ( ASMAtomicReadBool(&pThis->fTimerActive) 1388 || AudioMixerSinkHasData(pThis->pSinkLineIn) 1389 || AudioMixerSinkHasData(pThis->pSinkMicIn) 1390 || AudioMixerSinkHasData(pThis->pSinkOutput)) 1402 || fKickTimer) 1391 1403 { 1392 1404 /* Kick the timer again. */ … … 1401 1413 #endif /* !VBOX_WITH_AUDIO_CALLBACKS */ 1402 1414 1403 static int ichac97TransferAudio(PAC97STATE pThis, PAC97STREAM pStream , uint32_t cbElapsed)1404 { 1405 Log3Func(("SD=%RU8 , cbElapsed=%RU32\n", pStream->u8Strm , cbElapsed));1415 static int ichac97TransferAudio(PAC97STATE pThis, PAC97STREAM pStream) 1416 { 1417 Log3Func(("SD=%RU8\n", pStream->u8Strm)); 1406 1418 1407 1419 PAC97BMREGS pRegs = &pStream->Regs; … … 1409 1421 if (pRegs->sr & SR_DCH) /* Controller halted? */ 1410 1422 { 1411 if (pRegs->cr & CR_RPBM) 1423 if (pRegs->cr & CR_RPBM) /* Bus master operation starts. */ 1412 1424 { 1413 1425 switch (pStream->u8Strm) 1414 1426 { 1415 1427 case PO_INDEX: 1416 ichac97WriteBUP(pThis, cbElapsed);1428 ichac97WriteBUP(pThis, (uint32_t)(pRegs->picb << 1)); 1417 1429 break; 1418 1430 … … 1432 1444 uint32_t cbWrittenTotal = 0; 1433 1445 1434 while (cbElapsed >> 1) /** @todo r=andy This assumes (hardcodes) 16bit sample size.*/1446 do 1435 1447 { 1436 1448 if (!pRegs->bd_valid) … … 1446 1458 if (pRegs->civ == pRegs->lvi) 1447 1459 { 1448 pRegs->sr |= SR_DCH; /* CELV? */1460 pRegs->sr |= SR_DCH; /** @todo r=andy Also set CELV? */ 1449 1461 pThis->bup_flag = 0; 1450 1462 … … 1461 1473 } 1462 1474 1463 uint32_t cbT ransferred;1475 uint32_t cbToTransfer, cbTransferred; 1464 1476 switch (pStream->u8Strm) 1465 1477 { 1466 1478 case PO_INDEX: 1467 1479 { 1468 rc = ichac97WriteAudio(pThis, pStream, cbElapsed, &cbTransferred); 1480 cbToTransfer = (uint32_t)(pRegs->picb << 1); 1481 1482 rc = ichac97WriteAudio(pThis, pStream, cbToTransfer, &cbTransferred); 1469 1483 if ( RT_SUCCESS(rc) 1470 1484 && cbTransferred) 1471 1485 { 1472 1486 cbWrittenTotal += cbTransferred; 1473 Assert(cbElapsed >= cbTransferred); 1474 cbElapsed -= cbTransferred; 1475 Assert((cbTransferred & 1) == 0); /* Else the following shift won't work */ 1487 Assert((cbTransferred & 1) == 0); /* Else the following shift won't work */ 1476 1488 pRegs->picb -= (cbTransferred >> 1); /** @todo r=andy Assumes 16bit samples. */ 1477 1489 } … … 1482 1494 case MC_INDEX: 1483 1495 { 1484 rc = ichac97ReadAudio(pThis, pStream, cbElapsed, &cbTransferred); 1496 cbToTransfer = (uint32_t)(pRegs->picb << 1); 1497 1498 rc = ichac97ReadAudio(pThis, pStream, cbToTransfer, &cbTransferred); 1485 1499 if ( RT_SUCCESS(rc) 1486 1500 && cbTransferred) 1487 1501 { 1488 Assert(cbElapsed >= cbTransferred); 1489 cbElapsed -= cbTransferred; 1490 Assert((cbTransferred & 1) == 0); /* Else the following shift won't work */ 1502 Assert((cbTransferred & 1) == 0); /* Else the following shift won't work */ 1491 1503 pRegs->picb -= (cbTransferred >> 1); /** @todo r=andy Assumes 16bit samples. */ 1492 1504 } … … 1532 1544 } 1533 1545 1534 if ( RT_FAILURE(rc) 1535 || rc == VINF_EOF) /* All data processed? */ 1536 { 1537 break; 1538 } 1539 } 1546 if (rc == VINF_EOF) /* All data processed? */ 1547 break; 1548 1549 } while (RT_SUCCESS(rc)); 1540 1550 1541 1551 LogFlowFuncLeaveRC(rc); … … 1549 1559 uint32_t *pu32Val, unsigned cbVal) 1550 1560 { 1551 PAC97STATE pThis 1561 PAC97STATE pThis = (PAC97STATE)pvUser; 1552 1562 1553 1563 /* Get the index of the NABMBAR port. */
Note:
See TracChangeset
for help on using the changeset viewer.