Changeset 63862 in vbox
- Timestamp:
- Sep 16, 2016 9:47:12 AM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
r63819 r63862 84 84 #define AC97_CR_DONT_CLEAR_MASK (AC97_CR_IOCE | AC97_CR_FEIE | AC97_CR_LVBIE) 85 85 86 #define AC97_GC_WR 4 /* rw*/87 #define AC97_GC_CR 2 /* rw*/86 #define AC97_GC_WR 4 /* rw Warm reset. */ 87 #define AC97_GC_CR 2 /* rw Cold reset. */ 88 88 #define AC97_GC_VALID_MASK (RT_BIT(6) - 1) 89 89 … … 282 282 283 283 /** 284 * Internal state of an AC 97 stream.284 * Internal state of an AC'97 stream. 285 285 */ 286 286 typedef struct AC97STREAMSTATE … … 296 296 297 297 /** 298 * Structure for keeping an AC97 stream state. 299 * 300 * Contains only register values which do *not* change until a 301 * stream reset occurs. 298 * Structure for keeping an AC'97 stream state. 302 299 */ 303 300 typedef struct AC97STREAM … … 305 302 /** Stream number (SDn). */ 306 303 uint8_t u8Strm; 304 /** Criticial section for this stream. */ 305 RTCRITSECT CritSect; 307 306 /** Bus master registers of this stream. */ 308 307 AC97BMREGS Regs; … … 378 377 /** The timer for pumping data thru the attached LUN drivers. */ 379 378 PTMTIMERR3 pTimer; 379 /** Criticial section for timer. */ 380 RTCRITSECT csTimer; 380 381 # if HC_ARCH_BITS == 32 381 382 uint32_t Padding0; … … 401 402 R3PTRTYPE(PAUDIOMIXER) pMixer; 402 403 /** Audio sink for PCM output. */ 403 R3PTRTYPE(PAUDMIXSINK) pSinkOut put;404 R3PTRTYPE(PAUDMIXSINK) pSinkOut; 404 405 /** Audio sink for line input. */ 405 406 R3PTRTYPE(PAUDMIXSINK) pSinkLineIn; … … 429 430 #endif 430 431 DECLINLINE(PAC97STREAM) ichac97GetStreamFromID(PAC97STATE pThis, uint32_t uID); 431 static int ichac97StreamInit(PAC97STATE pThis, PAC97STREAM pStream, uint8_t u8Strm); 432 static int ichac97StreamInit(PAC97STREAM pStream, uint8_t u8Strm); 433 static void ichac97StreamDestroy(PAC97STREAM pStream); 434 static int ichac97StreamOpen(PAC97STATE pThis, PAC97STREAM pStream); 435 static int ichac97StreamReOpen(PAC97STATE pThis, PAC97STREAM pStream); 436 static void ichac97StreamClose(PAC97STREAM pStream); 432 437 static DECLCALLBACK(void) ichac97Reset(PPDMDEVINS pDevIns); 433 438 #ifndef VBOX_WITH_AUDIO_AC97_CALLBACKS … … 455 460 { 456 461 case AC97SOUNDSOURCE_PI_INDEX: return pThis->pSinkLineIn; break; 457 case AC97SOUNDSOURCE_PO_INDEX: return pThis->pSinkOut put;break;462 case AC97SOUNDSOURCE_PO_INDEX: return pThis->pSinkOut; break; 458 463 case AC97SOUNDSOURCE_MC_INDEX: return pThis->pSinkMicIn; break; 459 464 default: break; … … 540 545 } 541 546 542 static bool ichac97StreamIsActive(PAC97STATE pThis, PAC97STREAM pStream) 547 /** 548 * Returns whether an AC'97 stream is enabled or not. 549 * 550 * @returns IPRT status code. 551 * @param pThis AC'97 device state. 552 * @param pStream Stream to return status for. 553 */ 554 static bool ichac97StreamIsEnabled(PAC97STATE pThis, PAC97STREAM pStream) 543 555 { 544 556 AssertPtrReturn(pThis, false); … … 546 558 547 559 PAUDMIXSINK pSink = ichac97IndexToSink(pThis, pStream->u8Strm); 548 bool f Active= RT_BOOL(AudioMixerSinkGetStatus(pSink) & AUDMIXSINK_STS_RUNNING);549 550 LogF lowFunc(("[SD%RU8] fActive=%RTbool\n", pStream->u8Strm, fActive));551 return f Active;552 } 553 554 static int ichac97Stream SetActive(PAC97STATE pThis, PAC97STREAM pStream, bool fActive)560 bool fIsEnabled = RT_BOOL(AudioMixerSinkGetStatus(pSink) & AUDMIXSINK_STS_RUNNING); 561 562 LogFunc(("[SD%RU8] fIsEnabled=%RTbool\n", pStream->u8Strm, fIsEnabled)); 563 return fIsEnabled; 564 } 565 566 static int ichac97StreamEnable(PAC97STATE pThis, PAC97STREAM pStream, bool fEnable) 555 567 { 556 568 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 557 569 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 558 570 559 /* Check the stream's status register if a state change actually is required. */ 560 const bool fIsActive = !RT_BOOL(pStream->Regs.sr & AC97_SR_DCH); 561 562 LogFunc(("[SD%RU8] fActive=%RTbool, fIsActive=%RTbool, cStreamsActive=%RU8\n", 563 pStream->u8Strm, fActive, fIsActive, pThis->cStreamsActive)); 564 565 if (fIsActive == fActive) /* Is a change required? */ 566 return VINF_SUCCESS; 567 568 if (!fActive) 569 { 570 if (pThis->cStreamsActive) /* Disable can be called mupltiple times. */ 571 pThis->cStreamsActive--; 571 PAUDMIXSINK pSink = ichac97IndexToSink(pThis, pStream->u8Strm); 572 AssertPtr(pSink); 573 574 const bool fIsEnabled = AudioMixerSinkGetStatus(pSink) & AUDMIXSINK_STS_RUNNING; 575 576 LogFunc(("[SD%RU8] fEnable=%RTbool, fIsEnabled=%RTbool, DCH=%RTbool, cStreamsActive=%RU8\n", 577 pStream->u8Strm, fEnable, fIsEnabled, RT_BOOL(pStream->Regs.sr & AC97_SR_DCH), pThis->cStreamsActive)); 578 579 int rc = VINF_SUCCESS; 580 581 if (fEnable != fIsEnabled) 582 { 583 rc = ichac97StreamReOpen(pThis, pStream); 584 if (RT_SUCCESS(rc)) 585 rc = AudioMixerSinkCtl(ichac97IndexToSink(pThis, pStream->u8Strm), 586 fEnable ? AUDMIXSINKCMD_ENABLE : AUDMIXSINKCMD_DISABLE); 587 if (RT_SUCCESS(rc)) 588 { 589 if (!fEnable) 590 { 591 if (pThis->cStreamsActive) /* Disable can be called mupltiple times. */ 592 pThis->cStreamsActive--; 572 593 573 594 #ifndef VBOX_WITH_AUDIO_AC97_CALLBACKS 574 ichac97TimerMaybeStop(pThis);595 ichac97TimerMaybeStop(pThis); 575 596 #endif 576 }577 else578 {579 pThis->cStreamsActive++;597 } 598 else 599 { 600 pThis->cStreamsActive++; 580 601 #ifndef VBOX_WITH_AUDIO_AC97_CALLBACKS 581 ichac97TimerMaybeStart(pThis);602 ichac97TimerMaybeStart(pThis); 582 603 #endif 583 } 584 585 return AudioMixerSinkCtl(ichac97IndexToSink(pThis, pStream->u8Strm), 586 fActive ? AUDMIXSINKCMD_ENABLE : AUDMIXSINKCMD_DISABLE); 604 } 605 } 606 } 607 608 LogFunc(("Returning %Rrc\n", rc)); 609 return rc; 587 610 } 588 611 … … 592 615 AssertPtrReturnVoid(pStream); 593 616 594 LogF lowFunc(("[SD%RU8]\n", pStream->u8Strm));617 LogFunc(("[SD%RU8]\n", pStream->u8Strm)); 595 618 596 619 PAC97BMREGS pRegs = &pStream->Regs; … … 600 623 pRegs->lvi = 0; 601 624 602 ichac97Stream SetActive(pThis, pStream, false /* fActive */);625 ichac97StreamEnable(pThis, pStream, false /* fActive */); 603 626 604 627 ichac97StreamUpdateSR(pThis, pStream, AC97_SR_DCH); /** @todo Do we need to do that? */ … … 612 635 } 613 636 637 static int ichac97StreamInit(PAC97STREAM pStream, uint8_t u8Strm) 638 { 639 AssertPtrReturn(pStream, VERR_INVALID_PARAMETER); 640 641 LogFunc(("[SD%RU8] pStream=%p\n", u8Strm, pStream)); 642 643 int rc = VINF_SUCCESS; 644 645 pStream->u8Strm = u8Strm; 646 pStream->State.cbFIFOW = _4K; /** @todo Make FIFOW size configurable. */ 647 pStream->State.offFIFOW = 0; 648 pStream->State.au8FIFOW = (uint8_t *)RTMemAllocZ(pStream->State.cbFIFOW); 649 if (pStream->State.au8FIFOW) 650 { 651 rc = RTCritSectInit(&pStream->CritSect); 652 } 653 else 654 rc = VERR_NO_MEMORY; 655 656 return rc; 657 } 658 614 659 static void ichac97StreamDestroy(PAC97STREAM pStream) 615 660 { … … 625 670 pStream->State.cbFIFOW = 0; 626 671 pStream->State.offFIFOW = 0; 627 } 628 629 #if 0 /* unused */ 630 static void ichac97StreamsDestroy(PAC97STATE pThis) 672 673 if (RTCritSectIsInitialized(&pStream->CritSect)) 674 RTCritSectDelete(&pStream->CritSect); 675 } 676 677 static int ichac97StreamsInit(PAC97STATE pThis) 631 678 { 632 679 LogFlowFuncEnter(); 633 680 634 ichac97DestroyIn(pThis, PDMAUDIORECSOURCE_LINE); 635 ichac97DestroyIn(pThis, PDMAUDIORECSOURCE_MIC); 636 ichac97DestroyOut(pThis); 637 638 ichac97StreamDestroy(&pThis->StreamLineIn); 639 ichac97StreamDestroy(&pThis->StreamMicIn); 640 ichac97StreamDestroy(&pThis->StreamOut); 641 } 642 #endif 643 644 static int ichac97StreamsInit(PAC97STATE pThis) 645 { 646 LogFlowFuncEnter(); 647 648 ichac97StreamInit(pThis, &pThis->StreamLineIn, AC97SOUNDSOURCE_PI_INDEX); 649 ichac97StreamInit(pThis, &pThis->StreamMicIn, AC97SOUNDSOURCE_MC_INDEX); 650 ichac97StreamInit(pThis, &pThis->StreamOut, AC97SOUNDSOURCE_PO_INDEX); 681 ichac97StreamInit(&pThis->StreamLineIn, AC97SOUNDSOURCE_PI_INDEX); 682 ichac97StreamInit(&pThis->StreamMicIn, AC97SOUNDSOURCE_MC_INDEX); 683 ichac97StreamInit(&pThis->StreamOut, AC97SOUNDSOURCE_PO_INDEX); 651 684 652 685 return VINF_SUCCESS; … … 810 843 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 811 844 845 LogFunc(("%s\n", pszName)); 846 812 847 /* Update the sink's format. */ 813 848 PDMAUDIOPCMPROPS PCMProps; 814 849 int rc = DrvAudioHlpStreamCfgToProps(pCfg, &PCMProps); 815 850 if (RT_SUCCESS(rc)) 816 rc = AudioMixerSinkSetFormat(pThis->pSinkOut put, &PCMProps);851 rc = AudioMixerSinkSetFormat(pThis->pSinkOut, &PCMProps); 817 852 818 853 if (RT_FAILURE(rc)) … … 829 864 } 830 865 831 AudioMixerSinkRemoveStream(pThis->pSinkOut put, pDrv->Out.pMixStrm);866 AudioMixerSinkRemoveStream(pThis->pSinkOut, pDrv->Out.pMixStrm); 832 867 833 868 AudioMixerStreamDestroy(pDrv->Out.pMixStrm); 834 869 pDrv->Out.pMixStrm = NULL; 835 870 836 int rc2 = AudioMixerSinkCreateStream(pThis->pSinkOut put, pDrv->pConnector, pCfg, 0 /* fFlags */, &pDrv->Out.pMixStrm);871 int rc2 = AudioMixerSinkCreateStream(pThis->pSinkOut, pDrv->pConnector, pCfg, 0 /* fFlags */, &pDrv->Out.pMixStrm); 837 872 if (RT_SUCCESS(rc2)) 838 873 { 839 rc2 = AudioMixerSinkAddStream(pThis->pSinkOut put, pDrv->Out.pMixStrm);874 rc2 = AudioMixerSinkAddStream(pThis->pSinkOut, pDrv->Out.pMixStrm); 840 875 LogFlowFunc(("LUN#%RU8: Created output \"%s\", rc=%Rrc\n", pDrv->uLUN, pCfg->szName, rc2)); 841 876 } … … 849 884 } 850 885 851 static int ichac97StreamInitEx(PAC97STATE pThis, PAC97STREAM pStream, uint8_t u8Strm, PPDMAUDIOSTREAMCFG pCfg) 886 /** 887 * Opens an AC'97 stream, extended version. 888 * 889 * @returns IPRT status code. 890 * @param pThis AC'97 device state. 891 * @param pStream Stream to initialize. 892 * @param pCfg Audio stream configuration to initialize the stream with. 893 */ 894 static int ichac97StreamOpenEx(PAC97STATE pThis, PAC97STREAM pStream, PPDMAUDIOSTREAMCFG pCfg) 852 895 { 853 896 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 854 897 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 855 AssertReturn(u8Strm <= AC97SOUNDSOURCE_LAST_INDEX, VERR_INVALID_PARAMETER);856 898 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 857 899 858 pStream->u8Strm = u8Strm; 859 860 LogFlowFunc(("u8Strm=%RU8, %RU32Hz, %RU8 %s\n", 861 pStream->u8Strm, pCfg->uHz, pCfg->cChannels, pCfg->cChannels > 1 ? "Channels" : "Channel")); 900 LogFunc(("[SD%RU8] pCfg=%p\n", pStream->u8Strm, pCfg)); 862 901 863 902 int rc; … … 877 916 878 917 default: 879 rc = VERR_NOT_SUPPORTED;918 AssertFailedStmt(rc = VERR_NOT_SUPPORTED); 880 919 break; 881 920 } … … 888 927 } 889 928 890 static int ichac97StreamInit(PAC97STATE pThis, PAC97STREAM pStream, uint8_t u8Strm) 929 /** 930 * Opens an AC'97 stream. 931 * This will open an AC'97 stream with 2 (stereo) channels, 16-bit samples and 932 * the last set sample rate in the AC'97 mixer for this stream. 933 * 934 * @returns IPRT status code. 935 * @param pThis AC'97 device state. 936 * @param pStream Stream to initialize. 937 */ 938 static int ichac97StreamOpen(PAC97STATE pThis, PAC97STREAM pStream) 891 939 { 892 940 int rc = VINF_SUCCESS; 941 942 LogFunc(("[SD%RU8]\n", pStream->u8Strm)); 893 943 894 944 PDMAUDIOSTREAMCFG streamCfg; 895 945 RT_ZERO(streamCfg); 896 946 897 switch ( u8Strm)947 switch (pStream->u8Strm) 898 948 { 899 949 case AC97SOUNDSOURCE_PI_INDEX: … … 922 972 if (RT_SUCCESS(rc)) 923 973 { 924 pStream->State.cbFIFOW = _4K; /** @todo Make FIFOW size configurable. */925 pStream->State.offFIFOW = 0;926 pStream->State.au8FIFOW = (uint8_t *)RTMemAllocZ(pStream->State.cbFIFOW);927 if (!pStream->State.au8FIFOW)928 rc = VERR_NO_MEMORY;929 }930 931 if (RT_SUCCESS(rc))932 {933 974 if (streamCfg.uHz) 934 975 { 935 streamCfg.cChannels = 2; /** @todo Handle mono channels? */976 streamCfg.cChannels = 2; 936 977 streamCfg.enmFormat = PDMAUDIOFMT_S16; 937 978 streamCfg.enmEndianness = PDMAUDIOHOSTENDIANNESS; 938 979 939 rc = ichac97Stream InitEx(pThis, pStream, u8Strm, &streamCfg);980 rc = ichac97StreamOpenEx(pThis, pStream, &streamCfg); 940 981 } 941 982 else 942 { 943 /* If no frequency is given, disable the stream. */ 944 rc = ichac97StreamSetActive(pThis, pStream, false /* fActive */); 945 } 946 } 947 948 LogFlowFunc(("[SD%RU8] rc=%Rrc\n", u8Strm, rc)); 983 rc = VERR_INVALID_PARAMETER; 984 } 985 986 LogFlowFunc(("[SD%RU8] rc=%Rrc\n", pStream->u8Strm, rc)); 949 987 return rc; 950 988 } 951 989 952 static int ichac97StreamReInit(PAC97STATE pThis, PAC97STREAM pStrm) 953 { 954 return ichac97StreamInit(pThis, pStrm, pStrm->u8Strm); 990 static void ichac97StreamClose(PAC97STREAM pStream) 991 { 992 LogFlowFunc(("[SD%RU8]\n", pStream->u8Strm)); 993 } 994 995 /** 996 * Re-opens an AC'97 stream on the backend side with the current AC'97 mixer 997 * settings for this stream. 998 * 999 * @returns IPRT status code. 1000 * @param pThis AC'97 device state. 1001 * @param pStream Stream to re-open. 1002 */ 1003 static int ichac97StreamReOpen(PAC97STATE pThis, PAC97STREAM pStream) 1004 { 1005 LogFlowFunc(("[SD%RU8]\n", pStream->u8Strm)); 1006 1007 ichac97StreamClose(pStream); 1008 1009 return ichac97StreamOpen(pThis, pStream); 955 1010 } 956 1011 … … 1033 1088 break; 1034 1089 case PDMAUDIOMIXERCTL_FRONT: 1035 rc = AudioMixerSinkSetVolume(pThis->pSinkOut put,&Vol);1090 rc = AudioMixerSinkSetVolume(pThis->pSinkOut, &Vol); 1036 1091 break; 1037 1092 … … 1226 1281 * Write data to the mixer sink. 1227 1282 */ 1228 rc = AudioMixerSinkWrite(pThis->pSinkOut put, AUDMIXOP_COPY, pu8FIFOW, cbToRead, &cbWritten);1283 rc = AudioMixerSinkWrite(pThis->pSinkOut, AUDMIXOP_COPY, pu8FIFOW, cbToRead, &cbWritten); 1229 1284 if (RT_FAILURE(rc)) 1230 1285 break; … … 1290 1345 uint32_t cbWrittenToStream; 1291 1346 1292 int rc2 = AudioMixerSinkWrite(pThis->pSinkOut put, AUDMIXOP_COPY,1347 int rc2 = AudioMixerSinkWrite(pThis->pSinkOut, AUDMIXOP_COPY, 1293 1348 pThis->silence, cbToWrite, &cbWrittenToStream); 1294 1349 if (RT_SUCCESS(rc2)) … … 1355 1410 1356 1411 #ifndef VBOX_WITH_AUDIO_AC97_CALLBACKS 1412 #if 0 1413 static int ichac97TimerStart(PAC97STATE pThis) 1414 { 1415 /*int rc = RTCritSectEnter(&pThis->csTimer); 1416 if (RT_SUCCESS(rc))*/ 1417 { 1418 AssertPtr(pThis->pTimer); 1419 1420 const bool fIsActive = TMTimerIsActive(pThis->pTimer); 1421 1422 LogFunc(("cStreamsActive=%RU8, fIsActive=%RTbool\n", pThis->cStreamsActive, fIsActive)); 1423 1424 if (!fIsActive) /* Timer not started yet? */ 1425 { 1426 LogFunc(("Starting timer\n")); 1427 LogRel3(("AC97: Starting timer\n")); 1428 1429 /* Update current time timestamp. */ 1430 pThis->uTimerTS = TMTimerGet(pThis->pTimer); 1431 1432 /* Fire off timer. */ 1433 TMTimerSet(pThis->pTimer, TMTimerGet(pThis->pTimer) + pThis->cTimerTicks); 1434 } 1435 1436 /*int rc2 = RTCritSectLeave(&pThis->csTimer); 1437 if (RT_SUCCESS(rc)) 1438 rc = rc2;*/ 1439 } 1440 1441 return 0; 1442 } 1443 #endif 1444 1357 1445 static void ichac97TimerMaybeStart(PAC97STATE pThis) 1358 1446 { … … 1375 1463 1376 1464 /* Fire off timer. */ 1377 TMTimerSet(pThis->pTimer, TMTimerGet(pThis->pTimer) + pThis->cTimerTicks);1465 TMTimerSet(pThis->pTimer, 0 /* u64Expire */); 1378 1466 } 1379 1467 … … 1402 1490 AssertPtr(pThis); 1403 1491 1404 STAM_PROFILE_START(&pThis->StatTimer, a); 1405 1406 uint64_t cTicksNow = TMTimerGet(pTimer); 1407 1408 LogFlowFuncEnter(); 1409 1410 /* Update current time timestamp. */ 1411 pThis->uTimerTS = cTicksNow; 1412 1413 /* Flag indicating whether to kick the timer again for a 1414 * new data processing round. */ 1415 bool fKickTimer = false; 1416 1417 uint32_t cbToProcess; 1418 1419 int rc = AudioMixerSinkUpdate(pThis->pSinkLineIn); 1492 int rc = RTCritSectEnter(&pThis->csTimer); 1420 1493 if (RT_SUCCESS(rc)) 1421 1494 { 1422 cbToProcess = AudioMixerSinkGetReadable(pThis->pSinkLineIn); 1423 if (cbToProcess) 1424 rc = ichac97TransferAudio(pThis, &pThis->StreamLineIn, cbToProcess, NULL /* pcbProcessed */); 1425 1426 fKickTimer |= !!(AudioMixerSinkGetStatus(pThis->pSinkLineIn) & AUDMIXSINK_STS_DIRTY); 1427 } 1428 1429 rc = AudioMixerSinkUpdate(pThis->pSinkMicIn); 1430 if (RT_SUCCESS(rc)) 1431 { 1432 cbToProcess = AudioMixerSinkGetReadable(pThis->pSinkMicIn); 1433 if (cbToProcess) 1434 rc = ichac97TransferAudio(pThis, &pThis->StreamMicIn, cbToProcess, NULL /* pcbProcessed */); 1435 1436 fKickTimer |= !!(AudioMixerSinkGetStatus(pThis->pSinkMicIn) & AUDMIXSINK_STS_DIRTY); 1437 } 1438 1439 rc = AudioMixerSinkUpdate(pThis->pSinkOutput); 1440 if (RT_SUCCESS(rc)) 1441 { 1442 cbToProcess = AudioMixerSinkGetWritable(pThis->pSinkOutput); 1443 if (cbToProcess) 1444 rc = ichac97TransferAudio(pThis, &pThis->StreamOut, cbToProcess, NULL /* pcbProcessed */); 1445 1446 fKickTimer |= !!(AudioMixerSinkGetStatus(pThis->pSinkOutput) & AUDMIXSINK_STS_DIRTY); 1447 } 1448 1449 if ( ASMAtomicReadBool(&pThis->fTimerActive) 1450 || fKickTimer) 1451 { 1452 /* Kick the timer again. */ 1453 uint64_t cTicks = pThis->cTimerTicks; 1454 /** @todo adjust cTicks down by now much cbOutMin represents. */ 1455 TMTimerSet(pThis->pTimer, cTicksNow + cTicks); 1456 } 1457 1458 STAM_PROFILE_STOP(&pThis->StatTimer, a); 1495 STAM_PROFILE_START(&pThis->StatTimer, a); 1496 1497 uint64_t cTicksNow = TMTimerGet(pTimer); 1498 1499 /* Update current time timestamp. */ 1500 pThis->uTimerTS = cTicksNow; 1501 1502 /* Flag indicating whether to kick the timer again for the next DMA transfer or sink processing. */ 1503 bool fDoNextTransfer = false; 1504 1505 uint32_t cbToProcess; 1506 1507 rc = AudioMixerSinkUpdate(pThis->pSinkLineIn); 1508 if (RT_SUCCESS(rc)) 1509 { 1510 cbToProcess = AudioMixerSinkGetReadable(pThis->pSinkLineIn); 1511 if (cbToProcess) 1512 rc = ichac97TransferAudio(pThis, &pThis->StreamLineIn, cbToProcess, NULL /* pcbProcessed */); 1513 1514 if (AudioMixerSinkGetStatus(pThis->pSinkLineIn) & AUDMIXSINK_STS_DIRTY) 1515 fDoNextTransfer = true; 1516 } 1517 1518 rc = AudioMixerSinkUpdate(pThis->pSinkMicIn); 1519 if (RT_SUCCESS(rc)) 1520 { 1521 cbToProcess = AudioMixerSinkGetReadable(pThis->pSinkMicIn); 1522 if (cbToProcess) 1523 rc = ichac97TransferAudio(pThis, &pThis->StreamMicIn, cbToProcess, NULL /* pcbProcessed */); 1524 1525 if (AudioMixerSinkGetStatus(pThis->pSinkMicIn) & AUDMIXSINK_STS_DIRTY) 1526 fDoNextTransfer = true; 1527 } 1528 1529 rc = AudioMixerSinkUpdate(pThis->pSinkOut); 1530 if (RT_SUCCESS(rc)) 1531 { 1532 cbToProcess = AudioMixerSinkGetWritable(pThis->pSinkOut); 1533 if (cbToProcess) 1534 rc = ichac97TransferAudio(pThis, &pThis->StreamOut, cbToProcess, NULL /* pcbProcessed */); 1535 1536 if (AudioMixerSinkGetStatus(pThis->pSinkOut) & AUDMIXSINK_STS_DIRTY) 1537 fDoNextTransfer = true; 1538 } 1539 1540 if (fDoNextTransfer) 1541 { 1542 /* Kick the timer again. */ 1543 uint64_t cTicks = pThis->cTimerTicks; 1544 /** @todo adjust cTicks down by now much cbOutMin represents. */ 1545 TMTimerSet(pThis->pTimer, cTicksNow + cTicks); 1546 } 1547 else 1548 { 1549 LogFunc(("Stopping timer\n")); 1550 LogRel3(("AC97: Stopping timer\n")); 1551 } 1552 1553 STAM_PROFILE_STOP(&pThis->StatTimer, a); 1554 1555 int rc2 = RTCritSectLeave(&pThis->csTimer); 1556 if (RT_SUCCESS(rc)) 1557 rc2 = rc; 1558 } 1459 1559 } 1460 1560 #endif /* !VBOX_WITH_AUDIO_AC97_CALLBACKS */ … … 1466 1566 /* pcbProcessed is optional. */ 1467 1567 1468 Log3Func(("[SD%RU8] cbToProcess=%RU32\n", pStream->u8Strm, cbToProcess)); 1568 int rc = RTCritSectEnter(&pStream->CritSect); 1569 if (RT_FAILURE(rc)) 1570 return rc; 1571 1572 LogFunc(("[SD%RU8] cbToProcess=%RU32\n", pStream->u8Strm, cbToProcess)); 1469 1573 1470 1574 PAC97BMREGS pRegs = &pStream->Regs; … … 1487 1591 if (pcbProcessed) 1488 1592 *pcbProcessed = 0; 1593 1594 Log3Func(("[SD%RU8] Halted\n", pStream->u8Strm)); 1595 1596 rc = RTCritSectLeave(&pStream->CritSect); 1597 AssertRC(rc); 1598 1489 1599 return VINF_SUCCESS; 1490 1600 } … … 1494 1604 { 1495 1605 Log3Func(("[SD%RU8] BCIS set\n", pStream->u8Strm)); 1606 1496 1607 if (pcbProcessed) 1497 1608 *pcbProcessed = 0; 1609 1610 rc = RTCritSectLeave(&pStream->CritSect); 1611 AssertRC(rc); 1612 1498 1613 return VINF_SUCCESS; 1499 1614 } 1500 1501 int rc = VINF_SUCCESS;1502 1615 1503 1616 uint32_t cbLeft = RT_MIN((uint32_t)(pRegs->picb << 1), cbToProcess); … … 1619 1732 } 1620 1733 1734 int rc2 = RTCritSectLeave(&pStream->CritSect); 1735 AssertRC(rc2); 1736 1621 1737 if (RT_SUCCESS(rc)) 1622 1738 { … … 1641 1757 1642 1758 PAC97STREAM pStream = ichac97GetStreamFromID(pThis, AC97_PORT2IDX(uPortIdx)); 1643 PAC97BMREGS pRegs = pStream ? &pStream->Regs : NULL; 1759 PAC97BMREGS pRegs = NULL; 1760 1761 if (pStream) 1762 { 1763 pRegs = &pStream->Regs; 1764 1765 int rc2 = RTCritSectEnter(&pStream->CritSect); 1766 AssertRC(rc2); 1767 } 1768 1769 int rc = VINF_SUCCESS; 1644 1770 1645 1771 switch (cbVal) … … 1687 1813 case MC_SR: 1688 1814 /* Status Register (lower part) */ 1689 *pu32Val = pRegs->sr & 0xff; /** @todo r=andy Use RT_LO_U8. */1815 *pu32Val = RT_LO_U8(pRegs->sr); 1690 1816 Log3Func(("SRb[%d] -> %#x\n", AC97_PORT2IDX(uPortIdx), *pu32Val)); 1691 1817 break; … … 1774 1900 1775 1901 default: 1776 return VERR_IOM_IOPORT_UNUSED; 1777 } 1778 return VINF_SUCCESS; 1902 { 1903 AssertFailed(); 1904 rc = VERR_IOM_IOPORT_UNUSED; 1905 } 1906 } 1907 1908 if (pStream) 1909 { 1910 int rc2 = RTCritSectLeave(&pStream->CritSect); 1911 AssertRC(rc2); 1912 } 1913 1914 return rc; 1779 1915 } 1780 1916 … … 1792 1928 1793 1929 PAC97STREAM pStream = ichac97GetStreamFromID(pThis, AC97_PORT2IDX(uPortIdx)); 1794 PAC97BMREGS pRegs = pStream ? &pStream->Regs : NULL; 1930 PAC97BMREGS pRegs = NULL; 1931 1932 PAUDMIXSINK pSink = NULL; 1933 1934 if (pStream) 1935 { 1936 pRegs = &pStream->Regs; 1937 pSink = ichac97IndexToSink(pThis, pStream->u8Strm); 1938 AssertPtr(pSink); 1939 1940 int rc2 = RTCritSectEnter(&pStream->CritSect); 1941 AssertRC(rc2); 1942 } 1795 1943 1796 1944 switch (cbVal) … … 1800 1948 switch (uPortIdx) 1801 1949 { 1950 /* 1951 * Last Valid Index. 1952 */ 1802 1953 case PI_LVI: 1803 1954 case PO_LVI: 1804 1955 case MC_LVI: 1805 /* Last Valid Index */ 1806 if ((pRegs->cr & AC97_CR_RPBM) && (pRegs->sr & AC97_SR_DCH)) 1956 { 1957 if ( (pRegs->cr & AC97_CR_RPBM) 1958 && (pRegs->sr & AC97_SR_DCH)) 1807 1959 { 1808 1960 pRegs->sr &= ~(AC97_SR_DCH | AC97_SR_CELV); … … 1813 1965 } 1814 1966 pRegs->lvi = u32Val % 32; 1815 Log3Func(("LVI[%d] <- %#x\n", AC97_PORT2IDX(uPortIdx), u32Val)); 1816 break; 1967 Log3Func(("[SD%RU8] LVI <- %#x\n", pStream->u8Strm, u32Val)); 1968 break; 1969 } 1970 1971 /* 1972 * Control Registers. 1973 */ 1817 1974 case PI_CR: 1818 1975 case PO_CR: 1819 1976 case MC_CR: 1820 1977 { 1821 /* Control Register */1822 1978 if (u32Val & AC97_CR_RR) /* Busmaster reset */ 1823 1979 { … … 1829 1985 if (!(pRegs->cr & AC97_CR_RPBM)) 1830 1986 { 1831 ichac97Stream SetActive(pThis, pStream, false /* fActive */);1987 ichac97StreamEnable(pThis, pStream, false /* fActive */); 1832 1988 1833 1989 pRegs->sr |= AC97_SR_DCH; … … 1838 1994 pRegs->piv = (pRegs->piv + 1) % 32; 1839 1995 1996 pRegs->sr &= ~AC97_SR_DCH; 1997 1998 /* Fetch the initial BDLE descriptor. */ 1840 1999 ichac97StreamFetchBDLE(pThis, pStream); 1841 ichac97StreamSetActive(pThis, pStream, true /* fActive */); 1842 1843 pRegs->sr &= ~AC97_SR_DCH; 2000 2001 ichac97StreamEnable(pThis, pStream, true /* fActive */); 1844 2002 } 1845 2003 } 1846 Log3Func((" CR[%d] <- %#x (cr %#x)\n", AC97_PORT2IDX(uPortIdx), u32Val, pRegs->cr));2004 Log3Func(("[SD%RU8] CR <- %#x (cr %#x)\n", pStream->u8Strm, u32Val, pRegs->cr)); 1847 2005 break; 1848 2006 } 2007 2008 /* 2009 * Status Registers. 2010 */ 1849 2011 case PI_SR: 1850 2012 case PO_SR: 1851 2013 case MC_SR: 1852 /* Status Register */2014 { 1853 2015 pRegs->sr |= u32Val & ~(AC97_SR_RO_MASK | AC97_SR_WCLEAR_MASK); 1854 2016 ichac97StreamUpdateSR(pThis, pStream, pRegs->sr & ~(u32Val & AC97_SR_WCLEAR_MASK)); 1855 Log3Func(("SR[%d] <- %#x (sr %#x)\n", AC97_PORT2IDX(uPortIdx), u32Val, pRegs->sr)); 1856 break; 2017 Log3Func(("[SD%RU8] SR <- %#x (sr %#x)\n", pStream->u8Strm, u32Val, pRegs->sr)); 2018 break; 2019 } 2020 1857 2021 default: 1858 LogFunc(("U nabm writeb %#x <- %#x\n", Port, u32Val));2022 LogFunc(("Unimplemented: %#x <- %#x (Byte)\n", Port, u32Val)); 1859 2023 break; 1860 2024 } … … 1872 2036 pRegs->sr |= u32Val & ~(AC97_SR_RO_MASK | AC97_SR_WCLEAR_MASK); 1873 2037 ichac97StreamUpdateSR(pThis, pStream, pRegs->sr & ~(u32Val & AC97_SR_WCLEAR_MASK)); 1874 Log3Func((" SR[%d] <- %#x (sr %#x)\n", AC97_PORT2IDX(uPortIdx), u32Val, pRegs->sr));2038 Log3Func(("[SD%RU8] SR <- %#x (sr %#x)\n", pStream->u8Strm, u32Val, pRegs->sr)); 1875 2039 break; 1876 2040 default: 1877 LogFunc(("U nabm writew %#x <- %#x\n", Port, u32Val));2041 LogFunc(("Unimplemented: %#x <- %#x (Word)\n", Port, u32Val)); 1878 2042 break; 1879 2043 } … … 1890 2054 /* Buffer Descriptor list Base Address Register */ 1891 2055 pRegs->bdbar = u32Val & ~3; 1892 Log3Func((" BDBAR[%d]<- %#x (bdbar %#x)\n", AC97_PORT2IDX(uPortIdx), u32Val, pRegs->bdbar));2056 Log3Func(("[SD%RU8] BDBAR <- %#x (bdbar %#x)\n", AC97_PORT2IDX(uPortIdx), u32Val, pRegs->bdbar)); 1893 2057 break; 1894 2058 case AC97_GLOB_CNT: … … 1909 2073 break; 1910 2074 default: 1911 LogFunc(("U nabm writel %#x <- %#x\n", Port, u32Val));2075 LogFunc(("Unimplemented: %#x <- %#x (DWord)\n", Port, u32Val)); 1912 2076 break; 1913 2077 } … … 1919 2083 break; 1920 2084 } 2085 2086 if (pStream) 2087 { 2088 int rc2 = RTCritSectLeave(&pStream->CritSect); 2089 AssertRC(rc2); 2090 } 2091 1921 2092 return VINF_SUCCESS; 1922 2093 } … … 1929 2100 RT_NOREF(pDevIns); 1930 2101 PAC97STATE pThis = (PAC97STATE)pvUser; 2102 2103 int rc = VINF_SUCCESS; 1931 2104 1932 2105 switch (cbVal) … … 1966 2139 { 1967 2140 AssertFailed(); 1968 return VERR_IOM_IOPORT_UNUSED; 1969 } 1970 } 1971 return VINF_SUCCESS; 2141 rc = VERR_IOM_IOPORT_UNUSED; 2142 } 2143 } 2144 2145 return rc; 1972 2146 } 1973 2147 … … 2041 2215 { 2042 2216 ichac97MixerSet(pThis, AC97_PCM_Front_DAC_Rate, 48000); 2043 ichac97StreamRe Init(pThis, &pThis->StreamOut);2217 ichac97StreamReOpen(pThis, &pThis->StreamOut); 2044 2218 2045 2219 ichac97MixerSet(pThis, AC97_PCM_LR_ADC_Rate, 48000); 2046 ichac97StreamRe Init(pThis, &pThis->StreamLineIn);2220 ichac97StreamReOpen(pThis, &pThis->StreamLineIn); 2047 2221 } 2048 2222 if (!(u32Val & AC97_EACS_VRM)) 2049 2223 { 2050 2224 ichac97MixerSet(pThis, AC97_MIC_ADC_Rate, 48000); 2051 ichac97StreamRe Init(pThis, &pThis->StreamMicIn);2225 ichac97StreamReOpen(pThis, &pThis->StreamMicIn); 2052 2226 } 2053 2227 LogFunc(("Setting extended audio control to %#x\n", u32Val)); … … 2059 2233 ichac97MixerSet(pThis, index, u32Val); 2060 2234 LogFunc(("Set front DAC rate to %RU32\n", u32Val)); 2061 ichac97StreamRe Init(pThis, &pThis->StreamOut);2235 ichac97StreamReOpen(pThis, &pThis->StreamOut); 2062 2236 } 2063 2237 else … … 2069 2243 ichac97MixerSet(pThis, index, u32Val); 2070 2244 LogFunc(("Set MIC ADC rate to %RU32\n", u32Val)); 2071 ichac97StreamRe Init(pThis, &pThis->StreamMicIn);2245 ichac97StreamReOpen(pThis, &pThis->StreamMicIn); 2072 2246 } 2073 2247 else … … 2079 2253 ichac97MixerSet(pThis, index, u32Val); 2080 2254 LogFunc(("Set front LR ADC rate to %RU32\n", u32Val)); 2081 ichac97StreamRe Init(pThis, &pThis->StreamLineIn);2255 ichac97StreamReOpen(pThis, &pThis->StreamLineIn); 2082 2256 } 2083 2257 else … … 2148 2322 case AC97SOUNDSOURCE_MC_INDEX: return &pThis->StreamMicIn; 2149 2323 case AC97SOUNDSOURCE_PO_INDEX: return &pThis->StreamOut; 2150 default: break;2324 default: break; 2151 2325 } 2152 2326 … … 2200 2374 uint8_t active[AC97SOUNDSOURCE_LAST_INDEX]; 2201 2375 2202 active[AC97SOUNDSOURCE_PI_INDEX] = ichac97StreamIs Active(pThis, &pThis->StreamLineIn) ? 1 : 0;2203 active[AC97SOUNDSOURCE_PO_INDEX] = ichac97StreamIs Active(pThis, &pThis->StreamOut) ? 1 : 0;2204 active[AC97SOUNDSOURCE_MC_INDEX] = ichac97StreamIs Active(pThis, &pThis->StreamMicIn) ? 1 : 0;2376 active[AC97SOUNDSOURCE_PI_INDEX] = ichac97StreamIsEnabled(pThis, &pThis->StreamLineIn) ? 1 : 0; 2377 active[AC97SOUNDSOURCE_PO_INDEX] = ichac97StreamIsEnabled(pThis, &pThis->StreamOut) ? 1 : 0; 2378 active[AC97SOUNDSOURCE_MC_INDEX] = ichac97StreamIsEnabled(pThis, &pThis->StreamMicIn) ? 1 : 0; 2205 2379 2206 2380 SSMR3PutMem(pSSM, active, sizeof(active)); … … 2272 2446 ichac97MixerGet(pThis, AC97_Headphone_Volume_Mute)); 2273 2447 2274 int rc= ichac97StreamsInit(pThis);2275 if (RT_SUCCESS(rc ))2448 rc2 = ichac97StreamsInit(pThis); 2449 if (RT_SUCCESS(rc2)) 2276 2450 { 2277 2451 /** @todo r=andy Stream IDs are hardcoded to certain streams. */ 2278 rc = ichac97StreamSetActive(pThis, &pThis->StreamLineIn, RT_BOOL(uaStrmsActive[AC97SOUNDSOURCE_PI_INDEX]));2279 if (RT_SUCCESS(rc ))2280 rc = ichac97StreamSetActive(pThis, &pThis->StreamMicIn, RT_BOOL(uaStrmsActive[AC97SOUNDSOURCE_MC_INDEX]));2281 if (RT_SUCCESS(rc ))2282 rc = ichac97StreamSetActive(pThis, &pThis->StreamOut, RT_BOOL(uaStrmsActive[AC97SOUNDSOURCE_PO_INDEX]));2452 rc2 = ichac97StreamEnable(pThis, &pThis->StreamLineIn, RT_BOOL(uaStrmsActive[AC97SOUNDSOURCE_PI_INDEX])); 2453 if (RT_SUCCESS(rc2)) 2454 rc2 = ichac97StreamEnable(pThis, &pThis->StreamMicIn, RT_BOOL(uaStrmsActive[AC97SOUNDSOURCE_MC_INDEX])); 2455 if (RT_SUCCESS(rc2)) 2456 rc2 = ichac97StreamEnable(pThis, &pThis->StreamOut, RT_BOOL(uaStrmsActive[AC97SOUNDSOURCE_PO_INDEX])); 2283 2457 } 2284 2458 … … 2286 2460 pThis->last_samp = 0; 2287 2461 2288 LogFlowFuncLeaveRC(rc); 2289 return rc; 2462 return VINF_SUCCESS; 2290 2463 } 2291 2464 … … 2355 2528 2356 2529 /* 2357 * Stop any audio currently playing and/or recording.2358 */2359 AudioMixerSinkCtl(pThis->pSinkOutput, AUDMIXSINKCMD_DISABLE);2360 AudioMixerSinkCtl(pThis->pSinkMicIn, AUDMIXSINKCMD_DISABLE);2361 AudioMixerSinkCtl(pThis->pSinkLineIn, AUDMIXSINKCMD_DISABLE);2362 2363 /*2364 2530 * Reset all streams. 2365 2531 */ … … 2395 2561 Assert(RTListIsEmpty(&pThis->lstDrv)); 2396 2562 2397 LogFlowFuncLeave(); 2398 return VINF_SUCCESS; 2563 int rc; 2564 #ifndef VBOX_WITH_AUDIO_AC97_CALLBACKS 2565 rc = RTCritSectDelete(&pThis->csTimer); 2566 #else 2567 rc = VINF_SUCCESS; 2568 #endif 2569 2570 LogFlowFuncLeaveRC(rc); 2571 return rc; 2399 2572 } 2400 2573 … … 2712 2885 { 2713 2886 /* Add all required audio sinks. */ 2714 int rc2 = AudioMixerCreateSink(pThis->pMixer, "[Playback] PCM Output", AUDMIXSINKDIR_OUTPUT, &pThis->pSinkOut put);2887 int rc2 = AudioMixerCreateSink(pThis->pMixer, "[Playback] PCM Output", AUDMIXSINKDIR_OUTPUT, &pThis->pSinkOut); 2715 2888 AssertRC(rc2); 2716 2889 … … 2731 2904 if (RT_SUCCESS(rc)) 2732 2905 { 2733 /* Start the emulation timer. */ 2734 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, ichac97Timer, pThis, 2735 TMTIMER_FLAGS_NO_CRIT_SECT, "DevIchAc97", &pThis->pTimer); 2736 AssertRCReturn(rc, rc); 2737 2906 rc = RTCritSectInit(&pThis->csTimer); 2738 2907 if (RT_SUCCESS(rc)) 2739 2908 { 2740 pThis->cTimerTicks = TMTimerGetFreq(pThis->pTimer) / uTimerHz; 2741 pThis->uTimerTS = TMTimerGet(pThis->pTimer); 2742 LogFunc(("Timer ticks=%RU64 (%RU16 Hz)\n", pThis->cTimerTicks, uTimerHz)); 2743 2744 ichac97TimerMaybeStart(pThis); 2909 /* Start the emulation timer. */ 2910 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, ichac97Timer, pThis, 2911 TMTIMER_FLAGS_NO_CRIT_SECT, "DevIchAc97", &pThis->pTimer); 2912 AssertRCReturn(rc, rc); 2913 2914 if (RT_SUCCESS(rc)) 2915 { 2916 pThis->cTimerTicks = TMTimerGetFreq(pThis->pTimer) / uTimerHz; 2917 pThis->uTimerTS = TMTimerGet(pThis->pTimer); 2918 LogFunc(("Timer ticks=%RU64 (%RU16 Hz)\n", pThis->cTimerTicks, uTimerHz)); 2919 } 2745 2920 } 2746 2921 }
Note:
See TracChangeset
for help on using the changeset viewer.