DrvHostOSSAudio.cpp revision 8a204879c937e7c55da35682a0e5d2e1df91c856
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync * OSS (Open Sound System) host audio backend.
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync * Copyright (C) 2014-2015 Oracle Corporation
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync * available from http://www.virtualbox.org. This file is free software;
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync * you can redistribute it and/or modify it under the terms of the GNU
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync * General Public License (GPL) as published by the Free Software
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync * --------------------------------------------------------------------
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync * OSS host audio driver instance data.
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync * @implements PDMIAUDIOCONNECTOR
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync /** Pointer to the driver instance structure. */
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync /** Pointer to host audio interface. */
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync /** Error count for not flooding the release log.
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync * UINT32_MAX for unlimited logging. */
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync /** Note: Always must come first! */
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync /** Note: Always must come first! */
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsynctypedef struct OSSAUDIOCFG
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync/* http://www.df.lth.se/~john_e/gems/gem002d.html */
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync AssertMsgFailed(("Format %ld not supported\n", fmt));
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync AssertMsgFailed(("Format %ld not supported\n", fmt));
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync const char *pszDev = fIn ? s_OSSConf.devpath_in : s_OSSConf.devpath_out;
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync hFile = open(pszDev, (fIn ? O_RDONLY : O_WRONLY) | O_NONBLOCK);
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync LogRel(("OSS: Failed to open %s: %s\n", pszDev, strerror(errno)));
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync int iFormat = drvHostOSSAudioFmtToOSS(pReq->enmFormat);
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync LogRel(("OSS: Failed to set audio format to %ld\n",
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync LogRel(("OSS: Failed to set number of audio channels (%d): %s\n",
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync LogRel(("OSS: Failed to set audio frequency (%dHZ): %s\n",
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync /* Obsolete on Solaris (using O_NONBLOCK is sufficient). */
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync LogRel(("OSS: Failed to set non-blocking mode: %s\n",
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync int mmmmssss = (pReq->cFragments << 16) | lsbindex(pReq->cbFragmentSize);
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync if (ioctl(hFile, SNDCTL_DSP_SETFRAGMENT, &mmmmssss))
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync LogRel(("OSS: Failed to set %RU16 fragments to %RU32 bytes each: %s\n",
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync pReq->cFragments, pReq->cbFragmentSize, strerror(errno)));
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync if (ioctl(hFile, fIn ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE,
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync LogRel(("OSS: Failed to retrieve buffer length: %s\n", strerror(errno)));
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsyncstatic DECLCALLBACK(int) drvHostOSSAudioControlIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMIN pHstStrmIn,
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync /** @todo Nothing to do here right now!? */
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsyncstatic DECLCALLBACK(int) drvHostOSSAudioControlOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMOUT pHstStrmOut,
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync AssertPtrReturn(pHstStrmOut, VERR_INVALID_POINTER);
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync POSSAUDIOSTREAMOUT pThisStrmOut = (POSSAUDIOSTREAMOUT)pHstStrmOut;
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync pThisStrmOut->pvPCMBuf, audioMixBufSize(&pHstStrmOut->MixBuf));
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync if (ioctl(pThisStrmOut->hFile, SNDCTL_DSP_SETTRIGGER, &mask) < 0)
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync LogRel(("OSS: Failed to enable output stream: %s\n",
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync if (ioctl(pThisStrmOut->hFile, SNDCTL_DSP_SETTRIGGER, &mask) < 0)
527eff46676ca64c098dc7d1bf0857408c3a6f82vboxsync LogRel(("OSS: Failed to disable output stream: %s\n",
return rc;
return VINF_SUCCESS;
static DECLCALLBACK(int) drvHostOSSAudioCaptureIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMIN pHstStrmIn,
while (cbToRead)
if (cbRead < 0)
switch (errno)
case EINTR:
case EAGAIN:
else if (cbRead)
&cWritten);
if (cWrittenTotal)
&cProcessed);
if (pcSamplesCaptured)
return rc;
static DECLCALLBACK(int) drvHostOSSAudioFiniIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMIN pHstStrmIn)
return VINF_SUCCESS;
static DECLCALLBACK(int) drvHostOSSAudioFiniOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMOUT pHstStrmOut)
#ifndef RT_OS_L4
return VINF_SUCCESS;
static DECLCALLBACK(int) drvHostOSSAudioGetConf(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pCfg)
return VINF_SUCCESS;
int rc;
if (!cSamples)
if (pcSamples)
return rc;
int rc;
#ifndef RT_OS_L4
int mask = 0;
if (rc2)
#ifndef RT_OS_L4
#ifndef RT_OS_L4
if (pcSamples)
return rc;
static DECLCALLBACK(int) drvHostOSSAudioPlayOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMOUT pHstStrmOut,
int rc;
#ifndef RT_OS_L4
if (!rc2)
int cbData;
cLive);
if (rc2 < 0)
cLive);
if (!cToRead)
#ifndef RT_OS_L4
while (cbToRead)
cbRead);
#ifndef RT_OS_L4
if (cReadTotal)
if (pcSamplesPlayed)
return rc;
return NULL;
static DECLCALLBACK(int) drvHostOSSAudioConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
return VINF_SUCCESS;
sizeof(DRVHOSTOSSAUDIO),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,