VirtualBox

Changeset 62350 in vbox


Ignore:
Timestamp:
Jul 20, 2016 10:47:36 AM (8 years ago)
Author:
vboxsync
Message:

Audio/DevSB16.cpp: Fixes.

File:
1 edited

Legend:

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

    r61609 r62350  
    22/** @file
    33 * DevSB16 - VBox SB16 Audio Controller.
    4  *
    5  * @todo hiccups on NT4 and Win98.
    64 */
    75
     
    4442#include <VBox/log.h>
    4543#include <iprt/assert.h>
     44#include <iprt/file.h>
    4645#ifdef IN_RING3
    4746# include <iprt/mem.h>
     
    5857#include "AudioMixer.h"
    5958#include "DrvAudio.h"
     59
     60#if 0
     61/*
     62 * SB16_DEBUG_DUMP_PCM_DATA enables dumping the raw PCM data
     63 * to a file on the host. Be sure to adjust SB16_DEBUG_DUMP_PCM_DATA_PATH
     64 * to your needs before using this!
     65 */
     66# define SB16_DEBUG_DUMP_PCM_DATA
     67# ifdef RT_OS_WINDOWS
     68#  define SB16_DEBUG_DUMP_PCM_DATA_PATH "c:\\temp\\"
     69# else
     70#  define SB16_DEBUG_DUMP_PCM_DATA_PATH "/tmp/"
     71# endif
     72#endif
    6073
    6174/** Current saved state version. */
     
    16381651        AssertMsgRC(rc, ("DMAReadMemory -> %Rrc\n", rc));
    16391652
     1653#ifdef SB16_DEBUG_DUMP_PCM_DATA
     1654        RTFILE fh;
     1655        RTFileOpen(&fh, SB16_DEBUG_DUMP_PCM_DATA_PATH "sb16WriteAudio.pcm",
     1656                   RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
     1657        RTFileWrite(fh, tmpbuf, cbToRead, NULL);
     1658        RTFileClose(fh);
     1659#endif
    16401660        /*
    16411661         * Write data to the backends.
     
    16811701        pThis->left_till_irq = pThis->block_size;
    16821702
    1683     PSB16DRIVER pDrv;
    1684     RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
    1685         pDrv->pConnector->pfnStreamIterate(pDrv->pConnector, pDrv->Out.pStream);
    1686 
    16871703    free = dma_len;
    16881704
     
    16931709    till = pThis->left_till_irq;
    16941710
    1695 #ifdef DEBUG_SB16_MOST
    1696     LogFlowFunc(("pos:%06d %d till:%d len:%d\n", dma_pos, free, till, dma_len));
    1697 #endif
     1711    Log3Func(("pos %d/%d free %5d till %5d\n", dma_pos, dma_len, free, till));
    16981712
    16991713    if (copy >= till)
     
    17251739    }
    17261740
    1727 #ifdef DEBUG_SB16_MOST
    1728     LogFlowFunc(("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
    1729                  dma_pos, free, dma_len, pThis->left_till_irq, copy, written,
    1730                  pThis->block_size));
    1731 #endif
     1741    Log3Func(("pos %d/%d free %5d till %5d copy %5d written %5d block_size %5d\n",
     1742               dma_pos, dma_len, free, pThis->left_till_irq, copy, written,
     1743               pThis->block_size));
    17321744
    17331745    while (pThis->left_till_irq <= 0)
     
    17831795    uint64_t cTicksPerSec  = TMTimerGetFreq(pTimer);
    17841796
     1797    bool     fIsPlaying    = false; /* Whether one or more streams are still playing. */
     1798    bool     fDoTransfer   = false;
     1799
    17851800    pThis->uTimerTSIO = cTicksNow;
    1786 
    1787     bool     fIsPlaying = false;
    1788     uint32_t cbWritable = UINT32_MAX;
    1789 
    1790     LogFlowFuncEnter();
    17911801
    17921802    PSB16DRIVER pDrv;
     
    17971807            continue;
    17981808
     1809#ifdef DEBUG
     1810        PSB16DRIVER pDrvPrev = RTListNodeGetPrev(&pDrv->Node, SB16DRIVER, Node);
     1811        if (   pDrvPrev
     1812            && !RTListNodeIsDummy(&pThis->lstDrv, pDrvPrev, SB16DRIVER, Node))
     1813        {
     1814            PPDMAUDIOSTREAM pStreamPrev = pDrvPrev->Out.pStream;
     1815            AssertPtr(pStreamPrev);
     1816
     1817            /*
     1818             * Sanity. Make sure that all streams have the same configuration
     1819             * to get SB16's DMA transfers right.
     1820             *
     1821             * SB16 only allows one output configuration per serial data out,
     1822             * so check if all streams have the same configuration.
     1823             */
     1824            AssertMsg(pStream->Cfg.uHz       == pStreamPrev->Cfg.uHz,
     1825                      ("%RU32Hz vs. %RU32Hz\n", pStream->Cfg.uHz, pStreamPrev->Cfg.uHz));
     1826            AssertMsg(pStream->Cfg.cChannels == pStreamPrev->Cfg.cChannels,
     1827                      ("%RU8 vs. %RU8 channels\n", pStream->Cfg.cChannels, pStreamPrev->Cfg.cChannels));
     1828            AssertMsg(pStream->Cfg.enmFormat == pStreamPrev->Cfg.enmFormat,
     1829                      ("%ld vs. %ld format\n", pStream->Cfg.enmFormat, pStreamPrev->Cfg.enmFormat));
     1830        }
     1831#endif
    17991832        PPDMIAUDIOCONNECTOR pConn = pDrv->pConnector;
    18001833        if (!pConn)
     
    18161849                    continue;
    18171850                }
    1818 
    1819                 rc2 = pConn->pfnStreamIterate(pConn, pStream);
    1820                 if (RT_FAILURE(rc2))
    1821                 {
    1822                     LogFlowFunc(("%s: Failed re-iterating stream, rc=%Rrc\n", pStream->szName, rc2));
    1823                     continue;
    1824                 }
    1825 
    1826                 cbWritable = RT_MIN(pConn->pfnStreamGetWritable(pConn, pStream), cbWritable);
     1851            }
     1852
     1853            if (pDrv->Flags & PDMAUDIODRVFLAG_PRIMARY)
     1854            {
     1855                /* Only do the next DMA transfer if we're able to write the entire
     1856                 * next data block. */
     1857                fDoTransfer = pConn->pfnStreamGetWritable(pConn, pStream) >= (uint32_t)pThis->block_size;
    18271858            }
    18281859        }
     
    18311862        fIsPlaying |= (   (strmSts & PDMAUDIOSTRMSTS_FLAG_ENABLED)
    18321863                       || (strmSts & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE));
    1833 
    1834         LogFlowFunc(("%s: strmSts=0x%x -> fIsPlaying=%RTbool\n", pStream->szName, strmSts, fIsPlaying));
    1835     }
    1836 
    1837     if (   ASMAtomicReadBool(&pThis->fTimerActive)
    1838         || fIsPlaying)
    1839     {
    1840         if (cbWritable)
    1841         {
    1842             /* Schedule the next transfer. */
    1843             PDMDevHlpDMASchedule(pThis->pDevInsR3);
    1844         }
    1845 
     1864    }
     1865
     1866    bool fTimerActive = ASMAtomicReadBool(&pThis->fTimerActive);
     1867    bool fKickTimer   = fTimerActive || fIsPlaying;
     1868
     1869    LogFlowFunc(("fTimerActive=%RTbool, fIsPlaying=%RTbool\n", fTimerActive, fIsPlaying));
     1870
     1871    if (fDoTransfer)
     1872    {
     1873        /* Schedule the next transfer. */
     1874        PDMDevHlpDMASchedule(pThis->pDevInsR3);
     1875
     1876        /* Kick the timer at least one more time. */
     1877        fKickTimer = true;
     1878    }
     1879
     1880    if (fKickTimer)
     1881    {
    18461882        /* Kick the timer again. */
    18471883        uint64_t cTicks = pThis->cTimerTicksIO;
     
    18491885        TMTimerSet(pThis->pTimerIO, cTicksNow + cTicks);
    18501886    }
    1851 
    1852     LogFlowFuncLeave();
    18531887}
    18541888
     
    20752109
    20762110    AssertReturn(pCfg->enmDir == PDMAUDIODIR_OUT, VERR_INVALID_PARAMETER);
     2111    Assert(DrvAudioHlpStreamCfgIsValid(pCfg));
    20772112
    20782113    /* Set a default audio format for the host. */
     
    20802115    CfgHost.enmDir          = PDMAUDIODIR_OUT;
    20812116    CfgHost.DestSource.Dest = PDMAUDIOPLAYBACKDEST_FRONT;
    2082     CfgHost.uHz             = 44100;
    2083     CfgHost.cChannels       = 2;
     2117    CfgHost.uHz             = pCfg->uHz;
     2118    CfgHost.cChannels       = pCfg->cChannels;
    20842119    CfgHost.enmFormat       = PDMAUDIOFMT_S16;
    20852120    CfgHost.enmEndianness   = PDMAUDIOHOSTENDIANNESS;
     
    20942129    RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
    20952130    {
    2096         if (!RTStrPrintf(pCfg->szName, sizeof(pCfg->szName), "[LUN#%RU8] sb16.po (%RU32Hz, %RU8 %s)",
    2097                          pDrv->uLUN, pCfg->uHz, pCfg->cChannels, pCfg->cChannels > 1 ? "Channels" : "Channel"))
     2131        if (!RTStrPrintf(pCfg->szName, sizeof(pCfg->szName), "[LUN#%RU8] %s (%RU32Hz, %RU8 %s)",
     2132                         pDrv->uLUN, CfgHost.szName, pCfg->uHz, pCfg->cChannels, pCfg->cChannels > 1 ? "Channels" : "Channel"))
    20982133        {
    20992134            rc = VERR_BUFFER_OVERFLOW;
     
    21392174    RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
    21402175    {
    2141         if (pDrv->Out.pStream)
    2142         {
    2143             pDrv->pConnector->pfnStreamRelease(pDrv->pConnector, pDrv->Out.pStream);
    2144 
    2145             int rc2 = pDrv->pConnector->pfnStreamDestroy(pDrv->pConnector, pDrv->Out.pStream);
    2146             if (RT_SUCCESS(rc2))
    2147                 pDrv->Out.pStream = NULL;
    2148         }
     2176        int rc2 = pDrv->pConnector->pfnStreamControl(pDrv->pConnector, pDrv->Out.pStream, PDMAUDIOSTREAMCMD_DISABLE);
     2177        AssertRC(rc2);
    21492178    }
    21502179
     
    22082237    LogRel2(("SB16: Powering off ...\n"));
    22092238
    2210     sb16CloseOut(pThis);
     2239    PSB16DRIVER pDrv;
     2240    RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
     2241    {
     2242        if (pDrv->Out.pStream)
     2243        {
     2244            pDrv->pConnector->pfnStreamRelease(pDrv->pConnector, pDrv->Out.pStream);
     2245
     2246            int rc2 = pDrv->pConnector->pfnStreamDestroy(pDrv->pConnector, pDrv->Out.pStream);
     2247            if (RT_SUCCESS(rc2))
     2248                pDrv->Out.pStream = NULL;
     2249        }
     2250    }
    22112251}
    22122252
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