VirtualBox

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


Ignore:
Timestamp:
Mar 24, 2021 11:45:54 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
143474
Message:

Audio: Made sure PDMAUDIOPCMPROPS is initialized using a helper function or the initializer macro, and that vital changes are made using setting helper functions. There are now two derived fields (frame size and shift count) that must be maintained, so this was the sanest way of doing it. Added a raw flag to PDMAUDIOPCMPROPS for VRDE/VRDP, since it wants the raw mixer content and we need a way of expressing this (PDMAUDIOSTREAMLAYOUT isn't the right place). The mixer buffers now uses PDMAUDIOPCMPROPS rather than the weird 32-bit format contraption for picking conversion functions. Simplify the drvAudioStreamPlay code by eliminating the PDMAUDIOSTREAMLAYOUT_RAW special case. bugref:9890

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

Legend:

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

    r88235 r88269  
    179179bool AudioHlpStreamCfgIsValid(PCPDMAUDIOSTREAMCFG pCfg)
    180180{
    181     AssertPtrReturn(pCfg, false);
    182 
    183     AssertReturn(PDMAudioStrmCfgIsValid(pCfg), false);
    184 
    185     bool fValid = (   pCfg->enmDir == PDMAUDIODIR_IN
    186                    || pCfg->enmDir == PDMAUDIODIR_OUT);
    187 
    188     fValid &= (   pCfg->enmLayout == PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED
    189                || pCfg->enmLayout == PDMAUDIOSTREAMLAYOUT_RAW);
    190 
    191     if (fValid)
    192         fValid = AudioHlpPcmPropsAreValid(&pCfg->Props);
    193 
    194     return fValid;
     181    /* Ugly! HDA attach code calls us with uninitialized (all zero) config. */
     182    if (   pCfg->enmLayout != PDMAUDIOSTREAMLAYOUT_INVALID
     183        || PDMAudioPropsHz(&pCfg->Props) != 0)
     184    {
     185        if (PDMAudioStrmCfgIsValid(pCfg))
     186        {
     187            if (   pCfg->enmDir == PDMAUDIODIR_IN
     188                || pCfg->enmDir == PDMAUDIODIR_OUT)
     189            {
     190                if (   pCfg->enmLayout == PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED
     191                    || pCfg->enmLayout == PDMAUDIOSTREAMLAYOUT_RAW)
     192                    return AudioHlpPcmPropsAreValid(&pCfg->Props);
     193            }
     194        }
     195    }
     196    return false;
    195197}
    196198
     
    219221 *        function will flag such properties as not valid.
    220222 *
    221  * @todo  r=bird: See note and explain properly.
     223 * @todo  r=bird: See note and explain properly. Perhaps rename to
     224 *        AudioHlpPcmPropsAreValidAndSupported?
    222225 *
    223226 * @returns @c true if the properties are valid, @c false if not.
     
    227230{
    228231    AssertPtrReturn(pProps, false);
    229 
    230232    AssertReturn(PDMAudioPropsAreValid(pProps), false);
    231233
    232     /** @todo r=bird: This code is cannot make up its mind whether to return on
    233      *        false, or whether to return at the end. (hint: just return
    234      *        immediately, duh.) */
    235 
    236234    /* Minimum 1 channel (mono), maximum 7.1 (= 8) channels. */
    237     bool fValid = (   pProps->cChannels >= 1
    238                    && pProps->cChannels <= 8);
    239 
    240     if (fValid)
    241     {
    242         switch (pProps->cbSample)
     235    if (PDMAudioPropsChannels(pProps) >= 1 && PDMAudioPropsChannels(pProps) <= 8)
     236    {
     237        switch (PDMAudioPropsSampleSize(pProps))
    243238        {
    244239            case 1: /* 8 bit */
    245                if (pProps->fSigned)
    246                    fValid = false;
     240               if (PDMAudioPropsIsSigned(pProps))
     241                   return false;
    247242               break;
    248243            case 2: /* 16 bit */
    249                 if (!pProps->fSigned)
    250                     fValid = false;
     244                if (!PDMAudioPropsIsSigned(pProps))
     245                    return false;
    251246                break;
    252247            /** @todo Do we need support for 24 bit samples? */
    253248            case 4: /* 32 bit */
    254                 if (!pProps->fSigned)
    255                     fValid = false;
     249                if (!PDMAudioPropsIsSigned(pProps))
     250                    return false;
     251                break;
     252            case 8: /* 64-bit raw */
     253                if (   !PDMAudioPropsIsSigned(pProps)
     254                    || !pProps->fRaw)
     255                    return false;
    256256                break;
    257257            default:
    258                 fValid = false;
    259                 break;
    260         }
    261     }
    262 
    263     if (!fValid)
    264         return false;
    265 
    266     fValid &= pProps->uHz > 0;
    267     fValid &= pProps->cShift == PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pProps->cbSample, pProps->cChannels);
    268     fValid &= pProps->fSwapEndian == false; /** @todo Handling Big Endian audio data is not supported yet. */
    269 
    270     return fValid;
     258                return false;
     259        }
     260
     261        if (pProps->uHz > 0)
     262        {
     263            if (!pProps->fSwapEndian) /** @todo Handling Big Endian audio data is not supported yet. */
     264                return true;
     265        }
     266    }
     267    return false;
    271268}
    272269
     
    520517    /** @todo Validate fOpen flags. */
    521518    AssertPtrReturn(pProps,  VERR_INVALID_POINTER);
     519    Assert(PDMAudioPropsAreValid(pProps));
    522520
    523521    int rc;
     
    529527    else if (pFile->enmType == PDMAUDIOFILETYPE_WAV)
    530528    {
    531         Assert(pProps->cChannels);
    532         Assert(pProps->uHz);
    533         Assert(pProps->cbSample);
    534 
    535529        pFile->pvData = (PAUDIOWAVFILEDATA)RTMemAllocZ(sizeof(AUDIOWAVFILEDATA));
    536530        if (pFile->pvData)
     
    549543            pData->Hdr.u32Size1         = 16; /* Means PCM. */
    550544            pData->Hdr.u16AudioFormat   = 1;  /* PCM, linear quantization. */
    551             pData->Hdr.u16NumChannels   = pProps->cChannels;
     545            pData->Hdr.u16NumChannels   = PDMAudioPropsChannels(pProps);
    552546            pData->Hdr.u32SampleRate    = pProps->uHz;
    553547            pData->Hdr.u32ByteRate      = PDMAudioPropsGetBitrate(pProps) / 8;
    554             pData->Hdr.u16BlockAlign    = pProps->cChannels * pProps->cbSample;
    555             pData->Hdr.u16BitsPerSample = pProps->cbSample * 8;
     548            pData->Hdr.u16BlockAlign    = PDMAudioPropsFrameSize(pProps);
     549            pData->Hdr.u16BitsPerSample = PDMAudioPropsSampleBits(pProps);
    556550
    557551            /* Data chunk. */
     
    584578
    585579    if (RT_SUCCESS(rc))
    586     {
    587580        LogRel2(("Audio: Opened file '%s'\n", pFile->szName));
    588     }
    589581    else
    590582        LogRel(("Audio: Failed opening file '%s', rc=%Rrc\n", pFile->szName, rc));
  • trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp

    r88253 r88269  
    4747#endif
    4848#include <VBox/err.h>
     49#include <VBox/vmm/pdmaudioinline.h>
    4950
    5051#include "AudioMixBuffer.h"
     
    5354# ifdef DEBUG
    5455#  define AUDMIXBUF_LOG(x) LogFlowFunc(x)
     56#  define AUDMIXBUF_LOG_ENABLED
    5557# else
    56 # define AUDMIXBUF_LOG(x) do {} while (0)
     58#  define AUDMIXBUF_LOG(x) do {} while (0)
    5759# endif
    5860#else /* VBOX_AUDIO_TESTCASE */
    5961# define AUDMIXBUF_LOG(x) RTPrintf x
     62# define AUDMIXBUF_LOG_ENABLED
    6063#endif
    6164
     
    136139
    137140/**
    138  * Peeks for audio frames without any conversion done.
    139  * This will get the raw frame data out of a mixing buffer.
    140  *
    141  * @return  IPRT status code or VINF_AUDIO_MORE_DATA_AVAILABLE if more data is available to read.
    142  *
    143  * @param   pMixBuf                 Mixing buffer to acquire audio frames from.
    144  * @param   cFramesToRead           Number of audio frames to read.
    145  * @param   paFrameBuf              Buffer where to store the returned audio frames.
    146  * @param   cFrameBuf               Size (in frames) of the buffer to store audio frames into.
    147  * @param   pcFramesRead            Returns number of read audio frames. Optional.
    148  *
    149  * @remark  This function is not thread safe!
    150  */
    151 /** @todo r=bird: This isn't a 'ing Peek function, it's a Read function!
    152  *        Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaarg!!!!!!!!!!!!!!!!!!! */
    153 int AudioMixBufPeek(PPDMAUDIOMIXBUF pMixBuf, uint32_t cFramesToRead,
    154                     PPDMAUDIOFRAME paFrameBuf, uint32_t cFrameBuf, uint32_t *pcFramesRead)
    155 {
    156     AssertPtrReturn(pMixBuf,    VERR_INVALID_POINTER);
    157     AssertPtrReturn(paFrameBuf, VERR_INVALID_POINTER);
    158     AssertReturn(cFrameBuf,     VERR_INVALID_PARAMETER);
    159     /* pcRead is optional. */
    160 
    161     int rc;
    162 
    163     if (!cFramesToRead)
    164     {
    165         if (pcFramesRead)
    166             *pcFramesRead = 0;
    167         return VINF_SUCCESS;
    168     }
    169 
    170     uint32_t cRead;
    171     if (pMixBuf->offRead + cFramesToRead > pMixBuf->cFrames)
    172     {
    173         cRead = pMixBuf->cFrames - pMixBuf->offRead;
    174         rc = VINF_AUDIO_MORE_DATA_AVAILABLE;
    175     }
    176     else
    177     {
    178         cRead = cFramesToRead;
    179         rc = VINF_SUCCESS;
    180     }
    181 
    182     if (cRead > cFrameBuf)
    183     {
    184         cRead = cFrameBuf;
    185         rc = VINF_AUDIO_MORE_DATA_AVAILABLE;
    186     }
    187 
    188     if (cRead)
    189     {
    190         memcpy(paFrameBuf, &pMixBuf->pFrames[pMixBuf->offRead], sizeof(PDMAUDIOFRAME) * cRead);
    191 
    192         pMixBuf->offRead = (pMixBuf->offRead + cRead) % pMixBuf->cFrames;
    193         Assert(pMixBuf->offRead <= pMixBuf->cFrames);
    194         pMixBuf->cUsed  -= RT_MIN(cRead, pMixBuf->cUsed);
    195     }
    196 
    197     if (pcFramesRead)
    198         *pcFramesRead = cRead;
    199 
    200     return rc;
    201 }
    202 
    203 /**
    204141 * Returns a mutable pointer to the mixing buffer's audio frame buffer for writing raw
    205142 * audio frames.
     
    213150 * @remark  This function is not thread safe!
    214151 */
     152/** @todo r=bird: This isn't a 'ing Peek function, it's a Read function!
     153 *        Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaarg!!!!!!!!!!!!!!!!!!! */
    215154int AudioMixBufPeekMutable(PPDMAUDIOMIXBUF pMixBuf, uint32_t cFrames,
    216155                           PPDMAUDIOFRAME *ppvFrames, uint32_t *pcFramesToWrite)
     
    281220    AssertStmt(cFramesToClear <= pMixBuf->cFrames, cFramesToClear = pMixBuf->cFrames);
    282221
     222/** @todo r=bird: Why isn't this done when reading/releaseing ? */
    283223    PPDMAUDIOMIXBUF pIter;
    284224    RTListForEach(&pMixBuf->lstChildren, pIter, PDMAUDIOMIXBUF, Node)
     
    291231    }
    292232
     233/** @todo r=bird: waste of time? */
    293234    uint32_t cClearOff;
    294235    uint32_t cClearLen;
     
    559500
    560501#undef AUDMIXBUF_CONVERT
     502
     503/*
     504 * Manually coded signed 64-bit conversion.
     505 */
     506#if 0
     507DECLCALLBACK(uint32_t) audioMixBufConvFromS64Stereo(PPDMAUDIOFRAME paDst, const void *pvSrc, uint32_t cbSrc,
     508                                                    PCPDMAUDMIXBUFCONVOPTS pOpts)
     509{
     510    _aType const *pSrc = (_aType const *)pvSrc;
     511    uint32_t cFrames = RT_MIN(pOpts->cFrames, cbSrc / sizeof(_aType));
     512    AUDMIXBUF_MACRO_LOG(("cFrames=%RU32, BpS=%zu, lVol=%RU32, rVol=%RU32\n",
     513                         pOpts->cFrames, sizeof(_aType), pOpts->From.Volume.uLeft, pOpts->From.Volume.uRight));
     514    for (uint32_t i = 0; i < cFrames; i++)
     515    {
     516        paDst->i64LSample = ASMMult2xS32RetS64((int32_t)audioMixBufClipFrom##_aName(*pSrc++), pOpts->From.Volume.uLeft ) >> AUDIOMIXBUF_VOL_SHIFT; \
     517        paDst->i64RSample = ASMMult2xS32RetS64((int32_t)audioMixBufClipFrom##_aName(*pSrc++), pOpts->From.Volume.uRight) >> AUDIOMIXBUF_VOL_SHIFT; \
     518        paDst++;
     519    }
     520
     521    return cFrames;
     522}
     523#endif
     524
     525DECLCALLBACK(void) audioMixBufConvToRawS64Stereo(void *pvDst, PCPDMAUDIOFRAME paSrc, PCPDMAUDMIXBUFCONVOPTS pOpts)
     526{
     527    AssertCompile(sizeof(paSrc[0]) == sizeof(int64_t) * 2);
     528    memcpy(pvDst, paSrc, sizeof(int64_t) * 2 * pOpts->cFrames);
     529}
     530
     531
     532
    561533
    562534#define AUDMIXBUF_MIXOP(_aName, _aOp) \
     
    674646
    675647/**
    676  * Looks up the matching conversion (macro) routine for converting
    677  * audio frames from a source format.
    678  *
    679  ** @todo Speed up the lookup by binding it to the actual stream state.
    680  *
    681  * @return  PAUDMIXBUF_FN_CONVFROM  Function pointer to conversion macro if found, NULL if not supported.
    682  * @param   enmFmt                  Audio format to lookup conversion macro for.
    683  */
    684 static PFNPDMAUDIOMIXBUFCONVFROM audioMixBufConvFromLookup(PDMAUDIOMIXBUFFMT enmFmt)
    685 {
    686     if (AUDMIXBUF_FMT_SIGNED(enmFmt))
    687     {
    688         if (AUDMIXBUF_FMT_CHANNELS(enmFmt) == 2)
     648 * Looks up the matching conversion function for converting audio frames from a
     649 * source format.
     650 *
     651 * @returns Pointer to matching conversion function, NULL if not supported.
     652 * @param   pProp       The audio format to find a "from" converter for.
     653 */
     654static PFNPDMAUDIOMIXBUFCONVFROM audioMixBufConvFromLookup(PCPDMAUDIOPCMPROPS pProps)
     655{
     656    if (PDMAudioPropsIsSigned(pProps))
     657    {
     658        switch (PDMAudioPropsChannels(pProps))
    689659        {
    690             switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt))
    691             {
    692                 case 8:  return audioMixBufConvFromS8Stereo;
    693                 case 16: return audioMixBufConvFromS16Stereo;
    694                 case 32: return audioMixBufConvFromS32Stereo;
    695                 default: return NULL;
    696             }
     660            case 2:
     661                switch (PDMAudioPropsSampleSize(pProps))
     662                {
     663                    case 1:  return audioMixBufConvFromS8Stereo;
     664                    case 2:  return audioMixBufConvFromS16Stereo;
     665                    case 4:  return audioMixBufConvFromS32Stereo;
     666                    //case 8:  return pProps->fRaw ? audioMixBufConvToRawS64Stereo : NULL;
     667                    default: return NULL;
     668                }
     669
     670            case 1:
     671                switch (PDMAudioPropsSampleSize(pProps))
     672                {
     673                    case 1:  return audioMixBufConvFromS8Mono;
     674                    case 2:  return audioMixBufConvFromS16Mono;
     675                    case 4:  return audioMixBufConvFromS32Mono;
     676                    default: return NULL;
     677                }
     678            default:
     679                return NULL;
    697680        }
    698         else
     681    }
     682    else /* Unsigned */
     683    {
     684        switch (PDMAudioPropsChannels(pProps))
    699685        {
    700             switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt))
    701             {
    702                 case 8:  return audioMixBufConvFromS8Mono;
    703                 case 16: return audioMixBufConvFromS16Mono;
    704                 case 32: return audioMixBufConvFromS32Mono;
    705                 default: return NULL;
    706             }
     686            case 2:
     687                switch (PDMAudioPropsSampleSize(pProps))
     688                {
     689                    case 1:  return audioMixBufConvFromU8Stereo;
     690                    case 2:  return audioMixBufConvFromU16Stereo;
     691                    case 4:  return audioMixBufConvFromU32Stereo;
     692                    default: return NULL;
     693                }
     694
     695            case 1:
     696                switch (PDMAudioPropsSampleSize(pProps))
     697                {
     698                    case 1:  return audioMixBufConvFromU8Mono;
     699                    case 2:  return audioMixBufConvFromU16Mono;
     700                    case 4:  return audioMixBufConvFromU32Mono;
     701                    default: return NULL;
     702                }
     703            default:
     704                return NULL;
    707705        }
    708706    }
     707    /* not reached */
     708}
     709
     710/**
     711 * Looks up the matching conversion function for converting audio frames to a
     712 * destination format.
     713 *
     714 * @returns Pointer to matching conversion function, NULL if not supported.
     715 * @param   pProp       The audio format to find a "to" converter for.
     716 */
     717static PFNPDMAUDIOMIXBUFCONVTO audioMixBufConvToLookup(PCPDMAUDIOPCMPROPS pProps)
     718{
     719    if (PDMAudioPropsIsSigned(pProps))
     720    {
     721        switch (PDMAudioPropsChannels(pProps))
     722        {
     723            case 2:
     724                switch (PDMAudioPropsSampleSize(pProps))
     725                {
     726                    case 1:  return audioMixBufConvToS8Stereo;
     727                    case 2:  return audioMixBufConvToS16Stereo;
     728                    case 4:  return audioMixBufConvToS32Stereo;
     729                    case 8:  return pProps->fRaw ? audioMixBufConvToRawS64Stereo : NULL;
     730                    default: return NULL;
     731                }
     732
     733            case 1:
     734                switch (PDMAudioPropsSampleSize(pProps))
     735                {
     736                    case 1:  return audioMixBufConvToS8Mono;
     737                    case 2:  return audioMixBufConvToS16Mono;
     738                    case 4:  return audioMixBufConvToS32Mono;
     739                    default: return NULL;
     740                }
     741            default:
     742                return NULL;
     743        }
     744    }
    709745    else /* Unsigned */
    710746    {
    711         if (AUDMIXBUF_FMT_CHANNELS(enmFmt) == 2)
     747        switch (PDMAudioPropsChannels(pProps))
    712748        {
    713             switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt))
    714             {
    715                 case 8:  return audioMixBufConvFromU8Stereo;
    716                 case 16: return audioMixBufConvFromU16Stereo;
    717                 case 32: return audioMixBufConvFromU32Stereo;
    718                 default: return NULL;
    719             }
    720         }
    721         else
    722         {
    723             switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt))
    724             {
    725                 case 8:  return audioMixBufConvFromU8Mono;
    726                 case 16: return audioMixBufConvFromU16Mono;
    727                 case 32: return audioMixBufConvFromU32Mono;
    728                 default: return NULL;
    729             }
    730         }
    731     }
    732     /* not reached */
    733 }
    734 
    735 /**
    736  * Looks up the matching conversion (macro) routine for converting
    737  * audio frames to a destination format.
    738  *
    739  ** @todo Speed up the lookup by binding it to the actual stream state.
    740  *
    741  * @return  PAUDMIXBUF_FN_CONVTO    Function pointer to conversion macro if found, NULL if not supported.
    742  * @param   enmFmt                  Audio format to lookup conversion macro for.
    743  */
    744 static PFNPDMAUDIOMIXBUFCONVTO audioMixBufConvToLookup(PDMAUDIOMIXBUFFMT enmFmt)
    745 {
    746     if (AUDMIXBUF_FMT_SIGNED(enmFmt))
    747     {
    748         if (AUDMIXBUF_FMT_CHANNELS(enmFmt) == 2)
    749         {
    750             switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt))
    751             {
    752                 case 8:  return audioMixBufConvToS8Stereo;
    753                 case 16: return audioMixBufConvToS16Stereo;
    754                 case 32: return audioMixBufConvToS32Stereo;
    755                 default: return NULL;
    756             }
    757         }
    758         else
    759         {
    760             switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt))
    761             {
    762                 case 8:  return audioMixBufConvToS8Mono;
    763                 case 16: return audioMixBufConvToS16Mono;
    764                 case 32: return audioMixBufConvToS32Mono;
    765                 default: return NULL;
    766             }
    767         }
    768     }
    769     else /* Unsigned */
    770     {
    771         if (AUDMIXBUF_FMT_CHANNELS(enmFmt) == 2)
    772         {
    773             switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt))
    774             {
    775                 case 8:  return audioMixBufConvToU8Stereo;
    776                 case 16: return audioMixBufConvToU16Stereo;
    777                 case 32: return audioMixBufConvToU32Stereo;
    778                 default: return NULL;
    779             }
    780         }
    781         else
    782         {
    783             switch (AUDMIXBUF_FMT_BITS_PER_SAMPLE(enmFmt))
    784             {
    785                 case 8:  return audioMixBufConvToU8Mono;
    786                 case 16: return audioMixBufConvToU16Mono;
    787                 case 32: return audioMixBufConvToU32Mono;
    788                 default: return NULL;
    789             }
     749            case 2:
     750                switch (PDMAudioPropsSampleSize(pProps))
     751                {
     752                    case 1:  return audioMixBufConvToU8Stereo;
     753                    case 2:  return audioMixBufConvToU16Stereo;
     754                    case 4:  return audioMixBufConvToU32Stereo;
     755                    default: return NULL;
     756                }
     757
     758            case 1:
     759                switch (PDMAudioPropsSampleSize(pProps))
     760                {
     761                    case 1:  return audioMixBufConvToU8Mono;
     762                    case 2:  return audioMixBufConvToU16Mono;
     763                    case 4:  return audioMixBufConvToU32Mono;
     764                    default: return NULL;
     765                }
     766            default:
     767                return NULL;
    790768        }
    791769    }
     
    826804 * @param   cFrames                 Maximum number of audio frames the mixing buffer can hold.
    827805 */
    828 int AudioMixBufInit(PPDMAUDIOMIXBUF pMixBuf, const char *pszName, PPDMAUDIOPCMPROPS pProps, uint32_t cFrames)
     806int AudioMixBufInit(PPDMAUDIOMIXBUF pMixBuf, const char *pszName, PCPDMAUDIOPCMPROPS pProps, uint32_t cFrames)
    829807{
    830808    AssertPtrReturn(pMixBuf, VERR_INVALID_POINTER);
    831809    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
    832810    AssertPtrReturn(pProps,  VERR_INVALID_POINTER);
     811    Assert(PDMAudioPropsAreValid(pProps));
    833812
    834813    pMixBuf->uMagic  = PDMAUDIOMIXBUF_MAGIC;
     
    857836    pMixBuf->pRate = NULL;
    858837
     838    /** @todo r=bird: Why invent a new representation for the mixer?  See also
     839     *        comment in pdmaudioifs.h about missing MAKE macros. */
    859840    pMixBuf->uAudioFmt = AUDMIXBUF_AUDIO_FMT_MAKE(pProps->uHz,
    860                                                  pProps->cChannels,
    861                                                  pProps->cbSample * 8 /* Bit */,
    862                                                  pProps->fSigned);
    863 
    864     pMixBuf->pfnConvFrom = audioMixBufConvFromLookup(pMixBuf->uAudioFmt);
    865     pMixBuf->pfnConvTo   = audioMixBufConvToLookup(pMixBuf->uAudioFmt);
    866 
    867     pMixBuf->cShift = pProps->cShift;
     841                                                  PDMAudioPropsChannels(pProps),
     842                                                  PDMAudioPropsSampleBits(pProps),
     843                                                  pProps->fSigned);
     844
     845    pMixBuf->Props       = *pProps;
     846    pMixBuf->pfnConvFrom = audioMixBufConvFromLookup(pProps);
     847    pMixBuf->pfnConvTo   = audioMixBufConvToLookup(pProps);
     848
    868849    pMixBuf->pszName = RTStrDup(pszName);
    869850    if (!pMixBuf->pszName)
    870851        return VERR_NO_MEMORY;
    871852
    872     AUDMIXBUF_LOG(("%s: uHz=%RU32, cChan=%RU8, cBits=%RU8, fSigned=%RTbool\n",
    873                    pMixBuf->pszName,
    874                    AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBuf->uAudioFmt),
    875                    AUDMIXBUF_FMT_CHANNELS(pMixBuf->uAudioFmt),
    876                    AUDMIXBUF_FMT_BITS_PER_SAMPLE(pMixBuf->uAudioFmt),
    877                    RT_BOOL(AUDMIXBUF_FMT_SIGNED(pMixBuf->uAudioFmt))));
     853
     854#ifdef AUDMIXBUF_LOG_ENABLED
     855    char szTmp[PDMAUDIOPROPSTOSTRING_MAX];
     856    AUDMIXBUF_LOG(("%s: %s\n", pMixBuf->pszName, PDMAudioPropsToString(pProps, szTmp, sizeof(szTmp))));
     857#endif
    878858
    879859    return audioMixBufAlloc(pMixBuf, cFrames);
     
    14561436 * @param   pcbRead                 Size (in bytes) of data read. Optional.
    14571437 */
    1458 int AudioMixBufReadAt(PPDMAUDIOMIXBUF pMixBuf,
    1459                       uint32_t offFrames,
    1460                       void *pvBuf, uint32_t cbBuf,
    1461                       uint32_t *pcbRead)
    1462 {
    1463     return AudioMixBufReadAtEx(pMixBuf, pMixBuf->uAudioFmt,
    1464                                offFrames, pvBuf, cbBuf, pcbRead);
     1438int AudioMixBufReadAt(PPDMAUDIOMIXBUF pMixBuf, uint32_t offFrames, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
     1439{
     1440    return AudioMixBufReadAtEx(pMixBuf, &pMixBuf->Props, offFrames, pvBuf, cbBuf, pcbRead);
    14651441}
    14661442
     
    14711447 *
    14721448 * @return  IPRT status code.
    1473  * @param   pMixBuf                 Mixing buffer to read audio frames from.
    1474  * @param   enmFmt                  Audio format to use for output.
    1475  * @param   offFrames               Offset (in audio frames) to start reading from.
    1476  * @param   pvBuf                   Pointer to buffer to write output to.
    1477  * @param   cbBuf                   Size (in bytes) of buffer to write to.
    1478  * @param   pcbRead                 Size (in bytes) of data read. Optional.
    1479  */
    1480 int AudioMixBufReadAtEx(PPDMAUDIOMIXBUF pMixBuf, PDMAUDIOMIXBUFFMT enmFmt,
    1481                         uint32_t offFrames,
    1482                         void *pvBuf, uint32_t cbBuf,
    1483                         uint32_t *pcbRead)
     1449 * @param   pMixBuf     Mixing buffer to read audio frames from.
     1450 * @param   pDstProps   The target format.
     1451 * @param   offFrames   Offset (in audio frames) to start reading from.
     1452 * @param   pvBuf       Pointer to buffer to write output to.
     1453 * @param   cbBuf       Size (in bytes) of buffer to write to.
     1454 * @param   pcbRead     Size (in bytes) of data read. Optional.
     1455 */
     1456int AudioMixBufReadAtEx(PPDMAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pDstProps,
     1457                        uint32_t offFrames, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
    14841458{
    14851459    AssertPtrReturn(pMixBuf, VERR_INVALID_POINTER);
     
    15011475    {
    15021476        PFNPDMAUDIOMIXBUFCONVTO pfnConvTo = NULL;
    1503         if (pMixBuf->uAudioFmt != enmFmt)
    1504             pfnConvTo = audioMixBufConvToLookup(enmFmt);
     1477        if (PDMAudioPropsAreEqual(&pMixBuf->Props, pDstProps))
     1478            pfnConvTo = pMixBuf->pfnConvTo;
    15051479        else
    1506             pfnConvTo = pMixBuf->pfnConvTo;
    1507 
     1480            pfnConvTo = audioMixBufConvToLookup(pDstProps);
    15081481        if (pfnConvTo)
    15091482        {
     
    15521525int AudioMixBufAcquireReadBlock(PPDMAUDIOMIXBUF pMixBuf, void *pvBuf, uint32_t cbBuf, uint32_t *pcAcquiredFrames)
    15531526{
    1554     return AudioMixBufAcquireReadBlockEx(pMixBuf, pMixBuf->uAudioFmt, pvBuf, cbBuf, pcAcquiredFrames);
     1527    return AudioMixBufAcquireReadBlockEx(pMixBuf, &pMixBuf->Props, pvBuf, cbBuf, pcAcquiredFrames);
    15551528}
    15561529
    15571530/**
    15581531 * Reads audio frames in a specific audio format.
     1532 *
    15591533 * If the audio format of the mixing buffer and the requested audio format do
    15601534 * not match the output will be converted accordingly.
    15611535 *
    1562  * @return  IPRT status code.
     1536 * @returns VBox status code.
    15631537 * @param   pMixBuf             Mixing buffer to read audio frames from.
    1564  * @param   enmFmt              Audio format to use for output.
     1538 * @param   pDstProps           The target format.
    15651539 * @param   pvBuf               Pointer to buffer to write output to.
    15661540 * @param   cbBuf               Size (in bytes) of buffer to write to.
     
    15681542 *                              the block that was acquired.
    15691543 */
    1570 int AudioMixBufAcquireReadBlockEx(PPDMAUDIOMIXBUF pMixBuf, PDMAUDIOMIXBUFFMT enmFmt,
     1544int AudioMixBufAcquireReadBlockEx(PPDMAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pDstProps,
    15711545                                  void *pvBuf, uint32_t cbBuf, uint32_t *pcAcquiredFrames)
    15721546{
     
    15811555    uint32_t cFramesToRead = RT_MIN(pMixBuf->cUsed, AUDIOMIXBUF_B2F(pMixBuf, cbBuf));
    15821556
    1583     AUDMIXBUF_LOG(("%s: cbBuf=%RU32 (%RU32 frames), cFramesToRead=%RU32, fmtSrc=0x%x, fmtDst=0x%x\n",
    1584                    pMixBuf->pszName, cbBuf, AUDIOMIXBUF_B2F(pMixBuf, cbBuf), cFramesToRead, pMixBuf->uAudioFmt, enmFmt));
    1585 
     1557#ifdef AUDMIXBUF_LOG_ENABLED
     1558    char szTmp1[PDMAUDIOPROPSTOSTRING_MAX], szTmp2[PDMAUDIOPROPSTOSTRING_MAX];
     1559#endif
     1560    AUDMIXBUF_LOG(("%s: cbBuf=%RU32 (%RU32 frames), cFramesToRead=%RU32, MixBuf=%s, pDstProps=%s\n",
     1561                   pMixBuf->pszName, cbBuf, AUDIOMIXBUF_B2F(pMixBuf, cbBuf), cFramesToRead,
     1562                   PDMAudioPropsToString(&pMixBuf->Props, szTmp1, sizeof(szTmp1)),
     1563                   PDMAudioPropsToString(pDstProps, szTmp2, sizeof(szTmp2))));
    15861564    if (!cFramesToRead)
    15871565    {
     
    15941572
    15951573    PFNPDMAUDIOMIXBUFCONVTO pfnConvTo;
    1596     if (pMixBuf->uAudioFmt == enmFmt)
     1574    if (PDMAudioPropsAreEqual(&pMixBuf->Props, pDstProps))
    15971575        pfnConvTo = pMixBuf->pfnConvTo;
    15981576    else
    1599         pfnConvTo = audioMixBufConvToLookup(enmFmt);
     1577        pfnConvTo = audioMixBufConvToLookup(pDstProps);
    16001578    AssertReturn(pfnConvTo, VERR_NOT_SUPPORTED);
    16011579
     
    17991777int AudioMixBufWriteAt(PPDMAUDIOMIXBUF pMixBuf, uint32_t offFrames, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten)
    18001778{
    1801     return AudioMixBufWriteAtEx(pMixBuf, pMixBuf->uAudioFmt, offFrames, pvBuf, cbBuf, pcWritten);
     1779    return AudioMixBufWriteAtEx(pMixBuf, &pMixBuf->Props, offFrames, pvBuf, cbBuf, pcWritten);
    18021780}
    18031781
     
    18121790 *
    18131791 * @return  IPRT status code.
    1814  * @param   pMixBuf                 Pointer to mixing buffer to write to.
    1815  * @param   enmFmt                  Audio format supplied in the buffer.
    1816  * @param   offFrames               Offset (in frames) starting to write at.
    1817  * @param   pvBuf                   Pointer to audio buffer to be written.
    1818  * @param   cbBuf                   Size (in bytes) of audio buffer.
    1819  * @param   pcWritten               Returns number of audio frames written. Optional.
    1820  */
    1821 int AudioMixBufWriteAtEx(PPDMAUDIOMIXBUF pMixBuf, PDMAUDIOMIXBUFFMT enmFmt,
    1822                          uint32_t offFrames, const void *pvBuf, uint32_t cbBuf,
    1823                          uint32_t *pcWritten)
     1792 * @param   pMixBuf     Pointer to mixing buffer to write to.
     1793 * @param   pSrcProps   The source format.
     1794 * @param   offFrames   Offset (in frames) starting to write at.
     1795 * @param   pvBuf       Pointer to audio buffer to be written.
     1796 * @param   cbBuf       Size (in bytes) of audio buffer.
     1797 * @param   pcWritten   Returns number of audio frames written. Optional.
     1798 */
     1799int AudioMixBufWriteAtEx(PPDMAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pSrcProps,
     1800                         uint32_t offFrames, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten)
    18241801{
    18251802    AssertPtrReturn(pMixBuf, VERR_INVALID_POINTER);
     
    18601837    if (!pMixBuf->Volume.fMuted)
    18611838    {
    1862         if (pMixBuf->uAudioFmt != enmFmt)
    1863             pfnConvFrom = audioMixBufConvFromLookup(enmFmt);
     1839        if (PDMAudioPropsAreEqual(&pMixBuf->Props, pSrcProps))
     1840            pfnConvFrom = pMixBuf->pfnConvFrom;
    18641841        else
    1865             pfnConvFrom = pMixBuf->pfnConvFrom;
     1842            pfnConvFrom = audioMixBufConvFromLookup(pSrcProps);
     1843        AssertReturn(pfnConvFrom, VERR_NOT_SUPPORTED);
    18661844    }
    18671845    else
     
    18711849
    18721850    uint32_t cWritten;
    1873     if (   pfnConvFrom
    1874         && cToWrite)
     1851    if (cToWrite)
    18751852    {
    18761853        PDMAUDMIXBUFCONVOPTS convOpts;
    18771854
    1878         convOpts.cFrames           = cToWrite;
     1855        convOpts.cFrames            = cToWrite;
    18791856        convOpts.From.Volume.fMuted = pMixBuf->Volume.fMuted;
    18801857        convOpts.From.Volume.uLeft  = pMixBuf->Volume.uLeft;
     
    18841861    }
    18851862    else
    1886     {
    18871863        cWritten = 0;
    1888         if (!pfnConvFrom)
    1889         {
    1890             AssertFailed();
    1891             rc = VERR_NOT_SUPPORTED;
    1892         }
    1893     }
    18941864
    18951865    AUDMIXBUF_LOG(("%s: offFrames=%RU32, cbBuf=%RU32, cToWrite=%RU32 (%zu bytes), cWritten=%RU32 (%zu bytes), rc=%Rrc\n",
     
    19291899 * @param   pcWritten               Returns number of audio frames written. Optional.
    19301900 */
    1931 int AudioMixBufWriteCirc(PPDMAUDIOMIXBUF pMixBuf,
    1932                          const void *pvBuf, uint32_t cbBuf,
    1933                          uint32_t *pcWritten)
    1934 {
    1935     return AudioMixBufWriteCircEx(pMixBuf, pMixBuf->uAudioFmt, pvBuf, cbBuf, pcWritten);
     1901int AudioMixBufWriteCirc(PPDMAUDIOMIXBUF pMixBuf, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten)
     1902{
     1903    return AudioMixBufWriteCircEx(pMixBuf, &pMixBuf->Props, pvBuf, cbBuf, pcWritten);
    19361904}
    19371905
     
    19411909 *
    19421910 * @return  IPRT status code, or VERR_BUFFER_OVERFLOW no space is available for writing anymore.
    1943  * @param   pMixBuf                 Pointer to mixing buffer to write to.
    1944  * @param   enmFmt                  Audio format supplied in the buffer.
    1945  * @param   pvBuf                   Pointer to audio buffer to be written.
    1946  * @param   cbBuf                   Size (in bytes) of audio buffer.
    1947  * @param   pcWritten               Returns number of audio frames written. Optional.
    1948  */
    1949 int AudioMixBufWriteCircEx(PPDMAUDIOMIXBUF pMixBuf, PDMAUDIOMIXBUFFMT enmFmt,
     1911 * @param   pMixBuf     Pointer to mixing buffer to write to.
     1912 * @param   pSrcProps   The source format.
     1913 * @param   enmFmt      Audio format supplied in the buffer.
     1914 * @param   pvBuf       Pointer to audio buffer to be written.
     1915 * @param   cbBuf       Size (in bytes) of audio buffer.
     1916 * @param   pcWritten   Returns number of audio frames written. Optional.
     1917 */
     1918int AudioMixBufWriteCircEx(PPDMAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pSrcProps,
    19501919                           const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten)
    19511920{
    19521921    AssertPtrReturn(pMixBuf, VERR_INVALID_POINTER);
    19531922    AssertPtrReturn(pvBuf,   VERR_INVALID_POINTER);
    1954     /* pcbWritten is optional. */
     1923    AssertPtrNullReturn(pcWritten, VERR_INVALID_POINTER);
    19551924
    19561925    if (!cbBuf)
     
    19701939    if (!pMixBuf->Volume.fMuted)
    19711940    {
    1972         if (pMixBuf->uAudioFmt != enmFmt)
    1973             pfnConvFrom = audioMixBufConvFromLookup(enmFmt);
     1941        if (PDMAudioPropsAreEqual(&pMixBuf->Props, pSrcProps))
     1942            pfnConvFrom = pMixBuf->pfnConvFrom;
    19741943        else
    1975             pfnConvFrom = pMixBuf->pfnConvFrom;
     1944            pfnConvFrom = audioMixBufConvFromLookup(pSrcProps);
     1945        AssertReturn(pfnConvFrom, VERR_NOT_SUPPORTED);
    19761946    }
    19771947    else
    19781948        pfnConvFrom = &audioMixBufConvFromSilence;
    1979 
    1980     if (!pfnConvFrom)
    1981     {
    1982         AssertFailed();
    1983         return VERR_NOT_SUPPORTED;
    1984     }
    19851949
    19861950    int rc = VINF_SUCCESS;
     
    20341998        *pcWritten = cWritten;
    20351999
    2036     AUDMIXBUF_LOG(("%s: enmFmt=0x%x, cbBuf=%RU32 (%RU32 frames), cWritten=%RU32, rc=%Rrc\n",
    2037                    pMixBuf->pszName, enmFmt, cbBuf, AUDIOMIXBUF_B2F(pMixBuf, cbBuf), cWritten, rc));
     2000#ifdef AUDMIXBUF_LOG_ENABLED
     2001    char szTmp[PDMAUDIOPROPSTOSTRING_MAX];
     2002#endif
     2003    AUDMIXBUF_LOG(("%s: pSrcProps=%s, cbBuf=%RU32 (%RU32 frames), cWritten=%RU32, rc=%Rrc\n", pMixBuf->pszName,
     2004                   PDMAudioPropsToString(pSrcProps, szTmp, sizeof(szTmp)), cbBuf, AUDIOMIXBUF_B2F(pMixBuf, cbBuf), cWritten, rc));
    20382005    return rc;
    20392006}
  • trunk/src/VBox/Devices/Audio/AudioMixBuffer.h

    r88253 r88269  
    2626
    2727/** Constructs 32 bit value for given frequency, number of channels, bits per sample and signed bit.
    28  *  Note: This currently matches 1:1 the VRDE encoding -- this might change in the future, so better don't rely on this fact! */
     28 * @note This currently matches 1:1 the VRDE encoding -- this might change in the future, so better don't rely on this fact! */
    2929#define AUDMIXBUF_AUDIO_FMT_MAKE(freq, c, bps, s) ((((s) & 0x1) << 28) + (((bps) & 0xFF) << 20) + (((c) & 0xF) << 16) + ((freq) & 0xFFFF))
    3030
     
    4040#define AUDMIXBUF_FMT_BYTES_PER_SAMPLE(a) ((AUDMIXBUF_AUDIO_FMT_BITS_PER_SAMPLE(a) + 7) / 8)
    4141
    42 /** Converts frames to bytes. */
    43 #define AUDIOMIXBUF_F2B(pBuf, frames) ((frames) << (pBuf)->cShift)
     42/** Converts (audio) frames to bytes. */
     43#define AUDIOMIXBUF_F2B(a_pMixBuf, a_cFrames)   PDMAUDIOPCMPROPS_F2B(&(a_pMixBuf)->Props, a_cFrames)
     44/** Converts bytes to (audio) frames.
     45 * @note Does *not* take the conversion ratio into account. */
     46#define AUDIOMIXBUF_B2F(a_pMixBuf, a_cb)        PDMAUDIOPCMPROPS_B2F(&(a_pMixBuf)->Props, a_cb)
     47
    4448/** Converts frames to bytes, respecting the conversion ratio to
    4549 *  a linked buffer. */
    46 #define AUDIOMIXBUF_F2B_RATIO(pBuf, frames) ((((int64_t) frames << 32) / (pBuf)->iFreqRatio) << (pBuf)->cShift)
    47 /** Converts bytes to frames, *not* taking the conversion ratio
    48  *  into account. */
    49 #define AUDIOMIXBUF_B2F(pBuf, cb)  (cb >> (pBuf)->cShift)
    50 /** Converts number of frames according to the buffer's ratio. */
    51 #define AUDIOMIXBUF_F2F_RATIO(pBuf, frames)  (((int64_t) frames << 32) / (pBuf)->iFreqRatio)
     50#define AUDIOMIXBUF_F2B_RATIO(a_pMixBuf, a_cFrames) AUDIOMIXBUF_F2B(a_pMixBuf, AUDIOMIXBUF_F2F_RATIO(a_pMixBuf, a_cFrames))
     51/** Converts number of frames according to the buffer's ratio.
     52 * @todo r=bird: Why the *signed* cast?  */
     53#define AUDIOMIXBUF_F2F_RATIO(a_pMixBuf, a_cFrames) (((int64_t)(a_cFrames) << 32) / (a_pMixBuf)->iFreqRatio)
    5254
    5355
     
    5860uint32_t AudioMixBufFree(PPDMAUDIOMIXBUF pMixBuf);
    5961uint32_t AudioMixBufFreeBytes(PPDMAUDIOMIXBUF pMixBuf);
    60 int AudioMixBufInit(PPDMAUDIOMIXBUF pMixBuf, const char *pszName, PPDMAUDIOPCMPROPS pProps, uint32_t cFrames);
     62int AudioMixBufInit(PPDMAUDIOMIXBUF pMixBuf, const char *pszName, PCPDMAUDIOPCMPROPS pProps, uint32_t cFrames);
    6163bool AudioMixBufIsEmpty(PPDMAUDIOMIXBUF pMixBuf);
    6264int AudioMixBufLinkTo(PPDMAUDIOMIXBUF pMixBuf, PPDMAUDIOMIXBUF pParent);
     
    6466int AudioMixBufMixToParent(PPDMAUDIOMIXBUF pMixBuf, uint32_t cSrcFrames, uint32_t *pcSrcMixed);
    6567int AudioMixBufMixToParentEx(PPDMAUDIOMIXBUF pMixBuf, uint32_t cSrcOffset, uint32_t cSrcFrames, uint32_t *pcSrcMixed);
    66 int AudioMixBufPeek(PPDMAUDIOMIXBUF pMixBuf, uint32_t cFramesToRead, PPDMAUDIOFRAME paSampleBuf, uint32_t cSampleBuf, uint32_t *pcFramesRead);
    6768int AudioMixBufPeekMutable(PPDMAUDIOMIXBUF pMixBuf, uint32_t cFramesToRead, PPDMAUDIOFRAME *ppvSamples, uint32_t *pcFramesRead);
    6869uint32_t AudioMixBufUsed(PPDMAUDIOMIXBUF pMixBuf);
    6970uint32_t AudioMixBufUsedBytes(PPDMAUDIOMIXBUF pMixBuf);
    70 int AudioMixBufReadAt(PPDMAUDIOMIXBUF pMixBuf, uint32_t offSamples, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead);
    71 int AudioMixBufReadAtEx(PPDMAUDIOMIXBUF pMixBuf, PDMAUDIOMIXBUFFMT enmFmt, uint32_t offSamples, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead);
    72 int AudioMixBufAcquireReadBlock(PPDMAUDIOMIXBUF pMixBuf, void *pvBuf, uint32_t cbBuf, uint32_t *pcAcquiredFrames);
    73 int AudioMixBufAcquireReadBlockEx(PPDMAUDIOMIXBUF pMixBuf, PDMAUDIOMIXBUFFMT enmFmt, void *pvBuf, uint32_t cbBuf, uint32_t *pcAcquiredFrames);
     71int         AudioMixBufReadAt(PPDMAUDIOMIXBUF pMixBuf, uint32_t offFrames, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead);
     72int         AudioMixBufReadAtEx(PPDMAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pDstProps, uint32_t offFrames,
     73                                void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead);
     74int         AudioMixBufAcquireReadBlock(PPDMAUDIOMIXBUF pMixBuf, void *pvBuf, uint32_t cbBuf, uint32_t *pcAcquiredFrames);
     75int         AudioMixBufAcquireReadBlockEx(PPDMAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pDstProps,
     76                                          void *pvBuf, uint32_t cbBuf, uint32_t *pcAcquiredFrames);
    7477void AudioMixBufReleaseReadBlock(PPDMAUDIOMIXBUF pMixBuf, uint32_t cFrames);
    7578uint32_t AudioMixBufReadPos(PPDMAUDIOMIXBUF pMixBuf);
     
    7982uint32_t AudioMixBufSizeBytes(PPDMAUDIOMIXBUF pMixBuf);
    8083void AudioMixBufUnlink(PPDMAUDIOMIXBUF pMixBuf);
    81 int AudioMixBufWriteAt(PPDMAUDIOMIXBUF pMixBuf, uint32_t offSamples, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
    82 int AudioMixBufWriteAtEx(PPDMAUDIOMIXBUF pMixBuf, PDMAUDIOMIXBUFFMT enmFmt, uint32_t offSamples, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
    83 int AudioMixBufWriteCirc(PPDMAUDIOMIXBUF pMixBuf, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
    84 int AudioMixBufWriteCircEx(PPDMAUDIOMIXBUF pMixBuf, PDMAUDIOMIXBUFFMT enmFmt, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
     84int         AudioMixBufWriteAt(PPDMAUDIOMIXBUF pMixBuf, uint32_t offSamples, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
     85int         AudioMixBufWriteAtEx(PPDMAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pSrcProps, uint32_t offFrames,
     86                                 const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
     87int         AudioMixBufWriteCirc(PPDMAUDIOMIXBUF pMixBuf, const void *pvBuf, uint32_t cbBuf, uint32_t *pcWritten);
     88int         AudioMixBufWriteCircEx(PPDMAUDIOMIXBUF pMixBuf, PCPDMAUDIOPCMPROPS pSrcProps,
     89                                   const void *pvBuf,uint32_t cbBuf, uint32_t *pcWritten);
    8590uint32_t AudioMixBufWritePos(PPDMAUDIOMIXBUF pMixBuf);
    8691
  • trunk/src/VBox/Devices/Audio/AudioMixer.cpp

    r88235 r88269  
    264264        }
    265265        else
    266             RTMemFree(pMixer);
     266            RTMemFree(pMixer); /** @todo leaks pszName due to badly structured code */
    267267    }
    268268    else
     
    611611        return rc;
    612612
    613     LogFlowFunc(("[%s] fFlags=0x%x (enmDir=%ld, %u bits, %RU8 channels, %RU32Hz)\n",
    614                  pSink->pszName, fFlags, pCfg->enmDir, pCfg->Props.cbSample * 8, pCfg->Props.cChannels, pCfg->Props.uHz));
     613    LogFlowFunc(("[%s] fFlags=0x%x (enmDir=%ld, %u bits, %RU8 channels, %RU32Hz)\n", pSink->pszName, fFlags, pCfg->enmDir,
     614                 PDMAudioPropsSampleBits(&pCfg->Props), PDMAudioPropsChannels(&pCfg->Props), pCfg->Props.uHz));
    615615
    616616    /*
     
    14881488
    14891489    if (pSink->PCMProps.uHz)
    1490         LogFlowFunc(("[%s] Old format: %u bit, %RU8 channels, %RU32Hz\n",
    1491                      pSink->pszName, pSink->PCMProps.cbSample * 8, pSink->PCMProps.cChannels, pSink->PCMProps.uHz));
     1490        LogFlowFunc(("[%s] Old format: %u bit, %RU8 channels, %RU32Hz\n", pSink->pszName,
     1491                     PDMAudioPropsSampleBits(&pSink->PCMProps), PDMAudioPropsChannels(&pSink->PCMProps), pSink->PCMProps.uHz));
    14921492
    14931493    memcpy(&pSink->PCMProps, pPCMProps, sizeof(PDMAUDIOPCMPROPS));
    14941494
    1495     LogFlowFunc(("[%s] New format %u bit, %RU8 channels, %RU32Hz\n",
    1496                  pSink->pszName, pSink->PCMProps.cbSample * 8, pSink->PCMProps.cChannels, pSink->PCMProps.uHz));
     1495    LogFlowFunc(("[%s] New format %u bit, %RU8 channels, %RU32Hz\n", pSink->pszName, PDMAudioPropsSampleBits(&pSink->PCMProps),
     1496                 PDMAudioPropsChannels(&pSink->PCMProps), pSink->PCMProps.uHz));
    14971497
    14981498    /* Also update the sink's mixing buffer format. */
  • trunk/src/VBox/Devices/Audio/DevHda.cpp

    r88235 r88269  
    14491449
    14501450# ifdef LOG_ENABLED
    1451                 PDMAUDIOPCMPROPS Props;
    1452                 rc2 = hdaR3SDFMTToPCMProps(HDA_STREAM_REG(pThis, FMT, uSD), &Props);
    1453                 AssertRC(rc2);
    1454                 LogFunc(("[SD%RU8] %RU32Hz, %RU8bit, %RU8 channel(s)\n",
    1455                          uSD, Props.uHz, Props.cbSample * 8 /* Bit */, Props.cChannels));
     1451                if (LogIsEnabled())
     1452                {
     1453                    PDMAUDIOPCMPROPS Props = { 0 };
     1454                    rc2 = hdaR3SDFMTToPCMProps(HDA_STREAM_REG(pThis, FMT, uSD), &Props); AssertRC(rc2);
     1455                    LogFunc(("[SD%RU8] %RU32Hz, %RU8bit, %RU8 channel(s)\n",
     1456                             uSD, Props.uHz, PDMAudioPropsSampleBits(&Props), PDMAudioPropsChannels(&Props)));
     1457                }
    14561458# endif
    14571459                /* (Re-)initialize the stream with current values. */
     
    16671669
    16681670    /** @todo Make the following configurable through mixer API and/or CFGM? */
    1669     switch (pCfg->Props.cChannels)
     1671    switch (PDMAudioPropsGetChannels(&pCfg->Props))
    16701672    {
    16711673        case 3:  /* 2.1: Front (Stereo) + LFE. */
     
    17061708    if (rc == VERR_NOT_SUPPORTED)
    17071709    {
    1708         LogRel2(("HDA: Warning: Unsupported channel count (%RU8), falling back to stereo channels (2)\n", pCfg->Props.cChannels));
     1710        LogRel2(("HDA: Warning: Unsupported channel count (%RU8), falling back to stereo channels (2)\n", pCfg->Props.cChannelsX));
    17091711
    17101712        /* Fall back to 2 channels (see below in fUseFront block). */
     
    17231725            pCfg->u.enmDst          = PDMAUDIOPLAYBACKDST_FRONT;
    17241726            pCfg->enmLayout         = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
    1725 
    1726             pCfg->Props.cShift      = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cbSample, pCfg->Props.cChannels);
     1727            /// @todo PDMAudioPropsSetChannels(&pCfg->Props, 2); ?
    17271728
    17281729            rc = hdaR3CodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_FRONT, pCfg);
     
    17371738            pCfg->u.enmDst          = PDMAUDIOPLAYBACKDST_CENTER_LFE;
    17381739            pCfg->enmLayout         = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
    1739 
    1740             pCfg->Props.cChannels   = (fUseCenter && fUseLFE) ? 2 : 1;
    1741             pCfg->Props.cShift      = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cbSample, pCfg->Props.cChannels);
     1740            PDMAudioPropsSetChannels(&pCfg->Props, fUseCenter && fUseLFE ? 2 : 1);
    17421741
    17431742            rc = hdaR3CodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_CENTER_LFE, pCfg);
     
    17511750            pCfg->u.enmDst          = PDMAUDIOPLAYBACKDST_REAR;
    17521751            pCfg->enmLayout         = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
    1753 
    1754             pCfg->Props.cChannels   = 2;
    1755             pCfg->Props.cShift      = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cbSample, pCfg->Props.cChannels);
     1752            PDMAudioPropsSetChannels(&pCfg->Props, 2);
    17561753
    17571754            rc = hdaR3CodecAddStream(pThisCC->pCodec, PDMAUDIOMIXERCTL_REAR, pCfg);
     
    19121909    int rc2 = hdaR3SDFMTToPCMProps(RT_LO_U16(u32Value), &Props);
    19131910    AssertRC(rc2);
    1914     LogFunc(("[SD%RU8] Set to %#x (%RU32Hz, %RU8bit, %RU8 channel(s))\n",
    1915              HDA_SD_NUM_FROM_REG(pThis, FMT, iReg), u32Value, Props.uHz, Props.cbSample * 8 /* Bit */, Props.cChannels));
     1911    LogFunc(("[SD%RU8] Set to %#x (%RU32Hz, %RU8bit, %RU8 channel(s))\n", HDA_SD_NUM_FROM_REG(pThis, FMT, iReg), u32Value,
     1912             PDMAudioPropsHz(&Props), PDMAudioPropsSampleBits(&Props), PDMAudioPropsChannels(&Props)));
    19161913
    19171914    /*
     
    23192316    AssertPtrReturn(pCfg,     VERR_INVALID_POINTER);
    23202317
    2321     LogFunc(("szSink=%s, szStream=%s, cChannels=%RU8\n", pMixSink->pszName, pCfg->szName, pCfg->Props.cChannels));
     2318    LogFunc(("szSink=%s, szStream=%s, cChannels=%RU8\n", pMixSink->pszName, pCfg->szName, PDMAudioPropsChannels(&pCfg->Props)));
    23222319
    23232320    PPDMAUDIOSTREAMCFG pStreamCfg = PDMAudioStrmCfgDup(pCfg);
     
    53565353        PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStreams[idxStream].State.Cfg.Props.uHz, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_BYTES,
    53575354                               "The stream frequency.",                     "Stream%u/Cfg/Hz", idxStream);
    5358         PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStreams[idxStream].State.Cfg.Props.cChannels, STAMTYPE_U8, STAMVISIBILITY_USED, STAMUNIT_BYTES,
     5355        PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStreams[idxStream].State.Cfg.Props.cbFrame, STAMTYPE_U8, STAMVISIBILITY_USED, STAMUNIT_BYTES,
     5356                               "The number of channels.",                   "Stream%u/Cfg/FrameSize-Host", idxStream);
     5357        PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.Mapping.GuestProps.cbFrame, STAMTYPE_U8, STAMVISIBILITY_USED, STAMUNIT_BYTES,
     5358                               "The number of channels.",                   "Stream%u/Cfg/FrameSize-Guest", idxStream);
     5359#if 0 /** @todo this would require some callback */
     5360        PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStreams[idxStream].State.Cfg.Props.cChannelsX, STAMTYPE_U8, STAMVISIBILITY_USED, STAMUNIT_BYTES,
    53595361                               "The number of channels.",                   "Stream%u/Cfg/Channels-Host", idxStream);
    53605362        PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.Mapping.GuestProps.cChannels, STAMTYPE_U8, STAMVISIBILITY_USED, STAMUNIT_BYTES,
     
    53625364        PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStreams[idxStream].State.Cfg.Props.cbSample, STAMTYPE_U8, STAMVISIBILITY_USED, STAMUNIT_BYTES,
    53635365                               "The size of a sample (per channel).",       "Stream%u/Cfg/cbSample", idxStream);
     5366#endif
    53645367    }
    53655368
  • trunk/src/VBox/Devices/Audio/DevHdaCommon.cpp

    r88235 r88269  
    2222*   Header Files                                                                                                                 *
    2323*********************************************************************************************************************************/
     24#define LOG_GROUP LOG_GROUP_DEV_HDA
    2425#include <iprt/assert.h>
    2526#include <iprt/errcore.h>
     
    2728
    2829#include <VBox/AssertGuest.h>
    29 
    30 #define LOG_GROUP LOG_GROUP_DEV_HDA
     30#include <VBox/vmm/pdmaudioinline.h>
     31
    3132#include <VBox/log.h>
    3233
     
    3435#include "DevHdaCommon.h"
    3536#include "DevHdaStream.h"
     37
    3638
    3739
     
    304306    }
    305307
    306     uint8_t cBytes = 0;
     308    uint8_t cbSample = 0;
    307309    switch (EXTRACT_VALUE(u16SDFMT, HDA_SDFMT_BITS_MASK, HDA_SDFMT_BITS_SHIFT))
    308310    {
    309311        case 0:
    310             cBytes = 1;
     312            cbSample = 1;
    311313            break;
    312314        case 1:
    313             cBytes = 2;
     315            cbSample = 2;
    314316            break;
    315317        case 4:
    316             cBytes = 4;
     318            cbSample = 4;
    317319            break;
    318320        default:
     
    324326
    325327    if (RT_SUCCESS(rc))
    326     {
    327         RT_BZERO(pProps, sizeof(PDMAUDIOPCMPROPS));
    328 
    329         pProps->cbSample  = cBytes;
    330         pProps->fSigned   = true;
    331         pProps->cChannels = (u16SDFMT & 0xf) + 1;
    332         pProps->uHz       = u32Hz * u32HzMult / u32HzDiv;
    333         pProps->cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pProps->cbSample, pProps->cChannels);
    334     }
     328        PDMAudioPropsInit(pProps, cbSample, true /*fSigned*/, (u16SDFMT & 0xf) + 1 /*cChannels*/, u32Hz * u32HzMult / u32HzDiv);
    335329
    336330# undef EXTRACT_VALUE
  • trunk/src/VBox/Devices/Audio/DevHdaStream.cpp

    r88235 r88269  
    739739
    740740    /* Serious paranoia: */
    741     ASSERT_GUEST_LOGREL_MSG_STMT(cbCircBuf % (pCfg->Props.cbSample * pCfg->Props.cChannels) == 0,
     741    ASSERT_GUEST_LOGREL_MSG_STMT(cbCircBuf % PDMAudioPropsFrameSize(&pCfg->Props) == 0,
    742742                                 ("Ring buffer size (%RU32) for stream #%RU8 not aligned to the (host) frame size (%RU8)\n",
    743                                   cbCircBuf, uSD, pCfg->Props.cbSample * pCfg->Props.cChannels),
     743                                  cbCircBuf, uSD, PDMAudioPropsFrameSize(&pCfg->Props)),
    744744                                 rc = VERR_INVALID_PARAMETER);
    745745    ASSERT_GUEST_LOGREL_MSG_STMT(cbCircBuf, ("Ring buffer size for stream #%RU8 is invalid\n", uSD),
  • trunk/src/VBox/Devices/Audio/DevHdaStreamMap.cpp

    r88235 r88269  
    209209     *        - have a simple (raw) data layout
    210210     *        - work in a non-striped fashion, e.g. interleaved (only on one SDn, not spread over multiple SDns) */
    211     if  (   pProps->cChannels == 1  /* Mono */
    212          || pProps->cChannels == 2  /* Stereo */
    213          || pProps->cChannels == 4  /* Quadrophonic */
    214          || pProps->cChannels == 6) /* Surround (5.1) */
     211    uint8_t cChannels = PDMAudioPropsChannels(pProps);
     212    if  (   cChannels == 1  /* Mono */
     213         || cChannels == 2  /* Stereo */
     214         || cChannels == 4  /* Quadrophonic */
     215         || cChannels == 6) /* Surround (5.1) */
    215216    {
    216217        /*
     
    218219         */
    219220        memcpy(&pMap->GuestProps, pProps, sizeof(PDMAUDIOPCMPROPS));
    220         if (pProps->cChannels != cHostChannels)
     221        if (cChannels != cHostChannels)
    221222        {
    222             if (pProps->cChannels == 1)
     223            if (cChannels == 1)
    223224                LogRelMax(32, ("HDA: Warning: Guest mono, host stereo.\n"));
    224             else if (cHostChannels == 1 && pProps->cChannels == 2)
     225            else if (cHostChannels == 1 && cChannels == 2)
    225226                LogRelMax(32, ("HDA: Warning: Host mono, guest stereo.\n"));
    226227            else
    227228#ifndef VBOX_WITH_AUDIO_HDA_51_SURROUND
    228229                LogRelMax(32, ("HDA: Warning: Guest configured %u channels, host only supports %u. Ignoring additional channels.\n",
    229                                pProps->cChannels, cHostChannels));
     230                               cChannels, cHostChannels));
    230231#else
    231232# error reconsider the above logic
    232233#endif
    233             pProps->cChannels = cHostChannels;
    234             pProps->cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT(pProps);
     234            PDMAudioPropsSetChannels(pProps, cHostChannels);
    235235        }
    236236
     
    238238         * Pick conversion functions.
    239239         */
    240         Assert(pMap->GuestProps.cbSample == pProps->cbSample);
     240        Assert(PDMAudioPropsSampleSize(&pMap->GuestProps) == PDMAudioPropsSampleSize(pProps));
    241241
    242242        /* If the channel count matches, we can use the memcpy converters: */
    243         if (pProps->cChannels == pMap->GuestProps.cChannels)
     243        if (PDMAudioPropsChannels(pProps) == PDMAudioPropsChannels(&pMap->GuestProps))
    244244        {
    245245            pMap->pfnGuestToHost = hdaR3StreamMap_GenericCopy;
     
    252252               first two channels and map this onto the host stereo ones. */
    253253            AssertReturn(cHostChannels == 2, VERR_NOT_SUPPORTED);
    254             switch (pMap->GuestProps.cbSample)
     254            switch (PDMAudioPropsSampleSize(&pMap->GuestProps))
    255255            {
    256256                case 2:
    257                     if (pMap->GuestProps.cChannels > 1)
     257                    if (PDMAudioPropsChannels(&pMap->GuestProps) > 1)
    258258                    {
    259259                        pMap->pfnGuestToHost = hdaR3StreamMap_G2H_GenericS16_NonMono2Stereo;
     
    268268
    269269                case 4:
    270                     if (pMap->GuestProps.cChannels > 1)
     270                    if (PDMAudioPropsChannels(&pMap->GuestProps) > 1)
    271271                    {
    272272                        pMap->pfnGuestToHost = hdaR3StreamMap_G2H_GenericS32_NonMono2Stereo;
     
    281281
    282282                default:
    283                     AssertMsgFailedReturn(("cbSample=%u\n", pMap->GuestProps.cbSample), VERR_NOT_SUPPORTED);
     283                    AssertMsgFailedReturn(("cbSample=%u\n", PDMAudioPropsChannels(&pMap->GuestProps)), VERR_NOT_SUPPORTED);
    284284            }
    285285            pMap->fMappingNeeded = true;
     
    297297            pMapLR->aenmIDs[0]  = PDMAUDIOSTREAMCHANNELID_FRONT_LEFT;
    298298            pMapLR->aenmIDs[1]  = PDMAUDIOSTREAMCHANNELID_FRONT_RIGHT;
    299             pMapLR->cbFrame     = pProps->cbSample * pProps->cChannels;
    300             pMapLR->cbStep      = pProps->cbSample * 2 /* Front left + Front right channels */;
     299            pMapLR->cbFrame     = PDMAudioPropsFrameSize(pProps);
     300            pMapLR->cbStep      = PDMAudioPropsSampleSize(pProps) * 2 /* Front left + Front right channels */;
    301301            pMapLR->offFirst    = 0;
    302302            pMapLR->offNext     = pMapLR->offFirst;
     
    334334    hdaR3StreamMapReset(pMap);
    335335
    336     pMap->cbGuestFrame = pProps->cChannels * pProps->cbSample;
     336    pMap->cbGuestFrame = PDMAudioPropsFrameSize(pProps);
    337337    int rc = hdaR3StreamMapSetup(pMap, pProps, cHostChannels);
    338338    if (RT_SUCCESS(rc))
     
    346346        {
    347347            LogFunc(("cChannels=%RU8, cBytes=%RU8 -> cbGuestFrame=%RU32\n",
    348                      pProps->cChannels, pProps->cbSample, pMap->cbGuestFrame));
     348                     PDMAudioPropsChannels(pProps), PDMAudioPropsSampleSize(pProps), pMap->cbGuestFrame));
    349349
    350350            Assert(pMap->cbGuestFrame); /* Frame size must not be 0. */
  • trunk/src/VBox/Devices/Audio/DevIchAc97.cpp

    r88234 r88269  
    21372137static int ichac97R3StreamOpen(PAC97STATE pThis, PAC97STATER3 pThisCC, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, bool fForce)
    21382138{
    2139     PDMAUDIOSTREAMCFG Cfg;
     2139    int                 rc = VINF_SUCCESS;
     2140    PAUDMIXSINK         pMixSink;
     2141    PDMAUDIOSTREAMCFG   Cfg;
    21402142    RT_ZERO(Cfg);
    2141     Cfg.Props.cChannels = 2;
    2142     Cfg.Props.cbSample  = 2 /* 16-bit */;
    2143     Cfg.Props.fSigned   = true;
    2144     Cfg.Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(Cfg.Props.cbSample, Cfg.Props.cChannels);
    2145 
    2146     int rc = VINF_SUCCESS;
    2147     PAUDMIXSINK pMixSink;
    21482143    switch (pStream->u8SD)
    21492144    {
    21502145        case AC97SOUNDSOURCE_PI_INDEX:
    21512146        {
    2152             Cfg.Props.uHz   = ichac97MixerGet(pThis, AC97_PCM_LR_ADC_Rate);
     2147            PDMAudioPropsInit(&Cfg.Props, 2 /*16-bit*/, true /*signed*/, 2 /*stereo*/,
     2148                              ichac97MixerGet(pThis, AC97_PCM_LR_ADC_Rate));
    21532149            Cfg.enmDir      = PDMAUDIODIR_IN;
    21542150            Cfg.u.enmSrc    = PDMAUDIORECSRC_LINE;
     
    21622158        case AC97SOUNDSOURCE_MC_INDEX:
    21632159        {
    2164             Cfg.Props.uHz   = ichac97MixerGet(pThis, AC97_MIC_ADC_Rate);
     2160            PDMAudioPropsInit(&Cfg.Props, 2 /*16-bit*/, true /*signed*/, 2 /*stereo*/,
     2161                              ichac97MixerGet(pThis, AC97_MIC_ADC_Rate));
    21652162            Cfg.enmDir      = PDMAUDIODIR_IN;
    21662163            Cfg.u.enmSrc    = PDMAUDIORECSRC_MIC;
     
    21742171        case AC97SOUNDSOURCE_PO_INDEX:
    21752172        {
    2176             Cfg.Props.uHz   = ichac97MixerGet(pThis, AC97_PCM_Front_DAC_Rate);
     2173            PDMAudioPropsInit(&Cfg.Props, 2 /*16-bit*/, true /*signed*/, 2 /*stereo*/,
     2174                              ichac97MixerGet(pThis, AC97_PCM_Front_DAC_Rate));
    21772175            Cfg.enmDir      = PDMAUDIODIR_OUT;
    21782176            Cfg.u.enmDst    = PDMAUDIOPLAYBACKDST_FRONT;
     
    21972195            || fForce)
    21982196        {
    2199             LogRel2(("AC97: (Re-)Opening stream '%s' (%RU32Hz, %RU8 channels, %s%RU8)\n",
    2200                      Cfg.szName, Cfg.Props.uHz, Cfg.Props.cChannels, Cfg.Props.fSigned ? "S" : "U", Cfg.Props.cbSample * 8));
     2197            LogRel2(("AC97: (Re-)Opening stream '%s' (%RU32Hz, %RU8 channels, %s%RU8)\n", Cfg.szName, Cfg.Props.uHz,
     2198                     PDMAudioPropsChannels(&Cfg.Props), Cfg.Props.fSigned ? "S" : "U",  PDMAudioPropsSampleBits(&Cfg.Props)));
    22012199
    22022200            LogFlowFunc(("[SD%RU8] uHz=%RU32\n", pStream->u8SD, Cfg.Props.uHz));
  • trunk/src/VBox/Devices/Audio/DevSB16.cpp

    r88234 r88269  
    910910    pCfg->u.enmDst        = PDMAUDIOPLAYBACKDST_FRONT;
    911911    pCfg->enmLayout       = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
    912 
    913     pCfg->Props.uHz       = pThis->freq;
    914     pCfg->Props.cChannels = 1; /* Mono */
    915     pCfg->Props.cbSample  = 1 /* 8-bit */;
    916     pCfg->Props.fSigned   = false;
    917     pCfg->Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cbSample, pCfg->Props.cChannels);
     912    PDMAudioPropsInit(&pCfg->Props, 1 /*8-bit*/, false /*fSigned*/, 1 /*mono*/, pThis->freq);
    918913
    919914    AssertCompile(sizeof(pCfg->szName) >= sizeof("Output"));
     
    18331828        PDMAUDIOSTREAMCFG Cfg;
    18341829        RT_ZERO(Cfg);
    1835 
    1836         Cfg.Props.uHz       = pThis->freq;
    1837         Cfg.Props.cChannels = 1 << pThis->fmt_stereo;
    1838         Cfg.Props.cbSample  = pThis->fmt_bits / 8;
    1839         Cfg.Props.fSigned   = RT_BOOL(pThis->fmt_signed);
    1840         Cfg.Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(Cfg.Props.cbSample, Cfg.Props.cChannels);
     1830        PDMAudioPropsInit(&Cfg.Props, pThis->fmt_bits / 8, pThis->fmt_signed != 0, 1 << pThis->fmt_stereo, pThis->freq);
    18411831
    18421832        if (!PDMAudioStrmCfgMatchesProps(&Cfg, &pThis->Out.Cfg.Props))
  • trunk/src/VBox/Devices/Audio/DrvAudio.cpp

    r88259 r88269  
    716716
    717717    LogRel2(("Audio: Creating stream '%s'\n", pStream->szName));
    718     LogRel2(("Audio: Guest %s format for '%s': %RU32Hz, %u%s, %RU8 %s\n",
     718    LogRel2(("Audio: Guest %s format for '%s': %RU32Hz, %u%s, %RU8 channel%s\n",
    719719             pCfgGuest->enmDir == PDMAUDIODIR_IN ? "recording" : "playback", pStream->szName,
    720              pCfgGuest->Props.uHz, pCfgGuest->Props.cbSample * 8, pCfgGuest->Props.fSigned ? "S" : "U",
    721              pCfgGuest->Props.cChannels, pCfgGuest->Props.cChannels == 1 ? "Channel" : "Channels"));
    722     LogRel2(("Audio: Requested host %s format for '%s': %RU32Hz, %u%s, %RU8 %s\n",
     720             pCfgGuest->Props.uHz, PDMAudioPropsSampleBits(&pCfgGuest->Props), pCfgGuest->Props.fSigned ? "S" : "U",
     721             PDMAudioPropsChannels(&pCfgGuest->Props), PDMAudioPropsChannels(&pCfgGuest->Props) == 1 ? "" : "s"));
     722    LogRel2(("Audio: Requested host %s format for '%s': %RU32Hz, %u%s, %RU8 channel%s\n",
    723723             pCfgHost->enmDir == PDMAUDIODIR_IN ? "recording" : "playback", pStream->szName,
    724              pCfgHost->Props.uHz, pCfgHost->Props.cbSample * 8, pCfgHost->Props.fSigned ? "S" : "U",
    725              pCfgHost->Props.cChannels, pCfgHost->Props.cChannels == 1 ? "Channel" : "Channels"));
     724             pCfgHost->Props.uHz, PDMAudioPropsSampleBits(&pCfgHost->Props), pCfgHost->Props.fSigned ? "S" : "U",
     725             PDMAudioPropsChannels(&pCfgHost->Props), PDMAudioPropsChannels(&pCfgHost->Props) == 1 ? "" : "s"));
    726726
    727727    PDMAUDIOSTREAMCFG CfgHostAcq;
     
    730730        return rc;
    731731
    732 #ifdef LOG_ENABLED
    733732    LogFunc(("[%s] Acquired host format:\n",  pStream->szName));
    734733    PDMAudioStrmCfgLog(&CfgHostAcq);
    735 #endif
    736 
    737     LogRel2(("Audio: Acquired host %s format for '%s': %RU32Hz, %u%s, %RU8 %s\n",
     734    LogRel2(("Audio: Acquired host %s format for '%s': %RU32Hz, %u%s, %RU8 channel%s\n",
    738735             CfgHostAcq.enmDir == PDMAUDIODIR_IN ? "recording" : "playback",  pStream->szName,
    739              CfgHostAcq.Props.uHz, CfgHostAcq.Props.cbSample * 8, CfgHostAcq.Props.fSigned ? "S" : "U",
    740              CfgHostAcq.Props.cChannels, CfgHostAcq.Props.cChannels == 1 ? "Channel" : "Channels"));
     736             CfgHostAcq.Props.uHz, PDMAudioPropsSampleBits(&CfgHostAcq.Props), CfgHostAcq.Props.fSigned ? "S" : "U",
     737             PDMAudioPropsChannels(&CfgHostAcq.Props), PDMAudioPropsChannels(&CfgHostAcq.Props) == 1 ? "" : "s"));
     738    Assert(PDMAudioPropsAreValid(&CfgHostAcq.Props));
    741739
    742740    /* Let the user know if the backend changed some of the tweakable values. */
     
    755753                 PDMAudioPropsFramesToMilli(&pCfgHost->Props, pCfgHost->Backend.cFramesPreBuffering), pCfgHost->Backend.cFramesPreBuffering,
    756754                 PDMAudioPropsFramesToMilli(&CfgHostAcq.Props, CfgHostAcq.Backend.cFramesPreBuffering), CfgHostAcq.Backend.cFramesPreBuffering));
     755
    757756    /*
    758757     * Configure host buffers.
     
    801800    AudioMixBufDestroy(&pStream->Host.MixBuf);
    802801
    803     /* Make sure to (re-)set the host buffer's shift size. */
    804     CfgHostAcq.Props.cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(CfgHostAcq.Props.cbSample, CfgHostAcq.Props.cChannels);
    805 
    806802    rc = AudioMixBufInit(&pStream->Host.MixBuf, pStream->szName, &CfgHostAcq.Props, CfgHostAcq.Backend.cFramesBufferSize);
    807803    AssertRC(rc);
     
    825821    /* Set the guests's default audio data layout. */
    826822    pCfgGuest->enmLayout = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
    827 
    828     /* Make sure to (re-)set the guest buffer's shift size. */
    829     pCfgGuest->Props.cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfgGuest->Props.cbSample, pCfgGuest->Props.cChannels);
    830823
    831824    rc = AudioMixBufInit(&pStream->Guest.MixBuf, pStream->szName, &pCfgGuest->Props, CfgHostAcq.Backend.cFramesBufferSize);
     
    14481441
    14491442/**
    1450  * Worker for drvAudioStreamPlay that plays non-interleaved data.
     1443 * Worker for drvAudioStreamPlay that does the actual playing.
    14511444 *
    14521445 * @returns VBox status code.
    14531446 * @param   pThis           The audio driver instance data.
    14541447 * @param   pStream         The stream to play.
    1455  * @param   cFramesToPlay   Number of audio frames to play.
     1448 * @param   cFramesToPlay   Number of audio frames to play.  The backend is
     1449 *                          supposed to have buffer space for this.
    14561450 * @param   pcFramesPlayed  Where to return the number of audio frames played.
    14571451 */
    1458 static int drvAudioStreamPlayNonInterleaved(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream,
    1459                                             uint32_t cFramesToPlay, uint32_t *pcFramesPlayed)
     1452static int drvAudioStreamPlayDoIt(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream, uint32_t cFramesToPlay, uint32_t *pcFramesPlayed)
    14601453{
    14611454    Assert(pStream->enmDir == PDMAUDIODIR_OUT);
    1462     Assert(pStream->Host.Cfg.enmLayout == PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED);
    14631455
    14641456    /*
     
    14901482        if (RT_SUCCESS(rc))
    14911483        {
    1492             if (cbPlayed)
    1493             {
    1494                 if (pThis->Out.Cfg.Dbg.fEnabled)
    1495                     AudioHlpFileWrite(pStream->Out.Dbg.pFilePlayNonInterleaved, abChunk, cbPlayed, 0 /* fFlags */);
    1496 
    1497                 if (cbRead != cbPlayed)
    1498                     LogRel2(("Audio: Host stream '%s' played wrong amount (%RU32 bytes read but played %RU32)\n",
    1499                              pStream->szName, cbRead, cbPlayed));
    1500 
    1501                 cFramesPlayed  = AUDIOMIXBUF_B2F(&pStream->Host.MixBuf, cbPlayed);
    1502                 AssertStmt(cFramesLeft >= cFramesPlayed, cFramesPlayed = cFramesLeft);
    1503                 cFramesLeft   -= cFramesPlayed;
    1504             }
    1505             else
    1506             {
    1507                 /** @todo r=bird: If the backend is doing non-blocking writes, we'll probably
    1508                  *        be spinning like crazy here...  The ALSA backend is non-blocking.   */
    1509             }
     1484            if (pThis->Out.Cfg.Dbg.fEnabled)
     1485                AudioHlpFileWrite(pStream->Out.Dbg.pFilePlayNonInterleaved, abChunk, cbPlayed, 0 /* fFlags */);
     1486
     1487            if (cbRead != cbPlayed)
     1488                LogRel2(("Audio: Host stream '%s' played wrong amount (%RU32 bytes read but played %RU32)\n",
     1489                         pStream->szName, cbRead, cbPlayed));
     1490
     1491            cFramesPlayed  = AUDIOMIXBUF_B2F(&pStream->Host.MixBuf, cbPlayed);
     1492            AssertStmt(cFramesLeft >= cFramesPlayed, cFramesPlayed = cFramesLeft);
     1493            cFramesLeft   -= cFramesPlayed;
    15101494        }
    15111495
     
    15131497
    15141498        AssertRCBreak(rc); /* (this is here for Acquire/Release symmetry - which isn't at all necessary) */
     1499        AssertBreak(cbPlayed > 0); /* (ditto) */
    15151500    }
    15161501
    15171502    Log3Func(("[%s] Played %RU32/%RU32 frames, rc=%Rrc\n", pStream->szName, cFramesToPlay - cFramesLeft, cFramesToPlay, rc));
    15181503    *pcFramesPlayed = cFramesToPlay - cFramesLeft;
    1519     return rc;
    1520 }
    1521 
    1522 /**
    1523  * Plays an audio host output stream which has been configured for raw audio (layout) data.
    1524  *
    1525  * @returns VBox status code.
    1526  * @param   pThis               Pointer to driver instance.
    1527  * @param   pStream             Stream to play.
    1528  * @param   cFramesToPlay       Number of audio frames to play.
    1529  * @param   pcFramesPlayed      Where to return number of audio frames played.
    1530  */
    1531 static int drvAudioStreamPlayRaw(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream, uint32_t cFramesToPlay, uint32_t *pcFramesPlayed)
    1532 {
    1533     Assert(pStream->enmDir == PDMAUDIODIR_OUT);
    1534     Assert(pStream->Host.Cfg.enmLayout == PDMAUDIOSTREAMLAYOUT_RAW);
    1535 
    1536     /*
    1537      * ...
    1538      */
    1539     int      rc          = VINF_SUCCESS;
    1540     uint32_t cFramesLeft = cFramesToPlay;
    1541     while (cFramesLeft > 0)
    1542     {
    1543         PDMAUDIOFRAME   aFrames[_2K];
    1544         uint32_t        cFramesRead = 0;
    1545         /** @todo r=bird: Peek functions do _not_ generally drop stuff from what they're
    1546          *        peeking into.  We normally name such functions Read.  (Oh man, am I
    1547          *        getting tired of this kind of crap.) */
    1548         rc = AudioMixBufPeek(&pStream->Host.MixBuf, cFramesLeft, aFrames,
    1549                              RT_MIN(cFramesLeft, RT_ELEMENTS(aFrames)), &cFramesRead);
    1550         if (RT_SUCCESS(rc))
    1551         {
    1552             Assert(cFramesRead <= RT_ELEMENTS(aFrames));
    1553             if (cFramesRead)
    1554             {
    1555                 uint32_t cbPlayed = 0;
    1556                 rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pStream->pvBackend,
    1557                                                          aFrames, cFramesRead * sizeof(aFrames[0]), &cbPlayed);
    1558                 AssertRCBreak(rc);
    1559                 /** @todo r=bird: This is a natural follow up to the non-peeking peek crap
    1560                  *        above.  It works because VRDE is the only consumer and it always
    1561                  *        processes all that it gets. */
    1562                 AssertBreakStmt(cbPlayed == cFramesRead * sizeof(aFrames[0]), rc = VERR_INTERNAL_ERROR_2);
    1563 
    1564                 Assert(cFramesRead <= cFramesLeft);
    1565                 cFramesLeft -= cFramesRead;
    1566             }
    1567             else
    1568             {
    1569 /** @todo r=bird: This looks totally loopy.  Why should another call return data
    1570  *        when the first one didn't? */
    1571                 if (rc == VINF_AUDIO_MORE_DATA_AVAILABLE) /* Do another peeking round if there is more data available. */
    1572                     continue;
    1573                 break;
    1574             }
    1575         }
    1576         else
    1577             break;
    1578     }
    1579 
    1580     *pcFramesPlayed = cFramesToPlay - cFramesLeft;
    1581     Log3Func(("[%s] Played %RU32/%RU32 frames, rc=%Rrc\n", pStream->szName, cFramesToPlay - cFramesLeft, cFramesToPlay, rc));
    15821504    return rc;
    15831505}
     
    16751597        if (cFramesLive >= pStream->Host.Cfg.Backend.cFramesPreBuffering)
    16761598        {
    1677             LogRel2(("Audio: Stream '%s' buffering complete\n", pStream->szName));
    1678             Log3Func(("[%s] Dbg: Buffering complete!\n", pStream->szName));
     1599            LogRel2(("Audio: Stream '%s' buffering complete!\n", pStream->szName));
    16791600            pStream->fThresholdReached = fJustStarted = true;
    16801601        }
     
    16901611                 && (pStream->fStatus & PDMAUDIOSTREAMSTS_FLAGS_PENDING_DISABLE))
    16911612        {
    1692             LogRel2(("Audio: Stream '%s' buffering complete (short sound)\n", pStream->szName));
    1693             Log3Func(("[%s] Dbg: Buffering complete (short)!\n", pStream->szName));
     1613            LogRel2(("Audio: Stream '%s' buffering complete (short sound)!\n", pStream->szName));
    16941614            pStream->fThresholdReached = fJustStarted = true;
    16951615        }
     
    17561676         *        https://stackoverflow.com/questions/17879933/whats-the-interleaved-audio
    17571677         */
    1758         if (RT_LIKELY(pStream->Host.Cfg.enmLayout == PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED))
    1759             rc = drvAudioStreamPlayNonInterleaved(pThis, pStream, cFramesToPlay, pcFramesPlayed);
    1760         else if (pStream->Host.Cfg.enmLayout == PDMAUDIOSTREAMLAYOUT_RAW)
    1761             rc = drvAudioStreamPlayRaw(pThis, pStream, cFramesToPlay, pcFramesPlayed);
    1762         else
    1763             AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
     1678        rc = drvAudioStreamPlayDoIt(pThis, pStream, cFramesToPlay, pcFramesPlayed);
    17641679
    17651680        if (pThis->pHostDrvAudio->pfnStreamPlayEnd)
     
    30853000     * PCM
    30863001     */
    3087     if (pDrvCfg->Props.cbSample) /* Anything set via custom extra-data? */
    3088     {
    3089         pCfgReq->Props.cbSample = pDrvCfg->Props.cbSample;
    3090         LogRel2(("Audio: Using custom sample size of %RU8 bytes for stream '%s'\n", pCfgReq->Props.cbSample, pStream->szName));
     3002    if (PDMAudioPropsSampleSize(&pDrvCfg->Props) != 0) /* Anything set via custom extra-data? */
     3003    {
     3004        PDMAudioPropsSetSampleSize(&pCfgReq->Props, PDMAudioPropsSampleSize(&pDrvCfg->Props));
     3005        LogRel2(("Audio: Using custom sample size of %RU8 bytes for stream '%s'\n",
     3006                 PDMAudioPropsSampleSize(&pCfgReq->Props), pStream->szName));
    30913007    }
    30923008
     
    31113027    }
    31123028
    3113     if (pDrvCfg->Props.cChannels) /* Anything set via custom extra-data? */
    3114     {
    3115         pCfgReq->Props.cChannels = pDrvCfg->Props.cChannels;
    3116         LogRel2(("Audio: Using custom %RU8 channel(s) for stream '%s'\n", pCfgReq->Props.cChannels, pStream->szName));
    3117     }
    3118 
    3119     /* Make sure to (re-)set the host buffer's shift size. */
    3120     pCfgReq->Props.cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfgReq->Props.cbSample, pCfgReq->Props.cChannels);
     3029    if (PDMAudioPropsChannels(&pDrvCfg->Props) != 0) /* Anything set via custom extra-data? */
     3030    {
     3031        PDMAudioPropsSetChannels(&pCfgReq->Props, PDMAudioPropsChannels(&pDrvCfg->Props));
     3032        LogRel2(("Audio: Using custom %RU8 channel(s) for stream '%s'\n", PDMAudioPropsChannels(&pDrvCfg->Props), pStream->szName));
     3033    }
    31213034
    31223035    /* Validate PCM properties. */
     
    32373150
    32383151    /* Validate acquired configuration. */
    3239     if (!AudioHlpStreamCfgIsValid(pCfgAcq))
    3240     {
    3241         LogRel(("Audio: Creating stream '%s' returned an invalid backend configuration, skipping\n", pStream->szName));
    3242         return VERR_INVALID_PARAMETER;
    3243     }
     3152    char szTmp[PDMAUDIOPROPSTOSTRING_MAX];
     3153    AssertLogRelMsgReturn(AudioHlpStreamCfgIsValid(pCfgAcq),
     3154                          ("Audio: Creating stream '%s' returned an invalid backend configuration (%s), skipping\n",
     3155                           pStream->szName, PDMAudioPropsToString(&pCfgAcq->Props, szTmp, sizeof(szTmp))),
     3156                          VERR_INVALID_PARAMETER);
    32443157
    32453158    /* Let the user know that the backend changed one of the values requested above. */
     
    36373550    }
    36383551
     3552    PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->Out.StatsReBuffering);
    36393553#ifdef VBOX_WITH_STATISTICS
    36403554    PDMDrvHlpSTAMDeregister(pDrvIns, &pThis->Stats.TotalStreamsActive);
     
    37873701        AssertRCReturn(rc, rc);
    37883702
    3789         QUERY_VAL_RET(8,  "PCMSampleBit",        &pAudioCfg->Props.cbSample,    0,
    3790                          pAudioCfg->Props.cbSample == 0
    3791                       || pAudioCfg->Props.cbSample == 8
    3792                       || pAudioCfg->Props.cbSample == 16
    3793                       || pAudioCfg->Props.cbSample == 32
    3794                       || pAudioCfg->Props.cbSample == 64,
     3703        uint8_t cSampleBits = 0;
     3704        QUERY_VAL_RET(8,  "PCMSampleBit",        &cSampleBits,                  0,
     3705                         cSampleBits == 0
     3706                      || cSampleBits == 8
     3707                      || cSampleBits == 16
     3708                      || cSampleBits == 32
     3709                      || cSampleBits == 64,
    37953710                      "Must be either 0, 8, 16, 32 or 64");
    3796         pAudioCfg->Props.cbSample /= 8;
    3797 
    3798         QUERY_VAL_RET(8,  "PCMSampleChannels",   &pAudioCfg->Props.cChannels,   0,
    3799                       pAudioCfg->Props.cChannels <= 16, "Max 16");
     3711        if (cSampleBits)
     3712            PDMAudioPropsSetSampleSize(&pAudioCfg->Props, cSampleBits / 8);
     3713
     3714        uint8_t cChannels;
     3715        QUERY_VAL_RET(8,  "PCMSampleChannels",   &cChannels,                    0, cChannels <= 16, "Max 16");
     3716        if (cChannels)
     3717            PDMAudioPropsSetChannels(&pAudioCfg->Props, cChannels);
    38003718
    38013719        QUERY_VAL_RET(32, "PCMSampleHz",         &pAudioCfg->Props.uHz,         0,
  • trunk/src/VBox/Devices/Audio/DrvHostAudioAlsa.cpp

    r88235 r88269  
    149149static snd_pcm_format_t alsaAudioPropsToALSA(PPDMAUDIOPCMPROPS pProps)
    150150{
    151     switch (pProps->cbSample)
     151    switch (PDMAudioPropsSampleSize(pProps))
    152152    {
    153153        case 1:
     
    155155
    156156        case 2:
    157             return pProps->fSigned ? SND_PCM_FORMAT_S16_LE : SND_PCM_FORMAT_U16_LE;
     157            if (PDMAudioPropsIsLittleEndian(pProps))
     158                return pProps->fSigned ? SND_PCM_FORMAT_S16_LE : SND_PCM_FORMAT_U16_LE;
     159            return pProps->fSigned ? SND_PCM_FORMAT_S16_BE : SND_PCM_FORMAT_U16_BE;
    158160
    159161        case 4:
    160             return pProps->fSigned ? SND_PCM_FORMAT_S32_LE : SND_PCM_FORMAT_U32_LE;
     162            if (PDMAudioPropsIsLittleEndian(pProps))
     163                return pProps->fSigned ? SND_PCM_FORMAT_S32_LE : SND_PCM_FORMAT_U32_LE;
     164            return pProps->fSigned ? SND_PCM_FORMAT_S32_BE : SND_PCM_FORMAT_U32_BE;
    161165
    162166        default:
    163             break;
    164     }
    165 
    166     AssertMsgFailed(("%RU8 bytes not supported\n", pProps->cbSample));
    167     return SND_PCM_FORMAT_U8;
     167            AssertMsgFailed(("%RU8 bytes not supported\n", PDMAudioPropsSampleSize(pProps)));
     168            return SND_PCM_FORMAT_U8;
     169    }
    168170}
    169171
     
    173175 *
    174176 * @returns VBox status code.
    175  * @param   fmt                 ALSA PCM format to convert.
    176  * @param   pProps              Where to store the converted PCM properties on success.
    177  */
    178 static int alsaALSAToAudioProps(snd_pcm_format_t fmt, PPDMAUDIOPCMPROPS pProps)
    179 {
     177 * @param   pProps      Where to store the converted PCM properties on success.
     178 * @param   fmt         ALSA PCM format to convert.
     179 * @param   cChannels   Number of channels.
     180 * @param   uHz         Frequency.
     181 */
     182static int alsaALSAToAudioProps(PPDMAUDIOPCMPROPS pProps, snd_pcm_format_t fmt, int cChannels, unsigned uHz)
     183{
     184    AssertReturn(cChannels > 0, VERR_INVALID_PARAMETER);
     185    AssertReturn(cChannels < 16, VERR_INVALID_PARAMETER);
    180186    switch (fmt)
    181187    {
    182188        case SND_PCM_FORMAT_S8:
    183             pProps->cbSample    = 1;
    184             pProps->fSigned     = true;
    185             pProps->fSwapEndian = false;
     189            PDMAudioPropsInit(pProps, 1 /*8-bit*/,  true /*signed*/, cChannels, uHz);
    186190            break;
    187191
    188192        case SND_PCM_FORMAT_U8:
    189             pProps->cbSample    = 1;
    190             pProps->fSigned     = false;
    191             pProps->fSwapEndian = false;
     193            PDMAudioPropsInit(pProps, 1 /*8-bit*/, false /*signed*/, cChannels, uHz);
    192194            break;
    193195
    194196        case SND_PCM_FORMAT_S16_LE:
    195             pProps->cbSample    = 2;
    196             pProps->fSigned     = true;
    197             pProps->fSwapEndian = false;
     197            PDMAudioPropsInitEx(pProps, 2 /*16-bit*/,  true /*signed*/, cChannels, uHz, true /*fLittleEndian*/, false /*fRaw*/);
    198198            break;
    199199
    200200        case SND_PCM_FORMAT_U16_LE:
    201             pProps->cbSample    = 2;
    202             pProps->fSigned     = false;
    203             pProps->fSwapEndian = false;
     201            PDMAudioPropsInitEx(pProps, 2 /*16-bit*/, false /*signed*/, cChannels, uHz, true /*fLittleEndian*/, false /*fRaw*/);
    204202            break;
    205203
    206204        case SND_PCM_FORMAT_S16_BE:
    207             pProps->cbSample    = 2;
    208             pProps->fSigned     = true;
    209 #ifdef RT_LITTLE_ENDIAN
    210             pProps->fSwapEndian = true;
    211 #endif
     205            PDMAudioPropsInitEx(pProps, 2 /*16-bit*/,  true /*signed*/, cChannels, uHz, false /*fLittleEndian*/, false /*fRaw*/);
    212206            break;
    213207
    214208        case SND_PCM_FORMAT_U16_BE:
    215             pProps->cbSample    = 2;
    216             pProps->fSigned     = false;
    217 #ifdef RT_LITTLE_ENDIAN
    218             pProps->fSwapEndian = true;
    219 #endif
     209            PDMAudioPropsInitEx(pProps, 2 /*16-bit*/, false /*signed*/, cChannels, uHz, false /*fLittleEndian*/, false /*fRaw*/);
    220210            break;
    221211
    222212        case SND_PCM_FORMAT_S32_LE:
    223             pProps->cbSample    = 4;
    224             pProps->fSigned     = true;
    225             pProps->fSwapEndian = false;
     213            PDMAudioPropsInitEx(pProps, 4 /*32-bit*/,  true /*signed*/, cChannels, uHz, true /*fLittleEndian*/, false /*fRaw*/);
    226214            break;
    227215
    228216        case SND_PCM_FORMAT_U32_LE:
    229             pProps->cbSample    = 4;
    230             pProps->fSigned     = false;
    231             pProps->fSwapEndian = false;
     217            PDMAudioPropsInitEx(pProps, 4 /*32-bit*/, false /*signed*/, cChannels, uHz, true /*fLittleEndian*/, false /*fRaw*/);
    232218            break;
    233219
    234220        case SND_PCM_FORMAT_S32_BE:
    235             pProps->cbSample    = 4;
    236             pProps->fSigned     = true;
    237 #ifdef RT_LITTLE_ENDIAN
    238             pProps->fSwapEndian = true;
    239 #endif
     221            PDMAudioPropsInitEx(pProps, 4 /*32-bit*/,  true /*signed*/, cChannels, uHz, false /*fLittleEndian*/, false /*fRaw*/);
    240222            break;
    241223
    242224        case SND_PCM_FORMAT_U32_BE:
    243             pProps->cbSample    = 4;
    244             pProps->fSigned     = false;
    245 #ifdef RT_LITTLE_ENDIAN
    246             pProps->fSwapEndian = true;
    247 #endif
     225            PDMAudioPropsInitEx(pProps, 4 /*32-bit*/, false /*signed*/, cChannels, uHz, false /*fLittleEndian*/, false /*fRaw*/);
    248226            break;
    249227
     
    251229            AssertMsgFailedReturn(("Format %d not supported\n", fmt), VERR_NOT_SUPPORTED);
    252230    }
    253 
    254     AssertReturn(pProps->cbSample > 0,  VERR_NOT_SUPPORTED);
    255     AssertReturn(pProps->cChannels > 0, VERR_INVALID_PARAMETER);
    256 
    257     pProps->cShift = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pProps->cbSample, pProps->cChannels);
    258 
    259231    return VINF_SUCCESS;
    260232}
     
    937909        ALSAAUDIOSTREAMCFG req;
    938910        req.fmt         = alsaAudioPropsToALSA(&pCfgReq->Props);
    939         req.freq        = pCfgReq->Props.uHz;
    940         req.nchannels   = pCfgReq->Props.cChannels;
     911        req.freq        = PDMAudioPropsHz(&pCfgReq->Props);
     912        req.nchannels   = PDMAudioPropsChannels(&pCfgReq->Props);
    941913        req.period_size = pCfgReq->Backend.cFramesPeriod;
    942914        req.buffer_size = pCfgReq->Backend.cFramesBufferSize;
     
    948920            break;
    949921
    950         pCfgAcq->Props.uHz       = obt.freq;
    951         pCfgAcq->Props.cChannels = obt.nchannels;
    952 
    953         rc = alsaALSAToAudioProps(obt.fmt, &pCfgAcq->Props);
     922        rc = alsaALSAToAudioProps(&pCfgAcq->Props, obt.fmt, obt.nchannels, obt.freq);
    954923        if (RT_FAILURE(rc))
    955924            break;
     
    1000969        ALSAAUDIOSTREAMCFG req;
    1001970        req.fmt         = alsaAudioPropsToALSA(&pCfgReq->Props);
    1002         req.freq        = pCfgReq->Props.uHz;
    1003         req.nchannels   = pCfgReq->Props.cChannels;
     971        req.freq        = PDMAudioPropsHz(&pCfgReq->Props);
     972        req.nchannels   = PDMAudioPropsChannels(&pCfgReq->Props);
    1004973        req.period_size = PDMAudioPropsMilliToFrames(&pCfgReq->Props, 50 /*ms*/); /** @todo Make this configurable. */
    1005974        req.buffer_size = req.period_size * 2; /** @todo Make this configurable. */
     
    1011980            break;
    1012981
    1013         pCfgAcq->Props.uHz       = obt.freq;
    1014         pCfgAcq->Props.cChannels = obt.nchannels;
    1015 
    1016         rc = alsaALSAToAudioProps(obt.fmt, &pCfgAcq->Props);
     982        rc = alsaALSAToAudioProps(&pCfgAcq->Props, obt.fmt, obt.nchannels, obt.freq);
    1017983        if (RT_FAILURE(rc))
    1018984            break;
  • trunk/src/VBox/Devices/Audio/DrvHostAudioCoreAudio.cpp

    r88235 r88269  
    150150    char pszSampleRate[32];
    151151    LogRel2(("CoreAudio: %s description:\n", pszDesc));
    152     LogRel2(("CoreAudio:\tFormat ID: %RU32 (%c%c%c%c)\n", pASBD->mFormatID,
     152    LogRel2(("CoreAudio:  Format ID: %RU32 (%c%c%c%c)\n", pASBD->mFormatID,
    153153             RT_BYTE4(pASBD->mFormatID), RT_BYTE3(pASBD->mFormatID),
    154154             RT_BYTE2(pASBD->mFormatID), RT_BYTE1(pASBD->mFormatID)));
    155     LogRel2(("CoreAudio:\tFlags: %RU32", pASBD->mFormatFlags));
     155    LogRel2(("CoreAudio:  Flags: %RU32", pASBD->mFormatFlags));
    156156    if (pASBD->mFormatFlags & kAudioFormatFlagIsFloat)
    157157        LogRel2((" Float"));
     
    171171        LogRel2((" AllClear"));
    172172    LogRel2(("\n"));
    173     snprintf(pszSampleRate, 32, "%.2f", (float)pASBD->mSampleRate); /** @todo r=andy Use RTStrPrint*. */
    174     LogRel2(("CoreAudio:\tSampleRate      : %s\n", pszSampleRate));
    175     LogRel2(("CoreAudio:\tChannelsPerFrame: %RU32\n", pASBD->mChannelsPerFrame));
    176     LogRel2(("CoreAudio:\tFramesPerPacket : %RU32\n", pASBD->mFramesPerPacket));
    177     LogRel2(("CoreAudio:\tBitsPerChannel  : %RU32\n", pASBD->mBitsPerChannel));
    178     LogRel2(("CoreAudio:\tBytesPerFrame   : %RU32\n", pASBD->mBytesPerFrame));
    179     LogRel2(("CoreAudio:\tBytesPerPacket  : %RU32\n", pASBD->mBytesPerPacket));
    180 }
    181 
    182 static void coreAudioPCMPropsToASBD(PDMAUDIOPCMPROPS *pPCMProps, AudioStreamBasicDescription *pASBD)
    183 {
    184     AssertPtrReturnVoid(pPCMProps);
     173    LogRel2(("CoreAudio:  SampleRate      : %RU64.%02u Hz\n",
     174             (uint64_t)pASBD->mSampleRate, (unsigned)(pASBD->mSampleRate * 100) % 100));
     175    LogRel2(("CoreAudio:  ChannelsPerFrame: %RU32\n", pASBD->mChannelsPerFrame));
     176    LogRel2(("CoreAudio:  FramesPerPacket : %RU32\n", pASBD->mFramesPerPacket));
     177    LogRel2(("CoreAudio:  BitsPerChannel  : %RU32\n", pASBD->mBitsPerChannel));
     178    LogRel2(("CoreAudio:  BytesPerFrame   : %RU32\n", pASBD->mBytesPerFrame));
     179    LogRel2(("CoreAudio:  BytesPerPacket  : %RU32\n", pASBD->mBytesPerPacket));
     180}
     181
     182static void coreAudioPCMPropsToASBD(PCPDMAUDIOPCMPROPS pProps, AudioStreamBasicDescription *pASBD)
     183{
     184    AssertPtrReturnVoid(pProps);
    185185    AssertPtrReturnVoid(pASBD);
    186186
     
    189189    pASBD->mFormatID         = kAudioFormatLinearPCM;
    190190    pASBD->mFormatFlags      = kAudioFormatFlagIsPacked;
     191    if (pProps->fSigned)
     192        pASBD->mFormatFlags |= kAudioFormatFlagIsSignedInteger;
     193    if (PDMAudioPropsIsBigEndian(pProps))
     194        pASBD->mFormatFlags |= kAudioFormatFlagIsBigEndian;
     195    pASBD->mSampleRate       = PDMAudioPropsHz(pProps);
     196    pASBD->mChannelsPerFrame = PDMAudioPropsChannels(pProps);
     197    pASBD->mBitsPerChannel   = PDMAudioPropsSampleBits(pProps);
     198    pASBD->mBytesPerFrame    = PDMAudioPropsFrameSize(pProps);
    191199    pASBD->mFramesPerPacket  = 1; /* For uncompressed audio, set this to 1. */
    192     pASBD->mSampleRate       = (Float64)pPCMProps->uHz;
    193     pASBD->mChannelsPerFrame = pPCMProps->cChannels;
    194     pASBD->mBitsPerChannel   = pPCMProps->cbSample * 8;
    195     if (pPCMProps->fSigned)
    196         pASBD->mFormatFlags |= kAudioFormatFlagIsSignedInteger;
    197     pASBD->mBytesPerFrame    = pASBD->mChannelsPerFrame * (pASBD->mBitsPerChannel / 8);
    198     pASBD->mBytesPerPacket   = pASBD->mFramesPerPacket * pASBD->mBytesPerFrame;
     200    pASBD->mBytesPerPacket   = PDMAudioPropsFrameSize(pProps) * pASBD->mFramesPerPacket;
    199201}
    200202
     
    205207    AssertPtrReturn(pCfg,  VERR_INVALID_PARAMETER);
    206208
    207     pCfg->Props.cChannels = pASBD->mChannelsPerFrame;
    208     pCfg->Props.uHz       = (uint32_t)pASBD->mSampleRate;
    209     AssertMsg(!(pASBD->mBitsPerChannel & 7), ("%u\n", pASBD->mBitsPerChannel));
    210     pCfg->Props.cbSample  = pASBD->mBitsPerChannel / 8;
    211     pCfg->Props.fSigned   = RT_BOOL(pASBD->mFormatFlags & kAudioFormatFlagIsSignedInteger);
    212     pCfg->Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cbSample, pCfg->Props.cChannels);
    213     /** @todo r=bird: pCfg->Props.fSwapEndian is not initialized here!  */
    214 
     209    AssertLogRelMsgReturn(pASBD->mChannelsPerFrame > 0, VERR_NOT_SUPPORTED);
     210    AssertLogRelMsgReturn(pASBD->mChannelsPerFrame < 16, VERR_NOT_SUPPORTED);
     211    AssertLogRelMsgReturn(   pASBD->mBitsPerChannel == 8
     212                          || pASBD->mBitsPerChannel == 16
     213                          || pASBD->mBitsPerChannel == 32,
     214                          ("%u\n", pASBD->mBitsPerChannel), VERR_NOT_SUPPORTED);
     215    AssertLogRelMsgReturn(!(pASBD->mFormatFlags & (kAudioFormatFlagIsFloat /** @todo more we don't like?*/)),
     216                          ("%#x\n", pASBD->mFormatFlags), VERR_NOT_SUPPORTED);
     217
     218    PDMAudioPropsInitEx(&pCfg->Props,
     219                        pASBD->mBitsPerChannel / 8,
     220                        RT_BOOL(pASBD->mFormatFlags & kAudioFormatFlagIsSignedInteger),
     221                        pASBD->mChannelsPerFrame,
     222                        (uint32_t)pASBD->mSampleRate,
     223                        RT_BOOL(pASBD->mFormatFlags & kAudioFormatFlagIsBigEndian),
     224                        false /*fRaw*/);
    215225    return VINF_SUCCESS;
    216226}
  • trunk/src/VBox/Devices/Audio/DrvHostAudioDSound.cpp

    r88235 r88269  
    269269
    270270    pFmt->wFormatTag      = WAVE_FORMAT_PCM;
    271     pFmt->nChannels       = pCfg->Props.cChannels;
    272     pFmt->wBitsPerSample  = pCfg->Props.cbSample * 8;
    273     pFmt->nSamplesPerSec  = pCfg->Props.uHz;
    274     pFmt->nBlockAlign     = pFmt->nChannels * pFmt->wBitsPerSample / 8;
    275     pFmt->nAvgBytesPerSec = pFmt->nSamplesPerSec * pFmt->nBlockAlign;
     271    pFmt->nChannels       = PDMAudioPropsChannels(&pCfg->Props);
     272    pFmt->wBitsPerSample  = PDMAudioPropsSampleBits(&pCfg->Props);
     273    pFmt->nSamplesPerSec  = PDMAudioPropsHz(&pCfg->Props);
     274    pFmt->nBlockAlign     = PDMAudioPropsFrameSize(&pCfg->Props);
     275    pFmt->nAvgBytesPerSec = PDMAudioPropsFramesToBytes(&pCfg->Props, PDMAudioPropsHz(&pCfg->Props));
    276276    pFmt->cbSize          = 0; /* No extra data specified. */
    277277
     
    614614    AssertPtrReturn(pCfgAcq,   E_POINTER);
    615615
     616/** @todo r=bird: I cannot see any code populating pCfgAcq... */
     617
    616618    LogFlowFuncEnter();
    617619
    618620    Assert(pStreamDS->Out.pDSB == NULL);
    619621
    620     DSLOG(("DSound: Opening playback stream (uHz=%RU32, cChannels=%RU8, cBits=%u, fSigned=%RTbool)\n",
    621            pCfgReq->Props.uHz, pCfgReq->Props.cChannels, pCfgReq->Props.cbSample * 8, pCfgReq->Props.fSigned));
     622    DSLOG(("DSound: Opening playback stream (uHz=%RU32, cChannels=%RU8, cBits=%u, fSigned=%RTbool)\n", pCfgReq->Props.uHz,
     623           PDMAudioPropsChannels(&pCfgReq->Props), PDMAudioPropsSampleBits(&pCfgReq->Props), pCfgReq->Props.fSigned));
    622624
    623625    WAVEFORMATEX wfx;
     
    13691371    AssertPtrReturn(pCfgAcq,   E_POINTER);
    13701372
     1373    /** @todo r=bird: I cannot see any code populating pCfgAcq... */
     1374
    13711375    LogFlowFuncEnter();
    13721376
    13731377    Assert(pStreamDS->In.pDSCB == NULL);
    13741378
    1375     DSLOG(("DSound: Opening capturing stream (uHz=%RU32, cChannels=%RU8, cBits=%u, fSigned=%RTbool)\n",
    1376            pCfgReq->Props.uHz, pCfgReq->Props.cChannels, pCfgReq->Props.cbSample * 8, pCfgReq->Props.fSigned));
     1379    DSLOG(("DSound: Opening capturing stream (uHz=%RU32, cChannels=%RU8, cBits=%u, fSigned=%RTbool)\n", pCfgReq->Props.uHz,
     1380           PDMAudioPropsChannels(&pCfgReq->Props), PDMAudioPropsSampleBits(&pCfgReq->Props), pCfgReq->Props.fSigned));
    13771381
    13781382    WAVEFORMATEX wfx;
     
    20672071             pStreamDS, pCfgReq, PDMAudioRecSrcGetName(pCfgReq->u.enmSrc)));
    20682072
    2069     int rc = VINF_SUCCESS;
    20702073
    20712074    /* Try to open capture in case the device is already there. */
     2075    int rc;
    20722076    HRESULT hr = directSoundCaptureOpen(pThis, pStreamDS, pCfgReq, pCfgAcq);
    20732077    if (SUCCEEDED(hr))
     
    23632367    if (RT_SUCCESS(rc))
    23642368    {
     2369        /** @todo already copied   */
    23652370        rc = PDMAudioStrmCfgCopy(&pStreamDS->Cfg, pCfgAcq);
    23662371        if (RT_SUCCESS(rc))
  • trunk/src/VBox/Devices/Audio/DrvHostAudioDebug.cpp

    r88235 r88269  
    1616 */
    1717
    18 #include <iprt/alloc.h>
     18#include <iprt/mem.h>
    1919#include <iprt/rand.h>
    2020#include <iprt/uuid.h> /* For PDMIBASE_2_PDMDRV. */
     
    211211 */
    212212static DECLCALLBACK(int) drvHostDebugAudioHA_StreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
    213                                                         const void *pvBuf, uint32_t uBufSize, uint32_t *puWritten)
    214 {
    215     RT_NOREF(pInterface);
    216     PDEBUGAUDIOSTREAM  pStreamDbg = (PDEBUGAUDIOSTREAM)pStream;
    217 
    218     int rc = AudioHlpFileWrite(pStreamDbg->pFile, pvBuf, uBufSize, 0 /* fFlags */);
     213                                                        const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
     214{
     215    PDEBUGAUDIOSTREAM pStreamDbg = (PDEBUGAUDIOSTREAM)pStream;
     216    RT_NOREF(pInterface);
     217
     218    int rc = AudioHlpFileWrite(pStreamDbg->pFile, pvBuf, cbBuf, 0 /* fFlags */);
    219219    if (RT_FAILURE(rc))
    220220    {
     
    223223    }
    224224
    225     if (puWritten)
    226         *puWritten = uBufSize;
    227 
     225    *pcbWritten = cbBuf;
    228226    return VINF_SUCCESS;
    229227}
     
    243241    AssertPtr(pCfg);
    244242
    245     Assert(uBufSize % pCfg->Props.cbSample == 0);
     243    Assert(uBufSize % PDMAudioPropsSampleSize(&pCfg->Props) == 0);
     244    size_t const cSamples = uBufSize / PDMAudioPropsSampleSize(&pCfg->Props);
    246245
    247246    uint16_t *paBuf = (uint16_t *)pvBuf;
    248247
    249248    /* Generate a simple mono sine wave. */
    250     for (size_t i = 0; i < uBufSize / pCfg->Props.cbSample; i++)
     249    for (size_t i = 0; i < cSamples; i++)
    251250    {
    252251        paBuf[i] = 32760 * sin((2.f * float(3.1415) * pStreamDbg->In.uFreqHz) / pCfg->Props.uHz * pStreamDbg->In.uSample);
  • trunk/src/VBox/Devices/Audio/DrvHostAudioOss.cpp

    r88235 r88269  
    151151
    152152
    153 static int ossOSSToAudioProps(int fmt, PPDMAUDIOPCMPROPS pProps)
    154 {
    155     RT_BZERO(pProps, sizeof(PDMAUDIOPCMPROPS));
    156 
    157     /** @todo r=bird: What's the assumption about the incoming pProps?  Code is
    158      *        clearly ASSUMING something about how it's initialized, but even so,
    159      *        the fSwapEndian isn't correct in a portable way. */
     153static int ossOSSToAudioProps(PPDMAUDIOPCMPROPS pProps, int fmt, int cChannels, int uHz)
     154{
    160155    switch (fmt)
    161156    {
    162157        case AFMT_S8:
    163             pProps->cbSample    = 1;
    164             pProps->fSigned     = true;
     158            PDMAudioPropsInit(pProps, 1 /*8-bit*/, true /*signed*/, cChannels, uHz);
    165159            break;
    166160
    167161        case AFMT_U8:
    168             pProps->cbSample    = 1;
    169             pProps->fSigned     = false;
     162            PDMAudioPropsInit(pProps, 1 /*8-bit*/, false /*signed*/, cChannels, uHz);
    170163            break;
    171164
    172165        case AFMT_S16_LE:
    173             pProps->cbSample    = 2;
    174             pProps->fSigned     = true;
     166            PDMAudioPropsInitEx(pProps, 2 /*16-bit*/, true /*signed*/, cChannels, uHz, true /*fLittleEndian*/, false /*fRaw*/);
    175167            break;
    176168
    177169        case AFMT_U16_LE:
    178             pProps->cbSample    = 2;
    179             pProps->fSigned     = false;
    180             break;
    181 
    182        case AFMT_S16_BE:
    183             pProps->cbSample    = 2;
    184             pProps->fSigned     = true;
    185 #ifdef RT_LITTLE_ENDIAN
    186             pProps->fSwapEndian = true;
    187 #endif
     170            PDMAudioPropsInitEx(pProps, 2 /*16-bit*/, false /*signed*/, cChannels, uHz, true /*fLittleEndian*/, false /*fRaw*/);
     171            break;
     172
     173        case AFMT_S16_BE:
     174            PDMAudioPropsInitEx(pProps, 2 /*16-bit*/, true /*signed*/, cChannels, uHz, false /*fLittleEndian*/, false /*fRaw*/);
    188175            break;
    189176
    190177        case AFMT_U16_BE:
    191             pProps->cbSample    = 2;
    192             pProps->fSigned     = false;
    193 #ifdef RT_LITTLE_ENDIAN
    194             pProps->fSwapEndian = true;
    195 #endif
     178            PDMAudioPropsInitEx(pProps, 2 /*16-bit*/, false /*signed*/, cChannels, uHz, false /*fLittleEndian*/, false /*fRaw*/);
    196179            break;
    197180
     
    240223
    241224        int iFormat;
    242         switch (pOSSReq->Props.cbSample)
     225        switch (PDMAudioPropsSampleSize(&pOSSReq->Props))
    243226        {
    244227            case 1:
     
    266249        }
    267250
    268         int cChannels = pOSSReq->Props.cChannels;
     251        int cChannels = PDMAudioPropsChannels(&pOSSReq->Props);
    269252        if (ioctl(fdFile, SNDCTL_DSP_CHANNELS, &cChannels))
    270253        {
    271254            LogRel(("OSS: Failed to set number of audio channels (%RU8): %s (%d)\n",
    272                     pOSSReq->Props.cChannels, strerror(errno), errno));
     255                    PDMAudioPropsChannels(&pOSSReq->Props), strerror(errno), errno));
    273256            break;
    274257        }
     
    311294        }
    312295
    313         rc = ossOSSToAudioProps(iFormat, &pOSSAcq->Props);
     296        rc = ossOSSToAudioProps(&pOSSAcq->Props, iFormat, cChannels, freq);
    314297        if (RT_SUCCESS(rc))
    315298        {
    316             pOSSAcq->Props.cChannels = cChannels;
    317             pOSSAcq->Props.uHz       = freq;
    318             pOSSAcq->Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pOSSAcq->Props.cbSample, pOSSAcq->Props.cChannels);
    319 
    320299            pOSSAcq->cFragments      = abinfo.fragstotal;
    321300            pOSSAcq->cbFragmentSize  = abinfo.fragsize;
  • trunk/src/VBox/Devices/Audio/DrvHostAudioPulseAudio.cpp

    r88235 r88269  
    217217static pa_sample_format_t paAudioPropsToPulse(PPDMAUDIOPCMPROPS pProps)
    218218{
    219     switch (pProps->cbSample)
     219    switch (PDMAudioPropsSampleSize(pProps))
    220220    {
    221221        case 1:
     
    226226        case 2:
    227227            if (pProps->fSigned)
    228                 return PA_SAMPLE_S16LE;
     228                return PDMAudioPropsIsLittleEndian(pProps) ? PA_SAMPLE_S16LE : PA_SAMPLE_S16BE;
    229229            break;
    230230
     
    232232        case 4:
    233233            if (pProps->fSigned)
    234                 return PA_SAMPLE_S32LE;
     234                return PDMAudioPropsIsLittleEndian(pProps) ? PA_SAMPLE_S32LE : PA_SAMPLE_S32BE;
    235235            break;
    236236#endif
    237 
    238         default:
    239             break;
    240     }
    241 
    242     AssertMsgFailed(("%RU8%s not supported\n", pProps->cbSample, pProps->fSigned ? "S" : "U"));
     237    }
     238
     239    AssertMsgFailed(("%RU8%s not supported\n", PDMAudioPropsSampleSize(pProps), pProps->fSigned ? "S" : "U"));
    243240    return PA_SAMPLE_INVALID;
    244241}
    245242
    246243
    247 static int paPulseToAudioProps(pa_sample_format_t pulsefmt, PPDMAUDIOPCMPROPS pProps)
    248 {
    249     /** @todo r=bird: You are assuming undocumented stuff about
    250      *        pProps->fSwapEndian. */
     244static int paPulseToAudioProps(PPDMAUDIOPCMPROPS pProps, pa_sample_format_t pulsefmt, uint8_t cChannels, uint32_t uHz)
     245{
     246    AssertReturn(cChannels > 0, VERR_INVALID_PARAMETER);
     247    AssertReturn(cChannels < 16, VERR_INVALID_PARAMETER);
     248
    251249    switch (pulsefmt)
    252250    {
    253251        case PA_SAMPLE_U8:
    254             pProps->cbSample    = 1;
    255             pProps->fSigned     = false;
     252            PDMAudioPropsInit(pProps, 1 /*8-bit*/, false /*signed*/, cChannels, uHz);
    256253            break;
    257254
    258255        case PA_SAMPLE_S16LE:
    259             pProps->cbSample    = 2;
    260             pProps->fSigned     = true;
     256            PDMAudioPropsInitEx(pProps, 2 /*16-bit*/, true /*signed*/, cChannels, uHz, true /*fLittleEndian*/, false /*fRaw*/);
    261257            break;
    262258
    263259        case PA_SAMPLE_S16BE:
    264             pProps->cbSample    = 2;
    265             pProps->fSigned     = true;
    266             /** @todo Handle Endianess. */
     260            PDMAudioPropsInitEx(pProps, 2 /*16-bit*/, true /*signed*/, cChannels, uHz, false /*fLittleEndian*/, false /*fRaw*/);
    267261            break;
    268262
    269263#ifdef PA_SAMPLE_S32LE
    270264        case PA_SAMPLE_S32LE:
    271             pProps->cbSample    = 4;
    272             pProps->fSigned     = true;
     265            PDMAudioPropsInitEx(pProps, 4 /*32-bit*/, true /*signed*/, cChannels, uHz, true /*fLittleEndian*/, false /*fRaw*/);
    273266            break;
    274267#endif
     
    276269#ifdef PA_SAMPLE_S32BE
    277270        case PA_SAMPLE_S32BE:
    278             pProps->cbSample    = 4;
    279             pProps->fSigned     = true;
    280             /** @todo Handle Endianess. */
     271            PDMAudioPropsInitEx(pProps, 4 /*32-bit*/, true /*signed*/, cChannels, uHz, false /*fLittleEndian*/, false /*fRaw*/);
    281272            break;
    282273#endif
    283274
    284275        default:
    285             AssertLogRelMsgFailed(("PulseAudio: Format (%ld) not supported\n", pulsefmt));
     276            AssertLogRelMsgFailed(("PulseAudio: Format (%d) not supported\n", pulsefmt));
    286277            return VERR_NOT_SUPPORTED;
    287278    }
     
    789780
    790781    pStreamPA->SampleSpec.format   = paAudioPropsToPulse(&pCfgReq->Props);
    791     pStreamPA->SampleSpec.rate     = pCfgReq->Props.uHz;
    792     pStreamPA->SampleSpec.channels = pCfgReq->Props.cChannels;
     782    pStreamPA->SampleSpec.rate     = PDMAudioPropsHz(&pCfgReq->Props);
     783    pStreamPA->SampleSpec.channels = PDMAudioPropsChannels(&pCfgReq->Props);
    793784
    794785    pStreamPA->curLatencyUs        = PDMAudioPropsFramesToMilli(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize) * RT_US_1MS;
     
    816807        return rc;
    817808
    818     rc = paPulseToAudioProps(pStreamPA->SampleSpec.format, &pCfgAcq->Props);
     809    rc = paPulseToAudioProps(&pCfgAcq->Props, pStreamPA->SampleSpec.format,
     810                             pStreamPA->SampleSpec.channels, pStreamPA->SampleSpec.rate);
    819811    if (RT_FAILURE(rc))
    820812    {
     
    822814        return rc;
    823815    }
    824 
    825     pCfgAcq->Props.uHz       = pStreamPA->SampleSpec.rate;
    826     pCfgAcq->Props.cChannels = pStreamPA->SampleSpec.channels;
    827     pCfgAcq->Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfgAcq->Props.cbSample, pCfgAcq->Props.cChannels);
    828816
    829817    LogFunc(("Acquired: BufAttr tlength=%RU32, maxLength=%RU32, minReq=%RU32\n",
     
    844832{
    845833    pStreamPA->SampleSpec.format   = paAudioPropsToPulse(&pCfgReq->Props);
    846     pStreamPA->SampleSpec.rate     = pCfgReq->Props.uHz;
    847     pStreamPA->SampleSpec.channels = pCfgReq->Props.cChannels;
     834    pStreamPA->SampleSpec.rate     = PDMAudioPropsHz(&pCfgReq->Props);
     835    pStreamPA->SampleSpec.channels = PDMAudioPropsChannels(&pCfgReq->Props);
    848836
    849837    pStreamPA->BufAttr.fragsize    = PDMAudioPropsFramesToBytes(&pCfgReq->Props, pCfgReq->Backend.cFramesPeriod);
     
    860848        return rc;
    861849
    862     rc = paPulseToAudioProps(pStreamPA->SampleSpec.format, &pCfgAcq->Props);
     850    rc = paPulseToAudioProps(&pCfgAcq->Props, pStreamPA->SampleSpec.format,
     851                             pStreamPA->SampleSpec.channels, pStreamPA->SampleSpec.rate);
    863852    if (RT_FAILURE(rc))
    864853    {
     
    869858    pStreamPA->pDrv       = pThis;
    870859    pStreamPA->pu8PeekBuf = NULL;
    871 
    872     pCfgAcq->Props.uHz         = pStreamPA->SampleSpec.rate;
    873     pCfgAcq->Props.cChannels   = pStreamPA->SampleSpec.channels;
    874860
    875861    pCfgAcq->Backend.cFramesPeriod       = PDMAUDIOSTREAMCFG_B2F(pCfgAcq, pStreamPA->BufAttr.fragsize);
  • trunk/src/VBox/Devices/Audio/testcase/tstAudioMixBuffer.cpp

    r88234 r88269  
    3838    RTTestSub(hTest, "Basics");
    3939
    40     const PDMAUDIOPCMPROPS Cfg441StereoS16 = PDMAUDIOPCMPROPS_INITIALIZOR(
     40    const PDMAUDIOPCMPROPS Cfg441StereoS16 = PDMAUDIOPCMPROPS_INITIALIZER(
    4141        /* a_cb: */             2,
    4242        /* a_fSigned: */        true,
    4343        /* a_cChannels: */      2,
    4444        /* a_uHz: */            44100,
    45         /* a_cShift: */         PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(2 /* cb */, 2 /* cChannels */),
    4645        /* a_fSwapEndian: */    false
    4746    );
    48     const PDMAUDIOPCMPROPS Cfg441StereoU16 = PDMAUDIOPCMPROPS_INITIALIZOR(
     47    const PDMAUDIOPCMPROPS Cfg441StereoU16 = PDMAUDIOPCMPROPS_INITIALIZER(
    4948        /* a_cb: */             2,
    5049        /* a_fSigned: */        false,
    5150        /* a_cChannels: */      2,
    5251        /* a_uHz: */            44100,
    53         /* a_cShift: */         PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(2 /* cb */, 2 /* cChannels */),
    5452        /* a_fSwapEndian: */    false
    5553    );
    56     const PDMAUDIOPCMPROPS Cfg441StereoU32 = PDMAUDIOPCMPROPS_INITIALIZOR(
     54    const PDMAUDIOPCMPROPS Cfg441StereoU32 = PDMAUDIOPCMPROPS_INITIALIZER(
    5755        /* a_cb: */             4,
    5856        /* a_fSigned: */        false,
    5957        /* a_cChannels: */      2,
    6058        /* a_uHz: */            44100,
    61         /* a_cShift: */         PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(4 /* cb */, 2 /* cChannels */),
    6259        /* a_fSwapEndian: */    false
    6360    );
     
    191188
    192189    /* 44100Hz, 2 Channels, S16 */
    193     PDMAUDIOPCMPROPS config = PDMAUDIOPCMPROPS_INITIALIZOR(
     190    PDMAUDIOPCMPROPS config = PDMAUDIOPCMPROPS_INITIALIZER(
    194191        2,                                                                  /* Bytes */
    195192        true,                                                               /* Signed */
    196193        2,                                                                  /* Channels */
    197194        44100,                                                              /* Hz */
    198         PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(2 /* Bytes */, 2 /* Channels */), /* Shift */
    199195        false                                                               /* Swap Endian */
    200196    );
     
    312308
    313309    /* 44100Hz, 2 Channels, S16 */
    314     PDMAUDIOPCMPROPS cfg_p = PDMAUDIOPCMPROPS_INITIALIZOR(
     310    PDMAUDIOPCMPROPS cfg_p = PDMAUDIOPCMPROPS_INITIALIZER(
    315311        2,                                                                  /* Bytes */
    316312        true,                                                               /* Signed */
    317313        2,                                                                  /* Channels */
    318314        44100,                                                              /* Hz */
    319         PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(2 /* Bytes */, 2 /* Channels */), /* Shift */
    320315        false                                                               /* Swap Endian */
    321316    );
     
    327322
    328323    /* 22050Hz, 2 Channels, S16 */
    329     PDMAUDIOPCMPROPS cfg_c1 = PDMAUDIOPCMPROPS_INITIALIZOR(/* Upmixing to parent */
     324    PDMAUDIOPCMPROPS cfg_c1 = PDMAUDIOPCMPROPS_INITIALIZER(/* Upmixing to parent */
    330325        2,                                                                  /* Bytes */
    331326        true,                                                               /* Signed */
    332327        2,                                                                  /* Channels */
    333328        22050,                                                              /* Hz */
    334         PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(2 /* Bytes */, 2 /* Channels */), /* Shift */
    335329        false                                                               /* Swap Endian */
    336330    );
     
    346340
    347341    /* 48000Hz, 2 Channels, S16 */
    348     PDMAUDIOPCMPROPS cfg_c2 = PDMAUDIOPCMPROPS_INITIALIZOR(/* Downmixing to parent */
     342    PDMAUDIOPCMPROPS cfg_c2 = PDMAUDIOPCMPROPS_INITIALIZER(/* Downmixing to parent */
    349343        2,                                                                  /* Bytes */
    350344        true,                                                               /* Signed */
    351345        2,                                                                  /* Channels */
    352346        48000,                                                              /* Hz */
    353         PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(2 /* Bytes */, 2 /* Channels */), /* Shift */
    354347        false                                                               /* Swap Endian */
    355348    );
     
    460453
    461454    /* 44100Hz, 1 Channel, U8 */
    462     PDMAUDIOPCMPROPS cfg_p = PDMAUDIOPCMPROPS_INITIALIZOR(
     455    PDMAUDIOPCMPROPS cfg_p = PDMAUDIOPCMPROPS_INITIALIZER(
    463456        1,                                                                  /* Bytes */
    464457        false,                                                              /* Signed */
    465458        1,                                                                  /* Channels */
    466459        44100,                                                              /* Hz */
    467         PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(1 /* Bytes */, 1 /* Channels */), /* Shift */
    468460        false                                                               /* Swap Endian */
    469461    );
     
    483475
    484476    /* 22050Hz, 1 Channel, U8 */
    485     PDMAUDIOPCMPROPS cfg_c = PDMAUDIOPCMPROPS_INITIALIZOR( /* Upmixing to parent */
     477    PDMAUDIOPCMPROPS cfg_c = PDMAUDIOPCMPROPS_INITIALIZER( /* Upmixing to parent */
    486478        1,                                                                  /* Bytes */
    487479        false,                                                              /* Signed */
    488480        1,                                                                  /* Channels */
    489481        22050,                                                              /* Hz */
    490         PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(1 /* Bytes */, 1 /* Channels */), /* Shift */
    491482        false                                                               /* Swap Endian */
    492483    );
     
    514505
    515506    /**** 8-bit unsigned samples ****/
    516     RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Conversion test %uHz %uch 8-bit\n", cfg_c.uHz, cfg_c.cChannels);
     507    RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Conversion test %uHz %uch 8-bit\n", cfg_c.uHz, PDMAudioPropsChannels(&cfg_c));
    517508    RTTESTI_CHECK_RC_OK(AudioMixBufWriteCirc(&child, &aFrames8U, sizeof(aFrames8U), &cFramesWritten));
    518509    RTTESTI_CHECK_MSG(cFramesWritten == cFramesChild, ("Child: Expected %RU32 written frames, got %RU32\n", cFramesChild, cFramesWritten));
     
    565556
    566557    /* 44100Hz, 1 Channel, S16 */
    567     PDMAUDIOPCMPROPS cfg_p = PDMAUDIOPCMPROPS_INITIALIZOR(
     558    PDMAUDIOPCMPROPS cfg_p = PDMAUDIOPCMPROPS_INITIALIZER(
    568559        2,                                                                  /* Bytes */
    569560        true,                                                               /* Signed */
    570561        1,                                                                  /* Channels */
    571562        44100,                                                              /* Hz */
    572         PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(2 /* Bytes */, 1 /* Channels */), /* Shift */
    573563        false                                                               /* Swap Endian */
    574564    );
     
    580570
    581571    /* 22050Hz, 1 Channel, S16 */
    582     PDMAUDIOPCMPROPS cfg_c = PDMAUDIOPCMPROPS_INITIALIZOR( /* Upmixing to parent */
     572    PDMAUDIOPCMPROPS cfg_c = PDMAUDIOPCMPROPS_INITIALIZER( /* Upmixing to parent */
    583573        2,                                                                  /* Bytes */
    584574        true,                                                               /* Signed */
    585575        1,                                                                  /* Channels */
    586576        22050,                                                              /* Hz */
    587         PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(2 /* Bytes */, 1 /* Channels */), /* Shift */
    588577        false                                                               /* Swap Endian */
    589578    );
     
    611600
    612601    /**** 16-bit signed samples ****/
    613     RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Conversion test %uHz %uch 16-bit\n", cfg_c.uHz, cfg_c.cChannels);
     602    RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Conversion test %uHz %uch 16-bit\n", cfg_c.uHz, PDMAudioPropsChannels(&cfg_c));
    614603    RTTESTI_CHECK_RC_OK(AudioMixBufWriteCirc(&child, &aFrames16S, sizeof(aFrames16S), &cFramesWritten));
    615604    RTTESTI_CHECK_MSG(cFramesWritten == cFramesChild, ("Child: Expected %RU32 written frames, got %RU32\n", cFramesChild, cFramesWritten));
     
    662651    /* Same for parent/child. */
    663652    /* 44100Hz, 2 Channels, S16 */
    664     PDMAUDIOPCMPROPS cfg = PDMAUDIOPCMPROPS_INITIALIZOR(
     653    PDMAUDIOPCMPROPS cfg = PDMAUDIOPCMPROPS_INITIALIZER(
    665654        2,                                                                  /* Bytes */
    666655        true,                                                               /* Signed */
    667656        2,                                                                  /* Channels */
    668657        44100,                                                              /* Hz */
    669         PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(2 /* Bytes */, 2 /* Channels */), /* Shift */
    670658        false                                                               /* Swap Endian */
    671659    );
     
    699687
    700688    /**** Volume control test ****/
    701     RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Volume control test %uHz %uch \n", cfg.uHz, cfg.cChannels);
     689    RTTestPrintf(hTest, RTTESTLVL_DEBUG, "Volume control test %uHz %uch \n", cfg.uHz, PDMAudioPropsChannels(&cfg));
    702690
    703691    /* 1) Full volume/0dB attenuation (255). */
Note: See TracChangeset for help on using the changeset viewer.

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