VirtualBox

Changeset 65624 in vbox


Ignore:
Timestamp:
Feb 6, 2017 2:13:36 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
113296
Message:

Audio: More abstraction for the backends: Now the backend stream's data is completely separate from the audio connector interface. That way the backends cannot mess with the audio connector's data (e.g. mixing buffers and friends) anymore, and those are forced to use the audio connector API as meant now. Needs more testing, partly work in progress.

Location:
trunk
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/pdmaudioifs.h

    r65565 r65624  
    44
    55/*
    6  * Copyright (C) 2006-2016 Oracle Corporation
     6 * Copyright (C) 2006-2017 Oracle Corporation
    77 *
    88 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    337337
    338338/**
     339 * Properties of audio streams for host/guest
     340 * for in or out directions.
     341 */
     342typedef struct PDMAUDIOPCMPROPS
     343{
     344    /** Sample width. Bits per sample. */
     345    uint8_t     cBits;
     346    /** Signed or unsigned sample. */
     347    bool        fSigned;
     348    /** Shift count used for faster calculation of various
     349     *  values, such as the alignment, bytes to samples and so on.
     350     *  Depends on number of stream channels and the stream format
     351     *  being used.
     352     *
     353     ** @todo Use some RTAsmXXX functions instead?
     354     */
     355    uint8_t     cShift;
     356    /** Number of audio channels. */
     357    uint8_t     cChannels;
     358    /** Sample frequency in Hertz (Hz). */
     359    uint32_t    uHz;
     360    /** Whether the endianness is swapped or not. */
     361    bool        fSwapEndian;
     362} PDMAUDIOPCMPROPS, *PPDMAUDIOPCMPROPS;
     363
     364/** Calculates the cShift value of given samples bits and audio channels.
     365 *  Note: Does only support mono/stereo channels for now. */
     366#define PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(cBits, cChannels)     ((cChannels == 2) + cBits / 16)
     367/** Calculates the cShift value of a PDMAUDIOPCMPROPS structure.
     368 *  Note: Does only support mono/stereo channels for now. */
     369#define PDMAUDIOPCMPROPS_MAKE_SHIFT(pProps)                     PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS((pProps)->cChannels == 2) + (pProps)->cBits / 16)
     370/** Converts (audio) samples to bytes.
     371 *  Needs the cShift value set correctly, using PDMAUDIOPCMPROPS_MAKE_SHIFT. */
     372#define PDMAUDIOPCMPROPS_S2B(pProps, samples)                   ((samples) << (pProps)->cShift)
     373/** Converts bytes to (audio) samples.
     374 *  Needs the cShift value set correctly, using PDMAUDIOPCMPROPS_MAKE_SHIFT. */
     375#define PDMAUDIOPCMPROPS_B2S(pProps, cb)                        (cb >> (pProps)->cShift)
     376
     377/**
    339378 * Structure for keeping an audio stream configuration.
    340379 */
     
    347386    /** Destination / source indicator, depending on enmDir. */
    348387    PDMAUDIODESTSOURCE       DestSource;
    349     /** Frequency in Hertz (Hz). */
    350     uint32_t                 uHz;
    351     /** Number of audio channels (2 for stereo, 1 for mono). */
    352     uint8_t                  cChannels;
    353     /** Audio format. */
    354     PDMAUDIOFMT              enmFormat;
    355     /** @todo Use RT_LE2H_*? */
    356     PDMAUDIOENDIANNESS       enmEndianness;
     388    /** The stream's PCM properties. */
     389    PDMAUDIOPCMPROPS         Props;
    357390    /** Hint about the optimal sample buffer size (in audio samples).
    358391     *  0 if no hint is given. */
    359     uint32_t                 cSampleBufferSize;
     392    uint32_t                 cSampleBufferHint;
    360393} PDMAUDIOSTREAMCFG, *PPDMAUDIOSTREAMCFG;
     394
     395/** Converts (audio) samples to bytes. */
     396#define PDMAUDIOSTREAMCFG_S2B(pCfg, samples) ((samples) << (pCfg->Props).cShift)
     397/** Converts bytes to (audio) samples. */
     398#define PDMAUDIOSTREAMCFG_B2S(pCfg, cb)  (cb >> (pCfg->Props).cShift)
    361399
    362400#if defined(RT_LITTLE_ENDIAN)
     
    410448    PDMAUDIOSTREAMCMD_32BIT_HACK = 0x7fffffff
    411449} PDMAUDIOSTREAMCMD;
    412 
    413 /**
    414  * Properties of audio streams for host/guest
    415  * for in or out directions.
    416  */
    417 typedef struct PDMAUDIOPCMPROPS
    418 {
    419     /** Sample width. Bits per sample. */
    420     uint8_t     cBits;
    421     /** Signed or unsigned sample. */
    422     bool        fSigned;
    423     /** Shift count used for faster calculation of various
    424      *  values, such as the alignment, bytes to samples and so on.
    425      *  Depends on number of stream channels and the stream format
    426      *  being used.
    427      *
    428      ** @todo Use some RTAsmXXX functions instead?
    429      */
    430     uint8_t     cShift;
    431     /** Number of audio channels. */
    432     uint8_t     cChannels;
    433     /** Alignment mask. */
    434     uint32_t    uAlign;
    435     /** Sample frequency in Hertz (Hz). */
    436     uint32_t    uHz;
    437     /** Bitrate (in bytes/s). */
    438     uint32_t    cbBitrate;
    439     /** Whether the endianness is swapped or not. */
    440     bool        fSwapEndian;
    441 } PDMAUDIOPCMPROPS, *PPDMAUDIOPCMPROPS;
    442 
    443 /** Converts (audio) samples to bytes. */
    444 #define PDMAUDIOPCMPROPS_S2B(pProps, samples) ((samples) << (pProps)->cShift)
    445 /** Converts bytes to (audio) samples. */
    446 #define PDMAUDIOPCMPROPS_B2S(pProps, cb)  (cb >> (pProps)->cShift)
    447450
    448451/**
     
    786789        PDMAUDIOSTREAMOUT  Out;
    787790    };
     791    /** Data to backend-specific stream data.
     792     *  This data block will be casted by the backend to access its backend-dependent data.
     793     *
     794     *  That way the backends do not have access to the audio connector's data. */
     795    void                  *pvBackend;
     796    /** Size (in bytes) of the backend-specific stream data. */
     797    size_t                 cbBackend;
    788798} PDMAUDIOSTREAM, *PPDMAUDIOSTREAM;
    789799
     
    867877} PDMAUDIOCALLBACK, *PPDMAUDIOCALLBACK;
    868878#endif /* VBOX_WITH_AUDIO_DEVICE_CALLBACKS */
     879
     880#define PPDMAUDIOBACKENDSTREAM void *
    869881
    870882/**
     
    11281140     * @param   pCfgAcq             Pointer to acquired stream configuration.
    11291141     */
    1130     DECLR3CALLBACKMEMBER(int, pfnStreamCreate, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq));
     1142    DECLR3CALLBACKMEMBER(int, pfnStreamCreate, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq));
    11311143
    11321144    /**
     
    11371149     * @param   pStream             Pointer to audio stream.
    11381150     */
    1139     DECLR3CALLBACKMEMBER(int, pfnStreamDestroy, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream));
     1151    DECLR3CALLBACKMEMBER(int, pfnStreamDestroy, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));
    11401152
    11411153    /**
     
    11471159     * @param   enmStreamCmd        The stream command to issue.
    11481160     */
    1149     DECLR3CALLBACKMEMBER(int, pfnStreamControl, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd));
     1161    DECLR3CALLBACKMEMBER(int, pfnStreamControl, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd));
    11501162
    11511163    /**
     
    11561168     * @param   pStream             Pointer to audio stream.
    11571169     */
    1158     DECLR3CALLBACKMEMBER(PDMAUDIOSTRMSTS, pfnStreamGetStatus, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream));
     1170    DECLR3CALLBACKMEMBER(PDMAUDIOSTRMSTS, pfnStreamGetStatus, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));
    11591171
    11601172    /**
     
    11651177     * @param   pStream             Pointer to audio stream.
    11661178     */
    1167     DECLR3CALLBACKMEMBER(int, pfnStreamIterate, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream));
     1179    DECLR3CALLBACKMEMBER(int, pfnStreamIterate, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream));
    11681180
    11691181    /**
     
    11771189     * @param   pcbWritten          Returns number of bytes written.  Optional.
    11781190     */
    1179     DECLR3CALLBACKMEMBER(int, pfnStreamPlay, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten));
     1191    DECLR3CALLBACKMEMBER(int, pfnStreamPlay, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten));
    11801192
    11811193    /**
     
    11891201     * @param   pcbRead             Returns number of bytes read.  Optional.
    11901202     */
    1191     DECLR3CALLBACKMEMBER(int, pfnStreamCapture, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead));
     1203    DECLR3CALLBACKMEMBER(int, pfnStreamCapture, (PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead));
    11921204
    11931205} PDMIHOSTAUDIO;
    11941206
    11951207/** PDMIHOSTAUDIO interface ID. */
    1196 #define PDMIHOSTAUDIO_IID                           "C45550DE-03C0-4A45-9A96-C5EB956F806D"
     1208#define PDMIHOSTAUDIO_IID                           "1F1C3DEB-AEA3-4E32-8405-EC7E7661E888"
    11971209
    11981210/** @} */
  • trunk/src/VBox/Devices/Audio/AudioMixer.cpp

    r65056 r65624  
    3030
    3131/*
    32  * Copyright (C) 2014-2016 Oracle Corporation
     32 * Copyright (C) 2014-2017 Oracle Corporation
    3333 *
    3434 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    600600        return rc;
    601601
    602     LogFlowFunc(("[%s]: fFlags=0x%x (enmDir=%d, %s, %RU8 channels, %RU32Hz)\n",
    603                  pSink->pszName, fFlags, pCfg->enmDir, DrvAudioHlpAudFmtToStr(pCfg->enmFormat), pCfg->cChannels, pCfg->uHz));
     602    LogFlowFunc(("[%s]: fFlags=0x%x (enmDir=%ld, %RU8 bits, %RU8 channels, %RU32Hz)\n",
     603                 pSink->pszName, fFlags, pCfg->enmDir, pCfg->Props.cBits, pCfg->Props.cChannels, pCfg->Props.uHz));
    604604
    605605    /*
     
    839839    uint64_t tsDeltaMS  = RTTimeMilliTS() - pSink->tsLastUpdatedMS;
    840840
    841     cbReadable = (pSink->PCMProps.cbBitrate / 1000 /* s to ms */) * tsDeltaMS;
     841    cbReadable = ((DrvAudioHlpCalcBitrate(&pSink->PCMProps) / 8) / 1000 /* s to ms */) * tsDeltaMS;
    842842
    843843    Log3Func(("[%s] Bitrate is %RU32 bytes/s -> %RU64ms / %RU32 bytes elapsed\n",
    844               pSink->pszName, pSink->PCMProps.cbBitrate, tsDeltaMS, cbReadable));
     844              pSink->pszName, DrvAudioHlpCalcBitrate(&pSink->PCMProps) / 8, tsDeltaMS, cbReadable));
    845845#endif
    846846
     
    890890        uint64_t tsDeltaMS  = RTTimeMilliTS() - pSink->tsLastUpdatedMS;
    891891
    892         cbWritable = (pSink->PCMProps.cbBitrate / 1000 /* s to ms */) * tsDeltaMS;
     892        cbWritable = ((DrvAudioHlpCalcBitrate(&pSink->PCMProps) / 8) / 1000 /* s to ms */) * tsDeltaMS;
    893893
    894894        Log3Func(("[%s] Bitrate is %RU32 bytes/s -> %RU64ms / %RU32 bytes elapsed\n",
    895                   pSink->pszName, pSink->PCMProps.cbBitrate, tsDeltaMS, cbWritable));
     895                  pSink->pszName, DrvAudioHlpCalcBitrate(&pSink->PCMProps) / 8, tsDeltaMS, cbWritable));
    896896#endif
    897897    }
  • trunk/src/VBox/Devices/Audio/DevHDA.cpp

    r65152 r65624  
    99
    1010/*
    11  * Copyright (C) 2006-2016 Oracle Corporation
     11 * Copyright (C) 2006-2017 Oracle Corporation
    1212 *
    1313 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    26472647    }
    26482648
    2649     PDMAUDIOFMT enmFmt;
     2649    uint8_t cBits = 0;
    26502650    switch (EXTRACT_VALUE(u32SDFMT, HDA_SDFMT_BITS_MASK, HDA_SDFMT_BITS_SHIFT))
    26512651    {
    26522652        case 0:
    2653             enmFmt = PDMAUDIOFMT_S8;
     2653            cBits = 8;
    26542654            break;
    26552655        case 1:
    2656             enmFmt = PDMAUDIOFMT_S16;
     2656            cBits = 16;
    26572657            break;
    26582658        case 4:
    2659             enmFmt = PDMAUDIOFMT_S32;
     2659            cBits = 32;
    26602660            break;
    26612661        default:
    26622662            AssertMsgFailed(("Unsupported bits per sample %x\n",
    26632663                             EXTRACT_VALUE(u32SDFMT, HDA_SDFMT_BITS_MASK, HDA_SDFMT_BITS_SHIFT)));
    2664             enmFmt = PDMAUDIOFMT_INVALID;
    26652664            rc = VERR_NOT_SUPPORTED;
    26662665            break;
     
    26692668    if (RT_SUCCESS(rc))
    26702669    {
    2671         pStrmCfg->uHz           = u32Hz * u32HzMult / u32HzDiv;
    2672         pStrmCfg->cChannels     = (u32SDFMT & 0xf) + 1;
    2673         pStrmCfg->enmFormat     = enmFmt;
    2674         pStrmCfg->enmEndianness = PDMAUDIOHOSTENDIANNESS;
     2670        RT_ZERO(pStrmCfg->Props);
     2671
     2672        pStrmCfg->Props.uHz       = u32Hz * u32HzMult / u32HzDiv;
     2673        pStrmCfg->Props.cChannels = (u32SDFMT & 0xf) + 1;
     2674        pStrmCfg->Props.cBits     = cBits;
     2675        pStrmCfg->Props.fSigned   = true;
    26752676    }
    26762677
     
    27402741#else /* !VBOX_WITH_AUDIO_HDA_51_SURROUND */
    27412742    /* Only support mono or stereo channels. */
    2742     if (   pCfg->cChannels != 1 /* Mono */
    2743         && pCfg->cChannels != 2 /* Stereo */)
     2743    if (   pCfg->Props.cChannels != 1 /* Mono */
     2744        && pCfg->Props.cChannels != 2 /* Stereo */)
    27442745    {
    27452746        rc = VERR_NOT_SUPPORTED;
     
    27492750    if (rc == VERR_NOT_SUPPORTED)
    27502751    {
    2751         LogRel(("HDA: Unsupported channel count (%RU8), falling back to stereo channels\n", pCfg->cChannels));
    2752         pCfg->cChannels = 2;
     2752        LogRel(("HDA: Unsupported channel count (%RU8), falling back to stereo channels\n", pCfg->Props.cChannels));
     2753        pCfg->Props.cChannels = 2;
    27532754
    27542755        rc = VINF_SUCCESS;
     
    27642765            RTStrPrintf(pCfg->szName, RT_ELEMENTS(pCfg->szName), "Front");
    27652766            pCfg->DestSource.Dest = PDMAUDIOPLAYBACKDEST_FRONT;
    2766             pCfg->cChannels      = 2;
     2767            pCfg->Props.cChannels = 2;
    27672768
    27682769            rc = hdaCodecRemoveStream(pThis->pCodec,  PDMAUDIOMIXERCTL_FRONT);
     
    27772778            RTStrPrintf(pCfg->szName, RT_ELEMENTS(pCfg->szName), "Center/LFE");
    27782779            pCfg->DestSource.Dest = PDMAUDIOPLAYBACKDEST_CENTER_LFE;
    2779             pCfg->cChannels      = (fUseCenter && fUseLFE) ? 2 : 1;
     2780            pCfg->Props.cChannels = (fUseCenter && fUseLFE) ? 2 : 1;
    27802781
    27812782            rc = hdaCodecRemoveStream(pThis->pCodec,  PDMAUDIOMIXERCTL_CENTER_LFE);
     
    27892790            RTStrPrintf(pCfg->szName, RT_ELEMENTS(pCfg->szName), "Rear");
    27902791            pCfg->DestSource.Dest = PDMAUDIOPLAYBACKDEST_REAR;
    2791             pCfg->cChannels      = 2;
     2792            pCfg->Props.cChannels = 2;
    27922793
    27932794            rc = hdaCodecRemoveStream(pThis->pCodec,  PDMAUDIOMIXERCTL_REAR);
     
    28602861    }
    28612862
    2862     LogFunc(("[SD%RU8]: Hz=%RU32, Channels=%RU8, enmFmt=%RU32\n",
    2863              pStream->u8SD, strmCfg.uHz, strmCfg.cChannels, strmCfg.enmFormat));
     2863    LogFunc(("[SD%RU8]: Hz=%RU32, Channels=%RU8, cBits=%RU8\n",
     2864             pStream->u8SD, strmCfg.Props.uHz, strmCfg.Props.cChannels, strmCfg.Props.cBits));
    28642865
    28652866    /* Set audio direction. */
     
    32973298    AssertPtrReturn(pCfg,     VERR_INVALID_POINTER);
    32983299
    3299     AssertReturn(pCfg->cChannels, VERR_INVALID_PARAMETER);
     3300    AssertReturn(pCfg->Props.cChannels, VERR_INVALID_PARAMETER);
    33003301
    33013302    hdaStreamMapReset(pMapping);
    33023303
    3303     pMapping->paChannels = (PPDMAUDIOSTREAMCHANNEL)RTMemAlloc(sizeof(PDMAUDIOSTREAMCHANNEL) * pCfg->cChannels);
     3304    pMapping->paChannels = (PPDMAUDIOSTREAMCHANNEL)RTMemAlloc(sizeof(PDMAUDIOSTREAMCHANNEL) * pCfg->Props.cChannels);
    33043305    if (!pMapping->paChannels)
    33053306        return VERR_NO_MEMORY;
    33063307
    3307     PDMAUDIOPCMPROPS Props;
    3308     int rc = DrvAudioHlpStreamCfgToProps(pCfg, &Props);
    3309     if (RT_FAILURE(rc))
    3310         return rc;
    3311 
    3312     Assert(RT_IS_POWER_OF_TWO(Props.cBits));
     3308    if (!DrvAudioHlpStreamCfgIsValid(pCfg))
     3309        return VERR_INVALID_PARAMETER;
     3310
     3311    int rc = VINF_SUCCESS;
     3312
     3313    Assert(RT_IS_POWER_OF_TWO(pCfg->Props.cBits));
    33133314
    33143315    /** @todo We assume all channels in a stream have the same format. */
    33153316    PPDMAUDIOSTREAMCHANNEL pChan = pMapping->paChannels;
    3316     for (uint8_t i = 0; i < pCfg->cChannels; i++)
     3317    for (uint8_t i = 0; i < pCfg->Props.cChannels; i++)
    33173318    {
    33183319        pChan->uChannel = i;
    3319         pChan->cbStep   = (Props.cBits / 2);
    3320         pChan->cbFrame  = pChan->cbStep * pCfg->cChannels;
     3320        pChan->cbStep   = (pCfg->Props.cBits / 2);
     3321        pChan->cbFrame  = pChan->cbStep * pCfg->Props.cChannels;
    33213322        pChan->cbFirst  = i * pChan->cbStep;
    33223323        pChan->cbOff    = pChan->cbFirst;
     
    33413342    if (RT_SUCCESS(rc))
    33423343    {
    3343         pMapping->cChannels = pCfg->cChannels;
     3344        pMapping->cChannels = pCfg->Props.cChannels;
    33443345#ifdef VBOX_WITH_HDA_AUDIO_INTERLEAVING_STREAMS_SUPPORT
    33453346        pMapping->enmLayout = PDMAUDIOSTREAMLAYOUT_INTERLEAVED;
     
    35273528    LogFunc(("Sink=%s, Stream=%s\n", pSink->pMixSink->pszName, pCfg->szName));
    35283529
    3529     /* Update the sink's format. */
    3530     PDMAUDIOPCMPROPS PCMProps;
    3531     int rc = DrvAudioHlpStreamCfgToProps(pCfg, &PCMProps);
    3532     if (RT_SUCCESS(rc))
    3533         rc = AudioMixerSinkSetFormat(pSink->pMixSink, &PCMProps);
    3534 
     3530    if (!DrvAudioHlpStreamCfgIsValid(pCfg))
     3531        return VERR_INVALID_PARAMETER;
     3532
     3533    int rc = AudioMixerSinkSetFormat(pSink->pMixSink, &pCfg->Props);
    35353534    if (RT_FAILURE(rc))
    35363535        return rc;
     
    35423541        PHDADRIVERSTREAM pDrvStream = NULL;
    35433542
    3544         PPDMAUDIOSTREAMCFG pStreamCfg = (PPDMAUDIOSTREAMCFG)RTMemDup(pCfg, sizeof(PDMAUDIOSTREAMCFG));
     3543        PPDMAUDIOSTREAMCFG pStreamCfg = DrvAudioHlpStreamCfgDup(pCfg);
    35453544        if (!pStreamCfg)
    35463545        {
     
    46984697            }
    46994698
    4700 #ifdef DEBUG_andy
    47014699            AssertMsg(cbDMALeft == 0, ("%RU32 bytes of DMA data left, CircBuf=%zu/%zu\n",
    47024700                                       cbDMALeft, RTCircBufUsed(pCircBuf), RTCircBufSize(pCircBuf)));
    4703 #endif
     4701
    47044702            /*
    47054703             * Process backends.
     
    47824780            AssertFailed();
    47834781
    4784         if (++cTransfers > 32) /* Failsafe counter. */
     4782        if (++cTransfers == UINT8_MAX) /* Failsafe counter. */
    47854783            fDone = true;
    47864784
    47874785    } /* while !fDone */
     4786
     4787#ifdef VBOX_STRICT
     4788    AssertMsg(cTransfers < UINT8_MAX, ("HDA: Update for SD#%RU8 ran for too long\n", pStream->u8SD));
     4789#endif
    47884790
    47894791    Log2Func(("[SD%RU8] End\n", pStream->u8SD));
  • trunk/src/VBox/Devices/Audio/DevIchAc97.cpp

    r65150 r65624  
    14751475    AssertPtrReturn(pCfg,     VERR_INVALID_POINTER);
    14761476
    1477     /* Update the sink's format. */
    1478     PDMAUDIOPCMPROPS PCMProps;
    1479     int rc = DrvAudioHlpStreamCfgToProps(pCfg, &PCMProps);
    1480     if (RT_SUCCESS(rc))
    1481         rc = AudioMixerSinkSetFormat(pMixSink, &PCMProps);
    1482 
     1477    if (!DrvAudioHlpStreamCfgIsValid(pCfg))
     1478        return VERR_INVALID_PARAMETER;
     1479
     1480    int rc = AudioMixerSinkSetFormat(pMixSink, &pCfg->Props);
    14831481    if (RT_FAILURE(rc))
    14841482        return rc;
     
    14871485    RTListForEach(&pThis->lstDrv, pDrv, AC97DRIVER, Node)
    14881486    {
    1489         PPDMAUDIOSTREAMCFG pStreamCfg = (PPDMAUDIOSTREAMCFG)RTMemDup(pCfg, sizeof(PDMAUDIOSTREAMCFG));
     1487        PPDMAUDIOSTREAMCFG pStreamCfg = DrvAudioHlpStreamCfgDup(pCfg);
    14901488        if (!pStreamCfg)
    14911489        {
     
    15931591        case AC97SOUNDSOURCE_PI_INDEX:
    15941592        {
    1595             streamCfg.uHz               = ichac97MixerGet(pThis, AC97_PCM_LR_ADC_Rate);
     1593            streamCfg.Props.uHz         = ichac97MixerGet(pThis, AC97_PCM_LR_ADC_Rate);
    15961594            streamCfg.enmDir            = PDMAUDIODIR_IN;
    15971595            streamCfg.DestSource.Source = PDMAUDIORECSOURCE_LINE;
     
    16051603        case AC97SOUNDSOURCE_MC_INDEX:
    16061604        {
    1607             streamCfg.uHz               = ichac97MixerGet(pThis, AC97_MIC_ADC_Rate);
     1605            streamCfg.Props.uHz         = ichac97MixerGet(pThis, AC97_MIC_ADC_Rate);
    16081606            streamCfg.enmDir            = PDMAUDIODIR_IN;
    16091607            streamCfg.DestSource.Source = PDMAUDIORECSOURCE_MIC;
     
    16171615        case AC97SOUNDSOURCE_PO_INDEX:
    16181616        {
    1619             streamCfg.uHz               = ichac97MixerGet(pThis, AC97_PCM_Front_DAC_Rate);
     1617            streamCfg.Props.uHz         = ichac97MixerGet(pThis, AC97_PCM_Front_DAC_Rate);
    16201618            streamCfg.enmDir            = PDMAUDIODIR_OUT;
    16211619            streamCfg.DestSource.Dest   = PDMAUDIOPLAYBACKDEST_FRONT;
     
    16361634        ichac97MixerRemoveDrvStreams(pThis, pMixSink, streamCfg.enmDir, streamCfg.DestSource);
    16371635
    1638         if (streamCfg.uHz)
     1636        if (streamCfg.Props.uHz)
    16391637        {
    16401638            Assert(streamCfg.enmDir != PDMAUDIODIR_UNKNOWN);
    16411639
    1642             streamCfg.cChannels    = 2;
    1643             streamCfg.enmFormat     = PDMAUDIOFMT_S16;
    1644             streamCfg.enmEndianness = PDMAUDIOHOSTENDIANNESS;
     1640            streamCfg.Props.cChannels = 2;
     1641            streamCfg.Props.cBits     = 16;
     1642            streamCfg.Props.fSigned   = true;
    16451643
    16461644            rc = ichac97MixerAddDrvStreams(pThis, pMixSink, &streamCfg);
  • trunk/src/VBox/Devices/Audio/DevSB16.cpp

    r64333 r65624  
    492492        PDMAUDIOSTREAMCFG streamCfg;
    493493        RT_ZERO(streamCfg);
     494
    494495        streamCfg.enmDir          = PDMAUDIODIR_OUT;
    495496        streamCfg.DestSource.Dest = PDMAUDIOPLAYBACKDEST_FRONT;
    496         streamCfg.uHz             = pThis->freq;
    497         streamCfg.cChannels       = 1 << pThis->fmt_stereo;
    498         streamCfg.enmFormat       = pThis->fmt;
    499         streamCfg.enmEndianness   = PDMAUDIOHOSTENDIANNESS;
     497
     498        streamCfg.Props.uHz             = pThis->freq;
     499        streamCfg.Props.cChannels       = 1 << pThis->fmt_stereo;
     500        streamCfg.Props.cBits           = pThis->fmt_bits;
     501        streamCfg.Props.fSigned         = RT_BOOL(pThis->fmt_signed);
    500502
    501503        int rc = sb16OpenOut(pThis, &streamCfg);
     
    630632        PDMAUDIOSTREAMCFG streamCfg;
    631633        RT_ZERO(streamCfg);
     634
    632635        streamCfg.enmDir          = PDMAUDIODIR_OUT;
    633636        streamCfg.DestSource.Dest = PDMAUDIOPLAYBACKDEST_FRONT;
    634         streamCfg.uHz             = pThis->freq;
    635         streamCfg.cChannels       = 1 << pThis->fmt_stereo;
    636         streamCfg.enmFormat       = pThis->fmt;
    637         streamCfg.enmEndianness   = PDMAUDIOHOSTENDIANNESS;
     637
     638        streamCfg.Props.uHz       = pThis->freq;
     639        streamCfg.Props.cChannels = 1 << pThis->fmt_stereo;
     640        streamCfg.Props.cBits     = pThis->fmt_bits;
     641        streamCfg.Props.fSigned   = RT_BOOL(pThis->fmt_signed);
    638642
    639643        int rc = sb16OpenOut(pThis, &streamCfg);
     
    11631167    PDMAUDIOSTREAMCFG streamCfg;
    11641168    RT_ZERO(streamCfg);
     1169
    11651170    streamCfg.enmDir          = PDMAUDIODIR_OUT;
    11661171    streamCfg.DestSource.Dest = PDMAUDIOPLAYBACKDEST_FRONT;
    1167     streamCfg.uHz             = pThis->freq;
    1168     streamCfg.cChannels       = 1; /* Mono */
    1169     streamCfg.enmFormat       = PDMAUDIOFMT_U8;
    1170     streamCfg.enmEndianness   = PDMAUDIOHOSTENDIANNESS;
     1172
     1173    streamCfg.Props.uHz       = pThis->freq;
     1174    streamCfg.Props.cChannels = 1; /* Mono */
     1175    streamCfg.Props.cBits     = 8;
     1176    streamCfg.Props.fSigned   = false;
    11711177
    11721178    int rc2 = sb16OpenOut(pThis, &streamCfg);
     
    18261832             * so check if all streams have the same configuration.
    18271833             */
    1828             AssertMsg(pStream->Cfg.uHz       == pStreamPrev->Cfg.uHz,
    1829                       ("%RU32Hz vs. %RU32Hz\n", pStream->Cfg.uHz, pStreamPrev->Cfg.uHz));
    1830             AssertMsg(pStream->Cfg.cChannels == pStreamPrev->Cfg.cChannels,
    1831                       ("%RU8 vs. %RU8 channels\n", pStream->Cfg.cChannels, pStreamPrev->Cfg.cChannels));
    1832             AssertMsg(pStream->Cfg.enmFormat == pStreamPrev->Cfg.enmFormat,
    1833                       ("%d vs. %d format\n", pStream->Cfg.enmFormat, pStreamPrev->Cfg.enmFormat));
     1834            AssertMsg(pStream->Cfg.Props.uHz       == pStreamPrev->Cfg.Props.uHz,
     1835                      ("%RU32Hz vs. %RU32Hz\n", pStream->Cfg.Props.uHz, pStreamPrev->Cfg.Props.uHz));
     1836            AssertMsg(pStream->Cfg.Props.cChannels == pStreamPrev->Cfg.Props.cChannels,
     1837                      ("%RU8 vs. %RU8 channels\n", pStream->Cfg.Props.cChannels, pStreamPrev->Cfg.Props.cChannels));
     1838            AssertMsg(pStream->Cfg.Props.cBits     == pStreamPrev->Cfg.Props.cBits,
     1839                      ("%d vs. %d bits\n", pStream->Cfg.Props.cBits, pStreamPrev->Cfg.Props.cBits));
     1840            AssertMsg(pStream->Cfg.Props.fSigned   == pStreamPrev->Cfg.Props.fSigned,
     1841                      ("%RTbool vs. %RTbool signed\n", pStream->Cfg.Props.fSigned, pStreamPrev->Cfg.Props.fSigned));
    18341842        }
    18351843#endif
     
    20162024            PDMAUDIOSTREAMCFG streamCfg;
    20172025            RT_ZERO(streamCfg);
     2026
    20182027            streamCfg.enmDir          = PDMAUDIODIR_OUT;
    20192028            streamCfg.DestSource.Dest = PDMAUDIOPLAYBACKDEST_FRONT;
    2020             streamCfg.uHz             = pThis->freq;
    2021             streamCfg.cChannels       = 1 << pThis->fmt_stereo;
    2022             streamCfg.enmFormat       = pThis->fmt;
    2023             streamCfg.enmEndianness   = PDMAUDIOHOSTENDIANNESS;
     2029
     2030            streamCfg.Props.uHz             = pThis->freq;
     2031            streamCfg.Props.cChannels       = 1 << pThis->fmt_stereo;
     2032            streamCfg.Props.cBits           = pThis->fmt_bits;
     2033            streamCfg.Props.fSigned         = RT_BOOL(pThis->fmt_signed);
    20242034
    20252035            int rc = sb16OpenOut(pThis, &streamCfg);
     
    21172127    /* Set a default audio format for the host. */
    21182128    PDMAUDIOSTREAMCFG CfgHost;
     2129    RT_ZERO(CfgHost);
     2130
    21192131    CfgHost.enmDir          = PDMAUDIODIR_OUT;
    21202132    CfgHost.DestSource.Dest = PDMAUDIOPLAYBACKDEST_FRONT;
    2121     CfgHost.uHz             = pCfg->uHz;
    2122     CfgHost.cChannels       = pCfg->cChannels;
    2123     CfgHost.enmFormat       = PDMAUDIOFMT_S16;
    2124     CfgHost.enmEndianness   = PDMAUDIOHOSTENDIANNESS;
     2133
     2134    CfgHost.Props.uHz       = pCfg->Props.uHz;
     2135    CfgHost.Props.cChannels = pCfg->Props.cChannels;
     2136    CfgHost.Props.cBits     = pCfg->Props.cBits;
     2137    CfgHost.Props.fSigned   = pCfg->Props.fSigned;
    21252138
    21262139    RTStrPrintf(CfgHost.szName, sizeof(CfgHost.szName), "sb16.po");
     
    21342147    {
    21352148        if (!RTStrPrintf(pCfg->szName, sizeof(pCfg->szName), "[LUN#%RU8] %s (%RU32Hz, %RU8 %s)",
    2136                          pDrv->uLUN, CfgHost.szName, pCfg->uHz, pCfg->cChannels, pCfg->cChannels > 1 ? "Channels" : "Channel"))
     2149                         pDrv->uLUN, CfgHost.szName,
     2150                         pCfg->Props.uHz, pCfg->Props.cChannels, pCfg->Props.cChannels > 1 ? "Channels" : "Channel"))
    21372151        {
    21382152            rc = VERR_BUFFER_OVERFLOW;
  • trunk/src/VBox/Devices/Audio/DrvAudio.cpp

    r65570 r65624  
    88
    99/*
    10  * Copyright (C) 2006-2016 Oracle Corporation
     10 * Copyright (C) 2006-2017 Oracle Corporation
    1111 *
    1212 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    5050static int drvAudioStreamCreateInternalBackend(PDRVAUDIO pThis, PPDMAUDIOSTREAM pHstStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq);
    5151static int drvAudioStreamDestroyInternalBackend(PDRVAUDIO pThis, PPDMAUDIOSTREAM pHstStream);
     52static void drvAudioStreamFree(PPDMAUDIOSTREAM pStream);
    5253static int drvAudioStreamUninitInternal(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream);
    5354static int drvAudioStreamInitInternal(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgHost, PPDMAUDIOSTREAMCFG pCfgGuest);
     
    499500            {
    500501                LogRel2(("Audio: Enabling stream '%s'\n", pHstStream->szName));
    501                 rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_ENABLE);
     502                rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream->pvBackend,
     503                                                            PDMAUDIOSTREAMCMD_ENABLE);
    502504                if (RT_SUCCESS(rc))
    503505                {
     
    515517            {
    516518                LogRel2(("Audio: Disabling stream '%s'\n", pHstStream->szName));
    517                 rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_DISABLE);
     519                rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream->pvBackend,
     520                                                            PDMAUDIOSTREAMCMD_DISABLE);
    518521                if (RT_SUCCESS(rc))
    519522                {
     
    537540            {
    538541                LogRel2(("Audio: Pausing stream '%s'\n", pHstStream->szName));
    539                 rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_PAUSE);
     542                rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream->pvBackend,
     543                                                            PDMAUDIOSTREAMCMD_PAUSE);
    540544                if (RT_SUCCESS(rc))
    541545                {
     
    557561            {
    558562                LogRel2(("Audio: Resuming stream '%s'\n", pHstStream->szName));
    559                 rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_RESUME);
     563                rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream->pvBackend,
     564                                                            PDMAUDIOSTREAMCMD_RESUME);
    560565                if (RT_SUCCESS(rc))
    561566                {
     
    632637
    633638    /* No sample buffer size hint given by the backend? Default to some sane value. */
    634     if (!CfgHostAcq.cSampleBufferSize)
    635     {
    636         CfgHostAcq.cSampleBufferSize = _1K; /** @todo Make this configurable? */
    637     }
    638 
    639     PDMAUDIOPCMPROPS PCMProps;
    640     int rc2 = DrvAudioHlpStreamCfgToProps(&CfgHostAcq, &PCMProps);
    641     AssertRC(rc2);
     639    if (!CfgHostAcq.cSampleBufferHint)
     640    {
     641        CfgHostAcq.cSampleBufferHint = _1K; /** @todo Make this configurable? */
     642    }
    642643
    643644    /* Destroy any former mixing buffer. */
    644645    AudioMixBufDestroy(&pHstStream->MixBuf);
    645646
    646     CfgHostAcq.cSampleBufferSize *= 10; /** @todo Make this configurable. */
    647 
    648     LogFlowFunc(("[%s] cSamples=%RU32\n", pHstStream->szName, CfgHostAcq.cSampleBufferSize));
    649 
    650     rc2 = AudioMixBufInit(&pHstStream->MixBuf, pHstStream->szName, &PCMProps, CfgHostAcq.cSampleBufferSize);
     647    /* Make sure to (re-)set the host buffer's shift size. */
     648    CfgHostAcq.Props.cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(CfgHostAcq.Props.cBits, CfgHostAcq.Props.cChannels);
     649
     650    /* Set set host buffer size multiplicator. */
     651    const unsigned cSampleBufferHostFactor = 10; /** @todo Make this configurable. */
     652
     653    LogFlowFunc(("[%s] cSamples=%RU32 (x %u)\n", pHstStream->szName, CfgHostAcq.cSampleBufferHint, cSampleBufferHostFactor));
     654
     655    int rc2 = AudioMixBufInit(&pHstStream->MixBuf, pHstStream->szName, &CfgHostAcq.Props,
     656                              CfgHostAcq.cSampleBufferHint * cSampleBufferHostFactor);
    651657    AssertRC(rc2);
    652658
    653     /* Make a copy of the host stream configuration. */
    654     memcpy(&pHstStream->Cfg, pCfgHost, sizeof(PDMAUDIOSTREAMCFG));
     659    /* Make a copy of the acquired host stream configuration. */
     660    rc2 = DrvAudioHlpStreamCfgCopy(&pHstStream->Cfg, pCfgHost);
     661    AssertRC(rc2);
    655662
    656663    /*
     
    658665     */
    659666
    660     RT_ZERO(PCMProps);
    661     rc2 = DrvAudioHlpStreamCfgToProps(pCfgGuest, &PCMProps);
    662     AssertRC(rc2);
    663 
    664667    /* Destroy any former mixing buffer. */
    665668    AudioMixBufDestroy(&pGstStream->MixBuf);
    666669
    667     CfgHostAcq.cSampleBufferSize *= 20; /** @todo Make this configurable. */
    668 
    669     LogFlowFunc(("[%s] cSamples=%RU32\n", pGstStream->szName, CfgHostAcq.cSampleBufferSize));
    670 
    671     rc2 = AudioMixBufInit(&pGstStream->MixBuf, pGstStream->szName, &PCMProps, CfgHostAcq.cSampleBufferSize);
     670    /* Make sure to (re-)set the guest buffer's shift size. */
     671    pCfgGuest->Props.cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfgGuest->Props.cBits, pCfgGuest->Props.cChannels);
     672
     673    /* Set set guest buffer size multiplicator. */
     674    const unsigned cSampleBufferGuestFactor = 10; /** @todo Make this configurable. */
     675
     676    LogFlowFunc(("[%s] cSamples=%RU32 (x %u)\n", pGstStream->szName, CfgHostAcq.cSampleBufferHint));
     677
     678    rc2 = AudioMixBufInit(&pGstStream->MixBuf, pGstStream->szName, &pCfgGuest->Props,
     679                          CfgHostAcq.cSampleBufferHint * cSampleBufferGuestFactor);
    672680    AssertRC(rc2);
    673681
     
    685693    }
    686694
    687     /* Make a copy of the host stream configuration. */
    688     memcpy(&pGstStream->Cfg, pCfgGuest, sizeof(PDMAUDIOSTREAMCFG));
     695    /* Make a copy of the guest stream configuration. */
     696    rc2 = DrvAudioHlpStreamCfgCopy(&pGstStream->Cfg, pCfgGuest);
     697    AssertRC(rc2);
    689698
    690699    if (RT_FAILURE(rc))
     
    693702    LogFlowFunc(("[%s] Returning %Rrc\n", pStream->szName, rc));
    694703    return rc;
     704}
     705
     706/**
     707 * Frees an audio stream and its allocated resources.
     708 *
     709 * @param   pStream             Audio stream to free.
     710 *                              After this call the pointer will not be valid anymore.
     711 */
     712static void drvAudioStreamFree(PPDMAUDIOSTREAM pStream)
     713{
     714    if (!pStream)
     715        return;
     716
     717    if (pStream->pvBackend)
     718    {
     719        Assert(pStream->cbBackend);
     720        RTMemFree(pStream->pvBackend);
     721        pStream->pvBackend = NULL;
     722    }
     723
     724    RTMemFree(pStream);
     725    pStream = NULL;
    695726}
    696727
     
    11081139        uint32_t csMixed = 0;
    11091140
    1110         rc = pThis->pHostDrvAudio->pfnStreamIterate(pThis->pHostDrvAudio, pHstStream);
     1141        rc = pThis->pHostDrvAudio->pfnStreamIterate(pThis->pHostDrvAudio, pHstStream->pvBackend);
    11111142        if (RT_FAILURE(rc))
    11121143            break;
     
    12621293        uint32_t csLive = AudioMixBufUsed(&pHstStream->MixBuf);
    12631294
    1264         PDMAUDIOSTRMSTS stsBackend = pThis->pHostDrvAudio->pfnStreamGetStatus(pThis->pHostDrvAudio, pHstStream);
     1295        PDMAUDIOSTRMSTS stsBackend = pThis->pHostDrvAudio->pfnStreamGetStatus(pThis->pHostDrvAudio, pHstStream->pvBackend);
    12651296
    12661297#ifdef LOG_ENABLED
     
    12741305            && (stsBackend & PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE))
    12751306        {
    1276             uint8_t u8Buf[_1K];
     1307            uint8_t u8Buf[_4K]; /** @todo Get rid of this here. */
    12771308
    12781309            uint32_t cRead = 0;
     
    12841315
    12851316            AssertPtr(pThis->pHostDrvAudio->pfnStreamPlay);
    1286             rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream, u8Buf, cbBuf, &cbPlayed);
     1317            rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream->pvBackend, u8Buf, cbBuf, &cbPlayed);
    12871318            if (RT_SUCCESS(rc))
    12881319            {
     1320                AssertMsg(cbPlayed % 2 == 0,
     1321                          ("Backend for stream '%s' returned uneven played bytes count (%RU32)\n", pHstStream->szName, cbPlayed));
     1322
    12891323                csPlayed = AUDIOMIXBUF_B2S(&pHstStream->MixBuf, cbPlayed);
    12901324
     
    13771411
    13781412        AssertPtr(pThis->pHostDrvAudio->pfnStreamGetStatus);
    1379         PDMAUDIOSTRMSTS stsBackend = pThis->pHostDrvAudio->pfnStreamGetStatus(pThis->pHostDrvAudio, pHstStream);
     1413        PDMAUDIOSTRMSTS stsBackend = pThis->pHostDrvAudio->pfnStreamGetStatus(pThis->pHostDrvAudio, pHstStream->pvBackend);
    13801414
    13811415        uint32_t csLive = AudioMixBufLive(&pGstStream->MixBuf);
     
    13881422                uint32_t cbCaptured;
    13891423
    1390                 rc = pThis->pHostDrvAudio->pfnStreamCapture(pThis->pHostDrvAudio, pHstStream, auBuf, sizeof(auBuf), &cbCaptured);
     1424                rc = pThis->pHostDrvAudio->pfnStreamCapture(pThis->pHostDrvAudio, pHstStream->pvBackend,
     1425                                                            auBuf, sizeof(auBuf), &cbCaptured);
    13911426                if (RT_FAILURE(rc))
    13921427                {
     
    19631998        }
    19641999
    1965         /* Note: cbHstStrm will contain sizeof(PDMAUDIOSTREAM) + additional data
    1966          *       which the host backend will need. */
    1967         size_t cbHstStrm;
     2000        /* Note: cbHstStrm will contain the size of the data the backend needs to operate on. */
     2001        size_t cbHstStrm = 0;
    19682002        if (pCfgHost->enmDir == PDMAUDIODIR_IN)
    19692003        {
     
    19712005                LogFunc(("Warning: No more input streams free to use\n"));
    19722006
    1973             /* Validate backend configuration. */
    1974             if (!pThis->BackendCfg.cbStreamIn)
    1975             {
    1976                 LogFunc(("Backend input configuration not valid, bailing out\n"));
    1977                 RC_BREAK(VERR_INVALID_PARAMETER);
    1978             }
    1979 
    19802007            cbHstStrm = pThis->BackendCfg.cbStreamIn;
    19812008        }
     
    19882015            }
    19892016
    1990             /* Validate backend configuration. */
    1991             if (!pThis->BackendCfg.cbStreamOut)
    1992             {
    1993                 LogFlowFunc(("Backend output configuration invalid, bailing out\n"));
    1994                 RC_BREAK(VERR_INVALID_PARAMETER);
    1995             }
    1996 
    19972017            cbHstStrm = pThis->BackendCfg.cbStreamOut;
    19982018        }
    19992019
    2000         pHstStrm = (PPDMAUDIOSTREAM)RTMemAllocZ(cbHstStrm);
     2020        pHstStrm = (PPDMAUDIOSTREAM)RTMemAllocZ(sizeof(PDMAUDIOSTREAM));
    20012021        AssertPtrBreakStmt(pHstStrm, rc = VERR_NO_MEMORY);
     2022
     2023        if (cbHstStrm) /* High unlikely that backends do not have an own space for data, but better check. */
     2024        {
     2025            pHstStrm->pvBackend = RTMemAllocZ(cbHstStrm);
     2026            AssertPtrBreakStmt(pHstStrm->pvBackend, rc = VERR_NO_MEMORY);
     2027
     2028            pHstStrm->cbBackend = cbHstStrm;
     2029        }
    20022030
    20032031        pHstStrm->enmCtx = PDMAUDIOSTREAMCTX_HOST;
     
    20932121            if (RT_SUCCESS(rc2))
    20942122            {
    2095                 RTMemFree(pHstStrm);
     2123                drvAudioStreamFree(pHstStrm);
    20962124                pHstStrm = NULL;
    20972125            }
     
    23812409                RTListNodeRemove(&pHstStream->Node);
    23822410
    2383                 RTMemFree(pHstStream);
     2411                drvAudioStreamFree(pHstStream);
    23842412                pHstStream = NULL;
    23852413            }
     
    24632491              ("Stream '%s' already initialized in backend\n", pHstStream->szName));
    24642492
    2465     PDMAUDIOSTREAMCFG CfgAcq;
    2466 
    24672493    /* Make the acquired host configuration the requested host configuration initially,
    24682494     * in case the backend does not report back an acquired configuration. */
    2469     memcpy(&CfgAcq, pCfgReq, sizeof(PDMAUDIOSTREAMCFG));
    2470 
    2471     int rc = pThis->pHostDrvAudio->pfnStreamCreate(pThis->pHostDrvAudio, pHstStream, pCfgReq, &CfgAcq);
     2495    PDMAUDIOSTREAMCFG CfgAcq;
     2496    int rc = DrvAudioHlpStreamCfgCopy(&CfgAcq, pCfgReq);
     2497    if (RT_FAILURE(rc))
     2498    {
     2499        LogRel2(("Audio: Creating stream '%s' with an invalid backend configuration not possible, skipping\n",
     2500                 pHstStream->szName));
     2501        return rc;
     2502    }
     2503
     2504    rc = pThis->pHostDrvAudio->pfnStreamCreate(pThis->pHostDrvAudio, pHstStream->pvBackend, pCfgReq, &CfgAcq);
    24722505    if (RT_FAILURE(rc))
    24732506    {
     
    24792512    if (!DrvAudioHlpStreamCfgIsValid(&CfgAcq))
    24802513    {
    2481         LogRel2(("Audio: Creating stream '%s' has an invalid configuration, skipping\n", pHstStream->szName));
     2514        LogRel2(("Audio: Creating stream '%s' returned an invalid backend configuration, skipping\n", pHstStream->szName));
    24822515        return VERR_INVALID_PARAMETER;
    24832516    }
     
    24892522
    24902523    if (pCfgAcq)
    2491         memcpy(pCfgAcq, &CfgAcq, sizeof(PDMAUDIOSTREAMCFG));
     2524    {
     2525        int rc2 = DrvAudioHlpStreamCfgCopy(pCfgAcq, &CfgAcq);
     2526        AssertRC(rc2);
     2527    }
    24922528
    24932529    return VINF_SUCCESS;
     
    25222558         * It can be NULL if we were called in drvAudioDestruct, for example. */
    25232559        if (pThis->pHostDrvAudio)
    2524             rc = pThis->pHostDrvAudio->pfnStreamDestroy(pThis->pHostDrvAudio, pHstStream);
     2560            rc = pThis->pHostDrvAudio->pfnStreamDestroy(pThis->pHostDrvAudio, pHstStream->pvBackend);
    25252561        if (RT_SUCCESS(rc))
    25262562        {
     
    27832819            RTListNodeRemove(&pStream->Node);
    27842820
    2785             RTMemFree(pStream);
     2821            drvAudioStreamFree(pStream);
    27862822            pStream = NULL;
    27872823        }
  • trunk/src/VBox/Devices/Audio/DrvAudio.h

    r65027 r65624  
    55
    66/*
    7  * Copyright (C) 2006-2016 Oracle Corporation
     7 * Copyright (C) 2006-2017 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    155155void DrvAudioHlpClearBuf(PPDMAUDIOPCMPROPS pPCMInfo, void *pvBuf, size_t cbBuf, uint32_t cSamples);
    156156uint32_t DrvAudioHlpCalcBitrate(uint8_t cBits, uint32_t uHz, uint8_t cChannels);
    157 uint32_t DrvAudioHlpCalcBitrate(PPDMAUDIOSTREAMCFG pCfg);
     157uint32_t DrvAudioHlpCalcBitrate(PPDMAUDIOPCMPROPS pProps);
    158158bool DrvAudioHlpPCMPropsAreEqual(PPDMAUDIOPCMPROPS pPCMProps1, PPDMAUDIOPCMPROPS pPCMProps2);
    159159bool DrvAudioHlpPCMPropsAreEqual(PPDMAUDIOPCMPROPS pPCMProps, PPDMAUDIOSTREAMCFG pCfg);
     
    161161const char *DrvAudioHlpRecSrcToStr(PDMAUDIORECSOURCE enmRecSource);
    162162void DrvAudioHlpStreamCfgPrint(PPDMAUDIOSTREAMCFG pCfg);
    163 bool DrvAudioHlpStreamCfgIsValid(PPDMAUDIOSTREAMCFG pCfg);
    164 int DrvAudioHlpStreamCfgToProps(PPDMAUDIOSTREAMCFG pCfg, PPDMAUDIOPCMPROPS pProps);
     163bool DrvAudioHlpStreamCfgIsValid(const PPDMAUDIOSTREAMCFG pCfg);
     164int DrvAudioHlpStreamCfgCopy(PPDMAUDIOSTREAMCFG pDstCfg, const PPDMAUDIOSTREAMCFG pSrcCfg);
     165PPDMAUDIOSTREAMCFG DrvAudioHlpStreamCfgDup(const PPDMAUDIOSTREAMCFG pCfg);
     166void DrvAudioHlpStreamCfgFree(PPDMAUDIOSTREAMCFG pCfg);
    165167const char *DrvAudioHlpStreamCmdToStr(PDMAUDIOSTREAMCMD enmCmd);
    166168PDMAUDIOFMT DrvAudioHlpStrToAudFmt(const char *pszFmt);
  • trunk/src/VBox/Devices/Audio/DrvAudioCommon.cpp

    r65056 r65624  
    156156        cbToClear = cbBuf;
    157157
    158     Log2Func(("pPCMInfo=%p, pvBuf=%p, cSamples=%RU32, fSigned=%RTbool, cBits=%RU8, cShift=%RU8\n",
    159               pPCMProps, pvBuf, cSamples, pPCMProps->fSigned, pPCMProps->cBits, pPCMProps->cShift));
     158    Log2Func(("pPCMProps=%p, pvBuf=%p, cSamples=%RU32, fSigned=%RTbool, cBits=%RU8\n",
     159              pPCMProps, pvBuf, cSamples, pPCMProps->fSigned, pPCMProps->cBits));
    160160
    161161    if (pPCMProps->fSigned)
     
    761761
    762762/**
     763 * Checks whether two given PCM properties are equal.
     764 *
     765 * @returns @c true if equal, @c false if not.
     766 * @param   pProps1             First properties to compare.
     767 * @param   pProps2             Second properties to compare.
     768 */
     769bool DrvAudioHlpPCMPropsAreEqual(PPDMAUDIOPCMPROPS pProps1, PPDMAUDIOPCMPROPS pProps2)
     770{
     771    AssertPtrReturn(pProps1, false);
     772    AssertPtrReturn(pProps2, false);
     773
     774    if (pProps1 == pProps2) /* If the pointers match, take a shortcut. */
     775        return true;
     776
     777    return    pProps1->uHz         == pProps2->uHz
     778           && pProps1->cChannels   == pProps2->cChannels
     779           && pProps1->cBits       == pProps2->cBits
     780           && pProps1->fSigned     == pProps2->fSigned
     781           && pProps1->fSwapEndian == pProps2->fSwapEndian;
     782}
     783
     784/**
    763785 * Checks whether the given PCM properties are equal with the given
    764786 * stream configuration.
     
    773795    AssertPtrReturn(pCfg,   false);
    774796
    775     int cBits = 8;
    776     bool fSigned = false;
    777 
    778     switch (pCfg->enmFormat)
    779     {
    780         case PDMAUDIOFMT_S8:
    781             fSigned = true;
    782         case PDMAUDIOFMT_U8:
    783             break;
    784 
    785         case PDMAUDIOFMT_S16:
    786             fSigned = true;
    787         case PDMAUDIOFMT_U16:
    788             cBits = 16;
    789             break;
    790 
    791         case PDMAUDIOFMT_S32:
    792             fSigned = true;
    793         case PDMAUDIOFMT_U32:
    794             cBits = 32;
    795             break;
    796 
    797         default:
    798             AssertMsgFailed(("Unknown format %ld\n", pCfg->enmFormat));
    799             break;
    800     }
    801 
    802     bool fEqual =    pProps->uHz         == pCfg->uHz
    803                   && pProps->cChannels   == pCfg->cChannels
    804                   && pProps->fSigned     == fSigned
    805                   && pProps->cBits       == cBits
    806                   && pProps->fSwapEndian == !(pCfg->enmEndianness == PDMAUDIOHOSTENDIANNESS);
    807     return fEqual;
    808 }
    809 
    810 /**
    811  * Checks whether two given PCM properties are equal.
    812  *
    813  * @returns @c true if equal, @c false if not.
    814  * @param   pProps1             First properties to compare.
    815  * @param   pProps2             Second properties to compare.
    816  */
    817 bool DrvAudioHlpPCMPropsAreEqual(PPDMAUDIOPCMPROPS pProps1, PPDMAUDIOPCMPROPS pProps2)
    818 {
    819     AssertPtrReturn(pProps1, false);
    820     AssertPtrReturn(pProps2, false);
    821 
    822     if (pProps1 == pProps2) /* If the pointers match, take a shortcut. */
    823         return true;
    824 
    825     return    pProps1->uHz         == pProps2->uHz
    826            && pProps1->cChannels   == pProps2->cChannels
    827            && pProps1->fSigned     == pProps2->fSigned
    828            && pProps1->cBits       == pProps2->cBits
    829            && pProps1->fSwapEndian == pProps2->fSwapEndian;
     797    return DrvAudioHlpPCMPropsAreEqual(pProps, &pCfg->Props);
    830798}
    831799
     
    842810    AssertPtrReturn(pCfg,      VERR_INVALID_POINTER);
    843811
    844     pCfg->uHz           = pPCMProps->uHz;
    845     pCfg->cChannels     = pPCMProps->cChannels;
    846     pCfg->enmFormat     = DrvAudioAudFmtBitsToAudFmt(pPCMProps->cBits, pPCMProps->fSigned);
    847 
    848     /** @todo We assume little endian is the default for now. */
    849     pCfg->enmEndianness = pPCMProps->fSwapEndian == false ? PDMAUDIOENDIANNESS_LITTLE : PDMAUDIOENDIANNESS_BIG;
     812    memcpy(&pCfg->Props, pPCMProps, sizeof(PDMAUDIOPCMPROPS));
    850813    return VINF_SUCCESS;
    851814}
     
    856819 * Returns @c true if configuration is valid, @c false if not.
    857820 * @param   pCfg                Stream configuration to check.
    858  */
    859 bool DrvAudioHlpStreamCfgIsValid(PPDMAUDIOSTREAMCFG pCfg)
    860 {
    861     bool fValid = (   pCfg->cChannels == 1
    862                    || pCfg->cChannels == 2); /* Either stereo (2) or mono (1), per stream. */
    863 
    864     fValid |= (   pCfg->enmEndianness == PDMAUDIOENDIANNESS_LITTLE
    865                || pCfg->enmEndianness == PDMAUDIOENDIANNESS_BIG);
     821 *
     822 * @remarks Does *not* support surround (> 2 channels) yet! This is intentional, as
     823 *          we consider surround support as experimental / not enabled by default for now.
     824 */
     825bool DrvAudioHlpStreamCfgIsValid(const PPDMAUDIOSTREAMCFG pCfg)
     826{
     827    AssertPtrReturn(pCfg, false);
     828
     829    bool fValid = (   pCfg->Props.cChannels == 1
     830                   || pCfg->Props.cChannels == 2); /* Either stereo (2) or mono (1), per stream. */
    866831
    867832    fValid |= (   pCfg->enmDir == PDMAUDIODIR_IN
     
    870835    if (fValid)
    871836    {
    872         switch (pCfg->enmFormat)
    873         {
    874             case PDMAUDIOFMT_S8:
    875             case PDMAUDIOFMT_U8:
    876             case PDMAUDIOFMT_S16:
    877             case PDMAUDIOFMT_U16:
    878             case PDMAUDIOFMT_S32:
    879             case PDMAUDIOFMT_U32:
     837        switch (pCfg->Props.cBits)
     838        {
     839            case 8:
     840            case 16:
     841            /** @todo Do we need support for 24-bit samples? */
     842            case 32:
    880843                break;
    881844            default:
     
    885848    }
    886849
    887     fValid |= pCfg->uHz > 0;
    888     /** @todo Check for defined frequencies supported. */
     850    if (!fValid)
     851        return false;
     852
     853    fValid |= pCfg->Props.uHz > 0;
     854    fValid |= pCfg->Props.cShift == PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cBits, pCfg->Props.cChannels);
     855
     856    fValid |= pCfg->Props.fSwapEndian == false; /** @todo Handling Big Endian audio data is not supported yet. */
    889857
    890858    return fValid;
     
    892860
    893861/**
    894  * Converts an audio stream configuration to matching PCM properties.
    895  *
    896  * @return  IPRT status code.
    897  * @param   pCfg                    Audio stream configuration to convert.
    898  * @param   pProps                  PCM properties to save result to.
    899  */
    900 int DrvAudioHlpStreamCfgToProps(PPDMAUDIOSTREAMCFG pCfg, PPDMAUDIOPCMPROPS pProps)
    901 {
    902     AssertPtrReturn(pCfg,   VERR_INVALID_POINTER);
    903     AssertPtrReturn(pProps, VERR_INVALID_POINTER);
    904 
    905     int rc = VINF_SUCCESS;
    906 
    907     int cBits = 8, cShift = 0;
    908     bool fSigned = false;
    909 
    910     switch (pCfg->enmFormat)
    911     {
    912         case PDMAUDIOFMT_S8:
    913             fSigned = true;
    914         case PDMAUDIOFMT_U8:
    915             break;
    916 
    917         case PDMAUDIOFMT_S16:
    918             fSigned = true;
    919         case PDMAUDIOFMT_U16:
    920             cBits = 16;
    921             cShift = 1;
    922             break;
    923 
    924         case PDMAUDIOFMT_S32:
    925             fSigned = true;
    926         case PDMAUDIOFMT_U32:
    927             cBits = 32;
    928             cShift = 2;
    929             break;
    930 
    931         default:
    932             AssertMsgFailed(("Unknown format %ld\n", pCfg->enmFormat));
    933             rc = VERR_NOT_SUPPORTED;
    934             break;
    935     }
    936 
    937     if (RT_SUCCESS(rc))
    938     {
    939         pProps->uHz         = pCfg->uHz;
    940         pProps->cBits       = cBits;
    941         pProps->fSigned     = fSigned;
    942         pProps->cShift      = (pCfg->cChannels == 2) + cShift;
    943         pProps->cChannels   = pCfg->cChannels;
    944         pProps->cbBitrate   = DrvAudioHlpCalcBitrate(pProps->cBits, pProps->uHz, pProps->cChannels) / 8 /* Convert to bytes */;
    945         pProps->uAlign      = (1 << pProps->cShift) - 1;
    946         pProps->fSwapEndian = pCfg->enmEndianness != PDMAUDIOHOSTENDIANNESS;
    947     }
    948 
    949     return rc;
     862 * Frees an allocated audio stream configuration.
     863 *
     864 * @param   pCfg                Audio stream configuration to free.
     865 */
     866void DrvAudioHlpStreamCfgFree(PPDMAUDIOSTREAMCFG pCfg)
     867{
     868    if (pCfg)
     869    {
     870        RTMemFree(pCfg);
     871        pCfg = NULL;
     872    }
     873}
     874
     875/**
     876 * Copies a source stream configuration to a destination stream configuration.
     877 *
     878 * @returns IPRT status code.
     879 * @param   pDstCfg             Destination stream configuration to copy source to.
     880 * @param   pSrcCfg             Source stream configuration to copy to destination.
     881 */
     882int DrvAudioHlpStreamCfgCopy(PPDMAUDIOSTREAMCFG pDstCfg, const PPDMAUDIOSTREAMCFG pSrcCfg)
     883{
     884    AssertPtrReturn(pDstCfg, VERR_INVALID_POINTER);
     885    AssertPtrReturn(pSrcCfg, VERR_INVALID_POINTER);
     886
     887#ifdef VBOX_STRICT
     888    if (!DrvAudioHlpStreamCfgIsValid(pSrcCfg))
     889    {
     890        AssertMsgFailed(("Stream config '%s' (%p) is invalid\n", pSrcCfg->szName, pSrcCfg));
     891        return VERR_INVALID_PARAMETER;
     892    }
     893#endif
     894
     895    memcpy(pDstCfg, pSrcCfg, sizeof(PDMAUDIOSTREAMCFG));
     896
     897    return VINF_SUCCESS;
     898}
     899
     900/**
     901 * Duplicates an audio stream configuration.
     902 * Must be free'd with DrvAudioHlpStreamCfgFree().
     903 *
     904 * @return  Duplicates audio stream configuration on success, or NULL on failure.
     905 * @param   pCfg                    Audio stream configuration to duplicate.
     906 */
     907PPDMAUDIOSTREAMCFG DrvAudioHlpStreamCfgDup(const PPDMAUDIOSTREAMCFG pCfg)
     908{
     909    AssertPtrReturn(pCfg, NULL);
     910
     911    PPDMAUDIOSTREAMCFG pDst = (PPDMAUDIOSTREAMCFG)RTMemAllocZ(sizeof(PDMAUDIOSTREAMCFG));
     912    if (!pDst)
     913        return NULL;
     914
     915    int rc2 = DrvAudioHlpStreamCfgCopy(pDst, pCfg);
     916    if (RT_FAILURE(rc2))
     917    {
     918        DrvAudioHlpStreamCfgFree(pDst);
     919        pDst = NULL;
     920    }
     921
     922    return pDst;
    950923}
    951924
     
    959932    AssertPtrReturnVoid(pCfg);
    960933
    961     LogFlowFunc(("uHz=%RU32, cChannels=%RU8, enmFormat=", pCfg->uHz, pCfg->cChannels));
    962 
    963     switch (pCfg->enmFormat)
    964     {
    965         case PDMAUDIOFMT_S8:
    966             LogFlow(("S8"));
    967             break;
    968         case PDMAUDIOFMT_U8:
    969             LogFlow(("U8"));
    970             break;
    971         case PDMAUDIOFMT_S16:
    972             LogFlow(("S16"));
    973             break;
    974         case PDMAUDIOFMT_U16:
    975             LogFlow(("U16"));
    976             break;
    977         case PDMAUDIOFMT_S32:
    978             LogFlow(("S32"));
    979             break;
    980         case PDMAUDIOFMT_U32:
    981             LogFlow(("U32"));
    982             break;
    983         default:
    984             LogFlow(("invalid(%d)", pCfg->enmFormat));
    985             break;
    986     }
    987 
    988     LogFlow((", endianness="));
    989     switch (pCfg->enmEndianness)
    990     {
    991         case PDMAUDIOENDIANNESS_LITTLE:
    992             LogFlow(("little\n"));
    993             break;
    994         case PDMAUDIOENDIANNESS_BIG:
    995             LogFlow(("big\n"));
    996             break;
    997         default:
    998             LogFlow(("invalid\n"));
    999             break;
    1000     }
     934    LogFlowFunc(("uHz=%RU32, cChannels=%RU8, cBits=%RU8%s",
     935                 pCfg->Props.uHz, pCfg->Props.cChannels, pCfg->Props.cBits, pCfg->Props.fSigned ? "S" : "U"));
    1001936}
    1002937
     
    1045980 *
    1046981 * @returns The calculated bit rate.
    1047  * @param   pCfg                Audio stream configuration to calculate bit rate for.
     982 * @param   pProps              PCM properties to calculate bitrate for.
    1048983 *
    1049984 * @remark
    1050985 */
    1051 uint32_t DrvAudioHlpCalcBitrate(PPDMAUDIOSTREAMCFG pCfg)
    1052 {
    1053     return DrvAudioHlpCalcBitrate(DrvAudioHlpAudFmtToBits(pCfg->enmFormat), pCfg->uHz, pCfg->cChannels);
     986uint32_t DrvAudioHlpCalcBitrate(PPDMAUDIOPCMPROPS pProps)
     987{
     988    return DrvAudioHlpCalcBitrate(pProps->cBits, pProps->uHz, pProps->cChannels);
    1054989}
    1055990
  • trunk/src/VBox/Devices/Audio/DrvHostALSAAudio.cpp

    r65566 r65624  
    7676*********************************************************************************************************************************/
    7777
    78 typedef struct ALSAAUDIOSTREAMIN
    79 {
    80     /** Associated host input stream.
    81      *  Note: Always must come first! */
    82     PDMAUDIOSTREAM      Stream;
    83     /** The PCM properties of this stream. */
    84     PDMAUDIOPCMPROPS    Props;
     78typedef struct ALSAAUDIOSTREAM
     79{
     80    /** The stream's acquired configuration. */
     81    PPDMAUDIOSTREAMCFG pCfg;
     82    union
     83    {
     84        struct
     85        {
     86
     87        } In;
     88        struct
     89        {
     90            /** Minimum samples required for ALSA to play data. */
     91            uint32_t    cSamplesMin;
     92        } Out;
     93    };
    8594    snd_pcm_t          *phPCM;
    8695    void               *pvBuf;
    8796    size_t              cbBuf;
    88 } ALSAAUDIOSTREAMIN, *PALSAAUDIOSTREAMIN;
    89 
    90 typedef struct ALSAAUDIOSTREAMOUT
    91 {
    92     /** Associated host output stream.
    93      *  Note: Always must come first! */
    94     PDMAUDIOSTREAM      Stream;
    95     /** The PCM properties of this stream. */
    96     PDMAUDIOPCMPROPS    Props;
    97     snd_pcm_t          *phPCM;
    98     void               *pvBuf;
    99     size_t              cbBuf;
    100     /** Minimum samples required for ALSA to play data. */
    101     uint32_t            cSamplesMin;
    102 } ALSAAUDIOSTREAMOUT, *PALSAAUDIOSTREAMOUT;
     97} ALSAAUDIOSTREAM, *PALSAAUDIOSTREAM;
    10398
    10499/* latency = period_size * periods / (rate * bytes_per_frame) */
     
    192187
    193188
    194 static snd_pcm_format_t alsaAudioFmtToALSA(PDMAUDIOFMT fmt)
     189static snd_pcm_format_t alsaAudioPropsToALSA(PPDMAUDIOPCMPROPS pProps)
     190{
     191    switch (pProps->cBits)
     192    {
     193        case 8:
     194            return pProps->fSigned ? SND_PCM_FORMAT_S8 : SND_PCM_FORMAT_U8;
     195
     196        case 16:
     197            return pProps->fSigned ? SND_PCM_FORMAT_S16_LE : SND_PCM_FORMAT_U16_LE;
     198
     199        case 32:
     200            return pProps->fSigned ? SND_PCM_FORMAT_S32_LE : SND_PCM_FORMAT_U32_LE;
     201
     202        default:
     203            break;
     204    }
     205
     206    AssertMsgFailed(("%RU8 bits not supported\n", pProps->cBits));
     207    return SND_PCM_FORMAT_U8;
     208}
     209
     210
     211static int alsaALSAToAudioProps(snd_pcm_format_t fmt, PPDMAUDIOPCMPROPS pProps)
    195212{
    196213    switch (fmt)
    197214    {
    198         case PDMAUDIOFMT_S8:
    199             return SND_PCM_FORMAT_S8;
    200 
    201         case PDMAUDIOFMT_U8:
    202             return SND_PCM_FORMAT_U8;
    203 
    204         case PDMAUDIOFMT_S16:
    205             return SND_PCM_FORMAT_S16_LE;
    206 
    207         case PDMAUDIOFMT_U16:
    208             return SND_PCM_FORMAT_U16_LE;
    209 
    210         case PDMAUDIOFMT_S32:
    211             return SND_PCM_FORMAT_S32_LE;
    212 
    213         case PDMAUDIOFMT_U32:
    214             return SND_PCM_FORMAT_U32_LE;
    215 
    216         default:
    217             break;
    218     }
    219 
    220     AssertMsgFailed(("Format %ld not supported\n", fmt));
    221     return SND_PCM_FORMAT_U8;
    222 }
    223 
    224 
    225 static int alsaALSAToAudioFmt(snd_pcm_format_t fmt,
    226                               PDMAUDIOFMT *pFmt, PDMAUDIOENDIANNESS *pEndianness)
    227 {
    228     AssertPtrReturn(pFmt, VERR_INVALID_POINTER);
    229     /* pEndianness is optional. */
    230 
    231     switch (fmt)
    232     {
    233215        case SND_PCM_FORMAT_S8:
    234             *pFmt = PDMAUDIOFMT_S8;
    235             if (pEndianness)
    236                 *pEndianness = PDMAUDIOENDIANNESS_LITTLE;
     216            pProps->cBits   = 8;
     217            pProps->fSigned = true;
    237218            break;
    238219
    239220        case SND_PCM_FORMAT_U8:
    240             *pFmt = PDMAUDIOFMT_U8;
    241             if (pEndianness)
    242                 *pEndianness = PDMAUDIOENDIANNESS_LITTLE;
     221            pProps->cBits   = 8;
     222            pProps->fSigned = false;
    243223            break;
    244224
    245225        case SND_PCM_FORMAT_S16_LE:
    246             *pFmt = PDMAUDIOFMT_S16;
    247             if (pEndianness)
    248                 *pEndianness = PDMAUDIOENDIANNESS_LITTLE;
     226            pProps->cBits   = 16;
     227            pProps->fSigned = true;
    249228            break;
    250229
    251230        case SND_PCM_FORMAT_U16_LE:
    252             *pFmt = PDMAUDIOFMT_U16;
    253             if (pEndianness)
    254                 *pEndianness = PDMAUDIOENDIANNESS_LITTLE;
     231            pProps->cBits   = 16;
     232            pProps->fSigned = false;
    255233            break;
    256234
    257235        case SND_PCM_FORMAT_S16_BE:
    258             *pFmt = PDMAUDIOFMT_S16;
    259             if (pEndianness)
    260                 *pEndianness = PDMAUDIOENDIANNESS_BIG;
     236            pProps->cBits       = 16;
     237            pProps->fSigned     = true;
     238#ifdef RT_LITTLE_ENDIAN
     239            pProps->fSwapEndian = true;
     240#endif
    261241            break;
    262242
    263243        case SND_PCM_FORMAT_U16_BE:
    264             *pFmt = PDMAUDIOFMT_U16;
    265             if (pEndianness)
    266                 *pEndianness = PDMAUDIOENDIANNESS_BIG;
     244            pProps->cBits       = 16;
     245            pProps->fSigned     = false;
     246#ifdef RT_LITTLE_ENDIAN
     247            pProps->fSwapEndian = true;
     248#endif
    267249            break;
    268250
    269251        case SND_PCM_FORMAT_S32_LE:
    270             *pFmt = PDMAUDIOFMT_S32;
    271             if (pEndianness)
    272                 *pEndianness = PDMAUDIOENDIANNESS_LITTLE;
     252            pProps->cBits   = 32;
     253            pProps->fSigned = true;
    273254            break;
    274255
    275256        case SND_PCM_FORMAT_U32_LE:
    276             *pFmt = PDMAUDIOFMT_U32;
    277             if (pEndianness)
    278                 *pEndianness = PDMAUDIOENDIANNESS_LITTLE;
     257            pProps->cBits       = 32;
     258            pProps->fSigned     = false;
    279259            break;
    280260
    281261        case SND_PCM_FORMAT_S32_BE:
    282             *pFmt = PDMAUDIOFMT_S32;
    283             if (pEndianness)
    284                 *pEndianness = PDMAUDIOENDIANNESS_BIG;
     262            pProps->cBits       = 32;
     263            pProps->fSigned     = true;
     264#ifdef RT_LITTLE_ENDIAN
     265            pProps->fSwapEndian = true;
     266#endif
    285267            break;
    286268
    287269        case SND_PCM_FORMAT_U32_BE:
    288             *pFmt = PDMAUDIOFMT_U32;
    289             if (pEndianness)
    290                 *pEndianness = PDMAUDIOENDIANNESS_BIG;
     270            pProps->cBits       = 32;
     271            pProps->fSigned     = false;
     272#ifdef RT_LITTLE_ENDIAN
     273            pProps->fSwapEndian = true;
     274#endif
    291275            break;
    292276
     
    295279            return VERR_NOT_SUPPORTED;
    296280    }
     281
     282    Assert(pProps->cChannels);
     283    pProps->cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pProps->cBits, pProps->cChannels);
    297284
    298285    return VINF_SUCCESS;
     
    912899    int rc;
    913900
    914     snd_pcm_sframes_t framesAvail;
    915     framesAvail = snd_pcm_avail_update(phPCM);
     901    snd_pcm_sframes_t framesAvail = snd_pcm_avail_update(phPCM);
    916902    if (framesAvail < 0)
    917903    {
     
    996982static DECLCALLBACK(int) drvHostALSAAudioInit(PPDMIHOSTAUDIO pInterface)
    997983{
    998     NOREF(pInterface);
     984    RT_NOREF(pInterface);
    999985
    1000986    LogFlowFuncEnter();
     
    10181004 */
    10191005static DECLCALLBACK(int) drvHostALSAAudioStreamCapture(PPDMIHOSTAUDIO pInterface,
    1020                                                        PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
     1006                                                       PPDMAUDIOBACKENDSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
    10211007{
    10221008    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     
    10261012    /* pcbRead is optional. */
    10271013
    1028     PALSAAUDIOSTREAMIN pStreamALSA = (PALSAAUDIOSTREAMIN)pStream;
     1014    PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream;
    10291015
    10301016    snd_pcm_sframes_t cAvail;
     
    10361022    }
    10371023
     1024    PPDMAUDIOSTREAMCFG pCfg = pStreamALSA->pCfg;
     1025    AssertPtr(pCfg);
     1026
    10381027    if (!cAvail) /* No data yet? */
    10391028    {
     
    10421031        {
    10431032            case SND_PCM_STATE_PREPARED:
    1044                 cAvail = PDMAUDIOPCMPROPS_B2S(&pStreamALSA->Props, cbBuf);
     1033                cAvail = PDMAUDIOSTREAMCFG_B2S(pCfg, cbBuf);
    10451034                break;
    10461035
     
    10721061     * the mixer buffer.
    10731062     */
    1074     size_t cbToRead = RT_MIN((size_t)PDMAUDIOPCMPROPS_S2B(&pStreamALSA->Props, cAvail), cbBuf);
     1063    size_t cbToRead = RT_MIN((size_t)PDMAUDIOSTREAMCFG_S2B(pCfg, cAvail), cbBuf);
    10751064
    10761065    LogFlowFunc(("cbToRead=%zu, cAvail=%RI32\n", cbToRead, cAvail));
     
    10841073           && RT_SUCCESS(rc))
    10851074    {
    1086         cToRead = RT_MIN(PDMAUDIOPCMPROPS_B2S(&pStreamALSA->Props, cbToRead),
    1087                          PDMAUDIOPCMPROPS_B2S(&pStreamALSA->Props, pStreamALSA->cbBuf));
     1075        cToRead = RT_MIN(PDMAUDIOSTREAMCFG_B2S(pCfg, cbToRead),
     1076                         PDMAUDIOSTREAMCFG_B2S(pCfg, pStreamALSA->cbBuf));
    10881077        AssertBreakStmt(cToRead, rc = VERR_NO_DATA);
    10891078        cRead = snd_pcm_readi(pStreamALSA->phPCM, pStreamALSA->pvBuf, cToRead);
     
    11351124             * capture device for example).
    11361125             */
    1137             uint32_t cbRead = PDMAUDIOPCMPROPS_S2B(&pStreamALSA->Props, cRead);
     1126            uint32_t cbRead = PDMAUDIOSTREAMCFG_S2B(pCfg, cRead);
    11381127
    11391128            memcpy(pvBuf, pStreamALSA->pvBuf, cbRead);
     
    11581147 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay}
    11591148 */
    1160 static DECLCALLBACK(int) drvHostALSAAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream,
     1149static DECLCALLBACK(int) drvHostALSAAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
    11611150                                                    const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
    11621151{
     
    11671156    /* pcbWritten is optional. */
    11681157
    1169     PALSAAUDIOSTREAMOUT pStreamALSA = (PALSAAUDIOSTREAMOUT)pStream;
     1158    PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream;
    11701159
    11711160    int rc = VINF_SUCCESS;
     
    11751164    do
    11761165    {
    1177         snd_pcm_sframes_t cAvail;
    1178         rc = alsaStreamGetAvail(pStreamALSA->phPCM, &cAvail);
     1166        snd_pcm_sframes_t csAvail;
     1167        rc = alsaStreamGetAvail(pStreamALSA->phPCM, &csAvail);
    11791168        if (RT_FAILURE(rc))
    11801169        {
     
    11831172        }
    11841173
    1185         size_t cbToRead = RT_MIN((unsigned)PDMAUDIOPCMPROPS_S2B(&pStreamALSA->Props, cAvail), cbBuf);
    1186         if (!cbToRead)
    1187             break;
    1188 
    1189         memcpy(pStreamALSA->pvBuf, pvBuf, cbToRead);
    1190 
    1191         snd_pcm_sframes_t cWritten = 0;
     1174        if (!csAvail)
     1175            break;
     1176
     1177        PPDMAUDIOSTREAMCFG pCfg = pStreamALSA->pCfg;
     1178        AssertPtr(pCfg);
     1179
     1180        size_t cbToWrite = RT_MIN((unsigned)PDMAUDIOSTREAMCFG_S2B(pCfg, csAvail), RT_MIN(pStreamALSA->cbBuf, cbBuf));
     1181        if (!cbToWrite)
     1182            break;
     1183
     1184        memcpy(pStreamALSA->pvBuf, pvBuf, cbToWrite);
     1185
     1186        snd_pcm_sframes_t csWritten = 0;
    11921187
    11931188        /* Don't try infinitely on recoverable errors. */
     
    11951190        for (iTry = 0; iTry < ALSA_RECOVERY_TRIES_MAX; iTry++)
    11961191        {
    1197             cWritten = snd_pcm_writei(pStreamALSA->phPCM, pStreamALSA->pvBuf,
    1198                                       PDMAUDIOPCMPROPS_B2S(&pStreamALSA->Props, cbToRead));
    1199             if (cWritten <= 0)
     1192            csWritten = snd_pcm_writei(pStreamALSA->phPCM, pStreamALSA->pvBuf,
     1193                                       PDMAUDIOSTREAMCFG_B2S(pCfg, cbToWrite));
     1194            if (csWritten <= 0)
    12001195            {
    1201                 switch (cWritten)
     1196                switch (csWritten)
    12021197                {
    12031198                    case 0:
    12041199                    {
    1205                         LogFunc(("Failed to write %zu bytes\n", cbToRead));
     1200                        LogFunc(("Failed to write %zu bytes\n", cbToWrite));
    12061201                        rc = VERR_ACCESS_DENIED;
    12071202                        break;
     
    12331228
    12341229                    default:
    1235                         LogFlowFunc(("Failed to write %RU32 bytes, error unknown\n", cbToRead));
     1230                        LogFlowFunc(("Failed to write %RU32 bytes, error unknown\n", cbToWrite));
    12361231                        rc = VERR_GENERAL_FAILURE; /** @todo */
    12371232                        break;
     
    12431238
    12441239        if (   iTry == ALSA_RECOVERY_TRIES_MAX
    1245             && cWritten <= 0)
     1240            && csWritten <= 0)
    12461241            rc = VERR_BROKEN_PIPE;
    12471242
     
    12491244            break;
    12501245
    1251         cbWrittenTotal = cbToRead;
     1246        cbWrittenTotal += cbToWrite;
    12521247
    12531248    } while (0);
     
    12641259
    12651260
    1266 static int alsaDestroyStreamIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
    1267 {
    1268     NOREF(pInterface);
    1269     AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    1270 
    1271     PALSAAUDIOSTREAMIN pThisStream = (PALSAAUDIOSTREAMIN)pStream;
    1272 
    1273     alsaStreamClose(&pThisStream->phPCM);
    1274 
    1275     if (pThisStream->pvBuf)
    1276     {
    1277         RTMemFree(pThisStream->pvBuf);
    1278         pThisStream->pvBuf = NULL;
     1261static int alsaDestroyStreamIn(PALSAAUDIOSTREAM pStreamALSA)
     1262{
     1263    alsaStreamClose(&pStreamALSA->phPCM);
     1264
     1265    if (pStreamALSA->pvBuf)
     1266    {
     1267        RTMemFree(pStreamALSA->pvBuf);
     1268        pStreamALSA->pvBuf = NULL;
    12791269    }
    12801270
     
    12831273
    12841274
    1285 static int alsaDestroyStreamOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
    1286 {
    1287     NOREF(pInterface);
    1288     AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    1289 
    1290     PALSAAUDIOSTREAMOUT pThisStream = (PALSAAUDIOSTREAMOUT)pStream;
    1291 
    1292     alsaStreamClose(&pThisStream->phPCM);
    1293 
    1294     if (pThisStream->pvBuf)
    1295     {
    1296         RTMemFree(pThisStream->pvBuf);
    1297         pThisStream->pvBuf = NULL;
     1275static int alsaDestroyStreamOut(PALSAAUDIOSTREAM pStreamALSA)
     1276{
     1277    alsaStreamClose(&pStreamALSA->phPCM);
     1278
     1279    if (pStreamALSA->pvBuf)
     1280    {
     1281        RTMemFree(pStreamALSA->pvBuf);
     1282        pStreamALSA->pvBuf = NULL;
    12981283    }
    12991284
     
    13021287
    13031288
    1304 static int alsaCreateStreamOut(PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    1305 {
    1306     PALSAAUDIOSTREAMOUT pStreamALSA = (PALSAAUDIOSTREAMOUT)pStream;
    1307 
     1289static int alsaCreateStreamOut(PALSAAUDIOSTREAM pStreamALSA, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     1290{
    13081291    snd_pcm_t *phPCM = NULL;
    13091292
     
    13131296    {
    13141297        ALSAAUDIOSTREAMCFG req;
    1315         req.fmt         = alsaAudioFmtToALSA(pCfgReq->enmFormat);
    1316         req.freq        = pCfgReq->uHz;
    1317         req.nchannels   = pCfgReq->cChannels;
    1318         req.period_size = s_ALSAConf.period_size_out;
    1319         req.buffer_size = s_ALSAConf.buffer_size_out;
     1298        req.fmt         = alsaAudioPropsToALSA(&pCfgReq->Props);
     1299        req.freq        = pCfgReq->Props.uHz;
     1300        req.nchannels   = pCfgReq->Props.cChannels;
     1301        req.period_size = s_ALSAConf.period_size_out; /** @todo Make this configurable. */
     1302        req.buffer_size = s_ALSAConf.buffer_size_out; /** @todo Make this configurable. */
    13201303
    13211304        ALSAAUDIOSTREAMCFG obt;
     
    13241307            break;
    13251308
    1326         PDMAUDIOFMT enmFormat;
    1327         PDMAUDIOENDIANNESS enmEnd;
    1328         rc = alsaALSAToAudioFmt(obt.fmt, &enmFormat, &enmEnd);
     1309        pCfgAcq->Props.uHz       = obt.freq;
     1310        pCfgAcq->Props.cChannels = obt.nchannels;
     1311
     1312        rc = alsaALSAToAudioProps(obt.fmt, &pCfgAcq->Props);
    13291313        if (RT_FAILURE(rc))
    13301314            break;
    13311315
    1332         pCfgAcq->uHz               = obt.freq;
    1333         pCfgAcq->cChannels         = obt.nchannels;
    1334         pCfgAcq->enmFormat         = enmFormat;
    1335         pCfgAcq->enmEndianness     = enmEnd;
    1336         pCfgAcq->cSampleBufferSize = obt.samples * 4;
    1337 
    1338         rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &pStreamALSA->Props);
    1339         if (RT_FAILURE(rc))
    1340             break;
     1316        pCfgAcq->cSampleBufferHint = obt.samples * 4;
    13411317
    13421318        AssertBreakStmt(obt.samples, rc = VERR_INVALID_PARAMETER);
    13431319
    1344         size_t cbBuf = obt.samples * PDMAUDIOPCMPROPS_S2B(&pStreamALSA->Props, 1);
     1320        size_t cbBuf = obt.samples * PDMAUDIOSTREAMCFG_S2B(pCfgAcq, 1);
    13451321        AssertBreakStmt(cbBuf, rc = VERR_INVALID_PARAMETER);
    13461322
     
    13661342
    13671343
    1368 static int alsaCreateStreamIn(PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     1344static int alsaCreateStreamIn(PALSAAUDIOSTREAM pStreamALSA, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    13691345{
    13701346    int rc;
    13711347
    1372     PALSAAUDIOSTREAMIN pThisStream = (PALSAAUDIOSTREAMIN)pStream;
    13731348    snd_pcm_t *phPCM = NULL;
    13741349
     
    13761351    {
    13771352        ALSAAUDIOSTREAMCFG req;
    1378         req.fmt         = alsaAudioFmtToALSA(pCfgReq->enmFormat);
    1379         req.freq        = pCfgReq->uHz;
    1380         req.nchannels   = pCfgReq->cChannels;
    1381         req.period_size = s_ALSAConf.period_size_in;
    1382         req.buffer_size = s_ALSAConf.buffer_size_in;
     1353        req.fmt         = alsaAudioPropsToALSA(&pCfgReq->Props);
     1354        req.freq        = pCfgReq->Props.uHz;
     1355        req.nchannels   = pCfgReq->Props.cChannels;
     1356        req.period_size = s_ALSAConf.period_size_in; /** @todo Make this configurable. */
     1357        req.buffer_size = s_ALSAConf.buffer_size_in; /** @todo Make this configurable. */
    13831358
    13841359        ALSAAUDIOSTREAMCFG obt;
     
    13871362            break;
    13881363
    1389         PDMAUDIOFMT enmFormat;
    1390         PDMAUDIOENDIANNESS enmEnd;
    1391         rc = alsaALSAToAudioFmt(obt.fmt, &enmFormat, &enmEnd);
     1364        pCfgAcq->Props.uHz       = obt.freq;
     1365        pCfgAcq->Props.cChannels = obt.nchannels;
     1366
     1367        rc = alsaALSAToAudioProps(obt.fmt, &pCfgAcq->Props);
    13921368        if (RT_FAILURE(rc))
    13931369            break;
    13941370
    1395         pCfgAcq->uHz               = obt.freq;
    1396         pCfgAcq->cChannels         = obt.nchannels;
    1397         pCfgAcq->enmFormat         = enmFormat;
    1398         pCfgAcq->enmEndianness     = enmEnd;
    1399         pCfgAcq->cSampleBufferSize = obt.samples;
    1400 
    1401         PDMAUDIOPCMPROPS Props;
    1402         rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &Props);
    1403         if (RT_FAILURE(rc))
    1404             break;
     1371        pCfgAcq->cSampleBufferHint = obt.samples;
    14051372
    14061373        AssertBreakStmt(obt.samples, rc = VERR_INVALID_PARAMETER);
    1407         size_t cbBuf = obt.samples * (1 << Props.cShift); /** @todo Get rid of using Props! */
     1374
     1375        size_t cbBuf = obt.samples * PDMAUDIOSTREAMCFG_S2B(pCfgAcq, 1);
    14081376        AssertBreakStmt(cbBuf, rc = VERR_INVALID_PARAMETER);
    1409         pThisStream->pvBuf = RTMemAlloc(cbBuf);
    1410         if (!pThisStream->pvBuf)
    1411         {
    1412             LogRel(("ALSA: Not enough memory for input ADC buffer (%RU32 samples, each %d bytes)\n",
    1413                     obt.samples, 1 << Props.cShift));
     1377
     1378        pStreamALSA->pvBuf = RTMemAlloc(cbBuf);
     1379        if (!pStreamALSA->pvBuf)
     1380        {
     1381            LogRel(("ALSA: Not enough memory for input ADC buffer (%RU32 samples, %zu bytes)\n", obt.samples, cbBuf));
    14141382            rc = VERR_NO_MEMORY;
    14151383            break;
    14161384        }
    14171385
    1418         pThisStream->cbBuf = cbBuf;
    1419         pThisStream->phPCM = phPCM;
     1386        pStreamALSA->cbBuf = cbBuf;
     1387        pStreamALSA->phPCM = phPCM;
    14201388    }
    14211389    while (0);
     
    14291397
    14301398
    1431 static int alsaControlStreamIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream,
    1432                                PDMAUDIOSTREAMCMD enmStreamCmd)
    1433 {
    1434     NOREF(pInterface);
    1435     AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    1436     PALSAAUDIOSTREAMIN pThisStream = (PALSAAUDIOSTREAMIN)pStream;
    1437 
    1438     LogFlowFunc(("enmStreamCmd=%ld\n", enmStreamCmd));
    1439 
     1399static int alsaControlStreamIn(PALSAAUDIOSTREAM pStreamALSA, PDMAUDIOSTREAMCMD enmStreamCmd)
     1400{
    14401401    int rc;
    14411402    switch (enmStreamCmd)
     
    14431404        case PDMAUDIOSTREAMCMD_ENABLE:
    14441405        case PDMAUDIOSTREAMCMD_RESUME:
    1445             rc = drvHostALSAAudioStreamCtl(pThisStream->phPCM, false /* fStop */);
     1406            rc = drvHostALSAAudioStreamCtl(pStreamALSA->phPCM, false /* fStop */);
    14461407            break;
    14471408
    14481409        case PDMAUDIOSTREAMCMD_DISABLE:
    14491410        case PDMAUDIOSTREAMCMD_PAUSE:
    1450             rc = drvHostALSAAudioStreamCtl(pThisStream->phPCM, true /* fStop */);
     1411            rc = drvHostALSAAudioStreamCtl(pStreamALSA->phPCM, true /* fStop */);
    14511412            break;
    14521413
     
    14611422
    14621423
    1463 static int alsaControlStreamOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream,
    1464                                 PDMAUDIOSTREAMCMD enmStreamCmd)
    1465 {
    1466     NOREF(pInterface);
    1467     AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    1468     PALSAAUDIOSTREAMOUT pThisStream = (PALSAAUDIOSTREAMOUT)pStream;
    1469 
    1470     LogFlowFunc(("enmStreamCmd=%ld\n", enmStreamCmd));
    1471 
     1424static int alsaControlStreamOut(PALSAAUDIOSTREAM pStreamALSA, PDMAUDIOSTREAMCMD enmStreamCmd)
     1425{
    14721426    int rc;
    14731427    switch (enmStreamCmd)
     
    14751429        case PDMAUDIOSTREAMCMD_ENABLE:
    14761430        case PDMAUDIOSTREAMCMD_RESUME:
    1477             rc = drvHostALSAAudioStreamCtl(pThisStream->phPCM, false /* fStop */);
     1431            rc = drvHostALSAAudioStreamCtl(pStreamALSA->phPCM, false /* fStop */);
    14781432            break;
    14791433
    14801434        case PDMAUDIOSTREAMCMD_DISABLE:
    14811435        case PDMAUDIOSTREAMCMD_PAUSE:
    1482             rc = drvHostALSAAudioStreamCtl(pThisStream->phPCM, true /* fStop */);
     1436            rc = drvHostALSAAudioStreamCtl(pStreamALSA->phPCM, true /* fStop */);
    14831437            break;
    14841438
     
    14981452static DECLCALLBACK(int) drvHostALSAAudioGetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg)
    14991453{
    1500     NOREF(pInterface);
     1454    RT_NOREF(pInterface);
    15011455    AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER);
    15021456
    1503     pBackendCfg->cbStreamIn  = sizeof(ALSAAUDIOSTREAMIN);
    1504     pBackendCfg->cbStreamOut = sizeof(ALSAAUDIOSTREAMOUT);
     1457    pBackendCfg->cbStreamIn  = sizeof(ALSAAUDIOSTREAM);
     1458    pBackendCfg->cbStreamOut = sizeof(ALSAAUDIOSTREAM);
    15051459
    15061460    /* Enumerate sound devices. */
     
    15711525static DECLCALLBACK(void) drvHostALSAAudioShutdown(PPDMIHOSTAUDIO pInterface)
    15721526{
    1573     NOREF(pInterface);
     1527    RT_NOREF(pInterface);
    15741528}
    15751529
     
    15901544 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate}
    15911545 */
    1592 static DECLCALLBACK(int) drvHostALSAAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     1546static DECLCALLBACK(int) drvHostALSAAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
     1547                                                      PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    15931548{
    15941549    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     
    15971552    AssertPtrReturn(pCfgAcq,    VERR_INVALID_POINTER);
    15981553
     1554    PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream;
     1555
    15991556    int rc;
    16001557    if (pCfgReq->enmDir == PDMAUDIODIR_IN)
    1601         rc = alsaCreateStreamIn(pStream, pCfgReq, pCfgAcq);
     1558        rc = alsaCreateStreamIn (pStreamALSA, pCfgReq, pCfgAcq);
    16021559    else
    1603         rc = alsaCreateStreamOut(pStream, pCfgReq, pCfgAcq);
    1604 
    1605     LogFlowFunc(("%s: rc=%Rrc\n", pStream->szName, rc));
     1560        rc = alsaCreateStreamOut(pStreamALSA, pCfgReq, pCfgAcq);
     1561
     1562    if (RT_SUCCESS(rc))
     1563    {
     1564        pStreamALSA->pCfg = DrvAudioHlpStreamCfgDup(pCfgAcq);
     1565        if (!pStreamALSA->pCfg)
     1566            rc = VERR_NO_MEMORY;
     1567    }
     1568
    16061569    return rc;
    16071570}
     
    16111574 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy}
    16121575 */
    1613 static DECLCALLBACK(int) drvHostALSAAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     1576static DECLCALLBACK(int) drvHostALSAAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    16141577{
    16151578    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    16161579    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    16171580
     1581    PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream;
     1582
     1583    if (!pStreamALSA->pCfg) /* Not (yet) configured? Skip. */
     1584        return VINF_SUCCESS;
     1585
    16181586    int rc;
    1619     if (pStream->enmDir == PDMAUDIODIR_IN)
    1620         rc = alsaDestroyStreamIn(pInterface,  pStream);
     1587    if (pStreamALSA->pCfg->enmDir == PDMAUDIODIR_IN)
     1588        rc = alsaDestroyStreamIn(pStreamALSA);
    16211589    else
    1622         rc = alsaDestroyStreamOut(pInterface, pStream);
     1590        rc = alsaDestroyStreamOut(pStreamALSA);
     1591
     1592    if (RT_SUCCESS(rc))
     1593    {
     1594        DrvAudioHlpStreamCfgFree(pStreamALSA->pCfg);
     1595        pStreamALSA->pCfg = NULL;
     1596    }
    16231597
    16241598    return rc;
     
    16291603 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl}
    16301604 */
    1631 static DECLCALLBACK(int) drvHostALSAAudioStreamControl(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
     1605static DECLCALLBACK(int) drvHostALSAAudioStreamControl(PPDMIHOSTAUDIO pInterface,
     1606                                                       PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
    16321607{
    16331608    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    16341609    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    16351610
    1636     Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST);
     1611    PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream;
     1612
     1613    if (!pStreamALSA->pCfg) /* Not (yet) configured? Skip. */
     1614        return VINF_SUCCESS;
    16371615
    16381616    int rc;
    1639     if (pStream->enmDir == PDMAUDIODIR_IN)
    1640         rc = alsaControlStreamIn(pInterface,  pStream, enmStreamCmd);
     1617    if (pStreamALSA->pCfg->enmDir == PDMAUDIODIR_IN)
     1618        rc = alsaControlStreamIn (pStreamALSA, enmStreamCmd);
    16411619    else
    1642         rc = alsaControlStreamOut(pInterface, pStream, enmStreamCmd);
     1620        rc = alsaControlStreamOut(pStreamALSA, enmStreamCmd);
    16431621
    16441622    return rc;
     
    16491627 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
    16501628 */
    1651 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostALSAAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
    1652 {
    1653     NOREF(pInterface);
    1654     NOREF(pStream);
     1629static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostALSAAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
     1630{
     1631    RT_NOREF(pInterface);
     1632
     1633    PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream;
    16551634
    16561635    PDMAUDIOSTRMSTS strmSts =   PDMAUDIOSTRMSTS_FLAG_INITIALIZED
    16571636                              | PDMAUDIOSTRMSTS_FLAG_ENABLED;
    16581637
    1659     snd_pcm_t         *phPCM       = NULL;
    1660     snd_pcm_sframes_t  cSamplesMin;
    1661 
    1662     /** @todo Get rid of this once we have a unified ALSA stream. */
    1663     if (pStream->enmDir == PDMAUDIODIR_IN)
    1664     {
    1665         PALSAAUDIOSTREAMIN pStreamIn = (PALSAAUDIOSTREAMIN)pStream;
    1666         phPCM       = pStreamIn->phPCM;
    1667         cSamplesMin = 0;
    1668     }
    1669     else if (pStream->enmDir == PDMAUDIODIR_OUT)
    1670     {
    1671         PALSAAUDIOSTREAMOUT pStreamOut = (PALSAAUDIOSTREAMOUT)pStream;
    1672         phPCM       = pStreamOut->phPCM;
    1673         cSamplesMin = pStreamOut->cSamplesMin;
    1674     }
    1675     else
    1676         AssertFailed();
     1638    snd_pcm_t         *phPCM       = pStreamALSA->phPCM;
     1639    snd_pcm_sframes_t  cSamplesMin = 0;
     1640
     1641    if (pStreamALSA->pCfg->enmDir == PDMAUDIODIR_OUT)
     1642        cSamplesMin = pStreamALSA->Out.cSamplesMin;
    16771643
    16781644    if (phPCM)
     
    16841650            Log3Func(("cAvail=%ld \n", cSamplesAvail));
    16851651            if (cSamplesAvail >= cSamplesMin)
    1686                 strmSts |= pStream->enmDir == PDMAUDIODIR_IN
     1652                strmSts |= pStreamALSA->pCfg->enmDir == PDMAUDIODIR_IN
    16871653                         ? PDMAUDIOSTRMSTS_FLAG_DATA_READABLE
    16881654                         : PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE;
     
    16971663 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate}
    16981664 */
    1699 static DECLCALLBACK(int) drvHostALSAAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     1665static DECLCALLBACK(int) drvHostALSAAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    17001666{
    17011667    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
  • trunk/src/VBox/Devices/Audio/DrvHostCoreAudio.cpp

    r65567 r65624  
    209209    AssertPtrReturn(pCfg,  VERR_INVALID_PARAMETER);
    210210
    211     pCfg->cChannels     = pASBD->mChannelsPerFrame;
    212     pCfg->uHz           = (uint32_t)pASBD->mSampleRate;
    213     pCfg->enmEndianness = PDMAUDIOENDIANNESS_LITTLE;
    214 
    215     int rc = VINF_SUCCESS;
    216 
    217     if (pASBD->mFormatFlags & kAudioFormatFlagIsSignedInteger)
    218     {
    219         switch (pASBD->mBitsPerChannel)
    220         {
    221             case 8:  pCfg->enmFormat = PDMAUDIOFMT_S8;  break;
    222             case 16: pCfg->enmFormat = PDMAUDIOFMT_S16; break;
    223             case 32: pCfg->enmFormat = PDMAUDIOFMT_S32; break;
    224             default: rc = VERR_NOT_SUPPORTED;           break;
    225         }
    226     }
    227     else
    228     {
    229         switch (pASBD->mBitsPerChannel)
    230         {
    231             case 8:  pCfg->enmFormat = PDMAUDIOFMT_U8;  break;
    232             case 16: pCfg->enmFormat = PDMAUDIOFMT_U16; break;
    233             case 32: pCfg->enmFormat = PDMAUDIOFMT_U32; break;
    234             default: rc = VERR_NOT_SUPPORTED;           break;
    235         }
    236     }
    237 
    238     AssertRC(rc);
    239     return rc;
     211    pCfg->Props.cChannels = pASBD->mChannelsPerFrame;
     212    pCfg->Props.uHz       = (uint32_t)pASBD->mSampleRate;
     213    pCfg->Props.cBits     = pASBD->mBitsPerChannel;
     214    pCfg->Props.fSigned   = RT_BOOL(pASBD->mFormatFlags & kAudioFormatFlagIsSignedInteger);
     215    pCfg->Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cBits, pCfg->Props.cChannels);
     216
     217    return VINF_SUCCESS;
    240218}
    241219#endif /* !VBOX_WITH_AUDIO_CALLBACKS */
     
    382360typedef struct COREAUDIOSTREAM
    383361{
    384     /** PDM audio stream data.
    385      *  Note: Always must come first in this structure! */
    386     PDMAUDIOSTREAM              Stream;
     362    /** The stream's acquired configuration. */
     363    PPDMAUDIOSTREAMCFG          pCfg;
    387364    /** Stream-specific data, depending on the stream type. */
    388365    union
     
    395372    /** Pointer to driver instance this stream is bound to. */
    396373    PDRVHOSTCOREAUDIO           pDrv;
    397     /** The PCM properties of this stream. */
    398     PDMAUDIOPCMPROPS            Props;
    399     /** The stream's direction. */
    400     PDMAUDIODIR                 enmDir;
    401374    /** The stream's thread handle for maintaining the audio queue. */
    402375    RTTHREAD                    hThread;
     
    13071280    PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pvUser;
    13081281    AssertPtr(pCAStream);
     1282    AssertPtr(pCAStream->pCfg);
    13091283
    13101284    LogFunc(("Starting pCAStream=%p\n", pCAStream));
     1285
     1286    const bool fIn = pCAStream->pCfg->enmDir == PDMAUDIODIR_IN;
    13111287
    13121288    /*
     
    13141290     */
    13151291    OSStatus err;
    1316     if (pCAStream->enmDir == PDMAUDIODIR_IN)
     1292    if (fIn)
    13171293        err = AudioQueueNewInput(&pCAStream->asbdStream, coreAudioInputQueueCb, pCAStream /* pvData */,
    13181294                                 CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0, &pCAStream->audioQueue);
     
    13561332     * Enter the main loop.
    13571333     */
    1358     const bool fIn = pCAStream->enmDir == PDMAUDIODIR_IN;
    1359 
    13601334    while (!ASMAtomicReadBool(&pCAStream->fShutdown))
    13611335    {
     
    15631537        AudioQueueBufferRef pBuf = pCAStream->audioBuffer[i];
    15641538
    1565         if (pCAStream->enmDir == PDMAUDIODIR_IN)
     1539        if (pCAStream->pCfg->enmDir == PDMAUDIODIR_IN)
    15661540        {
    15671541            int rc2 = coreAudioInputQueueProcBuffer(pCAStream, pBuf);
     
    15711545            }
    15721546        }
    1573         else if (pCAStream->enmDir == PDMAUDIODIR_OUT)
     1547        else if (pCAStream->pCfg->enmDir == PDMAUDIODIR_OUT)
    15741548        {
    15751549            int rc2 = coreAudioOutputQueueProcBuffer(pCAStream, pBuf);
     
    16081582        return VERR_NOT_AVAILABLE;
    16091583
    1610     pCAStream->enmDir = pCfgReq->enmDir;
    1611 
    1612     const bool fIn = pCAStream->enmDir == PDMAUDIODIR_IN;
     1584    const bool fIn = pCfgReq->enmDir == PDMAUDIODIR_IN;
     1585
     1586    int rc = VINF_SUCCESS;
    16131587
    16141588    /* Create the recording device's out format based on our required audio settings. */
    1615     int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pCAStream->Props);
    1616     if (RT_FAILURE(rc))
    1617     {
    1618         LogRel(("CoreAudio: Failed to convert requested %s format to native format (%Rrc)\n", fIn ? "input" : "output", rc));
    1619         return rc;
    1620     }
    1621 
    1622     coreAudioPCMPropsToASBD(&pCAStream->Props, &pCAStream->asbdStream);
     1589    Assert(pCAStream->pCfg == NULL);
     1590    pCAStream->pCfg = DrvAudioHlpStreamCfgDup(pCfgReq);
     1591    if (!pCAStream->pCfg)
     1592        rc = VERR_NO_MEMORY;
     1593
     1594    coreAudioPCMPropsToASBD(&pCfgReq->Props, &pCAStream->asbdStream);
     1595    /** @todo Do some validation? */
    16231596
    16241597    coreAudioPrintASBD(  fIn
    16251598                       ? "Capturing queue format"
    16261599                       : "Playback queue format", &pCAStream->asbdStream);
     1600
     1601    if (RT_FAILURE(rc))
     1602    {
     1603        LogRel(("CoreAudio: Failed to convert requested %s format to native format (%Rrc)\n", fIn ? "input" : "output", rc));
     1604        return rc;
     1605    }
    16271606
    16281607    rc = RTCircBufCreate(&pCAStream->pCircBuf, 8096 << 1 /*pHstStrmIn->Props.cShift*/); /** @todo FIX THIS !!! */
     
    19221901 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture}
    19231902 */
    1924 static DECLCALLBACK(int) drvHostCoreAudioStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream,
     1903static DECLCALLBACK(int) drvHostCoreAudioStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
    19251904                                                       void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
    19261905{
     
    20242003 */
    20252004static DECLCALLBACK(int) drvHostCoreAudioStreamPlay(PPDMIHOSTAUDIO pInterface,
    2026                                                     PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf,
     2005                                                    PPDMAUDIOBACKENDSTREAM pStream, const void *pvBuf, uint32_t cbBuf,
    20272006                                                    uint32_t *pcbWritten)
    20282007{
     
    20812060        Assert(cbWrittenTotal + cbChunk <= cbBuf);
    20822061
    2083         memcpy((uint8_t *)pvBuf + cbWrittenTotal, pvChunk, cbChunk);
     2062        memcpy(pvChunk, (uint8_t *)pvBuf + cbWrittenTotal, cbChunk);
    20842063
    20852064        /* Release the ring buffer, so the read thread could start reading this data. */
     
    21382117    }
    21392118
     2119    if (!pCAStream->pCfg) /* Not (yet) configured? Skip. */
     2120        return VINF_SUCCESS;
     2121
    21402122    int rc = VINF_SUCCESS;
    21412123
     
    21462128        {
    21472129            LogFunc(("Queue enable\n"));
    2148             if (pCAStream->enmDir == PDMAUDIODIR_IN)
     2130            if (pCAStream->pCfg->enmDir == PDMAUDIODIR_IN)
    21492131            {
    21502132                rc = coreAudioStreamInvalidateQueue(pCAStream);
     
    21552137                }
    21562138            }
    2157             if (pCAStream->enmDir == PDMAUDIODIR_OUT)
     2139            else if (pCAStream->pCfg->enmDir == PDMAUDIODIR_OUT)
    21582140            {
    21592141                /* Touch the run flag to start the audio queue as soon as
     
    22882270static DECLCALLBACK(PDMAUDIOBACKENDSTS) drvHostCoreAudioGetStatus(PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir)
    22892271{
    2290     RT_NOREF(enmDir);
     2272    RT_NOREF(pInterface, enmDir);
    22912273    AssertPtrReturn(pInterface, PDMAUDIOBACKENDSTS_UNKNOWN);
    22922274
     
    22982280 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate}
    22992281 */
    2300 static DECLCALLBACK(int) drvHostCoreAudioStreamCreate(PPDMIHOSTAUDIO pInterface,
    2301                                                       PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     2282static DECLCALLBACK(int) drvHostCoreAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
     2283                                                      PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    23022284{
    23032285    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     
    23062288    AssertPtrReturn(pCfgAcq,    VERR_INVALID_POINTER);
    23072289
    2308     PDRVHOSTCOREAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTCOREAUDIO(pInterface);
    2309 
    2310     Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST);
    2311 
    2312     PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream;
     2290    PDRVHOSTCOREAUDIO pThis     = PDMIHOSTAUDIO_2_DRVHOSTCOREAUDIO(pInterface);
     2291    PCOREAUDIOSTREAM  pCAStream = (PCOREAUDIOSTREAM)pStream;
    23132292
    23142293    int rc = RTCritSectInit(&pCAStream->CritSect);
     
    23442323            if (RT_SUCCESS(rc))
    23452324            {
    2346                 pCfgAcq->cSampleBufferSize = _4K; /** @todo FIX THIS !!! */
     2325                pCfgAcq->cSampleBufferHint = _4K; /** @todo FIX THIS !!! */
    23472326            }
    23482327            if (RT_SUCCESS(rc))
     
    23722351 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy}
    23732352 */
    2374 static DECLCALLBACK(int) drvHostCoreAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     2353static DECLCALLBACK(int) drvHostCoreAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    23752354{
    23762355    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     
    23782357
    23792358    PDRVHOSTCOREAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTCOREAUDIO(pInterface);
    2380 
    2381     Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST);
    23822359
    23832360    PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream;
     
    23942371    }
    23952372
     2373    if (!pCAStream->pCfg) /* Not (yet) configured? Skip. */
     2374        return VINF_SUCCESS;
     2375
    23962376    int rc = coreAudioStreamControl(pThis, pCAStream, PDMAUDIOSTREAMCMD_DISABLE);
    23972377    if (RT_SUCCESS(rc))
     
    24202400 */
    24212401static DECLCALLBACK(int) drvHostCoreAudioStreamControl(PPDMIHOSTAUDIO pInterface,
    2422                                                        PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
     2402                                                       PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
    24232403{
    24242404    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    24252405    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    24262406
    2427     PDRVHOSTCOREAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTCOREAUDIO(pInterface);
    2428 
    2429     Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST);
    2430 
     2407    PDRVHOSTCOREAUDIO pThis    = PDMIHOSTAUDIO_2_DRVHOSTCOREAUDIO(pInterface);
    24312408    PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream;
    24322409
     
    24382415 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
    24392416 */
    2440 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostCoreAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     2417static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostCoreAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    24412418{
    24422419    RT_NOREF(pInterface);
    24432420    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    24442421
    2445     Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST);
     2422    PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream;
    24462423
    24472424    PDMAUDIOSTRMSTS strmSts = PDMAUDIOSTRMSTS_FLAG_NONE;
    24482425
    2449     PCOREAUDIOSTREAM pCAStream = (PCOREAUDIOSTREAM)pStream;
     2426    if (!pCAStream->pCfg) /* Not (yet) configured? Skip. */
     2427        return strmSts;
    24502428
    24512429    if (ASMAtomicReadU32(&pCAStream->enmStatus) == COREAUDIOSTATUS_INIT)
    24522430        strmSts |= PDMAUDIOSTRMSTS_FLAG_INITIALIZED | PDMAUDIOSTRMSTS_FLAG_ENABLED;
    24532431
    2454     if (pStream->enmDir == PDMAUDIODIR_IN)
     2432    if (pCAStream->pCfg->enmDir == PDMAUDIODIR_IN)
    24552433    {
    24562434        if (strmSts & PDMAUDIOSTRMSTS_FLAG_ENABLED)
    24572435            strmSts |= PDMAUDIOSTRMSTS_FLAG_DATA_READABLE;
    24582436    }
    2459     else if (pStream->enmDir == PDMAUDIODIR_OUT)
     2437    else if (pCAStream->pCfg->enmDir == PDMAUDIODIR_OUT)
    24602438    {
    24612439        if (strmSts & PDMAUDIOSTRMSTS_FLAG_ENABLED)
     
    24722450 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate}
    24732451 */
    2474 static DECLCALLBACK(int) drvHostCoreAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     2452static DECLCALLBACK(int) drvHostCoreAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    24752453{
    24762454    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    24772455    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
     2456
     2457    RT_NOREF(pInterface, pStream);
    24782458
    24792459    /* Nothing to do here for Core Audio. */
  • trunk/src/VBox/Devices/Audio/DrvHostDSound.cpp

    r65568 r65624  
    55
    66/*
    7  * Copyright (C) 2006-2016 Oracle Corporation
     7 * Copyright (C) 2006-2017 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    104104} DSOUNDHOSTCFG, *PDSOUNDHOSTCFG;
    105105
    106 typedef struct DSOUNDSTREAMOUT
    107 {
    108     /** Note: Always must come first! */
    109     PDMAUDIOSTREAM       Stream;
    110     /** The PCM properties of this stream. */
    111     PDMAUDIOPCMPROPS     Props;
    112     LPDIRECTSOUND8       pDS;     /** @todo Move this out of this structure! Not required per-stream (e.g. for multi-channel). */
    113     LPDIRECTSOUNDBUFFER8 pDSB;
    114     DWORD                offPlayWritePos;
    115     DWORD                cbPlayBuf;
    116     bool                 fEnabled;
    117     bool                 fRestartPlayback;
    118     PDMAUDIOSTREAMCFG    streamCfg;
    119 } DSOUNDSTREAMOUT, *PDSOUNDSTREAMOUT;
    120 
    121 typedef struct DSOUNDSTREAMIN
    122 {
    123     /** Associated host input stream. */
    124     PDMAUDIOSTREAM              Stream;
    125     /** The PCM properties of this stream. */
    126     PDMAUDIOPCMPROPS            Props;
    127     LPDIRECTSOUNDCAPTURE8       pDSC;
    128     LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB;
    129     DWORD                       offCaptureBufRead;
    130     DWORD                       cbCaptureBuf;
    131     HRESULT                     hrLastCapture;
    132     PDMAUDIORECSOURCE           enmRecSource;
    133     bool                        fEnabled;
    134     PDMAUDIOSTREAMCFG           streamCfg;
    135 } DSOUNDSTREAMIN, *PDSOUNDSTREAMIN;
     106typedef struct DSOUNDSTREAM
     107{
     108    /** The stream's acquired configuration. */
     109    PPDMAUDIOSTREAMCFG pCfg;
     110    /** Buffer alignment. */
     111    uint8_t            uAlign;
     112    union
     113    {
     114        struct
     115        {
     116            LPDIRECTSOUNDCAPTURE8       pDSC;
     117            LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB;
     118            DWORD                       offCaptureBufRead;
     119            DWORD                       cbCaptureBuf;
     120            HRESULT                     hrLastCapture;
     121            bool                        fEnabled;
     122        } In;
     123        struct
     124        {
     125            LPDIRECTSOUND8              pDS;     /** @todo Move this out of this structure! Not required per-stream (e.g. for multi-channel). */
     126            LPDIRECTSOUNDBUFFER8        pDSB;
     127            DWORD                       offPlayWritePos;
     128            DWORD                       cbPlayBuf;
     129            bool                        fEnabled;
     130            bool                        fRestartPlayback;
     131        } Out;
     132    };
     133} DSOUNDSTREAM, *PDSOUNDSTREAM;
    136134
    137135typedef struct DRVHOSTDSOUND
     
    166164    uint8_t             cEvents;
    167165    /** Pointer to the input stream. */
    168     PDSOUNDSTREAMIN     pDSStrmIn;
     166    PDSOUNDSTREAM       pDSStrmIn;
    169167    /** Pointer to the output stream. */
    170     PDSOUNDSTREAMOUT    pDSStrmOut;
     168    PDSOUNDSTREAM       pDSStrmOut;
    171169#endif
    172170} DRVHOSTDSOUND, *PDRVHOSTDSOUND;
     
    226224
    227225    pFmt->wFormatTag      = WAVE_FORMAT_PCM;
    228     pFmt->nChannels       = pCfg->cChannels;
    229     pFmt->nSamplesPerSec  = pCfg->uHz;
    230     pFmt->nAvgBytesPerSec = pCfg->uHz << (pCfg->cChannels == 2 ? 1: 0);
    231     pFmt->nBlockAlign     = 1 << (pCfg->cChannels == 2 ? 1: 0);
     226    pFmt->nChannels       = pCfg->Props.cChannels;
     227    pFmt->nSamplesPerSec  = pCfg->Props.uHz;
     228    pFmt->nAvgBytesPerSec = pCfg->Props.uHz << (pCfg->Props.cChannels == 2 ? 1: 0);
     229    pFmt->nBlockAlign     = 1 << (pCfg->Props.cChannels == 2 ? 1 : 0);
    232230    pFmt->cbSize          = 0; /* No extra data specified. */
    233231
    234     switch (pCfg->enmFormat)
    235     {
    236         case PDMAUDIOFMT_S8:
    237         case PDMAUDIOFMT_U8:
     232    switch (pCfg->Props.cBits)
     233    {
     234        case 8:
    238235            pFmt->wBitsPerSample = 8;
    239236            break;
    240237
    241         case PDMAUDIOFMT_S16:
    242         case PDMAUDIOFMT_U16:
     238        case 16:
    243239            pFmt->wBitsPerSample = 16;
    244240            pFmt->nAvgBytesPerSec <<= 1;
     
    246242            break;
    247243
    248         case PDMAUDIOFMT_S32:
    249         case PDMAUDIOFMT_U32:
     244        case 32:
    250245            pFmt->wBitsPerSample = 32;
    251246            pFmt->nAvgBytesPerSec <<= 2;
     
    254249
    255250        default:
    256             AssertMsgFailed(("Wave format %d not supported\n", pCfg->enmFormat));
     251            AssertMsgFailed(("Wave format for %RU8 bits not supported\n", pCfg->Props.cBits));
    257252            return VERR_NOT_SUPPORTED;
    258253    }
     
    262257
    263258
    264 static int dsoundGetPosOut(PDRVHOSTDSOUND   pThis,
    265                            PDSOUNDSTREAMOUT pDSoundStream, DWORD *pdwBuffer, DWORD *pdwFree, DWORD *pdwPlayPos)
     259static int dsoundGetPosOut(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS,
     260                           DWORD *pdwBuffer, DWORD *pdwFree, DWORD *pdwPlayPos)
    266261{
    267262    AssertPtr(pThis);
    268     AssertPtrReturn(pDSoundStream, VERR_INVALID_POINTER);
     263    AssertPtrReturn(pStreamDS, VERR_INVALID_POINTER);
    269264    AssertPtrNull(pdwBuffer);
    270265    AssertPtrNull(pdwFree);
    271266    AssertPtrNull(pdwPlayPos);
    272267
    273     LPDIRECTSOUNDBUFFER8 pDSB = pDSoundStream->pDSB;
     268    LPDIRECTSOUNDBUFFER8 pDSB = pStreamDS->Out.pDSB;
    274269    if (!pDSB)
    275270        return VERR_INVALID_POINTER;
     
    283278        if (SUCCEEDED(hr))
    284279        {
    285             DWORD const cbBuffer = pDSoundStream->cbPlayBuf;
     280            DWORD const cbBuffer = pStreamDS->Out.cbPlayBuf;
    286281            if (pdwBuffer)
    287282                *pdwBuffer  = cbBuffer;
    288283            if (pdwFree)
    289                 *pdwFree    = cbBuffer - dsoundRingDistance(pDSoundStream->offPlayWritePos, cbPlayPos, cbBuffer);
     284                *pdwFree    = cbBuffer - dsoundRingDistance(pStreamDS->Out.offPlayWritePos, cbPlayPos, cbBuffer);
    290285            if (pdwPlayPos)
    291286                *pdwPlayPos = cbPlayPos;
     
    385380
    386381
    387 static HRESULT directSoundPlayLock(PDRVHOSTDSOUND pThis,
    388                                    LPDIRECTSOUNDBUFFER8 pDSB, PPDMAUDIOPCMPROPS pProps,
     382static HRESULT directSoundPlayLock(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS,
    389383                                   DWORD dwOffset, DWORD dwBytes,
    390384                                   PVOID *ppv1, PVOID *ppv2,
     
    398392        *ppv1 = *ppv2 = NULL;
    399393        *pcb1 = *pcb2 = 0;
    400         hr = IDirectSoundBuffer8_Lock(pDSB, dwOffset, dwBytes, ppv1, pcb1, ppv2, pcb2, dwFlags);
     394        hr = IDirectSoundBuffer8_Lock(pStreamDS->Out.pDSB, dwOffset, dwBytes, ppv1, pcb1, ppv2, pcb2, dwFlags);
    401395        if (SUCCEEDED(hr))
    402396        {
    403             if (   (!*ppv1 || !(*pcb1 & pProps->uAlign))
    404                 && (!*ppv2 || !(*pcb2 & pProps->uAlign)) )
     397            if (   (!*ppv1 || !(*pcb1 & pStreamDS->uAlign))
     398                && (!*ppv2 || !(*pcb2 & pStreamDS->uAlign)) )
    405399                return S_OK;
    406400            DSLOGREL(("DSound: Locking playback buffer returned misaligned buffer: cb1=%#RX32, cb2=%#RX32 (alignment: %#RX32)\n",
    407                       *pcb1, *pcb2, pProps->uAlign));
    408             directSoundPlayUnlock(pThis, pDSB, *ppv1, *ppv2, *pcb1, *pcb2);
     401                      *pcb1, *pcb2, pStreamDS->uAlign));
     402            directSoundPlayUnlock(pThis, pStreamDS->uAlign, *ppv1, *ppv2, *pcb1, *pcb2);
    409403            return E_FAIL;
    410404        }
     
    414408
    415409        LogFlowFunc(("Locking failed due to lost buffer, restoring ...\n"));
    416         directSoundPlayRestore(pThis, pDSB);
     410        directSoundPlayRestore(pThis, pStreamDS->Out.pDSB);
    417411    }
    418412
     
    422416
    423417
    424 static HRESULT directSoundCaptureLock(LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB, PPDMAUDIOPCMPROPS pProps,
     418static HRESULT directSoundCaptureLock(PDSOUNDSTREAM pStreamDS,
    425419                                      DWORD dwOffset, DWORD dwBytes,
    426420                                      PVOID *ppv1, PVOID *ppv2,
     
    433427    DWORD cb2 = 0;
    434428
    435     HRESULT hr = IDirectSoundCaptureBuffer8_Lock(pDSCB, dwOffset, dwBytes,
     429    HRESULT hr = IDirectSoundCaptureBuffer8_Lock(pStreamDS->In.pDSCB, dwOffset, dwBytes,
    436430                                                 &pv1, &cb1, &pv2, &cb2, dwFlags);
    437431    if (FAILED(hr))
     
    441435    }
    442436
    443     if (   (pv1 && (cb1 & pProps->uAlign))
    444         || (pv2 && (cb2 & pProps->uAlign)))
     437    if (   (pv1 && (cb1 & pStreamDS->uAlign))
     438        || (pv2 && (cb2 & pStreamDS->uAlign)))
    445439    {
    446440        DSLOGREL(("DSound: Locking capture buffer returned misaligned buffer: cb1=%RI32, cb2=%RI32 (alignment: %RU32)\n",
    447                   cb1, cb2, pProps->uAlign));
    448         directSoundCaptureUnlock(pDSCB, pv1, pv2, cb1, cb2);
     441                  cb1, cb2, pStreamDS->uAlign));
     442        directSoundCaptureUnlock(pStreamDS->In.pDSCB, pv1, pv2, cb1, cb2);
    449443        return E_FAIL;
    450444    }
     
    463457 */
    464458
    465 static void directSoundPlayInterfaceRelease(PDSOUNDSTREAMOUT pDSoundStream)
    466 {
    467     if (pDSoundStream->pDS)
    468     {
    469         IDirectSound8_Release(pDSoundStream->pDS);
    470         pDSoundStream->pDS = NULL;
    471     }
    472 }
    473 
    474 
    475 static HRESULT directSoundPlayInterfaceCreate(PDRVHOSTDSOUND pThis, PDSOUNDSTREAMOUT pDSoundStream)
    476 {
    477     if (pDSoundStream->pDS != NULL)
     459static void directSoundPlayInterfaceRelease(PDSOUNDSTREAM pStreamDS)
     460{
     461    if (pStreamDS->Out.pDS)
     462    {
     463        IDirectSound8_Release(pStreamDS->Out.pDS);
     464        pStreamDS->Out.pDS = NULL;
     465    }
     466}
     467
     468
     469static HRESULT directSoundPlayInterfaceCreate(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS)
     470{
     471    if (pStreamDS->Out.pDS != NULL)
    478472    {
    479473        DSLOG(("DSound: DirectSound instance already exists\n"));
     
    482476
    483477    HRESULT hr = CoCreateInstance(CLSID_DirectSound8, NULL, CLSCTX_ALL,
    484                                   IID_IDirectSound8, (void **)&pDSoundStream->pDS);
     478                                  IID_IDirectSound8, (void **)&pStreamDS->Out.pDS);
    485479    if (FAILED(hr))
    486480    {
     
    489483    else
    490484    {
    491         hr = IDirectSound8_Initialize(pDSoundStream->pDS, pThis->cfg.pGuidPlay);
     485        hr = IDirectSound8_Initialize(pStreamDS->Out.pDS, pThis->cfg.pGuidPlay);
    492486        if (SUCCEEDED(hr))
    493487        {
    494488            HWND hWnd = GetDesktopWindow();
    495             hr = IDirectSound8_SetCooperativeLevel(pDSoundStream->pDS, hWnd, DSSCL_PRIORITY);
     489            hr = IDirectSound8_SetCooperativeLevel(pStreamDS->Out.pDS, hWnd, DSSCL_PRIORITY);
    496490            if (FAILED(hr))
    497491                DSLOGREL(("DSound: Setting cooperative level for window %p failed with %Rhrc\n", hWnd, hr));
     
    505499                DSLOGREL(("DSound: DirectSound playback initialization failed with %Rhrc\n", hr));
    506500
    507             directSoundPlayInterfaceRelease(pDSoundStream);
     501            directSoundPlayInterfaceRelease(pStreamDS);
    508502        }
    509503    }
     
    513507
    514508
    515 static HRESULT directSoundPlayClose(PDRVHOSTDSOUND pThis, PDSOUNDSTREAMOUT pDSoundStream)
     509static HRESULT directSoundPlayClose(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS)
    516510{
    517511    AssertPtrReturn(pThis, E_POINTER);
    518     AssertPtrReturn(pDSoundStream, E_POINTER);
    519 
    520     DSLOG(("DSound: Closing playback stream %p, buffer %p\n", pDSoundStream, pDSoundStream->pDSB));
     512    AssertPtrReturn(pStreamDS, E_POINTER);
     513
     514    DSLOG(("DSound: Closing playback stream %p, buffer %p\n", pStreamDS, pStreamDS->Out.pDSB));
    521515
    522516    HRESULT hr = S_OK;
    523517
    524     if (pDSoundStream->pDSB)
    525     {
    526         hr = IDirectSoundBuffer8_Stop(pDSoundStream->pDSB);
     518    if (pStreamDS->Out.pDSB)
     519    {
     520        hr = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB);
    527521        if (SUCCEEDED(hr))
    528522        {
     
    536530                    pThis->cEvents--;
    537531
    538                 pThis->pDSStream = NULL;
     532                pThis->pDSStrmOut = NULL;
    539533            }
    540534
     
    542536            AssertRC(rc2);
    543537#endif
    544             IDirectSoundBuffer8_Release(pDSoundStream->pDSB);
    545             pDSoundStream->pDSB = NULL;
     538            IDirectSoundBuffer8_Release(pStreamDS->Out.pDSB);
     539            pStreamDS->Out.pDSB = NULL;
    546540        }
    547541        else
    548             DSLOGREL(("DSound: Stop playback stream %p when closing %Rhrc\n", pDSoundStream, hr));
     542            DSLOGREL(("DSound: Stop playback stream %p when closing %Rhrc\n", pStreamDS, hr));
    549543    }
    550544
    551545    if (SUCCEEDED(hr))
    552         directSoundPlayInterfaceRelease(pDSoundStream);
     546        directSoundPlayInterfaceRelease(pStreamDS);
    553547
    554548    return hr;
     
    556550
    557551
    558 static HRESULT directSoundPlayOpen(PDRVHOSTDSOUND pThis, PDSOUNDSTREAMOUT pDSoundStream)
    559 {
    560     AssertPtrReturn(pThis,         E_POINTER);
    561     AssertPtrReturn(pDSoundStream, E_POINTER);
    562 
    563     DSLOG(("DSound: pDSoundStream=%p, cbBufferOut=%RU32, uHz=%RU32, cChannels=%RU8, cBits=%RU8, fSigned=%RTbool\n",
    564            pDSoundStream,
    565            pThis->cfg.cbBufferOut,
    566            pDSoundStream->Props.uHz,
    567            pDSoundStream->Props.cChannels,
    568            pDSoundStream->Props.cBits,
    569            pDSoundStream->Props.fSigned));
    570 
    571     if (pDSoundStream->pDSB != NULL)
     552static HRESULT directSoundPlayOpen(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS,
     553                                   PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     554{
     555    AssertPtrReturn(pThis,     E_POINTER);
     556    AssertPtrReturn(pStreamDS, E_POINTER);
     557    AssertPtrReturn(pCfgReq,   E_POINTER);
     558    AssertPtrReturn(pCfgAcq,   E_POINTER);
     559
     560    DSLOG(("DSound: pStreamDS=%p, cbBufferOut=%RU32, uHz=%RU32, cChannels=%RU8, cBits=%RU8, fSigned=%RTbool\n",
     561           pStreamDS, pThis->cfg.cbBufferOut,
     562           pCfgReq->Props.uHz,
     563           pCfgReq->Props.cChannels,
     564           pCfgReq->Props.cBits,
     565           pCfgReq->Props.fSigned));
     566
     567    if (pStreamDS->Out.pDSB != NULL)
    572568    {
    573569        /* Should not happen but be forgiving. */
    574570        DSLOGREL(("DSound: Playback buffer already exists\n"));
    575         directSoundPlayClose(pThis, pDSoundStream);
     571        directSoundPlayClose(pThis, pStreamDS);
    576572    }
    577573
    578574    WAVEFORMATEX wfx;
    579     int rc = dsoundWaveFmtFromCfg(&pDSoundStream->streamCfg, &wfx);
     575    int rc = dsoundWaveFmtFromCfg(pCfgReq, &wfx);
    580576    if (RT_FAILURE(rc))
    581577        return E_INVALIDARG;
    582578
    583     HRESULT hr = directSoundPlayInterfaceCreate(pThis, pDSoundStream);
     579    HRESULT hr = directSoundPlayInterfaceCreate(pThis, pStreamDS);
    584580    if (FAILED(hr))
    585581        return hr;
     
    611607        bd.dwBufferBytes = pThis->cfg.cbBufferOut;
    612608
    613         hr = IDirectSound8_CreateSoundBuffer(pDSoundStream->pDS, &bd, &pDSB, NULL);
     609        hr = IDirectSound8_CreateSoundBuffer(pStreamDS->Out.pDS, &bd, &pDSB, NULL);
    614610        if (FAILED(hr))
    615611        {
     
    619615
    620616        /* "Upgrade" to IDirectSoundBuffer8 interface. */
    621         hr = IDirectSoundBuffer_QueryInterface(pDSB, IID_IDirectSoundBuffer8, (PVOID *)&pDSoundStream->pDSB);
     617        hr = IDirectSoundBuffer_QueryInterface(pDSB, IID_IDirectSoundBuffer8, (PVOID *)&pStreamDS->Out.pDSB);
    622618        IDirectSoundBuffer_Release(pDSB);
    623619        if (FAILED(hr))
     
    630626         * Query the actual parameters.
    631627         */
    632         hr = IDirectSoundBuffer8_GetFormat(pDSoundStream->pDSB, &wfx, sizeof(wfx), NULL);
     628        hr = IDirectSoundBuffer8_GetFormat(pStreamDS->Out.pDSB, &wfx, sizeof(wfx), NULL);
    633629        if (FAILED(hr))
    634630        {
     
    640636        RT_ZERO(bc);
    641637        bc.dwSize = sizeof(bc);
    642         hr = IDirectSoundBuffer8_GetCaps(pDSoundStream->pDSB, &bc);
     638        hr = IDirectSoundBuffer8_GetCaps(pStreamDS->Out.pDSB, &bc);
    643639        if (FAILED(hr))
    644640        {
     
    667663               wfx.cbSize));
    668664
    669         if (bc.dwBufferBytes & pDSoundStream->Props.uAlign)
     665        if (bc.dwBufferBytes & pStreamDS->uAlign)
    670666            DSLOGREL(("DSound: Playback capabilities returned misaligned buffer: size %RU32, alignment %RU32\n",
    671                       bc.dwBufferBytes, pDSoundStream->Props.uAlign + 1));
     667                      bc.dwBufferBytes, pStreamDS->uAlign + 1));
    672668
    673669        if (bc.dwBufferBytes != pThis->cfg.cbBufferOut)
     
    680676         * playback buffer position.
    681677         */
    682         pDSoundStream->cbPlayBuf = bc.dwBufferBytes;
    683         DSLOG(("DSound: cMaxSamplesInBuffer=%RU32\n", pDSoundStream->cbPlayBuf));
     678        pStreamDS->Out.cbPlayBuf = bc.dwBufferBytes;
     679        DSLOG(("DSound: cMaxSamplesInBuffer=%RU32\n", pStreamDS->Out.cbPlayBuf));
    684680
    685681#ifdef VBOX_WITH_AUDIO_DEVICE_CALLBACKS
     
    698694
    699695        LPDIRECTSOUNDNOTIFY8 pNotify;
    700         hr = IDirectSoundNotify_QueryInterface(pDSoundStream->pDSB, IID_IDirectSoundNotify8, (PVOID *)&pNotify);
     696        hr = IDirectSoundNotify_QueryInterface(pStreamDS->Out.pDSB, IID_IDirectSoundNotify8, (PVOID *)&pNotify);
    701697        if (SUCCEEDED(hr))
    702698        {
     
    718714            break;
    719715
    720         pThis->pDSStreamOut = pDSoundStream;
     716        pThis->pDSStrmOut = pStreamDS;
    721717
    722718        Assert(pThis->cEvents < VBOX_DSOUND_MAX_EVENTS);
     
    727723
    728724        /* Trigger the just installed output notification. */
    729         hr = IDirectSoundBuffer8_Play(pDSoundStream->pDSB, 0, 0, 0);
     725        hr = IDirectSoundBuffer8_Play(pStreamDS->Out.pDSB, 0, 0, 0);
     726        if (FAILED(hr))
     727            break;
    730728
    731729#endif /* VBOX_WITH_AUDIO_DEVICE_CALLBACKS */
    732730
     731        pCfgAcq->cSampleBufferHint = PDMAUDIOSTREAMCFG_B2S(pCfgAcq, pThis->cfg.cbBufferOut);
     732
    733733    } while (0);
    734734
    735735    if (FAILED(hr))
    736         directSoundPlayClose(pThis, pDSoundStream);
     736        directSoundPlayClose(pThis, pStreamDS);
    737737
    738738    return hr;
     
    740740
    741741
    742 static void dsoundPlayClearSamples(PDRVHOSTDSOUND pThis, PDSOUNDSTREAMOUT pDSoundStream)
    743 {
    744     AssertPtrReturnVoid(pDSoundStream);
     742static void dsoundPlayClearSamples(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS)
     743{
     744    AssertPtrReturnVoid(pStreamDS);
     745
     746    AssertPtr(pStreamDS->pCfg);
     747    PPDMAUDIOPCMPROPS pProps = &pStreamDS->pCfg->Props;
    745748
    746749    PVOID pv1, pv2;
    747750    DWORD cb1, cb2;
    748     HRESULT hr = directSoundPlayLock(pThis, pDSoundStream->pDSB, &pDSoundStream->Props,
    749                                      0 /* dwOffset */, pDSoundStream->cbPlayBuf,
     751    HRESULT hr = directSoundPlayLock(pThis, pStreamDS,
     752                                     0 /* dwOffset */, pStreamDS->Out.cbPlayBuf,
    750753                                     &pv1, &pv2, &cb1, &cb2, DSBLOCK_ENTIREBUFFER);
    751754    if (SUCCEEDED(hr))
    752755    {
    753         DWORD len1 = PDMAUDIOPCMPROPS_B2S(&pDSoundStream->Props, cb1);
    754         DWORD len2 = PDMAUDIOPCMPROPS_B2S(&pDSoundStream->Props, cb2);
     756        DWORD len1 = PDMAUDIOPCMPROPS_B2S(pProps, cb1);
     757        DWORD len2 = PDMAUDIOPCMPROPS_B2S(pProps, cb2);
    755758
    756759        if (pv1 && len1)
    757             DrvAudioHlpClearBuf(&pDSoundStream->Props, pv1, cb1, len1);
     760            DrvAudioHlpClearBuf(pProps, pv1, cb1, len1);
    758761
    759762        if (pv2 && len2)
    760             DrvAudioHlpClearBuf(&pDSoundStream->Props, pv2, cb2, len2);
    761 
    762         directSoundPlayUnlock(pThis, pDSoundStream->pDSB, pv1, pv2, cb1, cb2);
     763            DrvAudioHlpClearBuf(pProps, pv2, cb2, len2);
     764
     765        directSoundPlayUnlock(pThis, pStreamDS->Out.pDSB, pv1, pv2, cb1, cb2);
    763766    }
    764767}
     
    799802
    800803
    801 static HRESULT directSoundPlayStop(PDRVHOSTDSOUND pThis, PDSOUNDSTREAMOUT pDSoundStream)
    802 {
    803     AssertPtrReturn(pThis,         E_POINTER);
    804     AssertPtrReturn(pDSoundStream, E_POINTER);
     804static HRESULT directSoundPlayStop(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS)
     805{
     806    AssertPtrReturn(pThis,     E_POINTER);
     807    AssertPtrReturn(pStreamDS, E_POINTER);
    805808
    806809    HRESULT hr;
    807810
    808     if (pDSoundStream->pDSB != NULL)
     811    if (pStreamDS->Out.pDSB != NULL)
    809812    {
    810813        DSLOG(("DSound: Stopping playback\n"));
    811814
    812         HRESULT hr2 = IDirectSoundBuffer8_Stop(pDSoundStream->pDSB);
     815        HRESULT hr2 = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB);
    813816        if (FAILED(hr2))
    814817        {
    815             hr2 = directSoundPlayRestore(pThis, pDSoundStream->pDSB);
     818            hr2 = directSoundPlayRestore(pThis, pStreamDS->Out.pDSB);
    816819            if (FAILED(hr2))
    817                 hr2 = IDirectSoundBuffer8_Stop(pDSoundStream->pDSB);
     820                hr2 = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB);
    818821        }
    819822
     
    828831    if (SUCCEEDED(hr))
    829832    {
    830         dsoundPlayClearSamples(pThis, pDSoundStream);
    831         pDSoundStream->fEnabled = false;
     833        dsoundPlayClearSamples(pThis, pStreamDS);
     834        pStreamDS->Out.fEnabled = false;
    832835    }
    833836    else
     
    838841
    839842
    840 static HRESULT directSoundPlayStart(PDRVHOSTDSOUND pThis, PDSOUNDSTREAMOUT pDSoundStream)
     843static HRESULT directSoundPlayStart(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS)
    841844{
    842845    AssertPtrReturn(pThis,         E_POINTER);
    843     AssertPtrReturn(pDSoundStream, E_POINTER);
     846    AssertPtrReturn(pStreamDS, E_POINTER);
    844847
    845848    HRESULT hr;
    846     if (pDSoundStream->pDSB != NULL)
     849    if (pStreamDS->Out.pDSB != NULL)
    847850    {
    848851        DWORD dwStatus;
    849         hr = directSoundPlayGetStatus(pThis, pDSoundStream->pDSB, &dwStatus);
     852        hr = directSoundPlayGetStatus(pThis, pStreamDS->Out.pDSB, &dwStatus);
    850853        if (SUCCEEDED(hr))
    851854        {
     
    856859            else
    857860            {
    858                 dsoundPlayClearSamples(pThis, pDSoundStream);
    859 
    860                 pDSoundStream->fRestartPlayback = true;
    861                 pDSoundStream->fEnabled         = true;
     861                dsoundPlayClearSamples(pThis, pStreamDS);
     862
     863                pStreamDS->Out.fRestartPlayback = true;
     864                pStreamDS->Out.fEnabled         = true;
    862865
    863866                DSLOG(("DSound: Playback started\n"));
     
    883886 */
    884887
    885 static LPCGUID dsoundCaptureSelectDevice(PDRVHOSTDSOUND pThis, PDSOUNDSTREAMIN pDSoundStream)
    886 {
    887     AssertPtrReturn(pThis, NULL);
    888     AssertPtrReturn(pDSoundStream, NULL);
     888static LPCGUID dsoundCaptureSelectDevice(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS)
     889{
     890    AssertPtrReturn(pThis,     NULL);
     891    AssertPtrReturn(pStreamDS, NULL);
    889892
    890893    int rc = VINF_SUCCESS;
     
    895898        PDSOUNDDEV pDev = NULL;
    896899
    897         switch (pDSoundStream->enmRecSource)
     900        switch (pStreamDS->pCfg->DestSource.Source)
    898901        {
    899902            case PDMAUDIORECSOURCE_LINE:
     
    909912                RTListForEach(&pThis->lstDevInput, pDev, DSOUNDDEV, Node)
    910913                {
    911                     if (RTStrIStr(pDev->pszName, "Mic")) /** @todo what is with non en_us windows versions? */
     914                    if (RTStrIStr(pDev->pszName, "Mic")) /** @todo What is with non en_us windows versions? */
    912915                        break;
    913916                }
     
    928931        {
    929932            DSLOG(("DSound: Guest source '%s' is using host recording device '%s'\n",
    930                    DrvAudioHlpRecSrcToStr(pDSoundStream->enmRecSource), pDev->pszName));
     933                   DrvAudioHlpRecSrcToStr(pStreamDS->pCfg->DestSource.Source), pDev->pszName));
    931934
    932935            pGUID = &pDev->Guid;
     
    944947    /* This always has to be in the release log. */
    945948    LogRel(("DSound: Guest source '%s' is using host recording device with GUID '%s'\n",
    946             DrvAudioHlpRecSrcToStr(pDSoundStream->enmRecSource), pszGUID ? pszGUID: "{?}"));
     949            DrvAudioHlpRecSrcToStr(pStreamDS->pCfg->DestSource.Source), pszGUID ? pszGUID: "{?}"));
    947950
    948951    if (pszGUID)
     
    956959
    957960
    958 static void directSoundCaptureInterfaceRelease(PDSOUNDSTREAMIN pDSoundStream)
    959 {
    960     if (pDSoundStream->pDSC)
     961static void directSoundCaptureInterfaceRelease(PDSOUNDSTREAM pStreamDS)
     962{
     963    if (pStreamDS->In.pDSC)
    961964    {
    962965        LogFlowFuncEnter();
    963         IDirectSoundCapture_Release(pDSoundStream->pDSC);
    964         pDSoundStream->pDSC = NULL;
    965     }
    966 }
    967 
    968 
    969 static HRESULT directSoundCaptureInterfaceCreate(PDRVHOSTDSOUND pThis, PDSOUNDSTREAMIN pDSoundStream)
    970 {
    971     if (pDSoundStream->pDSC != NULL)
     966        IDirectSoundCapture_Release(pStreamDS->In.pDSC);
     967        pStreamDS->In.pDSC = NULL;
     968    }
     969}
     970
     971
     972static HRESULT directSoundCaptureInterfaceCreate(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS)
     973{
     974    if (pStreamDS->In.pDSC != NULL)
    972975    {
    973976        DSLOG(("DSound: DirectSoundCapture instance already exists\n"));
     
    976979
    977980    HRESULT hr = CoCreateInstance(CLSID_DirectSoundCapture8, NULL, CLSCTX_ALL,
    978                                   IID_IDirectSoundCapture8, (void **)&pDSoundStream->pDSC);
     981                                  IID_IDirectSoundCapture8, (void **)&pStreamDS->In.pDSC);
    979982    if (FAILED(hr))
    980983    {
     
    983986    else
    984987    {
    985         LPCGUID pGUID = dsoundCaptureSelectDevice(pThis, pDSoundStream);
    986         hr = IDirectSoundCapture_Initialize(pDSoundStream->pDSC, pGUID);
     988        LPCGUID pGUID = dsoundCaptureSelectDevice(pThis, pStreamDS);
     989        hr = IDirectSoundCapture_Initialize(pStreamDS->In.pDSC, pGUID);
    987990        if (FAILED(hr))
    988991        {
     
    992995                DSLOGREL(("DSound: Initializing capturing device failed with %Rhrc\n", hr));
    993996
    994             directSoundCaptureInterfaceRelease(pDSoundStream);
     997            directSoundCaptureInterfaceRelease(pStreamDS);
    995998        }
    996999    }
     
    10011004
    10021005
    1003 static HRESULT directSoundCaptureClose(PDSOUNDSTREAMIN pDSoundStream)
    1004 {
    1005     AssertPtrReturn(pDSoundStream, E_POINTER);
    1006 
    1007     DSLOG(("DSound: pDSoundStream=%p, pDSCB=%p\n", pDSoundStream, pDSoundStream->pDSCB));
     1006static HRESULT directSoundCaptureClose(PDSOUNDSTREAM pStreamDS)
     1007{
     1008    AssertPtrReturn(pStreamDS, E_POINTER);
     1009
     1010    DSLOG(("DSound: pStreamDS=%p, pDSCB=%p\n", pStreamDS, pStreamDS->In.pDSCB));
    10081011
    10091012    HRESULT hr = S_OK;
    10101013
    1011     if (pDSoundStream->pDSCB)
    1012     {
    1013         hr = IDirectSoundCaptureBuffer_Stop(pDSoundStream->pDSCB);
     1014    if (pStreamDS->In.pDSCB)
     1015    {
     1016        hr = IDirectSoundCaptureBuffer_Stop(pStreamDS->In.pDSCB);
    10141017        if (SUCCEEDED(hr))
    10151018        {
    1016             IDirectSoundCaptureBuffer8_Release(pDSoundStream->pDSCB);
    1017             pDSoundStream->pDSCB = NULL;
     1019            IDirectSoundCaptureBuffer8_Release(pStreamDS->In.pDSCB);
     1020            pStreamDS->In.pDSCB = NULL;
    10181021        }
    10191022        else
     
    10221025
    10231026    if (SUCCEEDED(hr))
    1024         directSoundCaptureInterfaceRelease(pDSoundStream);
     1027        directSoundCaptureInterfaceRelease(pStreamDS);
    10251028
    10261029    LogFlowFunc(("Returning %Rhrc\n", hr));
     
    10291032
    10301033
    1031 static HRESULT directSoundCaptureOpen(PDRVHOSTDSOUND pThis, PDSOUNDSTREAMIN pDSoundStream)
    1032 {
    1033     AssertPtrReturn(pThis, E_POINTER);
    1034     AssertPtrReturn(pDSoundStream, E_POINTER);
    1035 
    1036     DSLOG(("DSound: pDSoundStream=%p, cbBufferIn=%RU32, uHz=%RU32, cChannels=%RU8, cBits=%RU8, fSigned=%RTbool\n",
    1037            pDSoundStream,
     1034static HRESULT directSoundCaptureOpen(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS,
     1035                                      PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     1036{
     1037    AssertPtrReturn(pThis,     E_POINTER);
     1038    AssertPtrReturn(pStreamDS, E_POINTER);
     1039    AssertPtrReturn(pCfgReq,   E_POINTER);
     1040    AssertPtrReturn(pCfgAcq,   E_POINTER);
     1041
     1042    DSLOG(("DSound: pStreamDS=%p, cbBufferIn=%RU32, uHz=%RU32, cChannels=%RU8, cBits=%RU8, fSigned=%RTbool\n",
     1043           pStreamDS,
    10381044           pThis->cfg.cbBufferIn,
    1039            pDSoundStream->Props.uHz,
    1040            pDSoundStream->Props.cChannels,
    1041            pDSoundStream->Props.cBits,
    1042            pDSoundStream->Props.fSigned));
    1043 
    1044     if (pDSoundStream->pDSCB != NULL)
     1045           pCfgReq->Props.uHz,
     1046           pCfgReq->Props.cChannels,
     1047           pCfgReq->Props.cBits,
     1048           pCfgReq->Props.fSigned));
     1049
     1050    if (pStreamDS->In.pDSCB != NULL)
    10451051    {
    10461052        /* Should not happen but be forgiving. */
    10471053        DSLOGREL(("DSound: DirectSoundCaptureBuffer already exists\n"));
    1048         directSoundCaptureClose(pDSoundStream);
     1054        directSoundCaptureClose(pStreamDS);
    10491055    }
    10501056
    10511057    WAVEFORMATEX wfx;
    1052     int rc = dsoundWaveFmtFromCfg(&pDSoundStream->streamCfg, &wfx);
     1058    int rc = dsoundWaveFmtFromCfg(pCfgReq, &wfx);
    10531059    if (RT_FAILURE(rc))
    10541060        return E_INVALIDARG;
    10551061
    1056     HRESULT hr = directSoundCaptureInterfaceCreate(pThis, pDSoundStream);
     1062    HRESULT hr = directSoundCaptureInterfaceCreate(pThis, pStreamDS);
    10571063    if (FAILED(hr))
    10581064        return hr;
     
    10611067    {
    10621068        LPDIRECTSOUNDCAPTUREBUFFER pDSCB = NULL;
     1069
    10631070        DSCBUFFERDESC bd;
    10641071        RT_ZERO(bd);
    1065         bd.dwSize = sizeof(bd);
    1066         bd.lpwfxFormat = &wfx;
     1072
     1073        bd.dwSize        = sizeof(bd);
     1074        bd.lpwfxFormat   = &wfx;
    10671075        bd.dwBufferBytes = pThis->cfg.cbBufferIn;
    1068         hr = IDirectSoundCapture_CreateCaptureBuffer(pDSoundStream->pDSC,
    1069                                                     &bd, &pDSCB, NULL);
     1076
     1077        hr = IDirectSoundCapture_CreateCaptureBuffer(pStreamDS->In.pDSC, &bd, &pDSCB, NULL);
    10701078        if (FAILED(hr))
    10711079        {
     
    10791087        }
    10801088
    1081         hr = IDirectSoundCaptureBuffer_QueryInterface(pDSCB, IID_IDirectSoundCaptureBuffer8, (void **)&pDSoundStream->pDSCB);
     1089        hr = IDirectSoundCaptureBuffer_QueryInterface(pDSCB, IID_IDirectSoundCaptureBuffer8, (void **)&pStreamDS->In.pDSCB);
    10821090        IDirectSoundCaptureBuffer_Release(pDSCB);
    10831091        if (FAILED(hr))
     
    10911099         */
    10921100        DWORD offByteReadPos = 0;
    1093         hr = IDirectSoundCaptureBuffer8_GetCurrentPosition(pDSoundStream->pDSCB, NULL, &offByteReadPos);
     1101        hr = IDirectSoundCaptureBuffer8_GetCurrentPosition(pStreamDS->In.pDSCB, NULL, &offByteReadPos);
    10941102        if (FAILED(hr))
    10951103        {
     
    10991107
    11001108        RT_ZERO(wfx);
    1101         hr = IDirectSoundCaptureBuffer8_GetFormat(pDSoundStream->pDSCB, &wfx, sizeof(wfx), NULL);
     1109        hr = IDirectSoundCaptureBuffer8_GetFormat(pStreamDS->In.pDSCB, &wfx, sizeof(wfx), NULL);
    11021110        if (FAILED(hr))
    11031111        {
     
    11091117        RT_ZERO(bc);
    11101118        bc.dwSize = sizeof(bc);
    1111         hr = IDirectSoundCaptureBuffer8_GetCaps(pDSoundStream->pDSCB, &bc);
     1119        hr = IDirectSoundCaptureBuffer8_GetCaps(pStreamDS->In.pDSCB, &bc);
    11121120        if (FAILED(hr))
    11131121        {
     
    11361144               wfx.cbSize));
    11371145
    1138         if (bc.dwBufferBytes & pDSoundStream->Props.uAlign)
     1146        if (bc.dwBufferBytes & pStreamDS->uAlign)
    11391147            DSLOGREL(("DSound: Capture GetCaps returned misaligned buffer: size %RU32, alignment %RU32\n",
    1140                       bc.dwBufferBytes, pDSoundStream->Props.uAlign + 1));
     1148                      bc.dwBufferBytes, pStreamDS->uAlign + 1));
    11411149
    11421150        if (bc.dwBufferBytes != pThis->cfg.cbBufferIn)
     
    11451153
    11461154        /* Initial state: reading at the initial capture position, no error. */
    1147         pDSoundStream->offCaptureBufRead = offByteReadPos;
    1148         pDSoundStream->cbCaptureBuf      = bc.dwBufferBytes;
    1149 
    1150         pDSoundStream->hrLastCapture     = S_OK;
     1155        pStreamDS->In.offCaptureBufRead = offByteReadPos;
     1156        pStreamDS->In.cbCaptureBuf      = bc.dwBufferBytes;
     1157
     1158        pStreamDS->In.hrLastCapture     = S_OK;
    11511159
    11521160        DSLOG(("DSound: offCaptureBufRead=%RU32, cbCaptureBuf=%RU32\n",
    1153                pDSoundStream->offCaptureBufRead, pDSoundStream->cbCaptureBuf));
     1161               pStreamDS->In.offCaptureBufRead, pStreamDS->In.cbCaptureBuf));
     1162
     1163        pCfgAcq->cSampleBufferHint = PDMAUDIOSTREAMCFG_B2S(pCfgAcq, pThis->cfg.cbBufferIn);
    11541164
    11551165    } while (0);
    11561166
    11571167    if (FAILED(hr))
    1158         directSoundCaptureClose(pDSoundStream);
     1168        directSoundCaptureClose(pStreamDS);
    11591169
    11601170    LogFlowFunc(("Returning %Rhrc\n", hr));
     
    11631173
    11641174
    1165 static HRESULT directSoundCaptureStop(PDRVHOSTDSOUND pThis, PDSOUNDSTREAMIN pDSoundStream)
    1166 {
    1167     AssertPtrReturn(pThis        , E_POINTER);
    1168     AssertPtrReturn(pDSoundStream, E_POINTER);
    1169 
    1170     NOREF(pThis);
     1175static HRESULT directSoundCaptureStop(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS)
     1176{
     1177    AssertPtrReturn(pThis,    E_POINTER);
     1178    AssertPtrReturn(pStreamDS, E_POINTER);
     1179
     1180    RT_NOREF(pThis);
    11711181
    11721182    HRESULT hr;
    11731183
    1174     if (pDSoundStream->pDSCB)
     1184    if (pStreamDS->In.pDSCB)
    11751185    {
    11761186        DSLOG(("DSound: Stopping capture\n"));
    11771187
    1178         hr = IDirectSoundCaptureBuffer_Stop(pDSoundStream->pDSCB);
     1188        hr = IDirectSoundCaptureBuffer_Stop(pStreamDS->In.pDSCB);
    11791189        if (FAILED(hr))
    11801190            DSLOGREL(("DSound: Stopping capture buffer failed with %Rhrc\n", hr));
     
    11841194
    11851195    if (SUCCEEDED(hr))
    1186         pDSoundStream->fEnabled = false;
     1196        pStreamDS->In.fEnabled = false;
    11871197
    11881198    LogFlowFunc(("Returning %Rhrc\n", hr));
     
    11911201
    11921202
    1193 static HRESULT directSoundCaptureStart(PDRVHOSTDSOUND pThis, PDSOUNDSTREAMIN pDSoundStream)
    1194 {
    1195     AssertPtrReturn(pThis,         VERR_INVALID_POINTER);
    1196     AssertPtrReturn(pDSoundStream, VERR_INVALID_POINTER);
     1203static HRESULT directSoundCaptureStart(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS)
     1204{
     1205    AssertPtrReturn(pThis,     VERR_INVALID_POINTER);
     1206    AssertPtrReturn(pStreamDS, VERR_INVALID_POINTER);
    11971207
    11981208    HRESULT hr;
    1199     if (pDSoundStream->pDSCB != NULL)
     1209    if (pStreamDS->In.pDSCB != NULL)
    12001210    {
    12011211        DWORD dwStatus;
    1202         hr = IDirectSoundCaptureBuffer8_GetStatus(pDSoundStream->pDSCB, &dwStatus);
     1212        hr = IDirectSoundCaptureBuffer8_GetStatus(pStreamDS->In.pDSCB, &dwStatus);
    12031213        if (FAILED(hr))
    12041214        {
     
    12181228#endif
    12191229                DSLOG(("DSound: Starting to capture\n"));
    1220                 hr = IDirectSoundCaptureBuffer8_Start(pDSoundStream->pDSCB, fFlags);
     1230                hr = IDirectSoundCaptureBuffer8_Start(pStreamDS->In.pDSCB, fFlags);
    12211231                if (FAILED(hr))
    12221232                    DSLOGREL(("DSound: Starting to capture failed with %Rhrc\n", hr));
     
    12281238
    12291239    if (SUCCEEDED(hr))
    1230         pDSoundStream->fEnabled = true;
     1240        pStreamDS->In.fEnabled = true;
    12311241
    12321242    LogFlowFunc(("Returning %Rhrc\n", hr));
     
    14021412    RT_ZERO(Cfg);
    14031413
    1404     Cfg.cbStreamOut     = sizeof(DSOUNDSTREAMOUT);
    1405     Cfg.cbStreamIn      = sizeof(DSOUNDSTREAMIN);
     1414    Cfg.cbStreamOut = sizeof(DSOUNDSTREAM);
     1415    Cfg.cbStreamIn  = sizeof(DSOUNDSTREAM);
    14061416
    14071417    DSOUNDENUMCBCTX cbCtx = { pThis, fEnum, 0, 0 };
     
    14391449
    14401450
    1441 static int dsoundCreateStreamOut(PDRVHOSTDSOUND pThis, PPDMAUDIOSTREAM pStream,
     1451static int dsoundCreateStreamOut(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS,
    14421452                                 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    14431453{
    1444     LogFlowFunc(("pStream=%p, pCfg=%p\n", pStream, pCfgReq));
    1445     PDSOUNDSTREAMOUT pDSoundStream = (PDSOUNDSTREAMOUT)pStream;
    1446 
    1447     pDSoundStream->streamCfg = *pCfgReq;
    1448     pDSoundStream->streamCfg.enmEndianness = PDMAUDIOHOSTENDIANNESS;
    1449 
    1450     int rc = DrvAudioHlpStreamCfgToProps(&pDSoundStream->streamCfg, &pDSoundStream->Props);
    1451     if (RT_SUCCESS(rc))
    1452     {
    1453         pDSoundStream->pDS = NULL;
    1454         pDSoundStream->pDSB = NULL;
    1455         pDSoundStream->offPlayWritePos = 0;
    1456         pDSoundStream->fRestartPlayback = true;
    1457         pDSoundStream->cbPlayBuf = 0;
    1458 
    1459         if (pCfgAcq)
    1460             pCfgAcq->cSampleBufferSize = pThis->cfg.cbBufferOut >> pDSoundStream->Props.cShift;
    1461 
    1462         /* Try to open playback in case the device is already there. */
    1463         directSoundPlayOpen(pThis, pDSoundStream);
    1464     }
    1465     else
    1466         RT_ZERO(pDSoundStream->streamCfg);
     1454    LogFlowFunc(("pStreamDS=%p, pCfgReq=%p\n", pStreamDS, pCfgReq));
     1455
     1456    pStreamDS->Out.pDS = NULL;
     1457    pStreamDS->Out.pDSB = NULL;
     1458    pStreamDS->Out.offPlayWritePos = 0;
     1459    pStreamDS->Out.fRestartPlayback = true;
     1460    pStreamDS->Out.cbPlayBuf = 0;
     1461
     1462    int rc = VINF_SUCCESS;
     1463
     1464    /* Try to open playback in case the device is already there. */
     1465    HRESULT hr = directSoundPlayOpen(pThis, pStreamDS, pCfgReq, pCfgAcq);
     1466    if (FAILED(hr))
     1467        rc = VERR_GENERAL_FAILURE; /** @todo Fudge! */
    14671468
    14681469    LogFlowFuncLeaveRC(rc);
     
    14701471}
    14711472
    1472 static int dsoundControlStreamOut(PDRVHOSTDSOUND pThis, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
    1473 {
    1474     LogFlowFunc(("pStream=%p, cmd=%d\n", pStream, enmStreamCmd));
    1475     PDSOUNDSTREAMOUT pDSoundStream = (PDSOUNDSTREAMOUT)pStream;
     1473static int dsoundControlStreamOut(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, PDMAUDIOSTREAMCMD enmStreamCmd)
     1474{
     1475    LogFlowFunc(("pStreamDS=%p, cmd=%d\n", pStreamDS, enmStreamCmd));
    14761476
    14771477    int rc = VINF_SUCCESS;
     
    14851485            DSLOG(("DSound: Playback PDMAUDIOSTREAMCMD_ENABLE\n"));
    14861486            /* Try to start playback. If it fails, then reopen and try again. */
    1487             hr = directSoundPlayStart(pThis, pDSoundStream);
     1487            hr = directSoundPlayStart(pThis, pStreamDS);
    14881488            if (FAILED(hr))
    14891489            {
    1490                 hr = directSoundPlayClose(pThis, pDSoundStream);
     1490                hr = directSoundPlayClose(pThis, pStreamDS);
    14911491                if (SUCCEEDED(hr))
    1492                     hr = directSoundPlayOpen(pThis, pDSoundStream);
     1492                {
     1493                    PDMAUDIOSTREAMCFG CfgAcq;
     1494                    hr = directSoundPlayOpen(pThis, pStreamDS, pStreamDS->pCfg /* pCfqReq */, &CfgAcq);
     1495                    if (SUCCEEDED(hr))
     1496                    {
     1497                        DrvAudioHlpStreamCfgFree(pStreamDS->pCfg);
     1498
     1499                        pStreamDS->pCfg = DrvAudioHlpStreamCfgDup(&CfgAcq);
     1500                        AssertPtr(pStreamDS->pCfg);
     1501
     1502                        /** @todo What to do if the format has changed? */
     1503                    }
     1504                }
    14931505                if (SUCCEEDED(hr))
    1494                     hr = directSoundPlayStart(pThis, pDSoundStream);
     1506                    hr = directSoundPlayStart(pThis, pStreamDS);
    14951507            }
    14961508
     
    15041516        {
    15051517            DSLOG(("DSound: Playback PDMAUDIOSTREAMCMD_DISABLE\n"));
    1506             hr = directSoundPlayStop(pThis, pDSoundStream);
     1518            hr = directSoundPlayStop(pThis, pStreamDS);
    15071519            if (FAILED(hr))
    15081520                rc = VERR_NOT_SUPPORTED;
     
    15271539 */
    15281540int drvHostDSoundStreamPlay(PPDMIHOSTAUDIO pInterface,
    1529                             PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
     1541                            PPDMAUDIOBACKENDSTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
    15301542{
    15311543    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     
    15351547    /* pcbRead is optional. */
    15361548
    1537     PDRVHOSTDSOUND   pThis         = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface);
    1538     PDSOUNDSTREAMOUT pDSoundStream = (PDSOUNDSTREAMOUT)pStream;
     1549    PDRVHOSTDSOUND pThis     = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface);
     1550    PDSOUNDSTREAM  pStreamDS = (PDSOUNDSTREAM)pStream;
    15391551
    15401552    int rc = VINF_SUCCESS;
     
    15481560    do /* to use 'break' */
    15491561    {
     1562        AssertPtr(pStreamDS->pCfg);
     1563        PPDMAUDIOPCMPROPS pProps = &pStreamDS->pCfg->Props;
     1564
    15501565        DWORD cbBuffer, cbFree, cbPlayPos;
    1551         rc = dsoundGetPosOut(pThis, pDSoundStream, &cbBuffer, &cbFree, &cbPlayPos);
     1566        rc = dsoundGetPosOut(pThis, pStreamDS, &cbBuffer, &cbFree, &cbPlayPos);
    15521567        if (RT_FAILURE(rc))
    15531568            break;
     
    15571572         * i.e. always leave a free space for 1 audio sample.
    15581573         */
    1559         const DWORD cbSample = PDMAUDIOPCMPROPS_S2B(&pDSoundStream->Props, 1);
     1574        const DWORD cbSample = PDMAUDIOPCMPROPS_S2B(pProps, 1);
    15601575        if (cbFree <= cbSample)
    15611576            break;
     
    15661581        /* Do not write more than available space in the DirectSound playback buffer. */
    15671582        cbLive = RT_MIN(cbFree, cbLive);
    1568         cbLive &= ~pDSoundStream->Props.uAlign;
     1583        cbLive &= ~pStreamDS->uAlign;
    15691584        if (cbLive == 0 || cbLive > cbBuffer)
    15701585        {
    15711586            DSLOG(("DSound: cbLive=%RU32, cbBuffer=%ld, offPlayWritePos=%ld, cbPlayPos=%ld\n",
    1572                    cbLive, cbBuffer, pDSoundStream->offPlayWritePos, cbPlayPos));
    1573             break;
    1574         }
    1575 
    1576         LPDIRECTSOUNDBUFFER8 pDSB = pDSoundStream->pDSB;
     1587                   cbLive, cbBuffer, pStreamDS->Out.offPlayWritePos, cbPlayPos));
     1588            break;
     1589        }
     1590
     1591        LPDIRECTSOUNDBUFFER8 pDSB = pStreamDS->Out.pDSB;
    15771592        AssertPtr(pDSB);
    15781593
    15791594        PVOID pv1, pv2;
    15801595        DWORD cb1, cb2;
    1581         HRESULT hr = directSoundPlayLock(pThis, pDSB, &pDSoundStream->Props, pDSoundStream->offPlayWritePos, cbLive,
     1596        HRESULT hr = directSoundPlayLock(pThis, pStreamDS, pStreamDS->Out.offPlayWritePos, cbLive,
    15821597                                         &pv1, &pv2, &cb1, &cb2, 0 /* dwFlags */);
    15831598        if (FAILED(hr))
     
    16031618        directSoundPlayUnlock(pThis, pDSB, pv1, pv2, cb1, cb2);
    16041619
    1605         pDSoundStream->offPlayWritePos = (pDSoundStream->offPlayWritePos + PDMAUDIOPCMPROPS_S2B(&pDSoundStream->Props, cbWrittenTotal))
     1620        pStreamDS->Out.offPlayWritePos = (pStreamDS->Out.offPlayWritePos + PDMAUDIOPCMPROPS_S2B(pProps, cbWrittenTotal))
    16061621                                       % cbBuffer;
    16071622
    16081623        DSLOGF(("DSound: %RU32/%RU32, buffer write pos %ld, rc=%Rrc\n",
    1609                 PDMAUDIOPCMPROPS_S2B(&pDSoundStream->Props, cbWrittenTotal), cbLive,
    1610                 pDSoundStream->offPlayWritePos, rc));
    1611 
    1612         if (pDSoundStream->fRestartPlayback)
     1624                PDMAUDIOPCMPROPS_S2B(pProps, cbWrittenTotal), cbLive, pStreamDS->Out.offPlayWritePos, rc));
     1625
     1626        if (pStreamDS->Out.fRestartPlayback)
    16131627        {
    16141628            /*
     
    16171631             * and it can start playing.
    16181632             */
    1619             pDSoundStream->fRestartPlayback = false;
     1633            pStreamDS->Out.fRestartPlayback = false;
    16201634
    16211635            DWORD fFlags = 0;
     
    16251639            for (unsigned i = 0; i < DRV_DSOUND_RESTORE_ATTEMPTS_MAX; i++)
    16261640            {
    1627                 hr = IDirectSoundBuffer8_Play(pDSoundStream->pDSB, 0, 0, fFlags);
     1641                hr = IDirectSoundBuffer8_Play(pStreamDS->Out.pDSB, 0, 0, fFlags);
    16281642                if (   SUCCEEDED(hr)
    16291643                    || hr != DSERR_BUFFERLOST)
     
    16321646                {
    16331647                    LogFlowFunc(("Restarting playback failed due to lost buffer, restoring ...\n"));
    1634                     directSoundPlayRestore(pThis, pDSoundStream->pDSB);
     1648                    directSoundPlayRestore(pThis, pStreamDS->Out.pDSB);
    16351649                }
    16361650            }
     
    16461660    } while (0);
    16471661
    1648     if (RT_FAILURE(rc))
     1662    if (RT_SUCCESS(rc))
     1663    {
     1664        if (pcbWritten)
     1665            *pcbWritten = cbWrittenTotal;
     1666    }
     1667    else
    16491668        dsoundUpdateStatusInternal(pThis);
    1650     else if (pcbWritten)
    1651         *pcbWritten = cbWrittenTotal;
    16521669
    16531670    return rc;
     
    16551672
    16561673
    1657 static int dsoundDestroyStreamOut(PDRVHOSTDSOUND pThis, PPDMAUDIOSTREAM pStream)
    1658 {
    1659     PDSOUNDSTREAMOUT pDSoundStream = (PDSOUNDSTREAMOUT)pStream;
    1660 
    1661     directSoundPlayClose(pThis, pDSoundStream);
    1662 
    1663     pDSoundStream->offPlayWritePos  = 0;
    1664     pDSoundStream->fRestartPlayback = true;
    1665     pDSoundStream->cbPlayBuf        = 0;
    1666 
    1667     RT_ZERO(pDSoundStream->streamCfg);
     1674static int dsoundDestroyStreamOut(PDRVHOSTDSOUND pThis, PPDMAUDIOBACKENDSTREAM pStream)
     1675{
     1676    PDSOUNDSTREAM pStreamDS = (PDSOUNDSTREAM)pStream;
     1677
     1678    directSoundPlayClose(pThis, pStreamDS);
     1679
     1680    pStreamDS->Out.offPlayWritePos  = 0;
     1681    pStreamDS->Out.fRestartPlayback = true;
     1682    pStreamDS->Out.cbPlayBuf        = 0;
    16681683
    16691684    return VINF_SUCCESS;
    16701685}
    16711686
    1672 static int dsoundCreateStreamIn(PDRVHOSTDSOUND pThis, PPDMAUDIOSTREAM pStream,
     1687static int dsoundCreateStreamIn(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS,
    16731688                                PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    16741689{
    1675     PDSOUNDSTREAMIN pDSoundStream = (PDSOUNDSTREAMIN)pStream;
    1676 
    1677     LogFlowFunc(("pStream=%p, pCfg=%p, enmRecSource=%ld\n", pStream, pCfgReq, pCfgReq->DestSource.Source));
    1678 
    1679     memcpy(&pDSoundStream->streamCfg, pCfgReq, sizeof(PDMAUDIOSTREAMCFG));
    1680 
    1681     /** @todo caller should already init Props? */
    1682     int rc = DrvAudioHlpStreamCfgToProps(&pDSoundStream->streamCfg, &pDSoundStream->Props);
    1683     if (RT_SUCCESS(rc))
    1684     {
    1685         /* Init the stream structure and save relevant information to it. */
    1686         pDSoundStream->offCaptureBufRead = 0;
    1687         pDSoundStream->cbCaptureBuf      = 0;
    1688         pDSoundStream->pDSC              = NULL;
    1689         pDSoundStream->pDSCB             = NULL;
    1690         pDSoundStream->enmRecSource      = pCfgReq->DestSource.Source;
    1691         pDSoundStream->hrLastCapture     = S_OK;
    1692 
    1693         if (pCfgAcq)
    1694             pCfgAcq->cSampleBufferSize = pThis->cfg.cbBufferIn >> pDSoundStream->Props.cShift;
    1695 
    1696         /* Try to open capture in case the device is already there. */
    1697         directSoundCaptureOpen(pThis, pDSoundStream); /** @todo r=andy Why not checking the result here?? */
    1698     }
    1699     else
    1700     {
    1701         RT_ZERO(pDSoundStream->streamCfg);
    1702     }
    1703 
    1704     LogFlowFuncLeaveRC(rc);
     1690    LogFunc(("pStreamDS=%p, pCfgReq=%p, enmRecSource=%s\n",
     1691             pStreamDS, pCfgReq, DrvAudioHlpRecSrcToStr(pCfgReq->DestSource.Source)));
     1692
     1693    /* Init the stream structure and save relevant information to it. */
     1694    pStreamDS->In.offCaptureBufRead = 0;
     1695    pStreamDS->In.cbCaptureBuf      = 0;
     1696    pStreamDS->In.pDSC              = NULL;
     1697    pStreamDS->In.pDSCB             = NULL;
     1698    pStreamDS->In.hrLastCapture     = S_OK;
     1699
     1700    int rc = VINF_SUCCESS;
     1701
     1702    /* Try to open capture in case the device is already there. */
     1703    HRESULT hr = directSoundCaptureOpen(pThis, pStreamDS, pCfgReq, pCfgAcq);
     1704    if (FAILED(hr))
     1705        rc = VERR_GENERAL_FAILURE; /** @todo Fudge! */
     1706
    17051707    return rc;
    17061708}
    17071709
    1708 static int dsoundControlStreamIn(PDRVHOSTDSOUND pThis, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
    1709 {
    1710     LogFlowFunc(("pStream=%p, enmStreamCmd=%ld\n", pStream, enmStreamCmd));
    1711     PDSOUNDSTREAMIN pDSoundStream = (PDSOUNDSTREAMIN)pStream;
     1710static int dsoundControlStreamIn(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, PDMAUDIOSTREAMCMD enmStreamCmd)
     1711{
     1712    LogFlowFunc(("pStreamDS=%p, enmStreamCmd=%ld\n", pStreamDS, enmStreamCmd));
    17121713
    17131714    int rc = VINF_SUCCESS;
     
    17201721        {
    17211722            /* Try to start capture. If it fails, then reopen and try again. */
    1722             hr = directSoundCaptureStart(pThis, pDSoundStream);
     1723            hr = directSoundCaptureStart(pThis, pStreamDS);
    17231724            if (FAILED(hr))
    17241725            {
    1725                 hr = directSoundCaptureClose(pDSoundStream);
     1726                hr = directSoundCaptureClose(pStreamDS);
    17261727                if (SUCCEEDED(hr))
    17271728                {
    1728                     hr = directSoundCaptureOpen(pThis, pDSoundStream);
     1729                    PDMAUDIOSTREAMCFG CfgAcq;
     1730                    hr = directSoundCaptureOpen(pThis, pStreamDS, pStreamDS->pCfg /* pCfgReq */, &CfgAcq);
    17291731                    if (SUCCEEDED(hr))
    1730                         hr = directSoundCaptureStart(pThis, pDSoundStream);
     1732                    {
     1733                        DrvAudioHlpStreamCfgFree(pStreamDS->pCfg);
     1734
     1735                        pStreamDS->pCfg = DrvAudioHlpStreamCfgDup(&CfgAcq);
     1736                        AssertPtr(pStreamDS->pCfg);
     1737
     1738                        /** @todo What to do if the format has changed? */
     1739
     1740                        hr = directSoundCaptureStart(pThis, pStreamDS);
     1741                    }
    17311742                }
    17321743            }
     
    17401751        case PDMAUDIOSTREAMCMD_PAUSE:
    17411752        {
    1742             hr = directSoundCaptureStop(pThis, pDSoundStream);
     1753            hr = directSoundCaptureStop(pThis, pStreamDS);
    17431754            if (FAILED(hr))
    17441755                rc = VERR_NOT_SUPPORTED;
     
    17621773 */
    17631774int drvHostDSoundStreamCapture(PPDMIHOSTAUDIO pInterface,
    1764                                PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
     1775                               PPDMAUDIOBACKENDSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
    17651776{
    17661777
     
    17701781    AssertReturn(cbBuf,         VERR_INVALID_PARAMETER);
    17711782
    1772     PDRVHOSTDSOUND pThis = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface);
    1773 
    1774     PDSOUNDSTREAMIN             pDSoundStream = (PDSOUNDSTREAMIN)pStream;
    1775     LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB         = pDSoundStream->pDSCB;
     1783    PDRVHOSTDSOUND pThis     = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface);
     1784    PDSOUNDSTREAM  pStreamDS = (PDSOUNDSTREAM)pStream;
     1785
     1786    LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB = pStreamDS->In.pDSCB;
     1787    AssertPtr(pDSCB);
    17761788
    17771789    int rc = VINF_SUCCESS;
     
    17921804        if (FAILED(hr))
    17931805        {
    1794             if (hr != pDSoundStream->hrLastCapture)
     1806            if (hr != pStreamDS->In.hrLastCapture)
    17951807            {
    17961808                DSLOGREL(("DSound: Getting capture position failed with %Rhrc\n", hr));
    1797                 pDSoundStream->hrLastCapture = hr;
     1809                pStreamDS->In.hrLastCapture = hr;
    17981810            }
    17991811
     
    18021814        }
    18031815
    1804         pDSoundStream->hrLastCapture = hr;
    1805 
    1806         if (offCurPos & pDSoundStream->Props.uAlign)
    1807             DSLOGF(("DSound: Misaligned capture read position %ld (alignment: %RU32)\n", offCurPos, pDSoundStream->Props.uAlign));
     1816        pStreamDS->In.hrLastCapture = hr;
     1817
     1818        if (offCurPos & pStreamDS->uAlign)
     1819            DSLOGF(("DSound: Misaligned capture read position %ld (alignment: %RU32)\n",
     1820                    offCurPos, pStreamDS->uAlign + 1));
    18081821
    18091822        /* Number of samples available in the DirectSound capture buffer. */
    1810         DWORD cbToCapture = dsoundRingDistance(offCurPos, pDSoundStream->offCaptureBufRead, pDSoundStream->cbCaptureBuf);
     1823        DWORD cbToCapture = dsoundRingDistance(offCurPos, pStreamDS->In.offCaptureBufRead, pStreamDS->In.cbCaptureBuf);
    18111824        if (cbToCapture == 0)
    18121825            break;
     
    18191832
    18201833        DSLOGF(("DSound: Capture cbBuf=%RU32, offCurPos=%ld, offCaptureBufRead=%ld, cbToCapture=%ld\n",
    1821                 cbBuf, offCurPos, pDSoundStream->offCaptureBufRead, cbToCapture));
     1834                cbBuf, offCurPos, pStreamDS->In.offCaptureBufRead, cbToCapture));
    18221835
    18231836        /* No need to fetch more samples than mix buffer can receive. */
     
    18271840        PVOID pv1, pv2;
    18281841        DWORD cb1, cb2;
    1829         hr = directSoundCaptureLock(pDSCB, &pDSoundStream->Props,
    1830                                     pDSoundStream->offCaptureBufRead, /* dwOffset */
     1842        hr = directSoundCaptureLock(pDSCB, &pStreamDS->pCfg->Props,
     1843                                    pStreamDS->In.offCaptureBufRead, /* dwOffset */
    18311844                                    cbToCapture,                      /* dwBytes */
    18321845                                    &pv1, &pv2, &cb1, &cb2,
     
    18541867        if (RT_SUCCESS(rc))
    18551868        {
    1856             pDSoundStream->offCaptureBufRead = (pDSoundStream->offCaptureBufRead + cbReadTotal)
    1857                                              % pDSoundStream->cbCaptureBuf;
     1869            pStreamDS->In.offCaptureBufRead = (pStreamDS->In.offCaptureBufRead + cbReadTotal)
     1870                                            % pStreamDS->In.cbCaptureBuf;
    18581871            DSLOGF(("DSound: Captured %ld bytes (%RU32 total)\n", cbToCapture, cbReadTotal));
    18591872        }
     
    18721885}
    18731886
    1874 static int dsoundDestroyStreamIn(PPDMAUDIOSTREAM pStream)
    1875 {
    1876     PDSOUNDSTREAMIN pDSoundStream = (PDSOUNDSTREAMIN)pStream;
    1877 
    1878     directSoundCaptureClose(pDSoundStream);
    1879 
    1880     pDSoundStream->offCaptureBufRead = 0;
    1881     pDSoundStream->cbCaptureBuf      = 0;
    1882 
    1883     RT_ZERO(pDSoundStream->streamCfg);
     1887static int dsoundDestroyStreamIn(PDSOUNDSTREAM pStreamDS)
     1888{
     1889    directSoundCaptureClose(pStreamDS);
     1890
     1891    pStreamDS->In.offCaptureBufRead = 0;
     1892    pStreamDS->In.cbCaptureBuf      = 0;
    18841893
    18851894    return VINF_SUCCESS;
     
    21562165 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate}
    21572166 */
    2158 static DECLCALLBACK(int) drvHostDSoundStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     2167static DECLCALLBACK(int) drvHostDSoundStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
     2168                                                   PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    21592169{
    21602170    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     
    21632173    AssertPtrReturn(pCfgAcq,    VERR_INVALID_POINTER);
    21642174
    2165     PDRVHOSTDSOUND pThis = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface);
     2175    PDRVHOSTDSOUND pThis     = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface);
     2176    PDSOUNDSTREAM  pStreamDS = (PDSOUNDSTREAM)pStream;
    21662177
    21672178    int rc;
    21682179    if (pCfgReq->enmDir == PDMAUDIODIR_IN)
    2169         rc = dsoundCreateStreamIn(pThis,  pStream, pCfgReq, pCfgAcq);
     2180        rc = dsoundCreateStreamIn(pThis,  pStreamDS, pCfgReq, pCfgAcq);
    21702181    else
    2171         rc = dsoundCreateStreamOut(pThis, pStream, pCfgReq, pCfgAcq);
     2182        rc = dsoundCreateStreamOut(pThis, pStreamDS, pCfgReq, pCfgAcq);
     2183
     2184    if (RT_SUCCESS(rc))
     2185    {
     2186        pStreamDS->pCfg = DrvAudioHlpStreamCfgDup(pCfgAcq);
     2187        if (!pStreamDS->pCfg)
     2188            rc = VERR_NO_MEMORY;
     2189    }
    21722190
    21732191    return rc;
     
    21782196 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy}
    21792197 */
    2180 static DECLCALLBACK(int) drvHostDSoundStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     2198static DECLCALLBACK(int) drvHostDSoundStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    21812199{
    21822200    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    21832201    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    21842202
    2185     PDRVHOSTDSOUND pThis = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface);
     2203    PDRVHOSTDSOUND pThis     = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface);
     2204    PDSOUNDSTREAM  pStreamDS = (PDSOUNDSTREAM)pStream;
     2205
     2206    if (!pStreamDS->pCfg) /* Not (yet) configured? Skip. */
     2207        return VINF_SUCCESS;
    21862208
    21872209    int rc;
    2188     if (pStream->enmDir == PDMAUDIODIR_IN)
    2189         rc = dsoundDestroyStreamIn(pStream);
     2210    if (pStreamDS->pCfg->enmDir == PDMAUDIODIR_IN)
     2211        rc = dsoundDestroyStreamIn(pStreamDS);
    21902212    else
    2191         rc = dsoundDestroyStreamOut(pThis, pStream);
     2213        rc = dsoundDestroyStreamOut(pThis, pStreamDS);
     2214
     2215    if (RT_SUCCESS(rc))
     2216    {
     2217        DrvAudioHlpStreamCfgFree(pStreamDS->pCfg);
     2218        pStreamDS->pCfg = NULL;
     2219    }
    21922220
    21932221    return rc;
     
    21982226 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl}
    21992227 */
    2200 static DECLCALLBACK(int) drvHostDSoundStreamControl(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
     2228static DECLCALLBACK(int) drvHostDSoundStreamControl(PPDMIHOSTAUDIO pInterface,
     2229                                                    PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
    22012230{
    22022231    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    22032232    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    22042233
    2205     PDRVHOSTDSOUND pThis = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface);
    2206 
    2207     Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST);
     2234    PDRVHOSTDSOUND pThis     = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface);
     2235    PDSOUNDSTREAM  pStreamDS = (PDSOUNDSTREAM)pStream;
     2236
     2237    if (!pStreamDS->pCfg) /* Not (yet) configured? Skip. */
     2238        return VINF_SUCCESS;
    22082239
    22092240    int rc;
    2210     if (pStream->enmDir == PDMAUDIODIR_IN)
    2211         rc = dsoundControlStreamIn(pThis,  pStream, enmStreamCmd);
     2241    if (pStreamDS->pCfg->enmDir == PDMAUDIODIR_IN)
     2242        rc = dsoundControlStreamIn(pThis,  pStreamDS, enmStreamCmd);
    22122243    else
    2213         rc = dsoundControlStreamOut(pThis, pStream, enmStreamCmd);
     2244        rc = dsoundControlStreamOut(pThis, pStreamDS, enmStreamCmd);
    22142245
    22152246    return rc;
     
    22202251 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
    22212252 */
    2222 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostDSoundStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     2253static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostDSoundStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    22232254{
    22242255    AssertPtrReturn(pInterface, PDMAUDIOSTRMSTS_FLAG_NONE);
    22252256    AssertPtrReturn(pStream,    PDMAUDIOSTRMSTS_FLAG_NONE);
    22262257
    2227     PDRVHOSTDSOUND pThis = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface);
     2258    PDRVHOSTDSOUND pThis     = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface);
     2259    PDSOUNDSTREAM  pStreamDS = (PDSOUNDSTREAM)pStream;
     2260
     2261    if (!pStreamDS->pCfg) /* Not (yet) configured? Skip. */
     2262        return PDMAUDIOSTRMSTS_FLAG_NONE;
    22282263
    22292264    PDMAUDIOSTRMSTS strmSts = PDMAUDIOSTRMSTS_FLAG_INITIALIZED;
    2230     if (pStream->enmDir == PDMAUDIODIR_IN)
    2231     {
    2232         PDSOUNDSTREAMIN pDSoundStream = (PDSOUNDSTREAMIN)pStream;
    2233         if (pDSoundStream->fEnabled)
     2265    if (pStreamDS->pCfg->enmDir == PDMAUDIODIR_IN)
     2266    {
     2267        if (pStreamDS->In.fEnabled)
    22342268            strmSts |= PDMAUDIOSTRMSTS_FLAG_ENABLED | PDMAUDIOSTRMSTS_FLAG_DATA_READABLE;
    22352269    }
    22362270    else
    22372271    {
    2238         PDSOUNDSTREAMOUT pDSoundStream = (PDSOUNDSTREAMOUT)pStream;
    2239         if (pDSoundStream->fEnabled)
     2272        if (pStreamDS->Out.fEnabled)
    22402273        {
    22412274            strmSts |= PDMAUDIOSTRMSTS_FLAG_ENABLED;
    22422275
    22432276            DWORD cbFree;
    2244             int rc = dsoundGetPosOut(pThis, pDSoundStream, NULL /* cbBuffer */, &cbFree, NULL /* cbPlayPos */);
     2277            int rc = dsoundGetPosOut(pThis, pStreamDS, NULL /* cbBuffer */, &cbFree, NULL /* cbPlayPos */);
    22452278            if (   RT_SUCCESS(rc)
    22462279                && cbFree)
     
    22592292 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate}
    22602293 */
    2261 static DECLCALLBACK(int) drvHostDSoundStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     2294static DECLCALLBACK(int) drvHostDSoundStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    22622295{
    22632296    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
  • trunk/src/VBox/Devices/Audio/DrvHostDebugAudio.cpp

    r65565 r65624  
    3434typedef struct DEBUGAUDIOSTREAM
    3535{
    36     /** Note: Always must come first! */
    37     PDMAUDIOSTREAM     Stream;
     36    /** The stream's acquired configuration. */
     37    PPDMAUDIOSTREAMCFG pCfg;
    3838    /** Audio file to dump output to or read input from. */
    3939    PDMAUDIOFILE       File;
     
    5050            uint64_t   tsLastPlayed;
    5151            uint8_t   *pu8PlayBuffer;
    52             size_t     cbPlayBuffer;
     52            uint32_t   cbPlayBuffer;
    5353        } Out;
    5454    };
    55     PDMAUDIOPCMPROPS   Props;
    56 
    5755} DEBUGAUDIOSTREAM, *PDEBUGAUDIOSTREAM;
    5856
     
    7775static DECLCALLBACK(int) drvHostDebugAudioGetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg)
    7876{
    79     NOREF(pInterface);
     77    RT_NOREF(pInterface);
    8078    AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER);
    8179
     
    9593static DECLCALLBACK(int) drvHostDebugAudioInit(PPDMIHOSTAUDIO pInterface)
    9694{
    97     NOREF(pInterface);
     95    RT_NOREF(pInterface);
    9896
    9997    LogFlowFuncLeaveRC(VINF_SUCCESS);
     
    107105static DECLCALLBACK(void) drvHostDebugAudioShutdown(PPDMIHOSTAUDIO pInterface)
    108106{
    109     NOREF(pInterface);
     107    RT_NOREF(pInterface);
    110108}
    111109
     
    123121
    124122
    125 static int debugCreateStreamIn(PPDMIHOSTAUDIO pInterface,
    126                                PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    127 {
    128     RT_NOREF(pInterface, pStream);
    129 
    130     PDEBUGAUDIOSTREAM pDbgStream = (PDEBUGAUDIOSTREAM)pStream;
    131 
    132     /* Just adopt the wanted stream configuration. */
    133     int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pDbgStream->Props);
    134     if (RT_SUCCESS(rc))
    135     {
    136         if (pCfgAcq)
    137             pCfgAcq->cSampleBufferSize = _1K;
    138     }
    139 
    140     LogFlowFuncLeaveRC(rc);
    141     return rc;
    142 }
    143 
    144 
    145 static int debugCreateStreamOut(PPDMIHOSTAUDIO pInterface,
    146                                 PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    147 {
    148     RT_NOREF(pInterface);
    149 
    150     PDEBUGAUDIOSTREAM pDbgStream = (PDEBUGAUDIOSTREAM)pStream;
    151 
    152     /* Just adopt the wanted stream configuration. */
    153     int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pDbgStream->Props);
    154     if (RT_SUCCESS(rc))
    155     {
    156         pDbgStream->Out.tsLastPlayed  = 0;
    157         pDbgStream->Out.cbPlayBuffer  = _1K * PDMAUDIOPCMPROPS_S2B(&pDbgStream->Props, 1); /** @todo Make this configurable? */
    158         pDbgStream->Out.pu8PlayBuffer = (uint8_t *)RTMemAlloc(pDbgStream->Out.cbPlayBuffer);
    159         if (!pDbgStream->Out.pu8PlayBuffer)
    160             rc = VERR_NO_MEMORY;
    161     }
     123static int debugCreateStreamIn(PDRVHOSTDEBUGAUDIO pDrv, PDEBUGAUDIOSTREAM pStreamDbg,
     124                               PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     125{
     126    RT_NOREF(pDrv, pStreamDbg, pCfgReq);
     127
     128    if (pCfgAcq)
     129        pCfgAcq->cSampleBufferHint = _1K;
     130
     131    return VINF_SUCCESS;
     132}
     133
     134
     135static int debugCreateStreamOut(PDRVHOSTDEBUGAUDIO pDrv, PDEBUGAUDIOSTREAM pStreamDbg,
     136                                PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     137{
     138    RT_NOREF(pDrv);
     139
     140    int rc = VINF_SUCCESS;
     141
     142    pStreamDbg->Out.tsLastPlayed  = 0;
     143    pStreamDbg->Out.cbPlayBuffer  = _1K * PDMAUDIOSTREAMCFG_S2B(pCfgReq, 1); /** @todo Make this configurable? */
     144    pStreamDbg->Out.pu8PlayBuffer = (uint8_t *)RTMemAlloc(pStreamDbg->Out.cbPlayBuffer);
     145    if (!pStreamDbg->Out.pu8PlayBuffer)
     146        rc = VERR_NO_MEMORY;
    162147
    163148    if (RT_SUCCESS(rc))
     
    172157            {
    173158                LogFlowFunc(("%s\n", szFile));
    174                 rc = DrvAudioHlpWAVFileOpen(&pDbgStream->File, szFile,
     159                rc = DrvAudioHlpWAVFileOpen(&pStreamDbg->File, szFile,
    175160                                            RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE_REPLACE,
    176                                             &pDbgStream->Props, PDMAUDIOFILEFLAG_NONE);
     161                                            &pCfgReq->Props, PDMAUDIOFILEFLAG_NONE);
    177162                if (RT_FAILURE(rc))
    178163                    LogRel(("DebugAudio: Creating output file '%s' failed with %Rrc\n", szFile, rc));
     
    188173    {
    189174        if (pCfgAcq)
    190             pCfgAcq->cSampleBufferSize = PDMAUDIOPCMPROPS_B2S(&pDbgStream->Props, pDbgStream->Out.cbPlayBuffer);
    191     }
    192 
    193     LogFlowFuncLeaveRC(rc);
     175            pCfgAcq->cSampleBufferHint = PDMAUDIOSTREAMCFG_B2S(pCfgAcq, pStreamDbg->Out.cbPlayBuffer);
     176    }
     177
    194178    return rc;
    195179}
     
    200184 */
    201185static DECLCALLBACK(int) drvHostDebugAudioStreamCreate(PPDMIHOSTAUDIO pInterface,
    202                                                        PPDMAUDIOSTREAM pStream,
     186                                                       PPDMAUDIOBACKENDSTREAM pStream,
    203187                                                       PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    204188{
     
    206190    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    207191    AssertPtrReturn(pCfgReq,    VERR_INVALID_POINTER);
     192    AssertPtrReturn(pCfgAcq,    VERR_INVALID_POINTER);
     193
     194    PDRVHOSTDEBUGAUDIO pDrv       = RT_FROM_MEMBER(pInterface, DRVHOSTDEBUGAUDIO, IHostAudio);
     195    PDEBUGAUDIOSTREAM  pStreamDbg = (PDEBUGAUDIOSTREAM)pStream;
    208196
    209197    int rc;
    210198    if (pCfgReq->enmDir == PDMAUDIODIR_IN)
    211         rc = debugCreateStreamIn( pInterface, pStream, pCfgReq, pCfgAcq);
     199        rc = debugCreateStreamIn( pDrv, pStreamDbg, pCfgReq, pCfgAcq);
    212200    else
    213         rc = debugCreateStreamOut(pInterface, pStream, pCfgReq, pCfgAcq);
    214 
    215     LogFlowFunc(("%s: rc=%Rrc\n", pStream->szName, rc));
     201        rc = debugCreateStreamOut(pDrv, pStreamDbg, pCfgReq, pCfgAcq);
     202
     203    if (RT_SUCCESS(rc))
     204    {
     205        pStreamDbg->pCfg = DrvAudioHlpStreamCfgDup(pCfgAcq);
     206        if (!pStreamDbg->pCfg)
     207            rc = VERR_NO_MEMORY;
     208    }
     209
    216210    return rc;
    217211}
     
    222216 */
    223217static DECLCALLBACK(int) drvHostDebugAudioStreamPlay(PPDMIHOSTAUDIO pInterface,
    224                                                      PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf,
     218                                                     PPDMAUDIOBACKENDSTREAM pStream, const void *pvBuf, uint32_t cbBuf,
    225219                                                     uint32_t *pcbWritten)
    226220{
     
    228222
    229223    PDRVHOSTDEBUGAUDIO pDrv       = RT_FROM_MEMBER(pInterface, DRVHOSTDEBUGAUDIO, IHostAudio);
    230     PDEBUGAUDIOSTREAM  pDbgStream = (PDEBUGAUDIOSTREAM)pStream;
     224    PDEBUGAUDIOSTREAM  pStreamDbg = (PDEBUGAUDIOSTREAM)pStream;
    231225
    232226    /* Consume as many samples as would be played at the current frequency since last call. */
     
    234228
    235229    uint64_t u64TicksNow     = PDMDrvHlpTMGetVirtualTime(pDrv->pDrvIns);
    236    // uint64_t u64TicksElapsed = u64TicksNow  - pDbgStream->Out.tsLastPlayed;
     230   // uint64_t u64TicksElapsed = u64TicksNow  - pStreamDbg->Out.tsLastPlayed;
    237231   // uint64_t u64TicksFreq    = PDMDrvHlpTMGetVirtualFreq(pDrv->pDrvIns);
    238232
     
    249243    uint32_t cbWritten = 0;
    250244
    251     uint32_t cbAvail  = RT_MIN(cbBuf, pDbgStream->Out.cbPlayBuffer);
     245    uint32_t cbAvail  = RT_MIN(cbBuf, pStreamDbg->Out.cbPlayBuffer);
    252246    while (cbAvail)
    253247    {
    254248        uint32_t cbChunk = cbAvail; /** @todo Use chunks? */
    255249
    256         memcpy(pDbgStream->Out.pu8PlayBuffer, pvBuf, cbChunk);
     250        memcpy(pStreamDbg->Out.pu8PlayBuffer, pvBuf, cbChunk);
    257251#if 0
    258252        RTFILE fh;
    259253        RTFileOpen(&fh, "/tmp/AudioDebug-Output.pcm",
    260254                   RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
    261         RTFileWrite(fh, pDbgStream->Out.pu8PlayBuffer, cbChunk, NULL);
     255        RTFileWrite(fh, pStreamDbg->Out.pu8PlayBuffer, cbChunk, NULL);
    262256        RTFileClose(fh);
    263257#endif
    264         int rc2 = DrvAudioHlpWAVFileWrite(&pDbgStream->File,
    265                                           pDbgStream->Out.pu8PlayBuffer, cbChunk, 0 /* fFlags */);
     258        int rc2 = DrvAudioHlpWAVFileWrite(&pStreamDbg->File,
     259                                          pStreamDbg->Out.pu8PlayBuffer, cbChunk, 0 /* fFlags */);
    266260        if (RT_FAILURE(rc2))
    267261        {
     
    277271
    278272    /* Remember when samples were consumed. */
    279     pDbgStream->Out.tsLastPlayed = u64TicksNow;
     273    pStreamDbg->Out.tsLastPlayed = u64TicksNow;
    280274
    281275    if (pcbWritten)
     
    290284 */
    291285static DECLCALLBACK(int) drvHostDebugAudioStreamCapture(PPDMIHOSTAUDIO pInterface,
    292                                                         PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
     286                                                        PPDMAUDIOBACKENDSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
    293287{
    294288    RT_NOREF(pInterface, pStream, pvBuf, cbBuf);
     
    302296
    303297
    304 static int debugDestroyStreamIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
    305 {
    306     RT_NOREF(pInterface, pStream);
    307     LogFlowFuncLeaveRC(VINF_SUCCESS);
    308     return VINF_SUCCESS;
    309 }
    310 
    311 
    312 static int debugDestroyStreamOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
    313 {
    314     RT_NOREF(pInterface);
    315     PDEBUGAUDIOSTREAM pDbgStream = (PDEBUGAUDIOSTREAM)pStream;
    316     if (   pDbgStream
    317         && pDbgStream->Out.pu8PlayBuffer)
    318     {
    319         RTMemFree(pDbgStream->Out.pu8PlayBuffer);
    320         pDbgStream->Out.pu8PlayBuffer = NULL;
    321     }
    322 
    323     size_t cbDataSize = DrvAudioHlpWAVFileGetDataSize(&pDbgStream->File);
    324 
    325     int rc = DrvAudioHlpWAVFileClose(&pDbgStream->File);
     298static int debugDestroyStreamIn(PDRVHOSTDEBUGAUDIO pDrv, PDEBUGAUDIOSTREAM pStreamDbg)
     299{
     300    RT_NOREF(pDrv, pStreamDbg);
     301    return VINF_SUCCESS;
     302}
     303
     304
     305static int debugDestroyStreamOut(PDRVHOSTDEBUGAUDIO pDrv, PDEBUGAUDIOSTREAM pStreamDbg)
     306{
     307    RT_NOREF(pDrv);
     308
     309    if (pStreamDbg->Out.pu8PlayBuffer)
     310    {
     311        RTMemFree(pStreamDbg->Out.pu8PlayBuffer);
     312        pStreamDbg->Out.pu8PlayBuffer = NULL;
     313    }
     314
     315    size_t cbDataSize = DrvAudioHlpWAVFileGetDataSize(&pStreamDbg->File);
     316
     317    int rc = DrvAudioHlpWAVFileClose(&pStreamDbg->File);
    326318    if (RT_SUCCESS(rc))
    327319    {
     
    332324            && fDeleteEmptyFiles)
    333325        {
    334             rc = RTFileDelete(pDbgStream->File.szName);
     326            rc = RTFileDelete(pStreamDbg->File.szName);
    335327        }
    336328        else
    337             LogRel(("DebugAudio: Created output file '%s' (%zu bytes)\n", pDbgStream->File.szName, cbDataSize));
    338     }
    339 
    340     LogFlowFuncLeaveRC(rc);
     329            LogRel(("DebugAudio: Created output file '%s' (%zu bytes)\n", pStreamDbg->File.szName, cbDataSize));
     330    }
     331
    341332    return rc;
    342333}
    343334
    344335
    345 static DECLCALLBACK(int) drvHostDebugAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     336static DECLCALLBACK(int) drvHostDebugAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    346337{
    347338    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    348     AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
     339
     340    PDRVHOSTDEBUGAUDIO pDrv       = RT_FROM_MEMBER(pInterface, DRVHOSTDEBUGAUDIO, IHostAudio);
     341    PDEBUGAUDIOSTREAM  pStreamDbg = (PDEBUGAUDIOSTREAM)pStream;
     342
     343    if (!pStreamDbg->pCfg) /* Not (yet) configured? Skip. */
     344        return VINF_SUCCESS;
    349345
    350346    int rc;
    351     if (pStream->enmDir == PDMAUDIODIR_IN)
    352         rc = debugDestroyStreamIn(pInterface,  pStream);
     347    if (pStreamDbg->pCfg->enmDir == PDMAUDIODIR_IN)
     348        rc = debugDestroyStreamIn (pDrv, pStreamDbg);
    353349    else
    354         rc = debugDestroyStreamOut(pInterface, pStream);
     350        rc = debugDestroyStreamOut(pDrv, pStreamDbg);
     351
     352    if (RT_SUCCESS(rc))
     353    {
     354        DrvAudioHlpStreamCfgFree(pStreamDbg->pCfg);
     355        pStreamDbg->pCfg = NULL;
     356    }
    355357
    356358    return rc;
     
    358360
    359361static DECLCALLBACK(int) drvHostDebugAudioStreamControl(PPDMIHOSTAUDIO pInterface,
    360                                                         PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
     362                                                        PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
    361363{
    362364    RT_NOREF(enmStreamCmd);
     
    364366    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    365367
    366     Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST);
    367 
    368     return VINF_SUCCESS;
    369 }
    370 
    371 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostDebugAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
    372 {
    373     NOREF(pInterface);
    374     NOREF(pStream);
     368    return VINF_SUCCESS;
     369}
     370
     371static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostDebugAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
     372{
     373    RT_NOREF(pInterface, pStream);
    375374
    376375    return (  PDMAUDIOSTRMSTS_FLAG_INITIALIZED | PDMAUDIOSTRMSTS_FLAG_ENABLED
     
    378377}
    379378
    380 static DECLCALLBACK(int) drvHostDebugAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
    381 {
    382     NOREF(pInterface);
    383     NOREF(pStream);
    384 
     379static DECLCALLBACK(int) drvHostDebugAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
     380{
     381    RT_NOREF(pInterface, pStream);
    385382    return VINF_SUCCESS;
    386383}
  • trunk/src/VBox/Devices/Audio/DrvHostNullAudio.cpp

    r65565 r65624  
    6060*   Structures and Typedefs                                                                                                      *
    6161*********************************************************************************************************************************/
    62 typedef struct NULLAUDIOSTREAMOUT
    63 {
    64     /** @note Always must come first! */
    65     PDMAUDIOSTREAM      Stream;
    66     /** The PCM properties of this stream. */
    67     PDMAUDIOPCMPROPS    Props;
    68     uint64_t            u64TicksLast;
    69 } NULLAUDIOSTREAMOUT;
    70 typedef NULLAUDIOSTREAMOUT *PNULLAUDIOSTREAMOUT;
    71 
    72 typedef struct NULLAUDIOSTREAMIN
    73 {
    74     /** @note Always must come first! */
    75     PDMAUDIOSTREAM      Stream;
    76     /** The PCM properties of this stream. */
    77     PDMAUDIOPCMPROPS    Props;
    78 } NULLAUDIOSTREAMIN;
    79 typedef NULLAUDIOSTREAMIN *PNULLAUDIOSTREAMIN;
     62typedef struct NULLAUDIOSTREAM
     63{
     64    /** The stream's acquired configuration. */
     65    PPDMAUDIOSTREAMCFG pCfg;
     66    union
     67    {
     68        struct
     69        {
     70            /** Timestamp of last played samples. */
     71            uint64_t   u64TicksLast;
     72        } Out;
     73    };
     74} NULLAUDIOSTREAM;
     75typedef NULLAUDIOSTREAM *PNULLAUDIOSTREAM;
    8076
    8177/**
     
    10197    AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER);
    10298
    103     pBackendCfg->cbStreamOut    = sizeof(NULLAUDIOSTREAMOUT);
    104     pBackendCfg->cbStreamIn     = sizeof(NULLAUDIOSTREAMIN);
     99    pBackendCfg->cbStreamOut    = sizeof(NULLAUDIOSTREAM);
     100    pBackendCfg->cbStreamIn     = sizeof(NULLAUDIOSTREAM);
    105101
    106102    pBackendCfg->cMaxStreamsOut = 1; /* Output */
     
    147143 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay}
    148144 */
    149 static DECLCALLBACK(int) drvHostNullAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream,
     145static DECLCALLBACK(int) drvHostNullAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
    150146                                                    const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
    151147{
     
    155151    AssertReturn(cbBuf,         VERR_INVALID_PARAMETER);
    156152
    157     PDRVHOSTNULLAUDIO   pDrv        = RT_FROM_MEMBER(pInterface, DRVHOSTNULLAUDIO, IHostAudio);
    158     PNULLAUDIOSTREAMOUT pNullStream = RT_FROM_MEMBER(pStream, NULLAUDIOSTREAMOUT, Stream);
     153    PDRVHOSTNULLAUDIO pDrv        = RT_FROM_MEMBER(pInterface, DRVHOSTNULLAUDIO, IHostAudio);
     154    PNULLAUDIOSTREAM  pStreamNull = (PNULLAUDIOSTREAM)pStream;
    159155
    160156    /* Consume as many samples as would be played at the current frequency since last call. */
    161     uint32_t csLive          = PDMAUDIOPCMPROPS_B2S(&pNullStream->Props, cbBuf);
     157    uint32_t csLive          = PDMAUDIOPCMPROPS_B2S(&pStreamNull->pCfg->Props, cbBuf);
    162158
    163159    uint64_t u64TicksNow     = PDMDrvHlpTMGetVirtualTime(pDrv->pDrvIns);
    164     uint64_t u64TicksElapsed = u64TicksNow  - pNullStream->u64TicksLast;
     160    uint64_t u64TicksElapsed = u64TicksNow  - pStreamNull->Out.u64TicksLast;
    165161    uint64_t u64TicksFreq    = PDMDrvHlpTMGetVirtualFreq(pDrv->pDrvIns);
    166162
    167163    /* Remember when samples were consumed. */
    168     pNullStream->u64TicksLast = u64TicksNow;
     164    pStreamNull->Out.u64TicksLast = u64TicksNow;
    169165
    170166    /*
     
    172168     * If rounding is not taken into account then the playback rate will be consistently lower that expected.
    173169     */
    174     uint64_t csPlayed = (2 * u64TicksElapsed * pNullStream->Props.uHz + u64TicksFreq) / u64TicksFreq / 2;
     170    uint64_t csPlayed = (2 * u64TicksElapsed * pStreamNull->pCfg->Props.uHz + u64TicksFreq) / u64TicksFreq / 2;
    175171
    176172    /* Don't play more than available. */
     
    181177
    182178    if (pcbWritten)
    183         *pcbWritten = PDMAUDIOPCMPROPS_S2B(&pNullStream->Props, csPlayed);
     179        *pcbWritten = PDMAUDIOPCMPROPS_S2B(&pStreamNull->pCfg->Props, csPlayed);
    184180
    185181    return VINF_SUCCESS;
     
    190186 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture}
    191187 */
    192 static DECLCALLBACK(int) drvHostNullAudioStreamCapture(PPDMIHOSTAUDIO pInterface,
    193                                                        PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
     188static DECLCALLBACK(int) drvHostNullAudioStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
     189                                                       void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
    194190{
    195191    RT_NOREF(pInterface, pStream);
    196192
     193    /* Return silence. */
    197194    RT_BZERO(pvBuf, cbBuf);
    198195
    199     /* Return silent audio. */
    200196    if (pcbRead)
    201197        *pcbRead = cbBuf;
     
    205201
    206202
    207 static int nullCreateStreamIn(PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    208 {
    209     PNULLAUDIOSTREAMIN pNullStream = RT_FROM_MEMBER(pStream, NULLAUDIOSTREAMIN, Stream);
    210 
    211     /* Just adopt the wanted stream configuration. */
    212     int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pNullStream->Props);
    213     if (RT_SUCCESS(rc))
    214     {
    215         if (pCfgAcq)
    216             pCfgAcq->cSampleBufferSize = _1K;
    217     }
    218 
    219     return rc;
    220 }
    221 
    222 
    223 static int nullCreateStreamOut(PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    224 {
    225     PNULLAUDIOSTREAMOUT pNullStream = RT_FROM_MEMBER(pStream, NULLAUDIOSTREAMOUT, Stream);
    226 
    227     /* Just adopt the wanted stream configuration. */
    228     int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pNullStream->Props);
    229     if (RT_SUCCESS(rc))
    230     {
    231         pNullStream->u64TicksLast  = 0;
    232 
    233         if (pCfgAcq)
    234             pCfgAcq->cSampleBufferSize = _1K; /** @todo Make this configurable. */
    235     }
    236 
    237     return rc;
     203static int nullCreateStreamIn(PNULLAUDIOSTREAM pStreamNull, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     204{
     205    RT_NOREF(pStreamNull, pCfgReq);
     206
     207    if (pCfgAcq)
     208        pCfgAcq->cSampleBufferHint = _1K;
     209
     210    return VINF_SUCCESS;
     211}
     212
     213
     214static int nullCreateStreamOut(PNULLAUDIOSTREAM pStreamNull, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     215{
     216    RT_NOREF(pCfgReq);
     217
     218    pStreamNull->Out.u64TicksLast  = 0;
     219
     220    if (pCfgAcq)
     221        pCfgAcq->cSampleBufferHint = _1K; /** @todo Make this configurable. */
     222
     223    return VINF_SUCCESS;
    238224}
    239225
     
    242228 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate}
    243229 */
    244 static DECLCALLBACK(int) drvHostNullAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream,
     230static DECLCALLBACK(int) drvHostNullAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
    245231                                                      PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    246232{
     
    248234    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    249235    AssertPtrReturn(pCfgReq,    VERR_INVALID_POINTER);
     236    AssertPtrReturn(pCfgAcq,    VERR_INVALID_POINTER);
     237
     238    PNULLAUDIOSTREAM pStreamNull = (PNULLAUDIOSTREAM)pStream;
    250239
    251240    int rc;
    252241    if (pCfgReq->enmDir == PDMAUDIODIR_IN)
    253         rc = nullCreateStreamIn( pStream, pCfgReq, pCfgAcq);
     242        rc = nullCreateStreamIn( pStreamNull, pCfgReq, pCfgAcq);
    254243    else
    255         rc = nullCreateStreamOut(pStream, pCfgReq, pCfgAcq);
    256 
    257     LogFlowFunc(("%s: rc=%Rrc\n", pStream->szName, rc));
     244        rc = nullCreateStreamOut(pStreamNull, pCfgReq, pCfgAcq);
     245
     246    if (RT_SUCCESS(rc))
     247    {
     248        pStreamNull->pCfg = DrvAudioHlpStreamCfgDup(pCfgAcq);
     249        if (!pStreamNull->pCfg)
     250            rc = VERR_NO_MEMORY;
     251    }
     252
    258253    return rc;
    259254}
     
    267262
    268263
    269 static int nullDestroyStreamOut(PPDMAUDIOSTREAM pStream)
    270 {
    271     RT_NOREF(pStream);
     264static int nullDestroyStreamOut(PNULLAUDIOSTREAM pStreamNull)
     265{
     266    RT_NOREF(pStreamNull);
    272267    return VINF_SUCCESS;
    273268}
     
    277272 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy}
    278273 */
    279 static DECLCALLBACK(int) drvHostNullAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     274static DECLCALLBACK(int) drvHostNullAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    280275{
    281276    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    282277    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    283278
     279    PNULLAUDIOSTREAM pStreamNull = (PNULLAUDIOSTREAM)pStream;
     280
     281    if (!pStreamNull->pCfg) /* Not (yet) configured? Skip. */
     282        return VINF_SUCCESS;
     283
    284284    int rc;
    285     if (pStream->enmDir == PDMAUDIODIR_IN)
     285    if (pStreamNull->pCfg->enmDir == PDMAUDIODIR_IN)
    286286        rc = nullDestroyStreamIn();
    287287    else
    288         rc = nullDestroyStreamOut(pStream);
     288        rc = nullDestroyStreamOut(pStreamNull);
     289
     290    if (RT_SUCCESS(rc))
     291    {
     292        DrvAudioHlpStreamCfgFree(pStreamNull->pCfg);
     293        pStreamNull->pCfg = NULL;
     294    }
    289295
    290296    return rc;
     
    295301 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl}
    296302 */
    297 static DECLCALLBACK(int) drvHostNullAudioStreamControl(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
    298 {
    299     RT_NOREF(enmStreamCmd);
    300     AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    301     AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    302 
    303     Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST);
    304 
     303static DECLCALLBACK(int) drvHostNullAudioStreamControl(PPDMIHOSTAUDIO pInterface,
     304                                                       PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
     305{
     306    RT_NOREF(pInterface, pStream, enmStreamCmd);
    305307    return VINF_SUCCESS;
    306308}
     
    310312 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
    311313 */
    312 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostNullAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     314static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostNullAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    313315{
    314316    RT_NOREF(pInterface, pStream);
     
    321323 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate}
    322324 */
    323 static DECLCALLBACK(int) drvHostNullAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     325static DECLCALLBACK(int) drvHostNullAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    324326{
    325327    NOREF(pInterface);
  • trunk/src/VBox/Devices/Audio/DrvHostOSSAudio.cpp

    r65613 r65624  
    7070typedef struct OSSAUDIOSTREAMCFG
    7171{
    72     PDMAUDIOFMT       enmFormat;
    73     PDMAUDIOENDIANNESS enmENDIANNESS;
    74     uint16_t          uFreq;
    75     uint8_t           cChannels;
     72    PDMAUDIOPCMPROPS  Props;
    7673    uint16_t          cFragments;
    7774    uint32_t          cbFragmentSize;
    7875} OSSAUDIOSTREAMCFG, *POSSAUDIOSTREAMCFG;
    7976
    80 typedef struct OSSAUDIOSTREAMIN
    81 {
    82     /** Note: Always must come first! */
    83     PDMAUDIOSTREAM     pStreamIn;
    84     /** The PCM properties of this stream. */
    85     PDMAUDIOPCMPROPS   Props;
     77typedef struct OSSAUDIOSTREAM
     78{
     79    /** The stream's acquired configuration. */
     80    PPDMAUDIOSTREAMCFG pCfg;
     81    /** Buffer alignment. */
     82    uint8_t            uAlign;
     83    union
     84    {
     85        struct
     86        {
     87
     88        } In;
     89        struct
     90        {
     91#ifndef RT_OS_L4
     92            /** Whether we use a memory mapped file instead of our
     93             *  own allocated PCM buffer below. */
     94            /** @todo The memory mapped code seems to be utterly broken.
     95             *        Needs investigation! */
     96            bool       fMMIO;
     97#endif
     98        } Out;
     99    };
    86100    int                hFile;
    87101    int                cFragments;
     
    92106    size_t             cbBuf;
    93107    int                old_optr;
    94 } OSSAUDIOSTREAMIN, *POSSAUDIOSTREAMIN;
    95 
    96 typedef struct OSSAUDIOSTREAMOUT
    97 {
    98     /** Note: Always must come first! */
    99     PDMAUDIOSTREAM      pStreamOut;
    100     /** The PCM properties of this stream. */
    101     PDMAUDIOPCMPROPS    Props;
    102     int                 hFile;
    103     int                 cFragments;
    104     int                 cbFragmentSize;
    105 #ifndef RT_OS_L4
    106     /** Whether we use a memory mapped file instead of our
    107      *  own allocated PCM buffer below. */
    108     /** @todo The memory mapped code seems to be utterly broken.
    109      *        Needs investigation! */
    110     bool                fMMIO;
    111 #endif
    112     /** Own PCM buffer in case memory mapping is unavailable. */
    113     void               *pvBuf;
    114     /** Size (in bytes) of own PCM buffer. */
    115     size_t              cbBuf;
    116     int                 old_optr;
    117 } OSSAUDIOSTREAMOUT, *POSSAUDIOSTREAMOUT;
     108} OSSAUDIOSTREAM, *POSSAUDIOSTREAM;
    118109
    119110typedef struct OSSAUDIOCFG
     
    160151
    161152
    162 static int ossAudioFmtToOSS(PDMAUDIOFMT fmt)
    163 {
     153static int ossOSSToAudioProps(int fmt, PPDMAUDIOPCMPROPS pProps)
     154{
     155    RT_BZERO(pProps, sizeof(PDMAUDIOPCMPROPS));
     156
    164157    switch (fmt)
    165158    {
    166         case PDMAUDIOFMT_S8:
    167             return AFMT_S8;
    168 
    169         case PDMAUDIOFMT_U8:
    170             return AFMT_U8;
    171 
    172         case PDMAUDIOFMT_S16:
    173             return AFMT_S16_LE;
    174 
    175         case PDMAUDIOFMT_U16:
    176             return AFMT_U16_LE;
    177 
    178         default:
    179             break;
    180     }
    181 
    182     AssertMsgFailed(("Format %ld not supported\n", fmt));
    183     return AFMT_U8;
    184 }
    185 
    186 
    187 static int ossOSSToAudioFmt(int fmt, PDMAUDIOFMT *pFmt, PDMAUDIOENDIANNESS *pENDIANNESS)
    188 {
    189     switch (fmt)
    190     {
    191159        case AFMT_S8:
    192             *pFmt = PDMAUDIOFMT_S8;
    193             if (pENDIANNESS)
    194                 *pENDIANNESS = PDMAUDIOENDIANNESS_LITTLE;
     160            pProps->cBits   = 8;
     161            pProps->fSigned = true;
    195162            break;
    196163
    197164        case AFMT_U8:
    198             *pFmt = PDMAUDIOFMT_U8;
    199             if (pENDIANNESS)
    200                 *pENDIANNESS = PDMAUDIOENDIANNESS_LITTLE;
     165            pProps->cBits   = 8;
     166            pProps->fSigned = false;
    201167            break;
    202168
    203169        case AFMT_S16_LE:
    204             *pFmt = PDMAUDIOFMT_S16;
    205             if (pENDIANNESS)
    206                 *pENDIANNESS = PDMAUDIOENDIANNESS_LITTLE;
     170            pProps->cBits   = 16;
     171            pProps->fSigned = true;
    207172            break;
    208173
    209174        case AFMT_U16_LE:
    210             *pFmt = PDMAUDIOFMT_U16;
    211             if (pENDIANNESS)
    212                 *pENDIANNESS = PDMAUDIOENDIANNESS_LITTLE;
    213             break;
    214 
    215         case AFMT_S16_BE:
    216             *pFmt = PDMAUDIOFMT_S16;
    217             if (pENDIANNESS)
    218                 *pENDIANNESS = PDMAUDIOENDIANNESS_BIG;
     175            pProps->cBits   = 16;
     176            pProps->fSigned = false;
     177            break;
     178
     179       case AFMT_S16_BE:
     180            pProps->cBits   = 16;
     181            pProps->fSigned = true;
     182#ifdef RT_LITTLE_ENDIAN
     183            pProps->fSwapEndian = true;
     184#endif
    219185            break;
    220186
    221187        case AFMT_U16_BE:
    222             *pFmt = PDMAUDIOFMT_U16;
    223             if (pENDIANNESS)
    224                 *pENDIANNESS = PDMAUDIOENDIANNESS_BIG;
     188            pProps->cBits   = 16;
     189            pProps->fSigned = false;
     190#ifdef RT_LITTLE_ENDIAN
     191            pProps->fSwapEndian = true;
     192#endif
    225193            break;
    226194
     
    255223
    256224
    257 static int ossStreamOpen(const char *pszDev, int fOpen, POSSAUDIOSTREAMCFG pReq, POSSAUDIOSTREAMCFG pObt, int *phFile)
    258 {
    259     int rc;
     225static int ossStreamOpen(const char *pszDev, int fOpen, POSSAUDIOSTREAMCFG pOSSReq, POSSAUDIOSTREAMCFG pOSSAcq, int *phFile)
     226{
     227    int rc = VINF_SUCCESS;
    260228
    261229    int hFile = -1;
     
    270238        }
    271239
    272         int iFormat = ossAudioFmtToOSS(pReq->enmFormat);
     240        int iFormat;
     241        switch (pOSSReq->Props.cBits)
     242        {
     243            case 8:
     244                iFormat = pOSSReq->Props.fSigned ? AFMT_S8 : AFMT_U8;
     245                break;
     246
     247            case 16:
     248                iFormat = pOSSReq->Props.fSigned ? AFMT_S16_LE : AFMT_U16_LE;
     249                break;
     250
     251            default:
     252                rc = VERR_NOT_SUPPORTED;
     253                break;
     254        }
     255
     256        if (RT_FAILURE(rc))
     257            break;
     258
    273259        if (ioctl(hFile, SNDCTL_DSP_SAMPLESIZE, &iFormat))
    274260        {
     
    278264        }
    279265
    280         int cChannels = pReq->cChannels;
     266        int cChannels = pOSSReq->Props.cChannels;
    281267        if (ioctl(hFile, SNDCTL_DSP_CHANNELS, &cChannels))
    282268        {
    283             LogRel(("OSS: Failed to set number of audio channels (%d): %s (%d)\n", pReq->cChannels, strerror(errno), errno));
     269            LogRel(("OSS: Failed to set number of audio channels (%RU8): %s (%d)\n",
     270                    pOSSReq->Props.cChannels, strerror(errno), errno));
    284271            rc = RTErrConvertFromErrno(errno);
    285272            break;
    286273        }
    287274
    288         int freq = pReq->uFreq;
     275        int freq = pOSSReq->Props.uHz;
    289276        if (ioctl(hFile, SNDCTL_DSP_SPEED, &freq))
    290277        {
    291             LogRel(("OSS: Failed to set audio frequency (%dHZ): %s (%d)\n", pReq->uFreq, strerror(errno), errno));
     278            LogRel(("OSS: Failed to set audio frequency (%dHZ): %s (%d)\n", pOSSReq->Props.uHz, strerror(errno), errno));
    292279            rc = RTErrConvertFromErrno(errno);
    293280            break;
     
    308295
    309296        LogRel2(("OSS: Requested %RU16 %s fragments, %RU32 bytes each\n",
    310                  pReq->cFragments, fIn ? "input" : "output", pReq->cbFragmentSize));
    311 
    312         int mmmmssss = (pReq->cFragments << 16) | lsbindex(pReq->cbFragmentSize);
     297                 pOSSReq->cFragments, fIn ? "input" : "output", pOSSReq->cbFragmentSize));
     298
     299        int mmmmssss = (pOSSReq->cFragments << 16) | lsbindex(pOSSReq->cbFragmentSize);
    313300        if (ioctl(hFile, SNDCTL_DSP_SETFRAGMENT, &mmmmssss))
    314301        {
    315302            LogRel(("OSS: Failed to set %RU16 fragments to %RU32 bytes each: %s (%d)\n",
    316                     pReq->cFragments, pReq->cbFragmentSize, strerror(errno), errno));
     303                    pOSSReq->cFragments, pOSSReq->cbFragmentSize, strerror(errno), errno));
    317304            rc = RTErrConvertFromErrno(errno);
    318305            break;
     
    327314        }
    328315
    329         rc = ossOSSToAudioFmt(iFormat, &pObt->enmFormat, &pObt->enmENDIANNESS);
     316        rc = ossOSSToAudioProps(iFormat, &pOSSAcq->Props);
    330317        if (RT_SUCCESS(rc))
    331318        {
    332             pObt->cChannels      = cChannels;
    333             pObt->uFreq          = freq;
    334             pObt->cFragments     = abinfo.fragstotal;
    335             pObt->cbFragmentSize = abinfo.fragsize;
     319            pOSSAcq->Props.cChannels = cChannels;
     320            pOSSAcq->Props.uHz       = freq;
     321            pOSSAcq->Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pOSSAcq->Props.cBits, pOSSAcq->Props.cChannels);
     322
     323            pOSSAcq->cFragments      = abinfo.fragstotal;
     324            pOSSAcq->cbFragmentSize  = abinfo.fragsize;
    336325
    337326            LogRel2(("OSS: Got %RU16 %s fragments, %RU32 bytes each\n",
    338                      pObt->cFragments, fIn ? "input" : "output", pObt->cbFragmentSize));
     327                     pOSSAcq->cFragments, fIn ? "input" : "output", pOSSAcq->cbFragmentSize));
    339328
    340329            *phFile = hFile;
     
    351340
    352341
    353 static int ossControlStreamIn(/*PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd*/ void)
     342static int ossControlStreamIn(/*PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd*/ void)
    354343{
    355344    /** @todo Nothing to do here right now!? */
     
    359348
    360349
    361 static int ossControlStreamOut(PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
    362 {
    363     POSSAUDIOSTREAMOUT pStreamOut = (POSSAUDIOSTREAMOUT)pStream;
     350static int ossControlStreamOut(PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
     351{
     352    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
    364353
    365354    int rc = VINF_SUCCESS;
     
    370359        case PDMAUDIOSTREAMCMD_RESUME:
    371360        {
    372             DrvAudioHlpClearBuf(&pStreamOut->Props, pStreamOut->pvBuf, pStreamOut->cbBuf,
    373                                 PDMAUDIOPCMPROPS_B2S(&pStreamOut->Props, pStreamOut->cbBuf));
     361            DrvAudioHlpClearBuf(&pStreamOSS->pCfg->Props, pStreamOSS->pvBuf, pStreamOSS->cbBuf,
     362                                PDMAUDIOPCMPROPS_B2S(&pStreamOSS->pCfg->Props, pStreamOSS->cbBuf));
    374363
    375364            int mask = PCM_ENABLE_OUTPUT;
    376             if (ioctl(pStreamOut->hFile, SNDCTL_DSP_SETTRIGGER, &mask) < 0)
     365            if (ioctl(pStreamOSS->hFile, SNDCTL_DSP_SETTRIGGER, &mask) < 0)
    377366            {
    378367                LogRel(("OSS: Failed to enable output stream: %s\n", strerror(errno)));
     
    387376        {
    388377            int mask = 0;
    389             if (ioctl(pStreamOut->hFile, SNDCTL_DSP_SETTRIGGER, &mask) < 0)
     378            if (ioctl(pStreamOSS->hFile, SNDCTL_DSP_SETTRIGGER, &mask) < 0)
    390379            {
    391380                LogRel(("OSS: Failed to disable output stream: %s\n", strerror(errno)));
     
    402391    }
    403392
    404     LogFlowFuncLeaveRC(rc);
    405393    return rc;
    406394}
     
    414402    RT_NOREF(pInterface);
    415403
    416     LogFlowFuncEnter();
    417 
    418404    return VINF_SUCCESS;
    419405}
     
    423409 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture}
    424410 */
    425 static DECLCALLBACK(int) drvHostOSSAudioStreamCapture(PPDMIHOSTAUDIO pInterface,
    426                                                       PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
    427 {
    428     RT_NOREF(pInterface, cbBuf, pvBuf);
     411static DECLCALLBACK(int) drvHostOSSAudioStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
     412                                                      void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
     413{
     414    RT_NOREF(pInterface);
    429415    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    430416
    431     POSSAUDIOSTREAMIN pStreamOSS = (POSSAUDIOSTREAMIN)pStream;
     417    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
    432418
    433419    int rc = VINF_SUCCESS;
     
    501487
    502488
    503 static int ossDestroyStreamIn(PPDMAUDIOSTREAM pStream)
    504 {
    505     POSSAUDIOSTREAMIN pStrm = (POSSAUDIOSTREAMIN)pStream;
     489static int ossDestroyStreamIn(PPDMAUDIOBACKENDSTREAM pStream)
     490{
     491    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
    506492
    507493    LogFlowFuncEnter();
    508494
    509     if (pStrm->pvBuf)
    510     {
    511         Assert(pStrm->cbBuf);
    512 
    513         RTMemFree(pStrm->pvBuf);
    514         pStrm->pvBuf = NULL;
    515     }
    516 
    517     pStrm->cbBuf = 0;
    518 
    519     ossStreamClose(&pStrm->hFile);
     495    if (pStreamOSS->pvBuf)
     496    {
     497        Assert(pStreamOSS->cbBuf);
     498
     499        RTMemFree(pStreamOSS->pvBuf);
     500        pStreamOSS->pvBuf = NULL;
     501    }
     502
     503    pStreamOSS->cbBuf = 0;
     504
     505    ossStreamClose(&pStreamOSS->hFile);
    520506
    521507    return VINF_SUCCESS;
     
    523509
    524510
    525 static int ossDestroyStreamOut(PPDMAUDIOSTREAM pStream)
    526 {
    527     POSSAUDIOSTREAMOUT pStrm = (POSSAUDIOSTREAMOUT)pStream;
    528 
    529     LogFlowFuncEnter();
     511static int ossDestroyStreamOut(PPDMAUDIOBACKENDSTREAM pStream)
     512{
     513    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
    530514
    531515#ifndef RT_OS_L4
    532     if (pStrm->fMMIO)
    533     {
    534         if (pStrm->pvBuf)
    535         {
    536             Assert(pStrm->cbBuf);
    537 
    538             int rc2 = munmap(pStrm->pvBuf, pStrm->cbBuf);
     516    if (pStreamOSS->Out.fMMIO)
     517    {
     518        if (pStreamOSS->pvBuf)
     519        {
     520            Assert(pStreamOSS->cbBuf);
     521
     522            int rc2 = munmap(pStreamOSS->pvBuf, pStreamOSS->cbBuf);
    539523            if (rc2 == 0)
    540524            {
    541                 pStrm->pvBuf      = NULL;
    542                 pStrm->cbBuf      = 0;
    543 
    544                 pStrm->fMMIO      = false;
     525                pStreamOSS->pvBuf      = NULL;
     526                pStreamOSS->cbBuf      = 0;
     527
     528                pStreamOSS->Out.fMMIO  = false;
    545529            }
    546530            else
     
    551535    {
    552536#endif
    553         if (pStrm->pvBuf)
    554         {
    555             Assert(pStrm->cbBuf);
    556 
    557             RTMemFree(pStrm->pvBuf);
    558             pStrm->pvBuf = NULL;
    559         }
    560 
    561         pStrm->cbBuf = 0;
     537        if (pStreamOSS->pvBuf)
     538        {
     539            Assert(pStreamOSS->cbBuf);
     540
     541            RTMemFree(pStreamOSS->pvBuf);
     542            pStreamOSS->pvBuf = NULL;
     543        }
     544
     545        pStreamOSS->cbBuf = 0;
    562546#ifndef RT_OS_L4
    563547    }
    564548#endif
    565549
    566     ossStreamClose(&pStrm->hFile);
     550    ossStreamClose(&pStreamOSS->hFile);
    567551
    568552    return VINF_SUCCESS;
     
    577561    RT_NOREF(pInterface);
    578562
    579     pBackendCfg->cbStreamIn  = sizeof(OSSAUDIOSTREAMIN);
    580     pBackendCfg->cbStreamOut = sizeof(OSSAUDIOSTREAMOUT);
     563    pBackendCfg->cbStreamIn  = sizeof(OSSAUDIOSTREAM);
     564    pBackendCfg->cbStreamOut = sizeof(OSSAUDIOSTREAM);
    581565
    582566    int hFile = open("/dev/dsp", O_WRONLY | O_NONBLOCK, 0);
     
    636620
    637621
    638 static int ossCreateStreamIn(PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    639 {
    640     POSSAUDIOSTREAMIN pStrm = (POSSAUDIOSTREAMIN)pStream;
    641 
     622static int ossCreateStreamIn(POSSAUDIOSTREAM pStreamOSS, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     623{
    642624    int rc;
     625
    643626    int hFile = -1;
    644627
    645628    do
    646629    {
    647         uint32_t cSamples;
    648 
    649         OSSAUDIOSTREAMCFG reqStream, obtStream;
    650         reqStream.enmFormat      = pCfgReq->enmFormat;
    651         reqStream.uFreq          = pCfgReq->uHz;
    652         reqStream.cChannels      = pCfgReq->cChannels;
    653         reqStream.cFragments     = s_OSSConf.nfrags;
    654         reqStream.cbFragmentSize = s_OSSConf.fragsize;
    655 
    656         rc = ossStreamOpen(s_OSSConf.devpath_in, O_RDONLY | O_NONBLOCK, &reqStream, &obtStream, &hFile);
     630        OSSAUDIOSTREAMCFG ossReq;
     631        memcpy(&ossReq.Props, &pCfgReq->Props, sizeof(PDMAUDIOPCMPROPS));
     632
     633        ossReq.cFragments     = s_OSSConf.nfrags;
     634        ossReq.cbFragmentSize = s_OSSConf.fragsize;
     635
     636        OSSAUDIOSTREAMCFG ossAcq;
     637
     638        rc = ossStreamOpen(s_OSSConf.devpath_in, O_RDONLY | O_NONBLOCK, &ossReq, &ossAcq, &hFile);
    657639        if (RT_SUCCESS(rc))
    658640        {
    659             pCfgAcq->enmFormat     = obtStream.enmFormat;
    660             pCfgAcq->uHz           = obtStream.uFreq;
    661             pCfgAcq->cChannels     = obtStream.cChannels;
    662             pCfgAcq->enmEndianness = obtStream.enmENDIANNESS;
    663 
    664             rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &pStrm->Props);
     641            memcpy(&pCfgAcq->Props, &ossAcq.Props, sizeof(PDMAUDIOPCMPROPS));
     642
     643            if (ossAcq.cFragments * ossAcq.cbFragmentSize & pStreamOSS->uAlign)
     644            {
     645                LogRel(("OSS: Warning: Misaligned capturing buffer: Size = %zu, Alignment = %u\n",
     646                        ossAcq.cFragments * ossAcq.cbFragmentSize, pStreamOSS->uAlign + 1));
     647            }
     648
     649            uint32_t cSamples = PDMAUDIOSTREAMCFG_B2S(pCfgAcq, ossAcq.cFragments * ossAcq.cbFragmentSize);
     650            if (!cSamples)
     651                rc = VERR_INVALID_PARAMETER;
     652
    665653            if (RT_SUCCESS(rc))
    666654            {
    667                 if (obtStream.cFragments * obtStream.cbFragmentSize & pStrm->Props.uAlign)
    668                 {
    669                     LogRel(("OSS: Warning: Misaligned capturing buffer: Size = %zu, Alignment = %u\n",
    670                             obtStream.cFragments * obtStream.cbFragmentSize, pStrm->Props.uAlign + 1));
    671                 }
    672 
    673                 cSamples = (obtStream.cFragments * obtStream.cbFragmentSize) >> pStrm->Props.cShift;
    674                 if (!cSamples)
    675                     rc = VERR_INVALID_PARAMETER;
    676             }
    677 
    678             if (RT_SUCCESS(rc))
    679             {
    680                 size_t cbSample = (1 << pStrm->Props.cShift);
    681 
    682                 size_t cbBuf = cSamples * cbSample;
     655                size_t cbBuf = PDMAUDIOSTREAMCFG_S2B(pCfgAcq, cSamples);
    683656                void  *pvBuf = RTMemAlloc(cbBuf);
    684657                if (!pvBuf)
    685658                {
    686                     LogRel(("OSS: Failed allocating capturing buffer with %RU32 samples (%zu bytes per sample)\n",
    687                             cSamples, cbSample));
     659                    LogRel(("OSS: Failed allocating capturing buffer with (%zu bytes)\n", cbBuf));
    688660                    rc = VERR_NO_MEMORY;
    689                     break;
    690661                }
    691662
    692                 pStrm->hFile = hFile;
    693                 pStrm->pvBuf = pvBuf;
    694                 pStrm->cbBuf = cbBuf;
    695 
    696                 pCfgAcq->cSampleBufferSize = cSamples;
     663                pStreamOSS->hFile = hFile;
     664                pStreamOSS->pvBuf = pvBuf;
     665                pStreamOSS->cbBuf = cbBuf;
     666
     667                pCfgAcq->cSampleBufferHint = cSamples;
    697668            }
    698669        }
     
    708679
    709680
    710 static int ossCreateStreamOut(PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    711 {
    712     POSSAUDIOSTREAMOUT pStrm = (POSSAUDIOSTREAMOUT)pStream;
    713 
     681static int ossCreateStreamOut(POSSAUDIOSTREAM pStreamOSS, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     682{
    714683    int rc;
    715684    int hFile = -1;
     
    720689
    721690        OSSAUDIOSTREAMCFG reqStream, obtStream;
    722         reqStream.enmFormat      = pCfgReq->enmFormat;
    723         reqStream.uFreq          = pCfgReq->uHz;
    724         reqStream.cChannels      = pCfgReq->cChannels;
     691
     692        memcpy(&reqStream.Props, &pCfgReq->Props, sizeof(PDMAUDIOPCMPROPS));
     693
    725694        reqStream.cFragments     = s_OSSConf.nfrags;
    726695        reqStream.cbFragmentSize = s_OSSConf.fragsize;
     
    729698        if (RT_SUCCESS(rc))
    730699        {
    731             pCfgAcq->enmFormat     = obtStream.enmFormat;
    732             pCfgAcq->uHz           = obtStream.uFreq;
    733             pCfgAcq->cChannels     = obtStream.cChannels;
    734             pCfgAcq->enmEndianness = obtStream.enmENDIANNESS;
    735 
    736             rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &pStrm->Props);
    737             if (RT_SUCCESS(rc))
    738             {
    739                 cSamples = (obtStream.cFragments * obtStream.cbFragmentSize) >> pStrm->Props.cShift;
    740 
    741                 if (obtStream.cFragments * obtStream.cbFragmentSize & pStrm->Props.uAlign)
    742                 {
    743                     LogRel(("OSS: Warning: Misaligned playback buffer: Size = %zu, Alignment = %u\n",
    744                             obtStream.cFragments * obtStream.cbFragmentSize, pStrm->Props.uAlign + 1));
    745                 }
     700            memcpy(&pCfgAcq->Props, &obtStream.Props, sizeof(PDMAUDIOPCMPROPS));
     701
     702            cSamples = PDMAUDIOSTREAMCFG_B2S(pCfgAcq, obtStream.cFragments * obtStream.cbFragmentSize);
     703
     704            if (obtStream.cFragments * obtStream.cbFragmentSize & pStreamOSS->uAlign)
     705            {
     706                LogRel(("OSS: Warning: Misaligned playback buffer: Size = %zu, Alignment = %u\n",
     707                        obtStream.cFragments * obtStream.cbFragmentSize, pStreamOSS->uAlign + 1));
    746708            }
    747709        }
     
    749711        if (RT_SUCCESS(rc))
    750712        {
    751             pStrm->fMMIO = false;
    752 
    753             size_t cbSample = (1 << pStrm->Props.cShift);
    754 
    755             size_t cbSamples = cSamples * cbSample;
    756             Assert(cbSamples);
     713            pStreamOSS->Out.fMMIO = false;
     714
     715            size_t cbBuf = PDMAUDIOSTREAMCFG_S2B(pCfgAcq, cSamples);
     716            Assert(cbBuf);
    757717
    758718#ifndef RT_OS_L4
    759719            if (s_OSSConf.try_mmap)
    760720            {
    761                 pStrm->pvBuf = mmap(0, cbSamples, PROT_READ | PROT_WRITE, MAP_SHARED, hFile, 0);
    762                 if (pStrm->pvBuf == MAP_FAILED)
     721                pStreamOSS->pvBuf = mmap(0, cbBuf, PROT_READ | PROT_WRITE, MAP_SHARED, hFile, 0);
     722                if (pStreamOSS->pvBuf == MAP_FAILED)
    763723                {
    764                     LogRel(("OSS: Failed to memory map %zu bytes of playback buffer: %s\n", cbSamples, strerror(errno)));
     724                    LogRel(("OSS: Failed to memory map %zu bytes of playback buffer: %s\n", cbBuf, strerror(errno)));
    765725                    rc = RTErrConvertFromErrno(errno);
    766726                    break;
     
    786746                        else
    787747                        {
    788                             pStrm->fMMIO = true;
     748                            pStreamOSS->Out.fMMIO = true;
    789749                            LogRel(("OSS: Using MMIO\n"));
    790750                        }
     
    793753                    if (RT_FAILURE(rc))
    794754                    {
    795                         int rc2 = munmap(pStrm->pvBuf, cbSamples);
     755                        int rc2 = munmap(pStreamOSS->pvBuf, cbBuf);
    796756                        if (rc2)
    797757                            LogRel(("OSS: Failed to memory unmap playback buffer: %s\n", strerror(errno)));
     
    804764            /* Memory mapping failed above? Try allocating an own buffer. */
    805765#ifndef RT_OS_L4
    806             if (!pStrm->fMMIO)
    807             {
    808 #endif
    809                 void *pvBuf = RTMemAlloc(cbSamples);
     766            if (!pStreamOSS->Out.fMMIO)
     767            {
     768#endif
     769                void *pvBuf = RTMemAlloc(cbBuf);
    810770                if (!pvBuf)
    811771                {
    812                     LogRel(("OSS: Failed allocating playback buffer with %RU32 samples (%zu bytes)\n", cSamples, cbSamples));
     772                    LogRel(("OSS: Failed allocating playback buffer with %RU32 samples (%zu bytes)\n", cSamples, cbBuf));
    813773                    rc = VERR_NO_MEMORY;
    814774                    break;
    815775                }
    816776
    817                 pStrm->hFile = hFile;
    818                 pStrm->pvBuf = pvBuf;
    819                 pStrm->cbBuf = cbSamples;
     777                pStreamOSS->hFile = hFile;
     778                pStreamOSS->pvBuf = pvBuf;
     779                pStreamOSS->cbBuf = cbBuf;
    820780#ifndef RT_OS_L4
    821781            }
    822782#endif
    823             pCfgAcq->cSampleBufferSize = cSamples;
     783            pCfgAcq->cSampleBufferHint = cSamples;
    824784        }
    825785
     
    838798 */
    839799static DECLCALLBACK(int) drvHostOSSAudioStreamPlay(PPDMIHOSTAUDIO pInterface,
    840                                                    PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf,
     800                                                   PPDMAUDIOBACKENDSTREAM pStream, const void *pvBuf, uint32_t cbBuf,
    841801                                                   uint32_t *pcbWritten)
    842802{
    843     RT_NOREF(pInterface, cbBuf, pvBuf);
     803    RT_NOREF(pInterface);
    844804    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    845805
    846     POSSAUDIOSTREAMOUT pStreamOSS = (POSSAUDIOSTREAMOUT)pStream;
     806    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
    847807
    848808    int rc = VINF_SUCCESS;
     
    855815    do
    856816    {
    857         uint32_t cbAvail = PDMAUDIOPCMPROPS_S2B(&pStreamOSS->Props, cbBuf);
    858         uint32_t cbToRead;
     817        uint32_t cbAvail = cbBuf;
     818        uint32_t cbToWrite;
    859819
    860820#ifndef RT_OS_L4
    861         if (pStreamOSS->fMMIO)
     821        if (pStreamOSS->Out.fMMIO)
    862822        {
    863823            /* Get current playback pointer. */
     
    881841            Assert(cbData >= 0);
    882842
    883             cbToRead = RT_MIN((unsigned)cbData, cbAvail);
     843            cbToWrite = RT_MIN((unsigned)cbData, cbAvail);
    884844        }
    885845        else
     
    909869            }
    910870
    911             cbToRead = RT_MIN(unsigned(abinfo.fragments * abinfo.fragsize), cbAvail);
     871            cbToWrite = RT_MIN(unsigned(abinfo.fragments * abinfo.fragsize), cbAvail);
    912872#ifndef RT_OS_L4
    913873        }
    914874#endif
    915         while (cbToRead)
    916         {
    917             uint32_t cbRead     = cbToRead;
    918 
    919             memcpy(pStreamOSS->pvBuf, pvBuf, cbRead);
    920 
    921             uint32_t cbChunk    = cbRead;
     875        cbToWrite = RT_MIN(cbToWrite, pStreamOSS->cbBuf);
     876
     877        while (cbToWrite)
     878        {
     879            uint32_t cbWritten = cbToWrite;
     880
     881            memcpy(pStreamOSS->pvBuf, pvBuf, cbWritten);
     882
     883            uint32_t cbChunk    = cbWritten;
    922884            uint32_t cbChunkOff = 0;
    923885            while (cbChunk)
     
    932894                }
    933895
    934                 if (cbChunkWritten & pStreamOSS->Props.uAlign)
     896                if (cbChunkWritten & pStreamOSS->uAlign)
    935897                {
    936898                    LogRel(("OSS: Misaligned write (written %z, expected %RU32)\n", cbChunkWritten, cbChunk));
     
    939901
    940902                cbChunkOff += (uint32_t)cbChunkWritten;
    941                 Assert(cbChunkOff <= cbRead);
     903                Assert(cbChunkOff <= cbWritten);
    942904                Assert(cbChunk    >= (uint32_t)cbChunkWritten);
    943905                cbChunk    -= (uint32_t)cbChunkWritten;
    944906            }
    945907
    946             Assert(cbToRead >= cbRead);
    947             cbToRead       -= cbRead;
    948             cbWrittenTotal += cbRead;
     908            Assert(cbToWrite >= cbWritten);
     909            cbToWrite      -= cbWritten;
     910            cbWrittenTotal += cbWritten;
    949911        }
    950912
    951913#ifndef RT_OS_L4
    952914        /* Update read pointer. */
    953         if (pStreamOSS->fMMIO)
     915        if (pStreamOSS->Out.fMMIO)
    954916            pStreamOSS->old_optr = cntinfo.ptr;
    955917#endif
     
    991953 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate}
    992954 */
    993 static DECLCALLBACK(int) drvHostOSSAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream,
     955static DECLCALLBACK(int) drvHostOSSAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
    994956                                                     PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    995957{
     
    999961    AssertPtrReturn(pCfgAcq,    VERR_INVALID_POINTER);
    1000962
     963    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
     964
    1001965    int rc;
    1002966    if (pCfgReq->enmDir == PDMAUDIODIR_IN)
    1003         rc = ossCreateStreamIn(pStream, pCfgReq, pCfgAcq);
     967        rc = ossCreateStreamIn (pStreamOSS, pCfgReq, pCfgAcq);
    1004968    else
    1005         rc = ossCreateStreamOut(pStream, pCfgReq, pCfgAcq);
     969        rc = ossCreateStreamOut(pStreamOSS, pCfgReq, pCfgAcq);
     970
     971    if (RT_SUCCESS(rc))
     972    {
     973        pStreamOSS->pCfg = DrvAudioHlpStreamCfgDup(pCfgAcq);
     974        if (!pStreamOSS->pCfg)
     975            rc = VERR_NO_MEMORY;
     976    }
    1006977
    1007978    return rc;
     
    1012983 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy}
    1013984 */
    1014 static DECLCALLBACK(int) drvHostOSSAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     985static DECLCALLBACK(int) drvHostOSSAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    1015986{
    1016987    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    1017988    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    1018989
     990    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
     991
     992    if (!pStreamOSS->pCfg) /* Not (yet) configured? Skip. */
     993        return VINF_SUCCESS;
     994
    1019995    int rc;
    1020     if (pStream->enmDir == PDMAUDIODIR_IN)
     996    if (pStreamOSS->pCfg->enmDir == PDMAUDIODIR_IN)
    1021997        rc = ossDestroyStreamIn(pStream);
    1022998    else
    1023999        rc = ossDestroyStreamOut(pStream);
    10241000
     1001    if (RT_SUCCESS(rc))
     1002    {
     1003        DrvAudioHlpStreamCfgFree(pStreamOSS->pCfg);
     1004        pStreamOSS->pCfg = NULL;
     1005    }
     1006
    10251007    return rc;
    10261008}
     
    10301012 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl}
    10311013 */
    1032 static DECLCALLBACK(int) drvHostOSSAudioStreamControl(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream,
     1014static DECLCALLBACK(int) drvHostOSSAudioStreamControl(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
    10331015                                                      PDMAUDIOSTREAMCMD enmStreamCmd)
    10341016{
     
    10361018    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    10371019
    1038     Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST);
     1020    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
     1021
     1022    if (!pStreamOSS->pCfg) /* Not (yet) configured? Skip. */
     1023        return VINF_SUCCESS;
    10391024
    10401025    int rc;
    1041     if (pStream->enmDir == PDMAUDIODIR_IN)
     1026    if (pStreamOSS->pCfg->enmDir == PDMAUDIODIR_IN)
    10421027        rc = ossControlStreamIn(/*pInterface,  pStream, enmStreamCmd*/);
    10431028    else
    1044         rc = ossControlStreamOut(pStream, enmStreamCmd);
     1029        rc = ossControlStreamOut(pStreamOSS, enmStreamCmd);
    10451030
    10461031    return rc;
     
    10511036 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate}
    10521037 */
    1053 static DECLCALLBACK(int) drvHostOSSAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     1038static DECLCALLBACK(int) drvHostOSSAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    10541039{
    10551040    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     
    10661051 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
    10671052 */
    1068 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostOSSAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     1053static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostOSSAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    10691054{
    10701055    RT_NOREF(pInterface);
    1071     RT_NOREF(pStream);
     1056
     1057    POSSAUDIOSTREAM pStreamOSS = (POSSAUDIOSTREAM)pStream;
    10721058
    10731059    PDMAUDIOSTRMSTS strmSts =   PDMAUDIOSTRMSTS_FLAG_INITIALIZED
    10741060                              | PDMAUDIOSTRMSTS_FLAG_ENABLED;
    10751061
    1076     strmSts |=   pStream->enmDir == PDMAUDIODIR_IN
     1062    strmSts |=   pStreamOSS->pCfg->enmDir == PDMAUDIODIR_IN
    10771063               ? PDMAUDIOSTRMSTS_FLAG_DATA_READABLE
    10781064               : PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE;
  • trunk/src/VBox/Devices/Audio/DrvHostPulseAudio.cpp

    r65565 r65624  
    9696typedef struct PULSEAUDIOSTREAM
    9797{
    98     /** Associated host input/output stream.
    99      *  Note: Always must come first! */
    100     PDMAUDIOSTREAM         Stream;
    101     PDMAUDIOPCMPROPS       Props;
     98    /** The stream's acquired configuration. */
     99    PPDMAUDIOSTREAMCFG     pCfg;
    102100    /** Pointer to driver instance. */
    103101    PDRVHOSTPULSEAUDIO     pDrv;
    104102    /** Pointer to opaque PulseAudio stream. */
    105     pa_stream             *pPAStream;
     103    pa_stream             *pStream;
    106104    /** Pulse sample format and attribute specification. */
    107105    pa_sample_spec         SampleSpec;
     
    199197
    200198
    201 static pa_sample_format_t paFmtToPulse(PDMAUDIOFMT fmt)
    202 {
    203     switch (fmt)
    204     {
    205         case PDMAUDIOFMT_U8:
    206             return PA_SAMPLE_U8;
    207 
    208         case PDMAUDIOFMT_S16:
    209             return PA_SAMPLE_S16LE;
     199static pa_sample_format_t paAudioPropsToPulse(PPDMAUDIOPCMPROPS pProps)
     200{
     201    switch (pProps->cBits)
     202    {
     203        case 8:
     204            if (!pProps->fSigned)
     205                return PA_SAMPLE_U8;
     206
     207        case 16:
     208            if (pProps->fSigned)
     209                return PA_SAMPLE_S16LE;
    210210
    211211#ifdef PA_SAMPLE_S32LE
    212         case PDMAUDIOFMT_S32:
    213             return PA_SAMPLE_S32LE;
     212        case 32:
     213            if (pProps->fSigned)
     214                return PA_SAMPLE_S32LE;
    214215#endif
    215216        default:
     
    217218    }
    218219
    219     AssertMsgFailed(("Format %ld not supported\n", fmt));
    220     return PA_SAMPLE_U8;
    221 }
    222 
    223 
    224 static int paPulseToFmt(pa_sample_format_t pulsefmt,
    225                         PDMAUDIOFMT *pFmt, PDMAUDIOENDIANNESS *pEndianness)
     220    AssertMsgFailed(("%RU8%s not supported\n", pProps->cBits, pProps->fSigned ? "S" : "U"));
     221    return PA_SAMPLE_INVALID;
     222}
     223
     224
     225static int paPulseToAudioProps(pa_sample_format_t pulsefmt, PPDMAUDIOPCMPROPS pProps)
    226226{
    227227    switch (pulsefmt)
    228228    {
    229229        case PA_SAMPLE_U8:
    230             *pFmt = PDMAUDIOFMT_U8;
    231             *pEndianness = PDMAUDIOENDIANNESS_LITTLE;
     230            pProps->cBits   = 8;
     231            pProps->fSigned = false;
    232232            break;
    233233
    234234        case PA_SAMPLE_S16LE:
    235             *pFmt = PDMAUDIOFMT_S16;
    236             *pEndianness = PDMAUDIOENDIANNESS_LITTLE;
     235            pProps->cBits   = 16;
     236            pProps->fSigned = true;
    237237            break;
    238238
    239239        case PA_SAMPLE_S16BE:
    240             *pFmt = PDMAUDIOFMT_S16;
    241             *pEndianness = PDMAUDIOENDIANNESS_BIG;
     240            pProps->cBits   = 16;
     241            pProps->fSigned = true;
     242            /** @todo Handle Endianess. */
    242243            break;
    243244
    244245#ifdef PA_SAMPLE_S32LE
    245246        case PA_SAMPLE_S32LE:
    246             *pFmt = PDMAUDIOFMT_S32;
    247             *pEndianness = PDMAUDIOENDIANNESS_LITTLE;
     247            pProps->cBits   = 32;
     248            pProps->fSigned = true;
    248249            break;
    249250#endif
     
    251252#ifdef PA_SAMPLE_S32BE
    252253        case PA_SAMPLE_S32BE:
    253             *pFmt = PDMAUDIOFMT_S32;
    254             *pEndianness = PDMAUDIOENDIANNESS_BIG;
     254            pProps->cBits   = 32;
     255            pProps->fSigned = true;
     256            /** @todo Handle Endianess. */
    255257            break;
    256258#endif
     
    649651
    650652
    651 static int paCreateStreamOut(PPDMIHOSTAUDIO pInterface,
    652                              PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    653 {
    654     PDRVHOSTPULSEAUDIO pThis     = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
    655     PPULSEAUDIOSTREAM  pStreamPA = (PPULSEAUDIOSTREAM)pStream;
    656 
    657     LogFlowFuncEnter();
    658 
     653static int paCreateStreamOut(PDRVHOSTPULSEAUDIO pThis, PPULSEAUDIOSTREAM pStreamPA,
     654                             PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     655{
    659656    pStreamPA->pDrainOp            = NULL;
    660657
    661     pStreamPA->SampleSpec.format   = paFmtToPulse(pCfgReq->enmFormat);
    662     pStreamPA->SampleSpec.rate     = pCfgReq->uHz;
    663     pStreamPA->SampleSpec.channels = pCfgReq->cChannels;
     658    pStreamPA->SampleSpec.format   = paAudioPropsToPulse(&pCfgReq->Props);
     659    pStreamPA->SampleSpec.rate     = pCfgReq->Props.uHz;
     660    pStreamPA->SampleSpec.channels = pCfgReq->Props.cChannels;
    664661
    665662    /* Note that setting maxlength to -1 does not work on PulseAudio servers
     
    672669
    673670    /* Note that the struct BufAttr is updated to the obtained values after this call! */
    674     int rc = paStreamOpen(pThis, false /* fIn */, "PulseAudio (Out)", &pStreamPA->SampleSpec, &pStreamPA->BufAttr, &pStreamPA->pPAStream);
     671    int rc = paStreamOpen(pThis, false /* fIn */, "PulseAudio (Out)",
     672                          &pStreamPA->SampleSpec, &pStreamPA->BufAttr, &pStreamPA->pStream);
    675673    if (RT_FAILURE(rc))
    676674        return rc;
    677675
    678     rc = paPulseToFmt(pStreamPA->SampleSpec.format,
    679                       &pCfgAcq->enmFormat, &pCfgAcq->enmEndianness);
     676    rc = paPulseToAudioProps(pStreamPA->SampleSpec.format, &pCfgAcq->Props);
    680677    if (RT_FAILURE(rc))
    681678    {
     
    684681    }
    685682
    686     pCfgAcq->uHz       = pStreamPA->SampleSpec.rate;
    687     pCfgAcq->cChannels = pStreamPA->SampleSpec.channels;
    688 
    689     rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &pStreamPA->Props);
    690     if (RT_SUCCESS(rc))
    691     {
    692         uint32_t cbBuf  = RT_MIN(pStreamPA->BufAttr.tlength * 2,
    693                                  pStreamPA->BufAttr.maxlength); /** @todo Make this configurable! */
    694         if (cbBuf)
    695         {
    696             pStreamPA->pDrv     = pThis;
    697 
    698             pCfgAcq->cSampleBufferSize = PDMAUDIOPCMPROPS_B2S(&pStreamPA->Props, cbBuf);
    699         }
    700         else
    701             rc = VERR_INVALID_PARAMETER;
    702     }
    703 
    704     LogFlowFuncLeaveRC(rc);
     683    pCfgAcq->Props.uHz       = pStreamPA->SampleSpec.rate;
     684    pCfgAcq->Props.cChannels = pStreamPA->SampleSpec.channels;
     685    pCfgAcq->Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfgAcq->Props.cBits, pCfgAcq->Props.cChannels);
     686
     687    uint32_t cbBuf = RT_MIN(pStreamPA->BufAttr.tlength * 2,
     688                            pStreamPA->BufAttr.maxlength); /** @todo Make this configurable! */
     689    if (cbBuf)
     690    {
     691        pCfgAcq->cSampleBufferHint = PDMAUDIOSTREAMCFG_B2S(pCfgAcq, cbBuf);
     692
     693        pStreamPA->pDrv = pThis;
     694    }
     695    else
     696        rc = VERR_INVALID_PARAMETER;
     697
    705698    return rc;
    706699}
    707700
    708701
    709 static int paCreateStreamIn(PPDMIHOSTAUDIO pInterface,
    710                             PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    711 {
    712     PDRVHOSTPULSEAUDIO pThis     = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
    713     PPULSEAUDIOSTREAM  pStreamPA = (PPULSEAUDIOSTREAM)pStream;
    714 
    715     pStreamPA->SampleSpec.format   = paFmtToPulse(pCfgReq->enmFormat);
    716     pStreamPA->SampleSpec.rate     = pCfgReq->uHz;
    717     pStreamPA->SampleSpec.channels = pCfgReq->cChannels;
     702static int paCreateStreamIn(PDRVHOSTPULSEAUDIO pThis, PPULSEAUDIOSTREAM  pStreamPA,
     703                            PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     704{
     705    pStreamPA->SampleSpec.format   = paAudioPropsToPulse(&pCfgReq->Props);
     706    pStreamPA->SampleSpec.rate     = pCfgReq->Props.uHz;
     707    pStreamPA->SampleSpec.channels = pCfgReq->Props.cChannels;
    718708
    719709    /** @todo Check these values! */
     
    723713    /* Note: Other members of BufAttr are ignored for record streams. */
    724714    int rc = paStreamOpen(pThis, true /* fIn */, "PulseAudio (In)", &pStreamPA->SampleSpec, &pStreamPA->BufAttr,
    725                           &pStreamPA->pPAStream);
     715                          &pStreamPA->pStream);
    726716    if (RT_FAILURE(rc))
    727717        return rc;
    728718
    729     rc = paPulseToFmt(pStreamPA->SampleSpec.format, &pCfgAcq->enmFormat, &pCfgAcq->enmEndianness);
     719    rc = paPulseToAudioProps(pStreamPA->SampleSpec.format, &pCfgAcq->Props);
    730720    if (RT_FAILURE(rc))
    731721    {
     
    734724    }
    735725
    736     rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &pStreamPA->Props);
    737     if (RT_SUCCESS(rc))
    738     {
    739         pStreamPA->pDrv       = pThis;
    740         pStreamPA->pu8PeekBuf = NULL;
    741 
    742         pCfgAcq->uHz               = pStreamPA->SampleSpec.rate;
    743         pCfgAcq->cChannels         = pStreamPA->SampleSpec.channels;
    744         pCfgAcq->cSampleBufferSize = PDMAUDIOPCMPROPS_B2S(&pStreamPA->Props,
    745                                                           RT_MIN(pStreamPA->BufAttr.fragsize * 10, pStreamPA->BufAttr.maxlength));
    746     }
     726    pStreamPA->pDrv       = pThis;
     727    pStreamPA->pu8PeekBuf = NULL;
     728
     729    pCfgAcq->Props.uHz         = pStreamPA->SampleSpec.rate;
     730    pCfgAcq->Props.cChannels   = pStreamPA->SampleSpec.channels;
     731    pCfgAcq->cSampleBufferHint = PDMAUDIOSTREAMCFG_B2S(pCfgAcq,
     732                                                       RT_MIN(pStreamPA->BufAttr.fragsize * 10, pStreamPA->BufAttr.maxlength));
    747733
    748734    LogFlowFuncLeaveRC(rc);
     
    755741 */
    756742static DECLCALLBACK(int) drvHostPulseAudioStreamCapture(PPDMIHOSTAUDIO pInterface,
    757                                                         PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
     743                                                        PPDMAUDIOBACKENDSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
    758744{
    759745    RT_NOREF(pvBuf, cbBuf);
     
    769755    /* We should only call pa_stream_readable_size() once and trust the first value. */
    770756    pa_threaded_mainloop_lock(pThis->pMainLoop);
    771     size_t cbAvail = pa_stream_readable_size(pStreamPA->pPAStream);
     757    size_t cbAvail = pa_stream_readable_size(pStreamPA->pStream);
    772758    pa_threaded_mainloop_unlock(pThis->pMainLoop);
    773759
     
    806792        {
    807793            pa_threaded_mainloop_lock(pThis->pMainLoop);
    808             pa_stream_peek(pStreamPA->pPAStream,
     794            pa_stream_peek(pStreamPA->pStream,
    809795                           (const void**)&pStreamPA->pu8PeekBuf, &pStreamPA->cbPeekBuf);
    810796            pa_threaded_mainloop_unlock(pThis->pMainLoop);
     
    849835        {
    850836            pa_threaded_mainloop_lock(pThis->pMainLoop);
    851             pa_stream_drop(pStreamPA->pPAStream);
     837            pa_stream_drop(pStreamPA->pStream);
    852838            pa_threaded_mainloop_unlock(pThis->pMainLoop);
    853839
     
    870856 */
    871857static DECLCALLBACK(int) drvHostPulseAudioStreamPlay(PPDMIHOSTAUDIO pInterface,
    872                                                      PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf,
     858                                                     PPDMAUDIOBACKENDSTREAM pStream, const void *pvBuf, uint32_t cbBuf,
    873859                                                     uint32_t *pcbWritten)
    874860{
     
    891877    do
    892878    {
    893         size_t cbWriteable = pa_stream_writable_size(pPAStream->pPAStream);
     879        size_t cbWriteable = pa_stream_writable_size(pPAStream->pStream);
    894880        if (cbWriteable == (size_t)-1)
    895881        {
     
    904890        {
    905891            cbWritten = cbToWrite;
    906             if (pa_stream_write(pPAStream->pPAStream, (uint8_t *)pvBuf + cbWrittenTotal, cbWritten, NULL /* Cleanup callback */,
     892            if (pa_stream_write(pPAStream->pStream, (uint8_t *)pvBuf + cbWrittenTotal, cbWritten, NULL /* Cleanup callback */,
    907893                                0, PA_SEEK_RELATIVE) < 0)
    908894            {
     
    11201106
    11211107
    1122 static int paDestroyStreamIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
    1123 {
    1124     AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    1125     AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    1126 
    1127     PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
    1128     PPULSEAUDIOSTREAM  pStrm = (PPULSEAUDIOSTREAM)pStream;
    1129 
     1108static int paDestroyStreamIn(PDRVHOSTPULSEAUDIO pThis, PPULSEAUDIOSTREAM pStreamPA)
     1109{
    11301110    LogFlowFuncEnter();
    11311111
    1132     if (pStrm->pPAStream)
     1112    if (pStreamPA->pStream)
    11331113    {
    11341114        pa_threaded_mainloop_lock(pThis->pMainLoop);
    11351115
    1136         pa_stream_disconnect(pStrm->pPAStream);
    1137         pa_stream_unref(pStrm->pPAStream);
    1138 
    1139         pStrm->pPAStream = NULL;
     1116        pa_stream_disconnect(pStreamPA->pStream);
     1117        pa_stream_unref(pStreamPA->pStream);
     1118
     1119        pStreamPA->pStream = NULL;
    11401120
    11411121        pa_threaded_mainloop_unlock(pThis->pMainLoop);
     
    11461126
    11471127
    1148 static int paDestroyStreamOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
    1149 {
    1150     AssertPtrReturn(pInterface,  VERR_INVALID_POINTER);
    1151     AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    1152 
    1153     PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
    1154     PPULSEAUDIOSTREAM  pStrm = (PPULSEAUDIOSTREAM)pStream;
    1155 
    1156     LogFlowFuncEnter();
    1157 
    1158     if (pStrm->pPAStream)
     1128static int paDestroyStreamOut(PDRVHOSTPULSEAUDIO pThis, PPULSEAUDIOSTREAM pStreamPA)
     1129{
     1130    if (pStreamPA->pStream)
    11591131    {
    11601132        pa_threaded_mainloop_lock(pThis->pMainLoop);
    11611133
    11621134        /* Make sure to cancel a pending draining operation, if any. */
    1163         if (pStrm->pDrainOp)
    1164         {
    1165             pa_operation_cancel(pStrm->pDrainOp);
    1166             pStrm->pDrainOp = NULL;
    1167         }
    1168 
    1169         pa_stream_disconnect(pStrm->pPAStream);
    1170         pa_stream_unref(pStrm->pPAStream);
    1171 
    1172         pStrm->pPAStream = NULL;
     1135        if (pStreamPA->pDrainOp)
     1136        {
     1137            pa_operation_cancel(pStreamPA->pDrainOp);
     1138            pStreamPA->pDrainOp = NULL;
     1139        }
     1140
     1141        pa_stream_disconnect(pStreamPA->pStream);
     1142        pa_stream_unref(pStreamPA->pStream);
     1143
     1144        pStreamPA->pStream = NULL;
    11731145
    11741146        pa_threaded_mainloop_unlock(pThis->pMainLoop);
     
    11791151
    11801152
    1181 static int paControlStreamOut(PPDMIHOSTAUDIO pInterface,
    1182                               PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
    1183 {
    1184     AssertPtrReturn(pInterface , VERR_INVALID_POINTER);
    1185     AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    1186 
    1187     PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
    1188     PPULSEAUDIOSTREAM  pStrm = (PPULSEAUDIOSTREAM)pStream;
    1189 
     1153static int paControlStreamOut(PDRVHOSTPULSEAUDIO pThis, PPULSEAUDIOSTREAM pStreamPA, PDMAUDIOSTREAMCMD enmStreamCmd)
     1154{
    11901155    int rc = VINF_SUCCESS;
    1191 
    1192     LogFlowFunc(("enmStreamCmd=%ld\n", enmStreamCmd));
    11931156
    11941157    switch (enmStreamCmd)
     
    11991162            pa_threaded_mainloop_lock(pThis->pMainLoop);
    12001163
    1201             if (   pStrm->pDrainOp
    1202                 && pa_operation_get_state(pStrm->pDrainOp) != PA_OPERATION_DONE)
     1164            if (   pStreamPA->pDrainOp
     1165                && pa_operation_get_state(pStreamPA->pDrainOp) != PA_OPERATION_DONE)
    12031166            {
    1204                 pa_operation_cancel(pStrm->pDrainOp);
    1205                 pa_operation_unref(pStrm->pDrainOp);
    1206 
    1207                 pStrm->pDrainOp = NULL;
     1167                pa_operation_cancel(pStreamPA->pDrainOp);
     1168                pa_operation_unref(pStreamPA->pDrainOp);
     1169
     1170                pStreamPA->pDrainOp = NULL;
    12081171            }
    12091172            else
    12101173            {
    1211                 rc = paWaitFor(pThis, pa_stream_cork(pStrm->pPAStream, 0, paStreamCbSuccess, pStrm));
     1174                rc = paWaitFor(pThis, pa_stream_cork(pStreamPA->pStream, 0, paStreamCbSuccess, pStreamPA));
    12121175            }
    12131176
     
    12221185             * Note that we must return immediately from here! */
    12231186            pa_threaded_mainloop_lock(pThis->pMainLoop);
    1224             if (!pStrm->pDrainOp)
     1187            if (!pStreamPA->pDrainOp)
    12251188            {
    1226                 rc = paWaitFor(pThis, pa_stream_trigger(pStrm->pPAStream, paStreamCbSuccess, pStrm));
     1189                rc = paWaitFor(pThis, pa_stream_trigger(pStreamPA->pStream, paStreamCbSuccess, pStreamPA));
    12271190                if (RT_SUCCESS(rc))
    1228                     pStrm->pDrainOp = pa_stream_drain(pStrm->pPAStream, paStreamCbDrain, pStrm);
     1191                    pStreamPA->pDrainOp = pa_stream_drain(pStreamPA->pStream, paStreamCbDrain, pStreamPA);
    12291192            }
    12301193            pa_threaded_mainloop_unlock(pThis->pMainLoop);
     
    12431206
    12441207
    1245 static int paControlStreamIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream,
    1246                              PDMAUDIOSTREAMCMD enmStreamCmd)
    1247 {
    1248     AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    1249     AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    1250 
    1251     PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
    1252     PPULSEAUDIOSTREAM  pStrm = (PPULSEAUDIOSTREAM)pStream;
    1253 
     1208static int paControlStreamIn(PDRVHOSTPULSEAUDIO pThis, PPULSEAUDIOSTREAM pStreamPA, PDMAUDIOSTREAMCMD enmStreamCmd)
     1209{
    12541210    int rc = VINF_SUCCESS;
    12551211
     
    12621218        {
    12631219            pa_threaded_mainloop_lock(pThis->pMainLoop);
    1264             rc = paWaitFor(pThis, pa_stream_cork(pStrm->pPAStream, 0 /* Play / resume */, paStreamCbSuccess, pStrm));
     1220            rc = paWaitFor(pThis, pa_stream_cork(pStreamPA->pStream, 0 /* Play / resume */, paStreamCbSuccess, pStreamPA));
    12651221            pa_threaded_mainloop_unlock(pThis->pMainLoop);
    12661222            break;
     
    12711227        {
    12721228            pa_threaded_mainloop_lock(pThis->pMainLoop);
    1273             if (pStrm->pu8PeekBuf) /* Do we need to drop the peek buffer?*/
     1229            if (pStreamPA->pu8PeekBuf) /* Do we need to drop the peek buffer?*/
    12741230            {
    1275                 pa_stream_drop(pStrm->pPAStream);
    1276                 pStrm->pu8PeekBuf = NULL;
     1231                pa_stream_drop(pStreamPA->pStream);
     1232                pStreamPA->pu8PeekBuf = NULL;
    12771233            }
    12781234
    1279             rc = paWaitFor(pThis, pa_stream_cork(pStrm->pPAStream, 1 /* Stop / pause */, paStreamCbSuccess, pStrm));
     1235            rc = paWaitFor(pThis, pa_stream_cork(pStreamPA->pStream, 1 /* Stop / pause */, paStreamCbSuccess, pStreamPA));
    12801236            pa_threaded_mainloop_unlock(pThis->pMainLoop);
    12811237            break;
     
    13521308 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate}
    13531309 */
    1354 static DECLCALLBACK(int) drvHostPulseAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     1310static DECLCALLBACK(int) drvHostPulseAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
     1311                                                       PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    13551312{
    13561313    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     
    13591316    AssertPtrReturn(pCfgAcq,    VERR_INVALID_POINTER);
    13601317
     1318    PDRVHOSTPULSEAUDIO pThis     = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
     1319    PPULSEAUDIOSTREAM  pStreamPA = (PPULSEAUDIOSTREAM)pStream;
     1320
    13611321    int rc;
    13621322    if (pCfgReq->enmDir == PDMAUDIODIR_IN)
    1363         rc = paCreateStreamIn(pInterface,  pStream, pCfgReq, pCfgAcq);
    1364     else if (pStream->enmDir == PDMAUDIODIR_OUT)
    1365         rc = paCreateStreamOut(pInterface, pStream, pCfgReq, pCfgAcq);
     1323        rc = paCreateStreamIn (pThis, pStreamPA, pCfgReq, pCfgAcq);
     1324    else if (pCfgReq->enmDir == PDMAUDIODIR_OUT)
     1325        rc = paCreateStreamOut(pThis, pStreamPA, pCfgReq, pCfgAcq);
    13661326    else
    13671327        AssertFailedReturn(VERR_NOT_IMPLEMENTED);
    13681328
     1329    if (RT_SUCCESS(rc))
     1330    {
     1331        pStreamPA->pCfg = DrvAudioHlpStreamCfgDup(pCfgAcq);
     1332        if (!pStreamPA->pCfg)
     1333            rc = VERR_NO_MEMORY;
     1334    }
     1335
    13691336    return rc;
    13701337}
     
    13741341 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy}
    13751342 */
    1376 static DECLCALLBACK(int) drvHostPulseAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     1343static DECLCALLBACK(int) drvHostPulseAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    13771344{
    13781345    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    13791346    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    13801347
     1348    PDRVHOSTPULSEAUDIO pThis     = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
     1349    PPULSEAUDIOSTREAM  pStreamPA = (PPULSEAUDIOSTREAM)pStream;
     1350
     1351    if (!pStreamPA->pCfg) /* Not (yet) configured? Skip. */
     1352        return VINF_SUCCESS;
     1353
    13811354    int rc;
    1382     if (pStream->enmDir == PDMAUDIODIR_IN)
    1383         rc = paDestroyStreamIn(pInterface,  pStream);
    1384     else if (pStream->enmDir == PDMAUDIODIR_OUT)
    1385         rc = paDestroyStreamOut(pInterface, pStream);
     1355    if (pStreamPA->pCfg->enmDir == PDMAUDIODIR_IN)
     1356        rc = paDestroyStreamIn (pThis, pStreamPA);
     1357    else if (pStreamPA->pCfg->enmDir == PDMAUDIODIR_OUT)
     1358        rc = paDestroyStreamOut(pThis, pStreamPA);
    13861359    else
    1387         AssertFailedReturn(VERR_NOT_IMPLEMENTED);
     1360        AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
     1361
     1362    if (RT_SUCCESS(rc))
     1363    {
     1364        DrvAudioHlpStreamCfgFree(pStreamPA->pCfg);
     1365        pStreamPA->pCfg = NULL;
     1366    }
    13881367
    13891368    return rc;
     
    13941373 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl}
    13951374 */
    1396 static DECLCALLBACK(int) drvHostPulseAudioStreamControl(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
     1375static DECLCALLBACK(int) drvHostPulseAudioStreamControl(PPDMIHOSTAUDIO pInterface,
     1376                                                        PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
    13971377{
    13981378    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    13991379    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    14001380
    1401     Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST);
     1381    PDRVHOSTPULSEAUDIO pThis     = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
     1382    PPULSEAUDIOSTREAM  pStreamPA = (PPULSEAUDIOSTREAM)pStream;
     1383
     1384    if (!pStreamPA->pCfg) /* Not (yet) configured? Skip. */
     1385        return VINF_SUCCESS;
    14021386
    14031387    int rc;
    1404     if (pStream->enmDir == PDMAUDIODIR_IN)
    1405         rc = paControlStreamIn(pInterface,  pStream, enmStreamCmd);
    1406     else if (pStream->enmDir == PDMAUDIODIR_OUT)
    1407         rc = paControlStreamOut(pInterface, pStream, enmStreamCmd);
     1388    if (pStreamPA->pCfg->enmDir == PDMAUDIODIR_IN)
     1389        rc = paControlStreamIn (pThis, pStreamPA, enmStreamCmd);
     1390    else if (pStreamPA->pCfg->enmDir == PDMAUDIODIR_OUT)
     1391        rc = paControlStreamOut(pThis, pStreamPA, enmStreamCmd);
    14081392    else
    1409         AssertFailedReturn(VERR_NOT_IMPLEMENTED);
     1393        AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
    14101394
    14111395    return rc;
     
    14161400 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
    14171401 */
    1418 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostPulseAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     1402static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostPulseAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    14191403{
    14201404    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    14211405    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    14221406
    1423     PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
    1424     PPULSEAUDIOSTREAM  pStrm = (PPULSEAUDIOSTREAM)pStream;
     1407    PDRVHOSTPULSEAUDIO pThis     = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
     1408    PPULSEAUDIOSTREAM  pStreamPA = (PPULSEAUDIOSTREAM)pStream;
    14251409
    14261410    PDMAUDIOSTRMSTS strmSts  = PDMAUDIOSTRMSTS_FLAG_NONE;
     
    14371421
    14381422    /* Check the PulseAudio stream. */
    1439     if (PA_STREAM_IS_GOOD(pa_stream_get_state(pStrm->pPAStream)))
     1423    if (PA_STREAM_IS_GOOD(pa_stream_get_state(pStreamPA->pStream)))
    14401424    {
    14411425        size_t cbSize;
    1442         if (pStream->enmDir == PDMAUDIODIR_IN)
    1443         {
    1444             cbSize = pa_stream_readable_size(pStrm->pPAStream);
     1426        if (pStreamPA->pCfg->enmDir == PDMAUDIODIR_IN)
     1427        {
     1428            cbSize = pa_stream_readable_size(pStreamPA->pStream);
    14451429            Log3Func(("cbSize=%zu\n", cbSize));
    14461430
     
    14481432                strmSts |= PDMAUDIOSTRMSTS_FLAG_DATA_READABLE;
    14491433        }
    1450         else if (pStream->enmDir == PDMAUDIODIR_OUT)
    1451         {
    1452             cbSize = pa_stream_writable_size(pStrm->pPAStream);
    1453             Log3Func(("cbSize=%zu, cbMinReq=%RU32\n", cbSize, pStrm->BufAttr.minreq));
    1454 
    1455             if (cbSize >= pStrm->BufAttr.minreq)
     1434        else if (pStreamPA->pCfg->enmDir == PDMAUDIODIR_OUT)
     1435        {
     1436            cbSize = pa_stream_writable_size(pStreamPA->pStream);
     1437            Log3Func(("cbSize=%zu, cbMinReq=%RU32\n", cbSize, pStreamPA->BufAttr.minreq));
     1438
     1439            if (cbSize >= pStreamPA->BufAttr.minreq)
    14561440                strmSts |= PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE;
    14571441        }
     
    14691453 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate}
    14701454 */
    1471 static DECLCALLBACK(int) drvHostPulseAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     1455static DECLCALLBACK(int) drvHostPulseAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    14721456{
    14731457    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
  • trunk/src/VBox/Devices/Audio/DrvHostValidationKit.cpp

    r65606 r65624  
    3333typedef struct VAKITAUDIOSTREAM
    3434{
    35     /** Note: Always must come first! */
    36     PDMAUDIOSTREAM     Stream;
     35    /** The stream's acquired configuration. */
     36    PDMAUDIOSTREAMCFG  Cfg;
    3737    /** Audio file to dump output to or read input from. */
    3838    PDMAUDIOFILE       File;
     
    128128
    129129static int debugCreateStreamIn(PPDMIHOSTAUDIO pInterface,
    130                                PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     130                               PPDMAUDIOBACKENDSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    131131{
    132132    RT_NOREF(pInterface, pStream);
     
    134134    /* Just adopt the wanted stream configuration. */
    135135    PDMAUDIOPCMPROPS Props;
    136     int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &Props);
     136    int rc = DrvAudioHlpStreamCfgDup(pCfgReq, &Props);
    137137    if (RT_SUCCESS(rc))
    138138    {
    139139        if (pCfgAcq)
    140             pCfgAcq->cSampleBufferSize = _1K;
     140            pCfgAcq->cSampleBufferHint = _1K;
    141141    }
    142142
     
    147147
    148148static int debugCreateStreamOut(PPDMIHOSTAUDIO pInterface,
    149                                 PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     149                                PPDMAUDIOBACKENDSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    150150{
    151151    NOREF(pInterface);
     
    155155    /* Just adopt the wanted stream configuration. */
    156156    PDMAUDIOPCMPROPS Props;
    157     int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &Props);
     157    int rc = DrvAudioHlpStreamCfgDup(pCfgReq, &Props);
    158158    if (RT_SUCCESS(rc))
    159159    {
     
    204204    {
    205205        if (pCfgAcq)
    206             pCfgAcq->cSampleBufferSize = pDbgStream->Out.cMaxSamplesInPlayBuffer;
     206            pCfgAcq->cSampleBufferHint = pDbgStream->Out.cMaxSamplesInPlayBuffer;
    207207    }
    208208
     
    216216 */
    217217static DECLCALLBACK(int) drvHostVaKitAudioStreamCreate(PPDMIHOSTAUDIO pInterface,
    218                                                        PPDMAUDIOSTREAM pStream,
     218                                                       PPDMAUDIOBACKENDSTREAM pStream,
    219219                                                       PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    220220{
     
    238238 */
    239239static DECLCALLBACK(int) drvHostVaKitAudioStreamPlay(PPDMIHOSTAUDIO pInterface,
    240                                                      PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf,
     240                                                     PPDMAUDIOBACKENDSTREAM pStream, const void *pvBuf, uint32_t cbBuf,
    241241                                                     uint32_t *pcbWritten)
    242242{
     
    338338 */
    339339static DECLCALLBACK(int) drvHostVaKitAudioStreamCapture(PPDMIHOSTAUDIO pInterface,
    340                                                         PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
     340                                                        PPDMAUDIOBACKENDSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
    341341{
    342342    RT_NOREF(pInterface, pStream, pvBuf, cbBuf);
     
    350350
    351351
    352 static int debugDestroyStreamIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     352static int debugDestroyStreamIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    353353{
    354354    RT_NOREF(pInterface, pStream);
     
    358358
    359359
    360 static int debugDestroyStreamOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     360static int debugDestroyStreamOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    361361{
    362362    RT_NOREF(pInterface);
     
    400400
    401401
    402 static DECLCALLBACK(int) drvHostVaKitAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     402static DECLCALLBACK(int) drvHostVaKitAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    403403{
    404404    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     
    415415
    416416static DECLCALLBACK(int) drvHostVaKitAudioStreamControl(PPDMIHOSTAUDIO pInterface,
    417                                                         PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
     417                                                        PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
    418418{
    419419    RT_NOREF(enmStreamCmd);
     
    427427}
    428428
    429 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostVaKitAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     429static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostVaKitAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    430430{
    431431    NOREF(pInterface);
     
    436436}
    437437
    438 static DECLCALLBACK(int) drvHostVaKitAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     438static DECLCALLBACK(int) drvHostVaKitAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    439439{
    440440    NOREF(pInterface);
  • trunk/src/VBox/Devices/Audio/HDACodec.cpp

    r64991 r65624  
    88
    99/*
    10  * Copyright (C) 2006-2016 Oracle Corporation
     10 * Copyright (C) 2006-2017 Oracle Corporation
    1111 *
    1212 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    601601
    602602    uint32_t    u32A_param;
    603     AMPLIFIER B_params;
     603    AMPLIFIER   B_params;
    604604
    605605} DACNODE, *PDACNODE;
     
    15841584 * Misc helpers.
    15851585 */
    1586 static int hdaCodecToAudVolume(PHDACODEC pThis, AMPLIFIER *pAmp, PDMAUDIOMIXERCTL enmMixerCtl)
    1587 {
     1586static int hdaCodecToAudVolume(PHDACODEC pThis, PCODECNODE pNode, AMPLIFIER *pAmp, PDMAUDIOMIXERCTL enmMixerCtl)
     1587{
     1588    RT_NOREF(pNode);
     1589
    15881590    uint8_t iDir;
    15891591    switch (enmMixerCtl)
     
    16211623
    16221624    PDMAUDIOVOLUME Vol = { RT_BOOL(iMute), lVol, rVol };
     1625
     1626    LogFunc(("[NID0x%02x] %RU8/%RU8 (%s)\n",
     1627             pNode->node.uID, lVol, rVol, RT_BOOL(iMute) ? "Muted" : "Unmuted"));
    16231628
    16241629    LogRel2(("HDA: Setting volume for mixer control '%s' to %RU8/%RU8 (%s)\n",
     
    17441749    bool fIsOut     = CODEC_SET_AMP_IS_OUT_DIRECTION(cmd);
    17451750    bool fIsIn      = CODEC_SET_AMP_IS_IN_DIRECTION(cmd);
     1751    bool fIsLeft    = CODEC_SET_AMP_IS_LEFT_SIDE(cmd);
    17461752    bool fIsRight   = CODEC_SET_AMP_IS_RIGHT_SIDE(cmd);
    1747     bool fIsLeft    = CODEC_SET_AMP_IS_LEFT_SIDE(cmd);
    17481753    uint8_t u8Index = CODEC_SET_AMP_INDEX(cmd);
    17491754
     
    17511756        || (!fIsOut && !fIsIn))
    17521757        return VINF_SUCCESS;
     1758
     1759    LogFunc(("[NID0x%02x] fIsOut=%RTbool, fIsIn=%RTbool, fIsLeft=%RTbool, fIsRight=%RTbool, Idx=%RU8\n",
     1760             CODEC_NID(cmd), fIsOut, fIsIn, fIsLeft, fIsRight, u8Index));
    17531761
    17541762    if (fIsIn)
     
    17591767            hdaCodecSetRegisterU8(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_RIGHT, u8Index), cmd, 0);
    17601768
    1761         /** @todo Fix ID of u8AdcVolsLineIn! */
    1762         hdaCodecToAudVolume(pThis, pAmplifier, PDMAUDIOMIXERCTL_LINE_IN);
     1769    //    if (CODEC_NID(cmd) == pThis->u8AdcVolsLineIn)
     1770    //    {
     1771            hdaCodecToAudVolume(pThis, pNode, pAmplifier, PDMAUDIOMIXERCTL_LINE_IN);
     1772    //    }
    17631773    }
    17641774    if (fIsOut)
     
    17701780
    17711781        if (CODEC_NID(cmd) == pThis->u8DacLineOut)
    1772             hdaCodecToAudVolume(pThis, pAmplifier, PDMAUDIOMIXERCTL_FRONT);
     1782            hdaCodecToAudVolume(pThis, pNode, pAmplifier, PDMAUDIOMIXERCTL_FRONT);
    17731783    }
    17741784
     
    23252335#endif
    23262336
     2337/* F06 */
    23272338static DECLCALLBACK(int) vrbProcGetStreamId(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    23282339{
     
    23482359}
    23492360
    2350 /* F06 */
     2361/* 706 */
    23512362static DECLCALLBACK(int) vrbProcSetStreamId(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp)
    23522363{
    23532364    *pResp = 0;
    23542365
     2366    uint8_t uSD      = CODEC_F00_06_GET_STREAM_ID(cmd);
     2367    uint8_t uChannel = CODEC_F00_06_GET_CHANNEL_ID(cmd);
     2368
     2369    LogFlowFunc(("[NID0x%02x] Setting to stream ID=%RU8, channel=%RU8\n",
     2370                 CODEC_NID(cmd), uSD, uChannel));
     2371
    23552372    PDMAUDIODIR enmDir;
    2356 
    23572373    uint32_t *pu32Addr = NULL;
    23582374    if (hdaCodecIsDacNode(pThis, CODEC_NID(cmd)))
     
    23852401    if (enmDir != PDMAUDIODIR_UNKNOWN)
    23862402    {
    2387         uint8_t uSD      = CODEC_F00_06_GET_STREAM_ID(cmd);
    2388         uint8_t uChannel = CODEC_F00_06_GET_CHANNEL_ID(cmd);
    2389 
    2390         LogFlowFunc(("[NID0x%02x] Setting to stream ID=%RU8, channel=%RU8, enmDir=%RU32\n",
    2391                      CODEC_NID(cmd), uSD, uChannel, enmDir));
    2392 
    23932403        pThis->paNodes[CODEC_NID(cmd)].node.uSD      = uSD;
    23942404        pThis->paNodes[CODEC_NID(cmd)].node.uChannel = uChannel;
     
    31143124int hdaCodecLoadState(PHDACODEC pThis, PSSMHANDLE pSSM, uint32_t uVersion)
    31153125{
    3116     PCSSMFIELD pFields;
    3117     uint32_t   fFlags;
     3126    int rc = VINF_SUCCESS;
     3127
     3128    PCSSMFIELD pFields = NULL;
     3129    uint32_t   fFlags  = 0;
    31183130    switch (uVersion)
    31193131    {
     
    31493161
    31503162        default:
    3151             return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
    3152     }
    3153 
    3154     for (unsigned idxNode = 0; idxNode < pThis->cTotalNodes; ++idxNode)
    3155     {
    3156         uint8_t idOld = pThis->paNodes[idxNode].SavedState.Core.uID;
    3157         int rc = SSMR3GetStructEx(pSSM, &pThis->paNodes[idxNode].SavedState,
    3158                                   sizeof(pThis->paNodes[idxNode].SavedState),
    3159                                   fFlags, pFields, NULL);
    3160         if (RT_FAILURE(rc))
    3161             return rc;
    3162         AssertLogRelMsgReturn(idOld == pThis->paNodes[idxNode].SavedState.Core.uID,
    3163                               ("loaded %#x, expected %#x\n", pThis->paNodes[idxNode].SavedState.Core.uID, idOld),
    3164                               VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
    3165     }
    3166 
    3167     /*
    3168      * Update stuff after changing the state.
    3169      */
    3170     if (hdaCodecIsDacNode(pThis, pThis->u8DacLineOut))
    3171         hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params, PDMAUDIOMIXERCTL_FRONT);
    3172     else if (hdaCodecIsSpdifOutNode(pThis, pThis->u8DacLineOut))
    3173         hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].spdifout.B_params, PDMAUDIOMIXERCTL_FRONT);
    3174     hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN);
    3175 
    3176     return VINF_SUCCESS;
     3163            rc = VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
     3164            break;
     3165    }
     3166
     3167    if (RT_SUCCESS(rc))
     3168    {
     3169        for (unsigned idxNode = 0; idxNode < pThis->cTotalNodes; ++idxNode)
     3170        {
     3171            uint8_t idOld = pThis->paNodes[idxNode].SavedState.Core.uID;
     3172            int rc2 = SSMR3GetStructEx(pSSM, &pThis->paNodes[idxNode].SavedState,
     3173                                       sizeof(pThis->paNodes[idxNode].SavedState),
     3174                                       fFlags, pFields, NULL);
     3175            if (RT_SUCCESS(rc))
     3176                rc = rc2;
     3177
     3178            if (RT_FAILURE(rc))
     3179                break;
     3180
     3181            AssertLogRelMsgReturn(idOld == pThis->paNodes[idxNode].SavedState.Core.uID,
     3182                                  ("loaded %#x, expected %#x\n", pThis->paNodes[idxNode].SavedState.Core.uID, idOld),
     3183                                  VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
     3184        }
     3185
     3186        if (RT_SUCCESS(rc))
     3187        {
     3188            /*
     3189             * Update stuff after changing the state.
     3190             */
     3191            PCODECNODE pNode;
     3192            if (hdaCodecIsDacNode(pThis, pThis->u8DacLineOut))
     3193            {
     3194                pNode = &pThis->paNodes[pThis->u8DacLineOut];
     3195                hdaCodecToAudVolume(pThis, pNode, &pNode->dac.B_params, PDMAUDIOMIXERCTL_FRONT);
     3196            }
     3197            else if (hdaCodecIsSpdifOutNode(pThis, pThis->u8DacLineOut))
     3198            {
     3199                pNode = &pThis->paNodes[pThis->u8DacLineOut];
     3200                hdaCodecToAudVolume(pThis, pNode, &pNode->spdifout.B_params, PDMAUDIOMIXERCTL_FRONT);
     3201            }
     3202
     3203            pNode = &pThis->paNodes[pThis->u8AdcVolsLineIn];
     3204            hdaCodecToAudVolume(pThis, pNode, &pNode->adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN);
     3205        }
     3206    }
     3207
     3208    LogFlowFuncLeaveRC(rc);
     3209    return rc;
    31773210}
    31783211
     
    32583291        PDMAUDIOSTREAMCFG strmCfg;
    32593292        RT_ZERO(strmCfg);
    3260         strmCfg.uHz           = 44100;
    3261         strmCfg.cChannels     = 2;
    3262         strmCfg.enmFormat     = PDMAUDIOFMT_S16;
    3263         strmCfg.enmEndianness = PDMAUDIOHOSTENDIANNESS;
     3293
     3294        strmCfg.Props.uHz       = 44100;
     3295        strmCfg.Props.cChannels = 2;
     3296        strmCfg.Props.cBits     = 16;
     3297        strmCfg.Props.fSigned   = true;
    32643298
    32653299        /* Note: Adding the default input/output streams is *not* critical for the overall
     
    33183352     * Set initial volume.
    33193353     */
    3320     hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params,       PDMAUDIOMIXERCTL_FRONT);
    3321     hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN);
     3354    PCODECNODE pNode = &pThis->paNodes[pThis->u8DacLineOut];
     3355    hdaCodecToAudVolume(pThis, pNode, &pNode->dac.B_params, PDMAUDIOMIXERCTL_FRONT);
     3356
     3357    pNode = &pThis->paNodes[pThis->u8AdcVolsLineIn];
     3358    hdaCodecToAudVolume(pThis, pNode, &pNode->adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN);
    33223359#ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    3323     #error "Implement mic-in support!"
     3360# error "Implement mic-in support!"
    33243361#endif
    33253362
  • trunk/src/VBox/Devices/Audio/testcase/tstAudioMixBuffer.cpp

    r63362 r65624  
    4646        PDMAUDIODIR_OUT,
    4747        { PDMAUDIOPLAYBACKDEST_UNKNOWN },
    48         44100,                    /* Hz */
    49         2                         /* Channels */,
    50         PDMAUDIOFMT_S16           /* Format */,
    51         PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */
    52     };
    53     PDMAUDIOPCMPROPS props;
    54 
    55     int rc = DrvAudioHlpStreamCfgToProps(&config, &props);
    56     AssertRC(rc);
     48        { 16,                       /* Bits */
     49          true,                     /* Signed */
     50          1,                        /* Shift */
     51          2,                        /* Channels */
     52          44100,                    /* Hz */
     53          false                     /* Swap Endian */ },
     54        0 /* cSampleBufferSize */
     55    };
     56
     57    RTTESTI_CHECK(DrvAudioHlpStreamCfgIsValid(&config));
    5758
    5859    uint32_t cBufSize = _1K;
     
    6263     */
    6364    PDMAUDIOMIXBUF mb;
    64     RTTESTI_CHECK_RC_OK(AudioMixBufInit(&mb, "Single", &props, cBufSize));
     65    RTTESTI_CHECK_RC_OK(AudioMixBufInit(&mb, "Single", &config.Props, cBufSize));
    6566    RTTESTI_CHECK(AudioMixBufSize(&mb) == cBufSize);
    6667    RTTESTI_CHECK(AUDIOMIXBUF_B2S(&mb, AudioMixBufSizeBytes(&mb)) == cBufSize);
     
    149150        PDMAUDIODIR_OUT,
    150151        { PDMAUDIOPLAYBACKDEST_UNKNOWN },
    151         44100,                    /* Hz */
    152         2                         /* Channels */,
    153         PDMAUDIOFMT_S16           /* Format */,
    154         PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */
    155     };
    156 
    157     PDMAUDIOPCMPROPS props;
    158     int rc = DrvAudioHlpStreamCfgToProps(&cfg_p, &props);
    159     AssertRC(rc);
     152        { 16,                       /* Bits */
     153          true,                     /* Signed */
     154          1,                        /* Shift */
     155          2,                        /* Channels */
     156          44100,                    /* Hz */
     157          false                     /* Swap Endian */ },
     158        0 /* cSampleBufferSize */
     159    };
     160
     161    RTTESTI_CHECK(DrvAudioHlpStreamCfgIsValid(&cfg_p));
    160162
    161163    PDMAUDIOMIXBUF parent;
    162     RTTESTI_CHECK_RC_OK(AudioMixBufInit(&parent, "Parent", &props, cBufSize));
     164    RTTESTI_CHECK_RC_OK(AudioMixBufInit(&parent, "Parent", &cfg_p.Props, cBufSize));
    163165
    164166    PDMAUDIOSTREAMCFG cfg_c1 = /* Upmixing to parent */
     
    167169        PDMAUDIODIR_OUT,
    168170        { PDMAUDIOPLAYBACKDEST_UNKNOWN },
    169         22050,                    /* Hz */
    170         2                         /* Channels */,
    171         PDMAUDIOFMT_S16           /* Format */,
    172         PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */
    173     };
    174 
    175     rc = DrvAudioHlpStreamCfgToProps(&cfg_c1, &props);
    176     AssertRC(rc);
     171        { 16,                       /* Bits */
     172          true,                     /* Signed */
     173          1,                        /* Shift */
     174          2,                        /* Channels */
     175          22050,                    /* Hz */
     176          false                     /* Swap Endian */ },
     177        0 /* cSampleBufferSize */
     178    };
     179
     180    RTTESTI_CHECK(DrvAudioHlpStreamCfgIsValid(&cfg_c1));
    177181
    178182    PDMAUDIOMIXBUF child1;
    179     RTTESTI_CHECK_RC_OK(AudioMixBufInit(&child1, "Child1", &props, cBufSize));
     183    RTTESTI_CHECK_RC_OK(AudioMixBufInit(&child1, "Child1", &cfg_c1.Props, cBufSize));
    180184    RTTESTI_CHECK_RC_OK(AudioMixBufLinkTo(&child1, &parent));
    181185
     
    185189        PDMAUDIODIR_OUT,
    186190        { PDMAUDIOPLAYBACKDEST_UNKNOWN },
    187         48000,                    /* Hz */
    188         2                         /* Channels */,
    189         PDMAUDIOFMT_S16           /* Format */,
    190         PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */
    191     };
    192 
    193     rc = DrvAudioHlpStreamCfgToProps(&cfg_c2, &props);
    194     AssertRC(rc);
     191        { 16,                       /* Bits */
     192          true,                     /* Signed */
     193          1,                        /* Shift */
     194          2,                        /* Channels */
     195          48000,                    /* Hz */
     196          false                     /* Swap Endian */ },
     197        0 /* cSampleBufferSize */
     198    };
     199
     200    RTTESTI_CHECK(DrvAudioHlpStreamCfgIsValid(&cfg_c2));
    195201
    196202    PDMAUDIOMIXBUF child2;
    197     RTTESTI_CHECK_RC_OK(AudioMixBufInit(&child2, "Child2", &props, cBufSize));
     203    RTTESTI_CHECK_RC_OK(AudioMixBufInit(&child2, "Child2", &cfg_c2.Props, cBufSize));
    198204    RTTESTI_CHECK_RC_OK(AudioMixBufLinkTo(&child2, &parent));
    199205
     
    262268    unsigned         i;
    263269    uint32_t         cBufSize = 256;
    264     PDMAUDIOPCMPROPS props;
    265270
    266271    RTTestSubF(hTest, "Sample conversion (U8)");
     
    271276        PDMAUDIODIR_OUT,
    272277        { PDMAUDIOPLAYBACKDEST_UNKNOWN },
    273         44100,                    /* Hz */
    274         1                         /* Channels */,
    275         PDMAUDIOFMT_U8            /* Format */,
    276         PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */
    277     };
    278 
    279     int rc = DrvAudioHlpStreamCfgToProps(&cfg_p, &props);
    280     AssertRC(rc);
     278        { 8,                        /* Bits */
     279          false,                    /* Signed */
     280          1,                        /* Shift */
     281          1,                        /* Channels */
     282          44100,                    /* Hz */
     283          false                     /* Swap Endian */ },
     284        0 /* cSampleBufferSize */
     285    };
     286
     287    RTTESTI_CHECK(DrvAudioHlpStreamCfgIsValid(&cfg_p));
    281288
    282289    PDMAUDIOMIXBUF parent;
    283     RTTESTI_CHECK_RC_OK(AudioMixBufInit(&parent, "Parent", &props, cBufSize));
     290    RTTESTI_CHECK_RC_OK(AudioMixBufInit(&parent, "Parent", &cfg_p.Props, cBufSize));
    284291
    285292    /* Child uses half the sample rate; that ensures the mixing engine can't
     
    295302        PDMAUDIODIR_OUT,
    296303        { PDMAUDIOPLAYBACKDEST_UNKNOWN },
    297         22050,                    /* Hz */
    298         1                         /* Channels */,
    299         PDMAUDIOFMT_U8            /* Format */,
    300         PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */
    301     };
    302 
    303     rc = DrvAudioHlpStreamCfgToProps(&cfg_c, &props);
    304     AssertRC(rc);
     304        { 8,                        /* Bits */
     305          false,                    /* Signed */
     306          1,                        /* Shift */
     307          1,                        /* Channels */
     308          22050,                    /* Hz */
     309          false                     /* Swap Endian */ },
     310        0 /* cSampleBufferSize */
     311    };
     312
     313    RTTESTI_CHECK(DrvAudioHlpStreamCfgIsValid(&cfg_c));
    305314
    306315    PDMAUDIOMIXBUF child;
    307     RTTESTI_CHECK_RC_OK(AudioMixBufInit(&child, "Child", &props, cBufSize));
     316    RTTESTI_CHECK_RC_OK(AudioMixBufInit(&child, "Child", &cfg_c.Props, cBufSize));
    308317    RTTESTI_CHECK_RC_OK(AudioMixBufLinkTo(&child, &parent));
    309318
     
    324333
    325334    /**** 8-bit unsigned samples ****/
    326     RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Conversion test %uHz %uch 8-bit\n", cfg_c.uHz, cfg_c.cChannels);
     335    RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Conversion test %uHz %uch 8-bit\n", cfg_c.Props.uHz, cfg_c.Props.cChannels);
    327336    RTTESTI_CHECK_RC_OK(AudioMixBufWriteCirc(&child, &samples, sizeof(samples), &cSamplesWritten));
    328337    RTTESTI_CHECK_MSG(cSamplesWritten == cSamplesChild, ("Child: Expected %RU32 written samples, got %RU32\n", cSamplesChild, cSamplesWritten));
     
    370379    unsigned         i;
    371380    uint32_t         cBufSize = 256;
    372     PDMAUDIOPCMPROPS props;
    373381
    374382    RTTestSubF(hTest, "Sample conversion (S16)");
     
    379387        PDMAUDIODIR_OUT,
    380388        { PDMAUDIOPLAYBACKDEST_UNKNOWN },
    381         44100,                    /* Hz */
    382         1                         /* Channels */,
    383         PDMAUDIOFMT_S16           /* Format */,
    384         PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */
    385     };
    386 
    387     int rc = DrvAudioHlpStreamCfgToProps(&cfg_p, &props);
    388     AssertRC(rc);
     389        { 16,                       /* Bits */
     390          true,                     /* Signed */
     391          1,                        /* Shift */
     392          1,                        /* Channels */
     393          44100,                    /* Hz */
     394          false                     /* Swap Endian */ },
     395        0 /* cSampleBufferSize */
     396    };
     397
     398    RTTESTI_CHECK(DrvAudioHlpStreamCfgIsValid(&cfg_p));
    389399
    390400    PDMAUDIOMIXBUF parent;
    391     RTTESTI_CHECK_RC_OK(AudioMixBufInit(&parent, "Parent", &props, cBufSize));
     401    RTTESTI_CHECK_RC_OK(AudioMixBufInit(&parent, "Parent", &cfg_p.Props, cBufSize));
    392402
    393403    PDMAUDIOSTREAMCFG cfg_c =   /* Upmixing to parent */
     
    396406        PDMAUDIODIR_OUT,
    397407        { PDMAUDIOPLAYBACKDEST_UNKNOWN },
    398         22050,                    /* Hz */
    399         1                         /* Channels */,
    400         PDMAUDIOFMT_S16               /* Format */,
    401         PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */
    402     };
    403 
    404     rc = DrvAudioHlpStreamCfgToProps(&cfg_c, &props);
    405     AssertRC(rc);
     408        { 16,                       /* Bits */
     409          true,                     /* Signed */
     410          1,                        /* Shift */
     411          1,                        /* Channels */
     412          22050,                    /* Hz */
     413          false                     /* Swap Endian */ },
     414        0 /* cSampleBufferSize */
     415    };
     416
     417    RTTESTI_CHECK(DrvAudioHlpStreamCfgIsValid(&cfg_c));
    406418
    407419    PDMAUDIOMIXBUF child;
    408     RTTESTI_CHECK_RC_OK(AudioMixBufInit(&child, "Child", &props, cBufSize));
     420    RTTESTI_CHECK_RC_OK(AudioMixBufInit(&child, "Child", &cfg_c.Props, cBufSize));
    409421    RTTESTI_CHECK_RC_OK(AudioMixBufLinkTo(&child, &parent));
    410422
     
    425437
    426438    /**** 16-bit signed samples ****/
    427     RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Conversion test %uHz %uch 16-bit\n", cfg_c.uHz, cfg_c.cChannels);
     439    RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Conversion test %uHz %uch 16-bit\n", cfg_c.Props.uHz, cfg_c.Props.cChannels);
    428440    RTTESTI_CHECK_RC_OK(AudioMixBufWriteCirc(&child, &samples, sizeof(samples), &cSamplesWritten));
    429441    RTTESTI_CHECK_MSG(cSamplesWritten == cSamplesChild, ("Child: Expected %RU32 written samples, got %RU32\n", cSamplesChild, cSamplesWritten));
     
    470482    unsigned         i;
    471483    uint32_t         cBufSize = 256;
    472     PDMAUDIOPCMPROPS props;
    473484
    474485    RTTestSubF(hTest, "Volume control");
     
    480491        PDMAUDIODIR_OUT,
    481492        { PDMAUDIOPLAYBACKDEST_UNKNOWN },
    482         44100,                    /* Hz */
    483         2                         /* Channels */,
    484         PDMAUDIOFMT_S16               /* Format */,
    485         PDMAUDIOENDIANNESS_LITTLE /* ENDIANNESS */
    486     };
    487 
    488     int rc = DrvAudioHlpStreamCfgToProps(&cfg, &props);
    489     AssertRC(rc);
     493        { 16,                       /* Bits */
     494          true,                     /* Signed */
     495          1,                        /* Shift */
     496          2,                        /* Channels */
     497          44100,                    /* Hz */
     498          false                     /* Swap Endian */ },
     499        0 /* cSampleBufferSize */
     500    };
     501
     502    RTTESTI_CHECK(DrvAudioHlpStreamCfgIsValid(&cfg));
    490503
    491504    PDMAUDIOVOLUME vol = { false, 0, 0 };   /* Not muted. */
    492505    PDMAUDIOMIXBUF parent;
    493     RTTESTI_CHECK_RC_OK(AudioMixBufInit(&parent, "Parent", &props, cBufSize));
     506    RTTESTI_CHECK_RC_OK(AudioMixBufInit(&parent, "Parent", &cfg.Props, cBufSize));
    494507
    495508    PDMAUDIOMIXBUF child;
    496     RTTESTI_CHECK_RC_OK(AudioMixBufInit(&child, "Child", &props, cBufSize));
     509    RTTESTI_CHECK_RC_OK(AudioMixBufInit(&child, "Child", &cfg.Props, cBufSize));
    497510    RTTESTI_CHECK_RC_OK(AudioMixBufLinkTo(&child, &parent));
    498511
     
    515528
    516529    /**** Volume control test ****/
    517     RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Volume control test %uHz %uch \n", cfg.uHz, cfg.cChannels);
     530    RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Volume control test %uHz %uch \n", cfg.Props.uHz, cfg.Props.cChannels);
    518531
    519532    /* 1) Full volume/0dB attenuation (255). */
  • trunk/src/VBox/Main/src-client/DrvAudioVRDE.cpp

    r65596 r65624  
    6161} DRVAUDIOVRDE, *PDRVAUDIOVRDE;
    6262
    63 typedef struct VRDESTREAMIN
    64 {
    65     /** Note: Always must come first! */
    66     PDMAUDIOSTREAM       Stream;
    67     /** The PCM properties of this stream. */
    68     PDMAUDIOPCMPROPS     Props;
    69     /** Number of samples this stream can handle at once. */
    70     uint32_t             cSamplesMax;
    71     /** Circular buffer for holding the recorded audio samples from the host. */
    72     PRTCIRCBUF           pCircBuf;
    73 } VRDESTREAMIN, *PVRDESTREAMIN;
    74 
    75 typedef struct VRDESTREAMOUT
    76 {
    77     /** Note: Always must come first! */
    78     PDMAUDIOSTREAM       Stream;
    79     /** The PCM properties of this stream. */
    80     PDMAUDIOPCMPROPS     Props;
    81     uint64_t             old_ticks;
    82     uint64_t             cSamplesSentPerSec;
    83 } VRDESTREAMOUT, *PVRDESTREAMOUT;
    84 
    85 
    86 
    87 static int vrdeCreateStreamIn(PVRDESTREAMIN pStreamVRDE, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    88 {
    89     int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pStreamVRDE->Props);
     63typedef struct VRDESTREAM
     64{
     65    /** The stream's acquired configuration. */
     66    PPDMAUDIOSTREAMCFG pCfg;
     67    union
     68    {
     69        struct
     70        {
     71            /** Number of samples this stream can handle at once. */
     72            uint32_t    cSamplesMax;
     73            /** Circular buffer for holding the recorded audio samples from the host. */
     74            PRTCIRCBUF  pCircBuf;
     75        } In;
     76        struct
     77        {
     78            uint64_t    old_ticks;
     79            uint64_t    cSamplesSentPerSec;
     80        } Out;
     81    };
     82} VRDESTREAM, *PVRDESTREAM;
     83
     84
     85static int vrdeCreateStreamIn(PVRDESTREAM pStreamVRDE, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     86{
     87    pStreamVRDE->In.cSamplesMax = _1K; /** @todo Make this configurable. */
     88
     89    int rc = RTCircBufCreate(&pStreamVRDE->In.pCircBuf, pStreamVRDE->In.cSamplesMax * (pCfgReq->Props.cBits / 8) /* Bytes */);
    9090    if (RT_SUCCESS(rc))
    9191    {
    92         pStreamVRDE->cSamplesMax = _1K; /** @todo Make this configurable. */
    93 
    94         rc = RTCircBufCreate(&pStreamVRDE->pCircBuf, pStreamVRDE->cSamplesMax * (pStreamVRDE->Props.cBits / 8) /* Bytes */);
    95         if (RT_SUCCESS(rc))
    96         {
    97             if (pCfgAcq)
    98                 pCfgAcq->cSampleBufferSize = pStreamVRDE->cSamplesMax;
    99         }
     92        if (pCfgAcq)
     93            pCfgAcq->cSampleBufferHint = pStreamVRDE->In.cSamplesMax;
    10094    }
    10195
     
    10498
    10599
    106 static int vrdeCreateStreamOut(PVRDESTREAMOUT pStreamVRDE, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    107 {
    108     int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pStreamVRDE->Props);
    109     if (RT_SUCCESS(rc))
    110     {
    111         if (pCfgAcq)
    112             pCfgAcq->cSampleBufferSize = _4K; /** @todo Make this configurable. */
    113     }
    114 
    115     return rc;
    116 }
    117 
    118 
    119 static int vrdeControlStreamOut(PDRVAUDIOVRDE pDrv, PVRDESTREAMOUT pStreamVRDE, PDMAUDIOSTREAMCMD enmStreamCmd)
     100static int vrdeCreateStreamOut(PVRDESTREAM pStreamVRDE, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     101{
     102    RT_NOREF(pStreamVRDE, pCfgReq);
     103
     104    if (pCfgAcq)
     105        pCfgAcq->cSampleBufferHint = _4K; /** @todo Make this configurable. */
     106
     107    return VINF_SUCCESS;
     108}
     109
     110
     111static int vrdeControlStreamOut(PDRVAUDIOVRDE pDrv, PVRDESTREAM pStreamVRDE, PDMAUDIOSTREAMCMD enmStreamCmd)
    120112{
    121113    RT_NOREF(pDrv, pStreamVRDE, enmStreamCmd);
     
    127119
    128120
    129 static int vrdeControlStreamIn(PDRVAUDIOVRDE pDrv, PVRDESTREAMIN pVRDEStrmIn, PDMAUDIOSTREAMCMD enmStreamCmd)
     121static int vrdeControlStreamIn(PDRVAUDIOVRDE pDrv, PVRDESTREAM pStreamVRDE, PDMAUDIOSTREAMCMD enmStreamCmd)
    130122{
    131123    LogFlowFunc(("enmStreamCmd=%ld\n", enmStreamCmd));
     
    141133        case PDMAUDIOSTREAMCMD_ENABLE:
    142134        {
    143             rc = pDrv->pConsoleVRDPServer->SendAudioInputBegin(NULL, pVRDEStrmIn, pVRDEStrmIn->cSamplesMax,
    144                                                                pVRDEStrmIn->Props.uHz,
    145                                                                pVRDEStrmIn->Props.cChannels, pVRDEStrmIn->Props.cBits);
     135            rc = pDrv->pConsoleVRDPServer->SendAudioInputBegin(NULL, pStreamVRDE, pStreamVRDE->In.cSamplesMax,
     136                                                               pStreamVRDE->pCfg->Props.uHz, pStreamVRDE->pCfg->Props.cChannels,
     137                                                               pStreamVRDE->pCfg->Props.cBits);
    146138            if (rc == VERR_NOT_SUPPORTED)
    147139            {
     
    203195 */
    204196static DECLCALLBACK(int) drvAudioVRDEStreamCapture(PPDMIHOSTAUDIO pInterface,
    205                                                    PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
     197                                                   PPDMAUDIOBACKENDSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
    206198{
    207199    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     
    211203    /* pcbRead is optional. */
    212204
    213     PVRDESTREAMIN pStreamVRDE = (PVRDESTREAMIN)pStream;
     205    PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pStream;
    214206
    215207    size_t cbData = 0;
    216208
    217     if (RTCircBufUsed(pStreamVRDE->pCircBuf))
     209    if (RTCircBufUsed(pStreamVRDE->In.pCircBuf))
    218210    {
    219211        void *pvData;
    220212
    221         RTCircBufAcquireReadBlock(pStreamVRDE->pCircBuf, cbBuf, &pvData, &cbData);
     213        RTCircBufAcquireReadBlock(pStreamVRDE->In.pCircBuf, cbBuf, &pvData, &cbData);
    222214
    223215        if (cbData)
    224216            memcpy(pvBuf, pvData, cbData);
    225217
    226         RTCircBufReleaseReadBlock(pStreamVRDE->pCircBuf, cbData);
     218        RTCircBufReleaseReadBlock(pStreamVRDE->In.pCircBuf, cbData);
    227219    }
    228220
     
    237229 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay}
    238230 */
    239 static DECLCALLBACK(int) drvAudioVRDEStreamPlay(PPDMIHOSTAUDIO pInterface,
    240                                                 PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
     231static DECLCALLBACK(int) drvAudioVRDEStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
     232                                                const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
    241233{
    242234    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     
    246238    /* pcbWritten is optional. */
    247239
    248     PDRVAUDIOVRDE  pDrv        = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio);
    249     PVRDESTREAMOUT pStreamVRDE = (PVRDESTREAMOUT)pStream;
     240    PDRVAUDIOVRDE pDrv        = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio);
     241    PVRDESTREAM   pStreamVRDE = (PVRDESTREAM)pStream;
    250242
    251243    uint32_t cbLive           = cbBuf;
    252244
    253245    uint64_t now              = PDMDrvHlpTMGetVirtualTime(pDrv->pDrvIns);
    254     uint64_t ticks            = now  - pStreamVRDE->old_ticks;
     246    uint64_t ticks            = now  - pStreamVRDE->Out.old_ticks;
    255247    uint64_t ticks_per_second = PDMDrvHlpTMGetVirtualFreq(pDrv->pDrvIns);
    256248
     249    PPDMAUDIOPCMPROPS pProps  = &pStreamVRDE->pCfg->Props;
     250
    257251    /* Minimize the rounding error: samples = int((ticks * freq) / ticks_per_second + 0.5). */
    258     uint32_t cbToWrite = (int)((2 * ticks * pStreamVRDE->Props.uHz + ticks_per_second) / ticks_per_second / 2);
     252    uint32_t cbToWrite = (int)((2 * ticks * pProps->uHz + ticks_per_second) / ticks_per_second / 2);
    259253
    260254    /* Remember when samples were consumed. */
    261     pStreamVRDE->old_ticks = now;
    262 
    263     VRDEAUDIOFORMAT format = VRDE_AUDIO_FMT_MAKE(pStreamVRDE->Props.uHz,
    264                                                  pStreamVRDE->Props.cChannels,
    265                                                  pStreamVRDE->Props.cBits,
    266                                                  pStreamVRDE->Props.fSigned);
     255    pStreamVRDE->Out.old_ticks = now;
     256
     257    VRDEAUDIOFORMAT format = VRDE_AUDIO_FMT_MAKE(pProps->uHz,
     258                                                 pProps->cChannels,
     259                                                 pProps->cBits,
     260                                                 pProps->fSigned);
    267261
    268262    Log2Func(("uFreq=%RU32, cChan=%RU8, cBits=%RU8, fSigned=%RTbool, enmFormat=%ld, cbLive=%RU32, cbToWrite=%RU32\n",
    269               pStreamVRDE->Props.uHz,   pStreamVRDE->Props.cChannels,
    270               pStreamVRDE->Props.cBits, pStreamVRDE->Props.fSigned,
    271               format, cbLive, cbToWrite));
     263              pProps->uHz,   pProps->cChannels, pProps->cBits, pProps->fSigned, format, cbLive, cbToWrite));
    272264
    273265    /* Don't play more than available. */
     
    291283
    292284        pDrv->pConsoleVRDPServer->SendAudioSamples((uint8_t *)pvBuf + cbWritten,
    293                                                    PDMAUDIOPCMPROPS_B2S(&pStreamVRDE->Props, cbChunk) /* Samples */, format);
     285                                                   PDMAUDIOSTREAMCFG_B2S(pStreamVRDE->pCfg, cbChunk) /* Samples */, format);
    294286        cbWritten += cbChunk;
    295287        Assert(cbWritten <= cbBuf);
     
    311303
    312304
    313 static int vrdeDestroyStreamIn(PDRVAUDIOVRDE pDrv, PVRDESTREAMIN pStreamVRDE)
     305static int vrdeDestroyStreamIn(PDRVAUDIOVRDE pDrv, PVRDESTREAM pStreamVRDE)
    314306{
    315307    if (pDrv->pConsoleVRDPServer)
    316308        pDrv->pConsoleVRDPServer->SendAudioInputEnd(NULL);
    317309
    318     if (pStreamVRDE->pCircBuf)
    319     {
    320         RTCircBufDestroy(pStreamVRDE->pCircBuf);
    321         pStreamVRDE->pCircBuf = NULL;
    322     }
    323 
    324     return VINF_SUCCESS;
    325 }
    326 
    327 
    328 static int vrdeDestroyStreamOut(PDRVAUDIOVRDE pDrv, PVRDESTREAMOUT pStreamVRDE)
     310    if (pStreamVRDE->In.pCircBuf)
     311    {
     312        RTCircBufDestroy(pStreamVRDE->In.pCircBuf);
     313        pStreamVRDE->In.pCircBuf = NULL;
     314    }
     315
     316    return VINF_SUCCESS;
     317}
     318
     319
     320static int vrdeDestroyStreamOut(PDRVAUDIOVRDE pDrv, PVRDESTREAM pStreamVRDE)
    329321{
    330322    RT_NOREF(pDrv, pStreamVRDE);
     
    339331static DECLCALLBACK(int) drvAudioVRDEGetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg)
    340332{
    341     NOREF(pInterface);
     333    RT_NOREF(pInterface);
    342334    AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER);
    343335
    344     pBackendCfg->cbStreamOut    = sizeof(VRDESTREAMOUT);
    345     pBackendCfg->cbStreamIn     = sizeof(VRDESTREAMIN);
     336    pBackendCfg->cbStreamOut    = sizeof(VRDESTREAM);
     337    pBackendCfg->cbStreamIn     = sizeof(VRDESTREAM);
    346338    pBackendCfg->cMaxStreamsIn  = UINT32_MAX;
    347339    pBackendCfg->cMaxStreamsOut = UINT32_MAX;
     
    379371 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate}
    380372 */
    381 static DECLCALLBACK(int) drvAudioVRDEStreamCreate(PPDMIHOSTAUDIO pInterface,
    382                                                   PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     373static DECLCALLBACK(int) drvAudioVRDEStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
     374                                                  PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    383375{
    384376    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     
    389381    RT_NOREF(pInterface);
    390382
     383    PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pStream;
     384
    391385    int rc;
    392386    if (pCfgReq->enmDir == PDMAUDIODIR_IN)
    393     {
    394         PVRDESTREAMIN pStreamVRDE = (PVRDESTREAMIN)pStream;
    395         rc = vrdeCreateStreamIn(pStreamVRDE, pCfgReq, pCfgAcq);
    396     }
     387        rc = vrdeCreateStreamIn (pStreamVRDE, pCfgReq, pCfgAcq);
    397388    else
    398     {
    399         PVRDESTREAMOUT pStreamVRDE = (PVRDESTREAMOUT)pStream;
    400389        rc = vrdeCreateStreamOut(pStreamVRDE, pCfgReq, pCfgAcq);
     390
     391    if (RT_SUCCESS(rc))
     392    {
     393        pStreamVRDE->pCfg = DrvAudioHlpStreamCfgDup(pCfgAcq);
     394        if (!pStreamVRDE->pCfg)
     395            rc = VERR_NO_MEMORY;
    401396    }
    402397
     
    408403 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy}
    409404 */
    410 static DECLCALLBACK(int) drvAudioVRDEStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     405static DECLCALLBACK(int) drvAudioVRDEStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
     406{
     407    RT_NOREF(pInterface);
     408    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
     409
     410    PDRVAUDIOVRDE pDrv        = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio);
     411    PVRDESTREAM   pStreamVRDE = (PVRDESTREAM)pStream;
     412
     413    if (!pStreamVRDE->pCfg) /* Not (yet) configured? Skip. */
     414        return VINF_SUCCESS;
     415
     416    int rc;
     417    if (pStreamVRDE->pCfg->enmDir == PDMAUDIODIR_IN)
     418        rc = vrdeDestroyStreamIn(pDrv, pStreamVRDE);
     419    else
     420        rc = vrdeDestroyStreamOut(pDrv, pStreamVRDE);
     421
     422    if (RT_SUCCESS(rc))
     423    {
     424        DrvAudioHlpStreamCfgFree(pStreamVRDE->pCfg);
     425        pStreamVRDE->pCfg = NULL;
     426    }
     427
     428    return rc;
     429}
     430
     431
     432/**
     433 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl}
     434 */
     435static DECLCALLBACK(int) drvAudioVRDEStreamControl(PPDMIHOSTAUDIO pInterface,
     436                                                   PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
    411437{
    412438    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    413439    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    414440
    415     PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio);
     441    PDRVAUDIOVRDE pDrv        = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio);
     442    PVRDESTREAM   pStreamVRDE = (PVRDESTREAM)pStream;
     443
     444    if (!pStreamVRDE->pCfg) /* Not (yet) configured? Skip. */
     445        return VINF_SUCCESS;
    416446
    417447    int rc;
    418     if (pStream->enmDir == PDMAUDIODIR_IN)
    419     {
    420         PVRDESTREAMIN pStreamVRDE = (PVRDESTREAMIN)pStream;
    421         rc = vrdeDestroyStreamIn(pDrv, pStreamVRDE);
    422     }
     448    if (pStreamVRDE->pCfg->enmDir == PDMAUDIODIR_IN)
     449        rc = vrdeControlStreamIn(pDrv, pStreamVRDE, enmStreamCmd);
    423450    else
    424     {
    425         PVRDESTREAMOUT pStreamVRDE = (PVRDESTREAMOUT)pStream;
    426         rc = vrdeDestroyStreamOut(pDrv, pStreamVRDE);
    427     }
     451        rc = vrdeControlStreamOut(pDrv, pStreamVRDE, enmStreamCmd);
    428452
    429453    return rc;
     
    432456
    433457/**
    434  * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl}
    435  */
    436 static DECLCALLBACK(int) drvAudioVRDEStreamControl(PPDMIHOSTAUDIO pInterface,
    437                                                    PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
     458 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
     459 */
     460static DECLCALLBACK(PDMAUDIOSTRMSTS) drvAudioVRDEStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
     461{
     462    RT_NOREF(pInterface);
     463    RT_NOREF(pStream);
     464
     465    return (  PDMAUDIOSTRMSTS_FLAG_INITIALIZED | PDMAUDIOSTRMSTS_FLAG_ENABLED
     466            | PDMAUDIOSTRMSTS_FLAG_DATA_READABLE | PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE);
     467}
     468
     469
     470/**
     471 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate}
     472 */
     473static DECLCALLBACK(int) drvAudioVRDEStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    438474{
    439475    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    440476    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    441 
    442     PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio);
    443 
    444     int rc;
    445     if (pStream->enmDir == PDMAUDIODIR_IN)
    446     {
    447         PVRDESTREAMIN pStreamVRDE = (PVRDESTREAMIN)pStream;
    448         rc = vrdeControlStreamIn(pDrv, pStreamVRDE, enmStreamCmd);
    449     }
    450     else
    451     {
    452         PVRDESTREAMOUT pStreamVRDE = (PVRDESTREAMOUT)pStream;
    453         rc = vrdeControlStreamOut(pDrv, pStreamVRDE, enmStreamCmd);
    454     }
    455 
    456     return rc;
    457 }
    458 
    459 
    460 /**
    461  * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
    462  */
    463 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvAudioVRDEStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
    464 {
    465     NOREF(pInterface);
    466     NOREF(pStream);
    467 
    468     return (  PDMAUDIOSTRMSTS_FLAG_INITIALIZED | PDMAUDIOSTRMSTS_FLAG_ENABLED
    469             | PDMAUDIOSTRMSTS_FLAG_DATA_READABLE | PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE);
    470 }
    471 
    472 
    473 /**
    474  * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate}
    475  */
    476 static DECLCALLBACK(int) drvAudioVRDEStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
    477 {
    478     AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    479     AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    480 
    481     LogFlowFuncEnter();
    482477
    483478    /* Nothing to do here for VRDE. */
     
    543538    AssertPtrReturn(pVRDEAudioBegin, VERR_INVALID_POINTER);
    544539
    545     PVRDESTREAMIN pVRDEStrmIn = (PVRDESTREAMIN)pvContext;
     540    PVRDESTREAM pVRDEStrmIn = (PVRDESTREAM)pvContext;
    546541    AssertPtrReturn(pVRDEStrmIn, VERR_INVALID_POINTER);
    547542
    548543    VRDEAUDIOFORMAT audioFmt = pVRDEAudioBegin->fmt;
    549544
    550     int iSampleHz  = VRDE_AUDIO_FMT_SAMPLE_FREQ(audioFmt);     NOREF(iSampleHz);
    551     int cChannels  = VRDE_AUDIO_FMT_CHANNELS(audioFmt);        NOREF(cChannels);
    552     int cBits      = VRDE_AUDIO_FMT_BITS_PER_SAMPLE(audioFmt); NOREF(cBits);
    553     bool fUnsigned = VRDE_AUDIO_FMT_SIGNED(audioFmt);          NOREF(fUnsigned);
     545    int iSampleHz  = VRDE_AUDIO_FMT_SAMPLE_FREQ(audioFmt);     RT_NOREF(iSampleHz);
     546    int cChannels  = VRDE_AUDIO_FMT_CHANNELS(audioFmt);        RT_NOREF(cChannels);
     547    int cBits      = VRDE_AUDIO_FMT_BITS_PER_SAMPLE(audioFmt); RT_NOREF(cBits);
     548    bool fUnsigned = VRDE_AUDIO_FMT_SIGNED(audioFmt);          RT_NOREF(fUnsigned);
    554549
    555550    LogFlowFunc(("cbSample=%RU32, iSampleHz=%d, cChannels=%d, cBits=%d, fUnsigned=%RTbool\n",
     
    562557int AudioVRDE::onVRDEInputData(void *pvContext, const void *pvData, uint32_t cbData)
    563558{
    564     PVRDESTREAMIN pStreamVRDE = (PVRDESTREAMIN)pvContext;
     559    PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pvContext;
    565560    AssertPtrReturn(pStreamVRDE, VERR_INVALID_POINTER);
    566561
     
    568563    size_t cbBuf;
    569564
    570     RTCircBufAcquireWriteBlock(pStreamVRDE->pCircBuf, cbData, &pvBuf, &cbBuf);
     565    RTCircBufAcquireWriteBlock(pStreamVRDE->In.pCircBuf, cbData, &pvBuf, &cbBuf);
    571566
    572567    if (cbBuf)
    573568        memcpy(pvBuf, pvData, cbBuf);
    574569
    575     RTCircBufReleaseWriteBlock(pStreamVRDE->pCircBuf, cbBuf);
     570    RTCircBufReleaseWriteBlock(pStreamVRDE->In.pCircBuf, cbBuf);
    576571
    577572    if (cbBuf < cbData)
     
    584579int AudioVRDE::onVRDEInputEnd(void *pvContext)
    585580{
    586     NOREF(pvContext);
     581    RT_NOREF(pvContext);
    587582
    588583    return VINF_SUCCESS;
  • trunk/src/VBox/Main/src-client/DrvAudioVideoRec.cpp

    r65565 r65624  
    180180
    181181/**
    182  * Audio video recording output stream.
    183  */
    184 typedef struct AVRECSTREAMOUT
    185 {
    186     /** Note: Always must come first! */
    187     PDMAUDIOSTREAM       Stream;
    188     /** The PCM properties of this stream. */
    189     PDMAUDIOPCMPROPS     Props;
     182 * Audio video recording (output) stream.
     183 */
     184typedef struct AVRECSTREAM
     185{
     186    /** The stream's acquired configuration. */
     187    PPDMAUDIOSTREAMCFG   pCfg;
    190188    /** (Audio) frame buffer. */
    191189    PRTCIRCBUF           pCircBuf;
    192190    /** Pointer to sink to use for writing. */
    193191    PAVRECSINK           pSink;
    194 } AVRECSTREAMOUT, *PAVRECSTREAMOUT;
     192} AVRECSTREAM, *PAVRECSTREAM;
    195193
    196194/**
     
    359357 * @returns IPRT status code.
    360358 * @param   pThis               Driver instance.
    361  * @param   pStream             Audio output stream to create.
     359 * @param   pStreamAV           Audio output stream to create.
    362360 * @param   pSink               Recording sink to associate audio output stream to.
    363361 * @param   pCfgReq             Requested configuration by the audio backend.
    364362 * @param   pCfgAcq             Acquired configuration by the audio output stream.
    365363 */
    366 static int avRecCreateStreamOut(PDRVAUDIOVIDEOREC pThis, PPDMAUDIOSTREAM pStream,
     364static int avRecCreateStreamOut(PDRVAUDIOVIDEOREC pThis, PAVRECSTREAM pStreamAV,
    367365                                PAVRECSINK pSink, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    368366{
    369     AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
    370     AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    371     AssertPtrReturn(pSink,   VERR_INVALID_POINTER);
    372     AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER);
    373     AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER);
    374 
    375     PAVRECSTREAMOUT pStreamOut = (PAVRECSTREAMOUT)pStream;
     367    AssertPtrReturn(pThis,     VERR_INVALID_POINTER);
     368    AssertPtrReturn(pStreamAV, VERR_INVALID_POINTER);
     369    AssertPtrReturn(pSink,     VERR_INVALID_POINTER);
     370    AssertPtrReturn(pCfgReq,   VERR_INVALID_POINTER);
     371    AssertPtrReturn(pCfgAcq,   VERR_INVALID_POINTER);
    376372
    377373    if (pCfgReq->DestSource.Dest != PDMAUDIOPLAYBACKDEST_FRONT)
     
    380376
    381377        if (pCfgAcq)
    382             pCfgAcq->cSampleBufferSize = 0;
     378            pCfgAcq->cSampleBufferHint = 0;
    383379
    384380        LogRel2(("VideoRec: Support for surround audio not implemented yet\n"));
     
    386382    }
    387383
    388     int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pStreamOut->Props);
    389     if (RT_FAILURE(rc))
    390         return rc;
     384    int rc = VINF_SUCCESS;
    391385
    392386#ifdef VBOX_WITH_LIBOPUS
     
    398392                                           WebMWriter::AudioCodec_Opus, WebMWriter::VideoCodec_None);
    399393        if (RT_SUCCESS(rc))
    400             rc = pSink->Con.WebM.pWebM->AddAudioTrack(pSink->Codec.Parms.uHz, pStreamOut->Props.cChannels, pStreamOut->Props.cBits,
     394            rc = pSink->Con.WebM.pWebM->AddAudioTrack(pSink->Codec.Parms.uHz, pCfgReq->Props.cChannels, pCfgReq->Props.cBits,
    401395                                                      &pSink->Con.WebM.uTrack);
    402396    }
     
    405399        return rc;
    406400
    407     rc = RTCircBufCreate(&pStreamOut->pCircBuf, (pSink->Codec.Opus.csFrame * pSink->Codec.Parms.cChannels) * sizeof(uint16_t));
     401    rc = RTCircBufCreate(&pStreamAV->pCircBuf, (pSink->Codec.Opus.csFrame * pSink->Codec.Parms.cChannels) * sizeof(uint16_t));
    408402    if (RT_SUCCESS(rc))
    409403    {
    410         pStreamOut->pSink = pSink; /* Assign sink to stream. */
     404        pStreamAV->pSink = pSink; /* Assign sink to stream. */
    411405
    412406        if (pCfgAcq)
     
    414408            /* Make sure to let the driver backend know that we need the audio data in
    415409             * a specific sampling rate Opus is optimized for. */
    416             pCfgAcq->uHz               = pSink->Codec.Parms.uHz;
    417             pCfgAcq->cSampleBufferSize = _4K; /** @todo Make this configurable. */
     410            pCfgAcq->Props.uHz         = pSink->Codec.Parms.uHz;
     411            pCfgAcq->Props.cShift      = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfgAcq->Props.cBits, pCfgAcq->Props.cChannels);
     412            pCfgAcq->cSampleBufferHint = _4K; /** @todo Make this configurable. */
    418413        }
    419414    }
    420415#else
    421     RT_NOREF(pThis, pSink, pStream, pCfgReq, pCfgAcq);
     416    RT_NOREF(pThis, pSink, pStreamAV, pCfgReq, pCfgAcq);
    422417    rc = VERR_NOT_SUPPORTED;
    423418#endif /* VBOX_WITH_LIBOPUS */
     
    433428 * @returns IPRT status code.
    434429 * @param   pThis               Driver instance.
    435  * @param   pStream             Audio output stream to destroy.
    436  */
    437 static int avRecDestroyStreamOut(PDRVAUDIOVIDEOREC pThis, PPDMAUDIOSTREAM pStream)
     430 * @param   pStreamAV           Audio output stream to destroy.
     431 */
     432static int avRecDestroyStreamOut(PDRVAUDIOVIDEOREC pThis, PAVRECSTREAM pStreamAV)
    438433{
    439434    RT_NOREF(pThis);
    440     PAVRECSTREAMOUT pStreamOut = (PAVRECSTREAMOUT)pStream;
    441 
    442     if (pStreamOut->pCircBuf)
    443     {
    444         RTCircBufDestroy(pStreamOut->pCircBuf);
    445         pStreamOut->pCircBuf = NULL;
     435
     436    if (pStreamAV->pCircBuf)
     437    {
     438        RTCircBufDestroy(pStreamAV->pCircBuf);
     439        pStreamAV->pCircBuf = NULL;
    446440    }
    447441
     
    455449 * @returns IPRT status code.
    456450 * @param   pThis               Driver instance.
    457  * @param   pStream             Audio output stream to control.
     451 * @param   pStreamAV           Audio output stream to control.
    458452 * @param   enmStreamCmd        Stream command to issue.
    459453 */
    460454static int avRecControlStreamOut(PDRVAUDIOVIDEOREC pThis,
    461                                  PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
    462 {
    463     AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
    464     AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    465     RT_NOREF(enmStreamCmd);
    466 
    467     RT_NOREF(pThis);
    468 
    469     LogFlowFunc(("enmStreamCmd=%ld\n", enmStreamCmd));
     455                                 PAVRECSTREAM pStreamAV, PDMAUDIOSTREAMCMD enmStreamCmd)
     456{
     457    RT_NOREF(pThis, pStreamAV);
    470458
    471459    switch (enmStreamCmd)
     
    520508 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture}
    521509 */
    522 static DECLCALLBACK(int) drvAudioVideoRecStreamCapture(PPDMIHOSTAUDIO pInterface,
    523                                                        PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
     510static DECLCALLBACK(int) drvAudioVideoRecStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
     511                                                       void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
    524512{
    525513    RT_NOREF(pInterface, pStream, pvBuf, cbBuf);
     
    535523 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay}
    536524 */
    537 static DECLCALLBACK(int) drvAudioVideoRecStreamPlay(PPDMIHOSTAUDIO pInterface,
    538                                                     PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf,
    539                                                     uint32_t *pcbWritten)
     525static DECLCALLBACK(int) drvAudioVideoRecStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
     526                                                    const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
    540527{
    541528    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     
    545532    /* pcbWritten is optional. */
    546533
    547     PDRVAUDIOVIDEOREC pThis      = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface);
     534    PDRVAUDIOVIDEOREC pThis     = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface);
    548535    RT_NOREF(pThis);
    549     PAVRECSTREAMOUT   pStreamOut = (PAVRECSTREAMOUT)pStream;
     536    PAVRECSTREAM      pStreamAV = (PAVRECSTREAM)pStream;
    550537
    551538    int rc = VINF_SUCCESS;
     
    557544     */
    558545#ifdef VBOX_WITH_LIBOPUS
    559     PAVRECSINK pSink    = pStreamOut->pSink;
     546    PAVRECSINK pSink    = pStreamAV->pSink;
    560547    AssertPtr(pSink);
    561     PRTCIRCBUF pCircBuf = pStreamOut->pCircBuf;
     548    PRTCIRCBUF pCircBuf = pStreamAV->pCircBuf;
    562549    AssertPtr(pCircBuf);
    563550
     
    598585
    599586    const uint32_t csFrame = pSink->Codec.Opus.csFrame;
    600     const uint32_t cbFrame = PDMAUDIOPCMPROPS_S2B(&pStreamOut->Props, csFrame);
     587    const uint32_t cbFrame = PDMAUDIOSTREAMCFG_S2B(pStreamAV->pCfg, csFrame);
    601588
    602589    while (RTCircBufUsed(pCircBuf) >= cbFrame)
     
    716703static DECLCALLBACK(int) drvAudioVideoRecGetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg)
    717704{
    718     NOREF(pInterface);
     705    RT_NOREF(pInterface);
    719706    AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER);
    720707
    721     pBackendCfg->cbStreamOut    = sizeof(AVRECSTREAMOUT);
     708    pBackendCfg->cbStreamOut    = sizeof(AVRECSTREAM);
    722709    pBackendCfg->cbStreamIn     = 0;
    723710    pBackendCfg->cMaxStreamsIn  = 0;
     
    756743 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate}
    757744 */
    758 static DECLCALLBACK(int) drvAudioVideoRecStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream,
     745static DECLCALLBACK(int) drvAudioVideoRecStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
    759746                                                      PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    760747{
    761748    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    762     AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    763749    AssertPtrReturn(pCfgReq,    VERR_INVALID_POINTER);
    764750    AssertPtrReturn(pCfgAcq,    VERR_INVALID_POINTER);
    765751
    766     PDRVAUDIOVIDEOREC pThis = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface);
     752    if (pCfgReq->enmDir == PDMAUDIODIR_IN)
     753        return VERR_NOT_SUPPORTED;
     754
     755    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
     756
     757    PDRVAUDIOVIDEOREC pThis     = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface);
     758    PAVRECSTREAM      pStreamAV = (PAVRECSTREAM)pStream;
    767759
    768760    /* For now we only have one sink, namely the driver's one.
     
    770762    PAVRECSINK pSink = &pThis->Sink;
    771763
    772     if (pCfgReq->enmDir == PDMAUDIODIR_OUT)
    773         return avRecCreateStreamOut(pThis, pStream, pSink, pCfgReq, pCfgAcq);
    774 
    775     return VERR_NOT_SUPPORTED;
     764    int rc = avRecCreateStreamOut(pThis, pStreamAV, pSink, pCfgReq, pCfgAcq);
     765    if (RT_SUCCESS(rc))
     766    {
     767        pStreamAV->pCfg = DrvAudioHlpStreamCfgDup(pCfgAcq);
     768        if (!pStreamAV->pCfg)
     769            rc = VERR_NO_MEMORY;
     770    }
     771
     772    return rc;
    776773}
    777774
     
    780777 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy}
    781778 */
    782 static DECLCALLBACK(int) drvAudioVideoRecStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     779static DECLCALLBACK(int) drvAudioVideoRecStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    783780{
    784781    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    785782    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    786783
    787     PDRVAUDIOVIDEOREC pThis = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface);
    788 
    789     if (pStream->enmDir == PDMAUDIODIR_OUT)
    790         return avRecDestroyStreamOut(pThis, pStream);
    791 
    792     return VINF_SUCCESS;
     784    PDRVAUDIOVIDEOREC pThis     = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface);
     785    PAVRECSTREAM      pStreamAV = (PAVRECSTREAM)pStream;
     786
     787    if (!pStreamAV->pCfg) /* Not (yet) configured? Skip. */
     788        return VINF_SUCCESS;
     789
     790    int rc = VINF_SUCCESS;
     791
     792    if (pStreamAV->pCfg->enmDir == PDMAUDIODIR_OUT)
     793        rc = avRecDestroyStreamOut(pThis, pStreamAV);
     794
     795    if (RT_SUCCESS(rc))
     796    {
     797        DrvAudioHlpStreamCfgFree(pStreamAV->pCfg);
     798        pStreamAV->pCfg = NULL;
     799    }
     800
     801    return rc;
    793802}
    794803
     
    798807 */
    799808static DECLCALLBACK(int) drvAudioVideoRecStreamControl(PPDMIHOSTAUDIO pInterface,
    800                                                        PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
     809                                                       PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
    801810{
    802811    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    803812    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    804813
    805     PDRVAUDIOVIDEOREC pThis = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface);
    806 
    807     Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST);
    808 
    809     if (pStream->enmDir == PDMAUDIODIR_OUT)
    810         return avRecControlStreamOut(pThis,  pStream, enmStreamCmd);
     814    PDRVAUDIOVIDEOREC pThis     = PDMIHOSTAUDIO_2_DRVAUDIOVIDEOREC(pInterface);
     815    PAVRECSTREAM      pStreamAV = (PAVRECSTREAM)pStream;
     816
     817    if (!pStreamAV->pCfg) /* Not (yet) configured? Skip. */
     818        return VINF_SUCCESS;
     819
     820    if (pStreamAV->pCfg->enmDir == PDMAUDIODIR_OUT)
     821        return avRecControlStreamOut(pThis, pStreamAV, enmStreamCmd);
    811822
    812823    return VINF_SUCCESS;
     
    817828 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
    818829 */
    819 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvAudioVideoRecStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
    820 {
    821     NOREF(pInterface);
    822     NOREF(pStream);
     830static DECLCALLBACK(PDMAUDIOSTRMSTS) drvAudioVideoRecStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
     831{
     832    RT_NOREF(pInterface);
     833    RT_NOREF(pStream);
    823834
    824835    return (  PDMAUDIOSTRMSTS_FLAG_INITIALIZED | PDMAUDIOSTRMSTS_FLAG_ENABLED
     
    830841 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate}
    831842 */
    832 static DECLCALLBACK(int) drvAudioVideoRecStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream)
     843static DECLCALLBACK(int) drvAudioVideoRecStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    833844{
    834845    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
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