VirtualBox

Changeset 65036 in vbox for trunk/src


Ignore:
Timestamp:
Dec 30, 2016 11:50:29 AM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
112531
Message:

Audio/DrvHostOSSAudio.cpp: Resolved some @todos, formatting, extended logging.

File:
1 edited

Legend:

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

    r63766 r65036  
    108108    /** Whether we use a memory mapped file instead of our
    109109     *  own allocated PCM buffer below. */
    110     bool                fMemMapped;
     110    /** @todo The memory mapped code seems to be utterly broken.
     111     *        Needs investigation! */
     112    bool                fMMIO;
    111113#endif
    112114    /** Own PCM buffer in case memory mapping is unavailable. */
     
    303305        }
    304306#endif
     307
     308        /* Check access mode (input or output). */
     309        bool fIn = ((fOpen & O_ACCMODE) == O_RDONLY);
     310
     311        LogRel2(("OSS: Requested %RU16 %s fragments, %RU32 bytes each\n",
     312                 pReq->cFragments, fIn ? "input" : "output", pReq->cbFragmentSize));
     313
    305314        int mmmmssss = (pReq->cFragments << 16) | lsbindex(pReq->cbFragmentSize);
    306315        if (ioctl(hFile, SNDCTL_DSP_SETFRAGMENT, &mmmmssss))
     
    311320            break;
    312321        }
    313 
    314         /* Check access mode (input or output). */
    315         bool fIn = ((fOpen & O_ACCMODE) == O_RDONLY);
    316322
    317323        audio_buf_info abinfo;
     
    331337            pObt->cbFragmentSize = abinfo.fragsize;
    332338
     339            LogRel2(("OSS: Got %RU16 %s fragments, %RU32 bytes each\n",
     340                     pObt->cFragments, fIn ? "input" : "output", pObt->cbFragmentSize));
     341
    333342            *phFile = hFile;
    334343        }
     
    356365    POSSAUDIOSTREAMOUT pStreamOut = (POSSAUDIOSTREAMOUT)pStream;
    357366
    358 #ifdef RT_OS_L4
    359     return VINF_SUCCESS;
    360 #else
    361     if (!pStreamOut->fMemMapped)
    362         return VINF_SUCCESS;
    363 #endif
    364 
    365367    int rc = VINF_SUCCESS;
    366     int mask;
     368
    367369    switch (enmStreamCmd)
    368370    {
     
    370372        case PDMAUDIOSTREAMCMD_RESUME:
    371373        {
    372             DrvAudioHlpClearBuf(&pStreamOut->Props,
    373                                 pStreamOut->pvBuf, pStreamOut->cbBuf, AudioMixBufSize(&pStream->MixBuf));
    374 
    375             mask = PCM_ENABLE_OUTPUT;
     374            DrvAudioHlpClearBuf(&pStreamOut->Props, pStreamOut->pvBuf, pStreamOut->cbBuf,
     375                                AUDIOMIXBUF_B2S(&pStream->MixBuf, pStreamOut->cbBuf));
     376
     377            int mask = PCM_ENABLE_OUTPUT;
    376378            if (ioctl(pStreamOut->hFile, SNDCTL_DSP_SETTRIGGER, &mask) < 0)
    377379            {
     
    386388        case PDMAUDIOSTREAMCMD_PAUSE:
    387389        {
    388             mask = 0;
     390            int mask = 0;
    389391            if (ioctl(pStreamOut->hFile, SNDCTL_DSP_SETTRIGGER, &mask) < 0)
    390392            {
     
    423425 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture}
    424426 */
    425 static DECLCALLBACK(int) drvHostOSSAudioStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
     427static DECLCALLBACK(int) drvHostOSSAudioStreamCapture(PPDMIHOSTAUDIO pInterface,
     428                                                      PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
    426429{
    427430    RT_NOREF(pInterface, cbBuf, pvBuf);
     
    542545
    543546#ifndef RT_OS_L4
    544     if (pStrm->fMemMapped)
     547    if (pStrm->fMMIO)
    545548    {
    546549        if (pStrm->pvBuf)
     
    554557                pStrm->cbBuf      = 0;
    555558
    556                 pStrm->fMemMapped = false;
     559                pStrm->fMMIO      = false;
    557560            }
    558561            else
     
    671674            pCfgAcq->enmFormat     = obtStream.enmFormat;
    672675            pCfgAcq->uHz           = obtStream.uFreq;
    673             pCfgAcq->cChannels     = pCfgReq->cChannels; /** @todo r=andy Why not using obtStream? */
     676            pCfgAcq->cChannels     = obtStream.cChannels;
    674677            pCfgAcq->enmEndianness = obtStream.enmENDIANNESS;
    675678
     
    738741        reqStream.cbFragmentSize = s_OSSConf.fragsize;
    739742
    740         rc = ossStreamOpen(s_OSSConf.devpath_out, O_WRONLY | O_NONBLOCK, &reqStream, &obtStream, &hFile);
     743        rc = ossStreamOpen(s_OSSConf.devpath_out, O_WRONLY, &reqStream, &obtStream, &hFile);
    741744        if (RT_SUCCESS(rc))
    742745        {
    743746            pCfgAcq->enmFormat     = obtStream.enmFormat;
    744747            pCfgAcq->uHz           = obtStream.uFreq;
    745             pCfgAcq->cChannels     = pCfgReq->cChannels; /** @todo r=andy Why not using obtStream? */
     748            pCfgAcq->cChannels     = obtStream.cChannels;
    746749            pCfgAcq->enmEndianness = obtStream.enmENDIANNESS;
    747750
     
    761764        if (RT_SUCCESS(rc))
    762765        {
    763             pStrm->fMemMapped = false;
    764 
    765             size_t cbSamples =  cSamples << pStrm->Props.cShift;
     766            pStrm->fMMIO = false;
     767
     768            size_t cbSample = (1 << pStrm->Props.cShift);
     769
     770            size_t cbSamples = cSamples * cbSample;
    766771            Assert(cbSamples);
    767772
     
    795800                        }
    796801                        else
    797                             pStrm->fMemMapped = true;
     802                        {
     803                            pStrm->fMMIO = true;
     804                            LogRel(("OSS: Using MMIO\n"));
     805                        }
    798806                    }
    799807
     
    811819            /* Memory mapping failed above? Try allocating an own buffer. */
    812820#ifndef RT_OS_L4
    813             if (!pStrm->fMemMapped)
     821            if (!pStrm->fMMIO)
    814822            {
    815823#endif
     
    844852 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay}
    845853 */
    846 static DECLCALLBACK(int) drvHostOSSAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
     854static DECLCALLBACK(int) drvHostOSSAudioStreamPlay(PPDMIHOSTAUDIO pInterface,
     855                                                   PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf,
     856                                                   uint32_t *pcbWritten)
    847857{
    848858    RT_NOREF(pInterface, cbBuf, pvBuf);
     
    852862
    853863    int rc = VINF_SUCCESS;
    854     uint32_t cbReadTotal = 0;
     864    uint32_t cbWrittenTotal = 0;
     865
     866#ifndef RT_OS_L4
    855867    count_info cntinfo;
     868#endif
    856869
    857870    do
     
    859872        size_t cbBufSize = AudioMixBufSizeBytes(&pStream->MixBuf);
    860873
    861         uint32_t cLive = AudioMixBufLive(&pStream->MixBuf);
    862         uint32_t cToRead;
     874        uint32_t csLive = AudioMixBufLive(&pStream->MixBuf);
     875        uint32_t csToRead;
    863876
    864877#ifndef RT_OS_L4
    865         if (pStrm->fMemMapped)
     878        if (pStrm->fMMIO)
    866879        {
    867880            /* Get current playback pointer. */
     
    869882            if (!rc2)
    870883            {
    871                 LogRel(("OSS: Failed to retrieve current playback pointer: %s\n",
    872                         strerror(errno)));
     884                LogRel(("OSS: Failed to retrieve current playback pointer: %s\n", strerror(errno)));
    873885                rc = RTErrConvertFromErrno(errno);
    874886                break;
     
    886898            Assert(cbData);
    887899
    888             cToRead = RT_MIN((uint32_t)AUDIOMIXBUF_B2S(&pStream->MixBuf, cbData),
    889                              cLive);
     900            csToRead = RT_MIN((uint32_t)AUDIOMIXBUF_B2S(&pStream->MixBuf, cbData),
     901                             csLive);
    890902        }
    891903        else
     
    903915            if ((size_t)abinfo.bytes > cbBufSize)
    904916            {
    905                 LogFlowFunc(("Warning: Invalid available size, size=%d, bufsize=%zu\n", abinfo.bytes, cbBufSize));
     917                LogRel2(("OSS: Warning: Too big output size (%d > %zu), limiting to %zu\n", abinfo.bytes, cbBufSize, cbBufSize));
    906918                abinfo.bytes = cbBufSize;
    907919                /* Keep going. */
     
    910922            if (abinfo.bytes < 0)
    911923            {
    912                 LogFlowFunc(("Warning: Invalid available size, size=%d, bufsize=%zu\n", abinfo.bytes, cbBufSize));
     924                LogRel2(("OSS: Warning: Invalid available size (%d vs. %zu)\n", abinfo.bytes, cbBufSize));
    913925                rc = VERR_INVALID_PARAMETER;
    914926                break;
    915927            }
    916928
    917             cToRead = RT_MIN((uint32_t)AUDIOMIXBUF_B2S(&pStream->MixBuf, abinfo.bytes), cLive);
    918             if (!cToRead)
     929            csToRead = RT_MIN((uint32_t)AUDIOMIXBUF_B2S(&pStream->MixBuf, abinfo.fragments * abinfo.fragsize), csLive);
     930            if (!csToRead)
    919931                break;
    920932#ifndef RT_OS_L4
    921933        }
    922934#endif
    923         size_t cbToRead = AUDIOMIXBUF_S2B(&pStream->MixBuf, cToRead);
    924         LogFlowFunc(("cbToRead=%zu\n", cbToRead));
    925 
    926         uint32_t cRead, cbRead;
     935        size_t cbToRead = RT_MIN(AUDIOMIXBUF_S2B(&pStream->MixBuf, csToRead), pStrm->cbBuf);
     936
     937        uint32_t csRead, cbRead;
    927938        while (cbToRead)
    928939        {
    929             rc = AudioMixBufReadCirc(&pStream->MixBuf, pStrm->pvBuf, cbToRead, &cRead);
     940            rc = AudioMixBufReadCirc(&pStream->MixBuf, pStrm->pvBuf, cbToRead, &csRead);
    930941            if (RT_FAILURE(rc))
    931942                break;
    932943
    933             cbRead = AUDIOMIXBUF_S2B(&pStream->MixBuf, cRead);
    934             ssize_t cbWritten = write(pStrm->hFile, pStrm->pvBuf, cbRead);
    935             if (cbWritten == -1)
    936             {
    937                 LogRel(("OSS: Failed writing output data: %s\n", strerror(errno)));
    938                 rc = RTErrConvertFromErrno(errno);
    939                 break;
     944            cbRead = AUDIOMIXBUF_S2B(&pStream->MixBuf, csRead);
     945
     946            uint32_t cbChunk    = cbRead;
     947            uint32_t cbChunkOff = 0;
     948            while (cbChunk)
     949            {
     950                ssize_t cbChunkWritten = write(pStrm->hFile, (uint8_t *)pStrm->pvBuf + cbChunkOff, RT_MIN(cbChunk, 4096));
     951                if (cbChunkWritten < 0)
     952                {
     953                    LogRel(("OSS: Failed writing output data: %s\n", strerror(errno)));
     954                    rc = RTErrConvertFromErrno(errno);
     955                    break;
     956                }
     957
     958                if (cbChunkWritten & pStrm->Props.uAlign)
     959                {
     960                    LogRel(("OSS: Misaligned write (written %z, expected %RU32)\n", cbChunkWritten, cbChunk));
     961                    break;
     962                }
     963
     964                cbChunkOff += cbChunkWritten;
     965                Assert(cbChunkOff <= cbRead);
     966                Assert(cbChunk    >= cbChunkWritten);
     967                cbChunk    -= cbChunkWritten;
    940968            }
    941969
    942970            Assert(cbToRead >= cbRead);
    943             cbToRead    -= cbRead;
    944             cbReadTotal += cbRead;
     971            cbToRead       -= cbRead;
     972            cbWrittenTotal += cbRead;
    945973        }
    946974
    947975#ifndef RT_OS_L4
    948976        /* Update read pointer. */
    949         if (pStrm->fMemMapped)
     977        if (pStrm->fMMIO)
    950978            pStrm->old_optr = cntinfo.ptr;
    951979#endif
     
    955983    if (RT_SUCCESS(rc))
    956984    {
    957         uint32_t cReadTotal = AUDIOMIXBUF_B2S(&pStream->MixBuf, cbReadTotal);
    958         if (cReadTotal)
    959             AudioMixBufFinish(&pStream->MixBuf, cReadTotal);
     985        uint32_t cWrittenTotal = AUDIOMIXBUF_B2S(&pStream->MixBuf, cbWrittenTotal);
     986        if (cWrittenTotal)
     987            AudioMixBufFinish(&pStream->MixBuf, cWrittenTotal);
    960988
    961989        if (pcbWritten)
    962             *pcbWritten = cReadTotal;
    963 
    964         LogFlowFunc(("cReadTotal=%RU32 (%RU32 bytes), rc=%Rrc\n", cReadTotal, cbReadTotal, rc));
     990            *pcbWritten = cbWrittenTotal;
    965991    }
    966992
     
    9941020 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate}
    9951021 */
    996 static DECLCALLBACK(int) drvHostOSSAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     1022static DECLCALLBACK(int) drvHostOSSAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream,
     1023                                                     PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    9971024{
    9981025    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     
    10321059 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl}
    10331060 */
    1034 static DECLCALLBACK(int) drvHostOSSAudioStreamControl(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
     1061static DECLCALLBACK(int) drvHostOSSAudioStreamControl(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream,
     1062                                                      PDMAUDIOSTREAMCMD enmStreamCmd)
    10351063{
    10361064    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
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