15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * Intermedia audio driver, common routines. These are also used
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * in the drivers which are bound to Main, e.g. the VRDE or the
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * video audio recording drivers.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * Copyright (C) 2006-2014 Oracle Corporation
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * available from http://www.virtualbox.org. This file is free software;
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * you can redistribute it and/or modify it under the terms of the GNU
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * General Public License (GPL) as published by the Free Software
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * --------------------------------------------------------------------
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * This code is based on: audio_template.h from QEMU AUDIO subsystem.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * QEMU Audio subsystem header
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * Copyright (c) 2005 Vassili Karpov (malc)
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * Permission is hereby granted, free of charge, to any person obtaining a copy
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * of this software and associated documentation files (the "Software"), to deal
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * in the Software without restriction, including without limitation the rights
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * copies of the Software, and to permit persons to whom the Software is
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * furnished to do so, subject to the following conditions:
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * The above copyright notice and this permission notice shall be included in
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * all copies or substantial portions of the Software.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * THE SOFTWARE.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsyncbool drvAudioPCMPropsAreEqual(PPDMPCMPROPS pProps, PPDMAUDIOSTREAMCFG pCfg);
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsyncconst char *drvAudioRecSourceToString(PDMAUDIORECSOURCE enmRecSource)
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync case PDMAUDIORECSOURCE_MIC: return "Microphone In";
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync AssertMsgFailed(("Bogus recording source %ld\n", enmRecSource));
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync return "Unknown";
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsyncconst char *drvAudioHlpFormatToString(PDMAUDIOFMT enmFormat)
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync return "U8";
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync return "U16";
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync return "U32";
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync return "S8";
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync return "S16";
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync return "S32";
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync AssertMsgFailed(("Bogus audio format %ld\n", enmFormat));
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync return "Invalid";
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsyncPDMAUDIOFMT drvAudioHlpStringToFormat(const char *pszFormat)
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync AssertMsgFailed(("Bogus audio format \"%s\"\n", pszFormat));
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync/*********************************** In Stream Functions **********************************************/
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsyncvoid drvAudioGstInFreeRes(PPDMAUDIOGSTSTRMIN pGstStrmIn)
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsyncvoid drvAudioHstInFreeRes(PPDMAUDIOHSTSTRMIN pHstStrmIn)
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsyncvoid drvAudioGstOutFreeRes(PPDMAUDIOGSTSTRMOUT pGstStrmOut)
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * Finds the minimum number of not yet captured samples of all
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * attached guest input streams for a certain host input stream.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * @return uint32_t Minimum number of not yet captured samples.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * UINT32_MAX if none found.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * @param pHstStrmIn Host input stream to check for.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsyncinline uint32_t drvAudioHstInFindMinCaptured(PPDMAUDIOHSTSTRMIN pHstStrmIn)
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync RTListForEach(&pHstStrmIn->lstGstStrmIn, pGstStrmIn, PDMAUDIOGSTSTRMIN, Node)
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync cMinSamples = RT_MIN(cMinSamples, audioMixBufMixed(&pGstStrmIn->MixBuf));
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsyncuint32_t drvAudioHstInGetFree(PPDMAUDIOHSTSTRMIN pHstStrmIn)
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync return audioMixBufSize(&pHstStrmIn->MixBuf) - drvAudioHstInGetLive(pHstStrmIn);
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsyncuint32_t drvAudioHstInGetLive(PPDMAUDIOHSTSTRMIN pHstStrmIn)
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync uint32_t cMinSamplesCaptured = drvAudioHstInFindMinCaptured(pHstStrmIn);
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync uint32_t cSamplesCaptured = audioMixBufMixed(&pHstStrmIn->MixBuf);
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync uint32_t cSamplesLive = cSamplesCaptured - cMinSamplesCaptured;
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync Assert(cSamplesLive <= audioMixBufSize(&pHstStrmIn->MixBuf));
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync LogFlowFunc(("cSamplesLive=%RU32\n", cSamplesLive));
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsyncvoid drvAudioHstOutFreeRes(PPDMAUDIOHSTSTRMOUT pHstStrmOut)
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * Returns the number of live sample data (in bytes) of a certain
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * guest input stream.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * @return uint32_t Live sample data (in bytes), 0 if none.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * @param pGstStrmIn Guest input stream to check for.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsyncuint32_t drvAudioGstInGetLiveBytes(PPDMAUDIOGSTSTRMIN pGstStrmIn)
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync Assert(pGstStrmIn->pHstStrmIn->cTotalSamplesCaptured >= pGstStrmIn->cTotalHostSamplesRead);
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync uint32_t cSamplesLive = pGstStrmIn->pHstStrmIn->cTotalSamplesCaptured - pGstStrmIn->cTotalHostSamplesRead;
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync Assert(cSamplesLive <= pGstStrmIn->pHstStrmIn->cSamples);
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync /** @todo Document / refactor this! */
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync return (((int64_t) cSamplesLive << 32) / pGstStrmIn->State.uFreqRatio) << pGstStrmIn->Props.cShift;
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * Returns the total number of unused sample data (in bytes) of a certain
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * guest output stream.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * @return uint32_t Number of unused sample data (in bytes), 0 if all used up.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * @param pGstStrmOut Guest output stream to check for.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsyncuint32_t drvAudioGstOutGetFreeBytes(PPDMAUDIOGSTSTRMOUT pGstStrmOut)
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync Assert(pGstStrmOut->cTotalSamplesWritten <= pGstStrmOut->pHstStrmOut->cSamples);
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync uint32_t cSamplesFree = pGstStrmOut->pHstStrmOut->cSamples
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync /** @todo Document / refactor this! */
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync return (((int64_t) cSamplesFree << 32) / pGstStrmOut->State.uFreqRatio) << pGstStrmOut->Props.cShift;
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsyncbool drvAudioPCMPropsAreEqual(PPDMPCMPROPS pProps, PPDMAUDIOSTREAMCFG pCfg)
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync AssertMsgFailed(("Unknown format %ld\n", pCfg->enmFormat));
10258d88c40d8254a2a0d89e9b6c1f3b487f5c2dvboxsync && pProps->fSwapEndian == !(pCfg->enmEndianness == PDMAUDIOHOSTENDIANNESS);
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsyncint drvAudioStreamCfgToProps(PPDMAUDIOSTREAMCFG pCfg, PPDMPCMPROPS pProps)
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync AssertMsgFailed(("Unknown format %ld\n", pCfg->enmFormat));
10258d88c40d8254a2a0d89e9b6c1f3b487f5c2dvboxsync pProps->fSwapEndian = pCfg->enmEndianness != PDMAUDIOHOSTENDIANNESS;
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsyncvoid drvAudioStreamCfgPrint(PPDMAUDIOSTREAMCFG pCfg)
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync LogFlowFunc(("uHz=%RU32, cChannels=%RU8, enmFormat=",
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * Returns the minimum number of live samples already written to all associated
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * guest output streams of a specific host output stream.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * @return uint32_t Minimum number of total live samples already written to all
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * associated guest output streams, UINT32_MAX if none found.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * @param pHstStrmOut Host output stream to search in.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * @param pcStreamsLive Returns the number of live guest streams associated to
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * this host output stream. Optional.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsyncstatic uint32_t drvAudioHstOutMinSamplesMixed(PPDMAUDIOHSTSTRMOUT pHstStrmOut, uint32_t *pcStreamsLive)
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync /* pcStreamsLive is optional. */
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync RTListForEach(&pHstStrmOut->lstGstStrmOut, pGstStrmOut, PDMAUDIOGSTSTRMOUT, Node)
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync cMinSamplesMixed = RT_MIN(cMinSamplesMixed, cSamples);
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * Finds the number of live (guest) samples of a specific host output stream.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * @return uint32_t Minimum number of live host output samples processed
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * by all connected guest output streams.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * @param pHstStrmOut Host output stream to search in.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync * @param pcStreamsLive Number of associated guest live streams. Optional.
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsyncuint32_t drvAudioHstOutSamplesLive(PPDMAUDIOHSTSTRMOUT pHstStrmOut, uint32_t *pcStreamsLive)
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync /* pcStreamsLive is optional. */
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync uint32_t cSamplesMin = drvAudioHstOutMinSamplesMixed(pHstStrmOut, &cStreamsLive);
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync || cSamplesMin > audioMixBufSize(&pHstStrmOut->MixBuf))
15c5e2945e3abf354a7d822904579c64f7a190c3vboxsync LogFlowFunc(("Error: cSamplesMin=%RU32\n", cSamplesMin));