VirtualBox

Changeset 63743 in vbox


Ignore:
Timestamp:
Sep 7, 2016 9:26:22 AM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
110532
Message:

Audio: More code for device enumeration and dynamic device handling / switching.

Location:
trunk/src/VBox/Devices/Audio
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/DrvAudio.cpp

    r63719 r63743  
    4040#include "DrvAudio.h"
    4141#include "AudioMixBuffer.h"
     42
     43static int drvAudioDevicesEnumerateInternal(PDRVAUDIO pThis, bool fLog, PPDMAUDIODEVICEENUM pDevEnum);
    4244
    4345static DECLCALLBACK(int) drvAudioStreamDestroy(PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream);
     
    618620 * @param   pThis               Pointer to driver instance.
    619621 */
    620 static int drvAudioScheduleReInit(PDRVAUDIO pThis)
     622static int drvAudioScheduleReInitInternal(PDRVAUDIO pThis)
    621623{
    622624    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     
    624626    LogFunc(("\n"));
    625627
     628    /* Mark all host streams to re-initialize. */
    626629    PPDMAUDIOSTREAM pHstStream;
    627630    RTListForEach(&pThis->lstHstStreams, pHstStream, PDMAUDIOSTREAM, Node)
    628631        pHstStream->fStatus |= PDMAUDIOSTRMSTS_FLAG_PENDING_REINIT;
    629632
     633    /* Re-enumerate all host devices as soon as possible. */
     634    pThis->fEnumerateDevices = true;
     635
    630636    return VINF_SUCCESS;
    631637}
     
    648654
    649655    PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream);
     656    AssertPtr(pHstStream);
    650657
    651658    /*
     
    673680    if (RT_SUCCESS(rc))
    674681    {
     682        PPDMAUDIOSTREAM pGstStream = pHstStream->pPair;
     683
    675684        if (fIsEnabled)
     685        {
    676686            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
    677737    }
    678738
     
    857917
    858918    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    }
    859939
    860940    /* Whether to try closing a pending to close stream. */
     
    10201100                                   pStream->szName, pStream->cRefs, pStream->fStatus, pStream->enmCtx),
    10211101                                  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 succeeded
    1027              * 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         }
    10341102
    10351103        AssertPtr(pThis->pHostDrvAudio->pfnStreamGetStatus);
     
    11321200                                  rc = VERR_NOT_AVAILABLE);
    11331201
    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 succeeded
    1138              * 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 
    11461202        AssertPtr(pThis->pHostDrvAudio->pfnStreamGetStatus);
    11471203        PDMAUDIOSTRMSTS strmSts = pThis->pHostDrvAudio->pfnStreamGetStatus(pThis->pHostDrvAudio, pHstStream);
     
    13401396 * Important: No calls back to the backend within this function, as the backend
    13411397 *            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.
    13431399 *
    13441400 * @copydoc FNPDMHOSTAUDIOCALLBACK
     
    13661422        case PDMAUDIOCBTYPE_DEVICES_CHANGED:
    13671423            LogRel(("Audio: Host audio device configuration has changed\n"));
    1368             rc = drvAudioScheduleReInit(pThis);
     1424            rc = drvAudioScheduleReInitInternal(pThis);
    13691425            break;
    13701426
     
    13821438}
    13831439#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 */
     1451static 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}
    13841508
    13851509/**
     
    14311555             RT_MIN(64, pThis->cStreamsFreeIn), RT_MIN(64, pThis->cStreamsFreeOut)));
    14321556
    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. */
    14761559
    14771560#ifdef VBOX_WITH_AUDIO_CALLBACKS
     
    14811564    if (pThis->pHostDrvAudio->pfnSetCallback)
    14821565    {
    1483         int rc2 = pThis->pHostDrvAudio->pfnSetCallback(pThis->pHostDrvAudio, drvAudioBackendCallback);
     1566        rc2 = pThis->pHostDrvAudio->pfnSetCallback(pThis->pHostDrvAudio, drvAudioBackendCallback);
    14841567        if (RT_FAILURE(rc2))
    14851568             LogRel(("Audio: Error registering backend callback, rc=%Rrc\n", rc2));
  • trunk/src/VBox/Devices/Audio/DrvAudio.h

    r63711 r63743  
    118118     *  UINT32_MAX for unlimited streams. */
    119119    uint32_t                cStreamsFreeOut;
     120    /** Flag indicating to perform an (re-)enumeration of the host audio devices. */
     121    bool                    fEnumerateDevices;
    120122    /** Audio configuration settings retrieved from the backend. */
    121123    PDMAUDIOBACKENDCFG      BackendCfg;
     
    156158PPDMAUDIODEVICE DrvAudioHlpDeviceAlloc(size_t cbData);
    157159void DrvAudioHlpDeviceFree(PPDMAUDIODEVICE pDev);
     160PPDMAUDIODEVICE DrvAudioHlpDeviceDup(PPDMAUDIODEVICE pDev, bool fCopyUserData);
    158161
    159162int DrvAudioHlpDeviceEnumInit(PPDMAUDIODEVICEENUM pDevEnm);
    160163void DrvAudioHlpDeviceEnumFree(PPDMAUDIODEVICEENUM pDevEnm);
    161164int DrvAudioHlpDeviceEnumAdd(PPDMAUDIODEVICEENUM pDevEnm, PPDMAUDIODEVICE pDev);
     165int DrvAudioHlpDeviceEnumCopyEx(PPDMAUDIODEVICEENUM pDstDevEnm, PPDMAUDIODEVICEENUM pSrcDevEnm, PDMAUDIODIR enmUsage);
     166int DrvAudioHlpDeviceEnumCopy(PPDMAUDIODEVICEENUM pDstDevEnm, PPDMAUDIODEVICEENUM pSrcDevEnm);
     167PPDMAUDIODEVICEENUM DrvAudioHlpDeviceEnumDup(PPDMAUDIODEVICEENUM pDevEnm);
     168int DrvAudioHlpDeviceEnumCopy(PPDMAUDIODEVICEENUM pDstDevEnm, PPDMAUDIODEVICEENUM pSrcDevEnm);
    162169PPDMAUDIODEVICE DrvAudioHlpDeviceEnumGetDefaultDevice(PPDMAUDIODEVICEENUM pDevEnm, PDMAUDIODIR enmDir);
    163170void DrvAudioHlpDeviceEnumPrint(const char *pszDesc, PPDMAUDIODEVICEENUM pDevEnm);
  • trunk/src/VBox/Devices/Audio/DrvAudioCommon.cpp

    r63715 r63743  
    221221    if (cbData)
    222222    {
    223         pDev->pvData = RTMemAlloc(cbData);
     223        pDev->pvData = RTMemAllocZ(cbData);
    224224        if (!pDev->pvData)
    225225        {
     
    254254
    255255        RTMemFree(pDev->pvData);
     256        pDev->pvData = NULL;
    256257    }
    257258
    258259    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 */
     270PPDMAUDIODEVICE 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;
    259292}
    260293
     
    305338 * @return IPRT status code.
    306339 * @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.
    308341 */
    309342int DrvAudioHlpDeviceEnumAdd(PPDMAUDIODEVICEENUM pDevEnm, PPDMAUDIODEVICE pDev)
     
    316349
    317350    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 */
     360PPDMAUDIODEVICEENUM 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 */
     407int 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 */
     449int DrvAudioHlpDeviceEnumCopy(PPDMAUDIODEVICEENUM pDstDevEnm, PPDMAUDIODEVICEENUM pSrcDevEnm)
     450{
     451    return DrvAudioHlpDeviceEnumCopyEx(pDstDevEnm, pSrcDevEnm, PDMAUDIODIR_ANY, false /* fCopyUserData */);
    318452}
    319453
  • trunk/src/VBox/Devices/Audio/DrvHostCoreAudio.cpp

    r63711 r63743  
    8686    /** Pointer to driver instance this device is bound to. */
    8787    PDRVHOSTCOREAUDIO pDrv;
    88     /** The audio device ID of the currently used device. */
     88    /** The audio device ID of the currently used device (UInt32 typedef). */
    8989    AudioDeviceID     deviceID;
    9090    /** List of attached (native) Core Audio streams attached to this device. */
     
    395395    /** The device is currently uninitializing. */
    396396    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. */
    398402    COREAUDIOSTATUS_REINIT,
     403#endif
    399404    /** The usual 32-bit hack. */
    400405    COREAUDIOSTATUS_32BIT_HACK = 0x7fffffff
     
    479484    /** Initialization status tracker. Used when some of the device parameters
    480485     *  or the device itself is changed during the runtime. */
    481     volatile uint32_t       status;
     486    volatile uint32_t       enmStatus;
    482487    /** An internal ring buffer for transferring data from/to the rendering callbacks. */
    483488    PRTCIRCBUF              pCircBuf;
     
    485490
    486491static int coreAudioStreamInit(PCOREAUDIOSTREAM pCAStream, PDRVHOSTCOREAUDIO pThis, PPDMAUDIODEVICE pDev);
     492#ifndef VBOX_WITH_AUDIO_CALLBACKS
    487493static int coreAudioStreamReinit(PDRVHOSTCOREAUDIO pThis, PCOREAUDIOSTREAM pCAStream, PPDMAUDIODEVICE pDev);
     494#endif
    488495static int coreAudioStreamUninit(PCOREAUDIOSTREAM pCAStream);
    489496
     
    729736                }
    730737
     738                LogFunc(("Device '%s': %RU32\n", pszName, curDevID));
     739
    731740                if (pszName)
    732741                {
     
    10231032         * This make sure this thread isn't blocked and the
    10241033         * reinitialization is done when necessary only. */
    1025         ASMAtomicXchgU32(&pCAStream->status, enmSts);
     1034        ASMAtomicXchgU32(&pCAStream->enmStatus, enmSts);
    10261035    }
    10271036
     
    10991108    AssertRC(rc2);
    11001109
    1101     OSStatus err = noErr;
    1102 
    11031110    for (UInt32 idxAddress = 0; idxAddress < nAddresses; idxAddress++)
    11041111    {
     
    11281135        LogFlowFunc(("pDev=%p\n", pDev));
    11291136
     1137#ifndef VBOX_WITH_AUDIO_CALLBACKS
    11301138        if (pDev)
    11311139        {
     
    11381146            UInt32 uResp = 0;
    11391147
    1140             err = AudioObjectGetPropertyData(kAudioObjectSystemObject, pProperty, 0, NULL, &uSize, &uResp);
     1148            OSStatus err = AudioObjectGetPropertyData(kAudioObjectSystemObject, pProperty, 0, NULL, &uSize, &uResp);
    11411149            if (err == noErr)
    11421150            {
     
    11481156            }
    11491157        }
     1158#endif /* VBOX_WITH_AUDIO_CALLBACKS */
    11501159    }
    11511160
    11521161#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;
    11551163#endif
    11561164
     1165    /* Make sure to leave the critical section before calling the callback. */
    11571166    rc2 = RTCritSectLeave(&pThis->CritSect);
    11581167    AssertRC(rc2);
    11591168
     1169#ifdef VBOX_WITH_AUDIO_CALLBACKS
     1170    if (pfnCallback)
     1171        /* Ignore rc */ pfnCallback(pThis->pDrvIns, PDMAUDIOCBTYPE_DEVICES_CHANGED, NULL, 0);
     1172#endif
     1173
    11601174    return noErr;
    11611175}
    11621176
     1177#ifndef VBOX_WITH_AUDIO_CALLBACKS
    11631178/**
    11641179 * Re-initializes a Core Audio stream with a specific audio device and stream configuration.
     
    12241239    return rc;
    12251240}
     1241#endif /* VBOX_WITH_AUDIO_CALLBACKS */
    12261242
    12271243#ifdef VBOX_WITH_AUDIO_CA_CONVERTER
     
    13351351    AssertPtr(pStream->Unit.pDevice);
    13361352
    1337     if (ASMAtomicReadU32(&pStream->status) != COREAUDIOSTATUS_INIT)
     1353    if (ASMAtomicReadU32(&pStream->enmStatus) != COREAUDIOSTATUS_INIT)
    13381354        return noErr;
    13391355
     
    16991715static int coreAudioStreamInit(PCOREAUDIOSTREAM pCAStream, PDRVHOSTCOREAUDIO pThis, PPDMAUDIODEVICE pDev)
    17001716{
     1717    AssertPtrReturn(pCAStream, VERR_INVALID_POINTER);
     1718    AssertPtrReturn(pThis,     VERR_INVALID_POINTER);
     1719    AssertPtrReturn(pDev,      VERR_INVALID_POINTER);
     1720
    17011721    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));
    17021729
    17031730    pCAStream->Unit.pDevice = pDev;
     
    17201747    OSStatus err = noErr;
    17211748
     1749    LogFunc(("pCAStream=%p, pCfgReq=%p, pCfgAcq=%p\n", pCAStream, pCfgReq, pCfgAcq));
     1750
    17221751    PPDMAUDIODEVICE pDev = pCAStream->Unit.pDevice;
    17231752    AssertPtr(pDev);
     
    17271756
    17281757    AudioDeviceID deviceID = pData->deviceID;
     1758    LogFunc(("deviceID=%RU32\n", deviceID));
    17291759    Assert(deviceID != kAudioDeviceUnknown);
    17301760
    17311761    do
    17321762    {
    1733         ASMAtomicXchgU32(&pCAStream->status, COREAUDIOSTATUS_IN_INIT);
     1763        ASMAtomicXchgU32(&pCAStream->enmStatus, COREAUDIOSTATUS_IN_INIT);
    17341764
    17351765        /* Get the default frames buffer size, so that we can setup our internal buffers. */
     
    20702100        AssertRC(rc);
    20712101
    2072         ASMAtomicXchgU32(&pCAStream->status, COREAUDIOSTATUS_INIT);
     2102        ASMAtomicXchgU32(&pCAStream->enmStatus, COREAUDIOSTATUS_INIT);
    20732103
    20742104        pCfgAcq->cSampleBufferSize = cSamples;
     
    20792109        AssertRC(rc2);
    20802110
    2081         ASMAtomicXchgU32(&pCAStream->status, COREAUDIOSTATUS_UNINIT);
     2111        ASMAtomicXchgU32(&pCAStream->enmStatus, COREAUDIOSTATUS_UNINIT);
    20822112    }
    20832113
     
    20942124    OSStatus err = noErr;
    20952125
     2126    LogFunc(("pCAStream=%p, pCfgReq=%p, pCfgAcq=%p\n", pCAStream, pCfgReq, pCfgAcq));
     2127
    20962128    PPDMAUDIODEVICE pDev = pCAStream->Unit.pDevice;
    20972129    AssertPtr(pDev);
     
    21012133
    21022134    AudioDeviceID deviceID = pData->deviceID;
     2135    LogFunc(("deviceID=%RU32\n", deviceID));
    21032136    Assert(deviceID != kAudioDeviceUnknown);
    21042137
    21052138    do
    21062139    {
    2107         ASMAtomicXchgU32(&pCAStream->status, COREAUDIOSTATUS_IN_INIT);
     2140        ASMAtomicXchgU32(&pCAStream->enmStatus, COREAUDIOSTATUS_IN_INIT);
    21082141
    21092142        /* Get the default frames buffer size, so that we can setup our internal buffers. */
     
    23062339        AssertRC(rc);
    23072340
    2308         ASMAtomicXchgU32(&pCAStream->status, COREAUDIOSTATUS_INIT);
     2341        ASMAtomicXchgU32(&pCAStream->enmStatus, COREAUDIOSTATUS_INIT);
    23092342
    23102343        pCfgAcq->cSampleBufferSize = cSamples;
     
    23152348        AssertRC(rc2);
    23162349
    2317         ASMAtomicXchgU32(&pCAStream->status, COREAUDIOSTATUS_UNINIT);
     2350        ASMAtomicXchgU32(&pCAStream->enmStatus, COREAUDIOSTATUS_UNINIT);
    23182351    }
    23192352
     
    23522385        }
    23532386
    2354         pCAStream->status = COREAUDIOSTATUS_UNINIT;
     2387        pCAStream->enmStatus = COREAUDIOSTATUS_UNINIT;
    23552388
    23562389        pCAStream->enmDir = PDMAUDIODIR_UNKNOWN;
     
    24042437    if (deviceID != kAudioDeviceUnknown)
    24052438    {
     2439        LogFunc(("deviceID=%RU32\n", deviceID));
     2440
    24062441        /*
    24072442         * Register device callbacks.
     
    24572492    if (deviceID != kAudioDeviceUnknown)
    24582493    {
     2494        LogFunc(("deviceID=%RU32\n", deviceID));
     2495
    24592496        /*
    24602497         * Unregister per-device callbacks.
     
    25162553        case kAudioDevicePropertyNominalSampleRate:
    25172554        {
     2555#ifndef VBOX_WITH_AUDIO_CALLBACKS
    25182556            int rc2 = coreAudioDevicePropagateStatus(pDev, COREAUDIOSTATUS_REINIT);
    25192557            AssertRC(rc2);
     2558#endif
    25202559            break;
    25212560        }
     
    25272566
    25282567    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 */
     2576static 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;
    25292641}
    25302642
     
    25472659    AssertPtr(pStream->Unit.pDevice);
    25482660
    2549     if (ASMAtomicReadU32(&pStream->status) != COREAUDIOSTATUS_INIT)
     2661    if (ASMAtomicReadU32(&pStream->enmStatus) != COREAUDIOSTATUS_INIT)
    25502662    {
    25512663        pBufData->mBuffers[0].mDataByteSize = 0;
     
    26172729    /* pcbRead is optional. */
    26182730
     2731    PCOREAUDIOSTREAM  pCAStream = (PCOREAUDIOSTREAM)pStream;
    26192732    PDRVHOSTCOREAUDIO pThis     = PDMIHOSTAUDIO_2_DRVHOSTCOREAUDIO(pInterface);
    2620     PCOREAUDIOSTREAM  pCAStream = (PCOREAUDIOSTREAM)pStream;
    2621 
     2733
     2734#ifndef VBOX_WITH_AUDIO_CALLBACKS
    26222735    /* 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)
    26242737    {
    26252738        /* For now re just re-initialize with the current input device. */
     
    26332746            return VERR_NOT_AVAILABLE;
    26342747    }
    2635 
    2636     if (ASMAtomicReadU32(&pCAStream->status) != COREAUDIOSTATUS_INIT)
     2748#else
     2749    RT_NOREF(pThis);
     2750#endif
     2751
     2752    if (ASMAtomicReadU32(&pCAStream->enmStatus) != COREAUDIOSTATUS_INIT)
    26372753    {
    26382754        if (pcbRead)
     
    27342850    PCOREAUDIOSTREAM  pCAStream = (PCOREAUDIOSTREAM)pStream;
    27352851
     2852#ifndef VBOX_WITH_AUDIO_CALLBACKS
    27362853    /* 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)
    27382855    {
    27392856        if (pThis->pDefaultDevOut)
     
    27472864            return VERR_NOT_AVAILABLE;
    27482865    }
     2866#else
     2867    RT_NOREF(pThis);
     2868#endif
    27492869
    27502870    uint32_t cLive = AudioMixBufLive(&pStream->MixBuf);
     
    28192939    RT_NOREF(pThis);
    28202940
    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          ))
    28262950    {
    28272951        return VINF_SUCCESS;
     
    29233047    PDRVHOSTCOREAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTCOREAUDIO(pInterface);
    29243048
    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;
    29263072}
    29273073
     
    29903136    Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST);
    29913137
    2992     PCOREAUDIOSTREAM  pCAStream = (PCOREAUDIOSTREAM)pStream;
     3138    PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream;
    29933139
    29943140    int rc;
     
    30003146    PPDMAUDIODEVICE pDev = fIn ? pThis->pDefaultDevIn : pThis->pDefaultDevOut;
    30013147
    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))
    30073155        {
    30083156            /* Sanity. */
     
    30243172            }
    30253173        }
    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 */
     3186static 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);
    30283215    }
    30293216
     
    30343221
    30353222/**
    3036  * @interface_method_impl{PDMIHOSTAUDIO, pfnStreamDestroy}
    3037  */
    3038 static DECLCALLBACK(int) drvHostCoreAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     3223 * @interface_method_impl{PDMIHOSTAUDIO, pfnStreamControl}
     3224 */
     3225static DECLCALLBACK(int) drvHostCoreAudioStreamControl(PPDMIHOSTAUDIO pInterface,
     3226                                                       PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
    30393227{
    30403228    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     
    30473235    PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream;
    30483236
    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 */
     3244static 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 */
     3278static DECLCALLBACK(int) drvHostCoreAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
    30763279{
    30773280    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    30783281    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    30793282
    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     else
    3118         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 
    31323283    /* Nothing to do here for Core Audio. */
    31333284    return VINF_SUCCESS;
     
    31453296    if (RT_SUCCESS(rc))
    31463297    {
    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);
    31843300    }
    31853301
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette