VirtualBox

儲存庫 vbox 的更動 62966


忽略:
時間撮記:
2016-8-4 上午10:15:55 (8 年 以前)
作者:
vboxsync
訊息:

Devices: warnings

檔案:
修改 1 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/Devices/Audio/DrvHostNullAudio.cpp

    r61924 r62966  
    4141 * THE SOFTWARE.
    4242 */
    43 #include <iprt/alloc.h>
     43
     44/*********************************************************************************************************************************
     45*   Header Files                                                                                                                 *
     46*********************************************************************************************************************************/
     47#include <iprt/mem.h>
    4448#include <iprt/uuid.h> /* For PDMIBASE_2_PDMDRV. */
    4549
     
    5357
    5458
     59/*********************************************************************************************************************************
     60*   Structures and Typedefs                                                                                                      *
     61*********************************************************************************************************************************/
    5562typedef struct NULLAUDIOSTREAMOUT
    5663{
    57     /** Note: Always must come first! */
    58     PDMAUDIOSTREAM     Stream;
    59     uint64_t           u64TicksLast;
    60     uint64_t           csPlayBuffer;
    61     uint8_t           *pu8PlayBuffer;
    62 } NULLAUDIOSTREAMOUT, *PNULLAUDIOSTREAMOUT;
     64    PDMAUDIOSTREAM      Stream;
     65    uint64_t            u64TicksLast;
     66    uint64_t            csPlayBuffer;
     67    uint8_t            *pu8PlayBuffer;
     68} NULLAUDIOSTREAMOUT;
     69typedef NULLAUDIOSTREAMOUT *PNULLAUDIOSTREAMOUT;
    6370
    6471typedef struct NULLAUDIOSTREAMIN
    6572{
    66     /** Note: Always must come first! */
    67     PDMAUDIOSTREAM     Stream;
    68 } NULLAUDIOSTREAMIN, *PNULLAUDIOSTREAMIN;
     73    /** @note Always must come first! */
     74    PDMAUDIOSTREAM      Stream;
     75} NULLAUDIOSTREAMIN;
     76typedef NULLAUDIOSTREAMIN *PNULLAUDIOSTREAMIN;
    6977
    7078/**
     
    7583{
    7684    /** Pointer to the driver instance structure. */
    77     PPDMDRVINS    pDrvIns;
     85    PPDMDRVINS          pDrvIns;
    7886    /** Pointer to host audio interface. */
    79     PDMIHOSTAUDIO IHostAudio;
     87    PDMIHOSTAUDIO       IHostAudio;
    8088} DRVHOSTNULLAUDIO, *PDRVHOSTNULLAUDIO;
    8189
    82 /*******************************************PDM_AUDIO_DRIVER******************************/
    83 
    84 
     90
     91
     92/**
     93 * @interface_method_impl{PDMIHOSTAUDIO,pfnGetConfig}
     94 */
    8595static DECLCALLBACK(int) drvHostNullAudioGetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pCfg)
    8696{
     
    101111}
    102112
     113
     114/**
     115 * @interface_method_impl{PDMIHOSTAUDIO,pfnInit}
     116 */
    103117static DECLCALLBACK(int) drvHostNullAudioInit(PPDMIHOSTAUDIO pInterface)
    104118{
     
    109123}
    110124
    111 static int nullCreateStreamIn(PPDMIHOSTAUDIO pInterface,
    112                               PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfg, uint32_t *pcSamples)
    113 {
    114     NOREF(pInterface);
    115 
     125
     126/**
     127 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay}
     128 */
     129static DECLCALLBACK(int) drvHostNullAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, uint32_t *pcSamplesPlayed)
     130{
     131    PDRVHOSTNULLAUDIO   pDrv        = RT_FROM_MEMBER(pInterface, DRVHOSTNULLAUDIO, IHostAudio);
     132    PNULLAUDIOSTREAMOUT pNullStream = RT_FROM_MEMBER(pStream, NULLAUDIOSTREAMOUT, Stream);
     133
     134    /* Consume as many samples as would be played at the current frequency since last call. */
     135    uint32_t cLive           = AudioMixBufLive(&pStream->MixBuf);
     136
     137    uint64_t u64TicksNow     = PDMDrvHlpTMGetVirtualTime(pDrv->pDrvIns);
     138    uint64_t u64TicksElapsed = u64TicksNow  - pNullStream->u64TicksLast;
     139    uint64_t u64TicksFreq    = PDMDrvHlpTMGetVirtualFreq(pDrv->pDrvIns);
     140
     141    /* Remember when samples were consumed. */
     142    pNullStream->u64TicksLast = u64TicksNow;
     143
     144    /*
     145     * Minimize the rounding error by adding 0.5: samples = int((u64TicksElapsed * samplesFreq) / u64TicksFreq + 0.5).
     146     * If rounding is not taken into account then the playback rate will be consistently lower that expected.
     147     */
     148    uint64_t cSamplesPlayed = (2 * u64TicksElapsed * pStream->Props.uHz + u64TicksFreq) / u64TicksFreq / 2;
     149
     150    /* Don't play more than available. */
     151    if (cSamplesPlayed > cLive)
     152        cSamplesPlayed = cLive;
     153
     154    cSamplesPlayed = RT_MIN(cSamplesPlayed, pNullStream->csPlayBuffer);
     155
     156    uint32_t csRead = 0;
     157    AudioMixBufReadCirc(&pStream->MixBuf, pNullStream->pu8PlayBuffer, AUDIOMIXBUF_S2B(&pStream->MixBuf, cSamplesPlayed), &csRead);
     158    AudioMixBufFinish(&pStream->MixBuf, csRead);
     159
     160    if (pcSamplesPlayed)
     161        *pcSamplesPlayed = csRead;
     162
     163    return VINF_SUCCESS;
     164}
     165
     166
     167/**
     168 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture}
     169 */
     170static DECLCALLBACK(int)
     171drvHostNullAudioStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, uint32_t *pcSamplesCaptured)
     172{
     173    RT_NOREF(pInterface, pStream);
     174
     175    /* Never capture anything. */
     176    if (pcSamplesCaptured)
     177        *pcSamplesCaptured = 0;
     178
     179    return VINF_SUCCESS;
     180}
     181
     182
     183/**
     184 * @interface_method_impl{PDMIHOSTAUDIO,pfnGetStatus}
     185 */
     186static DECLCALLBACK(PDMAUDIOBACKENDSTS) drvHostNullAudioGetStatus(PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir)
     187{
     188    RT_NOREF(enmDir);
     189    AssertPtrReturn(pInterface, PDMAUDIOBACKENDSTS_UNKNOWN);
     190
     191    return PDMAUDIOBACKENDSTS_RUNNING;
     192}
     193
     194
     195static int nullCreateStreamIn(PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfg, uint32_t *pcSamples)
     196{
    116197    /* Just adopt the wanted stream configuration. */
    117198    int rc = DrvAudioHlpStreamCfgToProps(pCfg, &pStream->Props);
     
    126207}
    127208
    128 static int nullCreateStreamOut(PPDMIHOSTAUDIO pInterface,
    129                                PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfg,
    130                                uint32_t *pcSamples)
    131 {
    132     NOREF(pInterface);
    133 
     209
     210static int nullCreateStreamOut(PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfg, uint32_t *pcSamples)
     211{
    134212    /* Just adopt the wanted stream configuration. */
    135213    int rc = DrvAudioHlpStreamCfgToProps(pCfg, &pStream->Props);
    136214    if (RT_SUCCESS(rc))
    137215    {
    138         PNULLAUDIOSTREAMOUT pNullStream = (PNULLAUDIOSTREAMOUT)pStream;
     216        PNULLAUDIOSTREAMOUT pNullStream = RT_FROM_MEMBER(pStream, NULLAUDIOSTREAMOUT, Stream);
    139217        pNullStream->u64TicksLast  = 0;
    140218        pNullStream->csPlayBuffer  = _1K;
     
    153231}
    154232
    155 static DECLCALLBACK(int) drvHostNullAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream,
    156                                                     uint32_t *pcSamplesPlayed)
    157 {
    158     PDRVHOSTNULLAUDIO pDrv = RT_FROM_MEMBER(pInterface, DRVHOSTNULLAUDIO, IHostAudio);
    159     PNULLAUDIOSTREAMOUT pNullStream = (PNULLAUDIOSTREAMOUT)pStream;
    160 
    161     /* Consume as many samples as would be played at the current frequency since last call. */
    162     uint32_t cLive           = AudioMixBufLive(&pStream->MixBuf);
    163 
    164     uint64_t u64TicksNow     = PDMDrvHlpTMGetVirtualTime(pDrv->pDrvIns);
    165     uint64_t u64TicksElapsed = u64TicksNow  - pNullStream->u64TicksLast;
    166     uint64_t u64TicksFreq    = PDMDrvHlpTMGetVirtualFreq(pDrv->pDrvIns);
    167 
    168     /* Remember when samples were consumed. */
    169     pNullStream->u64TicksLast = u64TicksNow;
    170 
    171     /*
    172      * Minimize the rounding error by adding 0.5: samples = int((u64TicksElapsed * samplesFreq) / u64TicksFreq + 0.5).
    173      * If rounding is not taken into account then the playback rate will be consistently lower that expected.
    174      */
    175     uint64_t cSamplesPlayed = (2 * u64TicksElapsed * pStream->Props.uHz + u64TicksFreq) / u64TicksFreq / 2;
    176 
    177     /* Don't play more than available. */
    178     if (cSamplesPlayed > cLive)
    179         cSamplesPlayed = cLive;
    180 
    181     cSamplesPlayed = RT_MIN(cSamplesPlayed, pNullStream->csPlayBuffer);
    182 
    183     uint32_t csRead = 0;
    184     AudioMixBufReadCirc(&pStream->MixBuf, pNullStream->pu8PlayBuffer,
    185                         AUDIOMIXBUF_S2B(&pStream->MixBuf, cSamplesPlayed), &csRead);
    186     AudioMixBufFinish(&pStream->MixBuf, csRead);
    187 
    188     if (pcSamplesPlayed)
    189         *pcSamplesPlayed = csRead;
    190 
    191     return VINF_SUCCESS;
    192 }
    193 
    194 static DECLCALLBACK(int) drvHostNullAudioStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream,
    195                                                        uint32_t *pcSamplesCaptured)
    196 {
    197     /* Never capture anything. */
    198     if (pcSamplesCaptured)
    199         *pcSamplesCaptured = 0;
    200 
    201     return VINF_SUCCESS;
    202 }
    203 
    204 static int nullDestroyStreamIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     233
     234/**
     235 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate}
     236 */
     237static DECLCALLBACK(int)
     238drvHostNullAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfg, uint32_t *pcSamples)
     239{
     240    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     241    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
     242    AssertPtrReturn(pCfg,       VERR_INVALID_POINTER);
     243
     244    int rc;
     245    if (pCfg->enmDir == PDMAUDIODIR_IN)
     246        rc = nullCreateStreamIn( pStream, pCfg, pcSamples);
     247    else
     248        rc = nullCreateStreamOut(pStream, pCfg, pcSamples);
     249
     250    LogFlowFunc(("%s: rc=%Rrc\n", pStream->szName, rc));
     251    return rc;
     252}
     253
     254
     255static int nullDestroyStreamIn(void)
    205256{
    206257    LogFlowFuncLeaveRC(VINF_SUCCESS);
     
    208259}
    209260
    210 static int nullDestroyStreamOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
    211 {
    212     PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
    213 
    214     PNULLAUDIOSTREAMOUT pNullStream = (PNULLAUDIOSTREAMOUT)pStream;
     261
     262static int nullDestroyStreamOut(PPDMAUDIOSTREAM pStream)
     263{
     264    PNULLAUDIOSTREAMOUT pNullStream = RT_FROM_MEMBER(pStream, NULLAUDIOSTREAMOUT, Stream);
    215265    if (   pNullStream
    216266        && pNullStream->pu8PlayBuffer)
     
    224274}
    225275
    226 static DECLCALLBACK(PDMAUDIOBACKENDSTS) drvHostNullAudioGetStatus(PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir)
    227 {
    228     AssertPtrReturn(pInterface, PDMAUDIOBACKENDSTS_UNKNOWN);
    229 
    230     return PDMAUDIOBACKENDSTS_RUNNING;
    231 }
    232 
    233 static DECLCALLBACK(int) drvHostNullAudioStreamCreate(PPDMIHOSTAUDIO pInterface,
    234                                                       PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfg, uint32_t *pcSamples)
     276
     277/**
     278 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy}
     279 */
     280static DECLCALLBACK(int) drvHostNullAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
    235281{
    236282    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    237283    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    238     AssertPtrReturn(pCfg,       VERR_INVALID_POINTER);
    239284
    240285    int rc;
    241     if (pCfg->enmDir == PDMAUDIODIR_IN)
    242         rc = nullCreateStreamIn(pInterface,  pStream, pCfg, pcSamples);
     286    if (pStream->enmDir == PDMAUDIODIR_IN)
     287        rc = nullDestroyStreamIn();
    243288    else
    244         rc = nullCreateStreamOut(pInterface, pStream, pCfg, pcSamples);
    245 
    246     LogFlowFunc(("%s: rc=%Rrc\n", pStream->szName, rc));
     289        rc = nullDestroyStreamOut(pStream);
     290
    247291    return rc;
    248292}
    249293
    250 static DECLCALLBACK(int) drvHostNullAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
    251 {
     294
     295/**
     296 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl}
     297 */
     298static DECLCALLBACK(int)
     299drvHostNullAudioStreamControl(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
     300{
     301    RT_NOREF(enmStreamCmd);
    252302    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    253303    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    254304
    255     int rc;
    256     if (pStream->enmDir == PDMAUDIODIR_IN)
    257         rc = nullDestroyStreamIn(pInterface,  pStream);
    258     else
    259         rc = nullDestroyStreamOut(pInterface, pStream);
    260 
    261     return rc;
    262 }
    263 
    264 static DECLCALLBACK(int) drvHostNullAudioStreamControl(PPDMIHOSTAUDIO pInterface,
    265                                                        PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
    266 {
    267     AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    268     AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    269 
    270305    Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST);
    271306
     
    273308}
    274309
     310
     311/**
     312 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
     313 */
    275314static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostNullAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     315{
     316    RT_NOREF(pInterface, pStream);
     317    return PDMAUDIOSTRMSTS_FLAG_INITIALIZED | PDMAUDIOSTRMSTS_FLAG_ENABLED
     318         | PDMAUDIOSTRMSTS_FLAG_DATA_READABLE | PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE;
     319}
     320
     321
     322/**
     323 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate}
     324 */
     325static DECLCALLBACK(int) drvHostNullAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
    276326{
    277327    NOREF(pInterface);
    278328    NOREF(pStream);
    279329
    280     return (  PDMAUDIOSTRMSTS_FLAG_INITIALIZED | PDMAUDIOSTRMSTS_FLAG_ENABLED
    281             | PDMAUDIOSTRMSTS_FLAG_DATA_READABLE | PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE);
    282 }
    283 
    284 static DECLCALLBACK(int) drvHostNullAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
    285 {
    286     NOREF(pInterface);
    287     NOREF(pStream);
    288 
    289     return VINF_SUCCESS;
    290 }
     330    return VINF_SUCCESS;
     331}
     332
     333
     334/**
     335 * @interface_method_impl{PDMIHOSTAUDIO,pfnShutdown}
     336 */
     337static DECLCALLBACK(void) drvHostNullAudioShutdown(PPDMIHOSTAUDIO pInterface)
     338{
     339    RT_NOREF(pInterface);
     340}
     341
    291342
    292343/**
     
    303354}
    304355
    305 static DECLCALLBACK(void) drvHostNullAudioShutdown(PPDMIHOSTAUDIO pInterface)
    306 {
    307     NOREF(pInterface);
    308 }
    309356
    310357/**
     
    315362static DECLCALLBACK(int) drvHostNullAudioConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
    316363{
     364    RT_NOREF(pCfg, fFlags);
     365    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    317366    AssertPtrReturn(pDrvIns, VERR_INVALID_POINTER);
    318367    /* pCfg is optional. */
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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