VirtualBox

Changeset 50686 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Mar 4, 2014 7:21:18 PM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
92630
Message:

src/VBox/Devices/Audio, src/VBox/Main/src-client, include/VBox/vmm:

src/VBox/Devices/Audio: part of restructuring of audio code. Devices files correspondin to Hda, AC97 and SB16 audio. The structure of files have been modifed as per PDM specs. The modified code is under #ifdef VBOX_WITH_PDM_AUDIO_DRIVER

src/VBox/Main/src-client: Driver for the VRDE that interacts with DrvAudio. Enhancement of the CFGM tree for audio.

Config.kmk : addition of one configuration parameter that will control whether new audio code is disabled or enabled. "VBOX_WITH_PDM_AUDIO_DRIVER"

pdmaudioifs.h: common header file between Device , Intermediate audio driver and Backends specific to audio.

Location:
trunk/src/VBox/Main
Files:
6 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/Makefile.kmk

    r50560 r50686  
    282282        $(if $(VBOX_WITH_S3),VBOX_WITH_S3,) \
    283283        $(if $(VBOX_WITH_PCI_PASSTHROUGH),VBOX_WITH_PCI_PASSTHROUGH,) \
     284        $(if $(VBOX_WITH_PDM_AUDIO_DRIVER),VBOX_WITH_PDM_AUDIO_DRIVER,) \
    284285        $(if $(VBOX_WITH_NAT_SERVICE),VBOX_WITH_NAT_SERVICE,) \
    285286        $(if $(VBOX_WITH_CROGL),VBOX_WITH_CROGL,) \
     
    615616        $(if $(VBOX_WITH_EXTPACK),VBOX_WITH_EXTPACK,) \
    616617        $(if $(VBOX_WITH_PCI_PASSTHROUGH),VBOX_WITH_PCI_PASSTHROUGH,) \
    617         $(if $(VBOX_WITH_VPX),VBOX_WITH_VPX,)
     618        $(if $(VBOX_WITH_VPX),VBOX_WITH_VPX,) \
     619        $(if $(VBOX_WITH_PDM_AUDIO_DRIVER),VBOX_WITH_PDM_AUDIO_DRIVER,)
    618620ifdef VBOX_WITH_CRHGSMI
    619621 VBoxC_DEFS += VBOX_WITH_CRHGSMI
     
    693695        src-client/Nvram.cpp \
    694696        src-client/AdditionsFacilityImpl.cpp \
    695         src-client/AudioSnifferInterface.cpp \
    696697        src-client/BusAssignmentManager.cpp \
    697698        $(if $(VBOX_WITH_PCI_PASSTHROUGH),src-client/PCIRawDevImpl.cpp,) \
     
    721722        $(VBOX_AUTOGEN_EVENT_CPP) \
    722723        $(VBOX_XML_SCHEMADEFS_CPP)
     724ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     725 VBoxC_SOURCES += \
     726        src-client/DrvAudioVRDE.cpp
     727else
     728 VBoxC_SOURCES += \
     729        src-client/AudioSnifferInterface.cpp
     730endif
    723731VBoxC_SOURCES.win = \
    724732        src-client/win/dllmain.cpp \
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r49983 r50686  
    3434class VRDEServerInfo;
    3535class EmulatedUSB;
     36#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     37class AudioVRDE;
     38#else
    3639class AudioSniffer;
     40#endif
    3741class Nvram;
    3842#ifdef VBOX_WITH_USB_CARDREADER
     
    190194    Display *getDisplay() const { return mDisplay; }
    191195    MachineDebugger *getMachineDebugger() const { return mDebugger; }
     196#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     197    AudioVRDE *getAudioVRDE() const { return mAudioVRDE; }
     198#else
    192199    AudioSniffer *getAudioSniffer() const { return mAudioSniffer; }
     200#endif
    193201
    194202    const ComPtr<IMachine> &machine() const { return mMachine; }
     
    235243    int hgcmLoadService(const char *pszServiceLibrary, const char *pszServiceName);
    236244    VMMDev *getVMMDev() { return m_pVMMDev; }
     245#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     246    AudioVRDE *getAudioVRDE() { return mAudioVRDE; }
     247#else
    237248    AudioSniffer *getAudioSniffer() { return mAudioSniffer; }
     249#endif
     250
    238251#ifdef VBOX_WITH_EXTPACK
    239252    ExtPackManager *getExtPackManager();
     
    825838
    826839    VMMDev * m_pVMMDev;
     840#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     841    AudioVRDE * const mAudioVRDE;
     842#else
    827843    AudioSniffer * const mAudioSniffer;
     844#endif
    828845    Nvram   * const mNvram;
    829846#ifdef VBOX_WITH_USB_CARDREADER
  • trunk/src/VBox/Main/src-client/ConsoleImpl.cpp

    r50544 r50686  
    5656#include "RemoteUSBDeviceImpl.h"
    5757#include "SharedFolderImpl.h"
     58#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     59#include "DrvAudioVRDE.h"
     60#else
    5861#include "AudioSnifferInterface.h"
     62#endif
    5963#include "Nvram.h"
    6064#ifdef VBOX_WITH_USB_CARDREADER
     
    404408    , mpVmm2UserMethods(NULL)
    405409    , m_pVMMDev(NULL)
     410#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
    406411    , mAudioSniffer(NULL)
     412#endif
    407413    , mNvram(NULL)
    408414#ifdef VBOX_WITH_USB_CARDREADER
     
    564570        //     AssertReturn(mVMMDev, E_FAIL);
    565571
     572#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     573        unconst(mAudioVRDE) = new AudioVRDE(this);
     574        AssertComRCReturnRC(rc);
     575#else
    566576        unconst(mAudioSniffer) = new AudioSniffer(this);
    567577        AssertReturn(mAudioSniffer, E_FAIL);
     578#endif
    568579
    569580        FirmwareType_T enmFirmwareType;
     
    683694    }
    684695#endif
    685 
     696#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
    686697    if (mAudioSniffer)
    687698    {
     
    689700        unconst(mAudioSniffer) = NULL;
    690701    }
     702#endif
    691703
    692704    // if the VM had a VMMDev with an HGCM thread, then remove that here
     
    13891401        if (mcAudioRefs <= 0)
    13901402        {
     1403#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
    13911404            if (mAudioSniffer)
    13921405            {
     
    13971410                }
    13981411            }
     1412#endif
    13991413        }
    14001414    }
     
    14301444    AutoCaller autoCaller(this);
    14311445    AssertComRCReturnVoid(autoCaller.rc());
    1432 
     1446#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
    14331447    LogFlowFunc(("mAudioSniffer %p, u32ClientId %d.\n",
    14341448                 mAudioSniffer, u32ClientId));
    14351449    NOREF(u32ClientId);
     1450#endif
    14361451
    14371452    ++mcAudioRefs;
     
    14391454    if (mcAudioRefs == 1)
    14401455    {
     1456#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
    14411457        if (mAudioSniffer)
    14421458        {
     
    14471463            }
    14481464        }
     1465#endif
    14491466    }
    14501467
  • trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp

    r50585 r50686  
    25032503        attachStatusDriver(pInst, &mapSharedFolderLed, 0, 0, NULL, NULL, 0);
    25042504
     2505#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
    25052506        /*
    25062507         * Audio Sniffer Device
     
    25162517        AudioSniffer *pAudioSniffer = mAudioSniffer;
    25172518        InsertConfigInteger(pCfg,  "Object", (uintptr_t)pAudioSniffer);
     2519#endif
    25182520
    25192521        /*
     
    25692571            /* the Audio driver */
    25702572            InsertConfigNode(pInst,    "LUN#0", &pLunL0);
    2571             InsertConfigString(pLunL0, "Driver",               "AUDIO");
     2573            InsertConfigString(pLunL0, "Driver", "AUDIO");
     2574
     2575#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2576            InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
     2577            InsertConfigString(pLunL1, "Driver", "PulseAudio");
     2578#endif
     2579
    25722580            InsertConfigNode(pLunL0,   "Config", &pCfg);
    25732581
     
    25912599                case AudioDriverType_DirectSound:
    25922600                {
     2601#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2602                    InsertConfigString(pCfg, "AudioDriver", "DSoundAudio");
     2603#else
    25932604                    InsertConfigString(pCfg, "AudioDriver", "dsound");
     2605#endif
    25942606                    break;
    25952607                }
     
    26062618                case AudioDriverType_ALSA:
    26072619                {
     2620#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2621                    InsertConfigString(pCfg, "AudioDriver", "AlsaAudio");
     2622#else
    26082623                    InsertConfigString(pCfg, "AudioDriver", "alsa");
     2624#endif
    26092625                    break;
    26102626                }
     
    26132629                case AudioDriverType_Pulse:
    26142630                {
     2631#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2632                    InsertConfigString(pCfg, "AudioDriver", "PulseAudio");
     2633#else
    26152634                    InsertConfigString(pCfg, "AudioDriver", "pulse");
     2635#endif
    26162636                    break;
    26172637                }
     
    26292649                case AudioDriverType_Pulse:
    26302650                {
     2651#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2652                    InsertConfigString(pCfg, "AudioDriver", "PulseAudio");
     2653#else
    26312654                    InsertConfigString(pCfg, "AudioDriver", "pulse");
     2655#endif
    26322656                    break;
    26332657                }
     
    26442668            hrc = pMachine->COMGETTER(Name)(bstr.asOutParam());                             H();
    26452669            InsertConfigString(pCfg, "StreamName", bstr);
     2670#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     2671            /* the Audio driver */
     2672            InsertConfigNode(pInst, "LUN#1", &pLunL0);
     2673            InsertConfigString(pLunL0, "Driver", "AUDIO");
     2674            InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
     2675            InsertConfigString(pLunL1, "Driver", "AudioVRDE");
     2676            InsertConfigNode(pLunL0, "Config", &pCfg);
     2677            InsertConfigString(pCfg, "AudioDriver", "AudioVRDE");
     2678            InsertConfigString(pCfg, "StreamName", bstr);
     2679            InsertConfigNode(pLunL1, "Config", &pCfg);
     2680            InsertConfigInteger(pCfg,  "Object", (uintptr_t)mAudioVRDE);
     2681            InsertConfigInteger(pCfg,  "ObjectVRDPServer", (uintptr_t)mConsoleVRDPServer);
     2682
     2683#endif
    26462684        }
    26472685
  • trunk/src/VBox/Main/src-client/ConsoleVRDPServer.cpp

    r50319 r50686  
    2121#include "KeyboardImpl.h"
    2222#include "MouseImpl.h"
     23#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     24#include "DrvAudioVRDE.h"
     25#else
    2326#include "AudioSnifferInterface.h"
     27#endif
    2428#ifdef VBOX_WITH_EXTPACK
    2529# include "ExtPackManagerImpl.h"
     
    947951        ASMAtomicWriteU32(&server->mu32AudioInputClientId, 0);
    948952
     953#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     954        server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputIntercept(false);
     955#else
    949956        PPDMIAUDIOSNIFFERPORT pPort = server->mConsole->getAudioSniffer()->getAudioSnifferPort();
    950957        if (pPort)
     
    956963            AssertFailed();
    957964        }
     965#endif
    958966    }
    959967
     
    10101018            {
    10111019                Log(("AUDIOIN: connected client %u\n", u32ClientId));
    1012 
     1020#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1021                server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputIntercept(true);
     1022#else
    10131023                PPDMIAUDIOSNIFFERPORT pPort = server->mConsole->getAudioSniffer()->getAudioSnifferPort();
    10141024                if (pPort)
     
    10261036                    rc = VERR_NOT_SUPPORTED;
    10271037                }
     1038#endif
    10281039            }
    10291040            else
     
    12941305{
    12951306    ConsoleVRDPServer *server = static_cast<ConsoleVRDPServer*>(pvCallback);
    1296 
     1307#ifndef VBOX_WITH_PDM_AUDIO_DRIVER
    12971308    PPDMIAUDIOSNIFFERPORT pPort = server->mConsole->getAudioSniffer()->getAudioSnifferPort();
     1309#endif
    12981310
    12991311    switch (u32Event)
     
    13021314        {
    13031315            const VRDEAUDIOINBEGIN *pParms = (const VRDEAUDIOINBEGIN *)pvData;
    1304 
     1316#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1317            server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputEventBegin(pvCtx,
     1318                                                                                   VRDE_AUDIO_FMT_SAMPLE_FREQ(pParms->fmt),
     1319                                                                                   VRDE_AUDIO_FMT_CHANNELS(pParms->fmt),
     1320                                                                                   VRDE_AUDIO_FMT_BITS_PER_SAMPLE(pParms->fmt),
     1321                                                                                   VRDE_AUDIO_FMT_SIGNED(pParms->fmt)
     1322                                                                                  );
     1323#else
    13051324            pPort->pfnAudioInputEventBegin (pPort, pvCtx,
    13061325                                            VRDE_AUDIO_FMT_SAMPLE_FREQ(pParms->fmt),
     
    13091328                                            VRDE_AUDIO_FMT_SIGNED(pParms->fmt)
    13101329                                           );
     1330#endif
    13111331        } break;
    13121332
    13131333        case VRDE_AUDIOIN_DATA:
    13141334        {
     1335#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1336            server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputEventData(pvCtx, pvData, cbData);
     1337#else
    13151338            pPort->pfnAudioInputEventData (pPort, pvCtx, pvData, cbData);
     1339#endif
    13161340        } break;
    13171341
    13181342        case VRDE_AUDIOIN_END:
    13191343        {
     1344#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1345            server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputEventEnd(pvCtx);
     1346#else
    13201347            pPort->pfnAudioInputEventEnd (pPort, pvCtx);
     1348#endif
    13211349        } break;
    13221350
     
    13361364    mcClipboardRefs = 0;
    13371365    mpfnClipboardCallback = NULL;
    1338 
    13391366#ifdef VBOX_WITH_USB
    13401367    mUSBBackends.pHead = NULL;
     
    38803907                                            audioFormat,
    38813908                                            cSamples);
     3909#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     3910            //*ppvUserCtx = NULL;
     3911#else
    38823912            *ppvUserCtx = NULL; /* This is the ConsoleVRDPServer context.
    3883                                  * Currently not used because only one client is allowed to
    3884                                  * do audio input and the client id is saved by the ConsoleVRDPServer.
    3885                                  */
     3913-                                * Currently not used because only one client is allowed to
     3914-                                * do audio input and the client id is saved by the ConsoleVRDPServer.
     3915-                                */
     3916#endif
    38863917
    38873918            return VINF_SUCCESS;
  • trunk/src/VBox/Main/src-client/DrvAudioVRDE.cpp

    r50177 r50686  
    11/* $Id$ */
    22/** @file
    3  * VirtualBox Driver Interface to Audio Sniffer device
     3 *
     4 * VBox Audio VRDE backend
    45 */
    56
    67/*
    7  * Copyright (C) 2006-2012 Oracle Corporation
     8 * Copyright (C) 2006-2010 Oracle Corporation
    89 *
    910 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1516 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
    1617 */
    17 
    18 #include "AudioSnifferInterface.h"
     18#include "DrvAudioVRDE.h"
    1919#include "ConsoleImpl.h"
    2020#include "ConsoleVRDPServer.h"
     
    2222#include "Logging.h"
    2323
     24#include <VBox/vmm/pdmaudioifs.h>
    2425#include <VBox/vmm/pdmdrv.h>
    2526#include <VBox/RemoteDesktop/VRDE.h>
    2627#include <VBox/vmm/cfgm.h>
    2728#include <VBox/err.h>
    28 
    29 //
    30 // defines
    31 //
    32 
    33 
    34 //
    35 // globals
    36 //
    37 
    38 
     29#include <iprt/mem.h>
     30#include <iprt/cdefs.h>
     31
     32
     33/*******************************************************************************
     34 *
     35 * IO Ring Buffer section
     36 *
     37 ******************************************************************************/
     38
     39/* Implementation of a lock free ring buffer which could be used in a multi
     40 * threaded environment. Note that only the acquire, release and getter
     41 * functions are threading aware. So don't use reset if the ring buffer is
     42 * still in use. */
     43typedef struct IORINGBUFFER
     44{
     45    /* The current read position in the buffer */
     46    uint32_t uReadPos;
     47    /* The current write position in the buffer */
     48    uint32_t uWritePos;
     49    /* How much space of the buffer is currently in use */
     50    volatile uint32_t cBufferUsed;
     51    /* How big is the buffer */
     52    uint32_t cBufSize;
     53    /* The buffer itself */
     54    char *pBuffer;
     55} IORINGBUFFER;
     56/* Pointer to an ring buffer structure */
     57typedef IORINGBUFFER* PIORINGBUFFER;
     58
     59PPDMDRVINS gpDrvIns; //@todo handle this bad programming;
     60
     61static void IORingBufferCreate(PIORINGBUFFER *ppBuffer, uint32_t cSize)
     62{
     63    PIORINGBUFFER pTmpBuffer;
     64
     65    AssertPtr(ppBuffer);
     66
     67    *ppBuffer = NULL;
     68    pTmpBuffer = RTMemAllocZ(sizeof(IORINGBUFFER));
     69    if (pTmpBuffer)
     70    {
     71        pTmpBuffer->pBuffer = RTMemAlloc(cSize);
     72        if(pTmpBuffer->pBuffer)
     73        {
     74            pTmpBuffer->cBufSize = cSize;
     75            *ppBuffer = pTmpBuffer;
     76        }
     77        else
     78            RTMemFree(pTmpBuffer);
     79    }
     80}
     81
     82static void IORingBufferDestroy(PIORINGBUFFER pBuffer)
     83{
     84    if (pBuffer)
     85    {
     86        if (pBuffer->pBuffer)
     87            RTMemFree(pBuffer->pBuffer);
     88        RTMemFree(pBuffer);
     89    }
     90}
     91
     92DECL_FORCE_INLINE(void) IORingBufferReset(PIORINGBUFFER pBuffer)
     93{
     94    AssertPtr(pBuffer);
     95
     96    pBuffer->uReadPos = 0;
     97    pBuffer->uWritePos = 0;
     98    pBuffer->cBufferUsed = 0;
     99}
     100
     101DECL_FORCE_INLINE(uint32_t) IORingBufferFree(PIORINGBUFFER pBuffer)
     102{
     103    AssertPtr(pBuffer);
     104    return pBuffer->cBufSize - ASMAtomicReadU32(&pBuffer->cBufferUsed);
     105}
     106
     107DECL_FORCE_INLINE(uint32_t) IORingBufferUsed(PIORINGBUFFER pBuffer)
     108{
     109    AssertPtr(pBuffer);
     110    return ASMAtomicReadU32(&pBuffer->cBufferUsed);
     111}
     112
     113DECL_FORCE_INLINE(uint32_t) IORingBufferSize(PIORINGBUFFER pBuffer)
     114{
     115    AssertPtr(pBuffer);
     116    return pBuffer->cBufSize;
     117}
     118
     119static void IORingBufferAquireReadBlock(PIORINGBUFFER pBuffer, uint32_t cReqSize, char **ppStart, uint32_t *pcSize)
     120{
     121    uint32_t uUsed = 0;
     122    uint32_t uSize = 0;
     123
     124    AssertPtr(pBuffer);
     125
     126    *ppStart = 0;
     127    *pcSize = 0;
     128
     129    /* How much is in use? */
     130    uUsed = ASMAtomicReadU32(&pBuffer->cBufferUsed);
     131    if (uUsed > 0)
     132    {
     133        /* Get the size out of the requested size, the read block till the end
     134         * of the buffer & the currently used size. */
     135        uSize = RT_MIN(cReqSize, RT_MIN(pBuffer->cBufSize - pBuffer->uReadPos, uUsed));
     136        if (uSize > 0)
     137        {
     138            /* Return the pointer address which point to the current read
     139             * position. */
     140            *ppStart = pBuffer->pBuffer + pBuffer->uReadPos;
     141            *pcSize = uSize;
     142        }
     143    }
     144}
     145
     146DECL_FORCE_INLINE(void) IORingBufferReleaseReadBlock(PIORINGBUFFER pBuffer, uint32_t cSize)
     147{
     148    AssertPtr(pBuffer);
     149
     150    /* Split at the end of the buffer. */
     151    pBuffer->uReadPos = (pBuffer->uReadPos + cSize) % pBuffer->cBufSize;
     152    ASMAtomicSubU32(&pBuffer->cBufferUsed, cSize);
     153}
     154
     155static void IORingBufferAquireWriteBlock(PIORINGBUFFER pBuffer, uint32_t cReqSize, char **ppStart, uint32_t *pcSize)
     156{
     157    uint32_t uFree;
     158    uint32_t uSize;
     159
     160    AssertPtr(pBuffer);
     161
     162    *ppStart = 0;
     163    *pcSize = 0;
     164
     165    /* How much is free? */
     166    uFree = pBuffer->cBufSize - ASMAtomicReadU32(&pBuffer->cBufferUsed);
     167    if (uFree > 0)
     168    {
     169        /* Get the size out of the requested size, the write block till the end
     170         * of the buffer & the currently free size. */
     171        uSize = RT_MIN(cReqSize, RT_MIN(pBuffer->cBufSize - pBuffer->uWritePos, uFree));
     172        if (uSize > 0)
     173        {
     174            /* Return the pointer address which point to the current write
     175             * position. */
     176            *ppStart = pBuffer->pBuffer + pBuffer->uWritePos;
     177            *pcSize = uSize;
     178        }
     179    }
     180}
     181
     182DECL_FORCE_INLINE(void) IORingBufferReleaseWriteBlock(PIORINGBUFFER pBuffer, uint32_t cSize)
     183{
     184    AssertPtr(pBuffer);
     185
     186    /* Split at the end of the buffer. */
     187    pBuffer->uWritePos = (pBuffer->uWritePos + cSize) % pBuffer->cBufSize;
     188
     189    ASMAtomicAddU32(&pBuffer->cBufferUsed, cSize);
     190}
     191
     192/****************** Ring Buffer Function Ends *****************/
     193
     194//@todo need to see if they need to move to pdmifs.h
     195#define AUDIO_HOST_ENDIANNESS 0
     196#define VOICE_ENABLE 1
     197#define VOICE_DISABLE 2
     198
     199
     200/* Initialization status indicator used for the recreation of the AudioUnits. */
     201#define CA_STATUS_UNINIT    UINT32_C(0) /* The device is uninitialized */
     202#define CA_STATUS_IN_INIT   UINT32_C(1) /* The device is currently initializing */
     203#define CA_STATUS_INIT      UINT32_C(2) /* The device is initialized */
     204#define CA_STATUS_IN_UNINIT UINT32_C(3) /* The device is currently uninitializing */
     205
     206//@todo move t_sample as a PDM interface
     207//typedef struct { int mute;  uint32_t r; uint32_t l; } volume_t;
     208
     209#define INT_MAX         0x7fffffff
     210volume_t nominal_volume = {
     211    0,
     212    INT_MAX,
     213    INT_MAX
     214};
     215
     216/* The desired buffer length in milliseconds. Will be the target total stream
     217 * latency on newer version of pulse. Apparent latency can be less (or more.)
     218 * In case its need to be used. Currently its not used.
     219 */
     220#if 0
     221static struct
     222{
     223    int         buffer_msecs_out;
     224    int         buffer_msecs_in;
     225} confAudioVRDE
     226=
     227{
     228    INIT_FIELD (.buffer_msecs_out = ) 100,
     229    INIT_FIELD (.buffer_msecs_in  = ) 100,
     230};
     231#endif
    39232/**
    40  * Audio Sniffer driver instance data.
     233 * Audio VRDE driver instance data.
    41234 *
    42235 * @extends PDMIAUDIOSNIFFERCONNECTOR
    43236 */
    44 typedef struct DRVAUDIOSNIFFER
    45 {
    46     /** Pointer to the Audio Sniffer object. */
    47     AudioSniffer                *pAudioSniffer;
    48 
     237typedef struct DRVAUDIOVRDE
     238{
     239    /** Pointer to audio VRDE object */
     240    AudioVRDE           *pAudioVRDE;
     241    PPDMDRVINS          pDrvIns;
    49242    /** Pointer to the driver instance structure. */
    50     PPDMDRVINS                  pDrvIns;
    51 
    52     /** Pointer to the AudioSniffer port interface of the driver/device above us. */
    53     PPDMIAUDIOSNIFFERPORT       pUpPort;
    54     /** Our VMM device connector interface. */
    55     PDMIAUDIOSNIFFERCONNECTOR   Connector;
    56 
    57 } DRVAUDIOSNIFFER, *PDRVAUDIOSNIFFER;
    58 
    59 /** Converts PDMIAUDIOSNIFFERCONNECTOR pointer to a DRVAUDIOSNIFFER pointer. */
    60 #define PDMIAUDIOSNIFFERCONNECTOR_2_MAINAUDIOSNIFFER(pInterface)    RT_FROM_MEMBER(pInterface, DRVAUDIOSNIFFER, Connector)
    61 
    62 
    63 //
    64 // constructor / destructor
    65 //
    66 AudioSniffer::AudioSniffer(Console *console)
     243    PDMIHOSTAUDIO       IHostAudioR3;
     244    ConsoleVRDPServer *pConsoleVRDPServer;
     245    /** Pointer to the DrvAudio port interface that is above it. */
     246    PPDMIAUDIOCONNECTOR       pUpPort;
     247} DRVAUDIOVRDE, *PDRVAUDIOVRDE;
     248typedef struct PDMHOSTVOICEOUT PDMHOSTVOICEOUT;
     249typedef PDMHOSTVOICEOUT *PPDMHOSTVOICEOUT;
     250
     251typedef struct VRDEVoice
     252{
     253    /* Audio and audio details for recording */
     254    PDMHOSTVOICEIN   pHostVoiceIn;
     255    void * pvUserCtx;
     256    /* Number of bytes per frame (bitsPerSample * channels) of the actual input format. */
     257    uint32_t cBytesPerFrame;
     258    /* Frequency of the actual audio format. */
     259    uint32_t uFrequency;
     260    /* If the actual format frequence differs from the requested format, this is not NULL. */
     261    void *rate;
     262    /* Temporary buffer for st_sample_t representation of the input audio data. */
     263    void *pvSamplesBuffer;
     264    /* buffer for bytes of samples (not rate converted) */
     265    uint32_t cbSamplesBufferAllocated;
     266    /* Temporary buffer for frequency conversion. */
     267    void *pvRateBuffer;
     268    /* buffer for bytes rate converted samples */
     269    uint32_t cbRateBufferAllocated;
     270    /* A ring buffer for transferring data to the playback thread */
     271    PIORINGBUFFER pRecordedVoiceBuf;
     272    t_sample * convAudioDevFmtToStSampl;
     273    uint32_t fIsInit;
     274    uint32_t status;
     275};
     276typedef VRDEVoice *PVRDEVoice;
     277
     278typedef struct VRDEVoiceOut
     279{
     280    PDMHOSTVOICEOUT pHostVoiceOut;
     281    uint64_t old_ticks;
     282    uint64_t cSamplesSentPerSec;
     283};
     284typedef VRDEVoiceOut * PVRDEVoiceOut;
     285
     286/** Makes a PDRVBLOCK out of a PPDMIBLOCK. */
     287#define PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface)        ( (PDRVAUDIOVRDE)((uintptr_t)pInterface - RT_OFFSETOF(DRVAUDIOVRDE, IHostAudioR3)) )
     288
     289AudioVRDE::AudioVRDE(Console *console)
    67290    : mpDrv(NULL),
    68291      mParent(console)
     
    70293}
    71294
    72 AudioSniffer::~AudioSniffer()
     295AudioVRDE::~AudioVRDE()
    73296{
    74297    if (mpDrv)
    75298    {
    76         mpDrv->pAudioSniffer = NULL;
     299        mpDrv->pAudioVRDE = NULL;
    77300        mpDrv = NULL;
    78301    }
    79302}
    80303
    81 PPDMIAUDIOSNIFFERPORT AudioSniffer::getAudioSnifferPort()
     304PPDMIAUDIOCONNECTOR AudioVRDE::getDrvAudioPort()
    82305{
    83306    Assert(mpDrv);
     
    85308}
    86309
    87 
    88 
    89 //
    90 // public methods
    91 //
    92 
    93 DECLCALLBACK(void) iface_AudioSamplesOut (PPDMIAUDIOSNIFFERCONNECTOR pInterface, void *pvSamples, uint32_t cSamples,
    94                                           int samplesPerSec, int nChannels, int bitsPerSample, bool fUnsigned)
    95 {
    96     PDRVAUDIOSNIFFER pDrv = PDMIAUDIOSNIFFERCONNECTOR_2_MAINAUDIOSNIFFER(pInterface);
    97 
     310void AudioVRDE::handleVRDESvrCmdAudioInputIntercept(bool fIntercept)
     311{
     312    LogFlow(("AudioVRDE: handleVRDPCmdInputIntercept\n"));
     313}
     314
     315static DECLCALLBACK(void *)  drvAudioVRDEInit(PPDMIHOSTAUDIO pInterface)
     316{
     317    LogFlow(("drvAudioVRDEInit \n"));
     318    return 1;
     319}
     320
     321static void drvAudioVRDEPcmInitInfo(PDMPCMPROPERTIES * pProps, audsettings_t *as)
     322{
     323    int bits = 8, sign = 0, shift = 0;
     324    LogFlow(("AudioVRDE: PcmInitInfo \n"));
     325
     326    switch (as->fmt) {
     327    case AUD_FMT_S8:
     328        sign = 1;
     329    case AUD_FMT_U8:
     330        break;
     331
     332    case AUD_FMT_S16:
     333        sign = 1;
     334    case AUD_FMT_U16:
     335        bits = 16;
     336        shift = 1;
     337        break;
     338
     339    case AUD_FMT_S32:
     340        sign = 1;
     341    case AUD_FMT_U32:
     342        bits = 32;
     343        shift = 2;
     344        break;
     345    }
     346
     347    pProps->uFrequency = as->freq;
     348    pProps->cBits = bits;
     349    pProps->fSigned = sign;
     350    pProps->cChannels = as->nchannels;
     351    pProps->cShift = (as->nchannels == 2) + shift;
     352    pProps->fAlign = (1 << pProps->cShift) - 1;
     353    pProps->cbPerSec = pProps->uFrequency << pProps->cShift;
     354    pProps->fSwapEndian = (as->endianness != AUDIO_HOST_ENDIANNESS);
     355}
     356
     357/*
     358 * Hard voice (playback)
     359 */
     360static int audio_pcm_hw_find_min_out (PPDMHOSTVOICEOUT hw, int *nb_livep)
     361{
     362    PPDMGSTVOICEOUT sw;
     363    PPDMGSTVOICEOUT pIter;
     364    int m = INT_MAX;
     365    int nb_live = 0;
     366    LogFlow(("Hard Voice Playback \n"));
     367
     368    RTListForEach(&hw->HeadGstVoiceOut, pIter, PDMGSTVOICEOUT, ListGstVoiceOut)
     369    {
     370        sw = pIter;
     371        if (sw->State.fActive || !sw->State.fEmpty)
     372        {
     373            m = audio_MIN (m, sw->cSamplesMixed);
     374            nb_live += 1;
     375        }
     376    }
     377
     378    *nb_livep = nb_live;
     379    return m;
     380}
     381
     382int audio_pcm_hw_get_live_out2 (PPDMHOSTVOICEOUT hw, int *nb_live)
     383{
     384    int smin;
     385
     386    smin = audio_pcm_hw_find_min_out (hw, nb_live);
     387
     388    if (!*nb_live) {
     389        return 0;
     390    }
     391    else
     392    {
     393        int live = smin;
     394
     395        if (live < 0 || live > hw->cSamples)
     396        {
     397            LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples));
     398            return 0;
     399        }
     400        return live;
     401    }
     402}
     403
     404
     405int audio_pcm_hw_get_live_out (PPDMHOSTVOICEOUT hw)
     406{
     407    int nb_live;
     408    int live;
     409
     410    live = audio_pcm_hw_get_live_out2 (hw, &nb_live);
     411    if (live < 0 || live > hw->cSamples)
     412    {
     413        LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples));
     414        return 0;
     415    }
     416    return live;
     417}
     418
     419/*
     420 * Hard voice (capture)
     421 */
     422static int audio_pcm_hw_find_min_in (PPDMHOSTVOICEIN hw)
     423{
     424    PPDMGSTVOICEIN pIter;
     425    int m = hw->cSamplesCaptured;
     426
     427    RTListForEach(&hw->HeadGstVoiceIn, pIter, PDMGSTVOICEIN, ListGstVoiceIn)
     428    {
     429        if (pIter->State.fActive)
     430        {
     431            m = audio_MIN (m, pIter->cHostSamplesAcquired);
     432        }
     433    }
     434    return m;
     435}
     436
     437int audio_pcm_hw_get_live_in (PPDMHOSTVOICEIN hw)
     438{
     439    int live = hw->cSamplesCaptured - audio_pcm_hw_find_min_in (hw);
     440    if (live < 0 || live > hw->cSamples)
     441    {
     442        LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples));
     443        return 0;
     444    }
     445    return live;
     446}
     447
     448static inline void *advance (void *p, int incr)
     449{
     450    uint8_t *d = (uint8_t*)p;
     451    return (d + incr);
     452}
     453
     454uint64_t audio_get_ticks_per_sec (void)
     455{
     456    return PDMDrvHlpTMGetVirtualFreq (gpDrvIns);
     457}
     458
     459uint64_t audio_get_clock (void)
     460{
     461    return PDMDrvHlpTMGetVirtualTime (gpDrvIns);
     462}
     463
     464void VRDEReallocSampleBuf(PVRDEVoice pVRDEVoice, uint32_t cSamples)
     465{
     466    uint32_t cbBuffer = cSamples * sizeof(PDMHOSTSTEREOSAMPLE);
     467    if (cbBuffer > pVRDEVoice->cbSamplesBufferAllocated)
     468    {
     469        if (pVRDEVoice->pvSamplesBuffer)
     470        {
     471            RTMemFree(pVRDEVoice->pvSamplesBuffer);
     472            pVRDEVoice->pvSamplesBuffer = NULL;
     473        }
     474        pVRDEVoice->pvSamplesBuffer = RTMemAlloc(cbBuffer);
     475        if (pVRDEVoice->pvSamplesBuffer)
     476            pVRDEVoice->cbSamplesBufferAllocated = cbBuffer;
     477        else
     478            pVRDEVoice->cbSamplesBufferAllocated = 0;
     479    }
     480
     481}
     482
     483void VRDEReallocRateAdjSampleBuf(PVRDEVoice pVRDEVoice, uint32_t cSamples)
     484{
     485    uint32_t cbBuffer = cSamples * sizeof(PDMHOSTSTEREOSAMPLE);
     486    if (cbBuffer > pVRDEVoice->cbRateBufferAllocated)
     487    {
     488        RTMemFree(pVRDEVoice->pvRateBuffer);
     489        pVRDEVoice->pvRateBuffer = RTMemAlloc(cbBuffer);
     490        if (pVRDEVoice->pvRateBuffer)
     491            pVRDEVoice->cbRateBufferAllocated = cbBuffer;
     492        else
     493            pVRDEVoice->cbRateBufferAllocated = 0;
     494    }
     495}
     496
     497/*******************************************************************************
     498 *
     499 * AudioVRDE input section
     500 *
     501 ******************************************************************************/
     502
     503/*
     504 * Callback to feed audio input buffer. Samples format is be the same as
     505 * in the voice. The caller prepares st_sample_t.
     506 *
     507 * @param cbSamples Size of pvSamples array in bytes.
     508 * @param pvSamples Points to an array of samples.
     509 *
     510 * @return IPRT status code.
     511 */
     512static int fltRecordingCallback(PVRDEVoice pVRDEVoice, uint32_t cbSamples, const void *pvSamples)
     513{
     514    int rc = VINF_SUCCESS;
     515    uint32_t csAvail = 0;
     516    uint32_t csToWrite = 0;
     517    uint32_t cbToWrite = 0;
     518    uint32_t csWritten = 0;
     519    char *pcDst = NULL;
     520
     521    LogFlow(("audio-filter: fltRecordingCallback\n"));
     522
     523    Assert((cbSamples % sizeof(PDMHOSTSTEREOSAMPLE)) == 0);
     524
     525    if (!pVRDEVoice->fIsInit)
     526        return VINF_SUCCESS;
     527
     528    /* If nothing is pending return immediately. */
     529    if (cbSamples == 0)
     530        return VINF_SUCCESS;
     531
     532    /* How much space is free in the ring buffer? */
     533    PPDMHOSTSTEREOSAMPLE psSrc;
     534    csAvail = IORingBufferFree(pVRDEVoice->pRecordedVoiceBuf) / sizeof(PDMHOSTSTEREOSAMPLE); /* bytes -> samples */
     535
     536    /* How much space is used in the audio buffer. Use the smaller size of the too. */
     537    csAvail = RT_MIN(csAvail, cbSamples / sizeof(PDMHOSTSTEREOSAMPLE));
     538
     539    /* Iterate as long as data is available */
     540    while(csWritten < csAvail)
     541    {
     542        /* How much is left? */
     543        csToWrite = csAvail - csWritten;
     544        cbToWrite = csToWrite * sizeof(PDMHOSTSTEREOSAMPLE);
     545
     546        /* Try to acquire the necessary space from the ring buffer. */
     547        IORingBufferAquireWriteBlock(pVRDEVoice->pRecordedVoiceBuf, cbToWrite, &pcDst, &cbToWrite);
     548
     549        /* How much do we get? */
     550        csToWrite = cbToWrite / sizeof(PDMHOSTSTEREOSAMPLE);
     551
     552            /* Break if nothing is free anymore. */
     553        if (RT_UNLIKELY(csToWrite == 0))
     554            break;
     555
     556        /* Copy the data from the audio buffer to the ring buffer in PVRDEVoice. */
     557        memcpy(pcDst, (uint8_t *)pvSamples + (csWritten * sizeof(PDMHOSTSTEREOSAMPLE)), cbToWrite);
     558
     559        /* Release the ring buffer, so the main thread could start reading this data. */
     560        IORingBufferReleaseWriteBlock(pVRDEVoice->pRecordedVoiceBuf, cbToWrite);
     561
     562        csWritten += csToWrite;
     563    }
     564
     565    LogFlow(("AudioVRDE: [Input] Finished writing buffer with %RU32 samples (%RU32 bytes)\n",
     566              csWritten, csWritten * sizeof(PDMHOSTSTEREOSAMPLE)));
     567
     568    return rc;
     569}
     570
     571
     572STDMETHODIMP AudioVRDE::handleVRDESvrCmdAudioInputEventBegin(void *pvContext, int iSampleHz, int cChannels, int cBits, bool fUnsigned)
     573{
     574    int bitIdx;
     575    PVRDEVoice pVRDEVoice = (PVRDEVoice)pvContext;
     576    LogFlow(("AudioVRDE: handleVRDPCmdInputEventBegin\n"));
     577    /* Prepare a format convertion for the actually used format. */
     578    pVRDEVoice->cBytesPerFrame = ((cBits + 7) / 8) * cChannels;
     579    if (cBits == 16)
     580    {
     581        bitIdx = 1;
     582    }
     583    else if (cBits == 32)
     584    {
     585        bitIdx = 2;
     586    }
     587    else
     588    {
     589        bitIdx = 0;
     590    }
     591    //PPDMIAUDIOCONNECTOR pPort = server->mConsole->getAudioVRDE()->getDrvAudioPort();
     592    /* Call DrvAudio interface to get the t_sample type conversion function */
     593    pVRDEVoice->convAudioDevFmtToStSampl = mpDrv->pUpPort->pfnConvDevFmtToStSample(mpDrv->pUpPort,
     594                                                                                   (cChannels == 2) ? 1 : 0,
     595                                                                                   !fUnsigned, 0, bitIdx
     596                                                                                  );
     597    if (pVRDEVoice->convAudioDevFmtToStSampl)
     598    {
     599        LogFlow(("AudioVRDE: Failed to get the conversion function \n"));
     600    }
     601    LogFlow(("AudioVRDE: Required freq as requested by VRDP Server = %d\n", iSampleHz));
     602    //if (iSampleHz && iSampleHz != pVRDEVoice->pHostVoiceIn.Props.uFrequency)
     603    {
     604        /* @todo if the above condition is false then pVRDEVoice->uFrequency will remain 0 */
     605        pVRDEVoice->rate = mpDrv->pUpPort->pfnPrepareAudioConversion(mpDrv->pUpPort, iSampleHz,
     606                                                                     pVRDEVoice->pHostVoiceIn.Props.uFrequency);
     607        pVRDEVoice->uFrequency = iSampleHz;
     608        LogFlow(("AudioVRDE: pVRDEVoice assigned requested freq =%d\n", pVRDEVoice->uFrequency));
     609    }
     610    return VINF_SUCCESS;
     611}
     612
     613/*
     614 * pvContext: pointer to VRDP voice returned by the VRDP server. The is same pointer that we initialized in
     615 *            drvAudioVRDEDisableEnableIn VOICE_ENABLE case.
     616 */
     617void AudioVRDE::handleVRDESvrCmdAudioInputEventData(void *pvContext, const void *pvData, uint32_t cbData)
     618{
     619    PVRDEVoice pVRDEVoice = (PVRDEVoice)pvContext;
     620    PPDMHOSTSTEREOSAMPLE pHostStereoSampleBuf; /* target sample buffer */
     621    PPDMHOSTSTEREOSAMPLE pConvertedSampleBuf; /* samples adjusted for rate */
     622    uint32_t cSamples = cbData / pVRDEVoice->cBytesPerFrame; /* Count of samples */
     623    void * pTmpSampleBuf = NULL;
     624    uint32_t cConvertedSamples; /* samples adjusted for rate */
     625    uint32_t cbSamples; /* count of bytes occupied by samples */
     626    uint32_t rc;
     627    LogFlow(("AudioVRDE: handleVRDPCmdInputEventData cbData = %d, bytesperfram=%d\n",
     628              cbData, pVRDEVoice->cBytesPerFrame));
     629
     630    VRDEReallocSampleBuf(pVRDEVoice, cSamples);
     631    pHostStereoSampleBuf = (PPDMHOSTSTEREOSAMPLE)pVRDEVoice->pvSamplesBuffer;
     632    pVRDEVoice->convAudioDevFmtToStSampl(pHostStereoSampleBuf, pvData, cSamples, &nominal_volume);
     633
     634    /* count of rate adjusted samples */
     635    pVRDEVoice->uFrequency = 22100; /* @todo handle this. How pVRDEVoice will get proper value */
     636    cConvertedSamples = (cSamples * pVRDEVoice->pHostVoiceIn.Props.uFrequency) / pVRDEVoice->uFrequency;
     637    VRDEReallocRateAdjSampleBuf(pVRDEVoice, cConvertedSamples);
     638
     639    pConvertedSampleBuf = (PPDMHOSTSTEREOSAMPLE)pVRDEVoice->pvRateBuffer;
     640
     641    if (pConvertedSampleBuf)
     642    {
     643        uint32_t cSampleSrc = cSamples;
     644        uint32_t cSampleDst = cConvertedSamples;
     645        mpDrv->pUpPort->pfnDoRateConversion(mpDrv->pUpPort, pVRDEVoice->rate, pHostStereoSampleBuf,
     646                                            pConvertedSampleBuf, &cSampleSrc, &cConvertedSamples);
     647        pTmpSampleBuf = pConvertedSampleBuf;
     648        cbSamples =  cConvertedSamples * sizeof(PDMHOSTSTEREOSAMPLE);
     649    }
     650
     651    if (cbSamples)
     652    {
     653        rc = fltRecordingCallback(pVRDEVoice, cbSamples, pTmpSampleBuf);
     654    }
     655}
     656
     657/*
     658 * pvContext: pointer to VRDP voice returned by the VRDP server. The is same pointer that we initialized in
     659 *            drvAudioVRDEDisableEnableIn VOICE_ENABLE case.
     660 */
     661void AudioVRDE::handleVRDESvrCmdAudioInputEventEnd(void *pvContext)
     662{
     663    PVRDEVoice pVRDEVoice = (PVRDEVoice)pvContext;
     664    LogFlow(("AudioVRDE: handleVRDPCmdInputEventEnd\n"));
     665     /* The caller will not use this context anymore. */
     666    if (pVRDEVoice->rate)
     667    {
     668        mpDrv->pUpPort->pfnEndAudioConversion(mpDrv->pUpPort, pVRDEVoice->rate);
     669    }
     670
     671    if (pVRDEVoice->pvSamplesBuffer)
     672    {
     673        RTMemFree(pVRDEVoice->pvSamplesBuffer);
     674        pVRDEVoice->pvSamplesBuffer = NULL;
     675    }
     676    if(pVRDEVoice->pvRateBuffer)
     677    {
     678        RTMemFree(pVRDEVoice->pvRateBuffer);
     679        pVRDEVoice->pvRateBuffer = NULL;
     680    }
     681}
     682
     683static DECLCALLBACK(int)  drvAudioVRDEInitOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT pHostVoiceOut, audsettings_t *as)
     684{
     685    PDRVAUDIOVRDE pDrv =  PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface);
     686    PVRDEVoiceOut pVRDEVoiceOut = (PVRDEVoiceOut)pHostVoiceOut;
     687    LogFlow(("DrvAudioVRDEInitOut: audio input begin cShift=%d\n", pHostVoiceOut->Props.cShift));
     688    pHostVoiceOut->cSamples =  6174;
     689    drvAudioVRDEPcmInitInfo(&pVRDEVoiceOut->pHostVoiceOut.Props, as);
     690    return VINF_SUCCESS;
     691
     692}
     693
     694static DECLCALLBACK(int) drvAudioVRDEInitIn (PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN pHostVoiceIn, audsettings_t *as)
     695{
     696    LogFlow(("DrvAudioVRDE: drvAudioVRDEInitIn \n"));
     697    PDRVAUDIOVRDE pDrv =  PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface);
     698    PVRDEVoice pVRDEVoice = (PVRDEVoice)pHostVoiceIn;
     699    pHostVoiceIn->cSamples =  6174;
     700    drvAudioVRDEPcmInitInfo(&pVRDEVoice->pHostVoiceIn.Props, as);
     701    return VINF_SUCCESS;
     702}
     703
     704static DECLCALLBACK(int) drvAudioVRDEPlayIn(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN pHostVoiceIn)
     705{
     706    uint32_t cbAvlblRingBuffer = 0;
     707    uint32_t cSamplesRingBuffer = 0;
     708    uint32_t cSamplesToRead = 0;
     709    uint32_t cSamplesRead = 0;
     710    uint32_t cbToRead;
     711    char *pcSrc;
     712    PDMHOSTSTEREOSAMPLE * psDst;
     713    //@todo take care of the size of the buffer allocated to pHostVoiceIn
     714    PVRDEVoice pVRDEVoice = (PVRDEVoice)pHostVoiceIn;
     715    LogFlow(("DrvAudioVRDE: drvAudioVRDEPlayIn \n"));
     716
     717 /* use this from DrvHostCoreAudio.c */
     718    if (ASMAtomicReadU32(&pVRDEVoice->status) != CA_STATUS_INIT)
     719    {
     720        LogFlow(("AudioVRDE: VRDE voice not initialized \n"));
     721        return 0;
     722    }
     723
     724    /* how much space is used in the ring buffer in pRecordedVocieBuf with pAudioVRDE . Bytes-> samples*/
     725    cSamplesRingBuffer = IORingBufferUsed(pVRDEVoice->pRecordedVoiceBuf) / sizeof(PDMHOSTSTEREOSAMPLE);
     726
     727    /* How much space is available in the mix buffer. Use the smaller size of the too. */
     728    cSamplesRingBuffer = RT_MIN(cSamplesRingBuffer, (uint32_t)(pVRDEVoice->pHostVoiceIn.cSamples -
     729                               audio_pcm_hw_get_live_in (&pVRDEVoice->pHostVoiceIn)));
     730    LogFlow(("AudioVRDE: [Input] Start reading buffer with %d samples (%d bytes)\n", cSamplesRingBuffer,
     731              cSamplesRingBuffer * sizeof(PDMHOSTSTEREOSAMPLE)));
     732
     733    /* Iterate as long as data is available */
     734    while (cSamplesRead < cSamplesRingBuffer)
     735    {
     736        /* How much is left? Split request at the end of our samples buffer. */
     737        cSamplesToRead = RT_MIN(cSamplesRingBuffer - cSamplesRead,
     738                                (uint32_t)(pVRDEVoice->pHostVoiceIn.cSamples - pVRDEVoice->pHostVoiceIn.offWrite));
     739        cbToRead = cSamplesToRead * sizeof(PDMHOSTSTEREOSAMPLE);
     740        LogFlow(("AudioVRDE: [Input] Try reading %RU32 samples (%RU32 bytes)\n", cSamplesToRead, cbToRead));
     741
     742        /* Try to acquire the necessary block from the ring buffer. Remeber in fltRecrodCallback we
     743         * we are filling this buffer with the audio data available from VRDP. Here we are reading it
     744         */
     745        /*todo do I need to introduce a thread to fill the buffer in fltRecordcallback. So that
     746         * filling is in separate thread and the reading of that buffer is in separate thread
     747         */
     748        IORingBufferAquireReadBlock(pVRDEVoice->pRecordedVoiceBuf, cbToRead, &pcSrc, &cbToRead);
     749
     750        /* How much to we get? */
     751        cSamplesToRead = cbToRead / sizeof(PDMHOSTSTEREOSAMPLE);
     752        LogFlow(("AuderVRDE: [Input] There are %d samples (%d bytes) available\n", cSamplesToRead, cbToRead));
     753
     754        /* Break if nothing is used anymore. */
     755        if (cSamplesToRead == 0)
     756        {
     757            LogFlow(("AudioVRDE: Nothing to read \n"));
     758            break;
     759        }
     760
     761        /* Copy the data from our ring buffer to the mix buffer. */
     762        psDst = pVRDEVoice->pHostVoiceIn.pConversionBuf + pVRDEVoice->pHostVoiceIn.offWrite;
     763        memcpy(psDst, pcSrc, cbToRead);
     764
     765        /* Release the read buffer, so it could be used for new data. */
     766        IORingBufferReleaseReadBlock(pVRDEVoice->pRecordedVoiceBuf, cbToRead);
     767
     768        pVRDEVoice->pHostVoiceIn.offWrite = (pVRDEVoice->pHostVoiceIn.offWrite + cSamplesToRead)
     769                                              % pVRDEVoice->pHostVoiceIn.cSamples;
     770
     771        /* How much have we reads so far. */
     772        cSamplesRead += cSamplesToRead;
     773    }
     774    LogFlow(("AudioVRDE: [Input] Finished reading buffer with %d samples (%d bytes)\n",
     775               cSamplesRead, cSamplesRead * sizeof(PDMHOSTSTEREOSAMPLE)));
     776
     777    return cSamplesRead;
     778}
     779
     780static DECLCALLBACK(int) drvAudioVRDEPlayOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT pHostVoiceOut)
     781{
     782    PDRVAUDIOVRDE pDrv = PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface);
     783    PVRDEVoiceOut pVRDEVoiceOut = (PVRDEVoiceOut)pHostVoiceOut;
     784    int live;
     785    uint8_t     *pu8Dst;
     786    int cSamplesPlayed;
     787    int cSamplesToSend = 0;
    98788    /*
    99789     * Just call the VRDP server with the data.
    100790     */
    101     VRDEAUDIOFORMAT format = VRDE_AUDIO_FMT_MAKE(samplesPerSec, nChannels, bitsPerSample, !fUnsigned);
    102     pDrv->pAudioSniffer->getParent()->consoleVRDPServer()->SendAudioSamples(pvSamples, cSamples, format);
    103 }
    104 
    105 DECLCALLBACK(void) iface_AudioVolumeOut (PPDMIAUDIOSNIFFERCONNECTOR pInterface, uint16_t left, uint16_t right)
    106 {
    107     PDRVAUDIOSNIFFER pDrv = PDMIAUDIOSNIFFERCONNECTOR_2_MAINAUDIOSNIFFER(pInterface);
    108 
    109     /*
    110      * Just call the VRDP server with the data.
     791    live = audio_pcm_hw_get_live_out (pHostVoiceOut);
     792    uint64_t now = audio_get_clock();
     793    uint64_t ticks = now  - pVRDEVoiceOut->old_ticks;
     794    uint64_t ticks_per_second = audio_get_ticks_per_sec();
     795    cSamplesPlayed = (int)((2 * ticks * pHostVoiceOut->Props.uFrequency + ticks_per_second) / ticks_per_second / 2);
     796    if (cSamplesPlayed < 0)
     797        cSamplesPlayed = live;
     798    pHostVoiceOut->Props.cBits = 128;
     799    VRDEAUDIOFORMAT format = VRDE_AUDIO_FMT_MAKE(pHostVoiceOut->Props.uFrequency,
     800                                                 pHostVoiceOut->Props.cChannels,
     801                                                 pHostVoiceOut->Props.cBits, /* bits per sample */
     802                                                 !pHostVoiceOut->Props.fSigned);
     803    LogFlow(("DrvAudioVRDE: send audio sample freq=%d, chan=%d, cBits = %d, fsigned = %d, cSamples=%d format=%d \n",
     804             pHostVoiceOut->Props.uFrequency, pHostVoiceOut->Props.cChannels,
     805             pHostVoiceOut->Props.cBits, pHostVoiceOut->Props.fSigned,
     806             pHostVoiceOut->cSamples, format)
     807            );
     808    pVRDEVoiceOut->old_ticks = now;
     809    cSamplesToSend = RT_MIN(live, cSamplesPlayed);
     810    if (pHostVoiceOut->offRead + cSamplesToSend > pHostVoiceOut->cSamples)
     811    {
     812        /* send the samples till the end of pHostStereoSampleBuf */
     813        pDrv->pConsoleVRDPServer->SendAudioSamples(&pHostVoiceOut->pHostSterioSampleBuf[pHostVoiceOut->offRead],
     814                                                   (pHostVoiceOut->cSamples - pHostVoiceOut->offRead), format);
     815        /*pHostStereoSampleBuff already has the samples which exceeded its space. They have overwriten the old
     816         * played sampled starting from offset 0. So based on the number of samples that we had to play,
     817         * read the number of samples from offset 0 .
     818         */
     819        pDrv->pConsoleVRDPServer->SendAudioSamples(&pHostVoiceOut->pHostSterioSampleBuf[0],
     820                                                   (cSamplesToSend - (pHostVoiceOut->cSamples -
     821                                                                     pHostVoiceOut->offRead)),
     822                                                   format);
     823    }
     824    else
     825    {
     826        pDrv->pConsoleVRDPServer->SendAudioSamples(&pHostVoiceOut->pHostSterioSampleBuf[pHostVoiceOut->offRead],
     827                                                   cSamplesToSend, format);
     828    }
     829        pHostVoiceOut->offRead = (pHostVoiceOut->offRead + cSamplesToSend) % pHostVoiceOut->cSamples;
     830    return  cSamplesToSend;
     831}
     832
     833static DECLCALLBACK(void) drvAudioVRDEFiniIn(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN hw)
     834{
     835    PDRVAUDIOVRDE pDrv = PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface);
     836    LogFlow(("DrvAudioVRDE: drvAudioVRDEFiniIn \n"));
     837    pDrv->pConsoleVRDPServer->SendAudioInputEnd(NULL);
     838}
     839
     840static DECLCALLBACK(void) drvAudioVRDEFiniOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT pHostVoiceOut)
     841{
     842    PDRVAUDIOVRDE pDrv = PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface);
     843    LogFlow(("DrvAudioVRDE: audio input end\n"));
     844}
     845
     846static DECLCALLBACK(int) drvAudioVRDEDisableEnableOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT hw, int cmd)
     847{
     848    LogFlow(("DrvAudioVRDE: drvAudioVRDEDisableEnableOut \n"));
     849    return VINF_SUCCESS;
     850}
     851
     852static DECLCALLBACK(int) drvAudioVRDEDisableEnableIn(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN pHostVoiceIn, int cmd)
     853{
     854    PDRVAUDIOVRDE pDrv = PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface);
     855
     856    /* Initialize  VRDEVoice and return to VRDP server which returns this struct back to us
     857     * in the form void * pvContext
    111858     */
    112     pDrv->pAudioSniffer->getParent()->consoleVRDPServer()->SendAudioVolume(left, right);
    113 }
    114 
    115 DECLCALLBACK(int) iface_AudioInputBegin (PPDMIAUDIOSNIFFERCONNECTOR pInterface,
    116                                          void **ppvUserCtx,
    117                                          void *pvContext,
    118                                          uint32_t cSamples,
    119                                          uint32_t iSampleHz,
    120                                          uint32_t cChannels,
    121                                          uint32_t cBits)
    122 {
    123     PDRVAUDIOSNIFFER pDrv = PDMIAUDIOSNIFFERCONNECTOR_2_MAINAUDIOSNIFFER(pInterface);
    124 
    125     return pDrv->pAudioSniffer->getParent()->consoleVRDPServer()->SendAudioInputBegin(ppvUserCtx,
    126                                                                                       pvContext,
    127                                                                                       cSamples,
    128                                                                                       iSampleHz,
    129                                                                                       cChannels,
    130                                                                                       cBits);
    131 }
    132 
    133 DECLCALLBACK(void) iface_AudioInputEnd (PPDMIAUDIOSNIFFERCONNECTOR pInterface,
    134                                         void *pvUserCtx)
    135 {
    136     PDRVAUDIOSNIFFER pDrv = PDMIAUDIOSNIFFERCONNECTOR_2_MAINAUDIOSNIFFER(pInterface);
    137 
    138     pDrv->pAudioSniffer->getParent()->consoleVRDPServer()->SendAudioInputEnd(pvUserCtx);
    139 }
    140 
     859    PVRDEVoice pVRDEVoice = (PVRDEVoice)pHostVoiceIn;
     860    LogFlow(("DrvAudioVRDE: drvAudioVRDEDisableEnableIn \n"));
     861    /* initialize only if not already done */
     862    if (cmd == VOICE_ENABLE)
     863    {
     864        //@todo if (!pVRDEVoice->fIsInit)
     865        //    IORingBufferReset(pVRDEVoice->pRecordedVoiceBuf);
     866        LogFlow(("DrvAudioVRDE: Intializing the VRDE params and buffer \n"));
     867        pVRDEVoice->fIsInit = 1;
     868        pVRDEVoice->pHostVoiceIn = *pHostVoiceIn;
     869        pVRDEVoice->cBytesPerFrame =1 ;
     870        pVRDEVoice->uFrequency = 0;
     871        pVRDEVoice->rate = NULL;
     872        pVRDEVoice->cbSamplesBufferAllocated = 0;
     873        pVRDEVoice->pvRateBuffer = NULL;
     874        pVRDEVoice->cbRateBufferAllocated = 0;
     875
     876        pVRDEVoice->pHostVoiceIn.cSamples = 2048;
     877        /* Initialize the hardware info section with the audio settings */
     878
     879        ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_IN_INIT);
     880
     881        /* Create the internal ring buffer. */
     882        IORingBufferCreate(&pVRDEVoice->pRecordedVoiceBuf,
     883                           pVRDEVoice->pHostVoiceIn.cSamples * sizeof(PDMHOSTSTEREOSAMPLE));
     884
     885        if (!RT_VALID_PTR(pVRDEVoice->pRecordedVoiceBuf))
     886        {
     887            LogRel(("AudioVRDE: [Input] Failed to create internal ring buffer\n"));
     888            return  VERR_NO_MEMORY;
     889        }
     890
     891        ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_INIT);
     892        return pDrv->pConsoleVRDPServer->SendAudioInputBegin(NULL, pVRDEVoice, pHostVoiceIn->cSamples,
     893                                                             pHostVoiceIn->Props.uFrequency,
     894                                                             pHostVoiceIn->Props.cChannels, pHostVoiceIn->Props.cBits);
     895    }
     896    else if (cmd == VOICE_DISABLE)
     897    {
     898        LogFlow(("DrvAudioVRDE: Cmd to disable VRDE \n"));
     899        pVRDEVoice->fIsInit = 0;
     900        ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_IN_UNINIT);
     901        IORingBufferDestroy(pVRDEVoice->pRecordedVoiceBuf);
     902        pVRDEVoice->pRecordedVoiceBuf = NULL;
     903        ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_UNINIT);
     904        pDrv->pConsoleVRDPServer->SendAudioInputEnd(NULL);
     905    }
     906    return VINF_SUCCESS;
     907}
     908
     909static DECLCALLBACK(void) drvAudioVRDEGetConf(PPDMIBASE pInterface, PPDMAUDIOCONF pAudioConf)
     910{
     911    LogFlow(("drvAudioVRDE: drvAudioVRDEGetConf \n"));
     912    /* @todo check if szHostVoiceOut = sizeof VRDEVoice works. VRDEVoice doesn't contain HOSTVOICEOUT. */
     913    pAudioConf->szHostVoiceOut = sizeof(VRDEVoice);
     914    pAudioConf->szHostVoiceIn = sizeof(VRDEVoice);
     915    pAudioConf->MaxHostVoicesOut = 1;
     916    pAudioConf->MaxHostVoicesIn = 1;
     917}
    141918
    142919/**
    143920 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
    144921 */
    145 DECLCALLBACK(void *) AudioSniffer::drvQueryInterface(PPDMIBASE pInterface, const char *pszIID)
     922static DECLCALLBACK(void *) drvAudioVRDEQueryInterface(PPDMIBASE pInterface, const char *pszIID)
    146923{
    147924    PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
    148     PDRVAUDIOSNIFFER pDrv = PDMINS_2_DATA(pDrvIns, PDRVAUDIOSNIFFER);
     925    PDRVAUDIOVRDE  pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOVRDE);
    149926    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
    150     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIAUDIOSNIFFERCONNECTOR, &pDrv->Connector);
     927    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIHOSTAUDIO, &pThis->IHostAudioR3);
    151928    return NULL;
    152929}
    153930
    154931
     932static DECLCALLBACK(void) drvAudioVRDEDestruct(PPDMDRVINS pDrvIns)
     933{
     934}
     935
    155936/**
    156  * Destruct a Audio Sniffer driver instance.
    157  *
    158  * @returns VBox status.
    159  * @param   pDrvIns     The driver instance data.
    160  */
    161 DECLCALLBACK(void) AudioSniffer::drvDestruct(PPDMDRVINS pDrvIns)
    162 {
    163     PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
    164     PDRVAUDIOSNIFFER pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOSNIFFER);
    165     LogFlow(("AudioSniffer::drvDestruct: iInstance=%d\n", pDrvIns->iInstance));
    166 
    167     if (pThis->pAudioSniffer)
    168     {
    169         pThis->pAudioSniffer->mpDrv = NULL;
    170     }
    171 }
    172 
    173 
    174 /**
    175  * Construct a AudioSniffer driver instance.
     937 * Construct a DirectSound Audio driver instance.
    176938 *
    177939 * @copydoc FNPDMDRVCONSTRUCT
    178940 */
    179 DECLCALLBACK(int) AudioSniffer::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
    180 {
    181     PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    182     PDRVAUDIOSNIFFER pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOSNIFFER);
    183 
    184     LogFlow(("AudioSniffer::drvConstruct: iInstance=%d\n", pDrvIns->iInstance));
    185 
    186     /*
    187      * Validate configuration.
     941DECLCALLBACK(int) AudioVRDE::drvAudioVRDEConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
     942{
     943    PDRVAUDIOVRDE pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOVRDE);
     944    LogRel(("drvAudioVRDEConstruct\n"));
     945
     946    /* we save the address of AudioVRDE in Object node in CFGM tree and address of VRDP server in
     947     * ObjectVRDPServer node. So presence of both is necessary.
    188948     */
    189     if (!CFGMR3AreValuesValid(pCfg, "Object\0"))
    190         return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
     949    //if (!CFGMR3AreValuesValid(pCfg, "Object\0") || !CFGMR3AreValuesValid(pCfg, "ObjectVRDPServer\0"))
     950    //   return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
    191951    AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER,
    192952                    ("Configuration error: Not possible to attach anything to this driver!\n"),
     
    194954
    195955    /*
    196      * IBase.
     956     * Init the static parts.
    197957     */
    198     pDrvIns->IBase.pfnQueryInterface            = AudioSniffer::drvQueryInterface;
    199 
    200     /* Audio Sniffer connector. */
    201     pThis->Connector.pfnAudioSamplesOut         = iface_AudioSamplesOut;
    202     pThis->Connector.pfnAudioVolumeOut          = iface_AudioVolumeOut;
    203     pThis->Connector.pfnAudioInputBegin         = iface_AudioInputBegin;
    204     pThis->Connector.pfnAudioInputEnd           = iface_AudioInputEnd;
    205 
     958    pThis->pDrvIns                          = pDrvIns;
     959    gpDrvIns = pDrvIns;
     960    /* IBase */
     961    pDrvIns->IBase.pfnQueryInterface        = drvAudioVRDEQueryInterface;
     962    pThis->IHostAudioR3.pfnInitIn           = drvAudioVRDEInitIn;
     963    pThis->IHostAudioR3.pfnInitOut          = drvAudioVRDEInitOut;
     964    pThis->IHostAudioR3.pfnDisableEnableOut = drvAudioVRDEDisableEnableOut;
     965    pThis->IHostAudioR3.pfnDisableEnableIn  = drvAudioVRDEDisableEnableIn;
     966    pThis->IHostAudioR3.pfnFiniIn           = drvAudioVRDEFiniIn;
     967    pThis->IHostAudioR3.pfnFiniOut          = drvAudioVRDEFiniOut;
     968    pThis->IHostAudioR3.pfnPlayIn           = drvAudioVRDEPlayIn;
     969    pThis->IHostAudioR3.pfnPlayOut          = drvAudioVRDEPlayOut;
     970    pThis->IHostAudioR3.pfnGetConf          = drvAudioVRDEGetConf;
     971    pThis->IHostAudioR3.pfnInit             = drvAudioVRDEInit;
     972
     973    /* Get VRDPServer pointer */
     974    void *pv;
     975    int rc = CFGMR3QueryPtr(pCfg, "ObjectVRDPServer", &pv);
     976    if (RT_FAILURE(rc))
     977    {
     978        AssertMsgFailed(("DrvAudioVRDE Confguration error: No/bad \"Object\" value! rc=%Rrc\n", rc));
     979        return rc;
     980    }
     981    /* CFGM tree saves the pointer to ConsoleVRDPServer in the Object node of AudioVRDE */
     982    pThis->pConsoleVRDPServer = (ConsoleVRDPServer *)pv;
     983    pv = NULL;
     984
     985    rc = CFGMR3QueryPtr(pCfg, "Object", &pv);
     986    if (RT_FAILURE(rc))
     987    {
     988        AssertMsgFailed(("DrvAudioVRDE Confguration error: No/bad \"Object\" value! rc=%Rrc\n", rc));
     989        return rc;
     990    }
     991    pThis->pAudioVRDE = (AudioVRDE *)pv;
     992    pThis->pAudioVRDE->mpDrv = pThis;
    206993    /*
    207      * Get the Audio Sniffer Port interface of the above driver/device.
     994     * Get the interface for the above driver (DrvAudio) to make mixer/conversion calls .
     995     * Described in CFGM tree.
    208996     */
    209     pThis->pUpPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIAUDIOSNIFFERPORT);
     997    pThis->pUpPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIAUDIOCONNECTOR);
    210998    if (!pThis->pUpPort)
    211999    {
     
    2141002    }
    2151003
    216     /*
    217      * Get the Console object pointer and update the mpDrv member.
    218      */
    219     void *pv;
    220     int rc = CFGMR3QueryPtr(pCfg, "Object", &pv);
    221     if (RT_FAILURE(rc))
    222     {
    223         AssertMsgFailed(("Configuration error: No/bad \"Object\" value! rc=%Rrc\n", rc));
    224         return rc;
    225     }
    226     pThis->pAudioSniffer = (AudioSniffer *)pv;        /** @todo Check this cast! */
    227     pThis->pAudioSniffer->mpDrv = pThis;
    228 
    2291004    return VINF_SUCCESS;
    2301005}
     
    2321007
    2331008/**
    234  * Audio Sniffer driver registration record.
    235  */
    236 const PDMDRVREG AudioSniffer::DrvReg =
    237 {
    238     /* u32Version */
    239     PDM_DRVREG_VERSION,
    240     /* szName */
    241     "MainAudioSniffer",
     1009 * Char driver registration record.
     1010 */
     1011const PDMDRVREG g_DrvAudioVRDE =
     1012{
     1013     PDM_DRVREG_VERSION,
     1014   /* szName */
     1015    "AudioVRDE",
    2421016    /* szRCMod */
    2431017    "",
     
    2451019    "",
    2461020    /* pszDescription */
    247     "Main Audio Sniffer driver (Main as in the API).",
     1021    "Audio VRDE",
    2481022    /* fFlags */
    2491023    PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
     
    2531027    ~0U,
    2541028    /* cbInstance */
    255     sizeof(DRVAUDIOSNIFFER),
     1029    sizeof(DRVAUDIOVRDE),
    2561030    /* pfnConstruct */
    257     AudioSniffer::drvConstruct,
     1031    AudioVRDE::drvAudioVRDEConstruct,
    2581032    /* pfnDestruct */
    259     AudioSniffer::drvDestruct,
     1033    drvAudioVRDEDestruct,
    2601034    /* pfnRelocate */
    2611035    NULL,
     
    2811055    PDM_DRVREG_VERSION
    2821056};
    283 /* vi: set tabstop=4 shiftwidth=4 expandtab: */
     1057
     1058
     1059
  • trunk/src/VBox/Main/src-client/VBoxDriversRegister.cpp

    r48406 r50686  
    2424#include "DisplayImpl.h"
    2525#include "VMMDev.h"
     26#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     27#include "DrvAudioVRDE.h"
     28#else
    2629#include "AudioSnifferInterface.h"
     30#endif
    2731#include "Nvram.h"
    2832#include "UsbWebcamInterface.h"
     
    6771    if (RT_FAILURE(rc))
    6872        return rc;
    69 
     73#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     74    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvAudioVRDE);
     75#else
    7076    rc = pCallbacks->pfnRegister(pCallbacks, &AudioSniffer::DrvReg);
     77#endif
    7178    if (RT_FAILURE(rc))
    7279        return rc;
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