Changeset 63743 in vbox
- Timestamp:
- Sep 7, 2016 9:26:22 AM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 110532
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvAudio.cpp
r63719 r63743 40 40 #include "DrvAudio.h" 41 41 #include "AudioMixBuffer.h" 42 43 static int drvAudioDevicesEnumerateInternal(PDRVAUDIO pThis, bool fLog, PPDMAUDIODEVICEENUM pDevEnum); 42 44 43 45 static DECLCALLBACK(int) drvAudioStreamDestroy(PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream); … … 618 620 * @param pThis Pointer to driver instance. 619 621 */ 620 static int drvAudioScheduleReInit (PDRVAUDIO pThis)622 static int drvAudioScheduleReInitInternal(PDRVAUDIO pThis) 621 623 { 622 624 AssertPtrReturn(pThis, VERR_INVALID_POINTER); … … 624 626 LogFunc(("\n")); 625 627 628 /* Mark all host streams to re-initialize. */ 626 629 PPDMAUDIOSTREAM pHstStream; 627 630 RTListForEach(&pThis->lstHstStreams, pHstStream, PDMAUDIOSTREAM, Node) 628 631 pHstStream->fStatus |= PDMAUDIOSTRMSTS_FLAG_PENDING_REINIT; 629 632 633 /* Re-enumerate all host devices as soon as possible. */ 634 pThis->fEnumerateDevices = true; 635 630 636 return VINF_SUCCESS; 631 637 } … … 648 654 649 655 PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream); 656 AssertPtr(pHstStream); 650 657 651 658 /* … … 673 680 if (RT_SUCCESS(rc)) 674 681 { 682 PPDMAUDIOSTREAM pGstStream = pHstStream->pPair; 683 675 684 if (fIsEnabled) 685 { 676 686 rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_ENABLE); 687 if (RT_SUCCESS(rc)) 688 { 689 if (pGstStream) 690 { 691 /* Also reset the guest stream mixing buffer. */ 692 AudioMixBufReset(&pGstStream->MixBuf); 693 } 694 } 695 } 696 697 #ifdef VBOX_WITH_STATISTICS 698 /* 699 * Reset statistics. 700 */ 701 if (RT_SUCCESS(rc)) 702 { 703 if (pHstStream->enmDir == PDMAUDIODIR_IN) 704 { 705 STAM_COUNTER_RESET(&pHstStream->In.StatBytesElapsed); 706 STAM_COUNTER_RESET(&pHstStream->In.StatBytesTotalRead); 707 STAM_COUNTER_RESET(&pHstStream->In.StatSamplesCaptured); 708 709 if (pGstStream) 710 { 711 Assert(pGstStream->enmDir == pHstStream->enmDir); 712 713 STAM_COUNTER_RESET(&pGstStream->In.StatBytesElapsed); 714 STAM_COUNTER_RESET(&pGstStream->In.StatBytesTotalRead); 715 STAM_COUNTER_RESET(&pGstStream->In.StatSamplesCaptured); 716 } 717 } 718 else if (pHstStream->enmDir == PDMAUDIODIR_OUT) 719 { 720 STAM_COUNTER_RESET(&pHstStream->Out.StatBytesElapsed); 721 STAM_COUNTER_RESET(&pHstStream->Out.StatBytesTotalWritten); 722 STAM_COUNTER_RESET(&pHstStream->Out.StatSamplesPlayed); 723 724 if (pGstStream) 725 { 726 Assert(pGstStream->enmDir == pHstStream->enmDir); 727 728 STAM_COUNTER_RESET(&pGstStream->Out.StatBytesElapsed); 729 STAM_COUNTER_RESET(&pGstStream->Out.StatBytesTotalWritten); 730 STAM_COUNTER_RESET(&pGstStream->Out.StatSamplesPlayed); 731 } 732 } 733 else 734 AssertFailed(); 735 } 736 #endif 677 737 } 678 738 … … 857 917 858 918 int rc; 919 920 /* Is the stream scheduled for re-initialization? Do so now. */ 921 if (pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PENDING_REINIT) 922 { 923 if (pThis->fEnumerateDevices) 924 { 925 /* Re-enumerate all host devices. */ 926 drvAudioDevicesEnumerateInternal(pThis, true /* fLog */, NULL /* pDevEnum */); 927 928 pThis->fEnumerateDevices = false; 929 } 930 931 /* Remove the pending re-init flag in any case, regardless whether the actual re-initialization succeeded 932 * or not. If it failed, the backend needs to notify us again to try again at some later point in time. */ 933 pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_PENDING_REINIT; 934 935 rc = drvAudioStreamReInitInternal(pThis, pStream); 936 if (RT_FAILURE(rc)) 937 return rc; 938 } 859 939 860 940 /* Whether to try closing a pending to close stream. */ … … 1020 1100 pStream->szName, pStream->cRefs, pStream->fStatus, pStream->enmCtx), 1021 1101 rc = VERR_NOT_AVAILABLE); 1022 1023 /* Is the stream scheduled for re-initialization? Do so now. */1024 if (pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PENDING_REINIT)1025 {1026 /* Remove the pending re-init flag in any case, regardless whether the actual re-initialization succeeded1027 * or not. If it failed, the backend needs to notify us again to try again at some later point in time. */1028 pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_PENDING_REINIT;1029 1030 rc = drvAudioStreamReInitInternal(pThis, pStream);1031 if (RT_FAILURE(rc))1032 break;1033 }1034 1102 1035 1103 AssertPtr(pThis->pHostDrvAudio->pfnStreamGetStatus); … … 1132 1200 rc = VERR_NOT_AVAILABLE); 1133 1201 1134 /* Is the stream scheduled for re-initialization? Do so now. */1135 if (pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PENDING_REINIT)1136 {1137 /* Remove the pending re-init flag in any case, regardless whether the actual re-initialization succeeded1138 * or not. If it failed, the backend needs to notify us again to try again at some later point in time. */1139 pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_PENDING_REINIT;1140 1141 rc = drvAudioStreamReInitInternal(pThis, pStream);1142 if (RT_FAILURE(rc))1143 break;1144 }1145 1146 1202 AssertPtr(pThis->pHostDrvAudio->pfnStreamGetStatus); 1147 1203 PDMAUDIOSTRMSTS strmSts = pThis->pHostDrvAudio->pfnStreamGetStatus(pThis->pHostDrvAudio, pHstStream); … … 1340 1396 * Important: No calls back to the backend within this function, as the backend 1341 1397 * might hold any locks / critical sections while executing this callback. 1342 * Will result in some ugly deadlocks then.1398 * Will result in some ugly deadlocks (or at least locking order violations) then. 1343 1399 * 1344 1400 * @copydoc FNPDMHOSTAUDIOCALLBACK … … 1366 1422 case PDMAUDIOCBTYPE_DEVICES_CHANGED: 1367 1423 LogRel(("Audio: Host audio device configuration has changed\n")); 1368 rc = drvAudioScheduleReInit (pThis);1424 rc = drvAudioScheduleReInitInternal(pThis); 1369 1425 break; 1370 1426 … … 1382 1438 } 1383 1439 #endif /* VBOX_WITH_AUDIO_CALLBACKS */ 1440 1441 /** 1442 * Enumerates all host audio devices. 1443 * This functionality might not be implemented by all backends and will return VERR_NOT_SUPPORTED 1444 * if not being supported. 1445 * 1446 * @returns IPRT status code. 1447 * @param pThis Driver instance to be called. 1448 * @param fLog Whether to print the enumerated device to the release log or not. 1449 * @param pDevEnum Where to store the device enumeration. 1450 */ 1451 static int drvAudioDevicesEnumerateInternal(PDRVAUDIO pThis, bool fLog, PPDMAUDIODEVICEENUM pDevEnum) 1452 { 1453 int rc; 1454 1455 /* 1456 * If the backend supports it, do a device enumeration. 1457 */ 1458 if (pThis->pHostDrvAudio->pfnGetDevices) 1459 { 1460 PDMAUDIODEVICEENUM DevEnum; 1461 rc = pThis->pHostDrvAudio->pfnGetDevices(pThis->pHostDrvAudio, &DevEnum); 1462 if (RT_SUCCESS(rc)) 1463 { 1464 if (fLog) 1465 LogRel(("Audio: Found %RU16 devices\n", DevEnum.cDevices)); 1466 1467 PPDMAUDIODEVICE pDev; 1468 RTListForEach(&DevEnum.lstDevices, pDev, PDMAUDIODEVICE, Node) 1469 { 1470 if (fLog) 1471 { 1472 char *pszFlags = DrvAudioHlpAudDevFlagsToStrA(pDev->fFlags); 1473 1474 LogRel(("Audio: Device '%s':\n", pDev->szName)); 1475 LogRel(("Audio: \tUsage = %s\n", DrvAudioHlpAudDirToStr(pDev->enmUsage))); 1476 LogRel(("Audio: \tFlags = %s\n", pszFlags ? pszFlags : "<NONE>")); 1477 LogRel(("Audio: \tInput channels = %RU8\n", pDev->cMaxInputChannels)); 1478 LogRel(("Audio: \tOutput channels = %RU8\n", pDev->cMaxOutputChannels)); 1479 1480 if (pszFlags) 1481 RTStrFree(pszFlags); 1482 } 1483 } 1484 1485 if (pDevEnum) 1486 rc = DrvAudioHlpDeviceEnumCopy(pDevEnum, &DevEnum); 1487 1488 DrvAudioHlpDeviceEnumFree(&DevEnum); 1489 } 1490 else 1491 { 1492 if (fLog) 1493 LogRel(("Audio: Device enumeration failed with %Rrc\n", rc)); 1494 /* Not fatal. */ 1495 } 1496 } 1497 else 1498 { 1499 rc = VERR_NOT_SUPPORTED; 1500 1501 if (fLog) 1502 LogRel3(("Audio: Host audio backend does not support audio device enumeration, skipping\n")); 1503 } 1504 1505 LogFunc(("Returning %Rrc\n", rc)); 1506 return rc; 1507 } 1384 1508 1385 1509 /** … … 1431 1555 RT_MIN(64, pThis->cStreamsFreeIn), RT_MIN(64, pThis->cStreamsFreeOut))); 1432 1556 1433 /* 1434 * If the backend supports it, do a device enumeration. 1435 */ 1436 bool fLog = true; 1437 1438 if (pThis->pHostDrvAudio->pfnGetDevices) 1439 { 1440 PDMAUDIODEVICEENUM DevEnum; 1441 int rc2 = pThis->pHostDrvAudio->pfnGetDevices(pThis->pHostDrvAudio, &DevEnum); 1442 if (RT_SUCCESS(rc2)) 1443 { 1444 if (fLog) 1445 LogRel(("Audio: Found %RU16 devices\n", DevEnum.cDevices)); 1446 1447 PPDMAUDIODEVICE pDev; 1448 RTListForEach(&DevEnum.lstDevices, pDev, PDMAUDIODEVICE, Node) 1449 { 1450 if (fLog) 1451 { 1452 char *pszFlags = DrvAudioHlpAudDevFlagsToStrA(pDev->fFlags); 1453 1454 LogRel(("Audio: Device '%s':\n", pDev->szName)); 1455 LogRel(("Audio: \tUsage = %s\n", DrvAudioHlpAudDirToStr(pDev->enmUsage))); 1456 LogRel(("Audio: \tFlags = %s\n", pszFlags ? pszFlags : "<NONE>")); 1457 LogRel(("Audio: \tInput channels = %RU8\n", pDev->cMaxInputChannels)); 1458 LogRel(("Audio: \tOutput channels = %RU8\n", pDev->cMaxOutputChannels)); 1459 1460 if (pszFlags) 1461 RTStrFree(pszFlags); 1462 } 1463 } 1464 1465 DrvAudioHlpDeviceEnumFree(&DevEnum); 1466 } 1467 else 1468 { 1469 if (fLog) 1470 LogRel(("Audio: Device enumeration failed with %Rrc\n", rc2)); 1471 /* Not fatal. */ 1472 } 1473 } 1474 else if (fLog) 1475 LogRel2(("Audio: Selected host audio backend does not support audio device enumeration\n")); 1557 int rc2 = drvAudioDevicesEnumerateInternal(pThis, true /* fLog */, NULL /* pDevEnum */); 1558 /* Ignore rc. */ 1476 1559 1477 1560 #ifdef VBOX_WITH_AUDIO_CALLBACKS … … 1481 1564 if (pThis->pHostDrvAudio->pfnSetCallback) 1482 1565 { 1483 intrc2 = pThis->pHostDrvAudio->pfnSetCallback(pThis->pHostDrvAudio, drvAudioBackendCallback);1566 rc2 = pThis->pHostDrvAudio->pfnSetCallback(pThis->pHostDrvAudio, drvAudioBackendCallback); 1484 1567 if (RT_FAILURE(rc2)) 1485 1568 LogRel(("Audio: Error registering backend callback, rc=%Rrc\n", rc2)); -
trunk/src/VBox/Devices/Audio/DrvAudio.h
r63711 r63743 118 118 * UINT32_MAX for unlimited streams. */ 119 119 uint32_t cStreamsFreeOut; 120 /** Flag indicating to perform an (re-)enumeration of the host audio devices. */ 121 bool fEnumerateDevices; 120 122 /** Audio configuration settings retrieved from the backend. */ 121 123 PDMAUDIOBACKENDCFG BackendCfg; … … 156 158 PPDMAUDIODEVICE DrvAudioHlpDeviceAlloc(size_t cbData); 157 159 void DrvAudioHlpDeviceFree(PPDMAUDIODEVICE pDev); 160 PPDMAUDIODEVICE DrvAudioHlpDeviceDup(PPDMAUDIODEVICE pDev, bool fCopyUserData); 158 161 159 162 int DrvAudioHlpDeviceEnumInit(PPDMAUDIODEVICEENUM pDevEnm); 160 163 void DrvAudioHlpDeviceEnumFree(PPDMAUDIODEVICEENUM pDevEnm); 161 164 int DrvAudioHlpDeviceEnumAdd(PPDMAUDIODEVICEENUM pDevEnm, PPDMAUDIODEVICE pDev); 165 int DrvAudioHlpDeviceEnumCopyEx(PPDMAUDIODEVICEENUM pDstDevEnm, PPDMAUDIODEVICEENUM pSrcDevEnm, PDMAUDIODIR enmUsage); 166 int DrvAudioHlpDeviceEnumCopy(PPDMAUDIODEVICEENUM pDstDevEnm, PPDMAUDIODEVICEENUM pSrcDevEnm); 167 PPDMAUDIODEVICEENUM DrvAudioHlpDeviceEnumDup(PPDMAUDIODEVICEENUM pDevEnm); 168 int DrvAudioHlpDeviceEnumCopy(PPDMAUDIODEVICEENUM pDstDevEnm, PPDMAUDIODEVICEENUM pSrcDevEnm); 162 169 PPDMAUDIODEVICE DrvAudioHlpDeviceEnumGetDefaultDevice(PPDMAUDIODEVICEENUM pDevEnm, PDMAUDIODIR enmDir); 163 170 void DrvAudioHlpDeviceEnumPrint(const char *pszDesc, PPDMAUDIODEVICEENUM pDevEnm); -
trunk/src/VBox/Devices/Audio/DrvAudioCommon.cpp
r63715 r63743 221 221 if (cbData) 222 222 { 223 pDev->pvData = RTMemAlloc (cbData);223 pDev->pvData = RTMemAllocZ(cbData); 224 224 if (!pDev->pvData) 225 225 { … … 254 254 255 255 RTMemFree(pDev->pvData); 256 pDev->pvData = NULL; 256 257 } 257 258 258 259 RTMemFree(pDev); 260 pDev = NULL; 261 } 262 263 /** 264 * Duplicates an audio device entry. 265 * 266 * @returns Duplicated audio device entry on success, or NULL on failure. 267 * @param pDev Audio device entry to duplicate. 268 * @param fCopyUserData Whether to also copy the user data portion or not. 269 */ 270 PPDMAUDIODEVICE DrvAudioHlpDeviceDup(PPDMAUDIODEVICE pDev, bool fCopyUserData) 271 { 272 AssertPtrReturn(pDev, NULL); 273 274 PPDMAUDIODEVICE pDevDup = DrvAudioHlpDeviceAlloc(fCopyUserData ? pDev->cbData : 0); 275 if (pDevDup) 276 { 277 memcpy(pDevDup, pDev, sizeof(PDMAUDIODEVICE)); 278 279 if ( fCopyUserData 280 && pDevDup->cbData) 281 { 282 memcpy(pDevDup->pvData, pDev->pvData, pDevDup->cbData); 283 } 284 else 285 { 286 pDevDup->cbData = 0; 287 pDevDup->pvData = NULL; 288 } 289 } 290 291 return pDevDup; 259 292 } 260 293 … … 305 338 * @return IPRT status code. 306 339 * @param pDevEnm Device enumeration to add device to. 307 * @param pDev Device to add. 340 * @param pDev Device to add. The pointer will be owned by the device enumeration then. 308 341 */ 309 342 int DrvAudioHlpDeviceEnumAdd(PPDMAUDIODEVICEENUM pDevEnm, PPDMAUDIODEVICE pDev) … … 316 349 317 350 return VINF_SUCCESS; 351 } 352 353 /** 354 * Duplicates a device enumeration. 355 * 356 * @returns Duplicated device enumeration, or NULL on failure. 357 * Must be free'd with DrvAudioHlpDeviceEnumFree(). 358 * @param pDevEnm Device enumeration to duplicate. 359 */ 360 PPDMAUDIODEVICEENUM DrvAudioHlpDeviceEnumDup(PPDMAUDIODEVICEENUM pDevEnm) 361 { 362 AssertPtrReturn(pDevEnm, NULL); 363 364 PPDMAUDIODEVICEENUM pDevEnmDup = (PPDMAUDIODEVICEENUM)RTMemAlloc(sizeof(PDMAUDIODEVICEENUM)); 365 if (!pDevEnmDup) 366 return NULL; 367 368 int rc2 = DrvAudioHlpDeviceEnumInit(pDevEnmDup); 369 AssertRC(rc2); 370 371 PPDMAUDIODEVICE pDev; 372 RTListForEach(&pDevEnm->lstDevices, pDev, PDMAUDIODEVICE, Node) 373 { 374 PPDMAUDIODEVICE pDevDup = DrvAudioHlpDeviceDup(pDev, true /* fCopyUserData */); 375 if (!pDevDup) 376 { 377 rc2 = VERR_NO_MEMORY; 378 break; 379 } 380 381 rc2 = DrvAudioHlpDeviceEnumAdd(pDevEnmDup, pDevDup); 382 if (RT_FAILURE(rc2)) 383 { 384 DrvAudioHlpDeviceFree(pDevDup); 385 break; 386 } 387 } 388 389 if (RT_FAILURE(rc2)) 390 { 391 DrvAudioHlpDeviceEnumFree(pDevEnmDup); 392 pDevEnmDup = NULL; 393 } 394 395 return pDevEnmDup; 396 } 397 398 /** 399 * Copies device enumeration entries from the source to the destination enumeration. 400 * 401 * @returns IPRT status code. 402 * @param pDstDevEnm Destination enumeration to store enumeration entries into. 403 * @param pSrcDevEnm Source enumeration to use. 404 * @param enmUsage Which entries to copy. Specify PDMAUDIODIR_ANY to copy all entries. 405 * @param fCopyUserData Whether to also copy the user data portion or not. 406 */ 407 int DrvAudioHlpDeviceEnumCopyEx(PPDMAUDIODEVICEENUM pDstDevEnm, PPDMAUDIODEVICEENUM pSrcDevEnm, 408 PDMAUDIODIR enmUsage, bool fCopyUserData) 409 { 410 AssertPtrReturn(pDstDevEnm, VERR_INVALID_POINTER); 411 AssertPtrReturn(pSrcDevEnm, VERR_INVALID_POINTER); 412 413 int rc = VINF_SUCCESS; 414 415 PPDMAUDIODEVICE pSrcDev; 416 RTListForEach(&pSrcDevEnm->lstDevices, pSrcDev, PDMAUDIODEVICE, Node) 417 { 418 if ( enmUsage != PDMAUDIODIR_ANY 419 && enmUsage != pSrcDev->enmUsage) 420 { 421 continue; 422 } 423 424 PPDMAUDIODEVICE pDstDev = DrvAudioHlpDeviceDup(pSrcDev, fCopyUserData); 425 if (!pDstDev) 426 { 427 rc = VERR_NO_MEMORY; 428 break; 429 } 430 431 rc = DrvAudioHlpDeviceEnumAdd(pDstDevEnm, pDstDev); 432 if (RT_FAILURE(rc)) 433 break; 434 } 435 436 return rc; 437 } 438 439 /** 440 * Copies all device enumeration entries from the source to the destination enumeration. 441 * 442 * Note: Does *not* copy the user-specific data assigned to a device enumeration entry. 443 * To do so, use DrvAudioHlpDeviceEnumCopyEx(). 444 * 445 * @returns IPRT status code. 446 * @param pDstDevEnm Destination enumeration to store enumeration entries into. 447 * @param pSrcDevEnm Source enumeration to use. 448 */ 449 int DrvAudioHlpDeviceEnumCopy(PPDMAUDIODEVICEENUM pDstDevEnm, PPDMAUDIODEVICEENUM pSrcDevEnm) 450 { 451 return DrvAudioHlpDeviceEnumCopyEx(pDstDevEnm, pSrcDevEnm, PDMAUDIODIR_ANY, false /* fCopyUserData */); 318 452 } 319 453 -
trunk/src/VBox/Devices/Audio/DrvHostCoreAudio.cpp
r63711 r63743 86 86 /** Pointer to driver instance this device is bound to. */ 87 87 PDRVHOSTCOREAUDIO pDrv; 88 /** The audio device ID of the currently used device . */88 /** The audio device ID of the currently used device (UInt32 typedef). */ 89 89 AudioDeviceID deviceID; 90 90 /** List of attached (native) Core Audio streams attached to this device. */ … … 395 395 /** The device is currently uninitializing. */ 396 396 COREAUDIOSTATUS_IN_UNINIT, 397 /* The device has to be reinitialized */ 397 #ifndef VBOX_WITH_AUDIO_CALLBACKS 398 /** The device has to be reinitialized. 399 * Note: Only needed if VBOX_WITH_AUDIO_CALLBACKS is not defined, as otherwise 400 * the Audio Connector will take care of this as soon as this backend 401 * tells it to do so via the provided audio callback. */ 398 402 COREAUDIOSTATUS_REINIT, 403 #endif 399 404 /** The usual 32-bit hack. */ 400 405 COREAUDIOSTATUS_32BIT_HACK = 0x7fffffff … … 479 484 /** Initialization status tracker. Used when some of the device parameters 480 485 * or the device itself is changed during the runtime. */ 481 volatile uint32_t status;486 volatile uint32_t enmStatus; 482 487 /** An internal ring buffer for transferring data from/to the rendering callbacks. */ 483 488 PRTCIRCBUF pCircBuf; … … 485 490 486 491 static int coreAudioStreamInit(PCOREAUDIOSTREAM pCAStream, PDRVHOSTCOREAUDIO pThis, PPDMAUDIODEVICE pDev); 492 #ifndef VBOX_WITH_AUDIO_CALLBACKS 487 493 static int coreAudioStreamReinit(PDRVHOSTCOREAUDIO pThis, PCOREAUDIOSTREAM pCAStream, PPDMAUDIODEVICE pDev); 494 #endif 488 495 static int coreAudioStreamUninit(PCOREAUDIOSTREAM pCAStream); 489 496 … … 729 736 } 730 737 738 LogFunc(("Device '%s': %RU32\n", pszName, curDevID)); 739 731 740 if (pszName) 732 741 { … … 1023 1032 * This make sure this thread isn't blocked and the 1024 1033 * reinitialization is done when necessary only. */ 1025 ASMAtomicXchgU32(&pCAStream-> status, enmSts);1034 ASMAtomicXchgU32(&pCAStream->enmStatus, enmSts); 1026 1035 } 1027 1036 … … 1099 1108 AssertRC(rc2); 1100 1109 1101 OSStatus err = noErr;1102 1103 1110 for (UInt32 idxAddress = 0; idxAddress < nAddresses; idxAddress++) 1104 1111 { … … 1128 1135 LogFlowFunc(("pDev=%p\n", pDev)); 1129 1136 1137 #ifndef VBOX_WITH_AUDIO_CALLBACKS 1130 1138 if (pDev) 1131 1139 { … … 1138 1146 UInt32 uResp = 0; 1139 1147 1140 err = AudioObjectGetPropertyData(kAudioObjectSystemObject, pProperty, 0, NULL, &uSize, &uResp);1148 OSStatus err = AudioObjectGetPropertyData(kAudioObjectSystemObject, pProperty, 0, NULL, &uSize, &uResp); 1141 1149 if (err == noErr) 1142 1150 { … … 1148 1156 } 1149 1157 } 1158 #endif /* VBOX_WITH_AUDIO_CALLBACKS */ 1150 1159 } 1151 1160 1152 1161 #ifdef VBOX_WITH_AUDIO_CALLBACKS 1153 if (pThis->pfnCallback) 1154 /* Ignore rc */ pThis->pfnCallback(pThis->pDrvIns, PDMAUDIOCBTYPE_DEVICES_CHANGED, NULL, 0); 1162 PFNPDMHOSTAUDIOCALLBACK pfnCallback = pThis->pfnCallback; 1155 1163 #endif 1156 1164 1165 /* Make sure to leave the critical section before calling the callback. */ 1157 1166 rc2 = RTCritSectLeave(&pThis->CritSect); 1158 1167 AssertRC(rc2); 1159 1168 1169 #ifdef VBOX_WITH_AUDIO_CALLBACKS 1170 if (pfnCallback) 1171 /* Ignore rc */ pfnCallback(pThis->pDrvIns, PDMAUDIOCBTYPE_DEVICES_CHANGED, NULL, 0); 1172 #endif 1173 1160 1174 return noErr; 1161 1175 } 1162 1176 1177 #ifndef VBOX_WITH_AUDIO_CALLBACKS 1163 1178 /** 1164 1179 * Re-initializes a Core Audio stream with a specific audio device and stream configuration. … … 1224 1239 return rc; 1225 1240 } 1241 #endif /* VBOX_WITH_AUDIO_CALLBACKS */ 1226 1242 1227 1243 #ifdef VBOX_WITH_AUDIO_CA_CONVERTER … … 1335 1351 AssertPtr(pStream->Unit.pDevice); 1336 1352 1337 if (ASMAtomicReadU32(&pStream-> status) != COREAUDIOSTATUS_INIT)1353 if (ASMAtomicReadU32(&pStream->enmStatus) != COREAUDIOSTATUS_INIT) 1338 1354 return noErr; 1339 1355 … … 1699 1715 static int coreAudioStreamInit(PCOREAUDIOSTREAM pCAStream, PDRVHOSTCOREAUDIO pThis, PPDMAUDIODEVICE pDev) 1700 1716 { 1717 AssertPtrReturn(pCAStream, VERR_INVALID_POINTER); 1718 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1719 AssertPtrReturn(pDev, VERR_INVALID_POINTER); 1720 1701 1721 Assert(pCAStream->Unit.pDevice == NULL); /* Make sure no device is assigned yet. */ 1722 1723 AssertPtr(pDev->pvData); 1724 Assert(pDev->cbData == sizeof(COREAUDIODEVICEDATA)); 1725 1726 PCOREAUDIODEVICEDATA pData = (PCOREAUDIODEVICEDATA)pDev->pvData; 1727 1728 LogFunc(("pCAStream=%p, pDev=%p ('%s', ID=%RU32)\n", pCAStream, pDev, pDev->szName, pData->deviceID)); 1702 1729 1703 1730 pCAStream->Unit.pDevice = pDev; … … 1720 1747 OSStatus err = noErr; 1721 1748 1749 LogFunc(("pCAStream=%p, pCfgReq=%p, pCfgAcq=%p\n", pCAStream, pCfgReq, pCfgAcq)); 1750 1722 1751 PPDMAUDIODEVICE pDev = pCAStream->Unit.pDevice; 1723 1752 AssertPtr(pDev); … … 1727 1756 1728 1757 AudioDeviceID deviceID = pData->deviceID; 1758 LogFunc(("deviceID=%RU32\n", deviceID)); 1729 1759 Assert(deviceID != kAudioDeviceUnknown); 1730 1760 1731 1761 do 1732 1762 { 1733 ASMAtomicXchgU32(&pCAStream-> status, COREAUDIOSTATUS_IN_INIT);1763 ASMAtomicXchgU32(&pCAStream->enmStatus, COREAUDIOSTATUS_IN_INIT); 1734 1764 1735 1765 /* Get the default frames buffer size, so that we can setup our internal buffers. */ … … 2070 2100 AssertRC(rc); 2071 2101 2072 ASMAtomicXchgU32(&pCAStream-> status, COREAUDIOSTATUS_INIT);2102 ASMAtomicXchgU32(&pCAStream->enmStatus, COREAUDIOSTATUS_INIT); 2073 2103 2074 2104 pCfgAcq->cSampleBufferSize = cSamples; … … 2079 2109 AssertRC(rc2); 2080 2110 2081 ASMAtomicXchgU32(&pCAStream-> status, COREAUDIOSTATUS_UNINIT);2111 ASMAtomicXchgU32(&pCAStream->enmStatus, COREAUDIOSTATUS_UNINIT); 2082 2112 } 2083 2113 … … 2094 2124 OSStatus err = noErr; 2095 2125 2126 LogFunc(("pCAStream=%p, pCfgReq=%p, pCfgAcq=%p\n", pCAStream, pCfgReq, pCfgAcq)); 2127 2096 2128 PPDMAUDIODEVICE pDev = pCAStream->Unit.pDevice; 2097 2129 AssertPtr(pDev); … … 2101 2133 2102 2134 AudioDeviceID deviceID = pData->deviceID; 2135 LogFunc(("deviceID=%RU32\n", deviceID)); 2103 2136 Assert(deviceID != kAudioDeviceUnknown); 2104 2137 2105 2138 do 2106 2139 { 2107 ASMAtomicXchgU32(&pCAStream-> status, COREAUDIOSTATUS_IN_INIT);2140 ASMAtomicXchgU32(&pCAStream->enmStatus, COREAUDIOSTATUS_IN_INIT); 2108 2141 2109 2142 /* Get the default frames buffer size, so that we can setup our internal buffers. */ … … 2306 2339 AssertRC(rc); 2307 2340 2308 ASMAtomicXchgU32(&pCAStream-> status, COREAUDIOSTATUS_INIT);2341 ASMAtomicXchgU32(&pCAStream->enmStatus, COREAUDIOSTATUS_INIT); 2309 2342 2310 2343 pCfgAcq->cSampleBufferSize = cSamples; … … 2315 2348 AssertRC(rc2); 2316 2349 2317 ASMAtomicXchgU32(&pCAStream-> status, COREAUDIOSTATUS_UNINIT);2350 ASMAtomicXchgU32(&pCAStream->enmStatus, COREAUDIOSTATUS_UNINIT); 2318 2351 } 2319 2352 … … 2352 2385 } 2353 2386 2354 pCAStream-> status = COREAUDIOSTATUS_UNINIT;2387 pCAStream->enmStatus = COREAUDIOSTATUS_UNINIT; 2355 2388 2356 2389 pCAStream->enmDir = PDMAUDIODIR_UNKNOWN; … … 2404 2437 if (deviceID != kAudioDeviceUnknown) 2405 2438 { 2439 LogFunc(("deviceID=%RU32\n", deviceID)); 2440 2406 2441 /* 2407 2442 * Register device callbacks. … … 2457 2492 if (deviceID != kAudioDeviceUnknown) 2458 2493 { 2494 LogFunc(("deviceID=%RU32\n", deviceID)); 2495 2459 2496 /* 2460 2497 * Unregister per-device callbacks. … … 2516 2553 case kAudioDevicePropertyNominalSampleRate: 2517 2554 { 2555 #ifndef VBOX_WITH_AUDIO_CALLBACKS 2518 2556 int rc2 = coreAudioDevicePropagateStatus(pDev, COREAUDIOSTATUS_REINIT); 2519 2557 AssertRC(rc2); 2558 #endif 2520 2559 break; 2521 2560 } … … 2527 2566 2528 2567 return noErr; 2568 } 2569 2570 /** 2571 * Enumerates all available host audio devices internally. 2572 * 2573 * @returns IPRT status code. 2574 * @param pThis Host audio driver instance. 2575 */ 2576 static int coreAudioEnumerateDevices(PDRVHOSTCOREAUDIO pThis) 2577 { 2578 LogFlowFuncEnter(); 2579 2580 /* 2581 * Unregister old default devices, if any. 2582 */ 2583 if (pThis->pDefaultDevIn) 2584 { 2585 coreAudioDeviceUnregisterCallbacks(pThis, pThis->pDefaultDevIn); 2586 pThis->pDefaultDevIn = NULL; 2587 } 2588 2589 if (pThis->pDefaultDevOut) 2590 { 2591 coreAudioDeviceUnregisterCallbacks(pThis, pThis->pDefaultDevOut); 2592 pThis->pDefaultDevOut = NULL; 2593 } 2594 2595 /* Remove old / stale device entries. */ 2596 DrvAudioHlpDeviceEnumFree(&pThis->Devices); 2597 2598 /* Enumerate all devices internally. */ 2599 int rc = coreAudioDevicesEnumerateAll(pThis, &pThis->Devices); 2600 if (RT_SUCCESS(rc)) 2601 { 2602 /* 2603 * Default input device. 2604 */ 2605 pThis->pDefaultDevIn = DrvAudioHlpDeviceEnumGetDefaultDevice(&pThis->Devices, PDMAUDIODIR_IN); 2606 if (pThis->pDefaultDevIn) 2607 { 2608 LogRel2(("CoreAudio: Default capturing device is '%s'\n", pThis->pDefaultDevIn->szName)); 2609 2610 #ifdef DEBUG 2611 PCOREAUDIODEVICEDATA pDevData = (PCOREAUDIODEVICEDATA)pThis->pDefaultDevIn->pvData; 2612 AssertPtr(pDevData); 2613 LogFunc(("pDefaultDevIn=%p, ID=%RU32\n", pThis->pDefaultDevIn, pDevData->deviceID)); 2614 #endif 2615 rc = coreAudioDeviceRegisterCallbacks(pThis, pThis->pDefaultDevIn); 2616 } 2617 else 2618 LogRel2(("CoreAudio: No default capturing device found\n")); 2619 2620 /* 2621 * Default output device. 2622 */ 2623 pThis->pDefaultDevOut = DrvAudioHlpDeviceEnumGetDefaultDevice(&pThis->Devices, PDMAUDIODIR_OUT); 2624 if (pThis->pDefaultDevOut) 2625 { 2626 LogRel2(("CoreAudio: Default playback device is '%s'\n", pThis->pDefaultDevOut->szName)); 2627 2628 #ifdef DEBUG 2629 PCOREAUDIODEVICEDATA pDevData = (PCOREAUDIODEVICEDATA)pThis->pDefaultDevOut->pvData; 2630 AssertPtr(pDevData); 2631 LogFunc(("pDefaultDevOut=%p, ID=%RU32\n", pThis->pDefaultDevOut, pDevData->deviceID)); 2632 #endif 2633 rc = coreAudioDeviceRegisterCallbacks(pThis, pThis->pDefaultDevOut); 2634 } 2635 else 2636 LogRel2(("CoreAudio: No default playback device found\n")); 2637 } 2638 2639 LogFunc(("Returning %Rrc\n", rc)); 2640 return rc; 2529 2641 } 2530 2642 … … 2547 2659 AssertPtr(pStream->Unit.pDevice); 2548 2660 2549 if (ASMAtomicReadU32(&pStream-> status) != COREAUDIOSTATUS_INIT)2661 if (ASMAtomicReadU32(&pStream->enmStatus) != COREAUDIOSTATUS_INIT) 2550 2662 { 2551 2663 pBufData->mBuffers[0].mDataByteSize = 0; … … 2617 2729 /* pcbRead is optional. */ 2618 2730 2731 PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream; 2619 2732 PDRVHOSTCOREAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTCOREAUDIO(pInterface); 2620 PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream; 2621 2733 2734 #ifndef VBOX_WITH_AUDIO_CALLBACKS 2622 2735 /* Check if the audio device should be reinitialized. If so do it. */ 2623 if (ASMAtomicReadU32(&pCAStream-> status) == COREAUDIOSTATUS_REINIT)2736 if (ASMAtomicReadU32(&pCAStream->enmStatus) == COREAUDIOSTATUS_REINIT) 2624 2737 { 2625 2738 /* For now re just re-initialize with the current input device. */ … … 2633 2746 return VERR_NOT_AVAILABLE; 2634 2747 } 2635 2636 if (ASMAtomicReadU32(&pCAStream->status) != COREAUDIOSTATUS_INIT) 2748 #else 2749 RT_NOREF(pThis); 2750 #endif 2751 2752 if (ASMAtomicReadU32(&pCAStream->enmStatus) != COREAUDIOSTATUS_INIT) 2637 2753 { 2638 2754 if (pcbRead) … … 2734 2850 PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream; 2735 2851 2852 #ifndef VBOX_WITH_AUDIO_CALLBACKS 2736 2853 /* Check if the audio device should be reinitialized. If so do it. */ 2737 if (ASMAtomicReadU32(&pCAStream-> status) == COREAUDIOSTATUS_REINIT)2854 if (ASMAtomicReadU32(&pCAStream->enmStatus) == COREAUDIOSTATUS_REINIT) 2738 2855 { 2739 2856 if (pThis->pDefaultDevOut) … … 2747 2864 return VERR_NOT_AVAILABLE; 2748 2865 } 2866 #else 2867 RT_NOREF(pThis); 2868 #endif 2749 2869 2750 2870 uint32_t cLive = AudioMixBufLive(&pStream->MixBuf); … … 2819 2939 RT_NOREF(pThis); 2820 2940 2821 LogFlowFunc(("enmStreamCmd=%RU32\n", enmStreamCmd)); 2822 2823 uint32_t uStatus = ASMAtomicReadU32(&pCAStream->status); 2824 if (!( uStatus == COREAUDIOSTATUS_INIT 2825 || uStatus == COREAUDIOSTATUS_REINIT)) 2941 uint32_t enmStatus = ASMAtomicReadU32(&pCAStream->enmStatus); 2942 2943 LogFlowFunc(("enmStreamCmd=%RU32, enmStatus=%RU32\n", enmStreamCmd, enmStatus)); 2944 2945 if (!( enmStatus == COREAUDIOSTATUS_INIT 2946 #ifndef VBOX_WITH_AUDIO_CALLBACKS 2947 || enmStatus == COREAUDIOSTATUS_REINIT 2948 #endif 2949 )) 2826 2950 { 2827 2951 return VINF_SUCCESS; … … 2923 3047 PDRVHOSTCOREAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTCOREAUDIO(pInterface); 2924 3048 2925 return coreAudioDevicesEnumerateAll(pThis, pDeviceEnum); 3049 int rc = RTCritSectEnter(&pThis->CritSect); 3050 if (RT_SUCCESS(rc)) 3051 { 3052 rc = coreAudioEnumerateDevices(pThis); 3053 if (RT_SUCCESS(rc)) 3054 { 3055 if (pDeviceEnum) 3056 { 3057 rc = DrvAudioHlpDeviceEnumInit(pDeviceEnum); 3058 if (RT_SUCCESS(rc)) 3059 rc = DrvAudioHlpDeviceEnumCopy(pDeviceEnum, &pThis->Devices); 3060 3061 if (RT_FAILURE(rc)) 3062 DrvAudioHlpDeviceEnumFree(pDeviceEnum); 3063 } 3064 } 3065 3066 int rc2 = RTCritSectLeave(&pThis->CritSect); 3067 AssertRC(rc2); 3068 } 3069 3070 LogFlowFunc(("Returning %Rrc\n", rc)); 3071 return rc; 2926 3072 } 2927 3073 … … 2990 3136 Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST); 2991 3137 2992 PCOREAUDIOSTREAM 3138 PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream; 2993 3139 2994 3140 int rc; … … 3000 3146 PPDMAUDIODEVICE pDev = fIn ? pThis->pDefaultDevIn : pThis->pDefaultDevOut; 3001 3147 3002 /* Init the Core Audio stream. */ 3003 rc = coreAudioStreamInit(pCAStream, pThis, pDev); 3004 if (RT_SUCCESS(rc)) 3005 { 3006 if (pDev) /* (Default) device available? */ 3148 LogFunc(("pStream=%p, pCfgReq=%p, pCfgAcq=%p, fIn=%RTbool, pDev=%p\n", pStream, pCfgReq, pCfgAcq, fIn, pDev)); 3149 3150 if (pDev) /* (Default) device available? */ 3151 { 3152 /* Init the Core Audio stream. */ 3153 rc = coreAudioStreamInit(pCAStream, pThis, pDev); 3154 if (RT_SUCCESS(rc)) 3007 3155 { 3008 3156 /* Sanity. */ … … 3024 3172 } 3025 3173 } 3026 else 3027 rc = VERR_NOT_AVAILABLE; 3174 } 3175 else 3176 rc = VERR_NOT_AVAILABLE; 3177 3178 LogFunc(("Returning %Rrc\n", rc)); 3179 return rc; 3180 } 3181 3182 3183 /** 3184 * @interface_method_impl{PDMIHOSTAUDIO, pfnStreamDestroy} 3185 */ 3186 static DECLCALLBACK(int) drvHostCoreAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 3187 { 3188 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 3189 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 3190 3191 PDRVHOSTCOREAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTCOREAUDIO(pInterface); 3192 3193 Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST); 3194 3195 PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream; 3196 3197 uint32_t status = ASMAtomicReadU32(&pCAStream->enmStatus); 3198 if (!( status == COREAUDIOSTATUS_INIT 3199 #ifndef VBOX_WITH_AUDIO_CALLBACKS 3200 || status == COREAUDIOSTATUS_REINIT 3201 #endif 3202 )) 3203 { 3204 return VINF_SUCCESS; 3205 } 3206 3207 int rc = coreAudioStreamControl(pThis, pCAStream, PDMAUDIOSTREAMCMD_DISABLE); 3208 if (RT_SUCCESS(rc)) 3209 { 3210 ASMAtomicXchgU32(&pCAStream->enmStatus, COREAUDIOSTATUS_IN_UNINIT); 3211 3212 rc = coreAudioStreamUninit(pCAStream); 3213 if (RT_SUCCESS(rc)) 3214 ASMAtomicXchgU32(&pCAStream->enmStatus, COREAUDIOSTATUS_UNINIT); 3028 3215 } 3029 3216 … … 3034 3221 3035 3222 /** 3036 * @interface_method_impl{PDMIHOSTAUDIO, pfnStreamDestroy} 3037 */ 3038 static DECLCALLBACK(int) drvHostCoreAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 3223 * @interface_method_impl{PDMIHOSTAUDIO, pfnStreamControl} 3224 */ 3225 static DECLCALLBACK(int) drvHostCoreAudioStreamControl(PPDMIHOSTAUDIO pInterface, 3226 PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 3039 3227 { 3040 3228 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 3047 3235 PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream; 3048 3236 3049 uint32_t status = ASMAtomicReadU32(&pCAStream->status); 3050 if (!( status == COREAUDIOSTATUS_INIT 3051 || status == COREAUDIOSTATUS_REINIT)) 3052 { 3053 return VINF_SUCCESS; 3054 } 3055 3056 int rc = coreAudioStreamControl(pThis, pCAStream, PDMAUDIOSTREAMCMD_DISABLE); 3057 if (RT_SUCCESS(rc)) 3058 { 3059 ASMAtomicXchgU32(&pCAStream->status, COREAUDIOSTATUS_IN_UNINIT); 3060 3061 rc = coreAudioStreamUninit(pCAStream); 3062 if (RT_SUCCESS(rc)) 3063 ASMAtomicXchgU32(&pCAStream->status, COREAUDIOSTATUS_UNINIT); 3064 } 3065 3066 LogFlowFunc(("%s: rc=%Rrc\n", pStream->szName, rc)); 3067 return rc; 3068 } 3069 3070 3071 /** 3072 * @interface_method_impl{PDMIHOSTAUDIO, pfnStreamControl} 3073 */ 3074 static DECLCALLBACK(int) drvHostCoreAudioStreamControl(PPDMIHOSTAUDIO pInterface, 3075 PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 3237 return coreAudioStreamControl(pThis, pCAStream, enmStreamCmd); 3238 } 3239 3240 3241 /** 3242 * @interface_method_impl{PDMIHOSTAUDIO, pfnStreamGetStatus} 3243 */ 3244 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostCoreAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 3245 { 3246 RT_NOREF(pInterface); 3247 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 3248 3249 Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST); 3250 3251 PDMAUDIOSTRMSTS strmSts = PDMAUDIOSTRMSTS_FLAG_NONE; 3252 3253 PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream; 3254 3255 if (ASMAtomicReadU32(&pCAStream->enmStatus) == COREAUDIOSTATUS_INIT) 3256 strmSts |= PDMAUDIOSTRMSTS_FLAG_INITIALIZED | PDMAUDIOSTRMSTS_FLAG_ENABLED; 3257 3258 if (pStream->enmDir == PDMAUDIODIR_IN) 3259 { 3260 if (strmSts & PDMAUDIOSTRMSTS_FLAG_ENABLED) 3261 strmSts |= PDMAUDIOSTRMSTS_FLAG_DATA_READABLE; 3262 } 3263 else if (pStream->enmDir == PDMAUDIODIR_OUT) 3264 { 3265 if (strmSts & PDMAUDIOSTRMSTS_FLAG_ENABLED) 3266 strmSts |= PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE; 3267 } 3268 else 3269 AssertFailed(); 3270 3271 return strmSts; 3272 } 3273 3274 3275 /** 3276 * @interface_method_impl{PDMIHOSTAUDIO, pfnStreamIterate} 3277 */ 3278 static DECLCALLBACK(int) drvHostCoreAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 3076 3279 { 3077 3280 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 3078 3281 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 3079 3282 3080 PDRVHOSTCOREAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTCOREAUDIO(pInterface);3081 3082 Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST);3083 3084 PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream;3085 3086 return coreAudioStreamControl(pThis, pCAStream, enmStreamCmd);3087 }3088 3089 3090 /**3091 * @interface_method_impl{PDMIHOSTAUDIO, pfnStreamGetStatus}3092 */3093 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostCoreAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)3094 {3095 RT_NOREF(pInterface);3096 AssertPtrReturn(pStream, VERR_INVALID_POINTER);3097 3098 Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST);3099 3100 PDMAUDIOSTRMSTS strmSts = PDMAUDIOSTRMSTS_FLAG_NONE;3101 3102 PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream;3103 3104 if (ASMAtomicReadU32(&pCAStream->status) == COREAUDIOSTATUS_INIT)3105 strmSts |= PDMAUDIOSTRMSTS_FLAG_INITIALIZED | PDMAUDIOSTRMSTS_FLAG_ENABLED;3106 3107 if (pStream->enmDir == PDMAUDIODIR_IN)3108 {3109 if (strmSts & PDMAUDIOSTRMSTS_FLAG_ENABLED)3110 strmSts |= PDMAUDIOSTRMSTS_FLAG_DATA_READABLE;3111 }3112 else if (pStream->enmDir == PDMAUDIODIR_OUT)3113 {3114 if (strmSts & PDMAUDIOSTRMSTS_FLAG_ENABLED)3115 strmSts |= PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE;3116 }3117 else3118 AssertFailed();3119 3120 return strmSts;3121 }3122 3123 3124 /**3125 * @interface_method_impl{PDMIHOSTAUDIO, pfnStreamIterate}3126 */3127 static DECLCALLBACK(int) drvHostCoreAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)3128 {3129 AssertPtrReturn(pInterface, VERR_INVALID_POINTER);3130 AssertPtrReturn(pStream, VERR_INVALID_POINTER);3131 3132 3283 /* Nothing to do here for Core Audio. */ 3133 3284 return VINF_SUCCESS; … … 3145 3296 if (RT_SUCCESS(rc)) 3146 3297 { 3147 /* Enumerate all devices internally. */ 3148 rc = coreAudioDevicesEnumerateAll(pThis, &pThis->Devices); 3149 if (RT_SUCCESS(rc)) 3150 { 3151 if (pThis->pDefaultDevIn) 3152 coreAudioDeviceUnregisterCallbacks(pThis, pThis->pDefaultDevIn); 3153 3154 pThis->pDefaultDevIn = DrvAudioHlpDeviceEnumGetDefaultDevice(&pThis->Devices, PDMAUDIODIR_IN); 3155 if (pThis->pDefaultDevIn) 3156 { 3157 #ifdef DEBUG 3158 PCOREAUDIODEVICEDATA pDevData = (PCOREAUDIODEVICEDATA)pThis->pDefaultDevIn; 3159 AssertPtr(pDevData); 3160 LogFunc(("defaultDevIn ID=%RU32\n", pDevData->deviceID)); 3161 #endif 3162 rc = coreAudioDeviceRegisterCallbacks(pThis, pThis->pDefaultDevIn); 3163 } 3164 else 3165 LogRel2(("CoreAudio: No initial default capturing device found!\n")); 3166 3167 if (pThis->pDefaultDevOut) 3168 coreAudioDeviceUnregisterCallbacks(pThis, pThis->pDefaultDevOut); 3169 3170 pThis->pDefaultDevOut = DrvAudioHlpDeviceEnumGetDefaultDevice(&pThis->Devices, PDMAUDIODIR_OUT); 3171 if (pThis->pDefaultDevOut) 3172 { 3173 #ifdef DEBUG 3174 PCOREAUDIODEVICEDATA pDevData = (PCOREAUDIODEVICEDATA)pThis->pDefaultDevOut; 3175 AssertPtr(pDevData); 3176 3177 LogFunc(("defaultDevOut ID=%RU32\n", pDevData->deviceID)); 3178 #endif 3179 rc = coreAudioDeviceRegisterCallbacks(pThis, pThis->pDefaultDevOut); 3180 } 3181 else 3182 LogRel2(("CoreAudio: No initial default playback device found!\n")); 3183 } 3298 /* Do the first (initial) internal device enumeration. */ 3299 rc = coreAudioEnumerateDevices(pThis); 3184 3300 } 3185 3301
Note:
See TracChangeset
for help on using the changeset viewer.