VirtualBox

Changeset 58744 in vbox for trunk/src/VBox/Devices/Audio


Ignore:
Timestamp:
Nov 18, 2015 3:41:04 PM (9 years ago)
Author:
vboxsync
Message:

Audio: Update for audio notification support.

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

Legend:

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

    r58600 r58744  
    13941394}
    13951395
     1396#ifdef VBOX_WITH_AUDIO_CALLBACKS
     1397static PPDMAUDIOCALLBACK drvAudioCallbackDuplicate(PPDMAUDIOCALLBACK pCB)
     1398{
     1399    PPDMAUDIOCALLBACK pCBCopy = (PPDMAUDIOCALLBACK)RTMemDup((void *)pCB, sizeof(PDMAUDIOCALLBACK));
     1400    if (!pCBCopy)
     1401        return NULL;
     1402
     1403    if (pCB->pvCtx)
     1404    {
     1405        pCBCopy->pvCtx = RTMemDup(pCB->pvCtx, pCB->cbCtx);
     1406        if (!pCBCopy->pvCtx)
     1407        {
     1408            RTMemFree(pCBCopy);
     1409            return NULL;
     1410        }
     1411
     1412        pCBCopy->cbCtx = pCB->cbCtx;
     1413    }
     1414
     1415    return pCBCopy;
     1416}
     1417
     1418static void drvAudioCallbackDestroy(PPDMAUDIOCALLBACK pCB)
     1419{
     1420    if (!pCB)
     1421        return;
     1422
     1423    RTListNodeRemove(&pCB->Node);
     1424    if (pCB->pvCtx)
     1425    {
     1426        Assert(pCB->cbCtx);
     1427        RTMemFree(pCB->pvCtx);
     1428    }
     1429    RTMemFree(pCB);
     1430}
     1431
     1432static DECLCALLBACK(int) drvAudioRegisterCallbacks(PPDMIAUDIOCONNECTOR pInterface,
     1433                                                   PPDMAUDIOCALLBACK paCallbacks, size_t cCallbacks)
     1434{
     1435    AssertPtrReturn(pInterface,  VERR_INVALID_POINTER);
     1436    AssertPtrReturn(paCallbacks, VERR_INVALID_POINTER);
     1437    AssertReturn(cCallbacks,     VERR_INVALID_PARAMETER);
     1438
     1439    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
     1440    int          rc = VINF_SUCCESS;
     1441
     1442    for (size_t i = 0; i < cCallbacks; i++)
     1443    {
     1444        PPDMAUDIOCALLBACK pCB = drvAudioCallbackDuplicate(&paCallbacks[i]);
     1445        if (!pCB)
     1446        {
     1447            rc = VERR_NO_MEMORY;
     1448            break;
     1449        }
     1450
     1451        switch (pCB->enmType)
     1452        {
     1453            case PDMAUDIOCALLBACKTYPE_INPUT:
     1454                RTListAppend(&pThis->lstCBIn, &pCB->Node);
     1455                break;
     1456
     1457            case PDMAUDIOCALLBACKTYPE_OUTPUT:
     1458                RTListAppend(&pThis->lstCBOut, &pCB->Node);
     1459                break;
     1460
     1461            default:
     1462                AssertMsgFailed(("Not supported\n"));
     1463                break;
     1464        }
     1465    }
     1466
     1467    /** @todo Undo allocations on error. */
     1468
     1469    return rc;
     1470}
     1471
     1472static DECLCALLBACK(int) drvAudioCallback(PPDMIAUDIOCONNECTOR pInterface, PDMAUDIOCALLBACKTYPE enmType,
     1473                                          void *pvUser, size_t cbUser)
     1474{
     1475    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     1476    AssertPtrReturn(pvUser,     VERR_INVALID_POINTER);
     1477    AssertReturn(cbUser,        VERR_INVALID_PARAMETER);
     1478
     1479    PDRVAUDIO     pThis       = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
     1480    PRTLISTANCHOR pListAnchor = NULL;
     1481
     1482    switch (enmType)
     1483    {
     1484        case PDMAUDIOCALLBACKTYPE_INPUT:
     1485            pListAnchor = &pThis->lstCBIn;
     1486            break;
     1487
     1488        case PDMAUDIOCALLBACKTYPE_OUTPUT:
     1489            pListAnchor = &pThis->lstCBOut;
     1490            break;
     1491
     1492        default:
     1493            AssertMsgFailed(("Not supported\n"));
     1494            break;
     1495    }
     1496
     1497    if (pListAnchor)
     1498    {
     1499        PPDMAUDIOCALLBACK pCB;
     1500        RTListForEach(pListAnchor, pCB, PDMAUDIOCALLBACK, Node)
     1501        {
     1502            Assert(pCB->enmType == enmType);
     1503            pCB->pfnCallback(enmType, pCB->pvCtx, pCB->cbCtx, pvUser, cbUser);
     1504        }
     1505    }
     1506
     1507    return VINF_SUCCESS;
     1508}
     1509#endif
     1510
    13961511static int drvAudioHostInit(PCFGMNODE pCfgHandle, PDRVAUDIO pThis)
    13971512{
     
    15301645    RTListInit(&pThis->lstHstStrmIn);
    15311646    RTListInit(&pThis->lstHstStrmOut);
     1647#ifdef VBOX_WITH_AUDIO_CALLBACKS
     1648    RTListInit(&pThis->lstCBIn);
     1649    RTListInit(&pThis->lstCBOut);
     1650#endif
    15321651
    15331652    int rc = VINF_SUCCESS;
     
    19652084        pThis->pHostDrvAudio->pfnShutdown(pThis->pHostDrvAudio);
    19662085
     2086#ifdef VBOX_WITH_AUDIO_CALLBACKS
     2087    PPDMAUDIOCALLBACK pCB, pCBNext;
     2088    RTListForEachSafe(&pThis->lstCBIn, pCB, pCBNext, PDMAUDIOCALLBACK, Node)
     2089        drvAudioCallbackDestroy(pCB);
     2090
     2091    RTListForEachSafe(&pThis->lstCBOut, pCB, pCBNext, PDMAUDIOCALLBACK, Node)
     2092        drvAudioCallbackDestroy(pCB);
     2093#endif
     2094
    19672095    LogFlowFuncLeave();
    19682096}
     
    19862114    /* IBase. */
    19872115    pDrvIns->IBase.pfnQueryInterface                 = drvAudioQueryInterface;
    1988     /* IAudio. */
     2116    /* IAudioConnector. */
    19892117    pThis->IAudioConnector.pfnQueryStatus            = drvAudioQueryStatus;
    19902118    pThis->IAudioConnector.pfnRead                   = drvAudioRead;
     
    20022130    pThis->IAudioConnector.pfnCreateOut              = drvAudioCreateOut;
    20032131    pThis->IAudioConnector.pfnPlayOut                = drvAudioPlayOut;
     2132#ifdef VBOX_WITH_AUDIO_CALLBACKS
     2133    pThis->IAudioConnector.pfnRegisterCallbacks      = drvAudioRegisterCallbacks;
     2134    pThis->IAudioConnector.pfnCallback               = drvAudioCallback;
     2135#endif
    20042136
    20052137    /*
  • trunk/src/VBox/Devices/Audio/DrvAudio.h

    r58378 r58744  
    8383    /** Shutdown indicator. */
    8484    bool                    fTerminate;
    85     /** The audio interface presented to the device/driver above us. */
     85    /** Our audio connector interface. */
    8686    PDMIAUDIOCONNECTOR      IAudioConnector;
    8787    /** Pointer to the driver instance. */
     
    9898     *  from the backend. */
    9999    PDMAUDIOBACKENDCFG      BackendCfg;
    100 
     100#ifdef VBOX_WITH_AUDIO_CALLBACKS
     101    /** @todo Use a map with primary key set to the callback type? */
     102    RTLISTANCHOR            lstCBIn;
     103    RTLISTANCHOR            lstCBOut;
     104#endif
    101105} DRVAUDIO, *PDRVAUDIO;
    102106
    103 /** Makes a PDRVBLOCK out of a PPDMIBLOCK. */
     107/** Makes a PDRVAUDIO out of a PPDMIAUDIOCONNECTOR. */
    104108#define PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface) \
    105109    ( (PDRVAUDIO)((uintptr_t)pInterface - RT_OFFSETOF(DRVAUDIO, IAudioConnector)) )
  • trunk/src/VBox/Devices/Audio/DrvHostDSound.cpp

    r58736 r58744  
    114114{
    115115    /** Pointer to the driver instance structure. */
    116     PPDMDRVINS    pDrvIns;
    117     /** Pointer to host audio interface. */
    118     PDMIHOSTAUDIO IHostAudio;
     116    PPDMDRVINS          pDrvIns;
     117    /** Our audio host audio interface. */
     118    PDMIHOSTAUDIO       IHostAudio;
    119119    /** List of found host input devices. */
    120     RTLISTANCHOR  lstDevInput;
     120    RTLISTANCHOR        lstDevInput;
    121121    /** List of found host output devices. */
    122     RTLISTANCHOR  lstDevOutput;
     122    RTLISTANCHOR        lstDevOutput;
    123123    /** DirectSound configuration options. */
    124     DSOUNDHOSTCFG cfg;
     124    DSOUNDHOSTCFG       cfg;
    125125#ifdef VBOX_WITH_AUDIO_CALLBACKS
     126    /** Pointer to the audio connector interface of the driver/device above us. */
     127    PPDMIAUDIOCONNECTOR pUpIAudioConnector;
    126128    /** Stopped indicator. */
    127     bool          fStopped;
     129    bool                fStopped;
    128130    /** Shutdown indicator. */
    129     bool          fShutdown;
     131    bool                fShutdown;
    130132    /** Notification thread. */
    131     RTTHREAD      Thread;
     133    RTTHREAD            Thread;
    132134    /** Array of events to wait for in notification thread. */
    133     HANDLE        aEvents[VBOX_DSOUND_MAX_EVENTS];
     135    HANDLE              aEvents[VBOX_DSOUND_MAX_EVENTS];
    134136    /** Number of events to wait for in notification thread.
    135137     *  Must not exceed VBOX_DSOUND_MAX_EVENTS. */
    136     uint8_t       cEvents;
    137     PDSOUNDSTREAMIN pStrmIn;
    138     PDSOUNDSTREAMOUT pStrmOut;
     138    uint8_t             cEvents;
     139    PDSOUNDSTREAMIN     pStrmIn;
     140    PDSOUNDSTREAMOUT    pStrmOut;
    139141#endif
    140142} DRVHOSTDSOUND, *PDRVHOSTDSOUND;
     
    429431            pThis->pStrmOut = NULL;
    430432        }
     433
     434        int rc2 = dsoundNotifyThread(pThis, false /* fShutdown */);
     435        AssertRC(rc2);
    431436#endif
    432437        IDirectSoundBuffer8_Release(pDSoundStrmOut->pDSB);
     
    17241729                    DWORD cbPlayPos;
    17251730                    hr = IDirectSoundCaptureBuffer8_GetCurrentPosition(pThis->pStrmOut->pDSB, NULL, &cbPlayPos);
     1731                    if (SUCCEEDED(hr))
     1732                    {
    17261733                        LogFlowFunc(("Output: hr=%Rhrc, dwPlayPos=%ld\n", hr, cbPlayPos));
     1734
     1735                        uint32_t cbFree = pThis->pStrmOut->csPlaybackBufferSize - pThis->pStrmOut->cbPlayWritePos;
     1736
     1737                        AssertPtr(pThis->pUpIAudioConnector);
     1738                        pThis->pUpIAudioConnector->pfnCallback(pThis->pUpIAudioConnector, PDMAUDIOCALLBACKTYPE_OUTPUT, &cbFree, sizeof(cbFree));
    17271739                    }
     1740                }
    17281741                break;
    17291742            }
     
    19001913
    19011914    /*
    1902      * Init the static parts.
     1915     * Init basic data members and interfaces.
    19031916     */
    19041917    pThis->pDrvIns                   = pDrvIns;
     
    19081921    PDMAUDIO_IHOSTAUDIO_CALLBACKS(drvHostDSound);
    19091922
     1923#ifdef VBOX_WITH_AUDIO_CALLBACKS
     1924    /*
     1925     * Get the IAudioConnector interface of the above driver/device.
     1926     */
     1927    pThis->pUpIAudioConnector = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIAUDIOCONNECTOR);
     1928    if (!pThis->pUpIAudioConnector)
     1929    {
     1930        AssertMsgFailed(("Configuration error: No audio connector interface above!\n"));
     1931        return VERR_PDM_MISSING_INTERFACE_ABOVE;
     1932    }
     1933#endif
     1934
     1935    /*
     1936     * Init the static parts.
     1937     */
    19101938    RTListInit(&pThis->lstDevInput);
    19111939    RTListInit(&pThis->lstDevOutput);
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