- Timestamp:
- Jun 9, 2016 10:22:39 AM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 107952
- Location:
- trunk
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/pdmaudioifs.h
r61523 r61609 174 174 * mixed together with data of other audio streams. */ 175 175 PDMAUDIOSTREAMLAYOUT_INTERLEAVED, 176 /** Complex layout, which does not fit into the 177 * interleaved / non-interleaved layouts. */ 178 PDMAUDIOSTREAMLAYOUT_COMPLEX, 176 179 /** Hack to blow the type up to 32-bit. */ 177 180 PDMAUDIOSTREAMLAYOUT_32BIT_HACK = 0x7fffffff … … 503 506 } PDMAUDIOSTREAMCTX; 504 507 508 /** 509 * Structure for keeping audio input stream specifics. 510 * Do not use directly. Instead, use PDMAUDIOSTREAM. 511 */ 505 512 typedef struct PDMAUDIOSTREAMIN 506 513 { 507 508 514 } PDMAUDIOSTREAMIN, *PPDMAUDIOSTREAMIN; 509 515 516 /** 517 * Structure for keeping audio output stream specifics. 518 * Do not use directly. Instead, use PDMAUDIOSTREAM. 519 */ 510 520 typedef struct PDMAUDIOSTREAMOUT 511 521 { 512 513 522 } PDMAUDIOSTREAMOUT, *PPDMAUDIOSTREAMOUT; 514 523 … … 516 525 typedef PDMAUDIOSTREAM *PPDMAUDIOSTREAM; 517 526 527 /** 528 * Structure for maintaining an nput/output audio stream. 529 */ 518 530 typedef struct PDMAUDIOSTREAM 519 531 { … … 538 550 /** Context of this stream. */ 539 551 PDMAUDIOSTREAMCTX enmCtx; 540 typedef union 552 /** Union for input/output specifics. */ 553 union 541 554 { 542 555 PDMAUDIOSTREAMIN In; 543 556 PDMAUDIOSTREAMOUT Out; 544 } InOut;557 }; 545 558 } PDMAUDIOSTREAM, *PPDMAUDIOSTREAM; 546 559 … … 699 712 700 713 /** 701 * Retrieves the status of a specific audio stream. 714 * Returns the number of readable data (in bytes) of a specific audio input stream. 715 * 716 * @returns Number of readable data (in bytes). 717 * @param pInterface Pointer to the interface structure containing the called function pointer. 718 * @param pStream Pointer to audio stream. 719 */ 720 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetReadable, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream)); 721 722 /** 723 * Returns the number of writable data (in bytes) of a specific audio output stream. 724 * 725 * @returns Number of writable data (in bytes). 726 * @param pInterface Pointer to the interface structure containing the called function pointer. 727 * @param pStream Pointer to audio stream. 728 */ 729 DECLR3CALLBACKMEMBER(uint32_t, pfnStreamGetWritable, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream)); 730 731 /** 732 * Returns the status of a specific audio stream. 702 733 * 703 734 * @returns Audio stream status … … 743 774 744 775 /** PDMIAUDIOCONNECTOR interface ID. */ 745 #define PDMIAUDIOCONNECTOR_IID " D1B6465D-E3DD-455B-9E05-FB6D56F7D472"776 #define PDMIAUDIOCONNECTOR_IID "C850CCE0-C5F4-42AB-BFC5-BACB41A8284D" 746 777 747 778 -
trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp
r61523 r61609 191 191 192 192 /** 193 * Returns available number of samples for processing.194 *195 * @return uint32_t Number of samples available for reading.196 * @param pMixBuf Mixing buffer to return value for.197 */198 uint32_t AudioMixBufAvail(PPDMAUDIOMIXBUF pMixBuf)199 {200 AssertPtrReturn(pMixBuf, 0);201 202 uint32_t cAvail;203 if (pMixBuf->pParent) /* Is this a child buffer? */204 cAvail = pMixBuf->cMixed;205 else206 cAvail = pMixBuf->cUsed;207 208 Assert(cAvail <= pMixBuf->cSamples);209 return cAvail;210 }211 212 /**213 193 * Clears the entire sample buffer. 214 194 * … … 327 307 AssertPtrReturn(pMixBuf, 0); 328 308 329 uint32_t cSamples Free;309 uint32_t cSamples, cSamplesFree; 330 310 if (pMixBuf->pParent) 331 311 { … … 334 314 * already have been consumed by the parent. 335 315 */ 336 Assert(pMixBuf->cMixed <= pMixBuf->pParent->cSamples); 337 cSamplesFree = pMixBuf->pParent->cSamples - pMixBuf->cMixed; 316 cSamples = pMixBuf->pParent->cSamples; 317 318 Assert(pMixBuf->cMixed <= cSamples); 319 cSamplesFree = cSamples - pMixBuf->cMixed; 338 320 } 339 321 else /* As a parent. */ 340 322 { 341 Assert(pMixBuf->cSamples >= pMixBuf->cUsed); 323 cSamples = pMixBuf->cSamples; 324 Assert(cSamples >= pMixBuf->cUsed); 342 325 cSamplesFree = pMixBuf->cSamples - pMixBuf->cUsed; 343 326 } 344 327 345 AUDMIXBUF_LOG(("%s: cSamplesFree=%RU32\n", pMixBuf->pszName, cSamplesFree));328 AUDMIXBUF_LOG(("%s: %RU32 of %RU32\n", pMixBuf->pszName, cSamplesFree, cSamples)); 346 329 return cSamplesFree; 347 330 } … … 920 903 921 904 /** 922 * Returns the number of audio samples mixed (processed) by 923 * the parent mixing buffer. 924 * 925 * @return uint32_t Number of audio samples mixed (processed). 926 * @param pMixBuf Mixing buffer to return number from. 927 */ 928 uint32_t AudioMixBufMixed(PPDMAUDIOMIXBUF pMixBuf) 905 * Returns number of available live samples. 906 * 907 * @return uint32_t Number of live samples available. 908 * @param pMixBuf Mixing buffer to return value for. 909 */ 910 uint32_t AudioMixBufLive(PPDMAUDIOMIXBUF pMixBuf) 929 911 { 930 912 AssertPtrReturn(pMixBuf, 0); 931 913 932 AssertMsgReturn(VALID_PTR(pMixBuf->pParent), 933 ("Buffer is not linked to a parent buffer\n"), 934 0); 935 936 AUDMIXBUF_LOG(("%s: cMixed=%RU32\n", pMixBuf->pszName, pMixBuf->cMixed)); 937 return pMixBuf->cMixed; 914 uint32_t cSamples, cAvail; 915 if (pMixBuf->pParent) /* Is this a child buffer? */ 916 { 917 /* Use the sample count from the parent, as 918 * pMixBuf->cMixed specifies the sample count 919 * in parent samples. */ 920 cSamples = pMixBuf->pParent->cSamples; 921 cAvail = pMixBuf->cMixed; 922 } 923 else 924 { 925 cSamples = pMixBuf->cSamples; 926 cAvail = pMixBuf->cUsed; 927 } 928 929 Assert(cAvail <= cSamples); 930 return cAvail; 938 931 } 939 932 … … 944 937 * @param pDst Destination mixing buffer. 945 938 * @param pSrc Source mixing buffer. 946 * @param cS amplesNumber of source audio samples to mix.939 * @param cSrcSamples Number of source audio samples to mix. 947 940 * @param pcProcessed Number of audio samples successfully mixed. 948 941 */ 949 static int audioMixBufMixTo(PPDMAUDIOMIXBUF pDst, PPDMAUDIOMIXBUF pSrc, uint32_t cS amples, uint32_t *pcProcessed)942 static int audioMixBufMixTo(PPDMAUDIOMIXBUF pDst, PPDMAUDIOMIXBUF pSrc, uint32_t cSrcSamples, uint32_t *pcProcessed) 950 943 { 951 944 AssertPtrReturn(pDst, VERR_INVALID_POINTER); … … 969 962 Assert(pSrc->cUsed >= pDst->cMixed); 970 963 971 uint32_t cSrcAvail = RT_MIN(cS amples, pSrc->cUsed - pDst->cMixed);964 uint32_t cSrcAvail = RT_MIN(cSrcSamples, pSrc->cUsed - pDst->cMixed); 972 965 uint32_t offSrcRead = pSrc->offRead; 973 966 uint32_t cDstMixed = pSrc->cMixed; … … 985 978 } 986 979 987 AUDMIXBUF_LOG(("cS amples=%RU32, cSrcAvail=%RU32 -> cDstAvail=%RU32\n",cSamples, cSrcAvail, cDstAvail));980 AUDMIXBUF_LOG(("cSrcSamples=%RU32, cSrcAvail=%RU32 -> cDstAvail=%RU32\n", cSrcSamples, cSrcAvail, cDstAvail)); 988 981 989 982 #ifdef DEBUG … … 1094 1087 * @return IPRT status code. 1095 1088 * @param pMixBuf Mixing buffer to mix samples down to parent. 1096 * @param cSamples Number of audio samples to mix down. 1089 * @param cSamples Number of audio samples of specified mixing buffer to to mix 1090 * to its attached parent mixing buffer (if any). 1097 1091 * @param pcProcessed Number of audio samples successfully processed. Optional. 1098 1092 */ -
trunk/src/VBox/Devices/Audio/AudioMixBuffer.h
r61320 r61609 51 51 52 52 int AudioMixBufAcquire(PPDMAUDIOMIXBUF pMixBuf, uint32_t cSamplesToRead, PPDMAUDIOSAMPLE *ppvSamples, uint32_t *pcSamplesRead); 53 uint32_t AudioMixBufAvail(PPDMAUDIOMIXBUF pMixBuf);54 53 inline uint32_t AudioMixBufBytesToSamples(PPDMAUDIOMIXBUF pMixBuf); 55 54 void AudioMixBufClear(PPDMAUDIOMIXBUF pMixBuf); … … 61 60 bool AudioMixBufIsEmpty(PPDMAUDIOMIXBUF pMixBuf); 62 61 int AudioMixBufLinkTo(PPDMAUDIOMIXBUF pMixBuf, PPDMAUDIOMIXBUF pParent); 63 uint32_t AudioMixBuf Mixed(PPDMAUDIOMIXBUF pMixBuf);62 uint32_t AudioMixBufLive(PPDMAUDIOMIXBUF pMixBuf); 64 63 int AudioMixBufMixToParent(PPDMAUDIOMIXBUF pMixBuf, uint32_t cSamples, uint32_t *pcProcessed); 65 64 uint32_t AudioMixBufUsed(PPDMAUDIOMIXBUF pMixBuf); -
trunk/src/VBox/Devices/Audio/AudioMixer.cpp
r61523 r61609 55 55 static void audioMixerSinkRemoveAllStreamsInternal(PAUDMIXSINK pSink); 56 56 static int audioMixerSinkRemoveStreamInternal(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream); 57 static void audioMixerSinkReset(PAUDMIXSINK pSink); 57 58 static int audioMixerSinkUpdateInternal(PAUDMIXSINK pSink); 58 59 … … 78 79 { 79 80 pSink->pParent = pMixer; 80 pSink->cStreams = 0;81 81 pSink->enmDir = enmDir; 82 82 RTListInit(&pSink->lstStreams); … … 479 479 pSink->fStatus &= ~AUDMIXSINK_STS_RUNNING; 480 480 481 /* Not running anymore? Reset. */ 482 if (!(pSink->fStatus & AUDMIXSINK_STS_RUNNING)) 483 audioMixerSinkReset(pSink); 484 481 485 LogFlowFunc(("[%s]: enmCmd=%ld, fStatus=0x%x, rc=%Rrc\n", pSink->pszName, enmSinkCmd, pSink->fStatus, rc)); 482 486 return rc; … … 528 532 RTMemFree(pSink); 529 533 pSink = NULL; 534 } 535 536 /** 537 * Returns the amount of bytes ready to be read from a sink since the last call 538 * to AudioMixerSinkUpdate(). 539 * 540 * @returns Amount of bytes ready to be read from the sink. 541 * @param pSink Sink to return number of available samples for. 542 */ 543 uint32_t AudioMixerSinkGetReadable(PAUDMIXSINK pSink) 544 { 545 AssertPtrReturn(pSink, 0); 546 547 AssertMsg(pSink->enmDir == AUDMIXSINKDIR_INPUT, ("Can't read from a non-input sink\n")); 548 549 #ifdef VBOX_AUDIO_MIXER_WITH_MIXBUF 550 # error "Implement me!" 551 #else 552 LogFlowFunc(("[%s]: cbReadable=%RU32\n", pSink->pszName, pSink->In.cbReadable)); 553 return pSink->In.cbReadable; 554 #endif 555 } 556 557 /** 558 * Returns the amount of bytes ready to be written to a sink since the last call 559 * to AudioMixerSinkUpdate(). 560 * 561 * @returns Amount of bytes ready to be written to the sink. 562 * @param pSink Sink to return number of available samples for. 563 */ 564 uint32_t AudioMixerSinkGetWritable(PAUDMIXSINK pSink) 565 { 566 AssertPtrReturn(pSink, 0); 567 568 AssertMsg(pSink->enmDir == AUDMIXSINKDIR_OUTPUT, ("Can't write to a non-output sink\n")); 569 570 #ifdef VBOX_AUDIO_MIXER_WITH_MIXBUF 571 # error "Implement me!" 572 #else 573 LogFlowFunc(("[%s]: cbWritable=%RU32\n", pSink->pszName, pSink->Out.cbWritable)); 574 return pSink->Out.cbWritable; 575 #endif 530 576 } 531 577 … … 721 767 722 768 /** 769 * Resets the sink's state. 770 * 771 * @param pSink Sink to reset. 772 */ 773 static void audioMixerSinkReset(PAUDMIXSINK pSink) 774 { 775 if (!pSink) 776 return; 777 778 LogFunc(("%s\n", pSink->pszName)); 779 780 if (pSink->enmDir == AUDMIXSINKDIR_INPUT) 781 { 782 #ifdef VBOX_AUDIO_MIXER_WITH_MIXBUF 783 AudioMixBufReset(&pSink->MixBuf); 784 #else 785 pSink->In.cbReadable = 0; 786 #endif 787 } 788 else if (pSink->enmDir == AUDMIXSINKDIR_OUTPUT) 789 { 790 #ifdef VBOX_AUDIO_MIXER_WITH_MIXBUF 791 AudioMixBufReset(&pSink->MixBuf); 792 #else 793 pSink->Out.cbWritable = 0; 794 #endif 795 } 796 } 797 798 /** 723 799 * Removes all attached streams from a given sink. 724 800 * … … 792 868 } 793 869 794 void AudioMixerSinkTimerUpdate(PAUDMIXSINK pSink, uint64_t cTimerTicks, uint64_t cTicksElapsed)795 {796 AssertPtrReturnVoid(pSink);797 798 /* Note: cTimerTicks / cTicksElapsed = Hz elapsed. */799 800 LogFlowFunc(("[%s]: cTimerTicks=%RU64, cTicksElapsed=%RU64 -> %zuHz\n",801 pSink->pszName, cTimerTicks, cTicksElapsed, cTimerTicks / cTicksElapsed));802 803 audioMixerSinkUpdateInternal(pSink);804 }805 806 870 static int audioMixerSinkUpdateInternal(PAUDMIXSINK pSink) 807 871 { … … 811 875 812 876 Log3Func(("[%s]\n", pSink->pszName)); 877 878 /* Update last updated timestamp. */ 879 pSink->tsLastUpdatedNS = RTTimeNanoTS(); 813 880 814 881 PAUDMIXSTREAM pMixStream; 815 882 RTListForEach(&pSink->lstStreams, pMixStream, AUDMIXSTREAM, Node) 816 883 { 817 PPDMAUDIOSTREAM pStream = pMixStream->pStream;884 PPDMAUDIOSTREAM pStream = pMixStream->pStream; 818 885 AssertPtr(pStream); 886 887 PPDMIAUDIOCONNECTOR pConn = pMixStream->pConn; 888 AssertPtr(pConn); 819 889 820 890 uint32_t cPlayed = 0; 821 891 uint32_t cCaptured = 0; 822 892 823 int rc2 = p MixStream->pConn->pfnStreamIterate(pMixStream->pConn, pStream);893 int rc2 = pConn->pfnStreamIterate(pConn, pStream); 824 894 if (RT_SUCCESS(rc2)) 825 895 { 826 if (pS tream->enmDir == PDMAUDIODIR_IN)896 if (pSink->enmDir == AUDMIXSINKDIR_INPUT) 827 897 { 828 rc = p MixStream->pConn->pfnStreamCapture(pMixStream->pConn, pMixStream->pStream, &cCaptured);898 rc = pConn->pfnStreamCapture(pConn, pMixStream->pStream, &cCaptured); 829 899 if (RT_FAILURE(rc2)) 830 900 { 831 LogFlowFunc(("%s: Failed captur e stream '%s':%Rrc\n", pSink->pszName, pMixStream->pStream->szName, rc2));901 LogFlowFunc(("%s: Failed capturing stream '%s', rc=%Rrc\n", pSink->pszName, pMixStream->pStream->szName, rc2)); 832 902 if (RT_SUCCESS(rc)) 833 903 rc = rc2; 904 continue; 834 905 } 835 906 … … 837 908 pSink->fStatus |= AUDMIXSINK_STS_DIRTY; 838 909 } 839 else if (pS tream->enmDir == PDMAUDIODIR_OUT)910 else if (pSink->enmDir == AUDMIXSINKDIR_OUTPUT) 840 911 { 841 rc2 = p MixStream->pConn->pfnStreamPlay(pMixStream->pConn, pMixStream->pStream, &cPlayed);912 rc2 = pConn->pfnStreamPlay(pConn, pMixStream->pStream, NULL /* cPlayed */); 842 913 if (RT_FAILURE(rc2)) 843 914 { 844 LogFlowFunc(("%s: Failed playing stream '%s' :%Rrc\n", pSink->pszName, pMixStream->pStream->szName, rc2));915 LogFlowFunc(("%s: Failed playing stream '%s', rc=%Rrc\n", pSink->pszName, pMixStream->pStream->szName, rc2)); 845 916 if (RT_SUCCESS(rc)) 846 917 rc = rc2; 918 continue; 847 919 } 848 920 } 849 921 else 922 { 850 923 AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED); 924 continue; 925 } 926 927 rc2 = pConn->pfnStreamIterate(pConn, pStream); 928 if (RT_FAILURE(rc2)) 929 { 930 LogFlowFunc(("%s: Failed re-iterating stream '%s', rc=%Rrc\n", pSink->pszName, pMixStream->pStream->szName, rc2)); 931 if (RT_SUCCESS(rc)) 932 rc = rc2; 933 continue; 934 } 935 936 if (pSink->enmDir == AUDMIXSINKDIR_INPUT) 937 { 938 #ifdef VBOX_AUDIO_MIXER_WITH_MIXBUF 939 # error "Implement me!" 940 #else 941 pSink->In.cbReadable = pConn->pfnStreamGetReadable(pConn, pMixStream->pStream); 942 #endif 943 } 944 else if (pSink->enmDir == AUDMIXSINKDIR_OUTPUT) 945 { 946 #ifdef VBOX_AUDIO_MIXER_WITH_MIXBUF 947 # error "Implement me!" 948 #else 949 pSink->Out.cbWritable = pConn->pfnStreamGetWritable(pConn, pMixStream->pStream); 950 #endif 951 } 851 952 } 852 953 … … 862 963 int AudioMixerSinkUpdate(PAUDMIXSINK pSink) 863 964 { 965 AssertPtrReturn(pSink, VERR_INVALID_POINTER); 966 967 uint64_t tsElapsed = RTTimeNanoTS() - pSink->tsLastUpdatedNS; 968 969 /* 970 * Note: Hz elapsed = cTicksElapsed / cTimerTicks 971 * Bytes / second = Sample rate (Hz) * Audio channels * Bytes per sample 972 */ 973 // uint32_t cSamples = (int)((pSink->PCMProps.cChannels * cTicksElapsed * pSink->PCMProps.uHz + cTimerTicks) / cTimerTicks / pSink->PCMProps.cChannels); 974 975 // LogFlowFunc(("[%s]: cTimerTicks=%RU64, cTicksElapsed=%RU64\n", pSink->pszName, cTimerTicks, cTicksElapsed)); 976 // LogFlowFunc(("\t%zuHz elapsed, %RU32 samples (%RU32 bytes)\n", cTicksElapsed / cTimerTicks, cSamples, cSamples << 1)); 977 864 978 return audioMixerSinkUpdateInternal(pSink); 865 979 } -
trunk/src/VBox/Devices/Audio/AudioMixer.h
r61523 r61609 115 115 116 116 /** 117 * Structure for keeping audio input sink specifics. 118 * Do not use directly. Instead, use AUDMIXSINK. 119 */ 120 typedef struct AUDMIXSINKIN 121 { 122 #ifdef VBOX_AUDIO_MIXER_WITH_MIXBUF 123 /** This sink's mixing buffer, acting as 124 * a parent buffer for all streams this sink owns. */ 125 PDMAUDIOMIXBUF MixBuf; 126 #else 127 /** Number of bytes available to read from the sink. */ 128 uint32_t cbReadable; 129 #endif 130 } AUDMIXSINKIN; 131 132 /** 133 * Structure for keeping audio output sink specifics. 134 * Do not use directly. Instead, use AUDMIXSINK. 135 */ 136 typedef struct AUDMIXSINKOUT 137 { 138 #ifdef VBOX_AUDIO_MIXER_WITH_MIXBUF 139 /** This sink's mixing buffer, acting as 140 * a parent buffer for all streams this sink owns. */ 141 PDMAUDIOMIXBUF MixBuf; 142 #else 143 /** Number of bytes available to write to the sink. */ 144 uint32_t cbWritable; 145 #endif 146 } AUDMIXSINKOUT; 147 148 /** 117 149 * Structure for maintaining an audio mixer sink. 118 150 */ … … 127 159 * if this sink handles input or output. */ 128 160 AUDMIXSINKDIR enmDir; 161 /** Union for input/output specifics. */ 162 union 163 { 164 AUDMIXSINKIN In; 165 AUDMIXSINKOUT Out; 166 }; 129 167 /** Sink status of type AUDMIXSINK_STS_XXX. */ 130 168 AUDMIXSINKSTS fStatus; … … 138 176 /** @todo Use something faster -- vector maybe? */ 139 177 RTLISTANCHOR lstStreams; 140 #ifdef VBOX_AUDIO_MIXER_WITH_MIXBUF141 /** This sink's mixing buffer, acting as142 * a parent buffer for all streams this sink owns. */143 PDMAUDIOMIXBUF MixBuf;144 #endif145 178 /** The volume of this sink. The volume always will 146 179 * be combined with the mixer's master volume. */ 147 180 PDMAUDIOVOLUME Volume; 181 /** Timestamp (in ns) since last update. */ 182 uint64_t tsLastUpdatedNS; 148 183 } AUDMIXSINK, *PAUDMIXSINK; 149 184 … … 178 213 int AudioMixerSinkCtl(PAUDMIXSINK pSink, AUDMIXSINKCMD enmCmd); 179 214 void AudioMixerSinkDestroy(PAUDMIXSINK pSink); 215 uint32_t AudioMixerSinkGetReadable(PAUDMIXSINK pSink); 216 uint32_t AudioMixerSinkGetWritable(PAUDMIXSINK pSink); 180 217 AUDMIXSINKDIR AudioMixerSinkGetDir(PAUDMIXSINK pSink); 181 218 PAUDMIXSTREAM AudioMixerSinkGetStream(PAUDMIXSINK pSink, uint8_t uIndex); … … 187 224 int AudioMixerSinkSetFormat(PAUDMIXSINK pSink, PPDMPCMPROPS pPCMProps); 188 225 int AudioMixerSinkSetVolume(PAUDMIXSINK pSink, PPDMAUDIOVOLUME pVol); 189 void AudioMixerSinkTimerUpdate(PAUDMIXSINK pSink, uint64_t cTimerTicks, uint64_t cTicksElapsed );226 void AudioMixerSinkTimerUpdate(PAUDMIXSINK pSink, uint64_t cTimerTicks, uint64_t cTicksElapsed, uint32_t *pcbToProcess); 190 227 int AudioMixerSinkWrite(PAUDMIXSINK pSink, AUDMIXOP enmOp, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten); 191 228 int AudioMixerSinkUpdate(PAUDMIXSINK pSink); -
trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
r61529 r61609 424 424 static DECLCALLBACK(void) ichac97Timer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser); 425 425 #endif 426 static int ichac97TransferAudio(PAC97STATE pThis, PAC97STREAM pStream );426 static int ichac97TransferAudio(PAC97STATE pThis, PAC97STREAM pStream, uint32_t cbToProcess, uint32_t *pcbProcessed); 427 427 428 428 static void ichac97WarmReset(PAC97STATE pThis) … … 530 530 static bool ichac97StreamIsActive(PAC97STATE pThis, PAC97STREAM pStream) 531 531 { 532 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 533 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 534 535 bool fActive = AudioMixerSinkGetStatus(ichac97IndexToSink(pThis, pStream->u8Strm)); 532 AssertPtrReturn(pThis, false); 533 AssertPtrReturn(pStream, false); 534 535 PAUDMIXSINK pSink = ichac97IndexToSink(pThis, pStream->u8Strm); 536 bool fActive = RT_BOOL(AudioMixerSinkGetStatus(pSink) & AUDMIXSINK_STS_RUNNING); 536 537 537 538 LogFlowFunc(("SD=%RU8, fActive=%RTbool\n", pStream->u8Strm, fActive)); … … 1321 1322 static void ichac97TimerMaybeStart(PAC97STATE pThis) 1322 1323 { 1323 LogFlowFunc(("cStreamsActive=%RU8\n", pThis->cStreamsActive));1324 1325 1324 if (pThis->cStreamsActive == 0) /* Only start the timer if there are no active streams. */ 1326 1325 return; … … 1329 1328 return; 1330 1329 1330 LogFlowFunc(("Starting timer\n")); 1331 1331 1332 /* Set timer flag. */ 1332 1333 ASMAtomicXchgBool(&pThis->fTimerActive, true); … … 1341 1342 static void ichac97TimerMaybeStop(PAC97STATE pThis) 1342 1343 { 1343 LogFlowFunc(("cStreamsActive=%RU8\n", pThis->cStreamsActive));1344 1345 1344 if (pThis->cStreamsActive) /* Some streams still active? Bail out. */ 1346 1345 return; … … 1348 1347 if (!pThis->pTimer) 1349 1348 return; 1349 1350 LogFlowFunc(("Stopping timer\n")); 1350 1351 1351 1352 /* Set timer flag. */ … … 1374 1375 bool fKickTimer = false; 1375 1376 1376 AudioMixerSinkTimerUpdate(pThis->pSinkLineIn, pThis->cTimerTicks, cTicksPerSec); 1377 ichac97TransferAudio(pThis, &pThis->StreamLineIn); 1378 1379 fKickTimer = AudioMixerSinkGetStatus(pThis->pSinkLineIn) & AUDMIXSINK_STS_DIRTY; 1380 1381 AudioMixerSinkTimerUpdate(pThis->pSinkMicIn , pThis->cTimerTicks, cTicksPerSec); 1382 ichac97TransferAudio(pThis, &pThis->StreamMicIn); 1383 1384 fKickTimer = AudioMixerSinkGetStatus(pThis->pSinkMicIn) & AUDMIXSINK_STS_DIRTY; 1385 1386 AudioMixerSinkTimerUpdate(pThis->pSinkOutput, pThis->cTimerTicks, cTicksPerSec); 1387 ichac97TransferAudio(pThis, &pThis->StreamOut); 1388 1389 fKickTimer = AudioMixerSinkGetStatus(pThis->pSinkOutput) & AUDMIXSINK_STS_DIRTY; 1377 uint32_t cbToProcess; 1378 1379 int rc = AudioMixerSinkUpdate(pThis->pSinkLineIn); 1380 if (RT_SUCCESS(rc)) 1381 { 1382 cbToProcess = AudioMixerSinkGetReadable(pThis->pSinkLineIn); 1383 if (cbToProcess) 1384 { 1385 rc = ichac97TransferAudio(pThis, &pThis->StreamLineIn, cbToProcess, NULL /* pcbProcessed */); 1386 fKickTimer |= RT_SUCCESS(rc); 1387 } 1388 } 1389 1390 rc = AudioMixerSinkUpdate(pThis->pSinkMicIn); 1391 if (RT_SUCCESS(rc)) 1392 { 1393 cbToProcess = AudioMixerSinkGetReadable(pThis->pSinkMicIn); 1394 if (cbToProcess) 1395 { 1396 rc = ichac97TransferAudio(pThis, &pThis->StreamMicIn, cbToProcess, NULL /* pcbProcessed */); 1397 fKickTimer |= RT_SUCCESS(rc); 1398 } 1399 } 1400 1401 rc = AudioMixerSinkUpdate(pThis->pSinkOutput); 1402 if (RT_SUCCESS(rc)) 1403 { 1404 cbToProcess = AudioMixerSinkGetReadable(pThis->pSinkOutput); 1405 if (cbToProcess) 1406 { 1407 rc = ichac97TransferAudio(pThis, &pThis->StreamOut, cbToProcess, NULL /* pcbProcessed */); 1408 fKickTimer |= RT_SUCCESS(rc); 1409 } 1410 } 1390 1411 1391 1412 if ( ASMAtomicReadBool(&pThis->fTimerActive) … … 1403 1424 #endif /* !VBOX_WITH_AUDIO_CALLBACKS */ 1404 1425 1405 static int ichac97TransferAudio(PAC97STATE pThis, PAC97STREAM pStream) 1406 { 1426 static int ichac97TransferAudio(PAC97STATE pThis, PAC97STREAM pStream, uint32_t cbToProcess, uint32_t *pcbProcessed) 1427 { 1428 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1429 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1430 /* pcbProcessed is optional. */ 1431 1407 1432 Log3Func(("SD=%RU8\n", pStream->u8Strm)); 1408 1433 … … 1416 1441 { 1417 1442 case PO_INDEX: 1418 ichac97WriteBUP(pThis, (uint32_t)(pRegs->picb << 1));1443 ichac97WriteBUP(pThis, cbToProcess); 1419 1444 break; 1420 1445 … … 1424 1449 } 1425 1450 1451 if (pcbProcessed) 1452 *pcbProcessed = 0; 1426 1453 return VINF_SUCCESS; 1427 1454 } … … 1429 1456 /* BCIS flag still set? Skip iteration. */ 1430 1457 if (pRegs->sr & SR_BCIS) 1458 { 1459 if (pcbProcessed) 1460 *pcbProcessed = 0; 1431 1461 return VINF_SUCCESS; 1462 } 1432 1463 1433 1464 int rc = VINF_SUCCESS; 1434 uint32_t cbWrittenTotal = 0; 1435 1436 do 1465 1466 uint32_t cbLeft = cbToProcess; 1467 uint32_t cbTotal = 0; 1468 1469 while (cbLeft) 1437 1470 { 1438 1471 if (!pRegs->bd_valid) … … 1474 1507 && cbTransferred) 1475 1508 { 1476 cbWrittenTotal += cbTransferred; 1477 Assert((cbTransferred & 1) == 0); /* Else the following shift won't work */ 1478 pRegs->picb -= (cbTransferred >> 1); /** @todo r=andy Assumes 16bit samples. */ 1479 } 1480 break; 1481 } 1482 1483 case PI_INDEX: 1484 case MC_INDEX: 1485 { 1486 cbToTransfer = (uint32_t)(pRegs->picb << 1); 1487 1488 rc = ichac97ReadAudio(pThis, pStream, cbToTransfer, &cbTransferred); 1489 if ( RT_SUCCESS(rc) 1490 && cbTransferred) 1491 { 1509 cbTotal += cbTransferred; 1510 Assert(cbLeft >= cbTransferred); 1511 cbLeft -= cbTransferred; 1492 1512 Assert((cbTransferred & 1) == 0); /* Else the following shift won't work */ 1493 1513 pRegs->picb -= (cbTransferred >> 1); /** @todo r=andy Assumes 16bit samples. */ … … 1496 1516 } 1497 1517 1518 case PI_INDEX: 1519 case MC_INDEX: 1520 { 1521 cbToTransfer = (uint32_t)(pRegs->picb << 1); 1522 1523 rc = ichac97ReadAudio(pThis, pStream, cbToTransfer, &cbTransferred); 1524 if ( RT_SUCCESS(rc) 1525 && cbTransferred) 1526 { 1527 cbTotal += cbTransferred; 1528 Assert(cbLeft >= cbTransferred); 1529 cbLeft -= cbTransferred; 1530 Assert((cbTransferred & 1) == 0); /* Else the following shift won't work */ 1531 pRegs->picb -= (cbTransferred >> 1); /** @todo r=andy Assumes 16bit samples. */ 1532 } 1533 break; 1534 } 1535 1498 1536 default: 1499 1537 AssertMsgFailed(("Stream #%RU8 not supported\n", pStream->u8Strm)); … … 1502 1540 } 1503 1541 1504 Log3Func(("PICB=%RU16 (%#x), cbTransferred=%RU32 (%zu samples), cbWrittenTotal=%RU32\n", 1505 pRegs->picb, pRegs->picb, cbTransferred, (cbTransferred >> 1), cbWrittenTotal)); 1542 LogFlowFunc(("[SD%RU8]: %RU32 / %RU32, rc=%Rrc\n", pStream->u8Strm, cbTotal, cbToProcess, rc)); 1506 1543 1507 1544 if (!pRegs->picb) … … 1536 1573 if (rc == VINF_EOF) /* All data processed? */ 1537 1574 break; 1538 1539 } while (RT_SUCCESS(rc)); 1575 } 1576 1577 if (RT_SUCCESS(rc)) 1578 { 1579 if (pcbProcessed) 1580 *pcbProcessed = cbTotal; 1581 } 1540 1582 1541 1583 LogFlowFuncLeaveRC(rc); -
trunk/src/VBox/Devices/Audio/DevIchHda.cpp
r61529 r61609 942 942 static int hdaStreamStop(PHDASTREAM pStream); 943 943 static int hdaStreamWaitForStateChange(PHDASTREAM pStream, RTMSINTERVAL msTimeout); 944 static int hdaTransfer(PHDASTATE pThis, PHDASTREAM pStream );944 static int hdaTransfer(PHDASTATE pThis, PHDASTREAM pStream, uint32_t cbToProcess, uint32_t *pcbProcessed); 945 945 #endif 946 946 … … 966 966 static void hdaTimerMaybeStart(PHDASTATE pThis); 967 967 static void hdaTimerMaybeStop(PHDASTATE pThis); 968 static DECLCALLBACK(void) hdaTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser);969 968 #endif 970 969 … … 1765 1764 static bool hdaStreamIsActive(PHDASTATE pThis, PHDASTREAM pStream) 1766 1765 { 1766 AssertPtrReturn(pThis, false); 1767 AssertPtrReturn(pStream, false); 1768 1769 bool fActive = pStream->State.fActive; 1770 1771 LogFlowFunc(("SD=%RU8, fActive=%RTbool\n", pStream->u8SD, fActive)); 1772 return fActive; 1773 } 1774 1775 static int hdaStreamSetActive(PHDASTATE pThis, PHDASTREAM pStream, bool fActive) 1776 { 1767 1777 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1768 1778 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1769 1779 1770 bool fActive = pStream->State.fActive; 1771 1772 if (!fActive) 1773 { 1774 AssertPtr(pStream->pMixSink); 1780 LogFlowFunc(("[SD%RU8]: fActive=%RTbool, pMixSink=%p\n", pStream->u8SD, fActive, pStream->pMixSink)); 1781 1782 if (pStream->State.fActive == fActive) /* No change required? */ 1783 { 1784 LogFlowFunc(("[SD%RU8]: No change\n", pStream->u8SD)); 1785 return VINF_SUCCESS; 1786 } 1787 1788 int rc; 1789 1790 if (pStream->pMixSink) /* Stream attached to a sink? */ 1791 { 1792 AUDMIXSINKCMD enmCmd = fActive 1793 ? AUDMIXSINKCMD_ENABLE : AUDMIXSINKCMD_DISABLE; 1794 1795 /* First, enable or disable the stream and the stream's sink, if any. */ 1775 1796 if (pStream->pMixSink->pMixSink) 1776 fActive = AudioMixerSinkGetStatus(pStream->pMixSink->pMixSink) & AUDMIXSINK_STS_DIRTY; 1777 } 1778 1779 LogFlowFunc(("SD=%RU8, fActive=%RTbool\n", pStream->u8SD, fActive)); 1780 return fActive; 1781 } 1782 1783 static int hdaStreamSetActive(PHDASTATE pThis, PHDASTREAM pStream, bool fActive) 1784 { 1785 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1786 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1787 1788 if (!pStream->pMixSink) /* No mixer sink assigned? Bail out early. */ 1789 { 1790 LogFlowFunc(("u8Strm=%RU8 has no mixer sink assigned\n", pStream->u8SD)); 1791 return VINF_SUCCESS; 1792 } 1793 1794 AUDMIXSINKCMD enmCmd = fActive 1795 ? AUDMIXSINKCMD_ENABLE : AUDMIXSINKCMD_DISABLE; 1796 1797 /* First, enable or disable the stream and the stream's sink, if any. */ 1798 if (pStream->pMixSink->pMixSink) 1799 AudioMixerSinkCtl(pStream->pMixSink->pMixSink, enmCmd); 1797 rc = AudioMixerSinkCtl(pStream->pMixSink->pMixSink, enmCmd); 1798 } 1799 else 1800 rc = VINF_SUCCESS; 1801 1802 if (RT_FAILURE(rc)) 1803 { 1804 LogFlowFunc(("Failed with rc=%Rrc\n", rc)); 1805 return rc; 1806 } 1800 1807 1801 1808 pStream->State.fActive = fActive; … … 3482 3489 * but "reports bytes" when all conditions are met (FIFOW). 3483 3490 */ 3484 static int hdaReadAudio(PHDASTATE pThis, PHDASTREAM pStream, uint32_t cbTo Process, uint32_t *pcbProcessed)3491 static int hdaReadAudio(PHDASTATE pThis, PHDASTREAM pStream, uint32_t cbToRead, uint32_t *pcbRead) 3485 3492 { 3486 3493 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 3487 3494 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 3488 /* pcb Processed is optional. */3495 /* pcbRead is optional. */ 3489 3496 3490 3497 int rc; … … 3495 3502 PHDABDLE pBDLE = &pStream->State.BDLE; 3496 3503 3497 if (!cbTo Process)3504 if (!cbToRead) 3498 3505 { 3499 3506 rc = VINF_EOF; … … 3503 3510 AssertPtr(pStream->pMixSink); 3504 3511 AssertPtr(pStream->pMixSink->pMixSink); 3505 rc = AudioMixerSinkRead(pStream->pMixSink->pMixSink, AUDMIXOP_BLEND, pBDLE->State.au8FIFO, cbTo Process, &cbRead);3512 rc = AudioMixerSinkRead(pStream->pMixSink->pMixSink, AUDMIXOP_BLEND, pBDLE->State.au8FIFO, cbToRead, &cbRead); 3506 3513 if (RT_FAILURE(rc)) 3507 3514 break; … … 3514 3521 3515 3522 /* Sanity checks. */ 3516 Assert(cbRead <= cbTo Process);3523 Assert(cbRead <= cbToRead); 3517 3524 Assert(cbRead <= sizeof(pBDLE->State.au8FIFO)); 3518 3525 Assert(cbRead <= pBDLE->u32BufSize - pBDLE->State.u32BufOff); … … 3548 3555 if (RT_SUCCESS(rc)) 3549 3556 { 3550 if (pcb Processed)3551 *pcb Processed = cbRead;3557 if (pcbRead) 3558 *pcbRead = cbRead; 3552 3559 } 3553 3560 … … 3558 3565 } 3559 3566 3560 static int hdaWriteAudio(PHDASTATE pThis, PHDASTREAM pStream, uint32_t cbTo Process, uint32_t *pcbProcessed)3567 static int hdaWriteAudio(PHDASTATE pThis, PHDASTREAM pStream, uint32_t cbToWrite, uint32_t *pcbWritten) 3561 3568 { 3562 3569 AssertPtrReturn(pThis, VERR_INVALID_POINTER); … … 3573 3580 */ 3574 3581 int rc; 3575 if (!cbTo Process)3582 if (!cbToWrite) 3576 3583 { 3577 3584 rc = VINF_EOF; … … 3580 3587 { 3581 3588 void *pvBuf = pBDLE->State.au8FIFO + pBDLE->State.cbBelowFIFOW; 3582 Assert(cbTo Process>= pBDLE->State.cbBelowFIFOW);3583 uint32_t cbBuf = cbTo Process- pBDLE->State.cbBelowFIFOW;3589 Assert(cbToWrite >= pBDLE->State.cbBelowFIFOW); 3590 uint32_t cbBuf = cbToWrite - pBDLE->State.cbBelowFIFOW; 3584 3591 3585 3592 /* … … 3674 3681 /* Always report all data as being written; 3675 3682 * backends who were not able to catch up have to deal with it themselves. */ 3676 cbWritten = cbTo Process;3677 3678 hdaBDLEUpdate(pBDLE, cbTo Process, cbWritten);3683 cbWritten = cbToWrite; 3684 3685 hdaBDLEUpdate(pBDLE, cbToWrite, cbWritten); 3679 3686 } 3680 3687 else … … 3695 3702 if (RT_SUCCESS(rc)) 3696 3703 { 3697 if (pcb Processed)3698 *pcb Processed= cbWritten;3704 if (pcbWritten) 3705 *pcbWritten = cbWritten; 3699 3706 } 3700 3707 … … 3938 3945 } 3939 3946 3940 AssertPtr(pMixStream); 3941 3942 AudioMixerSinkRemoveStream(pSink->pMixSink, pMixStream); 3943 AudioMixerStreamDestroy(pMixStream); 3947 if (pMixStream) 3948 { 3949 AudioMixerSinkRemoveStream(pSink->pMixSink, pMixStream); 3950 AudioMixerStreamDestroy(pMixStream); 3951 3952 pMixStream = NULL; 3953 } 3944 3954 } 3945 3955 … … 4051 4061 static void hdaTimerMaybeStart(PHDASTATE pThis) 4052 4062 { 4053 LogFlowFunc(("cStreamsActive=%RU8\n", pThis->cStreamsActive));4054 4055 4063 if (pThis->cStreamsActive == 0) /* Only start the timer if there are no active streams. */ 4056 4064 return; … … 4061 4069 LogFlowFuncEnter(); 4062 4070 4071 LogFlowFunc(("Starting timer\n")); 4072 4063 4073 /* Set timer flag. */ 4064 4074 ASMAtomicXchgBool(&pThis->fTimerActive, true); … … 4073 4083 static void hdaTimerMaybeStop(PHDASTATE pThis) 4074 4084 { 4075 LogFlowFunc(("cStreamsActive=%RU8\n", pThis->cStreamsActive));4076 4077 4085 if (pThis->cStreamsActive) /* Some streams still active? Bail out. */ 4078 4086 return; … … 4081 4089 return; 4082 4090 4083 LogFlowFunc Enter();4091 LogFlowFunc(("Stopping timer\n")); 4084 4092 4085 4093 /* Set timer flag. */ … … 4095 4103 STAM_PROFILE_START(&pThis->StatTimer, a); 4096 4104 4097 uint32_t cbInMax = 0;4098 uint32_t cbOutMin = UINT32_MAX;4099 4100 4105 uint64_t cTicksNow = TMTimerGet(pTimer); 4101 4106 uint64_t cTicksElapsed = cTicksNow - pThis->uTimerTS; … … 4119 4124 #endif 4120 4125 4121 AudioMixerSinkTimerUpdate(pThis->SinkLineIn.pMixSink, pThis->cTimerTicks, cTicksElapsed); 4122 hdaTransfer(pThis, pStreamLineIn); 4123 4124 if (AudioMixerSinkGetStatus(pThis->SinkLineIn.pMixSink) & AUDMIXSINK_STS_DIRTY) 4125 fKickTimer = true; 4126 uint32_t cbToProcess; 4127 int rc = AudioMixerSinkUpdate(pThis->SinkLineIn.pMixSink); 4128 if (RT_SUCCESS(rc)) 4129 { 4130 cbToProcess = AudioMixerSinkGetReadable(pThis->SinkLineIn.pMixSink); 4131 if (cbToProcess) 4132 { 4133 rc = hdaTransfer(pThis, pStreamLineIn, cbToProcess, NULL /* pcbProcessed */); 4134 fKickTimer = RT_SUCCESS(rc); 4135 } 4136 } 4126 4137 4127 4138 #ifdef VBOX_WITH_HDA_MIC_IN 4128 AudioMixerSinkTimerUpdate(pThis->SinkMicIn.pMixSink, pThis->cTimerTicks, cTicksElapsed); 4129 hdaTransfer(pThis, pStreamMicIn); 4130 4131 if (AudioMixerSinkGetStatus(pThis->SinkLineIn.pMixSink) & AUDMIXSINK_STS_DIRTY) 4132 fKickTimer = true; 4133 #endif 4134 4135 AudioMixerSinkTimerUpdate(pThis->SinkFront.pMixSink, pThis->cTimerTicks, cTicksElapsed); 4136 hdaTransfer(pThis, pStreamFront); 4137 4138 if (AudioMixerSinkGetStatus(pThis->SinkFront.pMixSink) & AUDMIXSINK_STS_DIRTY) 4139 fKickTimer = true; 4139 rc = AudioMixerSinkUpdate(pThis->SinkMicIn.pMixSink); 4140 if (RT_SUCCESS(rc)) 4141 { 4142 cbToProcess = AudioMixerSinkGetReadable(pThis->SinkMicIn.pMixSink); 4143 if (cbToProcess) 4144 { 4145 rc = hdaTransfer(pThis, pStreamMicIn, cbToProcess, NULL /* pcbProcessed */); 4146 fKickTimer = RT_SUCCESS(rc); 4147 } 4148 } 4149 #endif 4140 4150 4141 4151 #ifdef VBOX_WITH_HDA_51_SURROUND 4142 AudioMixerSinkTimerUpdate(pThis->SinkCenterLFE.pMixSink, pThis->cTimerTicks, cTicksElapsed); 4143 AudioMixerSinkTimerUpdate(pThis->SinkRear.pMixSink, pThis->cTimerTicks, cTicksElapsed); 4144 4152 rc = AudioMixerSinkUpdate(pThis->SinkCenterLFE.pMixSink); 4153 if (RT_SUCCESS(rc)) 4154 { 4155 4156 } 4157 4158 rc = AudioMixerSinkUpdate(pThis->SinkRear.pMixSink); 4159 if (RT_SUCCESS(rc)) 4160 { 4161 4162 } 4145 4163 /** @todo Check for stream interleaving and only call hdaTransfer() if required! */ 4146 #endif 4147 4148 #ifdef VBOX_WITH_HDA_51_SURROUND 4164 4149 4165 /* 4150 4166 * Only call hdaTransfer if CenterLFE and/or Rear are on different SDs, … … 4153 4169 */ 4154 4170 #endif 4171 rc = AudioMixerSinkUpdate(pThis->SinkFront.pMixSink); 4172 if (RT_SUCCESS(rc)) 4173 { 4174 cbToProcess = AudioMixerSinkGetWritable(pThis->SinkFront.pMixSink); 4175 if (cbToProcess) 4176 { 4177 rc = hdaTransfer(pThis, pStreamFront, cbToProcess, NULL /* pcbProcessed */); 4178 fKickTimer = RT_SUCCESS(rc); 4179 } 4180 } 4155 4181 4156 4182 if ( ASMAtomicReadBool(&pThis->fTimerActive) … … 4218 4244 #endif /* VBOX_WITH_AUDIO_CALLBACKS */ 4219 4245 4220 static int hdaTransfer(PHDASTATE pThis, PHDASTREAM pStream )4246 static int hdaTransfer(PHDASTATE pThis, PHDASTREAM pStream, uint32_t cbToProcess, uint32_t *pcbProcessed) 4221 4247 { 4222 4248 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 4223 4249 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 4250 /* pcbProcessed is optional. */ 4224 4251 4225 4252 if (ASMAtomicReadBool(&pThis->fInReset)) /* HDA controller in reset mode? Bail out. */ 4226 4253 { 4227 4254 LogFlowFunc(("HDA in reset mode, skipping\n")); 4255 4256 if (pcbProcessed) 4257 *pcbProcessed = 0; 4228 4258 return VINF_SUCCESS; 4229 4259 } … … 4250 4280 else if (!(HDA_STREAM_REG(pThis, CTL, pStream->u8SD) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN))) 4251 4281 fProceed = false; 4282 /* Nothing to process? */ 4283 else if (!cbToProcess) 4284 fProceed = false; 4252 4285 4253 4286 if ((HDA_STREAM_REG(pThis, STS, pStream->u8SD) & HDA_REG_FIELD_FLAG_MASK(SDSTS, BCIS))) … … 4264 4297 AssertRC(rc); 4265 4298 4299 if (pcbProcessed) 4300 *pcbProcessed = 0; 4266 4301 return VINF_SUCCESS; 4267 4302 } … … 4281 4316 4282 4317 #ifdef DEBUG_andy 4283 # define DEBUG_SIMPLE4318 //# define DEBUG_SIMPLE 4284 4319 #endif 4285 4320 … … 4289 4324 #endif 4290 4325 4291 uint32_t cbToProcess = 0; 4292 uint32_t cbProcessed = 0; 4293 uint32_t cbProcessedTotal = 0; 4326 uint32_t cbLeft = cbToProcess; 4327 uint32_t cbTotal = 0; 4328 uint32_t cbChunk = 0; 4329 uint32_t cbChunkProcessed = 0; 4294 4330 4295 4331 /* Set the FIFORDY bit on the stream while doing the transfer. */ 4296 4332 HDA_STREAM_REG(pThis, STS, pStream->u8SD) |= HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY); 4297 4333 4298 do4334 while (cbLeft) 4299 4335 { 4300 4336 /* Do we need to fetch the next Buffer Descriptor Entry (BDLE)? */ … … 4306 4342 } 4307 4343 4308 cb ToProcess = hdaStreamGetTransferSize(pThis, pStream, _4K /** @todo Fix this */);4309 cb Processed = 0;4344 cbChunk = hdaStreamGetTransferSize(pThis, pStream, cbLeft); 4345 cbChunkProcessed = 0; 4310 4346 4311 4347 if (hdaGetDirFromSD(pStream->u8SD) == PDMAUDIODIR_IN) 4312 rc = hdaReadAudio(pThis, pStream, cb ToProcess, &cbProcessed);4348 rc = hdaReadAudio(pThis, pStream, cbChunk, &cbChunkProcessed); 4313 4349 else 4314 4350 { 4315 4351 #ifndef DEBUG_SIMPLE 4316 rc = hdaWriteAudio(pThis, pStream, cb ToProcess, &cbProcessed);4352 rc = hdaWriteAudio(pThis, pStream, cbChunk, &cbChunkProcessed); 4317 4353 #else 4318 uint32_t cbToWrite = hdaStreamGetTransferSize(pThis, pStream, cbToProcess);4319 4320 4354 void *pvBuf = u8FIFO + u8FIFOff; 4321 int32_t cbBuf = cbToWrite;4355 int32_t cbBuf = cbChunk; 4322 4356 4323 4357 PHDABDLE pBDLE = &pStream->State.BDLE; 4324 4358 4325 rc = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), 4326 pBDLE->u64BufAdr + pBDLE->State.u32BufOff, 4327 pvBuf, cbBuf); 4328 4329 hdaBDLEUpdate(pBDLE, cbToWrite, cbToWrite); 4330 4331 u8FIFOff += cbToWrite; 4359 if (cbBuf) 4360 rc = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), 4361 pBDLE->u64BufAdr + pBDLE->State.u32BufOff, 4362 pvBuf, cbBuf); 4363 4364 cbChunkProcessed = cbChunk; 4365 4366 hdaBDLEUpdate(pBDLE, cbChunkProcessed, cbChunkProcessed); 4367 4368 u8FIFOff += cbChunkProcessed; 4332 4369 Assert((u8FIFOff & 1) == 0); 4333 4370 Assert(u8FIFOff <= sizeof(u8FIFO)); 4334 4335 cbProcessed = cbToWrite;4336 4371 #endif 4337 4372 } … … 4340 4375 break; 4341 4376 4342 hdaStreamTransferUpdate(pThis, pStream, cbProcessed); 4343 4344 cbProcessedTotal += cbProcessed; 4377 hdaStreamTransferUpdate(pThis, pStream, cbChunkProcessed); 4378 4379 Assert(cbLeft >= cbChunkProcessed); 4380 cbLeft -= cbChunkProcessed; 4381 cbTotal += cbChunkProcessed; 4345 4382 4346 4383 if (rc == VINF_EOF) … … 4349 4386 if (hdaStreamTransferIsComplete(pThis, pStream, &fInterrupt)) 4350 4387 break; 4351 4352 } while (RT_SUCCESS(rc)); 4388 } 4353 4389 4354 4390 /* Remove the FIFORDY bit again. */ 4355 4391 HDA_STREAM_REG(pThis, STS, pStream->u8SD) &= ~HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY); 4356 4392 4357 LogFlowFunc(("[SD%RU8]: %RU32 / %RU32, rc=%Rrc\n", pStream->u8SD, cb ProcessedTotal, cbToProcess, rc));4393 LogFlowFunc(("[SD%RU8]: %RU32 / %RU32, rc=%Rrc\n", pStream->u8SD, cbTotal, cbToProcess, rc)); 4358 4394 4359 4395 #ifdef DEBUG_SIMPLE … … 4386 4422 4387 4423 hdaProcessInterrupt(pThis); 4424 } 4425 4426 if (RT_SUCCESS(rc)) 4427 { 4428 if (pcbProcessed) 4429 *pcbProcessed = cbTotal; 4388 4430 } 4389 4431 … … 5051 5093 if (pStream) 5052 5094 { 5095 /* Deactive first. */ 5096 int rc2 = hdaStreamSetActive(pThis, pStream, false); 5097 AssertRC(rc2); 5098 5053 5099 bool fActive = RT_BOOL(HDA_STREAM_REG(pThis, CTL, i) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 5054 LogFlowFunc(("[SD%RU8]: fActive=%RTbool\n", i, fActive)); 5055 int rc2 = hdaStreamSetActive(pThis, pStream, fActive); 5100 5101 /* Activate, if needed. */ 5102 rc2 = hdaStreamSetActive(pThis, pStream, fActive); 5056 5103 AssertRC(rc2); 5057 5104 } … … 5699 5746 #ifndef VBOX_WITH_AUDIO_CALLBACKS 5700 5747 uint16_t uTimerHz; 5701 rc = CFGMR3QueryU16Def(pCfg, "TimerHz", &uTimerHz, 100 /* Hz */);5748 rc = CFGMR3QueryU16Def(pCfg, "TimerHz", &uTimerHz, 200 /* Hz */); 5702 5749 if (RT_FAILURE(rc)) 5703 5750 return PDMDEV_SET_ERROR(pDevIns, rc, -
trunk/src/VBox/Devices/Audio/DevSB16.cpp
r61386 r61609 1785 1785 pThis->uTimerTSIO = cTicksNow; 1786 1786 1787 bool fIsPlaying = false; 1787 bool fIsPlaying = false; 1788 uint32_t cbWritable = UINT32_MAX; 1788 1789 1789 1790 LogFlowFuncEnter(); … … 1796 1797 continue; 1797 1798 1798 int rc2 = pDrv->pConnector->pfnStreamIterate(pDrv->pConnector, pStream); 1799 PPDMIAUDIOCONNECTOR pConn = pDrv->pConnector; 1800 if (!pConn) 1801 continue; 1802 1803 int rc2 = pConn->pfnStreamIterate(pConn, pStream); 1799 1804 if (RT_SUCCESS(rc2)) 1800 1805 { 1801 1806 if (pStream->enmDir == PDMAUDIODIR_IN) 1802 1807 { 1803 /** @todo Implement this! */1808 /** @todo Implement recording! */ 1804 1809 } 1805 1810 else 1806 1811 { 1807 rc2 = p Drv->pConnector->pfnStreamPlay(pDrv->pConnector, pStream, NULL /* cPlayed */);1812 rc2 = pConn->pfnStreamPlay(pConn, pStream, NULL /* cPlayed */); 1808 1813 if (RT_FAILURE(rc2)) 1814 { 1809 1815 LogFlowFunc(("%s: Failed playing stream, rc=%Rrc\n", pStream->szName, rc2)); 1816 continue; 1817 } 1818 1819 rc2 = pConn->pfnStreamIterate(pConn, pStream); 1820 if (RT_FAILURE(rc2)) 1821 { 1822 LogFlowFunc(("%s: Failed re-iterating stream, rc=%Rrc\n", pStream->szName, rc2)); 1823 continue; 1824 } 1825 1826 cbWritable = RT_MIN(pConn->pfnStreamGetWritable(pConn, pStream), cbWritable); 1810 1827 } 1811 1828 } 1812 1829 1813 PDMAUDIOSTRMSTS strmSts = p Drv->pConnector->pfnStreamGetStatus(pDrv->pConnector, pStream);1830 PDMAUDIOSTRMSTS strmSts = pConn->pfnStreamGetStatus(pConn, pStream); 1814 1831 fIsPlaying |= ( (strmSts & PDMAUDIOSTRMSTS_FLAG_ENABLED) 1815 1832 || (strmSts & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE)); … … 1821 1838 || fIsPlaying) 1822 1839 { 1823 /* Schedule the next transfer. */ 1824 PDMDevHlpDMASchedule(pThis->pDevInsR3); 1840 if (cbWritable) 1841 { 1842 /* Schedule the next transfer. */ 1843 PDMDevHlpDMASchedule(pThis->pDevInsR3); 1844 } 1825 1845 1826 1846 /* Kick the timer again. */ -
trunk/src/VBox/Devices/Audio/DrvAudio.cpp
r61568 r61609 581 581 AssertPtr(pGstStream); 582 582 583 int rc = VINF_SUCCESS;583 int rc; 584 584 585 585 do … … 587 587 uint32_t cSamplesMixed = 0; 588 588 589 PDMAUDIOSTRMSTS hstStrmSts = pThis->pHostDrvAudio->pfnStreamGetStatus(pThis->pHostDrvAudio, pHstStream); 589 rc = pThis->pHostDrvAudio->pfnStreamIterate(pThis->pHostDrvAudio, pHstStream); 590 if (RT_FAILURE(rc)) 591 break; 590 592 591 593 if (pHstStream->enmDir == PDMAUDIODIR_IN) 592 594 { 593 uint32_t cSamplesToCapture = AudioMixBufFree(&pGstStream->MixBuf); 594 if (cSamplesToCapture) 595 { 596 if (hstStrmSts & PDMAUDIOSTRMSTS_FLAG_DATA_READABLE) 595 /* Has the host captured any samples which were not mixed to the guest side yet? */ 596 uint32_t cSamplesCaptured = AudioMixBufUsed(&pHstStream->MixBuf); 597 598 LogFlowFunc(("[%s] %RU32 samples captured\n", pHstStream->szName, cSamplesCaptured)); 599 600 if (cSamplesCaptured) 601 { 602 /* When capturing samples, the guest is the parent while the host is the child. 603 * So try mixing not yet mixed host-side samples to the guest-side buffer. */ 604 rc = AudioMixBufMixToParent(&pHstStream->MixBuf, cSamplesCaptured, &cSamplesMixed); 605 if ( RT_SUCCESS(rc) 606 && cSamplesMixed) 597 607 { 598 uint32_t cSamplesCaptured = 0; 599 600 /* Call the host backend to capture the audio input data. */ 601 rc = pThis->pHostDrvAudio->pfnStreamCapture(pThis->pHostDrvAudio, pHstStream, &cSamplesCaptured); 602 if (RT_FAILURE(rc)) 603 break; 604 605 LogFlowFunc(("%s: %RU32 samples captured, rc=%Rrc\n", pHstStream->szName, cSamplesCaptured, rc)); 608 LogFlowFunc(("[%s] %RU32 captured samples mixed\n", pHstStream->szName, cSamplesMixed)); 606 609 } 607 610 } … … 609 612 else if (pHstStream->enmDir == PDMAUDIODIR_OUT) 610 613 { 611 uint32_t cSamplesToMix = AudioMixBufUsed(&pGstStream->MixBuf); 612 613 if (cSamplesToMix) 614 { 615 uint32_t cSamplesPlayed = 0; 616 if (hstStrmSts & PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE) 614 uint32_t cSamplesLive = AudioMixBufLive(&pGstStream->MixBuf); 615 if (!cSamplesLive) /* No live samples at the moment? */ 616 { 617 /* When playing samples, the host is the parent while the guest is the child. 618 * So try mixing not yet mixed guest-side samples to the host-side buffer. */ 619 rc = AudioMixBufMixToParent(&pGstStream->MixBuf, AudioMixBufUsed(&pGstStream->MixBuf), &cSamplesMixed); 620 if ( RT_SUCCESS(rc) 621 && cSamplesMixed) 617 622 { 618 rc = AudioMixBufMixToParent(&pGstStream->MixBuf, cSamplesToMix, &cSamplesMixed); 619 620 LogFlowFunc(("%s: %RU32/%RU32 playback samples mixed, rc=%Rrc\n", 621 pHstStream->szName, cSamplesMixed, cSamplesToMix, rc)); 623 LogFlowFunc(("[%s] %RU32 samples mixed\n", pHstStream->szName, cSamplesMixed)); 622 624 } 625 626 if (RT_SUCCESS(rc)) 627 cSamplesLive = AudioMixBufLive(&pGstStream->MixBuf); 628 } 629 630 LogFlowFunc(("[%s] %RU32 live samples\n", pHstStream->szName, cSamplesLive)); 631 632 if (!cSamplesLive) /* No live samples at the moment? */ 633 { 634 /* Has the host stream marked as disabled but there still were guest streams relying 635 * on it? Check if the stream now can be closed and do so, if possible. */ 636 if (pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE) 637 { 638 LogFunc(("[%s] Closing pending stream\n", pHstStream->szName)); 639 rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE); 640 if (RT_SUCCESS(rc)) 641 { 642 pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE; 643 } 644 else 645 LogFunc(("%s: Backend vetoed against closing output stream, rc=%Rrc\n", pHstStream->szName, rc)); 646 } 647 648 break; 623 649 } 624 650 } 625 651 else 626 652 AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED); 627 628 if (RT_SUCCESS(rc))629 rc = pThis->pHostDrvAudio->pfnStreamIterate(pThis->pHostDrvAudio, pHstStream);630 653 631 654 } while (0); … … 656 679 if (RT_FAILURE(rc)) 657 680 return rc; 658 659 LogFlowFunc(("[%s]\n", pStream->szName));660 681 661 682 uint32_t cSamplesPlayed = 0; … … 682 703 AssertPtr(pGstStream); 683 704 684 uint32_t cSamplesLive = AudioMixBuf Used(&pHstStream->MixBuf);705 uint32_t cSamplesLive = AudioMixBufLive(&pGstStream->MixBuf); 685 706 if (cSamplesLive) 686 707 { … … 690 711 rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream, &cSamplesPlayed); 691 712 if (RT_FAILURE(rc)) 692 drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE); 693 } 694 695 LogFlowFunc(("[%s] strmSts=0x%x, cSamplesPlayed=%RU32, rc=%Rrc\n", pStream->szName, strmSts, cSamplesPlayed, rc)); 696 697 if (RT_SUCCESS(rc)) 698 { 699 rc = drvAudioStreamIterateInternal(pThis, pStream); 700 if (RT_SUCCESS(rc)) 701 cSamplesLive = AudioMixBufUsed(&pHstStream->MixBuf); 702 } 713 { 714 int rc2 = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE); 715 AssertRC(rc2); 716 } 717 } 718 719 LogFlowFunc(("[%s] strmSts=0x%x, cSamplesPlayed=%RU32, rc=%Rrc\n", pHstStream->szName, strmSts, cSamplesPlayed, rc)); 703 720 } 704 721 … … 709 726 if (pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE) 710 727 { 711 LogFunc((" %s:Closing pending stream\n", pHstStream->szName));728 LogFunc(("[%s] Closing pending stream\n", pHstStream->szName)); 712 729 rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE); 713 730 if (RT_SUCCESS(rc)) … … 716 733 } 717 734 else 718 LogFunc((" %s:Backend vetoed against closing output stream, rc=%Rrc\n", pHstStream->szName, rc));735 LogFunc(("[%s] Backend vetoed against closing output stream, rc=%Rrc\n", pHstStream->szName, rc)); 719 736 } 720 737 } … … 733 750 734 751 if (RT_FAILURE(rc)) 735 LogFlowFunc LeaveRC(rc);752 LogFlowFunc(("[%s] Failed with %Rrc\n", rc)); 736 753 737 754 return rc; … … 779 796 AssertPtr(pGstStream); 780 797 781 uint32_t cSamplesLive = AudioMixBuf Used(&pHstStream->MixBuf);782 if ( cSamplesLive)798 uint32_t cSamplesLive = AudioMixBufLive(&pGstStream->MixBuf); 799 if (!cSamplesLive) 783 800 { 784 801 PDMAUDIOSTRMSTS strmSts = pThis->pHostDrvAudio->pfnStreamGetStatus(pThis->pHostDrvAudio, pHstStream); … … 787 804 rc = pThis->pHostDrvAudio->pfnStreamCapture(pThis->pHostDrvAudio, pHstStream, &cSamplesCaptured); 788 805 if (RT_FAILURE(rc)) 789 drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE);790 }791 792 LogFlowFunc(("[%s] strmSts=0x%x, cSamplesCaptured=%RU32, rc=%Rrc\n", pStream->szName, strmSts, cSamplesCaptured, rc));793 794 if (RT_SUCCESS(rc))795 {796 rc = drvAudioStreamIterateInternal(pThis, pStream);797 if (RT_SUCCESS(rc))798 cSamplesLive = AudioMixBufUsed(&pHstStream->MixBuf);799 }800 }801 802 if (!cSamplesLive)803 {804 /* Has the host stream marked as disabled but there still were guest streams relying805 * on it? Check if the stream now can be closed and do so, if possible. */806 if (pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE)807 {808 LogFunc(("%s: Closing pending stream\n", pHstStream->szName));809 rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE);810 if (RT_SUCCESS(rc))811 806 { 812 pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE; 807 int rc2 = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE); 808 AssertRC(rc2); 813 809 } 814 else815 LogFunc(("%s: Backend vetoed against closing input stream, rc=%Rrc\n", pHstStream->szName, rc)); 816 }810 } 811 812 LogFlowFunc(("[%s] strmSts=0x%x, cSamplesCaptured=%RU32, rc=%Rrc\n", pHstStream->szName, strmSts, cSamplesCaptured, rc)); 817 813 } 818 814 … … 1366 1362 LogFlowFuncLeaveRC(rc); 1367 1363 return backendSts; 1364 } 1365 1366 static DECLCALLBACK(uint32_t) drvAudioStreamGetReadable(PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream) 1367 { 1368 AssertPtrReturn(pInterface, 0); 1369 AssertPtrReturn(pStream, 0); 1370 1371 PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface); 1372 1373 int rc2 = RTCritSectEnter(&pThis->CritSect); 1374 AssertRC(rc2); 1375 1376 AssertMsg(pStream->enmDir == PDMAUDIODIR_IN, ("Can't read from a non-input stream\n")); 1377 1378 PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream); 1379 if (!pHstStream) /* No host stream available? Bail out early. */ 1380 { 1381 rc2 = RTCritSectLeave(&pThis->CritSect); 1382 AssertRC(rc2); 1383 1384 return 0; 1385 } 1386 1387 uint32_t cbReadable = 0; 1388 1389 PPDMAUDIOSTREAM pGstStream = pHstStream->pPair; 1390 if (pGstStream) 1391 cbReadable = AudioMixBufLive(&pGstStream->MixBuf); 1392 1393 LogFlowFunc(("[%s] cbReadable=%RU32\n", pHstStream->szName, cbReadable)); 1394 1395 rc2 = RTCritSectLeave(&pThis->CritSect); 1396 AssertRC(rc2); 1397 1398 return cbReadable; 1399 } 1400 1401 static DECLCALLBACK(uint32_t) drvAudioStreamGetWritable(PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream) 1402 { 1403 AssertPtrReturn(pInterface, 0); 1404 AssertPtrReturn(pStream, 0); 1405 1406 PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface); 1407 1408 int rc2 = RTCritSectEnter(&pThis->CritSect); 1409 AssertRC(rc2); 1410 1411 AssertMsg(pStream->enmDir == PDMAUDIODIR_OUT, ("Can't write to a non-output stream\n")); 1412 1413 PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream); 1414 if (!pHstStream) /* No host stream available? Bail out early. */ 1415 { 1416 rc2 = RTCritSectLeave(&pThis->CritSect); 1417 AssertRC(rc2); 1418 1419 return 0; 1420 } 1421 1422 PPDMAUDIOSTREAM pGstStream = pHstStream->pPair; 1423 1424 uint32_t cbWritable = 0; 1425 1426 if (AudioMixBufLive(&pHstStream->MixBuf) == 0) 1427 cbWritable = AudioMixBufFreeBytes(&pGstStream->MixBuf); 1428 1429 LogFlowFunc(("[%s] cWritable=%RU32\n", pHstStream->szName, cbWritable)); 1430 1431 rc2 = RTCritSectLeave(&pThis->CritSect); 1432 AssertRC(rc2); 1433 1434 return cbWritable; 1368 1435 } 1369 1436 … … 1634 1701 pThis->IAudioConnector.pfnStreamWrite = drvAudioStreamWrite; 1635 1702 pThis->IAudioConnector.pfnStreamIterate = drvAudioStreamIterate; 1703 pThis->IAudioConnector.pfnStreamGetReadable = drvAudioStreamGetReadable; 1704 pThis->IAudioConnector.pfnStreamGetWritable = drvAudioStreamGetWritable; 1636 1705 pThis->IAudioConnector.pfnStreamGetStatus = drvAudioStreamGetStatus; 1637 1706 pThis->IAudioConnector.pfnStreamSetVolume = drvAudioStreamSetVolume; -
trunk/src/VBox/Devices/Audio/DrvHostALSAAudio.cpp
r61523 r61609 1166 1166 (uint32_t)cAvail), /* cAvail is always >= 0 */ 1167 1167 AUDIOMIXBUF_S2B(&pStream->MixBuf, 1168 AudioMixBuf Avail(&pStream->MixBuf)));1168 AudioMixBufLive(&pStream->MixBuf))); 1169 1169 LogFlowFunc(("cbToRead=%zu, cbAvail=%zu\n", 1170 1170 cbToRead, AUDIOMIXBUF_S2B(&pStream->MixBuf, cAvail))); -
trunk/src/VBox/Devices/Audio/DrvHostCoreAudio.cpp
r61321 r61609 1561 1561 /* Not much else to do here. */ 1562 1562 1563 uint32_t cLive = AudioMixBuf Avail(&pStream->MixBuf);;1564 if (!cLive) /* Not samples to play? Bail out. */1563 uint32_t cLive = AudioMixBufLive(&pStream->MixBuf); 1564 if (!cLive) /* Not live samples to play? Bail out. */ 1565 1565 { 1566 1566 if (pcSamplesPlayed) … … 1569 1569 } 1570 1570 1571 size_t cbLive = AUDIOMIXBUF_S2B(&pStream->MixBuf, cLive); 1572 1571 1573 uint32_t cbReadTotal = 0; 1572 uint32_t cAvail = AudioMixBufAvail(&pStream->MixBuf); 1573 size_t cbAvail = AUDIOMIXBUF_S2B(&pStream->MixBuf, cAvail); 1574 size_t cbToRead = RT_MIN(cbAvail, RTCircBufFree(pStreamOut->pBuf)); 1574 1575 size_t cbToRead = RT_MIN(cbLive, RTCircBufFree(pStreamOut->pBuf)); 1575 1576 LogFlowFunc(("cbToRead=%zu\n", cbToRead)); 1576 1577 -
trunk/src/VBox/Devices/Audio/DrvHostDSound.cpp
r61345 r61609 257 257 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 258 258 AssertPtrReturn(pDSoundStream, VERR_INVALID_POINTER); 259 /* pdwBuffer is optional. */ 260 /* pdwFree is optional. */ 261 /* pdwPlayPos is optional. */ 259 262 260 263 LPDIRECTSOUNDBUFFER8 pDSB = pDSoundStream->pDSB; … … 305 308 } 306 309 307 LogFlowFuncLeaveRC(rc); 310 if (RT_FAILURE(rc)) 311 LogFlowFuncLeaveRC(rc); 308 312 return rc; 309 313 } … … 1540 1544 cbFree -= cbSample; 1541 1545 1542 uint32_t c sLive = AudioMixBufAvail(&pStream->MixBuf);1543 uint32_t cbLive = AUDIOMIXBUF_S2B(&pStream->MixBuf, c sLive);1546 uint32_t cLive = AudioMixBufLive(&pStream->MixBuf); 1547 uint32_t cbLive = AUDIOMIXBUF_S2B(&pStream->MixBuf, cLive); 1544 1548 1545 1549 /* Do not write more than available space in the DirectSound playback buffer. */ … … 2237 2241 PDSOUNDSTREAMOUT pDSoundStream = (PDSOUNDSTREAMOUT)pStream; 2238 2242 if (pDSoundStream->fEnabled) 2239 strmSts |= PDMAUDIOSTRMSTS_FLAG_ENABLED | PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE; 2243 { 2244 strmSts |= PDMAUDIOSTRMSTS_FLAG_ENABLED; 2245 2246 DWORD cbFree; 2247 int rc = dsoundGetPosOut(pThis, pDSoundStream, NULL /* cbBuffer */, &cbFree, NULL /* cbPlayPos */); 2248 if ( RT_SUCCESS(rc) 2249 && cbFree) 2250 { 2251 LogFlowFunc(("cbFree=%ld\n", cbFree)); 2252 strmSts |= PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE; 2253 } 2254 } 2240 2255 } 2241 2256 -
trunk/src/VBox/Devices/Audio/DrvHostNullAudio.cpp
r61320 r61609 160 160 161 161 /* Consume as many samples as would be played at the current frequency since last call. */ 162 uint32_t csLive = AudioMixBufAvail(&pStream->MixBuf); 162 uint32_t cLive = AudioMixBufLive(&pStream->MixBuf); 163 163 164 uint64_t u64TicksNow = PDMDrvHlpTMGetVirtualTime(pDrv->pDrvIns); 164 165 uint64_t u64TicksElapsed = u64TicksNow - pNullStream->u64TicksLast; … … 175 176 176 177 /* Don't play more than available. */ 177 if (cSamplesPlayed > c sLive)178 cSamplesPlayed = c sLive;178 if (cSamplesPlayed > cLive) 179 cSamplesPlayed = cLive; 179 180 180 181 cSamplesPlayed = RT_MIN(cSamplesPlayed, pNullStream->csPlayBuffer); -
trunk/src/VBox/Devices/Audio/DrvHostOSSAudio.cpp
r61332 r61609 875 875 size_t cbBuf = AudioMixBufSizeBytes(&pStream->MixBuf); 876 876 877 uint32_t cLive = AudioMixBuf Avail(&pStream->MixBuf);877 uint32_t cLive = AudioMixBufLive(&pStream->MixBuf); 878 878 uint32_t cToRead; 879 879 -
trunk/src/VBox/Devices/Audio/DrvHostPulseAudio.cpp
r61523 r61609 772 772 } 773 773 774 LogFlowFunc(("cbAvail=%zu\n", cbAvail)); 775 774 776 if (!cbAvail) /* No data? Bail out. */ 775 777 { … … 853 855 { 854 856 uint32_t cProcessed = 0; 855 if (cWrittenTotal)857 /* if (cWrittenTotal) 856 858 rc = AudioMixBufMixToParent(&pStream->MixBuf, cWrittenTotal, 857 &cProcessed); 859 &cProcessed);*/ 858 860 859 861 if (pcSamplesCaptured) … … 1424 1426 && pa_stream_get_state(pStrm->pPAStream) == PA_STREAM_READY) 1425 1427 { 1426 size_t cbSize;1427 1428 1428 if (pStream->enmDir == PDMAUDIODIR_IN) 1429 1429 { 1430 cbSize = pa_stream_readable_size(pStrm->pPAStream); 1431 1432 if (cbSize) 1433 strmSts |= PDMAUDIOSTRMSTS_FLAG_DATA_READABLE; 1430 strmSts |= PDMAUDIOSTRMSTS_FLAG_DATA_READABLE; 1434 1431 } 1435 1432 else 1436 1433 { 1437 cbSize = pa_stream_writable_size(pStrm->pPAStream); 1434 size_t cbSize = pa_stream_writable_size(pStrm->pPAStream); 1435 LogFlowFunc(("cbSize=%zu\n", cbSize)); 1438 1436 1439 1437 if (cbSize >= pStrm->BufAttr.minreq) 1440 1438 strmSts |= PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE; 1441 1439 } 1442 1443 LogFlowFunc(("cbSize=%zu\n", cbSize));1444 1440 } 1445 1441 -
trunk/src/VBox/Devices/Audio/testcase/tstAudioMixBuffer.cpp
r61352 r61609 231 231 RTTESTI_CHECK_MSG_BREAK(written == cSamplesChild1, ("Child1: Expected %RU32 written samples, got %RU32\n", cSamplesChild1, written)); 232 232 RTTESTI_CHECK_RC_OK_BREAK(AudioMixBufMixToParent(&child1, written, &mixed)); 233 RTTESTI_CHECK_MSG_BREAK(AudioMixBuf Mixed(&child1) == mixed, ("Child1: Expected %RU32 mixed samples, got %RU32\n", AudioMixBufMixed(&child1), mixed));234 RTTESTI_CHECK_MSG_BREAK(AudioMixBufUsed(&child1) == AUDIOMIXBUF_S2S_RATIO(&parent, mixed), ("Child1: Expected %RU32 used samples, got %RU32\n", AudioMixBuf Mixed(&child1), AUDIOMIXBUF_S2S_RATIO(&parent, mixed)));233 RTTESTI_CHECK_MSG_BREAK(AudioMixBufLive(&child1) == mixed, ("Child1: Expected %RU32 mixed samples, got %RU32\n", AudioMixBufLive(&child1), mixed)); 234 RTTESTI_CHECK_MSG_BREAK(AudioMixBufUsed(&child1) == AUDIOMIXBUF_S2S_RATIO(&parent, mixed), ("Child1: Expected %RU32 used samples, got %RU32\n", AudioMixBufLive(&child1), AUDIOMIXBUF_S2S_RATIO(&parent, mixed))); 235 235 RTTESTI_CHECK_MSG_BREAK(AudioMixBufUsed(&parent) == 0, ("Parent: Expected 0 used samples, got %RU32\n", AudioMixBufUsed(&parent))); 236 236 … … 238 238 RTTESTI_CHECK_MSG_BREAK(written == cSamplesChild2, ("Child2: Expected %RU32 written samples, got %RU32\n", cSamplesChild2, written)); 239 239 RTTESTI_CHECK_RC_OK_BREAK(AudioMixBufMixToParent(&child2, written, &mixed)); 240 RTTESTI_CHECK_MSG_BREAK(AudioMixBuf Mixed(&child2) == mixed, ("Child2: Expected %RU32 mixed samples, got %RU32\n", AudioMixBufMixed(&child2), AudioMixBufUsed(&parent)));241 RTTESTI_CHECK_MSG_BREAK(AudioMixBufUsed(&child2) == AUDIOMIXBUF_S2S_RATIO(&parent, mixed), ("Child2: Expected %RU32 used samples, got %RU32\n", AudioMixBuf Mixed(&child2), AUDIOMIXBUF_S2S_RATIO(&parent, mixed)));240 RTTESTI_CHECK_MSG_BREAK(AudioMixBufLive(&child2) == mixed, ("Child2: Expected %RU32 mixed samples, got %RU32\n", AudioMixBufLive(&child2), AudioMixBufUsed(&parent))); 241 RTTESTI_CHECK_MSG_BREAK(AudioMixBufUsed(&child2) == AUDIOMIXBUF_S2S_RATIO(&parent, mixed), ("Child2: Expected %RU32 used samples, got %RU32\n", AudioMixBufLive(&child2), AUDIOMIXBUF_S2S_RATIO(&parent, mixed))); 242 242 RTTESTI_CHECK_MSG_BREAK(AudioMixBufUsed(&parent) == 0, ("Parent2: Expected 0 used samples, got %RU32\n", AudioMixBufUsed(&parent))); 243 243 } 244 244 245 RTTESTI_CHECK(AudioMixBufUsed(&parent) == AudioMixBuf Mixed(&child1) + AudioMixBufMixed(&child2));245 RTTESTI_CHECK(AudioMixBufUsed(&parent) == AudioMixBufLive(&child1) + AudioMixBufLive(&child2)); 246 246 247 247 for (;;) … … 254 254 255 255 RTTESTI_CHECK(AudioMixBufUsed(&parent) == 0); 256 RTTESTI_CHECK(AudioMixBuf Mixed(&child1) == 0);257 RTTESTI_CHECK(AudioMixBuf Mixed(&child2) == 0);256 RTTESTI_CHECK(AudioMixBufLive(&child1) == 0); 257 RTTESTI_CHECK(AudioMixBufLive(&child2) == 0); 258 258 259 259 AudioMixBufDestroy(&parent); … … 338 338 RTTESTI_CHECK_RC_OK(AudioMixBufMixToParent(&child, written, &mixed)); 339 339 temp = AudioMixBufUsed(&parent); 340 RTTESTI_CHECK_MSG(AudioMixBuf Mixed(&child) == temp, ("Child: Expected %RU32 mixed samples, got %RU32\n", AudioMixBufMixed(&child), temp));341 342 RTTESTI_CHECK(AudioMixBufUsed(&parent) == AudioMixBuf Mixed(&child));340 RTTESTI_CHECK_MSG(AudioMixBufLive(&child) == temp, ("Child: Expected %RU32 mixed samples, got %RU32\n", AudioMixBufLive(&child), temp)); 341 342 RTTESTI_CHECK(AudioMixBufUsed(&parent) == AudioMixBufLive(&child)); 343 343 344 344 for (;;) … … 366 366 367 367 RTTESTI_CHECK(AudioMixBufUsed(&parent) == 0); 368 RTTESTI_CHECK(AudioMixBuf Mixed(&child)== 0);368 RTTESTI_CHECK(AudioMixBufLive(&child) == 0); 369 369 370 370 AudioMixBufDestroy(&parent); … … 441 441 RTTESTI_CHECK_RC_OK(AudioMixBufMixToParent(&child, written, &mixed)); 442 442 temp = AudioMixBufUsed(&parent); 443 RTTESTI_CHECK_MSG(AudioMixBuf Mixed(&child) == temp, ("Child: Expected %RU32 mixed samples, got %RU32\n", AudioMixBufMixed(&child), temp));444 445 RTTESTI_CHECK(AudioMixBufUsed(&parent) == AudioMixBuf Mixed(&child));443 RTTESTI_CHECK_MSG(AudioMixBufLive(&child) == temp, ("Child: Expected %RU32 mixed samples, got %RU32\n", AudioMixBufLive(&child), temp)); 444 445 RTTESTI_CHECK(AudioMixBufUsed(&parent) == AudioMixBufLive(&child)); 446 446 447 447 for (;;) … … 468 468 469 469 RTTESTI_CHECK(AudioMixBufUsed(&parent) == 0); 470 RTTESTI_CHECK(AudioMixBuf Mixed(&child)== 0);470 RTTESTI_CHECK(AudioMixBufLive(&child) == 0); 471 471 472 472 AudioMixBufDestroy(&parent); -
trunk/src/VBox/Main/src-client/DrvAudioVRDE.cpp
r61320 r61609 254 254 AssertPtrReturn(pVRDEStrmOut, VERR_INVALID_POINTER); 255 255 256 uint32_t live = AudioMixBufAvail(&pStream->MixBuf); 256 uint32_t cLive = AudioMixBufLive(&pStream->MixBuf); 257 257 258 uint64_t now = PDMDrvHlpTMGetVirtualTime(pDrv->pDrvIns); 258 259 uint64_t ticks = now - pVRDEStrmOut->old_ticks; … … 263 264 264 265 /* Don't play more than available. */ 265 if (cSamplesPlayed > live)266 cSamplesPlayed = live;266 if (cSamplesPlayed > cLive) 267 cSamplesPlayed = cLive; 267 268 268 269 /* Remember when samples were consumed. */
Note:
See TracChangeset
for help on using the changeset viewer.