Changeset 65624 in vbox
- Timestamp:
- Feb 6, 2017 2:13:36 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 113296
- Location:
- trunk
- Files:
-
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/pdmaudioifs.h
r65565 r65624 4 4 5 5 /* 6 * Copyright (C) 2006-201 6Oracle Corporation6 * Copyright (C) 2006-2017 Oracle Corporation 7 7 * 8 8 * This file is part of VirtualBox Open Source Edition (OSE), as … … 337 337 338 338 /** 339 * Properties of audio streams for host/guest 340 * for in or out directions. 341 */ 342 typedef struct PDMAUDIOPCMPROPS 343 { 344 /** Sample width. Bits per sample. */ 345 uint8_t cBits; 346 /** Signed or unsigned sample. */ 347 bool fSigned; 348 /** Shift count used for faster calculation of various 349 * values, such as the alignment, bytes to samples and so on. 350 * Depends on number of stream channels and the stream format 351 * being used. 352 * 353 ** @todo Use some RTAsmXXX functions instead? 354 */ 355 uint8_t cShift; 356 /** Number of audio channels. */ 357 uint8_t cChannels; 358 /** Sample frequency in Hertz (Hz). */ 359 uint32_t uHz; 360 /** Whether the endianness is swapped or not. */ 361 bool fSwapEndian; 362 } PDMAUDIOPCMPROPS, *PPDMAUDIOPCMPROPS; 363 364 /** Calculates the cShift value of given samples bits and audio channels. 365 * Note: Does only support mono/stereo channels for now. */ 366 #define PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(cBits, cChannels) ((cChannels == 2) + cBits / 16) 367 /** Calculates the cShift value of a PDMAUDIOPCMPROPS structure. 368 * Note: Does only support mono/stereo channels for now. */ 369 #define PDMAUDIOPCMPROPS_MAKE_SHIFT(pProps) PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS((pProps)->cChannels == 2) + (pProps)->cBits / 16) 370 /** Converts (audio) samples to bytes. 371 * Needs the cShift value set correctly, using PDMAUDIOPCMPROPS_MAKE_SHIFT. */ 372 #define PDMAUDIOPCMPROPS_S2B(pProps, samples) ((samples) << (pProps)->cShift) 373 /** Converts bytes to (audio) samples. 374 * Needs the cShift value set correctly, using PDMAUDIOPCMPROPS_MAKE_SHIFT. */ 375 #define PDMAUDIOPCMPROPS_B2S(pProps, cb) (cb >> (pProps)->cShift) 376 377 /** 339 378 * Structure for keeping an audio stream configuration. 340 379 */ … … 347 386 /** Destination / source indicator, depending on enmDir. */ 348 387 PDMAUDIODESTSOURCE DestSource; 349 /** Frequency in Hertz (Hz). */ 350 uint32_t uHz; 351 /** Number of audio channels (2 for stereo, 1 for mono). */ 352 uint8_t cChannels; 353 /** Audio format. */ 354 PDMAUDIOFMT enmFormat; 355 /** @todo Use RT_LE2H_*? */ 356 PDMAUDIOENDIANNESS enmEndianness; 388 /** The stream's PCM properties. */ 389 PDMAUDIOPCMPROPS Props; 357 390 /** Hint about the optimal sample buffer size (in audio samples). 358 391 * 0 if no hint is given. */ 359 uint32_t cSampleBuffer Size;392 uint32_t cSampleBufferHint; 360 393 } PDMAUDIOSTREAMCFG, *PPDMAUDIOSTREAMCFG; 394 395 /** Converts (audio) samples to bytes. */ 396 #define PDMAUDIOSTREAMCFG_S2B(pCfg, samples) ((samples) << (pCfg->Props).cShift) 397 /** Converts bytes to (audio) samples. */ 398 #define PDMAUDIOSTREAMCFG_B2S(pCfg, cb) (cb >> (pCfg->Props).cShift) 361 399 362 400 #if defined(RT_LITTLE_ENDIAN) … … 410 448 PDMAUDIOSTREAMCMD_32BIT_HACK = 0x7fffffff 411 449 } PDMAUDIOSTREAMCMD; 412 413 /**414 * Properties of audio streams for host/guest415 * for in or out directions.416 */417 typedef struct PDMAUDIOPCMPROPS418 {419 /** Sample width. Bits per sample. */420 uint8_t cBits;421 /** Signed or unsigned sample. */422 bool fSigned;423 /** Shift count used for faster calculation of various424 * values, such as the alignment, bytes to samples and so on.425 * Depends on number of stream channels and the stream format426 * being used.427 *428 ** @todo Use some RTAsmXXX functions instead?429 */430 uint8_t cShift;431 /** Number of audio channels. */432 uint8_t cChannels;433 /** Alignment mask. */434 uint32_t uAlign;435 /** Sample frequency in Hertz (Hz). */436 uint32_t uHz;437 /** Bitrate (in bytes/s). */438 uint32_t cbBitrate;439 /** Whether the endianness is swapped or not. */440 bool fSwapEndian;441 } PDMAUDIOPCMPROPS, *PPDMAUDIOPCMPROPS;442 443 /** Converts (audio) samples to bytes. */444 #define PDMAUDIOPCMPROPS_S2B(pProps, samples) ((samples) << (pProps)->cShift)445 /** Converts bytes to (audio) samples. */446 #define PDMAUDIOPCMPROPS_B2S(pProps, cb) (cb >> (pProps)->cShift)447 450 448 451 /** … … 786 789 PDMAUDIOSTREAMOUT Out; 787 790 }; 791 /** Data to backend-specific stream data. 792 * This data block will be casted by the backend to access its backend-dependent data. 793 * 794 * That way the backends do not have access to the audio connector's data. */ 795 void *pvBackend; 796 /** Size (in bytes) of the backend-specific stream data. */ 797 size_t cbBackend; 788 798 } PDMAUDIOSTREAM, *PPDMAUDIOSTREAM; 789 799 … … 867 877 } PDMAUDIOCALLBACK, *PPDMAUDIOCALLBACK; 868 878 #endif /* VBOX_WITH_AUDIO_DEVICE_CALLBACKS */ 879 880 #define PPDMAUDIOBACKENDSTREAM void * 869 881 870 882 /** … … 1128 1140 * @param pCfgAcq Pointer to acquired stream configuration. 1129 1141 */ 1130 DECLR3CALLBACKMEMBER(int, pfnStreamCreate, (PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq));1142 DECLR3CALLBACKMEMBER(int, pfnStreamCreate, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)); 1131 1143 1132 1144 /** … … 1137 1149 * @param pStream Pointer to audio stream. 1138 1150 */ 1139 DECLR3CALLBACKMEMBER(int, pfnStreamDestroy, (PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream));1151 DECLR3CALLBACKMEMBER(int, pfnStreamDestroy, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)); 1140 1152 1141 1153 /** … … 1147 1159 * @param enmStreamCmd The stream command to issue. 1148 1160 */ 1149 DECLR3CALLBACKMEMBER(int, pfnStreamControl, (PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd));1161 DECLR3CALLBACKMEMBER(int, pfnStreamControl, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)); 1150 1162 1151 1163 /** … … 1156 1168 * @param pStream Pointer to audio stream. 1157 1169 */ 1158 DECLR3CALLBACKMEMBER(PDMAUDIOSTRMSTS, pfnStreamGetStatus, (PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream));1170 DECLR3CALLBACKMEMBER(PDMAUDIOSTRMSTS, pfnStreamGetStatus, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)); 1159 1171 1160 1172 /** … … 1165 1177 * @param pStream Pointer to audio stream. 1166 1178 */ 1167 DECLR3CALLBACKMEMBER(int, pfnStreamIterate, (PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream));1179 DECLR3CALLBACKMEMBER(int, pfnStreamIterate, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)); 1168 1180 1169 1181 /** … … 1177 1189 * @param pcbWritten Returns number of bytes written. Optional. 1178 1190 */ 1179 DECLR3CALLBACKMEMBER(int, pfnStreamPlay, (PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten));1191 DECLR3CALLBACKMEMBER(int, pfnStreamPlay, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)); 1180 1192 1181 1193 /** … … 1189 1201 * @param pcbRead Returns number of bytes read. Optional. 1190 1202 */ 1191 DECLR3CALLBACKMEMBER(int, pfnStreamCapture, (PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead));1203 DECLR3CALLBACKMEMBER(int, pfnStreamCapture, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)); 1192 1204 1193 1205 } PDMIHOSTAUDIO; 1194 1206 1195 1207 /** PDMIHOSTAUDIO interface ID. */ 1196 #define PDMIHOSTAUDIO_IID " C45550DE-03C0-4A45-9A96-C5EB956F806D"1208 #define PDMIHOSTAUDIO_IID "1F1C3DEB-AEA3-4E32-8405-EC7E7661E888" 1197 1209 1198 1210 /** @} */ -
trunk/src/VBox/Devices/Audio/AudioMixer.cpp
r65056 r65624 30 30 31 31 /* 32 * Copyright (C) 2014-201 6Oracle Corporation32 * Copyright (C) 2014-2017 Oracle Corporation 33 33 * 34 34 * This file is part of VirtualBox Open Source Edition (OSE), as … … 600 600 return rc; 601 601 602 LogFlowFunc(("[%s]: fFlags=0x%x (enmDir=% d, %s, %RU8 channels, %RU32Hz)\n",603 pSink->pszName, fFlags, pCfg->enmDir, DrvAudioHlpAudFmtToStr(pCfg->enmFormat), pCfg->cChannels, pCfg->uHz));602 LogFlowFunc(("[%s]: fFlags=0x%x (enmDir=%ld, %RU8 bits, %RU8 channels, %RU32Hz)\n", 603 pSink->pszName, fFlags, pCfg->enmDir, pCfg->Props.cBits, pCfg->Props.cChannels, pCfg->Props.uHz)); 604 604 605 605 /* … … 839 839 uint64_t tsDeltaMS = RTTimeMilliTS() - pSink->tsLastUpdatedMS; 840 840 841 cbReadable = ( pSink->PCMProps.cbBitrate/ 1000 /* s to ms */) * tsDeltaMS;841 cbReadable = ((DrvAudioHlpCalcBitrate(&pSink->PCMProps) / 8) / 1000 /* s to ms */) * tsDeltaMS; 842 842 843 843 Log3Func(("[%s] Bitrate is %RU32 bytes/s -> %RU64ms / %RU32 bytes elapsed\n", 844 pSink->pszName, pSink->PCMProps.cbBitrate, tsDeltaMS, cbReadable));844 pSink->pszName, DrvAudioHlpCalcBitrate(&pSink->PCMProps) / 8, tsDeltaMS, cbReadable)); 845 845 #endif 846 846 … … 890 890 uint64_t tsDeltaMS = RTTimeMilliTS() - pSink->tsLastUpdatedMS; 891 891 892 cbWritable = ( pSink->PCMProps.cbBitrate/ 1000 /* s to ms */) * tsDeltaMS;892 cbWritable = ((DrvAudioHlpCalcBitrate(&pSink->PCMProps) / 8) / 1000 /* s to ms */) * tsDeltaMS; 893 893 894 894 Log3Func(("[%s] Bitrate is %RU32 bytes/s -> %RU64ms / %RU32 bytes elapsed\n", 895 pSink->pszName, pSink->PCMProps.cbBitrate, tsDeltaMS, cbWritable));895 pSink->pszName, DrvAudioHlpCalcBitrate(&pSink->PCMProps) / 8, tsDeltaMS, cbWritable)); 896 896 #endif 897 897 } -
trunk/src/VBox/Devices/Audio/DevHDA.cpp
r65152 r65624 9 9 10 10 /* 11 * Copyright (C) 2006-201 6Oracle Corporation11 * Copyright (C) 2006-2017 Oracle Corporation 12 12 * 13 13 * This file is part of VirtualBox Open Source Edition (OSE), as … … 2647 2647 } 2648 2648 2649 PDMAUDIOFMT enmFmt;2649 uint8_t cBits = 0; 2650 2650 switch (EXTRACT_VALUE(u32SDFMT, HDA_SDFMT_BITS_MASK, HDA_SDFMT_BITS_SHIFT)) 2651 2651 { 2652 2652 case 0: 2653 enmFmt = PDMAUDIOFMT_S8;2653 cBits = 8; 2654 2654 break; 2655 2655 case 1: 2656 enmFmt = PDMAUDIOFMT_S16;2656 cBits = 16; 2657 2657 break; 2658 2658 case 4: 2659 enmFmt = PDMAUDIOFMT_S32;2659 cBits = 32; 2660 2660 break; 2661 2661 default: 2662 2662 AssertMsgFailed(("Unsupported bits per sample %x\n", 2663 2663 EXTRACT_VALUE(u32SDFMT, HDA_SDFMT_BITS_MASK, HDA_SDFMT_BITS_SHIFT))); 2664 enmFmt = PDMAUDIOFMT_INVALID;2665 2664 rc = VERR_NOT_SUPPORTED; 2666 2665 break; … … 2669 2668 if (RT_SUCCESS(rc)) 2670 2669 { 2671 pStrmCfg->uHz = u32Hz * u32HzMult / u32HzDiv; 2672 pStrmCfg->cChannels = (u32SDFMT & 0xf) + 1; 2673 pStrmCfg->enmFormat = enmFmt; 2674 pStrmCfg->enmEndianness = PDMAUDIOHOSTENDIANNESS; 2670 RT_ZERO(pStrmCfg->Props); 2671 2672 pStrmCfg->Props.uHz = u32Hz * u32HzMult / u32HzDiv; 2673 pStrmCfg->Props.cChannels = (u32SDFMT & 0xf) + 1; 2674 pStrmCfg->Props.cBits = cBits; 2675 pStrmCfg->Props.fSigned = true; 2675 2676 } 2676 2677 … … 2740 2741 #else /* !VBOX_WITH_AUDIO_HDA_51_SURROUND */ 2741 2742 /* Only support mono or stereo channels. */ 2742 if ( pCfg-> cChannels != 1 /* Mono */2743 && pCfg-> cChannels != 2 /* Stereo */)2743 if ( pCfg->Props.cChannels != 1 /* Mono */ 2744 && pCfg->Props.cChannels != 2 /* Stereo */) 2744 2745 { 2745 2746 rc = VERR_NOT_SUPPORTED; … … 2749 2750 if (rc == VERR_NOT_SUPPORTED) 2750 2751 { 2751 LogRel(("HDA: Unsupported channel count (%RU8), falling back to stereo channels\n", pCfg-> cChannels));2752 pCfg-> cChannels = 2;2752 LogRel(("HDA: Unsupported channel count (%RU8), falling back to stereo channels\n", pCfg->Props.cChannels)); 2753 pCfg->Props.cChannels = 2; 2753 2754 2754 2755 rc = VINF_SUCCESS; … … 2764 2765 RTStrPrintf(pCfg->szName, RT_ELEMENTS(pCfg->szName), "Front"); 2765 2766 pCfg->DestSource.Dest = PDMAUDIOPLAYBACKDEST_FRONT; 2766 pCfg-> cChannels= 2;2767 pCfg->Props.cChannels = 2; 2767 2768 2768 2769 rc = hdaCodecRemoveStream(pThis->pCodec, PDMAUDIOMIXERCTL_FRONT); … … 2777 2778 RTStrPrintf(pCfg->szName, RT_ELEMENTS(pCfg->szName), "Center/LFE"); 2778 2779 pCfg->DestSource.Dest = PDMAUDIOPLAYBACKDEST_CENTER_LFE; 2779 pCfg-> cChannels= (fUseCenter && fUseLFE) ? 2 : 1;2780 pCfg->Props.cChannels = (fUseCenter && fUseLFE) ? 2 : 1; 2780 2781 2781 2782 rc = hdaCodecRemoveStream(pThis->pCodec, PDMAUDIOMIXERCTL_CENTER_LFE); … … 2789 2790 RTStrPrintf(pCfg->szName, RT_ELEMENTS(pCfg->szName), "Rear"); 2790 2791 pCfg->DestSource.Dest = PDMAUDIOPLAYBACKDEST_REAR; 2791 pCfg-> cChannels= 2;2792 pCfg->Props.cChannels = 2; 2792 2793 2793 2794 rc = hdaCodecRemoveStream(pThis->pCodec, PDMAUDIOMIXERCTL_REAR); … … 2860 2861 } 2861 2862 2862 LogFunc(("[SD%RU8]: Hz=%RU32, Channels=%RU8, enmFmt=%RU32\n",2863 pStream->u8SD, strmCfg. uHz, strmCfg.cChannels, strmCfg.enmFormat));2863 LogFunc(("[SD%RU8]: Hz=%RU32, Channels=%RU8, cBits=%RU8\n", 2864 pStream->u8SD, strmCfg.Props.uHz, strmCfg.Props.cChannels, strmCfg.Props.cBits)); 2864 2865 2865 2866 /* Set audio direction. */ … … 3297 3298 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 3298 3299 3299 AssertReturn(pCfg-> cChannels, VERR_INVALID_PARAMETER);3300 AssertReturn(pCfg->Props.cChannels, VERR_INVALID_PARAMETER); 3300 3301 3301 3302 hdaStreamMapReset(pMapping); 3302 3303 3303 pMapping->paChannels = (PPDMAUDIOSTREAMCHANNEL)RTMemAlloc(sizeof(PDMAUDIOSTREAMCHANNEL) * pCfg-> cChannels);3304 pMapping->paChannels = (PPDMAUDIOSTREAMCHANNEL)RTMemAlloc(sizeof(PDMAUDIOSTREAMCHANNEL) * pCfg->Props.cChannels); 3304 3305 if (!pMapping->paChannels) 3305 3306 return VERR_NO_MEMORY; 3306 3307 3307 PDMAUDIOPCMPROPS Props;3308 int rc = DrvAudioHlpStreamCfgToProps(pCfg, &Props);3309 if (RT_FAILURE(rc)) 3310 return rc;3311 3312 Assert(RT_IS_POWER_OF_TWO( Props.cBits));3308 if (!DrvAudioHlpStreamCfgIsValid(pCfg)) 3309 return VERR_INVALID_PARAMETER; 3310 3311 int rc = VINF_SUCCESS; 3312 3313 Assert(RT_IS_POWER_OF_TWO(pCfg->Props.cBits)); 3313 3314 3314 3315 /** @todo We assume all channels in a stream have the same format. */ 3315 3316 PPDMAUDIOSTREAMCHANNEL pChan = pMapping->paChannels; 3316 for (uint8_t i = 0; i < pCfg-> cChannels; i++)3317 for (uint8_t i = 0; i < pCfg->Props.cChannels; i++) 3317 3318 { 3318 3319 pChan->uChannel = i; 3319 pChan->cbStep = ( Props.cBits / 2);3320 pChan->cbFrame = pChan->cbStep * pCfg-> cChannels;3320 pChan->cbStep = (pCfg->Props.cBits / 2); 3321 pChan->cbFrame = pChan->cbStep * pCfg->Props.cChannels; 3321 3322 pChan->cbFirst = i * pChan->cbStep; 3322 3323 pChan->cbOff = pChan->cbFirst; … … 3341 3342 if (RT_SUCCESS(rc)) 3342 3343 { 3343 pMapping->cChannels = pCfg-> cChannels;3344 pMapping->cChannels = pCfg->Props.cChannels; 3344 3345 #ifdef VBOX_WITH_HDA_AUDIO_INTERLEAVING_STREAMS_SUPPORT 3345 3346 pMapping->enmLayout = PDMAUDIOSTREAMLAYOUT_INTERLEAVED; … … 3527 3528 LogFunc(("Sink=%s, Stream=%s\n", pSink->pMixSink->pszName, pCfg->szName)); 3528 3529 3529 /* Update the sink's format. */ 3530 PDMAUDIOPCMPROPS PCMProps; 3531 int rc = DrvAudioHlpStreamCfgToProps(pCfg, &PCMProps); 3532 if (RT_SUCCESS(rc)) 3533 rc = AudioMixerSinkSetFormat(pSink->pMixSink, &PCMProps); 3534 3530 if (!DrvAudioHlpStreamCfgIsValid(pCfg)) 3531 return VERR_INVALID_PARAMETER; 3532 3533 int rc = AudioMixerSinkSetFormat(pSink->pMixSink, &pCfg->Props); 3535 3534 if (RT_FAILURE(rc)) 3536 3535 return rc; … … 3542 3541 PHDADRIVERSTREAM pDrvStream = NULL; 3543 3542 3544 PPDMAUDIOSTREAMCFG pStreamCfg = (PPDMAUDIOSTREAMCFG)RTMemDup(pCfg, sizeof(PDMAUDIOSTREAMCFG));3543 PPDMAUDIOSTREAMCFG pStreamCfg = DrvAudioHlpStreamCfgDup(pCfg); 3545 3544 if (!pStreamCfg) 3546 3545 { … … 4698 4697 } 4699 4698 4700 #ifdef DEBUG_andy4701 4699 AssertMsg(cbDMALeft == 0, ("%RU32 bytes of DMA data left, CircBuf=%zu/%zu\n", 4702 4700 cbDMALeft, RTCircBufUsed(pCircBuf), RTCircBufSize(pCircBuf))); 4703 #endif 4701 4704 4702 /* 4705 4703 * Process backends. … … 4782 4780 AssertFailed(); 4783 4781 4784 if (++cTransfers > 32) /* Failsafe counter. */4782 if (++cTransfers == UINT8_MAX) /* Failsafe counter. */ 4785 4783 fDone = true; 4786 4784 4787 4785 } /* while !fDone */ 4786 4787 #ifdef VBOX_STRICT 4788 AssertMsg(cTransfers < UINT8_MAX, ("HDA: Update for SD#%RU8 ran for too long\n", pStream->u8SD)); 4789 #endif 4788 4790 4789 4791 Log2Func(("[SD%RU8] End\n", pStream->u8SD)); -
trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
r65150 r65624 1475 1475 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 1476 1476 1477 /* Update the sink's format. */ 1478 PDMAUDIOPCMPROPS PCMProps; 1479 int rc = DrvAudioHlpStreamCfgToProps(pCfg, &PCMProps); 1480 if (RT_SUCCESS(rc)) 1481 rc = AudioMixerSinkSetFormat(pMixSink, &PCMProps); 1482 1477 if (!DrvAudioHlpStreamCfgIsValid(pCfg)) 1478 return VERR_INVALID_PARAMETER; 1479 1480 int rc = AudioMixerSinkSetFormat(pMixSink, &pCfg->Props); 1483 1481 if (RT_FAILURE(rc)) 1484 1482 return rc; … … 1487 1485 RTListForEach(&pThis->lstDrv, pDrv, AC97DRIVER, Node) 1488 1486 { 1489 PPDMAUDIOSTREAMCFG pStreamCfg = (PPDMAUDIOSTREAMCFG)RTMemDup(pCfg, sizeof(PDMAUDIOSTREAMCFG));1487 PPDMAUDIOSTREAMCFG pStreamCfg = DrvAudioHlpStreamCfgDup(pCfg); 1490 1488 if (!pStreamCfg) 1491 1489 { … … 1593 1591 case AC97SOUNDSOURCE_PI_INDEX: 1594 1592 { 1595 streamCfg. uHz= ichac97MixerGet(pThis, AC97_PCM_LR_ADC_Rate);1593 streamCfg.Props.uHz = ichac97MixerGet(pThis, AC97_PCM_LR_ADC_Rate); 1596 1594 streamCfg.enmDir = PDMAUDIODIR_IN; 1597 1595 streamCfg.DestSource.Source = PDMAUDIORECSOURCE_LINE; … … 1605 1603 case AC97SOUNDSOURCE_MC_INDEX: 1606 1604 { 1607 streamCfg. uHz= ichac97MixerGet(pThis, AC97_MIC_ADC_Rate);1605 streamCfg.Props.uHz = ichac97MixerGet(pThis, AC97_MIC_ADC_Rate); 1608 1606 streamCfg.enmDir = PDMAUDIODIR_IN; 1609 1607 streamCfg.DestSource.Source = PDMAUDIORECSOURCE_MIC; … … 1617 1615 case AC97SOUNDSOURCE_PO_INDEX: 1618 1616 { 1619 streamCfg. uHz= ichac97MixerGet(pThis, AC97_PCM_Front_DAC_Rate);1617 streamCfg.Props.uHz = ichac97MixerGet(pThis, AC97_PCM_Front_DAC_Rate); 1620 1618 streamCfg.enmDir = PDMAUDIODIR_OUT; 1621 1619 streamCfg.DestSource.Dest = PDMAUDIOPLAYBACKDEST_FRONT; … … 1636 1634 ichac97MixerRemoveDrvStreams(pThis, pMixSink, streamCfg.enmDir, streamCfg.DestSource); 1637 1635 1638 if (streamCfg. uHz)1636 if (streamCfg.Props.uHz) 1639 1637 { 1640 1638 Assert(streamCfg.enmDir != PDMAUDIODIR_UNKNOWN); 1641 1639 1642 streamCfg. cChannels= 2;1643 streamCfg. enmFormat = PDMAUDIOFMT_S16;1644 streamCfg. enmEndianness = PDMAUDIOHOSTENDIANNESS;1640 streamCfg.Props.cChannels = 2; 1641 streamCfg.Props.cBits = 16; 1642 streamCfg.Props.fSigned = true; 1645 1643 1646 1644 rc = ichac97MixerAddDrvStreams(pThis, pMixSink, &streamCfg); -
trunk/src/VBox/Devices/Audio/DevSB16.cpp
r64333 r65624 492 492 PDMAUDIOSTREAMCFG streamCfg; 493 493 RT_ZERO(streamCfg); 494 494 495 streamCfg.enmDir = PDMAUDIODIR_OUT; 495 496 streamCfg.DestSource.Dest = PDMAUDIOPLAYBACKDEST_FRONT; 496 streamCfg.uHz = pThis->freq; 497 streamCfg.cChannels = 1 << pThis->fmt_stereo; 498 streamCfg.enmFormat = pThis->fmt; 499 streamCfg.enmEndianness = PDMAUDIOHOSTENDIANNESS; 497 498 streamCfg.Props.uHz = pThis->freq; 499 streamCfg.Props.cChannels = 1 << pThis->fmt_stereo; 500 streamCfg.Props.cBits = pThis->fmt_bits; 501 streamCfg.Props.fSigned = RT_BOOL(pThis->fmt_signed); 500 502 501 503 int rc = sb16OpenOut(pThis, &streamCfg); … … 630 632 PDMAUDIOSTREAMCFG streamCfg; 631 633 RT_ZERO(streamCfg); 634 632 635 streamCfg.enmDir = PDMAUDIODIR_OUT; 633 636 streamCfg.DestSource.Dest = PDMAUDIOPLAYBACKDEST_FRONT; 634 streamCfg.uHz = pThis->freq; 635 streamCfg.cChannels = 1 << pThis->fmt_stereo; 636 streamCfg.enmFormat = pThis->fmt; 637 streamCfg.enmEndianness = PDMAUDIOHOSTENDIANNESS; 637 638 streamCfg.Props.uHz = pThis->freq; 639 streamCfg.Props.cChannels = 1 << pThis->fmt_stereo; 640 streamCfg.Props.cBits = pThis->fmt_bits; 641 streamCfg.Props.fSigned = RT_BOOL(pThis->fmt_signed); 638 642 639 643 int rc = sb16OpenOut(pThis, &streamCfg); … … 1163 1167 PDMAUDIOSTREAMCFG streamCfg; 1164 1168 RT_ZERO(streamCfg); 1169 1165 1170 streamCfg.enmDir = PDMAUDIODIR_OUT; 1166 1171 streamCfg.DestSource.Dest = PDMAUDIOPLAYBACKDEST_FRONT; 1167 streamCfg.uHz = pThis->freq; 1168 streamCfg.cChannels = 1; /* Mono */ 1169 streamCfg.enmFormat = PDMAUDIOFMT_U8; 1170 streamCfg.enmEndianness = PDMAUDIOHOSTENDIANNESS; 1172 1173 streamCfg.Props.uHz = pThis->freq; 1174 streamCfg.Props.cChannels = 1; /* Mono */ 1175 streamCfg.Props.cBits = 8; 1176 streamCfg.Props.fSigned = false; 1171 1177 1172 1178 int rc2 = sb16OpenOut(pThis, &streamCfg); … … 1826 1832 * so check if all streams have the same configuration. 1827 1833 */ 1828 AssertMsg(pStream->Cfg.uHz == pStreamPrev->Cfg.uHz, 1829 ("%RU32Hz vs. %RU32Hz\n", pStream->Cfg.uHz, pStreamPrev->Cfg.uHz)); 1830 AssertMsg(pStream->Cfg.cChannels == pStreamPrev->Cfg.cChannels, 1831 ("%RU8 vs. %RU8 channels\n", pStream->Cfg.cChannels, pStreamPrev->Cfg.cChannels)); 1832 AssertMsg(pStream->Cfg.enmFormat == pStreamPrev->Cfg.enmFormat, 1833 ("%d vs. %d format\n", pStream->Cfg.enmFormat, pStreamPrev->Cfg.enmFormat)); 1834 AssertMsg(pStream->Cfg.Props.uHz == pStreamPrev->Cfg.Props.uHz, 1835 ("%RU32Hz vs. %RU32Hz\n", pStream->Cfg.Props.uHz, pStreamPrev->Cfg.Props.uHz)); 1836 AssertMsg(pStream->Cfg.Props.cChannels == pStreamPrev->Cfg.Props.cChannels, 1837 ("%RU8 vs. %RU8 channels\n", pStream->Cfg.Props.cChannels, pStreamPrev->Cfg.Props.cChannels)); 1838 AssertMsg(pStream->Cfg.Props.cBits == pStreamPrev->Cfg.Props.cBits, 1839 ("%d vs. %d bits\n", pStream->Cfg.Props.cBits, pStreamPrev->Cfg.Props.cBits)); 1840 AssertMsg(pStream->Cfg.Props.fSigned == pStreamPrev->Cfg.Props.fSigned, 1841 ("%RTbool vs. %RTbool signed\n", pStream->Cfg.Props.fSigned, pStreamPrev->Cfg.Props.fSigned)); 1834 1842 } 1835 1843 #endif … … 2016 2024 PDMAUDIOSTREAMCFG streamCfg; 2017 2025 RT_ZERO(streamCfg); 2026 2018 2027 streamCfg.enmDir = PDMAUDIODIR_OUT; 2019 2028 streamCfg.DestSource.Dest = PDMAUDIOPLAYBACKDEST_FRONT; 2020 streamCfg.uHz = pThis->freq; 2021 streamCfg.cChannels = 1 << pThis->fmt_stereo; 2022 streamCfg.enmFormat = pThis->fmt; 2023 streamCfg.enmEndianness = PDMAUDIOHOSTENDIANNESS; 2029 2030 streamCfg.Props.uHz = pThis->freq; 2031 streamCfg.Props.cChannels = 1 << pThis->fmt_stereo; 2032 streamCfg.Props.cBits = pThis->fmt_bits; 2033 streamCfg.Props.fSigned = RT_BOOL(pThis->fmt_signed); 2024 2034 2025 2035 int rc = sb16OpenOut(pThis, &streamCfg); … … 2117 2127 /* Set a default audio format for the host. */ 2118 2128 PDMAUDIOSTREAMCFG CfgHost; 2129 RT_ZERO(CfgHost); 2130 2119 2131 CfgHost.enmDir = PDMAUDIODIR_OUT; 2120 2132 CfgHost.DestSource.Dest = PDMAUDIOPLAYBACKDEST_FRONT; 2121 CfgHost.uHz = pCfg->uHz; 2122 CfgHost.cChannels = pCfg->cChannels; 2123 CfgHost.enmFormat = PDMAUDIOFMT_S16; 2124 CfgHost.enmEndianness = PDMAUDIOHOSTENDIANNESS; 2133 2134 CfgHost.Props.uHz = pCfg->Props.uHz; 2135 CfgHost.Props.cChannels = pCfg->Props.cChannels; 2136 CfgHost.Props.cBits = pCfg->Props.cBits; 2137 CfgHost.Props.fSigned = pCfg->Props.fSigned; 2125 2138 2126 2139 RTStrPrintf(CfgHost.szName, sizeof(CfgHost.szName), "sb16.po"); … … 2134 2147 { 2135 2148 if (!RTStrPrintf(pCfg->szName, sizeof(pCfg->szName), "[LUN#%RU8] %s (%RU32Hz, %RU8 %s)", 2136 pDrv->uLUN, CfgHost.szName, pCfg->uHz, pCfg->cChannels, pCfg->cChannels > 1 ? "Channels" : "Channel")) 2149 pDrv->uLUN, CfgHost.szName, 2150 pCfg->Props.uHz, pCfg->Props.cChannels, pCfg->Props.cChannels > 1 ? "Channels" : "Channel")) 2137 2151 { 2138 2152 rc = VERR_BUFFER_OVERFLOW; -
trunk/src/VBox/Devices/Audio/DrvAudio.cpp
r65570 r65624 8 8 9 9 /* 10 * Copyright (C) 2006-201 6Oracle Corporation10 * Copyright (C) 2006-2017 Oracle Corporation 11 11 * 12 12 * This file is part of VirtualBox Open Source Edition (OSE), as … … 50 50 static int drvAudioStreamCreateInternalBackend(PDRVAUDIO pThis, PPDMAUDIOSTREAM pHstStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq); 51 51 static int drvAudioStreamDestroyInternalBackend(PDRVAUDIO pThis, PPDMAUDIOSTREAM pHstStream); 52 static void drvAudioStreamFree(PPDMAUDIOSTREAM pStream); 52 53 static int drvAudioStreamUninitInternal(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream); 53 54 static int drvAudioStreamInitInternal(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgHost, PPDMAUDIOSTREAMCFG pCfgGuest); … … 499 500 { 500 501 LogRel2(("Audio: Enabling stream '%s'\n", pHstStream->szName)); 501 rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_ENABLE); 502 rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream->pvBackend, 503 PDMAUDIOSTREAMCMD_ENABLE); 502 504 if (RT_SUCCESS(rc)) 503 505 { … … 515 517 { 516 518 LogRel2(("Audio: Disabling stream '%s'\n", pHstStream->szName)); 517 rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_DISABLE); 519 rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream->pvBackend, 520 PDMAUDIOSTREAMCMD_DISABLE); 518 521 if (RT_SUCCESS(rc)) 519 522 { … … 537 540 { 538 541 LogRel2(("Audio: Pausing stream '%s'\n", pHstStream->szName)); 539 rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_PAUSE); 542 rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream->pvBackend, 543 PDMAUDIOSTREAMCMD_PAUSE); 540 544 if (RT_SUCCESS(rc)) 541 545 { … … 557 561 { 558 562 LogRel2(("Audio: Resuming stream '%s'\n", pHstStream->szName)); 559 rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_RESUME); 563 rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream->pvBackend, 564 PDMAUDIOSTREAMCMD_RESUME); 560 565 if (RT_SUCCESS(rc)) 561 566 { … … 632 637 633 638 /* No sample buffer size hint given by the backend? Default to some sane value. */ 634 if (!CfgHostAcq.cSampleBufferSize) 635 { 636 CfgHostAcq.cSampleBufferSize = _1K; /** @todo Make this configurable? */ 637 } 638 639 PDMAUDIOPCMPROPS PCMProps; 640 int rc2 = DrvAudioHlpStreamCfgToProps(&CfgHostAcq, &PCMProps); 641 AssertRC(rc2); 639 if (!CfgHostAcq.cSampleBufferHint) 640 { 641 CfgHostAcq.cSampleBufferHint = _1K; /** @todo Make this configurable? */ 642 } 642 643 643 644 /* Destroy any former mixing buffer. */ 644 645 AudioMixBufDestroy(&pHstStream->MixBuf); 645 646 646 CfgHostAcq.cSampleBufferSize *= 10; /** @todo Make this configurable. */ 647 648 LogFlowFunc(("[%s] cSamples=%RU32\n", pHstStream->szName, CfgHostAcq.cSampleBufferSize)); 649 650 rc2 = AudioMixBufInit(&pHstStream->MixBuf, pHstStream->szName, &PCMProps, CfgHostAcq.cSampleBufferSize); 647 /* Make sure to (re-)set the host buffer's shift size. */ 648 CfgHostAcq.Props.cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(CfgHostAcq.Props.cBits, CfgHostAcq.Props.cChannels); 649 650 /* Set set host buffer size multiplicator. */ 651 const unsigned cSampleBufferHostFactor = 10; /** @todo Make this configurable. */ 652 653 LogFlowFunc(("[%s] cSamples=%RU32 (x %u)\n", pHstStream->szName, CfgHostAcq.cSampleBufferHint, cSampleBufferHostFactor)); 654 655 int rc2 = AudioMixBufInit(&pHstStream->MixBuf, pHstStream->szName, &CfgHostAcq.Props, 656 CfgHostAcq.cSampleBufferHint * cSampleBufferHostFactor); 651 657 AssertRC(rc2); 652 658 653 /* Make a copy of the host stream configuration. */ 654 memcpy(&pHstStream->Cfg, pCfgHost, sizeof(PDMAUDIOSTREAMCFG)); 659 /* Make a copy of the acquired host stream configuration. */ 660 rc2 = DrvAudioHlpStreamCfgCopy(&pHstStream->Cfg, pCfgHost); 661 AssertRC(rc2); 655 662 656 663 /* … … 658 665 */ 659 666 660 RT_ZERO(PCMProps);661 rc2 = DrvAudioHlpStreamCfgToProps(pCfgGuest, &PCMProps);662 AssertRC(rc2);663 664 667 /* Destroy any former mixing buffer. */ 665 668 AudioMixBufDestroy(&pGstStream->MixBuf); 666 669 667 CfgHostAcq.cSampleBufferSize *= 20; /** @todo Make this configurable. */ 668 669 LogFlowFunc(("[%s] cSamples=%RU32\n", pGstStream->szName, CfgHostAcq.cSampleBufferSize)); 670 671 rc2 = AudioMixBufInit(&pGstStream->MixBuf, pGstStream->szName, &PCMProps, CfgHostAcq.cSampleBufferSize); 670 /* Make sure to (re-)set the guest buffer's shift size. */ 671 pCfgGuest->Props.cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfgGuest->Props.cBits, pCfgGuest->Props.cChannels); 672 673 /* Set set guest buffer size multiplicator. */ 674 const unsigned cSampleBufferGuestFactor = 10; /** @todo Make this configurable. */ 675 676 LogFlowFunc(("[%s] cSamples=%RU32 (x %u)\n", pGstStream->szName, CfgHostAcq.cSampleBufferHint)); 677 678 rc2 = AudioMixBufInit(&pGstStream->MixBuf, pGstStream->szName, &pCfgGuest->Props, 679 CfgHostAcq.cSampleBufferHint * cSampleBufferGuestFactor); 672 680 AssertRC(rc2); 673 681 … … 685 693 } 686 694 687 /* Make a copy of the host stream configuration. */ 688 memcpy(&pGstStream->Cfg, pCfgGuest, sizeof(PDMAUDIOSTREAMCFG)); 695 /* Make a copy of the guest stream configuration. */ 696 rc2 = DrvAudioHlpStreamCfgCopy(&pGstStream->Cfg, pCfgGuest); 697 AssertRC(rc2); 689 698 690 699 if (RT_FAILURE(rc)) … … 693 702 LogFlowFunc(("[%s] Returning %Rrc\n", pStream->szName, rc)); 694 703 return rc; 704 } 705 706 /** 707 * Frees an audio stream and its allocated resources. 708 * 709 * @param pStream Audio stream to free. 710 * After this call the pointer will not be valid anymore. 711 */ 712 static void drvAudioStreamFree(PPDMAUDIOSTREAM pStream) 713 { 714 if (!pStream) 715 return; 716 717 if (pStream->pvBackend) 718 { 719 Assert(pStream->cbBackend); 720 RTMemFree(pStream->pvBackend); 721 pStream->pvBackend = NULL; 722 } 723 724 RTMemFree(pStream); 725 pStream = NULL; 695 726 } 696 727 … … 1108 1139 uint32_t csMixed = 0; 1109 1140 1110 rc = pThis->pHostDrvAudio->pfnStreamIterate(pThis->pHostDrvAudio, pHstStream );1141 rc = pThis->pHostDrvAudio->pfnStreamIterate(pThis->pHostDrvAudio, pHstStream->pvBackend); 1111 1142 if (RT_FAILURE(rc)) 1112 1143 break; … … 1262 1293 uint32_t csLive = AudioMixBufUsed(&pHstStream->MixBuf); 1263 1294 1264 PDMAUDIOSTRMSTS stsBackend = pThis->pHostDrvAudio->pfnStreamGetStatus(pThis->pHostDrvAudio, pHstStream );1295 PDMAUDIOSTRMSTS stsBackend = pThis->pHostDrvAudio->pfnStreamGetStatus(pThis->pHostDrvAudio, pHstStream->pvBackend); 1265 1296 1266 1297 #ifdef LOG_ENABLED … … 1274 1305 && (stsBackend & PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE)) 1275 1306 { 1276 uint8_t u8Buf[_ 1K];1307 uint8_t u8Buf[_4K]; /** @todo Get rid of this here. */ 1277 1308 1278 1309 uint32_t cRead = 0; … … 1284 1315 1285 1316 AssertPtr(pThis->pHostDrvAudio->pfnStreamPlay); 1286 rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream , u8Buf, cbBuf, &cbPlayed);1317 rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream->pvBackend, u8Buf, cbBuf, &cbPlayed); 1287 1318 if (RT_SUCCESS(rc)) 1288 1319 { 1320 AssertMsg(cbPlayed % 2 == 0, 1321 ("Backend for stream '%s' returned uneven played bytes count (%RU32)\n", pHstStream->szName, cbPlayed)); 1322 1289 1323 csPlayed = AUDIOMIXBUF_B2S(&pHstStream->MixBuf, cbPlayed); 1290 1324 … … 1377 1411 1378 1412 AssertPtr(pThis->pHostDrvAudio->pfnStreamGetStatus); 1379 PDMAUDIOSTRMSTS stsBackend = pThis->pHostDrvAudio->pfnStreamGetStatus(pThis->pHostDrvAudio, pHstStream );1413 PDMAUDIOSTRMSTS stsBackend = pThis->pHostDrvAudio->pfnStreamGetStatus(pThis->pHostDrvAudio, pHstStream->pvBackend); 1380 1414 1381 1415 uint32_t csLive = AudioMixBufLive(&pGstStream->MixBuf); … … 1388 1422 uint32_t cbCaptured; 1389 1423 1390 rc = pThis->pHostDrvAudio->pfnStreamCapture(pThis->pHostDrvAudio, pHstStream, auBuf, sizeof(auBuf), &cbCaptured); 1424 rc = pThis->pHostDrvAudio->pfnStreamCapture(pThis->pHostDrvAudio, pHstStream->pvBackend, 1425 auBuf, sizeof(auBuf), &cbCaptured); 1391 1426 if (RT_FAILURE(rc)) 1392 1427 { … … 1963 1998 } 1964 1999 1965 /* Note: cbHstStrm will contain sizeof(PDMAUDIOSTREAM) + additional data 1966 * which the host backend will need. */ 1967 size_t cbHstStrm; 2000 /* Note: cbHstStrm will contain the size of the data the backend needs to operate on. */ 2001 size_t cbHstStrm = 0; 1968 2002 if (pCfgHost->enmDir == PDMAUDIODIR_IN) 1969 2003 { … … 1971 2005 LogFunc(("Warning: No more input streams free to use\n")); 1972 2006 1973 /* Validate backend configuration. */1974 if (!pThis->BackendCfg.cbStreamIn)1975 {1976 LogFunc(("Backend input configuration not valid, bailing out\n"));1977 RC_BREAK(VERR_INVALID_PARAMETER);1978 }1979 1980 2007 cbHstStrm = pThis->BackendCfg.cbStreamIn; 1981 2008 } … … 1988 2015 } 1989 2016 1990 /* Validate backend configuration. */1991 if (!pThis->BackendCfg.cbStreamOut)1992 {1993 LogFlowFunc(("Backend output configuration invalid, bailing out\n"));1994 RC_BREAK(VERR_INVALID_PARAMETER);1995 }1996 1997 2017 cbHstStrm = pThis->BackendCfg.cbStreamOut; 1998 2018 } 1999 2019 2000 pHstStrm = (PPDMAUDIOSTREAM)RTMemAllocZ( cbHstStrm);2020 pHstStrm = (PPDMAUDIOSTREAM)RTMemAllocZ(sizeof(PDMAUDIOSTREAM)); 2001 2021 AssertPtrBreakStmt(pHstStrm, rc = VERR_NO_MEMORY); 2022 2023 if (cbHstStrm) /* High unlikely that backends do not have an own space for data, but better check. */ 2024 { 2025 pHstStrm->pvBackend = RTMemAllocZ(cbHstStrm); 2026 AssertPtrBreakStmt(pHstStrm->pvBackend, rc = VERR_NO_MEMORY); 2027 2028 pHstStrm->cbBackend = cbHstStrm; 2029 } 2002 2030 2003 2031 pHstStrm->enmCtx = PDMAUDIOSTREAMCTX_HOST; … … 2093 2121 if (RT_SUCCESS(rc2)) 2094 2122 { 2095 RTMemFree(pHstStrm);2123 drvAudioStreamFree(pHstStrm); 2096 2124 pHstStrm = NULL; 2097 2125 } … … 2381 2409 RTListNodeRemove(&pHstStream->Node); 2382 2410 2383 RTMemFree(pHstStream);2411 drvAudioStreamFree(pHstStream); 2384 2412 pHstStream = NULL; 2385 2413 } … … 2463 2491 ("Stream '%s' already initialized in backend\n", pHstStream->szName)); 2464 2492 2465 PDMAUDIOSTREAMCFG CfgAcq;2466 2467 2493 /* Make the acquired host configuration the requested host configuration initially, 2468 2494 * in case the backend does not report back an acquired configuration. */ 2469 memcpy(&CfgAcq, pCfgReq, sizeof(PDMAUDIOSTREAMCFG)); 2470 2471 int rc = pThis->pHostDrvAudio->pfnStreamCreate(pThis->pHostDrvAudio, pHstStream, pCfgReq, &CfgAcq); 2495 PDMAUDIOSTREAMCFG CfgAcq; 2496 int rc = DrvAudioHlpStreamCfgCopy(&CfgAcq, pCfgReq); 2497 if (RT_FAILURE(rc)) 2498 { 2499 LogRel2(("Audio: Creating stream '%s' with an invalid backend configuration not possible, skipping\n", 2500 pHstStream->szName)); 2501 return rc; 2502 } 2503 2504 rc = pThis->pHostDrvAudio->pfnStreamCreate(pThis->pHostDrvAudio, pHstStream->pvBackend, pCfgReq, &CfgAcq); 2472 2505 if (RT_FAILURE(rc)) 2473 2506 { … … 2479 2512 if (!DrvAudioHlpStreamCfgIsValid(&CfgAcq)) 2480 2513 { 2481 LogRel2(("Audio: Creating stream '%s' has an invalid configuration, skipping\n", pHstStream->szName));2514 LogRel2(("Audio: Creating stream '%s' returned an invalid backend configuration, skipping\n", pHstStream->szName)); 2482 2515 return VERR_INVALID_PARAMETER; 2483 2516 } … … 2489 2522 2490 2523 if (pCfgAcq) 2491 memcpy(pCfgAcq, &CfgAcq, sizeof(PDMAUDIOSTREAMCFG)); 2524 { 2525 int rc2 = DrvAudioHlpStreamCfgCopy(pCfgAcq, &CfgAcq); 2526 AssertRC(rc2); 2527 } 2492 2528 2493 2529 return VINF_SUCCESS; … … 2522 2558 * It can be NULL if we were called in drvAudioDestruct, for example. */ 2523 2559 if (pThis->pHostDrvAudio) 2524 rc = pThis->pHostDrvAudio->pfnStreamDestroy(pThis->pHostDrvAudio, pHstStream );2560 rc = pThis->pHostDrvAudio->pfnStreamDestroy(pThis->pHostDrvAudio, pHstStream->pvBackend); 2525 2561 if (RT_SUCCESS(rc)) 2526 2562 { … … 2783 2819 RTListNodeRemove(&pStream->Node); 2784 2820 2785 RTMemFree(pStream);2821 drvAudioStreamFree(pStream); 2786 2822 pStream = NULL; 2787 2823 } -
trunk/src/VBox/Devices/Audio/DrvAudio.h
r65027 r65624 5 5 6 6 /* 7 * Copyright (C) 2006-201 6Oracle Corporation7 * Copyright (C) 2006-2017 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 155 155 void DrvAudioHlpClearBuf(PPDMAUDIOPCMPROPS pPCMInfo, void *pvBuf, size_t cbBuf, uint32_t cSamples); 156 156 uint32_t DrvAudioHlpCalcBitrate(uint8_t cBits, uint32_t uHz, uint8_t cChannels); 157 uint32_t DrvAudioHlpCalcBitrate(PPDMAUDIO STREAMCFG pCfg);157 uint32_t DrvAudioHlpCalcBitrate(PPDMAUDIOPCMPROPS pProps); 158 158 bool DrvAudioHlpPCMPropsAreEqual(PPDMAUDIOPCMPROPS pPCMProps1, PPDMAUDIOPCMPROPS pPCMProps2); 159 159 bool DrvAudioHlpPCMPropsAreEqual(PPDMAUDIOPCMPROPS pPCMProps, PPDMAUDIOSTREAMCFG pCfg); … … 161 161 const char *DrvAudioHlpRecSrcToStr(PDMAUDIORECSOURCE enmRecSource); 162 162 void DrvAudioHlpStreamCfgPrint(PPDMAUDIOSTREAMCFG pCfg); 163 bool DrvAudioHlpStreamCfgIsValid(PPDMAUDIOSTREAMCFG pCfg); 164 int DrvAudioHlpStreamCfgToProps(PPDMAUDIOSTREAMCFG pCfg, PPDMAUDIOPCMPROPS pProps); 163 bool DrvAudioHlpStreamCfgIsValid(const PPDMAUDIOSTREAMCFG pCfg); 164 int DrvAudioHlpStreamCfgCopy(PPDMAUDIOSTREAMCFG pDstCfg, const PPDMAUDIOSTREAMCFG pSrcCfg); 165 PPDMAUDIOSTREAMCFG DrvAudioHlpStreamCfgDup(const PPDMAUDIOSTREAMCFG pCfg); 166 void DrvAudioHlpStreamCfgFree(PPDMAUDIOSTREAMCFG pCfg); 165 167 const char *DrvAudioHlpStreamCmdToStr(PDMAUDIOSTREAMCMD enmCmd); 166 168 PDMAUDIOFMT DrvAudioHlpStrToAudFmt(const char *pszFmt); -
trunk/src/VBox/Devices/Audio/DrvAudioCommon.cpp
r65056 r65624 156 156 cbToClear = cbBuf; 157 157 158 Log2Func(("pPCM Info=%p, pvBuf=%p, cSamples=%RU32, fSigned=%RTbool, cBits=%RU8, cShift=%RU8\n",159 pPCMProps, pvBuf, cSamples, pPCMProps->fSigned, pPCMProps->cBits , pPCMProps->cShift));158 Log2Func(("pPCMProps=%p, pvBuf=%p, cSamples=%RU32, fSigned=%RTbool, cBits=%RU8\n", 159 pPCMProps, pvBuf, cSamples, pPCMProps->fSigned, pPCMProps->cBits)); 160 160 161 161 if (pPCMProps->fSigned) … … 761 761 762 762 /** 763 * Checks whether two given PCM properties are equal. 764 * 765 * @returns @c true if equal, @c false if not. 766 * @param pProps1 First properties to compare. 767 * @param pProps2 Second properties to compare. 768 */ 769 bool DrvAudioHlpPCMPropsAreEqual(PPDMAUDIOPCMPROPS pProps1, PPDMAUDIOPCMPROPS pProps2) 770 { 771 AssertPtrReturn(pProps1, false); 772 AssertPtrReturn(pProps2, false); 773 774 if (pProps1 == pProps2) /* If the pointers match, take a shortcut. */ 775 return true; 776 777 return pProps1->uHz == pProps2->uHz 778 && pProps1->cChannels == pProps2->cChannels 779 && pProps1->cBits == pProps2->cBits 780 && pProps1->fSigned == pProps2->fSigned 781 && pProps1->fSwapEndian == pProps2->fSwapEndian; 782 } 783 784 /** 763 785 * Checks whether the given PCM properties are equal with the given 764 786 * stream configuration. … … 773 795 AssertPtrReturn(pCfg, false); 774 796 775 int cBits = 8; 776 bool fSigned = false; 777 778 switch (pCfg->enmFormat) 779 { 780 case PDMAUDIOFMT_S8: 781 fSigned = true; 782 case PDMAUDIOFMT_U8: 783 break; 784 785 case PDMAUDIOFMT_S16: 786 fSigned = true; 787 case PDMAUDIOFMT_U16: 788 cBits = 16; 789 break; 790 791 case PDMAUDIOFMT_S32: 792 fSigned = true; 793 case PDMAUDIOFMT_U32: 794 cBits = 32; 795 break; 796 797 default: 798 AssertMsgFailed(("Unknown format %ld\n", pCfg->enmFormat)); 799 break; 800 } 801 802 bool fEqual = pProps->uHz == pCfg->uHz 803 && pProps->cChannels == pCfg->cChannels 804 && pProps->fSigned == fSigned 805 && pProps->cBits == cBits 806 && pProps->fSwapEndian == !(pCfg->enmEndianness == PDMAUDIOHOSTENDIANNESS); 807 return fEqual; 808 } 809 810 /** 811 * Checks whether two given PCM properties are equal. 812 * 813 * @returns @c true if equal, @c false if not. 814 * @param pProps1 First properties to compare. 815 * @param pProps2 Second properties to compare. 816 */ 817 bool DrvAudioHlpPCMPropsAreEqual(PPDMAUDIOPCMPROPS pProps1, PPDMAUDIOPCMPROPS pProps2) 818 { 819 AssertPtrReturn(pProps1, false); 820 AssertPtrReturn(pProps2, false); 821 822 if (pProps1 == pProps2) /* If the pointers match, take a shortcut. */ 823 return true; 824 825 return pProps1->uHz == pProps2->uHz 826 && pProps1->cChannels == pProps2->cChannels 827 && pProps1->fSigned == pProps2->fSigned 828 && pProps1->cBits == pProps2->cBits 829 && pProps1->fSwapEndian == pProps2->fSwapEndian; 797 return DrvAudioHlpPCMPropsAreEqual(pProps, &pCfg->Props); 830 798 } 831 799 … … 842 810 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 843 811 844 pCfg->uHz = pPCMProps->uHz; 845 pCfg->cChannels = pPCMProps->cChannels; 846 pCfg->enmFormat = DrvAudioAudFmtBitsToAudFmt(pPCMProps->cBits, pPCMProps->fSigned); 847 848 /** @todo We assume little endian is the default for now. */ 849 pCfg->enmEndianness = pPCMProps->fSwapEndian == false ? PDMAUDIOENDIANNESS_LITTLE : PDMAUDIOENDIANNESS_BIG; 812 memcpy(&pCfg->Props, pPCMProps, sizeof(PDMAUDIOPCMPROPS)); 850 813 return VINF_SUCCESS; 851 814 } … … 856 819 * Returns @c true if configuration is valid, @c false if not. 857 820 * @param pCfg Stream configuration to check. 858 */ 859 bool DrvAudioHlpStreamCfgIsValid(PPDMAUDIOSTREAMCFG pCfg) 860 { 861 bool fValid = ( pCfg->cChannels == 1 862 || pCfg->cChannels == 2); /* Either stereo (2) or mono (1), per stream. */ 863 864 fValid |= ( pCfg->enmEndianness == PDMAUDIOENDIANNESS_LITTLE 865 || pCfg->enmEndianness == PDMAUDIOENDIANNESS_BIG); 821 * 822 * @remarks Does *not* support surround (> 2 channels) yet! This is intentional, as 823 * we consider surround support as experimental / not enabled by default for now. 824 */ 825 bool DrvAudioHlpStreamCfgIsValid(const PPDMAUDIOSTREAMCFG pCfg) 826 { 827 AssertPtrReturn(pCfg, false); 828 829 bool fValid = ( pCfg->Props.cChannels == 1 830 || pCfg->Props.cChannels == 2); /* Either stereo (2) or mono (1), per stream. */ 866 831 867 832 fValid |= ( pCfg->enmDir == PDMAUDIODIR_IN … … 870 835 if (fValid) 871 836 { 872 switch (pCfg->enmFormat) 873 { 874 case PDMAUDIOFMT_S8: 875 case PDMAUDIOFMT_U8: 876 case PDMAUDIOFMT_S16: 877 case PDMAUDIOFMT_U16: 878 case PDMAUDIOFMT_S32: 879 case PDMAUDIOFMT_U32: 837 switch (pCfg->Props.cBits) 838 { 839 case 8: 840 case 16: 841 /** @todo Do we need support for 24-bit samples? */ 842 case 32: 880 843 break; 881 844 default: … … 885 848 } 886 849 887 fValid |= pCfg->uHz > 0; 888 /** @todo Check for defined frequencies supported. */ 850 if (!fValid) 851 return false; 852 853 fValid |= pCfg->Props.uHz > 0; 854 fValid |= pCfg->Props.cShift == PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cBits, pCfg->Props.cChannels); 855 856 fValid |= pCfg->Props.fSwapEndian == false; /** @todo Handling Big Endian audio data is not supported yet. */ 889 857 890 858 return fValid; … … 892 860 893 861 /** 894 * Converts an audio stream configuration to matching PCM properties. 895 * 896 * @return IPRT status code. 897 * @param pCfg Audio stream configuration to convert. 898 * @param pProps PCM properties to save result to. 899 */ 900 int DrvAudioHlpStreamCfgToProps(PPDMAUDIOSTREAMCFG pCfg, PPDMAUDIOPCMPROPS pProps) 901 { 902 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 903 AssertPtrReturn(pProps, VERR_INVALID_POINTER); 904 905 int rc = VINF_SUCCESS; 906 907 int cBits = 8, cShift = 0; 908 bool fSigned = false; 909 910 switch (pCfg->enmFormat) 911 { 912 case PDMAUDIOFMT_S8: 913 fSigned = true; 914 case PDMAUDIOFMT_U8: 915 break; 916 917 case PDMAUDIOFMT_S16: 918 fSigned = true; 919 case PDMAUDIOFMT_U16: 920 cBits = 16; 921 cShift = 1; 922 break; 923 924 case PDMAUDIOFMT_S32: 925 fSigned = true; 926 case PDMAUDIOFMT_U32: 927 cBits = 32; 928 cShift = 2; 929 break; 930 931 default: 932 AssertMsgFailed(("Unknown format %ld\n", pCfg->enmFormat)); 933 rc = VERR_NOT_SUPPORTED; 934 break; 935 } 936 937 if (RT_SUCCESS(rc)) 938 { 939 pProps->uHz = pCfg->uHz; 940 pProps->cBits = cBits; 941 pProps->fSigned = fSigned; 942 pProps->cShift = (pCfg->cChannels == 2) + cShift; 943 pProps->cChannels = pCfg->cChannels; 944 pProps->cbBitrate = DrvAudioHlpCalcBitrate(pProps->cBits, pProps->uHz, pProps->cChannels) / 8 /* Convert to bytes */; 945 pProps->uAlign = (1 << pProps->cShift) - 1; 946 pProps->fSwapEndian = pCfg->enmEndianness != PDMAUDIOHOSTENDIANNESS; 947 } 948 949 return rc; 862 * Frees an allocated audio stream configuration. 863 * 864 * @param pCfg Audio stream configuration to free. 865 */ 866 void DrvAudioHlpStreamCfgFree(PPDMAUDIOSTREAMCFG pCfg) 867 { 868 if (pCfg) 869 { 870 RTMemFree(pCfg); 871 pCfg = NULL; 872 } 873 } 874 875 /** 876 * Copies a source stream configuration to a destination stream configuration. 877 * 878 * @returns IPRT status code. 879 * @param pDstCfg Destination stream configuration to copy source to. 880 * @param pSrcCfg Source stream configuration to copy to destination. 881 */ 882 int DrvAudioHlpStreamCfgCopy(PPDMAUDIOSTREAMCFG pDstCfg, const PPDMAUDIOSTREAMCFG pSrcCfg) 883 { 884 AssertPtrReturn(pDstCfg, VERR_INVALID_POINTER); 885 AssertPtrReturn(pSrcCfg, VERR_INVALID_POINTER); 886 887 #ifdef VBOX_STRICT 888 if (!DrvAudioHlpStreamCfgIsValid(pSrcCfg)) 889 { 890 AssertMsgFailed(("Stream config '%s' (%p) is invalid\n", pSrcCfg->szName, pSrcCfg)); 891 return VERR_INVALID_PARAMETER; 892 } 893 #endif 894 895 memcpy(pDstCfg, pSrcCfg, sizeof(PDMAUDIOSTREAMCFG)); 896 897 return VINF_SUCCESS; 898 } 899 900 /** 901 * Duplicates an audio stream configuration. 902 * Must be free'd with DrvAudioHlpStreamCfgFree(). 903 * 904 * @return Duplicates audio stream configuration on success, or NULL on failure. 905 * @param pCfg Audio stream configuration to duplicate. 906 */ 907 PPDMAUDIOSTREAMCFG DrvAudioHlpStreamCfgDup(const PPDMAUDIOSTREAMCFG pCfg) 908 { 909 AssertPtrReturn(pCfg, NULL); 910 911 PPDMAUDIOSTREAMCFG pDst = (PPDMAUDIOSTREAMCFG)RTMemAllocZ(sizeof(PDMAUDIOSTREAMCFG)); 912 if (!pDst) 913 return NULL; 914 915 int rc2 = DrvAudioHlpStreamCfgCopy(pDst, pCfg); 916 if (RT_FAILURE(rc2)) 917 { 918 DrvAudioHlpStreamCfgFree(pDst); 919 pDst = NULL; 920 } 921 922 return pDst; 950 923 } 951 924 … … 959 932 AssertPtrReturnVoid(pCfg); 960 933 961 LogFlowFunc(("uHz=%RU32, cChannels=%RU8, enmFormat=", pCfg->uHz, pCfg->cChannels)); 962 963 switch (pCfg->enmFormat) 964 { 965 case PDMAUDIOFMT_S8: 966 LogFlow(("S8")); 967 break; 968 case PDMAUDIOFMT_U8: 969 LogFlow(("U8")); 970 break; 971 case PDMAUDIOFMT_S16: 972 LogFlow(("S16")); 973 break; 974 case PDMAUDIOFMT_U16: 975 LogFlow(("U16")); 976 break; 977 case PDMAUDIOFMT_S32: 978 LogFlow(("S32")); 979 break; 980 case PDMAUDIOFMT_U32: 981 LogFlow(("U32")); 982 break; 983 default: 984 LogFlow(("invalid(%d)", pCfg->enmFormat)); 985 break; 986 } 987 988 LogFlow((", endianness=")); 989 switch (pCfg->enmEndianness) 990 { 991 case PDMAUDIOENDIANNESS_LITTLE: 992 LogFlow(("little\n")); 993 break; 994 case PDMAUDIOENDIANNESS_BIG: 995 LogFlow(("big\n")); 996 break; 997 default: 998 LogFlow(("invalid\n")); 999 break; 1000 } 934 LogFlowFunc(("uHz=%RU32, cChannels=%RU8, cBits=%RU8%s", 935 pCfg->Props.uHz, pCfg->Props.cChannels, pCfg->Props.cBits, pCfg->Props.fSigned ? "S" : "U")); 1001 936 } 1002 937 … … 1045 980 * 1046 981 * @returns The calculated bit rate. 1047 * @param p Cfg Audio stream configuration to calculate bitrate for.982 * @param pProps PCM properties to calculate bitrate for. 1048 983 * 1049 984 * @remark 1050 985 */ 1051 uint32_t DrvAudioHlpCalcBitrate(PPDMAUDIO STREAMCFG pCfg)1052 { 1053 return DrvAudioHlpCalcBitrate( DrvAudioHlpAudFmtToBits(pCfg->enmFormat), pCfg->uHz, pCfg->cChannels);986 uint32_t DrvAudioHlpCalcBitrate(PPDMAUDIOPCMPROPS pProps) 987 { 988 return DrvAudioHlpCalcBitrate(pProps->cBits, pProps->uHz, pProps->cChannels); 1054 989 } 1055 990 -
trunk/src/VBox/Devices/Audio/DrvHostALSAAudio.cpp
r65566 r65624 76 76 *********************************************************************************************************************************/ 77 77 78 typedef struct ALSAAUDIOSTREAMIN 79 { 80 /** Associated host input stream. 81 * Note: Always must come first! */ 82 PDMAUDIOSTREAM Stream; 83 /** The PCM properties of this stream. */ 84 PDMAUDIOPCMPROPS Props; 78 typedef struct ALSAAUDIOSTREAM 79 { 80 /** The stream's acquired configuration. */ 81 PPDMAUDIOSTREAMCFG pCfg; 82 union 83 { 84 struct 85 { 86 87 } In; 88 struct 89 { 90 /** Minimum samples required for ALSA to play data. */ 91 uint32_t cSamplesMin; 92 } Out; 93 }; 85 94 snd_pcm_t *phPCM; 86 95 void *pvBuf; 87 96 size_t cbBuf; 88 } ALSAAUDIOSTREAMIN, *PALSAAUDIOSTREAMIN; 89 90 typedef struct ALSAAUDIOSTREAMOUT 91 { 92 /** Associated host output stream. 93 * Note: Always must come first! */ 94 PDMAUDIOSTREAM Stream; 95 /** The PCM properties of this stream. */ 96 PDMAUDIOPCMPROPS Props; 97 snd_pcm_t *phPCM; 98 void *pvBuf; 99 size_t cbBuf; 100 /** Minimum samples required for ALSA to play data. */ 101 uint32_t cSamplesMin; 102 } ALSAAUDIOSTREAMOUT, *PALSAAUDIOSTREAMOUT; 97 } ALSAAUDIOSTREAM, *PALSAAUDIOSTREAM; 103 98 104 99 /* latency = period_size * periods / (rate * bytes_per_frame) */ … … 192 187 193 188 194 static snd_pcm_format_t alsaAudioFmtToALSA(PDMAUDIOFMT fmt) 189 static snd_pcm_format_t alsaAudioPropsToALSA(PPDMAUDIOPCMPROPS pProps) 190 { 191 switch (pProps->cBits) 192 { 193 case 8: 194 return pProps->fSigned ? SND_PCM_FORMAT_S8 : SND_PCM_FORMAT_U8; 195 196 case 16: 197 return pProps->fSigned ? SND_PCM_FORMAT_S16_LE : SND_PCM_FORMAT_U16_LE; 198 199 case 32: 200 return pProps->fSigned ? SND_PCM_FORMAT_S32_LE : SND_PCM_FORMAT_U32_LE; 201 202 default: 203 break; 204 } 205 206 AssertMsgFailed(("%RU8 bits not supported\n", pProps->cBits)); 207 return SND_PCM_FORMAT_U8; 208 } 209 210 211 static int alsaALSAToAudioProps(snd_pcm_format_t fmt, PPDMAUDIOPCMPROPS pProps) 195 212 { 196 213 switch (fmt) 197 214 { 198 case PDMAUDIOFMT_S8:199 return SND_PCM_FORMAT_S8;200 201 case PDMAUDIOFMT_U8:202 return SND_PCM_FORMAT_U8;203 204 case PDMAUDIOFMT_S16:205 return SND_PCM_FORMAT_S16_LE;206 207 case PDMAUDIOFMT_U16:208 return SND_PCM_FORMAT_U16_LE;209 210 case PDMAUDIOFMT_S32:211 return SND_PCM_FORMAT_S32_LE;212 213 case PDMAUDIOFMT_U32:214 return SND_PCM_FORMAT_U32_LE;215 216 default:217 break;218 }219 220 AssertMsgFailed(("Format %ld not supported\n", fmt));221 return SND_PCM_FORMAT_U8;222 }223 224 225 static int alsaALSAToAudioFmt(snd_pcm_format_t fmt,226 PDMAUDIOFMT *pFmt, PDMAUDIOENDIANNESS *pEndianness)227 {228 AssertPtrReturn(pFmt, VERR_INVALID_POINTER);229 /* pEndianness is optional. */230 231 switch (fmt)232 {233 215 case SND_PCM_FORMAT_S8: 234 *pFmt = PDMAUDIOFMT_S8; 235 if (pEndianness) 236 *pEndianness = PDMAUDIOENDIANNESS_LITTLE; 216 pProps->cBits = 8; 217 pProps->fSigned = true; 237 218 break; 238 219 239 220 case SND_PCM_FORMAT_U8: 240 *pFmt = PDMAUDIOFMT_U8; 241 if (pEndianness) 242 *pEndianness = PDMAUDIOENDIANNESS_LITTLE; 221 pProps->cBits = 8; 222 pProps->fSigned = false; 243 223 break; 244 224 245 225 case SND_PCM_FORMAT_S16_LE: 246 *pFmt = PDMAUDIOFMT_S16; 247 if (pEndianness) 248 *pEndianness = PDMAUDIOENDIANNESS_LITTLE; 226 pProps->cBits = 16; 227 pProps->fSigned = true; 249 228 break; 250 229 251 230 case SND_PCM_FORMAT_U16_LE: 252 *pFmt = PDMAUDIOFMT_U16; 253 if (pEndianness) 254 *pEndianness = PDMAUDIOENDIANNESS_LITTLE; 231 pProps->cBits = 16; 232 pProps->fSigned = false; 255 233 break; 256 234 257 235 case SND_PCM_FORMAT_S16_BE: 258 *pFmt = PDMAUDIOFMT_S16; 259 if (pEndianness) 260 *pEndianness = PDMAUDIOENDIANNESS_BIG; 236 pProps->cBits = 16; 237 pProps->fSigned = true; 238 #ifdef RT_LITTLE_ENDIAN 239 pProps->fSwapEndian = true; 240 #endif 261 241 break; 262 242 263 243 case SND_PCM_FORMAT_U16_BE: 264 *pFmt = PDMAUDIOFMT_U16; 265 if (pEndianness) 266 *pEndianness = PDMAUDIOENDIANNESS_BIG; 244 pProps->cBits = 16; 245 pProps->fSigned = false; 246 #ifdef RT_LITTLE_ENDIAN 247 pProps->fSwapEndian = true; 248 #endif 267 249 break; 268 250 269 251 case SND_PCM_FORMAT_S32_LE: 270 *pFmt = PDMAUDIOFMT_S32; 271 if (pEndianness) 272 *pEndianness = PDMAUDIOENDIANNESS_LITTLE; 252 pProps->cBits = 32; 253 pProps->fSigned = true; 273 254 break; 274 255 275 256 case SND_PCM_FORMAT_U32_LE: 276 *pFmt = PDMAUDIOFMT_U32; 277 if (pEndianness) 278 *pEndianness = PDMAUDIOENDIANNESS_LITTLE; 257 pProps->cBits = 32; 258 pProps->fSigned = false; 279 259 break; 280 260 281 261 case SND_PCM_FORMAT_S32_BE: 282 *pFmt = PDMAUDIOFMT_S32; 283 if (pEndianness) 284 *pEndianness = PDMAUDIOENDIANNESS_BIG; 262 pProps->cBits = 32; 263 pProps->fSigned = true; 264 #ifdef RT_LITTLE_ENDIAN 265 pProps->fSwapEndian = true; 266 #endif 285 267 break; 286 268 287 269 case SND_PCM_FORMAT_U32_BE: 288 *pFmt = PDMAUDIOFMT_U32; 289 if (pEndianness) 290 *pEndianness = PDMAUDIOENDIANNESS_BIG; 270 pProps->cBits = 32; 271 pProps->fSigned = false; 272 #ifdef RT_LITTLE_ENDIAN 273 pProps->fSwapEndian = true; 274 #endif 291 275 break; 292 276 … … 295 279 return VERR_NOT_SUPPORTED; 296 280 } 281 282 Assert(pProps->cChannels); 283 pProps->cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pProps->cBits, pProps->cChannels); 297 284 298 285 return VINF_SUCCESS; … … 912 899 int rc; 913 900 914 snd_pcm_sframes_t framesAvail; 915 framesAvail = snd_pcm_avail_update(phPCM); 901 snd_pcm_sframes_t framesAvail = snd_pcm_avail_update(phPCM); 916 902 if (framesAvail < 0) 917 903 { … … 996 982 static DECLCALLBACK(int) drvHostALSAAudioInit(PPDMIHOSTAUDIO pInterface) 997 983 { 998 NOREF(pInterface);984 RT_NOREF(pInterface); 999 985 1000 986 LogFlowFuncEnter(); … … 1018 1004 */ 1019 1005 static DECLCALLBACK(int) drvHostALSAAudioStreamCapture(PPDMIHOSTAUDIO pInterface, 1020 PPDMAUDIO STREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)1006 PPDMAUDIOBACKENDSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 1021 1007 { 1022 1008 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 1026 1012 /* pcbRead is optional. */ 1027 1013 1028 PALSAAUDIOSTREAM IN pStreamALSA = (PALSAAUDIOSTREAMIN)pStream;1014 PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream; 1029 1015 1030 1016 snd_pcm_sframes_t cAvail; … … 1036 1022 } 1037 1023 1024 PPDMAUDIOSTREAMCFG pCfg = pStreamALSA->pCfg; 1025 AssertPtr(pCfg); 1026 1038 1027 if (!cAvail) /* No data yet? */ 1039 1028 { … … 1042 1031 { 1043 1032 case SND_PCM_STATE_PREPARED: 1044 cAvail = PDMAUDIO PCMPROPS_B2S(&pStreamALSA->Props, cbBuf);1033 cAvail = PDMAUDIOSTREAMCFG_B2S(pCfg, cbBuf); 1045 1034 break; 1046 1035 … … 1072 1061 * the mixer buffer. 1073 1062 */ 1074 size_t cbToRead = RT_MIN((size_t)PDMAUDIO PCMPROPS_S2B(&pStreamALSA->Props, cAvail), cbBuf);1063 size_t cbToRead = RT_MIN((size_t)PDMAUDIOSTREAMCFG_S2B(pCfg, cAvail), cbBuf); 1075 1064 1076 1065 LogFlowFunc(("cbToRead=%zu, cAvail=%RI32\n", cbToRead, cAvail)); … … 1084 1073 && RT_SUCCESS(rc)) 1085 1074 { 1086 cToRead = RT_MIN(PDMAUDIO PCMPROPS_B2S(&pStreamALSA->Props, cbToRead),1087 PDMAUDIO PCMPROPS_B2S(&pStreamALSA->Props, pStreamALSA->cbBuf));1075 cToRead = RT_MIN(PDMAUDIOSTREAMCFG_B2S(pCfg, cbToRead), 1076 PDMAUDIOSTREAMCFG_B2S(pCfg, pStreamALSA->cbBuf)); 1088 1077 AssertBreakStmt(cToRead, rc = VERR_NO_DATA); 1089 1078 cRead = snd_pcm_readi(pStreamALSA->phPCM, pStreamALSA->pvBuf, cToRead); … … 1135 1124 * capture device for example). 1136 1125 */ 1137 uint32_t cbRead = PDMAUDIO PCMPROPS_S2B(&pStreamALSA->Props, cRead);1126 uint32_t cbRead = PDMAUDIOSTREAMCFG_S2B(pCfg, cRead); 1138 1127 1139 1128 memcpy(pvBuf, pStreamALSA->pvBuf, cbRead); … … 1158 1147 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay} 1159 1148 */ 1160 static DECLCALLBACK(int) drvHostALSAAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream,1149 static DECLCALLBACK(int) drvHostALSAAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 1161 1150 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten) 1162 1151 { … … 1167 1156 /* pcbWritten is optional. */ 1168 1157 1169 PALSAAUDIOSTREAM OUT pStreamALSA = (PALSAAUDIOSTREAMOUT)pStream;1158 PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream; 1170 1159 1171 1160 int rc = VINF_SUCCESS; … … 1175 1164 do 1176 1165 { 1177 snd_pcm_sframes_t c Avail;1178 rc = alsaStreamGetAvail(pStreamALSA->phPCM, &c Avail);1166 snd_pcm_sframes_t csAvail; 1167 rc = alsaStreamGetAvail(pStreamALSA->phPCM, &csAvail); 1179 1168 if (RT_FAILURE(rc)) 1180 1169 { … … 1183 1172 } 1184 1173 1185 size_t cbToRead = RT_MIN((unsigned)PDMAUDIOPCMPROPS_S2B(&pStreamALSA->Props, cAvail), cbBuf); 1186 if (!cbToRead) 1187 break; 1188 1189 memcpy(pStreamALSA->pvBuf, pvBuf, cbToRead); 1190 1191 snd_pcm_sframes_t cWritten = 0; 1174 if (!csAvail) 1175 break; 1176 1177 PPDMAUDIOSTREAMCFG pCfg = pStreamALSA->pCfg; 1178 AssertPtr(pCfg); 1179 1180 size_t cbToWrite = RT_MIN((unsigned)PDMAUDIOSTREAMCFG_S2B(pCfg, csAvail), RT_MIN(pStreamALSA->cbBuf, cbBuf)); 1181 if (!cbToWrite) 1182 break; 1183 1184 memcpy(pStreamALSA->pvBuf, pvBuf, cbToWrite); 1185 1186 snd_pcm_sframes_t csWritten = 0; 1192 1187 1193 1188 /* Don't try infinitely on recoverable errors. */ … … 1195 1190 for (iTry = 0; iTry < ALSA_RECOVERY_TRIES_MAX; iTry++) 1196 1191 { 1197 c Written = snd_pcm_writei(pStreamALSA->phPCM, pStreamALSA->pvBuf,1198 PDMAUDIOPCMPROPS_B2S(&pStreamALSA->Props, cbToRead));1199 if (c Written <= 0)1192 csWritten = snd_pcm_writei(pStreamALSA->phPCM, pStreamALSA->pvBuf, 1193 PDMAUDIOSTREAMCFG_B2S(pCfg, cbToWrite)); 1194 if (csWritten <= 0) 1200 1195 { 1201 switch (c Written)1196 switch (csWritten) 1202 1197 { 1203 1198 case 0: 1204 1199 { 1205 LogFunc(("Failed to write %zu bytes\n", cbTo Read));1200 LogFunc(("Failed to write %zu bytes\n", cbToWrite)); 1206 1201 rc = VERR_ACCESS_DENIED; 1207 1202 break; … … 1233 1228 1234 1229 default: 1235 LogFlowFunc(("Failed to write %RU32 bytes, error unknown\n", cbTo Read));1230 LogFlowFunc(("Failed to write %RU32 bytes, error unknown\n", cbToWrite)); 1236 1231 rc = VERR_GENERAL_FAILURE; /** @todo */ 1237 1232 break; … … 1243 1238 1244 1239 if ( iTry == ALSA_RECOVERY_TRIES_MAX 1245 && c Written <= 0)1240 && csWritten <= 0) 1246 1241 rc = VERR_BROKEN_PIPE; 1247 1242 … … 1249 1244 break; 1250 1245 1251 cbWrittenTotal = cbToRead;1246 cbWrittenTotal += cbToWrite; 1252 1247 1253 1248 } while (0); … … 1264 1259 1265 1260 1266 static int alsaDestroyStreamIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 1267 { 1268 NOREF(pInterface); 1269 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1270 1271 PALSAAUDIOSTREAMIN pThisStream = (PALSAAUDIOSTREAMIN)pStream; 1272 1273 alsaStreamClose(&pThisStream->phPCM); 1274 1275 if (pThisStream->pvBuf) 1276 { 1277 RTMemFree(pThisStream->pvBuf); 1278 pThisStream->pvBuf = NULL; 1261 static int alsaDestroyStreamIn(PALSAAUDIOSTREAM pStreamALSA) 1262 { 1263 alsaStreamClose(&pStreamALSA->phPCM); 1264 1265 if (pStreamALSA->pvBuf) 1266 { 1267 RTMemFree(pStreamALSA->pvBuf); 1268 pStreamALSA->pvBuf = NULL; 1279 1269 } 1280 1270 … … 1283 1273 1284 1274 1285 static int alsaDestroyStreamOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 1286 { 1287 NOREF(pInterface); 1288 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1289 1290 PALSAAUDIOSTREAMOUT pThisStream = (PALSAAUDIOSTREAMOUT)pStream; 1291 1292 alsaStreamClose(&pThisStream->phPCM); 1293 1294 if (pThisStream->pvBuf) 1295 { 1296 RTMemFree(pThisStream->pvBuf); 1297 pThisStream->pvBuf = NULL; 1275 static int alsaDestroyStreamOut(PALSAAUDIOSTREAM pStreamALSA) 1276 { 1277 alsaStreamClose(&pStreamALSA->phPCM); 1278 1279 if (pStreamALSA->pvBuf) 1280 { 1281 RTMemFree(pStreamALSA->pvBuf); 1282 pStreamALSA->pvBuf = NULL; 1298 1283 } 1299 1284 … … 1302 1287 1303 1288 1304 static int alsaCreateStreamOut(PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 1305 { 1306 PALSAAUDIOSTREAMOUT pStreamALSA = (PALSAAUDIOSTREAMOUT)pStream; 1307 1289 static int alsaCreateStreamOut(PALSAAUDIOSTREAM pStreamALSA, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 1290 { 1308 1291 snd_pcm_t *phPCM = NULL; 1309 1292 … … 1313 1296 { 1314 1297 ALSAAUDIOSTREAMCFG req; 1315 req.fmt = alsaAudio FmtToALSA(pCfgReq->enmFormat);1316 req.freq = pCfgReq-> uHz;1317 req.nchannels = pCfgReq-> cChannels;1318 req.period_size = s_ALSAConf.period_size_out; 1319 req.buffer_size = s_ALSAConf.buffer_size_out; 1298 req.fmt = alsaAudioPropsToALSA(&pCfgReq->Props); 1299 req.freq = pCfgReq->Props.uHz; 1300 req.nchannels = pCfgReq->Props.cChannels; 1301 req.period_size = s_ALSAConf.period_size_out; /** @todo Make this configurable. */ 1302 req.buffer_size = s_ALSAConf.buffer_size_out; /** @todo Make this configurable. */ 1320 1303 1321 1304 ALSAAUDIOSTREAMCFG obt; … … 1324 1307 break; 1325 1308 1326 PDMAUDIOFMT enmFormat; 1327 PDMAUDIOENDIANNESS enmEnd; 1328 rc = alsaALSAToAudioFmt(obt.fmt, &enmFormat, &enmEnd); 1309 pCfgAcq->Props.uHz = obt.freq; 1310 pCfgAcq->Props.cChannels = obt.nchannels; 1311 1312 rc = alsaALSAToAudioProps(obt.fmt, &pCfgAcq->Props); 1329 1313 if (RT_FAILURE(rc)) 1330 1314 break; 1331 1315 1332 pCfgAcq->uHz = obt.freq; 1333 pCfgAcq->cChannels = obt.nchannels; 1334 pCfgAcq->enmFormat = enmFormat; 1335 pCfgAcq->enmEndianness = enmEnd; 1336 pCfgAcq->cSampleBufferSize = obt.samples * 4; 1337 1338 rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &pStreamALSA->Props); 1339 if (RT_FAILURE(rc)) 1340 break; 1316 pCfgAcq->cSampleBufferHint = obt.samples * 4; 1341 1317 1342 1318 AssertBreakStmt(obt.samples, rc = VERR_INVALID_PARAMETER); 1343 1319 1344 size_t cbBuf = obt.samples * PDMAUDIO PCMPROPS_S2B(&pStreamALSA->Props, 1);1320 size_t cbBuf = obt.samples * PDMAUDIOSTREAMCFG_S2B(pCfgAcq, 1); 1345 1321 AssertBreakStmt(cbBuf, rc = VERR_INVALID_PARAMETER); 1346 1322 … … 1366 1342 1367 1343 1368 static int alsaCreateStreamIn(P PDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)1344 static int alsaCreateStreamIn(PALSAAUDIOSTREAM pStreamALSA, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 1369 1345 { 1370 1346 int rc; 1371 1347 1372 PALSAAUDIOSTREAMIN pThisStream = (PALSAAUDIOSTREAMIN)pStream;1373 1348 snd_pcm_t *phPCM = NULL; 1374 1349 … … 1376 1351 { 1377 1352 ALSAAUDIOSTREAMCFG req; 1378 req.fmt = alsaAudio FmtToALSA(pCfgReq->enmFormat);1379 req.freq = pCfgReq-> uHz;1380 req.nchannels = pCfgReq-> cChannels;1381 req.period_size = s_ALSAConf.period_size_in; 1382 req.buffer_size = s_ALSAConf.buffer_size_in; 1353 req.fmt = alsaAudioPropsToALSA(&pCfgReq->Props); 1354 req.freq = pCfgReq->Props.uHz; 1355 req.nchannels = pCfgReq->Props.cChannels; 1356 req.period_size = s_ALSAConf.period_size_in; /** @todo Make this configurable. */ 1357 req.buffer_size = s_ALSAConf.buffer_size_in; /** @todo Make this configurable. */ 1383 1358 1384 1359 ALSAAUDIOSTREAMCFG obt; … … 1387 1362 break; 1388 1363 1389 PDMAUDIOFMT enmFormat; 1390 PDMAUDIOENDIANNESS enmEnd; 1391 rc = alsaALSAToAudioFmt(obt.fmt, &enmFormat, &enmEnd); 1364 pCfgAcq->Props.uHz = obt.freq; 1365 pCfgAcq->Props.cChannels = obt.nchannels; 1366 1367 rc = alsaALSAToAudioProps(obt.fmt, &pCfgAcq->Props); 1392 1368 if (RT_FAILURE(rc)) 1393 1369 break; 1394 1370 1395 pCfgAcq->uHz = obt.freq; 1396 pCfgAcq->cChannels = obt.nchannels; 1397 pCfgAcq->enmFormat = enmFormat; 1398 pCfgAcq->enmEndianness = enmEnd; 1399 pCfgAcq->cSampleBufferSize = obt.samples; 1400 1401 PDMAUDIOPCMPROPS Props; 1402 rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &Props); 1403 if (RT_FAILURE(rc)) 1404 break; 1371 pCfgAcq->cSampleBufferHint = obt.samples; 1405 1372 1406 1373 AssertBreakStmt(obt.samples, rc = VERR_INVALID_PARAMETER); 1407 size_t cbBuf = obt.samples * (1 << Props.cShift); /** @todo Get rid of using Props! */ 1374 1375 size_t cbBuf = obt.samples * PDMAUDIOSTREAMCFG_S2B(pCfgAcq, 1); 1408 1376 AssertBreakStmt(cbBuf, rc = VERR_INVALID_PARAMETER); 1409 pThisStream->pvBuf = RTMemAlloc(cbBuf); 1410 if (!pThisStream->pvBuf)1411 {1412 LogRel(("ALSA: Not enough memory for input ADC buffer (%RU32 samples, each %d bytes)\n",1413 obt.samples, 1 << Props.cShift));1377 1378 pStreamALSA->pvBuf = RTMemAlloc(cbBuf); 1379 if (!pStreamALSA->pvBuf) 1380 { 1381 LogRel(("ALSA: Not enough memory for input ADC buffer (%RU32 samples, %zu bytes)\n", obt.samples, cbBuf)); 1414 1382 rc = VERR_NO_MEMORY; 1415 1383 break; 1416 1384 } 1417 1385 1418 p ThisStream->cbBuf = cbBuf;1419 p ThisStream->phPCM = phPCM;1386 pStreamALSA->cbBuf = cbBuf; 1387 pStreamALSA->phPCM = phPCM; 1420 1388 } 1421 1389 while (0); … … 1429 1397 1430 1398 1431 static int alsaControlStreamIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, 1432 PDMAUDIOSTREAMCMD enmStreamCmd) 1433 { 1434 NOREF(pInterface); 1435 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1436 PALSAAUDIOSTREAMIN pThisStream = (PALSAAUDIOSTREAMIN)pStream; 1437 1438 LogFlowFunc(("enmStreamCmd=%ld\n", enmStreamCmd)); 1439 1399 static int alsaControlStreamIn(PALSAAUDIOSTREAM pStreamALSA, PDMAUDIOSTREAMCMD enmStreamCmd) 1400 { 1440 1401 int rc; 1441 1402 switch (enmStreamCmd) … … 1443 1404 case PDMAUDIOSTREAMCMD_ENABLE: 1444 1405 case PDMAUDIOSTREAMCMD_RESUME: 1445 rc = drvHostALSAAudioStreamCtl(p ThisStream->phPCM, false /* fStop */);1406 rc = drvHostALSAAudioStreamCtl(pStreamALSA->phPCM, false /* fStop */); 1446 1407 break; 1447 1408 1448 1409 case PDMAUDIOSTREAMCMD_DISABLE: 1449 1410 case PDMAUDIOSTREAMCMD_PAUSE: 1450 rc = drvHostALSAAudioStreamCtl(p ThisStream->phPCM, true /* fStop */);1411 rc = drvHostALSAAudioStreamCtl(pStreamALSA->phPCM, true /* fStop */); 1451 1412 break; 1452 1413 … … 1461 1422 1462 1423 1463 static int alsaControlStreamOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, 1464 PDMAUDIOSTREAMCMD enmStreamCmd) 1465 { 1466 NOREF(pInterface); 1467 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1468 PALSAAUDIOSTREAMOUT pThisStream = (PALSAAUDIOSTREAMOUT)pStream; 1469 1470 LogFlowFunc(("enmStreamCmd=%ld\n", enmStreamCmd)); 1471 1424 static int alsaControlStreamOut(PALSAAUDIOSTREAM pStreamALSA, PDMAUDIOSTREAMCMD enmStreamCmd) 1425 { 1472 1426 int rc; 1473 1427 switch (enmStreamCmd) … … 1475 1429 case PDMAUDIOSTREAMCMD_ENABLE: 1476 1430 case PDMAUDIOSTREAMCMD_RESUME: 1477 rc = drvHostALSAAudioStreamCtl(p ThisStream->phPCM, false /* fStop */);1431 rc = drvHostALSAAudioStreamCtl(pStreamALSA->phPCM, false /* fStop */); 1478 1432 break; 1479 1433 1480 1434 case PDMAUDIOSTREAMCMD_DISABLE: 1481 1435 case PDMAUDIOSTREAMCMD_PAUSE: 1482 rc = drvHostALSAAudioStreamCtl(p ThisStream->phPCM, true /* fStop */);1436 rc = drvHostALSAAudioStreamCtl(pStreamALSA->phPCM, true /* fStop */); 1483 1437 break; 1484 1438 … … 1498 1452 static DECLCALLBACK(int) drvHostALSAAudioGetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg) 1499 1453 { 1500 NOREF(pInterface);1454 RT_NOREF(pInterface); 1501 1455 AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER); 1502 1456 1503 pBackendCfg->cbStreamIn = sizeof(ALSAAUDIOSTREAM IN);1504 pBackendCfg->cbStreamOut = sizeof(ALSAAUDIOSTREAM OUT);1457 pBackendCfg->cbStreamIn = sizeof(ALSAAUDIOSTREAM); 1458 pBackendCfg->cbStreamOut = sizeof(ALSAAUDIOSTREAM); 1505 1459 1506 1460 /* Enumerate sound devices. */ … … 1571 1525 static DECLCALLBACK(void) drvHostALSAAudioShutdown(PPDMIHOSTAUDIO pInterface) 1572 1526 { 1573 NOREF(pInterface);1527 RT_NOREF(pInterface); 1574 1528 } 1575 1529 … … 1590 1544 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate} 1591 1545 */ 1592 static DECLCALLBACK(int) drvHostALSAAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 1546 static DECLCALLBACK(int) drvHostALSAAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 1547 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 1593 1548 { 1594 1549 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 1597 1552 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER); 1598 1553 1554 PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream; 1555 1599 1556 int rc; 1600 1557 if (pCfgReq->enmDir == PDMAUDIODIR_IN) 1601 rc = alsaCreateStreamIn (pStream, pCfgReq, pCfgAcq);1558 rc = alsaCreateStreamIn (pStreamALSA, pCfgReq, pCfgAcq); 1602 1559 else 1603 rc = alsaCreateStreamOut(pStream, pCfgReq, pCfgAcq); 1604 1605 LogFlowFunc(("%s: rc=%Rrc\n", pStream->szName, rc)); 1560 rc = alsaCreateStreamOut(pStreamALSA, pCfgReq, pCfgAcq); 1561 1562 if (RT_SUCCESS(rc)) 1563 { 1564 pStreamALSA->pCfg = DrvAudioHlpStreamCfgDup(pCfgAcq); 1565 if (!pStreamALSA->pCfg) 1566 rc = VERR_NO_MEMORY; 1567 } 1568 1606 1569 return rc; 1607 1570 } … … 1611 1574 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy} 1612 1575 */ 1613 static DECLCALLBACK(int) drvHostALSAAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)1576 static DECLCALLBACK(int) drvHostALSAAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 1614 1577 { 1615 1578 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 1616 1579 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1617 1580 1581 PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream; 1582 1583 if (!pStreamALSA->pCfg) /* Not (yet) configured? Skip. */ 1584 return VINF_SUCCESS; 1585 1618 1586 int rc; 1619 if (pStream ->enmDir == PDMAUDIODIR_IN)1620 rc = alsaDestroyStreamIn(p Interface, pStream);1587 if (pStreamALSA->pCfg->enmDir == PDMAUDIODIR_IN) 1588 rc = alsaDestroyStreamIn(pStreamALSA); 1621 1589 else 1622 rc = alsaDestroyStreamOut(pInterface, pStream); 1590 rc = alsaDestroyStreamOut(pStreamALSA); 1591 1592 if (RT_SUCCESS(rc)) 1593 { 1594 DrvAudioHlpStreamCfgFree(pStreamALSA->pCfg); 1595 pStreamALSA->pCfg = NULL; 1596 } 1623 1597 1624 1598 return rc; … … 1629 1603 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl} 1630 1604 */ 1631 static DECLCALLBACK(int) drvHostALSAAudioStreamControl(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 1605 static DECLCALLBACK(int) drvHostALSAAudioStreamControl(PPDMIHOSTAUDIO pInterface, 1606 PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 1632 1607 { 1633 1608 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 1634 1609 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1635 1610 1636 Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST); 1611 PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream; 1612 1613 if (!pStreamALSA->pCfg) /* Not (yet) configured? Skip. */ 1614 return VINF_SUCCESS; 1637 1615 1638 1616 int rc; 1639 if (pStream ->enmDir == PDMAUDIODIR_IN)1640 rc = alsaControlStreamIn (pInterface, pStream, enmStreamCmd);1617 if (pStreamALSA->pCfg->enmDir == PDMAUDIODIR_IN) 1618 rc = alsaControlStreamIn (pStreamALSA, enmStreamCmd); 1641 1619 else 1642 rc = alsaControlStreamOut(p Interface, pStream, enmStreamCmd);1620 rc = alsaControlStreamOut(pStreamALSA, enmStreamCmd); 1643 1621 1644 1622 return rc; … … 1649 1627 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus} 1650 1628 */ 1651 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostALSAAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 1652 { 1653 NOREF(pInterface); 1654 NOREF(pStream); 1629 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostALSAAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 1630 { 1631 RT_NOREF(pInterface); 1632 1633 PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream; 1655 1634 1656 1635 PDMAUDIOSTRMSTS strmSts = PDMAUDIOSTRMSTS_FLAG_INITIALIZED 1657 1636 | PDMAUDIOSTRMSTS_FLAG_ENABLED; 1658 1637 1659 snd_pcm_t *phPCM = NULL; 1660 snd_pcm_sframes_t cSamplesMin; 1661 1662 /** @todo Get rid of this once we have a unified ALSA stream. */ 1663 if (pStream->enmDir == PDMAUDIODIR_IN) 1664 { 1665 PALSAAUDIOSTREAMIN pStreamIn = (PALSAAUDIOSTREAMIN)pStream; 1666 phPCM = pStreamIn->phPCM; 1667 cSamplesMin = 0; 1668 } 1669 else if (pStream->enmDir == PDMAUDIODIR_OUT) 1670 { 1671 PALSAAUDIOSTREAMOUT pStreamOut = (PALSAAUDIOSTREAMOUT)pStream; 1672 phPCM = pStreamOut->phPCM; 1673 cSamplesMin = pStreamOut->cSamplesMin; 1674 } 1675 else 1676 AssertFailed(); 1638 snd_pcm_t *phPCM = pStreamALSA->phPCM; 1639 snd_pcm_sframes_t cSamplesMin = 0; 1640 1641 if (pStreamALSA->pCfg->enmDir == PDMAUDIODIR_OUT) 1642 cSamplesMin = pStreamALSA->Out.cSamplesMin; 1677 1643 1678 1644 if (phPCM) … … 1684 1650 Log3Func(("cAvail=%ld \n", cSamplesAvail)); 1685 1651 if (cSamplesAvail >= cSamplesMin) 1686 strmSts |= pStream ->enmDir == PDMAUDIODIR_IN1652 strmSts |= pStreamALSA->pCfg->enmDir == PDMAUDIODIR_IN 1687 1653 ? PDMAUDIOSTRMSTS_FLAG_DATA_READABLE 1688 1654 : PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE; … … 1697 1663 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate} 1698 1664 */ 1699 static DECLCALLBACK(int) drvHostALSAAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)1665 static DECLCALLBACK(int) drvHostALSAAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 1700 1666 { 1701 1667 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); -
trunk/src/VBox/Devices/Audio/DrvHostCoreAudio.cpp
r65567 r65624 209 209 AssertPtrReturn(pCfg, VERR_INVALID_PARAMETER); 210 210 211 pCfg->cChannels = pASBD->mChannelsPerFrame; 212 pCfg->uHz = (uint32_t)pASBD->mSampleRate; 213 pCfg->enmEndianness = PDMAUDIOENDIANNESS_LITTLE; 214 215 int rc = VINF_SUCCESS; 216 217 if (pASBD->mFormatFlags & kAudioFormatFlagIsSignedInteger) 218 { 219 switch (pASBD->mBitsPerChannel) 220 { 221 case 8: pCfg->enmFormat = PDMAUDIOFMT_S8; break; 222 case 16: pCfg->enmFormat = PDMAUDIOFMT_S16; break; 223 case 32: pCfg->enmFormat = PDMAUDIOFMT_S32; break; 224 default: rc = VERR_NOT_SUPPORTED; break; 225 } 226 } 227 else 228 { 229 switch (pASBD->mBitsPerChannel) 230 { 231 case 8: pCfg->enmFormat = PDMAUDIOFMT_U8; break; 232 case 16: pCfg->enmFormat = PDMAUDIOFMT_U16; break; 233 case 32: pCfg->enmFormat = PDMAUDIOFMT_U32; break; 234 default: rc = VERR_NOT_SUPPORTED; break; 235 } 236 } 237 238 AssertRC(rc); 239 return rc; 211 pCfg->Props.cChannels = pASBD->mChannelsPerFrame; 212 pCfg->Props.uHz = (uint32_t)pASBD->mSampleRate; 213 pCfg->Props.cBits = pASBD->mBitsPerChannel; 214 pCfg->Props.fSigned = RT_BOOL(pASBD->mFormatFlags & kAudioFormatFlagIsSignedInteger); 215 pCfg->Props.cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cBits, pCfg->Props.cChannels); 216 217 return VINF_SUCCESS; 240 218 } 241 219 #endif /* !VBOX_WITH_AUDIO_CALLBACKS */ … … 382 360 typedef struct COREAUDIOSTREAM 383 361 { 384 /** PDM audio stream data. 385 * Note: Always must come first in this structure! */ 386 PDMAUDIOSTREAM Stream; 362 /** The stream's acquired configuration. */ 363 PPDMAUDIOSTREAMCFG pCfg; 387 364 /** Stream-specific data, depending on the stream type. */ 388 365 union … … 395 372 /** Pointer to driver instance this stream is bound to. */ 396 373 PDRVHOSTCOREAUDIO pDrv; 397 /** The PCM properties of this stream. */398 PDMAUDIOPCMPROPS Props;399 /** The stream's direction. */400 PDMAUDIODIR enmDir;401 374 /** The stream's thread handle for maintaining the audio queue. */ 402 375 RTTHREAD hThread; … … 1307 1280 PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pvUser; 1308 1281 AssertPtr(pCAStream); 1282 AssertPtr(pCAStream->pCfg); 1309 1283 1310 1284 LogFunc(("Starting pCAStream=%p\n", pCAStream)); 1285 1286 const bool fIn = pCAStream->pCfg->enmDir == PDMAUDIODIR_IN; 1311 1287 1312 1288 /* … … 1314 1290 */ 1315 1291 OSStatus err; 1316 if ( pCAStream->enmDir == PDMAUDIODIR_IN)1292 if (fIn) 1317 1293 err = AudioQueueNewInput(&pCAStream->asbdStream, coreAudioInputQueueCb, pCAStream /* pvData */, 1318 1294 CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0, &pCAStream->audioQueue); … … 1356 1332 * Enter the main loop. 1357 1333 */ 1358 const bool fIn = pCAStream->enmDir == PDMAUDIODIR_IN;1359 1360 1334 while (!ASMAtomicReadBool(&pCAStream->fShutdown)) 1361 1335 { … … 1563 1537 AudioQueueBufferRef pBuf = pCAStream->audioBuffer[i]; 1564 1538 1565 if (pCAStream-> enmDir == PDMAUDIODIR_IN)1539 if (pCAStream->pCfg->enmDir == PDMAUDIODIR_IN) 1566 1540 { 1567 1541 int rc2 = coreAudioInputQueueProcBuffer(pCAStream, pBuf); … … 1571 1545 } 1572 1546 } 1573 else if (pCAStream-> enmDir == PDMAUDIODIR_OUT)1547 else if (pCAStream->pCfg->enmDir == PDMAUDIODIR_OUT) 1574 1548 { 1575 1549 int rc2 = coreAudioOutputQueueProcBuffer(pCAStream, pBuf); … … 1608 1582 return VERR_NOT_AVAILABLE; 1609 1583 1610 pCAStream->enmDir = pCfgReq->enmDir;1611 1612 const bool fIn = pCAStream->enmDir == PDMAUDIODIR_IN;1584 const bool fIn = pCfgReq->enmDir == PDMAUDIODIR_IN; 1585 1586 int rc = VINF_SUCCESS; 1613 1587 1614 1588 /* Create the recording device's out format based on our required audio settings. */ 1615 int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pCAStream->Props); 1616 if (RT_FAILURE(rc)) 1617 { 1618 LogRel(("CoreAudio: Failed to convert requested %s format to native format (%Rrc)\n", fIn ? "input" : "output", rc)); 1619 return rc; 1620 } 1621 1622 coreAudioPCMPropsToASBD(&pCAStream->Props, &pCAStream->asbdStream); 1589 Assert(pCAStream->pCfg == NULL); 1590 pCAStream->pCfg = DrvAudioHlpStreamCfgDup(pCfgReq); 1591 if (!pCAStream->pCfg) 1592 rc = VERR_NO_MEMORY; 1593 1594 coreAudioPCMPropsToASBD(&pCfgReq->Props, &pCAStream->asbdStream); 1595 /** @todo Do some validation? */ 1623 1596 1624 1597 coreAudioPrintASBD( fIn 1625 1598 ? "Capturing queue format" 1626 1599 : "Playback queue format", &pCAStream->asbdStream); 1600 1601 if (RT_FAILURE(rc)) 1602 { 1603 LogRel(("CoreAudio: Failed to convert requested %s format to native format (%Rrc)\n", fIn ? "input" : "output", rc)); 1604 return rc; 1605 } 1627 1606 1628 1607 rc = RTCircBufCreate(&pCAStream->pCircBuf, 8096 << 1 /*pHstStrmIn->Props.cShift*/); /** @todo FIX THIS !!! */ … … 1922 1901 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture} 1923 1902 */ 1924 static DECLCALLBACK(int) drvHostCoreAudioStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream,1903 static DECLCALLBACK(int) drvHostCoreAudioStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 1925 1904 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 1926 1905 { … … 2024 2003 */ 2025 2004 static DECLCALLBACK(int) drvHostCoreAudioStreamPlay(PPDMIHOSTAUDIO pInterface, 2026 PPDMAUDIO STREAM pStream, const void *pvBuf, uint32_t cbBuf,2005 PPDMAUDIOBACKENDSTREAM pStream, const void *pvBuf, uint32_t cbBuf, 2027 2006 uint32_t *pcbWritten) 2028 2007 { … … 2081 2060 Assert(cbWrittenTotal + cbChunk <= cbBuf); 2082 2061 2083 memcpy( (uint8_t *)pvBuf + cbWrittenTotal, pvChunk, cbChunk);2062 memcpy(pvChunk, (uint8_t *)pvBuf + cbWrittenTotal, cbChunk); 2084 2063 2085 2064 /* Release the ring buffer, so the read thread could start reading this data. */ … … 2138 2117 } 2139 2118 2119 if (!pCAStream->pCfg) /* Not (yet) configured? Skip. */ 2120 return VINF_SUCCESS; 2121 2140 2122 int rc = VINF_SUCCESS; 2141 2123 … … 2146 2128 { 2147 2129 LogFunc(("Queue enable\n")); 2148 if (pCAStream-> enmDir == PDMAUDIODIR_IN)2130 if (pCAStream->pCfg->enmDir == PDMAUDIODIR_IN) 2149 2131 { 2150 2132 rc = coreAudioStreamInvalidateQueue(pCAStream); … … 2155 2137 } 2156 2138 } 2157 if (pCAStream->enmDir == PDMAUDIODIR_OUT)2139 else if (pCAStream->pCfg->enmDir == PDMAUDIODIR_OUT) 2158 2140 { 2159 2141 /* Touch the run flag to start the audio queue as soon as … … 2288 2270 static DECLCALLBACK(PDMAUDIOBACKENDSTS) drvHostCoreAudioGetStatus(PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir) 2289 2271 { 2290 RT_NOREF( enmDir);2272 RT_NOREF(pInterface, enmDir); 2291 2273 AssertPtrReturn(pInterface, PDMAUDIOBACKENDSTS_UNKNOWN); 2292 2274 … … 2298 2280 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate} 2299 2281 */ 2300 static DECLCALLBACK(int) drvHostCoreAudioStreamCreate(PPDMIHOSTAUDIO pInterface, 2301 PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)2282 static DECLCALLBACK(int) drvHostCoreAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 2283 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 2302 2284 { 2303 2285 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 2306 2288 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER); 2307 2289 2308 PDRVHOSTCOREAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTCOREAUDIO(pInterface); 2309 2310 Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST); 2311 2312 PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream; 2290 PDRVHOSTCOREAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTCOREAUDIO(pInterface); 2291 PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream; 2313 2292 2314 2293 int rc = RTCritSectInit(&pCAStream->CritSect); … … 2344 2323 if (RT_SUCCESS(rc)) 2345 2324 { 2346 pCfgAcq->cSampleBuffer Size= _4K; /** @todo FIX THIS !!! */2325 pCfgAcq->cSampleBufferHint = _4K; /** @todo FIX THIS !!! */ 2347 2326 } 2348 2327 if (RT_SUCCESS(rc)) … … 2372 2351 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy} 2373 2352 */ 2374 static DECLCALLBACK(int) drvHostCoreAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)2353 static DECLCALLBACK(int) drvHostCoreAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 2375 2354 { 2376 2355 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 2378 2357 2379 2358 PDRVHOSTCOREAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTCOREAUDIO(pInterface); 2380 2381 Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST);2382 2359 2383 2360 PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream; … … 2394 2371 } 2395 2372 2373 if (!pCAStream->pCfg) /* Not (yet) configured? Skip. */ 2374 return VINF_SUCCESS; 2375 2396 2376 int rc = coreAudioStreamControl(pThis, pCAStream, PDMAUDIOSTREAMCMD_DISABLE); 2397 2377 if (RT_SUCCESS(rc)) … … 2420 2400 */ 2421 2401 static DECLCALLBACK(int) drvHostCoreAudioStreamControl(PPDMIHOSTAUDIO pInterface, 2422 PPDMAUDIO STREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)2402 PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 2423 2403 { 2424 2404 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 2425 2405 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 2426 2406 2427 PDRVHOSTCOREAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTCOREAUDIO(pInterface); 2428 2429 Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST); 2430 2407 PDRVHOSTCOREAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTCOREAUDIO(pInterface); 2431 2408 PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream; 2432 2409 … … 2438 2415 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus} 2439 2416 */ 2440 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostCoreAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)2417 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostCoreAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 2441 2418 { 2442 2419 RT_NOREF(pInterface); 2443 2420 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 2444 2421 2445 Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST);2422 PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream; 2446 2423 2447 2424 PDMAUDIOSTRMSTS strmSts = PDMAUDIOSTRMSTS_FLAG_NONE; 2448 2425 2449 PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream; 2426 if (!pCAStream->pCfg) /* Not (yet) configured? Skip. */ 2427 return strmSts; 2450 2428 2451 2429 if (ASMAtomicReadU32(&pCAStream->enmStatus) == COREAUDIOSTATUS_INIT) 2452 2430 strmSts |= PDMAUDIOSTRMSTS_FLAG_INITIALIZED | PDMAUDIOSTRMSTS_FLAG_ENABLED; 2453 2431 2454 if (p Stream->enmDir == PDMAUDIODIR_IN)2432 if (pCAStream->pCfg->enmDir == PDMAUDIODIR_IN) 2455 2433 { 2456 2434 if (strmSts & PDMAUDIOSTRMSTS_FLAG_ENABLED) 2457 2435 strmSts |= PDMAUDIOSTRMSTS_FLAG_DATA_READABLE; 2458 2436 } 2459 else if (p Stream->enmDir == PDMAUDIODIR_OUT)2437 else if (pCAStream->pCfg->enmDir == PDMAUDIODIR_OUT) 2460 2438 { 2461 2439 if (strmSts & PDMAUDIOSTRMSTS_FLAG_ENABLED) … … 2472 2450 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate} 2473 2451 */ 2474 static DECLCALLBACK(int) drvHostCoreAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)2452 static DECLCALLBACK(int) drvHostCoreAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 2475 2453 { 2476 2454 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 2477 2455 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 2456 2457 RT_NOREF(pInterface, pStream); 2478 2458 2479 2459 /* Nothing to do here for Core Audio. */ -
trunk/src/VBox/Devices/Audio/DrvHostDSound.cpp
r65568 r65624 5 5 6 6 /* 7 * Copyright (C) 2006-201 6Oracle Corporation7 * Copyright (C) 2006-2017 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 104 104 } DSOUNDHOSTCFG, *PDSOUNDHOSTCFG; 105 105 106 typedef struct DSOUNDSTREAMOUT 107 { 108 /** Note: Always must come first! */ 109 PDMAUDIOSTREAM Stream; 110 /** The PCM properties of this stream. */ 111 PDMAUDIOPCMPROPS Props; 112 LPDIRECTSOUND8 pDS; /** @todo Move this out of this structure! Not required per-stream (e.g. for multi-channel). */ 113 LPDIRECTSOUNDBUFFER8 pDSB; 114 DWORD offPlayWritePos; 115 DWORD cbPlayBuf; 116 bool fEnabled; 117 bool fRestartPlayback; 118 PDMAUDIOSTREAMCFG streamCfg; 119 } DSOUNDSTREAMOUT, *PDSOUNDSTREAMOUT; 120 121 typedef struct DSOUNDSTREAMIN 122 { 123 /** Associated host input stream. */ 124 PDMAUDIOSTREAM Stream; 125 /** The PCM properties of this stream. */ 126 PDMAUDIOPCMPROPS Props; 127 LPDIRECTSOUNDCAPTURE8 pDSC; 128 LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB; 129 DWORD offCaptureBufRead; 130 DWORD cbCaptureBuf; 131 HRESULT hrLastCapture; 132 PDMAUDIORECSOURCE enmRecSource; 133 bool fEnabled; 134 PDMAUDIOSTREAMCFG streamCfg; 135 } DSOUNDSTREAMIN, *PDSOUNDSTREAMIN; 106 typedef struct DSOUNDSTREAM 107 { 108 /** The stream's acquired configuration. */ 109 PPDMAUDIOSTREAMCFG pCfg; 110 /** Buffer alignment. */ 111 uint8_t uAlign; 112 union 113 { 114 struct 115 { 116 LPDIRECTSOUNDCAPTURE8 pDSC; 117 LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB; 118 DWORD offCaptureBufRead; 119 DWORD cbCaptureBuf; 120 HRESULT hrLastCapture; 121 bool fEnabled; 122 } In; 123 struct 124 { 125 LPDIRECTSOUND8 pDS; /** @todo Move this out of this structure! Not required per-stream (e.g. for multi-channel). */ 126 LPDIRECTSOUNDBUFFER8 pDSB; 127 DWORD offPlayWritePos; 128 DWORD cbPlayBuf; 129 bool fEnabled; 130 bool fRestartPlayback; 131 } Out; 132 }; 133 } DSOUNDSTREAM, *PDSOUNDSTREAM; 136 134 137 135 typedef struct DRVHOSTDSOUND … … 166 164 uint8_t cEvents; 167 165 /** Pointer to the input stream. */ 168 PDSOUNDSTREAM INpDSStrmIn;166 PDSOUNDSTREAM pDSStrmIn; 169 167 /** Pointer to the output stream. */ 170 PDSOUNDSTREAM OUTpDSStrmOut;168 PDSOUNDSTREAM pDSStrmOut; 171 169 #endif 172 170 } DRVHOSTDSOUND, *PDRVHOSTDSOUND; … … 226 224 227 225 pFmt->wFormatTag = WAVE_FORMAT_PCM; 228 pFmt->nChannels = pCfg-> cChannels;229 pFmt->nSamplesPerSec = pCfg-> uHz;230 pFmt->nAvgBytesPerSec = pCfg-> uHz << (pCfg->cChannels == 2 ? 1: 0);231 pFmt->nBlockAlign = 1 << (pCfg-> cChannels == 2 ? 1: 0);226 pFmt->nChannels = pCfg->Props.cChannels; 227 pFmt->nSamplesPerSec = pCfg->Props.uHz; 228 pFmt->nAvgBytesPerSec = pCfg->Props.uHz << (pCfg->Props.cChannels == 2 ? 1: 0); 229 pFmt->nBlockAlign = 1 << (pCfg->Props.cChannels == 2 ? 1 : 0); 232 230 pFmt->cbSize = 0; /* No extra data specified. */ 233 231 234 switch (pCfg->enmFormat) 235 { 236 case PDMAUDIOFMT_S8: 237 case PDMAUDIOFMT_U8: 232 switch (pCfg->Props.cBits) 233 { 234 case 8: 238 235 pFmt->wBitsPerSample = 8; 239 236 break; 240 237 241 case PDMAUDIOFMT_S16: 242 case PDMAUDIOFMT_U16: 238 case 16: 243 239 pFmt->wBitsPerSample = 16; 244 240 pFmt->nAvgBytesPerSec <<= 1; … … 246 242 break; 247 243 248 case PDMAUDIOFMT_S32: 249 case PDMAUDIOFMT_U32: 244 case 32: 250 245 pFmt->wBitsPerSample = 32; 251 246 pFmt->nAvgBytesPerSec <<= 2; … … 254 249 255 250 default: 256 AssertMsgFailed(("Wave format %d not supported\n", pCfg->enmFormat));251 AssertMsgFailed(("Wave format for %RU8 bits not supported\n", pCfg->Props.cBits)); 257 252 return VERR_NOT_SUPPORTED; 258 253 } … … 262 257 263 258 264 static int dsoundGetPosOut(PDRVHOSTDSOUND pThis,265 PDSOUNDSTREAMOUT pDSoundStream,DWORD *pdwBuffer, DWORD *pdwFree, DWORD *pdwPlayPos)259 static int dsoundGetPosOut(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, 260 DWORD *pdwBuffer, DWORD *pdwFree, DWORD *pdwPlayPos) 266 261 { 267 262 AssertPtr(pThis); 268 AssertPtrReturn(p DSoundStream, VERR_INVALID_POINTER);263 AssertPtrReturn(pStreamDS, VERR_INVALID_POINTER); 269 264 AssertPtrNull(pdwBuffer); 270 265 AssertPtrNull(pdwFree); 271 266 AssertPtrNull(pdwPlayPos); 272 267 273 LPDIRECTSOUNDBUFFER8 pDSB = p DSoundStream->pDSB;268 LPDIRECTSOUNDBUFFER8 pDSB = pStreamDS->Out.pDSB; 274 269 if (!pDSB) 275 270 return VERR_INVALID_POINTER; … … 283 278 if (SUCCEEDED(hr)) 284 279 { 285 DWORD const cbBuffer = p DSoundStream->cbPlayBuf;280 DWORD const cbBuffer = pStreamDS->Out.cbPlayBuf; 286 281 if (pdwBuffer) 287 282 *pdwBuffer = cbBuffer; 288 283 if (pdwFree) 289 *pdwFree = cbBuffer - dsoundRingDistance(p DSoundStream->offPlayWritePos, cbPlayPos, cbBuffer);284 *pdwFree = cbBuffer - dsoundRingDistance(pStreamDS->Out.offPlayWritePos, cbPlayPos, cbBuffer); 290 285 if (pdwPlayPos) 291 286 *pdwPlayPos = cbPlayPos; … … 385 380 386 381 387 static HRESULT directSoundPlayLock(PDRVHOSTDSOUND pThis, 388 LPDIRECTSOUNDBUFFER8 pDSB, PPDMAUDIOPCMPROPS pProps, 382 static HRESULT directSoundPlayLock(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, 389 383 DWORD dwOffset, DWORD dwBytes, 390 384 PVOID *ppv1, PVOID *ppv2, … … 398 392 *ppv1 = *ppv2 = NULL; 399 393 *pcb1 = *pcb2 = 0; 400 hr = IDirectSoundBuffer8_Lock(p DSB, dwOffset, dwBytes, ppv1, pcb1, ppv2, pcb2, dwFlags);394 hr = IDirectSoundBuffer8_Lock(pStreamDS->Out.pDSB, dwOffset, dwBytes, ppv1, pcb1, ppv2, pcb2, dwFlags); 401 395 if (SUCCEEDED(hr)) 402 396 { 403 if ( (!*ppv1 || !(*pcb1 & p Props->uAlign))404 && (!*ppv2 || !(*pcb2 & p Props->uAlign)) )397 if ( (!*ppv1 || !(*pcb1 & pStreamDS->uAlign)) 398 && (!*ppv2 || !(*pcb2 & pStreamDS->uAlign)) ) 405 399 return S_OK; 406 400 DSLOGREL(("DSound: Locking playback buffer returned misaligned buffer: cb1=%#RX32, cb2=%#RX32 (alignment: %#RX32)\n", 407 *pcb1, *pcb2, p Props->uAlign));408 directSoundPlayUnlock(pThis, p DSB, *ppv1, *ppv2, *pcb1, *pcb2);401 *pcb1, *pcb2, pStreamDS->uAlign)); 402 directSoundPlayUnlock(pThis, pStreamDS->uAlign, *ppv1, *ppv2, *pcb1, *pcb2); 409 403 return E_FAIL; 410 404 } … … 414 408 415 409 LogFlowFunc(("Locking failed due to lost buffer, restoring ...\n")); 416 directSoundPlayRestore(pThis, p DSB);410 directSoundPlayRestore(pThis, pStreamDS->Out.pDSB); 417 411 } 418 412 … … 422 416 423 417 424 static HRESULT directSoundCaptureLock( LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB, PPDMAUDIOPCMPROPS pProps,418 static HRESULT directSoundCaptureLock(PDSOUNDSTREAM pStreamDS, 425 419 DWORD dwOffset, DWORD dwBytes, 426 420 PVOID *ppv1, PVOID *ppv2, … … 433 427 DWORD cb2 = 0; 434 428 435 HRESULT hr = IDirectSoundCaptureBuffer8_Lock(p DSCB, dwOffset, dwBytes,429 HRESULT hr = IDirectSoundCaptureBuffer8_Lock(pStreamDS->In.pDSCB, dwOffset, dwBytes, 436 430 &pv1, &cb1, &pv2, &cb2, dwFlags); 437 431 if (FAILED(hr)) … … 441 435 } 442 436 443 if ( (pv1 && (cb1 & p Props->uAlign))444 || (pv2 && (cb2 & p Props->uAlign)))437 if ( (pv1 && (cb1 & pStreamDS->uAlign)) 438 || (pv2 && (cb2 & pStreamDS->uAlign))) 445 439 { 446 440 DSLOGREL(("DSound: Locking capture buffer returned misaligned buffer: cb1=%RI32, cb2=%RI32 (alignment: %RU32)\n", 447 cb1, cb2, p Props->uAlign));448 directSoundCaptureUnlock(p DSCB, pv1, pv2, cb1, cb2);441 cb1, cb2, pStreamDS->uAlign)); 442 directSoundCaptureUnlock(pStreamDS->In.pDSCB, pv1, pv2, cb1, cb2); 449 443 return E_FAIL; 450 444 } … … 463 457 */ 464 458 465 static void directSoundPlayInterfaceRelease(PDSOUNDSTREAM OUT pDSoundStream)466 { 467 if (p DSoundStream->pDS)468 { 469 IDirectSound8_Release(p DSoundStream->pDS);470 p DSoundStream->pDS = NULL;471 } 472 } 473 474 475 static HRESULT directSoundPlayInterfaceCreate(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM OUT pDSoundStream)476 { 477 if (p DSoundStream->pDS != NULL)459 static void directSoundPlayInterfaceRelease(PDSOUNDSTREAM pStreamDS) 460 { 461 if (pStreamDS->Out.pDS) 462 { 463 IDirectSound8_Release(pStreamDS->Out.pDS); 464 pStreamDS->Out.pDS = NULL; 465 } 466 } 467 468 469 static HRESULT directSoundPlayInterfaceCreate(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS) 470 { 471 if (pStreamDS->Out.pDS != NULL) 478 472 { 479 473 DSLOG(("DSound: DirectSound instance already exists\n")); … … 482 476 483 477 HRESULT hr = CoCreateInstance(CLSID_DirectSound8, NULL, CLSCTX_ALL, 484 IID_IDirectSound8, (void **)&p DSoundStream->pDS);478 IID_IDirectSound8, (void **)&pStreamDS->Out.pDS); 485 479 if (FAILED(hr)) 486 480 { … … 489 483 else 490 484 { 491 hr = IDirectSound8_Initialize(p DSoundStream->pDS, pThis->cfg.pGuidPlay);485 hr = IDirectSound8_Initialize(pStreamDS->Out.pDS, pThis->cfg.pGuidPlay); 492 486 if (SUCCEEDED(hr)) 493 487 { 494 488 HWND hWnd = GetDesktopWindow(); 495 hr = IDirectSound8_SetCooperativeLevel(p DSoundStream->pDS, hWnd, DSSCL_PRIORITY);489 hr = IDirectSound8_SetCooperativeLevel(pStreamDS->Out.pDS, hWnd, DSSCL_PRIORITY); 496 490 if (FAILED(hr)) 497 491 DSLOGREL(("DSound: Setting cooperative level for window %p failed with %Rhrc\n", hWnd, hr)); … … 505 499 DSLOGREL(("DSound: DirectSound playback initialization failed with %Rhrc\n", hr)); 506 500 507 directSoundPlayInterfaceRelease(p DSoundStream);501 directSoundPlayInterfaceRelease(pStreamDS); 508 502 } 509 503 } … … 513 507 514 508 515 static HRESULT directSoundPlayClose(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM OUT pDSoundStream)509 static HRESULT directSoundPlayClose(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS) 516 510 { 517 511 AssertPtrReturn(pThis, E_POINTER); 518 AssertPtrReturn(p DSoundStream, E_POINTER);519 520 DSLOG(("DSound: Closing playback stream %p, buffer %p\n", p DSoundStream, pDSoundStream->pDSB));512 AssertPtrReturn(pStreamDS, E_POINTER); 513 514 DSLOG(("DSound: Closing playback stream %p, buffer %p\n", pStreamDS, pStreamDS->Out.pDSB)); 521 515 522 516 HRESULT hr = S_OK; 523 517 524 if (p DSoundStream->pDSB)525 { 526 hr = IDirectSoundBuffer8_Stop(p DSoundStream->pDSB);518 if (pStreamDS->Out.pDSB) 519 { 520 hr = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB); 527 521 if (SUCCEEDED(hr)) 528 522 { … … 536 530 pThis->cEvents--; 537 531 538 pThis->pDSStr eam= NULL;532 pThis->pDSStrmOut = NULL; 539 533 } 540 534 … … 542 536 AssertRC(rc2); 543 537 #endif 544 IDirectSoundBuffer8_Release(p DSoundStream->pDSB);545 p DSoundStream->pDSB = NULL;538 IDirectSoundBuffer8_Release(pStreamDS->Out.pDSB); 539 pStreamDS->Out.pDSB = NULL; 546 540 } 547 541 else 548 DSLOGREL(("DSound: Stop playback stream %p when closing %Rhrc\n", p DSoundStream, hr));542 DSLOGREL(("DSound: Stop playback stream %p when closing %Rhrc\n", pStreamDS, hr)); 549 543 } 550 544 551 545 if (SUCCEEDED(hr)) 552 directSoundPlayInterfaceRelease(p DSoundStream);546 directSoundPlayInterfaceRelease(pStreamDS); 553 547 554 548 return hr; … … 556 550 557 551 558 static HRESULT directSoundPlayOpen(PDRVHOSTDSOUND pThis, PDSOUNDSTREAMOUT pDSoundStream) 559 { 560 AssertPtrReturn(pThis, E_POINTER); 561 AssertPtrReturn(pDSoundStream, E_POINTER); 562 563 DSLOG(("DSound: pDSoundStream=%p, cbBufferOut=%RU32, uHz=%RU32, cChannels=%RU8, cBits=%RU8, fSigned=%RTbool\n", 564 pDSoundStream, 565 pThis->cfg.cbBufferOut, 566 pDSoundStream->Props.uHz, 567 pDSoundStream->Props.cChannels, 568 pDSoundStream->Props.cBits, 569 pDSoundStream->Props.fSigned)); 570 571 if (pDSoundStream->pDSB != NULL) 552 static HRESULT directSoundPlayOpen(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, 553 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 554 { 555 AssertPtrReturn(pThis, E_POINTER); 556 AssertPtrReturn(pStreamDS, E_POINTER); 557 AssertPtrReturn(pCfgReq, E_POINTER); 558 AssertPtrReturn(pCfgAcq, E_POINTER); 559 560 DSLOG(("DSound: pStreamDS=%p, cbBufferOut=%RU32, uHz=%RU32, cChannels=%RU8, cBits=%RU8, fSigned=%RTbool\n", 561 pStreamDS, pThis->cfg.cbBufferOut, 562 pCfgReq->Props.uHz, 563 pCfgReq->Props.cChannels, 564 pCfgReq->Props.cBits, 565 pCfgReq->Props.fSigned)); 566 567 if (pStreamDS->Out.pDSB != NULL) 572 568 { 573 569 /* Should not happen but be forgiving. */ 574 570 DSLOGREL(("DSound: Playback buffer already exists\n")); 575 directSoundPlayClose(pThis, p DSoundStream);571 directSoundPlayClose(pThis, pStreamDS); 576 572 } 577 573 578 574 WAVEFORMATEX wfx; 579 int rc = dsoundWaveFmtFromCfg( &pDSoundStream->streamCfg, &wfx);575 int rc = dsoundWaveFmtFromCfg(pCfgReq, &wfx); 580 576 if (RT_FAILURE(rc)) 581 577 return E_INVALIDARG; 582 578 583 HRESULT hr = directSoundPlayInterfaceCreate(pThis, p DSoundStream);579 HRESULT hr = directSoundPlayInterfaceCreate(pThis, pStreamDS); 584 580 if (FAILED(hr)) 585 581 return hr; … … 611 607 bd.dwBufferBytes = pThis->cfg.cbBufferOut; 612 608 613 hr = IDirectSound8_CreateSoundBuffer(p DSoundStream->pDS, &bd, &pDSB, NULL);609 hr = IDirectSound8_CreateSoundBuffer(pStreamDS->Out.pDS, &bd, &pDSB, NULL); 614 610 if (FAILED(hr)) 615 611 { … … 619 615 620 616 /* "Upgrade" to IDirectSoundBuffer8 interface. */ 621 hr = IDirectSoundBuffer_QueryInterface(pDSB, IID_IDirectSoundBuffer8, (PVOID *)&p DSoundStream->pDSB);617 hr = IDirectSoundBuffer_QueryInterface(pDSB, IID_IDirectSoundBuffer8, (PVOID *)&pStreamDS->Out.pDSB); 622 618 IDirectSoundBuffer_Release(pDSB); 623 619 if (FAILED(hr)) … … 630 626 * Query the actual parameters. 631 627 */ 632 hr = IDirectSoundBuffer8_GetFormat(p DSoundStream->pDSB, &wfx, sizeof(wfx), NULL);628 hr = IDirectSoundBuffer8_GetFormat(pStreamDS->Out.pDSB, &wfx, sizeof(wfx), NULL); 633 629 if (FAILED(hr)) 634 630 { … … 640 636 RT_ZERO(bc); 641 637 bc.dwSize = sizeof(bc); 642 hr = IDirectSoundBuffer8_GetCaps(p DSoundStream->pDSB, &bc);638 hr = IDirectSoundBuffer8_GetCaps(pStreamDS->Out.pDSB, &bc); 643 639 if (FAILED(hr)) 644 640 { … … 667 663 wfx.cbSize)); 668 664 669 if (bc.dwBufferBytes & p DSoundStream->Props.uAlign)665 if (bc.dwBufferBytes & pStreamDS->uAlign) 670 666 DSLOGREL(("DSound: Playback capabilities returned misaligned buffer: size %RU32, alignment %RU32\n", 671 bc.dwBufferBytes, p DSoundStream->Props.uAlign + 1));667 bc.dwBufferBytes, pStreamDS->uAlign + 1)); 672 668 673 669 if (bc.dwBufferBytes != pThis->cfg.cbBufferOut) … … 680 676 * playback buffer position. 681 677 */ 682 p DSoundStream->cbPlayBuf = bc.dwBufferBytes;683 DSLOG(("DSound: cMaxSamplesInBuffer=%RU32\n", p DSoundStream->cbPlayBuf));678 pStreamDS->Out.cbPlayBuf = bc.dwBufferBytes; 679 DSLOG(("DSound: cMaxSamplesInBuffer=%RU32\n", pStreamDS->Out.cbPlayBuf)); 684 680 685 681 #ifdef VBOX_WITH_AUDIO_DEVICE_CALLBACKS … … 698 694 699 695 LPDIRECTSOUNDNOTIFY8 pNotify; 700 hr = IDirectSoundNotify_QueryInterface(p DSoundStream->pDSB, IID_IDirectSoundNotify8, (PVOID *)&pNotify);696 hr = IDirectSoundNotify_QueryInterface(pStreamDS->Out.pDSB, IID_IDirectSoundNotify8, (PVOID *)&pNotify); 701 697 if (SUCCEEDED(hr)) 702 698 { … … 718 714 break; 719 715 720 pThis->pDSStr eamOut = pDSoundStream;716 pThis->pDSStrmOut = pStreamDS; 721 717 722 718 Assert(pThis->cEvents < VBOX_DSOUND_MAX_EVENTS); … … 727 723 728 724 /* Trigger the just installed output notification. */ 729 hr = IDirectSoundBuffer8_Play(pDSoundStream->pDSB, 0, 0, 0); 725 hr = IDirectSoundBuffer8_Play(pStreamDS->Out.pDSB, 0, 0, 0); 726 if (FAILED(hr)) 727 break; 730 728 731 729 #endif /* VBOX_WITH_AUDIO_DEVICE_CALLBACKS */ 732 730 731 pCfgAcq->cSampleBufferHint = PDMAUDIOSTREAMCFG_B2S(pCfgAcq, pThis->cfg.cbBufferOut); 732 733 733 } while (0); 734 734 735 735 if (FAILED(hr)) 736 directSoundPlayClose(pThis, p DSoundStream);736 directSoundPlayClose(pThis, pStreamDS); 737 737 738 738 return hr; … … 740 740 741 741 742 static void dsoundPlayClearSamples(PDRVHOSTDSOUND pThis, PDSOUNDSTREAMOUT pDSoundStream) 743 { 744 AssertPtrReturnVoid(pDSoundStream); 742 static void dsoundPlayClearSamples(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS) 743 { 744 AssertPtrReturnVoid(pStreamDS); 745 746 AssertPtr(pStreamDS->pCfg); 747 PPDMAUDIOPCMPROPS pProps = &pStreamDS->pCfg->Props; 745 748 746 749 PVOID pv1, pv2; 747 750 DWORD cb1, cb2; 748 HRESULT hr = directSoundPlayLock(pThis, p DSoundStream->pDSB, &pDSoundStream->Props,749 0 /* dwOffset */, p DSoundStream->cbPlayBuf,751 HRESULT hr = directSoundPlayLock(pThis, pStreamDS, 752 0 /* dwOffset */, pStreamDS->Out.cbPlayBuf, 750 753 &pv1, &pv2, &cb1, &cb2, DSBLOCK_ENTIREBUFFER); 751 754 if (SUCCEEDED(hr)) 752 755 { 753 DWORD len1 = PDMAUDIOPCMPROPS_B2S( &pDSoundStream->Props, cb1);754 DWORD len2 = PDMAUDIOPCMPROPS_B2S( &pDSoundStream->Props, cb2);756 DWORD len1 = PDMAUDIOPCMPROPS_B2S(pProps, cb1); 757 DWORD len2 = PDMAUDIOPCMPROPS_B2S(pProps, cb2); 755 758 756 759 if (pv1 && len1) 757 DrvAudioHlpClearBuf( &pDSoundStream->Props, pv1, cb1, len1);760 DrvAudioHlpClearBuf(pProps, pv1, cb1, len1); 758 761 759 762 if (pv2 && len2) 760 DrvAudioHlpClearBuf( &pDSoundStream->Props, pv2, cb2, len2);761 762 directSoundPlayUnlock(pThis, p DSoundStream->pDSB, pv1, pv2, cb1, cb2);763 DrvAudioHlpClearBuf(pProps, pv2, cb2, len2); 764 765 directSoundPlayUnlock(pThis, pStreamDS->Out.pDSB, pv1, pv2, cb1, cb2); 763 766 } 764 767 } … … 799 802 800 803 801 static HRESULT directSoundPlayStop(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM OUT pDSoundStream)802 { 803 AssertPtrReturn(pThis, 804 AssertPtrReturn(p DSoundStream, E_POINTER);804 static HRESULT directSoundPlayStop(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS) 805 { 806 AssertPtrReturn(pThis, E_POINTER); 807 AssertPtrReturn(pStreamDS, E_POINTER); 805 808 806 809 HRESULT hr; 807 810 808 if (p DSoundStream->pDSB != NULL)811 if (pStreamDS->Out.pDSB != NULL) 809 812 { 810 813 DSLOG(("DSound: Stopping playback\n")); 811 814 812 HRESULT hr2 = IDirectSoundBuffer8_Stop(p DSoundStream->pDSB);815 HRESULT hr2 = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB); 813 816 if (FAILED(hr2)) 814 817 { 815 hr2 = directSoundPlayRestore(pThis, p DSoundStream->pDSB);818 hr2 = directSoundPlayRestore(pThis, pStreamDS->Out.pDSB); 816 819 if (FAILED(hr2)) 817 hr2 = IDirectSoundBuffer8_Stop(p DSoundStream->pDSB);820 hr2 = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB); 818 821 } 819 822 … … 828 831 if (SUCCEEDED(hr)) 829 832 { 830 dsoundPlayClearSamples(pThis, p DSoundStream);831 p DSoundStream->fEnabled = false;833 dsoundPlayClearSamples(pThis, pStreamDS); 834 pStreamDS->Out.fEnabled = false; 832 835 } 833 836 else … … 838 841 839 842 840 static HRESULT directSoundPlayStart(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM OUT pDSoundStream)843 static HRESULT directSoundPlayStart(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS) 841 844 { 842 845 AssertPtrReturn(pThis, E_POINTER); 843 AssertPtrReturn(p DSoundStream, E_POINTER);846 AssertPtrReturn(pStreamDS, E_POINTER); 844 847 845 848 HRESULT hr; 846 if (p DSoundStream->pDSB != NULL)849 if (pStreamDS->Out.pDSB != NULL) 847 850 { 848 851 DWORD dwStatus; 849 hr = directSoundPlayGetStatus(pThis, p DSoundStream->pDSB, &dwStatus);852 hr = directSoundPlayGetStatus(pThis, pStreamDS->Out.pDSB, &dwStatus); 850 853 if (SUCCEEDED(hr)) 851 854 { … … 856 859 else 857 860 { 858 dsoundPlayClearSamples(pThis, p DSoundStream);859 860 p DSoundStream->fRestartPlayback = true;861 p DSoundStream->fEnabled = true;861 dsoundPlayClearSamples(pThis, pStreamDS); 862 863 pStreamDS->Out.fRestartPlayback = true; 864 pStreamDS->Out.fEnabled = true; 862 865 863 866 DSLOG(("DSound: Playback started\n")); … … 883 886 */ 884 887 885 static LPCGUID dsoundCaptureSelectDevice(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM IN pDSoundStream)886 { 887 AssertPtrReturn(pThis, NULL);888 AssertPtrReturn(p DSoundStream, NULL);888 static LPCGUID dsoundCaptureSelectDevice(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS) 889 { 890 AssertPtrReturn(pThis, NULL); 891 AssertPtrReturn(pStreamDS, NULL); 889 892 890 893 int rc = VINF_SUCCESS; … … 895 898 PDSOUNDDEV pDev = NULL; 896 899 897 switch (p DSoundStream->enmRecSource)900 switch (pStreamDS->pCfg->DestSource.Source) 898 901 { 899 902 case PDMAUDIORECSOURCE_LINE: … … 909 912 RTListForEach(&pThis->lstDevInput, pDev, DSOUNDDEV, Node) 910 913 { 911 if (RTStrIStr(pDev->pszName, "Mic")) /** @todo what is with non en_us windows versions? */914 if (RTStrIStr(pDev->pszName, "Mic")) /** @todo What is with non en_us windows versions? */ 912 915 break; 913 916 } … … 928 931 { 929 932 DSLOG(("DSound: Guest source '%s' is using host recording device '%s'\n", 930 DrvAudioHlpRecSrcToStr(p DSoundStream->enmRecSource), pDev->pszName));933 DrvAudioHlpRecSrcToStr(pStreamDS->pCfg->DestSource.Source), pDev->pszName)); 931 934 932 935 pGUID = &pDev->Guid; … … 944 947 /* This always has to be in the release log. */ 945 948 LogRel(("DSound: Guest source '%s' is using host recording device with GUID '%s'\n", 946 DrvAudioHlpRecSrcToStr(p DSoundStream->enmRecSource), pszGUID ? pszGUID: "{?}"));949 DrvAudioHlpRecSrcToStr(pStreamDS->pCfg->DestSource.Source), pszGUID ? pszGUID: "{?}")); 947 950 948 951 if (pszGUID) … … 956 959 957 960 958 static void directSoundCaptureInterfaceRelease(PDSOUNDSTREAM IN pDSoundStream)959 { 960 if (p DSoundStream->pDSC)961 static void directSoundCaptureInterfaceRelease(PDSOUNDSTREAM pStreamDS) 962 { 963 if (pStreamDS->In.pDSC) 961 964 { 962 965 LogFlowFuncEnter(); 963 IDirectSoundCapture_Release(p DSoundStream->pDSC);964 p DSoundStream->pDSC = NULL;965 } 966 } 967 968 969 static HRESULT directSoundCaptureInterfaceCreate(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM IN pDSoundStream)970 { 971 if (p DSoundStream->pDSC != NULL)966 IDirectSoundCapture_Release(pStreamDS->In.pDSC); 967 pStreamDS->In.pDSC = NULL; 968 } 969 } 970 971 972 static HRESULT directSoundCaptureInterfaceCreate(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS) 973 { 974 if (pStreamDS->In.pDSC != NULL) 972 975 { 973 976 DSLOG(("DSound: DirectSoundCapture instance already exists\n")); … … 976 979 977 980 HRESULT hr = CoCreateInstance(CLSID_DirectSoundCapture8, NULL, CLSCTX_ALL, 978 IID_IDirectSoundCapture8, (void **)&p DSoundStream->pDSC);981 IID_IDirectSoundCapture8, (void **)&pStreamDS->In.pDSC); 979 982 if (FAILED(hr)) 980 983 { … … 983 986 else 984 987 { 985 LPCGUID pGUID = dsoundCaptureSelectDevice(pThis, p DSoundStream);986 hr = IDirectSoundCapture_Initialize(p DSoundStream->pDSC, pGUID);988 LPCGUID pGUID = dsoundCaptureSelectDevice(pThis, pStreamDS); 989 hr = IDirectSoundCapture_Initialize(pStreamDS->In.pDSC, pGUID); 987 990 if (FAILED(hr)) 988 991 { … … 992 995 DSLOGREL(("DSound: Initializing capturing device failed with %Rhrc\n", hr)); 993 996 994 directSoundCaptureInterfaceRelease(p DSoundStream);997 directSoundCaptureInterfaceRelease(pStreamDS); 995 998 } 996 999 } … … 1001 1004 1002 1005 1003 static HRESULT directSoundCaptureClose(PDSOUNDSTREAM IN pDSoundStream)1004 { 1005 AssertPtrReturn(p DSoundStream, E_POINTER);1006 1007 DSLOG(("DSound: p DSoundStream=%p, pDSCB=%p\n", pDSoundStream, pDSoundStream->pDSCB));1006 static HRESULT directSoundCaptureClose(PDSOUNDSTREAM pStreamDS) 1007 { 1008 AssertPtrReturn(pStreamDS, E_POINTER); 1009 1010 DSLOG(("DSound: pStreamDS=%p, pDSCB=%p\n", pStreamDS, pStreamDS->In.pDSCB)); 1008 1011 1009 1012 HRESULT hr = S_OK; 1010 1013 1011 if (p DSoundStream->pDSCB)1012 { 1013 hr = IDirectSoundCaptureBuffer_Stop(p DSoundStream->pDSCB);1014 if (pStreamDS->In.pDSCB) 1015 { 1016 hr = IDirectSoundCaptureBuffer_Stop(pStreamDS->In.pDSCB); 1014 1017 if (SUCCEEDED(hr)) 1015 1018 { 1016 IDirectSoundCaptureBuffer8_Release(p DSoundStream->pDSCB);1017 p DSoundStream->pDSCB = NULL;1019 IDirectSoundCaptureBuffer8_Release(pStreamDS->In.pDSCB); 1020 pStreamDS->In.pDSCB = NULL; 1018 1021 } 1019 1022 else … … 1022 1025 1023 1026 if (SUCCEEDED(hr)) 1024 directSoundCaptureInterfaceRelease(p DSoundStream);1027 directSoundCaptureInterfaceRelease(pStreamDS); 1025 1028 1026 1029 LogFlowFunc(("Returning %Rhrc\n", hr)); … … 1029 1032 1030 1033 1031 static HRESULT directSoundCaptureOpen(PDRVHOSTDSOUND pThis, PDSOUNDSTREAMIN pDSoundStream) 1032 { 1033 AssertPtrReturn(pThis, E_POINTER); 1034 AssertPtrReturn(pDSoundStream, E_POINTER); 1035 1036 DSLOG(("DSound: pDSoundStream=%p, cbBufferIn=%RU32, uHz=%RU32, cChannels=%RU8, cBits=%RU8, fSigned=%RTbool\n", 1037 pDSoundStream, 1034 static HRESULT directSoundCaptureOpen(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, 1035 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 1036 { 1037 AssertPtrReturn(pThis, E_POINTER); 1038 AssertPtrReturn(pStreamDS, E_POINTER); 1039 AssertPtrReturn(pCfgReq, E_POINTER); 1040 AssertPtrReturn(pCfgAcq, E_POINTER); 1041 1042 DSLOG(("DSound: pStreamDS=%p, cbBufferIn=%RU32, uHz=%RU32, cChannels=%RU8, cBits=%RU8, fSigned=%RTbool\n", 1043 pStreamDS, 1038 1044 pThis->cfg.cbBufferIn, 1039 p DSoundStream->Props.uHz,1040 p DSoundStream->Props.cChannels,1041 p DSoundStream->Props.cBits,1042 p DSoundStream->Props.fSigned));1043 1044 if (p DSoundStream->pDSCB != NULL)1045 pCfgReq->Props.uHz, 1046 pCfgReq->Props.cChannels, 1047 pCfgReq->Props.cBits, 1048 pCfgReq->Props.fSigned)); 1049 1050 if (pStreamDS->In.pDSCB != NULL) 1045 1051 { 1046 1052 /* Should not happen but be forgiving. */ 1047 1053 DSLOGREL(("DSound: DirectSoundCaptureBuffer already exists\n")); 1048 directSoundCaptureClose(p DSoundStream);1054 directSoundCaptureClose(pStreamDS); 1049 1055 } 1050 1056 1051 1057 WAVEFORMATEX wfx; 1052 int rc = dsoundWaveFmtFromCfg( &pDSoundStream->streamCfg, &wfx);1058 int rc = dsoundWaveFmtFromCfg(pCfgReq, &wfx); 1053 1059 if (RT_FAILURE(rc)) 1054 1060 return E_INVALIDARG; 1055 1061 1056 HRESULT hr = directSoundCaptureInterfaceCreate(pThis, p DSoundStream);1062 HRESULT hr = directSoundCaptureInterfaceCreate(pThis, pStreamDS); 1057 1063 if (FAILED(hr)) 1058 1064 return hr; … … 1061 1067 { 1062 1068 LPDIRECTSOUNDCAPTUREBUFFER pDSCB = NULL; 1069 1063 1070 DSCBUFFERDESC bd; 1064 1071 RT_ZERO(bd); 1065 bd.dwSize = sizeof(bd); 1066 bd.lpwfxFormat = &wfx; 1072 1073 bd.dwSize = sizeof(bd); 1074 bd.lpwfxFormat = &wfx; 1067 1075 bd.dwBufferBytes = pThis->cfg.cbBufferIn; 1068 hr = IDirectSoundCapture_CreateCaptureBuffer(pDSoundStream->pDSC, 1069 1076 1077 hr = IDirectSoundCapture_CreateCaptureBuffer(pStreamDS->In.pDSC, &bd, &pDSCB, NULL); 1070 1078 if (FAILED(hr)) 1071 1079 { … … 1079 1087 } 1080 1088 1081 hr = IDirectSoundCaptureBuffer_QueryInterface(pDSCB, IID_IDirectSoundCaptureBuffer8, (void **)&p DSoundStream->pDSCB);1089 hr = IDirectSoundCaptureBuffer_QueryInterface(pDSCB, IID_IDirectSoundCaptureBuffer8, (void **)&pStreamDS->In.pDSCB); 1082 1090 IDirectSoundCaptureBuffer_Release(pDSCB); 1083 1091 if (FAILED(hr)) … … 1091 1099 */ 1092 1100 DWORD offByteReadPos = 0; 1093 hr = IDirectSoundCaptureBuffer8_GetCurrentPosition(p DSoundStream->pDSCB, NULL, &offByteReadPos);1101 hr = IDirectSoundCaptureBuffer8_GetCurrentPosition(pStreamDS->In.pDSCB, NULL, &offByteReadPos); 1094 1102 if (FAILED(hr)) 1095 1103 { … … 1099 1107 1100 1108 RT_ZERO(wfx); 1101 hr = IDirectSoundCaptureBuffer8_GetFormat(p DSoundStream->pDSCB, &wfx, sizeof(wfx), NULL);1109 hr = IDirectSoundCaptureBuffer8_GetFormat(pStreamDS->In.pDSCB, &wfx, sizeof(wfx), NULL); 1102 1110 if (FAILED(hr)) 1103 1111 { … … 1109 1117 RT_ZERO(bc); 1110 1118 bc.dwSize = sizeof(bc); 1111 hr = IDirectSoundCaptureBuffer8_GetCaps(p DSoundStream->pDSCB, &bc);1119 hr = IDirectSoundCaptureBuffer8_GetCaps(pStreamDS->In.pDSCB, &bc); 1112 1120 if (FAILED(hr)) 1113 1121 { … … 1136 1144 wfx.cbSize)); 1137 1145 1138 if (bc.dwBufferBytes & p DSoundStream->Props.uAlign)1146 if (bc.dwBufferBytes & pStreamDS->uAlign) 1139 1147 DSLOGREL(("DSound: Capture GetCaps returned misaligned buffer: size %RU32, alignment %RU32\n", 1140 bc.dwBufferBytes, p DSoundStream->Props.uAlign + 1));1148 bc.dwBufferBytes, pStreamDS->uAlign + 1)); 1141 1149 1142 1150 if (bc.dwBufferBytes != pThis->cfg.cbBufferIn) … … 1145 1153 1146 1154 /* Initial state: reading at the initial capture position, no error. */ 1147 p DSoundStream->offCaptureBufRead = offByteReadPos;1148 p DSoundStream->cbCaptureBuf = bc.dwBufferBytes;1149 1150 p DSoundStream->hrLastCapture = S_OK;1155 pStreamDS->In.offCaptureBufRead = offByteReadPos; 1156 pStreamDS->In.cbCaptureBuf = bc.dwBufferBytes; 1157 1158 pStreamDS->In.hrLastCapture = S_OK; 1151 1159 1152 1160 DSLOG(("DSound: offCaptureBufRead=%RU32, cbCaptureBuf=%RU32\n", 1153 pDSoundStream->offCaptureBufRead, pDSoundStream->cbCaptureBuf)); 1161 pStreamDS->In.offCaptureBufRead, pStreamDS->In.cbCaptureBuf)); 1162 1163 pCfgAcq->cSampleBufferHint = PDMAUDIOSTREAMCFG_B2S(pCfgAcq, pThis->cfg.cbBufferIn); 1154 1164 1155 1165 } while (0); 1156 1166 1157 1167 if (FAILED(hr)) 1158 directSoundCaptureClose(p DSoundStream);1168 directSoundCaptureClose(pStreamDS); 1159 1169 1160 1170 LogFlowFunc(("Returning %Rhrc\n", hr)); … … 1163 1173 1164 1174 1165 static HRESULT directSoundCaptureStop(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM IN pDSoundStream)1166 { 1167 AssertPtrReturn(pThis ,E_POINTER);1168 AssertPtrReturn(p DSoundStream, E_POINTER);1169 1170 NOREF(pThis);1175 static HRESULT directSoundCaptureStop(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS) 1176 { 1177 AssertPtrReturn(pThis, E_POINTER); 1178 AssertPtrReturn(pStreamDS, E_POINTER); 1179 1180 RT_NOREF(pThis); 1171 1181 1172 1182 HRESULT hr; 1173 1183 1174 if (p DSoundStream->pDSCB)1184 if (pStreamDS->In.pDSCB) 1175 1185 { 1176 1186 DSLOG(("DSound: Stopping capture\n")); 1177 1187 1178 hr = IDirectSoundCaptureBuffer_Stop(p DSoundStream->pDSCB);1188 hr = IDirectSoundCaptureBuffer_Stop(pStreamDS->In.pDSCB); 1179 1189 if (FAILED(hr)) 1180 1190 DSLOGREL(("DSound: Stopping capture buffer failed with %Rhrc\n", hr)); … … 1184 1194 1185 1195 if (SUCCEEDED(hr)) 1186 p DSoundStream->fEnabled = false;1196 pStreamDS->In.fEnabled = false; 1187 1197 1188 1198 LogFlowFunc(("Returning %Rhrc\n", hr)); … … 1191 1201 1192 1202 1193 static HRESULT directSoundCaptureStart(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM IN pDSoundStream)1194 { 1195 AssertPtrReturn(pThis, 1196 AssertPtrReturn(p DSoundStream, VERR_INVALID_POINTER);1203 static HRESULT directSoundCaptureStart(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS) 1204 { 1205 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1206 AssertPtrReturn(pStreamDS, VERR_INVALID_POINTER); 1197 1207 1198 1208 HRESULT hr; 1199 if (p DSoundStream->pDSCB != NULL)1209 if (pStreamDS->In.pDSCB != NULL) 1200 1210 { 1201 1211 DWORD dwStatus; 1202 hr = IDirectSoundCaptureBuffer8_GetStatus(p DSoundStream->pDSCB, &dwStatus);1212 hr = IDirectSoundCaptureBuffer8_GetStatus(pStreamDS->In.pDSCB, &dwStatus); 1203 1213 if (FAILED(hr)) 1204 1214 { … … 1218 1228 #endif 1219 1229 DSLOG(("DSound: Starting to capture\n")); 1220 hr = IDirectSoundCaptureBuffer8_Start(p DSoundStream->pDSCB, fFlags);1230 hr = IDirectSoundCaptureBuffer8_Start(pStreamDS->In.pDSCB, fFlags); 1221 1231 if (FAILED(hr)) 1222 1232 DSLOGREL(("DSound: Starting to capture failed with %Rhrc\n", hr)); … … 1228 1238 1229 1239 if (SUCCEEDED(hr)) 1230 p DSoundStream->fEnabled = true;1240 pStreamDS->In.fEnabled = true; 1231 1241 1232 1242 LogFlowFunc(("Returning %Rhrc\n", hr)); … … 1402 1412 RT_ZERO(Cfg); 1403 1413 1404 Cfg.cbStreamOut = sizeof(DSOUNDSTREAMOUT);1405 Cfg.cbStreamIn = sizeof(DSOUNDSTREAMIN);1414 Cfg.cbStreamOut = sizeof(DSOUNDSTREAM); 1415 Cfg.cbStreamIn = sizeof(DSOUNDSTREAM); 1406 1416 1407 1417 DSOUNDENUMCBCTX cbCtx = { pThis, fEnum, 0, 0 }; … … 1439 1449 1440 1450 1441 static int dsoundCreateStreamOut(PDRVHOSTDSOUND pThis, P PDMAUDIOSTREAM pStream,1451 static int dsoundCreateStreamOut(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, 1442 1452 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 1443 1453 { 1444 LogFlowFunc(("pStream=%p, pCfg=%p\n", pStream, pCfgReq)); 1445 PDSOUNDSTREAMOUT pDSoundStream = (PDSOUNDSTREAMOUT)pStream; 1446 1447 pDSoundStream->streamCfg = *pCfgReq; 1448 pDSoundStream->streamCfg.enmEndianness = PDMAUDIOHOSTENDIANNESS; 1449 1450 int rc = DrvAudioHlpStreamCfgToProps(&pDSoundStream->streamCfg, &pDSoundStream->Props); 1451 if (RT_SUCCESS(rc)) 1452 { 1453 pDSoundStream->pDS = NULL; 1454 pDSoundStream->pDSB = NULL; 1455 pDSoundStream->offPlayWritePos = 0; 1456 pDSoundStream->fRestartPlayback = true; 1457 pDSoundStream->cbPlayBuf = 0; 1458 1459 if (pCfgAcq) 1460 pCfgAcq->cSampleBufferSize = pThis->cfg.cbBufferOut >> pDSoundStream->Props.cShift; 1461 1462 /* Try to open playback in case the device is already there. */ 1463 directSoundPlayOpen(pThis, pDSoundStream); 1464 } 1465 else 1466 RT_ZERO(pDSoundStream->streamCfg); 1454 LogFlowFunc(("pStreamDS=%p, pCfgReq=%p\n", pStreamDS, pCfgReq)); 1455 1456 pStreamDS->Out.pDS = NULL; 1457 pStreamDS->Out.pDSB = NULL; 1458 pStreamDS->Out.offPlayWritePos = 0; 1459 pStreamDS->Out.fRestartPlayback = true; 1460 pStreamDS->Out.cbPlayBuf = 0; 1461 1462 int rc = VINF_SUCCESS; 1463 1464 /* Try to open playback in case the device is already there. */ 1465 HRESULT hr = directSoundPlayOpen(pThis, pStreamDS, pCfgReq, pCfgAcq); 1466 if (FAILED(hr)) 1467 rc = VERR_GENERAL_FAILURE; /** @todo Fudge! */ 1467 1468 1468 1469 LogFlowFuncLeaveRC(rc); … … 1470 1471 } 1471 1472 1472 static int dsoundControlStreamOut(PDRVHOSTDSOUND pThis, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 1473 { 1474 LogFlowFunc(("pStream=%p, cmd=%d\n", pStream, enmStreamCmd)); 1475 PDSOUNDSTREAMOUT pDSoundStream = (PDSOUNDSTREAMOUT)pStream; 1473 static int dsoundControlStreamOut(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, PDMAUDIOSTREAMCMD enmStreamCmd) 1474 { 1475 LogFlowFunc(("pStreamDS=%p, cmd=%d\n", pStreamDS, enmStreamCmd)); 1476 1476 1477 1477 int rc = VINF_SUCCESS; … … 1485 1485 DSLOG(("DSound: Playback PDMAUDIOSTREAMCMD_ENABLE\n")); 1486 1486 /* Try to start playback. If it fails, then reopen and try again. */ 1487 hr = directSoundPlayStart(pThis, p DSoundStream);1487 hr = directSoundPlayStart(pThis, pStreamDS); 1488 1488 if (FAILED(hr)) 1489 1489 { 1490 hr = directSoundPlayClose(pThis, p DSoundStream);1490 hr = directSoundPlayClose(pThis, pStreamDS); 1491 1491 if (SUCCEEDED(hr)) 1492 hr = directSoundPlayOpen(pThis, pDSoundStream); 1492 { 1493 PDMAUDIOSTREAMCFG CfgAcq; 1494 hr = directSoundPlayOpen(pThis, pStreamDS, pStreamDS->pCfg /* pCfqReq */, &CfgAcq); 1495 if (SUCCEEDED(hr)) 1496 { 1497 DrvAudioHlpStreamCfgFree(pStreamDS->pCfg); 1498 1499 pStreamDS->pCfg = DrvAudioHlpStreamCfgDup(&CfgAcq); 1500 AssertPtr(pStreamDS->pCfg); 1501 1502 /** @todo What to do if the format has changed? */ 1503 } 1504 } 1493 1505 if (SUCCEEDED(hr)) 1494 hr = directSoundPlayStart(pThis, p DSoundStream);1506 hr = directSoundPlayStart(pThis, pStreamDS); 1495 1507 } 1496 1508 … … 1504 1516 { 1505 1517 DSLOG(("DSound: Playback PDMAUDIOSTREAMCMD_DISABLE\n")); 1506 hr = directSoundPlayStop(pThis, p DSoundStream);1518 hr = directSoundPlayStop(pThis, pStreamDS); 1507 1519 if (FAILED(hr)) 1508 1520 rc = VERR_NOT_SUPPORTED; … … 1527 1539 */ 1528 1540 int drvHostDSoundStreamPlay(PPDMIHOSTAUDIO pInterface, 1529 PPDMAUDIO STREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)1541 PPDMAUDIOBACKENDSTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten) 1530 1542 { 1531 1543 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 1535 1547 /* pcbRead is optional. */ 1536 1548 1537 PDRVHOSTDSOUND pThis= PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface);1538 PDSOUNDSTREAM OUT pDSoundStream = (PDSOUNDSTREAMOUT)pStream;1549 PDRVHOSTDSOUND pThis = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface); 1550 PDSOUNDSTREAM pStreamDS = (PDSOUNDSTREAM)pStream; 1539 1551 1540 1552 int rc = VINF_SUCCESS; … … 1548 1560 do /* to use 'break' */ 1549 1561 { 1562 AssertPtr(pStreamDS->pCfg); 1563 PPDMAUDIOPCMPROPS pProps = &pStreamDS->pCfg->Props; 1564 1550 1565 DWORD cbBuffer, cbFree, cbPlayPos; 1551 rc = dsoundGetPosOut(pThis, p DSoundStream, &cbBuffer, &cbFree, &cbPlayPos);1566 rc = dsoundGetPosOut(pThis, pStreamDS, &cbBuffer, &cbFree, &cbPlayPos); 1552 1567 if (RT_FAILURE(rc)) 1553 1568 break; … … 1557 1572 * i.e. always leave a free space for 1 audio sample. 1558 1573 */ 1559 const DWORD cbSample = PDMAUDIOPCMPROPS_S2B( &pDSoundStream->Props, 1);1574 const DWORD cbSample = PDMAUDIOPCMPROPS_S2B(pProps, 1); 1560 1575 if (cbFree <= cbSample) 1561 1576 break; … … 1566 1581 /* Do not write more than available space in the DirectSound playback buffer. */ 1567 1582 cbLive = RT_MIN(cbFree, cbLive); 1568 cbLive &= ~p DSoundStream->Props.uAlign;1583 cbLive &= ~pStreamDS->uAlign; 1569 1584 if (cbLive == 0 || cbLive > cbBuffer) 1570 1585 { 1571 1586 DSLOG(("DSound: cbLive=%RU32, cbBuffer=%ld, offPlayWritePos=%ld, cbPlayPos=%ld\n", 1572 cbLive, cbBuffer, p DSoundStream->offPlayWritePos, cbPlayPos));1573 break; 1574 } 1575 1576 LPDIRECTSOUNDBUFFER8 pDSB = p DSoundStream->pDSB;1587 cbLive, cbBuffer, pStreamDS->Out.offPlayWritePos, cbPlayPos)); 1588 break; 1589 } 1590 1591 LPDIRECTSOUNDBUFFER8 pDSB = pStreamDS->Out.pDSB; 1577 1592 AssertPtr(pDSB); 1578 1593 1579 1594 PVOID pv1, pv2; 1580 1595 DWORD cb1, cb2; 1581 HRESULT hr = directSoundPlayLock(pThis, p DSB, &pDSoundStream->Props, pDSoundStream->offPlayWritePos, cbLive,1596 HRESULT hr = directSoundPlayLock(pThis, pStreamDS, pStreamDS->Out.offPlayWritePos, cbLive, 1582 1597 &pv1, &pv2, &cb1, &cb2, 0 /* dwFlags */); 1583 1598 if (FAILED(hr)) … … 1603 1618 directSoundPlayUnlock(pThis, pDSB, pv1, pv2, cb1, cb2); 1604 1619 1605 p DSoundStream->offPlayWritePos = (pDSoundStream->offPlayWritePos + PDMAUDIOPCMPROPS_S2B(&pDSoundStream->Props, cbWrittenTotal))1620 pStreamDS->Out.offPlayWritePos = (pStreamDS->Out.offPlayWritePos + PDMAUDIOPCMPROPS_S2B(pProps, cbWrittenTotal)) 1606 1621 % cbBuffer; 1607 1622 1608 1623 DSLOGF(("DSound: %RU32/%RU32, buffer write pos %ld, rc=%Rrc\n", 1609 PDMAUDIOPCMPROPS_S2B(&pDSoundStream->Props, cbWrittenTotal), cbLive, 1610 pDSoundStream->offPlayWritePos, rc)); 1611 1612 if (pDSoundStream->fRestartPlayback) 1624 PDMAUDIOPCMPROPS_S2B(pProps, cbWrittenTotal), cbLive, pStreamDS->Out.offPlayWritePos, rc)); 1625 1626 if (pStreamDS->Out.fRestartPlayback) 1613 1627 { 1614 1628 /* … … 1617 1631 * and it can start playing. 1618 1632 */ 1619 p DSoundStream->fRestartPlayback = false;1633 pStreamDS->Out.fRestartPlayback = false; 1620 1634 1621 1635 DWORD fFlags = 0; … … 1625 1639 for (unsigned i = 0; i < DRV_DSOUND_RESTORE_ATTEMPTS_MAX; i++) 1626 1640 { 1627 hr = IDirectSoundBuffer8_Play(p DSoundStream->pDSB, 0, 0, fFlags);1641 hr = IDirectSoundBuffer8_Play(pStreamDS->Out.pDSB, 0, 0, fFlags); 1628 1642 if ( SUCCEEDED(hr) 1629 1643 || hr != DSERR_BUFFERLOST) … … 1632 1646 { 1633 1647 LogFlowFunc(("Restarting playback failed due to lost buffer, restoring ...\n")); 1634 directSoundPlayRestore(pThis, p DSoundStream->pDSB);1648 directSoundPlayRestore(pThis, pStreamDS->Out.pDSB); 1635 1649 } 1636 1650 } … … 1646 1660 } while (0); 1647 1661 1648 if (RT_FAILURE(rc)) 1662 if (RT_SUCCESS(rc)) 1663 { 1664 if (pcbWritten) 1665 *pcbWritten = cbWrittenTotal; 1666 } 1667 else 1649 1668 dsoundUpdateStatusInternal(pThis); 1650 else if (pcbWritten)1651 *pcbWritten = cbWrittenTotal;1652 1669 1653 1670 return rc; … … 1655 1672 1656 1673 1657 static int dsoundDestroyStreamOut(PDRVHOSTDSOUND pThis, PPDMAUDIOSTREAM pStream) 1658 { 1659 PDSOUNDSTREAMOUT pDSoundStream = (PDSOUNDSTREAMOUT)pStream; 1660 1661 directSoundPlayClose(pThis, pDSoundStream); 1662 1663 pDSoundStream->offPlayWritePos = 0; 1664 pDSoundStream->fRestartPlayback = true; 1665 pDSoundStream->cbPlayBuf = 0; 1666 1667 RT_ZERO(pDSoundStream->streamCfg); 1674 static int dsoundDestroyStreamOut(PDRVHOSTDSOUND pThis, PPDMAUDIOBACKENDSTREAM pStream) 1675 { 1676 PDSOUNDSTREAM pStreamDS = (PDSOUNDSTREAM)pStream; 1677 1678 directSoundPlayClose(pThis, pStreamDS); 1679 1680 pStreamDS->Out.offPlayWritePos = 0; 1681 pStreamDS->Out.fRestartPlayback = true; 1682 pStreamDS->Out.cbPlayBuf = 0; 1668 1683 1669 1684 return VINF_SUCCESS; 1670 1685 } 1671 1686 1672 static int dsoundCreateStreamIn(PDRVHOSTDSOUND pThis, P PDMAUDIOSTREAM pStream,1687 static int dsoundCreateStreamIn(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, 1673 1688 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 1674 1689 { 1675 PDSOUNDSTREAMIN pDSoundStream = (PDSOUNDSTREAMIN)pStream; 1676 1677 LogFlowFunc(("pStream=%p, pCfg=%p, enmRecSource=%ld\n", pStream, pCfgReq, pCfgReq->DestSource.Source)); 1678 1679 memcpy(&pDSoundStream->streamCfg, pCfgReq, sizeof(PDMAUDIOSTREAMCFG)); 1680 1681 /** @todo caller should already init Props? */ 1682 int rc = DrvAudioHlpStreamCfgToProps(&pDSoundStream->streamCfg, &pDSoundStream->Props); 1683 if (RT_SUCCESS(rc)) 1684 { 1685 /* Init the stream structure and save relevant information to it. */ 1686 pDSoundStream->offCaptureBufRead = 0; 1687 pDSoundStream->cbCaptureBuf = 0; 1688 pDSoundStream->pDSC = NULL; 1689 pDSoundStream->pDSCB = NULL; 1690 pDSoundStream->enmRecSource = pCfgReq->DestSource.Source; 1691 pDSoundStream->hrLastCapture = S_OK; 1692 1693 if (pCfgAcq) 1694 pCfgAcq->cSampleBufferSize = pThis->cfg.cbBufferIn >> pDSoundStream->Props.cShift; 1695 1696 /* Try to open capture in case the device is already there. */ 1697 directSoundCaptureOpen(pThis, pDSoundStream); /** @todo r=andy Why not checking the result here?? */ 1698 } 1699 else 1700 { 1701 RT_ZERO(pDSoundStream->streamCfg); 1702 } 1703 1704 LogFlowFuncLeaveRC(rc); 1690 LogFunc(("pStreamDS=%p, pCfgReq=%p, enmRecSource=%s\n", 1691 pStreamDS, pCfgReq, DrvAudioHlpRecSrcToStr(pCfgReq->DestSource.Source))); 1692 1693 /* Init the stream structure and save relevant information to it. */ 1694 pStreamDS->In.offCaptureBufRead = 0; 1695 pStreamDS->In.cbCaptureBuf = 0; 1696 pStreamDS->In.pDSC = NULL; 1697 pStreamDS->In.pDSCB = NULL; 1698 pStreamDS->In.hrLastCapture = S_OK; 1699 1700 int rc = VINF_SUCCESS; 1701 1702 /* Try to open capture in case the device is already there. */ 1703 HRESULT hr = directSoundCaptureOpen(pThis, pStreamDS, pCfgReq, pCfgAcq); 1704 if (FAILED(hr)) 1705 rc = VERR_GENERAL_FAILURE; /** @todo Fudge! */ 1706 1705 1707 return rc; 1706 1708 } 1707 1709 1708 static int dsoundControlStreamIn(PDRVHOSTDSOUND pThis, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 1709 { 1710 LogFlowFunc(("pStream=%p, enmStreamCmd=%ld\n", pStream, enmStreamCmd)); 1711 PDSOUNDSTREAMIN pDSoundStream = (PDSOUNDSTREAMIN)pStream; 1710 static int dsoundControlStreamIn(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, PDMAUDIOSTREAMCMD enmStreamCmd) 1711 { 1712 LogFlowFunc(("pStreamDS=%p, enmStreamCmd=%ld\n", pStreamDS, enmStreamCmd)); 1712 1713 1713 1714 int rc = VINF_SUCCESS; … … 1720 1721 { 1721 1722 /* Try to start capture. If it fails, then reopen and try again. */ 1722 hr = directSoundCaptureStart(pThis, p DSoundStream);1723 hr = directSoundCaptureStart(pThis, pStreamDS); 1723 1724 if (FAILED(hr)) 1724 1725 { 1725 hr = directSoundCaptureClose(p DSoundStream);1726 hr = directSoundCaptureClose(pStreamDS); 1726 1727 if (SUCCEEDED(hr)) 1727 1728 { 1728 hr = directSoundCaptureOpen(pThis, pDSoundStream); 1729 PDMAUDIOSTREAMCFG CfgAcq; 1730 hr = directSoundCaptureOpen(pThis, pStreamDS, pStreamDS->pCfg /* pCfgReq */, &CfgAcq); 1729 1731 if (SUCCEEDED(hr)) 1730 hr = directSoundCaptureStart(pThis, pDSoundStream); 1732 { 1733 DrvAudioHlpStreamCfgFree(pStreamDS->pCfg); 1734 1735 pStreamDS->pCfg = DrvAudioHlpStreamCfgDup(&CfgAcq); 1736 AssertPtr(pStreamDS->pCfg); 1737 1738 /** @todo What to do if the format has changed? */ 1739 1740 hr = directSoundCaptureStart(pThis, pStreamDS); 1741 } 1731 1742 } 1732 1743 } … … 1740 1751 case PDMAUDIOSTREAMCMD_PAUSE: 1741 1752 { 1742 hr = directSoundCaptureStop(pThis, p DSoundStream);1753 hr = directSoundCaptureStop(pThis, pStreamDS); 1743 1754 if (FAILED(hr)) 1744 1755 rc = VERR_NOT_SUPPORTED; … … 1762 1773 */ 1763 1774 int drvHostDSoundStreamCapture(PPDMIHOSTAUDIO pInterface, 1764 PPDMAUDIO STREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)1775 PPDMAUDIOBACKENDSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 1765 1776 { 1766 1777 … … 1770 1781 AssertReturn(cbBuf, VERR_INVALID_PARAMETER); 1771 1782 1772 PDRVHOSTDSOUND pThis = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface); 1773 1774 PDSOUNDSTREAMIN pDSoundStream = (PDSOUNDSTREAMIN)pStream; 1775 LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB = pDSoundStream->pDSCB; 1783 PDRVHOSTDSOUND pThis = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface); 1784 PDSOUNDSTREAM pStreamDS = (PDSOUNDSTREAM)pStream; 1785 1786 LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB = pStreamDS->In.pDSCB; 1787 AssertPtr(pDSCB); 1776 1788 1777 1789 int rc = VINF_SUCCESS; … … 1792 1804 if (FAILED(hr)) 1793 1805 { 1794 if (hr != p DSoundStream->hrLastCapture)1806 if (hr != pStreamDS->In.hrLastCapture) 1795 1807 { 1796 1808 DSLOGREL(("DSound: Getting capture position failed with %Rhrc\n", hr)); 1797 p DSoundStream->hrLastCapture = hr;1809 pStreamDS->In.hrLastCapture = hr; 1798 1810 } 1799 1811 … … 1802 1814 } 1803 1815 1804 pDSoundStream->hrLastCapture = hr; 1805 1806 if (offCurPos & pDSoundStream->Props.uAlign) 1807 DSLOGF(("DSound: Misaligned capture read position %ld (alignment: %RU32)\n", offCurPos, pDSoundStream->Props.uAlign)); 1816 pStreamDS->In.hrLastCapture = hr; 1817 1818 if (offCurPos & pStreamDS->uAlign) 1819 DSLOGF(("DSound: Misaligned capture read position %ld (alignment: %RU32)\n", 1820 offCurPos, pStreamDS->uAlign + 1)); 1808 1821 1809 1822 /* Number of samples available in the DirectSound capture buffer. */ 1810 DWORD cbToCapture = dsoundRingDistance(offCurPos, p DSoundStream->offCaptureBufRead, pDSoundStream->cbCaptureBuf);1823 DWORD cbToCapture = dsoundRingDistance(offCurPos, pStreamDS->In.offCaptureBufRead, pStreamDS->In.cbCaptureBuf); 1811 1824 if (cbToCapture == 0) 1812 1825 break; … … 1819 1832 1820 1833 DSLOGF(("DSound: Capture cbBuf=%RU32, offCurPos=%ld, offCaptureBufRead=%ld, cbToCapture=%ld\n", 1821 cbBuf, offCurPos, p DSoundStream->offCaptureBufRead, cbToCapture));1834 cbBuf, offCurPos, pStreamDS->In.offCaptureBufRead, cbToCapture)); 1822 1835 1823 1836 /* No need to fetch more samples than mix buffer can receive. */ … … 1827 1840 PVOID pv1, pv2; 1828 1841 DWORD cb1, cb2; 1829 hr = directSoundCaptureLock(pDSCB, &p DSoundStream->Props,1830 p DSoundStream->offCaptureBufRead,/* dwOffset */1842 hr = directSoundCaptureLock(pDSCB, &pStreamDS->pCfg->Props, 1843 pStreamDS->In.offCaptureBufRead, /* dwOffset */ 1831 1844 cbToCapture, /* dwBytes */ 1832 1845 &pv1, &pv2, &cb1, &cb2, … … 1854 1867 if (RT_SUCCESS(rc)) 1855 1868 { 1856 p DSoundStream->offCaptureBufRead = (pDSoundStream->offCaptureBufRead + cbReadTotal)1857 % pDSoundStream->cbCaptureBuf;1869 pStreamDS->In.offCaptureBufRead = (pStreamDS->In.offCaptureBufRead + cbReadTotal) 1870 % pStreamDS->In.cbCaptureBuf; 1858 1871 DSLOGF(("DSound: Captured %ld bytes (%RU32 total)\n", cbToCapture, cbReadTotal)); 1859 1872 } … … 1872 1885 } 1873 1886 1874 static int dsoundDestroyStreamIn(PPDMAUDIOSTREAM pStream) 1875 { 1876 PDSOUNDSTREAMIN pDSoundStream = (PDSOUNDSTREAMIN)pStream; 1877 1878 directSoundCaptureClose(pDSoundStream); 1879 1880 pDSoundStream->offCaptureBufRead = 0; 1881 pDSoundStream->cbCaptureBuf = 0; 1882 1883 RT_ZERO(pDSoundStream->streamCfg); 1887 static int dsoundDestroyStreamIn(PDSOUNDSTREAM pStreamDS) 1888 { 1889 directSoundCaptureClose(pStreamDS); 1890 1891 pStreamDS->In.offCaptureBufRead = 0; 1892 pStreamDS->In.cbCaptureBuf = 0; 1884 1893 1885 1894 return VINF_SUCCESS; … … 2156 2165 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate} 2157 2166 */ 2158 static DECLCALLBACK(int) drvHostDSoundStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 2167 static DECLCALLBACK(int) drvHostDSoundStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 2168 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 2159 2169 { 2160 2170 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 2163 2173 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER); 2164 2174 2165 PDRVHOSTDSOUND pThis = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface); 2175 PDRVHOSTDSOUND pThis = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface); 2176 PDSOUNDSTREAM pStreamDS = (PDSOUNDSTREAM)pStream; 2166 2177 2167 2178 int rc; 2168 2179 if (pCfgReq->enmDir == PDMAUDIODIR_IN) 2169 rc = dsoundCreateStreamIn(pThis, pStream , pCfgReq, pCfgAcq);2180 rc = dsoundCreateStreamIn(pThis, pStreamDS, pCfgReq, pCfgAcq); 2170 2181 else 2171 rc = dsoundCreateStreamOut(pThis, pStream, pCfgReq, pCfgAcq); 2182 rc = dsoundCreateStreamOut(pThis, pStreamDS, pCfgReq, pCfgAcq); 2183 2184 if (RT_SUCCESS(rc)) 2185 { 2186 pStreamDS->pCfg = DrvAudioHlpStreamCfgDup(pCfgAcq); 2187 if (!pStreamDS->pCfg) 2188 rc = VERR_NO_MEMORY; 2189 } 2172 2190 2173 2191 return rc; … … 2178 2196 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy} 2179 2197 */ 2180 static DECLCALLBACK(int) drvHostDSoundStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)2198 static DECLCALLBACK(int) drvHostDSoundStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 2181 2199 { 2182 2200 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 2183 2201 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 2184 2202 2185 PDRVHOSTDSOUND pThis = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface); 2203 PDRVHOSTDSOUND pThis = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface); 2204 PDSOUNDSTREAM pStreamDS = (PDSOUNDSTREAM)pStream; 2205 2206 if (!pStreamDS->pCfg) /* Not (yet) configured? Skip. */ 2207 return VINF_SUCCESS; 2186 2208 2187 2209 int rc; 2188 if (pStream ->enmDir == PDMAUDIODIR_IN)2189 rc = dsoundDestroyStreamIn(pStream );2210 if (pStreamDS->pCfg->enmDir == PDMAUDIODIR_IN) 2211 rc = dsoundDestroyStreamIn(pStreamDS); 2190 2212 else 2191 rc = dsoundDestroyStreamOut(pThis, pStream); 2213 rc = dsoundDestroyStreamOut(pThis, pStreamDS); 2214 2215 if (RT_SUCCESS(rc)) 2216 { 2217 DrvAudioHlpStreamCfgFree(pStreamDS->pCfg); 2218 pStreamDS->pCfg = NULL; 2219 } 2192 2220 2193 2221 return rc; … … 2198 2226 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl} 2199 2227 */ 2200 static DECLCALLBACK(int) drvHostDSoundStreamControl(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 2228 static DECLCALLBACK(int) drvHostDSoundStreamControl(PPDMIHOSTAUDIO pInterface, 2229 PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 2201 2230 { 2202 2231 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 2203 2232 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 2204 2233 2205 PDRVHOSTDSOUND pThis = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface); 2206 2207 Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST); 2234 PDRVHOSTDSOUND pThis = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface); 2235 PDSOUNDSTREAM pStreamDS = (PDSOUNDSTREAM)pStream; 2236 2237 if (!pStreamDS->pCfg) /* Not (yet) configured? Skip. */ 2238 return VINF_SUCCESS; 2208 2239 2209 2240 int rc; 2210 if (pStream ->enmDir == PDMAUDIODIR_IN)2211 rc = dsoundControlStreamIn(pThis, pStream , enmStreamCmd);2241 if (pStreamDS->pCfg->enmDir == PDMAUDIODIR_IN) 2242 rc = dsoundControlStreamIn(pThis, pStreamDS, enmStreamCmd); 2212 2243 else 2213 rc = dsoundControlStreamOut(pThis, pStream , enmStreamCmd);2244 rc = dsoundControlStreamOut(pThis, pStreamDS, enmStreamCmd); 2214 2245 2215 2246 return rc; … … 2220 2251 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus} 2221 2252 */ 2222 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostDSoundStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)2253 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostDSoundStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 2223 2254 { 2224 2255 AssertPtrReturn(pInterface, PDMAUDIOSTRMSTS_FLAG_NONE); 2225 2256 AssertPtrReturn(pStream, PDMAUDIOSTRMSTS_FLAG_NONE); 2226 2257 2227 PDRVHOSTDSOUND pThis = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface); 2258 PDRVHOSTDSOUND pThis = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface); 2259 PDSOUNDSTREAM pStreamDS = (PDSOUNDSTREAM)pStream; 2260 2261 if (!pStreamDS->pCfg) /* Not (yet) configured? Skip. */ 2262 return PDMAUDIOSTRMSTS_FLAG_NONE; 2228 2263 2229 2264 PDMAUDIOSTRMSTS strmSts = PDMAUDIOSTRMSTS_FLAG_INITIALIZED; 2230 if (pStream->enmDir == PDMAUDIODIR_IN) 2231 { 2232 PDSOUNDSTREAMIN pDSoundStream = (PDSOUNDSTREAMIN)pStream; 2233 if (pDSoundStream->fEnabled) 2265 if (pStreamDS->pCfg->enmDir == PDMAUDIODIR_IN) 2266 { 2267 if (pStreamDS->In.fEnabled) 2234 2268 strmSts |= PDMAUDIOSTRMSTS_FLAG_ENABLED | PDMAUDIOSTRMSTS_FLAG_DATA_READABLE; 2235 2269 } 2236 2270 else 2237 2271 { 2238 PDSOUNDSTREAMOUT pDSoundStream = (PDSOUNDSTREAMOUT)pStream; 2239 if (pDSoundStream->fEnabled) 2272 if (pStreamDS->Out.fEnabled) 2240 2273 { 2241 2274 strmSts |= PDMAUDIOSTRMSTS_FLAG_ENABLED; 2242 2275 2243 2276 DWORD cbFree; 2244 int rc = dsoundGetPosOut(pThis, p DSoundStream, NULL /* cbBuffer */, &cbFree, NULL /* cbPlayPos */);2277 int rc = dsoundGetPosOut(pThis, pStreamDS, NULL /* cbBuffer */, &cbFree, NULL /* cbPlayPos */); 2245 2278 if ( RT_SUCCESS(rc) 2246 2279 && cbFree) … … 2259 2292 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate} 2260 2293 */ 2261 static DECLCALLBACK(int) drvHostDSoundStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)2294 static DECLCALLBACK(int) drvHostDSoundStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 2262 2295 { 2263 2296 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); -
trunk/src/VBox/Devices/Audio/DrvHostDebugAudio.cpp
r65565 r65624 34 34 typedef struct DEBUGAUDIOSTREAM 35 35 { 36 /** Note: Always must come first!*/37 P DMAUDIOSTREAM Stream;36 /** The stream's acquired configuration. */ 37 PPDMAUDIOSTREAMCFG pCfg; 38 38 /** Audio file to dump output to or read input from. */ 39 39 PDMAUDIOFILE File; … … 50 50 uint64_t tsLastPlayed; 51 51 uint8_t *pu8PlayBuffer; 52 size_tcbPlayBuffer;52 uint32_t cbPlayBuffer; 53 53 } Out; 54 54 }; 55 PDMAUDIOPCMPROPS Props;56 57 55 } DEBUGAUDIOSTREAM, *PDEBUGAUDIOSTREAM; 58 56 … … 77 75 static DECLCALLBACK(int) drvHostDebugAudioGetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg) 78 76 { 79 NOREF(pInterface);77 RT_NOREF(pInterface); 80 78 AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER); 81 79 … … 95 93 static DECLCALLBACK(int) drvHostDebugAudioInit(PPDMIHOSTAUDIO pInterface) 96 94 { 97 NOREF(pInterface);95 RT_NOREF(pInterface); 98 96 99 97 LogFlowFuncLeaveRC(VINF_SUCCESS); … … 107 105 static DECLCALLBACK(void) drvHostDebugAudioShutdown(PPDMIHOSTAUDIO pInterface) 108 106 { 109 NOREF(pInterface);107 RT_NOREF(pInterface); 110 108 } 111 109 … … 123 121 124 122 125 static int debugCreateStreamIn(PPDMIHOSTAUDIO pInterface, 126 PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 127 { 128 RT_NOREF(pInterface, pStream); 129 130 PDEBUGAUDIOSTREAM pDbgStream = (PDEBUGAUDIOSTREAM)pStream; 131 132 /* Just adopt the wanted stream configuration. */ 133 int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pDbgStream->Props); 134 if (RT_SUCCESS(rc)) 135 { 136 if (pCfgAcq) 137 pCfgAcq->cSampleBufferSize = _1K; 138 } 139 140 LogFlowFuncLeaveRC(rc); 141 return rc; 142 } 143 144 145 static int debugCreateStreamOut(PPDMIHOSTAUDIO pInterface, 146 PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 147 { 148 RT_NOREF(pInterface); 149 150 PDEBUGAUDIOSTREAM pDbgStream = (PDEBUGAUDIOSTREAM)pStream; 151 152 /* Just adopt the wanted stream configuration. */ 153 int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pDbgStream->Props); 154 if (RT_SUCCESS(rc)) 155 { 156 pDbgStream->Out.tsLastPlayed = 0; 157 pDbgStream->Out.cbPlayBuffer = _1K * PDMAUDIOPCMPROPS_S2B(&pDbgStream->Props, 1); /** @todo Make this configurable? */ 158 pDbgStream->Out.pu8PlayBuffer = (uint8_t *)RTMemAlloc(pDbgStream->Out.cbPlayBuffer); 159 if (!pDbgStream->Out.pu8PlayBuffer) 160 rc = VERR_NO_MEMORY; 161 } 123 static int debugCreateStreamIn(PDRVHOSTDEBUGAUDIO pDrv, PDEBUGAUDIOSTREAM pStreamDbg, 124 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 125 { 126 RT_NOREF(pDrv, pStreamDbg, pCfgReq); 127 128 if (pCfgAcq) 129 pCfgAcq->cSampleBufferHint = _1K; 130 131 return VINF_SUCCESS; 132 } 133 134 135 static int debugCreateStreamOut(PDRVHOSTDEBUGAUDIO pDrv, PDEBUGAUDIOSTREAM pStreamDbg, 136 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 137 { 138 RT_NOREF(pDrv); 139 140 int rc = VINF_SUCCESS; 141 142 pStreamDbg->Out.tsLastPlayed = 0; 143 pStreamDbg->Out.cbPlayBuffer = _1K * PDMAUDIOSTREAMCFG_S2B(pCfgReq, 1); /** @todo Make this configurable? */ 144 pStreamDbg->Out.pu8PlayBuffer = (uint8_t *)RTMemAlloc(pStreamDbg->Out.cbPlayBuffer); 145 if (!pStreamDbg->Out.pu8PlayBuffer) 146 rc = VERR_NO_MEMORY; 162 147 163 148 if (RT_SUCCESS(rc)) … … 172 157 { 173 158 LogFlowFunc(("%s\n", szFile)); 174 rc = DrvAudioHlpWAVFileOpen(&p DbgStream->File, szFile,159 rc = DrvAudioHlpWAVFileOpen(&pStreamDbg->File, szFile, 175 160 RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE_REPLACE, 176 &p DbgStream->Props, PDMAUDIOFILEFLAG_NONE);161 &pCfgReq->Props, PDMAUDIOFILEFLAG_NONE); 177 162 if (RT_FAILURE(rc)) 178 163 LogRel(("DebugAudio: Creating output file '%s' failed with %Rrc\n", szFile, rc)); … … 188 173 { 189 174 if (pCfgAcq) 190 pCfgAcq->cSampleBufferSize = PDMAUDIOPCMPROPS_B2S(&pDbgStream->Props, pDbgStream->Out.cbPlayBuffer); 191 } 192 193 LogFlowFuncLeaveRC(rc); 175 pCfgAcq->cSampleBufferHint = PDMAUDIOSTREAMCFG_B2S(pCfgAcq, pStreamDbg->Out.cbPlayBuffer); 176 } 177 194 178 return rc; 195 179 } … … 200 184 */ 201 185 static DECLCALLBACK(int) drvHostDebugAudioStreamCreate(PPDMIHOSTAUDIO pInterface, 202 PPDMAUDIO STREAM pStream,186 PPDMAUDIOBACKENDSTREAM pStream, 203 187 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 204 188 { … … 206 190 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 207 191 AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER); 192 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER); 193 194 PDRVHOSTDEBUGAUDIO pDrv = RT_FROM_MEMBER(pInterface, DRVHOSTDEBUGAUDIO, IHostAudio); 195 PDEBUGAUDIOSTREAM pStreamDbg = (PDEBUGAUDIOSTREAM)pStream; 208 196 209 197 int rc; 210 198 if (pCfgReq->enmDir == PDMAUDIODIR_IN) 211 rc = debugCreateStreamIn( p Interface, pStream, pCfgReq, pCfgAcq);199 rc = debugCreateStreamIn( pDrv, pStreamDbg, pCfgReq, pCfgAcq); 212 200 else 213 rc = debugCreateStreamOut(pInterface, pStream, pCfgReq, pCfgAcq); 214 215 LogFlowFunc(("%s: rc=%Rrc\n", pStream->szName, rc)); 201 rc = debugCreateStreamOut(pDrv, pStreamDbg, pCfgReq, pCfgAcq); 202 203 if (RT_SUCCESS(rc)) 204 { 205 pStreamDbg->pCfg = DrvAudioHlpStreamCfgDup(pCfgAcq); 206 if (!pStreamDbg->pCfg) 207 rc = VERR_NO_MEMORY; 208 } 209 216 210 return rc; 217 211 } … … 222 216 */ 223 217 static DECLCALLBACK(int) drvHostDebugAudioStreamPlay(PPDMIHOSTAUDIO pInterface, 224 PPDMAUDIO STREAM pStream, const void *pvBuf, uint32_t cbBuf,218 PPDMAUDIOBACKENDSTREAM pStream, const void *pvBuf, uint32_t cbBuf, 225 219 uint32_t *pcbWritten) 226 220 { … … 228 222 229 223 PDRVHOSTDEBUGAUDIO pDrv = RT_FROM_MEMBER(pInterface, DRVHOSTDEBUGAUDIO, IHostAudio); 230 PDEBUGAUDIOSTREAM p DbgStream= (PDEBUGAUDIOSTREAM)pStream;224 PDEBUGAUDIOSTREAM pStreamDbg = (PDEBUGAUDIOSTREAM)pStream; 231 225 232 226 /* Consume as many samples as would be played at the current frequency since last call. */ … … 234 228 235 229 uint64_t u64TicksNow = PDMDrvHlpTMGetVirtualTime(pDrv->pDrvIns); 236 // uint64_t u64TicksElapsed = u64TicksNow - p DbgStream->Out.tsLastPlayed;230 // uint64_t u64TicksElapsed = u64TicksNow - pStreamDbg->Out.tsLastPlayed; 237 231 // uint64_t u64TicksFreq = PDMDrvHlpTMGetVirtualFreq(pDrv->pDrvIns); 238 232 … … 249 243 uint32_t cbWritten = 0; 250 244 251 uint32_t cbAvail = RT_MIN(cbBuf, p DbgStream->Out.cbPlayBuffer);245 uint32_t cbAvail = RT_MIN(cbBuf, pStreamDbg->Out.cbPlayBuffer); 252 246 while (cbAvail) 253 247 { 254 248 uint32_t cbChunk = cbAvail; /** @todo Use chunks? */ 255 249 256 memcpy(p DbgStream->Out.pu8PlayBuffer, pvBuf, cbChunk);250 memcpy(pStreamDbg->Out.pu8PlayBuffer, pvBuf, cbChunk); 257 251 #if 0 258 252 RTFILE fh; 259 253 RTFileOpen(&fh, "/tmp/AudioDebug-Output.pcm", 260 254 RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 261 RTFileWrite(fh, p DbgStream->Out.pu8PlayBuffer, cbChunk, NULL);255 RTFileWrite(fh, pStreamDbg->Out.pu8PlayBuffer, cbChunk, NULL); 262 256 RTFileClose(fh); 263 257 #endif 264 int rc2 = DrvAudioHlpWAVFileWrite(&p DbgStream->File,265 p DbgStream->Out.pu8PlayBuffer, cbChunk, 0 /* fFlags */);258 int rc2 = DrvAudioHlpWAVFileWrite(&pStreamDbg->File, 259 pStreamDbg->Out.pu8PlayBuffer, cbChunk, 0 /* fFlags */); 266 260 if (RT_FAILURE(rc2)) 267 261 { … … 277 271 278 272 /* Remember when samples were consumed. */ 279 p DbgStream->Out.tsLastPlayed = u64TicksNow;273 pStreamDbg->Out.tsLastPlayed = u64TicksNow; 280 274 281 275 if (pcbWritten) … … 290 284 */ 291 285 static DECLCALLBACK(int) drvHostDebugAudioStreamCapture(PPDMIHOSTAUDIO pInterface, 292 PPDMAUDIO STREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)286 PPDMAUDIOBACKENDSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 293 287 { 294 288 RT_NOREF(pInterface, pStream, pvBuf, cbBuf); … … 302 296 303 297 304 static int debugDestroyStreamIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 305 { 306 RT_NOREF(pInterface, pStream); 307 LogFlowFuncLeaveRC(VINF_SUCCESS); 308 return VINF_SUCCESS; 309 } 310 311 312 static int debugDestroyStreamOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 313 { 314 RT_NOREF(pInterface); 315 PDEBUGAUDIOSTREAM pDbgStream = (PDEBUGAUDIOSTREAM)pStream; 316 if ( pDbgStream 317 && pDbgStream->Out.pu8PlayBuffer) 318 { 319 RTMemFree(pDbgStream->Out.pu8PlayBuffer); 320 pDbgStream->Out.pu8PlayBuffer = NULL; 321 } 322 323 size_t cbDataSize = DrvAudioHlpWAVFileGetDataSize(&pDbgStream->File); 324 325 int rc = DrvAudioHlpWAVFileClose(&pDbgStream->File); 298 static int debugDestroyStreamIn(PDRVHOSTDEBUGAUDIO pDrv, PDEBUGAUDIOSTREAM pStreamDbg) 299 { 300 RT_NOREF(pDrv, pStreamDbg); 301 return VINF_SUCCESS; 302 } 303 304 305 static int debugDestroyStreamOut(PDRVHOSTDEBUGAUDIO pDrv, PDEBUGAUDIOSTREAM pStreamDbg) 306 { 307 RT_NOREF(pDrv); 308 309 if (pStreamDbg->Out.pu8PlayBuffer) 310 { 311 RTMemFree(pStreamDbg->Out.pu8PlayBuffer); 312 pStreamDbg->Out.pu8PlayBuffer = NULL; 313 } 314 315 size_t cbDataSize = DrvAudioHlpWAVFileGetDataSize(&pStreamDbg->File); 316 317 int rc = DrvAudioHlpWAVFileClose(&pStreamDbg->File); 326 318 if (RT_SUCCESS(rc)) 327 319 { … … 332 324 && fDeleteEmptyFiles) 333 325 { 334 rc = RTFileDelete(p DbgStream->File.szName);326 rc = RTFileDelete(pStreamDbg->File.szName); 335 327 } 336 328 else 337 LogRel(("DebugAudio: Created output file '%s' (%zu bytes)\n", pDbgStream->File.szName, cbDataSize)); 338 } 339 340 LogFlowFuncLeaveRC(rc); 329 LogRel(("DebugAudio: Created output file '%s' (%zu bytes)\n", pStreamDbg->File.szName, cbDataSize)); 330 } 331 341 332 return rc; 342 333 } 343 334 344 335 345 static DECLCALLBACK(int) drvHostDebugAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)336 static DECLCALLBACK(int) drvHostDebugAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 346 337 { 347 338 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 348 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 339 340 PDRVHOSTDEBUGAUDIO pDrv = RT_FROM_MEMBER(pInterface, DRVHOSTDEBUGAUDIO, IHostAudio); 341 PDEBUGAUDIOSTREAM pStreamDbg = (PDEBUGAUDIOSTREAM)pStream; 342 343 if (!pStreamDbg->pCfg) /* Not (yet) configured? Skip. */ 344 return VINF_SUCCESS; 349 345 350 346 int rc; 351 if (pStream ->enmDir == PDMAUDIODIR_IN)352 rc = debugDestroyStreamIn (pInterface, pStream);347 if (pStreamDbg->pCfg->enmDir == PDMAUDIODIR_IN) 348 rc = debugDestroyStreamIn (pDrv, pStreamDbg); 353 349 else 354 rc = debugDestroyStreamOut(pInterface, pStream); 350 rc = debugDestroyStreamOut(pDrv, pStreamDbg); 351 352 if (RT_SUCCESS(rc)) 353 { 354 DrvAudioHlpStreamCfgFree(pStreamDbg->pCfg); 355 pStreamDbg->pCfg = NULL; 356 } 355 357 356 358 return rc; … … 358 360 359 361 static DECLCALLBACK(int) drvHostDebugAudioStreamControl(PPDMIHOSTAUDIO pInterface, 360 PPDMAUDIO STREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)362 PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 361 363 { 362 364 RT_NOREF(enmStreamCmd); … … 364 366 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 365 367 366 Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST); 367 368 return VINF_SUCCESS; 369 } 370 371 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostDebugAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 372 { 373 NOREF(pInterface); 374 NOREF(pStream); 368 return VINF_SUCCESS; 369 } 370 371 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostDebugAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 372 { 373 RT_NOREF(pInterface, pStream); 375 374 376 375 return ( PDMAUDIOSTRMSTS_FLAG_INITIALIZED | PDMAUDIOSTRMSTS_FLAG_ENABLED … … 378 377 } 379 378 380 static DECLCALLBACK(int) drvHostDebugAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 381 { 382 NOREF(pInterface); 383 NOREF(pStream); 384 379 static DECLCALLBACK(int) drvHostDebugAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 380 { 381 RT_NOREF(pInterface, pStream); 385 382 return VINF_SUCCESS; 386 383 } -
trunk/src/VBox/Devices/Audio/DrvHostNullAudio.cpp
r65565 r65624 60 60 * Structures and Typedefs * 61 61 *********************************************************************************************************************************/ 62 typedef struct NULLAUDIOSTREAMOUT 63 { 64 /** @note Always must come first! */ 65 PDMAUDIOSTREAM Stream; 66 /** The PCM properties of this stream. */ 67 PDMAUDIOPCMPROPS Props; 68 uint64_t u64TicksLast; 69 } NULLAUDIOSTREAMOUT; 70 typedef NULLAUDIOSTREAMOUT *PNULLAUDIOSTREAMOUT; 71 72 typedef struct NULLAUDIOSTREAMIN 73 { 74 /** @note Always must come first! */ 75 PDMAUDIOSTREAM Stream; 76 /** The PCM properties of this stream. */ 77 PDMAUDIOPCMPROPS Props; 78 } NULLAUDIOSTREAMIN; 79 typedef NULLAUDIOSTREAMIN *PNULLAUDIOSTREAMIN; 62 typedef struct NULLAUDIOSTREAM 63 { 64 /** The stream's acquired configuration. */ 65 PPDMAUDIOSTREAMCFG pCfg; 66 union 67 { 68 struct 69 { 70 /** Timestamp of last played samples. */ 71 uint64_t u64TicksLast; 72 } Out; 73 }; 74 } NULLAUDIOSTREAM; 75 typedef NULLAUDIOSTREAM *PNULLAUDIOSTREAM; 80 76 81 77 /** … … 101 97 AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER); 102 98 103 pBackendCfg->cbStreamOut = sizeof(NULLAUDIOSTREAM OUT);104 pBackendCfg->cbStreamIn = sizeof(NULLAUDIOSTREAM IN);99 pBackendCfg->cbStreamOut = sizeof(NULLAUDIOSTREAM); 100 pBackendCfg->cbStreamIn = sizeof(NULLAUDIOSTREAM); 105 101 106 102 pBackendCfg->cMaxStreamsOut = 1; /* Output */ … … 147 143 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay} 148 144 */ 149 static DECLCALLBACK(int) drvHostNullAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream,145 static DECLCALLBACK(int) drvHostNullAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 150 146 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten) 151 147 { … … 155 151 AssertReturn(cbBuf, VERR_INVALID_PARAMETER); 156 152 157 PDRVHOSTNULLAUDIO 158 PNULLAUDIOSTREAM OUT pNullStream = RT_FROM_MEMBER(pStream, NULLAUDIOSTREAMOUT, Stream);153 PDRVHOSTNULLAUDIO pDrv = RT_FROM_MEMBER(pInterface, DRVHOSTNULLAUDIO, IHostAudio); 154 PNULLAUDIOSTREAM pStreamNull = (PNULLAUDIOSTREAM)pStream; 159 155 160 156 /* Consume as many samples as would be played at the current frequency since last call. */ 161 uint32_t csLive = PDMAUDIOPCMPROPS_B2S(&p NullStream->Props, cbBuf);157 uint32_t csLive = PDMAUDIOPCMPROPS_B2S(&pStreamNull->pCfg->Props, cbBuf); 162 158 163 159 uint64_t u64TicksNow = PDMDrvHlpTMGetVirtualTime(pDrv->pDrvIns); 164 uint64_t u64TicksElapsed = u64TicksNow - p NullStream->u64TicksLast;160 uint64_t u64TicksElapsed = u64TicksNow - pStreamNull->Out.u64TicksLast; 165 161 uint64_t u64TicksFreq = PDMDrvHlpTMGetVirtualFreq(pDrv->pDrvIns); 166 162 167 163 /* Remember when samples were consumed. */ 168 p NullStream->u64TicksLast = u64TicksNow;164 pStreamNull->Out.u64TicksLast = u64TicksNow; 169 165 170 166 /* … … 172 168 * If rounding is not taken into account then the playback rate will be consistently lower that expected. 173 169 */ 174 uint64_t csPlayed = (2 * u64TicksElapsed * p NullStream->Props.uHz + u64TicksFreq) / u64TicksFreq / 2;170 uint64_t csPlayed = (2 * u64TicksElapsed * pStreamNull->pCfg->Props.uHz + u64TicksFreq) / u64TicksFreq / 2; 175 171 176 172 /* Don't play more than available. */ … … 181 177 182 178 if (pcbWritten) 183 *pcbWritten = PDMAUDIOPCMPROPS_S2B(&p NullStream->Props, csPlayed);179 *pcbWritten = PDMAUDIOPCMPROPS_S2B(&pStreamNull->pCfg->Props, csPlayed); 184 180 185 181 return VINF_SUCCESS; … … 190 186 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture} 191 187 */ 192 static DECLCALLBACK(int) drvHostNullAudioStreamCapture(PPDMIHOSTAUDIO pInterface, 193 PPDMAUDIOSTREAM pStream,void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)188 static DECLCALLBACK(int) drvHostNullAudioStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 189 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 194 190 { 195 191 RT_NOREF(pInterface, pStream); 196 192 193 /* Return silence. */ 197 194 RT_BZERO(pvBuf, cbBuf); 198 195 199 /* Return silent audio. */200 196 if (pcbRead) 201 197 *pcbRead = cbBuf; … … 205 201 206 202 207 static int nullCreateStreamIn(PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 208 { 209 PNULLAUDIOSTREAMIN pNullStream = RT_FROM_MEMBER(pStream, NULLAUDIOSTREAMIN, Stream); 210 211 /* Just adopt the wanted stream configuration. */ 212 int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pNullStream->Props); 213 if (RT_SUCCESS(rc)) 214 { 215 if (pCfgAcq) 216 pCfgAcq->cSampleBufferSize = _1K; 217 } 218 219 return rc; 220 } 221 222 223 static int nullCreateStreamOut(PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 224 { 225 PNULLAUDIOSTREAMOUT pNullStream = RT_FROM_MEMBER(pStream, NULLAUDIOSTREAMOUT, Stream); 226 227 /* Just adopt the wanted stream configuration. */ 228 int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pNullStream->Props); 229 if (RT_SUCCESS(rc)) 230 { 231 pNullStream->u64TicksLast = 0; 232 233 if (pCfgAcq) 234 pCfgAcq->cSampleBufferSize = _1K; /** @todo Make this configurable. */ 235 } 236 237 return rc; 203 static int nullCreateStreamIn(PNULLAUDIOSTREAM pStreamNull, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 204 { 205 RT_NOREF(pStreamNull, pCfgReq); 206 207 if (pCfgAcq) 208 pCfgAcq->cSampleBufferHint = _1K; 209 210 return VINF_SUCCESS; 211 } 212 213 214 static int nullCreateStreamOut(PNULLAUDIOSTREAM pStreamNull, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 215 { 216 RT_NOREF(pCfgReq); 217 218 pStreamNull->Out.u64TicksLast = 0; 219 220 if (pCfgAcq) 221 pCfgAcq->cSampleBufferHint = _1K; /** @todo Make this configurable. */ 222 223 return VINF_SUCCESS; 238 224 } 239 225 … … 242 228 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate} 243 229 */ 244 static DECLCALLBACK(int) drvHostNullAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream,230 static DECLCALLBACK(int) drvHostNullAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 245 231 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 246 232 { … … 248 234 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 249 235 AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER); 236 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER); 237 238 PNULLAUDIOSTREAM pStreamNull = (PNULLAUDIOSTREAM)pStream; 250 239 251 240 int rc; 252 241 if (pCfgReq->enmDir == PDMAUDIODIR_IN) 253 rc = nullCreateStreamIn( pStream , pCfgReq, pCfgAcq);242 rc = nullCreateStreamIn( pStreamNull, pCfgReq, pCfgAcq); 254 243 else 255 rc = nullCreateStreamOut(pStream, pCfgReq, pCfgAcq); 256 257 LogFlowFunc(("%s: rc=%Rrc\n", pStream->szName, rc)); 244 rc = nullCreateStreamOut(pStreamNull, pCfgReq, pCfgAcq); 245 246 if (RT_SUCCESS(rc)) 247 { 248 pStreamNull->pCfg = DrvAudioHlpStreamCfgDup(pCfgAcq); 249 if (!pStreamNull->pCfg) 250 rc = VERR_NO_MEMORY; 251 } 252 258 253 return rc; 259 254 } … … 267 262 268 263 269 static int nullDestroyStreamOut(P PDMAUDIOSTREAM pStream)270 { 271 RT_NOREF(pStream );264 static int nullDestroyStreamOut(PNULLAUDIOSTREAM pStreamNull) 265 { 266 RT_NOREF(pStreamNull); 272 267 return VINF_SUCCESS; 273 268 } … … 277 272 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy} 278 273 */ 279 static DECLCALLBACK(int) drvHostNullAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)274 static DECLCALLBACK(int) drvHostNullAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 280 275 { 281 276 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 282 277 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 283 278 279 PNULLAUDIOSTREAM pStreamNull = (PNULLAUDIOSTREAM)pStream; 280 281 if (!pStreamNull->pCfg) /* Not (yet) configured? Skip. */ 282 return VINF_SUCCESS; 283 284 284 int rc; 285 if (pStream ->enmDir == PDMAUDIODIR_IN)285 if (pStreamNull->pCfg->enmDir == PDMAUDIODIR_IN) 286 286 rc = nullDestroyStreamIn(); 287 287 else 288 rc = nullDestroyStreamOut(pStream); 288 rc = nullDestroyStreamOut(pStreamNull); 289 290 if (RT_SUCCESS(rc)) 291 { 292 DrvAudioHlpStreamCfgFree(pStreamNull->pCfg); 293 pStreamNull->pCfg = NULL; 294 } 289 295 290 296 return rc; … … 295 301 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl} 296 302 */ 297 static DECLCALLBACK(int) drvHostNullAudioStreamControl(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 298 { 299 RT_NOREF(enmStreamCmd); 300 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 301 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 302 303 Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST); 304 303 static DECLCALLBACK(int) drvHostNullAudioStreamControl(PPDMIHOSTAUDIO pInterface, 304 PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 305 { 306 RT_NOREF(pInterface, pStream, enmStreamCmd); 305 307 return VINF_SUCCESS; 306 308 } … … 310 312 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus} 311 313 */ 312 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostNullAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)314 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostNullAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 313 315 { 314 316 RT_NOREF(pInterface, pStream); … … 321 323 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate} 322 324 */ 323 static DECLCALLBACK(int) drvHostNullAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)325 static DECLCALLBACK(int) drvHostNullAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 324 326 { 325 327 NOREF(pInterface); -
trunk/src/VBox/Devices/Audio/DrvHostOSSAudio.cpp
r65613 r65624 70 70 typedef struct OSSAUDIOSTREAMCFG 71 71 { 72 PDMAUDIOFMT enmFormat; 73 PDMAUDIOENDIANNESS enmENDIANNESS; 74 uint16_t uFreq; 75 uint8_t cChannels; 72 PDMAUDIOPCMPROPS Props; 76 73 uint16_t cFragments; 77 74 uint32_t cbFragmentSize; 78 75 } OSSAUDIOSTREAMCFG, *POSSAUDIOSTREAMCFG; 79 76 80 typedef struct OSSAUDIOSTREAMIN 81 { 82 /** Note: Always must come first! */ 83 PDMAUDIOSTREAM pStreamIn; 84 /** The PCM properties of this stream. */ 85 PDMAUDIOPCMPROPS Props; 77 typedef struct OSSAUDIOSTREAM 78 { 79 /** The stream's acquired configuration. */ 80 PPDMAUDIOSTREAMCFG pCfg; 81 /** Buffer alignment. */ 82 uint8_t uAlign; 83 union 84 { 85 struct 86 { 87 88 } In; 89 struct 90 { 91 #ifndef RT_OS_L4 92 /** Whether we use a memory mapped file instead of our 93 * own allocated PCM buffer below. */ 94 /** @todo The memory mapped code seems to be utterly broken. 95 * Needs investigation! */ 96 bool fMMIO; 97 #endif 98 } Out; 99 }; 86 100 int hFile; 87 101 int cFragments; … … 92 106 size_t cbBuf; 93 107 int old_optr; 94 } OSSAUDIOSTREAMIN, *POSSAUDIOSTREAMIN; 95 96 typedef struct OSSAUDIOSTREAMOUT 97 { 98 /** Note: Always must come first! */ 99 PDMAUDIOSTREAM pStreamOut; 100 /** The PCM properties of this stream. */ 101 PDMAUDIOPCMPROPS Props; 102 int hFile; 103 int cFragments; 104 int cbFragmentSize; 105 #ifndef RT_OS_L4 106 /** Whether we use a memory mapped file instead of our 107 * own allocated PCM buffer below. */ 108 /** @todo The memory mapped code seems to be utterly broken. 109 * Needs investigation! */ 110 bool fMMIO; 111 #endif 112 /** Own PCM buffer in case memory mapping is unavailable. */ 113 void *pvBuf; 114 /** Size (in bytes) of own PCM buffer. */ 115 size_t cbBuf; 116 int old_optr; 117 } OSSAUDIOSTREAMOUT, *POSSAUDIOSTREAMOUT; 108 } OSSAUDIOSTREAM, *POSSAUDIOSTREAM; 118 109 119 110 typedef struct OSSAUDIOCFG … … 160 151 161 152 162 static int ossAudioFmtToOSS(PDMAUDIOFMT fmt) 163 { 153 static int ossOSSToAudioProps(int fmt, PPDMAUDIOPCMPROPS pProps) 154 { 155 RT_BZERO(pProps, sizeof(PDMAUDIOPCMPROPS)); 156 164 157 switch (fmt) 165 158 { 166 case PDMAUDIOFMT_S8:167 return AFMT_S8;168 169 case PDMAUDIOFMT_U8:170 return AFMT_U8;171 172 case PDMAUDIOFMT_S16:173 return AFMT_S16_LE;174 175 case PDMAUDIOFMT_U16:176 return AFMT_U16_LE;177 178 default:179 break;180 }181 182 AssertMsgFailed(("Format %ld not supported\n", fmt));183 return AFMT_U8;184 }185 186 187 static int ossOSSToAudioFmt(int fmt, PDMAUDIOFMT *pFmt, PDMAUDIOENDIANNESS *pENDIANNESS)188 {189 switch (fmt)190 {191 159 case AFMT_S8: 192 *pFmt = PDMAUDIOFMT_S8; 193 if (pENDIANNESS) 194 *pENDIANNESS = PDMAUDIOENDIANNESS_LITTLE; 160 pProps->cBits = 8; 161 pProps->fSigned = true; 195 162 break; 196 163 197 164 case AFMT_U8: 198 *pFmt = PDMAUDIOFMT_U8; 199 if (pENDIANNESS) 200 *pENDIANNESS = PDMAUDIOENDIANNESS_LITTLE; 165 pProps->cBits = 8; 166 pProps->fSigned = false; 201 167 break; 202 168 203 169 case AFMT_S16_LE: 204 *pFmt = PDMAUDIOFMT_S16; 205 if (pENDIANNESS) 206 *pENDIANNESS = PDMAUDIOENDIANNESS_LITTLE; 170 pProps->cBits = 16; 171 pProps->fSigned = true; 207 172 break; 208 173 209 174 case AFMT_U16_LE: 210 *pFmt = PDMAUDIOFMT_U16; 211 if (pENDIANNESS) 212 *pENDIANNESS = PDMAUDIOENDIANNESS_LITTLE; 213 break; 214 215 case AFMT_S16_BE: 216 *pFmt = PDMAUDIOFMT_S16; 217 if (pENDIANNESS) 218 *pENDIANNESS = PDMAUDIOENDIANNESS_BIG; 175 pProps->cBits = 16; 176 pProps->fSigned = false; 177 break; 178 179 case AFMT_S16_BE: 180 pProps->cBits = 16; 181 pProps->fSigned = true; 182 #ifdef RT_LITTLE_ENDIAN 183 pProps->fSwapEndian = true; 184 #endif 219 185 break; 220 186 221 187 case AFMT_U16_BE: 222 *pFmt = PDMAUDIOFMT_U16; 223 if (pENDIANNESS) 224 *pENDIANNESS = PDMAUDIOENDIANNESS_BIG; 188 pProps->cBits = 16; 189 pProps->fSigned = false; 190 #ifdef RT_LITTLE_ENDIAN 191 pProps->fSwapEndian = true; 192 #endif 225 193 break; 226 194 … … 255 223 256 224 257 static int ossStreamOpen(const char *pszDev, int fOpen, POSSAUDIOSTREAMCFG p Req, POSSAUDIOSTREAMCFG pObt, int *phFile)258 { 259 int rc ;225 static int ossStreamOpen(const char *pszDev, int fOpen, POSSAUDIOSTREAMCFG pOSSReq, POSSAUDIOSTREAMCFG pOSSAcq, int *phFile) 226 { 227 int rc = VINF_SUCCESS; 260 228 261 229 int hFile = -1; … … 270 238 } 271 239 272 int iFormat = ossAudioFmtToOSS(pReq->enmFormat); 240 int iFormat; 241 switch (pOSSReq->Props.cBits) 242 { 243 case 8: 244 iFormat = pOSSReq->Props.fSigned ? AFMT_S8 : AFMT_U8; 245 break; 246 247 case 16: 248 iFormat = pOSSReq->Props.fSigned ? AFMT_S16_LE : AFMT_U16_LE; 249 break; 250 251 default: 252 rc = VERR_NOT_SUPPORTED; 253 break; 254 } 255 256 if (RT_FAILURE(rc)) 257 break; 258 273 259 if (ioctl(hFile, SNDCTL_DSP_SAMPLESIZE, &iFormat)) 274 260 { … … 278 264 } 279 265 280 int cChannels = p Req->cChannels;266 int cChannels = pOSSReq->Props.cChannels; 281 267 if (ioctl(hFile, SNDCTL_DSP_CHANNELS, &cChannels)) 282 268 { 283 LogRel(("OSS: Failed to set number of audio channels (%d): %s (%d)\n", pReq->cChannels, strerror(errno), errno)); 269 LogRel(("OSS: Failed to set number of audio channels (%RU8): %s (%d)\n", 270 pOSSReq->Props.cChannels, strerror(errno), errno)); 284 271 rc = RTErrConvertFromErrno(errno); 285 272 break; 286 273 } 287 274 288 int freq = p Req->uFreq;275 int freq = pOSSReq->Props.uHz; 289 276 if (ioctl(hFile, SNDCTL_DSP_SPEED, &freq)) 290 277 { 291 LogRel(("OSS: Failed to set audio frequency (%dHZ): %s (%d)\n", p Req->uFreq, strerror(errno), errno));278 LogRel(("OSS: Failed to set audio frequency (%dHZ): %s (%d)\n", pOSSReq->Props.uHz, strerror(errno), errno)); 292 279 rc = RTErrConvertFromErrno(errno); 293 280 break; … … 308 295 309 296 LogRel2(("OSS: Requested %RU16 %s fragments, %RU32 bytes each\n", 310 p Req->cFragments, fIn ? "input" : "output", pReq->cbFragmentSize));311 312 int mmmmssss = (p Req->cFragments << 16) | lsbindex(pReq->cbFragmentSize);297 pOSSReq->cFragments, fIn ? "input" : "output", pOSSReq->cbFragmentSize)); 298 299 int mmmmssss = (pOSSReq->cFragments << 16) | lsbindex(pOSSReq->cbFragmentSize); 313 300 if (ioctl(hFile, SNDCTL_DSP_SETFRAGMENT, &mmmmssss)) 314 301 { 315 302 LogRel(("OSS: Failed to set %RU16 fragments to %RU32 bytes each: %s (%d)\n", 316 p Req->cFragments, pReq->cbFragmentSize, strerror(errno), errno));303 pOSSReq->cFragments, pOSSReq->cbFragmentSize, strerror(errno), errno)); 317 304 rc = RTErrConvertFromErrno(errno); 318 305 break; … … 327 314 } 328 315 329 rc = ossOSSToAudio Fmt(iFormat, &pObt->enmFormat, &pObt->enmENDIANNESS);316 rc = ossOSSToAudioProps(iFormat, &pOSSAcq->Props); 330 317 if (RT_SUCCESS(rc)) 331 318 { 332 pObt->cChannels = cChannels; 333 pObt->uFreq = freq; 334 pObt->cFragments = abinfo.fragstotal; 335 pObt->cbFragmentSize = abinfo.fragsize; 319 pOSSAcq->Props.cChannels = cChannels; 320 pOSSAcq->Props.uHz = freq; 321 pOSSAcq->Props.cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pOSSAcq->Props.cBits, pOSSAcq->Props.cChannels); 322 323 pOSSAcq->cFragments = abinfo.fragstotal; 324 pOSSAcq->cbFragmentSize = abinfo.fragsize; 336 325 337 326 LogRel2(("OSS: Got %RU16 %s fragments, %RU32 bytes each\n", 338 pO bt->cFragments, fIn ? "input" : "output", pObt->cbFragmentSize));327 pOSSAcq->cFragments, fIn ? "input" : "output", pOSSAcq->cbFragmentSize)); 339 328 340 329 *phFile = hFile; … … 351 340 352 341 353 static int ossControlStreamIn(/*PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd*/ void)342 static int ossControlStreamIn(/*PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd*/ void) 354 343 { 355 344 /** @todo Nothing to do here right now!? */ … … 359 348 360 349 361 static int ossControlStreamOut(PPDMAUDIO STREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)362 { 363 POSSAUDIOSTREAM OUT pStreamOut = (POSSAUDIOSTREAMOUT)pStream;350 static int ossControlStreamOut(PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 351 { 352 POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream; 364 353 365 354 int rc = VINF_SUCCESS; … … 370 359 case PDMAUDIOSTREAMCMD_RESUME: 371 360 { 372 DrvAudioHlpClearBuf(&pStreamO ut->Props, pStreamOut->pvBuf, pStreamOut->cbBuf,373 PDMAUDIOPCMPROPS_B2S(&pStreamO ut->Props, pStreamOut->cbBuf));361 DrvAudioHlpClearBuf(&pStreamOSS->pCfg->Props, pStreamOSS->pvBuf, pStreamOSS->cbBuf, 362 PDMAUDIOPCMPROPS_B2S(&pStreamOSS->pCfg->Props, pStreamOSS->cbBuf)); 374 363 375 364 int mask = PCM_ENABLE_OUTPUT; 376 if (ioctl(pStreamO ut->hFile, SNDCTL_DSP_SETTRIGGER, &mask) < 0)365 if (ioctl(pStreamOSS->hFile, SNDCTL_DSP_SETTRIGGER, &mask) < 0) 377 366 { 378 367 LogRel(("OSS: Failed to enable output stream: %s\n", strerror(errno))); … … 387 376 { 388 377 int mask = 0; 389 if (ioctl(pStreamO ut->hFile, SNDCTL_DSP_SETTRIGGER, &mask) < 0)378 if (ioctl(pStreamOSS->hFile, SNDCTL_DSP_SETTRIGGER, &mask) < 0) 390 379 { 391 380 LogRel(("OSS: Failed to disable output stream: %s\n", strerror(errno))); … … 402 391 } 403 392 404 LogFlowFuncLeaveRC(rc);405 393 return rc; 406 394 } … … 414 402 RT_NOREF(pInterface); 415 403 416 LogFlowFuncEnter();417 418 404 return VINF_SUCCESS; 419 405 } … … 423 409 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture} 424 410 */ 425 static DECLCALLBACK(int) drvHostOSSAudioStreamCapture(PPDMIHOSTAUDIO pInterface, 426 PPDMAUDIOSTREAM pStream,void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)427 { 428 RT_NOREF(pInterface , cbBuf, pvBuf);411 static DECLCALLBACK(int) drvHostOSSAudioStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 412 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 413 { 414 RT_NOREF(pInterface); 429 415 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 430 416 431 POSSAUDIOSTREAM IN pStreamOSS = (POSSAUDIOSTREAMIN)pStream;417 POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream; 432 418 433 419 int rc = VINF_SUCCESS; … … 501 487 502 488 503 static int ossDestroyStreamIn(PPDMAUDIO STREAM pStream)504 { 505 POSSAUDIOSTREAM IN pStrm = (POSSAUDIOSTREAMIN)pStream;489 static int ossDestroyStreamIn(PPDMAUDIOBACKENDSTREAM pStream) 490 { 491 POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream; 506 492 507 493 LogFlowFuncEnter(); 508 494 509 if (pStr m->pvBuf)510 { 511 Assert(pStr m->cbBuf);512 513 RTMemFree(pStr m->pvBuf);514 pStr m->pvBuf = NULL;515 } 516 517 pStr m->cbBuf = 0;518 519 ossStreamClose(&pStr m->hFile);495 if (pStreamOSS->pvBuf) 496 { 497 Assert(pStreamOSS->cbBuf); 498 499 RTMemFree(pStreamOSS->pvBuf); 500 pStreamOSS->pvBuf = NULL; 501 } 502 503 pStreamOSS->cbBuf = 0; 504 505 ossStreamClose(&pStreamOSS->hFile); 520 506 521 507 return VINF_SUCCESS; … … 523 509 524 510 525 static int ossDestroyStreamOut(PPDMAUDIOSTREAM pStream) 526 { 527 POSSAUDIOSTREAMOUT pStrm = (POSSAUDIOSTREAMOUT)pStream; 528 529 LogFlowFuncEnter(); 511 static int ossDestroyStreamOut(PPDMAUDIOBACKENDSTREAM pStream) 512 { 513 POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream; 530 514 531 515 #ifndef RT_OS_L4 532 if (pStr m->fMMIO)533 { 534 if (pStr m->pvBuf)535 { 536 Assert(pStr m->cbBuf);537 538 int rc2 = munmap(pStr m->pvBuf, pStrm->cbBuf);516 if (pStreamOSS->Out.fMMIO) 517 { 518 if (pStreamOSS->pvBuf) 519 { 520 Assert(pStreamOSS->cbBuf); 521 522 int rc2 = munmap(pStreamOSS->pvBuf, pStreamOSS->cbBuf); 539 523 if (rc2 == 0) 540 524 { 541 pStr m->pvBuf = NULL;542 pStr m->cbBuf = 0;543 544 pStr m->fMMIO= false;525 pStreamOSS->pvBuf = NULL; 526 pStreamOSS->cbBuf = 0; 527 528 pStreamOSS->Out.fMMIO = false; 545 529 } 546 530 else … … 551 535 { 552 536 #endif 553 if (pStr m->pvBuf)554 { 555 Assert(pStr m->cbBuf);556 557 RTMemFree(pStr m->pvBuf);558 pStr m->pvBuf = NULL;559 } 560 561 pStr m->cbBuf = 0;537 if (pStreamOSS->pvBuf) 538 { 539 Assert(pStreamOSS->cbBuf); 540 541 RTMemFree(pStreamOSS->pvBuf); 542 pStreamOSS->pvBuf = NULL; 543 } 544 545 pStreamOSS->cbBuf = 0; 562 546 #ifndef RT_OS_L4 563 547 } 564 548 #endif 565 549 566 ossStreamClose(&pStr m->hFile);550 ossStreamClose(&pStreamOSS->hFile); 567 551 568 552 return VINF_SUCCESS; … … 577 561 RT_NOREF(pInterface); 578 562 579 pBackendCfg->cbStreamIn = sizeof(OSSAUDIOSTREAM IN);580 pBackendCfg->cbStreamOut = sizeof(OSSAUDIOSTREAM OUT);563 pBackendCfg->cbStreamIn = sizeof(OSSAUDIOSTREAM); 564 pBackendCfg->cbStreamOut = sizeof(OSSAUDIOSTREAM); 581 565 582 566 int hFile = open("/dev/dsp", O_WRONLY | O_NONBLOCK, 0); … … 636 620 637 621 638 static int ossCreateStreamIn(PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 639 { 640 POSSAUDIOSTREAMIN pStrm = (POSSAUDIOSTREAMIN)pStream; 641 622 static int ossCreateStreamIn(POSSAUDIOSTREAM pStreamOSS, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 623 { 642 624 int rc; 625 643 626 int hFile = -1; 644 627 645 628 do 646 629 { 647 uint32_t cSamples; 648 649 OSSAUDIOSTREAMCFG reqStream, obtStream; 650 reqStream.enmFormat = pCfgReq->enmFormat; 651 reqStream.uFreq = pCfgReq->uHz; 652 reqStream.cChannels = pCfgReq->cChannels; 653 reqStream.cFragments = s_OSSConf.nfrags; 654 reqStream.cbFragmentSize = s_OSSConf.fragsize; 655 656 rc = ossStreamOpen(s_OSSConf.devpath_in, O_RDONLY | O_NONBLOCK, &reqStream, &obtStream, &hFile); 630 OSSAUDIOSTREAMCFG ossReq; 631 memcpy(&ossReq.Props, &pCfgReq->Props, sizeof(PDMAUDIOPCMPROPS)); 632 633 ossReq.cFragments = s_OSSConf.nfrags; 634 ossReq.cbFragmentSize = s_OSSConf.fragsize; 635 636 OSSAUDIOSTREAMCFG ossAcq; 637 638 rc = ossStreamOpen(s_OSSConf.devpath_in, O_RDONLY | O_NONBLOCK, &ossReq, &ossAcq, &hFile); 657 639 if (RT_SUCCESS(rc)) 658 640 { 659 pCfgAcq->enmFormat = obtStream.enmFormat; 660 pCfgAcq->uHz = obtStream.uFreq; 661 pCfgAcq->cChannels = obtStream.cChannels; 662 pCfgAcq->enmEndianness = obtStream.enmENDIANNESS; 663 664 rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &pStrm->Props); 641 memcpy(&pCfgAcq->Props, &ossAcq.Props, sizeof(PDMAUDIOPCMPROPS)); 642 643 if (ossAcq.cFragments * ossAcq.cbFragmentSize & pStreamOSS->uAlign) 644 { 645 LogRel(("OSS: Warning: Misaligned capturing buffer: Size = %zu, Alignment = %u\n", 646 ossAcq.cFragments * ossAcq.cbFragmentSize, pStreamOSS->uAlign + 1)); 647 } 648 649 uint32_t cSamples = PDMAUDIOSTREAMCFG_B2S(pCfgAcq, ossAcq.cFragments * ossAcq.cbFragmentSize); 650 if (!cSamples) 651 rc = VERR_INVALID_PARAMETER; 652 665 653 if (RT_SUCCESS(rc)) 666 654 { 667 if (obtStream.cFragments * obtStream.cbFragmentSize & pStrm->Props.uAlign) 668 { 669 LogRel(("OSS: Warning: Misaligned capturing buffer: Size = %zu, Alignment = %u\n", 670 obtStream.cFragments * obtStream.cbFragmentSize, pStrm->Props.uAlign + 1)); 671 } 672 673 cSamples = (obtStream.cFragments * obtStream.cbFragmentSize) >> pStrm->Props.cShift; 674 if (!cSamples) 675 rc = VERR_INVALID_PARAMETER; 676 } 677 678 if (RT_SUCCESS(rc)) 679 { 680 size_t cbSample = (1 << pStrm->Props.cShift); 681 682 size_t cbBuf = cSamples * cbSample; 655 size_t cbBuf = PDMAUDIOSTREAMCFG_S2B(pCfgAcq, cSamples); 683 656 void *pvBuf = RTMemAlloc(cbBuf); 684 657 if (!pvBuf) 685 658 { 686 LogRel(("OSS: Failed allocating capturing buffer with %RU32 samples (%zu bytes per sample)\n", 687 cSamples, cbSample)); 659 LogRel(("OSS: Failed allocating capturing buffer with (%zu bytes)\n", cbBuf)); 688 660 rc = VERR_NO_MEMORY; 689 break;690 661 } 691 662 692 pStr m->hFile = hFile;693 pStr m->pvBuf = pvBuf;694 pStr m->cbBuf = cbBuf;695 696 pCfgAcq->cSampleBuffer Size= cSamples;663 pStreamOSS->hFile = hFile; 664 pStreamOSS->pvBuf = pvBuf; 665 pStreamOSS->cbBuf = cbBuf; 666 667 pCfgAcq->cSampleBufferHint = cSamples; 697 668 } 698 669 } … … 708 679 709 680 710 static int ossCreateStreamOut(PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 711 { 712 POSSAUDIOSTREAMOUT pStrm = (POSSAUDIOSTREAMOUT)pStream; 713 681 static int ossCreateStreamOut(POSSAUDIOSTREAM pStreamOSS, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 682 { 714 683 int rc; 715 684 int hFile = -1; … … 720 689 721 690 OSSAUDIOSTREAMCFG reqStream, obtStream; 722 reqStream.enmFormat = pCfgReq->enmFormat; 723 reqStream.uFreq = pCfgReq->uHz;724 reqStream.cChannels = pCfgReq->cChannels; 691 692 memcpy(&reqStream.Props, &pCfgReq->Props, sizeof(PDMAUDIOPCMPROPS)); 693 725 694 reqStream.cFragments = s_OSSConf.nfrags; 726 695 reqStream.cbFragmentSize = s_OSSConf.fragsize; … … 729 698 if (RT_SUCCESS(rc)) 730 699 { 731 pCfgAcq->enmFormat = obtStream.enmFormat; 732 pCfgAcq->uHz = obtStream.uFreq; 733 pCfgAcq->cChannels = obtStream.cChannels; 734 pCfgAcq->enmEndianness = obtStream.enmENDIANNESS; 735 736 rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &pStrm->Props); 737 if (RT_SUCCESS(rc)) 738 { 739 cSamples = (obtStream.cFragments * obtStream.cbFragmentSize) >> pStrm->Props.cShift; 740 741 if (obtStream.cFragments * obtStream.cbFragmentSize & pStrm->Props.uAlign) 742 { 743 LogRel(("OSS: Warning: Misaligned playback buffer: Size = %zu, Alignment = %u\n", 744 obtStream.cFragments * obtStream.cbFragmentSize, pStrm->Props.uAlign + 1)); 745 } 700 memcpy(&pCfgAcq->Props, &obtStream.Props, sizeof(PDMAUDIOPCMPROPS)); 701 702 cSamples = PDMAUDIOSTREAMCFG_B2S(pCfgAcq, obtStream.cFragments * obtStream.cbFragmentSize); 703 704 if (obtStream.cFragments * obtStream.cbFragmentSize & pStreamOSS->uAlign) 705 { 706 LogRel(("OSS: Warning: Misaligned playback buffer: Size = %zu, Alignment = %u\n", 707 obtStream.cFragments * obtStream.cbFragmentSize, pStreamOSS->uAlign + 1)); 746 708 } 747 709 } … … 749 711 if (RT_SUCCESS(rc)) 750 712 { 751 pStrm->fMMIO = false; 752 753 size_t cbSample = (1 << pStrm->Props.cShift); 754 755 size_t cbSamples = cSamples * cbSample; 756 Assert(cbSamples); 713 pStreamOSS->Out.fMMIO = false; 714 715 size_t cbBuf = PDMAUDIOSTREAMCFG_S2B(pCfgAcq, cSamples); 716 Assert(cbBuf); 757 717 758 718 #ifndef RT_OS_L4 759 719 if (s_OSSConf.try_mmap) 760 720 { 761 pStr m->pvBuf = mmap(0, cbSamples, PROT_READ | PROT_WRITE, MAP_SHARED, hFile, 0);762 if (pStr m->pvBuf == MAP_FAILED)721 pStreamOSS->pvBuf = mmap(0, cbBuf, PROT_READ | PROT_WRITE, MAP_SHARED, hFile, 0); 722 if (pStreamOSS->pvBuf == MAP_FAILED) 763 723 { 764 LogRel(("OSS: Failed to memory map %zu bytes of playback buffer: %s\n", cb Samples, strerror(errno)));724 LogRel(("OSS: Failed to memory map %zu bytes of playback buffer: %s\n", cbBuf, strerror(errno))); 765 725 rc = RTErrConvertFromErrno(errno); 766 726 break; … … 786 746 else 787 747 { 788 pStr m->fMMIO = true;748 pStreamOSS->Out.fMMIO = true; 789 749 LogRel(("OSS: Using MMIO\n")); 790 750 } … … 793 753 if (RT_FAILURE(rc)) 794 754 { 795 int rc2 = munmap(pStr m->pvBuf, cbSamples);755 int rc2 = munmap(pStreamOSS->pvBuf, cbBuf); 796 756 if (rc2) 797 757 LogRel(("OSS: Failed to memory unmap playback buffer: %s\n", strerror(errno))); … … 804 764 /* Memory mapping failed above? Try allocating an own buffer. */ 805 765 #ifndef RT_OS_L4 806 if (!pStr m->fMMIO)807 { 808 #endif 809 void *pvBuf = RTMemAlloc(cb Samples);766 if (!pStreamOSS->Out.fMMIO) 767 { 768 #endif 769 void *pvBuf = RTMemAlloc(cbBuf); 810 770 if (!pvBuf) 811 771 { 812 LogRel(("OSS: Failed allocating playback buffer with %RU32 samples (%zu bytes)\n", cSamples, cb Samples));772 LogRel(("OSS: Failed allocating playback buffer with %RU32 samples (%zu bytes)\n", cSamples, cbBuf)); 813 773 rc = VERR_NO_MEMORY; 814 774 break; 815 775 } 816 776 817 pStr m->hFile = hFile;818 pStr m->pvBuf = pvBuf;819 pStr m->cbBuf = cbSamples;777 pStreamOSS->hFile = hFile; 778 pStreamOSS->pvBuf = pvBuf; 779 pStreamOSS->cbBuf = cbBuf; 820 780 #ifndef RT_OS_L4 821 781 } 822 782 #endif 823 pCfgAcq->cSampleBuffer Size= cSamples;783 pCfgAcq->cSampleBufferHint = cSamples; 824 784 } 825 785 … … 838 798 */ 839 799 static DECLCALLBACK(int) drvHostOSSAudioStreamPlay(PPDMIHOSTAUDIO pInterface, 840 PPDMAUDIO STREAM pStream, const void *pvBuf, uint32_t cbBuf,800 PPDMAUDIOBACKENDSTREAM pStream, const void *pvBuf, uint32_t cbBuf, 841 801 uint32_t *pcbWritten) 842 802 { 843 RT_NOREF(pInterface , cbBuf, pvBuf);803 RT_NOREF(pInterface); 844 804 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 845 805 846 POSSAUDIOSTREAM OUT pStreamOSS = (POSSAUDIOSTREAMOUT)pStream;806 POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream; 847 807 848 808 int rc = VINF_SUCCESS; … … 855 815 do 856 816 { 857 uint32_t cbAvail = PDMAUDIOPCMPROPS_S2B(&pStreamOSS->Props, cbBuf);858 uint32_t cbTo Read;817 uint32_t cbAvail = cbBuf; 818 uint32_t cbToWrite; 859 819 860 820 #ifndef RT_OS_L4 861 if (pStreamOSS-> fMMIO)821 if (pStreamOSS->Out.fMMIO) 862 822 { 863 823 /* Get current playback pointer. */ … … 881 841 Assert(cbData >= 0); 882 842 883 cbTo Read= RT_MIN((unsigned)cbData, cbAvail);843 cbToWrite = RT_MIN((unsigned)cbData, cbAvail); 884 844 } 885 845 else … … 909 869 } 910 870 911 cbTo Read= RT_MIN(unsigned(abinfo.fragments * abinfo.fragsize), cbAvail);871 cbToWrite = RT_MIN(unsigned(abinfo.fragments * abinfo.fragsize), cbAvail); 912 872 #ifndef RT_OS_L4 913 873 } 914 874 #endif 915 while (cbToRead) 916 { 917 uint32_t cbRead = cbToRead; 918 919 memcpy(pStreamOSS->pvBuf, pvBuf, cbRead); 920 921 uint32_t cbChunk = cbRead; 875 cbToWrite = RT_MIN(cbToWrite, pStreamOSS->cbBuf); 876 877 while (cbToWrite) 878 { 879 uint32_t cbWritten = cbToWrite; 880 881 memcpy(pStreamOSS->pvBuf, pvBuf, cbWritten); 882 883 uint32_t cbChunk = cbWritten; 922 884 uint32_t cbChunkOff = 0; 923 885 while (cbChunk) … … 932 894 } 933 895 934 if (cbChunkWritten & pStreamOSS-> Props.uAlign)896 if (cbChunkWritten & pStreamOSS->uAlign) 935 897 { 936 898 LogRel(("OSS: Misaligned write (written %z, expected %RU32)\n", cbChunkWritten, cbChunk)); … … 939 901 940 902 cbChunkOff += (uint32_t)cbChunkWritten; 941 Assert(cbChunkOff <= cb Read);903 Assert(cbChunkOff <= cbWritten); 942 904 Assert(cbChunk >= (uint32_t)cbChunkWritten); 943 905 cbChunk -= (uint32_t)cbChunkWritten; 944 906 } 945 907 946 Assert(cbTo Read >= cbRead);947 cbTo Read -= cbRead;948 cbWrittenTotal += cb Read;908 Assert(cbToWrite >= cbWritten); 909 cbToWrite -= cbWritten; 910 cbWrittenTotal += cbWritten; 949 911 } 950 912 951 913 #ifndef RT_OS_L4 952 914 /* Update read pointer. */ 953 if (pStreamOSS-> fMMIO)915 if (pStreamOSS->Out.fMMIO) 954 916 pStreamOSS->old_optr = cntinfo.ptr; 955 917 #endif … … 991 953 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate} 992 954 */ 993 static DECLCALLBACK(int) drvHostOSSAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream,955 static DECLCALLBACK(int) drvHostOSSAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 994 956 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 995 957 { … … 999 961 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER); 1000 962 963 POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream; 964 1001 965 int rc; 1002 966 if (pCfgReq->enmDir == PDMAUDIODIR_IN) 1003 rc = ossCreateStreamIn (pStream, pCfgReq, pCfgAcq);967 rc = ossCreateStreamIn (pStreamOSS, pCfgReq, pCfgAcq); 1004 968 else 1005 rc = ossCreateStreamOut(pStream, pCfgReq, pCfgAcq); 969 rc = ossCreateStreamOut(pStreamOSS, pCfgReq, pCfgAcq); 970 971 if (RT_SUCCESS(rc)) 972 { 973 pStreamOSS->pCfg = DrvAudioHlpStreamCfgDup(pCfgAcq); 974 if (!pStreamOSS->pCfg) 975 rc = VERR_NO_MEMORY; 976 } 1006 977 1007 978 return rc; … … 1012 983 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy} 1013 984 */ 1014 static DECLCALLBACK(int) drvHostOSSAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)985 static DECLCALLBACK(int) drvHostOSSAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 1015 986 { 1016 987 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 1017 988 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1018 989 990 POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream; 991 992 if (!pStreamOSS->pCfg) /* Not (yet) configured? Skip. */ 993 return VINF_SUCCESS; 994 1019 995 int rc; 1020 if (pStream ->enmDir == PDMAUDIODIR_IN)996 if (pStreamOSS->pCfg->enmDir == PDMAUDIODIR_IN) 1021 997 rc = ossDestroyStreamIn(pStream); 1022 998 else 1023 999 rc = ossDestroyStreamOut(pStream); 1024 1000 1001 if (RT_SUCCESS(rc)) 1002 { 1003 DrvAudioHlpStreamCfgFree(pStreamOSS->pCfg); 1004 pStreamOSS->pCfg = NULL; 1005 } 1006 1025 1007 return rc; 1026 1008 } … … 1030 1012 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl} 1031 1013 */ 1032 static DECLCALLBACK(int) drvHostOSSAudioStreamControl(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream,1014 static DECLCALLBACK(int) drvHostOSSAudioStreamControl(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 1033 1015 PDMAUDIOSTREAMCMD enmStreamCmd) 1034 1016 { … … 1036 1018 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1037 1019 1038 Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST); 1020 POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream; 1021 1022 if (!pStreamOSS->pCfg) /* Not (yet) configured? Skip. */ 1023 return VINF_SUCCESS; 1039 1024 1040 1025 int rc; 1041 if (pStream ->enmDir == PDMAUDIODIR_IN)1026 if (pStreamOSS->pCfg->enmDir == PDMAUDIODIR_IN) 1042 1027 rc = ossControlStreamIn(/*pInterface, pStream, enmStreamCmd*/); 1043 1028 else 1044 rc = ossControlStreamOut(pStream , enmStreamCmd);1029 rc = ossControlStreamOut(pStreamOSS, enmStreamCmd); 1045 1030 1046 1031 return rc; … … 1051 1036 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate} 1052 1037 */ 1053 static DECLCALLBACK(int) drvHostOSSAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)1038 static DECLCALLBACK(int) drvHostOSSAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 1054 1039 { 1055 1040 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 1066 1051 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus} 1067 1052 */ 1068 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostOSSAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)1053 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostOSSAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 1069 1054 { 1070 1055 RT_NOREF(pInterface); 1071 RT_NOREF(pStream); 1056 1057 POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream; 1072 1058 1073 1059 PDMAUDIOSTRMSTS strmSts = PDMAUDIOSTRMSTS_FLAG_INITIALIZED 1074 1060 | PDMAUDIOSTRMSTS_FLAG_ENABLED; 1075 1061 1076 strmSts |= pStream ->enmDir == PDMAUDIODIR_IN1062 strmSts |= pStreamOSS->pCfg->enmDir == PDMAUDIODIR_IN 1077 1063 ? PDMAUDIOSTRMSTS_FLAG_DATA_READABLE 1078 1064 : PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE; -
trunk/src/VBox/Devices/Audio/DrvHostPulseAudio.cpp
r65565 r65624 96 96 typedef struct PULSEAUDIOSTREAM 97 97 { 98 /** Associated host input/output stream. 99 * Note: Always must come first! */ 100 PDMAUDIOSTREAM Stream; 101 PDMAUDIOPCMPROPS Props; 98 /** The stream's acquired configuration. */ 99 PPDMAUDIOSTREAMCFG pCfg; 102 100 /** Pointer to driver instance. */ 103 101 PDRVHOSTPULSEAUDIO pDrv; 104 102 /** Pointer to opaque PulseAudio stream. */ 105 pa_stream *p PAStream;103 pa_stream *pStream; 106 104 /** Pulse sample format and attribute specification. */ 107 105 pa_sample_spec SampleSpec; … … 199 197 200 198 201 static pa_sample_format_t paFmtToPulse(PDMAUDIOFMT fmt) 202 { 203 switch (fmt) 204 { 205 case PDMAUDIOFMT_U8: 206 return PA_SAMPLE_U8; 207 208 case PDMAUDIOFMT_S16: 209 return PA_SAMPLE_S16LE; 199 static pa_sample_format_t paAudioPropsToPulse(PPDMAUDIOPCMPROPS pProps) 200 { 201 switch (pProps->cBits) 202 { 203 case 8: 204 if (!pProps->fSigned) 205 return PA_SAMPLE_U8; 206 207 case 16: 208 if (pProps->fSigned) 209 return PA_SAMPLE_S16LE; 210 210 211 211 #ifdef PA_SAMPLE_S32LE 212 case PDMAUDIOFMT_S32: 213 return PA_SAMPLE_S32LE; 212 case 32: 213 if (pProps->fSigned) 214 return PA_SAMPLE_S32LE; 214 215 #endif 215 216 default: … … 217 218 } 218 219 219 AssertMsgFailed(("Format %ld not supported\n", fmt)); 220 return PA_SAMPLE_U8; 221 } 222 223 224 static int paPulseToFmt(pa_sample_format_t pulsefmt, 225 PDMAUDIOFMT *pFmt, PDMAUDIOENDIANNESS *pEndianness) 220 AssertMsgFailed(("%RU8%s not supported\n", pProps->cBits, pProps->fSigned ? "S" : "U")); 221 return PA_SAMPLE_INVALID; 222 } 223 224 225 static int paPulseToAudioProps(pa_sample_format_t pulsefmt, PPDMAUDIOPCMPROPS pProps) 226 226 { 227 227 switch (pulsefmt) 228 228 { 229 229 case PA_SAMPLE_U8: 230 *pFmt = PDMAUDIOFMT_U8;231 *pEndianness = PDMAUDIOENDIANNESS_LITTLE;230 pProps->cBits = 8; 231 pProps->fSigned = false; 232 232 break; 233 233 234 234 case PA_SAMPLE_S16LE: 235 *pFmt = PDMAUDIOFMT_S16;236 *pEndianness = PDMAUDIOENDIANNESS_LITTLE;235 pProps->cBits = 16; 236 pProps->fSigned = true; 237 237 break; 238 238 239 239 case PA_SAMPLE_S16BE: 240 *pFmt = PDMAUDIOFMT_S16; 241 *pEndianness = PDMAUDIOENDIANNESS_BIG; 240 pProps->cBits = 16; 241 pProps->fSigned = true; 242 /** @todo Handle Endianess. */ 242 243 break; 243 244 244 245 #ifdef PA_SAMPLE_S32LE 245 246 case PA_SAMPLE_S32LE: 246 *pFmt = PDMAUDIOFMT_S32;247 *pEndianness = PDMAUDIOENDIANNESS_LITTLE;247 pProps->cBits = 32; 248 pProps->fSigned = true; 248 249 break; 249 250 #endif … … 251 252 #ifdef PA_SAMPLE_S32BE 252 253 case PA_SAMPLE_S32BE: 253 *pFmt = PDMAUDIOFMT_S32; 254 *pEndianness = PDMAUDIOENDIANNESS_BIG; 254 pProps->cBits = 32; 255 pProps->fSigned = true; 256 /** @todo Handle Endianess. */ 255 257 break; 256 258 #endif … … 649 651 650 652 651 static int paCreateStreamOut(PPDMIHOSTAUDIO pInterface, 652 PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 653 { 654 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 655 PPULSEAUDIOSTREAM pStreamPA = (PPULSEAUDIOSTREAM)pStream; 656 657 LogFlowFuncEnter(); 658 653 static int paCreateStreamOut(PDRVHOSTPULSEAUDIO pThis, PPULSEAUDIOSTREAM pStreamPA, 654 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 655 { 659 656 pStreamPA->pDrainOp = NULL; 660 657 661 pStreamPA->SampleSpec.format = pa FmtToPulse(pCfgReq->enmFormat);662 pStreamPA->SampleSpec.rate = pCfgReq-> uHz;663 pStreamPA->SampleSpec.channels = pCfgReq-> cChannels;658 pStreamPA->SampleSpec.format = paAudioPropsToPulse(&pCfgReq->Props); 659 pStreamPA->SampleSpec.rate = pCfgReq->Props.uHz; 660 pStreamPA->SampleSpec.channels = pCfgReq->Props.cChannels; 664 661 665 662 /* Note that setting maxlength to -1 does not work on PulseAudio servers … … 672 669 673 670 /* Note that the struct BufAttr is updated to the obtained values after this call! */ 674 int rc = paStreamOpen(pThis, false /* fIn */, "PulseAudio (Out)", &pStreamPA->SampleSpec, &pStreamPA->BufAttr, &pStreamPA->pPAStream); 671 int rc = paStreamOpen(pThis, false /* fIn */, "PulseAudio (Out)", 672 &pStreamPA->SampleSpec, &pStreamPA->BufAttr, &pStreamPA->pStream); 675 673 if (RT_FAILURE(rc)) 676 674 return rc; 677 675 678 rc = paPulseToFmt(pStreamPA->SampleSpec.format, 679 &pCfgAcq->enmFormat, &pCfgAcq->enmEndianness); 676 rc = paPulseToAudioProps(pStreamPA->SampleSpec.format, &pCfgAcq->Props); 680 677 if (RT_FAILURE(rc)) 681 678 { … … 684 681 } 685 682 686 pCfgAcq->uHz = pStreamPA->SampleSpec.rate; 687 pCfgAcq->cChannels = pStreamPA->SampleSpec.channels; 688 689 rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &pStreamPA->Props); 690 if (RT_SUCCESS(rc)) 691 { 692 uint32_t cbBuf = RT_MIN(pStreamPA->BufAttr.tlength * 2, 693 pStreamPA->BufAttr.maxlength); /** @todo Make this configurable! */ 694 if (cbBuf) 695 { 696 pStreamPA->pDrv = pThis; 697 698 pCfgAcq->cSampleBufferSize = PDMAUDIOPCMPROPS_B2S(&pStreamPA->Props, cbBuf); 699 } 700 else 701 rc = VERR_INVALID_PARAMETER; 702 } 703 704 LogFlowFuncLeaveRC(rc); 683 pCfgAcq->Props.uHz = pStreamPA->SampleSpec.rate; 684 pCfgAcq->Props.cChannels = pStreamPA->SampleSpec.channels; 685 pCfgAcq->Props.cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfgAcq->Props.cBits, pCfgAcq->Props.cChannels); 686 687 uint32_t cbBuf = RT_MIN(pStreamPA->BufAttr.tlength * 2, 688 pStreamPA->BufAttr.maxlength); /** @todo Make this configurable! */ 689 if (cbBuf) 690 { 691 pCfgAcq->cSampleBufferHint = PDMAUDIOSTREAMCFG_B2S(pCfgAcq, cbBuf); 692 693 pStreamPA->pDrv = pThis; 694 } 695 else 696 rc = VERR_INVALID_PARAMETER; 697 705 698 return rc; 706 699 } 707 700 708 701 709 static int paCreateStreamIn(PPDMIHOSTAUDIO pInterface, 710 PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 711 { 712 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 713 PPULSEAUDIOSTREAM pStreamPA = (PPULSEAUDIOSTREAM)pStream; 714 715 pStreamPA->SampleSpec.format = paFmtToPulse(pCfgReq->enmFormat); 716 pStreamPA->SampleSpec.rate = pCfgReq->uHz; 717 pStreamPA->SampleSpec.channels = pCfgReq->cChannels; 702 static int paCreateStreamIn(PDRVHOSTPULSEAUDIO pThis, PPULSEAUDIOSTREAM pStreamPA, 703 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 704 { 705 pStreamPA->SampleSpec.format = paAudioPropsToPulse(&pCfgReq->Props); 706 pStreamPA->SampleSpec.rate = pCfgReq->Props.uHz; 707 pStreamPA->SampleSpec.channels = pCfgReq->Props.cChannels; 718 708 719 709 /** @todo Check these values! */ … … 723 713 /* Note: Other members of BufAttr are ignored for record streams. */ 724 714 int rc = paStreamOpen(pThis, true /* fIn */, "PulseAudio (In)", &pStreamPA->SampleSpec, &pStreamPA->BufAttr, 725 &pStreamPA->p PAStream);715 &pStreamPA->pStream); 726 716 if (RT_FAILURE(rc)) 727 717 return rc; 728 718 729 rc = paPulseTo Fmt(pStreamPA->SampleSpec.format, &pCfgAcq->enmFormat, &pCfgAcq->enmEndianness);719 rc = paPulseToAudioProps(pStreamPA->SampleSpec.format, &pCfgAcq->Props); 730 720 if (RT_FAILURE(rc)) 731 721 { … … 734 724 } 735 725 736 rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &pStreamPA->Props); 737 if (RT_SUCCESS(rc)) 738 { 739 pStreamPA->pDrv = pThis; 740 pStreamPA->pu8PeekBuf = NULL; 741 742 pCfgAcq->uHz = pStreamPA->SampleSpec.rate; 743 pCfgAcq->cChannels = pStreamPA->SampleSpec.channels; 744 pCfgAcq->cSampleBufferSize = PDMAUDIOPCMPROPS_B2S(&pStreamPA->Props, 745 RT_MIN(pStreamPA->BufAttr.fragsize * 10, pStreamPA->BufAttr.maxlength)); 746 } 726 pStreamPA->pDrv = pThis; 727 pStreamPA->pu8PeekBuf = NULL; 728 729 pCfgAcq->Props.uHz = pStreamPA->SampleSpec.rate; 730 pCfgAcq->Props.cChannels = pStreamPA->SampleSpec.channels; 731 pCfgAcq->cSampleBufferHint = PDMAUDIOSTREAMCFG_B2S(pCfgAcq, 732 RT_MIN(pStreamPA->BufAttr.fragsize * 10, pStreamPA->BufAttr.maxlength)); 747 733 748 734 LogFlowFuncLeaveRC(rc); … … 755 741 */ 756 742 static DECLCALLBACK(int) drvHostPulseAudioStreamCapture(PPDMIHOSTAUDIO pInterface, 757 PPDMAUDIO STREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)743 PPDMAUDIOBACKENDSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 758 744 { 759 745 RT_NOREF(pvBuf, cbBuf); … … 769 755 /* We should only call pa_stream_readable_size() once and trust the first value. */ 770 756 pa_threaded_mainloop_lock(pThis->pMainLoop); 771 size_t cbAvail = pa_stream_readable_size(pStreamPA->p PAStream);757 size_t cbAvail = pa_stream_readable_size(pStreamPA->pStream); 772 758 pa_threaded_mainloop_unlock(pThis->pMainLoop); 773 759 … … 806 792 { 807 793 pa_threaded_mainloop_lock(pThis->pMainLoop); 808 pa_stream_peek(pStreamPA->p PAStream,794 pa_stream_peek(pStreamPA->pStream, 809 795 (const void**)&pStreamPA->pu8PeekBuf, &pStreamPA->cbPeekBuf); 810 796 pa_threaded_mainloop_unlock(pThis->pMainLoop); … … 849 835 { 850 836 pa_threaded_mainloop_lock(pThis->pMainLoop); 851 pa_stream_drop(pStreamPA->p PAStream);837 pa_stream_drop(pStreamPA->pStream); 852 838 pa_threaded_mainloop_unlock(pThis->pMainLoop); 853 839 … … 870 856 */ 871 857 static DECLCALLBACK(int) drvHostPulseAudioStreamPlay(PPDMIHOSTAUDIO pInterface, 872 PPDMAUDIO STREAM pStream, const void *pvBuf, uint32_t cbBuf,858 PPDMAUDIOBACKENDSTREAM pStream, const void *pvBuf, uint32_t cbBuf, 873 859 uint32_t *pcbWritten) 874 860 { … … 891 877 do 892 878 { 893 size_t cbWriteable = pa_stream_writable_size(pPAStream->p PAStream);879 size_t cbWriteable = pa_stream_writable_size(pPAStream->pStream); 894 880 if (cbWriteable == (size_t)-1) 895 881 { … … 904 890 { 905 891 cbWritten = cbToWrite; 906 if (pa_stream_write(pPAStream->p PAStream, (uint8_t *)pvBuf + cbWrittenTotal, cbWritten, NULL /* Cleanup callback */,892 if (pa_stream_write(pPAStream->pStream, (uint8_t *)pvBuf + cbWrittenTotal, cbWritten, NULL /* Cleanup callback */, 907 893 0, PA_SEEK_RELATIVE) < 0) 908 894 { … … 1120 1106 1121 1107 1122 static int paDestroyStreamIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 1123 { 1124 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 1125 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1126 1127 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 1128 PPULSEAUDIOSTREAM pStrm = (PPULSEAUDIOSTREAM)pStream; 1129 1108 static int paDestroyStreamIn(PDRVHOSTPULSEAUDIO pThis, PPULSEAUDIOSTREAM pStreamPA) 1109 { 1130 1110 LogFlowFuncEnter(); 1131 1111 1132 if (pStr m->pPAStream)1112 if (pStreamPA->pStream) 1133 1113 { 1134 1114 pa_threaded_mainloop_lock(pThis->pMainLoop); 1135 1115 1136 pa_stream_disconnect(pStr m->pPAStream);1137 pa_stream_unref(pStr m->pPAStream);1138 1139 pStr m->pPAStream = NULL;1116 pa_stream_disconnect(pStreamPA->pStream); 1117 pa_stream_unref(pStreamPA->pStream); 1118 1119 pStreamPA->pStream = NULL; 1140 1120 1141 1121 pa_threaded_mainloop_unlock(pThis->pMainLoop); … … 1146 1126 1147 1127 1148 static int paDestroyStreamOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 1149 { 1150 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 1151 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1152 1153 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 1154 PPULSEAUDIOSTREAM pStrm = (PPULSEAUDIOSTREAM)pStream; 1155 1156 LogFlowFuncEnter(); 1157 1158 if (pStrm->pPAStream) 1128 static int paDestroyStreamOut(PDRVHOSTPULSEAUDIO pThis, PPULSEAUDIOSTREAM pStreamPA) 1129 { 1130 if (pStreamPA->pStream) 1159 1131 { 1160 1132 pa_threaded_mainloop_lock(pThis->pMainLoop); 1161 1133 1162 1134 /* Make sure to cancel a pending draining operation, if any. */ 1163 if (pStr m->pDrainOp)1164 { 1165 pa_operation_cancel(pStr m->pDrainOp);1166 pStr m->pDrainOp = NULL;1167 } 1168 1169 pa_stream_disconnect(pStr m->pPAStream);1170 pa_stream_unref(pStr m->pPAStream);1171 1172 pStr m->pPAStream = NULL;1135 if (pStreamPA->pDrainOp) 1136 { 1137 pa_operation_cancel(pStreamPA->pDrainOp); 1138 pStreamPA->pDrainOp = NULL; 1139 } 1140 1141 pa_stream_disconnect(pStreamPA->pStream); 1142 pa_stream_unref(pStreamPA->pStream); 1143 1144 pStreamPA->pStream = NULL; 1173 1145 1174 1146 pa_threaded_mainloop_unlock(pThis->pMainLoop); … … 1179 1151 1180 1152 1181 static int paControlStreamOut(PPDMIHOSTAUDIO pInterface, 1182 PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 1183 { 1184 AssertPtrReturn(pInterface , VERR_INVALID_POINTER); 1185 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1186 1187 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 1188 PPULSEAUDIOSTREAM pStrm = (PPULSEAUDIOSTREAM)pStream; 1189 1153 static int paControlStreamOut(PDRVHOSTPULSEAUDIO pThis, PPULSEAUDIOSTREAM pStreamPA, PDMAUDIOSTREAMCMD enmStreamCmd) 1154 { 1190 1155 int rc = VINF_SUCCESS; 1191 1192 LogFlowFunc(("enmStreamCmd=%ld\n", enmStreamCmd));1193 1156 1194 1157 switch (enmStreamCmd) … … 1199 1162 pa_threaded_mainloop_lock(pThis->pMainLoop); 1200 1163 1201 if ( pStr m->pDrainOp1202 && pa_operation_get_state(pStr m->pDrainOp) != PA_OPERATION_DONE)1164 if ( pStreamPA->pDrainOp 1165 && pa_operation_get_state(pStreamPA->pDrainOp) != PA_OPERATION_DONE) 1203 1166 { 1204 pa_operation_cancel(pStr m->pDrainOp);1205 pa_operation_unref(pStr m->pDrainOp);1206 1207 pStr m->pDrainOp = NULL;1167 pa_operation_cancel(pStreamPA->pDrainOp); 1168 pa_operation_unref(pStreamPA->pDrainOp); 1169 1170 pStreamPA->pDrainOp = NULL; 1208 1171 } 1209 1172 else 1210 1173 { 1211 rc = paWaitFor(pThis, pa_stream_cork(pStr m->pPAStream, 0, paStreamCbSuccess, pStrm));1174 rc = paWaitFor(pThis, pa_stream_cork(pStreamPA->pStream, 0, paStreamCbSuccess, pStreamPA)); 1212 1175 } 1213 1176 … … 1222 1185 * Note that we must return immediately from here! */ 1223 1186 pa_threaded_mainloop_lock(pThis->pMainLoop); 1224 if (!pStr m->pDrainOp)1187 if (!pStreamPA->pDrainOp) 1225 1188 { 1226 rc = paWaitFor(pThis, pa_stream_trigger(pStr m->pPAStream, paStreamCbSuccess, pStrm));1189 rc = paWaitFor(pThis, pa_stream_trigger(pStreamPA->pStream, paStreamCbSuccess, pStreamPA)); 1227 1190 if (RT_SUCCESS(rc)) 1228 pStr m->pDrainOp = pa_stream_drain(pStrm->pPAStream, paStreamCbDrain, pStrm);1191 pStreamPA->pDrainOp = pa_stream_drain(pStreamPA->pStream, paStreamCbDrain, pStreamPA); 1229 1192 } 1230 1193 pa_threaded_mainloop_unlock(pThis->pMainLoop); … … 1243 1206 1244 1207 1245 static int paControlStreamIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, 1246 PDMAUDIOSTREAMCMD enmStreamCmd) 1247 { 1248 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 1249 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1250 1251 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 1252 PPULSEAUDIOSTREAM pStrm = (PPULSEAUDIOSTREAM)pStream; 1253 1208 static int paControlStreamIn(PDRVHOSTPULSEAUDIO pThis, PPULSEAUDIOSTREAM pStreamPA, PDMAUDIOSTREAMCMD enmStreamCmd) 1209 { 1254 1210 int rc = VINF_SUCCESS; 1255 1211 … … 1262 1218 { 1263 1219 pa_threaded_mainloop_lock(pThis->pMainLoop); 1264 rc = paWaitFor(pThis, pa_stream_cork(pStr m->pPAStream, 0 /* Play / resume */, paStreamCbSuccess, pStrm));1220 rc = paWaitFor(pThis, pa_stream_cork(pStreamPA->pStream, 0 /* Play / resume */, paStreamCbSuccess, pStreamPA)); 1265 1221 pa_threaded_mainloop_unlock(pThis->pMainLoop); 1266 1222 break; … … 1271 1227 { 1272 1228 pa_threaded_mainloop_lock(pThis->pMainLoop); 1273 if (pStr m->pu8PeekBuf) /* Do we need to drop the peek buffer?*/1229 if (pStreamPA->pu8PeekBuf) /* Do we need to drop the peek buffer?*/ 1274 1230 { 1275 pa_stream_drop(pStr m->pPAStream);1276 pStr m->pu8PeekBuf = NULL;1231 pa_stream_drop(pStreamPA->pStream); 1232 pStreamPA->pu8PeekBuf = NULL; 1277 1233 } 1278 1234 1279 rc = paWaitFor(pThis, pa_stream_cork(pStr m->pPAStream, 1 /* Stop / pause */, paStreamCbSuccess, pStrm));1235 rc = paWaitFor(pThis, pa_stream_cork(pStreamPA->pStream, 1 /* Stop / pause */, paStreamCbSuccess, pStreamPA)); 1280 1236 pa_threaded_mainloop_unlock(pThis->pMainLoop); 1281 1237 break; … … 1352 1308 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate} 1353 1309 */ 1354 static DECLCALLBACK(int) drvHostPulseAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 1310 static DECLCALLBACK(int) drvHostPulseAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 1311 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 1355 1312 { 1356 1313 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 1359 1316 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER); 1360 1317 1318 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 1319 PPULSEAUDIOSTREAM pStreamPA = (PPULSEAUDIOSTREAM)pStream; 1320 1361 1321 int rc; 1362 1322 if (pCfgReq->enmDir == PDMAUDIODIR_IN) 1363 rc = paCreateStreamIn (pInterface, pStream, pCfgReq, pCfgAcq);1364 else if (p Stream->enmDir == PDMAUDIODIR_OUT)1365 rc = paCreateStreamOut(p Interface, pStream, pCfgReq, pCfgAcq);1323 rc = paCreateStreamIn (pThis, pStreamPA, pCfgReq, pCfgAcq); 1324 else if (pCfgReq->enmDir == PDMAUDIODIR_OUT) 1325 rc = paCreateStreamOut(pThis, pStreamPA, pCfgReq, pCfgAcq); 1366 1326 else 1367 1327 AssertFailedReturn(VERR_NOT_IMPLEMENTED); 1368 1328 1329 if (RT_SUCCESS(rc)) 1330 { 1331 pStreamPA->pCfg = DrvAudioHlpStreamCfgDup(pCfgAcq); 1332 if (!pStreamPA->pCfg) 1333 rc = VERR_NO_MEMORY; 1334 } 1335 1369 1336 return rc; 1370 1337 } … … 1374 1341 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy} 1375 1342 */ 1376 static DECLCALLBACK(int) drvHostPulseAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)1343 static DECLCALLBACK(int) drvHostPulseAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 1377 1344 { 1378 1345 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 1379 1346 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1380 1347 1348 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 1349 PPULSEAUDIOSTREAM pStreamPA = (PPULSEAUDIOSTREAM)pStream; 1350 1351 if (!pStreamPA->pCfg) /* Not (yet) configured? Skip. */ 1352 return VINF_SUCCESS; 1353 1381 1354 int rc; 1382 if (pStream ->enmDir == PDMAUDIODIR_IN)1383 rc = paDestroyStreamIn (pInterface, pStream);1384 else if (pStream ->enmDir == PDMAUDIODIR_OUT)1385 rc = paDestroyStreamOut(p Interface, pStream);1355 if (pStreamPA->pCfg->enmDir == PDMAUDIODIR_IN) 1356 rc = paDestroyStreamIn (pThis, pStreamPA); 1357 else if (pStreamPA->pCfg->enmDir == PDMAUDIODIR_OUT) 1358 rc = paDestroyStreamOut(pThis, pStreamPA); 1386 1359 else 1387 AssertFailedReturn(VERR_NOT_IMPLEMENTED); 1360 AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED); 1361 1362 if (RT_SUCCESS(rc)) 1363 { 1364 DrvAudioHlpStreamCfgFree(pStreamPA->pCfg); 1365 pStreamPA->pCfg = NULL; 1366 } 1388 1367 1389 1368 return rc; … … 1394 1373 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl} 1395 1374 */ 1396 static DECLCALLBACK(int) drvHostPulseAudioStreamControl(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 1375 static DECLCALLBACK(int) drvHostPulseAudioStreamControl(PPDMIHOSTAUDIO pInterface, 1376 PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 1397 1377 { 1398 1378 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 1399 1379 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1400 1380 1401 Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST); 1381 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 1382 PPULSEAUDIOSTREAM pStreamPA = (PPULSEAUDIOSTREAM)pStream; 1383 1384 if (!pStreamPA->pCfg) /* Not (yet) configured? Skip. */ 1385 return VINF_SUCCESS; 1402 1386 1403 1387 int rc; 1404 if (pStream ->enmDir == PDMAUDIODIR_IN)1405 rc = paControlStreamIn (pInterface, pStream, enmStreamCmd);1406 else if (pStream ->enmDir == PDMAUDIODIR_OUT)1407 rc = paControlStreamOut(p Interface, pStream, enmStreamCmd);1388 if (pStreamPA->pCfg->enmDir == PDMAUDIODIR_IN) 1389 rc = paControlStreamIn (pThis, pStreamPA, enmStreamCmd); 1390 else if (pStreamPA->pCfg->enmDir == PDMAUDIODIR_OUT) 1391 rc = paControlStreamOut(pThis, pStreamPA, enmStreamCmd); 1408 1392 else 1409 AssertFailed Return(VERR_NOT_IMPLEMENTED);1393 AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED); 1410 1394 1411 1395 return rc; … … 1416 1400 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus} 1417 1401 */ 1418 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostPulseAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)1402 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostPulseAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 1419 1403 { 1420 1404 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 1421 1405 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1422 1406 1423 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);1424 PPULSEAUDIOSTREAM pStr m= (PPULSEAUDIOSTREAM)pStream;1407 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 1408 PPULSEAUDIOSTREAM pStreamPA = (PPULSEAUDIOSTREAM)pStream; 1425 1409 1426 1410 PDMAUDIOSTRMSTS strmSts = PDMAUDIOSTRMSTS_FLAG_NONE; … … 1437 1421 1438 1422 /* Check the PulseAudio stream. */ 1439 if (PA_STREAM_IS_GOOD(pa_stream_get_state(pStr m->pPAStream)))1423 if (PA_STREAM_IS_GOOD(pa_stream_get_state(pStreamPA->pStream))) 1440 1424 { 1441 1425 size_t cbSize; 1442 if (pStream ->enmDir == PDMAUDIODIR_IN)1443 { 1444 cbSize = pa_stream_readable_size(pStr m->pPAStream);1426 if (pStreamPA->pCfg->enmDir == PDMAUDIODIR_IN) 1427 { 1428 cbSize = pa_stream_readable_size(pStreamPA->pStream); 1445 1429 Log3Func(("cbSize=%zu\n", cbSize)); 1446 1430 … … 1448 1432 strmSts |= PDMAUDIOSTRMSTS_FLAG_DATA_READABLE; 1449 1433 } 1450 else if (pStream ->enmDir == PDMAUDIODIR_OUT)1451 { 1452 cbSize = pa_stream_writable_size(pStr m->pPAStream);1453 Log3Func(("cbSize=%zu, cbMinReq=%RU32\n", cbSize, pStr m->BufAttr.minreq));1454 1455 if (cbSize >= pStr m->BufAttr.minreq)1434 else if (pStreamPA->pCfg->enmDir == PDMAUDIODIR_OUT) 1435 { 1436 cbSize = pa_stream_writable_size(pStreamPA->pStream); 1437 Log3Func(("cbSize=%zu, cbMinReq=%RU32\n", cbSize, pStreamPA->BufAttr.minreq)); 1438 1439 if (cbSize >= pStreamPA->BufAttr.minreq) 1456 1440 strmSts |= PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE; 1457 1441 } … … 1469 1453 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate} 1470 1454 */ 1471 static DECLCALLBACK(int) drvHostPulseAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)1455 static DECLCALLBACK(int) drvHostPulseAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 1472 1456 { 1473 1457 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); -
trunk/src/VBox/Devices/Audio/DrvHostValidationKit.cpp
r65606 r65624 33 33 typedef struct VAKITAUDIOSTREAM 34 34 { 35 /** Note: Always must come first!*/36 PDMAUDIOSTREAM Stream;35 /** The stream's acquired configuration. */ 36 PDMAUDIOSTREAMCFG Cfg; 37 37 /** Audio file to dump output to or read input from. */ 38 38 PDMAUDIOFILE File; … … 128 128 129 129 static int debugCreateStreamIn(PPDMIHOSTAUDIO pInterface, 130 PPDMAUDIO STREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)130 PPDMAUDIOBACKENDSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 131 131 { 132 132 RT_NOREF(pInterface, pStream); … … 134 134 /* Just adopt the wanted stream configuration. */ 135 135 PDMAUDIOPCMPROPS Props; 136 int rc = DrvAudioHlpStreamCfg ToProps(pCfgReq, &Props);136 int rc = DrvAudioHlpStreamCfgDup(pCfgReq, &Props); 137 137 if (RT_SUCCESS(rc)) 138 138 { 139 139 if (pCfgAcq) 140 pCfgAcq->cSampleBuffer Size= _1K;140 pCfgAcq->cSampleBufferHint = _1K; 141 141 } 142 142 … … 147 147 148 148 static int debugCreateStreamOut(PPDMIHOSTAUDIO pInterface, 149 PPDMAUDIO STREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)149 PPDMAUDIOBACKENDSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 150 150 { 151 151 NOREF(pInterface); … … 155 155 /* Just adopt the wanted stream configuration. */ 156 156 PDMAUDIOPCMPROPS Props; 157 int rc = DrvAudioHlpStreamCfg ToProps(pCfgReq, &Props);157 int rc = DrvAudioHlpStreamCfgDup(pCfgReq, &Props); 158 158 if (RT_SUCCESS(rc)) 159 159 { … … 204 204 { 205 205 if (pCfgAcq) 206 pCfgAcq->cSampleBuffer Size= pDbgStream->Out.cMaxSamplesInPlayBuffer;206 pCfgAcq->cSampleBufferHint = pDbgStream->Out.cMaxSamplesInPlayBuffer; 207 207 } 208 208 … … 216 216 */ 217 217 static DECLCALLBACK(int) drvHostVaKitAudioStreamCreate(PPDMIHOSTAUDIO pInterface, 218 PPDMAUDIO STREAM pStream,218 PPDMAUDIOBACKENDSTREAM pStream, 219 219 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 220 220 { … … 238 238 */ 239 239 static DECLCALLBACK(int) drvHostVaKitAudioStreamPlay(PPDMIHOSTAUDIO pInterface, 240 PPDMAUDIO STREAM pStream, const void *pvBuf, uint32_t cbBuf,240 PPDMAUDIOBACKENDSTREAM pStream, const void *pvBuf, uint32_t cbBuf, 241 241 uint32_t *pcbWritten) 242 242 { … … 338 338 */ 339 339 static DECLCALLBACK(int) drvHostVaKitAudioStreamCapture(PPDMIHOSTAUDIO pInterface, 340 PPDMAUDIO STREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)340 PPDMAUDIOBACKENDSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 341 341 { 342 342 RT_NOREF(pInterface, pStream, pvBuf, cbBuf); … … 350 350 351 351 352 static int debugDestroyStreamIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)352 static int debugDestroyStreamIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 353 353 { 354 354 RT_NOREF(pInterface, pStream); … … 358 358 359 359 360 static int debugDestroyStreamOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)360 static int debugDestroyStreamOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 361 361 { 362 362 RT_NOREF(pInterface); … … 400 400 401 401 402 static DECLCALLBACK(int) drvHostVaKitAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)402 static DECLCALLBACK(int) drvHostVaKitAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 403 403 { 404 404 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 415 415 416 416 static DECLCALLBACK(int) drvHostVaKitAudioStreamControl(PPDMIHOSTAUDIO pInterface, 417 PPDMAUDIO STREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)417 PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 418 418 { 419 419 RT_NOREF(enmStreamCmd); … … 427 427 } 428 428 429 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostVaKitAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)429 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostVaKitAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 430 430 { 431 431 NOREF(pInterface); … … 436 436 } 437 437 438 static DECLCALLBACK(int) drvHostVaKitAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)438 static DECLCALLBACK(int) drvHostVaKitAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 439 439 { 440 440 NOREF(pInterface); -
trunk/src/VBox/Devices/Audio/HDACodec.cpp
r64991 r65624 8 8 9 9 /* 10 * Copyright (C) 2006-201 6Oracle Corporation10 * Copyright (C) 2006-2017 Oracle Corporation 11 11 * 12 12 * This file is part of VirtualBox Open Source Edition (OSE), as … … 601 601 602 602 uint32_t u32A_param; 603 AMPLIFIER B_params;603 AMPLIFIER B_params; 604 604 605 605 } DACNODE, *PDACNODE; … … 1584 1584 * Misc helpers. 1585 1585 */ 1586 static int hdaCodecToAudVolume(PHDACODEC pThis, AMPLIFIER *pAmp, PDMAUDIOMIXERCTL enmMixerCtl) 1587 { 1586 static int hdaCodecToAudVolume(PHDACODEC pThis, PCODECNODE pNode, AMPLIFIER *pAmp, PDMAUDIOMIXERCTL enmMixerCtl) 1587 { 1588 RT_NOREF(pNode); 1589 1588 1590 uint8_t iDir; 1589 1591 switch (enmMixerCtl) … … 1621 1623 1622 1624 PDMAUDIOVOLUME Vol = { RT_BOOL(iMute), lVol, rVol }; 1625 1626 LogFunc(("[NID0x%02x] %RU8/%RU8 (%s)\n", 1627 pNode->node.uID, lVol, rVol, RT_BOOL(iMute) ? "Muted" : "Unmuted")); 1623 1628 1624 1629 LogRel2(("HDA: Setting volume for mixer control '%s' to %RU8/%RU8 (%s)\n", … … 1744 1749 bool fIsOut = CODEC_SET_AMP_IS_OUT_DIRECTION(cmd); 1745 1750 bool fIsIn = CODEC_SET_AMP_IS_IN_DIRECTION(cmd); 1751 bool fIsLeft = CODEC_SET_AMP_IS_LEFT_SIDE(cmd); 1746 1752 bool fIsRight = CODEC_SET_AMP_IS_RIGHT_SIDE(cmd); 1747 bool fIsLeft = CODEC_SET_AMP_IS_LEFT_SIDE(cmd);1748 1753 uint8_t u8Index = CODEC_SET_AMP_INDEX(cmd); 1749 1754 … … 1751 1756 || (!fIsOut && !fIsIn)) 1752 1757 return VINF_SUCCESS; 1758 1759 LogFunc(("[NID0x%02x] fIsOut=%RTbool, fIsIn=%RTbool, fIsLeft=%RTbool, fIsRight=%RTbool, Idx=%RU8\n", 1760 CODEC_NID(cmd), fIsOut, fIsIn, fIsLeft, fIsRight, u8Index)); 1753 1761 1754 1762 if (fIsIn) … … 1759 1767 hdaCodecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_RIGHT, u8Index), cmd, 0); 1760 1768 1761 /** @todo Fix ID of u8AdcVolsLineIn! */ 1762 hdaCodecToAudVolume(pThis, pAmplifier, PDMAUDIOMIXERCTL_LINE_IN); 1769 // if (CODEC_NID(cmd) == pThis->u8AdcVolsLineIn) 1770 // { 1771 hdaCodecToAudVolume(pThis, pNode, pAmplifier, PDMAUDIOMIXERCTL_LINE_IN); 1772 // } 1763 1773 } 1764 1774 if (fIsOut) … … 1770 1780 1771 1781 if (CODEC_NID(cmd) == pThis->u8DacLineOut) 1772 hdaCodecToAudVolume(pThis, p Amplifier, PDMAUDIOMIXERCTL_FRONT);1782 hdaCodecToAudVolume(pThis, pNode, pAmplifier, PDMAUDIOMIXERCTL_FRONT); 1773 1783 } 1774 1784 … … 2325 2335 #endif 2326 2336 2337 /* F06 */ 2327 2338 static DECLCALLBACK(int) vrbProcGetStreamId(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp) 2328 2339 { … … 2348 2359 } 2349 2360 2350 /* F06 */2361 /* 706 */ 2351 2362 static DECLCALLBACK(int) vrbProcSetStreamId(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp) 2352 2363 { 2353 2364 *pResp = 0; 2354 2365 2366 uint8_t uSD = CODEC_F00_06_GET_STREAM_ID(cmd); 2367 uint8_t uChannel = CODEC_F00_06_GET_CHANNEL_ID(cmd); 2368 2369 LogFlowFunc(("[NID0x%02x] Setting to stream ID=%RU8, channel=%RU8\n", 2370 CODEC_NID(cmd), uSD, uChannel)); 2371 2355 2372 PDMAUDIODIR enmDir; 2356 2357 2373 uint32_t *pu32Addr = NULL; 2358 2374 if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd))) … … 2385 2401 if (enmDir != PDMAUDIODIR_UNKNOWN) 2386 2402 { 2387 uint8_t uSD = CODEC_F00_06_GET_STREAM_ID(cmd);2388 uint8_t uChannel = CODEC_F00_06_GET_CHANNEL_ID(cmd);2389 2390 LogFlowFunc(("[NID0x%02x] Setting to stream ID=%RU8, channel=%RU8, enmDir=%RU32\n",2391 CODEC_NID(cmd), uSD, uChannel, enmDir));2392 2393 2403 pThis->paNodes[CODEC_NID(cmd)].node.uSD = uSD; 2394 2404 pThis->paNodes[CODEC_NID(cmd)].node.uChannel = uChannel; … … 3114 3124 int hdaCodecLoadState(PHDACODEC pThis, PSSMHANDLE pSSM, uint32_t uVersion) 3115 3125 { 3116 PCSSMFIELD pFields; 3117 uint32_t fFlags; 3126 int rc = VINF_SUCCESS; 3127 3128 PCSSMFIELD pFields = NULL; 3129 uint32_t fFlags = 0; 3118 3130 switch (uVersion) 3119 3131 { … … 3149 3161 3150 3162 default: 3151 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION; 3152 } 3153 3154 for (unsigned idxNode = 0; idxNode < pThis->cTotalNodes; ++idxNode) 3155 { 3156 uint8_t idOld = pThis->paNodes[idxNode].SavedState.Core.uID; 3157 int rc = SSMR3GetStructEx(pSSM, &pThis->paNodes[idxNode].SavedState, 3158 sizeof(pThis->paNodes[idxNode].SavedState), 3159 fFlags, pFields, NULL); 3160 if (RT_FAILURE(rc)) 3161 return rc; 3162 AssertLogRelMsgReturn(idOld == pThis->paNodes[idxNode].SavedState.Core.uID, 3163 ("loaded %#x, expected %#x\n", pThis->paNodes[idxNode].SavedState.Core.uID, idOld), 3164 VERR_SSM_DATA_UNIT_FORMAT_CHANGED); 3165 } 3166 3167 /* 3168 * Update stuff after changing the state. 3169 */ 3170 if (hdaCodecIsDacNode(pThis, pThis->u8DacLineOut)) 3171 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params, PDMAUDIOMIXERCTL_FRONT); 3172 else if (hdaCodecIsSpdifOutNode(pThis, pThis->u8DacLineOut)) 3173 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].spdifout.B_params, PDMAUDIOMIXERCTL_FRONT); 3174 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN); 3175 3176 return VINF_SUCCESS; 3163 rc = VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION; 3164 break; 3165 } 3166 3167 if (RT_SUCCESS(rc)) 3168 { 3169 for (unsigned idxNode = 0; idxNode < pThis->cTotalNodes; ++idxNode) 3170 { 3171 uint8_t idOld = pThis->paNodes[idxNode].SavedState.Core.uID; 3172 int rc2 = SSMR3GetStructEx(pSSM, &pThis->paNodes[idxNode].SavedState, 3173 sizeof(pThis->paNodes[idxNode].SavedState), 3174 fFlags, pFields, NULL); 3175 if (RT_SUCCESS(rc)) 3176 rc = rc2; 3177 3178 if (RT_FAILURE(rc)) 3179 break; 3180 3181 AssertLogRelMsgReturn(idOld == pThis->paNodes[idxNode].SavedState.Core.uID, 3182 ("loaded %#x, expected %#x\n", pThis->paNodes[idxNode].SavedState.Core.uID, idOld), 3183 VERR_SSM_DATA_UNIT_FORMAT_CHANGED); 3184 } 3185 3186 if (RT_SUCCESS(rc)) 3187 { 3188 /* 3189 * Update stuff after changing the state. 3190 */ 3191 PCODECNODE pNode; 3192 if (hdaCodecIsDacNode(pThis, pThis->u8DacLineOut)) 3193 { 3194 pNode = &pThis->paNodes[pThis->u8DacLineOut]; 3195 hdaCodecToAudVolume(pThis, pNode, &pNode->dac.B_params, PDMAUDIOMIXERCTL_FRONT); 3196 } 3197 else if (hdaCodecIsSpdifOutNode(pThis, pThis->u8DacLineOut)) 3198 { 3199 pNode = &pThis->paNodes[pThis->u8DacLineOut]; 3200 hdaCodecToAudVolume(pThis, pNode, &pNode->spdifout.B_params, PDMAUDIOMIXERCTL_FRONT); 3201 } 3202 3203 pNode = &pThis->paNodes[pThis->u8AdcVolsLineIn]; 3204 hdaCodecToAudVolume(pThis, pNode, &pNode->adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN); 3205 } 3206 } 3207 3208 LogFlowFuncLeaveRC(rc); 3209 return rc; 3177 3210 } 3178 3211 … … 3258 3291 PDMAUDIOSTREAMCFG strmCfg; 3259 3292 RT_ZERO(strmCfg); 3260 strmCfg.uHz = 44100; 3261 strmCfg.cChannels = 2; 3262 strmCfg.enmFormat = PDMAUDIOFMT_S16; 3263 strmCfg.enmEndianness = PDMAUDIOHOSTENDIANNESS; 3293 3294 strmCfg.Props.uHz = 44100; 3295 strmCfg.Props.cChannels = 2; 3296 strmCfg.Props.cBits = 16; 3297 strmCfg.Props.fSigned = true; 3264 3298 3265 3299 /* Note: Adding the default input/output streams is *not* critical for the overall … … 3318 3352 * Set initial volume. 3319 3353 */ 3320 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params, PDMAUDIOMIXERCTL_FRONT); 3321 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN); 3354 PCODECNODE pNode = &pThis->paNodes[pThis->u8DacLineOut]; 3355 hdaCodecToAudVolume(pThis, pNode, &pNode->dac.B_params, PDMAUDIOMIXERCTL_FRONT); 3356 3357 pNode = &pThis->paNodes[pThis->u8AdcVolsLineIn]; 3358 hdaCodecToAudVolume(pThis, pNode, &pNode->adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN); 3322 3359 #ifdef VBOX_WITH_AUDIO_HDA_MIC_IN 3323 #error "Implement mic-in support!"3360 # error "Implement mic-in support!" 3324 3361 #endif 3325 3362 -
trunk/src/VBox/Devices/Audio/testcase/tstAudioMixBuffer.cpp
r63362 r65624 46 46 PDMAUDIODIR_OUT, 47 47 { PDMAUDIOPLAYBACKDEST_UNKNOWN }, 48 44100, /* Hz */ 49 2 /* Channels */, 50 PDMAUDIOFMT_S16 /* Format */, 51 PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */ 52 }; 53 PDMAUDIOPCMPROPS props; 54 55 int rc = DrvAudioHlpStreamCfgToProps(&config, &props); 56 AssertRC(rc); 48 { 16, /* Bits */ 49 true, /* Signed */ 50 1, /* Shift */ 51 2, /* Channels */ 52 44100, /* Hz */ 53 false /* Swap Endian */ }, 54 0 /* cSampleBufferSize */ 55 }; 56 57 RTTESTI_CHECK(DrvAudioHlpStreamCfgIsValid(&config)); 57 58 58 59 uint32_t cBufSize = _1K; … … 62 63 */ 63 64 PDMAUDIOMIXBUF mb; 64 RTTESTI_CHECK_RC_OK(AudioMixBufInit(&mb, "Single", & props, cBufSize));65 RTTESTI_CHECK_RC_OK(AudioMixBufInit(&mb, "Single", &config.Props, cBufSize)); 65 66 RTTESTI_CHECK(AudioMixBufSize(&mb) == cBufSize); 66 67 RTTESTI_CHECK(AUDIOMIXBUF_B2S(&mb, AudioMixBufSizeBytes(&mb)) == cBufSize); … … 149 150 PDMAUDIODIR_OUT, 150 151 { PDMAUDIOPLAYBACKDEST_UNKNOWN }, 151 44100, /* Hz */ 152 2 /* Channels */, 153 PDMAUDIOFMT_S16 /* Format */, 154 PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */ 155 }; 156 157 PDMAUDIOPCMPROPS props; 158 int rc = DrvAudioHlpStreamCfgToProps(&cfg_p, &props); 159 AssertRC(rc); 152 { 16, /* Bits */ 153 true, /* Signed */ 154 1, /* Shift */ 155 2, /* Channels */ 156 44100, /* Hz */ 157 false /* Swap Endian */ }, 158 0 /* cSampleBufferSize */ 159 }; 160 161 RTTESTI_CHECK(DrvAudioHlpStreamCfgIsValid(&cfg_p)); 160 162 161 163 PDMAUDIOMIXBUF parent; 162 RTTESTI_CHECK_RC_OK(AudioMixBufInit(&parent, "Parent", & props, cBufSize));164 RTTESTI_CHECK_RC_OK(AudioMixBufInit(&parent, "Parent", &cfg_p.Props, cBufSize)); 163 165 164 166 PDMAUDIOSTREAMCFG cfg_c1 = /* Upmixing to parent */ … … 167 169 PDMAUDIODIR_OUT, 168 170 { PDMAUDIOPLAYBACKDEST_UNKNOWN }, 169 22050, /* Hz */ 170 2 /* Channels */, 171 PDMAUDIOFMT_S16 /* Format */, 172 PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */ 173 }; 174 175 rc = DrvAudioHlpStreamCfgToProps(&cfg_c1, &props); 176 AssertRC(rc); 171 { 16, /* Bits */ 172 true, /* Signed */ 173 1, /* Shift */ 174 2, /* Channels */ 175 22050, /* Hz */ 176 false /* Swap Endian */ }, 177 0 /* cSampleBufferSize */ 178 }; 179 180 RTTESTI_CHECK(DrvAudioHlpStreamCfgIsValid(&cfg_c1)); 177 181 178 182 PDMAUDIOMIXBUF child1; 179 RTTESTI_CHECK_RC_OK(AudioMixBufInit(&child1, "Child1", & props, cBufSize));183 RTTESTI_CHECK_RC_OK(AudioMixBufInit(&child1, "Child1", &cfg_c1.Props, cBufSize)); 180 184 RTTESTI_CHECK_RC_OK(AudioMixBufLinkTo(&child1, &parent)); 181 185 … … 185 189 PDMAUDIODIR_OUT, 186 190 { PDMAUDIOPLAYBACKDEST_UNKNOWN }, 187 48000, /* Hz */ 188 2 /* Channels */, 189 PDMAUDIOFMT_S16 /* Format */, 190 PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */ 191 }; 192 193 rc = DrvAudioHlpStreamCfgToProps(&cfg_c2, &props); 194 AssertRC(rc); 191 { 16, /* Bits */ 192 true, /* Signed */ 193 1, /* Shift */ 194 2, /* Channels */ 195 48000, /* Hz */ 196 false /* Swap Endian */ }, 197 0 /* cSampleBufferSize */ 198 }; 199 200 RTTESTI_CHECK(DrvAudioHlpStreamCfgIsValid(&cfg_c2)); 195 201 196 202 PDMAUDIOMIXBUF child2; 197 RTTESTI_CHECK_RC_OK(AudioMixBufInit(&child2, "Child2", & props, cBufSize));203 RTTESTI_CHECK_RC_OK(AudioMixBufInit(&child2, "Child2", &cfg_c2.Props, cBufSize)); 198 204 RTTESTI_CHECK_RC_OK(AudioMixBufLinkTo(&child2, &parent)); 199 205 … … 262 268 unsigned i; 263 269 uint32_t cBufSize = 256; 264 PDMAUDIOPCMPROPS props;265 270 266 271 RTTestSubF(hTest, "Sample conversion (U8)"); … … 271 276 PDMAUDIODIR_OUT, 272 277 { PDMAUDIOPLAYBACKDEST_UNKNOWN }, 273 44100, /* Hz */ 274 1 /* Channels */, 275 PDMAUDIOFMT_U8 /* Format */, 276 PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */ 277 }; 278 279 int rc = DrvAudioHlpStreamCfgToProps(&cfg_p, &props); 280 AssertRC(rc); 278 { 8, /* Bits */ 279 false, /* Signed */ 280 1, /* Shift */ 281 1, /* Channels */ 282 44100, /* Hz */ 283 false /* Swap Endian */ }, 284 0 /* cSampleBufferSize */ 285 }; 286 287 RTTESTI_CHECK(DrvAudioHlpStreamCfgIsValid(&cfg_p)); 281 288 282 289 PDMAUDIOMIXBUF parent; 283 RTTESTI_CHECK_RC_OK(AudioMixBufInit(&parent, "Parent", & props, cBufSize));290 RTTESTI_CHECK_RC_OK(AudioMixBufInit(&parent, "Parent", &cfg_p.Props, cBufSize)); 284 291 285 292 /* Child uses half the sample rate; that ensures the mixing engine can't … … 295 302 PDMAUDIODIR_OUT, 296 303 { PDMAUDIOPLAYBACKDEST_UNKNOWN }, 297 22050, /* Hz */ 298 1 /* Channels */, 299 PDMAUDIOFMT_U8 /* Format */, 300 PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */ 301 }; 302 303 rc = DrvAudioHlpStreamCfgToProps(&cfg_c, &props); 304 AssertRC(rc); 304 { 8, /* Bits */ 305 false, /* Signed */ 306 1, /* Shift */ 307 1, /* Channels */ 308 22050, /* Hz */ 309 false /* Swap Endian */ }, 310 0 /* cSampleBufferSize */ 311 }; 312 313 RTTESTI_CHECK(DrvAudioHlpStreamCfgIsValid(&cfg_c)); 305 314 306 315 PDMAUDIOMIXBUF child; 307 RTTESTI_CHECK_RC_OK(AudioMixBufInit(&child, "Child", & props, cBufSize));316 RTTESTI_CHECK_RC_OK(AudioMixBufInit(&child, "Child", &cfg_c.Props, cBufSize)); 308 317 RTTESTI_CHECK_RC_OK(AudioMixBufLinkTo(&child, &parent)); 309 318 … … 324 333 325 334 /**** 8-bit unsigned samples ****/ 326 RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Conversion test %uHz %uch 8-bit\n", cfg_c. uHz, cfg_c.cChannels);335 RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Conversion test %uHz %uch 8-bit\n", cfg_c.Props.uHz, cfg_c.Props.cChannels); 327 336 RTTESTI_CHECK_RC_OK(AudioMixBufWriteCirc(&child, &samples, sizeof(samples), &cSamplesWritten)); 328 337 RTTESTI_CHECK_MSG(cSamplesWritten == cSamplesChild, ("Child: Expected %RU32 written samples, got %RU32\n", cSamplesChild, cSamplesWritten)); … … 370 379 unsigned i; 371 380 uint32_t cBufSize = 256; 372 PDMAUDIOPCMPROPS props;373 381 374 382 RTTestSubF(hTest, "Sample conversion (S16)"); … … 379 387 PDMAUDIODIR_OUT, 380 388 { PDMAUDIOPLAYBACKDEST_UNKNOWN }, 381 44100, /* Hz */ 382 1 /* Channels */, 383 PDMAUDIOFMT_S16 /* Format */, 384 PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */ 385 }; 386 387 int rc = DrvAudioHlpStreamCfgToProps(&cfg_p, &props); 388 AssertRC(rc); 389 { 16, /* Bits */ 390 true, /* Signed */ 391 1, /* Shift */ 392 1, /* Channels */ 393 44100, /* Hz */ 394 false /* Swap Endian */ }, 395 0 /* cSampleBufferSize */ 396 }; 397 398 RTTESTI_CHECK(DrvAudioHlpStreamCfgIsValid(&cfg_p)); 389 399 390 400 PDMAUDIOMIXBUF parent; 391 RTTESTI_CHECK_RC_OK(AudioMixBufInit(&parent, "Parent", & props, cBufSize));401 RTTESTI_CHECK_RC_OK(AudioMixBufInit(&parent, "Parent", &cfg_p.Props, cBufSize)); 392 402 393 403 PDMAUDIOSTREAMCFG cfg_c = /* Upmixing to parent */ … … 396 406 PDMAUDIODIR_OUT, 397 407 { PDMAUDIOPLAYBACKDEST_UNKNOWN }, 398 22050, /* Hz */ 399 1 /* Channels */, 400 PDMAUDIOFMT_S16 /* Format */, 401 PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */ 402 }; 403 404 rc = DrvAudioHlpStreamCfgToProps(&cfg_c, &props); 405 AssertRC(rc); 408 { 16, /* Bits */ 409 true, /* Signed */ 410 1, /* Shift */ 411 1, /* Channels */ 412 22050, /* Hz */ 413 false /* Swap Endian */ }, 414 0 /* cSampleBufferSize */ 415 }; 416 417 RTTESTI_CHECK(DrvAudioHlpStreamCfgIsValid(&cfg_c)); 406 418 407 419 PDMAUDIOMIXBUF child; 408 RTTESTI_CHECK_RC_OK(AudioMixBufInit(&child, "Child", & props, cBufSize));420 RTTESTI_CHECK_RC_OK(AudioMixBufInit(&child, "Child", &cfg_c.Props, cBufSize)); 409 421 RTTESTI_CHECK_RC_OK(AudioMixBufLinkTo(&child, &parent)); 410 422 … … 425 437 426 438 /**** 16-bit signed samples ****/ 427 RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Conversion test %uHz %uch 16-bit\n", cfg_c. uHz, cfg_c.cChannels);439 RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Conversion test %uHz %uch 16-bit\n", cfg_c.Props.uHz, cfg_c.Props.cChannels); 428 440 RTTESTI_CHECK_RC_OK(AudioMixBufWriteCirc(&child, &samples, sizeof(samples), &cSamplesWritten)); 429 441 RTTESTI_CHECK_MSG(cSamplesWritten == cSamplesChild, ("Child: Expected %RU32 written samples, got %RU32\n", cSamplesChild, cSamplesWritten)); … … 470 482 unsigned i; 471 483 uint32_t cBufSize = 256; 472 PDMAUDIOPCMPROPS props;473 484 474 485 RTTestSubF(hTest, "Volume control"); … … 480 491 PDMAUDIODIR_OUT, 481 492 { PDMAUDIOPLAYBACKDEST_UNKNOWN }, 482 44100, /* Hz */ 483 2 /* Channels */, 484 PDMAUDIOFMT_S16 /* Format */, 485 PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */ 486 }; 487 488 int rc = DrvAudioHlpStreamCfgToProps(&cfg, &props); 489 AssertRC(rc); 493 { 16, /* Bits */ 494 true, /* Signed */ 495 1, /* Shift */ 496 2, /* Channels */ 497 44100, /* Hz */ 498 false /* Swap Endian */ }, 499 0 /* cSampleBufferSize */ 500 }; 501 502 RTTESTI_CHECK(DrvAudioHlpStreamCfgIsValid(&cfg)); 490 503 491 504 PDMAUDIOVOLUME vol = { false, 0, 0 }; /* Not muted. */ 492 505 PDMAUDIOMIXBUF parent; 493 RTTESTI_CHECK_RC_OK(AudioMixBufInit(&parent, "Parent", & props, cBufSize));506 RTTESTI_CHECK_RC_OK(AudioMixBufInit(&parent, "Parent", &cfg.Props, cBufSize)); 494 507 495 508 PDMAUDIOMIXBUF child; 496 RTTESTI_CHECK_RC_OK(AudioMixBufInit(&child, "Child", & props, cBufSize));509 RTTESTI_CHECK_RC_OK(AudioMixBufInit(&child, "Child", &cfg.Props, cBufSize)); 497 510 RTTESTI_CHECK_RC_OK(AudioMixBufLinkTo(&child, &parent)); 498 511 … … 515 528 516 529 /**** Volume control test ****/ 517 RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Volume control test %uHz %uch \n", cfg. uHz, cfg.cChannels);530 RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Volume control test %uHz %uch \n", cfg.Props.uHz, cfg.Props.cChannels); 518 531 519 532 /* 1) Full volume/0dB attenuation (255). */ -
trunk/src/VBox/Main/src-client/DrvAudioVRDE.cpp
r65596 r65624 61 61 } DRVAUDIOVRDE, *PDRVAUDIOVRDE; 62 62 63 typedef struct VRDESTREAM IN64 { 65 /** Note: Always must come first!*/66 P DMAUDIOSTREAM Stream;67 /** The PCM properties of this stream. */68 PDMAUDIOPCMPROPS Props;69 /** Number of samples this stream can handle at once. */70 uint32_t cSamplesMax;71 /** Circular buffer for holding the recorded audio samples from the host. */72 PRTCIRCBUF pCircBuf;73 } VRDESTREAMIN, *PVRDESTREAMIN; 74 75 typedef struct VRDESTREAMOUT 76 { 77 /** Note: Always must come first! */78 PDMAUDIOSTREAM Stream;79 /** The PCM properties of this stream. */80 PDMAUDIOPCMPROPS Props;81 uint64_t old_ticks;82 uint64_t cSamplesSentPerSec;83 } VRDESTREAMOUT, *PVRDESTREAMOUT; 84 85 86 87 static int vrdeCreateStreamIn(PVRDESTREAMIN pStreamVRDE, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 88 { 89 int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pStreamVRDE->Props);63 typedef struct VRDESTREAM 64 { 65 /** The stream's acquired configuration. */ 66 PPDMAUDIOSTREAMCFG pCfg; 67 union 68 { 69 struct 70 { 71 /** Number of samples this stream can handle at once. */ 72 uint32_t cSamplesMax; 73 /** Circular buffer for holding the recorded audio samples from the host. */ 74 PRTCIRCBUF pCircBuf; 75 } In; 76 struct 77 { 78 uint64_t old_ticks; 79 uint64_t cSamplesSentPerSec; 80 } Out; 81 }; 82 } VRDESTREAM, *PVRDESTREAM; 83 84 85 static int vrdeCreateStreamIn(PVRDESTREAM pStreamVRDE, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 86 { 87 pStreamVRDE->In.cSamplesMax = _1K; /** @todo Make this configurable. */ 88 89 int rc = RTCircBufCreate(&pStreamVRDE->In.pCircBuf, pStreamVRDE->In.cSamplesMax * (pCfgReq->Props.cBits / 8) /* Bytes */); 90 90 if (RT_SUCCESS(rc)) 91 91 { 92 pStreamVRDE->cSamplesMax = _1K; /** @todo Make this configurable. */ 93 94 rc = RTCircBufCreate(&pStreamVRDE->pCircBuf, pStreamVRDE->cSamplesMax * (pStreamVRDE->Props.cBits / 8) /* Bytes */); 95 if (RT_SUCCESS(rc)) 96 { 97 if (pCfgAcq) 98 pCfgAcq->cSampleBufferSize = pStreamVRDE->cSamplesMax; 99 } 92 if (pCfgAcq) 93 pCfgAcq->cSampleBufferHint = pStreamVRDE->In.cSamplesMax; 100 94 } 101 95 … … 104 98 105 99 106 static int vrdeCreateStreamOut(PVRDESTREAMOUT pStreamVRDE, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 107 { 108 int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pStreamVRDE->Props); 109 if (RT_SUCCESS(rc)) 110 { 111 if (pCfgAcq) 112 pCfgAcq->cSampleBufferSize = _4K; /** @todo Make this configurable. */ 113 } 114 115 return rc; 116 } 117 118 119 static int vrdeControlStreamOut(PDRVAUDIOVRDE pDrv, PVRDESTREAMOUT pStreamVRDE, PDMAUDIOSTREAMCMD enmStreamCmd) 100 static int vrdeCreateStreamOut(PVRDESTREAM pStreamVRDE, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 101 { 102 RT_NOREF(pStreamVRDE, pCfgReq); 103 104 if (pCfgAcq) 105 pCfgAcq->cSampleBufferHint = _4K; /** @todo Make this configurable. */ 106 107 return VINF_SUCCESS; 108 } 109 110 111 static int vrdeControlStreamOut(PDRVAUDIOVRDE pDrv, PVRDESTREAM pStreamVRDE, PDMAUDIOSTREAMCMD enmStreamCmd) 120 112 { 121 113 RT_NOREF(pDrv, pStreamVRDE, enmStreamCmd); … … 127 119 128 120 129 static int vrdeControlStreamIn(PDRVAUDIOVRDE pDrv, PVRDESTREAM IN pVRDEStrmIn, PDMAUDIOSTREAMCMD enmStreamCmd)121 static int vrdeControlStreamIn(PDRVAUDIOVRDE pDrv, PVRDESTREAM pStreamVRDE, PDMAUDIOSTREAMCMD enmStreamCmd) 130 122 { 131 123 LogFlowFunc(("enmStreamCmd=%ld\n", enmStreamCmd)); … … 141 133 case PDMAUDIOSTREAMCMD_ENABLE: 142 134 { 143 rc = pDrv->pConsoleVRDPServer->SendAudioInputBegin(NULL, p VRDEStrmIn, pVRDEStrmIn->cSamplesMax,144 p VRDEStrmIn->Props.uHz,145 p VRDEStrmIn->Props.cChannels, pVRDEStrmIn->Props.cBits);135 rc = pDrv->pConsoleVRDPServer->SendAudioInputBegin(NULL, pStreamVRDE, pStreamVRDE->In.cSamplesMax, 136 pStreamVRDE->pCfg->Props.uHz, pStreamVRDE->pCfg->Props.cChannels, 137 pStreamVRDE->pCfg->Props.cBits); 146 138 if (rc == VERR_NOT_SUPPORTED) 147 139 { … … 203 195 */ 204 196 static DECLCALLBACK(int) drvAudioVRDEStreamCapture(PPDMIHOSTAUDIO pInterface, 205 PPDMAUDIO STREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)197 PPDMAUDIOBACKENDSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 206 198 { 207 199 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 211 203 /* pcbRead is optional. */ 212 204 213 PVRDESTREAM IN pStreamVRDE = (PVRDESTREAMIN)pStream;205 PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pStream; 214 206 215 207 size_t cbData = 0; 216 208 217 if (RTCircBufUsed(pStreamVRDE-> pCircBuf))209 if (RTCircBufUsed(pStreamVRDE->In.pCircBuf)) 218 210 { 219 211 void *pvData; 220 212 221 RTCircBufAcquireReadBlock(pStreamVRDE-> pCircBuf, cbBuf, &pvData, &cbData);213 RTCircBufAcquireReadBlock(pStreamVRDE->In.pCircBuf, cbBuf, &pvData, &cbData); 222 214 223 215 if (cbData) 224 216 memcpy(pvBuf, pvData, cbData); 225 217 226 RTCircBufReleaseReadBlock(pStreamVRDE-> pCircBuf, cbData);218 RTCircBufReleaseReadBlock(pStreamVRDE->In.pCircBuf, cbData); 227 219 } 228 220 … … 237 229 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay} 238 230 */ 239 static DECLCALLBACK(int) drvAudioVRDEStreamPlay(PPDMIHOSTAUDIO pInterface, 240 PPDMAUDIOSTREAM pStream,const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)231 static DECLCALLBACK(int) drvAudioVRDEStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 232 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten) 241 233 { 242 234 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 246 238 /* pcbWritten is optional. */ 247 239 248 PDRVAUDIOVRDE 249 PVRDESTREAM OUT pStreamVRDE = (PVRDESTREAMOUT)pStream;240 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio); 241 PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pStream; 250 242 251 243 uint32_t cbLive = cbBuf; 252 244 253 245 uint64_t now = PDMDrvHlpTMGetVirtualTime(pDrv->pDrvIns); 254 uint64_t ticks = now - pStreamVRDE-> old_ticks;246 uint64_t ticks = now - pStreamVRDE->Out.old_ticks; 255 247 uint64_t ticks_per_second = PDMDrvHlpTMGetVirtualFreq(pDrv->pDrvIns); 256 248 249 PPDMAUDIOPCMPROPS pProps = &pStreamVRDE->pCfg->Props; 250 257 251 /* Minimize the rounding error: samples = int((ticks * freq) / ticks_per_second + 0.5). */ 258 uint32_t cbToWrite = (int)((2 * ticks * p StreamVRDE->Props.uHz + ticks_per_second) / ticks_per_second / 2);252 uint32_t cbToWrite = (int)((2 * ticks * pProps->uHz + ticks_per_second) / ticks_per_second / 2); 259 253 260 254 /* Remember when samples were consumed. */ 261 pStreamVRDE-> old_ticks = now;262 263 VRDEAUDIOFORMAT format = VRDE_AUDIO_FMT_MAKE(p StreamVRDE->Props.uHz,264 p StreamVRDE->Props.cChannels,265 p StreamVRDE->Props.cBits,266 p StreamVRDE->Props.fSigned);255 pStreamVRDE->Out.old_ticks = now; 256 257 VRDEAUDIOFORMAT format = VRDE_AUDIO_FMT_MAKE(pProps->uHz, 258 pProps->cChannels, 259 pProps->cBits, 260 pProps->fSigned); 267 261 268 262 Log2Func(("uFreq=%RU32, cChan=%RU8, cBits=%RU8, fSigned=%RTbool, enmFormat=%ld, cbLive=%RU32, cbToWrite=%RU32\n", 269 pStreamVRDE->Props.uHz, pStreamVRDE->Props.cChannels, 270 pStreamVRDE->Props.cBits, pStreamVRDE->Props.fSigned, 271 format, cbLive, cbToWrite)); 263 pProps->uHz, pProps->cChannels, pProps->cBits, pProps->fSigned, format, cbLive, cbToWrite)); 272 264 273 265 /* Don't play more than available. */ … … 291 283 292 284 pDrv->pConsoleVRDPServer->SendAudioSamples((uint8_t *)pvBuf + cbWritten, 293 PDMAUDIO PCMPROPS_B2S(&pStreamVRDE->Props, cbChunk) /* Samples */, format);285 PDMAUDIOSTREAMCFG_B2S(pStreamVRDE->pCfg, cbChunk) /* Samples */, format); 294 286 cbWritten += cbChunk; 295 287 Assert(cbWritten <= cbBuf); … … 311 303 312 304 313 static int vrdeDestroyStreamIn(PDRVAUDIOVRDE pDrv, PVRDESTREAM INpStreamVRDE)305 static int vrdeDestroyStreamIn(PDRVAUDIOVRDE pDrv, PVRDESTREAM pStreamVRDE) 314 306 { 315 307 if (pDrv->pConsoleVRDPServer) 316 308 pDrv->pConsoleVRDPServer->SendAudioInputEnd(NULL); 317 309 318 if (pStreamVRDE-> pCircBuf)319 { 320 RTCircBufDestroy(pStreamVRDE-> pCircBuf);321 pStreamVRDE-> pCircBuf = NULL;322 } 323 324 return VINF_SUCCESS; 325 } 326 327 328 static int vrdeDestroyStreamOut(PDRVAUDIOVRDE pDrv, PVRDESTREAM OUTpStreamVRDE)310 if (pStreamVRDE->In.pCircBuf) 311 { 312 RTCircBufDestroy(pStreamVRDE->In.pCircBuf); 313 pStreamVRDE->In.pCircBuf = NULL; 314 } 315 316 return VINF_SUCCESS; 317 } 318 319 320 static int vrdeDestroyStreamOut(PDRVAUDIOVRDE pDrv, PVRDESTREAM pStreamVRDE) 329 321 { 330 322 RT_NOREF(pDrv, pStreamVRDE); … … 339 331 static DECLCALLBACK(int) drvAudioVRDEGetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg) 340 332 { 341 NOREF(pInterface);333 RT_NOREF(pInterface); 342 334 AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER); 343 335 344 pBackendCfg->cbStreamOut = sizeof(VRDESTREAM OUT);345 pBackendCfg->cbStreamIn = sizeof(VRDESTREAM IN);336 pBackendCfg->cbStreamOut = sizeof(VRDESTREAM); 337 pBackendCfg->cbStreamIn = sizeof(VRDESTREAM); 346 338 pBackendCfg->cMaxStreamsIn = UINT32_MAX; 347 339 pBackendCfg->cMaxStreamsOut = UINT32_MAX; … … 379 371 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate} 380 372 */ 381 static DECLCALLBACK(int) drvAudioVRDEStreamCreate(PPDMIHOSTAUDIO pInterface, 382 PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)373 static DECLCALLBACK(int) drvAudioVRDEStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 374 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 383 375 { 384 376 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 389 381 RT_NOREF(pInterface); 390 382 383 PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pStream; 384 391 385 int rc; 392 386 if (pCfgReq->enmDir == PDMAUDIODIR_IN) 393 { 394 PVRDESTREAMIN pStreamVRDE = (PVRDESTREAMIN)pStream; 395 rc = vrdeCreateStreamIn(pStreamVRDE, pCfgReq, pCfgAcq); 396 } 387 rc = vrdeCreateStreamIn (pStreamVRDE, pCfgReq, pCfgAcq); 397 388 else 398 {399 PVRDESTREAMOUT pStreamVRDE = (PVRDESTREAMOUT)pStream;400 389 rc = vrdeCreateStreamOut(pStreamVRDE, pCfgReq, pCfgAcq); 390 391 if (RT_SUCCESS(rc)) 392 { 393 pStreamVRDE->pCfg = DrvAudioHlpStreamCfgDup(pCfgAcq); 394 if (!pStreamVRDE->pCfg) 395 rc = VERR_NO_MEMORY; 401 396 } 402 397 … … 408 403 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy} 409 404 */ 410 static DECLCALLBACK(int) drvAudioVRDEStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 405 static DECLCALLBACK(int) drvAudioVRDEStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 406 { 407 RT_NOREF(pInterface); 408 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 409 410 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio); 411 PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pStream; 412 413 if (!pStreamVRDE->pCfg) /* Not (yet) configured? Skip. */ 414 return VINF_SUCCESS; 415 416 int rc; 417 if (pStreamVRDE->pCfg->enmDir == PDMAUDIODIR_IN) 418 rc = vrdeDestroyStreamIn(pDrv, pStreamVRDE); 419 else 420 rc = vrdeDestroyStreamOut(pDrv, pStreamVRDE); 421 422 if (RT_SUCCESS(rc)) 423 { 424 DrvAudioHlpStreamCfgFree(pStreamVRDE->pCfg); 425 pStreamVRDE->pCfg = NULL; 426 } 427 428 return rc; 429 } 430 431 432 /** 433 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl} 434 */ 435 static DECLCALLBACK(int) drvAudioVRDEStreamControl(PPDMIHOSTAUDIO pInterface, 436 PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 411 437 { 412 438 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 413 439 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 414 440 415 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio); 441 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio); 442 PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pStream; 443 444 if (!pStreamVRDE->pCfg) /* Not (yet) configured? Skip. */ 445 return VINF_SUCCESS; 416 446 417 447 int rc; 418 if (pStream->enmDir == PDMAUDIODIR_IN) 419 { 420 PVRDESTREAMIN pStreamVRDE = (PVRDESTREAMIN)pStream; 421 rc = vrdeDestroyStreamIn(pDrv, pStreamVRDE); 422 } 448 if (pStreamVRDE->pCfg->enmDir == PDMAUDIODIR_IN) 449 rc = vrdeControlStreamIn(pDrv, pStreamVRDE, enmStreamCmd); 423 450 else 424 { 425 PVRDESTREAMOUT pStreamVRDE = (PVRDESTREAMOUT)pStream; 426 rc = vrdeDestroyStreamOut(pDrv, pStreamVRDE); 427 } 451 rc = vrdeControlStreamOut(pDrv, pStreamVRDE, enmStreamCmd); 428 452 429 453 return rc; … … 432 456 433 457 /** 434 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl} 435 */ 436 static DECLCALLBACK(int) drvAudioVRDEStreamControl(PPDMIHOSTAUDIO pInterface, 437 PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 458 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus} 459 */ 460 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvAudioVRDEStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 461 { 462 RT_NOREF(pInterface); 463 RT_NOREF(pStream); 464 465 return ( PDMAUDIOSTRMSTS_FLAG_INITIALIZED | PDMAUDIOSTRMSTS_FLAG_ENABLED 466 | PDMAUDIOSTRMSTS_FLAG_DATA_READABLE | PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE); 467 } 468 469 470 /** 471 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate} 472 */ 473 static DECLCALLBACK(int) drvAudioVRDEStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 438 474 { 439 475 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 440 476 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 441 442 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio);443 444 int rc;445 if (pStream->enmDir == PDMAUDIODIR_IN)446 {447 PVRDESTREAMIN pStreamVRDE = (PVRDESTREAMIN)pStream;448 rc = vrdeControlStreamIn(pDrv, pStreamVRDE, enmStreamCmd);449 }450 else451 {452 PVRDESTREAMOUT pStreamVRDE = (PVRDESTREAMOUT)pStream;453 rc = vrdeControlStreamOut(pDrv, pStreamVRDE, enmStreamCmd);454 }455 456 return rc;457 }458 459 460 /**461 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}462 */463 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvAudioVRDEStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)464 {465 NOREF(pInterface);466 NOREF(pStream);467 468 return ( PDMAUDIOSTRMSTS_FLAG_INITIALIZED | PDMAUDIOSTRMSTS_FLAG_ENABLED469 | PDMAUDIOSTRMSTS_FLAG_DATA_READABLE | PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE);470 }471 472 473 /**474 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate}475 */476 static DECLCALLBACK(int) drvAudioVRDEStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)477 {478 AssertPtrReturn(pInterface, VERR_INVALID_POINTER);479 AssertPtrReturn(pStream, VERR_INVALID_POINTER);480 481 LogFlowFuncEnter();482 477 483 478 /* Nothing to do here for VRDE. */ … … 543 538 AssertPtrReturn(pVRDEAudioBegin, VERR_INVALID_POINTER); 544 539 545 PVRDESTREAM IN pVRDEStrmIn = (PVRDESTREAMIN)pvContext;540 PVRDESTREAM pVRDEStrmIn = (PVRDESTREAM)pvContext; 546 541 AssertPtrReturn(pVRDEStrmIn, VERR_INVALID_POINTER); 547 542 548 543 VRDEAUDIOFORMAT audioFmt = pVRDEAudioBegin->fmt; 549 544 550 int iSampleHz = VRDE_AUDIO_FMT_SAMPLE_FREQ(audioFmt); NOREF(iSampleHz);551 int cChannels = VRDE_AUDIO_FMT_CHANNELS(audioFmt); NOREF(cChannels);552 int cBits = VRDE_AUDIO_FMT_BITS_PER_SAMPLE(audioFmt); NOREF(cBits);553 bool fUnsigned = VRDE_AUDIO_FMT_SIGNED(audioFmt); NOREF(fUnsigned);545 int iSampleHz = VRDE_AUDIO_FMT_SAMPLE_FREQ(audioFmt); RT_NOREF(iSampleHz); 546 int cChannels = VRDE_AUDIO_FMT_CHANNELS(audioFmt); RT_NOREF(cChannels); 547 int cBits = VRDE_AUDIO_FMT_BITS_PER_SAMPLE(audioFmt); RT_NOREF(cBits); 548 bool fUnsigned = VRDE_AUDIO_FMT_SIGNED(audioFmt); RT_NOREF(fUnsigned); 554 549 555 550 LogFlowFunc(("cbSample=%RU32, iSampleHz=%d, cChannels=%d, cBits=%d, fUnsigned=%RTbool\n", … … 562 557 int AudioVRDE::onVRDEInputData(void *pvContext, const void *pvData, uint32_t cbData) 563 558 { 564 PVRDESTREAM IN pStreamVRDE = (PVRDESTREAMIN)pvContext;559 PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pvContext; 565 560 AssertPtrReturn(pStreamVRDE, VERR_INVALID_POINTER); 566 561 … … 568 563 size_t cbBuf; 569 564 570 RTCircBufAcquireWriteBlock(pStreamVRDE-> pCircBuf, cbData, &pvBuf, &cbBuf);565 RTCircBufAcquireWriteBlock(pStreamVRDE->In.pCircBuf, cbData, &pvBuf, &cbBuf); 571 566 572 567 if (cbBuf) 573 568 memcpy(pvBuf, pvData, cbBuf); 574 569 575 RTCircBufReleaseWriteBlock(pStreamVRDE-> pCircBuf, cbBuf);570 RTCircBufReleaseWriteBlock(pStreamVRDE->In.pCircBuf, cbBuf); 576 571 577 572 if (cbBuf < cbData) … … 584 579 int AudioVRDE::onVRDEInputEnd(void *pvContext) 585 580 { 586 NOREF(pvContext);581 RT_NOREF(pvContext); 587 582 588 583 return VINF_SUCCESS; -
trunk/src/VBox/Main/src-client/DrvAudioVideoRec.cpp
r65565 r65624 180 180 181 181 /** 182 * Audio video recording output stream. 183 */ 184 typedef struct AVRECSTREAMOUT 185 { 186 /** Note: Always must come first! */ 187 PDMAUDIOSTREAM Stream; 188 /** The PCM properties of this stream. */ 189 PDMAUDIOPCMPROPS Props; 182 * Audio video recording (output) stream. 183 */ 184 typedef struct AVRECSTREAM 185 { 186 /** The stream's acquired configuration. */ 187 PPDMAUDIOSTREAMCFG pCfg; 190 188 /** (Audio) frame buffer. */ 191 189 PRTCIRCBUF pCircBuf; 192 190 /** Pointer to sink to use for writing. */ 193 191 PAVRECSINK pSink; 194 } AVRECSTREAM OUT, *PAVRECSTREAMOUT;192 } AVRECSTREAM, *PAVRECSTREAM; 195 193 196 194 /** … … 359 357 * @returns IPRT status code. 360 358 * @param pThis Driver instance. 361 * @param pStream 359 * @param pStreamAV Audio output stream to create. 362 360 * @param pSink Recording sink to associate audio output stream to. 363 361 * @param pCfgReq Requested configuration by the audio backend. 364 362 * @param pCfgAcq Acquired configuration by the audio output stream. 365 363 */ 366 static int avRecCreateStreamOut(PDRVAUDIOVIDEOREC pThis, P PDMAUDIOSTREAM pStream,364 static int avRecCreateStreamOut(PDRVAUDIOVIDEOREC pThis, PAVRECSTREAM pStreamAV, 367 365 PAVRECSINK pSink, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 368 366 { 369 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 370 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 371 AssertPtrReturn(pSink, VERR_INVALID_POINTER); 372 AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER); 373 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER); 374 375 PAVRECSTREAMOUT pStreamOut = (PAVRECSTREAMOUT)pStream; 367 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 368 AssertPtrReturn(pStreamAV, VERR_INVALID_POINTER); 369 AssertPtrReturn(pSink, VERR_INVALID_POINTER); 370 AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER); 371 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER); 376 372 377 373 if (pCfgReq->DestSource.Dest != PDMAUDIOPLAYBACKDEST_FRONT) … … 380 376 381 377 if (pCfgAcq) 382 pCfgAcq->cSampleBuffer Size= 0;378 pCfgAcq->cSampleBufferHint = 0; 383 379 384 380 LogRel2(("VideoRec: Support for surround audio not implemented yet\n")); … … 386 382 } 387 383 388 int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pStreamOut->Props); 389 if (RT_FAILURE(rc)) 390 return rc; 384 int rc = VINF_SUCCESS; 391 385 392 386 #ifdef VBOX_WITH_LIBOPUS … … 398 392 WebMWriter::AudioCodec_Opus, WebMWriter::VideoCodec_None); 399 393 if (RT_SUCCESS(rc)) 400 rc = pSink->Con.WebM.pWebM->AddAudioTrack(pSink->Codec.Parms.uHz, p StreamOut->Props.cChannels, pStreamOut->Props.cBits,394 rc = pSink->Con.WebM.pWebM->AddAudioTrack(pSink->Codec.Parms.uHz, pCfgReq->Props.cChannels, pCfgReq->Props.cBits, 401 395 &pSink->Con.WebM.uTrack); 402 396 } … … 405 399 return rc; 406 400 407 rc = RTCircBufCreate(&pStream Out->pCircBuf, (pSink->Codec.Opus.csFrame * pSink->Codec.Parms.cChannels) * sizeof(uint16_t));401 rc = RTCircBufCreate(&pStreamAV->pCircBuf, (pSink->Codec.Opus.csFrame * pSink->Codec.Parms.cChannels) * sizeof(uint16_t)); 408 402 if (RT_SUCCESS(rc)) 409 403 { 410 pStream Out->pSink = pSink; /* Assign sink to stream. */404 pStreamAV->pSink = pSink; /* Assign sink to stream. */ 411 405 412 406 if (pCfgAcq) … … 414 408 /* Make sure to let the driver backend know that we need the audio data in 415 409 * a specific sampling rate Opus is optimized for. */ 416 pCfgAcq->uHz = pSink->Codec.Parms.uHz; 417 pCfgAcq->cSampleBufferSize = _4K; /** @todo Make this configurable. */ 410 pCfgAcq->Props.uHz = pSink->Codec.Parms.uHz; 411 pCfgAcq->Props.cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfgAcq->Props.cBits, pCfgAcq->Props.cChannels); 412 pCfgAcq->cSampleBufferHint = _4K; /** @todo Make this configurable. */ 418 413 } 419 414 } 420 415 #else 421 RT_NOREF(pThis, pSink, pStream , pCfgReq, pCfgAcq);416 RT_NOREF(pThis, pSink, pStreamAV, pCfgReq, pCfgAcq); 422 417 rc = VERR_NOT_SUPPORTED; 423 418 #endif /* VBOX_WITH_LIBOPUS */ … … 433 428 * @returns IPRT status code. 434 429 * @param pThis Driver instance. 435 * @param pStream 436 */ 437 static int avRecDestroyStreamOut(PDRVAUDIOVIDEOREC pThis, P PDMAUDIOSTREAM pStream)430 * @param pStreamAV Audio output stream to destroy. 431 */ 432 static int avRecDestroyStreamOut(PDRVAUDIOVIDEOREC pThis, PAVRECSTREAM pStreamAV) 438 433 { 439 434 RT_NOREF(pThis); 440 PAVRECSTREAMOUT pStreamOut = (PAVRECSTREAMOUT)pStream; 441 442 if (pStreamOut->pCircBuf) 443 { 444 RTCircBufDestroy(pStreamOut->pCircBuf); 445 pStreamOut->pCircBuf = NULL; 435 436 if (pStreamAV->pCircBuf) 437 { 438 RTCircBufDestroy(pStreamAV->pCircBuf); 439 pStreamAV->pCircBuf = NULL; 446 440 } 447 441 … … 455 449 * @returns IPRT status code. 456 450 * @param pThis Driver instance. 457 * @param pStream 451 * @param pStreamAV Audio output stream to control. 458 452 * @param enmStreamCmd Stream command to issue. 459 453 */ 460 454 static int avRecControlStreamOut(PDRVAUDIOVIDEOREC pThis, 461 PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 462 { 463 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 464 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 465 RT_NOREF(enmStreamCmd); 466 467 RT_NOREF(pThis); 468 469 LogFlowFunc(("enmStreamCmd=%ld\n", enmStreamCmd)); 455 PAVRECSTREAM pStreamAV, PDMAUDIOSTREAMCMD enmStreamCmd) 456 { 457 RT_NOREF(pThis, pStreamAV); 470 458 471 459 switch (enmStreamCmd) … … 520 508 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture} 521 509 */ 522 static DECLCALLBACK(int) drvAudioVideoRecStreamCapture(PPDMIHOSTAUDIO pInterface, 523 PPDMAUDIOSTREAM pStream,void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)510 static DECLCALLBACK(int) drvAudioVideoRecStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 511 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 524 512 { 525 513 RT_NOREF(pInterface, pStream, pvBuf, cbBuf); … … 535 523 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay} 536 524 */ 537 static DECLCALLBACK(int) drvAudioVideoRecStreamPlay(PPDMIHOSTAUDIO pInterface, 538 PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf, 539 uint32_t *pcbWritten) 525 static DECLCALLBACK(int) drvAudioVideoRecStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 526 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten) 540 527 { 541 528 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 545 532 /* pcbWritten is optional. */ 546 533 547 PDRVAUDIOVIDEOREC pThis 534 PDRVAUDIOVIDEOREC pThis = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface); 548 535 RT_NOREF(pThis); 549 PAVRECSTREAM OUT pStreamOut = (PAVRECSTREAMOUT)pStream;536 PAVRECSTREAM pStreamAV = (PAVRECSTREAM)pStream; 550 537 551 538 int rc = VINF_SUCCESS; … … 557 544 */ 558 545 #ifdef VBOX_WITH_LIBOPUS 559 PAVRECSINK pSink = pStream Out->pSink;546 PAVRECSINK pSink = pStreamAV->pSink; 560 547 AssertPtr(pSink); 561 PRTCIRCBUF pCircBuf = pStream Out->pCircBuf;548 PRTCIRCBUF pCircBuf = pStreamAV->pCircBuf; 562 549 AssertPtr(pCircBuf); 563 550 … … 598 585 599 586 const uint32_t csFrame = pSink->Codec.Opus.csFrame; 600 const uint32_t cbFrame = PDMAUDIO PCMPROPS_S2B(&pStreamOut->Props, csFrame);587 const uint32_t cbFrame = PDMAUDIOSTREAMCFG_S2B(pStreamAV->pCfg, csFrame); 601 588 602 589 while (RTCircBufUsed(pCircBuf) >= cbFrame) … … 716 703 static DECLCALLBACK(int) drvAudioVideoRecGetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg) 717 704 { 718 NOREF(pInterface);705 RT_NOREF(pInterface); 719 706 AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER); 720 707 721 pBackendCfg->cbStreamOut = sizeof(AVRECSTREAM OUT);708 pBackendCfg->cbStreamOut = sizeof(AVRECSTREAM); 722 709 pBackendCfg->cbStreamIn = 0; 723 710 pBackendCfg->cMaxStreamsIn = 0; … … 756 743 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate} 757 744 */ 758 static DECLCALLBACK(int) drvAudioVideoRecStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream,745 static DECLCALLBACK(int) drvAudioVideoRecStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 759 746 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 760 747 { 761 748 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 762 AssertPtrReturn(pStream, VERR_INVALID_POINTER);763 749 AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER); 764 750 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER); 765 751 766 PDRVAUDIOVIDEOREC pThis = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface); 752 if (pCfgReq->enmDir == PDMAUDIODIR_IN) 753 return VERR_NOT_SUPPORTED; 754 755 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 756 757 PDRVAUDIOVIDEOREC pThis = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface); 758 PAVRECSTREAM pStreamAV = (PAVRECSTREAM)pStream; 767 759 768 760 /* For now we only have one sink, namely the driver's one. … … 770 762 PAVRECSINK pSink = &pThis->Sink; 771 763 772 if (pCfgReq->enmDir == PDMAUDIODIR_OUT) 773 return avRecCreateStreamOut(pThis, pStream, pSink, pCfgReq, pCfgAcq); 774 775 return VERR_NOT_SUPPORTED; 764 int rc = avRecCreateStreamOut(pThis, pStreamAV, pSink, pCfgReq, pCfgAcq); 765 if (RT_SUCCESS(rc)) 766 { 767 pStreamAV->pCfg = DrvAudioHlpStreamCfgDup(pCfgAcq); 768 if (!pStreamAV->pCfg) 769 rc = VERR_NO_MEMORY; 770 } 771 772 return rc; 776 773 } 777 774 … … 780 777 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy} 781 778 */ 782 static DECLCALLBACK(int) drvAudioVideoRecStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)779 static DECLCALLBACK(int) drvAudioVideoRecStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 783 780 { 784 781 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 785 782 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 786 783 787 PDRVAUDIOVIDEOREC pThis = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface); 788 789 if (pStream->enmDir == PDMAUDIODIR_OUT) 790 return avRecDestroyStreamOut(pThis, pStream); 791 792 return VINF_SUCCESS; 784 PDRVAUDIOVIDEOREC pThis = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface); 785 PAVRECSTREAM pStreamAV = (PAVRECSTREAM)pStream; 786 787 if (!pStreamAV->pCfg) /* Not (yet) configured? Skip. */ 788 return VINF_SUCCESS; 789 790 int rc = VINF_SUCCESS; 791 792 if (pStreamAV->pCfg->enmDir == PDMAUDIODIR_OUT) 793 rc = avRecDestroyStreamOut(pThis, pStreamAV); 794 795 if (RT_SUCCESS(rc)) 796 { 797 DrvAudioHlpStreamCfgFree(pStreamAV->pCfg); 798 pStreamAV->pCfg = NULL; 799 } 800 801 return rc; 793 802 } 794 803 … … 798 807 */ 799 808 static DECLCALLBACK(int) drvAudioVideoRecStreamControl(PPDMIHOSTAUDIO pInterface, 800 PPDMAUDIO STREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)809 PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 801 810 { 802 811 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 803 812 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 804 813 805 PDRVAUDIOVIDEOREC pThis = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface); 806 807 Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST); 808 809 if (pStream->enmDir == PDMAUDIODIR_OUT) 810 return avRecControlStreamOut(pThis, pStream, enmStreamCmd); 814 PDRVAUDIOVIDEOREC pThis = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface); 815 PAVRECSTREAM pStreamAV = (PAVRECSTREAM)pStream; 816 817 if (!pStreamAV->pCfg) /* Not (yet) configured? Skip. */ 818 return VINF_SUCCESS; 819 820 if (pStreamAV->pCfg->enmDir == PDMAUDIODIR_OUT) 821 return avRecControlStreamOut(pThis, pStreamAV, enmStreamCmd); 811 822 812 823 return VINF_SUCCESS; … … 817 828 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus} 818 829 */ 819 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvAudioVideoRecStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)820 { 821 NOREF(pInterface);822 NOREF(pStream);830 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvAudioVideoRecStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 831 { 832 RT_NOREF(pInterface); 833 RT_NOREF(pStream); 823 834 824 835 return ( PDMAUDIOSTRMSTS_FLAG_INITIALIZED | PDMAUDIOSTRMSTS_FLAG_ENABLED … … 830 841 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate} 831 842 */ 832 static DECLCALLBACK(int) drvAudioVideoRecStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIO STREAM pStream)843 static DECLCALLBACK(int) drvAudioVideoRecStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 833 844 { 834 845 AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
Note:
See TracChangeset
for help on using the changeset viewer.