VirtualBox

Changeset 75962 in vbox for trunk/src


Ignore:
Timestamp:
Dec 5, 2018 9:34:58 AM (6 years ago)
Author:
vboxsync
Message:

Forward ported r127158 (Audio/HDA: Implemented support for Windows 10 Build 1809 default surround speaker setup) + build fixes (r127159, r127160, r127162, r127165, r127167).

Location:
trunk/src/VBox/Devices
Files:
10 edited

Legend:

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

    r75866 r75962  
    5757#include "HDACodec.h"
    5858#include "HDAStream.h"
    59 # if defined(VBOX_WITH_HDA_AUDIO_INTERLEAVING_STREAMS_SUPPORT) || defined(VBOX_WITH_AUDIO_HDA_51_SURROUND)
    60 #  include "HDAStreamChannel.h"
    61 # endif
    6259#include "HDAStreamMap.h"
    6360#include "HDAStreamPeriod.h"
     
    108105#else
    109106# error "Please specify your HDA device vendor/device IDs"
    110 #endif
    111 
    112 /* Make sure that interleaving streams support is enabled if the 5.1 surround code is being used. */
    113 #if defined (VBOX_WITH_AUDIO_HDA_51_SURROUND) && !defined(VBOX_WITH_HDA_AUDIO_INTERLEAVING_STREAMS_SUPPORT)
    114 # define VBOX_WITH_HDA_AUDIO_INTERLEAVING_STREAMS_SUPPORT
    115107#endif
    116108
     
    13121304             uSD, fRun, fInRun, fReset, fInReset, u32Value));
    13131305
     1306# ifdef DEBUG
     1307    if (hdaGetDirFromSD(uSD) == PDMAUDIODIR_OUT)
     1308    {
     1309        const uint8_t uStripeCtl = ((u32Value >> HDA_SDCTL_STRIPE_SHIFT) & HDA_SDCTL_STRIPE_MASK) + 1;
     1310        LogFunc(("[SD%RU8] Using %RU8 SDOs (stripe control)\n", uSD, uStripeCtl));
     1311    }
     1312# endif
     1313
    13141314    /*
    13151315     * Extract the stream tag the guest wants to use for this specific
     
    18101810        }
    18111811    }
    1812 # else  /* !VBOX_WITH_AUDIO_HDA_51_SURROUND */
    1813     /* Only support mono or stereo channels. */
    1814     if (   pCfg->Props.cChannels != 1 /* Mono */
    1815         && pCfg->Props.cChannels != 2 /* Stereo */)
    1816     {
    1817         rc = VERR_NOT_SUPPORTED;
    1818     }
    18191812# endif /* !VBOX_WITH_AUDIO_HDA_51_SURROUND */
    18201813
     
    18391832            pCfg->enmLayout       = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
    18401833
    1841             pCfg->Props.cChannels = 2;
    18421834            pCfg->Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cBytes, pCfg->Props.cChannels);
    18431835
     
    18551847
    18561848            pCfg->Props.cChannels = (fUseCenter && fUseLFE) ? 2 : 1;
    1857             pCfg->Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cBits, pCfg->Props.cChannels);
     1849            pCfg->Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cBytes, pCfg->Props.cChannels);
    18581850
    18591851            rc = hdaCodecAddStream(pThis->pCodec, PDMAUDIOMIXERCTL_CENTER_LFE, pCfg);
     
    18691861
    18701862            pCfg->Props.cChannels = 2;
    1871             pCfg->Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cBits, pCfg->Props.cChannels);
     1863            pCfg->Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfg->Props.cBytes, pCfg->Props.cChannels);
    18721864
    18731865            rc = hdaCodecAddStream(pThis->pCodec, PDMAUDIOMIXERCTL_REAR, pCfg);
     
    24852477    AssertPtrReturn(pCfg,     VERR_INVALID_POINTER);
    24862478
    2487     LogFunc(("Sink=%s, Stream=%s\n", pMixSink->pszName, pCfg->szName));
     2479    LogFunc(("szSink=%s, szStream=%s, cChannels=%RU8\n", pMixSink->pszName, pCfg->szName, pCfg->Props.cChannels));
    24882480
    24892481    PPDMAUDIOSTREAMCFG pStreamCfg = DrvAudioHlpStreamCfgDup(pCfg);
  • trunk/src/VBox/Devices/Audio/DevHDACommon.cpp

    r75866 r75962  
    340340# endif
    341341        if (pStream->Dbg.Runtime.fEnabled)
    342             DrvAudioHlpFileWrite(pStream->Dbg.Runtime.pFileDMA, (uint8_t *)pvBuf + cbReadTotal, cbChunk, 0 /* fFlags */);
     342            DrvAudioHlpFileWrite(pStream->Dbg.Runtime.pFileDMARaw, (uint8_t *)pvBuf + cbReadTotal, cbChunk, 0 /* fFlags */);
    343343
    344344        STAM_COUNTER_ADD(&pThis->StatBytesRead, cbChunk);
     
    406406
    407407        if (pStream->Dbg.Runtime.fEnabled)
    408             DrvAudioHlpFileWrite(pStream->Dbg.Runtime.pFileDMA, (uint8_t *)pvBuf + cbWrittenTotal, cbChunk, 0 /* fFlags */);
     408            DrvAudioHlpFileWrite(pStream->Dbg.Runtime.pFileDMARaw, (uint8_t *)pvBuf + cbWrittenTotal, cbChunk, 0 /* fFlags */);
    409409
    410410        rc = PDMDevHlpPCIPhysWrite(pThis->CTX_SUFF(pDevIns),
  • trunk/src/VBox/Devices/Audio/DevHDACommon.h

    r75866 r75962  
    9191 *
    9292 * Lowering this value can ask for trouble, as backends then can run
    93  * into data underruns. */
    94 #define HDA_TIMER_HZ_DEFAULT        100
     93 * into data underruns.
     94 *
     95 * Note: For handling surround setups (e.g. 5.1 speaker setups) we need
     96 *       a higher Hz rate, as the device emulation otherwise will come into
     97 *       timing trouble, making the output (DMA reads) crackling. */
     98#define HDA_TIMER_HZ_DEFAULT        200
    9599
    96100/** Default position adjustment (in audio samples).
     
    113117/** HDA's (fixed) audio frame size in bytes.
    114118 *  We only support 16-bit stereo frames at the moment. */
    115 #define HDA_FRAME_SIZE              4
     119#define HDA_FRAME_SIZE_DEFAULT      4
    116120
    117121/** Offset of the SD0 register map. */
  • trunk/src/VBox/Devices/Audio/HDAStream.cpp

    r75866 r75962  
    9494
    9595        if (hdaGetDirFromSD(pStream->u8SD) == PDMAUDIODIR_IN)
    96             RTStrPrintf(szFile, sizeof(szFile), "hdaDMAWriteSD%RU8", pStream->u8SD);
     96            RTStrPrintf(szFile, sizeof(szFile), "hdaDMARawWriteSD%RU8", pStream->u8SD);
    9797        else
    98             RTStrPrintf(szFile, sizeof(szFile), "hdaDMAReadSD%RU8", pStream->u8SD);
     98            RTStrPrintf(szFile, sizeof(szFile), "hdaDMARawReadSD%RU8", pStream->u8SD);
    9999
    100100        rc2 = DrvAudioHlpFileNameGet(szPath, sizeof(szPath), pThis->Dbg.szOutPath, szFile,
     
    102102        AssertRC(rc2);
    103103
    104         rc2 = DrvAudioHlpFileCreate(PDMAUDIOFILETYPE_WAV, szPath, PDMAUDIOFILE_FLAG_NONE, &pStream->Dbg.Runtime.pFileDMA);
     104        rc2 = DrvAudioHlpFileCreate(PDMAUDIOFILETYPE_WAV, szPath, PDMAUDIOFILE_FLAG_NONE, &pStream->Dbg.Runtime.pFileDMARaw);
     105        AssertRC(rc2);
     106
     107        if (hdaGetDirFromSD(pStream->u8SD) == PDMAUDIODIR_IN)
     108            RTStrPrintf(szFile, sizeof(szFile), "hdaDMAWriteMappedSD%RU8", pStream->u8SD);
     109        else
     110            RTStrPrintf(szFile, sizeof(szFile), "hdaDMAReadMappedSD%RU8", pStream->u8SD);
     111
     112        rc2 = DrvAudioHlpFileNameGet(szPath, sizeof(szPath), pThis->Dbg.szOutPath, szFile,
     113                                     0 /* uInst */, PDMAUDIOFILETYPE_WAV, PDMAUDIOFILENAME_FLAG_NONE);
     114        AssertRC(rc2);
     115
     116        rc2 = DrvAudioHlpFileCreate(PDMAUDIOFILETYPE_WAV, szPath, PDMAUDIOFILE_FLAG_NONE, &pStream->Dbg.Runtime.pFileDMAMapped);
    105117        AssertRC(rc2);
    106118
    107119        /* Delete stale debugging files from a former run. */
    108120        DrvAudioHlpFileDelete(pStream->Dbg.Runtime.pFileStream);
    109         DrvAudioHlpFileDelete(pStream->Dbg.Runtime.pFileDMA);
     121        DrvAudioHlpFileDelete(pStream->Dbg.Runtime.pFileDMARaw);
     122        DrvAudioHlpFileDelete(pStream->Dbg.Runtime.pFileDMAMapped);
    110123    }
    111124
     
    160173        pStream->Dbg.Runtime.pFileStream = NULL;
    161174
    162         DrvAudioHlpFileDestroy(pStream->Dbg.Runtime.pFileDMA);
    163         pStream->Dbg.Runtime.pFileDMA = NULL;
     175        DrvAudioHlpFileDestroy(pStream->Dbg.Runtime.pFileDMARaw);
     176        pStream->Dbg.Runtime.pFileDMARaw = NULL;
     177
     178        DrvAudioHlpFileDestroy(pStream->Dbg.Runtime.pFileDMAMapped);
     179        pStream->Dbg.Runtime.pFileDMAMapped = NULL;
    164180    }
    165181
     
    245261        return VINF_SUCCESS;
    246262    }
    247 
    248     /* Set the stream's frame size. */
    249     pStream->State.cbFrameSize = pCfg->Props.cChannels * pCfg->Props.cBytes;
    250     LogFunc(("[SD%RU8] cChannels=%RU8, cBytes=%RU8 -> cbFrameSize=%RU32\n",
    251              pStream->u8SD, pCfg->Props.cChannels, pCfg->Props.cBytes, pStream->State.cbFrameSize));
    252     Assert(pStream->State.cbFrameSize); /* Frame size must not be 0. */
    253263
    254264    /*
     
    263273    AssertRCReturn(rc, rc);
    264274
     275#ifndef VBOX_WITH_AUDIO_HDA_51_SURROUND
     276    /*
     277     * When not running with surround support enabled, override the channel count
     278     * with stereo (2) channels so that we at least can properly work with those.
     279     *
     280     * Note: This also involves dealing with surround setups the guest might has set up for us.
     281     */
     282    pCfg->Props.cChannels = 2;
     283#endif
     284
    265285    LogFunc(("[SD%RU8] DMA @ 0x%x (%RU32 bytes), LVI=%RU16, FIFOS=%RU16, Hz=%RU32, rc=%Rrc\n",
    266286             pStream->u8SD, pStream->u64BDLBase, pStream->u32CBL, pStream->u16LVI, pStream->u16FIFOS,
     
    268288
    269289    /* Make sure that mandatory parameters are set up correctly. */
    270     AssertStmt(pStream->u32CBL %  pStream->State.cbFrameSize == 0, rc = VERR_INVALID_PARAMETER);
    271     AssertStmt(pStream->u16LVI >= 1,                               rc = VERR_INVALID_PARAMETER);
     290    AssertStmt(pStream->u32CBL %  pStream->State.Mapping.cbFrameSize == 0, rc = VERR_INVALID_PARAMETER);
     291    AssertStmt(pStream->u16LVI >= 1,                                       rc = VERR_INVALID_PARAMETER);
    272292
    273293    if (RT_SUCCESS(rc))
     
    275295        /* Make sure that the chosen Hz rate dividable by the stream's rate. */
    276296        if (pStream->State.Cfg.Props.uHz % pThis->uTimerHz != 0)
    277             LogRel(("HDA: Device timer (%RU32) does not fit to stream #RU8 timing (%RU32)\n",
    278                     pThis->uTimerHz, pStream->State.Cfg.Props.uHz));
     297            LogRel(("HDA: Device timer (%RU32) does not fit to stream #%RU8 timing (%RU32)\n",
     298                    pThis->uTimerHz, pStream->u8SD, pStream->State.Cfg.Props.uHz));
    279299
    280300        /* Figure out how many transfer fragments we're going to use for this stream. */
     
    318338#ifdef VBOX_WITH_INTEL_HDA
    319339                /* Intel ICH / PCH: 1 frame. */
    320                 if (BDLE.Desc.u32BufSize == 1 * pStream->State.cbFrameSize)
     340                if (BDLE.Desc.u32BufSize == (uint32_t)(1 * pStream->State.Mapping.cbFrameSize))
    321341                {
    322342                    cfPosAdjust = 1;
    323343                }
    324344                /* Intel Baytrail / Braswell: 32 frames. */
    325                 else if (BDLE.Desc.u32BufSize == 32 * pStream->State.cbFrameSize)
     345                else if (BDLE.Desc.u32BufSize == (uint32_t)(32 * pStream->State.Mapping.cbFrameSize))
    326346                {
    327347                    cfPosAdjust = 32;
     
    344364                 * position adjustment.
    345365                 */
    346                 if (   (cfPosAdjust * pStream->State.cbFrameSize) == BDLE.Desc.u32BufSize
     366                if (   (cfPosAdjust * pStream->State.Mapping.cbFrameSize) == BDLE.Desc.u32BufSize
    347367                    && cFragments)
    348368                {
     
    365385        pStream->State.cbTransferSize = pStream->u32CBL / cFragments;
    366386        Assert(pStream->State.cbTransferSize);
    367         Assert(pStream->State.cbTransferSize % pStream->State.cbFrameSize == 0);
     387        Assert(pStream->State.cbTransferSize % pStream->State.Mapping.cbFrameSize == 0);
    368388
    369389        /* Calculate the bytes we need to transfer to / from the stream's DMA per iteration.
    370390         * This is bound to the device's Hz rate and thus to the (virtual) timing the device expects. */
    371         pStream->State.cbTransferChunk = (pStream->State.Cfg.Props.uHz / pThis->uTimerHz) * pStream->State.cbFrameSize;
     391        pStream->State.cbTransferChunk = (pStream->State.Cfg.Props.uHz / pThis->uTimerHz) * pStream->State.Mapping.cbFrameSize;
    372392        Assert(pStream->State.cbTransferChunk);
    373         Assert(pStream->State.cbTransferChunk % pStream->State.cbFrameSize == 0);
     393        Assert(pStream->State.cbTransferChunk % pStream->State.Mapping.cbFrameSize == 0);
    374394
    375395        /* Make sure that the transfer chunk does not exceed the overall transfer size. */
     
    379399        pStream->State.cbTransferProcessed        = 0;
    380400        pStream->State.cTransferPendingInterrupts = 0;
    381         pStream->State.cbDMALeft                  = 0;
    382401        pStream->State.tsLastUpdateNs             = 0;
    383402
     
    542561            }
    543562
    544             if (!DrvAudioHlpFileIsOpen(pStream->Dbg.Runtime.pFileDMA))
    545             {
    546                 int rc2 = DrvAudioHlpFileOpen(pStream->Dbg.Runtime.pFileDMA, PDMAUDIOFILE_DEFAULT_OPEN_FLAGS,
     563            if (!DrvAudioHlpFileIsOpen(pStream->Dbg.Runtime.pFileDMARaw))
     564            {
     565                int rc2 = DrvAudioHlpFileOpen(pStream->Dbg.Runtime.pFileDMARaw, PDMAUDIOFILE_DEFAULT_OPEN_FLAGS,
     566                                              &pStream->State.Cfg.Props);
     567                AssertRC(rc2);
     568            }
     569
     570            if (!DrvAudioHlpFileIsOpen(pStream->Dbg.Runtime.pFileDMAMapped))
     571            {
     572                int rc2 = DrvAudioHlpFileOpen(pStream->Dbg.Runtime.pFileDMAMapped, PDMAUDIOFILE_DEFAULT_OPEN_FLAGS,
    547573                                              &pStream->State.Cfg.Props);
    548574                AssertRC(rc2);
     
    916942         * make sure that we process them first as a whole. */
    917943        if (pStream->State.cPosAdjustFramesLeft)
    918             cbChunk = RT_MIN(cbChunk, uint32_t(pStream->State.cPosAdjustFramesLeft * pStream->State.cbFrameSize));
     944            cbChunk = RT_MIN(cbChunk, uint32_t(pStream->State.cPosAdjustFramesLeft * pStream->State.Mapping.cbFrameSize));
    919945
    920946        Log3Func(("[SD%RU8] cbChunk=%RU32, cPosAdjustFramesLeft=%RU16\n",
     
    9771003            if (RT_SUCCESS(rc))
    9781004            {
    979                 const uint32_t cbDMAFree = (uint32_t)RTCircBufFree(pCircBuf);
    980                 Assert(cbDMAFree >= cbDMA); /* This must always hold. */
    981 
    982 #ifndef VBOX_WITH_HDA_AUDIO_INTERLEAVING_STREAMS_SUPPORT
     1005                const uint32_t cbFree = (uint32_t)RTCircBufFree(pCircBuf);
     1006
    9831007                /*
    9841008                 * Most guests don't use different stream frame sizes than
     
    9881012                 * Only macOS guests need the frame extraction branch below at the moment AFAIK.
    9891013                 */
    990                 if (pStream->State.cbFrameSize == HDA_FRAME_SIZE)
     1014                if (pStream->State.Mapping.cbFrameSize == HDA_FRAME_SIZE_DEFAULT)
    9911015                {
    9921016                    uint32_t cbDMARead = 0;
    993                     uint32_t cbDMALeft = RT_MIN(cbDMA, cbDMAFree);
     1017                    uint32_t cbDMALeft = RT_MIN(cbDMA, cbFree);
    9941018
    9951019                    while (cbDMALeft)
     
    10211045                     * and just discard the other channel's data.
    10221046                     *
     1047                     * I know, the following code is horribly slow, but seems to work for now.
     1048                     ** @todo Optimize channel data extraction! Use some SSE(3) / intrinsics?
    10231049                     */
    1024                     /** @todo Optimize this stuff -- copying only one frame a time is expensive. */
    1025                     uint32_t cbDMARead = pStream->State.cbDMALeft ? pStream->State.cbFrameSize - pStream->State.cbDMALeft : 0;
    1026                     uint32_t cbDMALeft = RT_MIN(cbDMA, cbDMAFree);
    1027 
    1028                     while (cbDMALeft >= pStream->State.cbFrameSize)
     1050                    for (unsigned m = 0; m < pStream->State.Mapping.cMappings; m++)
    10291051                    {
    1030                         void *pvBuf; size_t cbBuf;
    1031                         RTCircBufAcquireWriteBlock(pCircBuf, HDA_FRAME_SIZE, &pvBuf, &cbBuf);
    1032 
    1033                         AssertBreak(cbDMARead <= sizeof(abChunk));
    1034 
    1035                         if (cbBuf)
    1036                             memcpy(pvBuf, abChunk + cbDMARead, cbBuf);
    1037 
    1038                         RTCircBufReleaseWriteBlock(pCircBuf, cbBuf);
    1039 
    1040                         Assert(cbDMALeft >= pStream->State.cbFrameSize);
    1041                         cbDMALeft -= pStream->State.cbFrameSize;
    1042                         cbDMARead += pStream->State.cbFrameSize;
     1052                        const uint32_t cbFrame  = pStream->State.Mapping.cbFrameSize;
     1053
     1054                        Assert(cbFree >= cbDMA);
     1055
     1056                        PPDMAUDIOSTREAMMAP pMap = &pStream->State.Mapping.paMappings[m];
     1057                        AssertPtr(pMap);
     1058
     1059                        Log3Func(("Mapping #%u: Start (cbDMA=%RU32, cbFrame=%RU32, cbOff=%RU32)\n",
     1060                                  m, cbDMA, cbFrame, pMap->cbOff));
     1061
     1062                        uint8_t *pbSrcBuf = abChunk;
     1063                        size_t cbSrcOff   = pMap->cbOff;
     1064                        Assert(cbChunk >= cbSrcOff);
     1065
     1066                        for (unsigned i = 0; i < cbDMA / cbFrame; i++)
     1067                        {
     1068                            void *pvDstBuf; size_t cbDstBuf;
     1069                            RTCircBufAcquireWriteBlock(pCircBuf, pMap->cbSize, &pvDstBuf, &cbDstBuf);
     1070
     1071                            Assert(cbDstBuf >= pMap->cbSize);
     1072
     1073                            if (cbDstBuf)
     1074                            {
     1075                                Log3Func(("Mapping #%u: Frame #%02u:    cbSize=%zu, cbFirst=%zu, cbOff=%zu, cbDstBuf=%zu, cbSrcOff=%zu\n",
     1076                                          m, i, pMap->cbSize, pMap->cbFirst, pMap->cbOff, cbDstBuf, cbSrcOff));
     1077
     1078                                memcpy(pvDstBuf, pbSrcBuf + cbSrcOff, cbDstBuf);
     1079
     1080#if 0 /* Too slow, even for release builds, so disabled it. */
     1081                                if (pStream->Dbg.Runtime.fEnabled)
     1082                                    DrvAudioHlpFileWrite(pStream->Dbg.Runtime.pFileDMAMapped, pvDstBuf, cbDstBuf,
     1083                                                         0 /* fFlags */);
     1084#endif
     1085                                Assert(cbSrcOff <= cbDMA);
     1086                                if (cbSrcOff + cbFrame + pMap->cbFirst <= cbDMA)
     1087                                    cbSrcOff += cbFrame + pMap->cbFirst;
     1088
     1089                                Log3Func(("Mapping #%u: Frame #%02u:    -> cbSrcOff=%zu\n", m, i, cbSrcOff));
     1090                            }
     1091
     1092                            RTCircBufReleaseWriteBlock(pCircBuf, cbDstBuf);
     1093                        }
     1094
     1095                        Log3Func(("Mapping #%u: End cbSize=%zu, cbDMA=%RU32, cbSrcOff=%zu\n",
     1096                                  m, pMap->cbSize, cbDMA, cbSrcOff));
     1097
     1098                        Assert(cbSrcOff <= cbDMA);
     1099
     1100                        const uint32_t cbSrcLeft = cbDMA - (uint32_t)cbSrcOff;
     1101                        if (cbSrcLeft)
     1102                        {
     1103                            Log3Func(("Mapping #%u: cbSrcLeft=%RU32\n", m, cbSrcLeft));
     1104
     1105                            if (cbSrcLeft >= pMap->cbSize)
     1106                            {
     1107                                void *pvDstBuf; size_t cbDstBuf;
     1108                                RTCircBufAcquireWriteBlock(pCircBuf, pMap->cbSize, &pvDstBuf, &cbDstBuf);
     1109
     1110                                Assert(cbDstBuf >= pMap->cbSize);
     1111
     1112                                if (cbDstBuf)
     1113                                {
     1114                                    memcpy(pvDstBuf, pbSrcBuf + cbSrcOff, cbDstBuf);
     1115                                }
     1116
     1117                                RTCircBufReleaseWriteBlock(pCircBuf, cbDstBuf);
     1118                            }
     1119
     1120                            Assert(pMap->cbFrame >= cbSrcLeft);
     1121                            pMap->cbOff = pMap->cbFrame - cbSrcLeft;
     1122                        }
     1123                        else
     1124                            pMap->cbOff = 0;
     1125
     1126                        Log3Func(("Mapping #%u finish (cbSrcOff=%zu, cbOff=%zu)\n", m, cbSrcOff, pMap->cbOff));
    10431127                    }
    1044 
    1045                     pStream->State.cbDMALeft = cbDMALeft;
    1046                     Assert(pStream->State.cbDMALeft < pStream->State.cbFrameSize);
    10471128                }
    1048 #else
    1049                 /** @todo This needs making use of HDAStreamMap + HDAStreamChannel. */
    1050 # error "Implement reading interleaving streams support here."
    1051 #endif
    10521129            }
    10531130            else
     
    11271204
    11281205        /* Do the position adjustment accounting. */
    1129         pStream->State.cPosAdjustFramesLeft -= RT_MIN(pStream->State.cPosAdjustFramesLeft, cbDMA / pStream->State.cbFrameSize);
     1206        pStream->State.cPosAdjustFramesLeft -=
     1207            RT_MIN(pStream->State.cPosAdjustFramesLeft, cbDMA / pStream->State.Mapping.cbFrameSize);
    11301208
    11311209        if (RT_FAILURE(rc))
     
    11441222    if (pStream->State.cPosAdjustFramesLeft == 0)
    11451223    {
    1146         hdaR3StreamPeriodInc(pPeriod, RT_MIN(cbProcessed / pStream->State.cbFrameSize,
     1224        hdaR3StreamPeriodInc(pPeriod, RT_MIN(cbProcessed / pStream->State.Mapping.cbFrameSize,
    11471225                                             hdaR3StreamPeriodGetRemainingFrames(pPeriod)));
    11481226
     
    11761254                                               + hdaR3StreamPeriodFramesToWalClk(pPeriod,
    11771255                                                                                   pStream->State.cbTransferProcessed
    1178                                                                                  / pStream->State.cbFrameSize),
     1256                                                                                 / pStream->State.Mapping.cbFrameSize),
    11791257                                               false /* fForce */);
    11801258        RT_NOREF(fWalClkSet);
  • trunk/src/VBox/Devices/Audio/HDAStream.h

    r73833 r75962  
    6161     *  whereas for output streams this dumps data being read from the device FIFO. */
    6262    R3PTRTYPE(PPDMAUDIOFILE) pFileStream;
    63     /** File for dumping DMA reads / writes.
     63    /** File for dumping raw DMA reads / writes.
    6464     *  For input streams, this dumps data being written to the device DMA,
    6565     *  whereas for output streams this dumps data being read from the device DMA. */
    66     R3PTRTYPE(PPDMAUDIOFILE) pFileDMA;
     66    R3PTRTYPE(PPDMAUDIOFILE) pFileDMARaw;
     67    /** File for dumping mapped (that is, extracted) DMA reads / writes. */
     68    R3PTRTYPE(PPDMAUDIOFILE) pFileDMAMapped;
    6769} HDASTREAMDBGINFORT, *PHDASTREAMDBGINFORT;
    6870
     
    124126#endif
    125127    /** This stream's data mapping. */
    126     HDASTREAMMAPPING        Mapping;
     128    HDASTREAMMAP            Mapping;
    127129    /** Current BDLE (Buffer Descriptor List Entry). */
    128130    HDABDLE                 BDLE;
     
    148150     *  BDLE interrupt-on-completion (IOC) bits set. */
    149151    uint8_t                 cTransferPendingInterrupts;
    150     /** The stream's current audio frame size (in bytes). */
    151     uint32_t                cbFrameSize;
     152    uint8_t                 Padding2[4];
    152153    /** How many audio data frames are left to be processed
    153154     *  for the position adjustment handling.
     
    155156     *  0 if position adjustment handling is done or inactive. */
    156157    uint16_t                cPosAdjustFramesLeft;
    157     uint8_t                 Padding2[2];
     158    uint8_t                 Padding3[2];
    158159    /** (Virtual) clock ticks per byte. */
    159160    uint64_t                cTicksPerByte;
     
    165166     *  Should match SDFMT. */
    166167    PDMAUDIOSTREAMCFG       Cfg;
    167     uint32_t                Padding3;
     168    uint32_t                Padding4;
    168169#ifdef HDA_USE_DMA_ACCESS_HANDLER
    169170    /** List of DMA handlers. */
    170171    RTLISTANCHORR3          lstDMAHandlers;
    171172#endif
    172     /** How much DMA data from a previous transfer is left to be processed (in bytes).
    173      *  This can happen if the stream's frame size is bigger (e.g. 16 bytes) than
    174      *  the current DMA FIFO can hold (e.g. 10 bytes). Mostly needed for more complex
    175      *  stuff like interleaved surround streams. */
    176     uint16_t                cbDMALeft;
    177     /** Unused, padding. */
    178     uint8_t                 abPadding4[2+4];
    179173   /** Timestamp (in ns) of last stream update. */
    180174    uint64_t                tsLastUpdateNs;
  • trunk/src/VBox/Devices/Audio/HDAStreamChannel.cpp

    r71736 r75962  
    6666
    6767/**
    68  * Extracts HDA audio stream data and stores it into the given stream channel data block.
    69  *
    70  * @returns IPRT status code.
    71  * @param   pChan               Channel data to extract audio stream data into.
    72  * @param   pvBuf               Buffer of audio data to extract.
    73  * @param   cbBuf               Size (in bytes) of audio data to extract.
    74  */
    75 int hdaR3StreamChannelExtract(PPDMAUDIOSTREAMCHANNEL pChan, const void *pvBuf, size_t cbBuf)
    76 {
    77     AssertPtrReturn(pChan, VERR_INVALID_POINTER);
    78     AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
    79     AssertReturn(cbBuf,    VERR_INVALID_PARAMETER);
    80 
    81     AssertRelease(pChan->cbOff <= cbBuf);
    82 
    83     const uint8_t *pu8Buf = (const uint8_t *)pvBuf;
    84 
    85     size_t         cbSrc = cbBuf - pChan->cbOff;
    86     const uint8_t *pvSrc = &pu8Buf[pChan->cbOff];
    87 
    88     size_t         cbDst;
    89     uint8_t       *pvDst;
    90     RTCircBufAcquireWriteBlock(pChan->Data.pCircBuf, cbBuf, (void **)&pvDst, &cbDst);
    91 
    92     cbSrc = RT_MIN(cbSrc, cbDst);
    93 
    94     while (cbSrc)
    95     {
    96         AssertBreak(cbDst >= cbSrc);
    97 
    98         /* Enough data for at least one next frame? */
    99         if (cbSrc < pChan->cbFrame)
    100             break;
    101 
    102         memcpy(pvDst, pvSrc, pChan->cbFrame);
    103 
    104         /* Advance to next channel frame in stream. */
    105         pvSrc        += pChan->cbStep;
    106         Assert(cbSrc >= pChan->cbStep);
    107         cbSrc        -= pChan->cbStep;
    108 
    109         /* Advance destination by one frame. */
    110         pvDst        += pChan->cbFrame;
    111         Assert(cbDst >= pChan->cbFrame);
    112         cbDst        -= pChan->cbFrame;
    113 
    114         /* Adjust offset. */
    115         pChan->cbOff += pChan->cbFrame;
    116     }
    117 
    118     RTCircBufReleaseWriteBlock(pChan->Data.pCircBuf, cbDst);
    119 
    120     return VINF_SUCCESS;
    121 }
    122 
    123 /**
    124  * Advances the current read / write pointer by a certain amount.
    125  *
    126  * @returns IPRT status code.
    127  * @param   pChan               Channel data to advance read / write pointer for.
    128  * @param   cbAdv               Amount (in bytes) to advance read / write pointer.
    129  *
    130  * @remark  Currently not used / implemented.
    131  */
    132 int hdaR3StreamChannelAdvance(PPDMAUDIOSTREAMCHANNEL pChan, size_t cbAdv)
    133 {
    134     AssertPtrReturn(pChan, VERR_INVALID_POINTER);
    135 
    136     if (!cbAdv)
    137         return VINF_SUCCESS;
    138 
    139     return VINF_SUCCESS;
    140 }
    141 
    142 /**
    14368 * Acquires (reads) audio channel data.
    14469 * Must be released when done with hdaR3StreamChannelReleaseData().
  • trunk/src/VBox/Devices/Audio/HDAStreamChannel.h

    r71736 r75962  
    2121int  hdaR3StreamChannelDataInit(PPDMAUDIOSTREAMCHANNELDATA pChanData, uint32_t fFlags);
    2222void hdaR3StreamChannelDataDestroy(PPDMAUDIOSTREAMCHANNELDATA pChanData);
    23 int  hdaR3StreamChannelExtract(PPDMAUDIOSTREAMCHANNEL pChan, const void *pvBuf, size_t cbBuf);
    24 int  hdaR3StreamChannelAdvance(PPDMAUDIOSTREAMCHANNEL pChan, size_t cbAdv);
    2523int  hdaR3StreamChannelAcquireData(PPDMAUDIOSTREAMCHANNELDATA pChanData, void *ppvData, size_t *pcbData);
    2624int  hdaR3StreamChannelReleaseData(PPDMAUDIOSTREAMCHANNELDATA pChanData);
  • trunk/src/VBox/Devices/Audio/HDAStreamMap.cpp

    r73529 r75962  
    55
    66/*
    7  * Copyright (C) 2017 Oracle Corporation
     7 * Copyright (C) 2017-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3535#ifdef IN_RING3
    3636
     37static int hdaR3StreamMapSetup(PHDASTREAMMAP pMap, PPDMAUDIOPCMPROPS pProps);
     38
    3739/**
    3840 * Initializes a stream mapping structure according to the given PCM properties.
    3941 *
    4042 * @return  IPRT status code.
    41  * @param   pMapping            Pointer to mapping to initialize.
     43 * @param   pMap                Pointer to mapping to initialize.
    4244 * @param   pProps              Pointer to PCM properties to use for initialization.
    4345 */
    44 int hdaR3StreamMapInit(PHDASTREAMMAPPING pMapping, PPDMAUDIOPCMPROPS pProps)
     46int hdaR3StreamMapInit(PHDASTREAMMAP pMap, PPDMAUDIOPCMPROPS pProps)
    4547{
    46     AssertPtrReturn(pMapping, VERR_INVALID_POINTER);
     48    AssertPtrReturn(pMap, VERR_INVALID_POINTER);
    4749    AssertPtrReturn(pProps,   VERR_INVALID_POINTER);
    4850
     
    5052        return VERR_INVALID_PARAMETER;
    5153
    52     hdaR3StreamMapReset(pMapping);
     54    hdaR3StreamMapReset(pMap);
    5355
    54     pMapping->paChannels = (PPDMAUDIOSTREAMCHANNEL)RTMemAlloc(sizeof(PDMAUDIOSTREAMCHANNEL) * pProps->cChannels);
    55     if (!pMapping->paChannels)
    56         return VERR_NO_MEMORY;
     56    int rc = hdaR3StreamMapSetup(pMap, pProps);
     57    if (RT_FAILURE(rc))
     58        return rc;
    5759
    58     int rc = VINF_SUCCESS;
    59 
    60     Assert(RT_IS_POWER_OF_TWO(pProps->cBytes * 8));
    61 
    62     /** @todo We assume all channels in a stream have the same format. */
    63     PPDMAUDIOSTREAMCHANNEL pChan = pMapping->paChannels;
    64     for (uint8_t i = 0; i < pProps->cChannels; i++)
    65     {
    66         pChan->uChannel = i;
    67         pChan->cbStep   = pProps->cBytes;
    68         pChan->cbFrame  = pChan->cbStep * pProps->cChannels;
    69         pChan->cbFirst  = i * pChan->cbStep;
    70         pChan->cbOff    = pChan->cbFirst;
    71 
    72         int rc2 = hdaR3StreamChannelDataInit(&pChan->Data, PDMAUDIOSTREAMCHANNELDATA_FLAG_NONE);
    73         if (RT_SUCCESS(rc))
    74             rc = rc2;
    75 
    76         if (RT_FAILURE(rc))
    77             break;
    78 
    79         pChan++;
    80     }
    81 
     60#ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
    8261    if (   RT_SUCCESS(rc)
    8362        /* Create circular buffer if not created yet. */
    84         && !pMapping->pCircBuf)
     63        && !pMap->pCircBuf)
    8564    {
    86         rc = RTCircBufCreate(&pMapping->pCircBuf, _4K); /** @todo Make size configurable? */
     65        rc = RTCircBufCreate(&pMap->pCircBuf, _4K); /** @todo Make size configurable? */
    8766    }
     67#endif
    8868
    8969    if (RT_SUCCESS(rc))
    9070    {
    91         pMapping->cChannels = pProps->cChannels;
    92 #ifdef VBOX_WITH_HDA_AUDIO_INTERLEAVING_STREAMS_SUPPORT
    93         pMapping->enmLayout = PDMAUDIOSTREAMLAYOUT_INTERLEAVED;
    94 #else
    95         pMapping->enmLayout = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
    96 #endif
     71        pMap->cbFrameSize = pProps->cChannels * pProps->cBytes;
     72
     73        LogFunc(("cChannels=%RU8, cBytes=%RU8 -> cbFrameSize=%RU32\n",
     74                 pProps->cChannels, pProps->cBytes, pMap->cbFrameSize));
     75
     76        Assert(pMap->cbFrameSize); /* Frame size must not be 0. */
     77
     78        pMap->enmLayout = PDMAUDIOSTREAMLAYOUT_INTERLEAVED;
    9779    }
    9880
     
    10486 * Destroys a given stream mapping.
    10587 *
    106  * @param   pMapping            Pointer to mapping to destroy.
     88 * @param   pMap            Pointer to mapping to destroy.
    10789 */
    108 void hdaR3StreamMapDestroy(PHDASTREAMMAPPING pMapping)
     90void hdaR3StreamMapDestroy(PHDASTREAMMAP pMap)
    10991{
    110     hdaR3StreamMapReset(pMapping);
     92    hdaR3StreamMapReset(pMap);
    11193
    112     if (pMapping->pCircBuf)
     94#ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
     95    if (pMap->pCircBuf)
    11396    {
    114         RTCircBufDestroy(pMapping->pCircBuf);
    115         pMapping->pCircBuf = NULL;
     97        RTCircBufDestroy(pMap->pCircBuf);
     98        pMap->pCircBuf = NULL;
    11699    }
     100#endif
    117101}
    118102
     
    121105 * Resets a given stream mapping.
    122106 *
    123  * @param   pMapping            Pointer to mapping to reset.
     107 * @param   pMap            Pointer to mapping to reset.
    124108 */
    125 void hdaR3StreamMapReset(PHDASTREAMMAPPING pMapping)
     109void hdaR3StreamMapReset(PHDASTREAMMAP pMap)
    126110{
    127     AssertPtrReturnVoid(pMapping);
     111    AssertPtrReturnVoid(pMap);
    128112
    129     pMapping->enmLayout = PDMAUDIOSTREAMLAYOUT_UNKNOWN;
     113    pMap->enmLayout = PDMAUDIOSTREAMLAYOUT_UNKNOWN;
    130114
    131     if (pMapping->cChannels)
     115    if (pMap->paMappings)
    132116    {
    133         for (uint8_t i = 0; i < pMapping->cChannels; i++)
    134             hdaR3StreamChannelDataDestroy(&pMapping->paChannels[i].Data);
     117        for (uint8_t i = 0; i < pMap->cMappings; i++)
     118            hdaR3StreamChannelDataDestroy(&pMap->paMappings[i].Data);
    135119
    136         AssertPtr(pMapping->paChannels);
    137         RTMemFree(pMapping->paChannels);
    138         pMapping->paChannels = NULL;
     120        RTMemFree(pMap->paMappings);
     121        pMap->paMappings = NULL;
    139122
    140         pMapping->cChannels = 0;
     123        pMap->cMappings = 0;
    141124    }
    142125}
    143126
     127
     128/**
     129 * Sets up a stream mapping according to the given properties / configuration.
     130 *
     131 * @return VBox status code, or VERR_NOT_SUPPORTED if the channel setup is not supported (yet).
     132 * @param  pMap                 Pointer to mapping to set up.
     133 * @param  pProps               PCM audio properties to use for lookup.
     134 */
     135static int hdaR3StreamMapSetup(PHDASTREAMMAP pMap, PPDMAUDIOPCMPROPS pProps)
     136{
     137    int rc;
     138
     139    /** @todo We ASSUME that all channels in a stream ...
     140     *        - have the same format
     141     *        - are in a consecutive order with no gaps in between
     142     *        - have a simple (raw) data layout
     143     *        - work in a non-striped fashion, e.g. interleaved (only on one SDn, not spread over multiple SDns) */
     144    if  (   pProps->cChannels == 1  /* Mono */
     145         || pProps->cChannels == 2  /* Stereo */
     146         || pProps->cChannels == 4  /* Quadrophonic */
     147         || pProps->cChannels == 6) /* Surround (5.1) */
     148    {
     149        /* For now we don't have anything other as mono / stereo channels being covered by the backends.
     150         * So just set up one channel covering those and skipping the rest (like configured rear or center/LFE outputs). */
     151        pMap->cMappings  = 1;
     152        pMap->paMappings = (PPDMAUDIOSTREAMMAP)RTMemAlloc(sizeof(PDMAUDIOSTREAMMAP) * pMap->cMappings);
     153        if (!pMap->paMappings)
     154            return VERR_NO_MEMORY;
     155
     156        PPDMAUDIOSTREAMMAP pMapLR = &pMap->paMappings[0];
     157
     158        pMapLR->aID[0]  = PDMAUDIOSTREAMCHANNELID_FRONT_LEFT;
     159        pMapLR->aID[1]  = PDMAUDIOSTREAMCHANNELID_FRONT_RIGHT;
     160        pMapLR->cbFrame = pProps->cBytes * pProps->cChannels;
     161        pMapLR->cbSize  = pProps->cBytes * 2 /* Front left + Front right channels */;
     162        pMapLR->cbFirst = 0;
     163        pMapLR->cbOff   = pMapLR->cbFirst;
     164
     165        rc = hdaR3StreamChannelDataInit(&pMapLR->Data, PDMAUDIOSTREAMCHANNELDATA_FLAG_NONE);
     166        AssertRC(rc);
     167    }
     168    else
     169        rc = VERR_NOT_SUPPORTED; /** @todo r=andy Support more setups. */
     170
     171    return rc;
     172}
    144173#endif /* IN_RING3 */
    145174
  • trunk/src/VBox/Devices/Audio/HDAStreamMap.h

    r71754 r75962  
    11/* $Id$ */
    22/** @file
    3  * HDAStreamMap.h - Stream mapping functions for HD Audio.
     3 * HDAStreamMap.h - Stream map functions for HD Audio.
    44 */
    55
    66/*
    7  * Copyright (C) 2017 Oracle Corporation
     7 * Copyright (C) 2017-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2222 * Structure for keeping an audio stream data mapping.
    2323 */
    24 typedef struct HDASTREAMMAPPING
     24typedef struct HDASTREAMMAP
    2525{
    2626    /** The stream's layout. */
    27     PDMAUDIOSTREAMLAYOUT              enmLayout;
    28     /** Number of audio channels in this stream. */
    29     uint8_t                           cChannels;
    30     /** Array of audio channels. */
    31     R3PTRTYPE(PPDMAUDIOSTREAMCHANNEL) paChannels;
     27    PDMAUDIOSTREAMLAYOUT               enmLayout;
     28    uint8_t                            cbFrameSize;
     29    /** Number of mappings in paMappings. */
     30    uint8_t                            cMappings;
     31    uint8_t                            aPadding[2];
     32    /** Array of stream mappings.
     33     *  Note: The mappings *must* be layed out in an increasing order, e.g.
     34     *        how the data appears in the given data block. */
     35    R3PTRTYPE(PPDMAUDIOSTREAMMAP)      paMappings;
     36#if HC_ARCH_BITS == 32
     37    RTR3PTR                            Padding1;
     38#endif
     39#ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
    3240    /** Circular buffer holding for holding audio data for this mapping. */
    33     R3PTRTYPE(PRTCIRCBUF)             pCircBuf;
    34 } HDASTREAMMAPPING;
    35 AssertCompileSizeAlignment(HDASTREAMMAPPING, 8);
    36 typedef HDASTREAMMAPPING *PHDASTREAMMAPPING;
     41    R3PTRTYPE(PRTCIRCBUF)              pCircBuf;
     42#endif
     43} HDASTREAMMAP;
     44AssertCompileSizeAlignment(HDASTREAMMAP, 8);
     45typedef HDASTREAMMAP *PHDASTREAMMAP;
    3746
    3847/** @name Stream mapping functions.
     
    4049 */
    4150#ifdef IN_RING3
    42 int  hdaR3StreamMapInit(PHDASTREAMMAPPING pMapping, PPDMAUDIOPCMPROPS pProps);
    43 void hdaR3StreamMapDestroy(PHDASTREAMMAPPING pMapping);
    44 void hdaR3StreamMapReset(PHDASTREAMMAPPING pMapping);
     51int  hdaR3StreamMapInit(PHDASTREAMMAP pMapping, PPDMAUDIOPCMPROPS pProps);
     52void hdaR3StreamMapDestroy(PHDASTREAMMAP pMapping);
     53void hdaR3StreamMapReset(PHDASTREAMMAP pMapping);
    4554#endif /* IN_RING3 */
    4655/** @} */
  • trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp

    r75867 r75962  
    19761976    GEN_CHECK_OFF(HDABDLE, State);
    19771977
     1978    GEN_CHECK_SIZE(HDASTREAMMAP);
     1979
    19781980    GEN_CHECK_SIZE(HDASTREAMSTATE);
    19791981    GEN_CHECK_OFF(HDASTREAMSTATE, uCurBDLE);
Note: See TracChangeset for help on using the changeset viewer.

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