Changeset 61050 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- May 19, 2016 3:26:50 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 107316
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/AudioMixer.cpp
r60941 r61050 37 37 #include "AudioMixer.h" 38 38 #include "AudioMixBuffer.h" 39 #include "DrvAudio.h" 39 40 40 41 #include <VBox/vmm/pdm.h> … … 101 102 } 102 103 104 int AudioMixerCreateStream(PAUDIOMIXER pMixer, 105 PPDMIAUDIOCONNECTOR pConn, PPDMAUDIOSTREAMCFG pCfg, uint32_t fFlags, PAUDMIXSTREAM *ppStream) 106 { 107 AssertPtrReturn(pMixer, VERR_INVALID_POINTER); 108 AssertPtrReturn(pConn, VERR_INVALID_POINTER); 109 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 110 /** @todo Validate fFlags. */ 111 /* ppStream is optional. */ 112 113 PAUDMIXSTREAM pMixStream = (PAUDMIXSTREAM)RTMemAllocZ(sizeof(AUDMIXSTREAM)); 114 if (!pMixStream) 115 return VERR_NO_MEMORY; 116 117 pMixStream->pszName = RTStrDup(pCfg->szName); 118 if (!pMixStream->pszName) 119 { 120 RTMemFree(pMixStream); 121 return VERR_NO_MEMORY; 122 } 123 124 LogFlowFunc(("[%s]: fFlags=0x%x (enmDir=%ld, %s, %RU8 channels, %RU32Hz)\n", 125 pMixer->pszName, fFlags, pCfg->enmDir, DrvAudioAudFmtToStr(pCfg->enmFormat), pCfg->cChannels, pCfg->uHz)); 126 127 int rc; 128 if (pCfg->enmDir == PDMAUDIODIR_IN) 129 { 130 PPDMAUDIOGSTSTRMIN pGstStrm; 131 rc = pConn->pfnCreateIn(pConn, pCfg, &pGstStrm); 132 if (RT_SUCCESS(rc)) 133 { 134 pMixStream->InOut.pIn = pGstStrm; 135 136 /* Increase the stream's reference count to let others know 137 * we're reyling on it to be around now. */ 138 pConn->pfnAddRefIn(pConn, pGstStrm); 139 } 140 } 141 else if (pCfg->enmDir == PDMAUDIODIR_OUT) 142 { 143 PPDMAUDIOGSTSTRMOUT pGstStrm; 144 rc = pConn->pfnCreateOut(pConn, pCfg, &pGstStrm); 145 if (RT_SUCCESS(rc)) 146 { 147 pMixStream->InOut.pOut = pGstStrm; 148 149 /* Increase the stream's reference count to let others know 150 * we're reyling on it to be around now. */ 151 pConn->pfnAddRefOut(pConn, pGstStrm); 152 } 153 } 154 else 155 { 156 AssertMsgFailed(("Direction not implemented\n")); 157 rc = VERR_NOT_IMPLEMENTED; 158 } 159 160 if (RT_SUCCESS(rc)) 161 { 162 pMixStream->fFlags = fFlags; 163 pMixStream->enmDir = pCfg->enmDir; 164 pMixStream->pConn = pConn; 165 166 if (ppStream) 167 *ppStream = pMixStream; 168 } 169 else if (pMixStream) 170 { 171 RTStrFree(pMixStream->pszName); 172 pMixStream->pszName = NULL; 173 174 RTMemFree(pMixStream); 175 pMixStream = NULL; 176 } 177 178 return rc; 179 } 180 103 181 int AudioMixerCreate(const char *pszName, uint32_t uFlags, PAUDIOMIXER *ppMixer) 104 182 { … … 191 269 AssertPtrReturnVoid(pMixer); 192 270 193 LogFlowFunc((" %s: Invalidating ...\n", pMixer->pszName));271 LogFlowFunc(("[%s]: Invalidating ...\n", pMixer->pszName)); 194 272 195 273 /* Propagate new master volume to all connected sinks. */ … … 219 297 pMixer->cSinks--; 220 298 221 LogFlowFunc((" %s: pSink=%s, cSinks=%RU8\n",299 LogFlowFunc(("[%s]: pSink=%s, cSinks=%RU8\n", 222 300 pMixer->pszName, pSink->pszName, pMixer->cSinks)); 223 301 } … … 248 326 pMixer->VolMaster = *pVol; 249 327 250 LogFlowFunc((" %s: lVol=%RU32, rVol=%RU32 => fMuted=%RTbool, lVol=%RU32, rVol=%RU32\n",328 LogFlowFunc(("[%s]: lVol=%RU32, rVol=%RU32 => fMuted=%RTbool, lVol=%RU32, rVol=%RU32\n", 251 329 pMixer->pszName, pVol->uLeft, pVol->uRight, 252 330 pMixer->VolMaster.fMuted, pMixer->VolMaster.uLeft, pMixer->VolMaster.uRight)); … … 256 334 } 257 335 258 /***************************************************************************** 336 /********************************************************************************************************************************* 259 337 * Mixer Sink implementation. 260 ***************************************************************************** /338 ********************************************************************************************************************************/ 261 339 262 340 int AudioMixerSinkAddStream(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream) … … 273 351 pSink->cStreams++; 274 352 275 LogFlowFunc((" %s: cStreams=%RU8\n", pSink->pszName, pSink->cStreams));353 LogFlowFunc(("[%s]: cStreams=%RU8\n", pSink->pszName, pSink->cStreams)); 276 354 277 355 return VINF_SUCCESS; … … 312 390 } 313 391 314 LogFlowFunc((" %s: enmCmd=%ld, rc=%Rrc\n", pSink->pszName, enmCmd, rc));392 LogFlowFunc(("[%s]: enmCmd=%ld, rc=%Rrc\n", pSink->pszName, enmCmd, rc)); 315 393 return rc; 316 394 } … … 384 462 } 385 463 464 bool AudioMixerSinkHasData(PAUDMIXSINK pSink) 465 { 466 if (!pSink) 467 return false; 468 469 /* If the dirty flag is set, there is unprocessed data in the sink. */ 470 return (pSink->fFlags & AUDMIXSINK_FLAG_DIRTY); 471 } 472 386 473 int AudioMixerSinkRead(PAUDMIXSINK pSink, AUDMIXOP enmOp, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 387 474 { … … 442 529 RTMemFree(pvMixBuf); 443 530 444 Log3Func((" %s: cbRead=%RU32, rc=%Rrc\n", pSink->pszName, cbRead, rc));531 Log3Func(("[%s]: cbRead=%RU32, rc=%Rrc\n", pSink->pszName, cbRead, rc)); 445 532 return rc; 446 533 } … … 460 547 ? pStream->InOut.pIn->MixBuf.pszName : pStream->InOut.pOut->MixBuf.pszName; 461 548 462 LogFlowFunc((" %s: (Stream = %s), cStreams=%RU8\n",549 LogFlowFunc(("[%s]: (Stream = %s), cStreams=%RU8\n", 463 550 pSink->pszName, pszStream ? pszStream : "<Unnamed>", pSink->cStreams)); 464 551 #endif … … 500 587 AssertPtrReturn(pPCMProps, VERR_INVALID_POINTER); 501 588 589 if (DrvAudioPCMPropsAreEqual(&pSink->PCMProps, pPCMProps)) /* Bail out early if PCM properties are equal. */ 590 return VINF_SUCCESS; 591 592 if (pSink->PCMProps.uHz) 593 LogFlowFunc(("[%s]: Old format: %RU8 bit, %RU8 channels, %RU32Hz\n", 594 pSink->pszName, pSink->PCMProps.cBits, pSink->PCMProps.cChannels, pSink->PCMProps.uHz)); 595 502 596 memcpy(&pSink->PCMProps, pPCMProps, sizeof(PDMPCMPROPS)); 503 597 598 LogFlowFunc(("[%s]: New format %RU8 bit, %RU8 channels, %RU32Hz\n", 599 pSink->pszName, pSink->PCMProps.cBits, pSink->PCMProps.cChannels, pSink->PCMProps.uHz)); 600 601 #if 0 504 602 PAUDMIXSTREAM pStream; 505 603 RTListForEach(&pSink->lstStreams, pStream, AUDMIXSTREAM, Node) … … 507 605 /** @todo Invalidate mix buffers! */ 508 606 } 607 #endif 509 608 510 609 return VINF_SUCCESS; … … 524 623 AssertPtr(pSink->pParent); 525 624 526 LogFlowFunc((" %s: fMuted=%RTbool, lVol=%RU32, rVol=%RU32\n", pSink->pszName, pVol->fMuted, pVol->uLeft, pVol->uRight));625 LogFlowFunc(("[%s]: fMuted=%RTbool, lVol=%RU32, rVol=%RU32\n", pSink->pszName, pVol->fMuted, pVol->uLeft, pVol->uRight)); 527 626 528 627 pSink->Volume = *pVol; … … 531 630 } 532 631 533 void AudioMixerSinkTimerUpdate(PAUDMIXSINK pSink, uint64_t cTi cksPerSec, uint64_t cTicksElapsed, uint32_t *pcbData)632 void AudioMixerSinkTimerUpdate(PAUDMIXSINK pSink, uint64_t cTimerTicks, uint64_t cTicksElapsed, uint32_t *pcbData) 534 633 { 535 634 AssertPtrReturnVoid(pSink); 536 635 /* pcbData is optional. */ 537 636 538 uint32_t cSamplesMin = (uint32_t)((2 * cTicksElapsed * pSink->PCMProps.uHz + cTicksPerSec) / cTicksPerSec / 2); 637 /* Note: cTimerTicks / cTicksElapsed = Hz elapsed. */ 638 639 LogFlowFunc(("[%s]: cTimerTicks=%RU64, cTicksElapsed=%RU64\n", pSink->pszName, cTimerTicks, cTicksElapsed)); 640 641 //uint32_t cSamplesMin = (uint32_t)((2 * cTicksElapsed * pSink->PCMProps.uHz + cTimerTicks) / cTimerTicks / 2); 642 uint32_t cSamplesMin = (cTicksElapsed / pSink->PCMProps.uHz) * pSink->PCMProps.cChannels; 539 643 uint32_t cbSamplesMin = cSamplesMin << pSink->PCMProps.cShift; 540 644 541 LogFlowFunc(("%s: cbSamplesMin=%RU32\n", pSink->pszName, cbSamplesMin)); 645 Assert((cbSamplesMin % 2 == 0)); 646 647 LogFlowFunc(("[%s]: cSamplesMin=%RU32 (%RU32 bytes, %RU32Hz)\n", pSink->pszName, cSamplesMin, cbSamplesMin, pSink->PCMProps.uHz)); 542 648 543 649 audioMixerSinkUpdateInternal(pSink); … … 551 657 AssertPtrReturn(pSink, VERR_INVALID_POINTER); 552 658 659 int rc = VINF_SUCCESS; 660 553 661 PAUDMIXSTREAM pStream; 554 662 RTListForEach(&pSink->lstStreams, pStream, AUDMIXSTREAM, Node) 555 663 { 556 uint32_t cbIn, cbOut;557 uint32_t cSamplesLive;558 int rc2 = pStream->pConn->pfnQueryStatus(pStream->pConn,559 &cbIn, &cbOut, &cSamplesLive);560 #ifdef DEBUG561 if ( cbIn562 || cbOut563 || cSamplesLive)564 {565 Log3Func(("%s: cbIn=%RU32, cbOut=%RU32, cSamplesLive=%RU32, rc2=%Rrc\n",566 pSink->pszName, cbIn, cbOut, cSamplesLive, rc2));567 }568 #endif569 664 if (pSink->enmDir == AUDMIXSINKDIR_OUTPUT) 570 665 { 571 rc2 = pStream->pConn->pfnPlayOut(pStream->pConn, NULL /* pcSamplesPlayed */); 572 if (RT_FAILURE(rc2)) 573 Log3Func(("rc2=%Rrc\n", rc2)); 666 uint32_t cSamplesLive; 667 uint32_t cSamplesPlayed = 0; 668 rc = pStream->pConn->pfnGetDataOut(pStream->pConn, NULL /* cbOut */, &cSamplesLive); 669 if ( RT_SUCCESS(rc) 670 && cSamplesLive) 671 { 672 rc = pStream->pConn->pfnPlayOut(pStream->pConn, &cSamplesPlayed); 673 } 674 675 if (RT_SUCCESS(rc)) 676 { 677 Assert(cSamplesLive >= cSamplesPlayed); 678 if (cSamplesLive - cSamplesPlayed) /* Some live samples left? */ 679 pSink->fFlags |= AUDMIXSINK_FLAG_DIRTY; 680 else 681 pSink->fFlags &= ~AUDMIXSINK_FLAG_DIRTY; 682 } 683 684 Log3Func(("[%s]: fFlags=0x%x, cSamplesLive=%RU32, rc=%Rrc\n", pSink->pszName, pSink->fFlags, cSamplesLive, rc)); 574 685 } 575 686 else if (pSink->enmDir == AUDMIXSINKDIR_INPUT) 576 687 { 577 //int rc2 = pStream->pConn->pfnCaptureIn(pStream->pConn, NULL /* pcSamplesCaptured */); 578 //Log3Func(("rc2=%Rrc\n", rc2)); 688 uint32_t cbIn; 689 rc = pStream->pConn->pfnGetDataIn(pStream->pConn, &cbIn); 690 if ( RT_SUCCESS(rc) 691 && cbIn) 692 { 693 /** @todo Implement this! */ 694 // int rc2 = pStream->pConn->pfnCaptureIn(pStream->pConn, NULL /* pcSamplesCaptured */); 695 // Log3Func(("rc2=%Rrc\n", rc2)); 696 } 697 698 if (RT_SUCCESS(rc)) 699 { 700 if (cbIn) /* Some inpput data available? */ 701 pSink->fFlags |= AUDMIXSINK_FLAG_DIRTY; 702 else 703 pSink->fFlags &= ~AUDMIXSINK_FLAG_DIRTY; 704 } 705 706 Log3Func(("[%s]: fFlags=0x%x, cbIn=%RU32, rc=%Rrc\n", pSink->pszName, pSink->fFlags, cbIn, rc)); 579 707 } 580 708 else 709 { 710 rc = VERR_NOT_IMPLEMENTED; 581 711 AssertMsgFailed(("Direction not implemented\n")); 582 } 583 584 return VINF_SUCCESS; 712 } 713 } 714 715 return rc; 585 716 } 586 717 … … 597 728 LogFlowFunc(("Master fMuted=%RTbool, lVol=%RU32, rVol=%RU32\n", 598 729 pVolMaster->fMuted, pVolMaster->uLeft, pVolMaster->uRight)); 599 LogFlowFunc((" %s: fMuted=%RTbool, lVol=%RU32, rVol=%RU32\n",730 LogFlowFunc(("[%s]: fMuted=%RTbool, lVol=%RU32, rVol=%RU32\n", 600 731 pSink->pszName, pSink->Volume.fMuted, pSink->Volume.uLeft, pSink->Volume.uRight)); 601 732 … … 656 787 } 657 788 658 /***************************************************************************** 789 /********************************************************************************************************************************* 659 790 * Mixer Stream implementation. 660 ***************************************************************************** /791 ********************************************************************************************************************************/ 661 792 662 793 int AudioMixerStreamCtl(PAUDMIXSTREAM pStream, PDMAUDIOSTREAMCMD enmCmd, uint32_t fCtl) … … 702 833 } 703 834 704 int AudioMixerStreamCreate(PPDMIAUDIOCONNECTOR pConn, PPDMAUDIOSTREAMCFG pCfg, uint32_t fFlags, PAUDMIXSTREAM *ppStream)705 {706 AssertPtrReturn(pConn, VERR_INVALID_POINTER);707 AssertPtrReturn(pCfg, VERR_INVALID_POINTER);708 /** @todo Validate fFlags. */709 /* ppStream is optional. */710 711 PAUDMIXSTREAM pMixStream = (PAUDMIXSTREAM)RTMemAllocZ(sizeof(AUDMIXSTREAM));712 if (!pMixStream)713 return VERR_NO_MEMORY;714 715 pMixStream->pszName = RTStrDup(pCfg->szName);716 if (!pMixStream->pszName)717 {718 RTMemFree(pMixStream);719 return VERR_NO_MEMORY;720 }721 722 int rc;723 if (pCfg->enmDir == PDMAUDIODIR_IN)724 {725 PPDMAUDIOGSTSTRMIN pGstStrm;726 rc = pConn->pfnCreateIn(pConn, pCfg, &pGstStrm);727 if (RT_SUCCESS(rc))728 {729 pMixStream->InOut.pIn = pGstStrm;730 731 /* Increase the stream's reference count to let others know732 * we're reyling on it to be around now. */733 pConn->pfnAddRefIn(pConn, pGstStrm);734 }735 }736 else if (pCfg->enmDir == PDMAUDIODIR_OUT)737 {738 PPDMAUDIOGSTSTRMOUT pGstStrm;739 rc = pConn->pfnCreateOut(pConn, pCfg, &pGstStrm);740 if (RT_SUCCESS(rc))741 {742 pMixStream->InOut.pOut = pGstStrm;743 744 /* Increase the stream's reference count to let others know745 * we're reyling on it to be around now. */746 pConn->pfnAddRefOut(pConn, pGstStrm);747 }748 }749 else750 rc = VERR_NOT_SUPPORTED;751 752 if (RT_SUCCESS(rc))753 {754 pMixStream->fFlags = fFlags;755 pMixStream->enmDir = pCfg->enmDir;756 pMixStream->pConn = pConn;757 758 if (ppStream)759 *ppStream = pMixStream;760 }761 else if (pMixStream)762 {763 RTStrFree(pMixStream->pszName);764 pMixStream->pszName = NULL;765 766 RTMemFree(pMixStream);767 pMixStream = NULL;768 }769 770 return rc;771 }772 773 835 static void audioMixerStreamDestroyInternal(PAUDMIXSTREAM pStream) 774 836 { … … 832 894 return false; 833 895 896 bool fIsActive; 897 switch (pStream->enmDir) 898 { 899 case PDMAUDIODIR_IN: 900 { 901 fIsActive = pStream->pConn->pfnIsActiveIn(pStream->pConn, pStream->InOut.pIn); 902 break; 903 } 904 905 case PDMAUDIODIR_OUT: 906 { 907 fIsActive = pStream->pConn->pfnIsActiveOut(pStream->pConn, pStream->InOut.pOut); 908 break; 909 } 910 911 default: 912 fIsActive = false; 913 AssertMsgFailed(("Not implemented\n")); 914 break; 915 } 916 917 return fIsActive; 918 } 919 920 bool AudioMixerStreamIsValid(PAUDMIXSTREAM pStream) 921 { 922 if (!pStream) 923 return false; 924 834 925 bool fIsValid; 835 926 switch (pStream->enmDir) … … 837 928 case PDMAUDIODIR_IN: 838 929 { 839 fIsValid = pStream->pConn->pfnIs ActiveIn(pStream->pConn, pStream->InOut.pIn);930 fIsValid = pStream->pConn->pfnIsValidIn(pStream->pConn, pStream->InOut.pIn); 840 931 break; 841 932 } … … 843 934 case PDMAUDIODIR_OUT: 844 935 { 845 fIsValid = pStream->pConn->pfnIs ActiveOut(pStream->pConn, pStream->InOut.pOut);936 fIsValid = pStream->pConn->pfnIsValidOut(pStream->pConn, pStream->InOut.pOut); 846 937 break; 847 938 } … … 856 947 } 857 948 858 bool AudioMixerStreamIsValid(PAUDMIXSTREAM pStream)859 {860 if (!pStream)861 return false;862 863 bool fIsValid;864 switch (pStream->enmDir)865 {866 case PDMAUDIODIR_IN:867 {868 fIsValid = pStream->pConn->pfnIsValidIn(pStream->pConn, pStream->InOut.pIn);869 break;870 }871 872 case PDMAUDIODIR_OUT:873 {874 fIsValid = pStream->pConn->pfnIsValidOut(pStream->pConn, pStream->InOut.pOut);875 break;876 }877 878 default:879 fIsValid = false;880 AssertMsgFailed(("Not implemented\n"));881 break;882 }883 884 return fIsValid;885 }886 -
trunk/src/VBox/Devices/Audio/AudioMixer.h
r60941 r61050 69 69 } AUDMIXSTREAM, *PAUDMIXSTREAM; 70 70 71 /** No flags specified. */ 72 #define AUDMIXSINK_FLAG_NONE 0 73 /** Dirty flag. */ 74 #define AUDMIXSINK_FLAG_DIRTY RT_BIT(0) 75 71 76 /** 72 77 * Audio mixer sink direction. … … 113 118 * if this sink handles input or output. */ 114 119 AUDMIXSINKDIR enmDir; 120 /** Sink flags of type AUDMIXSINK_FLAG_. */ 121 uint32_t fFlags; 115 122 /** The sink's PCM format. */ 116 123 PDMPCMPROPS PCMProps; … … 145 152 int AudioMixerCreate(const char *pszName, uint32_t uFlags, PAUDIOMIXER *ppMixer); 146 153 int AudioMixerCreateSink(PAUDIOMIXER pMixer, const char *pszName, AUDMIXSINKDIR enmDir, PAUDMIXSINK *ppSink); 154 int AudioMixerCreateStream(PAUDIOMIXER pMixer, PPDMIAUDIOCONNECTOR pConnector, PPDMAUDIOSTREAMCFG pCfg, uint32_t fFlags, PAUDMIXSTREAM *ppStream); 147 155 void AudioMixerDestroy(PAUDIOMIXER pMixer); 148 156 int AudioMixerGetDeviceFormat(PAUDIOMIXER pMixer, PPDMAUDIOSTREAMCFG pCfg); … … 159 167 PAUDMIXSTREAM AudioMixerSinkGetStream(PAUDMIXSINK pSink, uint8_t uIndex); 160 168 uint8_t AudioMixerSinkGetStreamCount(PAUDMIXSINK pSink); 169 bool AudioMixerSinkHasData(PAUDMIXSINK pSink); 161 170 int AudioMixerSinkRead(PAUDMIXSINK pSink, AUDMIXOP enmOp, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead); 162 171 void AudioMixerSinkRemoveStream(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream); … … 164 173 int AudioMixerSinkSetFormat(PAUDMIXSINK pSink, PPDMPCMPROPS pPCMProps); 165 174 int AudioMixerSinkSetVolume(PAUDMIXSINK pSink, PPDMAUDIOVOLUME pVol); 166 void AudioMixerSinkTimerUpdate(PAUDMIXSINK pSink, uint64_t cTi cksPerSec, uint64_t cTicksElapsed, uint32_t *pcbData);175 void AudioMixerSinkTimerUpdate(PAUDMIXSINK pSink, uint64_t cTimerTicks, uint64_t cTicksElapsed, uint32_t *pcbData); 167 176 int AudioMixerSinkWrite(PAUDMIXSINK pSink, AUDMIXOP enmOp, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten); 168 177 int AudioMixerSinkUpdate(PAUDMIXSINK pSink); 169 178 170 int AudioMixerStreamCreate(PPDMIAUDIOCONNECTOR pConnector, PPDMAUDIOSTREAMCFG pCfg, uint32_t fFlags, PAUDMIXSTREAM *ppStream);171 179 int AudioMixerStreamCtl(PAUDMIXSTREAM pStream, PDMAUDIOSTREAMCMD enmCmd, uint32_t fCtl); 172 180 void AudioMixerStreamDestroy(PAUDMIXSTREAM pStream); -
trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
r60942 r61050 27 27 #include <iprt/assert.h> 28 28 #ifdef IN_RING3 29 # ifdef DEBUG 30 # include <iprt/file.h> 31 # endif 29 32 # include <iprt/mem.h> 30 33 # include <iprt/string.h> … … 371 374 uint32_t Padding0; 372 375 # endif 376 /** Flag indicating whether the timer is active or not. */ 377 bool fTimerActive; 378 uint8_t u8Padding1[7]; 373 379 /** The timer interval for pumping data thru the LUN drivers in timer ticks. */ 374 380 uint64_t cTimerTicks; … … 547 553 } 548 554 549 LogFlowFunc(("u8Strm=%RU8, fActive=%RTbool, cStreamsActive=%RU8\n", pStream->u8Strm, fActive, pThis->cStreamsActive)); 550 551 return AudioMixerSinkCtl(ichac97IndexToSink(pThis, pStream->u8Strm), 552 fActive ? AUDMIXSINKCMD_ENABLE : AUDMIXSINKCMD_DISABLE); 555 int rc = AudioMixerSinkCtl(ichac97IndexToSink(pThis, pStream->u8Strm), 556 fActive ? AUDMIXSINKCMD_ENABLE : AUDMIXSINKCMD_DISABLE); 557 558 LogFlowFunc(("u8Strm=%RU8, fActive=%RTbool, cStreamsActive=%RU8, rc=%Rrc\n", 559 pStream->u8Strm, fActive, pThis->cStreamsActive, rc)); 560 if (rc == VERR_AUDIO_STREAM_PENDING_DISABLE) 561 { 562 LogFlowFunc(("On pending disable\n")); 563 rc = VINF_SUCCESS; 564 } 565 566 return rc; 553 567 } 554 568 … … 743 757 pStrmIn->pMixStrm = NULL; 744 758 745 int rc2 = AudioMixer StreamCreate(pDrv->pConnector, pCfg, 0 /* fFlags */ , &pStrmIn->pMixStrm);759 int rc2 = AudioMixerCreateStream(pThis->pMixer, pDrv->pConnector, pCfg, 0 /* fFlags */ , &pStrmIn->pMixStrm); 746 760 if (RT_SUCCESS(rc2)) 747 761 { … … 788 802 pDrv->Out.pMixStrm = NULL; 789 803 790 int rc2 = AudioMixer StreamCreate(pDrv->pConnector, pCfg, 0 /* fFlags */, &pDrv->Out.pMixStrm);804 int rc2 = AudioMixerCreateStream(pThis->pMixer, pDrv->pConnector, pCfg, 0 /* fFlags */, &pDrv->Out.pMixStrm); 791 805 if (RT_SUCCESS(rc2)) 792 806 { … … 876 890 if (RT_SUCCESS(rc)) 877 891 { 878 pStream->State.cbFIFOW = 256; /** @todo Make FIFOW size configurable. */892 pStream->State.cbFIFOW = _4K; /** @todo Make FIFOW size configurable. */ 879 893 pStream->State.offFIFOW = 0; 880 894 pStream->State.au8FIFOW = (uint8_t *)RTMemAllocZ(pStream->State.cbFIFOW); … … 1158 1172 PDMDevHlpPhysRead(pDevIns, addr, pu8FIFOW, cbToRead); /** @todo r=andy Check rc? */ 1159 1173 1174 #if defined (RT_OS_LINUX) && defined(DEBUG_andy) 1175 RTFILE fh; 1176 RTFileOpen(&fh, "/tmp/ac97WriteAudio.pcm", 1177 RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 1178 RTFileWrite(fh, pu8FIFOW, cbToRead, NULL); 1179 RTFileClose(fh); 1180 #endif 1160 1181 /* 1161 1182 * Write data to the mixer sink. … … 1313 1334 return; 1314 1335 1336 /* Set timer flag. */ 1337 ASMAtomicXchgBool(&pThis->fTimerActive, true); 1338 1339 /* Update current time timestamp. */ 1340 pThis->uTimerTS = TMTimerGet(pThis->pTimer); 1341 1315 1342 /* Fire off timer. */ 1316 1343 TMTimerSet(pThis->pTimer, TMTimerGet(pThis->pTimer) + pThis->cTimerTicks); … … 1327 1354 return; 1328 1355 1329 int rc2 = TMTimerStop(pThis->pTimer);1330 A ssertRC(rc2);1356 /* Set timer flag. */ 1357 ASMAtomicXchgBool(&pThis->fTimerActive, false); 1331 1358 } 1332 1359 … … 1341 1368 uint64_t cTicksNow = TMTimerGet(pTimer); 1342 1369 uint64_t cTicksElapsed = cTicksNow - pThis->uTimerTS; 1343 uint64_t cTicksPerSec = TMTimerGetFreq(pTimer); 1344 1370 1371 /* Update current time timestamp. */ 1345 1372 pThis->uTimerTS = cTicksNow; 1346 1373 1347 1374 uint32_t cbLineIn; 1348 AudioMixerSinkTimerUpdate(pThis->pSinkLineIn, cTicksPerSec, cTicksElapsed, &cbLineIn);1375 AudioMixerSinkTimerUpdate(pThis->pSinkLineIn, pThis->cTimerTicks, cTicksElapsed, &cbLineIn); 1349 1376 if (cbLineIn) 1350 ichac97TransferAudio(pThis, &pThis->StreamLineIn, cbLineIn); /** @todo Add rc! */1377 ichac97TransferAudio(pThis, &pThis->StreamLineIn, cbLineIn); 1351 1378 1352 1379 uint32_t cbMicIn; 1353 AudioMixerSinkTimerUpdate(pThis->pSinkMicIn , cTicksPerSec, cTicksElapsed, &cbMicIn); 1380 AudioMixerSinkTimerUpdate(pThis->pSinkMicIn , pThis->cTimerTicks, cTicksElapsed, &cbMicIn); 1381 if (cbMicIn) 1382 ichac97TransferAudio(pThis, &pThis->StreamMicIn, cbMicIn); 1354 1383 1355 1384 uint32_t cbOut; 1356 AudioMixerSinkTimerUpdate(pThis->pSinkOutput, cTicksPerSec, cTicksElapsed, &cbOut);1385 AudioMixerSinkTimerUpdate(pThis->pSinkOutput, pThis->cTimerTicks, cTicksElapsed, &cbOut); 1357 1386 if (cbOut) 1358 ichac97TransferAudio(pThis, &pThis->StreamOut, cbOut); /** @todo Add rc! */ 1359 1360 /* Kick the timer again. */ 1361 uint64_t cTicks = pThis->cTimerTicks; 1362 /** @todo adjust cTicks down by now much cbOutMin represents. */ 1363 TMTimerSet(pThis->pTimer, cTicksNow + cTicks); 1387 ichac97TransferAudio(pThis, &pThis->StreamOut, cbOut); 1388 1389 if ( ASMAtomicReadBool(&pThis->fTimerActive) 1390 || AudioMixerSinkHasData(pThis->pSinkLineIn) 1391 || AudioMixerSinkHasData(pThis->pSinkMicIn) 1392 || AudioMixerSinkHasData(pThis->pSinkOutput)) 1393 { 1394 /* Kick the timer again. */ 1395 uint64_t cTicks = pThis->cTimerTicks; 1396 /** @todo adjust cTicks down by now much cbOutMin represents. */ 1397 TMTimerSet(pThis->pTimer, cTicksNow + cTicks); 1398 } 1364 1399 1365 1400 STAM_PROFILE_STOP(&pThis->StatTimer, a); -
trunk/src/VBox/Devices/Audio/DevIchHda.cpp
r60942 r61050 469 469 * Other values not listed are not supported. 470 470 */ 471 #define HDA_SDI NFIFO_120B0x77 /* 8-, 16-, 20-, 24-, 32-bit Input Streams */472 #define HDA_SDI NFIFO_160B0x9F /* 20-, 24-bit Input Streams Streams */473 474 #define HDA_SDO NFIFO_16B0x0F /* 8-, 16-, 20-, 24-, 32-bit Output Streams */475 #define HDA_SDO NFIFO_32B0x1F /* 8-, 16-, 20-, 24-, 32-bit Output Streams */476 #define HDA_SDO NFIFO_64B0x3F /* 8-, 16-, 20-, 24-, 32-bit Output Streams */477 #define HDA_SDO NFIFO_128B0x7F /* 8-, 16-, 20-, 24-, 32-bit Output Streams */478 #define HDA_SDO NFIFO_192B0xBF /* 8-, 16-, 20-, 24-, 32-bit Output Streams */479 #define HDA_SDO NFIFO_256B0xFF /* 20-, 24-bit Output Streams */471 #define HDA_SDIFIFO_120B 0x77 /* 8-, 16-, 20-, 24-, 32-bit Input Streams */ 472 #define HDA_SDIFIFO_160B 0x9F /* 20-, 24-bit Input Streams Streams */ 473 474 #define HDA_SDOFIFO_16B 0x0F /* 8-, 16-, 20-, 24-, 32-bit Output Streams */ 475 #define HDA_SDOFIFO_32B 0x1F /* 8-, 16-, 20-, 24-, 32-bit Output Streams */ 476 #define HDA_SDOFIFO_64B 0x3F /* 8-, 16-, 20-, 24-, 32-bit Output Streams */ 477 #define HDA_SDOFIFO_128B 0x7F /* 8-, 16-, 20-, 24-, 32-bit Output Streams */ 478 #define HDA_SDOFIFO_192B 0xBF /* 8-, 16-, 20-, 24-, 32-bit Output Streams */ 479 #define HDA_SDOFIFO_256B 0xFF /* 20-, 24-bit Output Streams */ 480 480 #define SDFIFOS(pThis, num) HDA_REG((pThis), SD(FIFOS, num)) 481 481 … … 559 559 uint32_t cbBelowFIFOW; 560 560 /** The buffer descriptor's internal DMA buffer. */ 561 uint8_t au8FIFO[HDA_SDO NFIFO_256B + 1];561 uint8_t au8FIFO[HDA_SDOFIFO_256B + 1]; 562 562 /** Current offset in DMA buffer (in bytes).*/ 563 563 uint32_t u32BufOff; … … 789 789 bool fDMAPosition; 790 790 /** Padding for alignment. */ 791 uint8_t u 32Padding0[7];791 uint8_t u8Padding0[7]; 792 792 /** Pointer to CORB buffer. */ 793 793 R3PTRTYPE(uint32_t *) pu32CorbBuf; … … 811 811 /** The timer for pumping data thru the attached LUN drivers. */ 812 812 PTMTIMERR3 pTimer; 813 /** The timer interval for pumping data thru the LUN drivers in timer ticks. */ 813 /** Flag indicating whether the timer is active or not. */ 814 bool fTimerActive; 815 uint8_t u8Padding1[7]; 816 /** Timer ticks per Hz. */ 814 817 uint64_t cTimerTicks; 815 818 /** Timestamp of the last timer callback (hdaTimer). … … 1172 1175 { 1173 1176 /* Input */ 1174 case HDA_SDI NFIFO_120B: cb = 120; break;1175 case HDA_SDI NFIFO_160B: cb = 160; break;1177 case HDA_SDIFIFO_120B: cb = 120; break; 1178 case HDA_SDIFIFO_160B: cb = 160; break; 1176 1179 1177 1180 /* Output */ 1178 case HDA_SDO NFIFO_16B: cb = 16; break;1179 case HDA_SDO NFIFO_32B: cb = 32; break;1180 case HDA_SDO NFIFO_64B: cb = 64; break;1181 case HDA_SDO NFIFO_128B: cb = 128; break;1182 case HDA_SDO NFIFO_192B: cb = 192; break;1183 case HDA_SDO NFIFO_256B: cb = 256; break;1181 case HDA_SDOFIFO_16B: cb = 16; break; 1182 case HDA_SDOFIFO_32B: cb = 32; break; 1183 case HDA_SDOFIFO_64B: cb = 64; break; 1184 case HDA_SDOFIFO_128B: cb = 128; break; 1185 case HDA_SDOFIFO_192B: cb = 192; break; 1186 case HDA_SDOFIFO_256B: cb = 256; break; 1184 1187 default: 1185 1188 { … … 1341 1344 && (SDSTS(pThis, num) & HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS))) 1342 1345 1343 uint8_t uLevel = 0;1346 int iLevel = 0; 1344 1347 1345 1348 /** @todo Optimize IRQ handling. */ … … 1350 1353 || HDA_REG_FLAG_VALUE(pThis, RIRBSTS, RIRBOIS) 1351 1354 || (HDA_REG(pThis, STATESTS) & HDA_REG(pThis, WAKEEN)))) 1352 uLevel = 1; 1355 { 1356 iLevel = 1; 1357 } 1353 1358 1354 1359 if ( IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 0) … … 1361 1366 || IS_INTERRUPT_OCCURED_AND_ENABLED(pThis, 7)) 1362 1367 { 1363 uLevel = 1;1368 iLevel = 1; 1364 1369 } 1365 1370 1366 1371 if (HDA_REG_FLAG_VALUE(pThis, INTCTL, GIE)) 1367 1372 { 1368 Log3Func(("Level=%d\n", uLevel));1369 PDMDevHlpPCISetIrq(pThis->CTX_SUFF(pDevIns), 0 , uLevel);1373 Log3Func(("Level=%d\n", iLevel)); 1374 PDMDevHlpPCISetIrq(pThis->CTX_SUFF(pDevIns), 0 , iLevel); 1370 1375 } 1371 1376 … … 1489 1494 { 1490 1495 Assert((HDA_REG_FLAG_VALUE(pThis, CORBCTL, DMA))); 1496 Assert(pThis->u64CORBBase); 1497 AssertPtr(pThis->pu32CorbBuf); 1498 Assert(pThis->cbCorbBuf); 1499 1491 1500 rc = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), pThis->u64CORBBase, pThis->pu32CorbBuf, pThis->cbCorbBuf); 1492 1501 if (RT_FAILURE(rc)) … … 1720 1729 HDA_STREAM_REG(pThis, CTL, uSD) = 0x40000 | (HDA_STREAM_REG(pThis, CTL, uSD) & HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST)); 1721 1730 /* ICH6 defines default values (0x77 for input and 0xBF for output descriptors) of FIFO size. 18.2.39. */ 1722 HDA_STREAM_REG(pThis, FIFOS, uSD) = hdaGetDirFromSD(uSD) == PDMAUDIODIR_IN ? HDA_SDI NFIFO_120B : HDA_SDONFIFO_192B;1731 HDA_STREAM_REG(pThis, FIFOS, uSD) = hdaGetDirFromSD(uSD) == PDMAUDIODIR_IN ? HDA_SDIFIFO_120B : HDA_SDOFIFO_192B; 1723 1732 /* See 18.2.38: Always defaults to 0x4 (32 bytes). */ 1724 1733 HDA_STREAM_REG(pThis, FIFOW, uSD) = HDA_SDFIFOW_32B; … … 2097 2106 } 2098 2107 2099 HDA_MARK_STREAM(0); /* SD0: Input. */ 2100 HDA_MARK_STREAM(4); /* SD4: Output. */ 2108 HDA_MARK_STREAM(0); 2109 HDA_MARK_STREAM(1); 2110 HDA_MARK_STREAM(2); 2111 HDA_MARK_STREAM(3); 2112 HDA_MARK_STREAM(4); 2113 HDA_MARK_STREAM(5); 2114 HDA_MARK_STREAM(6); 2115 HDA_MARK_STREAM(7); 2101 2116 2102 2117 #undef HDA_MARK_STREAM 2103 2118 2104 2119 /* "OR" bit of all interrupt status bits. */ 2105 if (v) 2106 v |= RT_BIT(31); 2120 v |= v ? RT_BIT(31) : 0; 2107 2121 2108 2122 *pu32Value = v; … … 2240 2254 bool fInReset = RT_BOOL(HDA_REG_IND(pThis, iReg) & HDA_REG_FIELD_FLAG_MASK(SDCTL, SRST)); 2241 2255 2242 uint32_t uVal = HDA_REG_IND(pThis, iReg);2243 LogFunc(("uVal=%RU32 vs u32Value=%RU32\n", uVal, u32Value));2244 2245 2256 if (HDA_REG_IND(pThis, iReg) == u32Value) /* Value already set? */ 2246 2257 return VINF_SUCCESS; … … 2346 2357 static int hdaRegWriteSDSTS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 2347 2358 { 2348 if (HDA_REG_IND(pThis, iReg) == u32Value) /* Value already set? */2349 return VINF_SUCCESS;2350 2351 2359 uint32_t v = HDA_REG_IND(pThis, iReg); 2352 2360 /* Clear (zero) FIFOE and DESE bits when writing 1 to it. */ … … 2396 2404 static int hdaRegWriteSDFIFOW(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 2397 2405 { 2398 if (HDA_REG_IND(pThis, iReg) == u32Value) /* Value already set? */ 2406 uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, FIFOW, iReg); 2407 /** @todo Only allow updating FIFOS if RUN bit is 0? */ 2408 uint32_t u32FIFOW = 0; 2409 2410 if (hdaGetDirFromSD(uSD) != PDMAUDIODIR_IN) /* FIFOW for input streams only. */ 2411 { 2412 LogRel(("HDA: Warning: Guest tried to write read-only FIFOW to stream #%RU8, ignoring\n", uSD)); 2399 2413 return VINF_SUCCESS; 2414 } 2400 2415 2401 2416 switch (u32Value) … … 2404 2419 case HDA_SDFIFOW_16B: 2405 2420 case HDA_SDFIFOW_32B: 2406 return hdaRegWriteU16(pThis, iReg, u32Value); 2421 u32FIFOW = u32Value; 2422 break; 2407 2423 default: 2408 LogFunc(("Attempt to store unsupported value(%x) in SDFIFOW\n", u32Value)); 2409 return hdaRegWriteU16(pThis, iReg, HDA_SDFIFOW_32B); 2410 } 2424 LogRel(("HDA: Warning: Guest tried write unsupported FIFOW (0x%x) to stream #%RU8, defaulting to 32 bytes\n", 2425 u32Value, uSD)); 2426 u32FIFOW = HDA_SDFIFOW_32B; 2427 break; 2428 } 2429 2430 if (u32FIFOW) 2431 { 2432 LogFunc(("[SD%RU8]: Updating FIFOW to %RU32 bytes\n", uSD, hdaSDFIFOSToBytes(u32FIFOW))); 2433 /** @todo Update internal stream state with new FIFOS. */ 2434 2435 return hdaRegWriteU16(pThis, iReg, u32FIFOW); 2436 } 2437 2411 2438 return VINF_SUCCESS; /* Never reached. */ 2412 2439 } … … 2418 2445 static int hdaRegWriteSDFIFOS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 2419 2446 { 2420 if (HDA_REG_IND(pThis, iReg) == u32Value) /* Value already set? */2421 return VINF_SUCCESS;2422 2423 2447 uint8_t uSD = HDA_SD_NUM_FROM_REG(pThis, FIFOS, iReg); 2424 2448 /** @todo Only allow updating FIFOS if RUN bit is 0? */ 2425 2449 uint32_t u32FIFOS = 0; 2426 2450 2427 if (hdaGetDirFromSD(uSD) == PDMAUDIODIR_IN) /* FIFOS for input streams is read-only. */ 2428 { 2429 LogRel(("HDA: Warning: Guest tried to write read-only FIFOS for input stream #%RU8, skipping\n", uSD)); 2430 AssertFailed(); 2451 if (hdaGetDirFromSD(uSD) != PDMAUDIODIR_OUT) /* FIFOS for output streams only. */ 2452 { 2453 LogRel(("HDA: Warning: Guest tried to write read-only FIFOS to stream #%RU8, ignoring\n", uSD)); 2431 2454 return VINF_SUCCESS; 2432 2455 } … … 2434 2457 switch(u32Value) 2435 2458 { 2436 case HDA_SDO NFIFO_16B:2437 case HDA_SDO NFIFO_32B:2438 case HDA_SDO NFIFO_64B:2439 case HDA_SDO NFIFO_128B:2440 case HDA_SDO NFIFO_192B:2459 case HDA_SDOFIFO_16B: 2460 case HDA_SDOFIFO_32B: 2461 case HDA_SDOFIFO_64B: 2462 case HDA_SDOFIFO_128B: 2463 case HDA_SDOFIFO_192B: 2441 2464 u32FIFOS = u32Value; 2442 2465 break; 2443 2466 2444 case HDA_SDO NFIFO_256B: /** @todo r=andy Investigate this. */2467 case HDA_SDOFIFO_256B: /** @todo r=andy Investigate this. */ 2445 2468 LogFunc(("256-bit is unsupported, HDA is switched into 192-bit mode\n")); 2446 2469 /* Fall through is intentional. */ 2447 2470 default: 2448 LogRel(("HDA: Warning: Guest tried write unsupported FIFOS (0x%x) to inputstream #%RU8, defaulting to 192 bytes\n",2471 LogRel(("HDA: Warning: Guest tried write unsupported FIFOS (0x%x) to stream #%RU8, defaulting to 192 bytes\n", 2449 2472 u32Value, uSD)); 2450 u32FIFOS = HDA_SDONFIFO_192B; 2451 AssertFailed(); 2473 u32FIFOS = HDA_SDOFIFO_192B; 2452 2474 break; 2453 2475 } … … 2474 2496 int rc = VINF_SUCCESS; 2475 2497 2476 uint32_t u32Hz = (u32SDFMT & HDA_SDFMT_BASE_RATE_SHIFT) ? 44100 : 48000; 2498 uint32_t u32Hz = EXTRACT_VALUE(u32SDFMT, HDA_SDFMT_BASE_RATE_MASK, HDA_SDFMT_BASE_RATE_SHIFT) 2499 ? 44100 : 48000; 2477 2500 uint32_t u32HzMult = 1; 2478 2501 uint32_t u32HzDiv = 1; … … 2598 2621 } 2599 2622 #else /* !VBOX_WITH_HDA_51_SURROUND */ 2623 /* Only support mono or stereo channels. */ 2600 2624 if ( pCfg->cChannels != 1 /* Mono */ 2601 2625 && pCfg->cChannels != 2 /* Stereo */) … … 2605 2629 #endif 2606 2630 2607 if ( RT_FAILURE(rc))2631 if (rc == VERR_NOT_SUPPORTED) 2608 2632 { 2609 2633 LogRel(("HDA: Unsupported channel count (%RU8), falling back to stereo channels\n", pCfg->cChannels)); 2610 2634 pCfg->cChannels = 2; 2635 2636 rc = VINF_SUCCESS; 2611 2637 } 2612 2638 2613 2639 do 2614 2640 { 2641 if (RT_FAILURE(rc)) 2642 break; 2643 2615 2644 if (fUseFront) 2616 2645 { … … 2643 2672 if (RT_SUCCESS(rc)) 2644 2673 rc = hdaCodecAddStream(pThis->pCodec, PDMAUDIOMIXERCTL_CENTER_LFE, pCfg); 2645 2646 RTStrFree(pszName);2647 2674 } 2648 2675 … … 2666 2693 } while (0); 2667 2694 2695 LogFlowFuncLeaveRC(rc); 2668 2696 return rc; 2669 2697 } … … 2707 2735 } 2708 2736 2737 LogFlowFuncLeaveRC(rc); 2709 2738 return rc; 2710 2739 } … … 2865 2894 if (fIsRunning) 2866 2895 { 2867 LogFlowFunc(("[SD%RU8]: Warning: Cannot write to register 0x%x (0x%x) when RUN bit is set (%R[sdctl])\n", 2868 pStream->u8SD, iReg, u32Value, u32SDCTL)); 2896 LogFunc(("[SD%RU8]: Warning: Cannot write to register 0x%x (0x%x) when RUN bit is set (%R[sdctl])\n", 2897 pStream->u8SD, iReg, u32Value, u32SDCTL)); 2898 # ifdef DEBUG_andy 2899 AssertFailed(); 2900 # endif 2869 2901 return VERR_ACCESS_DENIED; 2870 2902 } … … 3111 3143 Assert(u32LPIB <= pStream->u32CBL); 3112 3144 3113 uint32_t cbFree = pStream->u32CBL - u32LPIB; /** @todo Convert samples to bytes? */3145 uint32_t cbFree = pStream->u32CBL - u32LPIB; 3114 3146 if (cbFree) 3115 3147 { … … 3118 3150 3119 3151 /* Make sure we only copy as much as the stream's FIFO can hold (SDFIFOS, 18.2.39). */ 3120 cbFree = RT_MIN(cbFree, pStream->u16FIFOS);3152 // cbFree = RT_MIN(cbFree, uint32_t(pStream->u16FIFOS)); 3121 3153 3122 3154 /* Make sure we only transfer as many bytes as requested. */ … … 3136 3168 } 3137 3169 3138 LogFlowFunc(("[SD%RU8]: CBL=%RU32, LPIB=%RU32, cbFree=%RU32, %R[bdle]\n", pStream->u8SD,3139 pStream->u32CBL, HDA_STREAM_REG(pThis, LPIB, pStream->u8SD), cbFree, pBDLE));3170 LogFlowFunc(("[SD%RU8]: CBL=%RU32, LPIB=%RU32, FIFOS=%RU16, cbFree=%RU32, %R[bdle]\n", pStream->u8SD, 3171 pStream->u32CBL, HDA_STREAM_REG(pThis, LPIB, pStream->u8SD), pStream->u16FIFOS, cbFree, pBDLE)); 3140 3172 return cbFree; 3141 3173 } … … 3223 3255 } 3224 3256 3225 if (RT_SUCCESS(rc)) 3226 rc = RTCircBufCreate(&pMapping->pCircBuf, _4K); 3257 if ( RT_SUCCESS(rc) 3258 /* Create circular buffer if not created yet. */ 3259 && !pMapping->pCircBuf) 3260 { 3261 rc = RTCircBufCreate(&pMapping->pCircBuf, _4K); /** @todo Make size configurable? */ 3262 } 3227 3263 3228 3264 if (RT_SUCCESS(rc)) … … 3312 3348 LogFlowFunc(("[SD%RU8]: cbInc=%RU32\n", pStream->u8SD, cbInc)); 3313 3349 3314 Assert(cbInc <= pStream->u16FIFOS);3350 //Assert(cbInc <= pStream->u16FIFOS); 3315 3351 3316 3352 if (!cbInc) /* Nothing to do? Bail out early. */ … … 3429 3465 Assert(cbRead <= cbBuf); 3430 3466 Assert(cbRead <= pBDLE->u32BufSize - pBDLE->State.u32BufOff); 3431 Assert(cbRead <= pStream->u16FIFOS);3467 //Assert(cbRead <= pStream->u16FIFOS); 3432 3468 3433 3469 /* … … 3503 3539 pvBuf, cbBuf); 3504 3540 AssertRC(rc); 3505 #if defined (RT_OS_LINUX) && defined(DEBUG )3541 #if defined (RT_OS_LINUX) && defined(DEBUG_andy) 3506 3542 RTFILE fh; 3507 RTFileOpen(&fh, "/tmp/hdaWriteAudio .pcm",3543 RTFileOpen(&fh, "/tmp/hdaWriteAudio-hda.pcm", 3508 3544 RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 3509 3545 RTFileWrite(fh, pvBuf, cbBuf, NULL); … … 3602 3638 } 3603 3639 3604 Assert(cbWritten <= pStream->u16FIFOS);3640 //Assert(cbWritten <= pStream->u16FIFOS); 3605 3641 3606 3642 if (RT_SUCCESS(rc)) … … 3681 3717 if (RT_SUCCESS(rc)) 3682 3718 rc = AudioMixerSinkSetFormat(pSink->pMixSink, &PCMProps); 3719 3720 if (RT_FAILURE(rc)) 3721 return rc; 3683 3722 3684 3723 PHDADRIVER pDrv; … … 3736 3775 3737 3776 PAUDMIXSTREAM pMixStrm; 3738 rc2 = AudioMixer StreamCreate(pDrv->pConnector, pCfg, 0 /* fFlags */, &pMixStrm);3777 rc2 = AudioMixerCreateStream(pThis->pMixer, pDrv->pConnector, pCfg, 0 /* fFlags */, &pMixStrm); 3739 3778 if (RT_SUCCESS(rc2)) 3740 3779 { … … 3776 3815 { 3777 3816 rc = hdaMixerAddStream(pThis, pSink, pCfg); 3817 3818 AssertPtr(pSink->pMixSink); 3819 LogFlowFunc(("Sink=%s, enmMixerCtl=%ld\n", pSink->pMixSink->pszName, enmMixerCtl)); 3778 3820 } 3779 3821 else 3780 3822 rc = VERR_NOT_FOUND; 3781 3823 3782 LogFlowFunc (("Sink=%s, enmMixerCtl=%ld, rc=%Rrc\n", pSink->pMixSink->pszName, enmMixerCtl, rc));3824 LogFlowFuncLeaveRC(rc); 3783 3825 return rc; 3784 3826 } … … 3952 3994 static void hdaTimerMaybeStart(PHDASTATE pThis) 3953 3995 { 3996 LogFlowFunc(("cStreamsActive=%RU8\n", pThis->cStreamsActive)); 3997 3954 3998 if (pThis->cStreamsActive == 0) /* Only start the timer if there are no active streams. */ 3955 3999 return; … … 3960 4004 LogFlowFuncEnter(); 3961 4005 4006 /* Set timer flag. */ 4007 ASMAtomicXchgBool(&pThis->fTimerActive, true); 4008 4009 /* Update current time timestamp. */ 4010 pThis->uTimerTS = TMTimerGet(pThis->pTimer); 4011 3962 4012 /* Fire off timer. */ 3963 4013 TMTimerSet(pThis->pTimer, TMTimerGet(pThis->pTimer) + pThis->cTimerTicks); … … 3966 4016 static void hdaTimerMaybeStop(PHDASTATE pThis) 3967 4017 { 4018 LogFlowFunc(("cStreamsActive=%RU8\n", pThis->cStreamsActive)); 4019 3968 4020 if (pThis->cStreamsActive) /* Some streams still active? Bail out. */ 3969 4021 return; … … 3974 4026 LogFlowFuncEnter(); 3975 4027 3976 int rc2 = TMTimerStop(pThis->pTimer);3977 A ssertRC(rc2);4028 /* Set timer flag. */ 4029 ASMAtomicXchgBool(&pThis->fTimerActive, false); 3978 4030 } 3979 4031 … … 3991 4043 uint64_t cTicksNow = TMTimerGet(pTimer); 3992 4044 uint64_t cTicksElapsed = cTicksNow - pThis->uTimerTS; 3993 uint64_t cTicksPerSec = TMTimerGetFreq(pTimer); 3994 4045 4046 /* Update current time timestamp. */ 3995 4047 pThis->uTimerTS = cTicksNow; 3996 4048 … … 4000 4052 #endif 4001 4053 PHDASTREAM pStreamFront = hdaGetStreamFromSink(pThis, &pThis->SinkFront); 4054 #ifdef VBOX_WITH_HDA_51_SURROUND 4055 /** @todo See note below. */ 4056 #endif 4002 4057 4003 4058 uint32_t cbLineIn; 4004 AudioMixerSinkTimerUpdate(pThis->SinkLineIn.pMixSink, cTicksPerSec, cTicksElapsed, &cbLineIn);4059 AudioMixerSinkTimerUpdate(pThis->SinkLineIn.pMixSink, pThis->cTimerTicks, cTicksElapsed, &cbLineIn); 4005 4060 if (cbLineIn) 4006 4061 hdaTransfer(pThis, pStreamLineIn, cbLineIn, NULL); /** @todo Add rc! */ … … 4008 4063 #ifdef VBOX_WITH_HDA_MIC_IN 4009 4064 uint32_t cbMicIn; 4010 AudioMixerSinkTimerUpdate(pThis->SinkMicIn.pMixSink , cTicksPerSec, cTicksElapsed, &cbMicIn); 4011 #endif 4012 4013 uint32_t cbOut; 4014 AudioMixerSinkTimerUpdate(pThis->SinkFront.pMixSink, cTicksPerSec, cTicksElapsed, &cbOut); 4015 if (cbOut) 4016 hdaTransfer(pThis, pStreamFront, cbOut, NULL); /** @todo Add rc! */ 4017 4018 /* Kick the timer again. */ 4019 uint64_t cTicks = pThis->cTimerTicks; 4020 /** @todo adjust cTicks down by now much cbOutMin represents. */ 4021 TMTimerSet(pThis->pTimer, cTicksNow + cTicks); 4065 AudioMixerSinkTimerUpdate(pThis->SinkMicIn.pMixSink , pThis->cTimerTicks, cTicksElapsed, &cbMicIn); 4066 #endif 4067 4068 uint32_t cbFront; 4069 AudioMixerSinkTimerUpdate(pThis->SinkFront.pMixSink, pThis->cTimerTicks, cTicksElapsed, &cbFront); 4070 #ifdef VBOX_WITH_HDA_51_SURROUND 4071 uint32_t cbCenterLFE; 4072 AudioMixerSinkTimerUpdate(pThis->SinkCenterLFE.pMixSink, pThis->cTimerTicks, cTicksElapsed, &cbCenterLFE); 4073 uint32_t cbRear; 4074 AudioMixerSinkTimerUpdate(pThis->SinkRear.pMixSink, pThis->cTimerTicks, cTicksElapsed, &cbRear); 4075 #endif 4076 4077 if (cbFront) 4078 hdaTransfer(pThis, pStreamFront, cbFront, NULL); /** @todo Add rc! */ 4079 #ifdef VBOX_WITH_HDA_51_SURROUND 4080 /* 4081 * Only call hdaTransfer if CenterLFE and/or Rear are on different SDs, 4082 * otherwise we have to use the interleaved streams support for getting the data 4083 * out of the Front sink (depending on the mapping layout). 4084 */ 4085 #endif 4086 4087 if ( ASMAtomicReadBool(&pThis->fTimerActive) 4088 || AudioMixerSinkHasData(pThis->SinkFront.pMixSink) 4089 #ifdef VBOX_WITH_HDA_51_SURROUND 4090 || AudioMixerSinkHasData(pThis->SinkCenterLFE.pMixSink) 4091 || AudioMixerSinkHasData(pThis->SinkRear.pMixSink) 4092 #endif 4093 || AudioMixerSinkHasData(pThis->SinkLineIn.pMixSink)) 4094 { 4095 /* Kick the timer again. */ 4096 uint64_t cTicks = pThis->cTimerTicks; 4097 /** @todo adjust cTicks down by now much cbOutMin represents. */ 4098 TMTimerSet(pThis->pTimer, cTicksNow + cTicks); 4099 } 4022 4100 4023 4101 STAM_PROFILE_STOP(&pThis->StatTimer, a); … … 4111 4189 fProceed = false; 4112 4190 4113 #if 04114 Log3Func(("[SD%RU8] fProceed=%RTbool, fRun=%RTbool, cbToProcess=%RU32\n",4115 pStream->u8SD, fProceed, HDA_STREAM_REG(pThis, CTL, pStream->u8SD) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN),4116 cbToProcess));4117 #endif4118 4119 4191 if ((HDA_STREAM_REG(pThis, STS, pStream->u8SD) & HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS))) 4120 4192 { 4121 Log3Func(("[SD%RU8]: BCIS : Skipping\n", pStream->u8SD));4193 Log3Func(("[SD%RU8]: BCIS set\n", pStream->u8SD)); 4122 4194 fProceed = false; 4123 4195 } … … 4125 4197 if (!fProceed) 4126 4198 { 4199 Log3Func(("[SD%RU8] Skipping\n")); 4200 4127 4201 rc = RTSemMutexRelease(pStream->State.hMtx); 4128 4202 AssertRC(rc); … … 4144 4218 Assert(u32LPIB <= pStream->u32CBL); 4145 4219 4146 if (u32LPIB == pStream->u32CBL) 4147 u32LPIB = hdaStreamUpdateLPIB(pThis, pStream, 0); 4148 4149 uint32_t cbLeft = pStream->u32CBL - u32LPIB; 4220 uint32_t cbLeft = cbToProcess; 4150 4221 uint32_t cbTotal = 0; 4151 4222 … … 4154 4225 Log3Func(("cbLeft=%RU32\n", cbLeft)); 4155 4226 4227 #define FOO 4228 4229 #ifdef FOO 4230 uint8_t u8FIFO[_16K+1]; 4231 size_t u8FIFOff = 0; 4232 #endif 4233 4234 /* Set the FIFORDY bit on the stream while doing the transfer. */ 4235 HDA_STREAM_REG(pThis, STS, pStream->u8SD) |= HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY); 4236 4156 4237 while (cbLeft) 4157 4238 { 4158 #if 14159 4239 /* Do we need to fetch the next Buffer Descriptor Entry (BDLE)? */ 4160 4240 if (hdaStreamNeedsNextBDLE(pThis, pStream)) … … 4164 4244 break; 4165 4245 } 4166 #else4167 PHDABDLE pBDLE = &pStream->State.BDLE;4168 4169 /* Did we reach the CBL (Cyclic Buffer List) limit? */4170 bool fCBLLimitReached = u32LPIB >= pStream->u32CBL;4171 4172 /* Do we need to use the next BDLE entry? Either because we reached4173 * the CBL limit or our internal DMA buffer is full. */4174 bool fNeedsNextBDLE = ( fCBLLimitReached4175 || (pBDLE->State.u32BufOff >= pBDLE->u32BufSize));4176 4177 Assert(u32LPIB <= pStream->u32CBL);4178 Assert(pBDLE->State.u32BufOff <= pBDLE->u32BufSize);4179 4180 if (fNeedsNextBDLE)4181 {4182 4183 4184 #if 14185 if (/* IOC (Interrupt On Completion) bit set? */4186 pBDLE->fIntOnCompletion4187 /* All data put into the DMA FIFO? */4188 && pBDLE->State.cbBelowFIFOW == 04189 )4190 {4191 // fSetIRQ = true;4192 /*4193 * If the ICE (IOCE, "Interrupt On Completion Enable") bit of the SDCTL register is set4194 * we need to generate an interrupt.4195 */4196 // if (HDA_STREAM_REG(pThis, CTL, pStream->u8SD) & HDA_REG_FIELD_FLAG_MASK(SDCTL, ICE))4197 // PDMDevHlpPCISetIrq(pThis->CTX_SUFF(pDevIns), 0 , 1 /* Raised */);4198 }4199 #endif4200 4201 4202 }4203 #endif4204 4205 /* Set the FIFORDY bit on the stream while doing the transfer. */4206 HDA_STREAM_REG(pThis, STS, pStream->u8SD) |= HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY);4207 4246 4208 4247 uint32_t cbProcessed; … … 4210 4249 rc = hdaReadAudio (pThis, pStream, cbLeft, &cbProcessed); 4211 4250 else 4251 { 4252 #ifndef FOO 4212 4253 rc = hdaWriteAudio(pThis, pStream, cbLeft, &cbProcessed); 4213 4214 /* Remove the FIFORDY bit again. */ 4215 HDA_STREAM_REG(pThis, STS, pStream->u8SD) &= ~HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY); 4254 #else 4255 uint32_t cbToWrite = hdaStreamGetTransferSize(pThis, pStream, cbLeft); 4256 4257 void *pvBuf = u8FIFO + u8FIFOff; 4258 int32_t cbBuf = cbToWrite; 4259 4260 PHDABDLE pBDLE = &pStream->State.BDLE; 4261 4262 rc = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), 4263 pBDLE->u64BufAdr + pBDLE->State.u32BufOff, 4264 pvBuf, cbBuf); 4265 4266 hdaBDLEUpdate(pBDLE, cbToWrite, cbToWrite); 4267 4268 LogFlowFunc(("u8FIFOff=%zu, cbLeft=%RU32, cbToWrite=%RU32\n", u8FIFOff, cbLeft, cbToWrite)); 4269 4270 u8FIFOff += cbToWrite; 4271 Assert(u8FIFOff <= sizeof(u8FIFO)); 4272 4273 cbProcessed = cbToWrite; 4274 #endif 4275 } 4216 4276 4217 4277 if (RT_FAILURE(rc)) 4218 4278 break; 4219 4279 4220 #if 14221 4280 hdaStreamTransferUpdate(pThis, pStream, cbProcessed); 4222 4281 … … 4232 4291 4233 4292 if (hdaStreamTransferIsComplete(pThis, pStream, &fInterrupt)) 4234 {4235 rc = hdaStreamGetNextBDLE(pThis, pStream);4236 4293 break; 4237 } 4238 #else 4239 Assert(cbProcessedLeft >= cbProcessed); 4240 cbProcessedLeft -= cbProcessed; 4241 cbProcessedTotal += cbProcessed; 4242 4243 4244 u32LPIB = hdaStreamUpdateLPIB(pThis, pStream, u32LPIB + cbProcessed); 4245 4246 Assert(u32LPIB <= pStream->u32CBL); 4247 if (u32LPIB == pStream->u32CBL) 4248 { 4249 // HDA_STREAM_REG(pThis, STS, pStream->u8SD) |= HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS); 4250 Log3Func(("[SD%RU8]: Transfer complete\n", pStream->u8SD)); 4294 } 4295 4296 /* Remove the FIFORDY bit again. */ 4297 HDA_STREAM_REG(pThis, STS, pStream->u8SD) &= ~HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY); 4298 4299 #ifdef FOO 4300 #if defined (RT_OS_LINUX) && defined(DEBUG_andy) 4301 RTFILE fh; 4302 RTFileOpen(&fh, "/tmp/hdaWriteAudio.pcm", 4303 RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 4304 RTFileWrite(fh, u8FIFO, u8FIFOff, NULL); 4305 RTFileClose(fh); 4306 #endif 4251 4307 #if 1 4252 if (/* IOC (Interrupt On Completion) bit set? */ 4253 pBDLE->fIntOnCompletion 4254 /* All data put into the DMA FIFO? */ 4255 && pBDLE->State.cbBelowFIFOW == 0 4256 ) 4257 { 4258 fSetIRQ = true; 4259 /* 4260 * If the ICE (IOCE, "Interrupt On Completion Enable") bit of the SDCTL register is set 4261 * we need to generate an interrupt. 4262 */ 4263 // if (HDA_STREAM_REG(pThis, CTL, pStream->u8SD) & HDA_REG_FIELD_FLAG_MASK(SDCTL, ICE)) 4264 // PDMDevHlpPCISetIrq(pThis->CTX_SUFF(pDevIns), 0 , 1 /* Raised */); 4265 // fIRQ = true; 4266 } 4267 #endif 4268 fIsComplete = true; 4269 } 4270 4271 if ( fIsComplete 4272 || pBDLE->State.u32BufOff >= pBDLE->u32BufSize) 4273 { 4274 Assert(pBDLE->State.u32BufOff <= pBDLE->u32BufSize); 4275 4276 Log3Func(("[SD%RU8]: LPIB=%RU32, CBL=%RU32, %R[bdle] => Next BDLE\n", 4277 pStream->u8SD, u32LPIB, u32LPIB >= pStream->u32CBL, pBDLE)); 4278 4279 /* 4280 * Switch to the next BDLE entry and do a wrap around 4281 * if we reached the end of the Buffer Descriptor List (BDL). 4282 */ 4283 pStream->State.uCurBDLE++; 4284 if (pStream->State.uCurBDLE == pStream->u16LVI + 1) 4285 { 4286 pStream->State.uCurBDLE = 0; 4287 u32LPIB = hdaStreamUpdateLPIB(pThis, pStream, 0); 4288 } 4289 4290 hdaBDLEFetch(pThis, &pStream->State.BDLE, pStream->u64BDLBase, pStream->State.uCurBDLE); 4291 4292 if (/* IOC (Interrupt On Completion) bit set? */ 4293 pBDLE->fIntOnCompletion 4294 /* All data put into the DMA FIFO? */ 4295 && pBDLE->State.cbBelowFIFOW == 0 4296 ) 4297 { 4298 fSetIRQ = true; 4299 } 4300 } 4301 4302 #endif 4303 4304 /*if (fIsComplete) 4305 break;*/ 4306 } 4307 4308 AudioMixerSinkWrite(pThis->SinkFront.pMixSink, AUDMIXOP_COPY, u8FIFO, u8FIFOff, 4309 NULL /* pcbWritten */); 4310 #endif 4311 #endif 4312 4313 #ifdef FOO 4308 4314 if (fInterrupt) 4309 4315 { … … 4319 4325 */ 4320 4326 HDA_STREAM_REG(pThis, STS, pStream->u8SD) |= HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS); 4321 Log3Func(("[SD%RU8]: BCIS: Set (fInterrupt=%RTbool)\n", pStream->u8SD, fInterrupt));4327 Log3Func(("[SD%RU8]: BCIS: Set\n", pStream->u8SD)); 4322 4328 4323 4329 hdaProcessInterrupt(pThis); 4324 }4325 4326 #if 04327 if (fSetIRQ)4328 {4329 Log3Func(("[SD%RU8]: IRQ\n", pStream->u8SD));4330 4331 /**4332 * Set the BCIS (Buffer Completion Interrupt Status) flag as the4333 * last byte of data for the current descriptor has been fetched4334 * from memory and put into the DMA FIFO.4335 *4336 * Speech synthesis works fine on Mac Guest if this bit isn't set4337 * but in general sound quality gets worse.4338 *4339 * This must be set in *any* case.4340 */4341 HDA_STREAM_REG(pThis, STS, pStream->u8SD) |= HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS);4342 4343 /*4344 * If the ICE (IOCE, "Interrupt On Completion Enable") bit of the SDCTL register is set4345 * we need to generate an interrupt.4346 */4347 if (HDA_STREAM_REG(pThis, CTL, pStream->u8SD) & HDA_REG_FIELD_FLAG_MASK(SDCTL, ICE))4348 PDMDevHlpPCISetIrq(pThis->CTX_SUFF(pDevIns), 0 , 1 /* Raised */);4349 4330 } 4350 4331 #endif … … 5006 4987 if (RT_SUCCESS(rc)) 5007 4988 { 5008 /*5009 * Update sinks after the state changes.5010 */5011 AUDMIXSINKCMD enmCmdLineIn = RT_BOOL(HDA_SDCTL(pThis, 0 /** @todo Use a define. */) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN))5012 ? AUDMIXSINKCMD_ENABLE : AUDMIXSINKCMD_DISABLE;5013 #ifdef VBOX_WITH_HDA_MIC_IN5014 AUDMIXSINKCMD enmCmdMicIn = RT_BOOL(HDA_SDCTL(pThis, 2 /** @todo Use a define. */) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN))5015 ? AUDMIXSINKCMD_ENABLE : AUDMIXSINKCMD_DISABLE;5016 #endif5017 AUDMIXSINKCMD enmCmdOut = RT_BOOL(HDA_SDCTL(pThis, 4 /** @todo Use a define. */) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN))5018 ? AUDMIXSINKCMD_ENABLE : AUDMIXSINKCMD_DISABLE;5019 5020 # ifdef VBOX_WITH_HDA_MIC_IN5021 AudioMixerSinkCtl(pThis->SinkMicIn.pMixSink, enmCmdMicIn);5022 # endif5023 AudioMixerSinkCtl(pThis->SinkLineIn.pMixSink, enmCmdLineIn);5024 AudioMixerSinkCtl(pThis->SinkFront.pMixSink, enmCmdOut);5025 # ifdef VBOX_WITH_HDA_51_SURROUND5026 AudioMixerSinkCtl(pThis->SinkCenterLFE.pMixSink, enmCmdOut);5027 AudioMixerSinkCtl(pThis->SinkRear.pMixSink, enmCmdOut);5028 # endif5029 }5030 5031 if (RT_SUCCESS(rc))5032 {5033 4989 pThis->u64CORBBase = RT_MAKE_U64(HDA_REG(pThis, CORBLBASE), HDA_REG(pThis, CORBUBASE)); 5034 4990 pThis->u64RIRBBase = RT_MAKE_U64(HDA_REG(pThis, RIRBLBASE), HDA_REG(pThis, RIRBUBASE)); … … 5038 4994 pThis->fDMAPosition = RT_BOOL(pThis->u64DPBase & RT_BIT_64(0)); 5039 4995 } 5040 else 4996 4997 if (RT_SUCCESS(rc)) 4998 { 4999 for (uint8_t i = 0; i < HDA_MAX_STREAMS; i++) 5000 { 5001 PHDASTREAM pStream = hdaStreamFromSD(pThis, i); 5002 if (pStream) 5003 { 5004 bool fActive = RT_BOOL(HDA_STREAM_REG(pThis, CTL, i) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 5005 LogFlowFunc(("[SD%RU8]: fActive=%RTbool\n", i, fActive)); 5006 int rc2 = hdaStreamSetActive(pThis, pStream, fActive); 5007 AssertRC(rc2); 5008 } 5009 } 5010 } 5011 5012 if (RT_FAILURE(rc)) 5041 5013 LogRel(("HDA: Failed loading device state (version %RU32, pass 0x%x), rc=%Rrc\n", uVersion, uPass, rc)); 5042 5014 … … 5678 5650 #ifndef VBOX_WITH_AUDIO_CALLBACKS 5679 5651 uint16_t uTimerHz; 5680 rc = CFGMR3QueryU16Def(pCfg, "TimerHz", &uTimerHz, 100 /* Hz */);5652 rc = CFGMR3QueryU16Def(pCfg, "TimerHz", &uTimerHz, 200 /* Hz */); 5681 5653 if (RT_FAILURE(rc)) 5682 5654 return PDMDEV_SET_ERROR(pDevIns, rc, -
trunk/src/VBox/Devices/Audio/DevSB16.cpp
r60938 r61050 1685 1685 RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node) 1686 1686 { 1687 int rc2 = pDrv->pConnector->pfnQueryStatus(pDrv->pConnector, 1688 NULL /* pcbIn */, &cbOut, NULL /* pcSamplesLive */); 1687 int rc2 = pDrv->pConnector->pfnGetDataOut(pDrv->pConnector, &cbOut, NULL /* pcSamplesLive */); 1689 1688 if (RT_SUCCESS(rc2)) 1690 1689 cbOutMin = RT_MIN(cbOutMin, cbOut); … … 1761 1760 if (!pThis->pTimerIO) 1762 1761 return; 1762 1763 /* Update current time timestamp. */ 1764 pThis->uTimerTSIO = TMTimerGet(pThis->pTimerIO); 1763 1765 1764 1766 /* Fire off timer. */ … … 2052 2054 pDrv->Out.pMixStrm = NULL; 2053 2055 2054 int rc2 = AudioMixer StreamCreate(pDrv->pConnector, pCfg, 0 /* fFlags */, &pDrv->Out.pMixStrm);2056 int rc2 = AudioMixerCreateStream(pThis->pMixer, pDrv->pConnector, pCfg, 0 /* fFlags */, &pDrv->Out.pMixStrm); 2055 2057 if (RT_SUCCESS(rc2)) 2056 2058 { -
trunk/src/VBox/Devices/Audio/DrvAudio.cpp
r61033 r61050 1161 1161 } 1162 1162 1163 static DECLCALLBACK(int) drvAudioQueryStatus(PPDMIAUDIOCONNECTOR pInterface, 1164 uint32_t *pcbAvailIn, uint32_t *pcbFreeOut, 1165 uint32_t *pcSamplesLive) 1163 static DECLCALLBACK(int) drvAudioGetDataIn(PPDMIAUDIOCONNECTOR pInterface, uint32_t *pcbAvailIn) 1166 1164 { 1167 1165 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 1168 1166 /* pcbAvailIn is optional. */ 1167 1168 PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface); 1169 1170 int rc = RTCritSectEnter(&pThis->CritSect); 1171 if (RT_FAILURE(rc)) 1172 return rc; 1173 1174 uint32_t cbAvailIn = 0; 1175 1176 PPDMAUDIOHSTSTRMIN pHstStrmIn = NULL; 1177 while ((pHstStrmIn = drvAudioFindAnyHstIn(pThis, pHstStrmIn))) 1178 { 1179 /* Disabled? Skip it! */ 1180 if (!(pHstStrmIn->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED)) 1181 continue; 1182 1183 /* Call the host backend to capture the audio input data. */ 1184 uint32_t cSamplesCaptured; 1185 int rc2 = pThis->pHostDrvAudio->pfnCaptureIn(pThis->pHostDrvAudio, pHstStrmIn, 1186 &cSamplesCaptured); 1187 if (RT_FAILURE(rc2)) 1188 continue; 1189 1190 PPDMAUDIOGSTSTRMIN pGstStrmIn = pHstStrmIn->pGstStrmIn; 1191 AssertPtrBreak(pGstStrmIn); 1192 1193 if (pGstStrmIn->State.fActive) 1194 { 1195 cbAvailIn = RT_MAX(cbAvailIn, AUDIOMIXBUF_S2B(&pHstStrmIn->MixBuf, 1196 AudioMixBufMixed(&pHstStrmIn->MixBuf))); 1197 #ifdef DEBUG_andy 1198 LogFlowFunc(("\t[%s] cbAvailIn=%RU32\n", pHstStrmIn->MixBuf.pszName, cbAvailIn)); 1199 #endif 1200 } 1201 } 1202 1203 if (RT_SUCCESS(rc)) 1204 { 1205 if (pcbAvailIn) 1206 *pcbAvailIn = cbAvailIn; 1207 } 1208 1209 int rc2 = RTCritSectLeave(&pThis->CritSect); 1210 if (RT_SUCCESS(rc)) 1211 rc = rc2; 1212 1213 if (RT_FAILURE(rc)) 1214 LogFlowFuncLeaveRC(rc); 1215 1216 return rc; 1217 } 1218 1219 static DECLCALLBACK(int) drvAudioGetDataOut(PPDMIAUDIOCONNECTOR pInterface, uint32_t *pcbFreeOut, uint32_t *pcSamplesLive) 1220 { 1221 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 1169 1222 /* pcbFreeOut is optional. */ 1170 1223 /* pcSamplesLive is optional. */ … … 1234 1287 } 1235 1288 1236 /*1237 * Recording.1238 */1239 uint32_t cbAvailIn = 0;1240 1241 PPDMAUDIOHSTSTRMIN pHstStrmIn = NULL;1242 while ((pHstStrmIn = drvAudioFindAnyHstIn(pThis, pHstStrmIn)))1243 {1244 /* Disabled? Skip it! */1245 if (!(pHstStrmIn->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED))1246 continue;1247 1248 /* Call the host backend to capture the audio input data. */1249 uint32_t cSamplesCaptured;1250 int rc2 = pThis->pHostDrvAudio->pfnCaptureIn(pThis->pHostDrvAudio, pHstStrmIn,1251 &cSamplesCaptured);1252 if (RT_FAILURE(rc2))1253 continue;1254 1255 PPDMAUDIOGSTSTRMIN pGstStrmIn = pHstStrmIn->pGstStrmIn;1256 AssertPtrBreak(pGstStrmIn);1257 1258 if (pGstStrmIn->State.fActive)1259 {1260 cbAvailIn = RT_MAX(cbAvailIn, AUDIOMIXBUF_S2B(&pHstStrmIn->MixBuf,1261 AudioMixBufMixed(&pHstStrmIn->MixBuf)));1262 #ifdef DEBUG_andy1263 LogFlowFunc(("\t[%s] cbAvailIn=%RU32\n", pHstStrmIn->MixBuf.pszName, cbAvailIn));1264 #endif1265 }1266 }1267 1268 1289 if (RT_SUCCESS(rc)) 1269 1290 { 1270 1291 if (cbFreeOut == UINT32_MAX) 1271 1292 cbFreeOut = 0; 1272 1273 if (pcbAvailIn)1274 *pcbAvailIn = cbAvailIn;1275 1293 1276 1294 if (pcbFreeOut) … … 1713 1731 if (RT_SUCCESS(rc)) 1714 1732 rc = drvAudioControlHstOut(pThis, pHstStrmOut, PDMAUDIOSTREAMCMD_ENABLE); 1733 1734 if (RT_SUCCESS(rc)) 1735 pGstStrmOut->State.fActive = fEnable; 1715 1736 } 1716 1737 else /* Disable */ … … 1718 1739 if (pHstStrmOut->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED) 1719 1740 { 1720 uint32_t cGstStrmsActive = 0;1741 size_t cGstStrmsActive = 0; 1721 1742 1722 1743 /* … … 1738 1759 1739 1760 /* Do we need to defer closing the host stream? */ 1740 if (cGstStrmsActive >= 1) 1761 if (cGstStrmsActive) 1762 { 1763 LogFlowFunc(("Closing stream deferred: %zu guest stream(s) active\n", cGstStrmsActive)); 1741 1764 pHstStrmOut->fStatus |= PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE; 1742 1765 1743 /* Can we close the host stream now instead of deferring it? */ 1744 if (!(pHstStrmOut->fStatus & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE)) 1766 rc = VERR_AUDIO_STREAM_PENDING_DISABLE; 1767 } 1768 else 1769 { 1745 1770 rc = drvAudioControlHstOut(pThis, pHstStrmOut, PDMAUDIOSTREAMCMD_DISABLE); 1746 }1747 }1748 1749 if (RT_SUCCESS(rc))1750 pGstStrmOut->State.fActive = fEnable;1771 if (RT_SUCCESS(rc)) 1772 pGstStrmOut->State.fActive = fEnable; 1773 } 1774 } 1775 } 1751 1776 1752 1777 LogFlowFunc(("%s: fEnable=%RTbool, fStatus=0x%x, rc=%Rrc\n", … … 2071 2096 pDrvIns->IBase.pfnQueryInterface = drvAudioQueryInterface; 2072 2097 /* IAudioConnector. */ 2073 pThis->IAudioConnector.pfnQueryStatus = drvAudioQueryStatus;2074 2098 pThis->IAudioConnector.pfnAddRefIn = drvAudioAddRefIn; 2075 2099 pThis->IAudioConnector.pfnAddRefOut = drvAudioAddRefOut; … … 2079 2103 pThis->IAudioConnector.pfnWrite = drvAudioWrite; 2080 2104 pThis->IAudioConnector.pfnGetConfig = drvAudioGetConfig; 2105 pThis->IAudioConnector.pfnGetDataIn = drvAudioGetDataIn; 2106 pThis->IAudioConnector.pfnGetDataOut = drvAudioGetDataOut; 2081 2107 pThis->IAudioConnector.pfnIsActiveIn = drvAudioIsActiveIn; 2082 2108 pThis->IAudioConnector.pfnIsActiveOut = drvAudioIsActiveOut; -
trunk/src/VBox/Devices/Audio/DrvAudio.h
r60925 r61050 115 115 const char *DrvAudioAudFmtToStr(PDMAUDIOFMT enmFmt); 116 116 void DrvAudioClearBuf(PPDMPCMPROPS pPCMInfo, void *pvBuf, size_t cbBuf, uint32_t cSamples); 117 bool DrvAudioPCMPropsAreEqual(PPDMPCMPROPS pProps1, PPDMPCMPROPS pProps2); 117 118 bool DrvAudioPCMPropsAreEqual(PPDMPCMPROPS pPCMInfo, PPDMAUDIOSTREAMCFG pCfg); 118 119 const char *DrvAudRecSrcToStr(PDMAUDIORECSOURCE enmRecSource); -
trunk/src/VBox/Devices/Audio/DrvAudioCommon.cpp
r60925 r61050 205 205 bool DrvAudioPCMPropsAreEqual(PPDMPCMPROPS pProps, PPDMAUDIOSTREAMCFG pCfg) 206 206 { 207 AssertPtrReturn(pProps, VERR_INVALID_POINTER); 208 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 209 207 210 int cBits = 8; 208 211 bool fSigned = false; … … 238 241 && pProps->fSwapEndian == !(pCfg->enmEndianness == PDMAUDIOHOSTENDIANNESS); 239 242 return fEqual; 243 } 244 245 bool DrvAudioPCMPropsAreEqual(PPDMPCMPROPS pProps1, PPDMPCMPROPS pProps2) 246 { 247 AssertPtrReturn(pProps1, VERR_INVALID_POINTER); 248 AssertPtrReturn(pProps2, VERR_INVALID_POINTER); 249 250 return pProps1->uHz == pProps2->uHz 251 && pProps1->cChannels == pProps2->cChannels 252 && pProps1->fSigned == pProps2->fSigned 253 && pProps1->cBits == pProps2->cBits 254 && pProps1->fSwapEndian == pProps2->fSwapEndian; 240 255 } 241 256 -
trunk/src/VBox/Devices/Audio/DrvHostPulseAudio.cpp
r60925 r61050 636 636 pStrm->BufAttr.maxlength = (pStrm->BufAttr.tlength * 3) / 2; 637 637 pStrm->BufAttr.prebuf = -1; /* Same as tlength */ 638 pStrm->BufAttr.minreq = -1; /* Pulse should set something sensible for minreq on it's own */ 638 639 /* Set minreq to 0, as we want to control ourselves when to start/stop the stream. */ 640 pStrm->BufAttr.minreq = 0; 639 641 640 642 /* Note that the struct BufAttr is updated to the obtained values after this call! */
Note:
See TracChangeset
for help on using the changeset viewer.