VirtualBox

Changeset 53562 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Dec 17, 2014 3:37:22 PM (10 years ago)
Author:
vboxsync
Message:

PDM/Audio: First working version of the OSS backend.

File:
1 edited

Legend:

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

    r53523 r53562  
    7272    int                cFragments;
    7373    int                cbFragmentSize;
    74     void              *pvPCMBuf;
     74    void              *pvBuf;
     75    size_t             cbBuf;
    7576    int                old_optr;
    7677} OSSAUDIOSTREAMIN, *POSSAUDIOSTREAMIN;
     
    412413                                                  uint32_t *pcSamplesCaptured)
    413414{
    414     *pcSamplesCaptured = 0;
    415     return VINF_SUCCESS;
    416 }
    417 
    418 static DECLCALLBACK(int) drvHostOSSAudioFiniIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMIN pHstStrmIn)
    419 {
    420415    NOREF(pInterface);
    421416    AssertPtrReturn(pHstStrmIn, VERR_INVALID_POINTER);
     
    423418    POSSAUDIOSTREAMIN pThisStrmIn = (POSSAUDIOSTREAMIN)pHstStrmIn;
    424419
     420    int rc = VINF_SUCCESS;
     421    size_t cbToRead = RT_MIN(pThisStrmIn->cbBuf,
     422                             audioMixBufFreeBytes(&pHstStrmIn->MixBuf));
     423
     424    LogFlowFunc(("cbToRead=%zu\n", cbToRead));
     425
     426    uint32_t cWrittenTotal = 0;
     427    uint32_t cbTemp;
     428    ssize_t  cbRead;
     429    size_t   offWrite = 0;
     430
     431    while (cbToRead)
     432    {
     433        cbTemp = RT_MIN(cbToRead, pThisStrmIn->cbBuf);
     434        AssertBreakStmt(cbTemp, rc = VERR_NO_DATA);
     435        cbRead = read(pThisStrmIn->hFile, pThisStrmIn->pvBuf + offWrite, cbTemp);
     436
     437        LogFlowFunc(("cbRead=%zi, cbTemp=%RU32, cbToRead=%zu\n",
     438                     cbRead, cbTemp, cbToRead));
     439
     440        if (cbRead < 0)
     441        {
     442            switch (errno)
     443            {
     444                case 0:
     445                {
     446                    LogFunc(("Failed to read %z frames\n", cbRead));
     447                    rc = VERR_ACCESS_DENIED;
     448                    break;
     449                }
     450
     451                case EINTR:
     452                case EAGAIN:
     453                    rc = VERR_NO_DATA;
     454                    break;
     455
     456                default:
     457                    LogFlowFunc(("Failed to read %zu input frames, rc=%Rrc\n",
     458                                 cbTemp, rc));
     459                    rc = VERR_GENERAL_FAILURE; /** @todo */
     460                    break;
     461            }
     462
     463            if (RT_FAILURE(rc))
     464                break;
     465        }
     466        else if (cbRead)
     467        {
     468            uint32_t cWritten; 
     469            rc = audioMixBufWriteCirc(&pHstStrmIn->MixBuf,
     470                                      pThisStrmIn->pvBuf, cbRead,
     471                                      &cWritten);
     472            if (RT_FAILURE(rc))
     473                break;
     474
     475            uint32_t cbWritten = AUDIOMIXBUF_S2B(&pHstStrmIn->MixBuf, cWritten);
     476
     477            Assert(cbToRead >= cbWritten);
     478            cbToRead      -= cbWritten;
     479            offWrite      += cbWritten;
     480            cWrittenTotal += cWritten;
     481        }
     482        else /* No more data, try next round. */
     483            break;
     484    }
     485
     486    if (rc == VERR_NO_DATA)
     487        rc = VINF_SUCCESS;
     488
     489    if (RT_SUCCESS(rc))
     490    {
     491        uint32_t cProcessed = 0;
     492        if (cWrittenTotal)
     493            rc = audioMixBufMixToParent(&pHstStrmIn->MixBuf, cWrittenTotal,
     494                                        &cProcessed);
     495
     496        if (pcSamplesCaptured)
     497            *pcSamplesCaptured = cWrittenTotal;
     498
     499        LogFlowFunc(("cWrittenTotal=%RU32 (%RU32 processed), rc=%Rrc\n",
     500                     cWrittenTotal, cProcessed, rc));
     501    }
     502
     503    LogFlowFuncLeaveRC(rc);
     504    return rc;
     505}
     506
     507static DECLCALLBACK(int) drvHostOSSAudioFiniIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMIN pHstStrmIn)
     508{
     509    NOREF(pInterface);
     510    AssertPtrReturn(pHstStrmIn, VERR_INVALID_POINTER);
     511
     512    POSSAUDIOSTREAMIN pThisStrmIn = (POSSAUDIOSTREAMIN)pHstStrmIn;
     513
    425514    LogFlowFuncEnter();
    426515
    427     RTMemFree(pThisStrmIn->pvPCMBuf);
    428     pThisStrmIn->pvPCMBuf = NULL;
     516    if (pThisStrmIn->pvBuf)
     517    {
     518        RTMemFree(pThisStrmIn->pvBuf);
     519        pThisStrmIn->pvBuf = NULL;
     520    }
    429521
    430522    return VINF_SUCCESS;
     
    443535    if (!pThisStrmOut->fMemMapped)
    444536    {
    445         RTMemFree(pThisStrmOut->pvPCMBuf);
    446         pThisStrmOut->pvPCMBuf = NULL;
     537        if (pThisStrmOut->pvPCMBuf)
     538        {
     539            RTMemFree(pThisStrmOut->pvPCMBuf);
     540            pThisStrmOut->pvPCMBuf = NULL;
     541        }
    447542    }
    448543#endif
     
    509604            {
    510605                cSamples = (obtStream.cFragments * obtStream.cbFragmentSize)
    511                            >> pHstStrmIn->Props.cShift; 
     606                           >> pHstStrmIn->Props.cShift;
     607                if (!cSamples)
     608                    rc = VERR_INVALID_PARAMETER;
    512609            }
    513610        }
     
    515612        if (RT_SUCCESS(rc))
    516613        {
    517             pThisStrmIn->pvPCMBuf = RTMemAlloc(cSamples * (1 << pHstStrmIn->Props.cShift));
    518             if (!pThisStrmIn->pvPCMBuf)
     614            size_t cbBuf = cSamples * (1 << pHstStrmIn->Props.cShift);
     615            pThisStrmIn->pvBuf = RTMemAlloc(cbBuf);
     616            if (!pThisStrmIn->pvBuf)
    519617            {
    520618                LogRel(("Audio: Failed allocating ADC buffer with %RU32 samples, each %d bytes\n",
     
    522620                rc = VERR_NO_MEMORY;
    523621            }
     622
     623            pThisStrmIn->cbBuf = cbBuf;
    524624
    525625            if (pcSamples)
     
    579679            rc = drvAudioStreamCfgToProps(&streamCfg, &pHstStrmOut->Props);
    580680            if (RT_SUCCESS(rc))
    581             {
    582681                cSamples = (obtStream.cFragments * obtStream.cbFragmentSize)
    583682                           >> pHstStrmOut->Props.cShift; 
    584             }
    585683        }
    586684
     
    643741            {
    644742#endif
     743                LogFlowFunc(("cSamples=%RU32\n", cSamples));
    645744                pThisStrmOut->pvPCMBuf = RTMemAlloc(cSamples * (1 << pHstStrmOut->Props.cShift));
    646745                if (!pThisStrmOut->pvPCMBuf)
     
    649748                            cSamples, 1 << pHstStrmOut->Props.cShift));
    650749                    rc = VERR_NO_MEMORY;
     750                    break;
    651751                }
    652 
    653                 break;
    654752#ifndef RT_OS_L4
    655753            }
     
    720818            audio_buf_info abinfo;
    721819            int rc2 = ioctl(pThisStrmOut->hFile, SNDCTL_DSP_GETOSPACE, &abinfo);
    722             if (!rc2)
     820            if (rc2 < 0)
    723821            {
    724822                LogRel(("Audio: Failed to retrieve current playback buffer: %s\n",
     
    788886    } while(0);
    789887
    790     uint32_t cReadTotal = AUDIOMIXBUF_B2S(&pHstStrmOut->MixBuf, cbReadTotal);
    791     if (cReadTotal)
    792         audioMixBufFinish(&pHstStrmOut->MixBuf, cReadTotal);
    793 
    794     if (pcSamplesPlayed)
    795         *pcSamplesPlayed = cReadTotal;
    796 
    797     LogFlowFunc(("cReadTotal=%RU32 (%RU32 bytes), rc=%Rrc\n",
    798                  cReadTotal, cbReadTotal, rc));
     888    if (RT_SUCCESS(rc))
     889    {
     890        uint32_t cReadTotal = AUDIOMIXBUF_B2S(&pHstStrmOut->MixBuf, cbReadTotal);
     891        if (cReadTotal)
     892            audioMixBufFinish(&pHstStrmOut->MixBuf, cReadTotal);
     893
     894        if (pcSamplesPlayed)
     895            *pcSamplesPlayed = cReadTotal;
     896
     897        LogFlowFunc(("cReadTotal=%RU32 (%RU32 bytes), rc=%Rrc\n",
     898                     cReadTotal, cbReadTotal, rc));
     899    }
     900
     901    LogFlowFuncLeaveRC(rc);
    799902    return rc;
    800903}
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