DrvAudioVRDE.cpp revision 5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * VBox Audio VRDE backend
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * Copyright (C) 2006-2010 Oracle Corporation
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * available from http://www.virtualbox.org. This file is free software;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * you can redistribute it and/or modify it under the terms of the GNU
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * General Public License (GPL) as published by the Free Software
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync/*******************************************************************************
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * IO Ring Buffer section
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync ******************************************************************************/
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync/* Implementation of a lock free ring buffer which could be used in a multi
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * threaded environment. Note that only the acquire, release and getter
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * functions are threading aware. So don't use reset if the ring buffer is
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * still in use. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsynctypedef struct IORINGBUFFER
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* The current read position in the buffer */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* The current write position in the buffer */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* How much space of the buffer is currently in use */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* How big is the buffer */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* The buffer itself */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync/* Pointer to an ring buffer structure */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncPPDMDRVINS gpDrvIns; //@todo handle this bad programming;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic void IORingBufferCreate(PIORINGBUFFER *ppBuffer, uint32_t cSize)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic void IORingBufferDestroy(PIORINGBUFFER pBuffer)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncDECL_FORCE_INLINE(void) IORingBufferReset(PIORINGBUFFER pBuffer)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncDECL_FORCE_INLINE(uint32_t) IORingBufferFree(PIORINGBUFFER pBuffer)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync return pBuffer->cBufSize - ASMAtomicReadU32(&pBuffer->cBufferUsed);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncDECL_FORCE_INLINE(uint32_t) IORingBufferUsed(PIORINGBUFFER pBuffer)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncDECL_FORCE_INLINE(uint32_t) IORingBufferSize(PIORINGBUFFER pBuffer)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic void IORingBufferAquireReadBlock(PIORINGBUFFER pBuffer, uint32_t cReqSize, char **ppStart, uint32_t *pcSize)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* How much is in use? */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Get the size out of the requested size, the read block till the end
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * of the buffer & the currently used size. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync uSize = RT_MIN(cReqSize, RT_MIN(pBuffer->cBufSize - pBuffer->uReadPos, uUsed));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Return the pointer address which point to the current read
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * position. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncDECL_FORCE_INLINE(void) IORingBufferReleaseReadBlock(PIORINGBUFFER pBuffer, uint32_t cSize)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Split at the end of the buffer. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pBuffer->uReadPos = (pBuffer->uReadPos + cSize) % pBuffer->cBufSize;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic void IORingBufferAquireWriteBlock(PIORINGBUFFER pBuffer, uint32_t cReqSize, char **ppStart, uint32_t *pcSize)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* How much is free? */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync uFree = pBuffer->cBufSize - ASMAtomicReadU32(&pBuffer->cBufferUsed);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Get the size out of the requested size, the write block till the end
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * of the buffer & the currently free size. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync uSize = RT_MIN(cReqSize, RT_MIN(pBuffer->cBufSize - pBuffer->uWritePos, uFree));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Return the pointer address which point to the current write
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * position. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncDECL_FORCE_INLINE(void) IORingBufferReleaseWriteBlock(PIORINGBUFFER pBuffer, uint32_t cSize)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Split at the end of the buffer. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pBuffer->uWritePos = (pBuffer->uWritePos + cSize) % pBuffer->cBufSize;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync/****************** Ring Buffer Function Ends *****************/
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync//@todo need to see if they need to move to pdmifs.h
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync/* Initialization status indicator used for the recreation of the AudioUnits. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync#define CA_STATUS_UNINIT UINT32_C(0) /* The device is uninitialized */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync#define CA_STATUS_IN_INIT UINT32_C(1) /* The device is currently initializing */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync#define CA_STATUS_INIT UINT32_C(2) /* The device is initialized */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync#define CA_STATUS_IN_UNINIT UINT32_C(3) /* The device is currently uninitializing */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync//@todo move t_sample as a PDM interface
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync//typedef struct { int mute; uint32_t r; uint32_t l; } volume_t;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync/* The desired buffer length in milliseconds. Will be the target total stream
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * latency on newer version of pulse. Apparent latency can be less (or more.)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * In case its need to be used. Currently its not used.
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic struct
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * Audio VRDE driver instance data.
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * @extends PDMIAUDIOSNIFFERCONNECTOR
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsynctypedef struct DRVAUDIOVRDE
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /** Pointer to audio VRDE object */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /** Pointer to the driver instance structure. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /** Pointer to the DrvAudio port interface that is above it. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsynctypedef struct VRDEVoice
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Audio and audio details for recording */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Number of bytes per frame (bitsPerSample * channels) of the actual input format. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Frequency of the actual audio format. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* If the actual format frequence differs from the requested format, this is not NULL. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Temporary buffer for st_sample_t representation of the input audio data. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* buffer for bytes of samples (not rate converted) */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Temporary buffer for frequency conversion. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* buffer for bytes rate converted samples */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* A ring buffer for transferring data to the playback thread */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsynctypedef struct VRDEVoiceOut
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync/** Makes a PDRVBLOCK out of a PPDMIBLOCK. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync#define PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface) ( (PDRVAUDIOVRDE)((uintptr_t)pInterface - RT_OFFSETOF(DRVAUDIOVRDE, IHostAudioR3)) )
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncvoid AudioVRDE::handleVRDESvrCmdAudioInputIntercept(bool fIntercept)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("AudioVRDE: handleVRDPCmdInputIntercept\n"));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic DECLCALLBACK(void *) drvAudioVRDEInit(PPDMIHOSTAUDIO pInterface)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic void drvAudioVRDEPcmInitInfo(PDMPCMPROPERTIES * pProps, audsettings_t *as)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pProps->cbPerSec = pProps->uFrequency << pProps->cShift;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pProps->fSwapEndian = (as->endianness != AUDIO_HOST_ENDIANNESS);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * Hard voice (playback)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic int audio_pcm_hw_find_min_out (PPDMHOSTVOICEOUT hw, int *nb_livep)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync RTListForEach(&hw->HeadGstVoiceOut, pIter, PDMGSTVOICEOUT, ListGstVoiceOut)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncint audio_pcm_hw_get_live_out2 (PPDMHOSTVOICEOUT hw, int *nb_live)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * Hard voice (capture)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic int audio_pcm_hw_find_min_in (PPDMHOSTVOICEIN hw)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync RTListForEach(&hw->HeadGstVoiceIn, pIter, PDMGSTVOICEIN, ListGstVoiceIn)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync int live = hw->cSamplesCaptured - audio_pcm_hw_find_min_in (hw);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync return (d + incr);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncvoid VRDEReallocSampleBuf(PVRDEVoice pVRDEVoice, uint32_t cSamples)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync uint32_t cbBuffer = cSamples * sizeof(PDMHOSTSTEREOSAMPLE);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync if (cbBuffer > pVRDEVoice->cbSamplesBufferAllocated)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pVRDEVoice->pvSamplesBuffer = RTMemAlloc(cbBuffer);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncvoid VRDEReallocRateAdjSampleBuf(PVRDEVoice pVRDEVoice, uint32_t cSamples)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync uint32_t cbBuffer = cSamples * sizeof(PDMHOSTSTEREOSAMPLE);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync/*******************************************************************************
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * AudioVRDE input section
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync ******************************************************************************/
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * Callback to feed audio input buffer. Samples format is be the same as
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * in the voice. The caller prepares st_sample_t.
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * @param cbSamples Size of pvSamples array in bytes.
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * @param pvSamples Points to an array of samples.
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * @return IPRT status code.
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic int fltRecordingCallback(PVRDEVoice pVRDEVoice, uint32_t cbSamples, const void *pvSamples)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync Assert((cbSamples % sizeof(PDMHOSTSTEREOSAMPLE)) == 0);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* If nothing is pending return immediately. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* How much space is free in the ring buffer? */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync csAvail = IORingBufferFree(pVRDEVoice->pRecordedVoiceBuf) / sizeof(PDMHOSTSTEREOSAMPLE); /* bytes -> samples */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* How much space is used in the audio buffer. Use the smaller size of the too. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync csAvail = RT_MIN(csAvail, cbSamples / sizeof(PDMHOSTSTEREOSAMPLE));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Iterate as long as data is available */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* How much is left? */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync cbToWrite = csToWrite * sizeof(PDMHOSTSTEREOSAMPLE);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Try to acquire the necessary space from the ring buffer. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync IORingBufferAquireWriteBlock(pVRDEVoice->pRecordedVoiceBuf, cbToWrite, &pcDst, &cbToWrite);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* How much do we get? */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync csToWrite = cbToWrite / sizeof(PDMHOSTSTEREOSAMPLE);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Break if nothing is free anymore. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Copy the data from the audio buffer to the ring buffer in PVRDEVoice. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync memcpy(pcDst, (uint8_t *)pvSamples + (csWritten * sizeof(PDMHOSTSTEREOSAMPLE)), cbToWrite);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Release the ring buffer, so the main thread could start reading this data. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync IORingBufferReleaseWriteBlock(pVRDEVoice->pRecordedVoiceBuf, cbToWrite);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("AudioVRDE: [Input] Finished writing buffer with %RU32 samples (%RU32 bytes)\n",
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync csWritten, csWritten * sizeof(PDMHOSTSTEREOSAMPLE)));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncSTDMETHODIMP AudioVRDE::handleVRDESvrCmdAudioInputEventBegin(void *pvContext, int iSampleHz, int cChannels, int cBits, bool fUnsigned)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("AudioVRDE: handleVRDPCmdInputEventBegin\n"));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Prepare a format convertion for the actually used format. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pVRDEVoice->cBytesPerFrame = ((cBits + 7) / 8) * cChannels;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync //PPDMIAUDIOCONNECTOR pPort = server->mConsole->getAudioVRDE()->getDrvAudioPort();
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Call DrvAudio interface to get the t_sample type conversion function */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pVRDEVoice->convAudioDevFmtToStSampl = mpDrv->pUpPort->pfnConvDevFmtToStSample(mpDrv->pUpPort,
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("AudioVRDE: Failed to get the conversion function \n"));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("AudioVRDE: Required freq as requested by VRDP Server = %d\n", iSampleHz));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync //if (iSampleHz && iSampleHz != pVRDEVoice->pHostVoiceIn.Props.uFrequency)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* @todo if the above condition is false then pVRDEVoice->uFrequency will remain 0 */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pVRDEVoice->rate = mpDrv->pUpPort->pfnPrepareAudioConversion(mpDrv->pUpPort, iSampleHz,
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("AudioVRDE: pVRDEVoice assigned requested freq =%d\n", pVRDEVoice->uFrequency));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * pvContext: pointer to VRDP voice returned by the VRDP server. The is same pointer that we initialized in
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * drvAudioVRDEDisableEnableIn VOICE_ENABLE case.
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncvoid AudioVRDE::handleVRDESvrCmdAudioInputEventData(void *pvContext, const void *pvData, uint32_t cbData)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync PPDMHOSTSTEREOSAMPLE pHostStereoSampleBuf; /* target sample buffer */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync PPDMHOSTSTEREOSAMPLE pConvertedSampleBuf; /* samples adjusted for rate */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync uint32_t cSamples = cbData / pVRDEVoice->cBytesPerFrame; /* Count of samples */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync uint32_t cConvertedSamples; /* samples adjusted for rate */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync uint32_t cbSamples; /* count of bytes occupied by samples */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("AudioVRDE: handleVRDPCmdInputEventData cbData = %d, bytesperfram=%d\n",
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pHostStereoSampleBuf = (PPDMHOSTSTEREOSAMPLE)pVRDEVoice->pvSamplesBuffer;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pVRDEVoice->convAudioDevFmtToStSampl(pHostStereoSampleBuf, pvData, cSamples, &nominal_volume);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* count of rate adjusted samples */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pVRDEVoice->uFrequency = 22100; /* @todo handle this. How pVRDEVoice will get proper value */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync cConvertedSamples = (cSamples * pVRDEVoice->pHostVoiceIn.Props.uFrequency) / pVRDEVoice->uFrequency;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync VRDEReallocRateAdjSampleBuf(pVRDEVoice, cConvertedSamples);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pConvertedSampleBuf = (PPDMHOSTSTEREOSAMPLE)pVRDEVoice->pvRateBuffer;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync mpDrv->pUpPort->pfnDoRateConversion(mpDrv->pUpPort, pVRDEVoice->rate, pHostStereoSampleBuf,
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pConvertedSampleBuf, &cSampleSrc, &cConvertedSamples);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync cbSamples = cConvertedSamples * sizeof(PDMHOSTSTEREOSAMPLE);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync rc = fltRecordingCallback(pVRDEVoice, cbSamples, pTmpSampleBuf);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * pvContext: pointer to VRDP voice returned by the VRDP server. The is same pointer that we initialized in
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * drvAudioVRDEDisableEnableIn VOICE_ENABLE case.
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncvoid AudioVRDE::handleVRDESvrCmdAudioInputEventEnd(void *pvContext)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("AudioVRDE: handleVRDPCmdInputEventEnd\n"));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* The caller will not use this context anymore. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync mpDrv->pUpPort->pfnEndAudioConversion(mpDrv->pUpPort, pVRDEVoice->rate);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic DECLCALLBACK(int) drvAudioVRDEInitOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT pHostVoiceOut, audsettings_t *as)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync PDRVAUDIOVRDE pDrv = PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync PVRDEVoiceOut pVRDEVoiceOut = (PVRDEVoiceOut)pHostVoiceOut;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("DrvAudioVRDEInitOut: audio input begin cShift=%d\n", pHostVoiceOut->Props.cShift));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync drvAudioVRDEPcmInitInfo(&pVRDEVoiceOut->pHostVoiceOut.Props, as);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic DECLCALLBACK(int) drvAudioVRDEInitIn (PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN pHostVoiceIn, audsettings_t *as)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync PDRVAUDIOVRDE pDrv = PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync drvAudioVRDEPcmInitInfo(&pVRDEVoice->pHostVoiceIn.Props, as);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic DECLCALLBACK(int) drvAudioVRDEPlayIn(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN pHostVoiceIn)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync //@todo take care of the size of the buffer allocated to pHostVoiceIn
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* use this from DrvHostCoreAudio.c */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync if (ASMAtomicReadU32(&pVRDEVoice->status) != CA_STATUS_INIT)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("AudioVRDE: VRDE voice not initialized \n"));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* how much space is used in the ring buffer in pRecordedVocieBuf with pAudioVRDE . Bytes-> samples*/
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync cSamplesRingBuffer = IORingBufferUsed(pVRDEVoice->pRecordedVoiceBuf) / sizeof(PDMHOSTSTEREOSAMPLE);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* How much space is available in the mix buffer. Use the smaller size of the too. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync cSamplesRingBuffer = RT_MIN(cSamplesRingBuffer, (uint32_t)(pVRDEVoice->pHostVoiceIn.cSamples -
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync audio_pcm_hw_get_live_in (&pVRDEVoice->pHostVoiceIn)));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("AudioVRDE: [Input] Start reading buffer with %d samples (%d bytes)\n", cSamplesRingBuffer,
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync cSamplesRingBuffer * sizeof(PDMHOSTSTEREOSAMPLE)));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Iterate as long as data is available */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* How much is left? Split request at the end of our samples buffer. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync cSamplesToRead = RT_MIN(cSamplesRingBuffer - cSamplesRead,
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync (uint32_t)(pVRDEVoice->pHostVoiceIn.cSamples - pVRDEVoice->pHostVoiceIn.offWrite));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync cbToRead = cSamplesToRead * sizeof(PDMHOSTSTEREOSAMPLE);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("AudioVRDE: [Input] Try reading %RU32 samples (%RU32 bytes)\n", cSamplesToRead, cbToRead));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Try to acquire the necessary block from the ring buffer. Remeber in fltRecrodCallback we
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * we are filling this buffer with the audio data available from VRDP. Here we are reading it
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /*todo do I need to introduce a thread to fill the buffer in fltRecordcallback. So that
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * filling is in separate thread and the reading of that buffer is in separate thread
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync IORingBufferAquireReadBlock(pVRDEVoice->pRecordedVoiceBuf, cbToRead, &pcSrc, &cbToRead);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* How much to we get? */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync cSamplesToRead = cbToRead / sizeof(PDMHOSTSTEREOSAMPLE);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("AuderVRDE: [Input] There are %d samples (%d bytes) available\n", cSamplesToRead, cbToRead));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Break if nothing is used anymore. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Copy the data from our ring buffer to the mix buffer. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync psDst = pVRDEVoice->pHostVoiceIn.pConversionBuf + pVRDEVoice->pHostVoiceIn.offWrite;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Release the read buffer, so it could be used for new data. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync IORingBufferReleaseReadBlock(pVRDEVoice->pRecordedVoiceBuf, cbToRead);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pVRDEVoice->pHostVoiceIn.offWrite = (pVRDEVoice->pHostVoiceIn.offWrite + cSamplesToRead)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* How much have we reads so far. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("AudioVRDE: [Input] Finished reading buffer with %d samples (%d bytes)\n",
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync cSamplesRead, cSamplesRead * sizeof(PDMHOSTSTEREOSAMPLE)));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic DECLCALLBACK(int) drvAudioVRDEPlayOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT pHostVoiceOut)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync PDRVAUDIOVRDE pDrv = PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync PVRDEVoiceOut pVRDEVoiceOut = (PVRDEVoiceOut)pHostVoiceOut;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * Just call the VRDP server with the data.
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync uint64_t ticks_per_second = audio_get_ticks_per_sec();
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync cSamplesPlayed = (int)((2 * ticks * pHostVoiceOut->Props.uFrequency + ticks_per_second) / ticks_per_second / 2);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync VRDEAUDIOFORMAT format = VRDE_AUDIO_FMT_MAKE(pHostVoiceOut->Props.uFrequency,
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("DrvAudioVRDE: send audio sample freq=%d, chan=%d, cBits = %d, fsigned = %d, cSamples=%d format=%d \n",
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pHostVoiceOut->Props.uFrequency, pHostVoiceOut->Props.cChannels,
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pHostVoiceOut->Props.cBits, pHostVoiceOut->Props.fSigned,
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync if (pHostVoiceOut->offRead + cSamplesToSend > pHostVoiceOut->cSamples)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* send the samples till the end of pHostStereoSampleBuf */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pDrv->pConsoleVRDPServer->SendAudioSamples(&pHostVoiceOut->pHostSterioSampleBuf[pHostVoiceOut->offRead],
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync (pHostVoiceOut->cSamples - pHostVoiceOut->offRead), format);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /*pHostStereoSampleBuff already has the samples which exceeded its space. They have overwriten the old
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * played sampled starting from offset 0. So based on the number of samples that we had to play,
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * read the number of samples from offset 0 .
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pDrv->pConsoleVRDPServer->SendAudioSamples(&pHostVoiceOut->pHostSterioSampleBuf[0],
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pDrv->pConsoleVRDPServer->SendAudioSamples(&pHostVoiceOut->pHostSterioSampleBuf[pHostVoiceOut->offRead],
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pHostVoiceOut->offRead = (pHostVoiceOut->offRead + cSamplesToSend) % pHostVoiceOut->cSamples;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic DECLCALLBACK(void) drvAudioVRDEFiniIn(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN hw)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync PDRVAUDIOVRDE pDrv = PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic DECLCALLBACK(void) drvAudioVRDEFiniOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT pHostVoiceOut)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync PDRVAUDIOVRDE pDrv = PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic DECLCALLBACK(int) drvAudioVRDEDisableEnableOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT hw, int cmd)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("DrvAudioVRDE: drvAudioVRDEDisableEnableOut \n"));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic DECLCALLBACK(int) drvAudioVRDEDisableEnableIn(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN pHostVoiceIn, int cmd)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync PDRVAUDIOVRDE pDrv = PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Initialize VRDEVoice and return to VRDP server which returns this struct back to us
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * in the form void * pvContext
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("DrvAudioVRDE: drvAudioVRDEDisableEnableIn \n"));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* initialize only if not already done */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync //@todo if (!pVRDEVoice->fIsInit)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync // IORingBufferReset(pVRDEVoice->pRecordedVoiceBuf);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogFlow(("DrvAudioVRDE: Intializing the VRDE params and buffer \n"));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Initialize the hardware info section with the audio settings */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_IN_INIT);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Create the internal ring buffer. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pVRDEVoice->pHostVoiceIn.cSamples * sizeof(PDMHOSTSTEREOSAMPLE));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync LogRel(("AudioVRDE: [Input] Failed to create internal ring buffer\n"));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_INIT);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync return pDrv->pConsoleVRDPServer->SendAudioInputBegin(NULL, pVRDEVoice, pHostVoiceIn->cSamples,
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pHostVoiceIn->Props.cChannels, pHostVoiceIn->Props.cBits);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_IN_UNINIT);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync IORingBufferDestroy(pVRDEVoice->pRecordedVoiceBuf);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_UNINIT);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic DECLCALLBACK(void) drvAudioVRDEGetConf(PPDMIBASE pInterface, PPDMAUDIOCONF pAudioConf)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* @todo check if szHostVoiceOut = sizeof VRDEVoice works. VRDEVoice doesn't contain HOSTVOICEOUT. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * @interface_method_impl{PDMIBASE,pfnQueryInterface}
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic DECLCALLBACK(void *) drvAudioVRDEQueryInterface(PPDMIBASE pInterface, const char *pszIID)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync PDRVAUDIOVRDE pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOVRDE);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync PDMIBASE_RETURN_INTERFACE(pszIID, PDMIHOSTAUDIO, &pThis->IHostAudioR3);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncstatic DECLCALLBACK(void) drvAudioVRDEDestruct(PPDMDRVINS pDrvIns)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * Construct a DirectSound Audio driver instance.
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * @copydoc FNPDMDRVCONSTRUCT
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsyncDECLCALLBACK(int) AudioVRDE::drvAudioVRDEConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync PDRVAUDIOVRDE pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOVRDE);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* we save the address of AudioVRDE in Object node in CFGM tree and address of VRDP server in
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * ObjectVRDPServer node. So presence of both is necessary.
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync //if (!CFGMR3AreValuesValid(pCfg, "Object\0") || !CFGMR3AreValuesValid(pCfg, "ObjectVRDPServer\0"))
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync // return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER,
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync ("Configuration error: Not possible to attach anything to this driver!\n"),
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * Init the static parts.
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* IBase */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pDrvIns->IBase.pfnQueryInterface = drvAudioVRDEQueryInterface;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pThis->IHostAudioR3.pfnInitIn = drvAudioVRDEInitIn;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pThis->IHostAudioR3.pfnInitOut = drvAudioVRDEInitOut;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pThis->IHostAudioR3.pfnDisableEnableOut = drvAudioVRDEDisableEnableOut;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pThis->IHostAudioR3.pfnDisableEnableIn = drvAudioVRDEDisableEnableIn;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pThis->IHostAudioR3.pfnFiniIn = drvAudioVRDEFiniIn;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pThis->IHostAudioR3.pfnFiniOut = drvAudioVRDEFiniOut;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pThis->IHostAudioR3.pfnPlayIn = drvAudioVRDEPlayIn;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pThis->IHostAudioR3.pfnPlayOut = drvAudioVRDEPlayOut;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pThis->IHostAudioR3.pfnGetConf = drvAudioVRDEGetConf;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* Get VRDPServer pointer */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync int rc = CFGMR3QueryPtr(pCfg, "ObjectVRDPServer", &pv);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync AssertMsgFailed(("DrvAudioVRDE Confguration error: No/bad \"Object\" value! rc=%Rrc\n", rc));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* CFGM tree saves the pointer to ConsoleVRDPServer in the Object node of AudioVRDE */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pThis->pConsoleVRDPServer = (ConsoleVRDPServer *)pv;
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync AssertMsgFailed(("DrvAudioVRDE Confguration error: No/bad \"Object\" value! rc=%Rrc\n", rc));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * Get the interface for the above driver (DrvAudio) to make mixer/conversion calls .
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * Described in CFGM tree.
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync pThis->pUpPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIAUDIOCONNECTOR);
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync AssertMsgFailed(("Configuration error: No Audio Sniffer port interface above!\n"));
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync * Char driver registration record.
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* szName */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync "AudioVRDE",
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* szRCMod */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* szR0Mod */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* pszDescription */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync "Audio VRDE",
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* fFlags */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* fClass. */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* cMaxInstances */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* cbInstance */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* pfnConstruct */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* pfnDestruct */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* pfnRelocate */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* pfnIOCtl */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* pfnPowerOn */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* pfnReset */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* pfnSuspend */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* pfnResume */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* pfnAttach */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* pfnDetach */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* pfnPowerOff */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* pfnSoftReset */
5f80794f0fac6c6ae43bf4d2baaef60babb2a7c7vboxsync /* u32EndVersion */