VirtualBox

Ignore:
Timestamp:
Jun 7, 2016 9:47:21 AM (9 years ago)
Author:
vboxsync
Message:

Audio: Update.

File:
1 edited

Legend:

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

    r61399 r61523  
    4646*********************************************************************************************************************************/
    4747
    48 #ifdef DEBUG
    49 //#define DEBUG_LUN
    50 # ifdef DEBUG_LUN
    51 #  define DEBUG_LUN_NUM 1
     48#ifdef DEBUG_andy
     49/*
     50 * AC97_DEBUG_DUMP_PCM_DATA enables dumping the raw PCM data
     51 * to a file on the host. Be sure to adjust AC97_DEBUG_DUMP_PCM_DATA_PATH
     52 * to your needs before using this!
     53 */
     54# define AC97_DEBUG_DUMP_PCM_DATA
     55# ifdef RT_OS_WINDOWS
     56#  define AC97_DEBUG_DUMP_PCM_DATA_PATH "c:\\temp\\"
     57# else
     58#  define AC97_DEBUG_DUMP_PCM_DATA_PATH "/tmp/"
    5259# endif
    53 #endif /* DEBUG */
     60#endif /* DEBUG_andy */
    5461
    5562#define AC97_SSM_VERSION 1
     
    7683#define CR_IOCE  RT_BIT(4)         /* rw,   Interrupt On Completion Enable. */
    7784#define CR_FEIE  RT_BIT(3)         /* rw    FIFO Error Interrupt Enable. */
    78 #define CR_LVBIE RT_BIT(2)         /* rw    */
    79 #define CR_RR    RT_BIT(1)         /* rw */
    80 #define CR_RPBM  RT_BIT(0)         /* rw */
     85#define CR_LVBIE RT_BIT(2)         /* rw    Last Valid Buffer Interrupt Enable. */
     86#define CR_RR    RT_BIT(1)         /* rw    Reset Registers. */
     87#define CR_RPBM  RT_BIT(0)         /* rw    Run/Pause Bus Master. */
    8188#define CR_VALID_MASK (RT_BIT(5) - 1)
    8289#define CR_DONT_CLEAR_MASK (CR_IOCE | CR_FEIE | CR_LVBIE)
     
    263270    uint8_t  lvi;               /** rw 0, Last valid index. */
    264271    uint16_t sr;                /** rw 1, Status register. */
    265     uint16_t picb;              /** ro 0, Position in current buffer. */
     272    uint16_t picb;              /** ro 0, Position in current buffer (in samples). */
    266273    uint8_t  piv;               /** ro 0, Prefetched index value. */
    267274    uint8_t  cr;                /** rw 0, Control register. */
     
    423430static DECLCALLBACK(void) ichac97Timer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser);
    424431#endif
    425 static int ichac97TransferAudio(PAC97STATE pThis, PAC97STREAM pStream, uint32_t cbElapsed);
     432static int ichac97TransferAudio(PAC97STATE pThis, PAC97STREAM pStream);
    426433
    427434static void ichac97WarmReset(PAC97STATE pThis)
     
    532539    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    533540
    534     bool fActive = AudioMixerSinkHasData(ichac97IndexToSink(pThis, pStream->u8Strm));
     541    bool fActive = AudioMixerSinkGetStatus(ichac97IndexToSink(pThis, pStream->u8Strm));
    535542
    536543    LogFlowFunc(("SD=%RU8, fActive=%RTbool\n", pStream->u8Strm, fActive));
     
    11451152 * @param   pcbWritten
    11461153 */
    1147 static int ichac97WriteAudio(PAC97STATE pThis, PAC97STREAM pStream, uint32_t cbMax, uint32_t *pcbWritten)
     1154static int ichac97WriteAudio(PAC97STATE pThis, PAC97STREAM pStream, uint32_t cbToWrite, uint32_t *pcbWritten)
    11481155{
    11491156    AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
    11501157    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    1151     AssertReturn(cbMax,      VERR_INVALID_PARAMETER);
     1158    AssertReturn(cbToWrite,  VERR_INVALID_PARAMETER);
    11521159    /* pcbWritten is optional. */
    11531160
     
    11581165    uint32_t    cbWrittenTotal = 0;
    11591166
    1160     Log3Func(("PICB=%RU16, cbMax=%RU32\n", pRegs->picb, cbMax));
    1161 
    1162     uint32_t cbToWrite = RT_MIN((uint32_t)(pRegs->picb << 1), cbMax); /** @todo r=andy Assumes 16bit sample size. */
     1167    Log3Func(("PICB=%RU16, cbMax=%RU32\n", pRegs->picb, cbToWrite));
     1168
     1169    cbToWrite = RT_MIN((uint32_t)(pRegs->picb << 1), cbToWrite); /** @todo r=andy Assumes 16bit sample size. */
    11631170    if (!cbToWrite)
    11641171    {
     
    11701177    int rc = VINF_SUCCESS;
    11711178
    1172     LogFlowFunc(("pReg=%p, cbMax=%RU32, cbToWrite=%RU32\n", pRegs, cbMax, cbToWrite));
     1179    LogFlowFunc(("pRegs=%p, cbMax=%RU32, cbToWrite=%RU32\n", pRegs, cbToWrite, cbToWrite));
    11731180
    11741181    Assert(pStream->State.offFIFOW <= pStream->State.cbFIFOW);
     
    11821189        PDMDevHlpPhysRead(pDevIns, addr, pu8FIFOW, cbToRead); /** @todo r=andy Check rc? */
    11831190
    1184 #if defined (RT_OS_LINUX) && defined(DEBUG_andy)
     1191#ifdef AC97_DEBUG_DUMP_PCM_DATA
    11851192        RTFILE fh;
    1186         RTFileOpen(&fh, "/tmp/ac97WriteAudio.pcm",
     1193        RTFileOpen(&fh, AC97_DEBUG_DUMP_PCM_DATA_PATH "ac97WriteAudio.pcm",
    11871194                   RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
    11881195        RTFileWrite(fh, pu8FIFOW, cbToRead, NULL);
     
    12341241static void ichac97WriteBUP(PAC97STATE pThis, uint32_t cbElapsed)
    12351242{
     1243    LogFlowFunc(("cbElapsed=%RU32\n", cbElapsed));
     1244
    12361245    if (!(pThis->bup_flag & BUP_SET))
    12371246    {
     
    12401249            unsigned int i;
    12411250            uint32_t *p = (uint32_t*)pThis->silence;
    1242             for (i = 0; i < sizeof(pThis->silence) / 4; i++)
     1251            for (i = 0; i < sizeof(pThis->silence) / 4; i++) /** @todo r=andy Assumes 16-bit samples, stereo. */
    12431252                *p++ = pThis->last_samp;
    12441253        }
     
    12691278}
    12701279
    1271 static int ichac97ReadAudio(PAC97STATE pThis, PAC97STREAM pStream, uint32_t cbMax, uint32_t *pcbRead)
     1280static int ichac97ReadAudio(PAC97STATE pThis, PAC97STREAM pStream, uint32_t cbToRead, uint32_t *pcbRead)
    12721281{
    12731282    AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
    12741283    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    1275     AssertReturn(cbMax,      VERR_INVALID_PARAMETER);
     1284    AssertReturn(cbToRead,   VERR_INVALID_PARAMETER);
    12761285    /* pcbRead is optional. */
    12771286
     
    12851294
    12861295    uint32_t cbRead   = 0;
    1287     uint32_t cbToRead = RT_MIN((uint32_t)(pRegs->picb << 1),
    1288                                RT_MIN(pStream->State.cbFIFOW, cbMax)); /** @todo r=andy Assumes 16bit samples. */
     1296
     1297    cbToRead = RT_MIN((uint32_t)(pRegs->picb << 1),
     1298                      RT_MIN(pStream->State.cbFIFOW, cbToRead)); /** @todo r=andy Assumes 16bit samples. */
    12891299
    12901300    if (!cbToRead)
     
    13651375    uint64_t cTicksPerSec  = TMTimerGetFreq(pTimer);
    13661376
     1377    LogFlowFuncEnter();
     1378
    13671379    /* Update current time timestamp. */
    13681380    pThis->uTimerTS = cTicksNow;
    13691381
    1370     LogFlowFuncEnter();
    1371 
    1372     uint32_t cbLineIn;
    1373     AudioMixerSinkTimerUpdate(pThis->pSinkLineIn, pThis->cTimerTicks, cTicksPerSec, &cbLineIn);
    1374     if (cbLineIn)
    1375         ichac97TransferAudio(pThis, &pThis->StreamLineIn, cbLineIn);
    1376 
    1377     uint32_t cbMicIn;
    1378     AudioMixerSinkTimerUpdate(pThis->pSinkMicIn , pThis->cTimerTicks, cTicksPerSec, &cbMicIn);
    1379     if (cbMicIn)
    1380         ichac97TransferAudio(pThis, &pThis->StreamMicIn, cbMicIn);
    1381 
    1382     uint32_t cbOut;
    1383     AudioMixerSinkTimerUpdate(pThis->pSinkOutput, pThis->cTimerTicks, cTicksPerSec, &cbOut);
    1384     if (cbOut)
    1385         ichac97TransferAudio(pThis, &pThis->StreamOut, cbOut);
     1382    /* Flag indicating whether to kick the timer again for a
     1383     * new data processing round. */
     1384    bool fKickTimer = false;
     1385
     1386    AudioMixerSinkTimerUpdate(pThis->pSinkLineIn, pThis->cTimerTicks, cTicksPerSec);
     1387    ichac97TransferAudio(pThis, &pThis->StreamLineIn);
     1388
     1389    fKickTimer = AudioMixerSinkGetStatus(pThis->pSinkLineIn) & AUDMIXSINK_STS_DIRTY;
     1390
     1391    AudioMixerSinkTimerUpdate(pThis->pSinkMicIn , pThis->cTimerTicks, cTicksPerSec);
     1392    ichac97TransferAudio(pThis, &pThis->StreamMicIn);
     1393
     1394    fKickTimer = AudioMixerSinkGetStatus(pThis->pSinkMicIn) & AUDMIXSINK_STS_DIRTY;
     1395
     1396    AudioMixerSinkTimerUpdate(pThis->pSinkOutput, pThis->cTimerTicks, cTicksPerSec);
     1397    ichac97TransferAudio(pThis, &pThis->StreamOut);
     1398
     1399    fKickTimer = AudioMixerSinkGetStatus(pThis->pSinkOutput) & AUDMIXSINK_STS_DIRTY;
    13861400
    13871401    if (   ASMAtomicReadBool(&pThis->fTimerActive)
    1388         || AudioMixerSinkHasData(pThis->pSinkLineIn)
    1389         || AudioMixerSinkHasData(pThis->pSinkMicIn)
    1390         || AudioMixerSinkHasData(pThis->pSinkOutput))
     1402        || fKickTimer)
    13911403    {
    13921404        /* Kick the timer again. */
     
    14011413#endif /* !VBOX_WITH_AUDIO_CALLBACKS */
    14021414
    1403 static int ichac97TransferAudio(PAC97STATE pThis, PAC97STREAM pStream, uint32_t cbElapsed)
    1404 {
    1405     Log3Func(("SD=%RU8, cbElapsed=%RU32\n", pStream->u8Strm , cbElapsed));
     1415static int ichac97TransferAudio(PAC97STATE pThis, PAC97STREAM pStream)
     1416{
     1417    Log3Func(("SD=%RU8\n", pStream->u8Strm));
    14061418
    14071419    PAC97BMREGS pRegs = &pStream->Regs;
     
    14091421    if (pRegs->sr & SR_DCH) /* Controller halted? */
    14101422    {
    1411         if (pRegs->cr & CR_RPBM)
     1423        if (pRegs->cr & CR_RPBM) /* Bus master operation starts. */
    14121424        {
    14131425            switch (pStream->u8Strm)
    14141426            {
    14151427                case PO_INDEX:
    1416                     ichac97WriteBUP(pThis, cbElapsed);
     1428                    ichac97WriteBUP(pThis, (uint32_t)(pRegs->picb << 1));
    14171429                    break;
    14181430
     
    14321444    uint32_t cbWrittenTotal = 0;
    14331445
    1434     while (cbElapsed >> 1) /** @todo r=andy This assumes (hardcodes) 16bit sample size.*/
     1446    do
    14351447    {
    14361448        if (!pRegs->bd_valid)
     
    14461458            if (pRegs->civ == pRegs->lvi)
    14471459            {
    1448                 pRegs->sr |= SR_DCH; /* CELV? */
     1460                pRegs->sr |= SR_DCH; /** @todo r=andy Also set CELV? */
    14491461                pThis->bup_flag = 0;
    14501462
     
    14611473        }
    14621474
    1463         uint32_t cbTransferred;
     1475        uint32_t cbToTransfer, cbTransferred;
    14641476        switch (pStream->u8Strm)
    14651477        {
    14661478            case PO_INDEX:
    14671479            {
    1468                 rc = ichac97WriteAudio(pThis, pStream, cbElapsed, &cbTransferred);
     1480                cbToTransfer = (uint32_t)(pRegs->picb << 1);
     1481
     1482                rc = ichac97WriteAudio(pThis, pStream, cbToTransfer, &cbTransferred);
    14691483                if (   RT_SUCCESS(rc)
    14701484                    && cbTransferred)
    14711485                {
    14721486                    cbWrittenTotal += cbTransferred;
    1473                     Assert(cbElapsed >= cbTransferred);
    1474                     cbElapsed      -= cbTransferred;
    1475                     Assert((cbTransferred & 1) == 0);    /* Else the following shift won't work */
     1487                    Assert((cbTransferred & 1) == 0); /* Else the following shift won't work */
    14761488                    pRegs->picb    -= (cbTransferred >> 1); /** @todo r=andy Assumes 16bit samples. */
    14771489                }
     
    14821494            case MC_INDEX:
    14831495            {
    1484                 rc = ichac97ReadAudio(pThis, pStream, cbElapsed, &cbTransferred);
     1496                cbToTransfer = (uint32_t)(pRegs->picb << 1);
     1497
     1498                rc = ichac97ReadAudio(pThis, pStream, cbToTransfer, &cbTransferred);
    14851499                if (   RT_SUCCESS(rc)
    14861500                    && cbTransferred)
    14871501                {
    1488                     Assert(cbElapsed >= cbTransferred);
    1489                     cbElapsed   -= cbTransferred;
    1490                     Assert((cbTransferred & 1) == 0);    /* Else the following shift won't work */
     1502                    Assert((cbTransferred & 1) == 0); /* Else the following shift won't work */
    14911503                    pRegs->picb -= (cbTransferred >> 1); /** @todo r=andy Assumes 16bit samples. */
    14921504                }
     
    15321544        }
    15331545
    1534         if (   RT_FAILURE(rc)
    1535             || rc == VINF_EOF) /* All data processed? */
    1536         {
    1537             break;
    1538         }
    1539     }
     1546        if (rc == VINF_EOF) /* All data processed? */
     1547            break;
     1548
     1549    } while (RT_SUCCESS(rc));
    15401550
    15411551    LogFlowFuncLeaveRC(rc);
     
    15491559                                               uint32_t *pu32Val, unsigned cbVal)
    15501560{
    1551     PAC97STATE pThis    = (PAC97STATE)pvUser;
     1561    PAC97STATE pThis = (PAC97STATE)pvUser;
    15521562
    15531563    /* Get the index of the NABMBAR port. */
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